Skip to content

Commit

Permalink
ASoC: Intel: Fix Audio DSP usage when IOMMU is enabled.
Browse files Browse the repository at this point in the history
The Intel IOMMU requires that the ACPI device is used to allocate all
DMA memory buffers. This means we need to pass the DMA device pointer into child
component devices that allocate DMA memory.

We also only set the DMA mask for the ACPI device now instead of for each
component device.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
  • Loading branch information
Liam Girdwood authored and Mark Brown committed May 2, 2014
1 parent 0b708c8 commit 10df350
Show file tree
Hide file tree
Showing 7 changed files with 12 additions and 15 deletions.
1 change: 1 addition & 0 deletions sound/soc/intel/sst-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ static int sst_acpi_probe(struct platform_device *pdev)

sst_pdata = &sst_acpi->sst_pdata;
sst_pdata->id = desc->sst_id;
sst_pdata->dma_dev = dev;
sst_acpi->desc = desc;
sst_acpi->mach = mach;

Expand Down
1 change: 1 addition & 0 deletions sound/soc/intel/sst-dsp-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ struct sst_dsp {
spinlock_t spinlock; /* IPC locking */
struct mutex mutex; /* DSP FW lock */
struct device *dev;
struct device *dma_dev;
void *thread_context;
int irq;
u32 id;
Expand Down
1 change: 1 addition & 0 deletions sound/soc/intel/sst-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ struct sst_dsp *sst_dsp_new(struct device *dev,
spin_lock_init(&sst->spinlock);
mutex_init(&sst->mutex);
sst->dev = dev;
sst->dma_dev = pdata->dma_dev;
sst->thread_context = sst_dev->thread_context;
sst->sst_dev = sst_dev;
sst->id = pdata->id;
Expand Down
1 change: 1 addition & 0 deletions sound/soc/intel/sst-dsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ struct sst_pdata {
u32 dma_base;
u32 dma_size;
int dma_engine;
struct device *dma_dev;

/* DSP */
u32 id;
Expand Down
10 changes: 2 additions & 8 deletions sound/soc/intel/sst-firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,8 @@ struct sst_fw *sst_fw_new(struct sst_dsp *dsp,
sst_fw->private = private;
sst_fw->size = fw->size;

err = dma_coerce_mask_and_coherent(dsp->dev, DMA_BIT_MASK(32));
if (err < 0) {
kfree(sst_fw);
return NULL;
}

/* allocate DMA buffer to store FW data */
sst_fw->dma_buf = dma_alloc_coherent(dsp->dev, sst_fw->size,
sst_fw->dma_buf = dma_alloc_coherent(dsp->dma_dev, sst_fw->size,
&sst_fw->dmable_fw_paddr, GFP_DMA | GFP_KERNEL);
if (!sst_fw->dma_buf) {
dev_err(dsp->dev, "error: DMA alloc failed\n");
Expand Down Expand Up @@ -106,7 +100,7 @@ void sst_fw_free(struct sst_fw *sst_fw)
list_del(&sst_fw->list);
mutex_unlock(&dsp->mutex);

dma_free_coherent(dsp->dev, sst_fw->size, sst_fw->dma_buf,
dma_free_coherent(dsp->dma_dev, sst_fw->size, sst_fw->dma_buf,
sst_fw->dmable_fw_paddr);
kfree(sst_fw);
}
Expand Down
4 changes: 2 additions & 2 deletions sound/soc/intel/sst-haswell-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
int ret = -ENODEV, i, j, region_count;
u32 offset, size;

dev = sst->dev;
dev = sst->dma_dev;

switch (sst->id) {
case SST_DEV_ID_LYNX_POINT:
Expand Down Expand Up @@ -466,7 +466,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
return ret;
}

ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(31));
if (ret)
return ret;

Expand Down
9 changes: 4 additions & 5 deletions sound/soc/intel/sst-haswell-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,17 +633,16 @@ static void hsw_pcm_free(struct snd_pcm *pcm)
static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_pcm *pcm = rtd->pcm;
struct snd_soc_platform *platform = rtd->platform;
struct sst_pdata *pdata = dev_get_platdata(platform->dev);
struct device *dev = pdata->dma_dev;
int ret = 0;

ret = dma_coerce_mask_and_coherent(rtd->card->dev, DMA_BIT_MASK(32));
if (ret)
return ret;

if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
SNDRV_DMA_TYPE_DEV_SG,
rtd->card->dev,
dev,
hsw_pcm_hardware.buffer_bytes_max,
hsw_pcm_hardware.buffer_bytes_max);
if (ret) {
Expand Down

0 comments on commit 10df350

Please sign in to comment.