diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2016-06-21 10:41:19 -0700 |
---|---|---|
committer | Duncan Laurie <dlaurie@chromium.org> | 2016-07-01 18:51:51 +0200 |
commit | 222381e390191d7a4476642ae0e544c96349a096 (patch) | |
tree | 1958377e5a15f05aff00bc4a713d851c16783b9d /src/soc/intel/skylake/romstage | |
parent | cc37c85ab4edb0c5d3d0c3e82865b65e0f469875 (diff) | |
download | coreboot-222381e390191d7a4476642ae0e544c96349a096.tar.xz |
skylake: Generate ACPI timing values for I2C devices
Have the Skylake SOC generate ACPI timing values for the enabled I2C
controllers instead of passing it in the DSDT with static timings.
The timing values are generated from the controller clock speed and
are more accurate than the hardcoded values that were in the ASL which
were originally copied from Broadwell where the controller is running
at a different clock speed...
Additionally it is now possible for a board to override the values
using devicetree.cb. If zero is passed in for SCL HCNT or LCNT then
the kernel will generate its own timing using the same forumla, but if
the SDA hold time value is zero the kernel will NOT generate a correct
value and the SDA hold time may be incorrect.
This was tested on the Chell platform to ensure all the I2C devices on
the board are still operational with these new timing values.
Change-Id: I4feb3df9e083592792f8fadd7105e081a984a906
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/15291
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel/skylake/romstage')
-rw-r--r-- | src/soc/intel/skylake/romstage/i2c.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/soc/intel/skylake/romstage/i2c.c b/src/soc/intel/skylake/romstage/i2c.c index 64e692420e..3d2e9945c0 100644 --- a/src/soc/intel/skylake/romstage/i2c.c +++ b/src/soc/intel/skylake/romstage/i2c.c @@ -46,6 +46,8 @@ static void i2c_early_init_bus(unsigned bus) { ROMSTAGE_CONST struct soc_intel_skylake_config *config; ROMSTAGE_CONST struct device *tree_dev; + const struct lpss_i2c_speed_config *sptr; + enum i2c_speed speed; pci_devfn_t dev; unsigned devfn; uintptr_t base; @@ -84,7 +86,17 @@ static void i2c_early_init_bus(unsigned bus) write32(reg, value); /* Initialize the controller */ - lpss_i2c_init(bus, config->i2c[bus].speed ? : I2C_SPEED_FAST); + speed = config->i2c[bus].speed ? : I2C_SPEED_FAST; + lpss_i2c_init(bus, speed); + + /* Apply custom speed config if it has been set by the board */ + for (value = 0; value < LPSS_I2C_SPEED_CONFIG_COUNT; value++) { + sptr = &config->i2c[bus].speed_config[value]; + if (sptr->speed == speed) { + lpss_i2c_set_speed_config(bus, sptr); + break; + } + } } void i2c_early_init(void) |