From 96fe11c3dace9038e2df0e7c4625d1c3e330425f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 23 Jan 2020 11:48:15 -0700 Subject: [PATCH] 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 Reviewed-by: Heiko Schocher --- drivers/i2c/designware_i2c.c | 10 +++++++++- drivers/i2c/designware_i2c.h | 2 ++ drivers/i2c/designware_i2c_pci.c | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 0069602103..4aee25c543 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 f32dc0f854..8789c7d8ce 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 2b974a07c3..50f03e3d90 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); } -- 2.25.1