diff options
author | Yu Zhao <yuzhao@google.com> | 2018-12-04 17:42:52 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-12-06 07:53:04 -0500 |
commit | d6d08273996b3363178b920ccfa74acabaf67963 (patch) | |
tree | db0aa557c36a9b2ab3b262a0d2bb9462b27cf012 /sound/soc/amd | |
parent | 20f2ab247d3b787af91c1aa5eb27c5061744c154 (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.c | 15 | ||||
-rw-r--r-- | sound/soc/amd/acp.h | 2 |
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 */ |
306 | static void acp_pte_config(void __iomem *acp_mmio, struct page *pg, | 306 | static 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 | ||
125 | struct audio_substream_data { | 125 | struct 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; |