[Nouveau] [PATCH 19/19] volt: add coefficients I found on my gpu
Karol Herbst
nouveau at karolherbst.de
Thu Mar 17 23:03:56 UTC 2016
I am sure that those are a bit different on other GPUs, but while testing
the error range compared to nvidia was around 100%+-3%.
Without this change we are most of the time around 10% below nvidias voltage,
so this change causes no harm and improves the situation a lot already.
The remaining task for this is to figure out which of these constants are
chip specific and from where to get the chip specific factors
Signed-off-by: Karol Herbst <nouveau at karolherbst.de>
---
drm/nouveau/nvkm/subdev/volt/base.c | 54 ++++++++++++++++++++++++++++++++-----
1 file changed, 48 insertions(+), 6 deletions(-)
diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c
index 58738e3..2b3f460 100644
--- a/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drm/nouveau/nvkm/subdev/volt/base.c
@@ -117,13 +117,55 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp)
vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
if (vmap) {
- if (info.link != 0xff) {
- int ret = nvkm_volt_map(volt, info.link, temp);
- if (ret < 0)
- return ret;
- info.min += ret;
+ switch (ver) {
+ case 0x10:
+ if (info.link != 0xff) {
+ int ret = nvkm_volt_map(volt, info.link, temp);
+ if (ret < 0)
+ return ret;
+ info.min += ret;
+ }
+ return info.min;
+ case 0x20: {
+ s32 result;
+ u16 temp = 40;
+ switch (info.mode) {
+ case 0x0:
+ result = info.arg[0] / 10;
+ result += info.arg[1] * 168;
+ result += info.arg[2] * 28;
+ break;
+ case 0x1:
+ result = (info.arg[0] / 1675) * 100;
+ result += info.arg[1] * 100;
+ result += (info.arg[2] / 10) * 153 * temp;
+ result += info.arg[3] * 100 * temp;
+ result += info.arg[4] * 41;
+ result += (info.arg[5] * (temp * temp)) / 15;
+ break;
+ case 0x3:
+ result = (info.min + info.max) / 2;
+ break;
+ case 0x2:
+ default:
+ result = info.min;
+ break;
+ }
+ result = min(max(result, (s32)info.min),
+ (s32)info.max);
+
+ if (info.link != 0xff) {
+ int ret = nvkm_volt_map(volt, info.link, temp);
+ if (ret < 0)
+ return ret;
+ result += ret;
+ }
+
+ return result;
+ }
+ default:
+ return -ENODEV;
}
- return info.min;
}
return id ? id * 10000 : -ENODEV;
--
2.7.3
More information about the Nouveau
mailing list