xref: /linux/drivers/phy/freescale/phy-fsl-lynx-10g.c (revision 16e6a1a3cb3fa5fa11cd76a9d71235d927923329)
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Copyright 2021-2026 NXP */
3 
4 #include <linux/delay.h>
5 #include <linux/module.h>
6 #include <linux/of.h>
7 #include <linux/phy.h>
8 #include <linux/phy/phy.h>
9 #include <linux/platform_device.h>
10 #include <linux/workqueue.h>
11 #include <linux/fsl/guts.h>
12 
13 #include "phy-fsl-lynx-core.h"
14 
15 /* SoC IP wrapper for protocol converters */
16 #define PCCR8				0x220
17 #define PCCR8_SGMIIa_KX			BIT(3)
18 #define PCCR8_SGMIIa_CFG		GENMASK(2, 0)
19 
20 #define PCCR9				0x224
21 #define PCCR9_QSGMIIa_CFG		GENMASK(2, 0)
22 #define PCCR9_QXGMIIa_CFG		GENMASK(2, 0)
23 
24 #define PCCRB				0x22c
25 #define PCCRB_XFIa_CFG			GENMASK(2, 0)
26 #define PCCRB_SXGMIIa_CFG		GENMASK(2, 0)
27 
28 #define SGMII_CFG(id)			(28 - (id) * 4)
29 #define QSGMII_CFG(id)			(28 - (id) * 4)
30 #define SXGMII_CFG(id)			(28 - (id) * 4)
31 #define QXGMII_CFG(id)			(12 - (id) * 4)
32 #define XFI_CFG(id)			(28 - (id) * 4)
33 
34 #define CR(x)				((x) * 4)
35 
36 #define A				0
37 #define B				1
38 #define C				2
39 #define D				3
40 #define E				4
41 #define F				5
42 #define G				6
43 #define H				7
44 
45 #define SGMIIaCR0(id)			(0x1800 + (id) * 0x10)
46 #define QSGMIIaCR0(id)			(0x1880 + (id) * 0x10)
47 #define XAUIaCR0(id)			(0x1900 + (id) * 0x10)
48 #define XFIaCR0(id)			(0x1980 + (id) * 0x10)
49 #define SXGMIIaCR0(id)			(0x1a80 + (id) * 0x10)
50 #define QXGMIIaCR0(id)			(0x1b00 + (id) * 0x20)
51 
52 #define SGMIIaCR0_RST_SGM		BIT(31)
53 #define SGMIIaCR0_RST_SGM_OFF		SGMIIaCR0_RST_SGM
54 #define SGMIIaCR0_RST_SGM_ON		0
55 #define SGMIIaCR0_PD_SGM		BIT(30)
56 #define SGMIIaCR1_SGPCS_EN		BIT(11)
57 #define SGMIIaCR1_SGPCS_DIS		0x0
58 
59 #define QSGMIIaCR0_RST_QSGM		BIT(31)
60 #define QSGMIIaCR0_RST_QSGM_OFF		QSGMIIaCR0_RST_QSGM
61 #define QSGMIIaCR0_RST_QSGM_ON		0
62 #define QSGMIIaCR0_PD_QSGM		BIT(30)
63 
64 /* Per PLL registers */
65 #define PLLnCR0(pll)			((pll) * 0x20 + 0x4)
66 
67 #define PLLnCR0_POFF			BIT(31)
68 
69 #define PLLnCR0_REFCLK_SEL		GENMASK(30, 28)
70 #define PLLnCR0_REFCLK_SEL_100MHZ	0x0
71 #define PLLnCR0_REFCLK_SEL_125MHZ	0x1
72 #define PLLnCR0_REFCLK_SEL_156MHZ	0x2
73 #define PLLnCR0_REFCLK_SEL_150MHZ	0x3
74 #define PLLnCR0_REFCLK_SEL_161MHZ	0x4
75 #define PLLnCR0_PLL_LCK			BIT(23)
76 #define PLLnCR0_FRATE_SEL		GENMASK(19, 16)
77 #define PLLnCR0_FRATE_5G		0x0
78 #define PLLnCR0_FRATE_5_15625G		0x6
79 #define PLLnCR0_FRATE_4G		0x7
80 #define PLLnCR0_FRATE_3_125G		0x9
81 #define PLLnCR0_FRATE_3G		0xa
82 
83 /* Per SerDes lane registers */
84 
85 /* Lane a Protocol Select status register */
86 #define LNaPSSR0(lane)			(0x100 + (lane) * 0x20)
87 #define LNaPSSR0_TYPE			GENMASK(30, 26)
88 #define LNaPSSR0_IS_QUAD		GENMASK(25, 24)
89 #define LNaPSSR0_MAC			GENMASK(19, 16)
90 #define LNaPSSR0_PCS			GENMASK(10, 8)
91 #define LNaPSSR0_LANE			GENMASK(2, 0)
92 
93 /* Lane a General Control Register */
94 #define LNaGCR0(lane)			(0x800 + (lane) * 0x40 + 0x0)
95 #define LNaGCR0_RPLL_PLLF		BIT(31)
96 #define LNaGCR0_RPLL_PLLS		0x0
97 #define LNaGCR0_RPLL_MSK		BIT(31)
98 #define LNaGCR0_RRAT_SEL		GENMASK(29, 28)
99 #define LNaGCR0_TRAT_SEL		GENMASK(25, 24)
100 #define LNaGCR0_TPLL_PLLF		BIT(27)
101 #define LNaGCR0_TPLL_PLLS		0x0
102 #define LNaGCR0_TPLL_MSK		BIT(27)
103 #define LNaGCR0_RRST_OFF		LNaGCR0_RRST
104 #define LNaGCR0_TRST_OFF		LNaGCR0_TRST
105 #define LNaGCR0_RRST_ON			0x0
106 #define LNaGCR0_TRST_ON			0x0
107 #define LNaGCR0_RRST			BIT(22)
108 #define LNaGCR0_TRST			BIT(21)
109 #define LNaGCR0_RX_PD			BIT(20)
110 #define LNaGCR0_TX_PD			BIT(19)
111 #define LNaGCR0_IF20BIT_EN		BIT(18)
112 #define LNaGCR0_PROTS			GENMASK(11, 7)
113 
114 #define LNaGCR1(lane)			(0x800 + (lane) * 0x40 + 0x4)
115 #define LNaGCR1_RDAT_INV		BIT(31)
116 #define LNaGCR1_TDAT_INV		BIT(30)
117 #define LNaGCR1_OPAD_CTL		BIT(26)
118 #define LNaGCR1_REIDL_TH		GENMASK(22, 20)
119 #define LNaGCR1_REIDL_EX_SEL		GENMASK(19, 18)
120 #define LNaGCR1_REIDL_ET_SEL		GENMASK(17, 16)
121 #define LNaGCR1_REIDL_EX_MSB		BIT(15)
122 #define LNaGCR1_REIDL_ET_MSB		BIT(14)
123 #define LNaGCR1_REQ_CTL_SNP		BIT(13)
124 #define LNaGCR1_REQ_CDR_SNP		BIT(12)
125 #define LNaGCR1_TRSTDIR			BIT(7)
126 #define LNaGCR1_REQ_BIN_SNP		BIT(6)
127 #define LNaGCR1_ISLEW_RCTL		GENMASK(5, 4)
128 #define LNaGCR1_OSLEW_RCTL		GENMASK(1, 0)
129 
130 #define LNaRECR0(lane)			(0x800 + (lane) * 0x40 + 0x10)
131 #define LNaRECR0_RXEQ_BST		BIT(28)
132 #define LNaRECR0_GK2OVD			GENMASK(27, 24)
133 #define LNaRECR0_GK3OVD			GENMASK(19, 16)
134 #define LNaRECR0_GK2OVD_EN		BIT(15)
135 #define LNaRECR0_GK3OVD_EN		BIT(14)
136 #define LNaRECR0_OSETOVD_EN		BIT(13)
137 #define LNaRECR0_BASE_WAND		GENMASK(11, 10)
138 #define LNaRECR0_OSETOVD		GENMASK(6, 0)
139 
140 #define LNaTECR0(lane)			(0x800 + (lane) * 0x40 + 0x18)
141 #define LNaTECR0_TEQ_TYPE		GENMASK(29, 28)
142 #define LNaTECR0_SGN_PREQ		BIT(26)
143 #define LNaTECR0_RATIO_PREQ		GENMASK(25, 22)
144 #define LNaTECR0_SGN_POST1Q		BIT(21)
145 #define LNaTECR0_RATIO_PST1Q		GENMASK(20, 16)
146 #define LNaTECR0_ADPT_EQ		GENMASK(13, 8)
147 #define LNaTECR0_AMP_RED		GENMASK(5, 0)
148 
149 #define LNaTTLCR0(lane)			(0x800 + (lane) * 0x40 + 0x20)
150 #define LNaTTLCR1(lane)			(0x800 + (lane) * 0x40 + 0x24)
151 #define LNaTTLCR2(lane)			(0x800 + (lane) * 0x40 + 0x28)
152 
153 #define LNaTCSR3(lane)			(0x800 + (lane) * 0x40 + 0x3C)
154 #define LNaTCSR3_CDR_LCK		BIT(27)
155 
156 enum lynx_10g_rat_sel {
157 	RAT_SEL_FULL = 0x0,
158 	RAT_SEL_HALF = 0x1,
159 	RAT_SEL_QUARTER = 0x2,
160 	RAT_SEL_DOUBLE = 0x3,
161 };
162 
163 enum lynx_10g_eq_type {
164 	EQ_TYPE_NO_EQ = 0,
165 	EQ_TYPE_2TAP = 1,
166 	EQ_TYPE_3TAP = 2,
167 };
168 
169 enum lynx_10g_proto_sel {
170 	PROTO_SEL_PCIE = 0,
171 	PROTO_SEL_SGMII_BASEX_KX_QSGMII = 1,
172 	PROTO_SEL_SATA = 2,
173 	PROTO_SEL_XAUI = 4,
174 	PROTO_SEL_XFI_10GBASER_KR_SXGMII = 0xa,
175 };
176 
177 struct lynx_10g_proto_conf {
178 	int proto_sel;
179 	int if20bit_en;
180 	int reidl_th;
181 	int reidl_et_msb;
182 	int reidl_et_sel;
183 	int reidl_ex_msb;
184 	int reidl_ex_sel;
185 	int islew_rctl;
186 	int oslew_rctl;
187 	int rxeq_bst;
188 	int gk2ovd;
189 	int gk3ovd;
190 	int gk2ovd_en;
191 	int gk3ovd_en;
192 	int base_wand;
193 	int teq_type;
194 	int sgn_preq;
195 	int ratio_preq;
196 	int sgn_post1q;
197 	int ratio_post1q;
198 	int adpt_eq;
199 	int amp_red;
200 	int ttlcr0;
201 };
202 
203 static const struct lynx_10g_proto_conf lynx_10g_proto_conf[LANE_MODE_MAX] = {
204 	[LANE_MODE_1000BASEX_SGMII] = {
205 		.proto_sel = PROTO_SEL_SGMII_BASEX_KX_QSGMII,
206 		.reidl_th = 1,
207 		.reidl_ex_sel = 3,
208 		.reidl_et_msb = 1,
209 		.islew_rctl = 1,
210 		.oslew_rctl = 1,
211 		.gk2ovd = 15,
212 		.gk3ovd = 15,
213 		.gk2ovd_en = 1,
214 		.gk3ovd_en = 1,
215 		.teq_type = EQ_TYPE_NO_EQ,
216 		.adpt_eq = 48,
217 		.amp_red = 6,
218 		.ttlcr0 = 0x39000400,
219 	},
220 	[LANE_MODE_2500BASEX] = {
221 		.proto_sel = PROTO_SEL_SGMII_BASEX_KX_QSGMII,
222 		.islew_rctl = 2,
223 		.oslew_rctl = 2,
224 		.teq_type = EQ_TYPE_2TAP,
225 		.sgn_post1q = 1,
226 		.ratio_post1q = 6,
227 		.adpt_eq = 48,
228 		.ttlcr0 = 0x00000400,
229 	},
230 	[LANE_MODE_QSGMII] = {
231 		.proto_sel = PROTO_SEL_SGMII_BASEX_KX_QSGMII,
232 		.islew_rctl = 1,
233 		.oslew_rctl = 1,
234 		.teq_type = EQ_TYPE_2TAP,
235 		.sgn_post1q = 1,
236 		.ratio_post1q = 6,
237 		.adpt_eq = 48,
238 		.amp_red = 2,
239 		.ttlcr0 = 0x00000400,
240 	},
241 	[LANE_MODE_10G_QXGMII] = {
242 		.proto_sel = PROTO_SEL_XFI_10GBASER_KR_SXGMII,
243 		.if20bit_en = 1,
244 		.islew_rctl = 1,
245 		.oslew_rctl = 1,
246 		.base_wand = 1,
247 		.teq_type = EQ_TYPE_NO_EQ,
248 		.adpt_eq = 48,
249 		.ttlcr0 = 0x00000400,
250 	},
251 	[LANE_MODE_USXGMII] = {
252 		.proto_sel = PROTO_SEL_XFI_10GBASER_KR_SXGMII,
253 		.if20bit_en = 1,
254 		.islew_rctl = 1,
255 		.oslew_rctl = 1,
256 		.base_wand = 1,
257 		.teq_type = EQ_TYPE_NO_EQ,
258 		.sgn_post1q = 1,
259 		.adpt_eq = 48,
260 		.ttlcr0 = 0x00000400,
261 	},
262 	[LANE_MODE_10GBASER] = {
263 		.proto_sel = PROTO_SEL_XFI_10GBASER_KR_SXGMII,
264 		.if20bit_en = 1,
265 		.islew_rctl = 2,
266 		.oslew_rctl = 2,
267 		.rxeq_bst = 1,
268 		.base_wand = 1,
269 		.teq_type = EQ_TYPE_2TAP,
270 		.sgn_post1q = 1,
271 		.ratio_post1q = 3,
272 		.adpt_eq = 48,
273 		.amp_red = 7,
274 		.ttlcr0 = 0x00000400,
275 	},
276 };
277 
lynx_10g_cdr_lock_check(struct lynx_lane * lane)278 static void lynx_10g_cdr_lock_check(struct lynx_lane *lane)
279 {
280 	u32 tcsr3 = lynx_lane_read(lane, LNaTCSR3);
281 
282 	if (tcsr3 & LNaTCSR3_CDR_LCK)
283 		return;
284 
285 	dev_dbg(&lane->phy->dev,
286 		"Lane %c CDR unlocked, resetting receiver...\n",
287 		'A' + lane->id);
288 
289 	lynx_lane_rmw(lane, LNaGCR0, LNaGCR0_RRST_ON, LNaGCR0_RRST);
290 	usleep_range(1, 2);
291 	lynx_lane_rmw(lane, LNaGCR0, LNaGCR0_RRST_OFF, LNaGCR0_RRST);
292 
293 	usleep_range(1, 2);
294 }
295 
lynx_10g_pll_read_configuration(struct lynx_pll * pll)296 static void lynx_10g_pll_read_configuration(struct lynx_pll *pll)
297 {
298 	u32 val;
299 
300 	val = lynx_pll_read(pll, PLLnCR0);
301 	pll->frate_sel = FIELD_GET(PLLnCR0_FRATE_SEL, val);
302 	pll->refclk_sel = FIELD_GET(PLLnCR0_REFCLK_SEL, val);
303 	pll->enabled = !(val & PLLnCR0_POFF);
304 	pll->locked = !!(val & PLLnCR0_PLL_LCK);
305 
306 	if (!pll->enabled)
307 		return;
308 
309 	switch (pll->frate_sel) {
310 	case PLLnCR0_FRATE_5G:
311 		/* 5GHz clock net */
312 		__set_bit(LANE_MODE_1000BASEX_SGMII, pll->supported);
313 		__set_bit(LANE_MODE_QSGMII, pll->supported);
314 		break;
315 	case PLLnCR0_FRATE_3_125G:
316 		__set_bit(LANE_MODE_2500BASEX, pll->supported);
317 		break;
318 	case PLLnCR0_FRATE_5_15625G:
319 		/* 10.3125GHz clock net */
320 		__set_bit(LANE_MODE_10GBASER, pll->supported);
321 		__set_bit(LANE_MODE_USXGMII, pll->supported);
322 		__set_bit(LANE_MODE_10G_QXGMII, pll->supported);
323 		break;
324 	default:
325 		break;
326 	}
327 }
328 
329 /* On LS1028A, SGMIIA_CFG, SGMIIB_CFG, and SGMIIC_CFG from PCCR8 have the
330  * ability to map either an ENETC PCS (PCCR8_SGMIIa_CFG=2) or a Felix switch
331  * PCS (PCCR8_SGMIIa_CFG=1) to the same lane.
332  *
333  * On LS1088A, the same QSGMII PCS B can be connected to SerDes lane 1
334  * (PCCR9_QSGMIIa_CFG=1) or to lane 3 (PCCR9_QSGMIIa_CFG=2).
335  *
336  * The PHY API lacks the capability to distinguish anything about the consumer,
337  * so we don't support changing the initial muxing done by the RCW.
338  *
339  * However, after disabling a PCS through PCCR8, we need to properly restore
340  * the original value to keep the same muxing, and for that we need to back
341  * it up (here).
342  */
lynx_10g_backup_pccr_val(struct lynx_lane * lane)343 static void lynx_10g_backup_pccr_val(struct lynx_lane *lane)
344 {
345 	u32 val;
346 	int err;
347 
348 	if (lane->mode == LANE_MODE_UNKNOWN)
349 		return;
350 
351 	err = lynx_pccr_read(lane, lane->mode, &val);
352 	if (err) {
353 		dev_warn(&lane->phy->dev,
354 			 "The driver doesn't know how to access the PCCR for lane mode %s\n",
355 			 lynx_lane_mode_str(lane->mode));
356 		lane->mode = LANE_MODE_UNKNOWN;
357 		return;
358 	}
359 
360 	lane->default_pccr[lane->mode] = val;
361 
362 	/* 1000Base-X, 1000Base-KX, 2500Base-KX and SGMII use the same PCCR8.
363 	 * Only the KX bit differs (set for 1000Base-KX). Since we back up PCCR
364 	 * values per lane mode, make sure to not back up the PCCR8 value with
365 	 * the KX bit set for the non-KX modes, if the lane was in KX mode at
366 	 * boot time. Just preserve bits 2:0, which tell whether the (and
367 	 * which) 1G PCS was enabled.
368 	 */
369 	switch (lane->mode) {
370 	case LANE_MODE_1000BASEX_SGMII:
371 	case LANE_MODE_2500BASEX:
372 		lane->default_pccr[LANE_MODE_1000BASEX_SGMII] = val & ~PCCR8_SGMIIa_KX;
373 		lane->default_pccr[LANE_MODE_2500BASEX] = val & ~PCCR8_SGMIIa_KX;
374 		break;
375 	default:
376 		break;
377 	}
378 }
379 
380 /* Is the PCS enabled, according to the value backed up from the PCCR register
381  * for this lane mode?
382  *
383  * Normally we'd need to ask "what lane mode are we talking about?", but the
384  * answer is invariably the same regardless - PCCR8_SGMIIa_CFG has the same
385  * layout as PCCR9_QSGMIIa_CFG, PCCRB_XFIa_CFG etc etc, and the value 0
386  * universally means "PCS disabled". So this is just a shorthand answer.
387  */
lynx_10g_pccr_val_enabled(u32 pccr)388 static bool lynx_10g_pccr_val_enabled(u32 pccr)
389 {
390 	return FIELD_GET(PCCR8_SGMIIa_CFG, pccr) != 0;
391 }
392 
lynx_10g_lane_is_3_125g(struct lynx_lane * lane)393 static bool lynx_10g_lane_is_3_125g(struct lynx_lane *lane)
394 {
395 	struct lynx_priv *priv = lane->priv;
396 	struct lynx_pll *pll;
397 	u32 gcr0;
398 
399 	gcr0 = lynx_lane_read(lane, LNaGCR0);
400 
401 	if (gcr0 & LNaGCR0_TPLL_PLLF)
402 		pll = &priv->pll[0];
403 	else
404 		pll = &priv->pll[1];
405 
406 	if (pll->frate_sel != PLLnCR0_FRATE_3_125G)
407 		return false;
408 
409 	if (FIELD_GET(LNaGCR0_TRAT_SEL, gcr0) != RAT_SEL_FULL ||
410 	    FIELD_GET(LNaGCR0_RRAT_SEL, gcr0) != RAT_SEL_FULL)
411 		return false;
412 
413 	return true;
414 }
415 
lynx_10g_lane_read_configuration(struct lynx_lane * lane)416 static void lynx_10g_lane_read_configuration(struct lynx_lane *lane)
417 {
418 	u32 pssr0 = lynx_lane_read(lane, LNaPSSR0);
419 	struct lynx_priv *priv = lane->priv;
420 	int proto;
421 
422 	proto = FIELD_GET(LNaPSSR0_TYPE, pssr0);
423 	switch (proto) {
424 	case PROTO_SEL_SGMII_BASEX_KX_QSGMII:
425 		if (lynx_10g_lane_is_3_125g(lane))
426 			lane->mode = LANE_MODE_2500BASEX;
427 		else if (FIELD_GET(LNaPSSR0_IS_QUAD, pssr0))
428 			lane->mode = LANE_MODE_QSGMII;
429 		else
430 			lane->mode = LANE_MODE_1000BASEX_SGMII;
431 		break;
432 	case PROTO_SEL_XFI_10GBASER_KR_SXGMII:
433 		if (FIELD_GET(LNaPSSR0_IS_QUAD, pssr0))
434 			lane->mode = LANE_MODE_10G_QXGMII;
435 		else if (priv->info->quirks & LYNX_QUIRK_HAS_HARDCODED_USXGMII)
436 			lane->mode = LANE_MODE_USXGMII;
437 		else
438 			lane->mode = LANE_MODE_10GBASER;
439 		break;
440 	case PROTO_SEL_PCIE:
441 	case PROTO_SEL_SATA:
442 	case PROTO_SEL_XAUI:
443 		break;
444 	default:
445 		dev_warn(&lane->phy->dev, "Unknown lane protocol 0x%x\n",
446 			 proto);
447 	}
448 
449 	lynx_10g_backup_pccr_val(lane);
450 }
451 
ls1028a_get_pccr(enum lynx_lane_mode lane_mode,int lane,struct lynx_pccr * pccr)452 static int ls1028a_get_pccr(enum lynx_lane_mode lane_mode, int lane,
453 			    struct lynx_pccr *pccr)
454 {
455 	switch (lane_mode) {
456 	case LANE_MODE_1000BASEX_SGMII:
457 	case LANE_MODE_2500BASEX:
458 		pccr->offset = PCCR8;
459 		pccr->width = 4;
460 		pccr->shift = SGMII_CFG(lane);
461 		break;
462 	case LANE_MODE_QSGMII:
463 		if (lane != 1)
464 			return -EINVAL;
465 
466 		pccr->offset = PCCR9;
467 		pccr->width = 3;
468 		pccr->shift = QSGMII_CFG(A);
469 		break;
470 	case LANE_MODE_10G_QXGMII:
471 		if (lane != 1)
472 			return -EINVAL;
473 
474 		pccr->offset = PCCR9;
475 		pccr->width = 3;
476 		pccr->shift = QXGMII_CFG(A);
477 		break;
478 	case LANE_MODE_USXGMII:
479 		if (lane != 0)
480 			return -EINVAL;
481 
482 		pccr->offset = PCCRB;
483 		pccr->width = 3;
484 		pccr->shift = SXGMII_CFG(A);
485 		break;
486 	default:
487 		return -EINVAL;
488 	}
489 
490 	return 0;
491 }
492 
ls1028a_get_pcvt_offset(int lane,enum lynx_lane_mode mode)493 static int ls1028a_get_pcvt_offset(int lane, enum lynx_lane_mode mode)
494 {
495 	switch (mode) {
496 	case LANE_MODE_1000BASEX_SGMII:
497 	case LANE_MODE_2500BASEX:
498 		return SGMIIaCR0(lane);
499 	case LANE_MODE_QSGMII:
500 		return lane == 1 ? QSGMIIaCR0(A) : -EINVAL;
501 	case LANE_MODE_USXGMII:
502 		return lane == 0 ? SXGMIIaCR0(A) : -EINVAL;
503 	case LANE_MODE_10G_QXGMII:
504 		return lane == 1 ? QXGMIIaCR0(A) : -EINVAL;
505 	default:
506 		return -EINVAL;
507 	}
508 }
509 
510 static const struct lynx_info lynx_info_ls1028a = {
511 	.get_pccr = ls1028a_get_pccr,
512 	.get_pcvt_offset = ls1028a_get_pcvt_offset,
513 	.pll_read_configuration = lynx_10g_pll_read_configuration,
514 	.lane_read_configuration = lynx_10g_lane_read_configuration,
515 	.cdr_lock_check = lynx_10g_cdr_lock_check,
516 	.num_lanes = 4,
517 	.index = 1,
518 	.quirks = LYNX_QUIRK_HAS_HARDCODED_USXGMII,
519 };
520 
ls1046a_serdes1_get_pccr(enum lynx_lane_mode lane_mode,int lane,struct lynx_pccr * pccr)521 static int ls1046a_serdes1_get_pccr(enum lynx_lane_mode lane_mode, int lane,
522 				    struct lynx_pccr *pccr)
523 {
524 	switch (lane_mode) {
525 	case LANE_MODE_1000BASEX_SGMII:
526 	case LANE_MODE_2500BASEX:
527 		pccr->offset = PCCR8;
528 		pccr->width = 4;
529 		pccr->shift = SGMII_CFG(lane);
530 		break;
531 	case LANE_MODE_QSGMII:
532 		if (lane != 1)
533 			return -EINVAL;
534 
535 		pccr->offset = PCCR9;
536 		pccr->width = 3;
537 		pccr->shift = QSGMII_CFG(B);
538 		break;
539 	case LANE_MODE_10GBASER:
540 		switch (lane) {
541 		case 2:
542 			pccr->shift = XFI_CFG(A);
543 			break;
544 		case 3:
545 			pccr->shift = XFI_CFG(B);
546 			break;
547 		default:
548 			return -EINVAL;
549 		}
550 
551 		pccr->offset = PCCRB;
552 		pccr->width = 3;
553 		break;
554 	default:
555 		return -EINVAL;
556 	}
557 
558 	return 0;
559 }
560 
ls1046a_serdes1_get_pcvt_offset(int lane,enum lynx_lane_mode mode)561 static int ls1046a_serdes1_get_pcvt_offset(int lane, enum lynx_lane_mode mode)
562 {
563 	switch (mode) {
564 	case LANE_MODE_1000BASEX_SGMII:
565 	case LANE_MODE_2500BASEX:
566 		return SGMIIaCR0(lane);
567 	case LANE_MODE_QSGMII:
568 		if (lane != 1)
569 			return -EINVAL;
570 
571 		return QSGMIIaCR0(B);
572 	case LANE_MODE_10GBASER:
573 		switch (lane) {
574 		case 2:
575 			return XFIaCR0(A);
576 		case 3:
577 			return XFIaCR0(B);
578 		default:
579 			return -EINVAL;
580 		}
581 	default:
582 		return -EINVAL;
583 	}
584 }
585 
586 static const struct lynx_info lynx_info_ls1046a_serdes1 = {
587 	.get_pccr = ls1046a_serdes1_get_pccr,
588 	.get_pcvt_offset = ls1046a_serdes1_get_pcvt_offset,
589 	.pll_read_configuration = lynx_10g_pll_read_configuration,
590 	.lane_read_configuration = lynx_10g_lane_read_configuration,
591 	.cdr_lock_check = lynx_10g_cdr_lock_check,
592 	.num_lanes = 4,
593 	.index = 1,
594 };
595 
ls1046a_serdes2_get_pccr(enum lynx_lane_mode lane_mode,int lane,struct lynx_pccr * pccr)596 static int ls1046a_serdes2_get_pccr(enum lynx_lane_mode lane_mode, int lane,
597 				    struct lynx_pccr *pccr)
598 {
599 	switch (lane_mode) {
600 	case LANE_MODE_1000BASEX_SGMII:
601 	case LANE_MODE_2500BASEX:
602 		if (lane != 1)
603 			return -EINVAL;
604 
605 		pccr->offset = PCCR8;
606 		pccr->width = 4;
607 		pccr->shift = SGMII_CFG(B);
608 		break;
609 	default:
610 		return -EINVAL;
611 	}
612 
613 	return 0;
614 }
615 
ls1046a_serdes2_get_pcvt_offset(int lane,enum lynx_lane_mode mode)616 static int ls1046a_serdes2_get_pcvt_offset(int lane, enum lynx_lane_mode mode)
617 {
618 	switch (mode) {
619 	case LANE_MODE_1000BASEX_SGMII:
620 	case LANE_MODE_2500BASEX:
621 		if (lane != 1)
622 			return -EINVAL;
623 
624 		return SGMIIaCR0(B);
625 	default:
626 		return -EINVAL;
627 	}
628 }
629 
630 static const struct lynx_info lynx_info_ls1046a_serdes2 = {
631 	.get_pccr = ls1046a_serdes2_get_pccr,
632 	.get_pcvt_offset = ls1046a_serdes2_get_pcvt_offset,
633 	.pll_read_configuration = lynx_10g_pll_read_configuration,
634 	.lane_read_configuration = lynx_10g_lane_read_configuration,
635 	.cdr_lock_check = lynx_10g_cdr_lock_check,
636 	.num_lanes = 4,
637 	.index = 2,
638 };
639 
ls1088a_serdes1_get_pccr(enum lynx_lane_mode lane_mode,int lane,struct lynx_pccr * pccr)640 static int ls1088a_serdes1_get_pccr(enum lynx_lane_mode lane_mode, int lane,
641 				    struct lynx_pccr *pccr)
642 {
643 	switch (lane_mode) {
644 	case LANE_MODE_1000BASEX_SGMII:
645 		pccr->offset = PCCR8;
646 		pccr->width = 4;
647 		pccr->shift = SGMII_CFG(lane);
648 		break;
649 	case LANE_MODE_QSGMII:
650 		switch (lane) {
651 		case 0:
652 			pccr->shift = QSGMII_CFG(A);
653 			break;
654 		case 1:
655 		case 3:
656 			pccr->shift = QSGMII_CFG(B);
657 			break;
658 		default:
659 			return -EINVAL;
660 		}
661 
662 		pccr->offset = PCCR9;
663 		pccr->width = 3;
664 		break;
665 	case LANE_MODE_10GBASER:
666 		switch (lane) {
667 		case 2:
668 			pccr->shift = XFI_CFG(A);
669 			break;
670 		case 3:
671 			pccr->shift = XFI_CFG(B);
672 			break;
673 		default:
674 			return -EINVAL;
675 		}
676 
677 		pccr->offset = PCCRB;
678 		pccr->width = 3;
679 		break;
680 	default:
681 		return -EINVAL;
682 	}
683 
684 	return 0;
685 }
686 
ls1088a_serdes1_get_pcvt_offset(int lane,enum lynx_lane_mode mode)687 static int ls1088a_serdes1_get_pcvt_offset(int lane, enum lynx_lane_mode mode)
688 {
689 	switch (mode) {
690 	case LANE_MODE_1000BASEX_SGMII:
691 		return SGMIIaCR0(lane);
692 	case LANE_MODE_QSGMII:
693 		switch (lane) {
694 		case 0:
695 			return QSGMIIaCR0(A);
696 		case 1:
697 		case 3:
698 			return QSGMIIaCR0(B);
699 		default:
700 			return -EINVAL;
701 		}
702 	case LANE_MODE_10GBASER:
703 		switch (lane) {
704 		case 2:
705 			return XFIaCR0(A);
706 		case 3:
707 			return XFIaCR0(B);
708 		default:
709 			return -EINVAL;
710 		}
711 	default:
712 		return -EINVAL;
713 	}
714 }
715 
716 static const struct lynx_info lynx_info_ls1088a_serdes1 = {
717 	.get_pccr = ls1088a_serdes1_get_pccr,
718 	.get_pcvt_offset = ls1088a_serdes1_get_pcvt_offset,
719 	.pll_read_configuration = lynx_10g_pll_read_configuration,
720 	.lane_read_configuration = lynx_10g_lane_read_configuration,
721 	.cdr_lock_check = lynx_10g_cdr_lock_check,
722 	.num_lanes = 4,
723 	.index = 1,
724 };
725 
ls2088a_serdes1_get_pccr(enum lynx_lane_mode lane_mode,int lane,struct lynx_pccr * pccr)726 static int ls2088a_serdes1_get_pccr(enum lynx_lane_mode lane_mode, int lane,
727 				    struct lynx_pccr *pccr)
728 {
729 	switch (lane_mode) {
730 	case LANE_MODE_1000BASEX_SGMII:
731 	case LANE_MODE_2500BASEX:
732 		pccr->offset = PCCR8;
733 		pccr->width = 4;
734 		pccr->shift = SGMII_CFG(lane);
735 		break;
736 	case LANE_MODE_QSGMII:
737 		switch (lane) {
738 		case 2:
739 		case 6:
740 			pccr->shift = QSGMII_CFG(A);
741 			break;
742 		case 7:
743 			pccr->shift = QSGMII_CFG(B);
744 			break;
745 		case 0:
746 		case 4:
747 			pccr->shift = QSGMII_CFG(C);
748 			break;
749 		case 1:
750 		case 5:
751 			pccr->shift = QSGMII_CFG(D);
752 			break;
753 		default:
754 			return -EINVAL;
755 		}
756 
757 		pccr->offset = PCCR9;
758 		pccr->width = 3;
759 		break;
760 	case LANE_MODE_10GBASER:
761 		pccr->offset = PCCRB;
762 		pccr->width = 3;
763 		pccr->shift = XFI_CFG(lane);
764 		break;
765 	default:
766 		return -EINVAL;
767 	}
768 
769 	return 0;
770 }
771 
ls2088a_serdes1_get_pcvt_offset(int lane,enum lynx_lane_mode mode)772 static int ls2088a_serdes1_get_pcvt_offset(int lane, enum lynx_lane_mode mode)
773 {
774 	switch (mode) {
775 	case LANE_MODE_1000BASEX_SGMII:
776 	case LANE_MODE_2500BASEX:
777 		return SGMIIaCR0(lane);
778 	case LANE_MODE_QSGMII:
779 		switch (lane) {
780 		case 2:
781 		case 6:
782 			return QSGMIIaCR0(A);
783 		case 7:
784 			return QSGMIIaCR0(B);
785 		case 0:
786 		case 4:
787 			return QSGMIIaCR0(C);
788 		case 1:
789 		case 5:
790 			return QSGMIIaCR0(D);
791 		default:
792 			return -EINVAL;
793 		}
794 	case LANE_MODE_10GBASER:
795 		return XFIaCR0(lane);
796 	default:
797 		return -EINVAL;
798 	}
799 }
800 
801 static const struct lynx_info lynx_info_ls2088a_serdes1 = {
802 	.get_pccr = ls2088a_serdes1_get_pccr,
803 	.get_pcvt_offset = ls2088a_serdes1_get_pcvt_offset,
804 	.pll_read_configuration = lynx_10g_pll_read_configuration,
805 	.lane_read_configuration = lynx_10g_lane_read_configuration,
806 	.cdr_lock_check = lynx_10g_cdr_lock_check,
807 	.num_lanes = 8,
808 	.index = 1,
809 };
810 
ls2088a_serdes2_get_pccr(enum lynx_lane_mode lane_mode,int lane,struct lynx_pccr * pccr)811 static int ls2088a_serdes2_get_pccr(enum lynx_lane_mode lane_mode, int lane,
812 				    struct lynx_pccr *pccr)
813 {
814 	switch (lane_mode) {
815 	case LANE_MODE_1000BASEX_SGMII:
816 	case LANE_MODE_2500BASEX:
817 		pccr->offset = PCCR8;
818 		pccr->width = 4;
819 		pccr->shift = SGMII_CFG(lane);
820 		break;
821 	default:
822 		return -EINVAL;
823 	}
824 
825 	return 0;
826 }
827 
ls2088a_serdes2_get_pcvt_offset(int lane,enum lynx_lane_mode mode)828 static int ls2088a_serdes2_get_pcvt_offset(int lane, enum lynx_lane_mode mode)
829 {
830 	switch (mode) {
831 	case LANE_MODE_1000BASEX_SGMII:
832 	case LANE_MODE_2500BASEX:
833 		return SGMIIaCR0(lane);
834 	default:
835 		return -EINVAL;
836 	}
837 }
838 
839 static const struct lynx_info lynx_info_ls2088a_serdes2 = {
840 	.get_pccr = ls2088a_serdes2_get_pccr,
841 	.get_pcvt_offset = ls2088a_serdes2_get_pcvt_offset,
842 	.pll_read_configuration = lynx_10g_pll_read_configuration,
843 	.lane_read_configuration = lynx_10g_lane_read_configuration,
844 	.cdr_lock_check = lynx_10g_cdr_lock_check,
845 	.num_lanes = 8,
846 	.index = 2,
847 };
848 
849 /* Halting puts the lane in a mode in which it can be reconfigured */
lynx_10g_lane_halt(struct phy * phy)850 static void lynx_10g_lane_halt(struct phy *phy)
851 {
852 	struct lynx_lane *lane = phy_get_drvdata(phy);
853 
854 	/* Issue a reset request */
855 	lynx_lane_rmw(lane, LNaGCR0,
856 		      LNaGCR0_RRST_ON | LNaGCR0_TRST_ON,
857 		      LNaGCR0_RRST | LNaGCR0_TRST);
858 
859 	/* The RM says to wait for at least 50ns */
860 	usleep_range(1, 2);
861 }
862 
lynx_10g_lane_reset(struct phy * phy)863 static void lynx_10g_lane_reset(struct phy *phy)
864 {
865 	struct lynx_lane *lane = phy_get_drvdata(phy);
866 
867 	/* Finalize the reset request */
868 	lynx_lane_rmw(lane, LNaGCR0,
869 		      LNaGCR0_RRST_OFF | LNaGCR0_TRST_OFF,
870 		      LNaGCR0_RRST | LNaGCR0_TRST);
871 }
872 
lynx_10g_power_off(struct phy * phy)873 static int lynx_10g_power_off(struct phy *phy)
874 {
875 	struct lynx_lane *lane = phy_get_drvdata(phy);
876 
877 	if (!lane->powered_up)
878 		return 0;
879 
880 	/* Issue a reset request with the power down bits set */
881 	lynx_lane_rmw(lane, LNaGCR0,
882 		      LNaGCR0_RRST_ON | LNaGCR0_TRST_ON |
883 		      LNaGCR0_RX_PD | LNaGCR0_TX_PD,
884 		      LNaGCR0_RRST | LNaGCR0_TRST |
885 		      LNaGCR0_RX_PD | LNaGCR0_TX_PD);
886 
887 	/* The RM says to wait for at least 50ns */
888 	usleep_range(1, 2);
889 
890 	lane->powered_up = false;
891 
892 	return 0;
893 }
894 
lynx_10g_power_on(struct phy * phy)895 static int lynx_10g_power_on(struct phy *phy)
896 {
897 	struct lynx_lane *lane = phy_get_drvdata(phy);
898 
899 	if (lane->powered_up)
900 		return 0;
901 
902 	/* RM says that to enable a previously powered down lane, set
903 	 * LNmGCR0[{R,T}X_PD]=0, wait 15 us, then set LNmGCR0[{R,T}RST]=1.
904 	 */
905 	lynx_lane_rmw(lane, LNaGCR0, 0, LNaGCR0_RX_PD | LNaGCR0_TX_PD);
906 	usleep_range(150, 300);
907 	lynx_10g_lane_reset(phy);
908 
909 	lane->powered_up = true;
910 
911 	return 0;
912 }
913 
lynx_10g_lane_set_nrate(struct lynx_lane * lane,struct lynx_pll * pll,enum lynx_lane_mode mode)914 static void lynx_10g_lane_set_nrate(struct lynx_lane *lane,
915 				    struct lynx_pll *pll,
916 				    enum lynx_lane_mode mode)
917 {
918 	enum lynx_10g_rat_sel nrate;
919 
920 	switch (pll->frate_sel) {
921 	case PLLnCR0_FRATE_5G:
922 		switch (mode) {
923 		case LANE_MODE_1000BASEX_SGMII:
924 			nrate = RAT_SEL_QUARTER;
925 			break;
926 		case LANE_MODE_QSGMII:
927 			nrate = RAT_SEL_FULL;
928 			break;
929 		default:
930 			return;
931 		}
932 		break;
933 	case PLLnCR0_FRATE_3_125G:
934 		switch (mode) {
935 		case LANE_MODE_2500BASEX:
936 			nrate = RAT_SEL_FULL;
937 			break;
938 		default:
939 			return;
940 		}
941 		break;
942 	case PLLnCR0_FRATE_5_15625G:
943 		switch (mode) {
944 		case LANE_MODE_10GBASER:
945 		case LANE_MODE_USXGMII:
946 		case LANE_MODE_10G_QXGMII:
947 			nrate = RAT_SEL_DOUBLE;
948 			break;
949 		default:
950 			return;
951 		}
952 		break;
953 	default:
954 		return;
955 	}
956 
957 	lynx_lane_rmw(lane, LNaGCR0,
958 		      FIELD_PREP(LNaGCR0_TRAT_SEL, nrate) |
959 		      FIELD_PREP(LNaGCR0_RRAT_SEL, nrate),
960 		      LNaGCR0_RRAT_SEL | LNaGCR0_TRAT_SEL);
961 }
962 
lynx_10g_lane_set_pll(struct lynx_lane * lane,struct lynx_pll * pll)963 static void lynx_10g_lane_set_pll(struct lynx_lane *lane,
964 				  struct lynx_pll *pll)
965 {
966 	if (pll->id == 0) {
967 		lynx_lane_rmw(lane, LNaGCR0,
968 			      LNaGCR0_RPLL_PLLF | LNaGCR0_TPLL_PLLF,
969 			      LNaGCR0_RPLL_MSK | LNaGCR0_TPLL_MSK);
970 	} else {
971 		lynx_lane_rmw(lane, LNaGCR0,
972 			      LNaGCR0_RPLL_PLLS | LNaGCR0_TPLL_PLLS,
973 			      LNaGCR0_RPLL_MSK | LNaGCR0_TPLL_MSK);
974 	}
975 }
976 
lynx_10g_lane_remap_pll(struct lynx_lane * lane,enum lynx_lane_mode lane_mode)977 static void lynx_10g_lane_remap_pll(struct lynx_lane *lane,
978 				    enum lynx_lane_mode lane_mode)
979 {
980 	struct lynx_priv *priv = lane->priv;
981 	struct lynx_pll *pll;
982 
983 	/* Switch to the PLL that works with this interface type */
984 	pll = lynx_pll_get(priv, lane_mode);
985 	if (unlikely(!pll))
986 		return;
987 
988 	lynx_10g_lane_set_pll(lane, pll);
989 
990 	/* Choose the portion of clock net to be used on this lane */
991 	lynx_10g_lane_set_nrate(lane, pll, lane_mode);
992 }
993 
lynx_10g_lane_change_proto_conf(struct lynx_lane * lane,enum lynx_lane_mode mode)994 static void lynx_10g_lane_change_proto_conf(struct lynx_lane *lane,
995 					    enum lynx_lane_mode mode)
996 {
997 	const struct lynx_10g_proto_conf *conf = &lynx_10g_proto_conf[mode];
998 
999 	lynx_lane_rmw(lane, LNaGCR0,
1000 		      FIELD_PREP(LNaGCR0_PROTS, conf->proto_sel) |
1001 		      FIELD_PREP(LNaGCR0_IF20BIT_EN, conf->if20bit_en),
1002 		      LNaGCR0_PROTS | LNaGCR0_IF20BIT_EN);
1003 	lynx_lane_rmw(lane, LNaGCR1,
1004 		      FIELD_PREP(LNaGCR1_REIDL_TH, conf->reidl_th) |
1005 		      FIELD_PREP(LNaGCR1_REIDL_ET_MSB, conf->reidl_et_msb) |
1006 		      FIELD_PREP(LNaGCR1_REIDL_ET_SEL, conf->reidl_et_sel) |
1007 		      FIELD_PREP(LNaGCR1_REIDL_EX_MSB, conf->reidl_ex_msb) |
1008 		      FIELD_PREP(LNaGCR1_REIDL_EX_SEL, conf->reidl_ex_sel) |
1009 		      FIELD_PREP(LNaGCR1_ISLEW_RCTL, conf->islew_rctl) |
1010 		      FIELD_PREP(LNaGCR1_OSLEW_RCTL, conf->oslew_rctl),
1011 		      LNaGCR1_REIDL_TH |
1012 		      LNaGCR1_REIDL_ET_MSB | LNaGCR1_REIDL_ET_SEL |
1013 		      LNaGCR1_REIDL_EX_MSB | LNaGCR1_REIDL_EX_SEL |
1014 		      LNaGCR1_ISLEW_RCTL | LNaGCR1_OSLEW_RCTL);
1015 	lynx_lane_rmw(lane, LNaRECR0,
1016 		      FIELD_PREP(LNaRECR0_RXEQ_BST, conf->rxeq_bst) |
1017 		      FIELD_PREP(LNaRECR0_GK2OVD, conf->gk2ovd) |
1018 		      FIELD_PREP(LNaRECR0_GK3OVD, conf->gk3ovd) |
1019 		      FIELD_PREP(LNaRECR0_GK2OVD_EN, conf->gk2ovd_en) |
1020 		      FIELD_PREP(LNaRECR0_GK3OVD_EN, conf->gk3ovd_en) |
1021 		      FIELD_PREP(LNaRECR0_BASE_WAND, conf->base_wand),
1022 		      LNaRECR0_RXEQ_BST | LNaRECR0_GK2OVD | LNaRECR0_GK3OVD |
1023 		      LNaRECR0_GK2OVD_EN | LNaRECR0_GK3OVD_EN |
1024 		      LNaRECR0_BASE_WAND);
1025 	lynx_lane_rmw(lane, LNaTECR0,
1026 		      FIELD_PREP(LNaTECR0_TEQ_TYPE, conf->teq_type) |
1027 		      FIELD_PREP(LNaTECR0_SGN_PREQ, conf->sgn_preq) |
1028 		      FIELD_PREP(LNaTECR0_RATIO_PREQ, conf->ratio_preq) |
1029 		      FIELD_PREP(LNaTECR0_SGN_POST1Q, conf->sgn_post1q) |
1030 		      FIELD_PREP(LNaTECR0_RATIO_PST1Q, conf->ratio_post1q) |
1031 		      FIELD_PREP(LNaTECR0_ADPT_EQ, conf->adpt_eq) |
1032 		      FIELD_PREP(LNaTECR0_AMP_RED, conf->amp_red),
1033 		      LNaTECR0_TEQ_TYPE | LNaTECR0_SGN_PREQ |
1034 		      LNaTECR0_RATIO_PREQ | LNaTECR0_SGN_POST1Q |
1035 		      LNaTECR0_RATIO_PST1Q | LNaTECR0_ADPT_EQ |
1036 		      LNaTECR0_AMP_RED);
1037 	lynx_lane_write(lane, LNaTTLCR0, conf->ttlcr0);
1038 }
1039 
lynx_10g_lane_disable_pcvt(struct lynx_lane * lane,enum lynx_lane_mode mode)1040 static int lynx_10g_lane_disable_pcvt(struct lynx_lane *lane,
1041 				      enum lynx_lane_mode mode)
1042 {
1043 	struct lynx_priv *priv = lane->priv;
1044 	int err;
1045 
1046 	spin_lock(&priv->pcc_lock);
1047 
1048 	err = lynx_pccr_write(lane, mode, 0);
1049 	if (err)
1050 		goto out;
1051 
1052 	switch (mode) {
1053 	case LANE_MODE_1000BASEX_SGMII:
1054 	case LANE_MODE_2500BASEX:
1055 		err = lynx_pcvt_rmw(lane, mode, CR(1), SGMIIaCR1_SGPCS_DIS,
1056 				    SGMIIaCR1_SGPCS_EN);
1057 		if (err)
1058 			goto out;
1059 
1060 		lynx_pcvt_rmw(lane, mode, CR(0),
1061 			      SGMIIaCR0_RST_SGM_ON | SGMIIaCR0_PD_SGM,
1062 			      SGMIIaCR0_RST_SGM | SGMIIaCR0_PD_SGM);
1063 		break;
1064 	case LANE_MODE_QSGMII:
1065 		err = lynx_pcvt_rmw(lane, mode, CR(0),
1066 				    QSGMIIaCR0_RST_QSGM_ON | QSGMIIaCR0_PD_QSGM,
1067 				    QSGMIIaCR0_RST_QSGM | QSGMIIaCR0_PD_QSGM);
1068 		if (err)
1069 			goto out;
1070 		break;
1071 	default:
1072 		err = 0;
1073 	}
1074 
1075 out:
1076 	spin_unlock(&priv->pcc_lock);
1077 
1078 	return err;
1079 }
1080 
lynx_10g_lane_enable_pcvt(struct lynx_lane * lane,enum lynx_lane_mode mode)1081 static int lynx_10g_lane_enable_pcvt(struct lynx_lane *lane,
1082 				     enum lynx_lane_mode mode)
1083 {
1084 	struct lynx_priv *priv = lane->priv;
1085 	u32 val;
1086 	int err;
1087 
1088 	spin_lock(&priv->pcc_lock);
1089 
1090 	switch (mode) {
1091 	case LANE_MODE_1000BASEX_SGMII:
1092 	case LANE_MODE_2500BASEX:
1093 		err = lynx_pcvt_rmw(lane, mode, CR(1), SGMIIaCR1_SGPCS_EN,
1094 				    SGMIIaCR1_SGPCS_EN);
1095 		if (err)
1096 			goto out;
1097 
1098 		lynx_pcvt_rmw(lane, mode, CR(0), SGMIIaCR0_RST_SGM_OFF,
1099 			      SGMIIaCR0_RST_SGM | SGMIIaCR0_PD_SGM);
1100 		break;
1101 	case LANE_MODE_QSGMII:
1102 		err = lynx_pcvt_rmw(lane, mode, CR(0), QSGMIIaCR0_RST_QSGM_OFF,
1103 				    QSGMIIaCR0_RST_QSGM | QSGMIIaCR0_PD_QSGM);
1104 		if (err)
1105 			goto out;
1106 		break;
1107 	default:
1108 		err = 0;
1109 	}
1110 
1111 	/* If the PCS was enabled at boot time, use the backed up PCCR value to
1112 	 * re-enable it here, to preserve the muxing.
1113 	 */
1114 	if (lynx_10g_pccr_val_enabled(lane->default_pccr[mode])) {
1115 		err = lynx_pccr_write(lane, mode, lane->default_pccr[mode]);
1116 		goto out;
1117 	}
1118 
1119 	/* If the PCS was not enabled, set the PCCR to a default value which
1120 	 * enables it (1). The assumption is that this is the only PCS <->
1121 	 * SerDes lane muxing value possible.
1122 	 *
1123 	 * This is mostly useful for SGMII <-> 10GBase-R major protocol
1124 	 * reconfiguration, where at boot time, either the SGMII or the
1125 	 * 10GBase-R PCS is enabled for the lane, but not both.
1126 	 *
1127 	 * In fact, if there are multiple lane muxing options, this function
1128 	 * will most likely not choose the right one. For correct functionality
1129 	 * there, we assume that the PCS we are enabling here was found enabled
1130 	 * at boot time (reset default, or through PBL, or...), and we preserve
1131 	 * its muxing through the default_pccr branch above.
1132 	 */
1133 	val = 0;
1134 
1135 	switch (mode) {
1136 	case LANE_MODE_1000BASEX_SGMII:
1137 	case LANE_MODE_2500BASEX:
1138 		val |= FIELD_PREP(PCCR8_SGMIIa_CFG, 1);
1139 		break;
1140 	case LANE_MODE_QSGMII:
1141 		val |= FIELD_PREP(PCCR9_QSGMIIa_CFG, 1);
1142 		break;
1143 	case LANE_MODE_10G_QXGMII:
1144 		val |= FIELD_PREP(PCCR9_QXGMIIa_CFG, 1);
1145 		break;
1146 	case LANE_MODE_10GBASER:
1147 		val |= FIELD_PREP(PCCRB_XFIa_CFG, 1);
1148 		break;
1149 	case LANE_MODE_USXGMII:
1150 		val |= FIELD_PREP(PCCRB_SXGMIIa_CFG, 1);
1151 		break;
1152 	default:
1153 		err = 0;
1154 		goto out;
1155 	}
1156 
1157 	err = lynx_pccr_write(lane, mode, val);
1158 out:
1159 	spin_unlock(&priv->pcc_lock);
1160 
1161 	return err;
1162 }
1163 
lynx_10g_lane_mode_needs_rcw_override(struct lynx_lane * lane,enum lynx_lane_mode new)1164 static bool lynx_10g_lane_mode_needs_rcw_override(struct lynx_lane *lane,
1165 						  enum lynx_lane_mode new)
1166 {
1167 	enum lynx_lane_mode curr = lane->mode;
1168 
1169 	/* Major protocol changes, which involve changing the PCS connection to
1170 	 * the GMII MAC with the one to the XGMII MAC, require an RCW override
1171 	 * procedure to reconfigure an internal mux.
1172 	 */
1173 	if ((lynx_lane_mode_uses_gmii_mac(curr) &&
1174 	     lynx_lane_mode_uses_xgmii_mac(new)) ||
1175 	    (lynx_lane_mode_uses_xgmii_mac(curr) &&
1176 	     lynx_lane_mode_uses_gmii_mac(new)))
1177 		return true;
1178 
1179 	return false;
1180 }
1181 
lynx_10g_validate(struct phy * phy,enum phy_mode mode,int submode,union phy_configure_opts * opts)1182 static int lynx_10g_validate(struct phy *phy, enum phy_mode mode, int submode,
1183 			     union phy_configure_opts *opts)
1184 {
1185 	struct lynx_lane *lane = phy_get_drvdata(phy);
1186 	struct lynx_priv *priv = lane->priv;
1187 	enum lynx_lane_mode lane_mode;
1188 	int err;
1189 
1190 	err = lynx_phy_mode_to_lane_mode(phy, mode, submode, &lane_mode);
1191 	if (err)
1192 		return err;
1193 
1194 	if (lynx_10g_lane_mode_needs_rcw_override(lane, lane_mode))
1195 		return fsl_guts_lane_validate(priv->info->index, lane->id,
1196 					      lane_mode);
1197 
1198 	return 0;
1199 }
1200 
lynx_10g_set_mode(struct phy * phy,enum phy_mode mode,int submode)1201 static int lynx_10g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
1202 {
1203 	struct lynx_lane *lane = phy_get_drvdata(phy);
1204 	struct lynx_priv *priv = lane->priv;
1205 	bool powered_up = lane->powered_up;
1206 	enum lynx_lane_mode lane_mode;
1207 	int err;
1208 
1209 	err = lynx_10g_validate(phy, mode, submode, NULL);
1210 	if (err)
1211 		return err;
1212 
1213 	lane_mode = phy_interface_to_lane_mode(submode);
1214 	/* lynx_10g_validate() already made sure the lane_mode is supported */
1215 
1216 	if (lane_mode == lane->mode)
1217 		return 0;
1218 
1219 	/* If the lane is powered up, put the lane into the halt state while
1220 	 * the reconfiguration is being done.
1221 	 */
1222 	if (powered_up)
1223 		lynx_10g_lane_halt(phy);
1224 
1225 	if (lynx_10g_lane_mode_needs_rcw_override(lane, lane_mode)) {
1226 		err = fsl_guts_lane_set_mode(priv->info->index, lane->id,
1227 					     lane_mode);
1228 		if (err)
1229 			goto out;
1230 	}
1231 
1232 	err = lynx_10g_lane_disable_pcvt(lane, lane->mode);
1233 	if (err)
1234 		goto out;
1235 
1236 	lynx_10g_lane_change_proto_conf(lane, lane_mode);
1237 	lynx_10g_lane_remap_pll(lane, lane_mode);
1238 	WARN_ON(lynx_10g_lane_enable_pcvt(lane, lane_mode));
1239 
1240 	lane->mode = lane_mode;
1241 
1242 out:
1243 	if (powered_up) {
1244 		/* The RM says to wait for at least 120 ns */
1245 		usleep_range(1, 2);
1246 		lynx_10g_lane_reset(phy);
1247 	}
1248 
1249 	return err;
1250 }
1251 
lynx_10g_init(struct phy * phy)1252 static int lynx_10g_init(struct phy *phy)
1253 {
1254 	struct lynx_lane *lane = phy_get_drvdata(phy);
1255 
1256 	/* Mark the fact that the lane was init */
1257 	lane->init = true;
1258 
1259 	/* SerDes lanes are powered on at boot time. Any lane that is
1260 	 * managed by this driver will get powered off when its consumer
1261 	 * calls phy_init().
1262 	 */
1263 	lane->powered_up = true;
1264 	lynx_10g_power_off(phy);
1265 
1266 	return 0;
1267 }
1268 
lynx_10g_exit(struct phy * phy)1269 static int lynx_10g_exit(struct phy *phy)
1270 {
1271 	struct lynx_lane *lane = phy_get_drvdata(phy);
1272 
1273 	/* The lane returns to the state where it isn't managed by the
1274 	 * consumer, so we must treat is as if it isn't initialized, and always
1275 	 * powered on.
1276 	 */
1277 	lane->init = false;
1278 	lane->powered_up = false;
1279 	lynx_10g_power_on(phy);
1280 
1281 	return 0;
1282 }
1283 
1284 static const struct phy_ops lynx_10g_ops = {
1285 	.init		= lynx_10g_init,
1286 	.exit		= lynx_10g_exit,
1287 	.power_on	= lynx_10g_power_on,
1288 	.power_off	= lynx_10g_power_off,
1289 	.set_mode	= lynx_10g_set_mode,
1290 	.validate	= lynx_10g_validate,
1291 	.owner		= THIS_MODULE,
1292 };
1293 
lynx_10g_probe(struct platform_device * pdev)1294 static int lynx_10g_probe(struct platform_device *pdev)
1295 {
1296 	return lynx_probe(pdev, of_device_get_match_data(&pdev->dev),
1297 			  &lynx_10g_ops);
1298 }
1299 
1300 static const struct of_device_id lynx_10g_of_match_table[] = {
1301 	{ .compatible = "fsl,ls1028a-serdes", .data = &lynx_info_ls1028a },
1302 	{ .compatible = "fsl,ls1046a-serdes1", .data = &lynx_info_ls1046a_serdes1 },
1303 	{ .compatible = "fsl,ls1046a-serdes2", .data = &lynx_info_ls1046a_serdes2 },
1304 	{ .compatible = "fsl,ls1088a-serdes1", .data = &lynx_info_ls1088a_serdes1 },
1305 	{ .compatible = "fsl,ls2088a-serdes1", .data = &lynx_info_ls2088a_serdes1 },
1306 	{ .compatible = "fsl,ls2088a-serdes2", .data = &lynx_info_ls2088a_serdes2 },
1307 	{}
1308 };
1309 MODULE_DEVICE_TABLE(of, lynx_10g_of_match_table);
1310 
1311 static struct platform_driver lynx_10g_driver = {
1312 	.probe	= lynx_10g_probe,
1313 	.remove	= lynx_remove,
1314 	.driver	= {
1315 		.name = "lynx-10g",
1316 		.of_match_table = lynx_10g_of_match_table,
1317 	},
1318 };
1319 module_platform_driver(lynx_10g_driver);
1320 
1321 MODULE_IMPORT_NS("FSL_GUTS");
1322 MODULE_IMPORT_NS("PHY_FSL_LYNX");
1323 MODULE_AUTHOR("Ioana Ciornei <ioana.ciornei@nxp.com>");
1324 MODULE_AUTHOR("Vladimir Oltean <vladimir.oltean@nxp.com>");
1325 MODULE_DESCRIPTION("Lynx 10G SerDes PHY driver for Layerscape SoCs");
1326 MODULE_LICENSE("GPL");
1327