diff options
Diffstat (limited to 'src/southbridge/amd/sb700')
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/Makefile.inc | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/early_setup.c | 44 | ||||
-rwxr-xr-x | src/southbridge/amd/sb700/pmio.c | 55 | ||||
-rwxr-xr-x | src/southbridge/amd/sb700/pmio.h | 34 | ||||
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/reset.c | 46 | ||||
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/sata.c | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/sb700.h | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/sm.c | 28 | ||||
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/smbus.c | 89 | ||||
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/smbus.h | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | src/southbridge/amd/sb700/usb.c | 1 |
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); } |