[PATCH 18/19] ASoC: amd: ps: implement system level pm ops for soundwire dma driver

From: Vijendar Mukunda
Date: Wed Jan 11 2023 - 04:07:23 EST


Add support for system level pm ops for soundwire dma driver for
pink sardine platform.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@xxxxxxx>
---
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 = {
--
2.34.1