From 31f60a0c943d6a7e84b06686b1ed86ddadf484fa Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Date: Wed, 9 Mar 2022 20:27:12 -0800
Subject: [PATCH] ASoC: SOF: Make pcm_hw_params snd_sof_dsp_ops callback IPC neutral
Git-commit: 31f60a0c943d6a7e84b06686b1ed86ddadf484fa
Patch-mainline: v5.18-rc1
References: jsc#PED-850

Do not send IPC structure directly via pcm_hw_params to make it IPC
agnostic.

A new struct is created to retrieve the needed platform parameters and if
there is a need it can be extended with new options.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20220310042720.976809-3-ranjani.sridharan@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 sound/soc/sof/amd/acp-pcm.c   |  8 +++++---
 sound/soc/sof/amd/acp.h       |  3 ++-
 sound/soc/sof/intel/hda-pcm.c | 18 ++++--------------
 sound/soc/sof/intel/hda.h     |  2 +-
 sound/soc/sof/ops.h           |  6 +++---
 sound/soc/sof/pcm.c           | 21 ++++++++++++++++++++-
 sound/soc/sof/sof-priv.h      | 17 ++++++++++++++++-
 7 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/sound/soc/sof/amd/acp-pcm.c b/sound/soc/sof/amd/acp-pcm.c
index b49cc55980ae..0ba8ae46bd76 100644
--- a/sound/soc/sof/amd/acp-pcm.c
+++ b/sound/soc/sof/amd/acp-pcm.c
@@ -17,7 +17,8 @@
 #include "acp-dsp-offset.h"
 
 int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
-		      struct snd_pcm_hw_params *params, struct sof_ipc_stream_params *ipc_params)
+		      struct snd_pcm_hw_params *params,
+		      struct snd_sof_platform_stream_params *platform_params)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct acp_dsp_stream *stream = runtime->private_data;
@@ -35,8 +36,9 @@ int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substr
 		return ret;
 	}
 
-	ipc_params->buffer.phy_addr = stream->reg_offset;
-	ipc_params->stream_tag = stream->stream_tag;
+	platform_params->use_phy_address = true;
+	platform_params->phy_addr = stream->reg_offset;
+	platform_params->stream_tag = stream->stream_tag;
 
 	/* write buffer size of stream in scratch memory */
 
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index f550a5010a91..35e46fe6676a 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -201,7 +201,8 @@ int acp_dsp_stream_put(struct snd_sof_dev *sdev, struct acp_dsp_stream *acp_stre
 int acp_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream);
 int acp_pcm_close(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream);
 int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
-		      struct snd_pcm_hw_params *params, struct sof_ipc_stream_params *ipc_params);
+		      struct snd_pcm_hw_params *params,
+		      struct snd_sof_platform_stream_params *platform_params);
 
 extern const struct snd_sof_dsp_ops sof_renoir_ops;
 
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
index eec83ca557a1..7991407d5508 100644
--- a/sound/soc/sof/intel/hda-pcm.c
+++ b/sound/soc/sof/intel/hda-pcm.c
@@ -93,13 +93,12 @@ u32 hda_dsp_get_bits(struct snd_sof_dev *sdev, int sample_bits)
 int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
 			  struct snd_pcm_substream *substream,
 			  struct snd_pcm_hw_params *params,
-			  struct sof_ipc_stream_params *ipc_params)
+			  struct snd_sof_platform_stream_params *platform_params)
 {
 	struct hdac_stream *hstream = substream->runtime->private_data;
 	struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 	struct snd_dma_buffer *dmab;
-	struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
 	int ret;
 	u32 size, rate, bits;
 
@@ -130,19 +129,10 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
 	else
 		hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0);
 
-	/* update no_stream_position flag for ipc params */
-	if (hda && hda->no_ipc_position) {
-		/* For older ABIs set host_period_bytes to zero to inform
-		 * FW we don't want position updates. Newer versions use
-		 * no_stream_position for this purpose.
-		 */
-		if (v->abi_version < SOF_ABI_VER(3, 10, 0))
-			ipc_params->host_period_bytes = 0;
-		else
-			ipc_params->no_stream_position = 1;
-	}
+	if (hda)
+		platform_params->no_ipc_position = hda->no_ipc_position;
 
