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

Commit 08c7f248 authored by Vince Hsu's avatar Vince Hsu Committed by Ben Skeggs
Browse files

drm/nouveau/volt: allow non-bios voltage scaling



Move the vbios parsing out of init() and call it conditionally if the
platform has a vbios. Non-vbios platforms can use the ctor() to init the
data structures.

Signed-off-by: default avatarVince Hsu <vinceh@nvidia.com>
Acked-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Acked-by: default avatarMartin Peres <martin.peres@free.fr>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent c6f37e0c
Loading
Loading
Loading
Loading
+38 −29
Original line number Diff line number Diff line
@@ -101,6 +101,41 @@ nouveau_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
	return ret;
}

static void nouveau_volt_parse_bios(struct nouveau_bios *bios,
		struct nouveau_volt *volt)
{
	struct nvbios_volt_entry ivid;
	struct nvbios_volt info;
	u8  ver, hdr, cnt, len;
	u16 data;
	int i;

	data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
	if (data && info.vidmask && info.base && info.step) {
		for (i = 0; i < info.vidmask + 1; i++) {
			if (info.base >= info.min &&
				info.base <= info.max) {
				volt->vid[volt->vid_nr].uv = info.base;
				volt->vid[volt->vid_nr].vid = i;
				volt->vid_nr++;
			}
			info.base += info.step;
		}
		volt->vid_mask = info.vidmask;
	} else if (data && info.vidmask) {
		for (i = 0; i < cnt; i++) {
			data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
							  &ivid);
			if (data) {
				volt->vid[volt->vid_nr].uv = ivid.voltage;
				volt->vid[volt->vid_nr].vid = ivid.vid;
				volt->vid_nr++;
			}
		}
		volt->vid_mask = info.vidmask;
	}
}

int
_nouveau_volt_init(struct nouveau_object *object)
{
@@ -136,10 +171,6 @@ nouveau_volt_create_(struct nouveau_object *parent,
{
	struct nouveau_bios *bios = nouveau_bios(parent);
	struct nouveau_volt *volt;
	struct nvbios_volt_entry ivid;
	struct nvbios_volt info;
	u8  ver, hdr, cnt, len;
	u16 data;
	int ret, i;

	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT",
@@ -152,31 +183,9 @@ nouveau_volt_create_(struct nouveau_object *parent,
	volt->set = nouveau_volt_set;
	volt->set_id = nouveau_volt_set_id;

	data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
	if (data && info.vidmask && info.base && info.step) {
		for (i = 0; i < info.vidmask + 1; i++) {
			if (info.base >= info.min &&
			    info.base <= info.max) {
				volt->vid[volt->vid_nr].uv = info.base;
				volt->vid[volt->vid_nr].vid = i;
				volt->vid_nr++;
			}
			info.base += info.step;
		}
		volt->vid_mask = info.vidmask;
	} else
	if (data && info.vidmask) {
		for (i = 0; i < cnt; i++) {
			data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
						      &ivid);
			if (data) {
				volt->vid[volt->vid_nr].uv = ivid.voltage;
				volt->vid[volt->vid_nr].vid = ivid.vid;
				volt->vid_nr++;
			}
		}
		volt->vid_mask = info.vidmask;
	}
	/* Assuming the non-bios device should build the voltage table later */
	if (bios)
		nouveau_volt_parse_bios(bios, volt);

	if (volt->vid_nr) {
		for (i = 0; i < volt->vid_nr; i++) {