Commit bc1099d2 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt
Browse files

fsi/fsi-master-gpio: Add "no-gpio-delays" option



This adds support for an optional device-tree property that
makes the driver skip all the delays around clocking the
GPIOs and set it in the device-tree of common POWER9 based
OpenPower platforms.

This useful on chips like the AST2500 where the GPIO block is
running at a fairly low clock frequency (25Mhz typically). In
this case, the delays are unnecessary and due to the low
precision of the timers, actually quite harmful in terms of
performance.

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: default avatarChristopher Bostic <cbostic@linux.vnet.ibm.com>
Tested-by: default avatarJoel Stanley <joel@jms.id.au>
parent 5d0d16f1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
		compatible = "fsi-master-gpio", "fsi-master";
		#address-cells = <2>;
		#size-cells = <0>;
		no-gpio-delays;

		clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>;
		data-gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_HIGH>;
+1 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@
		compatible = "fsi-master-gpio", "fsi-master";
		#address-cells = <2>;
		#size-cells = <0>;
		no-gpio-delays;

		clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>;
		data-gpios = <&gpio ASPEED_GPIO(E, 0) GPIO_ACTIVE_HIGH>;
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@
		compatible = "fsi-master-gpio", "fsi-master";
		#address-cells = <2>;
		#size-cells = <0>;
		no-gpio-delays;

		trans-gpios = <&gpio ASPEED_GPIO(O, 6) GPIO_ACTIVE_HIGH>;
		enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
+16 −4
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ struct fsi_master_gpio {
	struct gpio_desc	*gpio_enable;	/* FSI enable */
	struct gpio_desc	*gpio_mux;	/* Mux control */
	bool			external_mode;
	bool			no_delays;
};

#define CREATE_TRACE_POINTS
@@ -79,8 +80,10 @@ static void clock_toggle(struct fsi_master_gpio *master, int count)
	int i;

	for (i = 0; i < count; i++) {
		if (!master->no_delays)
			ndelay(FSI_GPIO_STD_DLY);
		gpiod_set_value(master->gpio_clk, 0);
		if (!master->no_delays)
			ndelay(FSI_GPIO_STD_DLY);
		gpiod_set_value(master->gpio_clk, 1);
	}
@@ -90,9 +93,11 @@ static int sda_clock_in(struct fsi_master_gpio *master)
{
	int in;

	if (!master->no_delays)
		ndelay(FSI_GPIO_STD_DLY);
	gpiod_set_value(master->gpio_clk, 0);
	in = gpiod_get_value(master->gpio_data);
	if (!master->no_delays)
		ndelay(FSI_GPIO_STD_DLY);
	gpiod_set_value(master->gpio_clk, 1);
	return in ? 1 : 0;
@@ -677,6 +682,13 @@ static int fsi_master_gpio_probe(struct platform_device *pdev)
	}
	master->gpio_mux = gpio;

	/*
	 * Check if GPIO block is slow enought that no extra delays
	 * are necessary. This improves performance on ast2500 by
	 * an order of magnitude.
	 */
	master->no_delays = device_property_present(&pdev->dev, "no-gpio-delays");

	master->master.n_links = 1;
	master->master.flags = FSI_MASTER_FLAG_SWCLOCK;
	master->master.read = fsi_master_gpio_read;