Message ID | 20230213222742.135093-8-macroalpha82@gmail.com |
---|---|
State | Changes Requested |
Delegated to: | Kever Yang |
Headers | show |
Series | Rockchip: Improve Support for RK3566 Devices | expand |
hi, On 2/14/23 07:27, Chris Morgan wrote: > From: Chris Morgan <macromorgan@hotmail.com> > > Add support for the newer GPIO controller used by the rk356x series, > as well as the pinctrl device for the rk356x series. The GPIOv2 > controller has a write enable bit for some registers which differs > from the older versions of the GPIO controller. > > Signed-off-by: Peter Geis <pgwipeout@gmail.com> > Signed-off-by: Chris Morgan <macromorgan@hotmail.com> > --- > arch/arm/include/asm/arch-rockchip/gpio.h | 38 ++ > drivers/gpio/rk_gpio.c | 49 +- > drivers/pinctrl/rockchip/Makefile | 1 + > drivers/pinctrl/rockchip/pinctrl-rk3568.c | 453 ++++++++++++++++++ > .../pinctrl/rockchip/pinctrl-rockchip-core.c | 12 +- > 5 files changed, 540 insertions(+), 13 deletions(-) > create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c > > diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h > index 1aaec5faec..15f5de321b 100644 > --- a/arch/arm/include/asm/arch-rockchip/gpio.h > +++ b/arch/arm/include/asm/arch-rockchip/gpio.h > @@ -6,6 +6,7 @@ > #ifndef _ASM_ARCH_GPIO_H > #define _ASM_ARCH_GPIO_H > > +#if !defined(CONFIG_ROCKCHIP_RK3568) > struct rockchip_gpio_regs { > u32 swport_dr; > u32 swport_ddr; > @@ -22,7 +23,44 @@ struct rockchip_gpio_regs { > u32 reserved1[(0x60 - 0x54) / 4]; > u32 ls_sync; > }; > + > check_member(rockchip_gpio_regs, ls_sync, 0x60); > +#else > +struct rockchip_gpio_regs { > + u32 swport_dr_l; /* ADDRESS OFFSET: 0x0000 */ > + u32 swport_dr_h; /* ADDRESS OFFSET: 0x0004 */ > + u32 swport_ddr_l; /* ADDRESS OFFSET: 0x0008 */ > + u32 swport_ddr_h; /* ADDRESS OFFSET: 0x000c */ > + u32 int_en_l; /* ADDRESS OFFSET: 0x0010 */ > + u32 int_en_h; /* ADDRESS OFFSET: 0x0014 */ > + u32 int_mask_l; /* ADDRESS OFFSET: 0x0018 */ > + u32 int_mask_h; /* ADDRESS OFFSET: 0x001c */ > + u32 int_type_l; /* ADDRESS OFFSET: 0x0020 */ > + u32 int_type_h; /* ADDRESS OFFSET: 0x0024 */ > + u32 int_polarity_l; /* ADDRESS OFFSET: 0x0028 */ > + u32 int_polarity_h; /* ADDRESS OFFSET: 0x002c */ > + u32 int_bothedge_l; /* ADDRESS OFFSET: 0x0030 */ > + u32 int_bothedge_h; /* ADDRESS OFFSET: 0x0034 */ > + u32 debounce_l; /* ADDRESS OFFSET: 0x0038 */ > + u32 debounce_h; /* ADDRESS OFFSET: 0x003c */ > + u32 dbclk_div_en_l; /* ADDRESS OFFSET: 0x0040 */ > + u32 dbclk_div_en_h; /* ADDRESS OFFSET: 0x0044 */ > + u32 dbclk_div_con; /* ADDRESS OFFSET: 0x0048 */ > + u32 reserved004c; /* ADDRESS OFFSET: 0x004c */ > + u32 int_status; /* ADDRESS OFFSET: 0x0050 */ > + u32 reserved0054; /* ADDRESS OFFSET: 0x0054 */ > + u32 int_rawstatus; /* ADDRESS OFFSET: 0x0058 */ > + u32 reserved005c; /* ADDRESS OFFSET: 0x005c */ > + u32 port_eoi_l; /* ADDRESS OFFSET: 0x0060 */ > + u32 port_eoi_h; /* ADDRESS OFFSET: 0x0064 */ > + u32 reserved0068[2]; /* ADDRESS OFFSET: 0x0068 */ > + u32 ext_port; /* ADDRESS OFFSET: 0x0070 */ > + u32 reserved0074; /* ADDRESS OFFSET: 0x0074 */ > + u32 ver_id; /* ADDRESS OFFSET: 0x0078 */ > +}; > + > +check_member(rockchip_gpio_regs, ver_id, 0x0078); > +#endif > > enum gpio_pu_pd { > GPIO_PULL_NORMAL = 0, > diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c > index 98a79b5f4d..e2653be058 100644 > --- a/drivers/gpio/rk_gpio.c > +++ b/drivers/gpio/rk_gpio.c > @@ -2,12 +2,15 @@ > /* > * (C) Copyright 2015 Google, Inc > * > - * (C) Copyright 2008-2014 Rockchip Electronics > + * (C) Copyright 2008-2023 Rockchip Electronics > * Peter, Software Engineering, <superpeter.cai@gmail.com>. > + * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>. > */ > > #include <common.h> > #include <dm.h> > +#include <dm/of_access.h> > +#include <dm/device_compat.h> > #include <syscon.h> > #include <linux/errno.h> > #include <asm/gpio.h> > @@ -23,6 +26,35 @@ enum { > > #define OFFSET_TO_BIT(bit) (1UL << (bit)) > > +/* > + * Newer Rockchip devices have additional registers that must be > + * accounted for. > + */ > +#if defined(CONFIG_ROCKCHIP_RK3568) > +#define GPIO_VER 2 > +#define REG_L(R) (R##_l) > +#define REG_H(R) (R##_h) > +#define READ_REG(REG) ((readl(REG_L(REG)) & 0xFFFF) | \ > + ((readl(REG_H(REG)) & 0xFFFF) << 16)) > +#define WRITE_REG(REG, VAL) \ > +{\ > + writel(((VAL) & 0xFFFF) | 0xFFFF0000, REG_L(REG)); \ > + writel((((VAL) & 0xFFFF0000) >> 16) | 0xFFFF0000, REG_H(REG));\ > +} > +#define CLRBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) & ~(MASK)) > +#define SETBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) | (MASK)) > +#define CLRSETBITS_LE32(REG, MASK, VAL) WRITE_REG(REG, \ > + (READ_REG(REG) & ~(MASK)) | (VAL)) > + > +#else > +#define GPIO_VER 1 > +#define READ_REG(REG) readl(REG) > +#define WRITE_REG(REG, VAL) writel(VAL, REG) > +#define CLRBITS_LE32(REG, MASK) clrbits_le32(REG, MASK) > +#define SETBITS_LE32(REG, MASK) setbits_le32(REG, MASK) > +#define CLRSETBITS_LE32(REG, MASK, VAL) clrsetbits_le32(REG, MASK, VAL) > +#endif > + > struct rockchip_gpio_priv { > struct rockchip_gpio_regs *regs; > struct udevice *pinctrl; > @@ -35,7 +68,7 @@ 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; > > - clrbits_le32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > + CLRBITS_LE32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > > return 0; > } > @@ -47,8 +80,8 @@ static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > - setbits_le32(®s->swport_ddr, mask); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > + SETBITS_LE32(®s->swport_ddr, mask); > > return 0; > } > @@ -68,7 +101,7 @@ static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > > return 0; > } > @@ -86,14 +119,14 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) > ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); > if (ret) > return ret; > - is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); > + is_output = READ_REG(®s->swport_ddr) & OFFSET_TO_BIT(offset); > > return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; > #endif > } > > /* Simple SPL interface to GPIOs */ > -#ifdef CONFIG_SPL_BUILD > +#if defined(CONFIG_SPL_BUILD) && (GPIO_VER == 1) > > enum { > PULL_NONE_1V8 = 0, > @@ -143,7 +176,7 @@ 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; > + char *end = NULL; > int ret; > > priv->regs = dev_read_addr_ptr(dev); > diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile > index 9884355473..90461ae881 100644 > --- a/drivers/pinctrl/rockchip/Makefile > +++ b/drivers/pinctrl/rockchip/Makefile > @@ -14,5 +14,6 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o > obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o > obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o > obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o > +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o > obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o > obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o > diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > new file mode 100644 > index 0000000000..dce1c1e7ee > --- /dev/null > +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > @@ -0,0 +1,453 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * (C) Copyright 2020 Rockchip Electronics Co., Ltd > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <dm/pinctrl.h> > +#include <regmap.h> > +#include <syscon.h> +#include <dt-bindings/pinctrl/rockchip.h> -- FUKAUMI Naoki > + > +#include "pinctrl-rockchip.h" > + > +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { > + /* CAN0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)), > + /* CAN0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)), > + /* CAN1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)), > + /* CAN1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)), > + /* CAN2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)), > + /* CAN2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)), > + /* EDPDP_HPDIN IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)), > + /* EDPDP_HPDIN IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)), > + /* GMAC1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)), > + /* GMAC1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)), > + /* HDMITX IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)), > + /* HDMITX IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)), > + /* I2C2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)), > + /* I2C2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)), > + /* I2C3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)), > + /* I2C3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)), > + /* I2C4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)), > + /* I2C4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)), > + /* I2C5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)), > + /* I2C5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)), > + /* PWM8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)), > + /* PWM8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)), > + /* PWM9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)), > + /* PWM9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)), > + /* PWM10 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)), > + /* PWM10 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)), > + /* PWM11 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)), > + /* PWM11 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM12 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM12 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM13 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM13 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM14 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM14 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM15 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM15 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)), > + /* SDMMC2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)), > + /* SDMMC2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)), > + /* SPI0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)), > + /* SPI0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)), > + /* SPI1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)), > + /* SPI1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)), > + /* SPI2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)), > + /* SPI2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)), > + /* SPI3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)), > + /* SPI3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)), > + /* UART1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)), > + /* UART1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)), > + /* UART2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)), > + /* UART2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)), > + /* UART3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)), > + /* UART3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)), > + /* UART4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)), > + /* UART4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)), > + /* UART5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)), > + /* UART5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)), > + /* UART6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)), > + /* UART6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)), > + /* UART7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)), > + /* UART7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)), > + /* UART7 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)), > + /* UART8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)), > + /* UART8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)), > + /* UART9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)), > + /* UART9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)), > + /* UART9 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)), > + /* I2S1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)), > + /* I2S1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)), > + /* I2S1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)), > + /* I2S2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)), > + /* I2S2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)), > + /* I2S3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)), > + /* I2S3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)), > + /* PDM IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)), > + /* PDM IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)), > + /* PCIE20 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)), > + /* PCIE20 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)), > + /* PCIE20 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)), > + /* PCIE30X1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)), > + /* PCIE30X1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)), > + /* PCIE30X1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)), > + /* PCIE30X2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)), > + /* PCIE30X2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)), > + /* PCIE30X2 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)), > +}; > + > +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) > +{ > + struct rockchip_pinctrl_priv *priv = bank->priv; > + int iomux_num = (pin / 8); > + struct regmap *regmap; > + int reg, ret, mask; > + u8 bit; > + u32 data; > + > + debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); > + > + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) > + regmap = priv->regmap_pmu; > + else > + regmap = priv->regmap_base; > + > + reg = bank->iomux[iomux_num].offset; > + if ((pin % 8) >= 4) > + reg += 0x4; > + bit = (pin % 4) * 4; > + mask = 0xf; > + > + data = (mask << (bit + 16)); > + data |= (mux & mask) << bit; > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +#define RK3568_PULL_PMU_OFFSET 0x20 > +#define RK3568_PULL_GRF_OFFSET 0x80 > +#define RK3568_PULL_BITS_PER_PIN 2 > +#define RK3568_PULL_PINS_PER_REG 8 > +#define RK3568_PULL_BANK_STRIDE 0x10 > + > +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_PULL_PMU_OFFSET; > + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_PULL_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); > + *bit *= RK3568_PULL_BITS_PER_PIN; > +} > + > +#define RK3568_DRV_PMU_OFFSET 0x70 > +#define RK3568_DRV_GRF_OFFSET 0x200 > +#define RK3568_DRV_BITS_PER_PIN 8 > +#define RK3568_DRV_PINS_PER_REG 2 > +#define RK3568_DRV_BANK_STRIDE 0x40 > + > +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + /* The first 32 pins of the first bank are located in PMU */ > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_DRV_PMU_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_DRV_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); > + *bit *= RK3568_DRV_BITS_PER_PIN; > +} > + > +#define RK3568_SCHMITT_BITS_PER_PIN 2 > +#define RK3568_SCHMITT_PINS_PER_REG 8 > +#define RK3568_SCHMITT_BANK_STRIDE 0x10 > +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 > +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 > + > +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_SCHMITT_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); > + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; > + *bit *= RK3568_SCHMITT_BITS_PER_PIN; > + > + return 0; > +} > + > +static int rk3568_set_pull(struct rockchip_pin_bank *bank, > + int pin_num, int pull) > +{ > + struct regmap *regmap; > + int reg, ret; > + u8 bit, type; > + u32 data; > + > + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) > + return -EOPNOTSUPP; > + > + rk3568_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + type = bank->pull_type[pin_num / 8]; > + ret = rockchip_translate_pull_value(type, pull); > + if (ret < 0) { > + debug("unsupported pull setting %d\n", pull); > + return ret; > + } > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); > + > + data |= (ret << bit); > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +static int rk3568_set_drive(struct rockchip_pin_bank *bank, > + int pin_num, int strength) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + int drv = (1 << (strength + 1)) - 1; > + int ret = 0; > + > + rk3568_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (drv << bit); > + > + ret = regmap_write(regmap, reg, data); > + if (ret) > + return ret; > + > + if (bank->bank_num == 1 && pin_num == 21) > + reg = 0x0840; > + else if (bank->bank_num == 2 && pin_num == 2) > + reg = 0x0844; > + else if (bank->bank_num == 2 && pin_num == 8) > + reg = 0x0848; > + else if (bank->bank_num == 3 && pin_num == 0) > + reg = 0x084c; > + else if (bank->bank_num == 3 && pin_num == 6) > + reg = 0x0850; > + else if (bank->bank_num == 4 && pin_num == 0) > + reg = 0x0854; > + else > + return 0; > + > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16; > + data |= drv; > + > + return regmap_write(regmap, reg, data); > +} > + > +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank, > + int pin_num, int enable) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + > + rk3568_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (enable << bit); > + > + return regmap_write(regmap, reg, data); > +} > + > +static struct rockchip_pin_bank rk3568_pin_banks[] = { > + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > +}; > + > +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = { > + .pin_banks = rk3568_pin_banks, > + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), > + .nr_pins = 160, > + .grf_mux_offset = 0x0, > + .pmu_mux_offset = 0x0, > + .iomux_routes = rk3568_mux_route_data, > + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), > + .set_mux = rk3568_set_mux, > + .set_pull = rk3568_set_pull, > + .set_drive = rk3568_set_drive, > + .set_schmitt = rk3568_set_schmitt, > +}; > + > +static const struct udevice_id rk3568_pinctrl_ids[] = { > + { > + .compatible = "rockchip,rk3568-pinctrl", > + .data = (ulong)&rk3568_pin_ctrl > + }, > + { } > +}; > + > +U_BOOT_DRIVER(pinctrl_rk3568) = { > + .name = "rockchip_rk3568_pinctrl", > + .id = UCLASS_PINCTRL, > + .of_match = rk3568_pinctrl_ids, > + .priv_auto = sizeof(struct rockchip_pinctrl_priv), > + .ops = &rockchip_pinctrl_ops, > +#if !IS_ENABLED(CONFIG_OF_PLATDATA) > + .bind = dm_scan_fdt_dev, > +#endif > + .probe = rockchip_pinctrl_probe, > +}; > diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > index d9d61fdb72..1481c1e51c 100644 > --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > @@ -433,7 +433,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > int prop_len, param; > const u32 *data; > ofnode node; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > const struct device_node *np; > struct property *pp; > #else > @@ -473,7 +473,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > node = ofnode_get_by_phandle(conf); > if (!ofnode_valid(node)) > return -ENODEV; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > np = ofnode_to_np(node); > for (pp = np->properties; pp; pp = pp->next) { > prop_name = pp->name; > @@ -548,13 +548,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d > > /* preset iomux offset value, set new start value */ > if (iom->offset >= 0) { > - if (iom->type & IOMUX_SOURCE_PMU) > + if ((iom->type & IOMUX_SOURCE_PMU) || \ > + (iom->type & IOMUX_L_SOURCE_PMU)) > pmu_offs = iom->offset; > else > grf_offs = iom->offset; > } else { /* set current iomux offset */ > - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? > - pmu_offs : grf_offs; > + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || > + (iom->type & IOMUX_L_SOURCE_PMU)) ? > + pmu_offs : grf_offs; > } > > /* preset drv offset value, set new start value */
On 2023/2/14 06:27, Chris Morgan wrote: > From: Chris Morgan <macromorgan@hotmail.com> > > Add support for the newer GPIO controller used by the rk356x series, > as well as the pinctrl device for the rk356x series. The GPIOv2 > controller has a write enable bit for some registers which differs > from the older versions of the GPIO controller. > > Signed-off-by: Peter Geis <pgwipeout@gmail.com> > Signed-off-by: Chris Morgan <macromorgan@hotmail.com> With FUKAUMI Naoki's comment apply: Reviewed-by: Kever Yang <kever.yang@rock-chips.com> Thanks, - Kever > --- > arch/arm/include/asm/arch-rockchip/gpio.h | 38 ++ > drivers/gpio/rk_gpio.c | 49 +- > drivers/pinctrl/rockchip/Makefile | 1 + > drivers/pinctrl/rockchip/pinctrl-rk3568.c | 453 ++++++++++++++++++ > .../pinctrl/rockchip/pinctrl-rockchip-core.c | 12 +- > 5 files changed, 540 insertions(+), 13 deletions(-) > create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c > > diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h > index 1aaec5faec..15f5de321b 100644 > --- a/arch/arm/include/asm/arch-rockchip/gpio.h > +++ b/arch/arm/include/asm/arch-rockchip/gpio.h > @@ -6,6 +6,7 @@ > #ifndef _ASM_ARCH_GPIO_H > #define _ASM_ARCH_GPIO_H > > +#if !defined(CONFIG_ROCKCHIP_RK3568) > struct rockchip_gpio_regs { > u32 swport_dr; > u32 swport_ddr; > @@ -22,7 +23,44 @@ struct rockchip_gpio_regs { > u32 reserved1[(0x60 - 0x54) / 4]; > u32 ls_sync; > }; > + > check_member(rockchip_gpio_regs, ls_sync, 0x60); > +#else > +struct rockchip_gpio_regs { > + u32 swport_dr_l; /* ADDRESS OFFSET: 0x0000 */ > + u32 swport_dr_h; /* ADDRESS OFFSET: 0x0004 */ > + u32 swport_ddr_l; /* ADDRESS OFFSET: 0x0008 */ > + u32 swport_ddr_h; /* ADDRESS OFFSET: 0x000c */ > + u32 int_en_l; /* ADDRESS OFFSET: 0x0010 */ > + u32 int_en_h; /* ADDRESS OFFSET: 0x0014 */ > + u32 int_mask_l; /* ADDRESS OFFSET: 0x0018 */ > + u32 int_mask_h; /* ADDRESS OFFSET: 0x001c */ > + u32 int_type_l; /* ADDRESS OFFSET: 0x0020 */ > + u32 int_type_h; /* ADDRESS OFFSET: 0x0024 */ > + u32 int_polarity_l; /* ADDRESS OFFSET: 0x0028 */ > + u32 int_polarity_h; /* ADDRESS OFFSET: 0x002c */ > + u32 int_bothedge_l; /* ADDRESS OFFSET: 0x0030 */ > + u32 int_bothedge_h; /* ADDRESS OFFSET: 0x0034 */ > + u32 debounce_l; /* ADDRESS OFFSET: 0x0038 */ > + u32 debounce_h; /* ADDRESS OFFSET: 0x003c */ > + u32 dbclk_div_en_l; /* ADDRESS OFFSET: 0x0040 */ > + u32 dbclk_div_en_h; /* ADDRESS OFFSET: 0x0044 */ > + u32 dbclk_div_con; /* ADDRESS OFFSET: 0x0048 */ > + u32 reserved004c; /* ADDRESS OFFSET: 0x004c */ > + u32 int_status; /* ADDRESS OFFSET: 0x0050 */ > + u32 reserved0054; /* ADDRESS OFFSET: 0x0054 */ > + u32 int_rawstatus; /* ADDRESS OFFSET: 0x0058 */ > + u32 reserved005c; /* ADDRESS OFFSET: 0x005c */ > + u32 port_eoi_l; /* ADDRESS OFFSET: 0x0060 */ > + u32 port_eoi_h; /* ADDRESS OFFSET: 0x0064 */ > + u32 reserved0068[2]; /* ADDRESS OFFSET: 0x0068 */ > + u32 ext_port; /* ADDRESS OFFSET: 0x0070 */ > + u32 reserved0074; /* ADDRESS OFFSET: 0x0074 */ > + u32 ver_id; /* ADDRESS OFFSET: 0x0078 */ > +}; > + > +check_member(rockchip_gpio_regs, ver_id, 0x0078); > +#endif > > enum gpio_pu_pd { > GPIO_PULL_NORMAL = 0, > diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c > index 98a79b5f4d..e2653be058 100644 > --- a/drivers/gpio/rk_gpio.c > +++ b/drivers/gpio/rk_gpio.c > @@ -2,12 +2,15 @@ > /* > * (C) Copyright 2015 Google, Inc > * > - * (C) Copyright 2008-2014 Rockchip Electronics > + * (C) Copyright 2008-2023 Rockchip Electronics > * Peter, Software Engineering, <superpeter.cai@gmail.com>. > + * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>. > */ > > #include <common.h> > #include <dm.h> > +#include <dm/of_access.h> > +#include <dm/device_compat.h> > #include <syscon.h> > #include <linux/errno.h> > #include <asm/gpio.h> > @@ -23,6 +26,35 @@ enum { > > #define OFFSET_TO_BIT(bit) (1UL << (bit)) > > +/* > + * Newer Rockchip devices have additional registers that must be > + * accounted for. > + */ > +#if defined(CONFIG_ROCKCHIP_RK3568) > +#define GPIO_VER 2 > +#define REG_L(R) (R##_l) > +#define REG_H(R) (R##_h) > +#define READ_REG(REG) ((readl(REG_L(REG)) & 0xFFFF) | \ > + ((readl(REG_H(REG)) & 0xFFFF) << 16)) > +#define WRITE_REG(REG, VAL) \ > +{\ > + writel(((VAL) & 0xFFFF) | 0xFFFF0000, REG_L(REG)); \ > + writel((((VAL) & 0xFFFF0000) >> 16) | 0xFFFF0000, REG_H(REG));\ > +} > +#define CLRBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) & ~(MASK)) > +#define SETBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) | (MASK)) > +#define CLRSETBITS_LE32(REG, MASK, VAL) WRITE_REG(REG, \ > + (READ_REG(REG) & ~(MASK)) | (VAL)) > + > +#else > +#define GPIO_VER 1 > +#define READ_REG(REG) readl(REG) > +#define WRITE_REG(REG, VAL) writel(VAL, REG) > +#define CLRBITS_LE32(REG, MASK) clrbits_le32(REG, MASK) > +#define SETBITS_LE32(REG, MASK) setbits_le32(REG, MASK) > +#define CLRSETBITS_LE32(REG, MASK, VAL) clrsetbits_le32(REG, MASK, VAL) > +#endif > + > struct rockchip_gpio_priv { > struct rockchip_gpio_regs *regs; > struct udevice *pinctrl; > @@ -35,7 +68,7 @@ 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; > > - clrbits_le32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > + CLRBITS_LE32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > > return 0; > } > @@ -47,8 +80,8 @@ static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > - setbits_le32(®s->swport_ddr, mask); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > + SETBITS_LE32(®s->swport_ddr, mask); > > return 0; > } > @@ -68,7 +101,7 @@ static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > > return 0; > } > @@ -86,14 +119,14 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) > ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); > if (ret) > return ret; > - is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); > + is_output = READ_REG(®s->swport_ddr) & OFFSET_TO_BIT(offset); > > return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; > #endif > } > > /* Simple SPL interface to GPIOs */ > -#ifdef CONFIG_SPL_BUILD > +#if defined(CONFIG_SPL_BUILD) && (GPIO_VER == 1) > > enum { > PULL_NONE_1V8 = 0, > @@ -143,7 +176,7 @@ 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; > + char *end = NULL; > int ret; > > priv->regs = dev_read_addr_ptr(dev); > diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile > index 9884355473..90461ae881 100644 > --- a/drivers/pinctrl/rockchip/Makefile > +++ b/drivers/pinctrl/rockchip/Makefile > @@ -14,5 +14,6 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o > obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o > obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o > obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o > +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o > obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o > obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o > diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > new file mode 100644 > index 0000000000..dce1c1e7ee > --- /dev/null > +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > @@ -0,0 +1,453 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * (C) Copyright 2020 Rockchip Electronics Co., Ltd > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <dm/pinctrl.h> > +#include <regmap.h> > +#include <syscon.h> > + > +#include "pinctrl-rockchip.h" > + > +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { > + /* CAN0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)), > + /* CAN0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)), > + /* CAN1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)), > + /* CAN1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)), > + /* CAN2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)), > + /* CAN2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)), > + /* EDPDP_HPDIN IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)), > + /* EDPDP_HPDIN IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)), > + /* GMAC1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)), > + /* GMAC1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)), > + /* HDMITX IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)), > + /* HDMITX IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)), > + /* I2C2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)), > + /* I2C2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)), > + /* I2C3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)), > + /* I2C3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)), > + /* I2C4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)), > + /* I2C4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)), > + /* I2C5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)), > + /* I2C5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)), > + /* PWM8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)), > + /* PWM8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)), > + /* PWM9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)), > + /* PWM9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)), > + /* PWM10 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)), > + /* PWM10 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)), > + /* PWM11 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)), > + /* PWM11 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM12 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM12 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM13 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM13 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM14 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM14 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM15 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM15 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)), > + /* SDMMC2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)), > + /* SDMMC2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)), > + /* SPI0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)), > + /* SPI0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)), > + /* SPI1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)), > + /* SPI1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)), > + /* SPI2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)), > + /* SPI2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)), > + /* SPI3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)), > + /* SPI3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)), > + /* UART1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)), > + /* UART1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)), > + /* UART2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)), > + /* UART2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)), > + /* UART3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)), > + /* UART3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)), > + /* UART4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)), > + /* UART4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)), > + /* UART5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)), > + /* UART5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)), > + /* UART6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)), > + /* UART6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)), > + /* UART7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)), > + /* UART7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)), > + /* UART7 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)), > + /* UART8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)), > + /* UART8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)), > + /* UART9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)), > + /* UART9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)), > + /* UART9 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)), > + /* I2S1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)), > + /* I2S1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)), > + /* I2S1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)), > + /* I2S2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)), > + /* I2S2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)), > + /* I2S3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)), > + /* I2S3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)), > + /* PDM IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)), > + /* PDM IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)), > + /* PCIE20 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)), > + /* PCIE20 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)), > + /* PCIE20 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)), > + /* PCIE30X1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)), > + /* PCIE30X1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)), > + /* PCIE30X1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)), > + /* PCIE30X2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)), > + /* PCIE30X2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)), > + /* PCIE30X2 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)), > +}; > + > +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) > +{ > + struct rockchip_pinctrl_priv *priv = bank->priv; > + int iomux_num = (pin / 8); > + struct regmap *regmap; > + int reg, ret, mask; > + u8 bit; > + u32 data; > + > + debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); > + > + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) > + regmap = priv->regmap_pmu; > + else > + regmap = priv->regmap_base; > + > + reg = bank->iomux[iomux_num].offset; > + if ((pin % 8) >= 4) > + reg += 0x4; > + bit = (pin % 4) * 4; > + mask = 0xf; > + > + data = (mask << (bit + 16)); > + data |= (mux & mask) << bit; > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +#define RK3568_PULL_PMU_OFFSET 0x20 > +#define RK3568_PULL_GRF_OFFSET 0x80 > +#define RK3568_PULL_BITS_PER_PIN 2 > +#define RK3568_PULL_PINS_PER_REG 8 > +#define RK3568_PULL_BANK_STRIDE 0x10 > + > +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_PULL_PMU_OFFSET; > + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_PULL_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); > + *bit *= RK3568_PULL_BITS_PER_PIN; > +} > + > +#define RK3568_DRV_PMU_OFFSET 0x70 > +#define RK3568_DRV_GRF_OFFSET 0x200 > +#define RK3568_DRV_BITS_PER_PIN 8 > +#define RK3568_DRV_PINS_PER_REG 2 > +#define RK3568_DRV_BANK_STRIDE 0x40 > + > +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + /* The first 32 pins of the first bank are located in PMU */ > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_DRV_PMU_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_DRV_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); > + *bit *= RK3568_DRV_BITS_PER_PIN; > +} > + > +#define RK3568_SCHMITT_BITS_PER_PIN 2 > +#define RK3568_SCHMITT_PINS_PER_REG 8 > +#define RK3568_SCHMITT_BANK_STRIDE 0x10 > +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 > +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 > + > +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_SCHMITT_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); > + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; > + *bit *= RK3568_SCHMITT_BITS_PER_PIN; > + > + return 0; > +} > + > +static int rk3568_set_pull(struct rockchip_pin_bank *bank, > + int pin_num, int pull) > +{ > + struct regmap *regmap; > + int reg, ret; > + u8 bit, type; > + u32 data; > + > + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) > + return -EOPNOTSUPP; > + > + rk3568_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + type = bank->pull_type[pin_num / 8]; > + ret = rockchip_translate_pull_value(type, pull); > + if (ret < 0) { > + debug("unsupported pull setting %d\n", pull); > + return ret; > + } > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); > + > + data |= (ret << bit); > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +static int rk3568_set_drive(struct rockchip_pin_bank *bank, > + int pin_num, int strength) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + int drv = (1 << (strength + 1)) - 1; > + int ret = 0; > + > + rk3568_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (drv << bit); > + > + ret = regmap_write(regmap, reg, data); > + if (ret) > + return ret; > + > + if (bank->bank_num == 1 && pin_num == 21) > + reg = 0x0840; > + else if (bank->bank_num == 2 && pin_num == 2) > + reg = 0x0844; > + else if (bank->bank_num == 2 && pin_num == 8) > + reg = 0x0848; > + else if (bank->bank_num == 3 && pin_num == 0) > + reg = 0x084c; > + else if (bank->bank_num == 3 && pin_num == 6) > + reg = 0x0850; > + else if (bank->bank_num == 4 && pin_num == 0) > + reg = 0x0854; > + else > + return 0; > + > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16; > + data |= drv; > + > + return regmap_write(regmap, reg, data); > +} > + > +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank, > + int pin_num, int enable) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + > + rk3568_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (enable << bit); > + > + return regmap_write(regmap, reg, data); > +} > + > +static struct rockchip_pin_bank rk3568_pin_banks[] = { > + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > +}; > + > +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = { > + .pin_banks = rk3568_pin_banks, > + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), > + .nr_pins = 160, > + .grf_mux_offset = 0x0, > + .pmu_mux_offset = 0x0, > + .iomux_routes = rk3568_mux_route_data, > + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), > + .set_mux = rk3568_set_mux, > + .set_pull = rk3568_set_pull, > + .set_drive = rk3568_set_drive, > + .set_schmitt = rk3568_set_schmitt, > +}; > + > +static const struct udevice_id rk3568_pinctrl_ids[] = { > + { > + .compatible = "rockchip,rk3568-pinctrl", > + .data = (ulong)&rk3568_pin_ctrl > + }, > + { } > +}; > + > +U_BOOT_DRIVER(pinctrl_rk3568) = { > + .name = "rockchip_rk3568_pinctrl", > + .id = UCLASS_PINCTRL, > + .of_match = rk3568_pinctrl_ids, > + .priv_auto = sizeof(struct rockchip_pinctrl_priv), > + .ops = &rockchip_pinctrl_ops, > +#if !IS_ENABLED(CONFIG_OF_PLATDATA) > + .bind = dm_scan_fdt_dev, > +#endif > + .probe = rockchip_pinctrl_probe, > +}; > diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > index d9d61fdb72..1481c1e51c 100644 > --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > @@ -433,7 +433,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > int prop_len, param; > const u32 *data; > ofnode node; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > const struct device_node *np; > struct property *pp; > #else > @@ -473,7 +473,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > node = ofnode_get_by_phandle(conf); > if (!ofnode_valid(node)) > return -ENODEV; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > np = ofnode_to_np(node); > for (pp = np->properties; pp; pp = pp->next) { > prop_name = pp->name; > @@ -548,13 +548,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d > > /* preset iomux offset value, set new start value */ > if (iom->offset >= 0) { > - if (iom->type & IOMUX_SOURCE_PMU) > + if ((iom->type & IOMUX_SOURCE_PMU) || \ > + (iom->type & IOMUX_L_SOURCE_PMU)) > pmu_offs = iom->offset; > else > grf_offs = iom->offset; > } else { /* set current iomux offset */ > - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? > - pmu_offs : grf_offs; > + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || > + (iom->type & IOMUX_L_SOURCE_PMU)) ? > + pmu_offs : grf_offs; > } > > /* preset drv offset value, set new start value */
Hi Chris, Â Â Â For this patch, I have pick below patch instead: https://patchwork.ozlabs.org/project/uboot/patch/20230217115845.75303-11-jagan@amarulasolutions.com/ Â Â Â For those change other than pinctrl-rk3568.c, please send a new patch is still available. Thanks, - Kever On 2023/2/14 06:27, Chris Morgan wrote: > From: Chris Morgan <macromorgan@hotmail.com> > > Add support for the newer GPIO controller used by the rk356x series, > as well as the pinctrl device for the rk356x series. The GPIOv2 > controller has a write enable bit for some registers which differs > from the older versions of the GPIO controller. > > Signed-off-by: Peter Geis <pgwipeout@gmail.com> > Signed-off-by: Chris Morgan <macromorgan@hotmail.com> > --- > arch/arm/include/asm/arch-rockchip/gpio.h | 38 ++ > drivers/gpio/rk_gpio.c | 49 +- > drivers/pinctrl/rockchip/Makefile | 1 + > drivers/pinctrl/rockchip/pinctrl-rk3568.c | 453 ++++++++++++++++++ > .../pinctrl/rockchip/pinctrl-rockchip-core.c | 12 +- > 5 files changed, 540 insertions(+), 13 deletions(-) > create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c > > diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h > index 1aaec5faec..15f5de321b 100644 > --- a/arch/arm/include/asm/arch-rockchip/gpio.h > +++ b/arch/arm/include/asm/arch-rockchip/gpio.h > @@ -6,6 +6,7 @@ > #ifndef _ASM_ARCH_GPIO_H > #define _ASM_ARCH_GPIO_H > > +#if !defined(CONFIG_ROCKCHIP_RK3568) > struct rockchip_gpio_regs { > u32 swport_dr; > u32 swport_ddr; > @@ -22,7 +23,44 @@ struct rockchip_gpio_regs { > u32 reserved1[(0x60 - 0x54) / 4]; > u32 ls_sync; > }; > + > check_member(rockchip_gpio_regs, ls_sync, 0x60); > +#else > +struct rockchip_gpio_regs { > + u32 swport_dr_l; /* ADDRESS OFFSET: 0x0000 */ > + u32 swport_dr_h; /* ADDRESS OFFSET: 0x0004 */ > + u32 swport_ddr_l; /* ADDRESS OFFSET: 0x0008 */ > + u32 swport_ddr_h; /* ADDRESS OFFSET: 0x000c */ > + u32 int_en_l; /* ADDRESS OFFSET: 0x0010 */ > + u32 int_en_h; /* ADDRESS OFFSET: 0x0014 */ > + u32 int_mask_l; /* ADDRESS OFFSET: 0x0018 */ > + u32 int_mask_h; /* ADDRESS OFFSET: 0x001c */ > + u32 int_type_l; /* ADDRESS OFFSET: 0x0020 */ > + u32 int_type_h; /* ADDRESS OFFSET: 0x0024 */ > + u32 int_polarity_l; /* ADDRESS OFFSET: 0x0028 */ > + u32 int_polarity_h; /* ADDRESS OFFSET: 0x002c */ > + u32 int_bothedge_l; /* ADDRESS OFFSET: 0x0030 */ > + u32 int_bothedge_h; /* ADDRESS OFFSET: 0x0034 */ > + u32 debounce_l; /* ADDRESS OFFSET: 0x0038 */ > + u32 debounce_h; /* ADDRESS OFFSET: 0x003c */ > + u32 dbclk_div_en_l; /* ADDRESS OFFSET: 0x0040 */ > + u32 dbclk_div_en_h; /* ADDRESS OFFSET: 0x0044 */ > + u32 dbclk_div_con; /* ADDRESS OFFSET: 0x0048 */ > + u32 reserved004c; /* ADDRESS OFFSET: 0x004c */ > + u32 int_status; /* ADDRESS OFFSET: 0x0050 */ > + u32 reserved0054; /* ADDRESS OFFSET: 0x0054 */ > + u32 int_rawstatus; /* ADDRESS OFFSET: 0x0058 */ > + u32 reserved005c; /* ADDRESS OFFSET: 0x005c */ > + u32 port_eoi_l; /* ADDRESS OFFSET: 0x0060 */ > + u32 port_eoi_h; /* ADDRESS OFFSET: 0x0064 */ > + u32 reserved0068[2]; /* ADDRESS OFFSET: 0x0068 */ > + u32 ext_port; /* ADDRESS OFFSET: 0x0070 */ > + u32 reserved0074; /* ADDRESS OFFSET: 0x0074 */ > + u32 ver_id; /* ADDRESS OFFSET: 0x0078 */ > +}; > + > +check_member(rockchip_gpio_regs, ver_id, 0x0078); > +#endif > > enum gpio_pu_pd { > GPIO_PULL_NORMAL = 0, > diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c > index 98a79b5f4d..e2653be058 100644 > --- a/drivers/gpio/rk_gpio.c > +++ b/drivers/gpio/rk_gpio.c > @@ -2,12 +2,15 @@ > /* > * (C) Copyright 2015 Google, Inc > * > - * (C) Copyright 2008-2014 Rockchip Electronics > + * (C) Copyright 2008-2023 Rockchip Electronics > * Peter, Software Engineering, <superpeter.cai@gmail.com>. > + * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>. > */ > > #include <common.h> > #include <dm.h> > +#include <dm/of_access.h> > +#include <dm/device_compat.h> > #include <syscon.h> > #include <linux/errno.h> > #include <asm/gpio.h> > @@ -23,6 +26,35 @@ enum { > > #define OFFSET_TO_BIT(bit) (1UL << (bit)) > > +/* > + * Newer Rockchip devices have additional registers that must be > + * accounted for. > + */ > +#if defined(CONFIG_ROCKCHIP_RK3568) > +#define GPIO_VER 2 > +#define REG_L(R) (R##_l) > +#define REG_H(R) (R##_h) > +#define READ_REG(REG) ((readl(REG_L(REG)) & 0xFFFF) | \ > + ((readl(REG_H(REG)) & 0xFFFF) << 16)) > +#define WRITE_REG(REG, VAL) \ > +{\ > + writel(((VAL) & 0xFFFF) | 0xFFFF0000, REG_L(REG)); \ > + writel((((VAL) & 0xFFFF0000) >> 16) | 0xFFFF0000, REG_H(REG));\ > +} > +#define CLRBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) & ~(MASK)) > +#define SETBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) | (MASK)) > +#define CLRSETBITS_LE32(REG, MASK, VAL) WRITE_REG(REG, \ > + (READ_REG(REG) & ~(MASK)) | (VAL)) > + > +#else > +#define GPIO_VER 1 > +#define READ_REG(REG) readl(REG) > +#define WRITE_REG(REG, VAL) writel(VAL, REG) > +#define CLRBITS_LE32(REG, MASK) clrbits_le32(REG, MASK) > +#define SETBITS_LE32(REG, MASK) setbits_le32(REG, MASK) > +#define CLRSETBITS_LE32(REG, MASK, VAL) clrsetbits_le32(REG, MASK, VAL) > +#endif > + > struct rockchip_gpio_priv { > struct rockchip_gpio_regs *regs; > struct udevice *pinctrl; > @@ -35,7 +68,7 @@ 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; > > - clrbits_le32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > + CLRBITS_LE32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > > return 0; > } > @@ -47,8 +80,8 @@ static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > - setbits_le32(®s->swport_ddr, mask); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > + SETBITS_LE32(®s->swport_ddr, mask); > > return 0; > } > @@ -68,7 +101,7 @@ static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > > return 0; > } > @@ -86,14 +119,14 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) > ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); > if (ret) > return ret; > - is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); > + is_output = READ_REG(®s->swport_ddr) & OFFSET_TO_BIT(offset); > > return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; > #endif > } > > /* Simple SPL interface to GPIOs */ > -#ifdef CONFIG_SPL_BUILD > +#if defined(CONFIG_SPL_BUILD) && (GPIO_VER == 1) > > enum { > PULL_NONE_1V8 = 0, > @@ -143,7 +176,7 @@ 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; > + char *end = NULL; > int ret; > > priv->regs = dev_read_addr_ptr(dev); > diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile > index 9884355473..90461ae881 100644 > --- a/drivers/pinctrl/rockchip/Makefile > +++ b/drivers/pinctrl/rockchip/Makefile > @@ -14,5 +14,6 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o > obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o > obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o > obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o > +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o > obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o > obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o > diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > new file mode 100644 > index 0000000000..dce1c1e7ee > --- /dev/null > +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > @@ -0,0 +1,453 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * (C) Copyright 2020 Rockchip Electronics Co., Ltd > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <dm/pinctrl.h> > +#include <regmap.h> > +#include <syscon.h> > + > +#include "pinctrl-rockchip.h" > + > +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { > + /* CAN0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)), > + /* CAN0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)), > + /* CAN1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)), > + /* CAN1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)), > + /* CAN2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)), > + /* CAN2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)), > + /* EDPDP_HPDIN IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)), > + /* EDPDP_HPDIN IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)), > + /* GMAC1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)), > + /* GMAC1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)), > + /* HDMITX IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)), > + /* HDMITX IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)), > + /* I2C2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)), > + /* I2C2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)), > + /* I2C3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)), > + /* I2C3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)), > + /* I2C4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)), > + /* I2C4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)), > + /* I2C5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)), > + /* I2C5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)), > + /* PWM8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)), > + /* PWM8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)), > + /* PWM9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)), > + /* PWM9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)), > + /* PWM10 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)), > + /* PWM10 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)), > + /* PWM11 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)), > + /* PWM11 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM12 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM12 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM13 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM13 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM14 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM14 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM15 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM15 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)), > + /* SDMMC2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)), > + /* SDMMC2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)), > + /* SPI0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)), > + /* SPI0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)), > + /* SPI1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)), > + /* SPI1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)), > + /* SPI2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)), > + /* SPI2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)), > + /* SPI3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)), > + /* SPI3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)), > + /* UART1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)), > + /* UART1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)), > + /* UART2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)), > + /* UART2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)), > + /* UART3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)), > + /* UART3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)), > + /* UART4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)), > + /* UART4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)), > + /* UART5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)), > + /* UART5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)), > + /* UART6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)), > + /* UART6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)), > + /* UART7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)), > + /* UART7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)), > + /* UART7 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)), > + /* UART8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)), > + /* UART8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)), > + /* UART9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)), > + /* UART9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)), > + /* UART9 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)), > + /* I2S1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)), > + /* I2S1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)), > + /* I2S1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)), > + /* I2S2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)), > + /* I2S2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)), > + /* I2S3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)), > + /* I2S3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)), > + /* PDM IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)), > + /* PDM IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)), > + /* PCIE20 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)), > + /* PCIE20 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)), > + /* PCIE20 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)), > + /* PCIE30X1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)), > + /* PCIE30X1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)), > + /* PCIE30X1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)), > + /* PCIE30X2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)), > + /* PCIE30X2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)), > + /* PCIE30X2 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)), > +}; > + > +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) > +{ > + struct rockchip_pinctrl_priv *priv = bank->priv; > + int iomux_num = (pin / 8); > + struct regmap *regmap; > + int reg, ret, mask; > + u8 bit; > + u32 data; > + > + debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); > + > + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) > + regmap = priv->regmap_pmu; > + else > + regmap = priv->regmap_base; > + > + reg = bank->iomux[iomux_num].offset; > + if ((pin % 8) >= 4) > + reg += 0x4; > + bit = (pin % 4) * 4; > + mask = 0xf; > + > + data = (mask << (bit + 16)); > + data |= (mux & mask) << bit; > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +#define RK3568_PULL_PMU_OFFSET 0x20 > +#define RK3568_PULL_GRF_OFFSET 0x80 > +#define RK3568_PULL_BITS_PER_PIN 2 > +#define RK3568_PULL_PINS_PER_REG 8 > +#define RK3568_PULL_BANK_STRIDE 0x10 > + > +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_PULL_PMU_OFFSET; > + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_PULL_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); > + *bit *= RK3568_PULL_BITS_PER_PIN; > +} > + > +#define RK3568_DRV_PMU_OFFSET 0x70 > +#define RK3568_DRV_GRF_OFFSET 0x200 > +#define RK3568_DRV_BITS_PER_PIN 8 > +#define RK3568_DRV_PINS_PER_REG 2 > +#define RK3568_DRV_BANK_STRIDE 0x40 > + > +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + /* The first 32 pins of the first bank are located in PMU */ > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_DRV_PMU_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_DRV_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); > + *bit *= RK3568_DRV_BITS_PER_PIN; > +} > + > +#define RK3568_SCHMITT_BITS_PER_PIN 2 > +#define RK3568_SCHMITT_PINS_PER_REG 8 > +#define RK3568_SCHMITT_BANK_STRIDE 0x10 > +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 > +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 > + > +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_SCHMITT_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); > + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; > + *bit *= RK3568_SCHMITT_BITS_PER_PIN; > + > + return 0; > +} > + > +static int rk3568_set_pull(struct rockchip_pin_bank *bank, > + int pin_num, int pull) > +{ > + struct regmap *regmap; > + int reg, ret; > + u8 bit, type; > + u32 data; > + > + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) > + return -EOPNOTSUPP; > + > + rk3568_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + type = bank->pull_type[pin_num / 8]; > + ret = rockchip_translate_pull_value(type, pull); > + if (ret < 0) { > + debug("unsupported pull setting %d\n", pull); > + return ret; > + } > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); > + > + data |= (ret << bit); > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +static int rk3568_set_drive(struct rockchip_pin_bank *bank, > + int pin_num, int strength) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + int drv = (1 << (strength + 1)) - 1; > + int ret = 0; > + > + rk3568_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (drv << bit); > + > + ret = regmap_write(regmap, reg, data); > + if (ret) > + return ret; > + > + if (bank->bank_num == 1 && pin_num == 21) > + reg = 0x0840; > + else if (bank->bank_num == 2 && pin_num == 2) > + reg = 0x0844; > + else if (bank->bank_num == 2 && pin_num == 8) > + reg = 0x0848; > + else if (bank->bank_num == 3 && pin_num == 0) > + reg = 0x084c; > + else if (bank->bank_num == 3 && pin_num == 6) > + reg = 0x0850; > + else if (bank->bank_num == 4 && pin_num == 0) > + reg = 0x0854; > + else > + return 0; > + > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16; > + data |= drv; > + > + return regmap_write(regmap, reg, data); > +} > + > +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank, > + int pin_num, int enable) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + > + rk3568_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (enable << bit); > + > + return regmap_write(regmap, reg, data); > +} > + > +static struct rockchip_pin_bank rk3568_pin_banks[] = { > + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > +}; > + > +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = { > + .pin_banks = rk3568_pin_banks, > + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), > + .nr_pins = 160, > + .grf_mux_offset = 0x0, > + .pmu_mux_offset = 0x0, > + .iomux_routes = rk3568_mux_route_data, > + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), > + .set_mux = rk3568_set_mux, > + .set_pull = rk3568_set_pull, > + .set_drive = rk3568_set_drive, > + .set_schmitt = rk3568_set_schmitt, > +}; > + > +static const struct udevice_id rk3568_pinctrl_ids[] = { > + { > + .compatible = "rockchip,rk3568-pinctrl", > + .data = (ulong)&rk3568_pin_ctrl > + }, > + { } > +}; > + > +U_BOOT_DRIVER(pinctrl_rk3568) = { > + .name = "rockchip_rk3568_pinctrl", > + .id = UCLASS_PINCTRL, > + .of_match = rk3568_pinctrl_ids, > + .priv_auto = sizeof(struct rockchip_pinctrl_priv), > + .ops = &rockchip_pinctrl_ops, > +#if !IS_ENABLED(CONFIG_OF_PLATDATA) > + .bind = dm_scan_fdt_dev, > +#endif > + .probe = rockchip_pinctrl_probe, > +}; > diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > index d9d61fdb72..1481c1e51c 100644 > --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > @@ -433,7 +433,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > int prop_len, param; > const u32 *data; > ofnode node; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > const struct device_node *np; > struct property *pp; > #else > @@ -473,7 +473,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > node = ofnode_get_by_phandle(conf); > if (!ofnode_valid(node)) > return -ENODEV; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > np = ofnode_to_np(node); > for (pp = np->properties; pp; pp = pp->next) { > prop_name = pp->name; > @@ -548,13 +548,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d > > /* preset iomux offset value, set new start value */ > if (iom->offset >= 0) { > - if (iom->type & IOMUX_SOURCE_PMU) > + if ((iom->type & IOMUX_SOURCE_PMU) || \ > + (iom->type & IOMUX_L_SOURCE_PMU)) > pmu_offs = iom->offset; > else > grf_offs = iom->offset; > } else { /* set current iomux offset */ > - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? > - pmu_offs : grf_offs; > + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || > + (iom->type & IOMUX_L_SOURCE_PMU)) ? > + pmu_offs : grf_offs; > } > > /* preset drv offset value, set new start value */
On Mon, Feb 13, 2023 at 2:30 PM Chris Morgan <macroalpha82@gmail.com> wrote: > > From: Chris Morgan <macromorgan@hotmail.com> > > Add support for the newer GPIO controller used by the rk356x series, > as well as the pinctrl device for the rk356x series. The GPIOv2 > controller has a write enable bit for some registers which differs > from the older versions of the GPIO controller. > > Signed-off-by: Peter Geis <pgwipeout@gmail.com> > Signed-off-by: Chris Morgan <macromorgan@hotmail.com> With pinctrl part from https://patchwork.ozlabs.org/project/uboot/patch/20230217115845.75303-11-jagan@amarulasolutions.com/ Tested-by: Vasily Khoruzhick <anarsoul@gmail.com> > --- > arch/arm/include/asm/arch-rockchip/gpio.h | 38 ++ > drivers/gpio/rk_gpio.c | 49 +- > drivers/pinctrl/rockchip/Makefile | 1 + > drivers/pinctrl/rockchip/pinctrl-rk3568.c | 453 ++++++++++++++++++ > .../pinctrl/rockchip/pinctrl-rockchip-core.c | 12 +- > 5 files changed, 540 insertions(+), 13 deletions(-) > create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c > > diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h > index 1aaec5faec..15f5de321b 100644 > --- a/arch/arm/include/asm/arch-rockchip/gpio.h > +++ b/arch/arm/include/asm/arch-rockchip/gpio.h > @@ -6,6 +6,7 @@ > #ifndef _ASM_ARCH_GPIO_H > #define _ASM_ARCH_GPIO_H > > +#if !defined(CONFIG_ROCKCHIP_RK3568) > struct rockchip_gpio_regs { > u32 swport_dr; > u32 swport_ddr; > @@ -22,7 +23,44 @@ struct rockchip_gpio_regs { > u32 reserved1[(0x60 - 0x54) / 4]; > u32 ls_sync; > }; > + > check_member(rockchip_gpio_regs, ls_sync, 0x60); > +#else > +struct rockchip_gpio_regs { > + u32 swport_dr_l; /* ADDRESS OFFSET: 0x0000 */ > + u32 swport_dr_h; /* ADDRESS OFFSET: 0x0004 */ > + u32 swport_ddr_l; /* ADDRESS OFFSET: 0x0008 */ > + u32 swport_ddr_h; /* ADDRESS OFFSET: 0x000c */ > + u32 int_en_l; /* ADDRESS OFFSET: 0x0010 */ > + u32 int_en_h; /* ADDRESS OFFSET: 0x0014 */ > + u32 int_mask_l; /* ADDRESS OFFSET: 0x0018 */ > + u32 int_mask_h; /* ADDRESS OFFSET: 0x001c */ > + u32 int_type_l; /* ADDRESS OFFSET: 0x0020 */ > + u32 int_type_h; /* ADDRESS OFFSET: 0x0024 */ > + u32 int_polarity_l; /* ADDRESS OFFSET: 0x0028 */ > + u32 int_polarity_h; /* ADDRESS OFFSET: 0x002c */ > + u32 int_bothedge_l; /* ADDRESS OFFSET: 0x0030 */ > + u32 int_bothedge_h; /* ADDRESS OFFSET: 0x0034 */ > + u32 debounce_l; /* ADDRESS OFFSET: 0x0038 */ > + u32 debounce_h; /* ADDRESS OFFSET: 0x003c */ > + u32 dbclk_div_en_l; /* ADDRESS OFFSET: 0x0040 */ > + u32 dbclk_div_en_h; /* ADDRESS OFFSET: 0x0044 */ > + u32 dbclk_div_con; /* ADDRESS OFFSET: 0x0048 */ > + u32 reserved004c; /* ADDRESS OFFSET: 0x004c */ > + u32 int_status; /* ADDRESS OFFSET: 0x0050 */ > + u32 reserved0054; /* ADDRESS OFFSET: 0x0054 */ > + u32 int_rawstatus; /* ADDRESS OFFSET: 0x0058 */ > + u32 reserved005c; /* ADDRESS OFFSET: 0x005c */ > + u32 port_eoi_l; /* ADDRESS OFFSET: 0x0060 */ > + u32 port_eoi_h; /* ADDRESS OFFSET: 0x0064 */ > + u32 reserved0068[2]; /* ADDRESS OFFSET: 0x0068 */ > + u32 ext_port; /* ADDRESS OFFSET: 0x0070 */ > + u32 reserved0074; /* ADDRESS OFFSET: 0x0074 */ > + u32 ver_id; /* ADDRESS OFFSET: 0x0078 */ > +}; > + > +check_member(rockchip_gpio_regs, ver_id, 0x0078); > +#endif > > enum gpio_pu_pd { > GPIO_PULL_NORMAL = 0, > diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c > index 98a79b5f4d..e2653be058 100644 > --- a/drivers/gpio/rk_gpio.c > +++ b/drivers/gpio/rk_gpio.c > @@ -2,12 +2,15 @@ > /* > * (C) Copyright 2015 Google, Inc > * > - * (C) Copyright 2008-2014 Rockchip Electronics > + * (C) Copyright 2008-2023 Rockchip Electronics > * Peter, Software Engineering, <superpeter.cai@gmail.com>. > + * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>. > */ > > #include <common.h> > #include <dm.h> > +#include <dm/of_access.h> > +#include <dm/device_compat.h> > #include <syscon.h> > #include <linux/errno.h> > #include <asm/gpio.h> > @@ -23,6 +26,35 @@ enum { > > #define OFFSET_TO_BIT(bit) (1UL << (bit)) > > +/* > + * Newer Rockchip devices have additional registers that must be > + * accounted for. > + */ > +#if defined(CONFIG_ROCKCHIP_RK3568) > +#define GPIO_VER 2 > +#define REG_L(R) (R##_l) > +#define REG_H(R) (R##_h) > +#define READ_REG(REG) ((readl(REG_L(REG)) & 0xFFFF) | \ > + ((readl(REG_H(REG)) & 0xFFFF) << 16)) > +#define WRITE_REG(REG, VAL) \ > +{\ > + writel(((VAL) & 0xFFFF) | 0xFFFF0000, REG_L(REG)); \ > + writel((((VAL) & 0xFFFF0000) >> 16) | 0xFFFF0000, REG_H(REG));\ > +} > +#define CLRBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) & ~(MASK)) > +#define SETBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) | (MASK)) > +#define CLRSETBITS_LE32(REG, MASK, VAL) WRITE_REG(REG, \ > + (READ_REG(REG) & ~(MASK)) | (VAL)) > + > +#else > +#define GPIO_VER 1 > +#define READ_REG(REG) readl(REG) > +#define WRITE_REG(REG, VAL) writel(VAL, REG) > +#define CLRBITS_LE32(REG, MASK) clrbits_le32(REG, MASK) > +#define SETBITS_LE32(REG, MASK) setbits_le32(REG, MASK) > +#define CLRSETBITS_LE32(REG, MASK, VAL) clrsetbits_le32(REG, MASK, VAL) > +#endif > + > struct rockchip_gpio_priv { > struct rockchip_gpio_regs *regs; > struct udevice *pinctrl; > @@ -35,7 +68,7 @@ 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; > > - clrbits_le32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > + CLRBITS_LE32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > > return 0; > } > @@ -47,8 +80,8 @@ static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > - setbits_le32(®s->swport_ddr, mask); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > + SETBITS_LE32(®s->swport_ddr, mask); > > return 0; > } > @@ -68,7 +101,7 @@ static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > > return 0; > } > @@ -86,14 +119,14 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) > ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); > if (ret) > return ret; > - is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); > + is_output = READ_REG(®s->swport_ddr) & OFFSET_TO_BIT(offset); > > return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; > #endif > } > > /* Simple SPL interface to GPIOs */ > -#ifdef CONFIG_SPL_BUILD > +#if defined(CONFIG_SPL_BUILD) && (GPIO_VER == 1) > > enum { > PULL_NONE_1V8 = 0, > @@ -143,7 +176,7 @@ 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; > + char *end = NULL; > int ret; > > priv->regs = dev_read_addr_ptr(dev); > diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile > index 9884355473..90461ae881 100644 > --- a/drivers/pinctrl/rockchip/Makefile > +++ b/drivers/pinctrl/rockchip/Makefile > @@ -14,5 +14,6 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o > obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o > obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o > obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o > +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o > obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o > obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o > diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > new file mode 100644 > index 0000000000..dce1c1e7ee > --- /dev/null > +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > @@ -0,0 +1,453 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * (C) Copyright 2020 Rockchip Electronics Co., Ltd > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <dm/pinctrl.h> > +#include <regmap.h> > +#include <syscon.h> > + > +#include "pinctrl-rockchip.h" > + > +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { > + /* CAN0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)), > + /* CAN0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)), > + /* CAN1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)), > + /* CAN1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)), > + /* CAN2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)), > + /* CAN2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)), > + /* EDPDP_HPDIN IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)), > + /* EDPDP_HPDIN IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)), > + /* GMAC1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)), > + /* GMAC1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)), > + /* HDMITX IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)), > + /* HDMITX IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)), > + /* I2C2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)), > + /* I2C2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)), > + /* I2C3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)), > + /* I2C3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)), > + /* I2C4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)), > + /* I2C4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)), > + /* I2C5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)), > + /* I2C5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)), > + /* PWM8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)), > + /* PWM8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)), > + /* PWM9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)), > + /* PWM9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)), > + /* PWM10 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)), > + /* PWM10 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)), > + /* PWM11 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)), > + /* PWM11 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM12 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM12 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM13 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM13 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM14 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM14 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM15 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM15 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)), > + /* SDMMC2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)), > + /* SDMMC2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)), > + /* SPI0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)), > + /* SPI0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)), > + /* SPI1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)), > + /* SPI1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)), > + /* SPI2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)), > + /* SPI2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)), > + /* SPI3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)), > + /* SPI3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)), > + /* UART1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)), > + /* UART1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)), > + /* UART2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)), > + /* UART2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)), > + /* UART3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)), > + /* UART3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)), > + /* UART4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)), > + /* UART4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)), > + /* UART5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)), > + /* UART5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)), > + /* UART6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)), > + /* UART6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)), > + /* UART7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)), > + /* UART7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)), > + /* UART7 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)), > + /* UART8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)), > + /* UART8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)), > + /* UART9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)), > + /* UART9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)), > + /* UART9 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)), > + /* I2S1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)), > + /* I2S1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)), > + /* I2S1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)), > + /* I2S2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)), > + /* I2S2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)), > + /* I2S3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)), > + /* I2S3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)), > + /* PDM IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)), > + /* PDM IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)), > + /* PCIE20 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)), > + /* PCIE20 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)), > + /* PCIE20 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)), > + /* PCIE30X1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)), > + /* PCIE30X1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)), > + /* PCIE30X1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)), > + /* PCIE30X2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)), > + /* PCIE30X2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)), > + /* PCIE30X2 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)), > +}; > + > +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) > +{ > + struct rockchip_pinctrl_priv *priv = bank->priv; > + int iomux_num = (pin / 8); > + struct regmap *regmap; > + int reg, ret, mask; > + u8 bit; > + u32 data; > + > + debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); > + > + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) > + regmap = priv->regmap_pmu; > + else > + regmap = priv->regmap_base; > + > + reg = bank->iomux[iomux_num].offset; > + if ((pin % 8) >= 4) > + reg += 0x4; > + bit = (pin % 4) * 4; > + mask = 0xf; > + > + data = (mask << (bit + 16)); > + data |= (mux & mask) << bit; > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +#define RK3568_PULL_PMU_OFFSET 0x20 > +#define RK3568_PULL_GRF_OFFSET 0x80 > +#define RK3568_PULL_BITS_PER_PIN 2 > +#define RK3568_PULL_PINS_PER_REG 8 > +#define RK3568_PULL_BANK_STRIDE 0x10 > + > +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_PULL_PMU_OFFSET; > + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_PULL_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); > + *bit *= RK3568_PULL_BITS_PER_PIN; > +} > + > +#define RK3568_DRV_PMU_OFFSET 0x70 > +#define RK3568_DRV_GRF_OFFSET 0x200 > +#define RK3568_DRV_BITS_PER_PIN 8 > +#define RK3568_DRV_PINS_PER_REG 2 > +#define RK3568_DRV_BANK_STRIDE 0x40 > + > +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + /* The first 32 pins of the first bank are located in PMU */ > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_DRV_PMU_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_DRV_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); > + *bit *= RK3568_DRV_BITS_PER_PIN; > +} > + > +#define RK3568_SCHMITT_BITS_PER_PIN 2 > +#define RK3568_SCHMITT_PINS_PER_REG 8 > +#define RK3568_SCHMITT_BANK_STRIDE 0x10 > +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 > +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 > + > +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_SCHMITT_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); > + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; > + *bit *= RK3568_SCHMITT_BITS_PER_PIN; > + > + return 0; > +} > + > +static int rk3568_set_pull(struct rockchip_pin_bank *bank, > + int pin_num, int pull) > +{ > + struct regmap *regmap; > + int reg, ret; > + u8 bit, type; > + u32 data; > + > + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) > + return -EOPNOTSUPP; > + > + rk3568_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + type = bank->pull_type[pin_num / 8]; > + ret = rockchip_translate_pull_value(type, pull); > + if (ret < 0) { > + debug("unsupported pull setting %d\n", pull); > + return ret; > + } > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); > + > + data |= (ret << bit); > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +static int rk3568_set_drive(struct rockchip_pin_bank *bank, > + int pin_num, int strength) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + int drv = (1 << (strength + 1)) - 1; > + int ret = 0; > + > + rk3568_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (drv << bit); > + > + ret = regmap_write(regmap, reg, data); > + if (ret) > + return ret; > + > + if (bank->bank_num == 1 && pin_num == 21) > + reg = 0x0840; > + else if (bank->bank_num == 2 && pin_num == 2) > + reg = 0x0844; > + else if (bank->bank_num == 2 && pin_num == 8) > + reg = 0x0848; > + else if (bank->bank_num == 3 && pin_num == 0) > + reg = 0x084c; > + else if (bank->bank_num == 3 && pin_num == 6) > + reg = 0x0850; > + else if (bank->bank_num == 4 && pin_num == 0) > + reg = 0x0854; > + else > + return 0; > + > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16; > + data |= drv; > + > + return regmap_write(regmap, reg, data); > +} > + > +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank, > + int pin_num, int enable) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + > + rk3568_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (enable << bit); > + > + return regmap_write(regmap, reg, data); > +} > + > +static struct rockchip_pin_bank rk3568_pin_banks[] = { > + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > +}; > + > +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = { > + .pin_banks = rk3568_pin_banks, > + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), > + .nr_pins = 160, > + .grf_mux_offset = 0x0, > + .pmu_mux_offset = 0x0, > + .iomux_routes = rk3568_mux_route_data, > + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), > + .set_mux = rk3568_set_mux, > + .set_pull = rk3568_set_pull, > + .set_drive = rk3568_set_drive, > + .set_schmitt = rk3568_set_schmitt, > +}; > + > +static const struct udevice_id rk3568_pinctrl_ids[] = { > + { > + .compatible = "rockchip,rk3568-pinctrl", > + .data = (ulong)&rk3568_pin_ctrl > + }, > + { } > +}; > + > +U_BOOT_DRIVER(pinctrl_rk3568) = { > + .name = "rockchip_rk3568_pinctrl", > + .id = UCLASS_PINCTRL, > + .of_match = rk3568_pinctrl_ids, > + .priv_auto = sizeof(struct rockchip_pinctrl_priv), > + .ops = &rockchip_pinctrl_ops, > +#if !IS_ENABLED(CONFIG_OF_PLATDATA) > + .bind = dm_scan_fdt_dev, > +#endif > + .probe = rockchip_pinctrl_probe, > +}; > diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > index d9d61fdb72..1481c1e51c 100644 > --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > @@ -433,7 +433,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > int prop_len, param; > const u32 *data; > ofnode node; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > const struct device_node *np; > struct property *pp; > #else > @@ -473,7 +473,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > node = ofnode_get_by_phandle(conf); > if (!ofnode_valid(node)) > return -ENODEV; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > np = ofnode_to_np(node); > for (pp = np->properties; pp; pp = pp->next) { > prop_name = pp->name; > @@ -548,13 +548,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d > > /* preset iomux offset value, set new start value */ > if (iom->offset >= 0) { > - if (iom->type & IOMUX_SOURCE_PMU) > + if ((iom->type & IOMUX_SOURCE_PMU) || \ > + (iom->type & IOMUX_L_SOURCE_PMU)) > pmu_offs = iom->offset; > else > grf_offs = iom->offset; > } else { /* set current iomux offset */ > - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? > - pmu_offs : grf_offs; > + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || > + (iom->type & IOMUX_L_SOURCE_PMU)) ? > + pmu_offs : grf_offs; > } > > /* preset drv offset value, set new start value */ > -- > 2.34.1 >
On 2/14/23 00:27, Chris Morgan wrote: > From: Chris Morgan <macromorgan@hotmail.com> > > Add support for the newer GPIO controller used by the rk356x series, > as well as the pinctrl device for the rk356x series. The GPIOv2 > controller has a write enable bit for some registers which differs > from the older versions of the GPIO controller. > > Signed-off-by: Peter Geis <pgwipeout@gmail.com> > Signed-off-by: Chris Morgan <macromorgan@hotmail.com> Hi Chris, In the file below you have added > + * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>. as copyright owner, maybe add him as co-author of this patch ? Or what was his contribution ? > --- > arch/arm/include/asm/arch-rockchip/gpio.h | 38 ++ > drivers/gpio/rk_gpio.c | 49 +- > drivers/pinctrl/rockchip/Makefile | 1 + > drivers/pinctrl/rockchip/pinctrl-rk3568.c | 453 ++++++++++++++++++ > .../pinctrl/rockchip/pinctrl-rockchip-core.c | 12 +- > 5 files changed, 540 insertions(+), 13 deletions(-) > create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c > > diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h > index 1aaec5faec..15f5de321b 100644 > --- a/arch/arm/include/asm/arch-rockchip/gpio.h > +++ b/arch/arm/include/asm/arch-rockchip/gpio.h > @@ -6,6 +6,7 @@ > #ifndef _ASM_ARCH_GPIO_H > #define _ASM_ARCH_GPIO_H > > +#if !defined(CONFIG_ROCKCHIP_RK3568) Can't we figure out from the compatible which struct layout to use ? Using conditionally compile code makes things difficult to read after some time. > struct rockchip_gpio_regs { > u32 swport_dr; > u32 swport_ddr; > @@ -22,7 +23,44 @@ struct rockchip_gpio_regs { > u32 reserved1[(0x60 - 0x54) / 4]; > u32 ls_sync; > }; > + > check_member(rockchip_gpio_regs, ls_sync, 0x60); > +#else > +struct rockchip_gpio_regs { > + u32 swport_dr_l; /* ADDRESS OFFSET: 0x0000 */ > + u32 swport_dr_h; /* ADDRESS OFFSET: 0x0004 */ > + u32 swport_ddr_l; /* ADDRESS OFFSET: 0x0008 */ > + u32 swport_ddr_h; /* ADDRESS OFFSET: 0x000c */ > + u32 int_en_l; /* ADDRESS OFFSET: 0x0010 */ > + u32 int_en_h; /* ADDRESS OFFSET: 0x0014 */ > + u32 int_mask_l; /* ADDRESS OFFSET: 0x0018 */ > + u32 int_mask_h; /* ADDRESS OFFSET: 0x001c */ > + u32 int_type_l; /* ADDRESS OFFSET: 0x0020 */ > + u32 int_type_h; /* ADDRESS OFFSET: 0x0024 */ > + u32 int_polarity_l; /* ADDRESS OFFSET: 0x0028 */ > + u32 int_polarity_h; /* ADDRESS OFFSET: 0x002c */ > + u32 int_bothedge_l; /* ADDRESS OFFSET: 0x0030 */ > + u32 int_bothedge_h; /* ADDRESS OFFSET: 0x0034 */ > + u32 debounce_l; /* ADDRESS OFFSET: 0x0038 */ > + u32 debounce_h; /* ADDRESS OFFSET: 0x003c */ > + u32 dbclk_div_en_l; /* ADDRESS OFFSET: 0x0040 */ > + u32 dbclk_div_en_h; /* ADDRESS OFFSET: 0x0044 */ > + u32 dbclk_div_con; /* ADDRESS OFFSET: 0x0048 */ > + u32 reserved004c; /* ADDRESS OFFSET: 0x004c */ > + u32 int_status; /* ADDRESS OFFSET: 0x0050 */ > + u32 reserved0054; /* ADDRESS OFFSET: 0x0054 */ > + u32 int_rawstatus; /* ADDRESS OFFSET: 0x0058 */ > + u32 reserved005c; /* ADDRESS OFFSET: 0x005c */ > + u32 port_eoi_l; /* ADDRESS OFFSET: 0x0060 */ > + u32 port_eoi_h; /* ADDRESS OFFSET: 0x0064 */ > + u32 reserved0068[2]; /* ADDRESS OFFSET: 0x0068 */ > + u32 ext_port; /* ADDRESS OFFSET: 0x0070 */ > + u32 reserved0074; /* ADDRESS OFFSET: 0x0074 */ > + u32 ver_id; /* ADDRESS OFFSET: 0x0078 */ > +}; > + > +check_member(rockchip_gpio_regs, ver_id, 0x0078); > +#endif > > enum gpio_pu_pd { > GPIO_PULL_NORMAL = 0, > diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c > index 98a79b5f4d..e2653be058 100644 > --- a/drivers/gpio/rk_gpio.c > +++ b/drivers/gpio/rk_gpio.c > @@ -2,12 +2,15 @@ > /* > * (C) Copyright 2015 Google, Inc > * > - * (C) Copyright 2008-2014 Rockchip Electronics > + * (C) Copyright 2008-2023 Rockchip Electronics > * Peter, Software Engineering, <superpeter.cai@gmail.com>. > + * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>. > */ > > #include <common.h> > #include <dm.h> > +#include <dm/of_access.h> > +#include <dm/device_compat.h> > #include <syscon.h> > #include <linux/errno.h> > #include <asm/gpio.h> > @@ -23,6 +26,35 @@ enum { > > #define OFFSET_TO_BIT(bit) (1UL << (bit)) > > +/* > + * Newer Rockchip devices have additional registers that must be > + * accounted for. > + */ > +#if defined(CONFIG_ROCKCHIP_RK3568) > +#define GPIO_VER 2 Why don't you use the gpio versioning from here: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpio/gpio-rockchip.c#n30 I think it's best to reuse the definitions from Linux kernel, as it's already implemented there. > +#define REG_L(R) (R##_l) > +#define REG_H(R) (R##_h) > +#define READ_REG(REG) ((readl(REG_L(REG)) & 0xFFFF) | \ > + ((readl(REG_H(REG)) & 0xFFFF) << 16)) > +#define WRITE_REG(REG, VAL) \ > +{\ > + writel(((VAL) & 0xFFFF) | 0xFFFF0000, REG_L(REG)); \ > + writel((((VAL) & 0xFFFF0000) >> 16) | 0xFFFF0000, REG_H(REG));\ > +} > +#define CLRBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) & ~(MASK)) > +#define SETBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) | (MASK)) > +#define CLRSETBITS_LE32(REG, MASK, VAL) WRITE_REG(REG, \ > + (READ_REG(REG) & ~(MASK)) | (VAL)) > + > +#else > +#define GPIO_VER 1 ditto > +#define READ_REG(REG) readl(REG) > +#define WRITE_REG(REG, VAL) writel(VAL, REG) > +#define CLRBITS_LE32(REG, MASK) clrbits_le32(REG, MASK) > +#define SETBITS_LE32(REG, MASK) setbits_le32(REG, MASK) > +#define CLRSETBITS_LE32(REG, MASK, VAL) clrsetbits_le32(REG, MASK, VAL) > +#endif > + > struct rockchip_gpio_priv { > struct rockchip_gpio_regs *regs; > struct udevice *pinctrl; > @@ -35,7 +68,7 @@ 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; > > - clrbits_le32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > + CLRBITS_LE32(®s->swport_ddr, OFFSET_TO_BIT(offset)); > > return 0; > } > @@ -47,8 +80,8 @@ static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > - setbits_le32(®s->swport_ddr, mask); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > + SETBITS_LE32(®s->swport_ddr, mask); > > return 0; > } > @@ -68,7 +101,7 @@ static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, > struct rockchip_gpio_regs *regs = priv->regs; > int mask = OFFSET_TO_BIT(offset); > > - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); > + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); > > return 0; > } > @@ -86,14 +119,14 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) > ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); > if (ret) > return ret; > - is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); > + is_output = READ_REG(®s->swport_ddr) & OFFSET_TO_BIT(offset); > > return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; > #endif > } > > /* Simple SPL interface to GPIOs */ > -#ifdef CONFIG_SPL_BUILD > +#if defined(CONFIG_SPL_BUILD) && (GPIO_VER == 1) > > enum { > PULL_NONE_1V8 = 0, > @@ -143,7 +176,7 @@ 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; > + char *end = NULL; > int ret; > > priv->regs = dev_read_addr_ptr(dev); > diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile > index 9884355473..90461ae881 100644 > --- a/drivers/pinctrl/rockchip/Makefile > +++ b/drivers/pinctrl/rockchip/Makefile > @@ -14,5 +14,6 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o > obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o > obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o > obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o > +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o > obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o > obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o > diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > new file mode 100644 > index 0000000000..dce1c1e7ee > --- /dev/null > +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c > @@ -0,0 +1,453 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * (C) Copyright 2020 Rockchip Electronics Co., Ltd > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <dm/pinctrl.h> > +#include <regmap.h> > +#include <syscon.h> > + > +#include "pinctrl-rockchip.h" > + > +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { > + /* CAN0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)), > + /* CAN0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)), > + /* CAN1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)), > + /* CAN1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)), > + /* CAN2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)), > + /* CAN2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)), > + /* EDPDP_HPDIN IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)), > + /* EDPDP_HPDIN IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)), > + /* GMAC1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)), > + /* GMAC1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)), > + /* HDMITX IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)), > + /* HDMITX IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)), > + /* I2C2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)), > + /* I2C2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)), > + /* I2C3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)), > + /* I2C3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)), > + /* I2C4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)), > + /* I2C4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)), > + /* I2C5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)), > + /* I2C5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)), > + /* PWM8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)), > + /* PWM8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)), > + /* PWM9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)), > + /* PWM9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)), > + /* PWM10 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)), > + /* PWM10 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)), > + /* PWM11 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)), > + /* PWM11 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)), > + /* PWM12 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)), > + /* PWM12 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)), > + /* PWM13 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)), > + /* PWM13 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)), > + /* PWM14 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)), > + /* PWM14 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)), > + /* PWM15 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)), > + /* PWM15 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)), > + /* SDMMC2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)), > + /* SDMMC2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)), > + /* SPI0 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)), > + /* SPI0 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)), > + /* SPI1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)), > + /* SPI1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)), > + /* SPI2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)), > + /* SPI2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)), > + /* SPI3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)), > + /* SPI3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)), > + /* UART1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)), > + /* UART1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)), > + /* UART2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)), > + /* UART2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)), > + /* UART3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)), > + /* UART3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)), > + /* UART4 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)), > + /* UART4 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)), > + /* UART5 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)), > + /* UART5 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)), > + /* UART6 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)), > + /* UART6 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)), > + /* UART7 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)), > + /* UART7 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)), > + /* UART7 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)), > + /* UART8 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)), > + /* UART8 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)), > + /* UART9 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)), > + /* UART9 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)), > + /* UART9 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)), > + /* I2S1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)), > + /* I2S1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)), > + /* I2S1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)), > + /* I2S2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)), > + /* I2S2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)), > + /* I2S3 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)), > + /* I2S3 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)), > + /* PDM IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)), > + /* PDM IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)), > + /* PCIE20 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)), > + /* PCIE20 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)), > + /* PCIE20 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)), > + /* PCIE30X1 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)), > + /* PCIE30X1 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)), > + /* PCIE30X1 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)), > + /* PCIE30X2 IO mux selection M0 */ > + MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)), > + /* PCIE30X2 IO mux selection M1 */ > + MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)), > + /* PCIE30X2 IO mux selection M2 */ > + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)), > +}; > + > +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) > +{ > + struct rockchip_pinctrl_priv *priv = bank->priv; > + int iomux_num = (pin / 8); > + struct regmap *regmap; > + int reg, ret, mask; > + u8 bit; > + u32 data; > + > + debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); > + > + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) > + regmap = priv->regmap_pmu; > + else > + regmap = priv->regmap_base; > + > + reg = bank->iomux[iomux_num].offset; > + if ((pin % 8) >= 4) > + reg += 0x4; > + bit = (pin % 4) * 4; > + mask = 0xf; > + > + data = (mask << (bit + 16)); > + data |= (mux & mask) << bit; > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +#define RK3568_PULL_PMU_OFFSET 0x20 > +#define RK3568_PULL_GRF_OFFSET 0x80 > +#define RK3568_PULL_BITS_PER_PIN 2 > +#define RK3568_PULL_PINS_PER_REG 8 > +#define RK3568_PULL_BANK_STRIDE 0x10 > + > +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_PULL_PMU_OFFSET; > + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_PULL_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); > + *bit *= RK3568_PULL_BITS_PER_PIN; > +} > + > +#define RK3568_DRV_PMU_OFFSET 0x70 > +#define RK3568_DRV_GRF_OFFSET 0x200 > +#define RK3568_DRV_BITS_PER_PIN 8 > +#define RK3568_DRV_PINS_PER_REG 2 > +#define RK3568_DRV_BANK_STRIDE 0x40 > + > +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + /* The first 32 pins of the first bank are located in PMU */ > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_DRV_PMU_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_DRV_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); > + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); > + *bit *= RK3568_DRV_BITS_PER_PIN; > +} > + > +#define RK3568_SCHMITT_BITS_PER_PIN 2 > +#define RK3568_SCHMITT_PINS_PER_REG 8 > +#define RK3568_SCHMITT_BANK_STRIDE 0x10 > +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 > +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 > + > +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, > + int pin_num, struct regmap **regmap, > + int *reg, u8 *bit) > +{ > + struct rockchip_pinctrl_priv *info = bank->priv; > + > + if (bank->bank_num == 0) { > + *regmap = info->regmap_pmu; > + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; > + } else { > + *regmap = info->regmap_base; > + *reg = RK3568_SCHMITT_GRF_OFFSET; > + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; > + } > + > + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); > + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; > + *bit *= RK3568_SCHMITT_BITS_PER_PIN; > + > + return 0; > +} > + > +static int rk3568_set_pull(struct rockchip_pin_bank *bank, > + int pin_num, int pull) > +{ > + struct regmap *regmap; > + int reg, ret; > + u8 bit, type; > + u32 data; > + > + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) > + return -EOPNOTSUPP; > + > + rk3568_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + type = bank->pull_type[pin_num / 8]; > + ret = rockchip_translate_pull_value(type, pull); > + if (ret < 0) { > + debug("unsupported pull setting %d\n", pull); > + return ret; > + } > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); > + > + data |= (ret << bit); > + ret = regmap_write(regmap, reg, data); > + > + return ret; > +} > + > +static int rk3568_set_drive(struct rockchip_pin_bank *bank, > + int pin_num, int strength) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + int drv = (1 << (strength + 1)) - 1; > + int ret = 0; > + > + rk3568_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (drv << bit); > + > + ret = regmap_write(regmap, reg, data); > + if (ret) > + return ret; > + > + if (bank->bank_num == 1 && pin_num == 21) > + reg = 0x0840; > + else if (bank->bank_num == 2 && pin_num == 2) > + reg = 0x0844; > + else if (bank->bank_num == 2 && pin_num == 8) > + reg = 0x0848; > + else if (bank->bank_num == 3 && pin_num == 0) > + reg = 0x084c; > + else if (bank->bank_num == 3 && pin_num == 6) > + reg = 0x0850; > + else if (bank->bank_num == 4 && pin_num == 0) > + reg = 0x0854; > + else > + return 0; > + > + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16; > + data |= drv; > + > + return regmap_write(regmap, reg, data); > +} > + > +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank, > + int pin_num, int enable) > +{ > + struct regmap *regmap; > + int reg; > + u32 data; > + u8 bit; > + > + rk3568_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); > + > + /* enable the write to the equivalent lower bits */ > + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); > + data |= (enable << bit); > + > + return regmap_write(regmap, reg, data); > +} > + > +static struct rockchip_pin_bank rk3568_pin_banks[] = { > + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, > + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT, > + IOMUX_WIDTH_4BIT), > +}; > + > +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = { > + .pin_banks = rk3568_pin_banks, > + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), > + .nr_pins = 160, > + .grf_mux_offset = 0x0, > + .pmu_mux_offset = 0x0, > + .iomux_routes = rk3568_mux_route_data, > + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), > + .set_mux = rk3568_set_mux, > + .set_pull = rk3568_set_pull, > + .set_drive = rk3568_set_drive, > + .set_schmitt = rk3568_set_schmitt, > +}; > + > +static const struct udevice_id rk3568_pinctrl_ids[] = { > + { > + .compatible = "rockchip,rk3568-pinctrl", > + .data = (ulong)&rk3568_pin_ctrl > + }, > + { } > +}; > + > +U_BOOT_DRIVER(pinctrl_rk3568) = { > + .name = "rockchip_rk3568_pinctrl", > + .id = UCLASS_PINCTRL, > + .of_match = rk3568_pinctrl_ids, > + .priv_auto = sizeof(struct rockchip_pinctrl_priv), > + .ops = &rockchip_pinctrl_ops, > +#if !IS_ENABLED(CONFIG_OF_PLATDATA) you should use here #if IS_ENABLED(CONFIG_OF_REAL) > + .bind = dm_scan_fdt_dev, > +#endif > + .probe = rockchip_pinctrl_probe, > +}; > diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > index d9d61fdb72..1481c1e51c 100644 > --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c > @@ -433,7 +433,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > int prop_len, param; > const u32 *data; > ofnode node; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > const struct device_node *np; > struct property *pp; > #else > @@ -473,7 +473,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, > node = ofnode_get_by_phandle(conf); > if (!ofnode_valid(node)) > return -ENODEV; > -#ifdef CONFIG_OF_LIVE > +#if CONFIG_IS_ENABLED(OF_LIVE) > np = ofnode_to_np(node); > for (pp = np->properties; pp; pp = pp->next) { > prop_name = pp->name; > @@ -548,13 +548,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d > > /* preset iomux offset value, set new start value */ > if (iom->offset >= 0) { > - if (iom->type & IOMUX_SOURCE_PMU) > + if ((iom->type & IOMUX_SOURCE_PMU) || \ > + (iom->type & IOMUX_L_SOURCE_PMU)) > pmu_offs = iom->offset; > else > grf_offs = iom->offset; > } else { /* set current iomux offset */ > - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? > - pmu_offs : grf_offs; > + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || > + (iom->type & IOMUX_L_SOURCE_PMU)) ? > + pmu_offs : grf_offs; > } > > /* preset drv offset value, set new start value */
Hi, On Wed, 1 Mar 2023 at 01:25, Eugen Hristev <eugen.hristev@collabora.com> wrote: > > On 2/14/23 00:27, Chris Morgan wrote: > > From: Chris Morgan <macromorgan@hotmail.com> > > > > Add support for the newer GPIO controller used by the rk356x series, > > as well as the pinctrl device for the rk356x series. The GPIOv2 > > controller has a write enable bit for some registers which differs > > from the older versions of the GPIO controller. > > > > Signed-off-by: Peter Geis <pgwipeout@gmail.com> > > Signed-off-by: Chris Morgan <macromorgan@hotmail.com> > > Hi Chris, > > In the file below you have added > > > + * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>. > > as copyright owner, maybe add him as co-author of this patch ? Or what > was his contribution ? > > > > --- > > arch/arm/include/asm/arch-rockchip/gpio.h | 38 ++ > > drivers/gpio/rk_gpio.c | 49 +- > > drivers/pinctrl/rockchip/Makefile | 1 + > > drivers/pinctrl/rockchip/pinctrl-rk3568.c | 453 ++++++++++++++++++ > > .../pinctrl/rockchip/pinctrl-rockchip-core.c | 12 +- > > 5 files changed, 540 insertions(+), 13 deletions(-) > > create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c > > > > diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h > > index 1aaec5faec..15f5de321b 100644 > > --- a/arch/arm/include/asm/arch-rockchip/gpio.h > > +++ b/arch/arm/include/asm/arch-rockchip/gpio.h > > @@ -6,6 +6,7 @@ > > #ifndef _ASM_ARCH_GPIO_H > > #define _ASM_ARCH_GPIO_H > > > > +#if !defined(CONFIG_ROCKCHIP_RK3568) > > Can't we figure out from the compatible which struct layout to use ? > Using conditionally compile code makes things difficult to read after > some time. Yes, we must not add arch-specific CONFIG things to drivers. Handle it at runtime instead, i.e. the driver should handle both. Regards, SImon
diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h index 1aaec5faec..15f5de321b 100644 --- a/arch/arm/include/asm/arch-rockchip/gpio.h +++ b/arch/arm/include/asm/arch-rockchip/gpio.h @@ -6,6 +6,7 @@ #ifndef _ASM_ARCH_GPIO_H #define _ASM_ARCH_GPIO_H +#if !defined(CONFIG_ROCKCHIP_RK3568) struct rockchip_gpio_regs { u32 swport_dr; u32 swport_ddr; @@ -22,7 +23,44 @@ struct rockchip_gpio_regs { u32 reserved1[(0x60 - 0x54) / 4]; u32 ls_sync; }; + check_member(rockchip_gpio_regs, ls_sync, 0x60); +#else +struct rockchip_gpio_regs { + u32 swport_dr_l; /* ADDRESS OFFSET: 0x0000 */ + u32 swport_dr_h; /* ADDRESS OFFSET: 0x0004 */ + u32 swport_ddr_l; /* ADDRESS OFFSET: 0x0008 */ + u32 swport_ddr_h; /* ADDRESS OFFSET: 0x000c */ + u32 int_en_l; /* ADDRESS OFFSET: 0x0010 */ + u32 int_en_h; /* ADDRESS OFFSET: 0x0014 */ + u32 int_mask_l; /* ADDRESS OFFSET: 0x0018 */ + u32 int_mask_h; /* ADDRESS OFFSET: 0x001c */ + u32 int_type_l; /* ADDRESS OFFSET: 0x0020 */ + u32 int_type_h; /* ADDRESS OFFSET: 0x0024 */ + u32 int_polarity_l; /* ADDRESS OFFSET: 0x0028 */ + u32 int_polarity_h; /* ADDRESS OFFSET: 0x002c */ + u32 int_bothedge_l; /* ADDRESS OFFSET: 0x0030 */ + u32 int_bothedge_h; /* ADDRESS OFFSET: 0x0034 */ + u32 debounce_l; /* ADDRESS OFFSET: 0x0038 */ + u32 debounce_h; /* ADDRESS OFFSET: 0x003c */ + u32 dbclk_div_en_l; /* ADDRESS OFFSET: 0x0040 */ + u32 dbclk_div_en_h; /* ADDRESS OFFSET: 0x0044 */ + u32 dbclk_div_con; /* ADDRESS OFFSET: 0x0048 */ + u32 reserved004c; /* ADDRESS OFFSET: 0x004c */ + u32 int_status; /* ADDRESS OFFSET: 0x0050 */ + u32 reserved0054; /* ADDRESS OFFSET: 0x0054 */ + u32 int_rawstatus; /* ADDRESS OFFSET: 0x0058 */ + u32 reserved005c; /* ADDRESS OFFSET: 0x005c */ + u32 port_eoi_l; /* ADDRESS OFFSET: 0x0060 */ + u32 port_eoi_h; /* ADDRESS OFFSET: 0x0064 */ + u32 reserved0068[2]; /* ADDRESS OFFSET: 0x0068 */ + u32 ext_port; /* ADDRESS OFFSET: 0x0070 */ + u32 reserved0074; /* ADDRESS OFFSET: 0x0074 */ + u32 ver_id; /* ADDRESS OFFSET: 0x0078 */ +}; + +check_member(rockchip_gpio_regs, ver_id, 0x0078); +#endif enum gpio_pu_pd { GPIO_PULL_NORMAL = 0, diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c index 98a79b5f4d..e2653be058 100644 --- a/drivers/gpio/rk_gpio.c +++ b/drivers/gpio/rk_gpio.c @@ -2,12 +2,15 @@ /* * (C) Copyright 2015 Google, Inc * - * (C) Copyright 2008-2014 Rockchip Electronics + * (C) Copyright 2008-2023 Rockchip Electronics * Peter, Software Engineering, <superpeter.cai@gmail.com>. + * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>. */ #include <common.h> #include <dm.h> +#include <dm/of_access.h> +#include <dm/device_compat.h> #include <syscon.h> #include <linux/errno.h> #include <asm/gpio.h> @@ -23,6 +26,35 @@ enum { #define OFFSET_TO_BIT(bit) (1UL << (bit)) +/* + * Newer Rockchip devices have additional registers that must be + * accounted for. + */ +#if defined(CONFIG_ROCKCHIP_RK3568) +#define GPIO_VER 2 +#define REG_L(R) (R##_l) +#define REG_H(R) (R##_h) +#define READ_REG(REG) ((readl(REG_L(REG)) & 0xFFFF) | \ + ((readl(REG_H(REG)) & 0xFFFF) << 16)) +#define WRITE_REG(REG, VAL) \ +{\ + writel(((VAL) & 0xFFFF) | 0xFFFF0000, REG_L(REG)); \ + writel((((VAL) & 0xFFFF0000) >> 16) | 0xFFFF0000, REG_H(REG));\ +} +#define CLRBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) & ~(MASK)) +#define SETBITS_LE32(REG, MASK) WRITE_REG(REG, READ_REG(REG) | (MASK)) +#define CLRSETBITS_LE32(REG, MASK, VAL) WRITE_REG(REG, \ + (READ_REG(REG) & ~(MASK)) | (VAL)) + +#else +#define GPIO_VER 1 +#define READ_REG(REG) readl(REG) +#define WRITE_REG(REG, VAL) writel(VAL, REG) +#define CLRBITS_LE32(REG, MASK) clrbits_le32(REG, MASK) +#define SETBITS_LE32(REG, MASK) setbits_le32(REG, MASK) +#define CLRSETBITS_LE32(REG, MASK, VAL) clrsetbits_le32(REG, MASK, VAL) +#endif + struct rockchip_gpio_priv { struct rockchip_gpio_regs *regs; struct udevice *pinctrl; @@ -35,7 +68,7 @@ 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; - clrbits_le32(®s->swport_ddr, OFFSET_TO_BIT(offset)); + CLRBITS_LE32(®s->swport_ddr, OFFSET_TO_BIT(offset)); return 0; } @@ -47,8 +80,8 @@ static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset, struct rockchip_gpio_regs *regs = priv->regs; int mask = OFFSET_TO_BIT(offset); - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); - setbits_le32(®s->swport_ddr, mask); + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); + SETBITS_LE32(®s->swport_ddr, mask); return 0; } @@ -68,7 +101,7 @@ static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, struct rockchip_gpio_regs *regs = priv->regs; int mask = OFFSET_TO_BIT(offset); - clrsetbits_le32(®s->swport_dr, mask, value ? mask : 0); + CLRSETBITS_LE32(®s->swport_dr, mask, value ? mask : 0); return 0; } @@ -86,14 +119,14 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); if (ret) return ret; - is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); + is_output = READ_REG(®s->swport_ddr) & OFFSET_TO_BIT(offset); return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; #endif } /* Simple SPL interface to GPIOs */ -#ifdef CONFIG_SPL_BUILD +#if defined(CONFIG_SPL_BUILD) && (GPIO_VER == 1) enum { PULL_NONE_1V8 = 0, @@ -143,7 +176,7 @@ 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; + char *end = NULL; int ret; priv->regs = dev_read_addr_ptr(dev); diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile index 9884355473..90461ae881 100644 --- a/drivers/pinctrl/rockchip/Makefile +++ b/drivers/pinctrl/rockchip/Makefile @@ -14,5 +14,6 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c new file mode 100644 index 0000000000..dce1c1e7ee --- /dev/null +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c @@ -0,0 +1,453 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2020 Rockchip Electronics Co., Ltd + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <regmap.h> +#include <syscon.h> + +#include "pinctrl-rockchip.h" + +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { + /* CAN0 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)), + /* CAN0 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)), + /* CAN1 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)), + /* CAN1 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)), + /* CAN2 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)), + /* CAN2 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)), + /* EDPDP_HPDIN IO mux selection M0 */ + MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)), + /* EDPDP_HPDIN IO mux selection M1 */ + MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)), + /* GMAC1 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)), + /* GMAC1 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)), + /* HDMITX IO mux selection M0 */ + MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)), + /* HDMITX IO mux selection M1 */ + MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)), + /* I2C2 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)), + /* I2C2 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)), + /* I2C3 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)), + /* I2C3 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)), + /* I2C4 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)), + /* I2C4 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)), + /* I2C5 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)), + /* I2C5 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)), + /* PWM4 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)), + /* PWM4 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)), + /* PWM5 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)), + /* PWM5 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)), + /* PWM6 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)), + /* PWM6 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)), + /* PWM7 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)), + /* PWM7 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)), + /* PWM8 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)), + /* PWM8 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)), + /* PWM9 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)), + /* PWM9 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)), + /* PWM10 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)), + /* PWM10 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)), + /* PWM11 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)), + /* PWM11 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)), + /* PWM12 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)), + /* PWM12 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)), + /* PWM13 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)), + /* PWM13 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)), + /* PWM14 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)), + /* PWM14 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)), + /* PWM15 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)), + /* PWM15 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)), + /* SDMMC2 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)), + /* SDMMC2 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)), + /* SPI0 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)), + /* SPI0 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)), + /* SPI1 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)), + /* SPI1 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)), + /* SPI2 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)), + /* SPI2 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)), + /* SPI3 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)), + /* SPI3 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)), + /* UART1 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)), + /* UART1 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)), + /* UART2 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)), + /* UART2 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)), + /* UART3 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)), + /* UART3 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)), + /* UART4 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)), + /* UART4 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)), + /* UART5 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)), + /* UART5 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)), + /* UART6 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)), + /* UART6 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)), + /* UART7 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)), + /* UART7 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)), + /* UART7 IO mux selection M2 */ + MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)), + /* UART8 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)), + /* UART8 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)), + /* UART9 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)), + /* UART9 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)), + /* UART9 IO mux selection M2 */ + MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)), + /* I2S1 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)), + /* I2S1 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)), + /* I2S1 IO mux selection M2 */ + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)), + /* I2S2 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)), + /* I2S2 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)), + /* I2S3 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)), + /* I2S3 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)), + /* PDM IO mux selection M0 */ + MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)), + /* PDM IO mux selection M1 */ + MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)), + /* PCIE20 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)), + /* PCIE20 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)), + /* PCIE20 IO mux selection M2 */ + MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)), + /* PCIE30X1 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)), + /* PCIE30X1 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)), + /* PCIE30X1 IO mux selection M2 */ + MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)), + /* PCIE30X2 IO mux selection M0 */ + MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)), + /* PCIE30X2 IO mux selection M1 */ + MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)), + /* PCIE30X2 IO mux selection M2 */ + MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)), +}; + +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + int iomux_num = (pin / 8); + struct regmap *regmap; + int reg, ret, mask; + u8 bit; + u32 data; + + debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); + + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + regmap = priv->regmap_pmu; + else + regmap = priv->regmap_base; + + reg = bank->iomux[iomux_num].offset; + if ((pin % 8) >= 4) + reg += 0x4; + bit = (pin % 4) * 4; + mask = 0xf; + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + ret = regmap_write(regmap, reg, data); + + return ret; +} + +#define RK3568_PULL_PMU_OFFSET 0x20 +#define RK3568_PULL_GRF_OFFSET 0x80 +#define RK3568_PULL_BITS_PER_PIN 2 +#define RK3568_PULL_PINS_PER_REG 8 +#define RK3568_PULL_BANK_STRIDE 0x10 + +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl_priv *info = bank->priv; + + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_PULL_PMU_OFFSET; + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; + } else { + *regmap = info->regmap_base; + *reg = RK3568_PULL_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; + } + + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); + *bit *= RK3568_PULL_BITS_PER_PIN; +} + +#define RK3568_DRV_PMU_OFFSET 0x70 +#define RK3568_DRV_GRF_OFFSET 0x200 +#define RK3568_DRV_BITS_PER_PIN 8 +#define RK3568_DRV_PINS_PER_REG 2 +#define RK3568_DRV_BANK_STRIDE 0x40 + +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl_priv *info = bank->priv; + + /* The first 32 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_DRV_PMU_OFFSET; + } else { + *regmap = info->regmap_base; + *reg = RK3568_DRV_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; + } + + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); + *bit *= RK3568_DRV_BITS_PER_PIN; +} + +#define RK3568_SCHMITT_BITS_PER_PIN 2 +#define RK3568_SCHMITT_PINS_PER_REG 8 +#define RK3568_SCHMITT_BANK_STRIDE 0x10 +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 + +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl_priv *info = bank->priv; + + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; + } else { + *regmap = info->regmap_base; + *reg = RK3568_SCHMITT_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; + } + + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; + *bit *= RK3568_SCHMITT_BITS_PER_PIN; + + return 0; +} + +static int rk3568_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit, type; + u32 data; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + return -EOPNOTSUPP; + + rk3568_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); + type = bank->pull_type[pin_num / 8]; + ret = rockchip_translate_pull_value(type, pull); + if (ret < 0) { + debug("unsupported pull setting %d\n", pull); + return ret; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + + data |= (ret << bit); + ret = regmap_write(regmap, reg, data); + + return ret; +} + +static int rk3568_set_drive(struct rockchip_pin_bank *bank, + int pin_num, int strength) +{ + struct regmap *regmap; + int reg; + u32 data; + u8 bit; + int drv = (1 << (strength + 1)) - 1; + int ret = 0; + + rk3568_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (drv << bit); + + ret = regmap_write(regmap, reg, data); + if (ret) + return ret; + + if (bank->bank_num == 1 && pin_num == 21) + reg = 0x0840; + else if (bank->bank_num == 2 && pin_num == 2) + reg = 0x0844; + else if (bank->bank_num == 2 && pin_num == 8) + reg = 0x0848; + else if (bank->bank_num == 3 && pin_num == 0) + reg = 0x084c; + else if (bank->bank_num == 3 && pin_num == 6) + reg = 0x0850; + else if (bank->bank_num == 4 && pin_num == 0) + reg = 0x0854; + else + return 0; + + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16; + data |= drv; + + return regmap_write(regmap, reg, data); +} + +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank, + int pin_num, int enable) +{ + struct regmap *regmap; + int reg; + u32 data; + u8 bit; + + rk3568_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); + data |= (enable << bit); + + return regmap_write(regmap, reg, data); +} + +static struct rockchip_pin_bank rk3568_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), +}; + +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = { + .pin_banks = rk3568_pin_banks, + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), + .nr_pins = 160, + .grf_mux_offset = 0x0, + .pmu_mux_offset = 0x0, + .iomux_routes = rk3568_mux_route_data, + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), + .set_mux = rk3568_set_mux, + .set_pull = rk3568_set_pull, + .set_drive = rk3568_set_drive, + .set_schmitt = rk3568_set_schmitt, +}; + +static const struct udevice_id rk3568_pinctrl_ids[] = { + { + .compatible = "rockchip,rk3568-pinctrl", + .data = (ulong)&rk3568_pin_ctrl + }, + { } +}; + +U_BOOT_DRIVER(pinctrl_rk3568) = { + .name = "rockchip_rk3568_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = rk3568_pinctrl_ids, + .priv_auto = sizeof(struct rockchip_pinctrl_priv), + .ops = &rockchip_pinctrl_ops, +#if !IS_ENABLED(CONFIG_OF_PLATDATA) + .bind = dm_scan_fdt_dev, +#endif + .probe = rockchip_pinctrl_probe, +}; diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c index d9d61fdb72..1481c1e51c 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c @@ -433,7 +433,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, int prop_len, param; const u32 *data; ofnode node; -#ifdef CONFIG_OF_LIVE +#if CONFIG_IS_ENABLED(OF_LIVE) const struct device_node *np; struct property *pp; #else @@ -473,7 +473,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, node = ofnode_get_by_phandle(conf); if (!ofnode_valid(node)) return -ENODEV; -#ifdef CONFIG_OF_LIVE +#if CONFIG_IS_ENABLED(OF_LIVE) np = ofnode_to_np(node); for (pp = np->properties; pp; pp = pp->next) { prop_name = pp->name; @@ -548,13 +548,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d /* preset iomux offset value, set new start value */ if (iom->offset >= 0) { - if (iom->type & IOMUX_SOURCE_PMU) + if ((iom->type & IOMUX_SOURCE_PMU) || \ + (iom->type & IOMUX_L_SOURCE_PMU)) pmu_offs = iom->offset; else grf_offs = iom->offset; } else { /* set current iomux offset */ - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? - pmu_offs : grf_offs; + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || + (iom->type & IOMUX_L_SOURCE_PMU)) ? + pmu_offs : grf_offs; } /* preset drv offset value, set new start value */