[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