diff options
author | Joe Bao <zheng.bao@amd.com> | 2008-12-01 19:37:21 +0000 |
---|---|---|
committer | Marc Jones <marc.jones@amd.com> | 2008-12-01 19:37:21 +0000 |
commit | 164463c551367d0ae3a9f8e5a1719200af99b060 (patch) | |
tree | 0b2b1a6682749dcc44302548edbebb08ce914df4 /src/southbridge | |
parent | 7a51e50582b65bb6ac54e8923470807b5975c6e1 (diff) |
Add AMD sb600 HPET setup and some minor cleanups.
Signed-off-by: Joe Bao <zheng.bao@amd.com>
Reviewed-by: Maggie Li <maggie.li@amd.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>
Acked-by: Marc Jones <marcj303@gmail.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3785 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/southbridge')
-rw-r--r-- | src/southbridge/amd/sb600/chip.h | 8 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_early_setup.c | 15 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_hda.c | 4 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_ide.c | 5 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_lpc.c | 10 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_reset.c | 2 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_sata.c | 18 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_sm.c | 77 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_smbus.c | 30 | ||||
-rw-r--r-- | src/southbridge/amd/sb600/sb600_smbus.h | 2 |
10 files changed, 111 insertions, 60 deletions
diff --git a/src/southbridge/amd/sb600/chip.h b/src/southbridge/amd/sb600/chip.h index 808d358965..4dc4c16274 100644 --- a/src/southbridge/amd/sb600/chip.h +++ b/src/southbridge/amd/sb600/chip.h @@ -20,11 +20,11 @@ #ifndef SB600_CHIP_H #define SB600_CHIP_H -struct southbridge_amd_sb600_config +struct southbridge_amd_sb600_config { - unsigned int ide0_enable : 1; - unsigned int sata0_enable : 1; - unsigned long hda_viddid; + u32 ide0_enable : 1; + u32 sata0_enable : 1; + u32 hda_viddid; }; struct chip_operations; extern struct chip_operations southbridge_amd_sb600_ops; diff --git a/src/southbridge/amd/sb600/sb600_early_setup.c b/src/southbridge/amd/sb600/sb600_early_setup.c index 7f588e9ce7..3ed9f53ac5 100644 --- a/src/southbridge/amd/sb600/sb600_early_setup.c +++ b/src/southbridge/amd/sb600/sb600_early_setup.c @@ -24,6 +24,7 @@ #define SMBUS_IO_BASE 0x1000 /* Is it a temporary SMBus I/O base address? */ /*SIZE 0x40 */ + static void pmio_write(u8 reg, u8 value) { outb(reg, PM_INDEX); @@ -44,6 +45,7 @@ static u8 get_sb600_revision() if (dev == PCI_DEV_INVALID) { die("SMBUS controller not found\r\n"); + /* NOT REACHED */ } return pci_read_config8(dev, 0x08); } @@ -259,6 +261,7 @@ static void sb600_devices_por_init() if (dev == PCI_DEV_INVALID) { die("SMBUS controller not found\r\n"); + /* NOT REACHED */ } printk_info("SMBus controller enabled, sb revision is 0x%x\r\n", get_sb600_revision()); @@ -317,7 +320,7 @@ static void sb600_devices_por_init() pci_write_config8(dev, 0x62, byte); /* Features Enable */ - pci_write_config32(dev, 0x64, 0x829E79BF); + pci_write_config32(dev, 0x64, 0x829E7DBF); /* bit10: Enables the HPET interrupt. */ /* SerialIrq Control */ pci_write_config8(dev, 0x69, 0x90); @@ -373,7 +376,7 @@ static void sb600_devices_por_init() 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 sb600_lpc_init(). + /* Set LPC ROM size, it has been done in sb600_lpc_init(). * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB; * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB * pci_write_config16(dev, 0x68, 0x000e) @@ -382,7 +385,7 @@ static void sb600_devices_por_init() /* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */ pci_write_config8(dev, 0x7C, 0x05); - /* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM, + /* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM, * TODO: I don't know what are their mean? */ printk_info("sb600_devices_por_init(): P2P Bridge, BDF:0-20-4\n"); dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0); @@ -397,7 +400,7 @@ static void sb600_devices_por_init() pci_write_config8(dev, 0x40, 0x26); - /* I don't know why CIM set reg0x1c as 0x11. + /* I don't know why CIM set reg0x1c as 0x11. * System will block at sdram_initialize() if I set it before call sdram_initialize(). * If it is necessary to set reg0x1c as 0x11, please call this function after sdram_initialize(). * pci_write_config8(dev, 0x1c, 0x11); @@ -490,8 +493,10 @@ static void sb600_pmio_por_init() pmio_write(0x9e, byte); /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */ + /* We have to clear this bit here, otherwise the kernel hangs. */ byte = pmio_read(0x55); byte |= 1 << 7; + byte |= 1 << 1; pmio_write(0x55, byte); /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridage */ @@ -550,7 +555,7 @@ static void sb600_pci_cfg() byte |= (1 << 3); pci_write_config8(dev, 0x41, byte); - /* Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles) + /* Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles) * generated PCIRST#. */ byte = pmio_read(0x65); byte |= (1 << 4); diff --git a/src/southbridge/amd/sb600/sb600_hda.c b/src/southbridge/amd/sb600/sb600_hda.c index ca46b21963..e123187c68 100644 --- a/src/southbridge/amd/sb600/sb600_hda.c +++ b/src/southbridge/amd/sb600/sb600_hda.c @@ -55,7 +55,7 @@ static int set_bits(u8 * port, u32 mask, u32 val) return 0; } -static int codec_detect(u8 * base) +static u32 codec_detect(u8 * base) { u32 dword; @@ -148,7 +148,7 @@ static u32 cim_verb_data[] = { 0x01f71ec4, 0x01f71f01, }; -static unsigned find_verb(u32 viddid, u32 ** verb) +static u32 find_verb(u32 viddid, u32 ** verb) { device_t azalia_dev = dev_find_slot(0, PCI_DEVFN(0x14, 2)); struct southbridge_amd_sb600_config *cfg = diff --git a/src/southbridge/amd/sb600/sb600_ide.c b/src/southbridge/amd/sb600/sb600_ide.c index 04afe83744..afe3f01fcc 100644 --- a/src/southbridge/amd/sb600/sb600_ide.c +++ b/src/southbridge/amd/sb600/sb600_ide.c @@ -38,13 +38,10 @@ static void ide_init(struct device *dev) pci_write_config32(dev, 0x70, dword); /* Ultra DMA mode */ + /* enable UDMA */ byte = pci_read_config8(dev, 0x54); byte |= 1 << 0; pci_write_config8(dev, 0x54, byte); - byte = pci_read_config8(dev, 0x56); - byte &= ~(7 << 0); - byte |= 5 << 0; /* mode 5 */ - pci_write_config8(dev, 0x56, byte); /* Enable I/O Access&& Bus Master */ dword = pci_read_config16(dev, 0x4); diff --git a/src/southbridge/amd/sb600/sb600_lpc.c b/src/southbridge/amd/sb600/sb600_lpc.c index 83dea99883..50d00e25fa 100644 --- a/src/southbridge/amd/sb600/sb600_lpc.c +++ b/src/southbridge/amd/sb600/sb600_lpc.c @@ -82,14 +82,14 @@ static void sb600_lpc_read_resources(device_t dev) compact_resources(dev); } -/** +/** * @brief Enable resources for children devices - * + * * @param dev the device whos children's resources are to be enabled - * + * * This function is call by the global enable_resources() indirectly via the * device_operation::enable_resources() method of devices. - * + * * Indirect mutual recursion: * enable_childrens_resources() -> enable_resources() * enable_resources() -> device_operation::enable_resources() @@ -115,7 +115,7 @@ static void sb600_lpc_enable_childrens_resources(device_t dev) && (child->path.type == DEVICE_PATH_PNP)) { for (i = 0; i < child->resources; i++) { struct resource *res; - unsigned long base, end; /* don't need long long */ + u32 base, end; /* don't need long long */ res = &child->resource[i]; if (!(res->flags & IORESOURCE_IO)) continue; diff --git a/src/southbridge/amd/sb600/sb600_reset.c b/src/southbridge/amd/sb600/sb600_reset.c index d46f734c3d..68913b4846 100644 --- a/src/southbridge/amd/sb600/sb600_reset.c +++ b/src/southbridge/amd/sb600/sb600_reset.c @@ -24,7 +24,7 @@ (((DEV) & 0x1F) << 15) | \ (((FN) & 0x7) << 12)) -typedef unsigned device_t; +typedef u32 device_t; #include "../../../northbridge/amd/amdk8/reset_test.c" diff --git a/src/southbridge/amd/sb600/sb600_sata.c b/src/southbridge/amd/sb600/sb600_sata.c index 995e5a7376..5b3c500bd9 100644 --- a/src/southbridge/amd/sb600/sb600_sata.c +++ b/src/southbridge/amd/sb600/sb600_sata.c @@ -62,12 +62,12 @@ static void sata_init(struct device *dev) sata_bar3 = pci_read_config16(dev, 0x1C) & ~0x7; sata_bar4 = pci_read_config16(dev, 0x20) & ~0x7; - printk_debug("sata_bar0=%x\n", sata_bar0); /* 3030 */ - printk_debug("sata_bar1=%x\n", sata_bar1); /* 3070 */ - printk_debug("sata_bar2=%x\n", sata_bar2); /* 3040 */ - printk_debug("sata_bar3=%x\n", sata_bar3); /* 3080 */ - printk_debug("sata_bar4=%x\n", sata_bar4); /* 3000 */ - printk_debug("sata_bar5=%x\n", sata_bar5); /* e0309000 */ + /* printk_debug("sata_bar0=%x\n", sata_bar0); */ /* 3030 */ + /* printk_debug("sata_bar1=%x\n", sata_bar1); */ /* 3070 */ + /* printk_debug("sata_bar2=%x\n", sata_bar2); */ /* 3040 */ + /* printk_debug("sata_bar3=%x\n", sata_bar3); */ /* 3080 */ + /* printk_debug("sata_bar4=%x\n", sata_bar4); */ /* 3000 */ + /* printk_debug("sata_bar5=%x\n", sata_bar5); */ /* e0309000 */ /* Program the 2C to 0x43801002 */ dword = 0x43801002; @@ -142,15 +142,15 @@ static void sata_init(struct device *dev) /* Use BAR5+0x2A8,BAR0+0x6 for Secondary Slave */ byte = readb(sata_bar5 + 0x128); - printk_debug("byte=%x\n", byte); + /* printk_debug("byte=%x\n", byte); */ byte &= 0xF; if (byte == 0x3) { outb(0xA0, sata_bar0 + 0x6); while ((inb(sata_bar0 + 0x6) != 0xA0) || ((inb(sata_bar0 + 0x7) & 0x88) != 0)) { mdelay(10); - printk_debug("0x6=%x,0x7=%x\n", inb(sata_bar0 + 0x6), - inb(sata_bar0 + 0x7)); + /* printk_debug("0x6=%x,0x7=%x\n", inb(sata_bar0 + 0x6), + inb(sata_bar0 + 0x7)); */ printk_debug("drive detection fail,trying...\n"); } printk_debug("Primary master device is ready\n"); diff --git a/src/southbridge/amd/sb600/sb600_sm.c b/src/southbridge/amd/sb600/sb600_sm.c index 97ad48f398..d6643ab91b 100644 --- a/src/southbridge/amd/sb600/sb600_sm.c +++ b/src/southbridge/amd/sb600/sb600_sm.c @@ -41,8 +41,8 @@ #endif struct ioapicreg { - unsigned int reg; - unsigned int value_low, value_high; + u32 reg; + u32 value_low, value_high; }; static struct ioapicreg ioapicregvalues[] = { @@ -89,18 +89,18 @@ static struct ioapicreg ioapicregvalues[] = { /* Be careful and don't write past the end... */ }; -static void setup_ioapic(unsigned long ioapic_base) +static void setup_ioapic(u32 ioapic_base) { int i; - unsigned long value_low, value_high; - volatile unsigned long *l; + u32 value_low, value_high; + volatile u32 *l; struct ioapicreg *a = ioapicregvalues; ioapicregvalues[0].value_high = lapicid() << (56 - 32); printk_debug("lapicid = %016x\n", ioapicregvalues[0].value_high); - l = (unsigned long *)ioapic_base; + l = (u32 *)ioapic_base; for (i = 0; i < ARRAY_SIZE(ioapicregvalues); i++, a++) { @@ -126,9 +126,9 @@ static void sm_init(device_t dev) u8 byte; u8 byte_old; u32 dword; - unsigned long ioapic_base; - int on; - int nmi_option; + u32 ioapic_base; + u32 on; + u32 nmi_option; printk_info("sm_init().\n"); @@ -143,6 +143,10 @@ static void sm_init(device_t dev) dword |= 1 << 9; pci_write_config32(dev, 0x78, dword); /* enable 0xCD6 0xCD7 */ + /* bit 10: MultiMediaTimerIrqEn */ + dword = pci_read_config8(dev, 0x64); + dword |= 1 << 10; + pci_write_config8(dev, 0x64, dword); /* enable serial irq */ byte = pci_read_config8(dev, 0x69); byte |= 1 << 7; /* enable serial irq function */ @@ -191,8 +195,21 @@ static void sm_init(device_t dev) byte = pm_ioread(0x68); byte &= ~(1 << 1); + /* 2.6 */ + byte |= 1 << 2; pm_iowrite(0x68, byte); + /* 2.6 */ + byte = pm_ioread(0x65); + byte &= ~(1 << 7); + pm_iowrite(0x65, byte); + + /* 2.3.4 */ + byte = pm_ioread(0x52); + byte &= ~0x2F; + byte |= 0x8; + pm_iowrite(0x52, byte); + byte = pm_ioread(0x8D); byte &= ~(1 << 6); pm_iowrite(0x8D, byte); @@ -344,9 +361,19 @@ static struct smbus_bus_operations lops_smbus_bus = { static void sb600_sm_read_resources(device_t dev) { struct resource *res; + u8 byte; + + /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */ + byte = pm_ioread(0x55); + byte |= 1 << 7; + pm_iowrite(0x55, byte); /* Get the normal pci resources of this device */ - pci_dev_read_resources(dev); + /* pci_dev_read_resources(dev); */ + + byte = pm_ioread(0x55); + byte &= ~(1 << 7); + pm_iowrite(0x55, byte); /* apic */ res = new_resource(dev, 0x74); @@ -357,19 +384,49 @@ static void sb600_sm_read_resources(device_t dev) res->gran = 8; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED; + res = new_resource(dev, 0x14); /* 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; /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */ + /* smbus */ + res = new_resource(dev, 0x10); + res->base = 0xB00; + res->size = 0x10; + res->limit = 0xFFFFUL; /* res->base + res->size -1; */ + res->align = 8; + res->gran = 8; + res->flags = IORESOURCE_IO | IORESOURCE_FIXED; + + compact_resources(dev); } static void sb600_sm_set_resources(struct device *dev) { struct resource *res; + u8 byte; pci_dev_set_resources(dev); + + /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridage */ + byte = pm_ioread(0x52); + byte |= 1 << 6; + pm_iowrite(0x52, byte); + res = find_resource(dev, 0x74); pci_write_config32(dev, 0x74, res->base | 1 << 3); + + res = find_resource(dev, 0x14); + pci_write_config32(dev, 0x14, res->base); + + res = find_resource(dev, 0x10); + pci_write_config32(dev, 0x10, res->base | 1); } static struct pci_operations lops_pci = { diff --git a/src/southbridge/amd/sb600/sb600_smbus.c b/src/southbridge/amd/sb600/sb600_smbus.c index 038cd14b7b..df7ec56c3e 100644 --- a/src/southbridge/amd/sb600/sb600_smbus.c +++ b/src/southbridge/amd/sb600/sb600_smbus.c @@ -17,12 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -//#include <arch/io.h> -//#include <device/device.h> -//#include <device/pci.h> -//#include <device/pci_ids.h> -//#include <device/pci_ops.h> -//#include <device/smbus_def.h> #include "sb600_smbus.h" static inline void smbus_delay(void) @@ -32,7 +26,7 @@ static inline void smbus_delay(void) static int smbus_wait_until_ready(u32 smbus_io_base) { - unsigned long loops; + u32 loops; loops = SMBUS_TIMEOUT; do { u8 val; @@ -48,7 +42,7 @@ static int smbus_wait_until_ready(u32 smbus_io_base) static int smbus_wait_until_done(u32 smbus_io_base) { - unsigned long loops; + u32 loops; loops = SMBUS_TIMEOUT; do { u8 val; @@ -121,7 +115,7 @@ static int do_smbus_send_byte(u32 smbus_io_base, u32 device, return 0; } -static int do_smbus_read_byte(u32 smbus_io_base, u32 device, +int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address) { u8 byte; @@ -152,7 +146,7 @@ static int do_smbus_read_byte(u32 smbus_io_base, u32 device, return byte; } -static int do_smbus_write_byte(u32 smbus_io_base, u32 device, +int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val) { u8 byte; @@ -183,10 +177,11 @@ static int do_smbus_write_byte(u32 smbus_io_base, u32 device, return 0; } -static void alink_ab_indx(unsigned int reg_space, unsigned int reg_addr, - unsigned int mask, unsigned int val) +static void alink_ab_indx(u32 reg_space, u32 reg_addr, + u32 mask, u32 val) { - unsigned int tmp; + u32 tmp; + outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX); tmp = inl(AB_DATA); @@ -201,10 +196,10 @@ static void alink_ab_indx(unsigned int reg_space, unsigned int reg_addr, /* space = 0: AX_INDXC, AX_DATAC * space = 1: AX_INDXP, AX_DATAP */ -static void alink_ax_indx(unsigned int space /*c or p? */ , unsigned int axindc, - unsigned int mask, unsigned int val) +static void alink_ax_indx(u32 space /*c or p? */ , u32 axindc, + u32 mask, u32 val) { - unsigned int tmp; + u32 tmp; /* read axindc to tmp */ outl(space << 30 | space << 3 | 0x30, AB_INDX); @@ -221,6 +216,3 @@ static void alink_ax_indx(unsigned int space /*c or p? */ , unsigned int axindc, outl(space << 30 | space << 3 | 0x34, AB_INDX); outl(tmp, AB_DATA); } - - - diff --git a/src/southbridge/amd/sb600/sb600_smbus.h b/src/southbridge/amd/sb600/sb600_smbus.h index 3fb6c794bd..83dfb8f20c 100644 --- a/src/southbridge/amd/sb600/sb600_smbus.h +++ b/src/southbridge/amd/sb600/sb600_smbus.h @@ -44,7 +44,7 @@ #define AB_INDX 0xCD8 #define AB_DATA (AB_INDX+4) -/* Between 1-10 seconds, We should never timeout normally +/* Between 1-10 seconds, We should never timeout normally * Longer than this is just painful when a timeout condition occurs. */ #define SMBUS_TIMEOUT (100*1000*10) |