[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