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