More range for HT_CHAIN_UNITID_BASE and HT_CHAIN_END_UNITID_BASE.
For example: in C51/MCP55 or C51/MCP51 Will allow 1. C51 at 0x10 to 0x14, and MCP at 0 to 4 2. C51 at 1 to 4, and MCP at 7 to 0x0a The reason is c51/mcp51/mcp55 reported unitid is 0x0f (far beyond it needed), and will prevent us from putting them on bus 0. Typical values for c51/mcp55 or c51/mcp51: HT_CHAIN_UNITID_BASE = 0x10 # for C51 HT_CHAIN_END_UNITID_BASE = 0 # for mcp If only have mcp with c51, HT_CHAIN_UNITID_BASE = 0 # for MCP #HT_CHAIN_END_UNITID_BASE = 0 # default value 0x20 Signed-off-by: Yinghai Lu <yinghai.lu@amd.com> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2776 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
3335adb771
commit
18c70d7222
|
@ -383,14 +383,14 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||||
struct ht_link prev;
|
struct ht_link prev;
|
||||||
device_t last_func = 0;
|
device_t last_func = 0;
|
||||||
int ht_dev_num = 0;
|
int ht_dev_num = 0;
|
||||||
unsigned temp_unitid;
|
unsigned max_unitid;
|
||||||
unsigned not_use_count;
|
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
||||||
unsigned real_last_unitid;
|
unsigned real_last_unitid;
|
||||||
uint8_t real_last_pos;
|
uint8_t real_last_pos;
|
||||||
device_t real_last_dev;
|
device_t real_last_dev;
|
||||||
|
unsigned end_used = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Restore the hypertransport chain to it's unitialized state */
|
/* Restore the hypertransport chain to it's unitialized state */
|
||||||
|
@ -410,7 +410,7 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||||
|
|
||||||
/* If present assign unitid to a hypertransport chain */
|
/* If present assign unitid to a hypertransport chain */
|
||||||
last_unitid = min_unitid -1;
|
last_unitid = min_unitid -1;
|
||||||
next_unitid = min_unitid;
|
max_unitid = next_unitid = min_unitid;
|
||||||
do {
|
do {
|
||||||
uint8_t pos;
|
uint8_t pos;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
@ -478,26 +478,27 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||||
flags &= ~0x1f; /* mask out base Unit ID */
|
flags &= ~0x1f; /* mask out base Unit ID */
|
||||||
|
|
||||||
count = (flags >> 5) & 0x1f; /* get unit count */
|
count = (flags >> 5) & 0x1f; /* get unit count */
|
||||||
not_use_count = 0;
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
temp_unitid = next_unitid;
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
|
||||||
if(offset_unitid) {
|
if(offset_unitid) {
|
||||||
if((next_unitid+count)>=0x20) {
|
if(next_unitid > (max_devfn>>3)) { // max_devfn will be (0x17<<3)|7 or (0x1f<<3)|7
|
||||||
temp_unitid = HT_CHAIN_END_UNITID_BASE;
|
if(!end_used) {
|
||||||
//still use the old next_unitid
|
next_unitid = HT_CHAIN_END_UNITID_BASE;
|
||||||
not_use_count = 1;
|
end_used = 1;
|
||||||
|
} else {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flags |= temp_unitid & 0x1f;
|
flags |= next_unitid & 0x1f;
|
||||||
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
|
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
|
||||||
|
|
||||||
/* Update the Unitd id in the device structure */
|
/* Update the Unitd id in the device structure */
|
||||||
static_count = 1;
|
static_count = 1;
|
||||||
for(func = dev; func; func = func->sibling) {
|
for(func = dev; func; func = func->sibling) {
|
||||||
func->path.u.pci.devfn += (temp_unitid << 3);
|
func->path.u.pci.devfn += (next_unitid << 3);
|
||||||
static_count = (func->path.u.pci.devfn >> 3)
|
static_count = (func->path.u.pci.devfn >> 3)
|
||||||
- (dev->path.u.pci.devfn >> 3) + 1;
|
- (dev->path.u.pci.devfn >> 3) + 1;
|
||||||
last_func = func;
|
last_func = func;
|
||||||
|
@ -508,20 +509,22 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||||
if (count < static_count) {
|
if (count < static_count) {
|
||||||
count = static_count;
|
count = static_count;
|
||||||
}
|
}
|
||||||
if(!not_use_count)
|
|
||||||
next_unitid += count;
|
|
||||||
|
|
||||||
/* Update the Unitid of the next device */
|
/* Update the Unitid of the next device */
|
||||||
ht_unitid_base[ht_dev_num] = temp_unitid;
|
ht_unitid_base[ht_dev_num] = next_unitid;
|
||||||
ht_dev_num++;
|
ht_dev_num++;
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
if(offset_unitid) {
|
if (offset_unitid) {
|
||||||
real_last_pos = pos;
|
real_last_pos = pos;
|
||||||
real_last_unitid = temp_unitid;
|
real_last_unitid = next_unitid;
|
||||||
real_last_dev = dev;
|
real_last_dev = dev;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
next_unitid += count;
|
||||||
|
if (next_unitid > max_unitid) {
|
||||||
|
max_unitid = next_unitid;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup the hypetransport link */
|
/* Setup the hypetransport link */
|
||||||
bus->reset_needed |= ht_setup_link(&prev, dev, pos);
|
bus->reset_needed |= ht_setup_link(&prev, dev, pos);
|
||||||
|
@ -531,7 +534,8 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||||
dev->vendor, dev->device,
|
dev->vendor, dev->device,
|
||||||
(dev->enabled? "enabled": "disabled"), next_unitid);
|
(dev->enabled? "enabled": "disabled"), next_unitid);
|
||||||
|
|
||||||
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f /*(max_devfn >> 3)*/ ));
|
} while (last_unitid != next_unitid);
|
||||||
|
out:
|
||||||
end_of_chain:
|
end_of_chain:
|
||||||
#if OPT_HT_LINK == 1
|
#if OPT_HT_LINK == 1
|
||||||
if(bus->reset_needed) {
|
if(bus->reset_needed) {
|
||||||
|
@ -542,8 +546,8 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) ) {
|
if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used) {
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
int i;
|
int i;
|
||||||
device_t last_func = 0;
|
device_t last_func = 0;
|
||||||
|
@ -559,15 +563,18 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||||
|
|
||||||
ht_unitid_base[ht_dev_num-1] = HT_CHAIN_END_UNITID_BASE; // update last one
|
ht_unitid_base[ht_dev_num-1] = HT_CHAIN_END_UNITID_BASE; // update last one
|
||||||
|
|
||||||
next_unitid = real_last_unitid;
|
printk_debug(" unitid: %04x --> %04x\n",
|
||||||
|
real_last_unitid, HT_CHAIN_END_UNITID_BASE);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
next_unitid = max_unitid;
|
||||||
|
|
||||||
if (next_unitid > 0x1f) {
|
if (next_unitid > 0x20) {
|
||||||
next_unitid = 0x1f;
|
next_unitid = 0x20;
|
||||||
}
|
}
|
||||||
if( (bus->secondary == 0) && (next_unitid > 0x17)) {
|
if( (bus->secondary == 0) && (next_unitid > 0x18)) {
|
||||||
next_unitid = 0x17; /* avoid K8 on bus 0 */
|
next_unitid = 0x18; /* avoid K8 on bus 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Die if any leftover Static devices are are found.
|
/* Die if any leftover Static devices are are found.
|
||||||
|
|
|
@ -13,22 +13,23 @@ static void enumerate_ht_chain(void)
|
||||||
* links needs to be programed to point at bus 0.
|
* links needs to be programed to point at bus 0.
|
||||||
*/
|
*/
|
||||||
unsigned next_unitid, last_unitid;
|
unsigned next_unitid, last_unitid;
|
||||||
unsigned temp_unitid;
|
device_t dev;
|
||||||
unsigned not_use_count;
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
|
||||||
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
||||||
unsigned real_last_unitid;
|
unsigned real_last_unitid;
|
||||||
uint8_t real_last_pos;
|
uint8_t real_last_pos;
|
||||||
int ht_dev_num = 0; // except host_bridge
|
int ht_dev_num = 0; // except host_bridge
|
||||||
|
uint8_t end_used = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
dev = PCI_DEV(0,0,0);
|
||||||
next_unitid = HT_CHAIN_UNITID_BASE;
|
next_unitid = HT_CHAIN_UNITID_BASE;
|
||||||
do {
|
do {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint8_t hdr_type, pos;
|
uint8_t hdr_type, pos;
|
||||||
last_unitid = next_unitid;
|
last_unitid = next_unitid;
|
||||||
|
|
||||||
id = pci_read_config32(PCI_DEV(0,0,0), PCI_VENDOR_ID);
|
id = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||||
/* If the chain is enumerated quit */
|
/* If the chain is enumerated quit */
|
||||||
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
|
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
|
||||||
(((id >> 16) & 0xffff) == 0xffff) ||
|
(((id >> 16) & 0xffff) == 0xffff) ||
|
||||||
|
@ -37,73 +38,102 @@ static void enumerate_ht_chain(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr_type = pci_read_config8(PCI_DEV(0,0,0), PCI_HEADER_TYPE);
|
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
|
||||||
pos = 0;
|
pos = 0;
|
||||||
hdr_type &= 0x7f;
|
hdr_type &= 0x7f;
|
||||||
|
|
||||||
if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
|
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);
|
pos = pci_read_config8(dev, PCI_CAPABILITY_LIST);
|
||||||
}
|
}
|
||||||
while(pos != 0) {
|
while(pos != 0) {
|
||||||
uint8_t cap;
|
uint8_t cap;
|
||||||
cap = pci_read_config8(PCI_DEV(0,0,0), pos + PCI_CAP_LIST_ID);
|
cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
|
||||||
if (cap == PCI_CAP_ID_HT) {
|
if (cap == PCI_CAP_ID_HT) {
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
/* Read and write and reread flags so the link
|
/* Read and write and reread flags so the link
|
||||||
* direction bit is valid.
|
* direction bit is valid.
|
||||||
*/
|
*/
|
||||||
flags = pci_read_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS);
|
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
||||||
pci_write_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS, flags);
|
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
|
||||||
flags = pci_read_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS);
|
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
||||||
if ((flags >> 13) == 0) {
|
if ((flags >> 13) == 0) {
|
||||||
unsigned count;
|
unsigned count;
|
||||||
unsigned ctrl, ctrl_off;
|
unsigned ctrl, ctrl_off;
|
||||||
|
device_t devx;
|
||||||
|
|
||||||
flags &= ~0x1f;
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
count = (flags >> 5) & 0x1f;
|
if(next_unitid>=0x18) { // don't get mask out by k8, at this time BSP, RT is not enabled, it will response from 0x18,0--0x1f.
|
||||||
not_use_count = 0;
|
if(!end_used) {
|
||||||
temp_unitid = next_unitid;
|
next_unitid = HT_CHAIN_END_UNITID_BASE;
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
end_used = 1;
|
||||||
if ( (count + next_unitid) >= 0x20) {
|
} else {
|
||||||
temp_unitid = HT_CHAIN_END_UNITID_BASE;
|
goto out;
|
||||||
not_use_count = 1;
|
}
|
||||||
}
|
}
|
||||||
real_last_unitid = temp_unitid;
|
real_last_unitid = next_unitid;
|
||||||
real_last_pos = pos;
|
real_last_pos = pos;
|
||||||
ht_dev_num++;
|
ht_dev_num++;
|
||||||
#endif
|
#endif
|
||||||
flags |= temp_unitid & 0x1f;
|
|
||||||
if(!not_use_count)
|
|
||||||
next_unitid += count;
|
|
||||||
|
|
||||||
|
flags &= ~0x1f;
|
||||||
|
flags |= next_unitid & 0x1f;
|
||||||
|
count = (flags >> 5) & 0x1f;
|
||||||
|
|
||||||
|
devx = PCI_DEV(0, next_unitid, 0);
|
||||||
|
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
|
||||||
|
|
||||||
|
next_unitid += count;
|
||||||
|
|
||||||
|
flags = pci_read_config16(devx, pos + PCI_CAP_FLAGS);
|
||||||
/* Test for end of chain */
|
/* Test for end of chain */
|
||||||
ctrl_off = ((flags >> 10) & 1)?
|
ctrl_off = ((flags >> 10) & 1)?
|
||||||
PCI_HT_CAP_SLAVE_CTRL1 : PCI_HT_CAP_SLAVE_CTRL0;
|
PCI_HT_CAP_SLAVE_CTRL0 : PCI_HT_CAP_SLAVE_CTRL1; // another end
|
||||||
ctrl = pci_read_config16(PCI_DEV(0,0,0), pos + ctrl_off);
|
|
||||||
/* Is this the end of the hypertransport chain.
|
do {
|
||||||
* or has the link failed?
|
ctrl = pci_read_config16(devx, pos + ctrl_off);
|
||||||
*/
|
/* Is this the end of the hypertransport chain? */
|
||||||
if (ctrl & ((1 << 6)|(1 << 4))) {
|
if (ctrl & (1 << 6)) {
|
||||||
next_unitid = 0x20;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_write_config16(PCI_DEV(0, 0, 0), pos + PCI_CAP_FLAGS, flags);
|
if (ctrl & ((1 << 4) | (1 << 8))) {
|
||||||
|
/*
|
||||||
|
* Either the link has failed, or we have
|
||||||
|
* a CRC error.
|
||||||
|
* Sometimes this can happen due to link
|
||||||
|
* retrain, so lets knock it down and see
|
||||||
|
* if its transient
|
||||||
|
*/
|
||||||
|
ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc
|
||||||
|
pci_write_config16(devx, pos + ctrl_off, ctrl);
|
||||||
|
ctrl = pci_read_config16(devx, pos + ctrl_off);
|
||||||
|
if (ctrl & ((1 << 4) | (1 << 8))) {
|
||||||
|
// can not clear the error
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while((ctrl & (1 << 5)) == 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pos = pci_read_config8(PCI_DEV(0, 0, 0), pos + PCI_CAP_LIST_NEXT);
|
pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
|
||||||
}
|
}
|
||||||
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
|
} while(last_unitid != next_unitid);
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
out:
|
||||||
if((ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE)) {
|
;
|
||||||
|
|
||||||
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
|
if((ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used) {
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
flags = pci_read_config16(PCI_DEV(0,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
dev = PCI_DEV(0,real_last_unitid, 0);
|
||||||
|
flags = pci_read_config16(dev, real_last_pos + PCI_CAP_FLAGS);
|
||||||
flags &= ~0x1f;
|
flags &= ~0x1f;
|
||||||
flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
|
flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
|
||||||
pci_write_config16(PCI_DEV(0, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags);
|
pci_write_config16(dev, real_last_pos + PCI_CAP_FLAGS, flags);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -314,12 +314,6 @@ static int scan_pci_bus( unsigned bus)
|
||||||
|
|
||||||
new_bus = bus;
|
new_bus = bus;
|
||||||
|
|
||||||
#if 0
|
|
||||||
#if CONFIG_USE_PRINTK_IN_CAR
|
|
||||||
printk_debug("bus_num=%02x\r\n", bus);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (devfn = 0; devfn <= 0xff; devfn++) {
|
for (devfn = 0; devfn <= 0xff; devfn++) {
|
||||||
uint8_t hdr_type;
|
uint8_t hdr_type;
|
||||||
uint16_t class;
|
uint16_t class;
|
||||||
|
@ -330,14 +324,6 @@ static int scan_pci_bus( unsigned bus)
|
||||||
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
|
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
|
||||||
class = pci_read_config16(dev, PCI_CLASS_DEVICE);
|
class = pci_read_config16(dev, PCI_CLASS_DEVICE);
|
||||||
|
|
||||||
#if 0
|
|
||||||
#if CONFIG_USE_PRINTK_IN_CAR
|
|
||||||
if(hdr_type !=0xff ) {
|
|
||||||
printk_debug("dev=%02x fn=%02x hdr_type=%02x class=%04x\r\n",
|
|
||||||
(devfn>>3)& 0x1f, (devfn & 0x7), hdr_type, class);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
switch(hdr_type & 0x7f) { /* header type */
|
switch(hdr_type & 0x7f) { /* header type */
|
||||||
case PCI_HEADER_TYPE_BRIDGE:
|
case PCI_HEADER_TYPE_BRIDGE:
|
||||||
if (class != PCI_CLASS_BRIDGE_PCI) goto bad;
|
if (class != PCI_CLASS_BRIDGE_PCI) goto bad;
|
||||||
|
@ -420,18 +406,17 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
|
||||||
|
|
||||||
uint8_t next_unitid, last_unitid;
|
uint8_t next_unitid, last_unitid;
|
||||||
unsigned uoffs;
|
unsigned uoffs;
|
||||||
uint8_t temp_unitid;
|
|
||||||
unsigned not_use_count;
|
|
||||||
|
|
||||||
#if RAMINIT_SYSINFO == 0
|
#if RAMINIT_SYSINFO == 0
|
||||||
int reset_needed = 0;
|
int reset_needed = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
||||||
unsigned real_last_unitid;
|
unsigned real_last_unitid;
|
||||||
uint8_t real_last_pos;
|
uint8_t real_last_pos;
|
||||||
int ht_dev_num = 0;
|
int ht_dev_num = 0;
|
||||||
|
uint8_t end_used = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uoffs = PCI_HT_HOST_OFFS;
|
uoffs = PCI_HT_HOST_OFFS;
|
||||||
|
@ -491,36 +476,36 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the Unitid of the current device */
|
|
||||||
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
|
||||||
/* Compute the number of unitids consumed */
|
|
||||||
count = (flags >> 5) & 0x1f;
|
|
||||||
flags &= ~0x1f; /* mask out the base Unit ID */
|
|
||||||
|
|
||||||
not_use_count = 0;
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
temp_unitid = next_unitid;
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
|
||||||
if(offset_unitid) {
|
if(offset_unitid) {
|
||||||
if( (next_unitid + count) >= 0x20) {
|
if(next_unitid>= (bus ? 0x20:0x18) ) {
|
||||||
temp_unitid = HT_CHAIN_END_UNITID_BASE;
|
if(!end_used) {
|
||||||
// keep to use the old next_unitid
|
next_unitid = HT_CHAIN_END_UNITID_BASE;
|
||||||
not_use_count = 1;
|
end_used = 1;
|
||||||
|
} else {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
real_last_pos = pos;
|
real_last_pos = pos;
|
||||||
real_last_unitid = temp_unitid;
|
real_last_unitid = next_unitid;
|
||||||
ht_dev_num++;
|
ht_dev_num++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Update the Unitid of the current device */
|
||||||
flags |= temp_unitid & 0x1f;
|
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
||||||
|
flags &= ~0x1f; /* mask out the base Unit ID */
|
||||||
|
flags |= next_unitid & 0x1f;
|
||||||
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
|
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
|
||||||
|
|
||||||
|
/* Compute the number of unitids consumed */
|
||||||
|
count = (flags >> 5) & 0x1f;
|
||||||
|
|
||||||
/* Note the change in device number */
|
/* Note the change in device number */
|
||||||
dev = PCI_DEV(bus, temp_unitid, 0);
|
dev = PCI_DEV(bus, next_unitid, 0);
|
||||||
|
|
||||||
if(!not_use_count)
|
|
||||||
next_unitid += count;
|
|
||||||
|
|
||||||
|
next_unitid += count;
|
||||||
|
|
||||||
/* Find which side of the ht link we are on,
|
/* Find which side of the ht link we are on,
|
||||||
* by reading which direction our last write to PCI_CAP_FLAGS
|
* by reading which direction our last write to PCI_CAP_FLAGS
|
||||||
|
@ -550,12 +535,13 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
|
||||||
upos = pos;
|
upos = pos;
|
||||||
uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
|
uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
|
||||||
|
|
||||||
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
|
} while (last_unitid != next_unitid );
|
||||||
|
|
||||||
|
out:
|
||||||
end_of_chain: ;
|
end_of_chain: ;
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) ) {
|
if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used ) {
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
int i;
|
int i;
|
||||||
flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
||||||
|
@ -594,7 +580,7 @@ static int ht_setup_chain(device_t udev, unsigned upos)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
unsigned offset_unitid = 0;
|
unsigned offset_unitid = 0;
|
||||||
#if HT_CHAIN_UNITID_BASE != 1
|
#if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
|
||||||
offset_unitid = 1;
|
offset_unitid = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -607,7 +593,7 @@ static int ht_setup_chain(device_t udev, unsigned upos)
|
||||||
/* Make certain the HT bus is not enumerated */
|
/* Make certain the HT bus is not enumerated */
|
||||||
ht_collapse_previous_enumeration(0, 0);
|
ht_collapse_previous_enumeration(0, 0);
|
||||||
|
|
||||||
#if HT_CHAIN_UNITID_BASE != 1
|
#if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
|
||||||
offset_unitid = 1;
|
offset_unitid = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -655,7 +641,7 @@ static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
unsigned devn = 1;
|
unsigned devn = 1;
|
||||||
|
|
||||||
#if HT_CHAIN_UNITID_BASE != 1
|
#if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
|
||||||
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
||||||
if(i==0) // to check if it is sb ht chain
|
if(i==0) // to check if it is sb ht chain
|
||||||
#endif
|
#endif
|
||||||
|
@ -788,7 +774,7 @@ static int ht_setup_chains(uint8_t ht_c_num)
|
||||||
pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword);
|
pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword);
|
||||||
|
|
||||||
|
|
||||||
#if HT_CHAIN_UNITID_BASE != 1
|
#if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
|
||||||
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
||||||
if(i==0) // to check if it is sb ht chain
|
if(i==0) // to check if it is sb ht chain
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -111,6 +111,7 @@ static unsigned int amdk8_scan_chain(device_t dev, unsigned nodeid, unsigned lin
|
||||||
unsigned ht_unitid_base[4]; // here assume only 4 HT device on chain
|
unsigned ht_unitid_base[4]; // here assume only 4 HT device on chain
|
||||||
unsigned max_bus;
|
unsigned max_bus;
|
||||||
unsigned min_bus;
|
unsigned min_bus;
|
||||||
|
unsigned max_devfn;
|
||||||
|
|
||||||
dev->link[link].cap = 0x80 + (link *0x20);
|
dev->link[link].cap = 0x80 + (link *0x20);
|
||||||
do {
|
do {
|
||||||
|
@ -212,7 +213,13 @@ static unsigned int amdk8_scan_chain(device_t dev, unsigned nodeid, unsigned lin
|
||||||
for(i=0;i<4;i++) {
|
for(i=0;i<4;i++) {
|
||||||
ht_unitid_base[i] = 0x20;
|
ht_unitid_base[i] = 0x20;
|
||||||
}
|
}
|
||||||
max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max, ht_unitid_base, offset_unitid);
|
|
||||||
|
if (min_bus == 0)
|
||||||
|
max_devfn = (0x17<<3) | 7;
|
||||||
|
else
|
||||||
|
max_devfn = (0x1f<<3) | 7;
|
||||||
|
|
||||||
|
max = hypertransport_scan_chain(&dev->link[link], 0, max_devfn, max, ht_unitid_base, offset_unitid);
|
||||||
|
|
||||||
/* We know the number of busses behind this bridge. Set the
|
/* We know the number of busses behind this bridge. Set the
|
||||||
* subordinate bus number to it's real value
|
* subordinate bus number to it's real value
|
||||||
|
@ -250,12 +257,10 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
||||||
unsigned offset_unitid = 0;
|
unsigned offset_unitid = 0;
|
||||||
nodeid = amdk8_nodeid(dev);
|
nodeid = amdk8_nodeid(dev);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(nodeid==0) {
|
if(nodeid==0) {
|
||||||
sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
|
sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
|
||||||
#if SB_HT_CHAIN_ON_BUS0 > 0
|
#if SB_HT_CHAIN_ON_BUS0 > 0
|
||||||
#if HT_CHAIN_UNITID_BASE != 1
|
#if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
|
||||||
offset_unitid = 1;
|
offset_unitid = 1;
|
||||||
#endif
|
#endif
|
||||||
max = amdk8_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
|
max = amdk8_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
|
||||||
|
@ -267,7 +272,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
||||||
if( (nodeid == 0) && (sblink == link) ) continue; //already done
|
if( (nodeid == 0) && (sblink == link) ) continue; //already done
|
||||||
#endif
|
#endif
|
||||||
offset_unitid = 0;
|
offset_unitid = 0;
|
||||||
#if HT_CHAIN_UNITID_BASE != 1
|
#if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
|
||||||
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
||||||
if((nodeid == 0) && (sblink == link))
|
if((nodeid == 0) && (sblink == link))
|
||||||
#endif
|
#endif
|
||||||
|
@ -276,6 +281,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
||||||
|
|
||||||
max = amdk8_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
|
max = amdk8_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
#define MCP55_DEVN_BASE HT_CHAIN_END_UNITID_BASE
|
#define MCP55_DEVN_BASE HT_CHAIN_END_UNITID_BASE
|
||||||
#else
|
#else
|
||||||
#define MCP55_DEVN_BASE HT_CHAIN_UNITID_BASE
|
#define MCP55_DEVN_BASE HT_CHAIN_UNITID_BASE
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE != 0x20
|
||||||
#define MCP55_DEVN_BASE HT_CHAIN_END_UNITID_BASE
|
#define MCP55_DEVN_BASE HT_CHAIN_END_UNITID_BASE
|
||||||
#else
|
#else
|
||||||
#define MCP55_DEVN_BASE HT_CHAIN_UNITID_BASE
|
#define MCP55_DEVN_BASE HT_CHAIN_UNITID_BASE
|
||||||
|
|
Loading…
Reference in New Issue