diff options
author | Jerome Glisse <jglisse@redhat.com> | 2010-04-20 11:43:34 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-22 23:59:18 -0400 |
commit | 61cf059325a30995a78c5001db2ed2a8ab1d4c36 (patch) | |
tree | 0c674f3252032a780e9496c466c7fce2c1b084e0 | |
parent | 2d2ef822758e3f5da59c40a392d0c6d89394d4b4 (diff) |
agp: use scratch page on memory remove and at GATT creation V4
Convert most AGP chipset to use scratch page as default entries.
This help avoiding GPU querying 0 address and trigger computer
fault. With KMS and memory manager we bind/unbind AGP memory
constantly and it seems that some GPU are still doing AGP
traffic even after GPU report being idle with the memory segment.
Tested (radeon GPU KMS + Xorg + compiz + glxgears + quake3) on :
- SIS 1039:0001 & 1039:0003
- Intel 865 8086:2571
Compile tested for other bridges
V2 enable scratch page on uninorth
V3 fix unbound check in uninorth insert memory (Michel Dänzer)
V4 rebase on top of drm-next branch with the lastest intel AGP
changeset (stable should use version V3 of the patch)
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Michel Dänzer <michel@daenzer.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/char/agp/ali-agp.c | 1 | ||||
-rw-r--r-- | drivers/char/agp/amd-k7-agp.c | 9 | ||||
-rw-r--r-- | drivers/char/agp/amd64-agp.c | 1 | ||||
-rw-r--r-- | drivers/char/agp/ati-agp.c | 8 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 9 | ||||
-rw-r--r-- | drivers/char/agp/nvidia-agp.c | 1 | ||||
-rw-r--r-- | drivers/char/agp/sis-agp.c | 1 | ||||
-rw-r--r-- | drivers/char/agp/uninorth-agp.c | 16 | ||||
-rw-r--r-- | drivers/char/agp/via-agp.c | 2 |
9 files changed, 44 insertions, 4 deletions
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index d2ce68f27e4b..fd793519ea2b 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -204,6 +204,7 @@ static const struct agp_bridge_driver ali_generic_bridge = { | |||
204 | .aperture_sizes = ali_generic_sizes, | 204 | .aperture_sizes = ali_generic_sizes, |
205 | .size_type = U32_APER_SIZE, | 205 | .size_type = U32_APER_SIZE, |
206 | .num_aperture_sizes = 7, | 206 | .num_aperture_sizes = 7, |
207 | .needs_scratch_page = true, | ||
207 | .configure = ali_configure, | 208 | .configure = ali_configure, |
208 | .fetch_size = ali_fetch_size, | 209 | .fetch_size = ali_fetch_size, |
209 | .cleanup = ali_cleanup, | 210 | .cleanup = ali_cleanup, |
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index a7637d72cef6..b6b1568314c8 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -142,6 +142,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) | |||
142 | { | 142 | { |
143 | struct aper_size_info_lvl2 *value; | 143 | struct aper_size_info_lvl2 *value; |
144 | struct amd_page_map page_dir; | 144 | struct amd_page_map page_dir; |
145 | unsigned long __iomem *cur_gatt; | ||
145 | unsigned long addr; | 146 | unsigned long addr; |
146 | int retval; | 147 | int retval; |
147 | u32 temp; | 148 | u32 temp; |
@@ -178,6 +179,13 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) | |||
178 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ | 179 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ |
179 | } | 180 | } |
180 | 181 | ||
182 | for (i = 0; i < value->num_entries; i++) { | ||
183 | addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; | ||
184 | cur_gatt = GET_GATT(addr); | ||
185 | writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr)); | ||
186 | readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ | ||
187 | } | ||
188 | |||
181 | return 0; | 189 | return 0; |
182 | } | 190 | } |
183 | 191 | ||
@@ -375,6 +383,7 @@ static const struct agp_bridge_driver amd_irongate_driver = { | |||
375 | .aperture_sizes = amd_irongate_sizes, | 383 | .aperture_sizes = amd_irongate_sizes, |
376 | .size_type = LVL2_APER_SIZE, | 384 | .size_type = LVL2_APER_SIZE, |
377 | .num_aperture_sizes = 7, | 385 | .num_aperture_sizes = 7, |
386 | .needs_scratch_page = true, | ||
378 | .configure = amd_irongate_configure, | 387 | .configure = amd_irongate_configure, |
379 | .fetch_size = amd_irongate_fetch_size, | 388 | .fetch_size = amd_irongate_fetch_size, |
380 | .cleanup = amd_irongate_cleanup, | 389 | .cleanup = amd_irongate_cleanup, |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index fd50ead59c79..73703b115cd2 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -210,6 +210,7 @@ static const struct agp_bridge_driver amd_8151_driver = { | |||
210 | .aperture_sizes = amd_8151_sizes, | 210 | .aperture_sizes = amd_8151_sizes, |
211 | .size_type = U32_APER_SIZE, | 211 | .size_type = U32_APER_SIZE, |
212 | .num_aperture_sizes = 7, | 212 | .num_aperture_sizes = 7, |
213 | .needs_scratch_page = true, | ||
213 | .configure = amd_8151_configure, | 214 | .configure = amd_8151_configure, |
214 | .fetch_size = amd64_fetch_size, | 215 | .fetch_size = amd64_fetch_size, |
215 | .cleanup = amd64_cleanup, | 216 | .cleanup = amd64_cleanup, |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 3b2ecbe86ebe..dc30e2243494 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -341,6 +341,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) | |||
341 | { | 341 | { |
342 | struct aper_size_info_lvl2 *value; | 342 | struct aper_size_info_lvl2 *value; |
343 | struct ati_page_map page_dir; | 343 | struct ati_page_map page_dir; |
344 | unsigned long __iomem *cur_gatt; | ||
344 | unsigned long addr; | 345 | unsigned long addr; |
345 | int retval; | 346 | int retval; |
346 | u32 temp; | 347 | u32 temp; |
@@ -395,6 +396,12 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) | |||
395 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ | 396 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ |
396 | } | 397 | } |
397 | 398 | ||
399 | for (i = 0; i < value->num_entries; i++) { | ||
400 | addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; | ||
401 | cur_gatt = GET_GATT(addr); | ||
402 | writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr)); | ||
403 | } | ||
404 | |||
398 | return 0; | 405 | return 0; |
399 | } | 406 | } |
400 | 407 | ||
@@ -415,6 +422,7 @@ static const struct agp_bridge_driver ati_generic_bridge = { | |||
415 | .aperture_sizes = ati_generic_sizes, | 422 | .aperture_sizes = ati_generic_sizes, |
416 | .size_type = LVL2_APER_SIZE, | 423 | .size_type = LVL2_APER_SIZE, |
417 | .num_aperture_sizes = 7, | 424 | .num_aperture_sizes = 7, |
425 | .needs_scratch_page = true, | ||
418 | .configure = ati_configure, | 426 | .configure = ati_configure, |
419 | .fetch_size = ati_fetch_size, | 427 | .fetch_size = ati_fetch_size, |
420 | .cleanup = ati_cleanup, | 428 | .cleanup = ati_cleanup, |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 034644eeedf2..d836a71bf06d 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -464,6 +464,7 @@ static const struct agp_bridge_driver intel_generic_driver = { | |||
464 | .aperture_sizes = intel_generic_sizes, | 464 | .aperture_sizes = intel_generic_sizes, |
465 | .size_type = U16_APER_SIZE, | 465 | .size_type = U16_APER_SIZE, |
466 | .num_aperture_sizes = 7, | 466 | .num_aperture_sizes = 7, |
467 | .needs_scratch_page = true, | ||
467 | .configure = intel_configure, | 468 | .configure = intel_configure, |
468 | .fetch_size = intel_fetch_size, | 469 | .fetch_size = intel_fetch_size, |
469 | .cleanup = intel_cleanup, | 470 | .cleanup = intel_cleanup, |
@@ -490,6 +491,7 @@ static const struct agp_bridge_driver intel_815_driver = { | |||
490 | .aperture_sizes = intel_815_sizes, | 491 | .aperture_sizes = intel_815_sizes, |
491 | .size_type = U8_APER_SIZE, | 492 | .size_type = U8_APER_SIZE, |
492 | .num_aperture_sizes = 2, | 493 | .num_aperture_sizes = 2, |
494 | .needs_scratch_page = true, | ||
493 | .configure = intel_815_configure, | 495 | .configure = intel_815_configure, |
494 | .fetch_size = intel_815_fetch_size, | 496 | .fetch_size = intel_815_fetch_size, |
495 | .cleanup = intel_8xx_cleanup, | 497 | .cleanup = intel_8xx_cleanup, |
@@ -516,6 +518,7 @@ static const struct agp_bridge_driver intel_820_driver = { | |||
516 | .aperture_sizes = intel_8xx_sizes, | 518 | .aperture_sizes = intel_8xx_sizes, |
517 | .size_type = U8_APER_SIZE, | 519 | .size_type = U8_APER_SIZE, |
518 | .num_aperture_sizes = 7, | 520 | .num_aperture_sizes = 7, |
521 | .needs_scratch_page = true, | ||
519 | .configure = intel_820_configure, | 522 | .configure = intel_820_configure, |
520 | .fetch_size = intel_8xx_fetch_size, | 523 | .fetch_size = intel_8xx_fetch_size, |
521 | .cleanup = intel_820_cleanup, | 524 | .cleanup = intel_820_cleanup, |
@@ -542,6 +545,7 @@ static const struct agp_bridge_driver intel_830mp_driver = { | |||
542 | .aperture_sizes = intel_830mp_sizes, | 545 | .aperture_sizes = intel_830mp_sizes, |
543 | .size_type = U8_APER_SIZE, | 546 | .size_type = U8_APER_SIZE, |
544 | .num_aperture_sizes = 4, | 547 | .num_aperture_sizes = 4, |
548 | .needs_scratch_page = true, | ||
545 | .configure = intel_830mp_configure, | 549 | .configure = intel_830mp_configure, |
546 | .fetch_size = intel_8xx_fetch_size, | 550 | .fetch_size = intel_8xx_fetch_size, |
547 | .cleanup = intel_8xx_cleanup, | 551 | .cleanup = intel_8xx_cleanup, |
@@ -568,6 +572,7 @@ static const struct agp_bridge_driver intel_840_driver = { | |||
568 | .aperture_sizes = intel_8xx_sizes, | 572 | .aperture_sizes = intel_8xx_sizes, |
569 | .size_type = U8_APER_SIZE, | 573 | .size_type = U8_APER_SIZE, |
570 | .num_aperture_sizes = 7, | 574 | .num_aperture_sizes = 7, |
575 | .needs_scratch_page = true, | ||
571 | .configure = intel_840_configure, | 576 | .configure = intel_840_configure, |
572 | .fetch_size = intel_8xx_fetch_size, | 577 | .fetch_size = intel_8xx_fetch_size, |
573 | .cleanup = intel_8xx_cleanup, | 578 | .cleanup = intel_8xx_cleanup, |
@@ -594,6 +599,7 @@ static const struct agp_bridge_driver intel_845_driver = { | |||
594 | .aperture_sizes = intel_8xx_sizes, | 599 | .aperture_sizes = intel_8xx_sizes, |
595 | .size_type = U8_APER_SIZE, | 600 | .size_type = U8_APER_SIZE, |
596 | .num_aperture_sizes = 7, | 601 | .num_aperture_sizes = 7, |
602 | .needs_scratch_page = true, | ||
597 | .configure = intel_845_configure, | 603 | .configure = intel_845_configure, |
598 | .fetch_size = intel_8xx_fetch_size, | 604 | .fetch_size = intel_8xx_fetch_size, |
599 | .cleanup = intel_8xx_cleanup, | 605 | .cleanup = intel_8xx_cleanup, |
@@ -620,6 +626,7 @@ static const struct agp_bridge_driver intel_850_driver = { | |||
620 | .aperture_sizes = intel_8xx_sizes, | 626 | .aperture_sizes = intel_8xx_sizes, |
621 | .size_type = U8_APER_SIZE, | 627 | .size_type = U8_APER_SIZE, |
622 | .num_aperture_sizes = 7, | 628 | .num_aperture_sizes = 7, |
629 | .needs_scratch_page = true, | ||
623 | .configure = intel_850_configure, | 630 | .configure = intel_850_configure, |
624 | .fetch_size = intel_8xx_fetch_size, | 631 | .fetch_size = intel_8xx_fetch_size, |
625 | .cleanup = intel_8xx_cleanup, | 632 | .cleanup = intel_8xx_cleanup, |
@@ -646,6 +653,7 @@ static const struct agp_bridge_driver intel_860_driver = { | |||
646 | .aperture_sizes = intel_8xx_sizes, | 653 | .aperture_sizes = intel_8xx_sizes, |
647 | .size_type = U8_APER_SIZE, | 654 | .size_type = U8_APER_SIZE, |
648 | .num_aperture_sizes = 7, | 655 | .num_aperture_sizes = 7, |
656 | .needs_scratch_page = true, | ||
649 | .configure = intel_860_configure, | 657 | .configure = intel_860_configure, |
650 | .fetch_size = intel_8xx_fetch_size, | 658 | .fetch_size = intel_8xx_fetch_size, |
651 | .cleanup = intel_8xx_cleanup, | 659 | .cleanup = intel_8xx_cleanup, |
@@ -672,6 +680,7 @@ static const struct agp_bridge_driver intel_7505_driver = { | |||
672 | .aperture_sizes = intel_8xx_sizes, | 680 | .aperture_sizes = intel_8xx_sizes, |
673 | .size_type = U8_APER_SIZE, | 681 | .size_type = U8_APER_SIZE, |
674 | .num_aperture_sizes = 7, | 682 | .num_aperture_sizes = 7, |
683 | .needs_scratch_page = true, | ||
675 | .configure = intel_7505_configure, | 684 | .configure = intel_7505_configure, |
676 | .fetch_size = intel_8xx_fetch_size, | 685 | .fetch_size = intel_8xx_fetch_size, |
677 | .cleanup = intel_8xx_cleanup, | 686 | .cleanup = intel_8xx_cleanup, |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 10f24e349a26..b9734a978186 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -310,6 +310,7 @@ static const struct agp_bridge_driver nvidia_driver = { | |||
310 | .aperture_sizes = nvidia_generic_sizes, | 310 | .aperture_sizes = nvidia_generic_sizes, |
311 | .size_type = U8_APER_SIZE, | 311 | .size_type = U8_APER_SIZE, |
312 | .num_aperture_sizes = 5, | 312 | .num_aperture_sizes = 5, |
313 | .needs_scratch_page = true, | ||
313 | .configure = nvidia_configure, | 314 | .configure = nvidia_configure, |
314 | .fetch_size = nvidia_fetch_size, | 315 | .fetch_size = nvidia_fetch_size, |
315 | .cleanup = nvidia_cleanup, | 316 | .cleanup = nvidia_cleanup, |
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 6c3837a0184d..b53d5f4e9cb2 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c | |||
@@ -125,6 +125,7 @@ static struct agp_bridge_driver sis_driver = { | |||
125 | .aperture_sizes = sis_generic_sizes, | 125 | .aperture_sizes = sis_generic_sizes, |
126 | .size_type = U8_APER_SIZE, | 126 | .size_type = U8_APER_SIZE, |
127 | .num_aperture_sizes = 7, | 127 | .num_aperture_sizes = 7, |
128 | .needs_scratch_page = true, | ||
128 | .configure = sis_configure, | 129 | .configure = sis_configure, |
129 | .fetch_size = sis_fetch_size, | 130 | .fetch_size = sis_fetch_size, |
130 | .cleanup = sis_cleanup, | 131 | .cleanup = sis_cleanup, |
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 6f48931ac1ce..95db71360d24 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
@@ -28,6 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | static int uninorth_rev; | 29 | static int uninorth_rev; |
30 | static int is_u3; | 30 | static int is_u3; |
31 | static u32 scratch_value; | ||
31 | 32 | ||
32 | #define DEFAULT_APERTURE_SIZE 256 | 33 | #define DEFAULT_APERTURE_SIZE 256 |
33 | #define DEFAULT_APERTURE_STRING "256" | 34 | #define DEFAULT_APERTURE_STRING "256" |
@@ -172,7 +173,7 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, int ty | |||
172 | 173 | ||
173 | gp = (u32 *) &agp_bridge->gatt_table[pg_start]; | 174 | gp = (u32 *) &agp_bridge->gatt_table[pg_start]; |
174 | for (i = 0; i < mem->page_count; ++i) { | 175 | for (i = 0; i < mem->page_count; ++i) { |
175 | if (gp[i]) { | 176 | if (gp[i] != scratch_value) { |
176 | dev_info(&agp_bridge->dev->dev, | 177 | dev_info(&agp_bridge->dev->dev, |
177 | "uninorth_insert_memory: entry 0x%x occupied (%x)\n", | 178 | "uninorth_insert_memory: entry 0x%x occupied (%x)\n", |
178 | i, gp[i]); | 179 | i, gp[i]); |
@@ -214,8 +215,9 @@ int uninorth_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
214 | return 0; | 215 | return 0; |
215 | 216 | ||
216 | gp = (u32 *) &agp_bridge->gatt_table[pg_start]; | 217 | gp = (u32 *) &agp_bridge->gatt_table[pg_start]; |
217 | for (i = 0; i < mem->page_count; ++i) | 218 | for (i = 0; i < mem->page_count; ++i) { |
218 | gp[i] = 0; | 219 | gp[i] = scratch_value; |
220 | } | ||
219 | mb(); | 221 | mb(); |
220 | uninorth_tlbflush(mem); | 222 | uninorth_tlbflush(mem); |
221 | 223 | ||
@@ -421,8 +423,13 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) | |||
421 | 423 | ||
422 | bridge->gatt_bus_addr = virt_to_phys(table); | 424 | bridge->gatt_bus_addr = virt_to_phys(table); |
423 | 425 | ||
426 | if (is_u3) | ||
427 | scratch_value = (page_to_phys(agp_bridge->scratch_page_page) >> PAGE_SHIFT) | 0x80000000UL; | ||
428 | else | ||
429 | scratch_value = cpu_to_le32((page_to_phys(agp_bridge->scratch_page_page) & 0xFFFFF000UL) | | ||
430 | 0x1UL); | ||
424 | for (i = 0; i < num_entries; i++) | 431 | for (i = 0; i < num_entries; i++) |
425 | bridge->gatt_table[i] = 0; | 432 | bridge->gatt_table[i] = scratch_value; |
426 | 433 | ||
427 | return 0; | 434 | return 0; |
428 | 435 | ||
@@ -519,6 +526,7 @@ const struct agp_bridge_driver uninorth_agp_driver = { | |||
519 | .agp_destroy_pages = agp_generic_destroy_pages, | 526 | .agp_destroy_pages = agp_generic_destroy_pages, |
520 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 527 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
521 | .cant_use_aperture = true, | 528 | .cant_use_aperture = true, |
529 | .needs_scratch_page = true, | ||
522 | }; | 530 | }; |
523 | 531 | ||
524 | const struct agp_bridge_driver u3_agp_driver = { | 532 | const struct agp_bridge_driver u3_agp_driver = { |
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index d3bd243867fc..df67e80019d2 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c | |||
@@ -175,6 +175,7 @@ static const struct agp_bridge_driver via_agp3_driver = { | |||
175 | .aperture_sizes = agp3_generic_sizes, | 175 | .aperture_sizes = agp3_generic_sizes, |
176 | .size_type = U8_APER_SIZE, | 176 | .size_type = U8_APER_SIZE, |
177 | .num_aperture_sizes = 10, | 177 | .num_aperture_sizes = 10, |
178 | .needs_scratch_page = true, | ||
178 | .configure = via_configure_agp3, | 179 | .configure = via_configure_agp3, |
179 | .fetch_size = via_fetch_size_agp3, | 180 | .fetch_size = via_fetch_size_agp3, |
180 | .cleanup = via_cleanup_agp3, | 181 | .cleanup = via_cleanup_agp3, |
@@ -201,6 +202,7 @@ static const struct agp_bridge_driver via_driver = { | |||
201 | .aperture_sizes = via_generic_sizes, | 202 | .aperture_sizes = via_generic_sizes, |
202 | .size_type = U8_APER_SIZE, | 203 | .size_type = U8_APER_SIZE, |
203 | .num_aperture_sizes = 9, | 204 | .num_aperture_sizes = 9, |
205 | .needs_scratch_page = true, | ||
204 | .configure = via_configure, | 206 | .configure = via_configure, |
205 | .fetch_size = via_fetch_size, | 207 | .fetch_size = via_fetch_size, |
206 | .cleanup = via_cleanup, | 208 | .cleanup = via_cleanup, |