]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/gpu/drm/nouveau/nouveau_sgdma.c
drm/nouveau: port to nvif client/device/objects
[mirror_ubuntu-jammy-kernel.git] / drivers / gpu / drm / nouveau / nouveau_sgdma.c
CommitLineData
6ee73861 1#include <linux/pagemap.h>
5a0e3ad6 2#include <linux/slab.h>
6ee73861 3
ebb945a9
BS
4#include "nouveau_drm.h"
5#include "nouveau_ttm.h"
6ee73861
BS
6
7struct nouveau_sgdma_be {
8e7e7052
JG
8 /* this has to be the first field so populate/unpopulated in
9 * nouve_bo.c works properly, otherwise have to move them here
10 */
11 struct ttm_dma_tt ttm;
6ee73861 12 struct drm_device *dev;
3863c9bc 13 struct nouveau_mem *node;
6ee73861
BS
14};
15
efa58db3 16static void
649bf3ca 17nouveau_sgdma_destroy(struct ttm_tt *ttm)
efa58db3 18{
649bf3ca 19 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
efa58db3 20
649bf3ca 21 if (ttm) {
8e7e7052 22 ttm_dma_tt_fini(&nvbe->ttm);
649bf3ca 23 kfree(nvbe);
efa58db3
BS
24 }
25}
26
6ee73861 27static int
649bf3ca 28nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
6ee73861 29{
649bf3ca 30 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
3863c9bc 31 struct nouveau_mem *node = mem->mm_node;
6ee73861 32
3863c9bc 33 if (ttm->sg) {
2e2cfbe6
BS
34 node->sg = ttm->sg;
35 node->pages = NULL;
3863c9bc 36 } else {
2e2cfbe6 37 node->sg = NULL;
3863c9bc 38 node->pages = nvbe->ttm.dma_address;
6ee73861 39 }
2e2cfbe6 40 node->size = (mem->num_pages << PAGE_SHIFT) >> 12;
6ee73861 41
2e2cfbe6 42 nouveau_vm_map(&node->vma[0], node);
3863c9bc 43 nvbe->node = node;
6ee73861
BS
44 return 0;
45}
46
47static int
649bf3ca 48nv04_sgdma_unbind(struct ttm_tt *ttm)
6ee73861 49{
649bf3ca 50 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
3863c9bc 51 nouveau_vm_unmap(&nvbe->node->vma[0]);
6ee73861
BS
52 return 0;
53}
54
efa58db3 55static struct ttm_backend_func nv04_sgdma_backend = {
efa58db3
BS
56 .bind = nv04_sgdma_bind,
57 .unbind = nv04_sgdma_unbind,
58 .destroy = nouveau_sgdma_destroy
59};
6ee73861 60
b571fe21 61static int
649bf3ca 62nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
b571fe21 63{
8e7e7052 64 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
26c0c9e3 65 struct nouveau_mem *node = mem->mm_node;
649bf3ca 66
26c0c9e3 67 /* noop: bound in move_notify() */
22b33e8e 68 if (ttm->sg) {
2e2cfbe6
BS
69 node->sg = ttm->sg;
70 node->pages = NULL;
71 } else {
72 node->sg = NULL;
22b33e8e 73 node->pages = nvbe->ttm.dma_address;
2e2cfbe6
BS
74 }
75 node->size = (mem->num_pages << PAGE_SHIFT) >> 12;
b571fe21
BS
76 return 0;
77}
78
79static int
649bf3ca 80nv50_sgdma_unbind(struct ttm_tt *ttm)
b571fe21 81{
26c0c9e3 82 /* noop: unbound in move_notify() */
b571fe21
BS
83 return 0;
84}
85
b571fe21 86static struct ttm_backend_func nv50_sgdma_backend = {
b571fe21
BS
87 .bind = nv50_sgdma_bind,
88 .unbind = nv50_sgdma_unbind,
89 .destroy = nouveau_sgdma_destroy
90};
91
649bf3ca
JG
92struct ttm_tt *
93nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
94 unsigned long size, uint32_t page_flags,
95 struct page *dummy_read_page)
6ee73861 96{
ebb945a9 97 struct nouveau_drm *drm = nouveau_bdev(bdev);
6ee73861
BS
98 struct nouveau_sgdma_be *nvbe;
99
6ee73861
BS
100 nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL);
101 if (!nvbe)
102 return NULL;
103
ebb945a9 104 nvbe->dev = drm->dev;
967e7bde 105 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA)
ebb945a9
BS
106 nvbe->ttm.ttm.func = &nv04_sgdma_backend;
107 else
108 nvbe->ttm.ttm.func = &nv50_sgdma_backend;
6ee73861 109
7a59cc34 110 if (ttm_dma_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page))
649bf3ca 111 return NULL;
8e7e7052 112 return &nvbe->ttm.ttm;
6ee73861 113}