net: mediatek: add support for GMAC/USB3 PHY mux mode for MT7981
authorWeijie Gao <weijie.gao@mediatek.com>
Wed, 19 Jul 2023 09:17:22 +0000 (17:17 +0800)
committerTom Rini <trini@konsulko.com>
Thu, 3 Aug 2023 13:40:50 +0000 (09:40 -0400)
MT7981 has its GMAC2 PHY shared with USB3. To enable GMAC2, mux
register must be set to connect the SGMII phy to GMAC2.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
drivers/net/mtk_eth.c
drivers/net/mtk_eth.h

index e006427..064b4a4 100644 (file)
@@ -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),
index 320266c..519986c 100644 (file)
 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