[Nouveau] [RFC PATCH 26/29] clk: refactor the base and boost clock limits so that we can limit pstates as well
Karol Herbst
karolherbst at gmail.com
Fri Sep 15 17:11:26 UTC 2017
Signed-off-by: Karol Herbst <karolherbst at 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(-)
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;
--
2.14.1
More information about the Nouveau
mailing list