Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b655f2bb authored by Ben Skeggs's avatar Ben Skeggs
Browse files

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
Loading
Loading
Loading
Loading
+56 −0
Original line number Original line Diff line number Diff line
@@ -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 *);


+20 −6
Original line number Original line Diff line number Diff line
#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
+5 −0
Original line number Original line Diff line number Diff line
#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
+9 −0
Original line number Original line Diff line number Diff line
@@ -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 {
	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
+95 −11
Original line number Original line Diff line number Diff line
@@ -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,
	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,
	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;
}
Loading