* [PATCH v6 1/5] pinctrl: renesas: rzg2l: Generalize the power source code
2026-09-03 11:33 [PATCH v6 0/5] pinctrl: renesas: rzg2l: Add support for RZ/G3S I3C Claudiu Beznea
@ 2026-09-03 11:33 ` Claudiu Beznea
2026-09-03 11:33 ` [PATCH v6 2/5] pinctrl: renesas: rzg2l: Drop defines present in struct rzg2l_hwcfg Claudiu Beznea
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Claudiu Beznea @ 2026-09-03 11:33 UTC (permalink / raw)
To: geert+renesas, linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj
Cc: claudiu.beznea, linux-renesas-soc, linux-gpio, devicetree,
linux-kernel, Claudiu Beznea, Wolfram Sang
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
The current functions used to get/set the pin power source check the
OTHER_POC register, which is specific to the RZ/G3L SoC only. To allow the
code to be extended for other power source functionalities (e.g. I3C on
RZ/G3S), generalize the functions used to get/set the pin power source.
For this, introduce the struct rzg2l_register_masks data structure whose
purpose is to store SoC specific register bit masks. The members of this
structure are then used in rzg2l_caps_to_pwr_reg() to retrieve the bitmask
corresponding to a SoC specific power source capability.
The conversion between HW specific power source values and SW specific
power source values is now handled through rzg2l_pwr_reg_val_to_ps() and
rzg2l_ps_to_pwr_reg_val().
Finally, to keep the code generic, the register update in
rzg2l_set_power_source() was changed to a read-modify-write approach to
cover all cases.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
Changes in v6:
- collected tags
- rebased on top of the latest next
Changes in v5:
- in function rzg2l_ps_to_pwr_reg_val() return power source register
value or negative error; due to this, in rzg2l_set_power_source()
dropped the val local variable and use ret instead; due to this,
to be able to use ret on register setup, moved the rzg2l_ps_to_pwr_reg_val()
call after rzg2l_caps_to_pwr_reg()
- dropped the tags
- collected tags
Changes in v4:
- none
Changes in v3:
- collected tags
Changes in v2:
- none
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 182 +++++++++++++++---------
1 file changed, 114 insertions(+), 68 deletions(-)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index e3e24ce917c9..40bf8f9e8f2f 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -187,6 +187,7 @@
#define PVDD_2500 2 /* I/O domain voltage 2.5V */
#define PVDD_1800 1 /* I/O domain voltage <= 1.8V */
#define PVDD_3300 0 /* I/O domain voltage >= 3.3V */
+#define PVDD_MASK 0x3
#define PWPR_B0WI BIT(7) /* Bit Write Disable */
#define PWPR_PFCWE BIT(6) /* PFC Register Write Enable */
@@ -271,6 +272,23 @@ struct rzg2l_register_offsets {
u16 other_poc;
};
+/**
+ * struct rzg2l_register_masks - Masks for different RZ/G2L pinctrl functionalities
+ * @other_poc_pvdd1833_oth_awo_poc: PVDD1833_OTH_AWO_POC mask
+ * @other_poc_pvdd1833_oth_iso_poc: PVDD1833_OTH_ISO_POC mask
+ * @other_poc_wdtovf_n_poc: WDTOVF_N_POC mask
+ */
+struct rzg2l_register_masks {
+ union {
+ /* RZ/G3L masks */
+ struct {
+ u8 other_poc_pvdd1833_oth_awo_poc;
+ u8 other_poc_pvdd1833_oth_iso_poc;
+ u8 other_poc_wdtovf_n_poc;
+ };
+ };
+};
+
/**
* enum rzg2l_iolh_index - starting indices in IOLH specific arrays
* @RZG2L_IOLH_IDX_1V8: starting index for 1V8 power source
@@ -291,6 +309,8 @@ enum rzg2l_iolh_index {
/**
* struct rzg2l_hwcfg - hardware configuration data structure
* @regs: hardware specific register offsets
+ * @masks: hardware specific masks for various functionalities available in
+ * the registers described by regs
* @iolh_groupa_ua: IOLH group A uA specific values
* @iolh_groupb_ua: IOLH group B uA specific values
* @iolh_groupc_ua: IOLH group C uA specific values
@@ -304,6 +324,7 @@ enum rzg2l_iolh_index {
*/
struct rzg2l_hwcfg {
const struct rzg2l_register_offsets regs;
+ const struct rzg2l_register_masks masks;
u16 iolh_groupa_ua[RZG2L_IOLH_IDX_MAX];
u16 iolh_groupb_ua[RZG2L_IOLH_IDX_MAX];
u16 iolh_groupc_ua[RZG2L_IOLH_IDX_MAX];
@@ -1064,29 +1085,74 @@ static void rzg2l_rmw_pin_config(struct rzg2l_pinctrl *pctrl, u32 offset,
}
static int rzg2l_caps_to_pwr_reg(const struct rzg2l_register_offsets *regs,
- u32 caps, u8 *mask)
-{
- if (caps & PIN_CFG_IO_VMC_SD0)
- 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)
- return ETH_POC(regs->eth_poc, 1);
- if (caps & PIN_CFG_IO_VMC_QSPI)
- return QSPI;
+ const struct rzg2l_register_masks *masks,
+ u32 caps, u16 *offset, u8 *mask)
+{
+ *mask = PVDD_MASK;
+
+ if (caps & PIN_CFG_IO_VMC_SD0) {
+ *offset = SD_CH(regs->sd_ch, 0);
+ return 0;
+ }
+ if (caps & PIN_CFG_IO_VMC_SD1) {
+ *offset = SD_CH(regs->sd_ch, 1);
+ return 0;
+ }
+ if (caps & PIN_CFG_IO_VMC_SD2) {
+ *offset = regs->sd_ch2;
+ return 0;
+ }
+ if (caps & PIN_CFG_IO_VMC_ETH0) {
+ *offset = ETH_POC(regs->eth_poc, 0);
+ return 0;
+ }
+ if (caps & PIN_CFG_IO_VMC_ETH1) {
+ *offset = ETH_POC(regs->eth_poc, 1);
+ return 0;
+ }
+ if (caps & PIN_CFG_IO_VMC_QSPI) {
+ *offset = regs->qspi;
+ return 0;
+ }
if (caps & PIN_CFG_OTHER_POC_MASK) {
+ *offset = regs->other_poc;
if (caps & PIN_CFG_PVDD1833_OTH_AWO_POC)
- *mask = BIT(0);
+ *mask = masks->other_poc_pvdd1833_oth_awo_poc;
else if (caps & PIN_CFG_PVDD1833_OTH_ISO_POC)
- *mask = BIT(1);
+ *mask = masks->other_poc_pvdd1833_oth_iso_poc;
else
- *mask = BIT(2);
+ *mask = masks->other_poc_wdtovf_n_poc;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int rzg2l_pwr_reg_val_to_ps(u8 val, u32 caps)
+{
+ switch (val) {
+ case PVDD_1800:
+ return 1800;
+ case PVDD_2500:
+ return 2500;
+ case PVDD_3300:
+ return 3300;
+ }
- return OTHER_POC;
+ return -EINVAL;
+}
+
+static int rzg2l_ps_to_pwr_reg_val(u32 ps, u32 caps)
+{
+ switch (ps) {
+ case 1800:
+ return PVDD_1800;
+ case 2500:
+ if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1)))
+ return -EINVAL;
+ return PVDD_2500;
+ case 3300:
+ return PVDD_3300;
}
return -EINVAL;
@@ -1096,76 +1162,51 @@ static int rzg2l_get_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps
{
const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
const struct rzg2l_register_offsets *regs = &hwcfg->regs;
- u8 val, mask;
- int pwr_reg;
+ const struct rzg2l_register_masks *masks = &hwcfg->masks;
+ u8 mask, val;
+ u16 offset;
+ int ret;
if (caps & PIN_CFG_SOFT_PS)
return pctrl->settings[pin].power_source;
- pwr_reg = rzg2l_caps_to_pwr_reg(regs, caps, &mask);
- if (pwr_reg < 0)
- return pwr_reg;
+ ret = rzg2l_caps_to_pwr_reg(regs, masks, caps, &offset, &mask);
+ if (ret)
+ return ret;
- val = readb(pctrl->base + pwr_reg);
- if (pwr_reg == OTHER_POC)
- val = field_get(mask, val);
+ val = readb(pctrl->base + offset);
- switch (val) {
- case PVDD_1800:
- return 1800;
- case PVDD_2500:
- return 2500;
- case PVDD_3300:
- return 3300;
- default:
- /* Should not happen. */
- return -EINVAL;
- }
+ return rzg2l_pwr_reg_val_to_ps(field_get(mask, val), caps);
}
static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps, u32 ps)
{
const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
const struct rzg2l_register_offsets *regs = &hwcfg->regs;
- u8 poc_val, val, mask;
- int pwr_reg;
+ const struct rzg2l_register_masks *masks = &hwcfg->masks;
+ u16 offset;
+ u8 mask;
+ int ret;
if (caps & PIN_CFG_SOFT_PS) {
pctrl->settings[pin].power_source = ps;
return 0;
}
- switch (ps) {
- case 1800:
- poc_val = PVDD_1800;
- break;
- case 2500:
- if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1)))
- return -EINVAL;
- poc_val = PVDD_2500;
- break;
- case 3300:
- poc_val = PVDD_3300;
- break;
- default:
- return -EINVAL;
- }
+ ret = rzg2l_caps_to_pwr_reg(regs, masks, caps, &offset, &mask);
+ if (ret)
+ return ret;
+
+ ret = rzg2l_ps_to_pwr_reg_val(ps, caps);
+ if (ret < 0)
+ return ret;
- pwr_reg = rzg2l_caps_to_pwr_reg(regs, caps, &mask);
- if (pwr_reg < 0)
- return pwr_reg;
+ scoped_guard(raw_spinlock_irqsave, &pctrl->lock) {
+ u8 tmp = readb(pctrl->base + offset);
- if (pwr_reg == OTHER_POC) {
- scoped_guard(raw_spinlock_irqsave, &pctrl->lock) {
- val = readb(pctrl->base + pwr_reg);
- if (poc_val)
- val |= mask;
- else
- val &= ~mask;
- writeb(val, pctrl->base + pwr_reg);
- }
- } else {
- writeb(poc_val, pctrl->base + pwr_reg);
+ tmp &= ~mask;
+ tmp |= field_prep(mask, ret);
+ writeb(tmp, pctrl->base + offset);
}
pctrl->settings[pin].power_source = ps;
@@ -3821,6 +3862,11 @@ static const struct rzg2l_hwcfg rzg3l_hwcfg = {
.oen = 0x3018,
.other_poc = OTHER_POC,
},
+ .masks = {
+ .other_poc_pvdd1833_oth_awo_poc = BIT(0),
+ .other_poc_pvdd1833_oth_iso_poc = BIT(1),
+ .other_poc_wdtovf_n_poc = BIT(2),
+ },
.iolh_groupa_ua = {
/* 1v8 power source */
[RZG2L_IOLH_IDX_1V8] = 2200, 4400, 9000, 10000,
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 2/5] pinctrl: renesas: rzg2l: Drop defines present in struct rzg2l_hwcfg
2026-09-03 11:33 [PATCH v6 0/5] pinctrl: renesas: rzg2l: Add support for RZ/G3S I3C Claudiu Beznea
2026-09-03 11:33 ` [PATCH v6 1/5] pinctrl: renesas: rzg2l: Generalize the power source code Claudiu Beznea
@ 2026-09-03 11:33 ` Claudiu Beznea
2026-09-03 11:33 ` [PATCH v6 3/5] pinctrl: renesas: rzg2l: Unify the power source handling Claudiu Beznea
` (2 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Claudiu Beznea @ 2026-09-03 11:33 UTC (permalink / raw)
To: geert+renesas, linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj
Cc: claudiu.beznea, linux-renesas-soc, linux-gpio, devicetree,
linux-kernel, Claudiu Beznea, Wolfram Sang
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Drop the QSPI and OTHER_POC register defines, which are SoC specific and
accessible through struct rzg2l_hwcfg::{qspi, other_poc}. While at it
move the assignement of rzg2l_hwcfg->regs->qspi upper to have the
initializations as sorted (by offsets) as possible.
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
Changes in v6:
- collected tags
Changes in v5:
- collected tags
Changes in v4:
- none
Changes in v3:
- updated patch description
- collected tags
Changes in v2:
- none
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 40bf8f9e8f2f..c17983aafcf5 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -181,8 +181,6 @@
#define SMT(off) (0x3400 + (off) * 8)
#define SD_CH(off, ch) ((off) + (ch) * 4)
#define ETH_POC(off, ch) ((off) + (ch) * 4)
-#define QSPI (0x3008) /* known on RZ/{G2L,G2LC,G2UL,Five} only */
-#define OTHER_POC (0x3028) /* known on RZ/G3L only */
#define PVDD_2500 2 /* I/O domain voltage 2.5V */
#define PVDD_1800 1 /* I/O domain voltage <= 1.8V */
@@ -3840,9 +3838,9 @@ static const struct rzg2l_hwcfg rzg2l_hwcfg = {
.regs = {
.pwpr = 0x3014,
.sd_ch = 0x3000,
+ .qspi = 0x3008,
.eth_poc = 0x300c,
.oen = 0x3018,
- .qspi = QSPI,
},
.iolh_groupa_ua = {
/* 3v3 power source */
@@ -3860,7 +3858,7 @@ static const struct rzg2l_hwcfg rzg3l_hwcfg = {
.sd_ch2 = 0x3024,
.eth_poc = 0x3010,
.oen = 0x3018,
- .other_poc = OTHER_POC,
+ .other_poc = 0x3028,
},
.masks = {
.other_poc_pvdd1833_oth_awo_poc = BIT(0),
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 3/5] pinctrl: renesas: rzg2l: Unify the power source handling
2026-09-03 11:33 [PATCH v6 0/5] pinctrl: renesas: rzg2l: Add support for RZ/G3S I3C Claudiu Beznea
2026-09-03 11:33 ` [PATCH v6 1/5] pinctrl: renesas: rzg2l: Generalize the power source code Claudiu Beznea
2026-09-03 11:33 ` [PATCH v6 2/5] pinctrl: renesas: rzg2l: Drop defines present in struct rzg2l_hwcfg Claudiu Beznea
@ 2026-09-03 11:33 ` Claudiu Beznea
2026-09-03 15:32 ` Geert Uytterhoeven
2026-09-03 22:10 ` Wolfram Sang
2026-09-03 11:33 ` [PATCH v6 4/5] dt-bindings: pinctrl: renesas,rzg2l-pinctrl: Document the missing I3C power source option Claudiu Beznea
2026-09-03 11:33 ` [PATCH v6 5/5] pinctrl: renesas: rzg2l: Add RZ/G3S support for selecting the I3C power source Claudiu Beznea
4 siblings, 2 replies; 11+ messages in thread
From: Claudiu Beznea @ 2026-09-03 11:33 UTC (permalink / raw)
To: geert+renesas, linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj
Cc: claudiu.beznea, linux-renesas-soc, linux-gpio, devicetree,
linux-kernel, Claudiu Beznea
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
The previous code handled power sources using a mixture of power
source specific definitions and lookups in the available_ps[] array.
Unify the power source handling by introducing
struct rzg2l_pinctrl_ps_desc, whose purpose is to describe a power
source through its power source value, associated register value,
associated capabilities (e.g. Ethernet), and associated IOLH index.
Introduce two new functions, rzg2l_ps_to_desc() and
rzg2l_pwr_reg_val_to_desc(), using the
RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC() macro, as their
implementations are similar.
These functions retrieve a power source descriptor based on either a
power source value or a power source register value. Other functions
that need to perform power source specific operations can call them to
retrieve the corresponding power source descriptor.
The register values for the soft power sources were kept to zero since
they are not used across the driver's code.
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
Changes in v6:
- described all the available power sources in the available_ps[]
array and dropped to wildcard approach to avoid letting the user
selecting unavailable power source for pins
- simplified RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC()
- for these two points ^ didn't collect the Wolfram's Tb tag
- dropped rzg2l_ps_is_supported()
- used conditional operator in rzg2l_ps_to_iolh_idx()
- adjusted the patch description
Changes in v5:
- none, this patch is new
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 165 ++++++++++++++++--------
1 file changed, 111 insertions(+), 54 deletions(-)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index c17983aafcf5..18656f6d2891 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -182,9 +182,6 @@
#define SD_CH(off, ch) ((off) + (ch) * 4)
#define ETH_POC(off, ch) ((off) + (ch) * 4)
-#define PVDD_2500 2 /* I/O domain voltage 2.5V */
-#define PVDD_1800 1 /* I/O domain voltage <= 1.8V */
-#define PVDD_3300 0 /* I/O domain voltage >= 3.3V */
#define PVDD_MASK 0x3
#define PWPR_B0WI BIT(7) /* Bit Write Disable */
@@ -289,12 +286,14 @@ struct rzg2l_register_masks {
/**
* enum rzg2l_iolh_index - starting indices in IOLH specific arrays
+ * @RZG2L_IOLH_IDX_NA: index N/A (to be used for error checking)
* @RZG2L_IOLH_IDX_1V8: starting index for 1V8 power source
* @RZG2L_IOLH_IDX_2V5: starting index for 2V5 power source
* @RZG2L_IOLH_IDX_3V3: starting index for 3V3 power source
* @RZG2L_IOLH_IDX_MAX: maximum index
*/
enum rzg2l_iolh_index {
+ RZG2L_IOLH_IDX_NA = -1,
RZG2L_IOLH_IDX_1V8 = 0,
RZG2L_IOLH_IDX_2V5 = 4,
RZG2L_IOLH_IDX_3V3 = 8,
@@ -445,7 +444,88 @@ struct rzg2l_pinctrl {
u32 clone_offset;
};
-static const u16 available_ps[] = { 1800, 2500, 3300 };
+/**
+ * struct rzg2l_pinctrl_ps_desc - RZ/G2L power source descriptor
+ * @caps: Capabilities that applies to the power source
+ * @iolh_index: IOLH index
+ * @ps: Power source value
+ * @pwr_reg_val: Power source register value
+ */
+struct rzg2l_pinctrl_ps_desc {
+ u32 caps;
+ enum rzg2l_iolh_index iolh_index;
+ u16 ps;
+ u16 pwr_reg_val;
+};
+
+#define RZG2L_PINCTRL_PS_DESC(_ps, _pwr_reg_val, _caps, _iolh_index) \
+ { \
+ .ps = _ps, \
+ .pwr_reg_val = _pwr_reg_val, \
+ .caps = _caps, \
+ .iolh_index = _iolh_index, \
+ }
+
+static const struct rzg2l_pinctrl_ps_desc available_ps[] = {
+ /* Ethernet I/O voltage domains */
+ RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
+ RZG2L_IOLH_IDX_1V8),
+ RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
+ RZG2L_IOLH_IDX_2V5),
+ RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
+ RZG2L_IOLH_IDX_3V3),
+
+ /* SD I/O voltage domains */
+ RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
+ PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_1V8),
+ RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
+ PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_2V5),
+ RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
+ PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_3V3),
+
+ /* QSPI I/O voltage domains */
+ RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_1V8),
+ RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_2V5),
+ RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_3V3),
+
+ /* AWO I/O voltage domains */
+ RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_PVDD1833_OTH_AWO_POC,
+ RZG2L_IOLH_IDX_1V8),
+ RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_PVDD1833_OTH_AWO_POC,
+ RZG2L_IOLH_IDX_3V3),
+
+ /* ISO I/O voltage domains */
+ RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_PVDD1833_OTH_ISO_POC,
+ RZG2L_IOLH_IDX_1V8),
+ RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_PVDD1833_OTH_ISO_POC,
+ RZG2L_IOLH_IDX_3V3),
+
+ /* WDTOVF I/O voltage domains */
+ RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_WDTOVF_N_POC, RZG2L_IOLH_IDX_1V8),
+ RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_WDTOVF_N_POC, RZG2L_IOLH_IDX_3V3),
+
+ /* Software voltage domains */
+ RZG2L_PINCTRL_PS_DESC(1800, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_1V8),
+ RZG2L_PINCTRL_PS_DESC(2500, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_2V5),
+ RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_3V3),
+};
+
+#define RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC(_name, _desc_member, _caps) \
+static const struct rzg2l_pinctrl_ps_desc *_name(u16 _desc_member, u32 _caps) \
+{ \
+ for (unsigned int i = 0; i < ARRAY_SIZE(available_ps); i++) { \
+ if (available_ps[i]._desc_member != _desc_member) \
+ continue; \
+ \
+ if (available_ps[i].caps & _caps) \
+ return &available_ps[i]; \
+ } \
+ \
+ return NULL; \
+}
+
+RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC(rzg2l_ps_to_desc, ps, caps)
+RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC(rzg2l_pwr_reg_val_to_desc, pwr_reg_val, caps)
static u64 rzg2l_pinctrl_get_variable_pin_cfg(struct rzg2l_pinctrl *pctrl,
u64 pincfg,
@@ -1126,34 +1206,26 @@ static int rzg2l_caps_to_pwr_reg(const struct rzg2l_register_offsets *regs,
return -EINVAL;
}
-static int rzg2l_pwr_reg_val_to_ps(u8 val, u32 caps)
+static int rzg2l_pwr_reg_val_to_ps(u16 pwr_reg_val, u32 caps)
{
- switch (val) {
- case PVDD_1800:
- return 1800;
- case PVDD_2500:
- return 2500;
- case PVDD_3300:
- return 3300;
- }
+ const struct rzg2l_pinctrl_ps_desc *desc;
- return -EINVAL;
+ desc = rzg2l_pwr_reg_val_to_desc(pwr_reg_val, caps);
+ if (!desc)
+ return -EINVAL;
+
+ return desc->ps;
}
-static int rzg2l_ps_to_pwr_reg_val(u32 ps, u32 caps)
+static int rzg2l_ps_to_pwr_reg_val(u16 ps, u32 caps)
{
- switch (ps) {
- case 1800:
- return PVDD_1800;
- case 2500:
- if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1)))
- return -EINVAL;
- return PVDD_2500;
- case 3300:
- return PVDD_3300;
- }
+ const struct rzg2l_pinctrl_ps_desc *desc;
- return -EINVAL;
+ desc = rzg2l_ps_to_desc(ps, caps);
+ if (!desc)
+ return -EINVAL;
+
+ return desc->pwr_reg_val;
}
static int rzg2l_get_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps)
@@ -1212,32 +1284,11 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps
return 0;
}
-static bool rzg2l_ps_is_supported(u16 ps)
+static enum rzg2l_iolh_index rzg2l_ps_to_iolh_idx(u16 ps, u32 caps)
{
- unsigned int i;
+ const struct rzg2l_pinctrl_ps_desc *desc = rzg2l_ps_to_desc(ps, caps);
- for (i = 0; i < ARRAY_SIZE(available_ps); i++) {
- if (available_ps[i] == ps)
- return true;
- }
-
- return false;
-}
-
-static enum rzg2l_iolh_index rzg2l_ps_to_iolh_idx(u16 ps)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(available_ps); i++) {
- if (available_ps[i] == ps)
- break;
- }
-
- /*
- * We multiply with RZG2L_IOLH_MAX_DS_ENTRIES as we have
- * RZG2L_IOLH_MAX_DS_ENTRIES DS values per power source
- */
- return i * RZG2L_IOLH_MAX_DS_ENTRIES;
+ return desc ? desc->iolh_index : RZG2L_IOLH_IDX_NA;
}
static u16 rzg2l_iolh_val_to_ua(const struct rzg2l_hwcfg *hwcfg, u32 caps, u8 val)
@@ -1622,7 +1673,11 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
ret = rzg2l_get_power_source(pctrl, _pin, cfg);
if (ret < 0)
return ret;
- iolh_idx = rzg2l_ps_to_iolh_idx(ret);
+
+ iolh_idx = rzg2l_ps_to_iolh_idx(ret, cfg);
+ if (iolh_idx == RZG2L_IOLH_IDX_NA)
+ return -EINVAL;
+
val = rzg2l_read_pin_config(pctrl, IOLH(off), bit, IOLH_MASK);
arg = rzg2l_iolh_val_to_ua(hwcfg, cfg, iolh_idx + val);
break;
@@ -1818,8 +1873,7 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
/* Apply power source. */
if (settings.power_source != pctrl->settings[_pin].power_source) {
- ret = rzg2l_ps_is_supported(settings.power_source);
- if (!ret)
+ if (!rzg2l_ps_to_desc(settings.power_source, cfg))
return -EINVAL;
/* Apply power source. */
@@ -1833,7 +1887,10 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
enum rzg2l_iolh_index iolh_idx;
int val;
- iolh_idx = rzg2l_ps_to_iolh_idx(settings.power_source);
+ iolh_idx = rzg2l_ps_to_iolh_idx(settings.power_source, cfg);
+ if (iolh_idx == RZG2L_IOLH_IDX_NA)
+ return -EINVAL;
+
ret = rzg2l_ds_is_supported(pctrl, cfg, iolh_idx,
settings.drive_strength_ua);
if (!ret)
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v6 3/5] pinctrl: renesas: rzg2l: Unify the power source handling
2026-09-03 11:33 ` [PATCH v6 3/5] pinctrl: renesas: rzg2l: Unify the power source handling Claudiu Beznea
@ 2026-09-03 15:32 ` Geert Uytterhoeven
2026-09-03 16:32 ` Claudiu Beznea
2026-09-03 22:10 ` Wolfram Sang
1 sibling, 1 reply; 11+ messages in thread
From: Geert Uytterhoeven @ 2026-09-03 15:32 UTC (permalink / raw)
To: Claudiu Beznea
Cc: linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj, claudiu.beznea, linux-renesas-soc,
linux-gpio, devicetree, linux-kernel, Claudiu Beznea
Hi Claudiu,
On Thu, 3 Sept 2026 at 13:34, Claudiu Beznea
<claudiu.beznea+renesas@tuxon.dev> wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>
> The previous code handled power sources using a mixture of power
> source specific definitions and lookups in the available_ps[] array.
> Unify the power source handling by introducing
> struct rzg2l_pinctrl_ps_desc, whose purpose is to describe a power
> source through its power source value, associated register value,
> associated capabilities (e.g. Ethernet), and associated IOLH index.
>
> Introduce two new functions, rzg2l_ps_to_desc() and
> rzg2l_pwr_reg_val_to_desc(), using the
> RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC() macro, as their
> implementations are similar.
>
> These functions retrieve a power source descriptor based on either a
> power source value or a power source register value. Other functions
> that need to perform power source specific operations can call them to
> retrieve the corresponding power source descriptor.
>
> The register values for the soft power sources were kept to zero since
> they are not used across the driver's code.
>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> ---
>
> Changes in v6:
> - described all the available power sources in the available_ps[]
> array and dropped to wildcard approach to avoid letting the user
> selecting unavailable power source for pins
> - simplified RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC()
> - for these two points ^ didn't collect the Wolfram's Tb tag
> - dropped rzg2l_ps_is_supported()
> - used conditional operator in rzg2l_ps_to_iolh_idx()
> - adjusted the patch description
Thanks for the update!
> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> +static const struct rzg2l_pinctrl_ps_desc available_ps[] = {
> + /* Ethernet I/O voltage domains */
> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
> + RZG2L_IOLH_IDX_1V8),
> + RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
> + RZG2L_IOLH_IDX_2V5),
> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
> + RZG2L_IOLH_IDX_3V3),
> +
> + /* SD I/O voltage domains */
> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
> + PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_1V8),
> + RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
> + PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_2V5),
Before (see below), only Ethernet could select the 2.5V domain, so
shouldn't this entry be dropped?
> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
> + PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_3V3),
> +
> + /* QSPI I/O voltage domains */
> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_1V8),
> + RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_2V5),
Same here?
> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_3V3),
> +
> + /* AWO I/O voltage domains */
> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_PVDD1833_OTH_AWO_POC,
> + RZG2L_IOLH_IDX_1V8),
> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_PVDD1833_OTH_AWO_POC,
> + RZG2L_IOLH_IDX_3V3),
> +
> + /* ISO I/O voltage domains */
> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_PVDD1833_OTH_ISO_POC,
> + RZG2L_IOLH_IDX_1V8),
> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_PVDD1833_OTH_ISO_POC,
> + RZG2L_IOLH_IDX_3V3),
> +
> + /* WDTOVF I/O voltage domains */
> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_WDTOVF_N_POC, RZG2L_IOLH_IDX_1V8),
> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_WDTOVF_N_POC, RZG2L_IOLH_IDX_3V3),
> +
> + /* Software voltage domains */
> + RZG2L_PINCTRL_PS_DESC(1800, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_1V8),
> + RZG2L_PINCTRL_PS_DESC(2500, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_2V5),
> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_3V3),
I never really understood PIN_CFG_SOFT_PS...
> +};
> -static int rzg2l_ps_to_pwr_reg_val(u32 ps, u32 caps)
> +static int rzg2l_ps_to_pwr_reg_val(u16 ps, u32 caps)
> {
> - switch (ps) {
> - case 1800:
> - return PVDD_1800;
> - case 2500:
> - if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1)))
> - return -EINVAL;
> - return PVDD_2500;
> - case 3300:
> - return PVDD_3300;
> - }
> + const struct rzg2l_pinctrl_ps_desc *desc;
>
> - return -EINVAL;
> + desc = rzg2l_ps_to_desc(ps, caps);
> + if (!desc)
> + return -EINVAL;
> +
> + return desc->pwr_reg_val;
> }
>
> static int rzg2l_get_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v6 3/5] pinctrl: renesas: rzg2l: Unify the power source handling
2026-09-03 15:32 ` Geert Uytterhoeven
@ 2026-09-03 16:32 ` Claudiu Beznea
0 siblings, 0 replies; 11+ messages in thread
From: Claudiu Beznea @ 2026-09-03 16:32 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj, claudiu.beznea, linux-renesas-soc,
linux-gpio, devicetree, linux-kernel, Claudiu Beznea
Hi, Geert,
On 9/3/26 18:32, Geert Uytterhoeven wrote:
> Hi Claudiu,
>
> On Thu, 3 Sept 2026 at 13:34, Claudiu Beznea
> <claudiu.beznea+renesas@tuxon.dev> wrote:
>> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>>
>> The previous code handled power sources using a mixture of power
>> source specific definitions and lookups in the available_ps[] array.
>> Unify the power source handling by introducing
>> struct rzg2l_pinctrl_ps_desc, whose purpose is to describe a power
>> source through its power source value, associated register value,
>> associated capabilities (e.g. Ethernet), and associated IOLH index.
>>
>> Introduce two new functions, rzg2l_ps_to_desc() and
>> rzg2l_pwr_reg_val_to_desc(), using the
>> RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC() macro, as their
>> implementations are similar.
>>
>> These functions retrieve a power source descriptor based on either a
>> power source value or a power source register value. Other functions
>> that need to perform power source specific operations can call them to
>> retrieve the corresponding power source descriptor.
>>
>> The register values for the soft power sources were kept to zero since
>> they are not used across the driver's code.
>>
>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>> ---
>>
>> Changes in v6:
>> - described all the available power sources in the available_ps[]
>> array and dropped to wildcard approach to avoid letting the user
>> selecting unavailable power source for pins
>> - simplified RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC()
>> - for these two points ^ didn't collect the Wolfram's Tb tag
>> - dropped rzg2l_ps_is_supported()
>> - used conditional operator in rzg2l_ps_to_iolh_idx()
>> - adjusted the patch description
>
> Thanks for the update!
>
>> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
>> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
>
>> +static const struct rzg2l_pinctrl_ps_desc available_ps[] = {
>> + /* Ethernet I/O voltage domains */
>> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
>> + RZG2L_IOLH_IDX_1V8),
>> + RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
>> + RZG2L_IOLH_IDX_2V5),
>> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1,
>> + RZG2L_IOLH_IDX_3V3),
>> +
>> + /* SD I/O voltage domains */
>> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
>> + PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_1V8),
>> + RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
>> + PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_2V5),
>
> Before (see below), only Ethernet could select the 2.5V domain, so
> shouldn't this entry be dropped?
That's a mistake. I'll drop it from here and from QSPI section.
>
>> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_SD0 | PIN_CFG_IO_VMC_SD1 |
>> + PIN_CFG_IO_VMC_SD2, RZG2L_IOLH_IDX_3V3),
>> +
>> + /* QSPI I/O voltage domains */
>> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_1V8),
>> + RZG2L_PINCTRL_PS_DESC(2500, 2, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_2V5),
>
> Same here?
>
>> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_IO_VMC_QSPI, RZG2L_IOLH_IDX_3V3),
>> +
>> + /* AWO I/O voltage domains */
>> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_PVDD1833_OTH_AWO_POC,
>> + RZG2L_IOLH_IDX_1V8),
>> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_PVDD1833_OTH_AWO_POC,
>> + RZG2L_IOLH_IDX_3V3),
>> +
>> + /* ISO I/O voltage domains */
>> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_PVDD1833_OTH_ISO_POC,
>> + RZG2L_IOLH_IDX_1V8),
>> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_PVDD1833_OTH_ISO_POC,
>> + RZG2L_IOLH_IDX_3V3),
>> +
>> + /* WDTOVF I/O voltage domains */
>> + RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_WDTOVF_N_POC, RZG2L_IOLH_IDX_1V8),
>> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_WDTOVF_N_POC, RZG2L_IOLH_IDX_3V3),
>> +
>> + /* Software voltage domains */
>> + RZG2L_PINCTRL_PS_DESC(1800, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_1V8),
>> + RZG2L_PINCTRL_PS_DESC(2500, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_2V5),
>> + RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_3V3),
>
> I never really understood PIN_CFG_SOFT_PS...
That was to match b/w a voltage and an IOLH value according to the table from
45.3.7 Driving Ability Control Register (IOLH_m) in the RZ/G3S manual (rev.1.30)
Thank you,
Claudiu
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 3/5] pinctrl: renesas: rzg2l: Unify the power source handling
2026-09-03 11:33 ` [PATCH v6 3/5] pinctrl: renesas: rzg2l: Unify the power source handling Claudiu Beznea
2026-09-03 15:32 ` Geert Uytterhoeven
@ 2026-09-03 22:10 ` Wolfram Sang
1 sibling, 0 replies; 11+ messages in thread
From: Wolfram Sang @ 2026-09-03 22:10 UTC (permalink / raw)
To: Claudiu Beznea
Cc: geert+renesas, linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj, claudiu.beznea, linux-renesas-soc,
linux-gpio, devicetree, linux-kernel, Claudiu Beznea
[-- Attachment #1: Type: text/plain, Size: 1330 bytes --]
On Thu, Sep 03, 2026 at 02:33:25PM +0300, Claudiu Beznea wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>
> The previous code handled power sources using a mixture of power
> source specific definitions and lookups in the available_ps[] array.
> Unify the power source handling by introducing
> struct rzg2l_pinctrl_ps_desc, whose purpose is to describe a power
> source through its power source value, associated register value,
> associated capabilities (e.g. Ethernet), and associated IOLH index.
>
> Introduce two new functions, rzg2l_ps_to_desc() and
> rzg2l_pwr_reg_val_to_desc(), using the
> RZG2L_PINCTRL_PS_DESC_MEMBER_TO_DESC_FUNC() macro, as their
> implementations are similar.
>
> These functions retrieve a power source descriptor based on either a
> power source value or a power source register value. Other functions
> that need to perform power source specific operations can call them to
> retrieve the corresponding power source descriptor.
>
> The register values for the soft power sources were kept to zero since
> they are not used across the driver's code.
>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
I3C with temp sensors work. SD card on carrier board works also.
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v6 4/5] dt-bindings: pinctrl: renesas,rzg2l-pinctrl: Document the missing I3C power source option
2026-09-03 11:33 [PATCH v6 0/5] pinctrl: renesas: rzg2l: Add support for RZ/G3S I3C Claudiu Beznea
` (2 preceding siblings ...)
2026-09-03 11:33 ` [PATCH v6 3/5] pinctrl: renesas: rzg2l: Unify the power source handling Claudiu Beznea
@ 2026-09-03 11:33 ` Claudiu Beznea
2026-09-03 11:33 ` [PATCH v6 5/5] pinctrl: renesas: rzg2l: Add RZ/G3S support for selecting the I3C power source Claudiu Beznea
4 siblings, 0 replies; 11+ messages in thread
From: Claudiu Beznea @ 2026-09-03 11:33 UTC (permalink / raw)
To: geert+renesas, linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj
Cc: claudiu.beznea, linux-renesas-soc, linux-gpio, devicetree,
linux-kernel, Claudiu Beznea, Conor Dooley, Wolfram Sang
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
The I3C pins on the Renesas RZ/G3S SoC can be powered at either 1.2V or
1.8V. Document the missing 1.2V power source option.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
Changes in v6:
- none (the Wolfram's Tb tag was not applied to this version since, based
on previous discussions, the tag don't apply to a binding patch).
Changes in v5:
- collected tags
Changes in v4:
- none
Changes in v3:
- collected tags
Changes in v2:
- collected tags
.../devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
index fb1fe1ea759f..32864c9add4a 100644
--- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
@@ -129,7 +129,7 @@ additionalProperties:
enum: [ 33, 50, 66, 100 ]
power-source:
description: I/O voltage in millivolt.
- enum: [ 1800, 2500, 3300 ]
+ enum: [ 1200, 1800, 2500, 3300 ]
slew-rate: true
gpio-hog: true
gpios: true
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 5/5] pinctrl: renesas: rzg2l: Add RZ/G3S support for selecting the I3C power source
2026-09-03 11:33 [PATCH v6 0/5] pinctrl: renesas: rzg2l: Add support for RZ/G3S I3C Claudiu Beznea
` (3 preceding siblings ...)
2026-09-03 11:33 ` [PATCH v6 4/5] dt-bindings: pinctrl: renesas,rzg2l-pinctrl: Document the missing I3C power source option Claudiu Beznea
@ 2026-09-03 11:33 ` Claudiu Beznea
2026-09-03 15:33 ` Geert Uytterhoeven
2026-09-03 22:11 ` Wolfram Sang
4 siblings, 2 replies; 11+ messages in thread
From: Claudiu Beznea @ 2026-09-03 11:33 UTC (permalink / raw)
To: geert+renesas, linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj
Cc: claudiu.beznea, linux-renesas-soc, linux-gpio, devicetree,
linux-kernel, Claudiu Beznea
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
The Renesas RZ/G3S I3C pins can be powered at either 1.8V or 1.2V. The
pin controller provides a register to select between these two options.
Update the Renesas RZ/G2L pin controller driver to allow selecting the
I3C power source on RZ/G3S SoC.
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
Changes in v6:
- used bit 23 to define PIN_CFG_IO_VMC_I3C
- described the I3C power sources according to the new method; due
to this didn't collect the Wolfram's Tb tag.
Changes in v5:
- due to patch 3 from this series:
-- dropped the definitions for PVDD_I3C_1200, PVDD_I3C_1800
-- dropped available_i3c_ps[] array and fill everything in available_ps[]
-- dropped the adjustments from rzg2l_pwr_reg_val_to_ps() and
rzg2l_ps_to_pwr_reg_val(), rzg2l_ps_is_supported() and
rzg2l_pinctrl_pinconf_set()
-- dropped the tags
Changes in v4:
- none
Changes in v3:
- collected tags
Changes in v2:
- none
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 30 +++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 18656f6d2891..f2e5fffd6e60 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -70,6 +70,7 @@
#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 PIN_CFG_IO_VMC_I3C BIT(23)
#define RZG2L_SINGLE_PIN BIT_ULL(63) /* Dedicated pin */
#define RZG2L_VARIABLE_CFG BIT_ULL(62) /* Variable cfg for port pins */
@@ -256,6 +257,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
+ * @i3c_set: I3C_SET register offset
*/
struct rzg2l_register_offsets {
u16 pwpr;
@@ -265,6 +267,7 @@ struct rzg2l_register_offsets {
u16 oen;
u16 qspi;
u16 other_poc;
+ u16 i3c_set;
};
/**
@@ -272,6 +275,7 @@ struct rzg2l_register_offsets {
* @other_poc_pvdd1833_oth_awo_poc: PVDD1833_OTH_AWO_POC mask
* @other_poc_pvdd1833_oth_iso_poc: PVDD1833_OTH_ISO_POC mask
* @other_poc_wdtovf_n_poc: WDTOVF_N_POC mask
+ * @i3c_set_poc: I3C_SET_POC mask
*/
struct rzg2l_register_masks {
union {
@@ -281,6 +285,11 @@ struct rzg2l_register_masks {
u8 other_poc_pvdd1833_oth_iso_poc;
u8 other_poc_wdtovf_n_poc;
};
+
+ /* RZ/G3S masks */
+ struct {
+ u8 i3c_set_poc;
+ };
};
};
@@ -394,6 +403,7 @@ struct rzg2l_pinctrl_pin_settings {
* @oen: Output Enable register cache
* @other_poc: OTHER_POC register cache
* @qspi: QSPI registers cache
+ * @i3c_set: I3C_SET register cache
*/
struct rzg2l_pinctrl_reg_cache {
u8 *p;
@@ -413,6 +423,7 @@ struct rzg2l_pinctrl_reg_cache {
u8 oen;
u8 other_poc;
u8 qspi;
+ u8 i3c_set;
};
struct rzg2l_pinctrl {
@@ -504,6 +515,10 @@ static const struct rzg2l_pinctrl_ps_desc available_ps[] = {
RZG2L_PINCTRL_PS_DESC(1800, 1, PIN_CFG_WDTOVF_N_POC, RZG2L_IOLH_IDX_1V8),
RZG2L_PINCTRL_PS_DESC(3300, 0, PIN_CFG_WDTOVF_N_POC, RZG2L_IOLH_IDX_3V3),
+ /* I3C I/O voltage domains */
+ RZG2L_PINCTRL_PS_DESC(1200, 1, PIN_CFG_IO_VMC_I3C, RZG2L_IOLH_IDX_NA),
+ RZG2L_PINCTRL_PS_DESC(1800, 0, PIN_CFG_IO_VMC_I3C, RZG2L_IOLH_IDX_NA),
+
/* Software voltage domains */
RZG2L_PINCTRL_PS_DESC(1800, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_1V8),
RZG2L_PINCTRL_PS_DESC(2500, 0, PIN_CFG_SOFT_PS, RZG2L_IOLH_IDX_2V5),
@@ -1202,6 +1217,11 @@ static int rzg2l_caps_to_pwr_reg(const struct rzg2l_register_offsets *regs,
*mask = masks->other_poc_wdtovf_n_poc;
return 0;
}
+ if (caps & PIN_CFG_IO_VMC_I3C) {
+ *offset = regs->i3c_set;
+ *mask = masks->i3c_set_poc;
+ return 0;
+ }
return -EINVAL;
}
@@ -2573,6 +2593,8 @@ static const struct rzg2l_dedicated_configs rzg3s_dedicated_pins[] = {
{ "AUDIO_CLK1", RZG2L_SINGLE_PIN_PACK(0x2, 0, PIN_CFG_IEN) },
{ "AUDIO_CLK2", RZG2L_SINGLE_PIN_PACK(0x2, 1, PIN_CFG_IEN) },
{ "WDTOVF_PERROUT#", RZG2L_SINGLE_PIN_PACK(0x6, 0, PIN_CFG_IOLH_A | PIN_CFG_SOFT_PS) },
+ { "I3C_SDA", RZG2L_SINGLE_PIN_PACK(0x9, 0, (PIN_CFG_IEN | PIN_CFG_IO_VMC_I3C)) },
+ { "I3C_SCL", RZG2L_SINGLE_PIN_PACK(0x9, 1, (PIN_CFG_IEN | PIN_CFG_IO_VMC_I3C)) },
{ "SD0_CLK", RZG2L_SINGLE_PIN_PACK(0x10, 0, (PIN_CFG_IOLH_B | PIN_CFG_IO_VMC_SD0)) },
{ "SD0_CMD", RZG2L_SINGLE_PIN_PACK(0x10, 1, (PIN_CFG_IOLH_B | PIN_CFG_IEN |
PIN_CFG_IO_VMC_SD0)) },
@@ -3795,6 +3817,8 @@ static int rzg2l_pinctrl_suspend_noirq(struct device *dev)
cache->oen = readb(pctrl->base + pctrl->data->hwcfg->regs.oen);
if (regs->other_poc)
cache->other_poc = readb(pctrl->base + regs->other_poc);
+ if (regs->i3c_set)
+ cache->i3c_set = readb(pctrl->base + regs->i3c_set);
if (pctrl->syscon) {
int ret;
@@ -3837,6 +3861,8 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev)
writeb(cache->qspi, pctrl->base + regs->qspi);
if (regs->other_poc)
writeb(cache->other_poc, pctrl->base + regs->other_poc);
+ if (regs->i3c_set)
+ writeb(cache->i3c_set, pctrl->base + regs->i3c_set);
raw_spin_lock_irqsave(&pctrl->lock, flags);
rzg2l_oen_write_with_pwpr(pctrl, cache->oen);
@@ -3953,8 +3979,12 @@ static const struct rzg2l_hwcfg rzg3s_hwcfg = {
.pwpr = 0x3000,
.sd_ch = 0x3004,
.eth_poc = 0x3010,
+ .i3c_set = 0x301c,
.oen = 0x3018,
},
+ .masks = {
+ .i3c_set_poc = BIT(2),
+ },
.iolh_groupa_ua = {
/* 1v8 power source */
[RZG2L_IOLH_IDX_1V8] = 2200, 4400, 9000, 10000,
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v6 5/5] pinctrl: renesas: rzg2l: Add RZ/G3S support for selecting the I3C power source
2026-09-03 11:33 ` [PATCH v6 5/5] pinctrl: renesas: rzg2l: Add RZ/G3S support for selecting the I3C power source Claudiu Beznea
@ 2026-09-03 15:33 ` Geert Uytterhoeven
2026-09-03 22:11 ` Wolfram Sang
1 sibling, 0 replies; 11+ messages in thread
From: Geert Uytterhoeven @ 2026-09-03 15:33 UTC (permalink / raw)
To: Claudiu Beznea
Cc: linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj, claudiu.beznea, linux-renesas-soc,
linux-gpio, devicetree, linux-kernel, Claudiu Beznea
On Thu, 3 Sept 2026 at 13:41, Claudiu Beznea
<claudiu.beznea+renesas@tuxon.dev> wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>
> The Renesas RZ/G3S I3C pins can be powered at either 1.8V or 1.2V. The
> pin controller provides a register to select between these two options.
> Update the Renesas RZ/G2L pin controller driver to allow selecting the
> I3C power source on RZ/G3S SoC.
>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> ---
>
> Changes in v6:
> - used bit 23 to define PIN_CFG_IO_VMC_I3C
> - described the I3C power sources according to the new method; due
> to this didn't collect the Wolfram's Tb tag.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v6 5/5] pinctrl: renesas: rzg2l: Add RZ/G3S support for selecting the I3C power source
2026-09-03 11:33 ` [PATCH v6 5/5] pinctrl: renesas: rzg2l: Add RZ/G3S support for selecting the I3C power source Claudiu Beznea
2026-09-03 15:33 ` Geert Uytterhoeven
@ 2026-09-03 22:11 ` Wolfram Sang
1 sibling, 0 replies; 11+ messages in thread
From: Wolfram Sang @ 2026-09-03 22:11 UTC (permalink / raw)
To: Claudiu Beznea
Cc: geert+renesas, linusw, robh, krzk+dt, conor+dt, magnus.damm,
prabhakar.mahadev-lad.rj, claudiu.beznea, linux-renesas-soc,
linux-gpio, devicetree, linux-kernel, Claudiu Beznea
[-- Attachment #1: Type: text/plain, Size: 522 bytes --]
On Thu, Sep 03, 2026 at 02:33:27PM +0300, Claudiu Beznea wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>
> The Renesas RZ/G3S I3C pins can be powered at either 1.8V or 1.2V. The
> pin controller provides a register to select between these two options.
> Update the Renesas RZ/G2L pin controller driver to allow selecting the
> I3C power source on RZ/G3S SoC.
>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread