aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2023-05-26 13:49:02 +0100
committerDaniel Golle <daniel@makrotopia.org>2023-05-29 13:04:14 +0100
commit7f0e1373f40c45e3b8c3ec4517070e8b9dec2a64 (patch)
treee8db421b98a7a8275b56d7ca525ad42741b3b9cc /target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch
parentdc2841045dec20209472938d50fdb27dc6682910 (diff)
downloadupstream-7f0e1373f40c45e3b8c3ec4517070e8b9dec2a64.tar.gz
upstream-7f0e1373f40c45e3b8c3ec4517070e8b9dec2a64.tar.bz2
upstream-7f0e1373f40c45e3b8c3ec4517070e8b9dec2a64.zip
mediatek: cleanly backport and add fix for I2C driver
Pick accepted patches from upstream Linux tree instead of having to maintain our slightly different downstream patches. Import pending patch fixing I2C on MT7981 by making sure all clocks are enabled before accessing I2C registers. Signed-off-by: Daniel Golle <daniel@makrotopia.org> (cherry picked from commit 213b7282760506ffab9151a20347d65ea70ed916)
Diffstat (limited to 'target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch')
-rw-r--r--target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch102
1 files changed, 102 insertions, 0 deletions
diff --git a/target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch b/target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch
new file mode 100644
index 0000000000..a2d2521c77
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch
@@ -0,0 +1,102 @@
+From 5b8e29e566e086ef9b5b9ea0d054370a295e1d05 Mon Sep 17 00:00:00 2001
+From: Kewei Xu <kewei.xu@mediatek.com>
+Date: Sun, 10 Oct 2021 15:05:13 +0800
+Subject: [PATCH 02/16] i2c: mediatek: Dump i2c/dma register when a timeout
+ occurs
+
+When a timeout error occurs in i2c transter, it is usually related
+to the i2c/dma IP hardware configuration. Therefore, the purpose of
+this patch is to dump the key register values of i2c/dma when a
+timeout occurs in i2c for debugging.
+
+Signed-off-by: Kewei Xu <kewei.xu@mediatek.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 54 +++++++++++++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -130,6 +130,7 @@ enum I2C_REGS_OFFSET {
+ OFFSET_HS,
+ OFFSET_SOFTRESET,
+ OFFSET_DCM_EN,
++ OFFSET_MULTI_DMA,
+ OFFSET_PATH_DIR,
+ OFFSET_DEBUGSTAT,
+ OFFSET_DEBUGCTRL,
+@@ -197,6 +198,7 @@ static const u16 mt_i2c_regs_v2[] = {
+ [OFFSET_TRANSFER_LEN_AUX] = 0x44,
+ [OFFSET_CLOCK_DIV] = 0x48,
+ [OFFSET_SOFTRESET] = 0x50,
++ [OFFSET_MULTI_DMA] = 0x8c,
+ [OFFSET_SCL_MIS_COMP_POINT] = 0x90,
+ [OFFSET_DEBUGSTAT] = 0xe4,
+ [OFFSET_DEBUGCTRL] = 0xe8,
+@@ -845,6 +847,57 @@ static int mtk_i2c_set_speed(struct mtk_
+ return 0;
+ }
+
++static void i2c_dump_register(struct mtk_i2c *i2c)
++{
++ dev_dbg(i2c->dev, "SLAVE_ADDR: 0x%x, INTR_MASK: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_SLAVE_ADDR),
++ mtk_i2c_readw(i2c, OFFSET_INTR_MASK));
++ dev_dbg(i2c->dev, "INTR_STAT: 0x%x, CONTROL: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_INTR_STAT),
++ mtk_i2c_readw(i2c, OFFSET_CONTROL));
++ dev_dbg(i2c->dev, "TRANSFER_LEN: 0x%x, TRANSAC_LEN: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN),
++ mtk_i2c_readw(i2c, OFFSET_TRANSAC_LEN));
++ dev_dbg(i2c->dev, "DELAY_LEN: 0x%x, HTIMING: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_DELAY_LEN),
++ mtk_i2c_readw(i2c, OFFSET_TIMING));
++ dev_dbg(i2c->dev, "START: 0x%x, EXT_CONF: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_START),
++ mtk_i2c_readw(i2c, OFFSET_EXT_CONF));
++ dev_dbg(i2c->dev, "HS: 0x%x, IO_CONFIG: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_HS),
++ mtk_i2c_readw(i2c, OFFSET_IO_CONFIG));
++ dev_dbg(i2c->dev, "DCM_EN: 0x%x, TRANSFER_LEN_AUX: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_DCM_EN),
++ mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN_AUX));
++ dev_dbg(i2c->dev, "CLOCK_DIV: 0x%x, FIFO_STAT: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_CLOCK_DIV),
++ mtk_i2c_readw(i2c, OFFSET_FIFO_STAT));
++ dev_dbg(i2c->dev, "DEBUGCTRL : 0x%x, DEBUGSTAT: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_DEBUGCTRL),
++ mtk_i2c_readw(i2c, OFFSET_DEBUGSTAT));
++ if (i2c->dev_comp->regs == mt_i2c_regs_v2) {
++ dev_dbg(i2c->dev, "LTIMING: 0x%x, MULTI_DMA: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_LTIMING),
++ mtk_i2c_readw(i2c, OFFSET_MULTI_DMA));
++ }
++ dev_dbg(i2c->dev, "\nDMA_INT_FLAG: 0x%x, DMA_INT_EN: 0x%x\n",
++ readl(i2c->pdmabase + OFFSET_INT_FLAG),
++ readl(i2c->pdmabase + OFFSET_INT_EN));
++ dev_dbg(i2c->dev, "DMA_EN: 0x%x, DMA_CON: 0x%x\n",
++ readl(i2c->pdmabase + OFFSET_EN),
++ readl(i2c->pdmabase + OFFSET_CON));
++ dev_dbg(i2c->dev, "DMA_TX_MEM_ADDR: 0x%x, DMA_RX_MEM_ADDR: 0x%x\n",
++ readl(i2c->pdmabase + OFFSET_TX_MEM_ADDR),
++ readl(i2c->pdmabase + OFFSET_RX_MEM_ADDR));
++ dev_dbg(i2c->dev, "DMA_TX_LEN: 0x%x, DMA_RX_LEN: 0x%x\n",
++ readl(i2c->pdmabase + OFFSET_TX_LEN),
++ readl(i2c->pdmabase + OFFSET_RX_LEN));
++ dev_dbg(i2c->dev, "DMA_TX_4G_MODE: 0x%x, DMA_RX_4G_MODE: 0x%x",
++ readl(i2c->pdmabase + OFFSET_TX_4G_MODE),
++ readl(i2c->pdmabase + OFFSET_RX_4G_MODE));
++}
++
+ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
+ int num, int left_num)
+ {
+@@ -1075,6 +1128,7 @@ static int mtk_i2c_do_transfer(struct mt
+
+ if (ret == 0) {
+ dev_dbg(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
++ i2c_dump_register(i2c);
+ mtk_i2c_init_hw(i2c);
+ return -ETIMEDOUT;
+ }