Re: [PATCH v5 2/4] pwm: Add support for RZ/V2M PWM driver

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

 



On Tue, Oct 10, 2023 at 10:48:19AM +0000, Fabrizio Castro wrote:
> Hi Uwe,
> 
> Thanks for your reply!
> 
> > From: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
> > Sent: Wednesday, October 4, 2023 3:15 PM
> > Subject: Re: [PATCH v5 2/4] pwm: Add support for RZ/V2M PWM driver
> > 
> > Hello Fabrizio,
> > 
> > On Tue, Oct 03, 2023 at 09:19:41PM +0000, Fabrizio Castro wrote:
> > > > > +	if (period)
> > > > > +		period += 1;
> > > >
> > > > This looks bogus, why don't you add 1 if RZV2M_PWMCYC is 0?
> > >
> > > Agreed. We should always add 1.
> > >
> > > > Also it suggests that the hardware cannot do a 100% relative duty
> > > > cycle?
> > >
> > > It does support 100% duty cycle.
> > > PWMCYC = 0 actually means 1 clock cycle, that's why the faff with
> > > increment and decrement operations, and that's why the confusion.
> > 
> > So it doesn't support a 0% relative duty cycle?
> 
> It does support 0% duty cycle.
> 
> > 
> > > > If I didn't miss anything here, please add that to the list of
> > > > Limitations above.
> > >
> > > Thankfully not a limitation.
> > >
> > > >
> > > > > +	state->period = DIV_ROUND_UP_ULL(NSEC_PER_SEC * (u64)period
> > << (4
> > > > * prescale),
> > > > > +					 rzv2m_pwm->rate);
> > > >
> > > > The multiplication can overflow. I see no easy way to prevent this
> > > > without introducing a mul_u64_u64_div_roundup helper. Maybe I miss
> > > > something?
> > >
> > > It does overflow, good catch!
> > > I think we could split this in three operations for now, and maybe
> > > improve it later on:
> > > period = NSEC_PER_SEC * (cyc + 1);
> > > period = DIV64_U64_ROUND_UP(period, rzv2m_pwm->rate);
> > > period <<= rzv2m_pwm_prescale_to_shift(prescale);
> > 
> > You're loosing precision here though. With /^ = div_round_up:
> > 
> > 	1000000000 * 5 /^ 3 << 2 == 6666666668
> > 	1000000000 * 5 << 2 /^ 3 == 6666666667
> 
> Yep.
> 
> > 
> > So I correct my statement to: I see no easy and exact way to prevent
> > an
> > overflow without introducing a mul_u64_u64_div_roundup helper. :-)
> 
> Indeed. In my mind, the best way to tackle this problem is for such an
> API to use an internal representation of 128-bit, so that it can calculate
> (a*b + c - 1)/c accurately, and return both the high and low part of the
> 128-bit result (and maybe keeping the high part result optional?).
> Something like
> u64 mul_u64_u64_div_u64_roundup(u64 a, u64 b, u64 c, u64 *res_high);
> or
> void mul_u64_u64_div_u64_roundup(u64 a, u64 b, u64 c, u64 *res_high, u64 *res_low);
> 
> Needless to say, the API may take quite some time to perform the calculations,
> but if precision/accuracy is what we need, there is probably no better
> way of addressing this, unless you have a better idea?
> 
> Looking around, my understanding is that other drivers may benefit from
> this sort of accurate rounded up result when a, b, and c are 64-bit, is that
> why you think it has come the time to address this, or do you think this
> is the first instance of such need?

The assumption of mul_u64_u64_div_u64 is that the result won't overflow
a u64. Iff your hardware doesn't support a period > U64_MAX I think
there is no need for an overflow-checking variant of
mul_u64_u64_div_u64(). I didn't recheck, but this would be the first
driver I'm aware of that can support a period > U64_MAX ns. But maybe it
depends on the clkrate and if that's small enough it can happen?!

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux