All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/29] Volting/Clocking improvements for Fermi and newer
@ 2016-04-07 21:23 Karol Herbst
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  0 siblings, 1 reply; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This is an updated series for the old clocking improvement one.

I think I got everything needed in place and also a simple update mechanism for
updating the cstates/voltage on temperature changes.

If anything is unclear how I REed or got the information, please leave a note
so that I can provide additional information in the commits.

Besides that I think we are pretty close now and only some minor improvements
are needed:
 * see if the factors differe on different GPUs (I only saw minor differences,
   which can be due to an inaccuracy retrieving the factors)
 * RE the factors on Voltage Map Tables with the Version 0x10 (usually Fermi)
 * add support for power budgets and watch over the power consumption, but for
   this we have to find out how to parse the budgets and map them to the rails
   or total power consumption.

I don't think those issues are critical, because by default this series doesn't
enable full boosting and we could also land the changes with capping the clocks
to the base clock to make sure we don't exceed any power budgets.

v3: adjust to temperature and minor fixes in the commits

Karol Herbst (29):
  bios/volt: handle voltage table version 0x50 with 0ed header
  volt: properly detect entry based voltage tables
  volt: save the voltage range we are able to set
  volt: add nvkm_volt_map_min function
  clk: don't create cstates whit voltages higher than what the gpu can
    do
  volt: parse the max voltage map entries
  volt: add min_id parameter to nvkm_volt_set_id
  clk: export nvkm_volt_map
  clk: add index field to nvkm_cstate
  add daemon to compare nouveau with blob voltage
  volt: add temperature parameter to nvkm_volt_map
  clk: fixup cstate selection
  clk: respect voltage limits in nvkm_cstate_prog
  bios: add parsing of BASE CLOCK table
  clk: allow boosting only when NvBoost is set
  volt: don't require perfect fit
  bios/vmap: unk0 field is the mode
  volt: add coefficients I found on my gpu
  clk: save the max clock we can set
  clk: rename nvkm_pstate_calc to nvkm_clk_update
  nvif: add boost info and set operations
  debugfs: add boost interface to change the boost_mode
  clk: remove dstate and tstate
  therm: don't cancel the timer
  clk: make pstate a pointer to nvkm_pstate
  clk: hold information about the current cstate status
  clk: we should pass the pstate id around not the index in the list
  clk: only do partial reclocks as required
  therm: trigger reclock in temperature daemon

 bin/nv_cmp_volt.c                                | 130 +++++++++
 drm/nouveau/include/nvif/if0001.h                |  15 ++
 drm/nouveau/include/nvkm/subdev/bios/baseclock.h |  24 ++
 drm/nouveau/include/nvkm/subdev/bios/vmap.h      |   5 +-
 drm/nouveau/include/nvkm/subdev/bios/volt.h      |   5 +-
 drm/nouveau/include/nvkm/subdev/clk.h            |  23 +-
 drm/nouveau/include/nvkm/subdev/volt.h           |  12 +-
 drm/nouveau/nouveau_debugfs.c                    |  76 ++++++
 drm/nouveau/nvkm/engine/device/ctrl.c            |  60 ++++-
 drm/nouveau/nvkm/subdev/bios/Kbuild              |   1 +
 drm/nouveau/nvkm/subdev/bios/baseclock.c         |  82 ++++++
 drm/nouveau/nvkm/subdev/bios/vmap.c              |  12 +-
 drm/nouveau/nvkm/subdev/bios/volt.c              |  45 ++--
 drm/nouveau/nvkm/subdev/clk/base.c               | 321 +++++++++++++++++------
 drm/nouveau/nvkm/subdev/clk/gf100.c              |   2 +-
 drm/nouveau/nvkm/subdev/clk/gk104.c              |   2 +-
 drm/nouveau/nvkm/subdev/pmu/gk20a.c              |  23 +-
 drm/nouveau/nvkm/subdev/therm/base.c             |  14 +-
 drm/nouveau/nvkm/subdev/volt/base.c              | 139 +++++++++-
 19 files changed, 838 insertions(+), 153 deletions(-)
 create mode 100644 bin/nv_cmp_volt.c
 create mode 100644 drm/nouveau/include/nvkm/subdev/bios/baseclock.h
 create mode 100644 drm/nouveau/nvkm/subdev/bios/baseclock.c

-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v3 01/29] bios/volt: handle voltage table version 0x50 with 0ed header
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 02/29] volt: properly detect entry based voltage tables Karol Herbst
                     ` (27 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Some Fermi+ gpus have no usefull header in the voltage table, which means
nouveau has to read the voltages out of the entries directly.

The mask may be bigger than 0x1fffff, but this value is already >2V, so it will
be fine for now.

This patch fixes volting issues on those cards enabling them to switch cstates.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Tested-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/nvkm/subdev/bios/volt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/bios/volt.c b/drm/nouveau/nvkm/subdev/bios/volt.c
index 6e0a336..81a47b2 100644
--- a/drm/nouveau/nvkm/subdev/bios/volt.c
+++ b/drm/nouveau/nvkm/subdev/bios/volt.c
@@ -142,7 +142,10 @@ nvbios_volt_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len,
 		info->vid     = nvbios_rd08(bios, volt + 0x01) >> 2;
 		break;
 	case 0x40:
+		break;
 	case 0x50:
+		info->voltage = nvbios_rd32(bios, volt) & 0x001fffff;
+		info->vid     = (nvbios_rd32(bios, volt) >> 23) & 0xff;
 		break;
 	}
 	return volt;
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 02/29] volt: properly detect entry based voltage tables
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  2016-04-07 21:23   ` [PATCH v3 01/29] bios/volt: handle voltage table version 0x50 with 0ed header Karol Herbst
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 03/29] volt: save the voltage range we are able to set Karol Herbst
                     ` (26 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

there is a field in the voltage table which tells us if the VIDs are taken from
the entries or calculated through the header.

v2: don't break older versions

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Tested-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/include/nvkm/subdev/bios/volt.h |  5 ++--
 drm/nouveau/nvkm/subdev/bios/volt.c         | 42 ++++++++++++++++-------------
 drm/nouveau/nvkm/subdev/volt/base.c         |  8 ++++--
 3 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/volt.h b/drm/nouveau/include/nvkm/subdev/bios/volt.h
index b0df610..0d91c24 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/volt.h
@@ -13,8 +13,9 @@ struct nvbios_volt {
 	u32 base;
 
 	/* GPIO mode */
-	u8  vidmask;
-	s16 step;
+	bool entry_based;
+	u8   vidmask;
+	s16  step;
 
 	/* PWM mode */
 	u32 pwm_freq;
diff --git a/drm/nouveau/nvkm/subdev/bios/volt.c b/drm/nouveau/nvkm/subdev/bios/volt.c
index 81a47b2..70e1f9d 100644
--- a/drm/nouveau/nvkm/subdev/bios/volt.c
+++ b/drm/nouveau/nvkm/subdev/bios/volt.c
@@ -73,30 +73,34 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
 	memset(info, 0x00, sizeof(*info));
 	switch (!!volt * *ver) {
 	case 0x12:
-		info->type    = NVBIOS_VOLT_GPIO;
-		info->vidmask = nvbios_rd08(bios, volt + 0x04);
+		info->type        = NVBIOS_VOLT_GPIO;
+		info->vidmask     = nvbios_rd08(bios, volt + 0x04);
+		info->entry_based = true;
 		break;
 	case 0x20:
-		info->type    = NVBIOS_VOLT_GPIO;
-		info->vidmask = nvbios_rd08(bios, volt + 0x05);
+		info->type        = NVBIOS_VOLT_GPIO;
+		info->vidmask     = nvbios_rd08(bios, volt + 0x05);
+		info->entry_based = true;
 		break;
 	case 0x30:
-		info->type    = NVBIOS_VOLT_GPIO;
-		info->vidmask = nvbios_rd08(bios, volt + 0x04);
+		info->type        = NVBIOS_VOLT_GPIO;
+		info->vidmask     = nvbios_rd08(bios, volt + 0x04);
+		info->entry_based = true;
 		break;
 	case 0x40:
-		info->type    = NVBIOS_VOLT_GPIO;
-		info->base    = nvbios_rd32(bios, volt + 0x04);
-		info->step    = nvbios_rd16(bios, volt + 0x08);
-		info->vidmask = nvbios_rd08(bios, volt + 0x0b);
+		info->type        = NVBIOS_VOLT_GPIO;
+		info->base        = nvbios_rd32(bios, volt + 0x04);
+		info->step        = nvbios_rd16(bios, volt + 0x08);
+		info->vidmask     = nvbios_rd08(bios, volt + 0x0b);
+		info->entry_based = false; /* XXX: find the flag byte */
 		/*XXX*/
-		info->min     = 0;
-		info->max     = info->base;
+		info->min         = 0;
+		info->max         = info->base;
 		break;
 	case 0x50:
-		info->min     = nvbios_rd32(bios, volt + 0x0a);
-		info->max     = nvbios_rd32(bios, volt + 0x0e);
-		info->base    = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff;
+		info->min  = nvbios_rd32(bios, volt + 0x0a);
+		info->max  = nvbios_rd32(bios, volt + 0x0e);
+		info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff;
 
 		/* offset 4 seems to be a flag byte */
 		if (nvbios_rd32(bios, volt + 0x4) & 1) {
@@ -104,9 +108,11 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
 			info->pwm_freq  = nvbios_rd32(bios, volt + 0x5) / 1000;
 			info->pwm_range = nvbios_rd32(bios, volt + 0x16);
 		} else {
-			info->type      = NVBIOS_VOLT_GPIO;
-			info->vidmask   = nvbios_rd08(bios, volt + 0x06);
-			info->step      = nvbios_rd16(bios, volt + 0x16);
+			info->type        = NVBIOS_VOLT_GPIO;
+			info->vidmask     = nvbios_rd08(bios, volt + 0x06);
+			info->step        = nvbios_rd16(bios, volt + 0x16);
+			info->entry_based =
+				!(nvbios_rd08(bios, volt + 0x4) & 0x2);
 		}
 		break;
 	}
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index 50b5649..ef653b1 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -112,6 +112,7 @@ nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition)
 static void
 nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
 {
+	struct nvkm_subdev *subdev = &bios->subdev;
 	struct nvbios_volt_entry ivid;
 	struct nvbios_volt info;
 	u8  ver, hdr, cnt, len;
@@ -119,7 +120,9 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
 	int i;
 
 	data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
-	if (data && info.vidmask && info.base && info.step) {
+	if (data && info.vidmask && info.base && info.step
+	    && !info.entry_based) {
+		nvkm_debug(subdev, "found header based VIDs\n");
 		for (i = 0; i < info.vidmask + 1; i++) {
 			if (info.base >= info.min &&
 				info.base <= info.max) {
@@ -130,7 +133,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
 			info.base += info.step;
 		}
 		volt->vid_mask = info.vidmask;
-	} else if (data && info.vidmask) {
+	} else if (data && info.vidmask && info.entry_based) {
+		nvkm_debug(subdev, "found entry based VIDs\n");
 		for (i = 0; i < cnt; i++) {
 			data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
 						       &ivid);
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 03/29] volt: save the voltage range we are able to set
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  2016-04-07 21:23   ` [PATCH v3 01/29] bios/volt: handle voltage table version 0x50 with 0ed header Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 02/29] volt: properly detect entry based voltage tables Karol Herbst
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 04/29] volt: add nvkm_volt_map_min function Karol Herbst
                     ` (25 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

We shouldn't set voltages below the min or above the max voltage the gpu is
able to set, so save the range.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Tested-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/include/nvkm/subdev/volt.h |  3 +++
 drm/nouveau/nvkm/subdev/volt/base.c    | 14 +++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h
index feff55c..b765f4f 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -12,6 +12,9 @@ struct nvkm_volt {
 		u32 uv;
 		u8 vid;
 	} vid[256];
+
+	u32 max_uv;
+	u32 min_uv;
 };
 
 int nvkm_volt_get(struct nvkm_volt *);
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index ef653b1..95fe065 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -123,6 +123,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
 	if (data && info.vidmask && info.base && info.step
 	    && !info.entry_based) {
 		nvkm_debug(subdev, "found header based VIDs\n");
+		volt->min_uv = info.min;
+		volt->max_uv = info.max;
 		for (i = 0; i < info.vidmask + 1; i++) {
 			if (info.base >= info.min &&
 				info.base <= info.max) {
@@ -135,6 +137,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
 		volt->vid_mask = info.vidmask;
 	} else if (data && info.vidmask && info.entry_based) {
 		nvkm_debug(subdev, "found entry based VIDs\n");
+		volt->min_uv = 0xffffffff;
+		volt->max_uv = 0;
 		for (i = 0; i < cnt; i++) {
 			data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
 						       &ivid);
@@ -142,9 +146,14 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
 				volt->vid[volt->vid_nr].uv = ivid.voltage;
 				volt->vid[volt->vid_nr].vid = ivid.vid;
 				volt->vid_nr++;
+				volt->min_uv = min(volt->min_uv, ivid.voltage);
+				volt->max_uv = max(volt->max_uv, ivid.voltage);
 			}
 		}
 		volt->vid_mask = info.vidmask;
+	} else if (data && info.type == NVBIOS_VOLT_PWM) {
+		volt->min_uv = info.base;
+		volt->max_uv = info.base + info.pwm_range;
 	}
 }
 
@@ -185,8 +194,11 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct nvkm_device *device,
 	volt->func = func;
 
 	/* Assuming the non-bios device should build the voltage table later */
-	if (bios)
+	if (bios) {
 		nvkm_volt_parse_bios(bios, volt);
+		nvkm_debug(&volt->subdev, "min: %iuv max: %iuv\n",
+			   volt->min_uv, volt->max_uv);
+	}
 
 	if (volt->vid_nr) {
 		for (i = 0; i < volt->vid_nr; i++) {
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 04/29] volt: add nvkm_volt_map_min function
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-04-07 21:23   ` [PATCH v3 03/29] volt: save the voltage range we are able to set Karol Herbst
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 05/29] clk: don't create cstates whit voltages higher than what the gpu can do Karol Herbst
                     ` (24 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

this is a copy of nvkm_volt_map, which always returns the lowest possible
voltage for a cstate.

nvkm_volt_map will get a temperature parameter there later and also fix the
voltage calculation, so that this functions will be completly different later.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Tested-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/include/nvkm/subdev/volt.h |  1 +
 drm/nouveau/nvkm/subdev/volt/base.c    | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h
index b765f4f..fc68825 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -17,6 +17,7 @@ struct nvkm_volt {
 	u32 min_uv;
 };
 
+int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
 int nvkm_volt_get(struct nvkm_volt *);
 int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition);
 
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index 95fe065..71094a9 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -65,6 +65,28 @@ nvkm_volt_set(struct nvkm_volt *volt, u32 uv)
 	return ret;
 }
 
+int
+nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
+{
+	struct nvkm_bios *bios = volt->subdev.device->bios;
+	struct nvbios_vmap_entry info;
+	u8  ver, len;
+	u16 vmap;
+
+	vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
+	if (vmap) {
+		if (info.link != 0xff) {
+			int ret = nvkm_volt_map_min(volt, info.link);
+			if (ret < 0)
+				return ret;
+			info.min += ret;
+		}
+		return info.min;
+	}
+
+	return id ? id * 10000 : -ENODEV;
+}
+
 static int
 nvkm_volt_map(struct nvkm_volt *volt, u8 id)
 {
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 05/29] clk: don't create cstates whit voltages higher than what the gpu can do
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (3 preceding siblings ...)
  2016-04-07 21:23   ` [PATCH v3 04/29] volt: add nvkm_volt_map_min function Karol Herbst
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 06/29] volt: parse the max voltage map entries Karol Herbst
                     ` (23 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Tested-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/nvkm/subdev/clk/base.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 889cce2..75122a2 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -138,6 +138,7 @@ static int
 nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
 {
 	struct nvkm_bios *bios = clk->subdev.device->bios;
+	struct nvkm_volt *volt = clk->subdev.device->volt;
 	const struct nvkm_domain *domain = clk->domains;
 	struct nvkm_cstate *cstate = NULL;
 	struct nvbios_cstepX cstepX;
@@ -148,6 +149,9 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
 	if (!data)
 		return -ENOENT;
 
+	if (volt && nvkm_volt_map_min(volt, cstepX.voltage) > volt->max_uv)
+		return -EINVAL;
+
 	cstate = kzalloc(sizeof(*cstate), GFP_KERNEL);
 	if (!cstate)
 		return -ENOMEM;
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 06/29] volt: parse the max voltage map entries
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (4 preceding siblings ...)
  2016-04-07 21:23   ` [PATCH v3 05/29] clk: don't create cstates whit voltages higher than what the gpu can do Karol Herbst
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 07/29] volt: add min_id parameter to nvkm_volt_set_id Karol Herbst
                     ` (22 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

There are at least three "max" entries, which specify the max voltage. Because
they are actually normal voltage map entries, they can also be affected by the
temperature.

Nvidia respects those entries and if they get changed, nvidia uses the lower
voltage from both.

We shouldn't exceed those voltages at any given time.

v2: state what those entries do in the source
v3: add the third max entry

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/bios/vmap.h |  3 +++
 drm/nouveau/include/nvkm/subdev/volt.h      |  5 +++++
 drm/nouveau/nvkm/subdev/bios/vmap.c         | 10 ++++++++++
 drm/nouveau/nvkm/subdev/volt/base.c         | 13 +++++++++++++
 4 files changed, 31 insertions(+)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/vmap.h b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
index 6633c6d..ae2f27b 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/vmap.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
@@ -1,6 +1,9 @@
 #ifndef __NVBIOS_VMAP_H__
 #define __NVBIOS_VMAP_H__
 struct nvbios_vmap {
+	u8  max0;
+	u8  max1;
+	u8  max2;
 };
 
 u16 nvbios_vmap_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h
index fc68825..285c6bf 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -15,6 +15,11 @@ struct nvkm_volt {
 
 	u32 max_uv;
 	u32 min_uv;
+
+	/* max voltage map entries, might be affected by temperature */
+	u8 max0_id;
+	u8 max1_id;
+	u8 max2_id;
 };
 
 int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
diff --git a/drm/nouveau/nvkm/subdev/bios/vmap.c b/drm/nouveau/nvkm/subdev/bios/vmap.c
index 2f13db7..f2295e1 100644
--- a/drm/nouveau/nvkm/subdev/bios/vmap.c
+++ b/drm/nouveau/nvkm/subdev/bios/vmap.c
@@ -61,7 +61,17 @@ nvbios_vmap_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
 	memset(info, 0x00, sizeof(*info));
 	switch (!!vmap * *ver) {
 	case 0x10:
+		info->max0 = 0xff;
+		info->max1 = 0xff;
+		info->max2 = 0xff;
+		break;
 	case 0x20:
+		info->max0 = nvbios_rd08(bios, vmap + 0x7);
+		info->max1 = nvbios_rd08(bios, vmap + 0x8);
+		if (*len >= 0xc)
+			info->max2 = nvbios_rd08(bios, vmap + 0xc);
+		else
+			info->max2 = 0xff;
 		break;
 	}
 	return vmap;
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index 71094a9..c3b1910 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -217,9 +217,22 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct nvkm_device *device,
 
 	/* Assuming the non-bios device should build the voltage table later */
 	if (bios) {
+		u8 ver, hdr, cnt, len;
+		struct nvbios_vmap vmap;
+
 		nvkm_volt_parse_bios(bios, volt);
 		nvkm_debug(&volt->subdev, "min: %iuv max: %iuv\n",
 			   volt->min_uv, volt->max_uv);
+
+		if (nvbios_vmap_parse(bios, &ver, &hdr, &cnt, &len, &vmap)) {
+			volt->max0_id = vmap.max0;
+			volt->max1_id = vmap.max1;
+			volt->max2_id = vmap.max2;
+		} else {
+			volt->max0_id = 0xff;
+			volt->max1_id = 0xff;
+			volt->max2_id = 0xff;
+		}
 	}
 
 	if (volt->vid_nr) {
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 07/29] volt: add min_id parameter to nvkm_volt_set_id
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (5 preceding siblings ...)
  2016-04-07 21:23   ` [PATCH v3 06/29] volt: parse the max voltage map entries Karol Herbst
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 08/29] clk: export nvkm_volt_map Karol Herbst
                     ` (21 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Each pstate has its own voltage map entry like each cstate has.

The voltages of those entries act as a floor value for the currently selected
pstate and nvidia never sets a voltage below them.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/include/nvkm/subdev/volt.h | 2 +-
 drm/nouveau/nvkm/subdev/clk/base.c     | 6 ++++--
 drm/nouveau/nvkm/subdev/volt/base.c    | 5 ++++-
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h
index 285c6bf..ec9d87d 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -24,7 +24,7 @@ struct nvkm_volt {
 
 int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
 int nvkm_volt_get(struct nvkm_volt *);
-int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition);
+int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, int condition);
 
 int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
 int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 75122a2..ee193cf 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -99,7 +99,8 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 	}
 
 	if (volt) {
-		ret = nvkm_volt_set_id(volt, cstate->voltage, +1);
+		ret = nvkm_volt_set_id(volt, cstate->voltage,
+				       pstate->base.voltage, +1);
 		if (ret && ret != -ENODEV) {
 			nvkm_error(subdev, "failed to raise voltage: %d\n", ret);
 			return ret;
@@ -113,7 +114,8 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 	}
 
 	if (volt) {
-		ret = nvkm_volt_set_id(volt, cstate->voltage, -1);
+		ret = nvkm_volt_set_id(volt, cstate->voltage,
+				       pstate->base.voltage, -1);
 		if (ret && ret != -ENODEV)
 			nvkm_error(subdev, "failed to lower voltage: %d\n", ret);
 	}
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index c3b1910..e085e05 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -110,7 +110,7 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
 }
 
 int
-nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition)
+nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, u8 min_id, int condition)
 {
 	int ret;
 
@@ -123,6 +123,9 @@ nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition)
 		if (!condition || prev < 0 ||
 		    (condition < 0 && ret < prev) ||
 		    (condition > 0 && ret > prev)) {
+			int min = nvkm_volt_map(volt, min_id);
+			if (min >= 0)
+				ret = max(min, ret);
 			ret = nvkm_volt_set(volt, ret);
 		} else {
 			ret = 0;
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 08/29] clk: export nvkm_volt_map
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (6 preceding siblings ...)
  2016-04-07 21:23   ` [PATCH v3 07/29] volt: add min_id parameter to nvkm_volt_set_id Karol Herbst
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:23   ` [PATCH v3 09/29] clk: add index field to nvkm_cstate Karol Herbst
                     ` (20 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

before clocking to a cstate, we have to check if the voltage is within the
allowed range.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/volt.h | 1 +
 drm/nouveau/nvkm/subdev/volt/base.c    | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h
index ec9d87d..870d212 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -22,6 +22,7 @@ struct nvkm_volt {
 	u8 max2_id;
 };
 
+int nvkm_volt_map(struct nvkm_volt *volt, u8 id);
 int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
 int nvkm_volt_get(struct nvkm_volt *);
 int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, int condition);
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index e085e05..69e7eef 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -87,7 +87,7 @@ nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
 	return id ? id * 10000 : -ENODEV;
 }
 
