[v4,06/37] volt: parse the max voltage map entries

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

Details

Message ID 1461006851-5007-7-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.
There are at least three "max" entries, which specify the max voltage. Because
they are actually normal voltage map entries, they can also be affected by the
temperature.

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

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

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

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

Patch hide | download patch | download mbox

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

Comments

On 18/04/16 22:13, Karol Herbst wrote:
> There are at least three "max" entries, which specify the max voltage. Because
> they are actually normal voltage map entries, they can also be affected by the
> temperature.
>
> Nvidia respects those entries and if they get changed, nvidia uses the lower
> voltage from both.
both ;) I guess it is time to update this to: from the three of them.
>
> We shouldn't exceed those voltages at any given time.
>
> v2: state what those entries do in the source
> v3: add the third max entry
>
> Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
> ---
>   drm/nouveau/include/nvkm/subdev/bios/vmap.h |  3 +++
>   drm/nouveau/include/nvkm/subdev/volt.h      |  5 +++++
>   drm/nouveau/nvkm/subdev/bios/vmap.c         | 10 ++++++++++
>   drm/nouveau/nvkm/subdev/volt/base.c         | 13 +++++++++++++
>   4 files changed, 31 insertions(+)
>
> diff --git a/drm/nouveau/include/nvkm/subdev/bios/vmap.h b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
> index 6633c6d..ae2f27b 100644
> --- a/drm/nouveau/include/nvkm/subdev/bios/vmap.h
> +++ b/drm/nouveau/include/nvkm/subdev/bios/vmap.h
> @@ -1,6 +1,9 @@
>   #ifndef __NVBIOS_VMAP_H__
>   #define __NVBIOS_VMAP_H__
>   struct nvbios_vmap {
> +	u8  max0;
> +	u8  max1;
> +	u8  max2;
>   };
>   
>   u16 nvbios_vmap_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
> diff --git a/drm/nouveau/include/nvkm/subdev/volt.h b/drm/nouveau/include/nvkm/subdev/volt.h
> index fc68825..285c6bf 100644
> --- a/drm/nouveau/include/nvkm/subdev/volt.h
> +++ b/drm/nouveau/include/nvkm/subdev/volt.h
> @@ -15,6 +15,11 @@ struct nvkm_volt {
>   
>   	u32 max_uv;
>   	u32 min_uv;
> +
> +	/* max voltage map entries, might be affected by temperature */

might be affected *differently* by temperature.

> +	u8 max0_id;
> +	u8 max1_id;
> +	u8 max2_id;
>   };
>   
>   int nvkm_volt_map_min(struct nvkm_volt *volt, u8 id);
> diff --git a/drm/nouveau/nvkm/subdev/bios/vmap.c b/drm/nouveau/nvkm/subdev/bios/vmap.c
> index 2f13db7..f2295e1 100644
> --- a/drm/nouveau/nvkm/subdev/bios/vmap.c
> +++ b/drm/nouveau/nvkm/subdev/bios/vmap.c
> @@ -61,7 +61,17 @@ nvbios_vmap_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
>   	memset(info, 0x00, sizeof(*info));
>   	switch (!!vmap * *ver) {
>   	case 0x10:
> +		info->max0 = 0xff;
> +		info->max1 = 0xff;
> +		info->max2 = 0xff;
> +		break;
>   	case 0x20:
> +		info->max0 = nvbios_rd08(bios, vmap + 0x7);
> +		info->max1 = nvbios_rd08(bios, vmap + 0x8);
> +		if (*len >= 0xc)
> +			info->max2 = nvbios_rd08(bios, vmap + 0xc);
> +		else
> +			info->max2 = 0xff;
>   		break;
>   	}
>   	return vmap;
> diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
> index ecf4cb4..63fffb8 100644
> --- a/drm/nouveau/nvkm/subdev/volt/base.c
> +++ b/drm/nouveau/nvkm/subdev/volt/base.c
> @@ -217,9 +217,22 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct nvkm_device *device,
>   
>   	/* Assuming the non-bios device should build the voltage table later */
>   	if (bios) {
> +		u8 ver, hdr, cnt, len;
> +		struct nvbios_vmap vmap;
> +
>   		nvkm_volt_parse_bios(bios, volt);
>   		nvkm_debug(&volt->subdev, "min: %iuv max: %iuv\n",
>   			   volt->min_uv, volt->max_uv);
> +
> +		if (nvbios_vmap_parse(bios, &ver, &hdr, &cnt, &len, &vmap)) {
> +			volt->max0_id = vmap.max0;
> +			volt->max1_id = vmap.max1;
> +			volt->max2_id = vmap.max2;
> +		} else {
> +			volt->max0_id = 0xff;
> +			volt->max1_id = 0xff;
> +			volt->max2_id = 0xff;
> +		}
>   	}
>   
>   	if (volt->vid_nr) {

With the comment and commit message fixed:

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