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@xxxxxxxxxxxxxxx> --- 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx