diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 0eae08e389c5..f4d2814867d7 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -823,10 +823,6 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, return -ERANGE; } - /* right side of the image is on the slave crtc, adjust dst to match */ - if (intel_crtc_is_bigjoiner_slave(crtc_state)) - drm_rect_translate(dst, -drm_rect_width(&crtc_state->pipe_src), 0); - /* * FIXME: This might need further adjustment for seamless scaling * with phase information, for the 2p2 and 2p1 scenarios. @@ -843,6 +839,9 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, return -EINVAL; } + /* final plane coordinates will be relative to the plane's pipe */ + drm_rect_translate(dst, -clip->x1, -clip->y1); + return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 24a42be1b1c5..8c80de877605 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -152,9 +152,11 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state, /* Use the unclipped src/dst rectangles, which we program to hw */ plane_state->uapi.src = src; plane_state->uapi.dst = dst; - if (intel_crtc_is_bigjoiner_slave(crtc_state)) - drm_rect_translate(&plane_state->uapi.dst, - -drm_rect_width(&crtc_state->pipe_src), 0); + + /* final plane coordinates will be relative to the plane's pipe */ + drm_rect_translate(&plane_state->uapi.dst, + -crtc_state->pipe_src.x1, + -crtc_state->pipe_src.y1); ret = intel_cursor_check_surface(plane_state); if (ret) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 7a11f2224662..1ce31f79625f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3192,6 +3192,23 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, } } +static void intel_bigjoiner_adjust_pipe_src(struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + int num_pipes = intel_bigjoiner_num_pipes(crtc_state); + enum pipe master_pipe, pipe = crtc->pipe; + int width; + + if (num_pipes < 2) + return; + + master_pipe = bigjoiner_master_pipe(crtc_state); + width = drm_rect_width(&crtc_state->pipe_src); + + drm_rect_translate_to(&crtc_state->pipe_src, + (pipe - master_pipe) * width, 0); +} + static void intel_get_pipe_src_size(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { @@ -3204,6 +3221,8 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc, drm_rect_init(&pipe_config->pipe_src, 0, 0, REG_FIELD_GET(PIPESRC_WIDTH_MASK, tmp) + 1, REG_FIELD_GET(PIPESRC_HEIGHT_MASK, tmp) + 1); + + intel_bigjoiner_adjust_pipe_src(pipe_config); } static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) @@ -5838,6 +5857,8 @@ intel_modeset_pipe_config_late(struct intel_crtc_state *crtc_state) struct drm_connector *connector; int i; + intel_bigjoiner_adjust_pipe_src(crtc_state); + for_each_new_connector_in_state(&state->base, connector, conn_state, i) { struct intel_encoder *encoder = diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 631e1f1dc5e6..ee46561b5ae8 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -958,21 +958,21 @@ static void update_pfit_vscale_ratio(struct intel_overlay *overlay) static int check_overlay_dst(struct intel_overlay *overlay, struct drm_intel_overlay_put_image *rec) { - const struct intel_crtc_state *pipe_config = + const struct intel_crtc_state *crtc_state = overlay->crtc->config; - int pipe_src_w = drm_rect_width(&pipe_config->pipe_src); - int pipe_src_h = drm_rect_height(&pipe_config->pipe_src); + struct drm_rect req, clipped; - if (rec->dst_height == 0 || rec->dst_width == 0) + drm_rect_init(&req, rec->dst_x, rec->dst_y, + rec->dst_width, rec->dst_height); + + clipped = req; + drm_rect_intersect(&clipped, &crtc_state->pipe_src); + + if (!drm_rect_visible(&clipped) || + !drm_rect_equals(&clipped, &req)) return -EINVAL; - if (rec->dst_x < pipe_src_w && - rec->dst_x + rec->dst_width <= pipe_src_w && - rec->dst_y < pipe_src_h && - rec->dst_y + rec->dst_height <= pipe_src_h) - return 0; - else - return -EINVAL; + return 0; } static int check_overlay_scaling(struct drm_intel_overlay_put_image *rec)