diff options
author | Eric Anholt <eric@anholt.net> | 2009-05-26 18:46:16 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-05-26 19:11:33 -0700 |
commit | cfa16a0de5392c54db553ec2233a7110e4b4da7a (patch) | |
tree | dece86a45e71828827ef597b1bd3363149a6d655 /drivers/gpu/drm | |
parent | e76a16deb8785317a23cca7204331af053e0fb4e (diff) | |
download | kernel_samsung_tuna-cfa16a0de5392c54db553ec2233a7110e4b4da7a.zip kernel_samsung_tuna-cfa16a0de5392c54db553ec2233a7110e4b4da7a.tar.gz kernel_samsung_tuna-cfa16a0de5392c54db553ec2233a7110e4b4da7a.tar.bz2 |
drm/i915: Apply a big hammer to 865 GEM object CPU cache flushing.
On the 865, but not the 855, the clflush we do appears to not actually make
it out to the hardware all the time. An easy way to safely reproduce was
X -retro, which would show that some of the blits involved in drawing the
lovely root weave didn't make it out to the hardware. Those blits are 32
bytes each, and 1-2 would be missing at various points around the screen.
Other experimentation (doing more clflush, doing more AGP chipset flush,
poking at some more device registers to maybe trigger more flushing) didn't
help. krh came up with the wbinvd as a way to successfully get all those
blits to appear.
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e4408da..e242186 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2423,6 +2423,16 @@ i915_gem_clflush_object(struct drm_gem_object *obj) if (obj_priv->pages == NULL) return; + /* XXX: The 865 in particular appears to be weird in how it handles + * cache flushing. We haven't figured it out, but the + * clflush+agp_chipset_flush doesn't appear to successfully get the + * data visible to the PGU, while wbinvd + agp_chipset_flush does. + */ + if (IS_I865G(obj->dev)) { + wbinvd(); + return; + } + drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); } |