Hi George, On 7 October 2015 at 16:29, George McCollister <george.mccollis...@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.mccollis...@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@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot