===================================================================
@@ -11,6 +11,7 @@
select SOUTHBRIDGE_AMD_SB700
select SUPERIO_WINBOND_W83627DHG
select BOARD_HAS_FADT
+ select HAVE_ACPI_RESUME
select HAVE_ACPI_TABLES
select HAVE_MP_TABLE
select HAVE_PIRQ_TABLE
===================================================================
@@ -2226,6 +2226,8 @@
#endif
{
int i;
+ u32 whatWAIT;
+ int a = acpi_is_wakeup_early();
/* Error if I don't have memory */
if (memory_end_k(ctrl, controllers) == 0) {
@@ -2264,6 +2266,9 @@
if (!(dch & DCH_MEMCLK_VALID)) {
continue;
}
+ enable_lapic();
+ init_timer();
+ delay(1);
/* Toggle DisDqsHys to get it working */
dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
@@ -2277,13 +2282,34 @@
}
pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
}
- dcl |= DCL_DisDqsHys;
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
- dcl &= ~DCL_DisDqsHys;
- dcl &= ~DCL_DLL_Disable;
- dcl &= ~DCL_D_DRV;
- dcl &= ~DCL_QFC_EN;
- dcl |= DCL_DramInit;
+
+ if (!a) {
+ dcl |= DCL_DisDqsHys;
+ pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+ }
+ dcl &= ~DCL_DisDqsHys;
+ dcl &= ~DCL_DLL_Disable;
+ dcl &= ~DCL_D_DRV;
+ dcl &= ~DCL_QFC_EN;
+
+ if (a) {
+ print_debug("Exiting self-refreSH2\n\r");
+ dcl |= (DCL_ESR | DCL_SRS);
+ /* Handle errata 85 - 85 Insufficient Delay Between MEMCLK Startup and CKE Assertion During Resume From S3 */
+ delay(1); /* for unregistered */
+ if (is_registered(&ctrl[i])) {
+ udelay(90); /* 100us for registered */
+ }
+ print_debug("Exiting self-refresh - after delay\n\r");
+ whatWAIT = DCL_ESR;
+
+ } else {
+ dcl |= DCL_DramInit;
+ whatWAIT = DCL_DramInit;
+ }
+// print_debug("Initializing memory delay... ");
+// delay(5); /* for unregistered */
+// print_debug("done\n ");
pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
}
@@ -2305,19 +2331,22 @@
if ((loops & 1023) == 0) {
printk(BIOS_DEBUG, ".");
}
- } while(((dcl & DCL_DramInit) != 0) && (loops < TIMEOUT_LOOPS));
+ } while(((dcl & whatWAIT) != 0) && (loops < TIMEOUT_LOOPS));
if (loops >= TIMEOUT_LOOPS) {
printk(BIOS_DEBUG, " failed\n");
continue;
}
+
if (!is_cpu_pre_c0()) {
/* Wait until it is safe to touch memory */
- dcl &= ~(DCL_MemClrStatus | DCL_DramEnable);
- pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+// dcl &= ~(DCL_MemClrStatus | DCL_DramEnable);
+// pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
do {
dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
- } while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) );
+ printk(BIOS_DEBUG, "DCL %x\r\n", dcl);
+ } while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) ||
+ ((dcl & DCL_SRS)));
}
printk(BIOS_DEBUG, " done\n");
===================================================================
@@ -24,10 +24,21 @@
#include "chip.h"
/* Power management index/data registers */
+#define BIOSRAM_INDEX 0xcd4
+#define BIOSRAM_DATA 0xcd5
#define PM_INDEX 0xcd6
#define PM_DATA 0xcd7
#define PM2_INDEX 0xcd0
#define PM2_DATA 0xcd1
+
+#define SB600_PM_BASE 0x800
+
+#define ACPI_PM_EVT_BLK (SB600_PM_BASE + 0x00) /* 4 bytes */
+#define ACPI_PM1_CNT_BLK (SB600_PM_BASE + 0x04) /* 2 bytes */
+#define ACPI_PMA_CNT_BLK (SB600_PM_BASE + 0x0F) /* 1 byte */
+#define ACPI_PM_TMR_BLK (SB600_PM_BASE + 0x18) /* 4 bytes */
+#define ACPI_GPE0_BLK (SB600_PM_BASE + 0x10) /* 8 bytes */
+#define ACPI_CPU_CONTORL (SB600_PM_BASE + 0x08) /* 6 bytes */
extern void pm_iowrite(u8 reg, u8 value);
extern u8 pm_ioread(u8 reg);
===================================================================
@@ -40,6 +40,34 @@
return inb(PM_INDEX + 1);
}
+static void sb700_acpi_init(void) {
+ pmio_write(0x20, ACPI_PM_EVT_BLK & 0xFF);
+ pmio_write(0x21, ACPI_PM_EVT_BLK >> 8);
+ pmio_write(0x22, ACPI_PM1_CNT_BLK & 0xFF);
+ pmio_write(0x23, ACPI_PM1_CNT_BLK >> 8);
+ pmio_write(0x24, ACPI_PM_TMR_BLK & 0xFF);
+ pmio_write(0x25, ACPI_PM_TMR_BLK >> 8);
+ pmio_write(0x28, ACPI_GPE0_BLK & 0xFF);
+ pmio_write(0x29, ACPI_GPE0_BLK >> 8);
+
+ /* CpuControl is in \_PR.CPU0, 6 bytes */
+ pmio_write(0x26, ACPI_CPU_CONTORL & 0xFF);
+ pmio_write(0x27, ACPI_CPU_CONTORL >> 8);
+
+ pmio_write(0x2A, 0); /* AcpiSmiCmdLo */
+ pmio_write(0x2B, 0); /* AcpiSmiCmdHi */
+
+ pmio_write(0x2C, ACPI_PMA_CNT_BLK & 0xFF);
+ pmio_write(0x2D, ACPI_PMA_CNT_BLK >> 8);
+
+ pmio_write(0x0E, 1<<3 | 0<<2); /* AcpiDecodeEnable, When set, SB uses
+ * the contents of the PM registers at
+ * index 20-2B to decode ACPI I/O address.
+ * AcpiSmiEn & SmiCmdEn*/
+ pmio_write(0x10, 1<<1 | 1<<3| 1<<5); /* RTC_En_En, TMR_En_En, GBL_EN_EN */
+}
+
+
/* RPR 2.28: Get SB ASIC Revision. */
static u8 set_sb700_revision(void)
{
@@ -610,10 +638,59 @@
{
printk(BIOS_INFO, "sb700_early_setup()\n");
sb700_por_init();
+ sb700_acpi_init();
}
static int smbus_read_byte(u32 device, u32 address)
{
return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
}
+#if 0
+int s3_save_nvram_early(u32 dword, int size, int nvram_pos) {
+ int i;
+ printk_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_debug("Loading %x of size %d to nvram pos:%d\n", * old_dword, size, nvram_pos-size);
+ return nvram_pos;
+}
+#endif
+static int acpi_is_wakeup_early(void) {
+ u16 tmp;
+ tmp = inw(ACPI_PM1_CNT_BLK);
+ printk(BIOS_DEBUG, "IN TEST WAKEUP %x\n", tmp);
+ return ((tmp & (7 << 10)) >> 10);
+}
+
+#define get_cbmem_toc() ( { struct cbmem_entry *p ; \
+ int xi; \
+ uint32_t xdata = 0; \
+ int xnvram_pos = 0xfc; \
+ for (xi = 0; xi<4; xi++) { \
+ outb(xnvram_pos, BIOSRAM_INDEX); \
+ xdata &= ~(0xff << (xi * 8)); \
+ xdata |= inb(BIOSRAM_DATA) << (xi *8); \
+ xnvram_pos++; \
+ } \
+p = (struct cbmem_entry *) xdata; \
+p; } )
+
#endif
===================================================================
@@ -63,8 +63,37 @@
byte = pci_read_config8(dev, 0x78);
byte &= ~(1 << 1);
pci_write_config8(dev, 0x78, byte);
+
+ /* hack, but the whole sb700 startup lacks any device which
+ is doing the acpi init */
+#if CONFIG_HAVE_ACPI_RESUME == 1
+extern u8 acpi_slp_type;
+
+ {
+ u16 tmp = inw(ACPI_PM1_CNT_BLK);
+ acpi_slp_type = ((tmp & (7 << 10)) >> 10);
+ printk(BIOS_DEBUG, "SLP_TYP type was %x %x\n", tmp, acpi_slp_type);
+ }
+#endif
+
}
+#include <cbmem.h>
+void set_cbmem_toc(struct cbmem_entry *toc) {
+int i;
+u32 dword = (u32) toc;
+int nvram_pos = 0xfc;
+ for (i = 0; i<4; i++) {
+ outb(nvram_pos, BIOSRAM_INDEX);
+ outb((dword >>(8 * i)) & 0xff , BIOSRAM_DATA);
+ nvram_pos++;
+ }
+
+
+// outl((u32) toc, K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC);
+}
+
+
static void sb700_lpc_read_resources(device_t dev)
{
struct resource *res;
===================================================================
@@ -34,12 +34,13 @@
* registers into 32 bytes limit.
* */
-#define ACPI_PM_EVT_BLK (pm_base + 0x00) /* 4 bytes */
-#define ACPI_PM1_CNT_BLK (pm_base + 0x04) /* 2 bytes */
-#define ACPI_PMA_CNT_BLK (pm_base + 0x0F) /* 1 byte */
-#define ACPI_PM_TMR_BLK (pm_base + 0x18) /* 4 bytes */
-#define ACPI_GPE0_BLK (pm_base + 0x10) /* 8 bytes */
-#define ACPI_CPU_CONTORL (pm_base + 0x08) /* 6 bytes */
+
+//#define ACPI_PM_EVT_BLK (pm_base + 0x00) /* 4 bytes */
+//#define ACPI_PM1_CNT_BLK (pm_base + 0x04) /* 2 bytes */
+//#define ACPI_PMA_CNT_BLK (pm_base + 0x0F) /* 1 byte */
+//#define ACPI_PM_TMR_BLK (pm_base + 0x18) /* 4 bytes */
+//#define ACPI_GPE0_BLK (pm_base + 0x10) /* 8 bytes */
+//#define ACPI_CPU_CONTORL (pm_base + 0x08) /* 6 bytes */
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
{
===================================================================
@@ -67,11 +67,22 @@
#include "lib/generic_sdram.c"
#include "resourcemap.c"
#include "cpu/amd/dualcore/dualcore.c"
+
+
+// Now, this needs to be included because it relies on the symbol
+// __PRE_RAM__ being set during CAR stage (in order to compile the
+// BSS free versions of the functions). Either rewrite the code
+// to be always BSS free, or invent a flag that's better suited than
+// __PRE_RAM__ to determine whether we're in ram init stage (stage 1)
+//
+#include "lib/cbmem.c"
+
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "cpu/amd/model_fxx/fidvid.c"
#include "northbridge/amd/amdk8/early_ht.c"
+
static void sio_init(void)
{
u8 reg;
Hi all attached patch adds the suspend/resume support for socket 939 and AMD 785G/710 (on asrock board) The patch is still WIP but works right now. The purpose is just to show how it is done. Signed-off-by: Rudolf Marek <r.marek@assembler.cz> Proper patches will hopefully follow. Thanks Rudolf