From 7f5394e3f662f1cae27fb34d381fa827820accfe Mon Sep 17 00:00:00 2001 From: Dipesh Gandhi Date: Mon, 17 Apr 2017 10:27:44 +0530 Subject: [PATCH] ASoC: tegra-alt: remove pcm ack dependency Change remove dependency of ack by pcm ops to update application pointer. MMAP mode can't be used with ops ack. When trigger is called updated app pointer info is passed to adma plugin. On adma period completion callback, updated application pointer is again passed to adma plugin. Jira EMA-389 Change-Id: Iad1376cc218b2c7b49812db34e128ed43b10eddb Signed-off-by: Dipesh Gandhi Reviewed-on: http://git-master/r/1331554 Reviewed-by: Uday Gupta GVS: Gerrit_Virtual_Submit Reviewed-by: Viraj Karandikar Reviewed-by: Nitin Pai --- sound/soc/tegra-alt/tegra210_adsp_alt.c | 88 ++++++++++++++++++------- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/sound/soc/tegra-alt/tegra210_adsp_alt.c b/sound/soc/tegra-alt/tegra210_adsp_alt.c index 30f665ca..bb1d466b 100644 --- a/sound/soc/tegra-alt/tegra210_adsp_alt.c +++ b/sound/soc/tegra-alt/tegra210_adsp_alt.c @@ -120,6 +120,7 @@ struct tegra210_adsp_pcm_rtd { struct device *dev; struct snd_pcm_substream *substream; struct tegra210_adsp_app *fe_apm; + snd_pcm_uframes_t prev_appl_ptr; }; struct tegra210_adsp_compr_rtd { @@ -1114,14 +1115,47 @@ static int tegra210_adsp_app_default_msg_handler(struct tegra210_adsp_app *app, return 0; } +static int tegra210_adsp_pcm_ack(struct snd_pcm_substream *substream) +{ + struct tegra210_adsp_pcm_rtd *prtd = substream->runtime->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + size_t pos; + int ret = 0; + + dev_vdbg(prtd->dev, "%s %d", __func__, (int)runtime->control->appl_ptr); + + pos = frames_to_bytes(runtime, + runtime->control->appl_ptr % runtime->buffer_size); + ret = tegra210_adsp_send_pos_msg(prtd->fe_apm, pos, + TEGRA210_ADSP_MSG_FLAG_SEND); + if (ret < 0) { + dev_err(prtd->dev, "Failed to send write position."); + return ret; + } + + return ret; +} + static int tegra210_adsp_pcm_msg_handler(struct tegra210_adsp_app *app, apm_msg_t *apm_msg) { struct tegra210_adsp_pcm_rtd *prtd = app->private_data; + struct snd_pcm_runtime *runtime; switch (apm_msg->msg.call_params.method) { case nvfx_apm_method_set_position: + if (!prtd && !prtd->substream) + return 0; + runtime = prtd->substream->runtime; snd_pcm_period_elapsed(prtd->substream); + + if ((IS_MMAP_ACCESS(runtime->access))) { + if (prtd->prev_appl_ptr != + runtime->control->appl_ptr) { + prtd->prev_appl_ptr = runtime->control->appl_ptr; + tegra210_adsp_pcm_ack(prtd->substream); + } + } break; case nvfx_apm_method_ack: complete(app->msg_complete); @@ -1799,6 +1833,7 @@ static uint32_t tegra210_adsp_hv_pcm_trigger( static int tegra210_adsp_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { + struct snd_pcm_runtime *runtime = substream->runtime; struct tegra210_adsp_pcm_rtd *prtd = substream->runtime->private_data; #ifdef CONFIG_SND_SOC_TEGRA_VIRT_IVC_COMM struct tegra210_adsp *adsp = prtd->fe_apm->adsp; @@ -1833,6 +1868,12 @@ static int tegra210_adsp_pcm_trigger(struct snd_pcm_substream *substream, dev_err(prtd->dev, "Failed to set state"); return ret; } + + if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && + (IS_MMAP_ACCESS(runtime->access))) { + prtd->prev_appl_ptr = runtime->control->appl_ptr; + tegra210_adsp_pcm_ack(substream); + } break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: @@ -1860,26 +1901,6 @@ static int tegra210_adsp_pcm_trigger(struct snd_pcm_substream *substream, return 0; } -static int tegra210_adsp_pcm_ack(struct snd_pcm_substream *substream) -{ - struct tegra210_adsp_pcm_rtd *prtd = substream->runtime->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - size_t pos; - int ret = 0; - - dev_vdbg(prtd->dev, "%s %d", __func__, (int)runtime->control->appl_ptr); - - pos = frames_to_bytes(runtime, - runtime->control->appl_ptr % runtime->buffer_size); - ret = tegra210_adsp_send_pos_msg(prtd->fe_apm, pos, - TEGRA210_ADSP_MSG_FLAG_SEND); - if (ret < 0) { - dev_err(prtd->dev, "Failed to send write position."); - return ret; - } - - return ret; -} static snd_pcm_uframes_t tegra210_adsp_pcm_pointer( struct snd_pcm_substream *substream) @@ -2206,6 +2227,8 @@ static int tegra210_adsp_admaif_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct tegra210_adsp *adsp = snd_soc_dai_get_drvdata(dai); + struct tegra210_adsp_pcm_rtd *prtd = NULL; + struct snd_pcm_runtime *runtime = NULL; #ifdef CONFIG_SND_SOC_TEGRA_VIRT_IVC_COMM struct device *dev = adsp->dev; struct device_node *node = dev->of_node; @@ -2214,7 +2237,7 @@ static int tegra210_adsp_admaif_hw_params(struct snd_pcm_substream *substream, nvfx_adma_init_params_t adma_params; uint32_t be_reg = dai->id; uint32_t admaif_id = be_reg - ADSP_ADMAIF_START + 1; - uint32_t source; + uint32_t source, apm_in_reg; int i, ret; dev_vdbg(adsp->dev, "%s : stream %d admaif %d\n", @@ -2257,6 +2280,17 @@ static int tegra210_adsp_admaif_hw_params(struct snd_pcm_substream *substream, if (!IS_APM_OUT(app->reg)) return 0; + apm_in_reg = APM_IN_START + (source - APM_OUT_START); + + /* not needed for IO-IO and compr */ + if (adsp->apps[apm_in_reg].msg_handler + == tegra210_adsp_pcm_msg_handler) { + prtd = adsp->apps[apm_in_reg].private_data; + runtime = prtd->substream->runtime; + if ((IS_MMAP_ACCESS(runtime->access))) + adma_params.periods = 4; + } + source = tegra210_adsp_get_source(adsp, app->reg); app = &adsp->apps[source]; if (!IS_ADMA(app->reg)) @@ -2278,13 +2312,23 @@ static int tegra210_adsp_admaif_hw_params(struct snd_pcm_substream *substream, source = tegra210_adsp_get_source(adsp, app->reg); if (!IS_APM_IN(source)) continue; - app = &adsp->apps[source]; + + /* not needed for IO-IO and compr */ + if (app->msg_handler == + tegra210_adsp_pcm_msg_handler) { + prtd = adsp->apps[source].private_data; + runtime = prtd->substream->runtime; + } source = tegra210_adsp_get_source(adsp, app->reg); if (source != be_reg) continue; + if (runtime && (IS_MMAP_ACCESS(runtime->access))) + adma_params.periods = 4; + app = &adsp->apps[i]; + adma_params.adma_channel = app->adma_chan; adma_params.direction = ADMA_AHUB_TO_MEMORY; adma_params.event.pvoid = app->apm->input_event.pvoid;