1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2015 Freescale Semiconductor, Inc.
8 #include <linux/errno.h>
9 #include <asm/arch/fsl_serdes.h>
10 #include <asm/arch/soc.h>
12 #ifdef CONFIG_SYS_FSL_SRDS_1
13 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
15 #ifdef CONFIG_SYS_FSL_SRDS_2
16 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
19 int is_serdes_configured(enum srds_prtcl device)
23 #ifdef CONFIG_SYS_FSL_SRDS_1
24 if (!serdes1_prtcl_map[NONE])
27 ret |= serdes1_prtcl_map[device];
29 #ifdef CONFIG_SYS_FSL_SRDS_2
30 if (!serdes2_prtcl_map[NONE])
33 ret |= serdes2_prtcl_map[device];
39 int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
41 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
42 u32 cfg = gur_in32(&gur->rcwsr[4]);
46 #ifdef CONFIG_SYS_FSL_SRDS_1
48 cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
49 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
52 #ifdef CONFIG_SYS_FSL_SRDS_2
54 cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
55 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
59 printf("invalid SerDes%d\n", sd);
63 /* Is serdes enabled at all? */
64 if (unlikely(cfg == 0))
67 for (i = 0; i < SRDS_MAX_LANES; i++) {
68 if (serdes_get_prtcl(sd, cfg, i) == device)
75 int get_serdes_protocol(void)
77 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
78 u32 cfg = gur_in32(&gur->rcwsr[4]) &
79 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
80 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
85 const char *serdes_clock_to_string(u32 clock)
88 case SRDS_PLLCR0_RFCK_SEL_100:
90 case SRDS_PLLCR0_RFCK_SEL_125:
92 case SRDS_PLLCR0_RFCK_SEL_156_25:
99 void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
100 u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
102 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
106 if (serdes_prtcl_map[NONE])
109 memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
111 cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask;
112 cfg >>= sd_prctl_shift;
113 printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
115 if (!is_serdes_prtcl_valid(sd, cfg))
116 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
118 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
119 enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
121 if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
122 debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
124 serdes_prtcl_map[lane_prtcl] = 1;
127 /* Set the first element to indicate serdes has been initialized */
128 serdes_prtcl_map[NONE] = 1;
131 __weak int get_serdes_volt(void)
136 __weak int set_serdes_volt(int svdd)
141 int setup_serdes_volt(u32 svdd)
143 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
144 struct ccsr_serdes *serdes1_base;
145 #ifdef CONFIG_SYS_FSL_SRDS_2
146 struct ccsr_serdes *serdes2_base;
148 u32 cfg_rcw4 = gur_in32(&gur->rcwsr[4]);
149 u32 cfg_rcw5 = gur_in32(&gur->rcwsr[5]);
150 u32 cfg_tmp, reg = 0;
151 int svdd_cur, svdd_tar;
155 /* Only support switch SVDD to 900mV/1000mV */
156 if (svdd != 900 && svdd != 1000)
160 svdd_cur = get_serdes_volt();
164 debug("%s: current SVDD: %dmV; target SVDD: %dmV\n",
165 __func__, svdd_cur, svdd_tar);
166 if (svdd_cur == svdd_tar)
169 serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR;
170 #ifdef CONFIG_SYS_FSL_SRDS_2
171 serdes2_base = (void *)serdes1_base + 0x10000;
174 /* Put the all enabled lanes in reset */
175 #ifdef CONFIG_SYS_FSL_SRDS_1
176 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
177 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
179 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
180 reg = in_be32(&serdes1_base->lane[i].gcr0);
182 out_be32(&serdes1_base->lane[i].gcr0, reg);
185 #ifdef CONFIG_SYS_FSL_SRDS_2
186 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
187 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
189 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
190 reg = in_be32(&serdes2_base->lane[i].gcr0);
192 out_be32(&serdes2_base->lane[i].gcr0, reg);
196 /* Put the all enabled PLL in reset */
197 #ifdef CONFIG_SYS_FSL_SRDS_1
198 cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
199 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
200 reg = in_be32(&serdes1_base->bank[i].rstctl);
203 out_be32(&serdes1_base->bank[i].rstctl, reg);
206 reg = in_be32(&serdes1_base->bank[i].rstctl);
208 out_be32(&serdes1_base->bank[i].rstctl, reg);
213 #ifdef CONFIG_SYS_FSL_SRDS_2
214 cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
215 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
216 reg = in_be32(&serdes2_base->bank[i].rstctl);
219 out_be32(&serdes2_base->bank[i].rstctl, reg);
222 reg = in_be32(&serdes2_base->bank[i].rstctl);
224 out_be32(&serdes2_base->bank[i].rstctl, reg);
229 /* Put the Rx/Tx calibration into reset */
230 #ifdef CONFIG_SYS_FSL_SRDS_1
231 reg = in_be32(&serdes1_base->srdstcalcr);
233 out_be32(&serdes1_base->srdstcalcr, reg);
234 reg = in_be32(&serdes1_base->srdsrcalcr);
236 out_be32(&serdes1_base->srdsrcalcr, reg);
239 #ifdef CONFIG_SYS_FSL_SRDS_2
240 reg = in_be32(&serdes2_base->srdstcalcr);
242 out_be32(&serdes2_base->srdstcalcr, reg);
243 reg = in_be32(&serdes2_base->srdsrcalcr);
245 out_be32(&serdes2_base->srdsrcalcr, reg);
249 * If SVDD set failed, will not return directly, so that the
250 * serdes lanes can complete reseting.
252 ret = set_serdes_volt(svdd_tar);
254 printf("%s: Failed to set SVDD\n", __func__);
256 /* Wait for SVDD to stabilize */
259 /* For each PLL that’s not disabled via RCW */
260 #ifdef CONFIG_SYS_FSL_SRDS_1
261 cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
262 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
263 reg = in_be32(&serdes1_base->bank[i].rstctl);
265 out_be32(&serdes1_base->bank[i].rstctl, reg);
268 reg = in_be32(&serdes1_base->bank[i].rstctl);
270 out_be32(&serdes1_base->bank[i].rstctl, reg);
272 /* Take the Rx/Tx calibration out of reset */
273 if (!(cfg_tmp == 0x3 && i == 1)) {
275 reg = in_be32(&serdes1_base->srdstcalcr);
277 out_be32(&serdes1_base->srdstcalcr, reg);
278 reg = in_be32(&serdes1_base->srdsrcalcr);
280 out_be32(&serdes1_base->srdsrcalcr, reg);
286 #ifdef CONFIG_SYS_FSL_SRDS_2
287 cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
288 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
289 reg = in_be32(&serdes2_base->bank[i].rstctl);
291 out_be32(&serdes2_base->bank[i].rstctl, reg);
294 reg = in_be32(&serdes2_base->bank[i].rstctl);
296 out_be32(&serdes2_base->bank[i].rstctl, reg);
298 /* Take the Rx/Tx calibration out of reset */
299 if (!(cfg_tmp == 0x3 && i == 1)) {
301 reg = in_be32(&serdes2_base->srdstcalcr);
303 out_be32(&serdes2_base->srdstcalcr, reg);
304 reg = in_be32(&serdes2_base->srdsrcalcr);
306 out_be32(&serdes2_base->srdsrcalcr, reg);
313 /* Wait for at lesat 625us to ensure the PLLs being reset are locked */
316 #ifdef CONFIG_SYS_FSL_SRDS_1
317 cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
318 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
319 /* if the PLL is not locked, set RST_ERR */
320 reg = in_be32(&serdes1_base->bank[i].pllcr0);
321 if (!((reg >> 23) & 0x1)) {
322 reg = in_be32(&serdes1_base->bank[i].rstctl);
324 out_be32(&serdes1_base->bank[i].rstctl, reg);
327 reg = in_be32(&serdes1_base->bank[i].rstctl);
330 out_be32(&serdes1_base->bank[i].rstctl, reg);
336 #ifdef CONFIG_SYS_FSL_SRDS_2
337 cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
338 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
339 reg = in_be32(&serdes2_base->bank[i].pllcr0);
340 if (!((reg >> 23) & 0x1)) {
341 reg = in_be32(&serdes2_base->bank[i].rstctl);
343 out_be32(&serdes2_base->bank[i].rstctl, reg);
346 reg = in_be32(&serdes2_base->bank[i].rstctl);
349 out_be32(&serdes2_base->bank[i].rstctl, reg);
355 /* Take the all enabled lanes out of reset */
356 #ifdef CONFIG_SYS_FSL_SRDS_1
357 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
358 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
360 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
361 reg = in_be32(&serdes1_base->lane[i].gcr0);
363 out_be32(&serdes1_base->lane[i].gcr0, reg);
366 #ifdef CONFIG_SYS_FSL_SRDS_2
367 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
368 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
370 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
371 reg = in_be32(&serdes2_base->lane[i].gcr0);
373 out_be32(&serdes2_base->lane[i].gcr0, reg);
376 /* For each PLL being reset, and achieved PLL lock set RST_DONE */
377 #ifdef CONFIG_SYS_FSL_SRDS_1
378 cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
379 for (i = 0; i < 2; i++) {
380 reg = in_be32(&serdes1_base->bank[i].pllcr0);
381 if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
382 reg = in_be32(&serdes1_base->bank[i].rstctl);
384 out_be32(&serdes1_base->bank[i].rstctl, reg);
388 #ifdef CONFIG_SYS_FSL_SRDS_2
389 cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
390 for (i = 0; i < 2; i++) {
391 reg = in_be32(&serdes2_base->bank[i].pllcr0);
392 if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
393 reg = in_be32(&serdes2_base->bank[i].rstctl);
395 out_be32(&serdes2_base->bank[i].rstctl, reg);
403 void fsl_serdes_init(void)
405 #ifdef CONFIG_SYS_FSL_SRDS_1
406 serdes_init(FSL_SRDS_1,
407 CONFIG_SYS_FSL_SERDES_ADDR,
408 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK,
409 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
412 #ifdef CONFIG_SYS_FSL_SRDS_2
413 serdes_init(FSL_SRDS_2,
414 CONFIG_SYS_FSL_SERDES_ADDR,
415 FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
416 FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,