10 #include <linux/module.h>
11 #include <linux/pci.h>
13 #include <linux/string.h>
14 #include <linux/slab.h>
20 #define INTEL_I460_BAPBASE 0x98
21 #define INTEL_I460_GXBCTL 0xa0
22 #define INTEL_I460_AGPSIZ 0xa2
23 #define INTEL_I460_ATTBASE 0xfe200000
24 #define INTEL_I460_GATT_VALID (1UL << 24)
25 #define INTEL_I460_GATT_COHERENT (1UL << 25)
32 #define I460_LARGE_IO_PAGES 0
34 #if I460_LARGE_IO_PAGES
35 # define I460_IO_PAGE_SHIFT i460.io_page_shift
37 # define I460_IO_PAGE_SHIFT 12
40 #define I460_IOPAGES_PER_KPAGE (PAGE_SIZE >> I460_IO_PAGE_SHIFT)
41 #define I460_KPAGES_PER_IOPAGE (1 << (I460_IO_PAGE_SHIFT - PAGE_SHIFT))
42 #define I460_SRAM_IO_DISABLE (1 << 4)
43 #define I460_BAPBASE_ENABLE (1 << 3)
44 #define I460_AGPSIZ_MASK 0x7
45 #define I460_4M_PS (1 << 1)
48 #define I460_GXBCTL_OOG (1UL << 0)
49 #define I460_GXBCTL_BWC (1UL << 2)
55 #define RD_GATT(index) readl((u32 *) i460.gatt + (index))
56 #define WR_GATT(index, val) writel((val), (u32 *) i460.gatt + (index))
61 #define WR_FLUSH_GATT(index) RD_GATT(index)
104 static int i460_fetch_size (
void)
112 i460.io_page_shift = (temp &
I460_4M_PS) ? 22 : 12;
113 pr_debug(
"i460_fetch_size: io_page_shift=%d\n", i460.io_page_shift);
117 "I/O (GART) page-size %luKB doesn't match expected "
119 1
UL << (i460.io_page_shift - 10),
147 for (i = 0; i <
agp_bridge->driver->num_aperture_sizes; i++) {
157 for (i = 0; i <
agp_bridge->driver->num_aperture_sizes; i++) {
159 if ((temp & I460_AGPSIZ_MASK) == values[i].
size_value) {
162 return values[
i].
size;
185 ((temp & ~I460_AGPSIZ_MASK) | size_value));
188 static void i460_cleanup (
void)
199 static int i460_configure (
void)
219 pci_read_config_dword(
agp_bridge->dev, i460.dynamic_apbase, &(temp.small[0]));
220 pci_read_config_dword(
agp_bridge->dev, i460.dynamic_apbase + 4, &(temp.small[1]));
223 agp_bridge->gart_bus_addr = temp.large & ~((1
UL << 3) - 1);
234 size = current_size->
num_entries *
sizeof(i460.lp_desc[0]);
251 page_order =
A_SIZE_8(temp)->page_order;
252 num_entries =
A_SIZE_8(temp)->num_entries;
278 num_entries =
A_SIZE_8(temp)->num_entries;
293 static int i460_insert_memory_small_io_page (
struct agp_memory *
mem,
296 unsigned long paddr, io_pg_start, io_page_size;
300 pr_debug(
"i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n",
309 num_entries =
A_SIZE_8(temp)->num_entries;
319 pr_debug(
"i460_insert_memory_small_io_page: GATT[%d]=0x%x is busy\n",
327 for (i = 0, j = io_pg_start; i < mem->
page_count; i++) {
336 static int i460_remove_memory_small_io_page(
struct agp_memory *mem,
337 off_t pg_start,
int type)
341 pr_debug(
"i460_remove_memory_small_io_page(mem=%p, pg_start=%ld, type=%d)\n",
342 mem, pg_start, type);
344 pg_start = I460_IOPAGES_PER_KPAGE * pg_start;
346 for (i = pg_start; i < (pg_start + I460_IOPAGES_PER_KPAGE * mem->
page_count); i++)
352 #if I460_LARGE_IO_PAGES
366 static int i460_alloc_large_page (
struct lp_desc *
lp)
378 lp->alloced_map = kzalloc(map_size,
GFP_KERNEL);
379 if (!lp->alloced_map) {
391 static void i460_free_large_page (
struct lp_desc *lp)
393 kfree(lp->alloced_map);
394 lp->alloced_map =
NULL;
396 __free_pages(lp->page, I460_IO_PAGE_SHIFT - PAGE_SHIFT);
400 static int i460_insert_memory_large_io_page (
struct agp_memory *mem,
401 off_t pg_start,
int type)
411 num_entries =
A_SIZE_8(temp)->num_entries;
419 if (end > i460.lp_desc + num_entries) {
425 for (lp = start; lp <=
end; ++lp) {
426 if (!lp->alloced_map)
429 for (idx = ((lp == start) ? start_offset : 0);
438 for (lp = start, i = 0; lp <=
end; ++lp) {
439 if (!lp->alloced_map) {
441 if (i460_alloc_large_page(lp) < 0)
443 pg = lp - i460.lp_desc;
449 for (idx = ((lp == start) ? start_offset : 0);
461 static int i460_remove_memory_large_io_page (
struct agp_memory *mem,
462 off_t pg_start,
int type)
469 num_entries =
A_SIZE_8(temp)->num_entries;
477 for (i = 0, lp = start; lp <=
end; ++lp) {
478 for (idx = ((lp == start) ? start_offset : 0);
488 if (lp->refcount == 0) {
489 pg = lp - i460.lp_desc;
492 i460_free_large_page(lp);
500 static int i460_insert_memory (
struct agp_memory *mem,
501 off_t pg_start,
int type)
503 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
504 return i460_insert_memory_small_io_page(mem, pg_start, type);
506 return i460_insert_memory_large_io_page(mem, pg_start, type);
509 static int i460_remove_memory (
struct agp_memory *mem,
510 off_t pg_start,
int type)
512 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
513 return i460_remove_memory_small_io_page(mem, pg_start, type);
515 return i460_remove_memory_large_io_page(mem, pg_start, type);
530 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
539 static void i460_destroy_page (
struct page *page,
int flags)
541 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
552 return bridge->
driver->masks[0].mask
558 .aperture_sizes = i460_sizes,
560 .num_aperture_sizes = 3,
561 .configure = i460_configure,
562 .fetch_size = i460_fetch_size,
563 .cleanup = i460_cleanup,
564 .tlb_flush = i460_tlb_flush,
565 .mask_memory = i460_mask_memory,
569 .create_gatt_table = i460_create_gatt_table,
570 .free_gatt_table = i460_free_gatt_table,
571 #if I460_LARGE_IO_PAGES
572 .insert_memory = i460_insert_memory,
573 .remove_memory = i460_remove_memory,
574 .agp_alloc_page = i460_alloc_page,
575 .agp_destroy_page = i460_destroy_page,
577 .insert_memory = i460_insert_memory_small_io_page,
578 .remove_memory = i460_remove_memory_small_io_page,
587 .cant_use_aperture =
true,
610 pci_set_drvdata(pdev, bridge);
636 static struct pci_driver agp_intel_i460_pci_driver = {
637 .name =
"agpgart-intel-i460",
638 .id_table = agp_intel_i460_pci_table,
639 .probe = agp_intel_i460_probe,
643 static int __init agp_intel_i460_init(
void)
647 return pci_register_driver(&agp_intel_i460_pci_driver);
650 static void __exit agp_intel_i460_cleanup(
void)