aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r--drivers/pci/probe.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 188ee9cf0605..2803ab96a98c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -437,11 +437,56 @@ void pcie_update_link_speed(struct pci_bus *bus, u16 linksta)
437} 437}
438EXPORT_SYMBOL_GPL(pcie_update_link_speed); 438EXPORT_SYMBOL_GPL(pcie_update_link_speed);
439 439
440static unsigned char agp_speeds[] = {
441 AGP_UNKNOWN,
442 AGP_1X,
443 AGP_2X,
444 AGP_4X,
445 AGP_8X
446};
447
448static enum pci_bus_speed agp_speed(int agp3, int agpstat)
449{
450 int index = 0;
451
452 if (agpstat & 4)
453 index = 3;
454 else if (agpstat & 2)
455 index = 2;
456 else if (agpstat & 1)
457 index = 1;
458 else
459 goto out;
460
461 if (agp3) {
462 index += 2;
463 if (index == 5)
464 index = 0;
465 }
466
467 out:
468 return agp_speeds[index];
469}
470
471
440static void pci_set_bus_speed(struct pci_bus *bus) 472static void pci_set_bus_speed(struct pci_bus *bus)
441{ 473{
442 struct pci_dev *bridge = bus->self; 474 struct pci_dev *bridge = bus->self;
443 int pos; 475 int pos;
444 476
477 pos = pci_find_capability(bridge, PCI_CAP_ID_AGP);
478 if (!pos)
479 pos = pci_find_capability(bridge, PCI_CAP_ID_AGP3);
480 if (pos) {
481 u32 agpstat, agpcmd;
482
483 pci_read_config_dword(bridge, pos + PCI_AGP_STATUS, &agpstat);
484 bus->max_bus_speed = agp_speed(agpstat & 8, agpstat & 7);
485
486 pci_read_config_dword(bridge, pos + PCI_AGP_COMMAND, &agpcmd);
487 bus->cur_bus_speed = agp_speed(agpstat & 8, agpcmd & 7);
488 }
489
445 pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX); 490 pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX);
446 if (pos) { 491 if (pos) {
447 u16 status; 492 u16 status;