#include <device/device.h>
#include <device/path.h>
#include <device/pci.h>
+#include <device/pci_ids.h>
#include <device/hypertransport.h>
+#include <device/chip.h>
#include <part/hard_reset.h>
#include <part/fallback_boot.h>
first = *old_devices;
last = first;
while(last && last->sibling &&
+ (last->sibling->path.type == DEVICE_PATH_PCI) &&
(last->sibling->path.u.pci.devfn > last->path.u.pci.devfn)) {
last = last->sibling;
}
return first;
}
+static unsigned ht_read_freq_cap(device_t dev, unsigned pos)
+{
+ /* Handle bugs in valid hypertransport frequency reporting */
+ unsigned freq_cap;
+
+ freq_cap = pci_read_config16(dev, pos);
+ freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
+
+ /* AMD 8131 Errata 48 */
+ if ((dev->vendor == PCI_VENDOR_ID_AMD) &&
+ (dev->device == PCI_DEVICE_ID_AMD_8131_PCIX)) {
+ freq_cap &= ~(1 << HT_FREQ_800Mhz);
+ }
+ /* AMD 8151 Errata 23 */
+ if ((dev->vendor == PCI_VENDOR_ID_AMD) &&
+ (dev->device == PCI_DEVICE_ID_AMD_8151_SYSCTRL)) {
+ freq_cap &= ~(1 << HT_FREQ_800Mhz);
+ }
+ /* AMD K8 Unsupported 1Ghz? */
+ if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == 0x1100)) {
+ freq_cap &= ~(1 << HT_FREQ_1000Mhz);
+ }
+ return freq_cap;
+}
struct prev_link {
struct device *dev;
reset_needed = 0;
/* Read the capabilities */
- present_freq_cap = pci_read_config16(dev, pos + PCI_HT_CAP_SLAVE_FREQ_CAP0);
- upstream_freq_cap = pci_read_config16(prev->dev, prev->pos + prev->freq_cap_off);
+ present_freq_cap = ht_read_freq_cap(dev, pos + PCI_HT_CAP_SLAVE_FREQ_CAP0);
+ upstream_freq_cap = ht_read_freq_cap(prev->dev, prev->pos + prev->freq_cap_off);
present_width_cap = pci_read_config8(dev, pos + PCI_HT_CAP_SLAVE_WIDTH0);
upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off);
/* Calculate the highest useable frequency */
-#if 0
freq = log2(present_freq_cap & upstream_freq_cap);
-#else
- /* Errata for 8131 - freq 5 has hardware problems don't support it */
- freq = log2(present_freq_cap & upstream_freq_cap & 0x1f);
-#endif
/* Calculate the highest width */
ln_upstream_width_in = link_width_to_pow2[upstream_width_cap & 7];
break;
}
}
- if(pos) {
- pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
- }
+ pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
}
return pos;
}
else {
/* Add this device to the pci bus chain */
*chain_last = dev;
- /* Run the magice enable/disable sequence for the device */
- if (dev->ops && dev->ops->enable) {
- dev->ops->enable(dev);
+ /* Run the magice enable sequence for the device */
+ if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) {
+ int enable = dev->enabled;
+ dev->enabled = 1;
+ dev->chip->control->enable_dev(dev);
+ dev->enabled = enable;
}
/* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID);
+
+ /* If the chain is fully enumerated quit */
+ if (id == 0xffffffff || id == 0x00000000 ||
+ id == 0x0000ffff || id == 0xffff0000) {
+ printk_err("Missing static device: %s\n",
+ dev_path(dev));
+ break;
+ }
}
/* Update the device chain tail */
for(func = dev; func; func = func->sibling) {
/* Find the hypertransport link capability */
pos = ht_lookup_slave_capability(dev);
if (pos == 0) {
- printk_err("Hypertransport link capability not found");
+ printk_err("%s Hypertransport link capability not found",
+ dev_path(dev));
break;
}
printk_debug("%s [%04x/%04x] %s next_unitid: %04x\n",
dev_path(dev),
dev->vendor, dev->device,
- (dev->enable? "enabled": "disabled"), next_unitid);
+ (dev->enabled? "enabled": "disabled"), next_unitid);
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
#if HAVE_HARD_RESET == 1
printk_info("HyperT reset needed\n");
hard_reset();
}
- printk_debug("HyperT reset not needed\n");
+ else {
+ printk_debug("HyperT reset not needed\n");
+ }
#endif
if (next_unitid > 0x1f) {
next_unitid = 0x1f;