Re: [PATCH v17 3/4] pwm: Add support for RZ/G2L GPT

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

 



Hello Biju,

On Thu, Dec 07, 2023 at 06:26:44PM +0000, Biju Das wrote:
> > -----Original Message-----
> > From: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
> > Sent: Wednesday, December 6, 2023 6:38 PM
> > Subject: Re: [PATCH v17 3/4] pwm: Add support for RZ/G2L GPT
> > On Mon, Nov 20, 2023 at 11:33:06AM +0000, Biju Das wrote:
> > > +static u64 calculate_period_or_duty(struct rzg2l_gpt_chip *rzg2l_gpt,
> > > +u32 val, u8 prescale) {
> > > +	u64 retval;
> > > +	u64 tmp;
> > > +
> > > +	tmp = NSEC_PER_SEC * (u64)val;
> > > +	/*
> > > +	 * To avoid losing precision for smaller period/duty cycle values
> > > +	 * ((2^32 * 10^9 << 2) < 2^64), do not process the rounded values.
> > > +	 */
> > > +	if (prescale < 2)
> > > +		retval = DIV64_U64_ROUND_UP(tmp << (2 * prescale), rzg2l_gpt-
> > >rate);
> > > +	else
> > > +		retval = DIV64_U64_ROUND_UP(tmp, rzg2l_gpt->rate) << (2 *
> > > +prescale);
> > 
> > Maybe introduce a mul_u64_u64_div64_roundup (similar to
> > mul_u64_u64_div64) to also be exact for prescale >= 2?
> 
> mul_u64_u64_div_u64()has a bug already and we are losing precision with very high values.
> See the output with CONFIG_PWM_DEBUG enabled[1]. So we cannot reuse mul_u64_u64_div64()
> for roundup operation.
> 
> Maybe we need to come with 128bit operations for mul_u64_u64_div64_roundup().
> Do you have any specific algorithm in mind for doing mul_u64_u64_div64_roundup()?
> 
> Fabrizio already developed an algorithm for 128 bit operation, I could reuse once it
> hits the mainline.
> 
> [1]
> ######[  304.213944] pwm-rzg2l-gpt 10048000.pwm: .apply is not idempotent (ena=1 pol=0 5500000000000/43980352512000) -> (ena=1 pol=0 5500000000000/43980239923200)
> 	 High setting##
> 	[  304.230854] pwm-rzg2l-gpt 10048000.pwm: .apply is not idempotent (ena=1 pol=0 23980465100800/43980352512000) -> (ena=1 pol=0 23980465100800/43980239923200)

Have you tried to understand that? What is the clk rate when this
happens? You're not suggesting that mul_u64_u64_div_u64 is wrong, are
you?

> > With prescale <= 5 and rzg2l_gpt->rate >= 1024 this shouldn't work just
> > fine.

I meant here "this should work just fine", I guess you understood that
right.

> Practically this is not possible. Yes, from theoretical point, rate=1kHz 
> compared to the practical case, 100MHz won't work.
> 
> For the practical case, the current logic is fine. If we need to achieve
> theoretical example like you mentioned then we need to have 
> mul_u64_u64_div64_roundup().

That shouldn't be so hard to implement.

> > > +	rzg2l_gpt->max_val = mul_u64_u64_div_u64(U32_MAX, NSEC_PER_SEC,
> > > +						 rzg2l_gpt->rate) * RZG2L_MAX_SCALE_FACTOR;
> > 
> > Is it clear that this won't overflow?

U32_MAX * NSEC_PER_SEC doesn't even overflow an u64, so using a plain
u64 division would be more efficient.

You'd get a smaller rounding error with:

	rzg2l_gpt->max_val = mul_u64_u64_div_u64((u64)U32_MAX * NSEC_PER_SEC, RZG2L_MAX_SCALE_FACTOR, rzg2l_gpt->rate);

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