[Nouveau] [PATCH v4 16/37] volt: don't require perfect fit

Martin Peres martin.peres at free.fr
Tue Apr 19 21:10:47 UTC 2016


On 18/04/16 22:13, Karol Herbst wrote:
> 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 <nouveau at 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;

"best_err = uv" is not a safe value. You may set best_err to the maximum voltage, anything under that may fail in theory.

With this fixed, this is:

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

>   
>   	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;
>   }
>   



More information about the Nouveau mailing list