[PATCH v7 4/9] pwm: rzg2l-gpt: Add prescale_mult variable to struct rzg2l_gpt_info
Biju <[email protected]>
| Newsgroups | org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pwm |
|---|---|
| Message-ID | <[email protected]> |
From: Biju Das <[email protected]> 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 <[email protected]> Signed-off-by: Biju Das <[email protected]> --- v6->v7: * No change. 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 da2645a42608..fc77c27f0a97 100644 --- a/drivers/pwm/pwm-rzg2l-gpt.c +++ b/drivers/pwm/pwm-rzg2l-gpt.c @@ -79,6 +79,7 @@ struct rzg2l_gpt_info { u32 gtcr_tpcs; + u8 prescale_mult; }; struct rzg2l_gpt_chip { @@ -220,24 +221,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) * NSEC_PER_MSEC + * The calculation doesn't overflow a u64 because, + * prescale ≤ 5 for info->prescale_mult = 2 and so + * tmp = val << (info->prescale_mult * prescale) * NSEC_PER_MSEC * < 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 *= NSEC_PER_MSEC; 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); } @@ -247,6 +253,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); @@ -287,7 +294,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); if (is_small_second_period) { wfhw->gtccr = 0; return 1; @@ -296,7 +303,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, NSEC_PER_MSEC); 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; } @@ -342,9 +349,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, @@ -352,6 +359,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); @@ -407,6 +415,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); @@ -490,6 +499,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