Commit 4b9ce6e7 authored by Karol Herbst's avatar Karol Herbst Committed by Ben Skeggs

drm/nouveau/clk: Allow boosting only when NvBoost is set

0: base clock from the vbios is max clock (default)
1: boost only to boost clock from the vbios
2: boost to max clock available

v2: Moved into nvkm_cstate_valid.
v4: Check the existence of the clocks before limiting.
v5: Default to boost level 0.
Signed-off-by: default avatarKarol Herbst <karolherbst@gmail.com>
Reviewed-by: default avatarMartin Peres <martin.peres@free.fr>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f26493d2
...@@ -73,6 +73,7 @@ struct nvkm_domain { ...@@ -73,6 +73,7 @@ struct nvkm_domain {
enum nv_clk_src name; enum nv_clk_src name;
u8 bios; /* 0xff for none */ u8 bios; /* 0xff for none */
#define NVKM_CLK_DOM_FLAG_CORE 0x01 #define NVKM_CLK_DOM_FLAG_CORE 0x01
#define NVKM_CLK_DOM_FLAG_VPSTATE 0x02
u8 flags; u8 flags;
const char *mname; const char *mname;
int mdiv; int mdiv;
...@@ -102,6 +103,12 @@ struct nvkm_clk { ...@@ -102,6 +103,12 @@ struct nvkm_clk {
u8 temp; u8 temp;
bool allow_reclock; bool allow_reclock;
#define NVKM_CLK_BOOST_NONE 0x0
#define NVKM_CLK_BOOST_BIOS 0x1
#define NVKM_CLK_BOOST_FULL 0x2
u8 boost_mode;
u32 base_khz;
u32 boost_khz;
/*XXX: die, these are here *only* to support the completely /*XXX: die, these are here *only* to support the completely
* bat-shit insane what-was-nouveau_hw.c code * bat-shit insane what-was-nouveau_hw.c code
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <subdev/bios/boost.h> #include <subdev/bios/boost.h>
#include <subdev/bios/cstep.h> #include <subdev/bios/cstep.h>
#include <subdev/bios/perf.h> #include <subdev/bios/perf.h>
#include <subdev/bios/vpstate.h>
#include <subdev/fb.h> #include <subdev/fb.h>
#include <subdev/therm.h> #include <subdev/therm.h>
#include <subdev/volt.h> #include <subdev/volt.h>
...@@ -78,9 +79,25 @@ static bool ...@@ -78,9 +79,25 @@ static bool
nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate, nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate,
u32 max_volt, int temp) u32 max_volt, int temp)
{ {
const struct nvkm_domain *domain = clk->domains;
struct nvkm_volt *volt = clk->subdev.device->volt; struct nvkm_volt *volt = clk->subdev.device->volt;
int voltage; int voltage;
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;
}
}
domain++;
}
if (!volt) if (!volt)
return true; return true;
...@@ -635,10 +652,22 @@ int ...@@ -635,10 +652,22 @@ int
nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device, nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
int index, bool allow_reclock, struct nvkm_clk *clk) int index, bool allow_reclock, struct nvkm_clk *clk)
{ {
struct nvkm_subdev *subdev = &clk->subdev;
struct nvkm_bios *bios = device->bios;
int ret, idx, arglen; int ret, idx, arglen;
const char *mode; const char *mode;
struct nvbios_vpstate_header h;
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;
}
nvkm_subdev_ctor(&nvkm_clk, device, index, &clk->subdev);
clk->func = func; clk->func = func;
INIT_LIST_HEAD(&clk->states); INIT_LIST_HEAD(&clk->states);
clk->domains = func->domains; clk->domains = func->domains;
...@@ -681,6 +710,8 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device, ...@@ -681,6 +710,8 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
if (mode) if (mode)
clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen); clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen);
clk->boost_mode = nvkm_longopt(device->cfgopt, "NvBoost",
NVKM_CLK_BOOST_NONE);
return 0; return 0;
} }
......
...@@ -457,7 +457,7 @@ gf100_clk = { ...@@ -457,7 +457,7 @@ gf100_clk = {
{ nv_clk_src_hubk06 , 0x00 }, { nv_clk_src_hubk06 , 0x00 },
{ nv_clk_src_hubk01 , 0x01 }, { nv_clk_src_hubk01 , 0x01 },
{ nv_clk_src_copy , 0x02 }, { nv_clk_src_copy , 0x02 },
{ nv_clk_src_gpc , 0x03, 0, "core", 2000 }, { nv_clk_src_gpc , 0x03, NVKM_CLK_DOM_FLAG_VPSTATE, "core", 2000 },
{ nv_clk_src_rop , 0x04 }, { nv_clk_src_rop , 0x04 },
{ nv_clk_src_mem , 0x05, 0, "memory", 1000 }, { nv_clk_src_mem , 0x05, 0, "memory", 1000 },
{ nv_clk_src_vdec , 0x06 }, { nv_clk_src_vdec , 0x06 },
......
...@@ -491,7 +491,7 @@ gk104_clk = { ...@@ -491,7 +491,7 @@ gk104_clk = {
.domains = { .domains = {
{ nv_clk_src_crystal, 0xff }, { nv_clk_src_crystal, 0xff },
{ nv_clk_src_href , 0xff }, { nv_clk_src_href , 0xff },
{ nv_clk_src_gpc , 0x00, NVKM_CLK_DOM_FLAG_CORE, "core", 2000 }, { nv_clk_src_gpc , 0x00, NVKM_CLK_DOM_FLAG_CORE | NVKM_CLK_DOM_FLAG_VPSTATE, "core", 2000 },
{ nv_clk_src_hubk07 , 0x01, NVKM_CLK_DOM_FLAG_CORE }, { nv_clk_src_hubk07 , 0x01, NVKM_CLK_DOM_FLAG_CORE },
{ nv_clk_src_rop , 0x02, NVKM_CLK_DOM_FLAG_CORE }, { nv_clk_src_rop , 0x02, NVKM_CLK_DOM_FLAG_CORE },
{ nv_clk_src_mem , 0x03, 0, "memory", 500 }, { nv_clk_src_mem , 0x03, 0, "memory", 500 },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment