From d0de98fa16169562bd74913c6c9b3857f9065c79 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 31 May 2005 19:50:49 +0100 Subject: [PATCH] i945G patch for agpgart Attached is a small patch for i945G support against 2.6.11.11. From: Alan Hourihane Signed-off-by: Dave Jones diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 8c7d727..6a5047e 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -418,7 +418,8 @@ static void intel_i830_init_gtt_entries(void) case I915_GMCH_GMS_STOLEN_48M: /* Check it's really I915G */ if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) gtt_entries = MB(48) - KB(size); else gtt_entries = 0; @@ -426,7 +427,8 @@ static void intel_i830_init_gtt_entries(void) case I915_GMCH_GMS_STOLEN_64M: /* Check it's really I915G */ if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) gtt_entries = MB(64) - KB(size); else gtt_entries = 0; @@ -1662,6 +1664,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } name = "915GM"; break; + case PCI_DEVICE_ID_INTEL_82945G_HB: + if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG)) { + bridge->driver = &intel_915_driver; + } else { + bridge->driver = &intel_845_driver; + } + name = "945G"; + break; case PCI_DEVICE_ID_INTEL_7505_0: bridge->driver = &intel_7505_driver; name = "E7505"; @@ -1801,6 +1811,7 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_7205_0), ID(PCI_DEVICE_ID_INTEL_82915G_HB), ID(PCI_DEVICE_ID_INTEL_82915GM_HB), + ID(PCI_DEVICE_ID_INTEL_82945G_HB), { } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b0d6134..18f734e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2382,6 +2382,8 @@ #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 +#define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 +#define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 #define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 -- cgit v0.10.2 From e29b545cb153f230fbd8ff4c19bc98ab950f9f5c Mon Sep 17 00:00:00 2001 From: Michael Werner Date: Sun, 27 Mar 2005 22:08:42 -0800 Subject: [PATCH] sgi-agp: fixes a problem with accessing GART memory in sgi_tioca_insert_memory and sgi_tioca_remove_memory This patch fixes a problem with accessing GART memory in sgi_tioca_insert_memory and sgi_tioca_remove_memory. sgi-agp.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) Signed-off-by: Mike Werner Signed-off-by: Dave Jones diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 4b3eda2..d3aa159 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -133,11 +133,14 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, off_t j; void *temp; struct agp_bridge_data *bridge; + u64 *table; bridge = mem->bridge; if (!bridge) return -EINVAL; + table = (u64 *)bridge->gatt_table; + temp = bridge->current_size; switch (bridge->driver->size_type) { @@ -175,7 +178,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, j = pg_start; while (j < (pg_start + mem->page_count)) { - if (*(bridge->gatt_table + j)) + if (table[j]) return -EBUSY; j++; } @@ -186,7 +189,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - *(bridge->gatt_table + j) = + table[j] = bridge->driver->mask_memory(bridge, mem->memory[i], mem->type); } @@ -200,6 +203,7 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, { size_t i; struct agp_bridge_data *bridge; + u64 *table; bridge = mem->bridge; if (!bridge) @@ -209,8 +213,10 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, return -EINVAL; } + table = (u64 *)bridge->gatt_table; + for (i = pg_start; i < (mem->page_count + pg_start); i++) { - *(bridge->gatt_table + i) = 0; + table[i] = 0; } bridge->driver->tlb_flush(mem); -- cgit v0.10.2 From 07eee78ea8ba2d0b7b20551c35a3e7dd158d50bb Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 30 Mar 2005 13:17:04 -0800 Subject: [PATCH] AGP fix for Xen VMM When Linux is running on the Xen virtual machine monitor, physical addresses are virtualised and cannot be directly referenced by the AGP GART. This patch fixes the GART driver for Xen by adding a layer of abstraction between physical addresses and 'GART addresses'. Architecture-specific functions are also defined for allocating and freeing the GATT. Xen requires this to ensure that table really is contiguous from the point of view of the GART. These extra interface functions are defined as 'no-ops' for all existing architectures that use the GART driver. Signed-off-by: Keir Fraser Signed-off-by: Andrew Morton Signed-off-by: Dave Jones diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index ad9c113..c1fe013 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -278,6 +278,8 @@ void agp3_generic_cleanup(void); #define AGP_GENERIC_SIZES_ENTRIES 11 extern struct aper_size_info_16 agp3_generic_sizes[]; +#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x))) +#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x))) extern int agp_off; extern int agp_try_unsupported_boot; diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 0212feb..9c9c9c2 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -150,7 +150,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN )); + virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN )); return addr; } @@ -174,7 +174,7 @@ static void m1541_destroy_page(void * addr) pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN)); + virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); agp_generic_destroy_page(addr); } diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index e62a3c2..3a41672 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -43,7 +43,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); @@ -154,7 +154,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its @@ -167,7 +167,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { - writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, + writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1, page_dir.remapped+GET_PAGE_DIR_OFF(addr)); readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ } diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 399c042..1407945 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -219,7 +219,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] = static int amd_8151_configure(void) { - unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); + unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); /* Configure AGP regs in each x86-64 host bridge. */ for_each_nb() { @@ -591,7 +591,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - release_mem_region(virt_to_phys(bridge->gatt_table_real), + release_mem_region(virt_to_gart(bridge->gatt_table_real), amd64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index a65f882..e572ced 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_map *page_map) SetPageReserved(virt_to_page(page_map->real)); err = map_page_into_agp(virt_to_page(page_map->real)); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL || err) { ClearPageReserved(virt_to_page(page_map->real)); @@ -343,7 +343,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); /* Write out the size register */ current_size = A_SIZE_LVL2(agp_bridge->current_size); @@ -373,7 +373,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { - writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1, + writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1, page_dir.remapped+GET_PAGE_DIR_OFF(addr)); readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ } diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 2f3dfb6..4d4e602 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -148,7 +148,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) return -ENOMEM; } - bridge->scratch_page_real = virt_to_phys(addr); + bridge->scratch_page_real = virt_to_gart(addr); bridge->scratch_page = bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); } @@ -189,7 +189,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) err_out: if (bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( - phys_to_virt(bridge->scratch_page_real)); + gart_to_virt(bridge->scratch_page_real)); if (got_gatt) bridge->driver->free_gatt_table(bridge); if (got_keylist) { @@ -214,7 +214,7 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( - phys_to_virt(bridge->scratch_page_real)); + gart_to_virt(bridge->scratch_page_real)); } /* When we remove the global variable agp_bridge from all drivers diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 1383c31..ac19fdc 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge) efficeon_private.l1_table[index] = page; - value = __pa(page) | pati | present | index; + value = virt_to_gart(page) | pati | present | index; pci_write_config_dword(agp_bridge->dev, EFFICEON_ATTPAGE, value); diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index c321a92..d62505b 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -153,7 +153,7 @@ void agp_free_memory(struct agp_memory *curr) } if (curr->page_count != 0) { for (i = 0; i < curr->page_count; i++) { - curr->bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i])); + curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); } } agp_free_key(curr->key); @@ -209,7 +209,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, agp_free_memory(new); return NULL; } - new->memory[i] = virt_to_phys(addr); + new->memory[i] = virt_to_gart(addr); new->page_count++; } new->bridge = bridge; @@ -806,8 +806,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) break; } - table = (char *) __get_free_pages(GFP_KERNEL, - page_order); + table = alloc_gatt_pages(page_order); if (table == NULL) { i++; @@ -838,7 +837,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) size = ((struct aper_size_info_fixed *) temp)->size; page_order = ((struct aper_size_info_fixed *) temp)->page_order; num_entries = ((struct aper_size_info_fixed *) temp)->num_entries; - table = (char *) __get_free_pages(GFP_KERNEL, page_order); + table = alloc_gatt_pages(page_order); } if (table == NULL) @@ -853,7 +852,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) agp_gatt_table = (void *)table; bridge->driver->cache_flush(); - bridge->gatt_table = ioremap_nocache(virt_to_phys(table), + bridge->gatt_table = ioremap_nocache(virt_to_gart(table), (PAGE_SIZE * (1 << page_order))); bridge->driver->cache_flush(); @@ -861,11 +860,11 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_pages((unsigned long) table, page_order); + free_gatt_pages(table, page_order); return -ENOMEM; } - bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real); + bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real); /* AK: bogus, should encode addresses > 4GB */ for (i = 0; i < num_entries; i++) { @@ -919,7 +918,7 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_pages((unsigned long) bridge->gatt_table_real, page_order); + free_gatt_pages(bridge->gatt_table_real, page_order); agp_gatt_table = NULL; bridge->gatt_table = NULL; diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 6052bfa..99762b6 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -110,7 +110,7 @@ static int __init hp_zx1_ioc_shared(void) hp->gart_size = HP_ZX1_GART_SIZE; hp->gatt_entries = hp->gart_size / hp->io_page_size; - hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); + hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { @@ -248,7 +248,7 @@ hp_zx1_configure (void) agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); if (hp->io_pdir_owner) { - writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); + writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); readl(hp->ioc_regs+HP_ZX1_TCNFG); diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index adbea89..9494329 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -372,7 +372,7 @@ static int i460_alloc_large_page (struct lp_desc *lp) } memset(lp->alloced_map, 0, map_size); - lp->paddr = virt_to_phys(lpage); + lp->paddr = virt_to_gart(lpage); lp->refcount = 0; atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); return 0; @@ -383,7 +383,7 @@ static void i460_free_large_page (struct lp_desc *lp) kfree(lp->alloced_map); lp->alloced_map = NULL; - free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); + free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); } diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 6a5047e..51266d6 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -286,7 +286,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) if (new == NULL) return NULL; - new->memory[0] = virt_to_phys(addr); + new->memory[0] = virt_to_gart(addr); if (pg_count == 4) { /* kludge to get 4 physical pages for ARGB cursor */ new->memory[1] = new->memory[0] + PAGE_SIZE; @@ -329,10 +329,10 @@ static void intel_i810_free_by_type(struct agp_memory *curr) agp_free_key(curr->key); if(curr->type == AGP_PHYS_MEMORY) { if (curr->page_count == 4) - i8xx_destroy_pages(phys_to_virt(curr->memory[0])); + i8xx_destroy_pages(gart_to_virt(curr->memory[0])); else agp_bridge->driver->agp_destroy_page( - phys_to_virt(curr->memory[0])); + gart_to_virt(curr->memory[0])); vfree(curr->memory); } kfree(curr); diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 10c2330..a9fb12c 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -51,7 +51,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) } SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); @@ -162,7 +162,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) /* Create a fake scratch directory */ for(i = 0; i < 1024; i++) { writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); - writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); + writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); } retval = serverworks_create_gatt_pages(value->num_entries / 1024); @@ -174,7 +174,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its @@ -187,7 +187,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++) - writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); + writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); return 0; } diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index a673971..c825531 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -407,7 +407,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) bridge->gatt_table_real = (u32 *) table; bridge->gatt_table = (u32 *)table; - bridge->gatt_bus_addr = virt_to_phys(table); + bridge->gatt_bus_addr = virt_to_gart(table); for (i = 0; i < num_entries; i++) bridge->gatt_table[i] = 0; diff --git a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h index c99dbbb..ef855a3 100644 --- a/include/asm-alpha/agp.h +++ b/include/asm-alpha/agp.h @@ -10,4 +10,14 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-i386/agp.h b/include/asm-i386/agp.h index a917ff5..b82f5f3 100644 --- a/include/asm-i386/agp.h +++ b/include/asm-i386/agp.h @@ -21,4 +21,14 @@ int unmap_page_from_agp(struct page *page); worth it. Would need a page for it. */ #define flush_agp_cache() asm volatile("wbinvd":::"memory") +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h index d1316f1..4e517f0 100644 --- a/include/asm-ia64/agp.h +++ b/include/asm-ia64/agp.h @@ -18,4 +18,14 @@ #define flush_agp_mappings() /* nothing */ #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif /* _ASM_IA64_AGP_H */ diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h index be27cfa8..ca9e423 100644 --- a/include/asm-ppc/agp.h +++ b/include/asm-ppc/agp.h @@ -10,4 +10,14 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h index be27cfa8..ca9e423 100644 --- a/include/asm-ppc64/agp.h +++ b/include/asm-ppc64/agp.h @@ -10,4 +10,14 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h index ba05bdf..58f8cb6 100644 --- a/include/asm-sparc64/agp.h +++ b/include/asm-sparc64/agp.h @@ -8,4 +8,14 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h index 0bb9019..06c52ee 100644 --- a/include/asm-x86_64/agp.h +++ b/include/asm-x86_64/agp.h @@ -19,4 +19,14 @@ int unmap_page_from_agp(struct page *page); worth it. Would need a page for it. */ #define flush_agp_cache() asm volatile("wbinvd":::"memory") +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif -- cgit v0.10.2 From 66bb8bf8b235ba4d37fda14375827864977c6a3e Mon Sep 17 00:00:00 2001 From: David Mosberger Date: Mon, 4 Apr 2005 13:29:43 -0700 Subject: [PATCH] Replace check_bridge_mode() with (bridge->mode & AGSTAT_MODE_3_0). [AGPGART] Replace check_bridge_mode() with (bridge->mode & AGSTAT_MODE_3_0). As mentioned earlier, the current check_bridge_mode() code assumes that AGP bridges are PCI devices. This isn't always true. Definitely not for HP zx1 chipset and the same seems to be the case for SGI's AGP bridge. The patch below fixes the problem by picking up the AGP_MODE_3_0 bit from bridge->mode. I feel like I may be missing something, since I can't see any reason why check_bridge_mode() wasn't doing that in the first place. According to the AGP 3.0 specs, the AGP_MODE_3_0 bit is determined during the hardware reset and cannot be changed, so it seems to me it should be safe to pick it up from bridge->mode. With the patch applied, I can definitely use AGP acceleration both with AGP 2.0 and AGP 3.0 (one with an Nvidia card, the other with an ATI FireGL card). Unless someone spots a problem, please apply this patch so 3d acceleration can work on zx1 boxes again. This makes AGP work again on machines with an AGP bridge that isn't a PCI device. Signed-off-by: David Mosberger-Tang Signed-off-by: Dave Jones diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index d62505b..f0079e9 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -295,19 +295,6 @@ int agp_num_entries(void) EXPORT_SYMBOL_GPL(agp_num_entries); -static int check_bridge_mode(struct pci_dev *dev) -{ - u32 agp3; - u8 cap_ptr; - - cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); - pci_read_config_dword(dev, cap_ptr+AGPSTAT, &agp3); - if (agp3 & AGPSTAT_MODE_3_0) - return 1; - return 0; -} - - /** * agp_copy_info - copy bridge state information * @@ -328,7 +315,7 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info) info->version.minor = bridge->version->minor; info->chipset = SUPPORTED; info->device = bridge->dev; - if (check_bridge_mode(bridge->dev)) + if (bridge->mode & AGPSTAT_MODE_3_0) info->mode = bridge->mode & ~AGP3_RESERVED_MASK; else info->mode = bridge->mode & ~AGP2_RESERVED_MASK; @@ -661,7 +648,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode bridge_agpstat &= ~AGPSTAT_FW; /* Check to see if we are operating in 3.0 mode */ - if (check_bridge_mode(agp_bridge->dev)) + if (agp_bridge->mode & AGPSTAT_MODE_3_0) agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); else agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); @@ -732,7 +719,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode) /* Do AGP version specific frobbing. */ if (bridge->major_version >= 3) { - if (check_bridge_mode(bridge->dev)) { + if (bridge->mode & AGPSTAT_MODE_3_0) { /* If we have 3.5, we can do the isoch stuff. */ if (bridge->minor_version >= 5) agp_3_5_enable(bridge); -- cgit v0.10.2