mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
drm/nouveau/volt: Don't require perfect fit
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. v5: Initialize best_err with volt->max_uv. Signed-off-by: Karol Herbst <karolherbst@gmail.com> Reviewed-by: Martin Peres <martin.peres@free.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
4b9ce6e7b6
commit
5e00e3263b
1 changed files with 17 additions and 5 deletions
|
@ -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 = volt->max_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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue