[openwrt/openwrt] kernel: backport RTL8211F clkout-disable patch

LEDE Commits lede-commits at lists.infradead.org
Mon Jun 27 12:57:57 PDT 2022


svanheule pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/7bf73e270e7f1704b21860712820dcf12b593e91

commit 7bf73e270e7f1704b21860712820dcf12b593e91
Author: Sander Vanheule <sander at svanheule.net>
AuthorDate: Mon Jun 27 20:36:32 2022 +0200

    kernel: backport RTL8211F clkout-disable patch
    
    In Linux v5.14 an extra feature was introduced for the RTL8211F phy,
    allowing to disable a clock output from the phy. Part of that patch is to
    always (soft) reset the phy upon initialisation.
    
    This phy reset is required to have a working ethernet on the TP-Link
    EAP225-Outdoor v3 and EAP225 v4 after a reboot. Otherwise the ethernet
    port will only function properly on cold boots.
    
    Tested-by: Andre Klärner <kandre at ak-online.be> # EAP225-Outdoor v3
    Tested-by: Sven Hauer <sven.hauer+github at uniku.de> # EAP225 v4
    Signed-off-by: Sander Vanheule <sander at svanheule.net>
---
 ...ltek-add-dt-property-to-disable-CLKOUT-cl.patch | 119 +++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/target/linux/generic/backport-5.10/796-v5.14-net-phy-realtek-add-dt-property-to-disable-CLKOUT-cl.patch b/target/linux/generic/backport-5.10/796-v5.14-net-phy-realtek-add-dt-property-to-disable-CLKOUT-cl.patch
new file mode 100644
index 0000000000..52a6f83500
--- /dev/null
+++ b/target/linux/generic/backport-5.10/796-v5.14-net-phy-realtek-add-dt-property-to-disable-CLKOUT-cl.patch
@@ -0,0 +1,119 @@
+From 0a4355c2b7f8ecd5e61cc262ecdbd4a2cce1ea7e Mon Sep 17 00:00:00 2001
+From: Joakim Zhang <qiangqing.zhang at nxp.com>
+Date: Tue, 8 Jun 2021 11:15:33 +0800
+Subject: [PATCH] net: phy: realtek: add dt property to disable CLKOUT clock
+
+CLKOUT is enabled by default after PHY hardware reset, this patch adds
+"realtek,clkout-disable" property for user to disable CLKOUT clock
+to save PHY power.
+
+Per RTL8211F guide, a PHY reset should be issued after setting these
+bits in PHYCR2 register. After this patch, CLKOUT clock output to be
+disabled.
+
+Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/phy/realtek.c | 42 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 41 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -8,6 +8,7 @@
+  * Copyright (c) 2004 Freescale Semiconductor, Inc.
+  */
+ #include <linux/bitops.h>
++#include <linux/of.h>
+ #include <linux/phy.h>
+ #include <linux/module.h>
+ #include <linux/delay.h>
+@@ -27,6 +28,7 @@
+ #define RTL821x_PAGE_SELECT			0x1f
+ 
+ #define RTL8211F_PHYCR1				0x18
++#define RTL8211F_PHYCR2				0x19
+ #define RTL8211F_INSR				0x1d
+ 
+ #define RTL8211F_TX_DELAY			BIT(8)
+@@ -40,6 +42,8 @@
+ #define RTL8211E_TX_DELAY			BIT(12)
+ #define RTL8211E_RX_DELAY			BIT(11)
+ 
++#define RTL8211F_CLKOUT_EN			BIT(0)
++
+ #define RTL8201F_ISR				0x1e
+ #define RTL8201F_IER				0x13
+ 
+@@ -62,6 +66,10 @@ MODULE_DESCRIPTION("Realtek PHY driver")
+ MODULE_AUTHOR("Johnson Leung");
+ MODULE_LICENSE("GPL");
+ 
++struct rtl821x_priv {
++	u16 phycr2;
++};
++
+ static int rtl821x_read_page(struct phy_device *phydev)
+ {
+ 	return __phy_read(phydev, RTL821x_PAGE_SELECT);
+@@ -72,6 +80,28 @@ static int rtl821x_write_page(struct phy
+ 	return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
+ }
+ 
++static int rtl821x_probe(struct phy_device *phydev)
++{
++	struct device *dev = &phydev->mdio.dev;
++	struct rtl821x_priv *priv;
++
++	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	priv->phycr2 = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR2);
++	if (priv->phycr2 < 0)
++		return priv->phycr2;
++
++	priv->phycr2 &= RTL8211F_CLKOUT_EN;
++	if (of_property_read_bool(dev->of_node, "realtek,clkout-disable"))
++		priv->phycr2 &= ~RTL8211F_CLKOUT_EN;
++
++	phydev->priv = priv;
++
++	return 0;
++}
++
+ static int rtl8201_ack_interrupt(struct phy_device *phydev)
+ {
+ 	int err;
+@@ -180,6 +210,7 @@ static int rtl8211c_config_init(struct p
+ 
+ static int rtl8211f_config_init(struct phy_device *phydev)
+ {
++	struct rtl821x_priv *priv = phydev->priv;
+ 	struct device *dev = &phydev->mdio.dev;
+ 	u16 val_txdly, val_rxdly;
+ 	u16 val;
+@@ -243,7 +274,15 @@ static int rtl8211f_config_init(struct p
+ 			val_rxdly ? "enabled" : "disabled");
+ 	}
+ 
+-	return 0;
++	ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2,
++			       RTL8211F_CLKOUT_EN, priv->phycr2);
++	if (ret < 0) {
++		dev_err(dev, "clkout configuration failed: %pe\n",
++			ERR_PTR(ret));
++		return ret;
++	}
++
++	return genphy_soft_reset(phydev);
+ }
+ 
+ static int rtl821x_resume(struct phy_device *phydev)
+@@ -633,6 +672,7 @@ static struct phy_driver realtek_drvs[]
+ 	}, {
+ 		PHY_ID_MATCH_EXACT(0x001cc916),
+ 		.name		= "RTL8211F Gigabit Ethernet",
++		.probe		= rtl821x_probe,
+ 		.config_init	= &rtl8211f_config_init,
+ 		.ack_interrupt	= &rtl8211f_ack_interrupt,
+ 		.config_intr	= &rtl8211f_config_intr,




More information about the lede-commits mailing list