Commit bf504b3f authored by Roy Spliet's avatar Roy Spliet Committed by Ben Skeggs

drm/nouveau/fb/ramnva3: Ressurect timing calculation code

Signed-off-by: default avatarRoy Spliet <rspliet@eclipso.eu>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 7f4b9616
......@@ -95,9 +95,29 @@ struct nvbios_ramcfg {
union {
struct {
unsigned timing_10_WR:8;
unsigned timing_10_WTR:8;
unsigned timing_10_CL:8;
unsigned timing_10_RC:8;
/*empty: 4 */
unsigned timing_10_RFC:8; /* Byte 5 */
/*empty: 6 */
unsigned timing_10_RAS:8; /* Byte 7 */
/*empty: 8 */
unsigned timing_10_RP:8; /* Byte 9 */
unsigned timing_10_RCDRD:8;
unsigned timing_10_RCDWR:8;
unsigned timing_10_RRD:8;
unsigned timing_10_13:8;
unsigned timing_10_ODT:3;
/* empty: 15 */
unsigned timing_10_16:8;
/* empty: 17 */
unsigned timing_10_18:8;
unsigned timing_10_CWL:8;
unsigned timing_10_20:8;
unsigned timing_10_21:8;
/* empty: 22, 23 */
unsigned timing_10_24:8;
};
struct {
unsigned timing_20_2e_03:2;
......
......@@ -93,10 +93,44 @@ nvbios_timingEp(struct nouveau_bios *bios, int idx,
p->timing_hdr = *hdr;
switch (!!data * *ver) {
case 0x10:
p->timing_10_WR = nv_ro08(bios, data + 0x00);
p->timing_10_CL = nv_ro08(bios, data + 0x02);
p->timing_10_ODT = nv_ro08(bios, data + 0x0e) & 0x07;
p->timing_10_CWL = nv_ro08(bios, data + 0x13);
p->timing_10_WR = nv_ro08(bios, data + 0x00);
p->timing_10_WTR = nv_ro08(bios, data + 0x01);
p->timing_10_CL = nv_ro08(bios, data + 0x02);
p->timing_10_RC = nv_ro08(bios, data + 0x03);
p->timing_10_RFC = nv_ro08(bios, data + 0x05);
p->timing_10_RAS = nv_ro08(bios, data + 0x07);
p->timing_10_RP = nv_ro08(bios, data + 0x09);
p->timing_10_RCDRD = nv_ro08(bios, data + 0x0a);
p->timing_10_RCDWR = nv_ro08(bios, data + 0x0b);
p->timing_10_RRD = nv_ro08(bios, data + 0x0c);
p->timing_10_13 = nv_ro08(bios, data + 0x0d);
p->timing_10_ODT = nv_ro08(bios, data + 0x0e) & 0x07;
p->timing_10_24 = 0xff;
p->timing_10_21 = 0;
p->timing_10_20 = 0;
p->timing_10_CWL = 0;
p->timing_10_18 = 0;
p->timing_10_16 = 0;
switch (min_t(u8, *hdr, 25)) {
case 25:
p->timing_10_24 = nv_ro08(bios, data + 0x18);
case 24:
case 23:
case 22:
p->timing_10_21 = nv_ro08(bios, data + 0x15);
case 21:
p->timing_10_20 = nv_ro08(bios, data + 0x14);
case 20:
p->timing_10_CWL = nv_ro08(bios, data + 0x13);
case 19:
p->timing_10_18 = nv_ro08(bios, data + 0x12);
case 18:
case 17:
p->timing_10_16 = nv_ro08(bios, data + 0x10);
}
break;
case 0x20:
p->timing[0] = nv_ro32(bios, data + 0x00);
......
......@@ -343,6 +343,66 @@ nva3_link_train_fini(struct nouveau_fb *pfb)
pfb->ram->put(pfb, &ram->ltrain.mem);
}
/*
* RAM reclocking
*/
#define T(t) cfg->timing_10_##t
static int
nva3_ram_timing_calc(struct nouveau_fb *pfb, u32 *timing)
{
struct nva3_ram *ram = (void *)pfb->ram;
struct nvbios_ramcfg *cfg = &ram->base.target.bios;
int tUNK_base;
u32 cur3, cur7, cur8;
cur3 = nv_rd32(pfb, 0x10022c);
cur7 = nv_rd32(pfb, 0x10023c);
cur8 = nv_rd32(pfb, 0x100240);
if (T(CWL) == 0)
T(CWL) = ((nv_rd32(pfb, 0x100228) & 0x0f000000) >> 24) + 1;
tUNK_base = ((cur7 & 0x00ff0000) >> 16) -
(cur3 & 0x000000ff) - 1;
timing[0] = (T(RP) << 24 | T(RAS) << 16 | T(RFC) << 8 | T(RC));
timing[1] = (T(WR) + 1 + T(CWL)) << 24 |
max_t(u8,T(18), 1) << 16 |
(T(WTR) + 1 + T(CWL)) << 8 |
(5 + T(CL) - T(CWL));
timing[2] = (T(CWL) - 1) << 24 |
(T(RRD) << 16) |
(T(RCDWR) << 8) |
T(RCDRD);
timing[3] = (cur3 & 0x00ff0000) |
(0x30 + T(CL)) << 24 |
(0xb + T(CL)) << 8 |
(T(CL) - 1);
timing[4] = T(20) << 24 |
T(21) << 16 |
T(13) << 8 |
T(13);
timing[5] = T(RFC) << 24 |
max_t(u8,T(RCDRD), T(RCDWR)) << 16 |
(T(CWL) + 6) << 8 |
T(RP);
timing[6] = (0x5a + T(CL)) << 16 |
(6 - T(CL) + T(CWL)) << 8 |
(0x50 + T(CL) - T(CWL));
timing[7] = (cur7 & 0xff000000) |
((tUNK_base + T(CL)) << 16) |
0x202;
timing[8] = cur8 & 0xffffff00;
nv_debug(pfb, "Entry: 220: %08x %08x %08x %08x\n",
timing[0], timing[1], timing[2], timing[3]);
nv_debug(pfb, " 230: %08x %08x %08x %08x\n",
timing[4], timing[5], timing[6], timing[7]);
nv_debug(pfb, " 240: %08x\n", timing[8]);
return 0;
}
#undef T
static int
nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
{
......@@ -356,6 +416,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
u32 r004018, r100760, ctrl;
u32 unk714, unk718, unk71c;
int ret, i;
u32 timing[9];
next = &ram->base.target;
next->freq = freq;
......@@ -409,6 +470,8 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
return ret;
}
nva3_ram_timing_calc(pfb, timing);
ret = ram_init(fuc, pfb);
if (ret)
return ret;
......@@ -519,16 +582,17 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, mr[0], 0x00000000, 0x00000000);
ram_nsec(fuc, 1000);
ram_mask(fuc, 0x100220[3], 0x00000000, 0x00000000);
ram_mask(fuc, 0x100220[1], 0x00000000, 0x00000000);
ram_mask(fuc, 0x100220[6], 0x00000000, 0x00000000);
ram_mask(fuc, 0x100220[7], 0x00000000, 0x00000000);
ram_mask(fuc, 0x100220[2], 0x00000000, 0x00000000);
ram_mask(fuc, 0x100220[4], 0x00000000, 0x00000000);
ram_mask(fuc, 0x100220[5], 0x00000000, 0x00000000);
ram_mask(fuc, 0x100220[0], 0x00000000, 0x00000000);
ram_mask(fuc, 0x100220[8], 0x00000000, 0x00000000);
ram_wr32(fuc, 0x100220[3], timing[3]);
ram_wr32(fuc, 0x100220[1], timing[1]);
ram_wr32(fuc, 0x100220[6], timing[6]);
ram_wr32(fuc, 0x100220[7], timing[7]);
ram_wr32(fuc, 0x100220[2], timing[2]);
ram_wr32(fuc, 0x100220[4], timing[4]);
ram_wr32(fuc, 0x100220[5], timing[5]);
ram_wr32(fuc, 0x100220[0], timing[0]);
ram_wr32(fuc, 0x100220[8], timing[8]);
/* Misc */
ram_mask(fuc, 0x100200, 0x00001000, !next->bios.ramcfg_10_02_08 << 12);
unk714 = ram_rd32(fuc, 0x100714) & ~0xf0000010;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment