diff options
author | Matthew Wilcox <matthew@wil.cx> | 2009-12-13 14:11:34 +0100 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-02-23 01:15:19 +0100 |
commit | 45b4cdd57ef0e57555b2ab61b584784819b39365 (patch) | |
tree | 1e08008e0cdc57252022b5ad1a0e3029c7e96f99 | |
parent | PCI: Add support for detection of PCIe and PCI-X bus speeds (diff) | |
download | linux-45b4cdd57ef0e57555b2ab61b584784819b39365.tar.xz linux-45b4cdd57ef0e57555b2ab61b584784819b39365.zip |
PCI: Add support for AGP in cur/max bus speed
Take advantage of some gaps in the table to fit in support for AGP speeds.
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | drivers/pci/probe.c | 45 | ||||
-rw-r--r-- | drivers/pci/slot.c | 10 | ||||
-rw-r--r-- | include/linux/pci.h | 5 |
3 files changed, 55 insertions, 5 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) } EXPORT_SYMBOL_GPL(pcie_update_link_speed); +static unsigned char agp_speeds[] = { + AGP_UNKNOWN, + AGP_1X, + AGP_2X, + AGP_4X, + AGP_8X +}; + +static enum pci_bus_speed agp_speed(int agp3, int agpstat) +{ + int index = 0; + + if (agpstat & 4) + index = 3; + else if (agpstat & 2) + index = 2; + else if (agpstat & 1) + index = 1; + else + goto out; + + if (agp3) { + index += 2; + if (index == 5) + index = 0; + } + + out: + return agp_speeds[index]; +} + + static void pci_set_bus_speed(struct pci_bus *bus) { struct pci_dev *bridge = bus->self; int pos; + pos = pci_find_capability(bridge, PCI_CAP_ID_AGP); + if (!pos) + pos = pci_find_capability(bridge, PCI_CAP_ID_AGP3); + if (pos) { + u32 agpstat, agpcmd; + + pci_read_config_dword(bridge, pos + PCI_AGP_STATUS, &agpstat); + bus->max_bus_speed = agp_speed(agpstat & 8, agpstat & 7); + + pci_read_config_dword(bridge, pos + PCI_AGP_COMMAND, &agpcmd); + bus->cur_bus_speed = agp_speed(agpstat & 8, agpcmd & 7); + } + pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX); if (pos) { u16 status; diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 6f6b8d24786a..c7260d4e339b 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -61,11 +61,11 @@ static char *pci_bus_speed_strings[] = { "66 MHz PCI-X 266", /* 0x09 */ "100 MHz PCI-X 266", /* 0x0a */ "133 MHz PCI-X 266", /* 0x0b */ - NULL, /* 0x0c */ - NULL, /* 0x0d */ - NULL, /* 0x0e */ - NULL, /* 0x0f */ - NULL, /* 0x10 */ + "Unknown AGP", /* 0x0c */ + "1x AGP", /* 0x0d */ + "2x AGP", /* 0x0e */ + "4x AGP", /* 0x0f */ + "8x AGP", /* 0x10 */ "66 MHz PCI-X 533", /* 0x11 */ "100 MHz PCI-X 533", /* 0x12 */ "133 MHz PCI-X 533", /* 0x13 */ diff --git a/include/linux/pci.h b/include/linux/pci.h index a446097a9f68..842adaad312e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -200,6 +200,11 @@ enum pci_bus_speed { PCI_SPEED_66MHz_PCIX_266 = 0x09, PCI_SPEED_100MHz_PCIX_266 = 0x0a, PCI_SPEED_133MHz_PCIX_266 = 0x0b, + AGP_UNKNOWN = 0x0c, + AGP_1X = 0x0d, + AGP_2X = 0x0e, + AGP_4X = 0x0f, + AGP_8X = 0x10, PCI_SPEED_66MHz_PCIX_533 = 0x11, PCI_SPEED_100MHz_PCIX_533 = 0x12, PCI_SPEED_133MHz_PCIX_533 = 0x13, |