[PATCH v4 22/31] i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()

From: Dmitry Osipenko
Date: Sat Sep 05 2020 - 16:43:14 EST


The code related to packet header setting up is a bit messy and makes
tegra_i2c_xfer_msg() more difficult to read than it could be. Let's
factor the packet header setup from tegra_i2c_xfer_msg() into separate
function in order to make code easier to read and follow.

Signed-off-by: Dmitry Osipenko <digetx@xxxxxxxxx>
---
drivers/i2c/busses/i2c-tegra.c | 93 ++++++++++++++++++++--------------
1 file changed, 54 insertions(+), 39 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index aa7adf8df668..129ca5a6cb85 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1134,6 +1134,57 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
return -EAGAIN;
}

+static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
+ struct i2c_msg *msg,
+ enum msg_end_type end_state)
+{
+ u32 *dma_buf = i2c_dev->dma_buf;
+ u32 packet_header;
+
+ packet_header = FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) |
+ FIELD_PREP(PACKET_HEADER0_PROTOCOL,
+ PACKET_HEADER0_PROTOCOL_I2C) |
+ FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
+ FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
+
+ if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+ *dma_buf++ = packet_header;
+ else
+ i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+
+ packet_header = msg->len - 1;
+
+ if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+ *dma_buf++ = packet_header;
+ else
+ i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+
+ packet_header = I2C_HEADER_IE_ENABLE;
+
+ if (end_state == MSG_END_CONTINUE)
+ packet_header |= I2C_HEADER_CONTINUE_XFER;
+ else if (end_state == MSG_END_REPEAT_START)
+ packet_header |= I2C_HEADER_REPEAT_START;
+
+ if (msg->flags & I2C_M_TEN) {
+ packet_header |= msg->addr;
+ packet_header |= I2C_HEADER_10BIT_ADDR;
+ } else {
+ packet_header |= msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
+ }
+
+ if (msg->flags & I2C_M_IGNORE_NAK)
+ packet_header |= I2C_HEADER_CONT_ON_NAK;
+
+ if (msg->flags & I2C_M_RD)
+ packet_header |= I2C_HEADER_READ;
+
+ if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+ *dma_buf++ = packet_header;
+ else
+ i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+}
+
static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
struct i2c_msg *msg)
{
@@ -1165,9 +1216,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
enum msg_end_type end_state)
{
unsigned long time_left, xfer_time = 100;
- u32 packet_header, int_mask;
- u32 *buffer = NULL;
size_t xfer_size;
+ u32 int_mask;
int err;

err = tegra_i2c_flush_fifos(i2c_dev);
@@ -1219,49 +1269,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
i2c_dev->dma_phys,
xfer_size,
DMA_TO_DEVICE);
- buffer = i2c_dev->dma_buf;
}
}

- packet_header = FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) |
- FIELD_PREP(PACKET_HEADER0_PROTOCOL,
- PACKET_HEADER0_PROTOCOL_I2C) |
- FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
- FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
- if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
- *buffer++ = packet_header;
- else
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
-
- packet_header = msg->len - 1;
- if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
- *buffer++ = packet_header;
- else
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
-
- packet_header = I2C_HEADER_IE_ENABLE;
- if (end_state == MSG_END_CONTINUE)
- packet_header |= I2C_HEADER_CONTINUE_XFER;
- else if (end_state == MSG_END_REPEAT_START)
- packet_header |= I2C_HEADER_REPEAT_START;
- if (msg->flags & I2C_M_TEN) {
- packet_header |= msg->addr;
- packet_header |= I2C_HEADER_10BIT_ADDR;
- } else {
- packet_header |= msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
- }
- if (msg->flags & I2C_M_IGNORE_NAK)
- packet_header |= I2C_HEADER_CONT_ON_NAK;
- if (msg->flags & I2C_M_RD)
- packet_header |= I2C_HEADER_READ;
- if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
- *buffer++ = packet_header;
- else
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+ tegra_i2c_push_packet_header(i2c_dev, msg, end_state);

if (!i2c_dev->msg_read) {
if (i2c_dev->is_curr_dma_xfer) {
- memcpy(buffer, msg->buf, msg->len);
+ memcpy(i2c_dev->dma_buf, msg->buf, msg->len);
dma_sync_single_for_device(i2c_dev->dev,
i2c_dev->dma_phys,
xfer_size,
--
2.27.0