remove trailing whitespace
[coreboot.git] / src / southbridge / amd / sb700 / early_setup.c
index 81ffc1c7d502b7ea80fcf9cc94793d6ab25c4fc3..1f46da2228828f9b8f27d944694d9543d5b95dcc 100644 (file)
 #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)
 {
@@ -40,6 +46,38 @@ static u8 pmio_read(u8 reg)
        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)
 {
@@ -92,12 +130,11 @@ static u8 set_sb700_revision(void)
 *      Serial port 0
 *      KBC Port
 *      ACPI Micro-controller port
-*      LPC ROM size
 *      This function does not change port 0x80 decoding.
 *      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;
@@ -117,11 +154,25 @@ static void sb700_lpc_init(void)
        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)*/
@@ -134,31 +185,43 @@ static void sb700_lpc_init(void)
        reg8 |= 1 << 0;
        pci_write_config8(dev, 0xbb, reg8);
 
-       /* SuperIO, LPC ROM */
+       /* Super I/O, RTC */
        reg8 = pci_read_config8(dev, 0x48);
        /* Decode ports 0x2e-0x2f, 0x4e-0x4f (SuperI/O configuration) */
        reg8 |= (1 << 1) | (1 << 0);
-       /* Decode variable LPC ROM address ranges 1&2 (see register 0x68-0x6b, 0x6c-0x6f) */
-       reg8 |= (1 << 3) | (1 << 4);
        /* Decode port 0x70-0x73 (RTC) */
-       reg8 |= 1 << 6;
+       reg8 |= (1 << 6);
+       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);
+}
 
-       /* hardware should enable LPC ROM by pin straps */
-       /* ROM access at 0xFFF80000/0xFFF00000 - 0xFFFFFFFF */
-       /* See detail in 43366_sb700_bdg_nda_1.01.pdf page 17. */
-       /* enable LPC ROM range mirroring start 0x000e(0000) */
-       pci_write_config16(dev, 0x68, 0x000e);
-       /* enable LPC ROM range mirroring end   0x000f(ffff) */
-       pci_write_config16(dev, 0x6a, 0x000f);
-       /* enable LPC ROM range start, 0xfff8(0000): 512KB, 0xfff0(0000): 1MB */
-       pci_write_config16(dev, 0x6c, 0xfff0);
-       /* enable LPC ROM range end at 0xffff(ffff) */
-       pci_write_config16(dev, 0x6e, 0xffff);
+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;
 
@@ -175,7 +238,7 @@ static u8 dual_core(void)
 /*
  * 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);
@@ -218,25 +281,15 @@ static void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
        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;
@@ -281,7 +334,7 @@ void sb700_pci_port80(void)
        pci_write_config8(dev, 0x4A, byte);
 }
 
-void sb700_lpc_port80(void)
+void sb7xx_51xx_lpc_port80(void)
 {
        u8 byte;
        device_t dev;
@@ -305,6 +358,9 @@ static void sb700_devices_por_init(void)
 {
        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 */
@@ -403,13 +459,12 @@ static void sb700_devices_por_init(void)
        pci_write_config8(dev, 0x46, 0xC3);
        pci_write_config8(dev, 0x47, 0xFF);
 
+       // TODO: This has already been done(?)
        /* IO/Mem Port Decode Enable, I don't know why CIM disable some ports.
         *  Disable LPC TimeOut counter, enable SuperIO Configuration Port (2e/2f),
-        * Alternate SuperIO Configuration Port (4e/4f), Wide Generic IO Port (64/65).
-        * Enable bits for LPC ROM memory address range 1&2 for 1M ROM setting.*/
+        * Alternate Super I/O Configuration Port (4e/4f), Wide Generic IO Port (64/65). */
        byte = pci_read_config8(dev, 0x48);
        byte |= (1 << 1) | (1 << 0);    /* enable Super IO config port 2e-2h, 4e-4f */
-       byte |= (1 << 3) | (1 << 4);    /* enable for LPC ROM address range1&2, Enable 512KB rom access at 0xFFF80000 - 0xFFFFFFFF */
        byte |= 1 << 6;         /* enable for RTC I/O range */
        pci_write_config8(dev, 0x48, byte);
        pci_write_config8(dev, 0x49, 0xFF);
@@ -418,12 +473,6 @@ static void sb700_devices_por_init(void)
        byte |= ((1 << 1) + (1 << 6));  /*0x42, save the configuraion for port 0x80. */
        pci_write_config8(dev, 0x4A, byte);
 
-       /* Set LPC ROM size, it has been done in sb700_lpc_init().
-        * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB;
-        * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB
-        * pci_write_config16(dev, 0x68, 0x000e)
-        * pci_write_config16(dev, 0x6c, 0xfff0);*/
-
        /* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */
        pci_write_config8(dev, 0x7C, 0x05);
 
@@ -445,6 +494,29 @@ static void sb700_devices_por_init(void)
        /* 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);
@@ -598,7 +670,7 @@ static void sb700_por_init(void)
 /*
 * 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();
 }
@@ -606,14 +678,64 @@ static void sb700_before_pci_init(void)
 /*
 * 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();
+}
+
+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;
 }
 
-static int smbus_read_byte(u32 device, u32 address)
+int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos)
 {
-       return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+       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