4 #include <linux/module.h>
6 #include <linux/slab.h>
13 #include <asm/pci-bridge.h>
29 static int uninorth_rev;
31 static u32 scratch_value;
33 #define DEFAULT_APERTURE_SIZE 256
34 #define DEFAULT_APERTURE_STRING "256"
35 static char *aperture =
NULL;
37 static int uninorth_fetch_size(
void)
44 char *save = aperture;
46 size =
memparse(aperture, &aperture) >> 20;
49 for (i = 0; i <
agp_bridge->driver->num_aperture_sizes; i++)
50 if (size == values[i].size)
53 if (i ==
agp_bridge->driver->num_aperture_sizes) {
62 for (i = 0; i <
agp_bridge->driver->num_aperture_sizes; i++)
68 agp_bridge->current_size = (
void *)(values + i);
70 return values[
i].
size;
75 u32 ctrl = UNI_N_CFG_GART_ENABLE;
78 ctrl |= U3_N_CFG_GART_PERFRD;
79 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL,
80 ctrl | UNI_N_CFG_GART_INVAL);
81 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL, ctrl);
83 if (!mem && uninorth_rev <= 0x30) {
84 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL,
85 ctrl | UNI_N_CFG_GART_2xRESET);
86 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL,
91 static void uninorth_cleanup(
void)
95 pci_read_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL, &tmp);
96 if (!(tmp & UNI_N_CFG_GART_ENABLE))
98 tmp |= UNI_N_CFG_GART_INVAL;
99 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL, tmp);
100 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL, 0);
102 if (uninorth_rev <= 0x30) {
103 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL,
104 UNI_N_CFG_GART_2xRESET);
105 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_GART_CTRL,
110 static int uninorth_configure(
void)
133 pci_write_config_dword(
agp_bridge->dev, UNI_N_CFG_AGP_BASE,
137 UNI_N_CFG_AGP_BASE,
agp_bridge->gart_bus_addr);
142 UNI_N_CFG_GART_DUMMY_PAGE,
156 if (type != mem->
type)
160 if (mask_type != 0) {
169 num_entries =
A_SIZE_32(temp)->num_entries;
171 if ((pg_start + mem->
page_count) > num_entries)
176 if (gp[i] != scratch_value) {
178 "uninorth_insert_memory: entry 0x%x occupied (%x)\n",
194 uninorth_tlbflush(mem);
205 if (type != mem->
type)
209 if (mask_type != 0) {
219 gp[
i] = scratch_value;
222 uninorth_tlbflush(mem);
232 pci_read_config_dword(bridge->
dev,
239 if (uninorth_rev == 0x21) {
247 if ((uninorth_rev >= 0x30) && (uninorth_rev <= 0x33)) {
257 uninorth_tlbflush(
NULL);
261 pci_write_config_dword(bridge->
dev,
264 pci_read_config_dword(bridge->
dev,
268 if ((scratch & PCI_AGP_COMMAND_AGP) == 0)
269 dev_err(&bridge->
dev->dev,
"can't write UniNorth AGP "
270 "command register\n");
272 if (uninorth_rev >= 0x30) {
280 uninorth_tlbflush(
NULL);
289 static int agp_uninorth_suspend(
struct pci_dev *pdev)
315 if (device->
bus != pdev->
bus)
321 if (!(cmd & PCI_AGP_COMMAND_AGP))
323 dev_info(&pdev->
dev,
"disabling AGP on device %s\n",
325 cmd &= ~PCI_AGP_COMMAND_AGP;
333 if (cmd & PCI_AGP_COMMAND_AGP) {
335 cmd &= ~PCI_AGP_COMMAND_AGP;
344 static int agp_uninorth_resume(
struct pci_dev *pdev)
355 if (!(command & PCI_AGP_COMMAND_AGP))
358 uninorth_agp_enable(bridge, command);
383 size = page_order = num_entries = 0;
387 page_order =
A_SIZE_32(temp)->page_order;
388 num_entries =
A_SIZE_32(temp)->num_entries;
398 }
while (!table && (i < bridge->
driver->num_aperture_sizes));
407 table_end = table + ((
PAGE_SIZE * (1 << page_order)) - 1);
411 SetPageReserved(page);
418 (
unsigned long)table_end + 1);
446 char *
table, *table_end;
451 page_order =
A_SIZE_32(temp)->page_order;
460 table_end = table + ((
PAGE_SIZE * (1 << page_order)) - 1);
463 ClearPageReserved(page);
494 {512, 131072, 7, 128},
506 .aperture_sizes = (
void *)uninorth_sizes,
509 .configure = uninorth_configure,
510 .fetch_size = uninorth_fetch_size,
511 .cleanup = uninorth_cleanup,
512 .tlb_flush = uninorth_tlbflush,
516 .agp_enable = uninorth_agp_enable,
517 .create_gatt_table = uninorth_create_gatt_table,
518 .free_gatt_table = uninorth_free_gatt_table,
519 .insert_memory = uninorth_insert_memory,
528 .cant_use_aperture =
true,
529 .needs_scratch_page =
true,
534 .aperture_sizes = (
void *)u3_sizes,
537 .configure = uninorth_configure,
538 .fetch_size = uninorth_fetch_size,
539 .cleanup = uninorth_cleanup,
540 .tlb_flush = uninorth_tlbflush,
544 .agp_enable = uninorth_agp_enable,
545 .create_gatt_table = uninorth_create_gatt_table,
546 .free_gatt_table = uninorth_free_gatt_table,
547 .insert_memory = uninorth_insert_memory,
556 .cant_use_aperture =
true,
557 .needs_scratch_page =
true,
563 .chipset_name =
"UniNorth",
567 .chipset_name =
"UniNorth/Pangea",
571 .chipset_name =
"UniNorth 1.5",
575 .chipset_name =
"UniNorth 2",
579 .chipset_name =
"U3",
583 .chipset_name =
"U3L",
587 .chipset_name =
"U3H",
591 .chipset_name =
"UniNorth/Intrepid2",
617 dev_err(&pdev->
dev,
"unsupported Apple chipset [%04x/%04x]\n",
628 if (uninorth_node ==
NULL) {
636 uninorth_rev = *revprop & 0x3f;
637 of_node_put(uninorth_node);
662 pci_set_drvdata(pdev, bridge);
693 static struct pci_driver agp_uninorth_pci_driver = {
694 .name =
"agpgart-uninorth",
695 .id_table = agp_uninorth_pci_table,
696 .probe = agp_uninorth_probe,
697 .remove = agp_uninorth_remove,
700 static int __init agp_uninorth_init(
void)
704 return pci_register_driver(&agp_uninorth_pci_driver);
707 static void __exit agp_uninorth_cleanup(
void)
717 "Aperture size, must be power of two between 4MB and an\n"
718 "\t\tupper limit specific to the UniNorth revision.\n"