Commit d6d08273 authored by Yu Zhao's avatar Yu Zhao Committed by Mark Brown

ASoC: use DMA addr rather than CPU pa for acp_audio_dma

We shouldn't assume CPU physical address we get from page_to_phys()
is same as DMA address we get from dma_alloc_coherent(). On x86_64,
we won't run into any problem with the assumption when dma_ops is
nommu_dma_ops. However, DMA address is IOVA when IOMMU is enabled.
And it's most likely different from CPU physical address when AMD
IOMMU is not in passthrough mode.
Signed-off-by: default avatarYu Zhao <yuzhao@google.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 20f2ab24
...@@ -303,11 +303,10 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size, ...@@ -303,11 +303,10 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
} }
/* Create page table entries in ACP SRAM for the allocated memory */ /* Create page table entries in ACP SRAM for the allocated memory */
static void acp_pte_config(void __iomem *acp_mmio, struct page *pg, static void acp_pte_config(void __iomem *acp_mmio, dma_addr_t addr,
u16 num_of_pages, u32 pte_offset) u16 num_of_pages, u32 pte_offset)
{ {
u16 page_idx; u16 page_idx;
u64 addr;
u32 low; u32 low;
u32 high; u32 high;
u32 offset; u32 offset;
...@@ -317,7 +316,6 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg, ...@@ -317,7 +316,6 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
/* Load the low address of page int ACP SRAM through SRBM */ /* Load the low address of page int ACP SRAM through SRBM */
acp_reg_write((offset + (page_idx * 8)), acp_reg_write((offset + (page_idx * 8)),
acp_mmio, mmACP_SRBM_Targ_Idx_Addr); acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
addr = page_to_phys(pg);
low = lower_32_bits(addr); low = lower_32_bits(addr);
high = upper_32_bits(addr); high = upper_32_bits(addr);
...@@ -333,7 +331,7 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg, ...@@ -333,7 +331,7 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data); acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
/* Move to next physically contiguos page */ /* Move to next physically contiguos page */
pg++; addr += PAGE_SIZE;
} }
} }
...@@ -343,7 +341,7 @@ static void config_acp_dma(void __iomem *acp_mmio, ...@@ -343,7 +341,7 @@ static void config_acp_dma(void __iomem *acp_mmio,
{ {
u16 ch_acp_sysmem, ch_acp_i2s; u16 ch_acp_sysmem, ch_acp_i2s;
acp_pte_config(acp_mmio, rtd->pg, rtd->num_of_pages, acp_pte_config(acp_mmio, rtd->dma_addr, rtd->num_of_pages,
rtd->pte_offset); rtd->pte_offset);
if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) { if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) {
...@@ -850,7 +848,6 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream, ...@@ -850,7 +848,6 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
int status; int status;
uint64_t size; uint64_t size;
u32 val = 0; u32 val = 0;
struct page *pg;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
struct audio_substream_data *rtd; struct audio_substream_data *rtd;
struct snd_soc_pcm_runtime *prtd = substream->private_data; struct snd_soc_pcm_runtime *prtd = substream->private_data;
...@@ -986,16 +983,14 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream, ...@@ -986,16 +983,14 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
return status; return status;
memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
pg = virt_to_page(substream->dma_buffer.area);
if (pg) { if (substream->dma_buffer.area) {
acp_set_sram_bank_state(rtd->acp_mmio, 0, true); acp_set_sram_bank_state(rtd->acp_mmio, 0, true);
/* Save for runtime private data */ /* Save for runtime private data */
rtd->pg = pg; rtd->dma_addr = substream->dma_buffer.addr;
rtd->order = get_order(size); rtd->order = get_order(size);
/* Fill the page table entries in ACP SRAM */ /* Fill the page table entries in ACP SRAM */
rtd->pg = pg;
rtd->size = size; rtd->size = size;
rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
rtd->direction = substream->stream; rtd->direction = substream->stream;
......
...@@ -123,7 +123,7 @@ enum acp_dma_priority_level { ...@@ -123,7 +123,7 @@ enum acp_dma_priority_level {
}; };
struct audio_substream_data { struct audio_substream_data {
struct page *pg; dma_addr_t dma_addr;
unsigned int order; unsigned int order;
u16 num_of_pages; u16 num_of_pages;
u16 i2s_instance; u16 i2s_instance;
......
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