@@ -321,19 +321,12 @@ static void config_acp_dma(void __iomem *acp_mmio,
u32 asic_type)
{
u32 pte_offset, sram_bank;
- u16 ch1, ch2, destination, dma_dscr_idx;
if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) {
pte_offset = ACP_PLAYBACK_PTE_OFFSET;
- ch1 = SYSRAM_TO_ACP_CH_NUM;
- ch2 = ACP_TO_I2S_DMA_CH_NUM;
sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS;
- destination = TO_ACP_I2S_1;
-
} else {
pte_offset = ACP_CAPTURE_PTE_OFFSET;
- ch1 = SYSRAM_TO_ACP_CH_NUM;
- ch2 = ACP_TO_I2S_DMA_CH_NUM;
switch (asic_type) {
case CHIP_STONEY:
sram_bank = ACP_SHARED_RAM_BANK_3_ADDRESS;
@@ -341,30 +334,19 @@ static void config_acp_dma(void __iomem *acp_mmio,
default:
sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS;
}
- destination = FROM_ACP_I2S_1;
}
-
acp_pte_config(acp_mmio, rtd->pg, rtd->num_of_pages,
pte_offset);
- if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK)
- dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
- else
- dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14;
-
/* Configure System memory <-> ACP SRAM DMA descriptors */
set_acp_sysmem_dma_descriptors(acp_mmio, rtd->size,
- rtd->direction, pte_offset, ch1,
- sram_bank, dma_dscr_idx, asic_type);
-
- if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK)
- dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13;
- else
- dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15;
+ rtd->direction, pte_offset,
+ rtd->ch1, sram_bank,
+ rtd->dma_dscr_idx_1, asic_type);
/* Configure ACP SRAM <-> I2S DMA descriptors */
set_acp_to_i2s_dma_descriptors(acp_mmio, rtd->size,
rtd->direction, sram_bank,
- destination, ch2, dma_dscr_idx,
- asic_type);
+ rtd->destination, rtd->ch2,
+ rtd->dma_dscr_idx_2, asic_type);
}
/* Start a given DMA channel transfer */
@@ -804,6 +786,21 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
acp_reg_write(val, adata->acp_mmio,
mmACP_I2S_16BIT_RESOLUTION_EN);
}
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ rtd->ch1 = SYSRAM_TO_ACP_CH_NUM;
+ rtd->ch2 = ACP_TO_I2S_DMA_CH_NUM;
+ rtd->destination = TO_ACP_I2S_1;
+ rtd->dma_dscr_idx_1 = PLAYBACK_START_DMA_DESCR_CH12;
+ rtd->dma_dscr_idx_2 = PLAYBACK_START_DMA_DESCR_CH13;
+ } else {
+ rtd->ch1 = ACP_TO_SYSRAM_CH_NUM;
+ rtd->ch2 = I2S_TO_ACP_DMA_CH_NUM;
+ rtd->destination = FROM_ACP_I2S_1;
+ rtd->dma_dscr_idx_1 = CAPTURE_START_DMA_DESCR_CH14;
+ rtd->dma_dscr_idx_2 = CAPTURE_START_DMA_DESCR_CH15;
+ }
+
size = params_buffer_bytes(params);
status = snd_pcm_lib_malloc_pages(substream, size);
if (status < 0)
@@ -898,21 +895,15 @@ static int acp_dma_prepare(struct snd_pcm_substream *substream)
if (!rtd)
return -EINVAL;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM,
- PLAYBACK_START_DMA_DESCR_CH12,
- NUM_DSCRS_PER_CHANNEL, 0);
- config_acp_dma_channel(rtd->acp_mmio, ACP_TO_I2S_DMA_CH_NUM,
- PLAYBACK_START_DMA_DESCR_CH13,
- NUM_DSCRS_PER_CHANNEL, 0);
- } else {
- config_acp_dma_channel(rtd->acp_mmio, ACP_TO_SYSRAM_CH_NUM,
- CAPTURE_START_DMA_DESCR_CH14,
- NUM_DSCRS_PER_CHANNEL, 0);
- config_acp_dma_channel(rtd->acp_mmio, I2S_TO_ACP_DMA_CH_NUM,
- CAPTURE_START_DMA_DESCR_CH15,
- NUM_DSCRS_PER_CHANNEL, 0);
- }
+
+ config_acp_dma_channel(rtd->acp_mmio,
+ rtd->ch1,
+ rtd->dma_dscr_idx_1,
+ NUM_DSCRS_PER_CHANNEL, 0);
+ config_acp_dma_channel(rtd->acp_mmio,
+ rtd->ch2,
+ rtd->dma_dscr_idx_2,
+ NUM_DSCRS_PER_CHANNEL, 0);
return 0;
}
@@ -939,10 +930,9 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (rtd->i2ssp_renderbytescount == 0)
rtd->i2ssp_renderbytescount = bytescount;
- acp_dma_start(rtd->acp_mmio,
- SYSRAM_TO_ACP_CH_NUM, false);
+ acp_dma_start(rtd->acp_mmio, rtd->ch1, false);
while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) &
- BIT(SYSRAM_TO_ACP_CH_NUM)) {
+ BIT(rtd->ch1)) {
if (!loops--) {
dev_err(component->dev,
"acp dma start timeout\n");
@@ -950,38 +940,31 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
}
cpu_relax();
}
-
- acp_dma_start(rtd->acp_mmio,
- ACP_TO_I2S_DMA_CH_NUM, true);
-
} else {
if (rtd->i2ssp_capturebytescount == 0)
rtd->i2ssp_capturebytescount = bytescount;
- acp_dma_start(rtd->acp_mmio,
- I2S_TO_ACP_DMA_CH_NUM, true);
}
+ acp_dma_start(rtd->acp_mmio, rtd->ch2, true);
ret = 0;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
- /*
- * Need to stop only circular DMA channels :
- * ACP_TO_I2S_DMA_CH_NUM / I2S_TO_ACP_DMA_CH_NUM. Non-circular
- * channels will stopped automatically after its transfer
- * completes : SYSRAM_TO_ACP_CH_NUM / ACP_TO_SYSRAM_CH_NUM
+ /* For playback, non circular dma should be stopped first
+ * i.e Sysram to acp dma transfer channel(rtd->ch1) should be
+ * stopped before stopping cirular dma which is acp sram to i2s
+ * fifo dma transfer channel(rtd->ch2). Where as in Capture
+ * scenario, i2s fifo to acp sram dma channel(rtd->ch2) stopped
+ * first before stopping acp sram to sysram which is circular
+ * dma(rtd->ch1).
*/
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ret = acp_dma_stop(rtd->acp_mmio,
- SYSRAM_TO_ACP_CH_NUM);
- ret = acp_dma_stop(rtd->acp_mmio,
- ACP_TO_I2S_DMA_CH_NUM);
+ acp_dma_stop(rtd->acp_mmio, rtd->ch1);
+ ret = acp_dma_stop(rtd->acp_mmio, rtd->ch2);
rtd->i2ssp_renderbytescount = 0;
} else {
- ret = acp_dma_stop(rtd->acp_mmio,
- I2S_TO_ACP_DMA_CH_NUM);
- ret = acp_dma_stop(rtd->acp_mmio,
- ACP_TO_SYSRAM_CH_NUM);
+ acp_dma_stop(rtd->acp_mmio, rtd->ch2);
+ ret = acp_dma_stop(rtd->acp_mmio, rtd->ch1);
rtd->i2ssp_capturebytescount = 0;
}
break;
@@ -85,6 +85,11 @@ struct audio_substream_data {
unsigned int order;
u16 num_of_pages;
u16 direction;
+ u16 ch1;
+ u16 ch2;
+ u16 destination;
+ u16 dma_dscr_idx_1;
+ u16 dma_dscr_idx_2;
uint64_t size;
u64 i2ssp_renderbytescount;
u64 i2ssp_capturebytescount;