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