[PATCH v6 08/11] pwm: rzg2l-gpt: Add prescale_mult variable to struct rzg2l_gpt_info
From: Biju
Date: Thu Jun 04 2026 - 06:00:33 EST
From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
RZ/G3E GPT IP has prescale factor power of 2 where as that of RZ/G2L is 4.
Add prescale_mult variable to struct rzg2l_gpt_info for handling this
difference.
Reviewed-by: Tommaso Merciai <tommaso.merciai.xr@xxxxxxxxxxxxxx>
Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
v5->v6:
* Dropped extra parameter rzg2l_gpt from rzg2l_gpt_calculate_prescale()
in rzg2l_gpt_round_waveform_tohw().
* Updated comment in rzg2l_gpt_calculate_period_or_duty().
v4->v5:
* No change.
v3->v4:
* Updated commit header and description
* Renamed prescale_pow_of_two_mult_factor->prescale_mult
v2->v3:
* No change.
v1->v2:
* Collected tag.
---
drivers/pwm/pwm-rzg2l-gpt.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/pwm/pwm-rzg2l-gpt.c b/drivers/pwm/pwm-rzg2l-gpt.c
index 3ee5a70ca265..4f3b4dd959e6 100644
--- a/drivers/pwm/pwm-rzg2l-gpt.c
+++ b/drivers/pwm/pwm-rzg2l-gpt.c
@@ -92,6 +92,7 @@
struct rzg2l_gpt_info {
u32 gtcr_tpcs;
+ u8 prescale_mult;
};
struct rzg2l_gpt_chip {
@@ -234,24 +235,29 @@ static void rzg2l_gpt_disable(struct rzg2l_gpt_chip *rzg2l_gpt,
static u64 rzg2l_gpt_calculate_period_or_duty(struct rzg2l_gpt_chip *rzg2l_gpt,
u32 val, u8 prescale)
{
+ const struct rzg2l_gpt_info *info = rzg2l_gpt->info;
u64 tmp;
/*
- * The calculation doesn't overflow an u64 because prescale ≤ 5 and so
- * tmp = val << (2 * prescale) * USEC_PER_SEC
+ * The calculation doesn't overflow a u64 because,
+ * prescale ≤ 5 for info->prescale_mult = 2 and so
+ * tmp = val << (info->prescale_mult * prescale) * USEC_PER_SEC
* < 2^32 * 2^10 * 10^6
* < 2^32 * 2^10 * 2^20
* = 2^62
*/
- tmp = (u64)val << (2 * prescale);
+ tmp = (u64)val << (info->prescale_mult * prescale);
tmp *= USEC_PER_SEC;
return DIV64_U64_ROUND_UP(tmp, rzg2l_gpt->rate_khz);
}
-static u32 rzg2l_gpt_calculate_pv_or_dc(u64 period_or_duty_cycle, u8 prescale)
+static u32 rzg2l_gpt_calculate_pv_or_dc(const struct rzg2l_gpt_info *info,
+ u64 period_or_duty_cycle, u8 prescale)
{
- return min_t(u64, DIV_ROUND_DOWN_ULL(period_or_duty_cycle, 1 << (2 * prescale)),
+ return min_t(u64,
+ DIV_ROUND_DOWN_ULL(period_or_duty_cycle,
+ 1 << (info->prescale_mult * prescale)),
U32_MAX);
}
@@ -261,6 +267,7 @@ static int rzg2l_gpt_round_waveform_tohw(struct pwm_chip *chip,
void *_wfhw)
{
struct rzg2l_gpt_chip *rzg2l_gpt = to_rzg2l_gpt_chip(chip);
+ const struct rzg2l_gpt_info *info = rzg2l_gpt->info;
struct rzg2l_gpt_waveform *wfhw = _wfhw;
bool is_small_second_period = false;
u8 ch = RZG2L_GET_CH(pwm->hwpwm);
@@ -299,7 +306,7 @@ static int rzg2l_gpt_round_waveform_tohw(struct pwm_chip *chip,
}
wfhw->prescale = rzg2l_gpt_calculate_prescale(period_ticks);
- wfhw->gtpr = rzg2l_gpt_calculate_pv_or_dc(period_ticks, wfhw->prescale);
+ wfhw->gtpr = rzg2l_gpt_calculate_pv_or_dc(info, period_ticks, wfhw->prescale);
wfhw->gtccr = 0;
if (is_small_second_period)
return 1;
@@ -307,7 +314,7 @@ static int rzg2l_gpt_round_waveform_tohw(struct pwm_chip *chip,
duty_ticks = mul_u64_u64_div_u64(wf->duty_length_ns, rzg2l_gpt->rate_khz, USEC_PER_SEC);
if (duty_ticks > period_ticks)
duty_ticks = period_ticks;
- wfhw->gtccr = rzg2l_gpt_calculate_pv_or_dc(duty_ticks, wfhw->prescale);
+ wfhw->gtccr = rzg2l_gpt_calculate_pv_or_dc(info, duty_ticks, wfhw->prescale);
return 0;
}
@@ -353,9 +360,9 @@ static int rzg2l_gpt_read_waveform(struct pwm_chip *chip,
return 0;
}
-static u64 rzg2l_gpt_calculate_cycles(u32 value, u8 prescale)
+static u64 rzg2l_gpt_calculate_cycles(u32 value, u8 mult, u8 prescale)
{
- return (u64)value << (2 * prescale);
+ return (u64)value << (mult * prescale);
}
static int rzg2l_gpt_write_waveform(struct pwm_chip *chip,
@@ -363,6 +370,7 @@ static int rzg2l_gpt_write_waveform(struct pwm_chip *chip,
const void *_wfhw)
{
struct rzg2l_gpt_chip *rzg2l_gpt = to_rzg2l_gpt_chip(chip);
+ const struct rzg2l_gpt_info *info = rzg2l_gpt->info;
const struct rzg2l_gpt_waveform *wfhw = _wfhw;
u8 sub_ch = rzg2l_gpt_subchannel(pwm->hwpwm);
u8 ch = RZG2L_GET_CH(pwm->hwpwm);
@@ -418,6 +426,7 @@ static int rzg2l_gpt_write_waveform(struct pwm_chip *chip,
* value for both channels.
*/
rzg2l_gpt->period_ticks[ch] = rzg2l_gpt_calculate_cycles(wfhw->gtpr,
+ info->prescale_mult,
wfhw->prescale);
} else if (!wfhw->gtpr && rzg2l_gpt_is_ch_enabled(rzg2l_gpt, pwm->hwpwm, NULL)) {
rzg2l_gpt_disable(rzg2l_gpt, pwm);
@@ -580,6 +589,7 @@ static int rzg2l_gpt_probe(struct platform_device *pdev)
static const struct rzg2l_gpt_info rzg2l_data = {
.gtcr_tpcs = RZG2L_GTCR_TPCS,
+ .prescale_mult = 2,
};
static const struct of_device_id rzg2l_gpt_of_table[] = {
--
2.43.0