Skip to content

Commit 087591c

Browse files
dlechbroonie
authored andcommitted
spi: axi-spi-engine: optimize bits_per_word for offload
Add an optimization to avoid repeating bits_per_word instructions in each message when using SPI offload. This only applies when all data xfers in a message have the same bits_per_word. In this case, we can execute the instruction that sets bits_per_word when the offload trigger is enabled. This is useful e.g. for obtaining higher sample rates on ADCs since each message takes less time to execute. Signed-off-by: David Lechner <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 8fc13b8 commit 087591c

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ struct spi_engine_offload {
142142
unsigned long flags;
143143
unsigned int offload_num;
144144
unsigned int spi_mode_config;
145+
u8 bits_per_word;
145146
};
146147

147148
struct spi_engine {
@@ -267,6 +268,8 @@ static int spi_engine_precompile_message(struct spi_message *msg)
267268
{
268269
unsigned int clk_div, max_hz = msg->spi->controller->max_speed_hz;
269270
struct spi_transfer *xfer;
271+
u8 min_bits_per_word = U8_MAX;
272+
u8 max_bits_per_word = 0;
270273

271274
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
272275
/* If we have an offload transfer, we can't rx to buffer */
@@ -275,6 +278,24 @@ static int spi_engine_precompile_message(struct spi_message *msg)
275278

276279
clk_div = DIV_ROUND_UP(max_hz, xfer->speed_hz);
277280
xfer->effective_speed_hz = max_hz / min(clk_div, 256U);
281+
282+
if (xfer->len) {
283+
min_bits_per_word = min(min_bits_per_word, xfer->bits_per_word);
284+
max_bits_per_word = max(max_bits_per_word, xfer->bits_per_word);
285+
}
286+
}
287+
288+
/*
289+
* If all xfers in the message use the same bits_per_word, we can
290+
* provide some optimization when using SPI offload.
291+
*/
292+
if (msg->offload) {
293+
struct spi_engine_offload *priv = msg->offload->priv;
294+
295+
if (min_bits_per_word == max_bits_per_word)
296+
priv->bits_per_word = min_bits_per_word;
297+
else
298+
priv->bits_per_word = 0;
278299
}
279300

280301
return 0;
@@ -306,6 +327,12 @@ static void spi_engine_compile_message(struct spi_message *msg, bool dry,
306327
if (msg->offload) {
307328
priv = msg->offload->priv;
308329
priv->spi_mode_config = spi_engine_get_config(spi);
330+
331+
/*
332+
* If all xfers use the same bits_per_word, it can be optimized
333+
* in the same way.
334+
*/
335+
bits_per_word = priv->bits_per_word;
309336
} else {
310337
spi_engine_program_add_cmd(p, dry,
311338
SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CONFIG,
@@ -862,6 +889,11 @@ static int spi_engine_trigger_enable(struct spi_offload *offload)
862889
priv->spi_mode_config),
863890
spi_engine->base + SPI_ENGINE_REG_CMD_FIFO);
864891

892+
if (priv->bits_per_word)
893+
writel_relaxed(SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_XFER_BITS,
894+
priv->bits_per_word),
895+
spi_engine->base + SPI_ENGINE_REG_CMD_FIFO);
896+
865897
writel_relaxed(SPI_ENGINE_CMD_SYNC(1),
866898
spi_engine->base + SPI_ENGINE_REG_CMD_FIFO);
867899

0 commit comments

Comments
 (0)