[Nouveau] [PATCH 28/32] clk: Implement limiting pstates just like we do for cstates
Karol Herbst
karolherbst at gmail.com
Fri Nov 17 00:04:32 UTC 2017
Signed-off-by: Karol Herbst <karolherbst at gmail.com>
---
drm/nouveau/nvkm/subdev/clk/base.c | 61 ++++++++++++++++++++++++++++++++------
1 file changed, 52 insertions(+), 9 deletions(-)
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index e94aee09..ce427eaa 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -287,6 +287,51 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
/******************************************************************************
* P-States
*****************************************************************************/
+static struct nvkm_pstate *
+nvkm_pstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate)
+{
+ u8 limit;
+
+ switch (clk->boost_mode) {
+ case NVKM_CLK_BOOST_NONE:
+ limit = clk->base_limit.pstate;
+ if (limit)
+ break;
+ case NVKM_CLK_BOOST_BIOS:
+ limit = clk->boost_limit.pstate;
+ break;
+ default:
+ limit = 0;
+ break;
+ }
+
+ if (!limit)
+ return pstate;
+
+ list_for_each_entry_from_reverse(pstate, &clk->pstates, head) {
+ if (limit >= pstate->id)
+ break;
+ }
+ return pstate;
+}
+
+static struct nvkm_pstate *
+nvkm_pstate_get(struct nvkm_clk *clk, int pstateid)
+{
+ struct nvkm_pstate *pstate;
+
+ switch (pstateid) {
+ case NVKM_CLK_PSTATE_BOOT:
+ return NULL;
+ default:
+ list_for_each_entry(pstate, &clk->pstates, head) {
+ if (pstate->id == pstateid)
+ return pstate;
+ }
+ }
+ return NULL;
+}
+
static int
nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_id)
{
@@ -299,19 +344,17 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_id)
if (pstate_id == NVKM_CLK_PSTATE_BOOT)
return 0;
- list_for_each_entry(pstate, &clk->pstates, head) {
- if (pstate->id == pstate_id)
- break;
- }
-
- if (clk->pstate_id == pstate_id)
- goto cstate;
+ pstate = nvkm_pstate_get(clk, pstate_id);
+ pstate = nvkm_pstate_find_best(clk, pstate);
if (!pstate)
return -EINVAL;
- nvkm_debug(subdev, "setting performance state %x\n", pstate_id);
- clk->pstate_id = pstate_id;
+ if (clk->pstate_id == pstate_id)
+ goto cstate;
+
+ 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);
--
2.15.0
More information about the Nouveau
mailing list