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