Skip to content

Commit 4d5af83

Browse files
Wolfram Sanggregkh
authored andcommitted
i2c: rcar: handle RXDMA HW behaviour on Gen3
commit 2b16fd6 upstream. On Gen3, we can only do RXDMA once per transfer reliably. For that, we must reset the device, then we can have RXDMA once. This patch implements this. When there is no reset controller or the reset fails, RXDMA will be blocked completely. Otherwise, it will be disabled after the first RXDMA transfer. Based on a commit from the BSP by Hiromitsu Yamasaki, yet completely refactored to handle multiple read messages within one transfer. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Wolfram Sang <wsa@the-dreams.de> Cc: stable@kernel.org Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent faf578e commit 4d5af83

1 file changed

Lines changed: 51 additions & 3 deletions

File tree

drivers/i2c/busses/i2c-rcar.c

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <linux/of_device.h>
3333
#include <linux/platform_device.h>
3434
#include <linux/pm_runtime.h>
35+
#include <linux/reset.h>
3536
#include <linux/slab.h>
3637

3738
/* register offsets */
@@ -111,8 +112,9 @@
111112
#define ID_ARBLOST (1 << 3)
112113
#define ID_NACK (1 << 4)
113114
/* persistent flags */
115+
#define ID_P_NO_RXDMA (1 << 30) /* HW forbids RXDMA sometimes */
114116
#define ID_P_PM_BLOCKED (1 << 31)
115-
#define ID_P_MASK ID_P_PM_BLOCKED
117+
#define ID_P_MASK (ID_P_PM_BLOCKED | ID_P_NO_RXDMA)
116118

117119
enum rcar_i2c_type {
118120
I2C_RCAR_GEN1,
@@ -140,6 +142,8 @@ struct rcar_i2c_priv {
140142
struct dma_chan *dma_rx;
141143
struct scatterlist sg;
142144
enum dma_data_direction dma_direction;
145+
146+
struct reset_control *rstc;
143147
};
144148

145149
#define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent)
@@ -321,6 +325,11 @@ static void rcar_i2c_dma_unmap(struct rcar_i2c_priv *priv)
321325
dma_unmap_single(chan->device->dev, sg_dma_address(&priv->sg),
322326
sg_dma_len(&priv->sg), priv->dma_direction);
323327

328+
/* Gen3 can only do one RXDMA per transfer and we just completed it */
329+
if (priv->devtype == I2C_RCAR_GEN3 &&
330+
priv->dma_direction == DMA_FROM_DEVICE)
331+
priv->flags |= ID_P_NO_RXDMA;
332+
324333
priv->dma_direction = DMA_NONE;
325334
}
326335

@@ -358,8 +367,9 @@ static void rcar_i2c_dma(struct rcar_i2c_priv *priv)
358367
unsigned char *buf;
359368
int len;
360369

361-
/* Do not use DMA if it's not available or for messages < 8 bytes */
362-
if (IS_ERR(chan) || msg->len < 8)
370+
/* Do various checks to see if DMA is feasible at all */
371+
if (IS_ERR(chan) || msg->len < 8 ||
372+
(read && priv->flags & ID_P_NO_RXDMA))
363373
return;
364374

365375
if (read) {
@@ -688,6 +698,25 @@ static void rcar_i2c_release_dma(struct rcar_i2c_priv *priv)
688698
}
689699
}
690700

701+
/* I2C is a special case, we need to poll the status of a reset */
702+
static int rcar_i2c_do_reset(struct rcar_i2c_priv *priv)
703+
{
704+
int i, ret;
705+
706+
ret = reset_control_reset(priv->rstc);
707+
if (ret)
708+
return ret;
709+
710+
for (i = 0; i < LOOP_TIMEOUT; i++) {
711+
ret = reset_control_status(priv->rstc);
712+
if (ret == 0)
713+
return 0;
714+
udelay(1);
715+
}
716+
717+
return -ETIMEDOUT;
718+
}
719+
691720
static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
692721
struct i2c_msg *msgs,
693722
int num)
@@ -699,6 +728,16 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
699728

700729
pm_runtime_get_sync(dev);
701730

731+
/* Gen3 needs a reset before allowing RXDMA once */
732+
if (priv->devtype == I2C_RCAR_GEN3) {
733+
priv->flags |= ID_P_NO_RXDMA;
734+
if (!IS_ERR(priv->rstc)) {
735+
ret = rcar_i2c_do_reset(priv);
736+
if (ret == 0)
737+
priv->flags &= ~ID_P_NO_RXDMA;
738+
}
739+
}
740+
702741
rcar_i2c_init(priv);
703742

704743
ret = rcar_i2c_bus_barrier(priv);
@@ -868,6 +907,15 @@ static int rcar_i2c_probe(struct platform_device *pdev)
868907
if (ret < 0)
869908
goto out_pm_put;
870909

910+
if (priv->devtype == I2C_RCAR_GEN3) {
911+
priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
912+
if (!IS_ERR(priv->rstc)) {
913+
ret = reset_control_status(priv->rstc);
914+
if (ret < 0)
915+
priv->rstc = ERR_PTR(-ENOTSUPP);
916+
}
917+
}
918+
871919
/* Stay always active when multi-master to keep arbitration working */
872920
if (of_property_read_bool(dev->of_node, "multi-master"))
873921
priv->flags |= ID_P_PM_BLOCKED;

0 commit comments

Comments
 (0)