YhLu's patch for multi-ht-chain for S2885
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1478 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
30667d75a6
commit
edeff59c72
|
@ -149,6 +149,22 @@ static void main(void)
|
||||||
},
|
},
|
||||||
#endif
|
#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;
|
int needs_reset;
|
||||||
enable_lapic();
|
enable_lapic();
|
||||||
init_timer();
|
init_timer();
|
||||||
|
@ -164,11 +180,16 @@ static void main(void)
|
||||||
console_init();
|
console_init();
|
||||||
setup_s2885_resource_map();
|
setup_s2885_resource_map();
|
||||||
needs_reset = setup_coherent_ht_domain();
|
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) {
|
if (needs_reset) {
|
||||||
print_info("ht reset -");
|
print_info("ht reset -");
|
||||||
soft_reset();
|
soft_reset();
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
dump_pci_devices();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
print_pci_devices();
|
print_pci_devices();
|
||||||
|
|
|
@ -252,8 +252,10 @@ static void setup_s2885_resource_map(void)
|
||||||
* [31:24] Bus Number Limit i
|
* [31:24] Bus Number Limit i
|
||||||
* This field defines the highest bus number in configuration regin 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, 0xE0), 0x0000FC88, 0x04010207,
|
||||||
PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x06050003,
|
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, 0xE0), 0x0000FC88, 0x00000203,
|
||||||
// PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000,
|
// PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000,
|
||||||
PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
|
PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
|
||||||
|
|
|
@ -242,3 +242,111 @@ static int ht_setup_chain(device_t udev, unsigned upos)
|
||||||
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
|
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
|
||||||
return reset_needed;
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue