* [PATCH] i2c: stm32f7: truncate clock period instead of rounding it
@ 2026-06-11 10:48 Guillermo Rodríguez
2026-06-14 21:34 ` Andi Shyti
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Guillermo Rodríguez @ 2026-06-11 10:48 UTC (permalink / raw)
To: Pierre-Yves MORDRET, Alain Volmat, Andi Shyti, Maxime Coquelin,
Alexandre Torgue, M'boumba Cedric Madianga, Wolfram Sang
Cc: Guillermo Rodríguez, Pierre-Yves MORDRET, linux-i2c,
linux-stm32, linux-arm-kernel, linux-kernel
stm32f7_i2c_compute_timing() derives the I2C clock source period
(i2cclk) with DIV_ROUND_CLOSEST, which may round it up. When the
period is overestimated, all timings computed from it (SCLDEL,
SDADEL, SCLL, SCLH) come out shorter on the wire than calculated,
and the resulting bus rate can exceed the requested speed, violating
the I2C specification minimums for tLOW and tHIGH.
For example, with a 104.45 MHz clock source (e.g. PCLK1, the
reset-default I2C clock source on STM32MP1), i2cclk is rounded from
9.574 ns up to 10 ns. Requesting a 400 kHz fast mode bus with
72/27 ns rise/fall times and no analog/digital filters then produces
an actual bus rate of 415.6 kHz with tLOW = 1254 ns, violating both
the 400 kHz maximum rate and the 1300 ns tLOW minimum of the
specification.
Truncate the period instead, so that it can only be underestimated.
The error then falls on the safe side: the programmed timings come
out slightly longer than computed and the bus runs marginally below
the target rate (375.3 kHz in the example above) while meeting the
specification.
i2cbus is left rounded-to-closest: it is only used as the target of
the clk_error comparison and is never multiplied into the programmed
timings, so nearest rounding remains accurate there.
Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
Cc: stable@vger.kernel.org
Signed-off-by: Guillermo Rodríguez <guille.rodriguez@gmail.com>
---
drivers/i2c/busses/i2c-stm32f7.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index 53d9df70ebe4..6439620d6bed 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -464,8 +464,13 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
{
struct stm32f7_i2c_spec *specs;
u32 p_prev = STM32F7_PRESC_MAX;
- u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
- setup->clock_src);
+ /*
+ * Truncate instead of rounding to closest: if the clock period is
+ * overestimated, the computed SCL timings will come out shorter on
+ * the wire, which can push the bus above the target rate and below
+ * the spec's tLOW/tHIGH minimums.
+ */
+ u32 i2cclk = NSEC_PER_SEC / setup->clock_src;
u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
setup->speed_freq);
u32 clk_error_prev = i2cbus;
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] i2c: stm32f7: truncate clock period instead of rounding it
2026-06-11 10:48 [PATCH] i2c: stm32f7: truncate clock period instead of rounding it Guillermo Rodríguez
@ 2026-06-14 21:34 ` Andi Shyti
2026-06-17 8:06 ` Alain Volmat
2026-06-17 8:38 ` Andi Shyti
2 siblings, 0 replies; 6+ messages in thread
From: Andi Shyti @ 2026-06-14 21:34 UTC (permalink / raw)
To: Guillermo Rodríguez
Cc: Pierre-Yves MORDRET, Alain Volmat, Maxime Coquelin,
Alexandre Torgue, M'boumba Cedric Madianga, Wolfram Sang,
Pierre-Yves MORDRET, linux-i2c, linux-stm32, linux-arm-kernel,
linux-kernel
Pierre-Yves,
any thought on this?
Andi
On Thu, Jun 11, 2026 at 12:48:56PM +0200, Guillermo Rodríguez wrote:
> stm32f7_i2c_compute_timing() derives the I2C clock source period
> (i2cclk) with DIV_ROUND_CLOSEST, which may round it up. When the
> period is overestimated, all timings computed from it (SCLDEL,
> SDADEL, SCLL, SCLH) come out shorter on the wire than calculated,
> and the resulting bus rate can exceed the requested speed, violating
> the I2C specification minimums for tLOW and tHIGH.
>
> For example, with a 104.45 MHz clock source (e.g. PCLK1, the
> reset-default I2C clock source on STM32MP1), i2cclk is rounded from
> 9.574 ns up to 10 ns. Requesting a 400 kHz fast mode bus with
> 72/27 ns rise/fall times and no analog/digital filters then produces
> an actual bus rate of 415.6 kHz with tLOW = 1254 ns, violating both
> the 400 kHz maximum rate and the 1300 ns tLOW minimum of the
> specification.
>
> Truncate the period instead, so that it can only be underestimated.
> The error then falls on the safe side: the programmed timings come
> out slightly longer than computed and the bus runs marginally below
> the target rate (375.3 kHz in the example above) while meeting the
> specification.
>
> i2cbus is left rounded-to-closest: it is only used as the target of
> the clk_error comparison and is never multiplied into the programmed
> timings, so nearest rounding remains accurate there.
>
> Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guillermo Rodríguez <guille.rodriguez@gmail.com>
> ---
> drivers/i2c/busses/i2c-stm32f7.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
> index 53d9df70ebe4..6439620d6bed 100644
> --- a/drivers/i2c/busses/i2c-stm32f7.c
> +++ b/drivers/i2c/busses/i2c-stm32f7.c
> @@ -464,8 +464,13 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
> {
> struct stm32f7_i2c_spec *specs;
> u32 p_prev = STM32F7_PRESC_MAX;
> - u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
> - setup->clock_src);
> + /*
> + * Truncate instead of rounding to closest: if the clock period is
> + * overestimated, the computed SCL timings will come out shorter on
> + * the wire, which can push the bus above the target rate and below
> + * the spec's tLOW/tHIGH minimums.
> + */
> + u32 i2cclk = NSEC_PER_SEC / setup->clock_src;
> u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
> setup->speed_freq);
> u32 clk_error_prev = i2cbus;
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] i2c: stm32f7: truncate clock period instead of rounding it
2026-06-11 10:48 [PATCH] i2c: stm32f7: truncate clock period instead of rounding it Guillermo Rodríguez
2026-06-14 21:34 ` Andi Shyti
@ 2026-06-17 8:06 ` Alain Volmat
2026-06-17 8:16 ` Pierre Yves MORDRET
2026-06-17 8:38 ` Andi Shyti
2 siblings, 1 reply; 6+ messages in thread
From: Alain Volmat @ 2026-06-17 8:06 UTC (permalink / raw)
To: Guillermo Rodríguez
Cc: Pierre-Yves MORDRET, Andi Shyti, Maxime Coquelin,
Alexandre Torgue, M'boumba Cedric Madianga, Wolfram Sang,
Pierre-Yves MORDRET, linux-i2c, linux-stm32, linux-arm-kernel,
linux-kernel
Hi Guillermo,
make sense indeed. Thanks a lot for this patch.
On Thu, Jun 11, 2026 at 12:48:56PM +0200, Guillermo Rodríguez wrote:
> stm32f7_i2c_compute_timing() derives the I2C clock source period
> (i2cclk) with DIV_ROUND_CLOSEST, which may round it up. When the
> period is overestimated, all timings computed from it (SCLDEL,
> SDADEL, SCLL, SCLH) come out shorter on the wire than calculated,
> and the resulting bus rate can exceed the requested speed, violating
> the I2C specification minimums for tLOW and tHIGH.
>
> For example, with a 104.45 MHz clock source (e.g. PCLK1, the
> reset-default I2C clock source on STM32MP1), i2cclk is rounded from
> 9.574 ns up to 10 ns. Requesting a 400 kHz fast mode bus with
> 72/27 ns rise/fall times and no analog/digital filters then produces
> an actual bus rate of 415.6 kHz with tLOW = 1254 ns, violating both
> the 400 kHz maximum rate and the 1300 ns tLOW minimum of the
> specification.
>
> Truncate the period instead, so that it can only be underestimated.
> The error then falls on the safe side: the programmed timings come
> out slightly longer than computed and the bus runs marginally below
> the target rate (375.3 kHz in the example above) while meeting the
> specification.
>
> i2cbus is left rounded-to-closest: it is only used as the target of
> the clk_error comparison and is never multiplied into the programmed
> timings, so nearest rounding remains accurate there.
>
> Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guillermo Rodríguez <guille.rodriguez@gmail.com>
> ---
> drivers/i2c/busses/i2c-stm32f7.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
> index 53d9df70ebe4..6439620d6bed 100644
> --- a/drivers/i2c/busses/i2c-stm32f7.c
> +++ b/drivers/i2c/busses/i2c-stm32f7.c
> @@ -464,8 +464,13 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
> {
> struct stm32f7_i2c_spec *specs;
> u32 p_prev = STM32F7_PRESC_MAX;
> - u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
> - setup->clock_src);
> + /*
> + * Truncate instead of rounding to closest: if the clock period is
> + * overestimated, the computed SCL timings will come out shorter on
> + * the wire, which can push the bus above the target rate and below
> + * the spec's tLOW/tHIGH minimums.
> + */
> + u32 i2cclk = NSEC_PER_SEC / setup->clock_src;
> u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
> setup->speed_freq);
> u32 clk_error_prev = i2cbus;
> --
> 2.25.1
>
Acked-by: Alain Volmat <alain.volmat@foss.st.com>
Regards,
Alain
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] i2c: stm32f7: truncate clock period instead of rounding it
2026-06-17 8:06 ` Alain Volmat
@ 2026-06-17 8:16 ` Pierre Yves MORDRET
0 siblings, 0 replies; 6+ messages in thread
From: Pierre Yves MORDRET @ 2026-06-17 8:16 UTC (permalink / raw)
To: Alain Volmat, Guillermo Rodríguez
Cc: Andi Shyti, Maxime Coquelin, Alexandre Torgue,
M'boumba Cedric Madianga, Wolfram Sang, Pierre-Yves MORDRET,
linux-i2c, linux-stm32, linux-arm-kernel, linux-kernel
Hi all,
Look good to me.
Best Regards
Reviewed-by: Pierre-Yves MORDRET <pierre-yves.mordret@foss.st.com>
On 6/17/26 10:06, Alain Volmat wrote:
> Hi Guillermo,
>
> make sense indeed. Thanks a lot for this patch.
>
> On Thu, Jun 11, 2026 at 12:48:56PM +0200, Guillermo Rodríguez wrote:
>> stm32f7_i2c_compute_timing() derives the I2C clock source period
>> (i2cclk) with DIV_ROUND_CLOSEST, which may round it up. When the
>> period is overestimated, all timings computed from it (SCLDEL,
>> SDADEL, SCLL, SCLH) come out shorter on the wire than calculated,
>> and the resulting bus rate can exceed the requested speed, violating
>> the I2C specification minimums for tLOW and tHIGH.
>>
>> For example, with a 104.45 MHz clock source (e.g. PCLK1, the
>> reset-default I2C clock source on STM32MP1), i2cclk is rounded from
>> 9.574 ns up to 10 ns. Requesting a 400 kHz fast mode bus with
>> 72/27 ns rise/fall times and no analog/digital filters then produces
>> an actual bus rate of 415.6 kHz with tLOW = 1254 ns, violating both
>> the 400 kHz maximum rate and the 1300 ns tLOW minimum of the
>> specification.
>>
>> Truncate the period instead, so that it can only be underestimated.
>> The error then falls on the safe side: the programmed timings come
>> out slightly longer than computed and the bus runs marginally below
>> the target rate (375.3 kHz in the example above) while meeting the
>> specification.
>>
>> i2cbus is left rounded-to-closest: it is only used as the target of
>> the clk_error comparison and is never multiplied into the programmed
>> timings, so nearest rounding remains accurate there.
>>
>> Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Guillermo Rodríguez <guille.rodriguez@gmail.com>
>> ---
>> drivers/i2c/busses/i2c-stm32f7.c | 9 +++++++--
>> 1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
>> index 53d9df70ebe4..6439620d6bed 100644
>> --- a/drivers/i2c/busses/i2c-stm32f7.c
>> +++ b/drivers/i2c/busses/i2c-stm32f7.c
>> @@ -464,8 +464,13 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
>> {
>> struct stm32f7_i2c_spec *specs;
>> u32 p_prev = STM32F7_PRESC_MAX;
>> - u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
>> - setup->clock_src);
>> + /*
>> + * Truncate instead of rounding to closest: if the clock period is
>> + * overestimated, the computed SCL timings will come out shorter on
>> + * the wire, which can push the bus above the target rate and below
>> + * the spec's tLOW/tHIGH minimums.
>> + */
>> + u32 i2cclk = NSEC_PER_SEC / setup->clock_src;
>> u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
>> setup->speed_freq);
>> u32 clk_error_prev = i2cbus;
>> --
>> 2.25.1
>>
>
> Acked-by: Alain Volmat <alain.volmat@foss.st.com>
>
> Regards,
> Alain
--
--
~ Py MORDRET
--
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] i2c: stm32f7: truncate clock period instead of rounding it
2026-06-11 10:48 [PATCH] i2c: stm32f7: truncate clock period instead of rounding it Guillermo Rodríguez
2026-06-14 21:34 ` Andi Shyti
2026-06-17 8:06 ` Alain Volmat
@ 2026-06-17 8:38 ` Andi Shyti
2026-06-17 9:13 ` Guillermo Rodriguez Garcia
2 siblings, 1 reply; 6+ messages in thread
From: Andi Shyti @ 2026-06-17 8:38 UTC (permalink / raw)
To: Guillermo Rodríguez
Cc: Pierre-Yves MORDRET, Alain Volmat, Maxime Coquelin,
Alexandre Torgue, M'boumba Cedric Madianga, Wolfram Sang,
Pierre-Yves MORDRET, linux-i2c, linux-stm32, linux-arm-kernel,
linux-kernel
Hi Guillermo,
On Thu, Jun 11, 2026 at 12:48:56PM +0200, Guillermo Rodríguez wrote:
> stm32f7_i2c_compute_timing() derives the I2C clock source period
> (i2cclk) with DIV_ROUND_CLOSEST, which may round it up. When the
> period is overestimated, all timings computed from it (SCLDEL,
> SDADEL, SCLL, SCLH) come out shorter on the wire than calculated,
> and the resulting bus rate can exceed the requested speed, violating
> the I2C specification minimums for tLOW and tHIGH.
>
> For example, with a 104.45 MHz clock source (e.g. PCLK1, the
> reset-default I2C clock source on STM32MP1), i2cclk is rounded from
> 9.574 ns up to 10 ns. Requesting a 400 kHz fast mode bus with
> 72/27 ns rise/fall times and no analog/digital filters then produces
> an actual bus rate of 415.6 kHz with tLOW = 1254 ns, violating both
> the 400 kHz maximum rate and the 1300 ns tLOW minimum of the
> specification.
>
> Truncate the period instead, so that it can only be underestimated.
> The error then falls on the safe side: the programmed timings come
> out slightly longer than computed and the bus runs marginally below
> the target rate (375.3 kHz in the example above) while meeting the
> specification.
>
> i2cbus is left rounded-to-closest: it is only used as the target of
> the clk_error comparison and is never multiplied into the programmed
> timings, so nearest rounding remains accurate there.
>
> Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Guillermo Rodríguez <guille.rodriguez@gmail.com>
Merged to i2c/i2c-host.
Thanks to Alain and Pierre-Yves for their review!
Andi
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] i2c: stm32f7: truncate clock period instead of rounding it
2026-06-17 8:38 ` Andi Shyti
@ 2026-06-17 9:13 ` Guillermo Rodriguez Garcia
0 siblings, 0 replies; 6+ messages in thread
From: Guillermo Rodriguez Garcia @ 2026-06-17 9:13 UTC (permalink / raw)
To: Andi Shyti
Cc: Pierre-Yves MORDRET, Alain Volmat, Maxime Coquelin,
Alexandre Torgue, M'boumba Cedric Madianga, Wolfram Sang,
Pierre-Yves MORDRET, linux-i2c, linux-stm32, linux-arm-kernel,
linux-kernel
Hi,
Thank you everyone.
A possible improvement would be to derive the clock period in
picoseconds rather than ns and do all the timing calculations based on
that.
This would reduce the rounding error (from max 1ns to max 1ps) and
help the solver find TIMINGR values closer to the target bus
frequency, while still keeping both freq and tLOW within spec.
I wanted to keep this patch minimal to address the spec violation
itself, and also to make it easier to backport to stable. The
suggested improvement is a bit more involved, but I wanted to mention
it in case you want to consider it.
Thanks,
Guillermo
El mié, 17 jun 2026 a las 10:38, Andi Shyti (<andi.shyti@kernel.org>) escribió:
>
> Hi Guillermo,
>
> On Thu, Jun 11, 2026 at 12:48:56PM +0200, Guillermo Rodríguez wrote:
> > stm32f7_i2c_compute_timing() derives the I2C clock source period
> > (i2cclk) with DIV_ROUND_CLOSEST, which may round it up. When the
> > period is overestimated, all timings computed from it (SCLDEL,
> > SDADEL, SCLL, SCLH) come out shorter on the wire than calculated,
> > and the resulting bus rate can exceed the requested speed, violating
> > the I2C specification minimums for tLOW and tHIGH.
> >
> > For example, with a 104.45 MHz clock source (e.g. PCLK1, the
> > reset-default I2C clock source on STM32MP1), i2cclk is rounded from
> > 9.574 ns up to 10 ns. Requesting a 400 kHz fast mode bus with
> > 72/27 ns rise/fall times and no analog/digital filters then produces
> > an actual bus rate of 415.6 kHz with tLOW = 1254 ns, violating both
> > the 400 kHz maximum rate and the 1300 ns tLOW minimum of the
> > specification.
> >
> > Truncate the period instead, so that it can only be underestimated.
> > The error then falls on the safe side: the programmed timings come
> > out slightly longer than computed and the bus runs marginally below
> > the target rate (375.3 kHz in the example above) while meeting the
> > specification.
> >
> > i2cbus is left rounded-to-closest: it is only used as the target of
> > the clk_error comparison and is never multiplied into the programmed
> > timings, so nearest rounding remains accurate there.
> >
> > Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Guillermo Rodríguez <guille.rodriguez@gmail.com>
>
> Merged to i2c/i2c-host.
>
> Thanks to Alain and Pierre-Yves for their review!
>
> Andi
--
Guillermo Rodriguez Garcia
guille.rodriguez@gmail.com
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-17 9:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-11 10:48 [PATCH] i2c: stm32f7: truncate clock period instead of rounding it Guillermo Rodríguez
2026-06-14 21:34 ` Andi Shyti
2026-06-17 8:06 ` Alain Volmat
2026-06-17 8:16 ` Pierre Yves MORDRET
2026-06-17 8:38 ` Andi Shyti
2026-06-17 9:13 ` Guillermo Rodriguez Garcia
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox