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