diff options
-rw-r--r-- | src/mainboard/google/kahlee/mainboard.c | 1 | ||||
-rw-r--r-- | src/mainboard/google/zork/verstage.c | 1 | ||||
-rw-r--r-- | src/soc/amd/common/block/i2c/i2c.c | 120 | ||||
-rw-r--r-- | src/soc/amd/common/block/include/amdblocks/i2c.h | 34 | ||||
-rw-r--r-- | src/soc/amd/picasso/chip.c | 4 | ||||
-rw-r--r-- | src/soc/amd/picasso/chip.h | 2 | ||||
-rw-r--r-- | src/soc/amd/picasso/fch.c | 1 | ||||
-rw-r--r-- | src/soc/amd/picasso/i2c.c | 140 | ||||
-rw-r--r-- | src/soc/amd/picasso/include/soc/iomap.h | 3 | ||||
-rw-r--r-- | src/soc/amd/picasso/include/soc/southbridge.h | 6 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/chip.c | 19 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/i2c.c | 114 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/iomap.h | 6 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/southbridge.h | 6 |
14 files changed, 231 insertions, 226 deletions
diff --git a/src/mainboard/google/kahlee/mainboard.c b/src/mainboard/google/kahlee/mainboard.c index ad38b2d5b7..c44da75924 100644 --- a/src/mainboard/google/kahlee/mainboard.c +++ b/src/mainboard/google/kahlee/mainboard.c @@ -7,6 +7,7 @@ #include <acpi/acpi.h> #include <amdblocks/agesawrapper.h> #include <amdblocks/amd_pci_util.h> +#include <amdblocks/i2c.h> #include <baseboard/variants.h> #include <boardid.h> #include <smbios.h> diff --git a/src/mainboard/google/zork/verstage.c b/src/mainboard/google/zork/verstage.c index bcbf396bcc..dd59e734e3 100644 --- a/src/mainboard/google/zork/verstage.c +++ b/src/mainboard/google/zork/verstage.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include <amdblocks/gpio_banks.h> +#include <amdblocks/i2c.h> #include <baseboard/variants.h> #include <console/console.h> #include <security/vboot/vboot_common.h> diff --git a/src/soc/amd/common/block/i2c/i2c.c b/src/soc/amd/common/block/i2c/i2c.c index 59e885d807..95e25798d2 100644 --- a/src/soc/amd/common/block/i2c/i2c.c +++ b/src/soc/amd/common/block/i2c/i2c.c @@ -1,14 +1,132 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include <acpi/acpi.h> #include <assert.h> -#include <delay.h> #include <amdblocks/acpimmio.h> #include <amdblocks/gpio_banks.h> #include <amdblocks/gpio_defs.h> #include <amdblocks/i2c.h> +#include <console/console.h> +#include <delay.h> +#include <device/device.h> +#include <device/i2c.h> +#include <device/mmio.h> +#include <drivers/i2c/designware/dw_i2c.h> #define MAX_PIN_COUNT 4 +uintptr_t dw_i2c_base_address(unsigned int bus) +{ + size_t num_ctrlrs; + const struct soc_i2c_ctrlr_info *ctrlr = soc_get_i2c_ctrlr_info(&num_ctrlrs); + + if (bus >= num_ctrlrs) { + printk(BIOS_ERR, "Bus ID %d is >= number of I2C controllers %zu\n", + bus, num_ctrlrs); + return 0; + } + + return ctrlr[bus].bar; +} + +const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) +{ + size_t num_buses = 0; + const struct dw_i2c_bus_config *cfg = soc_get_i2c_bus_config(&num_buses); + + if (bus >= num_buses) { + printk(BIOS_ERR, "Bus ID %d is >= number of I2C buses %zu\n", bus, num_buses); + return NULL; + } + + return &cfg[bus]; +} + +static const char *i2c_acpi_name(const struct device *dev) +{ + size_t i; + size_t num_ctrlrs; + const struct soc_i2c_ctrlr_info *ctrlr = soc_get_i2c_ctrlr_info(&num_ctrlrs); + + if (!(uintptr_t)dev->path.mmio.addr) + die("NULL MMIO address at %s\n", __func__); + + for (i = 0; i < num_ctrlrs; i++) { + if ((uintptr_t)dev->path.mmio.addr == ctrlr[i].bar) + return ctrlr[i].acpi_name; + } + printk(BIOS_ERR, "%s: Could not find %lu\n", __func__, (uintptr_t)dev->path.mmio.addr); + return NULL; +} + +int dw_i2c_soc_dev_to_bus(const struct device *dev) +{ + size_t i; + size_t num_ctrlrs; + const struct soc_i2c_ctrlr_info *ctrlr = soc_get_i2c_ctrlr_info(&num_ctrlrs); + + if (!(uintptr_t)dev->path.mmio.addr) + die("NULL MMIO address at %s\n", __func__); + + for (i = 0; i < num_ctrlrs; i++) { + if ((uintptr_t)dev->path.mmio.addr == ctrlr[i].bar) + return i; + } + printk(BIOS_ERR, "%s: Could not find %lu\n", __func__, (uintptr_t)dev->path.mmio.addr); + return -1; +} + +void __weak soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg) +{ + /* Nothing by default. */ +} + +static void dw_i2c_soc_init(bool is_early_init) +{ + unsigned int bus; + size_t num_buses = 0, num_ctrlrs = 0; + const struct dw_i2c_bus_config *cfg = soc_get_i2c_bus_config(&num_buses); + const struct soc_i2c_ctrlr_info *ctrlr = soc_get_i2c_ctrlr_info(&num_ctrlrs); + + /* Ensure that the number of controllers in devicetree and SoC match. */ + assert(num_buses == num_ctrlrs); + + for (bus = 0; bus < num_buses; bus++, cfg++, ctrlr++) { + /* + * Skip initialization when controller is in peripheral mode or base address + * is not configured or is not the expected stage to initialize. + */ + if (ctrlr->mode == I2C_PERIPHERAL_MODE || !ctrlr->bar || + cfg->early_init != is_early_init) + continue; + + if (dw_i2c_init(bus, cfg)) + printk(BIOS_ERR, "Failed to init i2c bus %d\n", bus); + continue; + + soc_i2c_misc_init(bus, cfg); + } +} + +void i2c_soc_early_init(void) +{ + dw_i2c_soc_init(true); +} + +void i2c_soc_init(void) +{ + dw_i2c_soc_init(false); +} + +struct device_operations soc_amd_i2c_mmio_ops = { + /* TODO(kramasub): Move I2C resource info here. */ + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .scan_bus = scan_smbus, + .acpi_name = i2c_acpi_name, + .acpi_fill_ssdt = dw_i2c_acpi_fill_ssdt, +}; + struct common_i2c_save { uint32_t control_value; uint8_t mux_value; diff --git a/src/soc/amd/common/block/include/amdblocks/i2c.h b/src/soc/amd/common/block/include/amdblocks/i2c.h index 9fa203bf57..497de6f28e 100644 --- a/src/soc/amd/common/block/include/amdblocks/i2c.h +++ b/src/soc/amd/common/block/include/amdblocks/i2c.h @@ -4,8 +4,27 @@ #define AMD_COMMON_BLOCK_I2C_H #include <amdblocks/gpio_banks.h> +#include <device/i2c.h> +#include <drivers/i2c/designware/dw_i2c.h> #include <types.h> +/* Enum to identify in which mode the I2C controller is operating. */ +enum i2c_ctrlr_mode { + I2C_MASTER_MODE, + I2C_PERIPHERAL_MODE, +}; + +/** + * Data structure to hold SoC I2C controller information + * @bar: MMIO base address for the I2C bus. + * @acpi_name: ACPI Name corresponding to the I2C bus. + */ +struct soc_i2c_ctrlr_info { + enum i2c_ctrlr_mode mode; + uintptr_t bar; + const char *acpi_name; +}; + /** * Data structure to identify GPIO to be toggled to reset peripherals on an I2C bus. * @pin: GPIO corresponding to I2C SCL that needs to be toggled/bit-banged. @@ -30,6 +49,21 @@ struct soc_i2c_peripheral_reset_info { uint32_t num_pins; }; +/* Helper function to perform misc I2C configuration specific to SoC. */ +void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg); + +/* Getter function to get the SoC I2C Controller Information. */ +const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs); + +/* Getter function to get the SoC I2C bus configuration. */ +const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses); + +/* Initialize all the i2c buses that are marked with early init. */ +void i2c_soc_early_init(void); + +/* Initialize all the i2c buses that are not marked with early init. */ +void i2c_soc_init(void); + /* Reset I2C peripherals. */ void sb_reset_i2c_peripherals(const struct soc_i2c_peripheral_reset_info *reset_info); diff --git a/src/soc/amd/picasso/chip.c b/src/soc/amd/picasso/chip.c index 9f9ca24968..6a6c49e28f 100644 --- a/src/soc/amd/picasso/chip.c +++ b/src/soc/amd/picasso/chip.c @@ -14,7 +14,7 @@ #include <fsp/api.h> /* Supplied by i2c.c */ -extern struct device_operations picasso_i2c_mmio_ops; +extern struct device_operations soc_amd_i2c_mmio_ops; /* Supplied by uart.c */ extern struct device_operations picasso_uart_mmio_ops; @@ -51,7 +51,7 @@ static void set_mmio_dev_ops(struct device *dev) case APU_I2C2_BASE: case APU_I2C3_BASE: case APU_I2C4_BASE: - dev->ops = &picasso_i2c_mmio_ops; + dev->ops = &soc_amd_i2c_mmio_ops; break; case APU_UART0_BASE: case APU_UART1_BASE: diff --git a/src/soc/amd/picasso/chip.h b/src/soc/amd/picasso/chip.h index 2944b2a46f..2b0cbf49f4 100644 --- a/src/soc/amd/picasso/chip.h +++ b/src/soc/amd/picasso/chip.h @@ -105,7 +105,7 @@ struct soc_amd_picasso_config { * register i2c_scl_reset = (GPIO_I2C0_SCL | GPIO_I2C3_SCL) */ u8 i2c_scl_reset; - struct dw_i2c_bus_config i2c[I2C_MASTER_DEV_COUNT]; + struct dw_i2c_bus_config i2c[I2C_CTRLR_COUNT]; enum { I2S_PINS_MAX_HDA = 0, /* HDA w/reset 3xSDI, SW w/Data0 */ I2S_PINS_MAX_MHDA = 1, /* HDA no reset 3xSDI, SW w/Data0-1 */ diff --git a/src/soc/amd/picasso/fch.c b/src/soc/amd/picasso/fch.c index e52090a283..4568e20676 100644 --- a/src/soc/amd/picasso/fch.c +++ b/src/soc/amd/picasso/fch.c @@ -13,6 +13,7 @@ #include <amdblocks/reset.h> #include <amdblocks/acpimmio.h> #include <amdblocks/acpi.h> +#include <amdblocks/i2c.h> #include <amdblocks/smi.h> #include <soc/acpi.h> #include <soc/cpu.h> diff --git a/src/soc/amd/picasso/i2c.c b/src/soc/amd/picasso/i2c.c index 9d016150c0..11e69b1038 100644 --- a/src/soc/amd/picasso/i2c.c +++ b/src/soc/amd/picasso/i2c.c @@ -1,11 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include <device/mmio.h> -#include <acpi/acpi.h> #include <console/console.h> -#include <delay.h> -#include <device/device.h> -#include <drivers/i2c/designware/dw_i2c.h> #include <amdblocks/acpimmio.h> #include <amdblocks/i2c.h> #include <soc/i2c.h> @@ -15,130 +10,69 @@ #include "chip.h" #if ENV_X86 -static const uintptr_t i2c_bus_address[I2C_MASTER_DEV_COUNT + I2C_SLAVE_DEV_COUNT] = { - 0, - 0, - APU_I2C2_BASE, - APU_I2C3_BASE, - APU_I2C4_BASE, /* Can only be used in slave mode */ +/* Preferably keep all the I2C controllers operating in a specific mode together. */ +static const struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = { + { I2C_MASTER_MODE, 0, "" }, + { I2C_MASTER_MODE, 0, "" }, + { I2C_MASTER_MODE, APU_I2C2_BASE, "I2C2" }, + { I2C_MASTER_MODE, APU_I2C3_BASE, "I2C3" }, + { I2C_PERIPHERAL_MODE, APU_I2C4_BASE, "I2C4" } /* Can only be used in peripheral mode */ }; #else -static uintptr_t i2c_bus_address[I2C_MASTER_DEV_COUNT + I2C_SLAVE_DEV_COUNT]; -#endif - -uintptr_t dw_i2c_base_address(unsigned int bus) -{ - if (bus >= ARRAY_SIZE(i2c_bus_address)) - return 0; - - return i2c_bus_address[bus]; -} +static struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = { + { I2C_MASTER_MODE, 0, ""}, + { I2C_MASTER_MODE, 0, "" }, + { I2C_MASTER_MODE, 0, "" }, + { I2C_MASTER_MODE, 0, "" }, + { I2C_PERIPHERAL_MODE, 0, "" }, +}; -#if !ENV_X86 void i2c_set_bar(unsigned int bus, uintptr_t bar) { - if (bus >= ARRAY_SIZE(i2c_bus_address)) { + if (bus >= ARRAY_SIZE(i2c_ctrlr)) { printk(BIOS_ERR, "Error: i2c index out of bounds: %u.", bus); return; } - i2c_bus_address[bus] = bar; + i2c_ctrlr[bus].bar = bar; } #endif -const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) -{ - const struct soc_amd_picasso_config *config; - - if (bus >= ARRAY_SIZE(config->i2c)) - return NULL; - - /* config is not NULL; if it was, config_of_soc calls die() internally */ - config = config_of_soc(); - - return &config->i2c[bus]; -} - -static const char *i2c_acpi_name(const struct device *dev) -{ - if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[2]) - return "I2C2"; - else if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[3]) - return "I2C3"; - else if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[4]) - return "I2C4"; - return NULL; -} - -int dw_i2c_soc_dev_to_bus(const struct device *dev) -{ - if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[2]) - return 2; - else if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[3]) - return 3; - else if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[4]) - return 4; - return -1; -} - __weak void mainboard_i2c_override(int bus, uint32_t *pad_settings) { } -static void dw_i2c_soc_init(bool is_early_init) +void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg) { - size_t i; - const struct soc_amd_picasso_config *config; uint32_t pad_ctrl; int misc_reg; - /* config is not NULL; if it was, config_of_soc calls die() internally */ - config = config_of_soc(); - - for (i = I2C_MASTER_START_INDEX; i < ARRAY_SIZE(config->i2c); i++) { - const struct dw_i2c_bus_config *cfg = &config->i2c[i]; - - if (cfg->early_init != is_early_init) - continue; + misc_reg = MISC_I2C0_PAD_CTRL + sizeof(uint32_t) * bus; + pad_ctrl = misc_read32(misc_reg); - if (dw_i2c_init(i, cfg)) { - printk(BIOS_ERR, "Failed to init i2c bus %zd\n", i); - continue; - } + pad_ctrl &= ~I2C_PAD_CTRL_NG_MASK; + pad_ctrl |= I2C_PAD_CTRL_NG_NORMAL; - misc_reg = MISC_I2C0_PAD_CTRL + sizeof(uint32_t) * i; - pad_ctrl = misc_read32(misc_reg); + pad_ctrl &= ~I2C_PAD_CTRL_RX_SEL_MASK; + pad_ctrl |= I2C_PAD_CTRL_RX_SEL_3_3V; - pad_ctrl &= ~I2C_PAD_CTRL_NG_MASK; - pad_ctrl |= I2C_PAD_CTRL_NG_NORMAL; + pad_ctrl &= ~I2C_PAD_CTRL_FALLSLEW_MASK; + pad_ctrl |= cfg->speed == I2C_SPEED_STANDARD ? I2C_PAD_CTRL_FALLSLEW_STD : + I2C_PAD_CTRL_FALLSLEW_LOW; + pad_ctrl |= I2C_PAD_CTRL_FALLSLEW_EN; - pad_ctrl &= ~I2C_PAD_CTRL_RX_SEL_MASK; - pad_ctrl |= I2C_PAD_CTRL_RX_SEL_3_3V; - - pad_ctrl &= ~I2C_PAD_CTRL_FALLSLEW_MASK; - pad_ctrl |= cfg->speed == I2C_SPEED_STANDARD - ? I2C_PAD_CTRL_FALLSLEW_STD - : I2C_PAD_CTRL_FALLSLEW_LOW; - pad_ctrl |= I2C_PAD_CTRL_FALLSLEW_EN; - - mainboard_i2c_override(i, &pad_ctrl); - misc_write32(misc_reg, pad_ctrl); - } + mainboard_i2c_override(bus, &pad_ctrl); + misc_write32(misc_reg, pad_ctrl); } -void i2c_soc_early_init(void) +const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs) { - dw_i2c_soc_init(true); + *num_ctrlrs = ARRAY_SIZE(i2c_ctrlr); + return i2c_ctrlr; } -void i2c_soc_init(void) +const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses) { - dw_i2c_soc_init(false); -} + const struct soc_amd_picasso_config *config = config_of_soc(); -struct device_operations picasso_i2c_mmio_ops = { - /* TODO(teravest): Move I2C resource info here. */ - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, - .scan_bus = scan_smbus, - .acpi_name = i2c_acpi_name, - .acpi_fill_ssdt = dw_i2c_acpi_fill_ssdt, -}; + *num_buses = ARRAY_SIZE(config->i2c); + return config->i2c; +} diff --git a/src/soc/amd/picasso/include/soc/iomap.h b/src/soc/amd/picasso/include/soc/iomap.h index bde1008a75..5b75ecb466 100644 --- a/src/soc/amd/picasso/include/soc/iomap.h +++ b/src/soc/amd/picasso/include/soc/iomap.h @@ -39,7 +39,8 @@ */ #define I2C_MASTER_DEV_COUNT 4 #define I2C_MASTER_START_INDEX 2 -#define I2C_SLAVE_DEV_COUNT 1 +#define I2C_PERIPHERAL_DEV_COUNT 1 +#define I2C_CTRLR_COUNT (I2C_MASTER_DEV_COUNT + I2C_PERIPHERAL_DEV_COUNT) #if ENV_X86 diff --git a/src/soc/amd/picasso/include/soc/southbridge.h b/src/soc/amd/picasso/include/soc/southbridge.h index 60fd6f9686..49e4948495 100644 --- a/src/soc/amd/picasso/include/soc/southbridge.h +++ b/src/soc/amd/picasso/include/soc/southbridge.h @@ -181,12 +181,6 @@ void enable_aoac_devices(void); void wait_for_aoac_enabled(unsigned int dev); void sb_clk_output_48Mhz(void); -/* Initialize all the i2c buses that are marked with early init. */ -void i2c_soc_early_init(void); - -/* Initialize all the i2c buses that are not marked with early init. */ -void i2c_soc_init(void); - /* Allow the board to change the default I2C pad configuration */ void mainboard_i2c_override(int bus, uint32_t *pad_settings); diff --git a/src/soc/amd/stoneyridge/chip.c b/src/soc/amd/stoneyridge/chip.c index 8082165328..fbf205ece0 100644 --- a/src/soc/amd/stoneyridge/chip.c +++ b/src/soc/amd/stoneyridge/chip.c @@ -14,12 +14,12 @@ #include <amdblocks/psp.h> #include <amdblocks/agesawrapper.h> #include <amdblocks/agesawrapper_call.h> +#include <amdblocks/i2c.h> #include "chip.h" /* Supplied by i2c.c */ -extern struct device_operations stoneyridge_i2c_mmio_ops; -extern const char *i2c_acpi_name(const struct device *dev); +extern struct device_operations soc_amd_i2c_mmio_ops; struct device_operations cpu_bus_ops = { .read_resources = noop_read_resources, @@ -98,6 +98,18 @@ static struct device_operations pci_domain_ops = { .acpi_name = soc_acpi_name, }; +static void set_mmio_dev_ops(struct device *dev) +{ + switch (dev->path.mmio.addr) { + case I2CA_BASE_ADDRESS: + case I2CB_BASE_ADDRESS: + case I2CC_BASE_ADDRESS: + case I2CD_BASE_ADDRESS: + dev->ops = &soc_amd_i2c_mmio_ops; + break; + } +} + static void enable_dev(struct device *dev) { /* Set the operations if it is a special bus type */ @@ -109,8 +121,7 @@ static void enable_dev(struct device *dev) dev->ops = &cpu_bus_ops; break; case DEVICE_PATH_MMIO: - if (i2c_acpi_name(dev) != NULL) - dev->ops = &stoneyridge_i2c_mmio_ops; + set_mmio_dev_ops(dev); break; default: break; diff --git a/src/soc/amd/stoneyridge/i2c.c b/src/soc/amd/stoneyridge/i2c.c index 7b0bc77e59..a098775537 100644 --- a/src/soc/amd/stoneyridge/i2c.c +++ b/src/soc/amd/stoneyridge/i2c.c @@ -1,118 +1,28 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include <device/mmio.h> -#include <acpi/acpi.h> -#include <console/console.h> -#include <delay.h> -#include <device/device.h> -#include <drivers/i2c/designware/dw_i2c.h> #include <amdblocks/acpimmio.h> #include <amdblocks/i2c.h> #include <soc/iomap.h> -#include <soc/pci_devs.h> -#include <soc/southbridge.h> #include <soc/i2c.h> #include "chip.h" -#define I2C_BUS_ADDRESS(x) (I2C_BASE_ADDRESS + I2C_DEVICE_SIZE * (x)) -#define I2CA_BASE_ADDRESS (I2C_BUS_ADDRESS(0)) -#define I2CB_BASE_ADDRESS (I2C_BUS_ADDRESS(1)) -#define I2CC_BASE_ADDRESS (I2C_BUS_ADDRESS(2)) -#define I2CD_BASE_ADDRESS (I2C_BUS_ADDRESS(3)) - -/* Global to provide access to chip.c */ -const char *i2c_acpi_name(const struct device *dev); - -static const uintptr_t i2c_bus_address[] = { - I2CA_BASE_ADDRESS, - I2CB_BASE_ADDRESS, - I2CC_BASE_ADDRESS, - I2CD_BASE_ADDRESS, +static const struct soc_i2c_ctrlr_info i2c_ctrlr[] = { + { I2C_MASTER_MODE, I2CA_BASE_ADDRESS, "I2CA" }, + { I2C_MASTER_MODE, I2CB_BASE_ADDRESS, "I2CB" }, + { I2C_MASTER_MODE, I2CC_BASE_ADDRESS, "I2CC" }, + { I2C_MASTER_MODE, I2CD_BASE_ADDRESS, "I2CD" }, }; -uintptr_t dw_i2c_base_address(unsigned int bus) +const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs) { - return bus < I2C_DEVICE_COUNT ? i2c_bus_address[bus] : 0; + *num_ctrlrs = ARRAY_SIZE(i2c_ctrlr); + return i2c_ctrlr; } -const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) +const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses) { - const struct soc_amd_stoneyridge_config *config; - - if (bus >= ARRAY_SIZE(i2c_bus_address)) - return NULL; - - /* config is not NULL; if it was, config_of_soc calls die() internally */ - config = config_of_soc(); + const struct soc_amd_stoneyridge_config *config = config_of_soc(); - return &config->i2c[bus]; -} - -const char *i2c_acpi_name(const struct device *dev) -{ - switch (dev->path.mmio.addr) { - case I2CA_BASE_ADDRESS: - return "I2CA"; - case I2CB_BASE_ADDRESS: - return "I2CB"; - case I2CC_BASE_ADDRESS: - return "I2CC"; - case I2CD_BASE_ADDRESS: - return "I2CD"; - default: - return NULL; - } + *num_buses = ARRAY_SIZE(config->i2c); + return config->i2c; } - -int dw_i2c_soc_dev_to_bus(const struct device *dev) -{ - switch (dev->path.mmio.addr) { - case I2CA_BASE_ADDRESS: - return 0; - case I2CB_BASE_ADDRESS: - return 1; - case I2CC_BASE_ADDRESS: - return 2; - case I2CD_BASE_ADDRESS: - return 3; - } - return -1; -} - -static void dw_i2c_soc_init(bool is_early_init) -{ - size_t i; - const struct soc_amd_stoneyridge_config *config; - - /* config is not NULL; if it was, config_of_soc calls die() internally */ - config = config_of_soc(); - - for (i = 0; i < ARRAY_SIZE(config->i2c); i++) { - const struct dw_i2c_bus_config *cfg = &config->i2c[i]; - - if (cfg->early_init != is_early_init) - continue; - - if (dw_i2c_init(i, cfg)) - printk(BIOS_ERR, "Failed to init i2c bus %zd\n", i); - } -} - -void i2c_soc_early_init(void) -{ - dw_i2c_soc_init(true); -} - -void i2c_soc_init(void) -{ - dw_i2c_soc_init(false); -} - -struct device_operations stoneyridge_i2c_mmio_ops = { - /* TODO(teravest): Move I2C resource info here. */ - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, - .scan_bus = scan_smbus, - .acpi_name = i2c_acpi_name, - .acpi_fill_ssdt = dw_i2c_acpi_fill_ssdt, -}; diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h index 7832dadafc..b3c78e8055 100644 --- a/src/soc/amd/stoneyridge/include/soc/iomap.h +++ b/src/soc/amd/stoneyridge/include/soc/iomap.h @@ -15,6 +15,12 @@ #define I2C_DEVICE_SIZE 0x00001000 #define I2C_DEVICE_COUNT 4 +#define I2C_BUS_ADDRESS(x) (I2C_BASE_ADDRESS + I2C_DEVICE_SIZE * (x)) +#define I2CA_BASE_ADDRESS (I2C_BUS_ADDRESS(0)) +#define I2CB_BASE_ADDRESS (I2C_BUS_ADDRESS(1)) +#define I2CC_BASE_ADDRESS (I2C_BUS_ADDRESS(2)) +#define I2CD_BASE_ADDRESS (I2C_BUS_ADDRESS(3)) + #if CONFIG(HPET_ADDRESS_OVERRIDE) #error HPET address override is not allowed and must be fixed at 0xfed00000 #endif diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 9480e8b713..8aa881bb34 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -250,10 +250,4 @@ void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm); 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); - -/* Initialize all the i2c buses that are not marked with early init. */ -void i2c_soc_init(void); - #endif /* AMD_STONEYRIDGE_SOUTHBRIDGE_H */ |