All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vagrant Cascadian <vagrant@debian.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [U-Boot, 3/3] pwm: sunxi: choose best prescaler to improve PWM resolution
Date: Thu, 18 Oct 2018 09:34:19 -0700	[thread overview]
Message-ID: <87o9br43jo.fsf@aikidev.net> (raw)
In-Reply-To: <20181017045635.9857-3-anarsoul@gmail.com>

On 2018-10-16, Vasily Khoruzhick wrote:
> Choose best prescaler to improve PWM resolution. Without this change
> driver chooses first prescaler that gives us period value within
> range, but it could be not the best one.
>
> Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>

Fixes LCD backlight issues with the pinebook series:

  https://patchwork.ozlabs.org/project/uboot/list/?series=71358

Tested-by: Vagrant Cascadian <vagrant@debian.org>

> ---
>  drivers/pwm/sunxi_pwm.c | 32 +++++++++++++++++++-------------
>  1 file changed, 19 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/pwm/sunxi_pwm.c b/drivers/pwm/sunxi_pwm.c
> index 6284409b4f..8a55e4f461 100644
> --- a/drivers/pwm/sunxi_pwm.c
> +++ b/drivers/pwm/sunxi_pwm.c
> @@ -67,49 +67,55 @@ static int sunxi_pwm_set_config(struct udevice *dev, uint channel,
>  {
>  	struct sunxi_pwm_priv *priv = dev_get_priv(dev);
>  	struct sunxi_pwm *regs = priv->regs;
> -	int prescaler;
> -	u32 v, period = 0, duty;
> -	u64 scaled_freq = 0;
> +	int best_prescaler = 0;
> +	u32 v, best_period = 0, duty;
> +	u64 best_scaled_freq = 0;
>  	const u32 nsecs_per_sec = 1000000000U;
>  
>  	debug("%s: period_ns=%u, duty_ns=%u\n", __func__, period_ns, duty_ns);
>  
> -	for (prescaler = 0; prescaler <= SUNXI_PWM_CTRL_PRESCALE0_MASK;
> +	for (int prescaler = 0; prescaler <= SUNXI_PWM_CTRL_PRESCALE0_MASK;
>  	     prescaler++) {
> +		u32 period = 0;
> +		u64 scaled_freq = 0;
>  		if (!prescaler_table[prescaler])
>  			continue;
>  		scaled_freq = lldiv(OSC_24MHZ, prescaler_table[prescaler]);
>  		period = lldiv(scaled_freq * period_ns, nsecs_per_sec);
> -		if (period - 1 <= SUNXI_PWM_CH0_PERIOD_MAX)
> -			break;
> +		if ((period - 1 <= SUNXI_PWM_CH0_PERIOD_MAX) &&
> +		    best_period < period) {
> +			best_period = period;
> +			best_scaled_freq = scaled_freq;
> +			best_prescaler = prescaler;
> +		}
>  	}
>  
> -	if (period - 1 > SUNXI_PWM_CH0_PERIOD_MAX) {
> +	if (best_period - 1 > SUNXI_PWM_CH0_PERIOD_MAX) {
>  		debug("%s: failed to find prescaler value\n", __func__);
>  		return -EINVAL;
>  	}
>  
> -	duty = lldiv(scaled_freq * duty_ns, nsecs_per_sec);
> +	duty = lldiv(best_scaled_freq * duty_ns, nsecs_per_sec);
>  
> -	if (priv->prescaler != prescaler) {
> +	if (priv->prescaler != best_prescaler) {
>  		/* Mask clock to update prescaler */
>  		v = readl(&regs->ctrl);
>  		v &= ~SUNXI_PWM_CTRL_CLK_GATE;
>  		writel(v, &regs->ctrl);
>  		v &= ~SUNXI_PWM_CTRL_PRESCALE0_MASK;
> -		v |= (prescaler & SUNXI_PWM_CTRL_PRESCALE0_MASK);
> +		v |= (best_prescaler & SUNXI_PWM_CTRL_PRESCALE0_MASK);
>  		writel(v, &regs->ctrl);
>  		v |= SUNXI_PWM_CTRL_CLK_GATE;
>  		writel(v, &regs->ctrl);
> -		priv->prescaler = prescaler;
> +		priv->prescaler = best_prescaler;
>  	}
>  
> -	writel(SUNXI_PWM_CH0_PERIOD_PRD(period) |
> +	writel(SUNXI_PWM_CH0_PERIOD_PRD(best_period) |
>  	       SUNXI_PWM_CH0_PERIOD_DUTY(duty), &regs->ch0_period);
>  
>  	debug("%s: prescaler: %d, period: %d, duty: %d\n",
>  	      __func__, priv->prescaler,
> -	      period, duty);
> +	      best_period, duty);
>  
>  	return 0;
>  }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 227 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181018/fac95c6f/attachment.sig>

  reply	other threads:[~2018-10-18 16:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-17  4:56 [U-Boot] [PATCH 1/3] pwm: sunxi: fix off-by-one that prevented PWM to use prescaler bypass Vasily Khoruzhick
2018-10-17  4:56 ` [U-Boot] [PATCH 2/3] pwm: sunxi: use new prescaler when configuring PWM Vasily Khoruzhick
2018-10-17  4:56 ` [U-Boot] [PATCH 3/3] pwm: sunxi: choose best prescaler to improve PWM resolution Vasily Khoruzhick
2018-10-18 16:34   ` Vagrant Cascadian [this message]
2018-10-22 18:29   ` Jagan Teki
2018-10-22 18:35     ` Vasily Khoruzhick
2018-10-24 16:28   ` Jagan Teki
2018-10-24 17:07     ` Vasily Khoruzhick
2018-10-17  7:00 ` [U-Boot] [PATCH 1/3] pwm: sunxi: fix off-by-one that prevented PWM to use prescaler bypass Maxime Ripard
2018-10-18 21:10 ` Anatolij Gustschin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o9br43jo.fsf@aikidev.net \
    --to=vagrant@debian.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.