[v4,11/37] volt: add temperature parameter to nvkm_volt_map

Submitted by Karol Herbst on April 18, 2016, 7:13 p.m.

Details

Message ID 1461006851-5007-12-git-send-email-nouveau@karolherbst.de
State New
Headers show
Series "Volting/Clocking improvements for Fermi and newer" ( rev: 4 ) in Nouveau

Not browsing as part of any series.

Commit Message

Karol Herbst April 18, 2016, 7:13 p.m.
the voltage entries actually may map to a different voltage depending on the
current temperature.

v2: only read the temperatue when actually needed

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

Patch hide | download patch | download mbox

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

Comments

On 18/04/16 22:13, Karol Herbst wrote:
> the voltage entries actually may map to a different voltage depending on the
> current temperature.
>
> v2: only read the temperatue when actually needed
temperatue -> temperature
>
> Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
> ---
>   bin/nv_cmp_volt.c                      |  2 +-
>   drm/nouveau/include/nvkm/subdev/volt.h |  2 +-
>   drm/nouveau/nvkm/subdev/volt/base.c    | 14 ++++++++++----
>   3 files changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/bin/nv_cmp_volt.c b/bin/nv_cmp_volt.c
> index c63d91b..34147b9 100644
> --- a/bin/nv_cmp_volt.c
> +++ b/bin/nv_cmp_volt.c
> @@ -117,7 +117,7 @@ main(int argc, char **argv)
>   
>   		new_voltage = nvkm_volt_get(volt);
>   		new_temp = nvkm_rd32(device, 0x20400);//nvkm_therm_temp_get(therm);
> -		new_nouveau_voltage = max(nvkm_volt_map(volt, best_cstate->voltage), nvkm_volt_map(volt, best_pstate->base.voltage));
> +		new_nouveau_voltage = max(nvkm_volt_map(volt, best_cstate->voltage, new_temp), nvkm_volt_map(volt, best_pstate->base.voltage, new_temp));
>   		new_pstate = best_pstate->pstate;
>   		new_cstate = best_cstate->cstate;
>   
> diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h
> index 870d212..f223577 100644
> --- a/drm/nouveau/include/nvkm/subdev/volt.h
> +++ b/drm/nouveau/include/nvkm/subdev/volt.h
> @@ -22,7 +22,7 @@ struct nvkm_volt {
>   	u8 max2_id;
>   };
>   
> -int nvkm_volt_map(struct nvkm_volt *volt, u8 id);
> +int nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temperature);
>   int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
>   int nvkm_volt_get(struct nvkm_volt *);
>   int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, int condition);
> diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
> index 6fb9d2e..d72bd4a 100644
> --- a/drm/nouveau/nvkm/subdev/volt/base.c
> +++ b/drm/nouveau/nvkm/subdev/volt/base.c
> @@ -26,6 +26,7 @@
>   #include <subdev/bios.h>
>   #include <subdev/bios/vmap.h>
>   #include <subdev/bios/volt.h>
> +#include <subdev/therm.h>
>   
>   int
>   nvkm_volt_get(struct nvkm_volt *volt)
> @@ -88,7 +89,7 @@ nvkm_volt_map_min(struct nvkm_volt *volt, u8 id)
>   }
>   
>   int
> -nvkm_volt_map(struct nvkm_volt *volt, u8 id)
> +nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
>   {
>   	struct nvkm_bios *bios = volt->subdev.device->bios;
>   	struct nvbios_vmap_entry info;
> @@ -98,7 +99,7 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
>   	vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
>   	if (vmap) {
>   		if (info.link != 0xff) {
> -			int ret = nvkm_volt_map(volt, info.link);
> +			int ret = nvkm_volt_map(volt, info.link, temp);
>   			if (ret < 0)
>   				return ret;
>   			info.min += ret;
> @@ -112,18 +113,23 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id)
>   int
>   nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, u8 min_id, int condition)
>   {
> +	struct nvkm_therm *therm = volt->subdev.device->therm;
>   	int ret;

/* Set the default temperature to 0°C as it always produces the
  * highest possible voltage which is the safest from a stability point of
  * view. This may be overridden later if the temperature can be read.
  */

> +	int temp = 0;
>   
>   	if (volt->func->set_id)
>   		return volt->func->set_id(volt, id, condition);
>   
> -	ret = nvkm_volt_map(volt, id);
> +	if (therm)
> +		temp = nvkm_therm_temp_get(therm);
temp = max(0, nvkm_therm_temp_get(therm));
> +
> +	ret = nvkm_volt_map(volt, id, max(temp, 0));
s/max(temp, 0)/temp/g
>   	if (ret >= 0) {
>   		int prev = nvkm_volt_get(volt);
>   		if (!condition || prev < 0 ||
>   		    (condition < 0 && ret < prev) ||
>   		    (condition > 0 && ret > prev)) {
> -			int min = nvkm_volt_map(volt, min_id);
> +			int min = nvkm_volt_map(volt, min_id, max(temp, 0));
s/max(temp, 0)/temp/g
>   			if (min >= 0)
>   				ret = max(min, ret);
>   			ret = nvkm_volt_set(volt, ret);

With the commit message and the max() duplication fixed, this is:

Reviewed-by: Martin Peres <martin.peres@free.fr>