Skip to content

Commit 8426fe7

Browse files
Qii Wangwsakernel
authored andcommitted
i2c: mediatek: Add apdma sync in i2c driver
With the apdma remove hand-shake signal, it need to keep i2c and apdma in sync manually. Reviewed-by: Yingjoe Chen <[email protected]> Reviewed-by: Matthias Brugger <[email protected]> Signed-off-by: Qii Wang <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent f46efbc commit 8426fe7

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

drivers/i2c/busses/i2c-mt65xx.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848

4949
#define I2C_DMA_CON_TX 0x0000
5050
#define I2C_DMA_CON_RX 0x0001
51+
#define I2C_DMA_ASYNC_MODE 0x0004
52+
#define I2C_DMA_SKIP_CONFIG 0x0010
53+
#define I2C_DMA_DIR_CHANGE 0x0200
5154
#define I2C_DMA_START_EN 0x0001
5255
#define I2C_DMA_INT_FLAG_NONE 0x0000
5356
#define I2C_DMA_CLR_FLAG 0x0000
@@ -205,6 +208,7 @@ struct mtk_i2c_compatible {
205208
unsigned char timing_adjust: 1;
206209
unsigned char dma_sync: 1;
207210
unsigned char ltiming_adjust: 1;
211+
unsigned char apdma_sync: 1;
208212
};
209213

210214
struct mtk_i2c_ac_timing {
@@ -311,6 +315,7 @@ static const struct mtk_i2c_compatible mt2712_compat = {
311315
.timing_adjust = 1,
312316
.dma_sync = 0,
313317
.ltiming_adjust = 0,
318+
.apdma_sync = 0,
314319
};
315320

316321
static const struct mtk_i2c_compatible mt6577_compat = {
@@ -324,6 +329,7 @@ static const struct mtk_i2c_compatible mt6577_compat = {
324329
.timing_adjust = 0,
325330
.dma_sync = 0,
326331
.ltiming_adjust = 0,
332+
.apdma_sync = 0,
327333
};
328334

329335
static const struct mtk_i2c_compatible mt6589_compat = {
@@ -337,6 +343,7 @@ static const struct mtk_i2c_compatible mt6589_compat = {
337343
.timing_adjust = 0,
338344
.dma_sync = 0,
339345
.ltiming_adjust = 0,
346+
.apdma_sync = 0,
340347
};
341348

342349
static const struct mtk_i2c_compatible mt7622_compat = {
@@ -350,6 +357,7 @@ static const struct mtk_i2c_compatible mt7622_compat = {
350357
.timing_adjust = 0,
351358
.dma_sync = 0,
352359
.ltiming_adjust = 0,
360+
.apdma_sync = 0,
353361
};
354362

355363
static const struct mtk_i2c_compatible mt8173_compat = {
@@ -362,6 +370,7 @@ static const struct mtk_i2c_compatible mt8173_compat = {
362370
.timing_adjust = 0,
363371
.dma_sync = 0,
364372
.ltiming_adjust = 0,
373+
.apdma_sync = 0,
365374
};
366375

367376
static const struct mtk_i2c_compatible mt8183_compat = {
@@ -375,6 +384,7 @@ static const struct mtk_i2c_compatible mt8183_compat = {
375384
.timing_adjust = 1,
376385
.dma_sync = 1,
377386
.ltiming_adjust = 1,
387+
.apdma_sync = 0,
378388
};
379389

380390
static const struct of_device_id mtk_i2c_of_match[] = {
@@ -798,6 +808,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
798808
u16 start_reg;
799809
u16 control_reg;
800810
u16 restart_flag = 0;
811+
u16 dma_sync = 0;
801812
u32 reg_4g_mode;
802813
u8 *dma_rd_buf = NULL;
803814
u8 *dma_wr_buf = NULL;
@@ -851,10 +862,16 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
851862
mtk_i2c_writew(i2c, num, OFFSET_TRANSAC_LEN);
852863
}
853864

865+
if (i2c->dev_comp->apdma_sync) {
866+
dma_sync = I2C_DMA_SKIP_CONFIG | I2C_DMA_ASYNC_MODE;
867+
if (i2c->op == I2C_MASTER_WRRD)
868+
dma_sync |= I2C_DMA_DIR_CHANGE;
869+
}
870+
854871
/* Prepare buffer data to start transfer */
855872
if (i2c->op == I2C_MASTER_RD) {
856873
writel(I2C_DMA_INT_FLAG_NONE, i2c->pdmabase + OFFSET_INT_FLAG);
857-
writel(I2C_DMA_CON_RX, i2c->pdmabase + OFFSET_CON);
874+
writel(I2C_DMA_CON_RX | dma_sync, i2c->pdmabase + OFFSET_CON);
858875

859876
dma_rd_buf = i2c_get_dma_safe_msg_buf(msgs, 1);
860877
if (!dma_rd_buf)
@@ -877,7 +894,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
877894
writel(msgs->len, i2c->pdmabase + OFFSET_RX_LEN);
878895
} else if (i2c->op == I2C_MASTER_WR) {
879896
writel(I2C_DMA_INT_FLAG_NONE, i2c->pdmabase + OFFSET_INT_FLAG);
880-
writel(I2C_DMA_CON_TX, i2c->pdmabase + OFFSET_CON);
897+
writel(I2C_DMA_CON_TX | dma_sync, i2c->pdmabase + OFFSET_CON);
881898

882899
dma_wr_buf = i2c_get_dma_safe_msg_buf(msgs, 1);
883900
if (!dma_wr_buf)
@@ -900,7 +917,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
900917
writel(msgs->len, i2c->pdmabase + OFFSET_TX_LEN);
901918
} else {
902919
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_INT_FLAG);
903-
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_CON);
920+
writel(I2C_DMA_CLR_FLAG | dma_sync, i2c->pdmabase + OFFSET_CON);
904921

905922
dma_wr_buf = i2c_get_dma_safe_msg_buf(msgs, 1);
906923
if (!dma_wr_buf)

0 commit comments

Comments
 (0)