Commit 2e8ca20b authored by Thomas Kopp's avatar Thomas Kopp Committed by Marc Kleine-Budde

can: mcp251xfd: regmap: optimizing transfer size for CRC transfers size 1

For CRC transfers with size 1 it is more efficient to use the
write_safe command instead of the write_crc command. This saves the
length byte on the SPI transfer.

changes since v1: https://lore.kernel.org/all/20230127124258.2764-1-thomas.kopp@microchip.com
- change logic to remove 1 level of indention

Link: https://lore.kernel.org/all/20230202141811.2581795-1-mkl@pengutronix.deSigned-off-by: default avatarThomas Kopp <thomas.kopp@microchip.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent c6adf659
...@@ -30,11 +30,23 @@ mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv, ...@@ -30,11 +30,23 @@ mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv,
last_byte = mcp251xfd_last_byte_set(mask); last_byte = mcp251xfd_last_byte_set(mask);
len = last_byte - first_byte + 1; len = last_byte - first_byte + 1;
data = mcp251xfd_spi_cmd_write(priv, write_reg_buf, reg + first_byte); data = mcp251xfd_spi_cmd_write(priv, write_reg_buf, reg + first_byte, len);
val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte); val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte);
memcpy(data, &val_le32, len); memcpy(data, &val_le32, len);
if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) { if (!(priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG)) {
len += sizeof(write_reg_buf->nocrc.cmd);
} else if (len == 1) {
u16 crc;
/* CRC */
len += sizeof(write_reg_buf->safe.cmd);
crc = mcp251xfd_crc16_compute(&write_reg_buf->safe, len);
put_unaligned_be16(crc, (void *)write_reg_buf + len);
/* Total length */
len += sizeof(write_reg_buf->safe.crc);
} else {
u16 crc; u16 crc;
mcp251xfd_spi_cmd_crc_set_len_in_reg(&write_reg_buf->crc.cmd, mcp251xfd_spi_cmd_crc_set_len_in_reg(&write_reg_buf->crc.cmd,
...@@ -46,8 +58,6 @@ mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv, ...@@ -46,8 +58,6 @@ mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv,
/* Total length */ /* Total length */
len += sizeof(write_reg_buf->crc.crc); len += sizeof(write_reg_buf->crc.crc);
} else {
len += sizeof(write_reg_buf->nocrc.cmd);
} }
return len; return len;
......
...@@ -504,6 +504,11 @@ union mcp251xfd_write_reg_buf { ...@@ -504,6 +504,11 @@ union mcp251xfd_write_reg_buf {
u8 data[4]; u8 data[4];
__be16 crc; __be16 crc;
} crc; } crc;
struct __packed {
struct mcp251xfd_buf_cmd cmd;
u8 data[1];
__be16 crc;
} safe;
} ____cacheline_aligned; } ____cacheline_aligned;
struct mcp251xfd_tx_obj { struct mcp251xfd_tx_obj {
...@@ -758,6 +763,13 @@ mcp251xfd_spi_cmd_write_crc_set_addr(struct mcp251xfd_buf_cmd_crc *cmd, ...@@ -758,6 +763,13 @@ mcp251xfd_spi_cmd_write_crc_set_addr(struct mcp251xfd_buf_cmd_crc *cmd,
cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE_CRC | addr); cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE_CRC | addr);
} }
static inline void
mcp251xfd_spi_cmd_write_safe_set_addr(struct mcp251xfd_buf_cmd *cmd,
u16 addr)
{
cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE_CRC_SAFE | addr);
}
static inline void static inline void
mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd, mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd,
u16 addr, u16 len) u16 addr, u16 len)
...@@ -769,14 +781,20 @@ mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd, ...@@ -769,14 +781,20 @@ mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd,
static inline u8 * static inline u8 *
mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv, mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv,
union mcp251xfd_write_reg_buf *write_reg_buf, union mcp251xfd_write_reg_buf *write_reg_buf,
u16 addr) u16 addr, u8 len)
{ {
u8 *data; u8 *data;
if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) { if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) {
mcp251xfd_spi_cmd_write_crc_set_addr(&write_reg_buf->crc.cmd, if (len == 1) {
addr); mcp251xfd_spi_cmd_write_safe_set_addr(&write_reg_buf->safe.cmd,
data = write_reg_buf->crc.data; addr);
data = write_reg_buf->safe.data;
} else {
mcp251xfd_spi_cmd_write_crc_set_addr(&write_reg_buf->crc.cmd,
addr);
data = write_reg_buf->crc.data;
}
} else { } else {
mcp251xfd_spi_cmd_write_nocrc(&write_reg_buf->nocrc.cmd, mcp251xfd_spi_cmd_write_nocrc(&write_reg_buf->nocrc.cmd,
addr); addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment