diff options
author | David Lechner <dlechner@baylibre.com> | 2023-12-04 20:33:28 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2023-12-06 17:19:30 +0300 |
commit | 9d023ecc31859c7f7c8ca27b5fec52b2dbb8086f (patch) | |
tree | 6f3905e804724f952544b02339ea0f78db3496b8 | |
parent | 2e0d75f8dd9e31b3fb175f780494dd7dd988ceae (diff) | |
download | linux-9d023ecc31859c7f7c8ca27b5fec52b2dbb8086f.tar.xz |
spi: axi-spi-engine: populate xfer->effective_speed_hz
This adds a new spi_engine_precompile_message() function to the ADI AXI
SPI Engine driver to populate the xfer->effective_speed_hz field since
the SPI core doesn't/can't do this for us.
This driver is already using spi_delay_to_ns() which depends on
effective_speed_hz to get an accurate value in some cases.
Having an effective_speed_hz value can also be used in future changes
to simplify other code.
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-2-063672323fce@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-axi-spi-engine.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index 982b37ac3063..ee7b904ae5cf 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c @@ -218,6 +218,27 @@ static void spi_engine_gen_cs(struct spi_engine_program *p, bool dry, spi_engine_program_add_cmd(p, dry, SPI_ENGINE_CMD_ASSERT(1, mask)); } +/* + * Performs precompile steps on the message. + * + * The SPI core does most of the message/transfer validation and filling in + * fields for us via __spi_validate(). This fixes up anything remaining not + * done there. + * + * NB: This is separate from spi_engine_compile_message() because the latter + * is called twice and would otherwise result in double-evaluation. + */ +static void spi_engine_precompile_message(struct spi_message *msg) +{ + unsigned int clk_div, max_hz = msg->spi->controller->max_speed_hz; + struct spi_transfer *xfer; + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + clk_div = DIV_ROUND_UP(max_hz, xfer->speed_hz); + xfer->effective_speed_hz = max_hz / min(clk_div, 256U); + } +} + static void spi_engine_compile_message(struct spi_engine *spi_engine, struct spi_message *msg, bool dry, struct spi_engine_program *p) { @@ -504,6 +525,8 @@ static int spi_engine_prepare_message(struct spi_controller *host, if (!st) return -ENOMEM; + spi_engine_precompile_message(msg); + p_dry.length = 0; spi_engine_compile_message(spi_engine, msg, true, &p_dry); |