drm/i915: Store the final plane stride in plane_state
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 11 Sep 2018 15:01:39 +0000 (18:01 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 12 Sep 2018 14:53:05 +0000 (17:53 +0300)
Let's store the final plane stride in the plane state. This avoids
having to pick between the normal vs. rotated stride during hardware
programming. And once we get GTT remapping the plane stride will
no longer match the fb stride so we'll need a place to store it
anyway.

v2: Keep checking fb->pitches[0] for cursor as later on we won't
    populate plane_state->color_plane[0].stride for invisible planes
    and we have been checking the cursor fb stride even for invisible
    planes
v3: s/betwen/between in commit msg (José)
v4: Check color_plane[0].stride instead of fb->pitches[0] in
    the skl_check_main_surface() X-tiling kludge

Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180911150139.23922-1-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_sprite.c

index f6828dc14cc96f2cd9e090ebdee1e0054737905e..3fc90db7ae979e9a1b1bd57559125d65ef441dc2 100644 (file)
@@ -2202,7 +2202,7 @@ u32 intel_fb_xy_to_linear(int x, int y,
 {
        const struct drm_framebuffer *fb = state->base.fb;
        unsigned int cpp = fb->format->cpp[plane];
-       unsigned int pitch = fb->pitches[plane];
+       unsigned int pitch = state->color_plane[plane].stride;
 
        return y * pitch + x * cpp;
 }
@@ -2259,11 +2259,11 @@ static u32 intel_adjust_tile_offset(int *x, int *y,
 static u32 intel_adjust_aligned_offset(int *x, int *y,
                                       const struct drm_framebuffer *fb, int plane,
                                       unsigned int rotation,
+                                      unsigned int pitch,
                                       u32 old_offset, u32 new_offset)
 {
        struct drm_i915_private *dev_priv = to_i915(fb->dev);
        unsigned int cpp = fb->format->cpp[plane];
-       unsigned int pitch = intel_fb_pitch(fb, plane, rotation);
 
        WARN_ON(new_offset > old_offset);
 
@@ -2305,6 +2305,7 @@ static u32 intel_plane_adjust_aligned_offset(int *x, int *y,
 {
        return intel_adjust_aligned_offset(x, y, state->base.fb, plane,
                                           state->base.rotation,
+                                          state->color_plane[plane].stride,
                                           old_offset, new_offset);
 }
 
@@ -2381,7 +2382,7 @@ static u32 intel_plane_compute_aligned_offset(int *x, int *y,
        struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
        const struct drm_framebuffer *fb = state->base.fb;
        unsigned int rotation = state->base.rotation;
-       int pitch = intel_fb_pitch(fb, plane, rotation);
+       int pitch = state->color_plane[plane].stride;
        u32 alignment;
 
        if (intel_plane->id == PLANE_CURSOR)
@@ -2408,6 +2409,7 @@ static int intel_fb_offset_to_xy(int *x, int *y,
 
        intel_adjust_aligned_offset(x, y,
                                    fb, plane, DRM_MODE_ROTATE_0,
+                                   fb->pitches[0],
                                    fb->offsets[plane], 0);
 
        return 0;
@@ -2854,6 +2856,9 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
        return;
 
 valid_fb:
+       intel_state->color_plane[0].stride =
+               intel_fb_pitch(fb, 0, intel_state->base.rotation);
+
        mutex_lock(&dev->struct_mutex);
        intel_state->vma =
                intel_pin_and_fence_fb_obj(fb,
@@ -3047,7 +3052,7 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
        if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
                int cpp = fb->format->cpp[0];
 
-               while ((x + w) * cpp > fb->pitches[0]) {
+               while ((x + w) * cpp > plane_state->color_plane[0].stride) {
                        if (offset == 0) {
                                DRM_DEBUG_KMS("Unable to find suitable display surface offset due to X-tiling\n");
                                return -EINVAL;
@@ -3170,6 +3175,9 @@ int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
        unsigned int rotation = plane_state->base.rotation;
        int ret;
 
+       plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
+       plane_state->color_plane[1].stride = intel_fb_pitch(fb, 1, rotation);
+
        if (rotation & DRM_MODE_REFLECT_X &&
            fb->modifier == DRM_FORMAT_MOD_LINEAR) {
                DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
@@ -3306,10 +3314,14 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *dev_priv =
                to_i915(plane_state->base.plane->dev);
+       const struct drm_framebuffer *fb = plane_state->base.fb;
+       unsigned int rotation = plane_state->base.rotation;
        int src_x = plane_state->base.src.x1 >> 16;
        int src_y = plane_state->base.src.y1 >> 16;
        u32 offset;
 
+       plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
+
        intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
 
        if (INTEL_GEN(dev_priv) >= 4)
@@ -3320,7 +3332,6 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
 
        /* HSW/BDW do this automagically in hardware */
        if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) {
-               unsigned int rotation = plane_state->base.rotation;
                int src_w = drm_rect_width(&plane_state->base.src) >> 16;
                int src_h = drm_rect_height(&plane_state->base.src) >> 16;
 
@@ -3344,7 +3355,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
                              const struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-       const struct drm_framebuffer *fb = plane_state->base.fb;
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
        u32 linear_offset;
        u32 dspcntr = plane_state->ctl;
@@ -3381,7 +3391,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
 
        I915_WRITE_FW(reg, dspcntr);
 
-       I915_WRITE_FW(DSPSTRIDE(i9xx_plane), fb->pitches[0]);
+       I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride);
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
                I915_WRITE_FW(DSPSURF(i9xx_plane),
                              intel_plane_ggtt_offset(plane_state) +
@@ -3491,16 +3501,16 @@ static void skl_detach_scalers(struct intel_crtc *intel_crtc)
        }
 }
 
-u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
-                    unsigned int rotation)
+u32 skl_plane_stride(const struct intel_plane_state *plane_state,
+                    int plane)
 {
-       u32 stride;
+       const struct drm_framebuffer *fb = plane_state->base.fb;
+       unsigned int rotation = plane_state->base.rotation;
+       u32 stride = plane_state->color_plane[plane].stride;
 
        if (plane >= fb->format->num_planes)
                return 0;
 
-       stride = intel_fb_pitch(fb, plane, rotation);
-
        /*
         * The stride is either expressed as a multiple of 64 bytes chunks for
         * linear buffers or in number of tiles for tiled buffers.
@@ -9671,6 +9681,7 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
                              struct intel_plane_state *plane_state)
 {
        const struct drm_framebuffer *fb = plane_state->base.fb;
+       unsigned int rotation = plane_state->base.rotation;
        int src_x, src_y;
        u32 offset;
        int ret;
@@ -9691,6 +9702,8 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
                return -EINVAL;
        }
 
+       plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
+
        src_x = plane_state->base.src_x >> 16;
        src_y = plane_state->base.src_y >> 16;
 
@@ -9719,12 +9732,10 @@ i845_cursor_max_stride(struct intel_plane *plane,
 static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
                           const struct intel_plane_state *plane_state)
 {
-       const struct drm_framebuffer *fb = plane_state->base.fb;
-
        return CURSOR_ENABLE |
                CURSOR_GAMMA_ENABLE |
                CURSOR_FORMAT_ARGB |
-               CURSOR_STRIDE(fb->pitches[0]);
+               CURSOR_STRIDE(plane_state->color_plane[0].stride);
 }
 
 static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state)
@@ -9760,6 +9771,9 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state,
                return -EINVAL;
        }
 
+       WARN_ON(plane_state->base.visible &&
+               plane_state->color_plane[0].stride != fb->pitches[0]);
+
        switch (fb->pitches[0]) {
        case 256:
        case 512:
@@ -9961,6 +9975,9 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
                return -EINVAL;
        }
 
+       WARN_ON(plane_state->base.visible &&
+               plane_state->color_plane[0].stride != fb->pitches[0]);
+
        if (fb->pitches[0] != plane_state->base.crtc_w * fb->format->cpp[0]) {
                DRM_DEBUG_KMS("Invalid cursor stride (%u) (cursor width %d)\n",
                              fb->pitches[0], plane_state->base.crtc_w);
index 0c7a046b4f26e1ed58c6be6790494c9be0b81db8..2e06f9831ff4f2ec4d3c99b5298618731c468d9d 100644 (file)
@@ -502,6 +502,12 @@ struct intel_plane_state {
 
        struct {
                u32 offset;
+               /*
+                * Plane stride in:
+                * bytes for 0/180 degree rotation
+                * pixels for 90/270 degree rotation
+                */
+               u32 stride;
                int x, y;
        } color_plane[2];
 
@@ -1653,8 +1659,8 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
 u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
                  const struct intel_plane_state *plane_state);
 u32 glk_color_ctl(const struct intel_plane_state *plane_state);
-u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
-                    unsigned int rotation);
+u32 skl_plane_stride(const struct intel_plane_state *plane_state,
+                    int plane);
 int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
                            struct intel_plane_state *plane_state);
 int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
index df0cf3d2ea983472e6045d47b2b0dcc39e1b6052..ee98c7bc2f9d7603247c4971041c10b20023a3d7 100644 (file)
@@ -259,9 +259,8 @@ skl_update_plane(struct intel_plane *plane,
        u32 plane_ctl = plane_state->ctl;
        const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
        u32 surf_addr = plane_state->color_plane[0].offset;
-       unsigned int rotation = plane_state->base.rotation;
-       u32 stride = skl_plane_stride(fb, 0, rotation);
-       u32 aux_stride = skl_plane_stride(fb, 1, rotation);
+       u32 stride = skl_plane_stride(plane_state, 0);
+       u32 aux_stride = skl_plane_stride(plane_state, 1);
        int crtc_x = plane_state->base.dst.x1;
        int crtc_y = plane_state->base.dst.y1;
        uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
@@ -592,7 +591,8 @@ vlv_update_plane(struct intel_plane *plane,
                I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
                I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
        }
-       I915_WRITE_FW(SPSTRIDE(pipe, plane_id), fb->pitches[0]);
+       I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
+                     plane_state->color_plane[0].stride);
        I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
 
        if (fb->modifier == I915_FORMAT_MOD_X_TILED)
@@ -754,7 +754,7 @@ ivb_update_plane(struct intel_plane *plane,
                I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
        }
 
-       I915_WRITE_FW(SPRSTRIDE(pipe), fb->pitches[0]);
+       I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
        I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
 
        /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
@@ -926,7 +926,7 @@ g4x_update_plane(struct intel_plane *plane,
                I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
        }
 
-       I915_WRITE_FW(DVSSTRIDE(pipe), fb->pitches[0]);
+       I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
        I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
 
        if (fb->modifier == I915_FORMAT_MOD_X_TILED)