-	ipc_params->stream_tag = hstream->stream_tag;
+	platform_params->stream_tag = hstream->stream_tag;
 
 	return 0;
 }
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 21e34580a403..46641d31e9c5 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -524,7 +524,7 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
 int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
 			  struct snd_pcm_substream *substream,
 			  struct snd_pcm_hw_params *params,
-			  struct sof_ipc_stream_params *ipc_params);
+			  struct snd_sof_platform_stream_params *platform_params);
 int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
 			   struct snd_pcm_substream *substream);
 int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h
index 999a36208b11..98fa91f5927d 100644
--- a/sound/soc/sof/ops.h
+++ b/sound/soc/sof/ops.h
@@ -420,11 +420,11 @@ static inline int
 snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev,
 			       struct snd_pcm_substream *substream,
 			       struct snd_pcm_hw_params *params,
-			       struct sof_ipc_stream_params *ipc_params)
+			       struct snd_sof_platform_stream_params *platform_params)
 {
 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params)
-		return sof_ops(sdev)->pcm_hw_params(sdev, substream,
-						    params, ipc_params);
+		return sof_ops(sdev)->pcm_hw_params(sdev, substream, params,
+						    platform_params);
 
 	return 0;
 }
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 4628bc642fda..0c595d94dfce 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -162,6 +162,8 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
+	struct snd_sof_platform_stream_params platform_params = { 0 };
+	struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
 	struct snd_sof_pcm *spcm;
 	struct sof_ipc_pcm_params pcm;
 	struct sof_ipc_pcm_params_reply ipc_params_reply;
@@ -242,12 +244,29 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
 	ret = snd_sof_pcm_platform_hw_params(sdev,
 					     substream,
 					     params,
-					     &pcm.params);
+					     &platform_params);
 	if (ret < 0) {
 		dev_err(component->dev, "error: platform hw params failed\n");
 		return ret;
 	}
 
+	/* Update the IPC message with information from the platform */
+	pcm.params.stream_tag = platform_params.stream_tag;
+
+	if (platform_params.use_phy_address)
+		pcm.params.buffer.phy_addr = platform_params.phy_addr;
+
+	if (platform_params.no_ipc_position) {
+		/* For older ABIs set host_period_bytes to zero to inform
+		 * FW we don't want position updates. Newer versions use
+		 * no_stream_position for this purpose.
+		 */
+		if (v->abi_version < SOF_ABI_VER(3, 10, 0))
+			pcm.params.host_period_bytes = 0;
+		else
+			pcm.params.no_stream_position = 1;
+	}
+
 	dev_dbg(component->dev, "stream_tag %d", pcm.params.stream_tag);
 
 	/* if this is a repeated hw_params without hw_free, skip setting up widgets */
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 4ca18331e157..f87c454c789e 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -105,6 +105,21 @@ struct snd_soc_tplg_ops;
 struct snd_soc_component;
 struct snd_sof_pdata;
 
+/**
+ * struct snd_sof_platform_stream_params - platform dependent stream parameters
+ * @stream_tag:		Stream tag to use
+ * @use_phy_addr:	Use the provided @phy_addr for configuration
+ * @phy_addr:		Platform dependent address to be used, if  @use_phy_addr
+ *			is true
+ * @no_ipc_position:	Disable position update IPC from firmware
+ */
+struct snd_sof_platform_stream_params {
+	u16 stream_tag;
+	bool use_phy_address;
+	u32 phy_addr;
+	bool no_ipc_position;
+};
+
 /*
  * SOF DSP HW abstraction operations.
  * Used to abstract DSP HW architecture and any IO busses between host CPU
@@ -183,7 +198,7 @@ struct snd_sof_dsp_ops {
 	int (*pcm_hw_params)(struct snd_sof_dev *sdev,
 			     struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
-			     struct sof_ipc_stream_params *ipc_params); /* optional */
+			     struct snd_sof_platform_stream_params *platform_params); /* optional */
 
 	/* host stream hw_free */
 	int (*pcm_hw_free)(struct snd_sof_dev *sdev,
-- 
2.35.3

