summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-09-07 14:48:02 +0100
committerMark Brown <broonie@kernel.org>2026-09-07 14:48:02 +0100
commita0e0a91f126f1e2a87bdfeb57330ea65f9f95414 (patch)
tree1914117a5f74a4c0d847601d5957da89bdf723a8 /drivers
parenta2939050dd2f33c9c6561841bfab6947cefe5397 (diff)
parentec5202ccfa24791acf64146d5bac6b63ce234f95 (diff)
downloadlinux-next-a0e0a91f126f1e2a87bdfeb57330ea65f9f95414.tar.gz
linux-next-a0e0a91f126f1e2a87bdfeb57330ea65f9f95414.zip
Merge branch 'renesas-pinctrl' of https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pinctrl/renesas/pinctrl-rzg2l.c410
1 files changed, 282 insertions, 128 deletions
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index be52d47d77ae..9bf3743dc1ce 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -69,6 +69,8 @@
#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 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 */
@@ -180,12 +182,8 @@
#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 */
-#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 */
@@ -254,28 +252,57 @@ static const struct pin_config_item renesas_rzv2h_conf_items[] = {
* struct rzg2l_register_offsets - specific register offsets
* @pwpr: PWPR register offset
* @sd_ch: SD_CH register offset
+ * @sd_ch2: SD_CH2_POC register offset
* @eth_poc: ETH_POC register offset
* @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;
u16 sd_ch;
+ u16 sd_ch2;
u16 eth_poc;
u16 oen;
u16 qspi;
u16 other_poc;
+ u16 i3c_set;
+};
+
+/**
+ * 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
+ * @i3c_set_poc: I3C_SET_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;
+ };
+
+ /* RZ/G3S masks */
+ struct {
+ u8 i3c_set_poc;
+ };
+ };
};
/**
* 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,
@@ -288,6 +315,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
@@ -301,6 +330,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];
@@ -368,10 +398,12 @@ struct rzg2l_pinctrl_pin_settings {
* @nod: NOD registers cache
* @clone: Clone register cache
* @sd_ch: SD_CH registers cache
+ * @sd_ch2: SD_CH2_POC registers cache
* @eth_poc: ET_POC registers cache
* @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;
@@ -386,10 +418,12 @@ struct rzg2l_pinctrl_reg_cache {
u32 *nod[2];
u32 clone;
u8 sd_ch[2];
+ u8 sd_ch2;
u8 eth_poc[2];
u8 oen;
u8 other_poc;
u8 qspi;
+ u8 i3c_set;
};
struct rzg2l_pinctrl {
@@ -421,7 +455,89 @@ 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(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(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),
+
+ /* 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),
+ 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,
@@ -474,20 +590,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)),
@@ -1047,106 +1175,125 @@ 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)
+ const struct rzg2l_register_masks *masks,
+ u32 caps, u16 *offset, 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_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;
+ *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);
-
- return OTHER_POC;
+ *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;
}
+static int rzg2l_pwr_reg_val_to_ps(u16 pwr_reg_val, u32 caps)
+{
+ const struct rzg2l_pinctrl_ps_desc *desc;
+
+ 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(u16 ps, u32 caps)
+{
+ const struct rzg2l_pinctrl_ps_desc *desc;
+
+ 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)
{
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;
-
- val = readb(pctrl->base + pwr_reg);
- if (pwr_reg == OTHER_POC)
- val = field_get(mask, val);
-
- switch (val) {
- case PVDD_1800:
- return 1800;
- case PVDD_2500:
- return 2500;
- case PVDD_3300:
- return 3300;
- default:
- /* Should not happen. */
- return -EINVAL;
- }
+ ret = rzg2l_caps_to_pwr_reg(regs, masks, caps, &offset, &mask);
+ if (ret)
+ return ret;
+
+ val = readb(pctrl->base + offset);
+
+ 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;
@@ -1154,32 +1301,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)
@@ -1564,7 +1690,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;
@@ -1760,8 +1890,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. */
@@ -1775,7 +1904,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)
@@ -2458,6 +2590,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)) },
@@ -2677,28 +2811,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,11 +3806,16 @@ 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);
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;
@@ -3719,11 +3858,16 @@ 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);
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));
@@ -3774,9 +3918,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 */
@@ -3791,9 +3935,15 @@ static const struct rzg2l_hwcfg rzg3l_hwcfg = {
.regs = {
.pwpr = 0x3000,
.sd_ch = 0x3004,
+ .sd_ch2 = 0x3024,
.eth_poc = 0x3010,
.oen = 0x3018,
- .other_poc = OTHER_POC,
+ .other_poc = 0x3028,
+ },
+ .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 */
@@ -3826,8 +3976,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,