Skip to content

Commit 1bbc8ee

Browse files
claudiubezneageertu
authored andcommitted
pinctrl: renesas: rzg2l: Add output enable support
Some of the Ethernet pins on RZ/G3S (but also valid for RZ/G2L) need to have the direction of the IO buffer set as output for Ethernet to work properly. On RZ/G3S, these pins are P1_0/P7_0, P1_1/P7_1, and can have the following Ethernet functions: TXC/TX_CLK or TX_CTL/TX_EN. As the pins supporting output enable are SoC specific, and there is a limited number of these pins (TXC/TX_CLK and/or TX_CTL/TX_EN), specify output enable capable port limits in the platform-based configuration data structure, to ensure proper validation. The OEN support has been intantiated for RZ/G3S at the moment. Signed-off-by: Claudiu Beznea <[email protected]> Reviewed-by: Geert Uytterhoeven <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Geert Uytterhoeven <[email protected]>
1 parent 5199695 commit 1bbc8ee

File tree

1 file changed

+85
-2
lines changed

1 file changed

+85
-2
lines changed

drivers/pinctrl/renesas/pinctrl-rzg2l.c

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#define PIN_CFG_FILCLKSEL BIT(12)
5858
#define PIN_CFG_IOLH_C BIT(13)
5959
#define PIN_CFG_SOFT_PS BIT(14)
60+
#define PIN_CFG_OEN BIT(15)
6061

