summaryrefslogtreecommitdiff
path: root/src/northbridge/amd
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd')
-rw-r--r--src/northbridge/amd/amdk8/early_ht.c25
-rw-r--r--src/northbridge/amd/amdk8/incoherent_ht.c111
-rw-r--r--src/northbridge/amd/amdk8/setup_resource_map.c196
3 files changed, 300 insertions, 32 deletions
diff --git a/src/northbridge/amd/amdk8/early_ht.c b/src/northbridge/amd/amdk8/early_ht.c
index af9453492b..ab9d4592dd 100644
--- a/src/northbridge/amd/amdk8/early_ht.c
+++ b/src/northbridge/amd/amdk8/early_ht.c
@@ -7,6 +7,7 @@ static int enumerate_ht_chain(void)
*/
unsigned next_unitid, last_unitid;
int reset_needed = 0;
+
next_unitid = 1;
do {
uint32_t id;
@@ -16,18 +17,25 @@ static int enumerate_ht_chain(void)
id = pci_read_config32(PCI_DEV(0,0,0), PCI_VENDOR_ID);
/* If the chain is enumerated quit */
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0xffff) ||
- (((id >> 16) & 0xffff) == 0x0000))
- {
+ (((id >> 16) & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0x0000)) {
break;
}
+
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+
hdr_type = pci_read_config8(PCI_DEV(0,0,0), PCI_HEADER_TYPE);
pos = 0;
hdr_type &= 0x7f;
if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
- (hdr_type == PCI_HEADER_TYPE_BRIDGE))
- {
+ (hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
pos = pci_read_config8(PCI_DEV(0,0,0), PCI_CAPABILITY_LIST);
}
while(pos != 0) {
@@ -38,17 +46,22 @@ static int enumerate_ht_chain(void)
flags = pci_read_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS);
if ((flags >> 13) == 0) {
unsigned count;
+
flags &= ~0x1f;
flags |= next_unitid & 0x1f;
count = (flags >> 5) & 0x1f;
+
pci_write_config16(PCI_DEV(0, 0, 0), pos + PCI_CAP_FLAGS, flags);
+
next_unitid += count;
break;
}
}
pos = pci_read_config8(PCI_DEV(0, 0, 0), pos + PCI_CAP_LIST_NEXT);
}
- } while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
+ } while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
+
+
return reset_needed;
}
diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c
index ee7e5dc66d..d76a3e8731 100644
--- a/src/northbridge/amd/amdk8/incoherent_ht.c
+++ b/src/northbridge/amd/amdk8/incoherent_ht.c
@@ -6,9 +6,15 @@
#include <device/pci_ids.h>
#include <device/hypertransport_def.h>
+#ifndef K8_HT_FREQ_1G_SUPPORT
+ #define K8_HT_FREQ_1G_SUPPORT 0
+#endif
+
static inline void print_linkn_in (const char *strval, uint8_t byteval)
{
+#if 0
print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
+#endif
}
static uint8_t ht_lookup_slave_capability(device_t dev)
@@ -70,6 +76,15 @@ static void ht_collapse_previous_enumeration(uint8_t bus)
(id == 0x0000ffff) || (id == 0xffff0000)) {
continue;
}
+#if 0
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+#endif
pos = ht_lookup_slave_capability(dev);
if (!pos) {
@@ -97,15 +112,20 @@ static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos)
/* AMD 8131 Errata 48 */
if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
freq_cap &= ~(1 << HT_FREQ_800Mhz);
- }
+ return freq_cap;
+ }
+
/* AMD 8151 Errata 23 */
if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
freq_cap &= ~(1 << HT_FREQ_800Mhz);
- }
+ return freq_cap;
+ }
+
/* AMD K8 Unsupported 1Ghz? */
if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
- freq_cap &= ~(1 << HT_FREQ_1000Mhz);
+ freq_cap &= ~(1 << HT_FREQ_1000Mhz);
}
+
return freq_cap;
}
@@ -208,7 +228,7 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
* non Coherent links the appropriate bus registers for the
* links needs to be programed to point at bus 0.
*/
- unsigned next_unitid, last_unitid;
+ uint8_t next_unitid, last_unitid;
int reset_needed;
unsigned uoffs;
@@ -221,7 +241,8 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
do {
uint32_t id;
uint8_t pos;
- uint16_t flags, count;
+ uint16_t flags;
+ uint8_t count;
unsigned offs;
device_t dev = PCI_DEV(0, 0, 0);
@@ -240,6 +261,12 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
print_err("HT link capability not found\r\n");
break;
}
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+ if(id != 0x005e10de) {
+#endif
/* Update the Unitid of the current device */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
@@ -248,24 +275,35 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
dev = PCI_DEV(0, next_unitid, 0);
+#if CK804_DEVN_BASE==0
+ }
+ else {
+ dev = PCI_DEV(0, 0, 0);
+ }
+#endif
/* Compute the number of unitids consumed */
count = (flags >> 5) & 0x1f;
next_unitid += count;
-
+
/* get ht direction */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ??
-
+
offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
/* Setup the Hypertransport link */
reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
- /* Remeber the location of the last device */
- udev = dev;
- upos = pos;
- uoffs = (offs != PCI_HT_SLAVE0_OFFS) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
+#if CK804_DEVN_BASE==0
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+ /* Remeber the location of the last device */
+ udev = dev;
+ upos = pos;
+ uoffs = (offs != PCI_HT_SLAVE0_OFFS) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
return reset_needed;
@@ -273,7 +311,7 @@ static int ht_setup_chain(device_t udev, uint8_t upos)
static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
{
- unsigned next_unitid, last_unitid;
+ uint8_t next_unitid, last_unitid;
unsigned uoffs;
int reset_needed=0;
@@ -283,13 +321,15 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
do {
uint32_t id;
uint8_t pos;
- uint16_t flags, count;
+ uint16_t flags;
+ uint8_t count;
unsigned offs;
device_t dev = PCI_DEV(bus, 0, 0);
last_unitid = next_unitid;
id = pci_read_config32(dev, PCI_VENDOR_ID);
+
/* If the chain is enumerated quit */
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
@@ -299,34 +339,53 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
pos = ht_lookup_slave_capability(dev);
if (!pos) {
- print_err("HT link capability not found\r\n");
+ print_err(" HT link capability not found\r\n");
break;
}
- /* Update the Unitid of the current device */
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
- flags &= ~0x1f; /* mask out the bse Unit ID */
- flags |= next_unitid & 0x1f;
- pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
+#if CK804_DEVN_BASE==0
+ //CK804 workaround:
+ // CK804 UnitID changes not use
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+ if(id != 0x005e10de) {
+#endif
+
+ /* Update the Unitid of the current device */
+ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
+ flags &= ~0x1f; /* mask out the bse Unit ID */
+ flags |= next_unitid & 0x1f;
+ pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
- dev = PCI_DEV(bus, next_unitid, 0);
+ dev = PCI_DEV(bus, next_unitid, 0);
+#if CK804_DEVN_BASE==0
+ }
+ else {
+ dev = PCI_DEV(bus, 0, 0);
+ }
+#endif
/* Compute the number of unitids consumed */
count = (flags >> 5) & 0x1f;
next_unitid += count;
/* get ht direction */
- flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ??
+ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ??
offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
-
+
/* Setup the Hypertransport link */
reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
- /* Remeber the location of the last device */
- udev = dev;
- upos = pos;
- uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
+#if CK804_DEVN_BASE==0
+ if(id == 0x005e10de) {
+ break;
+ }
+#endif
+
+ /* Remeber the location of the last device */
+ udev = dev;
+ upos = pos;
+ uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
return reset_needed;
diff --git a/src/northbridge/amd/amdk8/setup_resource_map.c b/src/northbridge/amd/amdk8/setup_resource_map.c
new file mode 100644
index 0000000000..74bbfdf646
--- /dev/null
+++ b/src/northbridge/amd/amdk8/setup_resource_map.c
@@ -0,0 +1,196 @@
+#define RES_DEBUG 0
+
+#define RES_PCI_IO 0x10
+#define RES_PORT_IO_8 0x22
+#define RES_PORT_IO_32 0x20
+#define RES_MEM_IO 0x30
+
+static void setup_resource_map_x(const unsigned int *register_values, int max)
+{
+ int i;
+
+#if RES_DEBUG
+ print_debug("setting up resource map ex....");
+
+#endif
+
+#if RES_DEBUG
+ print_debug("\r\n");
+#endif
+ for(i = 0; i < max; i += 4) {
+#if RES_DEBUG
+ print_debug_hex16(i/4);
+ print_debug(": ");
+ print_debug_hex8(register_values[i]);
+ print_debug(" ");
+ print_debug_hex32(register_values[i+1]);
+ print_debug(" <- & ");
+ print_debug_hex32(register_values[i+2]);
+ print_debug(" | ");
+ print_debug_hex32(register_values[i+3]);
+ print_debug("\r\n");
+#endif
+ switch (register_values[i]) {
+ case RES_PCI_IO: //PCI
+ {
+ device_t dev;
+ unsigned where;
+ unsigned long reg;
+ dev = register_values[i+1] & ~0xff;
+ where = register_values[i+1] & 0xff;
+ reg = pci_read_config32(dev, where);
+ reg &= register_values[i+2];
+ reg |= register_values[i+3];
+ pci_write_config32(dev, where, reg);
+ }
+ break;
+ case RES_PORT_IO_8: // io 8
+ {
+ unsigned where;
+ unsigned reg;
+ where = register_values[i+1];
+ reg = inb(where);
+ reg &= register_values[i+2];
+ reg |= register_values[i+3];
+ outb(reg, where);
+ }
+ break;
+ case RES_PORT_IO_32: //io32
+ {
+ unsigned where;
+ unsigned long reg;
+ where = register_values[i+1];
+ reg = inl(where);
+ reg &= register_values[i+2];
+ reg |= register_values[i+3];
+ outl(reg, where);
+ }
+ break;
+#if 0
+ case RES_MEM_IO: //mem
+ {
+ unsigned where;
+ unsigned long reg;
+ where = register_values[i+1];
+ reg = read32(where);
+ reg &= register_values[i+2];
+ reg |= register_values[i+3];
+ write32( where, reg);
+ }
+ break;
+#endif
+
+ } // switch
+
+
+ }
+
+#if RES_DEBUG
+ print_debug("done.\r\n");
+#endif
+}
+
+
+static void setup_iob_resource_map(const unsigned int *register_values, int max)
+{
+ int i;
+
+ for(i = 0; i < max; i += 3) {
+ unsigned where;
+ unsigned reg;
+
+ where = register_values[i];
+#if 0
+ udelay(2000);
+ print_debug_hex16(where);
+#endif
+ reg = inb(where);
+#if 0
+ print_debug("=");
+ print_debug_hex8(reg);
+#endif
+
+ reg &= register_values[i+1];
+ reg |= register_values[i+2];
+#if 0
+ print_debug(" <- ");
+ print_debug_hex8(reg);
+#endif
+ outb(reg, where);
+#if 0
+
+ print_debug(" -> ");
+ reg = inb(where);
+ print_debug_hex8(reg);
+ print_debug("\r\n");
+#endif
+ }
+}
+
+static void setup_io_resource_map(const unsigned int *register_values, int max)
+{
+ int i;
+
+ for(i = 0; i < max; i += 3) {
+ unsigned where;
+ unsigned long reg;
+
+ where = register_values[i];
+#if 0
+ udelay(2000);
+ print_debug_hex16(where);
+#endif
+
+ reg = inl(where);
+#if 0
+ udelay(2000);
+ print_debug("=");
+ print_debug_hex32(reg);
+#endif
+ reg &= register_values[i+1];
+ reg |= register_values[i+2];
+
+#if 0
+ udelay(2000);
+ print_debug(" <- ");
+ print_debug_hex32(reg);
+#endif
+ outl(reg, where);
+#if 0
+ udelay(2000);
+ print_debug(" -> ");
+ reg = inl(where);
+ print_debug_hex32(reg);
+ print_debug("\r\n");
+#endif
+ }
+}
+
+#if 0
+static void setup_mem_resource_map(const unsigned int *register_values, int max)
+{
+ int i;
+
+ for(i = 0; i < max; i += 3) {
+ unsigned where;
+ unsigned long reg;
+#if 0
+ print_debug_hex32(register_values[i]);
+ print_debug(" <-");
+ print_debug_hex32(register_values[i+2]);
+#endif
+ where = register_values[i];
+ reg = read32(where);
+ reg &= register_values[i+1];
+ reg |= register_values[i+2];
+ write32( where, reg);
+#if 0
+ print_debug(" RB ");
+ reg = read32(where);
+ print_debug_hex32(reg);
+ print_debug("\r\n");
+#endif
+ }
+}
+#endif
+