[Intel-gfx] [PATCH 19/23] drm/i915: Prepare atomic plane check for bigjoiner planes
Maarten Lankhorst
maarten.lankhorst at linux.intel.com
Fri Sep 20 11:42:31 UTC 2019
A lot of delta, the main difference is that the master_plane_state is
not the same plane_state as being written to.
We read all properties like color key, crtc, fb, rotation from the
master_plane_state and coordinate properties.
The coordinate properties are different between the 2 bigjoiner planes,
as one gets the left and the other gets the right side.
Fortunately the drm core already has a src and dst rect, so we write
those for each plane separately.
In case of cursor, we don't use the clipped coordinates, but the raw
source coordinates from the master_plane_state instead.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
drivers/gpu/drm/i915/display/intel_atomic.c | 7 +-
.../gpu/drm/i915/display/intel_atomic_plane.c | 88 +++++++-
.../gpu/drm/i915/display/intel_atomic_plane.h | 8 +-
drivers/gpu/drm/i915/display/intel_display.c | 213 ++++++++++--------
drivers/gpu/drm/i915/display/intel_display.h | 5 +-
.../drm/i915/display/intel_display_types.h | 1 +
drivers/gpu/drm/i915/display/intel_sprite.c | 71 +++---
drivers/gpu/drm/i915/display/intel_sprite.h | 6 +-
8 files changed, 258 insertions(+), 141 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 0db04064c86e..a8f34254cd2a 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -297,9 +297,10 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta
return;
/* set scaler mode */
- if (plane_state && plane_state->base.fb &&
- plane_state->base.fb->format->is_yuv &&
- plane_state->base.fb->format->num_planes > 1) {
+ if (plane_state && (plane_state->linked_plane ||
+ (!plane_state->bigjoiner_slave && plane_state->base.fb &&
+ plane_state->base.fb->format->is_yuv &&
+ plane_state->base.fb->format->num_planes > 1))) {
struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
if (IS_GEN(dev_priv, 9) &&
!IS_GEMINILAKE(dev_priv)) {
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 5db091e4ad6a..a0c1d1696c8c 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -115,10 +115,11 @@ intel_plane_destroy_state(struct drm_plane *plane,
drm_atomic_helper_plane_destroy_state(plane, state);
}
-unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *plane_state)
+static unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
+ const struct intel_plane_state *plane_state)
{
- const struct drm_framebuffer *fb = plane_state->base.fb;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
unsigned int cpp;
if (!plane_state->base.visible)
@@ -143,8 +144,12 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
const struct intel_plane_state *old_plane_state,
struct intel_plane_state *new_plane_state)
{
+ const struct intel_plane_state *new_master_plane_state = new_plane_state;
+ const struct intel_plane_state *old_master_plane_state = old_plane_state;
struct intel_plane *plane = to_intel_plane(new_plane_state->base.plane);
- const struct drm_framebuffer *fb = new_plane_state->base.fb;
+ const struct drm_framebuffer *fb;
+ struct intel_atomic_state *state =
+ to_intel_atomic_state(new_plane_state->base.state);
int ret;
new_crtc_state->active_planes &= ~BIT(plane->id);
@@ -153,10 +158,21 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
new_crtc_state->data_rate[plane->id] = 0;
new_plane_state->base.visible = false;
- if (!new_plane_state->base.crtc && !old_plane_state->base.crtc)
+ if (old_plane_state->bigjoiner_slave)
+ old_master_plane_state =
+ intel_atomic_get_old_plane_state(state,
+ old_plane_state->bigjoiner_plane);
+
+ if (new_plane_state->bigjoiner_slave)
+ new_master_plane_state =
+ intel_atomic_get_new_plane_state(state,
+ new_plane_state->bigjoiner_plane);
+
+ if (!new_master_plane_state->base.crtc && !old_master_plane_state->base.crtc)
return 0;
- ret = plane->check_plane(new_crtc_state, new_plane_state);
+ ret = plane->check_plane(new_crtc_state,
+ new_master_plane_state, new_plane_state);
if (ret)
return ret;
@@ -164,6 +180,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
if (new_plane_state->base.visible)
new_crtc_state->active_planes |= BIT(plane->id);
+ fb = new_master_plane_state->base.fb;
if (new_plane_state->base.visible &&
drm_format_info_is_yuv_semiplanar(fb->format))
new_crtc_state->nv12_planes |= BIT(plane->id);
@@ -176,10 +193,11 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
new_crtc_state->update_planes |= BIT(plane->id);
new_crtc_state->data_rate[plane->id] =
- intel_plane_data_rate(new_crtc_state, new_plane_state);
+ intel_plane_data_rate(new_crtc_state, new_master_plane_state, new_plane_state);
return intel_plane_atomic_calc_changes(old_crtc_state, new_crtc_state,
- old_plane_state, new_plane_state);
+ old_plane_state, new_master_plane_state,
+ new_plane_state);
}
struct intel_crtc *
@@ -441,6 +459,60 @@ void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
}
}
+
+int intel_atomic_plane_check_scaling(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state,
+ int min_scale, int max_scale)
+{
+ struct drm_framebuffer *fb = master_plane_state->base.fb;
+ struct drm_rect *src = &plane_state->base.src;
+ struct drm_rect *dst = &plane_state->base.dst;
+ unsigned int rotation = master_plane_state->base.rotation;
+ struct drm_rect clip = {};
+ int hscale, vscale;
+
+ *src = drm_plane_state_src(&master_plane_state->base);
+ *dst = drm_plane_state_dest(&master_plane_state->base);
+
+ if (!fb) {
+ plane_state->base.visible = false;
+ return 0;
+ }
+
+ drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
+
+ /* Check scaling */
+ hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+ vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
+ if (hscale < 0 || vscale < 0) {
+ DRM_DEBUG_KMS("Invalid scaling of plane\n");
+ drm_rect_debug_print("src: ", src, true);
+ drm_rect_debug_print("dst: ", dst, false);
+ return -ERANGE;
+ }
+
+ if (crtc_state->hw.enable) {
+ clip.x2 = crtc_state->pipe_src_w;
+ clip.y2 = crtc_state->pipe_src_h;
+ }
+
+ /* right side of the image is on the slave crtc, adjust dst to match */
+ if (crtc_state->bigjoiner_slave)
+ drm_rect_translate(dst, -crtc_state->pipe_src_w, 0);
+
+ /*
+ * FIXME: This might need further adjustment for seamless scaling
+ * with phase information, for the 2p2 and 2p1 scenarios.
+ */
+
+ plane_state->base.visible = drm_rect_clip_scaled(src, dst, &clip);
+
+ drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+
+ return 0;
+}
+
const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
.prepare_fb = intel_prepare_plane_fb,
.cleanup_fb = intel_cleanup_plane_fb,
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 1cffda2b50b5..c98ccf8114c3 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -18,8 +18,6 @@ struct intel_plane_state;
extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
-unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *plane_state);
void intel_update_plane(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
@@ -43,10 +41,16 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *crtc_state,
const struct intel_plane_state *old_plane_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state);
struct intel_crtc *
intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
const struct intel_plane_state *old_plane_state,
const struct intel_plane_state *new_plane_state);
+int intel_atomic_plane_check_scaling(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state,
+ int min_scale, int max_scale);
+
#endif /* __INTEL_ATOMIC_PLANE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 7f86c358cf45..690c3d10ce44 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2289,12 +2289,13 @@ static u32 intel_adjust_aligned_offset(int *x, int *y,
* the x/y offsets.
*/
static u32 intel_plane_adjust_aligned_offset(int *x, int *y,
+ const struct intel_plane_state *master_plane_state,
const struct intel_plane_state *state,
int color_plane,
u32 old_offset, u32 new_offset)
{
- return intel_adjust_aligned_offset(x, y, state->base.fb, color_plane,
- state->base.rotation,
+ return intel_adjust_aligned_offset(x, y, master_plane_state->base.fb, color_plane,
+ master_plane_state->base.rotation,
state->color_plane[color_plane].stride,
old_offset, new_offset);
}
@@ -2365,14 +2366,15 @@ static u32 intel_compute_aligned_offset(struct drm_i915_private *dev_priv,
}
static u32 intel_plane_compute_aligned_offset(int *x, int *y,
- const struct intel_plane_state *state,
+ const struct intel_plane_state *master_plane_state,
+ const struct intel_plane_state *plane_state,
int color_plane)
{
- struct intel_plane *intel_plane = to_intel_plane(state->base.plane);
+ struct intel_plane *intel_plane = to_intel_plane(plane_state->base.plane);
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 = state->color_plane[color_plane].stride;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
+ unsigned int rotation = master_plane_state->base.rotation;
+ int pitch = plane_state->color_plane[color_plane].stride;
u32 alignment;
if (intel_plane->id == PLANE_CURSOR)
@@ -2594,11 +2596,12 @@ bool intel_plane_can_remap(const struct intel_plane_state *plane_state)
return true;
}
-static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
+static bool intel_plane_needs_remap(const struct intel_plane_state *master_plane_state,
+ const struct intel_plane_state *plane_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
- const struct drm_framebuffer *fb = plane_state->base.fb;
- unsigned int rotation = plane_state->base.rotation;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
+ unsigned int rotation = master_plane_state->base.rotation;
u32 stride, max_stride;
/*
@@ -2608,7 +2611,7 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
if (!plane_state->base.visible)
return false;
- if (!intel_plane_can_remap(plane_state))
+ if (!intel_plane_can_remap(master_plane_state))
return false;
/*
@@ -2788,14 +2791,15 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
}
static void
-intel_plane_remap_gtt(struct intel_plane_state *plane_state)
+intel_plane_remap_gtt(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv =
to_i915(plane_state->base.plane->dev);
- struct drm_framebuffer *fb = plane_state->base.fb;
+ struct drm_framebuffer *fb = master_plane_state->base.fb;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct intel_rotation_info *info = &plane_state->view.rotated;
- unsigned int rotation = plane_state->base.rotation;
+ unsigned int rotation = master_plane_state->base.rotation;
int i, num_planes = fb->format->num_planes;
unsigned int tile_size = intel_tile_size(dev_priv);
unsigned int src_x, src_y;
@@ -2901,11 +2905,12 @@ intel_plane_remap_gtt(struct intel_plane_state *plane_state)
}
static int
-intel_plane_compute_gtt(struct intel_plane_state *plane_state)
+intel_plane_compute_gtt(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state)
{
const struct intel_framebuffer *fb =
- to_intel_framebuffer(plane_state->base.fb);
- unsigned int rotation = plane_state->base.rotation;
+ to_intel_framebuffer(master_plane_state->base.fb);
+ unsigned int rotation = master_plane_state->base.rotation;
int i, num_planes;
if (!fb)
@@ -2913,8 +2918,8 @@ intel_plane_compute_gtt(struct intel_plane_state *plane_state)
num_planes = fb->base.format->num_planes;
- if (intel_plane_needs_remap(plane_state)) {
- intel_plane_remap_gtt(plane_state);
+ if (intel_plane_needs_remap(master_plane_state, plane_state)) {
+ intel_plane_remap_gtt(master_plane_state, plane_state);
/*
* Sometimes even remapping can't overcome
@@ -2922,7 +2927,7 @@ intel_plane_compute_gtt(struct intel_plane_state *plane_state)
* big plane sizes and suitably misaligned
* offsets.
*/
- return intel_plane_check_stride(plane_state);
+ return intel_plane_check_stride(master_plane_state, plane_state);
}
intel_fill_fb_ggtt_view(&plane_state->view, &fb->base, rotation);
@@ -2946,7 +2951,7 @@ intel_plane_compute_gtt(struct intel_plane_state *plane_state)
fb->base.width << 16, fb->base.height << 16,
DRM_MODE_ROTATE_270);
- return intel_plane_check_stride(plane_state);
+ return intel_plane_check_stride(master_plane_state, plane_state);
}
static int i9xx_format_to_fourcc(int format)
@@ -3363,10 +3368,11 @@ static int icl_max_plane_height(void)
return 4320;
}
-static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
+static bool skl_check_main_ccs_coordinates(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state,
int main_x, int main_y, u32 main_offset)
{
- const struct drm_framebuffer *fb = plane_state->base.fb;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
int hsub = fb->format->hsub;
int vsub = fb->format->vsub;
int aux_x = plane_state->color_plane[1].x;
@@ -3385,7 +3391,7 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
x = aux_x / hsub;
y = aux_y / vsub;
- aux_offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 1,
+ aux_offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 1,
aux_offset, aux_offset - alignment);
aux_x = x * hsub + aux_x % hsub;
aux_y = y * vsub + aux_y % vsub;
@@ -3401,11 +3407,12 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
return true;
}
-static int skl_check_main_surface(struct intel_plane_state *plane_state)
+static int skl_check_main_surface(const struct intel_plane_state *master_plane_state,
+ 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;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
+ unsigned int rotation = master_plane_state->base.rotation;
int x = plane_state->base.src.x1 >> 16;
int y = plane_state->base.src.y1 >> 16;
int w = drm_rect_width(&plane_state->base.src) >> 16;
@@ -3433,7 +3440,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
}
intel_add_fb_offsets(&x, &y, plane_state, 0);
- offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 0);
+ offset = intel_plane_compute_aligned_offset(&x, &y, master_plane_state, plane_state, 0);
alignment = intel_surf_alignment(fb, 0);
/*
@@ -3442,7 +3449,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
* sure that is what we will get.
*/
if (offset > aux_offset)
- offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
+ offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,
offset, aux_offset & ~(alignment - 1));
/*
@@ -3460,7 +3467,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
return -EINVAL;
}
- offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
+ offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,
offset, offset - alignment);
}
}
@@ -3470,11 +3477,11 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
* they match with the main surface x/y offsets.
*/
if (is_ccs_modifier(fb->modifier)) {
- while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset)) {
+ while (!skl_check_main_ccs_coordinates(master_plane_state, plane_state, x, y, offset)) {
if (offset == 0)
break;
- offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
+ offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,
offset, offset - alignment);
}
@@ -3499,10 +3506,11 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
return 0;
}
-static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
+static int skl_check_nv12_aux_surface(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state)
{
- const struct drm_framebuffer *fb = plane_state->base.fb;
- unsigned int rotation = plane_state->base.rotation;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
+ unsigned int rotation = master_plane_state->base.rotation;
int max_width = skl_max_plane_width(fb, 1, rotation);
int max_height = 4096;
int x = plane_state->base.src.x1 >> 17;
@@ -3512,7 +3520,7 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
u32 offset;
intel_add_fb_offsets(&x, &y, plane_state, 1);
- offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 1);
+ offset = intel_plane_compute_aligned_offset(&x, &y, master_plane_state, plane_state, 1);
/* FIXME not quite sure how/if these apply to the chroma plane */
if (w > max_width || h > max_height) {
@@ -3528,7 +3536,8 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
return 0;
}
-static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
+static int skl_check_ccs_aux_surface(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->base.fb;
int src_x = plane_state->base.src.x1 >> 16;
@@ -3540,7 +3549,7 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
u32 offset;
intel_add_fb_offsets(&x, &y, plane_state, 1);
- offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 1);
+ offset = intel_plane_compute_aligned_offset(&x, &y, master_plane_state, plane_state, 1);
plane_state->color_plane[1].offset = offset;
plane_state->color_plane[1].x = x * hsub + src_x % hsub;
@@ -3549,12 +3558,13 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
return 0;
}
-int skl_check_plane_surface(struct intel_plane_state *plane_state)
+int skl_check_plane_surface(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state)
{
- const struct drm_framebuffer *fb = plane_state->base.fb;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
int ret;
- ret = intel_plane_compute_gtt(plane_state);
+ ret = intel_plane_compute_gtt(master_plane_state, plane_state);
if (ret)
return ret;
@@ -3566,11 +3576,11 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
* the main surface setup depends on it.
*/
if (drm_format_info_is_yuv_semiplanar(fb->format)) {
- ret = skl_check_nv12_aux_surface(plane_state);
+ ret = skl_check_nv12_aux_surface(master_plane_state, plane_state);
if (ret)
return ret;
} else if (is_ccs_modifier(fb->modifier)) {
- ret = skl_check_ccs_aux_surface(plane_state);
+ ret = skl_check_ccs_aux_surface(master_plane_state, plane_state);
if (ret)
return ret;
} else {
@@ -3579,11 +3589,7 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
plane_state->color_plane[1].y = 0;
}
- ret = skl_check_main_surface(plane_state);
- if (ret)
- return ret;
-
- return 0;
+ return skl_check_main_surface(master_plane_state, plane_state);
}
unsigned int
@@ -3694,7 +3700,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
u32 offset;
int ret;
- ret = intel_plane_compute_gtt(plane_state);
+ ret = intel_plane_compute_gtt(plane_state, plane_state);
if (ret)
return ret;
@@ -3708,6 +3714,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
if (INTEL_GEN(dev_priv) >= 4)
offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
+ plane_state,
plane_state, 0);
else
offset = 0;
@@ -3759,6 +3766,7 @@ static bool i9xx_plane_has_windowing(struct intel_plane *plane)
static int
i9xx_plane_check(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
@@ -3784,7 +3792,7 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
if (!plane_state->base.visible)
return 0;
- ret = intel_plane_check_src_coordinates(plane_state);
+ ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
if (ret)
return ret;
@@ -5549,12 +5557,13 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
* error - requested scaling cannot be supported or other error condition
*/
static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
struct intel_plane *intel_plane =
to_intel_plane(plane_state->base.plane);
struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
- struct drm_framebuffer *fb = plane_state->base.fb;
+ struct drm_framebuffer *fb = master_plane_state->base.fb;
int ret;
bool force_detach = !fb || !plane_state->base.visible;
bool need_scaler = false;
@@ -5577,7 +5586,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
return ret;
/* check colorkey */
- if (plane_state->ckey.flags) {
+ if (master_plane_state->ckey.flags) {
DRM_DEBUG_KMS("[PLANE:%d:%s] scaling with color key not allowed",
intel_plane->base.base.id,
intel_plane->base.name);
@@ -10662,11 +10671,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
return active;
}
-static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
+static u32 intel_cursor_base(const struct intel_plane_state *master_plane_state,
+ const 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;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
const struct drm_i915_gem_object *obj = intel_fb_obj(fb);
u32 base;
@@ -10679,19 +10689,24 @@ static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
/* ILK+ do this automagically */
if (HAS_GMCH(dev_priv) &&
- plane_state->base.rotation & DRM_MODE_ROTATE_180)
- base += (plane_state->base.crtc_h *
- plane_state->base.crtc_w - 1) * fb->format->cpp[0];
+ master_plane_state->base.rotation & DRM_MODE_ROTATE_180)
+ base += (master_plane_state->base.crtc_h *
+ master_plane_state->base.crtc_w - 1) * fb->format->cpp[0];
return base;
}
-static u32 intel_cursor_position(const struct intel_plane_state *plane_state)
+static u32 intel_cursor_position(const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
+ const struct intel_plane_state *plane_state)
{
- int x = plane_state->base.crtc_x;
- int y = plane_state->base.crtc_y;
+ int x = master_plane_state->base.crtc_x;
+ int y = master_plane_state->base.crtc_y;
u32 pos = 0;
+ if (plane_state->bigjoiner_slave)
+ x -= crtc_state->pipe_src_w;
+
if (x < 0) {
pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
x = -x;
@@ -10718,13 +10733,14 @@ static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state)
height > 0 && height <= config->cursor_height;
}
-static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
+static int intel_cursor_check_surface(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state)
{
int src_x, src_y;
u32 offset;
int ret;
- ret = intel_plane_compute_gtt(plane_state);
+ ret = intel_plane_compute_gtt(master_plane_state, plane_state);
if (ret)
return ret;
@@ -10736,6 +10752,7 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
+ master_plane_state,
plane_state, 0);
if (src_x != 0 || src_y != 0) {
@@ -10749,6 +10766,7 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
}
static int intel_check_cursor(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -10759,22 +10777,21 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
return -EINVAL;
}
- ret = drm_atomic_helper_check_plane_state(&plane_state->base,
- &crtc_state->uapi,
- DRM_PLANE_HELPER_NO_SCALING,
- DRM_PLANE_HELPER_NO_SCALING,
- true, true);
+ ret = intel_atomic_plane_check_scaling(crtc_state, master_plane_state,
+ plane_state,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING);
if (ret)
return ret;
- ret = intel_cursor_check_surface(plane_state);
+ ret = intel_cursor_check_surface(master_plane_state, plane_state);
if (ret)
return ret;
if (!plane_state->base.visible)
return 0;
- ret = intel_plane_check_src_coordinates(plane_state);
+ ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
if (ret)
return ret;
@@ -10819,12 +10836,13 @@ static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state)
}
static int i845_check_cursor(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
- const struct drm_framebuffer *fb = plane_state->base.fb;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
int ret;
- ret = intel_check_cursor(crtc_state, plane_state);
+ ret = intel_check_cursor(crtc_state, master_plane_state, plane_state);
if (ret)
return ret;
@@ -10877,8 +10895,8 @@ static void i845_update_cursor(struct intel_plane *plane,
size = (height << 12) | width;
- base = intel_cursor_base(plane_state);
- pos = intel_cursor_position(plane_state);
+ base = intel_cursor_base(plane_state, plane_state);
+ pos = intel_cursor_position(crtc_state, plane_state, plane_state);
}
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
@@ -11032,15 +11050,16 @@ static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state)
}
static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
- const struct drm_framebuffer *fb = plane_state->base.fb;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
enum pipe pipe = plane->pipe;
int ret;
- ret = intel_check_cursor(crtc_state, plane_state);
+ ret = intel_check_cursor(crtc_state, master_plane_state, plane_state);
if (ret)
return ret;
@@ -11049,17 +11068,17 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
return 0;
/* Check for which cursor types we support */
- if (!i9xx_cursor_size_ok(plane_state)) {
+ if (!i9xx_cursor_size_ok(master_plane_state)) {
DRM_DEBUG("Cursor dimension %dx%d not supported\n",
- plane_state->base.crtc_w,
- plane_state->base.crtc_h);
+ master_plane_state->base.crtc_w,
+ master_plane_state->base.crtc_h);
return -EINVAL;
}
WARN_ON(plane_state->base.visible &&
- plane_state->color_plane[0].stride != fb->pitches[0]);
+ master_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] != master_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);
return -EINVAL;
@@ -11076,19 +11095,20 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
* Refuse the put the cursor into that compromised position.
*/
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_C &&
- plane_state->base.visible && plane_state->base.crtc_x < 0) {
+ plane_state->base.visible && master_plane_state->base.crtc_x < 0) {
DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
return -EINVAL;
}
- plane_state->ctl = i9xx_cursor_ctl(crtc_state, plane_state);
+ plane_state->ctl = i9xx_cursor_ctl(crtc_state, master_plane_state);
return 0;
}
-static void i9xx_update_cursor(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *plane_state)
+static void i9xx_update_cursor_slave(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
+ const struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
@@ -11099,11 +11119,11 @@ static void i9xx_update_cursor(struct intel_plane *plane,
cntl = plane_state->ctl |
i9xx_cursor_ctl_crtc(crtc_state);
- if (plane_state->base.crtc_h != plane_state->base.crtc_w)
- fbc_ctl = CUR_FBC_CTL_EN | (plane_state->base.crtc_h - 1);
+ if (master_plane_state->base.crtc_h != master_plane_state->base.crtc_w)
+ fbc_ctl = CUR_FBC_CTL_EN | (master_plane_state->base.crtc_h - 1);
- base = intel_cursor_base(plane_state);
- pos = intel_cursor_position(plane_state);
+ base = intel_cursor_base(master_plane_state, plane_state);
+ pos = intel_cursor_position(crtc_state, master_plane_state, plane_state);
}
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
@@ -11151,10 +11171,17 @@ static void i9xx_update_cursor(struct intel_plane *plane,
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
+static void i9xx_update_cursor(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *plane_state)
+{
+ i9xx_update_cursor_slave(plane, crtc_state, plane_state, plane_state);
+}
+
static void i9xx_disable_cursor(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
{
- i9xx_update_cursor(plane, crtc_state, NULL);
+ i9xx_update_cursor_slave(plane, crtc_state, NULL, NULL);
}
static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
@@ -11662,6 +11689,7 @@ static bool needs_scaling(const struct intel_plane_state *state)
int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *crtc_state,
const struct intel_plane_state *old_plane_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -11674,7 +11702,7 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
int ret;
if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
- ret = skl_update_scaler_plane(crtc_state, plane_state);
+ ret = skl_update_scaler_plane(crtc_state, master_plane_state, plane_state);
if (ret)
return ret;
}
@@ -15269,7 +15297,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
* wait for it to complete in the slowpath
*/
if (!crtc_state->hw.active || needs_modeset(crtc_state) ||
- crtc_state->update_pipe)
+ crtc_state->update_pipe || crtc_state->bigjoiner)
goto slow;
old_plane_state = plane->state;
@@ -15539,6 +15567,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
} else {
cursor->max_stride = i9xx_cursor_max_stride;
cursor->update_plane = i9xx_update_cursor;
+ cursor->update_slave = i9xx_update_cursor_slave;
cursor->disable_plane = i9xx_disable_cursor;
cursor->get_hw_state = i9xx_cursor_get_hw_state;
cursor->check_plane = i9xx_check_cursor;
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 764d05d13b9e..a8b2198fcef1 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -562,8 +562,9 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state);
u32 skl_plane_stride(const struct intel_plane_state *master_plane_state,
const struct intel_plane_state *plane_state,
- int plane);
-int skl_check_plane_surface(struct intel_plane_state *plane_state);
+ int color_plane);
+int skl_check_plane_surface(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state);
int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
int skl_format_to_fourcc(int format, bool rgb_order, bool alpha);
unsigned int i9xx_plane_max_stride(struct intel_plane *plane,
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index f05f4830a529..154fb07a62eb 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1117,6 +1117,7 @@ struct intel_plane {
const struct intel_crtc_state *crtc_state);
bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
int (*check_plane)(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state);
};
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 9337f5a8dce0..00d5f7eb0c29 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -250,11 +250,12 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state,
#endif
}
-int intel_plane_check_stride(const struct intel_plane_state *plane_state)
+int intel_plane_check_stride(const struct intel_plane_state *master_plane_state,
+ const struct intel_plane_state *plane_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
- const struct drm_framebuffer *fb = plane_state->base.fb;
- unsigned int rotation = plane_state->base.rotation;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
+ unsigned int rotation = master_plane_state->base.rotation;
u32 stride, max_stride;
/*
@@ -263,7 +264,7 @@ int intel_plane_check_stride(const struct intel_plane_state *plane_state)
* with a false positive when the remapping didn't
* kick in due the plane being invisible.
*/
- if (intel_plane_can_remap(plane_state) &&
+ if (intel_plane_can_remap(master_plane_state) &&
!plane_state->base.visible)
return 0;
@@ -282,12 +283,13 @@ int intel_plane_check_stride(const struct intel_plane_state *plane_state)
return 0;
}
-int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
+int intel_plane_check_src_coordinates(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state)
{
- const struct drm_framebuffer *fb = plane_state->base.fb;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
struct drm_rect *src = &plane_state->base.src;
u32 src_x, src_y, src_w, src_h, hsub, vsub;
- bool rotated = drm_rotation_90_or_270(plane_state->base.rotation);
+ bool rotated = drm_rotation_90_or_270(master_plane_state->base.rotation);
/*
* Hardware doesn't handle subpixel coordinates.
@@ -1574,6 +1576,7 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
static int
g4x_sprite_check(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
@@ -1592,10 +1595,9 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
}
}
- ret = drm_atomic_helper_check_plane_state(&plane_state->base,
- &crtc_state->uapi,
- min_scale, max_scale,
- true, true);
+ ret = intel_atomic_plane_check_scaling(crtc_state,
+ master_plane_state, plane_state,
+ min_scale, max_scale);
if (ret)
return ret;
@@ -1606,7 +1608,7 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
if (!plane_state->base.visible)
return 0;
- ret = intel_plane_check_src_coordinates(plane_state);
+ ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
if (ret)
return ret;
@@ -1641,6 +1643,7 @@ int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
static int
vlv_sprite_check(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
int ret;
@@ -1649,11 +1652,10 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
- ret = drm_atomic_helper_check_plane_state(&plane_state->base,
- &crtc_state->uapi,
- DRM_PLANE_HELPER_NO_SCALING,
- DRM_PLANE_HELPER_NO_SCALING,
- true, true);
+ ret = intel_atomic_plane_check_scaling(crtc_state,
+ master_plane_state, plane_state,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING);
if (ret)
return ret;
@@ -1664,7 +1666,7 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
if (!plane_state->base.visible)
return 0;
- ret = intel_plane_check_src_coordinates(plane_state);
+ ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
if (ret)
return ret;
@@ -1777,10 +1779,11 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s
return 0;
}
-static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
+static int skl_plane_check_nv12_rotation(const struct intel_plane_state *master_plane_state,
+ const struct intel_plane_state *plane_state)
{
- const struct drm_framebuffer *fb = plane_state->base.fb;
- unsigned int rotation = plane_state->base.rotation;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
+ unsigned int rotation = master_plane_state->base.rotation;
int src_w = drm_rect_width(&plane_state->base.src) >> 16;
/* Display WA #1106 */
@@ -1795,33 +1798,37 @@ static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_s
}
static int skl_plane_check(struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *master_plane_state,
struct intel_plane_state *plane_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
- const struct drm_framebuffer *fb = plane_state->base.fb;
+ const struct drm_framebuffer *fb = master_plane_state->base.fb;
int min_scale = DRM_PLANE_HELPER_NO_SCALING;
int max_scale = DRM_PLANE_HELPER_NO_SCALING;
int ret;
+ /*
+ * it's ok to check slave plane_state here, master_plane_state is already checked
+ * in its own skl_plane_check call.
+ */
ret = skl_plane_check_fb(crtc_state, plane_state);
if (ret)
return ret;
/* use scaler when colorkey is not required */
- if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
+ if (!master_plane_state->ckey.flags && intel_fb_scalable(fb)) {
min_scale = 1;
max_scale = skl_max_scale(crtc_state, fb->format);
}
- ret = drm_atomic_helper_check_plane_state(&plane_state->base,
- &crtc_state->uapi,
- min_scale, max_scale,
- true, true);
+ ret = intel_atomic_plane_check_scaling(crtc_state,
+ master_plane_state, plane_state,
+ min_scale, max_scale);
if (ret)
return ret;
- ret = skl_check_plane_surface(plane_state);
+ ret = skl_check_plane_surface(master_plane_state, plane_state);
if (ret)
return ret;
@@ -1832,11 +1839,11 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
- ret = intel_plane_check_src_coordinates(plane_state);
+ ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
if (ret)
return ret;
- ret = skl_plane_check_nv12_rotation(plane_state);
+ ret = skl_plane_check_nv12_rotation(master_plane_state, plane_state);
if (ret)
return ret;
@@ -1844,11 +1851,11 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
if (!(plane_state->base.alpha >> 8))
plane_state->base.visible = false;
- plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
+ plane_state->ctl = skl_plane_ctl(crtc_state, master_plane_state);
if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
- plane_state);
+ master_plane_state);
if (icl_is_hdr_plane(dev_priv, plane->id) && fb->format->is_yuv)
/* Enable and use MPEG-2 chroma siting */
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.h b/drivers/gpu/drm/i915/display/intel_sprite.h
index 6df62fae9368..453b153b303e 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.h
+++ b/drivers/gpu/drm/i915/display/intel_sprite.h
@@ -26,8 +26,10 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state);
void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state,
struct intel_crtc_state *slave_crtc_state);
-int intel_plane_check_stride(const struct intel_plane_state *plane_state);
-int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
+int intel_plane_check_stride(const struct intel_plane_state *master_plane_state,
+ const struct intel_plane_state *plane_state);
+int intel_plane_check_src_coordinates(const struct intel_plane_state *master_plane_state,
+ struct intel_plane_state *plane_state);
int chv_plane_check_rotation(const struct intel_plane_state *plane_state);
struct intel_plane *
skl_universal_plane_create(struct drm_i915_private *dev_priv,
--
2.20.1
More information about the Intel-gfx
mailing list