Later we will have situations where the expected and the current state isn't the same.
Signed-off-by: Karol Herbst <karolher...@gmail.com> Reviewed-by: Martin Peres <martin.pe...@free.fr> --- drm/nouveau/include/nvkm/subdev/clk.h | 2 ++ drm/nouveau/nvkm/subdev/clk/base.c | 32 +++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h index 37263b7f..0e0af704 100644 --- a/drm/nouveau/include/nvkm/subdev/clk.h +++ b/drm/nouveau/include/nvkm/subdev/clk.h @@ -101,6 +101,8 @@ struct nvkm_clk { int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */ int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */ int astate; /* perfmon adjustment (base) */ + struct nvkm_cstate *cstate; + int exp_cstateid; u8 temp; bool allow_reclock; diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c index 0d4d9fdf..d37c13b7 100644 --- a/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drm/nouveau/nvkm/subdev/clk/base.c @@ -146,9 +146,14 @@ 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) + switch (cstatei) { + case NVKM_CLK_CSTATE_HIGHEST: return list_last_entry(&pstate->list, typeof(*cstate), head); - else { + case NVKM_CLK_CSTATE_BASE: + return &pstate->base; + case NVKM_CLK_CSTATE_DEFAULT: + return NULL; + default: list_for_each_entry(cstate, &pstate->list, head) { if (cstate->id == cstatei) return cstate; @@ -167,6 +172,9 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei) struct nvkm_cstate *cstate; int ret; + if (cstatei == NVKM_CLK_CSTATE_DEFAULT) + return 0; + if (!list_empty(&pstate->list)) { cstate = nvkm_cstate_get(clk, pstate, cstatei); cstate = nvkm_cstate_find_best(clk, pstate, cstate); @@ -193,6 +201,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei) ret = clk->func->calc(clk, cstate); if (ret == 0) { + clk->cstate = cstate; ret = clk->func->prog(clk); clk->func->tidy(clk); } @@ -295,7 +304,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei) ram->func->tidy(ram); } - return nvkm_cstate_prog(clk, pstate, NVKM_CLK_CSTATE_HIGHEST); + return nvkm_cstate_prog(clk, pstate, clk->exp_cstateid); } static void @@ -313,9 +322,9 @@ nvkm_clk_update_work(struct work_struct *work) pstate = clk->pstate->pstate; else pstate = NVKM_CLK_PSTATE_DEFAULT; - nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d T %d°C\n", + nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d C %d T %d°C\n", pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc, - clk->astate, clk->temp); + clk->astate, clk->exp_cstateid, clk->temp); pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc; if (clk->state_nr && pstate != -1) { @@ -536,6 +545,7 @@ nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr) if (ret >= 0) { if (ret -= 2, pwr) clk->ustate_ac = ret; else clk->ustate_dc = ret; + clk->exp_cstateid = NVKM_CLK_CSTATE_HIGHEST; return nvkm_clk_update(clk, true); } return ret; @@ -548,6 +558,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait) if ( rel) clk->astate += rel; clk->astate = min(clk->astate, clk->state_nr - 1); clk->astate = max(clk->astate, 0); + clk->exp_cstateid = NVKM_CLK_CSTATE_BASE; return nvkm_clk_update(clk, wait); } @@ -618,6 +629,8 @@ nvkm_clk_init(struct nvkm_subdev *subdev) clk->astate = clk->state_nr - 1; clk->pstate = NULL; + clk->exp_cstateid = NVKM_CLK_CSTATE_DEFAULT; + clk->cstate = NULL; clk->temp = 90; /* reasonable default value */ nvkm_clk_update(clk, true); return 0; @@ -701,15 +714,20 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device, if (mode) { clk->ustate_ac = nvkm_clk_nstate(clk, mode, arglen); clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen); + clk->exp_cstateid = NVKM_CLK_CSTATE_HIGHEST; } mode = nvkm_stropt(device->cfgopt, "NvClkModeAC", &arglen); - if (mode) + if (mode) { clk->ustate_ac = nvkm_clk_nstate(clk, mode, arglen); + clk->exp_cstateid = NVKM_CLK_CSTATE_HIGHEST; + } mode = nvkm_stropt(device->cfgopt, "NvClkModeDC", &arglen); - if (mode) + if (mode) { clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen); + clk->exp_cstateid = NVKM_CLK_CSTATE_HIGHEST; + } clk->boost_mode = nvkm_longopt(device->cfgopt, "NvBoost", NVKM_CLK_BOOST_NONE); -- 2.12.0 _______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/nouveau