xref: /rk3399_rockchip-uboot/drivers/qe/qe.c (revision 3bf46e6a6de71a31be05545d59819ca73e367ddc)
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 "asm/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 	uint qe_base = CONFIG_SYS_IMMR + 0x01400000; /* QE immr base */
196 	qe_immr = (qe_map_t *)qe_base;
197 
198 	u_qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
199 	out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
200 }
201 #endif
202 
203 #ifdef CONFIG_U_QE
204 void u_qe_resume(void)
205 {
206 	qe_map_t *qe_immrr;
207 	uint qe_base = CONFIG_SYS_IMMR + QE_IMMR_OFFSET; /* QE immr base */
208 	qe_immrr = (qe_map_t *)qe_base;
209 
210 	u_qe_firmware_resume((const void *)CONFIG_SYS_QE_FW_ADDR, qe_immrr);
211 	out_be32(&qe_immrr->iram.iready, QE_IRAM_READY);
212 }
213 #endif
214 
215 void qe_reset(void)
216 {
217 	qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
218 			 (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
219 }
220 
221 #ifdef CONFIG_QE
222 void qe_assign_page(uint snum, uint para_ram_base)
223 {
224 	u32	cecr;
225 
226 	out_be32(&qe_immr->cp.cecdr, para_ram_base);
227 	out_be32(&qe_immr->cp.cecr, ((u32) snum<<QE_CR_ASSIGN_PAGE_SNUM_SHIFT)
228 					 | QE_CR_FLG | QE_ASSIGN_PAGE);
229 
230 	/* Wait for the QE_CR_FLG to clear */
231 	do {
232 		cecr = in_be32(&qe_immr->cp.cecr);
233 	} while (cecr & QE_CR_FLG );
234 
235 	return;
236 }
237 #endif
238 
239 /*
240  * brg: 0~15 as BRG1~BRG16
241    rate: baud rate
242  * BRG input clock comes from the BRGCLK (internal clock generated from
243    the QE clock, it is one-half of the QE clock), If need the clock source
244    from CLKn pin, we have te change the function.
245  */
246 
247 #define BRG_CLK		(gd->arch.brg_clk)
248 
249 #ifdef CONFIG_QE
250 int qe_set_brg(uint brg, uint rate)
251 {
252 	volatile uint	*bp;
253 	u32		divisor;
254 	int		div16 = 0;
255 
256 	if (brg >= QE_NUM_OF_BRGS)
257 		return -EINVAL;
258 	bp = (uint *)&qe_immr->brg.brgc1;
259 	bp += brg;
260 
261 	divisor = (BRG_CLK / rate);
262 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
263 		div16 = 1;
264 		divisor /= 16;
265 	}
266 
267 	*bp = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
268 	__asm__ __volatile__("sync");
269 
270 	if (div16) {
271 		*bp |= QE_BRGC_DIV16;
272 		__asm__ __volatile__("sync");
273 	}
274 
275 	return 0;
276 }
277 #endif
278 
279 /* Set ethernet MII clock master
280 */
281 int qe_set_mii_clk_src(int ucc_num)
282 {
283 	u32	cmxgcr;
284 
285 	/* check if the UCC number is in range. */
286 	if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) {
287 		printf("%s: ucc num not in ranges\n", __FUNCTION__);
288 		return -EINVAL;
289 	}
290 
291 	cmxgcr = in_be32(&qe_immr->qmx.cmxgcr);
292 	cmxgcr &= ~QE_CMXGCR_MII_ENET_MNG_MASK;
293 	cmxgcr |= (ucc_num <<QE_CMXGCR_MII_ENET_MNG_SHIFT);
294 	out_be32(&qe_immr->qmx.cmxgcr, cmxgcr);
295 
296 	return 0;
297 }
298 
299 /* Firmware information stored here for qe_get_firmware_info() */
300 static struct qe_firmware_info qe_firmware_info;
301 
302 /*
303  * Set to 1 if QE firmware has been uploaded, and therefore
304  * qe_firmware_info contains valid data.
305  */
306 static int qe_firmware_uploaded;
307 
308 /*
309  * Upload a QE microcode
310  *
311  * This function is a worker function for qe_upload_firmware().  It does
312  * the actual uploading of the microcode.
313  */
314 static void qe_upload_microcode(const void *base,
315 	const struct qe_microcode *ucode)
316 {
317 	const u32 *code = base + be32_to_cpu(ucode->code_offset);
318 	unsigned int i;
319 
320 	if (ucode->major || ucode->minor || ucode->revision)
321 		printf("QE: uploading microcode '%s' version %u.%u.%u\n",
322 		       (char *)ucode->id, (u16)ucode->major, (u16)ucode->minor,
323 		       (u16)ucode->revision);
324 	else
325 		printf("QE: uploading microcode '%s'\n", (char *)ucode->id);
326 
327 	/* Use auto-increment */
328 	out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
329 		QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
330 
331 	for (i = 0; i < be32_to_cpu(ucode->count); i++)
332 		out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
333 }
334 
335 /*
336  * Upload a microcode to the I-RAM at a specific address.
337  *
338  * See docs/README.qe_firmware for information on QE microcode uploading.
339  *
340  * Currently, only version 1 is supported, so the 'version' field must be
341  * set to 1.
342  *
343  * The SOC model and revision are not validated, they are only displayed for
344  * informational purposes.
345  *
346  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
347  * all of the microcode structures, minus the CRC.
348  *
349  * 'length' is the size that the structure says it is, including the CRC.
350  */
351 int qe_upload_firmware(const struct qe_firmware *firmware)
352 {
353 	unsigned int i;
354 	unsigned int j;
355 	u32 crc;
356 	size_t calc_size = sizeof(struct qe_firmware);
357 	size_t length;
358 	const struct qe_header *hdr;
359 #ifdef CONFIG_DEEP_SLEEP
360 #ifdef CONFIG_LS102XA
361 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
362 #else
363 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
364 #endif
365 #endif
366 	if (!firmware) {
367 		printf("Invalid address\n");
368 		return -EINVAL;
369 	}
370 
371 	hdr = &firmware->header;
372 	length = be32_to_cpu(hdr->length);
373 
374 	/* Check the magic */
375 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
376 	    (hdr->magic[2] != 'F')) {
377 		printf("QE microcode not found\n");
378 #ifdef CONFIG_DEEP_SLEEP
379 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
380 #endif
381 		return -EPERM;
382 	}
383 
384 	/* Check the version */
385 	if (hdr->version != 1) {
386 		printf("Unsupported version\n");
387 		return -EPERM;
388 	}
389 
390 	/* Validate some of the fields */
391 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
392 		printf("Invalid data\n");
393 		return -EINVAL;
394 	}
395 
396 	/* Validate the length and check if there's a CRC */
397 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
398 
399 	for (i = 0; i < firmware->count; i++)
400 		/*
401 		 * For situations where the second RISC uses the same microcode
402 		 * as the first, the 'code_offset' and 'count' fields will be
403 		 * zero, so it's okay to add those.
404 		 */
405 		calc_size += sizeof(u32) *
406 			be32_to_cpu(firmware->microcode[i].count);
407 
408 	/* Validate the length */
409 	if (length != calc_size + sizeof(u32)) {
410 		printf("Invalid length\n");
411 		return -EPERM;
412 	}
413 
414 	/*
415 	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
416 	 * function isn't available unless you turn on JFFS support.
417 	 */
418 	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
419 	if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) {
420 		printf("Firmware CRC is invalid\n");
421 		return -EIO;
422 	}
423 
424 	/*
425 	 * If the microcode calls for it, split the I-RAM.
426 	 */
427 	if (!firmware->split) {
428 		out_be16(&qe_immr->cp.cercr,
429 			in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
430 	}
431 
432 	if (firmware->soc.model)
433 		printf("Firmware '%s' for %u V%u.%u\n",
434 			firmware->id, be16_to_cpu(firmware->soc.model),
435 			firmware->soc.major, firmware->soc.minor);
436 	else
437 		printf("Firmware '%s'\n", firmware->id);
438 
439 	/*
440 	 * The QE only supports one microcode per RISC, so clear out all the
441 	 * saved microcode information and put in the new.
442 	 */
443 	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
444 	strncpy(qe_firmware_info.id, (char *)firmware->id, 62);
445 	qe_firmware_info.extended_modes = firmware->extended_modes;
446 	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
447 		sizeof(firmware->vtraps));
448 	qe_firmware_uploaded = 1;
449 
450 	/* Loop through each microcode. */
451 	for (i = 0; i < firmware->count; i++) {
452 		const struct qe_microcode *ucode = &firmware->microcode[i];
453 
454 		/* Upload a microcode if it's present */
455 		if (ucode->code_offset)
456 			qe_upload_microcode(firmware, ucode);
457 
458 		/* Program the traps for this processor */
459 		for (j = 0; j < 16; j++) {
460 			u32 trap = be32_to_cpu(ucode->traps[j]);
461 
462 			if (trap)
463 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
464 		}
465 
466 		/* Enable traps */
467 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
468 	}
469 
470 	return 0;
471 }
472 
473 #ifdef CONFIG_U_QE
474 /*
475  * Upload a microcode to the I-RAM at a specific address.
476  *
477  * See docs/README.qe_firmware for information on QE microcode uploading.
478  *
479  * Currently, only version 1 is supported, so the 'version' field must be
480  * set to 1.
481  *
482  * The SOC model and revision are not validated, they are only displayed for
483  * informational purposes.
484  *
485  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
486  * all of the microcode structures, minus the CRC.
487  *
488  * 'length' is the size that the structure says it is, including the CRC.
489  */
490 int u_qe_upload_firmware(const struct qe_firmware *firmware)
491 {
492 	unsigned int i;
493 	unsigned int j;
494 	u32 crc;
495 	size_t calc_size = sizeof(struct qe_firmware);
496 	size_t length;
497 	const struct qe_header *hdr;
498 #ifdef CONFIG_DEEP_SLEEP
499 #ifdef CONFIG_LS102XA
500 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
501 #else
502 	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
503 #endif
504 #endif
505 	if (!firmware) {
506 		printf("Invalid address\n");
507 		return -EINVAL;
508 	}
509 
510 	hdr = &firmware->header;
511 	length = be32_to_cpu(hdr->length);
512 
513 	/* Check the magic */
514 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
515 	    (hdr->magic[2] != 'F')) {
516 		printf("Not a microcode\n");
517 #ifdef CONFIG_DEEP_SLEEP
518 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
519 #endif
520 		return -EPERM;
521 	}
522 
523 	/* Check the version */
524 	if (hdr->version != 1) {
525 		printf("Unsupported version\n");
526 		return -EPERM;
527 	}
528 
529 	/* Validate some of the fields */
530 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
531 		printf("Invalid data\n");
532 		return -EINVAL;
533 	}
534 
535 	/* Validate the length and check if there's a CRC */
536 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
537 
538 	for (i = 0; i < firmware->count; i++)
539 		/*
540 		 * For situations where the second RISC uses the same microcode
541 		 * as the first, the 'code_offset' and 'count' fields will be
542 		 * zero, so it's okay to add those.
543 		 */
544 		calc_size += sizeof(u32) *
545 			be32_to_cpu(firmware->microcode[i].count);
546 
547 	/* Validate the length */
548 	if (length != calc_size + sizeof(u32)) {
549 		printf("Invalid length\n");
550 		return -EPERM;
551 	}
552 
553 	/*
554 	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
555 	 * function isn't available unless you turn on JFFS support.
556 	 */
557 	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
558 	if (crc != (crc32(-1, (const void *)firmware, calc_size) ^ -1)) {
559 		printf("Firmware CRC is invalid\n");
560 		return -EIO;
561 	}
562 
563 	/*
564 	 * If the microcode calls for it, split the I-RAM.
565 	 */
566 	if (!firmware->split) {
567 		out_be16(&qe_immr->cp.cercr,
568 			 in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
569 	}
570 
571 	if (firmware->soc.model)
572 		printf("Firmware '%s' for %u V%u.%u\n",
573 		       firmware->id, be16_to_cpu(firmware->soc.model),
574 		       firmware->soc.major, firmware->soc.minor);
575 	else
576 		printf("Firmware '%s'\n", firmware->id);
577 
578 	/* Loop through each microcode. */
579 	for (i = 0; i < firmware->count; i++) {
580 		const struct qe_microcode *ucode = &firmware->microcode[i];
581 
582 		/* Upload a microcode if it's present */
583 		if (ucode->code_offset)
584 			qe_upload_microcode(firmware, ucode);
585 
586 		/* Program the traps for this processor */
587 		for (j = 0; j < 16; j++) {
588 			u32 trap = be32_to_cpu(ucode->traps[j]);
589 
590 			if (trap)
591 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
592 		}
593 
594 		/* Enable traps */
595 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
596 	}
597 
598 	return 0;
599 }
600 #endif
601 
602 #ifdef CONFIG_U_QE
603 int u_qe_firmware_resume(const struct qe_firmware *firmware, qe_map_t *qe_immrr)
604 {
605 	unsigned int i;
606 	unsigned int j;
607 	const struct qe_header *hdr;
608 	const u32 *code;
609 #ifdef CONFIG_DEEP_SLEEP
610 #ifdef CONFIG_PPC
611 	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
612 #else
613 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
614 #endif
615 #endif
616 
617 	if (!firmware)
618 		return -EINVAL;
619 
620 	hdr = &firmware->header;
621 
622 	/* Check the magic */
623 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
624 	    (hdr->magic[2] != 'F')) {
625 #ifdef CONFIG_DEEP_SLEEP
626 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
627 #endif
628 		return -EPERM;
629 	}
630 
631 	/*
632 	 * If the microcode calls for it, split the I-RAM.
633 	 */
634 	if (!firmware->split) {
635 		out_be16(&qe_immrr->cp.cercr,
636 			 in_be16(&qe_immrr->cp.cercr) | QE_CP_CERCR_CIR);
637 	}
638 
639 	/* Loop through each microcode. */
640 	for (i = 0; i < firmware->count; i++) {
641 		const struct qe_microcode *ucode = &firmware->microcode[i];
642 
643 		/* Upload a microcode if it's present */
644 		if (!ucode->code_offset)
645 			return 0;
646 
647 		code = (const void *)firmware + be32_to_cpu(ucode->code_offset);
648 
649 		/* Use auto-increment */
650 		out_be32(&qe_immrr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
651 			QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
652 
653 		for (i = 0; i < be32_to_cpu(ucode->count); i++)
654 			out_be32(&qe_immrr->iram.idata, be32_to_cpu(code[i]));
655 
656 		/* Program the traps for this processor */
657 		for (j = 0; j < 16; j++) {
658 			u32 trap = be32_to_cpu(ucode->traps[j]);
659 
660 			if (trap)
661 				out_be32(&qe_immrr->rsp[i].tibcr[j], trap);
662 		}
663 
664 		/* Enable traps */
665 		out_be32(&qe_immrr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
666 	}
667 
668 	return 0;
669 }
670 #endif
671 
672 struct qe_firmware_info *qe_get_firmware_info(void)
673 {
674 	return qe_firmware_uploaded ? &qe_firmware_info : NULL;
675 }
676 
677 static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
678 {
679 	ulong addr;
680 
681 	if (argc < 3)
682 		return cmd_usage(cmdtp);
683 
684 	if (strcmp(argv[1], "fw") == 0) {
685 		addr = simple_strtoul(argv[2], NULL, 16);
686 
687 		if (!addr) {
688 			printf("Invalid address\n");
689 			return -EINVAL;
690 		}
691 
692 		/*
693 		 * If a length was supplied, compare that with the 'length'
694 		 * field.
695 		 */
696 
697 		if (argc > 3) {
698 			ulong length = simple_strtoul(argv[3], NULL, 16);
699 			struct qe_firmware *firmware = (void *) addr;
700 
701 			if (length != be32_to_cpu(firmware->header.length)) {
702 				printf("Length mismatch\n");
703 				return -EINVAL;
704 			}
705 		}
706 
707 		return qe_upload_firmware((const struct qe_firmware *) addr);
708 	}
709 
710 	return cmd_usage(cmdtp);
711 }
712 
713 U_BOOT_CMD(
714 	qe, 4, 0, qe_cmd,
715 	"QUICC Engine commands",
716 	"fw <addr> [<length>] - Upload firmware binary at address <addr> to "
717 		"the QE,\n"
718 	"\twith optional length <length> verification."
719 );
720