diff --git a/doc/device-tree-bindings/i2c/i2c-designware.txt b/doc/device-tree-bindings/i2c/i2c-designware.txt
new file mode 100644
index 0000000000000000000000000000000000000000..be766be81211c36a0fe3eeeaf11e42fcff55d8f8
--- /dev/null
+++ b/doc/device-tree-bindings/i2c/i2c-designware.txt
@@ -0,0 +1,73 @@
+* Synopsys DesignWare I2C
+
+Required properties :
+
+ - compatible : should be "snps,designware-i2c"
+                or "mscc,ocelot-i2c" with "snps,designware-i2c" for fallback
+ - reg : Offset and length of the register set for the device
+ - interrupts : <IRQ> where IRQ is the interrupt number.
+ - clocks : phandles for the clocks, see the description of clock-names below.
+   The phandle for the "ic_clk" clock is required. The phandle for the "pclk"
+   clock is optional. If a single clock is specified but no clock-name, it is
+   the "ic_clk" clock. If both clocks are listed, the "ic_clk" must be first.
+
+Recommended properties :
+
+ - clock-frequency : desired I2C bus clock frequency in Hz.
+
+Optional properties :
+
+ - clock-names : Contains the names of the clocks:
+    "ic_clk", for the core clock used to generate the external I2C clock.
+    "pclk", the interface clock, required for register access.
+
+ - reg : for "mscc,ocelot-i2c", a second register set to configure the SDA hold
+   time, named ICPU_CFG:TWI_DELAY in the datasheet.
+
+ - i2c-sda-hold-time-ns : should contain the SDA hold time in nanoseconds.
+   This option is only supported in hardware blocks version 1.11a or newer and
+   on Microsemi SoCs ("mscc,ocelot-i2c" compatible).
+
+ - i2c-scl-falling-time-ns : should contain the SCL falling time in nanoseconds.
+   This value which is by default 300ns is used to compute the tLOW period.
+
+ - i2c-sda-falling-time-ns : should contain the SDA falling time in nanoseconds.
+   This value which is by default 300ns is used to compute the tHIGH period.
+
+Examples :
+
+	i2c@f0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,designware-i2c";
+		reg = <0xf0000 0x1000>;
+		interrupts = <11>;
+		clock-frequency = <400000>;
+	};
+
+	i2c@1120000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,designware-i2c";
+		reg = <0x1120000 0x1000>;
+		interrupt-parent = <&ictl>;
+		interrupts = <12 1>;
+		clock-frequency = <400000>;
+		i2c-sda-hold-time-ns = <300>;
+		i2c-sda-falling-time-ns = <300>;
+		i2c-scl-falling-time-ns = <300>;
+	};x
+
+	i2c@1120000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x2000 0x100>;
+		clock-frequency = <400000>;
+		clocks = <&i2cclk>;
+		interrupts = <0>;
+
+		eeprom@64 {
+			compatible = "linux,slave-24c02";
+			reg = <0x40000064>;
+		};
+	};
diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c
index 763183d64920353fbbdf6d86e968a95065418971..35dc234160d9acd2bcd61667894357633582f05d 100644
--- a/drivers/i2c/ast_i2c.c
+++ b/drivers/i2c/ast_i2c.c
@@ -314,7 +314,7 @@ static int ast_i2c_set_speed(struct udevice *dev, unsigned int speed)
 	divider = i2c_rate / speed;
 
 	priv->speed = speed;
-	if (speed > I2C_HIGHSPEED_RATE) {
+	if (speed > I2C_SPEED_FAST_RATE) {
 		debug("Enable High Speed\n");
 		setbits_le32(&regs->fcr, I2CD_M_HIGH_SPEED_EN
 			     | I2CD_M_SDA_DRIVE_1T_EN
diff --git a/drivers/i2c/ast_i2c.h b/drivers/i2c/ast_i2c.h
index 401e0970f768c16b15ece2726bcb837b1fc8ce85..928785989e78a6e6fe83401258d07e69553e00b5 100644
--- a/drivers/i2c/ast_i2c.h
+++ b/drivers/i2c/ast_i2c.h
@@ -126,6 +126,4 @@ struct ast_i2c_regs {
 #define I2CD_RX_DATA_SHIFT			8
 #define I2CD_RX_DATA_MASK			(0xff << I2CD_RX_DATA_SHIFT)
 
-#define I2C_HIGHSPEED_RATE    400000
-
 #endif				/* __AST_I2C_H_ */
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index b8cdd1c661334fedd866ec100303f533c2e54042..c8c5d2c331026e18308a6ef192e96320e44ba2be 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -4,8 +4,8 @@
  * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
  */
 
-#include <clk.h>
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
 #include <i2c.h>
 #include <pci.h>
@@ -46,30 +46,220 @@ static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 }
 #endif
 
+/* High and low times in different speed modes (in ns) */
+enum {
+	/* SDA Hold Time */
+	DEFAULT_SDA_HOLD_TIME		= 300,
+};
+
+/**
+ * calc_counts() - Convert a period to a number of IC clk cycles
+ *
+ * @ic_clk: Input clock in Hz
+ * @period_ns: Period to represent, in ns
+ * @return calculated count
+ */
+static uint calc_counts(uint ic_clk, uint period_ns)
+{
+	return DIV_ROUND_UP(ic_clk / 1000 * period_ns, NANO_TO_KILO);
+}
+
+/**
+ * struct i2c_mode_info - Information about an I2C speed mode
+ *
+ * Each speed mode has its own characteristics. This struct holds these to aid
+ * calculations in dw_i2c_calc_timing().
+ *
+ * @speed: Speed in Hz
+ * @min_scl_lowtime_ns: Minimum value for SCL low period in ns
+ * @min_scl_hightime_ns: Minimum value for SCL high period in ns
+ * @def_rise_time_ns: Default rise time in ns
+ * @def_fall_time_ns: Default fall time in ns
+ */
+struct i2c_mode_info {
+	int speed;
+	int min_scl_hightime_ns;
+	int min_scl_lowtime_ns;
+	int def_rise_time_ns;
+	int def_fall_time_ns;
+};
+
+static const struct i2c_mode_info info_for_mode[] = {
+	[IC_SPEED_MODE_STANDARD] = {
+		I2C_SPEED_STANDARD_RATE,
+		MIN_SS_SCL_HIGHTIME,
+		MIN_SS_SCL_LOWTIME,
+		1000,
+		300,
+	},
+	[IC_SPEED_MODE_FAST] = {
+		I2C_SPEED_FAST_RATE,
+		MIN_FS_SCL_HIGHTIME,
+		MIN_FS_SCL_LOWTIME,
+		300,
+		300,
+	},
+	[IC_SPEED_MODE_FAST_PLUS] = {
+		I2C_SPEED_FAST_PLUS_RATE,
+		MIN_FP_SCL_HIGHTIME,
+		MIN_FP_SCL_LOWTIME,
+		260,
+		500,
+	},
+	[IC_SPEED_MODE_HIGH] = {
+		I2C_SPEED_HIGH_RATE,
+		MIN_HS_SCL_HIGHTIME,
+		MIN_HS_SCL_LOWTIME,
+		120,
+		120,
+	},
+};
+
+/**
+ * dw_i2c_calc_timing() - Calculate the timings to use for a bus
+ *
+ * @priv: Bus private information (NULL if not using driver model)
+ * @mode: Speed mode to use
+ * @ic_clk: IC clock speed in Hz
+ * @spk_cnt: Spike-suppression count
+ * @config: Returns value to use
+ * @return 0 if OK, -EINVAL if the calculation failed due to invalid data
+ */
+static int dw_i2c_calc_timing(struct dw_i2c *priv, enum i2c_speed_mode mode,
+			      int ic_clk, int spk_cnt,
+			      struct dw_i2c_speed_config *config)
+{
+	int fall_cnt, rise_cnt, min_tlow_cnt, min_thigh_cnt;
+	int hcnt, lcnt, period_cnt, diff, tot;
+	int sda_hold_time_ns, scl_rise_time_ns, scl_fall_time_ns;
+	const struct i2c_mode_info *info;
+
+	/*
+	 * Find the period, rise, fall, min tlow, and min thigh in terms of
+	 * counts of the IC clock
+	 */
+	info = &info_for_mode[mode];
+	period_cnt = ic_clk / info->speed;
+	scl_rise_time_ns = priv && priv->scl_rise_time_ns ?
+		 priv->scl_rise_time_ns : info->def_rise_time_ns;
+	scl_fall_time_ns = priv && priv->scl_fall_time_ns ?
+		 priv->scl_fall_time_ns : info->def_fall_time_ns;
+	rise_cnt = calc_counts(ic_clk, scl_rise_time_ns);
+	fall_cnt = calc_counts(ic_clk, scl_fall_time_ns);
+	min_tlow_cnt = calc_counts(ic_clk, info->min_scl_lowtime_ns);
+	min_thigh_cnt = calc_counts(ic_clk, info->min_scl_hightime_ns);
+
+	debug("dw_i2c: period %d rise %d fall %d tlow %d thigh %d spk %d\n",
+	      period_cnt, rise_cnt, fall_cnt, min_tlow_cnt, min_thigh_cnt,
+	      spk_cnt);
+
+	/*
+	 * Back-solve for hcnt and lcnt according to the following equations:
+	 * SCL_High_time = [(HCNT + IC_*_SPKLEN + 7) * ic_clk] + SCL_Fall_time
+	 * SCL_Low_time = [(LCNT + 1) * ic_clk] - SCL_Fall_time + SCL_Rise_time
+	 */
+	hcnt = min_thigh_cnt - fall_cnt - 7 - spk_cnt;
+	lcnt = min_tlow_cnt - rise_cnt + fall_cnt - 1;
+
+	if (hcnt < 0 || lcnt < 0) {
+		debug("dw_i2c: bad counts. hcnt = %d lcnt = %d\n", hcnt, lcnt);
+		return -EINVAL;
+	}
+
+	/*
+	 * Now add things back up to ensure the period is hit. If it is off,
+	 * split the difference and bias to lcnt for remainder
+	 */
+	tot = hcnt + lcnt + 7 + spk_cnt + rise_cnt + 1;
+
+	if (tot < period_cnt) {
+		diff = (period_cnt - tot) / 2;
+		hcnt += diff;
+		lcnt += diff;
+		tot = hcnt + lcnt + 7 + spk_cnt + rise_cnt + 1;
+		lcnt += period_cnt - tot;
+	}
+
+	config->scl_lcnt = lcnt;
+	config->scl_hcnt = hcnt;
+
+	/* Use internal default unless other value is specified */
+	sda_hold_time_ns = priv && priv->sda_hold_time_ns ?
+		 priv->sda_hold_time_ns : DEFAULT_SDA_HOLD_TIME;
+	config->sda_hold = calc_counts(ic_clk, sda_hold_time_ns);
+
+	debug("dw_i2c: hcnt = %d lcnt = %d sda hold = %d\n", hcnt, lcnt,
+	      config->sda_hold);
+
+	return 0;
+}
+
+static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk,
+			  struct dw_i2c_speed_config *config)
+{
+	const struct dw_scl_sda_cfg *scl_sda_cfg = NULL;
+	struct i2c_regs *regs = priv->regs;
+	enum i2c_speed_mode i2c_spd;
+	int spk_cnt;
+	int ret;
+
+	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))
+		i2c_spd = IC_SPEED_MODE_HIGH;
+	else if (speed >= I2C_SPEED_FAST_RATE)
+		i2c_spd = IC_SPEED_MODE_FAST_PLUS;
+	else if (speed >= I2C_SPEED_FAST_PLUS_RATE)
+		i2c_spd = IC_SPEED_MODE_FAST;
+	else
+		i2c_spd = IC_SPEED_MODE_STANDARD;
+
+	/* 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(&regs->hs_spklen);
+	else
+		spk_cnt = readl(&regs->fs_spklen);
+	if (scl_sda_cfg) {
+		config->sda_hold = scl_sda_cfg->sda_hold;
+		if (i2c_spd == IC_SPEED_MODE_STANDARD) {
+			config->scl_hcnt = scl_sda_cfg->ss_hcnt;
+			config->scl_lcnt = scl_sda_cfg->ss_lcnt;
+		} else {
+			config->scl_hcnt = scl_sda_cfg->fs_hcnt;
+			config->scl_lcnt = scl_sda_cfg->fs_lcnt;
+		}
+	} else {
+		ret = dw_i2c_calc_timing(priv, i2c_spd, bus_clk, spk_cnt,
+					 config);
+		if (ret)
+			return log_msg_ret("gen_confg", ret);
+	}
+	config->speed_mode = i2c_spd;
+
+	return 0;
+}
+
 /*
- * i2c_set_bus_speed - Set the i2c speed
+ * _dw_i2c_set_bus_speed - Set the i2c speed
  * @speed:	required i2c speed
  *
  * Set the i2c speed.
  */
-static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
-					   struct dw_scl_sda_cfg *scl_sda_cfg,
-					   unsigned int speed,
-					   unsigned int bus_mhz)
+static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, struct i2c_regs *i2c_base,
+				 unsigned int speed, unsigned int bus_clk)
 {
+	struct dw_i2c_speed_config config;
 	unsigned int cntl;
-	unsigned int hcnt, lcnt;
 	unsigned int ena;
-	int i2c_spd;
+	int ret;
 
-	/* Allow max speed if there is no config, or the config allows it */
-	if (speed >= I2C_MAX_SPEED &&
-	    (!scl_sda_cfg || scl_sda_cfg->has_max_speed))
-		i2c_spd = IC_SPEED_MODE_MAX;
-	else if (speed >= I2C_FAST_SPEED)
-		i2c_spd = IC_SPEED_MODE_FAST;
-	else
-		i2c_spd = IC_SPEED_MODE_STANDARD;
+	ret = calc_bus_speed(priv, speed, bus_clk, &config);
+	if (ret)
+		return ret;
 
 	/* Get enable setting for restore later */
 	ena = readl(&i2c_base->ic_enable) & IC_ENABLE_0B;
@@ -79,53 +269,31 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
 
 	cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK));
 