-static int
+int
 nvkm_volt_map(struct nvkm_volt *volt, u8 id)
 {
 	struct nvkm_bios *bios = volt->subdev.device->bios;
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 09/29] clk: add index field to nvkm_cstate
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (7 preceding siblings ...)
  2016-04-07 21:23   ` [PATCH v3 08/29] clk: export nvkm_volt_map Karol Herbst
@ 2016-04-07 21:23   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 10/29] add daemon to compare nouveau with blob voltage Karol Herbst
                     ` (19 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:23 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/clk.h | 1 +
 drm/nouveau/nvkm/subdev/clk/base.c    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index fb54417..6226f0d 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -52,6 +52,7 @@ struct nvkm_cstate {
 	struct list_head head;
 	u8  voltage;
 	u32 domain[nv_clk_src_max];
+	u8  cstate;
 };
 
 struct nvkm_pstate {
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index ee193cf..720434f 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -160,6 +160,7 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
 
 	*cstate = pstate->base;
 	cstate->voltage = cstepX.voltage;
+	cstate->cstate = idx;
 
 	while (domain && domain->name != nv_clk_src_max) {
 		if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) {
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 10/29] add daemon to compare nouveau with blob voltage
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (8 preceding siblings ...)
  2016-04-07 21:23   ` [PATCH v3 09/29] clk: add index field to nvkm_cstate Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 11/29] volt: add temperature parameter to nvkm_volt_map Karol Herbst
                     ` (18 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

this tool can be run alongside the nvidia driver to print information about
the current p/cstate, which voltage was set by nvidia and what nouveau would
set in the same situation.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 bin/nv_cmp_volt.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)
 create mode 100644 bin/nv_cmp_volt.c

diff --git a/bin/nv_cmp_volt.c b/bin/nv_cmp_volt.c
new file mode 100644
index 0000000..6147a7d
--- /dev/null
+++ b/bin/nv_cmp_volt.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2016 Karol Herbst
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst
+ */
+
+#include <nvif/client.h>
+#include <nvif/device.h>
+#include <nvif/class.h>
+
+#include <nvkm/subdev/volt.h>
+
+#include "util.h"
+
+int
+main(int argc, char **argv)
+{
+	struct nvif_client if_client;
+	struct nvif_device if_device;
+	struct nvkm_clk *clk;
+	struct nvkm_volt *volt;
+	struct nvkm_device *device;
+	int ret;
+	int old_voltage = 0, old_nouveau_voltage = 0, old_pstate = 0;
+	int old_cstate = 0, old_temp = 0;
+
+	ret = u_device("lib", argv[0], "error", true, true,
+                       (1ULL << NVKM_SUBDEV_CLK) |
+//                       (1ULL << NVKM_SUBDEV_FUSE) |
+                       (1ULL << NVKM_SUBDEV_GPIO) |
+//                       (1ULL << NVKM_SUBDEV_I2C) |
+                       (1ULL << NVKM_SUBDEV_PCI) |
+//                       (1ULL << NVKM_SUBDEV_THERM) |
+//                       (1ULL << NVKM_SUBDEV_TIMER) |
+                       (1ULL << NVKM_SUBDEV_VBIOS) |
+                       (1ULL << NVKM_SUBDEV_VOLT),
+                       0x00000000, &if_client, &if_device);
+
+	if (ret < 0)
+		return ret;
+
+	device = nvxx_device(&if_device);
+	clk = device->clk;
+//	therm = device->therm;
+	volt = device->volt;
+
+	printf("current voltage (µV), expected voltage (µV), abs diff (µV),"
+	       "rel diff nouveau/nvidia (%%), pstate, cstate, temperature"
+	       "(°C)\n");
+	while (true) {
+		int gpc_clock = nvkm_clk_read(clk, nv_clk_src_gpc);
+		int mem_clock = nvkm_clk_read(clk, nv_clk_src_mem);
+		struct nvkm_pstate *pstate = NULL, *best_pstate = NULL;
+		struct nvkm_cstate *cstate = NULL, *best_cstate = NULL;
+		int mem_err, gpc_err;
+		int new_voltage, new_nouveau_voltage, new_pstate, new_cstate;
+		int new_temp;
+
+		list_for_each_entry(pstate, &clk->states, head) {
+			list_for_each_entry(cstate, &pstate->list, head) {
+				if (!best_pstate) {
+					best_pstate = pstate;
+					best_cstate = cstate;
+					gpc_err = abs(cstate->domain[nv_clk_src_gpc] - gpc_clock);
+					mem_err = abs(cstate->domain[nv_clk_src_mem] - mem_clock);
+					continue;
+				}
+
+				if (abs(cstate->domain[nv_clk_src_gpc] - gpc_clock) <= gpc_err &&
+				    abs(cstate->domain[nv_clk_src_mem] - mem_clock) <= mem_err) {
+					best_pstate = pstate;
+					best_cstate = cstate;
+					gpc_err = abs(cstate->domain[nv_clk_src_gpc] - gpc_clock);
+					mem_err = abs(cstate->domain[nv_clk_src_mem] - mem_clock);
+				}
+			}
+
+			if (!best_pstate) {
+				best_pstate = pstate;
+				mem_err = abs(cstate->domain[nv_clk_src_mem] - mem_clock);
+				continue;
+			} else if (!best_cstate && (pstate->base.domain[nv_clk_src_mem] - mem_clock) <= mem_err) {
+				best_pstate = pstate;
+				mem_err = abs(cstate->domain[nv_clk_src_mem] - mem_clock);
+			}
+		}
+
+		if (!best_cstate)
+			best_cstate = &best_pstate->base;
+
+		new_voltage = nvkm_volt_get(volt);
+		new_temp = nvkm_rd32(device, 0x20400);//nvkm_therm_temp_get(therm);
+		new_nouveau_voltage = max(nvkm_volt_map(volt, best_cstate->voltage), nvkm_volt_map(volt, best_pstate->base.voltage));
+		new_pstate = best_pstate->pstate;
+		new_cstate = best_cstate->cstate;
+
+		if (new_voltage != old_voltage || new_nouveau_voltage != old_nouveau_voltage || new_pstate != old_pstate || new_cstate != old_cstate || new_temp != old_temp) {
+			old_voltage = new_voltage;
+			old_nouveau_voltage = new_nouveau_voltage;
+			old_pstate = new_pstate;
+			old_cstate = new_cstate;
+			old_temp = new_temp;
+			printf("%i, %i, %i, %f, %i, %i, %i\n", new_voltage,
+			       new_nouveau_voltage, new_nouveau_voltage - new_voltage,
+			       100 * (double)new_nouveau_voltage / new_voltage,
+			       new_pstate, new_cstate, new_temp);
+		}
+		usleep(100000);
+	}
+
+	return 0;
+}
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 11/29] volt: add temperature parameter to nvkm_volt_map
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (9 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 10/29] add daemon to compare nouveau with blob voltage Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 12/29] clk: fixup cstate selection Karol Herbst
                     ` (17 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

the voltage entries actually may map to a different voltage depending on the
current temperature.

v2: only read the temperatue when actually needed

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 bin/nv_cmp_volt.c                      |  2 +-
 drm/nouveau/include/nvkm/subdev/volt.h |  2 +-
 drm/nouveau/nvkm/subdev/volt/base.c    | 14 ++++++++++----
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/bin/nv_cmp_volt.c b/bin/nv_cmp_volt.c
index 6147a7d..16aa7e6 100644
--- a/bin/nv_cmp_volt.c
+++ b/bin/nv_cmp_volt.c
@@ -108,7 +108,7 @@ main(int argc, char **argv)
 
 		new_voltage = nvkm_volt_get(volt);
 		new_temp = nvkm_rd32(device, 0x20400);//nvkm_therm_temp_get(therm);
-		new_nouveau_voltage = max(nvkm_volt_map(volt, best_cstate->voltage), nvkm_volt_map(volt, best_pstate->base.voltage));
+		new_nouveau_voltage = max(nvkm_volt_map(volt, best_cstate->voltage, new_temp), nvkm_volt_map(volt, best_pstate->base.voltage, new_temp));
 		new_pstate = best_pstate->pstate;
 		new_cstate = best_cstate->cstate;
 
diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h
index 870d212..f223577 100644
--- a/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drm/nouveau/include/nvkm/subdev/volt.h
@@ -22,7 +22,7 @@ struct nvkm_volt {
 	u8 max2_id;
 };
 
-int nvkm_volt_map(struct nvkm_volt *volt, u8 id);
+int nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temperature);
 int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
 int nvkm_volt_get(struct nvkm_volt *);
 int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, int condition);
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index 69e7eef..a133b9c 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -26,6 +26,7 @@
 #include <subdev/bios.h>
 #include <subdev/bios/vmap.h>
 #include <subdev/bios/volt.h>
+#include <subdev/therm.h>
 
 int
 nvkm_volt_get(struct nvkm_volt *volt)
@@ -88,7 +89,7 @@ nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
 }
 
 int
-nvkm_volt_map(struct nvkm_volt *volt, u8 id)
+nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
 {
 	struct nvkm_bios *bios = volt->subdev.device->bios;
 	struct nvbios_vmap_entry info;
@@ -98,7 +99,7 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
 	vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
 	if (vmap) {
 		if (info.link != 0xff) {
-			int ret = nvkm_volt_map(volt, info.link);
+			int ret = nvkm_volt_map(volt, info.link, temp);
 			if (ret < 0)
 				return ret;
 			info.min += ret;
@@ -112,18 +113,23 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
 int
 nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, u8 min_id, int condition)
 {
+	struct nvkm_therm *therm = volt->subdev.device->therm;
 	int ret;
+	int temp = 0;
 
 	if (volt->func->set_id)
 		return volt->func->set_id(volt, id, condition);
 
-	ret = nvkm_volt_map(volt, id);
+	if (therm)
+		temp = nvkm_therm_temp_get(therm);
+
+	ret = nvkm_volt_map(volt, id, max(temp, 0));
 	if (ret >= 0) {
 		int prev = nvkm_volt_get(volt);
 		if (!condition || prev < 0 ||
 		    (condition < 0 && ret < prev) ||
 		    (condition > 0 && ret > prev)) {
-			int min = nvkm_volt_map(volt, min_id);
+			int min = nvkm_volt_map(volt, min_id, max(temp, 0));
 			if (min >= 0)
 				ret = max(min, ret);
 			ret = nvkm_volt_set(volt, ret);
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 12/29] clk: fixup cstate selection
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (10 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 11/29] volt: add temperature parameter to nvkm_volt_map Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 13/29] clk: respect voltage limits in nvkm_cstate_prog Karol Herbst
                     ` (16 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

now the cstatei parameter can be used of the nvkm_cstate_prog function to
select a specific cstate.

-1 is a magic value, which will always select the highest currently possible
cstate

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/clk/base.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 720434f..29478c7 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -85,7 +85,15 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 	int ret;
 
 	if (!list_empty(&pstate->list)) {
-		cstate = list_entry(pstate->list.prev, typeof(*cstate), head);
+		if (cstatei == -1)
+			cstate = list_entry(pstate->list.prev, typeof(*cstate),
+					    head);
+		else {
+			list_for_each_entry(cstate, &pstate->list, head) {
+				if (cstate->cstate == cstatei)
+					break;
+			}
+		}
 	} else {
 		cstate = &pstate->base;
 	}
@@ -207,7 +215,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 		ram->func->tidy(ram);
 	}
 
