aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/i460-agp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/agp/i460-agp.c')
-rw-r--r--drivers/char/agp/i460-agp.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 10da687d131a..60cc35bb5db7 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -60,6 +60,9 @@
60 */ 60 */
61#define WR_FLUSH_GATT(index) RD_GATT(index) 61#define WR_FLUSH_GATT(index) RD_GATT(index)
62 62
63static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
64 unsigned long addr, int type);
65
63static struct { 66static struct {
64 void *gatt; /* ioremap'd GATT area */ 67 void *gatt; /* ioremap'd GATT area */
65 68
@@ -74,6 +77,7 @@ static struct {
74 unsigned long *alloced_map; /* bitmap of kernel-pages in use */ 77 unsigned long *alloced_map; /* bitmap of kernel-pages in use */
75 int refcount; /* number of kernel pages using the large page */ 78 int refcount; /* number of kernel pages using the large page */
76 u64 paddr; /* physical address of large page */ 79 u64 paddr; /* physical address of large page */
80 struct page *page; /* page pointer */
77 } *lp_desc; 81 } *lp_desc;
78} i460; 82} i460;
79 83
@@ -294,7 +298,7 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem,
294 void *temp; 298 void *temp;
295 299
296 pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n", 300 pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n",
297 mem, pg_start, type, mem->memory[0]); 301 mem, pg_start, type, page_to_phys(mem->pages[0]));
298 302
299 if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES) 303 if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
300 return -EINVAL; 304 return -EINVAL;
@@ -321,10 +325,9 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem,
321 325
322 io_page_size = 1UL << I460_IO_PAGE_SHIFT; 326 io_page_size = 1UL << I460_IO_PAGE_SHIFT;
323 for (i = 0, j = io_pg_start; i < mem->page_count; i++) { 327 for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
324 paddr = mem->memory[i]; 328 paddr = phys_to_gart(page_to_phys(mem->pages[i]));
325 for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size) 329 for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size)
326 WR_GATT(j, agp_bridge->driver->mask_memory(agp_bridge, 330 WR_GATT(j, i460_mask_memory(agp_bridge, paddr, mem->type));
327 paddr, mem->type));
328 } 331 }
329 WR_FLUSH_GATT(j - 1); 332 WR_FLUSH_GATT(j - 1);
330 return 0; 333 return 0;
@@ -364,10 +367,9 @@ static int i460_alloc_large_page (struct lp_desc *lp)
364{ 367{
365 unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT; 368 unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT;
366 size_t map_size; 369 size_t map_size;
367 void *lpage;
368 370
369 lpage = (void *) __get_free_pages(GFP_KERNEL, order); 371 lp->page = alloc_pages(GFP_KERNEL, order);
370 if (!lpage) { 372 if (!lp->page) {
371 printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n"); 373 printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n");
372 return -ENOMEM; 374 return -ENOMEM;
373 } 375 }
@@ -375,12 +377,12 @@ static int i460_alloc_large_page (struct lp_desc *lp)
375 map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8; 377 map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8;
376 lp->alloced_map = kzalloc(map_size, GFP_KERNEL); 378 lp->alloced_map = kzalloc(map_size, GFP_KERNEL);
377 if (!lp->alloced_map) { 379 if (!lp->alloced_map) {
378 free_pages((unsigned long) lpage, order); 380 __free_pages(lp->page, order);
379 printk(KERN_ERR PFX "Out of memory, we're in trouble...\n"); 381 printk(KERN_ERR PFX "Out of memory, we're in trouble...\n");
380 return -ENOMEM; 382 return -ENOMEM;
381 } 383 }
382 384
383 lp->paddr = virt_to_gart(lpage); 385 lp->paddr = phys_to_gart(page_to_phys(lp->page));
384 lp->refcount = 0; 386 lp->refcount = 0;
385 atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); 387 atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
386 return 0; 388 return 0;
@@ -391,7 +393,7 @@ static void i460_free_large_page (struct lp_desc *lp)
391 kfree(lp->alloced_map); 393 kfree(lp->alloced_map);
392 lp->alloced_map = NULL; 394 lp->alloced_map = NULL;
393 395
394 free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); 396 __free_pages(lp->page, I460_IO_PAGE_SHIFT - PAGE_SHIFT);
395 atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); 397 atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
396} 398}
397 399
@@ -439,8 +441,8 @@ static int i460_insert_memory_large_io_page (struct agp_memory *mem,
439 if (i460_alloc_large_page(lp) < 0) 441 if (i460_alloc_large_page(lp) < 0)
440 return -ENOMEM; 442 return -ENOMEM;
441 pg = lp - i460.lp_desc; 443 pg = lp - i460.lp_desc;
442 WR_GATT(pg, agp_bridge->driver->mask_memory(agp_bridge, 444 WR_GATT(pg, i460_mask_memory(agp_bridge,
443 lp->paddr, 0)); 445 lp->paddr, 0));
444 WR_FLUSH_GATT(pg); 446 WR_FLUSH_GATT(pg);
445 } 447 }
446 448
@@ -448,7 +450,7 @@ static int i460_insert_memory_large_io_page (struct agp_memory *mem,
448 idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); 450 idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
449 idx++, i++) 451 idx++, i++)
450 { 452 {
451 mem->memory[i] = lp->paddr + idx*PAGE_SIZE; 453 mem->pages[i] = lp->page;
452 __set_bit(idx, lp->alloced_map); 454 __set_bit(idx, lp->alloced_map);
453 ++lp->refcount; 455 ++lp->refcount;
454 } 456 }
@@ -463,7 +465,7 @@ static int i460_remove_memory_large_io_page (struct agp_memory *mem,
463 struct lp_desc *start, *end, *lp; 465 struct lp_desc *start, *end, *lp;
464 void *temp; 466 void *temp;
465 467
466 temp = agp_bridge->driver->current_size; 468 temp = agp_bridge->current_size;
467 num_entries = A_SIZE_8(temp)->num_entries; 469 num_entries = A_SIZE_8(temp)->num_entries;
468 470
469 /* Figure out what pg_start means in terms of our large GART pages */ 471 /* Figure out what pg_start means in terms of our large GART pages */
@@ -477,7 +479,7 @@ static int i460_remove_memory_large_io_page (struct agp_memory *mem,
477 idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); 479 idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
478 idx++, i++) 480 idx++, i++)
479 { 481 {
480 mem->memory[i] = 0; 482 mem->pages[i] = NULL;
481 __clear_bit(idx, lp->alloced_map); 483 __clear_bit(idx, lp->alloced_map);
482 --lp->refcount; 484 --lp->refcount;
483 } 485 }
@@ -521,7 +523,7 @@ static int i460_remove_memory (struct agp_memory *mem,
521 * Let's just hope nobody counts on the allocated AGP memory being there before bind time 523 * Let's just hope nobody counts on the allocated AGP memory being there before bind time
522 * (I don't think current drivers do)... 524 * (I don't think current drivers do)...
523 */ 525 */
524static void *i460_alloc_page (struct agp_bridge_data *bridge) 526static struct page *i460_alloc_page (struct agp_bridge_data *bridge)
525{ 527{
526 void *page; 528 void *page;
527 529
@@ -534,7 +536,7 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
534 return page; 536 return page;
535} 537}
536 538
537static void i460_destroy_page (void *page, int flags) 539static void i460_destroy_page (struct page *page, int flags)
538{ 540{
539 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) { 541 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
540 agp_generic_destroy_page(page, flags); 542 agp_generic_destroy_page(page, flags);
@@ -544,13 +546,20 @@ static void i460_destroy_page (void *page, int flags)
544#endif /* I460_LARGE_IO_PAGES */ 546#endif /* I460_LARGE_IO_PAGES */
545 547
546static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, 548static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
547 unsigned long addr, int type) 549 unsigned long addr, int type)
548{ 550{
549 /* Make sure the returned address is a valid GATT entry */ 551 /* Make sure the returned address is a valid GATT entry */
550 return bridge->driver->masks[0].mask 552 return bridge->driver->masks[0].mask
551 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12); 553 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
552} 554}
553 555
556static unsigned long i460_page_mask_memory(struct agp_bridge_data *bridge,
557 struct page *page, int type)
558{
559 unsigned long addr = phys_to_gart(page_to_phys(page));
560 return i460_mask_memory(bridge, addr, type);
561}
562
554const struct agp_bridge_driver intel_i460_driver = { 563const struct agp_bridge_driver intel_i460_driver = {
555 .owner = THIS_MODULE, 564 .owner = THIS_MODULE,
556 .aperture_sizes = i460_sizes, 565 .aperture_sizes = i460_sizes,
@@ -560,7 +569,7 @@ const struct agp_bridge_driver intel_i460_driver = {
560 .fetch_size = i460_fetch_size, 569 .fetch_size = i460_fetch_size,
561 .cleanup = i460_cleanup, 570 .cleanup = i460_cleanup,
562 .tlb_flush = i460_tlb_flush, 571 .tlb_flush = i460_tlb_flush,
563 .mask_memory = i460_mask_memory, 572 .mask_memory = i460_page_mask_memory,
564 .masks = i460_masks, 573 .masks = i460_masks,
565 .agp_enable = agp_generic_enable, 574 .agp_enable = agp_generic_enable,
566 .cache_flush = global_cache_flush, 575 .cache_flush = global_cache_flush,