All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/32] Updated State of my clk patches
@ 2017-11-17  0:04 Karol Herbst
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Last update here: https://lists.freedesktop.org/archives/nouveau/2017-September/028848.html

Basically big cleanup, reordering, simplifications and some renaming to make
the code easier to read and to review. I also moved some bugfixes to the front
so they can be merged prior the other patches.

There was also a bug related to the therm daemon triggering a pstate change
leading to PMU lockups, because the timer wasn't disabled on fini.

I think we are getting close with this and hope we can merge this soon.

Karol Herbst (32):
  bios/vpstate: There are some fermi vbios with no boost or tdp entry
  debugfs: Wake up GPU before doing any reclocking
  therm: Split return code and value in nvkm_get_temp
  hwmon: Properly check for errors
  clk: Improve names of pstate/cstate related variables and fields
  clk: Add NVKM_CLK_PSTATE_BOOT
  clk: Rename NVKM_CLK_CSTATE_HIGHEST to NVKM_CLK_CSTATE_AUTO
  clk: Rename nvkm_clk.states to pstates
  clk: Rename nvkm_pstate.list to cstates
  clk: Remove dstate
  clk: Rename nvkm_pstate_calc to nvkm_clk_update and export it
  clk: Use list_for_each_entry_from_reverse in nvkm_cstate_find_best
  clk: We should pass the pstate id around not the index in the list
  clk: Hold information about the current cstate status
  clk: Refactor the base and boost clock limits so that we can limit
    pstates
  therm: Move the temp readout into nvkm_therm_update
  core/device: Move therm behind clk
  therm: Trigger reclock in temperature daemon
  bios: Add thermal policies table
  therm: Cancel the timer only in fini
  clk: Parse thermal policies for throttling thresholds
  clk: Thermal throttling
  clk: Skip unchanging parts of the reclock
  clk: Save the max clock we can set
  nvif: Add boost info and set operations
  debugfs: Add boost interface to change the boost_mode
  bios/vpstate: Parse max battery id
  clk: Implement limiting pstates just like we do for cstates
  clk: Limit clocks on battery
  secboot/acr352: Reset PMU after secboot
  device: Enable clk for Maxwell2
  clk: Add trace message when setting a new cstate

 drm/nouveau/include/nvif/if0001.h                  |  15 +
 drm/nouveau/include/nvkm/core/device.h             |   2 +-
 drm/nouveau/include/nvkm/subdev/bios/boost.h       |   2 +-
 drm/nouveau/include/nvkm/subdev/bios/perf.h        |   2 +-
 .../include/nvkm/subdev/bios/thermal_policies.h    |  25 ++
 drm/nouveau/include/nvkm/subdev/bios/vpstate.h     |   1 +
 drm/nouveau/include/nvkm/subdev/clk.h              |  40 +-
 drm/nouveau/include/nvkm/subdev/therm.h            |   2 +-
 drm/nouveau/nouveau_debugfs.c                      |  99 ++++-
 drm/nouveau/nouveau_hwmon.c                        |  48 ++-
 drm/nouveau/nvkm/engine/device/base.c              |   3 +
 drm/nouveau/nvkm/engine/device/ctrl.c              |  73 +++-
 drm/nouveau/nvkm/subdev/bios/Kbuild                |   1 +
 drm/nouveau/nvkm/subdev/bios/boost.c               |  11 +-
 drm/nouveau/nvkm/subdev/bios/perf.c                |   2 +-
 drm/nouveau/nvkm/subdev/bios/thermal_policies.c    |  81 ++++
 drm/nouveau/nvkm/subdev/bios/vpstate.c             |  13 +-
 drm/nouveau/nvkm/subdev/clk/base.c                 | 427 ++++++++++++++-------
 drm/nouveau/nvkm/subdev/clk/gk104.c                |  10 +-
 drm/nouveau/nvkm/subdev/clk/gk20a.c                |   4 +-
 drm/nouveau/nvkm/subdev/pmu/gk20a.c                |   9 +-
 drm/nouveau/nvkm/subdev/secboot/acr_r352.c         |  14 +
 drm/nouveau/nvkm/subdev/therm/base.c               |  52 ++-
 drm/nouveau/nvkm/subdev/therm/g84.c                |  13 +-
 drm/nouveau/nvkm/subdev/therm/gp100.c              |   9 +-
 drm/nouveau/nvkm/subdev/therm/nv40.c               |   9 +-
 drm/nouveau/nvkm/subdev/therm/nv50.c               |   9 +-
 drm/nouveau/nvkm/subdev/therm/priv.h               |   4 +-
 drm/nouveau/nvkm/subdev/therm/temp.c               |  16 +-
 drm/nouveau/nvkm/subdev/volt/base.c                |   3 +
 lib/include/nvif/list.h                            |   5 +
 31 files changed, 758 insertions(+), 246 deletions(-)
 create mode 100644 drm/nouveau/include/nvkm/subdev/bios/thermal_policies.h
 create mode 100644 drm/nouveau/nvkm/subdev/bios/thermal_policies.c

-- 
2.15.0

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

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

* [PATCH 01/32] bios/vpstate: There are some fermi vbios with no boost or tdp entry
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-11-17  0:04   ` Karol Herbst
       [not found]     ` <20171117000436.2432-2-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-11-17  0:04   ` [PATCH 02/32] debugfs: Wake up GPU before doing any reclocking Karol Herbst
                     ` (30 subsequent siblings)
  31 siblings, 1 reply; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/nvkm/subdev/bios/vpstate.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/bios/vpstate.c b/drm/nouveau/nvkm/subdev/bios/vpstate.c
index 20b6fc82..71524548 100644
--- a/drm/nouveau/nvkm/subdev/bios/vpstate.c
+++ b/drm/nouveau/nvkm/subdev/bios/vpstate.c
@@ -58,8 +58,14 @@ nvbios_vpstate_parse(struct nvkm_bios *b, struct nvbios_vpstate_header *h)
 		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);
+		if (h->hlen > 0x10)
+			h->boost_id = nvbios_rd08(b, h->offset + 0x10);
+		else
+			h->boost_id = 0xff;
+		if (h->hlen > 0x11)
+			h->tdp_id = nvbios_rd08(b, h->offset + 0x11);
+		else
+			h->tdp_id = 0xff;
 		return 0;
 	default:
 		return -EINVAL;
-- 
2.15.0

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

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

* [PATCH 02/32] debugfs: Wake up GPU before doing any reclocking
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-11-17  0:04   ` [PATCH 01/32] bios/vpstate: There are some fermi vbios with no boost or tdp entry Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
       [not found]     ` <20171117000436.2432-3-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-11-17  0:04   ` [PATCH 03/32] therm: Split return code and value in nvkm_get_temp Karol Herbst
                     ` (29 subsequent siblings)
  31 siblings, 1 reply; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Fixes various reclocking related issues on prime systems.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/nouveau_debugfs.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index 963a4dba..9109b69c 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -160,7 +160,11 @@ nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf,
 		args.ustate = value;
 	}
 
+	ret = pm_runtime_get_sync(drm->dev);
+	if (IS_ERR_VALUE(ret) && ret != -EACCES)
+		return ret;
 	ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args));
+	pm_runtime_put_autosuspend(drm->dev);
 	if (ret < 0)
 		return ret;
 
-- 
2.15.0

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

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

* [PATCH 03/32] therm: Split return code and value in nvkm_get_temp
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-11-17  0:04   ` [PATCH 01/32] bios/vpstate: There are some fermi vbios with no boost or tdp entry Karol Herbst
  2017-11-17  0:04   ` [PATCH 02/32] debugfs: Wake up GPU before doing any reclocking Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
       [not found]     ` <20171117000436.2432-4-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-11-17  0:04   ` [PATCH 04/32] hwmon: Properly check for errors Karol Herbst
                     ` (28 subsequent siblings)
  31 siblings, 1 reply; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

The current hwmon code doesn't check if the returned value was actually an
error.

Since Kepler temperature sensors are able to report negative values. Those
negative values are not for error reporting, but rather when you buried
your GPU in snow somewhere in Antarctica and still want a valid
temperature to be reported (unverified).

Since Pascal (and maybe earlier) we have sensors with improved precision.

Adjust the nvkm_get_temp method to be able to deal with those changes
and let hwmon return an error properly.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/include/nvkm/subdev/clk.h   |  4 ++--
 drm/nouveau/include/nvkm/subdev/therm.h |  2 +-
 drm/nouveau/nouveau_hwmon.c             | 15 +++++++++------
 drm/nouveau/nvkm/subdev/clk/base.c      |  2 +-
 drm/nouveau/nvkm/subdev/therm/base.c    | 19 ++++++++++++++-----
 drm/nouveau/nvkm/subdev/therm/g84.c     | 13 ++++++++-----
 drm/nouveau/nvkm/subdev/therm/gp100.c   |  9 +++++----
 drm/nouveau/nvkm/subdev/therm/nv40.c    |  9 +++------
 drm/nouveau/nvkm/subdev/therm/nv50.c    |  9 +++------
 drm/nouveau/nvkm/subdev/therm/priv.h    |  4 ++--
 drm/nouveau/nvkm/subdev/therm/temp.c    | 16 ++++++++++++----
 11 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index e5275f74..506f8cc6 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -100,7 +100,7 @@ struct nvkm_clk {
 	int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
 	int astate; /* perfmon adjustment (base) */
 	int dstate; /* display adjustment (min+) */
-	u8  temp;
+	int temp;
 
 	bool allow_reclock;
 #define NVKM_CLK_BOOST_NONE 0x0
@@ -122,7 +122,7 @@ 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 *, u8 temperature);
+int nvkm_clk_tstate(struct nvkm_clk *, int temperature);
 
 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/include/nvkm/subdev/therm.h b/drm/nouveau/include/nvkm/subdev/therm.h
index 9841f076..8c84017f 100644
--- a/drm/nouveau/include/nvkm/subdev/therm.h
+++ b/drm/nouveau/include/nvkm/subdev/therm.h
@@ -86,7 +86,7 @@ struct nvkm_therm {
 	int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
 };
 
-int nvkm_therm_temp_get(struct nvkm_therm *);
+int nvkm_therm_temp_get(struct nvkm_therm *, int *);
 int nvkm_therm_fan_sense(struct nvkm_therm *);
 int nvkm_therm_cstate(struct nvkm_therm *, int, int);
 
diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
index 7c965648..7486e4af 100644
--- a/drm/nouveau/nouveau_hwmon.c
+++ b/drm/nouveau/nouveau_hwmon.c
@@ -326,8 +326,9 @@ nouveau_temp_is_visible(const void *data, u32 attr, int channel)
 {
 	struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
 	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
+	int val;
 
-	if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
+	if (therm && therm->attr_get && nvkm_therm_temp_get(therm, &val))
 		return 0;
 
 	switch (attr) {
@@ -421,15 +422,16 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
 	struct nouveau_drm *drm = nouveau_drm(drm_dev);
 	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
-	int ret;
+	int ret = 0;
+	int temp;
 
 	if (!therm || !therm->attr_get)
 		return -EOPNOTSUPP;
 
 	switch (attr) {
 	case hwmon_temp_input:
-		ret = nvkm_therm_temp_get(therm);
-		*val = ret < 0 ? ret : (ret * 1000);
+		ret = nvkm_therm_temp_get(therm, &temp);
+		*val = temp * 1000;
 		break;
 	case hwmon_temp_max:
 		*val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
@@ -459,7 +461,7 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
 		return -EOPNOTSUPP;
 	}
 
-	return 0;
+	return ret;
 }
 
 static int
@@ -713,6 +715,7 @@ nouveau_hwmon_init(struct drm_device *dev)
 	struct device *hwmon_dev;
 	int ret = 0;
 	int i = 0;
+	int val;
 
 	hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
 	if (!hwmon)
@@ -720,7 +723,7 @@ nouveau_hwmon_init(struct drm_device *dev)
 	hwmon->dev = dev;
 
 	if (therm && therm->attr_get && therm->attr_set) {
-		if (nvkm_therm_temp_get(therm) >= 0)
+		if (!nvkm_therm_temp_get(therm, &val))
 			special_groups[i++] = &temp1_auto_point_sensor_group;
 		if (therm->fan_get && therm->fan_get(therm) >= 0)
 			special_groups[i++] = &pwm_fan_sensor_group;
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index e4c8d310..0b28dbb9 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -540,7 +540,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
 }
 
 int
-nvkm_clk_tstate(struct nvkm_clk *clk, u8 temp)
+nvkm_clk_tstate(struct nvkm_clk *clk, int temp)
 {
 	if (clk->temp == temp)
 		return 0;
diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
index f27fc6d0..8e5f6f7f 100644
--- a/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drm/nouveau/nvkm/subdev/therm/base.c
@@ -24,22 +24,26 @@
 #include "priv.h"
 
 int
-nvkm_therm_temp_get(struct nvkm_therm *therm)
+nvkm_therm_temp_get(struct nvkm_therm *therm, int *val)
 {
 	if (therm->func->temp_get)
-		return therm->func->temp_get(therm);
+		return therm->func->temp_get(therm, val);
 	return -ENODEV;
 }
 
 static int
 nvkm_therm_update_trip(struct nvkm_therm *therm)
 {
+	int temp, ret;
 	struct nvbios_therm_trip_point *trip = therm->fan->bios.trip,
 				       *cur_trip = NULL,
 				       *last_trip = therm->last_trip;
-	u8  temp = therm->func->temp_get(therm);
 	u16 duty, i;
 
+	ret = therm->func->temp_get(therm, &temp);
+	if (ret < 0)
+		return ret;
+
 	/* look for the trip point corresponding to the current temperature */
 	cur_trip = NULL;
 	for (i = 0; i < therm->fan->bios.nr_fan_trip; i++) {
@@ -67,9 +71,13 @@ static int
 nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
                                u8 linear_max_temp)
 {
-	u8  temp = therm->func->temp_get(therm);
+	int temp, ret;
 	u16 duty;
 
+	ret = therm->func->temp_get(therm, &temp);
+	if (ret < 0)
+		return ret;
+
 	/* handle the non-linear part first */
 	if (temp < linear_min_temp)
 		return therm->fan->bios.min_duty;
@@ -182,6 +190,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
 {
 	struct nvkm_subdev *subdev = &therm->subdev;
 	struct nvkm_device *device = subdev->device;
+	int val;
 	static const char *name[] = {
 		"disabled",
 		"manual",
@@ -197,7 +206,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
 	/* do not allow automatic fan management if the thermal sensor is
 	 * not available */
 	if (mode == NVKM_THERM_CTRL_AUTO &&
-	    therm->func->temp_get(therm) < 0)
+	    therm->func->temp_get(therm, &val))
 		return -EINVAL;
 
 	if (therm->mode == mode)
diff --git a/drm/nouveau/nvkm/subdev/therm/g84.c b/drm/nouveau/nvkm/subdev/therm/g84.c
index 96f8da40..81c0bda8 100644
--- a/drm/nouveau/nvkm/subdev/therm/g84.c
+++ b/drm/nouveau/nvkm/subdev/therm/g84.c
@@ -27,14 +27,15 @@
 #include <subdev/fuse.h>
 
 int
-g84_temp_get(struct nvkm_therm *therm)
+g84_temp_get(struct nvkm_therm *therm, int *val)
 {
 	struct nvkm_device *device = therm->subdev.device;
 
-	if (nvkm_fuse_read(device->fuse, 0x1a8) == 1)
-		return nvkm_rd32(device, 0x20400);
-	else
+	if (nvkm_fuse_read(device->fuse, 0x1a8) != 1)
 		return -ENODEV;
+
+	*val = nvkm_rd32(device, 0x20400);
+	return 0;
 }
 
 void
@@ -114,8 +115,10 @@ g84_therm_threshold_hyst_emulation(struct nvkm_therm *therm,
 		new_state = NVKM_THERM_THRS_LOWER;
 	}
 
+	if (therm->func->temp_get(therm, &cur))
+		return;
+
 	/* fix the state (in case someone reprogrammed the alarms) */
-	cur = therm->func->temp_get(therm);
 	if (new_state == NVKM_THERM_THRS_LOWER && cur > thrs->temp)
 		new_state = NVKM_THERM_THRS_HIGHER;
 	else if (new_state == NVKM_THERM_THRS_HIGHER &&
diff --git a/drm/nouveau/nvkm/subdev/therm/gp100.c b/drm/nouveau/nvkm/subdev/therm/gp100.c
index 9f0dea3f..d8206748 100644
--- a/drm/nouveau/nvkm/subdev/therm/gp100.c
+++ b/drm/nouveau/nvkm/subdev/therm/gp100.c
@@ -24,7 +24,7 @@
 #include "priv.h"
 
 static int
-gp100_temp_get(struct nvkm_therm *therm)
+gp100_temp_get(struct nvkm_therm *therm, int *val)
 {
 	struct nvkm_device *device = therm->subdev.device;
 	struct nvkm_subdev *subdev = &therm->subdev;
@@ -36,9 +36,10 @@ gp100_temp_get(struct nvkm_therm *therm)
 		nvkm_trace(subdev, "reading temperature from SHADOWed sensor\n");
 
 	/* device valid */
-	if (tsensor & 0x20000000)
-		return (inttemp >> 8);
-	else
+	if (tsensor & 0x20000000) {
+		*val = inttemp >> 8;
+		return 0;
+	} else
 		return -ENODEV;
 }
 
diff --git a/drm/nouveau/nvkm/subdev/therm/nv40.c b/drm/nouveau/nvkm/subdev/therm/nv40.c
index 2c92ffb5..cfd5b215 100644
--- a/drm/nouveau/nvkm/subdev/therm/nv40.c
+++ b/drm/nouveau/nvkm/subdev/therm/nv40.c
@@ -70,7 +70,7 @@ nv40_sensor_setup(struct nvkm_therm *therm)
 }
 
 static int
-nv40_temp_get(struct nvkm_therm *therm)
+nv40_temp_get(struct nvkm_therm *therm, int *val)
 {
 	struct nvkm_device *device = therm->subdev.device;
 	struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
@@ -95,11 +95,8 @@ nv40_temp_get(struct nvkm_therm *therm)
 	core_temp = core_temp + sensor->offset_num / sensor->offset_den;
 	core_temp = core_temp + sensor->offset_constant - 8;
 
-	/* reserve negative temperatures for errors */
-	if (core_temp < 0)
-		core_temp = 0;
-
-	return core_temp;
+	*val = core_temp;
+	return 0;
 }
 
 static int
diff --git a/drm/nouveau/nvkm/subdev/therm/nv50.c b/drm/nouveau/nvkm/subdev/therm/nv50.c
index 9b57b433..62ec4063 100644
--- a/drm/nouveau/nvkm/subdev/therm/nv50.c
+++ b/drm/nouveau/nvkm/subdev/therm/nv50.c
@@ -126,7 +126,7 @@ nv50_sensor_setup(struct nvkm_therm *therm)
 }
 
 static int
-nv50_temp_get(struct nvkm_therm *therm)
+nv50_temp_get(struct nvkm_therm *therm, int *val)
 {
 	struct nvkm_device *device = therm->subdev.device;
 	struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
@@ -143,11 +143,8 @@ nv50_temp_get(struct nvkm_therm *therm)
 	core_temp = core_temp + sensor->offset_num / sensor->offset_den;
 	core_temp = core_temp + sensor->offset_constant - 8;
 
-	/* reserve negative temperatures for errors */
-	if (core_temp < 0)
-		core_temp = 0;
-
-	return core_temp;
+	*val = core_temp;
+	return 0;
 }
 
 static void
diff --git a/drm/nouveau/nvkm/subdev/therm/priv.h b/drm/nouveau/nvkm/subdev/therm/priv.h
index 1f46e371..b325ec5f 100644
--- a/drm/nouveau/nvkm/subdev/therm/priv.h
+++ b/drm/nouveau/nvkm/subdev/therm/priv.h
@@ -91,7 +91,7 @@ struct nvkm_therm_func {
 	int (*pwm_set)(struct nvkm_therm *, int line, u32, u32);
 	int (*pwm_clock)(struct nvkm_therm *, int line);
 
-	int (*temp_get)(struct nvkm_therm *);
+	int (*temp_get)(struct nvkm_therm *, int *);
 
 	int (*fan_sense)(struct nvkm_therm *);
 
@@ -105,7 +105,7 @@ int  nv50_fan_pwm_get(struct nvkm_therm *, int, u32 *, u32 *);
 int  nv50_fan_pwm_set(struct nvkm_therm *, int, u32, u32);
 int  nv50_fan_pwm_clock(struct nvkm_therm *, int);
 
-int  g84_temp_get(struct nvkm_therm *);
+int  g84_temp_get(struct nvkm_therm *, int *);
 void g84_sensor_setup(struct nvkm_therm *);
 void g84_therm_fini(struct nvkm_therm *);
 
diff --git a/drm/nouveau/nvkm/subdev/therm/temp.c b/drm/nouveau/nvkm/subdev/therm/temp.c
index ddb2b2c6..e7b8cbe2 100644
--- a/drm/nouveau/nvkm/subdev/therm/temp.c
+++ b/drm/nouveau/nvkm/subdev/therm/temp.c
@@ -86,7 +86,10 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
 	static const char * const thresholds[] = {
 		"fanboost", "downclock", "critical", "shutdown"
 	};
-	int temperature = therm->func->temp_get(therm);
+	int temperature;
+
+	if (therm->func->temp_get(therm, &temperature))
+		return;
 
 	if (thrs < 0 || thrs > 3)
 		return;
@@ -140,7 +143,10 @@ nvkm_therm_threshold_hyst_polling(struct nvkm_therm *therm,
 {
 	enum nvkm_therm_thrs_direction direction;
 	enum nvkm_therm_thrs_state prev_state, new_state;
-	int temp = therm->func->temp_get(therm);
+	int temp;
+
+	if (therm->func->temp_get(therm, &temp))
+		return;
 
 	prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name);
 
@@ -166,6 +172,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
 	struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
 	struct nvkm_timer *tmr = therm->subdev.device->timer;
 	unsigned long flags;
+	int val;
 
 	spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags);
 
@@ -185,7 +192,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
 	spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags);
 
 	/* schedule the next poll in one second */
-	if (therm->func->temp_get(therm) >= 0)
+	if (!therm->func->temp_get(therm, &val))
 		nvkm_timer_alarm(tmr, 1000000000ULL, alarm);
 }
 
@@ -227,9 +234,10 @@ nvkm_therm_sensor_fini(struct nvkm_therm *therm, bool suspend)
 void
 nvkm_therm_sensor_preinit(struct nvkm_therm *therm)
 {
+	int val;
 	const char *sensor_avail = "yes";
 
-	if (therm->func->temp_get(therm) < 0)
+	if (therm->func->temp_get(therm, &val))
 		sensor_avail = "no";
 
 	nvkm_debug(&therm->subdev, "internal sensor: %s\n", sensor_avail);
-- 
2.15.0

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

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

* [PATCH 04/32] hwmon: Properly check for errors
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 03/32] therm: Split return code and value in nvkm_get_temp Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 05/32] clk: Improve names of pstate/cstate related variables and fields Karol Herbst
                     ` (27 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Otherwise hwmon interprets error codes as real values.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/nouveau_hwmon.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
index 7486e4af..6834e0fd 100644
--- a/drm/nouveau/nouveau_hwmon.c
+++ b/drm/nouveau/nouveau_hwmon.c
@@ -470,18 +470,23 @@ nouveau_fan_read(struct device *dev, u32 attr, int channel, long *val)
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
 	struct nouveau_drm *drm = nouveau_drm(drm_dev);
 	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
+	int ret;
 
 	if (!therm)
 		return -EOPNOTSUPP;
 
 	switch (attr) {
 	case hwmon_fan_input:
-		*val = nvkm_therm_fan_sense(therm);
+		ret = nvkm_therm_fan_sense(therm);
 		break;
 	default:
 		return -EOPNOTSUPP;
 	}
 
+	if (ret < 0)
+		return ret;
+
+	*val = ret;
 	return 0;
 }
 
@@ -491,7 +496,7 @@ nouveau_in_read(struct device *dev, u32 attr, int channel, long *val)
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
 	struct nouveau_drm *drm = nouveau_drm(drm_dev);
 	struct nvkm_volt *volt = nvxx_volt(&drm->client.device);
-	int ret;
+	int ret = 0;
 
 	if (!volt)
 		return -EOPNOTSUPP;
@@ -499,7 +504,8 @@ nouveau_in_read(struct device *dev, u32 attr, int channel, long *val)
 	switch (attr) {
 	case hwmon_in_input:
 		ret = nvkm_volt_get(volt);
-		*val = ret < 0 ? ret : (ret / 1000);
+		if (ret >= 0)
+			*val = ret / 1000;
 		break;
 	case hwmon_in_min:
 		*val = volt->min_uv > 0 ? (volt->min_uv / 1000) : -ENODEV;
@@ -511,7 +517,7 @@ nouveau_in_read(struct device *dev, u32 attr, int channel, long *val)
 		return -EOPNOTSUPP;
 	}
 
-	return 0;
+	return ret;
 }
 
 static int
@@ -520,21 +526,26 @@ nouveau_pwm_read(struct device *dev, u32 attr, int channel, long *val)
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
 	struct nouveau_drm *drm = nouveau_drm(drm_dev);
 	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
+	int ret;
 
 	if (!therm || !therm->attr_get || !therm->fan_get)
 		return -EOPNOTSUPP;
 
 	switch (attr) {
 	case hwmon_pwm_enable:
-		*val = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE);
+		ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE);
 		break;
 	case hwmon_pwm_input:
-		*val = therm->fan_get(therm);
+		ret = therm->fan_get(therm);
 		break;
 	default:
 		return -EOPNOTSUPP;
 	}
 
+	if (ret < 0)
+		return ret;
+
+	*val = ret;
 	return 0;
 }
 
