diff options
Diffstat (limited to 'package/boot/uboot-mediatek/patches/101-26-net-mediatek-add-support-for-MediaTek-MT7988-SoC.patch')
-rw-r--r-- | package/boot/uboot-mediatek/patches/101-26-net-mediatek-add-support-for-MediaTek-MT7988-SoC.patch | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/package/boot/uboot-mediatek/patches/101-26-net-mediatek-add-support-for-MediaTek-MT7988-SoC.patch b/package/boot/uboot-mediatek/patches/101-26-net-mediatek-add-support-for-MediaTek-MT7988-SoC.patch new file mode 100644 index 0000000000..29e8649052 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/101-26-net-mediatek-add-support-for-MediaTek-MT7988-SoC.patch @@ -0,0 +1,327 @@ +From 59dba9d87c9caf04a5d797af46699055a53870f4 Mon Sep 17 00:00:00 2001 +From: Weijie Gao <weijie.gao@mediatek.com> +Date: Wed, 19 Jul 2023 17:17:41 +0800 +Subject: [PATCH 26/29] net: mediatek: add support for MediaTek MT7988 SoC + +This patch adds support for MediaTek MT7988. + +MT7988 features MediaTek NETSYS v3, including three GMACs, and two +of them supports 10Gbps USXGMII. + +MT7988 embeds a MT7531 switch (not MCM) which supports accessing +internal registers through MMIO instead of MDIO. + +Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> +--- + drivers/net/mtk_eth.c | 158 +++++++++++++++++++++++++++++++++++++++++- + drivers/net/mtk_eth.h | 20 ++++++ + 2 files changed, 177 insertions(+), 1 deletion(-) + +--- a/drivers/net/mtk_eth.c ++++ b/drivers/net/mtk_eth.c +@@ -54,6 +54,16 @@ + (DP_PDMA << MC_DP_S) | \ + (DP_PDMA << UN_DP_S)) + ++#define GDMA_BRIDGE_TO_CPU \ ++ (0xC0000000 | \ ++ GDM_ICS_EN | \ ++ GDM_TCS_EN | \ ++ GDM_UCS_EN | \ ++ (DP_PDMA << MYMAC_DP_S) | \ ++ (DP_PDMA << BC_DP_S) | \ ++ (DP_PDMA << MC_DP_S) | \ ++ (DP_PDMA << UN_DP_S)) ++ + #define GDMA_FWD_DISCARD \ + (0x20000000 | \ + GDM_ICS_EN | \ +@@ -68,7 +78,8 @@ + enum mtk_switch { + SW_NONE, + SW_MT7530, +- SW_MT7531 ++ SW_MT7531, ++ SW_MT7988, + }; + + /* struct mtk_soc_data - This is the structure holding all differences +@@ -102,6 +113,7 @@ struct mtk_eth_priv { + void __iomem *fe_base; + void __iomem *gmac_base; + void __iomem *sgmii_base; ++ void __iomem *gsw_base; + + struct regmap *ethsys_regmap; + +@@ -171,6 +183,11 @@ static void mtk_gdma_write(struct mtk_et + writel(val, priv->fe_base + gdma_base + reg); + } + ++static void mtk_fe_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) ++{ ++ clrsetbits_le32(priv->fe_base + reg, clr, set); ++} ++ + static u32 mtk_gmac_read(struct mtk_eth_priv *priv, u32 reg) + { + return readl(priv->gmac_base + reg); +@@ -208,6 +225,16 @@ static void mtk_infra_rmw(struct mtk_eth + regmap_write(priv->infra_regmap, reg, val); + } + ++static u32 mtk_gsw_read(struct mtk_eth_priv *priv, u32 reg) ++{ ++ return readl(priv->gsw_base + reg); ++} ++ ++static void mtk_gsw_write(struct mtk_eth_priv *priv, u32 reg, u32 val) ++{ ++ writel(val, priv->gsw_base + reg); ++} ++ + /* Direct MDIO clause 22/45 access via SoC */ + static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data, + u32 cmd, u32 st) +@@ -342,6 +369,11 @@ static int mt753x_reg_read(struct mtk_et + { + int ret, low_word, high_word; + ++ if (priv->sw == SW_MT7988) { ++ *data = mtk_gsw_read(priv, reg); ++ return 0; ++ } ++ + /* Write page address */ + ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6); + if (ret) +@@ -367,6 +399,11 @@ static int mt753x_reg_write(struct mtk_e + { + int ret; + ++ if (priv->sw == SW_MT7988) { ++ mtk_gsw_write(priv, reg, data); ++ return 0; ++ } ++ + /* Write page address */ + ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6); + if (ret) +@@ -537,6 +574,7 @@ static int mtk_mdio_register(struct udev + priv->mmd_write = mtk_mmd_ind_write; + break; + case SW_MT7531: ++ case SW_MT7988: + priv->mii_read = mt7531_mii_ind_read; + priv->mii_write = mt7531_mii_ind_write; + priv->mmd_read = mt7531_mmd_ind_read; +@@ -957,6 +995,103 @@ static int mt7531_setup(struct mtk_eth_p + return 0; + } + ++static void mt7988_phy_setting(struct mtk_eth_priv *priv) ++{ ++ u16 val; ++ u32 i; ++ ++ for (i = 0; i < MT753X_NUM_PHYS; i++) { ++ /* Enable HW auto downshift */ ++ priv->mii_write(priv, i, 0x1f, 0x1); ++ val = priv->mii_read(priv, i, PHY_EXT_REG_14); ++ val |= PHY_EN_DOWN_SHFIT; ++ priv->mii_write(priv, i, PHY_EXT_REG_14, val); ++ ++ /* PHY link down power saving enable */ ++ val = priv->mii_read(priv, i, PHY_EXT_REG_17); ++ val |= PHY_LINKDOWN_POWER_SAVING_EN; ++ priv->mii_write(priv, i, PHY_EXT_REG_17, val); ++ } ++} ++ ++static void mt7988_mac_control(struct mtk_eth_priv *priv, bool enable) ++{ ++ u32 pmcr = FORCE_MODE_LNK; ++ ++ if (enable) ++ pmcr = priv->mt753x_pmcr; ++ ++ mt753x_reg_write(priv, PMCR_REG(6), pmcr); ++} ++ ++static int mt7988_setup(struct mtk_eth_priv *priv) ++{ ++ u16 phy_addr, phy_val; ++ u32 pmcr; ++ int i; ++ ++ priv->gsw_base = regmap_get_range(priv->ethsys_regmap, 0) + GSW_BASE; ++ ++ priv->mt753x_phy_base = (priv->mt753x_smi_addr + 1) & ++ MT753X_SMI_ADDR_MASK; ++ ++ /* Turn off PHYs */ ++ for (i = 0; i < MT753X_NUM_PHYS; i++) { ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i); ++ phy_val = priv->mii_read(priv, phy_addr, MII_BMCR); ++ phy_val |= BMCR_PDOWN; ++ priv->mii_write(priv, phy_addr, MII_BMCR, phy_val); ++ } ++ ++ switch (priv->phy_interface) { ++ case PHY_INTERFACE_MODE_USXGMII: ++ /* Use CPU bridge instead of actual USXGMII path */ ++ ++ /* Set GDM1 no drop */ ++ mtk_fe_rmw(priv, PSE_NO_DROP_CFG_REG, 0, PSE_NO_DROP_GDM1); ++ ++ /* Enable GDM1 to GSW CPU bridge */ ++ mtk_gmac_rmw(priv, GMAC_MAC_MISC_REG, 0, BIT(0)); ++ ++ /* XGMAC force link up */ ++ mtk_gmac_rmw(priv, GMAC_XGMAC_STS_REG, 0, P1_XGMAC_FORCE_LINK); ++ ++ /* Setup GSW CPU bridge IPG */ ++ mtk_gmac_rmw(priv, GMAC_GSW_CFG_REG, GSWTX_IPG_M | GSWRX_IPG_M, ++ (0xB << GSWTX_IPG_S) | (0xB << GSWRX_IPG_S)); ++ break; ++ default: ++ printf("Error: MT7988 GSW does not support %s interface\n", ++ phy_string_for_interface(priv->phy_interface)); ++ break; ++ } ++ ++ pmcr = MT7988_FORCE_MODE | ++ (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | ++ MAC_MODE | MAC_TX_EN | MAC_RX_EN | ++ BKOFF_EN | BACKPR_EN | ++ FORCE_RX_FC | FORCE_TX_FC | ++ (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX | ++ FORCE_LINK; ++ ++ priv->mt753x_pmcr = pmcr; ++ ++ /* Keep MAC link down before starting eth */ ++ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK); ++ ++ /* Turn on PHYs */ ++ for (i = 0; i < MT753X_NUM_PHYS; i++) { ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i); ++ phy_val = priv->mii_read(priv, phy_addr, MII_BMCR); ++ phy_val &= ~BMCR_PDOWN; ++ priv->mii_write(priv, phy_addr, MII_BMCR, phy_val); ++ } ++ ++ mt7988_phy_setting(priv); ++ ++ return 0; ++} ++ + static int mt753x_switch_init(struct mtk_eth_priv *priv) + { + int ret; +@@ -1497,6 +1632,11 @@ static int mtk_eth_start(struct udevice + } + + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3)) { ++ if (priv->sw == SW_MT7988 && priv->gmac_id == 0) { ++ mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, ++ GDMA_BRIDGE_TO_CPU); ++ } ++ + mtk_gdma_write(priv, priv->gmac_id, GDMA_EG_CTRL_REG, + GDMA_CPU_BRIDGE_EN); + } +@@ -1845,6 +1985,12 @@ static int mtk_eth_of_to_plat(struct ude + priv->switch_mac_control = mt7531_mac_control; + priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR; + priv->mt753x_reset_wait_time = 200; ++ } else if (!strcmp(str, "mt7988")) { ++ priv->sw = SW_MT7988; ++ priv->switch_init = mt7988_setup; ++ priv->switch_mac_control = mt7988_mac_control; ++ priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR; ++ priv->mt753x_reset_wait_time = 50; + } else { + printf("error: unsupported switch\n"); + return -EINVAL; +@@ -1879,6 +2025,15 @@ static int mtk_eth_of_to_plat(struct ude + return 0; + } + ++static const struct mtk_soc_data mt7988_data = { ++ .caps = MT7988_CAPS, ++ .ana_rgc3 = 0x128, ++ .gdma_count = 3, ++ .pdma_base = PDMA_V3_BASE, ++ .txd_size = sizeof(struct mtk_tx_dma_v2), ++ .rxd_size = sizeof(struct mtk_rx_dma_v2), ++}; ++ + static const struct mtk_soc_data mt7986_data = { + .caps = MT7986_CAPS, + .ana_rgc3 = 0x128, +@@ -1930,6 +2085,7 @@ static const struct mtk_soc_data mt7621_ + }; + + static const struct udevice_id mtk_eth_ids[] = { ++ { .compatible = "mediatek,mt7988-eth", .data = (ulong)&mt7988_data }, + { .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data }, + { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data }, + { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data }, +--- a/drivers/net/mtk_eth.h ++++ b/drivers/net/mtk_eth.h +@@ -51,6 +51,8 @@ enum mkt_eth_capabilities { + + #define MT7986_CAPS (MTK_NETSYS_V2) + ++#define MT7988_CAPS (MTK_NETSYS_V3 | MTK_INFRA) ++ + /* Frame Engine Register Bases */ + #define PDMA_V1_BASE 0x0800 + #define PDMA_V2_BASE 0x6000 +@@ -59,6 +61,7 @@ enum mkt_eth_capabilities { + #define GDMA2_BASE 0x1500 + #define GDMA3_BASE 0x0540 + #define GMAC_BASE 0x10000 ++#define GSW_BASE 0x20000 + + /* Ethernet subsystem registers */ + +@@ -117,6 +120,9 @@ enum mkt_eth_capabilities { + #define RG_XFI_PLL_ANA_SWWA 0x02283248 + + /* Frame Engine Registers */ ++#define PSE_NO_DROP_CFG_REG 0x108 ++#define PSE_NO_DROP_GDM1 BIT(1) ++ + #define FE_GLO_MISC_REG 0x124 + #define PDMA_VER_V2 BIT(4) + +@@ -187,6 +193,17 @@ enum mkt_eth_capabilities { + #define MDIO_RW_DATA_S 0 + #define MDIO_RW_DATA_M 0xffff + ++#define GMAC_XGMAC_STS_REG 0x000c ++#define P1_XGMAC_FORCE_LINK BIT(15) ++ ++#define GMAC_MAC_MISC_REG 0x0010 ++ ++#define GMAC_GSW_CFG_REG 0x0080 ++#define GSWTX_IPG_M 0xF0000 ++#define GSWTX_IPG_S 16 ++#define GSWRX_IPG_M 0xF ++#define GSWRX_IPG_S 0 ++ + /* MDIO_CMD: MDIO commands */ + #define MDIO_CMD_ADDR 0 + #define MDIO_CMD_WRITE 1 +@@ -285,6 +302,9 @@ enum mkt_eth_capabilities { + FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \ + FORCE_MODE_DPX | FORCE_MODE_SPD | \ + FORCE_MODE_LNK ++#define MT7988_FORCE_MODE FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \ ++ FORCE_MODE_DPX | FORCE_MODE_SPD | \ ++ FORCE_MODE_LNK + + /* MT7531 SGMII Registers */ + #define MT7531_SGMII_REG_BASE 0x5000 |