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>
        .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,
 
 {
        struct aper_size_info_lvl2 *value;
        struct amd_page_map page_dir;
+       unsigned long __iomem *cur_gatt;
        unsigned long addr;
        int retval;
        u32 temp;
                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;
 }
 
        .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,
 
        .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,
 
 {
        struct aper_size_info_lvl2 *value;
        struct ati_page_map page_dir;
+       unsigned long __iomem *cur_gatt;
        unsigned long addr;
        int retval;
        u32 temp;
                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;
 }
 
        .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,
 
        .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,
        .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,
        .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,
        .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,
        .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,
        .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,
        .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,
        .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,
        .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,
 
        .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,
 
        .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,
 
  */
 static int uninorth_rev;
 static int is_u3;
+static u32 scratch_value;
 
 #define DEFAULT_APERTURE_SIZE 256
 #define DEFAULT_APERTURE_STRING "256"
 
        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]);
                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);
 
 
        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;
 
        .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 = {
 
        .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,
        .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,