i2c: designware_i2c: check is high speed possible support
authorJun Chen <jun.chen@vatics.com>
Mon, 2 Mar 2020 08:58:55 +0000 (16:58 +0800)
committerHeiko Schocher <hs@denx.de>
Mon, 16 Mar 2020 07:04:09 +0000 (08:04 +0100)
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
drivers/i2c/designware_i2c.h

index 9186fcb..f4fbf3b 100644 (file)
@@ -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(&regs->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;
index 61a882c..23f311b 100644 (file)
@@ -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
  *