Skip to content

Commit 05f6f72

Browse files
Qii Wangwsakernel
authored andcommitted
i2c: mediatek: Fix apdma and i2c hand-shake timeout
With the apdma remove hand-shake signal, it requirs special operation timing to reset i2c manually, otherwise the interrupt will not be triggered, i2c transmission will be timeout. Fixes: 8426fe7("i2c: mediatek: Add apdma sync in i2c driver") Signed-off-by: Qii Wang <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 0b3ea2a commit 05f6f72

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

drivers/i2c/busses/i2c-mt65xx.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@
3838
#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003
3939
#define I2C_IO_CONFIG_PUSH_PULL 0x0000
4040
#define I2C_SOFT_RST 0x0001
41+
#define I2C_HANDSHAKE_RST 0x0020
4142
#define I2C_FIFO_ADDR_CLR 0x0001
4243
#define I2C_DELAY_LEN 0x0002
4344
#define I2C_TIME_CLR_VALUE 0x0000
4445
#define I2C_TIME_DEFAULT_VALUE 0x0003
4546
#define I2C_WRRD_TRANAC_VALUE 0x0002
4647
#define I2C_RD_TRANAC_VALUE 0x0001
4748
#define I2C_SCL_MIS_COMP_VALUE 0x0000
49+
#define I2C_CHN_CLR_FLAG 0x0000
4850

4951
#define I2C_DMA_CON_TX 0x0000
5052
#define I2C_DMA_CON_RX 0x0001
@@ -54,7 +56,9 @@
5456
#define I2C_DMA_START_EN 0x0001
5557
#define I2C_DMA_INT_FLAG_NONE 0x0000
5658
#define I2C_DMA_CLR_FLAG 0x0000
59+
#define I2C_DMA_WARM_RST 0x0001
5760
#define I2C_DMA_HARD_RST 0x0002
61+
#define I2C_DMA_HANDSHAKE_RST 0x0004
5862

5963
#define MAX_SAMPLE_CNT_DIV 8
6064
#define MAX_STEP_CNT_DIV 64
@@ -475,11 +479,24 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
475479
{
476480
u16 control_reg;
477481

478-
writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
479-
udelay(50);
480-
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
481-
482-
mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET);
482+
if (i2c->dev_comp->dma_sync) {
483+
writel(I2C_DMA_WARM_RST, i2c->pdmabase + OFFSET_RST);
484+
udelay(10);
485+
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
486+
udelay(10);
487+
writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_HARD_RST,
488+
i2c->pdmabase + OFFSET_RST);
489+
mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST | I2C_SOFT_RST,
490+
OFFSET_SOFTRESET);
491+
udelay(10);
492+
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
493+
mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET);
494+
} else {
495+
writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
496+
udelay(50);
497+
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
498+
mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET);
499+
}
483500

484501
/* Set ioconfig */
485502
if (i2c->use_push_pull)

0 commit comments

Comments
 (0)