diff options
author | Karthikeyan Ramasubramanian <kramasub@google.com> | 2021-03-18 23:16:29 -0600 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2021-03-22 03:40:42 +0000 |
commit | 4f87ae1d4a3a597f1260534001bd99160cc8ca99 (patch) | |
tree | d9b2e6f2a396744b9a10f8f3cc7106d85c0afdc7 | |
parent | 0dbea48d46013c004014a024ad8717d049e67c8d (diff) |
soc/amd/common/block/i2c: Move SoC agnostic parts into common
The logic behind I2C bus initialization, I2C MMIO base address getter
and setter, I2C bus ACPI name resolution are identical for all the AMD
SoCs. Hence moving all the SoC agnotic parts of the driver into the
common driver and just configure the SoC specific parts into individual
I2C drivers.
BUG=None
TEST=Build Dalboz and Grunt. Boot to OS in Dalboz. Ensure that the I2C
peripherals are detected as earlier in Dalboz. Verify some I2C
peripheral functionality like trackpad and touchscreen.
Change-Id: Ic9c99ec769d7d8ad7e1e566fdf42a5206657183d
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com>
Suggested-by: Kyosti Malkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51509
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-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 */ |