ttm: Include the 'struct dev' when using the DMA API.
[cascardo/linux.git] / drivers / gpu / drm / nouveau / nouveau_sgdma.c
1 #include "drmP.h"
2 #include "nouveau_drv.h"
3 #include <linux/pagemap.h>
4 #include <linux/slab.h>
5
6 #define NV_CTXDMA_PAGE_SHIFT 12
7 #define NV_CTXDMA_PAGE_SIZE  (1 << NV_CTXDMA_PAGE_SHIFT)
8 #define NV_CTXDMA_PAGE_MASK  (NV_CTXDMA_PAGE_SIZE - 1)
9
10 struct nouveau_sgdma_be {
11         struct ttm_backend backend;
12         struct drm_device *dev;
13
14         dma_addr_t *pages;
15         bool *ttm_alloced;
16         unsigned nr_pages;
17
18         unsigned pte_start;
19         bool bound;
20 };
21
22 static int
23 nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
24                        struct page **pages, struct page *dummy_read_page,
25                        dma_addr_t *dma_addrs)
26 {
27         struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
28         struct drm_device *dev = nvbe->dev;
29
30         NV_DEBUG(nvbe->dev, "num_pages = %ld\n", num_pages);
31
32         if (nvbe->pages)
33                 return -EINVAL;
34
35         nvbe->pages = kmalloc(sizeof(dma_addr_t) * num_pages, GFP_KERNEL);
36         if (!nvbe->pages)
37                 return -ENOMEM;
38
39         nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL);
40         if (!nvbe->ttm_alloced)
41                 return -ENOMEM;
42
43         nvbe->nr_pages = 0;
44         while (num_pages--) {
45                 if (dma_addrs[nvbe->nr_pages] != DMA_ERROR_CODE) {
46                         nvbe->pages[nvbe->nr_pages] =
47                                         dma_addrs[nvbe->nr_pages];
48                         nvbe->ttm_alloced[nvbe->nr_pages] = true;
49                 } else {
50                         nvbe->pages[nvbe->nr_pages] =
51                                 pci_map_page(dev->pdev, pages[nvbe->nr_pages], 0,
52                                      PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
53                         if (pci_dma_mapping_error(dev->pdev,
54                                                   nvbe->pages[nvbe->nr_pages])) {
55                                 be->func->clear(be);
56                                 return -EFAULT;
57                         }
58                 }
59
60                 nvbe->nr_pages++;
61         }
62
63         return 0;
64 }
65
66 static void
67 nouveau_sgdma_clear(struct ttm_backend *be)
68 {
69         struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
70         struct drm_device *dev;
71
72         if (nvbe && nvbe->pages) {
73                 dev = nvbe->dev;
74                 NV_DEBUG(dev, "\n");
75
76                 if (nvbe->bound)
77                         be->func->unbind(be);
78
79                 while (nvbe->nr_pages--) {
80                         if (!nvbe->ttm_alloced[nvbe->nr_pages])
81                                 pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
82                                        PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
83                 }
84                 kfree(nvbe->pages);
85                 kfree(nvbe->ttm_alloced);
86                 nvbe->pages = NULL;
87                 nvbe->ttm_alloced = NULL;
88                 nvbe->nr_pages = 0;
89         }
90 }
91
92 static inline unsigned
93 nouveau_sgdma_pte(struct drm_device *dev, uint64_t offset)
94 {
95         struct drm_nouveau_private *dev_priv = dev->dev_private;
96         unsigned pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
97
98         if (dev_priv->card_type < NV_50)
99                 return pte + 2;
100
101         return pte << 1;
102 }
103
104 static int
105 nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
106 {
107         struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
108         struct drm_device *dev = nvbe->dev;
109         struct drm_nouveau_private *dev_priv = dev->dev_private;
110         struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
111         unsigned i, j, pte;
112
113         NV_DEBUG(dev, "pg=0x%lx\n", mem->start);
114
115         pte = nouveau_sgdma_pte(nvbe->dev, mem->start << PAGE_SHIFT);
116         nvbe->pte_start = pte;
117         for (i = 0; i < nvbe->nr_pages; i++) {
118                 dma_addr_t dma_offset = nvbe->pages[i];
119                 uint32_t offset_l = lower_32_bits(dma_offset);
120                 uint32_t offset_h = upper_32_bits(dma_offset);
121
122                 for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) {
123                         if (dev_priv->card_type < NV_50) {
124                                 nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3);
125                                 pte += 1;
126                         } else {
127                                 nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 0x21);
128                                 nv_wo32(gpuobj, (pte * 4) + 4, offset_h & 0xff);
129                                 pte += 2;
130                         }
131
132                         dma_offset += NV_CTXDMA_PAGE_SIZE;
133                 }
134         }
135         dev_priv->engine.instmem.flush(nvbe->dev);
136
137         if (dev_priv->card_type == NV_50) {
138                 nv50_vm_flush(dev, 5); /* PGRAPH */
139                 nv50_vm_flush(dev, 0); /* PFIFO */
140         }
141
142         nvbe->bound = true;
143         return 0;
144 }
145
146 static int
147 nouveau_sgdma_unbind(struct ttm_backend *be)
148 {
149         struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
150         struct drm_device *dev = nvbe->dev;
151         struct drm_nouveau_private *dev_priv = dev->dev_private;
152         struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
153         unsigned i, j, pte;
154
155         NV_DEBUG(dev, "\n");
156
157         if (!nvbe->bound)
158                 return 0;
159
160         pte = nvbe->pte_start;
161         for (i = 0; i < nvbe->nr_pages; i++) {
162                 dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus;
163
164                 for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) {
165                         if (dev_priv->card_type < NV_50) {
166                                 nv_wo32(gpuobj, (pte * 4) + 0, dma_offset | 3);
167                                 pte += 1;
168                         } else {
169                                 nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000);
170                                 nv_wo32(gpuobj, (pte * 4) + 4, 0x00000000);
171                                 pte += 2;
172                         }
173
174                         dma_offset += NV_CTXDMA_PAGE_SIZE;
175                 }
176         }
177         dev_priv->engine.instmem.flush(nvbe->dev);
178
179         if (dev_priv->card_type == NV_50) {
180                 nv50_vm_flush(dev, 5);
181                 nv50_vm_flush(dev, 0);
182         }
183
184         nvbe->bound = false;
185         return 0;
186 }
187
188 static void
189 nouveau_sgdma_destroy(struct ttm_backend *be)
190 {
191         struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
192
193         if (be) {
194                 NV_DEBUG(nvbe->dev, "\n");
195
196                 if (nvbe) {
197                         if (nvbe->pages)
198                                 be->func->clear(be);
199                         kfree(nvbe);
200                 }
201         }
202 }
203
204 static struct ttm_backend_func nouveau_sgdma_backend = {
205         .populate               = nouveau_sgdma_populate,
206         .clear                  = nouveau_sgdma_clear,
207         .bind                   = nouveau_sgdma_bind,
208         .unbind                 = nouveau_sgdma_unbind,
209         .destroy                = nouveau_sgdma_destroy
210 };
211
212 struct ttm_backend *
213 nouveau_sgdma_init_ttm(struct drm_device *dev)
214 {
215         struct drm_nouveau_private *dev_priv = dev->dev_private;
216         struct nouveau_sgdma_be *nvbe;
217
218         if (!dev_priv->gart_info.sg_ctxdma)
219                 return NULL;
220
221         nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL);
222         if (!nvbe)
223                 return NULL;
224
225         nvbe->dev = dev;
226
227         nvbe->backend.func      = &nouveau_sgdma_backend;
228
229         return &nvbe->backend;
230 }
231
232 int
233 nouveau_sgdma_init(struct drm_device *dev)
234 {
235         struct drm_nouveau_private *dev_priv = dev->dev_private;
236         struct pci_dev *pdev = dev->pdev;
237         struct nouveau_gpuobj *gpuobj = NULL;
238         uint32_t aper_size, obj_size;
239         int i, ret;
240
241         if (dev_priv->card_type < NV_50) {
242                 aper_size = (64 * 1024 * 1024);
243                 obj_size  = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4;
244                 obj_size += 8; /* ctxdma header */
245         } else {
246                 /* 1 entire VM page table */
247                 aper_size = (512 * 1024 * 1024);
248                 obj_size  = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 8;
249         }
250
251         ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16,
252                                       NVOBJ_FLAG_ZERO_ALLOC |
253                                       NVOBJ_FLAG_ZERO_FREE, &gpuobj);
254         if (ret) {
255                 NV_ERROR(dev, "Error creating sgdma object: %d\n", ret);
256                 return ret;
257         }
258
259         dev_priv->gart_info.sg_dummy_page =
260                 alloc_page(GFP_KERNEL|__GFP_DMA32|__GFP_ZERO);
261         if (!dev_priv->gart_info.sg_dummy_page) {
262                 nouveau_gpuobj_ref(NULL, &gpuobj);
263                 return -ENOMEM;
264         }
265
266         set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags);
267         dev_priv->gart_info.sg_dummy_bus =
268                 pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0,
269                              PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
270         if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) {
271                 nouveau_gpuobj_ref(NULL, &gpuobj);
272                 return -EFAULT;
273         }
274
275         if (dev_priv->card_type < NV_50) {
276                 /* special case, allocated from global instmem heap so
277                  * cinst is invalid, we use it on all channels though so
278                  * cinst needs to be valid, set it the same as pinst
279                  */
280                 gpuobj->cinst = gpuobj->pinst;
281
282                 /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
283                  * confirmed to work on c51.  Perhaps means NV_DMA_TARGET_PCIE
284                  * on those cards? */
285                 nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY |
286                                    (1 << 12) /* PT present */ |
287                                    (0 << 13) /* PT *not* linear */ |
288                                    (NV_DMA_ACCESS_RW  << 14) |
289                                    (NV_DMA_TARGET_PCI << 16));
290                 nv_wo32(gpuobj, 4, aper_size - 1);
291                 for (i = 2; i < 2 + (aper_size >> 12); i++) {
292                         nv_wo32(gpuobj, i * 4,
293                                 dev_priv->gart_info.sg_dummy_bus | 3);
294                 }
295         } else {
296                 for (i = 0; i < obj_size; i += 8) {
297                         nv_wo32(gpuobj, i + 0, 0x00000000);
298                         nv_wo32(gpuobj, i + 4, 0x00000000);
299                 }
300         }
301         dev_priv->engine.instmem.flush(dev);
302
303         dev_priv->gart_info.type      = NOUVEAU_GART_SGDMA;
304         dev_priv->gart_info.aper_base = 0;
305         dev_priv->gart_info.aper_size = aper_size;
306         dev_priv->gart_info.sg_ctxdma = gpuobj;
307         return 0;
308 }
309
310 void
311 nouveau_sgdma_takedown(struct drm_device *dev)
312 {
313         struct drm_nouveau_private *dev_priv = dev->dev_private;
314
315         if (dev_priv->gart_info.sg_dummy_page) {
316                 pci_unmap_page(dev->pdev, dev_priv->gart_info.sg_dummy_bus,
317                                NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
318                 unlock_page(dev_priv->gart_info.sg_dummy_page);
319                 __free_page(dev_priv->gart_info.sg_dummy_page);
320                 dev_priv->gart_info.sg_dummy_page = NULL;
321                 dev_priv->gart_info.sg_dummy_bus = 0;
322         }
323
324         nouveau_gpuobj_ref(NULL, &dev_priv->gart_info.sg_ctxdma);
325 }
326
327 int
328 nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
329 {
330         struct drm_nouveau_private *dev_priv = dev->dev_private;
331         struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
332         int pte;
333
334         pte = (offset >> NV_CTXDMA_PAGE_SHIFT) << 2;
335         if (dev_priv->card_type < NV_50) {
336                 *page = nv_ro32(gpuobj, (pte + 8)) & ~NV_CTXDMA_PAGE_MASK;
337                 return 0;
338         }
339
340         NV_ERROR(dev, "Unimplemented on NV50\n");
341         return -EINVAL;
342 }