[PATCH 0/3] rockchip: gpio: Add support for RK3568 and RK3588

This series adds support for RK3568 and RK3588 in the rk gpio driver.
It also reverts the use of gpio-ranges to set gpio bank id and instead add gpio aliases and instead use the alias sequence as the bank id. Using an alias should remove the need for adding a new bank-id prop and abusing the gpio-ranges prop. The alias is also used to determin the bank id in the linux driver.
The series can also be found at [1].
[1] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-gpio-v1
Jonas Karlman (3): rockchip: dts: Add missing alias for gpio controllers gpio: rockchip: Use gpio alias id as gpio bank id gpio: rockchip: Add support for RK3568 and RK3588 banks
arch/arm/dts/px30-u-boot.dtsi | 4 + arch/arm/dts/rk3066a-u-boot.dtsi | 11 +++ arch/arm/dts/rk3188-u-boot.dtsi | 9 +++ arch/arm/dts/rk322x-u-boot.dtsi | 7 ++ arch/arm/dts/rk3308-u-boot.dtsi | 5 ++ arch/arm/dts/rk3328-u-boot.dtsi | 4 + arch/arm/dts/rk3368-u-boot.dtsi | 7 ++ arch/arm/dts/rk3399-u-boot.dtsi | 5 ++ arch/arm/dts/rk3588s-u-boot.dtsi | 8 ++ arch/arm/dts/rv1108-u-boot.dtsi | 9 +++ arch/arm/dts/rv1126-u-boot.dtsi | 8 ++ drivers/gpio/rk_gpio.c | 130 +++++++++++++++++++------------ 12 files changed, 157 insertions(+), 50 deletions(-)

