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