Messages in this thread Patch in this message | | | Date | Sun, 23 May 2004 23:04:34 +0200 | From | Lukas Hejtmanek <> | Subject | PATCH: i830-agp |
| |
Hello,
this patch is taken from 2.4.24 Intel original patch for Embeded controlers. (www.intel.com/design/intarch/swsup/IEGDLinux.htm) Their patch is GPL'ed so could you please it include in vanilla 2.6.x kernel?
This patch fixes only 852GME/855 and 830 AGP garts with integrated graphics.
-- Lukáš Hejtmánek --- intel-agp.c.orig 2004-05-10 04:32:36.000000000 +0200 +++ intel-agp.c 2004-05-23 11:54:12.000000000 +0200 @@ -353,6 +353,8 @@ "No pre-allocated video memory detected.\n"); gtt_entries /= KB(4); + atomic_add(gtt_entries, &agp_bridge->current_memory_agp); + intel_i830_private.gtt_entries = gtt_entries; } @@ -365,6 +367,11 @@ struct aper_size_info_fixed *size; int num_entries; u32 temp; + u32 page_table_bus_address; + char *gtt_table, *gtt_table_end, *gtt_table_entry; + struct page *gtt_table_page; + u32 gtt_table_order = 5; + u32 gtt_table_size = (1<<gtt_table_order)*PAGE_SIZE - 1; size = agp_bridge->current_size; page_order = size->page_order; @@ -379,8 +386,28 @@ return (-ENOMEM); temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000; + page_table_bus_address = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); + if(!page_table_bus_address) { + /* Create GTT table */ + printk (KERN_INFO PFX "Creating new GTT table.\n"); + num_entries = intel_i830_sizes[0].num_entries; + gtt_table = (char*) __get_free_pages(GFP_KERNEL, gtt_table_order); + gtt_table_end = gtt_table + gtt_table_size; + for (gtt_table_entry = gtt_table; + gtt_table_entry < gtt_table_end; + gtt_table_entry += PAGE_SIZE ) { + gtt_table_page = virt_to_page(gtt_table_entry); + set_bit(PG_reserved, >t_table_page->flags); + } + agp_bridge->gatt_bus_addr = virt_to_phys(gtt_table); + agp_bridge->gatt_table = NULL; + intel_i830_private.gtt_entries = 0; + intel_i830_init_gtt_entries(); + return 0; + } + /* we have to call this as early as possible after the MMIO base address is known */ intel_i830_init_gtt_entries(); @@ -525,13 +552,73 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type) { - if (type == AGP_PHYS_MEMORY) - return(alloc_agpphysmem_i8xx(pg_count, type)); + struct agp_memory *nw; + if (type == AGP_DCACHE_MEMORY) return(NULL); + + if (type == AGP_PHYS_MEMORY) { + unsigned long virt; + unsigned long order; + int i; + + /* The i830 requires a physical address to program + * it's mouse pointer into hardware. However the + * Xserver still writes to it through the agp + * aperture + * NOTE: We canot use alloc_page() here because we may need + * several contiguous pages. We must therefore use + * __get_free_pages() for this case. + */ + + if (pg_count == 1) { + order = 0; + } else if (pg_count == 8) { + order = 3; + } else { + return(NULL); + } + + nw = agp_create_memory(pg_count); + if (nw == NULL) return(NULL); + + virt = __get_free_pages(GFP_KERNEL, order); + nw->physical = virt_to_phys((void *)virt); + if (virt == 0) { + /* free this structure */ + agp_free_memory(nw); + return(NULL); + } + for(i=0; i<pg_count; i++) { + /* CHECKME: Is this right??? */ + /* nw->memory[0] = virt_to_phys((void *) nw->memory[0]); */ + nw->memory[i] = agp_bridge->driver->mask_memory(nw->physical + 4096*i, type); + } + nw->page_count = pg_count; + nw->num_scratch_pages = pg_count; + + nw->type = AGP_PHYS_MEMORY; + return(nw); + } + /* always return NULL for other allocation types for now */ return(NULL); } +static void intel_i830_free_by_type(struct agp_memory * curr) +{ + agp_free_key(curr->key); + if (curr->type == AGP_PHYS_MEMORY) { + if (curr->page_count == 1) { + free_pages((unsigned long)phys_to_virt(curr->memory[0] & 0xfffff000), 0); + } else if (curr->page_count == 8) { + free_pages((unsigned long)phys_to_virt(curr->memory[0] & 0xfffff000), 3); + } + vfree(curr->memory); + } + kfree(curr); +} + static int intel_fetch_size(void) { int i; @@ -1056,7 +1143,7 @@ .insert_memory = intel_i830_insert_entries, .remove_memory = intel_i830_remove_entries, .alloc_by_type = intel_i830_alloc_by_type, - .free_by_type = intel_i810_free_by_type, + .free_by_type = intel_i830_free_by_type, .agp_alloc_page = agp_generic_alloc_page, .agp_destroy_page = agp_generic_destroy_page, }; | |