Skip to content

Commit be9070b

Browse files
dlechbroonie
authored andcommitted
spi: axi-spi-engine: fix sleep ticks calculation
This fixes the sleep ticks calculation when generating sleep instructions in the AXI SPI Engine driver. The previous calculation was ignoring delays less than one microsecond and missed a microsecond to second conversion factor. This fixes the first issue by not rounding to microseconds. Now that xfer->effective_speed_hz is guaranteed to be set correctly, we can use that to simplify the calculation. This new calculation replaces the old incorrect math. Also add unit suffix to the delay variable for clarity while we are touching this. Signed-off-by: David Lechner <dlechner@baylibre.com> Acked-by: Michael Hennerich <michael.hennerich@analog.com> Acked-by: Nuno Sa <nuno.sa@analog.com> Link: https://lore.kernel.org/r/20231204-axi-spi-engine-series-2-v1-4-063672323fce@baylibre.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 1fc8dc5 commit be9070b

1 file changed

Lines changed: 10 additions & 15 deletions

File tree

drivers/spi/spi-axi-spi-engine.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -168,22 +168,17 @@ static void spi_engine_gen_xfer(struct spi_engine_program *p, bool dry,
168168
}
169169

170170
static void spi_engine_gen_sleep(struct spi_engine_program *p, bool dry,
171-
struct spi_engine *spi_engine, unsigned int clk_div,
172171
struct spi_transfer *xfer)
173172
{
174-
unsigned int spi_clk = clk_get_rate(spi_engine->ref_clk);
175173
unsigned int t;
176-
int delay;
174+
int delay_ns;
177175

178-
delay = spi_delay_to_ns(&xfer->delay, xfer);
179-
if (delay < 0)
176+
delay_ns = spi_delay_to_ns(&xfer->delay, xfer);
177+
if (delay_ns <= 0)
180178
return;
181-
delay /= 1000;
182179

183-
if (delay == 0)
184-
return;
185-
186-
t = DIV_ROUND_UP(delay * spi_clk, (clk_div + 1) * 2);
180+
/* rounding down since executing the instruction adds a couple of ticks delay */
181+
t = DIV_ROUND_DOWN_ULL((u64)delay_ns * xfer->effective_speed_hz, NSEC_PER_SEC);
187182
while (t) {
188183
unsigned int n = min(t, 256U);
189184

@@ -224,8 +219,8 @@ static void spi_engine_precompile_message(struct spi_message *msg)
224219
}
225220
}
226221

227-
static void spi_engine_compile_message(struct spi_engine *spi_engine,
228-
struct spi_message *msg, bool dry, struct spi_engine_program *p)
222+
static void spi_engine_compile_message(struct spi_message *msg, bool dry,
223+
struct spi_engine_program *p)
229224
{
230225
struct spi_device *spi = msg->spi;
231226
struct spi_controller *host = spi->controller;
@@ -261,7 +256,7 @@ static void spi_engine_compile_message(struct spi_engine *spi_engine,
261256
}
262257

263258
spi_engine_gen_xfer(p, dry, xfer);
264-
spi_engine_gen_sleep(p, dry, spi_engine, clk_div - 1, xfer);
259+
spi_engine_gen_sleep(p, dry, xfer);
265260

266261
if (xfer->cs_change) {
267262
if (list_is_last(&xfer->transfer_list, &msg->transfers)) {
@@ -515,7 +510,7 @@ static int spi_engine_prepare_message(struct spi_controller *host,
515510
spi_engine_precompile_message(msg);
516511

517512
p_dry.length = 0;
518-
spi_engine_compile_message(spi_engine, msg, true, &p_dry);
513+
spi_engine_compile_message(msg, true, &p_dry);
519514

520515
size = sizeof(*p->instructions) * (p_dry.length + 1);
521516
p = kzalloc(sizeof(*p) + size, GFP_KERNEL);
@@ -533,7 +528,7 @@ static int spi_engine_prepare_message(struct spi_controller *host,
533528

534529
st->sync_id = ret;
535530

536-
spi_engine_compile_message(spi_engine, msg, false, p);
531+
spi_engine_compile_message(msg, false, p);
537532

538533
spi_engine_program_add_cmd(p, false, SPI_ENGINE_CMD_SYNC(st->sync_id));
539534

0 commit comments

Comments
 (0)