Karol Herbst
2016-Mar-16 17:40 UTC
[Nouveau] [PATCH 0/2] Fix some VID parsing in the voltage table version 0x50
On a very few GPUs with the voltage table version 0x50 we have to read out the VIDs out of the entries of the table, where all the other gpus are either PWM based or get a base and a step voltage out of the table header. Currently nouveau tried to autodetect this and actually doesn't parse the entries. This Series adds two things: 1. It parses the entries 2. It decides upon a field in the voltage table to either use the base+step or entries approach This fixes volting on some GPUs Karol Herbst (2): bios/volt: handle voltage table version 0x50 with 0ed header volt: properly detect entry based voltage tables drm/nouveau/include/nvkm/subdev/bios/volt.h | 5 +++-- drm/nouveau/nvkm/subdev/bios/volt.c | 16 ++++++++++------ drm/nouveau/nvkm/subdev/volt/base.c | 7 +++++-- 3 files changed, 18 insertions(+), 10 deletions(-) -- 2.7.3
Karol Herbst
2016-Mar-16 17:40 UTC
[Nouveau] [PATCH 1/2] bios/volt: handle voltage table version 0x50 with 0ed header
Some Kepler cards have no usefull header in the voltage table, which means nouveau has to read the voltages out of the entries directly. The mask may be bigger than 0x1fffff, but this value is already >2V, so it will be fine for now. This patch fixes volting issues on those cards enabling them to switch cstates Signed-off-by: Karol Herbst <nouveau at karolherbst.de> --- drm/nouveau/nvkm/subdev/bios/volt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drm/nouveau/nvkm/subdev/bios/volt.c b/drm/nouveau/nvkm/subdev/bios/volt.c index 6e0a336..81a47b2 100644 --- a/drm/nouveau/nvkm/subdev/bios/volt.c +++ b/drm/nouveau/nvkm/subdev/bios/volt.c @@ -142,7 +142,10 @@ nvbios_volt_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len, info->vid = nvbios_rd08(bios, volt + 0x01) >> 2; break; case 0x40: + break; case 0x50: + info->voltage = nvbios_rd32(bios, volt) & 0x001fffff; + info->vid = (nvbios_rd32(bios, volt) >> 23) & 0xff; break; } return volt; -- 2.7.3
Karol Herbst
2016-Mar-16 17:40 UTC
[Nouveau] [PATCH 2/2] volt: properly detect entry based voltage tables
there is a field in the voltage table which tells us if the VIDs are taken from the entries or calculated through the header Signed-off-by: Karol Herbst <nouveau at karolherbst.de> --- drm/nouveau/include/nvkm/subdev/bios/volt.h | 5 +++-- drm/nouveau/nvkm/subdev/bios/volt.c | 13 +++++++------ drm/nouveau/nvkm/subdev/volt/base.c | 7 +++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drm/nouveau/include/nvkm/subdev/bios/volt.h b/drm/nouveau/include/nvkm/subdev/bios/volt.h index b0df610..0d91c24 100644 --- a/drm/nouveau/include/nvkm/subdev/bios/volt.h +++ b/drm/nouveau/include/nvkm/subdev/bios/volt.h @@ -13,8 +13,9 @@ struct nvbios_volt { u32 base; /* GPIO mode */ - u8 vidmask; - s16 step; + bool entry_based; + u8 vidmask; + s16 step; /* PWM mode */ u32 pwm_freq; diff --git a/drm/nouveau/nvkm/subdev/bios/volt.c b/drm/nouveau/nvkm/subdev/bios/volt.c index 81a47b2..ad1313b 100644 --- a/drm/nouveau/nvkm/subdev/bios/volt.c +++ b/drm/nouveau/nvkm/subdev/bios/volt.c @@ -100,13 +100,14 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, /* offset 4 seems to be a flag byte */ if (nvbios_rd32(bios, volt + 0x4) & 1) { - info->type = NVBIOS_VOLT_PWM; - info->pwm_freq = nvbios_rd32(bios, volt + 0x5) / 1000; - info->pwm_range = nvbios_rd32(bios, volt + 0x16); + info->type = NVBIOS_VOLT_PWM; + info->pwm_freq = nvbios_rd32(bios, volt + 0x5) / 1000; + info->pwm_range = nvbios_rd32(bios, volt + 0x16); } else { - info->type = NVBIOS_VOLT_GPIO; - info->vidmask = nvbios_rd08(bios, volt + 0x06); - info->step = nvbios_rd16(bios, volt + 0x16); + info->type = NVBIOS_VOLT_GPIO; + info->vidmask = nvbios_rd08(bios, volt + 0x06); + info->step = nvbios_rd16(bios, volt + 0x16); + info->entry_based = !(nvbios_rd08(bios, volt + 0x4) & 0x2); } break; } diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c index 50b5649..4653f3f 100644 --- a/drm/nouveau/nvkm/subdev/volt/base.c +++ b/drm/nouveau/nvkm/subdev/volt/base.c @@ -112,6 +112,7 @@ nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition) static void nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) { + struct nvkm_subdev *subdev = &bios->subdev; struct nvbios_volt_entry ivid; struct nvbios_volt info; u8 ver, hdr, cnt, len; @@ -119,7 +120,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) int i; data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info); - if (data && info.vidmask && info.base && info.step) { + if (data && info.vidmask && info.base && info.step && !info.entry_based) { + nvkm_debug(subdev, "found header based VIDs\n"); for (i = 0; i < info.vidmask + 1; i++) { if (info.base >= info.min && info.base <= info.max) { @@ -130,7 +132,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) info.base += info.step; } volt->vid_mask = info.vidmask; - } else if (data && info.vidmask) { + } else if (data && info.vidmask && info.entry_based) { + nvkm_debug(subdev, "found entry based VIDs\n"); for (i = 0; i < cnt; i++) { data = nvbios_volt_entry_parse(bios, i, &ver, &hdr, &ivid); -- 2.7.3
Apparently Analagous Threads
- [PATCH v2 2/2] volt: properly detect entry based voltage tables
- [PATCH 00/19] Volting/Clocking improvements for Fermi and newer
- [PATCH v2 00/22] Volting/Clocking improvements for Fermi and newer
- [PATCH v3 00/29] Volting/Clocking improvements for Fermi and newer
- [PATCH v5 00/20] Engine Reclocking Fixes for Fermi-Maxwell2