diff --git a/src/soc/amd/cezanne/Kconfig b/src/soc/amd/cezanne/Kconfig index f7f2d6898a..b916e71e15 100644 --- a/src/soc/amd/cezanne/Kconfig +++ b/src/soc/amd/cezanne/Kconfig @@ -19,6 +19,7 @@ config SOC_SPECIFIC_OPTIONS select RESET_VECTOR_IN_RAM select SOC_AMD_COMMON select SOC_AMD_COMMON_BLOCK_ACPIMMIO + select SOC_AMD_COMMON_BLOCK_AOAC select SOC_AMD_COMMON_BLOCK_BANKED_GPIOS select SOC_AMD_COMMON_BLOCK_NONCAR select SOC_AMD_COMMON_BLOCK_PCI_MMCONF diff --git a/src/soc/amd/cezanne/Makefile.inc b/src/soc/amd/cezanne/Makefile.inc index 6a0229cdbc..01dc97e819 100644 --- a/src/soc/amd/cezanne/Makefile.inc +++ b/src/soc/amd/cezanne/Makefile.inc @@ -5,7 +5,8 @@ ifeq ($(CONFIG_SOC_AMD_CEZANNE),y) subdirs-y += ../../../cpu/x86/mtrr # Beware that all-y also adds the compilation unit to verstage on PSP -all-y += config.c +all-y += config.c +all-y += aoac.c bootblock-y += bootblock.c bootblock-y += early_fch.c diff --git a/src/soc/amd/cezanne/aoac.c b/src/soc/amd/cezanne/aoac.c new file mode 100644 index 0000000000..9c58bb5442 --- /dev/null +++ b/src/soc/amd/cezanne/aoac.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#define FCH_AOAC_UART_FOR_CONSOLE \ + (CONFIG_UART_FOR_CONSOLE == 0 ? FCH_AOAC_DEV_UART0 \ + : CONFIG_UART_FOR_CONSOLE == 1 ? FCH_AOAC_DEV_UART1 \ + : -1) +#if CONFIG(AMD_SOC_CONSOLE_UART) && FCH_AOAC_UART_FOR_CONSOLE == -1 +# error Unsupported UART_FOR_CONSOLE chosen +#endif + +/* + * Table of devices that need their AOAC registers enabled and waited + * upon (usually about .55 milliseconds). Instead of individual delays + * waiting for each device to become available, a single delay will be + * executed. The console UART is handled separately from this table. + * + * TODO: Find out which I2C controllers we really need to enable here. + */ +const static unsigned int aoac_devs[] = { + FCH_AOAC_DEV_AMBA, + FCH_AOAC_DEV_I2C0, + FCH_AOAC_DEV_I2C1, + FCH_AOAC_DEV_I2C2, + FCH_AOAC_DEV_I2C3, + FCH_AOAC_DEV_ESPI, +}; + +void wait_for_aoac_enabled(unsigned int dev) +{ + while (!is_aoac_device_enabled(dev)) + udelay(100); +} + +void enable_aoac_devices(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(aoac_devs); i++) + power_on_aoac_device(aoac_devs[i]); + + if (CONFIG(AMD_SOC_CONSOLE_UART)) + power_on_aoac_device(FCH_AOAC_UART_FOR_CONSOLE); + + /* Wait for AOAC devices to indicate power and clock OK */ + for (i = 0; i < ARRAY_SIZE(aoac_devs); i++) + wait_for_aoac_enabled(aoac_devs[i]); + + if (CONFIG(AMD_SOC_CONSOLE_UART)) + wait_for_aoac_enabled(FCH_AOAC_UART_FOR_CONSOLE); +} diff --git a/src/soc/amd/cezanne/early_fch.c b/src/soc/amd/cezanne/early_fch.c index b6681e32e3..37ba4c7a1a 100644 --- a/src/soc/amd/cezanne/early_fch.c +++ b/src/soc/amd/cezanne/early_fch.c @@ -13,6 +13,7 @@ void fch_pre_init(void) fch_smbus_init(); fch_enable_cf9_io(); fch_enable_legacy_io(); + enable_aoac_devices(); /* * On reset Range_0 defaults to enabled. We want to start with a clean diff --git a/src/soc/amd/cezanne/include/soc/southbridge.h b/src/soc/amd/cezanne/include/soc/southbridge.h index 7fb61b67e2..2a294e96ef 100644 --- a/src/soc/amd/cezanne/include/soc/southbridge.h +++ b/src/soc/amd/cezanne/include/soc/southbridge.h @@ -12,9 +12,26 @@ #define FCH_LEGACY_UART_DECODE (ALINK_AHB_ADDRESS + 0x20) /* 0xfedc0020 */ +/* FCH AOAC device offsets for AOAC_DEV_D3_CTL/AOAC_DEV_D3_STATE */ +#define FCH_AOAC_DEV_CLK_GEN 0 +#define FCH_AOAC_DEV_I2C0 5 +#define FCH_AOAC_DEV_I2C1 6 +#define FCH_AOAC_DEV_I2C2 7 +#define FCH_AOAC_DEV_I2C3 8 +#define FCH_AOAC_DEV_I2C4 9 +#define FCH_AOAC_DEV_I2C5 10 +#define FCH_AOAC_DEV_UART0 11 +#define FCH_AOAC_DEV_UART1 12 +#define FCH_AOAC_DEV_UART2 16 +#define FCH_AOAC_DEV_AMBA 17 +#define FCH_AOAC_DEV_UART3 26 +#define FCH_AOAC_DEV_ESPI 27 + /* IO 0xf0 NCP Error */ #define NCP_WARM_BOOT (1 << 7) /* Write-once */ +void enable_aoac_devices(void); +void wait_for_aoac_enabled(unsigned int dev); void fch_pre_init(void); void fch_early_init(void);