diff options
author | Richard Spiegel <richard.spiegel@silverbackltd.com> | 2017-11-24 07:41:29 -0700 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2017-12-04 22:27:03 +0000 |
commit | bec44f22a49f3a74d26eb551cd5fd4c14fa2427a (patch) | |
tree | 33ce1aecabfb311cbca84ff2d3c036f6f8f2257e /src/soc/amd/stoneyridge/southbridge.c | |
parent | 61c817d0af3db14a69d3dbf9285e9670097893e1 (diff) |
amd/stoneyridge: Transfer functions from early_setup.c to southbridge.c
In preparation to deleting early_setup,c, transfer all functions except
those related to wide IO to southbridge.c.
BUG=b:64033893
TEST=Build and boot to OS.
Change-Id: Ibe1d87cb3e0eb3e8ed4d2dc2adbddf2e13557c9e
Signed-off-by: Richard Spiegel <richard.spiegel@silverbackltd.com>
Reviewed-on: https://review.coreboot.org/22568
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/amd/stoneyridge/southbridge.c')
-rw-r--r-- | src/soc/amd/stoneyridge/southbridge.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 600b064f2d..dbf27bc6b8 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -28,7 +28,254 @@ #include <soc/southbridge.h> #include <soc/smi.h> #include <fchec.h> +#include <delay.h> +#include <soc/pci_devs.h> +void configure_stoneyridge_uart(void) +{ + u8 byte, byte2; + + if (CONFIG_UART_FOR_CONSOLE < 0 || CONFIG_UART_FOR_CONSOLE > 1) + return; + + /* Power on the UART and AMBA devices */ + byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56 + + CONFIG_UART_FOR_CONSOLE * 2); + byte |= AOAC_PWR_ON_DEV; + write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56 + + CONFIG_UART_FOR_CONSOLE * 2, 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); + + /* 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); + + /* 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 + + 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)))); + +} + +void sb_pci_port80(void) +{ + u8 byte; + + byte = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH); + byte &= ~DECODE_IO_PORT_ENABLE4_H; /* disable lpc port 80 */ + pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH, byte); +} + +void sb_lpc_port80(void) +{ + u8 byte; + + /* Enable LPC controller */ + outb(PM_LPC_GATING, PM_INDEX); + byte = inb(PM_DATA); + byte |= PM_LPC_ENABLE; + outb(PM_LPC_GATING, PM_INDEX); + outb(byte, PM_DATA); + + /* Enable port 80 LPC decode in pci function 3 configuration space. */ + byte = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH); + byte |= DECODE_IO_PORT_ENABLE4_H; /* enable port 80 */ + pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH, byte); +} + +void sb_lpc_decode(void) +{ + u32 tmp = 0; + + /* Enable I/O decode to LPC bus */ + tmp = DECODE_ENABLE_PARALLEL_PORT0 | DECODE_ENABLE_PARALLEL_PORT2 + | DECODE_ENABLE_PARALLEL_PORT4 | DECODE_ENABLE_SERIAL_PORT0 + | DECODE_ENABLE_SERIAL_PORT1 | DECODE_ENABLE_SERIAL_PORT2 + | DECODE_ENABLE_SERIAL_PORT3 | DECODE_ENABLE_SERIAL_PORT4 + | DECODE_ENABLE_SERIAL_PORT5 | DECODE_ENABLE_SERIAL_PORT6 + | DECODE_ENABLE_SERIAL_PORT7 | DECODE_ENABLE_AUDIO_PORT0 + | DECODE_ENABLE_AUDIO_PORT1 | DECODE_ENABLE_AUDIO_PORT2 + | DECODE_ENABLE_AUDIO_PORT3 | DECODE_ENABLE_MSS_PORT2 + | DECODE_ENABLE_MSS_PORT3 | DECODE_ENABLE_FDC_PORT0 + | DECODE_ENABLE_FDC_PORT1 | DECODE_ENABLE_GAME_PORT + | DECODE_ENABLE_KBC_PORT | DECODE_ENABLE_ACPIUC_PORT + | DECODE_ENABLE_ADLIB_PORT; + + pci_write_config32(SOC_LPC_DEV, LPC_IO_PORT_DECODE_ENABLE, tmp); +} + +void sb_clk_output_48Mhz(void) +{ + u32 ctrl; + + /* + * 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)); + + /* 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); +} + +static uintptr_t sb_spibase(void) +{ + u32 base, enables; + + /* Make sure the base address is predictable */ + base = pci_read_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER); + enables = base & 0xf; + base &= ~0x3f; + + if (!base) { + base = SPI_BASE_ADDRESS; + pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER, + base | enables | SPI_ROM_ENABLE); + /* PCI_COMMAND_MEMORY is read-only and enabled. */ + } + return (uintptr_t)base; +} + +void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm) +{ + uintptr_t base = sb_spibase(); + write16((void *)base + SPI100_SPEED_CONFIG, + (norm << SPI_NORM_SPEED_NEW_SH) | + (fast << SPI_FAST_SPEED_NEW_SH) | + (alt << SPI_ALT_SPEED_NEW_SH) | + (tpm << SPI_TPM_SPEED_NEW_SH)); + write16((void *)base + SPI100_ENABLE, SPI_USE_SPI100); +} + +void sb_disable_4dw_burst(void) +{ + uintptr_t base = sb_spibase(); + write16((void *)base + SPI100_HOST_PREF_CONFIG, + read16((void *)base + SPI100_HOST_PREF_CONFIG) + & ~SPI_RD4DW_EN_HOST); +} + +void sb_set_readspeed(u16 norm, u16 fast) +{ + uintptr_t base = sb_spibase(); + write16((void *)base + SPI_CNTRL1, (read16((void *)base + SPI_CNTRL1) + & ~SPI_CNTRL1_SPEED_MASK) + | (norm << SPI_NORM_SPEED_SH) + | (fast << SPI_FAST_SPEED_SH)); +} + +void sb_read_mode(u32 mode) +{ + uintptr_t base = sb_spibase(); + write32((void *)base + SPI_CNTRL0, + (read32((void *)base + SPI_CNTRL0) + & ~SPI_READ_MODE_MASK) | mode); +} + +void sb_tpm_decode_spi(void) +{ + u32 spibase = pci_read_config32(SOC_LPC_DEV, + SPIROM_BASE_ADDRESS_REGISTER); + pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER, spibase + | ROUTE_TPM_2_SPI); +} + +/* + * Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF. + * + * Hardware should enable LPC ROM by pin straps. This function does not + * handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations. + * + * The southbridge power-on default is to map 512K ROM space. + * + */ +void sb_enable_rom(void) +{ + u8 reg8; + + /* + * Decode variable LPC ROM address ranges 1 and 2. + * Bits 3-4 are not defined in any publicly available datasheet + */ + reg8 = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DECODE_ENABLE); + reg8 |= (1 << 3) | (1 << 4); + pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DECODE_ENABLE, reg8); + + /* + * LPC ROM address range 1: + * Enable LPC ROM range mirroring start at 0x000e(0000). + */ + pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE1_START, 0x000e); + + /* Enable LPC ROM range mirroring end at 0x000f(ffff). */ + pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE1_END, 0x000f); + + /* + * LPC ROM address range 2: + * + * Enable LPC ROM range start at: + * 0xfff8(0000): 512KB + * 0xfff0(0000): 1MB + * 0xffe0(0000): 2MB + * 0xffc0(0000): 4MB + */ + pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE2_START, 0x10000 + - (CONFIG_COREBOOT_ROMSIZE_KB >> 6)); + + /* Enable LPC ROM range end at 0xffff(ffff). */ + pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE2_END, 0xffff); +} + +void bootblock_fch_early_init(void) +{ + sb_enable_rom(); + sb_lpc_port80(); + sb_lpc_decode(); +} + +int s3_save_nvram_early(u32 dword, int size, int nvram_pos) +{ + int i; + printk(BIOS_DEBUG, "Writing %x of size %d to nvram pos: %d\n", + dword, size, nvram_pos); + + for (i = 0; i < size; i++) { + outb(nvram_pos, BIOSRAM_INDEX); + outb((dword >> (8 * i)) & 0xff, BIOSRAM_DATA); + nvram_pos++; + } + + return nvram_pos; +} + +int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos) +{ + u32 data = *old_dword; + int i; + for (i = 0; i < size; i++) { + outb(nvram_pos, BIOSRAM_INDEX); + data &= ~(0xff << (i * 8)); + data |= inb(BIOSRAM_DATA) << (i * 8); + nvram_pos++; + } + *old_dword = data; + printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n", + *old_dword, size, nvram_pos-size); + return nvram_pos; +} int acpi_get_sleep_type(void) { |