summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/sst-haswell-pcm.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-pcm.c
parent9a80e8f597f3bde0e1d4a4abb021d475520005a5 (diff)
downloadlinux-e9600bc166d529cf03862afae51fb2e3cf987d02.tar.bz2
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-pcm.c')
-rw-r--r--sound/soc/intel/sst-haswell-pcm.c83
1 files changed, 61 insertions, 22 deletions
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c
index 32a6470ae38a..522edef20c86 100644
--- a/sound/soc/intel/sst-haswell-pcm.c
+++ b/sound/soc/intel/sst-haswell-pcm.c
@@ -89,16 +89,23 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = {
.buffer_bytes_max = HSW_PCM_PERIODS_MAX * PAGE_SIZE,
};
+struct hsw_pcm_module_map {
+ int dai_id;
+ enum sst_hsw_module_id mod_id;
+};
+
/* private data for each PCM DSP stream */
struct hsw_pcm_data {
int dai_id;
struct sst_hsw_stream *stream;
+ struct sst_module_runtime *runtime;
u32 volume[2];
struct snd_pcm_substream *substream;
struct snd_compr_stream *cstream;
unsigned int wpos;
struct mutex mutex;
bool allocated;
+ int persistent_offset;
};
/* private data for the driver */
@@ -472,28 +479,8 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- /* we use hardcoded memory offsets atm, will be updated for new FW */
- if (stream_type == SST_HSW_STREAM_TYPE_CAPTURE) {
- sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
- SST_HSW_MODULE_PCM_CAPTURE, module_data->entry);
- sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
- 0x449400, 0x4000);
- sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
- 0x400000, 0);
- } else { /* stream_type == SST_HSW_STREAM_TYPE_SYSTEM */
- sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
- SST_HSW_MODULE_PCM_SYSTEM, module_data->entry);
-
- sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
- module_data->offset, module_data->size);
- sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
- 0x44d400, 0x3800);
-
- sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
- module_data->offset, module_data->size);
- sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
- 0x400000, 0);
- }
+ sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
+ pcm_data->runtime);
ret = sst_hsw_stream_commit(hsw, pcm_data->stream);
if (ret < 0) {
@@ -654,6 +641,55 @@ static struct snd_pcm_ops hsw_pcm_ops = {
.page = snd_pcm_sgbuf_ops_page,
};
+/* static mappings between PCMs and modules - may be dynamic in future */
+static struct hsw_pcm_module_map mod_map[] = {
+ {0, SST_HSW_MODULE_PCM_SYSTEM}, /* "System Pin" */
+ {1, SST_HSW_MODULE_PCM}, /* "Offload0 Pin" */
+ {2, SST_HSW_MODULE_PCM}, /* "Offload1 Pin" */
+ {3, SST_HSW_MODULE_PCM_REFERENCE}, /* "Loopback Pin" */
+ {4, SST_HSW_MODULE_PCM_CAPTURE}, /* "Capture Pin" */
+};
+
+static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
+{
+ struct sst_hsw *hsw = pdata->hsw;
+ struct hsw_pcm_data *pcm_data;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
+ pcm_data = &pdata->pcm[i];
+
+ pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
+ mod_map[i].mod_id, pcm_data->persistent_offset);
+ if (pcm_data->runtime == NULL)
+ goto err;
+ pcm_data->persistent_offset =
+ pcm_data->runtime->persistent_offset;
+ }
+
+ return 0;
+
+err:
+ for (--i; i >= 0; i--) {
+ pcm_data = &pdata->pcm[i];
+ sst_hsw_runtime_module_free(pcm_data->runtime);
+ }
+
+ return -ENODEV;
+}
+
+static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
+{
+ struct hsw_pcm_data *pcm_data;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
+ pcm_data = &pdata->pcm[i];
+
+ sst_hsw_runtime_module_free(pcm_data->runtime);
+ }
+}
+
static void hsw_pcm_free(struct snd_pcm *pcm)
{
snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -797,6 +833,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
}
}
+ /* allocate runtime modules */
+ hsw_pcm_create_modules(priv_data);
+
return 0;
err: