Re: [Nouveau] [RFC PATCH 07/29] clk: Hold information about the current cstate status

2017-10-08 Thread Pierre Moreau
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

2017-09-15 Thread Karol Herbst
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