aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/intel-gtt.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-03-14 14:15:13 +1000
committerDave Airlie <airlied@redhat.com>2011-03-14 14:15:13 +1000
commit34db18abd376b2075c760c38f0b861aed379415d (patch)
treec4174e39a2f445f17c25ab206d45c66217bbbf85 /drivers/char/agp/intel-gtt.c
parentdrm: add cap bit to denote if dumb ioctl is available or not. (diff)
parentMerge branch 'drm-intel-fixes' into drm-intel-next (diff)
downloadlinux-dev-34db18abd376b2075c760c38f0b861aed379415d.tar.xz
linux-dev-34db18abd376b2075c760c38f0b861aed379415d.zip
Merge remote branch 'intel/drm-intel-next' of ../drm-next into drm-core-next
* 'intel/drm-intel-next' of ../drm-next: (755 commits) drm/i915: Only wait on a pending flip if we intend to write to the buffer drm/i915/dp: Sanity check eDP existence drm/i915: Rebind the buffer if its alignment constraints changes with tiling drm/i915: Disable GPU semaphores by default drm/i915: Do not overflow the MMADDR write FIFO Revert "drm/i915: fix corruptions on i8xx due to relaxed fencing" drm/i915: Don't save/restore hardware status page address register drm/i915: don't store the reg value for HWS_PGA drm/i915: fix memory corruption with GM965 and >4GB RAM Linux 2.6.38-rc7 Revert "TPM: Long default timeout fix" drm/i915: Re-enable GPU semaphores for SandyBridge mobile drm/i915: Replace vblank PM QoS with "Interrupt-Based AGPBUSY#" Revert "drm/i915: Use PM QoS to prevent C-State starvation of gen3 GPU" drm/i915: Allow relocation deltas outside of target bo drm/i915: Silence an innocuous compiler warning for an unused variable fs/block_dev.c: fix new kernel-doc warning ACPI: Fix build for CONFIG_NET unset mm: <asm-generic/pgtable.h> must include <linux/mm_types.h> x86: Use u32 instead of long to set reset vector back to 0 ... Conflicts: drivers/gpu/drm/i915/i915_gem.c
Diffstat (limited to 'drivers/char/agp/intel-gtt.c')
-rw-r--r--drivers/char/agp/intel-gtt.c56
1 files changed, 21 insertions, 35 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index fab3d3265adb..0d09b537bb9a 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/pagemap.h>
#include <linux/agp_backend.h>
+#include <linux/delay.h>
#include <asm/smp.h>
#include "agp.h"
#include "intel-agp.h"
@@ -70,12 +71,8 @@ static struct _intel_private {
u32 __iomem *gtt; /* I915G */
bool clear_fake_agp; /* on first access via agp, fill with scratch */
int num_dcache_entries;
- union {
- void __iomem *i9xx_flush_page;
- void *i8xx_flush_page;
- };
+ void __iomem *i9xx_flush_page;
char *i81x_gtt_table;
- struct page *i8xx_page;
struct resource ifp_resource;
int resource_valid;
struct page *scratch_page;
@@ -722,28 +719,6 @@ static int intel_fake_agp_fetch_size(void)
static void i830_cleanup(void)
{
- if (intel_private.i8xx_flush_page) {
- kunmap(intel_private.i8xx_flush_page);
- intel_private.i8xx_flush_page = NULL;
- }
-
- __free_page(intel_private.i8xx_page);
- intel_private.i8xx_page = NULL;
-}
-
-static void intel_i830_setup_flush(void)
-{
- /* return if we've already set the flush mechanism up */
- if (intel_private.i8xx_page)
- return;
-
- intel_private.i8xx_page = alloc_page(GFP_KERNEL);
- if (!intel_private.i8xx_page)
- return;
-
- intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page);
- if (!intel_private.i8xx_flush_page)
- i830_cleanup();
}
/* The chipset_flush interface needs to get data that has already been
@@ -758,14 +733,27 @@ static void intel_i830_setup_flush(void)
*/
static void i830_chipset_flush(void)
{
- unsigned int *pg = intel_private.i8xx_flush_page;
+ unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+
+ /* Forcibly evict everything from the CPU write buffers.
+ * clflush appears to be insufficient.
+ */
+ wbinvd_on_all_cpus();
+
+ /* Now we've only seen documents for this magic bit on 855GM,
+ * we hope it exists for the other gen2 chipsets...
+ *
+ * Also works as advertised on my 845G.
+ */
+ writel(readl(intel_private.registers+I830_HIC) | (1<<31),
+ intel_private.registers+I830_HIC);
- memset(pg, 0, 1024);
+ while (readl(intel_private.registers+I830_HIC) & (1<<31)) {
+ if (time_after(jiffies, timeout))
+ break;
- if (cpu_has_clflush)
- clflush_cache_range(pg, 1024);
- else if (wbinvd_on_all_cpus() != 0)
- printk(KERN_ERR "Timed out waiting for cache flush.\n");
+ udelay(50);
+ }
}
static void i830_write_entry(dma_addr_t addr, unsigned int entry,
@@ -849,8 +837,6 @@ static int i830_setup(void)
intel_private.gtt_bus_addr = reg_addr + I810_PTE_BASE;
- intel_i830_setup_flush();
-
return 0;
}