-	return nvkm_cstate_prog(clk, pstate, 0);
+	return nvkm_cstate_prog(clk, pstate, -1);
 }
 
 static void
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 13/29] clk: respect voltage limits in nvkm_cstate_prog
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (11 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 12/29] clk: fixup cstate selection Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 14/29] bios: add parsing of BASE CLOCK table Karol Herbst
                     ` (15 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

we should never allow to select a cstate which current voltage (depending on
the temperature) is higher than

1. the max volt entries in the voltage map table
2. what tha gpu actually can volt to.

this resolves all remaining volting errors on fermi and newer.

v3: use find_best for all cstates before actually trying
    add nvkm_cstate_get function to get cstate by index

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/clk/base.c | 83 +++++++++++++++++++++++++++++++++-----
 1 file changed, 74 insertions(+), 9 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 29478c7..0fda7b1 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -74,6 +74,78 @@ nvkm_clk_adjust(struct nvkm_clk *clk, bool adjust,
 /******************************************************************************
  * C-States
  *****************************************************************************/
+static bool
+nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate, u32 max_volt, int temp)
+{
+	struct nvkm_volt *volt = clk->subdev.device->volt;
+	int voltage;
+
+	if (!volt)
+		return true;
+
+	voltage = nvkm_volt_map(volt, cstate->voltage, temp);
+	if (voltage < 0)
+		return false;
+	return voltage <= min(max_volt, volt->max_uv) &&
+	       voltage >= volt->min_uv;
+}
+
+static struct nvkm_cstate *
+nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
+		      struct nvkm_cstate *start)
+{
+	struct nvkm_device *device = clk->subdev.device;
+	struct nvkm_therm *therm = device->therm;
+	struct nvkm_volt *volt = device->volt;
+	struct nvkm_cstate *cstate;
+	int max_volt, temp = 0;
+
+	if (!pstate || !start)
+		return NULL;
+
+	if (!volt)
+		return list_entry(pstate->list.prev, typeof(*cstate), head);
+
+	if (therm) {
+		/* ignore error code */
+		temp = max(0, nvkm_therm_temp_get(therm));
+	}
+
+	max_volt = volt->max_uv;
+	if (volt->max0_id != 0xff)
+		max_volt = min(max_volt,
+			       nvkm_volt_map(volt, volt->max0_id, temp));
+	if (volt->max1_id != 0xff)
+		max_volt = min(max_volt,
+			       nvkm_volt_map(volt, volt->max1_id, temp));
+	if (volt->max2_id != 0xff)
+		max_volt = min(max_volt,
+			       nvkm_volt_map(volt, volt->max2_id, temp));
+
+	for (cstate = start; &cstate->head != &pstate->list;
+	     cstate = list_entry(cstate->head.prev, typeof(*cstate), head)) {
+		if (nvkm_cstate_valid(clk, cstate, max_volt, temp))
+			break;
+	}
+
+	return cstate;
+}
+
+static struct nvkm_cstate *
+nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
+{
+	struct nvkm_cstate *cstate;
+	if (cstatei == -1)
+		return list_entry(pstate->list.prev, typeof(*cstate), head);
+	else {
+		list_for_each_entry(cstate, &pstate->list, head) {
+			if (cstate->cstate == cstatei)
+				return cstate;
+		}
+	}
+	return NULL;
+}
+
 static int
 nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 {
@@ -85,15 +157,8 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 	int ret;
 
 	if (!list_empty(&pstate->list)) {
-		if (cstatei == -1)
-			cstate = list_entry(pstate->list.prev, typeof(*cstate),
-					    head);
-		else {
-			list_for_each_entry(cstate, &pstate->list, head) {
-				if (cstate->cstate == cstatei)
-					break;
-			}
-		}
+		cstate = nvkm_cstate_get(clk, pstate, cstatei);
+		cstate = nvkm_cstate_find_best(clk, pstate, cstate);
 	} else {
 		cstate = &pstate->base;
 	}
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 14/29] bios: add parsing of BASE CLOCK table
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (12 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 13/29] clk: respect voltage limits in nvkm_cstate_prog Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 15/29] clk: allow boosting only when NvBoost is set Karol Herbst
                     ` (14 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

this table contains three important clocks:

base  clock: this is the non boosted max clock
tdp   clock: the clock at wich the vbios guarentees the TDP won't ever be
             exceeded at max load (seems to be always the same as the base
             clock, but behaves differently).
boost clock: the avg clock the gpu will stay boosted to. It doesn't seem to
             affect the behaviour of the nvidia driver at all though.

v2: make clear that base/boost/tdp fields are ids

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/include/nvkm/subdev/bios/baseclock.h | 24 +++++++
 drm/nouveau/nvkm/subdev/bios/Kbuild              |  1 +
 drm/nouveau/nvkm/subdev/bios/baseclock.c         | 82 ++++++++++++++++++++++++
 3 files changed, 107 insertions(+)
 create mode 100644 drm/nouveau/include/nvkm/subdev/bios/baseclock.h
 create mode 100644 drm/nouveau/nvkm/subdev/bios/baseclock.c

diff --git a/drm/nouveau/include/nvkm/subdev/bios/baseclock.h b/drm/nouveau/include/nvkm/subdev/bios/baseclock.h
new file mode 100644
index 0000000..ed6a3e6
--- /dev/null
+++ b/drm/nouveau/include/nvkm/subdev/bios/baseclock.h
@@ -0,0 +1,24 @@
+#ifndef __NVBIOS_BASECLOCK_H__
+#define __NVBIOS_BASECLOCK_H__
+struct nvbios_baseclk_header {
+	u16 offset;
+
+	u8 version;
+	u8 hlen;
+	u8 ecount;
+	u8 elen;
+	u8 scount;
+	u8 slen;
+
+	u8 base_id;
+	u8 boost_id;
+	u8 tdp_id;
+};
+struct nvbios_baseclk_entry {
+	u8  pstate;
+	u16 clock_mhz;
+};
+int nvbios_baseclock_parse(struct nvkm_bios *, struct nvbios_baseclk_header *);
+int nvbios_baseclock_entry(struct nvkm_bios *, struct nvbios_baseclk_header *,
+			   u8 idx, struct nvbios_baseclk_entry *);
+#endif
diff --git a/drm/nouveau/nvkm/subdev/bios/Kbuild b/drm/nouveau/nvkm/subdev/bios/Kbuild
index dbcb0ef..6cb3beb 100644
--- a/drm/nouveau/nvkm/subdev/bios/Kbuild
+++ b/drm/nouveau/nvkm/subdev/bios/Kbuild
@@ -1,4 +1,5 @@
 nvkm-y += nvkm/subdev/bios/base.o
+nvkm-y += nvkm/subdev/bios/baseclock.o
 nvkm-y += nvkm/subdev/bios/bit.o
 nvkm-y += nvkm/subdev/bios/boost.o
 nvkm-y += nvkm/subdev/bios/conn.o
diff --git a/drm/nouveau/nvkm/subdev/bios/baseclock.c b/drm/nouveau/nvkm/subdev/bios/baseclock.c
new file mode 100644
index 0000000..3c961e2
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/bios/baseclock.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Karol Herbst
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst
+ */
+#include <subdev/bios.h>
+#include <subdev/bios/bit.h>
+#include <subdev/bios/baseclock.h>
+
+static u16
+nvbios_baseclock_offset(struct nvkm_bios *b)
+{
+	struct bit_entry bit_P;
+
+	if (!bit_entry(b, 'P', &bit_P)) {
+		if (bit_P.version == 2)
+			return nvbios_rd16(b, bit_P.offset + 0x38);
+	}
+
+	return 0x0000;
+}
+
+int
+nvbios_baseclock_parse(struct nvkm_bios *b, struct nvbios_baseclk_header *h)
+{
+	if (!h)
+		return -EINVAL;
+
+	h->offset = nvbios_baseclock_offset(b);
+	if (!h->offset)
+		return -ENODEV;
+
+	h->version = nvbios_rd08(b, h->offset);
+	switch (h->version) {
+	case 0x10:
+		h->hlen     = nvbios_rd08(b, h->offset + 0x1);
+		h->elen     = nvbios_rd08(b, h->offset + 0x2);
+		h->slen     = nvbios_rd08(b, h->offset + 0x3);
+		h->scount   = nvbios_rd08(b, h->offset + 0x4);
+		h->ecount   = nvbios_rd08(b, h->offset + 0x5);
+
+		h->base_id  = nvbios_rd08(b, h->offset + 0x0f);
+		h->boost_id = nvbios_rd08(b, h->offset + 0x10);
+		h->tdp_id   = nvbios_rd08(b, h->offset + 0x11);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int
+nvbios_baseclock_entry(struct nvkm_bios *b, struct nvbios_baseclk_header *h,
+		       u8 idx, struct nvbios_baseclk_entry *e)
+{
+	u16 offset;
+
+	if (!e || !h || idx > h->ecount)
+		return -EINVAL;
+
+	offset = h->offset + h->hlen + idx * (h->elen + (h->slen * h->scount));
+	e->pstate    = nvbios_rd08(b, offset);
+	e->clock_mhz = nvbios_rd16(b, offset + 0x5);
+	return 0;
+}
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 15/29] clk: allow boosting only when NvBoost is set
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (13 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 14/29] bios: add parsing of BASE CLOCK table Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 16/29] volt: don't require perfect fit Karol Herbst
                     ` (13 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 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_CORE    0x01
+#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 0fda7b1..4e1b9d7 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 <subdev/bios.h>
+#include <subdev/bios/baseclock.h>
 #include <subdev/bios/boost.h>
 #include <subdev/bios/cstep.h>
 #include <subdev/bios/perf.h>
@@ -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 (freq > clk->base_khz)
+					return false;
+			case NVKM_CLK_BOOST_AVG:
+				if (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 = &clk->subdev;
+	struct nvkm_bios *bios = device->bios;
 	int ret, idx, arglen;
 	const char *mode;
+	struct nvbios_baseclk_header h;
+
+	nvkm_subdev_ctor(&nvkm_clk, device, index, 0, subdev);
+
+	clk->boost_mode = nvkm_longopt(device->cfgopt, "NvBoost",
+				       NVKM_CLK_BOOST_AVG);
+	if (bios && !nvbios_baseclock_parse(bios, &h)) {
+		struct nvbios_baseclk_entry base, boost;
+		if (!nvbios_baseclock_entry(bios, &h, h.boost_id, &boost))
+			clk->boost_khz = boost.clock_mhz * 1000;
+		if (!nvbios_baseclock_entry(bios, &h, h.base_id, &base))
+			clk->base_khz = base.clock_mhz * 1000;
+	}
 
-	nvkm_subdev_ctor(&nvkm_clk, device, index, 0, &clk->subdev);
 	clk->func = func;
 	INIT_LIST_HEAD(&clk->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 },
-		{ 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_BASECLK, "core", 2000 },
 		{ nv_clk_src_hubk07 , 0x01, NVKM_CLK_DOM_FLAG_CORE },
 		{ nv_clk_src_rop    , 0x02, NVKM_CLK_DOM_FLAG_CORE },
 		{ nv_clk_src_mem    , 0x03, 0, "memory", 500 },
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 16/29] volt: don't require perfect fit
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (14 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 15/29] clk: allow boosting only when NvBoost is set Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 17/29] bios/vmap: unk0 field is the mode Karol Herbst
                     ` (12 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

if we calculate the voltage in the table right, we get all kinds of values,
which never fit the hardware steps, so we use the closest higher value the
hardware can do.

v3: simplify the implementation

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/volt/base.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index a133b9c..552fecd 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -51,18 +51,30 @@ static int
 nvkm_volt_set(struct nvkm_volt *volt, u32 uv)
 {
 	struct nvkm_subdev *subdev = &volt->subdev;
-	int i, ret = -EINVAL;
+	int i, ret = -EINVAL, best_err = uv, best = -1;
 
 	if (volt->func->volt_set)
 		return volt->func->volt_set(volt, uv);
 
 	for (i = 0; i < volt->vid_nr; i++) {
-		if (volt->vid[i].uv == uv) {
-			ret = volt->func->vid_set(volt, volt->vid[i].vid);
-			nvkm_debug(subdev, "set %duv: %d\n", uv, ret);
+		int err = volt->vid[i].uv - uv;
+		if (err < 0 || err > best_err)
+			continue;
+
+		best_err = err;
+		best = i;
+		if (best_err == 0)
 			break;
-		}
 	}
+
+	if (best == -1) {
+		nvkm_error(subdev, "couldn't set %iuv\n", uv);
+		return ret;
+	}
+
+	ret = volt->func->vid_set(volt, volt->vid[best].vid);
+	nvkm_debug(subdev, "set req %duv to %duv: %d\n", uv,
+		   volt->vid[best].uv, ret);
 	return ret;
 }
 
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 17/29] bios/vmap: unk0 field is the mode
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (15 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 16/29] volt: don't require perfect fit Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 18/29] volt: add coefficients I found on my gpu Karol Herbst
                     ` (11 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

this selects which formula is used to calculate the voltage.

depending on the value, the entry maps to a different voltage and even enables
if the temperature has any effect or not. This is easy to observe with the
binary driver.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/bios/vmap.h | 2 +-
 drm/nouveau/nvkm/subdev/bios/vmap.c         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/vmap.h b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
index ae2f27b..8fa1294 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/vmap.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
@@ -11,7 +11,7 @@ u16 nvbios_vmap_parse(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
 		      struct nvbios_vmap *);
 
 struct nvbios_vmap_entry {
-	u8  unk0;
+	u8  mode;
 	u8  link;
 	u32 min;
 	u32 max;
diff --git a/drm/nouveau/nvkm/subdev/bios/vmap.c b/drm/nouveau/nvkm/subdev/bios/vmap.c
index f2295e1..32bd8b1 100644
--- a/drm/nouveau/nvkm/subdev/bios/vmap.c
+++ b/drm/nouveau/nvkm/subdev/bios/vmap.c
@@ -105,7 +105,7 @@ nvbios_vmap_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len,
 		info->arg[2] = nvbios_rd32(bios, vmap + 0x10);
 		break;
 	case 0x20:
-		info->unk0   = nvbios_rd08(bios, vmap + 0x00);
+		info->mode   = nvbios_rd08(bios, vmap + 0x00);
 		info->link   = nvbios_rd08(bios, vmap + 0x01);
 		info->min    = nvbios_rd32(bios, vmap + 0x02);
 		info->max    = nvbios_rd32(bios, vmap + 0x06);
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 18/29] volt: add coefficients I found on my gpu
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (16 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 17/29] bios/vmap: unk0 field is the mode Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 19/29] clk: save the max clock we can set Karol Herbst
                     ` (10 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

I am sure that those are a bit different on other GPUs, but while testing
the error range compared to nvidia was around 100%+-3%.

Without this change we are most of the time around 10% below nvidias voltage,
so this change causes no harm and improves the situation a lot already.

The remaining task for this is to figure out which of these constants are
chip specific and from where to get the chip specific factors

These coefficients were REed by modifing the voltage map entries and by
calculating the set voltage back until I was able to forecast which voltage
nvidia sets for a given voltage map entry.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/volt/base.c | 53 ++++++++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 6 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index 552fecd..654b88e 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -110,13 +110,54 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
 
 	vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
 	if (vmap) {
-		if (info.link != 0xff) {
-			int ret = nvkm_volt_map(volt, info.link, temp);
-			if (ret < 0)
-				return ret;
-			info.min += ret;
+		switch (ver) {
+		case 0x10:
+			if (info.link != 0xff) {
+				int ret = nvkm_volt_map(volt, info.link, temp);
+				if (ret < 0)
+					return ret;
+				info.min += ret;
+			}
+			return info.min;
+		case 0x20: {
+			s32 result;
+			switch (info.mode) {
+			case 0x0:
+				result =  info.arg[0] / 10;
+				result += info.arg[1] * 168;
+				result += info.arg[2] * 28;
+				break;
+			case 0x1:
+				result =  (info.arg[0] / 1675) * 100;
+				result += info.arg[1]          * 100;
+				result += (info.arg[2] / 10)   * 153 * temp;
+				result += info.arg[3]          * 100 * temp;
+				result += info.arg[4]          * 41;
+				result += (info.arg[5] * (temp * temp)) / 15;
+				break;
+			case 0x3:
+				result = (info.min + info.max) / 2;
+				break;
+			case 0x2:
+			default:
+				result = info.min;
+				break;
+			}
+			result = min(max(result, (s32)info.min),
+				     (s32)info.max);
+
+			if (info.link != 0xff) {
+				int ret = nvkm_volt_map(volt, info.link, temp);
+				if (ret < 0)
+					return ret;
+				result += ret;
+			}
+
+			return result;
+		}
+		default:
+			return -ENODEV;
 		}
-		return info.min;
 	}
 
 	return id ? id * 10000 : -ENODEV;
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 19/29] clk: save the max clock we can set
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (17 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 18/29] volt: add coefficients I found on my gpu Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 20/29] clk: rename nvkm_pstate_calc to nvkm_clk_update Karol Herbst
                     ` (9 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/clk.h | 1 +
 drm/nouveau/nvkm/subdev/clk/base.c    | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 99ee05c..61d99fd 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -105,6 +105,7 @@ struct nvkm_clk {
 	u8  boost_mode;
 	u32 base_khz;
 	u32 boost_khz;
+	u32 max_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 4e1b9d7..d058f8f 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -257,6 +257,8 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
 			u32 freq = nvkm_clk_adjust(clk, true, pstate->pstate,
 						   domain->bios, cstepX.freq);
 			cstate->domain[domain->name] = freq;
+			if (domain->flags & NVKM_CLK_DOM_FLAG_BASECLK)
+				clk->max_khz = max(clk->max_khz, freq);
 		}
 		domain++;
 	}
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 20/29] clk: rename nvkm_pstate_calc to nvkm_clk_update
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (18 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 19/29] clk: save the max clock we can set Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 21/29] nvif: add boost info and set operations Karol Herbst
                     ` (8 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

this function will be used to update the current clock state.

This will happen for various reasons:
 * temperature changes (may change cstate and/or voltage)
 * user changes boost mode
 * load changes

v2: add wait parameter

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  1 +
 drm/nouveau/nvkm/subdev/clk/base.c    | 46 ++++++++++++++++++++---------------
 2 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 61d99fd..77d94c1 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -120,6 +120,7 @@ int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
 int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
 int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
 int nvkm_clk_tstate(struct nvkm_clk *, int req, int rel);
+int nvkm_clk_update(struct nvkm_clk *, bool wait);
 
 int nv04_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
 int nv40_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index d058f8f..ddbb690 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -274,11 +274,14 @@ static int
 nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 {
 	struct nvkm_subdev *subdev = &clk->subdev;
-	struct nvkm_ram *ram = subdev->device->fb->ram;
+	struct nvkm_fb *fb = subdev->device->fb;
 	struct nvkm_pci *pci = subdev->device->pci;
 	struct nvkm_pstate *pstate;
 	int ret, idx = 0;
 
+	if (pstatei == -1)
+		return 0;
+
 	list_for_each_entry(pstate, &clk->states, head) {
 		if (idx++ == pstatei)
 			break;
@@ -289,7 +292,8 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 
 	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
 
-	if (ram && ram->func->calc) {
+	if (fb && fb->ram && fb->ram->func->calc) {
+		struct nvkm_ram *ram = fb->ram;
 		int khz = pstate->base.domain[nv_clk_src_mem];
 		do {
 			ret = ram->func->calc(ram, khz);
@@ -303,11 +307,11 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 }
 
 static void
-nvkm_pstate_work(struct work_struct *work)
+nvkm_clk_update_work(struct work_struct *work)
 {
 	struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
 	struct nvkm_subdev *subdev = &clk->subdev;
-	int pstate;
+	int pstate, ret;
 
 	if (!atomic_xchg(&clk->waiting, 0))
 		return;
@@ -327,21 +331,25 @@ nvkm_pstate_work(struct work_struct *work)
 	}
 
 	nvkm_trace(subdev, "-> %d\n", pstate);
-	if (pstate != clk->pstate) {
-		int ret = nvkm_pstate_prog(clk, pstate);
-		if (ret) {
-			nvkm_error(subdev, "error setting pstate %d: %d\n",
-				   pstate, ret);
-		}
+	ret = nvkm_pstate_prog(clk, pstate);
+	if (ret) {
+		nvkm_error(subdev, "error setting pstate %d: %d\n",
+			   pstate, ret);
 	}
 
 	wake_up_all(&clk->wait);
 	nvkm_notify_get(&clk->pwrsrc_ntfy);
 }
 
-static int
-nvkm_pstate_calc(struct nvkm_clk *clk, bool wait)
+int
+nvkm_clk_update(struct nvkm_clk *clk, bool wait)
 {
+	if (!clk)
+		return -EINVAL;
+
+	if (!clk->allow_reclock)
+		return -ENODEV;
+
 	atomic_set(&clk->waiting, 1);
 	schedule_work(&clk->work);
 	if (wait)
@@ -531,7 +539,7 @@ nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
 	if (ret >= 0) {
 		if (ret -= 2, pwr) clk->ustate_ac = ret;
 		else		   clk->ustate_dc = ret;
-		return nvkm_pstate_calc(clk, true);
+		return nvkm_clk_update(clk, true);
 	}
 	return ret;
 }
@@ -543,7 +551,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
 	if ( rel) clk->astate += rel;
 	clk->astate = min(clk->astate, clk->state_nr - 1);
 	clk->astate = max(clk->astate, 0);
-	return nvkm_pstate_calc(clk, wait);
+	return nvkm_clk_update(clk, wait);
 }
 
 int
@@ -553,7 +561,7 @@ nvkm_clk_tstate(struct nvkm_clk *clk, int req, int rel)
 	if ( rel) clk->tstate += rel;
 	clk->tstate = min(clk->tstate, 0);
 	clk->tstate = max(clk->tstate, -(clk->state_nr - 1));
-	return nvkm_pstate_calc(clk, true);
+	return nvkm_clk_update(clk, true);
 }
 
 int
@@ -563,7 +571,7 @@ nvkm_clk_dstate(struct nvkm_clk *clk, int req, int rel)
 	if ( rel) clk->dstate += rel;
 	clk->dstate = min(clk->dstate, clk->state_nr - 1);
 	clk->dstate = max(clk->dstate, 0);
-	return nvkm_pstate_calc(clk, true);
+	return nvkm_clk_update(clk, true);
 }
 
 static int
@@ -571,7 +579,7 @@ nvkm_clk_pwrsrc(struct nvkm_notify *notify)
 {
 	struct nvkm_clk *clk =
 		container_of(notify, typeof(*clk), pwrsrc_ntfy);
-	nvkm_pstate_calc(clk, false);
+	nvkm_clk_update(clk, false);
 	return NVKM_NOTIFY_DROP;
 }
 
@@ -626,7 +634,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 	clk->tstate = 0;
 	clk->dstate = 0;
 	clk->pstate = -1;
-	nvkm_pstate_calc(clk, true);
+	nvkm_clk_update(clk, true);
 	return 0;
 }
 
@@ -685,7 +693,7 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	clk->ustate_dc = -1;
 	clk->allow_reclock = allow_reclock;
 
-	INIT_WORK(&clk->work, nvkm_pstate_work);
+	INIT_WORK(&clk->work, nvkm_clk_update_work);
 	init_waitqueue_head(&clk->wait);
 	atomic_set(&clk->waiting, 0);
 
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 21/29] nvif: add boost info and set operations
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (19 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 20/29] clk: rename nvkm_pstate_calc to nvkm_clk_update Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 22/29] debugfs: add boost interface to change the boost_mode Karol Herbst
                     ` (7 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/include/nvif/if0001.h     | 15 ++++++++++
 drm/nouveau/nvkm/engine/device/ctrl.c | 55 +++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/drm/nouveau/include/nvif/if0001.h b/drm/nouveau/include/nvif/if0001.h
index bd5b641..e4acd19 100644
--- a/drm/nouveau/include/nvif/if0001.h
+++ b/drm/nouveau/include/nvif/if0001.h
@@ -4,6 +4,8 @@
 #define NVIF_CONTROL_PSTATE_INFO                                           0x00
 #define NVIF_CONTROL_PSTATE_ATTR                                           0x01
 #define NVIF_CONTROL_PSTATE_USER                                           0x02
+#define NVIF_CONTROL_BOOST_INFO                                            0x03
+#define NVIF_CONTROL_BOOST_SET                                             0x04
 
 struct nvif_control_pstate_info_v0 {
 	__u8  version;
@@ -43,4 +45,17 @@ struct nvif_control_pstate_user_v0 {
 	__s8  pwrsrc; /*  in: target power source */
 	__u8  pad03[5];
 };
+
+struct nvif_control_boost_info_v0 {
+	__u8  version;
+	__u8  mode;
+	__u16 base_mhz;
+	__u16 boost_mhz;
+	__u16 max_mhz;
+};
+
+struct nvif_control_boost_set_v0 {
+	__u8  version;
+	__u8  mode;
+};
 #endif
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c b/drm/nouveau/nvkm/engine/device/ctrl.c
index b0ece71..039e8a4 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -167,6 +167,57 @@ nvkm_control_mthd_pstate_user(struct nvkm_control *ctrl, void *data, u32 size)
 }
 
 static int
+nvkm_control_mthd_boost_info(struct nvkm_control *ctrl, void *data, u32 size)
+{
+	union {
+		struct nvif_control_boost_info_v0 v0;
+	} *args = data;
+	struct nvkm_clk *clk = ctrl->device->clk;
+	int ret = -ENOSYS;
+
+	nvif_ioctl(&ctrl->object, "control boost info size %d\n", size);
+	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+		nvif_ioctl(&ctrl->object, "control boost info vers %d\n",
+			   args->v0.version);
+	} else
+		return ret;
+
+	if (!clk)
+		return -ENODEV;
+
+	args->v0.mode = clk->boost_mode;
+	args->v0.base_mhz = clk->base_khz / 2000;
+	args->v0.boost_mhz = clk->boost_khz / 2000;
+	args->v0.max_mhz = clk->max_khz / 2000;
+	return 0;
+}
+
+static int
+nvkm_control_mthd_boost_set(struct nvkm_control *ctrl, void *data, u32 size)
+{
+	union {
+		struct nvif_control_boost_set_v0 v0;
+	} *args = data;
+	struct nvkm_clk *clk = ctrl->device->clk;
+	int ret = -ENOSYS;
+
+	nvif_ioctl(&ctrl->object, "control boost set size %d\n", size);
+	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+		nvif_ioctl(&ctrl->object, "control boost set vers %d\n",
+			   args->v0.version);
+	} else
+		return ret;
+
+	if (!clk)
+		return -ENODEV;
+
+	if (args->v0.mode > 2)
+		return -EINVAL;
+	clk->boost_mode = args->v0.mode;
+	return nvkm_clk_update(clk, true);
+}
+
+static int
 nvkm_control_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 {
 	struct nvkm_control *ctrl = nvkm_control(object);
@@ -177,6 +228,10 @@ nvkm_control_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 		return nvkm_control_mthd_pstate_attr(ctrl, data, size);
 	case NVIF_CONTROL_PSTATE_USER:
 		return nvkm_control_mthd_pstate_user(ctrl, data, size);
+	case NVIF_CONTROL_BOOST_INFO:
+		return nvkm_control_mthd_boost_info(ctrl, data, size);
+	case NVIF_CONTROL_BOOST_SET:
+		return nvkm_control_mthd_boost_set(ctrl, data, size);
 	default:
 		break;
 	}
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 22/29] debugfs: add boost interface to change the boost_mode
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (20 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 21/29] nvif: add boost info and set operations Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 23/29] clk: remove dstate and tstate Karol Herbst
                     ` (6 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/nouveau_debugfs.c | 76 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index 3d0dc19..31b309f 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -180,6 +180,81 @@ static const struct file_operations nouveau_pstate_fops = {
 	.write = nouveau_debugfs_pstate_set,
 };
 
+static void
+nouveau_debugfs_boost_get_entry(struct seq_file *m, u8 mode, u8 entry, u16 value)
+{
+	if (value) {
+		if (mode == entry)
+			seq_printf(m, "*%i", entry);
+		else
+			seq_printf(m, " %i", entry);
+		seq_printf(m, ": %u MHz\n", value);
+	}
+}
+
+static int
+nouveau_debugfs_boost_get(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct nouveau_debugfs *debugfs = nouveau_debugfs(node->minor->dev);
+	struct nvif_object *ctrl = &debugfs->ctrl;
+	struct nvif_control_boost_info_v0 info = {};
+	int ret;
+
+	ret = nvif_mthd(ctrl, NVIF_CONTROL_BOOST_INFO, &info, sizeof(info));
+	if (ret)
+		return ret;
+
+	nouveau_debugfs_boost_get_entry(m, info.mode, 0, info.base_mhz);
+	nouveau_debugfs_boost_get_entry(m, info.mode, 1, info.boost_mhz);
+	nouveau_debugfs_boost_get_entry(m, info.mode, 2, info.max_mhz);
+	return 0;
+}
+
+static ssize_t
+nouveau_debugfs_boost_set(struct file *file, const char __user *ubuf,
+			  size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct nouveau_debugfs *debugfs = nouveau_debugfs(node->minor->dev);
+	struct nvif_object *ctrl = &debugfs->ctrl;
+	struct nvif_control_boost_set_v0 args = {};
+	char buf[3] = {};
+	int ret;
+	u8 value;
+
+	if (len >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(buf, ubuf, len))
+		return -EFAULT;
+
+	ret = kstrtou8(buf, 10, &value);
+	if (ret)
+		return ret;
+
+	args.mode = value;
+	ret = nvif_mthd(ctrl, NVIF_CONTROL_BOOST_SET, &args, sizeof(args));
+	if (ret)
+		return ret;
+
+	return len;
+}
+
+static int
+nouveau_debugfs_boost_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, nouveau_debugfs_boost_get, inode->i_private);
+}
+
+static const struct file_operations nouveau_boost_fops = {
+	.owner = THIS_MODULE,
+	.open = nouveau_debugfs_boost_open,
+	.read = seq_read,
+	.write = nouveau_debugfs_boost_set,
+};
+
 static struct drm_info_list nouveau_debugfs_list[] = {
 	{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
 };
@@ -189,6 +264,7 @@ static const struct nouveau_debugfs_files {
 	const char *name;
 	const struct file_operations *fops;
 } nouveau_debugfs_files[] = {
+	{"boost", &nouveau_boost_fops},
 	{"pstate", &nouveau_pstate_fops},
 };
 
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 23/29] clk: remove dstate and tstate
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (21 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 22/29] debugfs: add boost interface to change the boost_mode Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 24/29] therm: don't cancel the timer Karol Herbst
                     ` (5 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

we won't need them, because we will adjust the clocks depending on engine loads
later on anyway. It also simplifies the clocking logic.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  4 ----
 drm/nouveau/nvkm/subdev/clk/base.c    | 28 ++--------------------------
 2 files changed, 2 insertions(+), 30 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 77d94c1..db52e65 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -95,8 +95,6 @@ struct nvkm_clk {
 	int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
 	int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
 	int astate; /* perfmon adjustment (base) */
-	int tstate; /* thermal adjustment (max-) */
-	int dstate; /* display adjustment (min+) */
 
 	bool allow_reclock;
 #define NVKM_CLK_BOOST_NONE 0x0
@@ -118,8 +116,6 @@ struct nvkm_clk {
 int nvkm_clk_read(struct nvkm_clk *, enum nv_clk_src);
 int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
 int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
-int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
-int nvkm_clk_tstate(struct nvkm_clk *, int req, int rel);
 int nvkm_clk_update(struct nvkm_clk *, bool wait);
 
 int nv04_clk_new(struct nvkm_device *, int, struct nvkm_clk **);
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index ddbb690..db64c82 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -317,15 +317,13 @@ nvkm_clk_update_work(struct work_struct *work)
 		return;
 	clk->pwrsrc = power_supply_is_system_supplied();
 
-	nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d T %d D %d\n",
+	nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d\n",
 		   clk->pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
-		   clk->astate, clk->tstate, clk->dstate);
+		   clk->astate);
 
 	pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
 	if (clk->state_nr && pstate != -1) {
 		pstate = (pstate < 0) ? clk->astate : pstate;
-		pstate = min(pstate, clk->state_nr - 1 + clk->tstate);
-		pstate = max(pstate, clk->dstate);
 	} else {
 		pstate = clk->pstate = -1;
 	}
@@ -554,26 +552,6 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
 	return nvkm_clk_update(clk, wait);
 }
 
-int
-nvkm_clk_tstate(struct nvkm_clk *clk, int req, int rel)
-{
-	if (!rel) clk->tstate  = req;
-	if ( rel) clk->tstate += rel;
-	clk->tstate = min(clk->tstate, 0);
-	clk->tstate = max(clk->tstate, -(clk->state_nr - 1));
-	return nvkm_clk_update(clk, true);
-}
-
-int
-nvkm_clk_dstate(struct nvkm_clk *clk, int req, int rel)
-{
-	if (!rel) clk->dstate  = req;
-	if ( rel) clk->dstate += rel;
-	clk->dstate = min(clk->dstate, clk->state_nr - 1);
-	clk->dstate = max(clk->dstate, 0);
-	return nvkm_clk_update(clk, true);
-}
-
 static int
 nvkm_clk_pwrsrc(struct nvkm_notify *notify)
 {
@@ -631,8 +609,6 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 		return clk->func->init(clk);
 
 	clk->astate = clk->state_nr - 1;
-	clk->tstate = 0;
-	clk->dstate = 0;
 	clk->pstate = -1;
 	nvkm_clk_update(clk, true);
 	return 0;
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 24/29] therm: don't cancel the timer
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (22 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 23/29] clk: remove dstate and tstate Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 25/29] clk: make pstate a pointer to nvkm_pstate Karol Herbst
                     ` (4 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

we will need a always running therm daemon to adjust the voltage/clocks on the
fly.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/therm/base.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
index 949dc61..fc5fcca 100644
--- a/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drm/nouveau/nvkm/subdev/therm/base.c
@@ -92,7 +92,6 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 	struct nvkm_timer *tmr = subdev->device->timer;
 	unsigned long flags;
 	bool immd = true;
-	bool poll = true;
 	int duty = -1;
 
 	spin_lock_irqsave(&therm->lock, flags);
@@ -102,11 +101,9 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 
 	switch (mode) {
 	case NVKM_THERM_CTRL_MANUAL:
-		nvkm_timer_alarm_cancel(tmr, &therm->alarm);
 		duty = nvkm_therm_fan_get(therm);
 		if (duty < 0)
 			duty = 100;
-		poll = false;
 		break;
 	case NVKM_THERM_CTRL_AUTO:
 		switch(therm->fan->bios.fan_mode) {
@@ -119,18 +116,16 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 		case NVBIOS_THERM_FAN_OTHER:
 			if (therm->cstate)
 				duty = therm->cstate;
-			poll = false;
 			break;
 		}
 		immd = false;
 		break;
 	case NVKM_THERM_CTRL_NONE:
 	default:
-		nvkm_timer_alarm_cancel(tmr, &therm->alarm);
-		poll = false;
+		break;
 	}
 
-	if (list_empty(&therm->alarm.head) && poll)
+	if (list_empty(&therm->alarm.head))
 		nvkm_timer_alarm(tmr, 1000000000ULL, &therm->alarm);
 	spin_unlock_irqrestore(&therm->lock, flags);
 
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 25/29] clk: make pstate a pointer to nvkm_pstate
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (23 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 24/29] therm: don't cancel the timer Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 26/29] clk: hold information about the current cstate status Karol Herbst
                     ` (3 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

we will access the current set cstate at least every second and this safes us
some CPU cycles looking them up every second.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  2 +-
 drm/nouveau/nvkm/engine/device/ctrl.c |  5 ++++-
 drm/nouveau/nvkm/subdev/clk/base.c    | 12 ++++++++----
 drm/nouveau/nvkm/subdev/pmu/gk20a.c   | 23 +++++++----------------
 4 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index db52e65..4fb2c1b 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -91,7 +91,7 @@ struct nvkm_clk {
 
 	struct nvkm_notify pwrsrc_ntfy;
 	int pwrsrc;
-	int pstate; /* current */
+	struct nvkm_pstate *pstate; /* current */
 	int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
 	int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
 	int astate; /* perfmon adjustment (base) */
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c b/drm/nouveau/nvkm/engine/device/ctrl.c
index 039e8a4..cb85266 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -52,7 +52,10 @@ nvkm_control_mthd_pstate_info(struct nvkm_control *ctrl, void *data, u32 size)
 		args->v0.ustate_ac = clk->ustate_ac;
 		args->v0.ustate_dc = clk->ustate_dc;
 		args->v0.pwrsrc = clk->pwrsrc;
-		args->v0.pstate = clk->pstate;
+		if (clk->pstate)
+			args->v0.pstate = clk->pstate->pstate;
+		else
+			args->v0.pstate = -1;
 	} else {
 		args->v0.count = 0;
 		args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index db64c82..4a48439 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -288,7 +288,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 	}
 
 	nvkm_debug(subdev, "setting performance state %d\n", pstatei);
-	clk->pstate = pstatei;
+	clk->pstate = pstate;
 
 	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
 
@@ -317,15 +317,19 @@ nvkm_clk_update_work(struct work_struct *work)
 		return;
 	clk->pwrsrc = power_supply_is_system_supplied();
 
+	if (clk->pstate)
+		pstate = clk->pstate->pstate;
+	else
+		pstate = -1;
 	nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d\n",
-		   clk->pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
+		   pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
 		   clk->astate);
 
 	pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
 	if (clk->state_nr && pstate != -1) {
 		pstate = (pstate < 0) ? clk->astate : pstate;
 	} else {
-		pstate = clk->pstate = -1;
+		pstate = -1;
 	}
 
 	nvkm_trace(subdev, "-> %d\n", pstate);
@@ -609,7 +613,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 		return clk->func->init(clk);
 
 	clk->astate = clk->state_nr - 1;
-	clk->pstate = -1;
+	clk->pstate = NULL;
 	nvkm_clk_update(clk, true);
 	return 0;
 }
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index 6689d02..4d7a979 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -57,24 +57,21 @@ gk20a_pmu_dvfs_target(struct gk20a_pmu *pmu, int *state)
 }
 
 static int
-gk20a_pmu_dvfs_get_cur_state(struct gk20a_pmu *pmu, int *state)
-{
-	struct nvkm_clk *clk = pmu->base.subdev.device->clk;
-
-	*state = clk->pstate;
-	return 0;
-}
-
-static int
 gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu *pmu,
 				int *state, int load)
 {
 	struct gk20a_pmu_dvfs_data *data = pmu->data;
 	struct nvkm_clk *clk = pmu->base.subdev.device->clk;
+	struct nvkm_pstate *pstate = clk->pstate;
 	int cur_level, level;
 
+	if (!pstate) {
+		*state = 0;
+		return 1;
+	}
+
 	/* For GK20A, the performance level is directly mapped to pstate */
-	level = cur_level = clk->pstate;
+	level = cur_level = clk->pstate->pstate;
 
 	if (load > data->p_load_max) {
 		level = min(clk->state_nr - 1, level + (clk->state_nr / 3));
@@ -150,12 +147,6 @@ gk20a_pmu_dvfs_work(struct nvkm_alarm *alarm)
 	nvkm_trace(subdev, "utilization = %d %%, avg_load = %d %%\n",
 		   utilization, data->avg_load);
 
-	ret = gk20a_pmu_dvfs_get_cur_state(pmu, &state);
-	if (ret) {
-		nvkm_warn(subdev, "failed to get current state\n");
-		goto resched;
-	}
-
 	if (gk20a_pmu_dvfs_get_target_state(pmu, &state, data->avg_load)) {
 		nvkm_trace(subdev, "set new state to %d\n", state);
 		gk20a_pmu_dvfs_target(pmu, &state);
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 26/29] clk: hold information about the current cstate status
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (24 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 25/29] clk: make pstate a pointer to nvkm_pstate Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 27/29] clk: we should pass the pstate id around not the index in the list Karol Herbst
                     ` (2 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  5 +++++
 drm/nouveau/nvkm/subdev/clk/base.c    | 32 +++++++++++++++++++++++++-------
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 4fb2c1b..6deda96 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -95,6 +95,11 @@ struct nvkm_clk {
 	int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
 	int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
 	int astate; /* perfmon adjustment (base) */
+	struct nvkm_cstate *set_cstate;
+#define NVKM_CLK_CSTATE_DEFAULT -1
+#define NVKM_CLK_CSTATE_BASE    -2
+#define NVKM_CLK_CSTATE_HIGHEST -3
+	int exp_cstate;
 
 	bool allow_reclock;
 #define NVKM_CLK_BOOST_NONE 0x0
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 4a48439..7e988e2 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -152,9 +152,14 @@ static struct nvkm_cstate *
 nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 {
 	struct nvkm_cstate *cstate;
-	if (cstatei == -1)
+	switch (cstatei) {
+	case NVKM_CLK_CSTATE_HIGHEST:
 		return list_entry(pstate->list.prev, typeof(*cstate), head);
-	else {
+	case NVKM_CLK_CSTATE_BASE:
+		return &pstate->base;
+	case NVKM_CLK_CSTATE_DEFAULT:
+		return NULL;
+	default:
 		list_for_each_entry(cstate, &pstate->list, head) {
 			if (cstate->cstate == cstatei)
 				return cstate;
@@ -173,6 +178,9 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 	struct nvkm_cstate *cstate;
 	int ret;
 
+	if (cstatei == NVKM_CLK_CSTATE_DEFAULT)
+		return 0;
+
 	if (!list_empty(&pstate->list)) {
 		cstate = nvkm_cstate_get(clk, pstate, cstatei);
 		cstate = nvkm_cstate_find_best(clk, pstate, cstate);
@@ -199,6 +207,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 
 	ret = clk->func->calc(clk, cstate);
 	if (ret == 0) {
+		clk->set_cstate = cstate;
 		ret = clk->func->prog(clk);
 		clk->func->tidy(clk);
 	}
@@ -303,7 +312,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 		ram->func->tidy(ram);
 	}
 
-	return nvkm_cstate_prog(clk, pstate, -1);
+	return nvkm_cstate_prog(clk, pstate, clk->exp_cstate);
 }
 
 static void
@@ -321,9 +330,9 @@ nvkm_clk_update_work(struct work_struct *work)
 		pstate = clk->pstate->pstate;
 	else
 		pstate = -1;
-	nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d\n",
+	nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d C %d\n",
 		   pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
-		   clk->astate);
+		   clk->astate, clk->exp_cstate);
 
 	pstate = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
 	if (clk->state_nr && pstate != -1) {
@@ -541,6 +550,7 @@ nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
 	if (ret >= 0) {
 		if (ret -= 2, pwr) clk->ustate_ac = ret;
 		else		   clk->ustate_dc = ret;
+		clk->exp_cstate = NVKM_CLK_CSTATE_HIGHEST;
 		return nvkm_clk_update(clk, true);
 	}
 	return ret;
@@ -553,6 +563,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
 	if ( rel) clk->astate += rel;
 	clk->astate = min(clk->astate, clk->state_nr - 1);
 	clk->astate = max(clk->astate, 0);
+	clk->exp_cstate = NVKM_CLK_CSTATE_BASE;
 	return nvkm_clk_update(clk, wait);
 }
 
@@ -614,6 +625,8 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 
 	clk->astate = clk->state_nr - 1;
 	clk->pstate = NULL;
+	clk->exp_cstate = NVKM_CLK_CSTATE_DEFAULT;
+	clk->set_cstate = NULL;
 	nvkm_clk_update(clk, true);
 	return 0;
 }
@@ -698,15 +711,20 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	if (mode) {
 		clk->ustate_ac = nvkm_clk_nstate(clk, mode, arglen);
 		clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen);
+		clk->exp_cstate = NVKM_CLK_CSTATE_HIGHEST;
 	}
 
 	mode = nvkm_stropt(device->cfgopt, "NvClkModeAC", &arglen);
-	if (mode)
+	if (mode) {
 		clk->ustate_ac = nvkm_clk_nstate(clk, mode, arglen);
+		clk->exp_cstate = NVKM_CLK_CSTATE_HIGHEST;
+	}
 
 	mode = nvkm_stropt(device->cfgopt, "NvClkModeDC", &arglen);
-	if (mode)
+	if (mode) {
 		clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen);
+		clk->exp_cstate = NVKM_CLK_CSTATE_HIGHEST;
+	}
 
 	return 0;
 }
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 27/29] clk: we should pass the pstate id around not the index in the list
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (25 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 26/29] clk: hold information about the current cstate status Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 28/29] clk: only do partial reclocks as required Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 29/29] therm: trigger reclock in temperature daemon Karol Herbst
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

