]> git.ipfire.org Git - people/ms/u-boot.git/blame - drivers/qe/qe.c
armv7: ls1021a: Drop macro CONFIG_LS102XA
[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
b5bf5cb3 10#include <common.h>
b8ec2385 11#include <command.h>
1221ce45 12#include <linux/errno.h>
b5bf5cb3
MY
13#include <asm/io.h>
14#include <linux/immap_qe.h>
2459afb1 15#include <fsl_qe.h>
73fb5838 16#ifdef CONFIG_ARCH_LS1021A
9c7c86f4
ZQ
17#include <asm/arch/immap_ls102xa.h>
18#endif
7737d5c6 19
ca721fb2
ZQ
20#define MPC85xx_DEVDISR_QE_DISABLE 0x1
21
7737d5c6 22qe_map_t *qe_immr = NULL;
3bf46e6a 23#ifdef CONFIG_QE
7737d5c6 24static qe_snum_t snums[QE_NUM_OF_SNUM];
3bf46e6a 25#endif
7737d5c6 26
1218abf1
WD
27DECLARE_GLOBAL_DATA_PTR;
28
7737d5c6
DL
29void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data)
30{
d3a6532c 31 u32 cecr;
7737d5c6
DL
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
93d33204 48#ifdef CONFIG_QE
7737d5c6
DL
49uint qe_muram_alloc(uint size, uint align)
50{
7737d5c6
DL
51 uint retloc;
52 uint align_mask, off;
53 uint savebase;
54
55 align_mask = align - 1;
45bae2e3 56 savebase = gd->arch.mp_alloc_base;
7737d5c6 57
45bae2e3
SG
58 off = gd->arch.mp_alloc_base & align_mask;
59 if (off != 0)
60 gd->arch.mp_alloc_base += (align - off);
7737d5c6
DL
61
62 if ((off = size & align_mask) != 0)
63 size += (align - off);
64
45bae2e3
SG
65 if ((gd->arch.mp_alloc_base + size) >= gd->arch.mp_alloc_top) {
66 gd->arch.mp_alloc_base = savebase;
7737d5c6
DL
67 printf("%s: ran out of ram.\n", __FUNCTION__);
68 }
69
45bae2e3
SG
70 retloc = gd->arch.mp_alloc_base;
71 gd->arch.mp_alloc_base += size;
7737d5c6
DL
72
73 memset((void *)&qe_immr->muram[retloc], 0, size);
74
75 __asm__ __volatile__("sync");
76
77 return retloc;
78}
93d33204 79#endif
7737d5c6
DL
80
81void *qe_muram_addr(uint offset)
82{
83 return (void *)&qe_immr->muram[offset];
84}
85
3bf46e6a 86#ifdef CONFIG_QE
7737d5c6
DL
87static 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 */
ff9658d7 99 sdma_buffer_base = qe_muram_alloc(2048, 4096);
7737d5c6
DL
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
4e7b25e4
HW
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 */
113static u8 thread_snum[] = {
a88731a6
GF
114/* Evthreads 16-29 are not supported in MPC8309 */
115#if !defined(CONFIG_MPC8309)
7737d5c6
DL
116 0x04, 0x05, 0x0c, 0x0d,
117 0x14, 0x15, 0x1c, 0x1d,
118 0x24, 0x25, 0x2c, 0x2d,
a88731a6
GF
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
7737d5c6
DL
129};
130
131static 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
141int 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
157void 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
169void qe_init(uint qe_base)
170{
7737d5c6
DL
171 /* Init the QE IMMR base */
172 qe_immr = (qe_map_t *)qe_base;
173
f2717b47 174#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
c0a14aed
WD
175 /*
176 * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
177 */
dcf1d774 178 qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
2d4de6ae 179
c0a14aed
WD
180 /* enable the microcode in IRAM */
181 out_be32(&qe_immr->iram.iready,QE_IRAM_READY);
2d4de6ae
HW
182#endif
183
45bae2e3
SG
184 gd->arch.mp_alloc_base = QE_DATAONLY_BASE;
185 gd->arch.mp_alloc_top = gd->arch.mp_alloc_base + QE_DATAONLY_SIZE;
7737d5c6
DL
186
187 qe_sdma_init();
188 qe_snums_init();
189}
3bf46e6a 190#endif
7737d5c6 191
93d33204
ZQ
192#ifdef CONFIG_U_QE
193void u_qe_init(void)
194{
d3e6d30c 195 qe_immr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET);
93d33204 196
5632d15c 197 u_qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
93d33204
ZQ
198 out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
199}
200#endif
201
ae42eb03
ZQ
202#ifdef CONFIG_U_QE
203void u_qe_resume(void)
204{
205 qe_map_t *qe_immrr;
ae42eb03 206
d3e6d30c 207 qe_immrr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET);
ae42eb03
ZQ
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
7737d5c6
DL
213void qe_reset(void)
214{
215 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
216 (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
217}
218
3bf46e6a 219#ifdef CONFIG_QE
7737d5c6
DL
220void 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}
3bf46e6a 235#endif
7737d5c6
DL
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
1206c184 245#define BRG_CLK (gd->arch.brg_clk)
7737d5c6 246
93d33204 247#ifdef CONFIG_QE
7737d5c6
DL
248int qe_set_brg(uint brg, uint rate)
249{
7737d5c6
DL
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}
93d33204 275#endif
7737d5c6
DL
276
277/* Set ethernet MII clock master
278*/
279int 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
b8ec2385
TT
297/* Firmware information stored here for qe_get_firmware_info() */
298static 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 */
304static 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 */
312static 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",
e94a8fd3
ZQ
320 (char *)ucode->id, (u16)ucode->major, (u16)ucode->minor,
321 (u16)ucode->revision);
b8ec2385 322 else
e94a8fd3 323 printf("QE: uploading microcode '%s'\n", (char *)ucode->id);
b8ec2385
TT
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 */
349int 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;
ca721fb2 357#ifdef CONFIG_DEEP_SLEEP
73fb5838 358#ifdef CONFIG_ARCH_LS1021A
9c7c86f4
ZQ
359 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
360#else
ca721fb2 361 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
9c7c86f4 362#endif
ca721fb2 363#endif
b8ec2385
TT
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')) {
12eeb135 375 printf("QE microcode not found\n");
ca721fb2
ZQ
376#ifdef CONFIG_DEEP_SLEEP
377 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
378#endif
b8ec2385
TT
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 */
491fb6de 389 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
b8ec2385
TT
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
d3a6532c
WD
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 */
b8ec2385
TT
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));
0e0224ee 442 strncpy(qe_firmware_info.id, (char *)firmware->id, 62);
b8ec2385
TT
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
5632d15c
ZQ
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 */
488int 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
73fb5838 497#ifdef CONFIG_ARCH_LS1021A
9c7c86f4
ZQ
498 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
499#else
5632d15c 500 ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
9c7c86f4 501#endif
5632d15c
ZQ
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
ae42eb03
ZQ
599
600#ifdef CONFIG_U_QE
601int 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
5632d15c 669
b8ec2385
TT
670struct qe_firmware_info *qe_get_firmware_info(void)
671{
672 return qe_firmware_uploaded ? &qe_firmware_info : NULL;
673}
674
54841ab5 675static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
b8ec2385
TT
676{
677 ulong addr;
678
47e26b1b
WD
679 if (argc < 3)
680 return cmd_usage(cmdtp);
b8ec2385
TT
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
d3a6532c
WD
690 /*
691 * If a length was supplied, compare that with the 'length'
692 * field.
693 */
b8ec2385
TT
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
47e26b1b 708 return cmd_usage(cmdtp);
b8ec2385
TT
709}
710
711U_BOOT_CMD(
712 qe, 4, 0, qe_cmd,
2fb2604d 713 "QUICC Engine commands",
b8ec2385 714 "fw <addr> [<length>] - Upload firmware binary at address <addr> to "
a89c33db
WD
715 "the QE,\n"
716 "\twith optional length <length> verification."
717);