[][kernel][mt7988][eth][Refactor USXGMII reset sequence]
[Description]
Refactor USXGMII reset sequence.
If without this patch, SGMII might be reset as well when resetting USXGMII.
[Release-log]
N/A
Change-Id: I7bef3a542b06c2beb339f117fc27a40cacac3bf0
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7267722
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 5b860d6..32b7f6b 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
@@ -923,6 +923,8 @@
#define SWSYSRST_XFI_PLL_GRST BIT(16)
#define SWSYSRST_XFI_PEXPT1_GRST BIT(15)
#define SWSYSRST_XFI_PEXPT0_GRST BIT(14)
+#define SWSYSRST_XFI1_GRST BIT(13)
+#define SWSYSRST_XFI0_GRST BIT(12)
#define SWSYSRST_SGMII1_GRST BIT(2)
#define SWSYSRST_SGMII0_GRST BIT(1)
#define TOPRGU_SWSYSRST_EN 0xFC
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
index 4a936ec..8fb28ca 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
@@ -466,24 +466,69 @@
{
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:
- regmap_update_bits(eth->toprgu, 0xFC, GENMASK(31, 0), 0x0000A004);
- regmap_update_bits(eth->toprgu, 0x18, GENMASK(31, 0), 0x88F0A004);
- regmap_update_bits(eth->toprgu, 0xFC, GENMASK(31, 0), 0x00000000);
- regmap_update_bits(eth->toprgu, 0x18, GENMASK(31, 0), 0x88F00000);
- regmap_update_bits(eth->toprgu, 0x18, GENMASK(31, 0), 0x00F00000);
+ /* Enable software reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+ val |= SWSYSRST_XFI_PEXPT1_GRST |
+ SWSYSRST_XFI1_GRST;
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+
+ /* Assert USXGMII reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
+ SWSYSRST_XFI_PEXPT1_GRST |
+ SWSYSRST_XFI1_GRST;
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+ udelay(100);
+
+ /* De-assert USXGMII reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
+ val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
+ SWSYSRST_XFI1_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_XFI1_GRST);
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
break;
case MTK_GMAC3_ID:
- regmap_update_bits(eth->toprgu, 0xFC, GENMASK(31, 0), 0x00005002);
- regmap_update_bits(eth->toprgu, 0x18, GENMASK(31, 0), 0x88F05002);
- regmap_update_bits(eth->toprgu, 0xFC, GENMASK(31, 0), 0x00000000);
- regmap_update_bits(eth->toprgu, 0x18, GENMASK(31, 0), 0x88F00000);
- regmap_update_bits(eth->toprgu, 0x18, GENMASK(31, 0), 0x00F00000);
+ /* Enable software reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
+ val |= SWSYSRST_XFI_PEXPT0_GRST |
+ SWSYSRST_XFI0_GRST;
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
+
+ /* Assert USXGMII reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
+ SWSYSRST_XFI_PEXPT0_GRST |
+ SWSYSRST_XFI0_GRST;
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
+
+ udelay(100);
+
+ /* De-assert USXGMII reset */
+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
+ val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
+ SWSYSRST_XFI0_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_XFI0_GRST);
+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
break;
}