2 * Copyright 2015 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <linux/errno.h>
10 #include <asm/arch/fsl_serdes.h>
11 #include <asm/arch/soc.h>
13 #ifdef CONFIG_SYS_FSL_SRDS_1
14 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
16 #ifdef CONFIG_SYS_FSL_SRDS_2
17 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
20 int is_serdes_configured(enum srds_prtcl device)
24 #ifdef CONFIG_SYS_FSL_SRDS_1
25 if (!serdes1_prtcl_map[NONE])
28 ret |= serdes1_prtcl_map[device];
30 #ifdef CONFIG_SYS_FSL_SRDS_2
31 if (!serdes2_prtcl_map[NONE])
34 ret |= serdes2_prtcl_map[device];
40 int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
42 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
43 u32 cfg = gur_in32(&gur->rcwsr[4]);
47 #ifdef CONFIG_SYS_FSL_SRDS_1
49 cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
50 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
53 #ifdef CONFIG_SYS_FSL_SRDS_2
55 cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
56 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
60 printf("invalid SerDes%d\n", sd);
64 /* Is serdes enabled at all? */
65 if (unlikely(cfg == 0))
68 for (i = 0; i < SRDS_MAX_LANES; i++) {
69 if (serdes_get_prtcl(sd, cfg, i) == device)
76 int get_serdes_protocol(void)
78 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
79 u32 cfg = gur_in32(&gur->rcwsr[4]) &
80 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
81 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
86 const char *serdes_clock_to_string(u32 clock)
89 case SRDS_PLLCR0_RFCK_SEL_100:
91 case SRDS_PLLCR0_RFCK_SEL_125:
93 case SRDS_PLLCR0_RFCK_SEL_156_25:
100 void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
101 u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
103 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
107 if (serdes_prtcl_map[NONE])
110 memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
112 cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask;
113 cfg >>= sd_prctl_shift;
114 printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
116 if (!is_serdes_prtcl_valid(sd, cfg))
117 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
119 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
120 enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
122 if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
123 debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
125 serdes_prtcl_map[lane_prtcl] = 1;
128 /* Set the first element to indicate serdes has been initialized */
129 serdes_prtcl_map[NONE] = 1;
132 __weak int get_serdes_volt(void)
137 __weak int set_serdes_volt(int svdd)
142 int setup_serdes_volt(u32 svdd)
144 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
145 struct ccsr_serdes *serdes1_base;
146 #ifdef CONFIG_SYS_FSL_SRDS_2
147 struct ccsr_serdes *serdes2_base;
149 u32 cfg_rcw4 = gur_in32(&gur->rcwsr[4]);
150 u32 cfg_rcw5 = gur_in32(&gur->rcwsr[5]);
151 u32 cfg_tmp, reg = 0;
152 int svdd_cur, svdd_tar;
156 /* Only support switch SVDD to 900mV/1000mV */
157 if (svdd != 900 && svdd != 1000)
161 svdd_cur = get_serdes_volt();
165 debug("%s: current SVDD: %dmV; target SVDD: %dmV\n",
166 __func__, svdd_cur, svdd_tar);
167 if (svdd_cur == svdd_tar)
170 serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR;
171 #ifdef CONFIG_SYS_FSL_SRDS_2
172 serdes2_base = (void *)serdes1_base + 0x10000;
175 /* Put the all enabled lanes in reset */
176 #ifdef CONFIG_SYS_FSL_SRDS_1
177 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
178 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
180 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
181 reg = in_be32(&serdes1_base->lane[i].gcr0);
183 out_be32(&serdes1_base->lane[i].gcr0, reg);
186 #ifdef CONFIG_SYS_FSL_SRDS_2
187 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
188 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
190 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
191 reg = in_be32(&serdes2_base->lane[i].gcr0);
193 out_be32(&serdes2_base->lane[i].gcr0, reg);
197 /* Put the all enabled PLL in reset */
198 #ifdef CONFIG_SYS_FSL_SRDS_1
199 cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
200 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
201 reg = in_be32(&serdes1_base->bank[i].rstctl);
204 out_be32(&serdes1_base->bank[i].rstctl, reg);
207 reg = in_be32(&serdes1_base->bank[i].rstctl);
209 out_be32(&serdes1_base->bank[i].rstctl, reg);
214 #ifdef CONFIG_SYS_FSL_SRDS_2
215 cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
216 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
217 reg = in_be32(&serdes2_base->bank[i].rstctl);
220 out_be32(&serdes2_base->bank[i].rstctl, reg);
223 reg = in_be32(&serdes2_base->bank[i].rstctl);
225 out_be32(&serdes2_base->bank[i].rstctl, reg);
230 /* Put the Rx/Tx calibration into reset */
231 #ifdef CONFIG_SYS_FSL_SRDS_1
232 reg = in_be32(&serdes1_base->srdstcalcr);
234 out_be32(&serdes1_base->srdstcalcr, reg);
235 reg = in_be32(&serdes1_base->srdsrcalcr);
237 out_be32(&serdes1_base->srdsrcalcr, reg);
240 #ifdef CONFIG_SYS_FSL_SRDS_2
241 reg = in_be32(&serdes2_base->srdstcalcr);
243 out_be32(&serdes2_base->srdstcalcr, reg);
244 reg = in_be32(&serdes2_base->srdsrcalcr);
246 out_be32(&serdes2_base->srdsrcalcr, reg);
250 * If SVDD set failed, will not return directly, so that the
251 * serdes lanes can complete reseting.
253 ret = set_serdes_volt(svdd_tar);
255 printf("%s: Failed to set SVDD\n", __func__);
257 /* Wait for SVDD to stabilize */
260 /* For each PLL that’s not disabled via RCW */
261 #ifdef CONFIG_SYS_FSL_SRDS_1
262 cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
263 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
264 reg = in_be32(&serdes1_base->bank[i].rstctl);
266 out_be32(&serdes1_base->bank[i].rstctl, reg);
269 reg = in_be32(&serdes1_base->bank[i].rstctl);
271 out_be32(&serdes1_base->bank[i].rstctl, reg);
273 /* Take the Rx/Tx calibration out of reset */
274 if (!(cfg_tmp == 0x3 && i == 1)) {
276 reg = in_be32(&serdes1_base->srdstcalcr);
278 out_be32(&serdes1_base->srdstcalcr, reg);
279 reg = in_be32(&serdes1_base->srdsrcalcr);
281 out_be32(&serdes1_base->srdsrcalcr, reg);
287 #ifdef CONFIG_SYS_FSL_SRDS_2
288 cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
289 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
290 reg = in_be32(&serdes2_base->bank[i].rstctl);
292 out_be32(&serdes2_base->bank[i].rstctl, reg);
295 reg = in_be32(&serdes2_base->bank[i].rstctl);
297 out_be32(&serdes2_base->bank[i].rstctl, reg);
299 /* Take the Rx/Tx calibration out of reset */
300 if (!(cfg_tmp == 0x3 && i == 1)) {
302 reg = in_be32(&serdes2_base->srdstcalcr);
304 out_be32(&serdes2_base->srdstcalcr, reg);
305 reg = in_be32(&serdes2_base->srdsrcalcr);
307 out_be32(&serdes2_base->srdsrcalcr, reg);
314 /* Wait for at lesat 625us to ensure the PLLs being reset are locked */
317 #ifdef CONFIG_SYS_FSL_SRDS_1
318 cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
319 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
320 /* if the PLL is not locked, set RST_ERR */
321 reg = in_be32(&serdes1_base->bank[i].pllcr0);
322 if (!((reg >> 23) & 0x1)) {
323 reg = in_be32(&serdes1_base->bank[i].rstctl);
325 out_be32(&serdes1_base->bank[i].rstctl, reg);
328 reg = in_be32(&serdes1_base->bank[i].rstctl);
331 out_be32(&serdes1_base->bank[i].rstctl, reg);
337 #ifdef CONFIG_SYS_FSL_SRDS_2
338 cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
339 for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
340 reg = in_be32(&serdes2_base->bank[i].pllcr0);
341 if (!((reg >> 23) & 0x1)) {
342 reg = in_be32(&serdes2_base->bank[i].rstctl);
344 out_be32(&serdes2_base->bank[i].rstctl, reg);
347 reg = in_be32(&serdes2_base->bank[i].rstctl);
350 out_be32(&serdes2_base->bank[i].rstctl, reg);
356 /* Take the all enabled lanes out of reset */
357 #ifdef CONFIG_SYS_FSL_SRDS_1
358 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
359 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
361 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
362 reg = in_be32(&serdes1_base->lane[i].gcr0);
364 out_be32(&serdes1_base->lane[i].gcr0, reg);
367 #ifdef CONFIG_SYS_FSL_SRDS_2
368 cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
369 cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
371 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
372 reg = in_be32(&serdes2_base->lane[i].gcr0);
374 out_be32(&serdes2_base->lane[i].gcr0, reg);
377 /* For each PLL being reset, and achieved PLL lock set RST_DONE */
378 #ifdef CONFIG_SYS_FSL_SRDS_1
379 cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
380 for (i = 0; i < 2; i++) {
381 reg = in_be32(&serdes1_base->bank[i].pllcr0);
382 if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
383 reg = in_be32(&serdes1_base->bank[i].rstctl);
385 out_be32(&serdes1_base->bank[i].rstctl, reg);
389 #ifdef CONFIG_SYS_FSL_SRDS_2
390 cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
391 for (i = 0; i < 2; i++) {
392 reg = in_be32(&serdes2_base->bank[i].pllcr0);
393 if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
394 reg = in_be32(&serdes2_base->bank[i].rstctl);
396 out_be32(&serdes2_base->bank[i].rstctl, reg);
404 void fsl_serdes_init(void)
406 #ifdef CONFIG_SYS_FSL_SRDS_1
407 serdes_init(FSL_SRDS_1,
408 CONFIG_SYS_FSL_SERDES_ADDR,
409 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK,
410 FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
413 #ifdef CONFIG_SYS_FSL_SRDS_2
414 serdes_init(FSL_SRDS_2,
415 CONFIG_SYS_FSL_SERDES_ADDR,
416 FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
417 FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,