summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_volt.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-06-09 16:16:38 +1000
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 16:01:06 +1000
commitf60dfb996c510d9f197d67983a7f61eaf1c8ad67 (patch)
tree21943a6b9e9ff102444ed077c63b017974830b8c /drivers/gpu/drm/nouveau/nouveau_volt.c
parentc3450239c78a4ef6c10da13dfc18831f43dbe0c5 (diff)
downloadtalos-obmc-linux-f60dfb996c510d9f197d67983a7f61eaf1c8ad67.tar.gz
talos-obmc-linux-f60dfb996c510d9f197d67983a7f61eaf1c8ad67.zip
drm/nouveau/pm: initial attempt at parsing volt 0x40
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_volt.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_volt.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_volt.c b/drivers/gpu/drm/nouveau/nouveau_volt.c
index 9eec27581b16..471daec933f1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_volt.c
+++ b/drivers/gpu/drm/nouveau/nouveau_volt.c
@@ -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;
}
OpenPOWER on IntegriCloud