From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Cc: Andrzej Hajda <andrzej.hajda@intel.com>,
Neil Armstrong <narmstrong@baylibre.com>,
Robert Foss <robert.foss@linaro.org>,
Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
Jonas Karlman <jonas@kwiboo.se>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>,
Thierry Reding <thierry.reding@gmail.com>,
Lee Jones <lee.jones@linaro.org>,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-pwm@vger.kernel.org, linux-arm-msm@vger.kernel.org,
Doug Anderson <dianders@google.com>
Subject: Re: [PATCH v6 3/3] drm/bridge: ti-sn65dsi86: Implement the pwm_chip
Date: Mon, 25 Oct 2021 08:27:48 -0700 [thread overview]
Message-ID: <YXbM9Pnxpo50TQy+@ripper> (raw)
In-Reply-To: <20211025084250.pkd5s4zdmevjjl7m@pengutronix.de>
On Mon 25 Oct 01:42 PDT 2021, Uwe Kleine-K?nig wrote:
> Hello,
>
> [replaced Andrzej Hajda's email address with his new one]
>
> On Wed, Sep 29, 2021 at 10:05:57PM -0500, Bjorn Andersson wrote:
> > The SN65DSI86 provides the ability to supply a PWM signal on GPIO 4,
> > with the primary purpose of controlling the backlight of the attached
> > panel. Add an implementation that exposes this using the standard PWM
> > framework, to allow e.g. pwm-backlight to expose this to the user.
>
> Sorry for the long delay in reviewing this.
>
No worries, glad to hear from you again.
> > Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> > ---
> >
[..]
> > +static int ti_sn_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > + const struct pwm_state *state)
> > +{
> > + struct ti_sn65dsi86 *pdata = pwm_chip_to_ti_sn_bridge(chip);
> > + unsigned int pwm_en_inv;
> > + unsigned int backlight;
> > + unsigned int pre_div;
> > + unsigned int scale;
> > + u64 period_max;
> > + u64 period;
> > + int ret;
> > +
> > + if (!pdata->pwm_enabled) {
> > + ret = pm_runtime_get_sync(pdata->dev);
> > + if (ret < 0) {
> > + pm_runtime_put_sync(pdata->dev);
> > + return ret;
> > + }
> > + }
> > +
> > + if (state->enabled) {
> > + if (!pdata->pwm_enabled) {
> > + /*
> > + * The chip might have been powered down while we
> > + * didn't hold a PM runtime reference, so mux in the
> > + * PWM function on the GPIO pin again.
> > + */
> > + ret = regmap_update_bits(pdata->regmap, SN_GPIO_CTRL_REG,
> > + SN_GPIO_MUX_MASK << (2 * SN_PWM_GPIO_IDX),
> > + SN_GPIO_MUX_SPECIAL << (2 * SN_PWM_GPIO_IDX));
> > + if (ret) {
> > + dev_err(pdata->dev, "failed to mux in PWM function\n");
> > + goto out;
> > + }
> > + }
> > +
> > + /*
> > + * Per the datasheet the PWM frequency is given by:
> > + *
> > + * REFCLK_FREQ
> > + * PWM_FREQ = -----------------------------------
> > + * PWM_PRE_DIV * BACKLIGHT_SCALE + 1
> > + *
> > + * However, after careful review the author is convinced that
> > + * the documentation has lost some parenthesis around
> > + * "BACKLIGHT_SCALE + 1".
> > + * With that the formula can be written:
> > + *
> > + * T_pwm * REFCLK_FREQ = PWM_PRE_DIV * (BACKLIGHT_SCALE + 1)
>
> For my understanding: T_pwm = period length = 1 / PWM_FREQ, right? Maybe
> it's a good idea to state this more explicitly?
>
Correct. I've improved the comment accordingly.
> > + * In order to keep BACKLIGHT_SCALE within its 16 bits,
> > + * PWM_PRE_DIV must be:
> > + *
> > + * T_pwm * REFCLK_FREQ
> > + * PWM_PRE_DIV >= -------------------------
> > + * BACKLIGHT_SCALE_MAX + 1
> > + *
> > + * To simplify the search and to favour higher resolution of
> > + * the duty cycle over accuracy of the period, the lowest
> > + * possible PWM_PRE_DIV is used. Finally the scale is
> > + * calculated as:
> > + *
> > + * T_pwm * REFCLK_FREQ
> > + * BACKLIGHT_SCALE = ---------------------- - 1
> > + * PWM_PRE_DIV
> > + *
> > + * Here T_pwm is represented in seconds, so appropriate scaling
> > + * to nanoseconds is necessary.
> > + */
> > +
> > + /* Minimum T_pwm is 1 / REFCLK_FREQ */
> > + if (state->period <= NSEC_PER_SEC / pdata->pwm_refclk_freq) {
> > + ret = -EINVAL;
> > + goto out;
> > + }
> > +
> > + /*
> > + * Maximum T_pwm is 255 * (65535 + 1) / REFCLK_FREQ
> > + * Limit period to this to avoid overflows
> > + */
> > + period_max = div_u64((u64)NSEC_PER_SEC * 255 * (65535 + 1),
> > + pdata->pwm_refclk_freq);
> > + if (period > period_max)
>
> period is uninitialized here. This must be
>
> if (state->period > period_max)
>
> . Alternatively to the if you could use
>
> period = min(state->period, period_max);
>
Yes of course.
>
> Apart from this I'm happy with your patch set now.
>
Thank you.
> > + period = period_max;
> > + else
> > + period = state->period;
> > +
> > + pre_div = DIV64_U64_ROUND_UP(period * pdata->pwm_refclk_freq,
> > + (u64)NSEC_PER_SEC * (BACKLIGHT_SCALE_MAX + 1));
> > + scale = div64_u64(period * pdata->pwm_refclk_freq, (u64)NSEC_PER_SEC * pre_div) - 1;
>
> After thinking a while about this---I think I stumbled about this
> calculation already in earlier revisions of this patch set---I think I
> now understood it. I never saw something like this before because other
> drivers with similar HW conditions would pick:
>
> pre_div = div64_u64(period * pdata->pwm_refclk_freq,
> (u64)NSEC_PER_SEC * (BACKLIGHT_SCALE_MAX + 1));
>
> and then scale = BACKLIGHT_SCALE_MAX. This latter approach weights high
> resolution of duty_cycle still higher over period exactness than your
> approach.
Interesting.
> For me both approaches are fine.
>
Thanks, I'll respin with the two minor things above and leave the math
as is now :)
Regards,
Bjorn
> Best regards
> Uwe
>
> --
> Pengutronix e.K. | Uwe Kleine-König |
> Industrial Linux Solutions | https://www.pengutronix.de/ |
next prev parent reply other threads:[~2021-10-25 15:26 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-30 3:05 [PATCH v6 1/3] pwm: Introduce single-PWM of_xlate function Bjorn Andersson
2021-09-30 3:05 ` [PATCH v6 2/3] drm/bridge: ti-sn65dsi86: Use regmap_bulk_write API Bjorn Andersson
2021-09-30 15:40 ` Doug Anderson
2021-09-30 3:05 ` [PATCH v6 3/3] drm/bridge: ti-sn65dsi86: Implement the pwm_chip Bjorn Andersson
2021-10-07 3:53 ` Bjorn Andersson
2021-10-08 15:46 ` Robert Foss
2021-10-08 21:37 ` Doug Anderson
2021-10-25 8:42 ` Uwe Kleine-König
2021-10-25 15:27 ` Bjorn Andersson [this message]
2021-09-30 21:35 ` [PATCH v6 1/3] pwm: Introduce single-PWM of_xlate function Steev Klimaszewski
2021-10-25 8:58 ` Uwe Kleine-König
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=YXbM9Pnxpo50TQy+@ripper \
--to=bjorn.andersson@linaro.org \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=airlied@linux.ie \
--cc=andrzej.hajda@intel.com \
--cc=daniel@ffwll.ch \
--cc=dianders@google.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jernej.skrabec@gmail.com \
--cc=jonas@kwiboo.se \
--cc=lee.jones@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=narmstrong@baylibre.com \
--cc=robert.foss@linaro.org \
--cc=thierry.reding@gmail.com \
--cc=u.kleine-koenig@pengutronix.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox