1
2
3
4
5
6
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
26qe_map_t *qe_immr = NULL;
27#ifdef CONFIG_QE
28static qe_snum_t snums[QE_NUM_OF_SNUM];
29#endif
30
31DECLARE_GLOBAL_DATA_PTR;
32
33void 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
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
53uint 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
85void *qe_muram_addr(uint offset)
86{
87 return (void *)&qe_immr->muram[offset];
88}
89
90#ifdef CONFIG_QE
91static 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
99 out_be32(&p->sdaqr, 0);
100 out_be32(&p->sdaqmr, 0);
101
102
103 sdma_buffer_base = qe_muram_alloc(2048, 4096);
104 out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK);
105
106
107 out_be32(&p->sdsr, 0x03000000);
108
109
110 out_be32(&p->sdmr, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT));
111}
112
113
114
115
116
117static u8 thread_snum[] = {
118
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
135static 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
145int 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
161void 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
173void qe_init(uint qe_base)
174{
175
176 qe_immr = (qe_map_t *)qe_base;
177
178#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
179
180
181
182 qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
183
184
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
197void 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
234void 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
244void 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
251void 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
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
270
271
272
273
274
275
276#define BRG_CLK (gd->arch.brg_clk)
277
278#ifdef CONFIG_QE
279int 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
309
310int qe_set_mii_clk_src(int ucc_num)
311{
312 u32 cmxgcr;
313
314
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
329static struct qe_firmware_info qe_firmware_info;
330
331
332
333
334
335static int qe_firmware_uploaded;
336
337
338
339
340
341
342
343static 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
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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380int 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
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
414 if (hdr->version != 1) {
415 printf("Unsupported version\n");
416 return -EPERM;
417 }
418
419
420 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
421 printf("Invalid data\n");
422 return -EINVAL;
423 }
424
425
426 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
427
428 for (i = 0; i < firmware->count; i++)
429
430
431
432
433
434 calc_size += sizeof(u32) *
435 be32_to_cpu(firmware->microcode[i].count);
436
437
438 if (length != calc_size + sizeof(u32)) {
439 printf("Invalid length\n");
440 return -EPERM;
441 }
442
443
444
445
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
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
470
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
480 for (i = 0; i < firmware->count; i++) {
481 const struct qe_microcode *ucode = &firmware->microcode[i];
482
483
484 if (ucode->code_offset)
485 qe_upload_microcode(firmware, ucode);
486
487
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
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
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519int 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
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
553 if (hdr->version != 1) {
554 printf("Unsupported version\n");
555 return -EPERM;
556 }
557
558
559 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
560 printf("Invalid data\n");
561 return -EINVAL;
562 }
563
564
565 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
566
567 for (i = 0; i < firmware->count; i++)
568
569
570
571
572
573 calc_size += sizeof(u32) *
574 be32_to_cpu(firmware->microcode[i].count);
575
576
577 if (length != calc_size + sizeof(u32)) {
578 printf("Invalid length\n");
579 return -EPERM;
580 }
581
582
583
584
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
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
608 for (i = 0; i < firmware->count; i++) {
609 const struct qe_microcode *ucode = &firmware->microcode[i];
610
611
612 if (ucode->code_offset)
613 qe_upload_microcode(firmware, ucode);
614
615
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
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
632int 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
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
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
669 for (i = 0; i < firmware->count; i++) {
670 const struct qe_microcode *ucode = &firmware->microcode[i];
671
672
673 if (!ucode->code_offset)
674 return 0;
675
676 code = (const void *)firmware + be32_to_cpu(ucode->code_offset);
677
678
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
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
694 out_be32(&qe_immrr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
695 }
696
697 return 0;
698}
699#endif
700
701struct qe_firmware_info *qe_get_firmware_info(void)
702{
703 return qe_firmware_uploaded ? &qe_firmware_info : NULL;
704}
705
706static 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
723
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
742U_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);
749