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

drm/nouveau: enable the ttm dma pool when swiotlb is active V3

If the card is capable of more than 32-bit, then use the default
TTM page pool code which allocates from anywhere in the memory.

Note: If the 'ttm.no_dma' parameter is set, the override is ignored
and the default TTM pool is used.

V2 use pci_set_consistent_dma_mask
V3 Rebase on top of no memory account changes (where/when is my
delorean when i need it ?)

CC: Ben Skeggs <bskeggs@redhat.com>
CC: Francisco Jerez <currojerez@riseup.net>
CC: Dave Airlie <airlied@redhat.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>

authored by

Konrad Rzeszutek Wilk and committed by
Dave Airlie
3230cfc3 c52494f6

+79 -61
+71 -2
drivers/gpu/drm/nouveau/nouveau_bo.c
··· 1049 1049 nouveau_fence_unref(&old_fence); 1050 1050 } 1051 1051 1052 + static int 1053 + nouveau_ttm_tt_populate(struct ttm_tt *ttm) 1054 + { 1055 + struct drm_nouveau_private *dev_priv; 1056 + struct drm_device *dev; 1057 + unsigned i; 1058 + int r; 1059 + 1060 + if (ttm->state != tt_unpopulated) 1061 + return 0; 1062 + 1063 + dev_priv = nouveau_bdev(ttm->bdev); 1064 + dev = dev_priv->dev; 1065 + 1066 + #ifdef CONFIG_SWIOTLB 1067 + if (swiotlb_nr_tbl()) { 1068 + return ttm_dma_populate(ttm, dev->dev); 1069 + } 1070 + #endif 1071 + 1072 + r = ttm_pool_populate(ttm); 1073 + if (r) { 1074 + return r; 1075 + } 1076 + 1077 + for (i = 0; i < ttm->num_pages; i++) { 1078 + ttm->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i], 1079 + 0, PAGE_SIZE, 1080 + PCI_DMA_BIDIRECTIONAL); 1081 + if (pci_dma_mapping_error(dev->pdev, ttm->dma_address[i])) { 1082 + while (--i) { 1083 + pci_unmap_page(dev->pdev, ttm->dma_address[i], 1084 + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 1085 + ttm->dma_address[i] = 0; 1086 + } 1087 + ttm_pool_unpopulate(ttm); 1088 + return -EFAULT; 1089 + } 1090 + } 1091 + return 0; 1092 + } 1093 + 1094 + static void 1095 + nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) 1096 + { 1097 + struct drm_nouveau_private *dev_priv; 1098 + struct drm_device *dev; 1099 + unsigned i; 1100 + 1101 + dev_priv = nouveau_bdev(ttm->bdev); 1102 + dev = dev_priv->dev; 1103 + 1104 + #ifdef CONFIG_SWIOTLB 1105 + if (swiotlb_nr_tbl()) { 1106 + ttm_dma_unpopulate(ttm, dev->dev); 1107 + return; 1108 + } 1109 + #endif 1110 + 1111 + for (i = 0; i < ttm->num_pages; i++) { 1112 + if (ttm->dma_address[i]) { 1113 + pci_unmap_page(dev->pdev, ttm->dma_address[i], 1114 + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 1115 + } 1116 + } 1117 + 1118 + ttm_pool_unpopulate(ttm); 1119 + } 1120 + 1052 1121 struct ttm_bo_driver nouveau_bo_driver = { 1053 1122 .ttm_tt_create = &nouveau_ttm_tt_create, 1054 - .ttm_tt_populate = &ttm_pool_populate, 1055 - .ttm_tt_unpopulate = &ttm_pool_unpopulate, 1123 + .ttm_tt_populate = &nouveau_ttm_tt_populate, 1124 + .ttm_tt_unpopulate = &nouveau_ttm_tt_unpopulate, 1056 1125 .invalidate_caches = nouveau_bo_invalidate_caches, 1057 1126 .init_mem_type = nouveau_bo_init_mem_type, 1058 1127 .evict_flags = nouveau_bo_evict_flags,
+1
drivers/gpu/drm/nouveau/nouveau_debugfs.c
··· 178 178 { "memory", nouveau_debugfs_memory_info, 0, NULL }, 179 179 { "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL }, 180 180 { "ttm_page_pool", ttm_page_alloc_debugfs, 0, NULL }, 181 + { "ttm_dma_page_pool", ttm_dma_page_alloc_debugfs, 0, NULL }, 181 182 }; 182 183 #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) 183 184
+6
drivers/gpu/drm/nouveau/nouveau_mem.c
··· 407 407 ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); 408 408 if (ret) 409 409 return ret; 410 + ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); 411 + if (ret) { 412 + /* Reset to default value. */ 413 + pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32)); 414 + } 415 + 410 416 411 417 ret = nouveau_ttm_global_init(dev_priv); 412 418 if (ret)
+1 -59
drivers/gpu/drm/nouveau/nouveau_sgdma.c
··· 13 13 u64 offset; 14 14 }; 15 15 16 - static int 17 - nouveau_sgdma_dma_map(struct ttm_tt *ttm) 18 - { 19 - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; 20 - struct drm_device *dev = nvbe->dev; 21 - int i; 22 - 23 - for (i = 0; i < ttm->num_pages; i++) { 24 - ttm->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i], 25 - 0, PAGE_SIZE, 26 - PCI_DMA_BIDIRECTIONAL); 27 - if (pci_dma_mapping_error(dev->pdev, ttm->dma_address[i])) { 28 - return -EFAULT; 29 - } 30 - } 31 - 32 - return 0; 33 - } 34 - 35 - static void 36 - nouveau_sgdma_dma_unmap(struct ttm_tt *ttm) 37 - { 38 - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; 39 - struct drm_device *dev = nvbe->dev; 40 - int i; 41 - 42 - for (i = 0; i < ttm->num_pages; i++) { 43 - if (ttm->dma_address[i]) { 44 - pci_unmap_page(dev->pdev, ttm->dma_address[i], 45 - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 46 - } 47 - ttm->dma_address[i] = 0; 48 - } 49 - } 50 - 51 16 static void 52 17 nouveau_sgdma_destroy(struct ttm_tt *ttm) 53 18 { ··· 32 67 struct drm_nouveau_private *dev_priv = dev->dev_private; 33 68 struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; 34 69 unsigned i, j, pte; 35 - int r; 36 70 37 71 NV_DEBUG(dev, "pg=0x%lx\n", mem->start); 38 - r = nouveau_sgdma_dma_map(ttm); 39 - if (r) { 40 - return r; 41 - } 42 72 43 73 nvbe->offset = mem->start << PAGE_SHIFT; 44 74 pte = (nvbe->offset >> NV_CTXDMA_PAGE_SHIFT) + 2; ··· 70 110 nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000); 71 111 } 72 112 73 - nouveau_sgdma_dma_unmap(ttm); 74 113 return 0; 75 114 } 76 115 ··· 100 141 dma_addr_t *list = ttm->dma_address; 101 142 u32 pte = mem->start << 2; 102 143 u32 cnt = ttm->num_pages; 103 - int r; 104 144 105 145 nvbe->offset = mem->start << PAGE_SHIFT; 106 - r = nouveau_sgdma_dma_map(ttm); 107 - if (r) { 108 - return r; 109 - } 110 146 111 147 while (cnt--) { 112 148 nv_wo32(pgt, pte, (*list++ >> 7) | 1); ··· 127 173 } 128 174 129 175 nv41_sgdma_flush(nvbe); 130 - nouveau_sgdma_dma_unmap(ttm); 131 176 return 0; 132 177 } 133 178 ··· 209 256 dma_addr_t *list = ttm->dma_address; 210 257 u32 pte = mem->start << 2, tmp[4]; 211 258 u32 cnt = ttm->num_pages; 212 - int i, r; 259 + int i; 213 260 214 261 nvbe->offset = mem->start << PAGE_SHIFT; 215 - r = nouveau_sgdma_dma_map(ttm); 216 - if (r) { 217 - return r; 218 - } 219 262 220 263 if (pte & 0x0000000c) { 221 264 u32 max = 4 - ((pte >> 2) & 0x3); ··· 270 321 nv44_sgdma_fill(pgt, NULL, pte, cnt); 271 322 272 323 nv44_sgdma_flush(ttm); 273 - nouveau_sgdma_dma_unmap(ttm); 274 324 return 0; 275 325 } 276 326 ··· 283 335 nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem) 284 336 { 285 337 struct nouveau_mem *node = mem->mm_node; 286 - int r; 287 338 288 339 /* noop: bound in move_notify() */ 289 - r = nouveau_sgdma_dma_map(ttm); 290 - if (r) { 291 - return r; 292 - } 293 340 node->pages = ttm->dma_address; 294 341 return 0; 295 342 } ··· 293 350 nv50_sgdma_unbind(struct ttm_tt *ttm) 294 351 { 295 352 /* noop: unbound in move_notify() */ 296 - nouveau_sgdma_dma_unmap(ttm); 297 353 return 0; 298 354 } 299 355