diff options
author | Felix Held <felix-coreboot@felixheld.de> | 2022-08-18 19:06:50 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-08-20 20:43:17 +0000 |
commit | 02b61ae9c034ed80cb726df44210cc7d20898b6f (patch) | |
tree | 9d9b634a5318e0487564976a9805afc2ac49f2a5 | |
parent | f7d86f21e12aa3a368aa87aa4a1406e7c38e07b0 (diff) |
soc/amd/stoneyridge: move early I2C init to early_fch.c
Since the I2C controller is part of the FCH, move the early
initialization from bootblock.c to early_fch.c which also matches what
the newer AMD SoCs do.
TEST=Successfully boots on google/liara and all I2C/cr50/TPM functions
appear to work properly
Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: I22d3a8888eaa34ea612da719c408c0083769e806
Reviewed-on: https://review.coreboot.org/c/coreboot/+/66866
Reviewed-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r-- | src/soc/amd/stoneyridge/bootblock.c | 35 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/early_fch.c | 33 |
2 files changed, 33 insertions, 35 deletions
diff --git a/src/soc/amd/stoneyridge/bootblock.c b/src/soc/amd/stoneyridge/bootblock.c index 66b22be99e..8ada7238f8 100644 --- a/src/soc/amd/stoneyridge/bootblock.c +++ b/src/soc/amd/stoneyridge/bootblock.c @@ -12,15 +12,12 @@ #include <amdblocks/agesawrapper_call.h> #include <amdblocks/amd_pci_mmconf.h> #include <amdblocks/biosram.h> -#include <amdblocks/i2c.h> #include <soc/pci_devs.h> #include <soc/cpu.h> #include <soc/southbridge.h> #include <timestamp.h> #include <halt.h> -#include "chip.h" - #if CONFIG_PI_AGESA_TEMP_RAM_BASE < 0x100000 #error "Error: CONFIG_PI_AGESA_TEMP_RAM_BASE must be >= 1MB" #endif @@ -28,14 +25,6 @@ #error "Error: CONFIG_PI_AGESA_CAR_HEAP_BASE must be >= 1MB" #endif -/* Table to switch SCL pins to outputs to initially reset the I2C peripherals */ -static const struct soc_i2c_scl_pin i2c_scl_pins[] = { - I2C_RESET_SCL_PIN(I2C0_SCL_PIN, GPIO_I2C0_SCL), - I2C_RESET_SCL_PIN(I2C1_SCL_PIN, GPIO_I2C1_SCL), - I2C_RESET_SCL_PIN(I2C2_SCL_PIN, GPIO_I2C2_SCL), - I2C_RESET_SCL_PIN(I2C3_SCL_PIN, GPIO_I2C3_SCL), -}; - /* Set the MMIO Configuration Base Address, Bus Range, and misc MTRRs. */ static void amd_initmmio(void) { @@ -64,17 +53,6 @@ static void amd_initmmio(void) CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_UNCACHEABLE); } -static void reset_i2c_peripherals(void) -{ - const struct soc_amd_stoneyridge_config *cfg = config_of_soc(); - struct soc_i2c_peripheral_reset_info reset_info; - - reset_info.i2c_scl_reset_mask = cfg->i2c_scl_reset & GPIO_I2C_MASK; - reset_info.i2c_scl = i2c_scl_pins; - reset_info.num_pins = ARRAY_SIZE(i2c_scl_pins); - sb_reset_i2c_peripherals(&reset_info); -} - asmlinkage void bootblock_c_entry(uint64_t base_timestamp) { enable_pci_mmconf(); @@ -102,16 +80,6 @@ void bootblock_soc_early_init(void) void bootblock_soc_init(void) { - /* - * This call (sb_reset_i2c_peripherals) was originally early at - * bootblock_c_entry, but had to be moved here. There was an - * unexplained delay in the middle of the i2c transaction when - * we had it in bootblock_c_entry. Moving it to this point - * (or adding delays) fixes the issue. It seems like the processor - * just pauses but we don't know why. - */ - reset_i2c_peripherals(); - if (CONFIG(AMD_SOC_CONSOLE_UART)) assert(CONFIG_UART_FOR_CONSOLE >= 0 && CONFIG_UART_FOR_CONSOLE <= 1); @@ -120,7 +88,4 @@ void bootblock_soc_init(void) printk(BIOS_DEBUG, "Family_Model: %08x\n", val); bootblock_fch_init(); - - /* Initialize any early i2c buses. */ - i2c_soc_early_init(); } diff --git a/src/soc/amd/stoneyridge/early_fch.c b/src/soc/amd/stoneyridge/early_fch.c index e0d5fa052d..5a8de13e20 100644 --- a/src/soc/amd/stoneyridge/early_fch.c +++ b/src/soc/amd/stoneyridge/early_fch.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include <amdblocks/acpimmio.h> +#include <amdblocks/i2c.h> #include <amdblocks/lpc.h> #include <amdblocks/pmlib.h> #include <amdblocks/reset.h> @@ -9,6 +10,16 @@ #include <soc/southbridge.h> #include <types.h> +#include "chip.h" + +/* Table to switch SCL pins to outputs to initially reset the I2C peripherals */ +static const struct soc_i2c_scl_pin i2c_scl_pins[] = { + I2C_RESET_SCL_PIN(I2C0_SCL_PIN, GPIO_I2C0_SCL), + I2C_RESET_SCL_PIN(I2C1_SCL_PIN, GPIO_I2C1_SCL), + I2C_RESET_SCL_PIN(I2C2_SCL_PIN, GPIO_I2C2_SCL), + I2C_RESET_SCL_PIN(I2C3_SCL_PIN, GPIO_I2C3_SCL), +}; + static void sb_lpc_decode(void) { u32 tmp = 0; @@ -100,6 +111,17 @@ static void setup_misc(int *reboot) } } +static void reset_i2c_peripherals(void) +{ + const struct soc_amd_stoneyridge_config *cfg = config_of_soc(); + struct soc_i2c_peripheral_reset_info reset_info; + + reset_info.i2c_scl_reset_mask = cfg->i2c_scl_reset & GPIO_I2C_MASK; + reset_info.i2c_scl = i2c_scl_pins; + reset_info.num_pins = ARRAY_SIZE(i2c_scl_pins); + sb_reset_i2c_peripherals(&reset_info); +} + /* Before console init */ void bootblock_fch_early_init(void) { @@ -132,8 +154,19 @@ void bootblock_fch_early_init(void) /* After console init */ void bootblock_fch_init(void) { + /* + * This call (sb_reset_i2c_peripherals) was originally early at + * bootblock_c_entry, but had to be moved here. There was an + * unexplained delay in the middle of the i2c transaction when + * we had it in bootblock_c_entry. Moving it to this point + * (or adding delays) fixes the issue. It seems like the processor + * just pauses but we don't know why. + */ + reset_i2c_peripherals(); pm_set_power_failure_state(); fch_print_pmxc0_status(); + /* Initialize any early i2c buses. */ + i2c_soc_early_init(); show_spi_speeds_and_modes(); } |