Message ID | 20200528021121.28987-19-hui.wang@canonical.com |
---|---|
State | New |
Headers | show |
Series | ASoC/amd: add audio driver for amd renoir | expand |
On 2020-05-28 04:11, Hui Wang wrote: > BugLink: https://bugs.launchpad.net/bugs/1881046 > > This amd renoir driver is for kernel-5.8, after backporting to > kernel-5.4, need to do some change according to API in the > kernel-5.4, otherwise there will be building errors and runtime > errors. > > Signed-off-by: Hui Wang <hui.wang@canonical.com> Hi Hui, Would it be possible to make these fixes on the patches that introduce the code and make them a backport instead of a cherry-pick? The reason I'm asking is because adding a follow up fix keeping the original patches unable to build will break the bisectability of the code. Also, these patches were already merged on linux-next with the same SHA1, we should replace the provenance from the upstream maintainer repo to it. Otherwise it looks good to me. These are a lot of changes and adding a whole new driver to a stable release should be done carefully. However, I see the value of adding it to Focal for support of the new AMD chips. The code is also limited in scope and already on linux-next so I believe the risks are relatively low. Thanks, Kleber > --- > sound/soc/amd/renoir/acp3x-pdm-dma.c | 70 +++++++++++++++++++--------- > 1 file changed, 48 insertions(+), 22 deletions(-) > > diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c > index 623dfd3ea705..a823c4d726ff 100644 > --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c > +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c > @@ -201,12 +201,14 @@ static void config_acp_dma(struct pdm_stream_instance *rtd, int direction) > } > } > > -static int acp_pdm_dma_open(struct snd_soc_component *component, > - struct snd_pcm_substream *substream) > +static int acp_pdm_dma_open(struct snd_pcm_substream *substream) > { > struct snd_pcm_runtime *runtime; > struct pdm_dev_data *adata; > struct pdm_stream_instance *pdm_data; > + struct snd_soc_pcm_runtime *prtd = substream->private_data; > + struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, > + DRV_NAME); > int ret; > > runtime = substream->runtime; > @@ -236,24 +238,34 @@ static int acp_pdm_dma_open(struct snd_soc_component *component, > return ret; > } > > -static int acp_pdm_dma_hw_params(struct snd_soc_component *component, > - struct snd_pcm_substream *substream, > +static int acp_pdm_dma_hw_params(struct snd_pcm_substream *substream, > struct snd_pcm_hw_params *params) > { > struct pdm_stream_instance *rtd; > size_t size, period_bytes; > + int status; > > rtd = substream->runtime->private_data; > if (!rtd) > return -EINVAL; > + > size = params_buffer_bytes(params); > period_bytes = params_period_bytes(params); > - rtd->dma_addr = substream->dma_buffer.addr; > - rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); > - config_acp_dma(rtd, substream->stream); > - init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes, > - rtd->acp_base); > - return 0; > + status = snd_pcm_lib_malloc_pages(substream, size); > + if (status < 0) > + return status; > + memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); > + if (substream->dma_buffer.area) { > + rtd->dma_addr = substream->dma_buffer.addr; > + rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); > + config_acp_dma(rtd, substream->stream); > + init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes, > + rtd->acp_base); > + status = 0; > + } else > + status = -ENOMEM; > + > + return status; > } > > static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd, > @@ -270,8 +282,7 @@ static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd, > return byte_count.bytescount; > } > > -static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp, > - struct snd_pcm_substream *stream) > +static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_pcm_substream *stream) > { > struct pdm_stream_instance *rtd; > u32 pos, buffersize; > @@ -287,26 +298,29 @@ static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp, > return bytes_to_frames(stream->runtime, pos); > } > > -static int acp_pdm_dma_new(struct snd_soc_component *component, > - struct snd_soc_pcm_runtime *rtd) > +static int acp_pdm_dma_new(struct snd_soc_pcm_runtime *rtd) > { > + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, > + DRV_NAME); > struct device *parent = component->dev->parent; > > - snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, > + snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, > parent, MIN_BUFFER, MAX_BUFFER); > + > return 0; > } > > -static int acp_pdm_dma_mmap(struct snd_soc_component *component, > - struct snd_pcm_substream *substream, > +static int acp_pdm_dma_mmap(struct snd_pcm_substream *substream, > struct vm_area_struct *vma) > { > return snd_pcm_lib_default_mmap(substream, vma); > } > > -static int acp_pdm_dma_close(struct snd_soc_component *component, > - struct snd_pcm_substream *substream) > +static int acp_pdm_dma_close(struct snd_pcm_substream *substream) > { > + struct snd_soc_pcm_runtime *prtd = substream->private_data; > + struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, > + DRV_NAME); > struct pdm_dev_data *adata = dev_get_drvdata(component->dev); > > disable_pdm_interrupts(adata->acp_base); > @@ -329,6 +343,7 @@ static int acp_pdm_dai_hw_params(struct snd_pcm_substream *substream, > default: > return -EINVAL; > } > + > rn_writel(ch_mask, rtd->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); > rn_writel(PDM_DECIMATION_FACTOR, rtd->acp_base + > ACP_WOV_PDM_DECIMATION_FACTOR); > @@ -368,6 +383,11 @@ static int acp_pdm_dai_trigger(struct snd_pcm_substream *substream, > return ret; > } > > +static int acp_pdm_dma_hw_free(struct snd_pcm_substream *substream) > +{ > + return snd_pcm_lib_free_pages(substream); > +} > + > static struct snd_soc_dai_ops acp_pdm_dai_ops = { > .hw_params = acp_pdm_dai_hw_params, > .trigger = acp_pdm_dai_trigger, > @@ -386,14 +406,20 @@ static struct snd_soc_dai_driver acp_pdm_dai_driver = { > .ops = &acp_pdm_dai_ops, > }; > > -static const struct snd_soc_component_driver acp_pdm_component = { > - .name = DRV_NAME, > +static const struct snd_pcm_ops acp_pdm_ops = { > .open = acp_pdm_dma_open, > .close = acp_pdm_dma_close, > .hw_params = acp_pdm_dma_hw_params, > + .hw_free = acp_pdm_dma_hw_free, > .pointer = acp_pdm_dma_pointer, > .mmap = acp_pdm_dma_mmap, > - .pcm_construct = acp_pdm_dma_new, > +}; > + > +static const struct snd_soc_component_driver acp_pdm_component = { > + .name = DRV_NAME, > + .ops = &acp_pdm_ops, > + .pcm_new = acp_pdm_dma_new, > + > }; > > static int acp_pdm_audio_probe(struct platform_device *pdev) >
On 2020/5/29 下午3:11, Kleber Souza wrote: > On 2020-05-28 04:11, Hui Wang wrote: >> BugLink: https://bugs.launchpad.net/bugs/1881046 >> >> This amd renoir driver is for kernel-5.8, after backporting to >> kernel-5.4, need to do some change according to API in the >> kernel-5.4, otherwise there will be building errors and runtime >> errors. >> >> Signed-off-by: Hui Wang <hui.wang@canonical.com> > Hi Hui, > > Would it be possible to make these fixes on the patches that introduce > the code and make them a backport instead of a cherry-pick? The reason > I'm asking is because adding a follow up fix keeping the original patches > unable to build will break the bisectability of the code. > > Also, these patches were already merged on linux-next with the same > SHA1, we should replace the provenance from the upstream maintainer > repo to it. > > Otherwise it looks good to me. These are a lot of changes and adding > a whole new driver to a stable release should be done carefully. However, > I see the value of adding it to Focal for support of the new AMD chips. > The code is also limited in scope and already on linux-next so I believe > the risks are relatively low. OK, will do that, let us merge the patchset to OEM-5.6 and unstable first. I will re-prepare the patchset to focal. thx. > > Thanks, > Kleber > > > >> --- >> sound/soc/amd/renoir/acp3x-pdm-dma.c | 70 +++++++++++++++++++--------- >> 1 file changed, 48 insertions(+), 22 deletions(-) >> >> diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c >> index 623dfd3ea705..a823c4d726ff 100644 >> --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c >> +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c >> @@ -201,12 +201,14 @@ static void config_acp_dma(struct pdm_stream_instance *rtd, int direction) >> } >> } >> >> -static int acp_pdm_dma_open(struct snd_soc_component *component, >> - struct snd_pcm_substream *substream) >> +static int acp_pdm_dma_open(struct snd_pcm_substream *substream) >> { >> struct snd_pcm_runtime *runtime; >> struct pdm_dev_data *adata; >> struct pdm_stream_instance *pdm_data; >> + struct snd_soc_pcm_runtime *prtd = substream->private_data; >> + struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, >> + DRV_NAME); >> int ret; >> >> runtime = substream->runtime; >> @@ -236,24 +238,34 @@ static int acp_pdm_dma_open(struct snd_soc_component *component, >> return ret; >> } >> >> -static int acp_pdm_dma_hw_params(struct snd_soc_component *component, >> - struct snd_pcm_substream *substream, >> +static int acp_pdm_dma_hw_params(struct snd_pcm_substream *substream, >> struct snd_pcm_hw_params *params) >> { >> struct pdm_stream_instance *rtd; >> size_t size, period_bytes; >> + int status; >> >> rtd = substream->runtime->private_data; >> if (!rtd) >> return -EINVAL; >> + >> size = params_buffer_bytes(params); >> period_bytes = params_period_bytes(params); >> - rtd->dma_addr = substream->dma_buffer.addr; >> - rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); >> - config_acp_dma(rtd, substream->stream); >> - init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes, >> - rtd->acp_base); >> - return 0; >> + status = snd_pcm_lib_malloc_pages(substream, size); >> + if (status < 0) >> + return status; >> + memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); >> + if (substream->dma_buffer.area) { >> + rtd->dma_addr = substream->dma_buffer.addr; >> + rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); >> + config_acp_dma(rtd, substream->stream); >> + init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes, >> + rtd->acp_base); >> + status = 0; >> + } else >> + status = -ENOMEM; >> + >> + return status; >> } >> >> static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd, >> @@ -270,8 +282,7 @@ static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd, >> return byte_count.bytescount; >> } >> >> -static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp, >> - struct snd_pcm_substream *stream) >> +static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_pcm_substream *stream) >> { >> struct pdm_stream_instance *rtd; >> u32 pos, buffersize; >> @@ -287,26 +298,29 @@ static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp, >> return bytes_to_frames(stream->runtime, pos); >> } >> >> -static int acp_pdm_dma_new(struct snd_soc_component *component, >> - struct snd_soc_pcm_runtime *rtd) >> +static int acp_pdm_dma_new(struct snd_soc_pcm_runtime *rtd) >> { >> + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, >> + DRV_NAME); >> struct device *parent = component->dev->parent; >> >> - snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, >> + snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, >> parent, MIN_BUFFER, MAX_BUFFER); >> + >> return 0; >> } >> >> -static int acp_pdm_dma_mmap(struct snd_soc_component *component, >> - struct snd_pcm_substream *substream, >> +static int acp_pdm_dma_mmap(struct snd_pcm_substream *substream, >> struct vm_area_struct *vma) >> { >> return snd_pcm_lib_default_mmap(substream, vma); >> } >> >> -static int acp_pdm_dma_close(struct snd_soc_component *component, >> - struct snd_pcm_substream *substream) >> +static int acp_pdm_dma_close(struct snd_pcm_substream *substream) >> { >> + struct snd_soc_pcm_runtime *prtd = substream->private_data; >> + struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, >> + DRV_NAME); >> struct pdm_dev_data *adata = dev_get_drvdata(component->dev); >> >> disable_pdm_interrupts(adata->acp_base); >> @@ -329,6 +343,7 @@ static int acp_pdm_dai_hw_params(struct snd_pcm_substream *substream, >> default: >> return -EINVAL; >> } >> + >> rn_writel(ch_mask, rtd->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); >> rn_writel(PDM_DECIMATION_FACTOR, rtd->acp_base + >> ACP_WOV_PDM_DECIMATION_FACTOR); >> @@ -368,6 +383,11 @@ static int acp_pdm_dai_trigger(struct snd_pcm_substream *substream, >> return ret; >> } >> >> +static int acp_pdm_dma_hw_free(struct snd_pcm_substream *substream) >> +{ >> + return snd_pcm_lib_free_pages(substream); >> +} >> + >> static struct snd_soc_dai_ops acp_pdm_dai_ops = { >> .hw_params = acp_pdm_dai_hw_params, >> .trigger = acp_pdm_dai_trigger, >> @@ -386,14 +406,20 @@ static struct snd_soc_dai_driver acp_pdm_dai_driver = { >> .ops = &acp_pdm_dai_ops, >> }; >> >> -static const struct snd_soc_component_driver acp_pdm_component = { >> - .name = DRV_NAME, >> +static const struct snd_pcm_ops acp_pdm_ops = { >> .open = acp_pdm_dma_open, >> .close = acp_pdm_dma_close, >> .hw_params = acp_pdm_dma_hw_params, >> + .hw_free = acp_pdm_dma_hw_free, >> .pointer = acp_pdm_dma_pointer, >> .mmap = acp_pdm_dma_mmap, >> - .pcm_construct = acp_pdm_dma_new, >> +}; >> + >> +static const struct snd_soc_component_driver acp_pdm_component = { >> + .name = DRV_NAME, >> + .ops = &acp_pdm_ops, >> + .pcm_new = acp_pdm_dma_new, >> + >> }; >> >> static int acp_pdm_audio_probe(struct platform_device *pdev) >>
On 2020-05-29 09:19, Hui Wang wrote: > > On 2020/5/29 下午3:11, Kleber Souza wrote: >> On 2020-05-28 04:11, Hui Wang wrote: >>> BugLink: https://bugs.launchpad.net/bugs/1881046 >>> >>> This amd renoir driver is for kernel-5.8, after backporting to >>> kernel-5.4, need to do some change according to API in the >>> kernel-5.4, otherwise there will be building errors and runtime >>> errors. >>> >>> Signed-off-by: Hui Wang <hui.wang@canonical.com> >> Hi Hui, >> >> Would it be possible to make these fixes on the patches that introduce >> the code and make them a backport instead of a cherry-pick? The reason >> I'm asking is because adding a follow up fix keeping the original patches >> unable to build will break the bisectability of the code. >> >> Also, these patches were already merged on linux-next with the same >> SHA1, we should replace the provenance from the upstream maintainer >> repo to it. >> >> Otherwise it looks good to me. These are a lot of changes and adding >> a whole new driver to a stable release should be done carefully. However, >> I see the value of adding it to Focal for support of the new AMD chips. >> The code is also limited in scope and already on linux-next so I believe >> the risks are relatively low. > > OK, will do that, let us merge the patchset to OEM-5.6 and unstable > first. I will re-prepare the patchset to focal. > > thx. Thank you, Hui! I will NAK the thread for Focal to keep it consistent. > > >> >> Thanks, >> Kleber >> >> >> >>> --- >>> sound/soc/amd/renoir/acp3x-pdm-dma.c | 70 +++++++++++++++++++--------- >>> 1 file changed, 48 insertions(+), 22 deletions(-) >>> >>> diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c >>> index 623dfd3ea705..a823c4d726ff 100644 >>> --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c >>> +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c >>> @@ -201,12 +201,14 @@ static void config_acp_dma(struct pdm_stream_instance *rtd, int direction) >>> } >>> } >>> >>> -static int acp_pdm_dma_open(struct snd_soc_component *component, >>> - struct snd_pcm_substream *substream) >>> +static int acp_pdm_dma_open(struct snd_pcm_substream *substream) >>> { >>> struct snd_pcm_runtime *runtime; >>> struct pdm_dev_data *adata; >>> struct pdm_stream_instance *pdm_data; >>> + struct snd_soc_pcm_runtime *prtd = substream->private_data; >>> + struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, >>> + DRV_NAME); >>> int ret; >>> >>> runtime = substream->runtime; >>> @@ -236,24 +238,34 @@ static int acp_pdm_dma_open(struct snd_soc_component *component, >>> return ret; >>> } >>> >>> -static int acp_pdm_dma_hw_params(struct snd_soc_component *component, >>> - struct snd_pcm_substream *substream, >>> +static int acp_pdm_dma_hw_params(struct snd_pcm_substream *substream, >>> struct snd_pcm_hw_params *params) >>> { >>> struct pdm_stream_instance *rtd; >>> size_t size, period_bytes; >>> + int status; >>> >>> rtd = substream->runtime->private_data; >>> if (!rtd) >>> return -EINVAL; >>> + >>> size = params_buffer_bytes(params); >>> period_bytes = params_period_bytes(params); >>> - rtd->dma_addr = substream->dma_buffer.addr; >>> - rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); >>> - config_acp_dma(rtd, substream->stream); >>> - init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes, >>> - rtd->acp_base); >>> - return 0; >>> + status = snd_pcm_lib_malloc_pages(substream, size); >>> + if (status < 0) >>> + return status; >>> + memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); >>> + if (substream->dma_buffer.area) { >>> + rtd->dma_addr = substream->dma_buffer.addr; >>> + rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); >>> + config_acp_dma(rtd, substream->stream); >>> + init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes, >>> + rtd->acp_base); >>> + status = 0; >>> + } else >>> + status = -ENOMEM; >>> + >>> + return status; >>> } >>> >>> static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd, >>> @@ -270,8 +282,7 @@ static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd, >>> return byte_count.bytescount; >>> } >>> >>> -static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp, >>> - struct snd_pcm_substream *stream) >>> +static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_pcm_substream *stream) >>> { >>> struct pdm_stream_instance *rtd; >>> u32 pos, buffersize; >>> @@ -287,26 +298,29 @@ static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp, >>> return bytes_to_frames(stream->runtime, pos); >>> } >>> >>> -static int acp_pdm_dma_new(struct snd_soc_component *component, >>> - struct snd_soc_pcm_runtime *rtd) >>> +static int acp_pdm_dma_new(struct snd_soc_pcm_runtime *rtd) >>> { >>> + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, >>> + DRV_NAME); >>> struct device *parent = component->dev->parent; >>> >>> - snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, >>> + snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, >>> parent, MIN_BUFFER, MAX_BUFFER); >>> + >>> return 0; >>> } >>> >>> -static int acp_pdm_dma_mmap(struct snd_soc_component *component, >>> - struct snd_pcm_substream *substream, >>> +static int acp_pdm_dma_mmap(struct snd_pcm_substream *substream, >>> struct vm_area_struct *vma) >>> { >>> return snd_pcm_lib_default_mmap(substream, vma); >>> } >>> >>> -static int acp_pdm_dma_close(struct snd_soc_component *component, >>> - struct snd_pcm_substream *substream) >>> +static int acp_pdm_dma_close(struct snd_pcm_substream *substream) >>> { >>> + struct snd_soc_pcm_runtime *prtd = substream->private_data; >>> + struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, >>> + DRV_NAME); >>> struct pdm_dev_data *adata = dev_get_drvdata(component->dev); >>> >>> disable_pdm_interrupts(adata->acp_base); >>> @@ -329,6 +343,7 @@ static int acp_pdm_dai_hw_params(struct snd_pcm_substream *substream, >>> default: >>> return -EINVAL; >>> } >>> + >>> rn_writel(ch_mask, rtd->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); >>> rn_writel(PDM_DECIMATION_FACTOR, rtd->acp_base + >>> ACP_WOV_PDM_DECIMATION_FACTOR); >>> @@ -368,6 +383,11 @@ static int acp_pdm_dai_trigger(struct snd_pcm_substream *substream, >>> return ret; >>> } >>> >>> +static int acp_pdm_dma_hw_free(struct snd_pcm_substream *substream) >>> +{ >>> + return snd_pcm_lib_free_pages(substream); >>> +} >>> + >>> static struct snd_soc_dai_ops acp_pdm_dai_ops = { >>> .hw_params = acp_pdm_dai_hw_params, >>> .trigger = acp_pdm_dai_trigger, >>> @@ -386,14 +406,20 @@ static struct snd_soc_dai_driver acp_pdm_dai_driver = { >>> .ops = &acp_pdm_dai_ops, >>> }; >>> >>> -static const struct snd_soc_component_driver acp_pdm_component = { >>> - .name = DRV_NAME, >>> +static const struct snd_pcm_ops acp_pdm_ops = { >>> .open = acp_pdm_dma_open, >>> .close = acp_pdm_dma_close, >>> .hw_params = acp_pdm_dma_hw_params, >>> + .hw_free = acp_pdm_dma_hw_free, >>> .pointer = acp_pdm_dma_pointer, >>> .mmap = acp_pdm_dma_mmap, >>> - .pcm_construct = acp_pdm_dma_new, >>> +}; >>> + >>> +static const struct snd_soc_component_driver acp_pdm_component = { >>> + .name = DRV_NAME, >>> + .ops = &acp_pdm_ops, >>> + .pcm_new = acp_pdm_dma_new, >>> + >>> }; >>> >>> static int acp_pdm_audio_probe(struct platform_device *pdev) >>>
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c index 623dfd3ea705..a823c4d726ff 100644 --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c @@ -201,12 +201,14 @@ static void config_acp_dma(struct pdm_stream_instance *rtd, int direction) } } -static int acp_pdm_dma_open(struct snd_soc_component *component, - struct snd_pcm_substream *substream) +static int acp_pdm_dma_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; struct pdm_dev_data *adata; struct pdm_stream_instance *pdm_data; + struct snd_soc_pcm_runtime *prtd = substream->private_data; + struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, + DRV_NAME); int ret; runtime = substream->runtime; @@ -236,24 +238,34 @@ static int acp_pdm_dma_open(struct snd_soc_component *component, return ret; } -static int acp_pdm_dma_hw_params(struct snd_soc_component *component, - struct snd_pcm_substream *substream, +static int acp_pdm_dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct pdm_stream_instance *rtd; size_t size, period_bytes; + int status; rtd = substream->runtime->private_data; if (!rtd) return -EINVAL; + size = params_buffer_bytes(params); period_bytes = params_period_bytes(params); - rtd->dma_addr = substream->dma_buffer.addr; - rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); - config_acp_dma(rtd, substream->stream); - init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes, - rtd->acp_base); - return 0; + status = snd_pcm_lib_malloc_pages(substream, size); + if (status < 0) + return status; + memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); + if (substream->dma_buffer.area) { + rtd->dma_addr = substream->dma_buffer.addr; + rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); + config_acp_dma(rtd, substream->stream); + init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes, + rtd->acp_base); + status = 0; + } else + status = -ENOMEM; + + return status; } static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd, @@ -270,8 +282,7 @@ static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd, return byte_count.bytescount; } -static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp, - struct snd_pcm_substream *stream) +static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_pcm_substream *stream) { struct pdm_stream_instance *rtd; u32 pos, buffersize; @@ -287,26 +298,29 @@ static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp, return bytes_to_frames(stream->runtime, pos); } -static int acp_pdm_dma_new(struct snd_soc_component *component, - struct snd_soc_pcm_runtime *rtd) +static int acp_pdm_dma_new(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, + DRV_NAME); struct device *parent = component->dev->parent; - snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, + snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, parent, MIN_BUFFER, MAX_BUFFER); + return 0; } -static int acp_pdm_dma_mmap(struct snd_soc_component *component, - struct snd_pcm_substream *substream, +static int acp_pdm_dma_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { return snd_pcm_lib_default_mmap(substream, vma); } -static int acp_pdm_dma_close(struct snd_soc_component *component, - struct snd_pcm_substream *substream) +static int acp_pdm_dma_close(struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *prtd = substream->private_data; + struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, + DRV_NAME); struct pdm_dev_data *adata = dev_get_drvdata(component->dev); disable_pdm_interrupts(adata->acp_base); @@ -329,6 +343,7 @@ static int acp_pdm_dai_hw_params(struct snd_pcm_substream *substream, default: return -EINVAL; } + rn_writel(ch_mask, rtd->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); rn_writel(PDM_DECIMATION_FACTOR, rtd->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR); @@ -368,6 +383,11 @@ static int acp_pdm_dai_trigger(struct snd_pcm_substream *substream, return ret; } +static int acp_pdm_dma_hw_free(struct snd_pcm_substream *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + static struct snd_soc_dai_ops acp_pdm_dai_ops = { .hw_params = acp_pdm_dai_hw_params, .trigger = acp_pdm_dai_trigger, @@ -386,14 +406,20 @@ static struct snd_soc_dai_driver acp_pdm_dai_driver = { .ops = &acp_pdm_dai_ops, }; -static const struct snd_soc_component_driver acp_pdm_component = { - .name = DRV_NAME, +static const struct snd_pcm_ops acp_pdm_ops = { .open = acp_pdm_dma_open, .close = acp_pdm_dma_close, .hw_params = acp_pdm_dma_hw_params, + .hw_free = acp_pdm_dma_hw_free, .pointer = acp_pdm_dma_pointer, .mmap = acp_pdm_dma_mmap, - .pcm_construct = acp_pdm_dma_new, +}; + +static const struct snd_soc_component_driver acp_pdm_component = { + .name = DRV_NAME, + .ops = &acp_pdm_ops, + .pcm_new = acp_pdm_dma_new, + }; static int acp_pdm_audio_probe(struct platform_device *pdev)
BugLink: https://bugs.launchpad.net/bugs/1881046 This amd renoir driver is for kernel-5.8, after backporting to kernel-5.4, need to do some change according to API in the kernel-5.4, otherwise there will be building errors and runtime errors. Signed-off-by: Hui Wang <hui.wang@canonical.com> --- sound/soc/amd/renoir/acp3x-pdm-dma.c | 70 +++++++++++++++++++--------- 1 file changed, 48 insertions(+), 22 deletions(-)