[RFC,26/29] clk: refactor the base and boost clock limits so that we can limit pstates as well

Submitted by Karol Herbst on Sept. 15, 2017, 5:11 p.m.

Details

Message ID 20170915171129.5009-27-karolherbst@gmail.com
State New
Headers show
Series "Current State of my clk patches" ( rev: 1 ) in Nouveau

Not browsing as part of any series.

Commit Message

Karol Herbst Sept. 15, 2017, 5:11 p.m.
Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  9 +++++++--
 drm/nouveau/nvkm/engine/device/ctrl.c |  8 ++++----
 drm/nouveau/nvkm/subdev/clk/base.c    | 34 +++++++++++++++++++++++++---------
 3 files changed, 36 insertions(+), 15 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 4c225dcb..70505c9b 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -81,6 +81,11 @@  struct nvkm_domain {
 	int mdiv;
 };
 
+struct nvkm_clk_limit {
+	u8  pstate;
+	u32 max_khz;
+};
+
 struct nvkm_clk {
 	const struct nvkm_clk_func *func;
 	struct nvkm_subdev subdev;
@@ -113,8 +118,8 @@  struct nvkm_clk {
 #define NVKM_CLK_BOOST_BIOS 0x1
 #define NVKM_CLK_BOOST_FULL 0x2
 	u8  boost_mode;
-	u32 base_khz;
-	u32 boost_khz;
+	struct nvkm_clk_limit base_limit;
+	struct nvkm_clk_limit boost_limit;
 	u32 max_khz;
 
 	/*XXX: die, these are here *only* to support the completely
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c b/drm/nouveau/nvkm/engine/device/ctrl.c
index 0c44e4d2..d521cd05 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -181,7 +181,7 @@  nvkm_control_mthd_boost_info(struct nvkm_control *ctrl, void *data, u32 size)
 	if (!clk)
 		return -ENODEV;
 
-	if (!clk->base_khz && !clk->boost_khz)
+	if (!clk->base_limit.max_khz && !clk->boost_limit.max_khz)
 		return -ENODEV;
 
 	nvif_ioctl(&ctrl->object, "control boost info size %d\n", size);
@@ -192,8 +192,8 @@  nvkm_control_mthd_boost_info(struct nvkm_control *ctrl, void *data, u32 size)
 		return ret;
 
 	args->v0.mode = clk->boost_mode;
-	args->v0.base_mhz = clk->base_khz / 2000;
-	args->v0.boost_mhz = clk->boost_khz / 2000;
+	args->v0.base_mhz = clk->base_limit.max_khz / 2000;
+	args->v0.boost_mhz = clk->boost_limit.max_khz / 2000;
 	args->v0.max_mhz = clk->max_khz / 2000;
 	return 0;
 }
@@ -210,7 +210,7 @@  nvkm_control_mthd_boost_set(struct nvkm_control *ctrl, void *data, u32 size)
 	if (!clk)
 		return -ENODEV;
 
-	if (!clk->base_khz && !clk->boost_khz)
+	if (!clk->base_limit.max_khz && !clk->boost_limit.max_khz)
 		return -ENODEV;
 
 	nvif_ioctl(&ctrl->object, "control boost set size %d\n", size);
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 0fd92790..9f44ace0 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -87,14 +87,22 @@  nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate,
 	while (domain && domain->name != nv_clk_src_max) {
 		if (domain->flags & NVKM_CLK_DOM_FLAG_VPSTATE) {
 			u32 freq = cstate->domain[domain->name];
+			u32 limit;
 			switch (clk->boost_mode) {
 			case NVKM_CLK_BOOST_NONE:
-				if (clk->base_khz && freq > clk->base_khz)
-					return false;
+				limit = clk->base_limit.max_khz;
+				if (limit)
+					break;
 			case NVKM_CLK_BOOST_BIOS:
-				if (clk->boost_khz && freq > clk->boost_khz)
-					return false;
+				limit = clk->boost_limit.max_khz;
+				break;
+			default:
+				limit = 0;
+				break;
 			}
+
+			if (limit && freq > limit)
+				return false;
 		}
 		domain++;
 	}
@@ -729,6 +737,14 @@  nvkm_clk_parse_max_temp(struct nvkm_clk *clk)
 		   clk->max_temp, clk->relax_temp);
 }
 
+void static
+nvkm_clk_fill_limit(struct nvkm_clk_limit *l,
+		    const struct nvbios_vpstate_entry *e)
+{
+	l->pstate = e->pstate;
+	l->max_khz = e->clock_mhz * 1000;
+}
+
 int
 nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	      int index, bool allow_reclock, struct nvkm_clk *clk)
@@ -742,11 +758,11 @@  nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	nvkm_subdev_ctor(&nvkm_clk, device, index, subdev);
 
 	if (bios && !nvbios_vpstate_parse(bios, &h)) {
-		struct nvbios_vpstate_entry base, boost;
-		if (!nvbios_vpstate_entry(bios, &h, h.boost_id, &boost))
-			clk->boost_khz = boost.clock_mhz * 1000;
-		if (!nvbios_vpstate_entry(bios, &h, h.base_id, &base))
-			clk->base_khz = base.clock_mhz * 1000;
+		struct nvbios_vpstate_entry vpe;
+		if (!nvbios_vpstate_entry(bios, &h, h.boost_id, &vpe))
+			nvkm_clk_fill_limit(&clk->boost_limit, &vpe);
+		if (!nvbios_vpstate_entry(bios, &h, h.base_id, &vpe))
+			nvkm_clk_fill_limit(&clk->base_limit, &vpe);
 	}
 
 	clk->func = func;