1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2015 Freescale Semiconductor, Inc.
4  */
5 
6 #include <common.h>
7 #include <log.h>
8 #include <asm/io.h>
9 #include <linux/delay.h>
10 #include <linux/errno.h>
11 #include <asm/arch/fsl_serdes.h>
12 #include <asm/arch/soc.h>
13 
14 #ifdef CONFIG_SYS_FSL_SRDS_1
15 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
16 #endif
17 #ifdef CONFIG_SYS_FSL_SRDS_2
18 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
19 #endif
20 
is_serdes_configured(enum srds_prtcl device)21 int is_serdes_configured(enum srds_prtcl device)
22 {
23 	int ret = 0;
24 
25 #ifdef CONFIG_SYS_FSL_SRDS_1
26 	if (!serdes1_prtcl_map[NONE])
27 		fsl_serdes_init();
28 
29 	ret |= serdes1_prtcl_map[device];
30 #endif
31 #ifdef CONFIG_SYS_FSL_SRDS_2
32 	if (!serdes2_prtcl_map[NONE])
33 		fsl_serdes_init();
34 
35 	ret |= serdes2_prtcl_map[device];
36 #endif
37 
38 	return !!ret;
39 }
40 
serdes_get_first_lane(u32 sd,enum srds_prtcl device)41 int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
42 {
43 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
44 	u32 cfg = gur_in32(&gur->rcwsr[4]);
45 	int i;
46 
47 	switch (sd) {
48 #ifdef CONFIG_SYS_FSL_SRDS_1
49 	case FSL_SRDS_1:
50 		cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
51 		cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
52 		break;
53 #endif
54 #ifdef CONFIG_SYS_FSL_SRDS_2
55 	case FSL_SRDS_2:
56 		cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
57 		cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
58 		break;
59 #endif
60 	default:
61 		printf("invalid SerDes%d\n", sd);
62 		break;
63 	}
64 
65 	/* Is serdes enabled at all? */
66 	if (unlikely(cfg == 0))
67 		return -ENODEV;
68 
69 	for (i = 0; i < SRDS_MAX_LANES; i++) {
70 		if (serdes_get_prtcl(sd, cfg, i) == device)
71 			return i;
72 	}
73 
74 	return -ENODEV;
75 }
76 
get_serdes_protocol(void)77 int get_serdes_protocol(void)
78 {
79 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
80 	u32 cfg = gur_in32(&gur->rcwsr[4]) &
81 			  FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
82 	cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
83 
84 	return cfg;
85 }
86 
serdes_clock_to_string(u32 clock)87 const char *serdes_clock_to_string(u32 clock)
88 {
89 	switch (clock) {
90 	case SRDS_PLLCR0_RFCK_SEL_100:
91 		return "100";
92 	case SRDS_PLLCR0_RFCK_SEL_125:
93 		return "125";
94 	case SRDS_PLLCR0_RFCK_SEL_156_25:
95 		return "156.25";
96 	default:
97 		return "100";
98 	}
99 }
100 
serdes_init(u32 sd,u32 sd_addr,u32 sd_prctl_mask,u32 sd_prctl_shift,u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])101 void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
102 		 u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
103 {
104 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
105 	u32 cfg;
106 	int lane;
107 
108 	if (serdes_prtcl_map[NONE])
109 		return;
110 
111 	memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
112 
113 	cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask;
114 	cfg >>= sd_prctl_shift;
115 	printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
116 
117 	if (!is_serdes_prtcl_valid(sd, cfg))
118 		printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
119 
120 	for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
121 		enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
122 
123 		if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
124 			debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
125 		else
126 			serdes_prtcl_map[lane_prtcl] = 1;
127 	}
128 
129 	/* Set the first element to indicate serdes has been initialized */
130 	serdes_prtcl_map[NONE] = 1;
131 }
132 
get_serdes_volt(void)133 __weak int get_serdes_volt(void)
134 {
135 	return -1;
136 }
137 
set_serdes_volt(int svdd)138 __weak int set_serdes_volt(int svdd)
139 {
140 	return -1;
141 }
142 
setup_serdes_volt(u32 svdd)143 int setup_serdes_volt(u32 svdd)
144 {
145 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
146 	struct ccsr_serdes *serdes1_base;
147 #ifdef CONFIG_SYS_FSL_SRDS_2
148 	struct ccsr_serdes *serdes2_base;
149 #endif
150 	u32 cfg_rcw4 = gur_in32(&gur->rcwsr[4]);
151 	u32 cfg_rcw5 = gur_in32(&gur->rcwsr[5]);
152 	u32 cfg_tmp, reg = 0;
153 	int svdd_cur, svdd_tar;
154 	int ret;
155 	int i;
156 
157 	/* Only support switch SVDD to 900mV/1000mV */
158 	if (svdd != 900 && svdd != 1000)
159 		return -EINVAL;
160 
161 	svdd_tar = svdd;
162 	svdd_cur = get_serdes_volt();
163 	if (svdd_cur < 0)
164 		return -EINVAL;
165 
166 	debug("%s: current SVDD: %dmV; target SVDD: %dmV\n",
167 	      __func__, svdd_cur, svdd_tar);
168 	if (svdd_cur == svdd_tar)
169 		return 0;
170 
171 	serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR;
172 #ifdef CONFIG_SYS_FSL_SRDS_2
173 	serdes2_base = (void *)serdes1_base + 0x10000;
174 #endif
175 
176 	/* Put the all enabled lanes in reset */
177 #ifdef CONFIG_SYS_FSL_SRDS_1
178 	cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
179 	cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
180 
181 	for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
182 		reg = in_be32(&serdes1_base->lane[i].gcr0);
183 		reg &= 0xFF9FFFFF;
184 		out_be32(&serdes1_base->lane[i].gcr0, reg);
185 	}
186 #endif
187 #ifdef CONFIG_SYS_FSL_SRDS_2
188 	cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
189 	cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
190 
191 	for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
192 		reg = in_be32(&serdes2_base->lane[i].gcr0);
193 		reg &= 0xFF9FFFFF;
194 		out_be32(&serdes2_base->lane[i].gcr0, reg);
195 	}
196 #endif
197 
198 	/* Put the all enabled PLL in reset */
199 #ifdef CONFIG_SYS_FSL_SRDS_1
200 	cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
201 	for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
202 		reg = in_be32(&serdes1_base->bank[i].rstctl);
203 		reg &= 0xFFFFFFBF;
204 		reg |= 0x10000000;
205 		out_be32(&serdes1_base->bank[i].rstctl, reg);
206 		udelay(1);
207 
208 		reg = in_be32(&serdes1_base->bank[i].rstctl);
209 		reg &= 0xFFFFFF1F;
210 		out_be32(&serdes1_base->bank[i].rstctl, reg);
211 	}
212 	udelay(1);
213 #endif
214 
215 #ifdef CONFIG_SYS_FSL_SRDS_2
216 	cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
217 	for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
218 		reg = in_be32(&serdes2_base->bank[i].rstctl);
219 		reg &= 0xFFFFFFBF;
220 		reg |= 0x10000000;
221 		out_be32(&serdes2_base->bank[i].rstctl, reg);
222 		udelay(1);
223 
224 		reg = in_be32(&serdes2_base->bank[i].rstctl);
225 		reg &= 0xFFFFFF1F;
226 		out_be32(&serdes2_base->bank[i].rstctl, reg);
227 	}
228 	udelay(1);
229 #endif
230 
231 	/* Put the Rx/Tx calibration into reset */
232 #ifdef CONFIG_SYS_FSL_SRDS_1
233 	reg = in_be32(&serdes1_base->srdstcalcr);
234 	reg &= 0xF7FFFFFF;
235 	out_be32(&serdes1_base->srdstcalcr, reg);
236 	reg = in_be32(&serdes1_base->srdsrcalcr);
237 	reg &= 0xF7FFFFFF;
238 	out_be32(&serdes1_base->srdsrcalcr, reg);
239 
240 #endif
241 #ifdef CONFIG_SYS_FSL_SRDS_2
242 	reg = in_be32(&serdes2_base->srdstcalcr);
243 	reg &= 0xF7FFFFFF;
244 	out_be32(&serdes2_base->srdstcalcr, reg);
245 	reg = in_be32(&serdes2_base->srdsrcalcr);
246 	reg &= 0xF7FFFFFF;
247 	out_be32(&serdes2_base->srdsrcalcr, reg);
248 #endif
249 
250 	/*
251 	 * If SVDD set failed, will not return directly, so that the
252 	 * serdes lanes can complete reseting.
253 	 */
254 	ret = set_serdes_volt(svdd_tar);
255 	if (ret)
256 		printf("%s: Failed to set SVDD\n", __func__);
257 
258 	/* Wait for SVDD to stabilize */
259 	udelay(100);
260 
261 	/* For each PLL that’s not disabled via RCW */
262 #ifdef CONFIG_SYS_FSL_SRDS_1
263 	cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
264 	for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
265 		reg = in_be32(&serdes1_base->bank[i].rstctl);
266 		reg |= 0x00000020;
267 		out_be32(&serdes1_base->bank[i].rstctl, reg);
268 		udelay(1);
269 
270 		reg = in_be32(&serdes1_base->bank[i].rstctl);
271 		reg |= 0x00000080;
272 		out_be32(&serdes1_base->bank[i].rstctl, reg);
273 
274 		/* Take the Rx/Tx calibration out of reset */
275 		if (!(cfg_tmp == 0x3 && i == 1)) {
276 			udelay(1);
277 			reg = in_be32(&serdes1_base->srdstcalcr);
278 			reg |= 0x08000000;
279 			out_be32(&serdes1_base->srdstcalcr, reg);
280 			reg = in_be32(&serdes1_base->srdsrcalcr);
281 			reg |= 0x08000000;
282 			out_be32(&serdes1_base->srdsrcalcr, reg);
283 		}
284 	}
285 	udelay(1);
286 #endif
287 
288 #ifdef CONFIG_SYS_FSL_SRDS_2
289 	cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
290 	for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
291 		reg = in_be32(&serdes2_base->bank[i].rstctl);
292 		reg |= 0x00000020;
293 		out_be32(&serdes2_base->bank[i].rstctl, reg);
294 		udelay(1);
295 
296 		reg = in_be32(&serdes2_base->bank[i].rstctl);
297 		reg |= 0x00000080;
298 		out_be32(&serdes2_base->bank[i].rstctl, reg);
299 
300 		/* Take the Rx/Tx calibration out of reset */
301 		if (!(cfg_tmp == 0x3 && i == 1)) {
302 			udelay(1);
303 			reg = in_be32(&serdes2_base->srdstcalcr);
304 			reg |= 0x08000000;
305 			out_be32(&serdes2_base->srdstcalcr, reg);
306 			reg = in_be32(&serdes2_base->srdsrcalcr);
307 			reg |= 0x08000000;
308 			out_be32(&serdes2_base->srdsrcalcr, reg);
309 		}
310 	}
311 	udelay(1);
312 
313 #endif
314 
315 	/* Wait for at lesat 625us to ensure the PLLs being reset are locked */
316 	udelay(800);
317 
318 #ifdef CONFIG_SYS_FSL_SRDS_1
319 	cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
320 	for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
321 		/* if the PLL is not locked, set RST_ERR */
322 		reg = in_be32(&serdes1_base->bank[i].pllcr0);
323 		if (!((reg >> 23) & 0x1)) {
324 			reg = in_be32(&serdes1_base->bank[i].rstctl);
325 			reg |= 0x20000000;
326 			out_be32(&serdes1_base->bank[i].rstctl, reg);
327 		} else {
328 			udelay(1);
329 			reg = in_be32(&serdes1_base->bank[i].rstctl);
330 			reg &= 0xFFFFFFEF;
331 			reg |= 0x00000040;
332 			out_be32(&serdes1_base->bank[i].rstctl, reg);
333 			udelay(1);
334 		}
335 	}
336 #endif
337 
338 #ifdef CONFIG_SYS_FSL_SRDS_2
339 	cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
340 	for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
341 		reg = in_be32(&serdes2_base->bank[i].pllcr0);
342 		if (!((reg >> 23) & 0x1)) {
343 			reg = in_be32(&serdes2_base->bank[i].rstctl);
344 			reg |= 0x20000000;
345 			out_be32(&serdes2_base->bank[i].rstctl, reg);
346 		} else {
347 			udelay(1);
348 			reg = in_be32(&serdes2_base->bank[i].rstctl);
349 			reg &= 0xFFFFFFEF;
350 			reg |= 0x00000040;
351 			out_be32(&serdes2_base->bank[i].rstctl, reg);
352 			udelay(1);
353 		}
354 	}
355 #endif
356 
357 	/* Take the all enabled lanes out of reset */
358 #ifdef CONFIG_SYS_FSL_SRDS_1
359 	cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
360 	cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
361 
362 	for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
363 		reg = in_be32(&serdes1_base->lane[i].gcr0);
364 		reg |= 0x00600000;
365 		out_be32(&serdes1_base->lane[i].gcr0, reg);
366 	}
367 #endif
368 #ifdef CONFIG_SYS_FSL_SRDS_2
369 	cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
370 	cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
371 
372 	for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
373 		reg = in_be32(&serdes2_base->lane[i].gcr0);
374 		reg |= 0x00600000;
375 		out_be32(&serdes2_base->lane[i].gcr0, reg);
376 	}
377 #endif
378 	/* For each PLL being reset, and achieved PLL lock set RST_DONE */
379 #ifdef CONFIG_SYS_FSL_SRDS_1
380 	cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
381 	for (i = 0; i < 2; i++) {
382 		reg = in_be32(&serdes1_base->bank[i].pllcr0);
383 		if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
384 			reg = in_be32(&serdes1_base->bank[i].rstctl);
385 			reg |= 0x40000000;
386 			out_be32(&serdes1_base->bank[i].rstctl, reg);
387 		}
388 	}
389 #endif
390 #ifdef CONFIG_SYS_FSL_SRDS_2
391 	cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
392 	for (i = 0; i < 2; i++) {
393 		reg = in_be32(&serdes2_base->bank[i].pllcr0);
394 		if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
395 			reg = in_be32(&serdes2_base->bank[i].rstctl);
396 			reg |= 0x40000000;
397 			out_be32(&serdes2_base->bank[i].rstctl, reg);
398 		}
399 	}
400 #endif
401 
402 	return ret;
403 }
404 
fsl_serdes_init(void)405 void fsl_serdes_init(void)
406 {
407 #ifdef CONFIG_SYS_FSL_SRDS_1
408 	serdes_init(FSL_SRDS_1,
409 		    CONFIG_SYS_FSL_SERDES_ADDR,
410 		    FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK,
411 		    FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
412 		    serdes1_prtcl_map);
413 #endif
414 #ifdef CONFIG_SYS_FSL_SRDS_2
415 	serdes_init(FSL_SRDS_2,
416 		    CONFIG_SYS_FSL_SERDES_ADDR,
417 		    FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
418 		    FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,
419 		    serdes2_prtcl_map);
420 #endif
421 }
422