Add support for system level pm ops for soundwire dma driver for pink sardine platform.
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com --- sound/soc/amd/ps/ps-sdw-dma.c | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+)
diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 960c0bc5e848..ba2eea23d41e 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -623,6 +623,64 @@ static int acp63_sdw_platform_remove(struct platform_device *pdev) return 0; }
+static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev) +{ + struct sdw_dma_dev_data *sdw_dma_data; + struct sdw_stream_instance *sdw_ins; + struct snd_pcm_runtime *runtime; + u32 period_bytes, buf_size, water_mark_size_reg; + int ret; + int index; + + sdw_dma_data = dev_get_drvdata(dev); + for (index = 0; index < ACP63_SDW_MAX_STREAMS; index++) { + if (sdw_dma_data->sdw_stream[index] && + sdw_dma_data->sdw_stream[index]->runtime) { + switch (index) { + case ACP_SDW_AUDIO_TX: + water_mark_size_reg = ACP_AUDIO_TX_INTR_WATERMARK_SIZE; + break; + case ACP_SDW_BT_TX: + water_mark_size_reg = ACP_BT_TX_INTR_WATERMARK_SIZE; + break; + case ACP_SDW_HS_TX: + water_mark_size_reg = ACP_HS_TX_INTR_WATERMARK_SIZE; + break; + case ACP_SDW1_BT_TX: + water_mark_size_reg = ACP_P1_BT_TX_INTR_WATERMARK_SIZE; + break; + case ACP_SDW_AUDIO_RX: + water_mark_size_reg = ACP_AUDIO_RX_INTR_WATERMARK_SIZE; + break; + case ACP_SDW_BT_RX: + water_mark_size_reg = ACP_BT_RX_INTR_WATERMARK_SIZE; + break; + case ACP_SDW_HS_RX: + water_mark_size_reg = ACP_HS_RX_INTR_WATERMARK_SIZE; + break; + case ACP_SDW1_BT_RX: + water_mark_size_reg = ACP_P1_BT_RX_INTR_WATERMARK_SIZE; + break; + default: + dev_err(dev, "%s: Invalid channel type\n", __func__); + return -EINVAL; + } + runtime = sdw_dma_data->sdw_stream[index]->runtime; + sdw_ins = runtime->private_data; + period_bytes = frames_to_bytes(runtime, runtime->period_size); + buf_size = frames_to_bytes(runtime, runtime->buffer_size); + acp63_config_dma(sdw_ins, index); + ret = acp63_configure_sdw_ringbuffer(sdw_dma_data->acp_base, index, + buf_size); + if (ret) + return ret; + acp63_writel(period_bytes, sdw_dma_data->acp_base + water_mark_size_reg); + } + } + acp63_enable_disable_sdw_dma_interrupts(sdw_dma_data->acp_base, true); + return 0; +} + static int __maybe_unused acp63_sdw_pcm_runtime_suspend(struct device *dev) { struct sdw_dma_dev_data *sdw_dma_data; @@ -650,6 +708,7 @@ static int __maybe_unused acp63_sdw_pcm_runtime_resume(struct device *dev) static const struct dev_pm_ops acp63_pm_ops = { SET_RUNTIME_PM_OPS(acp63_sdw_pcm_runtime_suspend, acp63_sdw_pcm_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(acp63_sdw_pcm_runtime_suspend, acp63_sdw_pcm_resume) };
static struct platform_driver acp63_sdw_dma_driver = {