]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
i2c: mediatek: fix I2C usability for MT7981
authorWeijie Gao <weijie.gao@mediatek.com>
Wed, 19 Jul 2023 09:16:15 +0000 (17:16 +0800)
committerTom Rini <trini@konsulko.com>
Thu, 3 Aug 2023 13:40:49 +0000 (09:40 -0400)
MT7981 actually uses MediaTek I2C controller v3 instead of v1.
This patch adds support for I2C controller v3 fix fixes the I2C usability
for MT7981.

Signed-off-by: Sam Shih <sam.shih@mediatek.com>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
drivers/i2c/mtk_i2c.c

index 5528bcd7ccead2a302505f5c2b1f6daade354259..2f331d3216ae30c28368ced7d2b8c0330dc33779 100644 (file)
@@ -183,9 +183,36 @@ static const uint mt_i2c_regs_v2[] = {
        [REG_DCM_EN] = 0xf88,
 };
 
+static const uint mt_i2c_regs_v3[] = {
+       [REG_PORT] = 0x0,
+       [REG_INTR_MASK] = 0x8,
+       [REG_INTR_STAT] = 0xc,
+       [REG_CONTROL] = 0x10,
+       [REG_TRANSFER_LEN] = 0x14,
+       [REG_TRANSAC_LEN] = 0x18,
+       [REG_DELAY_LEN] = 0x1c,
+       [REG_TIMING] = 0x20,
+       [REG_START] = 0x24,
+       [REG_EXT_CONF] = 0x28,
+       [REG_LTIMING] = 0x2c,
+       [REG_HS] = 0x30,
+       [REG_IO_CONFIG] = 0x34,
+       [REG_FIFO_ADDR_CLR] = 0x38,
+       [REG_TRANSFER_LEN_AUX] = 0x44,
+       [REG_CLOCK_DIV] = 0x48,
+       [REG_SOFTRESET] = 0x50,
+       [REG_SLAVE_ADDR] = 0x94,
+       [REG_DEBUGSTAT] = 0xe4,
+       [REG_DEBUGCTRL] = 0xe8,
+       [REG_FIFO_STAT] = 0xf4,
+       [REG_FIFO_THRESH] = 0xf8,
+       [REG_DCM_EN] = 0xf88,
+};
+
 struct mtk_i2c_soc_data {
        const uint *regs;
        uint dma_sync: 1;
+       uint ltiming_adjust: 1;
 };
 
 struct mtk_i2c_priv {
@@ -401,6 +428,10 @@ static int mtk_i2c_set_speed(struct udevice *dev, uint speed)
                                (sample_cnt << HS_SAMPLE_OFFSET) |
                                (step_cnt << HS_STEP_OFFSET);
                i2c_writel(priv, REG_HS, high_speed_reg);
+               if (priv->soc_data->ltiming_adjust) {
+                       timing_reg = (sample_cnt << 12) | (step_cnt << 9);
+                       i2c_writel(priv, REG_LTIMING, timing_reg);
+               }
        } else {
                ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
                                              &step_cnt, &sample_cnt);
@@ -412,7 +443,12 @@ static int mtk_i2c_set_speed(struct udevice *dev, uint speed)
                high_speed_reg = I2C_TIME_CLR_VALUE;
                i2c_writel(priv, REG_TIMING, timing_reg);
                i2c_writel(priv, REG_HS, high_speed_reg);
+               if (priv->soc_data->ltiming_adjust) {
+                       timing_reg = (sample_cnt << 6) | step_cnt;
+                       i2c_writel(priv, REG_LTIMING, timing_reg);
+               }
        }
+
 exit:
        if (mtk_i2c_clk_disable(priv))
                return log_msg_ret("set_speed disable clk", -1);
@@ -725,7 +761,6 @@ static int mtk_i2c_probe(struct udevice *dev)
                return log_msg_ret("probe enable clk", -1);
 
        mtk_i2c_init_hw(priv);
-
        if (mtk_i2c_clk_disable(priv))
                return log_msg_ret("probe disable clk", -1);
 
@@ -750,31 +785,37 @@ static int mtk_i2c_deblock(struct udevice *dev)
 static const struct mtk_i2c_soc_data mt76xx_soc_data = {
        .regs = mt_i2c_regs_v1,
        .dma_sync = 0,
+       .ltiming_adjust = 0,
 };
 
 static const struct mtk_i2c_soc_data mt7981_soc_data = {
-       .regs = mt_i2c_regs_v1,
+       .regs = mt_i2c_regs_v3,
        .dma_sync = 1,
+       .ltiming_adjust = 1,
 };
 
 static const struct mtk_i2c_soc_data mt7986_soc_data = {
        .regs = mt_i2c_regs_v1,
        .dma_sync = 1,
+       .ltiming_adjust = 0,
 };
 
 static const struct mtk_i2c_soc_data mt8183_soc_data = {
        .regs = mt_i2c_regs_v2,
        .dma_sync = 1,
+       .ltiming_adjust = 0,
 };
 
 static const struct mtk_i2c_soc_data mt8518_soc_data = {
        .regs = mt_i2c_regs_v1,
        .dma_sync = 0,
+       .ltiming_adjust = 0,
 };
 
 static const struct mtk_i2c_soc_data mt8512_soc_data = {
        .regs = mt_i2c_regs_v1,
        .dma_sync = 1,
+       .ltiming_adjust = 0,
 };
 
 static const struct dm_i2c_ops mtk_i2c_ops = {