Commit 1324e5ff authored by Mark Brown's avatar Mark Brown

Add i2s/tdm support for acp7.0 and acp7.1 platforms

Merge series from Venkata Prasad Potturu <venkataprasad.potturu@amd.com>:

1. Refactor acp generic driver to support all platforms.
2. Add i2s/tdm and support for acp7.0  and acp7.1 platforms.
parents 56f97d4d 3f600592
This diff is collapsed.
...@@ -113,40 +113,40 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, ...@@ -113,40 +113,40 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
switch (dai->driver->id) { switch (dai->driver->id) {
case I2S_SP_INSTANCE: case I2S_SP_INSTANCE:
if (dir == SNDRV_PCM_STREAM_PLAYBACK) { if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
reg_dma_size = ACP_I2S_TX_DMA_SIZE; reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset + acp_fifo_addr = rsrc->sram_pte_offset +
SP_PB_FIFO_ADDR_OFFSET; SP_PB_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_I2S_TX_FIFOADDR; reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata);
reg_fifo_size = ACP_I2S_TX_FIFOSIZE; reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata);
phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR); writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata));
} else { } else {
reg_dma_size = ACP_I2S_RX_DMA_SIZE; reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset + acp_fifo_addr = rsrc->sram_pte_offset +
SP_CAPT_FIFO_ADDR_OFFSET; SP_CAPT_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_I2S_RX_FIFOADDR; reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata);
reg_fifo_size = ACP_I2S_RX_FIFOSIZE; reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata);
phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR); writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata));
} }
break; break;
case I2S_BT_INSTANCE: case I2S_BT_INSTANCE:
if (dir == SNDRV_PCM_STREAM_PLAYBACK) { if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
reg_dma_size = ACP_BT_TX_DMA_SIZE; reg_dma_size = ACP_BT_TX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset + acp_fifo_addr = rsrc->sram_pte_offset +
BT_PB_FIFO_ADDR_OFFSET; BT_PB_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_BT_TX_FIFOADDR; reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata);
reg_fifo_size = ACP_BT_TX_FIFOSIZE; reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata);
phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR); writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata));
} else { } else {
reg_dma_size = ACP_BT_RX_DMA_SIZE; reg_dma_size = ACP_BT_RX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset + acp_fifo_addr = rsrc->sram_pte_offset +
BT_CAPT_FIFO_ADDR_OFFSET; BT_CAPT_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_BT_RX_FIFOADDR; reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata);
reg_fifo_size = ACP_BT_RX_FIFOSIZE; reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata);
phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR); writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata));
} }
break; break;
case I2S_HS_INSTANCE: case I2S_HS_INSTANCE:
......
...@@ -31,9 +31,11 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream, ...@@ -31,9 +31,11 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream,
struct acp_stream *stream = substream->runtime->private_data; struct acp_stream *stream = substream->runtime->private_data;
struct device *dev = dai->component->dev; struct device *dev = dai->component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_dev_data *adata = dev_get_drvdata(dev);
struct acp_chip_info *chip;
u32 physical_addr, size_dmic, period_bytes; u32 physical_addr, size_dmic, period_bytes;
unsigned int dmic_ctrl; unsigned int dmic_ctrl;
chip = dev_get_platdata(dev);
/* Enable default DMIC clk */ /* Enable default DMIC clk */
writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL); writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL);
dmic_ctrl = readl(adata->acp_base + ACP_WOV_MISC_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, ...@@ -45,7 +47,10 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream,
size_dmic = frames_to_bytes(substream->runtime, size_dmic = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size); 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 */ /* Init DMIC Ring buffer */
writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR); writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR);
......
...@@ -68,6 +68,46 @@ static const struct snd_pcm_hardware acp_pcm_hardware_capture = { ...@@ -68,6 +68,46 @@ static const struct snd_pcm_hardware acp_pcm_hardware_capture = {
.periods_max = CAPTURE_MAX_NUM_PERIODS, .periods_max = CAPTURE_MAX_NUM_PERIODS,
}; };
static const struct snd_pcm_hardware acp6x_pcm_hardware_playback = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 32,
.rates = SNDRV_PCM_RATE_8000_192000,
.rate_min = 8000,
.rate_max = 192000,
.buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
.period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
.period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
.periods_min = PLAYBACK_MIN_NUM_PERIODS,
.periods_max = PLAYBACK_MAX_NUM_PERIODS,
};
static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 32,
.rates = SNDRV_PCM_RATE_8000_192000,
.rate_min = 8000,
.rate_max = 192000,
.buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
.period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
.period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
.periods_min = CAPTURE_MIN_NUM_PERIODS,
.periods_max = CAPTURE_MAX_NUM_PERIODS,
};
int acp_machine_select(struct acp_dev_data *adata) int acp_machine_select(struct acp_dev_data *adata)
{ {
struct snd_soc_acpi_mach *mach; struct snd_soc_acpi_mach *mach;
...@@ -137,17 +177,20 @@ static irqreturn_t i2s_irq_handler(int irq, void *data) ...@@ -137,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) void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream)
{ {
struct acp_resource *rsrc = adata->rsrc; struct acp_resource *rsrc = adata->rsrc;
u32 pte_reg, pte_size, reg_val; u32 reg_val;
/* Use ATU base Group5 */ reg_val = rsrc->sram_pte_offset;
pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_5;
pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5;
stream->reg_offset = 0x02000000; stream->reg_offset = 0x02000000;
/* Group Enable */ writel((reg_val + GRP1_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
reg_val = rsrc->sram_pte_offset; writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
writel(reg_val | BIT(31), adata->acp_base + pte_reg);
writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + pte_size); 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); writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
} }
EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, SND_SOC_ACP_COMMON); EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, SND_SOC_ACP_COMMON);
...@@ -161,7 +204,40 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s ...@@ -161,7 +204,40 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s
u32 low, high, val; u32 low, high, val;
u16 page_idx; u16 page_idx;
val = stream->pte_offset; switch (adata->platform) {
case ACP70:
case ACP71:
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++) { for (page_idx = 0; page_idx < num_pages; page_idx++) {
/* Load the low address of page int ACP SRAM through SRBM */ /* Load the low address of page int ACP SRAM through SRBM */
...@@ -183,6 +259,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs ...@@ -183,6 +259,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct device *dev = component->dev; struct device *dev = component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_dev_data *adata = dev_get_drvdata(dev);
struct acp_chip_info *chip;
struct acp_stream *stream; struct acp_stream *stream;
int ret; int ret;
...@@ -191,11 +268,23 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs ...@@ -191,11 +268,23 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs
return -ENOMEM; return -ENOMEM;
stream->substream = substream; stream->substream = substream;
chip = dev_get_platdata(dev);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) switch (chip->acp_rev) {
runtime->hw = acp_pcm_hardware_playback; case ACP63_DEV:
else case ACP70_DEV:
runtime->hw = acp_pcm_hardware_capture; case ACP71_DEV:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
runtime->hw = acp6x_pcm_hardware_playback;
else
runtime->hw = acp6x_pcm_hardware_capture;
break;
default:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
runtime->hw = acp_pcm_hardware_playback;
else
runtime->hw = acp_pcm_hardware_capture;
break;
}
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, DMA_SIZE); ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, DMA_SIZE);
if (ret) { if (ret) {
......
...@@ -25,14 +25,17 @@ ...@@ -25,14 +25,17 @@
#define DRV_NAME "acp_asoc_acp70" #define DRV_NAME "acp_asoc_acp70"
#define CLK7_CLK0_DFS_CNTL_N1 0X0006C1A4
#define CLK0_DIVIDER 0X19
static struct acp_resource rsrc = { static struct acp_resource rsrc = {
.offset = 0, .offset = 0,
.no_of_ctrls = 2, .no_of_ctrls = 2,
.irqp_used = 1, .irqp_used = 1,
.soc_mclk = true, .soc_mclk = true,
.irq_reg_offset = 0x1a00, .irq_reg_offset = 0x1a00,
.scratch_reg_offset = 0x12800, .scratch_reg_offset = 0x10000,
.sram_pte_offset = 0x03802800, .sram_pte_offset = 0x03800000,
}; };
static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = { static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = {
...@@ -49,23 +52,23 @@ static struct snd_soc_dai_driver acp70_dai[] = { ...@@ -49,23 +52,23 @@ static struct snd_soc_dai_driver acp70_dai[] = {
.id = I2S_SP_INSTANCE, .id = I2S_SP_INSTANCE,
.playback = { .playback = {
.stream_name = "I2S SP Playback", .stream_name = "I2S SP Playback",
.rates = SNDRV_PCM_RATE_8000_96000, .rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2, .channels_min = 2,
.channels_max = 8, .channels_max = 32,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 96000, .rate_max = 192000,
}, },
.capture = { .capture = {
.stream_name = "I2S SP Capture", .stream_name = "I2S SP Capture",
.rates = SNDRV_PCM_RATE_8000_48000, .rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 32,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 48000, .rate_max = 192000,
}, },
.ops = &asoc_acp_cpu_dai_ops, .ops = &asoc_acp_cpu_dai_ops,
}, },
...@@ -74,23 +77,23 @@ static struct snd_soc_dai_driver acp70_dai[] = { ...@@ -74,23 +77,23 @@ static struct snd_soc_dai_driver acp70_dai[] = {
.id = I2S_BT_INSTANCE, .id = I2S_BT_INSTANCE,
.playback = { .playback = {
.stream_name = "I2S BT Playback", .stream_name = "I2S BT Playback",
.rates = SNDRV_PCM_RATE_8000_96000, .rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2, .channels_min = 2,
.channels_max = 8, .channels_max = 32,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 96000, .rate_max = 192000,
}, },
.capture = { .capture = {
.stream_name = "I2S BT Capture", .stream_name = "I2S BT Capture",
.rates = SNDRV_PCM_RATE_8000_48000, .rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 32,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 48000, .rate_max = 192000,
}, },
.ops = &asoc_acp_cpu_dai_ops, .ops = &asoc_acp_cpu_dai_ops,
}, },
...@@ -99,23 +102,23 @@ static struct snd_soc_dai_driver acp70_dai[] = { ...@@ -99,23 +102,23 @@ static struct snd_soc_dai_driver acp70_dai[] = {
.id = I2S_HS_INSTANCE, .id = I2S_HS_INSTANCE,
.playback = { .playback = {
.stream_name = "I2S HS Playback", .stream_name = "I2S HS Playback",
.rates = SNDRV_PCM_RATE_8000_96000, .rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2, .channels_min = 2,
.channels_max = 8, .channels_max = 32,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 96000, .rate_max = 192000,
}, },
.capture = { .capture = {
.stream_name = "I2S HS Capture", .stream_name = "I2S HS Capture",
.rates = SNDRV_PCM_RATE_8000_48000, .rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2, .channels_min = 2,
.channels_max = 8, .channels_max = 32,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 48000, .rate_max = 192000,
}, },
.ops = &asoc_acp_cpu_dai_ops, .ops = &asoc_acp_cpu_dai_ops,
}, },
...@@ -134,12 +137,36 @@ static struct snd_soc_dai_driver acp70_dai[] = { ...@@ -134,12 +137,36 @@ static struct snd_soc_dai_driver acp70_dai[] = {
}, },
}; };
static int acp70_i2s_master_clock_generate(struct acp_dev_data *adata)
{
struct pci_dev *smn_dev;
u32 device_id;
if (adata->platform == ACP70)
device_id = 0x1507;
else if (adata->platform == ACP71)
device_id = 0x1122;
else
return -ENODEV;
smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, device_id, NULL);
if (!smn_dev)
return -ENODEV;
/* Set clk7 DFS clock divider register value to get mclk as 196.608MHz*/
smn_write(smn_dev, CLK7_CLK0_DFS_CNTL_N1, CLK0_DIVIDER);
return 0;
}
static int acp_acp70_audio_probe(struct platform_device *pdev) static int acp_acp70_audio_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct acp_chip_info *chip; struct acp_chip_info *chip;
struct acp_dev_data *adata; struct acp_dev_data *adata;
struct resource *res; struct resource *res;
int ret;
chip = dev_get_platdata(&pdev->dev); chip = dev_get_platdata(&pdev->dev);
if (!chip || !chip->base) { if (!chip || !chip->base) {
...@@ -191,6 +218,12 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) ...@@ -191,6 +218,12 @@ static int acp_acp70_audio_probe(struct platform_device *pdev)
acp_machine_select(adata); acp_machine_select(adata);
dev_set_drvdata(dev, adata); dev_set_drvdata(dev, adata);
ret = acp70_i2s_master_clock_generate(adata);
if (ret) {
dev_err(&pdev->dev, "Failed to set I2S master clock as 196.608MHz\n");
return ret;
}
acp_enable_interrupts(adata); acp_enable_interrupts(adata);
acp_platform_register(dev); acp_platform_register(dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
......
...@@ -62,6 +62,14 @@ ...@@ -62,6 +62,14 @@
#define I2S_HS_TX_MEM_WINDOW_START 0x40A0000 #define I2S_HS_TX_MEM_WINDOW_START 0x40A0000
#define I2S_HS_RX_MEM_WINDOW_START 0x40C0000 #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_PB_FIFO_ADDR_OFFSET 0x500
#define SP_CAPT_FIFO_ADDR_OFFSET 0x700 #define SP_CAPT_FIFO_ADDR_OFFSET 0x700
#define BT_PB_FIFO_ADDR_OFFSET 0x900 #define BT_PB_FIFO_ADDR_OFFSET 0x900
...@@ -259,12 +267,12 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int ...@@ -259,12 +267,12 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int
if (direction == SNDRV_PCM_STREAM_PLAYBACK) { if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
switch (dai_id) { switch (dai_id) {
case I2S_BT_INSTANCE: case I2S_BT_INSTANCE:
high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH); high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata));
low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW); low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata));
break; break;
case I2S_SP_INSTANCE: case I2S_SP_INSTANCE:
high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH); high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata));
low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW); low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata));
break; break;
case I2S_HS_INSTANCE: case I2S_HS_INSTANCE:
high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH); high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH);
...@@ -277,12 +285,12 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int ...@@ -277,12 +285,12 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int
} else { } else {
switch (dai_id) { switch (dai_id) {
case I2S_BT_INSTANCE: case I2S_BT_INSTANCE:
high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH); high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata));
low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW); low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata));
break; break;
case I2S_SP_INSTANCE: case I2S_SP_INSTANCE:
high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH); high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata));
low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW); low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata));
break; break;
case I2S_HS_INSTANCE: case I2S_HS_INSTANCE:
high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH); high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH);
......
...@@ -12,9 +12,16 @@ ...@@ -12,9 +12,16 @@
#define _ACP_IP_OFFSET_HEADER #define _ACP_IP_OFFSET_HEADER
#define ACPAXI2AXI_ATU_CTRL 0xC40 #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_PAGE_SIZE_GRP_5 0xC20
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0xC24 #define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0xC24
#define GRP1_OFFSET 0x0
#define GRP2_OFFSET 0x4000
#define ACP_PGFSM_CONTROL 0x141C #define ACP_PGFSM_CONTROL 0x141C
#define ACP_PGFSM_STATUS 0x1420 #define ACP_PGFSM_STATUS 0x1420
#define ACP_SOFT_RESET 0x1000 #define ACP_SOFT_RESET 0x1000
...@@ -32,42 +39,47 @@ ...@@ -32,42 +39,47 @@
/* Registers from ACP_AUDIO_BUFFERS block */ /* Registers from ACP_AUDIO_BUFFERS block */
#define ACP_I2S_RX_RINGBUFADDR 0x2000 #define ACP_I2S_REG_ADDR(acp_adata, addr) \
#define ACP_I2S_RX_RINGBUFSIZE 0x2004 ((addr) + (acp_adata->rsrc->irqp_used * \
#define ACP_I2S_RX_LINKPOSITIONCNTR 0x2008 acp_adata->rsrc->irq_reg_offset))
#define ACP_I2S_RX_FIFOADDR 0x200C
#define ACP_I2S_RX_FIFOSIZE 0x2010 #define ACP_I2S_RX_RINGBUFADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2000)
#define ACP_I2S_RX_DMA_SIZE 0x2014 #define ACP_I2S_RX_RINGBUFSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2004)
#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x2018 #define ACP_I2S_RX_LINKPOSITIONCNTR(adata) ACP_I2S_REG_ADDR(adata, 0x2008)
#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x201C #define ACP_I2S_RX_FIFOADDR(adata) ACP_I2S_REG_ADDR(adata, 0x200C)
#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x2020 #define ACP_I2S_RX_FIFOSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2010)
#define ACP_I2S_TX_RINGBUFADDR 0x2024 #define ACP_I2S_RX_DMA_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2014)
#define ACP_I2S_TX_RINGBUFSIZE 0x2028 #define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata) ACP_I2S_REG_ADDR(adata, 0x2018)
#define ACP_I2S_TX_LINKPOSITIONCNTR 0x202C #define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata) ACP_I2S_REG_ADDR(adata, 0x201C)
#define ACP_I2S_TX_FIFOADDR 0x2030 #define ACP_I2S_RX_INTR_WATERMARK_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2020)
#define ACP_I2S_TX_FIFOSIZE 0x2034 #define ACP_I2S_TX_RINGBUFADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2024)
#define ACP_I2S_TX_DMA_SIZE 0x2038 #define ACP_I2S_TX_RINGBUFSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2028)
#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x203C #define ACP_I2S_TX_LINKPOSITIONCNTR(adata) ACP_I2S_REG_ADDR(adata, 0x202C)
#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x2040 #define ACP_I2S_TX_FIFOADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2030)
#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x2044 #define ACP_I2S_TX_FIFOSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2034)
#define ACP_BT_RX_RINGBUFADDR 0x2048 #define ACP_I2S_TX_DMA_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2038)
#define ACP_BT_RX_RINGBUFSIZE 0x204C #define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata) ACP_I2S_REG_ADDR(adata, 0x203C)
#define ACP_BT_RX_LINKPOSITIONCNTR 0x2050 #define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata) ACP_I2S_REG_ADDR(adata, 0x2040)
#define ACP_BT_RX_FIFOADDR 0x2054 #define ACP_I2S_TX_INTR_WATERMARK_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2044)
#define ACP_BT_RX_FIFOSIZE 0x2058 #define ACP_BT_RX_RINGBUFADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2048)
#define ACP_BT_RX_DMA_SIZE 0x205C #define ACP_BT_RX_RINGBUFSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x204C)
#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x2060 #define ACP_BT_RX_LINKPOSITIONCNTR(adata) ACP_I2S_REG_ADDR(adata, 0x2050)
#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x2064 #define ACP_BT_RX_FIFOADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2054)
#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x2068 #define ACP_BT_RX_FIFOSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2058)
#define ACP_BT_TX_RINGBUFADDR 0x206C #define ACP_BT_RX_DMA_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x205C)
#define ACP_BT_TX_RINGBUFSIZE 0x2070 #define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata) ACP_I2S_REG_ADDR(adata, 0x2060)
#define ACP_BT_TX_LINKPOSITIONCNTR 0x2074 #define ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata) ACP_I2S_REG_ADDR(adata, 0x2064)
#define ACP_BT_TX_FIFOADDR 0x2078 #define ACP_BT_RX_INTR_WATERMARK_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2068)
#define ACP_BT_TX_FIFOSIZE 0x207C #define ACP_BT_TX_RINGBUFADDR(adata) ACP_I2S_REG_ADDR(adata, 0x206C)
#define ACP_BT_TX_DMA_SIZE 0x2080 #define ACP_BT_TX_RINGBUFSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2070)
#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x2084 #define ACP_BT_TX_LINKPOSITIONCNTR(adata) ACP_I2S_REG_ADDR(adata, 0x2074)
#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x2088 #define ACP_BT_TX_FIFOADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2078)
#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x208C #define ACP_BT_TX_FIFOSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x207C)
#define ACP_BT_TX_DMA_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2080)
#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata) ACP_I2S_REG_ADDR(adata, 0x2084)
#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata) ACP_I2S_REG_ADDR(adata, 0x2088)
#define ACP_BT_TX_INTR_WATERMARK_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x208C)
#define ACP_HS_RX_RINGBUFADDR 0x3A90 #define ACP_HS_RX_RINGBUFADDR 0x3A90
#define ACP_HS_RX_RINGBUFSIZE 0x3A94 #define ACP_HS_RX_RINGBUFSIZE 0x3A94
#define ACP_HS_RX_LINKPOSITIONCNTR 0x3A98 #define ACP_HS_RX_LINKPOSITIONCNTR 0x3A98
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment