@@ -1761,6 +1761,39 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
return 0;
}
+unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb,
+ const struct intel_fb_view *view,
+ unsigned int rotation)
+{
+ struct drm_i915_private *i915 = to_i915(fb->dev);
+ unsigned int vtd_guard;
+ int color_plane;
+
+ if (!intel_scanout_needs_vtd_wa(i915))
+ return 0;
+
+ vtd_guard = 168;
+
+ for (color_plane = 0; color_plane < fb->format->num_planes; color_plane++) {
+ unsigned int stride, tile;
+
+ if (intel_fb_is_ccs_aux_plane(fb, color_plane) ||
+ is_gen12_ccs_cc_plane(fb, color_plane))
+ continue;
+
+ stride = view->color_plane[color_plane].mapping_stride;
+
+ if (drm_rotation_90_or_270(rotation))
+ tile = intel_tile_height(fb, color_plane);
+ else
+ tile = intel_tile_width_bytes(fb, color_plane);
+
+ vtd_guard = max(vtd_guard, DIV_ROUND_UP(stride, tile));
+ }
+
+ return vtd_guard;
+}
+
static void intel_plane_remap_gtt(struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 =
@@ -83,6 +83,9 @@ bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb);
int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb);
void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation,
struct intel_fb_view *view);
+unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb,
+ const struct intel_fb_view *view,
+ unsigned int rotation);
int intel_plane_compute_gtt(struct intel_plane_state *plane_state);
int intel_framebuffer_init(struct intel_framebuffer *ifb,
@@ -107,6 +107,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
const struct i915_gtt_view *view,
unsigned int alignment,
unsigned int phys_alignment,
+ unsigned int vtd_guard,
bool uses_fence,
unsigned long *out_flags)
{
@@ -162,7 +163,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
goto err;
vma = i915_gem_object_pin_to_display_plane(obj, &ww, alignment,
- view, pinctl);
+ vtd_guard, view, pinctl);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto err_unpin;
@@ -244,6 +245,14 @@ intel_plane_fb_min_phys_alignment(const struct intel_plane_state *plane_state)
return plane->min_alignment(plane, fb, 0);
}
+static unsigned int
+intel_plane_fb_vtd_guard(const struct intel_plane_state *plane_state)
+{
+ return intel_fb_view_vtd_guard(plane_state->hw.fb,
+ &plane_state->view,
+ plane_state->hw.rotation);
+}
+
int intel_plane_pin_fb(struct intel_plane_state *plane_state,
const struct intel_plane_state *old_plane_state)
{
@@ -256,6 +265,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state,
vma = intel_fb_pin_to_ggtt(&fb->base, &plane_state->view.gtt,
intel_plane_fb_min_alignment(plane_state),
intel_plane_fb_min_phys_alignment(plane_state),
+ intel_plane_fb_vtd_guard(plane_state),
intel_plane_uses_fence(plane_state),
&plane_state->flags);
if (IS_ERR(vma))
@@ -18,6 +18,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
const struct i915_gtt_view *view,
unsigned int alignment,
unsigned int phys_alignment,
+ unsigned int vtd_guard,
bool uses_fence,
unsigned long *out_flags);
@@ -228,6 +228,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
*/
vma = intel_fb_pin_to_ggtt(&fb->base, &view,
fb->min_alignment, 0,
+ intel_fb_view_vtd_guard(&fb->base, &fb->normal_view,
+ DRM_MODE_ROTATE_0),
false, &flags);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
@@ -772,7 +772,7 @@ static struct i915_vma *intel_overlay_pin_fb(struct drm_i915_gem_object *new_bo)
retry:
ret = i915_gem_object_lock(new_bo, &ww);
if (!ret) {
- vma = i915_gem_object_pin_to_display_plane(new_bo, &ww, 0,
+ vma = i915_gem_object_pin_to_display_plane(new_bo, &ww, 0, 0,
NULL, PIN_MAPPABLE);
ret = PTR_ERR_OR_ZERO(vma);
}
@@ -18,8 +18,6 @@
#include "i915_gem_object_frontbuffer.h"
#include "i915_vma.h"
-#define VTD_GUARD (168u * I915_GTT_PAGE_SIZE) /* 168 or tile-row PTE padding */
-
static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj)
{
struct drm_i915_private *i915 = to_i915(obj->base.dev);
@@ -424,7 +422,7 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
struct i915_vma *
i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
struct i915_gem_ww_ctx *ww,
- u32 alignment,
+ u32 alignment, unsigned int guard,
const struct i915_gtt_view *view,
unsigned int flags)
{
@@ -453,15 +451,8 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
return ERR_PTR(ret);
/* VT-d may overfetch before/after the vma, so pad with scratch */
- if (intel_scanout_needs_vtd_wa(i915)) {
- unsigned int guard = VTD_GUARD;
-
- if (i915_gem_object_is_tiled(obj))
- guard = max(guard,
- i915_gem_object_get_tile_row_size(obj));
-
- flags |= PIN_OFFSET_GUARD | guard;
- }
+ if (guard)
+ flags |= PIN_OFFSET_GUARD | (guard * I915_GTT_PAGE_SIZE);
/*
* As the user may map the buffer once pinned in the display plane
@@ -776,7 +776,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write);
struct i915_vma * __must_check
i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
struct i915_gem_ww_ctx *ww,
- u32 alignment,
+ u32 alignment, unsigned int guard,
const struct i915_gtt_view *view,
unsigned int flags);
@@ -369,6 +369,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
const struct i915_gtt_view *view,
unsigned int alignment,
unsigned int phys_alignment,
+ unsigned int vtd_guard,
bool uses_fence,
unsigned long *out_flags)
{
@@ -215,7 +215,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
plane_state->uapi.rotation, &plane_state->view);
vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt,
- 0, 0, false, &plane_state->flags);
+ 0, 0, 0, false, &plane_state->flags);
if (IS_ERR(vma))
goto nofb;