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: Karol Herbst <karolherbst@gmail.com> Reviewed-by: Martin Peres <martin.peres@free.fr> Tested-by: Pierre Moreau <pierre.morrow@free.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
@@ -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
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user