root/drivers/net/ethernet/mediatek/mtk_eth_path.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mtk_eth_path_name
  2. set_mux_gdm1_to_gmac1_esw
  3. set_mux_gmac2_gmac0_to_gephy
  4. set_mux_u3_gmac2_to_qphy
  5. set_mux_gmac1_gmac2_to_sgmii_rgmii
  6. set_mux_gmac12_to_gephy_sgmii
  7. mtk_eth_mux_setup
  8. mtk_gmac_sgmii_path_setup
  9. mtk_gmac_gephy_path_setup
  10. mtk_gmac_rgmii_path_setup

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (c) 2018-2019 MediaTek Inc.
   3 
   4 /* A library for configuring path from GMAC/GDM to target PHY
   5  *
   6  * Author: Sean Wang <sean.wang@mediatek.com>
   7  *
   8  */
   9 
  10 #include <linux/phy.h>
  11 #include <linux/regmap.h>
  12 
  13 #include "mtk_eth_soc.h"
  14 
  15 struct mtk_eth_muxc {
  16         const char      *name;
  17         int             cap_bit;
  18         int             (*set_path)(struct mtk_eth *eth, int path);
  19 };
  20 
  21 static const char *mtk_eth_path_name(int path)
  22 {
  23         switch (path) {
  24         case MTK_ETH_PATH_GMAC1_RGMII:
  25                 return "gmac1_rgmii";
  26         case MTK_ETH_PATH_GMAC1_TRGMII:
  27                 return "gmac1_trgmii";
  28         case MTK_ETH_PATH_GMAC1_SGMII:
  29                 return "gmac1_sgmii";
  30         case MTK_ETH_PATH_GMAC2_RGMII:
  31                 return "gmac2_rgmii";
  32         case MTK_ETH_PATH_GMAC2_SGMII:
  33                 return "gmac2_sgmii";
  34         case MTK_ETH_PATH_GMAC2_GEPHY:
  35                 return "gmac2_gephy";
  36         case MTK_ETH_PATH_GDM1_ESW:
  37                 return "gdm1_esw";
  38         default:
  39                 return "unknown path";
  40         }
  41 }
  42 
  43 static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
  44 {
  45         bool updated = true;
  46         u32 val, mask, set;
  47 
  48         switch (path) {
  49         case MTK_ETH_PATH_GMAC1_SGMII:
  50                 mask = ~(u32)MTK_MUX_TO_ESW;
  51                 set = 0;
  52                 break;
  53         case MTK_ETH_PATH_GDM1_ESW:
  54                 mask = ~(u32)MTK_MUX_TO_ESW;
  55                 set = MTK_MUX_TO_ESW;
  56                 break;
  57         default:
  58                 updated = false;
  59                 break;
  60         };
  61 
  62         if (updated) {
  63                 val = mtk_r32(eth, MTK_MAC_MISC);
  64                 val = (val & mask) | set;
  65                 mtk_w32(eth, val, MTK_MAC_MISC);
  66         }
  67 
  68         dev_dbg(eth->dev, "path %s in %s updated = %d\n",
  69                 mtk_eth_path_name(path), __func__, updated);
  70 
  71         return 0;
  72 }
  73 
  74 static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
  75 {
  76         unsigned int val = 0;
  77         bool updated = true;
  78 
  79         switch (path) {
  80         case MTK_ETH_PATH_GMAC2_GEPHY:
  81                 val = ~(u32)GEPHY_MAC_SEL;
  82                 break;
  83         default:
  84                 updated = false;
  85                 break;
  86         }
  87 
  88         if (updated)
  89                 regmap_update_bits(eth->infra, INFRA_MISC2, GEPHY_MAC_SEL, val);
  90 
  91         dev_dbg(eth->dev, "path %s in %s updated = %d\n",
  92                 mtk_eth_path_name(path), __func__, updated);
  93 
  94         return 0;
  95 }
  96 
  97 static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
  98 {
  99         unsigned int val = 0;
 100         bool updated = true;
 101 
 102         switch (path) {
 103         case MTK_ETH_PATH_GMAC2_SGMII:
 104                 val = CO_QPHY_SEL;
 105                 break;
 106         default:
 107                 updated = false;
 108                 break;
 109         }
 110 
 111         if (updated)
 112                 regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val);
 113 
 114         dev_dbg(eth->dev, "path %s in %s updated = %d\n",
 115                 mtk_eth_path_name(path), __func__, updated);
 116 
 117         return 0;
 118 }
 119 
 120 static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
 121 {
 122         unsigned int val = 0;
 123         bool updated = true;
 124 
 125         switch (path) {
 126         case MTK_ETH_PATH_GMAC1_SGMII:
 127                 val = SYSCFG0_SGMII_GMAC1;
 128                 break;
 129         case MTK_ETH_PATH_GMAC2_SGMII:
 130                 val = SYSCFG0_SGMII_GMAC2;
 131                 break;
 132         case MTK_ETH_PATH_GMAC1_RGMII:
 133         case MTK_ETH_PATH_GMAC2_RGMII:
 134                 regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
 135                 val &= SYSCFG0_SGMII_MASK;
 136 
 137                 if ((path == MTK_GMAC1_RGMII && val == SYSCFG0_SGMII_GMAC1) ||
 138                     (path == MTK_GMAC2_RGMII && val == SYSCFG0_SGMII_GMAC2))
 139                         val = 0;
 140                 else
 141                         updated = false;
 142                 break;
 143         default:
 144                 updated = false;
 145                 break;
 146         };
 147 
 148         if (updated)
 149                 regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
 150                                    SYSCFG0_SGMII_MASK, val);
 151 
 152         dev_dbg(eth->dev, "path %s in %s updated = %d\n",
 153                 mtk_eth_path_name(path), __func__, updated);
 154 
 155         return 0;
 156 }
 157 
 158 static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
 159 {
 160         unsigned int val = 0;
 161         bool updated = true;
 162 
 163         regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
 164 
 165         switch (path) {
 166         case MTK_ETH_PATH_GMAC1_SGMII:
 167                 val |= SYSCFG0_SGMII_GMAC1_V2;
 168                 break;
 169         case MTK_ETH_PATH_GMAC2_GEPHY:
 170                 val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
 171                 break;
 172         case MTK_ETH_PATH_GMAC2_SGMII:
 173                 val |= SYSCFG0_SGMII_GMAC2_V2;
 174                 break;
 175         default:
 176                 updated = false;
 177         };
 178 
 179         if (updated)
 180                 regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
 181                                    SYSCFG0_SGMII_MASK, val);
 182 
 183         dev_dbg(eth->dev, "path %s in %s updated = %d\n",
 184                 mtk_eth_path_name(path), __func__, updated);
 185 
 186         return 0;
 187 }
 188 
 189 static const struct mtk_eth_muxc mtk_eth_muxc[] = {
 190         {
 191                 .name = "mux_gdm1_to_gmac1_esw",
 192                 .cap_bit = MTK_ETH_MUX_GDM1_TO_GMAC1_ESW,
 193                 .set_path = set_mux_gdm1_to_gmac1_esw,
 194         }, {
 195                 .name = "mux_gmac2_gmac0_to_gephy",
 196                 .cap_bit = MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY,
 197                 .set_path = set_mux_gmac2_gmac0_to_gephy,
 198         }, {
 199                 .name = "mux_u3_gmac2_to_qphy",
 200                 .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
 201                 .set_path = set_mux_u3_gmac2_to_qphy,
 202         }, {
 203                 .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
 204                 .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
 205                 .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
 206         }, {
 207                 .name = "mux_gmac12_to_gephy_sgmii",
 208                 .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
 209                 .set_path = set_mux_gmac12_to_gephy_sgmii,
 210         },
 211 };
 212 
 213 static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
 214 {
 215         int i, err = 0;
 216 
 217         if (!MTK_HAS_CAPS(eth->soc->caps, path)) {
 218                 dev_err(eth->dev, "path %s isn't support on the SoC\n",
 219                         mtk_eth_path_name(path));
 220                 return -EINVAL;
 221         }
 222 
 223         if (!MTK_HAS_CAPS(eth->soc->caps, MTK_MUX))
 224                 return 0;
 225 
 226         /* Setup MUX in path fabric */
 227         for (i = 0; i < ARRAY_SIZE(mtk_eth_muxc); i++) {
 228                 if (MTK_HAS_CAPS(eth->soc->caps, mtk_eth_muxc[i].cap_bit)) {
 229                         err = mtk_eth_muxc[i].set_path(eth, path);
 230                         if (err)
 231                                 goto out;
 232                 } else {
 233                         dev_dbg(eth->dev, "mux %s isn't present on the SoC\n",
 234                                 mtk_eth_muxc[i].name);
 235                 }
 236         }
 237 
 238 out:
 239         return err;
 240 }
 241 
 242 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
 243 {
 244         int err, path;
 245 
 246         path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
 247                                 MTK_ETH_PATH_GMAC2_SGMII;
 248 
 249         /* Setup proper MUXes along the path */
 250         err = mtk_eth_mux_setup(eth, path);
 251         if (err)
 252                 return err;
 253 
 254         return 0;
 255 }
 256 
 257 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
 258 {
 259         int err, path = 0;
 260 
 261         if (mac_id == 1)
 262                 path = MTK_ETH_PATH_GMAC2_GEPHY;
 263 
 264         if (!path)
 265                 return -EINVAL;
 266 
 267         /* Setup proper MUXes along the path */
 268         err = mtk_eth_mux_setup(eth, path);
 269         if (err)
 270                 return err;
 271 
 272         return 0;
 273 }
 274 
 275 int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
 276 {
 277         int err, path;
 278 
 279         path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_RGMII :
 280                                 MTK_ETH_PATH_GMAC2_RGMII;
 281 
 282         /* Setup proper MUXes along the path */
 283         err = mtk_eth_mux_setup(eth, path);
 284         if (err)
 285                 return err;
 286 
 287         return 0;
 288 }
 289 

/* [<][>][^][v][top][bottom][index][help] */