Garrett Kirkendall has uploaded this change for review. ( https://review.coreboot.org/24998
Change subject: src/soc/amd/stoneyridge: cleanup southbridge.c ......................................................................
src/soc/amd/stoneyridge: cleanup southbridge.c
Limit dependency on vendorcode header files and add appropriate definitions to southbridge.h. Add code to enable decode of FCH ACPI MMIO regions. Factor out to functions, device power-on code for AMBA and UART. Add FCH I2C device power-on code. Add code for FCH to decode TPM memory and IO regions.
BUG=b:69220826 b:65442212 BRANCH=master TEST=Build and boot
Change-Id: I45c1d1d7edc864000282c7ca4e2b8f2a14ea9eac Signed-off-by: Garrett Kirkendall garrett.kirkendall@amd.corp-partner.google.com --- M src/soc/amd/stoneyridge/include/soc/southbridge.h M src/soc/amd/stoneyridge/southbridge.c 2 files changed, 181 insertions(+), 29 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/98/24998/1
diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 3489afc..9c75a12 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -31,7 +31,32 @@ #define PSP_BAR_ENABLES 0x48 #define PSP_MAILBOX_BAR_EN 0x10
+/* FCH ACPI MMIO register base addresses */ +#define ACPI_MMIO_BASE 0xFED80000ul +#define FCH_ACPI_MMIO_SMBUS_PCI_BASE ACPI_MMIO_BASE + 0x000 +#define FCH_ACPI_MMIO_SMI_BASE ACPI_MMIO_BASE + 0x200 +#define FCH_ACPI_MMIO_PMIO_BASE ACPI_MMIO_BASE + 0x300 +#define FCH_ACPI_MMIO_PMIO2_BASE ACPI_MMIO_BASE + 0x400 +#define FCH_ACPI_MMIO_BIOS_RAM_BASE ACPI_MMIO_BASE + 0x500 +#define FCH_ACPI_MMIO_CMOS_RAM_BASE ACPI_MMIO_BASE + 0x600 +#define FCH_ACPI_MMIO_CMOS_BASE ACPI_MMIO_BASE + 0x700 +#define FCH_ACPI_MMIO_ASF_BASE ACPI_MMIO_BASE + 0x900 +#define FCH_ACPI_MMIO_SMBUS_BASE ACPI_MMIO_BASE + 0xA00 +#define FCH_ACPI_MMIO_WATCHDOG_BASE ACPI_MMIO_BASE + 0xB00 +#define FCH_ACPI_MMIO_HPET_BASE ACPI_MMIO_BASE + 0xC00 +#define FCH_ACPI_MMIO_IOMUX_BASE ACPI_MMIO_BASE + 0xD00 +#define FCH_ACPI_MMIO_MISC_BASE ACPI_MMIO_BASE + 0xE00 +#define FCH_ACPI_MMIO_GFX_DAC_BASE ACPI_MMIO_BASE + 0x1400 +#define FCH_ACPI_MMIO_GPIO_BANK0_BASE ACPI_MMIO_BASE + 0x1500 +#define FCH_ACPI_MMIO_GPIO_BANK1_BASE ACPI_MMIO_BASE + 0x1600 +#define FCH_ACPI_MMIO_GPIO_BANK2_BASE ACPI_MMIO_BASE + 0x1700 +#define FCH_ACPI_MMIO_XHCI_BASE ACPI_MMIO_BASE + 0x1C00 +#define FCH_ACPI_MMIO_ACDC_BASE ACPI_MMIO_BASE + 0x1D00 +#define FCH_ACPI_MMIO_AOAC_BASE ACPI_MMIO_BASE + 0x1E00 + /* Power management registers: 0xfed80300 or index/data at IO 0xcd6/cd7 */ +#define PM_ISA_CONTROL 0x04 +#define MMIO_EN BIT(1) #define PM_PCI_CTRL 0x08 #define FORCE_SLPSTATE_RETRY BIT(25) #define FORCE_STPCLK_RETRY BIT(24) @@ -161,6 +186,10 @@ #define DECODE_IO_PORT_ENABLE1_H BIT(1) #define DECODE_IO_PORT_ENABLE0_H BIT(0)
+#define LPC_TRUSTED_PLATFORM_MODULE 0x7C +#define TPM_12_EN BIT(0) +#define TPM_LEGACY_EN BIT(2) + /* * Register 0x64 is 32-bit, composed by two 16-bit sub-registers. * For ease of access, each sub-register is declared separetely. @@ -247,7 +276,8 @@ #define SPI100_HOST_PREF_CONFIG 0x2c #define SPI_RD4DW_EN_HOST BIT(15)
-#define FCH_MISC_REG40_OSCOUT1_EN BIT(2) +#define MISC_MISC_CLK_CNTL_1 0x40 +#define OSCOUT1_CLK_OUTPUT_ENB BIT(2) // 0 = Enabled, 1 = Disabled
/* IO 0xcf9 - Reset control port*/ #define FULL_RST BIT(3) @@ -290,6 +320,60 @@ #endif #define STR_GPIO_STAGE ENV_STRING
+/* FCH IOMUX Registers 0xFED80D00 */ +#define UART0_RTS_L_EGPIO137 0x89 +#define UART0_RTS_L 0x00 +#define EGPIO_137 0x01 +#define UART0_TXD_EGPIO138 0x8A +#define UART0_TXD 0x00 +#define EGPIO138 0x01 +#define UART1_RTS_L_EGPIO142 0x8E +#define UART1_RTS_L 0x00 +#define EGPIO142 0x01 +#define UART1_TXD_EGPIO143 0x8F +#define UART1_TXD 0x00 +#define EGPIO143 0x01 + +/* FCH AOAC Registers 0xFED81E00 */ +#define AOAC_D3_CONTROL_CLK_GEN 0x40 +#define AOAC_D3_CONTROL_I2C0 0x4A +#define AOAC_D3_CONTROL_I2C1 0x4C +#define AOAC_D3_CONTROL_I2C2 0x4E +#define AOAC_D3_CONTROL_I2C3 0x50 +#define AOAC_D3_CONTROL_UART0 0x56 +#define AOAC_D3_CONTROL_UART1 0x58 +#define AOAC_D3_CONTROL_AMBA 0x62 +#define AOAC_D3_CONTROL_USB2 0x64 +#define AOAC_D3_CONTROL_USB3 0x6E + +#define AOAC_TARGET_DEVICE_STATE (BIT0 + BIT1) +#define AOAC_DEVICE_STATE BIT2 +#define AOAC_PWR_ON_DEV BIT3 +#define AOAC_SW_PWR_ON_RSTB BIT4 +#define AOAC_SW_REF_CLK_OK BIT5 +#define AOAC_SW_RST_B BIT6 +#define AOAC_IS_SW_CONTROL BIT7 + +#define AOAC_D3_STATE_CLK_GEN 0x41 +#define AOAC_D3_STATE_I2C0 0x4B +#define AOAC_D3_STATE_I2C1 0x4D +#define AOAC_D3_STATE_I2C2 0x4F +#define AOAC_D3_STATE_I2C3 0x51 +#define AOAC_D3_STATE_UART0 0x57 +#define AOAC_D3_STATE_UART1 0x59 +#define AOAC_D3_STATE_AMBA 0x63 +#define AOAC_D3_STATE_USB2 0x65 +#define AOAC_D3_STATE_USB3 0x6F + +#define A0AC_PWR_RST_STATE BIT0 +#define AOAC_RST_CLK_OK_STATE BIT1 +#define AOAC_RST_B_STATE BIT2 +#define AOAC_DEV_OFF_GATING_STATE BIT3 +#define AOAC_D3COLD BIT4 +#define AOAC_CLK_OK_STATE BIT5 +#define AOAC_STAT0 BIT6 +#define AOAC_STAT1 BIT7 + struct soc_amd_stoneyridge_gpio { uint8_t gpio; uint8_t function; @@ -298,6 +382,7 @@
void sb_enable_rom(void); void configure_stoneyridge_uart(void); +void configure_stoneyridge_i2c(void); void sb_clk_output_48Mhz(void); void sb_disable_4dw_burst(void); void sb_enable(device_t dev); @@ -305,10 +390,12 @@ void southbridge_init(void *chip_info); void sb_lpc_port80(void); void sb_lpc_decode(void); +void sb_acpi_mmio_decode(void); void sb_pci_port80(void); void sb_read_mode(u32 mode); void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm); void sb_set_readspeed(u16 norm, u16 fast); +void sb_tpm_decode(void); void sb_tpm_decode_spi(void); void lpc_wideio_512_window(uint16_t base); void lpc_wideio_16_window(uint16_t base); diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 5d7b73d..82c2ffc 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -30,7 +30,6 @@ #include <fchec.h> #include <delay.h> #include <soc/pci_devs.h> -#include <agesa_headers.h>
static int is_sata_config(void) { @@ -274,42 +273,88 @@ return index; }
-void configure_stoneyridge_uart(void) +static void power_on_aoac_device(int aoac_device_control_register) { - u8 byte, byte2; - - if (CONFIG_UART_FOR_CONSOLE < 0 || CONFIG_UART_FOR_CONSOLE > 1) - return; + u8 byte;
/* Power on the UART and AMBA devices */ - byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56 - + CONFIG_UART_FOR_CONSOLE * 2); + byte = read8((void *)FCH_ACPI_MMIO_AOAC_BASE + + aoac_device_control_register); byte |= AOAC_PWR_ON_DEV; - write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56 - + CONFIG_UART_FOR_CONSOLE * 2, byte); + write8((void *)FCH_ACPI_MMIO_AOAC_BASE + aoac_device_control_register, + byte); +}
- byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62); - byte |= AOAC_PWR_ON_DEV; - write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62, byte); +static bool is_aoac_device_enabled(int aoac_device_status_register) +{ + u8 byte; + byte = read8((void *)FCH_ACPI_MMIO_AOAC_BASE + + aoac_device_status_register); + byte &= (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE); + if (byte == (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE)) + return(true); + else + return(false); +} + +void configure_stoneyridge_i2c(void) +{ + bool status; + + /* Power on the I2C devices */ + power_on_aoac_device(AOAC_D3_CONTROL_I2C0); + power_on_aoac_device(AOAC_D3_CONTROL_I2C1); + power_on_aoac_device(AOAC_D3_CONTROL_I2C2); + power_on_aoac_device(AOAC_D3_CONTROL_I2C3); + + /* Wait for the I2C devices to indicate power and clock OK */ + do { + udelay(100); + status = is_aoac_device_enabled(AOAC_D3_STATE_I2C0); + status &= is_aoac_device_enabled(AOAC_D3_STATE_I2C1); + status &= is_aoac_device_enabled(AOAC_D3_STATE_I2C2); + status &= is_aoac_device_enabled(AOAC_D3_STATE_I2C3); + } while (!(status)); +} + +void sb_acpi_mmio_decode(void) +{ + u8 byte; + + /* Enable ACPI MMIO range 0xFED80000 - 0xFED81FFF */ + outb(PM_ISA_CONTROL, PM_INDEX); + byte = inb(PM_DATA); + byte |= MMIO_EN; + outb(PM_ISA_CONTROL, PM_INDEX); + outb(byte, PM_DATA); +} + +void configure_stoneyridge_uart(void) +{ + bool status; + + /* Power on the UART and AMBA devices */ + power_on_aoac_device(AOAC_D3_CONTROL_UART0 + + CONFIG_UART_FOR_CONSOLE * 2); + power_on_aoac_device(AOAC_D3_CONTROL_AMBA);
/* Set the GPIO mux to UART */ - write8((void *)FCH_IOMUXx89_UART0_RTS_L_EGPIO137, 0); - write8((void *)FCH_IOMUXx8A_UART0_TXD_EGPIO138, 0); - write8((void *)FCH_IOMUXx8E_UART1_RTS_L_EGPIO142, 0); - write8((void *)FCH_IOMUXx8F_UART1_TXD_EGPIO143, 0); + write8((void *)FCH_ACPI_MMIO_IOMUX_BASE + UART0_RTS_L_EGPIO137, + UART0_RTS_L); + write8((void *)FCH_ACPI_MMIO_IOMUX_BASE + UART0_TXD_EGPIO138, + UART0_TXD); + write8((void *)FCH_ACPI_MMIO_IOMUX_BASE + UART1_RTS_L_EGPIO142, + UART1_RTS_L); + write8((void *)FCH_ACPI_MMIO_IOMUX_BASE + UART1_TXD_EGPIO143, + UART1_TXD);
/* Wait for the UART and AMBA devices to indicate power and clock OK */ do { udelay(100); - byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG57 + status = is_aoac_device_enabled(AOAC_D3_STATE_UART0 + CONFIG_UART_FOR_CONSOLE * 2); - byte &= (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE); - byte2 = read8((void *)ACPI_MMIO_BASE + AOAC_BASE - + FCH_AOAC_REG63); - byte2 &= (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE); - } while (!((byte == (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE)) && - (byte2 == (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE)))); - + status &= is_aoac_device_enabled(AOAC_D3_STATE_AMBA); + } while (!(status)); }
void sb_pci_port80(void) @@ -367,11 +412,11 @@ * Enable the X14M_25M_48M_OSC pin and leaving it at it's default so * 48Mhz will be on ball AP13 (FT3b package) */ - ctrl = read32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40)); + ctrl = read32((void *)(FCH_ACPI_MMIO_MISC_BASE + MISC_MISC_CLK_CNTL_1));
/* clear the OSCOUT1_ClkOutputEnb to enable the 48 Mhz clock */ - ctrl &= ~FCH_MISC_REG40_OSCOUT1_EN; - write32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40), ctrl); + ctrl &= ~OSCOUT1_CLK_OUTPUT_ENB; + write32((void *)(FCH_ACPI_MMIO_MISC_BASE + MISC_MISC_CLK_CNTL_1), ctrl); }
static uintptr_t sb_spibase(void) @@ -428,8 +473,24 @@ & ~SPI_READ_MODE_MASK) | mode); }
+void sb_tpm_decode(void) +{ + /* Enable TPM decoding to FCH */ + u32 value = pci_read_config32(SOC_LPC_DEV, + LPC_TRUSTED_PLATFORM_MODULE); + value |= (TPM_12_EN | TPM_LEGACY_EN); + pci_write_config32(SOC_LPC_DEV, LPC_TRUSTED_PLATFORM_MODULE, value); +} + void sb_tpm_decode_spi(void) { + /* Enable TPM decoding to FCH */ + sb_tpm_decode(); + + /* Make sure SPI base register is programmed */ + sb_spibase(); + + /* Route TPM accesses to SPI */ u32 spibase = pci_read_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER); pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER, spibase @@ -487,6 +548,10 @@ sb_enable_rom(); sb_lpc_port80(); sb_lpc_decode(); + sb_set_spi100(SPI_SPEED_33M, + SPI_SPEED_33M, + SPI_SPEED_16M, + SPI_SPEED_16M); }
void sb_enable(device_t dev)