No empty .Rs/.Re
[netbsd-mini2440.git] / sys / external / bsd / drm / dist / shared-core / nouveau_mem.c
blob627b917811169954031e7091d5611399af10edd0
1 /*
2 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
3 * Copyright 2005 Stephane Marchesin
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.
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:
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.
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.
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "drmP.h"
34 #include "drm.h"
35 #include "drm_sarea.h"
36 #include "nouveau_drv.h"
38 static struct mem_block *
39 split_block(struct mem_block *p, uint64_t start, uint64_t size,
40 struct drm_file *file_priv)
42 /* Maybe cut off the start of an existing block */
43 if (start > p->start) {
44 struct mem_block *newblock =
45 drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
46 if (!newblock)
47 goto out;
48 newblock->start = start;
49 newblock->size = p->size - (start - p->start);
50 newblock->file_priv = NULL;
51 newblock->next = p->next;
52 newblock->prev = p;
53 p->next->prev = newblock;
54 p->next = newblock;
55 p->size -= newblock->size;
56 p = newblock;
59 /* Maybe cut off the end of an existing block */
60 if (size < p->size) {
61 struct mem_block *newblock =
62 drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
63 if (!newblock)
64 goto out;
65 newblock->start = start + size;
66 newblock->size = p->size - size;
67 newblock->file_priv = NULL;
68 newblock->next = p->next;
69 newblock->prev = p;
70 p->next->prev = newblock;
71 p->next = newblock;
72 p->size = size;
75 out:
76 /* Our block is in the middle */
77 p->file_priv = file_priv;
78 return p;
81 struct mem_block *
82 nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size,
83 int align2, struct drm_file *file_priv, int tail)
85 struct mem_block *p;
86 uint64_t mask = (1 << align2) - 1;
88 if (!heap)
89 return NULL;
91 if (tail) {
92 list_for_each_prev(p, heap) {
93 uint64_t start = ((p->start + p->size) - size) & ~mask;
95 if (p->file_priv == 0 && start >= p->start &&
96 start + size <= p->start + p->size)
97 return split_block(p, start, size, file_priv);
99 } else {
100 list_for_each(p, heap) {
101 uint64_t start = (p->start + mask) & ~mask;
103 if (p->file_priv == 0 &&
104 start + size <= p->start + p->size)
105 return split_block(p, start, size, file_priv);
109 return NULL;
112 static struct mem_block *find_block(struct mem_block *heap, uint64_t start)
114 struct mem_block *p;
116 list_for_each(p, heap)
117 if (p->start == start)
118 return p;
120 return NULL;
123 void nouveau_mem_free_block(struct mem_block *p)
125 p->file_priv = NULL;
127 /* Assumes a single contiguous range. Needs a special file_priv in
128 * 'heap' to stop it being subsumed.
130 if (p->next->file_priv == 0) {
131 struct mem_block *q = p->next;
132 p->size += q->size;
133 p->next = q->next;
134 p->next->prev = p;
135 drm_free(q, sizeof(*q), DRM_MEM_BUFS);
138 if (p->prev->file_priv == 0) {
139 struct mem_block *q = p->prev;
140 q->size += p->size;
141 q->next = p->next;
142 q->next->prev = q;
143 drm_free(p, sizeof(*q), DRM_MEM_BUFS);
147 /* Initialize. How to check for an uninitialized heap?
149 int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start,
150 uint64_t size)
152 struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS);
154 if (!blocks)
155 return -ENOMEM;
157 *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS);
158 if (!*heap) {
159 drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS);
160 return -ENOMEM;
163 blocks->start = start;
164 blocks->size = size;
165 blocks->file_priv = NULL;
166 blocks->next = blocks->prev = *heap;
168 memset(*heap, 0, sizeof(**heap));
169 (*heap)->file_priv = (struct drm_file *) - 1;
170 (*heap)->next = (*heap)->prev = blocks;
171 return 0;
175 * Free all blocks associated with the releasing file_priv
177 void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap)
179 struct mem_block *p;
181 if (!heap || !heap->next)
182 return;
184 list_for_each(p, heap) {
185 if (p->file_priv == file_priv)
186 p->file_priv = NULL;
189 /* Assumes a single contiguous range. Needs a special file_priv in
190 * 'heap' to stop it being subsumed.
192 list_for_each(p, heap) {
193 while ((p->file_priv == 0) && (p->next->file_priv == 0) &&
194 (p->next!=heap)) {
195 struct mem_block *q = p->next;
196 p->size += q->size;
197 p->next = q->next;
198 p->next->prev = p;
199 drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
205 * Cleanup everything
207 void nouveau_mem_takedown(struct mem_block **heap)
209 struct mem_block *p;
211 if (!*heap)
212 return;
214 for (p = (*heap)->next; p != *heap;) {
215 struct mem_block *q = p;
216 p = p->next;
217 drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
220 drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER);
221 *heap = NULL;
224 void nouveau_mem_close(struct drm_device *dev)
226 struct drm_nouveau_private *dev_priv = dev->dev_private;
228 nouveau_mem_takedown(&dev_priv->agp_heap);
229 nouveau_mem_takedown(&dev_priv->fb_heap);
230 if (dev_priv->pci_heap)
231 nouveau_mem_takedown(&dev_priv->pci_heap);
234 /*XXX BSD needs compat functions for pci access
235 * #define DRM_PCI_DEV struct device
236 * #define drm_pci_get_bsf pci_get_bsf
237 * and a small inline to do *val = pci_read_config(pdev->device, where, 4);
238 * might work
240 static int nforce_pci_fn_read_config_dword(int devfn, int where, uint32_t *val)
242 #ifdef __linux__
243 DRM_PCI_DEV *pdev;
245 if (!(pdev = drm_pci_get_bsf(0, 0, devfn))) {
246 DRM_ERROR("nForce PCI device function 0x%02x not found\n",
247 devfn);
248 return -ENODEV;
251 return drm_pci_read_config_dword(pdev, where, val);
252 #else
253 DRM_ERROR("BSD compat for checking IGP memory amount needed\n");
254 return 0;
255 #endif
258 static void nouveau_mem_check_nforce_dimms(struct drm_device *dev)
260 uint32_t mem_ctrlr_pciid;
262 nforce_pci_fn_read_config_dword(3, 0x00, &mem_ctrlr_pciid);
263 mem_ctrlr_pciid >>= 16;
265 if (mem_ctrlr_pciid == 0x01a9 || mem_ctrlr_pciid == 0x01ab ||
266 mem_ctrlr_pciid == 0x01ed) {
267 uint32_t dimm[3];
268 int i;
270 for (i = 0; i < 3; i++) {
271 nforce_pci_fn_read_config_dword(2, 0x40 + i * 4, &dimm[i]);
272 dimm[i] = (dimm[i] >> 8) & 0x4f;
275 if (dimm[0] + dimm[1] != dimm[2])
276 DRM_INFO("Your nForce DIMMs are not arranged in "
277 "optimal banks!\n");
281 static uint32_t
282 nouveau_mem_fb_amount_igp(struct drm_device *dev)
284 struct drm_nouveau_private *dev_priv = dev->dev_private;
285 uint32_t mem = 0;
287 if (dev_priv->flags & NV_NFORCE) {
288 nforce_pci_fn_read_config_dword(1, 0x7C, &mem);
289 return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
291 if (dev_priv->flags & NV_NFORCE2) {
292 nforce_pci_fn_read_config_dword(1, 0x84, &mem);
293 return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
296 DRM_ERROR("impossible!\n");
298 return 0;
301 /* returns the amount of FB ram in bytes */
302 uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
304 struct drm_nouveau_private *dev_priv=dev->dev_private;
305 switch(dev_priv->card_type)
307 case NV_04:
308 case NV_05:
309 if (NV_READ(NV03_BOOT_0) & 0x00000100) {
310 return (((NV_READ(NV03_BOOT_0) >> 12) & 0xf)*2+2)*1024*1024;
311 } else
312 switch(NV_READ(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT)
314 case NV04_BOOT_0_RAM_AMOUNT_32MB:
315 return 32*1024*1024;
316 case NV04_BOOT_0_RAM_AMOUNT_16MB:
317 return 16*1024*1024;
318 case NV04_BOOT_0_RAM_AMOUNT_8MB:
319 return 8*1024*1024;
320 case NV04_BOOT_0_RAM_AMOUNT_4MB:
321 return 4*1024*1024;
323 break;
324 case NV_10:
325 case NV_11:
326 case NV_17:
327 case NV_20:
328 case NV_30:
329 case NV_40:
330 case NV_44:
331 case NV_50:
332 default:
333 if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
334 return nouveau_mem_fb_amount_igp(dev);
335 } else {
336 uint64_t mem;
338 mem = (NV_READ(NV10_PFB_CSTATUS) &
339 NV10_PFB_CSTATUS_RAM_AMOUNT_MB_MASK) >>
340 NV10_PFB_CSTATUS_RAM_AMOUNT_MB_SHIFT;
341 return mem*1024*1024;
343 break;
346 DRM_ERROR("Unable to detect video ram size. Please report your setup to " DRIVER_EMAIL "\n");
347 return 0;
350 static void nouveau_mem_reset_agp(struct drm_device *dev)
352 struct drm_nouveau_private *dev_priv = dev->dev_private;
353 uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable;
355 saved_pci_nv_1 = NV_READ(NV04_PBUS_PCI_NV_1);
356 saved_pci_nv_19 = NV_READ(NV04_PBUS_PCI_NV_19);
358 /* clear busmaster bit */
359 NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4);
360 /* clear SBA and AGP bits */
361 NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff);
363 /* power cycle pgraph, if enabled */
364 pmc_enable = NV_READ(NV03_PMC_ENABLE);
365 if (pmc_enable & NV_PMC_ENABLE_PGRAPH) {
366 NV_WRITE(NV03_PMC_ENABLE, pmc_enable & ~NV_PMC_ENABLE_PGRAPH);
367 NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
368 NV_PMC_ENABLE_PGRAPH);
371 /* and restore (gives effect of resetting AGP) */
372 NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
373 NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
376 static int
377 nouveau_mem_init_agp(struct drm_device *dev, int ttm)
379 struct drm_nouveau_private *dev_priv = dev->dev_private;
380 struct drm_agp_info info;
381 struct drm_agp_mode mode;
382 int ret;
384 nouveau_mem_reset_agp(dev);
386 ret = drm_agp_acquire(dev);
387 if (ret) {
388 DRM_ERROR("Unable to acquire AGP: %d\n", ret);
389 return ret;
392 ret = drm_agp_info(dev, &info);
393 if (ret) {
394 DRM_ERROR("Unable to get AGP info: %d\n", ret);
395 return ret;
398 /* see agp.h for the AGPSTAT_* modes available */
399 mode.mode = info.mode;
400 ret = drm_agp_enable(dev, mode);
401 if (ret) {
402 DRM_ERROR("Unable to enable AGP: %d\n", ret);
403 return ret;
406 if (!ttm) {
407 struct drm_agp_buffer agp_req;
408 struct drm_agp_binding bind_req;
410 agp_req.size = info.aperture_size;
411 agp_req.type = 0;
412 ret = drm_agp_alloc(dev, &agp_req);
413 if (ret) {
414 DRM_ERROR("Unable to alloc AGP: %d\n", ret);
415 return ret;
418 bind_req.handle = agp_req.handle;
419 bind_req.offset = 0;
420 ret = drm_agp_bind(dev, &bind_req);
421 if (ret) {
422 DRM_ERROR("Unable to bind AGP: %d\n", ret);
423 return ret;
427 dev_priv->gart_info.type = NOUVEAU_GART_AGP;
428 dev_priv->gart_info.aper_base = info.aperture_base;
429 dev_priv->gart_info.aper_size = info.aperture_size;
430 return 0;
433 #define HACK_OLD_MM
435 nouveau_mem_init_ttm(struct drm_device *dev)
437 struct drm_nouveau_private *dev_priv = dev->dev_private;
438 uint32_t vram_size, bar1_size;
439 int ret;
441 dev_priv->agp_heap = dev_priv->pci_heap = dev_priv->fb_heap = NULL;
442 dev_priv->fb_phys = drm_get_resource_start(dev,1);
443 dev_priv->gart_info.type = NOUVEAU_GART_NONE;
445 drm_bo_driver_init(dev);
447 /* non-mappable vram */
448 dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
449 dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
450 vram_size = dev_priv->fb_available_size >> PAGE_SHIFT;
451 bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT;
452 if (bar1_size < vram_size) {
453 if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0,
454 bar1_size, vram_size - bar1_size, 1))) {
455 DRM_ERROR("Failed PRIV0 mm init: %d\n", ret);
456 return ret;
458 vram_size = bar1_size;
461 /* mappable vram */
462 #ifdef HACK_OLD_MM
463 vram_size /= 4;
464 #endif
465 if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size, 1))) {
466 DRM_ERROR("Failed VRAM mm init: %d\n", ret);
467 return ret;
470 /* GART */
471 #if !defined(__powerpc__) && !defined(__ia64__)
472 if (drm_device_is_agp(dev) && dev->agp) {
473 if ((ret = nouveau_mem_init_agp(dev, 1)))
474 DRM_ERROR("Error initialising AGP: %d\n", ret);
476 #endif
478 if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) {
479 if ((ret = nouveau_sgdma_init(dev)))
480 DRM_ERROR("Error initialising PCI SGDMA: %d\n", ret);
483 if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
484 dev_priv->gart_info.aper_size >>
485 PAGE_SHIFT, 1))) {
486 DRM_ERROR("Failed TT mm init: %d\n", ret);
487 return ret;
490 #ifdef HACK_OLD_MM
491 vram_size <<= PAGE_SHIFT;
492 DRM_INFO("Old MM using %dKiB VRAM\n", (vram_size * 3) >> 10);
493 if (nouveau_mem_init_heap(&dev_priv->fb_heap, vram_size, vram_size * 3))
494 return -ENOMEM;
495 #endif
497 return 0;
500 int nouveau_mem_init(struct drm_device *dev)
502 struct drm_nouveau_private *dev_priv = dev->dev_private;
503 uint32_t fb_size;
504 int ret = 0;
506 dev_priv->agp_heap = dev_priv->pci_heap = dev_priv->fb_heap = NULL;
507 dev_priv->fb_phys = 0;
508 dev_priv->gart_info.type = NOUVEAU_GART_NONE;
510 if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2))
511 nouveau_mem_check_nforce_dimms(dev);
513 /* setup a mtrr over the FB */
514 dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1),
515 nouveau_mem_fb_amount(dev),
516 DRM_MTRR_WC);
518 /* Init FB */
519 dev_priv->fb_phys=drm_get_resource_start(dev,1);
520 fb_size = nouveau_mem_fb_amount(dev);
521 /* On G80, limit VRAM to 512MiB temporarily due to limits in how
522 * we handle VRAM page tables.
524 if (dev_priv->card_type >= NV_50 && fb_size > (512 * 1024 * 1024))
525 fb_size = (512 * 1024 * 1024);
526 fb_size -= dev_priv->ramin_rsvd_vram;
527 dev_priv->fb_available_size = fb_size;
528 DRM_DEBUG("Available VRAM: %dKiB\n", fb_size>>10);
530 if (fb_size>256*1024*1024) {
531 /* On cards with > 256Mb, you can't map everything.
532 * So we create a second FB heap for that type of memory */
533 if (nouveau_mem_init_heap(&dev_priv->fb_heap,
534 0, 256*1024*1024))
535 return -ENOMEM;
536 if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap,
537 256*1024*1024, fb_size-256*1024*1024))
538 return -ENOMEM;
539 } else {
540 if (nouveau_mem_init_heap(&dev_priv->fb_heap, 0, fb_size))
541 return -ENOMEM;
542 dev_priv->fb_nomap_heap=NULL;
545 #if !defined(__powerpc__) && !defined(__ia64__)
546 /* Init AGP / NV50 PCIEGART */
547 if (drm_device_is_agp(dev) && dev->agp) {
548 if ((ret = nouveau_mem_init_agp(dev, 0)))
549 DRM_ERROR("Error initialising AGP: %d\n", ret);
551 #endif
553 /*Note: this is *not* just NV50 code, but only used on NV50 for now */
554 if (dev_priv->gart_info.type == NOUVEAU_GART_NONE &&
555 dev_priv->card_type >= NV_50) {
556 ret = nouveau_sgdma_init(dev);
557 if (!ret) {
558 ret = nouveau_sgdma_nottm_hack_init(dev);
559 if (ret)
560 nouveau_sgdma_takedown(dev);
563 if (ret)
564 DRM_ERROR("Error initialising SG DMA: %d\n", ret);
567 if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) {
568 if (nouveau_mem_init_heap(&dev_priv->agp_heap,
569 0, dev_priv->gart_info.aper_size)) {
570 if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) {
571 nouveau_sgdma_nottm_hack_takedown(dev);
572 nouveau_sgdma_takedown(dev);
577 /* NV04-NV40 PCIEGART */
578 if (!dev_priv->agp_heap && dev_priv->card_type < NV_50) {
579 struct drm_scatter_gather sgreq;
581 DRM_DEBUG("Allocating sg memory for PCI DMA\n");
582 sgreq.size = 16 << 20; //16MB of PCI scatter-gather zone
584 if (drm_sg_alloc(dev, &sgreq)) {
585 DRM_ERROR("Unable to allocate %ldMB of scatter-gather"
586 " pages for PCI DMA!",sgreq.size>>20);
587 } else {
588 if (nouveau_mem_init_heap(&dev_priv->pci_heap, 0,
589 dev->sg->pages * PAGE_SIZE)) {
590 DRM_ERROR("Unable to initialize pci_heap!");
595 /* G8x: Allocate shared page table to map real VRAM pages into */
596 if (dev_priv->card_type >= NV_50) {
597 unsigned size = ((512 * 1024 * 1024) / 65536) * 8;
599 ret = nouveau_gpuobj_new(dev, NULL, size, 0,
600 NVOBJ_FLAG_ZERO_ALLOC |
601 NVOBJ_FLAG_ALLOW_NO_REFS,
602 &dev_priv->vm_vram_pt);
603 if (ret) {
604 DRM_ERROR("Error creating VRAM page table: %d\n", ret);
605 return ret;
610 return 0;
613 struct mem_block *
614 nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size,
615 int flags, struct drm_file *file_priv)
617 struct drm_nouveau_private *dev_priv = dev->dev_private;
618 struct mem_block *block;
619 int type, tail = !(flags & NOUVEAU_MEM_USER);
622 * Make things easier on ourselves: all allocations are page-aligned.
623 * We need that to map allocated regions into the user space
625 if (alignment < PAGE_SIZE)
626 alignment = PAGE_SIZE;
628 /* Align allocation sizes to 64KiB blocks on G8x. We use a 64KiB
629 * page size in the GPU VM.
631 if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) {
632 size = (size + 65535) & ~65535;
633 if (alignment < 65536)
634 alignment = 65536;
637 /* Further down wants alignment in pages, not bytes */
638 alignment >>= PAGE_SHIFT;
641 * Warn about 0 sized allocations, but let it go through. It'll return 1 page
643 if (size == 0)
644 DRM_INFO("warning : 0 byte allocation\n");
647 * Keep alloc size a multiple of the page size to keep drm_addmap() happy
649 if (size & (~PAGE_MASK))
650 size = ((size/PAGE_SIZE) + 1) * PAGE_SIZE;
653 #define NOUVEAU_MEM_ALLOC_AGP {\
654 type=NOUVEAU_MEM_AGP;\
655 block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\
656 alignment, file_priv, tail); \
657 if (block) goto alloc_ok;\
660 #define NOUVEAU_MEM_ALLOC_PCI {\
661 type = NOUVEAU_MEM_PCI;\
662 block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, \
663 alignment, file_priv, tail); \
664 if ( block ) goto alloc_ok;\
667 #define NOUVEAU_MEM_ALLOC_FB {\
668 type=NOUVEAU_MEM_FB;\
669 if (!(flags&NOUVEAU_MEM_MAPPED)) {\
670 block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\
671 size, alignment, \
672 file_priv, tail); \
673 if (block) goto alloc_ok;\
675 block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\
676 alignment, file_priv, tail);\
677 if (block) goto alloc_ok;\
681 if (flags&NOUVEAU_MEM_FB) NOUVEAU_MEM_ALLOC_FB
682 if (flags&NOUVEAU_MEM_AGP) NOUVEAU_MEM_ALLOC_AGP
683 if (flags&NOUVEAU_MEM_PCI) NOUVEAU_MEM_ALLOC_PCI
684 if (flags&NOUVEAU_MEM_FB_ACCEPTABLE) NOUVEAU_MEM_ALLOC_FB
685 if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) NOUVEAU_MEM_ALLOC_AGP
686 if (flags&NOUVEAU_MEM_PCI_ACCEPTABLE) NOUVEAU_MEM_ALLOC_PCI
689 return NULL;
691 alloc_ok:
692 block->flags=type;
694 /* On G8x, map memory into VM */
695 if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50 &&
696 !(flags & NOUVEAU_MEM_NOVM)) {
697 struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
698 unsigned offset = block->start;
699 unsigned count = block->size / 65536;
700 unsigned tile = 0;
702 if (!pt) {
703 DRM_ERROR("vm alloc without vm pt\n");
704 nouveau_mem_free_block(block);
705 return NULL;
708 /* The tiling stuff is *not* what NVIDIA does - but both the
709 * 2D and 3D engines seem happy with this simpler method.
710 * Should look into why NVIDIA do what they do at some point.
712 if (flags & NOUVEAU_MEM_TILE) {
713 if (flags & NOUVEAU_MEM_TILE_ZETA)
714 tile = 0x00002800;
715 else
716 tile = 0x00007000;
719 while (count--) {
720 unsigned pte = offset / 65536;
722 INSTANCE_WR(pt, (pte * 2) + 0, offset | 1);
723 INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile);
724 offset += 65536;
726 } else {
727 block->flags |= NOUVEAU_MEM_NOVM;
730 if (flags&NOUVEAU_MEM_MAPPED)
732 struct drm_map_list *entry;
733 int ret = 0;
734 block->flags|=NOUVEAU_MEM_MAPPED;
736 if (type == NOUVEAU_MEM_AGP) {
737 if (dev_priv->gart_info.type != NOUVEAU_GART_SGDMA)
738 ret = drm_addmap(dev, block->start, block->size,
739 _DRM_AGP, 0, &block->map);
740 else
741 ret = drm_addmap(dev, block->start, block->size,
742 _DRM_SCATTER_GATHER, 0, &block->map);
744 else if (type == NOUVEAU_MEM_FB)
745 ret = drm_addmap(dev, block->start + dev_priv->fb_phys,
746 block->size, _DRM_FRAME_BUFFER,
747 0, &block->map);
748 else if (type == NOUVEAU_MEM_PCI)
749 ret = drm_addmap(dev, block->start, block->size,
750 _DRM_SCATTER_GATHER, 0, &block->map);
752 if (ret) {
753 nouveau_mem_free_block(block);
754 return NULL;
757 entry = drm_find_matching_map(dev, block->map);
758 if (!entry) {
759 nouveau_mem_free_block(block);
760 return NULL;
762 block->map_handle = entry->user_token;
765 DRM_DEBUG("allocated %lld bytes at 0x%llx type=0x%08x\n", block->size, block->start, block->flags);
766 return block;
769 void nouveau_mem_free(struct drm_device* dev, struct mem_block* block)
771 struct drm_nouveau_private *dev_priv = dev->dev_private;
773 DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags);
775 if (block->flags&NOUVEAU_MEM_MAPPED)
776 drm_rmmap(dev, block->map);
778 /* G8x: Remove pages from vm */
779 if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50 &&
780 !(block->flags & NOUVEAU_MEM_NOVM)) {
781 struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
782 unsigned offset = block->start;
783 unsigned count = block->size / 65536;
785 if (!pt) {
786 DRM_ERROR("vm free without vm pt\n");
787 goto out_free;
790 while (count--) {
791 unsigned pte = offset / 65536;
792 INSTANCE_WR(pt, (pte * 2) + 0, 0);
793 INSTANCE_WR(pt, (pte * 2) + 1, 0);
794 offset += 65536;
798 out_free:
799 nouveau_mem_free_block(block);
803 * Ioctls
807 nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data,
808 struct drm_file *file_priv)
810 struct drm_nouveau_private *dev_priv = dev->dev_private;
811 struct drm_nouveau_mem_alloc *alloc = data;
812 struct mem_block *block;
814 NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
816 if (alloc->flags & NOUVEAU_MEM_INTERNAL)
817 return -EINVAL;
819 block = nouveau_mem_alloc(dev, alloc->alignment, alloc->size,
820 alloc->flags | NOUVEAU_MEM_USER, file_priv);
821 if (!block)
822 return -ENOMEM;
823 alloc->map_handle=block->map_handle;
824 alloc->offset=block->start;
825 alloc->flags=block->flags;
827 if (dev_priv->card_type >= NV_50 && alloc->flags & NOUVEAU_MEM_FB)
828 alloc->offset += 512*1024*1024;
830 return 0;
834 nouveau_ioctl_mem_free(struct drm_device *dev, void *data,
835 struct drm_file *file_priv)
837 struct drm_nouveau_private *dev_priv = dev->dev_private;
838 struct drm_nouveau_mem_free *memfree = data;
839 struct mem_block *block;
841 NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
843 if (dev_priv->card_type >= NV_50 && memfree->flags & NOUVEAU_MEM_FB)
844 memfree->offset -= 512*1024*1024;
846 block=NULL;
847 if (dev_priv->fb_heap && memfree->flags & NOUVEAU_MEM_FB)
848 block = find_block(dev_priv->fb_heap, memfree->offset);
849 else if (dev_priv->agp_heap && memfree->flags & NOUVEAU_MEM_AGP)
850 block = find_block(dev_priv->agp_heap, memfree->offset);
851 else if (dev_priv->pci_heap && memfree->flags & NOUVEAU_MEM_PCI)
852 block = find_block(dev_priv->pci_heap, memfree->offset);
853 if (!block)
854 return -EFAULT;
855 if (block->file_priv != file_priv)
856 return -EPERM;
858 nouveau_mem_free(dev, block);
859 return 0;
863 nouveau_ioctl_mem_tile(struct drm_device *dev, void *data,
864 struct drm_file *file_priv)
866 struct drm_nouveau_private *dev_priv = dev->dev_private;
867 struct drm_nouveau_mem_tile *memtile = data;
868 struct mem_block *block = NULL;
870 NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
872 if (dev_priv->card_type < NV_50)
873 return -EINVAL;
875 if (memtile->flags & NOUVEAU_MEM_FB) {
876 memtile->offset -= 512*1024*1024;
877 block = find_block(dev_priv->fb_heap, memtile->offset);
880 if (!block)
881 return -EINVAL;
883 if (block->file_priv != file_priv)
884 return -EPERM;
887 struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
888 unsigned offset = block->start + memtile->delta;
889 unsigned count = memtile->size / 65536;
890 unsigned tile = 0;
892 if (memtile->flags & NOUVEAU_MEM_TILE) {
893 if (memtile->flags & NOUVEAU_MEM_TILE_ZETA)
894 tile = 0x00002800;
895 else
896 tile = 0x00007000;
899 while (count--) {
900 unsigned pte = offset / 65536;
902 INSTANCE_WR(pt, (pte * 2) + 0, offset | 1);
903 INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile);
904 offset += 65536;
908 return 0;