-	switch (i2c_spd) {
-	case IC_SPEED_MODE_MAX:
+	switch (config.speed_mode) {
+	case IC_SPEED_MODE_HIGH:
 		cntl |= IC_CON_SPD_SS;
-		if (scl_sda_cfg) {
-			hcnt = scl_sda_cfg->fs_hcnt;
-			lcnt = scl_sda_cfg->fs_lcnt;
-		} else {
-			hcnt = (bus_mhz * MIN_HS_SCL_HIGHTIME) / NANO_TO_MICRO;
-			lcnt = (bus_mhz * MIN_HS_SCL_LOWTIME) / NANO_TO_MICRO;
-		}
-		writel(hcnt, &i2c_base->ic_hs_scl_hcnt);
-		writel(lcnt, &i2c_base->ic_hs_scl_lcnt);
+		writel(config.scl_hcnt, &i2c_base->ic_hs_scl_hcnt);
+		writel(config.scl_lcnt, &i2c_base->ic_hs_scl_lcnt);
 		break;
-
 	case IC_SPEED_MODE_STANDARD:
 		cntl |= IC_CON_SPD_SS;
-		if (scl_sda_cfg) {
-			hcnt = scl_sda_cfg->ss_hcnt;
-			lcnt = scl_sda_cfg->ss_lcnt;
-		} else {
-			hcnt = (bus_mhz * MIN_SS_SCL_HIGHTIME) / NANO_TO_MICRO;
-			lcnt = (bus_mhz * MIN_SS_SCL_LOWTIME) / NANO_TO_MICRO;
-		}
-		writel(hcnt, &i2c_base->ic_ss_scl_hcnt);
-		writel(lcnt, &i2c_base->ic_ss_scl_lcnt);
+		writel(config.scl_hcnt, &i2c_base->ic_ss_scl_hcnt);
+		writel(config.scl_lcnt, &i2c_base->ic_ss_scl_lcnt);
 		break;
-
+	case IC_SPEED_MODE_FAST_PLUS:
 	case IC_SPEED_MODE_FAST:
 	default:
 		cntl |= IC_CON_SPD_FS;
-		if (scl_sda_cfg) {
-			hcnt = scl_sda_cfg->fs_hcnt;
-			lcnt = scl_sda_cfg->fs_lcnt;
-		} else {
-			hcnt = (bus_mhz * MIN_FS_SCL_HIGHTIME) / NANO_TO_MICRO;
-			lcnt = (bus_mhz * MIN_FS_SCL_LOWTIME) / NANO_TO_MICRO;
-		}
-		writel(hcnt, &i2c_base->ic_fs_scl_hcnt);
-		writel(lcnt, &i2c_base->ic_fs_scl_lcnt);
+		writel(config.scl_hcnt, &i2c_base->ic_fs_scl_hcnt);
+		writel(config.scl_lcnt, &i2c_base->ic_fs_scl_lcnt);
 		break;
 	}
 
 	writel(cntl, &i2c_base->ic_con);
 
 	/* Configure SDA Hold Time if required */
-	if (scl_sda_cfg)
-		writel(scl_sda_cfg->sda_hold, &i2c_base->ic_sda_hold);
+	if (config.sda_hold)
+		writel(config.sda_hold, &i2c_base->ic_sda_hold);
 
 	/* Restore back i2c now speed set */
 	if (ena == IC_ENABLE_0B)
@@ -370,7 +538,7 @@ static int __dw_i2c_init(struct i2c_regs *i2c_base, int speed, int slaveaddr)
 	writel(IC_TX_TL, &i2c_base->ic_tx_tl);
 	writel(IC_STOP_DET, &i2c_base->ic_intr_mask);
 #ifndef CONFIG_DM_I2C
-	__dw_i2c_set_bus_speed(i2c_base, NULL, speed, IC_CLK);
+	_dw_i2c_set_bus_speed(NULL, i2c_base, speed, IC_CLK);
 	writel(slaveaddr, &i2c_base->ic_sar);
 #endif
 
@@ -415,7 +583,7 @@ static unsigned int dw_i2c_set_bus_speed(struct i2c_adapter *adap,
 					 unsigned int speed)
 {
 	adap->speed = speed;
-	return __dw_i2c_set_bus_speed(i2c_get_base(adap), NULL, speed, IC_CLK);
+	return _dw_i2c_set_bus_speed(NULL, i2c_get_base(adap), speed, IC_CLK);
 }
 
 static void dw_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
@@ -511,14 +679,10 @@ static int designware_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 	rate = clk_get_rate(&i2c->clk);
 	if (IS_ERR_VALUE(rate))
 		return -EINVAL;
-
-	/* Convert to MHz */
-	rate /= 1000000;
 #else
 	rate = IC_CLK;
 #endif
-	return __dw_i2c_set_bus_speed(i2c->regs, i2c->scl_sda_cfg, speed,
-				      rate);
+	return _dw_i2c_set_bus_speed(i2c, i2c->regs, speed, rate);
 }
 
 static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr,
@@ -537,20 +701,17 @@ static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr,
 	return ret;
 }
 
-static int designware_i2c_ofdata_to_platdata(struct udevice *bus)
-{
-	struct dw_i2c *priv = dev_get_priv(bus);
-
-	priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
-
-	return 0;
-}
-
-int designware_i2c_probe(struct udevice *bus)
+int designware_i2c_ofdata_to_platdata(struct udevice *bus)
 {
 	struct dw_i2c *priv = dev_get_priv(bus);
 	int ret;
 
+	if (!priv->regs)
+		priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
+	dev_read_u32(bus, "i2c-scl-rising-time-ns", &priv->scl_rise_time_ns);
+	dev_read_u32(bus, "i2c-scl-falling-time-ns", &priv->scl_fall_time_ns);
+	dev_read_u32(bus, "i2c-sda-hold-time-ns", &priv->sda_hold_time_ns);
+
 	ret = reset_get_bulk(bus, &priv->resets);
 	if (ret)
 		dev_warn(bus, "Can't get reset: %d\n", ret);
@@ -570,6 +731,13 @@ int designware_i2c_probe(struct udevice *bus)
 	}
 #endif
 
+	return 0;
+}
+
+int designware_i2c_probe(struct udevice *bus)
+{
+	struct dw_i2c *priv = dev_get_priv(bus);
+
 	return __dw_i2c_init(priv->regs, 0, 0);
 }
 
diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h
index 48766d080671db7d3749e6e0555af191facaf015..61a882cb650dd7a7ce2cdd91e4e89683a753ccfe 100644
--- a/drivers/i2c/designware_i2c.h
+++ b/drivers/i2c/designware_i2c.h
@@ -7,6 +7,8 @@
 #ifndef __DW_I2C_H_
 #define __DW_I2C_H_
 
