Merge pull request #9870 from jernejsk/h6-net

Allwinner: linux: Use old OrangePi 3 net patches
This commit is contained in:
Matthias Reichl 2025-03-15 19:17:26 +01:00 committed by GitHub
commit cd5ee5f728
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 210 additions and 197 deletions

View File

@ -1,165 +0,0 @@
From 25b44143ea8162209beb02759ca3ea3bd3be7a74 Mon Sep 17 00:00:00 2001
From: Corentin Labbe <clabbe.montjoie@gmail.com>
Date: Fri, 14 Oct 2022 12:54:21 +0200
Subject: [PATCH] phy: handle optional regulator for PHY
Add handling of optional regulators for PHY.
Regulators need to be enabled before PHY scanning, so MDIO bus
initiate this task.
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
drivers/net/mdio/fwnode_mdio.c | 53 ++++++++++++++++++++++++++++++++--
drivers/net/phy/phy_device.c | 6 ++++
include/linux/phy.h | 3 ++
3 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index fd02f5cbc853..bd5a27eaf40c 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -11,6 +11,7 @@
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/pse-pd/pse.h>
+#include <linux/regulator/consumer.h>
MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>");
MODULE_LICENSE("GPL");
@@ -58,6 +59,40 @@ fwnode_find_mii_timestamper(struct fwnode_handle *fwnode)
return register_mii_timestamper(arg.np, arg.args[0]);
}
+static int
+fwnode_regulator_get_bulk_enabled(struct device *dev,
+ struct fwnode_handle *fwnode,
+ struct regulator_bulk_data **consumers)
+{
+ struct device_node *np;
+ int ret, reg_cnt;
+
+ np = to_of_node(fwnode);
+ if (!np)
+ return 0;
+
+ reg_cnt = of_regulator_bulk_get_all(dev, np, consumers);
+ if (reg_cnt < 0) {
+ ret = reg_cnt;
+ goto clean_consumers;
+ }
+
+ if (reg_cnt == 0)
+ return 0;
+
+ ret = regulator_bulk_enable(reg_cnt, *consumers);
+ if (ret)
+ goto clean_consumers;
+
+ return reg_cnt;
+
+clean_consumers:
+ kfree(*consumers);
+ *consumers = NULL;
+
+ return ret;
+}
+
int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
struct phy_device *phy,
struct fwnode_handle *child, u32 addr)
@@ -113,12 +148,13 @@ EXPORT_SYMBOL(fwnode_mdiobus_phy_device_register);
int fwnode_mdiobus_register_phy(struct mii_bus *bus,
struct fwnode_handle *child, u32 addr)
{
+ struct regulator_bulk_data *consumers = NULL;
struct mii_timestamper *mii_ts = NULL;
struct pse_control *psec = NULL;
struct phy_device *phy;
+ int rc, reg_cnt;
bool is_c45;
u32 phy_id;
- int rc;
psec = fwnode_find_pse_control(child);
if (IS_ERR(psec))
@@ -130,6 +166,12 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
goto clean_pse;
}
+ reg_cnt = fwnode_regulator_get_bulk_enabled(&bus->dev, child, &consumers);
+ if (reg_cnt < 0) {
+ rc = reg_cnt;
+ goto clean_mii_ts;
+ }
+
is_c45 = fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45");
if (is_c45 || fwnode_get_phy_id(child, &phy_id))
phy = get_phy_device(bus, addr, is_c45);
@@ -137,9 +179,12 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
phy = phy_device_create(bus, addr, phy_id, 0, NULL);
if (IS_ERR(phy)) {
rc = PTR_ERR(phy);
- goto clean_mii_ts;
+ goto clean_regulators;
}
+ phy->regulator_cnt = reg_cnt;
+ phy->consumers = consumers;
+
if (is_acpi_node(child)) {
phy->irq = bus->irq[addr];
@@ -174,6 +219,10 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
clean_phy:
phy_device_free(phy);
+clean_regulators:
+ if (reg_cnt > 0)
+ regulator_bulk_disable(reg_cnt, consumers);
+ kfree(consumers);
clean_mii_ts:
unregister_mii_timestamper(mii_ts);
clean_pse:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 2ce74593d6e4..31b6913ceed1 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -31,6 +31,7 @@
#include <linux/phy_led_triggers.h>
#include <linux/pse-pd/pse.h>
#include <linux/property.h>
+#include <linux/regulator/consumer.h>
#include <linux/rtnetlink.h>
#include <linux/sfp.h>
#include <linux/skbuff.h>
@@ -3400,6 +3401,11 @@ static int phy_remove(struct device *dev)
phydev->drv = NULL;
+ if (phydev->regulator_cnt > 0)
+ regulator_bulk_disable(phydev->regulator_cnt, phydev->consumers);
+
+ kfree(phydev->consumers);
+
return 0;
}
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 3cc52826f18e..832cb2d4f76a 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -757,6 +757,9 @@ struct phy_device {
void (*phy_link_change)(struct phy_device *phydev, bool up);
void (*adjust_link)(struct net_device *dev);
+ int regulator_cnt;
+ struct regulator_bulk_data *consumers;
+
#if IS_ENABLED(CONFIG_MACSEC)
/* MACsec management functions */
const struct macsec_ops *macsec_ops;
--
2.43.0

View File

@ -0,0 +1,75 @@
From 1877122b4d0fef204f7076f4c28761cae9fcd807 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Sat, 15 Mar 2025 17:38:35 +0100
Subject: [PATCH 1/3] net: stmmac: sun8i: Use devm_regulator_get for PHY
regulator
Use devm_regulator_get instead of devm_regulator_get_optional and rely
on dummy supply. This avoids NULL checks before regulator_enable/disable
calls.
This path also improves error reporting, because we now report both
use of dummy supply and error during registration with more detail,
instead of generic info level message "No regulator found" that
was reported previously on errors and lack of regulator property in DT.
Finally, we'll be adding further optional regulators, and the overall
code will be simpler.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 23 ++++++++-----------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 4b7b2582a120..94a4898260b0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -588,12 +588,10 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
struct sunxi_priv_data *gmac = priv;
int ret;
- if (gmac->regulator) {
- ret = regulator_enable(gmac->regulator);
- if (ret) {
- dev_err(&pdev->dev, "Fail to enable regulator\n");
- return ret;
- }
+ ret = regulator_enable(gmac->regulator);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to enable regulator\n");
+ return ret;
}
if (gmac->use_internal_phy) {
@@ -1051,8 +1049,7 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
if (gmac->variant->soc_has_internal_phy)
sun8i_dwmac_unpower_internal_phy(gmac);
- if (gmac->regulator)
- regulator_disable(gmac->regulator);
+ regulator_disable(gmac->regulator);
}
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
@@ -1176,12 +1173,12 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
}
/* Optional regulator for PHY */
- gmac->regulator = devm_regulator_get_optional(dev, "phy");
+ gmac->regulator = devm_regulator_get(dev, "phy");
if (IS_ERR(gmac->regulator)) {
- if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- dev_info(dev, "No regulator found\n");
- gmac->regulator = NULL;
+ ret = PTR_ERR(gmac->regulator);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get PHY regulator (%d)\n", ret);
+ return ret;
}
/* The "GMAC clock control" register might be located in the
--
2.48.1

View File

@ -0,0 +1,92 @@
From a46ed6e8213c96d0905de691620cd473b0a2e45e Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Sat, 15 Mar 2025 17:49:23 +0100
Subject: [PATCH 2/3] net: stmmac: sun8i: Add support for enabling a regulator
for PHY I/O pins
Orange Pi 3 has two regulators that power the Realtek RTL8211E. According
to the phy datasheet, both regulators need to be enabled at the same time.
Add support for the second optional regulator, "phy-io", to the glue
driver.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 94a4898260b0..da77e82f06d2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -61,6 +61,8 @@ struct emac_variant {
/* struct sunxi_priv_data - hold all sunxi private data
* @ephy_clk: reference to the optional EPHY clock for the internal PHY
* @regulator: reference to the optional regulator
+ * @regulator_phy_io: reference to the optional regulator for
+ * PHY I/O pins
* @rst_ephy: reference to the optional EPHY reset for the internal PHY
* @variant: reference to the current board variant
* @regmap: regmap for using the syscon
@@ -71,6 +73,7 @@ struct emac_variant {
struct sunxi_priv_data {
struct clk *ephy_clk;
struct regulator *regulator;
+ struct regulator *regulator_phy_io;
struct reset_control *rst_ephy;
const struct emac_variant *variant;
struct regmap_field *regmap_field;
@@ -588,10 +591,16 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
struct sunxi_priv_data *gmac = priv;
int ret;
+ ret = regulator_enable(gmac->regulator_phy_io);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to enable PHY I/O regulator\n");
+ return ret;
+ }
+
ret = regulator_enable(gmac->regulator);
if (ret) {
dev_err(&pdev->dev, "Fail to enable regulator\n");
- return ret;
+ goto err_disable_regulator_phy_io;
}
if (gmac->use_internal_phy) {
@@ -605,6 +614,8 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
err_disable_regulator:
if (gmac->regulator)
regulator_disable(gmac->regulator);
+err_disable_regulator_phy_io:
+ regulator_disable(gmac->regulator_phy_io);
return ret;
}
@@ -1050,6 +1061,7 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
sun8i_dwmac_unpower_internal_phy(gmac);
regulator_disable(gmac->regulator);
+ regulator_disable(gmac->regulator_phy_io);
}
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
@@ -1181,6 +1193,15 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
return ret;
}
+ /* Optional regulator for PHY I/O pins */
+ gmac->regulator_phy_io = devm_regulator_get(dev, "phy-io");
+ if (IS_ERR(gmac->regulator_phy_io)) {
+ ret = PTR_ERR(gmac->regulator_phy_io);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get PHY I/O regulator (%d)\n", ret);
+ return ret;
+ }
+
/* The "GMAC clock control" register might be located in the
* CCU address range (on the R40), or the system control address
* range (on most other sun8i and later SoCs).
--
2.48.1

View File

@ -1,12 +1,12 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= <megi@xff.cz>
Date: Tue, 20 Aug 2019 14:54:48 +0200
Subject: [PATCH] arm64: dts: allwinner: orange-pi-3: Enable ethernet
From 2409d598b229dee9036f9ea2f14dde2647e8c114 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Sat, 15 Mar 2025 18:00:20 +0100
Subject: [PATCH 3/3] arm64: dts: allwinner: orange-pi-3: Enable ethernet
Orange Pi 3 has two regulators that power the Realtek RTL8211E
PHY. According to the datasheet, both regulators need to be enabled
at the same time, or that "phy-io" should be enabled slightly earlier
than "ephy" regulator.
than "phy" regulator.
RTL8211E/RTL8211EG datasheet says:
@ -14,26 +14,33 @@ RTL8211E/RTL8211EG datasheet says:
or slightly earlier than 3.3V power. Rising 2.5V (or 1.8/1.5V) power
later than 3.3V power may lead to errors.
Signed-off-by: Ondrej Jirman <megi@xff.cz>
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
The driver ensures the regulator enable ordering. The timing is set
in DT via startup-delay-us.
We also need to wait at least 30ms after power-up/reset, before
accessing the PHY registers.
All values of RX/TX delay were tested exhaustively and a middle one
of the range of working values was chosen.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../dts/allwinner/sun50i-h6-orangepi-3.dts | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
.../dts/allwinner/sun50i-h6-orangepi-3.dts | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
index 6fc65e8db220..df8b6de2b4d2 100644
index d01a318653a3..89049a7c0473 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
@@ -13,6 +13,7 @@ / {
compatible = "xunlong,orangepi-3", "allwinner,sun50i-h6";
@@ -15,6 +15,7 @@ / {
aliases {
+ ethernet0 = &emac;
serial0 = &uart0;
serial1 = &uart1;
+ ethernet0 = &emac;
};
@@ -55,6 +56,16 @@ led-1 {
chosen {
@@ -55,6 +56,15 @@ led-1 {
};
};
@ -44,21 +51,30 @@ index 6fc65e8db220..df8b6de2b4d2 100644
+ regulator-max-microvolt = <2500000>;
+ enable-active-high;
+ gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
+ off-on-delay-us = <100000>;
+ };
+
reg_vcc5v: vcc5v {
/* board wide 5V supply directly from the DC jack */
compatible = "regulator-fixed";
@@ -113,6 +124,33 @@ &ehci3 {
status = "okay";
@@ -108,6 +118,35 @@ hdmi_out_con: endpoint {
};
};
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ext_rgmii_pins>;
+ phy-mode = "rgmii-id";
+ phy-mode = "rgmii-txid";
+ phy-handle = <&ext_rgmii_phy>;
+ /*
+ * The board uses 2.5V RGMII signalling. Power sequence to enable
+ * the phy is to enable GMAC-2V5 and GMAC-3V (aldo2) power rails
+ * at the same time and to wait 100ms. The driver enables phy-io
+ * first. Delay is achieved with enable-ramp-delay on reg_aldo2.
+ */
+ phy-supply = <&reg_aldo2>;
+ phy-io-supply = <&reg_gmac_2v5>;
+ allwinner,rx-delay-ps = <1500>;
+ allwinner,tx-delay-ps = <700>;
+ status = "okay";
+};
+
@ -66,14 +82,6 @@ index 6fc65e8db220..df8b6de2b4d2 100644
+ ext_rgmii_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ /*
+ * The board uses 2.5V RGMII signalling. Power sequence to enable
+ * the phy is to enable GMAC-2V5 and GMAC-3V (aldo2) power rails
+ * at the same time and to wait 100ms. The driver enables phy-io
+ * first. Delay is achieved with enable-ramp-delay on reg_aldo2.
+ */
+ phy-io-supply = <&reg_gmac_2v5>;
+ ephy-supply = <&reg_aldo2>;
+
+ reset-gpios = <&pio 3 14 GPIO_ACTIVE_LOW>; /* PD14 */
+ reset-assert-us = <15000>;
@ -81,10 +89,10 @@ index 6fc65e8db220..df8b6de2b4d2 100644
+ };
+};
+
&gpu {
mali-supply = <&reg_dcdcc>;
status = "okay";
@@ -211,6 +249,7 @@ reg_aldo2: aldo2 {
&mmc0 {
vmmc-supply = <&reg_cldo1>;
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
@@ -188,6 +227,7 @@ reg_aldo2: aldo2 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc33-audio-tv-ephy-mac";
@ -92,3 +100,6 @@ index 6fc65e8db220..df8b6de2b4d2 100644
};
/* ALDO3 is shorted to CLDO1 */
--
2.48.1