diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvc0_vram.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c index abed0d3d5792..edbfe9360ae2 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vram.c +++ b/drivers/gpu/drm/nouveau/nvc0_vram.c | |||
| @@ -106,12 +106,50 @@ nvc0_vram_init(struct drm_device *dev) | |||
| 106 | struct nouveau_vram_engine *vram = &dev_priv->engine.vram; | 106 | struct nouveau_vram_engine *vram = &dev_priv->engine.vram; |
| 107 | const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ | 107 | const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ |
| 108 | const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ | 108 | const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ |
| 109 | u32 length; | 109 | u32 parts = nv_rd32(dev, 0x121c74); |
| 110 | u32 bsize = nv_rd32(dev, 0x10f20c); | ||
| 111 | u32 offset, length; | ||
| 112 | bool uniform = true; | ||
| 113 | int ret, i; | ||
| 110 | 114 | ||
| 111 | dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20; | 115 | NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800)); |
| 112 | dev_priv->vram_size *= nv_rd32(dev, 0x121c74); | 116 | NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize); |
| 113 | 117 | ||
| 114 | length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail; | 118 | /* read amount of vram attached to each memory controller */ |
| 119 | for (i = 0; i < parts; i++) { | ||
| 120 | u32 psize = nv_rd32(dev, 0x11020c + (i * 0x1000)); | ||
| 121 | if (psize != bsize) { | ||
| 122 | if (psize < bsize) | ||
| 123 | bsize = psize; | ||
| 124 | uniform = false; | ||
| 125 | } | ||
| 126 | |||
| 127 | NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", i, psize); | ||
| 128 | |||
| 129 | dev_priv->vram_size += (u64)psize << 20; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* if all controllers have the same amount attached, there's no holes */ | ||
| 133 | if (uniform) { | ||
| 134 | offset = rsvd_head; | ||
| 135 | length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail; | ||
| 136 | return nouveau_mm_init(&vram->mm, offset, length, 1); | ||
| 137 | } | ||
| 115 | 138 | ||
| 116 | return nouveau_mm_init(&vram->mm, rsvd_head, length, 1); | 139 | /* otherwise, address lowest common amount from 0GiB */ |
| 140 | ret = nouveau_mm_init(&vram->mm, rsvd_head, (bsize << 8) * parts, 1); | ||
| 141 | if (ret) | ||
| 142 | return ret; | ||
| 143 | |||
| 144 | /* and the rest starting from (8GiB + common_size) */ | ||
| 145 | offset = (0x0200000000ULL >> 12) + (bsize << 8); | ||
| 146 | length = (dev_priv->vram_size >> 12) - (bsize << 8) - rsvd_tail; | ||
| 147 | |||
| 148 | ret = nouveau_mm_init(&vram->mm, offset, length, 0); | ||
| 149 | if (ret) { | ||
| 150 | nouveau_mm_fini(&vram->mm); | ||
| 151 | return ret; | ||
| 152 | } | ||
| 153 | |||
| 154 | return 0; | ||
| 117 | } | 155 | } |
