[PATCH 0/4] i2c: designware_i2c: Improvements for high speed mode

From: Jun Chen jun.chen@vatics.com
This series updates the Designware I2C driver for high speed mode, fix a bug and add some improvements.
Jun Chen (4): i2c: designware_i2c: Fix IC_CON register setting for high speed mode i2c: designware_i2c: check is high speed possible support i2c: designware_i2c: remove 'has_high_speed' i2c: designware_i2c: add 'hs_hcnt' and 'hs_lcnt' for high speed
drivers/i2c/designware_i2c.c | 18 +++++++++++++++--- drivers/i2c/designware_i2c.h | 9 +++++++-- 2 files changed, 22 insertions(+), 5 deletions(-)

From: Jun Chen jun.chen@vatics.com
IC_CON[2:1] should be 3 for high speed mode
Signed-off-by: Jun Chen ptchentw@gmail.com Signed-off-by: Jun Chen jun.chen@vatics.com ---
drivers/i2c/designware_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 0b5e70a..9186fcb 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -274,7 +274,7 @@ static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, struct i2c_regs *i2c_base,
switch (config.speed_mode) { case IC_SPEED_MODE_HIGH: - cntl |= IC_CON_SPD_SS; + cntl |= IC_CON_SPD_HS; writel(config.scl_hcnt, &i2c_base->ic_hs_scl_hcnt); writel(config.scl_lcnt, &i2c_base->ic_hs_scl_lcnt); break;

Hello Jun Chen,
Am 02.03.2020 um 09:58 schrieb Jun Chen:
From: Jun Chen jun.chen@vatics.com
IC_CON[2:1] should be 3 for high speed mode
Signed-off-by: Jun Chen ptchentw@gmail.com Signed-off-by: Jun Chen jun.chen@vatics.com
drivers/i2c/designware_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Applied to u-boot-i2c next, thanks!
bye, Heiko

From: Jun Chen jun.chen@vatics.com
To read IC_COMP_PARAM_1[3:2] to check is high speed possible, and fall back to fast mode if not.
Signed-off-by: Jun Chen ptchentw@gmail.com Signed-off-by: Jun Chen jun.chen@vatics.com ---
drivers/i2c/designware_i2c.c | 10 ++++++++++ drivers/i2c/designware_i2c.h | 3 +++ 2 files changed, 13 insertions(+)
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 9186fcb..f4fbf3b 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -203,9 +203,12 @@ static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk, const struct dw_scl_sda_cfg *scl_sda_cfg = NULL; struct i2c_regs *regs = priv->regs; enum i2c_speed_mode i2c_spd; + u32 comp_param1; int spk_cnt; int ret;
+ comp_param1 = readl(®s->comp_param1); + if (priv) scl_sda_cfg = priv->scl_sda_cfg; /* Allow high speed if there is no config, or the config allows it */ @@ -219,6 +222,13 @@ static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk, else i2c_spd = IC_SPEED_MODE_STANDARD;
+ /* Check is high speed possible and fall back to fast mode if not */ + if (i2c_spd == IC_SPEED_MODE_HIGH) { + if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK) + != DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH) + i2c_spd = IC_SPEED_MODE_FAST; + } + /* Get the proper spike-suppression count based on target speed */ if (!priv || !priv->has_spk_cnt) spk_cnt = 0; diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h index 61a882c..23f311b 100644 --- a/drivers/i2c/designware_i2c.h +++ b/drivers/i2c/designware_i2c.h @@ -138,6 +138,9 @@ struct i2c_regs { #define IC_STATUS_TFNF 0x0002 #define IC_STATUS_ACT 0x0001
+#define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH (BIT(2) | BIT(3)) +#define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK (BIT(2) | BIT(3)) + /** * struct dw_scl_sda_cfg - I2C timing configuration *

Hello Jun Chen,
Am 02.03.2020 um 09:58 schrieb Jun Chen:
From: Jun Chen jun.chen@vatics.com
To read IC_COMP_PARAM_1[3:2] to check is high speed possible, and fall back to fast mode if not.
Signed-off-by: Jun Chen ptchentw@gmail.com Signed-off-by: Jun Chen jun.chen@vatics.com
drivers/i2c/designware_i2c.c | 10 ++++++++++ drivers/i2c/designware_i2c.h | 3 +++ 2 files changed, 13 insertions(+)
Applied to u-boot-i2c next, thanks!
bye, Heiko

From: Jun Chen jun.chen@vatics.com
Remove 'has_high_speed' config since we can check high speed support from IC_COMP_PARAM_1 register.
Signed-off-by: Jun Chen ptchentw@gmail.com Signed-off-by: Jun Chen jun.chen@vatics.com ---
drivers/i2c/designware_i2c.c | 3 +-- drivers/i2c/designware_i2c.h | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index f4fbf3b..74aef77 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -212,8 +212,7 @@ static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk, if (priv) scl_sda_cfg = priv->scl_sda_cfg; /* Allow high speed if there is no config, or the config allows it */ - if (speed >= I2C_SPEED_HIGH_RATE && - (!scl_sda_cfg || scl_sda_cfg->has_high_speed)) + if (speed >= I2C_SPEED_HIGH_RATE) i2c_spd = IC_SPEED_MODE_HIGH; else if (speed >= I2C_SPEED_FAST_PLUS_RATE) i2c_spd = IC_SPEED_MODE_FAST_PLUS; diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h index 23f311b..5a04ce5 100644 --- a/drivers/i2c/designware_i2c.h +++ b/drivers/i2c/designware_i2c.h @@ -144,7 +144,6 @@ struct i2c_regs { /** * struct dw_scl_sda_cfg - I2C timing configuration * - * @has_high_speed: Support high speed (3.4Mbps) * @ss_hcnt: Standard speed high time in ns * @fs_hcnt: Fast speed high time in ns * @ss_lcnt: Standard speed low time in ns @@ -152,7 +151,6 @@ struct i2c_regs { * @sda_hold: SDA hold time */ struct dw_scl_sda_cfg { - bool has_high_speed; u32 ss_hcnt; u32 fs_hcnt; u32 ss_lcnt;

Hello Jun Chen,
Am 02.03.2020 um 09:58 schrieb Jun Chen:
From: Jun Chen jun.chen@vatics.com
Remove 'has_high_speed' config since we can check high speed support from IC_COMP_PARAM_1 register.
Signed-off-by: Jun Chen ptchentw@gmail.com Signed-off-by: Jun Chen jun.chen@vatics.com
drivers/i2c/designware_i2c.c | 3 +-- drivers/i2c/designware_i2c.h | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-)
Applied to u-boot-i2c next, thanks!
bye, Heiko

From: Jun Chen jun.chen@vatics.com
Add support for high speed if scl_sda_cfg exist.
Signed-off-by: Jun Chen ptchentw@gmail.com Signed-off-by: Jun Chen jun.chen@vatics.com ---
drivers/i2c/designware_i2c.c | 3 +++ drivers/i2c/designware_i2c.h | 4 ++++ 2 files changed, 7 insertions(+)
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 74aef77..088a6f3 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -240,6 +240,9 @@ static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk, if (i2c_spd == IC_SPEED_MODE_STANDARD) { config->scl_hcnt = scl_sda_cfg->ss_hcnt; config->scl_lcnt = scl_sda_cfg->ss_lcnt; + } else if (i2c_spd == IC_SPEED_MODE_HIGH) { + config->scl_hcnt = scl_sda_cfg->hs_hcnt; + config->scl_lcnt = scl_sda_cfg->hs_lcnt; } else { config->scl_hcnt = scl_sda_cfg->fs_hcnt; config->scl_lcnt = scl_sda_cfg->fs_lcnt; diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h index 5a04ce5..7ee2361 100644 --- a/drivers/i2c/designware_i2c.h +++ b/drivers/i2c/designware_i2c.h @@ -146,15 +146,19 @@ struct i2c_regs { * * @ss_hcnt: Standard speed high time in ns * @fs_hcnt: Fast speed high time in ns + * @hs_hcnt: High speed high time in ns * @ss_lcnt: Standard speed low time in ns * @fs_lcnt: Fast speed low time in ns + * @hs_lcnt: High speed low time in ns * @sda_hold: SDA hold time */ struct dw_scl_sda_cfg { u32 ss_hcnt; u32 fs_hcnt; + u32 hs_hcnt; u32 ss_lcnt; u32 fs_lcnt; + u32 hs_lcnt; u32 sda_hold; };

Hello Jun Chen,
Am 02.03.2020 um 09:58 schrieb Jun Chen:
From: Jun Chen jun.chen@vatics.com
Add support for high speed if scl_sda_cfg exist.
Signed-off-by: Jun Chen ptchentw@gmail.com Signed-off-by: Jun Chen jun.chen@vatics.com
drivers/i2c/designware_i2c.c | 3 +++ drivers/i2c/designware_i2c.h | 4 ++++ 2 files changed, 7 insertions(+)
Applied to u-boot-i2c next, thanks!
bye, Heiko
participants (2)
-
Heiko Schocher
-
Jun Chen