summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/imx-pcm-dma-v2.c
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2018-08-14 17:06:08 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:51:27 +0800
commit6ee22f9f6d6cd427d2b4ba4446d9de9858daaf8a (patch)
tree1c14e0aec29e1050f2371b2de76ab35dc5b14135 /sound/soc/fsl/imx-pcm-dma-v2.c
parent7047fb026bdb3128e2f8d5407210f66eb85623ed (diff)
MLK-18947: ASoC: imx-pcm-dma: alloc buffer from IRAM
In some platform, the low power audio playback should be supported, which need the audio buffer allocated from OCRAM/IRAM. So move the buffer allocation to .open function at that time the dma chan is allocated. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> (cherry picked from commit 85c59acfc5c8d17aa0f369dbe30e4a5fb128c25f)
Diffstat (limited to 'sound/soc/fsl/imx-pcm-dma-v2.c')
-rw-r--r--sound/soc/fsl/imx-pcm-dma-v2.c102
1 files changed, 39 insertions, 63 deletions
diff --git a/sound/soc/fsl/imx-pcm-dma-v2.c b/sound/soc/fsl/imx-pcm-dma-v2.c
index f8e89588b8e2..4c38efbbf907 100644
--- a/sound/soc/fsl/imx-pcm-dma-v2.c
+++ b/sound/soc/fsl/imx-pcm-dma-v2.c
@@ -99,6 +99,28 @@ static snd_pcm_uframes_t imx_pcm_pointer(struct snd_pcm_substream *substream)
return snd_dmaengine_pcm_pointer(substream);
}
+static int imx_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
+ struct device *dev)
+{
+ size_t size = imx_pcm_hardware.buffer_bytes_max;
+ int ret;
+
+ ret = snd_pcm_lib_preallocate_pages(substream,
+ SNDRV_DMA_TYPE_DEV_IRAM,
+ dev,
+ size,
+ size);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int imx_pcm_free_dma_buffers(struct snd_pcm_substream *substream)
+{
+ return snd_pcm_lib_preallocate_free(substream);
+}
+
static int imx_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -185,6 +207,10 @@ static int imx_pcm_open(struct snd_pcm_substream *substream)
snd_soc_set_runtime_hwparams(substream, &imx_pcm_hardware);
+ ret = imx_pcm_preallocate_dma_buffer(substream, chan->device->dev);
+ if (ret)
+ return ret;
+
ret = snd_pcm_hw_constraint_integer(substream->runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0)
@@ -204,9 +230,20 @@ static int imx_pcm_mmap(struct snd_pcm_substream *substream,
runtime->dma_bytes);
}
+static int imx_pcm_close(struct snd_pcm_substream *substream)
+{
+ int ret;
+
+ ret = imx_pcm_free_dma_buffers(substream);
+ if (ret)
+ return ret;
+
+ return snd_dmaengine_pcm_close_release_chan(substream);
+}
+
static struct snd_pcm_ops imx_pcm_ops = {
.open = imx_pcm_open,
- .close = snd_dmaengine_pcm_close_release_chan,
+ .close = imx_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = imx_pcm_hw_params,
.hw_free = imx_pcm_hw_free,
@@ -215,82 +252,21 @@ static struct snd_pcm_ops imx_pcm_ops = {
.mmap = imx_pcm_mmap,
};
-static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
- int stream)
-{
- struct snd_pcm_substream *substream = pcm->streams[stream].substream;
- struct snd_dma_buffer *buf = &substream->dma_buffer;
- size_t size = imx_pcm_hardware.buffer_bytes_max;
-
- buf->dev.type = SNDRV_DMA_TYPE_DEV;
- buf->dev.dev = pcm->card->dev;
- buf->private_data = NULL;
- buf->area = dma_alloc_writecombine(pcm->card->dev, size,
- &buf->addr, GFP_KERNEL);
- if (!buf->area)
- return -ENOMEM;
-
- buf->bytes = size;
- return 0;
-}
-
-static void imx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- struct snd_dma_buffer *buf;
- int stream;
-
- for (stream = SNDRV_PCM_STREAM_PLAYBACK; stream < SNDRV_PCM_STREAM_LAST; stream++) {
- substream = pcm->streams[stream].substream;
- if (!substream)
- continue;
-
- buf = &substream->dma_buffer;
- if (!buf->area)
- continue;
-
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
-}
-
static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- int ret;
+ int ret = 0;
ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
if (ret)
return ret;
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = imx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_PLAYBACK);
- if (ret)
- goto out;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = imx_pcm_preallocate_dma_buffer(pcm,
- SNDRV_PCM_STREAM_CAPTURE);
- if (ret)
- goto out;
- }
-
-out:
- /* free preallocated buffers in case of error */
- if (ret)
- imx_pcm_free_dma_buffers(pcm);
-
return ret;
}
static struct snd_soc_component_driver imx_soc_platform = {
.ops = &imx_pcm_ops,
.pcm_new = imx_pcm_new,
- .pcm_free = imx_pcm_free_dma_buffers,
};
int imx_pcm_platform_register(struct device *dev)