From b7e9445d6dcea9c4a6cd5f017a797ccc269c8c7a Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 22 Jul 2023 18:55:32 +0100 Subject: uboot-mediatek: add patches for MT7988 and builds for RFB Import pending patches adding support for MT7988 and provide builds for the reference board for all possible boot media. Signed-off-by: Daniel Golle --- .../101-24-net-mediatek-add-USXGMII-support.patch | 341 +++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 package/boot/uboot-mediatek/patches/101-24-net-mediatek-add-USXGMII-support.patch (limited to 'package/boot/uboot-mediatek/patches/101-24-net-mediatek-add-USXGMII-support.patch') diff --git a/package/boot/uboot-mediatek/patches/101-24-net-mediatek-add-USXGMII-support.patch b/package/boot/uboot-mediatek/patches/101-24-net-mediatek-add-USXGMII-support.patch new file mode 100644 index 0000000000..67288c749e --- /dev/null +++ b/package/boot/uboot-mediatek/patches/101-24-net-mediatek-add-USXGMII-support.patch @@ -0,0 +1,341 @@ +From d62b483092035bc86d1db83ea4ac29bfa7bba77d Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 19 Jul 2023 17:17:31 +0800 +Subject: [PATCH 24/29] net: mediatek: add USXGMII support + +This patch adds support for USXGMII of SoC. + +Signed-off-by: Weijie Gao +--- + drivers/net/mtk_eth.c | 230 +++++++++++++++++++++++++++++++++++++++++- + drivers/net/mtk_eth.h | 24 +++++ + 2 files changed, 251 insertions(+), 3 deletions(-) + +--- a/drivers/net/mtk_eth.c ++++ b/drivers/net/mtk_eth.c +@@ -105,6 +105,11 @@ struct mtk_eth_priv { + + struct regmap *infra_regmap; + ++ struct regmap *usxgmii_regmap; ++ struct regmap *xfi_pextp_regmap; ++ struct regmap *xfi_pll_regmap; ++ struct regmap *toprgu_regmap; ++ + struct mii_dev *mdio_bus; + int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg); + int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val); +@@ -989,6 +994,42 @@ static int mt753x_switch_init(struct mtk + return 0; + } + ++static void mtk_xphy_link_adjust(struct mtk_eth_priv *priv) ++{ ++ u16 lcl_adv = 0, rmt_adv = 0; ++ u8 flowctrl; ++ u32 mcr; ++ ++ mcr = mtk_gmac_read(priv, XGMAC_PORT_MCR(priv->gmac_id)); ++ mcr &= ~(XGMAC_FORCE_TX_FC | XGMAC_FORCE_RX_FC); ++ ++ if (priv->phydev->duplex) { ++ if (priv->phydev->pause) ++ rmt_adv = LPA_PAUSE_CAP; ++ if (priv->phydev->asym_pause) ++ rmt_adv |= LPA_PAUSE_ASYM; ++ ++ if (priv->phydev->advertising & ADVERTISED_Pause) ++ lcl_adv |= ADVERTISE_PAUSE_CAP; ++ if (priv->phydev->advertising & ADVERTISED_Asym_Pause) ++ lcl_adv |= ADVERTISE_PAUSE_ASYM; ++ ++ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); ++ ++ if (flowctrl & FLOW_CTRL_TX) ++ mcr |= XGMAC_FORCE_TX_FC; ++ if (flowctrl & FLOW_CTRL_RX) ++ mcr |= XGMAC_FORCE_RX_FC; ++ ++ debug("rx pause %s, tx pause %s\n", ++ flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled", ++ flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled"); ++ } ++ ++ mcr &= ~(XGMAC_TRX_DISABLE); ++ mtk_gmac_write(priv, XGMAC_PORT_MCR(priv->gmac_id), mcr); ++} ++ + static void mtk_phy_link_adjust(struct mtk_eth_priv *priv) + { + u16 lcl_adv = 0, rmt_adv = 0; +@@ -1063,8 +1104,12 @@ static int mtk_phy_start(struct mtk_eth_ + return 0; + } + +- if (!priv->force_mode) +- mtk_phy_link_adjust(priv); ++ if (!priv->force_mode) { ++ if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII) ++ mtk_xphy_link_adjust(priv); ++ else ++ mtk_phy_link_adjust(priv); ++ } + + debug("Speed: %d, %s duplex%s\n", phydev->speed, + (phydev->duplex) ? "full" : "half", +@@ -1140,6 +1185,112 @@ static void mtk_sgmii_force_init(struct + SGMII_PHYA_PWD, 0); + } + ++static void mtk_xfi_pll_enable(struct mtk_eth_priv *priv) ++{ ++ u32 val = 0; ++ ++ /* Add software workaround for USXGMII PLL TCL issue */ ++ regmap_write(priv->xfi_pll_regmap, XFI_PLL_ANA_GLB8, ++ RG_XFI_PLL_ANA_SWWA); ++ ++ regmap_read(priv->xfi_pll_regmap, XFI_PLL_DIG_GLB8, &val); ++ val |= RG_XFI_PLL_EN; ++ regmap_write(priv->xfi_pll_regmap, XFI_PLL_DIG_GLB8, val); ++} ++ ++static void mtk_usxgmii_reset(struct mtk_eth_priv *priv) ++{ ++ switch (priv->gmac_id) { ++ case 1: ++ regmap_write(priv->toprgu_regmap, 0xFC, 0x0000A004); ++ regmap_write(priv->toprgu_regmap, 0x18, 0x88F0A004); ++ regmap_write(priv->toprgu_regmap, 0xFC, 0x00000000); ++ regmap_write(priv->toprgu_regmap, 0x18, 0x88F00000); ++ regmap_write(priv->toprgu_regmap, 0x18, 0x00F00000); ++ break; ++ case 2: ++ regmap_write(priv->toprgu_regmap, 0xFC, 0x00005002); ++ regmap_write(priv->toprgu_regmap, 0x18, 0x88F05002); ++ regmap_write(priv->toprgu_regmap, 0xFC, 0x00000000); ++ regmap_write(priv->toprgu_regmap, 0x18, 0x88F00000); ++ regmap_write(priv->toprgu_regmap, 0x18, 0x00F00000); ++ break; ++ } ++ ++ mdelay(10); ++} ++ ++static void mtk_usxgmii_setup_phya_an_10000(struct mtk_eth_priv *priv) ++{ ++ regmap_write(priv->usxgmii_regmap, 0x810, 0x000FFE6D); ++ regmap_write(priv->usxgmii_regmap, 0x818, 0x07B1EC7B); ++ regmap_write(priv->usxgmii_regmap, 0x80C, 0x30000000); ++ ndelay(1020); ++ regmap_write(priv->usxgmii_regmap, 0x80C, 0x10000000); ++ ndelay(1020); ++ regmap_write(priv->usxgmii_regmap, 0x80C, 0x00000000); ++ ++ regmap_write(priv->xfi_pextp_regmap, 0x9024, 0x00C9071C); ++ regmap_write(priv->xfi_pextp_regmap, 0x2020, 0xAA8585AA); ++ regmap_write(priv->xfi_pextp_regmap, 0x2030, 0x0C020707); ++ regmap_write(priv->xfi_pextp_regmap, 0x2034, 0x0E050F0F); ++ regmap_write(priv->xfi_pextp_regmap, 0x2040, 0x00140032); ++ regmap_write(priv->xfi_pextp_regmap, 0x50F0, 0x00C014AA); ++ regmap_write(priv->xfi_pextp_regmap, 0x50E0, 0x3777C12B); ++ regmap_write(priv->xfi_pextp_regmap, 0x506C, 0x005F9CFF); ++ regmap_write(priv->xfi_pextp_regmap, 0x5070, 0x9D9DFAFA); ++ regmap_write(priv->xfi_pextp_regmap, 0x5074, 0x27273F3F); ++ regmap_write(priv->xfi_pextp_regmap, 0x5078, 0xA7883C68); ++ regmap_write(priv->xfi_pextp_regmap, 0x507C, 0x11661166); ++ regmap_write(priv->xfi_pextp_regmap, 0x5080, 0x0E000AAF); ++ regmap_write(priv->xfi_pextp_regmap, 0x5084, 0x08080D0D); ++ regmap_write(priv->xfi_pextp_regmap, 0x5088, 0x02030909); ++ regmap_write(priv->xfi_pextp_regmap, 0x50E4, 0x0C0C0000); ++ regmap_write(priv->xfi_pextp_regmap, 0x50E8, 0x04040000); ++ regmap_write(priv->xfi_pextp_regmap, 0x50EC, 0x0F0F0C06); ++ regmap_write(priv->xfi_pextp_regmap, 0x50A8, 0x506E8C8C); ++ regmap_write(priv->xfi_pextp_regmap, 0x6004, 0x18190000); ++ regmap_write(priv->xfi_pextp_regmap, 0x00F8, 0x01423342); ++ regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F20); ++ regmap_write(priv->xfi_pextp_regmap, 0x0030, 0x00050C00); ++ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x02002800); ++ ndelay(1020); ++ regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000020); ++ regmap_write(priv->xfi_pextp_regmap, 0x3028, 0x00008A01); ++ regmap_write(priv->xfi_pextp_regmap, 0x302C, 0x0000A884); ++ regmap_write(priv->xfi_pextp_regmap, 0x3024, 0x00083002); ++ regmap_write(priv->xfi_pextp_regmap, 0x3010, 0x00022220); ++ regmap_write(priv->xfi_pextp_regmap, 0x5064, 0x0F020A01); ++ regmap_write(priv->xfi_pextp_regmap, 0x50B4, 0x06100600); ++ regmap_write(priv->xfi_pextp_regmap, 0x3048, 0x40704000); ++ regmap_write(priv->xfi_pextp_regmap, 0x3050, 0xA8000000); ++ regmap_write(priv->xfi_pextp_regmap, 0x3054, 0x000000AA); ++ regmap_write(priv->xfi_pextp_regmap, 0x306C, 0x00000F00); ++ regmap_write(priv->xfi_pextp_regmap, 0xA060, 0x00040000); ++ regmap_write(priv->xfi_pextp_regmap, 0x90D0, 0x00000001); ++ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200E800); ++ udelay(150); ++ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C111); ++ ndelay(1020); ++ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0200C101); ++ udelay(15); ++ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C111); ++ ndelay(1020); ++ regmap_write(priv->xfi_pextp_regmap, 0x0070, 0x0202C101); ++ udelay(100); ++ regmap_write(priv->xfi_pextp_regmap, 0x30B0, 0x00000030); ++ regmap_write(priv->xfi_pextp_regmap, 0x00F4, 0x80201F00); ++ regmap_write(priv->xfi_pextp_regmap, 0x3040, 0x30000000); ++ udelay(400); ++} ++ ++static void mtk_usxgmii_an_init(struct mtk_eth_priv *priv) ++{ ++ mtk_xfi_pll_enable(priv); ++ mtk_usxgmii_reset(priv); ++ mtk_usxgmii_setup_phya_an_10000(priv); ++} ++ + static void mtk_mac_init(struct mtk_eth_priv *priv) + { + int i, ge_mode = 0; +@@ -1222,6 +1373,36 @@ static void mtk_mac_init(struct mtk_eth_ + } + } + ++static void mtk_xmac_init(struct mtk_eth_priv *priv) ++{ ++ u32 sts; ++ ++ switch (priv->phy_interface) { ++ case PHY_INTERFACE_MODE_USXGMII: ++ mtk_usxgmii_an_init(priv); ++ break; ++ default: ++ break; ++ } ++ ++ /* Set GMAC to the correct mode */ ++ mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG, ++ SYSCFG0_GE_MODE_M << SYSCFG0_GE_MODE_S(priv->gmac_id), ++ 0); ++ ++ if (priv->gmac_id == 1) { ++ mtk_infra_rmw(priv, TOPMISC_NETSYS_PCS_MUX, ++ NETSYS_PCS_MUX_MASK, MUX_G2_USXGMII_SEL); ++ } else if (priv->gmac_id == 2) { ++ sts = mtk_gmac_read(priv, XGMAC_STS(priv->gmac_id)); ++ sts |= XGMAC_FORCE_LINK; ++ mtk_gmac_write(priv, XGMAC_STS(priv->gmac_id), sts); ++ } ++ ++ /* Force GMAC link down */ ++ mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), FORCE_MODE); ++} ++ + static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) + { + char *pkt_base = priv->pkt_pool; +@@ -1463,7 +1644,10 @@ static int mtk_eth_probe(struct udevice + ARCH_DMA_MINALIGN); + + /* Set MAC mode */ +- mtk_mac_init(priv); ++ if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII) ++ mtk_xmac_init(priv); ++ else ++ mtk_mac_init(priv); + + /* Probe phy if switch is not specified */ + if (priv->sw == SW_NONE) +@@ -1581,6 +1765,46 @@ static int mtk_eth_of_to_plat(struct ude + } + + priv->pn_swap = ofnode_read_bool(args.node, "pn_swap"); ++ } else if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII) { ++ /* get corresponding usxgmii phandle */ ++ ret = dev_read_phandle_with_args(dev, "mediatek,usxgmiisys", ++ NULL, 0, 0, &args); ++ if (ret) ++ return ret; ++ ++ priv->usxgmii_regmap = syscon_node_to_regmap(args.node); ++ if (IS_ERR(priv->usxgmii_regmap)) ++ return PTR_ERR(priv->usxgmii_regmap); ++ ++ /* get corresponding xfi_pextp phandle */ ++ ret = dev_read_phandle_with_args(dev, "mediatek,xfi_pextp", ++ NULL, 0, 0, &args); ++ if (ret) ++ return ret; ++ ++ priv->xfi_pextp_regmap = syscon_node_to_regmap(args.node); ++ if (IS_ERR(priv->xfi_pextp_regmap)) ++ return PTR_ERR(priv->xfi_pextp_regmap); ++ ++ /* get corresponding xfi_pll phandle */ ++ ret = dev_read_phandle_with_args(dev, "mediatek,xfi_pll", ++ NULL, 0, 0, &args); ++ if (ret) ++ return ret; ++ ++ priv->xfi_pll_regmap = syscon_node_to_regmap(args.node); ++ if (IS_ERR(priv->xfi_pll_regmap)) ++ return PTR_ERR(priv->xfi_pll_regmap); ++ ++ /* get corresponding toprgu phandle */ ++ ret = dev_read_phandle_with_args(dev, "mediatek,toprgu", ++ NULL, 0, 0, &args); ++ if (ret) ++ return ret; ++ ++ priv->toprgu_regmap = syscon_node_to_regmap(args.node); ++ if (IS_ERR(priv->toprgu_regmap)) ++ return PTR_ERR(priv->toprgu_regmap); + } + + /* check for switch first, otherwise phy will be used */ +--- a/drivers/net/mtk_eth.h ++++ b/drivers/net/mtk_eth.h +@@ -68,6 +68,11 @@ enum mkt_eth_capabilities { + #define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11) + + /* Top misc registers */ ++#define TOPMISC_NETSYS_PCS_MUX 0x84 ++#define NETSYS_PCS_MUX_MASK GENMASK(1, 0) ++#define MUX_G2_USXGMII_SEL BIT(1) ++#define MUX_HSGMII1_G1_SEL BIT(0) ++ + #define USB_PHY_SWITCH_REG 0x218 + #define QPHY_SEL_MASK 0x3 + #define SGMII_QPHY_SEL 0x2 +@@ -98,6 +103,15 @@ enum mkt_eth_capabilities { + #define SGMSYS_GEN2_SPEED_V2 0x128 + #define SGMSYS_SPEED_2500 BIT(2) + ++/* USXGMII subsystem config registers */ ++/* Register to control USXGMII XFI PLL digital */ ++#define XFI_PLL_DIG_GLB8 0x08 ++#define RG_XFI_PLL_EN BIT(31) ++ ++/* Register to control USXGMII XFI PLL analog */ ++#define XFI_PLL_ANA_GLB8 0x108 ++#define RG_XFI_PLL_ANA_SWWA 0x02283248 ++ + /* Frame Engine Registers */ + #define FE_GLO_MISC_REG 0x124 + #define PDMA_VER_V2 BIT(4) +@@ -221,6 +235,16 @@ enum mkt_eth_capabilities { + #define TD_DM_DRVP_S 0 + #define TD_DM_DRVP_M 0x0f + ++/* XGMAC Status Registers */ ++#define XGMAC_STS(x) (((x) == 2) ? 0x001C : 0x000C) ++#define XGMAC_FORCE_LINK BIT(15) ++ ++/* XGMAC Registers */ ++#define XGMAC_PORT_MCR(x) (0x2000 + (((x) - 1) * 0x1000)) ++#define XGMAC_TRX_DISABLE 0xf ++#define XGMAC_FORCE_TX_FC BIT(5) ++#define XGMAC_FORCE_RX_FC BIT(4) ++ + /* MT7530 Registers */ + + #define PCR_REG(p) (0x2004 + (p) * 0x100) -- cgit v1.2.3