]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/i915: Use per-plane VT-d guard numbers
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 22 Jan 2025 15:17:54 +0000 (17:17 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 6 Feb 2025 13:40:16 +0000 (15:40 +0200)
Bspec lists different VT-d guard numbers (the number of dummy
padding PTEs) for different platforms and plane types. Use those
instead of just assuming the max glk+ number for everything.
This could avoid a bit of overhead on older platforms due to
reduced padding, and it makes it easier to cross check with the
spec.

Note that VLV/CHV do not document this w/a at all, so not sure
if it's actually needed or not. Nor do we actually know how much
padding is required if it is needed. For now use the same 128
PTEs that we use for snb-bdw primary planes.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250122151755.6928-5-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/i9xx_plane.c
drivers/gpu/drm/i915/display/intel_cursor.c
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_fb.c
drivers/gpu/drm/i915/display/intel_sprite.c
drivers/gpu/drm/i915/display/skl_universal_plane.c

index 65a2eb9e92c40039a0ee8758de9a8aec3e3cc9d3..bd3f8db13700730ff9e572452ece8672d357166c 100644 (file)
@@ -958,6 +958,10 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
        else
                plane->min_alignment = i9xx_plane_min_alignment;
 
+       /* FIXME undocumented for VLV/CHV so not sure what's actually needed */
+       if (intel_scanout_needs_vtd_wa(dev_priv))
+               plane->vtd_guard = 128;
+
        if (IS_I830(dev_priv) || IS_I845G(dev_priv)) {
                plane->update_arm = i830_plane_update_arm;
        } else {
index cbeea9d965174edf9129883d22b6a0a8ddfdc48f..6a1035a22b0a3b2cb3d25f0cb5dd89774e82e4e2 100644 (file)
@@ -1019,6 +1019,9 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
                else
                        cursor->min_alignment = i9xx_cursor_min_alignment;
 
+               if (intel_scanout_needs_vtd_wa(dev_priv))
+                       cursor->vtd_guard = 2;
+
                cursor->update_arm = i9xx_cursor_update_arm;
                cursor->disable_arm = i9xx_cursor_disable_arm;
                cursor->get_hw_state = i9xx_cursor_get_hw_state;
index 37b1a216b13b75d1b000e0736e2ca12f3aa9dd12..d8a3d4d6aedf85e187c1fed95f2800e8940824fd 100644 (file)
@@ -144,6 +144,7 @@ struct intel_framebuffer {
        struct i915_address_space *dpt_vm;
 
        unsigned int min_alignment;
+       unsigned int vtd_guard;
 };
 
 enum intel_hotplug_state {
@@ -1448,6 +1449,7 @@ struct intel_plane {
        enum plane_id id;
        enum pipe pipe;
        bool need_async_flip_toggle_wa;
+       u8 vtd_guard;
        u32 frontbuffer_bit;
 
        struct {
index ea8c8a99c5c7e8415691c508c1ce8c29a95c9255..d9328877cc6db49a3a33481699817415031adb4e 100644 (file)
@@ -1660,6 +1660,22 @@ static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb)
        return min_alignment;
 }
 
+static unsigned int intel_fb_vtd_guard(const struct drm_framebuffer *fb)
+{
+       struct drm_i915_private *i915 = to_i915(fb->dev);
+       struct intel_plane *plane;
+       unsigned int vtd_guard = 0;
+
+       for_each_intel_plane(&i915->drm, plane) {
+               if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier))
+                       continue;
+
+               vtd_guard = max_t(unsigned int, vtd_guard, plane->vtd_guard);
+       }
+
+       return vtd_guard;
+}
+
 int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb)
 {
        struct drm_gem_object *obj = intel_fb_bo(&fb->base);
@@ -1757,6 +1773,7 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
        }
 
        fb->min_alignment = intel_fb_min_alignment(&fb->base);
+       fb->vtd_guard = intel_fb_vtd_guard(&fb->base);
 
        return 0;
 }
@@ -1765,15 +1782,13 @@ 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))
+       vtd_guard = to_intel_framebuffer(fb)->vtd_guard;
+       if (!vtd_guard)
                return 0;
 
-       vtd_guard = 168;
-
        for (color_plane = 0; color_plane < fb->format->num_planes; color_plane++) {
                unsigned int stride, tile;
 
index af121c720b89dec67343502e7ce710ff0cca39c2..a6b27798fdc3f493d94c8b8d2809057489b5330b 100644 (file)
@@ -1609,6 +1609,10 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
                plane->min_alignment = vlv_plane_min_alignment;
                plane->min_cdclk = vlv_plane_min_cdclk;
 
+               /* FIXME undocumented for VLV/CHV so not sure what's actually needed */
+               if (intel_scanout_needs_vtd_wa(dev_priv))
+                       plane->vtd_guard = 128;
+
                if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
                        formats = chv_pipe_b_sprite_formats;
                        num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats);
@@ -1635,6 +1639,9 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
 
                plane->min_alignment = g4x_sprite_min_alignment;
 
+               if (intel_scanout_needs_vtd_wa(dev_priv))
+                       plane->vtd_guard = 64;
+
                formats = snb_sprite_formats;
                num_formats = ARRAY_SIZE(snb_sprite_formats);
 
@@ -1649,6 +1656,9 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
                plane->min_alignment = g4x_sprite_min_alignment;
                plane->min_cdclk = g4x_sprite_min_cdclk;
 
+               if (intel_scanout_needs_vtd_wa(dev_priv))
+                       plane->vtd_guard = 64;
+
                if (IS_SANDYBRIDGE(dev_priv)) {
                        formats = snb_sprite_formats;
                        num_formats = ARRAY_SIZE(snb_sprite_formats);
index d4774abbf462a216e747dd04f514fe37394897b3..ee93361bba097e30f21f4994947f92f3e18c3f24 100644 (file)
@@ -2750,6 +2750,9 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
        else
                plane->min_alignment = skl_plane_min_alignment;
 
+       if (intel_scanout_needs_vtd_wa(dev_priv))
+               plane->vtd_guard = DISPLAY_VER(dev_priv) >= 10 ? 168 : 136;
+
        if (DISPLAY_VER(dev_priv) >= 11) {
                plane->update_noarm = icl_plane_update_noarm;
                plane->update_arm = icl_plane_update_arm;