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

Message ID 20230111090222.2016499-19-Vijendar.Mukunda@amd.com
State New
Headers
Series [01/19] ASoC: amd: ps: create platform devices based on acp config |

Commit Message

Mukunda,Vijendar Jan. 11, 2023, 9:02 a.m. UTC
  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(+)
  

Patch

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 = {