diff options
author | Matthew Wilcox <matthew@wil.cx> | 2009-12-13 08:11:34 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-02-22 16:15:19 -0800 |
commit | 45b4cdd57ef0e57555b2ab61b584784819b39365 (patch) | |
tree | 1e08008e0cdc57252022b5ad1a0e3029c7e96f99 /drivers/pci/probe.c | |
parent | 9be60ca0497a2563662fde4c9007841c3b79a742 (diff) |
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>
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 188ee9cf060..2803ab96a98 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; |