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