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

Commit 17f486de authored by Karol Herbst's avatar Karol Herbst Committed by Ben Skeggs
Browse files

drm/nouveau/volt: Properly detect entry based voltage tables



There is a field in the voltage table which tells us if the VIDs are taken
from the entries or calculated through the header.

v2: Don't break older versions.
v5: Reverse flag name.

Signed-off-by: default avatarKarol Herbst <karolherbst@gmail.com>
Reviewed-by: default avatarMartin Peres <martin.peres@free.fr>
Tested-by: default avatarPierre Moreau <pierre.morrow@free.fr>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 32dd7f23
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ struct nvbios_volt {
	u32 base;

	/* GPIO mode */
	bool ranged;
	u8   vidmask;
	s16  step;

+9 −3
Original line number Diff line number Diff line
@@ -75,20 +75,24 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
	case 0x12:
		info->type    = NVBIOS_VOLT_GPIO;
		info->vidmask = nvbios_rd08(bios, volt + 0x04);
		info->ranged  = false;
		break;
	case 0x20:
		info->type    = NVBIOS_VOLT_GPIO;
		info->vidmask = nvbios_rd08(bios, volt + 0x05);
		info->ranged  = false;
		break;
	case 0x30:
		info->type    = NVBIOS_VOLT_GPIO;
		info->vidmask = nvbios_rd08(bios, volt + 0x04);
		info->ranged  = false;
		break;
	case 0x40:
		info->type    = NVBIOS_VOLT_GPIO;
		info->base    = nvbios_rd32(bios, volt + 0x04);
		info->step    = nvbios_rd16(bios, volt + 0x08);
		info->vidmask = nvbios_rd08(bios, volt + 0x0b);
		info->ranged  = true; /* XXX: find the flag byte */
		/*XXX*/
		info->min     = 0;
		info->max     = info->base;
@@ -107,6 +111,8 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
			info->type    = NVBIOS_VOLT_GPIO;
			info->vidmask = nvbios_rd08(bios, volt + 0x06);
			info->step    = nvbios_rd16(bios, volt + 0x16);
			info->ranged  =
				!!(nvbios_rd08(bios, volt + 0x4) & 0x2);
		}
		break;
	}
+5 −2
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition)
static void
nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
{
	struct nvkm_subdev *subdev = &bios->subdev;
	struct nvbios_volt_entry ivid;
	struct nvbios_volt info;
	u8  ver, hdr, cnt, len;
@@ -119,7 +120,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
	int i;

	data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
	if (data && info.vidmask && info.base && info.step) {
	if (data && info.vidmask && info.base && info.step && info.ranged) {
		nvkm_debug(subdev, "found ranged based VIDs\n");
		volt->min_uv = info.min;
		volt->max_uv = info.max;
		for (i = 0; i < info.vidmask + 1; i++) {
@@ -132,7 +134,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
			info.base += info.step;
		}
		volt->vid_mask = info.vidmask;
	} else if (data && info.vidmask) {
	} else if (data && info.vidmask && !info.ranged) {
		nvkm_debug(subdev, "found entry based VIDs\n");
		volt->min_uv = 0xffffffff;
		volt->max_uv = 0;
		for (i = 0; i < cnt; i++) {