Commit 2453e858 authored by Paul Barker's avatar Paul Barker Committed by Geert Uytterhoeven
Browse files

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: default avatarPaul Barker <paul.barker.ct@bp.renesas.com>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/20240625200316.4282-4-paul.barker.ct@bp.renesas.com


Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
parent a9024a32
Loading
Loading
Loading
Loading
+63 −4
Original line number Diff line number Diff line
@@ -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,
};