drm/nouveau/volt: Add temperature parameter to nvkm_volt_map
authorKarol Herbst <karolherbst@gmail.com>
Tue, 12 Jul 2016 19:36:08 +0000 (21:36 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 12 Oct 2016 07:29:23 +0000 (17:29 +1000)
The voltage entries actually may map to a different voltage depending on
the current temperature.

v2: Only read the temperature when actually needed.
v5: Be smarter about using max().
    Don't read the temperature anymore.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Martin Peres <martin.peres@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/clk/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c

index 06d45934b6a0c5b2faff8db3aa329bc6490a931c..6fd933df763e7108fe805e3f31a383dbce93b2a5 100644 (file)
@@ -29,7 +29,8 @@ struct nvkm_volt {
 
 int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
 int nvkm_volt_get(struct nvkm_volt *);
-int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, int condition);
+int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, u8 temp,
+                    int condition);
 
 int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
 int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
index 88a517c33842e8001649af7b7af085d370521820..98168be93515cbc2ac431261c5b3054c78ff1fdb 100644 (file)
@@ -100,7 +100,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 
        if (volt) {
                ret = nvkm_volt_set_id(volt, cstate->voltage,
-                                      pstate->base.voltage, +1);
+                                      pstate->base.voltage, clk->temp, +1);
                if (ret && ret != -ENODEV) {
                        nvkm_error(subdev, "failed to raise voltage: %d\n", ret);
                        return ret;
@@ -115,7 +115,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 
        if (volt) {
                ret = nvkm_volt_set_id(volt, cstate->voltage,
-                                      pstate->base.voltage, -1);
+                                      pstate->base.voltage, clk->temp, -1);
                if (ret && ret != -ENODEV)
                        nvkm_error(subdev, "failed to lower voltage: %d\n", ret);
        }
index 960505be5e280d549880d202591f7e5ad8888756..40ba088a5c81f1a365e0e53571961e988746dc89 100644 (file)
@@ -26,6 +26,7 @@
 #include <subdev/bios.h>
 #include <subdev/bios/vmap.h>
 #include <subdev/bios/volt.h>
+#include <subdev/therm.h>
 
 int
 nvkm_volt_get(struct nvkm_volt *volt)
@@ -88,7 +89,7 @@ nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
 }
 
 static int
-nvkm_volt_map(struct nvkm_volt *volt, u8 id)
+nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
 {
        struct nvkm_bios *bios = volt->subdev.device->bios;
        struct nvbios_vmap_entry info;
@@ -98,7 +99,7 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
        vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
        if (vmap) {
                if (info.link != 0xff) {
-                       int ret = nvkm_volt_map(volt, info.link);
+                       int ret = nvkm_volt_map(volt, info.link, temp);
                        if (ret < 0)
                                return ret;
                        info.min += ret;
@@ -110,20 +111,21 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
 }
 
 int
-nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, u8 min_id, int condition)
+nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, u8 min_id, u8 temp,
+                int condition)
 {
        int ret;
 
        if (volt->func->set_id)
                return volt->func->set_id(volt, id, condition);
 
-       ret = nvkm_volt_map(volt, id);
+       ret = nvkm_volt_map(volt, id, temp);
        if (ret >= 0) {
                int prev = nvkm_volt_get(volt);
                if (!condition || prev < 0 ||
                    (condition < 0 && ret < prev) ||
                    (condition > 0 && ret > prev)) {
-                       int min = nvkm_volt_map(volt, min_id);
+                       int min = nvkm_volt_map(volt, min_id, temp);
                        if (min >= 0)
                                ret = max(min, ret);
                        ret = nvkm_volt_set(volt, ret);