2023-02-14 23:25:19 +00:00
|
|
|
From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Alexander Couzens <lynxis@fe80.eu>
|
|
|
|
Date: Wed, 1 Feb 2023 19:23:29 +0100
|
2023-03-27 15:02:44 +00:00
|
|
|
Subject: [PATCH 11/13] net: mediatek: sgmii: ensure the SGMII PHY is powered
|
|
|
|
down on configuration
|
2023-02-14 23:25:19 +00:00
|
|
|
MIME-Version: 1.0
|
|
|
|
Content-Type: text/plain; charset=UTF-8
|
|
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
|
|
|
|
The code expect the PHY to be in power down which is only true after reset.
|
|
|
|
Allow changes of the SGMII parameters more than once.
|
|
|
|
|
|
|
|
Only power down when reconfiguring to avoid bouncing the link when there's
|
|
|
|
no reason to - based on code from Russell King.
|
|
|
|
|
|
|
|
There are cases when the SGMII_PHYA_PWD register contains 0x9 which
|
|
|
|
prevents SGMII from working. The SGMII still shows link but no traffic
|
|
|
|
can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
|
|
|
|
taken from a good working state of the SGMII interface.
|
|
|
|
|
|
|
|
Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC")
|
|
|
|
Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
|
|
|
|
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
|
|
|
[ bmork: rebased and squashed into one patch ]
|
|
|
|
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
|
|
|
Signed-off-by: Bjørn Mork <bjorn@mork.no>
|
|
|
|
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
|
|
|
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
|
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
|
|
---
|
|
|
|
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
|
|
|
|
drivers/net/ethernet/mediatek/mtk_sgmii.c | 39 +++++++++++++++------
|
|
|
|
2 files changed, 30 insertions(+), 11 deletions(-)
|
|
|
|
|
|
|
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
|
|
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
2023-03-27 15:02:44 +00:00
|
|
|
@@ -1070,11 +1070,13 @@ struct mtk_soc_data {
|
2023-02-14 23:25:19 +00:00
|
|
|
* @regmap: The register map pointing at the range used to setup
|
|
|
|
* SGMII modes
|
|
|
|
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
|
|
|
|
+ * @interface: Currently configured interface mode
|
|
|
|
* @pcs: Phylink PCS structure
|
|
|
|
*/
|
|
|
|
struct mtk_pcs {
|
|
|
|
struct regmap *regmap;
|
|
|
|
u32 ana_rgc3;
|
|
|
|
+ phy_interface_t interface;
|
|
|
|
struct phylink_pcs pcs;
|
|
|
|
};
|
|
|
|
|
|
|
|
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
|
|
|
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
2023-03-27 15:02:44 +00:00
|
|
|
@@ -43,11 +43,6 @@ static int mtk_pcs_config(struct phylink
|
|
|
|
int advertise, link_timer;
|
|
|
|
bool changed, use_an;
|
2023-02-14 23:25:19 +00:00
|
|
|
|
2023-03-27 15:02:44 +00:00
|
|
|
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
|
|
|
- rgc3 = RG_PHY_SPEED_3_125G;
|
|
|
|
- else
|
|
|
|
- rgc3 = 0;
|
2023-02-14 23:25:19 +00:00
|
|
|
-
|
2023-03-27 15:02:44 +00:00
|
|
|
advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
|
|
|
|
advertising);
|
|
|
|
if (advertise < 0)
|
|
|
|
@@ -88,9 +83,22 @@ static int mtk_pcs_config(struct phylink
|
|
|
|
bmcr = 0;
|
|
|
|
}
|
2023-02-14 23:25:19 +00:00
|
|
|
|
2023-03-27 15:02:44 +00:00
|
|
|
- /* Configure the underlying interface speed */
|
|
|
|
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
|
|
|
- RG_PHY_SPEED_3_125G, rgc3);
|
2023-02-14 23:25:19 +00:00
|
|
|
+ if (mpcs->interface != interface) {
|
|
|
|
+ /* PHYA power down */
|
|
|
|
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
|
|
|
+ SGMII_PHYA_PWD, SGMII_PHYA_PWD);
|
|
|
|
+
|
2023-03-27 15:02:44 +00:00
|
|
|
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
|
|
|
+ rgc3 = RG_PHY_SPEED_3_125G;
|
|
|
|
+ else
|
|
|
|
+ rgc3 = 0;
|
|
|
|
+
|
|
|
|
+ /* Configure the underlying interface speed */
|
|
|
|
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
|
|
|
+ RG_PHY_SPEED_3_125G, rgc3);
|
|
|
|
+
|
2023-02-14 23:25:19 +00:00
|
|
|
+ mpcs->interface = interface;
|
|
|
|
+ }
|
|
|
|
|
2023-03-27 15:02:44 +00:00
|
|
|
/* Update the advertisement, noting whether it has changed */
|
|
|
|
regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
|
|
|
|
@@ -108,9 +116,17 @@ static int mtk_pcs_config(struct phylink
|
|
|
|
regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
|
|
|
SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
|
|
|
|
|
|
|
|
- /* Release PHYA power down state */
|
|
|
|
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
|
|
|
- SGMII_PHYA_PWD, 0);
|
2023-02-14 23:25:19 +00:00
|
|
|
+ /* Release PHYA power down state
|
|
|
|
+ * Only removing bit SGMII_PHYA_PWD isn't enough.
|
|
|
|
+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
|
|
|
|
+ * prevents SGMII from working. The SGMII still shows link but no traffic
|
|
|
|
+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
|
|
|
|
+ * taken from a good working state of the SGMII interface.
|
|
|
|
+ * Unknown how much the QPHY needs but it is racy without a sleep.
|
|
|
|
+ * Tested on mt7622 & mt7986.
|
|
|
|
+ */
|
|
|
|
+ usleep_range(50, 100);
|
|
|
|
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
|
|
|
|
|
2023-03-27 15:02:44 +00:00
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
@@ -171,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
2023-02-14 23:25:19 +00:00
|
|
|
return PTR_ERR(ss->pcs[i].regmap);
|
|
|
|
|
|
|
|
ss->pcs[i].pcs.ops = &mtk_pcs_ops;
|
|
|
|
+ ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|