@@ -544,18 +555,26 @@ nouveau_power_read(struct device *dev, u32 attr, int channel, long *val)
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
 	struct nouveau_drm *drm = nouveau_drm(drm_dev);
 	struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device);
+	int ret;
 
 	if (!iccsense)
 		return -EOPNOTSUPP;
 
 	switch (attr) {
 	case hwmon_power_input:
-		*val = nvkm_iccsense_read_all(iccsense);
+		ret = nvkm_iccsense_read_all(iccsense);
+		if (ret < 0)
+			return ret;
+		*val = ret;
 		break;
 	case hwmon_power_max:
+		if (iccsense->power_w_max <= 0)
+			return -ENODEV;
 		*val = iccsense->power_w_max;
 		break;
 	case hwmon_power_crit:
+		if (iccsense->power_w_crit <= 0)
+			return -ENODEV;
 		*val = iccsense->power_w_crit;
 		break;
 	default:
-- 
2.15.0

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

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

* [PATCH 05/32] clk: Improve names of pstate/cstate related variables and fields
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (3 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 04/32] hwmon: Properly check for errors Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 06/32] clk: Add NVKM_CLK_PSTATE_BOOT Karol Herbst
                     ` (26 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Karol Herbst <kherbst@redhat.com>

id: id of the state
idx: index of the state inside the parent list
pstate/cstate: the struct itself

Signed-off-by: Karol Herbst <kherbst@redhat.com>
---
 drm/nouveau/include/nvkm/subdev/bios/boost.h |  2 +-
 drm/nouveau/include/nvkm/subdev/bios/perf.h  |  2 +-
 drm/nouveau/include/nvkm/subdev/clk.h        |  4 +-
 drm/nouveau/nouveau_debugfs.c                | 14 +++---
 drm/nouveau/nvkm/engine/device/ctrl.c        |  4 +-
 drm/nouveau/nvkm/subdev/bios/boost.c         | 11 +++--
 drm/nouveau/nvkm/subdev/bios/perf.c          |  2 +-
 drm/nouveau/nvkm/subdev/clk/base.c           | 70 ++++++++++++++--------------
 drm/nouveau/nvkm/subdev/clk/gk20a.c          |  2 +-
 drm/nouveau/nvkm/subdev/pmu/gk20a.c          |  4 +-
 10 files changed, 59 insertions(+), 56 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/boost.h b/drm/nouveau/include/nvkm/subdev/bios/boost.h
index 2ff64a20..74791349 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/boost.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/boost.h
@@ -3,7 +3,7 @@
 u32 nvbios_boostTe(struct nvkm_bios *, u8 *, u8 *, u8 *, u8 *, u8 *, u8 *);
 
 struct nvbios_boostE {
-	u8  pstate;
+	u8  pstate_id;
 	u32 min;
 	u32 max;
 };
diff --git a/drm/nouveau/include/nvkm/subdev/bios/perf.h b/drm/nouveau/include/nvkm/subdev/bios/perf.h
index 478b1c0d..69800168 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/perf.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/perf.h
@@ -4,7 +4,7 @@ u32 nvbios_perf_table(struct nvkm_bios *, u8 *ver, u8 *hdr,
 		      u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
 
 struct nvbios_perfE {
-	u8  pstate;
+	u8  pstate_id;
 	u8  fanspeed;
 	u8  voltage;
 	u32 core;
diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 506f8cc6..1f4fa5f5 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -63,7 +63,7 @@ struct nvkm_pstate {
 	struct list_head head;
 	struct list_head list; /* c-states */
 	struct nvkm_cstate base;
-	u8 pstate;
+	u8 id;
 	u8 fanspeed;
 	enum nvkm_pcie_speed pcie_speed;
 	u8 pcie_width;
@@ -95,7 +95,7 @@ struct nvkm_clk {
 
 	struct nvkm_notify pwrsrc_ntfy;
 	int pwrsrc;
-	int pstate; /* current */
+	int pstate_idx; /* 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/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index 9109b69c..df7e2f29 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -63,10 +63,10 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
 		return ret;
 
 	for (i = 0; i < info.count + 1; i++) {
-		const s32 state = i < info.count ? i :
+		const s32 state_idx = i < info.count ? i :
 			NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT;
 		struct nvif_control_pstate_attr_v0 attr = {
-			.state = state,
+			.state = state_idx,
 			.index = 0,
 		};
 
@@ -83,7 +83,7 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
 
 		attr.index = 0;
 		do {
-			attr.state = state;
+			attr.state = state_idx;
 			ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_ATTR,
 					&attr, sizeof(attr));
 			if (ret)
@@ -95,12 +95,12 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
 			seq_printf(m, " %s", attr.unit);
 		} while (attr.index);
 
-		if (state >= 0) {
-			if (info.ustate_ac == state)
+		if (state_idx >= 0) {
+			if (info.ustate_ac == state_idx)
 				seq_printf(m, " AC");
-			if (info.ustate_dc == state)
+			if (info.ustate_dc == state_idx)
 				seq_printf(m, " DC");
-			if (info.pstate == state)
+			if (info.pstate == state_idx)
 				seq_printf(m, " *");
 		} else {
 			if (info.ustate_ac < -1)
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c b/drm/nouveau/nvkm/engine/device/ctrl.c
index b0ece71a..e07948e6 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -52,7 +52,7 @@ 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;
+		args->v0.pstate = clk->pstate_idx;
 	} else {
 		args->v0.count = 0;
 		args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
@@ -115,7 +115,7 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void *data, u32 size)
 			hi = max(hi, cstate->domain[domain->name]);
 		}
 
-		args->v0.state = pstate->pstate;
+		args->v0.state = pstate->id;
 	} else {
 		lo = max(nvkm_clk_read(clk, domain->name), 0);
 		hi = lo;
diff --git a/drm/nouveau/nvkm/subdev/bios/boost.c b/drm/nouveau/nvkm/subdev/bios/boost.c
index 8ab896dd..6554e937 100644
--- a/drm/nouveau/nvkm/subdev/bios/boost.c
+++ b/drm/nouveau/nvkm/subdev/bios/boost.c
@@ -78,20 +78,21 @@ nvbios_boostEp(struct nvkm_bios *bios, int idx,
 	u32 data = nvbios_boostEe(bios, idx, ver, hdr, cnt, len);
 	memset(info, 0x00, sizeof(*info));
 	if (data) {
-		info->pstate = (nvbios_rd16(bios, data + 0x00) & 0x01e0) >> 5;
-		info->min    =  nvbios_rd16(bios, data + 0x02) * 1000;
-		info->max    =  nvbios_rd16(bios, data + 0x04) * 1000;
+		info->pstate_id =
+			(nvbios_rd16(bios, data + 0x00) & 0x01e0) >> 5;
+		info->min       =  nvbios_rd16(bios, data + 0x02) * 1000;
+		info->max       =  nvbios_rd16(bios, data + 0x04) * 1000;
 	}
 	return data;
 }
 
 u32
-nvbios_boostEm(struct nvkm_bios *bios, u8 pstate,
+nvbios_boostEm(struct nvkm_bios *bios, u8 pstate_id,
 	       u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info)
 {
 	u32 data, idx = 0;
 	while ((data = nvbios_boostEp(bios, idx++, ver, hdr, cnt, len, info))) {
-		if (info->pstate == pstate)
+		if (info->pstate_id == pstate_id)
 			break;
 	}
 	return data;
diff --git a/drm/nouveau/nvkm/subdev/bios/perf.c b/drm/nouveau/nvkm/subdev/bios/perf.c
index c3068358..82ba4300 100644
--- a/drm/nouveau/nvkm/subdev/bios/perf.c
+++ b/drm/nouveau/nvkm/subdev/bios/perf.c
@@ -97,7 +97,7 @@ nvbios_perfEp(struct nvkm_bios *bios, int idx,
 {
 	u32 perf = nvbios_perf_entry(bios, idx, ver, hdr, cnt, len);
 	memset(info, 0x00, sizeof(*info));
-	info->pstate = nvbios_rd08(bios, perf + 0x00);
+	info->pstate_id = nvbios_rd08(bios, perf + 0x00);
 	switch (!!perf * *ver) {
 	case 0x12:
 	case 0x13:
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 0b28dbb9..77a0624a 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -39,14 +39,15 @@
  *****************************************************************************/
 static u32
 nvkm_clk_adjust(struct nvkm_clk *clk, bool adjust,
-		u8 pstate, u8 domain, u32 input)
+		u8 pstate_id, u8 domain, u32 input)
 {
 	struct nvkm_bios *bios = clk->subdev.device->bios;
 	struct nvbios_boostE boostE;
 	u8  ver, hdr, cnt, len;
 	u32 data;
 
-	data = nvbios_boostEm(bios, pstate, &ver, &hdr, &cnt, &len, &boostE);
+	data = nvbios_boostEm(bios, pstate_id, &ver, &hdr, &cnt, &len,
+			      &boostE);
 	if (data) {
 		struct nvbios_boostS boostS;
 		u8  idx = 0, sver, shdr;
@@ -143,14 +144,14 @@ nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 }
 
 static struct nvkm_cstate *
-nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
+nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstate_id)
 {
 	struct nvkm_cstate *cstate;
-	if (cstatei == NVKM_CLK_CSTATE_HIGHEST)
+	if (cstate_id == NVKM_CLK_CSTATE_HIGHEST)
 		return list_last_entry(&pstate->list, typeof(*cstate), head);
 	else {
 		list_for_each_entry(cstate, &pstate->list, head) {
-			if (cstate->id == cstatei)
+			if (cstate->id == cstate_id)
 				return cstate;
 		}
 	}
@@ -158,7 +159,8 @@ nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 }
 
 static int
-nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
+nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
+		 int cstate_id)
 {
 	struct nvkm_subdev *subdev = &clk->subdev;
 	struct nvkm_device *device = subdev->device;
@@ -168,7 +170,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 	int ret;
 
 	if (!list_empty(&pstate->list)) {
-		cstate = nvkm_cstate_get(clk, pstate, cstatei);
+		cstate = nvkm_cstate_get(clk, pstate, cstate_id);
 		cstate = nvkm_cstate_find_best(clk, pstate, cstate);
 	} else {
 		cstate = &pstate->base;
@@ -248,7 +250,7 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
 
 	while (domain && domain->name != nv_clk_src_max) {
 		if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) {
-			u32 freq = nvkm_clk_adjust(clk, true, pstate->pstate,
+			u32 freq = nvkm_clk_adjust(clk, true, pstate->id,
 						   domain->bios, cstepX.freq);
 			cstate->domain[domain->name] = freq;
 		}
@@ -263,7 +265,7 @@ 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 pstate_idx)
 {
 	struct nvkm_subdev *subdev = &clk->subdev;
 	struct nvkm_fb *fb = subdev->device->fb;
@@ -272,12 +274,12 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
 	int ret, idx = 0;
 
 	list_for_each_entry(pstate, &clk->states, head) {
-		if (idx++ == pstatei)
+		if (idx++ == pstate_idx)
 			break;
 	}
 
-	nvkm_debug(subdev, "setting performance state %d\n", pstatei);
-	clk->pstate = pstatei;
+	nvkm_debug(subdev, "setting performance state %d\n", pstate_idx);
+	clk->pstate_idx = pstate_idx;
 
 	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
 
@@ -300,31 +302,31 @@ nvkm_pstate_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_idx;
 
 	if (!atomic_xchg(&clk->waiting, 0))
 		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°C D %d\n",
-		   clk->pstate, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
+		   clk->pstate_idx, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
 		   clk->astate, clk->temp, clk->dstate);
 
-	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);
-		pstate = max(pstate, clk->dstate);
+	pstate_idx = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
+	if (clk->state_nr && pstate_idx != -1) {
+		pstate_idx = (pstate_idx < 0) ? clk->astate : pstate_idx;
+		pstate_idx = min(pstate_idx, clk->state_nr - 1);
+		pstate_idx = max(pstate_idx, clk->dstate);
 	} else {
-		pstate = clk->pstate = -1;
+		pstate_idx = clk->pstate_idx = -1;
 	}
 
-	nvkm_trace(subdev, "-> %d\n", pstate);
-	if (pstate != clk->pstate) {
-		int ret = nvkm_pstate_prog(clk, pstate);
+	nvkm_trace(subdev, "-> %d\n", pstate_idx);
+	if (pstate_idx != clk->pstate_idx) {
+		int ret = nvkm_pstate_prog(clk, pstate_idx);
 		if (ret) {
 			nvkm_error(subdev, "error setting pstate %d: %d\n",
-				   pstate, ret);
+				   pstate_idx, ret);
 		}
 	}
 
@@ -352,8 +354,8 @@ nvkm_pstate_info(struct nvkm_clk *clk, struct nvkm_pstate *pstate)
 	char name[4] = "--";
 	int i = -1;
 
-	if (pstate->pstate != 0xff)
-		snprintf(name, sizeof(name), "%02x", pstate->pstate);
+	if (pstate->id != 0xff)
+		snprintf(name, sizeof(name), "%02x", pstate->id);
 
 	while ((++clock)->name != nv_clk_src_max) {
 		u32 lo = pstate->base.domain[clock->name];
@@ -413,7 +415,7 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
 	data = nvbios_perfEp(bios, idx, &ver, &hdr, &cnt, &len, &perfE);
 	if (!data)
 		return -EINVAL;
-	if (perfE.pstate == 0xff)
+	if (perfE.pstate_id == 0xff)
 		return 0;
 
 	pstate = kzalloc(sizeof(*pstate), GFP_KERNEL);
@@ -423,7 +425,7 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
 
 	INIT_LIST_HEAD(&pstate->list);
 
-	pstate->pstate = perfE.pstate;
+	pstate->id = perfE.pstate_id;
 	pstate->fanspeed = perfE.fanspeed;
 	pstate->pcie_speed = perfE.pcie_speed;
 	pstate->pcie_width = perfE.pcie_width;
@@ -444,7 +446,7 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
 
 		if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) {
 			perfS.v40.freq = nvkm_clk_adjust(clk, false,
-							 pstate->pstate,
+							 pstate->id,
 							 domain->bios,
 							 perfS.v40.freq);
 		}
@@ -452,7 +454,7 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
 		cstate->domain[domain->name] = perfS.v40.freq;
 	}
 
-	data = nvbios_cstepEm(bios, pstate->pstate, &ver, &hdr, &cstepE);
+	data = nvbios_cstepEm(bios, pstate->id, &ver, &hdr, &cstepE);
 	if (data) {
 		int idx = cstepE.index;
 		do {
@@ -480,12 +482,12 @@ nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
 
 	if (req != -1 && req != -2) {
 		list_for_each_entry(pstate, &clk->states, head) {
-			if (pstate->pstate == req)
+			if (pstate->id == req)
 				break;
 			i++;
 		}
 
-		if (pstate->pstate != req)
+		if (pstate->id != req)
 			return -EINVAL;
 		req = i;
 	}
@@ -597,7 +599,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 
 	memset(&clk->bstate, 0x00, sizeof(clk->bstate));
 	INIT_LIST_HEAD(&clk->bstate.list);
-	clk->bstate.pstate = 0xff;
+	clk->bstate.id = 0xff;
 
 	while (clock->name != nv_clk_src_max) {
 		ret = nvkm_clk_read(clk, clock->name);
@@ -616,7 +618,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 
 	clk->astate = clk->state_nr - 1;
 	clk->dstate = 0;
-	clk->pstate = -1;
+	clk->pstate_idx = -1;
 	clk->temp = 90; /* reasonable default value */
 	nvkm_pstate_calc(clk, true);
 	return 0;
diff --git a/drm/nouveau/nvkm/subdev/clk/gk20a.c b/drm/nouveau/nvkm/subdev/clk/gk20a.c
index 218893e3..dc98ad62 100644
--- a/drm/nouveau/nvkm/subdev/clk/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/clk/gk20a.c
@@ -622,7 +622,7 @@ gk20a_clk_ctor(struct nvkm_device *device, int index,
 	/* Finish initializing the pstates */
 	for (i = 0; i < func->nr_pstates; i++) {
 		INIT_LIST_HEAD(&func->pstates[i].list);
-		func->pstates[i].pstate = i + 1;
+		func->pstates[i].id = i + 1;
 	}
 
 	clk->params = params;
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index 05e81855..0c169215 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -60,7 +60,7 @@ gk20a_pmu_dvfs_get_cur_state(struct gk20a_pmu *pmu, int *state)
 {
 	struct nvkm_clk *clk = pmu->base.subdev.device->clk;
 
-	*state = clk->pstate;
+	*state = clk->pstate_idx;
 }
 
 static int
@@ -72,7 +72,7 @@ gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu *pmu,
 	int cur_level, level;
 
 	/* For GK20A, the performance level is directly mapped to pstate */
-	level = cur_level = clk->pstate;
+	level = cur_level = clk->pstate_idx;
 
 	if (load > data->p_load_max) {
 		level = min(clk->state_nr - 1, level + (clk->state_nr / 3));
-- 
2.15.0

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

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

* [PATCH 06/32] clk: Add NVKM_CLK_PSTATE_BOOT
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (4 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 05/32] clk: Improve names of pstate/cstate related variables and fields Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 07/32] clk: Rename NVKM_CLK_CSTATE_HIGHEST to NVKM_CLK_CSTATE_AUTO Karol Herbst
                     ` (25 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Karol Herbst <kherbst@redhat.com>

It is better using a constant than -1.

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

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 1f4fa5f5..d77843f5 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -6,6 +6,8 @@
 struct nvbios_pll;
 struct nvkm_pll_vals;
 
+#define NVKM_CLK_PSTATE_BOOT    -1 /* POSTed default */
+
 #define NVKM_CLK_CSTATE_DEFAULT -1 /* POSTed default */
 #define NVKM_CLK_CSTATE_BASE    -2 /* pstate base */
 #define NVKM_CLK_CSTATE_HIGHEST -3 /* highest possible */
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 77a0624a..96a09575 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -313,12 +313,12 @@ nvkm_pstate_work(struct work_struct *work)
 		   clk->astate, clk->temp, clk->dstate);
 
 	pstate_idx = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