+#include <clk.h>
+#include <i2c.h>
 #include <reset.h>
 
 struct i2c_regs {
@@ -43,20 +45,32 @@ struct i2c_regs {
 	u32 ic_rxflr;		/* 0x78 */
 	u32 ic_sda_hold;	/* 0x7c */
 	u32 ic_tx_abrt_source;	/* 0x80 */
-	u8 res1[0x18];		/* 0x84 */
+	u32 slv_data_nak_only;
+	u32 dma_cr;
+	u32 dma_tdlr;
+	u32 dma_rdlr;
+	u32 sda_setup;
+	u32 ack_general_call;
 	u32 ic_enable_status;	/* 0x9c */
+	u32 fs_spklen;
+	u32 hs_spklen;
+	u32 clr_restart_det;
+	u8 reserved[0xf4 - 0xac];
+	u32 comp_param1;	/* 0xf4 */
+	u32 comp_version;
+	u32 comp_type;
 };
 
-#if !defined(IC_CLK)
-#define IC_CLK			166
-#endif
-#define NANO_TO_MICRO		1000
+#define IC_CLK			166666666
+#define NANO_TO_KILO		1000000
 
 /* High and low times in different speed modes (in ns) */
 #define MIN_SS_SCL_HIGHTIME	4000
 #define MIN_SS_SCL_LOWTIME	4700
 #define MIN_FS_SCL_HIGHTIME	600
 #define MIN_FS_SCL_LOWTIME	1300
+#define MIN_FP_SCL_HIGHTIME	260
+#define MIN_FP_SCL_LOWTIME	500
 #define MIN_HS_SCL_HIGHTIME	60
 #define MIN_HS_SCL_LOWTIME	160
 
@@ -124,19 +138,10 @@ struct i2c_regs {
 #define IC_STATUS_TFNF		0x0002
 #define IC_STATUS_ACT		0x0001
 
-/* Speed Selection */
-#define IC_SPEED_MODE_STANDARD	1
-#define IC_SPEED_MODE_FAST	2
-#define IC_SPEED_MODE_MAX	3
-
-#define I2C_MAX_SPEED		3400000
-#define I2C_FAST_SPEED		400000
-#define I2C_STANDARD_SPEED	100000
-
 /**
  * struct dw_scl_sda_cfg - I2C timing configuration
  *
- * @has_max_speed: Support maximum speed (1Mbps)
+ * @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
@@ -144,7 +149,7 @@ struct i2c_regs {
  * @sda_hold: SDA hold time
  */
 struct dw_scl_sda_cfg {
-	bool has_max_speed;
+	bool has_high_speed;
 	u32 ss_hcnt;
 	u32 fs_hcnt;
 	u32 ss_lcnt;
@@ -152,10 +157,45 @@ struct dw_scl_sda_cfg {
 	u32 sda_hold;
 };
 
+/**
+ * struct dw_i2c_speed_config - timings to use for a particular speed
+ *
+ * This holds calculated values to be written to the I2C controller. Each value
+ * is represented as a number of IC clock cycles.
+ *
+ * @scl_lcnt: Low count value for SCL
+ * @scl_hcnt: High count value for SCL
+ * @sda_hold: Data hold count
+ * @speed_mode: Speed mode being used
+ */
+struct dw_i2c_speed_config {
+	/* SCL high and low period count */
+	u16 scl_lcnt;
+	u16 scl_hcnt;
+	u32 sda_hold;
+	enum i2c_speed_mode speed_mode;
+};
+
+/**
+ * struct dw_i2c - private information for the bus
+ *
+ * @regs: Registers pointer
+ * @scl_sda_cfg: Deprecated information for x86 (should move to device tree)
+ * @resets: Resets for the I2C controller
+ * @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 {
 	struct i2c_regs *regs;
 	struct dw_scl_sda_cfg *scl_sda_cfg;
 	struct reset_ctl_bulk resets;
+	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
@@ -165,5 +205,6 @@ extern const struct dm_i2c_ops designware_i2c_ops;
 
 int designware_i2c_probe(struct udevice *bus);
 int designware_i2c_remove(struct udevice *dev);
+int designware_i2c_ofdata_to_platdata(struct udevice *bus);
 
 #endif /* __DW_I2C_H_ */
diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index 7f0625df66b5bc754a0fd06a1a44b15025942bfa..50f03e3d90555f78a6c5a81fcc893a7781f4fb72 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -62,8 +62,10 @@ 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 0;
+	return designware_i2c_ofdata_to_platdata(dev);
 }
 
 static int designware_i2c_pci_probe(struct udevice *dev)
diff --git a/drivers/i2c/exynos_hs_i2c.c b/drivers/i2c/exynos_hs_i2c.c
index a0821c92578f579cdd89ca71da38e3ec9f3934e4..9f201c66d05b6903ac0de3617d37da6be1fa404c 100644
--- a/drivers/i2c/exynos_hs_i2c.c
+++ b/drivers/i2c/exynos_hs_i2c.c
@@ -527,8 +527,9 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
 
 	i2c_bus->id = pinmux_decode_periph_id(blob, node);
 
-	i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
-						  "clock-frequency", 100000);
+	i2c_bus->clock_frequency =
+		dev_read_u32_default(dev, "clock-frequency",
+				     I2C_SPEED_STANDARD_RATE);
 	i2c_bus->node = node;
 	i2c_bus->bus_num = dev->seq;
 
diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index bbbd6ef5bfdc6e5534f9293a90bd8f51ccd90729..097c54388f83416bceed19d8b996f606b2b7ab1a 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -584,7 +584,8 @@ static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
 	dev->index = dev_read_u32_default(bus, "cell-index", -1);
 	dev->slaveadd = dev_read_u32_default(bus, "u-boot,i2c-slave-addr",
 					     0x7f);
-	dev->speed = dev_read_u32_default(bus, "clock-frequency", 400000);
+	dev->speed = dev_read_u32_default(bus, "clock-frequency",
+					  I2C_SPEED_FAST_RATE);
 
 	if (!clk_get_by_index(bus, 0, &clock))
 		dev->i2c_clk = clk_get_rate(&clock);
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
index ff3956d8c23d7e7f1f0d82467c888b5c305ee66c..ac15da2c67ffea715dc5b3ece1c4b032dcd9f44b 100644
--- a/drivers/i2c/i2c-cdns.c
+++ b/drivers/i2c/i2c-cdns.c
@@ -213,7 +213,7 @@ static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
 	unsigned long speed_p = speed;
 	int ret = 0;
 
-	if (speed > 400000) {
+	if (speed > I2C_SPEED_FAST_RATE) {
 		debug("%s, failed to set clock speed to %u\n", __func__,
 		      speed);
 		return -EINVAL;
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index fe77e646193c57449d70cf5a5acb6e163c4ae8ff..2aa3efe8aaa01e7fa8f1b86109e917fd32056535 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -641,7 +641,8 @@ static int i2c_post_probe(struct udevice *dev)
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
 
-	i2c->speed_hz = dev_read_u32_default(dev, "clock-frequency", 100000);
+	i2c->speed_hz = dev_read_u32_default(dev, "clock-frequency",
+					     I2C_SPEED_STANDARD_RATE);
 
 	return dm_i2c_set_bus_speed(dev, i2c->speed_hz);
 #else
@@ -699,11 +700,10 @@ int i2c_uclass_init(struct uclass *class)
 		return -ENOMEM;
 
 	/* Get the last allocated alias. */
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-	priv->max_id = dev_read_alias_highest_id("i2c");
-#else
-	priv->max_id = -1;
-#endif
+	if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA))
+		priv->max_id = dev_read_alias_highest_id("i2c");
+	else
+		priv->max_id = -1;
 
 	debug("%s: highest alias id is %d\n", __func__, priv->max_id);
 
diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c
index ced606bf36fd179bd6f1352b3bf2fea0855a909f..62acd28e1bc0c2db4cb6bc86cf89b16e04d0fcd3 100644
--- a/drivers/i2c/i2c-uniphier-f.c
+++ b/drivers/i2c/i2c-uniphier-f.c
@@ -281,7 +281,7 @@ static int uniphier_fi2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 	struct uniphier_fi2c_regs __iomem *regs = priv->regs;
 
 	/* max supported frequency is 400 kHz */
-	if (speed > 400000)
+	if (speed > I2C_SPEED_FAST_RATE)
 		return -EINVAL;
 
 	ret = uniphier_fi2c_check_bus_busy(priv);
diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c
index e427415e7ed72b18bb2bc479982269b797909240..07a7e03033d9cbe5432c61cd2ab554716154f99a 100644
--- a/drivers/i2c/i2c-uniphier.c
+++ b/drivers/i2c/i2c-uniphier.c
@@ -177,7 +177,7 @@ static int uniphier_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 	struct uniphier_i2c_priv *priv = dev_get_priv(bus);
 
 	/* max supported frequency is 400 kHz */
-	if (speed > 400000)
+	if (speed > I2C_SPEED_FAST_RATE)
 		return -EINVAL;
 
 	/* bus reset: make sure the bus is idle when change the frequency */
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c
index 2de99d019e0869e4f7ec1d6d49c460ac40550664..c9d3faa9119f30fad2cf5b65dfa6183eb188deb3 100644
--- a/drivers/i2c/imx_lpi2c.c
+++ b/drivers/i2c/imx_lpi2c.c
@@ -169,7 +169,7 @@ static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir)
 		debug("i2c: start check busy bus: 0x%x\n", result);
 
 		/* Try to init the lpi2c then check the bus busy again */
-		bus_i2c_init(bus, 100000);
+		bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
 		result = imx_lpci2c_check_busy_bus(regs);
 		if (result) {
 			printf("i2c: Error check busy bus: 0x%x\n", result);
@@ -388,13 +388,13 @@ static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip,
 	result = bus_i2c_start(bus, chip, 0);
 	if (result) {
 		bus_i2c_stop(bus);
-		bus_i2c_init(bus, 100000);
+		bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
 		return result;
 	}
 
 	result = bus_i2c_stop(bus);
 	if (result)
-		bus_i2c_init(bus, 100000);
+		bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
 
 	return result;
 }
@@ -489,7 +489,7 @@ static int imx_lpi2c_probe(struct udevice *bus)
 			return ret;
 	}
 
-	ret = bus_i2c_init(bus, 100000);
+	ret = bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/i2c/kona_i2c.c b/drivers/i2c/kona_i2c.c
index d13e4deee59d85f40fa54d9bf093cd13d80c98f4..0726b4c9567b5c95b1614e52a0ae3b9282d29855 100644
--- a/drivers/i2c/kona_i2c.c
+++ b/drivers/i2c/kona_i2c.c
@@ -98,12 +98,6 @@ enum bcm_kona_cmd_t {
 	BCM_CMD_STOP,
 };
 
-enum bus_speed_index {
-	BCM_SPD_100K = 0,
-	BCM_SPD_400K,
-	BCM_SPD_1MHZ,
-};
-
 /* Internal divider settings for standard mode, fast mode and fast mode plus */
 struct bus_speed_cfg {
 	uint8_t time_m;		/* Number of cycles for setup time */
@@ -115,9 +109,9 @@ struct bus_speed_cfg {
 };
 
 static const struct bus_speed_cfg std_cfg_table[] = {
-	[BCM_SPD_100K] = {0x01, 0x01, 0x03, 0x06, 0x00, 0x02},
-	[BCM_SPD_400K] = {0x05, 0x01, 0x03, 0x05, 0x01, 0x02},
-	[BCM_SPD_1MHZ] = {0x01, 0x01, 0x03, 0x01, 0x01, 0x03},
+	[IC_SPEED_MODE_STANDARD] = {0x01, 0x01, 0x03, 0x06, 0x00, 0x02},
+	[IC_SPEED_MODE_FAST] = {0x05, 0x01, 0x03, 0x05, 0x01, 0x02},
+	[IC_SPEED_MODE_FAST_PLUS] = {0x01, 0x01, 0x03, 0x01, 0x01, 0x03},
 };
 
 struct bcm_kona_i2c_dev {
@@ -127,8 +121,8 @@ struct bcm_kona_i2c_dev {
 };
 
 /* Keep these two defines in sync */
-#define DEF_SPD 100000
-#define DEF_SPD_ENUM BCM_SPD_100K
+#define DEF_SPD I2C_SPEED_STANDARD_RATE
+#define DEF_SPD_ENUM IC_SPEED_MODE_STANDARD
 
 #define DEF_DEVICE(num) \
 {(void *)CONFIG_SYS_I2C_BASE##num, DEF_SPD, &std_cfg_table[DEF_SPD_ENUM]}
@@ -560,14 +554,14 @@ static uint bcm_kona_i2c_assign_bus_speed(struct bcm_kona_i2c_dev *dev,
 					  uint speed)
 {
 	switch (speed) {
-	case 100000:
-		dev->std_cfg = &std_cfg_table[BCM_SPD_100K];
+	case I2C_SPEED_STANDARD_RATE:
+		dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_STANDARD];
 		break;
-	case 400000:
-		dev->std_cfg = &std_cfg_table[BCM_SPD_400K];
+	case I2C_SPEED_FAST_RATE:
+		dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_FAST];
 		break;
-	case 1000000:
-		dev->std_cfg = &std_cfg_table[BCM_SPD_1MHZ];
+	case I2C_SPEED_FAST_PLUS_RATE:
+		dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_FAST_PLUS];
 		break;
 	default:
 		printf("%d hz bus speed not supported\n", speed);
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 8a56ef9a245977d788ca4c29934774bcd6cd5a82..63665f0952759a40e8ff98b4d2443bacc7d22599 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -434,7 +434,7 @@ void i2c_init(int speed, int slaveaddr)
 	base_glob = (struct mv_i2c *)CONFIG_MV_I2C_REG;
 #endif
 
-	if (speed > 100000)
+	if (speed > I2C_SPEED_STANDARD_RATE)
 		val = ICR_FM;
 	else
 		val = ICR_SM;
@@ -565,7 +565,7 @@ static int mv_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 	struct mv_i2c_priv *priv = dev_get_priv(bus);
 	u32 val;
 
-	if (speed > 100000)
+	if (speed > I2C_SPEED_STANDARD_RATE)
 		val = ICR_FM;
 	else
 		val = ICR_SM;
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 0a2dafcec6caceb1b0b25f1417112ae8da7657af..382cf4b30413a3379e454c83c71bc47d94560d3c 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -805,8 +805,9 @@ static int mvtwsi_i2c_ofdata_to_platdata(struct udevice *bus)
 				    "cell-index", -1);
 	dev->slaveadd = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
 				       "u-boot,i2c-slave-addr", 0x0);
