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