[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250618-winbond-6-16-rc1-octal-phy-upstream-v1-1-513202126013@bootlin.com>
Date: Wed, 18 Jun 2025 14:14:18 +0200
From: Miquel Raynal <miquel.raynal@...tlin.com>
To: Mark Brown <broonie@...nel.org>, Richard Weinberger <richard@....at>,
Vignesh Raghavendra <vigneshr@...com>
Cc: Yogesh S <yogeshs@...com>, Santhosh Kumar K <s-k6@...com>,
Steam Lin <STLin2@...bond.com>,
Thomas Petazzoni <thomas.petazzoni@...tlin.com>, linux-spi@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-mtd@...ts.infradead.org,
Miquel Raynal <miquel.raynal@...tlin.com>
Subject: [PATCH 1/8] spi: spi-mem: Use picoseconds for calculating the op
durations
spi_mem_calc_op_duration() is deriving the duration of a specific op, by
multiplying the number of cycles with the time a cycle will last. This
time was measured in nanoseconds, which means at high frequencies the
delta between two frequencies might not be properly catch due to
roundings.
For instance, the Winbond driver has a changing number of dummy cycles
depending on the speed, adding +8 dummy cycles when running at 166MHz
compared to 162MHz.
Both frequencies would lead to using a 6ns delay per cycle for the op
duration computation, whereas in practice there is a small difference
which actually offsets the number of extra dummy cycles on a normal page
read.
Augmenting the precision of the calculation by using picoseconds
prevents selecting a lower frequency if we can do slightly better with
another frequency involving more cycles. As a result, the above
situation leads to comparing cycles of 6024 and 6172 picoseconds which
leads to picking the most efficient variant.
Signed-off-by: Miquel Raynal <miquel.raynal@...tlin.com>
---
drivers/spi/spi-mem.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 5db0639d3b01596b6f2f2df4b914422316eb9a3f..c42c227eb2a29ccd291bdced6b9d188c3b0bfb67 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -591,9 +591,11 @@ EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq);
u64 spi_mem_calc_op_duration(struct spi_mem_op *op)
{
u64 ncycles = 0;
- u32 ns_per_cycles;
+ u64 ps_per_cycles, duration;
+
+ ps_per_cycles = 1000000000000ULL;
+ do_div(ps_per_cycles, op->max_freq);
- ns_per_cycles = 1000000000 / op->max_freq;
ncycles += ((op->cmd.nbytes * 8) / op->cmd.buswidth) / (op->cmd.dtr ? 2 : 1);
ncycles += ((op->addr.nbytes * 8) / op->addr.buswidth) / (op->addr.dtr ? 2 : 1);
@@ -603,7 +605,12 @@ u64 spi_mem_calc_op_duration(struct spi_mem_op *op)
ncycles += ((op->data.nbytes * 8) / op->data.buswidth) / (op->data.dtr ? 2 : 1);
- return ncycles * ns_per_cycles;
+ /* Derive the duration in ps */
+ duration = ncycles * ps_per_cycles;
+ /* Convert into ns */
+ do_div(duration, 1000);
+
+ return duration;
}
EXPORT_SYMBOL_GPL(spi_mem_calc_op_duration);
--
2.48.1
Powered by blists - more mailing lists