Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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=59631
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
[danvet: Apply s/vtd_wa/vtd_scanout_wa/ bikeshed since Damien likes
it, too.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

authored by

Chris Wilson and committed by
Daniel Vetter
693db184 4f770a5b

+34 -1
+29 -1
drivers/gpu/drm/i915/intel_display.c
··· 1950 1950 intel_wait_for_vblank(dev_priv->dev, pipe); 1951 1951 } 1952 1952 1953 + static bool need_vtd_wa(struct drm_device *dev) 1954 + { 1955 + #ifdef CONFIG_INTEL_IOMMU 1956 + if (INTEL_INFO(dev)->gen >= 6 && intel_iommu_gfx_mapped) 1957 + return true; 1958 + #endif 1959 + return false; 1960 + } 1961 + 1953 1962 int 1954 1963 intel_pin_and_fence_fb_obj(struct drm_device *dev, 1955 1964 struct drm_i915_gem_object *obj, ··· 1988 1979 default: 1989 1980 BUG(); 1990 1981 } 1982 + 1983 + /* Note that the w/a also requires 64 PTE of padding following the 1984 + * bo. We currently fill all unused PTE with the shadow page and so 1985 + * we should always have valid PTE following the scanout preventing 1986 + * the VT-d warning. 1987 + */ 1988 + if (need_vtd_wa(dev) && alignment < 256 * 1024) 1989 + alignment = 256 * 1024; 1991 1990 1992 1991 dev_priv->mm.interruptible = false; 1993 1992 ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); ··· 6388 6371 /* we only need to pin inside GTT if cursor is non-phy */ 6389 6372 mutex_lock(&dev->struct_mutex); 6390 6373 if (!dev_priv->info->cursor_needs_physical) { 6374 + unsigned alignment; 6375 + 6391 6376 if (obj->tiling_mode) { 6392 6377 DRM_ERROR("cursor cannot be tiled\n"); 6393 6378 ret = -EINVAL; 6394 6379 goto fail_locked; 6395 6380 } 6396 6381 6397 - ret = i915_gem_object_pin_to_display_plane(obj, 0, NULL); 6382 + /* Note that the w/a also requires 2 PTE of padding following 6383 + * the bo. We currently fill all unused PTE with the shadow 6384 + * page and so we should always have valid PTE following the 6385 + * cursor preventing the VT-d warning. 6386 + */ 6387 + alignment = 0; 6388 + if (need_vtd_wa(dev)) 6389 + alignment = 64*1024; 6390 + 6391 + ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL); 6398 6392 if (ret) { 6399 6393 DRM_ERROR("failed to move cursor bo into the GTT\n"); 6400 6394 goto fail_locked;
+5
drivers/gpu/drm/i915/intel_sprite.c
··· 522 522 523 523 mutex_lock(&dev->struct_mutex); 524 524 525 + /* Note that this will apply the VT-d workaround for scanouts, 526 + * which is more restrictive than required for sprites. (The 527 + * primary plane requires 256KiB alignment with 64 PTE padding, 528 + * the sprite planes only require 128KiB alignment and 32 PTE padding. 529 + */ 525 530 ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); 526 531 if (ret) 527 532 goto out_unlock;