Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / powerpc / cpu / mpc8xxx / srio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2011 Freescale Semiconductor, Inc.
4  */
5
6 #include <common.h>
7 #include <config.h>
8 #include <log.h>
9 #include <time.h>
10 #include <asm/fsl_law.h>
11 #include <asm/fsl_serdes.h>
12 #include <asm/fsl_srio.h>
13 #include <linux/delay.h>
14 #include <linux/errno.h>
15
16 #ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
17 #define SRIO_PORT_ACCEPT_ALL 0x10000001
18 #define SRIO_IB_ATMU_AR 0x80f55000
19 #define SRIO_OB_ATMU_AR_MAINT 0x80077000
20 #define SRIO_OB_ATMU_AR_RW 0x80045000
21 #define SRIO_LCSBA1CSR_OFFSET 0x5c
22 #define SRIO_MAINT_WIN_SIZE 0x1000000 /* 16M */
23 #define SRIO_RW_WIN_SIZE 0x100000 /* 1M */
24 #define SRIO_LCSBA1CSR 0x60000000
25 #endif
26
27 #if defined(CONFIG_FSL_CORENET)
28 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
29         #define _DEVDISR_SRIO1 FSL_CORENET_DEVDISR3_SRIO1
30         #define _DEVDISR_SRIO2 FSL_CORENET_DEVDISR3_SRIO2
31 #else
32         #define _DEVDISR_SRIO1 FSL_CORENET_DEVDISR_SRIO1
33         #define _DEVDISR_SRIO2 FSL_CORENET_DEVDISR_SRIO2
34 #endif
35         #define _DEVDISR_RMU   FSL_CORENET_DEVDISR_RMU
36         #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
37 #elif defined(CONFIG_MPC85xx)
38         #define _DEVDISR_SRIO1 MPC85xx_DEVDISR_SRIO
39         #define _DEVDISR_SRIO2 MPC85xx_DEVDISR_SRIO
40         #define _DEVDISR_RMU   MPC85xx_DEVDISR_RMSG
41         #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
42 #elif defined(CONFIG_MPC86xx)
43         #define _DEVDISR_SRIO1 MPC86xx_DEVDISR_SRIO
44         #define _DEVDISR_SRIO2 MPC86xx_DEVDISR_SRIO
45         #define _DEVDISR_RMU   MPC86xx_DEVDISR_RMSG
46         #define CONFIG_SYS_MPC8xxx_GUTS_ADDR \
47                 (&((immap_t *)CONFIG_SYS_IMMR)->im_gur)
48 #else
49 #error "No defines for DEVDISR_SRIO"
50 #endif
51
52 #ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
53 /*
54  * Erratum A-004034
55  * Affects: SRIO
56  * Description: During port initialization, the SRIO port performs
57  * lane synchronization (detecting valid symbols on a lane) and
58  * lane alignment (coordinating multiple lanes to receive valid data
59  * across lanes). Internal errors in lane synchronization and lane
60  * alignment may cause failure to achieve link initialization at
61  * the configured port width.
62  * An SRIO port configured as a 4x port may see one of these scenarios:
63  * 1. One or more lanes fails to achieve lane synchronization. Depending
64  * on which lanes fail, this may result in downtraining from 4x to 1x
65  * on lane 0, 4x to 1x on lane R (redundant lane).
66  * 2. The link may fail to achieve lane alignment as a 4x, even though
67  * all 4 lanes achieve lane synchronization, and downtrain to a 1x.
68  * An SRIO port configured as a 1x port may fail to complete port
69  * initialization (PnESCSR[PU] never deasserts) because of scenario 1.
70  * Impact: SRIO port may downtrain to 1x, or may fail to complete
71  * link initialization. Once a port completes link initialization
72  * successfully, it will operate normally.
73  */
74 static int srio_erratum_a004034(u8 port)
75 {
76         serdes_corenet_t *srds_regs;
77         u32 conf_lane;
78         u32 init_lane;
79         int idx, first, last;
80         u32 i;
81         unsigned long long end_tick;
82         struct ccsr_rio *srio_regs = (void *)CONFIG_SYS_FSL_SRIO_ADDR;
83
84         srds_regs = (void *)(CONFIG_SYS_FSL_CORENET_SERDES_ADDR);
85         conf_lane = (in_be32((void *)&srds_regs->srdspccr0)
86                         >> (12 - port * 4)) & 0x3;
87         init_lane = (in_be32((void *)&srio_regs->lp_serial
88                         .port[port].pccsr) >> 27) & 0x7;
89
90         /*
91          * Start a counter set to ~2 ms after the SERDES reset is
92          * complete (SERDES SRDSBnRSTCTL[RST_DONE]=1 for n
93          * corresponding to the SERDES bank/PLL for the SRIO port).
94          */
95          if (in_be32((void *)&srds_regs->bank[0].rstctl)
96                 & SRDS_RSTCTL_RSTDONE) {
97                 /*
98                  * Poll the port uninitialized status (SRIO PnESCSR[PO]) until
99                  * PO=1 or the counter expires. If the counter expires, the
100                  * port has failed initialization: go to recover steps. If PO=1
101                  * and the desired port width is 1x, go to normal steps. If
102                  * PO = 1 and the desired port width is 4x, go to recover steps.
103                  */
104                 end_tick = usec2ticks(2000) + get_ticks();
105                 do {
106                         if (in_be32((void *)&srio_regs->lp_serial
107                                 .port[port].pescsr) & 0x2) {
108                                 if (conf_lane == 0x1)
109                                         goto host_ok;
110                                 else {
111                                         if (init_lane == 0x2)
112                                                 goto host_ok;
113                                         else
114                                                 break;
115                                 }
116                         }
117                 } while (end_tick > get_ticks());
118
119                 /* recover at most 3 times */
120                 for (i = 0; i < 3; i++) {
121                         /* Set SRIO PnCCSR[PD]=1 */
122                         setbits_be32((void *)&srio_regs->lp_serial
123                                         .port[port].pccsr,
124                                         0x800000);
125                         /*
126                         * Set SRIO PnPCR[OBDEN] on the host to
127                         * enable the discarding of any pending packets.
128                         */
129                         setbits_be32((void *)&srio_regs->impl.port[port].pcr,
130                                 0x04);
131                         /* Wait 50 us */
132                         udelay(50);
133                         /* Run sync command */
134                         isync();
135
136                         if (port)
137                                 first = serdes_get_first_lane(SRIO2);
138                         else
139                                 first = serdes_get_first_lane(SRIO1);
140                         if (unlikely(first < 0))
141                                 return -ENODEV;
142                         if (conf_lane == 0x1)
143                                 last = first;
144                         else
145                                 last = first + 3;
146                         /*
147                          * Set SERDES BnGCRm0[RRST]=0 for each SRIO
148                          * bank n and lane m.
149                          */
150                         for (idx = first; idx <= last; idx++)
151                                 clrbits_be32(&srds_regs->lane[idx].gcr0,
152                                 SRDS_GCR0_RRST);
153                         /*
154                          * Read SERDES BnGCRm0 for each SRIO
155                          * bank n and lane m
156                          */
157                         for (idx = first; idx <= last; idx++)
158                                 in_be32(&srds_regs->lane[idx].gcr0);
159                         /* Run sync command */
160                         isync();
161                         /* Wait >= 100 ns */
162                         udelay(1);
163                         /*
164                          * Set SERDES BnGCRm0[RRST]=1 for each SRIO
165                          * bank n and lane m.
166                          */
167                         for (idx = first; idx <= last; idx++)
168                                 setbits_be32(&srds_regs->lane[idx].gcr0,
169                                 SRDS_GCR0_RRST);
170                         /*
171                          * Read SERDES BnGCRm0 for each SRIO
172                          * bank n and lane m
173                          */
174                         for (idx = first; idx <= last; idx++)
175                                 in_be32(&srds_regs->lane[idx].gcr0);
176                         /* Run sync command */
177                         isync();
178                         /* Wait >= 300 ns */
179                         udelay(1);
180
181                         /* Write 1 to clear all bits in SRIO PnSLCSR */
182                         out_be32((void *)&srio_regs->impl.port[port].slcsr,
183                                 0xffffffff);
184                         /* Clear SRIO PnPCR[OBDEN] on the host */
185                         clrbits_be32((void *)&srio_regs->impl.port[port].pcr,
186                                 0x04);
187                         /* Set SRIO PnCCSR[PD]=0 */
188                         clrbits_be32((void *)&srio_regs->lp_serial
189                                 .port[port].pccsr,
190                                 0x800000);
191                         /* Wait >= 24 ms */
192                         udelay(24000);
193                         /* Poll the state of the port again */
194                         init_lane =
195                                 (in_be32((void *)&srio_regs->lp_serial
196                                         .port[port].pccsr) >> 27) & 0x7;
197                         if (in_be32((void *)&srio_regs->lp_serial
198                                 .port[port].pescsr) & 0x2) {
199                                 if (conf_lane == 0x1)
200                                         goto host_ok;
201                                 else {
202                                         if (init_lane == 0x2)
203                                                 goto host_ok;
204                                 }
205                         }
206                         if (i == 2)
207                                 return -ENODEV;
208                 }
209         } else
210                 return -ENODEV;
211
212 host_ok:
213         /* Poll PnESCSR[OES] on the host until it is clear */
214         end_tick = usec2ticks(1000000) + get_ticks();
215         do {
216                 if (!(in_be32((void *)&srio_regs->lp_serial.port[port].pescsr)
217                         & 0x10000)) {
218                         out_be32(((void *)&srio_regs->lp_serial
219                                 .port[port].pescsr), 0xffffffff);
220                         out_be32(((void *)&srio_regs->phys_err
221                                 .port[port].edcsr), 0);
222                         out_be32(((void *)&srio_regs->logical_err.ltledcsr), 0);
223                         return 0;
224                 }
225         } while (end_tick > get_ticks());
226
227         return -ENODEV;
228 }
229 #endif
230
231 void srio_init(void)
232 {
233         ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC8xxx_GUTS_ADDR;
234         int srio1_used = 0, srio2_used = 0;
235         u32 *devdisr;
236
237 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
238         devdisr = &gur->devdisr3;
239 #else
240         devdisr = &gur->devdisr;
241 #endif
242         if (is_serdes_configured(SRIO1)) {
243                 set_next_law(CONFIG_SYS_SRIO1_MEM_PHYS,
244                                 law_size_bits(CONFIG_SYS_SRIO1_MEM_SIZE),
245                                 LAW_TRGT_IF_RIO_1);
246                 srio1_used = 1;
247 #ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
248                 if (srio_erratum_a004034(0) < 0)
249                         printf("SRIO1: enabled but port error\n");
250                 else
251 #endif
252                 printf("SRIO1: enabled\n");
253         } else {
254                 printf("SRIO1: disabled\n");
255         }
256
257 #ifdef CONFIG_SRIO2
258         if (is_serdes_configured(SRIO2)) {
259                 set_next_law(CONFIG_SYS_SRIO2_MEM_PHYS,
260                                 law_size_bits(CONFIG_SYS_SRIO2_MEM_SIZE),
261                                 LAW_TRGT_IF_RIO_2);
262                 srio2_used = 1;
263 #ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
264                 if (srio_erratum_a004034(1) < 0)
265                         printf("SRIO2: enabled but port error\n");
266                 else
267 #endif
268                 printf("SRIO2: enabled\n");
269
270         } else {
271                 printf("SRIO2: disabled\n");
272         }
273 #endif
274
275 #ifdef CONFIG_FSL_CORENET
276         /* On FSL_CORENET devices we can disable individual ports */
277         if (!srio1_used)
278                 setbits_be32(devdisr, _DEVDISR_SRIO1);
279         if (!srio2_used)
280                 setbits_be32(devdisr, _DEVDISR_SRIO2);
281 #endif
282
283         /* neither port is used - disable everything */
284         if (!srio1_used && !srio2_used) {
285                 setbits_be32(devdisr, _DEVDISR_SRIO1);
286                 setbits_be32(devdisr, _DEVDISR_SRIO2);
287                 setbits_be32(devdisr, _DEVDISR_RMU);
288         }
289 }
290
291 #ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
292 void srio_boot_master(int port)
293 {
294         struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR;
295
296         /* set port accept-all */
297         out_be32((void *)&srio->impl.port[port - 1].ptaacr,
298                                 SRIO_PORT_ACCEPT_ALL);
299
300         debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", port);
301         /* configure inbound window for slave's u-boot image */
302         debug("SRIOBOOT - MASTER: Inbound window for slave's image; "
303                         "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
304                         (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
305                         (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1,
306                         CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
307         out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar,
308                         CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12);
309         out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar,
310                         CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 >> 12);
311         out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar,
312                         SRIO_IB_ATMU_AR
313                         | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE));
314
315         /* configure inbound window for slave's u-boot image */
316         debug("SRIOBOOT - MASTER: Inbound window for slave's image; "
317                         "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
318                         (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS,
319                         (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2,
320                         CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE);
321         out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar,
322                         CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12);
323         out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar,
324                         CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 >> 12);
325         out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar,
326                         SRIO_IB_ATMU_AR
327                         | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE));
328
329         /* configure inbound window for slave's ucode and ENV */
330         debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; "
331                         "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n",
332                         (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS,
333                         (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS,
334                         CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE);
335         out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar,
336                         CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS >> 12);
337         out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar,
338                         CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS >> 12);
339         out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar,
340                         SRIO_IB_ATMU_AR
341                         | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE));
342 }
343
344 void srio_boot_master_release_slave(int port)
345 {
346         struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR;
347         u32 escsr;
348         debug("SRIOBOOT - MASTER: "
349                         "Check the port status and release slave core ...\n");
350
351         escsr = in_be32((void *)&srio->lp_serial.port[port - 1].pescsr);
352         if (escsr & 0x2) {
353                 if (escsr & 0x10100) {
354                         debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n",
355                                 port);
356                 } else {
357                         debug("SRIOBOOT - MASTER: "
358                                 "Port [ %d ] is ready, now release slave's core ...\n",
359                                 port);
360                         /*
361                          * configure outbound window
362                          * with maintenance attribute to set slave's LCSBA1CSR
363                          */
364                         out_be32((void *)&srio->atmu.port[port - 1]
365                                 .outbw[1].rowtar, 0);
366                         out_be32((void *)&srio->atmu.port[port - 1]
367                                 .outbw[1].rowtear, 0);
368                         if (port - 1)
369                                 out_be32((void *)&srio->atmu.port[port - 1]
370                                         .outbw[1].rowbar,
371                                         CONFIG_SYS_SRIO2_MEM_PHYS >> 12);
372                         else
373                                 out_be32((void *)&srio->atmu.port[port - 1]
374                                         .outbw[1].rowbar,
375                                         CONFIG_SYS_SRIO1_MEM_PHYS >> 12);
376                         out_be32((void *)&srio->atmu.port[port - 1]
377                                         .outbw[1].rowar,
378                                         SRIO_OB_ATMU_AR_MAINT
379                                         | atmu_size_mask(SRIO_MAINT_WIN_SIZE));
380
381                         /*
382                          * configure outbound window
383                          * with R/W attribute to set slave's BRR
384                          */
385                         out_be32((void *)&srio->atmu.port[port - 1]
386                                 .outbw[2].rowtar,
387                                 SRIO_LCSBA1CSR >> 9);
388                         out_be32((void *)&srio->atmu.port[port - 1]
389                                 .outbw[2].rowtear, 0);
390                         if (port - 1)
391                                 out_be32((void *)&srio->atmu.port[port - 1]
392                                         .outbw[2].rowbar,
393                                         (CONFIG_SYS_SRIO2_MEM_PHYS
394                                         + SRIO_MAINT_WIN_SIZE) >> 12);
395                         else
396                                 out_be32((void *)&srio->atmu.port[port - 1]
397                                         .outbw[2].rowbar,
398                                         (CONFIG_SYS_SRIO1_MEM_PHYS
399                                         + SRIO_MAINT_WIN_SIZE) >> 12);
400                         out_be32((void *)&srio->atmu.port[port - 1]
401                                 .outbw[2].rowar,
402                                 SRIO_OB_ATMU_AR_RW
403                                 | atmu_size_mask(SRIO_RW_WIN_SIZE));
404
405                         /*
406                          * Set the LCSBA1CSR register in slave
407                          * by the maint-outbound window
408                          */
409                         if (port - 1) {
410                                 out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
411                                         + SRIO_LCSBA1CSR_OFFSET,
412                                         SRIO_LCSBA1CSR);
413                                 while (in_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
414                                         + SRIO_LCSBA1CSR_OFFSET)
415                                         != SRIO_LCSBA1CSR)
416                                         ;
417                                 /*
418                                  * And then set the BRR register
419                                  * to release slave core
420                                  */
421                                 out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT
422                                         + SRIO_MAINT_WIN_SIZE
423                                         + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET,
424                                         CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK);
425                         } else {
426                                 out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
427                                         + SRIO_LCSBA1CSR_OFFSET,
428                                         SRIO_LCSBA1CSR);
429                                 while (in_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
430                                         + SRIO_LCSBA1CSR_OFFSET)
431                                         != SRIO_LCSBA1CSR)
432                                         ;
433                                 /*
434                                  * And then set the BRR register
435                                  * to release slave core
436                                  */
437                                 out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT
438                                         + SRIO_MAINT_WIN_SIZE
439                                         + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET,
440                                         CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK);
441                         }
442                         debug("SRIOBOOT - MASTER: "
443                                         "Release slave successfully! Now the slave should start up!\n");
444                 }
445         } else
446                 debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", port);
447 }
448 #endif