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