-	if (clk->state_nr && pstate_idx != -1) {
+	if (clk->state_nr && pstate_idx != NVKM_CLK_PSTATE_BOOT) {
 		pstate_idx = (pstate_idx < 0) ? clk->astate : pstate_idx;
 		pstate_idx = min(pstate_idx, clk->state_nr - 1);
 		pstate_idx = max(pstate_idx, clk->dstate);
 	} else {
-		pstate_idx = clk->pstate_idx = -1;
+		pstate_idx = clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
 	}
 
 	nvkm_trace(subdev, "-> %d\n", pstate_idx);
@@ -618,7 +618,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 
 	clk->astate = clk->state_nr - 1;
 	clk->dstate = 0;
-	clk->pstate_idx = -1;
+	clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
 	clk->temp = 90; /* reasonable default value */
 	nvkm_pstate_calc(clk, true);
 	return 0;
@@ -673,8 +673,8 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	clk->func = func;
 	INIT_LIST_HEAD(&clk->states);
 	clk->domains = func->domains;
-	clk->ustate_ac = -1;
-	clk->ustate_dc = -1;
+	clk->ustate_ac = NVKM_CLK_PSTATE_BOOT;
+	clk->ustate_dc = NVKM_CLK_PSTATE_BOOT;
 	clk->allow_reclock = allow_reclock;
 
 	INIT_WORK(&clk->work, nvkm_pstate_work);
-- 
2.15.0

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

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

* [PATCH 07/32] clk: Rename NVKM_CLK_CSTATE_HIGHEST to NVKM_CLK_CSTATE_AUTO
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (5 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 06/32] clk: Add NVKM_CLK_PSTATE_BOOT Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 08/32] clk: Rename nvkm_clk.states to pstates Karol Herbst
                     ` (24 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Karol Herbst <kherbst@redhat.com>

It is better describing what it is.

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

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index d77843f5..dcc93950 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -10,7 +10,7 @@ struct nvkm_pll_vals;
 
 #define NVKM_CLK_CSTATE_DEFAULT -1 /* POSTed default */
 #define NVKM_CLK_CSTATE_BASE    -2 /* pstate base */
-#define NVKM_CLK_CSTATE_HIGHEST -3 /* highest possible */
+#define NVKM_CLK_CSTATE_AUTO    -3 /* highest possible */
 
 enum nv_clk_src {
 	nv_clk_src_crystal,
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 96a09575..6229cb6a 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -147,7 +147,7 @@ static struct nvkm_cstate *
 nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstate_id)
 {
 	struct nvkm_cstate *cstate;
-	if (cstate_id == NVKM_CLK_CSTATE_HIGHEST)
+	if (cstate_id == NVKM_CLK_CSTATE_AUTO)
 		return list_last_entry(&pstate->list, typeof(*cstate), head);
 	else {
 		list_for_each_entry(cstate, &pstate->list, head) {
@@ -294,7 +294,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_idx)
 		ram->func->tidy(ram);
 	}
 
-	return nvkm_cstate_prog(clk, pstate, NVKM_CLK_CSTATE_HIGHEST);
+	return nvkm_cstate_prog(clk, pstate, NVKM_CLK_CSTATE_AUTO);
 }
 
 static void
-- 
2.15.0

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

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

* [PATCH 08/32] clk: Rename nvkm_clk.states to pstates
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (6 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 07/32] clk: Rename NVKM_CLK_CSTATE_HIGHEST to NVKM_CLK_CSTATE_AUTO Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 09/32] clk: Rename nvkm_pstate.list to cstates Karol Herbst
                     ` (23 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Karol Herbst <kherbst@redhat.com>

Those are pstates, so call them that way.

Signed-off-by: Karol Herbst <kherbst@redhat.com>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  4 ++--
 drm/nouveau/nvkm/engine/device/ctrl.c |  6 +++---
 drm/nouveau/nvkm/subdev/clk/base.c    | 26 +++++++++++++-------------
 drm/nouveau/nvkm/subdev/pmu/gk20a.c   |  5 +++--
 4 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index dcc93950..2f326554 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -88,8 +88,8 @@ struct nvkm_clk {
 	const struct nvkm_domain *domains;
 	struct nvkm_pstate bstate;
 
-	struct list_head states;
-	int state_nr;
+	struct list_head pstates;
+	int pstates_cnt;
 
 	struct work_struct work;
 	wait_queue_head_t wait;
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c b/drm/nouveau/nvkm/engine/device/ctrl.c
index e07948e6..279e442e 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -48,7 +48,7 @@ nvkm_control_mthd_pstate_info(struct nvkm_control *ctrl, void *data, u32 size)
 		return ret;
 
 	if (clk) {
-		args->v0.count = clk->state_nr;
+		args->v0.count = clk->pstates_cnt;
 		args->v0.ustate_ac = clk->ustate_ac;
 		args->v0.ustate_dc = clk->ustate_dc;
 		args->v0.pwrsrc = clk->pwrsrc;
@@ -87,7 +87,7 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void *data, u32 size)
 			return -ENODEV;
 		if (args->v0.state < NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT)
 			return -EINVAL;
-		if (args->v0.state >= clk->state_nr)
+		if (args->v0.state >= clk->pstates_cnt)
 			return -EINVAL;
 	} else
 		return ret;
@@ -103,7 +103,7 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void *data, u32 size)
 		return -EINVAL;
 
 	if (args->v0.state != NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) {
-		list_for_each_entry(pstate, &clk->states, head) {
+		list_for_each_entry(pstate, &clk->pstates, head) {
 			if (i++ == args->v0.state)
 				break;
 		}
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 6229cb6a..ef6ad783 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -273,7 +273,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_idx)
 	struct nvkm_pstate *pstate;
 	int ret, idx = 0;
 
-	list_for_each_entry(pstate, &clk->states, head) {
+	list_for_each_entry(pstate, &clk->pstates, head) {
 		if (idx++ == pstate_idx)
 			break;
 	}
@@ -313,9 +313,9 @@ nvkm_pstate_work(struct work_struct *work)
 		   clk->astate, clk->temp, clk->dstate);
 
 	pstate_idx = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
-	if (clk->state_nr && pstate_idx != NVKM_CLK_PSTATE_BOOT) {
+	if (clk->pstates_cnt && pstate_idx != NVKM_CLK_PSTATE_BOOT) {
 		pstate_idx = (pstate_idx < 0) ? clk->astate : pstate_idx;
-		pstate_idx = min(pstate_idx, clk->state_nr - 1);
+		pstate_idx = min(pstate_idx, clk->pstates_cnt - 1);
 		pstate_idx = max(pstate_idx, clk->dstate);
 	} else {
 		pstate_idx = clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
@@ -463,8 +463,8 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
 	}
 
 	nvkm_pstate_info(clk, pstate);
-	list_add_tail(&pstate->head, &clk->states);
-	clk->state_nr++;
+	list_add_tail(&pstate->head, &clk->pstates);
+	clk->pstates_cnt++;
 	return 0;
 }
 
@@ -481,7 +481,7 @@ nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
 		return -ENOSYS;
 
 	if (req != -1 && req != -2) {
-		list_for_each_entry(pstate, &clk->states, head) {
+		list_for_each_entry(pstate, &clk->pstates, head) {
 			if (pstate->id == req)
 				break;
 			i++;
@@ -536,7 +536,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
 {
 	if (!rel) clk->astate  = req;
 	if ( rel) clk->astate += rel;
-	clk->astate = min(clk->astate, clk->state_nr - 1);
+	clk->astate = min(clk->astate, clk->pstates_cnt - 1);
 	clk->astate = max(clk->astate, 0);
 	return nvkm_pstate_calc(clk, wait);
 }
@@ -555,7 +555,7 @@ 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 = min(clk->dstate, clk->pstates_cnt - 1);
 	clk->dstate = max(clk->dstate, 0);
 	return nvkm_pstate_calc(clk, true);
 }
@@ -616,7 +616,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 = clk->pstates_cnt - 1;
 	clk->dstate = 0;
 	clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
 	clk->temp = 90; /* reasonable default value */
@@ -636,7 +636,7 @@ nvkm_clk_dtor(struct nvkm_subdev *subdev)
 	if (clk->func->pstates)
 		return clk;
 
-	list_for_each_entry_safe(pstate, temp, &clk->states, head) {
+	list_for_each_entry_safe(pstate, temp, &clk->pstates, head) {
 		nvkm_pstate_del(pstate);
 	}
 
@@ -671,7 +671,7 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	}
 
 	clk->func = func;
-	INIT_LIST_HEAD(&clk->states);
+	INIT_LIST_HEAD(&clk->pstates);
 	clk->domains = func->domains;
 	clk->ustate_ac = NVKM_CLK_PSTATE_BOOT;
 	clk->ustate_dc = NVKM_CLK_PSTATE_BOOT;
@@ -689,8 +689,8 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 		} while (ret == 0);
 	} else {
 		for (idx = 0; idx < func->nr_pstates; idx++)
-			list_add_tail(&func->pstates[idx].head, &clk->states);
-		clk->state_nr = func->nr_pstates;
+			list_add_tail(&func->pstates[idx].head, &clk->pstates);
+		clk->pstates_cnt = func->nr_pstates;
 	}
 
 	ret = nvkm_notify_init(NULL, &device->event, nvkm_clk_pwrsrc, true,
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index 0c169215..f5abc664 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -75,12 +75,13 @@ gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu *pmu,
 	level = cur_level = clk->pstate_idx;
 
 	if (load > data->p_load_max) {
-		level = min(clk->state_nr - 1, level + (clk->state_nr / 3));
+		level = min(clk->pstates_cnt - 1,
+			    level + (clk->pstates_cnt / 3));
 	} else {
 		level += ((load - data->p_load_target) * 10 /
 				data->p_load_target) / 2;
 		level = max(0, level);
-		level = min(clk->state_nr - 1, level);
+		level = min(clk->pstates_cnt - 1, level);
 	}
 
 	nvkm_trace(&pmu->base.subdev, "cur level = %d, new level = %d\n",
-- 
2.15.0

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

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

* [PATCH 09/32] clk: Rename nvkm_pstate.list to cstates
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (7 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 08/32] clk: Rename nvkm_clk.states to pstates Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 10/32] clk: Remove dstate Karol Herbst
                     ` (22 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Karol Herbst <kherbst@redhat.com>

It was always confusing that the list was called list.

Signed-off-by: Karol Herbst <kherbst@redhat.com>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  2 +-
 drm/nouveau/nvkm/engine/device/ctrl.c |  2 +-
 drm/nouveau/nvkm/subdev/clk/base.c    | 18 +++++++++---------
 drm/nouveau/nvkm/subdev/clk/gk20a.c   |  2 +-
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 2f326554..32f733c3 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -63,7 +63,7 @@ struct nvkm_cstate {
 
 struct nvkm_pstate {
 	struct list_head head;
-	struct list_head list; /* c-states */
+	struct list_head cstates; /* c-states */
 	struct nvkm_cstate base;
 	u8 id;
 	u8 fanspeed;
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c b/drm/nouveau/nvkm/engine/device/ctrl.c
index 279e442e..1202e656 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -110,7 +110,7 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void *data, u32 size)
 
 		lo = pstate->base.domain[domain->name];
 		hi = lo;
-		list_for_each_entry(cstate, &pstate->list, head) {
+		list_for_each_entry(cstate, &pstate->cstates, head) {
 			lo = min(lo, cstate->domain[domain->name]);
 			hi = max(hi, cstate->domain[domain->name]);
 		}
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index ef6ad783..b268b8fd 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -134,7 +134,7 @@ nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 		max_volt = min(max_volt,
 			       nvkm_volt_map(volt, volt->max2_id, clk->temp));
 
-	for (cstate = start; &cstate->head != &pstate->list;
+	for (cstate = start; &cstate->head != &pstate->cstates;
 	     cstate = list_entry(cstate->head.prev, typeof(*cstate), head)) {
 		if (nvkm_cstate_valid(clk, cstate, max_volt, clk->temp))
 			break;
@@ -148,9 +148,9 @@ nvkm_cstate_get(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstate_id)
 {
 	struct nvkm_cstate *cstate;
 	if (cstate_id == NVKM_CLK_CSTATE_AUTO)
-		return list_last_entry(&pstate->list, typeof(*cstate), head);
+		return list_last_entry(&pstate->cstates, typeof(*cstate), head);
 	else {
-		list_for_each_entry(cstate, &pstate->list, head) {
+		list_for_each_entry(cstate, &pstate->cstates, head) {
 			if (cstate->id == cstate_id)
 				return cstate;
 		}
@@ -169,7 +169,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 	struct nvkm_cstate *cstate;
 	int ret;
 
-	if (!list_empty(&pstate->list)) {
+	if (!list_empty(&pstate->cstates)) {
 		cstate = nvkm_cstate_get(clk, pstate, cstate_id);
 		cstate = nvkm_cstate_find_best(clk, pstate, cstate);
 	} else {
@@ -257,7 +257,7 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
 		domain++;
 	}
 
-	list_add(&cstate->head, &pstate->list);
+	list_add(&cstate->head, &pstate->cstates);
 	return 0;
 }
 
@@ -364,7 +364,7 @@ nvkm_pstate_info(struct nvkm_clk *clk, struct nvkm_pstate *pstate)
 			continue;
 
 		nvkm_debug(subdev, "%02x: %10d KHz\n", clock->name, lo);
-		list_for_each_entry(cstate, &pstate->list, head) {
+		list_for_each_entry(cstate, &pstate->cstates, head) {
 			u32 freq = cstate->domain[clock->name];
 			lo = min(lo, freq);
 			hi = max(hi, freq);
@@ -392,7 +392,7 @@ nvkm_pstate_del(struct nvkm_pstate *pstate)
 {
 	struct nvkm_cstate *cstate, *temp;
 
-	list_for_each_entry_safe(cstate, temp, &pstate->list, head) {
+	list_for_each_entry_safe(cstate, temp, &pstate->cstates, head) {
 		nvkm_cstate_del(cstate);
 	}
 
@@ -423,7 +423,7 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
 	if (!pstate)
 		return -ENOMEM;
 
-	INIT_LIST_HEAD(&pstate->list);
+	INIT_LIST_HEAD(&pstate->cstates);
 
 	pstate->id = perfE.pstate_id;
 	pstate->fanspeed = perfE.fanspeed;
@@ -598,7 +598,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 	int ret;
 
 	memset(&clk->bstate, 0x00, sizeof(clk->bstate));
-	INIT_LIST_HEAD(&clk->bstate.list);
+	INIT_LIST_HEAD(&clk->bstate.cstates);
 	clk->bstate.id = 0xff;
 
 	while (clock->name != nv_clk_src_max) {
diff --git a/drm/nouveau/nvkm/subdev/clk/gk20a.c b/drm/nouveau/nvkm/subdev/clk/gk20a.c
index dc98ad62..07e5b00b 100644
--- a/drm/nouveau/nvkm/subdev/clk/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/clk/gk20a.c
@@ -621,7 +621,7 @@ gk20a_clk_ctor(struct nvkm_device *device, int index,
 
 	/* Finish initializing the pstates */
 	for (i = 0; i < func->nr_pstates; i++) {
-		INIT_LIST_HEAD(&func->pstates[i].list);
+		INIT_LIST_HEAD(&func->pstates[i].cstates);
 		func->pstates[i].id = i + 1;
 	}
 
-- 
2.15.0

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

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

* [PATCH 10/32] clk: Remove dstate
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (8 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 09/32] clk: Rename nvkm_pstate.list to cstates Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 11/32] clk: Rename nvkm_pstate_calc to nvkm_clk_update and export it Karol Herbst
                     ` (21 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

We won't need it now, because we will adjust the clocks depending on engine
loads later on anyway or a static lookup table. It also simplifies the
clocking logic.

This code was nowhere used anyway and just a mock up.

v2: fixed typo in commit message

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Reviewed-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  2 --
 drm/nouveau/nvkm/subdev/clk/base.c    | 16 ++--------------
 2 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 32f733c3..4f763309 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -101,7 +101,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 dstate; /* display adjustment (min+) */
 	int temp;
 
 	bool allow_reclock;
@@ -123,7 +122,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 temperature);
 
 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 b268b8fd..83b18d88 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -308,15 +308,14 @@ nvkm_pstate_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°C D %d\n",
+	nvkm_trace(subdev, "P %d PWR %d U(AC) %d U(DC) %d A %d T %d°C\n",
 		   clk->pstate_idx, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
-		   clk->astate, clk->temp, clk->dstate);
+		   clk->astate, clk->temp);
 
 	pstate_idx = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
 	if (clk->pstates_cnt && pstate_idx != NVKM_CLK_PSTATE_BOOT) {
 		pstate_idx = (pstate_idx < 0) ? clk->astate : pstate_idx;
 		pstate_idx = min(pstate_idx, clk->pstates_cnt - 1);
-		pstate_idx = max(pstate_idx, clk->dstate);
 	} else {
 		pstate_idx = clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
 	}
@@ -550,16 +549,6 @@ nvkm_clk_tstate(struct nvkm_clk *clk, int temp)
 	return nvkm_pstate_calc(clk, false);
 }
 
-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->pstates_cnt - 1);
-	clk->dstate = max(clk->dstate, 0);
-	return nvkm_pstate_calc(clk, true);
-}
-
 static int
 nvkm_clk_pwrsrc(struct nvkm_notify *notify)
 {
@@ -617,7 +606,6 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 		return clk->func->init(clk);
 
 	clk->astate = clk->pstates_cnt - 1;
-	clk->dstate = 0;
 	clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
 	clk->temp = 90; /* reasonable default value */
 	nvkm_pstate_calc(clk, true);
-- 
2.15.0

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

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

* [PATCH 11/32] clk: Rename nvkm_pstate_calc to nvkm_clk_update and export it
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (9 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 10/32] clk: Remove dstate Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 12/32] clk: Use list_for_each_entry_from_reverse in nvkm_cstate_find_best Karol Herbst
                     ` (20 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 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
  * User changes clocking state
  * Load changes

v2: remove parameter name

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

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 4f763309..44751db4 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -123,6 +123,7 @@ 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_tstate(struct nvkm_clk *, int temperature);
+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 83b18d88..254b62f8 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -298,7 +298,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_idx)
 }
 
 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;
@@ -333,9 +333,15 @@ nvkm_pstate_work(struct work_struct *work)
 	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)
@@ -525,7 +531,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;
 }
@@ -537,7 +543,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->pstates_cnt - 1);
 	clk->astate = max(clk->astate, 0);
-	return nvkm_pstate_calc(clk, wait);
+	return nvkm_clk_update(clk, wait);
 }
 
 int
@@ -546,7 +552,7 @@ nvkm_clk_tstate(struct nvkm_clk *clk, int temp)
 	if (clk->temp == temp)
 		return 0;
 	clk->temp = temp;
-	return nvkm_pstate_calc(clk, false);
+	return nvkm_clk_update(clk, false);
 }
 
 static int
@@ -554,7 +560,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;
 }
 
@@ -608,7 +614,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 	clk->astate = clk->pstates_cnt - 1;
 	clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
 	clk->temp = 90; /* reasonable default value */
-	nvkm_pstate_calc(clk, true);
+	nvkm_clk_update(clk, true);
 	return 0;
 }
 
@@ -665,7 +671,7 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	clk->ustate_dc = NVKM_CLK_PSTATE_BOOT;
 	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.15.0

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

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

* [PATCH 12/32] clk: Use list_for_each_entry_from_reverse in nvkm_cstate_find_best
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (10 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 11/32] clk: Rename nvkm_pstate_calc to nvkm_clk_update and export it Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 13/32] clk: We should pass the pstate id around not the index in the list Karol Herbst
                     ` (19 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Karol Herbst <kherbst@redhat.com>

Signed-off-by: Karol Herbst <kherbst@redhat.com>
---
 drm/nouveau/nvkm/subdev/clk/base.c | 10 ++++------
 lib/include/nvif/list.h            |  5 +++++
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 254b62f8..979f2cc3 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -110,18 +110,17 @@ nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate,
 
 static struct nvkm_cstate *
 nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
-		      struct nvkm_cstate *start)
+		      struct nvkm_cstate *cstate)
 {
 	struct nvkm_device *device = clk->subdev.device;
 	struct nvkm_volt *volt = device->volt;
-	struct nvkm_cstate *cstate;
 	int max_volt;
 
-	if (!pstate || !start)
+	if (!pstate || !cstate)
 		return NULL;
 
 	if (!volt)
-		return start;
+		return cstate;
 
 	max_volt = volt->max_uv;
 	if (volt->max0_id != 0xff)
@@ -134,8 +133,7 @@ nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 		max_volt = min(max_volt,
 			       nvkm_volt_map(volt, volt->max2_id, clk->temp));
 
-	for (cstate = start; &cstate->head != &pstate->cstates;
-	     cstate = list_entry(cstate->head.prev, typeof(*cstate), head)) {
+	list_for_each_entry_from_reverse(cstate, &pstate->cstates, head) {
 		if (nvkm_cstate_valid(clk, cstate, max_volt, clk->temp))
 			break;
 	}
diff --git a/lib/include/nvif/list.h b/lib/include/nvif/list.h
index 6a7e15ee..91e8387b 100644
--- a/lib/include/nvif/list.h
+++ b/lib/include/nvif/list.h
@@ -355,4 +355,9 @@ list_empty(struct list_head *head)
 	     &pos->member != (head);					\
 	     pos = __container_of(pos->member.next, pos, member))
 
+#define list_for_each_entry_from_reverse(pos, head, member)		\
+	for (;								\
+	     &pos->member != (head);					\
+	     pos = __container_of(pos->member.prev, pos, member))
+
 #endif
-- 
2.15.0

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

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

* [PATCH 13/32] clk: We should pass the pstate id around not the index in the list
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (11 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 12/32] clk: Use list_for_each_entry_from_reverse in nvkm_cstate_find_best Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 14/32] clk: Hold information about the current cstate status Karol Herbst
                     ` (18 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This makes the code easier, because we can compare the id with
pstate->id.

v2: reword commit message

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  2 +-
 drm/nouveau/nouveau_debugfs.c         |  6 +--
 drm/nouveau/nvkm/engine/device/ctrl.c |  2 +-
 drm/nouveau/nvkm/subdev/clk/base.c    | 98 ++++++++++++++++-------------------
 drm/nouveau/nvkm/subdev/pmu/gk20a.c   |  4 +-
 5 files changed, 52 insertions(+), 60 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 44751db4..ebaa57eb 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -97,7 +97,7 @@ struct nvkm_clk {
 
 	struct nvkm_notify pwrsrc_ntfy;
 	int pwrsrc;
-	int pstate_idx; /* current */
+	int pstate_id; /* 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/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index df7e2f29..7e1dbb03 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -96,11 +96,11 @@ nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
 		} while (attr.index);
 
 		if (state_idx >= 0) {
-			if (info.ustate_ac == state_idx)
+			if (info.ustate_ac == attr.state)
 				seq_printf(m, " AC");
-			if (info.ustate_dc == state_idx)
+			if (info.ustate_dc == attr.state)
 				seq_printf(m, " DC");
-			if (info.pstate == state_idx)
+			if (info.pstate == attr.state)
 				seq_printf(m, " *");
 		} else {
 			if (info.ustate_ac < -1)
diff --git a/drm/nouveau/nvkm/engine/device/ctrl.c b/drm/nouveau/nvkm/engine/device/ctrl.c
index 1202e656..bb92cefa 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -52,7 +52,7 @@ 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_idx;
+		args->v0.pstate = clk->pstate_id;
 	} 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 979f2cc3..85b9fb48 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -263,21 +263,27 @@ 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 pstate_idx)
+nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_id)
 {
 	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 (pstate_id == NVKM_CLK_PSTATE_BOOT)
+		return 0;
 
 	list_for_each_entry(pstate, &clk->pstates, head) {
-		if (idx++ == pstate_idx)
+		if (pstate->id == pstate_id)
 			break;
 	}
 
-	nvkm_debug(subdev, "setting performance state %d\n", pstate_idx);
-	clk->pstate_idx = pstate_idx;
+	if (!pstate)
+		return -EINVAL;
+
+	nvkm_debug(subdev, "setting performance state %x\n", pstate_id);
+	clk->pstate_id = pstate_id;
 
 	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
 
@@ -300,30 +306,28 @@ 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_idx;
+	int pstate_id;
 
 	if (!atomic_xchg(&clk->waiting, 0))
 		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°C\n",
-		   clk->pstate_idx, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
+	nvkm_trace(subdev, "P %x PWR %d U(AC) %d U(DC) %d A %d T %d°C\n",
+		   clk->pstate_id, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
 		   clk->astate, clk->temp);
 
-	pstate_idx = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
-	if (clk->pstates_cnt && pstate_idx != NVKM_CLK_PSTATE_BOOT) {
-		pstate_idx = (pstate_idx < 0) ? clk->astate : pstate_idx;
-		pstate_idx = min(pstate_idx, clk->pstates_cnt - 1);
-	} else {
-		pstate_idx = clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
-	}
+	pstate_id = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
+	if (clk->pstates_cnt && pstate_id != NVKM_CLK_PSTATE_BOOT)
+		pstate_id = (pstate_id < 0) ? clk->astate : pstate_id;
+	else
+		pstate_id = NVKM_CLK_PSTATE_BOOT;
 
-	nvkm_trace(subdev, "-> %d\n", pstate_idx);
-	if (pstate_idx != clk->pstate_idx) {
-		int ret = nvkm_pstate_prog(clk, pstate_idx);
+	nvkm_trace(subdev, "-> %x\n", pstate_id);
+	if (pstate_id != clk->pstate_id) {
+		int ret = nvkm_pstate_prog(clk, pstate_id);
 		if (ret) {
 			nvkm_error(subdev, "error setting pstate %d: %d\n",
-				   pstate_idx, ret);
+				   pstate_id, ret);
 		}
 	}
 
@@ -474,30 +478,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->pstates, head) {
-			if (pstate->id == req)
-				break;
-			i++;
-		}
-
-		if (pstate->id != req)
-			return -EINVAL;
-		req = i;
-	}
-
-	return req + 2;
-}
-
 static int
 nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, int arglen)
 {
@@ -512,26 +492,38 @@ 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 -EINVAL;
 }
 
 int
 nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
 {
-	int ret = nvkm_clk_ustate_update(clk, req);
-	if (ret >= 0) {
-		if (ret -= 2, pwr) clk->ustate_ac = ret;
-		else		   clk->ustate_dc = ret;
-		return nvkm_clk_update(clk, true);
+	struct nvkm_pstate *pstate;
+	bool valid = false;
+
+	list_for_each_entry(pstate, &clk->pstates, head) {
+		if (pstate->id == req) {
+			valid = true;
+			break;
+		}
 	}
-	return ret;
+
+	if (!valid)
+		return -EINVAL;
+
+	if (pwr)
+		clk->ustate_ac = req;
+	else
+		clk->ustate_dc = req;
+
+	return nvkm_clk_update(clk, true);
 }
 
 int
@@ -609,8 +601,8 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 	if (clk->func->init)
 		return clk->func->init(clk);
 
-	clk->astate = clk->pstates_cnt - 1;
-	clk->pstate_idx = NVKM_CLK_PSTATE_BOOT;
+	clk->astate = NVKM_CLK_PSTATE_BOOT;
+	clk->pstate_id = NVKM_CLK_PSTATE_BOOT;
 	clk->temp = 90; /* reasonable default value */
 	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 f5abc664..b316673f 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -60,7 +60,7 @@ gk20a_pmu_dvfs_get_cur_state(struct gk20a_pmu *pmu, int *state)
 {
 	struct nvkm_clk *clk = pmu->base.subdev.device->clk;
 
-	*state = clk->pstate_idx;
+	*state = clk->pstate_id;
 }
 
 static int
@@ -72,7 +72,7 @@ gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu *pmu,
 	int cur_level, level;
 
 	/* For GK20A, the performance level is directly mapped to pstate */
-	level = cur_level = clk->pstate_idx;
+	level = cur_level = clk->pstate_id;
 
 	if (load > data->p_load_max) {
 		level = min(clk->pstates_cnt - 1,
-- 
2.15.0

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

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

* [PATCH 14/32] clk: Hold information about the current cstate status
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (12 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 13/32] clk: We should pass the pstate id around not the index in the list Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 15/32] clk: Refactor the base and boost clock limits so that we can limit pstates Karol Herbst
                     ` (17 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Later we will have situations where the expected and the current state
isn't the same.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Acked-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/include/nvkm/subdev/clk.h | 9 +++++----
 drm/nouveau/nvkm/subdev/clk/base.c    | 5 +++++
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index ebaa57eb..310df485 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -6,11 +6,11 @@
 struct nvbios_pll;
 struct nvkm_pll_vals;
 
-#define NVKM_CLK_PSTATE_BOOT    -1 /* POSTed default */
+#define NVKM_CLK_PSTATE_BOOT -1 /* POSTed default */
 
-#define NVKM_CLK_CSTATE_DEFAULT -1 /* POSTed default */
-#define NVKM_CLK_CSTATE_BASE    -2 /* pstate base */
-#define NVKM_CLK_CSTATE_AUTO    -3 /* highest possible */
+#define NVKM_CLK_CSTATE_BOOT -1 /* POSTed default */
+#define NVKM_CLK_CSTATE_BASE -2 /* pstate base */
+#define NVKM_CLK_CSTATE_AUTO -3 /* highest possible */
 
 enum nv_clk_src {
 	nv_clk_src_crystal,
@@ -101,6 +101,7 @@ 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 cstate_id;
 	int temp;
 
 	bool allow_reclock;
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 85b9fb48..b2c1605e 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -167,6 +167,9 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 	struct nvkm_cstate *cstate;
 	int ret;
 
+	if (cstate_id == NVKM_CLK_CSTATE_BOOT)
+		return 0;
+
 	if (!list_empty(&pstate->cstates)) {
 		cstate = nvkm_cstate_get(clk, pstate, cstate_id);
 		cstate = nvkm_cstate_find_best(clk, pstate, cstate);
@@ -196,6 +199,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 		ret = clk->func->prog(clk);
 		clk->func->tidy(clk);
 	}
+	clk->cstate_id = cstate->id;
 
 	if (volt) {
 		ret = nvkm_volt_set_id(volt, cstate->voltage,
@@ -603,6 +607,7 @@ nvkm_clk_init(struct nvkm_subdev *subdev)
 
 	clk->astate = NVKM_CLK_PSTATE_BOOT;
 	clk->pstate_id = NVKM_CLK_PSTATE_BOOT;
+	clk->cstate_id = NVKM_CLK_CSTATE_BOOT;
 	clk->temp = 90; /* reasonable default value */
 	nvkm_clk_update(clk, true);
 	return 0;
-- 
2.15.0

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

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

* [PATCH 15/32] clk: Refactor the base and boost clock limits so that we can limit pstates
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (13 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 14/32] clk: Hold information about the current cstate status Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 16/32] therm: Move the temp readout into nvkm_therm_update Karol Herbst
                     ` (16 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  9 +++++--
 drm/nouveau/nvkm/subdev/clk/base.c    | 51 +++++++++++++++++++++++------------
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 310df485..9e05b088 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -81,6 +81,11 @@ struct nvkm_domain {
 	int mdiv;
 };
 
+struct nvkm_clk_limit {
+	u8  pstate;
+	u32 max_khz;
+};
+
 struct nvkm_clk {
 	const struct nvkm_clk_func *func;
 	struct nvkm_subdev subdev;
@@ -109,8 +114,8 @@ struct nvkm_clk {
 #define NVKM_CLK_BOOST_BIOS 0x1
 #define NVKM_CLK_BOOST_FULL 0x2
 	u8  boost_mode;
-	u32 base_khz;
-	u32 boost_khz;
+	struct nvkm_clk_limit base_limit;
+	struct nvkm_clk_limit boost_limit;
 
 	/*XXX: die, these are here *only* to support the completely
 	 *     bat-shit insane what-was-nouveau_hw.c code
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index b2c1605e..657456ce 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -83,20 +83,28 @@ nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate,
 	const struct nvkm_domain *domain = clk->domains;
 	struct nvkm_volt *volt = clk->subdev.device->volt;
 	int voltage;
+	u32 limit;
 
-	while (domain && domain->name != nv_clk_src_max) {
-		if (domain->flags & NVKM_CLK_DOM_FLAG_VPSTATE) {
-			u32 freq = cstate->domain[domain->name];
-			switch (clk->boost_mode) {
-			case NVKM_CLK_BOOST_NONE:
-				if (clk->base_khz && freq > clk->base_khz)
-					return false;
-			case NVKM_CLK_BOOST_BIOS:
-				if (clk->boost_khz && freq > clk->boost_khz)
-					return false;
-			}
+	switch (clk->boost_mode) {
+	case NVKM_CLK_BOOST_NONE:
+		limit = clk->base_limit.max_khz;
+		if (limit)
+			break;
+	case NVKM_CLK_BOOST_BIOS:
+		limit = clk->boost_limit.max_khz;
+		break;
+	default:
+		limit = 0;
+		break;
+	}
+
+	if (limit) {
+		for (; domain && domain->name != nv_clk_src_max; domain++) {
+			if (!(domain->flags & NVKM_CLK_DOM_FLAG_VPSTATE))
+				continue;
+			if (cstate->domain[domain->name] > limit)
+				return false;
 		}
-		domain++;
 	}
 
 	if (!volt)
@@ -639,6 +647,14 @@ nvkm_clk = {
 	.fini = nvkm_clk_fini,
 };
 
+static void
+nvkm_clk_fill_limit(struct nvkm_clk_limit *l,
+		    const struct nvbios_vpstate_entry *e)
+{
+	l->pstate = e->pstate;
+	l->max_khz = e->clock_mhz * 1000;
+}
+
 int
 nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	      int index, bool allow_reclock, struct nvkm_clk *clk)
@@ -652,11 +668,12 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	nvkm_subdev_ctor(&nvkm_clk, device, index, subdev);
 
 	if (bios && !nvbios_vpstate_parse(bios, &h)) {
-		struct nvbios_vpstate_entry base, boost;
-		if (!nvbios_vpstate_entry(bios, &h, h.boost_id, &boost))
-			clk->boost_khz = boost.clock_mhz * 1000;
-		if (!nvbios_vpstate_entry(bios, &h, h.base_id, &base))
-			clk->base_khz = base.clock_mhz * 1000;
+		struct nvbios_vpstate_entry vpe;
+
+		if (!nvbios_vpstate_entry(bios, &h, h.boost_id, &vpe))
+			nvkm_clk_fill_limit(&clk->boost_limit, &vpe);
+		if (!nvbios_vpstate_entry(bios, &h, h.base_id, &vpe))
+			nvkm_clk_fill_limit(&clk->base_limit, &vpe);
 	}
 
 	clk->func = func;
-- 
2.15.0

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

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

* [PATCH 16/32] therm: Move the temp readout into nvkm_therm_update
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (14 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 15/32] clk: Refactor the base and boost clock limits so that we can limit pstates Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 17/32] core/device: Move therm behind clk Karol Herbst
                     ` (15 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

It makes more sense to read out the temperature in the alarm, because we
want to do various things with it:
 1. adjust the fans
 2. notify the clk subdev about the changed temperature

v2: move into nvkm_therm_update

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/nvkm/subdev/therm/base.c | 34 ++++++++++++++--------------------
 1 file changed, 14 insertions(+), 20 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
index 8e5f6f7f..253da199 100644
--- a/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drm/nouveau/nvkm/subdev/therm/base.c
@@ -32,18 +32,13 @@ nvkm_therm_temp_get(struct nvkm_therm *therm, int *val)
 }
 
 static int
-nvkm_therm_update_trip(struct nvkm_therm *therm)
+nvkm_therm_update_trip(struct nvkm_therm *therm, int temp)
 {
-	int temp, ret;
 	struct nvbios_therm_trip_point *trip = therm->fan->bios.trip,
 				       *cur_trip = NULL,
 				       *last_trip = therm->last_trip;
 	u16 duty, i;
 
-	ret = therm->func->temp_get(therm, &temp);
-	if (ret < 0)
-		return ret;
-
 	/* look for the trip point corresponding to the current temperature */
 	cur_trip = NULL;
 	for (i = 0; i < therm->fan->bios.nr_fan_trip; i++) {
@@ -69,15 +64,10 @@ nvkm_therm_update_trip(struct nvkm_therm *therm)
 
 static int
 nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
-                               u8 linear_max_temp)
+			       u8 linear_max_temp, int temp)
 {
-	int temp, ret;
 	u16 duty;
 
-	ret = therm->func->temp_get(therm, &temp);
-	if (ret < 0)
-		return ret;
-
 	/* handle the non-linear part first */
 	if (temp < linear_min_temp)
 		return therm->fan->bios.min_duty;
@@ -93,18 +83,18 @@ nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
 }
 
 static int
-nvkm_therm_update_linear(struct nvkm_therm *therm)
+nvkm_therm_update_linear(struct nvkm_therm *therm, int temp)
 {
 	u8  min = therm->fan->bios.linear_min_temp;
 	u8  max = therm->fan->bios.linear_max_temp;
-	return nvkm_therm_compute_linear_duty(therm, min, max);
+	return nvkm_therm_compute_linear_duty(therm, min, max, temp);
 }
 
 static int
-nvkm_therm_update_linear_fallback(struct nvkm_therm *therm)
+nvkm_therm_update_linear_fallback(struct nvkm_therm *therm, int temp)
 {
 	u8 max = therm->bios_sensor.thrs_fan_boost.temp;
-	return nvkm_therm_compute_linear_duty(therm, 30, max);
+	return nvkm_therm_compute_linear_duty(therm, 30, max, temp);
 }
 
 static void
@@ -116,6 +106,10 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 	bool immd = true;
 	bool poll = true;
 	int duty = -1;
+	int temp;
+
+	if (nvkm_therm_temp_get(therm, &temp))
+		return;
 
 	spin_lock_irqsave(&therm->lock, flags);
 	if (mode < 0)
@@ -133,17 +127,17 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 	case NVKM_THERM_CTRL_AUTO:
 		switch(therm->fan->bios.fan_mode) {
 		case NVBIOS_THERM_FAN_TRIP:
-			duty = nvkm_therm_update_trip(therm);
+			duty = nvkm_therm_update_trip(therm, temp);
 			break;
 		case NVBIOS_THERM_FAN_LINEAR:
-			duty = nvkm_therm_update_linear(therm);
+			duty = nvkm_therm_update_linear(therm, temp);
 			break;
 		case NVBIOS_THERM_FAN_OTHER:
 			if (therm->cstate)
 				duty = therm->cstate;
 			else
-				duty = nvkm_therm_update_linear_fallback(therm);
-			poll = false;
+				duty = nvkm_therm_update_linear_fallback(therm,
+									 temp);
 			break;
 		}
 		immd = false;
-- 
2.15.0

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

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

* [PATCH 17/32] core/device: Move therm behind clk
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (15 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 16/32] therm: Move the temp readout into nvkm_therm_update Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 18/32] therm: Trigger reclock in temperature daemon Karol Herbst
                     ` (14 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Later therm will depend on clk reporting new temperatures and triggereing
reclocks for thermal throttling or therm related voltage/clock adjustments.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/include/nvkm/core/device.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drm/nouveau/include/nvkm/core/device.h b/drm/nouveau/include/nvkm/core/device.h
index 5046e1db..9e8a8217 100644
--- a/drm/nouveau/include/nvkm/core/device.h
+++ b/drm/nouveau/include/nvkm/core/device.h
@@ -24,8 +24,8 @@ enum nvkm_devidx {
 	NVKM_SUBDEV_PMU,
 	NVKM_SUBDEV_VOLT,
 	NVKM_SUBDEV_ICCSENSE,
-	NVKM_SUBDEV_THERM,
 	NVKM_SUBDEV_CLK,
+	NVKM_SUBDEV_THERM,
 	NVKM_SUBDEV_SECBOOT,
 
 	NVKM_ENGINE_BSP,
-- 
2.15.0

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

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

* [PATCH 18/32] therm: Trigger reclock in temperature daemon
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (16 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 17/32] core/device: Move therm behind clk Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 19/32] bios: Add thermal policies table Karol Herbst
                     ` (13 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 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 <karolherbst@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
Reviewed-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/nvkm/subdev/therm/base.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
index 253da199..3e1767a0 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, int *val)
 {
@@ -102,6 +104,7 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 {
 	struct nvkm_subdev *subdev = &therm->subdev;
 	struct nvkm_timer *tmr = subdev->device->timer;
+	struct nvkm_clk *clk = subdev->device->clk;
 	unsigned long flags;
 	bool immd = true;
 	bool poll = true;
@@ -156,6 +159,9 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 		nvkm_debug(subdev, "FAN target request: %d%%\n", duty);
 		nvkm_therm_fan_set(therm, immd, duty);
 	}
+
+	if (clk)
+		nvkm_clk_tstate(clk, temp);
 }
 
 int
-- 
2.15.0

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

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

* [PATCH 19/32] bios: Add thermal policies table
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (17 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 18/32] therm: Trigger reclock in temperature daemon Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 20/32] therm: Cancel the timer only in fini Karol Herbst
                     ` (12 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Acked-by: Pierre Moreau <pierre.morrow@free.fr>
---
 .../include/nvkm/subdev/bios/thermal_policies.h    | 25 +++++++
 drm/nouveau/nvkm/subdev/bios/Kbuild                |  1 +
 drm/nouveau/nvkm/subdev/bios/thermal_policies.c    | 81 ++++++++++++++++++++++
 3 files changed, 107 insertions(+)
 create mode 100644 drm/nouveau/include/nvkm/subdev/bios/thermal_policies.h
 create mode 100644 drm/nouveau/nvkm/subdev/bios/thermal_policies.c

diff --git a/drm/nouveau/include/nvkm/subdev/bios/thermal_policies.h b/drm/nouveau/include/nvkm/subdev/bios/thermal_policies.h
new file mode 100644
index 00000000..70a203b2
--- /dev/null
+++ b/drm/nouveau/include/nvkm/subdev/bios/thermal_policies.h
@@ -0,0 +1,25 @@
+#ifndef __NVBIOS_THERMAL_POLICIES_H__
+#define __NVBIOS_THERMAL_POLICIES_H__
+
+struct nvbios_thermal_policies_header {
+	u32 offset;
+
+	u8 version;
+	u8 hlen;
+	u8 ecount;
+	u8 elen;
+};
+struct nvbios_thermal_policies_entry {
+	u8  mode;
+	u16 t0;
+	s16 down_offset;
+	s16 up_offset;
+};
+
+int nvbios_thermal_policies_parse(struct nvkm_bios *,
+				  struct nvbios_thermal_policies_header *);
+int nvbios_thermal_policies_entry(struct nvkm_bios *,
+				  struct nvbios_thermal_policies_header *,
+				  u8 idx,
+				  struct nvbios_thermal_policies_entry *);
+#endif
diff --git a/drm/nouveau/nvkm/subdev/bios/Kbuild b/drm/nouveau/nvkm/subdev/bios/Kbuild
index 6b4f1e06..38f31dd0 100644
--- a/drm/nouveau/nvkm/subdev/bios/Kbuild
+++ b/drm/nouveau/nvkm/subdev/bios/Kbuild
@@ -30,6 +30,7 @@ nvkm-y += nvkm/subdev/bios/shadowramin.o
 nvkm-y += nvkm/subdev/bios/shadowrom.o
 nvkm-y += nvkm/subdev/bios/timing.o
 nvkm-y += nvkm/subdev/bios/therm.o
+nvkm-y += nvkm/subdev/bios/thermal_policies.o
 nvkm-y += nvkm/subdev/bios/vmap.o
 nvkm-y += nvkm/subdev/bios/volt.o
 nvkm-y += nvkm/subdev/bios/vpstate.o
diff --git a/drm/nouveau/nvkm/subdev/bios/thermal_policies.c b/drm/nouveau/nvkm/subdev/bios/thermal_policies.c
new file mode 100644
index 00000000..f6a0a843
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/bios/thermal_policies.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017 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/thermal_policies.h>
+
+static u32
+nvbios_thermal_policies_offset(struct nvkm_bios *b)
+{
+	struct bit_entry bit_P;
+
+	if (!bit_entry(b, 'P', &bit_P)) {
+		if (bit_P.version == 2 && bit_P.length >= 0x50)
+			return nvbios_rd32(b, bit_P.offset + 0x50);
+	}
+
+	return 0;
+}
+
+int
+nvbios_thermal_policies_parse(struct nvkm_bios *b,
+			      struct nvbios_thermal_policies_header *h)
+{
+	if (!h)
+		return -EINVAL;
+
+	h->offset = nvbios_thermal_policies_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->ecount   = nvbios_rd08(b, h->offset + 0x3);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int
+nvbios_thermal_policies_entry(struct nvkm_bios *b,
+			      struct nvbios_thermal_policies_header *h,
+			      u8 idx, struct nvbios_thermal_policies_entry *e)
+{
+	u32 offset;
+
+	if (!e || !h || idx > h->ecount)
+		return -EINVAL;
+
+	offset = h->offset + h->hlen + idx * h->elen;
+	e->mode = nvbios_rd08(b, offset);
+	e->t0 = nvbios_rd16(b, offset + 0x2);
+	e->down_offset = nvbios_rd16(b, offset + 0x12);
+	e->up_offset = nvbios_rd16(b, offset + 0x14);
+
+	return 0;
+}
-- 
2.15.0

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

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

* [PATCH 20/32] therm: Cancel the timer only in fini
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (18 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 19/32] bios: Add thermal policies table Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 21/32] clk: Parse thermal policies for throttling thresholds Karol Herbst
                     ` (11 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 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 <karolherbst@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/nvkm/subdev/therm/base.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
index 3e1767a0..c978008e 100644
--- a/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drm/nouveau/nvkm/subdev/therm/base.c
@@ -107,7 +107,6 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 	struct nvkm_clk *clk = subdev->device->clk;
 	unsigned long flags;
 	bool immd = true;
-	bool poll = true;
 	int duty = -1;
 	int temp;
 
@@ -121,11 +120,9 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 
 	switch (mode) {
 	case NVKM_THERM_CTRL_MANUAL:
-		nvkm_timer_alarm(tmr, 0, &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) {
@@ -147,11 +144,10 @@ nvkm_therm_update(struct nvkm_therm *therm, int mode)
 		break;
 	case NVKM_THERM_CTRL_NONE:
 	default:
-		nvkm_timer_alarm(tmr, 0, &therm->alarm);
-		poll = false;
+		break;
 	}
 
-	if (poll)
+	if (list_empty(&therm->alarm.head))
 		nvkm_timer_alarm(tmr, 1000000000ULL, &therm->alarm);
 	spin_unlock_irqrestore(&therm->lock, flags);
 
@@ -318,6 +314,11 @@ static int
 nvkm_therm_fini(struct nvkm_subdev *subdev, bool suspend)
 {
 	struct nvkm_therm *therm = nvkm_therm(subdev);
+	struct nvkm_timer *tmr = subdev->device->timer;
+
+	/* cancel the timer */
+	if (!list_empty(&therm->alarm.head))
+		nvkm_timer_alarm(tmr, 0, &therm->alarm);
 
 	if (therm->func->fini)
 		therm->func->fini(therm);
-- 
2.15.0

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

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

* [PATCH 21/32] clk: Parse thermal policies for throttling thresholds
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (19 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 20/32] therm: Cancel the timer only in fini Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 22/32] clk: Thermal throttling Karol Herbst
                     ` (10 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

v2: use min_t

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

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 9e05b088..3bb2099c 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -108,6 +108,8 @@ struct nvkm_clk {
 	int astate; /* perfmon adjustment (base) */
 	int cstate_id;
 	int temp;
+	int max_temp;
+	int relax_temp;
 
 	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 657456ce..4279f80a 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -27,6 +27,7 @@
 #include <subdev/bios/boost.h>
 #include <subdev/bios/cstep.h>
 #include <subdev/bios/perf.h>
+#include <subdev/bios/thermal_policies.h>
 #include <subdev/bios/vpstate.h>
 #include <subdev/fb.h>
 #include <subdev/therm.h>
@@ -655,6 +656,44 @@ nvkm_clk_fill_limit(struct nvkm_clk_limit *l,
 	l->max_khz = e->clock_mhz * 1000;
 }
 
+static void
+nvkm_clk_parse_max_temp(struct nvkm_clk *clk)
+{
+	struct nvkm_subdev *subdev = &clk->subdev;
+	struct nvkm_bios *bios = subdev->device->bios;
+	struct nvbios_thermal_policies_header header;
+	struct nvbios_thermal_policies_entry entry;
+	u8 i;
+	s16 mt = 0xff;
+	s16 rt = 0xff;
+
+	if (nvbios_thermal_policies_parse(bios, &header))
+		return;
+
+	if (!header.ecount)
+		return;
+
+	for (i = 0; i < header.ecount; i++) {
+		if (nvbios_thermal_policies_entry(bios, &header, i, &entry))
+			return;
+
+		if (entry.mode != 1)
+			continue;
+
+		mt = min_t(s16, mt, (entry.t0 + entry.down_offset) / 32);
+		rt = min_t(s16, rt, (entry.t0 + entry.up_offset) / 32);
+	}
+
+	if (mt == 0xff || rt == 0xff)
+		return;
+
+	clk->max_temp = mt;
+	clk->relax_temp = rt;
+
+	nvkm_debug(subdev, "setting up sw throttling thresholds (%u/%u°C)\n",
+		   clk->max_temp, clk->relax_temp);
+}
+
 int
 nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	      int index, bool allow_reclock, struct nvkm_clk *clk)
@@ -720,6 +759,9 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 
 	clk->boost_mode = nvkm_longopt(device->cfgopt, "NvBoost",
 				       NVKM_CLK_BOOST_NONE);
+
+	nvkm_clk_parse_max_temp(clk);
+
 	return 0;
 }
 
-- 
2.15.0

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

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

* [PATCH 22/32] clk: Thermal throttling
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (20 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 21/32] clk: Parse thermal policies for throttling thresholds Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 23/32] clk: Skip unchanging parts of the reclock Karol Herbst
                     ` (9 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

v2: make message about relaxed throttling an info
    rework reporting about current clk state

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Pierre Moreau <pierre.morrow@free.fr>
---
 drm/nouveau/include/nvkm/subdev/clk.h |  1 +
 drm/nouveau/nvkm/subdev/clk/base.c    | 47 +++++++++++++++++++++++++++--------
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 3bb2099c..32923732 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -110,6 +110,7 @@ struct nvkm_clk {
 	int temp;
 	int max_temp;
 	int relax_temp;
+	bool throttled;
 
 	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 4279f80a..3704475d 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -180,8 +180,13 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 		return 0;
 
 	if (!list_empty(&pstate->cstates)) {
-		cstate = nvkm_cstate_get(clk, pstate, cstate_id);
-		cstate = nvkm_cstate_find_best(clk, pstate, cstate);
+		if (clk->throttled) {
+			cstate = list_first_entry(&pstate->cstates,
+						  struct nvkm_cstate, head);
+		} else {
+			cstate = nvkm_cstate_get(clk, pstate, cstate_id);
+			cstate = nvkm_cstate_find_best(clk, pstate, cstate);
+		}
 	} else {
 		cstate = &pstate->base;
 	}
@@ -325,17 +330,22 @@ nvkm_clk_update_work(struct work_struct *work)
 		return;
 	clk->pwrsrc = power_supply_is_system_supplied();
 
-	nvkm_trace(subdev, "P %x PWR %d U(AC) %d U(DC) %d A %d T %d°C\n",
-		   clk->pstate_id, clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
-		   clk->astate, clk->temp);
-
 	pstate_id = clk->pwrsrc ? clk->ustate_ac : clk->ustate_dc;
-	if (clk->pstates_cnt && pstate_id != NVKM_CLK_PSTATE_BOOT)
-		pstate_id = (pstate_id < 0) ? clk->astate : pstate_id;
-	else
+	if (clk->pstates_cnt && pstate_id != NVKM_CLK_PSTATE_BOOT) {
+		if (clk->throttled)
+			pstate_id = list_first_entry(&clk->pstates,
+						     struct nvkm_pstate,
+						     head)->id;
+		else
+			pstate_id = (pstate_id < 0) ? clk->astate : pstate_id;
+	} else {
 		pstate_id = NVKM_CLK_PSTATE_BOOT;
+	}
+
+	nvkm_trace(subdev, "PWR %d U(AC) %d U(DC) %d A %d T %d°C -> %d\n",
+		   clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
+		   clk->astate, clk->temp, pstate_id);
 
-	nvkm_trace(subdev, "-> %x\n", pstate_id);
 	if (pstate_id != clk->pstate_id) {
 		int ret = nvkm_pstate_prog(clk, pstate_id);
 		if (ret) {
@@ -552,9 +562,25 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
 int
 nvkm_clk_tstate(struct nvkm_clk *clk, int temp)
 {
+	struct nvkm_subdev *subdev = &clk->subdev;
 	if (clk->temp == temp)
 		return 0;
 	clk->temp = temp;
+	if (clk->max_temp && clk->relax_temp) {
+		if (!clk->throttled && temp > clk->max_temp) {
+			nvkm_warn(subdev,
+				  "temperature (%d C) hit the 'downclock' "
+				  "threshold\n",
+				  temp);
+			clk->throttled = true;
+		} else if (clk->throttled && temp < clk->relax_temp) {
+			nvkm_info(subdev,
+				  "temperature (%d C) went below the "
+				  "'relax' threshold\n",
+				  temp);
+			clk->throttled = false;
+		}
+	}
 	return nvkm_clk_update(clk, false);
 }
 
@@ -720,6 +746,7 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 	clk->domains = func->domains;
 	clk->ustate_ac = NVKM_CLK_PSTATE_BOOT;
 	clk->ustate_dc = NVKM_CLK_PSTATE_BOOT;
+	clk->throttled = false;
 	clk->allow_reclock = allow_reclock;
 
 	INIT_WORK(&clk->work, nvkm_clk_update_work);
-- 
2.15.0

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

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

* [PATCH 23/32] clk: Skip unchanging parts of the reclock
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (21 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 22/32] clk: Thermal throttling Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 24/32] clk: Save the max clock we can set Karol Herbst
                     ` (8 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

If just the voltage is updated, we don't need to update the pstate or
cstate as well. Same goes for changing the cstate without the pstate.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/nvkm/subdev/clk/base.c  | 23 +++++++++++++++--------
 drm/nouveau/nvkm/subdev/volt/base.c |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 3704475d..9087e180 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -174,7 +174,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 	struct nvkm_therm *therm = device->therm;
 	struct nvkm_volt *volt = device->volt;
 	struct nvkm_cstate *cstate;
-	int ret;
+	int ret = 0;
 
 	if (cstate_id == NVKM_CLK_CSTATE_BOOT)
 		return 0;
@@ -191,6 +191,11 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 		cstate = &pstate->base;
 	}
 
+	/* if the cstate matches, just update the voltage */
+	if (clk->cstate_id == cstate->id)
+		return nvkm_volt_set_id(volt, cstate->voltage,
+					pstate->base.voltage, clk->temp, 0);
+
 	if (therm) {
 		ret = nvkm_therm_cstate(therm, pstate->fanspeed, +1);
 		if (ret && ret != -ENODEV) {
@@ -297,6 +302,9 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_id)
 			break;
 	}
 
+	if (clk->pstate_id == pstate_id)
+		goto cstate;
+
 	if (!pstate)
 		return -EINVAL;
 
@@ -316,6 +324,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_id)
 		ram->func->tidy(ram);
 	}
 
+cstate:
 	return nvkm_cstate_prog(clk, pstate, NVKM_CLK_CSTATE_AUTO);
 }
 
@@ -324,7 +333,7 @@ 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_id;
+	int pstate_id, ret;
 
 	if (!atomic_xchg(&clk->waiting, 0))
 		return;
@@ -346,12 +355,10 @@ nvkm_clk_update_work(struct work_struct *work)
 		   clk->pwrsrc, clk->ustate_ac, clk->ustate_dc,
 		   clk->astate, clk->temp, pstate_id);
 
-	if (pstate_id != clk->pstate_id) {
-		int ret = nvkm_pstate_prog(clk, pstate_id);
-		if (ret) {
-			nvkm_error(subdev, "error setting pstate %d: %d\n",
-				   pstate_id, ret);
-		}
+	ret = nvkm_pstate_prog(clk, pstate_id);
+	if (ret) {
+		nvkm_error(subdev, "error setting pstate %d: %d\n",
+			   pstate_id, ret);
 	}
 
 	wake_up_all(&clk->wait);
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index e344901c..56a0f379 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -162,6 +162,9 @@ nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, u8 min_id, u8 temp,
 {
 	int ret;
 
+	if (!volt)
+		return -ENODEV;
+
 	if (volt->func->set_id)
 		return volt->func->set_id(volt, id, condition);
 
-- 
2.15.0

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

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

* [PATCH 24/32] clk: Save the max clock we can set
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (22 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 23/32] clk: Skip unchanging parts of the reclock Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 25/32] nvif: Add boost info and set operations Karol Herbst
                     ` (7 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Saving the highest possible clock from the vpstate domain makes it easier
to read it out whenever we want.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 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 32923732..df12bbd5 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -119,6 +119,7 @@ struct nvkm_clk {
 	u8  boost_mode;
 	struct nvkm_clk_limit base_limit;
 	struct nvkm_clk_limit boost_limit;
+	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 9087e180..e94aee09 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -274,6 +274,8 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
 			u32 freq = nvkm_clk_adjust(clk, true, pstate->id,
 						   domain->bios, cstepX.freq);
 			cstate->domain[domain->name] = freq;
+			if (domain->flags & NVKM_CLK_DOM_FLAG_VPSTATE)
+				clk->max_khz = max(clk->max_khz, freq);
 		}
 		domain++;
 	}
-- 
2.15.0

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

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

* [PATCH 25/32] nvif: Add boost info and set operations
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (23 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 24/32] clk: Save the max clock we can set Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 26/32] debugfs: Add boost interface to change the boost_mode Karol Herbst
                     ` (6 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

v5: Return ENODEV on devices without any vpstates.
    Fail earlier if not supported.

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

diff --git a/drm/nouveau/include/nvif/if0001.h b/drm/nouveau/include/nvif/if0001.h
index bd5b6412..e4acd195 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 bb92cefa..83726a96 100644
--- a/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -166,6 +166,63 @@ nvkm_control_mthd_pstate_user(struct nvkm_control *ctrl, void *data, u32 size)
 	return ret;
 }
 
+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;
+
+	if (!clk)
+		return -ENODEV;
+
+	if (!clk->base_limit.max_khz && !clk->boost_limit.max_khz)
+		return -ENODEV;
+
+	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;
+
+	args->v0.mode = clk->boost_mode;
+	args->v0.base_mhz = clk->base_limit.max_khz / 2000;
+	args->v0.boost_mhz = clk->boost_limit.max_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;
+
+	if (!clk)
+		return -ENODEV;
+
+	if (!clk->base_limit.max_khz && !clk->boost_limit.max_khz)
+		return -ENODEV;
+
+	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 (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)
 {
@@ -177,6 +234,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.15.0

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

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

* [PATCH 26/32] debugfs: Add boost interface to change the boost_mode
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (24 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 25/32] nvif: Add boost info and set operations Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 27/32] bios/vpstate: Parse max battery id Karol Herbst
                     ` (5 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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

diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index 7e1dbb03..d110261b 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -184,6 +184,86 @@ 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_device *drm = m->private;
+	struct nouveau_debugfs *debugfs = nouveau_debugfs(drm);
+	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_device *drm = m->private;
+	struct nouveau_debugfs *debugfs = nouveau_debugfs(drm);
+	struct nvif_object *ctrl = &debugfs->ctrl;
+	struct nvif_control_boost_set_v0 args = {};
+	char buf[3] = {};
+	long 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 = pm_runtime_get_sync(drm->dev);
+	if (IS_ERR_VALUE(ret) && ret != -EACCES)
+		return ret;
+	ret = nvif_mthd(ctrl, NVIF_CONTROL_BOOST_SET, &args, sizeof(args));
+	pm_runtime_put_autosuspend(drm->dev);
+	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 },
 };
@@ -193,6 +273,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.15.0

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

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

* [PATCH 27/32] bios/vpstate: Parse max battery id
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (25 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 26/32] debugfs: Add boost interface to change the boost_mode Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 28/32] clk: Implement limiting pstates just like we do for cstates Karol Herbst
                     ` (4 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/include/nvkm/subdev/bios/vpstate.h | 1 +
 drm/nouveau/nvkm/subdev/bios/vpstate.c         | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drm/nouveau/include/nvkm/subdev/bios/vpstate.h b/drm/nouveau/include/nvkm/subdev/bios/vpstate.h
index 87f804fc..181de47b 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/vpstate.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/vpstate.h
@@ -10,6 +10,7 @@ struct nvbios_vpstate_header {
 	u8 scount;
 	u8 slen;
 
+	u8 battery_id;
 	u8 base_id;
 	u8 boost_id;
 	u8 tdp_id;
diff --git a/drm/nouveau/nvkm/subdev/bios/vpstate.c b/drm/nouveau/nvkm/subdev/bios/vpstate.c
index 71524548..c1de6421 100644
--- a/drm/nouveau/nvkm/subdev/bios/vpstate.c
+++ b/drm/nouveau/nvkm/subdev/bios/vpstate.c
@@ -57,7 +57,8 @@ nvbios_vpstate_parse(struct nvkm_bios *b, struct nvbios_vpstate_header *h)
 		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->battery_id = nvbios_rd08(b, h->offset + 0x0c);
+		h->base_id    = nvbios_rd08(b, h->offset + 0x0f);
 		if (h->hlen > 0x10)
 			h->boost_id = nvbios_rd08(b, h->offset + 0x10);
 		else
-- 
2.15.0

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

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

* [PATCH 28/32] clk: Implement limiting pstates just like we do for cstates
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (26 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 27/32] bios/vpstate: Parse max battery id Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 29/32] clk: Limit clocks on battery Karol Herbst
                     ` (3 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index e94aee09..ce427eaa 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -287,6 +287,51 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
 /******************************************************************************
  * P-States
  *****************************************************************************/
+static struct nvkm_pstate *
+nvkm_pstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate)
+{
+	u8 limit;
+
+	switch (clk->boost_mode) {
+	case NVKM_CLK_BOOST_NONE:
+		limit = clk->base_limit.pstate;
+		if (limit)
+			break;
+	case NVKM_CLK_BOOST_BIOS:
+		limit = clk->boost_limit.pstate;
+		break;
+	default:
+		limit = 0;
+		break;
+	}
+
+	if (!limit)
+		return pstate;
+
+	list_for_each_entry_from_reverse(pstate, &clk->pstates, head) {
+		if (limit >= pstate->id)
+			break;
+	}
+	return pstate;
+}
+
+static struct nvkm_pstate *
+nvkm_pstate_get(struct nvkm_clk *clk, int pstateid)
+{
+	struct nvkm_pstate *pstate;
+
+	switch (pstateid) {
+	case NVKM_CLK_PSTATE_BOOT:
+		return NULL;
+	default:
+		list_for_each_entry(pstate, &clk->pstates, head) {
+			if (pstate->id == pstateid)
+				return pstate;
+		}
+	}
+	return NULL;
+}
+
 static int
 nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_id)
 {
@@ -299,19 +344,17 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstate_id)
 	if (pstate_id == NVKM_CLK_PSTATE_BOOT)
 		return 0;
 
-	list_for_each_entry(pstate, &clk->pstates, head) {
-		if (pstate->id == pstate_id)
-			break;
-	}
-
-	if (clk->pstate_id == pstate_id)
-		goto cstate;
+	pstate = nvkm_pstate_get(clk, pstate_id);
+	pstate = nvkm_pstate_find_best(clk, pstate);
 
 	if (!pstate)
 		return -EINVAL;
 
-	nvkm_debug(subdev, "setting performance state %x\n", pstate_id);
-	clk->pstate_id = pstate_id;
+	if (clk->pstate_id == pstate_id)
+		goto cstate;
+
+	nvkm_debug(subdev, "setting performance state %x\n", pstate->id);
+	clk->pstate_id = pstate->id;
 
 	nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
 
-- 
2.15.0

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

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

* [PATCH 29/32] clk: Limit clocks on battery
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (27 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 28/32] clk: Implement limiting pstates just like we do for cstates Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 30/32] secboot/acr352: Reset PMU after secboot Karol Herbst
                     ` (2 subsequent siblings)
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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

diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index df12bbd5..d0497e9b 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -119,6 +119,7 @@ struct nvkm_clk {
 	u8  boost_mode;
 	struct nvkm_clk_limit base_limit;
 	struct nvkm_clk_limit boost_limit;
+	struct nvkm_clk_limit batt_limit;
 	u32 max_khz;
 
 	/*XXX: die, these are here *only* to support the completely
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index ce427eaa..1f136862 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -99,6 +99,15 @@ nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate,
 		break;
 	}
 
+	if (!clk->pwrsrc) {
+		u32 blimit = clk->batt_limit.max_khz;
+
+		if (!limit)
+			limit = blimit;
+		else if (blimit)
+			limit = min(blimit, limit);
+	}
+
 	if (limit) {
 		for (; domain && domain->name != nv_clk_src_max; domain++) {
 			if (!(domain->flags & NVKM_CLK_DOM_FLAG_VPSTATE))
@@ -305,6 +314,15 @@ nvkm_pstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate)
 		break;
 	}
 
+	if (!clk->pwrsrc) {
+		u8 blimit = clk->batt_limit.pstate;
+
+		if (!limit)
+			limit = blimit;
+		else if (blimit)
+			limit = min(blimit, limit);
+	}
+
 	if (!limit)
 		return pstate;
 
@@ -791,6 +809,8 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
 			nvkm_clk_fill_limit(&clk->boost_limit, &vpe);
 		if (!nvbios_vpstate_entry(bios, &h, h.base_id, &vpe))
 			nvkm_clk_fill_limit(&clk->base_limit, &vpe);
+		if (!nvbios_vpstate_entry(bios, &h, h.battery_id, &vpe))
+			nvkm_clk_fill_limit(&clk->batt_limit, &vpe);
 	}
 
 	clk->func = func;
-- 
2.15.0

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

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

* [PATCH 30/32] secboot/acr352: Reset PMU after secboot
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (28 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 29/32] clk: Limit clocks on battery Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 31/32] device: Enable clk for Maxwell2 Karol Herbst
  2017-11-17  0:04   ` [PATCH 32/32] clk: Add trace message when setting a new cstate Karol Herbst
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This is needed for using Nouveaus PMU image after performing secboot. This will
be helpful for Maxwell2 reclocking on boards without externally controlled
fans like on most laptops or fanless boards.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/nvkm/subdev/secboot/acr_r352.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/secboot/acr_r352.c b/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
index a7213542..bb8b7233 100644
--- a/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
+++ b/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
@@ -924,6 +924,20 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb)
 		}
 	}
 
