diff options
author | Karol Herbst <karolherbst@gmail.com> | 2016-07-12 22:36:08 +0300 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-10-12 10:29:20 +0300 |
commit | 17d063dbdce3bab04957b2281dcdceecb7407170 (patch) | |
tree | ba64d59bf1f92bfb2fb6e9fdd0eee83699f93d53 /drivers/gpu/drm/nouveau/nvkm/subdev | |
parent | 17f486de6a56ee255eaa6dae272f70255cc41d3d (diff) | |
download | linux-17d063dbdce3bab04957b2281dcdceecb7407170.tar.xz |
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c | 22 |
2 files changed, 26 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c index 1defd3215ed3..2881b2ceda32 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c @@ -138,6 +138,7 @@ static int nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate) { struct nvkm_bios *bios = clk->subdev.device->bios; + struct nvkm_volt *volt = clk->subdev.device->volt; const struct nvkm_domain *domain = clk->domains; struct nvkm_cstate *cstate = NULL; struct nvbios_cstepX cstepX; @@ -148,6 +149,9 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate) if (!data) return -ENOENT; + if (volt && nvkm_volt_map_min(volt, cstepX.voltage) > volt->max_uv) + return -EINVAL; + cstate = kzalloc(sizeof(*cstate), GFP_KERNEL); if (!cstate) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c index 53a1cba6ad8d..6eeb9d9de334 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c @@ -65,6 +65,28 @@ nvkm_volt_set(struct nvkm_volt *volt, u32 uv) 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 nvkm_volt_map(struct nvkm_volt *volt, u8 id) { |