Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/ttm: expose CPU address of DMA-allocated pages

Pages allocated using the DMA API have a coherent memory mapping. Make
this mapping visible to drivers so they can decide to use it instead of
creating their own redundant one.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Acked-by: David Airlie <airlied@linux.ie>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

authored by

Alexandre Courbot and committed by
Ben Skeggs
3d50d4dc 7963e9db

+12 -5
+2
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
··· 848 848 if (count) { 849 849 d_page = list_first_entry(&pool->free_list, struct dma_page, page_list); 850 850 ttm->pages[index] = d_page->p; 851 + ttm_dma->cpu_address[index] = d_page->vaddr; 851 852 ttm_dma->dma_address[index] = d_page->dma; 852 853 list_move_tail(&d_page->page_list, &ttm_dma->pages_list); 853 854 r = 0; ··· 980 979 INIT_LIST_HEAD(&ttm_dma->pages_list); 981 980 for (i = 0; i < ttm->num_pages; i++) { 982 981 ttm->pages[i] = NULL; 982 + ttm_dma->cpu_address[i] = 0; 983 983 ttm_dma->dma_address[i] = 0; 984 984 } 985 985
+8 -5
drivers/gpu/drm/ttm/ttm_tt.c
··· 55 55 56 56 static void ttm_dma_tt_alloc_page_directory(struct ttm_dma_tt *ttm) 57 57 { 58 - ttm->ttm.pages = drm_calloc_large(ttm->ttm.num_pages, sizeof(void*)); 59 - ttm->dma_address = drm_calloc_large(ttm->ttm.num_pages, 60 - sizeof(*ttm->dma_address)); 58 + ttm->ttm.pages = drm_calloc_large(ttm->ttm.num_pages, 59 + sizeof(*ttm->ttm.pages) + 60 + sizeof(*ttm->dma_address) + 61 + sizeof(*ttm->cpu_address)); 62 + ttm->cpu_address = (void *) (ttm->ttm.pages + ttm->ttm.num_pages); 63 + ttm->dma_address = (void *) (ttm->cpu_address + ttm->ttm.num_pages); 61 64 } 62 65 63 66 #ifdef CONFIG_X86 ··· 231 228 232 229 INIT_LIST_HEAD(&ttm_dma->pages_list); 233 230 ttm_dma_tt_alloc_page_directory(ttm_dma); 234 - if (!ttm->pages || !ttm_dma->dma_address) { 231 + if (!ttm->pages) { 235 232 ttm_tt_destroy(ttm); 236 233 pr_err("Failed allocating page table\n"); 237 234 return -ENOMEM; ··· 246 243 247 244 drm_free_large(ttm->pages); 248 245 ttm->pages = NULL; 249 - drm_free_large(ttm_dma->dma_address); 246 + ttm_dma->cpu_address = NULL; 250 247 ttm_dma->dma_address = NULL; 251 248 } 252 249 EXPORT_SYMBOL(ttm_dma_tt_fini);
+2
include/drm/ttm/ttm_bo_driver.h
··· 133 133 * struct ttm_dma_tt 134 134 * 135 135 * @ttm: Base ttm_tt struct. 136 + * @cpu_address: The CPU address of the pages 136 137 * @dma_address: The DMA (bus) addresses of the pages 137 138 * @pages_list: used by some page allocation backend 138 139 * ··· 143 142 */ 144 143 struct ttm_dma_tt { 145 144 struct ttm_tt ttm; 145 + void **cpu_address; 146 146 dma_addr_t *dma_address; 147 147 struct list_head pages_list; 148 148 };