f24ca7f1dc72c937fb163639400f0a14fb007d1e
[oweals/u-boot.git] / arch / arm / cpu / armv8 / fsl-layerscape / fsl_lsch2_serdes.c
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/errno.h>
10 #include <asm/arch/fsl_serdes.h>
11 #include <asm/arch/soc.h>
12
13 #ifdef CONFIG_SYS_FSL_SRDS_1
14 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
15 #endif
16 #ifdef CONFIG_SYS_FSL_SRDS_2
17 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
18 #endif
19
20 int is_serdes_configured(enum srds_prtcl device)
21 {
22         int ret = 0;
23
24 #ifdef CONFIG_SYS_FSL_SRDS_1
25         if (!serdes1_prtcl_map[NONE])
26                 fsl_serdes_init();
27
28         ret |= serdes1_prtcl_map[device];
29 #endif
30 #ifdef CONFIG_SYS_FSL_SRDS_2
31         if (!serdes2_prtcl_map[NONE])
32                 fsl_serdes_init();
33
34         ret |= serdes2_prtcl_map[device];
35 #endif
36
37         return !!ret;
38 }
39
40 int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
41 {
42         struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
43         u32 cfg = gur_in32(&gur->rcwsr[4]);
44         int i;
45
46         switch (sd) {
47 #ifdef CONFIG_SYS_FSL_SRDS_1
48         case FSL_SRDS_1:
49                 cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
50                 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
51                 break;
52 #endif
53 #ifdef CONFIG_SYS_FSL_SRDS_2
54         case FSL_SRDS_2:
55                 cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
56                 cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
57                 break;
58 #endif
59         default:
60                 printf("invalid SerDes%d\n", sd);
61                 break;
62         }
63
64         /* Is serdes enabled at all? */
65         if (unlikely(cfg == 0))
66                 return -ENODEV;
67
68         for (i = 0; i < SRDS_MAX_LANES; i++) {
69                 if (serdes_get_prtcl(sd, cfg, i) == device)
70                         return i;
71         }
72
73         return -ENODEV;
74 }
75
76 int get_serdes_protocol(void)
77 {
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;
82
83         return cfg;
84 }
85
86 const char *serdes_clock_to_string(u32 clock)
87 {
88         switch (clock) {
89         case SRDS_PLLCR0_RFCK_SEL_100:
90                 return "100";
91         case SRDS_PLLCR0_RFCK_SEL_125:
92                 return "125";
93         case SRDS_PLLCR0_RFCK_SEL_156_25:
94                 return "156.25";
95         default:
96                 return "100";
97         }
98 }
99
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])
102 {
103         struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
104         u32 cfg;
105         int lane;
106
107         if (serdes_prtcl_map[NONE])
108                 return;
109
110         memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
111
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);
115
116         if (!is_serdes_prtcl_valid(sd, cfg))
117                 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
118
119         for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
120                 enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
121
122                 if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
123                         debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
124                 else
125                         serdes_prtcl_map[lane_prtcl] = 1;
126         }
127
128         /* Set the first element to indicate serdes has been initialized */
129         serdes_prtcl_map[NONE] = 1;
130 }
131
132 __weak int get_serdes_volt(void)
133 {
134         return -1;
135 }
136
137 __weak int set_serdes_volt(int svdd)
138 {
139         return -1;
140 }
141
142 int setup_serdes_volt(u32 svdd)
143 {
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;
148 #endif
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;
153         int ret;
154         int i;
155
156         /* Only support switch SVDD to 900mV/1000mV */
157         if (svdd != 900 && svdd != 1000)
158                 return -EINVAL;
159
160         svdd_tar = svdd;
161         svdd_cur = get_serdes_volt();
162         if (svdd_cur < 0)
163                 return -EINVAL;
164
165         debug("%s: current SVDD: %dmV; target SVDD: %dmV\n",
166               __func__, svdd_cur, svdd_tar);
167         if (svdd_cur == svdd_tar)
168                 return 0;
169
170         serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR;
171 #ifdef CONFIG_SYS_FSL_SRDS_2
172         serdes2_base = (void *)serdes1_base + 0x10000;
173 #endif
174
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;
179
180         for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
181                 reg = in_be32(&serdes1_base->lane[i].gcr0);
182                 reg &= 0xFF9FFFFF;
183                 out_be32(&serdes1_base->lane[i].gcr0, reg);
184         }
185 #endif
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;
189
190         for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
191                 reg = in_be32(&serdes2_base->lane[i].gcr0);
192                 reg &= 0xFF9FFFFF;
193                 out_be32(&serdes2_base->lane[i].gcr0, reg);
194         }
195 #endif
196
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);
202                 reg &= 0xFFFFFFBF;
203                 reg |= 0x10000000;
204                 out_be32(&serdes1_base->bank[i].rstctl, reg);
205                 udelay(1);
206
207                 reg = in_be32(&serdes1_base->bank[i].rstctl);
208                 reg &= 0xFFFFFF1F;
209                 out_be32(&serdes1_base->bank[i].rstctl, reg);
210         }
211         udelay(1);
212 #endif
213
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);
218                 reg &= 0xFFFFFFBF;
219                 reg |= 0x10000000;
220                 out_be32(&serdes2_base->bank[i].rstctl, reg);
221                 udelay(1);
222
223                 reg = in_be32(&serdes2_base->bank[i].rstctl);
224                 reg &= 0xFFFFFF1F;
225                 out_be32(&serdes2_base->bank[i].rstctl, reg);
226         }
227         udelay(1);
228 #endif
229
230         /* Put the Rx/Tx calibration into reset */
231 #ifdef CONFIG_SYS_FSL_SRDS_1
232         reg = in_be32(&serdes1_base->srdstcalcr);
233         reg &= 0xF7FFFFFF;
234         out_be32(&serdes1_base->srdstcalcr, reg);
235         reg = in_be32(&serdes1_base->srdsrcalcr);
236         reg &= 0xF7FFFFFF;
237         out_be32(&serdes1_base->srdsrcalcr, reg);
238
239 #endif
240 #ifdef CONFIG_SYS_FSL_SRDS_2
241         reg = in_be32(&serdes2_base->srdstcalcr);
242         reg &= 0xF7FFFFFF;
243         out_be32(&serdes2_base->srdstcalcr, reg);
244         reg = in_be32(&serdes2_base->srdsrcalcr);
245         reg &= 0xF7FFFFFF;
246         out_be32(&serdes2_base->srdsrcalcr, reg);
247 #endif
248
249         /*
250          * If SVDD set failed, will not return directly, so that the
251          * serdes lanes can complete reseting.
252          */
253         ret = set_serdes_volt(svdd_tar);
254         if (ret)
255                 printf("%s: Failed to set SVDD\n", __func__);
256
257         /* Wait for SVDD to stabilize */
258         udelay(100);
259
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);
265                 reg |= 0x00000020;
266                 out_be32(&serdes1_base->bank[i].rstctl, reg);
267                 udelay(1);
268
269                 reg = in_be32(&serdes1_base->bank[i].rstctl);
270                 reg |= 0x00000080;
271                 out_be32(&serdes1_base->bank[i].rstctl, reg);
272
273                 /* Take the Rx/Tx calibration out of reset */
274                 if (!(cfg_tmp == 0x3 && i == 1)) {
275                         udelay(1);
276                         reg = in_be32(&serdes1_base->srdstcalcr);
277                         reg |= 0x08000000;
278                         out_be32(&serdes1_base->srdstcalcr, reg);
279                         reg = in_be32(&serdes1_base->srdsrcalcr);
280                         reg |= 0x08000000;
281                         out_be32(&serdes1_base->srdsrcalcr, reg);
282                 }
283         }
284         udelay(1);
285 #endif
286
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);
291                 reg |= 0x00000020;
292                 out_be32(&serdes2_base->bank[i].rstctl, reg);
293                 udelay(1);
294
295                 reg = in_be32(&serdes2_base->bank[i].rstctl);
296                 reg |= 0x00000080;
297                 out_be32(&serdes2_base->bank[i].rstctl, reg);
298
299                 /* Take the Rx/Tx calibration out of reset */
300                 if (!(cfg_tmp == 0x3 && i == 1)) {
301                         udelay(1);
302                         reg = in_be32(&serdes2_base->srdstcalcr);
303                         reg |= 0x08000000;
304                         out_be32(&serdes2_base->srdstcalcr, reg);
305                         reg = in_be32(&serdes2_base->srdsrcalcr);
306                         reg |= 0x08000000;
307                         out_be32(&serdes2_base->srdsrcalcr, reg);
308                 }
309         }
310         udelay(1);
311
312 #endif
313
314         /* Wait for at lesat 625us to ensure the PLLs being reset are locked */
315         udelay(800);
316
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);
324                         reg |= 0x20000000;
325                         out_be32(&serdes1_base->bank[i].rstctl, reg);
326                 } else {
327                         udelay(1);
328                         reg = in_be32(&serdes1_base->bank[i].rstctl);
329                         reg &= 0xFFFFFFEF;
330                         reg |= 0x00000040;
331                         out_be32(&serdes1_base->bank[i].rstctl, reg);
332                         udelay(1);
333                 }
334         }
335 #endif
336
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);
343                         reg |= 0x20000000;
344                         out_be32(&serdes2_base->bank[i].rstctl, reg);
345                 } else {
346                         udelay(1);
347                         reg = in_be32(&serdes2_base->bank[i].rstctl);
348                         reg &= 0xFFFFFFEF;
349                         reg |= 0x00000040;
350                         out_be32(&serdes2_base->bank[i].rstctl, reg);
351                         udelay(1);
352                 }
353         }
354 #endif
355
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;
360
361         for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
362                 reg = in_be32(&serdes1_base->lane[i].gcr0);
363                 reg |= 0x00600000;
364                 out_be32(&serdes1_base->lane[i].gcr0, reg);
365         }
366 #endif
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;
370
371         for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
372                 reg = in_be32(&serdes2_base->lane[i].gcr0);
373                 reg |= 0x00600000;
374                 out_be32(&serdes2_base->lane[i].gcr0, reg);
375         }
376 #endif
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);
384                         reg |= 0x40000000;
385                         out_be32(&serdes1_base->bank[i].rstctl, reg);
386                 }
387         }
388 #endif
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);
395                         reg |= 0x40000000;
396                         out_be32(&serdes2_base->bank[i].rstctl, reg);
397                 }
398         }
399 #endif
400
401         return ret;
402 }
403
404 void fsl_serdes_init(void)
405 {
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,
411                     serdes1_prtcl_map);
412 #endif
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,
418                     serdes2_prtcl_map);
419 #endif
420 }