diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index e0064276d02..064b4a41db3 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -103,6 +103,8 @@ struct mtk_eth_priv { struct regmap *ethsys_regmap; + struct regmap *infra_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); @@ -186,6 +188,17 @@ static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, regmap_write(priv->ethsys_regmap, reg, val); } +static void mtk_infra_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, + u32 set) +{ + uint val; + + regmap_read(priv->infra_regmap, reg, &val); + val &= ~clr; + val |= set; + regmap_write(priv->infra_regmap, reg, val); +} + /* 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) @@ -1139,6 +1152,11 @@ static void mtk_mac_init(struct mtk_eth_priv *priv) break; case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_2500BASEX: + if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC2_U3_QPHY)) { + mtk_infra_rmw(priv, USB_PHY_SWITCH_REG, QPHY_SEL_MASK, + SGMII_QPHY_SEL); + } + ge_mode = GE_MODE_RGMII; mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG, SYSCFG0_SGMII_SEL_M, SYSCFG0_SGMII_SEL(priv->gmac_id)); @@ -1497,6 +1515,19 @@ static int mtk_eth_of_to_plat(struct udevice *dev) if (IS_ERR(priv->ethsys_regmap)) return PTR_ERR(priv->ethsys_regmap); + if (MTK_HAS_CAPS(priv->soc->caps, MTK_INFRA)) { + /* get corresponding infracfg phandle */ + ret = dev_read_phandle_with_args(dev, "mediatek,infracfg", + NULL, 0, 0, &args); + + if (ret) + return ret; + + priv->infra_regmap = syscon_node_to_regmap(args.node); + if (IS_ERR(priv->infra_regmap)) + return PTR_ERR(priv->infra_regmap); + } + /* Reset controllers */ ret = reset_get_by_name(dev, "fe", &priv->rst_fe); if (ret) { @@ -1614,7 +1645,7 @@ static const struct mtk_soc_data mt7986_data = { }; static const struct mtk_soc_data mt7981_data = { - .caps = MT7986_CAPS, + .caps = MT7981_CAPS, .ana_rgc3 = 0x128, .pdma_base = PDMA_V2_BASE, .txd_size = sizeof(struct mtk_tx_dma_v2), diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h index 320266cd82a..519986c01e7 100644 --- a/drivers/net/mtk_eth.h +++ b/drivers/net/mtk_eth.h @@ -15,27 +15,38 @@ enum mkt_eth_capabilities { MTK_TRGMII_BIT, MTK_TRGMII_MT7621_CLK_BIT, + MTK_U3_COPHY_V2_BIT, + MTK_INFRA_BIT, MTK_NETSYS_V2_BIT, /* PATH BITS */ MTK_ETH_PATH_GMAC1_TRGMII_BIT, + MTK_ETH_PATH_GMAC2_SGMII_BIT, }; #define MTK_TRGMII BIT(MTK_TRGMII_BIT) #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) +#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) +#define MTK_INFRA BIT(MTK_INFRA_BIT) #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) /* Supported path present on SoCs */ #define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT) +#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT) + #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) +#define MTK_GMAC2_U3_QPHY (MTK_ETH_PATH_GMAC2_SGMII | MTK_U3_COPHY_V2 | MTK_INFRA) + #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) #define MT7621_CAPS (MTK_GMAC1_TRGMII | MTK_TRGMII_MT7621_CLK) #define MT7623_CAPS (MTK_GMAC1_TRGMII) +#define MT7981_CAPS (MTK_GMAC2_U3_QPHY | MTK_NETSYS_V2) + #define MT7986_CAPS (MTK_NETSYS_V2) /* Frame Engine Register Bases */ @@ -56,6 +67,11 @@ enum mkt_eth_capabilities { #define ETHSYS_CLKCFG0_REG 0x2c #define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11) +/* Top misc registers */ +#define USB_PHY_SWITCH_REG 0x218 +#define QPHY_SEL_MASK 0x3 +#define SGMII_QPHY_SEL 0x2 + /* SYSCFG0_GE_MODE: GE Modes */ #define GE_MODE_RGMII 0 #define GE_MODE_MII 1