#include <linux/gfp.h>
#include <linux/page-flags.h>
#include <linux/mm.h>
+#include <linux/jiffies.h>
#include "agp.h"
/* NVIDIA registers */
struct pci_dev *dev_1;
struct pci_dev *dev_2;
struct pci_dev *dev_3;
- volatile u32 *aperture;
+ volatile u32 __iomem *aperture;
int num_active_entries;
off_t pg_offset;
u32 wbc_mask;
/* Find the iorr that is already used for the base */
/* If not found, determine the uppermost available iorr */
free_iorr_addr = AMD_K7_NUM_IORR;
- for(iorr_addr = 0; iorr_addr < AMD_K7_NUM_IORR; iorr_addr++) {
+ for (iorr_addr = 0; iorr_addr < AMD_K7_NUM_IORR; iorr_addr++) {
rdmsr(IORR_BASE0 + 2 * iorr_addr, base_lo, base_hi);
rdmsr(IORR_MASK0 + 2 * iorr_addr, mask_lo, mask_hi);
if ((mask_lo & 0x00000800) == 0)
free_iorr_addr = iorr_addr;
}
-
+
if (iorr_addr >= AMD_K7_NUM_IORR) {
iorr_addr = free_iorr_addr;
if (iorr_addr >= AMD_K7_NUM_IORR)
}
/* attbase */
- for(i = 0; i < 8; i++) {
+ for (i = 0; i < 8; i++) {
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_ATTBASE(i),
(agp_bridge->gatt_bus_addr + (i % num_dirs) * 64 * 1024) | 1);
}
/* map aperture */
nvidia_private.aperture =
- (volatile u32 *) ioremap(apbase, 33 * PAGE_SIZE);
+ (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE);
return 0;
}
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, temp & ~(0x11));
/* unmap aperture */
- iounmap((void *) nvidia_private.aperture);
+ iounmap((void __iomem *) nvidia_private.aperture);
/* restore previous aperture size */
previous_size = A_SIZE_8(agp_bridge->previous_size);
static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i, j;
-
+
if ((type != 0) || (mem->type != 0))
return -EINVAL;
-
+
if ((pg_start + mem->page_count) >
(nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE))
return -EINVAL;
-
- for(j = pg_start; j < (pg_start + mem->page_count); j++) {
- if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[nvidia_private.pg_offset + j]))
+
+ for (j = pg_start; j < (pg_start + mem->page_count); j++) {
+ if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j)))
return -EBUSY;
}
global_cache_flush();
mem->is_flushed = TRUE;
}
- for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
- agp_bridge->gatt_table[nvidia_private.pg_offset + j] =
- agp_bridge->driver->mask_memory(mem->memory[i], mem->type);
-
+ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+ writel(agp_bridge->driver->mask_memory(agp_bridge,
+ mem->memory[i], mem->type),
+ agp_bridge->gatt_table+nvidia_private.pg_offset+j);
+ readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j); /* PCI Posting. */
+ }
agp_bridge->driver->tlb_flush(mem);
return 0;
}
if ((type != 0) || (mem->type != 0))
return -EINVAL;
-
- for (i = pg_start; i < (mem->page_count + pg_start); i++) {
- agp_bridge->gatt_table[nvidia_private.pg_offset + i] =
- (unsigned long) agp_bridge->scratch_page;
- }
+
+ for (i = pg_start; i < (mem->page_count + pg_start); i++)
+ writel(agp_bridge->scratch_page, agp_bridge->gatt_table+nvidia_private.pg_offset+i);
agp_bridge->driver->tlb_flush(mem);
return 0;
do {
pci_read_config_dword(nvidia_private.dev_1,
NVIDIA_1_WBC, &wbc_reg);
- if ((signed)(end - jiffies) <= 0) {
+ if (time_before_eq(end, jiffies)) {
printk(KERN_ERR PFX
"TLB flush took more than 3 seconds.\n");
}
}
/* flush TLB entries */
- for(i = 0; i < 32 + 1; i++)
- temp = nvidia_private.aperture[i * PAGE_SIZE / sizeof(u32)];
- for(i = 0; i < 32 + 1; i++)
- temp = nvidia_private.aperture[i * PAGE_SIZE / sizeof(u32)];
+ for (i = 0; i < 32 + 1; i++)
+ temp = readl(nvidia_private.aperture+(i * PAGE_SIZE / sizeof(u32)));
+ for (i = 0; i < 32 + 1; i++)
+ temp = readl(nvidia_private.aperture+(i * PAGE_SIZE / sizeof(u32)));
}
};
-struct agp_bridge_driver nvidia_driver = {
+static struct agp_bridge_driver nvidia_driver = {
.owner = THIS_MODULE,
.aperture_sizes = nvidia_generic_sizes,
.size_type = U8_APER_SIZE,
pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2));
nvidia_private.dev_3 =
pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0));
-
+
if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) {
printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 "
"chipset, but could not find the secondary devices.\n");
agp_put_bridge(bridge);
}
+#ifdef CONFIG_PM
+static int agp_nvidia_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ pci_save_state (pdev);
+ pci_set_power_state (pdev, 3);
+
+ return 0;
+}
+
+static int agp_nvidia_resume(struct pci_dev *pdev)
+{
+ /* set power state 0 and restore PCI space */
+ pci_set_power_state (pdev, 0);
+ pci_restore_state(pdev);
+
+ /* reconfigure AGP hardware again */
+ nvidia_configure();
+
+ return 0;
+}
+#endif
+
+
static struct pci_device_id agp_nvidia_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_ANY_ID,
+ .device = PCI_DEVICE_ID_NVIDIA_NFORCE,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+ {
+ .class = (PCI_CLASS_BRIDGE_HOST << 8),
+ .class_mask = ~0,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_NFORCE2,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
.id_table = agp_nvidia_pci_table,
.probe = agp_nvidia_probe,
.remove = agp_nvidia_remove,
+#ifdef CONFIG_PM
+ .suspend = agp_nvidia_suspend,
+ .resume = agp_nvidia_resume,
+#endif
};
static int __init agp_nvidia_init(void)
{
- return pci_module_init(&agp_nvidia_pci_driver);
+ if (agp_off)
+ return -EINVAL;
+ return pci_register_driver(&agp_nvidia_pci_driver);
}
static void __exit agp_nvidia_cleanup(void)