2 * Copyright (C) 2006-2009 Freescale Semiconductor, Inc.
5 * based on source code of Shlomi Gridish
7 * SPDX-License-Identifier: GPL-2.0+
12 #include "asm/errno.h"
14 #include "linux/immap_qe.h"
17 #define MPC85xx_DEVDISR_QE_DISABLE 0x1
19 qe_map_t *qe_immr = NULL;
20 static qe_snum_t snums[QE_NUM_OF_SNUM];
22 DECLARE_GLOBAL_DATA_PTR;
24 void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data)
28 if (cmd == QE_RESET) {
29 out_be32(&qe_immr->cp.cecr,(u32) (cmd | QE_CR_FLG));
31 out_be32(&qe_immr->cp.cecdr, cmd_data);
32 out_be32(&qe_immr->cp.cecr, (sbc | QE_CR_FLG |
33 ((u32) mcn<<QE_CR_PROTOCOL_SHIFT) | cmd));
35 /* Wait for the QE_CR_FLG to clear */
37 cecr = in_be32(&qe_immr->cp.cecr);
38 } while (cecr & QE_CR_FLG);
43 uint qe_muram_alloc(uint size, uint align)
49 align_mask = align - 1;
50 savebase = gd->arch.mp_alloc_base;
52 off = gd->arch.mp_alloc_base & align_mask;
54 gd->arch.mp_alloc_base += (align - off);
56 if ((off = size & align_mask) != 0)
57 size += (align - off);
59 if ((gd->arch.mp_alloc_base + size) >= gd->arch.mp_alloc_top) {
60 gd->arch.mp_alloc_base = savebase;
61 printf("%s: ran out of ram.\n", __FUNCTION__);
64 retloc = gd->arch.mp_alloc_base;
65 gd->arch.mp_alloc_base += size;
67 memset((void *)&qe_immr->muram[retloc], 0, size);
69 __asm__ __volatile__("sync");
74 void *qe_muram_addr(uint offset)
76 return (void *)&qe_immr->muram[offset];
79 static void qe_sdma_init(void)
82 uint sdma_buffer_base;
84 p = (volatile sdma_t *)&qe_immr->sdma;
86 /* All of DMA transaction in bus 1 */
87 out_be32(&p->sdaqr, 0);
88 out_be32(&p->sdaqmr, 0);
90 /* Allocate 2KB temporary buffer for sdma */
91 sdma_buffer_base = qe_muram_alloc(2048, 4096);
92 out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK);
94 /* Clear sdma status */
95 out_be32(&p->sdsr, 0x03000000);
97 /* Enable global mode on bus 1, and 2KB buffer size */
98 out_be32(&p->sdmr, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT));
101 /* This table is a list of the serial numbers of the Threads, taken from the
102 * "SNUM Table" chart in the QE Reference Manual. The order is not important,
103 * we just need to know what the SNUMs are for the threads.
105 static u8 thread_snum[] = {
106 /* Evthreads 16-29 are not supported in MPC8309 */
107 #if !defined(CONFIG_MPC8309)
108 0x04, 0x05, 0x0c, 0x0d,
109 0x14, 0x15, 0x1c, 0x1d,
110 0x24, 0x25, 0x2c, 0x2d,
113 0x88, 0x89, 0x98, 0x99,
114 0xa8, 0xa9, 0xb8, 0xb9,
115 0xc8, 0xc9, 0xd8, 0xd9,
116 0xe8, 0xe9, 0x08, 0x09,
117 0x18, 0x19, 0x28, 0x29,
118 0x38, 0x39, 0x48, 0x49,
119 0x58, 0x59, 0x68, 0x69,
120 0x78, 0x79, 0x80, 0x81
123 static void qe_snums_init(void)
127 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
128 snums[i].state = QE_SNUM_STATE_FREE;
129 snums[i].num = thread_snum[i];
133 int qe_get_snum(void)
138 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
139 if (snums[i].state == QE_SNUM_STATE_FREE) {
140 snums[i].state = QE_SNUM_STATE_USED;
149 void qe_put_snum(u8 snum)
153 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
154 if (snums[i].num == snum) {
155 snums[i].state = QE_SNUM_STATE_FREE;
161 void qe_init(uint qe_base)
163 /* Init the QE IMMR base */
164 qe_immr = (qe_map_t *)qe_base;
166 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
168 * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
170 qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
172 /* enable the microcode in IRAM */
173 out_be32(&qe_immr->iram.iready,QE_IRAM_READY);
176 gd->arch.mp_alloc_base = QE_DATAONLY_BASE;
177 gd->arch.mp_alloc_top = gd->arch.mp_alloc_base + QE_DATAONLY_SIZE;
185 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
186 (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
189 void qe_assign_page(uint snum, uint para_ram_base)
193 out_be32(&qe_immr->cp.cecdr, para_ram_base);
194 out_be32(&qe_immr->cp.cecr, ((u32) snum<<QE_CR_ASSIGN_PAGE_SNUM_SHIFT)
195 | QE_CR_FLG | QE_ASSIGN_PAGE);
197 /* Wait for the QE_CR_FLG to clear */
199 cecr = in_be32(&qe_immr->cp.cecr);
200 } while (cecr & QE_CR_FLG );
206 * brg: 0~15 as BRG1~BRG16
208 * BRG input clock comes from the BRGCLK (internal clock generated from
209 the QE clock, it is one-half of the QE clock), If need the clock source
210 from CLKn pin, we have te change the function.
213 #define BRG_CLK (gd->arch.brg_clk)
215 int qe_set_brg(uint brg, uint rate)
221 if (brg >= QE_NUM_OF_BRGS)
223 bp = (uint *)&qe_immr->brg.brgc1;
226 divisor = (BRG_CLK / rate);
227 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
232 *bp = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
233 __asm__ __volatile__("sync");
236 *bp |= QE_BRGC_DIV16;
237 __asm__ __volatile__("sync");
243 /* Set ethernet MII clock master
245 int qe_set_mii_clk_src(int ucc_num)
249 /* check if the UCC number is in range. */
250 if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) {
251 printf("%s: ucc num not in ranges\n", __FUNCTION__);
255 cmxgcr = in_be32(&qe_immr->qmx.cmxgcr);
256 cmxgcr &= ~QE_CMXGCR_MII_ENET_MNG_MASK;
257 cmxgcr |= (ucc_num <<QE_CMXGCR_MII_ENET_MNG_SHIFT);
258 out_be32(&qe_immr->qmx.cmxgcr, cmxgcr);
263 /* Firmware information stored here for qe_get_firmware_info() */
264 static struct qe_firmware_info qe_firmware_info;
267 * Set to 1 if QE firmware has been uploaded, and therefore
268 * qe_firmware_info contains valid data.
270 static int qe_firmware_uploaded;
273 * Upload a QE microcode
275 * This function is a worker function for qe_upload_firmware(). It does
276 * the actual uploading of the microcode.
278 static void qe_upload_microcode(const void *base,
279 const struct qe_microcode *ucode)
281 const u32 *code = base + be32_to_cpu(ucode->code_offset);
284 if (ucode->major || ucode->minor || ucode->revision)
285 printf("QE: uploading microcode '%s' version %u.%u.%u\n",
286 ucode->id, ucode->major, ucode->minor, ucode->revision);
288 printf("QE: uploading microcode '%s'\n", ucode->id);
290 /* Use auto-increment */
291 out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
292 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
294 for (i = 0; i < be32_to_cpu(ucode->count); i++)
295 out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
299 * Upload a microcode to the I-RAM at a specific address.
301 * See docs/README.qe_firmware for information on QE microcode uploading.
303 * Currently, only version 1 is supported, so the 'version' field must be
306 * The SOC model and revision are not validated, they are only displayed for
307 * informational purposes.
309 * 'calc_size' is the calculated size, in bytes, of the firmware structure and
310 * all of the microcode structures, minus the CRC.
312 * 'length' is the size that the structure says it is, including the CRC.
314 int qe_upload_firmware(const struct qe_firmware *firmware)
319 size_t calc_size = sizeof(struct qe_firmware);
321 const struct qe_header *hdr;
322 #ifdef CONFIG_DEEP_SLEEP
323 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
326 printf("Invalid address\n");
330 hdr = &firmware->header;
331 length = be32_to_cpu(hdr->length);
333 /* Check the magic */
334 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
335 (hdr->magic[2] != 'F')) {
336 printf("QE microcode not found\n");
337 #ifdef CONFIG_DEEP_SLEEP
338 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
343 /* Check the version */
344 if (hdr->version != 1) {
345 printf("Unsupported version\n");
349 /* Validate some of the fields */
350 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
351 printf("Invalid data\n");
355 /* Validate the length and check if there's a CRC */
356 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
358 for (i = 0; i < firmware->count; i++)
360 * For situations where the second RISC uses the same microcode
361 * as the first, the 'code_offset' and 'count' fields will be
362 * zero, so it's okay to add those.
364 calc_size += sizeof(u32) *
365 be32_to_cpu(firmware->microcode[i].count);
367 /* Validate the length */
368 if (length != calc_size + sizeof(u32)) {
369 printf("Invalid length\n");
374 * Validate the CRC. We would normally call crc32_no_comp(), but that
375 * function isn't available unless you turn on JFFS support.
377 crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
378 if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) {
379 printf("Firmware CRC is invalid\n");
384 * If the microcode calls for it, split the I-RAM.
386 if (!firmware->split) {
387 out_be16(&qe_immr->cp.cercr,
388 in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
391 if (firmware->soc.model)
392 printf("Firmware '%s' for %u V%u.%u\n",
393 firmware->id, be16_to_cpu(firmware->soc.model),
394 firmware->soc.major, firmware->soc.minor);
396 printf("Firmware '%s'\n", firmware->id);
399 * The QE only supports one microcode per RISC, so clear out all the
400 * saved microcode information and put in the new.
402 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
403 strcpy(qe_firmware_info.id, (char *)firmware->id);
404 qe_firmware_info.extended_modes = firmware->extended_modes;
405 memcpy(qe_firmware_info.vtraps, firmware->vtraps,
406 sizeof(firmware->vtraps));
407 qe_firmware_uploaded = 1;
409 /* Loop through each microcode. */
410 for (i = 0; i < firmware->count; i++) {
411 const struct qe_microcode *ucode = &firmware->microcode[i];
413 /* Upload a microcode if it's present */
414 if (ucode->code_offset)
415 qe_upload_microcode(firmware, ucode);
417 /* Program the traps for this processor */
418 for (j = 0; j < 16; j++) {
419 u32 trap = be32_to_cpu(ucode->traps[j]);
422 out_be32(&qe_immr->rsp[i].tibcr[j], trap);
426 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
432 struct qe_firmware_info *qe_get_firmware_info(void)
434 return qe_firmware_uploaded ? &qe_firmware_info : NULL;
437 static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
442 return cmd_usage(cmdtp);
444 if (strcmp(argv[1], "fw") == 0) {
445 addr = simple_strtoul(argv[2], NULL, 16);
448 printf("Invalid address\n");
453 * If a length was supplied, compare that with the 'length'
458 ulong length = simple_strtoul(argv[3], NULL, 16);
459 struct qe_firmware *firmware = (void *) addr;
461 if (length != be32_to_cpu(firmware->header.length)) {
462 printf("Length mismatch\n");
467 return qe_upload_firmware((const struct qe_firmware *) addr);
470 return cmd_usage(cmdtp);
475 "QUICC Engine commands",
476 "fw <addr> [<length>] - Upload firmware binary at address <addr> to "
478 "\twith optional length <length> verification."