Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2018-2019 MediaTek Inc.
0003 
0004 /* A library for configuring path from GMAC/GDM to target PHY
0005  *
0006  * Author: Sean Wang <sean.wang@mediatek.com>
0007  *
0008  */
0009 
0010 #include <linux/phy.h>
0011 #include <linux/regmap.h>
0012 
0013 #include "mtk_eth_soc.h"
0014 
0015 struct mtk_eth_muxc {
0016     const char  *name;
0017     int     cap_bit;
0018     int     (*set_path)(struct mtk_eth *eth, int path);
0019 };
0020 
0021 static const char *mtk_eth_path_name(int path)
0022 {
0023     switch (path) {
0024     case MTK_ETH_PATH_GMAC1_RGMII:
0025         return "gmac1_rgmii";
0026     case MTK_ETH_PATH_GMAC1_TRGMII:
0027         return "gmac1_trgmii";
0028     case MTK_ETH_PATH_GMAC1_SGMII:
0029         return "gmac1_sgmii";
0030     case MTK_ETH_PATH_GMAC2_RGMII:
0031         return "gmac2_rgmii";
0032     case MTK_ETH_PATH_GMAC2_SGMII:
0033         return "gmac2_sgmii";
0034     case MTK_ETH_PATH_GMAC2_GEPHY:
0035         return "gmac2_gephy";
0036     case MTK_ETH_PATH_GDM1_ESW:
0037         return "gdm1_esw";
0038     default:
0039         return "unknown path";
0040     }
0041 }
0042 
0043 static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
0044 {
0045     bool updated = true;
0046     u32 val, mask, set;
0047 
0048     switch (path) {
0049     case MTK_ETH_PATH_GMAC1_SGMII:
0050         mask = ~(u32)MTK_MUX_TO_ESW;
0051         set = 0;
0052         break;
0053     case MTK_ETH_PATH_GDM1_ESW:
0054         mask = ~(u32)MTK_MUX_TO_ESW;
0055         set = MTK_MUX_TO_ESW;
0056         break;
0057     default:
0058         updated = false;
0059         break;
0060     }
0061 
0062     if (updated) {
0063         val = mtk_r32(eth, MTK_MAC_MISC);
0064         val = (val & mask) | set;
0065         mtk_w32(eth, val, MTK_MAC_MISC);
0066     }
0067 
0068     dev_dbg(eth->dev, "path %s in %s updated = %d\n",
0069         mtk_eth_path_name(path), __func__, updated);
0070 
0071     return 0;
0072 }
0073 
0074 static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
0075 {
0076     unsigned int val = 0;
0077     bool updated = true;
0078 
0079     switch (path) {
0080     case MTK_ETH_PATH_GMAC2_GEPHY:
0081         val = ~(u32)GEPHY_MAC_SEL;
0082         break;
0083     default:
0084         updated = false;
0085         break;
0086     }
0087 
0088     if (updated)
0089         regmap_update_bits(eth->infra, INFRA_MISC2, GEPHY_MAC_SEL, val);
0090 
0091     dev_dbg(eth->dev, "path %s in %s updated = %d\n",
0092         mtk_eth_path_name(path), __func__, updated);
0093 
0094     return 0;
0095 }
0096 
0097 static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
0098 {
0099     unsigned int val = 0;
0100     bool updated = true;
0101 
0102     switch (path) {
0103     case MTK_ETH_PATH_GMAC2_SGMII:
0104         val = CO_QPHY_SEL;
0105         break;
0106     default:
0107         updated = false;
0108         break;
0109     }
0110 
0111     if (updated)
0112         regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val);
0113 
0114     dev_dbg(eth->dev, "path %s in %s updated = %d\n",
0115         mtk_eth_path_name(path), __func__, updated);
0116 
0117     return 0;
0118 }
0119 
0120 static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
0121 {
0122     unsigned int val = 0;
0123     bool updated = true;
0124 
0125     switch (path) {
0126     case MTK_ETH_PATH_GMAC1_SGMII:
0127         val = SYSCFG0_SGMII_GMAC1;
0128         break;
0129     case MTK_ETH_PATH_GMAC2_SGMII:
0130         val = SYSCFG0_SGMII_GMAC2;
0131         break;
0132     case MTK_ETH_PATH_GMAC1_RGMII:
0133     case MTK_ETH_PATH_GMAC2_RGMII:
0134         regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
0135         val &= SYSCFG0_SGMII_MASK;
0136 
0137         if ((path == MTK_GMAC1_RGMII && val == SYSCFG0_SGMII_GMAC1) ||
0138             (path == MTK_GMAC2_RGMII && val == SYSCFG0_SGMII_GMAC2))
0139             val = 0;
0140         else
0141             updated = false;
0142         break;
0143     default:
0144         updated = false;
0145         break;
0146     }
0147 
0148     if (updated)
0149         regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
0150                    SYSCFG0_SGMII_MASK, val);
0151 
0152     dev_dbg(eth->dev, "path %s in %s updated = %d\n",
0153         mtk_eth_path_name(path), __func__, updated);
0154 
0155     return 0;
0156 }
0157 
0158 static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
0159 {
0160     unsigned int val = 0;
0161     bool updated = true;
0162 
0163     regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
0164 
0165     switch (path) {
0166     case MTK_ETH_PATH_GMAC1_SGMII:
0167         val |= SYSCFG0_SGMII_GMAC1_V2;
0168         break;
0169     case MTK_ETH_PATH_GMAC2_GEPHY:
0170         val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
0171         break;
0172     case MTK_ETH_PATH_GMAC2_SGMII:
0173         val |= SYSCFG0_SGMII_GMAC2_V2;
0174         break;
0175     default:
0176         updated = false;
0177     }
0178 
0179     if (updated)
0180         regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
0181                    SYSCFG0_SGMII_MASK, val);
0182 
0183     dev_dbg(eth->dev, "path %s in %s updated = %d\n",
0184         mtk_eth_path_name(path), __func__, updated);
0185 
0186     return 0;
0187 }
0188 
0189 static const struct mtk_eth_muxc mtk_eth_muxc[] = {
0190     {
0191         .name = "mux_gdm1_to_gmac1_esw",
0192         .cap_bit = MTK_ETH_MUX_GDM1_TO_GMAC1_ESW,
0193         .set_path = set_mux_gdm1_to_gmac1_esw,
0194     }, {
0195         .name = "mux_gmac2_gmac0_to_gephy",
0196         .cap_bit = MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY,
0197         .set_path = set_mux_gmac2_gmac0_to_gephy,
0198     }, {
0199         .name = "mux_u3_gmac2_to_qphy",
0200         .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
0201         .set_path = set_mux_u3_gmac2_to_qphy,
0202     }, {
0203         .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
0204         .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
0205         .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
0206     }, {
0207         .name = "mux_gmac12_to_gephy_sgmii",
0208         .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
0209         .set_path = set_mux_gmac12_to_gephy_sgmii,
0210     },
0211 };
0212 
0213 static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
0214 {
0215     int i, err = 0;
0216 
0217     if (!MTK_HAS_CAPS(eth->soc->caps, path)) {
0218         dev_err(eth->dev, "path %s isn't support on the SoC\n",
0219             mtk_eth_path_name(path));
0220         return -EINVAL;
0221     }
0222 
0223     if (!MTK_HAS_CAPS(eth->soc->caps, MTK_MUX))
0224         return 0;
0225 
0226     /* Setup MUX in path fabric */
0227     for (i = 0; i < ARRAY_SIZE(mtk_eth_muxc); i++) {
0228         if (MTK_HAS_CAPS(eth->soc->caps, mtk_eth_muxc[i].cap_bit)) {
0229             err = mtk_eth_muxc[i].set_path(eth, path);
0230             if (err)
0231                 goto out;
0232         } else {
0233             dev_dbg(eth->dev, "mux %s isn't present on the SoC\n",
0234                 mtk_eth_muxc[i].name);
0235         }
0236     }
0237 
0238 out:
0239     return err;
0240 }
0241 
0242 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
0243 {
0244     int path;
0245 
0246     path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
0247                 MTK_ETH_PATH_GMAC2_SGMII;
0248 
0249     /* Setup proper MUXes along the path */
0250     return mtk_eth_mux_setup(eth, path);
0251 }
0252 
0253 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
0254 {
0255     int path = 0;
0256 
0257     if (mac_id == 1)
0258         path = MTK_ETH_PATH_GMAC2_GEPHY;
0259 
0260     if (!path)
0261         return -EINVAL;
0262 
0263     /* Setup proper MUXes along the path */
0264     return mtk_eth_mux_setup(eth, path);
0265 }
0266 
0267 int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
0268 {
0269     int path;
0270 
0271     path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_RGMII :
0272                 MTK_ETH_PATH_GMAC2_RGMII;
0273 
0274     /* Setup proper MUXes along the path */
0275     return mtk_eth_mux_setup(eth, path);
0276 }
0277