drm/nouveau/volt: save the voltage range we are able to set
authorKarol Herbst <nouveau@karolherbst.de>
Fri, 26 Feb 2016 06:49:08 +0000 (07:49 +0100)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 14 Jul 2016 01:53:25 +0000 (11:53 +1000)
We shouldn't set voltages below the min or above the max voltage the gpu is
able to set, so save the range for future lookups.

Signed-off-by: Karol Herbst <karolherbst@gmail.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Tested-by: Pierre Moreau <pierre.morrow@free.fr>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c

index feff55cff05bbf994ffed76ecf9ca05eac3055b6..b765f4ffcde63ba284aeba11ba0d757624e91253 100644 (file)
@@ -12,6 +12,9 @@ struct nvkm_volt {
                u32 uv;
                u8 vid;
        } vid[256];
+
+       u32 max_uv;
+       u32 min_uv;
 };
 
 int nvkm_volt_get(struct nvkm_volt *);
index 6b2d7531a7ff1beff1ee943745a0d5328e108940..1c3d23b0e84ad063c0c11310828327e232ac03bd 100644 (file)
@@ -120,6 +120,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
 
        data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
        if (data && info.vidmask && info.base && info.step) {
+               volt->min_uv = info.min;
+               volt->max_uv = info.max;
                for (i = 0; i < info.vidmask + 1; i++) {
                        if (info.base >= info.min &&
                                info.base <= info.max) {
@@ -131,6 +133,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
                }
                volt->vid_mask = info.vidmask;
        } else if (data && info.vidmask) {
+               volt->min_uv = 0xffffffff;
+               volt->max_uv = 0;
                for (i = 0; i < cnt; i++) {
                        data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
                                                       &ivid);
@@ -138,9 +142,14 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
                                volt->vid[volt->vid_nr].uv = ivid.voltage;
                                volt->vid[volt->vid_nr].vid = ivid.vid;
                                volt->vid_nr++;
+                               volt->min_uv = min(volt->min_uv, ivid.voltage);
+                               volt->max_uv = max(volt->max_uv, ivid.voltage);
                        }
                }
                volt->vid_mask = info.vidmask;
+       } else if (data && info.type == NVBIOS_VOLT_PWM) {
+               volt->min_uv = info.base;
+               volt->max_uv = info.base + info.pwm_range;
        }
 }
 
@@ -181,8 +190,11 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct nvkm_device *device,
        volt->func = func;
 
        /* Assuming the non-bios device should build the voltage table later */
-       if (bios)
+       if (bios) {
                nvkm_volt_parse_bios(bios, volt);
+               nvkm_debug(&volt->subdev, "min: %iuv max: %iuv\n",
+                          volt->min_uv, volt->max_uv);
+       }
 
        if (volt->vid_nr) {
                for (i = 0; i < volt->vid_nr; i++) {