drm/nouveau/volt: Add temperature parameter to nvkm_volt_map

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>
This commit is contained in:
Karol Herbst 2016-07-12 21:36:08 +02:00 committed by Ben Skeggs
parent 61a8b84f1c
commit 8d08c264d2
3 changed files with 11 additions and 8 deletions

View File

@ -29,7 +29,8 @@ struct nvkm_volt {
int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id); int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
int nvkm_volt_get(struct nvkm_volt *); 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 nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **);

View File

@ -100,7 +100,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
if (volt) { if (volt) {
ret = nvkm_volt_set_id(volt, cstate->voltage, ret = nvkm_volt_set_id(volt, cstate->voltage,
pstate->base.voltage, +1); pstate->base.voltage, clk->temp, +1);
if (ret && ret != -ENODEV) { if (ret && ret != -ENODEV) {
nvkm_error(subdev, "failed to raise voltage: %d\n", ret); nvkm_error(subdev, "failed to raise voltage: %d\n", ret);
return ret; return ret;
@ -115,7 +115,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
if (volt) { if (volt) {
ret = nvkm_volt_set_id(volt, cstate->voltage, ret = nvkm_volt_set_id(volt, cstate->voltage,
pstate->base.voltage, -1); pstate->base.voltage, clk->temp, -1);
if (ret && ret != -ENODEV) if (ret && ret != -ENODEV)
nvkm_error(subdev, "failed to lower voltage: %d\n", ret); nvkm_error(subdev, "failed to lower voltage: %d\n", ret);
} }

View File

@ -26,6 +26,7 @@
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/vmap.h> #include <subdev/bios/vmap.h>
#include <subdev/bios/volt.h> #include <subdev/bios/volt.h>
#include <subdev/therm.h>
int int
nvkm_volt_get(struct nvkm_volt *volt) nvkm_volt_get(struct nvkm_volt *volt)
@ -88,7 +89,7 @@ nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
} }
static int 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 nvkm_bios *bios = volt->subdev.device->bios;
struct nvbios_vmap_entry info; 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); vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
if (vmap) { if (vmap) {
if (info.link != 0xff) { if (info.link != 0xff) {
int ret = nvkm_volt_map(volt, info.link); int ret = nvkm_volt_map(volt, info.link, temp);
if (ret < 0) if (ret < 0)
return ret; return ret;
info.min += ret; info.min += ret;
@ -110,20 +111,21 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
} }
int 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; int ret;
if (volt->func->set_id) if (volt->func->set_id)
return volt->func->set_id(volt, id, condition); return volt->func->set_id(volt, id, condition);
ret = nvkm_volt_map(volt, id); ret = nvkm_volt_map(volt, id, temp);
if (ret >= 0) { if (ret >= 0) {
int prev = nvkm_volt_get(volt); int prev = nvkm_volt_get(volt);
if (!condition || prev < 0 || if (!condition || prev < 0 ||
(condition < 0 && ret < prev) || (condition < 0 && ret < prev) ||
(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) if (min >= 0)
ret = max(min, ret); ret = max(min, ret);
ret = nvkm_volt_set(volt, ret); ret = nvkm_volt_set(volt, ret);