Commit df79cf44 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Store the final plane stride in plane_state

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: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180911150139.23922-1-ville.syrjala@linux.intel.com
parent c11ada07
...@@ -2202,7 +2202,7 @@ u32 intel_fb_xy_to_linear(int x, int y, ...@@ -2202,7 +2202,7 @@ u32 intel_fb_xy_to_linear(int x, int y,
{ {
const struct drm_framebuffer *fb = state->base.fb; const struct drm_framebuffer *fb = state->base.fb;
unsigned int cpp = fb->format->cpp[plane]; 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; return y * pitch + x * cpp;
} }
...@@ -2259,11 +2259,11 @@ static u32 intel_adjust_tile_offset(int *x, int *y, ...@@ -2259,11 +2259,11 @@ static u32 intel_adjust_tile_offset(int *x, int *y,
static u32 intel_adjust_aligned_offset(int *x, int *y, static u32 intel_adjust_aligned_offset(int *x, int *y,
const struct drm_framebuffer *fb, int plane, const struct drm_framebuffer *fb, int plane,
unsigned int rotation, unsigned int rotation,
unsigned int pitch,
u32 old_offset, u32 new_offset) u32 old_offset, u32 new_offset)
{ {
struct drm_i915_private *dev_priv = to_i915(fb->dev); struct drm_i915_private *dev_priv = to_i915(fb->dev);
unsigned int cpp = fb->format->cpp[plane]; unsigned int cpp = fb->format->cpp[plane];
unsigned int pitch = intel_fb_pitch(fb, plane, rotation);
WARN_ON(new_offset > old_offset); WARN_ON(new_offset > old_offset);
...@@ -2305,6 +2305,7 @@ static u32 intel_plane_adjust_aligned_offset(int *x, int *y, ...@@ -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, return intel_adjust_aligned_offset(x, y, state->base.fb, plane,
state->base.rotation, state->base.rotation,
state->color_plane[plane].stride,
old_offset, new_offset); old_offset, new_offset);
} }
...@@ -2381,7 +2382,7 @@ static u32 intel_plane_compute_aligned_offset(int *x, int *y, ...@@ -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); struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
const struct drm_framebuffer *fb = state->base.fb; const struct drm_framebuffer *fb = state->base.fb;
unsigned int rotation = state->base.rotation; unsigned int rotation = state->base.rotation;
int pitch = intel_fb_pitch(fb, plane, rotation); int pitch = state->color_plane[plane].stride;
u32 alignment; u32 alignment;
if (intel_plane->id == PLANE_CURSOR) if (intel_plane->id == PLANE_CURSOR)
...@@ -2408,6 +2409,7 @@ static int intel_fb_offset_to_xy(int *x, int *y, ...@@ -2408,6 +2409,7 @@ static int intel_fb_offset_to_xy(int *x, int *y,
intel_adjust_aligned_offset(x, y, intel_adjust_aligned_offset(x, y,
fb, plane, DRM_MODE_ROTATE_0, fb, plane, DRM_MODE_ROTATE_0,
fb->pitches[0],
fb->offsets[plane], 0); fb->offsets[plane], 0);
return 0; return 0;
...@@ -2854,6 +2856,9 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, ...@@ -2854,6 +2856,9 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
return; return;
valid_fb: valid_fb:
intel_state->color_plane[0].stride =
intel_fb_pitch(fb, 0, intel_state->base.rotation);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
intel_state->vma = intel_state->vma =
intel_pin_and_fence_fb_obj(fb, intel_pin_and_fence_fb_obj(fb,
...@@ -3047,7 +3052,7 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state, ...@@ -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) { if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
int cpp = fb->format->cpp[0]; 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) { if (offset == 0) {
DRM_DEBUG_KMS("Unable to find suitable display surface offset due to X-tiling\n"); DRM_DEBUG_KMS("Unable to find suitable display surface offset due to X-tiling\n");
return -EINVAL; return -EINVAL;
...@@ -3170,6 +3175,9 @@ int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, ...@@ -3170,6 +3175,9 @@ int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
unsigned int rotation = plane_state->base.rotation; unsigned int rotation = plane_state->base.rotation;
int ret; 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 && if (rotation & DRM_MODE_REFLECT_X &&
fb->modifier == DRM_FORMAT_MOD_LINEAR) { fb->modifier == DRM_FORMAT_MOD_LINEAR) {
DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n"); 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) ...@@ -3306,10 +3314,14 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
to_i915(plane_state->base.plane->dev); 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_x = plane_state->base.src.x1 >> 16;
int src_y = plane_state->base.src.y1 >> 16; int src_y = plane_state->base.src.y1 >> 16;
u32 offset; 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); intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
if (INTEL_GEN(dev_priv) >= 4) if (INTEL_GEN(dev_priv) >= 4)
...@@ -3320,7 +3332,6 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) ...@@ -3320,7 +3332,6 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
/* HSW/BDW do this automagically in hardware */ /* HSW/BDW do this automagically in hardware */
if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) { 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_w = drm_rect_width(&plane_state->base.src) >> 16;
int src_h = drm_rect_height(&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, ...@@ -3344,7 +3355,6 @@ static void i9xx_update_plane(struct intel_plane *plane,
const struct intel_plane_state *plane_state) const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 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; enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
u32 linear_offset; u32 linear_offset;
u32 dspcntr = plane_state->ctl; u32 dspcntr = plane_state->ctl;
...@@ -3381,7 +3391,7 @@ static void i9xx_update_plane(struct intel_plane *plane, ...@@ -3381,7 +3391,7 @@ static void i9xx_update_plane(struct intel_plane *plane,
I915_WRITE_FW(reg, dspcntr); 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)) { if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
I915_WRITE_FW(DSPSURF(i9xx_plane), I915_WRITE_FW(DSPSURF(i9xx_plane),
intel_plane_ggtt_offset(plane_state) + intel_plane_ggtt_offset(plane_state) +
...@@ -3491,16 +3501,16 @@ static void skl_detach_scalers(struct intel_crtc *intel_crtc) ...@@ -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, u32 skl_plane_stride(const struct intel_plane_state *plane_state,
unsigned int rotation) 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) if (plane >= fb->format->num_planes)
return 0; return 0;
stride = intel_fb_pitch(fb, plane, rotation);
/* /*
* The stride is either expressed as a multiple of 64 bytes chunks for * The stride is either expressed as a multiple of 64 bytes chunks for
* linear buffers or in number of tiles for tiled buffers. * 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, ...@@ -9671,6 +9681,7 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state) struct intel_plane_state *plane_state)
{ {
const struct drm_framebuffer *fb = plane_state->base.fb; const struct drm_framebuffer *fb = plane_state->base.fb;
unsigned int rotation = plane_state->base.rotation;
int src_x, src_y; int src_x, src_y;
u32 offset; u32 offset;
int ret; int ret;
...@@ -9691,6 +9702,8 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state, ...@@ -9691,6 +9702,8 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
return -EINVAL; return -EINVAL;
} }
plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
src_x = plane_state->base.src_x >> 16; src_x = plane_state->base.src_x >> 16;
src_y = plane_state->base.src_y >> 16; src_y = plane_state->base.src_y >> 16;
...@@ -9719,12 +9732,10 @@ i845_cursor_max_stride(struct intel_plane *plane, ...@@ -9719,12 +9732,10 @@ i845_cursor_max_stride(struct intel_plane *plane,
static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state, static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state) const struct intel_plane_state *plane_state)
{ {
const struct drm_framebuffer *fb = plane_state->base.fb;
return CURSOR_ENABLE | return CURSOR_ENABLE |
CURSOR_GAMMA_ENABLE | CURSOR_GAMMA_ENABLE |
CURSOR_FORMAT_ARGB | 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) 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, ...@@ -9760,6 +9771,9 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state,
return -EINVAL; return -EINVAL;
} }
WARN_ON(plane_state->base.visible &&
plane_state->color_plane[0].stride != fb->pitches[0]);
switch (fb->pitches[0]) { switch (fb->pitches[0]) {
case 256: case 256:
case 512: case 512:
...@@ -9961,6 +9975,9 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, ...@@ -9961,6 +9975,9 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
return -EINVAL; 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]) { if (fb->pitches[0] != plane_state->base.crtc_w * fb->format->cpp[0]) {
DRM_DEBUG_KMS("Invalid cursor stride (%u) (cursor width %d)\n", DRM_DEBUG_KMS("Invalid cursor stride (%u) (cursor width %d)\n",
fb->pitches[0], plane_state->base.crtc_w); fb->pitches[0], plane_state->base.crtc_w);
......
...@@ -502,6 +502,12 @@ struct intel_plane_state { ...@@ -502,6 +502,12 @@ struct intel_plane_state {
struct { struct {
u32 offset; u32 offset;
/*
* Plane stride in:
* bytes for 0/180 degree rotation
* pixels for 90/270 degree rotation
*/
u32 stride;
int x, y; int x, y;
} color_plane[2]; } color_plane[2];
...@@ -1653,8 +1659,8 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, ...@@ -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, u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state); const struct intel_plane_state *plane_state);
u32 glk_color_ctl(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, u32 skl_plane_stride(const struct intel_plane_state *plane_state,
unsigned int rotation); int plane);
int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state); struct intel_plane_state *plane_state);
int i9xx_check_plane_surface(struct intel_plane_state *plane_state); int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
......
...@@ -259,9 +259,8 @@ skl_update_plane(struct intel_plane *plane, ...@@ -259,9 +259,8 @@ skl_update_plane(struct intel_plane *plane,
u32 plane_ctl = plane_state->ctl; u32 plane_ctl = plane_state->ctl;
const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
u32 surf_addr = plane_state->color_plane[0].offset; u32 surf_addr = plane_state->color_plane[0].offset;
unsigned int rotation = plane_state->base.rotation; u32 stride = skl_plane_stride(plane_state, 0);
u32 stride = skl_plane_stride(fb, 0, rotation); u32 aux_stride = skl_plane_stride(plane_state, 1);
u32 aux_stride = skl_plane_stride(fb, 1, rotation);
int crtc_x = plane_state->base.dst.x1; int crtc_x = plane_state->base.dst.x1;
int crtc_y = plane_state->base.dst.y1; int crtc_y = plane_state->base.dst.y1;
uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
...@@ -592,7 +591,8 @@ vlv_update_plane(struct intel_plane *plane, ...@@ -592,7 +591,8 @@ vlv_update_plane(struct intel_plane *plane,
I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value); I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask); 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); I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
if (fb->modifier == I915_FORMAT_MOD_X_TILED) if (fb->modifier == I915_FORMAT_MOD_X_TILED)
...@@ -754,7 +754,7 @@ ivb_update_plane(struct intel_plane *plane, ...@@ -754,7 +754,7 @@ ivb_update_plane(struct intel_plane *plane,
I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask); 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); I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
...@@ -926,7 +926,7 @@ g4x_update_plane(struct intel_plane *plane, ...@@ -926,7 +926,7 @@ g4x_update_plane(struct intel_plane *plane,
I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask); 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); I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
if (fb->modifier == I915_FORMAT_MOD_X_TILED) if (fb->modifier == I915_FORMAT_MOD_X_TILED)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment