diff options
Diffstat (limited to 'resources/libreboot/patch/kgpe-d16/0019-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch')
-rw-r--r-- | resources/libreboot/patch/kgpe-d16/0019-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/resources/libreboot/patch/kgpe-d16/0019-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch b/resources/libreboot/patch/kgpe-d16/0019-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch new file mode 100644 index 00000000..a097102e --- /dev/null +++ b/resources/libreboot/patch/kgpe-d16/0019-southbridge-amd-sb700-Add-Suspend-to-RAM-S3-support.patch @@ -0,0 +1,365 @@ +From a0ab6743661d88d7e7c699bc8e506e9b1243749c Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <kb9vqf@pearsoncomputing.net> +Date: Sat, 5 Sep 2015 18:14:25 -0500 +Subject: [PATCH 019/146] southbridge/amd/sb700: Add Suspend to RAM (S3) + support + +--- + src/southbridge/amd/sb700/Makefile.inc | 1 + + src/southbridge/amd/sb700/bootblock.c | 4 +- + src/southbridge/amd/sb700/early_setup.c | 39 ++++++-- + src/southbridge/amd/sb700/lpc.c | 12 ++- + src/southbridge/amd/sb700/sb700.h | 3 + + src/southbridge/amd/sb700/spi.c | 148 +++++++++++++++++++++++++++++++ + src/southbridge/amd/sb700/spi.h | 21 +++++ + 7 files changed, 216 insertions(+), 12 deletions(-) + create mode 100644 src/southbridge/amd/sb700/spi.c + create mode 100644 src/southbridge/amd/sb700/spi.h + +diff --git a/src/southbridge/amd/sb700/Makefile.inc b/src/southbridge/amd/sb700/Makefile.inc +index 5ec8431..538a7c1 100644 +--- a/src/southbridge/amd/sb700/Makefile.inc ++++ b/src/southbridge/amd/sb700/Makefile.inc +@@ -12,6 +12,7 @@ ramstage-y += pci.c + ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c + romstage-y += reset.c + ramstage-y += reset.c ++ramstage-y += spi.c + romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c + ramstage-$(CONFIG_USBDEBUG) += enable_usbdebug.c + +diff --git a/src/southbridge/amd/sb700/bootblock.c b/src/southbridge/amd/sb700/bootblock.c +index 8f722a8..46e5597 100644 +--- a/src/southbridge/amd/sb700/bootblock.c ++++ b/src/southbridge/amd/sb700/bootblock.c +@@ -71,7 +71,7 @@ static void sb700_enable_rom(void) + /* Enable LPC ROM range end at 0xffff(ffff). */ + pci_io_write_config16(dev, 0x6e, 0xffff); + +- /* SB700 LPC Bridge 0x48h. ++ /* SB700 LPC Bridge 0x48. + * Turn on all LPC IO Port decode enables + */ + dword = pci_io_read_config32(dev, 0x44); +@@ -89,7 +89,7 @@ static void sb700_enable_rom(void) + reg8 |= (1<<0) | (1<<1) | (1<<4) | (1<<6); + pci_io_write_config8(dev, 0x48, reg8); + +- /* SB700 LPC Bridge 0x4ah. ++ /* SB700 LPC Bridge 0x4a. + * BIT4: Port Enable for Port 0x80 + */ + reg8 = pci_io_read_config8(dev, 0x4a); +diff --git a/src/southbridge/amd/sb700/early_setup.c b/src/southbridge/amd/sb700/early_setup.c +index de3fa97..a6849b0 100644 +--- a/src/southbridge/amd/sb700/early_setup.c ++++ b/src/southbridge/amd/sb700/early_setup.c +@@ -474,8 +474,10 @@ static void sb700_devices_por_init(void) + /* LPC Device, BDF:0-20-3 */ + printk(BIOS_INFO, "sb700_devices_por_init(): LPC Device, BDF:0-20-3\n"); + dev = pci_locate_device(PCI_ID(0x1002, 0x439D), 0); +- /* DMA enable */ +- pci_write_config8(dev, 0x40, 0x04); ++ if (!IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA)) { ++ /* DMA enable */ ++ pci_write_config8(dev, 0x40, 0x04); ++ } + + /* IO Port Decode Enable */ + pci_write_config8(dev, 0x44, 0xFF); +@@ -618,6 +620,17 @@ static void sb700_pmio_por_init(void) + byte = pmio_read(0xB2); + byte |= 1 << 0; + pmio_write(0xB2, byte); ++ ++ // FIXME: Enabling this causes boot to hang while initializing processors. ++// /* Enable automatic C1e state switch */ ++// byte = pmio_read(0xc9); ++// byte |= 0x11; ++// pmio_write(0xc9, byte); ++ ++ /* Enable precision HPET clock and automatic C state switch */ ++ byte = pmio_read(0xbb); ++ byte |= 0xc0; ++ pmio_write(0xbb, byte); + } + + /* +@@ -653,10 +666,12 @@ static void sb700_pci_cfg(void) + * mentioned in RPR. But I keep them. The registers and the + * comments are compatible. */ + dev = pci_locate_device(PCI_ID(0x1002, 0x439D), 0); +- /* Enabling LPC DMA function. */ +- byte = pci_read_config8(dev, 0x40); +- byte |= (1 << 2); +- pci_write_config8(dev, 0x40, byte); ++ if (!IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA)) { ++ /* Enabling LPC DMA function. */ ++ byte = pci_read_config8(dev, 0x40); ++ byte |= (1 << 2); ++ pci_write_config8(dev, 0x40, byte); ++ } + /* Disabling LPC TimeOut. 0x48[7] clear. */ + byte = pci_read_config8(dev, 0x48); + byte &= 0x7f; +@@ -746,6 +761,18 @@ int acpi_get_sleep_type(void) + return ((tmp & (7 << 10)) >> 10); + } + ++void set_lpc_sticky_ctl(bool enable) ++{ ++ uint8_t byte; ++ ++ byte = pmio_read(0xbb); ++ if (enable) ++ byte |= 0x20; ++ else ++ byte &= ~0x20; ++ pmio_write(0xbb, byte); ++} ++ + #if IS_ENABLED(CONFIG_LATE_CBMEM_INIT) + unsigned long get_top_of_ram(void) + { +diff --git a/src/southbridge/amd/sb700/lpc.c b/src/southbridge/amd/sb700/lpc.c +index 0cc1e8b..145a01f 100644 +--- a/src/southbridge/amd/sb700/lpc.c ++++ b/src/southbridge/amd/sb700/lpc.c +@@ -61,10 +61,12 @@ static void lpc_init(device_t dev) + isa_dma_init(); + #endif + +- /* Enable DMA transaction on the LPC bus */ +- byte = pci_read_config8(dev, 0x40); +- byte |= (1 << 2); +- pci_write_config8(dev, 0x40, byte); ++ if (!IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA)) { ++ /* Enable DMA transaction on the LPC bus */ ++ byte = pci_read_config8(dev, 0x40); ++ byte |= (1 << 2); ++ pci_write_config8(dev, 0x40, byte); ++ } + + /* Disable the timeout mechanism on LPC */ + byte = pci_read_config8(dev, 0x48); +@@ -85,11 +87,13 @@ static void lpc_init(device_t dev) + cmos_check_update_date(); + } + ++#if (!IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)) + int acpi_get_sleep_type(void) + { + u16 tmp = inw(ACPI_PM1_CNT_BLK); + return ((tmp & (7 << 10)) >> 10); + } ++#endif + + #if IS_ENABLED(CONFIG_LATE_CBMEM_INIT) + void backup_top_of_ram(uint64_t ramtop) +diff --git a/src/southbridge/amd/sb700/sb700.h b/src/southbridge/amd/sb700/sb700.h +index ca020a5..b477091 100644 +--- a/src/southbridge/amd/sb700/sb700.h ++++ b/src/southbridge/amd/sb700/sb700.h +@@ -2,6 +2,7 @@ + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -75,6 +76,8 @@ void sb7xx_51xx_setup_sata_phys(struct device *dev); + + #endif + ++void set_lpc_sticky_ctl(bool enable); ++ + int s3_save_nvram_early(u32 dword, int size, int nvram_pos); + int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos); + +diff --git a/src/southbridge/amd/sb700/spi.c b/src/southbridge/amd/sb700/spi.c +new file mode 100644 +index 0000000..a38ca2b +--- /dev/null ++++ b/src/southbridge/amd/sb700/spi.c +@@ -0,0 +1,148 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2012 Advanced Micro Devices, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include <stdint.h> ++#include <stdlib.h> ++#include <string.h> ++#include <arch/io.h> ++#include <console/console.h> ++#include <spi-generic.h> ++#include <spi_flash.h> ++#include <device/device.h> ++#include <device/pci.h> ++#include <device/pci_ops.h> ++ ++#define AMD_SB_SPI_TX_LEN 8 ++ ++static uint32_t get_spi_bar(void) ++{ ++ device_t dev; ++ ++ dev = dev_find_slot(0, PCI_DEVFN(0x14, 3)); ++ return pci_read_config32(dev, 0xa0) & ~0x1f; ++} ++ ++void spi_init(void) ++{ ++ /* Not needed */ ++} ++ ++unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) ++{ ++ return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len); ++} ++ ++static void reset_internal_fifo_pointer(void) ++{ ++ uint32_t spibar = get_spi_bar(); ++ ++ do { ++ write8((void *)(spibar + 2), ++ read8((void *)(spibar + 2)) | 0x10); ++ } while (read8((void *)(spibar + 0xd)) & 0x7); ++} ++ ++static void execute_command(void) ++{ ++ uint32_t spibar = get_spi_bar(); ++ ++ write8((void *)(spibar + 2), read8((void *)(spibar + 2)) | 1); ++ ++ while ((read8((void *)(spibar + 2)) & 1) && ++ (read8((void *)(spibar+3)) & 0x80)); ++} ++ ++int spi_claim_bus(struct spi_slave *slave) ++{ ++ /* Handled internally by the SB700 */ ++ return 0; ++} ++ ++void spi_release_bus(struct spi_slave *slave) ++{ ++ /* Handled internally by the SB700 */ ++} ++ ++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) ++{ ++ struct spi_slave *slave = malloc(sizeof(*slave)); ++ ++ if (!slave) { ++ return NULL; ++ } ++ ++ memset(slave, 0, sizeof(*slave)); ++ ++ return slave; ++} ++ ++int spi_xfer(struct spi_slave *slave, const void *dout, ++ unsigned int bytesout, void *din, unsigned int bytesin) ++{ ++ /* First byte is cmd which cannot be sent through the FIFO. */ ++ u8 cmd = *(u8 *)dout++; ++ u8 readoffby1; ++ u8 readwrite; ++ u8 count; ++ ++ uint32_t spibar = get_spi_bar(); ++ ++ bytesout--; ++ ++ /* ++ * Check if this is a write command attempting to transfer more bytes ++ * than the controller can handle. Iterations for writes are not ++ * supported here because each SPI write command needs to be preceded ++ * and followed by other SPI commands, and this sequence is controlled ++ * by the SPI chip driver. ++ */ ++ if (bytesout > AMD_SB_SPI_TX_LEN) { ++ printk(BIOS_DEBUG, "FCH SPI: Too much to write. Does your SPI chip driver use" ++ " spi_crop_chunk()?\n"); ++ return -1; ++ } ++ ++ readoffby1 = bytesout ? 0 : 1; ++ ++ readwrite = (bytesin + readoffby1) << 4 | bytesout; ++ write8((void *)(spibar + 1), readwrite); ++ write8((void *)(spibar + 0), cmd); ++ ++ reset_internal_fifo_pointer(); ++ for (count = 0; count < bytesout; count++, dout++) { ++ write8((void *)(spibar + 0x0C), *(u8 *)dout); ++ } ++ ++ reset_internal_fifo_pointer(); ++ execute_command(); ++ ++ reset_internal_fifo_pointer(); ++ /* Skip the bytes we sent. */ ++ for (count = 0; count < bytesout; count++) { ++ cmd = read8((void *)(spibar + 0x0C)); ++ } ++ ++ reset_internal_fifo_pointer(); ++ for (count = 0; count < bytesin; count++, din++) { ++ *(u8 *)din = read8((void *)(spibar + 0x0C)); ++ } ++ ++ return 0; ++} +\ No newline at end of file +diff --git a/src/southbridge/amd/sb700/spi.h b/src/southbridge/amd/sb700/spi.h +new file mode 100644 +index 0000000..9b76b35 +--- /dev/null ++++ b/src/southbridge/amd/sb700/spi.h +@@ -0,0 +1,21 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++int spi_claim_bus(struct spi_slave *slave); ++void spi_release_bus(struct spi_slave *slave); +\ No newline at end of file +-- +1.7.9.5 + |