xref: /linux/drivers/phy/freescale/phy-fsl-lynx-28g.c (revision 1d1ba4d390141d602dbce8f5f0ac19a384d10a64)
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 	/* 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 
lynx_28g_lane_set_nrate(struct lynx_28g_lane * lane,struct lynx_28g_pll * pll,phy_interface_t intf)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 
lynx_28g_lane_set_pll(struct lynx_28g_lane * lane,struct lynx_28g_pll * pll)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 
lynx_28g_cleanup_lane(struct lynx_28g_lane * lane)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 
lynx_28g_lane_set_sgmii(struct lynx_28g_lane * lane)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 
lynx_28g_lane_set_10gbaser(struct lynx_28g_lane * lane)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 
lynx_28g_power_off(struct phy * phy)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 
lynx_28g_power_on(struct phy * phy)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 
lynx_28g_set_mode(struct phy * phy,enum phy_mode mode,int submode)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 
lynx_28g_validate(struct phy * phy,enum phy_mode mode,int submode,union phy_configure_opts * opts __always_unused)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 
lynx_28g_init(struct phy * phy)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 
lynx_28g_pll_read_configuration(struct lynx_28g_priv * priv)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 
lynx_28g_cdr_lock_check(struct work_struct * work)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 
lynx_28g_lane_read_configuration(struct lynx_28g_lane * lane)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 
lynx_28g_xlate(struct device * dev,const struct of_phandle_args * args)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 
lynx_28g_probe(struct platform_device * pdev)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 
lynx_28g_remove(struct platform_device * pdev)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