Commit 693db184 authored by Chris Wilson's avatar Chris Wilson Committed by Daniel Vetter

drm/i915: Apply alignment restrictions on scanout surfaces for VT-d

From the w/a database:

'To prevent false VT-d type 6 error:

  The primary display plane must be 256KiB aligned, and require an extra
  128 PTEs of padding afterward;

  The sprites planes must be 128KiB aligned, and require an extra 64 PTEs
  of padding afterward;

  The cursors must be 64KiB aligned, and require an extra 2 PTEs of
  padding afterward.'

As we use the same function to pin the primary and sprite planes, we can
simply use the more strict requirements for scanouts for both.

Instead of using explicit padding PTEs following the scanout objects, we
should be able to use the scratch page that is always mapped into the
unused PTEs to avoid the VT-d error.

References: https://bugs.freedesktop.org/show_bug.cgi?id=59626
References: https://bugs.freedesktop.org/show_bug.cgi?id=59627
References: https://bugs.freedesktop.org/show_bug.cgi?id=59631Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
[danvet: Apply s/vtd_wa/vtd_scanout_wa/ bikeshed since Damien likes
it, too.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 4f770a5b
...@@ -1950,6 +1950,15 @@ static void intel_disable_plane(struct drm_i915_private *dev_priv, ...@@ -1950,6 +1950,15 @@ static void intel_disable_plane(struct drm_i915_private *dev_priv,
intel_wait_for_vblank(dev_priv->dev, pipe); intel_wait_for_vblank(dev_priv->dev, pipe);
} }
static bool need_vtd_wa(struct drm_device *dev)
{
#ifdef CONFIG_INTEL_IOMMU
if (INTEL_INFO(dev)->gen >= 6 && intel_iommu_gfx_mapped)
return true;
#endif
return false;
}
int int
intel_pin_and_fence_fb_obj(struct drm_device *dev, intel_pin_and_fence_fb_obj(struct drm_device *dev,
struct drm_i915_gem_object *obj, struct drm_i915_gem_object *obj,
...@@ -1980,6 +1989,14 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, ...@@ -1980,6 +1989,14 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
BUG(); BUG();
} }
/* Note that the w/a also requires 64 PTE of padding following the
* bo. We currently fill all unused PTE with the shadow page and so
* we should always have valid PTE following the scanout preventing
* the VT-d warning.
*/
if (need_vtd_wa(dev) && alignment < 256 * 1024)
alignment = 256 * 1024;
dev_priv->mm.interruptible = false; dev_priv->mm.interruptible = false;
ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined);
if (ret) if (ret)
...@@ -6371,13 +6388,24 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, ...@@ -6371,13 +6388,24 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
/* we only need to pin inside GTT if cursor is non-phy */ /* we only need to pin inside GTT if cursor is non-phy */
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
if (!dev_priv->info->cursor_needs_physical) { if (!dev_priv->info->cursor_needs_physical) {
unsigned alignment;
if (obj->tiling_mode) { if (obj->tiling_mode) {
DRM_ERROR("cursor cannot be tiled\n"); DRM_ERROR("cursor cannot be tiled\n");
ret = -EINVAL; ret = -EINVAL;
goto fail_locked; goto fail_locked;
} }
ret = i915_gem_object_pin_to_display_plane(obj, 0, NULL); /* Note that the w/a also requires 2 PTE of padding following
* the bo. We currently fill all unused PTE with the shadow
* page and so we should always have valid PTE following the
* cursor preventing the VT-d warning.
*/
alignment = 0;
if (need_vtd_wa(dev))
alignment = 64*1024;
ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL);
if (ret) { if (ret) {
DRM_ERROR("failed to move cursor bo into the GTT\n"); DRM_ERROR("failed to move cursor bo into the GTT\n");
goto fail_locked; goto fail_locked;
......
...@@ -522,6 +522,11 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -522,6 +522,11 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
/* Note that this will apply the VT-d workaround for scanouts,
* which is more restrictive than required for sprites. (The
* primary plane requires 256KiB alignment with 64 PTE padding,
* the sprite planes only require 128KiB alignment and 32 PTE padding.
*/
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
if (ret) if (ret)
goto out_unlock; goto out_unlock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment