diff mbox series

[10/12] ASoC: amd: acp: Add pte configuration for ACP7.0 platform

Message ID 20240903113427.182997-11-venkataprasad.potturu@amd.com
State Accepted
Commit f6f7d25b11033bdbf25d800572c003fced21a035
Headers show
Series Add i2s/tdm support for acp7.0 and acp7.1 platforms | expand

Commit Message

Venkata Prasad Potturu Sept. 3, 2024, 11:34 a.m. UTC
Add page table entry configurations to support higher sample rate
streams with multiple channels for ACP7.0 platforms.

Signed-off-by: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
---
 sound/soc/amd/acp/acp-i2s.c          | 33 +++++++++++++----
 sound/soc/amd/acp/acp-pdm.c          |  7 +++-
 sound/soc/amd/acp/acp-platform.c     | 53 +++++++++++++++++++++++-----
 sound/soc/amd/acp/acp70.c            |  4 +--
 sound/soc/amd/acp/amd.h              |  8 +++++
 sound/soc/amd/acp/chip_offset_byte.h |  7 ++++
 6 files changed, 94 insertions(+), 18 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c
index 2a23c52eb512..74f2ad62e596 100644
--- a/sound/soc/amd/acp/acp-i2s.c
+++ b/sound/soc/amd/acp/acp-i2s.c
@@ -514,12 +514,14 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 {
 	struct device *dev = dai->component->dev;
 	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip;
 	struct acp_resource *rsrc = adata->rsrc;
 	struct acp_stream *stream = substream->runtime->private_data;
 	u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0;
 	u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl;
 	unsigned int dir = substream->stream;
 
+	chip = dev_get_platdata(dev);
 	switch (dai->driver->id) {
 	case I2S_SP_INSTANCE:
 		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -529,7 +531,10 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 			reg_fifo_addr =	ACP_I2S_TX_FIFOADDR(adata);
 			reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata);
 
-			phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
+			if (chip->acp_rev >= ACP70_DEV)
+				phy_addr = ACP7x_I2S_SP_TX_MEM_WINDOW_START;
+			else
+				phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
 			writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata));
 		} else {
 			reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata);
@@ -537,7 +542,11 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 						SP_CAPT_FIFO_ADDR_OFFSET;
 			reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata);
 			reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata);
-			phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
+
+			if (chip->acp_rev >= ACP70_DEV)
+				phy_addr = ACP7x_I2S_SP_RX_MEM_WINDOW_START;
+			else
+				phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
 			writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata));
 		}
 		break;
@@ -549,7 +558,10 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 			reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata);
 			reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata);
 
-			phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
+			if (chip->acp_rev >= ACP70_DEV)
+				phy_addr = ACP7x_I2S_BT_TX_MEM_WINDOW_START;
+			else
+				phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
 			writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata));
 		} else {
 			reg_dma_size = ACP_BT_RX_DMA_SIZE(adata);
@@ -558,7 +570,10 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 			reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata);
 			reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata);
 
-			phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
+			if (chip->acp_rev >= ACP70_DEV)
+				phy_addr = ACP7x_I2S_BT_RX_MEM_WINDOW_START;
+			else
+				phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
 			writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata));
 		}
 		break;
@@ -570,7 +585,10 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 			reg_fifo_addr = ACP_HS_TX_FIFOADDR;
 			reg_fifo_size = ACP_HS_TX_FIFOSIZE;
 
-			phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
+			if (chip->acp_rev >= ACP70_DEV)
+				phy_addr = ACP7x_I2S_HS_TX_MEM_WINDOW_START;
+			else
+				phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
 			writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR);
 		} else {
 			reg_dma_size = ACP_HS_RX_DMA_SIZE;
@@ -579,7 +597,10 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 			reg_fifo_addr = ACP_HS_RX_FIFOADDR;
 			reg_fifo_size = ACP_HS_RX_FIFOSIZE;
 
-			phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
+			if (chip->acp_rev >= ACP70_DEV)
+				phy_addr = ACP7x_I2S_HS_RX_MEM_WINDOW_START;
+			else
+				phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
 			writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR);
 		}
 		break;
diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c
index bb79269c2fc1..22dd8988d005 100644
--- a/sound/soc/amd/acp/acp-pdm.c
+++ b/sound/soc/amd/acp/acp-pdm.c
@@ -31,9 +31,11 @@  static int acp_dmic_prepare(struct snd_pcm_substream *substream,
 	struct acp_stream *stream = substream->runtime->private_data;
 	struct device *dev = dai->component->dev;
 	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip;
 	u32 physical_addr, size_dmic, period_bytes;
 	unsigned int dmic_ctrl;
 
+	chip = dev_get_platdata(dev);
 	/* Enable default DMIC clk */
 	writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL);
 	dmic_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL);
@@ -45,7 +47,10 @@  static int acp_dmic_prepare(struct snd_pcm_substream *substream,
 	size_dmic = frames_to_bytes(substream->runtime,
 			substream->runtime->buffer_size);
 
-	physical_addr = stream->reg_offset + MEM_WINDOW_START;
+	if (chip->acp_rev >= ACP70_DEV)
+		physical_addr = ACP7x_DMIC_MEM_WINDOW_START;
+	else
+		physical_addr = stream->reg_offset + MEM_WINDOW_START;
 
 	/* Init DMIC Ring buffer */
 	writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR);
diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c
index 55573bdd5ef4..6ef9baeed74a 100644
--- a/sound/soc/amd/acp/acp-platform.c
+++ b/sound/soc/amd/acp/acp-platform.c
@@ -177,17 +177,20 @@  static irqreturn_t i2s_irq_handler(int irq, void *data)
 void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream)
 {
 	struct acp_resource *rsrc = adata->rsrc;
-	u32 pte_reg, pte_size, reg_val;
+	u32 reg_val;
 
-	/* Use ATU base Group5 */
-	pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_5;
-	pte_size =  ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5;
+	reg_val = rsrc->sram_pte_offset;
 	stream->reg_offset = 0x02000000;
 
-	/* Group Enable */
-	reg_val = rsrc->sram_pte_offset;
-	writel(reg_val | BIT(31), adata->acp_base + pte_reg);
-	writel(PAGE_SIZE_4K_ENABLE,  adata->acp_base + pte_size);
+	writel((reg_val + GRP1_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+	writel(PAGE_SIZE_4K_ENABLE,  adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+
+	writel((reg_val + GRP2_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2);
+	writel(PAGE_SIZE_4K_ENABLE,  adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2);
+
+	writel(reg_val | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_5);
+	writel(PAGE_SIZE_4K_ENABLE,  adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5);
+
 	writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
 }
 EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, SND_SOC_ACP_COMMON);
@@ -201,7 +204,39 @@  void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s
 	u32 low, high, val;
 	u16 page_idx;
 
-	val = stream->pte_offset;
+	switch (adata->platform) {
+	case ACP70:
+		switch (stream->dai_id) {
+		case I2S_SP_INSTANCE:
+			if (stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
+				val = 0x0;
+			else
+				val = 0x1000;
+			break;
+		case I2S_BT_INSTANCE:
+			if (stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
+				val = 0x2000;
+			else
+				val = 0x3000;
+			break;
+		case I2S_HS_INSTANCE:
+			if (stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
+				val = 0x4000;
+			else
+				val = 0x5000;
+			break;
+		case DMIC_INSTANCE:
+			val = 0x6000;
+			break;
+		default:
+			dev_err(adata->dev, "Invalid dai id %x\n", stream->dai_id);
+			break;
+		}
+		break;
+	default:
+		val = stream->pte_offset;
+		break;
+	}
 
 	for (page_idx = 0; page_idx < num_pages; page_idx++) {
 		/* Load the low address of page int ACP SRAM through SRBM */
diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c
index a662c7db7506..3b3bd15964fc 100644
--- a/sound/soc/amd/acp/acp70.c
+++ b/sound/soc/amd/acp/acp70.c
@@ -34,8 +34,8 @@  static struct acp_resource rsrc = {
 	.irqp_used = 1,
 	.soc_mclk = true,
 	.irq_reg_offset = 0x1a00,
-	.scratch_reg_offset = 0x12800,
-	.sram_pte_offset = 0x03802800,
+	.scratch_reg_offset = 0x10000,
+	.sram_pte_offset = 0x03800000,
 };
 
 static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = {
diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h
index 9fb4e234d518..854269fea875 100644
--- a/sound/soc/amd/acp/amd.h
+++ b/sound/soc/amd/acp/amd.h
@@ -62,6 +62,14 @@ 
 #define I2S_HS_TX_MEM_WINDOW_START      0x40A0000
 #define I2S_HS_RX_MEM_WINDOW_START      0x40C0000
 
+#define ACP7x_I2S_SP_TX_MEM_WINDOW_START	0x4000000
+#define ACP7x_I2S_SP_RX_MEM_WINDOW_START	0x4200000
+#define ACP7x_I2S_BT_TX_MEM_WINDOW_START	0x4400000
+#define ACP7x_I2S_BT_RX_MEM_WINDOW_START	0x4600000
+#define ACP7x_I2S_HS_TX_MEM_WINDOW_START	0x4800000
+#define ACP7x_I2S_HS_RX_MEM_WINDOW_START	0x4A00000
+#define ACP7x_DMIC_MEM_WINDOW_START			0x4C00000
+
 #define SP_PB_FIFO_ADDR_OFFSET		0x500
 #define SP_CAPT_FIFO_ADDR_OFFSET	0x700
 #define BT_PB_FIFO_ADDR_OFFSET		0x900
diff --git a/sound/soc/amd/acp/chip_offset_byte.h b/sound/soc/amd/acp/chip_offset_byte.h
index 97b8b49f1e64..117ea63e85c6 100644
--- a/sound/soc/amd/acp/chip_offset_byte.h
+++ b/sound/soc/amd/acp/chip_offset_byte.h
@@ -12,9 +12,16 @@ 
 #define _ACP_IP_OFFSET_HEADER
 
 #define ACPAXI2AXI_ATU_CTRL                           0xC40
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1                0xC00
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_1                0xC04
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2                0xC08
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_2                0xC0C
 #define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5                0xC20
 #define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5                0xC24
 
+#define GRP1_OFFSET	0x0
+#define GRP2_OFFSET	0x4000
+
 #define ACP_PGFSM_CONTROL			0x141C
 #define ACP_PGFSM_STATUS                        0x1420
 #define ACP_SOFT_RESET                          0x1000