From: Ville Syrjälä <ville.syrj...@linux.intel.com>

Different hardware generations have different scanout alignment
requirements. Introduce a new vfunc that will allow us to
make that distinction without horrible if-ladders.

For now we directly plug in the existing intel_surf_alignment()
and intel_cursor_alignment() functions.

For fbdev we (temporarily) introduce intel_fbdev_min_alignment()
that simply queries the alignment from the primary plane of
the first crtc.

TODO: someone will need to fix xe's alignment handling

Reviewed-by: Imre Deak <imre.d...@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/i915/display/i9xx_plane.c     |  8 ++--
 drivers/gpu/drm/i915/display/intel_cursor.c   |  2 +
 .../drm/i915/display/intel_display_types.h    |  3 ++
 drivers/gpu/drm/i915/display/intel_fb.c       | 22 +++++-----
 drivers/gpu/drm/i915/display/intel_fb.h       |  7 +++-
 drivers/gpu/drm/i915/display/intel_fb_pin.c   | 40 ++++++++++++++-----
 drivers/gpu/drm/i915/display/intel_fb_pin.h   |  3 +-
 drivers/gpu/drm/i915/display/intel_fbdev.c    | 21 +++++++++-
 drivers/gpu/drm/i915/display/intel_sprite.c   |  2 +
 .../drm/i915/display/skl_universal_plane.c    | 11 +++--
 drivers/gpu/drm/xe/display/xe_fb_pin.c        |  3 +-
 drivers/gpu/drm/xe/display/xe_plane_initial.c |  4 +-
 12 files changed, 89 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c 
b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 864d94406894..53b18efaa88c 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -225,8 +225,8 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state 
*crtc_state,
 
 int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
 {
-       struct drm_i915_private *dev_priv =
-               to_i915(plane_state->uapi.plane->dev);
+       struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        const struct drm_framebuffer *fb = plane_state->hw.fb;
        int src_x, src_y, src_w;
        u32 offset;
@@ -267,7 +267,7 @@ int i9xx_check_plane_surface(struct intel_plane_state 
*plane_state)
         * despite them not using the linear offset anymore.
         */
        if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == 
I915_FORMAT_MOD_X_TILED) {
-               unsigned int alignment = intel_surf_alignment(fb, 0);
+               unsigned int alignment = plane->min_alignment(plane, fb, 0);
                int cpp = fb->format->cpp[0];
 
                while ((src_x + src_w) * cpp > 
plane_state->view.color_plane[0].mapping_stride) {
@@ -869,6 +869,8 @@ intel_primary_plane_create(struct drm_i915_private 
*dev_priv, enum pipe pipe)
                        plane->max_stride = ilk_primary_max_stride;
        }
 
+       plane->min_alignment = intel_surf_alignment;
+
        if (IS_I830(dev_priv) || IS_I845G(dev_priv)) {
                plane->update_arm = i830_plane_update_arm;
        } else {
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c 
b/drivers/gpu/drm/i915/display/intel_cursor.c
index 7f7fc710350c..5f8c23296b61 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -954,6 +954,8 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
                cursor->check_plane = i9xx_check_cursor;
        }
 
+       cursor->min_alignment = intel_cursor_alignment;
+
        cursor->cursor.base = ~0;
        cursor->cursor.cntl = ~0;
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 4fa785fd664e..0c165572fbd0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1560,6 +1560,9 @@ struct intel_plane {
        int (*max_height)(const struct drm_framebuffer *fb,
                          int color_plane,
                          unsigned int rotation);
+       unsigned int (*min_alignment)(struct intel_plane *plane,
+                                     const struct drm_framebuffer *fb,
+                                     int color_plane);
        unsigned int (*max_stride)(struct intel_plane *plane,
                                   u32 pixel_format, u64 modifier,
                                   unsigned int rotation);
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c 
b/drivers/gpu/drm/i915/display/intel_fb.c
index 8069abf91c5e..b3a48754a417 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -776,8 +776,12 @@ bool intel_fb_uses_dpt(const struct drm_framebuffer *fb)
                intel_fb_modifier_uses_dpt(to_i915(fb->dev), fb->modifier);
 }
 
-unsigned int intel_cursor_alignment(const struct drm_i915_private *i915)
+unsigned int intel_cursor_alignment(struct intel_plane *plane,
+                                   const struct drm_framebuffer *fb,
+                                   int color_plane)
 {
+       struct drm_i915_private *i915 = to_i915(plane->base.dev);
+
        if (IS_I830(i915))
                return 16 * 1024;
        else if (IS_I85X(i915))
@@ -801,10 +805,11 @@ static unsigned int intel_linear_alignment(const struct 
drm_i915_private *dev_pr
                return 0;
 }
 
-unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
+unsigned int intel_surf_alignment(struct intel_plane *plane,
+                                 const struct drm_framebuffer *fb,
                                  int color_plane)
 {
-       struct drm_i915_private *dev_priv = to_i915(fb->dev);
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 
        if (intel_fb_uses_dpt(fb)) {
                /* AUX_DIST needs only 4K alignment */
@@ -1099,17 +1104,12 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y,
                                       const struct intel_plane_state *state,
                                       int color_plane)
 {
-       struct intel_plane *intel_plane = to_intel_plane(state->uapi.plane);
-       struct drm_i915_private *i915 = to_i915(intel_plane->base.dev);
+       struct intel_plane *plane = to_intel_plane(state->uapi.plane);
+       struct drm_i915_private *i915 = to_i915(plane->base.dev);
        const struct drm_framebuffer *fb = state->hw.fb;
        unsigned int rotation = state->hw.rotation;
        unsigned int pitch = 
state->view.color_plane[color_plane].mapping_stride;
-       unsigned int alignment;
-
-       if (intel_plane->id == PLANE_CURSOR)
-               alignment = intel_cursor_alignment(i915);
-       else
-               alignment = intel_surf_alignment(fb, color_plane);
+       unsigned int alignment = plane->min_alignment(plane, fb, color_plane);
 
        return intel_compute_aligned_offset(i915, x, y, fb, color_plane,
                                            pitch, rotation, alignment);
diff --git a/drivers/gpu/drm/i915/display/intel_fb.h 
b/drivers/gpu/drm/i915/display/intel_fb.h
index 23db6628f53e..86c01a3ce81e 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.h
+++ b/drivers/gpu/drm/i915/display/intel_fb.h
@@ -60,8 +60,11 @@ unsigned int intel_tile_height(const struct drm_framebuffer 
*fb, int color_plane
 unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int 
color_plane);
 unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
                                   int color_plane, unsigned int height);
-unsigned int intel_cursor_alignment(const struct drm_i915_private *i915);
-unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
+unsigned int intel_cursor_alignment(struct intel_plane *plane,
+                                   const struct drm_framebuffer *fb,
+                                   int color_plane);
+unsigned int intel_surf_alignment(struct intel_plane *plane,
+                                 const struct drm_framebuffer *fb,
                                  int color_plane);
 
 void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c 
b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index 1acc11fa19f4..9b0f1ea41b70 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -103,8 +103,9 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
 
 struct i915_vma *
 intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
-                    bool phys_cursor,
                     const struct i915_gtt_view *view,
+                    unsigned int alignment,
+                    unsigned int phys_alignment,
                     bool uses_fence,
                     unsigned long *out_flags)
 {
@@ -113,7 +114,6 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        intel_wakeref_t wakeref;
        struct i915_gem_ww_ctx ww;
-       unsigned int alignment;
        struct i915_vma *vma;
        unsigned int pinctl;
        int ret;
@@ -121,10 +121,6 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
        if (drm_WARN_ON(dev, !i915_gem_object_is_framebuffer(obj)))
                return ERR_PTR(-EINVAL);
 
-       if (phys_cursor)
-               alignment = intel_cursor_alignment(dev_priv);
-       else
-               alignment = intel_surf_alignment(fb, 0);
        if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment)))
                return ERR_PTR(-EINVAL);
 
