diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-06-09 16:16:38 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 16:01:06 +1000 |
commit | f60dfb996c510d9f197d67983a7f61eaf1c8ad67 (patch) | |
tree | 21943a6b9e9ff102444ed077c63b017974830b8c /drivers/gpu/drm/nouveau/nouveau_volt.c | |
parent | c3450239c78a4ef6c10da13dfc18831f43dbe0c5 (diff) | |
download | talos-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.c | 43 |
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; } |