+	/* reset the PMU if needed */
+	if (acr->base.boot_falcon == NVKM_SECBOOT_FALCON_PMU &&
+	    !nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_PMU)) {
+		struct nvkm_pmu *pmu = subdev->device->pmu;
+
+		if (pmu) {
+			ret = nvkm_subdev_init(&pmu->subdev);
+			if (ret < 0) {
+				nvkm_error(subdev, "Failed to reset PMU\n");
+				return ret;
+			}
+		}
+	}
+
 	return 0;
 }
 
-- 
2.15.0

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

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

* [PATCH 31/32] device: Enable clk for Maxwell2
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (29 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 30/32] secboot/acr352: Reset PMU after secboot Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  2017-11-17  0:04   ` [PATCH 32/32] clk: Add trace message when setting a new cstate Karol Herbst
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Reclokcing will only be enabled by setting NvFanless to true.

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
---
 drm/nouveau/nvkm/engine/device/base.c |  3 +++
 drm/nouveau/nvkm/subdev/clk/gk104.c   | 10 +++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drm/nouveau/nvkm/engine/device/base.c b/drm/nouveau/nvkm/engine/device/base.c
index e1464361..f63aaf3e 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -2029,6 +2029,7 @@ nv120_chipset = {
 	.bar = gm107_bar_new,
 	.bios = nvkm_bios_new,
 	.bus = gf100_bus_new,
+	.clk = gk104_clk_new,
 	.devinit = gm200_devinit_new,
 	.fb = gm200_fb_new,
 	.fuse = gm107_fuse_new,
@@ -2064,6 +2065,7 @@ nv124_chipset = {
 	.bar = gm107_bar_new,
 	.bios = nvkm_bios_new,
 	.bus = gf100_bus_new,
+	.clk = gk104_clk_new,
 	.devinit = gm200_devinit_new,
 	.fb = gm200_fb_new,
 	.fuse = gm107_fuse_new,
@@ -2099,6 +2101,7 @@ nv126_chipset = {
 	.bar = gm107_bar_new,
 	.bios = nvkm_bios_new,
 	.bus = gf100_bus_new,
+	.clk = gk104_clk_new,
 	.devinit = gm200_devinit_new,
 	.fb = gm200_fb_new,
 	.fuse = gm107_fuse_new,
diff --git a/drm/nouveau/nvkm/subdev/clk/gk104.c b/drm/nouveau/nvkm/subdev/clk/gk104.c
index 0b37e3da..be04463e 100644
--- a/drm/nouveau/nvkm/subdev/clk/gk104.c
+++ b/drm/nouveau/nvkm/subdev/clk/gk104.c
@@ -25,6 +25,7 @@
 #include "priv.h"
 #include "pll.h"
 
+#include <core/option.h>
 #include <subdev/timer.h>
 #include <subdev/bios.h>
 #include <subdev/bios/pll.h>
@@ -507,10 +508,17 @@ int
 gk104_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
 {
 	struct gk104_clk *clk;
+	bool reclocking;
 
 	if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL)))
 		return -ENOMEM;
 	*pclk = &clk->base;
 
-	return nvkm_clk_ctor(&gk104_clk, device, index, true, &clk->base);
+	if (device->chipset >= 0x120)
+		reclocking = nvkm_boolopt(device->cfgopt, "NvFanless", false);
+	else
+		reclocking = true;
+
+	return nvkm_clk_ctor(&gk104_clk, device, index, reclocking,
+			     &clk->base);
 }
-- 
2.15.0

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

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

* [PATCH 32/32] clk: Add trace message when setting a new cstate
       [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (30 preceding siblings ...)
  2017-11-17  0:04   ` [PATCH 31/32] device: Enable clk for Maxwell2 Karol Herbst
@ 2017-11-17  0:04   ` Karol Herbst
  31 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-17  0:04 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Karol Herbst <kherbst@redhat.com>

Signed-off-by: Karol Herbst <kherbst@redhat.com>
---
 drm/nouveau/nvkm/subdev/clk/base.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 1f136862..2c7fbeb0 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -205,6 +205,8 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate,
 		return nvkm_volt_set_id(volt, cstate->voltage,
 					pstate->base.voltage, clk->temp, 0);
 
+	nvkm_trace(subdev, "setting cstate to %d\n", cstate->id);
+
 	if (therm) {
 		ret = nvkm_therm_cstate(therm, pstate->fanspeed, +1);
 		if (ret && ret != -ENODEV) {
-- 
2.15.0

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

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

* Re: [PATCH 01/32] bios/vpstate: There are some fermi vbios with no boost or tdp entry
       [not found]     ` <20171117000436.2432-2-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-11-22  0:16       ` Martin Peres
       [not found]         ` <6fd6503a-0d97-9148-0ebf-cba6f8bb0180-GANU6spQydw@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Martin Peres @ 2017-11-22  0:16 UTC (permalink / raw)
  To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 17/11/17 02:04, Karol Herbst wrote:

Please add here something like this:

If the entry size is too small, default to invalid values for both
boost_id and tdp_id, so as to default to the base clock in both cases.

> Signed-off-by: Karol Herbst <karolherbst@gmail.com>

With the better commit message, this patch is:
Signed-off-by: Martin Peres <martin.peres@free.fr>

> ---
>  drm/nouveau/nvkm/subdev/bios/vpstate.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drm/nouveau/nvkm/subdev/bios/vpstate.c b/drm/nouveau/nvkm/subdev/bios/vpstate.c
> index 20b6fc82..71524548 100644
> --- a/drm/nouveau/nvkm/subdev/bios/vpstate.c
> +++ b/drm/nouveau/nvkm/subdev/bios/vpstate.c
> @@ -58,8 +58,14 @@ nvbios_vpstate_parse(struct nvkm_bios *b, struct nvbios_vpstate_header *h)
>  		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);
> +		if (h->hlen > 0x10)
> +			h->boost_id = nvbios_rd08(b, h->offset + 0x10);
> +		else
> +			h->boost_id = 0xff;
> +		if (h->hlen > 0x11)
> +			h->tdp_id = nvbios_rd08(b, h->offset + 0x11);
> +		else
> +			h->tdp_id = 0xff;
>  		return 0;
>  	default:
>  		return -EINVAL;
> 

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

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

* Re: [PATCH 02/32] debugfs: Wake up GPU before doing any reclocking
       [not found]     ` <20171117000436.2432-3-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-11-22  0:21       ` Martin Peres
       [not found]         ` <b719fba2-3f0f-298e-a816-5992b587b293-GANU6spQydw@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Martin Peres @ 2017-11-22  0:21 UTC (permalink / raw)
  To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 17/11/17 02:04, Karol Herbst wrote:
> Fixes various reclocking related issues on prime systems.

Is that the only place that was not covered? Could you check if other
places would need this code too?

In any case, this patch is (assuming you are calling the right functions
to prevent the GPU from sleeping):
Signed-off-by: Martin Peres <martin.peres@free.fr>
> 
> Signed-off-by: Karol Herbst <karolherbst@gmail.com>
> ---
>  drm/nouveau/nouveau_debugfs.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
> index 963a4dba..9109b69c 100644
> --- a/drm/nouveau/nouveau_debugfs.c
> +++ b/drm/nouveau/nouveau_debugfs.c
> @@ -160,7 +160,11 @@ nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf,
>  		args.ustate = value;
>  	}
>  
> +	ret = pm_runtime_get_sync(drm->dev);
> +	if (IS_ERR_VALUE(ret) && ret != -EACCES)
> +		return ret;
>  	ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args));
> +	pm_runtime_put_autosuspend(drm->dev);
>  	if (ret < 0)
>  		return ret;
>  
> 

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

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

* Re: [PATCH 03/32] therm: Split return code and value in nvkm_get_temp
       [not found]     ` <20171117000436.2432-4-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-11-22  0:32       ` Martin Peres
       [not found]         ` <e6b18baa-46d5-0ff0-bd55-c5255d22e770-GANU6spQydw@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Martin Peres @ 2017-11-22  0:32 UTC (permalink / raw)
  To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 17/11/17 02:04, Karol Herbst wrote:
> The current hwmon code doesn't check if the returned value was actually an
> error.
> 
> Since Kepler temperature sensors are able to report negative values. Those
> negative values are not for error reporting, but rather when you buried
> your GPU in snow somewhere in Antarctica and still want a valid
> temperature to be reported (unverified).
> 
> Since Pascal (and maybe earlier) we have sensors with improved precision.
> 
> Adjust the nvkm_get_temp method to be able to deal with those changes
> and let hwmon return an error properly.

Where did you get this information? And if it is the case, then we will
royally screw up the value because we don't even know on how many bits
0x20400 uses...

If you are indeed right, I would like to see g84.c's temp_get().

