OSDN Git Service

Make it compile again.
[android-x86/external-libdrm.git] / shared-core / nouveau_mem.c
1 /*
2  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3  * Copyright 2005 Stephane Marchesin
4  *
5  * The Weather Channel (TM) funded Tungsten Graphics to develop the
6  * initial release of the Radeon 8500 driver under the XFree86 license.
7  * This notice must be preserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the next
17  * paragraph) shall be included in all copies or substantial portions of the
18  * Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  *
28  * Authors:
29  *    Keith Whitwell <keith@tungstengraphics.com>
30  */
31
32
33 #include "drmP.h"
34 #include "drm.h"
35 #include "drm_sarea.h"
36 #include "nouveau_drv.h"
37 #include "nv50_kms_wrapper.h"
38
39
40 static struct mem_block *
41 split_block(struct mem_block *p, uint64_t start, uint64_t size,
42             struct drm_file *file_priv)
43 {
44         /* Maybe cut off the start of an existing block */
45         if (start > p->start) {
46                 struct mem_block *newblock =
47                         drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
48                 if (!newblock)
49                         goto out;
50                 newblock->start = start;
51                 newblock->size = p->size - (start - p->start);
52                 newblock->file_priv = NULL;
53                 newblock->next = p->next;
54                 newblock->prev = p;
55                 p->next->prev = newblock;
56                 p->next = newblock;
57                 p->size -= newblock->size;
58                 p = newblock;
59         }
60
61         /* Maybe cut off the end of an existing block */
62         if (size < p->size) {
63                 struct mem_block *newblock =
64                         drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
65                 if (!newblock)
66                         goto out;
67                 newblock->start = start + size;
68                 newblock->size = p->size - size;
69                 newblock->file_priv = NULL;
70                 newblock->next = p->next;
71                 newblock->prev = p;
72                 p->next->prev = newblock;
73                 p->next = newblock;
74                 p->size = size;
75         }
76
77 out:
78         /* Our block is in the middle */
79         p->file_priv = file_priv;
80         return p;
81 }
82
83 struct mem_block *
84 nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size,
85                         int align2, struct drm_file *file_priv, int tail)
86 {
87         struct mem_block *p;
88         uint64_t mask = (1 << align2) - 1;
89
90         if (!heap)
91                 return NULL;
92
93         if (tail) {
94                 list_for_each_prev(p, heap) {
95                         uint64_t start = ((p->start + p->size) - size) & ~mask;
96
97                         if (p->file_priv == 0 && start >= p->start &&
98                             start + size <= p->start + p->size)
99                                 return split_block(p, start, size, file_priv);
100                 }
101         } else {
102                 list_for_each(p, heap) {
103                         uint64_t start = (p->start + mask) & ~mask;
104
105                         if (p->file_priv == 0 &&
106                             start + size <= p->start + p->size)
107                                 return split_block(p, start, size, file_priv);
108                 }
109         }
110
111         return NULL;
112 }
113
114 static struct mem_block *find_block(struct mem_block *heap, uint64_t start)
115 {
116         struct mem_block *p;
117
118         list_for_each(p, heap)
119                 if (p->start == start)
120                         return p;
121
122         return NULL;
123 }
124
125 struct mem_block *find_block_by_handle(struct mem_block *heap, drm_handle_t handle)
126 {
127         struct mem_block *p;
128
129         list_for_each(p, heap)
130                 if (p->map_handle == handle)
131                         return p;
132
133         return NULL;
134 }
135
136 void nouveau_mem_free_block(struct mem_block *p)
137 {
138         p->file_priv = NULL;
139
140         /* Assumes a single contiguous range.  Needs a special file_priv in
141          * 'heap' to stop it being subsumed.
142          */
143         if (p->next->file_priv == 0) {
144                 struct mem_block *q = p->next;
145                 p->size += q->size;
146                 p->next = q->next;
147                 p->next->prev = p;
148                 drm_free(q, sizeof(*q), DRM_MEM_BUFS);
149         }
150
151         if (p->prev->file_priv == 0) {
152                 struct mem_block *q = p->prev;
153                 q->size += p->size;
154                 q->next = p->next;
155                 q->next->prev = q;
156                 drm_free(p, sizeof(*q), DRM_MEM_BUFS);
157         }
158 }
159
160 /* Initialize.  How to check for an uninitialized heap?
161  */
162 int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start,
163                           uint64_t size)
164 {
165         struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS);
166
167         if (!blocks)
168                 return -ENOMEM;
169
170         *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS);
171         if (!*heap) {
172                 drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS);
173                 return -ENOMEM;
174         }
175
176         blocks->start = start;
177         blocks->size = size;
178         blocks->file_priv = NULL;
179         blocks->next = blocks->prev = *heap;
180
181         memset(*heap, 0, sizeof(**heap));
182         (*heap)->file_priv = (struct drm_file *) - 1;
183         (*heap)->next = (*heap)->prev = blocks;
184         return 0;
185 }
186
187 /*
188  * Free all blocks associated with the releasing file_priv
189  */
190 void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap)
191 {
192         struct mem_block *p;
193
194         if (!heap || !heap->next)
195                 return;
196
197         list_for_each(p, heap) {
198                 if (p->file_priv == file_priv)
199                         p->file_priv = NULL;
200         }
201
202         /* Assumes a single contiguous range.  Needs a special file_priv in
203          * 'heap' to stop it being subsumed.
204          */
205         list_for_each(p, heap) {
206                 while ((p->file_priv == 0) && (p->next->file_priv == 0) &&
207                        (p->next!=heap)) {
208                         struct mem_block *q = p->next;
209                         p->size += q->size;
210                         p->next = q->next;
211                         p->next->prev = p;
212                         drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
213                 }
214         }
215 }
216
217 /*
218  * Cleanup everything
219  */
220 void nouveau_mem_takedown(struct mem_block **heap)
221 {
222         struct mem_block *p;
223
224         if (!*heap)
225                 return;
226
227         for (p = (*heap)->next; p != *heap;) {
228                 struct mem_block *q = p;
229                 p = p->next;
230                 drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
231         }
232
233         drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER);
234         *heap = NULL;
235 }
236
237 void nouveau_mem_close(struct drm_device *dev)
238 {
239         struct drm_nouveau_private *dev_priv = dev->dev_private;
240
241         nouveau_mem_takedown(&dev_priv->agp_heap);
242         nouveau_mem_takedown(&dev_priv->fb_heap);
243         if (dev_priv->pci_heap)
244                 nouveau_mem_takedown(&dev_priv->pci_heap);
245 }
246
247 /*XXX won't work on BSD because of pci_read_config_dword */
248 static uint32_t
249 nouveau_mem_fb_amount_igp(struct drm_device *dev)
250 {
251 #if defined(__linux__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
252         struct drm_nouveau_private *dev_priv = dev->dev_private;
253         struct pci_dev *bridge;
254         uint32_t mem;
255
256         bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0,1));
257         if (!bridge) {
258                 DRM_ERROR("no bridge device\n");
259                 return 0;
260         }
261
262         if (dev_priv->flags&NV_NFORCE) {
263                 pci_read_config_dword(bridge, 0x7C, &mem);
264                 return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
265         } else
266         if(dev_priv->flags&NV_NFORCE2) {
267                 pci_read_config_dword(bridge, 0x84, &mem);
268                 return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
269         }
270
271         DRM_ERROR("impossible!\n");
272 #else
273         DRM_ERROR("Linux kernel >= 2.6.19 required to check for igp memory amount\n");
274 #endif
275
276         return 0;
277 }
278
279 /* returns the amount of FB ram in bytes */
280 uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
281 {
282         struct drm_nouveau_private *dev_priv=dev->dev_private;
283         switch(dev_priv->card_type)
284         {
285                 case NV_04:
286                 case NV_05:
287                         if (NV_READ(NV03_BOOT_0) & 0x00000100) {
288                                 return (((NV_READ(NV03_BOOT_0) >> 12) & 0xf)*2+2)*1024*1024;
289                         } else
290                         switch(NV_READ(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT)
291                         {
292                                 case NV04_BOOT_0_RAM_AMOUNT_32MB:
293                                         return 32*1024*1024;
294                                 case NV04_BOOT_0_RAM_AMOUNT_16MB:
295                                         return 16*1024*1024;
296                                 case NV04_BOOT_0_RAM_AMOUNT_8MB:
297                                         return 8*1024*1024;
298                                 case NV04_BOOT_0_RAM_AMOUNT_4MB:
299                                         return 4*1024*1024;
300                         }
301                         break;
302                 case NV_10:
303                 case NV_11:
304                 case NV_17:
305                 case NV_20:
306                 case NV_30:
307                 case NV_40:
308                 case NV_44:
309                 case NV_50:
310                 default:
311                         if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
312                                 return nouveau_mem_fb_amount_igp(dev);
313                         } else {
314                                 uint64_t mem;
315
316                                 mem = (NV_READ(NV04_FIFO_DATA) &
317                                        NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
318                                       NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
319                                 return mem*1024*1024;
320                         }
321                         break;
322         }
323
324         DRM_ERROR("Unable to detect video ram size. Please report your setup to " DRIVER_EMAIL "\n");
325         return 0;
326 }
327
328 static void nouveau_mem_reset_agp(struct drm_device *dev)
329 {
330         struct drm_nouveau_private *dev_priv = dev->dev_private;
331         uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable;
332
333         saved_pci_nv_1 = NV_READ(NV04_PBUS_PCI_NV_1);
334         saved_pci_nv_19 = NV_READ(NV04_PBUS_PCI_NV_19);
335
336         /* clear busmaster bit */
337         NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4);
338         /* clear SBA and AGP bits */
339         NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff);
340
341         /* power cycle pgraph, if enabled */
342         pmc_enable = NV_READ(NV03_PMC_ENABLE);
343         if (pmc_enable & NV_PMC_ENABLE_PGRAPH) {
344                 NV_WRITE(NV03_PMC_ENABLE, pmc_enable & ~NV_PMC_ENABLE_PGRAPH);
345                 NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
346                                 NV_PMC_ENABLE_PGRAPH);
347         }
348
349         /* and restore (gives effect of resetting AGP) */
350         NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
351         NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
352 }
353
354 static int
355 nouveau_mem_init_agp(struct drm_device *dev, int ttm)
356 {
357         struct drm_nouveau_private *dev_priv = dev->dev_private;
358         struct drm_agp_info info;
359         struct drm_agp_mode mode;
360         int ret;
361
362         nouveau_mem_reset_agp(dev);
363
364         ret = drm_agp_acquire(dev);
365         if (ret) {
366                 DRM_ERROR("Unable to acquire AGP: %d\n", ret);
367                 return ret;
368         }
369
370         ret = drm_agp_info(dev, &info);
371         if (ret) {
372                 DRM_ERROR("Unable to get AGP info: %d\n", ret);
373                 return ret;
374         }
375
376         /* see agp.h for the AGPSTAT_* modes available */
377         mode.mode = info.mode;
378         ret = drm_agp_enable(dev, mode);
379         if (ret) {
380                 DRM_ERROR("Unable to enable AGP: %d\n", ret);
381                 return ret;
382         }
383
384         if (!ttm) {
385                 struct drm_agp_buffer agp_req;
386                 struct drm_agp_binding bind_req;
387
388                 agp_req.size = info.aperture_size;
389                 agp_req.type = 0;
390                 ret = drm_agp_alloc(dev, &agp_req);
391                 if (ret) {
392                         DRM_ERROR("Unable to alloc AGP: %d\n", ret);
393                                 return ret;
394                 }
395
396                 bind_req.handle = agp_req.handle;
397                 bind_req.offset = 0;
398                 ret = drm_agp_bind(dev, &bind_req);
399                 if (ret) {
400                         DRM_ERROR("Unable to bind AGP: %d\n", ret);
401                         return ret;
402                 }
403         }
404
405         dev_priv->gart_info.type        = NOUVEAU_GART_AGP;
406         dev_priv->gart_info.aper_base   = info.aperture_base;
407         dev_priv->gart_info.aper_size   = info.aperture_size;
408         return 0;
409 }
410
411 #define HACK_OLD_MM
412 int
413 nouveau_mem_init_ttm(struct drm_device *dev)
414 {
415         struct drm_nouveau_private *dev_priv = dev->dev_private;
416         uint32_t vram_size, bar1_size;
417         int ret;
418
419         dev_priv->agp_heap = dev_priv->pci_heap = dev_priv->fb_heap = NULL;
420         dev_priv->fb_phys = drm_get_resource_start(dev,1);
421         dev_priv->gart_info.type = NOUVEAU_GART_NONE;
422
423         drm_bo_driver_init(dev);
424
425         /* non-mappable vram */
426         dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
427         dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
428         vram_size = dev_priv->fb_available_size >> PAGE_SHIFT;
429         bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT;
430         if (bar1_size < vram_size) {
431                 if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0,
432                                           bar1_size, vram_size - bar1_size, 1))) {
433                         DRM_ERROR("Failed PRIV0 mm init: %d\n", ret);
434                         return ret;
435                 }
436                 vram_size = bar1_size;
437         }
438
439         /* mappable vram */
440 #ifdef HACK_OLD_MM
441         vram_size /= 4;
442 #endif
443         if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size, 1))) {
444                 DRM_ERROR("Failed VRAM mm init: %d\n", ret);
445                 return ret;
446         }
447
448         /* GART */
449 #if !defined(__powerpc__) && !defined(__ia64__)
450         if (drm_device_is_agp(dev) && dev->agp) {
451                 if ((ret = nouveau_mem_init_agp(dev, 1)))
452                         DRM_ERROR("Error initialising AGP: %d\n", ret);
453         }
454 #endif
455
456         if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) {
457                 if ((ret = nouveau_sgdma_init(dev)))
458                         DRM_ERROR("Error initialising PCI SGDMA: %d\n", ret);
459         }
460
461         if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
462                                   dev_priv->gart_info.aper_size >>
463                                   PAGE_SHIFT, 1))) {
464                 DRM_ERROR("Failed TT mm init: %d\n", ret);
465                 return ret;
466         }
467
468 #ifdef HACK_OLD_MM
469         vram_size <<= PAGE_SHIFT;
470         DRM_INFO("Old MM using %dKiB VRAM\n", (vram_size * 3) >> 10);
471         if (nouveau_mem_init_heap(&dev_priv->fb_heap, vram_size, vram_size * 3))
472                 return -ENOMEM;
473 #endif
474
475         return 0;
476 }
477
478 int nouveau_mem_init(struct drm_device *dev)
479 {
480         struct drm_nouveau_private *dev_priv = dev->dev_private;
481         uint32_t fb_size;
482         int ret = 0;
483
484         dev_priv->agp_heap = dev_priv->pci_heap = dev_priv->fb_heap = NULL;
485         dev_priv->fb_phys = 0;
486         dev_priv->gart_info.type = NOUVEAU_GART_NONE;
487
488         /* setup a mtrr over the FB */
489         dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1),
490                                          nouveau_mem_fb_amount(dev),
491                                          DRM_MTRR_WC);
492
493         /* Init FB */
494         dev_priv->fb_phys=drm_get_resource_start(dev,1);
495         fb_size = nouveau_mem_fb_amount(dev);
496         /* On G80, limit VRAM to 512MiB temporarily due to limits in how
497          * we handle VRAM page tables.
498          */
499         if (dev_priv->card_type >= NV_50 && fb_size > (512 * 1024 * 1024))
500                 fb_size = (512 * 1024 * 1024);
501         /* On at least NV40, RAMIN is actually at the end of vram.
502          * We don't want to allocate this... */
503         if (dev_priv->card_type >= NV_40)
504                 fb_size -= dev_priv->ramin_rsvd_vram;
505         dev_priv->fb_available_size = fb_size;
506         DRM_DEBUG("Available VRAM: %dKiB\n", fb_size>>10);
507
508         if (fb_size>256*1024*1024) {
509                 /* On cards with > 256Mb, you can't map everything.
510                  * So we create a second FB heap for that type of memory */
511                 if (nouveau_mem_init_heap(&dev_priv->fb_heap,
512                                           0, 256*1024*1024))
513                         return -ENOMEM;
514                 if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap,
515                                           256*1024*1024, fb_size-256*1024*1024))
516                         return -ENOMEM;
517         } else {
518                 if (nouveau_mem_init_heap(&dev_priv->fb_heap, 0, fb_size))
519                         return -ENOMEM;
520                 dev_priv->fb_nomap_heap=NULL;
521         }
522
523 #if !defined(__powerpc__) && !defined(__ia64__)
524         /* Init AGP / NV50 PCIEGART */
525         if (drm_device_is_agp(dev) && dev->agp) {
526                 if ((ret = nouveau_mem_init_agp(dev, 0)))
527                         DRM_ERROR("Error initialising AGP: %d\n", ret);
528         }
529 #endif
530
531         /*Note: this is *not* just NV50 code, but only used on NV50 for now */
532         if (dev_priv->gart_info.type == NOUVEAU_GART_NONE &&
533             dev_priv->card_type >= NV_50) {
534                 ret = nouveau_sgdma_init(dev);
535                 if (!ret) {
536                         ret = nouveau_sgdma_nottm_hack_init(dev);
537                         if (ret)
538                                 nouveau_sgdma_takedown(dev);
539                 }
540
541                 if (ret)
542                         DRM_ERROR("Error initialising SG DMA: %d\n", ret);
543         }
544
545         if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) {
546                 if (nouveau_mem_init_heap(&dev_priv->agp_heap,
547                                           0, dev_priv->gart_info.aper_size)) {
548                         if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) {
549                                 nouveau_sgdma_nottm_hack_takedown(dev);
550                                 nouveau_sgdma_takedown(dev);
551                         }
552                 }
553         }
554
555         /* NV04-NV40 PCIEGART */
556         if (!dev_priv->agp_heap && dev_priv->card_type < NV_50) {
557                 struct drm_scatter_gather sgreq;
558
559                 DRM_DEBUG("Allocating sg memory for PCI DMA\n");
560                 sgreq.size = 16 << 20; //16MB of PCI scatter-gather zone
561
562                 if (drm_sg_alloc(dev, &sgreq)) {
563                         DRM_ERROR("Unable to allocate %ldMB of scatter-gather"
564                                   " pages for PCI DMA!",sgreq.size>>20);
565                 } else {
566                         if (nouveau_mem_init_heap(&dev_priv->pci_heap, 0,
567                                                   dev->sg->pages * PAGE_SIZE)) {
568                                 DRM_ERROR("Unable to initialize pci_heap!");
569                         }
570                 }
571         }
572
573         /* G8x: Allocate shared page table to map real VRAM pages into */
574         if (dev_priv->card_type >= NV_50) {
575                 unsigned size = ((512 * 1024 * 1024) / 65536) * 8;
576
577                 ret = nouveau_gpuobj_new(dev, NULL, size, 0,
578                                          NVOBJ_FLAG_ZERO_ALLOC |
579                                          NVOBJ_FLAG_ALLOW_NO_REFS,
580                                          &dev_priv->vm_vram_pt);
581                 if (ret) {
582                         DRM_ERROR("Error creating VRAM page table: %d\n", ret);
583                         return ret;
584                 }
585         }
586
587
588         return 0;
589 }
590
591 struct mem_block *
592 nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size,
593                   int flags, struct drm_file *file_priv)
594 {
595         struct drm_nouveau_private *dev_priv = dev->dev_private;
596         struct mem_block *block;
597         int type, tail = !(flags & NOUVEAU_MEM_USER);
598
599         /*
600          * Make things easier on ourselves: all allocations are page-aligned.
601          * We need that to map allocated regions into the user space
602          */
603         if (alignment < PAGE_SHIFT)
604                 alignment = PAGE_SHIFT;
605
606         /* Align allocation sizes to 64KiB blocks on G8x.  We use a 64KiB
607          * page size in the GPU VM.
608          */
609         if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) {
610                 size = (size + 65535) & ~65535;
611                 if (alignment < 16)
612                         alignment = 16;
613         }
614
615         /*
616          * Warn about 0 sized allocations, but let it go through. It'll return 1 page
617          */
618         if (size == 0)
619                 DRM_INFO("warning : 0 byte allocation\n");
620
621         /*
622          * Keep alloc size a multiple of the page size to keep drm_addmap() happy
623          */
624         if (size & (~PAGE_MASK))
625                 size = ((size/PAGE_SIZE) + 1) * PAGE_SIZE;
626
627
628 #define NOUVEAU_MEM_ALLOC_AGP {\
629                 type=NOUVEAU_MEM_AGP;\
630                 block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\
631                                                 alignment, file_priv, tail); \
632                 if (block) goto alloc_ok;\
633                 }
634
635 #define NOUVEAU_MEM_ALLOC_PCI {\
636                 type = NOUVEAU_MEM_PCI;\
637                 block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, \
638                                                 alignment, file_priv, tail); \
639                 if ( block ) goto alloc_ok;\
640                 }
641
642 #define NOUVEAU_MEM_ALLOC_FB {\
643                 type=NOUVEAU_MEM_FB;\
644                 if (!(flags&NOUVEAU_MEM_MAPPED)) {\
645                         block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\
646                                                         size, alignment, \
647                                                         file_priv, tail); \
648                         if (block) goto alloc_ok;\
649                 }\
650                 block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\
651                                                 alignment, file_priv, tail);\
652                 if (block) goto alloc_ok;\
653                 }
654
655
656         if (flags&NOUVEAU_MEM_FB) NOUVEAU_MEM_ALLOC_FB
657         if (flags&NOUVEAU_MEM_AGP) NOUVEAU_MEM_ALLOC_AGP
658         if (flags&NOUVEAU_MEM_PCI) NOUVEAU_MEM_ALLOC_PCI
659         if (flags&NOUVEAU_MEM_FB_ACCEPTABLE) NOUVEAU_MEM_ALLOC_FB
660         if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) NOUVEAU_MEM_ALLOC_AGP
661         if (flags&NOUVEAU_MEM_PCI_ACCEPTABLE) NOUVEAU_MEM_ALLOC_PCI
662
663
664         return NULL;
665
666 alloc_ok:
667         block->flags=type;
668
669         /* On G8x, map memory into VM */
670         if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50 &&
671             !(flags & NOUVEAU_MEM_NOVM)) {
672                 struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
673                 unsigned offset = block->start;
674                 unsigned count = block->size / 65536;
675                 unsigned tile = 0;
676
677                 if (!pt) {
678                         DRM_ERROR("vm alloc without vm pt\n");
679                         nouveau_mem_free_block(block);
680                         return NULL;
681                 }
682
683                 /* The tiling stuff is *not* what NVIDIA does - but both the
684                  * 2D and 3D engines seem happy with this simpler method.
685                  * Should look into why NVIDIA do what they do at some point.
686                  */
687                 if (flags & NOUVEAU_MEM_TILE) {
688                         if (flags & NOUVEAU_MEM_TILE_ZETA)
689                                 tile = 0x00002800;
690                         else
691                                 tile = 0x00007000;
692                 }
693
694                 while (count--) {
695                         unsigned pte = offset / 65536;
696
697                         INSTANCE_WR(pt, (pte * 2) + 0, offset | 1);
698                         INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile);
699                         offset += 65536;
700                 }
701         } else {
702                 block->flags |= NOUVEAU_MEM_NOVM;
703         }       
704
705         if (flags&NOUVEAU_MEM_MAPPED)
706         {
707                 struct drm_map_list *entry;
708                 int ret = 0;
709                 block->flags|=NOUVEAU_MEM_MAPPED;
710
711                 if (type == NOUVEAU_MEM_AGP) {
712                         if (dev_priv->gart_info.type != NOUVEAU_GART_SGDMA)
713                         ret = drm_addmap(dev, block->start, block->size,
714                                          _DRM_AGP, 0, &block->map);
715                         else
716                         ret = drm_addmap(dev, block->start, block->size,
717                                          _DRM_SCATTER_GATHER, 0, &block->map);
718                 }
719                 else if (type == NOUVEAU_MEM_FB)
720                         ret = drm_addmap(dev, block->start + dev_priv->fb_phys,
721                                          block->size, _DRM_FRAME_BUFFER,
722                                          0, &block->map);
723                 else if (type == NOUVEAU_MEM_PCI)
724                         ret = drm_addmap(dev, block->start, block->size,
725                                          _DRM_SCATTER_GATHER, 0, &block->map);
726
727                 if (ret) {
728                         nouveau_mem_free_block(block);
729                         return NULL;
730                 }
731
732                 entry = drm_find_matching_map(dev, block->map);
733                 if (!entry) {
734                         nouveau_mem_free_block(block);
735                         return NULL;
736                 }
737                 block->map_handle = entry->user_token;
738         }
739
740         DRM_DEBUG("allocated %lld bytes at 0x%llx type=0x%08x\n", block->size, block->start, block->flags);
741         return block;
742 }
743
744 void nouveau_mem_free(struct drm_device* dev, struct mem_block* block)
745 {
746         struct drm_nouveau_private *dev_priv = dev->dev_private;
747
748         DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags);
749
750         /* Check if the deallocations cause problems for our modesetting system. */
751         if (drm_core_check_feature(dev, DRIVER_MODESET)) {
752                 if (dev_priv->card_type >= NV_50) {
753                         struct nv50_crtc *crtc = NULL;
754                         struct nv50_display *display = nv50_get_display(dev);
755
756                         list_for_each_entry(crtc, &display->crtcs, item) {
757                                 if (crtc->fb->block == block) {
758                                         crtc->fb->block = NULL;
759
760                                         if (!crtc->blanked)
761                                                 crtc->blank(crtc, true);
762                                 }
763
764                                 if (crtc->cursor->block == block) {
765                                         crtc->cursor->block = NULL;
766
767                                         if (crtc->cursor->visible)
768                                                 crtc->cursor->hide(crtc);
769                                 }
770                         }
771                 }
772         }
773
774         if (block->flags&NOUVEAU_MEM_MAPPED)
775                 drm_rmmap(dev, block->map);
776
777         /* G8x: Remove pages from vm */
778         if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50 &&
779             !(block->flags & NOUVEAU_MEM_NOVM)) {
780                 struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
781                 unsigned offset = block->start;
782                 unsigned count = block->size / 65536;
783
784                 if (!pt) {
785                         DRM_ERROR("vm free without vm pt\n");
786                         goto out_free;
787                 }
788
789                 while (count--) {
790                         unsigned pte = offset / 65536;
791                         INSTANCE_WR(pt, (pte * 2) + 0, 0);
792                         INSTANCE_WR(pt, (pte * 2) + 1, 0);
793                         offset += 65536;
794                 }
795         }
796
797 out_free:
798         nouveau_mem_free_block(block);
799 }
800
801 /*
802  * Ioctls
803  */
804
805 int
806 nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data,
807                         struct drm_file *file_priv)
808 {
809         struct drm_nouveau_private *dev_priv = dev->dev_private;
810         struct drm_nouveau_mem_alloc *alloc = data;
811         struct mem_block *block;
812
813         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
814
815         if (alloc->flags & NOUVEAU_MEM_INTERNAL)
816                 return -EINVAL;
817
818         block = nouveau_mem_alloc(dev, alloc->alignment, alloc->size,
819                                   alloc->flags | NOUVEAU_MEM_USER, file_priv);
820         if (!block)
821                 return -ENOMEM;
822         alloc->map_handle=block->map_handle;
823         alloc->offset=block->start;
824         alloc->flags=block->flags;
825
826         if (dev_priv->card_type >= NV_50 && alloc->flags & NOUVEAU_MEM_FB)
827                 alloc->offset += 512*1024*1024;
828
829         return 0;
830 }
831
832 int
833 nouveau_ioctl_mem_free(struct drm_device *dev, void *data,
834                        struct drm_file *file_priv)
835 {
836         struct drm_nouveau_private *dev_priv = dev->dev_private;
837         struct drm_nouveau_mem_free *memfree = data;
838         struct mem_block *block;
839
840         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
841
842         if (dev_priv->card_type >= NV_50 && memfree->flags & NOUVEAU_MEM_FB)
843                 memfree->offset -= 512*1024*1024;
844
845         block=NULL;
846         if (memfree->flags & NOUVEAU_MEM_FB)
847                 block = find_block(dev_priv->fb_heap, memfree->offset);
848         else if (memfree->flags & NOUVEAU_MEM_AGP)
849                 block = find_block(dev_priv->agp_heap, memfree->offset);
850         else if (memfree->flags & NOUVEAU_MEM_PCI)
851                 block = find_block(dev_priv->pci_heap, memfree->offset);
852         if (!block)
853                 return -EFAULT;
854         if (block->file_priv != file_priv)
855                 return -EPERM;
856
857         nouveau_mem_free(dev, block);
858         return 0;
859 }
860
861 int
862 nouveau_ioctl_mem_tile(struct drm_device *dev, void *data,
863                        struct drm_file *file_priv)
864 {
865         struct drm_nouveau_private *dev_priv = dev->dev_private;
866         struct drm_nouveau_mem_tile *memtile = data;
867         struct mem_block *block = NULL;
868
869         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
870
871         if (dev_priv->card_type < NV_50)
872                 return -EINVAL;
873         
874         if (memtile->flags & NOUVEAU_MEM_FB) {
875                 memtile->offset -= 512*1024*1024;
876                 block = find_block(dev_priv->fb_heap, memtile->offset);
877         }
878
879         if (!block)
880                 return -EINVAL;
881
882         if (block->file_priv != file_priv)
883                 return -EPERM;
884
885         {
886                 struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
887                 unsigned offset = block->start + memtile->delta;
888                 unsigned count = memtile->size / 65536;
889                 unsigned tile = 0;
890
891                 if (memtile->flags & NOUVEAU_MEM_TILE) {
892                         if (memtile->flags & NOUVEAU_MEM_TILE_ZETA)
893                                 tile = 0x00002800;
894                         else
895                                 tile = 0x00007000;
896                 }
897
898                 while (count--) {
899                         unsigned pte = offset / 65536;
900
901                         INSTANCE_WR(pt, (pte * 2) + 0, offset | 1);
902                         INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile);
903                         offset += 65536;
904                 }
905         }
906
907         return 0;
908 }
909