MLK-16678-2: ASoC: fsl_hifi4: move hifi4 firmware to SDRAM
authorWeiguang Kong <weiguang.kong@nxp.com>
Mon, 23 Oct 2017 01:42:08 +0000 (09:42 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:39:00 +0000 (15:39 -0500)
move hifi4 dsp firmware's code and data section to SDRAM space
move hifi4 dsp codec lib's code section to SDRAM space

Signed-off-by: Weiguang Kong <weiguang.kong@nxp.com>
sound/soc/fsl/fsl_hifi4.c
sound/soc/fsl/fsl_hifi4.h

index 08dd38f..51b7a2b 100644 (file)
@@ -1952,25 +1952,28 @@ static void hifi4_load_firmware(const struct firmware *fw, void *context)
 
                sh_addr = shdr->sh_addr;
 
-               if ((!strcmp(&strtab[shdr->sh_name], ".rodata")) ||
-                   (!strcmp(&strtab[shdr->sh_name], ".text"))   ||
-                   (!strcmp(&strtab[shdr->sh_name], ".data"))   ||
-                   (!strcmp(&strtab[shdr->sh_name], ".bss"))
-                  ) {
-                       sh_addr = shdr->sh_addr + MEMORY_REMAP_OFFSET;
-               }
-
                if (shdr->sh_type == SHT_NOBITS) {
-                       memset_hifi((void *)(hifi4_priv->regs +
-                                       (sh_addr - hifi4_priv->paddr)),
-                                       0,
-                                       shdr->sh_size);
+                       memset_hifi((void *)(hifi4_priv->sdram_vir_addr +
+                               (sh_addr - hifi4_priv->sdram_phys_addr)),
+                               0,
+                               shdr->sh_size);
                } else {
                        image = (unsigned char *)addr + shdr->sh_offset;
-                       memcpy_hifi((void *)(hifi4_priv->regs +
-                                       (sh_addr - hifi4_priv->paddr)),
-                                       (const void *)image,
-                                       shdr->sh_size);
+                       if ((!strcmp(&strtab[shdr->sh_name], ".rodata")) ||
+                               (!strcmp(&strtab[shdr->sh_name], ".text"))   ||
+                               (!strcmp(&strtab[shdr->sh_name], ".data"))   ||
+                               (!strcmp(&strtab[shdr->sh_name], ".bss"))
+                       ) {
+                               memcpy_hifi((void *)(hifi4_priv->sdram_vir_addr
+                                 + (sh_addr - hifi4_priv->sdram_phys_addr)),
+                                 (const void *)image,
+                                 shdr->sh_size);
+                       } else {
+                               memcpy_hifi((void *)(hifi4_priv->regs +
+                                               (sh_addr - hifi4_priv->paddr)),
+                                               (const void *)image,
+                                               shdr->sh_size);
+                       }
                }
        }
 
@@ -2091,7 +2094,7 @@ static int fsl_hifi4_probe(struct platform_device *pdev)
        }
 
        sciErr = sc_misc_set_control(hifi4_priv->hifi_ipcHandle, SC_R_HIFI,
-                               SC_C_OFS_AUDIO, 0x20);
+                               SC_C_OFS_AUDIO, 0x80);
        if (sciErr != SC_ERR_NONE) {
                dev_err(&pdev->dev, "Error system address offset of AUDIO\n");
                return -EIO;
@@ -2129,10 +2132,20 @@ static int fsl_hifi4_probe(struct platform_device *pdev)
                return ret;
        }
 
+       hifi4_priv->sdram_phys_addr = SDRAM_BASE_ADDR;
+       hifi4_priv->sdram_vir_addr = ioremap(hifi4_priv->sdram_phys_addr,
+                                                       SDRAM_BASE_SIZE);
+       if (!hifi4_priv->sdram_vir_addr) {
+               dev_err(&pdev->dev, "failed to remap sdram space for hifi4 firmware\n");
+               return -ENXIO;
+       }
+       memset_io(hifi4_priv->sdram_vir_addr, 0, SDRAM_BASE_SIZE);
+
        /* code buffer */
-       hifi4_priv->code_buf_virt = hifi4_priv->regs  + LIBRARY_CODE_OFFSET;
-       hifi4_priv->code_buf_phys = hifi4_priv->paddr + LIBRARY_CODE_OFFSET -
-                                                       MEMORY_REMAP_OFFSET;
+       hifi4_priv->code_buf_virt = hifi4_priv->sdram_vir_addr
+                                               + SDRAM_CODEC_LIB_OFFSET;
+       hifi4_priv->code_buf_phys = hifi4_priv->sdram_phys_addr
+                                               + SDRAM_CODEC_LIB_OFFSET;
        hifi4_priv->code_buf_size = LIBRARY_CODE_SIZE;
 
        size = MSG_BUF_SIZE + INPUT_BUF_SIZE +
@@ -2216,6 +2229,8 @@ static int fsl_hifi4_remove(struct platform_device *pdev)
                        SCRATCH_DATA_BUF_SIZE;
        dma_free_coherent(&pdev->dev, size, hifi4_priv->msg_buf_virt,
                                hifi4_priv->msg_buf_phys);
+       if (hifi4_priv->sdram_vir_addr)
+               iounmap(hifi4_priv->sdram_vir_addr);
 
        return 0;
 }
index 04e52df..ee52119 100644 (file)
@@ -206,6 +206,8 @@ struct fsl_hifi4 {
        unsigned long                   dram1;
        unsigned long                   iram;
        unsigned long                   sram;
+       void                            *sdram_vir_addr;
+       unsigned long                   sdram_phys_addr;
        void                            *msg_buf_virt;
        dma_addr_t                       msg_buf_phys;
        int                              msg_buf_size;
@@ -302,6 +304,14 @@ struct hifi4_mem_msg {
 
 #define MEMORY_REMAP_OFFSET    0x39000000
 
+/* reserved memory for hifi4 firmware and core libs to
+ * save their instruction/data section in SDRAM, the physical
+ * address range is 0x8e000000 ~ 0x8fffffff (32M bytes).
+ */
+#define SDRAM_BASE_ADDR  0x8e000000
+#define SDRAM_BASE_SIZE  0x1ffffff
+#define SDRAM_CODEC_LIB_OFFSET 0x1000000
+
 #define SC_C_OFS_SEL    39
 #define SC_C_OFS_AUDIO  40
 #define SC_C_OFS_PERIPH 41