diff options
Diffstat (limited to 'nvkm/subdev/fb/ramnva3.c')
-rw-r--r-- | nvkm/subdev/fb/ramnva3.c | 87 |
1 files changed, 45 insertions, 42 deletions
diff --git a/nvkm/subdev/fb/ramnva3.c b/nvkm/subdev/fb/ramnva3.c index c2037b943..3601deca0 100644 --- a/nvkm/subdev/fb/ramnva3.c +++ b/nvkm/subdev/fb/ramnva3.c @@ -79,21 +79,27 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) struct nva3_ram *ram = (void *)pfb->ram; struct nva3_ramfuc *fuc = &ram->fuc; struct nva3_clock_info mclk; - struct nvbios_ramcfg cfg; - u8 ver, cnt, len, strap; + struct nouveau_ram_data *next; + u8 ver, hdr, cnt, len, strap; u32 data; - struct { - u32 data; - u8 size; - } rammap, ramcfg, timing; u32 r004018, r100760, ctrl; u32 unk714, unk718, unk71c; - int ret; + int ret, i; + + next = &ram->base.target; + next->freq = freq; + ram->base.next = next; /* lookup memory config data relevant to the target frequency */ - rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size, - &cnt, &ramcfg.size, &cfg); - if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) { + i = 0; + while ((data = nvbios_rammapEp(bios, i++, &ver, &hdr, &cnt, &len, + &next->bios))) { + if (freq / 1000 >= next->bios.rammap_min && + freq / 1000 <= next->bios.rammap_max) + break; + } + + if (!data || ver != 0x10 || hdr < 0x0e) { nv_error(pfb, "invalid/missing rammap entry\n"); return -EINVAL; } @@ -105,23 +111,22 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) return -EINVAL; } - ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size); - if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) { + data = nvbios_rammapSp(bios, data, ver, hdr, cnt, len, strap, + &ver, &hdr, &next->bios); + if (!data || ver != 0x10 || hdr < 0x0e) { nv_error(pfb, "invalid/missing ramcfg entry\n"); return -EINVAL; } /* lookup memory timings, if bios says they're present */ - strap = nv_ro08(bios, ramcfg.data + 0x01); - if (strap != 0xff) { - timing.data = nvbios_timingEe(bios, strap, &ver, &timing.size, - &cnt, &len); - if (!timing.data || ver != 0x10 || timing.size < 0x19) { + if (next->bios.ramcfg_timing != 0xff) { + data = nvbios_timingEp(bios, next->bios.ramcfg_timing, + &ver, &hdr, &cnt, &len, + &next->bios); + if (!data || ver != 0x10 || hdr < 0x19) { nv_error(pfb, "invalid/missing timing entry\n"); return -EINVAL; } - } else { - timing.data = 0; } ret = nva3_pll_info(nouveau_clock(pfb), 0x12, 0x4000, freq, &mclk); @@ -164,17 +169,17 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) ram_mask(fuc, 0x004168, 0x003f3141, ctrl); } - if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) { + if (next->bios.ramcfg_10_02_10) { ram_mask(fuc, 0x111104, 0x00000600, 0x00000000); } else { ram_mask(fuc, 0x111100, 0x40000000, 0x40000000); ram_mask(fuc, 0x111104, 0x00000180, 0x00000000); } - if (!(nv_ro08(bios, rammap.data + 0x04) & 0x02)) + if (!next->bios.rammap_10_04_02) ram_mask(fuc, 0x100200, 0x00000800, 0x00000000); ram_wr32(fuc, 0x611200, 0x00003300); - if (!(nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) + if (!next->bios.ramcfg_10_02_10) ram_wr32(fuc, 0x111100, 0x4c020000); /*XXX*/ ram_wr32(fuc, 0x1002d4, 0x00000001); @@ -203,17 +208,16 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) ram_wr32(fuc, 0x004018, 0x0000d000 | r004018); } - if ( (nv_ro08(bios, rammap.data + 0x04) & 0x08)) { - u32 unk5a0 = (nv_ro16(bios, ramcfg.data + 0x05) << 8) | - nv_ro08(bios, ramcfg.data + 0x05); - u32 unk5a4 = (nv_ro16(bios, ramcfg.data + 0x07)); - u32 unk804 = (nv_ro08(bios, ramcfg.data + 0x09) & 0xf0) << 16 | - (nv_ro08(bios, ramcfg.data + 0x03) & 0x0f) << 16 | - (nv_ro08(bios, ramcfg.data + 0x09) & 0x0f) | - 0x80000000; - ram_wr32(fuc, 0x1005a0, unk5a0); - ram_wr32(fuc, 0x1005a4, unk5a4); - ram_wr32(fuc, 0x10f804, unk804); + if (next->bios.rammap_10_04_08) { + ram_wr32(fuc, 0x1005a0, next->bios.ramcfg_10_06 << 16 | + next->bios.ramcfg_10_05 << 8 | + next->bios.ramcfg_10_05); + ram_wr32(fuc, 0x1005a4, next->bios.ramcfg_10_08 << 8 | + next->bios.ramcfg_10_07); + ram_wr32(fuc, 0x10f804, next->bios.ramcfg_10_09_f0 << 20 | + next->bios.ramcfg_10_03_0f << 16 | + next->bios.ramcfg_10_09_0f | + 0x80000000); ram_mask(fuc, 0x10053c, 0x00001000, 0x00000000); } else { ram_mask(fuc, 0x10053c, 0x00001000, 0x00001000); @@ -251,27 +255,26 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) ram_mask(fuc, 0x100220[0], 0x00000000, 0x00000000); ram_mask(fuc, 0x100220[8], 0x00000000, 0x00000000); - data = (nv_ro08(bios, ramcfg.data + 0x02) & 0x08) ? 0x00000000 : 0x00001000; - ram_mask(fuc, 0x100200, 0x00001000, data); + ram_mask(fuc, 0x100200, 0x00001000, !next->bios.ramcfg_10_02_08 << 12); unk714 = ram_rd32(fuc, 0x100714) & ~0xf0000010; unk718 = ram_rd32(fuc, 0x100718) & ~0x00000100; unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100; - if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x20)) + if (next->bios.ramcfg_10_02_20) unk714 |= 0xf0000000; - if (!(nv_ro08(bios, ramcfg.data + 0x02) & 0x04)) + if (!next->bios.ramcfg_10_02_04) unk714 |= 0x00000010; ram_wr32(fuc, 0x100714, unk714); - if (nv_ro08(bios, ramcfg.data + 0x02) & 0x01) + if (next->bios.ramcfg_10_02_01) unk71c |= 0x00000100; ram_wr32(fuc, 0x10071c, unk71c); - if (nv_ro08(bios, ramcfg.data + 0x02) & 0x02) + if (next->bios.ramcfg_10_02_02) unk718 |= 0x00000100; ram_wr32(fuc, 0x100718, unk718); - if (nv_ro08(bios, ramcfg.data + 0x02) & 0x10) + if (next->bios.ramcfg_10_02_10) ram_wr32(fuc, 0x111100, 0x48000000); /*XXX*/ ram_mask(fuc, mr[0], 0x100, 0x100); @@ -283,9 +286,9 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) ram_nsec(fuc, 12000); ram_wr32(fuc, 0x611200, 0x00003330); - if ( (nv_ro08(bios, rammap.data + 0x04) & 0x02)) + if (next->bios.rammap_10_04_02) ram_mask(fuc, 0x100200, 0x00000800, 0x00000800); - if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) { + if (next->bios.ramcfg_10_02_10) { ram_mask(fuc, 0x111104, 0x00000180, 0x00000180); ram_mask(fuc, 0x111100, 0x40000000, 0x00000000); } else { |