From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> 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@xxxxxxxxx> Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_display.c | 47 ++++++++++++++++++++++++------------ drivers/gpu/drm/i915/intel_drv.h | 10 ++++++-- drivers/gpu/drm/i915/intel_sprite.c | 12 ++++----- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c0dd62a617e3..ee6090c4b7f0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2203,7 +2203,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; } @@ -2260,11 +2260,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); @@ -2306,6 +2306,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); } @@ -2382,7 +2383,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) @@ -2409,6 +2410,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; @@ -2855,6 +2857,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, @@ -3048,7 +3053,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; @@ -3171,6 +3176,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"); @@ -3307,10 +3315,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) @@ -3321,7 +3333,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; @@ -3345,7 +3356,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; @@ -3382,7 +3392,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) + @@ -3492,16 +3502,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. @@ -9672,6 +9682,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; @@ -9692,6 +9703,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; @@ -9720,12 +9733,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) @@ -9761,6 +9772,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: @@ -9962,6 +9976,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); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9e16bdcffc84..f17c2bb8c4ef 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -503,6 +503,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]; @@ -1655,8 +1661,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); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index df0cf3d2ea98..ee98c7bc2f9d 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -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) -- 2.16.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx