X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fqe%2Fqe.c;h=4231594776a6c71dc5fc615ca27c0495da6a021e;hb=6f88a3a5d9488bc0aed5a62ca5f2a3cda4deded9;hp=bc946731a1eb20aa670722a9bdde67efb1d20eee;hpb=5632d15cf45a6e9f0559c80e1ca675d64f1650bc;p=oweals%2Fu-boot.git diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index bc946731a1..4231594776 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -7,17 +7,22 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include "common.h" +#include #include -#include "asm/errno.h" -#include "asm/io.h" -#include "linux/immap_qe.h" -#include "qe.h" +#include +#include +#include +#include +#ifdef CONFIG_LS102XA +#include +#endif #define MPC85xx_DEVDISR_QE_DISABLE 0x1 qe_map_t *qe_immr = NULL; +#ifdef CONFIG_QE static qe_snum_t snums[QE_NUM_OF_SNUM]; +#endif DECLARE_GLOBAL_DATA_PTR; @@ -78,6 +83,7 @@ void *qe_muram_addr(uint offset) return (void *)&qe_immr->muram[offset]; } +#ifdef CONFIG_QE static void qe_sdma_init(void) { volatile sdma_t *p; @@ -181,24 +187,36 @@ void qe_init(uint qe_base) qe_sdma_init(); qe_snums_init(); } +#endif #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_immr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET); u_qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR); out_be32(&qe_immr->iram.iready, QE_IRAM_READY); } #endif +#ifdef CONFIG_U_QE +void u_qe_resume(void) +{ + qe_map_t *qe_immrr; + + qe_immrr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET); + u_qe_firmware_resume((const void *)CONFIG_SYS_QE_FW_ADDR, qe_immrr); + out_be32(&qe_immrr->iram.iready, QE_IRAM_READY); +} +#endif + void qe_reset(void) { qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID, (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0); } +#ifdef CONFIG_QE void qe_assign_page(uint snum, uint para_ram_base) { u32 cecr; @@ -214,6 +232,7 @@ void qe_assign_page(uint snum, uint para_ram_base) return; } +#endif /* * brg: 0~15 as BRG1~BRG16 @@ -298,9 +317,10 @@ static void qe_upload_microcode(const void *base, if (ucode->major || ucode->minor || ucode->revision) printf("QE: uploading microcode '%s' version %u.%u.%u\n", - ucode->id, ucode->major, ucode->minor, ucode->revision); + (char *)ucode->id, (u16)ucode->major, (u16)ucode->minor, + (u16)ucode->revision); else - printf("QE: uploading microcode '%s'\n", ucode->id); + printf("QE: uploading microcode '%s'\n", (char *)ucode->id); /* Use auto-increment */ out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) | @@ -335,7 +355,11 @@ int qe_upload_firmware(const struct qe_firmware *firmware) size_t length; const struct qe_header *hdr; #ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_LS102XA + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; +#else ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +#endif #endif if (!firmware) { printf("Invalid address\n"); @@ -415,7 +439,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware) * saved microcode information and put in the new. */ memset(&qe_firmware_info, 0, sizeof(qe_firmware_info)); - strcpy(qe_firmware_info.id, (char *)firmware->id); + strncpy(qe_firmware_info.id, (char *)firmware->id, 62); qe_firmware_info.extended_modes = firmware->extended_modes; memcpy(qe_firmware_info.vtraps, firmware->vtraps, sizeof(firmware->vtraps)); @@ -470,7 +494,11 @@ int u_qe_upload_firmware(const struct qe_firmware *firmware) size_t length; const struct qe_header *hdr; #ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_LS102XA + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; +#else ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +#endif #endif if (!firmware) { printf("Invalid address\n"); @@ -569,6 +597,76 @@ int u_qe_upload_firmware(const struct qe_firmware *firmware) } #endif +#ifdef CONFIG_U_QE +int u_qe_firmware_resume(const struct qe_firmware *firmware, qe_map_t *qe_immrr) +{ + unsigned int i; + unsigned int j; + const struct qe_header *hdr; + const u32 *code; +#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_PPC + ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +#else + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; +#endif +#endif + + if (!firmware) + return -EINVAL; + + hdr = &firmware->header; + + /* Check the magic */ + if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || + (hdr->magic[2] != 'F')) { +#ifdef CONFIG_DEEP_SLEEP + setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE); +#endif + return -EPERM; + } + + /* + * If the microcode calls for it, split the I-RAM. + */ + if (!firmware->split) { + out_be16(&qe_immrr->cp.cercr, + in_be16(&qe_immrr->cp.cercr) | QE_CP_CERCR_CIR); + } + + /* 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) + return 0; + + code = (const void *)firmware + be32_to_cpu(ucode->code_offset); + + /* Use auto-increment */ + out_be32(&qe_immrr->iram.iadd, be32_to_cpu(ucode->iram_offset) | + QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); + + for (i = 0; i < be32_to_cpu(ucode->count); i++) + out_be32(&qe_immrr->iram.idata, be32_to_cpu(code[i])); + + /* 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_immrr->rsp[i].tibcr[j], trap); + } + + /* Enable traps */ + out_be32(&qe_immrr->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;