mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 15:43:59 +08:00
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: Benjamin Herrenschmidt <benh@kernel.crashing.org> Reviewed-by: Christopher Bostic <cbostic@linux.vnet.ibm.com> Tested-by: Joel Stanley <joel@jms.id.au>
This commit is contained in:
parent
5d0d16f135
commit
bc1099d2b2
@ -52,6 +52,7 @@
|
|||||||
compatible = "fsi-master-gpio", "fsi-master";
|
compatible = "fsi-master-gpio", "fsi-master";
|
||||||
#address-cells = <2>;
|
#address-cells = <2>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
no-gpio-delays;
|
||||||
|
|
||||||
clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>;
|
clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>;
|
||||||
data-gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_HIGH>;
|
data-gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_HIGH>;
|
||||||
|
@ -153,6 +153,7 @@
|
|||||||
compatible = "fsi-master-gpio", "fsi-master";
|
compatible = "fsi-master-gpio", "fsi-master";
|
||||||
#address-cells = <2>;
|
#address-cells = <2>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
no-gpio-delays;
|
||||||
|
|
||||||
clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>;
|
clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>;
|
||||||
data-gpios = <&gpio ASPEED_GPIO(E, 0) GPIO_ACTIVE_HIGH>;
|
data-gpios = <&gpio ASPEED_GPIO(E, 0) GPIO_ACTIVE_HIGH>;
|
||||||
|
@ -91,6 +91,7 @@
|
|||||||
compatible = "fsi-master-gpio", "fsi-master";
|
compatible = "fsi-master-gpio", "fsi-master";
|
||||||
#address-cells = <2>;
|
#address-cells = <2>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
no-gpio-delays;
|
||||||
|
|
||||||
trans-gpios = <&gpio ASPEED_GPIO(O, 6) GPIO_ACTIVE_HIGH>;
|
trans-gpios = <&gpio ASPEED_GPIO(O, 6) GPIO_ACTIVE_HIGH>;
|
||||||
enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
|
enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
|
||||||
|
@ -62,6 +62,7 @@ struct fsi_master_gpio {
|
|||||||
struct gpio_desc *gpio_enable; /* FSI enable */
|
struct gpio_desc *gpio_enable; /* FSI enable */
|
||||||
struct gpio_desc *gpio_mux; /* Mux control */
|
struct gpio_desc *gpio_mux; /* Mux control */
|
||||||
bool external_mode;
|
bool external_mode;
|
||||||
|
bool no_delays;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
@ -79,9 +80,11 @@ static void clock_toggle(struct fsi_master_gpio *master, int count)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
ndelay(FSI_GPIO_STD_DLY);
|
if (!master->no_delays)
|
||||||
|
ndelay(FSI_GPIO_STD_DLY);
|
||||||
gpiod_set_value(master->gpio_clk, 0);
|
gpiod_set_value(master->gpio_clk, 0);
|
||||||
ndelay(FSI_GPIO_STD_DLY);
|
if (!master->no_delays)
|
||||||
|
ndelay(FSI_GPIO_STD_DLY);
|
||||||
gpiod_set_value(master->gpio_clk, 1);
|
gpiod_set_value(master->gpio_clk, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,10 +93,12 @@ static int sda_clock_in(struct fsi_master_gpio *master)
|
|||||||
{
|
{
|
||||||
int in;
|
int in;
|
||||||
|
|
||||||
ndelay(FSI_GPIO_STD_DLY);
|
if (!master->no_delays)
|
||||||
|
ndelay(FSI_GPIO_STD_DLY);
|
||||||
gpiod_set_value(master->gpio_clk, 0);
|
gpiod_set_value(master->gpio_clk, 0);
|
||||||
in = gpiod_get_value(master->gpio_data);
|
in = gpiod_get_value(master->gpio_data);
|
||||||
ndelay(FSI_GPIO_STD_DLY);
|
if (!master->no_delays)
|
||||||
|
ndelay(FSI_GPIO_STD_DLY);
|
||||||
gpiod_set_value(master->gpio_clk, 1);
|
gpiod_set_value(master->gpio_clk, 1);
|
||||||
return in ? 1 : 0;
|
return in ? 1 : 0;
|
||||||
}
|
}
|
||||||
@ -677,6 +682,13 @@ static int fsi_master_gpio_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
master->gpio_mux = gpio;
|
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.n_links = 1;
|
||||||
master->master.flags = FSI_MASTER_FLAG_SWCLOCK;
|
master->master.flags = FSI_MASTER_FLAG_SWCLOCK;
|
||||||
master->master.read = fsi_master_gpio_read;
|
master->master.read = fsi_master_gpio_read;
|
||||||
|
Loading…
Reference in New Issue
Block a user