aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-mt65xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-mt65xx.c')
-rw-r--r--drivers/i2c/busses/i2c-mt65xx.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index aec8e6ce38a4..453358b4d9ca 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -60,6 +60,7 @@
60#define I2C_DMA_INT_FLAG_NONE 0x0000 60#define I2C_DMA_INT_FLAG_NONE 0x0000
61#define I2C_DMA_CLR_FLAG 0x0000 61#define I2C_DMA_CLR_FLAG 0x0000
62#define I2C_DMA_HARD_RST 0x0002 62#define I2C_DMA_HARD_RST 0x0002
63#define I2C_DMA_4G_MODE 0x0001
63 64
64#define I2C_DEFAULT_SPEED 100000 /* hz */ 65#define I2C_DEFAULT_SPEED 100000 /* hz */
65#define MAX_FS_MODE_SPEED 400000 66#define MAX_FS_MODE_SPEED 400000
@@ -88,6 +89,8 @@ enum DMA_REGS_OFFSET {
88 OFFSET_RX_MEM_ADDR = 0x20, 89 OFFSET_RX_MEM_ADDR = 0x20,
89 OFFSET_TX_LEN = 0x24, 90 OFFSET_TX_LEN = 0x24,
90 OFFSET_RX_LEN = 0x28, 91 OFFSET_RX_LEN = 0x28,
92 OFFSET_TX_4G_MODE = 0x54,
93 OFFSET_RX_4G_MODE = 0x58,
91}; 94};
92 95
93enum i2c_trans_st_rs { 96enum i2c_trans_st_rs {
@@ -133,6 +136,7 @@ struct mtk_i2c_compatible {
133 unsigned char dcm: 1; 136 unsigned char dcm: 1;
134 unsigned char auto_restart: 1; 137 unsigned char auto_restart: 1;
135 unsigned char aux_len_reg: 1; 138 unsigned char aux_len_reg: 1;
139 unsigned char support_33bits: 1;
136}; 140};
137 141
138struct mtk_i2c { 142struct mtk_i2c {
@@ -182,6 +186,7 @@ static const struct mtk_i2c_compatible mt6577_compat = {
182 .dcm = 1, 186 .dcm = 1,
183 .auto_restart = 0, 187 .auto_restart = 0,
184 .aux_len_reg = 0, 188 .aux_len_reg = 0,
189 .support_33bits = 0,
185}; 190};
186 191
187static const struct mtk_i2c_compatible mt6589_compat = { 192static const struct mtk_i2c_compatible mt6589_compat = {
@@ -190,6 +195,7 @@ static const struct mtk_i2c_compatible mt6589_compat = {
190 .dcm = 0, 195 .dcm = 0,
191 .auto_restart = 0, 196 .auto_restart = 0,
192 .aux_len_reg = 0, 197 .aux_len_reg = 0,
198 .support_33bits = 0,
193}; 199};
194 200
195static const struct mtk_i2c_compatible mt8173_compat = { 201static const struct mtk_i2c_compatible mt8173_compat = {
@@ -198,6 +204,7 @@ static const struct mtk_i2c_compatible mt8173_compat = {
198 .dcm = 1, 204 .dcm = 1,
199 .auto_restart = 1, 205 .auto_restart = 1,
200 .aux_len_reg = 1, 206 .aux_len_reg = 1,
207 .support_33bits = 1,
201}; 208};
202 209
203static const struct of_device_id mtk_i2c_of_match[] = { 210static const struct of_device_id mtk_i2c_of_match[] = {
@@ -366,6 +373,11 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk,
366 return 0; 373 return 0;
367} 374}
368 375
376static inline u32 mtk_i2c_set_4g_mode(dma_addr_t addr)
377{
378 return (addr & BIT_ULL(32)) ? I2C_DMA_4G_MODE : I2C_DMA_CLR_FLAG;
379}
380
369static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, 381static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
370 int num, int left_num) 382 int num, int left_num)
371{ 383{
@@ -373,6 +385,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
373 u16 start_reg; 385 u16 start_reg;
374 u16 control_reg; 386 u16 control_reg;
375 u16 restart_flag = 0; 387 u16 restart_flag = 0;
388 u32 reg_4g_mode;
376 dma_addr_t rpaddr = 0; 389 dma_addr_t rpaddr = 0;
377 dma_addr_t wpaddr = 0; 390 dma_addr_t wpaddr = 0;
378 int ret; 391 int ret;
@@ -439,6 +452,12 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
439 msgs->len, DMA_FROM_DEVICE); 452 msgs->len, DMA_FROM_DEVICE);
440 if (dma_mapping_error(i2c->dev, rpaddr)) 453 if (dma_mapping_error(i2c->dev, rpaddr))
441 return -ENOMEM; 454 return -ENOMEM;
455
456 if (i2c->dev_comp->support_33bits) {
457 reg_4g_mode = mtk_i2c_set_4g_mode(rpaddr);
458 writel(reg_4g_mode, i2c->pdmabase + OFFSET_RX_4G_MODE);
459 }
460
442 writel((u32)rpaddr, i2c->pdmabase + OFFSET_RX_MEM_ADDR); 461 writel((u32)rpaddr, i2c->pdmabase + OFFSET_RX_MEM_ADDR);
443 writel(msgs->len, i2c->pdmabase + OFFSET_RX_LEN); 462 writel(msgs->len, i2c->pdmabase + OFFSET_RX_LEN);
444 } else if (i2c->op == I2C_MASTER_WR) { 463 } else if (i2c->op == I2C_MASTER_WR) {
@@ -448,6 +467,12 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
448 msgs->len, DMA_TO_DEVICE); 467 msgs->len, DMA_TO_DEVICE);
449 if (dma_mapping_error(i2c->dev, wpaddr)) 468 if (dma_mapping_error(i2c->dev, wpaddr))
450 return -ENOMEM; 469 return -ENOMEM;
470
471 if (i2c->dev_comp->support_33bits) {
472 reg_4g_mode = mtk_i2c_set_4g_mode(wpaddr);
473 writel(reg_4g_mode, i2c->pdmabase + OFFSET_TX_4G_MODE);
474 }
475
451 writel((u32)wpaddr, i2c->pdmabase + OFFSET_TX_MEM_ADDR); 476 writel((u32)wpaddr, i2c->pdmabase + OFFSET_TX_MEM_ADDR);
452 writel(msgs->len, i2c->pdmabase + OFFSET_TX_LEN); 477 writel(msgs->len, i2c->pdmabase + OFFSET_TX_LEN);
453 } else { 478 } else {
@@ -465,6 +490,15 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
465 msgs->len, DMA_TO_DEVICE); 490 msgs->len, DMA_TO_DEVICE);
466 return -ENOMEM; 491 return -ENOMEM;
467 } 492 }
493
494 if (i2c->dev_comp->support_33bits) {
495 reg_4g_mode = mtk_i2c_set_4g_mode(wpaddr);
496 writel(reg_4g_mode, i2c->pdmabase + OFFSET_TX_4G_MODE);
497
498 reg_4g_mode = mtk_i2c_set_4g_mode(rpaddr);
499 writel(reg_4g_mode, i2c->pdmabase + OFFSET_RX_4G_MODE);
500 }
501
468 writel((u32)wpaddr, i2c->pdmabase + OFFSET_TX_MEM_ADDR); 502 writel((u32)wpaddr, i2c->pdmabase + OFFSET_TX_MEM_ADDR);
469 writel((u32)rpaddr, i2c->pdmabase + OFFSET_RX_MEM_ADDR); 503 writel((u32)rpaddr, i2c->pdmabase + OFFSET_RX_MEM_ADDR);
470 writel(msgs->len, i2c->pdmabase + OFFSET_TX_LEN); 504 writel(msgs->len, i2c->pdmabase + OFFSET_TX_LEN);
@@ -729,6 +763,14 @@ static int mtk_i2c_probe(struct platform_device *pdev)
729 return -EINVAL; 763 return -EINVAL;
730 } 764 }
731 765
766 if (i2c->dev_comp->support_33bits) {
767 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(33));
768 if (ret) {
769 dev_err(&pdev->dev, "dma_set_mask return error.\n");
770 return ret;
771 }
772 }
773
732 ret = mtk_i2c_clock_enable(i2c); 774 ret = mtk_i2c_clock_enable(i2c);
733 if (ret) { 775 if (ret) {
734 dev_err(&pdev->dev, "clock enable failed!\n"); 776 dev_err(&pdev->dev, "clock enable failed!\n");