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: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
Link: https://patch.msgid.link/20240903113427.182997-11-venkataprasad.potturu@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Venkata Prasad Potturu 2024-09-03 17:04:25 +05:30 committed by Mark Brown
parent b80d5a0c87
commit f6f7d25b11
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
6 changed files with 94 additions and 18 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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[] = {

View File

@ -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

View File

@ -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