drm/nouveau/clk: Don't create cstates with voltages higher than what the gpu can do
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:20 +0000 (17:29 +1000)
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>
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 b765f4ffcde63ba284aeba11ba0d757624e91253..fc68825ffcbb8dacb6852f7fefebe6235dcb1a72 100644 (file)
@@ -17,6 +17,7 @@ struct nvkm_volt {
        u32 min_uv;
 };
 
+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, int condition);
 
index 1defd3215ed376d6bce0d7ebe266ebce61789f4d..2881b2ceda329e0459618928e6ae98cc4e14bfff 100644 (file)
@@ -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;
index 53a1cba6ad8d4c49bba0fa4118879a0bafcef447..6eeb9d9de3344ca88b166ca52c48b0f428b60f1f 100644 (file)
@@ -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)
 {