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
This commit is contained in:
parent
7a51e50582
commit
164463c551
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue