Skip to content

Commit

Permalink
can: mcp25xxfd: rx-path: reduce number of SPI core requests to set UI…
Browse files Browse the repository at this point in the history
…NC bit

Reduce the number of separate SPI core requests when setting the UINC bit in
the RX FIFO, and instead batch them up into a single SPI core request.

Link: https://github.com/marckleinebudde/linux/issues/4
Link: https://lore.kernel.org/r/20201126132144.351154-3-mkl@pengutronix.de
Tested-by: Thomas Kopp <thomas.kopp@microchip.com>
Signed-off-by: Ursula Maplehurst <ursula@kangatronix.co.uk>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
  • Loading branch information
Ursula Maplehurst authored and Marc Kleine-Budde committed Nov 29, 2020
1 parent 4843ad9 commit 1f652bb
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
51 changes: 43 additions & 8 deletions drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
u32 val;
u16 addr;
u8 len;
int i;
int i, j;

/* TEF */
priv->tef.head = 0;
Expand Down Expand Up @@ -370,6 +370,23 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
prev_rx_ring->obj_num;

prev_rx_ring = rx_ring;

/* FIFO increment RX tail pointer */
addr = MCP251XFD_REG_FIFOCON(rx_ring->fifo_nr);
val = MCP251XFD_REG_FIFOCON_UINC;
len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->uinc_buf,
addr, val, val);

for (j = 0; j < ARRAY_SIZE(rx_ring->uinc_xfer); j++) {
struct spi_transfer *xfer;

xfer = &rx_ring->uinc_xfer[j];
xfer->tx_buf = &rx_ring->uinc_buf;
xfer->len = len;
xfer->cs_change = 1;
xfer->cs_change_delay.value = 0;
xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
}
}
}

Expand Down Expand Up @@ -1440,13 +1457,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv,
if (err)
stats->rx_fifo_errors++;

ring->tail++;

/* finally increment the RX pointer */
return regmap_update_bits(priv->map_reg,
MCP251XFD_REG_FIFOCON(ring->fifo_nr),
GENMASK(15, 8),
MCP251XFD_REG_FIFOCON_UINC);
return 0;
}

static inline int
Expand Down Expand Up @@ -1478,6 +1489,8 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
return err;

while ((len = mcp251xfd_get_rx_linear_len(ring))) {
struct spi_transfer *last_xfer;

rx_tail = mcp251xfd_get_rx_tail(ring);

err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj,
Expand All @@ -1492,6 +1505,28 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
if (err)
return err;
}

/* Increment the RX FIFO tail pointer 'len' times in a
* single SPI message.
*/
ring->tail += len;

/* Note:
*
* "cs_change == 1" on the last transfer results in an
* active chip select after the complete SPI
* message. This causes the controller to interpret
* the next register access as data. Temporary set
* "cs_change" of the last transfer to "0" to properly
* deactivate the chip select at the end of the
* message.
*/
last_xfer = &ring->uinc_xfer[len - 1];
last_xfer->cs_change = 0;
err = spi_sync_transfer(priv->spi, ring->uinc_xfer, len);
last_xfer->cs_change = 1;
if (err)
return err;
}

return 0;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/can/spi/mcp251xfd/mcp251xfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,8 @@ struct mcp251xfd_rx_ring {
u8 obj_num;
u8 obj_size;

union mcp251xfd_write_reg_buf uinc_buf;
struct spi_transfer uinc_xfer[MCP251XFD_RX_OBJ_NUM_MAX];
struct mcp251xfd_hw_rx_obj_canfd obj[];
};

Expand Down

0 comments on commit 1f652bb

Please sign in to comment.