aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_mem.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c124
1 files changed, 76 insertions, 48 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 2dc09dbd817d..775a7017af64 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -347,6 +347,20 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
347 return -EBUSY; 347 return -EBUSY;
348 } 348 }
349 349
350 nv_wr32(dev, 0x100c80, 0x00040001);
351 if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
352 NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
353 NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
354 return -EBUSY;
355 }
356
357 nv_wr32(dev, 0x100c80, 0x00060001);
358 if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
359 NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
360 NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
361 return -EBUSY;
362 }
363
350 return 0; 364 return 0;
351} 365}
352 366
@@ -387,6 +401,20 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
387 if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { 401 if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
388 NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); 402 NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
389 NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); 403 NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
404 return;
405 }
406
407 nv_wr32(dev, 0x100c80, 0x00040001);
408 if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
409 NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
410 NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
411 return;
412 }
413
414 nv_wr32(dev, 0x100c80, 0x00060001);
415 if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
416 NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
417 NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
390 } 418 }
391} 419}
392 420
@@ -449,9 +477,30 @@ void nouveau_mem_close(struct drm_device *dev)
449 } 477 }
450} 478}
451 479
452/*XXX won't work on BSD because of pci_read_config_dword */
453static uint32_t 480static uint32_t
454nouveau_mem_fb_amount_igp(struct drm_device *dev) 481nouveau_mem_detect_nv04(struct drm_device *dev)
482{
483 uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0);
484
485 if (boot0 & 0x00000100)
486 return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
487
488 switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
489 case NV04_BOOT_0_RAM_AMOUNT_32MB:
490 return 32 * 1024 * 1024;
491 case NV04_BOOT_0_RAM_AMOUNT_16MB:
492 return 16 * 1024 * 1024;
493 case NV04_BOOT_0_RAM_AMOUNT_8MB:
494 return 8 * 1024 * 1024;
495 case NV04_BOOT_0_RAM_AMOUNT_4MB:
496 return 4 * 1024 * 1024;
497 }
498
499 return 0;
500}
501
502static uint32_t
503nouveau_mem_detect_nforce(struct drm_device *dev)
455{ 504{
456 struct drm_nouveau_private *dev_priv = dev->dev_private; 505 struct drm_nouveau_private *dev_priv = dev->dev_private;
457 struct pci_dev *bridge; 506 struct pci_dev *bridge;
@@ -463,11 +512,11 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)
463 return 0; 512 return 0;
464 } 513 }
465 514
466 if (dev_priv->flags&NV_NFORCE) { 515 if (dev_priv->flags & NV_NFORCE) {
467 pci_read_config_dword(bridge, 0x7C, &mem); 516 pci_read_config_dword(bridge, 0x7C, &mem);
468 return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; 517 return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
469 } else 518 } else
470 if (dev_priv->flags&NV_NFORCE2) { 519 if (dev_priv->flags & NV_NFORCE2) {
471 pci_read_config_dword(bridge, 0x84, &mem); 520 pci_read_config_dword(bridge, 0x84, &mem);
472 return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; 521 return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
473 } 522 }
@@ -477,50 +526,32 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)
477} 526}
478 527
479/* returns the amount of FB ram in bytes */ 528/* returns the amount of FB ram in bytes */
480uint64_t nouveau_mem_fb_amount(struct drm_device *dev) 529int
530nouveau_mem_detect(struct drm_device *dev)
481{ 531{
482 struct drm_nouveau_private *dev_priv = dev->dev_private; 532 struct drm_nouveau_private *dev_priv = dev->dev_private;
483 uint32_t boot0; 533
484 534 if (dev_priv->card_type == NV_04) {
485 switch (dev_priv->card_type) { 535 dev_priv->vram_size = nouveau_mem_detect_nv04(dev);
486 case NV_04: 536 } else
487 boot0 = nv_rd32(dev, NV03_BOOT_0); 537 if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
488 if (boot0 & 0x00000100) 538 dev_priv->vram_size = nouveau_mem_detect_nforce(dev);
489 return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; 539 } else {
490 540 dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA);
491 switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { 541 dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
492 case NV04_BOOT_0_RAM_AMOUNT_32MB: 542 if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
493 return 32 * 1024 * 1024; 543 dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
494 case NV04_BOOT_0_RAM_AMOUNT_16MB:
495 return 16 * 1024 * 1024;
496 case NV04_BOOT_0_RAM_AMOUNT_8MB:
497 return 8 * 1024 * 1024;
498 case NV04_BOOT_0_RAM_AMOUNT_4MB:
499 return 4 * 1024 * 1024;
500 }
501 break;
502 case NV_10:
503 case NV_20:
504 case NV_30:
505 case NV_40:
506 case NV_50:
507 default:
508 if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
509 return nouveau_mem_fb_amount_igp(dev);
510 } else {
511 uint64_t mem;
512 mem = (nv_rd32(dev, NV04_FIFO_DATA) &
513 NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
514 NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
515 return mem * 1024 * 1024;
516 }
517 break;
518 } 544 }
519 545
520 NV_ERROR(dev, 546 NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
521 "Unable to detect video ram size. Please report your setup to " 547 if (dev_priv->vram_sys_base) {
522 DRIVER_EMAIL "\n"); 548 NV_INFO(dev, "Stolen system memory at: 0x%010llx\n",
523 return 0; 549 dev_priv->vram_sys_base);
550 }
551
552 if (dev_priv->vram_size)
553 return 0;
554 return -ENOMEM;
524} 555}
525 556
526#if __OS_HAS_AGP 557#if __OS_HAS_AGP
@@ -631,15 +662,12 @@ nouveau_mem_init(struct drm_device *dev)
631 spin_lock_init(&dev_priv->ttm.bo_list_lock); 662 spin_lock_init(&dev_priv->ttm.bo_list_lock);
632 spin_lock_init(&dev_priv->tile.lock); 663 spin_lock_init(&dev_priv->tile.lock);
633 664
634 dev_priv->fb_available_size = nouveau_mem_fb_amount(dev); 665 dev_priv->fb_available_size = dev_priv->vram_size;
635
636 dev_priv->fb_mappable_pages = dev_priv->fb_available_size; 666 dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
637 if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1)) 667 if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
638 dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1); 668 dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
639 dev_priv->fb_mappable_pages >>= PAGE_SHIFT; 669 dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
640 670
641 NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20));
642
643 /* remove reserved space at end of vram from available amount */ 671 /* remove reserved space at end of vram from available amount */
644 dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram; 672 dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
645 dev_priv->fb_aper_free = dev_priv->fb_available_size; 673 dev_priv->fb_aper_free = dev_priv->fb_available_size;