diff options
Diffstat (limited to 'drivers/char/agp/nvidia-agp.c')
| -rw-r--r-- | drivers/char/agp/nvidia-agp.c | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index df7f37b2739..a1861b75eb3 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -1,14 +1,13 @@ /* * Nvidia AGPGART routines. * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up - * to work in 2.5 by Dave Jones <davej@codemonkey.org.uk> + * to work in 2.5 by Dave Jones <davej@redhat.com> */ #include <linux/module.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/agp_backend.h> -#include <linux/gfp.h> #include <linux/page-flags.h> #include <linux/mm.h> #include <linux/jiffies.h> @@ -107,6 +106,7 @@ static int nvidia_configure(void) { int i, rc, num_dirs; u32 apbase, aplimit; + phys_addr_t apbase_phys; struct aper_size_info_8 *current_size; u32 temp; @@ -116,9 +116,8 @@ static int nvidia_configure(void) pci_write_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE, current_size->size_value); - /* address to map to */ - pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &apbase); - apbase &= PCI_BASE_ADDRESS_MEM_MASK; + /* address to map to */ + apbase = pci_bus_address(agp_bridge->dev, AGP_APERTURE_BAR); agp_bridge->gart_bus_addr = apbase; aplimit = apbase + (current_size->size * 1024 * 1024) - 1; pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APBASE, apbase); @@ -154,8 +153,12 @@ static int nvidia_configure(void) pci_write_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, temp | 0x100); /* map aperture */ + apbase_phys = pci_resource_start(agp_bridge->dev, AGP_APERTURE_BAR); nvidia_private.aperture = - (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE); + (volatile u32 __iomem *) ioremap(apbase_phys, 33 * PAGE_SIZE); + + if (!nvidia_private.aperture) + return -ENOMEM; return 0; } @@ -198,10 +201,15 @@ extern int agp_memory_reserved; static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type) { int i, j; + int mask_type; - if ((type != 0) || (mem->type != 0)) + mask_type = agp_generic_type_to_mask_type(mem->bridge, type); + if (mask_type != 0 || type != mem->type) return -EINVAL; + if (mem->page_count == 0) + return 0; + if ((pg_start + mem->page_count) > (nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE)) return -EINVAL; @@ -211,16 +219,19 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type return -EBUSY; } - if (mem->is_flushed == FALSE) { + if (!mem->is_flushed) { global_cache_flush(); - mem->is_flushed = TRUE; + mem->is_flushed = true; } 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), + page_to_phys(mem->pages[i]), mask_type), agp_bridge->gatt_table+nvidia_private.pg_offset+j); - readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j); /* PCI Posting. */ } + + /* PCI Posting. */ + readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j - 1); + agp_bridge->driver->tlb_flush(mem); return 0; } @@ -230,9 +241,15 @@ static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type { int i; - if ((type != 0) || (mem->type != 0)) + int mask_type; + + mask_type = agp_generic_type_to_mask_type(mem->bridge, type); + if (mask_type != 0 || type != mem->type) return -EINVAL; + if (mem->page_count == 0) + return 0; + 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); @@ -272,7 +289,7 @@ static void nvidia_tlbflush(struct agp_memory *mem) } -static struct aper_size_info_8 nvidia_generic_sizes[5] = +static const struct aper_size_info_8 nvidia_generic_sizes[5] = { {512, 131072, 7, 0}, {256, 65536, 6, 8}, @@ -283,17 +300,18 @@ static struct aper_size_info_8 nvidia_generic_sizes[5] = }; -static struct gatt_mask nvidia_generic_masks[] = +static const struct gatt_mask nvidia_generic_masks[] = { { .mask = 1, .type = 0} }; -static struct agp_bridge_driver nvidia_driver = { +static const struct agp_bridge_driver nvidia_driver = { .owner = THIS_MODULE, .aperture_sizes = nvidia_generic_sizes, .size_type = U8_APER_SIZE, .num_aperture_sizes = 5, + .needs_scratch_page = true, .configure = nvidia_configure, .fetch_size = nvidia_fetch_size, .cleanup = nvidia_cleanup, @@ -309,21 +327,24 @@ static struct agp_bridge_driver nvidia_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 int __devinit agp_nvidia_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int agp_nvidia_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { struct agp_bridge_data *bridge; u8 cap_ptr; nvidia_private.dev_1 = - pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); + pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); nvidia_private.dev_2 = - pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2)); + pci_get_bus_and_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)); + pci_get_bus_and_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 " @@ -368,7 +389,7 @@ static int __devinit agp_nvidia_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_nvidia_remove(struct pci_dev *pdev) +static void agp_nvidia_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); @@ -379,8 +400,8 @@ static void __devexit agp_nvidia_remove(struct pci_dev *pdev) #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); + pci_save_state(pdev); + pci_set_power_state(pdev, PCI_D3hot); return 0; } @@ -388,7 +409,7 @@ static int agp_nvidia_suspend(struct pci_dev *pdev, pm_message_t state) static int agp_nvidia_resume(struct pci_dev *pdev) { /* set power state 0 and restore PCI space */ - pci_set_power_state (pdev, 0); + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); /* reconfigure AGP hardware again */ @@ -442,6 +463,9 @@ static int __init agp_nvidia_init(void) static void __exit agp_nvidia_cleanup(void) { pci_unregister_driver(&agp_nvidia_pci_driver); + pci_dev_put(nvidia_private.dev_1); + pci_dev_put(nvidia_private.dev_2); + pci_dev_put(nvidia_private.dev_3); } module_init(agp_nvidia_init); |
