drm/nouveau/pm: initial attempt at parsing volt 0x40

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2011-06-09 16:16:38 +10:00
parent c3450239c7
commit f60dfb996c

View file

@ -170,6 +170,13 @@ nouveau_volt_init(struct drm_device *dev)
*/
vidshift = 2;
break;
case 0x40:
headerlen = volt[1];
recordlen = volt[2];
entries = volt[3]; /* not a clue what the entries are for.. */
vidmask = volt[11]; /* guess.. */
vidshift = 0;
break;
default:
NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]);
return;
@ -197,16 +204,36 @@ nouveau_volt_init(struct drm_device *dev)
}
/* parse vbios entries into common format */
voltage->level = kcalloc(entries, sizeof(*voltage->level), GFP_KERNEL);
if (!voltage->level)
return;
if (volt[0] < 0x40) {
voltage->nr_level = entries;
voltage->level =
kcalloc(entries, sizeof(*voltage->level), GFP_KERNEL);
if (!voltage->level)
return;
entry = volt + headerlen;
for (i = 0; i < entries; i++, entry += recordlen) {
voltage->level[i].voltage = entry[0] * 10000;
voltage->level[i].vid = entry[1] >> vidshift;
entry = volt + headerlen;
for (i = 0; i < entries; i++, entry += recordlen) {
voltage->level[i].voltage = entry[0] * 10000;
voltage->level[i].vid = entry[1] >> vidshift;
}
} else {
u32 volt_uv = ROM32(volt[4]);
s16 step_uv = ROM16(volt[8]);
u8 vid;
voltage->nr_level = voltage->vid_mask + 1;
voltage->level = kcalloc(voltage->nr_level,
sizeof(*voltage->level), GFP_KERNEL);
if (!voltage->level)
return;
for (vid = 0; vid <= voltage->vid_mask; vid++) {
voltage->level[vid].voltage = volt_uv;
voltage->level[vid].vid = vid;
volt_uv += step_uv;
}
}
voltage->nr_level = entries;
voltage->supported = true;
}