u_qe: add u_qe_upload_firmware for u_qe
PATCH v2 1/1 u_qe: add u_qe_upload_firmware for u_qe
Signed-off-by Zhao Qiang <[email protected]>
---
Changes for v2:
- put u_qe functions under "#ifdef CONFIG_U_QE"
drivers/qe/qe.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- drivers/qe/qe.h | 6 ++- 2 files changed, 133 insertions(+), 2 deletions(-)
drivers/qe/qe.c +128 -1
@@ -182,14 +182,16 @@ void qe_init(uint qe_base)qe_snums_init (); } +#ifdef CONFIG_U_QE void u_qe_init (void ) {uint qe_base =CONFIG_SYS_IMMR +0x01400000 ;/* QE immr base */ qe_immr = (qe_map_t *)qe_base; -qe_upload_firmware ((const void *)CONFIG_SYS_QE_FW_ADDR ); +u_qe_upload_firmware ((const void *)CONFIG_SYS_QE_FW_ADDR );out_be32 (&qe_immr->iram.iready,QE_IRAM_READY ); } +#endif void qe_reset (void ) {
@@ -442,6 +444,131 @@ int qe_upload_firmware(const struct qe_firmware *firmware)return 0 ; } +#ifdef CONFIG_U_QE +/* +* Upload a microcode to the I-RAM at a specific address. +* +* See docs/README.qe_firmware for information on QE microcode uploading. +* +* Currently, only version 1 is supported, so the 'version' field must be +* set to 1. +* +* The SOC model and revision are not validated, they are only displayed for +* informational purposes. +* +* 'calc_size' is the calculated size, in bytes, of the firmware structure and +* all of the microcode structures, minus the CRC. +* +* 'length' is the size that the structure says it is, including the CRC. +*/ +int u_qe_upload_firmware (const struct qe_firmware *firmware) +{ +unsigned int i; +unsigned int j; +u32 crc; +size_t calc_size =sizeof (struct qe_firmware ); +size_t length; +const struct qe_header *hdr; +#ifdef CONFIG_DEEP_SLEEP +ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +#endif +if (!firmware) { +printf ("Invalid address\n" ); +return -EINVAL ; + } + + hdr = &firmware->header; + length =be32_to_cpu (hdr->length); + +/* Check the magic */ +if ((hdr->magic[0 ] !='Q' ) || (hdr->magic[1 ] !='E' ) || + (hdr->magic[2 ] !='F' )) { +printf ("Not a microcode\n" ); +#ifdef CONFIG_DEEP_SLEEP +setbits_be32 (&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE); +#endif +return -EPERM ; + } + +/* Check the version */ +if (hdr->version !=1 ) { +printf ("Unsupported version\n" ); +return -EPERM ; + } + +/* Validate some of the fields */ +if ((firmware->count <1 ) || (firmware->count >MAX_QE_RISC )) { +printf ("Invalid data\n" ); +return -EINVAL ; + } + +/* Validate the length and check if there's a CRC */ + calc_size += (firmware->count -1 ) *sizeof (struct qe_microcode ); + +for (i =0 ; i < firmware->count; i++) +/* +* For situations where the second RISC uses the same microcode +* as the first, the 'code_offset' and 'count' fields will be +* zero, so it's okay to add those. +*/ + calc_size +=sizeof (u32) * +be32_to_cpu (firmware->microcode[i].count); + +/* Validate the length */ +if (length != calc_size +sizeof (u32)) { +printf ("Invalid length\n" ); +return -EPERM ; + } + +/* +* Validate the CRC. We would normally call crc32_no_comp(), but that +* function isn't available unless you turn on JFFS support. +*/ + crc =be32_to_cpu (*(u32 *)((void *)firmware + calc_size)); +if (crc != (crc32 (-1 , (const void *)firmware, calc_size) ^-1 )) { +printf ("Firmware CRC is invalid\n" ); +return -EIO ; + } + +/* +* If the microcode calls for it, split the I-RAM. +*/ +if (!firmware->split) { +out_be16 (&qe_immr->cp.cercr, +in_be16 (&qe_immr->cp.cercr) |QE_CP_CERCR_CIR ); + } + +if (firmware->soc.model) +printf ("Firmware '%s' for %u V%u.%u\n" , + firmware->id,be16_to_cpu (firmware->soc.model), + firmware->soc.major, firmware->soc.minor); +else +printf ("Firmware '%s'\n" , firmware->id); + +/* Loop through each microcode. */ +for (i =0 ; i < firmware->count; i++) { +const struct qe_microcode *ucode = &firmware->microcode[i]; + +/* Upload a microcode if it's present */ +if (ucode->code_offset) +qe_upload_microcode (firmware, ucode); + +/* Program the traps for this processor */ +for (j =0 ; j <16 ; j++) { +u32 trap =be32_to_cpu (ucode->traps[j]); + +if (trap) +out_be32 (&qe_immr->rsp[i].tibcr[j], trap); + } + +/* Enable traps */ +out_be32 (&qe_immr->rsp[i].eccr,be32_to_cpu (ucode->eccr)); + } + +return 0 ; +} +#endif +struct qe_firmware_info *qe_get_firmware_info (void ) {return qe_firmware_uploaded ? &qe_firmware_info :NULL ;
drivers/qe/qe.h +5 -1
@@ -275,7 +275,6 @@ void *qe_muram_addr(uint offset);int qe_get_snum (void );void qe_put_snum (u8 snum);void qe_init (uint qe_base); -void u_qe_init (void );void qe_reset (void );void qe_assign_page (uint snum,uint para_ram_base);int qe_set_brg (uint brg,uint rate);
@@ -286,4 +285,9 @@ void ft_qe_setup(void *blob);void qe_init (uint qe_base);void qe_reset (void ); +#ifdef CONFIG_U_QE +void u_qe_init (void ); +int u_qe_upload_firmware (const struct qe_firmware *firmware); +#endif +#endif /* __QE_H__ */
Signature · 1 line
2.1.0.27.g96db324
PATCH v2 1/1 u_qe: add u_qe_upload_firmware for u_qe
Quoted 9 lines · Zhao Qiang
Signed-off-by Zhao Qiang <[email protected]>---
Changes for v2:
- putu_qefunctions under "#ifdefCONFIG_U_QE"drivers/qe/qe.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- drivers/qe/qe.h | 6 ++- 2 files changed, 133 insertions(+), 2 deletions(-)
Applied to u-boot-fsl-qoriq master. Awaiting upstream. Thanks.
York