if we calculate the voltage in the table right, we get all kinds of values, which never fit the hardware steps, so we use the closest higher value the hardware can do.
v3: simplify the implementation Signed-off-by: Karol Herbst <nouv...@karolherbst.de> --- drm/nouveau/nvkm/subdev/volt/base.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c index d72bd4a..028c6e2 100644 --- a/drm/nouveau/nvkm/subdev/volt/base.c +++ b/drm/nouveau/nvkm/subdev/volt/base.c @@ -51,18 +51,30 @@ static int nvkm_volt_set(struct nvkm_volt *volt, u32 uv) { struct nvkm_subdev *subdev = &volt->subdev; - int i, ret = -EINVAL; + int i, ret = -EINVAL, best_err = uv, best = -1; if (volt->func->volt_set) return volt->func->volt_set(volt, uv); for (i = 0; i < volt->vid_nr; i++) { - if (volt->vid[i].uv == uv) { - ret = volt->func->vid_set(volt, volt->vid[i].vid); - nvkm_debug(subdev, "set %duv: %d\n", uv, ret); + int err = volt->vid[i].uv - uv; + if (err < 0 || err > best_err) + continue; + + best_err = err; + best = i; + if (best_err == 0) break; - } } + + if (best == -1) { + nvkm_error(subdev, "couldn't set %iuv\n", uv); + return ret; + } + + ret = volt->func->vid_set(volt, volt->vid[best].vid); + nvkm_debug(subdev, "set req %duv to %duv: %d\n", uv, + volt->vid[best].uv, ret); return ret; } -- 2.8.1 _______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/nouveau