PCI: Add support for AGP in cur/max bus speed
authorMatthew Wilcox <matthew@wil.cx>
Sun, 13 Dec 2009 13:11:34 +0000 (08:11 -0500)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Tue, 23 Feb 2010 00:15:19 +0000 (16:15 -0800)
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>
drivers/pci/probe.c
drivers/pci/slot.c
include/linux/pci.h

index 188ee9cf06057718fcd7264129e26125b14712d2..2803ab96a98c69a27b56df8e063d32369ec7a138 100644 (file)
@@ -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;
index 6f6b8d24786ac8f32b6c3528319da41247c0e56c..c7260d4e339b565e3800c7217f2f474225f9b6e1 100644 (file)
@@ -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 */
index a446097a9f683d385ef6d80de8e67ae70ee2bb6e..842adaad312e5e2394416793b8bf2bf853f44159 100644 (file)
@@ -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,