summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/sst-haswell-dsp.c
diff options
context:
space:
mode:
authorLiam Girdwood <liam.r.girdwood@linux.intel.com>2014-10-28 17:37:12 +0000
committerMark Brown <broonie@kernel.org>2014-10-28 22:25:02 +0000
commite9600bc166d529cf03862afae51fb2e3cf987d02 (patch)
treec85a52b6ebdd39c244a7881a320da540406559ff /sound/soc/intel/sst-haswell-dsp.c
parent9a80e8f597f3bde0e1d4a4abb021d475520005a5 (diff)
downloadop-kernel-dev-e9600bc166d529cf03862afae51fb2e3cf987d02.zip
op-kernel-dev-e9600bc166d529cf03862afae51fb2e3cf987d02.tar.gz
ASoC: Intel: Make ADSP memory block allocation more generic
Current block allocation is tied to block type and requestor type. Make the allocation more generic by removing the struct module parameter and adding a generic block allocator structure. Also pass in the list that the blocks have to be added too in order to remove dependence on block requestor type. ASoC: Intel: update scratch allocator to use generic block allocator Update the scratch allocator to use the generic block allocator and calculate total scratch buffer size. ASoC: Intel: Add call to calculate offsets internally within the DSP. A call to calculate internal DSP memory addresses used to allocate persistent and scartch buffers. ASoC: Intel: Add runtime module support. Add support for runtime module objects that can be created for every FW module that is parsed from the FW file. This gives a 1:N mapping between the FW module from file and the runtime instantiations of that module. We also need to make sure we remove every module and runtime module when we unload the FW. ASoC: Intel: Add DMA firmware loading support Add support for DMA to load firmware modules to the DSP memory blocks. Two DMA engines are supported, DesignWare and Intel MID. ASoC: Intel: Add runtime module lookup API call Add an API to allow quick lookup of runtime modules based on ID. ASoC: Intel: Provide streams with dynamic module information Remove the hard coded module paramaters and provide each module with dynamically generated buffer information for scratch and persistent buffers. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/sst-haswell-dsp.c')
-rw-r--r--sound/soc/intel/sst-haswell-dsp.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c
index 4b6c163..5058dc8 100644
--- a/sound/soc/intel/sst-haswell-dsp.c
+++ b/sound/soc/intel/sst-haswell-dsp.c
@@ -42,6 +42,10 @@
#define SST_LP_SHIM_OFFSET 0xE7000
#define SST_WPT_IRAM_OFFSET 0xA0000
#define SST_LP_IRAM_OFFSET 0x80000
+#define SST_WPT_DSP_DRAM_OFFSET 0x400000
+#define SST_WPT_DSP_IRAM_OFFSET 0x00000
+#define SST_LPT_DSP_DRAM_OFFSET 0x400000
+#define SST_LPT_DSP_IRAM_OFFSET 0x00000
#define SST_SHIM_PM_REG 0x84
@@ -86,9 +90,8 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
{
struct dma_block_info *block;
struct sst_module *mod;
- struct sst_module_data block_data;
struct sst_module_template template;
- int count;
+ int count, ret;
void __iomem *ram;
/* TODO: allowed module types need to be configurable */
@@ -109,13 +112,9 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
memset(&template, 0, sizeof(template));
template.id = module->type;
- template.entry = module->entry_point;
- template.p.size = module->info.persistent_size;
- template.p.type = SST_MEM_DRAM;
- template.p.data_type = SST_DATA_P;
- template.s.size = module->info.scratch_size;
- template.s.type = SST_MEM_DRAM;
- template.s.data_type = SST_DATA_S;
+ template.entry = module->entry_point - 4;
+ template.persistent_size = module->info.persistent_size;
+ template.scratch_size = module->info.scratch_size;
mod = sst_module_new(fw, &template, NULL);
if (mod == NULL)
@@ -135,14 +134,14 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
switch (block->type) {
case SST_HSW_IRAM:
ram = dsp->addr.lpe;
- block_data.offset =
+ mod->offset =
block->ram_offset + dsp->addr.iram_offset;
- block_data.type = SST_MEM_IRAM;
+ mod->type = SST_MEM_IRAM;
break;
case SST_HSW_DRAM:
ram = dsp->addr.lpe;
- block_data.offset = block->ram_offset;
- block_data.type = SST_MEM_DRAM;
+ mod->offset = block->ram_offset;
+ mod->type = SST_MEM_DRAM;
break;
default:
dev_err(dsp->dev, "error: bad type 0x%x for block 0x%x\n",
@@ -151,30 +150,34 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
return -EINVAL;
}
- block_data.size = block->size;
- block_data.data_type = SST_DATA_M;
- block_data.data = (void *)block + sizeof(*block);
- block_data.data_offset = block_data.data - fw->dma_buf;
+ mod->size = block->size;
+ mod->data = (void *)block + sizeof(*block);
+ mod->data_offset = mod->data - fw->dma_buf;
- dev_dbg(dsp->dev, "copy firmware block %d type 0x%x "
+ dev_dbg(dsp->dev, "module block %d type 0x%x "
"size 0x%x ==> ram %p offset 0x%x\n",
- count, block->type, block->size, ram,
+ count, mod->type, block->size, ram,
block->ram_offset);
- sst_module_insert_fixed_block(mod, &block_data);
+ ret = sst_module_alloc_blocks(mod);
+ if (ret < 0) {
+ dev_err(dsp->dev, "error: could not allocate blocks for module %d\n",
+ count);
+ sst_module_free(mod);
+ return ret;
+ }
block = (void *)block + sizeof(*block) + block->size;
}
+
return 0;
}
static int hsw_parse_fw_image(struct sst_fw *sst_fw)
{
struct fw_header *header;
- struct sst_module *scratch;
struct fw_module_header *module;
struct sst_dsp *dsp = sst_fw->dsp;
- struct sst_hsw *hsw = sst_fw->private;
int ret, count;
/* Read the header information from the data pointer */
@@ -204,12 +207,8 @@ static int hsw_parse_fw_image(struct sst_fw *sst_fw)
module = (void *)module + sizeof(*module) + module->mod_size;
}
- /* allocate persistent/scratch mem regions */
- scratch = sst_mem_block_alloc_scratch(dsp);
- if (scratch == NULL)
- return -ENOMEM;
-
- sst_hsw_set_scratch_module(hsw, scratch);
+ /* allocate scratch mem regions */
+ sst_block_alloc_scratch(dsp);
return 0;
}
@@ -467,12 +466,16 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
region = lp_region;
region_count = ARRAY_SIZE(lp_region);
sst->addr.iram_offset = SST_LP_IRAM_OFFSET;
+ sst->addr.dsp_iram_offset = SST_LPT_DSP_IRAM_OFFSET;
+ sst->addr.dsp_dram_offset = SST_LPT_DSP_DRAM_OFFSET;
sst->addr.shim_offset = SST_LP_SHIM_OFFSET;
break;
case SST_DEV_ID_WILDCAT_POINT:
region = wpt_region;
region_count = ARRAY_SIZE(wpt_region);
sst->addr.iram_offset = SST_WPT_IRAM_OFFSET;
+ sst->addr.dsp_iram_offset = SST_WPT_DSP_IRAM_OFFSET;
+ sst->addr.dsp_dram_offset = SST_WPT_DSP_DRAM_OFFSET;
sst->addr.shim_offset = SST_WPT_SHIM_OFFSET;
break;
default:
OpenPOWER on IntegriCloud