Commit 9ee4a955 authored by Furquan Shaikh's avatar Furquan Shaikh Committed by chrome-bot
Browse files

i2c/designware: Do not re-initialize bus if configured by coreboot



Coreboot is taking a lot of effort reading device-tree values for
fall/rise time or lcnt/hcnt and calculating and configuring
controller register values to ensure I2C bus speed is within limits
when used in firmware. Depthcharge driver was resetting all those
values by using default configuration. This resulted in I2C bus speed
in depthcharge going beyond limits. (Noticed by sudden spike in H1 I2C
frequency in depthcharge).

This change updates the designware I2C driver to check if high and low
cycle time registers are already configured and skip initialization
of the bus completely.

BUG=b:35948024
BRANCH=eve
TEST=Verified that H1 I2C frequency is <400KHz in coreboot and in
depthcharge. No spikes observed after jumping to depthcharge. Also, no
errors seen while communicating with H1 in depthcharge.

Change-Id: Icc2d2d45710a203325d1780f80e2e8d024c8c9a4
Signed-off-by: default avatarFurquan Shaikh <furquan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/592550

Reviewed-by: default avatarDuncan Laurie <dlaurie@google.com>
parent d35a0175
......@@ -230,6 +230,45 @@ static int i2c_set_bus_speed(DesignwareI2c *bus)
return 0;
}
/*
* i2c_speed_init_done - Check if bus speed is already configured
* @high_reg: high cycle time register
* @low_reg: low cycle time register
*
* Check if high and low cycle time registers are configured.
*
*/
static int i2c_speed_init_done(uint32_t *high_reg, uint32_t *low_reg)
{
/*
* If both high_reg and low_reg are set to non-zero value, assume that
* the bus speed is already configured.
*/
return readl(high_reg) && readl(low_reg);
}
/*
* i2c_bus_initialized - Check if coreboot already initialized bus
* @bus: i2c bus description structure
*
* Check if coreboot already initializaed the bus.
*
*/
static int i2c_bus_initialized(DesignwareI2c *bus)
{
DesignwareI2cRegs *regs = bus->regs;
if (bus->speed >= MAX_SPEED_HZ)
return i2c_speed_init_done(&regs->hs_scl_hcnt,
&regs->hs_scl_lcnt);
else if (bus->speed >= FAST_SPEED_HZ)
return i2c_speed_init_done(&regs->fs_scl_hcnt,
&regs->fs_scl_lcnt);
return i2c_speed_init_done(&regs->ss_scl_hcnt,
&regs->ss_scl_lcnt);
}
/*
* i2c_init - Init function.
* @bus: i2c bus description structure
......@@ -241,6 +280,15 @@ static void i2c_init(DesignwareI2c *bus)
{
DesignwareI2cRegs *regs = bus->regs;
/*
* If bus is already initialized in coreboot, skip initialization here
* and set bus->initialized to 1 directly.
*/
if (i2c_bus_initialized(bus)) {
bus->initialized = 1;
return;
}
/* Disable controller. */
i2c_disable(regs);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment