Skip to content

Commit 6672912

Browse files
mariobalanica6by9
authored andcommitted
drm/nouveau: Support non-coherent hardware
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
1 parent a4f632b commit 6672912

File tree

6 files changed

+32
-26
lines changed

6 files changed

+32
-26
lines changed

drivers/gpu/drm/nouveau/nouveau_drv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ nouveau_drm(struct drm_device *dev)
317317
static inline bool
318318
nouveau_drm_use_coherent_gpu_mapping(struct nouveau_drm *drm)
319319
{
320+
#ifdef CONFIG_DRM_FORCE_DMA_WRITE_COMBINED_MAPPINGS
321+
return false;
322+
#endif
320323
struct nvif_mmu *mmu = &drm->client.mmu;
321324
return !(mmu->type[drm->ttm.type_host[0]].type & NVIF_MEM_UNCACHED);
322325
}

drivers/gpu/drm/nouveau/nouveau_sgdma.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,7 @@ nouveau_sgdma_create_ttm(struct ttm_buffer_object *bo, uint32_t page_flags)
7272
struct nouveau_sgdma_be *nvbe;
7373
enum ttm_caching caching;
7474

75-
if (nvbo->force_coherent)
76-
caching = ttm_uncached;
77-
else if (drm->agp.bridge)
75+
if (nvbo->force_coherent || drm->agp.bridge)
7876
caching = ttm_write_combined;
7977
else
8078
caching = ttm_cached;

drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,8 @@ nvkm_device_pci_func = {
16451645
.irq = nvkm_device_pci_irq,
16461646
.resource_addr = nvkm_device_pci_resource_addr,
16471647
.resource_size = nvkm_device_pci_resource_size,
1648-
.cpu_coherent = !IS_ENABLED(CONFIG_ARM),
1648+
.cpu_coherent = !IS_ENABLED(CONFIG_ARM) &&
1649+
!IS_ENABLED(CONFIG_DRM_FORCE_DMA_WRITE_COMBINED_MAPPINGS),
16491650
};
16501651

16511652
int

drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,8 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev)
248248
nvkm_falcon_fw_dtor(&fb->vpr_scrubber);
249249

250250
if (fb->sysmem.flush_page) {
251-
dma_unmap_page(subdev->device->dev, fb->sysmem.flush_page_addr,
252-
PAGE_SIZE, DMA_BIDIRECTIONAL);
253-
__free_page(fb->sysmem.flush_page);
251+
dma_free_coherent(subdev->device->dev, PAGE_SIZE,
252+
fb->sysmem.flush_page, fb->sysmem.flush_page_addr);
254253
}
255254

256255
if (fb->func->dtor)
@@ -279,14 +278,11 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device,
279278
mutex_init(&fb->tags.mutex);
280279

281280
if (func->sysmem.flush_page_init) {
282-
fb->sysmem.flush_page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
281+
fb->sysmem.flush_page = dma_alloc_coherent(device->dev, PAGE_SIZE,
282+
&fb->sysmem.flush_page_addr,
283+
GFP_KERNEL | __GFP_ZERO);
283284
if (!fb->sysmem.flush_page)
284285
return -ENOMEM;
285-
286-
fb->sysmem.flush_page_addr = dma_map_page(device->dev, fb->sysmem.flush_page,
287-
0, PAGE_SIZE, DMA_BIDIRECTIONAL);
288-
if (dma_mapping_error(device->dev, fb->sysmem.flush_page_addr))
289-
return -EFAULT;
290286
}
291287

292288
return 0;

drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,12 +1571,12 @@ nvkm_gsp_sg_free(struct nvkm_device *device, struct sg_table *sgt)
15711571
struct scatterlist *sgl;
15721572
int i;
15731573

1574-
dma_unmap_sgtable(device->dev, sgt, DMA_BIDIRECTIONAL, 0);
1575-
15761574
for_each_sgtable_sg(sgt, sgl, i) {
1577-
struct page *page = sg_page(sgl);
1575+
void *cpu_addr = sg_virt(sgl);
1576+
dma_addr_t dma_addr = sg_dma_address(sgl);
15781577

1579-
__free_page(page);
1578+
if (cpu_addr && dma_addr)
1579+
dma_free_coherent(device->dev, PAGE_SIZE, cpu_addr, dma_addr);
15801580
}
15811581

15821582
sg_free_table(sgt);
@@ -1594,21 +1594,23 @@ nvkm_gsp_sg(struct nvkm_device *device, u64 size, struct sg_table *sgt)
15941594
return ret;
15951595

15961596
for_each_sgtable_sg(sgt, sgl, i) {
1597-
struct page *page = alloc_page(GFP_KERNEL);
1597+
void *cpu_addr;
1598+
dma_addr_t dma_addr;
15981599

1599-
if (!page) {
1600+
cpu_addr = dma_alloc_coherent(device->dev, PAGE_SIZE,
1601+
&dma_addr, GFP_KERNEL);
1602+
if (!cpu_addr) {
16001603
nvkm_gsp_sg_free(device, sgt);
16011604
return -ENOMEM;
16021605
}
16031606

1604-
sg_set_page(sgl, page, PAGE_SIZE, 0);
1607+
/* XXX: unsafe to use virt_to_page with dma_alloc_coherent */
1608+
sg_set_page(sgl, virt_to_page(cpu_addr), PAGE_SIZE, 0);
1609+
sg_dma_address(sgl) = dma_addr;
1610+
sg_dma_len(sgl) = PAGE_SIZE;
16051611
}
16061612

1607-
ret = dma_map_sgtable(device->dev, sgt, DMA_BIDIRECTIONAL, 0);
1608-
if (ret)
1609-
nvkm_gsp_sg_free(device, sgt);
1610-
1611-
return ret;
1613+
return 0;
16121614
}
16131615

16141616
static void

drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,14 @@ int
133133
nvkm_mem_map_host(struct nvkm_memory *memory, void **pmap)
134134
{
135135
struct nvkm_mem *mem = nvkm_mem(memory);
136+
pgprot_t prot = PAGE_KERNEL;
137+
138+
#ifdef CONFIG_DRM_FORCE_DMA_WRITE_COMBINED_MAPPINGS
139+
prot = pgprot_writecombine(prot);
140+
#endif
141+
136142
if (mem->mem) {
137-
*pmap = vmap(mem->mem, mem->pages, VM_MAP, PAGE_KERNEL);
143+
*pmap = vmap(mem->mem, mem->pages, VM_MAP, prot);
138144
return *pmap ? 0 : -EFAULT;
139145
}
140146
return -EINVAL;

0 commit comments

Comments
 (0)