diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 59031d308fccd7bbff86de5e80e5a69175d3cc17..5a4947919f1ce7ff1f577a95fb4d70f567823a75 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -909,6 +909,7 @@ extern int nouveau_mem_init_agp(struct drm_device *); extern int nouveau_mem_reset_agp(struct drm_device *); extern void nouveau_mem_close(struct drm_device *); extern bool nouveau_mem_flags_valid(struct drm_device *, u32 tile_flags); +extern int nouveau_mem_vbios_type(struct drm_device *); extern struct nouveau_tile_reg *nv10_mem_set_tiling( struct drm_device *dev, uint32_t addr, uint32_t size, uint32_t pitch, uint32_t flags); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 4a658310c29a3c01dd035ddd09f9cdae2aee4f97..c5ba6c2eab883b1f36ea9c575ea3149fdba3ab91 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -683,6 +683,29 @@ nouveau_mem_timing_fini(struct drm_device *dev) } } +int +nouveau_mem_vbios_type(struct drm_device *dev) +{ + struct bit_entry M; + u8 ramcfg = (nv_rd32(dev, 0x101000) & 0x0000003c) >> 2; + if (!bit_table(dev, 'M', &M) || M.version != 2 || M.length < 5) { + u8 *table = ROMPTR(dev, M.data[3]); + if (table && table[0] == 0x10 && ramcfg < table[3]) { + u8 *entry = table + table[1] + (ramcfg * table[2]); + switch (entry[0] & 0x0f) { + case 0: return NV_MEM_TYPE_DDR2; + case 1: return NV_MEM_TYPE_DDR3; + case 2: return NV_MEM_TYPE_GDDR3; + case 3: return NV_MEM_TYPE_GDDR5; + default: + break; + } + + } + } + return NV_MEM_TYPE_UNKNOWN; +} + static int nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c index 84069669461187d88f6787149125080fd57a8a69..1467efc6d61dea2dc43bc75fed59399efd9e2054 100644 --- a/drivers/gpu/drm/nouveau/nv50_vram.c +++ b/drivers/gpu/drm/nouveau/nv50_vram.c @@ -195,10 +195,10 @@ nv50_vram_init(struct drm_device *dev) switch (pfb714 & 0x00000007) { case 0: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; case 1: - if (0 /* some currently unknown condition */) - dev_priv->vram_type = NV_MEM_TYPE_DDR2; - else + if (nouveau_mem_vbios_type(dev) == NV_MEM_TYPE_DDR3) dev_priv->vram_type = NV_MEM_TYPE_DDR3; + else + dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; case 2: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; case 3: dev_priv->vram_type = NV_MEM_TYPE_GDDR4; break;