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

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.de


Signed-off-by: default avatarThomas Kopp <thomas.kopp@microchip.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent c6adf659
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -30,11 +30,23 @@ mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv,
	last_byte = mcp251xfd_last_byte_set(mask);
	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);
	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;

		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,

		/* Total length */
		len += sizeof(write_reg_buf->crc.crc);
	} else {
		len += sizeof(write_reg_buf->nocrc.cmd);
	}

	return len;
+22 −4
Original line number Diff line number Diff line
@@ -504,6 +504,11 @@ union mcp251xfd_write_reg_buf {
		u8 data[4];
		__be16 crc;
	} crc;
	struct __packed {
		struct mcp251xfd_buf_cmd cmd;
		u8 data[1];
		__be16 crc;
	} safe;
} ____cacheline_aligned;

struct mcp251xfd_tx_obj {
@@ -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);
}

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
mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd,
			    u16 addr, u16 len)
@@ -769,14 +781,20 @@ mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd,
static inline u8 *
mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv,
			union mcp251xfd_write_reg_buf *write_reg_buf,
			u16 addr)
			u16 addr, u8 len)
{
	u8 *data;

	if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) {
		if (len == 1) {
			mcp251xfd_spi_cmd_write_safe_set_addr(&write_reg_buf->safe.cmd,
							     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 {
		mcp251xfd_spi_cmd_write_nocrc(&write_reg_buf->nocrc.cmd,
					      addr);