Re: [Nouveau] [RFC PATCH 07/29] clk: Hold information about the current cstate status
Acked-by: Pierre Moreau On 2017-09-15 — 17:11, Karol Herbst wrote: > Later we will have situations where the expected and the current state > isn't the same. > > Signed-off-by: Karol Herbst > Reviewed-by: Martin Peres > --- > 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 ec537e08..f35518c3 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) { >
[Nouveau] [RFC PATCH 07/29] clk: Hold information about the current cstate status
Later we will have situations where the expected and the current state isn't the same. Signed-off-by: Karol Herbst Reviewed-by: Martin Peres --- 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 ec537e08..f35518c3 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