Signed-off-by: Karol Herbst <karolher...@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 _______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/nouveau