]> git.ipfire.org Git - people/ms/u-boot.git/blame - drivers/qe/qe.c
driver/qe: use strncpy instead of strcpy
[people/ms/u-boot.git] / drivers / qe / qe.c
CommitLineData
7737d5c6 1/*
4e7b25e4 2 * Copyright (C) 2006-2009 Freescale Semiconductor, Inc.
7737d5c6
DL
3 *
4 * Dave Liu <daveliu@freescale.com>
5 * based on source code of Shlomi Gridish
6 *
1a459660 7 * SPDX-License-Identifier: GPL-2.0+
7737d5c6
DL
8 */
9
10#include "common.h"
b8ec2385 11#include <command.h>
7737d5c6
DL
12#include "asm/errno.h"
13#include "asm/io.h"
38d67a4e 14#include "linux/immap_qe.h"
7737d5c6 15#include "qe.h"
9c7c86f4
ZQ
16#ifdef CONFIG_LS102XA
17#include <asm/arch/immap_ls102xa.h>
18#endif
7737d5c6 19
ca721fb2
ZQ
20#define MPC85xx_DEVDISR_QE_DISABLE 0x1
21
7737d5c6
DL
22qe_map_t *qe_immr = NULL;
23static qe_snum_t snums[QE_NUM_OF_SNUM];
24
1218abf1
WD
25DECLARE_GLOBAL_DATA_PTR;
26
7737d5c6
DL
27void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data)
28{
d3a6532c 29 u32 cecr;
7737d5c6
DL
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
93d33204 46#ifdef CONFIG_QE
7737d5c6
DL
47uint qe_muram_alloc(uint size, uint align)
48{
7737d5c6
DL
49 uint retloc;
50 uint align_mask, off;
51 uint savebase;
52
53 align_mask = align - 1;
45bae2e3 54 savebase = gd->arch.mp_alloc_base;
7737d5c6 55
45bae2e3
SG
56 off = gd->arch.mp_alloc_base & align_mask;
57 if (off != 0)
58 gd->arch.mp_alloc_base += (align - off);
7737d5c6
DL
59
60 if ((off = size & align_mask) != 0)
61 size += (align - off);
62
45bae2e3
SG
63 if ((gd->arch.mp_alloc_base + size) >= gd->arch.mp_alloc_top) {
64 gd->arch.mp_alloc_base = savebase;
7737d5c6
DL
65 printf("%s: ran out of ram.\n", __FUNCTION__);
66 }
67
45bae2e3
SG
68 retloc = gd->arch.mp_alloc_base;
69 gd->arch.mp_alloc_base += size;
7737d5c6
DL
70
71 memset((void *)&qe_immr->muram[retloc], 0, size);
72
73 __asm__ __volatile__("sync");
74
75 return retloc;
76}
93d33204 77#endif
7737d5c6
DL
78
79void *qe_muram_addr(uint offset)
80{
81 return (void *)&qe_immr->muram[offset];
82}
83
84static 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 */
ff9658d7 96 sdma_buffer_base = qe_muram_alloc(2048, 4096);
7737d5c6
DL
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
4e7b25e4
HW
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 */
110static u8 thread_snum[] = {
a88731a6
GF
111/* Evthreads 16-29 are not supported in MPC8309 */
112#if !defined(CONFIG_MPC8309)
7737d5c6
DL
113 0x04, 0x05, 0x0c, 0x0d,
114 0x14, 0x15, 0x1c, 0x1d,
115 0x24, 0x25, 0x2c, 0x2d,
a88731a6
GF
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
7737d5c6
DL
126};
127
128static 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
138int 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
154void 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
166void qe_init(uint qe_base)
167{
7737d5c6
DL
168 /* Init the QE IMMR base */
169 qe_immr = (qe_map_t *)qe_base;
170
f2717b47 171#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
c0a14aed
WD
172 /*
173 * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
174 */
dcf1d774 175 qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
2d4de6ae 176
c0a14aed
WD
177 /* enable the microcode in IRAM */
178 out_be32(&qe_immr->iram.iready,QE_IRAM_READY);
2d4de6ae
HW
179#endif
180
45bae2e3
SG
181 gd->arch.mp_alloc_base = QE_DATAONLY_BASE;
182 gd->arch.mp_alloc_top = gd->arch.mp_alloc_base + QE_DATAONLY_SIZE;
7737d5c6
DL
183
184 qe_sdma_init();
185 qe_snums_init();
186}
187
93d33204
ZQ
188#ifdef CONFIG_U_QE
189void 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
5632d15c 194 u_qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
93d33204
ZQ
195 out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
196}
197#endif
198
ae42eb03
ZQ
199#ifdef CONFIG_U_QE
200void 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
7737d5c6
DL
211void qe_reset(void)
212{
213 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
214 (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
215}
216
217void 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
1206c184 241#define BRG_CLK (gd->arch.brg_clk)
7737d5c6 242
93d33204 243#ifdef CONFIG_QE
7737d5c6
DL
244int qe_set_brg(uint brg, uint rate)
245{
7737d5c6
DL
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}
93d33204 271#endif
7737d5c6
DL
272
273/* Set ethernet MII clock master
274*/
275int 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
b8ec2385
TT
293/* Firmware information stored here for qe_get_firmware_info() */
294static 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 */
300static 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 */
308static 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",
e94a8fd3
ZQ
316 (char *)ucode->id, (u16)ucode->major, (u16)ucode->minor,
317 (u16)ucode->revision);
b8ec2385 318 else
e94a8fd3 319 printf("QE: uploading microcode '%s'\n", (char *)ucode->id);
b8ec2385
TT
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 */
345int 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;
ca721fb2 353#ifdef CONFIG_DEEP_SLEEP
9c7c86f4
ZQ
354#ifdef CONFIG_LS102XA
355 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
356#else
ca721fb2 357 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
9c7c86f4 358#endif
ca721fb2 359#endif
b8ec2385
TT
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')) {
12eeb135 371 printf("QE microcode not found\n");
ca721fb2
ZQ
372#ifdef CONFIG_DEEP_SLEEP
373 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
374#endif
b8ec2385
TT
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 */
491fb6de 385 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
b8ec2385
TT
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
d3a6532c
WD
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 */
b8ec2385
TT
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));
0e0224ee 438 strncpy(qe_firmware_info.id, (char *)firmware->id, 62);
b8ec2385
TT
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
5632d15c
ZQ
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 */
484int 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
9c7c86f4
ZQ
493#ifdef CONFIG_LS102XA
494 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
495#else
5632d15c 496 ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
9c7c86f4 497#endif
5632d15c
ZQ
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
ae42eb03
ZQ
595
596#ifdef CONFIG_U_QE
597int 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
5632d15c 665
b8ec2385
TT
666struct qe_firmware_info *qe_get_firmware_info(void)
667{
668 return qe_firmware_uploaded ? &qe_firmware_info : NULL;
669}
670
54841ab5 671static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
b8ec2385
TT
672{
673 ulong addr;
674
47e26b1b
WD
675 if (argc < 3)
676 return cmd_usage(cmdtp);
b8ec2385
TT
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
d3a6532c
WD
686 /*
687 * If a length was supplied, compare that with the 'length'
688 * field.
689 */
b8ec2385
TT
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
47e26b1b 704 return cmd_usage(cmdtp);
b8ec2385
TT
705}
706
707U_BOOT_CMD(
708 qe, 4, 0, qe_cmd,
2fb2604d 709 "QUICC Engine commands",
b8ec2385 710 "fw <addr> [<length>] - Upload firmware binary at address <addr> to "
a89c33db
WD
711 "the QE,\n"
712 "\twith optional length <length> verification."
713);