xref: /linux/drivers/phy/freescale/phy-fsl-lynx-28g.c (revision fc9eae25ecb769e0c03a1383c677e2ddc1de8adf)
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Copyright (c) 2021-2022 NXP. */
3 
4 #include <linux/bitfield.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 
12 #define LYNX_28G_NUM_LANE			8
13 #define LYNX_28G_NUM_PLL			2
14 
15 /* SoC IP wrapper for protocol converters */
16 #define PCC8					0x10a0
17 #define PCC8_SGMIIa_KX				BIT(3)
18 #define PCC8_SGMIIa_CFG				BIT(0)
19 
20 #define PCCC					0x10b0
21 #define PCCC_SXGMIIn_XFI			BIT(3)
22 #define PCCC_SXGMIIn_CFG			BIT(0)
23 
24 #define PCCD					0x10b4
25 #define PCCD_E25Gn_CFG				BIT(0)
26 
27 #define PCCE					0x10b8
28 #define PCCE_E40Gn_LRV				BIT(3)
29 #define PCCE_E40Gn_CFG				BIT(0)
30 #define PCCE_E50Gn_LRV				BIT(3)
31 #define PCCE_E50GnCFG				BIT(0)
32 #define PCCE_E100Gn_LRV				BIT(3)
33 #define PCCE_E100Gn_CFG				BIT(0)
34 
35 #define SGMII_CFG(id)				(28 - (id) * 4) /* Offset into PCC8 */
36 #define SXGMII_CFG(id)				(28 - (id) * 4) /* Offset into PCCC */
37 #define E25G_CFG(id)				(28 - (id) * 4) /* Offset into PCCD */
38 #define E40G_CFG(id)				(28 - (id) * 4) /* Offset into PCCE */
39 #define E50G_CFG(id)				(20 - (id) * 4) /* Offset into PCCE */
40 #define E100G_CFG(id)				(12 - (id) * 4) /* Offset into PCCE */
41 
42 /* Per PLL registers */
43 #define PLLnRSTCTL(pll)				(0x400 + (pll) * 0x100 + 0x0)
44 #define PLLnRSTCTL_DIS(rstctl)			(((rstctl) & BIT(24)) >> 24)
45 #define PLLnRSTCTL_LOCK(rstctl)			(((rstctl) & BIT(23)) >> 23)
46 
47 #define PLLnCR0(pll)				(0x400 + (pll) * 0x100 + 0x4)
48 #define PLLnCR0_REFCLK_SEL			GENMASK(20, 16)
49 #define PLLnCR0_REFCLK_SEL_100MHZ		0x0
50 #define PLLnCR0_REFCLK_SEL_125MHZ		0x1
51 #define PLLnCR0_REFCLK_SEL_156MHZ		0x2
52 #define PLLnCR0_REFCLK_SEL_150MHZ		0x3
53 #define PLLnCR0_REFCLK_SEL_161MHZ		0x4
54 
55 #define PLLnCR1(pll)				(0x400 + (pll) * 0x100 + 0x8)
56 #define PLLnCR1_FRATE_SEL			GENMASK(28, 24)
57 #define PLLnCR1_FRATE_5G_10GVCO			0x0
58 #define PLLnCR1_FRATE_5G_25GVCO			0x10
59 #define PLLnCR1_FRATE_10G_20GVCO		0x6
60 
61 /* Per SerDes lane registers */
62 /* Lane a General Control Register */
63 #define LNaGCR0(lane)				(0x800 + (lane) * 0x100 + 0x0)
64 #define LNaGCR0_PROTO_SEL			GENMASK(7, 3)
65 #define LNaGCR0_PROTO_SEL_SGMII			0x1
66 #define LNaGCR0_PROTO_SEL_XFI			0xa
67 #define LNaGCR0_IF_WIDTH			GENMASK(2, 0)
68 #define LNaGCR0_IF_WIDTH_10_BIT			0x0
69 #define LNaGCR0_IF_WIDTH_20_BIT			0x2
70 
71 /* Lane a Tx Reset Control Register */
72 #define LNaTRSTCTL(lane)			(0x800 + (lane) * 0x100 + 0x20)
73 #define LNaTRSTCTL_HLT_REQ			BIT(27)
74 #define LNaTRSTCTL_RST_DONE			BIT(30)
75 #define LNaTRSTCTL_RST_REQ			BIT(31)
76 
77 /* Lane a Tx General Control Register */
78 #define LNaTGCR0(lane)				(0x800 + (lane) * 0x100 + 0x24)
79 #define LNaTGCR0_USE_PLL			BIT(28)
80 #define LNaTGCR0_USE_PLLF			0x0
81 #define LNaTGCR0_USE_PLLS			0x1
82 #define LNaTGCR0_N_RATE				GENMASK(26, 24)
83 #define LNaTGCR0_N_RATE_FULL			0x0
84 #define LNaTGCR0_N_RATE_HALF			0x1
85 #define LNaTGCR0_N_RATE_QUARTER			0x2
86 
87 #define LNaTECR0(lane)				(0x800 + (lane) * 0x100 + 0x30)
88 #define LNaTECR0_EQ_TYPE			GENMASK(30, 28)
89 #define LNaTECR0_EQ_SGN_PREQ			BIT(23)
90 #define LNaTECR0_EQ_PREQ			GENMASK(19, 16)
91 #define LNaTECR0_EQ_SGN_POST1Q			BIT(15)
92 #define LNaTECR0_EQ_POST1Q			GENMASK(12, 8)
93 #define LNaTECR0_EQ_AMP_RED			GENMASK(5, 0)
94 
95 #define LNaTECR1(lane)				(0x800 + (lane) * 0x100 + 0x34)
96 #define LNaTECR1_EQ_ADPT_EQ_DRVR_DIS		BIT(31)
97 #define LNaTECR1_EQ_ADPT_EQ			GENMASK(29, 24)
98 
99 /* Lane a Rx Reset Control Register */
100 #define LNaRRSTCTL(lane)			(0x800 + (lane) * 0x100 + 0x40)
101 #define LNaRRSTCTL_HLT_REQ			BIT(27)
102 #define LNaRRSTCTL_RST_DONE			BIT(30)
103 #define LNaRRSTCTL_RST_REQ			BIT(31)
104 #define LNaRRSTCTL_CDR_LOCK			BIT(12)
105 
106 /* Lane a Rx General Control Register */
107 #define LNaRGCR0(lane)				(0x800 + (lane) * 0x100 + 0x44)
108 #define LNaRGCR0_USE_PLL			BIT(28)
109 #define LNaRGCR0_USE_PLLF			0x0
110 #define LNaRGCR0_USE_PLLS			0x1
111 #define LNaRGCR0_N_RATE				GENMASK(26, 24)
112 #define LNaRGCR0_N_RATE_FULL			0x0
113 #define LNaRGCR0_N_RATE_HALF			0x1
114 #define LNaRGCR0_N_RATE_QUARTER			0x2
115 
116 #define LNaRGCR1(lane)				(0x800 + (lane) * 0x100 + 0x48)
117 #define LNaRGCR1_RX_ORD_ELECIDLE		BIT(31)
118 #define LNaRGCR1_DATA_LOST_FLT			BIT(30)
119 #define LNaRGCR1_DATA_LOST			BIT(29)
120 #define LNaRGCR1_IDLE_CONFIG			BIT(28)
121 #define LNaRGCR1_ENTER_IDLE_FLT_SEL		GENMASK(26, 24)
122 #define LNaRGCR1_EXIT_IDLE_FLT_SEL		GENMASK(22, 20)
123 #define LNaRGCR1_DATA_LOST_TH_SEL		GENMASK(18, 16)
124 #define LNaRGCR1_EXT_REC_CLK_SEL		GENMASK(10, 8)
125 #define LNaRGCR1_WAKE_TX_DIS			BIT(5)
126 #define LNaRGCR1_PHY_RDY			BIT(4)
127 #define LNaRGCR1_CHANGE_RX_CLK			BIT(3)
128 #define LNaRGCR1_PWR_MGT			GENMASK(2, 0)
129 
130 #define LNaRECR0(lane)				(0x800 + (lane) * 0x100 + 0x50)
131 #define LNaRECR0_EQ_GAINK2_HF_OV_EN		BIT(31)
132 #define LNaRECR0_EQ_GAINK2_HF_OV		GENMASK(28, 24)
133 #define LNaRECR0_EQ_GAINK3_MF_OV_EN		BIT(23)
134 #define LNaRECR0_EQ_GAINK3_MF_OV		GENMASK(20, 16)
135 #define LNaRECR0_EQ_GAINK4_LF_OV_EN		BIT(7)
136 #define LNaRECR0_EQ_GAINK4_LF_DIS		BIT(6)
137 #define LNaRECR0_EQ_GAINK4_LF_OV		GENMASK(4, 0)
138 
139 #define LNaRECR1(lane)				(0x800 + (lane) * 0x100 + 0x54)
140 #define LNaRECR1_EQ_BLW_OV_EN			BIT(31)
141 #define LNaRECR1_EQ_BLW_OV			GENMASK(28, 24)
142 #define LNaRECR1_EQ_OFFSET_OV_EN		BIT(23)
143 #define LNaRECR1_EQ_OFFSET_OV			GENMASK(21, 16)
144 
145 #define LNaRECR2(lane)				(0x800 + (lane) * 0x100 + 0x58)
146 #define LNaRECR2_EQ_OFFSET_RNG_DBL		BIT(31)
147 #define LNaRECR2_EQ_BOOST			GENMASK(29, 28)
148 #define LNaRECR2_EQ_BLW_SEL			GENMASK(25, 24)
149 #define LNaRECR2_EQ_ZERO			GENMASK(17, 16)
150 #define LNaRECR2_EQ_IND				GENMASK(13, 12)
151 #define LNaRECR2_EQ_BIN_DATA_AVG_TC		GENMASK(5, 4)
152 #define LNaRECR2_SPARE_IN			GENMASK(1, 0)
153 
154 #define LNaRECR3(lane)				(0x800 + (lane) * 0x100 + 0x5c)
155 #define LNaRECR3_EQ_SNAP_START			BIT(31)
156 #define LNaRECR3_EQ_SNAP_DONE			BIT(30)
157 #define LNaRECR3_EQ_GAINK2_HF_STAT		GENMASK(28, 24)
158 #define LNaRECR3_EQ_GAINK3_MF_STAT		GENMASK(20, 16)
159 #define LNaRECR3_SPARE_OUT			GENMASK(13, 12)
160 #define LNaRECR3_EQ_GAINK4_LF_STAT		GENMASK(4, 0)
161 
162 #define LNaRECR4(lane)				(0x800 + (lane) * 0x100 + 0x60)
163 #define LNaRECR4_BLW_STAT			GENMASK(28, 24)
164 #define LNaRECR4_EQ_OFFSET_STAT			GENMASK(21, 16)
165 #define LNaRECR4_EQ_BIN_DATA_SEL		GENMASK(15, 12)
166 #define LNaRECR4_EQ_BIN_DATA			GENMASK(8, 0) /* bit 9 is reserved */
167 #define LNaRECR4_EQ_BIN_DATA_SGN		BIT(8)
168 
169 #define LNaRCCR0(lane)				(0x800 + (lane) * 0x100 + 0x68)
170 #define LNaRCCR0_CAL_EN				BIT(31)
171 #define LNaRCCR0_MEAS_EN			BIT(30)
172 #define LNaRCCR0_CAL_BIN_SEL			BIT(28)
173 #define LNaRCCR0_CAL_DC3_DIS			BIT(27)
174 #define LNaRCCR0_CAL_DC2_DIS			BIT(26)
175 #define LNaRCCR0_CAL_DC1_DIS			BIT(25)
176 #define LNaRCCR0_CAL_DC0_DIS			BIT(24)
177 #define LNaRCCR0_CAL_AC3_OV_EN			BIT(15)
178 #define LNaRCCR0_CAL_AC3_OV			GENMASK(11, 8)
179 #define LNaRCCR0_CAL_AC2_OV_EN			BIT(7)
180 
181 #define LNaRSCCR0(lane)				(0x800 + (lane) * 0x100 + 0x74)
182 #define LNaRSCCR0_SMP_OFF_EN			BIT(31)
183 #define LNaRSCCR0_SMP_OFF_OV_EN			BIT(30)
184 #define LNaRSCCR0_SMP_MAN_OFF_EN		BIT(29)
185 #define LNaRSCCR0_SMP_OFF_RNG_OV_EN		BIT(27)
186 #define LNaRSCCR0_SMP_OFF_RNG_4X_OV		BIT(25)
187 #define LNaRSCCR0_SMP_OFF_RNG_2X_OV		BIT(24)
188 #define LNaRSCCR0_SMP_AUTOZ_PD			BIT(23)
189 #define LNaRSCCR0_SMP_AUTOZ_CTRL		GENMASK(19, 16)
190 #define LNaRSCCR0_SMP_AUTOZ_D1R			GENMASK(13, 12)
191 #define LNaRSCCR0_SMP_AUTOZ_D1F			GENMASK(9, 8)
192 #define LNaRSCCR0_SMP_AUTOZ_EG1R		GENMASK(5, 4)
193 #define LNaRSCCR0_SMP_AUTOZ_EG1F		GENMASK(1, 0)
194 
195 #define LNaTTLCR0(lane)				(0x800 + (lane) * 0x100 + 0x80)
196 #define LNaTTLCR0_TTL_FLT_SEL			GENMASK(29, 24)
197 #define LNaTTLCR0_TTL_SLO_PM_BYP		BIT(22)
198 #define LNaTTLCR0_STALL_DET_DIS			BIT(21)
199 #define LNaTTLCR0_INACT_MON_DIS			BIT(20)
200 #define LNaTTLCR0_CDR_OV			GENMASK(18, 16)
201 #define LNaTTLCR0_DATA_IN_SSC			BIT(15)
202 #define LNaTTLCR0_CDR_MIN_SMP_ON		GENMASK(1, 0)
203 
204 #define LNaTCSR0(lane)				(0x800 + (lane) * 0x100 + 0xa0)
205 #define LNaTCSR0_SD_STAT_OBS_EN			BIT(31)
206 #define LNaTCSR0_SD_LPBK_SEL			GENMASK(29, 28)
207 
208 #define LNaPSS(lane)				(0x1000 + (lane) * 0x4)
209 #define LNaPSS_TYPE				GENMASK(30, 24)
210 #define LNaPSS_TYPE_SGMII			(PROTO_SEL_SGMII_BASEX_KX << 2)
211 #define LNaPSS_TYPE_XFI				(PROTO_SEL_XFI_10GBASER_KR_SXGMII << 2)
212 #define LNaPSS_TYPE_40G				((PROTO_SEL_XFI_10GBASER_KR_SXGMII << 2) | 3)
213 #define LNaPSS_TYPE_25G				(PROTO_SEL_25G_50G_100G << 2)
214 #define LNaPSS_TYPE_100G			((PROTO_SEL_25G_50G_100G << 2) | 2)
215 
216 /* MDEV_PORT is at the same bitfield address for all protocol converters */
217 #define MDEV_PORT				GENMASK(31, 27)
218 
219 #define SGMIIaCR0(lane)				(0x1800 + (lane) * 0x10)
220 #define SGMIIaCR1(lane)				(0x1804 + (lane) * 0x10)
221 #define SGMIIaCR1_SGPCS_EN			BIT(11)
222 
223 #define ANLTaCR0(lane)				(0x1a00 + (lane) * 0x10)
224 #define ANLTaCR1(lane)				(0x1a04 + (lane) * 0x10)
225 
226 #define SXGMIIaCR0(lane)			(0x1a80 + (lane) * 0x10)
227 #define SXGMIIaCR0_RST				BIT(31)
228 #define SXGMIIaCR0_PD				BIT(30)
229 
230 #define SXGMIIaCR1(lane)			(0x1a84 + (lane) * 0x10)
231 
232 #define E25GaCR0(lane)				(0x1b00 + (lane) * 0x10)
233 #define E25GaCR0_RST				BIT(31)
234 #define E25GaCR0_PD				BIT(30)
235 
236 #define E25GaCR1(lane)				(0x1b04 + (lane) * 0x10)
237 
238 #define E25GaCR2(lane)				(0x1b08 + (lane) * 0x10)
239 #define E25GaCR2_FEC_ENA			BIT(23)
240 #define E25GaCR2_FEC_ERR_ENA			BIT(22)
241 #define E25GaCR2_FEC91_ENA			BIT(20)
242 
243 #define E40GaCR0(pcvt)				(0x1b40 + (pcvt) * 0x20)
244 #define E40GaCR1(pcvt)				(0x1b44 + (pcvt) * 0x20)
245 
246 #define E50GaCR1(pcvt)				(0x1b84 + (pcvt) * 0x10)
247 
248 #define E100GaCR1(pcvt)				(0x1c04 + (pcvt) * 0x20)
249 
250 #define CR(x)					((x) * 4)
251 
252 enum lynx_28g_eq_type {
253 	EQ_TYPE_NO_EQ = 0,
254 	EQ_TYPE_2TAP = 1,
255 	EQ_TYPE_3TAP = 2,
256 };
257 
258 enum lynx_28g_proto_sel {
259 	PROTO_SEL_PCIE = 0,
260 	PROTO_SEL_SGMII_BASEX_KX = 1,
261 	PROTO_SEL_SATA = 2,
262 	PROTO_SEL_XAUI = 4,
263 	PROTO_SEL_XFI_10GBASER_KR_SXGMII = 0xa,
264 	PROTO_SEL_25G_50G_100G = 0x1a,
265 };
266 
267 enum lynx_lane_mode {
268 	LANE_MODE_UNKNOWN,
269 	LANE_MODE_1000BASEX_SGMII,
270 	LANE_MODE_10GBASER,
271 	LANE_MODE_USXGMII,
272 	LANE_MODE_MAX,
273 };
274 
275 struct lynx_28g_proto_conf {
276 	/* LNaGCR0 */
277 	int proto_sel;
278 	int if_width;
279 	/* LNaTECR0 */
280 	int teq_type;
281 	int sgn_preq;
282 	int ratio_preq;
283 	int sgn_post1q;
284 	int ratio_post1q;
285 	int amp_red;
286 	/* LNaTECR1 */
287 	int adpt_eq;
288 	/* LNaRGCR1 */
289 	int enter_idle_flt_sel;
290 	int exit_idle_flt_sel;
291 	int data_lost_th_sel;
292 	/* LNaRECR0 */
293 	int gk2ovd;
294 	int gk3ovd;
295 	int gk4ovd;
296 	int gk2ovd_en;
297 	int gk3ovd_en;
298 	int gk4ovd_en;
299 	/* LNaRECR1 ? */
300 	int eq_offset_ovd;
301 	int eq_offset_ovd_en;
302 	/* LNaRECR2 */
303 	int eq_offset_rng_dbl;
304 	int eq_blw_sel;
305 	int eq_boost;
306 	int spare_in;
307 	/* LNaRSCCR0 */
308 	int smp_autoz_d1r;
309 	int smp_autoz_eg1r;
310 	/* LNaRCCR0 */
311 	int rccr0;
312 	/* LNaTTLCR0 */
313 	int ttlcr0;
314 };
315 
316 static const struct lynx_28g_proto_conf lynx_28g_proto_conf[LANE_MODE_MAX] = {
317 	[LANE_MODE_1000BASEX_SGMII] = {
318 		.proto_sel = LNaGCR0_PROTO_SEL_SGMII,
319 		.if_width = LNaGCR0_IF_WIDTH_10_BIT,
320 		.teq_type = EQ_TYPE_NO_EQ,
321 		.sgn_preq = 1,
322 		.ratio_preq = 0,
323 		.sgn_post1q = 1,
324 		.ratio_post1q = 0,
325 		.amp_red = 6,
326 		.adpt_eq = 48,
327 		.enter_idle_flt_sel = 4,
328 		.exit_idle_flt_sel = 3,
329 		.data_lost_th_sel = 1,
330 		.gk2ovd = 0x1f,
331 		.gk3ovd = 0,
332 		.gk4ovd = 0,
333 		.gk2ovd_en = 1,
334 		.gk3ovd_en = 1,
335 		.gk4ovd_en = 0,
336 		.eq_offset_ovd = 0x1f,
337 		.eq_offset_ovd_en = 0,
338 		.eq_offset_rng_dbl = 0,
339 		.eq_blw_sel = 0,
340 		.eq_boost = 0,
341 		.spare_in = 0,
342 		.smp_autoz_d1r = 0,
343 		.smp_autoz_eg1r = 0,
344 		.rccr0 = LNaRCCR0_CAL_EN,
345 		.ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP |
346 			  LNaTTLCR0_DATA_IN_SSC,
347 	},
348 	[LANE_MODE_USXGMII] = {
349 		.proto_sel = LNaGCR0_PROTO_SEL_XFI,
350 		.if_width = LNaGCR0_IF_WIDTH_20_BIT,
351 		.teq_type = EQ_TYPE_2TAP,
352 		.sgn_preq = 1,
353 		.ratio_preq = 0,
354 		.sgn_post1q = 1,
355 		.ratio_post1q = 3,
356 		.amp_red = 7,
357 		.adpt_eq = 48,
358 		.enter_idle_flt_sel = 0,
359 		.exit_idle_flt_sel = 0,
360 		.data_lost_th_sel = 0,
361 		.gk2ovd = 0,
362 		.gk3ovd = 0,
363 		.gk4ovd = 0,
364 		.gk2ovd_en = 0,
365 		.gk3ovd_en = 0,
366 		.gk4ovd_en = 0,
367 		.eq_offset_ovd = 0x1f,
368 		.eq_offset_ovd_en = 0,
369 		.eq_offset_rng_dbl = 1,
370 		.eq_blw_sel = 1,
371 		.eq_boost = 0,
372 		.spare_in = 0,
373 		.smp_autoz_d1r = 2,
374 		.smp_autoz_eg1r = 0,
375 		.rccr0 = LNaRCCR0_CAL_EN,
376 		.ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP |
377 			  LNaTTLCR0_DATA_IN_SSC,
378 	},
379 	[LANE_MODE_10GBASER] = {
380 		.proto_sel = LNaGCR0_PROTO_SEL_XFI,
381 		.if_width = LNaGCR0_IF_WIDTH_20_BIT,
382 		.teq_type = EQ_TYPE_2TAP,
383 		.sgn_preq = 1,
384 		.ratio_preq = 0,
385 		.sgn_post1q = 1,
386 		.ratio_post1q = 3,
387 		.amp_red = 7,
388 		.adpt_eq = 48,
389 		.enter_idle_flt_sel = 0,
390 		.exit_idle_flt_sel = 0,
391 		.data_lost_th_sel = 0,
392 		.gk2ovd = 0,
393 		.gk3ovd = 0,
394 		.gk4ovd = 0,
395 		.gk2ovd_en = 0,
396 		.gk3ovd_en = 0,
397 		.gk4ovd_en = 0,
398 		.eq_offset_ovd = 0x1f,
399 		.eq_offset_ovd_en = 0,
400 		.eq_offset_rng_dbl = 1,
401 		.eq_blw_sel = 1,
402 		.eq_boost = 0,
403 		.spare_in = 0,
404 		.smp_autoz_d1r = 2,
405 		.smp_autoz_eg1r = 0,
406 		.rccr0 = LNaRCCR0_CAL_EN,
407 		.ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP |
408 			  LNaTTLCR0_DATA_IN_SSC,
409 	},
410 };
411 
412 struct lynx_pccr {
413 	int offset;
414 	int width;
415 	int shift;
416 };
417 
418 struct lynx_28g_priv;
419 
420 struct lynx_28g_pll {
421 	struct lynx_28g_priv *priv;
422 	u32 rstctl, cr0, cr1;
423 	int id;
424 	DECLARE_BITMAP(supported, LANE_MODE_MAX);
425 };
426 
427 struct lynx_28g_lane {
428 	struct lynx_28g_priv *priv;
429 	struct phy *phy;
430 	bool powered_up;
431 	bool init;
432 	unsigned int id;
433 	enum lynx_lane_mode mode;
434 };
435 
436 struct lynx_28g_priv {
437 	void __iomem *base;
438 	struct device *dev;
439 	/* Serialize concurrent access to registers shared between lanes,
440 	 * like PCCn
441 	 */
442 	spinlock_t pcc_lock;
443 	struct lynx_28g_pll pll[LYNX_28G_NUM_PLL];
444 	struct lynx_28g_lane lane[LYNX_28G_NUM_LANE];
445 
446 	struct delayed_work cdr_check;
447 };
448 
lynx_28g_rmw(struct lynx_28g_priv * priv,unsigned long off,u32 val,u32 mask)449 static void lynx_28g_rmw(struct lynx_28g_priv *priv, unsigned long off,
450 			 u32 val, u32 mask)
451 {
452 	void __iomem *reg = priv->base + off;
453 	u32 orig, tmp;
454 
455 	orig = ioread32(reg);
456 	tmp = orig & ~mask;
457 	tmp |= val;
458 	iowrite32(tmp, reg);
459 }
460 
461 #define lynx_28g_read(priv, off) \
462 	ioread32((priv)->base + (off))
463 #define lynx_28g_write(priv, off, val) \
464 	iowrite32(val, (priv)->base + (off))
465 #define lynx_28g_lane_rmw(lane, reg, val, mask)	\
466 	lynx_28g_rmw((lane)->priv, reg(lane->id), val, mask)
467 #define lynx_28g_lane_read(lane, reg)			\
468 	ioread32((lane)->priv->base + reg((lane)->id))
469 #define lynx_28g_lane_write(lane, reg, val)		\
470 	iowrite32(val, (lane)->priv->base + reg((lane)->id))
471 #define lynx_28g_pll_read(pll, reg)			\
472 	ioread32((pll)->priv->base + reg((pll)->id))
473 
lynx_lane_mode_str(enum lynx_lane_mode lane_mode)474 static const char *lynx_lane_mode_str(enum lynx_lane_mode lane_mode)
475 {
476 	switch (lane_mode) {
477 	case LANE_MODE_1000BASEX_SGMII:
478 		return "1000Base-X/SGMII";
479 	case LANE_MODE_10GBASER:
480 		return "10GBase-R";
481 	case LANE_MODE_USXGMII:
482 		return "USXGMII";
483 	default:
484 		return "unknown";
485 	}
486 }
487 
phy_interface_to_lane_mode(phy_interface_t intf)488 static enum lynx_lane_mode phy_interface_to_lane_mode(phy_interface_t intf)
489 {
490 	switch (intf) {
491 	case PHY_INTERFACE_MODE_SGMII:
492 	case PHY_INTERFACE_MODE_1000BASEX:
493 		return LANE_MODE_1000BASEX_SGMII;
494 	case PHY_INTERFACE_MODE_10GBASER:
495 		return LANE_MODE_10GBASER;
496 	case PHY_INTERFACE_MODE_USXGMII:
497 		return LANE_MODE_USXGMII;
498 	default:
499 		return LANE_MODE_UNKNOWN;
500 	}
501 }
502 
lynx_28g_supports_lane_mode(struct lynx_28g_priv * priv,enum lynx_lane_mode mode)503 static bool lynx_28g_supports_lane_mode(struct lynx_28g_priv *priv,
504 					enum lynx_lane_mode mode)
505 {
506 	int i;
507 
508 	for (i = 0; i < LYNX_28G_NUM_PLL; i++) {
509 		if (PLLnRSTCTL_DIS(priv->pll[i].rstctl))
510 			continue;
511 
512 		if (test_bit(mode, priv->pll[i].supported))
513 			return true;
514 	}
515 
516 	return false;
517 }
518 
lynx_28g_pll_get(struct lynx_28g_priv * priv,enum lynx_lane_mode mode)519 static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv,
520 					     enum lynx_lane_mode mode)
521 {
522 	struct lynx_28g_pll *pll;
523 	int i;
524 
525 	for (i = 0; i < LYNX_28G_NUM_PLL; i++) {
526 		pll = &priv->pll[i];
527 
528 		if (PLLnRSTCTL_DIS(pll->rstctl))
529 			continue;
530 
531 		if (test_bit(mode, pll->supported))
532 			return pll;
533 	}
534 
535 	/* no pll supports requested mode, either caller forgot to check
536 	 * lynx_28g_supports_lane_mode, or this is a bug.
537 	 */
538 	dev_WARN_ONCE(priv->dev, 1, "no pll for lane mode %s\n",
539 		      lynx_lane_mode_str(mode));
540 	return NULL;
541 }
542 
lynx_28g_lane_set_nrate(struct lynx_28g_lane * lane,struct lynx_28g_pll * pll,enum lynx_lane_mode lane_mode)543 static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane,
544 				    struct lynx_28g_pll *pll,
545 				    enum lynx_lane_mode lane_mode)
546 {
547 	switch (FIELD_GET(PLLnCR1_FRATE_SEL, pll->cr1)) {
548 	case PLLnCR1_FRATE_5G_10GVCO:
549 	case PLLnCR1_FRATE_5G_25GVCO:
550 		switch (lane_mode) {
551 		case LANE_MODE_1000BASEX_SGMII:
552 			lynx_28g_lane_rmw(lane, LNaTGCR0,
553 					  FIELD_PREP(LNaTGCR0_N_RATE, LNaTGCR0_N_RATE_QUARTER),
554 					  LNaTGCR0_N_RATE);
555 			lynx_28g_lane_rmw(lane, LNaRGCR0,
556 					  FIELD_PREP(LNaRGCR0_N_RATE, LNaRGCR0_N_RATE_QUARTER),
557 					  LNaRGCR0_N_RATE);
558 			break;
559 		default:
560 			break;
561 		}
562 		break;
563 	case PLLnCR1_FRATE_10G_20GVCO:
564 		switch (lane_mode) {
565 		case LANE_MODE_10GBASER:
566 		case LANE_MODE_USXGMII:
567 			lynx_28g_lane_rmw(lane, LNaTGCR0,
568 					  FIELD_PREP(LNaTGCR0_N_RATE, LNaTGCR0_N_RATE_FULL),
569 					  LNaTGCR0_N_RATE);
570 			lynx_28g_lane_rmw(lane, LNaRGCR0,
571 					  FIELD_PREP(LNaRGCR0_N_RATE, LNaRGCR0_N_RATE_FULL),
572 					  LNaRGCR0_N_RATE);
573 			break;
574 		default:
575 			break;
576 		}
577 		break;
578 	default:
579 		break;
580 	}
581 }
582 
lynx_28g_lane_set_pll(struct lynx_28g_lane * lane,struct lynx_28g_pll * pll)583 static void lynx_28g_lane_set_pll(struct lynx_28g_lane *lane,
584 				  struct lynx_28g_pll *pll)
585 {
586 	if (pll->id == 0) {
587 		lynx_28g_lane_rmw(lane, LNaTGCR0,
588 				  FIELD_PREP(LNaTGCR0_USE_PLL, LNaTGCR0_USE_PLLF),
589 				  LNaTGCR0_USE_PLL);
590 		lynx_28g_lane_rmw(lane, LNaRGCR0,
591 				  FIELD_PREP(LNaRGCR0_USE_PLL, LNaRGCR0_USE_PLLF),
592 				  LNaRGCR0_USE_PLL);
593 	} else {
594 		lynx_28g_lane_rmw(lane, LNaTGCR0,
595 				  FIELD_PREP(LNaTGCR0_USE_PLL, LNaTGCR0_USE_PLLS),
596 				  LNaTGCR0_USE_PLL);
597 		lynx_28g_lane_rmw(lane, LNaRGCR0,
598 				  FIELD_PREP(LNaRGCR0_USE_PLL, LNaRGCR0_USE_PLLS),
599 				  LNaRGCR0_USE_PLL);
600 	}
601 }
602 
lynx_28g_power_off(struct phy * phy)603 static int lynx_28g_power_off(struct phy *phy)
604 {
605 	struct lynx_28g_lane *lane = phy_get_drvdata(phy);
606 	u32 trstctl, rrstctl;
607 
608 	if (!lane->powered_up)
609 		return 0;
610 
611 	/* Issue a halt request */
612 	lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_HLT_REQ,
613 			  LNaTRSTCTL_HLT_REQ);
614 	lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_HLT_REQ,
615 			  LNaRRSTCTL_HLT_REQ);
616 
617 	/* Wait until the halting process is complete */
618 	do {
619 		trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL);
620 		rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
621 	} while ((trstctl & LNaTRSTCTL_HLT_REQ) ||
622 		 (rrstctl & LNaRRSTCTL_HLT_REQ));
623 
624 	lane->powered_up = false;
625 
626 	return 0;
627 }
628 
lynx_28g_power_on(struct phy * phy)629 static int lynx_28g_power_on(struct phy *phy)
630 {
631 	struct lynx_28g_lane *lane = phy_get_drvdata(phy);
632 	u32 trstctl, rrstctl;
633 
634 	if (lane->powered_up)
635 		return 0;
636 
637 	/* Issue a reset request on the lane */
638 	lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_RST_REQ,
639 			  LNaTRSTCTL_RST_REQ);
640 	lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ,
641 			  LNaRRSTCTL_RST_REQ);
642 
643 	/* Wait until the reset sequence is completed */
644 	do {
645 		trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL);
646 		rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
647 	} while (!(trstctl & LNaTRSTCTL_RST_DONE) ||
648 		 !(rrstctl & LNaRRSTCTL_RST_DONE));
649 
650 	lane->powered_up = true;
651 
652 	return 0;
653 }
654 
lynx_28g_get_pccr(enum lynx_lane_mode lane_mode,int lane,struct lynx_pccr * pccr)655 static int lynx_28g_get_pccr(enum lynx_lane_mode lane_mode, int lane,
656 			     struct lynx_pccr *pccr)
657 {
658 	switch (lane_mode) {
659 	case LANE_MODE_1000BASEX_SGMII:
660 		pccr->offset = PCC8;
661 		pccr->width = 4;
662 		pccr->shift = SGMII_CFG(lane);
663 		break;
664 	case LANE_MODE_USXGMII:
665 	case LANE_MODE_10GBASER:
666 		pccr->offset = PCCC;
667 		pccr->width = 4;
668 		pccr->shift = SXGMII_CFG(lane);
669 		break;
670 	default:
671 		return -EOPNOTSUPP;
672 	}
673 
674 	return 0;
675 }
676 
lynx_28g_get_pcvt_offset(int lane,enum lynx_lane_mode lane_mode)677 static int lynx_28g_get_pcvt_offset(int lane, enum lynx_lane_mode lane_mode)
678 {
679 	switch (lane_mode) {
680 	case LANE_MODE_1000BASEX_SGMII:
681 		return SGMIIaCR0(lane);
682 	case LANE_MODE_USXGMII:
683 	case LANE_MODE_10GBASER:
684 		return SXGMIIaCR0(lane);
685 	default:
686 		return -EOPNOTSUPP;
687 	}
688 }
689 
lynx_pccr_read(struct lynx_28g_lane * lane,enum lynx_lane_mode mode,u32 * val)690 static int lynx_pccr_read(struct lynx_28g_lane *lane, enum lynx_lane_mode mode,
691 			  u32 *val)
692 {
693 	struct lynx_28g_priv *priv = lane->priv;
694 	struct lynx_pccr pccr;
695 	u32 tmp;
696 	int err;
697 
698 	err = lynx_28g_get_pccr(mode, lane->id, &pccr);
699 	if (err)
700 		return err;
701 
702 	tmp = lynx_28g_read(priv, pccr.offset);
703 	*val = (tmp >> pccr.shift) & GENMASK(pccr.width - 1, 0);
704 
705 	return 0;
706 }
707 
lynx_pccr_write(struct lynx_28g_lane * lane,enum lynx_lane_mode lane_mode,u32 val)708 static int lynx_pccr_write(struct lynx_28g_lane *lane,
709 			   enum lynx_lane_mode lane_mode, u32 val)
710 {
711 	struct lynx_28g_priv *priv = lane->priv;
712 	struct lynx_pccr pccr;
713 	u32 old, tmp, mask;
714 	int err;
715 
716 	err = lynx_28g_get_pccr(lane_mode, lane->id, &pccr);
717 	if (err)
718 		return err;
719 
720 	old = lynx_28g_read(priv, pccr.offset);
721 	mask = GENMASK(pccr.width - 1, 0) << pccr.shift;
722 	tmp = (old & ~mask) | (val << pccr.shift);
723 	lynx_28g_write(priv, pccr.offset, tmp);
724 
725 	dev_dbg(&lane->phy->dev, "PCCR@0x%x: 0x%x -> 0x%x\n",
726 		pccr.offset, old, tmp);
727 
728 	return 0;
729 }
730 
lynx_pcvt_read(struct lynx_28g_lane * lane,enum lynx_lane_mode lane_mode,int cr,u32 * val)731 static int lynx_pcvt_read(struct lynx_28g_lane *lane,
732 			  enum lynx_lane_mode lane_mode, int cr, u32 *val)
733 {
734 	struct lynx_28g_priv *priv = lane->priv;
735 	int offset;
736 
737 	offset = lynx_28g_get_pcvt_offset(lane->id, lane_mode);
738 	if (offset < 0)
739 		return offset;
740 
741 	*val = lynx_28g_read(priv, offset + cr);
742 
743 	return 0;
744 }
745 
lynx_pcvt_write(struct lynx_28g_lane * lane,enum lynx_lane_mode lane_mode,int cr,u32 val)746 static int lynx_pcvt_write(struct lynx_28g_lane *lane,
747 			   enum lynx_lane_mode lane_mode, int cr, u32 val)
748 {
749 	struct lynx_28g_priv *priv = lane->priv;
750 	int offset;
751 
752 	offset = lynx_28g_get_pcvt_offset(lane->id, lane_mode);
753 	if (offset < 0)
754 		return offset;
755 
756 	lynx_28g_write(priv, offset + cr, val);
757 
758 	return 0;
759 }
760 
lynx_pcvt_rmw(struct lynx_28g_lane * lane,enum lynx_lane_mode lane_mode,int cr,u32 val,u32 mask)761 static int lynx_pcvt_rmw(struct lynx_28g_lane *lane,
762 			 enum lynx_lane_mode lane_mode,
763 			 int cr, u32 val, u32 mask)
764 {
765 	int err;
766 	u32 tmp;
767 
768 	err = lynx_pcvt_read(lane, lane_mode, cr, &tmp);
769 	if (err)
770 		return err;
771 
772 	tmp &= ~mask;
773 	tmp |= val;
774 
775 	return lynx_pcvt_write(lane, lane_mode, cr, tmp);
776 }
777 
lynx_28g_lane_remap_pll(struct lynx_28g_lane * lane,enum lynx_lane_mode lane_mode)778 static void lynx_28g_lane_remap_pll(struct lynx_28g_lane *lane,
779 				    enum lynx_lane_mode lane_mode)
780 {
781 	struct lynx_28g_priv *priv = lane->priv;
782 	struct lynx_28g_pll *pll;
783 
784 	/* Switch to the PLL that works with this interface type */
785 	pll = lynx_28g_pll_get(priv, lane_mode);
786 	if (unlikely(pll == NULL))
787 		return;
788 
789 	lynx_28g_lane_set_pll(lane, pll);
790 
791 	/* Choose the portion of clock net to be used on this lane */
792 	lynx_28g_lane_set_nrate(lane, pll, lane_mode);
793 }
794 
lynx_28g_lane_change_proto_conf(struct lynx_28g_lane * lane,enum lynx_lane_mode lane_mode)795 static void lynx_28g_lane_change_proto_conf(struct lynx_28g_lane *lane,
796 					    enum lynx_lane_mode lane_mode)
797 {
798 	const struct lynx_28g_proto_conf *conf = &lynx_28g_proto_conf[lane_mode];
799 
800 	lynx_28g_lane_rmw(lane, LNaGCR0,
801 			  FIELD_PREP(LNaGCR0_PROTO_SEL, conf->proto_sel) |
802 			  FIELD_PREP(LNaGCR0_IF_WIDTH, conf->if_width),
803 			  LNaGCR0_PROTO_SEL | LNaGCR0_IF_WIDTH);
804 
805 	lynx_28g_lane_rmw(lane, LNaTECR0,
806 			  FIELD_PREP(LNaTECR0_EQ_TYPE, conf->teq_type) |
807 			  FIELD_PREP(LNaTECR0_EQ_SGN_PREQ, conf->sgn_preq) |
808 			  FIELD_PREP(LNaTECR0_EQ_PREQ, conf->ratio_preq) |
809 			  FIELD_PREP(LNaTECR0_EQ_SGN_POST1Q, conf->sgn_post1q) |
810 			  FIELD_PREP(LNaTECR0_EQ_POST1Q, conf->ratio_post1q) |
811 			  FIELD_PREP(LNaTECR0_EQ_AMP_RED, conf->amp_red),
812 			  LNaTECR0_EQ_TYPE |
813 			  LNaTECR0_EQ_SGN_PREQ |
814 			  LNaTECR0_EQ_PREQ |
815 			  LNaTECR0_EQ_SGN_POST1Q |
816 			  LNaTECR0_EQ_POST1Q |
817 			  LNaTECR0_EQ_AMP_RED);
818 
819 	lynx_28g_lane_rmw(lane, LNaTECR1,
820 			  FIELD_PREP(LNaTECR1_EQ_ADPT_EQ, conf->adpt_eq),
821 			  LNaTECR1_EQ_ADPT_EQ);
822 
823 	lynx_28g_lane_rmw(lane, LNaRGCR1,
824 			  FIELD_PREP(LNaRGCR1_ENTER_IDLE_FLT_SEL, conf->enter_idle_flt_sel) |
825 			  FIELD_PREP(LNaRGCR1_EXIT_IDLE_FLT_SEL, conf->exit_idle_flt_sel) |
826 			  FIELD_PREP(LNaRGCR1_DATA_LOST_TH_SEL, conf->data_lost_th_sel),
827 			  LNaRGCR1_ENTER_IDLE_FLT_SEL |
828 			  LNaRGCR1_EXIT_IDLE_FLT_SEL |
829 			  LNaRGCR1_DATA_LOST_TH_SEL);
830 
831 	lynx_28g_lane_rmw(lane, LNaRECR0,
832 			  FIELD_PREP(LNaRECR0_EQ_GAINK2_HF_OV_EN, conf->gk2ovd_en) |
833 			  FIELD_PREP(LNaRECR0_EQ_GAINK3_MF_OV_EN, conf->gk3ovd_en) |
834 			  FIELD_PREP(LNaRECR0_EQ_GAINK4_LF_OV_EN, conf->gk4ovd_en) |
835 			  FIELD_PREP(LNaRECR0_EQ_GAINK2_HF_OV, conf->gk2ovd) |
836 			  FIELD_PREP(LNaRECR0_EQ_GAINK3_MF_OV, conf->gk3ovd) |
837 			  FIELD_PREP(LNaRECR0_EQ_GAINK4_LF_OV, conf->gk4ovd),
838 			  LNaRECR0_EQ_GAINK2_HF_OV |
839 			  LNaRECR0_EQ_GAINK3_MF_OV |
840 			  LNaRECR0_EQ_GAINK4_LF_OV |
841 			  LNaRECR0_EQ_GAINK2_HF_OV_EN |
842 			  LNaRECR0_EQ_GAINK3_MF_OV_EN |
843 			  LNaRECR0_EQ_GAINK4_LF_OV_EN);
844 
845 	lynx_28g_lane_rmw(lane, LNaRECR1,
846 			  FIELD_PREP(LNaRECR1_EQ_OFFSET_OV, conf->eq_offset_ovd) |
847 			  FIELD_PREP(LNaRECR1_EQ_OFFSET_OV_EN, conf->eq_offset_ovd_en),
848 			  LNaRECR1_EQ_OFFSET_OV |
849 			  LNaRECR1_EQ_OFFSET_OV_EN);
850 
851 	lynx_28g_lane_rmw(lane, LNaRECR2,
852 			  FIELD_PREP(LNaRECR2_EQ_OFFSET_RNG_DBL, conf->eq_offset_rng_dbl) |
853 			  FIELD_PREP(LNaRECR2_EQ_BLW_SEL, conf->eq_blw_sel) |
854 			  FIELD_PREP(LNaRECR2_EQ_BOOST, conf->eq_boost) |
855 			  FIELD_PREP(LNaRECR2_SPARE_IN, conf->spare_in),
856 			  LNaRECR2_EQ_OFFSET_RNG_DBL |
857 			  LNaRECR2_EQ_BLW_SEL |
858 			  LNaRECR2_EQ_BOOST |
859 			  LNaRECR2_SPARE_IN);
860 
861 	lynx_28g_lane_rmw(lane, LNaRSCCR0,
862 			  FIELD_PREP(LNaRSCCR0_SMP_AUTOZ_D1R, conf->smp_autoz_d1r) |
863 			  FIELD_PREP(LNaRSCCR0_SMP_AUTOZ_EG1R, conf->smp_autoz_eg1r),
864 			  LNaRSCCR0_SMP_AUTOZ_D1R |
865 			  LNaRSCCR0_SMP_AUTOZ_EG1R);
866 
867 	lynx_28g_lane_write(lane, LNaRCCR0, conf->rccr0);
868 	lynx_28g_lane_write(lane, LNaTTLCR0, conf->ttlcr0);
869 }
870 
lynx_28g_lane_disable_pcvt(struct lynx_28g_lane * lane,enum lynx_lane_mode lane_mode)871 static int lynx_28g_lane_disable_pcvt(struct lynx_28g_lane *lane,
872 				      enum lynx_lane_mode lane_mode)
873 {
874 	struct lynx_28g_priv *priv = lane->priv;
875 	int err;
876 
877 	spin_lock(&priv->pcc_lock);
878 
879 	err = lynx_pccr_write(lane, lane_mode, 0);
880 	if (err)
881 		goto out;
882 
883 	switch (lane_mode) {
884 	case LANE_MODE_1000BASEX_SGMII:
885 		err = lynx_pcvt_rmw(lane, lane_mode, CR(1), 0,
886 				    SGMIIaCR1_SGPCS_EN);
887 		break;
888 	default:
889 		err = 0;
890 	}
891 
892 out:
893 	spin_unlock(&priv->pcc_lock);
894 
895 	return err;
896 }
897 
lynx_28g_lane_enable_pcvt(struct lynx_28g_lane * lane,enum lynx_lane_mode lane_mode)898 static int lynx_28g_lane_enable_pcvt(struct lynx_28g_lane *lane,
899 				     enum lynx_lane_mode lane_mode)
900 {
901 	struct lynx_28g_priv *priv = lane->priv;
902 	u32 val;
903 	int err;
904 
905 	spin_lock(&priv->pcc_lock);
906 
907 	switch (lane_mode) {
908 	case LANE_MODE_1000BASEX_SGMII:
909 		err = lynx_pcvt_rmw(lane, lane_mode, CR(1), SGMIIaCR1_SGPCS_EN,
910 				    SGMIIaCR1_SGPCS_EN);
911 		break;
912 	default:
913 		err = 0;
914 	}
915 
916 	val = 0;
917 
918 	switch (lane_mode) {
919 	case LANE_MODE_1000BASEX_SGMII:
920 		val |= PCC8_SGMIIa_CFG;
921 		break;
922 	case LANE_MODE_10GBASER:
923 		val |= PCCC_SXGMIIn_XFI;
924 		fallthrough;
925 	case LANE_MODE_USXGMII:
926 		val |= PCCC_SXGMIIn_CFG;
927 		break;
928 	default:
929 		break;
930 	}
931 
932 	err = lynx_pccr_write(lane, lane_mode, val);
933 
934 	spin_unlock(&priv->pcc_lock);
935 
936 	return err;
937 }
938 
lynx_28g_set_mode(struct phy * phy,enum phy_mode mode,int submode)939 static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
940 {
941 	struct lynx_28g_lane *lane = phy_get_drvdata(phy);
942 	struct lynx_28g_priv *priv = lane->priv;
943 	int powered_up = lane->powered_up;
944 	enum lynx_lane_mode lane_mode;
945 	int err = 0;
946 
947 	if (mode != PHY_MODE_ETHERNET)
948 		return -EOPNOTSUPP;
949 
950 	if (lane->mode == LANE_MODE_UNKNOWN)
951 		return -EOPNOTSUPP;
952 
953 	lane_mode = phy_interface_to_lane_mode(submode);
954 	if (!lynx_28g_supports_lane_mode(priv, lane_mode))
955 		return -EOPNOTSUPP;
956 
957 	if (lane_mode == lane->mode)
958 		return 0;
959 
960 	/* If the lane is powered up, put the lane into the halt state while
961 	 * the reconfiguration is being done.
962 	 */
963 	if (powered_up)
964 		lynx_28g_power_off(phy);
965 
966 	err = lynx_28g_lane_disable_pcvt(lane, lane->mode);
967 	if (err)
968 		goto out;
969 
970 	lynx_28g_lane_change_proto_conf(lane, lane_mode);
971 	lynx_28g_lane_remap_pll(lane, lane_mode);
972 	WARN_ON(lynx_28g_lane_enable_pcvt(lane, lane_mode));
973 
974 	lane->mode = lane_mode;
975 
976 out:
977 	if (powered_up)
978 		lynx_28g_power_on(phy);
979 
980 	return err;
981 }
982 
lynx_28g_validate(struct phy * phy,enum phy_mode mode,int submode,union phy_configure_opts * opts __always_unused)983 static int lynx_28g_validate(struct phy *phy, enum phy_mode mode, int submode,
984 			     union phy_configure_opts *opts __always_unused)
985 {
986 	struct lynx_28g_lane *lane = phy_get_drvdata(phy);
987 	struct lynx_28g_priv *priv = lane->priv;
988 	enum lynx_lane_mode lane_mode;
989 
990 	if (mode != PHY_MODE_ETHERNET)
991 		return -EOPNOTSUPP;
992 
993 	lane_mode = phy_interface_to_lane_mode(submode);
994 	if (!lynx_28g_supports_lane_mode(priv, lane_mode))
995 		return -EOPNOTSUPP;
996 
997 	return 0;
998 }
999 
lynx_28g_init(struct phy * phy)1000 static int lynx_28g_init(struct phy *phy)
1001 {
1002 	struct lynx_28g_lane *lane = phy_get_drvdata(phy);
1003 
1004 	/* Mark the fact that the lane was init */
1005 	lane->init = true;
1006 
1007 	/* SerDes lanes are powered on at boot time.  Any lane that is managed
1008 	 * by this driver will get powered down at init time aka at dpaa2-eth
1009 	 * probe time.
1010 	 */
1011 	lane->powered_up = true;
1012 	lynx_28g_power_off(phy);
1013 
1014 	return 0;
1015 }
1016 
1017 static const struct phy_ops lynx_28g_ops = {
1018 	.init		= lynx_28g_init,
1019 	.power_on	= lynx_28g_power_on,
1020 	.power_off	= lynx_28g_power_off,
1021 	.set_mode	= lynx_28g_set_mode,
1022 	.validate	= lynx_28g_validate,
1023 	.owner		= THIS_MODULE,
1024 };
1025 
lynx_28g_pll_read_configuration(struct lynx_28g_priv * priv)1026 static void lynx_28g_pll_read_configuration(struct lynx_28g_priv *priv)
1027 {
1028 	struct lynx_28g_pll *pll;
1029 	int i;
1030 
1031 	for (i = 0; i < LYNX_28G_NUM_PLL; i++) {
1032 		pll = &priv->pll[i];
1033 		pll->priv = priv;
1034 		pll->id = i;
1035 
1036 		pll->rstctl = lynx_28g_pll_read(pll, PLLnRSTCTL);
1037 		pll->cr0 = lynx_28g_pll_read(pll, PLLnCR0);
1038 		pll->cr1 = lynx_28g_pll_read(pll, PLLnCR1);
1039 
1040 		if (PLLnRSTCTL_DIS(pll->rstctl))
1041 			continue;
1042 
1043 		switch (FIELD_GET(PLLnCR1_FRATE_SEL, pll->cr1)) {
1044 		case PLLnCR1_FRATE_5G_10GVCO:
1045 		case PLLnCR1_FRATE_5G_25GVCO:
1046 			/* 5GHz clock net */
1047 			__set_bit(LANE_MODE_1000BASEX_SGMII, pll->supported);
1048 			break;
1049 		case PLLnCR1_FRATE_10G_20GVCO:
1050 			/* 10.3125GHz clock net */
1051 			__set_bit(LANE_MODE_10GBASER, pll->supported);
1052 			__set_bit(LANE_MODE_USXGMII, pll->supported);
1053 			break;
1054 		default:
1055 			/* 6GHz, 12.890625GHz, 8GHz */
1056 			break;
1057 		}
1058 	}
1059 }
1060 
1061 #define work_to_lynx(w) container_of((w), struct lynx_28g_priv, cdr_check.work)
1062 
lynx_28g_cdr_lock_check(struct work_struct * work)1063 static void lynx_28g_cdr_lock_check(struct work_struct *work)
1064 {
1065 	struct lynx_28g_priv *priv = work_to_lynx(work);
1066 	struct lynx_28g_lane *lane;
1067 	u32 rrstctl;
1068 	int i;
1069 
1070 	for (i = 0; i < LYNX_28G_NUM_LANE; i++) {
1071 		lane = &priv->lane[i];
1072 		if (!lane->phy)
1073 			continue;
1074 
1075 		mutex_lock(&lane->phy->mutex);
1076 
1077 		if (!lane->init || !lane->powered_up) {
1078 			mutex_unlock(&lane->phy->mutex);
1079 			continue;
1080 		}
1081 
1082 		rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
1083 		if (!(rrstctl & LNaRRSTCTL_CDR_LOCK)) {
1084 			lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ,
1085 					  LNaRRSTCTL_RST_REQ);
1086 			do {
1087 				rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
1088 			} while (!(rrstctl & LNaRRSTCTL_RST_DONE));
1089 		}
1090 
1091 		mutex_unlock(&lane->phy->mutex);
1092 	}
1093 	queue_delayed_work(system_power_efficient_wq, &priv->cdr_check,
1094 			   msecs_to_jiffies(1000));
1095 }
1096 
lynx_28g_lane_read_configuration(struct lynx_28g_lane * lane)1097 static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane)
1098 {
1099 	u32 pccr, pss, protocol;
1100 
1101 	pss = lynx_28g_lane_read(lane, LNaPSS);
1102 	protocol = FIELD_GET(LNaPSS_TYPE, pss);
1103 	switch (protocol) {
1104 	case LNaPSS_TYPE_SGMII:
1105 		lane->mode = LANE_MODE_1000BASEX_SGMII;
1106 		break;
1107 	case LNaPSS_TYPE_XFI:
1108 		lynx_pccr_read(lane, LANE_MODE_10GBASER, &pccr);
1109 		if (pccr & PCCC_SXGMIIn_XFI)
1110 			lane->mode = LANE_MODE_10GBASER;
1111 		else
1112 			lane->mode = LANE_MODE_USXGMII;
1113 		break;
1114 	default:
1115 		lane->mode = LANE_MODE_UNKNOWN;
1116 	}
1117 }
1118 
lynx_28g_xlate(struct device * dev,const struct of_phandle_args * args)1119 static struct phy *lynx_28g_xlate(struct device *dev,
1120 				  const struct of_phandle_args *args)
1121 {
1122 	struct lynx_28g_priv *priv = dev_get_drvdata(dev);
1123 	int idx;
1124 
1125 	if (args->args_count == 0)
1126 		return of_phy_simple_xlate(dev, args);
1127 	else if (args->args_count != 1)
1128 		return ERR_PTR(-ENODEV);
1129 
1130 	idx = args->args[0];
1131 
1132 	if (WARN_ON(idx >= LYNX_28G_NUM_LANE))
1133 		return ERR_PTR(-EINVAL);
1134 
1135 	return priv->lane[idx].phy;
1136 }
1137 
lynx_28g_probe_lane(struct lynx_28g_priv * priv,int id,struct device_node * dn)1138 static int lynx_28g_probe_lane(struct lynx_28g_priv *priv, int id,
1139 			       struct device_node *dn)
1140 {
1141 	struct lynx_28g_lane *lane = &priv->lane[id];
1142 	struct phy *phy;
1143 
1144 	phy = devm_phy_create(priv->dev, dn, &lynx_28g_ops);
1145 	if (IS_ERR(phy))
1146 		return PTR_ERR(phy);
1147 
1148 	lane->priv = priv;
1149 	lane->phy = phy;
1150 	lane->id = id;
1151 	phy_set_drvdata(phy, lane);
1152 	lynx_28g_lane_read_configuration(lane);
1153 
1154 	return 0;
1155 }
1156 
lynx_28g_probe(struct platform_device * pdev)1157 static int lynx_28g_probe(struct platform_device *pdev)
1158 {
1159 	struct device *dev = &pdev->dev;
1160 	struct phy_provider *provider;
1161 	struct lynx_28g_priv *priv;
1162 	struct device_node *dn;
1163 	int err;
1164 
1165 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1166 	if (!priv)
1167 		return -ENOMEM;
1168 
1169 	priv->dev = dev;
1170 	dev_set_drvdata(dev, priv);
1171 	spin_lock_init(&priv->pcc_lock);
1172 	INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check);
1173 
1174 	priv->base = devm_platform_ioremap_resource(pdev, 0);
1175 	if (IS_ERR(priv->base))
1176 		return PTR_ERR(priv->base);
1177 
1178 	lynx_28g_pll_read_configuration(priv);
1179 
1180 	dn = dev_of_node(dev);
1181 	if (of_get_child_count(dn)) {
1182 		struct device_node *child;
1183 
1184 		for_each_available_child_of_node(dn, child) {
1185 			u32 reg;
1186 
1187 			/* PHY subnode name must be 'phy'. */
1188 			if (!(of_node_name_eq(child, "phy")))
1189 				continue;
1190 
1191 			if (of_property_read_u32(child, "reg", &reg)) {
1192 				dev_err(dev, "No \"reg\" property for %pOF\n", child);
1193 				of_node_put(child);
1194 				return -EINVAL;
1195 			}
1196 
1197 			if (reg >= LYNX_28G_NUM_LANE) {
1198 				dev_err(dev, "\"reg\" property out of range for %pOF\n", child);
1199 				of_node_put(child);
1200 				return -EINVAL;
1201 			}
1202 
1203 			err = lynx_28g_probe_lane(priv, reg, child);
1204 			if (err) {
1205 				of_node_put(child);
1206 				return err;
1207 			}
1208 		}
1209 	} else {
1210 		for (int i = 0; i < LYNX_28G_NUM_LANE; i++) {
1211 			err = lynx_28g_probe_lane(priv, i, NULL);
1212 			if (err)
1213 				return err;
1214 		}
1215 	}
1216 
1217 	provider = devm_of_phy_provider_register(dev, lynx_28g_xlate);
1218 	if (IS_ERR(provider))
1219 		return PTR_ERR(provider);
1220 
1221 	queue_delayed_work(system_power_efficient_wq, &priv->cdr_check,
1222 			   msecs_to_jiffies(1000));
1223 
1224 	return 0;
1225 }
1226 
lynx_28g_remove(struct platform_device * pdev)1227 static void lynx_28g_remove(struct platform_device *pdev)
1228 {
1229 	struct device *dev = &pdev->dev;
1230 	struct lynx_28g_priv *priv = dev_get_drvdata(dev);
1231 
1232 	cancel_delayed_work_sync(&priv->cdr_check);
1233 }
1234 
1235 static const struct of_device_id lynx_28g_of_match_table[] = {
1236 	{ .compatible = "fsl,lynx-28g" },
1237 	{ },
1238 };
1239 MODULE_DEVICE_TABLE(of, lynx_28g_of_match_table);
1240 
1241 static struct platform_driver lynx_28g_driver = {
1242 	.probe = lynx_28g_probe,
1243 	.remove = lynx_28g_remove,
1244 	.driver = {
1245 		.name = "lynx-28g",
1246 		.of_match_table = lynx_28g_of_match_table,
1247 	},
1248 };
1249 module_platform_driver(lynx_28g_driver);
1250 
1251 MODULE_AUTHOR("Ioana Ciornei <ioana.ciornei@nxp.com>");
1252 MODULE_DESCRIPTION("Lynx 28G SerDes PHY driver for Layerscape SoCs");
1253 MODULE_LICENSE("GPL v2");
1254