Re: [Nouveau] [PATCH v4 15/37] clk: allow boosting only when NvBoost is set

2016-04-19 Thread Martin Peres

On 18/04/16 22:13, Karol Herbst wrote:

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


As commented upon on IRC, I would prefer us to play it super safe and 
stick to the base
clock until we have power monitoring working, at which point we may make 
1 the default.


Please change it to keep my R-b :)

2: boost to max clock available

v2: moved into nvkm_cstate_valid
v4: check the existence of the clocks before limiting

Signed-off-by: Karol Herbst 
Reviewed-by: Martin Peres 
---
  drm/nouveau/include/nvkm/subdev/clk.h |  9 -
  drm/nouveau/nvkm/subdev/clk/base.c| 33 -
  drm/nouveau/nvkm/subdev/clk/gf100.c   |  2 +-
  drm/nouveau/nvkm/subdev/clk/gk104.c   |  2 +-
  4 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index 6226f0d..99ee05c 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -68,7 +68,8 @@ struct nvkm_pstate {
  struct nvkm_domain {
enum nv_clk_src name;
u8 bios; /* 0xff for none */
-#define NVKM_CLK_DOM_FLAG_CORE 0x01
+#define NVKM_CLK_DOM_FLAG_CORE0x01
+#define NVKM_CLK_DOM_FLAG_BASECLK 0x02
u8 flags;
const char *mname;
int mdiv;
@@ -98,6 +99,12 @@ struct nvkm_clk {
int dstate; /* display adjustment (min+) */
  
  	bool allow_reclock;

+#define NVKM_CLK_BOOST_NONE 0x0
+#define NVKM_CLK_BOOST_AVG  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

 * 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 21f6369..a9a3666 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -24,6 +24,7 @@
  #include "priv.h"
  
  #include 

+#include 
  #include 
  #include 
  #include 
@@ -77,9 +78,25 @@ nvkm_clk_adjust(struct nvkm_clk *clk, bool adjust,
  static bool
  nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate, u32 
max_volt, int temp)
  {
+   const struct nvkm_domain *domain = clk->domains;
struct nvkm_volt *volt = clk->subdev.device->volt;
int voltage;
  
+	while (domain && domain->name != nv_clk_src_max) {

+   if (domain->flags & NVKM_CLK_DOM_FLAG_BASECLK) {
+   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_AVG:
+   if (clk->boost_khz && freq > clk->boost_khz)
+   return false;
+   }
+   }
+   domain++;
+   }
+
if (!volt)
return true;
  
@@ -641,10 +658,24 @@ int

  nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
  int index, bool allow_reclock, struct nvkm_clk *clk)
  {
+   struct nvkm_subdev *subdev = >subdev;
+   struct nvkm_bios *bios = device->bios;
int ret, idx, arglen;
const char *mode;
+   struct nvbios_baseclk_header h;
+
+   nvkm_subdev_ctor(_clk, device, index, subdev);
+
+   clk->boost_mode = nvkm_longopt(device->cfgopt, "NvBoost",
+  NVKM_CLK_BOOST_AVG);
+   if (bios && !nvbios_baseclock_parse(bios, )) {
+   struct nvbios_baseclk_entry base, boost;
+   if (!nvbios_baseclock_entry(bios, , h.boost_id, ))
+   clk->boost_khz = boost.clock_mhz * 1000;
+   if (!nvbios_baseclock_entry(bios, , h.base_id, ))
+   clk->base_khz = base.clock_mhz * 1000;
+   }
  
-	nvkm_subdev_ctor(_clk, device, index, >subdev);

clk->func = func;
INIT_LIST_HEAD(>states);
clk->domains = func->domains;
diff --git a/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drm/nouveau/nvkm/subdev/clk/gf100.c
index 78c449b..71b7c9f 100644
--- a/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -443,7 +443,7 @@ gf100_clk = {
{ nv_clk_src_hubk06 , 0x00 },
{ nv_clk_src_hubk01 , 0x01 },
{ nv_clk_src_copy   , 0x02 },
-   { nv_clk_src_gpc, 0x03, 0, "core", 2000 },
+   { nv_clk_src_gpc, 0x03, NVKM_CLK_DOM_FLAG_BASECLK, "core", 
2000 },
{ nv_clk_src_rop, 0x04 },
{ nv_clk_src_mem, 0x05, 0, "memory", 1000 },
{ nv_clk_src_vdec   , 0x06 },
diff --git a/drm/nouveau/nvkm/subdev/clk/gk104.c 
b/drm/nouveau/nvkm/subdev/clk/gk104.c

[Nouveau] [PATCH v4 15/37] clk: allow boosting only when NvBoost is set

2016-04-18 Thread Karol Herbst
0: base clock from the vbios is max clock
1: boost only to boost clock from the vbios (default)
2: boost to max clock available

v2: moved into nvkm_cstate_valid
v4: check the existence of the clocks before limiting

Signed-off-by: Karol Herbst 
Reviewed-by: Martin Peres 
---
 drm/nouveau/include/nvkm/subdev/clk.h |  9 -
 drm/nouveau/nvkm/subdev/clk/base.c| 33 -
 drm/nouveau/nvkm/subdev/clk/gf100.c   |  2 +-
 drm/nouveau/nvkm/subdev/clk/gk104.c   |  2 +-
 4 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h 
b/drm/nouveau/include/nvkm/subdev/clk.h
index 6226f0d..99ee05c 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -68,7 +68,8 @@ struct nvkm_pstate {
 struct nvkm_domain {
enum nv_clk_src name;
u8 bios; /* 0xff for none */
-#define NVKM_CLK_DOM_FLAG_CORE 0x01
+#define NVKM_CLK_DOM_FLAG_CORE0x01
+#define NVKM_CLK_DOM_FLAG_BASECLK 0x02
u8 flags;
const char *mname;
int mdiv;
@@ -98,6 +99,12 @@ struct nvkm_clk {
int dstate; /* display adjustment (min+) */
 
bool allow_reclock;
+#define NVKM_CLK_BOOST_NONE 0x0
+#define NVKM_CLK_BOOST_AVG  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
 * 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 21f6369..a9a3666 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -24,6 +24,7 @@
 #include "priv.h"
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -77,9 +78,25 @@ nvkm_clk_adjust(struct nvkm_clk *clk, bool adjust,
 static bool
 nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate, u32 
max_volt, int temp)
 {
+   const struct nvkm_domain *domain = clk->domains;
struct nvkm_volt *volt = clk->subdev.device->volt;
int voltage;
 
+   while (domain && domain->name != nv_clk_src_max) {
+   if (domain->flags & NVKM_CLK_DOM_FLAG_BASECLK) {
+   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_AVG:
+   if (clk->boost_khz && freq > clk->boost_khz)
+   return false;
+   }
+   }
+   domain++;
+   }
+
if (!volt)
return true;
 
@@ -641,10 +658,24 @@ int
 nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
  int index, bool allow_reclock, struct nvkm_clk *clk)
 {
+   struct nvkm_subdev *subdev = >subdev;
+   struct nvkm_bios *bios = device->bios;
int ret, idx, arglen;
const char *mode;
+   struct nvbios_baseclk_header h;
+
+   nvkm_subdev_ctor(_clk, device, index, subdev);
+
+   clk->boost_mode = nvkm_longopt(device->cfgopt, "NvBoost",
+  NVKM_CLK_BOOST_AVG);
+   if (bios && !nvbios_baseclock_parse(bios, )) {
+   struct nvbios_baseclk_entry base, boost;
+   if (!nvbios_baseclock_entry(bios, , h.boost_id, ))
+   clk->boost_khz = boost.clock_mhz * 1000;
+   if (!nvbios_baseclock_entry(bios, , h.base_id, ))
+   clk->base_khz = base.clock_mhz * 1000;
+   }
 
-   nvkm_subdev_ctor(_clk, device, index, >subdev);
clk->func = func;
INIT_LIST_HEAD(>states);
clk->domains = func->domains;
diff --git a/drm/nouveau/nvkm/subdev/clk/gf100.c 
b/drm/nouveau/nvkm/subdev/clk/gf100.c
index 78c449b..71b7c9f 100644
--- a/drm/nouveau/nvkm/subdev/clk/gf100.c
+++ b/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -443,7 +443,7 @@ gf100_clk = {
{ nv_clk_src_hubk06 , 0x00 },
{ nv_clk_src_hubk01 , 0x01 },
{ nv_clk_src_copy   , 0x02 },
-   { nv_clk_src_gpc, 0x03, 0, "core", 2000 },
+   { nv_clk_src_gpc, 0x03, NVKM_CLK_DOM_FLAG_BASECLK, "core", 
2000 },
{ nv_clk_src_rop, 0x04 },
{ nv_clk_src_mem, 0x05, 0, "memory", 1000 },
{ nv_clk_src_vdec   , 0x06 },
diff --git a/drm/nouveau/nvkm/subdev/clk/gk104.c 
b/drm/nouveau/nvkm/subdev/clk/gk104.c
index 975c401..639234f 100644
--- a/drm/nouveau/nvkm/subdev/clk/gk104.c
+++ b/drm/nouveau/nvkm/subdev/clk/gk104.c
@@ -485,7 +485,7 @@ gk104_clk = {
.domains = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href   , 0xff },
-