v7:
Resubmit the patch based on version 5.15-rc1
v6:
1. Add the judgment condition, clear the handshake signal between dma and
i2c when multiple msgs are transmitted.
v5:
1. Replace the previous variable name "default_timing_adjust" with "use-default-timing"
2. Added waiting for dma reset mechanism
3. Remove received patch(dt-bindings: i2c: update bindings for MT8195 SOC)
v4:
1. Remove the repeated assignment of the inter_clk_div parameter
2. Modify the wrong assignment of OFFSET_MULTI_DMA
3. Unify the log print format of the i2c_dump_register() and drop the extra outer parentheses
4. Place the fixes at the very least
5. Add fixed tags 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183")
6. Add "i2c: mediatek: modify bus speed calculation formula"
7. Fix single line characters exceeding 80 characters
8. Combine two different series of patches.
v3:
1. Fix code errors caused by v2 modification
v2:
1. Add "dt-bindings: i2c: add attribute default-timing-adjust"
2. Split the fix into sepatate patch.
Kewei Xu (5):
i2c: mediatek: Reset the handshake signal between i2c and dma
i2c: mediatek: Dump i2c/dma register when a timeout occurs
dt-bindings: i2c: add attribute use-default-timing
i2c: mediatek: Isolate speed setting via dts for special devices
i2c: mediatek: modify bus speed calculation formula
.../devicetree/bindings/i2c/i2c-mt65xx.txt | 2 +
drivers/i2c/busses/i2c-mt65xx.c | 192 ++++++++++++++++--
2 files changed, 180 insertions(+), 14 deletions(-)
--
2.18.0
When clock-div is 0 or greater than 1, the bus speed
calculated by the old speed calculation formula will be
larger than the target speed. So we update the formula.
Signed-off-by: Kewei Xu <[email protected]>
Reviewed-by: Qii Wang <[email protected]>
---
drivers/i2c/busses/i2c-mt65xx.c | 35 +++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 3db4ed3f9050..ad07647f88d5 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -68,11 +68,12 @@
#define I2C_DEFAULT_CLK_DIV 5
#define MAX_SAMPLE_CNT_DIV 8
#define MAX_STEP_CNT_DIV 64
-#define MAX_CLOCK_DIV 256
+#define MAX_CLOCK_DIV_8BITS 256
+#define MAX_CLOCK_DIV_5BITS 32
#define MAX_HS_STEP_CNT_DIV 8
-#define I2C_STANDARD_MODE_BUFFER (1000 / 2)
-#define I2C_FAST_MODE_BUFFER (300 / 2)
-#define I2C_FAST_MODE_PLUS_BUFFER (20 / 2)
+#define I2C_STANDARD_MODE_BUFFER (1000 / 3)
+#define I2C_FAST_MODE_BUFFER (300 / 3)
+#define I2C_FAST_MODE_PLUS_BUFFER (20 / 3)
#define I2C_CONTROL_RS (0x1 << 1)
#define I2C_CONTROL_DMA_EN (0x1 << 2)
@@ -724,14 +725,26 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
unsigned int best_mul;
unsigned int cnt_mul;
int ret = -EINVAL;
+ int clock_div_constraint = 0;
if (target_speed > I2C_MAX_HIGH_SPEED_MODE_FREQ)
target_speed = I2C_MAX_HIGH_SPEED_MODE_FREQ;
+ if (i2c->use_default_timing) {
+ clock_div_constraint = 0;
+ } else if (i2c->dev_comp->ltiming_adjust &&
+ i2c->ac_timing.inter_clk_div > 1) {
+ clock_div_constraint = 1;
+ } else if (i2c->dev_comp->ltiming_adjust &&
+ i2c->ac_timing.inter_clk_div == 0) {
+ clock_div_constraint = -1;
+ }
+
max_step_cnt = mtk_i2c_max_step_cnt(target_speed);
base_step_cnt = max_step_cnt;
/* Find the best combination */
- opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
+ opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed) +
+ clock_div_constraint;
best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
/* Search for the best pair (sample_cnt, step_cnt) with
@@ -766,7 +779,8 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
sample_cnt = base_sample_cnt;
step_cnt = base_step_cnt;
- if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
+ if ((clk_src / (2 * (sample_cnt * step_cnt - clock_div_constraint))) >
+ target_speed) {
/* In this case, hardware can't support such
* low i2c_bus_freq
*/
@@ -853,13 +867,16 @@ static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
target_speed = i2c->speed_hz;
parent_clk /= i2c->clk_src_div;
- if (i2c->dev_comp->timing_adjust)
- max_clk_div = MAX_CLOCK_DIV;
+ if (i2c->dev_comp->timing_adjust && i2c->dev_comp->ltiming_adjust)
+ max_clk_div = MAX_CLOCK_DIV_5BITS;
+ else if (i2c->dev_comp->timing_adjust)
+ max_clk_div = MAX_CLOCK_DIV_8BITS;
else
max_clk_div = 1;
for (clk_div = 1; clk_div <= max_clk_div; clk_div++) {
clk_src = parent_clk / clk_div;
+ i2c->ac_timing.inter_clk_div = clk_div - 1;
if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) {
/* Set master code speed register */
@@ -906,8 +923,6 @@ static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
break;
}
- i2c->ac_timing.inter_clk_div = clk_div - 1;
-
return 0;
}
--
2.25.1
Add attribute use-default-timing for DT-binding document.
Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <[email protected]>
Acked-by: Rob Herring <[email protected]>
Reviewed-by: Qii Wang <[email protected]>
---
Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
index 5ea216ae7084..4dbb69745ff3 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
@@ -34,6 +34,8 @@ Optional properties:
Only mt6589 and mt8135 support this feature.
- mediatek,use-push-pull: IO config use push-pull mode.
- vbus-supply: phandle to the regulator that provides power to SCL/SDA.
+ - mediatek,use-default-timing: use default timing calculation, no timing
+ adjustment.
Example:
--
2.25.1