this makes the code easier, because we can compare the id with pstate->pstate
and safe us the trouble iterating over the entire pstate list

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/clk/base.c | 49 +++++++++++---------------------------
 1 file changed, 14 insertions(+), 35 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 7e988e2..50a4e36 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -280,23 +280,26 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
  * P-States
  *****************************************************************************/
 static int
-nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
+nvkm_pstate_prog(struct nvkm_clk *clk, int pstateid)
 {
 	struct nvkm_subdev *subdev = &clk->subdev;
 	struct nvkm_fb *fb = subdev->device->fb;
 	struct nvkm_pci *pci = subdev->device->pci;
 	struct nvkm_pstate *pstate;
-	int ret, idx = 0;
+	int ret;
 
-	if (pstatei == -1)
+	if (pstateid == -1)
 		return 0;
 
 	list_for_each_entry(pstate, &clk->states, head) {
-		if (idx++ == pstatei)
+		if (pstate->pstate == pstateid)
 			break;
 	}
 
-	nvkm_debug(subdev, "setting performance state %d\n", pstatei);
+	if (!pstate)
+		return -EINVAL;
+
+	nvkm_debug(subdev, "setting performance state %x\n", pstateid);
 	clk->pstate = pstate;
 
 	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
@@ -496,30 +499,6 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
  * Adjustment triggers
  *****************************************************************************/
 static int
-nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
-{
-	struct nvkm_pstate *pstate;
-	int i = 0;
-
-	if (!clk->allow_reclock)
-		return -ENOSYS;
-
-	if (req != -1 && req != -2) {
-		list_for_each_entry(pstate, &clk->states, head) {
-			if (pstate->pstate == req)
-				break;
-			i++;
-		}
-
-		if (pstate->pstate != req)
-			return -EINVAL;
-		req = i;
-	}
-
-	return req + 2;
-}
-
-static int
 nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, int arglen)
 {
 	int ret = 1;
@@ -533,23 +512,23 @@ nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, int arglen)
 
 		((char *)mode)[arglen] = '\0';
 		if (!kstrtol(mode, 0, &v)) {
-			ret = nvkm_clk_ustate_update(clk, v);
+			ret = v;
 			if (ret < 0)
 				ret = 1;
 		}
 		((char *)mode)[arglen] = save;
 	}
 
-	return ret - 2;
+	return ret;
 }
 
 int
 nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
 {
-	int ret = nvkm_clk_ustate_update(clk, req);
+	int ret = req;
 	if (ret >= 0) {
-		if (ret -= 2, pwr) clk->ustate_ac = ret;
-		else		   clk->ustate_dc = ret;
+		if (pwr) clk->ustate_ac = ret;
+		else	 clk->ustate_dc = ret;
 		clk->exp_cstate = NVKM_CLK_CSTATE_HIGHEST;
 		return nvkm_clk_update(clk, true);
 	}
@@ -623,7 +602,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 	if (clk->func->init)
 		return clk->func->init(clk);
 
-	clk->astate = clk->state_nr - 1;
+	clk->astate = -1;
 	clk->pstate = NULL;
 	clk->exp_cstate = NVKM_CLK_CSTATE_DEFAULT;
 	clk->set_cstate = NULL;
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 28/29] clk: only do partial reclocks as required
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (26 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 27/29] clk: we should pass the pstate id around not the index in the list Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  2016-04-07 21:24   ` [PATCH v3 29/29] therm: trigger reclock in temperature daemon Karol Herbst
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

we don't want to reclock to the same pstate or cstate over and over again, so
only do things we actually have to do.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/clk/base.c | 63 +++++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 5 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 50a4e36..e7101e1 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -188,6 +188,11 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 		cstate = &pstate->base;
 	}
 
+	if (!cstate) {
+		nvkm_error(subdev, "failed to set cstate %d\n", cstatei);
+		return -EINVAL;
+	}
+
 	if (therm) {
 		ret = nvkm_therm_cstate(therm, pstate->fanspeed, +1);
 		if (ret && ret != -ENODEV) {
@@ -318,6 +323,24 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstateid)
 	return nvkm_cstate_prog(clk, pstate, clk->exp_cstate);
 }
 
+static int
+nvkm_clk_update_volt(struct nvkm_clk *clk)
+{
+	struct nvkm_subdev *subdev = &clk->subdev;
+	struct nvkm_volt *volt = subdev->device->volt;
+	struct nvkm_therm *therm = subdev->device->therm;
+	int ret;
+
+	if (!volt || !therm || !clk->pstate || !clk->set_cstate)
+		return -EINVAL;
+
+	ret =  nvkm_volt_set_id(volt, clk->set_cstate->voltage,
+				clk->pstate->base.voltage, -1);
+	ret |= nvkm_volt_set_id(volt, clk->set_cstate->voltage,
+				clk->pstate->base.voltage, +1);
+	return ret;
+}
+
 static void
 nvkm_clk_update_work(struct work_struct *work)
 {
@@ -344,13 +367,43 @@ nvkm_clk_update_work(struct work_struct *work)
 		pstate = -1;
 	}
 
-	nvkm_trace(subdev, "-> %d\n", pstate);
-	ret = nvkm_pstate_prog(clk, pstate);
-	if (ret) {
-		nvkm_error(subdev, "error setting pstate %d: %d\n",
-			   pstate, ret);
+	if (!clk->pstate || clk->pstate->pstate != pstate) {
+		nvkm_trace(subdev, "-> P %d\n", pstate);
+		ret = nvkm_pstate_prog(clk, pstate);
+		if (ret) {
+			nvkm_error(subdev, "error setting pstate %d: %d\n",
+				   pstate, ret);
+		}
+	} else if (!clk->set_cstate ||
+		   clk->set_cstate->cstate != clk->exp_cstate) {
+
+		struct nvkm_cstate *cstate = nvkm_cstate_get(clk, clk->pstate, clk->exp_cstate);
+		if (!cstate) {
+			nvkm_error(subdev, "couldn't find fitting cstate\n");
+			goto update_err;
+		}
+
+		cstate = nvkm_cstate_find_best(clk, clk->pstate, cstate);
+		if (!cstate) {
+			nvkm_error(subdev, "couldn't find best cstate\n");
+			goto update_err;
+		}
+
+		if (cstate != clk->set_cstate) {
+			nvkm_trace(subdev, "-> C %d\n", cstate->cstate);
+			ret = nvkm_cstate_prog(clk, clk->pstate, cstate->cstate);
+			if (ret) {
+				nvkm_error(subdev, "error setting cstate %d: %d\n",
+					   cstate->cstate, ret);
+			}
+		} else {
+			nvkm_clk_update_volt(clk);
+		}
+	} else {
+		nvkm_clk_update_volt(clk);
 	}
 
+update_err:
 	wake_up_all(&clk->wait);
 	nvkm_notify_get(&clk->pwrsrc_ntfy);
 }
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v3 29/29] therm: trigger reclock in temperature daemon
       [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (27 preceding siblings ...)
  2016-04-07 21:24   ` [PATCH v3 28/29] clk: only do partial reclocks as required Karol Herbst
