xref: /openbmc/u-boot/drivers/qe/qe.c (revision 2399e401)
1 /*
2  * Copyright (C) 2006-2009 Freescale Semiconductor, Inc.
3  *
4  * Dave Liu <daveliu@freescale.com>
5  * based on source code of Shlomi Gridish
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <command.h>
12 #include <linux/errno.h>
13 #include <asm/io.h>
14 #include <linux/immap_qe.h>
15 #include <fsl_qe.h>
16 #ifdef CONFIG_LS102XA
17 #include <asm/arch/immap_ls102xa.h>
18 #endif
19 
20 #define MPC85xx_DEVDISR_QE_DISABLE	0x1
21 
22 qe_map_t		*qe_immr = NULL;
23 #ifdef CONFIG_QE
24 static qe_snum_t	snums[QE_NUM_OF_SNUM];
25 #endif
26 
27 DECLARE_GLOBAL_DATA_PTR;
28 
29 void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data)
30 {
31 	u32 cecr;
32 
33 	if (cmd == QE_RESET) {
34 		out_be32(&qe_immr->cp.cecr,(u32) (cmd | QE_CR_FLG));
35 	} else {
36 		out_be32(&qe_immr->cp.cecdr, cmd_data);
37 		out_be32(&qe_immr->cp.cecr, (sbc | QE_CR_FLG |
38 			 ((u32) mcn<<QE_CR_PROTOCOL_SHIFT) | cmd));
39 	}
40 	/* Wait for the QE_CR_FLG to clear */
41 	do {
42 		cecr = in_be32(&qe_immr->cp.cecr);
43 	} while (cecr & QE_CR_FLG);
44 
45 	return;
46 }
47 
48 #ifdef CONFIG_QE
49 uint qe_muram_alloc(uint size, uint align)
50 {
51 	uint	retloc;
52 	uint	align_mask, off;
53 	uint	savebase;
54 
55 	align_mask = align - 1;
56 	savebase = gd->arch.mp_alloc_base;
57 
58 	off = gd->arch.mp_alloc_base & align_mask;
59 	if (off != 0)
60 		gd->arch.mp_alloc_base += (align - off);
61 
62 	if ((off = size & align_mask) != 0)
63 		size += (align - off);
64 
65 	if ((gd->arch.mp_alloc_base + size) >= gd->arch.mp_alloc_top) {
66 		gd->arch.mp_alloc_base = savebase;
67 		printf("%s: ran out of ram.\n",  __FUNCTION__);
68 	}
69 
70 	retloc = gd->arch.mp_alloc_base;
71 	gd->arch.mp_alloc_base += size;
72 
73 	memset((void *)&qe_immr->muram[retloc], 0, size);
74 
75 	__asm__ __volatile__("sync");
76 
77 	return retloc;
78 }
79 #endif
80 
81 void *qe_muram_addr(uint offset)
82 {
83 	return (void *)&qe_immr->muram[offset];
84 }
85 
86 #ifdef CONFIG_QE
87 static void qe_sdma_init(void)
88 {
89 	volatile sdma_t	*p;
90 	uint		sdma_buffer_base;
91 
92 	p = (volatile sdma_t *)&qe_immr->sdma;
93 
94 	/* All of DMA transaction in bus 1 */
95 	out_be32(&p->sdaqr, 0);
96 	out_be32(&p->sdaqmr, 0);
97 
98 	/* Allocate 2KB temporary buffer for sdma */
99 	sdma_buffer_base = qe_muram_alloc(2048, 4096);
100 	out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK);
101 
102 	/* Clear sdma status */
103 	out_be32(&p->sdsr, 0x03000000);
104 
105 	/* Enable global mode on bus 1, and 2KB buffer size */
106 	out_be32(&p->sdmr, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT));
107 }
108 
109 /* This table is a list of the serial numbers of the Threads, taken from the
110  * "SNUM Table" chart in the QE Reference Manual. The order is not important,
111  * we just need to know what the SNUMs are for the threads.
112  */
113 static u8 thread_snum[] = {
114 /* Evthreads 16-29 are not supported in MPC8309 */
115 #if !defined(CONFIG_MPC8309)
116 	0x04, 0x05, 0x0c, 0x0d,
117 	0x14, 0x15, 0x1c, 0x1d,
118 	0x24, 0x25, 0x2c, 0x2d,
119 	0x34, 0x35,
120 #endif
121 	0x88, 0x89, 0x98, 0x99,
122 	0xa8, 0xa9, 0xb8, 0xb9,
123 	0xc8, 0xc9, 0xd8, 0xd9,
124 	0xe8, 0xe9, 0x08, 0x09,
125 	0x18, 0x19, 0x28, 0x29,
126 	0x38, 0x39, 0x48, 0x49,
127 	0x58, 0x59, 0x68, 0x69,
128 	0x78, 0x79, 0x80, 0x81
129 };
130 
131 static void qe_snums_init(void)
132 {
133 	int	i;
134 
135 	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
136 		snums[i].state = QE_SNUM_STATE_FREE;
137 		snums[i].num   = thread_snum[i];
138 	}
139 }
140 
141 int qe_get_snum(void)
142 {
143 	int	snum = -EBUSY;
144 	int	i;
145 
146 	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
147 		if (snums[i].state == QE_SNUM_STATE_FREE) {
148 			snums[i].state = QE_SNUM_STATE_USED;
149 			snum = snums[i].num;
150 			break;
151 		}
152 	}
153 
154 	return snum;
155 }
156 
157 void qe_put_snum(u8 snum)
158 {
159 	int	i;
160 
161 	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
162 		if (snums[i].num == snum) {
163 			snums[i].state = QE_SNUM_STATE_FREE;
164 			break;
165 		}
166 	}
167 }
168 
169 void qe_init(uint qe_base)
170 {
171 	/* Init the QE IMMR base */
172 	qe_immr = (qe_map_t *)qe_base;
173 
174 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
175 	/*
176 	 * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
177 	 */
178 	qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
179 
180 	/* enable the microcode in IRAM */
181 	out_be32(&qe_immr->iram.iready,QE_IRAM_READY);
182 #endif
183 
184 	gd->arch.mp_alloc_base = QE_DATAONLY_BASE;
185 	gd->arch.mp_alloc_top = gd->arch.mp_alloc_base + QE_DATAONLY_SIZE;
186 
187 	qe_sdma_init();
188 	qe_snums_init();
189 }
190 #endif
191 
192 #ifdef CONFIG_U_QE
193 void u_qe_init(void)
194 {
195 	qe_immr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET);
196 
197 	u_qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
198 	out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
199 }
200 #endif
201 
202 #ifdef CONFIG_U_QE
203 void u_qe_resume(void)
204 {
205 	qe_map_t *qe_immrr;
206 
207 	qe_immrr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET);
208 	u_qe_firmware_resume((const void *)CONFIG_SYS_QE_FW_ADDR, qe_immrr);
209 	out_be32(&qe_immrr->iram.iready, QE_IRAM_READY);
210 }
211 #endif
212 
213 void qe_reset(void)
214 {
215 	qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
216 			 (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
217 }
218 
219 #ifdef CONFIG_QE
220 void qe_assign_page(uint snum, uint para_ram_base)
221 {
222 	u32	cecr;
223 
224 	out_be32(&qe_immr->cp.cecdr, para_ram_base);
225 	out_be32(&qe_immr->cp.cecr, ((u32) snum<<QE_CR_ASSIGN_PAGE_SNUM_SHIFT)
226 					 | QE_CR_FLG | QE_ASSIGN_PAGE);
227 
228 	/* Wait for the QE_CR_FLG to clear */
229 	do {
230 		cecr = in_be32(&qe_immr->cp.cecr);
231 	} while (cecr & QE_CR_FLG );
232 
233 	return;
234 }
235 #endif
236 
237 /*
238  * brg: 0~15 as BRG1~BRG16
239    rate: baud rate
240  * BRG input clock comes from the BRGCLK (internal clock generated from
241    the QE clock, it is one-half of the QE clock), If need the clock source
242    from CLKn pin, we have te change the function.
243  */
244 
245 #define BRG_CLK		(gd->arch.brg_clk)
246 
247 #ifdef CONFIG_QE
248 int qe_set_brg(uint brg, uint rate)
249 {
250 	volatile uint	*bp;
251 	u32		divisor;
252 	int		div16 = 0;
253 
254 	if (brg >= QE_NUM_OF_BRGS)
255 		return -EINVAL;
256 	bp = (uint *)&qe_immr->brg.brgc1;
257 	bp += brg;
258 
259 	divisor = (BRG_CLK / rate);
260 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
261 		div16 = 1;
262 		divisor /= 16;
263 	}
264 
265 	*bp = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
266 	__asm__ __volatile__("sync");
267 
268 	if (div16) {
269 		*bp |= QE_BRGC_DIV16;
270 		__asm__ __volatile__("sync");
271 	}
272 
273 	return 0;
274 }
275 #endif
276 
277 /* Set ethernet MII clock master
278 */
279 int qe_set_mii_clk_src(int ucc_num)
280 {
281 	u32	cmxgcr;
282 
283 	/* check if the UCC number is in range. */
284 	if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) {
285 		printf("%s: ucc num not in ranges\n", __FUNCTION__);
286 		return -EINVAL;
287 	}
288 
289 	cmxgcr = in_be32(&qe_immr->qmx.cmxgcr);
290 	cmxgcr &= ~QE_CMXGCR_MII_ENET_MNG_MASK;
291 	cmxgcr |= (ucc_num <<QE_CMXGCR_MII_ENET_MNG_SHIFT);
292 	out_be32(&qe_immr->qmx.cmxgcr, cmxgcr);
293 
294 	return 0;
295 }
296 
297 /* Firmware information stored here for qe_get_firmware_info() */
298 static struct qe_firmware_info qe_firmware_info;
299 
300 /*
301  * Set to 1 if QE firmware has been uploaded, and therefore
302  * qe_firmware_info contains valid data.
303  */
304 static int qe_firmware_uploaded;
305 
306 /*
307  * Upload a QE microcode
308  *
309  * This function is a worker function for qe_upload_firmware().  It does
310  * the actual uploading of the microcode.
311  */
312 static void qe_upload_microcode(const void *base,
313 	const struct qe_microcode *ucode)
314 {
315 	const u32 *code = base + be32_to_cpu(ucode->code_offset);
316 	unsigned int i;
317 
318 	if (ucode->major || ucode->minor || ucode->revision)
319 		printf("QE: uploading microcode '%s' version %u.%u.%u\n",
320 		       (char *)ucode->id, (u16)ucode->major, (u16)ucode->minor,
321 		       (u16)ucode->revision);
322 	else
323 		printf("QE: uploading microcode '%s'\n", (char *)ucode->id);
324 
325 	/* Use auto-increment */
326 	out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
327 		QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
328 
329 	for (i = 0; i < be32_to_cpu(ucode->count); i++)
330 		out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
331 }
332 
333 /*
334  * Upload a microcode to the I-RAM at a specific address.
335  *
336  * See docs/README.qe_firmware for information on QE microcode uploading.
337  *
338  * Currently, only version 1 is supported, so the 'version' field must be
339  * set to 1.
340  *
341  * The SOC model and revision are not validated, they are only displayed for
342  * informational purposes.
343  *
344  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
345  * all of the microcode structures, minus the CRC.
346  *
347  * 'length' is the size that the structure says it is, including the CRC.
348  */
349 int qe_upload_firmware(const struct qe_firmware *firmware)
350 {
351 	unsigned int i;
352 	unsigned int j;
353 	u32 crc;
354 	size_t calc_size = sizeof(struct qe_firmware);
355 	size_t length;
356 	const struct qe_header *hdr;
357 #ifdef CONFIG_DEEP_SLEEP
358 #ifdef CONFIG_LS102XA
359 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
360 #else
361 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
362 #endif
363 #endif
364 	if (!firmware) {
365 		printf("Invalid address\n");
366 		return -EINVAL;
367 	}
368 
369 	hdr = &firmware->header;
370 	length = be32_to_cpu(hdr->length);
371 
372 	/* Check the magic */
373 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
374 	    (hdr->magic[2] != 'F')) {
375 		printf("QE microcode not found\n");
376 #ifdef CONFIG_DEEP_SLEEP
377 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
378 #endif
379 		return -EPERM;
380 	}
381 
382 	/* Check the version */
383 	if (hdr->version != 1) {
384 		printf("Unsupported version\n");
385 		return -EPERM;
386 	}
387 
388 	/* Validate some of the fields */
389 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
390 		printf("Invalid data\n");
391 		return -EINVAL;
392 	}
393 
394 	/* Validate the length and check if there's a CRC */
395 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
396 
397 	for (i = 0; i < firmware->count; i++)
398 		/*
399 		 * For situations where the second RISC uses the same microcode
400 		 * as the first, the 'code_offset' and 'count' fields will be
401 		 * zero, so it's okay to add those.
402 		 */
403 		calc_size += sizeof(u32) *
404 			be32_to_cpu(firmware->microcode[i].count);
405 
406 	/* Validate the length */
407 	if (length != calc_size + sizeof(u32)) {
408 		printf("Invalid length\n");
409 		return -EPERM;
410 	}
411 
412 	/*
413 	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
414 	 * function isn't available unless you turn on JFFS support.
415 	 */
416 	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
417 	if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) {
418 		printf("Firmware CRC is invalid\n");
419 		return -EIO;
420 	}
421 
422 	/*
423 	 * If the microcode calls for it, split the I-RAM.
424 	 */
425 	if (!firmware->split) {
426 		out_be16(&qe_immr->cp.cercr,
427 			in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
428 	}
429 
430 	if (firmware->soc.model)
431 		printf("Firmware '%s' for %u V%u.%u\n",
432 			firmware->id, be16_to_cpu(firmware->soc.model),
433 			firmware->soc.major, firmware->soc.minor);
434 	else
435 		printf("Firmware '%s'\n", firmware->id);
436 
437 	/*
438 	 * The QE only supports one microcode per RISC, so clear out all the
439 	 * saved microcode information and put in the new.
440 	 */
441 	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
442 	strncpy(qe_firmware_info.id, (char *)firmware->id, 62);
443 	qe_firmware_info.extended_modes = firmware->extended_modes;
444 	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
445 		sizeof(firmware->vtraps));
446 	qe_firmware_uploaded = 1;
447 
448 	/* Loop through each microcode. */
449 	for (i = 0; i < firmware->count; i++) {
450 		const struct qe_microcode *ucode = &firmware->microcode[i];
451 
452 		/* Upload a microcode if it's present */
453 		if (ucode->code_offset)
454 			qe_upload_microcode(firmware, ucode);
455 
456 		/* Program the traps for this processor */
457 		for (j = 0; j < 16; j++) {
458 			u32 trap = be32_to_cpu(ucode->traps[j]);
459 
460 			if (trap)
461 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
462 		}
463 
464 		/* Enable traps */
465 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
466 	}
467 
468 	return 0;
469 }
470 
471 #ifdef CONFIG_U_QE
472 /*
473  * Upload a microcode to the I-RAM at a specific address.
474  *
475  * See docs/README.qe_firmware for information on QE microcode uploading.
476  *
477  * Currently, only version 1 is supported, so the 'version' field must be
478  * set to 1.
479  *
480  * The SOC model and revision are not validated, they are only displayed for
481  * informational purposes.
482  *
483  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
484  * all of the microcode structures, minus the CRC.
485  *
486  * 'length' is the size that the structure says it is, including the CRC.
487  */
488 int u_qe_upload_firmware(const struct qe_firmware *firmware)
489 {
490 	unsigned int i;
491 	unsigned int j;
492 	u32 crc;
493 	size_t calc_size = sizeof(struct qe_firmware);
494 	size_t length;
495 	const struct qe_header *hdr;
496 #ifdef CONFIG_DEEP_SLEEP
497 #ifdef CONFIG_LS102XA
498 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
499 #else
500 	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
501 #endif
502 #endif
503 	if (!firmware) {
504 		printf("Invalid address\n");
505 		return -EINVAL;
506 	}
507 
508 	hdr = &firmware->header;
509 	length = be32_to_cpu(hdr->length);
510 
511 	/* Check the magic */
512 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
513 	    (hdr->magic[2] != 'F')) {
514 		printf("Not a microcode\n");
515 #ifdef CONFIG_DEEP_SLEEP
516 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
517 #endif
518 		return -EPERM;
519 	}
520 
521 	/* Check the version */
522 	if (hdr->version != 1) {
523 		printf("Unsupported version\n");
524 		return -EPERM;
525 	}
526 
527 	/* Validate some of the fields */
528 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
529 		printf("Invalid data\n");
530 		return -EINVAL;
531 	}
532 
533 	/* Validate the length and check if there's a CRC */
534 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
535 
536 	for (i = 0; i < firmware->count; i++)
537 		/*
538 		 * For situations where the second RISC uses the same microcode
539 		 * as the first, the 'code_offset' and 'count' fields will be
540 		 * zero, so it's okay to add those.
541 		 */
542 		calc_size += sizeof(u32) *
543 			be32_to_cpu(firmware->microcode[i].count);
544 
545 	/* Validate the length */
546 	if (length != calc_size + sizeof(u32)) {
547 		printf("Invalid length\n");
548 		return -EPERM;
549 	}
550 
551 	/*
552 	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
553 	 * function isn't available unless you turn on JFFS support.
554 	 */
555 	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
556 	if (crc != (crc32(-1, (const void *)firmware, calc_size) ^ -1)) {
557 		printf("Firmware CRC is invalid\n");
558 		return -EIO;
559 	}
560 
561 	/*
562 	 * If the microcode calls for it, split the I-RAM.
563 	 */
564 	if (!firmware->split) {
565 		out_be16(&qe_immr->cp.cercr,
566 			 in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
567 	}
568 
569 	if (firmware->soc.model)
570 		printf("Firmware '%s' for %u V%u.%u\n",
571 		       firmware->id, be16_to_cpu(firmware->soc.model),
572 		       firmware->soc.major, firmware->soc.minor);
573 	else
574 		printf("Firmware '%s'\n", firmware->id);
575 
576 	/* Loop through each microcode. */
577 	for (i = 0; i < firmware->count; i++) {
578 		const struct qe_microcode *ucode = &firmware->microcode[i];
579 
580 		/* Upload a microcode if it's present */
581 		if (ucode->code_offset)
582 			qe_upload_microcode(firmware, ucode);
583 
584 		/* Program the traps for this processor */
585 		for (j = 0; j < 16; j++) {
586 			u32 trap = be32_to_cpu(ucode->traps[j]);
587 
588 			if (trap)
589 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
590 		}
591 
592 		/* Enable traps */
593 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
594 	}
595 
596 	return 0;
597 }
598 #endif
599 
600 #ifdef CONFIG_U_QE
601 int u_qe_firmware_resume(const struct qe_firmware *firmware, qe_map_t *qe_immrr)
602 {
603 	unsigned int i;
604 	unsigned int j;
605 	const struct qe_header *hdr;
606 	const u32 *code;
607 #ifdef CONFIG_DEEP_SLEEP
608 #ifdef CONFIG_PPC
609 	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
610 #else
611 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
612 #endif
613 #endif
614 
615 	if (!firmware)
616 		return -EINVAL;
617 
618 	hdr = &firmware->header;
619 
620 	/* Check the magic */
621 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
622 	    (hdr->magic[2] != 'F')) {
623 #ifdef CONFIG_DEEP_SLEEP
624 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
625 #endif
626 		return -EPERM;
627 	}
628 
629 	/*
630 	 * If the microcode calls for it, split the I-RAM.
631 	 */
632 	if (!firmware->split) {
633 		out_be16(&qe_immrr->cp.cercr,
634 			 in_be16(&qe_immrr->cp.cercr) | QE_CP_CERCR_CIR);
635 	}
636 
637 	/* Loop through each microcode. */
638 	for (i = 0; i < firmware->count; i++) {
639 		const struct qe_microcode *ucode = &firmware->microcode[i];
640 
641 		/* Upload a microcode if it's present */
642 		if (!ucode->code_offset)
643 			return 0;
644 
645 		code = (const void *)firmware + be32_to_cpu(ucode->code_offset);
646 
647 		/* Use auto-increment */
648 		out_be32(&qe_immrr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
649 			QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
650 
651 		for (i = 0; i < be32_to_cpu(ucode->count); i++)
652 			out_be32(&qe_immrr->iram.idata, be32_to_cpu(code[i]));
653 
654 		/* Program the traps for this processor */
655 		for (j = 0; j < 16; j++) {
656 			u32 trap = be32_to_cpu(ucode->traps[j]);
657 
658 			if (trap)
659 				out_be32(&qe_immrr->rsp[i].tibcr[j], trap);
660 		}
661 
662 		/* Enable traps */
663 		out_be32(&qe_immrr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
664 	}
665 
666 	return 0;
667 }
668 #endif
669 
670 struct qe_firmware_info *qe_get_firmware_info(void)
671 {
672 	return qe_firmware_uploaded ? &qe_firmware_info : NULL;
673 }
674 
675 static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
676 {
677 	ulong addr;
678 
679 	if (argc < 3)
680 		return cmd_usage(cmdtp);
681 
682 	if (strcmp(argv[1], "fw") == 0) {
683 		addr = simple_strtoul(argv[2], NULL, 16);
684 
685 		if (!addr) {
686 			printf("Invalid address\n");
687 			return -EINVAL;
688 		}
689 
690 		/*
691 		 * If a length was supplied, compare that with the 'length'
692 		 * field.
693 		 */
694 
695 		if (argc > 3) {
696 			ulong length = simple_strtoul(argv[3], NULL, 16);
697 			struct qe_firmware *firmware = (void *) addr;
698 
699 			if (length != be32_to_cpu(firmware->header.length)) {
700 				printf("Length mismatch\n");
701 				return -EINVAL;
702 			}
703 		}
704 
705 		return qe_upload_firmware((const struct qe_firmware *) addr);
706 	}
707 
708 	return cmd_usage(cmdtp);
709 }
710 
711 U_BOOT_CMD(
712 	qe, 4, 0, qe_cmd,
713 	"QUICC Engine commands",
714 	"fw <addr> [<length>] - Upload firmware binary at address <addr> to "
715 		"the QE,\n"
716 	"\twith optional length <length> verification."
717 );
718