diff options
author | Li-Ta Lo <ollie@lanl.gov> | 2004-03-25 17:50:06 +0000 |
---|---|---|
committer | Li-Ta Lo <ollie@lanl.gov> | 2004-03-25 17:50:06 +0000 |
commit | edeff59c72f5ae0218a8366d38274947d2b48f8d (patch) | |
tree | b8233902246110a7c494db7e700bf41bf136f129 /src | |
parent | 30667d75a63495e98fc5e228af510f29a6e575fe (diff) |
YhLu's patch for multi-ht-chain for S2885
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1478 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src')
-rw-r--r-- | src/mainboard/tyan/s2885/auto.c | 23 | ||||
-rw-r--r-- | src/mainboard/tyan/s2885/resourcemap.c | 6 | ||||
-rw-r--r-- | src/northbridge/amd/amdk8/incoherent_ht.c | 108 |
3 files changed, 134 insertions, 3 deletions
diff --git a/src/mainboard/tyan/s2885/auto.c b/src/mainboard/tyan/s2885/auto.c index 307331375c..163491fb24 100644 --- a/src/mainboard/tyan/s2885/auto.c +++ b/src/mainboard/tyan/s2885/auto.c @@ -149,6 +149,22 @@ static void main(void) }, #endif }; + + static const struct ht_chain ht_c[] = { + { + .udev = PCI_DEV(0, 0x18, 0), + .upos = 0xc0, + .devreg = 0xe2, + .mindev = 1, + }, + { + .udev = PCI_DEV(0, 0x18, 0), + .upos = 0x80, + .devreg = 0xe6, + .mindev = 5, + + }, + }; int needs_reset; enable_lapic(); init_timer(); @@ -164,11 +180,16 @@ static void main(void) console_init(); setup_s2885_resource_map(); needs_reset = setup_coherent_ht_domain(); - needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0xc0); +// needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0xc0); + needs_reset |= ht_setup_chains(ht_c, sizeof(ht_c)/sizeof(ht_c[0])); if (needs_reset) { print_info("ht reset -"); soft_reset(); } +#if 0 + dump_pci_devices(); +#endif + #if 0 print_pci_devices(); diff --git a/src/mainboard/tyan/s2885/resourcemap.c b/src/mainboard/tyan/s2885/resourcemap.c index f2535bf02f..fcf99d87bd 100644 --- a/src/mainboard/tyan/s2885/resourcemap.c +++ b/src/mainboard/tyan/s2885/resourcemap.c @@ -252,8 +252,10 @@ static void setup_s2885_resource_map(void) * [31:24] Bus Number Limit i * This field defines the highest bus number in configuration regin i */ - PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x04000203, - PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x06050003, + PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x04010207, + PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x06050007, +// PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x04000203, +// PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x06050003, // PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x00000203, // PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000, diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c index 711100a045..efab9edb58 100644 --- a/src/northbridge/amd/amdk8/incoherent_ht.c +++ b/src/northbridge/amd/amdk8/incoherent_ht.c @@ -242,3 +242,111 @@ static int ht_setup_chain(device_t udev, unsigned upos) } while((last_unitid != next_unitid) && (next_unitid <= 0x1f)); return reset_needed; } +struct ht_chain { + device_t udev; + unsigned upos; + unsigned devreg; + unsigned mindev; +}; + +static int ht_setup_chains(const struct ht_chain *ht_c, int ht_c_num) +{ + /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. + * On most boards this just happens. If a cpu has multiple + * non Coherent links the appropriate bus registers for the + * links needs to be programed to point at bus 0. + */ + unsigned next_unitid, last_unitid; + int reset_needed; + unsigned uoffs; + unsigned upos; + device_t udev; + int i; + + /* Make certain the HT bus is not enumerated */ + ht_collapse_previous_enumeration(0); + + reset_needed = 0; + next_unitid = 1; + + + for(i=0;i<ht_c_num;i++) { +#if 0 + unsigned tmp; + tmp = pci_read_config8(PCI_DEV(0,0x18,1),ht_c[i].devreg); +#endif + + pci_write_config8(PCI_DEV(0,0x18,1), ht_c[i].devreg, 0); +#if CONFIG_MAX_CPUS > 1 + pci_write_config8(PCI_DEV(0,0x19,1), ht_c[i].devreg, 0); +#endif +#if CONFIG_MAX_CPUS > 2 + pci_write_config8(PCI_DEV(0,0x1a,1), ht_c[i].devreg, 0); + pci_write_config8(PCI_DEV(0,0x1b,1), ht_c[i].devreg, 0); +#endif + + uoffs = PCI_HT_HOST_OFFS; + upos = ht_c[i].upos; + udev = ht_c[i].udev; + do { + uint32_t id; + uint8_t pos; + unsigned flags, count; + device_t dev = PCI_DEV(0, 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) || + (((id >> 16) & 0xffff) == 0x0000)) { + break; + } + pos = ht_lookup_slave_capability(dev); + if (!pos) { + print_err("HT link capability not found\r\n"); + break; + } + /* Setup the Hypertransport link */ + reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, PCI_HT_SLAVE0_OFFS); + + /* 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); + + /* Remeber the location of the last device */ + udev = PCI_DEV(0, next_unitid, 0); + upos = pos; + uoffs = PCI_HT_SLAVE1_OFFS; + + /* Compute the number of unitids consumed */ + count = (flags >> 5) & 0x1f; + next_unitid += count; + + } while((last_unitid != next_unitid) && (next_unitid <= 0x1f)); +#if 0 + pci_write_config8(PCI_DEV(0,0x18,1), ht_c[i].devreg, tmp); +#if CONFIG_MAX_CPUS > 1 + pci_write_config8(PCI_DEV(0,0x19,1), ht_c[i].devreg, tmp); +#endif +#if CONFIG_MAX_CPUS > 2 + pci_write_config8(PCI_DEV(0,0x1a,1), ht_c[i].devreg, tmp); + pci_write_config8(PCI_DEV(0,0x1b,1), ht_c[i].devreg, tmp); +#endif +#else + pci_write_config8(PCI_DEV(0,0x18,1), ht_c[i].devreg, ht_c[i].mindev); +#if CONFIG_MAX_CPUS > 1 + pci_write_config8(PCI_DEV(0,0x19,1), ht_c[i].devreg, ht_c[i].mindev); +#endif +#if CONFIG_MAX_CPUS > 2 + pci_write_config8(PCI_DEV(0,0x1a,1), ht_c[i].devreg, ht_c[i].mindev); + pci_write_config8(PCI_DEV(0,0x1b,1), ht_c[i].devreg, ht_c[i].mindev); +#endif +#endif + + } + + return reset_needed; +} |