Unverified Commit f6f7d25b authored by Venkata Prasad Potturu's avatar Venkata Prasad Potturu Committed by Mark Brown
Browse files

ASoC: amd: acp: Add pte configuration for ACP7.0 platform



Add page table entry configurations to support higher sample rate
streams with multiple channels for ACP7.0 platforms.

Signed-off-by: default avatarVenkata Prasad Potturu <venkataprasad.potturu@amd.com>
Link: https://patch.msgid.link/20240903113427.182997-11-venkataprasad.potturu@amd.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b80d5a0c
Loading
Loading
Loading
Loading
+27 −6
Original line number Diff line number Diff line
@@ -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,6 +531,9 @@ 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);

			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 {
@@ -537,6 +542,10 @@ 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);

			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));
		}
@@ -549,6 +558,9 @@ 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);

			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 {
@@ -558,6 +570,9 @@ 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);

			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));
		}
@@ -570,6 +585,9 @@ 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;

			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 {
@@ -579,6 +597,9 @@ 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;

			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);
		}
+6 −1
Original line number Diff line number Diff line
@@ -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,6 +47,9 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream,
	size_dmic = frames_to_bytes(substream->runtime,
			substream->runtime->buffer_size);

	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 */
+44 −9
Original line number Diff line number Diff line
@@ -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;

	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 */
+2 −2
Original line number Diff line number Diff line
@@ -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[] = {
+8 −0
Original line number Diff line number Diff line
@@ -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
Loading