drm/nouveau: correct memtiming table parsing for nv4x
In line with envytools, verified on 4 or 5 BIOS'es. Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Roy Spliet <r.spliet@student.tudelft.nl>
This commit is contained in:
parent
758f231ea2
commit
ac5c15fa58
|
@ -552,6 +552,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||||
u8 tRC; /* Byte 9 */
|
u8 tRC; /* Byte 9 */
|
||||||
u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14;
|
u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14;
|
||||||
u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21;
|
u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21;
|
||||||
|
u8 magic_number = 0; /* Yeah... sorry*/
|
||||||
u8 *mem = NULL, *entry;
|
u8 *mem = NULL, *entry;
|
||||||
int i, recordlen, entries;
|
int i, recordlen, entries;
|
||||||
|
|
||||||
|
@ -596,6 +597,12 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||||
if (!memtimings->timing)
|
if (!memtimings->timing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Get "some number" from the timing reg for NV_40
|
||||||
|
* Used in calculations later */
|
||||||
|
if(dev_priv->card_type == NV_40) {
|
||||||
|
magic_number = (nv_rd32(dev,0x100228) & 0x0f000000) >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
entry = mem + mem[1];
|
entry = mem + mem[1];
|
||||||
for (i = 0; i < entries; i++, entry += recordlen) {
|
for (i = 0; i < entries; i++, entry += recordlen) {
|
||||||
struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i];
|
struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i];
|
||||||
|
@ -635,36 +642,51 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||||
|
|
||||||
/* XXX: I don't trust the -1's and +1's... they must come
|
/* XXX: I don't trust the -1's and +1's... they must come
|
||||||
* from somewhere! */
|
* from somewhere! */
|
||||||
timing->reg_100224 = ((tUNK_0 + tUNK_19 + 1) << 24 |
|
timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 |
|
||||||
tUNK_18 << 16 |
|
tUNK_18 << 16 |
|
||||||
(tUNK_1 + tUNK_19 + 1) << 8 |
|
(tUNK_1 + tUNK_19 + 1 + magic_number) << 8;
|
||||||
(tUNK_2 - 1));
|
if(dev_priv->chipset == 0xa8) {
|
||||||
|
timing->reg_100224 |= (tUNK_2 - 1);
|
||||||
|
} else {
|
||||||
|
timing->reg_100224 |= (tUNK_2 + 2 - magic_number);
|
||||||
|
}
|
||||||
|
|
||||||
timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
|
timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
|
||||||
if(recordlen > 19) {
|
if(dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) {
|
||||||
timing->reg_100228 += (tUNK_19 - 1) << 24;
|
timing->reg_100228 |= (tUNK_19 - 1) << 24;
|
||||||
}/* I cannot back-up this else-statement right now
|
}
|
||||||
else {
|
|
||||||
timing->reg_100228 += tUNK_12 << 24;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/* XXX: reg_10022c */
|
if(dev_priv->card_type == NV_40) {
|
||||||
timing->reg_10022c = tUNK_2 - 1;
|
/* 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;
|
||||||
|
} else if(dev_priv->card_type >= NV_50) {
|
||||||
|
/* XXX: reg_10022c */
|
||||||
|
timing->reg_10022c = tUNK_2 - 1;
|
||||||
|
|
||||||
timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
|
timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
|
||||||
tUNK_13 << 8 | tUNK_13);
|
tUNK_13 << 8 | tUNK_13);
|
||||||
|
|
||||||
/* XXX: +6? */
|
timing->reg_100234 = (tRAS << 24 | tRC);
|
||||||
timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC);
|
timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
|
||||||
timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
|
|
||||||
|
|
||||||
/* XXX; reg_100238, reg_10023c
|
if(dev_priv->chipset < 0xa3) {
|
||||||
* reg: 0x00??????
|
timing->reg_100234 |= (tUNK_2 + 2) << 8;
|
||||||
* reg_10023c:
|
} else {
|
||||||
* 0 for pre-NV50 cards
|
/* XXX: +6? */
|
||||||
* 0x????0202 for NV50+ cards (empirical evidence) */
|
timing->reg_100234 |= (tUNK_19 + 6) << 8;
|
||||||
if(dev_priv->card_type >= NV_50) {
|
}
|
||||||
|
|
||||||
|
/* XXX; reg_100238, reg_10023c
|
||||||
|
* reg_100238: 0x00??????
|
||||||
|
* reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */
|
||||||
timing->reg_10023c = 0x202;
|
timing->reg_10023c = 0x202;
|
||||||
|
if(dev_priv->chipset < 0xa3) {
|
||||||
|
timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16;
|
||||||
|
} else {
|
||||||
|
/* currently unknown
|
||||||
|
* 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
|
NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
|
||||||
|
@ -675,7 +697,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||||
timing->reg_100238, timing->reg_10023c);
|
timing->reg_100238, timing->reg_10023c);
|
||||||
}
|
}
|
||||||
|
|
||||||
memtimings->nr_timing = entries;
|
memtimings->nr_timing = entries;
|
||||||
memtimings->supported = true;
|
memtimings->supported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue