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 /* Serialize concurrent access to registers shared between lanes, 131 * like PCCn 132 */ 133 spinlock_t pcc_lock; 134 struct lynx_28g_pll pll[LYNX_28G_NUM_PLL]; 135 struct lynx_28g_lane lane[LYNX_28G_NUM_LANE]; 136 137 struct delayed_work cdr_check; 138 }; 139 140 static void lynx_28g_rmw(struct lynx_28g_priv *priv, unsigned long off, 141 u32 val, u32 mask) 142 { 143 void __iomem *reg = priv->base + off; 144 u32 orig, tmp; 145 146 orig = ioread32(reg); 147 tmp = orig & ~mask; 148 tmp |= val; 149 iowrite32(tmp, reg); 150 } 151 152 #define lynx_28g_lane_rmw(lane, reg, val, mask) \ 153 lynx_28g_rmw((lane)->priv, LYNX_28G_##reg(lane->id), \ 154 LYNX_28G_##reg##_##val, LYNX_28G_##reg##_##mask) 155 #define lynx_28g_lane_read(lane, reg) \ 156 ioread32((lane)->priv->base + LYNX_28G_##reg((lane)->id)) 157 #define lynx_28g_pll_read(pll, reg) \ 158 ioread32((pll)->priv->base + LYNX_28G_##reg((pll)->id)) 159 160 static bool lynx_28g_supports_interface(struct lynx_28g_priv *priv, int intf) 161 { 162 int i; 163 164 for (i = 0; i < LYNX_28G_NUM_PLL; i++) { 165 if (LYNX_28G_PLLnRSTCTL_DIS(priv->pll[i].rstctl)) 166 continue; 167 168 if (test_bit(intf, priv->pll[i].supported)) 169 return true; 170 } 171 172 return false; 173 } 174 175 static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv, 176 phy_interface_t intf) 177 { 178 struct lynx_28g_pll *pll; 179 int i; 180 181 for (i = 0; i < LYNX_28G_NUM_PLL; i++) { 182 pll = &priv->pll[i]; 183 184 if (LYNX_28G_PLLnRSTCTL_DIS(pll->rstctl)) 185 continue; 186 187 if (test_bit(intf, pll->supported)) 188 return pll; 189 } 190 191 /* no pll supports requested mode, either caller forgot to check 192 * lynx_28g_supports_lane_mode, or this is a bug. 193 */ 194 dev_WARN_ONCE(priv->dev, 1, "no pll for interface %s\n", phy_modes(intf)); 195 return NULL; 196 } 197 198 static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane, 199 struct lynx_28g_pll *pll, 200 phy_interface_t intf) 201 { 202 switch (LYNX_28G_PLLnCR1_FRATE_SEL(pll->cr1)) { 203 case LYNX_28G_PLLnCR1_FRATE_5G_10GVCO: 204 case LYNX_28G_PLLnCR1_FRATE_5G_25GVCO: 205 switch (intf) { 206 case PHY_INTERFACE_MODE_SGMII: 207 case PHY_INTERFACE_MODE_1000BASEX: 208 lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_QUARTER, N_RATE_MSK); 209 lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_QUARTER, N_RATE_MSK); 210 break; 211 default: 212 break; 213 } 214 break; 215 case LYNX_28G_PLLnCR1_FRATE_10G_20GVCO: 216 switch (intf) { 217 case PHY_INTERFACE_MODE_10GBASER: 218 case PHY_INTERFACE_MODE_USXGMII: 219 lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_FULL, N_RATE_MSK); 220 lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_FULL, N_RATE_MSK); 221 break; 222 default: 223 break; 224 } 225 break; 226 default: 227 break; 228 } 229 } 230 231 static void lynx_28g_lane_set_pll(struct lynx_28g_lane *lane, 232 struct lynx_28g_pll *pll) 233 { 234 if (pll->id == 0) { 235 lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLF, USE_PLL_MSK); 236 lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLF, USE_PLL_MSK); 237 } else { 238 lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLS, USE_PLL_MSK); 239 lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLS, USE_PLL_MSK); 240 } 241 } 242 243 static void lynx_28g_cleanup_lane(struct lynx_28g_lane *lane) 244 { 245 u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 246 struct lynx_28g_priv *priv = lane->priv; 247 248 /* Cleanup the protocol configuration registers of the current protocol */ 249 switch (lane->interface) { 250 case PHY_INTERFACE_MODE_10GBASER: 251 lynx_28g_rmw(priv, LYNX_28G_PCCC, 252 LYNX_28G_PCCC_SXGMII_DIS << lane_offset, 253 GENMASK(3, 0) << lane_offset); 254 break; 255 case PHY_INTERFACE_MODE_SGMII: 256 case PHY_INTERFACE_MODE_1000BASEX: 257 lynx_28g_rmw(priv, LYNX_28G_PCC8, 258 LYNX_28G_PCC8_SGMII_DIS << lane_offset, 259 GENMASK(3, 0) << lane_offset); 260 break; 261 default: 262 break; 263 } 264 } 265 266 static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane) 267 { 268 u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 269 struct lynx_28g_priv *priv = lane->priv; 270 struct lynx_28g_pll *pll; 271 272 lynx_28g_cleanup_lane(lane); 273 274 /* Setup the lane to run in SGMII */ 275 lynx_28g_rmw(priv, LYNX_28G_PCC8, 276 LYNX_28G_PCC8_SGMII << lane_offset, 277 GENMASK(3, 0) << lane_offset); 278 279 /* Setup the protocol select and SerDes parallel interface width */ 280 lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK); 281 lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK); 282 283 /* Find the PLL that works with this interface type */ 284 pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII); 285 if (unlikely(pll == NULL)) 286 return; 287 288 /* Switch to the PLL that works with this interface type */ 289 lynx_28g_lane_set_pll(lane, pll); 290 291 /* Choose the portion of clock net to be used on this lane */ 292 lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_SGMII); 293 294 /* Enable the SGMII PCS */ 295 lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_EN, SGPCS_MSK); 296 297 /* Configure the appropriate equalization parameters for the protocol */ 298 iowrite32(0x00808006, priv->base + LYNX_28G_LNaTECR0(lane->id)); 299 iowrite32(0x04310000, priv->base + LYNX_28G_LNaRGCR1(lane->id)); 300 iowrite32(0x9f800000, priv->base + LYNX_28G_LNaRECR0(lane->id)); 301 iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id)); 302 iowrite32(0x00000000, priv->base + LYNX_28G_LNaRECR2(lane->id)); 303 iowrite32(0x00000000, priv->base + LYNX_28G_LNaRSCCR0(lane->id)); 304 } 305 306 static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane) 307 { 308 u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); 309 struct lynx_28g_priv *priv = lane->priv; 310 struct lynx_28g_pll *pll; 311 312 lynx_28g_cleanup_lane(lane); 313 314 /* Enable the SXGMII lane */ 315 lynx_28g_rmw(priv, LYNX_28G_PCCC, 316 LYNX_28G_PCCC_10GBASER << lane_offset, 317 GENMASK(3, 0) << lane_offset); 318 319 /* Setup the protocol select and SerDes parallel interface width */ 320 lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK); 321 lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK); 322 323 /* Find the PLL that works with this interface type */ 324 pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER); 325 if (unlikely(pll == NULL)) 326 return; 327 328 /* Switch to the PLL that works with this interface type */ 329 lynx_28g_lane_set_pll(lane, pll); 330 331 /* Choose the portion of clock net to be used on this lane */ 332 lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_10GBASER); 333 334 /* Disable the SGMII PCS */ 335 lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_DIS, SGPCS_MSK); 336 337 /* Configure the appropriate equalization parameters for the protocol */ 338 iowrite32(0x10808307, priv->base + LYNX_28G_LNaTECR0(lane->id)); 339 iowrite32(0x10000000, priv->base + LYNX_28G_LNaRGCR1(lane->id)); 340 iowrite32(0x00000000, priv->base + LYNX_28G_LNaRECR0(lane->id)); 341 iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id)); 342 iowrite32(0x81000020, priv->base + LYNX_28G_LNaRECR2(lane->id)); 343 iowrite32(0x00002000, priv->base + LYNX_28G_LNaRSCCR0(lane->id)); 344 } 345 346 static int lynx_28g_power_off(struct phy *phy) 347 { 348 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 349 u32 trstctl, rrstctl; 350 351 if (!lane->powered_up) 352 return 0; 353 354 /* Issue a halt request */ 355 lynx_28g_lane_rmw(lane, LNaTRSTCTL, HLT_REQ, HLT_REQ); 356 lynx_28g_lane_rmw(lane, LNaRRSTCTL, HLT_REQ, HLT_REQ); 357 358 /* Wait until the halting process is complete */ 359 do { 360 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL); 361 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 362 } while ((trstctl & LYNX_28G_LNaTRSTCTL_HLT_REQ) || 363 (rrstctl & LYNX_28G_LNaRRSTCTL_HLT_REQ)); 364 365 lane->powered_up = false; 366 367 return 0; 368 } 369 370 static int lynx_28g_power_on(struct phy *phy) 371 { 372 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 373 u32 trstctl, rrstctl; 374 375 if (lane->powered_up) 376 return 0; 377 378 /* Issue a reset request on the lane */ 379 lynx_28g_lane_rmw(lane, LNaTRSTCTL, RST_REQ, RST_REQ); 380 lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ); 381 382 /* Wait until the reset sequence is completed */ 383 do { 384 trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL); 385 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 386 } while (!(trstctl & LYNX_28G_LNaTRSTCTL_RST_DONE) || 387 !(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); 388 389 lane->powered_up = true; 390 391 return 0; 392 } 393 394 static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode) 395 { 396 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 397 struct lynx_28g_priv *priv = lane->priv; 398 int powered_up = lane->powered_up; 399 int err = 0; 400 401 if (mode != PHY_MODE_ETHERNET) 402 return -EOPNOTSUPP; 403 404 if (lane->interface == PHY_INTERFACE_MODE_NA) 405 return -EOPNOTSUPP; 406 407 if (!lynx_28g_supports_interface(priv, submode)) 408 return -EOPNOTSUPP; 409 410 /* If the lane is powered up, put the lane into the halt state while 411 * the reconfiguration is being done. 412 */ 413 if (powered_up) 414 lynx_28g_power_off(phy); 415 416 spin_lock(&priv->pcc_lock); 417 418 switch (submode) { 419 case PHY_INTERFACE_MODE_SGMII: 420 case PHY_INTERFACE_MODE_1000BASEX: 421 lynx_28g_lane_set_sgmii(lane); 422 break; 423 case PHY_INTERFACE_MODE_10GBASER: 424 lynx_28g_lane_set_10gbaser(lane); 425 break; 426 default: 427 err = -EOPNOTSUPP; 428 goto out; 429 } 430 431 lane->interface = submode; 432 433 out: 434 spin_unlock(&priv->pcc_lock); 435 436 /* Power up the lane if necessary */ 437 if (powered_up) 438 lynx_28g_power_on(phy); 439 440 return err; 441 } 442 443 static int lynx_28g_validate(struct phy *phy, enum phy_mode mode, int submode, 444 union phy_configure_opts *opts __always_unused) 445 { 446 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 447 struct lynx_28g_priv *priv = lane->priv; 448 449 if (mode != PHY_MODE_ETHERNET) 450 return -EOPNOTSUPP; 451 452 if (!lynx_28g_supports_interface(priv, submode)) 453 return -EOPNOTSUPP; 454 455 return 0; 456 } 457 458 static int lynx_28g_init(struct phy *phy) 459 { 460 struct lynx_28g_lane *lane = phy_get_drvdata(phy); 461 462 /* Mark the fact that the lane was init */ 463 lane->init = true; 464 465 /* SerDes lanes are powered on at boot time. Any lane that is managed 466 * by this driver will get powered down at init time aka at dpaa2-eth 467 * probe time. 468 */ 469 lane->powered_up = true; 470 lynx_28g_power_off(phy); 471 472 return 0; 473 } 474 475 static const struct phy_ops lynx_28g_ops = { 476 .init = lynx_28g_init, 477 .power_on = lynx_28g_power_on, 478 .power_off = lynx_28g_power_off, 479 .set_mode = lynx_28g_set_mode, 480 .validate = lynx_28g_validate, 481 .owner = THIS_MODULE, 482 }; 483 484 static void lynx_28g_pll_read_configuration(struct lynx_28g_priv *priv) 485 { 486 struct lynx_28g_pll *pll; 487 int i; 488 489 for (i = 0; i < LYNX_28G_NUM_PLL; i++) { 490 pll = &priv->pll[i]; 491 pll->priv = priv; 492 pll->id = i; 493 494 pll->rstctl = lynx_28g_pll_read(pll, PLLnRSTCTL); 495 pll->cr0 = lynx_28g_pll_read(pll, PLLnCR0); 496 pll->cr1 = lynx_28g_pll_read(pll, PLLnCR1); 497 498 if (LYNX_28G_PLLnRSTCTL_DIS(pll->rstctl)) 499 continue; 500 501 switch (LYNX_28G_PLLnCR1_FRATE_SEL(pll->cr1)) { 502 case LYNX_28G_PLLnCR1_FRATE_5G_10GVCO: 503 case LYNX_28G_PLLnCR1_FRATE_5G_25GVCO: 504 /* 5GHz clock net */ 505 __set_bit(PHY_INTERFACE_MODE_1000BASEX, pll->supported); 506 __set_bit(PHY_INTERFACE_MODE_SGMII, pll->supported); 507 break; 508 case LYNX_28G_PLLnCR1_FRATE_10G_20GVCO: 509 /* 10.3125GHz clock net */ 510 __set_bit(PHY_INTERFACE_MODE_10GBASER, pll->supported); 511 break; 512 default: 513 /* 6GHz, 12.890625GHz, 8GHz */ 514 break; 515 } 516 } 517 } 518 519 #define work_to_lynx(w) container_of((w), struct lynx_28g_priv, cdr_check.work) 520 521 static void lynx_28g_cdr_lock_check(struct work_struct *work) 522 { 523 struct lynx_28g_priv *priv = work_to_lynx(work); 524 struct lynx_28g_lane *lane; 525 u32 rrstctl; 526 int i; 527 528 for (i = 0; i < LYNX_28G_NUM_LANE; i++) { 529 lane = &priv->lane[i]; 530 531 mutex_lock(&lane->phy->mutex); 532 533 if (!lane->init || !lane->powered_up) { 534 mutex_unlock(&lane->phy->mutex); 535 continue; 536 } 537 538 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 539 if (!(rrstctl & LYNX_28G_LNaRRSTCTL_CDR_LOCK)) { 540 lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ); 541 do { 542 rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); 543 } while (!(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); 544 } 545 546 mutex_unlock(&lane->phy->mutex); 547 } 548 queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, 549 msecs_to_jiffies(1000)); 550 } 551 552 static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane) 553 { 554 u32 pss, protocol; 555 556 pss = lynx_28g_lane_read(lane, LNaPSS); 557 protocol = LYNX_28G_LNaPSS_TYPE(pss); 558 switch (protocol) { 559 case LYNX_28G_LNaPSS_TYPE_SGMII: 560 lane->interface = PHY_INTERFACE_MODE_SGMII; 561 break; 562 case LYNX_28G_LNaPSS_TYPE_XFI: 563 lane->interface = PHY_INTERFACE_MODE_10GBASER; 564 break; 565 default: 566 lane->interface = PHY_INTERFACE_MODE_NA; 567 } 568 } 569 570 static struct phy *lynx_28g_xlate(struct device *dev, 571 const struct of_phandle_args *args) 572 { 573 struct lynx_28g_priv *priv = dev_get_drvdata(dev); 574 int idx = args->args[0]; 575 576 if (WARN_ON(idx >= LYNX_28G_NUM_LANE)) 577 return ERR_PTR(-EINVAL); 578 579 return priv->lane[idx].phy; 580 } 581 582 static int lynx_28g_probe(struct platform_device *pdev) 583 { 584 struct device *dev = &pdev->dev; 585 struct phy_provider *provider; 586 struct lynx_28g_priv *priv; 587 int i; 588 589 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 590 if (!priv) 591 return -ENOMEM; 592 priv->dev = &pdev->dev; 593 594 priv->base = devm_platform_ioremap_resource(pdev, 0); 595 if (IS_ERR(priv->base)) 596 return PTR_ERR(priv->base); 597 598 lynx_28g_pll_read_configuration(priv); 599 600 for (i = 0; i < LYNX_28G_NUM_LANE; i++) { 601 struct lynx_28g_lane *lane = &priv->lane[i]; 602 struct phy *phy; 603 604 memset(lane, 0, sizeof(*lane)); 605 606 phy = devm_phy_create(&pdev->dev, NULL, &lynx_28g_ops); 607 if (IS_ERR(phy)) 608 return PTR_ERR(phy); 609 610 lane->priv = priv; 611 lane->phy = phy; 612 lane->id = i; 613 phy_set_drvdata(phy, lane); 614 lynx_28g_lane_read_configuration(lane); 615 } 616 617 dev_set_drvdata(dev, priv); 618 619 spin_lock_init(&priv->pcc_lock); 620 INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); 621 622 queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, 623 msecs_to_jiffies(1000)); 624 625 dev_set_drvdata(&pdev->dev, priv); 626 provider = devm_of_phy_provider_register(&pdev->dev, lynx_28g_xlate); 627 628 return PTR_ERR_OR_ZERO(provider); 629 } 630 631 static void lynx_28g_remove(struct platform_device *pdev) 632 { 633 struct device *dev = &pdev->dev; 634 struct lynx_28g_priv *priv = dev_get_drvdata(dev); 635 636 cancel_delayed_work_sync(&priv->cdr_check); 637 } 638 639 static const struct of_device_id lynx_28g_of_match_table[] = { 640 { .compatible = "fsl,lynx-28g" }, 641 { }, 642 }; 643 MODULE_DEVICE_TABLE(of, lynx_28g_of_match_table); 644 645 static struct platform_driver lynx_28g_driver = { 646 .probe = lynx_28g_probe, 647 .remove = lynx_28g_remove, 648 .driver = { 649 .name = "lynx-28g", 650 .of_match_table = lynx_28g_of_match_table, 651 }, 652 }; 653 module_platform_driver(lynx_28g_driver); 654 655 MODULE_AUTHOR("Ioana Ciornei <ioana.ciornei@nxp.com>"); 656 MODULE_DESCRIPTION("Lynx 28G SerDes PHY driver for Layerscape SoCs"); 657 MODULE_LICENSE("GPL v2"); 658