[PATCH 03/17] pinctrl: renesas: rzg2l: Add SD channel POC support for RZ/G3L

From: Biju

Date: Sat May 30 2026 - 12:13:00 EST


From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>

Add power-on control (POC) support for SD channels 1 and 2 on the RZ/G3L
SoC (r9a08g046).

Introduce PIN_CFG_IO_VMC_SD2 capability flag (bit 22) and SD_CH2_POC
register offset (0x3024). Extend rzg2l_caps_to_pwr_reg() to return
SD_CH2_POC when PIN_CFG_IO_VMC_SD2 is set.

Replace RZG3L_MPXED_PIN_FUNCS() with RZG2L_MPXED_COMMON_PIN_FUNCS() for
port PG and PH pins, dropping PIN_CFG_SOFT_PS which is inappropriate for
SD pins, and annotate them with PIN_CFG_IO_VMC_SD1 and PIN_CFG_IO_VMC_SD2
respectively.

Annotate all RZ/G3L SD0 dedicated pins (CLK, CMD, RST#, DS, DAT0–DAT7)
with PIN_CFG_IO_VMC_SD0 so that power-source register lookups work
correctly for those pins.

Add sd_ch2 field to rzg2l_register_offsets and rzg2l_pinctrl_reg_cache to
save and restore the SD_CH2_POC register across suspend/resume cycles.

Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 74 +++++++++++++++++--------
1 file changed, 50 insertions(+), 24 deletions(-)

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 83c61dcb24b1..b1d4b2b9e176 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -69,6 +69,7 @@
#define PIN_CFG_PVDD1833_OTH_AWO_POC BIT(19) /* known on RZ/G3L only */
#define PIN_CFG_PVDD1833_OTH_ISO_POC BIT(20) /* known on RZ/G3L only */
#define PIN_CFG_WDTOVF_N_POC BIT(21) /* known on RZ/G3L only */
+#define PIN_CFG_IO_VMC_SD2 BIT(22) /* known on RZ/G3L only */

#define RZG2L_SINGLE_PIN BIT_ULL(63) /* Dedicated pin */
#define RZG2L_VARIABLE_CFG BIT_ULL(62) /* Variable cfg for port pins */
@@ -258,6 +259,7 @@ static const struct pin_config_item renesas_rzv2h_conf_items[] = {
* @oen: OEN register offset
* @qspi: QSPI register offset
* @other_poc: OTHER_POC register offset
+ * @sd_ch2: SD_CH2_POC register offset
*/
struct rzg2l_register_offsets {
u16 pwpr;
@@ -266,6 +268,7 @@ struct rzg2l_register_offsets {
u16 oen;
u16 qspi;
u16 other_poc;
+ u16 sd_ch2;
};

/**
@@ -372,6 +375,7 @@ struct rzg2l_pinctrl_pin_settings {
* @oen: Output Enable register cache
* @other_poc: OTHER_POC register cache
* @qspi: QSPI registers cache
+ * @sd_ch2: SD_CH2_POC registers cache
*/
struct rzg2l_pinctrl_reg_cache {
u8 *p;
@@ -390,6 +394,7 @@ struct rzg2l_pinctrl_reg_cache {
u8 oen;
u8 other_poc;
u8 qspi;
+ u8 sd_ch2;
};

struct rzg2l_pinctrl {
@@ -474,20 +479,32 @@ static const u64 r9a08g046_variable_pin_cfg[] = {
RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PE, 5, RZG3L_MPXED_ETH_PIN_FUNCS(ETH1)),
RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PE, 6, RZG3L_MPXED_ETH_PIN_FUNCS(ETH1)),
RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PE, 7, RZG3L_MPXED_ETH_PIN_FUNCS(ETH1)),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 0, RZG3L_MPXED_PIN_FUNCS(B)),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 1, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 2, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 3, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 4, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 5, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 0, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IO_VMC_SD1),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 1, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD1),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 2, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD1),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 3, RZG2L_MPXED_COMMON_PIN_FUNCS(B) | PIN_CFG_IEN |
+ PIN_CFG_IO_VMC_SD1),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 4, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD1),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 5, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD1),
RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 6, RZG3L_MPXED_PIN_FUNCS_POC(B, ISO)),
RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PG, 7, RZG3L_MPXED_PIN_FUNCS_POC(B, ISO)),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 0, RZG3L_MPXED_PIN_FUNCS(B)),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 1, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 2, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 3, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 4, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
- RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 5, RZG3L_MPXED_PIN_FUNCS(B) | PIN_CFG_IEN),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 0, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IO_VMC_SD2),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 1, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD2),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 2, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD2),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 3, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD2),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 4, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD2),
+ RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PH, 5, RZG2L_MPXED_COMMON_PIN_FUNCS(B) |
+ PIN_CFG_IEN | PIN_CFG_IO_VMC_SD2),
RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PJ, 0, RZG3L_MPXED_PIN_FUNCS(A) | PIN_CFG_IEN),
RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PJ, 1, RZG3L_MPXED_PIN_FUNCS(A)),
RZG2L_VARIABLE_PIN_CFG_PACK(RZG3L_PJ, 2, RZG3L_MPXED_PIN_FUNCS(A)),
@@ -1053,6 +1070,8 @@ static int rzg2l_caps_to_pwr_reg(const struct rzg2l_register_offsets *regs,
return SD_CH(regs->sd_ch, 0);
if (caps & PIN_CFG_IO_VMC_SD1)
return SD_CH(regs->sd_ch, 1);
+ if (caps & PIN_CFG_IO_VMC_SD2)
+ return regs->sd_ch2;
if (caps & PIN_CFG_IO_VMC_ETH0)
return ETH_POC(regs->eth_poc, 0);
if (caps & PIN_CFG_IO_VMC_ETH1)
@@ -2677,28 +2696,28 @@ static const struct rzg2l_dedicated_configs rzg3l_dedicated_pins[] = {
(PIN_CFG_IOLH_A | PIN_CFG_PUPD | PIN_CFG_PVDD1833_OTH_AWO_POC)) },
{ "SCIF0_TXD", RZG2L_SINGLE_PIN_PACK(0x6, 1,
(PIN_CFG_IOLH_A | PIN_CFG_PUPD | PIN_CFG_PVDD1833_OTH_AWO_POC)) },
- { "SD0_CLK", RZG2L_SINGLE_PIN_PACK(0x9, 0, PIN_CFG_IOLH_B) },
+ { "SD0_CLK", RZG2L_SINGLE_PIN_PACK(0x9, 0, PIN_CFG_IOLH_B | PIN_CFG_IO_VMC_SD0) },
{ "SD0_CMD", RZG2L_SINGLE_PIN_PACK(0x9, 1,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
- { "SD0_RST#", RZG2L_SINGLE_PIN_PACK(0x9, 2, PIN_CFG_IOLH_B) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
+ { "SD0_RST#", RZG2L_SINGLE_PIN_PACK(0x9, 2, PIN_CFG_IOLH_B | PIN_CFG_IO_VMC_SD0) },
{ "SD0_DS", RZG2L_SINGLE_PIN_PACK(0x9, 5,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_DAT0", RZG2L_SINGLE_PIN_PACK(0x0a, 0,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_DAT1", RZG2L_SINGLE_PIN_PACK(0x0a, 1,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_DAT2", RZG2L_SINGLE_PIN_PACK(0x0a, 2,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_DAT3", RZG2L_SINGLE_PIN_PACK(0x0a, 3,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_DAT4", RZG2L_SINGLE_PIN_PACK(0x0a, 4,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_DAT5", RZG2L_SINGLE_PIN_PACK(0x0a, 5,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_DAT6", RZG2L_SINGLE_PIN_PACK(0x0a, 6,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_DAT7", RZG2L_SINGLE_PIN_PACK(0x0a, 7,
- (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD)) },
+ (PIN_CFG_IOLH_B | PIN_CFG_IEN | PIN_CFG_PUPD | PIN_CFG_IO_VMC_SD0)) },
};

static const u32 r9a08g046_clone_channel_data[] = {
@@ -3672,6 +3691,9 @@ static int rzg2l_pinctrl_suspend_noirq(struct device *dev)
cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i));
}

+ if (regs->sd_ch2)
+ cache->sd_ch2 = readb(pctrl->base + regs->sd_ch2);
+
if (regs->qspi)
cache->qspi = readb(pctrl->base + regs->qspi);
cache->oen = readb(pctrl->base + pctrl->data->hwcfg->regs.oen);
@@ -3724,6 +3746,9 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev)
rzg2l_oen_write_with_pwpr(pctrl, cache->oen);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);

+ if (regs->sd_ch2)
+ writeb(cache->sd_ch2, pctrl->base + regs->sd_ch2);
+
for (u8 i = 0; i < 2; i++) {
if (regs->sd_ch)
writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i));
@@ -3794,6 +3819,7 @@ static const struct rzg2l_hwcfg rzg3l_hwcfg = {
.eth_poc = 0x3010,
.oen = 0x3018,
.other_poc = OTHER_POC,
+ .sd_ch2 = 0x3024,
},
.iolh_groupa_ua = {
/* 1v8 power source */
--
2.43.0