Commit 17d063db authored by Karol Herbst's avatar Karol Herbst Committed by Ben Skeggs

drm/nouveau/clk: Don't create cstates with voltages higher than what the gpu can do

nvkm_volt_map_min is a copy of nvkm_volt_map, which always returns the
lowest possible voltage for a cstate.

nvkm_volt_map will get a temperature parameter there later and also fix
the voltage calculation, so that this functions will be completly
different later.
Signed-off-by: default avatarKarol Herbst <karolherbst@gmail.com>
Reviewed-by: default avatarMartin Peres <martin.peres@free.fr>
Tested-by: default avatarPierre Moreau <pierre.morrow@free.fr>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 17f486de
...@@ -17,6 +17,7 @@ struct nvkm_volt { ...@@ -17,6 +17,7 @@ struct nvkm_volt {
u32 min_uv; u32 min_uv;
}; };
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, int condition); int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition);
......
...@@ -138,6 +138,7 @@ static int ...@@ -138,6 +138,7 @@ static int
nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate) nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
{ {
struct nvkm_bios *bios = clk->subdev.device->bios; struct nvkm_bios *bios = clk->subdev.device->bios;
struct nvkm_volt *volt = clk->subdev.device->volt;
const struct nvkm_domain *domain = clk->domains; const struct nvkm_domain *domain = clk->domains;
struct nvkm_cstate *cstate = NULL; struct nvkm_cstate *cstate = NULL;
struct nvbios_cstepX cstepX; struct nvbios_cstepX cstepX;
...@@ -148,6 +149,9 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate) ...@@ -148,6 +149,9 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
if (!data) if (!data)
return -ENOENT; return -ENOENT;
if (volt && nvkm_volt_map_min(volt, cstepX.voltage) > volt->max_uv)
return -EINVAL;
cstate = kzalloc(sizeof(*cstate), GFP_KERNEL); cstate = kzalloc(sizeof(*cstate), GFP_KERNEL);
if (!cstate) if (!cstate)
return -ENOMEM; return -ENOMEM;
......
...@@ -65,6 +65,28 @@ nvkm_volt_set(struct nvkm_volt *volt, u32 uv) ...@@ -65,6 +65,28 @@ nvkm_volt_set(struct nvkm_volt *volt, u32 uv)
return ret; return ret;
} }
int
nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
{
struct nvkm_bios *bios = volt->subdev.device->bios;
struct nvbios_vmap_entry info;
u8 ver, len;
u16 vmap;
vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
if (vmap) {
if (info.link != 0xff) {
int ret = nvkm_volt_map_min(volt, info.link);
if (ret < 0)
return ret;
info.min += ret;
}
return info.min;
}
return id ? id * 10000 : -ENODEV;
}
static int static int
nvkm_volt_map(struct nvkm_volt *volt, u8 id) nvkm_volt_map(struct nvkm_volt *volt, u8 id)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment