[Nouveau] [PATCH v2 20/22] clk: add nvkm_clk_reclock function

Karol Herbst nouveau at karolherbst.de
Mon Mar 21 16:16:38 UTC 2016


this function just forces a reclock. This makes sense if some cstates get (un)available and we have to adjust to that.

This can happen for various reasons:
 * temperature changes
 * user changes boost mode

Signed-off-by: Karol Herbst <nouveau at karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  1 +
 drm/nouveau/nvkm/subdev/clk/base.c    | 23 ++++++++++++++++-------
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 61d99fd..de164a3 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -120,6 +120,7 @@ int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
 int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
 int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
 int nvkm_clk_tstate(struct nvkm_clk *, int req, int rel);
+int nvkm_clk_reclock(struct nvkm_clk *);
 
 int nv04_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
 int nv40_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 2d16e9c..7a8451e 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -264,6 +264,9 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 	struct nvkm_pstate *pstate;
 	int ret, idx = 0;
 
+	if (pstatei == -1)
+		return 0;
+
 	list_for_each_entry(pstate, &clk->states, head) {
 		if (idx++ == pstatei)
 			break;
@@ -292,7 +295,7 @@ nvkm_pstate_work(struct work_struct *work)
 {
 	struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
 	struct nvkm_subdev *subdev = &clk->subdev;
-	int pstate;
+	int pstate, ret;
 
 	if (!atomic_xchg(&clk->waiting, 0))
 		return;
@@ -312,12 +315,10 @@ nvkm_pstate_work(struct work_struct *work)
 	}
 
 	nvkm_trace(subdev, "-> %d\n", pstate);
-	if (pstate != clk->pstate) {
-		int ret = nvkm_pstate_prog(clk, pstate);
-		if (ret) {
-			nvkm_error(subdev, "error setting pstate %d: %d\n",
-				   pstate, ret);
-		}
+	ret = nvkm_pstate_prog(clk, pstate);
+	if (ret) {
+		nvkm_error(subdev, "error setting pstate %d: %d\n",
+			   pstate, ret);
 	}
 
 	wake_up_all(&clk->wait);
@@ -560,6 +561,14 @@ nvkm_clk_pwrsrc(struct nvkm_notify *notify)
 	return NVKM_NOTIFY_DROP;
 }
 
+int
+nvkm_clk_reclock(struct nvkm_clk *clk)
+{
+	if (clk->allow_reclock)
+		return nvkm_pstate_calc(clk, true);
+	return -ENODEV;
+}
+
 /******************************************************************************
  * subdev base class implementation
  *****************************************************************************/
-- 
2.7.4



More information about the Nouveau mailing list