diff options
Diffstat (limited to 'src/northbridge/amd')
-rw-r--r-- | src/northbridge/amd/amdk8/early_ht.c | 25 | ||||
-rw-r--r-- | src/northbridge/amd/amdk8/incoherent_ht.c | 111 | ||||
-rw-r--r-- | src/northbridge/amd/amdk8/setup_resource_map.c | 196 |
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 + |