346 lines
12 KiB
Diff
346 lines
12 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <[email protected]>
|
|
Date: Tue, 29 Jul 2025 21:45:57 +0000
|
|
Subject: net: dsa: realtek: fix reset-gpios handling
|
|
|
|
- rpardini: picked from Kwiboo, to fix the ethernet switch on Radxa E24C
|
|
|
|
FIXME:
|
|
The commit c721f189e89c ("reset: Instantiate reset GPIO controller for
|
|
shared reset-gpios") in combination with the commit 56998aa6b7f0 ("net:
|
|
dsa: realtek: support reset controller"), both introduced in v6.9, can
|
|
typically cause probe issues for dsa realtek drivers when a reset-gpios
|
|
and CONFIG_RESET_GPIO enabled.
|
|
|
|
With CONFIG_RESET_GPIO enabled reset_control_get will fallback to look
|
|
for reset-gpios and instantiate a reset GPIO controller when found.
|
|
|
|
This interfere with gpiod_get and can result in an EBUSY error during
|
|
driver probe.
|
|
|
|
Change to first look for reset-gpios and only fallback to look for a
|
|
reset control when no reset-gpios was found to fix this EBUSY error.
|
|
|
|
Fixes: 56998aa6b7f0 ("net: dsa: realtek: support reset controller")
|
|
Signed-off-by: Jonas Karlman <[email protected]>
|
|
---
|
|
drivers/net/dsa/realtek/rtl83xx.c | 11 +++++-----
|
|
1 file changed, 6 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/net/dsa/realtek/rtl83xx.c b/drivers/net/dsa/realtek/rtl83xx.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
|
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
|
@@ -184,17 +184,18 @@ rtl83xx_probe(struct device *dev,
|
|
"realtek,disable-leds");
|
|
|
|
/* TODO: if power is software controlled, set up any regulators here */
|
|
- priv->reset_ctl = devm_reset_control_get_optional(dev, NULL);
|
|
- if (IS_ERR(priv->reset_ctl))
|
|
- return dev_err_cast_probe(dev, priv->reset_ctl,
|
|
- "failed to get reset control\n");
|
|
-
|
|
priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
|
if (IS_ERR(priv->reset)) {
|
|
dev_err(dev, "failed to get RESET GPIO\n");
|
|
return ERR_CAST(priv->reset);
|
|
}
|
|
|
|
+ if (!priv->reset)
|
|
+ priv->reset_ctl = devm_reset_control_get_optional(dev, NULL);
|
|
+ if (IS_ERR(priv->reset_ctl))
|
|
+ return dev_err_cast_probe(dev, priv->reset_ctl,
|
|
+ "failed to get reset control\n");
|
|
+
|
|
dev_set_drvdata(dev, priv);
|
|
|
|
if (priv->reset_ctl || priv->reset) {
|
|
--
|
|
Armbian
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <[email protected]>
|
|
Date: Sun, 27 Jul 2025 18:02:58 +0000
|
|
Subject: net: dsa: realtek: remove unused user_mii_bus from realtek_priv
|
|
|
|
user_mii_bus of struct realtek_priv is not dereferenced anywhere and it
|
|
is easy to confuse it with user_mii_bus from struct dsa_switch, remove
|
|
it.
|
|
|
|
Signed-off-by: Jonas Karlman <[email protected]>
|
|
---
|
|
drivers/net/dsa/realtek/realtek.h | 1 -
|
|
drivers/net/dsa/realtek/rtl83xx.c | 2 --
|
|
2 files changed, 3 deletions(-)
|
|
|
|
diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/net/dsa/realtek/realtek.h
|
|
+++ b/drivers/net/dsa/realtek/realtek.h
|
|
@@ -54,7 +54,6 @@ struct realtek_priv {
|
|
struct regmap *map;
|
|
struct regmap *map_nolock;
|
|
struct mutex map_lock;
|
|
- struct mii_bus *user_mii_bus;
|
|
struct mii_bus *bus;
|
|
int mdio_addr;
|
|
|
|
diff --git a/drivers/net/dsa/realtek/rtl83xx.c b/drivers/net/dsa/realtek/rtl83xx.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
|
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
|
@@ -102,8 +102,6 @@ int rtl83xx_setup_user_mdio(struct dsa_switch *ds)
|
|
goto err_put_node;
|
|
}
|
|
|
|
- priv->user_mii_bus = bus;
|
|
-
|
|
err_put_node:
|
|
of_node_put(mdio_np);
|
|
|
|
--
|
|
Armbian
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <[email protected]>
|
|
Date: Sun, 27 Jul 2025 18:02:59 +0000
|
|
Subject: net: dsa: realtek: add support for use of an optional mdio node
|
|
|
|
The dt-bindings schema for Realtek switches for unmanaged switches
|
|
contains a restriction on use of a mdio child OF node for MDIO-connected
|
|
switches, i.e.:
|
|
|
|
if:
|
|
required:
|
|
- reg
|
|
then:
|
|
not:
|
|
required:
|
|
- mdio
|
|
properties:
|
|
mdio: false
|
|
|
|
However, the driver currently requires the existence of a mdio child OF
|
|
node to successfully probe and properly function.
|
|
|
|
Relax the requirement of a mdio child OF node and assign the dsa_switch
|
|
user_mii_bus to allow a MDIO-connected switch to probe and function
|
|
when a mdio child OF node is missing.
|
|
|
|
Fixes: bba140a566ed ("net: dsa: realtek: use the same mii bus driver for both interfaces")
|
|
Signed-off-by: Jonas Karlman <[email protected]>
|
|
---
|
|
drivers/net/dsa/realtek/rtl83xx.c | 26 ++++++++--
|
|
1 file changed, 22 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/net/dsa/realtek/rtl83xx.c b/drivers/net/dsa/realtek/rtl83xx.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
|
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
|
@@ -1,5 +1,6 @@
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
+#include <linux/irqdomain.h>
|
|
#include <linux/module.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/of_mdio.h>
|
|
@@ -64,7 +65,7 @@ static int rtl83xx_user_mdio_write(struct mii_bus *bus, int addr, int regnum,
|
|
* @ds: DSA switch associated with this user_mii_bus
|
|
*
|
|
* Registers the MDIO bus for built-in Ethernet PHYs, and associates it with
|
|
- * the mandatory 'mdio' child OF node of the switch.
|
|
+ * the optional 'mdio' child OF node of the switch.
|
|
*
|
|
* Context: Can sleep.
|
|
* Return: 0 on success, negative value for failure.
|
|
@@ -75,11 +76,14 @@ int rtl83xx_setup_user_mdio(struct dsa_switch *ds)
|
|
struct device_node *mdio_np;
|
|
struct mii_bus *bus;
|
|
int ret = 0;
|
|
+ int irq;
|
|
+ int i;
|
|
|
|
mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
|
|
- if (!mdio_np) {
|
|
- dev_err(priv->dev, "no MDIO bus node\n");
|
|
- return -ENODEV;
|
|
+ if (mdio_np && !of_device_is_available(mdio_np)) {
|
|
+ dev_err(priv->dev, "no available MDIO bus node\n");
|
|
+ ret = -ENODEV;
|
|
+ goto err_put_node;
|
|
}
|
|
|
|
bus = devm_mdiobus_alloc(priv->dev);
|
|
@@ -95,6 +99,20 @@ int rtl83xx_setup_user_mdio(struct dsa_switch *ds)
|
|
snprintf(bus->id, MII_BUS_ID_SIZE, "%s:user_mii", dev_name(priv->dev));
|
|
bus->parent = priv->dev;
|
|
|
|
+ if (!mdio_np) {
|
|
+ ds->user_mii_bus = bus;
|
|
+ bus->phy_mask = ~ds->phys_mii_mask;
|
|
+
|
|
+ if (priv->irqdomain) {
|
|
+ for (i = 0; i < priv->num_ports; i++) {
|
|
+ irq = irq_find_mapping(priv->irqdomain, i);
|
|
+ if (irq < 0)
|
|
+ continue;
|
|
+ bus->irq[i] = irq;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
ret = devm_of_mdiobus_register(priv->dev, bus, mdio_np);
|
|
if (ret) {
|
|
dev_err(priv->dev, "unable to register MDIO bus %s\n",
|
|
--
|
|
Armbian
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <[email protected]>
|
|
Date: Sat, 26 Jul 2025 14:21:33 +0000
|
|
Subject: WIP: net: stmmac: dwmac-rk: Allow use of rx/tx delayline for rgmii-id
|
|
modes
|
|
|
|
Signed-off-by: Jonas Karlman <[email protected]>
|
|
---
|
|
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 37 ++++------
|
|
1 file changed, 15 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
|
|
@@ -1580,23 +1580,23 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
|
|
|
|
ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
|
|
if (ret) {
|
|
- bsp_priv->tx_delay = 0x30;
|
|
- dev_err(dev, "Can not read property: tx_delay.");
|
|
- dev_err(dev, "set tx_delay to 0x%x\n",
|
|
- bsp_priv->tx_delay);
|
|
+ if (plat->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
|
+ plat->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID)
|
|
+ bsp_priv->tx_delay = 0;
|
|
+ else
|
|
+ bsp_priv->tx_delay = 0x30;
|
|
} else {
|
|
- dev_info(dev, "TX delay(0x%x).\n", value);
|
|
bsp_priv->tx_delay = value;
|
|
}
|
|
|
|
ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
|
|
if (ret) {
|
|
- bsp_priv->rx_delay = 0x10;
|
|
- dev_err(dev, "Can not read property: rx_delay.");
|
|
- dev_err(dev, "set rx_delay to 0x%x\n",
|
|
- bsp_priv->rx_delay);
|
|
+ if (plat->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
|
+ plat->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID)
|
|
+ bsp_priv->rx_delay = 0;
|
|
+ else
|
|
+ bsp_priv->rx_delay = 0x10;
|
|
} else {
|
|
- dev_info(dev, "RX delay(0x%x).\n", value);
|
|
bsp_priv->rx_delay = value;
|
|
}
|
|
|
|
@@ -1675,21 +1675,14 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
|
|
/*rmii or rgmii*/
|
|
switch (bsp_priv->phy_iface) {
|
|
case PHY_INTERFACE_MODE_RGMII:
|
|
- dev_info(dev, "init for RGMII\n");
|
|
- bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
|
|
- bsp_priv->rx_delay);
|
|
- break;
|
|
case PHY_INTERFACE_MODE_RGMII_ID:
|
|
- dev_info(dev, "init for RGMII_ID\n");
|
|
- bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
|
|
- break;
|
|
case PHY_INTERFACE_MODE_RGMII_RXID:
|
|
- dev_info(dev, "init for RGMII_RXID\n");
|
|
- bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
|
|
- break;
|
|
case PHY_INTERFACE_MODE_RGMII_TXID:
|
|
- dev_info(dev, "init for RGMII_TXID\n");
|
|
- bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
|
|
+ dev_info(dev, "init for %s with delay (tx: 0x%x, rx: 0x%x)\n",
|
|
+ phy_modes(bsp_priv->phy_iface),
|
|
+ bsp_priv->tx_delay, bsp_priv->rx_delay);
|
|
+ bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
|
|
+ bsp_priv->rx_delay);
|
|
break;
|
|
case PHY_INTERFACE_MODE_RMII:
|
|
dev_info(dev, "init for RMII\n");
|
|
--
|
|
Armbian
|
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <[email protected]>
|
|
Date: Sat, 26 Jul 2025 15:19:15 +0000
|
|
Subject: WIP: net: stmmac: dwmac-rk: Use CRU as default TX clk source for
|
|
RGMII modes
|
|
|
|
The original meaning of the clock_in_out prop typically only had any
|
|
meaning for RMII modes, with 'input' meaning that clk source is from the
|
|
PHY and 'output' meaning clk source is from the internal CRU.
|
|
|
|
'input' means PHY provides the reference clock(50MHz), 'output' means GMAC provides the reference clock.
|
|
|
|
For RGMII the meaning of 'input' and 'output' is somewhat ambiguous, the
|
|
RX clk is input from PHY and the TX clock is output to the PHY. The
|
|
dt-binding also mention
|
|
|
|
Rockchip TRMs make it clear that for RGMII modes the TX clk source must
|
|
be from CRU. However, for RK3568 there is also support for using the PHY
|
|
output clk as a
|
|
|
|
Signed-off-by: Jonas Karlman <[email protected]>
|
|
---
|
|
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 15 +++++++---
|
|
1 file changed, 11 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
|
|
@@ -1567,17 +1567,22 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
|
|
|
|
ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
|
|
if (ret) {
|
|
- dev_err(dev, "Can not read property: clock_in_out.\n");
|
|
bsp_priv->clock_input = true;
|
|
} else {
|
|
- dev_info(dev, "clock input or output? (%s).\n",
|
|
- strings);
|
|
if (!strcmp(strings, "input"))
|
|
bsp_priv->clock_input = true;
|
|
else
|
|
bsp_priv->clock_input = false;
|
|
}
|
|
|
|
+ /* For RGMII, clock_in_out 'input' means main 125MHz clock is sourced
|
|
+ * from PHY and not from an internal PLL. Use of PHY or PLL as clock
|
|
+ * source for the 125MHz clock only affect the CRU clock tree.
|
|
+ * For RGMII modes, GMAC must always use CRU as the TX clock source.
|
|
+ */
|
|
+ if (phy_interface_mode_is_rgmii(plat->phy_interface))
|
|
+ bsp_priv->clock_input = false;
|
|
+
|
|
ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
|
|
if (ret) {
|
|
if (plat->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
|
@@ -1685,7 +1690,9 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
|
|
bsp_priv->rx_delay);
|
|
break;
|
|
case PHY_INTERFACE_MODE_RMII:
|
|
- dev_info(dev, "init for RMII\n");
|
|
+ dev_info(dev, "init for %s with %s clock\n",
|
|
+ phy_modes(bsp_priv->phy_iface),
|
|
+ bsp_priv->clock_input ? "input" : "output");
|
|
bsp_priv->ops->set_to_rmii(bsp_priv);
|
|
break;
|
|
default:
|
|
--
|
|
Armbian
|
|
|