xref: /openbmc/u-boot/drivers/qe/qe.c (revision 0c7fd8f4)
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 		       (char *)ucode->id, (u16)ucode->major, (u16)ucode->minor,
317 		       (u16)ucode->revision);
318 	else
319 		printf("QE: uploading microcode '%s'\n", (char *)ucode->id);
320 
321 	/* Use auto-increment */
322 	out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
323 		QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
324 
325 	for (i = 0; i < be32_to_cpu(ucode->count); i++)
326 		out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
327 }
328 
329 /*
330  * Upload a microcode to the I-RAM at a specific address.
331  *
332  * See docs/README.qe_firmware for information on QE microcode uploading.
333  *
334  * Currently, only version 1 is supported, so the 'version' field must be
335  * set to 1.
336  *
337  * The SOC model and revision are not validated, they are only displayed for
338  * informational purposes.
339  *
340  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
341  * all of the microcode structures, minus the CRC.
342  *
343  * 'length' is the size that the structure says it is, including the CRC.
344  */
345 int qe_upload_firmware(const struct qe_firmware *firmware)
346 {
347 	unsigned int i;
348 	unsigned int j;
349 	u32 crc;
350 	size_t calc_size = sizeof(struct qe_firmware);
351 	size_t length;
352 	const struct qe_header *hdr;
353 #ifdef CONFIG_DEEP_SLEEP
354 #ifdef CONFIG_LS102XA
355 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
356 #else
357 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
358 #endif
359 #endif
360 	if (!firmware) {
361 		printf("Invalid address\n");
362 		return -EINVAL;
363 	}
364 
365 	hdr = &firmware->header;
366 	length = be32_to_cpu(hdr->length);
367 
368 	/* Check the magic */
369 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
370 	    (hdr->magic[2] != 'F')) {
371 		printf("QE microcode not found\n");
372 #ifdef CONFIG_DEEP_SLEEP
373 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
374 #endif
375 		return -EPERM;
376 	}
377 
378 	/* Check the version */
379 	if (hdr->version != 1) {
380 		printf("Unsupported version\n");
381 		return -EPERM;
382 	}
383 
384 	/* Validate some of the fields */
385 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
386 		printf("Invalid data\n");
387 		return -EINVAL;
388 	}
389 
390 	/* Validate the length and check if there's a CRC */
391 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
392 
393 	for (i = 0; i < firmware->count; i++)
394 		/*
395 		 * For situations where the second RISC uses the same microcode
396 		 * as the first, the 'code_offset' and 'count' fields will be
397 		 * zero, so it's okay to add those.
398 		 */
399 		calc_size += sizeof(u32) *
400 			be32_to_cpu(firmware->microcode[i].count);
401 
402 	/* Validate the length */
403 	if (length != calc_size + sizeof(u32)) {
404 		printf("Invalid length\n");
405 		return -EPERM;
406 	}
407 
408 	/*
409 	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
410 	 * function isn't available unless you turn on JFFS support.
411 	 */
412 	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
413 	if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) {
414 		printf("Firmware CRC is invalid\n");
415 		return -EIO;
416 	}
417 
418 	/*
419 	 * If the microcode calls for it, split the I-RAM.
420 	 */
421 	if (!firmware->split) {
422 		out_be16(&qe_immr->cp.cercr,
423 			in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
424 	}
425 
426 	if (firmware->soc.model)
427 		printf("Firmware '%s' for %u V%u.%u\n",
428 			firmware->id, be16_to_cpu(firmware->soc.model),
429 			firmware->soc.major, firmware->soc.minor);
430 	else
431 		printf("Firmware '%s'\n", firmware->id);
432 
433 	/*
434 	 * The QE only supports one microcode per RISC, so clear out all the
435 	 * saved microcode information and put in the new.
436 	 */
437 	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
438 	strncpy(qe_firmware_info.id, (char *)firmware->id, 62);
439 	qe_firmware_info.extended_modes = firmware->extended_modes;
440 	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
441 		sizeof(firmware->vtraps));
442 	qe_firmware_uploaded = 1;
443 
444 	/* Loop through each microcode. */
445 	for (i = 0; i < firmware->count; i++) {
446 		const struct qe_microcode *ucode = &firmware->microcode[i];
447 
448 		/* Upload a microcode if it's present */
449 		if (ucode->code_offset)
450 			qe_upload_microcode(firmware, ucode);
451 
452 		/* Program the traps for this processor */
453 		for (j = 0; j < 16; j++) {
454 			u32 trap = be32_to_cpu(ucode->traps[j]);
455 
456 			if (trap)
457 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
458 		}
459 
460 		/* Enable traps */
461 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
462 	}
463 
464 	return 0;
465 }
466 
467 #ifdef CONFIG_U_QE
468 /*
469  * Upload a microcode to the I-RAM at a specific address.
470  *
471  * See docs/README.qe_firmware for information on QE microcode uploading.
472  *
473  * Currently, only version 1 is supported, so the 'version' field must be
474  * set to 1.
475  *
476  * The SOC model and revision are not validated, they are only displayed for
477  * informational purposes.
478  *
479  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
480  * all of the microcode structures, minus the CRC.
481  *
482  * 'length' is the size that the structure says it is, including the CRC.
483  */
484 int u_qe_upload_firmware(const struct qe_firmware *firmware)
485 {
486 	unsigned int i;
487 	unsigned int j;
488 	u32 crc;
489 	size_t calc_size = sizeof(struct qe_firmware);
490 	size_t length;
491 	const struct qe_header *hdr;
492 #ifdef CONFIG_DEEP_SLEEP
493 #ifdef CONFIG_LS102XA
494 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
495 #else
496 	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
497 #endif
498 #endif
499 	if (!firmware) {
500 		printf("Invalid address\n");
501 		return -EINVAL;
502 	}
503 
504 	hdr = &firmware->header;
505 	length = be32_to_cpu(hdr->length);
506 
507 	/* Check the magic */
508 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
509 	    (hdr->magic[2] != 'F')) {
510 		printf("Not a microcode\n");
511 #ifdef CONFIG_DEEP_SLEEP
512 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
513 #endif
514 		return -EPERM;
515 	}
516 
517 	/* Check the version */
518 	if (hdr->version != 1) {
519 		printf("Unsupported version\n");
520 		return -EPERM;
521 	}
522 
523 	/* Validate some of the fields */
524 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
525 		printf("Invalid data\n");
526 		return -EINVAL;
527 	}
528 
529 	/* Validate the length and check if there's a CRC */
530 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
531 
532 	for (i = 0; i < firmware->count; i++)
533 		/*
534 		 * For situations where the second RISC uses the same microcode
535 		 * as the first, the 'code_offset' and 'count' fields will be
536 		 * zero, so it's okay to add those.
537 		 */
538 		calc_size += sizeof(u32) *
539 			be32_to_cpu(firmware->microcode[i].count);
540 
541 	/* Validate the length */
542 	if (length != calc_size + sizeof(u32)) {
543 		printf("Invalid length\n");
544 		return -EPERM;
545 	}
546 
547 	/*
548 	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
549 	 * function isn't available unless you turn on JFFS support.
550 	 */
551 	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
552 	if (crc != (crc32(-1, (const void *)firmware, calc_size) ^ -1)) {
553 		printf("Firmware CRC is invalid\n");
554 		return -EIO;
555 	}
556 
557 	/*
558 	 * If the microcode calls for it, split the I-RAM.
559 	 */
560 	if (!firmware->split) {
561 		out_be16(&qe_immr->cp.cercr,
562 			 in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
563 	}
564 
565 	if (firmware->soc.model)
566 		printf("Firmware '%s' for %u V%u.%u\n",
567 		       firmware->id, be16_to_cpu(firmware->soc.model),
568 		       firmware->soc.major, firmware->soc.minor);
569 	else
570 		printf("Firmware '%s'\n", firmware->id);
571 
572 	/* Loop through each microcode. */
573 	for (i = 0; i < firmware->count; i++) {
574 		const struct qe_microcode *ucode = &firmware->microcode[i];
575 
576 		/* Upload a microcode if it's present */
577 		if (ucode->code_offset)
578 			qe_upload_microcode(firmware, ucode);
579 
580 		/* Program the traps for this processor */
581 		for (j = 0; j < 16; j++) {
582 			u32 trap = be32_to_cpu(ucode->traps[j]);
583 
584 			if (trap)
585 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
586 		}
587 
588 		/* Enable traps */
589 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
590 	}
591 
592 	return 0;
593 }
594 #endif
595 
596 #ifdef CONFIG_U_QE
597 int u_qe_firmware_resume(const struct qe_firmware *firmware, qe_map_t *qe_immrr)
598 {
599 	unsigned int i;
600 	unsigned int j;
601 	const struct qe_header *hdr;
602 	const u32 *code;
603 #ifdef CONFIG_DEEP_SLEEP
604 #ifdef CONFIG_PPC
605 	ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
606 #else
607 	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
608 #endif
609 #endif
610 
611 	if (!firmware)
612 		return -EINVAL;
613 
614 	hdr = &firmware->header;
615 
616 	/* Check the magic */
617 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
618 	    (hdr->magic[2] != 'F')) {
619 #ifdef CONFIG_DEEP_SLEEP
620 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
621 #endif
622 		return -EPERM;
623 	}
624 
625 	/*
626 	 * If the microcode calls for it, split the I-RAM.
627 	 */
628 	if (!firmware->split) {
629 		out_be16(&qe_immrr->cp.cercr,
630 			 in_be16(&qe_immrr->cp.cercr) | QE_CP_CERCR_CIR);
631 	}
632 
633 	/* Loop through each microcode. */
634 	for (i = 0; i < firmware->count; i++) {
635 		const struct qe_microcode *ucode = &firmware->microcode[i];
636 
637 		/* Upload a microcode if it's present */
638 		if (!ucode->code_offset)
639 			return 0;
640 
641 		code = (const void *)firmware + be32_to_cpu(ucode->code_offset);
642 
643 		/* Use auto-increment */
644 		out_be32(&qe_immrr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
645 			QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
646 
647 		for (i = 0; i < be32_to_cpu(ucode->count); i++)
648 			out_be32(&qe_immrr->iram.idata, be32_to_cpu(code[i]));
649 
650 		/* Program the traps for this processor */
651 		for (j = 0; j < 16; j++) {
652 			u32 trap = be32_to_cpu(ucode->traps[j]);
653 
654 			if (trap)
655 				out_be32(&qe_immrr->rsp[i].tibcr[j], trap);
656 		}
657 
658 		/* Enable traps */
659 		out_be32(&qe_immrr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
660 	}
661 
662 	return 0;
663 }
664 #endif
665 
666 struct qe_firmware_info *qe_get_firmware_info(void)
667 {
668 	return qe_firmware_uploaded ? &qe_firmware_info : NULL;
669 }
670 
671 static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
672 {
673 	ulong addr;
674 
675 	if (argc < 3)
676 		return cmd_usage(cmdtp);
677 
678 	if (strcmp(argv[1], "fw") == 0) {
679 		addr = simple_strtoul(argv[2], NULL, 16);
680 
681 		if (!addr) {
682 			printf("Invalid address\n");
683 			return -EINVAL;
684 		}
685 
686 		/*
687 		 * If a length was supplied, compare that with the 'length'
688 		 * field.
689 		 */
690 
691 		if (argc > 3) {
692 			ulong length = simple_strtoul(argv[3], NULL, 16);
693 			struct qe_firmware *firmware = (void *) addr;
694 
695 			if (length != be32_to_cpu(firmware->header.length)) {
696 				printf("Length mismatch\n");
697 				return -EINVAL;
698 			}
699 		}
700 
701 		return qe_upload_firmware((const struct qe_firmware *) addr);
702 	}
703 
704 	return cmd_usage(cmdtp);
705 }
706 
707 U_BOOT_CMD(
708 	qe, 4, 0, qe_cmd,
709 	"QUICC Engine commands",
710 	"fw <addr> [<length>] - Upload firmware binary at address <addr> to "
711 		"the QE,\n"
712 	"\twith optional length <length> verification."
713 );
714