Signed-off-by: Martin Peres <martin.pe...@free.fr>
---
 drm/nouveau/include/nvkm/subdev/bios/volt.h | 15 ++++++++++++++-
 drm/nouveau/nvkm/subdev/bios/volt.c         | 17 +++++++++++++++--
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/volt.h 
b/drm/nouveau/include/nvkm/subdev/bios/volt.h
index eb2de4b..b0df610 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/volt.h
@@ -1,11 +1,24 @@
 #ifndef __NVBIOS_VOLT_H__
 #define __NVBIOS_VOLT_H__
+
+enum nvbios_volt_type {
+       NVBIOS_VOLT_GPIO = 0,
+       NVBIOS_VOLT_PWM,
+};
+
 struct nvbios_volt {
-       u8  vidmask;
+       enum nvbios_volt_type type;
        u32 min;
        u32 max;
        u32 base;
+
+       /* GPIO mode */
+       u8  vidmask;
        s16 step;
+
+       /* PWM mode */
+       u32 pwm_freq;
+       u32 pwm_range;
 };
 
 u16 nvbios_volt_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
diff --git a/drm/nouveau/nvkm/subdev/bios/volt.c 
b/drm/nouveau/nvkm/subdev/bios/volt.c
index 615804c..6e0a336 100644
--- a/drm/nouveau/nvkm/subdev/bios/volt.c
+++ b/drm/nouveau/nvkm/subdev/bios/volt.c
@@ -73,15 +73,19 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, 
u8 *cnt, u8 *len,
        memset(info, 0x00, sizeof(*info));
        switch (!!volt * *ver) {
        case 0x12:
+               info->type    = NVBIOS_VOLT_GPIO;
                info->vidmask = nvbios_rd08(bios, volt + 0x04);
                break;
        case 0x20:
+               info->type    = NVBIOS_VOLT_GPIO;
                info->vidmask = nvbios_rd08(bios, volt + 0x05);
                break;
        case 0x30:
+               info->type    = NVBIOS_VOLT_GPIO;
                info->vidmask = nvbios_rd08(bios, volt + 0x04);
                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);
@@ -90,11 +94,20 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, 
u8 *cnt, u8 *len,
                info->max     = info->base;
                break;
        case 0x50:
-               info->vidmask = nvbios_rd08(bios, volt + 0x06);
                info->min     = nvbios_rd32(bios, volt + 0x0a);
                info->max     = nvbios_rd32(bios, volt + 0x0e);
                info->base    = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff;
-               info->step    = nvbios_rd16(bios, volt + 0x16);
+
+               /* offset 4 seems to be a flag byte */
+               if (nvbios_rd32(bios, volt + 0x4) & 1) {
+                       info->type      = NVBIOS_VOLT_PWM;
+                       info->pwm_freq  = nvbios_rd32(bios, volt + 0x5) / 1000;
+                       info->pwm_range = nvbios_rd32(bios, volt + 0x16);
+               } else {
+                       info->type      = NVBIOS_VOLT_GPIO;
+                       info->vidmask   = nvbios_rd08(bios, volt + 0x06);
+                       info->step      = nvbios_rd16(bios, volt + 0x16);
+               }
                break;
        }
        return volt;
-- 
2.5.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to