[][kernel][mt7988][eth][Add PHYA reset for HSGMII]
[Description]
Add PHYA reset for HSGMII.
If without this patch, HSGMII might work abnormally
which prevents GMAC from receiving packets.
[Release-log]
N/A
Change-Id: I32e041a0a05dae77220469e3ee448cfad599bc7c
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6889368
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 45b2e24..2f54f96 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -861,6 +861,16 @@
#define CO_QPHY_SEL BIT(0)
#define GEPHY_MAC_SEL BIT(1)
+/* Toprgu subsystem config registers */
+#define TOPRGU_SWSYSRST 0x18
+#define SWSYSRST_UNLOCK_KEY GENMASK(31, 24)
+#define SWSYSRST_XFI_PLL_GRST BIT(16)
+#define SWSYSRST_XFI_PEXPT1_GRST BIT(15)
+#define SWSYSRST_XFI_PEXPT0_GRST BIT(14)
+#define SWSYSRST_SGMII1_GRST BIT(2)
+#define SWSYSRST_SGMII0_GRST BIT(1)
+#define TOPRGU_SWSYSRST_EN 0xFC
+
/* Top misc registers */
#define TOP_MISC_NETSYS_PCS_MUX 0x84
#define NETSYS_PCS_MUX_MASK GENMASK(1, 0)
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
index 64a6353..ac77ef2 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -37,6 +37,79 @@
return 0;
}
+void mtk_sgmii_reset(struct mtk_xgmii *ss, int mac_id)
+{
+ struct mtk_eth *eth = ss->eth;
+ u32 id = mtk_mac2xgmii_id(eth, mac_id);
+ u32 val = 0;
+
+ if (id >= MTK_MAX_DEVS || !eth->toprgu)
+ return;
+
+ switch (mac_id) {
+ case MTK_GMAC2_ID:
+ /* Enable software reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+ val |= SWSYSRST_XFI_PEXPT1_GRST |
+ SWSYSRST_SGMII1_GRST;
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+
+ /* Assert SGMII reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
+ SWSYSRST_XFI_PEXPT1_GRST |
+ SWSYSRST_SGMII1_GRST;
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+ udelay(100);
+
+ /* De-assert SGMII reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
+ val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
+ SWSYSRST_SGMII1_GRST);
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+ /* Disable software reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+ val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
+ SWSYSRST_SGMII1_GRST);
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+ break;
+ case MTK_GMAC3_ID:
+ /* Enable Software reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+ val |= SWSYSRST_XFI_PEXPT0_GRST |
+ SWSYSRST_SGMII0_GRST;
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+
+ /* Assert SGMII reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
+ SWSYSRST_XFI_PEXPT0_GRST |
+ SWSYSRST_SGMII0_GRST;
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+ udelay(100);
+
+ /* De-assert SGMII reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
+ val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
+ SWSYSRST_SGMII0_GRST);
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+ /* Disable software reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+ val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
+ SWSYSRST_SGMII0_GRST);
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+ break;
+ }
+
+ mdelay(1);
+}
+
void mtk_sgmii_setup_phya_gen1(struct mtk_xgmii *ss, int mac_id)
{
u32 id = mtk_mac2xgmii_id(ss->eth, mac_id);
@@ -167,8 +240,10 @@
if (!ss->regmap_sgmii[id])
return -EINVAL;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
mtk_xfi_pll_enable(ss);
+ mtk_sgmii_reset(ss, mac_id);
+ }
/* Assert PHYA power down state */
regmap_write(ss->regmap_sgmii[id], SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD);
@@ -222,8 +297,10 @@
if (!ss->regmap_sgmii[id])
return -EINVAL;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
mtk_xfi_pll_enable(ss);
+ mtk_sgmii_reset(ss, mac_id);
+ }
/* Assert PHYA power down state */
regmap_write(ss->regmap_sgmii[id], SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD);