diff options
-rw-r--r-- | src/soc/amd/stoneyridge/bootblock/bootblock.c | 3 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/i2c.c | 38 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/southbridge.h | 3 |
3 files changed, 41 insertions, 3 deletions
diff --git a/src/soc/amd/stoneyridge/bootblock/bootblock.c b/src/soc/amd/stoneyridge/bootblock/bootblock.c index f9ae365c0d..709b4130a3 100644 --- a/src/soc/amd/stoneyridge/bootblock/bootblock.c +++ b/src/soc/amd/stoneyridge/bootblock/bootblock.c @@ -130,4 +130,7 @@ void bootblock_soc_init(void) post_code(0x38); /* APs will not exit amdinitearly */ do_agesawrapper(agesawrapper_amdinitearly, "amdinitearly"); + + /* Initialize any early i2c buses. */ + i2c_soc_early_init(); } diff --git a/src/soc/amd/stoneyridge/i2c.c b/src/soc/amd/stoneyridge/i2c.c index d0d75a82d2..947c43f3b0 100644 --- a/src/soc/amd/stoneyridge/i2c.c +++ b/src/soc/amd/stoneyridge/i2c.c @@ -19,6 +19,7 @@ #include <drivers/i2c/designware/dw_i2c.h> #include <soc/iomap.h> #include <soc/pci_devs.h> +#include <soc/southbridge.h> #include "chip.h" #define I2C_BUS_ADDRESS(x) (I2C_BASE_ADDRESS + I2C_DEVICE_SIZE * (x)) @@ -42,9 +43,8 @@ uintptr_t dw_i2c_base_address(unsigned int bus) return bus < I2C_DEVICE_COUNT ? i2c_bus_address[bus] : 0; } -const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) +static const struct soc_amd_stoneyridge_config *get_soc_config(void) { - const struct soc_amd_stoneyridge_config *config; const struct device *dev = dev_find_slot(0, GNB_DEVFN); if (!dev || !dev->chip_info) { @@ -52,10 +52,21 @@ const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) __func__); return NULL; } + + return dev->chip_info; +} + +const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) +{ + const struct soc_amd_stoneyridge_config *config; + if (bus >= ARRAY_SIZE(i2c_bus_address)) return NULL; - config = dev->chip_info; + config = get_soc_config(); + if (config == NULL) + return NULL; + return &config->i2c[bus]; } @@ -90,6 +101,27 @@ int dw_i2c_soc_dev_to_bus(struct device *dev) return -1; } +void i2c_soc_early_init(void) +{ + size_t i; + const struct soc_amd_stoneyridge_config *config; + + config = get_soc_config(); + + if (config == NULL) + return; + + for (i = 0; i < ARRAY_SIZE(config->i2c); i++) { + const struct dw_i2c_bus_config *cfg = &config->i2c[i]; + + if (!cfg->early_init) + continue; + + if (dw_i2c_init(i, cfg)) + printk(BIOS_ERR, "Failed to init i2c bus %zd\n", i); + } +} + struct device_operations stoneyridge_i2c_mmio_ops = { /* TODO(teravest): Move I2C resource info here. */ .read_resources = DEVICE_NOOP, diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index fa427eedc1..2f9d9f9e68 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -389,4 +389,7 @@ int sb_set_wideio_range(uint16_t start, uint16_t size); int mainboard_get_xhci_oc_map(uint16_t *usb_oc_map); int mainboard_get_ehci_oc_map(uint16_t *usb_oc_map); +/* Initialize all the i2c buses that are marked with early init. */ +void i2c_soc_early_init(void); + #endif /* __STONEYRIDGE_H__ */ |