6162
#define RZG2L_MPXED_COMMON_PIN_FUNCS(group) \
6263
(PIN_CFG_IOLH_##group | \
@@ -109,6 +110,7 @@
109110
#define SD_CH(off, ch) ((off) + (ch) * 4)
110111
#define ETH_POC(off, ch) ((off) + (ch) * 4)
111112
#define QSPI (0x3008)
113+
#define ETH_MODE (0x3018)
112114

113115
#define PVDD_2500 2 /* I/O domain voltage 2.5V */
114116
#define PVDD_1800 1 /* I/O domain voltage <= 1.8V */
@@ -170,6 +172,8 @@ enum rzg2l_iolh_index {
170172
* @iolh_groupb_oi: IOLH group B output impedance specific values
171173
* @drive_strength_ua: drive strength in uA is supported (otherwise mA is supported)
172174
* @func_base: base number for port function (see register PFC)
175+
* @oen_max_pin: the maximum pin number supporting output enable
176+
* @oen_max_port: the maximum port number supporting output enable
173177
*/
174178
struct rzg2l_hwcfg {
175179
const struct rzg2l_register_offsets regs;
@@ -179,6 +183,8 @@ struct rzg2l_hwcfg {
179183
u16 iolh_groupb_oi[4];
180184
bool drive_strength_ua;
181185
u8 func_base;
186+
u8 oen_max_pin;
187+
u8 oen_max_port;
182188
};
183189

184190
struct rzg2l_dedicated_configs {
@@ -782,6 +788,66 @@ static bool rzg2l_ds_is_supported(struct rzg2l_pinctrl *pctrl, u32 caps,
782788
return false;
783789
}
784790

791+
static bool rzg2l_oen_is_supported(u32 caps, u8 pin, u8 max_pin)
792+
{
793+
if (!(caps & PIN_CFG_OEN))
794+
return false;
795+
796+
if (pin > max_pin)
797+
return false;
798+
799+
return true;
800+
}
801+
802+
static u8 rzg2l_pin_to_oen_bit(u32 offset, u8 pin, u8 max_port)
803+
{
804+
if (pin)
805+
pin *= 2;
806+
807+
if (offset / RZG2L_PINS_PER_PORT == max_port)
808+
pin += 1;
809+
810+
return pin;
811+
}
812+
813+
static u32 rzg2l_read_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin)
814+
{
815+
u8 max_port = pctrl->data->hwcfg->oen_max_port;
816+
u8 max_pin = pctrl->data->hwcfg->oen_max_pin;
817+
u8 bit;
818+
819+
if (!rzg2l_oen_is_supported(caps, pin, max_pin))
820+
return 0;
821+
822+
bit = rzg2l_pin_to_oen_bit(offset, pin, max_port);
823+
824+
return !(readb(pctrl->base + ETH_MODE) & BIT(bit));
825+
}
826+
827+
static int rzg2l_write_oen(struct rzg2l_pinctrl *pctrl, u32 caps, u32 offset, u8 pin, u8 oen)
828+
{
829+
u8 max_port = pctrl->data->hwcfg->oen_max_port;
830+
u8 max_pin = pctrl->data->hwcfg->oen_max_pin;
831+
unsigned long flags;
832+
u8 val, bit;
833+
834+
if (!rzg2l_oen_is_supported(caps, pin, max_pin))
835+
return -EINVAL;
836+
837+
bit = rzg2l_pin_to_oen_bit(offset, pin, max_port);
838+
839+
spin_lock_irqsave(&pctrl->lock, flags);
840+
val = readb(pctrl->base + ETH_MODE);
841+
if (oen)
842+
val &= ~BIT(bit);
843+
else
844+
val |= BIT(bit);
845+
writeb(val, pctrl->base + ETH_MODE);
846+
spin_unlock_irqrestore(&pctrl->lock, flags);
847+
848+
return 0;
849+
}
850+
785851
static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
786852
unsigned int _pin,
787853
unsigned long *config)
@@ -819,6 +885,12 @@ static int rzg2l_pinctrl_pinconf_get(struct pinctrl_dev *pctldev,
819885
return -EINVAL;
820886
break;
821887

888+
case PIN_CONFIG_OUTPUT_ENABLE:
889+
arg = rzg2l_read_oen(pctrl, cfg, _pin, bit);
890+
if (!arg)
891+
return -EINVAL;
892+
break;
893+
822894
case PIN_CONFIG_POWER_SOURCE:
823895
ret = rzg2l_get_power_source(pctrl, _pin, cfg);
824896
if (ret < 0)
@@ -920,6 +992,13 @@ static int rzg2l_pinctrl_pinconf_set(struct pinctrl_dev *pctldev,
920992
rzg2l_rmw_pin_config(pctrl, IEN(off), bit, IEN_MASK, !!arg);
921993
break;
922994

995+
case PIN_CONFIG_OUTPUT_ENABLE:
996+
arg = pinconf_to_config_argument(_configs[i]);
997+
ret = rzg2l_write_oen(pctrl, cfg, _pin, bit, !!arg);
998+
if (ret)
999+
return ret;
1000+
break;
1001+
9231002
case PIN_CONFIG_POWER_SOURCE:
9241003
settings.power_source = pinconf_to_config_argument(_configs[i]);
9251004
break;
@@ -1364,7 +1443,8 @@ static const u32 r9a07g043_gpio_configs[] = {
13641443
static const u32 r9a08g045_gpio_configs[] = {
13651444
RZG2L_GPIO_PORT_PACK(4, 0x20, RZG3S_MPXED_PIN_FUNCS(A)), /* P0 */
13661445
RZG2L_GPIO_PORT_PACK(5, 0x30, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_C |
1367-
PIN_CFG_IO_VMC_ETH0)), /* P1 */
1446+
PIN_CFG_IO_VMC_ETH0)) |
1447+
PIN_CFG_OEN, /* P1 */
13681448
RZG2L_GPIO_PORT_PACK(4, 0x31, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_C |
13691449
PIN_CFG_IO_VMC_ETH0)), /* P2 */
13701450
RZG2L_GPIO_PORT_PACK(4, 0x32, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_C |
@@ -1374,7 +1454,8 @@ static const u32 r9a08g045_gpio_configs[] = {
13741454
RZG2L_GPIO_PORT_PACK(5, 0x21, RZG3S_MPXED_PIN_FUNCS(A)), /* P5 */
13751455
RZG2L_GPIO_PORT_PACK(5, 0x22, RZG3S_MPXED_PIN_FUNCS(A)), /* P6 */
13761456
RZG2L_GPIO_PORT_PACK(5, 0x34, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_C |
1377-
PIN_CFG_IO_VMC_ETH1)), /* P7 */
1457+
PIN_CFG_IO_VMC_ETH1)) |
1458+
PIN_CFG_OEN, /* P7 */
13781459
RZG2L_GPIO_PORT_PACK(5, 0x35, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_C |
13791460
PIN_CFG_IO_VMC_ETH1)), /* P8 */
13801461
RZG2L_GPIO_PORT_PACK(4, 0x36, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_C |
@@ -1956,6 +2037,8 @@ static const struct rzg2l_hwcfg rzg3s_hwcfg = {
19562037
},
19572038
.drive_strength_ua = true,
19582039
.func_base = 1,
2040+
.oen_max_pin = 1, /* Pin 1 of P0 and P7 is the maximum OEN pin. */
2041+
.oen_max_port = 7, /* P7_1 is the maximum OEN port. */
19592042
};
19602043

19612044
static struct rzg2l_pinctrl_data r9a07g043_data = {

0 commit comments

Comments
 (0)