drm/i915: Introduce fb->min_alignment
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 12 Jun 2024 20:47:07 +0000 (23:47 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 24 Jun 2024 14:12:10 +0000 (17:12 +0300)
Different planes could have different alignment requirements
even for the same format/modifier. Collect the alignment
requirements across all planes capable of scanning out the
fb such that the alignment is satisfactory to all those
planes.

So far this was sort of handled by making sure intel_surf_alignment()
declares the superset of all planes' alignment requirements,
but maintaining that manually is annoying. So we're going to move
towards each plane declaring only its own requirements, and thus
we need code to generate the superset.

v2: Drop the borked per-plane vma optimization (Imre)
    Assert that the plane's declared alignment is POT (Imre)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240612204712.31404-5-ville.syrjala@linux.intel.com
Reviewed-by: Imre Deak <imre.deak@intel.com>
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_fb.c
drivers/gpu/drm/i915/display/intel_fb_pin.c
drivers/gpu/drm/i915/display/intel_fbdev.c

index 8a9fd307b81ea03d6054e607e65194477d821ce1..ae069993913f4276d86fc4b599766fd6be96001e 100644 (file)
@@ -146,6 +146,8 @@ struct intel_framebuffer {
        };
 
        struct i915_address_space *dpt_vm;
+
+       unsigned int min_alignment;
 };
 
 enum intel_hotplug_state {
index b3a48754a4173fc9fcc0a48c95a27e60c18e0f3a..0abb80972885003058acac569407d5861a9d20f0 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "gem/i915_gem_object.h"
 #include "i915_drv.h"
+#include "intel_atomic_plane.h"
 #include "intel_display.h"
 #include "intel_display_types.h"
 #include "intel_dpt.h"
@@ -1617,6 +1618,32 @@ bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb)
               fb->base.modifier == I915_FORMAT_MOD_Yf_TILED;
 }
 
+static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb)
+{
+       struct drm_i915_private *i915 = to_i915(fb->dev);
+       struct intel_plane *plane;
+       unsigned int min_alignment = 0;
+
+       for_each_intel_plane(&i915->drm, plane) {
+               unsigned int plane_min_alignment;
+
+               if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier))
+                       continue;
+
+               plane_min_alignment = plane->min_alignment(plane, fb, 0);
+
+               drm_WARN_ON(&i915->drm, plane_min_alignment &&
+                           !is_power_of_2(plane_min_alignment));
+
+               if (intel_plane_needs_physical(plane))
+                       continue;
+
+               min_alignment = max(min_alignment, plane_min_alignment);
+       }
+
+       return min_alignment;
+}
+
 int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb)
 {
        struct drm_i915_gem_object *obj = intel_fb_obj(&fb->base);
@@ -1699,6 +1726,8 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
                return -EINVAL;
        }
 
+       fb->min_alignment = intel_fb_min_alignment(&fb->base);
+
        return 0;
 }
 
index 9b0f1ea41b70b91b8ea3b95c21820cda53a38f01..575b271e012bd82897cbd113eed5f482b41222e4 100644 (file)
@@ -233,10 +233,9 @@ void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags)
 static unsigned int
 intel_plane_fb_min_alignment(const struct intel_plane_state *plane_state)
 {
-       struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
-       const struct drm_framebuffer *fb = plane_state->hw.fb;
+       const struct intel_framebuffer *fb = to_intel_framebuffer(plane_state->hw.fb);
 
-       return plane->min_alignment(plane, fb, 0);
+       return fb->min_alignment;
 }
 
 static unsigned int
index 6e5f88f20482c59f4f5a494fe751278a64d2237f..49a1ac4f549195fc448d37d0d1cc0e501a788436 100644 (file)
@@ -47,7 +47,6 @@
 #include "gem/i915_gem_object.h"
 
 #include "i915_drv.h"
-#include "intel_crtc.h"
 #include "intel_display_types.h"
 #include "intel_fb.h"
 #include "intel_fb_pin.h"
@@ -173,21 +172,6 @@ static const struct fb_ops intelfb_ops = {
 
 __diag_pop();
 
-static unsigned int intel_fbdev_min_alignment(const struct drm_framebuffer *fb)
-{
-       struct drm_i915_private *i915 = to_i915(fb->dev);
-       struct intel_plane *plane;
-       struct intel_crtc *crtc;
-
-       crtc = intel_first_crtc(i915);
-       if (!crtc)
-               return 0;
-
-       plane = to_intel_plane(crtc->base.primary);
-
-       return plane->min_alignment(plane, fb, 0);
-}
-
 static int intelfb_create(struct drm_fb_helper *helper,
                          struct drm_fb_helper_surface_size *sizes)
 {
@@ -245,7 +229,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
         * BIOS is suitable for own access.
         */
        vma = intel_fb_pin_to_ggtt(&fb->base, &view,
-                                  intel_fbdev_min_alignment(&fb->base), 0,
+                                  fb->min_alignment, 0,
                                   false, &flags);
        if (IS_ERR(vma)) {
                ret = PTR_ERR(vma);