* [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup @ 2026-05-25 13:11 ` Maurice Hieronymus via B4 Relay 2026-05-25 14:36 ` Michal Wilczynski 0 siblings, 1 reply; 7+ messages in thread From: Maurice Hieronymus via B4 Relay @ 2026-05-25 13:11 UTC (permalink / raw) To: Drew Fustini, Guo Ren, Fu Wei, Michal Wilczynski, Uwe Kleine-König, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich Cc: linux-riscv, linux-pwm, linux-kernel, rust-for-linux, Maurice Hieronymus From: Maurice Hieronymus <mhi@mailbox.org> The cycle register is always u32, so cycles_to_ns() can take a u32 instead of a u64. With that narrowing, cycles * NSEC_PER_SEC is at most u32::MAX * 1e9 (~4.3e18), which fits in u64 without overflow. The saturating arithmetic is therefore no longer needed, and the ceiling division can use Rust's u64::div_ceil() directly instead of the open-coded numerator/denominator form. This also drops the TODO referring to a future mul_u64_u64_div_u64_roundup kernel helper, which is no longer required. Signed-off-by: Maurice Hieronymus <mhi@mailbox.org> --- Note: Resending v1 because my mail server (mailbox.org) was unable to deliver the original submission to @kernerl.org recipients. Going through the b4 web submission endpoint this time. No changes to the patch content. --- drivers/pwm/pwm_th1520.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/pwm/pwm_th1520.rs b/drivers/pwm/pwm_th1520.rs index ddd44a5ce497..933c1ec59c2a 100644 --- a/drivers/pwm/pwm_th1520.rs +++ b/drivers/pwm/pwm_th1520.rs @@ -67,16 +67,10 @@ fn ns_to_cycles(ns: u64, rate_hz: u64) -> u64 { ns.saturating_mul(rate_hz) / NSEC_PER_SEC_U64 } -fn cycles_to_ns(cycles: u64, rate_hz: u64) -> u64 { +fn cycles_to_ns(cycles: u32, rate_hz: u64) -> u64 { const NSEC_PER_SEC_U64: u64 = time::NSEC_PER_SEC as u64; - // TODO: Replace with a kernel helper like `mul_u64_u64_div_u64_roundup` - // once available in Rust. - let numerator = cycles - .saturating_mul(NSEC_PER_SEC_U64) - .saturating_add(rate_hz - 1); - - numerator / rate_hz + (u64::from(cycles) * NSEC_PER_SEC_U64).div_ceil(rate_hz) } /// Hardware-specific waveform representation for TH1520. @@ -192,15 +186,15 @@ fn round_waveform_fromhw( return Ok(()); } - wf.period_length_ns = cycles_to_ns(u64::from(wfhw.period_cycles), rate_hz); + wf.period_length_ns = cycles_to_ns(wfhw.period_cycles, rate_hz); - let duty_cycles = u64::from(wfhw.duty_cycles); + let duty_cycles = wfhw.duty_cycles; if (wfhw.ctrl_val & TH1520_PWM_FPOUT) != 0 { wf.duty_length_ns = cycles_to_ns(duty_cycles, rate_hz); wf.duty_offset_ns = 0; } else { - let period_cycles = u64::from(wfhw.period_cycles); + let period_cycles = wfhw.period_cycles; let original_duty_cycles = period_cycles.saturating_sub(duty_cycles); // For an inverted signal, `duty_length_ns` is the high time (period - low_time). --- base-commit: 3936b25815ee686a273ca7bbdc9ae19af5e608a3 change-id: 20260521-pwm-th1520-fix-8e45558bbd31 Best regards, -- Maurice Hieronymus <mhi@mailbox.org> ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup 2026-05-25 13:11 ` [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup Maurice Hieronymus via B4 Relay @ 2026-05-25 14:36 ` Michal Wilczynski 2026-05-25 15:51 ` Maurice Hieronymus 0 siblings, 1 reply; 7+ messages in thread From: Michal Wilczynski @ 2026-05-25 14:36 UTC (permalink / raw) To: mhi, Drew Fustini, Guo Ren, Fu Wei, Uwe Kleine-König, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich Cc: linux-riscv, linux-pwm, linux-kernel, rust-for-linux On 5/25/26 15:11, Maurice Hieronymus via B4 Relay wrote: > From: Maurice Hieronymus <mhi@mailbox.org> > > The cycle register is always u32, so cycles_to_ns() can take a u32 > instead of a u64. With that narrowing, cycles * NSEC_PER_SEC is at most > u32::MAX * 1e9 (~4.3e18), which fits in u64 without overflow. The > saturating arithmetic is therefore no longer needed, and the ceiling > division can use Rust's u64::div_ceil() directly instead of the > open-coded numerator/denominator form. > > This also drops the TODO referring to a future > mul_u64_u64_div_u64_roundup kernel helper, which is no longer required. > > Signed-off-by: Maurice Hieronymus <mhi@mailbox.org> Hi Maurice, Thanks for sending this. I agree that this optimization makes perfect sense when looking at the TH1520 driver in isolation. However, since this is currently the only Rust PWM driver in the tree, it serves as the reference implementation for future drivers. We need cycles_to_ns to remain a generic blueprint. Many PWM controllers have 64-bit registers, and in the C API, it is standard practice to use helpers like DIV64_U64_ROUND_UP regardless of the register size (e.g. axi_pwmgen). Resolving the TODO by assuming 32-bit registers removes that generic capability. At the time this was merged, the equivalent Rust math helpers didn't exist yet, which is why the open-coded saturating math is there as a placeholder. To move forward, we should fix this by implementing the proper generic 64-bit math helper in the Rust abstractions, rather than narrowing the types here. Are you open to looking into adding the Rust equivalent for mul_u64_u64_div_u64_roundup instead? Best regards, -- Michal Wilczynski <m.wilczynski@samsung.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup 2026-05-25 14:36 ` Michal Wilczynski @ 2026-05-25 15:51 ` Maurice Hieronymus 2026-05-25 17:29 ` Gary Guo 2026-05-25 21:38 ` Michal Wilczynski 0 siblings, 2 replies; 7+ messages in thread From: Maurice Hieronymus @ 2026-05-25 15:51 UTC (permalink / raw) To: Michal Wilczynski, Drew Fustini, Guo Ren, Fu Wei, Uwe Kleine-König, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich Cc: linux-riscv, linux-pwm, linux-kernel, rust-for-linux On Mon, 2026-05-25 at 16:36 +0200, Michal Wilczynski wrote: > > To move forward, we should fix this by implementing the proper > generic > 64-bit math helper in the Rust abstractions, rather than narrowing > the > types here. Are you open to looking into adding the Rust equivalent > for > mul_u64_u64_div_u64_roundup instead? I would be definitely down, to help with that. Before I start working on it, a couple of clarification questions. Should I implement this as a thin FFI wrapper calling the C-Functions? Or do you prefer to have a re-implementation in Rust. Since mul_u64_u64_div_u64_roundup is a macro: Is it okay if this will be a small Rust function or should it be a macro as well? Thanks a lot, Maurice ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup 2026-05-25 15:51 ` Maurice Hieronymus @ 2026-05-25 17:29 ` Gary Guo 2026-05-25 21:38 ` Michal Wilczynski 1 sibling, 0 replies; 7+ messages in thread From: Gary Guo @ 2026-05-25 17:29 UTC (permalink / raw) To: Maurice Hieronymus, Michal Wilczynski, Drew Fustini, Guo Ren, Fu Wei, Uwe Kleine-König, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich Cc: linux-riscv, linux-pwm, linux-kernel, rust-for-linux On Mon May 25, 2026 at 4:51 PM BST, Maurice Hieronymus wrote: > On Mon, 2026-05-25 at 16:36 +0200, Michal Wilczynski wrote: >> >> To move forward, we should fix this by implementing the proper >> generic >> 64-bit math helper in the Rust abstractions, rather than narrowing >> the >> types here. Are you open to looking into adding the Rust equivalent >> for >> mul_u64_u64_div_u64_roundup instead? > > I would be definitely down, to help with that. > > Before I start working on it, a couple of clarification questions. > > Should I implement this as a thin FFI wrapper calling the C-Functions? > Or do you prefer to have a re-implementation in Rust. > > Since mul_u64_u64_div_u64_roundup is a macro: Is it okay if this will > be a small Rust function or should it be a macro as well? This should definitely not be a macro. You should only use Rust macros when it needs to be a macro. This function should just be a method of `u64` added via an extension trait, so you could use `u64::mul_div_ceil` to invoke it. The implementation of `mul_u64_add_u64_div_u64`is non-trivial, and thus you should defer to the C function to avoid re-implementing the same code. However, I think it'll be fine to first wrap the `mul_u64_add_u64_div_u64` as `u64::mul_add_div()` and then have `u64::mul_div_ceil()` be #[inline] fn mul_div_ceil(self, mul: Self, div: Self) -> Self { self.mul_add_div(mul, div - 1, div) } Best, Gary ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup 2026-05-25 15:51 ` Maurice Hieronymus 2026-05-25 17:29 ` Gary Guo @ 2026-05-25 21:38 ` Michal Wilczynski 2026-05-30 10:41 ` Maurice Hieronymus 1 sibling, 1 reply; 7+ messages in thread From: Michal Wilczynski @ 2026-05-25 21:38 UTC (permalink / raw) To: Maurice Hieronymus, Drew Fustini, Guo Ren, Fu Wei, Uwe Kleine-König, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich Cc: linux-riscv, linux-pwm, linux-kernel, rust-for-linux On 5/25/26 17:51, Maurice Hieronymus wrote: > On Mon, 2026-05-25 at 16:36 +0200, Michal Wilczynski wrote: >> >> To move forward, we should fix this by implementing the proper >> generic >> 64-bit math helper in the Rust abstractions, rather than narrowing >> the >> types here. Are you open to looking into adding the Rust equivalent >> for >> mul_u64_u64_div_u64_roundup instead? > > I would be definitely down, to help with that. > > Before I start working on it, a couple of clarification questions. > > Should I implement this as a thin FFI wrapper calling the C-Functions? > Or do you prefer to have a re-implementation in Rust. > > Since mul_u64_u64_div_u64_roundup is a macro: Is it okay if this will > be a small Rust function or should it be a macro as well? > > Thanks a lot, Apologies, I have to correct my statement from before after discussing with Uwe. The reason the macro was used in the mentioned driver is NOT that PWM controllers have 64-bit registers - Uwe isn't aware of that being a real pattern either, and I was inferring it from the code rather than from hardware reality. The actual reason the macros get used isn't unified across drivers and we should pin that down separately rather than block your patch on it. So please hold off on the Rust helper for now - your initial patch might be the right direction. > > Maurice > Best regards, -- Michal Wilczynski <m.wilczynski@samsung.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup 2026-05-25 21:38 ` Michal Wilczynski @ 2026-05-30 10:41 ` Maurice Hieronymus 2026-05-30 17:45 ` Michal Wilczynski 0 siblings, 1 reply; 7+ messages in thread From: Maurice Hieronymus @ 2026-05-30 10:41 UTC (permalink / raw) To: Michal Wilczynski, Drew Fustini, Guo Ren, Fu Wei, Uwe Kleine-König, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich Cc: linux-riscv, linux-pwm, linux-kernel, rust-for-linux > > Apologies, I have to correct my statement from before after > discussing No worries! > with Uwe. The reason the macro was used in the mentioned driver is > NOT > that PWM controllers have 64-bit registers - Uwe isn't aware of that > being a real pattern either, and I was inferring it from the code > rather > than from hardware reality. The actual reason the macros get used > isn't > unified across drivers and we should pin that down separately rather > than block your patch on it. > > So please hold off on the Rust helper for now - your initial patch > might > be the right direction. > Is there any further conclusion which direction is right? Can we merge my patch, does it need some change or are we going down the road with the Rust helpers? Thanks! Maurice > > > > Maurice > > > > Best regards, ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup 2026-05-30 10:41 ` Maurice Hieronymus @ 2026-05-30 17:45 ` Michal Wilczynski 0 siblings, 0 replies; 7+ messages in thread From: Michal Wilczynski @ 2026-05-30 17:45 UTC (permalink / raw) To: Maurice Hieronymus, Drew Fustini, Guo Ren, Fu Wei, Uwe Kleine-König, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich Cc: linux-riscv, linux-pwm, linux-kernel, rust-for-linux On 5/30/26 12:41, Maurice Hieronymus wrote: >> >> Apologies, I have to correct my statement from before after >> discussing > No worries! >> with Uwe. The reason the macro was used in the mentioned driver is >> NOT >> that PWM controllers have 64-bit registers - Uwe isn't aware of that >> being a real pattern either, and I was inferring it from the code >> rather >> than from hardware reality. The actual reason the macros get used >> isn't >> unified across drivers and we should pin that down separately rather >> than block your patch on it. >> >> So please hold off on the Rust helper for now - your initial patch >> might >> be the right direction. >> > Is there any further conclusion which direction is right? Can we merge > my patch, does it need some change or are we going down the road with > the Rust helpers? I think this patch is fine to move forward. We were wondering if there would be any noticeable difference in execution speed between the 64-bit computations and the mixed 32-bit/64-bit computations. I ran a profile on the platform, and the performance with and without the patch is identical: Here's the test I ran WITH PATCH # hyperfine --warmup 2 --runs 40 './pwmtestperf' Time (mean ± σ): 3.370 s ± 0.069 s [User: 0.069 s, System: 3.313 s] Range (min … max): 3.271 s … 3.547 s 40 runs WITHOUT PATCH # hyperfine --warmup 2 --runs 40 './pwmtestperf Time (mean ± σ): 3.368 s ± 0.051 s [User: 0.058 s, System: 3.326 s] Range (min … max): 3.278 s … 3.516 s 40 runs The delta is completely within the margin of error, confirming that 64-bit math is just as fast as 32-bit math on this architecture under standard loads. It is worth mentioning that to get a more meaningful performance measurement, pwmtestperf would probably need to be modified to stress this specific code path much more heavily. That said, fitting it into 32-bit where appropriate makes perfect sense from a code quality perspective. Reviewed-by: Michal Wilczynski <m.wilczynski@samsung.com> > > Thanks! > > Maurice >>> >>> Maurice >>> >> >> Best regards, > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-30 17:54 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CGME20260525131112eucas1p1d7e4836f71c81686e1f71e4007e344ec@eucas1p1.samsung.com>
2026-05-25 13:11 ` [PATCH RESEND] pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup Maurice Hieronymus via B4 Relay
2026-05-25 14:36 ` Michal Wilczynski
2026-05-25 15:51 ` Maurice Hieronymus
2026-05-25 17:29 ` Gary Guo
2026-05-25 21:38 ` Michal Wilczynski
2026-05-30 10:41 ` Maurice Hieronymus
2026-05-30 17:45 ` Michal Wilczynski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox