All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Marangi <ansuelsmth@gmail.com>
To: "Uwe Kleine-König" <ukleinek@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,
	Benjamin Larsson <benjamin.larsson@genexis.eu>,
	AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	Lorenzo Bianconi <lorenzo@kernel.org>
Subject: Re: [RESEND PATCH v11] pwm: airoha: Add support for EN7581 SoC
Date: Mon, 7 Apr 2025 19:39:54 +0200	[thread overview]
Message-ID: <67f40dec.170a0220.5cda5.994c@mx.google.com> (raw)
In-Reply-To: <zwckkfd6mzzjxfpitojcmhokhjbtc4u3brf34pcu4phdlipf3z@uijstw7daze2>

On Thu, Apr 03, 2025 at 05:01:46PM +0200, Uwe Kleine-König wrote:
> Hello,
> 
> On Thu, Apr 03, 2025 at 12:50:27PM +0200, Christian Marangi wrote:
> > On Thu, Apr 03, 2025 at 11:58:48AM +0200, Uwe Kleine-König wrote:
> > > > +	if (hwpwm >= AIROHA_PWM_NUM_GPIO)
> > > > +		offset -= AIROHA_PWM_NUM_GPIO;
> > > > +
> > > > +	/* One FLASH_MAP register handles 8 pins */
> > > > +	*shift = do_div(offset, AIROHA_PWM_PINS_PER_FLASH_MAP);
> > > > +	*shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(*shift);
> > > > +
> > > > +	if (offset < AIROHA_PWM_NUM_GPIO)
> > > > +		*addr = AIROHA_PWM_REG_GPIO_FLASH_MAP(offset);
> > > > +	else
> > > > +		*addr = AIROHA_PWM_REG_SIPO_FLASH_MAP(offset);
> > > 
> > > A single if would be a bit more straight forward. Something like:
> > > 
> > > 	static void airoha_pwm_get_flash_map_addr_and_shift(unsigned int hwpwm,
> > > 							    unsigned int *addr, unsigned int *shift)
> > > 	{
> > > 		u64 offset = hwpwm;
> > > 	
> > > 		if (hwpwm >= AIROHA_PWM_NUM_GPIO) {
> > > 			unsigned sipohwpwm = hwpwm - AIROHA_PWM_NUM_GPIO;
> > > 
> > > 			*shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(sipohwpwm % AIROHA_PWM_PINS_PER_FLASH_MAP)
> > > 			*addr = AIROHA_PWM_REG_SIPO_FLASH_MAP(sipohwpwm);
> > > 		} else {
> > > 			*shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(hwpwm % AIROHA_PWM_PINS_PER_FLASH_MAP)
> > > 			*addr = AIROHA_PWM_REG_GPIO_FLASH_MAP(hwpwm);
> > > 		}
> > > 	}
> > > 
> > 
> > I think you missed the do_div that do side effect on offset. Also that
> > needs to be / AIROHA_PWM_PINS_PER_FLASH_MAP.
> 
> Ack. Luckily you got the idea anyhow. This double effect of do_div() is
> easy to miss, so getting rid of them sounds sensible.
> 
> > > > +		if (duty_ns == bucket->duty_ns &&
> > > > +		    period_ns == bucket->period_ns)
> > > > +			return i;
> > > 
> > > If period_ns == 4010 and bucket->period_ns == 4000 you're not
> > > considering *bucket even though it has the right period setting.
> > > (period_ns is the requested period and not the expected period actually
> > > implemented by HW, right?)
> > > 
> > 
> > Doesn't that requires a different generator? The value we store in the
> > bucket is the requested period yes.
> 
> No it doesn't. If I understood right the possible periods are: 4ms, 8ms,
> ..., so a request to do 4.01ms will be mapped to 4ms which allows to
> share the generator.
> 
> > > > +				  AIROHA_PWM_GPIO_FLASH_EN << shift);
> > > > +		return;
> > > > +	}
> > > > +
> > > > +	regmap_update_bits(pc->regmap, addr,
> > > > +			   AIROHA_PWM_GPIO_FLASH_SET_ID << shift,
> > > > +			   FIELD_PREP(AIROHA_PWM_GPIO_FLASH_SET_ID, index) << shift);
> > > 
> > > Huh, I'd prefer:
> > > 
> > > 	regmap_update_bits(pc->regmap, addr,
> > > 			   AIROHA_PWM_GPIO_FLASH_SET_ID(hwpwm % 8)
> > > 			   FIELD_PREP(AIROHA_PWM_GPIO_FLASH_SET_ID(hwpwm % 8), index));
> > > 
> > > (That probably doesn't work out of the box because of the
> > > __builtin_constant_p check on mask, so you might need a local
> > > alternative to FIELD_PREP without that check.)
> > 
> > Honestly it's not worth to introduce custom FIELD_PREP for this. Yes the
> > problem is that FIELD_PREP requires constant mask so hwpwm % 8 is
> > problematic. An old implementation had stuff in define but resulted in
> > very ugly and confusing define and macro. The shift and FIELD_PREP
> > permits a much cleaner description in the define part at the cost of
> > that additional << shift needed.
> > 
> > Hope you can understand why I think it's better to keep it this way.
> 
> OK, I can live with that.
> 
> > > > +	bucket = airoha_pwm_consume_generator(pc, duty_ns, period_ns,
> > > > +					      hwpwm);
> > > > +	if (bucket < 0)
> > > > +		return -EBUSY;
> > > > +
> > > > +	/*
> > > > +	 * For SIPO reinit is always needed to trigger the shift register chip
> > > > +	 * and apply the new flash configuration.
> > > 
> > > I don't understand that sentence. What is the shift register chip? What
> > > is a flash configuration?
> > > 
> > 
> > The SoC can have attached a shift register chip to supports multiple LEDs.
> > The handling of this chip and comunication is done internally to the SoC
> > and it's exposed to register with these additional register.
> > 
> > When such channel are used with an assumed shift register, to apply the
> > new configuration in airoha_pwm_config_flash_map(), the shift register
> > chip needs to be reinit to actually refresh the chip internal register
> > with the new "flash configuration" (aka the values for
> > AIROHA_PWM_GPIO_FLASH_SET_ID)
> > 
> > Will add more comments to this to make it more clear.
> 
> Sounds good.
> 
> > > > +	state->enabled = FIELD_GET(AIROHA_PWM_GPIO_FLASH_EN, val >> shift);
> > > > +	if (!state->enabled)
> > > > +		return 0;
> > > > +
> > > > +	state->polarity = PWM_POLARITY_NORMAL;
> > > > +
> > > > +	bucket = FIELD_GET(AIROHA_PWM_GPIO_FLASH_SET_ID, val >> shift);
> > > > +	state->period = pc->buckets[bucket].period_ns;
> > > 
> > > Does .period_ns hold the requested or the actual period? You should
> > > return the latter.
> > 
> > Problem is that putting .period_ns here cause error in the PWM_DEBUG
> > validations. This is caused by the conversion error of the various / and
> > * done to convert tick to ns. Also on applying the configuration we
> > already do all the validation to make sure the request value is the
> > expected one.
> 
> Then there is a bug somewhere. I wouldn't completely rule out it's in
> the PWM_DEBUG logic, but my bet is on your driver then.
>  
> > For the initial values, there is airoha_pwm_fill_bucket that read the
> > current PWM values at boot and fill the buckets with the current values.
> > 
> > This is the compromise I found to handle both pre-configured bucket and
> > also handle the division errors in the ns - tick conversion.
> > 
> > Hope this is acceptable, do you have hint on better handling this?
> 
> I'd wait for the next iteration of your patch and then take a deeper
> look in the maths involved. It should be possible to make PWM_DEBUG
> happy and still report the actual configuration.
> 

Hi Uwe,

I just sent v12. While making more test I notice something interesting
where the duty was off-by-1 in get_state in the PWM_DEBUG scenario.

That caused the idemponent error, I found the cause so now get_state
actually return the real values instead of the local one in the bucket!

I address everything else, hope v12 is the one!

-- 
	Ansuel

      reply	other threads:[~2025-04-07 17:39 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-26  0:24 [RESEND PATCH v11] pwm: airoha: Add support for EN7581 SoC Christian Marangi
2025-04-03  9:58 ` Uwe Kleine-König
2025-04-03 10:50   ` Christian Marangi
2025-04-03 15:01     ` Uwe Kleine-König
2025-04-07 17:39       ` Christian Marangi [this message]

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=67f40dec.170a0220.5cda5.994c@mx.google.com \
    --to=ansuelsmth@gmail.com \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=benjamin.larsson@genexis.eu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=lorenzo@kernel.org \
    --cc=ukleinek@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.