> 
> Signed-off-by: Karol Herbst <karolherbst@gmail.com>
> ---
>  drm/nouveau/include/nvkm/subdev/clk.h   |  4 ++--
>  drm/nouveau/include/nvkm/subdev/therm.h |  2 +-
>  drm/nouveau/nouveau_hwmon.c             | 15 +++++++++------
>  drm/nouveau/nvkm/subdev/clk/base.c      |  2 +-
>  drm/nouveau/nvkm/subdev/therm/base.c    | 19 ++++++++++++++-----
>  drm/nouveau/nvkm/subdev/therm/g84.c     | 13 ++++++++-----
>  drm/nouveau/nvkm/subdev/therm/gp100.c   |  9 +++++----
>  drm/nouveau/nvkm/subdev/therm/nv40.c    |  9 +++------
>  drm/nouveau/nvkm/subdev/therm/nv50.c    |  9 +++------
>  drm/nouveau/nvkm/subdev/therm/priv.h    |  4 ++--
>  drm/nouveau/nvkm/subdev/therm/temp.c    | 16 ++++++++++++----
>  11 files changed, 60 insertions(+), 42 deletions(-)
> 
> diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
> index e5275f74..506f8cc6 100644
> --- a/drm/nouveau/include/nvkm/subdev/clk.h
> +++ b/drm/nouveau/include/nvkm/subdev/clk.h
> @@ -100,7 +100,7 @@ struct nvkm_clk {
>  	int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
>  	int astate; /* perfmon adjustment (base) */
>  	int dstate; /* display adjustment (min+) */
> -	u8  temp;
> +	int temp;
>  
>  	bool allow_reclock;
>  #define NVKM_CLK_BOOST_NONE 0x0
> @@ -122,7 +122,7 @@ 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 *, u8 temperature);
> +int nvkm_clk_tstate(struct nvkm_clk *, int temperature);
>  
>  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/include/nvkm/subdev/therm.h b/drm/nouveau/include/nvkm/subdev/therm.h
> index 9841f076..8c84017f 100644
> --- a/drm/nouveau/include/nvkm/subdev/therm.h
> +++ b/drm/nouveau/include/nvkm/subdev/therm.h
> @@ -86,7 +86,7 @@ struct nvkm_therm {
>  	int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
>  };
>  
> -int nvkm_therm_temp_get(struct nvkm_therm *);
> +int nvkm_therm_temp_get(struct nvkm_therm *, int *);
>  int nvkm_therm_fan_sense(struct nvkm_therm *);
>  int nvkm_therm_cstate(struct nvkm_therm *, int, int);
>  
> diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
> index 7c965648..7486e4af 100644
> --- a/drm/nouveau/nouveau_hwmon.c
> +++ b/drm/nouveau/nouveau_hwmon.c
> @@ -326,8 +326,9 @@ nouveau_temp_is_visible(const void *data, u32 attr, int channel)
>  {
>  	struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>  	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
> +	int val;
>  
> -	if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
> +	if (therm && therm->attr_get && nvkm_therm_temp_get(therm, &val))
>  		return 0;
>  
>  	switch (attr) {
> @@ -421,15 +422,16 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
>  	struct drm_device *drm_dev = dev_get_drvdata(dev);
>  	struct nouveau_drm *drm = nouveau_drm(drm_dev);
>  	struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
> -	int ret;
> +	int ret = 0;
> +	int temp;
>  
>  	if (!therm || !therm->attr_get)
>  		return -EOPNOTSUPP;
>  
>  	switch (attr) {
>  	case hwmon_temp_input:
> -		ret = nvkm_therm_temp_get(therm);
> -		*val = ret < 0 ? ret : (ret * 1000);
> +		ret = nvkm_therm_temp_get(therm, &temp);
> +		*val = temp * 1000;
>  		break;
>  	case hwmon_temp_max:
>  		*val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
> @@ -459,7 +461,7 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
>  		return -EOPNOTSUPP;
>  	}
>  
> -	return 0;
> +	return ret;
>  }
>  
>  static int
> @@ -713,6 +715,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>  	struct device *hwmon_dev;
>  	int ret = 0;
>  	int i = 0;
> +	int val;
>  
>  	hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
>  	if (!hwmon)
> @@ -720,7 +723,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>  	hwmon->dev = dev;
>  
>  	if (therm && therm->attr_get && therm->attr_set) {
> -		if (nvkm_therm_temp_get(therm) >= 0)
> +		if (!nvkm_therm_temp_get(therm, &val))
>  			special_groups[i++] = &temp1_auto_point_sensor_group;
>  		if (therm->fan_get && therm->fan_get(therm) >= 0)
>  			special_groups[i++] = &pwm_fan_sensor_group;
> diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
> index e4c8d310..0b28dbb9 100644
> --- a/drm/nouveau/nvkm/subdev/clk/base.c
> +++ b/drm/nouveau/nvkm/subdev/clk/base.c
> @@ -540,7 +540,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
>  }
>  
>  int
> -nvkm_clk_tstate(struct nvkm_clk *clk, u8 temp)
> +nvkm_clk_tstate(struct nvkm_clk *clk, int temp)
>  {
>  	if (clk->temp == temp)
>  		return 0;
> diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
> index f27fc6d0..8e5f6f7f 100644
> --- a/drm/nouveau/nvkm/subdev/therm/base.c
> +++ b/drm/nouveau/nvkm/subdev/therm/base.c
> @@ -24,22 +24,26 @@
>  #include "priv.h"
>  
>  int
> -nvkm_therm_temp_get(struct nvkm_therm *therm)
> +nvkm_therm_temp_get(struct nvkm_therm *therm, int *val)
>  {
>  	if (therm->func->temp_get)
> -		return therm->func->temp_get(therm);
> +		return therm->func->temp_get(therm, val);
>  	return -ENODEV;
>  }
>  
>  static int
>  nvkm_therm_update_trip(struct nvkm_therm *therm)
>  {
> +	int temp, ret;
>  	struct nvbios_therm_trip_point *trip = therm->fan->bios.trip,
>  				       *cur_trip = NULL,
>  				       *last_trip = therm->last_trip;
> -	u8  temp = therm->func->temp_get(therm);
>  	u16 duty, i;
>  
> +	ret = therm->func->temp_get(therm, &temp);
> +	if (ret < 0)
> +		return ret;
> +
>  	/* look for the trip point corresponding to the current temperature */
>  	cur_trip = NULL;
>  	for (i = 0; i < therm->fan->bios.nr_fan_trip; i++) {
> @@ -67,9 +71,13 @@ static int
>  nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
>                                 u8 linear_max_temp)
>  {
> -	u8  temp = therm->func->temp_get(therm);
> +	int temp, ret;
>  	u16 duty;
>  
> +	ret = therm->func->temp_get(therm, &temp);
> +	if (ret < 0)
> +		return ret;
> +
>  	/* handle the non-linear part first */
>  	if (temp < linear_min_temp)
>  		return therm->fan->bios.min_duty;
> @@ -182,6 +190,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
>  {
>  	struct nvkm_subdev *subdev = &therm->subdev;
>  	struct nvkm_device *device = subdev->device;
> +	int val;
>  	static const char *name[] = {
>  		"disabled",
>  		"manual",
> @@ -197,7 +206,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
>  	/* do not allow automatic fan management if the thermal sensor is
>  	 * not available */
>  	if (mode == NVKM_THERM_CTRL_AUTO &&
> -	    therm->func->temp_get(therm) < 0)
> +	    therm->func->temp_get(therm, &val))
>  		return -EINVAL;
>  
>  	if (therm->mode == mode)
> diff --git a/drm/nouveau/nvkm/subdev/therm/g84.c b/drm/nouveau/nvkm/subdev/therm/g84.c
> index 96f8da40..81c0bda8 100644
> --- a/drm/nouveau/nvkm/subdev/therm/g84.c
> +++ b/drm/nouveau/nvkm/subdev/therm/g84.c
> @@ -27,14 +27,15 @@
>  #include <subdev/fuse.h>
>  
>  int
> -g84_temp_get(struct nvkm_therm *therm)
> +g84_temp_get(struct nvkm_therm *therm, int *val)
>  {
>  	struct nvkm_device *device = therm->subdev.device;
>  
> -	if (nvkm_fuse_read(device->fuse, 0x1a8) == 1)
> -		return nvkm_rd32(device, 0x20400);
> -	else
> +	if (nvkm_fuse_read(device->fuse, 0x1a8) != 1)
>  		return -ENODEV;
> +
> +	*val = nvkm_rd32(device, 0x20400);
> +	return 0;
>  }
>  
>  void
> @@ -114,8 +115,10 @@ g84_therm_threshold_hyst_emulation(struct nvkm_therm *therm,
>  		new_state = NVKM_THERM_THRS_LOWER;
>  	}
>  
> +	if (therm->func->temp_get(therm, &cur))
> +		return;
> +
>  	/* fix the state (in case someone reprogrammed the alarms) */
> -	cur = therm->func->temp_get(therm);
>  	if (new_state == NVKM_THERM_THRS_LOWER && cur > thrs->temp)
>  		new_state = NVKM_THERM_THRS_HIGHER;
>  	else if (new_state == NVKM_THERM_THRS_HIGHER &&
> diff --git a/drm/nouveau/nvkm/subdev/therm/gp100.c b/drm/nouveau/nvkm/subdev/therm/gp100.c
> index 9f0dea3f..d8206748 100644
> --- a/drm/nouveau/nvkm/subdev/therm/gp100.c
> +++ b/drm/nouveau/nvkm/subdev/therm/gp100.c
> @@ -24,7 +24,7 @@
>  #include "priv.h"
>  
>  static int
> -gp100_temp_get(struct nvkm_therm *therm)
> +gp100_temp_get(struct nvkm_therm *therm, int *val)
>  {
>  	struct nvkm_device *device = therm->subdev.device;
>  	struct nvkm_subdev *subdev = &therm->subdev;
> @@ -36,9 +36,10 @@ gp100_temp_get(struct nvkm_therm *therm)
>  		nvkm_trace(subdev, "reading temperature from SHADOWed sensor\n");
>  
>  	/* device valid */
> -	if (tsensor & 0x20000000)
> -		return (inttemp >> 8);
> -	else
> +	if (tsensor & 0x20000000) {
> +		*val = inttemp >> 8;
> +		return 0;
> +	} else
>  		return -ENODEV;
>  }
>  
> diff --git a/drm/nouveau/nvkm/subdev/therm/nv40.c b/drm/nouveau/nvkm/subdev/therm/nv40.c
> index 2c92ffb5..cfd5b215 100644
> --- a/drm/nouveau/nvkm/subdev/therm/nv40.c
> +++ b/drm/nouveau/nvkm/subdev/therm/nv40.c
> @@ -70,7 +70,7 @@ nv40_sensor_setup(struct nvkm_therm *therm)
>  }
>  
>  static int
> -nv40_temp_get(struct nvkm_therm *therm)
> +nv40_temp_get(struct nvkm_therm *therm, int *val)
>  {
>  	struct nvkm_device *device = therm->subdev.device;
>  	struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
> @@ -95,11 +95,8 @@ nv40_temp_get(struct nvkm_therm *therm)
>  	core_temp = core_temp + sensor->offset_num / sensor->offset_den;
>  	core_temp = core_temp + sensor->offset_constant - 8;
>  
> -	/* reserve negative temperatures for errors */
> -	if (core_temp < 0)
> -		core_temp = 0;
> -
> -	return core_temp;
> +	*val = core_temp;
> +	return 0;
>  }
>  
>  static int
> diff --git a/drm/nouveau/nvkm/subdev/therm/nv50.c b/drm/nouveau/nvkm/subdev/therm/nv50.c
> index 9b57b433..62ec4063 100644
> --- a/drm/nouveau/nvkm/subdev/therm/nv50.c
> +++ b/drm/nouveau/nvkm/subdev/therm/nv50.c
> @@ -126,7 +126,7 @@ nv50_sensor_setup(struct nvkm_therm *therm)
>  }
>  
>  static int
> -nv50_temp_get(struct nvkm_therm *therm)
> +nv50_temp_get(struct nvkm_therm *therm, int *val)
>  {
>  	struct nvkm_device *device = therm->subdev.device;
>  	struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
> @@ -143,11 +143,8 @@ nv50_temp_get(struct nvkm_therm *therm)
>  	core_temp = core_temp + sensor->offset_num / sensor->offset_den;
>  	core_temp = core_temp + sensor->offset_constant - 8;
>  
> -	/* reserve negative temperatures for errors */
> -	if (core_temp < 0)
> -		core_temp = 0;
> -
> -	return core_temp;
> +	*val = core_temp;
> +	return 0;
>  }
>  
>  static void
> diff --git a/drm/nouveau/nvkm/subdev/therm/priv.h b/drm/nouveau/nvkm/subdev/therm/priv.h
> index 1f46e371..b325ec5f 100644
> --- a/drm/nouveau/nvkm/subdev/therm/priv.h
> +++ b/drm/nouveau/nvkm/subdev/therm/priv.h
> @@ -91,7 +91,7 @@ struct nvkm_therm_func {
>  	int (*pwm_set)(struct nvkm_therm *, int line, u32, u32);
>  	int (*pwm_clock)(struct nvkm_therm *, int line);
>  
> -	int (*temp_get)(struct nvkm_therm *);
> +	int (*temp_get)(struct nvkm_therm *, int *);
>  
>  	int (*fan_sense)(struct nvkm_therm *);
>  
> @@ -105,7 +105,7 @@ int  nv50_fan_pwm_get(struct nvkm_therm *, int, u32 *, u32 *);
>  int  nv50_fan_pwm_set(struct nvkm_therm *, int, u32, u32);
>  int  nv50_fan_pwm_clock(struct nvkm_therm *, int);
>  
> -int  g84_temp_get(struct nvkm_therm *);
> +int  g84_temp_get(struct nvkm_therm *, int *);
>  void g84_sensor_setup(struct nvkm_therm *);
>  void g84_therm_fini(struct nvkm_therm *);
>  
> diff --git a/drm/nouveau/nvkm/subdev/therm/temp.c b/drm/nouveau/nvkm/subdev/therm/temp.c
> index ddb2b2c6..e7b8cbe2 100644
> --- a/drm/nouveau/nvkm/subdev/therm/temp.c
> +++ b/drm/nouveau/nvkm/subdev/therm/temp.c
> @@ -86,7 +86,10 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
>  	static const char * const thresholds[] = {
>  		"fanboost", "downclock", "critical", "shutdown"
>  	};
> -	int temperature = therm->func->temp_get(therm);
> +	int temperature;
> +
> +	if (therm->func->temp_get(therm, &temperature))
> +		return;
>  
>  	if (thrs < 0 || thrs > 3)
>  		return;
> @@ -140,7 +143,10 @@ nvkm_therm_threshold_hyst_polling(struct nvkm_therm *therm,
>  {
>  	enum nvkm_therm_thrs_direction direction;
>  	enum nvkm_therm_thrs_state prev_state, new_state;
> -	int temp = therm->func->temp_get(therm);
> +	int temp;
> +
> +	if (therm->func->temp_get(therm, &temp))
> +		return;
>  
>  	prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name);
>  
> @@ -166,6 +172,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
>  	struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>  	struct nvkm_timer *tmr = therm->subdev.device->timer;
>  	unsigned long flags;
> +	int val;
>  
>  	spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags);
>  
> @@ -185,7 +192,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
>  	spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags);
>  
>  	/* schedule the next poll in one second */
> -	if (therm->func->temp_get(therm) >= 0)
> +	if (!therm->func->temp_get(therm, &val))
>  		nvkm_timer_alarm(tmr, 1000000000ULL, alarm);
>  }
>  
> @@ -227,9 +234,10 @@ nvkm_therm_sensor_fini(struct nvkm_therm *therm, bool suspend)
>  void
>  nvkm_therm_sensor_preinit(struct nvkm_therm *therm)
>  {
> +	int val;
>  	const char *sensor_avail = "yes";
>  
> -	if (therm->func->temp_get(therm) < 0)
> +	if (therm->func->temp_get(therm, &val))
>  		sensor_avail = "no";
>  
>  	nvkm_debug(&therm->subdev, "internal sensor: %s\n", sensor_avail);
> 

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

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

* Re: [PATCH 01/32] bios/vpstate: There are some fermi vbios with no boost or tdp entry
       [not found]         ` <6fd6503a-0d97-9148-0ebf-cba6f8bb0180-GANU6spQydw@public.gmane.org>
@ 2017-11-22  1:33           ` Karol Herbst
  0 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-22  1:33 UTC (permalink / raw)
  To: Martin Peres; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Wed, Nov 22, 2017 at 1:16 AM, Martin Peres <martin.peres@free.fr> wrote:
> On 17/11/17 02:04, Karol Herbst wrote:
>
> Please add here something like this:
>
> If the entry size is too small, default to invalid values for both
> boost_id and tdp_id, so as to default to the base clock in both cases.
>

well actually we still have the option to go max clocks, there is no
entry for that. The entire table just defines limits, which may be
enabled or not.

>> Signed-off-by: Karol Herbst <karolherbst@gmail.com>
>
> With the better commit message, this patch is:
> Signed-off-by: Martin Peres <martin.peres@free.fr>
>
>> ---
>>  drm/nouveau/nvkm/subdev/bios/vpstate.c | 10 ++++++++--
>>  1 file changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/drm/nouveau/nvkm/subdev/bios/vpstate.c b/drm/nouveau/nvkm/subdev/bios/vpstate.c
>> index 20b6fc82..71524548 100644
>> --- a/drm/nouveau/nvkm/subdev/bios/vpstate.c
>> +++ b/drm/nouveau/nvkm/subdev/bios/vpstate.c
>> @@ -58,8 +58,14 @@ nvbios_vpstate_parse(struct nvkm_bios *b, struct nvbios_vpstate_header *h)
>>               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);
>> +             if (h->hlen > 0x10)
>> +                     h->boost_id = nvbios_rd08(b, h->offset + 0x10);
>> +             else
>> +                     h->boost_id = 0xff;
>> +             if (h->hlen > 0x11)
>> +                     h->tdp_id = nvbios_rd08(b, h->offset + 0x11);
>> +             else
>> +                     h->tdp_id = 0xff;
>>               return 0;
>>       default:
>>               return -EINVAL;
>>
>
> _______________________________________________
> Nouveau mailing list
> Nouveau@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/nouveau
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* Re: [PATCH 02/32] debugfs: Wake up GPU before doing any reclocking
       [not found]         ` <b719fba2-3f0f-298e-a816-5992b587b293-GANU6spQydw@public.gmane.org>
@ 2017-11-22  1:38           ` Karol Herbst
  0 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-22  1:38 UTC (permalink / raw)
  To: Martin Peres; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Wed, Nov 22, 2017 at 1:21 AM, Martin Peres <martin.peres@free.fr> wrote:
> On 17/11/17 02:04, Karol Herbst wrote:
>> Fixes various reclocking related issues on prime systems.
>
> Is that the only place that was not covered? Could you check if other
> places would need this code too?
>

I had quite a discussion with Ben about this and all the other cases
should be handled implicitly already. There are some follow patches to
fix some of those cases as well. Like having the therm subdev moved in
order.

> In any case, this patch is (assuming you are calling the right functions
> to prevent the GPU from sleeping):
> Signed-off-by: Martin Peres <martin.peres@free.fr>
>>
>> Signed-off-by: Karol Herbst <karolherbst@gmail.com>
>> ---
>>  drm/nouveau/nouveau_debugfs.c | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
>> index 963a4dba..9109b69c 100644
>> --- a/drm/nouveau/nouveau_debugfs.c
>> +++ b/drm/nouveau/nouveau_debugfs.c
>> @@ -160,7 +160,11 @@ nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf,
>>               args.ustate = value;
>>       }
>>
>> +     ret = pm_runtime_get_sync(drm->dev);
>> +     if (IS_ERR_VALUE(ret) && ret != -EACCES)
>> +             return ret;
>>       ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args));
>> +     pm_runtime_put_autosuspend(drm->dev);
>>       if (ret < 0)
>>               return ret;
>>
>>
>
> _______________________________________________
> Nouveau mailing list
> Nouveau@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/nouveau
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* Re: [PATCH 03/32] therm: Split return code and value in nvkm_get_temp
       [not found]         ` <e6b18baa-46d5-0ff0-bd55-c5255d22e770-GANU6spQydw@public.gmane.org>
@ 2017-11-22  1:42           ` Karol Herbst
       [not found]             ` <CACO55tvzR_iQqQY4SoECbq3MN1Tax-znrTBQsntYsGzjXGTMHg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Karol Herbst @ 2017-11-22  1:42 UTC (permalink / raw)
  To: Martin Peres; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Wed, Nov 22, 2017 at 1:32 AM, Martin Peres <martin.peres@free.fr> wrote:
> On 17/11/17 02:04, Karol Herbst wrote:
>> The current hwmon code doesn't check if the returned value was actually an
>> error.
>>
>> Since Kepler temperature sensors are able to report negative values. Those
>> negative values are not for error reporting, but rather when you buried
>> your GPU in snow somewhere in Antarctica and still want a valid
>> temperature to be reported (unverified).
>>
>> Since Pascal (and maybe earlier) we have sensors with improved precision.
>>
>> Adjust the nvkm_get_temp method to be able to deal with those changes
>> and let hwmon return an error properly.
>
> Where did you get this information? And if it is the case, then we will
> royally screw up the value because we don't even know on how many bits
> 0x20400 uses...
>
> If you are indeed right, I would like to see g84.c's temp_get().
>

Nvidia uses 0x020460 on Pascal and I thought we had that in envytools already?

[0] 228.412618 MMIO32 R 0x020460 0x20002f20 PTHERM.I2C_SLAVE+0x60 => 0x20002f20
[0] 229.413039 MMIO32 R 0x020460 0x20002f10 PTHERM.I2C_SLAVE+0x60 => 0x20002f10
[0] 230.416976 MMIO32 R 0x020460 0x20002f68 PTHERM.I2C_SLAVE+0x60 => 0x20002f68
[0] 231.417407 MMIO32 R 0x020460 0x20002fe8 PTHERM.I2C_SLAVE+0x60 => 0x20002fe8
[0] 232.417742 MMIO32 R 0x020460 0x20002ff0 PTHERM.I2C_SLAVE+0x60 => 0x20002ff0
[0] 233.417742 MMIO32 R 0x020460 0x20003020 PTHERM.I2C_SLAVE+0x60 => 0x20003020

or nvapeek 0x20400 && nvapeek 0x020460;
00020400: 0000002c
00020460: 20002c60

>>
>> Signed-off-by: Karol Herbst <karolherbst@gmail.com>
>> ---
>>  drm/nouveau/include/nvkm/subdev/clk.h   |  4 ++--
>>  drm/nouveau/include/nvkm/subdev/therm.h |  2 +-
>>  drm/nouveau/nouveau_hwmon.c             | 15 +++++++++------
>>  drm/nouveau/nvkm/subdev/clk/base.c      |  2 +-
>>  drm/nouveau/nvkm/subdev/therm/base.c    | 19 ++++++++++++++-----
>>  drm/nouveau/nvkm/subdev/therm/g84.c     | 13 ++++++++-----
>>  drm/nouveau/nvkm/subdev/therm/gp100.c   |  9 +++++----
>>  drm/nouveau/nvkm/subdev/therm/nv40.c    |  9 +++------
>>  drm/nouveau/nvkm/subdev/therm/nv50.c    |  9 +++------
>>  drm/nouveau/nvkm/subdev/therm/priv.h    |  4 ++--
>>  drm/nouveau/nvkm/subdev/therm/temp.c    | 16 ++++++++++++----
>>  11 files changed, 60 insertions(+), 42 deletions(-)
>>
>> diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
>> index e5275f74..506f8cc6 100644
>> --- a/drm/nouveau/include/nvkm/subdev/clk.h
>> +++ b/drm/nouveau/include/nvkm/subdev/clk.h
>> @@ -100,7 +100,7 @@ struct nvkm_clk {
>>       int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
>>       int astate; /* perfmon adjustment (base) */
>>       int dstate; /* display adjustment (min+) */
>> -     u8  temp;
>> +     int temp;
>>
>>       bool allow_reclock;
>>  #define NVKM_CLK_BOOST_NONE 0x0
>> @@ -122,7 +122,7 @@ 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 *, u8 temperature);
>> +int nvkm_clk_tstate(struct nvkm_clk *, int temperature);
>>
>>  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/include/nvkm/subdev/therm.h b/drm/nouveau/include/nvkm/subdev/therm.h
>> index 9841f076..8c84017f 100644
>> --- a/drm/nouveau/include/nvkm/subdev/therm.h
>> +++ b/drm/nouveau/include/nvkm/subdev/therm.h
>> @@ -86,7 +86,7 @@ struct nvkm_therm {
>>       int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
>>  };
>>
>> -int nvkm_therm_temp_get(struct nvkm_therm *);
>> +int nvkm_therm_temp_get(struct nvkm_therm *, int *);
>>  int nvkm_therm_fan_sense(struct nvkm_therm *);
>>  int nvkm_therm_cstate(struct nvkm_therm *, int, int);
>>
>> diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
>> index 7c965648..7486e4af 100644
>> --- a/drm/nouveau/nouveau_hwmon.c
>> +++ b/drm/nouveau/nouveau_hwmon.c
>> @@ -326,8 +326,9 @@ nouveau_temp_is_visible(const void *data, u32 attr, int channel)
>>  {
>>       struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>>       struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
>> +     int val;
>>
>> -     if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
>> +     if (therm && therm->attr_get && nvkm_therm_temp_get(therm, &val))
>>               return 0;
>>
>>       switch (attr) {
>> @@ -421,15 +422,16 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
>>       struct drm_device *drm_dev = dev_get_drvdata(dev);
>>       struct nouveau_drm *drm = nouveau_drm(drm_dev);
>>       struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
>> -     int ret;
>> +     int ret = 0;
>> +     int temp;
>>
>>       if (!therm || !therm->attr_get)
>>               return -EOPNOTSUPP;
>>
>>       switch (attr) {
>>       case hwmon_temp_input:
>> -             ret = nvkm_therm_temp_get(therm);
>> -             *val = ret < 0 ? ret : (ret * 1000);
>> +             ret = nvkm_therm_temp_get(therm, &temp);
>> +             *val = temp * 1000;
>>               break;
>>       case hwmon_temp_max:
>>               *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
>> @@ -459,7 +461,7 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
>>               return -EOPNOTSUPP;
>>       }
>>
>> -     return 0;
>> +     return ret;
>>  }
>>
>>  static int
>> @@ -713,6 +715,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>>       struct device *hwmon_dev;
>>       int ret = 0;
>>       int i = 0;
>> +     int val;
>>
>>       hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
>>       if (!hwmon)
>> @@ -720,7 +723,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>>       hwmon->dev = dev;
>>
>>       if (therm && therm->attr_get && therm->attr_set) {
>> -             if (nvkm_therm_temp_get(therm) >= 0)
>> +             if (!nvkm_therm_temp_get(therm, &val))
>>                       special_groups[i++] = &temp1_auto_point_sensor_group;
>>               if (therm->fan_get && therm->fan_get(therm) >= 0)
>>                       special_groups[i++] = &pwm_fan_sensor_group;
>> diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
>> index e4c8d310..0b28dbb9 100644
>> --- a/drm/nouveau/nvkm/subdev/clk/base.c
>> +++ b/drm/nouveau/nvkm/subdev/clk/base.c
>> @@ -540,7 +540,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
>>  }
>>
>>  int
>> -nvkm_clk_tstate(struct nvkm_clk *clk, u8 temp)
>> +nvkm_clk_tstate(struct nvkm_clk *clk, int temp)
>>  {
>>       if (clk->temp == temp)
>>               return 0;
>> diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
>> index f27fc6d0..8e5f6f7f 100644
>> --- a/drm/nouveau/nvkm/subdev/therm/base.c
>> +++ b/drm/nouveau/nvkm/subdev/therm/base.c
>> @@ -24,22 +24,26 @@
>>  #include "priv.h"
>>
>>  int
>> -nvkm_therm_temp_get(struct nvkm_therm *therm)
>> +nvkm_therm_temp_get(struct nvkm_therm *therm, int *val)
>>  {
>>       if (therm->func->temp_get)
>> -             return therm->func->temp_get(therm);
>> +             return therm->func->temp_get(therm, val);
>>       return -ENODEV;
>>  }
>>
>>  static int
>>  nvkm_therm_update_trip(struct nvkm_therm *therm)
>>  {
>> +     int temp, ret;
>>       struct nvbios_therm_trip_point *trip = therm->fan->bios.trip,
>>                                      *cur_trip = NULL,
>>                                      *last_trip = therm->last_trip;
>> -     u8  temp = therm->func->temp_get(therm);
>>       u16 duty, i;
>>
>> +     ret = therm->func->temp_get(therm, &temp);
>> +     if (ret < 0)
>> +             return ret;
>> +
>>       /* look for the trip point corresponding to the current temperature */
>>       cur_trip = NULL;
>>       for (i = 0; i < therm->fan->bios.nr_fan_trip; i++) {
>> @@ -67,9 +71,13 @@ static int
>>  nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
>>                                 u8 linear_max_temp)
>>  {
>> -     u8  temp = therm->func->temp_get(therm);
>> +     int temp, ret;
>>       u16 duty;
>>
>> +     ret = therm->func->temp_get(therm, &temp);
>> +     if (ret < 0)
>> +             return ret;
>> +
>>       /* handle the non-linear part first */
>>       if (temp < linear_min_temp)
>>               return therm->fan->bios.min_duty;
>> @@ -182,6 +190,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
>>  {
>>       struct nvkm_subdev *subdev = &therm->subdev;
>>       struct nvkm_device *device = subdev->device;
>> +     int val;
>>       static const char *name[] = {
>>               "disabled",
>>               "manual",
>> @@ -197,7 +206,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
>>       /* do not allow automatic fan management if the thermal sensor is
>>        * not available */
>>       if (mode == NVKM_THERM_CTRL_AUTO &&
>> -         therm->func->temp_get(therm) < 0)
>> +         therm->func->temp_get(therm, &val))
>>               return -EINVAL;
>>
>>       if (therm->mode == mode)
>> diff --git a/drm/nouveau/nvkm/subdev/therm/g84.c b/drm/nouveau/nvkm/subdev/therm/g84.c
>> index 96f8da40..81c0bda8 100644
>> --- a/drm/nouveau/nvkm/subdev/therm/g84.c
>> +++ b/drm/nouveau/nvkm/subdev/therm/g84.c
>> @@ -27,14 +27,15 @@
>>  #include <subdev/fuse.h>
>>
>>  int
>> -g84_temp_get(struct nvkm_therm *therm)
>> +g84_temp_get(struct nvkm_therm *therm, int *val)
>>  {
>>       struct nvkm_device *device = therm->subdev.device;
>>
>> -     if (nvkm_fuse_read(device->fuse, 0x1a8) == 1)
>> -             return nvkm_rd32(device, 0x20400);
>> -     else
>> +     if (nvkm_fuse_read(device->fuse, 0x1a8) != 1)
>>               return -ENODEV;
>> +
>> +     *val = nvkm_rd32(device, 0x20400);
>> +     return 0;
>>  }
>>
>>  void
>> @@ -114,8 +115,10 @@ g84_therm_threshold_hyst_emulation(struct nvkm_therm *therm,
>>               new_state = NVKM_THERM_THRS_LOWER;
>>       }
>>
>> +     if (therm->func->temp_get(therm, &cur))
>> +             return;
>> +
>>       /* fix the state (in case someone reprogrammed the alarms) */
>> -     cur = therm->func->temp_get(therm);
>>       if (new_state == NVKM_THERM_THRS_LOWER && cur > thrs->temp)
>>               new_state = NVKM_THERM_THRS_HIGHER;
>>       else if (new_state == NVKM_THERM_THRS_HIGHER &&
>> diff --git a/drm/nouveau/nvkm/subdev/therm/gp100.c b/drm/nouveau/nvkm/subdev/therm/gp100.c
>> index 9f0dea3f..d8206748 100644
>> --- a/drm/nouveau/nvkm/subdev/therm/gp100.c
>> +++ b/drm/nouveau/nvkm/subdev/therm/gp100.c
>> @@ -24,7 +24,7 @@
>>  #include "priv.h"
>>
>>  static int
>> -gp100_temp_get(struct nvkm_therm *therm)
>> +gp100_temp_get(struct nvkm_therm *therm, int *val)
>>  {
>>       struct nvkm_device *device = therm->subdev.device;
>>       struct nvkm_subdev *subdev = &therm->subdev;
>> @@ -36,9 +36,10 @@ gp100_temp_get(struct nvkm_therm *therm)
>>               nvkm_trace(subdev, "reading temperature from SHADOWed sensor\n");
>>
>>       /* device valid */
>> -     if (tsensor & 0x20000000)
>> -             return (inttemp >> 8);
>> -     else
>> +     if (tsensor & 0x20000000) {
>> +             *val = inttemp >> 8;
>> +             return 0;
>> +     } else
>>               return -ENODEV;
>>  }
>>
>> diff --git a/drm/nouveau/nvkm/subdev/therm/nv40.c b/drm/nouveau/nvkm/subdev/therm/nv40.c
>> index 2c92ffb5..cfd5b215 100644
>> --- a/drm/nouveau/nvkm/subdev/therm/nv40.c
>> +++ b/drm/nouveau/nvkm/subdev/therm/nv40.c
>> @@ -70,7 +70,7 @@ nv40_sensor_setup(struct nvkm_therm *therm)
>>  }
>>
>>  static int
>> -nv40_temp_get(struct nvkm_therm *therm)
>> +nv40_temp_get(struct nvkm_therm *therm, int *val)
>>  {
>>       struct nvkm_device *device = therm->subdev.device;
>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>> @@ -95,11 +95,8 @@ nv40_temp_get(struct nvkm_therm *therm)
>>       core_temp = core_temp + sensor->offset_num / sensor->offset_den;
>>       core_temp = core_temp + sensor->offset_constant - 8;
>>
>> -     /* reserve negative temperatures for errors */
>> -     if (core_temp < 0)
>> -             core_temp = 0;
>> -
>> -     return core_temp;
>> +     *val = core_temp;
>> +     return 0;
>>  }
>>
>>  static int
>> diff --git a/drm/nouveau/nvkm/subdev/therm/nv50.c b/drm/nouveau/nvkm/subdev/therm/nv50.c
>> index 9b57b433..62ec4063 100644
>> --- a/drm/nouveau/nvkm/subdev/therm/nv50.c
>> +++ b/drm/nouveau/nvkm/subdev/therm/nv50.c
>> @@ -126,7 +126,7 @@ nv50_sensor_setup(struct nvkm_therm *therm)
>>  }
>>
>>  static int
>> -nv50_temp_get(struct nvkm_therm *therm)
>> +nv50_temp_get(struct nvkm_therm *therm, int *val)
>>  {
>>       struct nvkm_device *device = therm->subdev.device;
>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>> @@ -143,11 +143,8 @@ nv50_temp_get(struct nvkm_therm *therm)
>>       core_temp = core_temp + sensor->offset_num / sensor->offset_den;
>>       core_temp = core_temp + sensor->offset_constant - 8;
>>
>> -     /* reserve negative temperatures for errors */
>> -     if (core_temp < 0)
>> -             core_temp = 0;
>> -
>> -     return core_temp;
>> +     *val = core_temp;
>> +     return 0;
>>  }
>>
>>  static void
>> diff --git a/drm/nouveau/nvkm/subdev/therm/priv.h b/drm/nouveau/nvkm/subdev/therm/priv.h
>> index 1f46e371..b325ec5f 100644
>> --- a/drm/nouveau/nvkm/subdev/therm/priv.h
>> +++ b/drm/nouveau/nvkm/subdev/therm/priv.h
>> @@ -91,7 +91,7 @@ struct nvkm_therm_func {
>>       int (*pwm_set)(struct nvkm_therm *, int line, u32, u32);
>>       int (*pwm_clock)(struct nvkm_therm *, int line);
>>
>> -     int (*temp_get)(struct nvkm_therm *);
>> +     int (*temp_get)(struct nvkm_therm *, int *);
>>
>>       int (*fan_sense)(struct nvkm_therm *);
>>
>> @@ -105,7 +105,7 @@ int  nv50_fan_pwm_get(struct nvkm_therm *, int, u32 *, u32 *);
>>  int  nv50_fan_pwm_set(struct nvkm_therm *, int, u32, u32);
>>  int  nv50_fan_pwm_clock(struct nvkm_therm *, int);
>>
>> -int  g84_temp_get(struct nvkm_therm *);
>> +int  g84_temp_get(struct nvkm_therm *, int *);
>>  void g84_sensor_setup(struct nvkm_therm *);
>>  void g84_therm_fini(struct nvkm_therm *);
>>
>> diff --git a/drm/nouveau/nvkm/subdev/therm/temp.c b/drm/nouveau/nvkm/subdev/therm/temp.c
>> index ddb2b2c6..e7b8cbe2 100644
>> --- a/drm/nouveau/nvkm/subdev/therm/temp.c
>> +++ b/drm/nouveau/nvkm/subdev/therm/temp.c
>> @@ -86,7 +86,10 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
>>       static const char * const thresholds[] = {
>>               "fanboost", "downclock", "critical", "shutdown"
>>       };
>> -     int temperature = therm->func->temp_get(therm);
>> +     int temperature;
>> +
>> +     if (therm->func->temp_get(therm, &temperature))
>> +             return;
>>
>>       if (thrs < 0 || thrs > 3)
>>               return;
>> @@ -140,7 +143,10 @@ nvkm_therm_threshold_hyst_polling(struct nvkm_therm *therm,
>>  {
>>       enum nvkm_therm_thrs_direction direction;
>>       enum nvkm_therm_thrs_state prev_state, new_state;
>> -     int temp = therm->func->temp_get(therm);
>> +     int temp;
>> +
>> +     if (therm->func->temp_get(therm, &temp))
>> +             return;
>>
>>       prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name);
>>
>> @@ -166,6 +172,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>>       struct nvkm_timer *tmr = therm->subdev.device->timer;
>>       unsigned long flags;
>> +     int val;
>>
>>       spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags);
>>
>> @@ -185,7 +192,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
>>       spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags);
>>
>>       /* schedule the next poll in one second */
>> -     if (therm->func->temp_get(therm) >= 0)
>> +     if (!therm->func->temp_get(therm, &val))
>>               nvkm_timer_alarm(tmr, 1000000000ULL, alarm);
>>  }
>>
>> @@ -227,9 +234,10 @@ nvkm_therm_sensor_fini(struct nvkm_therm *therm, bool suspend)
>>  void
>>  nvkm_therm_sensor_preinit(struct nvkm_therm *therm)
>>  {
>> +     int val;
>>       const char *sensor_avail = "yes";
>>
>> -     if (therm->func->temp_get(therm) < 0)
>> +     if (therm->func->temp_get(therm, &val))
>>               sensor_avail = "no";
>>
>>       nvkm_debug(&therm->subdev, "internal sensor: %s\n", sensor_avail);
>>
>
> _______________________________________________
> Nouveau mailing list
> Nouveau@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/nouveau
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* Re: [PATCH 03/32] therm: Split return code and value in nvkm_get_temp
       [not found]             ` <CACO55tvzR_iQqQY4SoECbq3MN1Tax-znrTBQsntYsGzjXGTMHg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-11-22  8:29               ` Martin Peres
       [not found]                 ` <9ff53665-3058-31a0-7020-bdbd6ba00f24-GANU6spQydw@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Martin Peres @ 2017-11-22  8:29 UTC (permalink / raw)
  To: Karol Herbst; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 22/11/17 03:42, Karol Herbst wrote:
> On Wed, Nov 22, 2017 at 1:32 AM, Martin Peres <martin.peres@free.fr> wrote:
>> On 17/11/17 02:04, Karol Herbst wrote:
>>> The current hwmon code doesn't check if the returned value was actually an
>>> error.
>>>
>>> Since Kepler temperature sensors are able to report negative values. Those
>>> negative values are not for error reporting, but rather when you buried
>>> your GPU in snow somewhere in Antarctica and still want a valid
>>> temperature to be reported (unverified).
>>>
>>> Since Pascal (and maybe earlier) we have sensors with improved precision.
>>>
>>> Adjust the nvkm_get_temp method to be able to deal with those changes
>>> and let hwmon return an error properly.
>>
>> Where did you get this information? And if it is the case, then we will
>> royally screw up the value because we don't even know on how many bits
>> 0x20400 uses...
>>
>> If you are indeed right, I would like to see g84.c's temp_get().
>>
> 
> Nvidia uses 0x020460 on Pascal and I thought we had that in envytools already?

Nothing in nvbios.

> 
> [0] 228.412618 MMIO32 R 0x020460 0x20002f20 PTHERM.I2C_SLAVE+0x60 => 0x20002f20
> [0] 229.413039 MMIO32 R 0x020460 0x20002f10 PTHERM.I2C_SLAVE+0x60 => 0x20002f10
> [0] 230.416976 MMIO32 R 0x020460 0x20002f68 PTHERM.I2C_SLAVE+0x60 => 0x20002f68
> [0] 231.417407 MMIO32 R 0x020460 0x20002fe8 PTHERM.I2C_SLAVE+0x60 => 0x20002fe8
> [0] 232.417742 MMIO32 R 0x020460 0x20002ff0 PTHERM.I2C_SLAVE+0x60 => 0x20002ff0
> [0] 233.417742 MMIO32 R 0x020460 0x20003020 PTHERM.I2C_SLAVE+0x60 => 0x20003020
> 
> or nvapeek 0x20400 && nvapeek 0x020460;
> 00020400: 0000002c
> 00020460: 20002c60

Cool that they increased the accuracy, but where do you get that the
value can be negative? And if it is, how many bits are used? 16 or more?
What are those high bits?

