aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_mem.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-08-11 22:37:28 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-09-24 02:21:55 -0400
commit6c3d7ef25e3b4a0ea511b1e9d4a0a212750874a6 (patch)
treef5f5ddfaa99dc244e51d2728eb1fc0156fb38506 /drivers/gpu/drm/nouveau/nouveau_mem.c
parent5125bfd88608012d58652ac7ea6a03a78773200f (diff)
drm/nv50: calculate vram reordering block size
Will be used at a later point when we plug in an alternative VRAM memory manager for GeForce 8+ boards. Based on pscnv code to do the same. Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Marcin Koƛcielnicki <koriakin@0x04.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_mem.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c67
1 files changed, 65 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index f34c532bcac3..6eeaeac56293 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -308,7 +308,61 @@ nouveau_mem_detect_nforce(struct drm_device *dev)
308 return 0; 308 return 0;
309} 309}
310 310
311/* returns the amount of FB ram in bytes */ 311static void
312nv50_vram_preinit(struct drm_device *dev)
313{
314 struct drm_nouveau_private *dev_priv = dev->dev_private;
315 int i, parts, colbits, rowbitsa, rowbitsb, banks;
316 u64 rowsize, predicted;
317 u32 r0, r4, rt, ru;
318
319 r0 = nv_rd32(dev, 0x100200);
320 r4 = nv_rd32(dev, 0x100204);
321 rt = nv_rd32(dev, 0x100250);
322 ru = nv_rd32(dev, 0x001540);
323 NV_DEBUG(dev, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
324
325 for (i = 0, parts = 0; i < 8; i++) {
326 if (ru & (0x00010000 << i))
327 parts++;
328 }
329
330 colbits = (r4 & 0x0000f000) >> 12;
331 rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
332 rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
333 banks = ((r4 & 0x01000000) ? 8 : 4);
334
335 rowsize = parts * banks * (1 << colbits) * 8;
336 predicted = rowsize << rowbitsa;
337 if (r0 & 0x00000004)
338 predicted += rowsize << rowbitsb;
339
340 if (predicted != dev_priv->vram_size) {
341 NV_WARN(dev, "memory controller reports %dMiB VRAM\n",
342 (u32)(dev_priv->vram_size >> 20));
343 NV_WARN(dev, "we calculated %dMiB VRAM\n",
344 (u32)(predicted >> 20));
345 }
346
347 dev_priv->vram_rblock_size = rowsize >> 12;
348 if (rt & 1)
349 dev_priv->vram_rblock_size *= 3;
350
351 NV_DEBUG(dev, "rblock %lld bytes\n",
352 (u64)dev_priv->vram_rblock_size << 12);
353}
354
355static void
356nvaa_vram_preinit(struct drm_device *dev)
357{
358 struct drm_nouveau_private *dev_priv = dev->dev_private;
359
360 /* To our knowledge, there's no large scale reordering of pages
361 * that occurs on IGP chipsets.
362 */
363 dev_priv->vram_rblock_size = 1;
364}
365
312int 366int
313nouveau_mem_detect(struct drm_device *dev) 367nouveau_mem_detect(struct drm_device *dev)
314{ 368{
@@ -328,9 +382,18 @@ nouveau_mem_detect(struct drm_device *dev)
328 dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); 382 dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA);
329 dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; 383 dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32;
330 dev_priv->vram_size &= 0xffffffff00ll; 384 dev_priv->vram_size &= 0xffffffff00ll;
331 if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { 385
386 switch (dev_priv->chipset) {
387 case 0xaa:
388 case 0xac:
389 case 0xaf:
332 dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); 390 dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
333 dev_priv->vram_sys_base <<= 12; 391 dev_priv->vram_sys_base <<= 12;
392 nvaa_vram_preinit(dev);
393 break;
394 default:
395 nv50_vram_preinit(dev);
396 break;
334 } 397 }
335 } else { 398 } else {
336 dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20; 399 dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20;