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