1 // SPDX-License-Identifier: GPL-2.0-or-later 2 3 #include <linux/err.h> 4 #include <linux/module.h> 5 #include <linux/of.h> 6 #include <linux/of_platform.h> 7 #include <linux/phy.h> 8 #include <linux/phy/phy.h> 9 #include <linux/platform_device.h> 10 11 #include <dt-bindings/phy/phy-lan966x-serdes.h> 12 #include "lan966x_serdes_regs.h" 13 14 #define PLL_CONF_MASK GENMASK(4, 3) 15 #define PLL_CONF_25MHZ 0 16 #define PLL_CONF_125MHZ 1 17 #define PLL_CONF_SERDES_125MHZ 2 18 #define PLL_CONF_BYPASS 3 19 20 #define lan_offset_(id, tinst, tcnt, \ 21 gbase, ginst, gcnt, gwidth, \ 22 raddr, rinst, rcnt, rwidth) \ 23 (gbase + ((ginst) * gwidth) + raddr + ((rinst) * rwidth)) 24 #define lan_offset(...) lan_offset_(__VA_ARGS__) 25 26 #define lan_rmw(val, mask, reg, off) \ 27 lan_rmw_(val, mask, reg, lan_offset(off)) 28 29 #define SERDES_MUX(_idx, _port, _mode, _submode, _mask, _mux) { \ 30 .idx = _idx, \ 31 .port = _port, \ 32 .mode = _mode, \ 33 .submode = _submode, \ 34 .mask = _mask, \ 35 .mux = _mux, \ 36 } 37 38 #define SERDES_MUX_GMII(i, p, m, c) \ 39 SERDES_MUX(i, p, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_GMII, m, c) 40 #define SERDES_MUX_SGMII(i, p, m, c) \ 41 SERDES_MUX(i, p, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_SGMII, m, c) 42 #define SERDES_MUX_QSGMII(i, p, m, c) \ 43 SERDES_MUX(i, p, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_QSGMII, m, c) 44 #define SERDES_MUX_RGMII(i, p, m, c) \ 45 SERDES_MUX(i, p, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_RGMII, m, c), \ 46 SERDES_MUX(i, p, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_RGMII_TXID, m, c), \ 47 SERDES_MUX(i, p, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_RGMII_RXID, m, c), \ 48 SERDES_MUX(i, p, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_RGMII_ID, m, c) 49 50 static void lan_rmw_(u32 val, u32 mask, void __iomem *mem, u32 offset) 51 { 52 u32 v; 53 54 v = readl(mem + offset); 55 v = (v & ~mask) | (val & mask); 56 writel(v, mem + offset); 57 } 58 59 struct serdes_mux { 60 u8 idx; 61 u8 port; 62 enum phy_mode mode; 63 int submode; 64 u32 mask; 65 u32 mux; 66 }; 67 68 static const struct serdes_mux lan966x_serdes_muxes[] = { 69 SERDES_MUX_QSGMII(SERDES6G(1), 0, HSIO_HW_CFG_QSGMII_ENA, 70 HSIO_HW_CFG_QSGMII_ENA_SET(BIT(0))), 71 SERDES_MUX_QSGMII(SERDES6G(1), 1, HSIO_HW_CFG_QSGMII_ENA, 72 HSIO_HW_CFG_QSGMII_ENA_SET(BIT(0))), 73 SERDES_MUX_QSGMII(SERDES6G(1), 2, HSIO_HW_CFG_QSGMII_ENA, 74 HSIO_HW_CFG_QSGMII_ENA_SET(BIT(0))), 75 SERDES_MUX_QSGMII(SERDES6G(1), 3, HSIO_HW_CFG_QSGMII_ENA, 76 HSIO_HW_CFG_QSGMII_ENA_SET(BIT(0))), 77 78 SERDES_MUX_QSGMII(SERDES6G(2), 4, HSIO_HW_CFG_QSGMII_ENA, 79 HSIO_HW_CFG_QSGMII_ENA_SET(BIT(1))), 80 SERDES_MUX_QSGMII(SERDES6G(2), 5, HSIO_HW_CFG_QSGMII_ENA, 81 HSIO_HW_CFG_QSGMII_ENA_SET(BIT(1))), 82 SERDES_MUX_QSGMII(SERDES6G(2), 6, HSIO_HW_CFG_QSGMII_ENA, 83 HSIO_HW_CFG_QSGMII_ENA_SET(BIT(1))), 84 SERDES_MUX_QSGMII(SERDES6G(2), 7, HSIO_HW_CFG_QSGMII_ENA, 85 HSIO_HW_CFG_QSGMII_ENA_SET(BIT(1))), 86 87 SERDES_MUX_GMII(CU(0), 0, HSIO_HW_CFG_GMII_ENA, 88 HSIO_HW_CFG_GMII_ENA_SET(BIT(0))), 89 SERDES_MUX_GMII(CU(1), 1, HSIO_HW_CFG_GMII_ENA, 90 HSIO_HW_CFG_GMII_ENA_SET(BIT(1))), 91 92 SERDES_MUX_SGMII(SERDES6G(0), 0, HSIO_HW_CFG_SD6G_0_CFG, 0), 93 SERDES_MUX_SGMII(SERDES6G(1), 1, HSIO_HW_CFG_SD6G_1_CFG, 0), 94 SERDES_MUX_SGMII(SERDES6G(0), 2, HSIO_HW_CFG_SD6G_0_CFG, 95 HSIO_HW_CFG_SD6G_0_CFG_SET(1)), 96 SERDES_MUX_SGMII(SERDES6G(1), 3, HSIO_HW_CFG_SD6G_1_CFG, 97 HSIO_HW_CFG_SD6G_1_CFG_SET(1)), 98 99 SERDES_MUX_SGMII(SERDES6G(2), 4, 0, 0), 100 101 SERDES_MUX_RGMII(RGMII(0), 2, HSIO_HW_CFG_RGMII_0_CFG | 102 HSIO_HW_CFG_RGMII_ENA | 103 HSIO_HW_CFG_GMII_ENA, 104 HSIO_HW_CFG_RGMII_0_CFG_SET(0) | 105 HSIO_HW_CFG_RGMII_ENA_SET(BIT(0)) | 106 HSIO_HW_CFG_GMII_ENA_SET(BIT(2))), 107 SERDES_MUX_RGMII(RGMII(1), 3, HSIO_HW_CFG_RGMII_1_CFG | 108 HSIO_HW_CFG_RGMII_ENA | 109 HSIO_HW_CFG_GMII_ENA, 110 HSIO_HW_CFG_RGMII_1_CFG_SET(0) | 111 HSIO_HW_CFG_RGMII_ENA_SET(BIT(1)) | 112 HSIO_HW_CFG_GMII_ENA_SET(BIT(3))), 113 SERDES_MUX_RGMII(RGMII(0), 5, HSIO_HW_CFG_RGMII_0_CFG | 114 HSIO_HW_CFG_RGMII_ENA | 115 HSIO_HW_CFG_GMII_ENA, 116 HSIO_HW_CFG_RGMII_0_CFG_SET(BIT(0)) | 117 HSIO_HW_CFG_RGMII_ENA_SET(BIT(0)) | 118 HSIO_HW_CFG_GMII_ENA_SET(BIT(5))), 119 SERDES_MUX_RGMII(RGMII(1), 6, HSIO_HW_CFG_RGMII_1_CFG | 120 HSIO_HW_CFG_RGMII_ENA | 121 HSIO_HW_CFG_GMII_ENA, 122 HSIO_HW_CFG_RGMII_1_CFG_SET(BIT(0)) | 123 HSIO_HW_CFG_RGMII_ENA_SET(BIT(1)) | 124 HSIO_HW_CFG_GMII_ENA_SET(BIT(6))), 125 }; 126 127 struct serdes_ctrl { 128 void __iomem *regs; 129 struct device *dev; 130 struct phy *phys[SERDES_MAX]; 131 int ref125; 132 }; 133 134 struct serdes_macro { 135 u8 idx; 136 int port; 137 struct serdes_ctrl *ctrl; 138 int speed; 139 phy_interface_t mode; 140 }; 141 142 enum lan966x_sd6g40_mode { 143 LAN966X_SD6G40_MODE_QSGMII, 144 LAN966X_SD6G40_MODE_SGMII, 145 }; 146 147 enum lan966x_sd6g40_ltx2rx { 148 LAN966X_SD6G40_TX2RX_LOOP_NONE, 149 LAN966X_SD6G40_LTX2RX 150 }; 151 152 struct lan966x_sd6g40_setup_args { 153 enum lan966x_sd6g40_mode mode; 154 enum lan966x_sd6g40_ltx2rx tx2rx_loop; 155 bool txinvert; 156 bool rxinvert; 157 bool refclk125M; 158 bool mute; 159 }; 160 161 struct lan966x_sd6g40_mode_args { 162 enum lan966x_sd6g40_mode mode; 163 u8 lane_10bit_sel; 164 u8 mpll_multiplier; 165 u8 ref_clkdiv2; 166 u8 tx_rate; 167 u8 rx_rate; 168 }; 169 170 struct lan966x_sd6g40_setup { 171 u8 rx_term_en; 172 u8 lane_10bit_sel; 173 u8 tx_invert; 174 u8 rx_invert; 175 u8 mpll_multiplier; 176 u8 lane_loopbk_en; 177 u8 ref_clkdiv2; 178 u8 tx_rate; 179 u8 rx_rate; 180 }; 181 182 static int lan966x_sd6g40_reg_cfg(struct serdes_macro *macro, 183 struct lan966x_sd6g40_setup *res_struct, 184 u32 idx) 185 { 186 u32 value; 187 188 /* Note: SerDes HSIO is configured in 1G_LAN mode */ 189 lan_rmw(HSIO_SD_CFG_LANE_10BIT_SEL_SET(res_struct->lane_10bit_sel) | 190 HSIO_SD_CFG_RX_RATE_SET(res_struct->rx_rate) | 191 HSIO_SD_CFG_TX_RATE_SET(res_struct->tx_rate) | 192 HSIO_SD_CFG_TX_INVERT_SET(res_struct->tx_invert) | 193 HSIO_SD_CFG_RX_INVERT_SET(res_struct->rx_invert) | 194 HSIO_SD_CFG_LANE_LOOPBK_EN_SET(res_struct->lane_loopbk_en) | 195 HSIO_SD_CFG_RX_RESET_SET(0) | 196 HSIO_SD_CFG_TX_RESET_SET(0), 197 HSIO_SD_CFG_LANE_10BIT_SEL | 198 HSIO_SD_CFG_RX_RATE | 199 HSIO_SD_CFG_TX_RATE | 200 HSIO_SD_CFG_TX_INVERT | 201 HSIO_SD_CFG_RX_INVERT | 202 HSIO_SD_CFG_LANE_LOOPBK_EN | 203 HSIO_SD_CFG_RX_RESET | 204 HSIO_SD_CFG_TX_RESET, 205 macro->ctrl->regs, HSIO_SD_CFG(idx)); 206 207 lan_rmw(HSIO_MPLL_CFG_MPLL_MULTIPLIER_SET(res_struct->mpll_multiplier) | 208 HSIO_MPLL_CFG_REF_CLKDIV2_SET(res_struct->ref_clkdiv2), 209 HSIO_MPLL_CFG_MPLL_MULTIPLIER | 210 HSIO_MPLL_CFG_REF_CLKDIV2, 211 macro->ctrl->regs, HSIO_MPLL_CFG(idx)); 212 213 lan_rmw(HSIO_SD_CFG_RX_TERM_EN_SET(res_struct->rx_term_en), 214 HSIO_SD_CFG_RX_TERM_EN, 215 macro->ctrl->regs, HSIO_SD_CFG(idx)); 216 217 lan_rmw(HSIO_MPLL_CFG_REF_SSP_EN_SET(1), 218 HSIO_MPLL_CFG_REF_SSP_EN, 219 macro->ctrl->regs, HSIO_MPLL_CFG(idx)); 220 221 usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC); 222 223 lan_rmw(HSIO_SD_CFG_PHY_RESET_SET(0), 224 HSIO_SD_CFG_PHY_RESET, 225 macro->ctrl->regs, HSIO_SD_CFG(idx)); 226 227 usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC); 228 229 lan_rmw(HSIO_MPLL_CFG_MPLL_EN_SET(1), 230 HSIO_MPLL_CFG_MPLL_EN, 231 macro->ctrl->regs, HSIO_MPLL_CFG(idx)); 232 233 usleep_range(7 * USEC_PER_MSEC, 8 * USEC_PER_MSEC); 234 235 value = readl(macro->ctrl->regs + lan_offset(HSIO_SD_STAT(idx))); 236 value = HSIO_SD_STAT_MPLL_STATE_GET(value); 237 if (value != 0x1) { 238 dev_err(macro->ctrl->dev, 239 "Unexpected sd_sd_stat[%u] mpll_state was 0x1 but is 0x%x\n", 240 idx, value); 241 return -EIO; 242 } 243 244 lan_rmw(HSIO_SD_CFG_TX_CM_EN_SET(1), 245 HSIO_SD_CFG_TX_CM_EN, 246 macro->ctrl->regs, HSIO_SD_CFG(idx)); 247 248 usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC); 249 250 value = readl(macro->ctrl->regs + lan_offset(HSIO_SD_STAT(idx))); 251 value = HSIO_SD_STAT_TX_CM_STATE_GET(value); 252 if (value != 0x1) { 253 dev_err(macro->ctrl->dev, 254 "Unexpected sd_sd_stat[%u] tx_cm_state was 0x1 but is 0x%x\n", 255 idx, value); 256 return -EIO; 257 } 258 259 lan_rmw(HSIO_SD_CFG_RX_PLL_EN_SET(1) | 260 HSIO_SD_CFG_TX_EN_SET(1), 261 HSIO_SD_CFG_RX_PLL_EN | 262 HSIO_SD_CFG_TX_EN, 263 macro->ctrl->regs, HSIO_SD_CFG(idx)); 264 265 usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC); 266 267 /* Waiting for serdes 0 rx DPLL to lock... */ 268 value = readl(macro->ctrl->regs + lan_offset(HSIO_SD_STAT(idx))); 269 value = HSIO_SD_STAT_RX_PLL_STATE_GET(value); 270 if (value != 0x1) { 271 dev_err(macro->ctrl->dev, 272 "Unexpected sd_sd_stat[%u] rx_pll_state was 0x1 but is 0x%x\n", 273 idx, value); 274 return -EIO; 275 } 276 277 /* Waiting for serdes 0 tx operational... */ 278 value = readl(macro->ctrl->regs + lan_offset(HSIO_SD_STAT(idx))); 279 value = HSIO_SD_STAT_TX_STATE_GET(value); 280 if (value != 0x1) { 281 dev_err(macro->ctrl->dev, 282 "Unexpected sd_sd_stat[%u] tx_state was 0x1 but is 0x%x\n", 283 idx, value); 284 return -EIO; 285 } 286 287 lan_rmw(HSIO_SD_CFG_TX_DATA_EN_SET(1) | 288 HSIO_SD_CFG_RX_DATA_EN_SET(1), 289 HSIO_SD_CFG_TX_DATA_EN | 290 HSIO_SD_CFG_RX_DATA_EN, 291 macro->ctrl->regs, HSIO_SD_CFG(idx)); 292 293 return 0; 294 } 295 296 static int lan966x_sd6g40_get_conf_from_mode(struct serdes_macro *macro, 297 enum lan966x_sd6g40_mode f_mode, 298 bool ref125M, 299 struct lan966x_sd6g40_mode_args *ret_val) 300 { 301 switch (f_mode) { 302 case LAN966X_SD6G40_MODE_QSGMII: 303 ret_val->lane_10bit_sel = 0; 304 if (ref125M) { 305 ret_val->mpll_multiplier = 40; 306 ret_val->ref_clkdiv2 = 0x1; 307 ret_val->tx_rate = 0x0; 308 ret_val->rx_rate = 0x0; 309 } else { 310 ret_val->mpll_multiplier = 100; 311 ret_val->ref_clkdiv2 = 0x0; 312 ret_val->tx_rate = 0x0; 313 ret_val->rx_rate = 0x0; 314 } 315 break; 316 317 case LAN966X_SD6G40_MODE_SGMII: 318 ret_val->lane_10bit_sel = 1; 319 if (ref125M) { 320 ret_val->mpll_multiplier = macro->speed == SPEED_2500 ? 50 : 40; 321 ret_val->ref_clkdiv2 = 0x1; 322 ret_val->tx_rate = macro->speed == SPEED_2500 ? 0x1 : 0x2; 323 ret_val->rx_rate = macro->speed == SPEED_2500 ? 0x1 : 0x2; 324 } else { 325 ret_val->mpll_multiplier = macro->speed == SPEED_2500 ? 125 : 100; 326 ret_val->ref_clkdiv2 = 0x0; 327 ret_val->tx_rate = macro->speed == SPEED_2500 ? 0x1 : 0x2; 328 ret_val->rx_rate = macro->speed == SPEED_2500 ? 0x1 : 0x2; 329 } 330 break; 331 332 default: 333 return -EOPNOTSUPP; 334 } 335 336 return 0; 337 } 338 339 static int lan966x_calc_sd6g40_setup_lane(struct serdes_macro *macro, 340 struct lan966x_sd6g40_setup_args config, 341 struct lan966x_sd6g40_setup *ret_val) 342 { 343 struct lan966x_sd6g40_mode_args sd6g40_mode; 344 struct lan966x_sd6g40_mode_args *mode_args = &sd6g40_mode; 345 int ret; 346 347 ret = lan966x_sd6g40_get_conf_from_mode(macro, config.mode, 348 config.refclk125M, mode_args); 349 if (ret) 350 return ret; 351 352 ret_val->lane_10bit_sel = mode_args->lane_10bit_sel; 353 ret_val->rx_rate = mode_args->rx_rate; 354 ret_val->tx_rate = mode_args->tx_rate; 355 ret_val->mpll_multiplier = mode_args->mpll_multiplier; 356 ret_val->ref_clkdiv2 = mode_args->ref_clkdiv2; 357 ret_val->rx_term_en = 0; 358 359 if (config.tx2rx_loop == LAN966X_SD6G40_LTX2RX) 360 ret_val->lane_loopbk_en = 1; 361 else 362 ret_val->lane_loopbk_en = 0; 363 364 ret_val->tx_invert = !!config.txinvert; 365 ret_val->rx_invert = !!config.rxinvert; 366 367 return 0; 368 } 369 370 static int lan966x_sd6g40_setup_lane(struct serdes_macro *macro, 371 struct lan966x_sd6g40_setup_args config, 372 u32 idx) 373 { 374 struct lan966x_sd6g40_setup calc_results = {}; 375 int ret; 376 377 ret = lan966x_calc_sd6g40_setup_lane(macro, config, &calc_results); 378 if (ret) 379 return ret; 380 381 return lan966x_sd6g40_reg_cfg(macro, &calc_results, idx); 382 } 383 384 static int lan966x_sd6g40_setup(struct serdes_macro *macro, u32 idx, int mode) 385 { 386 struct lan966x_sd6g40_setup_args conf = {}; 387 388 conf.refclk125M = macro->ctrl->ref125; 389 390 if (mode == PHY_INTERFACE_MODE_QSGMII) 391 conf.mode = LAN966X_SD6G40_MODE_QSGMII; 392 else 393 conf.mode = LAN966X_SD6G40_MODE_SGMII; 394 395 return lan966x_sd6g40_setup_lane(macro, conf, idx); 396 } 397 398 static int lan966x_rgmii_setup(struct serdes_macro *macro, u32 idx, int mode) 399 { 400 bool tx_delay = false; 401 bool rx_delay = false; 402 403 /* Configure RGMII */ 404 lan_rmw(HSIO_RGMII_CFG_RGMII_RX_RST_SET(0) | 405 HSIO_RGMII_CFG_RGMII_TX_RST_SET(0) | 406 HSIO_RGMII_CFG_TX_CLK_CFG_SET(macro->speed == SPEED_1000 ? 1 : 407 macro->speed == SPEED_100 ? 2 : 408 macro->speed == SPEED_10 ? 3 : 0), 409 HSIO_RGMII_CFG_RGMII_RX_RST | 410 HSIO_RGMII_CFG_RGMII_TX_RST | 411 HSIO_RGMII_CFG_TX_CLK_CFG, 412 macro->ctrl->regs, HSIO_RGMII_CFG(idx)); 413 414 if (mode == PHY_INTERFACE_MODE_RGMII || 415 mode == PHY_INTERFACE_MODE_RGMII_TXID) 416 rx_delay = true; 417 418 if (mode == PHY_INTERFACE_MODE_RGMII || 419 mode == PHY_INTERFACE_MODE_RGMII_RXID) 420 tx_delay = true; 421 422 /* Setup DLL configuration */ 423 lan_rmw(HSIO_DLL_CFG_DLL_RST_SET(0) | 424 HSIO_DLL_CFG_DLL_ENA_SET(rx_delay), 425 HSIO_DLL_CFG_DLL_RST | 426 HSIO_DLL_CFG_DLL_ENA, 427 macro->ctrl->regs, HSIO_DLL_CFG(idx == 0 ? 0x0 : 0x2)); 428 429 lan_rmw(HSIO_DLL_CFG_DELAY_ENA_SET(rx_delay), 430 HSIO_DLL_CFG_DELAY_ENA, 431 macro->ctrl->regs, HSIO_DLL_CFG(idx == 0 ? 0x0 : 0x2)); 432 433 lan_rmw(HSIO_DLL_CFG_DLL_RST_SET(0) | 434 HSIO_DLL_CFG_DLL_ENA_SET(tx_delay), 435 HSIO_DLL_CFG_DLL_RST | 436 HSIO_DLL_CFG_DLL_ENA, 437 macro->ctrl->regs, HSIO_DLL_CFG(idx == 0 ? 0x1 : 0x3)); 438 439 lan_rmw(HSIO_DLL_CFG_DELAY_ENA_SET(tx_delay), 440 HSIO_DLL_CFG_DELAY_ENA, 441 macro->ctrl->regs, HSIO_DLL_CFG(idx == 0 ? 0x1 : 0x3)); 442 443 return 0; 444 } 445 446 static int serdes_set_speed(struct phy *phy, int speed) 447 { 448 struct serdes_macro *macro = phy_get_drvdata(phy); 449 450 if (!phy_interface_mode_is_rgmii(macro->mode)) 451 return 0; 452 453 macro->speed = speed; 454 lan966x_rgmii_setup(macro, macro->idx - (SERDES6G_MAX + 1), macro->mode); 455 456 return 0; 457 } 458 459 static int serdes_set_mode(struct phy *phy, enum phy_mode mode, int submode) 460 { 461 struct serdes_macro *macro = phy_get_drvdata(phy); 462 unsigned int i; 463 int val; 464 465 /* As of now only PHY_MODE_ETHERNET is supported */ 466 if (mode != PHY_MODE_ETHERNET) 467 return -EOPNOTSUPP; 468 469 if (submode == PHY_INTERFACE_MODE_2500BASEX) 470 macro->speed = SPEED_2500; 471 else 472 macro->speed = SPEED_1000; 473 474 if (submode == PHY_INTERFACE_MODE_1000BASEX || 475 submode == PHY_INTERFACE_MODE_2500BASEX) 476 submode = PHY_INTERFACE_MODE_SGMII; 477 478 if (submode == PHY_INTERFACE_MODE_QUSGMII) 479 submode = PHY_INTERFACE_MODE_QSGMII; 480 481 for (i = 0; i < ARRAY_SIZE(lan966x_serdes_muxes); i++) { 482 if (macro->idx != lan966x_serdes_muxes[i].idx || 483 mode != lan966x_serdes_muxes[i].mode || 484 submode != lan966x_serdes_muxes[i].submode || 485 macro->port != lan966x_serdes_muxes[i].port) 486 continue; 487 488 val = readl(macro->ctrl->regs + lan_offset(HSIO_HW_CFG)); 489 val |= lan966x_serdes_muxes[i].mux; 490 lan_rmw(val, lan966x_serdes_muxes[i].mask, 491 macro->ctrl->regs, HSIO_HW_CFG); 492 493 macro->mode = lan966x_serdes_muxes[i].submode; 494 495 if (macro->idx < CU_MAX) 496 return 0; 497 498 if (macro->idx < SERDES6G_MAX) 499 return lan966x_sd6g40_setup(macro, 500 macro->idx - (CU_MAX + 1), 501 macro->mode); 502 503 if (macro->idx < RGMII_MAX) 504 return lan966x_rgmii_setup(macro, 505 macro->idx - (SERDES6G_MAX + 1), 506 macro->mode); 507 508 return -EOPNOTSUPP; 509 } 510 511 return -EINVAL; 512 } 513 514 static const struct phy_ops serdes_ops = { 515 .set_mode = serdes_set_mode, 516 .set_speed = serdes_set_speed, 517 .owner = THIS_MODULE, 518 }; 519 520 static struct phy *serdes_simple_xlate(struct device *dev, 521 const struct of_phandle_args *args) 522 { 523 struct serdes_ctrl *ctrl = dev_get_drvdata(dev); 524 unsigned int port, idx, i; 525 526 if (args->args_count != 2) 527 return ERR_PTR(-EINVAL); 528 529 port = args->args[0]; 530 idx = args->args[1]; 531 532 for (i = 0; i < SERDES_MAX; i++) { 533 struct serdes_macro *macro = phy_get_drvdata(ctrl->phys[i]); 534 535 if (idx != macro->idx) 536 continue; 537 538 macro->port = port; 539 return ctrl->phys[i]; 540 } 541 542 return ERR_PTR(-ENODEV); 543 } 544 545 static int serdes_phy_create(struct serdes_ctrl *ctrl, u8 idx, struct phy **phy) 546 { 547 struct serdes_macro *macro; 548 549 *phy = devm_phy_create(ctrl->dev, NULL, &serdes_ops); 550 if (IS_ERR(*phy)) 551 return PTR_ERR(*phy); 552 553 macro = devm_kzalloc(ctrl->dev, sizeof(*macro), GFP_KERNEL); 554 if (!macro) 555 return -ENOMEM; 556 557 macro->idx = idx; 558 macro->ctrl = ctrl; 559 macro->port = -1; 560 561 phy_set_drvdata(*phy, macro); 562 563 return 0; 564 } 565 566 static int serdes_probe(struct platform_device *pdev) 567 { 568 struct phy_provider *provider; 569 struct serdes_ctrl *ctrl; 570 void __iomem *hw_stat; 571 unsigned int i; 572 u32 val; 573 int ret; 574 575 ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL); 576 if (!ctrl) 577 return -ENOMEM; 578 579 ctrl->dev = &pdev->dev; 580 ctrl->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); 581 if (IS_ERR(ctrl->regs)) 582 return PTR_ERR(ctrl->regs); 583 584 hw_stat = devm_platform_get_and_ioremap_resource(pdev, 1, NULL); 585 if (IS_ERR(hw_stat)) 586 return PTR_ERR(hw_stat); 587 588 for (i = 0; i < SERDES_MAX; i++) { 589 ret = serdes_phy_create(ctrl, i, &ctrl->phys[i]); 590 if (ret) 591 return ret; 592 } 593 594 val = readl(hw_stat); 595 val = FIELD_GET(PLL_CONF_MASK, val); 596 ctrl->ref125 = (val == PLL_CONF_125MHZ || 597 val == PLL_CONF_SERDES_125MHZ); 598 599 dev_set_drvdata(&pdev->dev, ctrl); 600 601 provider = devm_of_phy_provider_register(ctrl->dev, 602 serdes_simple_xlate); 603 604 return PTR_ERR_OR_ZERO(provider); 605 } 606 607 static const struct of_device_id serdes_ids[] = { 608 { .compatible = "microchip,lan966x-serdes", }, 609 {}, 610 }; 611 MODULE_DEVICE_TABLE(of, serdes_ids); 612 613 static struct platform_driver mscc_lan966x_serdes = { 614 .probe = serdes_probe, 615 .driver = { 616 .name = "microchip,lan966x-serdes", 617 .of_match_table = of_match_ptr(serdes_ids), 618 }, 619 }; 620 621 module_platform_driver(mscc_lan966x_serdes); 622 623 MODULE_DESCRIPTION("Microchip lan966x switch serdes driver"); 624 MODULE_AUTHOR("Horatiu Vultur <horatiu.vultur@microchip.com>"); 625 MODULE_LICENSE("GPL v2"); 626