xref: /openbmc/u-boot/arch/powerpc/cpu/mpc8xxx/srio.c (revision e8f80a5a)
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  */
srio_erratum_a004034(u8 port)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 
srio_init(void)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
srio_boot_master(int port)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 
srio_boot_master_release_slave(int port)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
446