diff options
author | Paul Barker <paul.barker.ct@bp.renesas.com> | 2024-06-25 22:03:10 +0200 |
---|---|---|
committer | Geert Uytterhoeven <geert+renesas@glider.be> | 2024-07-04 19:22:03 +0200 |
commit | 2453e858e945e5e2fa8da9fde8584995e7dd17d1 (patch) | |
tree | 4edcc8c5b301c1964ab084e0fcca20c63960411a /drivers/pinctrl | |
parent | pinctrl: renesas: rzg2l: Clean up and refactor OEN read/write functions (diff) | |
download | linux-2453e858e945e5e2fa8da9fde8584995e7dd17d1.tar.xz linux-2453e858e945e5e2fa8da9fde8584995e7dd17d1.zip |
pinctrl: renesas: rzg2l: Support output enable on RZ/G2L
On the RZ/G2L SoC family, the direction of the Ethernet TXC/TX_CLK
signal is selectable to support an Ethernet PHY operating in either MII
or RGMII mode. By default, the signal is configured as an input and MII
mode is supported. The ETH_MODE register can be modified to configure
this signal as an output to support RGMII mode.
As this signal is by default an input, and can optionally be switched to
an output, it maps neatly onto an `output-enable` property in the device
tree.
Signed-off-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/20240625200316.4282-4-paul.barker.ct@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/renesas/pinctrl-rzg2l.c | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 31d9f0027388..632180570b70 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -999,6 +999,60 @@ static bool rzg2l_ds_is_supported(struct rzg2l_pinctrl *pctrl, u32 caps, return false; } +static int rzg2l_pin_to_oen_bit(struct rzg2l_pinctrl *pctrl, unsigned int _pin) +{ + u64 *pin_data = pctrl->desc.pins[_pin].drv_data; + u64 caps = FIELD_GET(PIN_CFG_MASK, *pin_data); + u8 pin = RZG2L_PIN_ID_TO_PIN(_pin); + + if (pin > pctrl->data->hwcfg->oen_max_pin) + return -EINVAL; + + /* + * We can determine which Ethernet interface we're dealing with from + * the caps. + */ + if (caps & PIN_CFG_IO_VMC_ETH0) + return 0; + if (caps & PIN_CFG_IO_VMC_ETH1) + return 1; + + return -EINVAL; +} + +static u32 rzg2l_read_oen(struct rzg2l_pinctrl *pctrl, unsigned int _pin) +{ + int bit; + + bit = rzg2l_pin_to_oen_bit(pctrl, _pin); + if (bit < 0) + return 0; + + return !(readb(pctrl->base + ETH_MODE) & BIT(bit)); +} + +static int rzg2l_write_oen(struct rzg2l_pinctrl *pctrl, unsigned int _pin, u8 oen) +{ + unsigned long flags; + int bit; + u8 val; + + bit = rzg2l_pin_to_oen_bit(pctrl, _pin); + if (bit < 0) + return bit; + + spin_lock_irqsave(&pctrl->lock, flags); + val = readb(pctrl->base + ETH_MODE); + if (oen) + val &= ~BIT(bit); + else + val |= BIT(bit); + writeb(val, pctrl->base + ETH_MODE); + spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + static int rzg3s_pin_to_oen_bit(struct rzg2l_pinctrl *pctrl, unsigned int _pin) { u64 *pin_data = pctrl->desc.pins[_pin].drv_data; @@ -1775,7 +1829,7 @@ static const u64 r9a07g044_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(3, 0x21, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(2, 0x22, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(2, 0x23, RZG2L_MPXED_PIN_FUNCS), - RZG2L_GPIO_PORT_PACK(3, 0x24, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), + RZG2L_GPIO_PORT_PACK(3, 0x24, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0) | PIN_CFG_OEN), RZG2L_GPIO_PORT_PACK(2, 0x25, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), RZG2L_GPIO_PORT_PACK(2, 0x26, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), RZG2L_GPIO_PORT_PACK(2, 0x27, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), @@ -1784,7 +1838,7 @@ static const u64 r9a07g044_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(2, 0x2a, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), RZG2L_GPIO_PORT_PACK(2, 0x2b, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), RZG2L_GPIO_PORT_PACK(2, 0x2c, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), - RZG2L_GPIO_PORT_PACK(2, 0x2d, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1)), + RZG2L_GPIO_PORT_PACK(2, 0x2d, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1) | PIN_CFG_OEN), RZG2L_GPIO_PORT_PACK(2, 0x2e, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1)), RZG2L_GPIO_PORT_PACK(2, 0x2f, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1)), RZG2L_GPIO_PORT_PACK(2, 0x30, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1)), @@ -1808,13 +1862,13 @@ static const u64 r9a07g044_gpio_configs[] = { static const u64 r9a07g043_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(4, 0x10, RZG2L_MPXED_PIN_FUNCS), - RZG2L_GPIO_PORT_PACK(5, 0x11, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), + RZG2L_GPIO_PORT_PACK(5, 0x11, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0) | PIN_CFG_OEN), RZG2L_GPIO_PORT_PACK(4, 0x12, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), RZG2L_GPIO_PORT_PACK(4, 0x13, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), RZG2L_GPIO_PORT_PACK(6, 0x14, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH0)), RZG2L_GPIO_PORT_PACK(5, 0x15, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(5, 0x16, RZG2L_MPXED_PIN_FUNCS), - RZG2L_GPIO_PORT_PACK(5, 0x17, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1)), + RZG2L_GPIO_PORT_PACK(5, 0x17, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1) | PIN_CFG_OEN), RZG2L_GPIO_PORT_PACK(5, 0x18, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1)), RZG2L_GPIO_PORT_PACK(4, 0x19, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1)), RZG2L_GPIO_PORT_PACK(5, 0x1a, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IO_VMC_ETH1)), @@ -3007,6 +3061,7 @@ static const struct rzg2l_hwcfg rzg2l_hwcfg = { [RZG2L_IOLH_IDX_3V3] = 2000, 4000, 8000, 12000, }, .iolh_groupb_oi = { 100, 66, 50, 33, }, + .oen_max_pin = 0, }; static const struct rzg2l_hwcfg rzg3s_hwcfg = { @@ -3061,6 +3116,8 @@ static struct rzg2l_pinctrl_data r9a07g043_data = { #endif .pwpr_pfc_lock_unlock = &rzg2l_pwpr_pfc_lock_unlock, .pmc_writeb = &rzg2l_pmc_writeb, + .oen_read = &rzg2l_read_oen, + .oen_write = &rzg2l_write_oen, .hw_to_bias_param = &rzg2l_hw_to_bias_param, .bias_param_to_hw = &rzg2l_bias_param_to_hw, }; @@ -3076,6 +3133,8 @@ static struct rzg2l_pinctrl_data r9a07g044_data = { .hwcfg = &rzg2l_hwcfg, .pwpr_pfc_lock_unlock = &rzg2l_pwpr_pfc_lock_unlock, .pmc_writeb = &rzg2l_pmc_writeb, + .oen_read = &rzg2l_read_oen, + .oen_write = &rzg2l_write_oen, .hw_to_bias_param = &rzg2l_hw_to_bias_param, .bias_param_to_hw = &rzg2l_bias_param_to_hw, }; |