aboutsummaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2020-01-23 11:48:15 -0700
committerHeiko Schocher <hs@denx.de>2020-01-27 07:22:01 +0100
commit96fe11c3dace9038e2df0e7c4625d1c3e330425f (patch)
tree031e52df4c897ca563ccf299ba16b2eaa7fe53bd /drivers/i2c
parente71b6f6622d6a3380d866943799f36e473a3cd9b (diff)
downloadu-boot-96fe11c3dace9038e2df0e7c4625d1c3e330425f.zip
u-boot-96fe11c3dace9038e2df0e7c4625d1c3e330425f.tar.gz
u-boot-96fe11c3dace9038e2df0e7c4625d1c3e330425f.tar.bz2
i2c: designware_i2c: Add spike supression
Some versions of this peripheral include a spike-suppression phase of the bus. Add support for this. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Heiko Schocher <hs@denx.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/designware_i2c.c10
-rw-r--r--drivers/i2c/designware_i2c.h2
-rw-r--r--drivers/i2c/designware_i2c_pci.c2
3 files changed, 13 insertions, 1 deletions
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 0069602..4aee25c 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -220,6 +220,7 @@ static unsigned int __dw_i2c_set_bus_speed(struct dw_i2c *priv,
enum i2c_speed_mode i2c_spd;
unsigned int cntl;
unsigned int ena;
+ int spk_cnt;
int ret;
if (priv)
@@ -241,6 +242,13 @@ static unsigned int __dw_i2c_set_bus_speed(struct dw_i2c *priv,
cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK));
+ /* Get the proper spike-suppression count based on target speed */
+ if (!priv || !priv->has_spk_cnt)
+ spk_cnt = 0;
+ else if (i2c_spd >= IC_SPEED_MODE_HIGH)
+ spk_cnt = readl(&i2c_base->hs_spklen);
+ else
+ spk_cnt = readl(&i2c_base->fs_spklen);
if (scl_sda_cfg) {
config.sda_hold = scl_sda_cfg->sda_hold;
if (i2c_spd == IC_SPEED_MODE_STANDARD) {
@@ -251,7 +259,7 @@ static unsigned int __dw_i2c_set_bus_speed(struct dw_i2c *priv,
config.scl_lcnt = scl_sda_cfg->fs_lcnt;
}
} else {
- ret = dw_i2c_calc_timing(priv, i2c_spd, bus_clk, 0,
+ ret = dw_i2c_calc_timing(priv, i2c_spd, bus_clk, spk_cnt,
&config);
if (ret)
return log_msg_ret("gen_confg", ret);
diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h
index f32dc0f..8789c7d 100644
--- a/drivers/i2c/designware_i2c.h
+++ b/drivers/i2c/designware_i2c.h
@@ -176,6 +176,7 @@ struct dw_scl_sda_cfg {
* @scl_rise_time_ns: Configured SCL rise time in nanoseconds
* @scl_fall_time_ns: Configured SCL fall time in nanoseconds
* @sda_hold_time_ns: Configured SDA hold time in nanoseconds
+ * @has_spk_cnt: true if the spike-count register is present
* @clk: Clock input to the I2C controller
*/
struct dw_i2c {
@@ -185,6 +186,7 @@ struct dw_i2c {
u32 scl_rise_time_ns;
u32 scl_fall_time_ns;
u32 sda_hold_time_ns;
+ bool has_spk_cnt;
#if CONFIG_IS_ENABLED(CLK)
struct clk clk;
#endif
diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index 2b974a0..50f03e3 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -62,6 +62,8 @@ static int designware_i2c_pci_ofdata_to_platdata(struct udevice *dev)
if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL))
/* Use BayTrail specific timing values */
priv->scl_sda_cfg = &byt_config;
+ if (dev_get_driver_data(dev) == INTEL_APL)
+ priv->has_spk_cnt = true;
return designware_i2c_ofdata_to_platdata(dev);
}