]> Git Repo - J-u-boot.git/blame - drivers/qe/qe.c
Merge branch '2022-12-05-Kconfig-migrations-and-renames' into next
[J-u-boot.git] / drivers / qe / qe.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
7737d5c6 2/*
4e7b25e4 3 * Copyright (C) 2006-2009 Freescale Semiconductor, Inc.
7737d5c6
DL
4 *
5 * Dave Liu <[email protected]>
6 * based on source code of Shlomi Gridish
7737d5c6
DL
7 */
8
b5bf5cb3 9#include <common.h>
5aa03ddd 10#include <malloc.h>
b8ec2385 11#include <command.h>
401d1c4f 12#include <asm/global_data.h>
1221ce45 13#include <linux/errno.h>
b5bf5cb3
MY
14#include <asm/io.h>
15#include <linux/immap_qe.h>
2459afb1 16#include <fsl_qe.h>
c5e6637f 17#include <mmc.h>
3db71108 18#include <u-boot/crc.h>
c5e6637f 19
73fb5838 20#ifdef CONFIG_ARCH_LS1021A
9c7c86f4
ZQ
21#include <asm/arch/immap_ls102xa.h>
22#endif
c5e6637f
RB
23#ifdef CONFIG_ARM64
24#include <asm/armv8/mmu.h>
25#include <asm/arch/cpu.h>
5aa03ddd
ZQ
26#endif
27
ca721fb2
ZQ
28#define MPC85xx_DEVDISR_QE_DISABLE 0x1
29
9bd64448 30qe_map_t *qe_immr;
3bf46e6a 31#ifdef CONFIG_QE
7737d5c6 32static qe_snum_t snums[QE_NUM_OF_SNUM];
3bf46e6a 33#endif
7737d5c6 34
1218abf1
WD
35DECLARE_GLOBAL_DATA_PTR;
36
7737d5c6
DL
37void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data)
38{
d3a6532c 39 u32 cecr;
7737d5c6
DL
40
41 if (cmd == QE_RESET) {
9bd64448 42 out_be32(&qe_immr->cp.cecr, (u32)(cmd | QE_CR_FLG));
7737d5c6
DL
43 } else {
44 out_be32(&qe_immr->cp.cecdr, cmd_data);
45 out_be32(&qe_immr->cp.cecr, (sbc | QE_CR_FLG |
9bd64448 46 ((u32)mcn << QE_CR_PROTOCOL_SHIFT) | cmd));
7737d5c6
DL
47 }
48 /* Wait for the QE_CR_FLG to clear */
49 do {
50 cecr = in_be32(&qe_immr->cp.cecr);
51 } while (cecr & QE_CR_FLG);
7737d5c6
DL
52}
53
93d33204 54#ifdef CONFIG_QE
7737d5c6
DL
55uint qe_muram_alloc(uint size, uint align)
56{
7737d5c6
DL
57 uint retloc;
58 uint align_mask, off;
59 uint savebase;
60
61 align_mask = align - 1;
45bae2e3 62 savebase = gd->arch.mp_alloc_base;
7737d5c6 63
45bae2e3
SG
64 off = gd->arch.mp_alloc_base & align_mask;
65 if (off != 0)
66 gd->arch.mp_alloc_base += (align - off);
7737d5c6 67
9bd64448
HS
68 off = size & align_mask;
69 if (off != 0)
7737d5c6
DL
70 size += (align - off);
71
45bae2e3
SG
72 if ((gd->arch.mp_alloc_base + size) >= gd->arch.mp_alloc_top) {
73 gd->arch.mp_alloc_base = savebase;
9bd64448 74 printf("%s: ran out of ram.\n", __func__);
7737d5c6
DL
75 }
76
45bae2e3
SG
77 retloc = gd->arch.mp_alloc_base;
78 gd->arch.mp_alloc_base += size;
7737d5c6
DL
79
80 memset((void *)&qe_immr->muram[retloc], 0, size);
81
82 __asm__ __volatile__("sync");
83
84 return retloc;
85}
93d33204 86#endif
7737d5c6
DL
87
88void *qe_muram_addr(uint offset)
89{
90 return (void *)&qe_immr->muram[offset];
91}
92
3bf46e6a 93#ifdef CONFIG_QE
7737d5c6
DL
94static void qe_sdma_init(void)
95{
9bd64448
HS
96 sdma_t *p;
97 uint sdma_buffer_base;
7737d5c6 98
9bd64448 99 p = (sdma_t *)&qe_immr->sdma;
7737d5c6
DL
100
101 /* All of DMA transaction in bus 1 */
102 out_be32(&p->sdaqr, 0);
103 out_be32(&p->sdaqmr, 0);
104
105 /* Allocate 2KB temporary buffer for sdma */
ff9658d7 106 sdma_buffer_base = qe_muram_alloc(2048, 4096);
7737d5c6
DL
107 out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK);
108
109 /* Clear sdma status */
110 out_be32(&p->sdsr, 0x03000000);
111
112 /* Enable global mode on bus 1, and 2KB buffer size */
113 out_be32(&p->sdmr, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT));
114}
115
4e7b25e4
HW
116/* This table is a list of the serial numbers of the Threads, taken from the
117 * "SNUM Table" chart in the QE Reference Manual. The order is not important,
118 * we just need to know what the SNUMs are for the threads.
119 */
120static u8 thread_snum[] = {
a88731a6 121/* Evthreads 16-29 are not supported in MPC8309 */
7737d5c6
DL
122 0x04, 0x05, 0x0c, 0x0d,
123 0x14, 0x15, 0x1c, 0x1d,
124 0x24, 0x25, 0x2c, 0x2d,
a88731a6 125 0x34, 0x35,
a88731a6
GF
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
7737d5c6
DL
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
c5e6637f
RB
174#ifdef CONFIG_TFABOOT
175void qe_init(uint qe_base)
176{
177 enum boot_src src = get_boot_src();
178
179 /* Init the QE IMMR base */
180 qe_immr = (qe_map_t *)qe_base;
181
182 if (src == BOOT_SOURCE_IFC_NOR) {
183 /*
184 * Upload microcode to IRAM for those SOCs
185 * which do not have ROM in QE.
186 */
187 qe_upload_firmware((const void *)(CONFIG_SYS_QE_FW_ADDR +
188 CONFIG_SYS_FSL_IFC_BASE));
189
190 /* enable the microcode in IRAM */
191 out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
192 }
193
194 gd->arch.mp_alloc_base = QE_DATAONLY_BASE;
195 gd->arch.mp_alloc_top = gd->arch.mp_alloc_base + QE_DATAONLY_SIZE;
196
197 qe_sdma_init();
198 qe_snums_init();
199}
200#else
7737d5c6
DL
201void qe_init(uint qe_base)
202{
7737d5c6
DL
203 /* Init the QE IMMR base */
204 qe_immr = (qe_map_t *)qe_base;
205
f2717b47 206#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
c0a14aed
WD
207 /*
208 * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
209 */
dcf1d774 210 qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
2d4de6ae 211
c0a14aed 212 /* enable the microcode in IRAM */
9bd64448 213 out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
2d4de6ae
HW
214#endif
215
45bae2e3
SG
216 gd->arch.mp_alloc_base = QE_DATAONLY_BASE;
217 gd->arch.mp_alloc_top = gd->arch.mp_alloc_base + QE_DATAONLY_SIZE;
7737d5c6
DL
218
219 qe_sdma_init();
220 qe_snums_init();
221}
3bf46e6a 222#endif
c5e6637f 223#endif
7737d5c6 224
93d33204 225#ifdef CONFIG_U_QE
c5e6637f
RB
226#ifdef CONFIG_TFABOOT
227void u_qe_init(void)
228{
229 enum boot_src src = get_boot_src();
230
231 qe_immr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET);
232
233 void *addr = (void *)CONFIG_SYS_QE_FW_ADDR;
234
235 if (src == BOOT_SOURCE_IFC_NOR)
9bd64448
HS
236 addr = (void *)(CONFIG_SYS_QE_FW_ADDR +
237 CONFIG_SYS_FSL_IFC_BASE);
c5e6637f
RB
238
239 if (src == BOOT_SOURCE_QSPI_NOR)
9bd64448 240 addr = (void *)(CONFIG_SYS_QE_FW_ADDR +
6cc04547 241 CFG_SYS_FSL_QSPI_BASE);
c5e6637f
RB
242
243 if (src == BOOT_SOURCE_SD_MMC) {
244 int dev = CONFIG_SYS_MMC_ENV_DEV;
245 u32 cnt = CONFIG_SYS_QE_FMAN_FW_LENGTH / 512;
246 u32 blk = CONFIG_SYS_QE_FW_ADDR / 512;
247
248 if (mmc_initialize(gd->bd)) {
249 printf("%s: mmc_initialize() failed\n", __func__);
250 return;
251 }
252 addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH);
253 struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
254
255 if (!mmc) {
256 free(addr);
257 printf("\nMMC cannot find device for ucode\n");
258 } else {
259 printf("\nMMC read: dev # %u, block # %u, count %u ...\n",
260 dev, blk, cnt);
261 mmc_init(mmc);
262 (void)blk_dread(mmc_get_blk_desc(mmc), blk, cnt,
263 addr);
264 }
265 }
266 if (!u_qe_upload_firmware(addr))
267 out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
268 if (src == BOOT_SOURCE_SD_MMC)
269 free(addr);
270}
271#else
93d33204
ZQ
272void u_qe_init(void)
273{
d3e6d30c 274 qe_immr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET);
93d33204 275
5aa03ddd
ZQ
276 void *addr = (void *)CONFIG_SYS_QE_FW_ADDR;
277#ifdef CONFIG_SYS_QE_FMAN_FW_IN_MMC
278 int dev = CONFIG_SYS_MMC_ENV_DEV;
279 u32 cnt = CONFIG_SYS_QE_FMAN_FW_LENGTH / 512;
280 u32 blk = CONFIG_SYS_QE_FW_ADDR / 512;
281
282 if (mmc_initialize(gd->bd)) {
283 printf("%s: mmc_initialize() failed\n", __func__);
284 return;
285 }
286 addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH);
287 struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
288
289 if (!mmc) {
5aa03ddd
ZQ
290 printf("\nMMC cannot find device for ucode\n");
291 } else {
292 printf("\nMMC read: dev # %u, block # %u, count %u ...\n",
293 dev, blk, cnt);
294 mmc_init(mmc);
c3ced8a6 295 (void)blk_dread(mmc_get_blk_desc(mmc), blk, cnt,
5aa03ddd 296 addr);
5aa03ddd
ZQ
297 }
298#endif
a7a81756
ZQ
299 if (!u_qe_upload_firmware(addr))
300 out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
5aa03ddd
ZQ
301#ifdef CONFIG_SYS_QE_FMAN_FW_IN_MMC
302 free(addr);
303#endif
93d33204
ZQ
304}
305#endif
c5e6637f 306#endif
93d33204 307
ae42eb03
ZQ
308#ifdef CONFIG_U_QE
309void u_qe_resume(void)
310{
311 qe_map_t *qe_immrr;
ae42eb03 312
d3e6d30c 313 qe_immrr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET);
ae42eb03
ZQ
314 u_qe_firmware_resume((const void *)CONFIG_SYS_QE_FW_ADDR, qe_immrr);
315 out_be32(&qe_immrr->iram.iready, QE_IRAM_READY);
316}
317#endif
318
7737d5c6
DL
319void qe_reset(void)
320{
321 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
9bd64448 322 (u8)QE_CR_PROTOCOL_UNSPECIFIED, 0);
7737d5c6
DL
323}
324
3bf46e6a 325#ifdef CONFIG_QE
7737d5c6
DL
326void qe_assign_page(uint snum, uint para_ram_base)
327{
328 u32 cecr;
329
330 out_be32(&qe_immr->cp.cecdr, para_ram_base);
9bd64448 331 out_be32(&qe_immr->cp.cecr, ((u32)snum << QE_CR_ASSIGN_PAGE_SNUM_SHIFT)
7737d5c6
DL
332 | QE_CR_FLG | QE_ASSIGN_PAGE);
333
334 /* Wait for the QE_CR_FLG to clear */
335 do {
336 cecr = in_be32(&qe_immr->cp.cecr);
9bd64448 337 } while (cecr & QE_CR_FLG);
7737d5c6 338}
3bf46e6a 339#endif
7737d5c6
DL
340
341/*
342 * brg: 0~15 as BRG1~BRG16
9bd64448 343 * rate: baud rate
7737d5c6 344 * BRG input clock comes from the BRGCLK (internal clock generated from
9bd64448
HS
345 * the QE clock, it is one-half of the QE clock), If need the clock source
346 * from CLKn pin, we have te change the function.
7737d5c6
DL
347 */
348
1206c184 349#define BRG_CLK (gd->arch.brg_clk)
7737d5c6 350
93d33204 351#ifdef CONFIG_QE
7737d5c6
DL
352int qe_set_brg(uint brg, uint rate)
353{
9bd64448
HS
354 uint *bp;
355 u32 divisor;
356 u32 val;
357 int div16 = 0;
7737d5c6
DL
358
359 if (brg >= QE_NUM_OF_BRGS)
360 return -EINVAL;
9bd64448 361
7737d5c6
DL
362 bp = (uint *)&qe_immr->brg.brgc1;
363 bp += brg;
364
365 divisor = (BRG_CLK / rate);
366 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
367 div16 = 1;
368 divisor /= 16;
369 }
370
9bd64448
HS
371 /* CHECK TODO */
372 /*
373 * was
374 * *bp = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
375 * __asm__ __volatile__("sync");
376 */
7737d5c6 377
9bd64448
HS
378 val = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
379 if (div16)
380 val |= QE_BRGC_DIV16;
381
382 out_be32(bp, val);
7737d5c6
DL
383
384 return 0;
385}
93d33204 386#endif
7737d5c6 387
9bd64448 388/* Set ethernet MII clock master */
7737d5c6
DL
389int qe_set_mii_clk_src(int ucc_num)
390{
391 u32 cmxgcr;
392
393 /* check if the UCC number is in range. */
9bd64448
HS
394 if ((ucc_num > UCC_MAX_NUM - 1) || ucc_num < 0) {
395 printf("%s: ucc num not in ranges\n", __func__);
7737d5c6
DL
396 return -EINVAL;
397 }
398
399 cmxgcr = in_be32(&qe_immr->qmx.cmxgcr);
400 cmxgcr &= ~QE_CMXGCR_MII_ENET_MNG_MASK;
9bd64448 401 cmxgcr |= (ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
7737d5c6
DL
402 out_be32(&qe_immr->qmx.cmxgcr, cmxgcr);
403
404 return 0;
405}
406
b8ec2385
TT
407/* Firmware information stored here for qe_get_firmware_info() */
408static struct qe_firmware_info qe_firmware_info;
409
410/*
411 * Set to 1 if QE firmware has been uploaded, and therefore
412 * qe_firmware_info contains valid data.
413 */
414static int qe_firmware_uploaded;
415
416/*
417 * Upload a QE microcode
418 *
419 * This function is a worker function for qe_upload_firmware(). It does
420 * the actual uploading of the microcode.
421 */
422static void qe_upload_microcode(const void *base,
9bd64448 423 const struct qe_microcode *ucode)
b8ec2385
TT
424{
425 const u32 *code = base + be32_to_cpu(ucode->code_offset);
426 unsigned int i;
427
428 if (ucode->major || ucode->minor || ucode->revision)
429 printf("QE: uploading microcode '%s' version %u.%u.%u\n",
e94a8fd3
ZQ
430 (char *)ucode->id, (u16)ucode->major, (u16)ucode->minor,
431 (u16)ucode->revision);
b8ec2385 432 else
e94a8fd3 433 printf("QE: uploading microcode '%s'\n", (char *)ucode->id);
b8ec2385
TT
434
435 /* Use auto-increment */
436 out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
437 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
438
439 for (i = 0; i < be32_to_cpu(ucode->count); i++)
440 out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
441}
442
443/*
444 * Upload a microcode to the I-RAM at a specific address.
445 *
d76485b9
HS
446 * See Documentation/powerpc/qe_firmware.rst in the Linux kernel tree for
447 * information on QE microcode uploading.
b8ec2385
TT
448 *
449 * Currently, only version 1 is supported, so the 'version' field must be
450 * set to 1.
451 *
452 * The SOC model and revision are not validated, they are only displayed for
453 * informational purposes.
454 *
455 * 'calc_size' is the calculated size, in bytes, of the firmware structure and
456 * all of the microcode structures, minus the CRC.
457 *
458 * 'length' is the size that the structure says it is, including the CRC.
459 */
460int qe_upload_firmware(const struct qe_firmware *firmware)
461{
462 unsigned int i;
463 unsigned int j;
464 u32 crc;
465 size_t calc_size = sizeof(struct qe_firmware);
466 size_t length;
467 const struct qe_header *hdr;
ca721fb2 468#ifdef CONFIG_DEEP_SLEEP
73fb5838 469#ifdef CONFIG_ARCH_LS1021A
6cc04547 470 struct ccsr_gur __iomem *gur = (void *)CFG_SYS_FSL_GUTS_ADDR;
9c7c86f4 471#else
5155207a 472 ccsr_gur_t *gur = (void *)(CFG_SYS_MPC85xx_GUTS_ADDR);
9c7c86f4 473#endif
ca721fb2 474#endif
b8ec2385
TT
475 if (!firmware) {
476 printf("Invalid address\n");
477 return -EINVAL;
478 }
479
480 hdr = &firmware->header;
481 length = be32_to_cpu(hdr->length);
482
483 /* Check the magic */
484 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
485 (hdr->magic[2] != 'F')) {
12eeb135 486 printf("QE microcode not found\n");
ca721fb2
ZQ
487#ifdef CONFIG_DEEP_SLEEP
488 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
489#endif
b8ec2385
TT
490 return -EPERM;
491 }
492
493 /* Check the version */
494 if (hdr->version != 1) {
495 printf("Unsupported version\n");
496 return -EPERM;
497 }
498
499 /* Validate some of the fields */
9bd64448 500 if (firmware->count < 1 || firmware->count > MAX_QE_RISC) {
b8ec2385
TT
501 printf("Invalid data\n");
502 return -EINVAL;
503 }
504
505 /* Validate the length and check if there's a CRC */
506 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
507
508 for (i = 0; i < firmware->count; i++)
509 /*
510 * For situations where the second RISC uses the same microcode
511 * as the first, the 'code_offset' and 'count' fields will be
512 * zero, so it's okay to add those.
513 */
514 calc_size += sizeof(u32) *
515 be32_to_cpu(firmware->microcode[i].count);
516
517 /* Validate the length */
518 if (length != calc_size + sizeof(u32)) {
519 printf("Invalid length\n");
520 return -EPERM;
521 }
522
d3a6532c
WD
523 /*
524 * Validate the CRC. We would normally call crc32_no_comp(), but that
525 * function isn't available unless you turn on JFFS support.
526 */
b8ec2385 527 crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
9bd64448 528 if (crc != (crc32(-1, (const void *)firmware, calc_size) ^ -1)) {
b8ec2385
TT
529 printf("Firmware CRC is invalid\n");
530 return -EIO;
531 }
532
533 /*
534 * If the microcode calls for it, split the I-RAM.
535 */
536 if (!firmware->split) {
537 out_be16(&qe_immr->cp.cercr,
9bd64448 538 in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
b8ec2385
TT
539 }
540
541 if (firmware->soc.model)
542 printf("Firmware '%s' for %u V%u.%u\n",
9bd64448 543 firmware->id, be16_to_cpu(firmware->soc.model),
b8ec2385
TT
544 firmware->soc.major, firmware->soc.minor);
545 else
546 printf("Firmware '%s'\n", firmware->id);
547
548 /*
549 * The QE only supports one microcode per RISC, so clear out all the
550 * saved microcode information and put in the new.
551 */
552 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
0e0224ee 553 strncpy(qe_firmware_info.id, (char *)firmware->id, 62);
b8ec2385
TT
554 qe_firmware_info.extended_modes = firmware->extended_modes;
555 memcpy(qe_firmware_info.vtraps, firmware->vtraps,
9bd64448 556 sizeof(firmware->vtraps));
b8ec2385
TT
557 qe_firmware_uploaded = 1;
558
559 /* Loop through each microcode. */
560 for (i = 0; i < firmware->count; i++) {
561 const struct qe_microcode *ucode = &firmware->microcode[i];
562
563 /* Upload a microcode if it's present */
564 if (ucode->code_offset)
565 qe_upload_microcode(firmware, ucode);
566
567 /* Program the traps for this processor */
568 for (j = 0; j < 16; j++) {
569 u32 trap = be32_to_cpu(ucode->traps[j]);
570
571 if (trap)
572 out_be32(&qe_immr->rsp[i].tibcr[j], trap);
573 }
574
575 /* Enable traps */
576 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
577 }
578
579 return 0;
580}
581
5632d15c
ZQ
582#ifdef CONFIG_U_QE
583/*
584 * Upload a microcode to the I-RAM at a specific address.
585 *
d76485b9
HS
586 * See Documentation/powerpc/qe_firmware.rst in the Linux kernel tree for
587 * information on QE microcode uploading.
5632d15c
ZQ
588 *
589 * Currently, only version 1 is supported, so the 'version' field must be
590 * set to 1.
591 *
592 * The SOC model and revision are not validated, they are only displayed for
593 * informational purposes.
594 *
595 * 'calc_size' is the calculated size, in bytes, of the firmware structure and
596 * all of the microcode structures, minus the CRC.
597 *
598 * 'length' is the size that the structure says it is, including the CRC.
599 */
600int u_qe_upload_firmware(const struct qe_firmware *firmware)
601{
602 unsigned int i;
603 unsigned int j;
604 u32 crc;
605 size_t calc_size = sizeof(struct qe_firmware);
606 size_t length;
607 const struct qe_header *hdr;
608#ifdef CONFIG_DEEP_SLEEP
73fb5838 609#ifdef CONFIG_ARCH_LS1021A
6cc04547 610 struct ccsr_gur __iomem *gur = (void *)CFG_SYS_FSL_GUTS_ADDR;
9c7c86f4 611#else
5155207a 612 ccsr_gur_t __iomem *gur = (void *)(CFG_SYS_MPC85xx_GUTS_ADDR);
9c7c86f4 613#endif
5632d15c
ZQ
614#endif
615 if (!firmware) {
616 printf("Invalid address\n");
617 return -EINVAL;
618 }
619
620 hdr = &firmware->header;
621 length = be32_to_cpu(hdr->length);
622
623 /* Check the magic */
624 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
625 (hdr->magic[2] != 'F')) {
626 printf("Not a microcode\n");
627#ifdef CONFIG_DEEP_SLEEP
628 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
629#endif
630 return -EPERM;
631 }
632
633 /* Check the version */
634 if (hdr->version != 1) {
635 printf("Unsupported version\n");
636 return -EPERM;
637 }
638
639 /* Validate some of the fields */
9bd64448 640 if (firmware->count < 1 || firmware->count > MAX_QE_RISC) {
5632d15c
ZQ
641 printf("Invalid data\n");
642 return -EINVAL;
643 }
644
645 /* Validate the length and check if there's a CRC */
646 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
647
648 for (i = 0; i < firmware->count; i++)
649 /*
650 * For situations where the second RISC uses the same microcode
651 * as the first, the 'code_offset' and 'count' fields will be
652 * zero, so it's okay to add those.
653 */
654 calc_size += sizeof(u32) *
655 be32_to_cpu(firmware->microcode[i].count);
656
657 /* Validate the length */
658 if (length != calc_size + sizeof(u32)) {
659 printf("Invalid length\n");
660 return -EPERM;
661 }
662
663 /*
664 * Validate the CRC. We would normally call crc32_no_comp(), but that
665 * function isn't available unless you turn on JFFS support.
666 */
667 crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
668 if (crc != (crc32(-1, (const void *)firmware, calc_size) ^ -1)) {
669 printf("Firmware CRC is invalid\n");
670 return -EIO;
671 }
672
673 /*
674 * If the microcode calls for it, split the I-RAM.
675 */
676 if (!firmware->split) {
677 out_be16(&qe_immr->cp.cercr,
678 in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
679 }
680
681 if (firmware->soc.model)
682 printf("Firmware '%s' for %u V%u.%u\n",
683 firmware->id, be16_to_cpu(firmware->soc.model),
684 firmware->soc.major, firmware->soc.minor);
685 else
686 printf("Firmware '%s'\n", firmware->id);
687
688 /* Loop through each microcode. */
689 for (i = 0; i < firmware->count; i++) {
690 const struct qe_microcode *ucode = &firmware->microcode[i];
691
692 /* Upload a microcode if it's present */
693 if (ucode->code_offset)
694 qe_upload_microcode(firmware, ucode);
695
696 /* Program the traps for this processor */
697 for (j = 0; j < 16; j++) {
698 u32 trap = be32_to_cpu(ucode->traps[j]);
699
700 if (trap)
701 out_be32(&qe_immr->rsp[i].tibcr[j], trap);
702 }
703
704 /* Enable traps */
705 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
706 }
707
708 return 0;
709}
710#endif
ae42eb03
ZQ
711
712#ifdef CONFIG_U_QE
713int u_qe_firmware_resume(const struct qe_firmware *firmware, qe_map_t *qe_immrr)
714{
715 unsigned int i;
716 unsigned int j;
717 const struct qe_header *hdr;
718 const u32 *code;
719#ifdef CONFIG_DEEP_SLEEP
720#ifdef CONFIG_PPC
5155207a 721 ccsr_gur_t __iomem *gur = (void *)(CFG_SYS_MPC85xx_GUTS_ADDR);
ae42eb03 722#else
6cc04547 723 struct ccsr_gur __iomem *gur = (void *)CFG_SYS_FSL_GUTS_ADDR;
ae42eb03
ZQ
724#endif
725#endif
726
727 if (!firmware)
728 return -EINVAL;
729
730 hdr = &firmware->header;
731
732 /* Check the magic */
733 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
734 (hdr->magic[2] != 'F')) {
735#ifdef CONFIG_DEEP_SLEEP
736 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
737#endif
738 return -EPERM;
739 }
740
741 /*
742 * If the microcode calls for it, split the I-RAM.
743 */
744 if (!firmware->split) {
745 out_be16(&qe_immrr->cp.cercr,
746 in_be16(&qe_immrr->cp.cercr) | QE_CP_CERCR_CIR);
747 }
748
749 /* Loop through each microcode. */
750 for (i = 0; i < firmware->count; i++) {
751 const struct qe_microcode *ucode = &firmware->microcode[i];
752
753 /* Upload a microcode if it's present */
754 if (!ucode->code_offset)
755 return 0;
756
757 code = (const void *)firmware + be32_to_cpu(ucode->code_offset);
758
759 /* Use auto-increment */
760 out_be32(&qe_immrr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
761 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
762
763 for (i = 0; i < be32_to_cpu(ucode->count); i++)
764 out_be32(&qe_immrr->iram.idata, be32_to_cpu(code[i]));
765
766 /* Program the traps for this processor */
767 for (j = 0; j < 16; j++) {
768 u32 trap = be32_to_cpu(ucode->traps[j]);
769
770 if (trap)
771 out_be32(&qe_immrr->rsp[i].tibcr[j], trap);
772 }
773
774 /* Enable traps */
775 out_be32(&qe_immrr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
776 }
777
778 return 0;
779}
780#endif
5632d15c 781
b8ec2385
TT
782struct qe_firmware_info *qe_get_firmware_info(void)
783{
784 return qe_firmware_uploaded ? &qe_firmware_info : NULL;
785}
786
09140113 787static int qe_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
b8ec2385
TT
788{
789 ulong addr;
790
47e26b1b
WD
791 if (argc < 3)
792 return cmd_usage(cmdtp);
b8ec2385
TT
793
794 if (strcmp(argv[1], "fw") == 0) {
7e5f460e 795 addr = hextoul(argv[2], NULL);
b8ec2385
TT
796
797 if (!addr) {
798 printf("Invalid address\n");
799 return -EINVAL;
800 }
801
d3a6532c
WD
802 /*
803 * If a length was supplied, compare that with the 'length'
804 * field.
805 */
b8ec2385
TT
806
807 if (argc > 3) {
7e5f460e 808 ulong length = hextoul(argv[3], NULL);
9bd64448 809 struct qe_firmware *firmware = (void *)addr;
b8ec2385
TT
810
811 if (length != be32_to_cpu(firmware->header.length)) {
812 printf("Length mismatch\n");
813 return -EINVAL;
814 }
815 }
816
9bd64448 817 return qe_upload_firmware((const struct qe_firmware *)addr);
b8ec2385
TT
818 }
819
47e26b1b 820 return cmd_usage(cmdtp);
b8ec2385
TT
821}
822
823U_BOOT_CMD(
824 qe, 4, 0, qe_cmd,
2fb2604d 825 "QUICC Engine commands",
9bd64448 826 "fw <addr> [<length>] - Upload firmware binary at address <addr> to the QE,\n"
a89c33db
WD
827 "\twith optional length <length> verification."
828);
This page took 0.608313 seconds and 4 git commands to generate.