This patch series and adds support for pin controller found on rk3308b.
According to rk3308b TRM, this pinctrl much the same as rk3308's,
but with additional iomux routes and 3bit iomuxes selected via
gpio##_sel_src_ctrl registers.
Downstream kernel [1] managed this SoC's with rk3308b_soc_data_init,
wich picked configuration based on cpuid. Upstream pinctrl patches
droped soc init function.
The function rk3308b_soc_sel_src_init sets up gpio##_sel_src_ctrl
registers, making SoC to use 3bit iomuxes over some 2bit old ones.
These patches have been tested on Radxa's ROCK Pi S, one based on rk3308
and the other on rk3308b (from the latest batches). For the new boards it
fixes broken spi1 clk.
Similar effort [2] was made several years ago, but without keeping base
rk3308 SoC pinctrl support.
Based on feedback from Luca, Heiko and Jonas, the v2 series droped dt
binding in the favor of runtime SoC detection, so iomux_recalced and
iomux_routes updated for the new SoC's and patch 1 delays recalced_mask
and route_mask init.
[1] https://github.com/radxa/kernel/blob/stable-4.4-rockpis/drivers/pinctrl/pinctrl-rockchip.c#L4388
[2] https://lore.kernel.org/linux-rockchip/[email protected]/
v1 Link: https://lore.kernel.org/all/[email protected]/
v2 Link: https://lore.kernel.org/all/[email protected]/
Changes in v3:
- Witespace cleanup
- Add Luca's r-b tag
- Rebase onto linux-pinctrl for-next branch
Changes in v2:
- Drop routes fixup patch, already applied
- Drop dt binding patch
- Add new patch to delay recalced_mask and route_mask init
- Rework last patch from dt to runtime setup with rk3308_soc_data_update
Dmitry Yashin (2):
pinctrl: rockchip: delay recalced_mask and route_mask init
pinctrl: rockchip: add rk3308b SoC support
drivers/pinctrl/pinctrl-rockchip.c | 286 +++++++++++++++++++++++++++--
drivers/pinctrl/pinctrl-rockchip.h | 1 +
2 files changed, 267 insertions(+), 20 deletions(-)
base-commit: 32335efff386d04961b178d4c6b7d1ccbafb729f
--
2.39.2
Add pinctrl support for rk3308b. This pin controller much the same as
rk3308's, but with additional iomux routes and 3bit iomuxes selected
via gpio##_sel_src_ctrl registers. Set them up in the function
rk3308b_soc_sel_src_init to use new 3bit iomuxes over some 2bit old
ones and update iomux_recalced and iomux_routes for the new SoC's.
Fixes: 1f3e25a06883 ("pinctrl: rockchip: fix RK3308 pinmux bits")
Signed-off-by: Dmitry Yashin <[email protected]>
Reviewed-by: Luca Ceresoli <[email protected]>
---
drivers/pinctrl/pinctrl-rockchip.c | 234 +++++++++++++++++++++++++++++
drivers/pinctrl/pinctrl-rockchip.h | 1 +
2 files changed, 235 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index b252d1454ce0..b6a0eadfeed2 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -632,6 +632,115 @@ static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
},
};
+static struct rockchip_mux_recalced_data rk3308b_mux_recalced_data[] = {
+ {
+ /* gpio1b6_sel */
+ .num = 1,
+ .pin = 14,
+ .reg = 0x28,
+ .bit = 12,
+ .mask = 0xf
+ }, {
+ /* gpio1b7_sel */
+ .num = 1,
+ .pin = 15,
+ .reg = 0x2c,
+ .bit = 0,
+ .mask = 0x3
+ }, {
+ /* gpio1c2_sel */
+ .num = 1,
+ .pin = 18,
+ .reg = 0x30,
+ .bit = 4,
+ .mask = 0xf
+ }, {
+ /* gpio1c3_sel */
+ .num = 1,
+ .pin = 19,
+ .reg = 0x30,
+ .bit = 8,
+ .mask = 0xf
+ }, {
+ /* gpio1c4_sel */
+ .num = 1,
+ .pin = 20,
+ .reg = 0x30,
+ .bit = 12,
+ .mask = 0xf
+ }, {
+ /* gpio1c5_sel */
+ .num = 1,
+ .pin = 21,
+ .reg = 0x34,
+ .bit = 0,
+ .mask = 0xf
+ }, {
+ /* gpio1c6_sel */
+ .num = 1,
+ .pin = 22,
+ .reg = 0x34,
+ .bit = 4,
+ .mask = 0xf
+ }, {
+ /* gpio1c7_sel */
+ .num = 1,
+ .pin = 23,
+ .reg = 0x34,
+ .bit = 8,
+ .mask = 0xf
+ }, {
+ /* gpio2a2_sel_plus */
+ .num = 2,
+ .pin = 2,
+ .reg = 0x608,
+ .bit = 0,
+ .mask = 0x7
+ }, {
+ /* gpio2a3_sel_plus */
+ .num = 2,
+ .pin = 3,
+ .reg = 0x608,
+ .bit = 4,
+ .mask = 0x7
+ }, {
+ /* gpio2c0_sel_plus */
+ .num = 2,
+ .pin = 16,
+ .reg = 0x610,
+ .bit = 8,
+ .mask = 0x7
+ }, {
+ /* gpio3b2_sel_plus */
+ .num = 3,
+ .pin = 10,
+ .reg = 0x610,
+ .bit = 0,
+ .mask = 0x7
+ }, {
+ /* gpio3b3_sel_plus */
+ .num = 3,
+ .pin = 11,
+ .reg = 0x610,
+ .bit = 4,
+ .mask = 0x7
+ }, {
+ /* gpio3b4_sel */
+ .num = 3,
+ .pin = 12,
+ .reg = 0x68,
+ .bit = 8,
+ .mask = 0xf
+ }, {
+ /* gpio3b5_sel */
+ .num = 3,
+ .pin = 13,
+ .reg = 0x68,
+ .bit = 12,
+ .mask = 0xf
+ },
+};
+
static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = {
{
.num = 2,
@@ -882,6 +991,35 @@ static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */
};
+static struct rockchip_mux_route_data rk3308b_mux_route_data[] = {
+ RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */
+ RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */
+ RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */
+ RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */
+ RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */
+ RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */
+ RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */
+ RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */
+ RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */
+ RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */
+ RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */
+ RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */
+ RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */
+ RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */
+ RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, BIT(16 + 9)), /* spi1_miso */
+ RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, BIT(16 + 9) | BIT(9)), /* spi1_miso_m1 */
+ RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, BIT(16 + 10) | BIT(16 + 11)), /* owire_m0 */
+ RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* owire_m1 */
+ RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* owire_m2 */
+ RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, BIT(16 + 12) | BIT(16 + 13)), /* can_rxd_m0 */
+ RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* can_rxd_m1 */
+ RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* can_rxd_m2 */
+ RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, BIT(16 + 14)), /* mac_rxd0_m0 */
+ RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, BIT(16 + 14) | BIT(14)), /* mac_rxd0_m1 */
+ RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, BIT(16 + 15)), /* uart3_rx */
+ RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, BIT(16 + 15) | BIT(15)), /* uart3_rx_m1 */
+};
+
static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
RK_MUXROUTE_SAME(1, RK_PA1, 2, 0x50, BIT(16) | BIT(16 + 1)), /* uart2dbg_rxm0 */
RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x50, BIT(16) | BIT(16 + 1) | BIT(0)), /* uart2dbg_rxm1 */
@@ -2420,6 +2558,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
case RK3188:
case RK3288:
case RK3308:
+ case RK3308B:
case RK3368:
case RK3399:
case RK3568:
@@ -2478,6 +2617,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
case RK3188:
case RK3288:
case RK3308:
+ case RK3308B:
case RK3368:
case RK3399:
case RK3568:
@@ -2740,6 +2880,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
case RK3188:
case RK3288:
case RK3308:
+ case RK3308B:
case RK3368:
case RK3399:
case RK3568:
@@ -3348,6 +3489,93 @@ static int __maybe_unused rockchip_pinctrl_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend,
rockchip_pinctrl_resume);
+#define RK3308B_GRF_SOC_CON13 0x608
+#define RK3308B_GRF_SOC_CON15 0x610
+
+/* RK3308B_GRF_SOC_CON13 */
+#define RK3308B_GRF_I2C3_IOFUNC_SRC_CTRL (BIT(16 + 10) | BIT(10))
+#define RK3308B_GRF_GPIO2A3_SEL_SRC_CTRL (BIT(16 + 7) | BIT(7))
+#define RK3308B_GRF_GPIO2A2_SEL_SRC_CTRL (BIT(16 + 3) | BIT(3))
+
+/* RK3308B_GRF_SOC_CON15 */
+#define RK3308B_GRF_GPIO2C0_SEL_SRC_CTRL (BIT(16 + 11) | BIT(11))
+#define RK3308B_GRF_GPIO3B3_SEL_SRC_CTRL (BIT(16 + 7) | BIT(7))
+#define RK3308B_GRF_GPIO3B2_SEL_SRC_CTRL (BIT(16 + 3) | BIT(3))
+
+/*
+ * RK3308B has 3bit gpio##_sel_plus iomuxes over some 2bit old ones.
+ * Put them in use by initializing gpio##_sel_src_ctrl registers.
+ */
+static int rk3308b_soc_sel_src_init(struct rockchip_pinctrl *info)
+{
+ int ret;
+
+ ret = regmap_write(info->regmap_base, RK3308B_GRF_SOC_CON13,
+ RK3308B_GRF_I2C3_IOFUNC_SRC_CTRL |
+ RK3308B_GRF_GPIO2A3_SEL_SRC_CTRL |
+ RK3308B_GRF_GPIO2A2_SEL_SRC_CTRL);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(info->regmap_base, RK3308B_GRF_SOC_CON15,
+ RK3308B_GRF_GPIO2C0_SEL_SRC_CTRL |
+ RK3308B_GRF_GPIO3B3_SEL_SRC_CTRL |
+ RK3308B_GRF_GPIO3B2_SEL_SRC_CTRL);
+
+ return ret;
+};
+
+#define RK3308_GRF_CHIP_ID 0x800
+
+static int rk3308_soc_update_type(struct rockchip_pinctrl *info)
+{
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
+ unsigned int chip_id;
+ int ret;
+
+ ret = regmap_read(info->regmap_base, RK3308_GRF_CHIP_ID, &chip_id);
+ if (ret)
+ return ret;
+
+ switch (chip_id) {
+ /* From RK3308 TRM: "Errata: The read only chip id value is 32'h0cea(32'd3306)" */
+ case 0xcea:
+ break;
+ case 0x3308:
+ case 0x3308c:
+ ctrl->type = RK3308B;
+ break;
+ default:
+ return dev_err_probe(info->dev, -EINVAL, "Unknown chip_id: 0x%x\n", chip_id);
+ }
+
+ return 0;
+}
+
+static int rk3308_soc_data_update(struct rockchip_pinctrl *info)
+{
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
+ int ret;
+
+ ret = rk3308_soc_update_type(info);
+ if (ret)
+ return ret;
+
+ if (ctrl->type == RK3308B) {
+ /* Replace iomux data for RK3308B and RK3308BS */
+ ctrl->iomux_recalced = rk3308b_mux_recalced_data;
+ ctrl->niomux_recalced = ARRAY_SIZE(rk3308b_mux_recalced_data);
+ ctrl->iomux_routes = rk3308b_mux_route_data;
+ ctrl->niomux_routes = ARRAY_SIZE(rk3308b_mux_route_data);
+
+ ret = rk3308b_soc_sel_src_init(info);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static int rockchip_pinctrl_probe(struct platform_device *pdev)
{
struct rockchip_pinctrl *info;
@@ -3413,6 +3641,12 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
return PTR_ERR(info->regmap_pmu);
}
+ if (ctrl->type == RK3308) {
+ ret = rk3308_soc_data_update(info);
+ if (ret)
+ return ret;
+ }
+
iomux_recalced_routes_init(info);
ret = rockchip_pinctrl_register(pdev, info);
diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
index 4759f336941e..3af5b1bd626b 100644
--- a/drivers/pinctrl/pinctrl-rockchip.h
+++ b/drivers/pinctrl/pinctrl-rockchip.h
@@ -193,6 +193,7 @@ enum rockchip_pinctrl_type {
RK3188,
RK3288,
RK3308,
+ RK3308B,
RK3368,
RK3399,
RK3568,
--
2.39.2
For some SoC's like rk3308 additional runtime setup needed, so delay
recalced_mask and route_mask init.
Signed-off-by: Dmitry Yashin <[email protected]>
---
drivers/pinctrl/pinctrl-rockchip.c | 52 ++++++++++++++++++------------
1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index cc647db76927..b252d1454ce0 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -3170,6 +3170,36 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
return 0;
}
+static void iomux_recalced_routes_init(struct rockchip_pinctrl *info)
+{
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
+ struct rockchip_pin_bank *bank = ctrl->pin_banks;
+ int i, j;
+
+ for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+
+ /* calculate the per-bank recalced_mask */
+ for (j = 0; j < ctrl->niomux_recalced; j++) {
+ int pin = 0;
+
+ if (ctrl->iomux_recalced[j].num == bank->bank_num) {
+ pin = ctrl->iomux_recalced[j].pin;
+ bank->recalced_mask |= BIT(pin);
+ }
+ }
+
+ /* calculate the per-bank route_mask */
+ for (j = 0; j < ctrl->niomux_routes; j++) {
+ int pin = 0;
+
+ if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
+ pin = ctrl->iomux_routes[j].pin;
+ bank->route_mask |= BIT(pin);
+ }
+ }
+ }
+}
+
static const struct of_device_id rockchip_pinctrl_dt_match[];
/* retrieve the soc specific data */
@@ -3265,26 +3295,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
bank_pins += 8;
}
-
- /* calculate the per-bank recalced_mask */
- for (j = 0; j < ctrl->niomux_recalced; j++) {
- int pin = 0;
-
- if (ctrl->iomux_recalced[j].num == bank->bank_num) {
- pin = ctrl->iomux_recalced[j].pin;
- bank->recalced_mask |= BIT(pin);
- }
- }
-
- /* calculate the per-bank route_mask */
- for (j = 0; j < ctrl->niomux_routes; j++) {
- int pin = 0;
-
- if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
- pin = ctrl->iomux_routes[j].pin;
- bank->route_mask |= BIT(pin);
- }
- }
}
return ctrl;
@@ -3403,6 +3413,8 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
return PTR_ERR(info->regmap_pmu);
}
+ iomux_recalced_routes_init(info);
+
ret = rockchip_pinctrl_register(pdev, info);
if (ret)
return ret;
--
2.39.2
On Tue, Jun 04, 2024 at 07:10:19PM +0500, Dmitry Yashin wrote:
> For some SoC's like rk3308 additional runtime setup needed, so delay
> recalced_mask and route_mask init.
>
> Signed-off-by: Dmitry Yashin <[email protected]>
This sounds like it needs a Fixes tag. Should it be backported to
stable?
I understand that you only know that rk3308 is affected, and probably
you worry that other devices are as well? Just do your best on trying
to figure out which is the first commit where this bug started to
matter. Any information is better than no information.
The commit message should say what the bug looks like to the user. Why
would a user want this patch? I can probably figure it out from reading
the code, but I shouldn't have to.
regards,
dan carpenter
On Tue, Jun 04, 2024 at 07:10:20PM +0500, Dmitry Yashin wrote:
> Add pinctrl support for rk3308b. This pin controller much the same as
> rk3308's, but with additional iomux routes and 3bit iomuxes selected
> via gpio##_sel_src_ctrl registers. Set them up in the function
> rk3308b_soc_sel_src_init to use new 3bit iomuxes over some 2bit old
> ones and update iomux_recalced and iomux_routes for the new SoC's.
>
> Fixes: 1f3e25a06883 ("pinctrl: rockchip: fix RK3308 pinmux bits")
Why does this one have a Fixes tag? Isn't this new hardware support?
Possibly patch 1/2 was not actually a fix but just preparation for this
patch?
regards,
dan carpenter
> Signed-off-by: Dmitry Yashin <[email protected]>
> Reviewed-by: Luca Ceresoli <[email protected]>
Hi Dan,
On 6/5/24 12:22 PM, Dan Carpenter wrote:
> On Tue, Jun 04, 2024 at 07:10:20PM +0500, Dmitry Yashin wrote:
> Why does this one have a Fixes tag? Isn't this new hardware support?
> Possibly patch 1/2 was not actually a fix but just preparation for this
> patch?
>
> regards,
> dan carpenter
Initial pinctrl support for rk3308 included registers for rk3308b variant, which didn't work well with some pins of the first SoC and these reg's were fixed in the patch mentioned in this tag. So I added Fixes tag as this patch brings back proper setup for rk3308b and 1/2 indeed is the preparation. Thank you for taking your time on it. Perhaps I should describe such moments better next time.
--
Thanks,
Dmitry
Hi Dan,
On 6/5/24 12:22 PM, Dan Carpenter wrote:
> On Tue, Jun 04, 2024 at 07:10:20PM +0500, Dmitry Yashin wrote:
> Why does this one have a Fixes tag? Isn't this new hardware support?
> Possibly patch 1/2 was not actually a fix but just preparation for this
> patch?
>
> regards,
> dan carpenter
Initial pinctrl support for rk3308 included registers for rk3308b variant,
which didn't work well with some pins of the first SoC and these reg's
were fixed in the patch mentioned in the tag. So I added Fixes tag as this
patch brings back proper setup for rk3308b and 1/2 indeed
is the preparation.
Thank you for taking your time on it. Perhaps I should describe such
moments better next time.
(resend without broken new line sorry)
--
Thanks,
Dmitry