diff options
Diffstat (limited to 'src/soc/intel/skylake')
-rw-r--r-- | src/soc/intel/skylake/acpi/serialio.asl | 19 | ||||
-rw-r--r-- | src/soc/intel/skylake/chip.h | 3 | ||||
-rw-r--r-- | src/soc/intel/skylake/i2c.c | 47 | ||||
-rw-r--r-- | src/soc/intel/skylake/romstage/i2c.c | 14 |
4 files changed, 54 insertions, 29 deletions
diff --git a/src/soc/intel/skylake/acpi/serialio.asl b/src/soc/intel/skylake/acpi/serialio.asl index f274be83eb..849679be62 100644 --- a/src/soc/intel/skylake/acpi/serialio.asl +++ b/src/soc/intel/skylake/acpi/serialio.asl @@ -20,55 +20,36 @@ Device (I2C0) { Name (_ADR, 0x00150000) Name (_DDN, "Serial IO I2C Controller 0") - - Name (SSCN, Package () { 432, 507, 30 }) - Name (FMCN, Package () { 72, 160, 30 }) } Device (I2C1) { Name (_ADR, 0x00150001) Name (_DDN, "Serial IO I2C Controller 1") - - Name (SSCN, Package () { 528, 640, 30 }) - Name (FMCN, Package () { 128, 160, 30 }) - Name (FPCN, Package () { 48, 64, 30}) } Device (I2C2) { Name (_ADR, 0x00150002) Name (_DDN, "Serial IO I2C Controller 2") - - Name (SSCN, Package () { 432, 507, 30 }) - Name (FMCN, Package () { 72, 160, 30 }) } Device (I2C3) { Name (_ADR, 0x00150003) Name (_DDN, "Serial IO I2C Controller 3") - - Name (SSCN, Package () { 432, 507, 30 }) - Name (FMCN, Package () { 72, 160, 30 }) } Device (I2C4) { Name (_ADR, 0x00190002) Name (_DDN, "Serial IO I2C Controller 4") - - Name (SSCN, Package () { 432, 507, 30 }) - Name (FMCN, Package () { 72, 160, 30 }) } Device (I2C5) { Name (_ADR, 0x00190002) Name (_DDN, "Serial IO I2C Controller 5") - - Name (SSCN, Package () { 432, 507, 30 }) - Name (FMCN, Package () { 72, 160, 30 }) } Device (SPI0) diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h index fe03e59451..eec6f1ed17 100644 --- a/src/soc/intel/skylake/chip.h +++ b/src/soc/intel/skylake/chip.h @@ -24,6 +24,7 @@ #include <stdint.h> #include <soc/gpio_defs.h> #include <soc/gpe.h> +#include <soc/intel/common/lpss_i2c.h> #include <soc/pci_devs.h> #include <soc/pmc.h> #include <soc/serialio.h> @@ -44,6 +45,8 @@ struct skylake_i2c_config { enum i2c_speed speed; /* Bus should be enabled prior to ramstage with temporary base */ int early_init; + /* Custom bus speed configuration { scl_lcnt, scl_hcnt, sda_hold } */ + struct lpss_i2c_speed_config speed_config[LPSS_I2C_SPEED_CONFIG_COUNT]; }; struct soc_intel_skylake_config { diff --git a/src/soc/intel/skylake/i2c.c b/src/soc/intel/skylake/i2c.c index 64d39cddb2..eebe665d94 100644 --- a/src/soc/intel/skylake/i2c.c +++ b/src/soc/intel/skylake/i2c.c @@ -13,9 +13,11 @@ * GNU General Public License for more details. */ +#include <arch/acpigen.h> #include <device/device.h> #include <device/i2c.h> #include <device/pci.h> +#include <device/pci_def.h> #include <device/pci_ids.h> #include <soc/intel/common/lpss_i2c.h> #include <soc/ramstage.h> @@ -54,26 +56,53 @@ static int i2c_dev_to_bus(struct device *dev) static void i2c_dev_init(struct device *dev) { struct soc_intel_skylake_config *config = dev->chip_info; + const struct lpss_i2c_speed_config *sptr; + enum i2c_speed speed; + int i, bus = i2c_dev_to_bus(dev); + + if (!config || bus < 0) + return; + + 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 (i = 0; i < LPSS_I2C_SPEED_CONFIG_COUNT; i++) { + sptr = &config->i2c[bus].speed_config[i]; + if (sptr->speed == speed) { + lpss_i2c_set_speed_config(bus, sptr); + break; + } + } +} + +/* Generate ACPI I2C device objects */ +static void i2c_fill_ssdt(struct device *dev) +{ + struct soc_intel_skylake_config *config = dev->chip_info; int bus = i2c_dev_to_bus(dev); if (!config || bus < 0) return; - lpss_i2c_init(bus, config->i2c[bus].speed ? : I2C_SPEED_FAST); + acpigen_write_scope(acpi_device_path(dev)); + lpss_i2c_acpi_fill_ssdt(config->i2c[bus].speed_config); + acpigen_pop_len(); } static struct i2c_bus_operations i2c_bus_ops = { - .dev_to_bus = &i2c_dev_to_bus, + .dev_to_bus = &i2c_dev_to_bus, }; static struct device_operations i2c_dev_ops = { - .read_resources = &pci_dev_read_resources, - .set_resources = &pci_dev_set_resources, - .enable_resources = &pci_dev_enable_resources, - .scan_bus = &scan_smbus, - .ops_pci = &soc_pci_ops, - .ops_i2c_bus = &i2c_bus_ops, - .init = &i2c_dev_init, + .read_resources = &pci_dev_read_resources, + .set_resources = &pci_dev_set_resources, + .enable_resources = &pci_dev_enable_resources, + .scan_bus = &scan_smbus, + .ops_pci = &soc_pci_ops, + .ops_i2c_bus = &i2c_bus_ops, + .init = &i2c_dev_init, + .acpi_fill_ssdt_generator = &i2c_fill_ssdt, }; static const unsigned short pci_device_ids[] = { 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) |