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
lynx_28g_rmw(struct lynx_28g_priv * priv,unsigned long off,u32 val,u32 mask)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
lynx_28g_supports_interface(struct lynx_28g_priv * priv,int intf)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
lynx_28g_pll_get(struct lynx_28g_priv * priv,phy_interface_t intf)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 return NULL;
192 }
193
lynx_28g_lane_set_nrate(struct lynx_28g_lane * lane,struct lynx_28g_pll * pll,phy_interface_t intf)194 static 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
lynx_28g_lane_set_pll(struct lynx_28g_lane * lane,struct lynx_28g_pll * pll)227 static 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
lynx_28g_cleanup_lane(struct lynx_28g_lane * lane)239 static 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
lynx_28g_lane_set_sgmii(struct lynx_28g_lane * lane)262 static 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
lynx_28g_lane_set_10gbaser(struct lynx_28g_lane * lane)298 static 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
lynx_28g_power_off(struct phy * phy)334 static 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
lynx_28g_power_on(struct phy * phy)358 static 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
lynx_28g_set_mode(struct phy * phy,enum phy_mode mode,int submode)382 static 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
421 out:
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
lynx_28g_validate(struct phy * phy,enum phy_mode mode,int submode,union phy_configure_opts * opts __always_unused)431 static 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
lynx_28g_init(struct phy * phy)446 static 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
463 static 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
lynx_28g_pll_read_configuration(struct lynx_28g_priv * priv)472 static 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
lynx_28g_cdr_lock_check(struct work_struct * work)509 static 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
lynx_28g_lane_read_configuration(struct lynx_28g_lane * lane)540 static 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
lynx_28g_xlate(struct device * dev,const struct of_phandle_args * args)558 static 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
lynx_28g_probe(struct platform_device * pdev)570 static 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
lynx_28g_remove(struct platform_device * pdev)619 static 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
627 static const struct of_device_id lynx_28g_of_match_table[] = {
628 { .compatible = "fsl,lynx-28g" },
629 { },
630 };
631 MODULE_DEVICE_TABLE(of, lynx_28g_of_match_table);
632
633 static 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 };
641 module_platform_driver(lynx_28g_driver);
642
643 MODULE_AUTHOR("Ioana Ciornei <ioana.ciornei@nxp.com>");
644 MODULE_DESCRIPTION("Lynx 28G SerDes PHY driver for Layerscape SoCs");
645 MODULE_LICENSE("GPL v2");
646