[5/5] ASoC: SOF: amd: add option to use sram for data bin loading

Message ID 20231020062822.3913760-5-Vijendar.Mukunda@amd.com
State New
Headers
Series [1/5] ASoC: amd: Add acpi machine id for acp6.3 version based platform |

Commit Message

Mukunda,Vijendar Oct. 20, 2023, 6:28 a.m. UTC
  Provide an option to load DSP data bin to ACP SRAM.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
---
 sound/soc/sof/amd/acp-loader.c | 46 +++++++++++++++++++++++++++++-----
 sound/soc/sof/amd/acp.h        | 10 +++++++-
 2 files changed, 49 insertions(+), 7 deletions(-)
  

Patch

diff --git a/sound/soc/sof/amd/acp-loader.c b/sound/soc/sof/amd/acp-loader.c
index d35d47d7e311..e05eb7a86dd4 100644
--- a/sound/soc/sof/amd/acp-loader.c
+++ b/sound/soc/sof/amd/acp-loader.c
@@ -19,8 +19,9 @@ 
 #include "acp-dsp-offset.h"
 #include "acp.h"
 
-#define FW_BIN		0
-#define FW_DATA_BIN	1
+#define FW_BIN			0
+#define FW_DATA_BIN		1
+#define FW_SRAM_DATA_BIN	2
 
 #define FW_BIN_PTE_OFFSET	0x00
 #define FW_DATA_BIN_PTE_OFFSET	0x08
@@ -49,7 +50,6 @@  int acp_dsp_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_t
 			u32 offset, void *src, size_t size)
 {
 	struct pci_dev *pci = to_pci_dev(sdev->dev);
-	const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
 	struct acp_dev_data *adata;
 	void *dest;
 	u32 dma_size, page_count;
@@ -86,9 +86,18 @@  int acp_dsp_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_t
 		adata->is_dram_in_use = true;
 		break;
 	case SOF_FW_BLK_TYPE_SRAM:
-		offset = offset - desc->sram_pte_offset;
-		memcpy_to_scratch(sdev, offset, src, size);
-		return 0;
+		if (!adata->sram_data_buf) {
+			adata->sram_data_buf = dma_alloc_coherent(&pci->dev,
+								  ACP_DEFAULT_SRAM_LENGTH,
+								  &adata->sram_dma_addr,
+								  GFP_ATOMIC);
+			if (!adata->sram_data_buf)
+				return -ENOMEM;
+		}
+		adata->fw_sram_data_bin_size = size + offset;
+		dest = adata->sram_data_buf + offset;
+		adata->is_sram_in_use = true;
+		break;
 	default:
 		dev_err(sdev->dev, "bad blk type 0x%x\n", blk_type);
 		return -EINVAL;
@@ -123,6 +132,10 @@  static void configure_pte_for_fw_loading(int type, int num_pages, struct acp_dev
 		offset = adata->fw_bin_page_count * 8;
 		addr = adata->dma_addr;
 		break;
+	case FW_SRAM_DATA_BIN:
+		offset = (adata->fw_bin_page_count + ACP_DRAM_PAGE_COUNT) * 8;
+		addr = adata->sram_dma_addr;
+		break;
 	default:
 		dev_err(sdev->dev, "Invalid data type %x\n", type);
 		return;
@@ -189,6 +202,22 @@  int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
 		if (ret < 0)
 			dev_err(sdev->dev, "acp dma transfer status: %d\n", ret);
 	}
+	if (adata->is_sram_in_use) {
+		configure_pte_for_fw_loading(FW_SRAM_DATA_BIN, ACP_SRAM_PAGE_COUNT, adata);
+		src_addr = ACP_SYSTEM_MEMORY_WINDOW + ACP_DEFAULT_SRAM_LENGTH +
+			   (page_count * ACP_PAGE_SIZE);
+		dest_addr = ACP_SRAM_BASE_ADDRESS;
+
+		ret = configure_and_run_dma(adata, src_addr, dest_addr,
+					    adata->fw_sram_data_bin_size);
+		if (ret < 0) {
+			dev_err(sdev->dev, "acp dma configuration failed: %d\n", ret);
+			return ret;
+		}
+		ret = acp_dma_status(adata, 0);
+		if (ret < 0)
+			dev_err(sdev->dev, "acp dma transfer status: %d\n", ret);
+	}
 
 	if (desc->rev > 3) {
 		/* Cache Window enable */
@@ -205,6 +234,11 @@  int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
 				  adata->dma_addr);
 		adata->data_buf = NULL;
 	}
+	if (adata->is_sram_in_use) {
+		dma_free_coherent(&pci->dev, ACP_DEFAULT_SRAM_LENGTH, adata->sram_data_buf,
+				  adata->sram_dma_addr);
+		adata->sram_data_buf = NULL;
+	}
 	return ret;
 }
 EXPORT_SYMBOL_NS(acp_dsp_pre_fw_run, SND_SOC_SOF_AMD_COMMON);
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index 2d1f57e1365a..c536cfde0e44 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -56,7 +56,7 @@ 
 #define ACP_IRAM_BASE_ADDRESS			0x000000
 #define ACP_DRAM_BASE_ADDRESS			0x01000000
 #define ACP_DRAM_PAGE_COUNT			128
-
+#define ACP_SRAM_BASE_ADDRESS			0x3806000
 #define ACP_DSP_TO_HOST_IRQ			0x04
 
 #define ACP_RN_PCI_ID				0x01
@@ -88,6 +88,8 @@ 
 #define PROBE_STATUS_BIT			BIT(31)
 
 #define ACP_FIRMWARE_SIGNATURE			0x100
+#define ACP_DEFAULT_SRAM_LENGTH			0x00080000
+#define ACP_SRAM_PAGE_COUNT			128
 
 enum clock_source {
 	ACP_CLOCK_96M = 0,
@@ -194,13 +196,18 @@  struct acp_dev_data {
 	struct platform_device *dmic_dev;
 	unsigned int fw_bin_size;
 	unsigned int fw_data_bin_size;
+	unsigned int fw_sram_data_bin_size;
 	const char *fw_code_bin;
 	const char *fw_data_bin;
+	const char *fw_sram_data_bin;
 	u32 fw_bin_page_count;
+	u32 fw_data_bin_page_count;
 	dma_addr_t sha_dma_addr;
 	u8 *bin_buf;
 	dma_addr_t dma_addr;
 	u8 *data_buf;
+	dma_addr_t sram_dma_addr;
+	u8 *sram_data_buf;
 	bool signed_fw_image;
 	struct dma_descriptor dscr_info[ACP_MAX_DESC];
 	struct acp_dsp_stream stream_buf[ACP_MAX_STREAM];
@@ -209,6 +216,7 @@  struct acp_dev_data {
 	struct acp_dsp_stream *probe_stream;
 	bool enable_fw_debug;
 	bool is_dram_in_use;
+	bool is_sram_in_use;
 };
 
 void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes);