[PATCH v2 2/2] pwm: sifive: change the PWM controlled LED algorithm

Uwe Kleine-König u.kleine-koenig at pengutronix.de
Fri Sep 8 07:49:42 PDT 2023


Hello,

On Fri, Sep 08, 2023 at 06:41:00PM +0800, Nylon Chen wrote:
> Sorry it's so long ago.
> 
> I have completed the implementation of the new version, but there is
> one thing about this letter that I still don't quite understand.
> 
> Uwe Kleine-König <u.kleine-koenig at pengutronix.de> 於 2023年1月30日 週一 下午6:17寫道:
> >
> > On Mon, Jan 30, 2023 at 05:32:29PM +0800, Nylon Chen wrote:
> > > The `frac` variable represents the pulse inactive time, and the result of
> > > this algorithm is the pulse active time. Therefore, we must reverse the
> > > result.
> > >
> > > The reference is SiFive FU740-C000 Manual[0].
> > >
> > > [0]: https://sifive.cdn.prismic.io/sifive/1a82e600-1f93-4f41-b2d8-86ed8b16acba_fu740-c000-manual-v1p6.pdf
> > >
> > > Signed-off-by: Nylon Chen <nylon.chen at sifive.com>
> > > ---
> > >  drivers/pwm/pwm-sifive.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
> > > index 62b6acc6373d..a5eda165d071 100644
> > > --- a/drivers/pwm/pwm-sifive.c
> > > +++ b/drivers/pwm/pwm-sifive.c
> > > @@ -158,6 +158,7 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > >       frac = DIV64_U64_ROUND_CLOSEST(num, state->period);
> > >       /* The hardware cannot generate a 100% duty cycle */
> > >       frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1);
> > > +     frac = (1U << PWM_SIFIVE_CMPWIDTH) - 1 - frac;
> >
> > The same problem exists in pwm_sifive_get_state(), doesn't it?
> >
> > As fixing this is an interruptive change anyhow, this is the opportunity
> > to align the driver to the rules tested by PWM_DEBUG.
> >
> > The problems I see in the driver (only checked quickly, so I might be
> > wrong):
> >
> >  - state->period != ddata->approx_period isn't necessarily a problem. If
> >    state->period > ddata->real_period that's fine and the driver should
> >    continue
>
> I still don’t quite understand the description of this paragraph.
> 
> state->period != ddate->approx_period seems to be used to compare the
> results of the previous and next two times.

There are two things to consider:

 - usually the hardware doesn't support all requestable states because
   the hardware's quantum is > 1 ns. That is, it might for example
   support periods in the form (160 ns * i / 3) for i in 1 .. 1023.

   If this hardware runs with i = 500 (that is period ~= 26666.66
   ns) because the first channel is configured to run with period =
   26667, and .request is called for the 2nd channel with .period =
   26700 ns, there is no need to refuse that, because 26666.66 is the
   best possible approximation for 26700 ns anyhow.

 - .apply is supposed to implement the highest possible period that
   isn't bigger than the requested period. So in the above case even if
   the hardware runs at 26666.66 ns without the possibility to change
   that, a request to configure for period = 30000 ns could succeed (and
   keep 26666.66 ns).

> Would you suggest I send the new implementation version before
> continuing the discussion?

Note that the above implements the optimal behaviour for a driver.
(For some definition of "optimal" that admittedly also yields strange
behaviour at times. The reasoning for this to the be thing to implement
is, that's the corner cases are easier to implement, idempotency is
possible and it's easier to work with than rounding to the nearest
possible value.)

While I'd like to see the sifive driver to implement this optimal
behaviour, it's not mandatory that you convert the driver to that
behaviour. Just make sure to not make it worse.

So to answer your question: If you understood what I wrote above and are
motivated to improve the driver, it would be great to do that before the
next review round.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20230908/6ea859ad/attachment.sig>


More information about the linux-riscv mailing list