[Nouveau] [PATCH 13/32] clk: We should pass the pstate id around not the index in the list

Karol Herbst karolherbst at gmail.com
Fri Nov 17 00:04:17 UTC 2017


This makes the code easier, because we can compare the id with
pstate->id.

v2: reword commit message

Signed-off-by: Karol Herbst <karolherbst at gmail.com>
Reviewed-by: Martin Peres <martin.peres at free.fr>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  2 +-
 drm/nouveau/nouveau_debugfs.c         |  6 +--
 drm/nouveau/nvkm/engine/device/ctrl.c |  2 +-
 drm/nouveau/nvkm/subdev/clk/base.c    | 98 ++++++++++++++++-------------------
 drm/nouveau/nvkm/subdev/pmu/gk20a.c   |  4 +-
 5 files changed, 52 insertions(+), 60 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 44751db4..ebaa57eb 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -97,7 +97,7 @@ struct nvkm_clk {
 
 	struct nvkm_notify pwrsrc_ntfy;
 	int pwrsrc;
-	int pstate_idx; /* current */
+	int pstate_id; /* current */
 	int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
 	int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
 	int astate; /* perfmon adjustment (base) */
diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index df7e2f29..7e1dbb03 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -96,11 +96,11 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
 		} while (attr.index);
 
 		if (state_idx >= 0) {
-			if (info.ustate_ac == state_idx)
+			if (info.ustate_ac == attr.state)
 				seq_printf(m, " AC");
-			if (info.ustate_dc == state_idx)
+			if (info.ustate_dc == attr.state)
 				seq_printf(m, " DC");
-			if (info.pstate == state_idx)
+			if (info.pstate == attr.state)
 				seq_printf(m, " *");
 		} else {
 			if (info.ustate_ac < -1)
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c b/drm/nouveau/nvkm/engine/device/ctrl.c
index 1202e656..bb92cefa 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -52,7 +52,7 @@ nvkm_control_mthd_pstate_info(struct nvkm_control *ctrl, void *data, u32 size)
 		args->v0.ustate_ac = clk->ustate_ac;
 		args->v0.ustate_dc = clk->ustate_dc;
 		args->v0.pwrsrc = clk->pwrsrc;
-		args->v0.pstate = clk->pstate_idx;
+		args->v0.pstate = clk->pstate_id;
 	} else {
 		args->v0.count = 0;
 		args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 979f2cc3..85b9fb48 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -263,21 +263,27 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
  * P-States
  *****************************************************************************/
 static int
-nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_idx)
+nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_id)
 {
 	struct nvkm_subdev *subdev = &clk->subdev;
 	struct nvkm_fb *fb = subdev->device->fb;
 	struct nvkm_pci *pci = subdev->device->pci;
 	struct nvkm_pstate *pstate;
-	int ret, idx = 0;
+	int ret;
+
+	if (pstate_id == NVKM_CLK_PSTATE_BOOT)
+		return 0;
 
 	list_for_each_entry(pstate, &clk->pstates, head) {
-		if (idx++ == pstate_idx)
+		if (pstate->id == pstate_id)
 			break;
 	}
 
-	nvkm_debug(subdev, "setting performance state %d\n", pstate_idx);
-	clk->pstate_idx = pstate_idx;
+	if (!pstate)
+		return -EINVAL;
+
+	nvkm_debug(subdev, "setting performance state %x\n", pstate_id);
+	clk->pstate_id = pstate_id;
 
 	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
 
@@ -300,30 +306,28 @@ nvkm_clk_update_work(struct work_struct *work)
 {
 	struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
 	struct nvkm_subdev *subdev = &clk->subdev;
-	int pstate_idx;
+	int pstate_id;
 
 	if (!atomic_xchg(&clk->waiting, 0))
 		return;
 	clk->pwrsrc = power_supply_is_system_supplied();
 
-	nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d T %d°C\n",
-		   clk->pstate_idx, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
+	nvkm_trace(subdev, "P %x PWR %d U(AC) %d U(DC) %d A %d T %d°C\n",
+		   clk->pstate_id, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
 		   clk->astate, clk->temp);
 
-	pstate_idx = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
-	if (clk->pstates_cnt && pstate_idx != NVKM_CLK_PSTATE_BOOT) {
-		pstate_idx = (pstate_idx < 0) ? clk->astate : pstate_idx;
-		pstate_idx = min(pstate_idx, clk->pstates_cnt - 1);
-	} else {
-		pstate_idx = clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
-	}
+	pstate_id = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
+	if (clk->pstates_cnt && pstate_id != NVKM_CLK_PSTATE_BOOT)
+		pstate_id = (pstate_id < 0) ? clk->astate : pstate_id;
+	else
+		pstate_id = NVKM_CLK_PSTATE_BOOT;
 
-	nvkm_trace(subdev, "-> %d\n", pstate_idx);
-	if (pstate_idx != clk->pstate_idx) {
-		int ret = nvkm_pstate_prog(clk, pstate_idx);
+	nvkm_trace(subdev, "-> %x\n", pstate_id);
+	if (pstate_id != clk->pstate_id) {
+		int ret = nvkm_pstate_prog(clk, pstate_id);
 		if (ret) {
 			nvkm_error(subdev, "error setting pstate %d: %d\n",
-				   pstate_idx, ret);
+				   pstate_id, ret);
 		}
 	}
 
@@ -474,30 +478,6 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
 /******************************************************************************
  * Adjustment triggers
  *****************************************************************************/
-static int
-nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
-{
-	struct nvkm_pstate *pstate;
-	int i = 0;
-
-	if (!clk->allow_reclock)
-		return -ENOSYS;
-
-	if (req != -1 && req != -2) {
-		list_for_each_entry(pstate, &clk->pstates, head) {
-			if (pstate->id == req)
-				break;
-			i++;
-		}
-
-		if (pstate->id != req)
-			return -EINVAL;
-		req = i;
-	}
-
-	return req + 2;
-}
-
 static int
 nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, int arglen)
 {
@@ -512,26 +492,38 @@ nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, int arglen)
 
 		((char *)mode)[arglen] = '\0';
 		if (!kstrtol(mode, 0, &v)) {
-			ret = nvkm_clk_ustate_update(clk, v);
+			ret = v;
 			if (ret < 0)
 				ret = 1;
 		}
 		((char *)mode)[arglen] = save;
 	}
 
-	return ret - 2;
+	return -EINVAL;
 }
 
 int
 nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
 {
-	int ret = nvkm_clk_ustate_update(clk, req);
-	if (ret >= 0) {
-		if (ret -= 2, pwr) clk->ustate_ac = ret;
-		else		   clk->ustate_dc = ret;
-		return nvkm_clk_update(clk, true);
+	struct nvkm_pstate *pstate;
+	bool valid = false;
+
+	list_for_each_entry(pstate, &clk->pstates, head) {
+		if (pstate->id == req) {
+			valid = true;
+			break;
+		}
 	}
-	return ret;
+
+	if (!valid)
+		return -EINVAL;
+
+	if (pwr)
+		clk->ustate_ac = req;
+	else
+		clk->ustate_dc = req;
+
+	return nvkm_clk_update(clk, true);
 }
 
 int
@@ -609,8 +601,8 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 	if (clk->func->init)
 		return clk->func->init(clk);
 
-	clk->astate = clk->pstates_cnt - 1;
-	clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
+	clk->astate = NVKM_CLK_PSTATE_BOOT;
+	clk->pstate_id = NVKM_CLK_PSTATE_BOOT;
 	clk->temp = 90; /* reasonable default value */
 	nvkm_clk_update(clk, true);
 	return 0;
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index f5abc664..b316673f 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -60,7 +60,7 @@ gk20a_pmu_dvfs_get_cur_state(struct gk20a_pmu *pmu, int *state)
 {
 	struct nvkm_clk *clk = pmu->base.subdev.device->clk;
 
-	*state = clk->pstate_idx;
+	*state = clk->pstate_id;
 }
 
 static int
@@ -72,7 +72,7 @@ gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu *pmu,
 	int cur_level, level;
 
 	/* For GK20A, the performance level is directly mapped to pstate */
-	level = cur_level = clk->pstate_idx;
+	level = cur_level = clk->pstate_id;
 
 	if (load > data->p_load_max) {
 		level = min(clk->pstates_cnt - 1,
-- 
2.15.0



More information about the Nouveau mailing list