1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2015 Freescale Semiconductor, Inc.
9 #include <linux/delay.h>
10 #include <linux/errno.h>
11 #include <asm/arch/fsl_serdes.h>
12 #include <asm/arch/soc.h>
14 #ifdef CONFIG_SYS_FSL_SRDS_1
15 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
17 #ifdef CONFIG_SYS_FSL_SRDS_2
18 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
21 int is_serdes_configured(enum srds_prtcl device)
25 #ifdef CONFIG_SYS_FSL_SRDS_1
26 if (!serdes1_prtcl_map[NONE])
29 ret |= serdes1_prtcl_map[device];
31 #ifdef CONFIG_SYS_FSL_SRDS_2
32 if (!serdes2_prtcl_map[NONE])
35 ret |= serdes2_prtcl_map[device];
41 int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
43 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
44 u32 cfg = gur_in32(&gur->rcwsr[4]);
48 #ifdef CONFIG_SYS_FSL_SRDS_1
50 cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
51 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
54 #ifdef CONFIG_SYS_FSL_SRDS_2
56 cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
57 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
61 printf("invalid SerDes%d\n", sd);
65 /* Is serdes enabled at all? */
66 if (unlikely(cfg == 0))
69 for (i = 0; i < SRDS_MAX_LANES; i++) {
70 if (serdes_get_prtcl(sd, cfg, i) == device)
77 int get_serdes_protocol(void)
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;
87 const char *serdes_clock_to_string(u32 clock)
90 case SRDS_PLLCR0_RFCK_SEL_100:
92 case SRDS_PLLCR0_RFCK_SEL_125:
94 case SRDS_PLLCR0_RFCK_SEL_156_25:
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])
104 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
108 if (serdes_prtcl_map[NONE])
111 memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
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);
117 if (!is_serdes_prtcl_valid(sd, cfg))
118 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
120 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
121 enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
123 if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
124 debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
126 serdes_prtcl_map[lane_prtcl] = 1;
129 /* Set the first element to indicate serdes has been initialized */
130 serdes_prtcl_map[NONE] = 1;
133 __weak int get_serdes_volt(void)
138 __weak int set_serdes_volt(int svdd)
143 int setup_serdes_volt(u32 svdd)
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;
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;
157 /* Only support switch SVDD to 900mV/1000mV */
158 if (svdd != 900 && svdd != 1000)
162 svdd_cur = get_serdes_volt();
166 debug("%s: current SVDD: %dmV; target SVDD: %dmV\n",
167 __func__, svdd_cur, svdd_tar);
168 if (svdd_cur == svdd_tar)
171 serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR;
172 #ifdef CONFIG_SYS_FSL_SRDS_2
173 serdes2_base = (void *)serdes1_base + 0x10000;
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;
181 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
182 reg = in_be32(&serdes1_base->lane[i].gcr0);
184 out_be32(&serdes1_base->lane[i].gcr0, reg);
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;
191 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
192 reg = in_be32(&serdes2_base->lane[i].gcr0);
194 out_be32(&serdes2_base->lane[i].gcr0, reg);
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);
205 out_be32(&serdes1_base->bank[i].rstctl, reg);
208 reg = in_be32(&serdes1_base->bank[i].rstctl);
210 out_be32(&serdes1_base->bank[i].rstctl, reg);
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);
221 out_be32(&serdes2_base->bank[i].rstctl, reg);
224 reg = in_be32(&serdes2_base->bank[i].rstctl);
226 out_be32(&serdes2_base->bank[i].rstctl, reg);
231 /* Put the Rx/Tx calibration into reset */
232 #ifdef CONFIG_SYS_FSL_SRDS_1
233 reg = in_be32(&serdes1_base->srdstcalcr);
235 out_be32(&serdes1_base->srdstcalcr, reg);
236 reg = in_be32(&serdes1_base->srdsrcalcr);
238 out_be32(&serdes1_base->srdsrcalcr, reg);
241 #ifdef CONFIG_SYS_FSL_SRDS_2
242 reg = in_be32(&serdes2_base->srdstcalcr);
244 out_be32(&serdes2_base->srdstcalcr, reg);
245 reg = in_be32(&serdes2_base->srdsrcalcr);
247 out_be32(&serdes2_base->srdsrcalcr, reg);
251 * If SVDD set failed, will not return directly, so that the
252 * serdes lanes can complete reseting.
254 ret = set_serdes_volt(svdd_tar);
256 printf("%s: Failed to set SVDD\n", __func__);
258 /* Wait for SVDD to stabilize */
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);
267 out_be32(&serdes1_base->bank[i].rstctl, reg);
270 reg = in_be32(&serdes1_base->bank[i].rstctl);
272 out_be32(&serdes1_base->bank[i].rstctl, reg);
274 /* Take the Rx/Tx calibration out of reset */
275 if (!(cfg_tmp == 0x3 && i == 1)) {
277 reg = in_be32(&serdes1_base->srdstcalcr);
279 out_be32(&serdes1_base->srdstcalcr, reg);
280 reg = in_be32(&serdes1_base->srdsrcalcr);
282 out_be32(&serdes1_base->srdsrcalcr, reg);
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);
293 out_be32(&serdes2_base->bank[i].rstctl, reg);
296 reg = in_be32(&serdes2_base->bank[i].rstctl);
298 out_be32(&serdes2_base->bank[i].rstctl, reg);
300 /* Take the Rx/Tx calibration out of reset */
301 if (!(cfg_tmp == 0x3 && i == 1)) {
303 reg = in_be32(&serdes2_base->srdstcalcr);
305 out_be32(&serdes2_base->srdstcalcr, reg);
306 reg = in_be32(&serdes2_base->srdsrcalcr);
308 out_be32(&serdes2_base->srdsrcalcr, reg);
315 /* Wait for at lesat 625us to ensure the PLLs being reset are locked */
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);
326 out_be32(&serdes1_base->bank[i].rstctl, reg);
329 reg = in_be32(&serdes1_base->bank[i].rstctl);
332 out_be32(&serdes1_base->bank[i].rstctl, reg);
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);
345 out_be32(&serdes2_base->bank[i].rstctl, reg);
348 reg = in_be32(&serdes2_base->bank[i].rstctl);
351 out_be32(&serdes2_base->bank[i].rstctl, reg);
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;
362 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
363 reg = in_be32(&serdes1_base->lane[i].gcr0);
365 out_be32(&serdes1_base->lane[i].gcr0, reg);
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;
372 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
373 reg = in_be32(&serdes2_base->lane[i].gcr0);
375 out_be32(&serdes2_base->lane[i].gcr0, reg);
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);
386 out_be32(&serdes1_base->bank[i].rstctl, reg);
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);
397 out_be32(&serdes2_base->bank[i].rstctl, reg);
405 void fsl_serdes_init(void)
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,
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,