Re: [PATCH v8 4/8] dt-bindings: pwm: Support new PWM_USAGE_POWER flag

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Apr 13, 2021 at 07:56:31PM +0200, Uwe Kleine-König wrote:
> On Tue, Apr 13, 2021 at 01:51:15PM +0200, Thierry Reding wrote:
> > On Mon, Apr 12, 2021 at 06:27:23PM +0200, Uwe Kleine-König wrote:
> > > On Mon, Apr 12, 2021 at 03:27:41PM +0200, Clemens Gruber wrote:
> > > > Add the flag and corresponding documentation for PWM_USAGE_POWER.
> > > 
> > > My concern here in the previous round was that PWM_USAGE_POWER isn't a
> > > name that intuitively suggests its semantic. Do you disagree?
> > 
> > I suggested PWM_USAGE_POWER because I think it accurately captures what
> > we want here.
> > 
> > > > Cc: Rob Herring <robh+dt@xxxxxxxxxx>
> > > > Signed-off-by: Clemens Gruber <clemens.gruber@xxxxxxxxxxxx>
> > > > ---
> > > >  Documentation/devicetree/bindings/pwm/pwm.txt | 3 +++
> > > >  include/dt-bindings/pwm/pwm.h                 | 1 +
> > > >  2 files changed, 4 insertions(+)
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm.txt b/Documentation/devicetree/bindings/pwm/pwm.txt
> > > > index 084886bd721e..fe3a28f887c0 100644
> > > > --- a/Documentation/devicetree/bindings/pwm/pwm.txt
> > > > +++ b/Documentation/devicetree/bindings/pwm/pwm.txt
> > > > @@ -46,6 +46,9 @@ period in nanoseconds.
> > > >  Optionally, the pwm-specifier can encode a number of flags (defined in
> > > >  <dt-bindings/pwm/pwm.h>) in a third cell:
> > > >  - PWM_POLARITY_INVERTED: invert the PWM signal polarity
> > > > +- PWM_USAGE_POWER: Only care about the power output of the signal. This
> > > > +  allows drivers (if supported) to optimize the signals, for example to
> > > > +  improve EMI and reduce current spikes.
> > > 
> > > IMHO there are too many open questions about which freedom this gives to
> > > the lowlevel driver. If the consumer requests .duty_cycle = 25ns +
> > > .period = 100ns, can the driver provide .duty_cycle = 25s + .period =
> > > 100s which nominally has the same power output? Let's not introduce more
> > > ambiguity than there already is.
> > 
> > The freedom given to the driver should be to adjust the signal within
> > reasonable bounds. Changing the time unit by a factor of 1000000000 is
> > not within reason, and I doubt anyone would interpret it that way, even
> > if we didn't document this at all.
> 
> Please define a rule that allows to judge if any given implementation is
> correct or not. For the record neither "within reasonable bounds" nor "a
> factor of 1000000000 is not within reason" is good enough.

We haven't had any rules thus far and I have yet to see a single report
that drivers get this completely wrong. So "within reason", which I
think is what driver authors will do by default, is good enough in
practice.

> This is not only important to be able to review drivers that implement
> it, but also for consumers, because they should know what to expect.

Again, consumers should expect that the PWM driver will do something
that is within reasonable margins. If that ever ends up being wrong for
a given use-case we may need to change that.

But I don't think it's necessary to take out all flexibility if we don't
have to. As long as things work fine there's no reason to make the rules
any more strict.

> > To be frank I think that quest of yours to try and rid the PWM API of
> > all ambiguity is futile.
> 
> I consider my quest about rounding reasonable. And I think this is
> painful because when the PWM framework was introduced it was too much ad
> hoc and the APIs were not thought through enough. And because I don't
> want to have that repeated, I express my concerns here.

Maybe try to look at this from another perspective. Maybe what you call
adhoc API was actually deliberately designed this way. To be honest I
don't know what the intentions were when the original PWM API was
created, that was way before I took on maintenance of the PWM subsystem.
The PWM framework adopted the existing API and there was no reason to
change it because it worked just fine.

And I still don't see a reason for the API to change. Like I said, if we
ever run into a case where the current flexibility gets in the way and
yields unpredictable or unusable results, then that's something we have
to improve. But I don't think we should make any such changes if they're
not necessary, because then we may end up making matters worse.

