aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2009-12-02 06:00:05 -0500
committerEric Anholt <eric@anholt.net>2009-12-07 18:29:04 -0500
commitfc61901373987ad61851ed001fe971f3ee8d96a3 (patch)
tree2711786140a63cbbbf7154ac1e5d2f1bc11e2b86 /drivers/char/agp
parentf2b115e69d46344ae7afcaad5823496d2a0d8650 (diff)
agp/intel-agp: Clear entire GTT on startup
Some BIOSes fail to initialise the GTT, which will cause DMA faults when the IOMMU is enabled. We need to clear the whole thing to point at the scratch page, not just the part that Linux is going to use. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> [anholt: Note that this may also help with stability in the presence of driver bugs, by not drawing to memory we don't own] Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/char/agp')
-rw-r--r--drivers/char/agp/intel-agp.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 37cb4e2b2328..33b4853b1353 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -176,6 +176,7 @@ static struct _intel_private {
176 * popup and for the GTT. 176 * popup and for the GTT.
177 */ 177 */
178 int gtt_entries; /* i830+ */ 178 int gtt_entries; /* i830+ */
179 int gtt_total_size;
179 union { 180 union {
180 void __iomem *i9xx_flush_page; 181 void __iomem *i9xx_flush_page;
181 void *i8xx_flush_page; 182 void *i8xx_flush_page;
@@ -1151,7 +1152,7 @@ static int intel_i915_configure(void)
1151 readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ 1152 readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
1152 1153
1153 if (agp_bridge->driver->needs_scratch_page) { 1154 if (agp_bridge->driver->needs_scratch_page) {
1154 for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { 1155 for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) {
1155 writel(agp_bridge->scratch_page, intel_private.gtt+i); 1156 writel(agp_bridge->scratch_page, intel_private.gtt+i);
1156 } 1157 }
1157 readl(intel_private.gtt+i-1); /* PCI Posting. */ 1158 readl(intel_private.gtt+i-1); /* PCI Posting. */
@@ -1312,6 +1313,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
1312 if (!intel_private.gtt) 1313 if (!intel_private.gtt)
1313 return -ENOMEM; 1314 return -ENOMEM;
1314 1315
1316 intel_private.gtt_total_size = gtt_map_size / 4;
1317
1315 temp &= 0xfff80000; 1318 temp &= 0xfff80000;
1316 1319
1317 intel_private.registers = ioremap(temp, 128 * 4096); 1320 intel_private.registers = ioremap(temp, 128 * 4096);
@@ -1398,6 +1401,8 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
1398 if (!intel_private.gtt) 1401 if (!intel_private.gtt)
1399 return -ENOMEM; 1402 return -ENOMEM;
1400 1403
1404 intel_private.gtt_total_size = gtt_size / 4;
1405
1401 intel_private.registers = ioremap(temp, 128 * 4096); 1406 intel_private.registers = ioremap(temp, 128 * 4096);
1402 if (!intel_private.registers) { 1407 if (!intel_private.registers) {
1403 iounmap(intel_private.gtt); 1408 iounmap(intel_private.gtt);