summaryrefslogtreecommitdiffstats
path: root/sound/soc/amd
diff options
context:
space:
mode:
authorYu Zhao <yuzhao@google.com>2018-12-04 17:42:52 -0500
committerMark Brown <broonie@kernel.org>2018-12-06 07:53:04 -0500
commitd6d08273996b3363178b920ccfa74acabaf67963 (patch)
treedb0aa557c36a9b2ab3b262a0d2bb9462b27cf012 /sound/soc/amd
parent20f2ab247d3b787af91c1aa5eb27c5061744c154 (diff)
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: Yu Zhao <yuzhao@google.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/amd')
-rw-r--r--sound/soc/amd/acp-pcm-dma.c15
-rw-r--r--sound/soc/amd/acp.h2
2 files changed, 6 insertions, 11 deletions
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index cdebab2f8ce5..fd3db4c37882 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -303,11 +303,10 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
303} 303}
304 304
305/* Create page table entries in ACP SRAM for the allocated memory */ 305/* Create page table entries in ACP SRAM for the allocated memory */
306static void acp_pte_config(void __iomem *acp_mmio, struct page *pg, 306static void acp_pte_config(void __iomem *acp_mmio, dma_addr_t addr,
307 u16 num_of_pages, u32 pte_offset) 307 u16 num_of_pages, u32 pte_offset)
308{ 308{
309 u16 page_idx; 309 u16 page_idx;
310 u64 addr;
311 u32 low; 310 u32 low;
312 u32 high; 311 u32 high;
313 u32 offset; 312 u32 offset;
@@ -317,7 +316,6 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
317 /* Load the low address of page int ACP SRAM through SRBM */ 316 /* Load the low address of page int ACP SRAM through SRBM */
318 acp_reg_write((offset + (page_idx * 8)), 317 acp_reg_write((offset + (page_idx * 8)),
319 acp_mmio, mmACP_SRBM_Targ_Idx_Addr); 318 acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
320 addr = page_to_phys(pg);
321 319
322 low = lower_32_bits(addr); 320 low = lower_32_bits(addr);
323 high = upper_32_bits(addr); 321 high = upper_32_bits(addr);
@@ -333,7 +331,7 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
333 acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data); 331 acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
334 332
335 /* Move to next physically contiguos page */ 333 /* Move to next physically contiguos page */
336 pg++; 334 addr += PAGE_SIZE;
337 } 335 }
338} 336}
339 337
@@ -343,7 +341,7 @@ static void config_acp_dma(void __iomem *acp_mmio,
343{ 341{
344 u16 ch_acp_sysmem, ch_acp_i2s; 342 u16 ch_acp_sysmem, ch_acp_i2s;
345 343
346 acp_pte_config(acp_mmio, rtd->pg, rtd->num_of_pages, 344 acp_pte_config(acp_mmio, rtd->dma_addr, rtd->num_of_pages,
347 rtd->pte_offset); 345 rtd->pte_offset);
348 346
349 if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) { 347 if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -850,7 +848,6 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
850 int status; 848 int status;
851 uint64_t size; 849 uint64_t size;
852 u32 val = 0; 850 u32 val = 0;
853 struct page *pg;
854 struct snd_pcm_runtime *runtime; 851 struct snd_pcm_runtime *runtime;
855 struct audio_substream_data *rtd; 852 struct audio_substream_data *rtd;
856 struct snd_soc_pcm_runtime *prtd = substream->private_data; 853 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 return status; 983 return status;
987 984
988 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); 985 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
989 pg = virt_to_page(substream->dma_buffer.area);
990 986
991 if (pg) { 987 if (substream->dma_buffer.area) {
992 acp_set_sram_bank_state(rtd->acp_mmio, 0, true); 988 acp_set_sram_bank_state(rtd->acp_mmio, 0, true);
993 /* Save for runtime private data */ 989 /* Save for runtime private data */
994 rtd->pg = pg; 990 rtd->dma_addr = substream->dma_buffer.addr;
995 rtd->order = get_order(size); 991 rtd->order = get_order(size);
996 992
997 /* Fill the page table entries in ACP SRAM */ 993 /* Fill the page table entries in ACP SRAM */
998 rtd->pg = pg;
999 rtd->size = size; 994 rtd->size = size;
1000 rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; 995 rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
1001 rtd->direction = substream->stream; 996 rtd->direction = substream->stream;
diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h
index dbbb1a85638d..e5ab6c6040a6 100644
--- a/sound/soc/amd/acp.h
+++ b/sound/soc/amd/acp.h
@@ -123,7 +123,7 @@ enum acp_dma_priority_level {
123}; 123};
124 124
125struct audio_substream_data { 125struct audio_substream_data {
126 struct page *pg; 126 dma_addr_t dma_addr;
127 unsigned int order; 127 unsigned int order;
128 u16 num_of_pages; 128 u16 num_of_pages;
129 u16 i2s_instance; 129 u16 i2s_instance;