aboutsummaryrefslogtreecommitdiff
path: root/src/southbridge/amd/sb700
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge/amd/sb700')
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/Makefile.inc5
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/early_setup.c44
-rwxr-xr-xsrc/southbridge/amd/sb700/pmio.c55
-rwxr-xr-xsrc/southbridge/amd/sb700/pmio.h34
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/reset.c46
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/sata.c2
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/sb700.h10
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/sm.c28
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/smbus.c89
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/smbus.h10
-rwxr-xr-x[-rw-r--r--]src/southbridge/amd/sb700/usb.c1
11 files changed, 235 insertions, 89 deletions
diff --git a/src/southbridge/amd/sb700/Makefile.inc b/src/southbridge/amd/sb700/Makefile.inc
index 8e8e0297db..e174e8b347 100644..100755
--- a/src/southbridge/amd/sb700/Makefile.inc
+++ b/src/southbridge/amd/sb700/Makefile.inc
@@ -1,11 +1,16 @@
driver-y += sb700.c
driver-y += usb.c
driver-y += lpc.c
+driver-y += smbus.c
driver-y += sm.c
driver-y += ide.c
driver-y += sata.c
driver-y += hda.c
driver-y += pci.c
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c
+romstage-y += reset.c
ramstage-y += reset.c
romstage-y += enable_usbdebug.c
+
+romstage-y += early_setup.c
+romstage-y += smbus.c
diff --git a/src/southbridge/amd/sb700/early_setup.c b/src/southbridge/amd/sb700/early_setup.c
index a5e76c7a05..1f46da2228 100644..100755
--- a/src/southbridge/amd/sb700/early_setup.c
+++ b/src/southbridge/amd/sb700/early_setup.c
@@ -20,14 +20,19 @@
#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)
{
@@ -129,7 +134,7 @@ 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 sb7xx_51xx_lpc_init(void)
+void sb7xx_51xx_lpc_init(void)
{
u8 reg8;
u32 reg32;
@@ -216,7 +221,7 @@ void sb7xx_51xx_disable_wideio(u8 wio_index)
}
/* what is its usage? */
-static u32 get_sbdn(u32 bus)
+u32 __attribute__ ((weak)) get_sbdn(u32 bus)
{
device_t dev;
@@ -233,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);
@@ -284,22 +289,6 @@ static void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
pmio_write(0x67, 0x6);
}
-void hard_reset(void)
-{
- set_bios_reset();
-
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
-}
-
-void soft_reset(void)
-{
- set_bios_reset();
- /* link reset */
- outb(0x06, 0x0cf9);
-}
-
void sb7xx_51xx_pci_port80(void)
{
u8 byte;
@@ -681,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 sb7xx_51xx_before_pci_init(void)
+void sb7xx_51xx_before_pci_init(void)
{
sb700_pci_cfg();
}
@@ -689,18 +678,13 @@ static void sb7xx_51xx_before_pci_init(void)
/*
* This function should be called after enable_sb700_smbus().
*/
-static void sb7xx_51xx_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)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-
int s3_save_nvram_early(u32 dword, int size, int nvram_pos)
{
int i;
@@ -732,7 +716,7 @@ int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos)
}
#if CONFIG_HAVE_ACPI_RESUME == 1
-static int acpi_is_wakeup_early(void)
+int acpi_is_wakeup_early(void)
{
u16 tmp;
tmp = inw(ACPI_PM1_CNT_BLK);
diff --git a/src/southbridge/amd/sb700/pmio.c b/src/southbridge/amd/sb700/pmio.c
new file mode 100755
index 0000000000..baded54ba6
--- /dev/null
+++ b/src/southbridge/amd/sb700/pmio.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 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 <arch/io.h> /*inb, outb*/
+#include "pmio.h"
+
+static void pmio_write_index(u16 port_base, u8 reg, u8 value)
+{
+ outb(reg, port_base);
+ outb(value, port_base + 1);
+}
+
+static u8 pmio_read_index(u16 port_base, u8 reg)
+{
+ outb(reg, port_base);
+ return inb(port_base + 1);
+}
+
+void pm_iowrite(u8 reg, u8 value)
+{
+ pmio_write_index(PM_INDEX, reg, value);
+}
+
+u8 pm_ioread(u8 reg)
+{
+ return pmio_read_index(PM_INDEX, reg);
+}
+
+void pm2_iowrite(u8 reg, u8 value)
+{
+ pmio_write_index(PM2_INDEX, reg, value);
+}
+
+u8 pm2_ioread(u8 reg)
+{
+ return pmio_read_index(PM2_INDEX, reg);
+}
+
diff --git a/src/southbridge/amd/sb700/pmio.h b/src/southbridge/amd/sb700/pmio.h
new file mode 100755
index 0000000000..207fdc24ab
--- /dev/null
+++ b/src/southbridge/amd/sb700/pmio.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 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
+ */
+
+
+#ifndef _PMIO_H_
+#define _PMIO_H_
+
+#define PM_INDEX 0xCD6
+#define PM_DATA 0xCD7
+#define PM2_INDEX 0xCD0
+#define PM2_DATA 0xCD1
+
+void pm_iowrite(u8 reg, u8 value);
+u8 pm_ioread(u8 reg);
+void pm2_iowrite(u8 reg, u8 value);
+u8 pm2_ioread(u8 reg);
+
+#endif
diff --git a/src/southbridge/amd/sb700/reset.c b/src/southbridge/amd/sb700/reset.c
index 32ee66b4b5..27ca32eb5e 100644..100755
--- a/src/southbridge/amd/sb700/reset.c
+++ b/src/southbridge/amd/sb700/reset.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2010 - 2011 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
@@ -17,17 +17,51 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <reset.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
+#include <reset.h> /* hard_reset, soft_rest*/
+#include <arch/io.h> /* inb, outb */
+#include <arch/romcc_io.h> /* pci_read_config32, device_t, PCI_DEV */
-#include "../../../northbridge/amd/amdk8/reset_test.c"
+#define HT_INIT_CONTROL 0x6C
+#define HTIC_BIOSR_Detect (1<<5)
+
+#if CONFIG_MAX_PHYSICAL_CPUS > 32
+#define NODE_PCI(x, fn) ((x<32)?(PCI_DEV(CONFIG_CBB,(CONFIG_CDB+x),fn)):(PCI_DEV((CONFIG_CBB-1),(CONFIG_CDB+x-32),fn)))
+#else
+#define NODE_PCI(x, fn) PCI_DEV(CONFIG_CBB,(CONFIG_CDB+x),fn)
+#endif
+
+static void set_bios_reset(void)
+{
+ u32 nodes;
+ u32 htic;
+ device_t dev;
+ int i;
+
+ nodes = ((pci_read_config32(PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0), 0x60) >> 4) & 7) + 1;
+ for(i = 0; i < nodes; i++) {
+ dev = NODE_PCI(i, 0);
+ htic = pci_read_config32(dev, HT_INIT_CONTROL);
+ htic &= ~HTIC_BIOSR_Detect;
+ pci_write_config32(dev, HT_INIT_CONTROL, htic);
+ }
+}
void hard_reset(void)
{
set_bios_reset();
+
/* Try rebooting through port 0xcf9 */
- /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
+ /* Actually it is not a real hard_reset
+ * --- it only reset coherent link table, but not reset link freq and width
+ */
outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
}
+
+void soft_reset(void)
+{
+ set_bios_reset();
+ /* link reset */
+ outb(0x06, 0x0cf9);
+}
+
diff --git a/src/southbridge/amd/sb700/sata.c b/src/southbridge/amd/sb700/sata.c
index 89eba4b168..411baf571f 100644..100755
--- a/src/southbridge/amd/sb700/sata.c
+++ b/src/southbridge/amd/sb700/sata.c
@@ -280,7 +280,7 @@ static void sata_init(struct device *dev)
}
static struct pci_operations lops_pci = {
- /* .set_subsystem = pci_dev_set_subsystem, */
+ .set_subsystem = pci_dev_set_subsystem,
};
static struct device_operations sata_ops = {
diff --git a/src/southbridge/amd/sb700/sb700.h b/src/southbridge/amd/sb700/sb700.h
index 60eea47ee7..794dd96a81 100644..100755
--- a/src/southbridge/amd/sb700/sb700.h
+++ b/src/southbridge/amd/sb700/sb700.h
@@ -63,8 +63,11 @@ void sb7xx_51xx_enable(device_t dev);
#ifdef __PRE_RAM__
void sb7xx_51xx_lpc_port80(void);
void sb7xx_51xx_pci_port80(void);
+void sb7xx_51xx_lpc_init(void);
void sb7xx_51xx_enable_wideio(u8 wio_index, u16 base);
void sb7xx_51xx_disable_wideio(u8 wio_index);
+void sb7xx_51xx_early_setup(void);
+void sb7xx_51xx_before_pci_init(void);
#else
#include <device/pci.h>
/* allow override in mainboard.c */
@@ -72,8 +75,15 @@ void sb7xx_51xx_setup_sata_phys(struct device *dev);
#endif
+#if CONFIG_HAVE_ACPI_RESUME == 1
+int acpi_is_wakeup_early(void);
+#endif
+
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);
void enable_usbdebug(unsigned int port);
+
+u32 __attribute__ ((weak)) get_sbdn(u32 bus);
+void __attribute__((weak)) enable_fid_change_on_sb(u32 sbbusn, u32 sbdn);
#endif /* SB700_H */
diff --git a/src/southbridge/amd/sb700/sm.c b/src/southbridge/amd/sb700/sm.c
index 7d341df327..05065b6dbe 100644..100755
--- a/src/southbridge/amd/sb700/sm.c
+++ b/src/southbridge/amd/sb700/sm.c
@@ -30,7 +30,7 @@
#include <arch/ioapic.h>
#include <stdlib.h>
#include "sb700.h"
-#include "smbus.c"
+#include "smbus.h"
#define NMI_OFF 0
@@ -95,6 +95,20 @@ static void sm_init(device_t dev)
byte |= 4 << 2; /* set NumSerIrqBits=4 */
pci_write_config8(dev, 0x69, byte);
+ /* Sx State Settings
+ * Note: These 2 registers need to be set correctly for the S-state
+ * to work properly. Otherwise the system may hang during resume
+ * from the S-state.
+ */
+ /*Use 8us clock for delays in the S-state resume timing sequence.*/
+ byte = pm_ioread(0x65);
+ byte &= ~(1 << 7);
+ pm_iowrite(0x65, byte);
+ /* Delay the APIC interrupt to the CPU until the system has fully resumed from the S-state. */
+ byte = pm_ioread(0x68);
+ byte |= 1 << 2;
+ pm_iowrite(0x68, byte);
+
/* IRQ0From8254 */
byte = pci_read_config8(dev, 0x41);
byte &= ~(1 << 7);
@@ -219,10 +233,10 @@ static void sm_init(device_t dev)
* Transactions for the K8 Platform (for All Revisions) */
abcfg_reg(0x10090, 1 << 8, 1 << 8);
- /* ACPI_SOFT_CLOCK_THROTTLE_PERIOD */
+ /* Set ACPI Software clock Throttling Period to 244 us*/
byte = pm_ioread(0x68);
byte &= ~(3 << 6);
- byte |= (2 << 6); /* 224us */
+ byte |= (2 << 6); /* 244us */
pm_iowrite(0x68, byte);
if (REV_SB700_A15 == rev) {
@@ -367,16 +381,16 @@ static void sb700_sm_read_resources(device_t dev)
res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
res->align = 8;
res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_RESERVE | IORESOURCE_ASSIGNED;
- /* Linux ACPI crashes when it is 1. For late debugging. */
+ /* HPET */
res = new_resource(dev, 0xB4); /* TODO: test hpet */
res->base = 0xfed00000; /* reset hpet to widely accepted address */
res->size = 0x400;
res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
res->align = 8;
res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_RESERVE | IORESOURCE_ASSIGNED;
/* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */
@@ -387,7 +401,7 @@ static void sb700_sm_read_resources(device_t dev)
res->limit = 0xFFFFUL; /* res->base + res->size -1; */
res->align = 8;
res->gran = 8;
- res->flags = IORESOURCE_IO | IORESOURCE_FIXED;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE | IORESOURCE_ASSIGNED;
compact_resources(dev);
}
diff --git a/src/southbridge/amd/sb700/smbus.c b/src/southbridge/amd/sb700/smbus.c
index e47bceed47..6edc3de80c 100644..100755
--- a/src/southbridge/amd/sb700/smbus.c
+++ b/src/southbridge/amd/sb700/smbus.c
@@ -22,6 +22,51 @@
#include "smbus.h"
+void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val)
+{
+ u32 tmp;
+
+ outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX);
+ tmp = inl(AB_DATA);
+ /* rpr 4.2
+ * For certain revisions of the chip, the ABCFG registers,
+ * with an address of 0x100NN (where 'N' is any hexadecimal
+ * number), require an extra programming step.*/
+ reg_addr & 0x10000 ? outl(0, AB_INDX) : NULL;
+
+ tmp &= ~mask;
+ tmp |= val;
+
+ /* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<30 | reg_addr); */
+ outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX); /* probably we dont have to do it again. */
+ outl(tmp, AB_DATA);
+ reg_addr & 0x10000 ? outl(0, AB_INDX) : NULL;
+}
+
+/* space = 0: AX_INDXC, AX_DATAC
+ * space = 1: AX_INDXP, AX_DATAP
+ */
+void alink_ax_indx(u32 space, u32 axindc, u32 mask, u32 val)
+{
+ u32 tmp;
+
+ /* read axindc to tmp */
+ outl(space << 30 | space << 3 | 0x30, AB_INDX);
+ outl(axindc, AB_DATA);
+ outl(space << 30 | space << 3 | 0x34, AB_INDX);
+ tmp = inl(AB_DATA);
+
+ tmp &= ~mask;
+ tmp |= val;
+
+ /* write tmp */
+ outl(space << 30 | space << 3 | 0x30, AB_INDX);
+ outl(axindc, AB_DATA);
+ outl(space << 30 | space << 3 | 0x34, AB_INDX);
+ outl(tmp, AB_DATA);
+}
+
+
static inline void smbus_delay(void)
{
outb(inb(0x80), 0x80);
@@ -177,48 +222,4 @@ int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val)
return 0;
}
-static void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val)
-{
- u32 tmp;
-
- outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX);
- tmp = inl(AB_DATA);
- /* rpr 4.2
- * For certain revisions of the chip, the ABCFG registers,
- * with an address of 0x100NN (where 'N' is any hexadecimal
- * number), require an extra programming step.*/
- reg_addr & 0x10000 ? outl(0, AB_INDX) : NULL;
-
- tmp &= ~mask;
- tmp |= val;
-
- /* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<30 | reg_addr); */
- outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX); /* probably we dont have to do it again. */
- outl(tmp, AB_DATA);
- reg_addr & 0x10000 ? outl(0, AB_INDX) : NULL;
-}
-
-/* space = 0: AX_INDXC, AX_DATAC
- * space = 1: AX_INDXP, AX_DATAP
- */
-static inline void alink_ax_indx(u32 space /*c or p? */ , u32 axindc,
- u32 mask, u32 val)
-{
- u32 tmp;
-
- /* read axindc to tmp */
- outl(space << 30 | space << 3 | 0x30, AB_INDX);
- outl(axindc, AB_DATA);
- outl(space << 30 | space << 3 | 0x34, AB_INDX);
- tmp = inl(AB_DATA);
-
- tmp &= ~mask;
- tmp |= val;
-
- /* write tmp */
- outl(space << 30 | space << 3 | 0x30, AB_INDX);
- outl(axindc, AB_DATA);
- outl(space << 30 | space << 3 | 0x34, AB_INDX);
- outl(tmp, AB_DATA);
-}
#endif
diff --git a/src/southbridge/amd/sb700/smbus.h b/src/southbridge/amd/sb700/smbus.h
index c21a1dc0a2..9ddfc35303 100644..100755
--- a/src/southbridge/amd/sb700/smbus.h
+++ b/src/southbridge/amd/sb700/smbus.h
@@ -20,6 +20,13 @@
#ifndef SB700_SMBUS_H
#define SB700_SMBUS_H
+#include <stdint.h>
+#include "stddef.h"
+#include <arch/io.h>
+
+#define SMBUS_IO_BASE 0x6000 /* Is it a temporary SMBus I/O base address? */
+ /*SIZE 0x40 */
+
#define SMBHSTSTAT 0x0
#define SMBSLVSTAT 0x1
#define SMBHSTCTRL 0x2
@@ -56,10 +63,11 @@
#define axindxp_reg(reg, mask, val) \
alink_ax_indx(1, (reg), (mask), (val))
+void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val);
+void alink_ax_indx(u32 space, u32 axindc, u32 mask, u32 val);
int do_smbus_recv_byte(u32 smbus_io_base, u32 device);
int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val);
int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address);
int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val);
-
#endif
diff --git a/src/southbridge/amd/sb700/usb.c b/src/southbridge/amd/sb700/usb.c
index 2957dc5aca..793240187f 100644..100755
--- a/src/southbridge/amd/sb700/usb.c
+++ b/src/southbridge/amd/sb700/usb.c
@@ -178,6 +178,7 @@ static void usb_init2(struct device *dev)
dword |= 1 << 8;
dword &= ~(1 << 27); /* 6.23 */
}
+ pci_write_config32(dev, 0x50, dword);
printk(BIOS_DEBUG, "rpr 6.23, final dword=%x\n", dword);
}