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)

Signed-off-by: Jerome Glisse <jgli...@redhat.com>
Signed-off-by: Michel Dänzer <mic...@daenzer.net>
Cc: stable <sta...@kernel.org>
---
 drivers/char/agp/ali-agp.c      |    1 +
 drivers/char/agp/amd-k7-agp.c   |    9 +++++++++
 drivers/char/agp/amd64-agp.c    |    1 +
 drivers/char/agp/ati-agp.c      |    8 ++++++++
 drivers/char/agp/intel-agp.c    |   30 +++++++++++++++++++++++++++---
 drivers/char/agp/nvidia-agp.c   |    1 +
 drivers/char/agp/sis-agp.c      |    1 +
 drivers/char/agp/uninorth-agp.c |   16 ++++++++++++----
 drivers/char/agp/via-agp.c      |    2 ++
 9 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index d2ce68f..fd79351 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 = {
        .aperture_sizes         = ali_generic_sizes,
        .size_type              = U32_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = ali_configure,
        .fetch_size             = ali_fetch_size,
        .cleanup                = ali_cleanup,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 73dbf40..cf4dc4c 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)
 {
        struct aper_size_info_lvl2 *value;
        struct amd_page_map page_dir;
+       unsigned long __iomem *cur_gatt;
        unsigned long addr;
        int retval;
        u32 temp;
@@ -178,6 +179,13 @@ static int amd_create_gatt_table(struct agp_bridge_data 
*bridge)
                readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));        /* PCI 
Posting. */
        }
 
+       for (i = 0; i < value->num_entries; i++) {
+               addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
+               cur_gatt = GET_GATT(addr);
+               writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
+               readl(cur_gatt+GET_GATT_OFF(addr));     /* PCI Posting. */
+       }
+
        return 0;
 }
 
@@ -375,6 +383,7 @@ static const struct agp_bridge_driver amd_irongate_driver = 
{
        .aperture_sizes         = amd_irongate_sizes,
        .size_type              = LVL2_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = amd_irongate_configure,
        .fetch_size             = amd_irongate_fetch_size,
        .cleanup                = amd_irongate_cleanup,
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index fd50ead..73703b1 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 = {
        .aperture_sizes         = amd_8151_sizes,
        .size_type              = U32_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = amd_8151_configure,
        .fetch_size             = amd64_fetch_size,
        .cleanup                = amd64_cleanup,
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 3b2ecbe..dc30e22 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)
 {
        struct aper_size_info_lvl2 *value;
        struct ati_page_map page_dir;
+       unsigned long __iomem *cur_gatt;
        unsigned long addr;
        int retval;
        u32 temp;
@@ -395,6 +396,12 @@ static int ati_create_gatt_table(struct agp_bridge_data 
*bridge)
                readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));        /* PCI 
Posting. */
        }
 
+       for (i = 0; i < value->num_entries; i++) {
+               addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
+               cur_gatt = GET_GATT(addr);
+               writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
+       }
+
        return 0;
 }
 
@@ -415,6 +422,7 @@ static const struct agp_bridge_driver ati_generic_bridge = {
        .aperture_sizes         = ati_generic_sizes,
        .size_type              = LVL2_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = ati_configure,
        .fetch_size             = ati_fetch_size,
        .cleanup                = ati_cleanup,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index b78d5c3..aa4c9bd 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -943,7 +943,7 @@ static int intel_i830_create_gatt_table(struct 
agp_bridge_data *bridge)
 {
        int page_order;
        struct aper_size_info_fixed *size;
-       int num_entries;
+       int num_entries, i;
        u32 temp;
 
        size = agp_bridge->current_size;
@@ -968,6 +968,11 @@ static int intel_i830_create_gatt_table(struct 
agp_bridge_data *bridge)
 
        agp_bridge->gatt_bus_addr = temp;
 
+       for (i = 0; i < num_entries; i++) {
+               writel(agp_bridge->scratch_page, 
intel_private.registers+I810_PTE_BASE+(i*4));
+       }
+       readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
+
        return 0;
 }
 
@@ -1385,7 +1390,7 @@ static int intel_i915_create_gatt_table(struct 
agp_bridge_data *bridge)
 {
        int page_order;
        struct aper_size_info_fixed *size;
-       int num_entries;
+       int num_entries, i;
        u32 temp, temp2;
        int gtt_map_size = 256 * 1024;
 
@@ -1423,6 +1428,11 @@ static int intel_i915_create_gatt_table(struct 
agp_bridge_data *bridge)
 
        agp_bridge->gatt_bus_addr = temp;
 
+       for (i = 0; i < num_entries; i++) {
+               writel(agp_bridge->scratch_page, intel_private.gtt+i);
+       }
+       readl(intel_private.gtt+i-1);
+
        return 0;
 }
 
@@ -1493,7 +1503,7 @@ static int intel_i965_create_gatt_table(struct 
agp_bridge_data *bridge)
 {
        int page_order;
        struct aper_size_info_fixed *size;
-       int num_entries;
+       int num_entries, i;
        u32 temp;
        int gtt_offset, gtt_size;
 
@@ -1531,6 +1541,11 @@ static int intel_i965_create_gatt_table(struct 
agp_bridge_data *bridge)
 
        agp_bridge->gatt_bus_addr = temp;
 
+       for (i = 0; i < num_entries; i++) {
+               writel(agp_bridge->scratch_page, intel_private.gtt+i);
+       }
+       readl(intel_private.gtt+i-1);
+
        return 0;
 }
 
@@ -1983,6 +1998,7 @@ static const struct agp_bridge_driver 
intel_generic_driver = {
        .aperture_sizes         = intel_generic_sizes,
        .size_type              = U16_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_configure,
        .fetch_size             = intel_fetch_size,
        .cleanup                = intel_cleanup,
@@ -2036,6 +2052,7 @@ static const struct agp_bridge_driver intel_815_driver = {
        .aperture_sizes         = intel_815_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 2,
+       .needs_scratch_page     = true,
        .configure              = intel_815_configure,
        .fetch_size             = intel_815_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2090,6 +2107,7 @@ static const struct agp_bridge_driver intel_820_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_820_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_820_cleanup,
@@ -2116,6 +2134,7 @@ static const struct agp_bridge_driver intel_830mp_driver 
= {
        .aperture_sizes         = intel_830mp_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 4,
+       .needs_scratch_page     = true,
        .configure              = intel_830mp_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2142,6 +2161,7 @@ static const struct agp_bridge_driver intel_840_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_840_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2168,6 +2188,7 @@ static const struct agp_bridge_driver intel_845_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_845_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2195,6 +2216,7 @@ static const struct agp_bridge_driver intel_850_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_850_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2221,6 +2243,7 @@ static const struct agp_bridge_driver intel_860_driver = {
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_860_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
@@ -2315,6 +2338,7 @@ static const struct agp_bridge_driver intel_7505_driver = 
{
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = intel_7505_configure,
        .fetch_size             = intel_8xx_fetch_size,
        .cleanup                = intel_8xx_cleanup,
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 7e36d2b..ae92cac 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -311,6 +311,7 @@ static const struct agp_bridge_driver nvidia_driver = {
        .aperture_sizes         = nvidia_generic_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 5,
+       .needs_scratch_page     = true,
        .configure              = nvidia_configure,
        .fetch_size             = nvidia_fetch_size,
        .cleanup                = nvidia_cleanup,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 6c3837a..b53d5f4 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 = {
        .aperture_sizes         = sis_generic_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 7,
+       .needs_scratch_page     = true,
        .configure              = sis_configure,
        .fetch_size             = sis_fetch_size,
        .cleanup                = sis_cleanup,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index d89da4a..9b26341 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -27,6 +27,7 @@
  */
 static int uninorth_rev;
 static int is_u3;
+static u32 scratch_value;
 
 #define DEFAULT_APERTURE_SIZE 256
 #define DEFAULT_APERTURE_STRING "256"
@@ -171,7 +172,7 @@ static int uninorth_insert_memory(struct agp_memory *mem, 
off_t pg_start, int ty
 
        gp = (u32 *) &agp_bridge->gatt_table[pg_start];
        for (i = 0; i < mem->page_count; ++i) {
-               if (gp[i]) {
+               if (gp[i] != scratch_value) {
                        dev_info(&agp_bridge->dev->dev,
                                 "uninorth_insert_memory: entry 0x%x occupied 
(%x)\n",
                                 i, gp[i]);
@@ -213,8 +214,9 @@ int uninorth_remove_memory(struct agp_memory *mem, off_t 
pg_start, int type)
                return 0;
 
        gp = (u32 *) &agp_bridge->gatt_table[pg_start];
-       for (i = 0; i < mem->page_count; ++i)
-               gp[i] = 0;
+       for (i = 0; i < mem->page_count; ++i) {
+               gp[i] = scratch_value;
+       }
        mb();
        uninorth_tlbflush(mem);
 
@@ -420,8 +422,13 @@ static int uninorth_create_gatt_table(struct 
agp_bridge_data *bridge)
 
        bridge->gatt_bus_addr = virt_to_phys(table);
 
+       if (is_u3)
+               scratch_value = (page_to_phys(agp_bridge->scratch_page_page) >> 
PAGE_SHIFT) | 0x80000000UL;
+       else
+               scratch_value = 
cpu_to_le32((page_to_phys(agp_bridge->scratch_page_page) & 0xFFFFF000UL) |
+                               0x1UL);
        for (i = 0; i < num_entries; i++)
-               bridge->gatt_table[i] = 0;
+               bridge->gatt_table[i] = scratch_value;
 
        return 0;
 
@@ -518,6 +525,7 @@ const struct agp_bridge_driver uninorth_agp_driver = {
        .agp_destroy_pages      = agp_generic_destroy_pages,
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
        .cant_use_aperture      = true,
+       .needs_scratch_page     = true,
 };
 
 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 d3bd243..df67e80 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 = {
        .aperture_sizes         = agp3_generic_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 10,
+       .needs_scratch_page     = true,
        .configure              = via_configure_agp3,
        .fetch_size             = via_fetch_size_agp3,
        .cleanup                = via_cleanup_agp3,
@@ -201,6 +202,7 @@ static const struct agp_bridge_driver via_driver = {
        .aperture_sizes         = via_generic_sizes,
        .size_type              = U8_APER_SIZE,
        .num_aperture_sizes     = 9,
+       .needs_scratch_page     = true,
        .configure              = via_configure,
        .fetch_size             = via_fetch_size,
        .cleanup                = via_cleanup,
-- 
1.7.0.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to