@ 2016-04-07 21:24   ` Karol Herbst
  28 siblings, 0 replies; 30+ messages in thread
From: Karol Herbst @ 2016-04-07 21:24 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

depending on the temperature, cstates might become unreachable or the maped
voltage of a cstate changes. We want to adjust to that.

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/therm/base.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
index fc5fcca..07ea9bd 100644
--- a/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drm/nouveau/nvkm/subdev/therm/base.c
@@ -23,6 +23,8 @@
  */
 #include "priv.h"
 
+#include <subdev/clk.h>
+
 int
 nvkm_therm_temp_get(struct nvkm_therm *therm)
 {
@@ -153,7 +155,10 @@ nvkm_therm_alarm(struct nvkm_alarm *alarm)
 {
 	struct nvkm_therm *therm =
 	       container_of(alarm, struct nvkm_therm, alarm);
+	struct nvkm_clk *clk = therm->subdev.device->clk;
 	nvkm_therm_update(therm, -1);
+	if (clk)
+		nvkm_clk_update(clk, false);
 }
 
 int
-- 
2.8.1

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2016-04-07 21:24 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-07 21:23 [PATCH v3 00/29] Volting/Clocking improvements for Fermi and newer Karol Herbst
     [not found] ` <1460064259-1243-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2016-04-07 21:23   ` [PATCH v3 01/29] bios/volt: handle voltage table version 0x50 with 0ed header Karol Herbst
2016-04-07 21:23   ` [PATCH v3 02/29] volt: properly detect entry based voltage tables Karol Herbst
2016-04-07 21:23   ` [PATCH v3 03/29] volt: save the voltage range we are able to set Karol Herbst
2016-04-07 21:23   ` [PATCH v3 04/29] volt: add nvkm_volt_map_min function Karol Herbst
2016-04-07 21:23   ` [PATCH v3 05/29] clk: don't create cstates whit voltages higher than what the gpu can do Karol Herbst
2016-04-07 21:23   ` [PATCH v3 06/29] volt: parse the max voltage map entries Karol Herbst
2016-04-07 21:23   ` [PATCH v3 07/29] volt: add min_id parameter to nvkm_volt_set_id Karol Herbst
2016-04-07 21:23   ` [PATCH v3 08/29] clk: export nvkm_volt_map Karol Herbst
2016-04-07 21:23   ` [PATCH v3 09/29] clk: add index field to nvkm_cstate Karol Herbst
2016-04-07 21:24   ` [PATCH v3 10/29] add daemon to compare nouveau with blob voltage Karol Herbst
2016-04-07 21:24   ` [PATCH v3 11/29] volt: add temperature parameter to nvkm_volt_map Karol Herbst
2016-04-07 21:24   ` [PATCH v3 12/29] clk: fixup cstate selection Karol Herbst
2016-04-07 21:24   ` [PATCH v3 13/29] clk: respect voltage limits in nvkm_cstate_prog Karol Herbst
2016-04-07 21:24   ` [PATCH v3 14/29] bios: add parsing of BASE CLOCK table Karol Herbst
2016-04-07 21:24   ` [PATCH v3 15/29] clk: allow boosting only when NvBoost is set Karol Herbst
2016-04-07 21:24   ` [PATCH v3 16/29] volt: don't require perfect fit Karol Herbst
2016-04-07 21:24   ` [PATCH v3 17/29] bios/vmap: unk0 field is the mode Karol Herbst
2016-04-07 21:24   ` [PATCH v3 18/29] volt: add coefficients I found on my gpu Karol Herbst
2016-04-07 21:24   ` [PATCH v3 19/29] clk: save the max clock we can set Karol Herbst
2016-04-07 21:24   ` [PATCH v3 20/29] clk: rename nvkm_pstate_calc to nvkm_clk_update Karol Herbst
2016-04-07 21:24   ` [PATCH v3 21/29] nvif: add boost info and set operations Karol Herbst
2016-04-07 21:24   ` [PATCH v3 22/29] debugfs: add boost interface to change the boost_mode Karol Herbst
2016-04-07 21:24   ` [PATCH v3 23/29] clk: remove dstate and tstate Karol Herbst
2016-04-07 21:24   ` [PATCH v3 24/29] therm: don't cancel the timer Karol Herbst
2016-04-07 21:24   ` [PATCH v3 25/29] clk: make pstate a pointer to nvkm_pstate Karol Herbst
2016-04-07 21:24   ` [PATCH v3 26/29] clk: hold information about the current cstate status Karol Herbst
2016-04-07 21:24   ` [PATCH v3 27/29] clk: we should pass the pstate id around not the index in the list Karol Herbst
2016-04-07 21:24   ` [PATCH v3 28/29] clk: only do partial reclocks as required Karol Herbst
2016-04-07 21:24   ` [PATCH v3 29/29] therm: trigger reclock in temperature daemon Karol Herbst

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.