This adds any missing gpio alias for gpio controllers in rockchip u-boot.dtsi files. They are needed to determin what gpio bank id to use in the rockchip gpio driver.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- arch/arm/dts/px30-u-boot.dtsi | 4 ++++ arch/arm/dts/rk3066a-u-boot.dtsi | 11 +++++++++++ arch/arm/dts/rk3188-u-boot.dtsi | 9 +++++++++ arch/arm/dts/rk322x-u-boot.dtsi | 7 +++++++ arch/arm/dts/rk3308-u-boot.dtsi | 5 +++++ arch/arm/dts/rk3328-u-boot.dtsi | 4 ++++ arch/arm/dts/rk3368-u-boot.dtsi | 7 +++++++ arch/arm/dts/rk3399-u-boot.dtsi | 5 +++++ arch/arm/dts/rk3588s-u-boot.dtsi | 8 ++++++++ arch/arm/dts/rv1108-u-boot.dtsi | 9 +++++++++ arch/arm/dts/rv1126-u-boot.dtsi | 8 ++++++++ 11 files changed, 77 insertions(+)
diff --git a/arch/arm/dts/px30-u-boot.dtsi b/arch/arm/dts/px30-u-boot.dtsi index 462eaf68f825..e5e12e849074 100644 --- a/arch/arm/dts/px30-u-boot.dtsi +++ b/arch/arm/dts/px30-u-boot.dtsi @@ -7,6 +7,10 @@
/ { aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; mmc0 = &emmc; mmc1 = &sdmmc; }; diff --git a/arch/arm/dts/rk3066a-u-boot.dtsi b/arch/arm/dts/rk3066a-u-boot.dtsi index bc6e609d02be..17a29b33ecee 100644 --- a/arch/arm/dts/rk3066a-u-boot.dtsi +++ b/arch/arm/dts/rk3066a-u-boot.dtsi @@ -2,3 +2,14 @@
#include "rockchip-u-boot.dtsi" #include "rk3xxx-u-boot.dtsi" + +/ { + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; + gpio6 = &gpio6; + }; +}; diff --git a/arch/arm/dts/rk3188-u-boot.dtsi b/arch/arm/dts/rk3188-u-boot.dtsi index 735776c16b8b..d436f8d3739c 100644 --- a/arch/arm/dts/rk3188-u-boot.dtsi +++ b/arch/arm/dts/rk3188-u-boot.dtsi @@ -6,6 +6,15 @@ #include "rockchip-u-boot.dtsi" #include "rk3xxx-u-boot.dtsi"
+/ { + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + }; +}; + &global_timer { status = "okay"; }; diff --git a/arch/arm/dts/rk322x-u-boot.dtsi b/arch/arm/dts/rk322x-u-boot.dtsi index 79c41e481be2..4c2ddac93f3b 100644 --- a/arch/arm/dts/rk322x-u-boot.dtsi +++ b/arch/arm/dts/rk322x-u-boot.dtsi @@ -3,6 +3,13 @@ #include "rockchip-u-boot.dtsi"
/ { + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + }; + bus_intmem@10080000 { compatible = "mmio-sram"; reg = <0x10080000 0x9000>; diff --git a/arch/arm/dts/rk3308-u-boot.dtsi b/arch/arm/dts/rk3308-u-boot.dtsi index ab5bfc2ce934..f3ffec8ec13e 100644 --- a/arch/arm/dts/rk3308-u-boot.dtsi +++ b/arch/arm/dts/rk3308-u-boot.dtsi @@ -7,6 +7,11 @@
/ { aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; mmc0 = &emmc; mmc1 = &sdmmc; }; diff --git a/arch/arm/dts/rk3328-u-boot.dtsi b/arch/arm/dts/rk3328-u-boot.dtsi index d4a7540a92c5..2c1d1e6e3a3e 100644 --- a/arch/arm/dts/rk3328-u-boot.dtsi +++ b/arch/arm/dts/rk3328-u-boot.dtsi @@ -7,6 +7,10 @@
/ { aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; mmc0 = &emmc; mmc1 = &sdmmc; spi0 = &spi0; diff --git a/arch/arm/dts/rk3368-u-boot.dtsi b/arch/arm/dts/rk3368-u-boot.dtsi index 811d59ac346e..16559771f686 100644 --- a/arch/arm/dts/rk3368-u-boot.dtsi +++ b/arch/arm/dts/rk3368-u-boot.dtsi @@ -7,6 +7,13 @@ #include "rockchip-u-boot.dtsi"
/ { + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + }; + dmc: dmc@ff610000 { compatible = "rockchip,rk3368-dmc", "syscon"; rockchip,cru = <&cru>; diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi index 8a0b1803f340..b8aa835c7ef1 100644 --- a/arch/arm/dts/rk3399-u-boot.dtsi +++ b/arch/arm/dts/rk3399-u-boot.dtsi @@ -8,6 +8,11 @@
/ { aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; mmc0 = &sdhci; mmc1 = &sdmmc; pci0 = &pcie0; diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi index 65960fa50adc..92ab1e7c2e18 100644 --- a/arch/arm/dts/rk3588s-u-boot.dtsi +++ b/arch/arm/dts/rk3588s-u-boot.dtsi @@ -6,6 +6,14 @@ #include "rockchip-u-boot.dtsi"
/ { + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; + }; + dmc { compatible = "rockchip,rk3588-dmc"; u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/rv1108-u-boot.dtsi b/arch/arm/dts/rv1108-u-boot.dtsi index 6a2098b8d416..c9f1574e5ad7 100644 --- a/arch/arm/dts/rv1108-u-boot.dtsi +++ b/arch/arm/dts/rv1108-u-boot.dtsi @@ -5,6 +5,15 @@
#include "rockchip-u-boot.dtsi"
+/ { + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + }; +}; + &grf { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/rv1126-u-boot.dtsi b/arch/arm/dts/rv1126-u-boot.dtsi index bc77037760e4..720a02370207 100644 --- a/arch/arm/dts/rv1126-u-boot.dtsi +++ b/arch/arm/dts/rv1126-u-boot.dtsi @@ -6,6 +6,14 @@ #include "rockchip-u-boot.dtsi"
/ { + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; + }; + chosen { u-boot,spl-boot-order = \ "same-as-spl", &emmc, &sdmmc;

On Sun, 19 Mar 2023 at 12:57, Jonas Karlman jonas@kwiboo.se wrote:
This adds any missing gpio alias for gpio controllers in rockchip u-boot.dtsi files. They are needed to determin what gpio bank id to use in the rockchip gpio driver.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
arch/arm/dts/px30-u-boot.dtsi | 4 ++++ arch/arm/dts/rk3066a-u-boot.dtsi | 11 +++++++++++ arch/arm/dts/rk3188-u-boot.dtsi | 9 +++++++++ arch/arm/dts/rk322x-u-boot.dtsi | 7 +++++++ arch/arm/dts/rk3308-u-boot.dtsi | 5 +++++ arch/arm/dts/rk3328-u-boot.dtsi | 4 ++++ arch/arm/dts/rk3368-u-boot.dtsi | 7 +++++++ arch/arm/dts/rk3399-u-boot.dtsi | 5 +++++ arch/arm/dts/rk3588s-u-boot.dtsi | 8 ++++++++ arch/arm/dts/rv1108-u-boot.dtsi | 9 +++++++++ arch/arm/dts/rv1126-u-boot.dtsi | 8 ++++++++ 11 files changed, 77 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Use the gpio alias id as the gpio bank id, same as in the linux driver.
This reverts the recent change to base bank id on the gpio-ranges prop and apply the same logic used when nodes was named gpio0@ to the alias.
With missing gpio aliases added to u-boot.dtsi files this should restore gpio function for SoCs that have synced gpio0@ to gpio@ node name changes from linux.
Fixes: 904b8700f81c ("gpio: gpio-rockchip: parse gpio-ranges for bank id") Signed-off-by: Jonas Karlman jonas@kwiboo.se --- drivers/gpio/rk_gpio.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-)
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c index f7ad4d68b452..bc77b28307c0 100644 --- a/drivers/gpio/rk_gpio.c +++ b/drivers/gpio/rk_gpio.c @@ -15,6 +15,7 @@ #include <asm/arch-rockchip/clock.h> #include <asm/arch-rockchip/gpio.h> #include <dm/pinctrl.h> +#include <dm/read.h> #include <dt-bindings/clock/rk3288-cru.h>
enum { @@ -142,7 +143,6 @@ static int rockchip_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct rockchip_gpio_priv *priv = dev_get_priv(dev); - struct ofnode_phandle_args args; char *end; int ret;
@@ -151,24 +151,15 @@ static int rockchip_gpio_probe(struct udevice *dev) if (ret) return ret;
- /* - * If "gpio-ranges" is present in the devicetree use it to parse - * the GPIO bank ID, otherwise use the legacy method. - */ - ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), - "gpio-ranges", NULL, 3, - 0, &args); - if (!ret || ret != -ENOENT) { - uc_priv->gpio_count = args.args[2]; - priv->bank = args.args[1] / args.args[2]; - } else { - uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK; + ret = dev_read_alias_seq(dev, &priv->bank); + if (ret) { end = strrchr(dev->name, '@'); priv->bank = trailing_strtoln(dev->name, end); }
priv->name[0] = 'A' + priv->bank; uc_priv->bank_name = priv->name; + uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
return 0; }

On Sun, 19 Mar 2023 at 12:57, Jonas Karlman jonas@kwiboo.se wrote:
Use the gpio alias id as the gpio bank id, same as in the linux driver.
This reverts the recent change to base bank id on the gpio-ranges prop and apply the same logic used when nodes was named gpio0@ to the alias.
With missing gpio aliases added to u-boot.dtsi files this should restore gpio function for SoCs that have synced gpio0@ to gpio@ node name changes from linux.
Fixes: 904b8700f81c ("gpio: gpio-rockchip: parse gpio-ranges for bank id") Signed-off-by: Jonas Karlman jonas@kwiboo.se
drivers/gpio/rk_gpio.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

Some GPIO regs used on RK35xx have changed offset and now use upper 16 bits as a write mask. Refactor and add support for this to add support for RK3568 and RK3588 to the driver.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- drivers/gpio/rk_gpio.c | 111 ++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 36 deletions(-)
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c index bc77b28307c0..1f71038e0366 100644 --- a/drivers/gpio/rk_gpio.c +++ b/drivers/gpio/rk_gpio.c @@ -13,84 +13,118 @@ #include <asm/gpio.h> #include <asm/io.h> #include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/hardware.h> #include <asm/arch-rockchip/gpio.h> #include <dm/pinctrl.h> #include <dm/read.h> -#include <dt-bindings/clock/rk3288-cru.h> +#include <dt-bindings/pinctrl/rockchip.h> + +#define SWPORT_DR 0x0000 +#define SWPORT_DDR 0x0004 +#define EXT_PORT 0x0050 +#define SWPORT_DR_L 0x0000 +#define SWPORT_DR_H 0x0004 +#define SWPORT_DDR_L 0x0008 +#define SWPORT_DDR_H 0x000C +#define EXT_PORT_V2 0x0070 +#define VER_ID_V2 0x0078
enum { ROCKCHIP_GPIOS_PER_BANK = 32, };
-#define OFFSET_TO_BIT(bit) (1UL << (bit)) - struct rockchip_gpio_priv { - struct rockchip_gpio_regs *regs; + void __iomem *regs; struct udevice *pinctrl; int bank; char name[2]; + u32 version; };
-static int rockchip_gpio_direction_input(struct udevice *dev, unsigned offset) +static int rockchip_gpio_get_value(struct udevice *dev, unsigned offset) { struct rockchip_gpio_priv *priv = dev_get_priv(dev); - struct rockchip_gpio_regs *regs = priv->regs; + u32 mask = BIT(offset), data;
- clrbits_le32(®s->swport_ddr, OFFSET_TO_BIT(offset)); + if (priv->version) + data = readl(priv->regs + EXT_PORT_V2); + else + data = readl(priv->regs + EXT_PORT);
- return 0; + return (data & mask) ? 1 : 0; }
-static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, - int value) +static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, + int value) { struct rockchip_gpio_priv *priv = dev_get_priv(dev); - struct rockchip_gpio_regs *regs = priv->regs; - int mask = OFFSET_TO_BIT(offset); + u32 mask = BIT(offset), data = value ? mask : 0;
- clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); - setbits_le32(®s->swport_ddr, mask); + if (priv->version && offset >= 16) + rk_clrsetreg(priv->regs + SWPORT_DR_H, mask >> 16, data >> 16); + else if (priv->version) + rk_clrsetreg(priv->regs + SWPORT_DR_L, mask, data); + else + clrsetbits_le32(priv->regs + SWPORT_DR, mask, data);
return 0; }
-static int rockchip_gpio_get_value(struct udevice *dev, unsigned offset) +static int rockchip_gpio_direction_input(struct udevice *dev, unsigned offset) { struct rockchip_gpio_priv *priv = dev_get_priv(dev); - struct rockchip_gpio_regs *regs = priv->regs; + u32 mask = BIT(offset); + + if (priv->version && offset >= 16) + rk_clrreg(priv->regs + SWPORT_DDR_H, mask >> 16); + else if (priv->version) + rk_clrreg(priv->regs + SWPORT_DDR_L, mask); + else + clrbits_le32(priv->regs + SWPORT_DDR, mask);
- return readl(®s->ext_port) & OFFSET_TO_BIT(offset) ? 1 : 0; + return 0; }
-static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, - int value) +static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) { struct rockchip_gpio_priv *priv = dev_get_priv(dev); - struct rockchip_gpio_regs *regs = priv->regs; - int mask = OFFSET_TO_BIT(offset); + u32 mask = BIT(offset); + + rockchip_gpio_set_value(dev, offset, value);
- clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); + if (priv->version && offset >= 16) + rk_setreg(priv->regs + SWPORT_DDR_H, mask >> 16); + else if (priv->version) + rk_setreg(priv->regs + SWPORT_DDR_L, mask); + else + setbits_le32(priv->regs + SWPORT_DDR, mask);
return 0; }
static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) { -#ifdef CONFIG_SPL_BUILD - return -ENODATA; -#else struct rockchip_gpio_priv *priv = dev_get_priv(dev); - struct rockchip_gpio_regs *regs = priv->regs; - bool is_output; + u32 mask = BIT(offset), data; int ret;
- ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); - if (ret) - return ret; - is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); + if (CONFIG_IS_ENABLED(PINCTRL)) { + ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); + if (ret < 0) + return ret; + else if (ret != RK_FUNC_GPIO) + return GPIOF_FUNC; + } + + if (priv->version && offset >= 16) + data = readl(priv->regs + SWPORT_DDR_H) << 16; + else if (priv->version) + data = readl(priv->regs + SWPORT_DDR_L); + else + data = readl(priv->regs + SWPORT_DDR);
- return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; -#endif + return (data & mask) ? GPIOF_OUTPUT : GPIOF_INPUT; }
/* Simple SPL interface to GPIOs */ @@ -147,9 +181,12 @@ static int rockchip_gpio_probe(struct udevice *dev) int ret;
priv->regs = dev_read_addr_ptr(dev); - ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl); - if (ret) - return ret; + + if (CONFIG_IS_ENABLED(PINCTRL)) { + ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl); + if (ret) + return ret; + }
ret = dev_read_alias_seq(dev, &priv->bank); if (ret) { @@ -161,6 +198,8 @@ static int rockchip_gpio_probe(struct udevice *dev) uc_priv->bank_name = priv->name; uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
+ priv->version = readl(priv->regs + VER_ID_V2); + return 0; }

Hi Jonas,
On 2023/3/19 07:56, Jonas Karlman wrote:
This series adds support for RK3568 and RK3588 in the rk gpio driver.
It also reverts the use of gpio-ranges to set gpio bank id and instead add gpio aliases and instead use the alias sequence as the bank id.
There is another patch set from Johan to make the gpio-ranges available for all rockchip SoCs, I think "gpio-ranges" is better solution than gpio aliases, which also accepted by kernel and used by socs from other vendors.
Thanks, - Kever
Using an alias should remove the need for adding a new bank-id prop and abusing the gpio-ranges prop. The alias is also used to determin the bank id in the linux driver.
The series can also be found at [1].
[1] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-gpio-v1
Jonas Karlman (3): rockchip: dts: Add missing alias for gpio controllers gpio: rockchip: Use gpio alias id as gpio bank id gpio: rockchip: Add support for RK3568 and RK3588 banks
arch/arm/dts/px30-u-boot.dtsi | 4 + arch/arm/dts/rk3066a-u-boot.dtsi | 11 +++ arch/arm/dts/rk3188-u-boot.dtsi | 9 +++ arch/arm/dts/rk322x-u-boot.dtsi | 7 ++ arch/arm/dts/rk3308-u-boot.dtsi | 5 ++ arch/arm/dts/rk3328-u-boot.dtsi | 4 + arch/arm/dts/rk3368-u-boot.dtsi | 7 ++ arch/arm/dts/rk3399-u-boot.dtsi | 5 ++ arch/arm/dts/rk3588s-u-boot.dtsi | 8 ++ arch/arm/dts/rv1108-u-boot.dtsi | 9 +++ arch/arm/dts/rv1126-u-boot.dtsi | 8 ++ drivers/gpio/rk_gpio.c | 130 +++++++++++++++++++------------ 12 files changed, 157 insertions(+), 50 deletions(-)
participants (3)
-
Jonas Karlman
-
Kever Yang
-
Simon Glass