#ifndef _SB700_EARLY_SETUP_C_
#define _SB700_EARLY_SETUP_C_
+#include <stdint.h>
+#include <arch/cpu.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+
#include <reset.h>
#include <arch/cpu.h>
+#include <cbmem.h>
#include "sb700.h"
-#include "smbus.c"
+#include "smbus.h"
-#define SMBUS_IO_BASE 0x6000 /* Is it a temporary SMBus I/O base address? */
- /*SIZE 0x40 */
static void pmio_write(u8 reg, u8 value)
{
return inb(PM_INDEX + 1);
}
+static void sb700_acpi_init(void)
+{
+ u16 word;
+ 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_CONTROL & 0xFF);
+ pmio_write(0x27, ACPI_CPU_CONTROL >> 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 */
+ word = inl(ACPI_PM1_CNT_BLK);
+ word |= 1;
+ outl(word, ACPI_PM1_CNT_BLK); /* set SCI_EN */
+}
+
/* RPR 2.28: Get SB ASIC Revision. */
static u8 set_sb700_revision(void)
{
* Console output through any port besides 0x3f8 is unsupported.
* If you use FWH ROMs, you have to setup IDSEL.
***************************************/
-static void sb700_lpc_init(void)
+void sb7xx_51xx_lpc_init(void)
{
u8 reg8;
u32 reg32;
reg32 |= 1 << 20;
pci_write_config32(dev, 0x64, reg32);
+#if CONFIG_SOUTHBRIDGE_AMD_SP5100
+ post_code(0x66);
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439d), 0); /* LPC Controller */
+ reg8 = pci_read_config8(dev, 0xBB);
+ reg8 |= 1 << 2 | 1 << 3 | 1 << 6 | 1 << 7;
+ reg8 &= ~(1 << 1);
+ pci_write_config8(dev, 0xBB, reg8);
+#endif
+
dev = pci_locate_device(PCI_ID(0x1002, 0x439d), 0); /* LPC Controller */
/* Decode port 0x3f8-0x3ff (Serial 0) */
// XXX Serial port decode on LPC is hardcoded to 0x3f8
reg8 = pci_read_config8(dev, 0x44);
reg8 |= 1 << 6;
+#if CONFIG_SOUTHBRIDGE_AMD_SP5100
+#if CONFIG_TTYS0_BASE == 0x2f8
+ reg8 |= 1 << 7;
+#endif
+#endif
pci_write_config8(dev, 0x44, reg8);
/* Decode port 0x60 & 0x64 (PS/2 keyboard) and port 0x62 & 0x66 (ACPI)*/
pci_write_config8(dev, 0x48, reg8);
}
+void sb7xx_51xx_enable_wideio(u8 wio_index, u16 base)
+{
+ /* TODO: Now assume wio_index=0 */
+ device_t dev;
+ u8 reg8;
+
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439d), 0); /* LPC Controller */
+ pci_write_config32(dev, 0x64, base);
+ reg8 = pci_read_config8(dev, 0x48);
+ reg8 |= 1 << 2;
+ pci_write_config8(dev, 0x48, reg8);
+}
+
+void sb7xx_51xx_disable_wideio(u8 wio_index)
+{
+ /* TODO: Now assume wio_index=0 */
+ device_t dev;
+ u8 reg8;
+
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439d), 0); /* LPC Controller */
+ pci_write_config32(dev, 0x64, 0);
+ reg8 = pci_read_config8(dev, 0x48);
+ reg8 &= ~(1 << 2);
+ pci_write_config8(dev, 0x48, reg8);
+}
+
/* what is its usage? */
-static u32 get_sbdn(u32 bus)
+u32 __attribute__ ((weak)) get_sbdn(u32 bus)
{
device_t dev;
/*
* RPR 2.4 C-state and VID/FID change for the K8 platform.
*/
-static void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
+void __attribute__((weak)) enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
{
u8 byte;
byte = pmio_read(0x9a);
pmio_write(0x42, byte);
pmio_write(0x89, 0x10);
-}
-
-void hard_reset(void)
-{
- set_bios_reset();
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
+ /* Toggle the LDT_STOP# during FID/VID Change, this bit is documented
+ only in SB600!
+ While here, enable C states too
+ */
+ pmio_write(0x67, 0x6);
}
-void soft_reset(void)
-{
- set_bios_reset();
- /* link reset */
- outb(0x06, 0x0cf9);
-}
-
-void sb700_pci_port80(void)
+void sb7xx_51xx_pci_port80(void)
{
u8 byte;
device_t dev;
pci_write_config8(dev, 0x4A, byte);
}
-void sb700_lpc_port80(void)
+void sb7xx_51xx_lpc_port80(void)
{
u8 byte;
device_t dev;
{
device_t dev;
u8 byte;
+#if CONFIG_SOUTHBRIDGE_AMD_SP5100
+ u32 dword;
+#endif
printk(BIOS_INFO, "sb700_devices_por_init()\n");
/* SMBus Device, BDF:0-20-0 */
/* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */
pci_write_config8(dev, 0x50, 0x01);
+#if CONFIG_SOUTHBRIDGE_AMD_SP5100
+ /* SP5100 default SATA mode is RAID5 MODE */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4393), 0);
+ /* Set SATA Operation Mode, Set to IDE mode */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 0);
+ pci_write_config8(dev, 0x40, byte);
+
+ dword = 0x01018f00;
+ pci_write_config32(dev, 0x8, dword);
+
+ /* set SATA Device ID writable */
+ dword = pci_read_config32(dev, 0x40);
+ dword &= ~(1 << 24);
+ pci_write_config32(dev, 0x40, dword);
+
+ /* set Device ID accommodate with IDE emulation mode configuration*/
+ pci_write_config32(dev, 0x0, 0x43901002);
+
+ /* rpr v2.13 4.17 Reset CPU on Sync Flood */
+ abcfg_reg(0x10050, 1 << 2, 1 << 2);
+#endif
+
/* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
printk(BIOS_INFO, "sb700_devices_por_init(): SATA Device, BDF:0-18-0\n");
dev = pci_locate_device(PCI_ID(0x1002, 0x4390), 0);
/*
* It should be called during early POST after memory detection and BIOS shadowing but before PCI bus enumeration.
*/
-static void sb700_before_pci_init(void)
+void sb7xx_51xx_before_pci_init(void)
{
sb700_pci_cfg();
}
/*
* This function should be called after enable_sb700_smbus().
*/
-static void sb700_early_setup(void)
+void sb7xx_51xx_early_setup(void)
{
printk(BIOS_INFO, "sb700_early_setup()\n");
sb700_por_init();
+ sb700_acpi_init();
}
-static int smbus_read_byte(u32 device, u32 address)
+int s3_save_nvram_early(u32 dword, int size, int nvram_pos)
{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+ 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;
+}
+
+#if CONFIG_HAVE_ACPI_RESUME == 1
+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) == 3);
}
#endif
+
+struct cbmem_entry *get_cbmem_toc(void)
+{
+ uint32_t xdata = 0;
+ int xnvram_pos = 0xfc, xi;
+ for (xi = 0; xi<4; xi++) {
+ outb(xnvram_pos, BIOSRAM_INDEX);
+ xdata &= ~(0xff << (xi * 8));
+ xdata |= inb(BIOSRAM_DATA) << (xi *8);
+ xnvram_pos++;
+ }
+ return (struct cbmem_entry *) xdata;
+}
+
+#endif