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);
}
}
+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)
{
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;