diff options
Diffstat (limited to 'drivers/char/agp/sis-agp.c')
| -rw-r--r-- | drivers/char/agp/sis-agp.c | 362 |
1 files changed, 227 insertions, 135 deletions
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index ebc05554045..2c74038da45 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -14,8 +14,11 @@ #define SIS_TLBCNTRL 0x97 #define SIS_TLBFLUSH 0x98 -static int __devinitdata agp_sis_force_delay = 0; -static int __devinitdata agp_sis_agp_spec = -1; +#define PCI_DEVICE_ID_SI_662 0x0662 +#define PCI_DEVICE_ID_SI_671 0x0671 + +static bool agp_sis_force_delay = 0; +static int agp_sis_agp_spec = -1; static int sis_fetch_size(void) { @@ -27,8 +30,8 @@ static int sis_fetch_size(void) values = A_SIZE_8(agp_bridge->driver->aperture_sizes); for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { if ((temp_size == values[i].size_value) || - ((temp_size & ~(0x03)) == - (values[i].size_value & ~(0x03)))) { + ((temp_size & ~(0x07)) == + (values[i].size_value & ~(0x07)))) { agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i); @@ -47,13 +50,12 @@ static void sis_tlbflush(struct agp_memory *mem) static int sis_configure(void) { - u32 temp; struct aper_size_info_8 *current_size; current_size = A_SIZE_8(agp_bridge->current_size); pci_write_config_byte(agp_bridge->dev, SIS_TLBCNTRL, 0x05); - pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); - agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev, + AGP_APERTURE_BAR); pci_write_config_dword(agp_bridge->dev, SIS_ATTBASE, agp_bridge->gatt_bus_addr); pci_write_config_byte(agp_bridge->dev, SIS_APSIZE, @@ -76,10 +78,8 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode) u32 command; int rate; - printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n", - agp_bridge->major_version, - agp_bridge->minor_version, - pci_name(agp_bridge->dev)); + dev_info(&agp_bridge->dev->dev, "AGP %d.%d bridge\n", + agp_bridge->major_version, agp_bridge->minor_version); pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + PCI_AGP_STATUS, &command); command = agp_collect_device_status(bridge, mode, command); @@ -91,8 +91,8 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode) if (!agp) continue; - printk(KERN_INFO PFX "Putting AGP V3 device at %s into %dx mode\n", - pci_name(device), rate); + dev_info(&agp_bridge->dev->dev, "putting AGP V3 device at %s into %dx mode\n", + pci_name(device), rate); pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command); @@ -102,13 +102,13 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode) * cannot be configured */ if (device->device == bridge->dev->device) { - printk(KERN_INFO PFX "SiS delay workaround: giving bridge time to recover.\n"); + dev_info(&agp_bridge->dev->dev, "SiS delay workaround: giving bridge time to recover\n"); msleep(10); } } } -static struct aper_size_info_8 sis_generic_sizes[7] = +static const struct aper_size_info_8 sis_generic_sizes[7] = { {256, 65536, 6, 99}, {128, 32768, 5, 83}, @@ -121,9 +121,10 @@ static struct aper_size_info_8 sis_generic_sizes[7] = static struct agp_bridge_driver sis_driver = { .owner = THIS_MODULE, - .aperture_sizes = sis_generic_sizes, + .aperture_sizes = sis_generic_sizes, .size_type = U8_APER_SIZE, .num_aperture_sizes = 7, + .needs_scratch_page = true, .configure = sis_configure, .fetch_size = sis_fetch_size, .cleanup = sis_cleanup, @@ -139,115 +140,28 @@ static struct agp_bridge_driver sis_driver = { .alloc_by_type = agp_generic_alloc_by_type, .free_by_type = agp_generic_free_by_type, .agp_alloc_page = agp_generic_alloc_page, + .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, + .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; -static struct agp_device_ids sis_agp_device_ids[] __devinitdata = -{ - { - .device_id = PCI_DEVICE_ID_SI_5591_AGP, - .chipset_name = "5591", - }, - { - .device_id = PCI_DEVICE_ID_SI_530, - .chipset_name = "530", - }, - { - .device_id = PCI_DEVICE_ID_SI_540, - .chipset_name = "540", - }, - { - .device_id = PCI_DEVICE_ID_SI_550, - .chipset_name = "550", - }, - { - .device_id = PCI_DEVICE_ID_SI_620, - .chipset_name = "620", - }, - { - .device_id = PCI_DEVICE_ID_SI_630, - .chipset_name = "630", - }, - { - .device_id = PCI_DEVICE_ID_SI_635, - .chipset_name = "635", - }, - { - .device_id = PCI_DEVICE_ID_SI_645, - .chipset_name = "645", - }, - { - .device_id = PCI_DEVICE_ID_SI_646, - .chipset_name = "646", - }, - { - .device_id = PCI_DEVICE_ID_SI_648, - .chipset_name = "648", - }, - { - .device_id = PCI_DEVICE_ID_SI_650, - .chipset_name = "650", - }, - { - .device_id = PCI_DEVICE_ID_SI_651, - .chipset_name = "651", - }, - { - .device_id = PCI_DEVICE_ID_SI_655, - .chipset_name = "655", - }, - { - .device_id = PCI_DEVICE_ID_SI_661, - .chipset_name = "661", - }, - { - .device_id = PCI_DEVICE_ID_SI_730, - .chipset_name = "730", - }, - { - .device_id = PCI_DEVICE_ID_SI_735, - .chipset_name = "735", - }, - { - .device_id = PCI_DEVICE_ID_SI_740, - .chipset_name = "740", - }, - { - .device_id = PCI_DEVICE_ID_SI_741, - .chipset_name = "741", - }, - { - .device_id = PCI_DEVICE_ID_SI_745, - .chipset_name = "745", - }, - { - .device_id = PCI_DEVICE_ID_SI_746, - .chipset_name = "746", - }, - { - .device_id = PCI_DEVICE_ID_SI_760, - .chipset_name = "760", - }, - { }, /* dummy final entry, always present */ -}; - - // chipsets that require the 'delay hack' -static int sis_broken_chipsets[] __devinitdata = { +static int sis_broken_chipsets[] = { PCI_DEVICE_ID_SI_648, PCI_DEVICE_ID_SI_746, 0 // terminator }; -static void __devinit sis_get_driver(struct agp_bridge_data *bridge) +static void sis_get_driver(struct agp_bridge_data *bridge) { int i; - for(i=0; sis_broken_chipsets[i]!=0; ++i) - if(bridge->dev->device==sis_broken_chipsets[i]) + for (i=0; sis_broken_chipsets[i]!=0; ++i) + if (bridge->dev->device==sis_broken_chipsets[i]) break; - if(sis_broken_chipsets[i] || agp_sis_force_delay) + if (sis_broken_chipsets[i] || agp_sis_force_delay) sis_driver.agp_enable=sis_delayed_enable; // sis chipsets that indicate less than agp3.5 @@ -265,32 +179,18 @@ static void __devinit sis_get_driver(struct agp_bridge_data *bridge) } -static int __devinit agp_sis_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int agp_sis_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct agp_device_ids *devs = sis_agp_device_ids; struct agp_bridge_data *bridge; u8 cap_ptr; - int j; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); if (!cap_ptr) return -ENODEV; - /* probe for known chipsets */ - for (j = 0; devs[j].chipset_name; j++) { - if (pdev->device == devs[j].device_id) { - printk(KERN_INFO PFX "Detected SiS %s chipset\n", - devs[j].chipset_name); - goto found; - } - } - - printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x)\n", - pdev->device); - return -ENODEV; -found: + dev_info(&pdev->dev, "SiS chipset [%04x/%04x]\n", + pdev->vendor, pdev->device); bridge = agp_alloc_bridge(); if (!bridge) return -ENOMEM; @@ -309,7 +209,7 @@ found: return agp_add_bridge(bridge); } -static void __devexit agp_sis_remove(struct pci_dev *pdev) +static void agp_sis_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); @@ -317,14 +217,202 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev) agp_put_bridge(bridge); } +#ifdef CONFIG_PM + +static int agp_sis_suspend(struct pci_dev *pdev, pm_message_t state) +{ + pci_save_state(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +static int agp_sis_resume(struct pci_dev *pdev) +{ + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + return sis_driver.configure(); +} + +#endif /* CONFIG_PM */ + static struct pci_device_id agp_sis_pci_table[] = { { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_5591, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_530, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_540, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_550, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_620, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_630, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_635, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_645, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_646, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_648, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_650, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_651, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_655, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_661, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_662, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_671, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_730, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_735, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_740, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_741, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_745, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_746, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { } }; @@ -336,6 +424,10 @@ static struct pci_driver agp_sis_pci_driver = { .id_table = agp_sis_pci_table, .probe = agp_sis_probe, .remove = agp_sis_remove, +#ifdef CONFIG_PM + .suspend = agp_sis_suspend, + .resume = agp_sis_resume, +#endif }; static int __init agp_sis_init(void) |
