Commit Graph

2 Commits

Author SHA1 Message Date
88a1f14cad lpss_i2c: Set SDA hold and support custom speed config
This I2C controller has separate registers for different speeds to set
specific timing for SCL high and low times, and then a single register
to configure the SDA hold time.

For the most part these values can be generated based on the freq of
the controller clock, which is SOC-specific.  The existing driver was
generating SCL HCNT/LCNT values, but not the SDA hold time so that is
added.

Additionally a board may need custom values as the exact timing can
depend on trace lengths and the number of devices on the I2C bus. This
is a two-part customizaton, the first is to set the values for desired
speed for use within firmware, and the second is to provide those
values in ACPI for the OS driver to consume.

And finally, recent upstream changes to the designware i2c driver in
the Linux kernel now support passing custom timing values for high
speed and fast-plus speed, so these are now supported as well.

Since these custom speed configs will come from devicetree a macro is
added to simplify the description:

register "i2c[4].speed_config" = "{
	 LPSS_I2C_SPEED_CONFIG(STANDARD, 432, 507, 30),
	 LPSS_I2C_SPEED_CONFIG(FAST, 72, 160, 30),
	 LPSS_I2C_SPEED_CONFIG(FAST_PLUS, 52, 120, 30),
	 LPSS_I2C_SPEED_CONFIG(HIGH, 38, 90, 30),
}"

Which will result in the following speed config in \_SB.PCI0.I2C4:

Name (SSCN, Package () { 432, 507, 30 })
Name (FMCN, Package () { 72, 160, 30 })
Name (FPCN, Package () { 52, 120, 30 })
Name (HSCN, Package () { 38, 90, 30 })

Change-Id: I18964426bb83fad0c956ad43a36ed9e04f3a66b5
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/15163
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2016-06-21 19:32:24 +02:00
8a14c39ac6 soc/intel/common: Add LPSS I2C driver
Add a generic LPSS I2C driver for Intel SOCs that use the Synopsys
DesignWare I2C block and have a similar configuration of that block.

This driver is ported from the Chromium depthcharge project where it
was ported from U-Boot originally, though it looks very different now.
From depthcharge it has been modified to fit into the coreboot I2C
driver model with platform_i2c_transfer() and use coreboot semantics
throughout including the stopwatch API for timeouts.

In order for this shared driver to work the SOC must:

1) Define CONFIG_SOC_INTEL_COMMON_LPSS_I2C_CLOCK_MHZ to set the clock
speed that the I2C controller core is running at.

2) Define the lpss_i2c_base_address() function to return the base
address for the specified bus.  This could be either done by looking
up the PCI device or a static table if the controllers are not PCI
devices and just have a static base address.

The driver is usable in verstage/romstage/ramstage, though it does
require early initialization of the controller to set a temporary base
address if it is used outside of ramstage.

This has been tested on Broadwell and Skylake SOCs in both pre-RAM and
ramstage environments by reading and writing both single bytes across
multiple segments as well as large blocks of data at once and with
different configured bus speeds.

While it does need specific configuration for each SOC this driver
should be able to work on all Intel SOCs currently in src/soc/intel.

Change-Id: Ibe492e53c45edb1d1745ec75e1ff66004081717e
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/15101
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2016-06-09 17:06:05 +02:00