Also, I think this actually corroborates the need for something like the
usage flags in the PWM specifier. Currently drivers will do their best
to generate a PWM signal that's as close as possible to the requested
parameters. If that's not enough for a specific use-case, then that's
something that the new use-case has to describe somehow. They could do
that using a usage flag (perhaps something like PWM_USAGE_STRICT, which
may tell the driver to return an error if the requested parameters
cannot be applied exactly). Another possibility is to give consumers a
way of running a given state through the driver but not applying just
yet so that they can inspect what the driver would have programmed and
then make adjustments (that's along the lines of what you had in mind
with the "round state" concept, I suppose).

> > I've been trying to be lenient because you seem
> > motivated, but I think you're taking this too far. There are always
> > going to be cases that aren't completely clear-cut and where drivers
> > need the flexibility to cheat in order to be useful at all. If we get to
> > a point where everything needs to be 100% accurate, the majority of the
> > PWM controllers won't be usable at all.
> > 
> > Don't let perfect be the enemy of good.
> 
> I admit here I don't have a constructive idea how to define what is
> needed.
> 
> For example if we only care about the relative duty cycle, a consumer
> requests
> 
> 	.period = 1045
> 	.duty_cyle = 680
> 
> and the driver can provide multiples of 100 ns for both .period and
> .duty_cycle, the candidates that might be sensible to chose from are
> (IMHO):
> 
>  - exact relative duty:
> 
> 	.period = 104500
> 	.duty_cycle = 68000
> 
>  - round both values in the same direction, minimizing error
> 
>  	.period = 1100
> 	.duty_cycle = 700
> 
>    (requested relative duty = 65.07%, implemented = 63.64%; when
>    rounding both down we get 60%)
> 
>  - round both values mathematically: 
> 
>  	.period = 1000
> 	.duty_cycle = 700
> 
>    (yielding a relative duty of 70% instead of the requested 65.07%)
> 
>  - Maybe
> 
>  	.period = 1000
> 	.duty_cycle = 600
> 
>    might also be preferable for some consumers?! (60%)
> 
>  - Maybe
> 
>  	.period = 2000
> 	.duty_cycle = 1300
> 
>    is a good compromise because the relative duty is nearly exactly
>    matched and the period is only stretched by a factor < 2.
> 
> In my eyes a driver author should be told which of these options should
> be picked. Do you consider it obvious which of these options is the
> objective best? If so why? Do you agree that we should tell driver
> authors how to implement this before we have several drivers that all
> implement their own ideas and getting this in a consistent state is
> another pain?

We already have several drivers implementing things inconsistently. And
again, I don't see how that's a problem. Most of the time, values for
period will be hand-picked to match the requirements of the use-case on
a given platform (for backlights or LEDs, for example, you don't want a
period that's too long, because then you'll get flicker). The duty cycle
is then simply used as a way of getting a power output of the desired
percentage. For something like PWM backlight, if interpolation doesn't
work, you have the option of specifying discrete levels with hand-picked
values.

Backlight and LEDs are the vast majority of applications for PWMs used
in the kernel today. Another category would be regulators and they end
up being pretty much the same in where the values come from.

The one use-case that's perhaps a bit more tricky is the sysfs interface
because people can throw whatever they want at it. But even that is not
likely to be problematic in practice because users will either be
satisfied with the result that they get when computationally getting the
numbers, or end up hand-picking values for those as well, with the only
difference being that they are programmed from userspace.

For the particular case of PWM_USAGE_POWER, I think it really only says
that the power output of the signal should be as requested. It does not
mean that the driver can pick whatever values it wants. Drivers should
still try to match period and duty cycle as closely as possible because
there's not enough other information to know if, for example, stretching
the clock by a factor of 2 is reasonable for the use-case.

> (My bet is you are lax and don't consider consistency among drivers soo
> important. In this case we don't agree. I think it's important for
> consumer driver authors to be able to rely on some expectations
> independently which lowlevel driver is in use.)

Well, yeah. Consumers should be able to rely on the expectation that the
provider will try to best match the given parameters. Something like
PWM_USAGE_POWER can be used to give the driver a bit more freedom, but
it doesn't mean it should switch into crazy mode.

Again, most of the time the values that we're dealing with here will be
hand-picked for a given use-case, which means a given PWM channel and
what it will be used for. So the values that the API and driver get are
going to be something that the driver can set to within a reasonable
margin, otherwise users will go and pick a better value.

So in practice these problems just don't exist, and we're spending a
huge amount of time tryng to solve a non-existent problem. And that's
the reason why we're not coming up with a good solution. You can't come
up with a good solution to a problem that doesn't exist because you
don't know any of the parameters.

Thierry

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux