2 * Copyright (C) 2006-2009 Freescale Semiconductor, Inc.
4 * Dave Liu <daveliu@freescale.com>
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
);
44 uint
qe_muram_alloc(uint size
, uint align
)
50 align_mask
= align
- 1;
51 savebase
= gd
->arch
.mp_alloc_base
;
53 off
= gd
->arch
.mp_alloc_base
& align_mask
;
55 gd
->arch
.mp_alloc_base
+= (align
- off
);
57 if ((off
= size
& align_mask
) != 0)
58 size
+= (align
- off
);
60 if ((gd
->arch
.mp_alloc_base
+ size
) >= gd
->arch
.mp_alloc_top
) {
61 gd
->arch
.mp_alloc_base
= savebase
;
62 printf("%s: ran out of ram.\n", __FUNCTION__
);
65 retloc
= gd
->arch
.mp_alloc_base
;
66 gd
->arch
.mp_alloc_base
+= size
;
68 memset((void *)&qe_immr
->muram
[retloc
], 0, size
);
70 __asm__
__volatile__("sync");
76 void *qe_muram_addr(uint offset
)
78 return (void *)&qe_immr
->muram
[offset
];
81 static void qe_sdma_init(void)
84 uint sdma_buffer_base
;
86 p
= (volatile sdma_t
*)&qe_immr
->sdma
;
88 /* All of DMA transaction in bus 1 */
89 out_be32(&p
->sdaqr
, 0);
90 out_be32(&p
->sdaqmr
, 0);
92 /* Allocate 2KB temporary buffer for sdma */
93 sdma_buffer_base
= qe_muram_alloc(2048, 4096);
94 out_be32(&p
->sdwbcr
, sdma_buffer_base
& QE_SDEBCR_BA_MASK
);
96 /* Clear sdma status */
97 out_be32(&p
->sdsr
, 0x03000000);
99 /* Enable global mode on bus 1, and 2KB buffer size */
100 out_be32(&p
->sdmr
, QE_SDMR_GLB_1_MSK
| (0x3 << QE_SDMR_CEN_SHIFT
));
103 /* This table is a list of the serial numbers of the Threads, taken from the
104 * "SNUM Table" chart in the QE Reference Manual. The order is not important,
105 * we just need to know what the SNUMs are for the threads.
107 static u8 thread_snum
[] = {
108 /* Evthreads 16-29 are not supported in MPC8309 */
109 #if !defined(CONFIG_MPC8309)
110 0x04, 0x05, 0x0c, 0x0d,
111 0x14, 0x15, 0x1c, 0x1d,
112 0x24, 0x25, 0x2c, 0x2d,
115 0x88, 0x89, 0x98, 0x99,
116 0xa8, 0xa9, 0xb8, 0xb9,
117 0xc8, 0xc9, 0xd8, 0xd9,
118 0xe8, 0xe9, 0x08, 0x09,
119 0x18, 0x19, 0x28, 0x29,
120 0x38, 0x39, 0x48, 0x49,
121 0x58, 0x59, 0x68, 0x69,
122 0x78, 0x79, 0x80, 0x81
125 static void qe_snums_init(void)
129 for (i
= 0; i
< QE_NUM_OF_SNUM
; i
++) {
130 snums
[i
].state
= QE_SNUM_STATE_FREE
;
131 snums
[i
].num
= thread_snum
[i
];
135 int qe_get_snum(void)
140 for (i
= 0; i
< QE_NUM_OF_SNUM
; i
++) {
141 if (snums
[i
].state
== QE_SNUM_STATE_FREE
) {
142 snums
[i
].state
= QE_SNUM_STATE_USED
;
151 void qe_put_snum(u8 snum
)
155 for (i
= 0; i
< QE_NUM_OF_SNUM
; i
++) {
156 if (snums
[i
].num
== snum
) {
157 snums
[i
].state
= QE_SNUM_STATE_FREE
;
163 void qe_init(uint qe_base
)
165 /* Init the QE IMMR base */
166 qe_immr
= (qe_map_t
*)qe_base
;
168 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
170 * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
172 qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR
);
174 /* enable the microcode in IRAM */
175 out_be32(&qe_immr
->iram
.iready
,QE_IRAM_READY
);
178 gd
->arch
.mp_alloc_base
= QE_DATAONLY_BASE
;
179 gd
->arch
.mp_alloc_top
= gd
->arch
.mp_alloc_base
+ QE_DATAONLY_SIZE
;
188 uint qe_base
= CONFIG_SYS_IMMR
+ 0x01400000; /* QE immr base */
189 qe_immr
= (qe_map_t
*)qe_base
;
191 qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR
);
192 out_be32(&qe_immr
->iram
.iready
, QE_IRAM_READY
);
198 qe_issue_cmd(QE_RESET
, QE_CR_SUBBLOCK_INVALID
,
199 (u8
) QE_CR_PROTOCOL_UNSPECIFIED
, 0);
202 void qe_assign_page(uint snum
, uint para_ram_base
)
206 out_be32(&qe_immr
->cp
.cecdr
, para_ram_base
);
207 out_be32(&qe_immr
->cp
.cecr
, ((u32
) snum
<<QE_CR_ASSIGN_PAGE_SNUM_SHIFT
)
208 | QE_CR_FLG
| QE_ASSIGN_PAGE
);
210 /* Wait for the QE_CR_FLG to clear */
212 cecr
= in_be32(&qe_immr
->cp
.cecr
);
213 } while (cecr
& QE_CR_FLG
);
219 * brg: 0~15 as BRG1~BRG16
221 * BRG input clock comes from the BRGCLK (internal clock generated from
222 the QE clock, it is one-half of the QE clock), If need the clock source
223 from CLKn pin, we have te change the function.
226 #define BRG_CLK (gd->arch.brg_clk)
229 int qe_set_brg(uint brg
, uint rate
)
235 if (brg
>= QE_NUM_OF_BRGS
)
237 bp
= (uint
*)&qe_immr
->brg
.brgc1
;
240 divisor
= (BRG_CLK
/ rate
);
241 if (divisor
> QE_BRGC_DIVISOR_MAX
+ 1) {
246 *bp
= ((divisor
- 1) << QE_BRGC_DIVISOR_SHIFT
) | QE_BRGC_ENABLE
;
247 __asm__
__volatile__("sync");
250 *bp
|= QE_BRGC_DIV16
;
251 __asm__
__volatile__("sync");
258 /* Set ethernet MII clock master
260 int qe_set_mii_clk_src(int ucc_num
)
264 /* check if the UCC number is in range. */
265 if ((ucc_num
> UCC_MAX_NUM
- 1) || (ucc_num
< 0)) {
266 printf("%s: ucc num not in ranges\n", __FUNCTION__
);
270 cmxgcr
= in_be32(&qe_immr
->qmx
.cmxgcr
);
271 cmxgcr
&= ~QE_CMXGCR_MII_ENET_MNG_MASK
;
272 cmxgcr
|= (ucc_num
<<QE_CMXGCR_MII_ENET_MNG_SHIFT
);
273 out_be32(&qe_immr
->qmx
.cmxgcr
, cmxgcr
);
278 /* Firmware information stored here for qe_get_firmware_info() */
279 static struct qe_firmware_info qe_firmware_info
;
282 * Set to 1 if QE firmware has been uploaded, and therefore
283 * qe_firmware_info contains valid data.
285 static int qe_firmware_uploaded
;
288 * Upload a QE microcode
290 * This function is a worker function for qe_upload_firmware(). It does
291 * the actual uploading of the microcode.
293 static void qe_upload_microcode(const void *base
,
294 const struct qe_microcode
*ucode
)
296 const u32
*code
= base
+ be32_to_cpu(ucode
->code_offset
);
299 if (ucode
->major
|| ucode
->minor
|| ucode
->revision
)
300 printf("QE: uploading microcode '%s' version %u.%u.%u\n",
301 ucode
->id
, ucode
->major
, ucode
->minor
, ucode
->revision
);
303 printf("QE: uploading microcode '%s'\n", ucode
->id
);
305 /* Use auto-increment */
306 out_be32(&qe_immr
->iram
.iadd
, be32_to_cpu(ucode
->iram_offset
) |
307 QE_IRAM_IADD_AIE
| QE_IRAM_IADD_BADDR
);
309 for (i
= 0; i
< be32_to_cpu(ucode
->count
); i
++)
310 out_be32(&qe_immr
->iram
.idata
, be32_to_cpu(code
[i
]));
314 * Upload a microcode to the I-RAM at a specific address.
316 * See docs/README.qe_firmware for information on QE microcode uploading.
318 * Currently, only version 1 is supported, so the 'version' field must be
321 * The SOC model and revision are not validated, they are only displayed for
322 * informational purposes.
324 * 'calc_size' is the calculated size, in bytes, of the firmware structure and
325 * all of the microcode structures, minus the CRC.
327 * 'length' is the size that the structure says it is, including the CRC.
329 int qe_upload_firmware(const struct qe_firmware
*firmware
)
334 size_t calc_size
= sizeof(struct qe_firmware
);
336 const struct qe_header
*hdr
;
337 #ifdef CONFIG_DEEP_SLEEP
338 ccsr_gur_t
*gur
= (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR
);
341 printf("Invalid address\n");
345 hdr
= &firmware
->header
;
346 length
= be32_to_cpu(hdr
->length
);
348 /* Check the magic */
349 if ((hdr
->magic
[0] != 'Q') || (hdr
->magic
[1] != 'E') ||
350 (hdr
->magic
[2] != 'F')) {
351 printf("QE microcode not found\n");
352 #ifdef CONFIG_DEEP_SLEEP
353 setbits_be32(&gur
->devdisr
, MPC85xx_DEVDISR_QE_DISABLE
);
358 /* Check the version */
359 if (hdr
->version
!= 1) {
360 printf("Unsupported version\n");
364 /* Validate some of the fields */
365 if ((firmware
->count
< 1) || (firmware
->count
> MAX_QE_RISC
)) {
366 printf("Invalid data\n");
370 /* Validate the length and check if there's a CRC */
371 calc_size
+= (firmware
->count
- 1) * sizeof(struct qe_microcode
);
373 for (i
= 0; i
< firmware
->count
; i
++)
375 * For situations where the second RISC uses the same microcode
376 * as the first, the 'code_offset' and 'count' fields will be
377 * zero, so it's okay to add those.
379 calc_size
+= sizeof(u32
) *
380 be32_to_cpu(firmware
->microcode
[i
].count
);
382 /* Validate the length */
383 if (length
!= calc_size
+ sizeof(u32
)) {
384 printf("Invalid length\n");
389 * Validate the CRC. We would normally call crc32_no_comp(), but that
390 * function isn't available unless you turn on JFFS support.
392 crc
= be32_to_cpu(*(u32
*)((void *)firmware
+ calc_size
));
393 if (crc
!= (crc32(-1, (const void *) firmware
, calc_size
) ^ -1)) {
394 printf("Firmware CRC is invalid\n");
399 * If the microcode calls for it, split the I-RAM.
401 if (!firmware
->split
) {
402 out_be16(&qe_immr
->cp
.cercr
,
403 in_be16(&qe_immr
->cp
.cercr
) | QE_CP_CERCR_CIR
);
406 if (firmware
->soc
.model
)
407 printf("Firmware '%s' for %u V%u.%u\n",
408 firmware
->id
, be16_to_cpu(firmware
->soc
.model
),
409 firmware
->soc
.major
, firmware
->soc
.minor
);
411 printf("Firmware '%s'\n", firmware
->id
);
414 * The QE only supports one microcode per RISC, so clear out all the
415 * saved microcode information and put in the new.
417 memset(&qe_firmware_info
, 0, sizeof(qe_firmware_info
));
418 strcpy(qe_firmware_info
.id
, (char *)firmware
->id
);
419 qe_firmware_info
.extended_modes
= firmware
->extended_modes
;
420 memcpy(qe_firmware_info
.vtraps
, firmware
->vtraps
,
421 sizeof(firmware
->vtraps
));
422 qe_firmware_uploaded
= 1;
424 /* Loop through each microcode. */
425 for (i
= 0; i
< firmware
->count
; i
++) {
426 const struct qe_microcode
*ucode
= &firmware
->microcode
[i
];
428 /* Upload a microcode if it's present */
429 if (ucode
->code_offset
)
430 qe_upload_microcode(firmware
, ucode
);
432 /* Program the traps for this processor */
433 for (j
= 0; j
< 16; j
++) {
434 u32 trap
= be32_to_cpu(ucode
->traps
[j
]);
437 out_be32(&qe_immr
->rsp
[i
].tibcr
[j
], trap
);
441 out_be32(&qe_immr
->rsp
[i
].eccr
, be32_to_cpu(ucode
->eccr
));
447 struct qe_firmware_info
*qe_get_firmware_info(void)
449 return qe_firmware_uploaded
? &qe_firmware_info
: NULL
;
452 static int qe_cmd(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
457 return cmd_usage(cmdtp
);
459 if (strcmp(argv
[1], "fw") == 0) {
460 addr
= simple_strtoul(argv
[2], NULL
, 16);
463 printf("Invalid address\n");
468 * If a length was supplied, compare that with the 'length'
473 ulong length
= simple_strtoul(argv
[3], NULL
, 16);
474 struct qe_firmware
*firmware
= (void *) addr
;
476 if (length
!= be32_to_cpu(firmware
->header
.length
)) {
477 printf("Length mismatch\n");
482 return qe_upload_firmware((const struct qe_firmware
*) addr
);
485 return cmd_usage(cmdtp
);
490 "QUICC Engine commands",
491 "fw <addr> [<length>] - Upload firmware binary at address <addr> to "
493 "\twith optional length <length> verification."