> 
>>>
>>> Signed-off-by: Karol Herbst <karolherbst@gmail.com>
>>> ---
>>>  drm/nouveau/include/nvkm/subdev/clk.h   |  4 ++--
>>>  drm/nouveau/include/nvkm/subdev/therm.h |  2 +-
>>>  drm/nouveau/nouveau_hwmon.c             | 15 +++++++++------
>>>  drm/nouveau/nvkm/subdev/clk/base.c      |  2 +-
>>>  drm/nouveau/nvkm/subdev/therm/base.c    | 19 ++++++++++++++-----
>>>  drm/nouveau/nvkm/subdev/therm/g84.c     | 13 ++++++++-----
>>>  drm/nouveau/nvkm/subdev/therm/gp100.c   |  9 +++++----
>>>  drm/nouveau/nvkm/subdev/therm/nv40.c    |  9 +++------
>>>  drm/nouveau/nvkm/subdev/therm/nv50.c    |  9 +++------
>>>  drm/nouveau/nvkm/subdev/therm/priv.h    |  4 ++--
>>>  drm/nouveau/nvkm/subdev/therm/temp.c    | 16 ++++++++++++----
>>>  11 files changed, 60 insertions(+), 42 deletions(-)
>>>
>>> diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
>>> index e5275f74..506f8cc6 100644
>>> --- a/drm/nouveau/include/nvkm/subdev/clk.h
>>> +++ b/drm/nouveau/include/nvkm/subdev/clk.h
>>> @@ -100,7 +100,7 @@ struct nvkm_clk {
>>>       int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
>>>       int astate; /* perfmon adjustment (base) */
>>>       int dstate; /* display adjustment (min+) */
>>> -     u8  temp;
>>> +     int temp;
>>>
>>>       bool allow_reclock;
>>>  #define NVKM_CLK_BOOST_NONE 0x0
>>> @@ -122,7 +122,7 @@ 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 *, u8 temperature);
>>> +int nvkm_clk_tstate(struct nvkm_clk *, int temperature);
>>>
>>>  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/include/nvkm/subdev/therm.h b/drm/nouveau/include/nvkm/subdev/therm.h
>>> index 9841f076..8c84017f 100644
>>> --- a/drm/nouveau/include/nvkm/subdev/therm.h
>>> +++ b/drm/nouveau/include/nvkm/subdev/therm.h
>>> @@ -86,7 +86,7 @@ struct nvkm_therm {
>>>       int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
>>>  };
>>>
>>> -int nvkm_therm_temp_get(struct nvkm_therm *);
>>> +int nvkm_therm_temp_get(struct nvkm_therm *, int *);
>>>  int nvkm_therm_fan_sense(struct nvkm_therm *);
>>>  int nvkm_therm_cstate(struct nvkm_therm *, int, int);
>>>
>>> diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
>>> index 7c965648..7486e4af 100644
>>> --- a/drm/nouveau/nouveau_hwmon.c
>>> +++ b/drm/nouveau/nouveau_hwmon.c
>>> @@ -326,8 +326,9 @@ nouveau_temp_is_visible(const void *data, u32 attr, int channel)
>>>  {
>>>       struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>>>       struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
>>> +     int val;
>>>
>>> -     if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
>>> +     if (therm && therm->attr_get && nvkm_therm_temp_get(therm, &val))
>>>               return 0;
>>>
>>>       switch (attr) {
>>> @@ -421,15 +422,16 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
>>>       struct drm_device *drm_dev = dev_get_drvdata(dev);
>>>       struct nouveau_drm *drm = nouveau_drm(drm_dev);
>>>       struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
>>> -     int ret;
>>> +     int ret = 0;
>>> +     int temp;
>>>
>>>       if (!therm || !therm->attr_get)
>>>               return -EOPNOTSUPP;
>>>
>>>       switch (attr) {
>>>       case hwmon_temp_input:
>>> -             ret = nvkm_therm_temp_get(therm);
>>> -             *val = ret < 0 ? ret : (ret * 1000);
>>> +             ret = nvkm_therm_temp_get(therm, &temp);
>>> +             *val = temp * 1000;
>>>               break;
>>>       case hwmon_temp_max:
>>>               *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
>>> @@ -459,7 +461,7 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
>>>               return -EOPNOTSUPP;
>>>       }
>>>
>>> -     return 0;
>>> +     return ret;
>>>  }
>>>
>>>  static int
>>> @@ -713,6 +715,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>>>       struct device *hwmon_dev;
>>>       int ret = 0;
>>>       int i = 0;
>>> +     int val;
>>>
>>>       hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
>>>       if (!hwmon)
>>> @@ -720,7 +723,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>>>       hwmon->dev = dev;
>>>
>>>       if (therm && therm->attr_get && therm->attr_set) {
>>> -             if (nvkm_therm_temp_get(therm) >= 0)
>>> +             if (!nvkm_therm_temp_get(therm, &val))
>>>                       special_groups[i++] = &temp1_auto_point_sensor_group;
>>>               if (therm->fan_get && therm->fan_get(therm) >= 0)
>>>                       special_groups[i++] = &pwm_fan_sensor_group;
>>> diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
>>> index e4c8d310..0b28dbb9 100644
>>> --- a/drm/nouveau/nvkm/subdev/clk/base.c
>>> +++ b/drm/nouveau/nvkm/subdev/clk/base.c
>>> @@ -540,7 +540,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
>>>  }
>>>
>>>  int
>>> -nvkm_clk_tstate(struct nvkm_clk *clk, u8 temp)
>>> +nvkm_clk_tstate(struct nvkm_clk *clk, int temp)
>>>  {
>>>       if (clk->temp == temp)
>>>               return 0;
>>> diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
>>> index f27fc6d0..8e5f6f7f 100644
>>> --- a/drm/nouveau/nvkm/subdev/therm/base.c
>>> +++ b/drm/nouveau/nvkm/subdev/therm/base.c
>>> @@ -24,22 +24,26 @@
>>>  #include "priv.h"
>>>
>>>  int
>>> -nvkm_therm_temp_get(struct nvkm_therm *therm)
>>> +nvkm_therm_temp_get(struct nvkm_therm *therm, int *val)
>>>  {
>>>       if (therm->func->temp_get)
>>> -             return therm->func->temp_get(therm);
>>> +             return therm->func->temp_get(therm, val);
>>>       return -ENODEV;
>>>  }
>>>
>>>  static int
>>>  nvkm_therm_update_trip(struct nvkm_therm *therm)
>>>  {
>>> +     int temp, ret;
>>>       struct nvbios_therm_trip_point *trip = therm->fan->bios.trip,
>>>                                      *cur_trip = NULL,
>>>                                      *last_trip = therm->last_trip;
>>> -     u8  temp = therm->func->temp_get(therm);
>>>       u16 duty, i;
>>>
>>> +     ret = therm->func->temp_get(therm, &temp);
>>> +     if (ret < 0)
>>> +             return ret;
>>> +
>>>       /* look for the trip point corresponding to the current temperature */
>>>       cur_trip = NULL;
>>>       for (i = 0; i < therm->fan->bios.nr_fan_trip; i++) {
>>> @@ -67,9 +71,13 @@ static int
>>>  nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
>>>                                 u8 linear_max_temp)
>>>  {
>>> -     u8  temp = therm->func->temp_get(therm);
>>> +     int temp, ret;
>>>       u16 duty;
>>>
>>> +     ret = therm->func->temp_get(therm, &temp);
>>> +     if (ret < 0)
>>> +             return ret;
>>> +
>>>       /* handle the non-linear part first */
>>>       if (temp < linear_min_temp)
>>>               return therm->fan->bios.min_duty;
>>> @@ -182,6 +190,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
>>>  {
>>>       struct nvkm_subdev *subdev = &therm->subdev;
>>>       struct nvkm_device *device = subdev->device;
>>> +     int val;
>>>       static const char *name[] = {
>>>               "disabled",
>>>               "manual",
>>> @@ -197,7 +206,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
>>>       /* do not allow automatic fan management if the thermal sensor is
>>>        * not available */
>>>       if (mode == NVKM_THERM_CTRL_AUTO &&
>>> -         therm->func->temp_get(therm) < 0)
>>> +         therm->func->temp_get(therm, &val))
>>>               return -EINVAL;
>>>
>>>       if (therm->mode == mode)
>>> diff --git a/drm/nouveau/nvkm/subdev/therm/g84.c b/drm/nouveau/nvkm/subdev/therm/g84.c
>>> index 96f8da40..81c0bda8 100644
>>> --- a/drm/nouveau/nvkm/subdev/therm/g84.c
>>> +++ b/drm/nouveau/nvkm/subdev/therm/g84.c
>>> @@ -27,14 +27,15 @@
>>>  #include <subdev/fuse.h>
>>>
>>>  int
>>> -g84_temp_get(struct nvkm_therm *therm)
>>> +g84_temp_get(struct nvkm_therm *therm, int *val)
>>>  {
>>>       struct nvkm_device *device = therm->subdev.device;
>>>
>>> -     if (nvkm_fuse_read(device->fuse, 0x1a8) == 1)
>>> -             return nvkm_rd32(device, 0x20400);
>>> -     else
>>> +     if (nvkm_fuse_read(device->fuse, 0x1a8) != 1)
>>>               return -ENODEV;
>>> +
>>> +     *val = nvkm_rd32(device, 0x20400);
>>> +     return 0;
>>>  }
>>>
>>>  void
>>> @@ -114,8 +115,10 @@ g84_therm_threshold_hyst_emulation(struct nvkm_therm *therm,
>>>               new_state = NVKM_THERM_THRS_LOWER;
>>>       }
>>>
>>> +     if (therm->func->temp_get(therm, &cur))
>>> +             return;
>>> +
>>>       /* fix the state (in case someone reprogrammed the alarms) */
>>> -     cur = therm->func->temp_get(therm);
>>>       if (new_state == NVKM_THERM_THRS_LOWER && cur > thrs->temp)
>>>               new_state = NVKM_THERM_THRS_HIGHER;
>>>       else if (new_state == NVKM_THERM_THRS_HIGHER &&
>>> diff --git a/drm/nouveau/nvkm/subdev/therm/gp100.c b/drm/nouveau/nvkm/subdev/therm/gp100.c
>>> index 9f0dea3f..d8206748 100644
>>> --- a/drm/nouveau/nvkm/subdev/therm/gp100.c
>>> +++ b/drm/nouveau/nvkm/subdev/therm/gp100.c
>>> @@ -24,7 +24,7 @@
>>>  #include "priv.h"
>>>
>>>  static int
>>> -gp100_temp_get(struct nvkm_therm *therm)
>>> +gp100_temp_get(struct nvkm_therm *therm, int *val)
>>>  {
>>>       struct nvkm_device *device = therm->subdev.device;
>>>       struct nvkm_subdev *subdev = &therm->subdev;
>>> @@ -36,9 +36,10 @@ gp100_temp_get(struct nvkm_therm *therm)
>>>               nvkm_trace(subdev, "reading temperature from SHADOWed sensor\n");
>>>
>>>       /* device valid */
>>> -     if (tsensor & 0x20000000)
>>> -             return (inttemp >> 8);
>>> -     else
>>> +     if (tsensor & 0x20000000) {
>>> +             *val = inttemp >> 8;
>>> +             return 0;
>>> +     } else
>>>               return -ENODEV;
>>>  }
>>>
>>> diff --git a/drm/nouveau/nvkm/subdev/therm/nv40.c b/drm/nouveau/nvkm/subdev/therm/nv40.c
>>> index 2c92ffb5..cfd5b215 100644
>>> --- a/drm/nouveau/nvkm/subdev/therm/nv40.c
>>> +++ b/drm/nouveau/nvkm/subdev/therm/nv40.c
>>> @@ -70,7 +70,7 @@ nv40_sensor_setup(struct nvkm_therm *therm)
>>>  }
>>>
>>>  static int
>>> -nv40_temp_get(struct nvkm_therm *therm)
>>> +nv40_temp_get(struct nvkm_therm *therm, int *val)
>>>  {
>>>       struct nvkm_device *device = therm->subdev.device;
>>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>>> @@ -95,11 +95,8 @@ nv40_temp_get(struct nvkm_therm *therm)
>>>       core_temp = core_temp + sensor->offset_num / sensor->offset_den;
>>>       core_temp = core_temp + sensor->offset_constant - 8;
>>>
>>> -     /* reserve negative temperatures for errors */
>>> -     if (core_temp < 0)
>>> -             core_temp = 0;
>>> -
>>> -     return core_temp;
>>> +     *val = core_temp;
>>> +     return 0;
>>>  }
>>>
>>>  static int
>>> diff --git a/drm/nouveau/nvkm/subdev/therm/nv50.c b/drm/nouveau/nvkm/subdev/therm/nv50.c
>>> index 9b57b433..62ec4063 100644
>>> --- a/drm/nouveau/nvkm/subdev/therm/nv50.c
>>> +++ b/drm/nouveau/nvkm/subdev/therm/nv50.c
>>> @@ -126,7 +126,7 @@ nv50_sensor_setup(struct nvkm_therm *therm)
>>>  }
>>>
>>>  static int
>>> -nv50_temp_get(struct nvkm_therm *therm)
>>> +nv50_temp_get(struct nvkm_therm *therm, int *val)
>>>  {
>>>       struct nvkm_device *device = therm->subdev.device;
>>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>>> @@ -143,11 +143,8 @@ nv50_temp_get(struct nvkm_therm *therm)
>>>       core_temp = core_temp + sensor->offset_num / sensor->offset_den;
>>>       core_temp = core_temp + sensor->offset_constant - 8;
>>>
>>> -     /* reserve negative temperatures for errors */
>>> -     if (core_temp < 0)
>>> -             core_temp = 0;
>>> -
>>> -     return core_temp;
>>> +     *val = core_temp;
>>> +     return 0;
>>>  }
>>>
>>>  static void
>>> diff --git a/drm/nouveau/nvkm/subdev/therm/priv.h b/drm/nouveau/nvkm/subdev/therm/priv.h
>>> index 1f46e371..b325ec5f 100644
>>> --- a/drm/nouveau/nvkm/subdev/therm/priv.h
>>> +++ b/drm/nouveau/nvkm/subdev/therm/priv.h
>>> @@ -91,7 +91,7 @@ struct nvkm_therm_func {
>>>       int (*pwm_set)(struct nvkm_therm *, int line, u32, u32);
>>>       int (*pwm_clock)(struct nvkm_therm *, int line);
>>>
>>> -     int (*temp_get)(struct nvkm_therm *);
>>> +     int (*temp_get)(struct nvkm_therm *, int *);
>>>
>>>       int (*fan_sense)(struct nvkm_therm *);
>>>
>>> @@ -105,7 +105,7 @@ int  nv50_fan_pwm_get(struct nvkm_therm *, int, u32 *, u32 *);
>>>  int  nv50_fan_pwm_set(struct nvkm_therm *, int, u32, u32);
>>>  int  nv50_fan_pwm_clock(struct nvkm_therm *, int);
>>>
>>> -int  g84_temp_get(struct nvkm_therm *);
>>> +int  g84_temp_get(struct nvkm_therm *, int *);
>>>  void g84_sensor_setup(struct nvkm_therm *);
>>>  void g84_therm_fini(struct nvkm_therm *);
>>>
>>> diff --git a/drm/nouveau/nvkm/subdev/therm/temp.c b/drm/nouveau/nvkm/subdev/therm/temp.c
>>> index ddb2b2c6..e7b8cbe2 100644
>>> --- a/drm/nouveau/nvkm/subdev/therm/temp.c
>>> +++ b/drm/nouveau/nvkm/subdev/therm/temp.c
>>> @@ -86,7 +86,10 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
>>>       static const char * const thresholds[] = {
>>>               "fanboost", "downclock", "critical", "shutdown"
>>>       };
>>> -     int temperature = therm->func->temp_get(therm);
>>> +     int temperature;
>>> +
>>> +     if (therm->func->temp_get(therm, &temperature))
>>> +             return;
>>>
>>>       if (thrs < 0 || thrs > 3)
>>>               return;
>>> @@ -140,7 +143,10 @@ nvkm_therm_threshold_hyst_polling(struct nvkm_therm *therm,
>>>  {
>>>       enum nvkm_therm_thrs_direction direction;
>>>       enum nvkm_therm_thrs_state prev_state, new_state;
>>> -     int temp = therm->func->temp_get(therm);
>>> +     int temp;
>>> +
>>> +     if (therm->func->temp_get(therm, &temp))
>>> +             return;
>>>
>>>       prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name);
>>>
>>> @@ -166,6 +172,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
>>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>>>       struct nvkm_timer *tmr = therm->subdev.device->timer;
>>>       unsigned long flags;
>>> +     int val;
>>>
>>>       spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags);
>>>
>>> @@ -185,7 +192,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
>>>       spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags);
>>>
>>>       /* schedule the next poll in one second */
>>> -     if (therm->func->temp_get(therm) >= 0)
>>> +     if (!therm->func->temp_get(therm, &val))
>>>               nvkm_timer_alarm(tmr, 1000000000ULL, alarm);
>>>  }
>>>
>>> @@ -227,9 +234,10 @@ nvkm_therm_sensor_fini(struct nvkm_therm *therm, bool suspend)
>>>  void
>>>  nvkm_therm_sensor_preinit(struct nvkm_therm *therm)
>>>  {
>>> +     int val;
>>>       const char *sensor_avail = "yes";
>>>
>>> -     if (therm->func->temp_get(therm) < 0)
>>> +     if (therm->func->temp_get(therm, &val))
>>>               sensor_avail = "no";
>>>
>>>       nvkm_debug(&therm->subdev, "internal sensor: %s\n", sensor_avail);
>>>
>>
>> _______________________________________________
>> Nouveau mailing list
>> Nouveau@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/nouveau

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

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

* Re: [PATCH 03/32] therm: Split return code and value in nvkm_get_temp
       [not found]                 ` <9ff53665-3058-31a0-7020-bdbd6ba00f24-GANU6spQydw@public.gmane.org>
@ 2017-11-22 10:38                   ` Karol Herbst
  0 siblings, 0 replies; 41+ messages in thread
From: Karol Herbst @ 2017-11-22 10:38 UTC (permalink / raw)
  To: Martin Peres; +Cc: nouveau

On Wed, Nov 22, 2017 at 9:29 AM, Martin Peres <martin.peres@free.fr> wrote:
> On 22/11/17 03:42, Karol Herbst wrote:
>> On Wed, Nov 22, 2017 at 1:32 AM, Martin Peres <martin.peres@free.fr> wrote:
>>> On 17/11/17 02:04, Karol Herbst wrote:
>>>> The current hwmon code doesn't check if the returned value was actually an
>>>> error.
>>>>
>>>> Since Kepler temperature sensors are able to report negative values. Those
>>>> negative values are not for error reporting, but rather when you buried
>>>> your GPU in snow somewhere in Antarctica and still want a valid
>>>> temperature to be reported (unverified).
>>>>
>>>> Since Pascal (and maybe earlier) we have sensors with improved precision.
>>>>
>>>> Adjust the nvkm_get_temp method to be able to deal with those changes
>>>> and let hwmon return an error properly.
>>>
>>> Where did you get this information? And if it is the case, then we will
>>> royally screw up the value because we don't even know on how many bits
>>> 0x20400 uses...
>>>
>>> If you are indeed right, I would like to see g84.c's temp_get().
>>>
>>
>> Nvidia uses 0x020460 on Pascal and I thought we had that in envytools already?
>
> Nothing in nvbios.
>
>>
>> [0] 228.412618 MMIO32 R 0x020460 0x20002f20 PTHERM.I2C_SLAVE+0x60 => 0x20002f20
>> [0] 229.413039 MMIO32 R 0x020460 0x20002f10 PTHERM.I2C_SLAVE+0x60 => 0x20002f10
>> [0] 230.416976 MMIO32 R 0x020460 0x20002f68 PTHERM.I2C_SLAVE+0x60 => 0x20002f68
>> [0] 231.417407 MMIO32 R 0x020460 0x20002fe8 PTHERM.I2C_SLAVE+0x60 => 0x20002fe8
>> [0] 232.417742 MMIO32 R 0x020460 0x20002ff0 PTHERM.I2C_SLAVE+0x60 => 0x20002ff0
>> [0] 233.417742 MMIO32 R 0x020460 0x20003020 PTHERM.I2C_SLAVE+0x60 => 0x20003020
>>
>> or nvapeek 0x20400 && nvapeek 0x020460;
>> 00020400: 0000002c
>> 00020460: 20002c60
>
> Cool that they increased the accuracy, but where do you get that the
> value can be negative? And if it is, how many bits are used? 16 or more?
> What are those high bits?
>

I was asking rhyskidd to add stuff to rnndb, because he wrote the
nouveau patch for those sensors, check out for more details:
https://github.com/skeggsb/nouveau/blob/master/drm/nouveau/nvkm/subdev/therm/gp100.c#L27

regarding negative values, we have 0x02044c + 0x020450 for that and I
could imagine that 0x020460 can display negative values as well...
nobody tried for sure, but it seems plausible.

Anyway, moving from u8 to int should make life much easier for us if
we decide to really care about the higher precision. Currently our
code can't handle that for multiple reasons, but this solves one of
those at least.

>>
>>>>
>>>> Signed-off-by: Karol Herbst <karolherbst@gmail.com>
>>>> ---
>>>>  drm/nouveau/include/nvkm/subdev/clk.h   |  4 ++--
>>>>  drm/nouveau/include/nvkm/subdev/therm.h |  2 +-
>>>>  drm/nouveau/nouveau_hwmon.c             | 15 +++++++++------
>>>>  drm/nouveau/nvkm/subdev/clk/base.c      |  2 +-
>>>>  drm/nouveau/nvkm/subdev/therm/base.c    | 19 ++++++++++++++-----
>>>>  drm/nouveau/nvkm/subdev/therm/g84.c     | 13 ++++++++-----
>>>>  drm/nouveau/nvkm/subdev/therm/gp100.c   |  9 +++++----
>>>>  drm/nouveau/nvkm/subdev/therm/nv40.c    |  9 +++------
>>>>  drm/nouveau/nvkm/subdev/therm/nv50.c    |  9 +++------
>>>>  drm/nouveau/nvkm/subdev/therm/priv.h    |  4 ++--
>>>>  drm/nouveau/nvkm/subdev/therm/temp.c    | 16 ++++++++++++----
>>>>  11 files changed, 60 insertions(+), 42 deletions(-)
>>>>
>>>> diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
>>>> index e5275f74..506f8cc6 100644
>>>> --- a/drm/nouveau/include/nvkm/subdev/clk.h
>>>> +++ b/drm/nouveau/include/nvkm/subdev/clk.h
>>>> @@ -100,7 +100,7 @@ struct nvkm_clk {
>>>>       int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
>>>>       int astate; /* perfmon adjustment (base) */
>>>>       int dstate; /* display adjustment (min+) */
>>>> -     u8  temp;
>>>> +     int temp;
>>>>
>>>>       bool allow_reclock;
>>>>  #define NVKM_CLK_BOOST_NONE 0x0
>>>> @@ -122,7 +122,7 @@ 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 *, u8 temperature);
>>>> +int nvkm_clk_tstate(struct nvkm_clk *, int temperature);
>>>>
>>>>  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/include/nvkm/subdev/therm.h b/drm/nouveau/include/nvkm/subdev/therm.h
>>>> index 9841f076..8c84017f 100644
>>>> --- a/drm/nouveau/include/nvkm/subdev/therm.h
>>>> +++ b/drm/nouveau/include/nvkm/subdev/therm.h
>>>> @@ -86,7 +86,7 @@ struct nvkm_therm {
>>>>       int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
>>>>  };
>>>>
>>>> -int nvkm_therm_temp_get(struct nvkm_therm *);
>>>> +int nvkm_therm_temp_get(struct nvkm_therm *, int *);
>>>>  int nvkm_therm_fan_sense(struct nvkm_therm *);
>>>>  int nvkm_therm_cstate(struct nvkm_therm *, int, int);
>>>>
>>>> diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
>>>> index 7c965648..7486e4af 100644
>>>> --- a/drm/nouveau/nouveau_hwmon.c
>>>> +++ b/drm/nouveau/nouveau_hwmon.c
>>>> @@ -326,8 +326,9 @@ nouveau_temp_is_visible(const void *data, u32 attr, int channel)
>>>>  {
>>>>       struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>>>>       struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
>>>> +     int val;
>>>>
>>>> -     if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
>>>> +     if (therm && therm->attr_get && nvkm_therm_temp_get(therm, &val))
>>>>               return 0;
>>>>
>>>>       switch (attr) {
>>>> @@ -421,15 +422,16 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
>>>>       struct drm_device *drm_dev = dev_get_drvdata(dev);
>>>>       struct nouveau_drm *drm = nouveau_drm(drm_dev);
>>>>       struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
>>>> -     int ret;
>>>> +     int ret = 0;
>>>> +     int temp;
>>>>
>>>>       if (!therm || !therm->attr_get)
>>>>               return -EOPNOTSUPP;
>>>>
>>>>       switch (attr) {
>>>>       case hwmon_temp_input:
>>>> -             ret = nvkm_therm_temp_get(therm);
>>>> -             *val = ret < 0 ? ret : (ret * 1000);
>>>> +             ret = nvkm_therm_temp_get(therm, &temp);
>>>> +             *val = temp * 1000;
>>>>               break;
>>>>       case hwmon_temp_max:
>>>>               *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK)
>>>> @@ -459,7 +461,7 @@ nouveau_temp_read(struct device *dev, u32 attr, int channel, long *val)
>>>>               return -EOPNOTSUPP;
>>>>       }
>>>>
>>>> -     return 0;
>>>> +     return ret;
>>>>  }
>>>>
>>>>  static int
>>>> @@ -713,6 +715,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>>>>       struct device *hwmon_dev;
>>>>       int ret = 0;
>>>>       int i = 0;
>>>> +     int val;
>>>>
>>>>       hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
>>>>       if (!hwmon)
>>>> @@ -720,7 +723,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>>>>       hwmon->dev = dev;
>>>>
>>>>       if (therm && therm->attr_get && therm->attr_set) {
>>>> -             if (nvkm_therm_temp_get(therm) >= 0)
>>>> +             if (!nvkm_therm_temp_get(therm, &val))
>>>>                       special_groups[i++] = &temp1_auto_point_sensor_group;
>>>>               if (therm->fan_get && therm->fan_get(therm) >= 0)
>>>>                       special_groups[i++] = &pwm_fan_sensor_group;
>>>> diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
>>>> index e4c8d310..0b28dbb9 100644
>>>> --- a/drm/nouveau/nvkm/subdev/clk/base.c
>>>> +++ b/drm/nouveau/nvkm/subdev/clk/base.c
>>>> @@ -540,7 +540,7 @@ nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
>>>>  }
>>>>
>>>>  int
>>>> -nvkm_clk_tstate(struct nvkm_clk *clk, u8 temp)
>>>> +nvkm_clk_tstate(struct nvkm_clk *clk, int temp)
>>>>  {
>>>>       if (clk->temp == temp)
>>>>               return 0;
>>>> diff --git a/drm/nouveau/nvkm/subdev/therm/base.c b/drm/nouveau/nvkm/subdev/therm/base.c
>>>> index f27fc6d0..8e5f6f7f 100644
>>>> --- a/drm/nouveau/nvkm/subdev/therm/base.c
>>>> +++ b/drm/nouveau/nvkm/subdev/therm/base.c
>>>> @@ -24,22 +24,26 @@
>>>>  #include "priv.h"
>>>>
>>>>  int
>>>> -nvkm_therm_temp_get(struct nvkm_therm *therm)
>>>> +nvkm_therm_temp_get(struct nvkm_therm *therm, int *val)
>>>>  {
>>>>       if (therm->func->temp_get)
>>>> -             return therm->func->temp_get(therm);
>>>> +             return therm->func->temp_get(therm, val);
>>>>       return -ENODEV;
>>>>  }
>>>>
>>>>  static int
>>>>  nvkm_therm_update_trip(struct nvkm_therm *therm)
>>>>  {
>>>> +     int temp, ret;
>>>>       struct nvbios_therm_trip_point *trip = therm->fan->bios.trip,
>>>>                                      *cur_trip = NULL,
>>>>                                      *last_trip = therm->last_trip;
>>>> -     u8  temp = therm->func->temp_get(therm);
>>>>       u16 duty, i;
>>>>
>>>> +     ret = therm->func->temp_get(therm, &temp);
>>>> +     if (ret < 0)
>>>> +             return ret;
>>>> +
>>>>       /* look for the trip point corresponding to the current temperature */
>>>>       cur_trip = NULL;
>>>>       for (i = 0; i < therm->fan->bios.nr_fan_trip; i++) {
>>>> @@ -67,9 +71,13 @@ static int
>>>>  nvkm_therm_compute_linear_duty(struct nvkm_therm *therm, u8 linear_min_temp,
>>>>                                 u8 linear_max_temp)
>>>>  {
>>>> -     u8  temp = therm->func->temp_get(therm);
>>>> +     int temp, ret;
>>>>       u16 duty;
>>>>
>>>> +     ret = therm->func->temp_get(therm, &temp);
>>>> +     if (ret < 0)
>>>> +             return ret;
>>>> +
>>>>       /* handle the non-linear part first */
>>>>       if (temp < linear_min_temp)
>>>>               return therm->fan->bios.min_duty;
>>>> @@ -182,6 +190,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
>>>>  {
>>>>       struct nvkm_subdev *subdev = &therm->subdev;
>>>>       struct nvkm_device *device = subdev->device;
>>>> +     int val;
>>>>       static const char *name[] = {
>>>>               "disabled",
>>>>               "manual",
>>>> @@ -197,7 +206,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
>>>>       /* do not allow automatic fan management if the thermal sensor is
>>>>        * not available */
>>>>       if (mode == NVKM_THERM_CTRL_AUTO &&
>>>> -         therm->func->temp_get(therm) < 0)
>>>> +         therm->func->temp_get(therm, &val))
>>>>               return -EINVAL;
>>>>
>>>>       if (therm->mode == mode)
>>>> diff --git a/drm/nouveau/nvkm/subdev/therm/g84.c b/drm/nouveau/nvkm/subdev/therm/g84.c
>>>> index 96f8da40..81c0bda8 100644
>>>> --- a/drm/nouveau/nvkm/subdev/therm/g84.c
>>>> +++ b/drm/nouveau/nvkm/subdev/therm/g84.c
>>>> @@ -27,14 +27,15 @@
>>>>  #include <subdev/fuse.h>
>>>>
>>>>  int
>>>> -g84_temp_get(struct nvkm_therm *therm)
>>>> +g84_temp_get(struct nvkm_therm *therm, int *val)
>>>>  {
>>>>       struct nvkm_device *device = therm->subdev.device;
>>>>
>>>> -     if (nvkm_fuse_read(device->fuse, 0x1a8) == 1)
>>>> -             return nvkm_rd32(device, 0x20400);
>>>> -     else
>>>> +     if (nvkm_fuse_read(device->fuse, 0x1a8) != 1)
>>>>               return -ENODEV;
>>>> +
>>>> +     *val = nvkm_rd32(device, 0x20400);
>>>> +     return 0;
>>>>  }
>>>>
>>>>  void
>>>> @@ -114,8 +115,10 @@ g84_therm_threshold_hyst_emulation(struct nvkm_therm *therm,
>>>>               new_state = NVKM_THERM_THRS_LOWER;
>>>>       }
>>>>
>>>> +     if (therm->func->temp_get(therm, &cur))
>>>> +             return;
>>>> +
>>>>       /* fix the state (in case someone reprogrammed the alarms) */
>>>> -     cur = therm->func->temp_get(therm);
>>>>       if (new_state == NVKM_THERM_THRS_LOWER && cur > thrs->temp)
>>>>               new_state = NVKM_THERM_THRS_HIGHER;
>>>>       else if (new_state == NVKM_THERM_THRS_HIGHER &&
>>>> diff --git a/drm/nouveau/nvkm/subdev/therm/gp100.c b/drm/nouveau/nvkm/subdev/therm/gp100.c
>>>> index 9f0dea3f..d8206748 100644
>>>> --- a/drm/nouveau/nvkm/subdev/therm/gp100.c
>>>> +++ b/drm/nouveau/nvkm/subdev/therm/gp100.c
>>>> @@ -24,7 +24,7 @@
>>>>  #include "priv.h"
>>>>
>>>>  static int
>>>> -gp100_temp_get(struct nvkm_therm *therm)
>>>> +gp100_temp_get(struct nvkm_therm *therm, int *val)
>>>>  {
>>>>       struct nvkm_device *device = therm->subdev.device;
>>>>       struct nvkm_subdev *subdev = &therm->subdev;
>>>> @@ -36,9 +36,10 @@ gp100_temp_get(struct nvkm_therm *therm)
>>>>               nvkm_trace(subdev, "reading temperature from SHADOWed sensor\n");
>>>>
>>>>       /* device valid */
>>>> -     if (tsensor & 0x20000000)
>>>> -             return (inttemp >> 8);
>>>> -     else
>>>> +     if (tsensor & 0x20000000) {
>>>> +             *val = inttemp >> 8;
>>>> +             return 0;
>>>> +     } else
>>>>               return -ENODEV;
>>>>  }
>>>>
>>>> diff --git a/drm/nouveau/nvkm/subdev/therm/nv40.c b/drm/nouveau/nvkm/subdev/therm/nv40.c
>>>> index 2c92ffb5..cfd5b215 100644
>>>> --- a/drm/nouveau/nvkm/subdev/therm/nv40.c
>>>> +++ b/drm/nouveau/nvkm/subdev/therm/nv40.c
>>>> @@ -70,7 +70,7 @@ nv40_sensor_setup(struct nvkm_therm *therm)
>>>>  }
>>>>
>>>>  static int
>>>> -nv40_temp_get(struct nvkm_therm *therm)
>>>> +nv40_temp_get(struct nvkm_therm *therm, int *val)
>>>>  {
>>>>       struct nvkm_device *device = therm->subdev.device;
>>>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>>>> @@ -95,11 +95,8 @@ nv40_temp_get(struct nvkm_therm *therm)
>>>>       core_temp = core_temp + sensor->offset_num / sensor->offset_den;
>>>>       core_temp = core_temp + sensor->offset_constant - 8;
>>>>
>>>> -     /* reserve negative temperatures for errors */
>>>> -     if (core_temp < 0)
>>>> -             core_temp = 0;
>>>> -
>>>> -     return core_temp;
>>>> +     *val = core_temp;
>>>> +     return 0;
>>>>  }
>>>>
>>>>  static int
>>>> diff --git a/drm/nouveau/nvkm/subdev/therm/nv50.c b/drm/nouveau/nvkm/subdev/therm/nv50.c
>>>> index 9b57b433..62ec4063 100644
>>>> --- a/drm/nouveau/nvkm/subdev/therm/nv50.c
>>>> +++ b/drm/nouveau/nvkm/subdev/therm/nv50.c
>>>> @@ -126,7 +126,7 @@ nv50_sensor_setup(struct nvkm_therm *therm)
>>>>  }
>>>>
>>>>  static int
>>>> -nv50_temp_get(struct nvkm_therm *therm)
>>>> +nv50_temp_get(struct nvkm_therm *therm, int *val)
>>>>  {
>>>>       struct nvkm_device *device = therm->subdev.device;
>>>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>>>> @@ -143,11 +143,8 @@ nv50_temp_get(struct nvkm_therm *therm)
>>>>       core_temp = core_temp + sensor->offset_num / sensor->offset_den;
>>>>       core_temp = core_temp + sensor->offset_constant - 8;
>>>>
>>>> -     /* reserve negative temperatures for errors */
>>>> -     if (core_temp < 0)
>>>> -             core_temp = 0;
>>>> -
>>>> -     return core_temp;
>>>> +     *val = core_temp;
>>>> +     return 0;
>>>>  }
>>>>
>>>>  static void
>>>> diff --git a/drm/nouveau/nvkm/subdev/therm/priv.h b/drm/nouveau/nvkm/subdev/therm/priv.h
>>>> index 1f46e371..b325ec5f 100644
>>>> --- a/drm/nouveau/nvkm/subdev/therm/priv.h
>>>> +++ b/drm/nouveau/nvkm/subdev/therm/priv.h
>>>> @@ -91,7 +91,7 @@ struct nvkm_therm_func {
>>>>       int (*pwm_set)(struct nvkm_therm *, int line, u32, u32);
>>>>       int (*pwm_clock)(struct nvkm_therm *, int line);
>>>>
>>>> -     int (*temp_get)(struct nvkm_therm *);
>>>> +     int (*temp_get)(struct nvkm_therm *, int *);
>>>>
>>>>       int (*fan_sense)(struct nvkm_therm *);
>>>>
>>>> @@ -105,7 +105,7 @@ int  nv50_fan_pwm_get(struct nvkm_therm *, int, u32 *, u32 *);
>>>>  int  nv50_fan_pwm_set(struct nvkm_therm *, int, u32, u32);
>>>>  int  nv50_fan_pwm_clock(struct nvkm_therm *, int);
>>>>
>>>> -int  g84_temp_get(struct nvkm_therm *);
>>>> +int  g84_temp_get(struct nvkm_therm *, int *);
>>>>  void g84_sensor_setup(struct nvkm_therm *);
>>>>  void g84_therm_fini(struct nvkm_therm *);
>>>>
>>>> diff --git a/drm/nouveau/nvkm/subdev/therm/temp.c b/drm/nouveau/nvkm/subdev/therm/temp.c
>>>> index ddb2b2c6..e7b8cbe2 100644
>>>> --- a/drm/nouveau/nvkm/subdev/therm/temp.c
>>>> +++ b/drm/nouveau/nvkm/subdev/therm/temp.c
>>>> @@ -86,7 +86,10 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
>>>>       static const char * const thresholds[] = {
>>>>               "fanboost", "downclock", "critical", "shutdown"
>>>>       };
>>>> -     int temperature = therm->func->temp_get(therm);
>>>> +     int temperature;
>>>> +
>>>> +     if (therm->func->temp_get(therm, &temperature))
>>>> +             return;
>>>>
>>>>       if (thrs < 0 || thrs > 3)
>>>>               return;
>>>> @@ -140,7 +143,10 @@ nvkm_therm_threshold_hyst_polling(struct nvkm_therm *therm,
>>>>  {
>>>>       enum nvkm_therm_thrs_direction direction;
>>>>       enum nvkm_therm_thrs_state prev_state, new_state;
>>>> -     int temp = therm->func->temp_get(therm);
>>>> +     int temp;
>>>> +
>>>> +     if (therm->func->temp_get(therm, &temp))
>>>> +             return;
>>>>
>>>>       prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name);
>>>>
>>>> @@ -166,6 +172,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
>>>>       struct nvbios_therm_sensor *sensor = &therm->bios_sensor;
>>>>       struct nvkm_timer *tmr = therm->subdev.device->timer;
>>>>       unsigned long flags;
>>>> +     int val;
>>>>
>>>>       spin_lock_irqsave(&therm->sensor.alarm_program_lock, flags);
>>>>
>>>> @@ -185,7 +192,7 @@ alarm_timer_callback(struct nvkm_alarm *alarm)
>>>>       spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags);
>>>>
>>>>       /* schedule the next poll in one second */
>>>> -     if (therm->func->temp_get(therm) >= 0)
>>>> +     if (!therm->func->temp_get(therm, &val))
>>>>               nvkm_timer_alarm(tmr, 1000000000ULL, alarm);
>>>>  }
>>>>
>>>> @@ -227,9 +234,10 @@ nvkm_therm_sensor_fini(struct nvkm_therm *therm, bool suspend)
>>>>  void
>>>>  nvkm_therm_sensor_preinit(struct nvkm_therm *therm)
>>>>  {
>>>> +     int val;
>>>>       const char *sensor_avail = "yes";
>>>>
>>>> -     if (therm->func->temp_get(therm) < 0)
>>>> +     if (therm->func->temp_get(therm, &val))
>>>>               sensor_avail = "no";
>>>>
>>>>       nvkm_debug(&therm->subdev, "internal sensor: %s\n", sensor_avail);
>>>>
>>>
>>> _______________________________________________
>>> Nouveau mailing list
>>> Nouveau@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/nouveau
>
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

end of thread, other threads:[~2017-11-22 10:38 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-17  0:04 [PATCH 00/32] Updated State of my clk patches Karol Herbst
     [not found] ` <20171117000436.2432-1-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-11-17  0:04   ` [PATCH 01/32] bios/vpstate: There are some fermi vbios with no boost or tdp entry Karol Herbst
     [not found]     ` <20171117000436.2432-2-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-11-22  0:16       ` Martin Peres
     [not found]         ` <6fd6503a-0d97-9148-0ebf-cba6f8bb0180-GANU6spQydw@public.gmane.org>
2017-11-22  1:33           ` Karol Herbst
2017-11-17  0:04   ` [PATCH 02/32] debugfs: Wake up GPU before doing any reclocking Karol Herbst
     [not found]     ` <20171117000436.2432-3-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-11-22  0:21       ` Martin Peres
     [not found]         ` <b719fba2-3f0f-298e-a816-5992b587b293-GANU6spQydw@public.gmane.org>
2017-11-22  1:38           ` Karol Herbst
2017-11-17  0:04   ` [PATCH 03/32] therm: Split return code and value in nvkm_get_temp Karol Herbst
     [not found]     ` <20171117000436.2432-4-karolherbst-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-11-22  0:32       ` Martin Peres
     [not found]         ` <e6b18baa-46d5-0ff0-bd55-c5255d22e770-GANU6spQydw@public.gmane.org>
2017-11-22  1:42           ` Karol Herbst
     [not found]             ` <CACO55tvzR_iQqQY4SoECbq3MN1Tax-znrTBQsntYsGzjXGTMHg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-11-22  8:29               ` Martin Peres
     [not found]                 ` <9ff53665-3058-31a0-7020-bdbd6ba00f24-GANU6spQydw@public.gmane.org>
2017-11-22 10:38                   ` Karol Herbst
2017-11-17  0:04   ` [PATCH 04/32] hwmon: Properly check for errors Karol Herbst
2017-11-17  0:04   ` [PATCH 05/32] clk: Improve names of pstate/cstate related variables and fields Karol Herbst
2017-11-17  0:04   ` [PATCH 06/32] clk: Add NVKM_CLK_PSTATE_BOOT Karol Herbst
2017-11-17  0:04   ` [PATCH 07/32] clk: Rename NVKM_CLK_CSTATE_HIGHEST to NVKM_CLK_CSTATE_AUTO Karol Herbst
2017-11-17  0:04   ` [PATCH 08/32] clk: Rename nvkm_clk.states to pstates Karol Herbst
2017-11-17  0:04   ` [PATCH 09/32] clk: Rename nvkm_pstate.list to cstates Karol Herbst
2017-11-17  0:04   ` [PATCH 10/32] clk: Remove dstate Karol Herbst
2017-11-17  0:04   ` [PATCH 11/32] clk: Rename nvkm_pstate_calc to nvkm_clk_update and export it Karol Herbst
2017-11-17  0:04   ` [PATCH 12/32] clk: Use list_for_each_entry_from_reverse in nvkm_cstate_find_best Karol Herbst
2017-11-17  0:04   ` [PATCH 13/32] clk: We should pass the pstate id around not the index in the list Karol Herbst
2017-11-17  0:04   ` [PATCH 14/32] clk: Hold information about the current cstate status Karol Herbst
2017-11-17  0:04   ` [PATCH 15/32] clk: Refactor the base and boost clock limits so that we can limit pstates Karol Herbst
2017-11-17  0:04   ` [PATCH 16/32] therm: Move the temp readout into nvkm_therm_update Karol Herbst
2017-11-17  0:04   ` [PATCH 17/32] core/device: Move therm behind clk Karol Herbst
2017-11-17  0:04   ` [PATCH 18/32] therm: Trigger reclock in temperature daemon Karol Herbst
2017-11-17  0:04   ` [PATCH 19/32] bios: Add thermal policies table Karol Herbst
2017-11-17  0:04   ` [PATCH 20/32] therm: Cancel the timer only in fini Karol Herbst
2017-11-17  0:04   ` [PATCH 21/32] clk: Parse thermal policies for throttling thresholds Karol Herbst
2017-11-17  0:04   ` [PATCH 22/32] clk: Thermal throttling Karol Herbst
2017-11-17  0:04   ` [PATCH 23/32] clk: Skip unchanging parts of the reclock Karol Herbst
2017-11-17  0:04   ` [PATCH 24/32] clk: Save the max clock we can set Karol Herbst
2017-11-17  0:04   ` [PATCH 25/32] nvif: Add boost info and set operations Karol Herbst
2017-11-17  0:04   ` [PATCH 26/32] debugfs: Add boost interface to change the boost_mode Karol Herbst
2017-11-17  0:04   ` [PATCH 27/32] bios/vpstate: Parse max battery id Karol Herbst
2017-11-17  0:04   ` [PATCH 28/32] clk: Implement limiting pstates just like we do for cstates Karol Herbst
2017-11-17  0:04   ` [PATCH 29/32] clk: Limit clocks on battery Karol Herbst
2017-11-17  0:04   ` [PATCH 30/32] secboot/acr352: Reset PMU after secboot Karol Herbst
2017-11-17  0:04   ` [PATCH 31/32] device: Enable clk for Maxwell2 Karol Herbst
2017-11-17  0:04   ` [PATCH 32/32] clk: Add trace message when setting a new cstate 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.