[Nouveau] [PATCH 15/32] clk: Refactor the base and boost clock limits so that we can limit pstates

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


Signed-off-by: Karol Herbst <karolherbst at gmail.com>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  9 +++++--
 drm/nouveau/nvkm/subdev/clk/base.c    | 51 +++++++++++++++++++++++------------
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 310df485..9e05b088 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;
@@ -109,8 +114,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;
 
 	/*XXX: die, these are here *only* to support the completely
 	 *     bat-shit insane what-was-nouveau_hw.c code
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index b2c1605e..657456ce 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -83,20 +83,28 @@ nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate,
 	const struct nvkm_domain *domain = clk->domains;
 	struct nvkm_volt *volt = clk->subdev.device->volt;
 	int voltage;
+	u32 limit;
 
-	while (domain && domain->name != nv_clk_src_max) {
-		if (domain->flags & NVKM_CLK_DOM_FLAG_VPSTATE) {
-			u32 freq = cstate->domain[domain->name];
-			switch (clk->boost_mode) {
-			case NVKM_CLK_BOOST_NONE:
-				if (clk->base_khz && freq > clk->base_khz)
-					return false;
-			case NVKM_CLK_BOOST_BIOS:
-				if (clk->boost_khz && freq > clk->boost_khz)
-					return false;
-			}
+	switch (clk->boost_mode) {
+	case NVKM_CLK_BOOST_NONE:
+		limit = clk->base_limit.max_khz;
+		if (limit)
+			break;
+	case NVKM_CLK_BOOST_BIOS:
+		limit = clk->boost_limit.max_khz;
+		break;
+	default:
+		limit = 0;
+		break;
+	}
+
+	if (limit) {
+		for (; domain && domain->name != nv_clk_src_max; domain++) {
+			if (!(domain->flags & NVKM_CLK_DOM_FLAG_VPSTATE))
+				continue;
+			if (cstate->domain[domain->name] > limit)
+				return false;
 		}
-		domain++;
 	}
 
 	if (!volt)
@@ -639,6 +647,14 @@ nvkm_clk = {
 	.fini = nvkm_clk_fini,
 };
 
+static void
+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)
@@ -652,11 +668,12 @@ 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;
-- 
2.15.0



More information about the Nouveau mailing list