aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/uninorth-agp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 12:51:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 12:51:09 -0400
commit723e9db7a46e328527cc3da2b478b831184fe828 (patch)
treecdeda255633057dcb4c84097bed27b2bbf76970f /drivers/char/agp/uninorth-agp.c
parentada3fa15057205b7d3f727bba5cd26b5912e350f (diff)
parentd331d8305cba713605854aab63a000fb892353a7 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (134 commits) powerpc/nvram: Enable use Generic NVRAM driver for different size chips powerpc/iseries: Fix oops reading from /proc/iSeries/mf/*/cmdline powerpc/ps3: Workaround for flash memory I/O error powerpc/booke: Don't set DABR on 64-bit BookE, use DAC1 instead powerpc/perf_counters: Reduce stack usage of power_check_constraints powerpc: Fix bug where perf_counters breaks oprofile powerpc/85xx: Fix SMP compile error and allow NULL for smp_ops powerpc/irq: Improve nanodoc powerpc: Fix some late PowerMac G5 with PCIe ATI graphics powerpc/fsl-booke: Use HW PTE format if CONFIG_PTE_64BIT powerpc/book3e: Add missing page sizes powerpc/pseries: Fix to handle slb resize across migration powerpc/powermac: Thermal control turns system off too eagerly powerpc/pci: Merge ppc32 and ppc64 versions of phb_scan() powerpc/405ex: support cuImage via included dtb powerpc/405ex: provide necessary fixup function to support cuImage powerpc/40x: Add support for the ESTeem 195E (PPC405EP) SBC powerpc/44x: Add Eiger AMCC (AppliedMicro) PPC460SX evaluation board support. powerpc/44x: Update Arches defconfig powerpc/44x: Update Arches dts ... Fix up conflicts in drivers/char/agp/uninorth-agp.c
Diffstat (limited to 'drivers/char/agp/uninorth-agp.c')
-rw-r--r--drivers/char/agp/uninorth-agp.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 4317a5588da..20ef1bf5e72 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -7,6 +7,7 @@
7#include <linux/pagemap.h> 7#include <linux/pagemap.h>
8#include <linux/agp_backend.h> 8#include <linux/agp_backend.h>
9#include <linux/delay.h> 9#include <linux/delay.h>
10#include <linux/vmalloc.h>
10#include <asm/uninorth.h> 11#include <asm/uninorth.h>
11#include <asm/pci-bridge.h> 12#include <asm/pci-bridge.h>
12#include <asm/prom.h> 13#include <asm/prom.h>
@@ -27,6 +28,8 @@
27static int uninorth_rev; 28static int uninorth_rev;
28static int is_u3; 29static int is_u3;
29 30
31#define DEFAULT_APERTURE_SIZE 256
32#define DEFAULT_APERTURE_STRING "256"
30static char *aperture = NULL; 33static char *aperture = NULL;
31 34
32static int uninorth_fetch_size(void) 35static int uninorth_fetch_size(void)
@@ -55,7 +58,7 @@ static int uninorth_fetch_size(void)
55 58
56 if (!size) { 59 if (!size) {
57 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) 60 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
58 if (values[i].size == 32) 61 if (values[i].size == DEFAULT_APERTURE_SIZE)
59 break; 62 break;
60 } 63 }
61 64
@@ -179,8 +182,6 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start,
179 } 182 }
180 (void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]); 183 (void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]);
181 mb(); 184 mb();
182 flush_dcache_range((unsigned long)&agp_bridge->gatt_table[pg_start],
183 (unsigned long)&agp_bridge->gatt_table[pg_start + mem->page_count]);
184 185
185 uninorth_tlbflush(mem); 186 uninorth_tlbflush(mem);
186 return 0; 187 return 0;
@@ -224,7 +225,6 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
224 (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000); 225 (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000);
225 } 226 }
226 mb(); 227 mb();
227 flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]);
228 uninorth_tlbflush(mem); 228 uninorth_tlbflush(mem);
229 229
230 return 0; 230 return 0;
@@ -243,7 +243,6 @@ int u3_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
243 for (i = 0; i < mem->page_count; ++i) 243 for (i = 0; i < mem->page_count; ++i)
244 gp[i] = 0; 244 gp[i] = 0;
245 mb(); 245 mb();
246 flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]);
247 uninorth_tlbflush(mem); 246 uninorth_tlbflush(mem);
248 247
249 return 0; 248 return 0;
@@ -396,6 +395,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
396 int i; 395 int i;
397 void *temp; 396 void *temp;
398 struct page *page; 397 struct page *page;
398 struct page **pages;
399 399
400 /* We can't handle 2 level gatt's */ 400 /* We can't handle 2 level gatt's */
401 if (bridge->driver->size_type == LVL2_APER_SIZE) 401 if (bridge->driver->size_type == LVL2_APER_SIZE)
@@ -424,21 +424,39 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
424 if (table == NULL) 424 if (table == NULL)
425 return -ENOMEM; 425 return -ENOMEM;
426 426
427 pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
428 if (pages == NULL)
429 goto enomem;
430
427 table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1); 431 table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
428 432
429 for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) 433 for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
434 page++, i++) {
430 SetPageReserved(page); 435 SetPageReserved(page);
436 pages[i] = page;
437 }
431 438
432 bridge->gatt_table_real = (u32 *) table; 439 bridge->gatt_table_real = (u32 *) table;
433 bridge->gatt_table = (u32 *)table; 440 /* Need to clear out any dirty data still sitting in caches */
441 flush_dcache_range((unsigned long)table,
442 (unsigned long)(table_end + PAGE_SIZE));
443 bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
444
445 if (bridge->gatt_table == NULL)
446 goto enomem;
447
434 bridge->gatt_bus_addr = virt_to_phys(table); 448 bridge->gatt_bus_addr = virt_to_phys(table);
435 449
436 for (i = 0; i < num_entries; i++) 450 for (i = 0; i < num_entries; i++)
437 bridge->gatt_table[i] = 0; 451 bridge->gatt_table[i] = 0;
438 452
439 flush_dcache_range((unsigned long)table, (unsigned long)table_end);
440
441 return 0; 453 return 0;
454
455enomem:
456 kfree(pages);
457 if (table)
458 free_pages((unsigned long)table, page_order);
459 return -ENOMEM;
442} 460}
443 461
444static int uninorth_free_gatt_table(struct agp_bridge_data *bridge) 462static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
@@ -456,6 +474,7 @@ static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
456 * from the table. 474 * from the table.
457 */ 475 */
458 476
477 vunmap(bridge->gatt_table);
459 table = (char *) bridge->gatt_table_real; 478 table = (char *) bridge->gatt_table_real;
460 table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1); 479 table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
461 480
@@ -474,13 +493,11 @@ void null_cache_flush(void)
474 493
475/* Setup function */ 494/* Setup function */
476 495
477static const struct aper_size_info_32 uninorth_sizes[7] = 496static const struct aper_size_info_32 uninorth_sizes[] =
478{ 497{
479#if 0 /* Not sure uninorth supports that high aperture sizes */
480 {256, 65536, 6, 64}, 498 {256, 65536, 6, 64},
481 {128, 32768, 5, 32}, 499 {128, 32768, 5, 32},
482 {64, 16384, 4, 16}, 500 {64, 16384, 4, 16},
483#endif
484 {32, 8192, 3, 8}, 501 {32, 8192, 3, 8},
485 {16, 4096, 2, 4}, 502 {16, 4096, 2, 4},
486 {8, 2048, 1, 2}, 503 {8, 2048, 1, 2},
@@ -491,7 +508,7 @@ static const struct aper_size_info_32 uninorth_sizes[7] =
491 * Not sure that u3 supports that high aperture sizes but it 508 * Not sure that u3 supports that high aperture sizes but it
492 * would strange if it did not :) 509 * would strange if it did not :)
493 */ 510 */
494static const struct aper_size_info_32 u3_sizes[8] = 511static const struct aper_size_info_32 u3_sizes[] =
495{ 512{
496 {512, 131072, 7, 128}, 513 {512, 131072, 7, 128},
497 {256, 65536, 6, 64}, 514 {256, 65536, 6, 64},
@@ -507,7 +524,7 @@ const struct agp_bridge_driver uninorth_agp_driver = {
507 .owner = THIS_MODULE, 524 .owner = THIS_MODULE,
508 .aperture_sizes = (void *)uninorth_sizes, 525 .aperture_sizes = (void *)uninorth_sizes,
509 .size_type = U32_APER_SIZE, 526 .size_type = U32_APER_SIZE,
510 .num_aperture_sizes = 4, 527 .num_aperture_sizes = ARRAY_SIZE(uninorth_sizes),
511 .configure = uninorth_configure, 528 .configure = uninorth_configure,
512 .fetch_size = uninorth_fetch_size, 529 .fetch_size = uninorth_fetch_size,
513 .cleanup = uninorth_cleanup, 530 .cleanup = uninorth_cleanup,
@@ -534,7 +551,7 @@ const struct agp_bridge_driver u3_agp_driver = {
534 .owner = THIS_MODULE, 551 .owner = THIS_MODULE,
535 .aperture_sizes = (void *)u3_sizes, 552 .aperture_sizes = (void *)u3_sizes,
536 .size_type = U32_APER_SIZE, 553 .size_type = U32_APER_SIZE,
537 .num_aperture_sizes = 8, 554 .num_aperture_sizes = ARRAY_SIZE(u3_sizes),
538 .configure = uninorth_configure, 555 .configure = uninorth_configure,
539 .fetch_size = uninorth_fetch_size, 556 .fetch_size = uninorth_fetch_size,
540 .cleanup = uninorth_cleanup, 557 .cleanup = uninorth_cleanup,
@@ -717,7 +734,7 @@ module_param(aperture, charp, 0);
717MODULE_PARM_DESC(aperture, 734MODULE_PARM_DESC(aperture,
718 "Aperture size, must be power of two between 4MB and an\n" 735 "Aperture size, must be power of two between 4MB and an\n"
719 "\t\tupper limit specific to the UniNorth revision.\n" 736 "\t\tupper limit specific to the UniNorth revision.\n"
720 "\t\tDefault: 32M"); 737 "\t\tDefault: " DEFAULT_APERTURE_STRING "M");
721 738
722MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras"); 739MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
723MODULE_LICENSE("GPL"); 740MODULE_LICENSE("GPL");