Commit 51996952 authored by Claudiu Beznea's avatar Claudiu Beznea Committed by Geert Uytterhoeven

pinctrl: renesas: rzg2l: Add support to select power source for Ethernet pins

The GPIO controller available on RZ/G3S (but also on RZ/G2L) supports
setting the power source for Ethernet pins.  Based on the interface b/w
the Ethernet controller and the Ethernet PHY, and on board design, a
specific power source needs to be selected.  The GPIO controller
supports 1.8V, 2.5V, and 3.3V power source selection for the Ethernet
pins.  This can be selected though the ETHx_POC registers (x={0, 1}).

Adjust the driver to support this, and to do proper instantiation for
the RZ/G3S and RZ/G2L SoCs.  On RZ/G2L only the get operation has been
tested at the moment.

While at it, as the power registers on RZ/G2L support access sizes of 8
bits, and these registers on RZ/G3S support access sizes of 8/16/32
bits, replace writel()/readl() on these registers with writeb()/readb().
This should allow us to use the same code on both SoCs w/o any issues.
Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20231207070700.4156557-6-claudiu.beznea.uj@bp.renesas.comSigned-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
parent d3aaa720
...@@ -107,8 +107,10 @@ ...@@ -107,8 +107,10 @@
#define IEN(off) (0x1800 + (off) * 8) #define IEN(off) (0x1800 + (off) * 8)
#define ISEL(off) (0x2C00 + (off) * 8) #define ISEL(off) (0x2C00 + (off) * 8)
#define SD_CH(off, ch) ((off) + (ch) * 4) #define SD_CH(off, ch) ((off) + (ch) * 4)
#define ETH_POC(off, ch) ((off) + (ch) * 4)
#define QSPI (0x3008) #define QSPI (0x3008)
#define PVDD_2500 2 /* I/O domain voltage 2.5V */
#define PVDD_1800 1 /* I/O domain voltage <= 1.8V */ #define PVDD_1800 1 /* I/O domain voltage <= 1.8V */
#define PVDD_3300 0 /* I/O domain voltage >= 3.3V */ #define PVDD_3300 0 /* I/O domain voltage >= 3.3V */
...@@ -116,7 +118,6 @@ ...@@ -116,7 +118,6 @@
#define PWPR_PFCWE BIT(6) /* PFC Register Write Enable */ #define PWPR_PFCWE BIT(6) /* PFC Register Write Enable */
#define PM_MASK 0x03 #define PM_MASK 0x03
#define PVDD_MASK 0x01
#define PFC_MASK 0x07 #define PFC_MASK 0x07
#define IEN_MASK 0x01 #define IEN_MASK 0x01
#define IOLH_MASK 0x03 #define IOLH_MASK 0x03
...@@ -135,10 +136,12 @@ ...@@ -135,10 +136,12 @@
* struct rzg2l_register_offsets - specific register offsets * struct rzg2l_register_offsets - specific register offsets
* @pwpr: PWPR register offset * @pwpr: PWPR register offset
* @sd_ch: SD_CH register offset * @sd_ch: SD_CH register offset
* @eth_poc: ETH_POC register offset
*/ */
struct rzg2l_register_offsets { struct rzg2l_register_offsets {
u16 pwpr; u16 pwpr;
u16 sd_ch; u16 sd_ch;
u16 eth_poc;
}; };
/** /**
...@@ -604,6 +607,10 @@ static int rzg2l_caps_to_pwr_reg(const struct rzg2l_register_offsets *regs, u32 ...@@ -604,6 +607,10 @@ static int rzg2l_caps_to_pwr_reg(const struct rzg2l_register_offsets *regs, u32
return SD_CH(regs->sd_ch, 0); return SD_CH(regs->sd_ch, 0);
if (caps & PIN_CFG_IO_VMC_SD1) if (caps & PIN_CFG_IO_VMC_SD1)
return SD_CH(regs->sd_ch, 1); 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) if (caps & PIN_CFG_IO_VMC_QSPI)
return QSPI; return QSPI;
...@@ -615,6 +622,7 @@ static int rzg2l_get_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps ...@@ -615,6 +622,7 @@ 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_hwcfg *hwcfg = pctrl->data->hwcfg;
const struct rzg2l_register_offsets *regs = &hwcfg->regs; const struct rzg2l_register_offsets *regs = &hwcfg->regs;
int pwr_reg; int pwr_reg;
u8 val;
if (caps & PIN_CFG_SOFT_PS) if (caps & PIN_CFG_SOFT_PS)
return pctrl->settings[pin].power_source; return pctrl->settings[pin].power_source;
...@@ -623,7 +631,18 @@ static int rzg2l_get_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps ...@@ -623,7 +631,18 @@ static int rzg2l_get_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps
if (pwr_reg < 0) if (pwr_reg < 0)
return pwr_reg; return pwr_reg;
return (readl(pctrl->base + pwr_reg) & PVDD_MASK) ? 1800 : 3300; val = readb(pctrl->base + pwr_reg);
switch (val) {
case PVDD_1800:
return 1800;
case PVDD_2500:
return 2500;
case PVDD_3300:
return 3300;
default:
/* Should not happen. */
return -EINVAL;
}
} }
static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps, u32 ps) static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps, u32 ps)
...@@ -631,17 +650,32 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps ...@@ -631,17 +650,32 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps
const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg;
const struct rzg2l_register_offsets *regs = &hwcfg->regs; const struct rzg2l_register_offsets *regs = &hwcfg->regs;
int pwr_reg; int pwr_reg;
u8 val;
if (caps & PIN_CFG_SOFT_PS) { if (caps & PIN_CFG_SOFT_PS) {
pctrl->settings[pin].power_source = ps; pctrl->settings[pin].power_source = ps;
return 0; return 0;
} }
switch (ps) {
case 1800:
val = PVDD_1800;
break;
case 2500:
val = PVDD_2500;
break;
case 3300:
val = PVDD_3300;
break;
default:
return -EINVAL;
}
pwr_reg = rzg2l_caps_to_pwr_reg(regs, caps); pwr_reg = rzg2l_caps_to_pwr_reg(regs, caps);
if (pwr_reg < 0) if (pwr_reg < 0)
return pwr_reg; return pwr_reg;
writel((ps == 1800) ? PVDD_1800 : PVDD_3300, pctrl->base + pwr_reg); writeb(val, pctrl->base + pwr_reg);
pctrl->settings[pin].power_source = ps; pctrl->settings[pin].power_source = ps;
return 0; return 0;
...@@ -1885,6 +1919,7 @@ static const struct rzg2l_hwcfg rzg2l_hwcfg = { ...@@ -1885,6 +1919,7 @@ static const struct rzg2l_hwcfg rzg2l_hwcfg = {
.regs = { .regs = {
.pwpr = 0x3014, .pwpr = 0x3014,
.sd_ch = 0x3000, .sd_ch = 0x3000,
.eth_poc = 0x300c,
}, },
.iolh_groupa_ua = { .iolh_groupa_ua = {
/* 3v3 power source */ /* 3v3 power source */
...@@ -1897,6 +1932,7 @@ static const struct rzg2l_hwcfg rzg3s_hwcfg = { ...@@ -1897,6 +1932,7 @@ static const struct rzg2l_hwcfg rzg3s_hwcfg = {
.regs = { .regs = {
.pwpr = 0x3000, .pwpr = 0x3000,
.sd_ch = 0x3004, .sd_ch = 0x3004,
.eth_poc = 0x3010,
}, },
.iolh_groupa_ua = { .iolh_groupa_ua = {
/* 1v8 power source */ /* 1v8 power source */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment