1 // SPDX-License-Identifier: GPL-2.0+ 2 /* Copyright (c) 2021-2022 NXP. */ 3 4 #include <linux/module.h> 5 #include <linux/of.h> 6 #include <linux/phy.h> 7 #include <linux/phy/phy.h> 8 #include <linux/platform_device.h> 9 #include <linux/workqueue.h> 10 11 #define LYNX_28G_NUM_LANE 8 12 #define LYNX_28G_NUM_PLL 2 13 14 /* General registers per SerDes block */ 15 #define LYNX_28G_PCC8 0x10a0 16 #define LYNX_28G_PCC8_SGMII 0x1 17 #define LYNX_28G_PCC8_SGMII_DIS 0x0 18 19 #define LYNX_28G_PCCC 0x10b0 20 #define LYNX_28G_PCCC_10GBASER 0x9 21 #define LYNX_28G_PCCC_USXGMII 0x1 22 #define LYNX_28G_PCCC_SXGMII_DIS 0x0 23 24 #define LYNX_28G_LNa_PCC_OFFSET(lane) (4 * (LYNX_28G_NUM_LANE - (lane->id) - 1)) 25 26 /* Per PLL registers */ 27 #define LYNX_28G_PLLnRSTCTL(pll) (0x400 + (pll) * 0x100 + 0x0) 28 #define LYNX_28G_PLLnRSTCTL_DIS(rstctl) (((rstctl) & BIT(24)) >> 24) 29 #define LYNX_28G_PLLnRSTCTL_LOCK(rstctl) (((rstctl) & BIT(23)) >> 23) 30 31 #define LYNX_28G_PLLnCR0(pll) (0x400 + (pll) * 0x100 + 0x4) 32 #define LYNX_28G_PLLnCR0_REFCLK_SEL(cr0) (((cr0) & GENMASK(20, 16))) 33 #define LYNX_28G_PLLnCR0_REFCLK_SEL_100MHZ 0x0 34 #define LYNX_28G_PLLnCR0_REFCLK_SEL_125MHZ 0x10000 35 #define LYNX_28G_PLLnCR0_REFCLK_SEL_156MHZ 0x20000 36 #define LYNX_28G_PLLnCR0_REFCLK_SEL_150MHZ 0x30000 37 #define LYNX_28G_PLLnCR0_REFCLK_SEL_161MHZ 0x40000 38 39 #define LYNX_28G_PLLnCR1(pll) (0x400 + (pll) * 0x100 + 0x8) 40 #define LYNX_28G_PLLnCR1_FRATE_SEL(cr1) (((cr1) & GENMASK(28, 24))) 41 #define LYNX_28G_PLLnCR1_FRATE_5G_10GVCO 0x0 42 #define LYNX_28G_PLLnCR1_FRATE_5G_25GVCO 0x10000000 43 #define LYNX_28G_PLLnCR1_FRATE_10G_20GVCO 0x6000000 44 45 /* Per SerDes lane registers */ 46 /* Lane a General Control Register */ 47 #define LYNX_28G_LNaGCR0(lane) (0x800 + (lane) * 0x100 + 0x0) 48 #define LYNX_28G_LNaGCR0_PROTO_SEL_MSK GENMASK(7, 3) 49 #define LYNX_28G_LNaGCR0_PROTO_SEL_SGMII 0x8 50 #define LYNX_28G_LNaGCR0_PROTO_SEL_XFI 0x50 51 #define LYNX_28G_LNaGCR0_IF_WIDTH_MSK GENMASK(2, 0) 52 #define LYNX_28G_LNaGCR0_IF_WIDTH_10_BIT 0x0 53 #define LYNX_28G_LNaGCR0_IF_WIDTH_20_BIT 0x2 54 55 /* Lane a Tx Reset Control Register */ 56 #define LYNX_28G_LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20) 57 #define LYNX_28G_LNaTRSTCTL_HLT_REQ BIT(27) 58 #define LYNX_28G_LNaTRSTCTL_RST_DONE BIT(30) 59 #define LYNX_28G_LNaTRSTCTL_RST_REQ BIT(31) 60 61 /* Lane a Tx General Control Register */ 62 #define LYNX_28G_LNaTGCR0(lane) (0x800 + (lane) * 0x100 + 0x24) 63 #define LYNX_28G_LNaTGCR0_USE_PLLF 0x0 64 #define LYNX_28G_LNaTGCR0_USE_PLLS BIT(28) 65 #define LYNX_28G_LNaTGCR0_USE_PLL_MSK BIT(28) 66 #define LYNX_28G_LNaTGCR0_N_RATE_FULL 0x0 67 #define LYNX_28G_LNaTGCR0_N_RATE_HALF 0x1000000 68 #define LYNX_28G_LNaTGCR0_N_RATE_QUARTER 0x2000000 69 #define LYNX_28G_LNaTGCR0_N_RATE_MSK GENMASK(26, 24) 70 71 #define LYNX_28G_LNaTECR0(lane) (0x800 + (lane) * 0x100 + 0x30) 72 73 /* Lane a Rx Reset Control Register */ 74 #define LYNX_28G_LNaRRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x40) 75 #define LYNX_28G_LNaRRSTCTL_HLT_REQ BIT(27) 76 #define LYNX_28G_LNaRRSTCTL_RST_DONE BIT(30) 77 #define LYNX_28G_LNaRRSTCTL_RST_REQ BIT(31) 78 #define LYNX_28G_LNaRRSTCTL_CDR_LOCK BIT(12) 79 80 /* Lane a Rx General Control Register */ 81 #define LYNX_28G_LNaRGCR0(lane) (0x800 + (lane) * 0x100 + 0x44) 82 #define LYNX_28G_LNaRGCR0_USE_PLLF 0x0 83 #define LYNX_28G_LNaRGCR0_USE_PLLS BIT(28) 84 #define LYNX_28G_LNaRGCR0_USE_PLL_MSK BIT(28) 85 #define LYNX_28G_LNaRGCR0_N_RATE_MSK GENMASK(26, 24) 86 #define LYNX_28G_LNaRGCR0_N_RATE_FULL 0x0 87 #define LYNX_28G_LNaRGCR0_N_RATE_HALF 0x1000000 88 #define LYNX_28G_LNaRGCR0_N_RATE_QUARTER 0x2000000 89 #define LYNX_28G_LNaRGCR0_N_RATE_MSK GENMASK(26, 24) 90 91 #define LYNX_28G_LNaRGCR1(lane) (0x800 + (lane) * 0x100 + 0x48) 92 93 #define LYNX_28G_LNaRECR0(lane) (0x800 + (lane) * 0x100 + 0x50) 94 #define LYNX_28G_LNaRECR1(lane) (0x800 + (lane) * 0x100 + 0x54) 95 #define LYNX_28G_LNaRECR2(lane) (0x800 + (lane) * 0x100 + 0x58) 96 97 #define LYNX_28G_LNaRSCCR0(lane) (0x800 + (lane) * 0x100 + 0x74) 98 99 #define LYNX_28G_LNaPSS(lane) (0x1000 + (lane) * 0x4) 100 #define LYNX_28G_LNaPSS_TYPE(pss) (((pss) & GENMASK(30, 24)) >> 24) 101 #define LYNX_28G_LNaPSS_TYPE_SGMII 0x4 102 #define LYNX_28G_LNaPSS_TYPE_XFI 0x28 103 104 #define LYNX_28G_SGMIIaCR1(lane) (0x1804 + (lane) * 0x10) 105 #define LYNX_28G_SGMIIaCR1_SGPCS_EN BIT(11) 106 #define LYNX_28G_SGMIIaCR1_SGPCS_DIS 0x0 107 #define LYNX_28G_SGMIIaCR1_SGPCS_MSK BIT(11) 108 109 struct lynx_28g_priv; 110 111 struct lynx_28g_pll { 112 struct lynx_28g_priv *priv; 113 u32 rstctl, cr0, cr1; 114 int id; 115 DECLARE_PHY_INTERFACE_MASK(supported); 116 }; 117 118 struct lynx_28g_lane { 119 struct lynx_28g_priv *priv; 120 struct phy *phy; 121 bool powered_up; 122 bool init; 123 unsigned int id; 124 phy_interface_t interface; 125 }; 126 127 struct lynx_28g_priv { 128 void __iomem *base; 129 struct device *dev; 130 struct lynx_28g_pll pll[LYNX_28G_NUM_PLL]; 131 struct lynx_28g_lane lane[LYNX_28G_NUM_LANE]; 132 133 struct delayed_work cdr_check; 134 }; 135 136 static void lynx_28g_rmw(struct lynx_28g_priv *priv, unsigned long off, 137 u32 val, u32 mask) 138 { 139 void __iomem *reg = priv->base + off; 140 u32 orig, tmp; 141 142 orig = ioread32(reg); 143 tmp = orig & ~mask; 144 tmp |= val; 145 iowrite32(tmp, reg); 146 } 147 148 #define lynx_28g_lane_rmw(lane, reg, val, mask) \ 149 lynx_28g_rmw((lane)->priv, LYNX_28G_##reg(lane->id), \ 150 LYNX_28G_##reg##_##val, LYNX_28G_##reg##_##mask) 151 #define lynx_28g_lane_read(lane, reg) \ 152 ioread32((lane)->priv->base + LYNX_28G_##reg((lane)->id)) 153 #define lynx_28g_pll_read(pll, reg) \ 154 ioread32((pll)->priv->base + LYNX_28G_##reg((pll)->id)) 155 156 static bool lynx_28g_supports_interface(struct lynx_28g_priv *priv, int intf) 157 { 158 int i; 159 160 for (i = 0; i < LYNX_28G_NUM_PLL; i++) { 161 if (LYNX_28G_PLLnRSTCTL_DIS(priv->pll[i].rstctl)) 162 continue; 163 164 if (test_bit(intf, priv->pll[i].supported)) 165 return true; 166 } 167 168 return false; 169 } 170 171 static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv, 172 phy_interface_t intf) 173 { 174 struct lynx_28g_pll *pll; 175 int i; 176 177 for (i = 0; i < LYNX_28G_NUM_PLL; i++) { 178 pll = &priv->pll[i]; 179 180 if (LYNX_28G_PLLnRSTCTL_DIS(pll->rstctl)) 181 continue; 182 183 if (test_bit(intf, pll->supported)) 184 return pll; 185 } 186 187 return NULL; 188 } 189 190 static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane, 191 struct lynx_28g_pll *pll, 192 phy_interface_t intf) 193 { 194 switch (LYNX_28G_PLLnCR1_FRATE_SEL(pll->cr1)) { 195 case LYNX_28G_PLLnCR1_FRATE_5G_10GVCO: 196 case LYNX_28G_PLLnCR1_FRATE_5G_25GVCO: 197 switch (intf) { 198 case PHY_INTERFACE_MODE_SGMII: 199 case PHY_INTERFACE_MODE_1000BASEX: 200 lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_QUARTER, N_RATE_MSK); 201 lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_QUARTER, N_RATE_MSK); 202 break; 203 default: 204 break; 205 } 206 break; 207 case LYNX_28G_PLLnCR1_FRATE_10G_20GVCO: 208 switch (intf) { 209 case PHY_INTERFACE_MODE_10GBASER: 210 case PHY_INTERFACE_MODE_USXGMII: 211 lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_FULL, N_RATE_MSK); 212 lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_FULL, N_RATE_MSK); 213 break; 214 default: 215 break; 216 } 217 break; 218 default: 219 break; 220 } 221 } 222 223 static void lynx_28g_lane_set_pll(struct lynx_28g_lane *lane, 224 struct lynx_28g_pll *pll) 225 { 226 if (pll->id == 0) { 227 lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLF, USE_PLL_MSK); 228 lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLF, USE_PLL_MSK); 229 } else { 230 lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLS, USE_PLL_MSK); 231 lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLS, USE_PLL_MSK); 232 } 233 } 234 235 static void lynx_28g_cleanup_lane(struct lynx_28g_lane *lane) 236 { 237 u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 238 struct lynx_28g_priv *priv = lane->priv; 239 240 /* Cleanup the protocol configuration registers of the current protocol */ 241 switch (lane->interface) { 242 case PHY_INTERFACE_MODE_10GBASER: 243 lynx_28g_rmw(priv, LYNX_28G_PCCC, 244 LYNX_28G_PCCC_SXGMII_DIS << lane_offset, 245 GENMASK(3, 0) << lane_offset); 246 break; 247 case PHY_INTERFACE_MODE_SGMII: 248 case PHY_INTERFACE_MODE_1000BASEX: 249 lynx_28g_rmw(priv, LYNX_28G_PCC8, 250 LYNX_28G_PCC8_SGMII_DIS << lane_offset, 251 GENMASK(3, 0) << lane_offset); 252 break; 253 default: 254 break; 255 } 256 } 257 258 static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane) 259 { 260 u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 261 struct lynx_28g_priv *priv = lane->priv; 262 struct lynx_28g_pll *pll; 263 264 lynx_28g_cleanup_lane(lane); 265 266 /* Setup the lane to run in SGMII */ 267 lynx_28g_rmw(priv, LYNX_28G_PCC8, 268 LYNX_28G_PCC8_SGMII << lane_offset, 269 GENMASK(3, 0) << lane_offset); 270 271 /* Setup the protocol select and SerDes parallel interface width */ 272 lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK); 273 lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK); 274 275 /* Switch to the PLL that works with this interface type */ 276 pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII); 277 lynx_28g_lane_set_pll(lane, pll); 278 279 /* Choose the portion of clock net to be used on this lane */ 280 lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_SGMII); 281 282 /* Enable the SGMII PCS */ 283 lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_EN, SGPCS_MSK); 284 285 /* Configure the appropriate equalization parameters for the protocol */ 286 iowrite32(0x00808006, priv->base + LYNX_28G_LNaTECR0(lane->id)); 287 iowrite32(0x04310000, priv->base + LYNX_28G_LNaRGCR1(lane->id)); 288 iowrite32(0x9f800000, priv->base + LYNX_28G_LNaRECR0(lane->id)); 289 iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id)); 290 iowrite32(0x00000000, priv->base + LYNX_28G_LNaRECR2(lane->id)); 291 iowrite32(0x00000000, priv->base + LYNX_28G_LNaRSCCR0(lane->id)); 292 } 293 294 static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane) 295 { 296 u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 297 struct lynx_28g_priv *priv = lane->priv; 298 struct lynx_28g_pll *pll; 299 300 lynx_28g_cleanup_lane(lane); 301 302 /* Enable the SXGMII lane */ 303 lynx_28g_rmw(priv, LYNX_28G_PCCC, 304 LYNX_28G_PCCC_10GBASER << lane_offset, 305 GENMASK(3, 0) << lane_offset); 306 307 /* Setup the protocol select and SerDes parallel interface width */ 308 lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK); 309 lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK); 310 311 /* Switch to the PLL that works with this interface type */ 312 pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER); 313 lynx_28g_lane_set_pll(lane, pll); 314 315 /* Choose the portion of clock net to be used on this lane */ 316 lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_10GBASER); 317 318 /* Disable the SGMII PCS */ 319 lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_DIS, SGPCS_MSK); 320 321 /* Configure the appropriate equalization parameters for the protocol */ 322 iowrite32(0x10808307, priv->base + LYNX_28G_LNaTECR0(lane->id)); 323 iowrite32(0x10000000, priv->base + LYNX_28G_LNaRGCR1(lane->id)); 324 iowrite32(0x00000000, priv->base + LYNX_28G_LNaRECR0(lane->id)); 325 iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id)); 326 iowrite32(0x81000020, priv->base + LYNX_28G_LNaRECR2(lane->id)); 327 iowrite32(0x00002000, priv->base + LYNX_28G_LNaRSCCR0(lane->id)); 328 } 329 330 static int lynx_28g_power_off(struct phy *phy) 331 { 332 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 333 u32 trstctl, rrstctl; 334 335 if (!lane->powered_up) 336 return 0; 337 338 /* Issue a halt request */ 339 lynx_28g_lane_rmw(lane, LNaTRSTCTL, HLT_REQ, HLT_REQ); 340 lynx_28g_lane_rmw(lane, LNaRRSTCTL, HLT_REQ, HLT_REQ); 341 342 /* Wait until the halting process is complete */ 343 do { 344 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL); 345 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 346 } while ((trstctl & LYNX_28G_LNaTRSTCTL_HLT_REQ) || 347 (rrstctl & LYNX_28G_LNaRRSTCTL_HLT_REQ)); 348 349 lane->powered_up = false; 350 351 return 0; 352 } 353 354 static int lynx_28g_power_on(struct phy *phy) 355 { 356 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 357 u32 trstctl, rrstctl; 358 359 if (lane->powered_up) 360 return 0; 361 362 /* Issue a reset request on the lane */ 363 lynx_28g_lane_rmw(lane, LNaTRSTCTL, RST_REQ, RST_REQ); 364 lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ); 365 366 /* Wait until the reset sequence is completed */ 367 do { 368 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL); 369 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 370 } while (!(trstctl & LYNX_28G_LNaTRSTCTL_RST_DONE) || 371 !(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); 372 373 lane->powered_up = true; 374 375 return 0; 376 } 377 378 static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode) 379 { 380 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 381 struct lynx_28g_priv *priv = lane->priv; 382 int powered_up = lane->powered_up; 383 int err = 0; 384 385 if (mode != PHY_MODE_ETHERNET) 386 return -EOPNOTSUPP; 387 388 if (lane->interface == PHY_INTERFACE_MODE_NA) 389 return -EOPNOTSUPP; 390 391 if (!lynx_28g_supports_interface(priv, submode)) 392 return -EOPNOTSUPP; 393 394 /* If the lane is powered up, put the lane into the halt state while 395 * the reconfiguration is being done. 396 */ 397 if (powered_up) 398 lynx_28g_power_off(phy); 399 400 switch (submode) { 401 case PHY_INTERFACE_MODE_SGMII: 402 case PHY_INTERFACE_MODE_1000BASEX: 403 lynx_28g_lane_set_sgmii(lane); 404 break; 405 case PHY_INTERFACE_MODE_10GBASER: 406 lynx_28g_lane_set_10gbaser(lane); 407 break; 408 default: 409 err = -EOPNOTSUPP; 410 goto out; 411 } 412 413 lane->interface = submode; 414 415 out: 416 /* Power up the lane if necessary */ 417 if (powered_up) 418 lynx_28g_power_on(phy); 419 420 return err; 421 } 422 423 static int lynx_28g_validate(struct phy *phy, enum phy_mode mode, int submode, 424 union phy_configure_opts *opts __always_unused) 425 { 426 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 427 struct lynx_28g_priv *priv = lane->priv; 428 429 if (mode != PHY_MODE_ETHERNET) 430 return -EOPNOTSUPP; 431 432 if (!lynx_28g_supports_interface(priv, submode)) 433 return -EOPNOTSUPP; 434 435 return 0; 436 } 437 438 static int lynx_28g_init(struct phy *phy) 439 { 440 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 441 442 /* Mark the fact that the lane was init */ 443 lane->init = true; 444 445 /* SerDes lanes are powered on at boot time. Any lane that is managed 446 * by this driver will get powered down at init time aka at dpaa2-eth 447 * probe time. 448 */ 449 lane->powered_up = true; 450 lynx_28g_power_off(phy); 451 452 return 0; 453 } 454 455 static const struct phy_ops lynx_28g_ops = { 456 .init = lynx_28g_init, 457 .power_on = lynx_28g_power_on, 458 .power_off = lynx_28g_power_off, 459 .set_mode = lynx_28g_set_mode, 460 .validate = lynx_28g_validate, 461 .owner = THIS_MODULE, 462 }; 463 464 static void lynx_28g_pll_read_configuration(struct lynx_28g_priv *priv) 465 { 466 struct lynx_28g_pll *pll; 467 int i; 468 469 for (i = 0; i < LYNX_28G_NUM_PLL; i++) { 470 pll = &priv->pll[i]; 471 pll->priv = priv; 472 pll->id = i; 473 474 pll->rstctl = lynx_28g_pll_read(pll, PLLnRSTCTL); 475 pll->cr0 = lynx_28g_pll_read(pll, PLLnCR0); 476 pll->cr1 = lynx_28g_pll_read(pll, PLLnCR1); 477 478 if (LYNX_28G_PLLnRSTCTL_DIS(pll->rstctl)) 479 continue; 480 481 switch (LYNX_28G_PLLnCR1_FRATE_SEL(pll->cr1)) { 482 case LYNX_28G_PLLnCR1_FRATE_5G_10GVCO: 483 case LYNX_28G_PLLnCR1_FRATE_5G_25GVCO: 484 /* 5GHz clock net */ 485 __set_bit(PHY_INTERFACE_MODE_1000BASEX, pll->supported); 486 __set_bit(PHY_INTERFACE_MODE_SGMII, pll->supported); 487 break; 488 case LYNX_28G_PLLnCR1_FRATE_10G_20GVCO: 489 /* 10.3125GHz clock net */ 490 __set_bit(PHY_INTERFACE_MODE_10GBASER, pll->supported); 491 break; 492 default: 493 /* 6GHz, 12.890625GHz, 8GHz */ 494 break; 495 } 496 } 497 } 498 499 #define work_to_lynx(w) container_of((w), struct lynx_28g_priv, cdr_check.work) 500 501 static void lynx_28g_cdr_lock_check(struct work_struct *work) 502 { 503 struct lynx_28g_priv *priv = work_to_lynx(work); 504 struct lynx_28g_lane *lane; 505 u32 rrstctl; 506 int i; 507 508 for (i = 0; i < LYNX_28G_NUM_LANE; i++) { 509 lane = &priv->lane[i]; 510 511 if (!lane->init) 512 continue; 513 514 if (!lane->powered_up) 515 continue; 516 517 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 518 if (!(rrstctl & LYNX_28G_LNaRRSTCTL_CDR_LOCK)) { 519 lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ); 520 do { 521 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 522 } while (!(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); 523 } 524 } 525 queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, 526 msecs_to_jiffies(1000)); 527 } 528 529 static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane) 530 { 531 u32 pss, protocol; 532 533 pss = lynx_28g_lane_read(lane, LNaPSS); 534 protocol = LYNX_28G_LNaPSS_TYPE(pss); 535 switch (protocol) { 536 case LYNX_28G_LNaPSS_TYPE_SGMII: 537 lane->interface = PHY_INTERFACE_MODE_SGMII; 538 break; 539 case LYNX_28G_LNaPSS_TYPE_XFI: 540 lane->interface = PHY_INTERFACE_MODE_10GBASER; 541 break; 542 default: 543 lane->interface = PHY_INTERFACE_MODE_NA; 544 } 545 } 546 547 static struct phy *lynx_28g_xlate(struct device *dev, 548 struct of_phandle_args *args) 549 { 550 struct lynx_28g_priv *priv = dev_get_drvdata(dev); 551 int idx = args->args[0]; 552 553 if (WARN_ON(idx >= LYNX_28G_NUM_LANE)) 554 return ERR_PTR(-EINVAL); 555 556 return priv->lane[idx].phy; 557 } 558 559 static int lynx_28g_probe(struct platform_device *pdev) 560 { 561 struct device *dev = &pdev->dev; 562 struct phy_provider *provider; 563 struct lynx_28g_priv *priv; 564 int i; 565 566 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 567 if (!priv) 568 return -ENOMEM; 569 priv->dev = &pdev->dev; 570 571 priv->base = devm_platform_ioremap_resource(pdev, 0); 572 if (IS_ERR(priv->base)) 573 return PTR_ERR(priv->base); 574 575 lynx_28g_pll_read_configuration(priv); 576 577 for (i = 0; i < LYNX_28G_NUM_LANE; i++) { 578 struct lynx_28g_lane *lane = &priv->lane[i]; 579 struct phy *phy; 580 581 memset(lane, 0, sizeof(*lane)); 582 583 phy = devm_phy_create(&pdev->dev, NULL, &lynx_28g_ops); 584 if (IS_ERR(phy)) 585 return PTR_ERR(phy); 586 587 lane->priv = priv; 588 lane->phy = phy; 589 lane->id = i; 590 phy_set_drvdata(phy, lane); 591 lynx_28g_lane_read_configuration(lane); 592 } 593 594 dev_set_drvdata(dev, priv); 595 596 INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); 597 598 queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, 599 msecs_to_jiffies(1000)); 600 601 dev_set_drvdata(&pdev->dev, priv); 602 provider = devm_of_phy_provider_register(&pdev->dev, lynx_28g_xlate); 603 604 return PTR_ERR_OR_ZERO(provider); 605 } 606 607 static const struct of_device_id lynx_28g_of_match_table[] = { 608 { .compatible = "fsl,lynx-28g" }, 609 { }, 610 }; 611 MODULE_DEVICE_TABLE(of, lynx_28g_of_match_table); 612 613 static struct platform_driver lynx_28g_driver = { 614 .probe = lynx_28g_probe, 615 .driver = { 616 .name = "lynx-28g", 617 .of_match_table = lynx_28g_of_match_table, 618 }, 619 }; 620 module_platform_driver(lynx_28g_driver); 621 622 MODULE_AUTHOR("Ioana Ciornei <ioana.ciornei@nxp.com>"); 623 MODULE_DESCRIPTION("Lynx 28G SerDes PHY driver for Layerscape SoCs"); 624 MODULE_LICENSE("GPL v2"); 625