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