drm/nouveau/clk: Fixup cstate selection
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:23 +0000 (17:29 +1000)
Now the cstatei parameter can be used of the nvkm_cstate_prog function to
select a specific cstate.

v5: Make a constant for the magic value.
    Use list_last_entry.
    Add nvkm_cstate_get here instead of in the next commit.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h
drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c

index 0cf3d86e399a6db3003f336b532ea704910c61bd..cc2a976446a90a1d565d8a044367d7b04ac54e3e 100644 (file)
@@ -6,6 +6,10 @@
 struct nvbios_pll;
 struct nvkm_pll_vals;
 
+#define NVKM_CLK_CSTATE_DEFAULT -1 /* POSTed default */
+#define NVKM_CLK_CSTATE_BASE    -2 /* pstate base */
+#define NVKM_CLK_CSTATE_HIGHEST -3 /* highest possible */
+
 enum nv_clk_src {
        nv_clk_src_crystal,
        nv_clk_src_href,
index 98168be93515cbc2ac431261c5b3054c78ff1fdb..688c908908d87db32338d502bb888dfd36739cb0 100644 (file)
@@ -74,6 +74,21 @@ nvkm_clk_adjust(struct nvkm_clk *clk, bool adjust,
 /******************************************************************************
  * C-States
  *****************************************************************************/
+static struct nvkm_cstate *
+nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
+{
+       struct nvkm_cstate *cstate;
+       if (cstatei == NVKM_CLK_CSTATE_HIGHEST)
+               return list_last_entry(&pstate->list, typeof(*cstate), head);
+       else {
+               list_for_each_entry(cstate, &pstate->list, head) {
+                       if (cstate->id == cstatei)
+                               return cstate;
+               }
+       }
+       return NULL;
+}
+
 static int
 nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 {
@@ -85,7 +100,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
        int ret;
 
        if (!list_empty(&pstate->list)) {
-               cstate = list_entry(pstate->list.prev, typeof(*cstate), head);
+               cstate = nvkm_cstate_get(clk, pstate, cstatei);
        } else {
                cstate = &pstate->base;
        }
@@ -208,7 +223,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
                ram->func->tidy(ram);
        }
 
-       return nvkm_cstate_prog(clk, pstate, 0);
+       return nvkm_cstate_prog(clk, pstate, NVKM_CLK_CSTATE_HIGHEST);
 }
 
 static void