diff options
Diffstat (limited to 'drivers/char/agp/efficeon-agp.c')
| -rw-r--r-- | drivers/char/agp/efficeon-agp.c | 103 |
1 files changed, 59 insertions, 44 deletions
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index ac19fdcd21c..533cb6d229b 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -1,6 +1,6 @@ /* * Transmeta's Efficeon AGPGART driver. - * + * * Based upon a diff by Linus around November '02. * * Ported to the 2.6 kernel by Carlos Puchol <cpglinux@puchol.com> @@ -9,7 +9,7 @@ /* * NOTE-cpg-040217: - * + * * - when compiled as a module, after loading the module, * it will refuse to unload, indicating it is in use, * when it is not. @@ -28,6 +28,7 @@ #include <linux/page-flags.h> #include <linux/mm.h> #include "agp.h" +#include "intel-agp.h" /* * The real differences to the generic AGP code is @@ -45,7 +46,7 @@ * 8: Present * 7:6: reserved, write as zero * 5:0: GATT directory index: which 1st-level entry - * + * * The Efficeon AGP spec requires pages to be WB-cacheable * but to be explicitly CLFLUSH'd after any changes. */ @@ -59,12 +60,19 @@ static struct _efficeon_private { unsigned long l1_table[EFFICEON_L1_SIZE]; } efficeon_private; -static struct gatt_mask efficeon_generic_masks[] = +static const struct gatt_mask efficeon_generic_masks[] = { {.mask = 0x00000001, .type = 0} }; -static struct aper_size_info_lvl2 efficeon_generic_sizes[4] = +/* This function does the same thing as mask_memory() for this chipset... */ +static inline unsigned long efficeon_mask_memory(struct page *page) +{ + unsigned long addr = page_to_phys(page); + return addr | 0x00000001; +} + +static const struct aper_size_info_lvl2 efficeon_generic_sizes[4] = { {256, 65536, 0}, {128, 32768, 32}, @@ -120,12 +128,11 @@ static void efficeon_cleanup(void) static int efficeon_configure(void) { - u32 temp; u16 temp2; struct aper_size_info_lvl2 *current_size; printk(KERN_DEBUG PFX "efficeon_configure()\n"); - + current_size = A_SIZE_LVL2(agp_bridge->current_size); /* aperture size */ @@ -133,8 +140,8 @@ static int efficeon_configure(void) current_size->size_value); /* address to map to */ - 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); /* agpctrl */ pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280); @@ -171,7 +178,7 @@ static int efficeon_free_gatt_table(struct agp_bridge_data *bridge) /* - * Since we don't need contigious memory we just try + * Since we don't need contiguous memory we just try * to get the gatt table once */ @@ -190,7 +197,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge) const int present = EFFICEON_PRESENT; const int clflush_chunk = ((cpuid_ebx(1) >> 8) & 0xff) << 3; int num_entries, l1_pages; - + num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; printk(KERN_DEBUG PFX "efficeon_create_gatt_table(%d)\n", num_entries); @@ -215,11 +222,11 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge) SetPageReserved(virt_to_page((char *)page)); for (offset = 0; offset < PAGE_SIZE; offset += clflush_chunk) - asm volatile("clflush %0" : : "m" (*(char *)(page+offset))); + clflush((char *)page+offset); efficeon_private.l1_table[index] = page; - value = virt_to_gart(page) | pati | present | index; + value = virt_to_phys((unsigned long *)page) | pati | present | index; pci_write_config_dword(agp_bridge->dev, EFFICEON_ATTPAGE, value); @@ -243,34 +250,35 @@ static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int t if (type != 0 || mem->type != 0) return -EINVAL; - if (mem->is_flushed == FALSE) { + if (!mem->is_flushed) { global_cache_flush(); - mem->is_flushed = TRUE; + mem->is_flushed = true; } last_page = NULL; for (i = 0; i < count; i++) { int index = pg_start + i; - unsigned long insert = mem->memory[i]; + unsigned long insert = efficeon_mask_memory(mem->pages[i]); page = (unsigned int *) efficeon_private.l1_table[index >> 10]; if (!page) continue; - + page += (index & 0x3ff); *page = insert; /* clflush is slow, so don't clflush until we have to */ - if ( last_page && - ((unsigned long)page^(unsigned long)last_page) & clflush_mask ) - asm volatile("clflush %0" : : "m" (*last_page)); + if (last_page && + (((unsigned long)page^(unsigned long)last_page) & + clflush_mask)) + clflush(last_page); last_page = page; } if ( last_page ) - asm volatile("clflush %0" : : "m" (*last_page)); + clflush(last_page); agp_bridge->driver->tlb_flush(mem); return 0; @@ -303,7 +311,7 @@ static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int t } -static struct agp_bridge_driver efficeon_driver = { +static const struct agp_bridge_driver efficeon_driver = { .owner = THIS_MODULE, .aperture_sizes = efficeon_generic_sizes, .size_type = LVL2_APER_SIZE, @@ -322,24 +330,20 @@ static struct agp_bridge_driver efficeon_driver = { .free_gatt_table = efficeon_free_gatt_table, .insert_memory = efficeon_insert_memory, .remove_memory = efficeon_remove_memory, - .cant_use_aperture = 0, // 1 might be faster? + .cant_use_aperture = false, // true might be faster? // Generic .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 agp_efficeon_resume(struct pci_dev *pdev) -{ - printk(KERN_DEBUG PFX "agp_efficeon_resume()\n"); - return efficeon_configure(); -} - -static int __devinit agp_efficeon_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int agp_efficeon_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { struct agp_bridge_data *bridge; u8 cap_ptr; @@ -367,28 +371,30 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, bridge->capndx = cap_ptr; /* + * If the device has not been properly setup, the following will catch + * the problem and should stop the system from crashing. + * 20030610 - hamish@zot.org + */ + if (pci_enable_device(pdev)) { + printk(KERN_ERR PFX "Unable to Enable PCI device\n"); + agp_put_bridge(bridge); + return -ENODEV; + } + + /* * The following fixes the case where the BIOS has "forgotten" to * provide an address range for the GART. * 20030610 - hamish@zot.org */ r = &pdev->resource[0]; if (!r->start && r->end) { - if(pci_assign_resource(pdev, 0)) { + if (pci_assign_resource(pdev, 0)) { printk(KERN_ERR PFX "could not assign resource 0\n"); + agp_put_bridge(bridge); return -ENODEV; } } - /* - * If the device has not been properly setup, the following will catch - * the problem and should stop the system from crashing. - * 20030610 - hamish@zot.org - */ - if (pci_enable_device(pdev)) { - printk(KERN_ERR PFX "Unable to Enable PCI device\n"); - return -ENODEV; - } - /* Fill in the mode register */ if (cap_ptr) { pci_read_config_dword(pdev, @@ -400,7 +406,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_efficeon_remove(struct pci_dev *pdev) +static void agp_efficeon_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); @@ -408,11 +414,18 @@ static void __devexit agp_efficeon_remove(struct pci_dev *pdev) agp_put_bridge(bridge); } +#ifdef CONFIG_PM static int agp_efficeon_suspend(struct pci_dev *dev, pm_message_t state) { return 0; } +static int agp_efficeon_resume(struct pci_dev *pdev) +{ + printk(KERN_DEBUG PFX "agp_efficeon_resume()\n"); + return efficeon_configure(); +} +#endif static struct pci_device_id agp_efficeon_pci_table[] = { { @@ -433,8 +446,10 @@ static struct pci_driver agp_efficeon_pci_driver = { .id_table = agp_efficeon_pci_table, .probe = agp_efficeon_probe, .remove = agp_efficeon_remove, +#ifdef CONFIG_PM .suspend = agp_efficeon_suspend, .resume = agp_efficeon_resume, +#endif }; static int __init agp_efficeon_init(void) |