-	dev->speed = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
-				    "clock-frequency", 100000);
+	dev->speed = dev_read_u32_default(bus, "clock-frequency",
+					  I2C_SPEED_STANDARD_RATE);
+
 	return 0;
 }
 
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 4b93e02bbe86b755e85e1622a2dcdb1d318fe9da..6e7d24d727b354684a9e2b9a028d2e57d38a22d3 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -306,7 +306,7 @@ static int __omap24_i2c_setspeed(void __iomem *i2c_base, int ip_rev, uint speed,
 	int hsscll = 0, hssclh = 0;
 	u32 scll = 0, sclh = 0;
 
-	if (speed >= OMAP_I2C_HIGH_SPEED) {
+	if (speed >= I2C_SPEED_HIGH_RATE) {
 		/* High speed */
 		psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK;
 		psc -= 1;
@@ -1066,7 +1066,8 @@ static int omap_i2c_ofdata_to_platdata(struct udevice *bus)
 	struct omap_i2c_platdata *plat = dev_get_platdata(bus);
 
 	plat->base = devfdt_get_addr(bus);
-	plat->speed = dev_read_u32_default(bus, "clock-frequency", 100000);
+	plat->speed = dev_read_u32_default(bus, "clock-frequency",
+					   I2C_SPEED_STANDARD_RATE);
 	plat->ip_rev = dev_get_driver_data(bus);
 
 	return 0;
diff --git a/drivers/i2c/omap24xx_i2c.h b/drivers/i2c/omap24xx_i2c.h
index 3458cf3a7dfaeab5078418108b333d821eb424e7..6904f2d9ad5bcfb370ffedacaee8d73d35637d60 100644
--- a/drivers/i2c/omap24xx_i2c.h
+++ b/drivers/i2c/omap24xx_i2c.h
@@ -81,10 +81,6 @@
 #define I2C_SCLH_HSSCLH		8
 #define I2C_SCLH_HSSCLH_M	0xFF
 
-#define OMAP_I2C_STANDARD	100000
-#define OMAP_I2C_FAST_MODE	400000
-#define OMAP_I2C_HIGH_SPEED	3400000
-
 #define SYSTEM_CLOCK_12		12000000
 #define SYSTEM_CLOCK_13		13000000
 #define SYSTEM_CLOCK_192	19200000
diff --git a/drivers/i2c/rcar_i2c.c b/drivers/i2c/rcar_i2c.c
index 2ebae349ed3c2123db58e539598e517ae468b3d7..05d0dc601210ebf788569f701db9a9f82443cbb5 100644
--- a/drivers/i2c/rcar_i2c.c
+++ b/drivers/i2c/rcar_i2c.c
@@ -344,7 +344,7 @@ static int rcar_i2c_probe(struct udevice *dev)
 	writel(0, priv->base + RCAR_I2C_ICMSR);
 	writel(0, priv->base + RCAR_I2C_ICMAR);
 
-	ret = rcar_i2c_set_speed(dev, 100000);
+	ret = rcar_i2c_set_speed(dev, I2C_SPEED_STANDARD_RATE);
 	if (ret)
 		clk_disable(&priv->clk);
 
diff --git a/drivers/i2c/rcar_iic.c b/drivers/i2c/rcar_iic.c
index 9d45f547d15313d24645df1ebf1800f68c8eb344..2a82eb0b764a081499042e9266a07d9f06c435ca 100644
--- a/drivers/i2c/rcar_iic.c
+++ b/drivers/i2c/rcar_iic.c
@@ -248,7 +248,7 @@ static int rcar_iic_probe(struct udevice *dev)
 
 	rcar_iic_finish(dev);
 
-	return rcar_iic_set_speed(dev, 100000);
+	return rcar_iic_set_speed(dev, I2C_SPEED_STANDARD_RATE);
 }
 
 static const struct dm_i2c_ops rcar_iic_ops = {
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index ad0bc69fa383e7d64e10ea72131ac9548a96b0e6..68bf93b324aaed9b6c7443a552cbbabd1751f7aa 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -313,8 +313,9 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
 
 	i2c_bus->id = pinmux_decode_periph_id(blob, node);
 
-	i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
-						  "clock-frequency", 100000);
+	i2c_bus->clock_frequency =
+		dev_read_u32_default(dev, "clock-frequency",
+				     I2C_SPEED_STANDARD_RATE);
 	i2c_bus->node = node;
 	i2c_bus->bus_num = dev->seq;
 
diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index 0dbbaa0c44730b86370b928bd67efc71dfae9ea3..1a4521d5b8e57644cd0f85fef64cc72785bc1344 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -72,7 +72,8 @@ static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
 		* 400KHz for reads.
 		*/
 		is_read = nmsgs > 1;
-		if (i2c->speed_hz > (is_read ? 400000 : 100000)) {
+		if (i2c->speed_hz > (is_read ? I2C_SPEED_FAST_RATE :
+				I2C_SPEED_STANDARD_RATE)) {
 			debug("%s: Max speed exceeded\n", __func__);
 			return -EINVAL;
 		}
diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c
index 2b18735fea6b470c02d15a1e804dab335fb14934..21dfa5023bdf94428c67d82cab2f4467c6c39fed 100644
--- a/drivers/i2c/stm32f7_i2c.c
+++ b/drivers/i2c/stm32f7_i2c.c
@@ -115,17 +115,6 @@ struct stm32_i2c_regs {
 
 #define STM32_NSEC_PER_SEC			1000000000L
 
-#define STANDARD_RATE				100000
-#define FAST_RATE				400000
-#define FAST_PLUS_RATE				1000000
-
-enum stm32_i2c_speed {
-	STM32_I2C_SPEED_STANDARD, /* 100 kHz */
-	STM32_I2C_SPEED_FAST, /* 400 kHz */
-	STM32_I2C_SPEED_FAST_PLUS, /* 1 MHz */
-	STM32_I2C_SPEED_END,
-};
-
 /**
  * struct stm32_i2c_spec - private i2c specification timing
  * @rate: I2C bus speed (Hz)
@@ -164,7 +153,7 @@ struct stm32_i2c_spec {
  * @analog_filter: Analog filter delay (On/Off)
  */
 struct stm32_i2c_setup {
-	enum stm32_i2c_speed speed;
+	enum i2c_speed_mode speed;
 	u32 speed_freq;
 	u32 clock_src;
 	u32 rise_time;
@@ -198,8 +187,8 @@ struct stm32_i2c_priv {
 };
 
 static const struct stm32_i2c_spec i2c_specs[] = {
-	[STM32_I2C_SPEED_STANDARD] = {
-		.rate = STANDARD_RATE,
+	[IC_SPEED_MODE_STANDARD] = {
+		.rate = I2C_SPEED_STANDARD_RATE,
 		.rate_min = 8000,
 		.rate_max = 120000,
 		.fall_max = 300,
@@ -210,8 +199,8 @@ static const struct stm32_i2c_spec i2c_specs[] = {
 		.l_min = 4700,
 		.h_min = 4000,
 	},
-	[STM32_I2C_SPEED_FAST] = {
-		.rate = FAST_RATE,
+	[IC_SPEED_MODE_FAST] = {
+		.rate = I2C_SPEED_FAST_RATE,
 		.rate_min = 320000,
 		.rate_max = 480000,
 		.fall_max = 300,
@@ -222,8 +211,8 @@ static const struct stm32_i2c_spec i2c_specs[] = {
 		.l_min = 1300,
 		.h_min = 600,
 	},
-	[STM32_I2C_SPEED_FAST_PLUS] = {
-		.rate = FAST_PLUS_RATE,
+	[IC_SPEED_MODE_FAST_PLUS] = {
+		.rate = I2C_SPEED_FAST_PLUS_RATE,
 		.rate_min = 800000,
 		.rate_max = 1200000,
 		.fall_max = 100,
@@ -648,9 +637,9 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv,
 	struct list_head solutions;
 	int ret;
 
-	if (setup->speed >= STM32_I2C_SPEED_END) {
+	if (setup->speed >= ARRAY_SIZE(i2c_specs)) {
 		pr_err("%s: speed out of bound {%d/%d}\n", __func__,
-		       setup->speed, STM32_I2C_SPEED_END - 1);
+		       setup->speed, ARRAY_SIZE(i2c_specs) - 1);
 		return -EINVAL;
 	}
 
@@ -719,7 +708,7 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
 		if (ret) {
 			debug("%s: failed to compute I2C timings.\n",
 			      __func__);
-			if (i2c_priv->speed > STM32_I2C_SPEED_STANDARD) {
+			if (i2c_priv->speed > IC_SPEED_MODE_STANDARD) {
 				i2c_priv->speed--;
 				setup->speed = i2c_priv->speed;
 				setup->speed_freq =
@@ -784,14 +773,14 @@ static int stm32_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 	struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus);
 
 	switch (speed) {
-	case STANDARD_RATE:
-		i2c_priv->speed = STM32_I2C_SPEED_STANDARD;
+	case I2C_SPEED_STANDARD_RATE:
+		i2c_priv->speed = IC_SPEED_MODE_STANDARD;
 		break;
-	case FAST_RATE:
-		i2c_priv->speed = STM32_I2C_SPEED_FAST;
+	case I2C_SPEED_FAST_RATE:
+		i2c_priv->speed = IC_SPEED_MODE_FAST;
 		break;
-	case FAST_PLUS_RATE:
-		i2c_priv->speed = STM32_I2C_SPEED_FAST_PLUS;
+	case I2C_SPEED_FAST_PLUS_RATE:
+		i2c_priv->speed = IC_SPEED_MODE_FAST_PLUS;
 		break;
 	default:
 		debug("%s: Speed %d not supported\n", __func__, speed);
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 7587ba2ee586ac8cf172a7b86eca64f52faea387..5d027329fe0f048c6b9ba88b84510cfcbe734872 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -89,9 +89,6 @@ typedef struct global_data {
 #endif
 #if defined(CONFIG_SYS_I2C)
 	int		cur_i2c_bus;	/* current used i2c bus */
-#endif
-#ifdef CONFIG_SYS_I2C_MXC
-	void *srdata[10];
 #endif
 	unsigned int timebase_h;
 	unsigned int timebase_l;
diff --git a/include/i2c.h b/include/i2c.h
index 72e2e8e4260e7f2f270c6c6ce07a4c0f0007c04c..0faf8542e283ac97007adeb6566d12dd5f8c8399 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -30,6 +30,32 @@ enum dm_i2c_chip_flags {
 	DM_I2C_CHIP_WR_ADDRESS	= 1 << 2, /* Send address for each write byte */
 };
 
+/** enum i2c_speed_mode - standard I2C speed modes */
+enum i2c_speed_mode {
+	IC_SPEED_MODE_STANDARD,
+	IC_SPEED_MODE_FAST,
+	IC_SPEED_MODE_FAST_PLUS,
+	IC_SPEED_MODE_HIGH,
+	IC_SPEED_MODE_FAST_ULTRA,
+
+	IC_SPEED_MODE_COUNT,
+};
+
+/** enum i2c_speed_rate - standard I2C speeds in Hz */
+enum i2c_speed_rate {
+	I2C_SPEED_STANDARD_RATE		= 100000,
+	I2C_SPEED_FAST_RATE		= 400000,
+	I2C_SPEED_FAST_PLUS_RATE	= 1000000,
+	I2C_SPEED_HIGH_RATE		= 3400000,
+	I2C_SPEED_FAST_ULTRA_RATE	= 5000000,
+};
+
+/** enum i2c_address_mode - available address modes */
+enum i2c_address_mode {
+	I2C_MODE_7_BIT,
+	I2C_MODE_10_BIT
+};
+
 struct udevice;
 /**
  * struct dm_i2c_chip - information about an i2c chip