提交 d9b5f261 编写于 作者: B Ben Skeggs

drm/nouveau/bios: parse freq ranges and timing id into ramcfg struct

Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
上级 595d373f
...@@ -4,11 +4,18 @@ ...@@ -4,11 +4,18 @@
struct nouveau_bios; struct nouveau_bios;
struct nvbios_ramcfg { struct nvbios_ramcfg {
unsigned rammap_ver;
unsigned rammap_hdr;
unsigned rammap_min;
unsigned rammap_max;
unsigned rammap_11_08_01:1; unsigned rammap_11_08_01:1;
unsigned rammap_11_08_0c:2; unsigned rammap_11_08_0c:2;
unsigned rammap_11_08_10:1; unsigned rammap_11_08_10:1;
unsigned rammap_11_11_0c:2; unsigned rammap_11_11_0c:2;
unsigned ramcfg_ver;
unsigned ramcfg_hdr;
unsigned ramcfg_timing;
unsigned ramcfg_11_01_01:1; unsigned ramcfg_11_01_01:1;
unsigned ramcfg_11_01_02:1; unsigned ramcfg_11_01_02:1;
unsigned ramcfg_11_01_04:1; unsigned ramcfg_11_01_04:1;
...@@ -43,6 +50,8 @@ struct nvbios_ramcfg { ...@@ -43,6 +50,8 @@ struct nvbios_ramcfg {
unsigned ramcfg_11_08_20:1; unsigned ramcfg_11_08_20:1;
unsigned ramcfg_11_09:8; unsigned ramcfg_11_09:8;
unsigned timing_ver;
unsigned timing_hdr;
unsigned timing[11]; unsigned timing[11];
unsigned timing_20_2e_03:2; unsigned timing_20_2e_03:2;
unsigned timing_20_2e_30:2; unsigned timing_20_2e_30:2;
......
...@@ -8,9 +8,10 @@ u32 nvbios_rammapTe(struct nouveau_bios *, u8 *ver, u8 *hdr, ...@@ -8,9 +8,10 @@ u32 nvbios_rammapTe(struct nouveau_bios *, u8 *ver, u8 *hdr,
u32 nvbios_rammapEe(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);
u32 nvbios_rammapEp(struct nouveau_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_ramcfg *);
u32 nvbios_rammapEm(struct nouveau_bios *, u16 mhz, u32 nvbios_rammapEm(struct nouveau_bios *, u16 mhz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_rammapEp(struct nouveau_bios *, u16 mhz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_ramcfg *); struct nvbios_ramcfg *);
......
...@@ -75,28 +75,18 @@ nvbios_rammapEe(struct nouveau_bios *bios, int idx, ...@@ -75,28 +75,18 @@ nvbios_rammapEe(struct nouveau_bios *bios, int idx,
} }
u32 u32
nvbios_rammapEm(struct nouveau_bios *bios, u16 khz, nvbios_rammapEp(struct nouveau_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
int idx = 0;
u32 data;
while ((data = nvbios_rammapEe(bios, idx++, ver, hdr, cnt, len))) {
if (khz >= nv_ro16(bios, data + 0x00) &&
khz <= nv_ro16(bios, data + 0x02))
break;
}
return data;
}
u32
nvbios_rammapEp(struct nouveau_bios *bios, u16 khz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_ramcfg *p) struct nvbios_ramcfg *p)
{ {
u32 data = nvbios_rammapEm(bios, khz, ver, hdr, cnt, len); u32 data = nvbios_rammapEe(bios, idx, ver, hdr, cnt, len);
memset(p, 0x00, sizeof(*p)); memset(p, 0x00, sizeof(*p));
p->rammap_ver = *ver;
p->rammap_hdr = *hdr;
switch (!!data * *ver) { switch (!!data * *ver) {
case 0x11: case 0x11:
p->rammap_min = nv_ro16(bios, data + 0x00);
p->rammap_max = nv_ro16(bios, data + 0x02);
p->rammap_11_08_01 = (nv_ro08(bios, data + 0x08) & 0x01) >> 0; 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_0c = (nv_ro08(bios, data + 0x08) & 0x0c) >> 2;
p->rammap_11_08_10 = (nv_ro08(bios, data + 0x08) & 0x10) >> 4; p->rammap_11_08_10 = (nv_ro08(bios, data + 0x08) & 0x10) >> 4;
...@@ -109,6 +99,20 @@ nvbios_rammapEp(struct nouveau_bios *bios, u16 khz, ...@@ -109,6 +99,20 @@ nvbios_rammapEp(struct nouveau_bios *bios, u16 khz,
return data; return data;
} }
u32
nvbios_rammapEm(struct nouveau_bios *bios, u16 mhz,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_ramcfg *info)
{
int idx = 0;
u32 data;
while ((data = nvbios_rammapEp(bios, idx++, ver, hdr, cnt, len, info))) {
if (mhz >= info->rammap_min && mhz <= info->rammap_max)
break;
}
return data;
}
u32 u32
nvbios_rammapSe(struct nouveau_bios *bios, u32 data, nvbios_rammapSe(struct nouveau_bios *bios, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx, u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
...@@ -129,8 +133,11 @@ nvbios_rammapSp(struct nouveau_bios *bios, u32 data, ...@@ -129,8 +133,11 @@ nvbios_rammapSp(struct nouveau_bios *bios, u32 data,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *p) u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
{ {
data = nvbios_rammapSe(bios, data, ever, ehdr, ecnt, elen, idx, ver, hdr); data = nvbios_rammapSe(bios, data, ever, ehdr, ecnt, elen, idx, ver, hdr);
p->ramcfg_ver = *ver;
p->ramcfg_hdr = *hdr;
switch (!!data * *ver) { switch (!!data * *ver) {
case 0x11: case 0x11:
p->ramcfg_timing = nv_ro08(bios, data + 0x00);
p->ramcfg_11_01_01 = (nv_ro08(bios, data + 0x01) & 0x01) >> 0; 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_02 = (nv_ro08(bios, data + 0x01) & 0x02) >> 1;
p->ramcfg_11_01_04 = (nv_ro08(bios, data + 0x01) & 0x04) >> 2; p->ramcfg_11_01_04 = (nv_ro08(bios, data + 0x01) & 0x04) >> 2;
......
...@@ -89,6 +89,8 @@ nvbios_timingEp(struct nouveau_bios *bios, int idx, ...@@ -89,6 +89,8 @@ nvbios_timingEp(struct nouveau_bios *bios, int idx,
struct nvbios_ramcfg *p) struct nvbios_ramcfg *p)
{ {
u16 data = nvbios_timingEe(bios, idx, ver, hdr, cnt, len), temp; u16 data = nvbios_timingEe(bios, idx, ver, hdr, cnt, len), temp;
p->timing_ver = *ver;
p->timing_hdr = *hdr;
switch (!!data * *ver) { switch (!!data * *ver) {
case 0x20: case 0x20:
p->timing[0] = nv_ro32(bios, data + 0x00); p->timing[0] = nv_ro32(bios, data + 0x00);
......
...@@ -79,6 +79,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -79,6 +79,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
struct nva3_ram *ram = (void *)pfb->ram; struct nva3_ram *ram = (void *)pfb->ram;
struct nva3_ramfuc *fuc = &ram->fuc; struct nva3_ramfuc *fuc = &ram->fuc;
struct nva3_clock_info mclk; struct nva3_clock_info mclk;
struct nvbios_ramcfg cfg;
u8 ver, cnt, len, strap; u8 ver, cnt, len, strap;
u32 data; u32 data;
struct { struct {
...@@ -91,7 +92,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -91,7 +92,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
/* lookup memory config data relevant to the target frequency */ /* lookup memory config data relevant to the target frequency */
rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size, rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
&cnt, &ramcfg.size); &cnt, &ramcfg.size, &cfg);
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");
return -EINVAL; return -EINVAL;
......
...@@ -133,6 +133,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -133,6 +133,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
struct nouveau_bios *bios = nouveau_bios(pfb); struct nouveau_bios *bios = nouveau_bios(pfb);
struct nvc0_ram *ram = (void *)pfb->ram; struct nvc0_ram *ram = (void *)pfb->ram;
struct nvc0_ramfuc *fuc = &ram->fuc; struct nvc0_ramfuc *fuc = &ram->fuc;
struct nvbios_ramcfg cfg;
u8 ver, cnt, len, strap; u8 ver, cnt, len, strap;
struct { struct {
u32 data; u32 data;
...@@ -145,7 +146,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq) ...@@ -145,7 +146,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
/* lookup memory config data relevant to the target frequency */ /* lookup memory config data relevant to the target frequency */
rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size, rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
&cnt, &ramcfg.size); &cnt, &ramcfg.size, &cfg);
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");
return -EINVAL; return -EINVAL;
......
...@@ -942,7 +942,7 @@ nve0_ram_calc_data(struct nouveau_fb *pfb, u32 freq, ...@@ -942,7 +942,7 @@ nve0_ram_calc_data(struct nouveau_fb *pfb, u32 freq,
u8 strap, cnt, len; u8 strap, 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_rammapEp(bios, freq / 1000, ram->base.rammap.data = nvbios_rammapEm(bios, freq / 1000,
&ram->base.rammap.version, &ram->base.rammap.version,
&ram->base.rammap.size, &ram->base.rammap.size,
&cnt, &len, &data->bios); &cnt, &len, &data->bios);
...@@ -968,12 +968,12 @@ nve0_ram_calc_data(struct nouveau_fb *pfb, u32 freq, ...@@ -968,12 +968,12 @@ nve0_ram_calc_data(struct nouveau_fb *pfb, u32 freq,
} }
/* lookup memory timings, if bios says they're present */ /* lookup memory timings, if bios says they're present */
strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00); if (data->bios.ramcfg_timing != 0xff) {
if (strap != 0xff) {
ram->base.timing.data = ram->base.timing.data =
nvbios_timingEp(bios, strap, &ram->base.timing.version, nvbios_timingEp(bios, data->bios.ramcfg_timing,
&ram->base.timing.size, &cnt, &len, &ram->base.timing.version,
&data->bios); &ram->base.timing.size, &cnt, &len,
&data->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) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册