summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi-Ta Lo <ollie@lanl.gov>2004-03-25 17:50:06 +0000
committerLi-Ta Lo <ollie@lanl.gov>2004-03-25 17:50:06 +0000
commitedeff59c72f5ae0218a8366d38274947d2b48f8d (patch)
treeb8233902246110a7c494db7e700bf41bf136f129 /src
parent30667d75a63495e98fc5e228af510f29a6e575fe (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.c23
-rw-r--r--src/mainboard/tyan/s2885/resourcemap.c6
-rw-r--r--src/northbridge/amd/amdk8/incoherent_ht.c108
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;
+}