]> git.ipfire.org Git - thirdparty/u-boot.git/blob - arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
SPDX: Convert all of our single license tags to Linux Kernel style
[thirdparty/u-boot.git] / arch / powerpc / cpu / mpc85xx / fsl_corenet2_serdes.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright 2012 Freescale Semiconductor, Inc.
4 */
5
6 #include <common.h>
7 #include <asm/fsl_serdes.h>
8 #include <asm/immap_85xx.h>
9 #include <asm/io.h>
10 #include <asm/processor.h>
11 #include <asm/fsl_law.h>
12 #include <linux/errno.h>
13 #include <fsl_errata.h>
14 #include "fsl_corenet2_serdes.h"
15
16 #ifdef CONFIG_SYS_FSL_SRDS_1
17 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
18 #endif
19 #ifdef CONFIG_SYS_FSL_SRDS_2
20 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
21 #endif
22 #ifdef CONFIG_SYS_FSL_SRDS_3
23 static u8 serdes3_prtcl_map[SERDES_PRCTL_COUNT];
24 #endif
25 #ifdef CONFIG_SYS_FSL_SRDS_4
26 static u8 serdes4_prtcl_map[SERDES_PRCTL_COUNT];
27 #endif
28
29 #ifdef DEBUG
30 static const char *serdes_prtcl_str[] = {
31 [NONE] = "NA",
32 [PCIE1] = "PCIE1",
33 [PCIE2] = "PCIE2",
34 [PCIE3] = "PCIE3",
35 [PCIE4] = "PCIE4",
36 [SATA1] = "SATA1",
37 [SATA2] = "SATA2",
38 [SRIO1] = "SRIO1",
39 [SRIO2] = "SRIO2",
40 [SGMII_FM1_DTSEC1] = "SGMII_FM1_DTSEC1",
41 [SGMII_FM1_DTSEC2] = "SGMII_FM1_DTSEC2",
42 [SGMII_FM1_DTSEC3] = "SGMII_FM1_DTSEC3",
43 [SGMII_FM1_DTSEC4] = "SGMII_FM1_DTSEC4",
44 [SGMII_FM1_DTSEC5] = "SGMII_FM1_DTSEC5",
45 [SGMII_FM1_DTSEC6] = "SGMII_FM1_DTSEC6",
46 [SGMII_FM2_DTSEC1] = "SGMII_FM2_DTSEC1",
47 [SGMII_FM2_DTSEC2] = "SGMII_FM2_DTSEC2",
48 [SGMII_FM2_DTSEC3] = "SGMII_FM2_DTSEC3",
49 [SGMII_FM2_DTSEC4] = "SGMII_FM2_DTSEC4",
50 [XAUI_FM1] = "XAUI_FM1",
51 [XAUI_FM2] = "XAUI_FM2",
52 [AURORA] = "DEBUG",
53 [CPRI1] = "CPRI1",
54 [CPRI2] = "CPRI2",
55 [CPRI3] = "CPRI3",
56 [CPRI4] = "CPRI4",
57 [CPRI5] = "CPRI5",
58 [CPRI6] = "CPRI6",
59 [CPRI7] = "CPRI7",
60 [CPRI8] = "CPRI8",
61 [XAUI_FM1_MAC9] = "XAUI_FM1_MAC9",
62 [XAUI_FM1_MAC10] = "XAUI_FM1_MAC10",
63 [XAUI_FM2_MAC9] = "XAUI_FM2_MAC9",
64 [XAUI_FM2_MAC10] = "XAUI_FM2_MAC10",
65 [HIGIG_FM1_MAC9] = "HiGig_FM1_MAC9",
66 [HIGIG_FM1_MAC10] = "HiGig_FM1_MAC10",
67 [HIGIG_FM2_MAC9] = "HiGig_FM2_MAC9",
68 [HIGIG_FM2_MAC10] = "HiGig_FM2_MAC10",
69 [QSGMII_FM1_A] = "QSGMII_FM1_A",
70 [QSGMII_FM1_B] = "QSGMII_FM1_B",
71 [QSGMII_FM2_A] = "QSGMII_FM2_A",
72 [QSGMII_FM2_B] = "QSGMII_FM2_B",
73 [XFI_FM1_MAC9] = "XFI_FM1_MAC9",
74 [XFI_FM1_MAC10] = "XFI_FM1_MAC10",
75 [XFI_FM2_MAC9] = "XFI_FM2_MAC9",
76 [XFI_FM2_MAC10] = "XFI_FM2_MAC10",
77 [INTERLAKEN] = "INTERLAKEN",
78 [QSGMII_SW1_A] = "QSGMII_SW1_A",
79 [QSGMII_SW1_B] = "QSGMII_SW1_B",
80 [SGMII_SW1_MAC1] = "SGMII_SW1_MAC1",
81 [SGMII_SW1_MAC2] = "SGMII_SW1_MAC2",
82 [SGMII_SW1_MAC3] = "SGMII_SW1_MAC3",
83 [SGMII_SW1_MAC4] = "SGMII_SW1_MAC4",
84 [SGMII_SW1_MAC5] = "SGMII_SW1_MAC5",
85 [SGMII_SW1_MAC6] = "SGMII_SW1_MAC6",
86 };
87 #endif
88
89 int is_serdes_configured(enum srds_prtcl device)
90 {
91 int ret = 0;
92
93 #ifdef CONFIG_SYS_FSL_SRDS_1
94 if (!serdes1_prtcl_map[NONE])
95 fsl_serdes_init();
96
97 ret |= serdes1_prtcl_map[device];
98 #endif
99 #ifdef CONFIG_SYS_FSL_SRDS_2
100 if (!serdes2_prtcl_map[NONE])
101 fsl_serdes_init();
102
103 ret |= serdes2_prtcl_map[device];
104 #endif
105 #ifdef CONFIG_SYS_FSL_SRDS_3
106 if (!serdes3_prtcl_map[NONE])
107 fsl_serdes_init();
108
109 ret |= serdes3_prtcl_map[device];
110 #endif
111 #ifdef CONFIG_SYS_FSL_SRDS_4
112 if (!serdes4_prtcl_map[NONE])
113 fsl_serdes_init();
114
115 ret |= serdes4_prtcl_map[device];
116 #endif
117
118 return !!ret;
119 }
120
121 int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
122 {
123 const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
124 u32 cfg = in_be32(&gur->rcwsr[4]);
125 int i;
126
127 switch (sd) {
128 #ifdef CONFIG_SYS_FSL_SRDS_1
129 case FSL_SRDS_1:
130 cfg &= FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
131 cfg >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
132 break;
133 #endif
134 #ifdef CONFIG_SYS_FSL_SRDS_2
135 case FSL_SRDS_2:
136 cfg &= FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
137 cfg >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
138 break;
139 #endif
140 #ifdef CONFIG_SYS_FSL_SRDS_3
141 case FSL_SRDS_3:
142 cfg &= FSL_CORENET2_RCWSR4_SRDS3_PRTCL;
143 cfg >>= FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT;
144 break;
145 #endif
146 #ifdef CONFIG_SYS_FSL_SRDS_4
147 case FSL_SRDS_4:
148 cfg &= FSL_CORENET2_RCWSR4_SRDS4_PRTCL;
149 cfg >>= FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT;
150 break;
151 #endif
152 default:
153 printf("invalid SerDes%d\n", sd);
154 break;
155 }
156 /* Is serdes enabled at all? */
157 if (unlikely(cfg == 0))
158 return -ENODEV;
159
160 for (i = 0; i < SRDS_MAX_LANES; i++) {
161 if (serdes_get_prtcl(sd, cfg, i) == device)
162 return i;
163 }
164
165 return -ENODEV;
166 }
167
168 #define BC3_SHIFT 9
169 #define DC3_SHIFT 6
170 #define FC3_SHIFT 0
171 #define BC2_SHIFT 19
172 #define DC2_SHIFT 16
173 #define FC2_SHIFT 10
174 #define BC1_SHIFT 29
175 #define DC1_SHIFT 26
176 #define FC1_SHIFT 20
177 #define BC_MASK 0x1
178 #define DC_MASK 0x7
179 #define FC_MASK 0x3F
180
181 #define FUSE_VAL_MASK 0x00000003
182 #define FUSE_VAL_SHIFT 30
183 #define CR0_DCBIAS_SHIFT 5
184 #define CR1_FCAP_SHIFT 15
185 #define CR1_BCAP_SHIFT 29
186 #define FCAP_MASK 0x001F8000
187 #define BCAP_MASK 0x20000000
188 #define BCAP_OVD_MASK 0x10000000
189 #define BYP_CAL_MASK 0x02000000
190
191 void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
192 u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
193 {
194 ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
195 u32 cfg;
196 int lane;
197
198 if (serdes_prtcl_map[NONE])
199 return;
200
201 memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
202 #ifdef CONFIG_SYS_FSL_ERRATUM_A007186
203 struct ccsr_sfp_regs __iomem *sfp_regs =
204 (struct ccsr_sfp_regs __iomem *)(CONFIG_SYS_SFP_ADDR);
205 u32 pll_num, pll_status, bc, dc, fc, pll_cr_upd, pll_cr0, pll_cr1;
206 u32 bc_status, fc_status, dc_status, pll_sr2;
207 serdes_corenet_t __iomem *srds_regs = (void *)sd_addr;
208 u32 sfp_spfr0, sel;
209 #endif
210
211 cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask;
212
213 /* Erratum A-007186
214 * Freescale Scratch Pad Fuse Register n (SFP_FSPFR0)
215 * The workaround requires factory pre-set SerDes calibration values to be
216 * read from a fuse block(Freescale Scratch Pad Fuse Register SFP_FSPFR0)
217 * These values have been shown to work across the
218 * entire temperature range for all SerDes. These values are then written into
219 * the SerDes registers to calibrate the SerDes PLL.
220 *
221 * This workaround for the protocols and rates that only have the Ring VCO.
222 */
223 #ifdef CONFIG_SYS_FSL_ERRATUM_A007186
224 sfp_spfr0 = in_be32(&sfp_regs->fsl_spfr0);
225 debug("A007186: sfp_spfr0= %x\n", sfp_spfr0);
226
227 sel = (sfp_spfr0 >> FUSE_VAL_SHIFT) & FUSE_VAL_MASK;
228
229 if (has_erratum_a007186() && (sel == 0x01 || sel == 0x02)) {
230 for (pll_num = 0; pll_num < SRDS_MAX_BANK; pll_num++) {
231 pll_status = in_be32(&srds_regs->bank[pll_num].pllcr0);
232 debug("A007186: pll_num=%x pllcr0=%x\n",
233 pll_num, pll_status);
234 /* STEP 1 */
235 /* Read factory pre-set SerDes calibration values
236 * from fuse block(SFP scratch register-sfp_spfr0)
237 */
238 switch (pll_status & SRDS_PLLCR0_FRATE_SEL_MASK) {
239 case SRDS_PLLCR0_FRATE_SEL_3_0:
240 case SRDS_PLLCR0_FRATE_SEL_3_072:
241 debug("A007186: 3.0/3.072 protocol rate\n");
242 bc = (sfp_spfr0 >> BC1_SHIFT) & BC_MASK;
243 dc = (sfp_spfr0 >> DC1_SHIFT) & DC_MASK;
244 fc = (sfp_spfr0 >> FC1_SHIFT) & FC_MASK;
245 break;
246 case SRDS_PLLCR0_FRATE_SEL_3_125:
247 debug("A007186: 3.125 protocol rate\n");
248 bc = (sfp_spfr0 >> BC2_SHIFT) & BC_MASK;
249 dc = (sfp_spfr0 >> DC2_SHIFT) & DC_MASK;
250 fc = (sfp_spfr0 >> FC2_SHIFT) & FC_MASK;
251 break;
252 case SRDS_PLLCR0_FRATE_SEL_3_75:
253 debug("A007186: 3.75 protocol rate\n");
254 bc = (sfp_spfr0 >> BC1_SHIFT) & BC_MASK;
255 dc = (sfp_spfr0 >> DC1_SHIFT) & DC_MASK;
256 fc = (sfp_spfr0 >> FC1_SHIFT) & FC_MASK;
257 break;
258 default:
259 continue;
260 }
261
262 /* STEP 2 */
263 /* Write SRDSxPLLnCR1[11:16] = FC
264 * Write SRDSxPLLnCR1[2] = BC
265 */
266 pll_cr1 = in_be32(&srds_regs->bank[pll_num].pllcr1);
267 pll_cr_upd = (((bc << CR1_BCAP_SHIFT) & BCAP_MASK) |
268 ((fc << CR1_FCAP_SHIFT) & FCAP_MASK));
269 out_be32(&srds_regs->bank[pll_num].pllcr1,
270 (pll_cr_upd | pll_cr1));
271 debug("A007186: pll_num=%x Updated PLLCR1=%x\n",
272 pll_num, (pll_cr_upd | pll_cr1));
273 /* Write SRDSxPLLnCR0[24:26] = DC
274 */
275 pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
276 out_be32(&srds_regs->bank[pll_num].pllcr0,
277 pll_cr0 | (dc << CR0_DCBIAS_SHIFT));
278 debug("A007186: pll_num=%x, Updated PLLCR0=%x\n",
279 pll_num, (pll_cr0 | (dc << CR0_DCBIAS_SHIFT)));
280 /* Write SRDSxPLLnCR1[3] = 1
281 * Write SRDSxPLLnCR1[6] = 1
282 */
283 pll_cr1 = in_be32(&srds_regs->bank[pll_num].pllcr1);
284 pll_cr_upd = (BCAP_OVD_MASK | BYP_CAL_MASK);
285 out_be32(&srds_regs->bank[pll_num].pllcr1,
286 (pll_cr_upd | pll_cr1));
287 debug("A007186: pll_num=%x Updated PLLCR1=%x\n",
288 pll_num, (pll_cr_upd | pll_cr1));
289
290 /* STEP 3 */
291 /* Read the status Registers */
292 /* Verify SRDSxPLLnSR2[8] = BC */
293 pll_sr2 = in_be32(&srds_regs->bank[pll_num].pllsr2);
294 debug("A007186: pll_num=%x pllsr2=%x\n",
295 pll_num, pll_sr2);
296 bc_status = (pll_sr2 >> 23) & BC_MASK;
297 if (bc_status != bc)
298 debug("BC mismatch\n");
299 fc_status = (pll_sr2 >> 16) & FC_MASK;
300 if (fc_status != fc)
301 debug("FC mismatch\n");
302 pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
303 out_be32(&srds_regs->bank[pll_num].pllcr0, pll_cr0 |
304 0x02000000);
305 pll_sr2 = in_be32(&srds_regs->bank[pll_num].pllsr2);
306 dc_status = (pll_sr2 >> 17) & DC_MASK;
307 if (dc_status != dc)
308 debug("DC mismatch\n");
309 pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
310 out_be32(&srds_regs->bank[pll_num].pllcr0, pll_cr0 &
311 0xfdffffff);
312
313 /* STEP 4 */
314 /* Wait 750us to verify the PLL is locked
315 * by checking SRDSxPLLnCR0[8] = 1.
316 */
317 udelay(750);
318 pll_status = in_be32(&srds_regs->bank[pll_num].pllcr0);
319 debug("A007186: pll_num=%x pllcr0=%x\n",
320 pll_num, pll_status);
321
322 if ((pll_status & SRDS_PLLCR0_PLL_LCK) == 0)
323 printf("A007186 Serdes PLL not locked\n");
324 else
325 debug("A007186 Serdes PLL locked\n");
326 }
327 }
328 #endif
329
330 cfg >>= sd_prctl_shift;
331 printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
332 if (!is_serdes_prtcl_valid(sd, cfg))
333 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
334
335 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
336 enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
337 if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
338 debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
339 else
340 serdes_prtcl_map[lane_prtcl] = 1;
341 }
342
343 /* Set the first element to indicate serdes has been initialized */
344 serdes_prtcl_map[NONE] = 1;
345 }
346
347 void fsl_serdes_init(void)
348 {
349
350 #ifdef CONFIG_SYS_FSL_SRDS_1
351 serdes_init(FSL_SRDS_1,
352 CONFIG_SYS_FSL_CORENET_SERDES_ADDR,
353 FSL_CORENET2_RCWSR4_SRDS1_PRTCL,
354 FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT,
355 serdes1_prtcl_map);
356 #endif
357 #ifdef CONFIG_SYS_FSL_SRDS_2
358 serdes_init(FSL_SRDS_2,
359 CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_2 * 0x1000,
360 FSL_CORENET2_RCWSR4_SRDS2_PRTCL,
361 FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT,
362 serdes2_prtcl_map);
363 #endif
364 #ifdef CONFIG_SYS_FSL_SRDS_3
365 serdes_init(FSL_SRDS_3,
366 CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_3 * 0x1000,
367 FSL_CORENET2_RCWSR4_SRDS3_PRTCL,
368 FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT,
369 serdes3_prtcl_map);
370 #endif
371 #ifdef CONFIG_SYS_FSL_SRDS_4
372 serdes_init(FSL_SRDS_4,
373 CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_4 * 0x1000,
374 FSL_CORENET2_RCWSR4_SRDS4_PRTCL,
375 FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT,
376 serdes4_prtcl_map);
377 #endif
378
379 }
380
381 const char *serdes_clock_to_string(u32 clock)
382 {
383 switch (clock) {
384 case SRDS_PLLCR0_RFCK_SEL_100:
385 return "100";
386 case SRDS_PLLCR0_RFCK_SEL_125:
387 return "125";
388 case SRDS_PLLCR0_RFCK_SEL_156_25:
389 return "156.25";
390 case SRDS_PLLCR0_RFCK_SEL_161_13:
391 return "161.1328123";
392 default:
393 #if defined(CONFIG_TARGET_T4240QDS) || defined(CONFIG_TARGET_T4160QDS)
394 return "???";
395 #else
396 return "122.88";
397 #endif
398 }
399 }
400