diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc index b62581cbb4..1b41292f7f 100644 --- a/src/soc/amd/stoneyridge/Makefile.inc +++ b/src/soc/amd/stoneyridge/Makefile.inc @@ -45,6 +45,7 @@ bootblock-y += pmutil.c bootblock-y += reset.c bootblock-y += sb_util.c bootblock-y += tsc_freq.c +bootblock-y += southbridge.c romstage-y += BiosCallOuts.c romstage-y += romstage.c @@ -60,6 +61,7 @@ romstage-y += smbus_spd.c romstage-y += ramtop.c romstage-$(CONFIG_STONEYRIDGE_UART) += uart.c romstage-y += tsc_freq.c +romstage-y += southbridge.c verstage-y += sb_util.c verstage-y += pmutil.c diff --git a/src/soc/amd/stoneyridge/early_setup.c b/src/soc/amd/stoneyridge/early_setup.c index ec3baa4d8b..09eb8b6aa3 100644 --- a/src/soc/amd/stoneyridge/early_setup.c +++ b/src/soc/amd/stoneyridge/early_setup.c @@ -27,98 +27,6 @@ #include #include -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; - pci_devfn_t dev; - - dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); - - byte = pci_read_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH); - byte &= ~DECODE_IO_PORT_ENABLE4_H; /* disable lpc port 80 */ - pci_write_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH, byte); -} - -void sb_lpc_port80(void) -{ - u8 byte; - pci_devfn_t dev; - - /* 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. */ - dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); - byte = pci_read_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH); - byte |= DECODE_IO_PORT_ENABLE4_H; /* enable port 80 */ - pci_write_config8(dev, LPC_IO_OR_MEM_DEC_EN_HIGH, byte); -} - -void sb_lpc_decode(void) -{ - pci_devfn_t dev; - u32 tmp = 0; - - /* Enable I/O decode to LPC bus */ - dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); - 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(dev, LPC_IO_PORT_DECODE_ENABLE, tmp); -} - static void enable_wideio(uint8_t port, uint16_t size) { uint32_t wideio_enable[] = { @@ -205,169 +113,3 @@ void lpc_wideio_16_window(uint16_t base) assert(IS_ALIGNED(base, 16)); lpc_wideio_window(base, 16); } - -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; -} - -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) -{ - /* Make sure the base address is predictable */ - device_t dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); - u32 base, enables; - - base = pci_read_config32(dev, SPIROM_BASE_ADDRESS_REGISTER); - enables = base & 0xf; - base &= ~0x3f; - - if (!base) { - base = SPI_BASE_ADDRESS; - pci_write_config32(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) -{ - device_t dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); /* LPC device */ - - u32 spibase = pci_read_config32(dev, SPIROM_BASE_ADDRESS_REGISTER); - pci_write_config32(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; - pci_devfn_t dev; - - dev = PCI_DEV(0, PCU_DEV, LPC_FUNC); - - /* - * Decode variable LPC ROM address ranges 1 and 2. - * Bits 3-4 are not defined in any publicly available datasheet - */ - reg8 = pci_io_read_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE); - reg8 |= (1 << 3) | (1 << 4); - pci_io_write_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE, reg8); - - /* - * LPC ROM address range 1: - * Enable LPC ROM range mirroring start at 0x000e(0000). - */ - pci_io_write_config16(dev, ROM_ADDRESS_RANGE1_START, 0x000e); - - /* Enable LPC ROM range mirroring end at 0x000f(ffff). */ - pci_io_write_config16(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_io_write_config16(dev, ROM_ADDRESS_RANGE2_START, 0x10000 - - (CONFIG_COREBOOT_ROMSIZE_KB >> 6)); - - /* Enable LPC ROM range end at 0xffff(ffff). */ - pci_io_write_config16(dev, ROM_ADDRESS_RANGE2_END, 0xffff); -} - -void bootblock_fch_early_init(void) -{ - sb_enable_rom(); - sb_lpc_port80(); - sb_lpc_decode(); -} 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 #include #include +#include +#include +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) {