Instead of having x86-pinctrl work separately from ich6-gpio have it work underneath ich6-gpio. This removes redundant configuration and will allow the addition of shared bank settings in future commits.
Signed-off-by: George McCollister <george.mccollis...@gmail.com> --- arch/x86/dts/minnowmax.dts | 96 +++++++++--------- arch/x86/include/asm/gpio.h | 1 - board/intel/minnowmax/minnowmax.c | 9 +- doc/device-tree-bindings/gpio/intel,ich6-gpio.txt | 14 +++ .../gpio/intel,x86-pinctrl.txt | 17 ++-- drivers/gpio/intel_ich6_gpio.c | 107 ++++++++------------- 6 files changed, 118 insertions(+), 126 deletions(-) create mode 100644 doc/device-tree-bindings/gpio/intel,ich6-gpio.txt diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index e917f0f..79ac26d 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -26,54 +26,6 @@ silent_console = <0>; }; - pch_pinctrl { - compatible = "intel,x86-pinctrl"; - io-base = <0x4c>; - - /* GPIO E0 */ - soc_gpio_s5_0@0 { - gpio-offset = <0x80 0>; - pad-offset = <0x1d0>; - mode-gpio; - output-value = <0>; - direction = <PIN_OUTPUT>; - }; - - /* GPIO E1 */ - soc_gpio_s5_1@0 { - gpio-offset = <0x80 1>; - pad-offset = <0x210>; - mode-gpio; - output-value = <0>; - direction = <PIN_OUTPUT>; - }; - - /* GPIO E2 */ - soc_gpio_s5_2@0 { - gpio-offset = <0x80 2>; - pad-offset = <0x1e0>; - mode-gpio; - output-value = <0>; - direction = <PIN_OUTPUT>; - }; - - pin_usb_host_en0@0 { - gpio-offset = <0x80 8>; - pad-offset = <0x260>; - mode-gpio; - output-value = <1>; - direction = <PIN_OUTPUT>; - }; - - pin_usb_host_en1@0 { - gpio-offset = <0x80 9>; - pad-offset = <0x250>; - mode-gpio; - output-value = <1>; - direction = <PIN_OUTPUT>; - }; - }; - gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc; @@ -107,6 +59,54 @@ u-boot,dm-pre-reloc; reg = <0x80 0x20>; bank-name = "E"; + + pch_pinctrl@0 { + compatible = "intel,x86-pinctrl"; + io-base = <0x4c>; + + /* GPIO E0 */ + soc_gpio_s5_0@0 { + gpio-offset = <0>; + pad-offset = <0x1d0>; + mode-gpio; + output-value = <0>; + direction = <PIN_OUTPUT>; + }; + + /* GPIO E1 */ + soc_gpio_s5_1@0 { + gpio-offset = <1>; + pad-offset = <0x210>; + mode-gpio; + output-value = <0>; + direction = <PIN_OUTPUT>; + }; + + /* GPIO E2 */ + soc_gpio_s5_2@0 { + gpio-offset = <2>; + pad-offset = <0x1e0>; + mode-gpio; + output-value = <0>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en0@0 { + gpio-offset = <8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1@0 { + gpio-offset = <9>; + pad-offset = <0x250>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; }; gpiof { diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h index ed85b08..1099427 100644 --- a/arch/x86/include/asm/gpio.h +++ b/arch/x86/include/asm/gpio.h @@ -147,7 +147,6 @@ struct pch_gpio_map { } set3; }; -int gpio_ich6_pinctrl_init(void); void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio); void ich_gpio_set_gpio_map(const struct pch_gpio_map *map); diff --git a/board/intel/minnowmax/minnowmax.c b/board/intel/minnowmax/minnowmax.c index 44e5bf4..ae06cc4 100644 --- a/board/intel/minnowmax/minnowmax.c +++ b/board/intel/minnowmax/minnowmax.c @@ -5,12 +5,17 @@ */ #include <common.h> +#include <dm.h> #include <asm/gpio.h> int arch_early_init_r(void) { - /* do the pin-muxing */ - gpio_ich6_pinctrl_init(); + struct udevice *dev; + + /* Force initialization of gpio so initial states are set correctly. */ + for (uclass_first_device(UCLASS_GPIO, &dev); + dev; + uclass_next_device(&dev)); return 0; } diff --git a/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt b/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt new file mode 100644 index 0000000..23345b2 --- /dev/null +++ b/doc/device-tree-bindings/gpio/intel,ich6-gpio.txt @@ -0,0 +1,14 @@ +Intel x86 GPIO controller + +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. + +Example: +gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; +}; diff --git a/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt b/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt index 45ab1af..eb9c8da 100644 --- a/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt +++ b/doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt @@ -1,7 +1,7 @@ -Intel x86 PINCTRL/GPIO controller +Intel x86 PINCTRL -Pin-muxing on x86 can be described with a node for the PINCTRL master -node and a set of child nodes for each pin on the SoC. +Pin-muxing on x86 can be described under each GPIO bank with a node for the +PINCTRL master node and a set of child nodes for each pin on the SoC. The PINCTRL master node requires the following properties: - compatible : "intel,x86-pinctrl" @@ -9,13 +9,12 @@ The PINCTRL master node requires the following properties: Pin nodes must be children of the pinctrl master node and can contain the following properties: - pad-offset - (required) offset in the IOBASE for the pin to configured. -- gpio-offset - (required) offset in the GPIOBASE for the pin to configured and - also the bit shift in this register. -- mode-gpio - (optional) standalone property to force the pin into GPIO mode. -- mode-func - (optional) function number to assign to the pin. if 'mode-gpio' +- gpio-offset - (required) bit shift in the GPIO register. +- mode-gpio - (optional) standalone property to force the pin into GPIO mode. +- mode-func - (optional) function number to assign to the pin. if 'mode-gpio' is set, this property will be ignored. in case of 'mode-gpio' property set: -- output-value - (optional) this set the default output value of the GPIO. +- output-value - (optional) this set the default output value of the GPIO. - direction - (optional) this set the direction of the gpio. - pull-str - (optional) this set the pull strength of the pin. - pull-assign - (optional) this set the pull assignement (up/down) of the pin. @@ -23,7 +22,7 @@ in case of 'mode-gpio' property set: Example: pin_usb_host_en0@0 { - gpio-offset = <0x80 8>; + gpio-offset = <8>; pad-offset = <0x260>; mode-gpio; output-value = <1>; diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c index 67bf0a2..18420f3 100644 --- a/drivers/gpio/intel_ich6_gpio.c +++ b/drivers/gpio/intel_ich6_gpio.c @@ -41,15 +41,11 @@ DECLARE_GLOBAL_DATA_PTR; struct ich6_bank_priv { /* These are I/O addresses */ - uint16_t use_sel; - uint16_t io_sel; - uint16_t lvl; + u16 use_sel; + u16 io_sel; + u16 lvl; }; -#define GPIO_USESEL_OFFSET(x) (x) -#define GPIO_IOSEL_OFFSET(x) (x + 4) -#define GPIO_LVL_OFFSET(x) (x + 8) - #define IOPAD_MODE_MASK 0x7 #define IOPAD_PULL_ASSIGN_SHIFT 7 #define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT) @@ -147,92 +143,90 @@ static int gpio_ich6_get_base(unsigned long base) return tmplong & 1 ? tmplong & ~3 : tmplong & ~15; } -static int _ich6_gpio_set_value(uint16_t base, unsigned offset, int value) + +static int ich6_gpio_set_value(struct udevice *dev, unsigned offset, + int value) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 val; - val = inl(base); + val = inl(bank->lvl); if (value) val |= (1UL << offset); else val &= ~(1UL << offset); - outl(val, base); + outl(val, bank->lvl); return 0; } -static int _ich6_gpio_set_function(uint16_t base, unsigned offset, int func) +static int ich6_gpio_set_function(struct udevice *dev, unsigned offset, + int func) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 val; if (func) { - val = inl(base); + val = inl(bank->use_sel); val |= (1UL << offset); - outl(val, base); + outl(val, bank->use_sel); } else { - val = inl(base); + val = inl(bank->use_sel); val &= ~(1UL << offset); - outl(val, base); + outl(val, bank->use_sel); } return 0; } -static int _ich6_gpio_set_direction(uint16_t base, unsigned offset, int dir) +static int ich6_gpio_set_direction(struct udevice *dev, unsigned offset, + int dir) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 val; if (!dir) { - val = inl(base); + val = inl(bank->io_sel); val |= (1UL << offset); - outl(val, base); + outl(val, bank->io_sel); } else { - val = inl(base); + val = inl(bank->io_sel); val &= ~(1UL << offset); - outl(val, base); + outl(val, bank->io_sel); } return 0; } -static int _gpio_ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node) +static int _gpio_ich6_pinctrl_cfg_pin(struct udevice *dev, s32 iobase, + int pin_node) { - u32 gpio_offset[2]; + int gpio_offset; int pad_offset; int val; - int ret; const void *prop; /* * GPIO node is not mandatory, so we only do the * pinmuxing if the node exist. */ - ret = fdtdec_get_int_array(gd->fdt_blob, pin_node, "gpio-offset", - gpio_offset, 2); - if (!ret) { + gpio_offset = fdtdec_get_int(gd->fdt_blob, pin_node, "gpio-offset", -1); + if (gpio_offset != -1) { /* Do we want to force the GPIO mode? */ prop = fdt_getprop(gd->fdt_blob, pin_node, "mode-gpio", NULL); if (prop) - _ich6_gpio_set_function(GPIO_USESEL_OFFSET - (gpiobase) + - gpio_offset[0], - gpio_offset[1], 1); + ich6_gpio_set_function(dev, gpio_offset, 1); val = fdtdec_get_int(gd->fdt_blob, pin_node, "direction", -1); if (val != -1) - _ich6_gpio_set_direction(GPIO_IOSEL_OFFSET - (gpiobase) + - gpio_offset[0], - gpio_offset[1], val); + ich6_gpio_set_direction(dev, gpio_offset, val); val = fdtdec_get_int(gd->fdt_blob, pin_node, "output-value", -1); if (val != -1) - _ich6_gpio_set_value(GPIO_LVL_OFFSET(gpiobase) - + gpio_offset[0], - gpio_offset[1], val); + ich6_gpio_set_value(dev, gpio_offset, val); } /* if iobase is present, let's configure the pad */ @@ -286,30 +280,19 @@ static int _gpio_ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node) return 0; } -int gpio_ich6_pinctrl_init(void) +static int gpio_ich6_pinctrl_init(struct udevice *dev) { int pin_node; int node; int ret; - int gpiobase; int iobase_offset; int iobase = -1; - - /* - * Get the memory/io base address to configure every pins. - * IOBASE is used to configure the mode/pads - * GPIOBASE is used to configure the direction and default value - */ - gpiobase = gpio_ich6_get_base(PCI_CFG_GPIOBASE); - if (gpiobase < 0) { - debug("%s: invalid GPIOBASE address (%08x)\n", __func__, - gpiobase); - return -EINVAL; - } + int depth = 0; /* This is not an error to not have a pinctrl node */ node = - fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_INTEL_X86_PINCTRL); + fdtdec_next_compatible_subnode(gd->fdt_blob, dev->of_offset, + COMPAT_INTEL_X86_PINCTRL, &depth); if (node <= 0) { debug("%s: no pinctrl node\n", __func__); return 0; @@ -335,7 +318,7 @@ int gpio_ich6_pinctrl_init(void) pin_node > 0; pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) { /* Configure the pin */ - ret = _gpio_ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node); + ret = _gpio_ich6_pinctrl_cfg_pin(dev, iobase, pin_node); if (ret != 0) { debug("%s: invalid configuration for the pin %d\n", __func__, pin_node); @@ -382,6 +365,8 @@ static int ich6_gpio_probe(struct udevice *dev) bank->io_sel = plat->base_addr + 4; bank->lvl = plat->base_addr + 8; + gpio_ich6_pinctrl_init(dev); + return 0; } @@ -408,22 +393,19 @@ static int ich6_gpio_request(struct udevice *dev, unsigned offset, static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset) { - struct ich6_bank_priv *bank = dev_get_priv(dev); - - return _ich6_gpio_set_direction(bank->io_sel, offset, 0); + return ich6_gpio_set_direction(dev, offset, 0); } static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset, int value) { int ret; - struct ich6_bank_priv *bank = dev_get_priv(dev); - ret = _ich6_gpio_set_direction(bank->io_sel, offset, 1); + ret = ich6_gpio_set_direction(dev, offset, 1); if (ret) return ret; - return _ich6_gpio_set_value(bank->lvl, offset, value); + return ich6_gpio_set_value(dev, offset, value); } static int ich6_gpio_get_value(struct udevice *dev, unsigned offset) @@ -437,13 +419,6 @@ static int ich6_gpio_get_value(struct udevice *dev, unsigned offset) return r; } -static int ich6_gpio_set_value(struct udevice *dev, unsigned offset, - int value) -{ - struct ich6_bank_priv *bank = dev_get_priv(dev); - return _ich6_gpio_set_value(bank->lvl, offset, value); -} - static int ich6_gpio_get_function(struct udevice *dev, unsigned offset) { struct ich6_bank_priv *bank = dev_get_priv(dev); -- 2.5.0 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot