x86: support of pin-muxing from device tree
Subsystems (4)
cover x86: support of pin-muxing from device tree
This serie of patches adds the support of pin-muxing from the device tree through different properties. I have put two example to enable the USB Host on the minnowboard max.
The support of the call to 'setup_pch_gpios' is still supported and only the minnowboard has been tested with the device tree implementation.
Because the GPIO and IO base register ares different, I have also defined some proxy function to set the function/value and direction of the GPIO as the GPIO register can override some registers in the IO.
Gabriel Huau (4):
x86: baytrail: fix the GPIOBASE address
x86: minnowmax: add GPIO banks in the device tree
x86: gpio: add pinctrl support from the device tree
x86: minnowmax: initialize the pin-muxing from device tree
arch/x86/dts/minnowmax.dts | 63 +++++++++ arch/x86/include/asm/arch-baytrail/gpio.h | 3 +- arch/x86/include/asm/gpio.h | 1 + board/intel/minnowmax/minnowmax.c | 9 ++ drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/configs/minnowmax.h | 1 + include/dt-bindings/gpio/gpio.h | 20 +++ 7 files changed, 292 insertions(+), 27 deletions(-)
Signature · 1 line
2.1.4
PATCH 1/4 x86: baytrail: fix the GPIOBASE address
--- arch/x86/include/asm/arch-baytrail/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/arch-baytrail/gpio.h +1 -1
@@ -8,6 +8,6 @@#define _X86_ARCH_GPIO_H_/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x44 +#define PCI_CFG_GPIOBASE 0x48#endif /* _X86_ARCH_GPIO_H_ */
Signature · 1 line
2.1.4
[U-Boot] unassigned-patches/139: [PATCH 1/4] x86: baytrail: fix the GPIOBASE address
---
Added to GNATS database as unassigned-patches/139
Quoted 5 lines
Responsible: patch-coord Message-Id: <[email protected]> In-Reply-To: <[email protected]> References: <[email protected]> Patch-Date: Thu Apr 23 18:16:12 +0200 2015
--- arch/x86/include/asm/arch-baytrail/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/arch-baytrail/gpio.h +1 -1
@@ -8,6 +8,6 @@#define _X86_ARCH_GPIO_H_/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x44 +#define PCI_CFG_GPIOBASE 0x48#endif /* _X86_ARCH_GPIO_H_ */
Signature · 1 line
2.1.4
PATCH 1/4 x86: baytrail: fix the GPIOBASE address
In reply to Gabriel HuauQuoted 10 lines · Gabriel Huau
Signed-off-by Gabriel Huau <[email protected]>--- arch/x86/include/asm/arch-baytrail/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/x86/include/asm/arch-baytrail/gpio.h +0
-0
arch/x86/include/asm/arch-baytrail/gpio.h
Quoted 8 lines
arch/x86/include/asm/arch-baytrail/gpio.h +1
-2@@ -8,6 +8,6 @@#define _X86_ARCH_GPIO_H_/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x44 +#define PCI_CFG_GPIOBASE 0x48#endif /* _X86_ARCH_GPIO_H_ */ --
PATCH 1/4 x86: baytrail: fix the GPIOBASE address
Hi Gabriel,
Quoted 2 lines · Bin Meng
Quoted 1 line · Gabriel Huau
Signed-off-by Gabriel Huau <[email protected]>
Can you please add a commit message?
Quoted 11 lines
Quoted 11 lines
--- arch/x86/include/asm/arch-baytrail/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/x86/include/asm/arch-baytrail/gpio.h +0
-0@@ -8,6 +8,6 @@#define _X86_ARCH_GPIO_H_
Quoted 8 lines
arch/x86/include/asm/arch-baytrail/gpio.h
Quoted 6 lines
arch/x86/include/asm/arch-baytrail/gpio.h +1
-2/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x44 +#define PCI_CFG_GPIOBASE 0x48#endif /* _X86_ARCH_GPIO_H_ */ --Reviewed-by Bin Meng <[email protected]>
Regards,
Simon
PATCH v2 1/5 x86: baytrail: fix the GPIOBASE address
In reply to Gabriel HuauThe correct GPIOBASE address on the baytrail is 0x48
---
Changes for v2:
- Add a commit message
arch/x86/include/asm/arch-baytrail/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/arch-baytrail/gpio.h +1 -1
@@ -8,6 +8,6 @@#define _X86_ARCH_GPIO_H_/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x44 +#define PCI_CFG_GPIOBASE 0x48#endif /* _X86_ARCH_GPIO_H_ */
Signature · 1 line
2.1.4
PATCH v3 1/4 x86: baytrail: fix the GPIOBASE address
In reply to Gabriel HuauThe correct GPIOBASE address on the baytrail is 0x48
---
Changes for v2:
- Add a commit message
Changes for v3:
- Fix patch number
arch/x86/include/asm/arch-baytrail/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/arch-baytrail/gpio.h +1 -1
@@ -8,6 +8,6 @@#define _X86_ARCH_GPIO_H_/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x44 +#define PCI_CFG_GPIOBASE 0x48#endif /* _X86_ARCH_GPIO_H_ */
Signature · 1 line
2.1.4
PATCH v3 1/4 x86: baytrail: fix the GPIOBASE address
Hi Gabriel,
Quoted 4 lines · Gabriel Huau
The correct GPIOBASE address on the baytrail is
0x48Signed-off-by Gabriel Huau <[email protected]>---
Please edit your commit message in the v2 to include such tags like Acked-by, Reviewed-by, etc so that we know the patch status.
Quoted 14 lines
Changes for v2:
- Add a commit messageChanges for v3:
- Fix patch numberarch/x86/include/asm/arch-baytrail/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/x86/include/asm/arch-baytrail/gpio.h +0
-0
arch/x86/include/asm/arch-baytrail/gpio.h
Quoted 8 lines
arch/x86/include/asm/arch-baytrail/gpio.h +1
-2@@ -8,6 +8,6 @@#define _X86_ARCH_GPIO_H_/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x44 +#define PCI_CFG_GPIOBASE 0x48#endif /* _X86_ARCH_GPIO_H_ */ --
Regards,
Bin
PATCH v3 1/4 x86: baytrail: fix the GPIOBASE address
Quoted 9 lines · Bin Meng
Hi Gabriel,
Quoted 4 lines · Gabriel Huau
The correct GPIOBASE address on the baytrail is
0x48Signed-off-by Gabriel Huau <[email protected]>---
Reviewed-by Bin Meng <[email protected]>
Quoted 3 lines
Please edit your commit message in the v2 to include such tags like Acked-by, Reviewed-by, etc so that we know the patch status.
Also you could take a look at patman which automates the creation of change lists, checking patches, etc.
Quoted 21 lines
Quoted 21 lines
Changes for v2:
- Add a commit messageChanges for v3:
- Fix patch numberarch/x86/include/asm/arch-baytrail/gpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/x86/include/asm/arch-baytrail/gpio.h +1
-1@@ -8,6 +8,6 @@#define _X86_ARCH_GPIO_H_/* Where in config space is the register that points to the GPIO registers? */ -#define PCI_CFG_GPIOBASE 0x44 +#define PCI_CFG_GPIOBASE 0x48
Quoted 5 lines
arch/x86/include/asm/arch-baytrail/gpio.h
Quoted 2 lines
arch/x86/include/asm/arch-baytrail/gpio.h +0
-1#endif /* _X86_ARCH_GPIO_H_ */ --Regards,
Bin
Regards,
Simon
PATCH v3 1/4 x86: baytrail: fix the GPIOBASE address
Quoted 4 lines · Simon Glass
Quoted 3 lines · Bin Meng
Hi Gabriel,
On Sun, Apr 26, 2015 at 4:16 AM, Gabriel Huau <[email protected]> wrote:
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
The correct GPIOBASE address on the baytrail is
0x48Signed-off-by Gabriel Huau <[email protected]>---
Reviewed-by Bin Meng <[email protected]>Acked-by Simon Glass <[email protected]>
Applied to u-boot-x86, thanks!
PATCH 2/4 x86: minnowmax: add GPIO banks in the device tree
In reply to Gabriel HuauThere is 6 banks:
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 mode
--- arch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
arch/x86/dts/minnowmax.dts +42 -0
@@ -21,6 +21,48 @@ silent_console = <0>; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F"; + }; + chosen { stdout-path = "/serial"; };
Signature · 1 line
2.1.4
[U-Boot] unassigned-patches/140: [PATCH 2/4] x86: minnowmax: add GPIO banks in the device tree
There is 6 banks:
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 mode
---
Added to GNATS database as unassigned-patches/140
Quoted 5 lines
Responsible: patch-coord Message-Id: <[email protected]> In-Reply-To: <[email protected]> References: <[email protected]> Patch-Date: Thu Apr 23 18:16:13 +0200 2015
--- arch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
arch/x86/dts/minnowmax.dts +42 -0
@@ -21,6 +21,48 @@ silent_console = <0>; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F"; + }; + chosen { stdout-path = "/serial"; };
Signature · 1 line
2.1.4
PATCH 2/4 x86: minnowmax: add GPIO banks in the device tree
In reply to Gabriel HuauHi Gabriel,
Quoted 1 line · Gabriel Huau
There is 6 banks:
There are
Quoted 52 lines
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 modeSigned-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)arch/x86/dts/minnowmax.dts +36
-0@@ -21,6 +21,48 @@ silent_console = <0>; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof {
arch/x86/dts/minnowmax.dts
Quoted 10 lines
arch/x86/dts/minnowmax.dts +6
-1+ compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F"; + }; + chosen { stdout-path = "/serial"; }; --
[U-Boot] unassigned-patches/146: Re: [PATCH 2/4] x86: minnowmax: add GPIO banks in the device tree
Hi Gabriel,
Quoted 1 line · Gabriel Huau
There is 6 banks:
There are
Quoted 52 lines
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 modeSigned-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)arch/x86/dts/minnowmax.dts +36
-0@@ -21,6 +21,48 @@ silent_console = <0>; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof {
arch/x86/dts/minnowmax.dts
Quoted 10 lines
arch/x86/dts/minnowmax.dts +6
-1+ compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F"; + }; + chosen { stdout-path = "/serial"; }; --
---
Added to GNATS database as unassigned-patches/146
Quoted 5 lines
Responsible: patch-coord Message-Id: <CAEUhbmXfHVYw79-NxfjT3ykpuiYSp0-k+WN518qWteTJoytx3Q@mail.gmail.com> In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> Patch-Date: Fri Apr 24 04:03:19 +0200 2015
PATCH 2/4 x86: minnowmax: add GPIO banks in the device tree
In reply to Gabriel HuauQuoted 8 lines · Gabriel Huau
There is 6 banks:
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 modeSigned-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
[U-Boot] unassigned-patches/147: Re: [PATCH 2/4] x86: minnowmax: add GPIO banks in the device tree
Quoted 8 lines · Gabriel Huau
There is 6 banks:
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 modeSigned-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
---
Added to GNATS database as unassigned-patches/147
Quoted 5 lines
Responsible: patch-coord Message-Id: <CAPnjgZ2nJnkhFvLuxW01YX1B1u8HKTGPA=dLwOHhpDjv9iDs=A@mail.gmail.com> In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> Patch-Date: Fri Apr 24 05:26:17 +0200 2015
PATCH v2 2/4 x86: minnowmax: add GPIO banks in the device tree
In reply to Gabriel HuauThere are 6 banks:
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 mode
---
Changes for v2:
- Fix typo in the commit message
arch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
arch/x86/dts/minnowmax.dts +42 -0
@@ -21,6 +21,48 @@ silent_console = <0>; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F"; + }; + chosen { stdout-path = "/serial"; };
Signature · 1 line
2.1.4
PATCH v2 2/4 x86: minnowmax: add GPIO banks in the device tree
Quoted 56 lines · Gabriel Huau
There are 6 banks:
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 modeSigned-off-by Gabriel Huau <[email protected]>---
Changes for v2:
- Fix typo in the commit messagearch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)arch/x86/dts/minnowmax.dts +36
-0@@ -21,6 +21,48 @@ silent_console = <0>; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof {
arch/x86/dts/minnowmax.dts
Quoted 10 lines
arch/x86/dts/minnowmax.dts +6
-1+ compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F"; + }; + chosen { stdout-path = "/serial"; }; --
PATCH v2 2/4 x86: minnowmax: add GPIO banks in the device tree
Quoted 61 lines · Bin Meng
Quoted 60 lines · Gabriel Huau
There are 6 banks:
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 modeSigned-off-by Gabriel Huau <[email protected]>---
Changes for v2:
- Fix typo in the commit messagearch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)arch/x86/dts/minnowmax.dts +40
-0@@ -21,6 +21,48 @@ silent_console = <0>; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F";
Quoted 8 lines
arch/x86/dts/minnowmax.dts
Quoted 6 lines
arch/x86/dts/minnowmax.dts +2
-1+ }; + chosen { stdout-path = "/serial"; }; --Reviewed-by Bin Meng <[email protected]>
PATCH v2 2/4 x86: minnowmax: add GPIO banks in the device tree
Quoted 6 lines · Simon Glass
Quoted 5 lines · Bin Meng
Quoted 4 lines · Gabriel Huau
There are 6 banks:
4 banks for CORE: available in S0 mode
2 banks for SUS (Suspend): available in S0-S5 mode
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Signed-off-by Gabriel Huau <[email protected]>---
Changes for v2:
- Fix typo in the commit messagearch/x86/dts/minnowmax.dts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
Applied to u-boot-x86, thanks!
Quoted 59 lines
Quoted 49 lines
Quoted 49 lines
arch/x86/dts/minnowmax.dts +40
-0@@ -21,6 +21,48 @@ silent_console = <0>; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F";Quoted 8 lines
arch/x86/dts/minnowmax.dts
Quoted 6 lines
arch/x86/dts/minnowmax.dts +2
-1+ }; + chosen { stdout-path = "/serial"; }; --Reviewed-by Bin Meng <[email protected]>Acked-by Simon Glass <[email protected]>
PATCH 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Gabriel HuauA set of properties has been defined for the device tree to select for each pin the pull/func/default output configuration.
The offset for the PAD needs to be provided and if a GPIO needs to be configured, his offset needs to be provided as well.
Here is an example:
pin_usb_host_en0 at 0 {
gpio-offset = <0x80 8>;
pad-offset = <0x260>;
mode-gpio;
output-value = <1>;
direction = <PIN_OUTPUT>;
};--- arch/x86/dts/minnowmax.dts | 21 +++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/dt-bindings/gpio/gpio.h | 20 +++ 5 files changed, 239 insertions(+), 26 deletions(-)
arch/x86/dts/minnowmax.dts +21 -0
@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,ich6-pinctrl"; + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;
arch/x86/include/asm/arch-baytrail/gpio.h +1 -0
@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */
arch/x86/include/asm/gpio.h +1 -0
@@ -147,6 +147,7 @@ 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);
drivers/gpio/intel_ich6_gpio.c +196 -26
287 lines not on this page · raw message
include/dt-bindings/gpio/gpio.h +20 -0
@@ -12,4 +12,24 @@#define GPIO_ACTIVE_HIGH 0#define GPIO_ACTIVE_LOW 1 +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 +#endif
Signature · 1 line
2.1.4
[U-Boot] unassigned-patches/138: [PATCH 3/4] x86: gpio: add pinctrl support from the device tree
A set of properties has been defined for the device tree to select for each pin the pull/func/default output configuration.
The offset for the PAD needs to be provided and if a GPIO needs to be configured, his offset needs to be provided as well.
Here is an example:
pin_usb_host_en0 at 0 {
gpio-offset = <0x80 8>;
pad-offset = <0x260>;
mode-gpio;
output-value = <1>;
direction = <PIN_OUTPUT>;
};---
Added to GNATS database as unassigned-patches/138
Quoted 5 lines
Responsible: patch-coord Message-Id: <[email protected]> In-Reply-To: <[email protected]> References: <[email protected]> Patch-Date: Thu Apr 23 18:16:14 +0200 2015
--- arch/x86/dts/minnowmax.dts | 21 +++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/dt-bindings/gpio/gpio.h | 20 +++ 5 files changed, 239 insertions(+), 26 deletions(-)
arch/x86/dts/minnowmax.dts +21 -0
@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,ich6-pinctrl"; + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;
arch/x86/include/asm/arch-baytrail/gpio.h +1 -0
@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */
arch/x86/include/asm/gpio.h +1 -0
@@ -147,6 +147,7 @@ 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);
drivers/gpio/intel_ich6_gpio.c +196 -26
287 lines not on this page · raw message
include/dt-bindings/gpio/gpio.h +20 -0
@@ -12,4 +12,24 @@#define GPIO_ACTIVE_HIGH 0#define GPIO_ACTIVE_LOW 1 +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 +#endif
Signature · 1 line
2.1.4
PATCH 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Gabriel HuauHi Gabriel,
Quoted 38 lines · Gabriel Huau
A set of properties has been defined for the device tree to select for each pin the pull/func/default output configuration.
The offset for the PAD needs to be provided and if a GPIO needs to be configured, his offset needs to be provided as well.
Here is an example:
pin_usb_host_en0 at 0 { gpio-offset = <0x80 8>; pad-offset = <0x260>; mode-gpio; output-value = <1>; direction = <PIN_OUTPUT>; };Signed-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 21 +++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/dt-bindings/gpio/gpio.h | 20 +++ 5 files changed, 239 insertions(+), 26 deletions(-)arch/x86/dts/minnowmax.dts +2
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
arch/x86/dts/minnowmax.dts line 27
Quoted 5 lines
arch/x86/dts/minnowmax.dts +2
-0@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,ich6-pinctrl";
I guess the prefix 'ich6' is debatable.
Quoted 107 lines
arch/x86/dts/minnowmax.dts +17
-0+ pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/arch-baytrail/gpio.h +1
-0@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */ arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);drivers/gpio/intel_ich6_gpio.c +22
-7@@ -44,21 +44,32 @@ struct ich6_bank_priv {uint16_t 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_MASK 0x3 +#define IOPAD_PULL_ASSIGN_SHIFT 7 +#define IOPAD_PULL_STRENGTH_MASK 0x3 +#define IOPAD_PULL_STRENGTH_SHIFT 9 + +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value); +static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir); +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func); +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev);pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE ); + tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }@@ -135,7 +146,138 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +int pin_node;
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 164
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+int node; +u32 iobase; +u32 gpiobase; + +/* +* 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 +*/ + iobase =gpio_ich6_get_base (PCI_CFG_IOBASE );
I believe this breaks other x86 boards as PCI_CFG_IOBASE is baytrail-specific.
Quoted 242 lines
drivers/gpio/intel_ich6_gpio.c +163
-19+if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + +/* This is not an error to not have a pinctrl node */ + node =fdt_node_offset_by_compatible (gd->fdt_blob,-1 , +"intel,ich6-pinctrl" ); +if (node <0 ) +return 0 ; + +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + pin_node >0 ; + pin_node =fdt_next_subnode (gd->fdt_blob, pin_node)) { +u32 gpio_offset[2 ] = {-1 ,-1 }; +u32 pad_offset; +u32 tmplong; +const void *tmpnode; + +/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset =fdtdec_get_int (gd->fdt_blob, pin_node, +"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset); +return -EINVAL ; + } + +/* +* GPIO node is not mandatory, so we only do the +* pinmuxing if the node exist. +*/ +fdtdec_get_int_array (gd->fdt_blob, pin_node, +"gpio-offset" , gpio_offset,2 ); +if (gpio_offset[0 ] !=-1 ) { +/* Do we want to force the GPIO mode? */ + tmpnode =fdt_getprop (gd->fdt_blob, pin_node, +"mode-gpio" ,NULL ); +if (tmpnode) +__ich6_gpio_set_function (GPIO_USESEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ],1 ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"direction" , +-1 ); +if (tmplong !=-1 ) +__ich6_gpio_set_direction (GPIO_IOSEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], + tmplong); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node, +"output-value" ,-1 ); +if (tmplong !=-1 ) +__ich6_gpio_set_value (GPIO_LVL_OFFSET (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + } + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset,IOPAD_MODE_MASK , + tmplong); + +/* Configure the pull-up/down if needed */ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_ASSIGN_MASK << +IOPAD_PULL_ASSIGN_SHIFT , + tmplong <<IOPAD_PULL_ASSIGN_SHIFT ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_STRENGTH_MASK << +IOPAD_PULL_STRENGTH_SHIFT , + tmplong <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase + pad_offset)); + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -189,33 +331,56 @@ static int ich6_gpio_request(struct udevice *dev, unsigned offset,return 0 ; } -static int ich6_gpio_direction_input (struct udevice *dev,unsigned offset) +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); +if (func) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } +return 0 ; } -static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, -int value) +static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; -gpio_set_value (offset, value); +if (!dir) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong);return 0 ; } -static int ich6_gpio_get_value (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 (inl (bank->io_sel), offset,0 ); +} + +static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, +int value) +{ +struct ich6_bank_priv *bank =dev_get_priv (dev); + +return __ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); +} +static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -226,21 +391,26 @@ 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) +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - - tmplong =inl (bank->lvl); + tmplong =inl (base);if (value) tmplong |= (1UL << offset);else tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); +outl (tmplong, base); +return 0 ; } +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);include/dt-bindings/gpio/gpio.h +12
-0@@ -12,4 +12,24 @@#define GPIO_ACTIVE_HIGH 0#define GPIO_ACTIVE_LOW 1 +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1
include/dt-bindings/gpio/gpio.h
Quoted 10 lines
include/dt-bindings/gpio/gpio.h +8
-1+ +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 +#endif --
Regards,
Bin
PATCH 3/4 x86: gpio: add pinctrl support from the device tree
Quoted 40 lines · Bin Meng
Hi Gabriel,
Quoted 37 lines · Gabriel Huau
A set of properties has been defined for the device tree to select for each pin the pull/func/default output configuration.
The offset for the PAD needs to be provided and if a GPIO needs to be configured, his offset needs to be provided as well.
Here is an example:
pin_usb_host_en0 at 0 { gpio-offset = <0x80 8>; pad-offset = <0x260>; mode-gpio; output-value = <1>; direction = <PIN_OUTPUT>; };Signed-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 21 +++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/dt-bindings/gpio/gpio.h | 20 +++ 5 files changed, 239 insertions(+), 26 deletions(-)arch/x86/dts/minnowmax.dts +2
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
Quoted 8 lines
arch/x86/dts/minnowmax.dts line 27
Quoted 6 lines
arch/x86/dts/minnowmax.dts +2
-0@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,ich6-pinctrl";I guess the prefix 'ich6' is debatable.
I hesitated with 'x86' but I'm open to any suggestion.
Quoted 110 lines
Quoted 110 lines
arch/x86/dts/minnowmax.dts +17
-0+ pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/arch-baytrail/gpio.h +1
-0@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */ arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);drivers/gpio/intel_ich6_gpio.c +25
-7@@ -44,21 +44,32 @@ struct ich6_bank_priv {uint16_t 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_MASK 0x3 +#define IOPAD_PULL_ASSIGN_SHIFT 7 +#define IOPAD_PULL_STRENGTH_MASK 0x3 +#define IOPAD_PULL_STRENGTH_SHIFT 9 + +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value); +static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir); +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func); +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev);pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE ); + tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }@@ -135,7 +146,138 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +int pin_node; +int node; +u32 iobase; +u32 gpiobase;
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 164
Quoted 7 lines
drivers/gpio/intel_ich6_gpio.c +7
-0+ +/* +* 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 +*/ + iobase =gpio_ich6_get_base (PCI_CFG_IOBASE );I believe this breaks other x86 boards as
PCI_CFG_IOBASEis baytrail-specific.
Well ... good point :). As Simon suggested, I might put the IOBASE into the device tree.
Quoted 254 lines
Quoted 242 lines
drivers/gpio/intel_ich6_gpio.c +163
-19+if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + +/* This is not an error to not have a pinctrl node */ + node =fdt_node_offset_by_compatible (gd->fdt_blob,-1 , +"intel,ich6-pinctrl" ); +if (node <0 ) +return 0 ; + +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + pin_node >0 ; + pin_node =fdt_next_subnode (gd->fdt_blob, pin_node)) { +u32 gpio_offset[2 ] = {-1 ,-1 }; +u32 pad_offset; +u32 tmplong; +const void *tmpnode; + +/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset =fdtdec_get_int (gd->fdt_blob, pin_node, +"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset); +return -EINVAL ; + } + +/* +* GPIO node is not mandatory, so we only do the +* pinmuxing if the node exist. +*/ +fdtdec_get_int_array (gd->fdt_blob, pin_node, +"gpio-offset" , gpio_offset,2 ); +if (gpio_offset[0 ] !=-1 ) { +/* Do we want to force the GPIO mode? */ + tmpnode =fdt_getprop (gd->fdt_blob, pin_node, +"mode-gpio" ,NULL ); +if (tmpnode) +__ich6_gpio_set_function (GPIO_USESEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ],1 ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"direction" , +-1 ); +if (tmplong !=-1 ) +__ich6_gpio_set_direction (GPIO_IOSEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], + tmplong); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node, +"output-value" ,-1 ); +if (tmplong !=-1 ) +__ich6_gpio_set_value (GPIO_LVL_OFFSET (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + } + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset,IOPAD_MODE_MASK , + tmplong); + +/* Configure the pull-up/down if needed */ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_ASSIGN_MASK << +IOPAD_PULL_ASSIGN_SHIFT , + tmplong <<IOPAD_PULL_ASSIGN_SHIFT ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_STRENGTH_MASK << +IOPAD_PULL_STRENGTH_SHIFT , + tmplong <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase + pad_offset)); + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -189,33 +331,56 @@ static int ich6_gpio_request(struct udevice *dev, unsigned offset,return 0 ; } -static int ich6_gpio_direction_input (struct udevice *dev,unsigned offset) +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); +if (func) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } +return 0 ; } -static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, -int value) +static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; -gpio_set_value (offset, value); +if (!dir) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong);return 0 ; } -static int ich6_gpio_get_value (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 (inl (bank->io_sel), offset,0 ); +} + +static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, +int value) +{ +struct ich6_bank_priv *bank =dev_get_priv (dev); + +return __ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); +} +static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -226,21 +391,26 @@ 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) +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - - tmplong =inl (bank->lvl); + tmplong =inl (base);if (value) tmplong |= (1UL << offset);else tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); +outl (tmplong, base); +return 0 ; } +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);include/dt-bindings/gpio/gpio.h +12
-0@@ -12,4 +12,24 @@#define GPIO_ACTIVE_HIGH 0#define GPIO_ACTIVE_LOW 1 +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1include/dt-bindings/gpio/gpio.h
Quoted 10 lines
include/dt-bindings/gpio/gpio.h +8
-1+ +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 +#endif --Regards,
Bin
PATCH 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Gabriel HuauHi,
Quoted 38 lines · Gabriel Huau
A set of properties has been defined for the device tree to select for each pin the pull/func/default output configuration.
The offset for the PAD needs to be provided and if a GPIO needs to be configured, his offset needs to be provided as well.
Here is an example:
pin_usb_host_en0 at 0 { gpio-offset = <0x80 8>; pad-offset = <0x260>; mode-gpio; output-value = <1>; direction = <PIN_OUTPUT>; };Signed-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 21 +++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/dt-bindings/gpio/gpio.h | 20 +++ 5 files changed, 239 insertions(+), 26 deletions(-)arch/x86/dts/minnowmax.dts +2
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
arch/x86/dts/minnowmax.dts line 27
Quoted 5 lines
arch/x86/dts/minnowmax.dts +2
-0@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,ich6-pinctrl";
Make sure you use tabs for indenting here.
You should create a binding file to describe your binding - in doc/device-tree-bindings.
Quoted 48 lines
arch/x86/dts/minnowmax.dts +17
-0+ pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/arch-baytrail/gpio.h +1
-0@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */ arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);drivers/gpio/intel_ich6_gpio.c +0
-0
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 49
Quoted 6 lines
drivers/gpio/intel_ich6_gpio.c +3
-0@@ -44,21 +44,32 @@ struct ich6_bank_priv {uint16_t lvl; }; +#define GPIO_USESEL_OFFSET (x) (x) +#define GPIO_IOSEL_OFFSET (x) (x + 4) +#define GPIO_LVL_OFFSET (x) (x + 8)
Comments on the above
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 53
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+ +#define IOPAD_MODE_MASK 0x7 +#define IOPAD_PULL_ASSIGN_MASK 0x3 +#define IOPAD_PULL_ASSIGN_SHIFT 7
Can you make the mask value an actual valid mask, like:
+#define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT)
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 57
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+#define IOPAD_PULL_STRENGTH_MASK 0x3 +#define IOPAD_PULL_STRENGTH_SHIFT 9 + +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value);
Can you reorder the functions to avoid the need for these forward declarations? Also only one underscore prefix please.
Quoted 23 lines
drivers/gpio/intel_ich6_gpio.c +4
-4+static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir); +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func); +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev);pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 126
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +0
-1@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE );
Can the base come from the device tree somewhere? E.g.
pch {
gpio {
reg = <some value>;There is something like this in chromebook_link.dts.
Quoted 34 lines
drivers/gpio/intel_ich6_gpio.c +24
-2+ tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }@@ -135,7 +146,138 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +int pin_node; +int node; +u32 iobase; +u32 gpiobase; + +/* +* 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 +*/ + iobase =gpio_ich6_get_base (PCI_CFG_IOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE );
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 180
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + +/* This is not an error to not have a pinctrl node */ + node =fdt_node_offset_by_compatible (gd->fdt_blob,-1 , +"intel,ich6-pinctrl" ); +if (node <0 ) +return 0 ;
Probably this should move to driver model, but let's worry about that later.
Quoted 20 lines
drivers/gpio/intel_ich6_gpio.c +20
-0+ +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + pin_node >0 ; + pin_node =fdt_next_subnode (gd->fdt_blob, pin_node)) { +u32 gpio_offset[2 ] = {-1 ,-1 }; +u32 pad_offset; +u32 tmplong; +const void *tmpnode; + +/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset =fdtdec_get_int (gd->fdt_blob, pin_node, +"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset);
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 210
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+return -EINVAL ; + } + +/* +* GPIO node is not mandatory, so we only do the +* pinmuxing if the node exist. +*/ +fdtdec_get_int_array (gd->fdt_blob, pin_node, +"gpio-offset" , gpio_offset,2 ); +if (gpio_offset[0 ] !=-1 ) {
Can you move this block into its own function without too much trouble?
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 223
Quoted 13 lines
drivers/gpio/intel_ich6_gpio.c +13
-0+/* Do we want to force the GPIO mode? */ + tmpnode =fdt_getprop (gd->fdt_blob, pin_node, +"mode-gpio" ,NULL ); +if (tmpnode) +__ich6_gpio_set_function (GPIO_USESEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ],1 ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"direction" , +-1 ); +if (tmplong !=-1 )
But tmplong is unsigned.
Quoted 170 lines
drivers/gpio/intel_ich6_gpio.c +104
-19+__ich6_gpio_set_direction (GPIO_IOSEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], + tmplong); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node, +"output-value" ,-1 ); +if (tmplong !=-1 ) +__ich6_gpio_set_value (GPIO_LVL_OFFSET (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + } + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset,IOPAD_MODE_MASK , + tmplong); + +/* Configure the pull-up/down if needed */ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_ASSIGN_MASK << +IOPAD_PULL_ASSIGN_SHIFT , + tmplong <<IOPAD_PULL_ASSIGN_SHIFT ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_STRENGTH_MASK << +IOPAD_PULL_STRENGTH_SHIFT , + tmplong <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase + pad_offset)); + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -189,33 +331,56 @@ static int ich6_gpio_request(struct udevice *dev, unsigned offset,return 0 ; } -static int ich6_gpio_direction_input (struct udevice *dev,unsigned offset) +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); +if (func) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } +return 0 ; } -static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, -int value) +static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; -gpio_set_value (offset, value); +if (!dir) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong);return 0 ; } -static int ich6_gpio_get_value (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 (inl (bank->io_sel), offset,0 ); +} + +static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, +int value) +{ +struct ich6_bank_priv *bank =dev_get_priv (dev); + +return __ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); +} +static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -226,21 +391,26 @@ 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) +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - - tmplong =inl (bank->lvl); + tmplong =inl (base);if (value) tmplong |= (1UL << offset);else tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); +outl (tmplong, base); +return 0 ; } +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);include/dt-bindings/gpio/gpio.h +0
-0@@ -12,4 +12,24 @@#define GPIO_ACTIVE_HIGH 0#define GPIO_ACTIVE_LOW 1
include/dt-bindings/gpio/gpio.h line 23
Quoted 10 lines
include/dt-bindings/gpio/gpio.h +9
-0+#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6
Can we use an enum for these? They mostly count up.
Quoted 13 lines
include/dt-bindings/gpio/gpio.h +11
-1+ +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 +#endif --
Quoted 2 lines
2.1.4
Regards,
Simon
[U-Boot] unassigned-patches/144: Re: [PATCH 3/4] x86: gpio: add pinctrl support from the device tree
Hi,
Quoted 38 lines · Gabriel Huau
A set of properties has been defined for the device tree to select for each pin the pull/func/default output configuration.
The offset for the PAD needs to be provided and if a GPIO needs to be configured, his offset needs to be provided as well.
Here is an example:
pin_usb_host_en0 at 0 { gpio-offset = <0x80 8>; pad-offset = <0x260>; mode-gpio; output-value = <1>; direction = <PIN_OUTPUT>; };Signed-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 21 +++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/dt-bindings/gpio/gpio.h | 20 +++ 5 files changed, 239 insertions(+), 26 deletions(-)arch/x86/dts/minnowmax.dts +2
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
arch/x86/dts/minnowmax.dts line 27
Quoted 5 lines
arch/x86/dts/minnowmax.dts +2
-0@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,ich6-pinctrl";
Make sure you use tabs for indenting here.
You should create a binding file to describe your binding - in doc/device-tree-bindings.
Quoted 48 lines
arch/x86/dts/minnowmax.dts +17
-0+ pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/arch-baytrail/gpio.h +1
-0@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */ arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);drivers/gpio/intel_ich6_gpio.c +0
-0
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 49
Quoted 6 lines
drivers/gpio/intel_ich6_gpio.c +3
-0@@ -44,21 +44,32 @@ struct ich6_bank_priv {uint16_t lvl; }; +#define GPIO_USESEL_OFFSET (x) (x) +#define GPIO_IOSEL_OFFSET (x) (x + 4) +#define GPIO_LVL_OFFSET (x) (x + 8)
Comments on the above
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 53
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+ +#define IOPAD_MODE_MASK 0x7 +#define IOPAD_PULL_ASSIGN_MASK 0x3 +#define IOPAD_PULL_ASSIGN_SHIFT 7
Can you make the mask value an actual valid mask, like:
+#define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT)
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 57
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+#define IOPAD_PULL_STRENGTH_MASK 0x3 +#define IOPAD_PULL_STRENGTH_SHIFT 9 + +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value);
Can you reorder the functions to avoid the need for these forward declarations? Also only one underscore prefix please.
Quoted 23 lines
drivers/gpio/intel_ich6_gpio.c +4
-4+static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir); +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func); +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev);pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 126
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +0
-1@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE );
Can the base come from the device tree somewhere? E.g.
pch {
gpio {
reg = <some value>;There is something like this in chromebook_link.dts.
Quoted 34 lines
drivers/gpio/intel_ich6_gpio.c +24
-2+ tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }@@ -135,7 +146,138 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +int pin_node; +int node; +u32 iobase; +u32 gpiobase; + +/* +* 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 +*/ + iobase =gpio_ich6_get_base (PCI_CFG_IOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE );
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 180
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + +/* This is not an error to not have a pinctrl node */ + node =fdt_node_offset_by_compatible (gd->fdt_blob,-1 , +"intel,ich6-pinctrl" ); +if (node <0 ) +return 0 ;
Probably this should move to driver model, but let's worry about that later.
Quoted 20 lines
drivers/gpio/intel_ich6_gpio.c +20
-0+ +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + pin_node >0 ; + pin_node =fdt_next_subnode (gd->fdt_blob, pin_node)) { +u32 gpio_offset[2 ] = {-1 ,-1 }; +u32 pad_offset; +u32 tmplong; +const void *tmpnode; + +/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset =fdtdec_get_int (gd->fdt_blob, pin_node, +"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset);
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 210
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+return -EINVAL ; + } + +/* +* GPIO node is not mandatory, so we only do the +* pinmuxing if the node exist. +*/ +fdtdec_get_int_array (gd->fdt_blob, pin_node, +"gpio-offset" , gpio_offset,2 ); +if (gpio_offset[0 ] !=-1 ) {
Can you move this block into its own function without too much trouble?
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 223
Quoted 13 lines
drivers/gpio/intel_ich6_gpio.c +13
-0+/* Do we want to force the GPIO mode? */ + tmpnode =fdt_getprop (gd->fdt_blob, pin_node, +"mode-gpio" ,NULL ); +if (tmpnode) +__ich6_gpio_set_function (GPIO_USESEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ],1 ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"direction" , +-1 ); +if (tmplong !=-1 )
But tmplong is unsigned.
Quoted 170 lines
drivers/gpio/intel_ich6_gpio.c +104
-19+__ich6_gpio_set_direction (GPIO_IOSEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], + tmplong); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node, +"output-value" ,-1 ); +if (tmplong !=-1 ) +__ich6_gpio_set_value (GPIO_LVL_OFFSET (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + } + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset,IOPAD_MODE_MASK , + tmplong); + +/* Configure the pull-up/down if needed */ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_ASSIGN_MASK << +IOPAD_PULL_ASSIGN_SHIFT , + tmplong <<IOPAD_PULL_ASSIGN_SHIFT ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_STRENGTH_MASK << +IOPAD_PULL_STRENGTH_SHIFT , + tmplong <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase + pad_offset)); + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -189,33 +331,56 @@ static int ich6_gpio_request(struct udevice *dev, unsigned offset,return 0 ; } -static int ich6_gpio_direction_input (struct udevice *dev,unsigned offset) +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); +if (func) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } +return 0 ; } -static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, -int value) +static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; -gpio_set_value (offset, value); +if (!dir) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong);return 0 ; } -static int ich6_gpio_get_value (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 (inl (bank->io_sel), offset,0 ); +} + +static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, +int value) +{ +struct ich6_bank_priv *bank =dev_get_priv (dev); + +return __ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); +} +static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -226,21 +391,26 @@ 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) +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - - tmplong =inl (bank->lvl); + tmplong =inl (base);if (value) tmplong |= (1UL << offset);else tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); +outl (tmplong, base); +return 0 ; } +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);include/dt-bindings/gpio/gpio.h +0
-0@@ -12,4 +12,24 @@#define GPIO_ACTIVE_HIGH 0#define GPIO_ACTIVE_LOW 1
include/dt-bindings/gpio/gpio.h line 23
Quoted 10 lines
include/dt-bindings/gpio/gpio.h +9
-0+#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6
Can we use an enum for these? They mostly count up.
Quoted 13 lines
include/dt-bindings/gpio/gpio.h +11
-1+ +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 +#endif --
Quoted 2 lines
2.1.4
Regards,
Simon
---
Added to GNATS database as unassigned-patches/144
Quoted 5 lines
Responsible: patch-coord Message-Id: <CAPnjgZ38cPE1h6EBg-ffdtOA4FhTdgTx8u1VS5yMpv9Ynik-KA@mail.gmail.com> In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> Patch-Date: Fri Apr 24 05:35:00 +0200 2015
PATCH 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Simon GlassHi Simon,
Quoted 151 lines · Simon Glass
Hi,
Quoted 38 lines · Gabriel Huau
A set of properties has been defined for the device tree to select for each pin the pull/func/default output configuration.
The offset for the PAD needs to be provided and if a GPIO needs to be configured, his offset needs to be provided as well.
Here is an example:
pin_usb_host_en0 at 0 { gpio-offset = <0x80 8>; pad-offset = <0x260>; mode-gpio; output-value = <1>; direction = <PIN_OUTPUT>; };Signed-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 21 +++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/dt-bindings/gpio/gpio.h | 20 +++ 5 files changed, 239 insertions(+), 26 deletions(-)arch/x86/dts/minnowmax.dts +2
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"arch/x86/dts/minnowmax.dts line 27
Quoted 5 lines
arch/x86/dts/minnowmax.dts +2
-0@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,ich6-pinctrl";Make sure you use tabs for indenting here.
You should create a binding file to describe your binding - in doc/device-tree-bindings.
Quoted 48 lines
arch/x86/dts/minnowmax.dts +17
-0+ pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/arch-baytrail/gpio.h +1
-0@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */ arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);drivers/gpio/intel_ich6_gpio.c +0
-0drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 49
Quoted 6 lines
drivers/gpio/intel_ich6_gpio.c +3
-0@@ -44,21 +44,32 @@ struct ich6_bank_priv {uint16_t lvl; }; +#define GPIO_USESEL_OFFSET (x) (x) +#define GPIO_IOSEL_OFFSET (x) (x + 4) +#define GPIO_LVL_OFFSET (x) (x + 8)Comments on the above
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 53
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+ +#define IOPAD_MODE_MASK 0x7 +#define IOPAD_PULL_ASSIGN_MASK 0x3 +#define IOPAD_PULL_ASSIGN_SHIFT 7Can you make the mask value an actual valid mask, like:
+#define
IOPAD_PULL_ASSIGN_MASK(0x3<<IOPAD_PULL_ASSIGN_SHIFT)drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 57
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+#define IOPAD_PULL_STRENGTH_MASK 0x3 +#define IOPAD_PULL_STRENGTH_SHIFT 9 + +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value);Can you reorder the functions to avoid the need for these forward declarations? Also only one underscore prefix please.
Quoted 23 lines
drivers/gpio/intel_ich6_gpio.c +4
-4+static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir); +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func); +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev);pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 126
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +0
-1@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE );Can the base come from the device tree somewhere? E.g.
Quoted 5 lines
pch { gpio { reg = <some value>;There is something like this in
chromebook_link.dts.
Sounds good and will answer to another issue to was breaking actually the other board ...
Quoted 37 lines
Quoted 37 lines
drivers/gpio/intel_ich6_gpio.c +27
-2+ tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }@@ -135,7 +146,138 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +int pin_node; +int node; +u32 iobase; +u32 gpiobase; + +/* +* 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 +*/ + iobase =gpio_ich6_get_base (PCI_CFG_IOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ;
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 180
Quoted 7 lines
drivers/gpio/intel_ich6_gpio.c +7
-0+ } + +/* This is not an error to not have a pinctrl node */ + node =fdt_node_offset_by_compatible (gd->fdt_blob,-1 , +"intel,ich6-pinctrl" ); +if (node <0 ) +return 0 ;Probably this should move to driver model, but let's worry about that later.
Agreed, for the first version I would like to have an easy implementation that we can move to driver model later.
Quoted 23 lines
Quoted 23 lines
drivers/gpio/intel_ich6_gpio.c +23
-0+ +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + pin_node >0 ; + pin_node =fdt_next_subnode (gd->fdt_blob, pin_node)) { +u32 gpio_offset[2 ] = {-1 ,-1 }; +u32 pad_offset; +u32 tmplong; +const void *tmpnode; + +/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset =fdtdec_get_int (gd->fdt_blob, pin_node, +"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset); +return -EINVAL ; + } +
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 210
Quoted 7 lines
drivers/gpio/intel_ich6_gpio.c +7
-0+/* +* GPIO node is not mandatory, so we only do the +* pinmuxing if the node exist. +*/ +fdtdec_get_int_array (gd->fdt_blob, pin_node, +"gpio-offset" , gpio_offset,2 ); +if (gpio_offset[0 ] !=-1 ) {Can you move this block into its own function without too much trouble?
Agreed.
Quoted 13 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 223
Quoted 13 lines
drivers/gpio/intel_ich6_gpio.c +13
-0+/* Do we want to force the GPIO mode? */ + tmpnode =fdt_getprop (gd->fdt_blob, pin_node, +"mode-gpio" ,NULL ); +if (tmpnode) +__ich6_gpio_set_function (GPIO_USESEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ],1 ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"direction" , +-1 ); +if (tmplong !=-1 )
Quoted 1 line
But tmplong is unsigned.
This is not how we do to never have an error? ;)
I'll do the modification.
Quoted 171 lines
Quoted 171 lines
drivers/gpio/intel_ich6_gpio.c +104
-19+__ich6_gpio_set_direction (GPIO_IOSEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], + tmplong); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node, +"output-value" ,-1 ); +if (tmplong !=-1 ) +__ich6_gpio_set_value (GPIO_LVL_OFFSET (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + } + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset,IOPAD_MODE_MASK , + tmplong); + +/* Configure the pull-up/down if needed */ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_ASSIGN_MASK << +IOPAD_PULL_ASSIGN_SHIFT , + tmplong <<IOPAD_PULL_ASSIGN_SHIFT ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_STRENGTH_MASK << +IOPAD_PULL_STRENGTH_SHIFT , + tmplong <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase + pad_offset)); + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -189,33 +331,56 @@ static int ich6_gpio_request(struct udevice *dev, unsigned offset,return 0 ; } -static int ich6_gpio_direction_input (struct udevice *dev,unsigned offset) +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); +if (func) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } +return 0 ; } -static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, -int value) +static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; -gpio_set_value (offset, value); +if (!dir) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong);return 0 ; } -static int ich6_gpio_get_value (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 (inl (bank->io_sel), offset,0 ); +} + +static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, +int value) +{ +struct ich6_bank_priv *bank =dev_get_priv (dev); + +return __ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); +} +static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -226,21 +391,26 @@ 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) +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - - tmplong =inl (bank->lvl); + tmplong =inl (base);if (value) tmplong |= (1UL << offset);else tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); +outl (tmplong, base); +return 0 ; } +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);include/dt-bindings/gpio/gpio.h +0
-0@@ -12,4 +12,24 @@#define GPIO_ACTIVE_HIGH 0#define GPIO_ACTIVE_LOW 1
Quoted 10 lines
include/dt-bindings/gpio/gpio.h line 23
Quoted 9 lines
include/dt-bindings/gpio/gpio.h +9
-0+#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6Can we use an enum for these? They mostly count up.
Agreed.
Quoted 9 lines
Quoted 9 lines
include/dt-bindings/gpio/gpio.h +9
-0+ +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0
Quoted 8 lines
Quoted 6 lines
include/dt-bindings/gpio/gpio.h +2
-1+#define PULL_STR_20K 2 +#endif --2.1.4
Regards,
Simon
Regards,
Gabriel
[U-Boot] unassigned-patches/150: Re: [PATCH 3/4] x86: gpio: add pinctrl support from the device tree
Hi Simon,
Quoted 151 lines · Simon Glass
Hi,
Quoted 38 lines · Gabriel Huau
A set of properties has been defined for the device tree to select for each pin the pull/func/default output configuration.
The offset for the PAD needs to be provided and if a GPIO needs to be configured, his offset needs to be provided as well.
Here is an example:
pin_usb_host_en0 at 0 { gpio-offset = <0x80 8>; pad-offset = <0x260>; mode-gpio; output-value = <1>; direction = <PIN_OUTPUT>; };Signed-off-by Gabriel Huau <[email protected]>--- arch/x86/dts/minnowmax.dts | 21 +++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/dt-bindings/gpio/gpio.h | 20 +++ 5 files changed, 239 insertions(+), 26 deletions(-)arch/x86/dts/minnowmax.dts +2
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"arch/x86/dts/minnowmax.dts line 27
Quoted 5 lines
arch/x86/dts/minnowmax.dts +2
-0@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,ich6-pinctrl";Make sure you use tabs for indenting here.
You should create a binding file to describe your binding - in doc/device-tree-bindings.
Quoted 48 lines
arch/x86/dts/minnowmax.dts +17
-0+ pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/arch-baytrail/gpio.h +1
-0@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */ arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);drivers/gpio/intel_ich6_gpio.c +0
-0drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 49
Quoted 6 lines
drivers/gpio/intel_ich6_gpio.c +3
-0@@ -44,21 +44,32 @@ struct ich6_bank_priv {uint16_t lvl; }; +#define GPIO_USESEL_OFFSET (x) (x) +#define GPIO_IOSEL_OFFSET (x) (x + 4) +#define GPIO_LVL_OFFSET (x) (x + 8)Comments on the above
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 53
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+ +#define IOPAD_MODE_MASK 0x7 +#define IOPAD_PULL_ASSIGN_MASK 0x3 +#define IOPAD_PULL_ASSIGN_SHIFT 7Can you make the mask value an actual valid mask, like:
+#define
IOPAD_PULL_ASSIGN_MASK(0x3<<IOPAD_PULL_ASSIGN_SHIFT)drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 57
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+#define IOPAD_PULL_STRENGTH_MASK 0x3 +#define IOPAD_PULL_STRENGTH_SHIFT 9 + +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value);Can you reorder the functions to avoid the need for these forward declarations? Also only one underscore prefix please.
Quoted 23 lines
drivers/gpio/intel_ich6_gpio.c +4
-4+static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir); +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func); +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev);pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 126
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +0
-1@@ -123,9 +134,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE );Can the base come from the device tree somewhere? E.g.
Quoted 5 lines
pch { gpio { reg = <some value>;There is something like this in
chromebook_link.dts.
Sounds good and will answer to another issue to was breaking actually the other board ...
Quoted 37 lines
Quoted 37 lines
drivers/gpio/intel_ich6_gpio.c +27
-2+ tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }@@ -135,7 +146,138 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +int pin_node; +int node; +u32 iobase; +u32 gpiobase; + +/* +* 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 +*/ + iobase =gpio_ich6_get_base (PCI_CFG_IOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ;
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 180
Quoted 7 lines
drivers/gpio/intel_ich6_gpio.c +7
-0+ } + +/* This is not an error to not have a pinctrl node */ + node =fdt_node_offset_by_compatible (gd->fdt_blob,-1 , +"intel,ich6-pinctrl" ); +if (node <0 ) +return 0 ;Probably this should move to driver model, but let's worry about that later.
Agreed, for the first version I would like to have an easy implementation that we can move to driver model later.
Quoted 23 lines
Quoted 23 lines
drivers/gpio/intel_ich6_gpio.c +23
-0+ +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + pin_node >0 ; + pin_node =fdt_next_subnode (gd->fdt_blob, pin_node)) { +u32 gpio_offset[2 ] = {-1 ,-1 }; +u32 pad_offset; +u32 tmplong; +const void *tmpnode; + +/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset =fdtdec_get_int (gd->fdt_blob, pin_node, +"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset); +return -EINVAL ; + } +
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 210
Quoted 7 lines
drivers/gpio/intel_ich6_gpio.c +7
-0+/* +* GPIO node is not mandatory, so we only do the +* pinmuxing if the node exist. +*/ +fdtdec_get_int_array (gd->fdt_blob, pin_node, +"gpio-offset" , gpio_offset,2 ); +if (gpio_offset[0 ] !=-1 ) {Can you move this block into its own function without too much trouble?
Agreed.
Quoted 13 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 223
Quoted 13 lines
drivers/gpio/intel_ich6_gpio.c +13
-0+/* Do we want to force the GPIO mode? */ + tmpnode =fdt_getprop (gd->fdt_blob, pin_node, +"mode-gpio" ,NULL ); +if (tmpnode) +__ich6_gpio_set_function (GPIO_USESEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ],1 ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"direction" , +-1 ); +if (tmplong !=-1 )
Quoted 1 line
But tmplong is unsigned.
This is not how we do to never have an error? ;)
I'll do the modification.
Quoted 171 lines
Quoted 171 lines
drivers/gpio/intel_ich6_gpio.c +104
-19+__ich6_gpio_set_direction (GPIO_IOSEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], + tmplong); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node, +"output-value" ,-1 ); +if (tmplong !=-1 ) +__ich6_gpio_set_value (GPIO_LVL_OFFSET (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + } + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset,IOPAD_MODE_MASK , + tmplong); + +/* Configure the pull-up/down if needed */ + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_ASSIGN_MASK << +IOPAD_PULL_ASSIGN_SHIFT , + tmplong <<IOPAD_PULL_ASSIGN_SHIFT ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_STRENGTH_MASK << +IOPAD_PULL_STRENGTH_SHIFT , + tmplong <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase + pad_offset)); + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -189,33 +331,56 @@ static int ich6_gpio_request(struct udevice *dev, unsigned offset,return 0 ; } -static int ich6_gpio_direction_input (struct udevice *dev,unsigned offset) +static int __ich6_gpio_set_function (uint16_t base,unsigned offset,int func) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); +if (func) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } +return 0 ; } -static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, -int value) +static int __ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; -gpio_set_value (offset, value); +if (!dir) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong);return 0 ; } -static int ich6_gpio_get_value (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 (inl (bank->io_sel), offset,0 ); +} + +static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset, +int value) +{ +struct ich6_bank_priv *bank =dev_get_priv (dev); + +return __ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); +} +static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -226,21 +391,26 @@ 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) +static int __ich6_gpio_set_value (uint16_t base,unsigned offset,int value) { -struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong; - - tmplong =inl (bank->lvl); + tmplong =inl (base);if (value) tmplong |= (1UL << offset);else tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); +outl (tmplong, base); +return 0 ; } +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);include/dt-bindings/gpio/gpio.h +0
-0@@ -12,4 +12,24 @@#define GPIO_ACTIVE_HIGH 0#define GPIO_ACTIVE_LOW 1
Quoted 10 lines
include/dt-bindings/gpio/gpio.h line 23
Quoted 9 lines
include/dt-bindings/gpio/gpio.h +9
-0+#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6Can we use an enum for these? They mostly count up.
Agreed.
Quoted 9 lines
Quoted 9 lines
include/dt-bindings/gpio/gpio.h +9
-0+ +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0
Quoted 8 lines
Quoted 6 lines
include/dt-bindings/gpio/gpio.h +2
-1+#define PULL_STR_20K 2 +#endif --2.1.4
Regards,
Simon
Regards,
Gabriel
---
Added to GNATS database as unassigned-patches/150
Quoted 5 lines
Responsible: patch-coord Message-Id: <[email protected]> In-Reply-To: <CAPnjgZ38cPE1h6EBg-ffdtOA4FhTdgTx8u1VS5yMpv9Ynik-KA@mail.gmail.com> References: <[email protected]> <[email protected]> <CAPnjgZ38cPE1h6EBg-ffdtOA4FhTdgTx8u1VS5yMpv9Ynik-KA@mail.gmail.com> Patch-Date: Fri Apr 24 16:37:17 +0200 2015
PATCH v2 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Gabriel HuauEvery pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
---
Changes for v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.
arch/x86/dts/minnowmax.dts | 21 ++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 234 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 36 ++++ 6 files changed, 295 insertions(+), 29 deletions(-) create mode 100644 doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt create mode 100644 include/dt-bindings/gpio/x86-gpio.h
arch/x86/dts/minnowmax.dts +21 -0
@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;
arch/x86/include/asm/arch-baytrail/gpio.h +1 -0
@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c#endif /* _X86_ARCH_GPIO_H_ */
arch/x86/include/asm/gpio.h +1 -0
@@ -147,6 +147,7 @@ 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);
doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31 -0
@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};
drivers/gpio/intel_ich6_gpio.c +205 -29
287 lines not on this page · raw message
include/dt-bindings/gpio/x86-gpio.h new file +36 -0
@@ -0,0 +1,36 @@ +/* +* This header provides constants for binding nvidia,tegra*-gpio. +* +* The first cell in Tegra's GPIO specifier is the GPIO ID. The macros below +* provide names for this. +* +* The second cell contains standard flag values specified in gpio.h. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 + +#endif
Signature · 1 line
2.1.4
PATCH v2 3/4 x86: gpio: add pinctrl support from the device tree
Hi Gabriel,
Quoted 4 lines · Gabriel Huau
Every pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
Signed-off-by Gabriel Huau <[email protected]>
Quoted 12 lines
---
Changes for v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.
I have a few minor comments below. Do you know how to access the GPIO pings on the top connector of the Minnowboard MAX? I'd like to figure out the pin names for those in U-Boot and that would allow me to test a few things.
Quoted 55 lines
arch/x86/dts/minnowmax.dts | 21 ++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 234 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 36 ++++ 6 files changed, 295 insertions(+), 29 deletions(-) create mode 100644 doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt create mode 100644 include/dt-bindings/gpio/x86-gpio.harch/x86/dts/minnowmax.dts +21
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/arch-baytrail/gpio.h +0
-0
arch/x86/include/asm/arch-baytrail/gpio.h line 12
Quoted 4 lines
arch/x86/include/asm/arch-baytrail/gpio.h +1
-0@@ -9,5 +9,6 @@/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4c
Can we put this in the device tree as a property of the pch_pinctrl node? If you like we could do it later.
Quoted 56 lines
arch/x86/include/asm/arch-baytrail/gpio.h +0
-0#endif /* _X86_ARCH_GPIO_H_ */ arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31
-0@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};drivers/gpio/intel_ich6_gpio.c +0
-0
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 49
Quoted 6 lines
drivers/gpio/intel_ich6_gpio.c +3
-0@@ -44,21 +44,28 @@ struct ich6_bank_priv {uint16_t lvl; }; +#define GPIO_USESEL_OFFSET (x) (x) +#define GPIO_IOSEL_OFFSET (x) (x + 4) +#define GPIO_LVL_OFFSET (x) (x + 8)
Please align all of these values to the same tab column.
Quoted 39 lines
drivers/gpio/intel_ich6_gpio.c +10
-6+ +#define IOPAD_MODE_MASK 0x7 +#define IOPAD_PULL_ASSIGN_SHIFT 7 +#define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT) +#define IOPAD_PULL_STRENGTH_SHIFT 9 +#define IOPAD_PULL_STRENGTH_MASK (0x3 << IOPAD_PULL_STRENGTH_SHIFT) +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev);pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );@@ -123,9 +130,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE ); + tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 150
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +6
-1@@ -135,7 +142,195 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +static int _ich6_gpio_set_value (uint16_t base,unsigned offset,int value) +{ +u32 tmplong;
blank line here. Also can we use something like 'val' instead of tmplong? I think calling a u32 'long' is confusing.
Quoted 40 lines
drivers/gpio/intel_ich6_gpio.c +40
-0+ tmplong =inl (base); +if (value) + tmplong |= (1UL << offset); +else + tmplong &= ~(1UL << offset); +outl (tmplong, base); + +return 0 ; +} + +static int _ich6_gpio_set_function (uint16_t base,unsigned offset,int func) +{ +u32 tmplong; + +if (func) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } + +return 0 ; +} + +static int _ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) +{ +u32 tmplong; + +if (!dir) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + }
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 200
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+ +return 0 ; +} + +static int _gpio_ich6_pinctrl_cfg_pin (u32 gpiobase,u32 iobase,int pin_node) +{ +u32 gpio_offset[2 ] = {-1 ,-1 }; +u32 pad_offset; +int tmplong; +const void *tmpnode;
Perhaps 'prop' is a better name. It doesn't point to a node, but a property of a node.
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 212
Quoted 12 lines
drivers/gpio/intel_ich6_gpio.c +12
-0+ +/* +* GPIO node is not mandatory, so we only do the +* pinmuxing if the node exist. +*/ +fdtdec_get_int_array (gd->fdt_blob, pin_node,"gpio-offset" , + gpio_offset,2 ); +if (gpio_offset[0 ] !=-1 ) { +/* Do we want to force the GPIO mode? */ + tmpnode =fdt_getprop (gd->fdt_blob, pin_node,"mode-gpio" , +NULL ); +if (tmpnode)
{} around these multi-line blocks. If you use patman it will run checkpatch for you.
Quoted 11 lines
drivers/gpio/intel_ich6_gpio.c +11
-0+_ich6_gpio_set_function (GPIO_USESEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ],1 ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"direction" ,-1 ); +if (tmplong !=-1 ) + _ich6_gpio_set_direction(GPIO_IOSEL_OFFSET + (gpiobase) + + gpio_offset[0],
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 233
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+ gpio_offset[1], tmplong); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"output-value" ,-1 ); +if (tmplong !=-1 ) +_ich6_gpio_set_value (GPIO_LVL_OFFSET (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + } +#ifdef PCI_CFG_IOBASE
We should avoid adding #ifdefs like this to the driver. Perhaps the device tree can provide this property, or not? OK if you want to tackle this in a follow-on patch.
Quoted 16 lines
drivers/gpio/intel_ich6_gpio.c +16
-0+/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset =fdtdec_get_int (gd->fdt_blob, pin_node,"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset); +return -EINVAL ; + } + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 259
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+* be just ignored by the controller +*/ + tmplong =fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset,IOPAD_MODE_MASK , tmplong); + +/* Configure the pull-up/down if needed */ + tmplong =fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (tmplong !=-1 ) + clrsetbits_le32(iobase + pad_offset,
Can you create a local variable for (iobase + pad_offset) ?
Quoted 15 lines
drivers/gpio/intel_ich6_gpio.c +15
-0+IOPAD_PULL_ASSIGN_MASK , + tmplong << IOPAD_PULL_ASSIGN_SHIFT); + + tmplong =fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_STRENGTH_MASK , + tmplong <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase + pad_offset)); +#endif + +return 0 ; +}
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 284
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+ +int gpio_ich6_pinctrl_init (void ) +{ +int pin_node; +int node; +int ret; +u32 gpiobase; +u32 iobase; + +#ifdef PCI_CFG_IOBASE
If this block is #ifdef'd out then you will have an uninited variable iobase, used below.
Quoted 12 lines
drivers/gpio/intel_ich6_gpio.c +12
-0+/* +* 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 +*/ + iobase =gpio_ich6_get_base (PCI_CFG_IOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } +#endif +
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 306
Quoted 10 lines
drivers/gpio/intel_ich6_gpio.c +10
-0+ gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); +if (gpiobase <0 ) { +debug ("%s: invalid GPIOBASE address (%08x)\n" , __func__, + gpiobase); +return -EINVAL ; + } + +/* This is not an error to not have a pinctrl node */ + node =fdt_node_offset_by_compatible (gd->fdt_blob,-1 , +"intel,x86-pinctrl" );
This should be added to the tables in fdtdec.c/h. Then use fdtdec_next_compatible(). That file contains a list of all the compatible strings we have in U-Boot and is an indicator of what needs to be converted to driver model.
Quoted 100 lines
drivers/gpio/intel_ich6_gpio.c +30
-22+if (node <0 ) { +debug ("%s: no pinctrl node\n" , __func__); +return 0 ; + } + +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + 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); +if (ret !=0 ) { +debug ("%s: invalid configuration for the pin %d\n" , + __func__, pin_node); +return ret; + } + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -192,30 +387,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); -u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); -return 0 ; +return _ich6_gpio_set_direction (inl (bank->io_sel), offset,0 ); }static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset,int value) {struct ich6_bank_priv *bank =dev_get_priv (dev); -u32 tmplong; -gpio_set_value (offset, value); - - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong); -return 0 ; +return _ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); }static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) - {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -230,15 +414,7 @@ static int ich6_gpio_set_value(struct udevice *dev, unsigned offset, int value) {struct ich6_bank_priv *bank =dev_get_priv (dev); -u32 tmplong; - - tmplong =inl (bank->lvl); -if (value) - tmplong |= (1UL << offset); -else - tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); -return 0 ; +return _ich6_gpio_set_value (bank->lvl, offset, value); }static int ich6_gpio_get_function (struct udevice *dev,unsigned offset)include/dt-bindings/gpio/x86-gpio.h new file +14
-0@@ -0,0 +1,36 @@ +/* +* This header provides constants for binding nvidia,tegra*-gpio. +* +* The first cell in Tegra's GPIO specifier is the GPIO ID. The macros below +* provide names for this. +* +* The second cell contains standard flag values specified in gpio.h. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> +
include/dt-bindings/gpio/x86-gpio.h line 24
Quoted 10 lines
include/dt-bindings/gpio/x86-gpio.h new file +10
-0+#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6
Please can you tab the numbers out to the same column?
Quoted 13 lines
include/dt-bindings/gpio/x86-gpio.h new file +12
-1+ +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 + +#endif --
Quoted 2 lines
2.1.4
Regards,
Simon
PATCH v2 3/4 x86: gpio: add pinctrl support from the device tree
Quoted 13 lines · Simon Glass
Hi Gabriel,
Quoted 10 lines · Gabriel Huau
Every pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
include/dt-bindings/gpio/x86-gpio.h +5
-0+/* +* This header provides constants for binding nvidia,tegra*-gpio. +* +* The first cell in Tegra's GPIO specifier is the GPIO ID. The macros below +* provide names for this.
I think this comment needs updating.
PATCH v2 3/4 x86: gpio: add pinctrl support from the device tree
Hi Stephen,
Thanks for the feedback, I completely miss it, I will do the modification for the v3.
Quoted 10 lines · Stephen Warren
Quoted 8 lines · Simon Glass
Hi Gabriel,
Quoted 5 lines · Gabriel Huau
Every pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
include/dt-bindings/gpio/x86-gpio.h +0
-0
Quoted 8 lines
Quoted 6 lines
Quoted 6 lines
+/*
+ * This header provides constants for binding nvidia,tegra*-gpio.
+ *
+ * The first cell in Tegra's GPIO specifier is the GPIO ID. The macros below
+ * provide names for this.I think this comment needs updating.
Regards,
Gabriel
PATCH v2 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Simon GlassHi Simon,
Sorry for the delay, I'm gonna provide a new version in the next few days but here is some answers to your question:
Quoted 19 lines · Simon Glass
Hi Gabriel,
Quoted 4 lines · Gabriel Huau
Every pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
Signed-off-by Gabriel Huau <[email protected]>Quoted 12 lines
---
Changes for v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.
Quoted 4 lines
I have a few minor comments below. Do you know how to access the GPIO pings on the top connector of the Minnowboard MAX? I'd like to figure out the pin names for those in U-Boot and that would allow me to test a few things.
You should be able to access SOC_GPIO_S5_0, SOC_GPIO_S5_1, SOC_GPIO_S5_2
GPIO_BASE should be 0x80 (respecting bit 0 1 and 2). IO_BASE should be 0x1D0, 0x210, 0x1E0 (respect GPIO0, 1 and 2).
Quoted 55 lines
Quoted 55 lines
arch/x86/dts/minnowmax.dts | 21 ++ arch/x86/include/asm/arch-baytrail/gpio.h | 1 + arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 234 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 36 ++++ 6 files changed, 295 insertions(+), 29 deletions(-)create mode 100644
doc/device-tree-bindings/gpio/intel,x86-pinctrl.txtcreate mode 100644include/dt-bindings/gpio/x86-gpio.harch/x86/dts/minnowmax.dts +21
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"@@ -21,6 +23,25 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/arch-baytrail/gpio.h +0
-0@@ -9,5 +9,6 @@
Quoted 5 lines
arch/x86/include/asm/arch-baytrail/gpio.h line 12
Quoted 3 lines
arch/x86/include/asm/arch-baytrail/gpio.h +1
-0/* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 +#define PCI_CFG_IOBASE 0x4cCan we put this in the device tree as a property of the
pch_pinctrlnode? If you like we could do it later.
Yes, I will do the modification, I thought as a first version it would be easier to use a define but actually, a property is cleaner and also easy to implement.
Quoted 58 lines
Quoted 58 lines
arch/x86/include/asm/arch-baytrail/gpio.h +0
-0#endif /* _X86_ARCH_GPIO_H_ */ arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31
-0@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};drivers/gpio/intel_ich6_gpio.c +0
-0@@ -44,21 +44,28 @@ struct ich6_bank_priv {uint16_t lvl; };
Quoted 5 lines
drivers/gpio/intel_ich6_gpio.c struct ich6_bank_priv { · line 49
Quoted 3 lines
drivers/gpio/intel_ich6_gpio.c +3
-0+#define GPIO_USESEL_OFFSET (x) (x) +#define GPIO_IOSEL_OFFSET (x) (x + 4) +#define GPIO_LVL_OFFSET (x) (x + 8)Please align all of these values to the same tab column.
I will do.
Quoted 38 lines
Quoted 38 lines
drivers/gpio/intel_ich6_gpio.c +10
-6+ +#define IOPAD_MODE_MASK 0x7 +#define IOPAD_PULL_ASSIGN_SHIFT 7 +#define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT) +#define IOPAD_PULL_STRENGTH_SHIFT 9 +#define IOPAD_PULL_STRENGTH_MASK (0x3 << IOPAD_PULL_STRENGTH_SHIFT) +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev);pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );@@ -123,9 +130,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE ); + tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }
Quoted 13 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 150
Quoted 11 lines
drivers/gpio/intel_ich6_gpio.c +6
-1@@ -135,7 +142,195 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +static int _ich6_gpio_set_value (uint16_t base,unsigned offset,int value) +{ +u32 tmplong;blank line here. Also can we use something like 'val' instead of tmplong? I think calling a u32 'long' is confusing.
Agreed, I was just trying to reuse the variable for some other property, but it was a bad idea as it also introduced some errors due to the sign of the type.
Quoted 44 lines
Quoted 44 lines
drivers/gpio/intel_ich6_gpio.c +44
-0+ tmplong =inl (base); +if (value) + tmplong |= (1UL << offset); +else + tmplong &= ~(1UL << offset); +outl (tmplong, base); + +return 0 ; +} + +static int _ich6_gpio_set_function (uint16_t base,unsigned offset,int func) +{ +u32 tmplong; + +if (func) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } + +return 0 ; +} + +static int _ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) +{ +u32 tmplong; + +if (!dir) { + tmplong =inl (base); + tmplong |= (1UL << offset); +outl (tmplong, base); + }else { + tmplong =inl (base); + tmplong &= ~(1UL << offset); +outl (tmplong, base); + } + +return 0 ; +} +
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 200
Quoted 6 lines
drivers/gpio/intel_ich6_gpio.c +6
-0+static int _gpio_ich6_pinctrl_cfg_pin (u32 gpiobase,u32 iobase,int pin_node) +{ +u32 gpio_offset[2 ] = {-1 ,-1 }; +u32 pad_offset; +int tmplong; +const void *tmpnode;Perhaps 'prop' is a better name. It doesn't point to a node, but a property of a node.
Agreed.
Quoted 12 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 212
Quoted 12 lines
drivers/gpio/intel_ich6_gpio.c +12
-0+ +/* +* GPIO node is not mandatory, so we only do the +* pinmuxing if the node exist. +*/ +fdtdec_get_int_array (gd->fdt_blob, pin_node,"gpio-offset" , + gpio_offset,2 ); +if (gpio_offset[0 ] !=-1 ) { +/* Do we want to force the GPIO mode? */ + tmpnode =fdt_getprop (gd->fdt_blob, pin_node,"mode-gpio" , +NULL ); +if (tmpnode)
Quoted 3 lines
{} around these multi-line blocks. If you use patman it will run checkpatch for you.
Actually, I'm running checkpatch on all the patches all the time, I'm pretty surprised to have miss it. I will definitely try to use patman,
Quoted 16 lines
Quoted 16 lines
drivers/gpio/intel_ich6_gpio.c +16
-0+_ich6_gpio_set_function (GPIO_USESEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ],1 ); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"direction" ,-1 ); +if (tmplong !=-1 ) +_ich6_gpio_set_direction (GPIO_IOSEL_OFFSET + (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + + tmplong = +fdtdec_get_int (gd->fdt_blob, pin_node,"output-value" ,-1 ); +if (tmplong !=-1 )
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 233
Quoted 5 lines
drivers/gpio/intel_ich6_gpio.c +5
-0+_ich6_gpio_set_value (GPIO_LVL_OFFSET (gpiobase) + + gpio_offset[0 ], + gpio_offset[1 ], tmplong); + } +#ifdef PCI_CFG_IOBASE We should avoid adding #ifdefs like this to the driver. Perhaps the device tree can provide this property, or not? OK if you want to tackle this in a follow-on patch.
No I think you are right, I can do the modification for the v3.
Quoted 19 lines
Quoted 19 lines
drivers/gpio/intel_ich6_gpio.c +19
-0+/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset =fdtdec_get_int (gd->fdt_blob, pin_node,"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset); +return -EINVAL ; + } + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + tmplong =fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 );
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 259
Quoted 7 lines
drivers/gpio/intel_ich6_gpio.c +7
-0+if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset,IOPAD_MODE_MASK , tmplong); + +/* Configure the pull-up/down if needed */ + tmplong =fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (tmplong !=-1 ) + clrsetbits_le32(iobase + pad_offset,Can you create a local variable for (iobase +
pad_offset) ?
I will do.
Quoted 19 lines
Quoted 19 lines
drivers/gpio/intel_ich6_gpio.c +19
-0+IOPAD_PULL_ASSIGN_MASK , + tmplong << IOPAD_PULL_ASSIGN_SHIFT); + + tmplong =fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (tmplong !=-1 ) +clrsetbits_le32 (iobase + pad_offset, +IOPAD_PULL_STRENGTH_MASK , + tmplong <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase + pad_offset)); +#endif + +return 0 ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +int pin_node;
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 284
Quoted 6 lines
drivers/gpio/intel_ich6_gpio.c +6
-0+int node; +int ret; +u32 gpiobase; +u32 iobase; + +#ifdef PCI_CFG_IOBASE If this block is #ifdef'd out then you will have an uninited variable iobase, used below.
Right, as I'm going to move to a property, I will fix this error as well.
Quoted 18 lines
Quoted 18 lines
drivers/gpio/intel_ich6_gpio.c +18
-0+/* +* 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 +*/ + iobase =gpio_ich6_get_base (PCI_CFG_IOBASE ); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, iobase); +return -EINVAL ; + } +#endif + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); +if (gpiobase <0 ) { +debug ("%s: invalid GPIOBASE address (%08x)\n" , __func__, + gpiobase); +return -EINVAL ; + }
Quoted 8 lines
drivers/gpio/intel_ich6_gpio.c static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) · line 306
Quoted 4 lines
drivers/gpio/intel_ich6_gpio.c +4
-0+ +/* This is not an error to not have a pinctrl node */ + node =fdt_node_offset_by_compatible (gd->fdt_blob,-1 , +"intel,x86-pinctrl" );This should be added to the tables in fdtdec.c/h. Then use
fdtdec_next_compatible(). That file contains a list of all the compatible strings we have in U-Boot and is an indicator of what needs to be converted to driver model.
Ok, make sense.
Quoted 103 lines
Quoted 103 lines
drivers/gpio/intel_ich6_gpio.c +30
-22+if (node <0 ) { +debug ("%s: no pinctrl node\n" , __func__); +return 0 ; + } + +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + 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); +if (ret !=0 ) { +debug ("%s: invalid configuration for the pin %d\n" , + __func__, pin_node); +return ret; + } + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -192,30 +387,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); -u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); -return 0 ; +return _ich6_gpio_set_direction (inl (bank->io_sel), offset,0 ); }static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset,int value) {struct ich6_bank_priv *bank =dev_get_priv (dev); -u32 tmplong; -gpio_set_value (offset, value); - - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong); -return 0 ; +return _ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); }static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) - {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -230,15 +414,7 @@ static int ich6_gpio_set_value(struct udevice *dev, unsigned offset, int value) {struct ich6_bank_priv *bank =dev_get_priv (dev); -u32 tmplong; - - tmplong =inl (bank->lvl); -if (value) - tmplong |= (1UL << offset); -else - tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); -return 0 ; +return _ich6_gpio_set_value (bank->lvl, offset, value); }static int ich6_gpio_get_function (struct udevice *dev,unsigned offset)include/dt-bindings/gpio/x86-gpio.h new file +17
-0@@ -0,0 +1,36 @@ +/* +* This header provides constants for binding nvidia,tegra*-gpio. +* +* The first cell in Tegra's GPIO specifier is the GPIO ID. The macros below +* provide names for this. +* +* The second cell contains standard flag values specified in gpio.h. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 +
Quoted 8 lines
include/dt-bindings/gpio/x86-gpio.h line 24
Quoted 7 lines
include/dt-bindings/gpio/x86-gpio.h new file +7
-0+#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6Please can you tab the numbers out to the same column?
I will do.
Quoted 9 lines
Quoted 9 lines
include/dt-bindings/gpio/x86-gpio.h new file +9
-0+ +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0
Quoted 8 lines
Quoted 6 lines
include/dt-bindings/gpio/x86-gpio.h new file +3
-1+#define PULL_STR_20K 2 + +#endif --2.1.4
Regards,
Simon
Regards,
Gabriel
PATCH v3 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Gabriel HuauEvery pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
---
Changes in v3:
- Fix the dt-binding copyright header
- Remove define for IOBASE and use a property
- Fix issues with signed/unsigned variable type
- Fix coding style
- Add a compatible string for the driver
Changes in v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.
arch/x86/dts/minnowmax.dts | 23 ++ arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 254 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 31 +++ include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 312 insertions(+), 30 deletions(-) create mode 100644 doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt create mode 100644 include/dt-bindings/gpio/x86-gpio.h
arch/x86/dts/minnowmax.dts +23 -0
@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
@@ -22,6 +24,27 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + io-base = <0x4c>; + + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;
arch/x86/include/asm/gpio.h +1 -0
@@ -147,6 +147,7 @@ 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);
doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31 -0
@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};
drivers/gpio/intel_ich6_gpio.c +224 -30
306 lines not on this page · raw message
include/dt-bindings/gpio/x86-gpio.h new file +31 -0
@@ -0,0 +1,31 @@ +/* +* This header provides constants for binding intel,x86-pinctrl. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 + +#endif
include/fdtdec.h +1 -0
@@ -175,6 +175,7 @@ enum fdt_compat_id {COMPAT_AMS_AS3722 ,/* AMS AS3722 PMIC */ COMPAT_INTEL_ICH_SPI ,/* Intel ICH7/9 SPI controller */ COMPAT_INTEL_QRK_MRC ,/* Intel Quark MRC */ +COMPAT_INTEL_X86_PINCTRL ,/* Intel ICH7/9 pin control */ COMPAT_SOCIONEXT_XHCI ,/* Socionext UniPhier xHCI */ COMPAT_INTEL_PCH, /* Intel PCH */
lib/fdtdec.c +1 -0
@@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {COMPAT (AMS_AS3722 ,"ams,as3722" ),COMPAT (INTEL_ICH_SPI ,"intel,ich-spi" ),COMPAT (INTEL_QRK_MRC ,"intel,quark-mrc" ), +COMPAT (INTEL_X86_PINCTRL ,"intel,x86-pinctrl" ),COMPAT (SOCIONEXT_XHCI ,"socionext,uniphier-xhci" ), COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), };
Signature · 1 line
2.1.4
PATCH v4 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Gabriel HuauEvery pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
---
Changes in v4:
- Rebase modification on latest update
- Fix typo to read the io-base
- Fix direction_output function to set the value
Changes in v3:
- Fix the dt-binding copyright header
- Remove define for IOBASE and use a property
- Fix issues with signed/unsigned variable type
- Fix coding style
- Add a compatible string for the driver
Changes in v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.
arch/x86/dts/minnowmax.dts | 23 ++ arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 257 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 31 +++ include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 317 insertions(+), 28 deletions(-) create mode 100644 doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt create mode 100644 include/dt-bindings/gpio/x86-gpio.h
arch/x86/dts/minnowmax.dts +23 -0
@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
@@ -22,6 +24,27 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + io-base = <0x4c>; + + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;
arch/x86/include/asm/gpio.h +1 -0
@@ -147,6 +147,7 @@ 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);
doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31 -0
@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};
drivers/gpio/intel_ich6_gpio.c +229 -28
311 lines not on this page · raw message
include/dt-bindings/gpio/x86-gpio.h new file +31 -0
@@ -0,0 +1,31 @@ +/* +* This header provides constants for binding intel,x86-pinctrl. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 + +#endif
include/fdtdec.h +1 -0
@@ -176,6 +176,7 @@ enum fdt_compat_id {COMPAT_AMS_AS3722 ,/* AMS AS3722 PMIC */ COMPAT_INTEL_ICH_SPI ,/* Intel ICH7/9 SPI controller */ COMPAT_INTEL_QRK_MRC ,/* Intel Quark MRC */ +COMPAT_INTEL_X86_PINCTRL ,/* Intel ICH7/9 pin control */ COMPAT_SOCIONEXT_XHCI ,/* Socionext UniPhier xHCI */ COMPAT_INTEL_PCH, /* Intel PCH */
lib/fdtdec.c +1 -0
@@ -75,6 +75,7 @@ static const char * const compat_names[COMPAT_COUNT] = {COMPAT (AMS_AS3722 ,"ams,as3722" ),COMPAT (INTEL_ICH_SPI ,"intel,ich-spi" ),COMPAT (INTEL_QRK_MRC ,"intel,quark-mrc" ), +COMPAT (INTEL_X86_PINCTRL ,"intel,x86-pinctrl" ),COMPAT (SOCIONEXT_XHCI ,"socionext,uniphier-xhci" ), COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), };
Signature · 1 line
2.1.4
PATCH v4 3/4 x86: gpio: add pinctrl support from the device tree
Quoted 30 lines · Gabriel Huau
Every pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
Signed-off-by Gabriel Huau <[email protected]>---
Changes in v4:
- Rebase modification on latest update
- Fix typo to read the io-base
- Fixdirection_outputfunction to set the valueChanges in v3:
- Fix the dt-binding copyright header
- Remove define for IOBASE and use a property
- Fix issues with signed/unsigned variable type
- Fix coding style
- Add a compatible string for the driverChanges in v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.
Quoted 10 lines
arch/x86/dts/minnowmax.dts | 23 ++ arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 257 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 31 +++ include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 317 insertions(+), 28 deletions(-) create mode 100644 doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt create mode 100644 include/dt-bindings/gpio/x86-gpio.h
Applied to u-boot-x86, thanks!
PATCH 4/4 x86: minnowmax: initialize the pin-muxing from device tree
In reply to Gabriel Huau--- board/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)
board/intel/minnowmax/minnowmax.c +9 -0
@@ -7,6 +7,7 @@#include <common.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> +#include <asm/gpio.h> #include <netdev.h> #include <smsc_lpc47m.h>
@@ -14,6 +15,14 @@DECLARE_GLOBAL_DATA_PTR ; +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE );
include/configs/minnowmax.h +1 -0
@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_NR_DRAM_BANKS 1
Signature · 1 line
2.1.4
[U-Boot] unassigned-patches/143: [PATCH 4/4] x86: minnowmax: initialize the pin-muxing from device tree
---
Added to GNATS database as unassigned-patches/143
Quoted 5 lines
Responsible: patch-coord Message-Id: <[email protected]> In-Reply-To: <[email protected]> References: <[email protected]> Patch-Date: Thu Apr 23 18:16:15 +0200 2015
--- board/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)
board/intel/minnowmax/minnowmax.c +9 -0
@@ -7,6 +7,7 @@#include <common.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> +#include <asm/gpio.h> #include <netdev.h> #include <smsc_lpc47m.h>
@@ -14,6 +15,14 @@DECLARE_GLOBAL_DATA_PTR ; +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE );
include/configs/minnowmax.h +1 -0
@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_NR_DRAM_BANKS 1
Signature · 1 line
2.1.4
PATCH 4/4 x86: minnowmax: initialize the pin-muxing from device tree
In reply to Gabriel HuauHi Grabriel,
On 23 April 2015 at 10:16, Gabriel Huau <[email protected]> wrote:
<commit message here>
Quoted 11 lines
Signed-off-by Gabriel Huau <[email protected]>--- board/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)board/intel/minnowmax/minnowmax.c +0
-0
board/intel/minnowmax/minnowmax.c line 10
Quoted 4 lines
board/intel/minnowmax/minnowmax.c +1
-0@@ -7,6 +7,7 @@#include <common.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> +#include <asm/gpio.h>
This should go up one line I think, for ordering.
Quoted 31 lines
board/intel/minnowmax/minnowmax.c +8
-0#include <netdev.h> #include <smsc_lpc47m.h> @@ -14,6 +15,14 @@DECLARE_GLOBAL_DATA_PTR ; +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE );include/configs/minnowmax.h +1
-1@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_NR_DRAM_BANKS 1 --
Quoted 2 lines
2.1.4
Regards,
Simon
[U-Boot] unassigned-patches/145: Re: [PATCH 4/4] x86: minnowmax: initialize the pin-muxing from device tree
Hi Grabriel,
On 23 April 2015 at 10:16, Gabriel Huau <[email protected]> wrote:
<commit message here>
Quoted 11 lines
Signed-off-by Gabriel Huau <[email protected]>--- board/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)board/intel/minnowmax/minnowmax.c +0
-0
board/intel/minnowmax/minnowmax.c line 10
Quoted 4 lines
board/intel/minnowmax/minnowmax.c +1
-0@@ -7,6 +7,7 @@#include <common.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> +#include <asm/gpio.h>
This should go up one line I think, for ordering.
Quoted 31 lines
board/intel/minnowmax/minnowmax.c +8
-0#include <netdev.h> #include <smsc_lpc47m.h> @@ -14,6 +15,14 @@DECLARE_GLOBAL_DATA_PTR ; +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE );include/configs/minnowmax.h +1
-1@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_NR_DRAM_BANKS 1 --
Quoted 2 lines
2.1.4
Regards,
Simon
---
Added to GNATS database as unassigned-patches/145
Quoted 5 lines
Responsible: patch-coord Message-Id: <CAPnjgZ1djEV3BHjoLysmc-O+KSsvN7rrn=S=qXEyUYwpErwNiQ@mail.gmail.com> In-Reply-To: <[email protected]> References: <[email protected]> <[email protected]> Patch-Date: Fri Apr 24 05:37:28 +0200 2015
PATCH v2 4/4 x86: minnowmax: initialize the pin-muxing from device tree
In reply to Gabriel Huau---
Changes for v2:
- Fix ordering of include header
board/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)
board/intel/minnowmax/minnowmax.c +9 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <asm/gpio.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> #include <netdev.h>
@@ -14,6 +15,14 @@DECLARE_GLOBAL_DATA_PTR ; +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE );
include/configs/minnowmax.h +1 -0
@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_NR_DRAM_BANKS 1
Signature · 1 line
2.1.4
PATCH v2 4/4 x86: minnowmax: initialize the pin-muxing from device tree
Quoted 41 lines · Gabriel Huau
Signed-off-by Gabriel Huau <[email protected]>---
Changes for v2:
- Fix ordering of include headerboard/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)board/intel/minnowmax/minnowmax.c +9
-0@@ -5,6 +5,7 @@*/ #include <common.h> +#include <asm/gpio.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> #include <netdev.h> @@ -14,6 +15,14 @@DECLARE_GLOBAL_DATA_PTR ; +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE );include/configs/minnowmax.h +0
-0
include/configs/minnowmax.h line 20
Quoted 6 lines
include/configs/minnowmax.h +1
-0@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_NR_DRAM_BANKS 1
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
In reply to Gabriel Huau---
Changes in v3:
- Rebase to the origin/master
Changes in v2:
- Fix ordering of include header
board/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)
board/intel/minnowmax/minnowmax.c +9 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <asm/gpio.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> #include <netdev.h>
@@ -12,6 +13,14 @@#define SERIAL_DEV PNP_DEV(0x2e, 4) +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE ,UART0_IRQ );
include/configs/minnowmax.h +1 -0
@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_X86_SERIAL #define CONFIG_SMSC_LPC47M
Signature · 1 line
2.1.4
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
Quoted 8 lines · Gabriel Huau
Signed-off-by Gabriel Huau <[email protected]>Acked-by Simon Glass <[email protected]>---
Changes in v3:
- Rebase to the origin/master
Quoted 6 lines
Changes in v2:
- Fix ordering of include headerboard/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)
Applied to u-boot-x86, thanks!
[U-Boot] unassigned-patches/142: [PATCH 0/4] x86: support of pin-muxing from device tree
In reply to Gabriel HuauThis serie of patches adds the support of pin-muxing from the device tree through different properties. I have put two example to enable the USB Host on the minnowboard max.
The support of the call to 'setup_pch_gpios' is still supported and only the minnowboard has been tested with the device tree implementation.
Because the GPIO and IO base register ares different, I have also defined some proxy function to set the function/value and direction of the GPIO as the GPIO register can override some registers in the IO.
Gabriel Huau (4):
x86: baytrail: fix the GPIOBASE address
x86: minnowmax: add GPIO banks in the device tree
x86: gpio: add pinctrl support from the device tree
x86: minnowmax: initialize the pin-muxing from device tree
arch/x86/dts/minnowmax.dts | 63 +++++++++ arch/x86/include/asm/arch-baytrail/gpio.h | 3 +- arch/x86/include/asm/gpio.h | 1 + board/intel/minnowmax/minnowmax.c | 9 ++ drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/configs/minnowmax.h | 1 + include/dt-bindings/gpio/gpio.h | 20 +++ 7 files changed, 292 insertions(+), 27 deletions(-)
--
2.1.4
---
Added to GNATS database as unassigned-patches/142
Quoted 5 lines
Responsible: patch-coord Message-Id: <[email protected]>In-Reply-To:
References:
Patch-Date: Thu Apr 23 18:16:11 +0200 2015
cover x86: support of pin-muxing from device tree
In reply to Gabriel HuauHi Gabriel,
Quoted 26 lines · Gabriel Huau
This serie of patches adds the support of pin-muxing from the device tree through different properties. I have put two example to enable the USB Host on the minnowboard max.
The support of the call to '
setup_pch_gpios' is still supported and only the minnowboard has been tested with the device tree implementation.Because the GPIO and IO base register ares different, I have also defined some proxy function to set the function/value and direction of the GPIO as the GPIO register can override some registers in the IO.
Gabriel Huau (4):
x86: baytrail: fix the GPIOBASE address
x86: minnowmax: add GPIO banks in the device tree
x86: gpio: add pinctrl support from the device tree
x86: minnowmax: initialize the pin-muxing from device treearch/x86/dts/minnowmax.dts | 63 +++++++++ arch/x86/include/asm/arch-baytrail/gpio.h | 3 +- arch/x86/include/asm/gpio.h | 1 + board/intel/minnowmax/minnowmax.c | 9 ++ drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/configs/minnowmax.h | 1 + include/dt-bindings/gpio/gpio.h | 20 +++ 7 files changed, 292 insertions(+), 27 deletions(-)
Quoted 1 line
--
Thanks for these patches! Just a general comment, you don't need send emails to u-boot-patches at bugs.denx.de, and always include a simple sentence in the commit message :)
Regards,
Bin
[U-Boot] unassigned-patches/148: Re: [PATCH 0/4] x86: support of pin-muxing from device tree
Hi Gabriel,
Quoted 26 lines · Gabriel Huau
This serie of patches adds the support of pin-muxing from the device tree through different properties. I have put two example to enable the USB Host on the minnowboard max.
The support of the call to '
setup_pch_gpios' is still supported and only the minnowboard has been tested with the device tree implementation.Because the GPIO and IO base register ares different, I have also defined some proxy function to set the function/value and direction of the GPIO as the GPIO register can override some registers in the IO.
Gabriel Huau (4):
x86: baytrail: fix the GPIOBASE address
x86: minnowmax: add GPIO banks in the device tree
x86: gpio: add pinctrl support from the device tree
x86: minnowmax: initialize the pin-muxing from device treearch/x86/dts/minnowmax.dts | 63 +++++++++ arch/x86/include/asm/arch-baytrail/gpio.h | 3 +- arch/x86/include/asm/gpio.h | 1 + board/intel/minnowmax/minnowmax.c | 9 ++ drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/configs/minnowmax.h | 1 + include/dt-bindings/gpio/gpio.h | 20 +++ 7 files changed, 292 insertions(+), 27 deletions(-)
Quoted 1 line
--
Thanks for these patches! Just a general comment, you don't need send emails to u-boot-patches at bugs.denx.de, and always include a simple sentence in the commit message :)
Regards,
Bin
---
Added to GNATS database as unassigned-patches/148
Quoted 5 lines
Responsible: patch-coord Message-Id: <CAEUhbmVTxF6NKX62O0JWXaTyYdbSqduv7SyYEw7jC-XqUjjKTQ@mail.gmail.com> In-Reply-To: <[email protected]> References: <[email protected]> Patch-Date: Fri Apr 24 05:23:35 +0200 2015
cover x86: support of pin-muxing from device tree
In reply to Bin MengHi Bin,
Quoted 29 lines · Bin Meng
Hi Gabriel,
Quoted 26 lines · Gabriel Huau
This serie of patches adds the support of pin-muxing from the device tree through different properties. I have put two example to enable the USB Host on the minnowboard max.
The support of the call to '
setup_pch_gpios' is still supported and only the minnowboard has been tested with the device tree implementation.Because the GPIO and IO base register ares different, I have also defined some proxy function to set the function/value and direction of the GPIO as the GPIO register can override some registers in the IO.
Gabriel Huau (4):
x86: baytrail: fix the GPIOBASE address
x86: minnowmax: add GPIO banks in the device tree
x86: gpio: add pinctrl support from the device tree
x86: minnowmax: initialize the pin-muxing from device treearch/x86/dts/minnowmax.dts | 63 +++++++++ arch/x86/include/asm/arch-baytrail/gpio.h | 3 +- arch/x86/include/asm/gpio.h | 1 + board/intel/minnowmax/minnowmax.c | 9 ++ drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/configs/minnowmax.h | 1 + include/dt-bindings/gpio/gpio.h | 20 +++ 7 files changed, 292 insertions(+), 27 deletions(-)
Quoted 7 lines
Quoted 1 line
--
Thanks for these patches! Just a general comment, you don't need send emails to u-boot-patches at bugs.denx.de, and always include a simple sentence in the commit message :)
Regards,
Bin
That's why I received plenty of emails to tell me that my patches were not assigned :).
I'll do the modification for the next version, thank you for the feedback, I appreciate this.
Regards,
Gabriel
[U-Boot] unassigned-patches/151: Re: [PATCH 0/4] x86: support of pin-muxing from device tree
Hi Bin,
Quoted 29 lines · Bin Meng
Hi Gabriel,
Quoted 26 lines · Gabriel Huau
This serie of patches adds the support of pin-muxing from the device tree through different properties. I have put two example to enable the USB Host on the minnowboard max.
The support of the call to '
setup_pch_gpios' is still supported and only the minnowboard has been tested with the device tree implementation.Because the GPIO and IO base register ares different, I have also defined some proxy function to set the function/value and direction of the GPIO as the GPIO register can override some registers in the IO.
Gabriel Huau (4):
x86: baytrail: fix the GPIOBASE address
x86: minnowmax: add GPIO banks in the device tree
x86: gpio: add pinctrl support from the device tree
x86: minnowmax: initialize the pin-muxing from device treearch/x86/dts/minnowmax.dts | 63 +++++++++ arch/x86/include/asm/arch-baytrail/gpio.h | 3 +- arch/x86/include/asm/gpio.h | 1 + board/intel/minnowmax/minnowmax.c | 9 ++ drivers/gpio/intel_ich6_gpio.c | 222 ++++++++++++++++++++++++++---- include/configs/minnowmax.h | 1 + include/dt-bindings/gpio/gpio.h | 20 +++ 7 files changed, 292 insertions(+), 27 deletions(-)
Quoted 7 lines
Quoted 1 line
--
Thanks for these patches! Just a general comment, you don't need send emails to u-boot-patches at bugs.denx.de, and always include a simple sentence in the commit message :)
Regards,
Bin
That's why I received plenty of emails to tell me that my patches were not assigned :).
I'll do the modification for the next version, thank you for the feedback, I appreciate this.
Regards,
Gabriel
---
Added to GNATS database as unassigned-patches/151
Quoted 5 lines
Responsible: patch-coord Message-Id: <[email protected]> In-Reply-To: <CAEUhbmVTxF6NKX62O0JWXaTyYdbSqduv7SyYEw7jC-XqUjjKTQ@mail.gmail.com> References: <[email protected]> <CAEUhbmVTxF6NKX62O0JWXaTyYdbSqduv7SyYEw7jC-XqUjjKTQ@mail.gmail.com> Patch-Date: Fri Apr 24 16:40:04 +0200 2015
PATCH v3 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Gabriel HuauEvery pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
---
Changes in v3:
- Fix the dt-binding copyright header
- Remove define for IOBASE and use a property
- Fix issues with signed/unsigned variable type
- Fix coding style
- Add a compatible string for the driver
Changes in v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.
arch/x86/dts/minnowmax.dts | 23 ++ arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 254 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 31 +++ include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 312 insertions(+), 30 deletions(-) create mode 100644 doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt create mode 100644 include/dt-bindings/gpio/x86-gpio.h
arch/x86/dts/minnowmax.dts +23 -0
@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
@@ -22,6 +24,27 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + io-base = <0x4c>; + + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;
arch/x86/include/asm/gpio.h +1 -0
@@ -147,6 +147,7 @@ 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);
doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31 -0
@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};
drivers/gpio/intel_ich6_gpio.c +224 -30
306 lines not on this page · raw message
include/dt-bindings/gpio/x86-gpio.h new file +31 -0
@@ -0,0 +1,31 @@ +/* +* This header provides constants for binding intel,x86-pinctrl. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 + +#endif
include/fdtdec.h +1 -0
@@ -175,6 +175,7 @@ enum fdt_compat_id {COMPAT_AMS_AS3722 ,/* AMS AS3722 PMIC */ COMPAT_INTEL_ICH_SPI ,/* Intel ICH7/9 SPI controller */ COMPAT_INTEL_QRK_MRC ,/* Intel Quark MRC */ +COMPAT_INTEL_X86_PINCTRL ,/* Intel ICH7/9 pin control */ COMPAT_SOCIONEXT_XHCI ,/* Socionext UniPhier xHCI */ COMPAT_INTEL_PCH, /* Intel PCH */
lib/fdtdec.c +1 -0
@@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {COMPAT (AMS_AS3722 ,"ams,as3722" ),COMPAT (INTEL_ICH_SPI ,"intel,ich-spi" ),COMPAT (INTEL_QRK_MRC ,"intel,quark-mrc" ), +COMPAT (INTEL_X86_PINCTRL ,"intel,x86-pinctrl" ),COMPAT (SOCIONEXT_XHCI ,"socionext,uniphier-xhci" ), COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), };
Signature · 1 line
2.1.4
PATCH v3 3/4 x86: gpio: add pinctrl support from the device tree
Please ignore this email/patch, I put the wrong message id ...
Quoted 503 lines · Gabriel Huau
Every pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
Signed-off-by Gabriel Huau <[email protected]>---
Changes in v3:
- Fix the dt-binding copyright header
- Remove define for IOBASE and use a property
- Fix issues with signed/unsigned variable type
- Fix coding style
- Add a compatible string for the driverChanges in v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.arch/x86/dts/minnowmax.dts | 23 ++ arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 254 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 31 +++ include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 312 insertions(+), 30 deletions(-)create mode 100644
doc/device-tree-bindings/gpio/intel,x86-pinctrl.txtcreate mode 100644include/dt-bindings/gpio/x86-gpio.harch/x86/dts/minnowmax.dts +23
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"@@ -22,6 +24,27 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + io-base = <0x4c>; + + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31
-0@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};drivers/gpio/intel_ich6_gpio.c +224
-30@@ -44,21 +44,28 @@ struct ich6_bank_priv {uint16_t 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) +#define IOPAD_PULL_STRENGTH_SHIFT 9 +#define IOPAD_PULL_STRENGTH_MASK (0x3 << IOPAD_PULL_STRENGTH_SHIFT) +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev); -pci_dev_t pci_dev;/* handle for 0:1f:0 */ +pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );@@ -123,9 +130,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE ); + tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }@@ -135,7 +142,213 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +static int _ich6_gpio_set_value (uint16_t base,unsigned offset,int value) +{ +u32 val; + + val =inl (base); +if (value) + val |= (1UL << offset); +else + val &= ~(1UL << offset); +outl (val, base); + +return 0 ; +} + +static int _ich6_gpio_set_function (uint16_t base,unsigned offset,int func) +{ +u32 val; + +if (func) { + val =inl (base); + val |= (1UL << offset); +outl (val, base); + }else { + val =inl (base); + val &= ~(1UL << offset); +outl (val, base); + } + +return 0 ; +} + +static int _ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) +{ +u32 val; + +if (!dir) { + val =inl (base); + val |= (1UL << offset); +outl (val, base); + }else { + val =inl (base); + val &= ~(1UL << offset); +outl (val, base); + } + +return 0 ; +} + +static int _gpio_ich6_pinctrl_cfg_pin (s32 gpiobase,s32 iobase,int pin_node) +{ +u32 gpio_offset[2 ]; +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) { +/* 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 ); + + 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); + + 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); + } + +/* if iobase is present, let's configure the pad */ +if (iobase !=-1 ) { +int iobase_addr; + +/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset = +fdtdec_get_int (gd->fdt_blob, pin_node,"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset); +return -EINVAL ; + } + +/* compute the absolute pad address */ + iobase_addr = iobase + pad_offset; + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + val =fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (val !=-1 ) +clrsetbits_le32 (iobase_addr,IOPAD_MODE_MASK , val); + +/* Configure the pull-up/down if needed */ + val =fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (val !=-1 ) +clrsetbits_le32 (iobase_addr, +IOPAD_PULL_ASSIGN_MASK , + val <<IOPAD_PULL_ASSIGN_SHIFT ); + + val = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (val !=-1 ) +clrsetbits_le32 (iobase_addr, +IOPAD_PULL_STRENGTH_MASK , + val <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase_addr)); + } + +return 0 ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +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 ; + } + +/* This is not an error to not have a pinctrl node */ + node = +fdtdec_next_compatible (gd->fdt_blob,0 ,COMPAT_INTEL_X86_PINCTRL ); +if (node <=0 ) { +debug ("%s: no pinctrl node\n" , __func__); +return 0 ; + } + +/* +* Get the IOBASE, this is not mandatory as this is not +* supported by all the CPU +*/ + iobase_offset =fdtdec_get_int (gd->fdt_blob, node,"io-offset" ,-1 ); +if (iobase_offset ==-1 ) { +debug ("%s: io-base offset not present\n" , __func__); + }else { + iobase =gpio_ich6_get_base (iobase_offset); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, + iobase); +return -EINVAL ; + } + } + +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + 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); +if (ret !=0 ) { +debug ("%s: invalid configuration for the pin %d\n" , + __func__, pin_node); +return ret; + } + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -192,30 +405,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); -u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); -return 0 ; +return _ich6_gpio_set_direction (inl (bank->io_sel), offset,0 ); }static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset,int value) {struct ich6_bank_priv *bank =dev_get_priv (dev); -u32 tmplong; -gpio_set_value (offset, value); - - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong); -return 0 ; +return _ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); }static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) - {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -230,15 +432,7 @@ static int ich6_gpio_set_value(struct udevice *dev, unsigned offset, int value) {struct ich6_bank_priv *bank =dev_get_priv (dev); -u32 tmplong; - - tmplong =inl (bank->lvl); -if (value) - tmplong |= (1UL << offset); -else - tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); -return 0 ; +return _ich6_gpio_set_value (bank->lvl, offset, value); }static int ich6_gpio_get_function (struct udevice *dev,unsigned offset)include/dt-bindings/gpio/x86-gpio.h new file +31
-0@@ -0,0 +1,31 @@ +/* +* This header provides constants for binding intel,x86-pinctrl. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 + +#endif include/fdtdec.h +1
-0@@ -175,6 +175,7 @@ enum fdt_compat_id {COMPAT_AMS_AS3722 ,/* AMS AS3722 PMIC */ COMPAT_INTEL_ICH_SPI ,/* Intel ICH7/9 SPI controller */ COMPAT_INTEL_QRK_MRC ,/* Intel Quark MRC */ +COMPAT_INTEL_X86_PINCTRL ,/* Intel ICH7/9 pin control */ COMPAT_SOCIONEXT_XHCI ,/* Socionext UniPhier xHCI */ COMPAT_INTEL_PCH, /* Intel PCH */lib/fdtdec.c +1
-0@@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {COMPAT (AMS_AS3722 ,"ams,as3722" ),COMPAT (INTEL_ICH_SPI ,"intel,ich-spi" ),COMPAT (INTEL_QRK_MRC ,"intel,quark-mrc" ), +COMPAT (INTEL_X86_PINCTRL ,"intel,x86-pinctrl" ),COMPAT (SOCIONEXT_XHCI ,"socionext,uniphier-xhci" ), COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), };
PATCH v3 3/4 x86: gpio: add pinctrl support from the device tree
In reply to Gabriel HuauEvery pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
---
Changes in v3:
- Fix the dt-binding copyright header
- Remove define for IOBASE and use a property
- Fix issues with signed/unsigned variable type
- Fix coding style
- Add a compatible string for the driver
Changes in v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.
arch/x86/dts/minnowmax.dts | 23 ++ arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 254 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 31 +++ include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 312 insertions(+), 30 deletions(-) create mode 100644 doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt create mode 100644 include/dt-bindings/gpio/x86-gpio.h
arch/x86/dts/minnowmax.dts +23 -0
@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"
@@ -22,6 +24,27 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + io-base = <0x4c>; + + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;
arch/x86/include/asm/gpio.h +1 -0
@@ -147,6 +147,7 @@ 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);
doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31 -0
@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};
drivers/gpio/intel_ich6_gpio.c +224 -30
306 lines not on this page · raw message
include/dt-bindings/gpio/x86-gpio.h new file +31 -0
@@ -0,0 +1,31 @@ +/* +* This header provides constants for binding intel,x86-pinctrl. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 + +#endif
include/fdtdec.h +1 -0
@@ -175,6 +175,7 @@ enum fdt_compat_id {COMPAT_AMS_AS3722 ,/* AMS AS3722 PMIC */ COMPAT_INTEL_ICH_SPI ,/* Intel ICH7/9 SPI controller */ COMPAT_INTEL_QRK_MRC ,/* Intel Quark MRC */ +COMPAT_INTEL_X86_PINCTRL ,/* Intel ICH7/9 pin control */ COMPAT_SOCIONEXT_XHCI ,/* Socionext UniPhier xHCI */ COMPAT_INTEL_PCH, /* Intel PCH */
lib/fdtdec.c +1 -0
@@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {COMPAT (AMS_AS3722 ,"ams,as3722" ),COMPAT (INTEL_ICH_SPI ,"intel,ich-spi" ),COMPAT (INTEL_QRK_MRC ,"intel,quark-mrc" ), +COMPAT (INTEL_X86_PINCTRL ,"intel,x86-pinctrl" ),COMPAT (SOCIONEXT_XHCI ,"socionext,uniphier-xhci" ), COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), };
Signature · 1 line
2.1.4
PATCH v3 3/4 x86: gpio: add pinctrl support from the device tree
Please ignore this email/patch, I put the wrong message id ...
Quoted 503 lines · Gabriel Huau
Every pin can be configured now from the device tree. A dt-bindings has been added to describe the different property available.
Signed-off-by Gabriel Huau <[email protected]>---
Changes in v3:
- Fix the dt-binding copyright header
- Remove define for IOBASE and use a property
- Fix issues with signed/unsigned variable type
- Fix coding style
- Add a compatible string for the driverChanges in v2:
- Clean commit message
- Rename compatible string 'ich6' to 'x86'
- Fix coding style
- Create a dt-bindinds documentation
- Move x86-gpio defines to a specific header
- Reorder the functions to avoid the need for forward declarations
- Rename double underscore functions to only one
- Create a specific function to configure one pin
- Use a define to prevent build/support issues with other x86 CPU that doesn't have a IOBASE.arch/x86/dts/minnowmax.dts | 23 ++ arch/x86/include/asm/gpio.h | 1 + .../gpio/intel,x86-pinctrl.txt | 31 +++ drivers/gpio/intel_ich6_gpio.c | 254 ++++++++++++++++++--- include/dt-bindings/gpio/x86-gpio.h | 31 +++ include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 312 insertions(+), 30 deletions(-)create mode 100644
doc/device-tree-bindings/gpio/intel,x86-pinctrl.txtcreate mode 100644include/dt-bindings/gpio/x86-gpio.harch/x86/dts/minnowmax.dts +23
-0@@ -6,6 +6,8 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "serial.dtsi"@@ -22,6 +24,27 @@ silent_console = <0>; }; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + io-base = <0x4c>; + + pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + + pin_usb_host_en1 at 0 { + gpio-offset = <0x80 9>; + pad-offset = <0x258>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; + }; + }; + gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc;arch/x86/include/asm/gpio.h +1
-0@@ -147,6 +147,7 @@ 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);doc/device-tree-bindings/gpio/intel,x86-pinctrl.txt new file +31
-0@@ -0,0 +1,31 @@ +Intel x86 PINCTRL/GPIO controller + +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. + +The PINCTRL master node requires the following properties: +- compatible : "intel,x86-pinctrl" + +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' + 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. +- 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. + +Example: + +pin_usb_host_en0 at 0 { + gpio-offset = <0x80 8>; + pad-offset = <0x260>; + mode-gpio; + output-value = <1>; + direction = <PIN_OUTPUT>; +};drivers/gpio/intel_ich6_gpio.c +224
-30@@ -44,21 +44,28 @@ struct ich6_bank_priv {uint16_t 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) +#define IOPAD_PULL_STRENGTH_SHIFT 9 +#define IOPAD_PULL_STRENGTH_MASK (0x3 << IOPAD_PULL_STRENGTH_SHIFT) +/* TODO: Move this to device tree, or platform data */ void ich_gpio_set_gpio_map (const struct pch_gpio_map *map) { gd->arch.gpio_map = map; } -static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +static int gpio_ich6_get_base (unsigned long base) { -struct ich6_bank_platdata *plat =dev_get_platdata (dev); -pci_dev_t pci_dev;/* handle for 0:1f:0 */ +pci_dev_t pci_dev;/* handle for 0:1f:0 */ u8 tmpbyte;u16 tmpword;u32 tmplong; -u16 gpiobase; -int offset;/* Where should it be? */ pci_dev =PCI_BDF (0 ,0x1f ,0 );@@ -123,9 +130,9 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong =x86_pci_read_config32 (pci_dev,PCI_CFG_GPIOBASE ); + tmplong =x86_pci_read_config32 (pci_dev, base);if (tmplong ==0x00000000 || tmplong ==0xffffffff ) { -debug ("%s: unexpected GPIOBASE value\n" , __func__); +debug ("%s: unexpected BASE value\n" , __func__);return -ENODEV ; }@@ -135,7 +142,213 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)* at the offset that we just read. Bit 0 indicates that it's * an I/O address, not a memory address, so mask that off. */ - gpiobase = tmplong &0xfffe ; +return tmplong &0xfffc ; +} + +static int _ich6_gpio_set_value (uint16_t base,unsigned offset,int value) +{ +u32 val; + + val =inl (base); +if (value) + val |= (1UL << offset); +else + val &= ~(1UL << offset); +outl (val, base); + +return 0 ; +} + +static int _ich6_gpio_set_function (uint16_t base,unsigned offset,int func) +{ +u32 val; + +if (func) { + val =inl (base); + val |= (1UL << offset); +outl (val, base); + }else { + val =inl (base); + val &= ~(1UL << offset); +outl (val, base); + } + +return 0 ; +} + +static int _ich6_gpio_set_direction (uint16_t base,unsigned offset,int dir) +{ +u32 val; + +if (!dir) { + val =inl (base); + val |= (1UL << offset); +outl (val, base); + }else { + val =inl (base); + val &= ~(1UL << offset); +outl (val, base); + } + +return 0 ; +} + +static int _gpio_ich6_pinctrl_cfg_pin (s32 gpiobase,s32 iobase,int pin_node) +{ +u32 gpio_offset[2 ]; +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) { +/* 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 ); + + 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); + + 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); + } + +/* if iobase is present, let's configure the pad */ +if (iobase !=-1 ) { +int iobase_addr; + +/* +* The offset for the same pin for the IOBASE and GPIOBASE are +* different, so instead of maintaining a lookup table, +* the device tree should provide directly the correct +* value for both mapping. +*/ + pad_offset = +fdtdec_get_int (gd->fdt_blob, pin_node,"pad-offset" ,-1 ); +if (pad_offset ==-1 ) { +debug ("%s: Invalid register io offset %d\n" , + __func__, pad_offset); +return -EINVAL ; + } + +/* compute the absolute pad address */ + iobase_addr = iobase + pad_offset; + +/* +* Do we need to set a specific function mode? +* If someone put also 'mode-gpio', this option will +* be just ignored by the controller +*/ + val =fdtdec_get_int (gd->fdt_blob, pin_node,"mode-func" ,-1 ); +if (val !=-1 ) +clrsetbits_le32 (iobase_addr,IOPAD_MODE_MASK , val); + +/* Configure the pull-up/down if needed */ + val =fdtdec_get_int (gd->fdt_blob, pin_node,"pull-assign" ,-1 ); +if (val !=-1 ) +clrsetbits_le32 (iobase_addr, +IOPAD_PULL_ASSIGN_MASK , + val <<IOPAD_PULL_ASSIGN_SHIFT ); + + val = +fdtdec_get_int (gd->fdt_blob, pin_node,"pull-strength" ,-1 ); +if (val !=-1 ) +clrsetbits_le32 (iobase_addr, +IOPAD_PULL_STRENGTH_MASK , + val <<IOPAD_PULL_STRENGTH_SHIFT ); + +debug ("%s: pad cfg [0x%x]: %08x\n" , __func__, pad_offset, +readl (iobase_addr)); + } + +return 0 ; +} + +int gpio_ich6_pinctrl_init (void ) +{ +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 ; + } + +/* This is not an error to not have a pinctrl node */ + node = +fdtdec_next_compatible (gd->fdt_blob,0 ,COMPAT_INTEL_X86_PINCTRL ); +if (node <=0 ) { +debug ("%s: no pinctrl node\n" , __func__); +return 0 ; + } + +/* +* Get the IOBASE, this is not mandatory as this is not +* supported by all the CPU +*/ + iobase_offset =fdtdec_get_int (gd->fdt_blob, node,"io-offset" ,-1 ); +if (iobase_offset ==-1 ) { +debug ("%s: io-base offset not present\n" , __func__); + }else { + iobase =gpio_ich6_get_base (iobase_offset); +if (iobase <0 ) { +debug ("%s: invalid IOBASE address (%08x)\n" , __func__, + iobase); +return -EINVAL ; + } + } + +for (pin_node =fdt_first_subnode (gd->fdt_blob, node); + 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); +if (ret !=0 ) { +debug ("%s: invalid configuration for the pin %d\n" , + __func__, pin_node); +return ret; + } + } + +return 0 ; +} + +static int gpio_ich6_ofdata_to_platdata (struct udevice *dev) +{ +struct ich6_bank_platdata *plat =dev_get_platdata (dev); +u16 gpiobase; +int offset; + + gpiobase =gpio_ich6_get_base (PCI_CFG_GPIOBASE ); offset =fdtdec_get_int (gd->fdt_blob, dev->of_offset,"reg" ,-1 );if (offset ==-1 ) {debug ("%s: Invalid register offset %d\n" , __func__, offset);@@ -192,30 +405,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); -u32 tmplong; - tmplong =inl (bank->io_sel); - tmplong |= (1UL << offset); -outl (bank->io_sel, tmplong); -return 0 ; +return _ich6_gpio_set_direction (inl (bank->io_sel), offset,0 ); }static int ich6_gpio_direction_output (struct udevice *dev,unsigned offset,int value) {struct ich6_bank_priv *bank =dev_get_priv (dev); -u32 tmplong; -gpio_set_value (offset, value); - - tmplong =inl (bank->io_sel); - tmplong &= ~(1UL << offset); -outl (bank->io_sel, tmplong); -return 0 ; +return _ich6_gpio_set_direction (inl (bank->io_sel), offset,1 ); }static int ich6_gpio_get_value (struct udevice *dev,unsigned offset) - {struct ich6_bank_priv *bank =dev_get_priv (dev);u32 tmplong;@@ -230,15 +432,7 @@ static int ich6_gpio_set_value(struct udevice *dev, unsigned offset, int value) {struct ich6_bank_priv *bank =dev_get_priv (dev); -u32 tmplong; - - tmplong =inl (bank->lvl); -if (value) - tmplong |= (1UL << offset); -else - tmplong &= ~(1UL << offset); -outl (bank->lvl, tmplong); -return 0 ; +return _ich6_gpio_set_value (bank->lvl, offset, value); }static int ich6_gpio_get_function (struct udevice *dev,unsigned offset)include/dt-bindings/gpio/x86-gpio.h new file +31
-0@@ -0,0 +1,31 @@ +/* +* This header provides constants for binding intel,x86-pinctrl. +*/ + +#ifndef _DT_BINDINGS_GPIO_X86_GPIO_H +#define _DT_BINDINGS_GPIO_X86_GPIO_H + +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_MODE_NATIVE 0 +#define GPIO_MODE_GPIO 1 + +#define GPIO_MODE_FUNC0 0 +#define GPIO_MODE_FUNC1 1 +#define GPIO_MODE_FUNC2 2 +#define GPIO_MODE_FUNC3 3 +#define GPIO_MODE_FUNC4 4 +#define GPIO_MODE_FUNC5 5 +#define GPIO_MODE_FUNC6 6 + +#define PIN_INPUT 0 +#define PIN_OUTPUT 1 + +#define PIN_INPUT_NOPULL 0 +#define PIN_INPUT_PULLUP 1 +#define PIN_INPUT_PULLDOWN 2 + +#define PULL_STR_2K 0 +#define PULL_STR_20K 2 + +#endif include/fdtdec.h +1
-0@@ -175,6 +175,7 @@ enum fdt_compat_id {COMPAT_AMS_AS3722 ,/* AMS AS3722 PMIC */ COMPAT_INTEL_ICH_SPI ,/* Intel ICH7/9 SPI controller */ COMPAT_INTEL_QRK_MRC ,/* Intel Quark MRC */ +COMPAT_INTEL_X86_PINCTRL ,/* Intel ICH7/9 pin control */ COMPAT_SOCIONEXT_XHCI ,/* Socionext UniPhier xHCI */ COMPAT_INTEL_PCH, /* Intel PCH */lib/fdtdec.c +1
-0@@ -74,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {COMPAT (AMS_AS3722 ,"ams,as3722" ),COMPAT (INTEL_ICH_SPI ,"intel,ich-spi" ),COMPAT (INTEL_QRK_MRC ,"intel,quark-mrc" ), +COMPAT (INTEL_X86_PINCTRL ,"intel,x86-pinctrl" ),COMPAT (SOCIONEXT_XHCI ,"socionext,uniphier-xhci" ), COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), };
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
In reply to Gabriel Huau---
Changes in v3:
- Rebase to the origin/master
Changes in v2:
- Fix ordering of include header
board/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)
board/intel/minnowmax/minnowmax.c +9 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <asm/gpio.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> #include <netdev.h>
@@ -12,6 +13,14 @@#define SERIAL_DEV PNP_DEV(0x2e, 4) +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE ,UART0_IRQ );
include/configs/minnowmax.h +1 -0
@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_X86_SERIAL #define CONFIG_SMSC_LPC47M
Signature · 1 line
2.1.4
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
Please ignore this email/patch, I put the wrong message id ...
Quoted 54 lines · Gabriel Huau
Signed-off-by Gabriel Huau <[email protected]>Acked-by Simon Glass <[email protected]>---
Changes in v3:
- Rebase to the origin/masterChanges in v2:
- Fix ordering of include headerboard/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)board/intel/minnowmax/minnowmax.c +9
-0@@ -5,6 +5,7 @@*/ #include <common.h> +#include <asm/gpio.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> #include <netdev.h> @@ -12,6 +13,14 @@#define SERIAL_DEV PNP_DEV(0x2e, 4) +int arch_early_init_r (void ) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE ,UART0_IRQ );include/configs/minnowmax.h +1
-0@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_X86_SERIAL #define CONFIG_SMSC_LPC47M
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
Hi Gabriel,
I have two patches in patchwork:
http://patchwork.ozlabs.org/patch/471146/
http://patchwork.ozlabs.org/patch/471147/
Are they the correct ones? Also do you know how to use the gpio command to toggle a bin on the Minnowboard MAX header? I'd like to try that.
Regards,
Simon
Quoted 57 lines · gabriel huau
Please ignore this email/patch, I put the wrong message id ...
Quoted 51 lines · Gabriel Huau
Signed-off-by Gabriel Huau <[email protected]>Acked-by Simon Glass <[email protected]>---
Changes in v3:
- Rebase to the origin/masterChanges in v2:
- Fix ordering of include headerboard/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)board/intel/minnowmax/minnowmax.c +8
-0@@ -5,6 +5,7 @@*/ #include <common.h> +#include <asm/gpio.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> #include <netdev.h> @@ -12,6 +13,14 @@#define SERIAL_DEV PNP_DEV(0x2e, 4) +int arch_early_init_r(void) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE ,UART0_IRQ );include/configs/minnowmax.h +1
-0@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_X86_SERIAL #define CONFIG_SMSC_LPC47M
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
Hi Simon,
I just submitted a new version of the patch, actually, when I tried to use the GPIO on the header I saw a typo in the code.
To test it, you have to define these nodes in the device tree (should be there by default or not?):
soc_gpio_s5_0 at 0 {
gpio-offset = <0x80 0>;
pad-offset = <0x1d0>;
mode-gpio;
output-value = <0>;
direction = <PIN_OUTPUT>;
};
soc_gpio_s5_1 at 0 {
gpio-offset = <0x80 1>;
pad-offset = <0x210>;
mode-gpio;
output-value = <0>;
direction = <PIN_OUTPUT>;
};
soc_gpio_s5_2 at 0 {
gpio-offset = <0x80 2>;
pad-offset = <0x1e0>;
mode-gpio;
output-value = <0>;
direction = <PIN_OUTPUT>;
};And after, you can use the GPIO commands:
=> gpio set E0
gpio: pin E0 (gpio 128) value is 1
=> gpio clear E0
gpio: pin E0 (gpio 128) value is 0
=> gpio set E2
gpio: pin E2 (gpio 130) value is 1
=> gpio clear E2
gpio: pin E2 (gpio 130) value is 0
E0 E1 and E2 correspond to the GPIO0 1 and 2.
Regards,
Gabriel
Quoted 71 lines · Simon Glass
Hi Gabriel,
I have two patches in patchwork:
http://patchwork.ozlabs.org/patch/471146/
http://patchwork.ozlabs.org/patch/471147/Are they the correct ones? Also do you know how to use the gpio command to toggle a bin on the Minnowboard MAX header? I'd like to try that.
Regards,
SimonQuoted 55 lines · gabriel huau
Please ignore this email/patch, I put the wrong message id ...
Quoted 50 lines · Gabriel Huau
Signed-off-by Gabriel Huau <[email protected]>Acked-by Simon Glass <[email protected]>---
Changes in v3:
- Rebase to the origin/masterChanges in v2:
- Fix ordering of include headerboard/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)board/intel/minnowmax/minnowmax.c +8
-0@@ -5,6 +5,7 @@*/ #include <common.h> +#include <asm/gpio.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> #include <netdev.h> @@ -12,6 +13,14 @@#define SERIAL_DEV PNP_DEV(0x2e, 4) +int arch_early_init_r(void) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE ,UART0_IRQ );include/configs/minnowmax.h +1
-0@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_X86_SERIAL #define CONFIG_SMSC_LPC47M
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
Hi Gabriel,
Quoted 36 lines
soc_gpio_s5_0 at 0 { gpio-offset = <0x80 0>; pad-offset = <0x1d0>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; }; soc_gpio_s5_1 at 0 { gpio-offset = <0x80 1>; pad-offset = <0x210>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; }; soc_gpio_s5_2 at 0 { gpio-offset = <0x80 2>; pad-offset = <0x1e0>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; };And after, you can use the GPIO commands:
=> gpio set E0
gpio: pin E0 (gpio 128) value is 1
=> gpio clear E0
gpio: pin E0 (gpio 128) value is 0
=> gpio set E2
gpio: pin E2 (gpio 130) value is 1
=> gpio clear E2
gpio: pin E2 (gpio 130) value is 0
Quoted 1 line
E0 E1 and E2 correspond to the GPIO0 1 and 2.
Is there, or can someone add, some documentation somewhere as to how to convert between the device tree definition and the value used for "pin" in the gpio commands as it doesn't seem intuitive or obvious to me that what you have defined translates to E0, E1 and E2.
Thanks,
Andy.
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
Hi Andy,
Quoted 37 lines · Andy Pont
Hi Gabriel,
Quoted 35 lines
soc_gpio_s5_0 at 0 { gpio-offset = <0x80 0>; pad-offset = <0x1d0>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; }; soc_gpio_s5_1 at 0 { gpio-offset = <0x80 1>; pad-offset = <0x210>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; }; soc_gpio_s5_2 at 0 { gpio-offset = <0x80 2>; pad-offset = <0x1e0>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; };And after, you can use the GPIO commands:
=> gpio set E0
gpio: pin E0 (gpio 128) value is 1
=> gpio clear E0
gpio: pin E0 (gpio 128) value is 0
=> gpio set E2
gpio: pin E2 (gpio 130) value is 1
=> gpio clear E2
gpio: pin E2 (gpio 130) value is 0
Quoted 5 lines
Quoted 1 line
E0 E1 and E2 correspond to the GPIO0 1 and 2.
Is there, or can someone add, some documentation somewhere as to how to convert between the device tree definition and the value used for "pin" in the gpio commands as it doesn't seem intuitive or obvious to me that what you have defined translates to E0, E1 and E2.
I agree, but I think the documentation should be part of another patch, especially as this is the case for all the x86 platform.
The naming is not specific to the minnowboard max (baytrail).
Quoted 4 lines
Thanks,
Andy.
Regards,
Gabriel
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
Hi Gabriel,
Quoted 44 lines · Gabriel Huau
Hi Andy,
Quoted 41 lines · Andy Pont
Hi Gabriel,
Quoted 36 lines
soc_gpio_s5_0 at 0 { gpio-offset = <0x80 0>; pad-offset = <0x1d0>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; }; soc_gpio_s5_1 at 0 { gpio-offset = <0x80 1>; pad-offset = <0x210>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; }; soc_gpio_s5_2 at 0 { gpio-offset = <0x80 2>; pad-offset = <0x1e0>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; };And after, you can use the GPIO commands:
=> gpio set E0
gpio: pin E0 (gpio 128) value is 1
=> gpio clear E0
gpio: pin E0 (gpio 128) value is 0
=> gpio set E2
gpio: pin E2 (gpio 130) value is 1
=> gpio clear E2
gpio: pin E2 (gpio 130) value is 0E0 E1 and E2 correspond to the GPIO0 1 and 2.
Quoted 8 lines
Quoted 4 lines
Is there, or can someone add, some documentation somewhere as to how to convert between the device tree definition and the value used for "pin" in the gpio commands as it doesn't seem intuitive or obvious to me that what you have defined translates to E0, E1 and E2.
I agree, but I think the documentation should be part of another patch, especially as this is the case for all the x86 platform.
The naming is not specific to the minnowboard max (baytrail).
Sounds good, please go ahead.
Regards,
Simon
PATCH v3 4/4 x86: minnowmax: initialize the pin-muxing from device tree
In reply to gabriel huauHi Gabriel,
Quoted 7 lines · gabriel huau
Hi Simon,
I just submitted a new version of the patch, actually, when I tried to use the GPIO on the header I saw a typo in the code.
To test it, you have to define these nodes in the device tree (should be there by default or not?):
Yes I think so. Can you please send a patch?
Quoted 36 lines
soc_gpio_s5_0 at 0 { gpio-offset = <0x80 0>; pad-offset = <0x1d0>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; }; soc_gpio_s5_1 at 0 { gpio-offset = <0x80 1>; pad-offset = <0x210>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; }; soc_gpio_s5_2 at 0 { gpio-offset = <0x80 2>; pad-offset = <0x1e0>; mode-gpio; output-value = <0>; direction = <PIN_OUTPUT>; };And after, you can use the GPIO commands:
=> gpio set E0
gpio: pin E0 (gpio 128) value is 1
=> gpio clear E0
gpio: pin E0 (gpio 128) value is 0
=> gpio set E2
gpio: pin E2 (gpio 130) value is 1
=> gpio clear E2
gpio: pin E2 (gpio 130) value is 0
Quoted 1 line
E0 E1 and E2 correspond to the GPIO0 1 and 2.
OK thanks, that seems to work for me. I tested these with a multimeter and can adjust the output.
Regards,
Simon
Quoted 82 lines
Regards,
GabrielQuoted 75 lines · Simon Glass
Hi Gabriel,
I have two patches in patchwork:
http://patchwork.ozlabs.org/patch/471146/
http://patchwork.ozlabs.org/patch/471147/Are they the correct ones? Also do you know how to use the gpio command to toggle a bin on the Minnowboard MAX header? I'd like to try that.
Regards,
SimonQuoted 58 lines · gabriel huau
Please ignore this email/patch, I put the wrong message id ...
Quoted 51 lines · Gabriel Huau
Signed-off-by Gabriel Huau <[email protected]>Acked-by Simon Glass <[email protected]>---
Changes in v3:
- Rebase to the origin/masterChanges in v2:
- Fix ordering of include headerboard/intel/minnowmax/minnowmax.c | 9 +++++++++ include/configs/minnowmax.h | 1 + 2 files changed, 10 insertions(+)board/intel/minnowmax/minnowmax.c +8
-0@@ -5,6 +5,7 @@*/ #include <common.h> +#include <asm/gpio.h> #include <asm/ibmpc.h> #include <asm/pnp_def.h> #include <netdev.h> @@ -12,6 +13,14 @@#define SERIAL_DEV PNP_DEV(0x2e, 4) +int arch_early_init_r(void) +{ +/* do the pin-muxing */ +gpio_ich6_pinctrl_init (); + +return 0 ; +} +int board_early_init_f (void ) {lpc47m_enable_serial (SERIAL_DEV ,UART0_BASE ,UART0_IRQ );include/configs/minnowmax.h +1
-0@@ -15,6 +15,7 @@#define CONFIG_SYS_MONITOR_LEN (1 << 20)#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_X86_SERIAL #define CONFIG_SMSC_LPC47M