[U-Boot] [PATCH 2/2] x86: gpio: Add use-lvl-write-cache to fix baytrail
Simon Glass
sjg at chromium.org
Thu Oct 8 19:43:59 CEST 2015
Hi George,
On 7 October 2015 at 16:29, George McCollister
<george.mccollister at gmail.com> wrote:
> Add a device-tree property use-lvl-write-cache that will cause writes to
> lvl to be cached instead of read from lvl before each write. This is
> required on some platforms that have the register implemented as dual
> read/write (such as Baytrail).
>
> Prior to this fix the blue USB port on the Minnowboard Max was unusable
> since USB_HOST_EN0 was set high then immediately set low when
> USB_HOST_EN1 was written.
Thanks for figuring this out. I saw this support in the datasheet but
it did not work. I think I misunderstood how the cache was
implemented.
One nit below.
>
> Signed-off-by: George McCollister <george.mccollister at gmail.com>
> ---
> arch/x86/dts/minnowmax.dts | 6 ++++++
> doc/device-tree-bindings/gpio/intel,ich6-gpio.txt | 5 +++++
> drivers/gpio/intel_ich6_gpio.c | 20 +++++++++++++++++++-
> 3 files changed, 30 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
> index 79ac26d..5a76c8e 100644
> --- a/arch/x86/dts/minnowmax.dts
> +++ b/arch/x86/dts/minnowmax.dts
> @@ -31,6 +31,7 @@
> u-boot,dm-pre-reloc;
> reg = <0 0x20>;
> bank-name = "A";
> + use-lvl-write-cache;
> };
>
> gpiob {
> @@ -38,6 +39,7 @@
> u-boot,dm-pre-reloc;
> reg = <0x20 0x20>;
> bank-name = "B";
> + use-lvl-write-cache;
> };
>
> gpioc {
> @@ -45,6 +47,7 @@
> u-boot,dm-pre-reloc;
> reg = <0x40 0x20>;
> bank-name = "C";
> + use-lvl-write-cache;
> };
>
> gpiod {
> @@ -52,6 +55,7 @@
> u-boot,dm-pre-reloc;
> reg = <0x60 0x20>;
> bank-name = "D";
> + use-lvl-write-cache;
> };
>
> gpioe {
> @@ -59,6 +63,7 @@
> u-boot,dm-pre-reloc;
> reg = <0x80 0x20>;
> bank-name = "E";
> + use-lvl-write-cache;
>
> pch_pinctrl at 0 {
> compatible = "intel,x86-pinctrl";
> @@ -114,6 +119,7 @@
> u-boot,dm-pre-reloc;
> reg = <0xA0 0x20>;
> bank-name = "F";
> + use-lvl-write-cache;
> };
>
> chosen {
> diff --git a/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt b/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt
> index 23345b2..dbdcff4 100644
> --- a/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt
> +++ b/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt
> @@ -4,6 +4,10 @@ Each GPIO bank node can have the following properties:
> - compatible - (required) must be set to "intel,x86-pinctrl"
> - reg - (required) GPIO offset and length.
> - bank-name - (required) Name of the bank.
> +- use-lvl-write-cache - (optional) Cache last value written to lvl and use it
> + the next time lvl is written instead of
> + reading lvl prior to writing. Required
> + for some platforms (Baytrail).
>
> Example:
> gpioa {
> @@ -11,4 +15,5 @@ gpioa {
> u-boot,dm-pre-reloc;
> reg = <0 0x20>;
> bank-name = "A";
> + use-lvl-write-cache;
> };
> diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
> index 18420f3..b239ab5 100644
> --- a/drivers/gpio/intel_ich6_gpio.c
> +++ b/drivers/gpio/intel_ich6_gpio.c
> @@ -44,6 +44,8 @@ struct ich6_bank_priv {
> u16 use_sel;
> u16 io_sel;
> u16 lvl;
> + u32 lvl_write_cache;
> + bool use_lvl_write_cache;
> };
>
> #define IOPAD_MODE_MASK 0x7
> @@ -150,12 +152,17 @@ static int ich6_gpio_set_value(struct udevice *dev, unsigned offset,
> struct ich6_bank_priv *bank = dev_get_priv(dev);
> u32 val;
>
> - val = inl(bank->lvl);
> + if (bank->use_lvl_write_cache)
> + val = bank->lvl_write_cache;
> + else
> + val = inl(bank->lvl);
> if (value)
> val |= (1UL << offset);
> else
> val &= ~(1UL << offset);
> outl(val, bank->lvl);
> + if (bank->use_lvl_write_cache)
> + bank->lvl_write_cache = val;
>
> return 0;
> }
> @@ -353,6 +360,7 @@ static int ich6_gpio_probe(struct udevice *dev)
> struct ich6_bank_platdata *plat = dev_get_platdata(dev);
> struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> struct ich6_bank_priv *bank = dev_get_priv(dev);
> + const void *prop;
>
> if (gd->arch.gpio_map) {
> setup_pch_gpios(plat->base_addr, gd->arch.gpio_map);
> @@ -365,6 +373,14 @@ static int ich6_gpio_probe(struct udevice *dev)
> bank->io_sel = plat->base_addr + 4;
> bank->lvl = plat->base_addr + 8;
>
> + prop = fdt_getprop(gd->fdt_blob, dev->of_offset,
> + "use-lvl-write-cache", NULL);
fdtdec_get_bool()
> + if (prop)
> + bank->use_lvl_write_cache = true;
> + else
> + bank->use_lvl_write_cache = false;
> + bank->lvl_write_cache = 0;
> +
> gpio_ich6_pinctrl_init(dev);
>
> return 0;
> @@ -415,6 +431,8 @@ static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
> int r;
>
> tmplong = inl(bank->lvl);
> + if (bank->use_lvl_write_cache)
> + tmplong |= bank->lvl_write_cache;
> r = (tmplong & (1UL << offset)) ? 1 : 0;
> return r;
> }
> --
> 2.5.0
>
Regards,
Simon
More information about the U-Boot
mailing list