|
@@ -597,9 +597,9 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|
|
if (!memtimings->timing)
|
|
|
return;
|
|
|
|
|
|
- /* Get "some number" from the timing reg for NV_40
|
|
|
+ /* Get "some number" from the timing reg for NV_40 and NV_50
|
|
|
* Used in calculations later */
|
|
|
- if (dev_priv->card_type == NV_40) {
|
|
|
+ if (dev_priv->card_type >= NV_40 && dev_priv->chipset < 0x98) {
|
|
|
magic_number = (nv_rd32(dev, 0x100228) & 0x0f000000) >> 24;
|
|
|
}
|
|
|
|
|
@@ -643,7 +643,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|
|
/* XXX: I don't trust the -1's and +1's... they must come
|
|
|
* from somewhere! */
|
|
|
timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 |
|
|
|
- tUNK_18 << 16 |
|
|
|
+ max(tUNK_18, (u8) 1) << 16 |
|
|
|
(tUNK_1 + tUNK_19 + 1 + magic_number) << 8;
|
|
|
if (dev_priv->chipset == 0xa8) {
|
|
|
timing->reg_100224 |= (tUNK_2 - 1);
|
|
@@ -652,17 +652,27 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|
|
}
|
|
|
|
|
|
timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
|
|
|
- if (dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) {
|
|
|
+ if (dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa)
|
|
|
timing->reg_100228 |= (tUNK_19 - 1) << 24;
|
|
|
- }
|
|
|
+ else
|
|
|
+ timing->reg_100228 |= magic_number << 24;
|
|
|
|
|
|
if (dev_priv->card_type == NV_40) {
|
|
|
/* NV40: don't know what the rest of the regs are..
|
|
|
* And don't need to know either */
|
|
|
- timing->reg_100228 |= 0x20200000 | magic_number << 24;
|
|
|
+ timing->reg_100228 |= 0x20200000;
|
|
|
} else if (dev_priv->card_type >= NV_50) {
|
|
|
- /* XXX: reg_10022c */
|
|
|
- timing->reg_10022c = tUNK_2 - 1;
|
|
|
+ if (dev_priv->chipset < 0x98 ||
|
|
|
+ (dev_priv->chipset == 0x98 &&
|
|
|
+ dev_priv->stepping <= 0xa1)) {
|
|
|
+ timing->reg_10022c = (0x14 + tUNK_2) << 24 |
|
|
|
+ 0x16 << 16 |
|
|
|
+ (tUNK_2 - 1) << 8 |
|
|
|
+ (tUNK_2 - 1);
|
|
|
+ } else {
|
|
|
+ /* XXX: reg_10022c for recentish cards */
|
|
|
+ timing->reg_10022c = tUNK_2 - 1;
|
|
|
+ }
|
|
|
|
|
|
timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
|
|
|
tUNK_13 << 8 | tUNK_13);
|
|
@@ -670,23 +680,29 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|
|
timing->reg_100234 = (tRAS << 24 | tRC);
|
|
|
timing->reg_100234 += max(tUNK_10, tUNK_11) << 16;
|
|
|
|
|
|
- if (dev_priv->chipset < 0xa3) {
|
|
|
+ if (dev_priv->chipset < 0x98 ||
|
|
|
+ (dev_priv->chipset == 0x98 &&
|
|
|
+ dev_priv->stepping <= 0xa1)) {
|
|
|
timing->reg_100234 |= (tUNK_2 + 2) << 8;
|
|
|
} else {
|
|
|
/* XXX: +6? */
|
|
|
timing->reg_100234 |= (tUNK_19 + 6) << 8;
|
|
|
}
|
|
|
|
|
|
- /* XXX; reg_100238, reg_10023c
|
|
|
- * reg_100238: 0x00??????
|
|
|
- * reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */
|
|
|
+ /* XXX; reg_100238
|
|
|
+ * reg_100238: 0x00?????? */
|
|
|
timing->reg_10023c = 0x202;
|
|
|
- if (dev_priv->chipset < 0xa3) {
|
|
|
+ if (dev_priv->chipset < 0x98 ||
|
|
|
+ (dev_priv->chipset == 0x98 &&
|
|
|
+ dev_priv->stepping <= 0xa1)) {
|
|
|
timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16;
|
|
|
} else {
|
|
|
- /* currently unknown
|
|
|
+ /* XXX: reg_10023c
|
|
|
+ * currently unknown
|
|
|
* 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */
|
|
|
}
|
|
|
+
|
|
|
+ /* XXX: reg_100240? */
|
|
|
}
|
|
|
|
|
|
NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
|
|
@@ -695,6 +711,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
|
|
NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n",
|
|
|
timing->reg_100230, timing->reg_100234,
|
|
|
timing->reg_100238, timing->reg_10023c);
|
|
|
+ NV_DEBUG(dev, " 240: %08x\n", timing->reg_100240);
|
|
|
}
|
|
|
|
|
|
memtimings->nr_timing = entries;
|