summaryrefslogtreecommitdiff
path: root/src/soc/intel/skylake
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/skylake')
-rw-r--r--src/soc/intel/skylake/acpi/serialio.asl19
-rw-r--r--src/soc/intel/skylake/chip.h3
-rw-r--r--src/soc/intel/skylake/i2c.c47
-rw-r--r--src/soc/intel/skylake/romstage/i2c.c14
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)