diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv20_fb.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv40_fb.c | 45 |
4 files changed, 57 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 576b0f67a8b..59031d308fc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1173,6 +1173,7 @@ extern void nv30_fb_init_tile_region(struct drm_device *dev, int i, extern void nv30_fb_free_tile_region(struct drm_device *dev, int i); /* nv40_fb.c */ +extern int nv40_fb_vram_init(struct drm_device *dev); extern int nv40_fb_init(struct drm_device *); extern void nv40_fb_takedown(struct drm_device *); extern void nv40_fb_set_tile_region(struct drm_device *dev, int i); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 6c262e1aaf9..a30d7af58eb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -290,7 +290,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.temp_get = nv40_temp_get; engine->pm.pwm_get = nv40_pm_pwm_get; engine->pm.pwm_set = nv40_pm_pwm_set; - engine->vram.init = nv20_fb_vram_init; + engine->vram.init = nv40_fb_vram_init; engine->vram.takedown = nouveau_stub_takedown; engine->vram.flags_valid = nouveau_mem_flags_valid; break; diff --git a/drivers/gpu/drm/nouveau/nv20_fb.c b/drivers/gpu/drm/nouveau/nv20_fb.c index 6585c27186d..19bd64059a6 100644 --- a/drivers/gpu/drm/nouveau/nv20_fb.c +++ b/drivers/gpu/drm/nouveau/nv20_fb.c @@ -100,8 +100,17 @@ int nv20_fb_vram_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + u32 mem_size = nv_rd32(dev, 0x10020c); + u32 pbus1218 = nv_rd32(dev, 0x001218); + + dev_priv->vram_size = mem_size & 0xff000000; + switch (pbus1218 & 0x00000300) { + case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break; + case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; + case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; + case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_GDDR2; break; + } - dev_priv->vram_size = nv_rd32(dev, 0x10020c) & 0xff000000; return 0; } diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c index f0ac2a768c6..7fbcb334c09 100644 --- a/drivers/gpu/drm/nouveau/nv40_fb.c +++ b/drivers/gpu/drm/nouveau/nv40_fb.c @@ -72,6 +72,51 @@ nv44_fb_init_gart(struct drm_device *dev) } int +nv40_fb_vram_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + /* 0x001218 is actually present on a few other NV4X I looked at, + * and even contains sane values matching 0x100474. From looking + * at various vbios images however, this isn't the case everywhere. + * So, I chose to use the same regs I've seen NVIDIA reading around + * the memory detection, hopefully that'll get us the right numbers + */ + if (dev_priv->chipset == 0x40) { + u32 pbus1218 = nv_rd32(dev, 0x001218); + switch (pbus1218 & 0x00000300) { + case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break; + case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; + case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; + case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; + } + } else + if (dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) { + u32 pfb914 = nv_rd32(dev, 0x100914); + switch (pfb914 & 0x00000003) { + case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; + case 0x00000001: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; + case 0x00000002: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; + case 0x00000003: break; + } + } else + if (dev_priv->chipset != 0x4e) { + u32 pfb474 = nv_rd32(dev, 0x100474); + if (pfb474 & 0x00000004) + dev_priv->vram_type = NV_MEM_TYPE_GDDR3; + if (pfb474 & 0x00000002) + dev_priv->vram_type = NV_MEM_TYPE_DDR2; + if (pfb474 & 0x00000001) + dev_priv->vram_type = NV_MEM_TYPE_DDR1; + } else { + dev_priv->vram_type = NV_MEM_TYPE_STOLEN; + } + + dev_priv->vram_size = nv_rd32(dev, 0x10020c) & 0xff000000; + return 0; +} + +int nv40_fb_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; |