Commit 1522ecae authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/bios: timing 2.0 entries can have subentries

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 09692e5b
#ifndef __NVBIOS_TIMING_H__
#define __NVBIOS_TIMING_H__
u16 nvbios_timing_table(struct nouveau_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 nvbios_timing_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
u16 nvbios_timingTe(struct nouveau_bios *,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
u16 nvbios_timingEe(struct nouveau_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
#endif
......@@ -27,8 +27,8 @@
#include <subdev/bios/timing.h>
u16
nvbios_timing_table(struct nouveau_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
nvbios_timingTe(struct nouveau_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{
struct bit_entry bit_P;
u16 timing = 0x0000;
......@@ -47,11 +47,15 @@ nvbios_timing_table(struct nouveau_bios *bios,
*hdr = nv_ro08(bios, timing + 1);
*cnt = nv_ro08(bios, timing + 2);
*len = nv_ro08(bios, timing + 3);
*snr = 0;
*ssz = 0;
return timing;
case 0x20:
*hdr = nv_ro08(bios, timing + 1);
*cnt = nv_ro08(bios, timing + 3);
*cnt = nv_ro08(bios, timing + 5);
*len = nv_ro08(bios, timing + 2);
*snr = nv_ro08(bios, timing + 4);
*ssz = nv_ro08(bios, timing + 3);
return timing;
default:
break;
......@@ -63,11 +67,17 @@ nvbios_timing_table(struct nouveau_bios *bios,
}
u16
nvbios_timing_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
nvbios_timingEe(struct nouveau_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u8 hdr, cnt;
u16 timing = nvbios_timing_table(bios, ver, &hdr, &cnt, len);
if (timing && idx < cnt)
return timing + hdr + (idx * *len);
u8 snr, ssz;
u16 timing = nvbios_timingTe(bios, ver, hdr, cnt, len, &snr, &ssz);
if (timing && idx < *cnt) {
timing += *hdr + idx * (*len + (snr * ssz));
*hdr = *len;
*cnt = snr;
*len = ssz;
return timing;
}
return 0x0000;
}
......@@ -74,7 +74,7 @@ nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
u32 data;
u8 size;
} ramcfg, timing;
u8 ver, hdr, cnt, strap;
u8 ver, hdr, cnt, len, strap;
int N1, M1, N2, M2, P;
int ret, i;
......@@ -102,7 +102,8 @@ nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
/* lookup memory timings, if bios says they're present */
strap = nv_ro08(bios, ramcfg.data + 0x01);
if (strap != 0xff) {
timing.data = nvbios_timing_entry(bios, strap, &ver, &hdr);
timing.data = nvbios_timingEe(bios, strap, &ver, &hdr,
&cnt, &len);
if (!timing.data || ver != 0x10 || hdr < 0x12) {
nv_error(pfb, "invalid/missing timing entry "
"%02x %04x %02x %02x\n",
......
......@@ -79,7 +79,7 @@ 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;
u8 ver, cnt, strap;
u8 ver, cnt, len, strap;
u32 data;
struct {
u32 data;
......@@ -113,8 +113,8 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
/* lookup memory timings, if bios says they're present */
strap = nv_ro08(bios, ramcfg.data + 0x01);
if (strap != 0xff) {
timing.data = nvbios_timing_entry(bios, strap, &ver,
&timing.size);
timing.data = nvbios_timingEe(bios, strap, &ver, &timing.size,
&cnt, &len);
if (!timing.data || ver != 0x10 || timing.size < 0x19) {
nv_error(pfb, "invalid/missing timing entry\n");
return -EINVAL;
......
......@@ -133,7 +133,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
struct nouveau_bios *bios = nouveau_bios(pfb);
struct nvc0_ram *ram = (void *)pfb->ram;
struct nvc0_ramfuc *fuc = &ram->fuc;
u8 ver, cnt, strap;
u8 ver, cnt, len, strap;
struct {
u32 data;
u8 size;
......@@ -167,8 +167,8 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
/* lookup memory timings, if bios says they're present */
strap = nv_ro08(bios, ramcfg.data + 0x01);
if (strap != 0xff) {
timing.data = nvbios_timing_entry(bios, strap, &ver,
&timing.size);
timing.data = nvbios_timingEe(bios, strap, &ver, &timing.size,
&cnt, &len);
if (!timing.data || ver != 0x10 || timing.size < 0x19) {
nv_error(pfb, "invalid/missing timing entry\n");
return -EINVAL;
......
......@@ -907,7 +907,7 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
struct nve0_ramfuc *fuc = &ram->fuc;
int ret, refclk, strap, i;
u32 data;
u8 cnt;
u8 cnt, len;
/* lookup memory config data relevant to the target frequency */
ram->base.rammap.data = nvbios_rammap_match(bios, freq / 1000,
......@@ -940,9 +940,8 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00);
if (strap != 0xff) {
ram->base.timing.data =
nvbios_timing_entry(bios, strap,
&ram->base.timing.version,
&ram->base.timing.size);
nvbios_timingEe(bios, strap, &ram->base.timing.version,
&ram->base.timing.size, &cnt, &len);
if (!ram->base.timing.data ||
ram->base.timing.version != 0x20 ||
ram->base.timing.size < 0x33) {
......
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