Files
BPI-CM9-Linux/build/patch/kernel/archive/rockchip64-6.19/rk3528-net-dsa-realtek-fixes-for-radxa-e24c-switch-chip.patch

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