Commit 80d40626 authored by Sowjanya Komatineni's avatar Sowjanya Komatineni Committed by Wolfram Sang

i2c: tegra: update transfer timeout

Tegra194 allows max of 64K bytes and Tegra186 and prior allows
max of 4K bytes of transfer per packet.

one sec timeout is not enough for transfers more than 10K bytes
at STD bus rate.

This patch updates I2C transfer timeout based on the transfer size
and I2C bus rate to allow enough time during max transfer size at
lower bus speed.
Acked-by: default avatarThierry Reding <treding@nvidia.com>
Reviewed-by: default avatarDmitry Osipenko <digetx@gmail.com>
Signed-off-by: default avatarSowjanya Komatineni <skomatineni@nvidia.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 86c92b99
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/reset.h> #include <linux/reset.h>
#define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000))
#define BYTES_PER_FIFO_WORD 4 #define BYTES_PER_FIFO_WORD 4
#define I2C_CNFG 0x000 #define I2C_CNFG 0x000
...@@ -936,7 +935,7 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap) ...@@ -936,7 +935,7 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE); tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
time_left = wait_for_completion_timeout(&i2c_dev->msg_complete, time_left = wait_for_completion_timeout(&i2c_dev->msg_complete,
TEGRA_I2C_TIMEOUT); msecs_to_jiffies(50));
if (time_left == 0) { if (time_left == 0) {
dev_err(i2c_dev->dev, "timed out for bus clear\n"); dev_err(i2c_dev->dev, "timed out for bus clear\n");
return -ETIMEDOUT; return -ETIMEDOUT;
...@@ -963,6 +962,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, ...@@ -963,6 +962,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
u32 *buffer = NULL; u32 *buffer = NULL;
int err = 0; int err = 0;
bool dma; bool dma;
u16 xfer_time = 100;
tegra_i2c_flush_fifos(i2c_dev); tegra_i2c_flush_fifos(i2c_dev);
...@@ -982,6 +982,12 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, ...@@ -982,6 +982,12 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
i2c_dev->dma_buf; i2c_dev->dma_buf;
tegra_i2c_config_fifo_trig(i2c_dev, xfer_size); tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
dma = i2c_dev->is_curr_dma_xfer; dma = i2c_dev->is_curr_dma_xfer;
/*
* Transfer time in mSec = Total bits / transfer rate
* Total bits = 9 bits per byte (including ACK bit) + Start & stop bits
*/
xfer_time += DIV_ROUND_CLOSEST(((xfer_size * 9) + 2) * MSEC_PER_SEC,
i2c_dev->bus_clk_rate);
spin_lock_irqsave(&i2c_dev->xfer_lock, flags); spin_lock_irqsave(&i2c_dev->xfer_lock, flags);
int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
...@@ -1085,7 +1091,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, ...@@ -1085,7 +1091,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
time_left = wait_for_completion_timeout( time_left = wait_for_completion_timeout(
&i2c_dev->dma_complete, &i2c_dev->dma_complete,
TEGRA_I2C_TIMEOUT); msecs_to_jiffies(xfer_time));
if (time_left == 0) { if (time_left == 0) {
dev_err(i2c_dev->dev, "DMA transfer timeout\n"); dev_err(i2c_dev->dev, "DMA transfer timeout\n");
dmaengine_terminate_sync(i2c_dev->msg_read ? dmaengine_terminate_sync(i2c_dev->msg_read ?
...@@ -1111,7 +1117,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, ...@@ -1111,7 +1117,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
} }
time_left = wait_for_completion_timeout(&i2c_dev->msg_complete, time_left = wait_for_completion_timeout(&i2c_dev->msg_complete,
TEGRA_I2C_TIMEOUT); msecs_to_jiffies(xfer_time));
tegra_i2c_mask_irq(i2c_dev, int_mask); tegra_i2c_mask_irq(i2c_dev, int_mask);
if (time_left == 0) { if (time_left == 0) {
...@@ -1390,6 +1396,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) ...@@ -1390,6 +1396,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
i2c_dev->div_clk = div_clk; i2c_dev->div_clk = div_clk;
i2c_dev->adapter.algo = &tegra_i2c_algo; i2c_dev->adapter.algo = &tegra_i2c_algo;
i2c_dev->adapter.retries = 1; i2c_dev->adapter.retries = 1;
i2c_dev->adapter.timeout = 6 * HZ;
i2c_dev->irq = irq; i2c_dev->irq = irq;
i2c_dev->cont_id = pdev->id; i2c_dev->cont_id = pdev->id;
i2c_dev->dev = &pdev->dev; i2c_dev->dev = &pdev->dev;
......
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