Commit b655f2bb authored by Ben Skeggs's avatar Ben Skeggs

drm/nve0/fb/gddr5: parse bios data into struct rather than using directly

Still essentially a struct of magic values with magic names and unknown
purposes.  But, we will shortly need to be able to mix and match bits of
the previous and next configurations to do a transition reclock, as such,
we can no longer directly use the vbios data with any ease.

This is probably nicer anyway in the long run, for a few reasons.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent ea8b4a38
...@@ -3,6 +3,62 @@ ...@@ -3,6 +3,62 @@
struct nouveau_bios; struct nouveau_bios;
struct nvbios_ramcfg {
unsigned rammap_11_08_01:1;
unsigned rammap_11_08_0c:2;
unsigned rammap_11_08_10:1;
unsigned rammap_11_11_0c:2;
unsigned ramcfg_11_01_01:1;
unsigned ramcfg_11_01_02:1;
unsigned ramcfg_11_01_04:1;
unsigned ramcfg_11_01_08:1;
unsigned ramcfg_11_01_10:1;
unsigned ramcfg_11_01_20:1;
unsigned ramcfg_11_01_40:1;
unsigned ramcfg_11_01_80:1;
unsigned ramcfg_11_02_03:2;
unsigned ramcfg_11_02_04:1;
unsigned ramcfg_11_02_08:1;
unsigned ramcfg_11_02_10:1;
unsigned ramcfg_11_02_40:1;
unsigned ramcfg_11_02_80:1;
unsigned ramcfg_11_03_0f:4;
unsigned ramcfg_11_03_30:2;
unsigned ramcfg_11_03_c0:2;
unsigned ramcfg_11_03_f0:4;
unsigned ramcfg_11_04:8;
unsigned ramcfg_11_06:8;
unsigned ramcfg_11_07_02:1;
unsigned ramcfg_11_07_04:1;
unsigned ramcfg_11_07_08:1;
unsigned ramcfg_11_07_10:1;
unsigned ramcfg_11_07_40:1;
unsigned ramcfg_11_07_80:1;
unsigned ramcfg_11_08_01:1;
unsigned ramcfg_11_08_02:1;
unsigned ramcfg_11_08_04:1;
unsigned ramcfg_11_08_08:1;
unsigned ramcfg_11_08_10:1;
unsigned ramcfg_11_09:8;
unsigned timing[11];
unsigned timing_20_2e_03:2;
unsigned timing_20_2e_30:2;
unsigned timing_20_2e_c0:2;
unsigned timing_20_2f_03:2;
unsigned timing_20_2c_003f:6;
unsigned timing_20_2c_1fc0:7;
unsigned timing_20_30_f8:5;
unsigned timing_20_30_07:3;
unsigned timing_20_31_0007:3;
unsigned timing_20_31_0078:4;
unsigned timing_20_31_0780:4;
unsigned timing_20_31_0800:1;
unsigned timing_20_31_7000:3;
unsigned timing_20_31_8000:1;
};
u8 nvbios_ramcfg_count(struct nouveau_bios *); u8 nvbios_ramcfg_count(struct nouveau_bios *);
u8 nvbios_ramcfg_index(struct nouveau_bios *); u8 nvbios_ramcfg_index(struct nouveau_bios *);
......
#ifndef __NVBIOS_RAMMAP_H__ #ifndef __NVBIOS_RAMMAP_H__
#define __NVBIOS_RAMMAP_H__ #define __NVBIOS_RAMMAP_H__
u16 nvbios_rammap_table(struct nouveau_bios *, u8 *ver, u8 *hdr, struct nvbios_ramcfg;
u32 nvbios_rammapTe(struct nouveau_bios *, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len, u8 *snr, u8 *ssz); u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
u16 nvbios_rammap_entry(struct nouveau_bios *, int idx,
u32 nvbios_rammapEe(struct nouveau_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len); u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 nvbios_rammap_match(struct nouveau_bios *, u16 khz, u32 nvbios_rammapEm(struct nouveau_bios *, u16 mhz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len); u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_rammapEp(struct nouveau_bios *, u16 mhz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_ramcfg *);
u32 nvbios_rammapSe(struct nouveau_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr);
u32 nvbios_rammapSp(struct nouveau_bios *, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr,
struct nvbios_ramcfg *);
#endif #endif
#ifndef __NVBIOS_TIMING_H__ #ifndef __NVBIOS_TIMING_H__
#define __NVBIOS_TIMING_H__ #define __NVBIOS_TIMING_H__
struct nvbios_ramcfg;
u16 nvbios_timingTe(struct nouveau_bios *, u16 nvbios_timingTe(struct nouveau_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz); u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
u16 nvbios_timingEe(struct nouveau_bios *, int idx, u16 nvbios_timingEe(struct nouveau_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len); u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 nvbios_timingEp(struct nouveau_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_ramcfg *);
#endif #endif
...@@ -106,6 +106,12 @@ extern struct nouveau_oclass *nvaf_fb_oclass; ...@@ -106,6 +106,12 @@ extern struct nouveau_oclass *nvaf_fb_oclass;
extern struct nouveau_oclass *nvc0_fb_oclass; extern struct nouveau_oclass *nvc0_fb_oclass;
extern struct nouveau_oclass *nve0_fb_oclass; extern struct nouveau_oclass *nve0_fb_oclass;
#include <subdev/bios/ramcfg.h>
struct nouveau_ram_data {
struct nvbios_ramcfg bios;
};
struct nouveau_ram { struct nouveau_ram {
struct nouveau_object base; struct nouveau_object base;
enum { enum {
...@@ -143,6 +149,9 @@ struct nouveau_ram { ...@@ -143,6 +149,9 @@ struct nouveau_ram {
u32 freq; u32 freq;
u32 mr[16]; u32 mr[16];
u32 mr1_nuts; u32 mr1_nuts;
struct nouveau_ram_data *next;
struct nouveau_ram_data target;
}; };
#endif #endif
...@@ -24,10 +24,11 @@ ...@@ -24,10 +24,11 @@
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/bit.h> #include <subdev/bios/bit.h>
#include <subdev/bios/ramcfg.h>
#include <subdev/bios/rammap.h> #include <subdev/bios/rammap.h>
u16 u32
nvbios_rammap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, nvbios_rammapTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len, u8 *snr, u8 *ssz) u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{ {
struct bit_entry bit_P; struct bit_entry bit_P;
...@@ -57,12 +58,12 @@ nvbios_rammap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, ...@@ -57,12 +58,12 @@ nvbios_rammap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
return 0x0000; return 0x0000;
} }
u16 u32
nvbios_rammap_entry(struct nouveau_bios *bios, int idx, nvbios_rammapEe(struct nouveau_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len) u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{ {
u8 snr, ssz; u8 snr, ssz;
u16 rammap = nvbios_rammap_table(bios, ver, hdr, cnt, len, &snr, &ssz); u16 rammap = nvbios_rammapTe(bios, ver, hdr, cnt, len, &snr, &ssz);
if (rammap && idx < *cnt) { if (rammap && idx < *cnt) {
rammap = rammap + *hdr + (idx * (*len + (snr * ssz))); rammap = rammap + *hdr + (idx * (*len + (snr * ssz)));
*hdr = *len; *hdr = *len;
...@@ -73,16 +74,99 @@ nvbios_rammap_entry(struct nouveau_bios *bios, int idx, ...@@ -73,16 +74,99 @@ nvbios_rammap_entry(struct nouveau_bios *bios, int idx,
return 0x0000; return 0x0000;
} }
u16 u32
nvbios_rammap_match(struct nouveau_bios *bios, u16 khz, nvbios_rammapEm(struct nouveau_bios *bios, u16 khz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len) u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{ {
int idx = 0; int idx = 0;
u32 data; u32 data;
while ((data = nvbios_rammap_entry(bios, idx++, ver, hdr, cnt, len))) { while ((data = nvbios_rammapEe(bios, idx++, ver, hdr, cnt, len))) {
if (khz >= nv_ro16(bios, data + 0x00) && if (khz >= nv_ro16(bios, data + 0x00) &&
khz <= nv_ro16(bios, data + 0x02)) khz <= nv_ro16(bios, data + 0x02))
break; break;
} }
return data; return data;
} }
u32
nvbios_rammapEp(struct nouveau_bios *bios, u16 khz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_ramcfg *p)
{
u32 data = nvbios_rammapEm(bios, khz, ver, hdr, cnt, len);
memset(p, 0x00, sizeof(*p));
switch (!!data * *ver) {
case 0x11:
p->rammap_11_08_01 = (nv_ro08(bios, data + 0x08) & 0x01) >> 0;
p->rammap_11_08_0c = (nv_ro08(bios, data + 0x08) & 0x0c) >> 2;
p->rammap_11_08_10 = (nv_ro08(bios, data + 0x08) & 0x10) >> 4;
p->rammap_11_11_0c = (nv_ro08(bios, data + 0x11) & 0x0c) >> 2;
break;
default:
data = 0;
break;
}
return data;
}
u32
nvbios_rammapSe(struct nouveau_bios *bios, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr)
{
if (idx < ecnt) {
data = data + ehdr + (idx * elen);
*ver = ever;
*hdr = elen;
return data;
}
return 0;
}
u32
nvbios_rammapSp(struct nouveau_bios *bios, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
{
data = nvbios_rammapSe(bios, data, ever, ehdr, ecnt, elen, idx, ver, hdr);
switch (!!data * *ver) {
case 0x11:
p->ramcfg_11_01_01 = (nv_ro08(bios, data + 0x01) & 0x01) >> 0;
p->ramcfg_11_01_02 = (nv_ro08(bios, data + 0x01) & 0x02) >> 1;
p->ramcfg_11_01_04 = (nv_ro08(bios, data + 0x01) & 0x04) >> 2;
p->ramcfg_11_01_08 = (nv_ro08(bios, data + 0x01) & 0x08) >> 3;
p->ramcfg_11_01_10 = (nv_ro08(bios, data + 0x01) & 0x10) >> 4;
p->ramcfg_11_01_20 = (nv_ro08(bios, data + 0x01) & 0x20) >> 5;
p->ramcfg_11_01_40 = (nv_ro08(bios, data + 0x01) & 0x40) >> 6;
p->ramcfg_11_01_80 = (nv_ro08(bios, data + 0x01) & 0x80) >> 7;
p->ramcfg_11_02_03 = (nv_ro08(bios, data + 0x02) & 0x03) >> 0;
p->ramcfg_11_02_04 = (nv_ro08(bios, data + 0x02) & 0x04) >> 2;
p->ramcfg_11_02_08 = (nv_ro08(bios, data + 0x02) & 0x08) >> 3;
p->ramcfg_11_02_10 = (nv_ro08(bios, data + 0x02) & 0x10) >> 4;
p->ramcfg_11_02_40 = (nv_ro08(bios, data + 0x02) & 0x40) >> 6;
p->ramcfg_11_02_80 = (nv_ro08(bios, data + 0x02) & 0x80) >> 7;
p->ramcfg_11_03_0f = (nv_ro08(bios, data + 0x03) & 0x0f) >> 0;
p->ramcfg_11_03_30 = (nv_ro08(bios, data + 0x03) & 0x30) >> 4;
p->ramcfg_11_03_c0 = (nv_ro08(bios, data + 0x03) & 0xc0) >> 6;
p->ramcfg_11_03_f0 = (nv_ro08(bios, data + 0x03) & 0xf0) >> 4;
p->ramcfg_11_04 = (nv_ro08(bios, data + 0x04) & 0xff) >> 0;
p->ramcfg_11_06 = (nv_ro08(bios, data + 0x06) & 0xff) >> 0;
p->ramcfg_11_07_02 = (nv_ro08(bios, data + 0x07) & 0x02) >> 1;
p->ramcfg_11_07_04 = (nv_ro08(bios, data + 0x07) & 0x04) >> 2;
p->ramcfg_11_07_08 = (nv_ro08(bios, data + 0x07) & 0x08) >> 3;
p->ramcfg_11_07_10 = (nv_ro08(bios, data + 0x07) & 0x10) >> 4;
p->ramcfg_11_07_40 = (nv_ro08(bios, data + 0x07) & 0x40) >> 6;
p->ramcfg_11_07_80 = (nv_ro08(bios, data + 0x07) & 0x80) >> 7;
p->ramcfg_11_08_01 = (nv_ro08(bios, data + 0x08) & 0x01) >> 0;
p->ramcfg_11_08_02 = (nv_ro08(bios, data + 0x08) & 0x02) >> 1;
p->ramcfg_11_08_04 = (nv_ro08(bios, data + 0x08) & 0x04) >> 2;
p->ramcfg_11_08_08 = (nv_ro08(bios, data + 0x08) & 0x08) >> 3;
p->ramcfg_11_08_10 = (nv_ro08(bios, data + 0x08) & 0x10) >> 4;
p->ramcfg_11_09 = (nv_ro08(bios, data + 0x09) & 0xff) >> 0;
break;
default:
data = 0;
break;
}
return data;
}
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/bit.h> #include <subdev/bios/bit.h>
#include <subdev/bios/ramcfg.h>
#include <subdev/bios/timing.h> #include <subdev/bios/timing.h>
u16 u16
...@@ -81,3 +82,46 @@ nvbios_timingEe(struct nouveau_bios *bios, int idx, ...@@ -81,3 +82,46 @@ nvbios_timingEe(struct nouveau_bios *bios, int idx,
} }
return 0x0000; return 0x0000;
} }
u16
nvbios_timingEp(struct nouveau_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_ramcfg *p)
{
u16 data = nvbios_timingEe(bios, idx, ver, hdr, cnt, len), temp;
switch (!!data * *ver) {
case 0x20:
p->timing[0] = nv_ro32(bios, data + 0x00);
p->timing[1] = nv_ro32(bios, data + 0x04);
p->timing[2] = nv_ro32(bios, data + 0x08);
p->timing[3] = nv_ro32(bios, data + 0x0c);
p->timing[4] = nv_ro32(bios, data + 0x10);
p->timing[5] = nv_ro32(bios, data + 0x14);
p->timing[6] = nv_ro32(bios, data + 0x18);
p->timing[7] = nv_ro32(bios, data + 0x1c);
p->timing[8] = nv_ro32(bios, data + 0x20);
p->timing[9] = nv_ro32(bios, data + 0x24);
p->timing[10] = nv_ro32(bios, data + 0x28);
p->timing_20_2e_03 = (nv_ro08(bios, data + 0x2e) & 0x03) >> 0;
p->timing_20_2e_30 = (nv_ro08(bios, data + 0x2e) & 0x30) >> 4;
p->timing_20_2e_c0 = (nv_ro08(bios, data + 0x2e) & 0xc0) >> 6;
p->timing_20_2f_03 = (nv_ro08(bios, data + 0x2f) & 0x03) >> 0;
temp = nv_ro16(bios, data + 0x2c);
p->timing_20_2c_003f = (temp & 0x003f) >> 0;
p->timing_20_2c_1fc0 = (temp & 0x1fc0) >> 6;
p->timing_20_30_07 = (nv_ro08(bios, data + 0x30) & 0x07) >> 0;
p->timing_20_30_f8 = (nv_ro08(bios, data + 0x30) & 0xf8) >> 3;
temp = nv_ro16(bios, data + 0x31);
p->timing_20_31_0007 = (temp & 0x0007) >> 0;
p->timing_20_31_0078 = (temp & 0x0078) >> 3;
p->timing_20_31_0780 = (temp & 0x0780) >> 7;
p->timing_20_31_0800 = (temp & 0x0800) >> 11;
p->timing_20_31_7000 = (temp & 0x7000) >> 12;
p->timing_20_31_8000 = (temp & 0x8000) >> 15;
break;
default:
data = 0;
break;
}
return data;
}
...@@ -28,34 +28,33 @@ ...@@ -28,34 +28,33 @@
int int
nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts) nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts)
{ {
struct nouveau_bios *bios = nouveau_bios(ram);
int pd, lf, xd, vh, vr, vo, l3; int pd, lf, xd, vh, vr, vo, l3;
int WL, CL, WR, at[2], dt, ds; int WL, CL, WR, at[2], dt, ds;
int rq = ram->freq < 1000000; /* XXX */ int rq = ram->freq < 1000000; /* XXX */
switch (!!ram->ramcfg.data * ram->ramcfg.version) { switch (ram->ramcfg.version) {
case 0x11: case 0x11:
pd = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x80) >> 7; pd = ram->next->bios.ramcfg_11_01_80;
lf = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x40) >> 6; lf = ram->next->bios.ramcfg_11_01_40;
xd = !(nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x20); xd = !ram->next->bios.ramcfg_11_01_20;
vh = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x10) >> 4; vh = ram->next->bios.ramcfg_11_02_10;
vr = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x04) >> 2; vr = ram->next->bios.ramcfg_11_02_04;
vo = nv_ro08(bios, ram->ramcfg.data + 0x06) & 0xff; vo = ram->next->bios.ramcfg_11_06;
l3 = !(nv_ro08(bios, ram->ramcfg.data + 0x07) & 0x02); l3 = !ram->next->bios.ramcfg_11_07_02;
break; break;
default: default:
return -ENOSYS; return -ENOSYS;
} }
switch (!!ram->timing.data * ram->timing.version) { switch (ram->timing.version) {
case 0x20: case 0x20:
WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7; WL = (ram->next->bios.timing[1] & 0x00000f80) >> 7;
CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f; CL = (ram->next->bios.timing[1] & 0x0000001f);
WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f; WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16;
at[0] = (nv_ro08(bios, ram->timing.data + 0x2e) & 0xc0) >> 6; at[0] = ram->next->bios.timing_20_2e_c0;
at[1] = (nv_ro08(bios, ram->timing.data + 0x2e) & 0x30) >> 4; at[1] = ram->next->bios.timing_20_2e_30;
dt = nv_ro08(bios, ram->timing.data + 0x2e) & 0x03; dt = ram->next->bios.timing_20_2e_03;
ds = nv_ro08(bios, ram->timing.data + 0x2f) & 0x03; ds = ram->next->bios.timing_20_2f_03;
break; break;
default: default:
return -ENOSYS; return -ENOSYS;
......
...@@ -90,7 +90,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -90,7 +90,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
int ret; int ret;
/* lookup memory config data relevant to the target frequency */ /* lookup memory config data relevant to the target frequency */
rammap.data = nvbios_rammap_match(bios, freq / 1000, &ver, &rammap.size, rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
&cnt, &ramcfg.size); &cnt, &ramcfg.size);
if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) { if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
nv_error(pfb, "invalid/missing rammap entry\n"); nv_error(pfb, "invalid/missing rammap entry\n");
......
...@@ -144,7 +144,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -144,7 +144,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
int ret; int ret;
/* lookup memory config data relevant to the target frequency */ /* lookup memory config data relevant to the target frequency */
rammap.data = nvbios_rammap_match(bios, freq / 1000, &ver, &rammap.size, rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
&cnt, &ramcfg.size); &cnt, &ramcfg.size);
if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) { if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
nv_error(pfb, "invalid/missing rammap entry\n"); nv_error(pfb, "invalid/missing rammap entry\n");
......
...@@ -213,12 +213,12 @@ r1373f4_init(struct nve0_ramfuc *fuc) ...@@ -213,12 +213,12 @@ r1373f4_init(struct nve0_ramfuc *fuc)
} }
static void static void
r1373f4_fini(struct nve0_ramfuc *fuc, u32 ramcfg) r1373f4_fini(struct nve0_ramfuc *fuc)
{ {
struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc); struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
struct nouveau_bios *bios = nouveau_bios(ram); struct nouveau_ram_data *next = ram->base.next;
u8 v0 = (nv_ro08(bios, ramcfg + 0x03) & 0xc0) >> 6; u8 v0 = next->bios.ramcfg_11_03_c0;
u8 v1 = (nv_ro08(bios, ramcfg + 0x03) & 0x30) >> 4; u8 v1 = next->bios.ramcfg_11_03_30;
u32 tmp; u32 tmp;
tmp = ram_rd32(fuc, 0x1373ec) & ~0x00030000; tmp = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
...@@ -259,15 +259,12 @@ nve0_ram_nuts(struct nve0_ram *ram, struct ramfuc_reg *reg, ...@@ -259,15 +259,12 @@ nve0_ram_nuts(struct nve0_ram *ram, struct ramfuc_reg *reg,
static int static int
nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
{ {
struct nouveau_bios *bios = nouveau_bios(pfb);
struct nve0_ram *ram = (void *)pfb->ram; struct nve0_ram *ram = (void *)pfb->ram;
struct nve0_ramfuc *fuc = &ram->fuc; struct nve0_ramfuc *fuc = &ram->fuc;
const u32 rammap = ram->base.rammap.data; struct nouveau_ram_data *next = ram->base.next;
const u32 ramcfg = ram->base.ramcfg.data; int vc = !(next->bios.ramcfg_11_02_08);
const u32 timing = ram->base.timing.data; int mv = 1; /*XXX: !(next->bios.ramcfg_11_02_04); */
int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08); u32 mask, data;
int mv = 1; /*XXX: !(nv_ro08(bios, ramcfg + 0x02) & 0x04); */
u32 mask, data, i;
ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000); ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
ram_wr32(fuc, 0x62c000, 0x0f0f0000); ram_wr32(fuc, 0x62c000, 0x0f0f0000);
...@@ -317,28 +314,28 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -317,28 +314,28 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
if (1) { if (1) {
data |= 0x800807e0; data |= 0x800807e0;
switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) { switch (next->bios.ramcfg_11_03_c0) {
case 0xc0: data &= ~0x00000040; break; case 3: data &= ~0x00000040; break;
case 0x80: data &= ~0x00000100; break; case 2: data &= ~0x00000100; break;
case 0x40: data &= ~0x80000000; break; case 1: data &= ~0x80000000; break;
case 0x00: data &= ~0x00000400; break; case 0: data &= ~0x00000400; break;
} }
switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) { switch (next->bios.ramcfg_11_03_30) {
case 0x30: data &= ~0x00000020; break; case 3: data &= ~0x00000020; break;
case 0x20: data &= ~0x00000080; break; case 2: data &= ~0x00000080; break;
case 0x10: data &= ~0x00080000; break; case 1: data &= ~0x00080000; break;
case 0x00: data &= ~0x00000200; break; case 0: data &= ~0x00000200; break;
} }
} }
if (nv_ro08(bios, ramcfg + 0x02) & 0x80) if (next->bios.ramcfg_11_02_80)
mask |= 0x03000000; mask |= 0x03000000;
if (nv_ro08(bios, ramcfg + 0x02) & 0x40) if (next->bios.ramcfg_11_02_40)
mask |= 0x00002000; mask |= 0x00002000;
if (nv_ro08(bios, ramcfg + 0x07) & 0x10) if (next->bios.ramcfg_11_07_10)
mask |= 0x00004000; mask |= 0x00004000;
if (nv_ro08(bios, ramcfg + 0x07) & 0x08) if (next->bios.ramcfg_11_07_08)
mask |= 0x00000003; mask |= 0x00000003;
else { else {
mask |= 0x34000000; mask |= 0x34000000;
...@@ -357,12 +354,12 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -357,12 +354,12 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000); ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
r1373f4_init(fuc); r1373f4_init(fuc);
ram_mask(fuc, 0x1373f0, 0x00000002, 0x00000001); ram_mask(fuc, 0x1373f0, 0x00000002, 0x00000001);
r1373f4_fini(fuc, ramcfg); r1373f4_fini(fuc);
ram_mask(fuc, 0x10f830, 0x00c00000, 0x00240001); ram_mask(fuc, 0x10f830, 0x00c00000, 0x00240001);
} else } else
if (ram->from != 2 && ram->mode != 2) { if (ram->from != 2 && ram->mode != 2) {
r1373f4_init(fuc); r1373f4_init(fuc);
r1373f4_fini(fuc, ramcfg); r1373f4_fini(fuc);
} }
if (ram_have(fuc, gpioMV)) { if (ram_have(fuc, gpioMV)) {
...@@ -373,8 +370,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -373,8 +370,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
} }
} }
if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) || if ( (next->bios.ramcfg_11_02_40) ||
(nv_ro08(bios, ramcfg + 0x07) & 0x10)) { (next->bios.ramcfg_11_07_10)) {
ram_mask(fuc, 0x132040, 0x00010000, 0x00010000); ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
ram_nsec(fuc, 20000); ram_nsec(fuc, 20000);
} }
...@@ -384,38 +381,37 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -384,38 +381,37 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x1373f0, 0x00000000, 0x00000002); ram_mask(fuc, 0x1373f0, 0x00000000, 0x00000002);
ram_mask(fuc, 0x10f830, 0x00800001, 0x00408010); ram_mask(fuc, 0x10f830, 0x00800001, 0x00408010);
r1373f4_init(fuc); r1373f4_init(fuc);
r1373f4_fini(fuc, ramcfg); r1373f4_fini(fuc);
ram_mask(fuc, 0x10f808, 0x00000000, 0x00080000); ram_mask(fuc, 0x10f808, 0x00000000, 0x00080000);
ram_mask(fuc, 0x10f200, 0x00808000, 0x00800000); ram_mask(fuc, 0x10f200, 0x00808000, 0x00800000);
} else } else
if (ram->from == 2 && ram->mode == 2) { if (ram->from == 2 && ram->mode == 2) {
ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000); ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000);
r1373f4_init(fuc); r1373f4_init(fuc);
r1373f4_fini(fuc, ramcfg); r1373f4_fini(fuc);
} }
if (ram->mode != 2) /*XXX*/ { if (ram->mode != 2) /*XXX*/ {
if (nv_ro08(bios, ramcfg + 0x07) & 0x40) if (next->bios.ramcfg_11_07_40)
ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000); ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
} }
data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2; ram_wr32(fuc, 0x10f65c, 0x00000011 * next->bios.rammap_11_11_0c);
ram_wr32(fuc, 0x10f65c, 0x00000011 * data); ram_wr32(fuc, 0x10f6b8, 0x01010101 * next->bios.ramcfg_11_09);
ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09)); ram_wr32(fuc, 0x10f6bc, 0x01010101 * next->bios.ramcfg_11_09);
ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
data = nv_ro08(bios, ramcfg + 0x04); if (!next->bios.ramcfg_11_07_08) {
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) { ram_wr32(fuc, 0x10f698, 0x01010101 * next->bios.ramcfg_11_04);
ram_wr32(fuc, 0x10f698, 0x01010101 * data); ram_wr32(fuc, 0x10f69c, 0x01010101 * next->bios.ramcfg_11_04);
ram_wr32(fuc, 0x10f69c, 0x01010101 * data);
} }
if (ram->mode != 2) { if (ram->mode != 2) {
u32 temp = ram_rd32(fuc, 0x10f694) & ~0xff00ff00; u32 data = 0x01000100 * next->bios.ramcfg_11_04;
ram_wr32(fuc, 0x10f694, temp | (0x01000100 * data)); ram_nuke(fuc, 0x10f694);
ram_mask(fuc, 0x10f694, 0xff00ff00, data);
} }
if (ram->mode == 2 && (nv_ro08(bios, ramcfg + 0x08) & 0x10)) if (ram->mode == 2 && (next->bios.ramcfg_11_08_10))
data = 0x00000080; data = 0x00000080;
else else
data = 0x00000000; data = 0x00000000;
...@@ -423,19 +419,19 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -423,19 +419,19 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
mask = 0x00070000; mask = 0x00070000;
data = 0x00000000; data = 0x00000000;
if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80)) if (!(next->bios.ramcfg_11_02_80))
data |= 0x03000000; data |= 0x03000000;
if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40)) if (!(next->bios.ramcfg_11_02_40))
data |= 0x00002000; data |= 0x00002000;
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10)) if (!(next->bios.ramcfg_11_07_10))
data |= 0x00004000; data |= 0x00004000;
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) if (!(next->bios.ramcfg_11_07_08))
data |= 0x00000003; data |= 0x00000003;
else else
data |= 0x74000000; data |= 0x74000000;
ram_mask(fuc, 0x10f824, mask, data); ram_mask(fuc, 0x10f824, mask, data);
if (nv_ro08(bios, ramcfg + 0x01) & 0x08) if (next->bios.ramcfg_11_01_08)
data = 0x00000000; data = 0x00000000;
else else
data = 0x00001000; data = 0x00001000;
...@@ -446,41 +442,41 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -446,41 +442,41 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x10f670, 0x80000000, 0x00000000); ram_mask(fuc, 0x10f670, 0x80000000, 0x00000000);
} }
if (nv_ro08(bios, ramcfg + 0x08) & 0x01) if (next->bios.ramcfg_11_08_01)
data = 0x00100000; data = 0x00100000;
else else
data = 0x00000000; data = 0x00000000;
ram_mask(fuc, 0x10f82c, 0x00100000, data); ram_mask(fuc, 0x10f82c, 0x00100000, data);
data = 0x00000000; data = 0x00000000;
if (nv_ro08(bios, ramcfg + 0x08) & 0x08) if (next->bios.ramcfg_11_08_08)
data |= 0x00002000; data |= 0x00002000;
if (nv_ro08(bios, ramcfg + 0x08) & 0x04) if (next->bios.ramcfg_11_08_04)
data |= 0x00001000; data |= 0x00001000;
if (nv_ro08(bios, ramcfg + 0x08) & 0x02) if (next->bios.ramcfg_11_08_02)
data |= 0x00004000; data |= 0x00004000;
ram_mask(fuc, 0x10f830, 0x00007000, data); ram_mask(fuc, 0x10f830, 0x00007000, data);
/* PFB timing */ /* PFB timing */
ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28)); ram_mask(fuc, 0x10f248, 0xffffffff, next->bios.timing[10]);
ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00)); ram_mask(fuc, 0x10f290, 0xffffffff, next->bios.timing[0]);
ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04)); ram_mask(fuc, 0x10f294, 0xffffffff, next->bios.timing[1]);
ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08)); ram_mask(fuc, 0x10f298, 0xffffffff, next->bios.timing[2]);
ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c)); ram_mask(fuc, 0x10f29c, 0xffffffff, next->bios.timing[3]);
ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10)); ram_mask(fuc, 0x10f2a0, 0xffffffff, next->bios.timing[4]);
ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14)); ram_mask(fuc, 0x10f2a4, 0xffffffff, next->bios.timing[5]);
ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18)); ram_mask(fuc, 0x10f2a8, 0xffffffff, next->bios.timing[6]);
ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c)); ram_mask(fuc, 0x10f2ac, 0xffffffff, next->bios.timing[7]);
ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20)); ram_mask(fuc, 0x10f2cc, 0xffffffff, next->bios.timing[8]);
ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24)); ram_mask(fuc, 0x10f2e8, 0xffffffff, next->bios.timing[9]);
data = mask = 0x00000000; data = mask = 0x00000000;
if (NOTE00(ramcfg_02_03 != 0)) { if (NOTE00(ramcfg_02_03 != 0)) {
data |= (nv_ro08(bios, ramcfg + 0x02) & 0x03) << 8; data |= (next->bios.ramcfg_11_02_03) << 8;
mask |= 0x00000300; mask |= 0x00000300;
} }
if (NOTE00(ramcfg_01_10)) { if (NOTE00(ramcfg_01_10)) {
if (nv_ro08(bios, ramcfg + 0x01) & 0x10) if (next->bios.ramcfg_11_01_10)
data |= 0x70000000; data |= 0x70000000;
mask |= 0x70000000; mask |= 0x70000000;
} }
...@@ -488,11 +484,11 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -488,11 +484,11 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
data = mask = 0x00000000; data = mask = 0x00000000;
if (NOTE00(timing_30_07 != 0)) { if (NOTE00(timing_30_07 != 0)) {
data |= (nv_ro08(bios, timing + 0x30) & 0x07) << 28; data |= (next->bios.timing_20_30_07) << 28;
mask |= 0x70000000; mask |= 0x70000000;
} }
if (NOTE00(ramcfg_01_01)) { if (NOTE00(ramcfg_01_01)) {
if (nv_ro08(bios, ramcfg + 0x01) & 0x01) if (next->bios.ramcfg_11_01_01)
data |= 0x00000100; data |= 0x00000100;
mask |= 0x00000100; mask |= 0x00000100;
} }
...@@ -500,11 +496,11 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -500,11 +496,11 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
data = mask = 0x00000000; data = mask = 0x00000000;
if (NOTE00(timing_30_07 != 0)) { if (NOTE00(timing_30_07 != 0)) {
data |= (nv_ro08(bios, timing + 0x30) & 0x07) << 28; data |= (next->bios.timing_20_30_07) << 28;
mask |= 0x70000000; mask |= 0x70000000;
} }
if (NOTE00(ramcfg_01_02)) { if (NOTE00(ramcfg_01_02)) {
if (nv_ro08(bios, ramcfg + 0x01) & 0x02) if (next->bios.ramcfg_11_01_02)
data |= 0x00000100; data |= 0x00000100;
mask |= 0x00000100; mask |= 0x00000100;
} }
...@@ -512,16 +508,16 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -512,16 +508,16 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
mask = 0x33f00000; mask = 0x33f00000;
data = 0x00000000; data = 0x00000000;
if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04)) if (!(next->bios.ramcfg_11_01_04))
data |= 0x20200000; data |= 0x20200000;
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80)) if (!(next->bios.ramcfg_11_07_80))
data |= 0x12800000; data |= 0x12800000;
/*XXX: see note above about there probably being some condition /*XXX: see note above about there probably being some condition
* for the 10f824 stuff that uses ramcfg 3... * for the 10f824 stuff that uses ramcfg 3...
*/ */
if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) { if ( (next->bios.ramcfg_11_03_f0)) {
if (nv_ro08(bios, rammap + 0x08) & 0x0c) { if (next->bios.rammap_11_08_0c) {
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80)) if (!(next->bios.ramcfg_11_07_80))
mask |= 0x00000020; mask |= 0x00000020;
else else
data |= 0x00000020; data |= 0x00000020;
...@@ -534,16 +530,15 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -534,16 +530,15 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x10f808, mask, data); ram_mask(fuc, 0x10f808, mask, data);
data = nv_ro08(bios, ramcfg + 0x03) & 0x0f; ram_wr32(fuc, 0x10f870, 0x11111111 * next->bios.ramcfg_11_03_0f);
ram_wr32(fuc, 0x10f870, 0x11111111 * data);
data = mask = 0x00000000; data = mask = 0x00000000;
if (NOTE00(ramcfg_02_03 != 0)) { if (NOTE00(ramcfg_02_03 != 0)) {
data |= nv_ro08(bios, ramcfg + 0x02) & 0x03; data |= next->bios.ramcfg_11_02_03;
mask |= 0x00000003; mask |= 0x00000003;
} }
if (NOTE00(ramcfg_01_10)) { if (NOTE00(ramcfg_01_10)) {
if (nv_ro08(bios, ramcfg + 0x01) & 0x10) if (next->bios.ramcfg_11_01_10)
data |= 0x00000004; data |= 0x00000004;
mask |= 0x00000004; mask |= 0x00000004;
} }
...@@ -554,25 +549,21 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -554,25 +549,21 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000); ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000);
} }
data = (nv_ro08(bios, timing + 0x30) & 0x07) << 8; data = (next->bios.timing_20_30_07) << 8;
if (nv_ro08(bios, ramcfg + 0x01) & 0x01) if (next->bios.ramcfg_11_01_01)
data |= 0x80000000; data |= 0x80000000;
ram_mask(fuc, 0x100778, 0x00000700, data); ram_mask(fuc, 0x100778, 0x00000700, data);
data = nv_ro16(bios, timing + 0x2c); ram_mask(fuc, 0x10f250, 0x000003f0, next->bios.timing_20_2c_003f << 4);
ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) << 4); ram_mask(fuc, 0x10f24c, 0x7f000000, next->bios.timing_20_2c_1fc0 << 24);
ram_mask(fuc, 0x10f24c, 0x7f000000, (data & 0x1fc0) << 18); ram_mask(fuc, 0x10f224, 0x001f0000, next->bios.timing_20_30_f8 << 16);
data = nv_ro08(bios, timing + 0x30);
ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13);
data = nv_ro16(bios, timing + 0x31); ram_mask(fuc, 0x10fec4, 0x041e0f07, next->bios.timing_20_31_0800 << 26 |
ram_mask(fuc, 0x10fec4, 0x041e0f07, (data & 0x0800) << 15 | next->bios.timing_20_31_0780 << 17 |
(data & 0x0780) << 10 | next->bios.timing_20_31_0078 << 8 |
(data & 0x0078) << 5 | next->bios.timing_20_31_0007);
(data & 0x0007)); ram_mask(fuc, 0x10fec8, 0x00000027, next->bios.timing_20_31_8000 << 5 |
ram_mask(fuc, 0x10fec8, 0x00000027, (data & 0x8000) >> 10 | next->bios.timing_20_31_7000);
(data & 0x7000) >> 12);
ram_wr32(fuc, 0x10f090, 0x4000007e); ram_wr32(fuc, 0x10f090, 0x4000007e);
ram_nsec(fuc, 2000); ram_nsec(fuc, 2000);
...@@ -580,7 +571,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -580,7 +571,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */ ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
if ((nv_ro08(bios, ramcfg + 0x08) & 0x10) && (ram->mode == 2) /*XXX*/) { if ((next->bios.ramcfg_11_08_10) && (ram->mode == 2) /*XXX*/) {
u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000); u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000);
nve0_ram_train(fuc, 0xbc0e0000, 0xa4010000); /*XXX*/ nve0_ram_train(fuc, 0xbc0e0000, 0xa4010000); /*XXX*/
ram_nsec(fuc, 1000); ram_nsec(fuc, 1000);
...@@ -613,8 +604,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -613,8 +604,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
data = ram_rd32(fuc, 0x10f978); data = ram_rd32(fuc, 0x10f978);
data &= ~0x00046144; data &= ~0x00046144;
data |= 0x0000000b; data |= 0x0000000b;
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) { if (!(next->bios.ramcfg_11_07_08)) {
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x04)) if (!(next->bios.ramcfg_11_07_04))
data |= 0x0000200c; data |= 0x0000200c;
else else
data |= 0x00000000; data |= 0x00000000;
...@@ -628,11 +619,11 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -628,11 +619,11 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_wr32(fuc, 0x10f830, data); ram_wr32(fuc, 0x10f830, data);
} }
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) { if (!(next->bios.ramcfg_11_07_08)) {
data = 0x88020000; data = 0x88020000;
if ( (nv_ro08(bios, ramcfg + 0x07) & 0x04)) if ( (next->bios.ramcfg_11_07_04))
data |= 0x10000000; data |= 0x10000000;
if (!(nv_ro08(bios, rammap + 0x08) & 0x10)) if (!(next->bios.rammap_11_08_10))
data |= 0x00080000; data |= 0x00080000;
} else { } else {
data = 0xa40e0000; data = 0xa40e0000;
...@@ -654,12 +645,12 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -654,12 +645,12 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000); ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
} }
if (nv_ro08(bios, ramcfg + 0x07) & 0x02) if (next->bios.ramcfg_11_07_02)
nve0_ram_train(fuc, 0x80020000, 0x01000000); nve0_ram_train(fuc, 0x80020000, 0x01000000);
ram_wr32(fuc, 0x62c000, 0x0f0f0f00); ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
if (nv_ro08(bios, rammap + 0x08) & 0x01) if (next->bios.rammap_11_08_01)
data = 0x00000800; data = 0x00000800;
else else
data = 0x00000000; data = 0x00000000;
...@@ -675,17 +666,14 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ...@@ -675,17 +666,14 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
static int static int
nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
{ {
struct nouveau_bios *bios = nouveau_bios(pfb);
struct nve0_ram *ram = (void *)pfb->ram; struct nve0_ram *ram = (void *)pfb->ram;
struct nve0_ramfuc *fuc = &ram->fuc; struct nve0_ramfuc *fuc = &ram->fuc;
const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1); const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
const u32 runk0 = ram->fN1 << 16; const u32 runk0 = ram->fN1 << 16;
const u32 runk1 = ram->fN1; const u32 runk1 = ram->fN1;
const u32 rammap = ram->base.rammap.data; struct nouveau_ram_data *next = ram->base.next;
const u32 ramcfg = ram->base.ramcfg.data; int vc = !(next->bios.ramcfg_11_02_08);
const u32 timing = ram->base.timing.data; int mv = 1; /*XXX: !(next->bios.ramcfg_11_02_04); */
int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08);
int mv = 1; /*XXX: !(nv_ro08(bios, ramcfg + 0x02) & 0x04); */
u32 mask, data; u32 mask, data;
ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000); ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000);
...@@ -700,7 +688,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) ...@@ -700,7 +688,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
} }
ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000); ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
if ((nv_ro08(bios, ramcfg + 0x03) & 0xf0)) if ((next->bios.ramcfg_11_03_f0))
ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000); ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */ ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
...@@ -725,28 +713,28 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) ...@@ -725,28 +713,28 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
if (1) { if (1) {
mask |= 0x800807e0; mask |= 0x800807e0;
data |= 0x800807e0; data |= 0x800807e0;
switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) { switch (next->bios.ramcfg_11_03_c0) {
case 0xc0: data &= ~0x00000040; break; case 3: data &= ~0x00000040; break;
case 0x80: data &= ~0x00000100; break; case 2: data &= ~0x00000100; break;
case 0x40: data &= ~0x80000000; break; case 1: data &= ~0x80000000; break;
case 0x00: data &= ~0x00000400; break; case 0: data &= ~0x00000400; break;
} }
switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) { switch (next->bios.ramcfg_11_03_30) {
case 0x30: data &= ~0x00000020; break; case 3: data &= ~0x00000020; break;
case 0x20: data &= ~0x00000080; break; case 2: data &= ~0x00000080; break;
case 0x10: data &= ~0x00080000; break; case 1: data &= ~0x00080000; break;
case 0x00: data &= ~0x00000200; break; case 0: data &= ~0x00000200; break;
} }
} }
if (nv_ro08(bios, ramcfg + 0x02) & 0x80) if (next->bios.ramcfg_11_02_80)
mask |= 0x03000000; mask |= 0x03000000;
if (nv_ro08(bios, ramcfg + 0x02) & 0x40) if (next->bios.ramcfg_11_02_40)
mask |= 0x00002000; mask |= 0x00002000;
if (nv_ro08(bios, ramcfg + 0x07) & 0x10) if (next->bios.ramcfg_11_07_10)
mask |= 0x00004000; mask |= 0x00004000;
if (nv_ro08(bios, ramcfg + 0x07) & 0x08) if (next->bios.ramcfg_11_07_08)
mask |= 0x00000003; mask |= 0x00000003;
else else
mask |= 0x14000000; mask |= 0x14000000;
...@@ -756,7 +744,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) ...@@ -756,7 +744,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010); ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010);
data = ram_rd32(fuc, 0x1373ec) & ~0x00030000; data = ram_rd32(fuc, 0x1373ec) & ~0x00030000;
data |= (nv_ro08(bios, ramcfg + 0x03) & 0x30) << 12; data |= (next->bios.ramcfg_11_03_30) << 12;
ram_wr32(fuc, 0x1373ec, data); ram_wr32(fuc, 0x1373ec, data);
ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000); ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000);
ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000); ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000);
...@@ -788,68 +776,67 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) ...@@ -788,68 +776,67 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
} }
} }
if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) || if ( (next->bios.ramcfg_11_02_40) ||
(nv_ro08(bios, ramcfg + 0x07) & 0x10)) { (next->bios.ramcfg_11_07_10)) {
ram_mask(fuc, 0x132040, 0x00010000, 0x00010000); ram_mask(fuc, 0x132040, 0x00010000, 0x00010000);
ram_nsec(fuc, 20000); ram_nsec(fuc, 20000);
} }
if (ram->mode != 2) /*XXX*/ { if (ram->mode != 2) /*XXX*/ {
if (nv_ro08(bios, ramcfg + 0x07) & 0x40) if (next->bios.ramcfg_11_07_40)
ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000); ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000);
} }
data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2; ram_wr32(fuc, 0x10f65c, 0x00000011 * next->bios.rammap_11_11_0c);
ram_wr32(fuc, 0x10f65c, 0x00000011 * data); ram_wr32(fuc, 0x10f6b8, 0x01010101 * next->bios.ramcfg_11_09);
ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09)); ram_wr32(fuc, 0x10f6bc, 0x01010101 * next->bios.ramcfg_11_09);
ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09));
mask = 0x00010000; mask = 0x00010000;
data = 0x00000000; data = 0x00000000;
if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80)) if (!(next->bios.ramcfg_11_02_80))
data |= 0x03000000; data |= 0x03000000;
if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40)) if (!(next->bios.ramcfg_11_02_40))
data |= 0x00002000; data |= 0x00002000;
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10)) if (!(next->bios.ramcfg_11_07_10))
data |= 0x00004000; data |= 0x00004000;
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) if (!(next->bios.ramcfg_11_07_08))
data |= 0x00000003; data |= 0x00000003;
else else
data |= 0x14000000; data |= 0x14000000;
ram_mask(fuc, 0x10f824, mask, data); ram_mask(fuc, 0x10f824, mask, data);
ram_nsec(fuc, 1000); ram_nsec(fuc, 1000);
if (nv_ro08(bios, ramcfg + 0x08) & 0x01) if (next->bios.ramcfg_11_08_01)
data = 0x00100000; data = 0x00100000;
else else
data = 0x00000000; data = 0x00000000;
ram_mask(fuc, 0x10f82c, 0x00100000, data); ram_mask(fuc, 0x10f82c, 0x00100000, data);
/* PFB timing */ /* PFB timing */
ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28)); ram_mask(fuc, 0x10f248, 0xffffffff, next->bios.timing[10]);
ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00)); ram_mask(fuc, 0x10f290, 0xffffffff, next->bios.timing[0]);
ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04)); ram_mask(fuc, 0x10f294, 0xffffffff, next->bios.timing[1]);
ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08)); ram_mask(fuc, 0x10f298, 0xffffffff, next->bios.timing[2]);
ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c)); ram_mask(fuc, 0x10f29c, 0xffffffff, next->bios.timing[3]);
ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10)); ram_mask(fuc, 0x10f2a0, 0xffffffff, next->bios.timing[4]);
ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14)); ram_mask(fuc, 0x10f2a4, 0xffffffff, next->bios.timing[5]);
ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18)); ram_mask(fuc, 0x10f2a8, 0xffffffff, next->bios.timing[6]);
ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c)); ram_mask(fuc, 0x10f2ac, 0xffffffff, next->bios.timing[7]);
ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20)); ram_mask(fuc, 0x10f2cc, 0xffffffff, next->bios.timing[8]);
ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24)); ram_mask(fuc, 0x10f2e8, 0xffffffff, next->bios.timing[9]);
mask = 0x33f00000; mask = 0x33f00000;
data = 0x00000000; data = 0x00000000;
if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04)) if (!(next->bios.ramcfg_11_01_04))
data |= 0x20200000; data |= 0x20200000;
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80)) if (!(next->bios.ramcfg_11_07_80))
data |= 0x12800000; data |= 0x12800000;
/*XXX: see note above about there probably being some condition /*XXX: see note above about there probably being some condition
* for the 10f824 stuff that uses ramcfg 3... * for the 10f824 stuff that uses ramcfg 3...
*/ */
if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) { if ( (next->bios.ramcfg_11_03_f0)) {
if (nv_ro08(bios, rammap + 0x08) & 0x0c) { if (next->bios.rammap_11_08_0c) {
if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80)) if (!(next->bios.ramcfg_11_07_80))
mask |= 0x00000020; mask |= 0x00000020;
else else
data |= 0x00000020; data |= 0x00000020;
...@@ -863,21 +850,16 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) ...@@ -863,21 +850,16 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x10f808, mask, data); ram_mask(fuc, 0x10f808, mask, data);
data = nv_ro08(bios, ramcfg + 0x03) & 0x0f; ram_wr32(fuc, 0x10f870, 0x11111111 * next->bios.ramcfg_11_03_0f);
ram_wr32(fuc, 0x10f870, 0x11111111 * data);
data = nv_ro16(bios, timing + 0x2c); ram_mask(fuc, 0x10f250, 0x000003f0, next->bios.timing_20_2c_003f << 4);
ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) << 4);
if (((nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >> 6) > data = (next->bios.timing[10] & 0x7f000000) >> 24;
((nv_ro32(bios, timing + 0x28) & 0x7f000000) >> 24)) if ( next->bios.timing_20_2c_1fc0 > data)
data = (nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >> 6; data = next->bios.timing_20_2c_1fc0;
else
data = (nv_ro32(bios, timing + 0x28) & 0x1f000000) >> 24;
ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24); ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24);
data = nv_ro08(bios, timing + 0x30); ram_mask(fuc, 0x10f224, 0x001f0000, next->bios.timing_20_30_f8);
ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13);
ram_wr32(fuc, 0x10f090, 0x4000007f); ram_wr32(fuc, 0x10f090, 0x4000007f);
ram_nsec(fuc, 1000); ram_nsec(fuc, 1000);
...@@ -919,7 +901,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) ...@@ -919,7 +901,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
ram_wr32(fuc, 0x62c000, 0x0f0f0f00); ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
if (nv_ro08(bios, rammap + 0x08) & 0x01) if (next->bios.rammap_11_08_01)
data = 0x00000800; data = 0x00000800;
else else
data = 0x00000000; data = 0x00000000;
...@@ -938,14 +920,14 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -938,14 +920,14 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
struct nve0_ram *ram = (void *)pfb->ram; struct nve0_ram *ram = (void *)pfb->ram;
struct nve0_ramfuc *fuc = &ram->fuc; struct nve0_ramfuc *fuc = &ram->fuc;
int ret, refclk, strap, i; int ret, refclk, strap, i;
u32 data;
u8 cnt, len; u8 cnt, len;
/* lookup memory config data relevant to the target frequency */ /* lookup memory config data relevant to the target frequency */
ram->base.rammap.data = nvbios_rammap_match(bios, freq / 1000, ram->base.rammap.data = nvbios_rammapEp(bios, freq / 1000,
&ram->base.rammap.version, &ram->base.rammap.version,
&ram->base.rammap.size, &cnt, &ram->base.rammap.size,
&ram->base.ramcfg.size); &cnt, &len,
&ram->base.target.bios);
if (!ram->base.rammap.data || ram->base.rammap.version != 0x11 || if (!ram->base.rammap.data || ram->base.rammap.version != 0x11 ||
ram->base.rammap.size < 0x09) { ram->base.rammap.size < 0x09) {
nv_error(pfb, "invalid/missing rammap entry\n"); nv_error(pfb, "invalid/missing rammap entry\n");
...@@ -953,15 +935,13 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -953,15 +935,13 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
} }
/* locate specific data set for the attached memory */ /* locate specific data set for the attached memory */
strap = nvbios_ramcfg_index(bios); ram->base.ramcfg.data = nvbios_rammapSp(bios, ram->base.rammap.data,
if (strap >= cnt) { ram->base.rammap.version,
nv_error(pfb, "invalid ramcfg strap\n"); ram->base.rammap.size, cnt, len,
return -EINVAL; nvbios_ramcfg_index(bios),
} &ram->base.ramcfg.version,
&ram->base.ramcfg.size,
ram->base.ramcfg.version = ram->base.rammap.version; &ram->base.target.bios);
ram->base.ramcfg.data = ram->base.rammap.data + ram->base.rammap.size +
(ram->base.ramcfg.size * strap);
if (!ram->base.ramcfg.data || ram->base.ramcfg.version != 0x11 || if (!ram->base.ramcfg.data || ram->base.ramcfg.version != 0x11 ||
ram->base.ramcfg.size < 0x08) { ram->base.ramcfg.size < 0x08) {
nv_error(pfb, "invalid/missing ramcfg entry\n"); nv_error(pfb, "invalid/missing ramcfg entry\n");
...@@ -972,8 +952,9 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -972,8 +952,9 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00); strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00);
if (strap != 0xff) { if (strap != 0xff) {
ram->base.timing.data = ram->base.timing.data =
nvbios_timingEe(bios, strap, &ram->base.timing.version, nvbios_timingEp(bios, strap, &ram->base.timing.version,
&ram->base.timing.size, &cnt, &len); &ram->base.timing.size, &cnt, &len,
&ram->base.target.bios);
if (!ram->base.timing.data || if (!ram->base.timing.data ||
ram->base.timing.version != 0x20 || ram->base.timing.version != 0x20 ||
ram->base.timing.size < 0x33) { ram->base.timing.size < 0x33) {
...@@ -984,6 +965,8 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -984,6 +965,8 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram->base.timing.data = 0; ram->base.timing.data = 0;
} }
ram->base.next = &ram->base.target;
ret = ram_init(fuc, pfb); ret = ram_init(fuc, pfb);
if (ret) if (ret)
return ret; return ret;
...@@ -1109,7 +1092,7 @@ nve0_ram_init(struct nouveau_object *object) ...@@ -1109,7 +1092,7 @@ nve0_ram_init(struct nouveau_object *object)
* binary driver skips the one that's already been setup by * binary driver skips the one that's already been setup by
* the init tables. * the init tables.
*/ */
data = nvbios_rammap_table(bios, &ver, &hdr, &cnt, &len, &snr, &ssz); data = nvbios_rammapTe(bios, &ver, &hdr, &cnt, &len, &snr, &ssz);
if (!data || hdr < 0x15) if (!data || hdr < 0x15)
return -EINVAL; return -EINVAL;
......
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