@@ -162,8 +158,8 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
        i915_gem_ww_ctx_init(&ww, true);
 retry:
        ret = i915_gem_object_lock(obj, &ww);
-       if (!ret && phys_cursor)
-               ret = i915_gem_object_attach_phys(obj, alignment);
+       if (!ret && phys_alignment)
+               ret = i915_gem_object_attach_phys(obj, phys_alignment);
        else if (!ret && HAS_LMEM(dev_priv))
                ret = i915_gem_object_migrate(obj, &ww, INTEL_REGION_LMEM_0);
        if (!ret)
@@ -234,6 +230,27 @@ void intel_fb_unpin_vma(struct i915_vma *vma, unsigned 
long flags)
        i915_vma_put(vma);
 }
 
+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;
+
+       return plane->min_alignment(plane, fb, 0);
+}
+
+static unsigned int
+intel_plane_fb_min_phys_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;
+
+       if (!intel_plane_needs_physical(plane))
+               return 0;
+
+       return plane->min_alignment(plane, fb, 0);
+}
+
 int intel_plane_pin_fb(struct intel_plane_state *plane_state)
 {
        struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
@@ -242,8 +259,9 @@ int intel_plane_pin_fb(struct intel_plane_state 
*plane_state)
        struct i915_vma *vma;
 
        if (!intel_fb_uses_dpt(&fb->base)) {
-               vma = intel_fb_pin_to_ggtt(&fb->base, 
intel_plane_needs_physical(plane),
-                                          &plane_state->view.gtt,
+               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_uses_fence(plane_state),
                                           &plane_state->flags);
                if (IS_ERR(vma))
@@ -261,7 +279,7 @@ int intel_plane_pin_fb(struct intel_plane_state 
*plane_state)
                        plane_state->phys_dma_addr =
                                
i915_gem_object_get_dma_address(intel_fb_obj(&fb->base), 0);
        } else {
-               unsigned int alignment = intel_surf_alignment(&fb->base, 0);
+               unsigned int alignment = 
intel_plane_fb_min_alignment(plane_state);
 
                vma = intel_dpt_pin_to_ggtt(fb->dpt_vm, alignment / 512);
                if (IS_ERR(vma))
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h 
b/drivers/gpu/drm/i915/display/intel_fb_pin.h
index 3f8245edcd15..ac0319b53af0 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.h
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h
@@ -15,8 +15,9 @@ struct i915_gtt_view;
 
 struct i915_vma *
 intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
-                    bool phys_cursor,
                     const struct i915_gtt_view *view,
+                    unsigned int alignment,
+                    unsigned int phys_alignment,
                     bool uses_fence,
                     unsigned long *out_flags);
 
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 37ae176bfeb0..6e5f88f20482 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -47,6 +47,7 @@
 #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"
@@ -172,6 +173,21 @@ 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)
 {
@@ -228,8 +244,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
         * This also validates that any existing fb inherited from the
         * BIOS is suitable for own access.
         */
-       vma = intel_fb_pin_to_ggtt(&fb->base, false,
-                                  &view, false, &flags);
+       vma = intel_fb_pin_to_ggtt(&fb->base, &view,
+                                  intel_fbdev_min_alignment(&fb->base), 0,
+                                  false, &flags);
        if (IS_ERR(vma)) {
                ret = PTR_ERR(vma);
                goto out_unlock;
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c 
b/drivers/gpu/drm/i915/display/intel_sprite.c
index e1c907f601da..6f9ae83b095c 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -1622,6 +1622,8 @@ intel_sprite_plane_create(struct drm_i915_private 
*dev_priv,
                }
        }
 
+       plane->min_alignment = intel_surf_alignment;
+
        if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
                supported_rotations =
                        DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 8a66b1002a74..7e4417459c41 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1680,11 +1680,12 @@ skl_check_main_ccs_coordinates(struct intel_plane_state 
*plane_state,
                               int main_x, int main_y, u32 main_offset,
                               int ccs_plane)
 {
+       struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
        const struct drm_framebuffer *fb = plane_state->hw.fb;
        int aux_x = plane_state->view.color_plane[ccs_plane].x;
        int aux_y = plane_state->view.color_plane[ccs_plane].y;
        u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
-       unsigned int alignment = intel_surf_alignment(fb, ccs_plane);
+       unsigned int alignment = plane->min_alignment(plane, fb, ccs_plane);
        int hsub;
        int vsub;
 
@@ -1728,7 +1729,7 @@ int skl_calc_main_surface_offset(const struct 
intel_plane_state *plane_state,
        const struct drm_framebuffer *fb = plane_state->hw.fb;
        int aux_plane = skl_main_to_aux_plane(fb, 0);
        u32 aux_offset = plane_state->view.color_plane[aux_plane].offset;
-       unsigned int alignment = intel_surf_alignment(fb, 0);
+       unsigned int alignment = plane->min_alignment(plane, fb, 0);
        int w = drm_rect_width(&plane_state->uapi.src) >> 16;
 
        intel_add_fb_offsets(x, y, plane_state, 0);
@@ -1784,7 +1785,7 @@ static int skl_check_main_surface(struct 
intel_plane_state *plane_state)
        int min_width = intel_plane_min_width(plane, fb, 0, rotation);
        int max_width = intel_plane_max_width(plane, fb, 0, rotation);
        int max_height = intel_plane_max_height(plane, fb, 0, rotation);
-       unsigned int alignment = intel_surf_alignment(fb, 0);
+       unsigned int alignment = plane->min_alignment(plane, fb, 0);
        int aux_plane = skl_main_to_aux_plane(fb, 0);
        u32 offset;
        int ret;
@@ -1873,7 +1874,7 @@ static int skl_check_nv12_aux_surface(struct 
intel_plane_state *plane_state)
 
        if (ccs_plane) {
                u32 aux_offset = 
plane_state->view.color_plane[ccs_plane].offset;
-               unsigned int alignment = intel_surf_alignment(fb, uv_plane);
+               unsigned int alignment = plane->min_alignment(plane, fb, 
uv_plane);
 
                if (offset > aux_offset)
                        offset = intel_plane_adjust_aligned_offset(&x, &y,
@@ -2430,6 +2431,8 @@ skl_universal_plane_create(struct drm_i915_private 
*dev_priv,
        else
                plane->max_stride = skl_plane_max_stride;
 
+       plane->min_alignment = intel_surf_alignment;
+
        if (DISPLAY_VER(dev_priv) >= 11) {
                plane->update_noarm = icl_plane_update_noarm;
                plane->update_arm = icl_plane_update_arm;
diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c 
b/drivers/gpu/drm/xe/display/xe_fb_pin.c
index a2f417209124..a807f869d39f 100644
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
@@ -334,8 +334,9 @@ static void __xe_unpin_fb_vma(struct i915_vma *vma)
 
 struct i915_vma *
 intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
-                    bool phys_cursor,
                     const struct i915_gtt_view *view,
+                    unsigned int alignment,
+                    unsigned int phys_alignment,
                     bool uses_fence,
                     unsigned long *out_flags)
 {
diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c 
b/drivers/gpu/drm/xe/display/xe_plane_initial.c
index e135b20962d9..5eccd6abb3ef 100644
--- a/drivers/gpu/drm/xe/display/xe_plane_initial.c
+++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c
@@ -210,8 +210,8 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
        intel_fb_fill_view(to_intel_framebuffer(fb),
                           plane_state->uapi.rotation, &plane_state->view);
 
-       vma = intel_fb_pin_to_ggtt(fb, false, &plane_state->view.gtt,
-                                  false, &plane_state->flags);
+       vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt,
+                                  0, 0, false, &plane_state->flags);
        if (IS_ERR(vma))
                goto nofb;
 
-- 
2.44.2

Reply via email to