diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/4528-drm-amd-display-upgrade-scaler-math.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/4528-drm-amd-display-upgrade-scaler-math.patch | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/4528-drm-amd-display-upgrade-scaler-math.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/4528-drm-amd-display-upgrade-scaler-math.patch new file mode 100644 index 00000000..364cb4a5 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/4528-drm-amd-display-upgrade-scaler-math.patch @@ -0,0 +1,525 @@ +From 28b39973cdb2d45d57e08e1c08e06d84b904bcdc Mon Sep 17 00:00:00 2001 +From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Date: Thu, 3 May 2018 13:42:43 -0400 +Subject: [PATCH 4528/5725] drm/amd/display: upgrade scaler math + +This change will allow the viewport overlap to apply to rotated/ +mirrored surfaces. Viewport overlap results in extra pixels being +added to viewport allowing the first few pixels to be scaled as +if there is no cut-off(mpo or pipe split) and allows us to get matching +crc's between scaled split and unsplit outputs of the same thing. + +Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Reviewed-by: Charlene Liu <Charlene.Liu@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 419 +++++++++++++++------- + 1 file changed, 289 insertions(+), 130 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +index f02f366..ad09f0c 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +@@ -521,13 +521,12 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) + } + } + +-static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip) ++static void calculate_recout(struct pipe_ctx *pipe_ctx, struct rect *recout_full) + { + const struct dc_plane_state *plane_state = pipe_ctx->plane_state; + const struct dc_stream_state *stream = pipe_ctx->stream; + struct rect surf_src = plane_state->src_rect; + struct rect surf_clip = plane_state->clip_rect; +- int recout_full_x, recout_full_y; + bool pri_split = pipe_ctx->bottom_pipe && + pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state; + bool sec_split = pipe_ctx->top_pipe && +@@ -596,20 +595,22 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip + } + } + /* Unclipped recout offset = stream dst offset + ((surf dst offset - stream surf_src offset) +- * * 1/ stream scaling ratio) - (surf surf_src offset * 1/ full scl +- * ratio) ++ * * 1/ stream scaling ratio) - (surf surf_src offset * 1/ full scl ++ * ratio) + */ +- recout_full_x = stream->dst.x + (plane_state->dst_rect.x - stream->src.x) ++ recout_full->x = stream->dst.x + (plane_state->dst_rect.x - stream->src.x) + * stream->dst.width / stream->src.width - + surf_src.x * plane_state->dst_rect.width / surf_src.width + * stream->dst.width / stream->src.width; +- recout_full_y = stream->dst.y + (plane_state->dst_rect.y - stream->src.y) ++ recout_full->y = stream->dst.y + (plane_state->dst_rect.y - stream->src.y) + * stream->dst.height / stream->src.height - + surf_src.y * plane_state->dst_rect.height / surf_src.height + * stream->dst.height / stream->src.height; + +- recout_skip->width = pipe_ctx->plane_res.scl_data.recout.x - recout_full_x; +- recout_skip->height = pipe_ctx->plane_res.scl_data.recout.y - recout_full_y; ++ recout_full->width = plane_state->dst_rect.width ++ * stream->dst.width / stream->src.width; ++ recout_full->height = plane_state->dst_rect.height ++ * stream->dst.height / stream->src.height; + } + + static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx) +@@ -661,7 +662,7 @@ static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx) + pipe_ctx->plane_res.scl_data.ratios.vert_c, 19); + } + +-static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *recout_skip) ++static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct rect *recout_full) + { + struct scaler_data *data = &pipe_ctx->plane_res.scl_data; + struct rect src = pipe_ctx->plane_state->src_rect; +@@ -679,15 +680,14 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r + flip_vert_scan_dir = true; + else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) + flip_horz_scan_dir = true; +- if (pipe_ctx->plane_state->horizontal_mirror) +- flip_horz_scan_dir = !flip_horz_scan_dir; + + if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 || + pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) { + rect_swap_helper(&src); + rect_swap_helper(&data->viewport_c); + rect_swap_helper(&data->viewport); +- } ++ } else if (pipe_ctx->plane_state->horizontal_mirror) ++ flip_horz_scan_dir = !flip_horz_scan_dir; + + /* + * Init calculated according to formula: +@@ -707,127 +707,286 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r + data->inits.v_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.v_c, dc_fixpt_div_int( + dc_fixpt_add_int(data->ratios.vert_c, data->taps.v_taps_c + 1), 2)), 19); + ++ if (!flip_horz_scan_dir) { ++ /* Adjust for viewport end clip-off */ ++ if ((data->viewport.x + data->viewport.width) < (src.x + src.width)) { ++ int vp_clip = src.x + src.width - data->viewport.width - data->viewport.x; ++ int int_part = dc_fixpt_floor( ++ dc_fixpt_sub(data->inits.h, data->ratios.horz)); + ++ int_part = int_part > 0 ? int_part : 0; ++ data->viewport.width += int_part < vp_clip ? int_part : vp_clip; ++ } ++ if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div) { ++ int vp_clip = (src.x + src.width) / vpc_div - ++ data->viewport_c.width - data->viewport_c.x; ++ int int_part = dc_fixpt_floor( ++ dc_fixpt_sub(data->inits.h_c, data->ratios.horz_c)); ++ ++ int_part = int_part > 0 ? int_part : 0; ++ data->viewport_c.width += int_part < vp_clip ? int_part : vp_clip; ++ } + +- /* Adjust for viewport end clip-off */ +- if ((data->viewport.x + data->viewport.width) < (src.x + src.width) && !flip_horz_scan_dir) { +- int vp_clip = src.x + src.width - data->viewport.width - data->viewport.x; +- int int_part = dc_fixpt_floor( +- dc_fixpt_sub(data->inits.h, data->ratios.horz)); +- +- int_part = int_part > 0 ? int_part : 0; +- data->viewport.width += int_part < vp_clip ? int_part : vp_clip; +- } +- if ((data->viewport.y + data->viewport.height) < (src.y + src.height) && !flip_vert_scan_dir) { +- int vp_clip = src.y + src.height - data->viewport.height - data->viewport.y; +- int int_part = dc_fixpt_floor( +- dc_fixpt_sub(data->inits.v, data->ratios.vert)); +- +- int_part = int_part > 0 ? int_part : 0; +- data->viewport.height += int_part < vp_clip ? int_part : vp_clip; +- } +- if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div && !flip_horz_scan_dir) { +- int vp_clip = (src.x + src.width) / vpc_div - +- data->viewport_c.width - data->viewport_c.x; +- int int_part = dc_fixpt_floor( +- dc_fixpt_sub(data->inits.h_c, data->ratios.horz_c)); +- +- int_part = int_part > 0 ? int_part : 0; +- data->viewport_c.width += int_part < vp_clip ? int_part : vp_clip; +- } +- if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div && !flip_vert_scan_dir) { +- int vp_clip = (src.y + src.height) / vpc_div - +- data->viewport_c.height - data->viewport_c.y; +- int int_part = dc_fixpt_floor( +- dc_fixpt_sub(data->inits.v_c, data->ratios.vert_c)); +- +- int_part = int_part > 0 ? int_part : 0; +- data->viewport_c.height += int_part < vp_clip ? int_part : vp_clip; +- } +- +- /* Adjust for non-0 viewport offset */ +- if (data->viewport.x && !flip_horz_scan_dir) { +- int int_part; +- +- data->inits.h = dc_fixpt_add(data->inits.h, dc_fixpt_mul_int( +- data->ratios.horz, recout_skip->width)); +- int_part = dc_fixpt_floor(data->inits.h) - data->viewport.x; +- if (int_part < data->taps.h_taps) { +- int int_adj = data->viewport.x >= (data->taps.h_taps - int_part) ? +- (data->taps.h_taps - int_part) : data->viewport.x; +- data->viewport.x -= int_adj; +- data->viewport.width += int_adj; +- int_part += int_adj; +- } else if (int_part > data->taps.h_taps) { +- data->viewport.x += int_part - data->taps.h_taps; +- data->viewport.width -= int_part - data->taps.h_taps; +- int_part = data->taps.h_taps; ++ /* Adjust for non-0 viewport offset */ ++ if (data->viewport.x) { ++ int int_part; ++ ++ data->inits.h = dc_fixpt_add(data->inits.h, dc_fixpt_mul_int( ++ data->ratios.horz, data->recout.x - recout_full->x)); ++ int_part = dc_fixpt_floor(data->inits.h) - data->viewport.x; ++ if (int_part < data->taps.h_taps) { ++ int int_adj = data->viewport.x >= (data->taps.h_taps - int_part) ? ++ (data->taps.h_taps - int_part) : data->viewport.x; ++ data->viewport.x -= int_adj; ++ data->viewport.width += int_adj; ++ int_part += int_adj; ++ } else if (int_part > data->taps.h_taps) { ++ data->viewport.x += int_part - data->taps.h_taps; ++ data->viewport.width -= int_part - data->taps.h_taps; ++ int_part = data->taps.h_taps; ++ } ++ data->inits.h.value &= 0xffffffff; ++ data->inits.h = dc_fixpt_add_int(data->inits.h, int_part); + } +- data->inits.h.value &= 0xffffffff; +- data->inits.h = dc_fixpt_add_int(data->inits.h, int_part); +- } +- +- if (data->viewport_c.x && !flip_horz_scan_dir) { +- int int_part; +- +- data->inits.h_c = dc_fixpt_add(data->inits.h_c, dc_fixpt_mul_int( +- data->ratios.horz_c, recout_skip->width)); +- int_part = dc_fixpt_floor(data->inits.h_c) - data->viewport_c.x; +- if (int_part < data->taps.h_taps_c) { +- int int_adj = data->viewport_c.x >= (data->taps.h_taps_c - int_part) ? +- (data->taps.h_taps_c - int_part) : data->viewport_c.x; +- data->viewport_c.x -= int_adj; +- data->viewport_c.width += int_adj; +- int_part += int_adj; +- } else if (int_part > data->taps.h_taps_c) { +- data->viewport_c.x += int_part - data->taps.h_taps_c; +- data->viewport_c.width -= int_part - data->taps.h_taps_c; +- int_part = data->taps.h_taps_c; ++ ++ if (data->viewport_c.x) { ++ int int_part; ++ ++ data->inits.h_c = dc_fixpt_add(data->inits.h_c, dc_fixpt_mul_int( ++ data->ratios.horz_c, data->recout.x - recout_full->x)); ++ int_part = dc_fixpt_floor(data->inits.h_c) - data->viewport_c.x; ++ if (int_part < data->taps.h_taps_c) { ++ int int_adj = data->viewport_c.x >= (data->taps.h_taps_c - int_part) ? ++ (data->taps.h_taps_c - int_part) : data->viewport_c.x; ++ data->viewport_c.x -= int_adj; ++ data->viewport_c.width += int_adj; ++ int_part += int_adj; ++ } else if (int_part > data->taps.h_taps_c) { ++ data->viewport_c.x += int_part - data->taps.h_taps_c; ++ data->viewport_c.width -= int_part - data->taps.h_taps_c; ++ int_part = data->taps.h_taps_c; ++ } ++ data->inits.h_c.value &= 0xffffffff; ++ data->inits.h_c = dc_fixpt_add_int(data->inits.h_c, int_part); + } +- data->inits.h_c.value &= 0xffffffff; +- data->inits.h_c = dc_fixpt_add_int(data->inits.h_c, int_part); +- } +- +- if (data->viewport.y && !flip_vert_scan_dir) { +- int int_part; +- +- data->inits.v = dc_fixpt_add(data->inits.v, dc_fixpt_mul_int( +- data->ratios.vert, recout_skip->height)); +- int_part = dc_fixpt_floor(data->inits.v) - data->viewport.y; +- if (int_part < data->taps.v_taps) { +- int int_adj = data->viewport.y >= (data->taps.v_taps - int_part) ? +- (data->taps.v_taps - int_part) : data->viewport.y; +- data->viewport.y -= int_adj; +- data->viewport.height += int_adj; +- int_part += int_adj; +- } else if (int_part > data->taps.v_taps) { +- data->viewport.y += int_part - data->taps.v_taps; +- data->viewport.height -= int_part - data->taps.v_taps; +- int_part = data->taps.v_taps; ++ } else { ++ /* Adjust for non-0 viewport offset */ ++ if (data->viewport.x) { ++ int int_part = dc_fixpt_floor( ++ dc_fixpt_sub(data->inits.h, data->ratios.horz)); ++ ++ int_part = int_part > 0 ? int_part : 0; ++ data->viewport.width += int_part < data->viewport.x ? int_part : data->viewport.x; ++ data->viewport.x -= int_part < data->viewport.x ? int_part : data->viewport.x; ++ } ++ if (data->viewport_c.x) { ++ int int_part = dc_fixpt_floor( ++ dc_fixpt_sub(data->inits.h_c, data->ratios.horz_c)); ++ ++ int_part = int_part > 0 ? int_part : 0; ++ data->viewport_c.width += int_part < data->viewport_c.x ? int_part : data->viewport_c.x; ++ data->viewport_c.x -= int_part < data->viewport_c.x ? int_part : data->viewport_c.x; + } +- data->inits.v.value &= 0xffffffff; +- data->inits.v = dc_fixpt_add_int(data->inits.v, int_part); +- } +- +- if (data->viewport_c.y && !flip_vert_scan_dir) { +- int int_part; +- +- data->inits.v_c = dc_fixpt_add(data->inits.v_c, dc_fixpt_mul_int( +- data->ratios.vert_c, recout_skip->height)); +- int_part = dc_fixpt_floor(data->inits.v_c) - data->viewport_c.y; +- if (int_part < data->taps.v_taps_c) { +- int int_adj = data->viewport_c.y >= (data->taps.v_taps_c - int_part) ? +- (data->taps.v_taps_c - int_part) : data->viewport_c.y; +- data->viewport_c.y -= int_adj; +- data->viewport_c.height += int_adj; +- int_part += int_adj; +- } else if (int_part > data->taps.v_taps_c) { +- data->viewport_c.y += int_part - data->taps.v_taps_c; +- data->viewport_c.height -= int_part - data->taps.v_taps_c; +- int_part = data->taps.v_taps_c; ++ ++ /* Adjust for viewport end clip-off */ ++ if ((data->viewport.x + data->viewport.width) < (src.x + src.width)) { ++ int int_part; ++ int end_offset = src.x + src.width ++ - data->viewport.x - data->viewport.width; ++ ++ /* ++ * this is init if vp had no offset, keep in mind this is from the ++ * right side of vp due to scan direction ++ */ ++ data->inits.h = dc_fixpt_add(data->inits.h, dc_fixpt_mul_int( ++ data->ratios.horz, data->recout.x - recout_full->x)); ++ /* ++ * this is the difference between first pixel of viewport available to read ++ * and init position, takning into account scan direction ++ */ ++ int_part = dc_fixpt_floor(data->inits.h) - end_offset; ++ if (int_part < data->taps.h_taps) { ++ int int_adj = end_offset >= (data->taps.h_taps - int_part) ? ++ (data->taps.h_taps - int_part) : end_offset; ++ data->viewport.width += int_adj; ++ int_part += int_adj; ++ } else if (int_part > data->taps.h_taps) { ++ data->viewport.width += int_part - data->taps.h_taps; ++ int_part = data->taps.h_taps; ++ } ++ data->inits.h.value &= 0xffffffff; ++ data->inits.h = dc_fixpt_add_int(data->inits.h, int_part); ++ } ++ ++ if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div) { ++ int int_part; ++ int end_offset = (src.x + src.width) / vpc_div ++ - data->viewport_c.x - data->viewport_c.width; ++ ++ /* ++ * this is init if vp had no offset, keep in mind this is from the ++ * right side of vp due to scan direction ++ */ ++ data->inits.h_c = dc_fixpt_add(data->inits.h_c, dc_fixpt_mul_int( ++ data->ratios.horz_c, data->recout.x - recout_full->x)); ++ /* ++ * this is the difference between first pixel of viewport available to read ++ * and init position, takning into account scan direction ++ */ ++ int_part = dc_fixpt_floor(data->inits.h_c) - end_offset; ++ if (int_part < data->taps.h_taps_c) { ++ int int_adj = end_offset >= (data->taps.h_taps_c - int_part) ? ++ (data->taps.h_taps_c - int_part) : end_offset; ++ data->viewport_c.width += int_adj; ++ int_part += int_adj; ++ } else if (int_part > data->taps.h_taps_c) { ++ data->viewport_c.width += int_part - data->taps.h_taps_c; ++ int_part = data->taps.h_taps_c; ++ } ++ data->inits.h_c.value &= 0xffffffff; ++ data->inits.h_c = dc_fixpt_add_int(data->inits.h_c, int_part); ++ } ++ ++ } ++ if (!flip_vert_scan_dir) { ++ /* Adjust for viewport end clip-off */ ++ if ((data->viewport.y + data->viewport.height) < (src.y + src.height)) { ++ int vp_clip = src.y + src.height - data->viewport.height - data->viewport.y; ++ int int_part = dc_fixpt_floor( ++ dc_fixpt_sub(data->inits.v, data->ratios.vert)); ++ ++ int_part = int_part > 0 ? int_part : 0; ++ data->viewport.height += int_part < vp_clip ? int_part : vp_clip; ++ } ++ if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div) { ++ int vp_clip = (src.y + src.height) / vpc_div - ++ data->viewport_c.height - data->viewport_c.y; ++ int int_part = dc_fixpt_floor( ++ dc_fixpt_sub(data->inits.v_c, data->ratios.vert_c)); ++ ++ int_part = int_part > 0 ? int_part : 0; ++ data->viewport_c.height += int_part < vp_clip ? int_part : vp_clip; ++ } ++ ++ /* Adjust for non-0 viewport offset */ ++ if (data->viewport.y) { ++ int int_part; ++ ++ data->inits.v = dc_fixpt_add(data->inits.v, dc_fixpt_mul_int( ++ data->ratios.vert, data->recout.y - recout_full->y)); ++ int_part = dc_fixpt_floor(data->inits.v) - data->viewport.y; ++ if (int_part < data->taps.v_taps) { ++ int int_adj = data->viewport.y >= (data->taps.v_taps - int_part) ? ++ (data->taps.v_taps - int_part) : data->viewport.y; ++ data->viewport.y -= int_adj; ++ data->viewport.height += int_adj; ++ int_part += int_adj; ++ } else if (int_part > data->taps.v_taps) { ++ data->viewport.y += int_part - data->taps.v_taps; ++ data->viewport.height -= int_part - data->taps.v_taps; ++ int_part = data->taps.v_taps; ++ } ++ data->inits.v.value &= 0xffffffff; ++ data->inits.v = dc_fixpt_add_int(data->inits.v, int_part); ++ } ++ ++ if (data->viewport_c.y) { ++ int int_part; ++ ++ data->inits.v_c = dc_fixpt_add(data->inits.v_c, dc_fixpt_mul_int( ++ data->ratios.vert_c, data->recout.y - recout_full->y)); ++ int_part = dc_fixpt_floor(data->inits.v_c) - data->viewport_c.y; ++ if (int_part < data->taps.v_taps_c) { ++ int int_adj = data->viewport_c.y >= (data->taps.v_taps_c - int_part) ? ++ (data->taps.v_taps_c - int_part) : data->viewport_c.y; ++ data->viewport_c.y -= int_adj; ++ data->viewport_c.height += int_adj; ++ int_part += int_adj; ++ } else if (int_part > data->taps.v_taps_c) { ++ data->viewport_c.y += int_part - data->taps.v_taps_c; ++ data->viewport_c.height -= int_part - data->taps.v_taps_c; ++ int_part = data->taps.v_taps_c; ++ } ++ data->inits.v_c.value &= 0xffffffff; ++ data->inits.v_c = dc_fixpt_add_int(data->inits.v_c, int_part); ++ } ++ } else { ++ /* Adjust for non-0 viewport offset */ ++ if (data->viewport.y) { ++ int int_part = dc_fixpt_floor( ++ dc_fixpt_sub(data->inits.v, data->ratios.vert)); ++ ++ int_part = int_part > 0 ? int_part : 0; ++ data->viewport.height += int_part < data->viewport.y ? int_part : data->viewport.y; ++ data->viewport.y -= int_part < data->viewport.y ? int_part : data->viewport.y; ++ } ++ if (data->viewport_c.y) { ++ int int_part = dc_fixpt_floor( ++ dc_fixpt_sub(data->inits.v_c, data->ratios.vert_c)); ++ ++ int_part = int_part > 0 ? int_part : 0; ++ data->viewport_c.height += int_part < data->viewport_c.y ? int_part : data->viewport_c.y; ++ data->viewport_c.y -= int_part < data->viewport_c.y ? int_part : data->viewport_c.y; ++ } ++ ++ /* Adjust for viewport end clip-off */ ++ if ((data->viewport.y + data->viewport.height) < (src.y + src.height)) { ++ int int_part; ++ int end_offset = src.y + src.height ++ - data->viewport.y - data->viewport.height; ++ ++ /* ++ * this is init if vp had no offset, keep in mind this is from the ++ * right side of vp due to scan direction ++ */ ++ data->inits.v = dc_fixpt_add(data->inits.v, dc_fixpt_mul_int( ++ data->ratios.vert, data->recout.y - recout_full->y)); ++ /* ++ * this is the difference between first pixel of viewport available to read ++ * and init position, taking into account scan direction ++ */ ++ int_part = dc_fixpt_floor(data->inits.v) - end_offset; ++ if (int_part < data->taps.v_taps) { ++ int int_adj = end_offset >= (data->taps.v_taps - int_part) ? ++ (data->taps.v_taps - int_part) : end_offset; ++ data->viewport.height += int_adj; ++ int_part += int_adj; ++ } else if (int_part > data->taps.v_taps) { ++ data->viewport.height += int_part - data->taps.v_taps; ++ int_part = data->taps.v_taps; ++ } ++ data->inits.v.value &= 0xffffffff; ++ data->inits.v = dc_fixpt_add_int(data->inits.v, int_part); ++ } ++ ++ if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div) { ++ int int_part; ++ int end_offset = (src.y + src.height) / vpc_div ++ - data->viewport_c.y - data->viewport_c.height; ++ ++ /* ++ * this is init if vp had no offset, keep in mind this is from the ++ * right side of vp due to scan direction ++ */ ++ data->inits.v_c = dc_fixpt_add(data->inits.v_c, dc_fixpt_mul_int( ++ data->ratios.vert_c, data->recout.y - recout_full->y)); ++ /* ++ * this is the difference between first pixel of viewport available to read ++ * and init position, taking into account scan direction ++ */ ++ int_part = dc_fixpt_floor(data->inits.v_c) - end_offset; ++ if (int_part < data->taps.v_taps_c) { ++ int int_adj = end_offset >= (data->taps.v_taps_c - int_part) ? ++ (data->taps.v_taps_c - int_part) : end_offset; ++ data->viewport_c.height += int_adj; ++ int_part += int_adj; ++ } else if (int_part > data->taps.v_taps_c) { ++ data->viewport_c.height += int_part - data->taps.v_taps_c; ++ int_part = data->taps.v_taps_c; ++ } ++ data->inits.v_c.value &= 0xffffffff; ++ data->inits.v_c = dc_fixpt_add_int(data->inits.v_c, int_part); + } +- data->inits.v_c.value &= 0xffffffff; +- data->inits.v_c = dc_fixpt_add_int(data->inits.v_c, int_part); + } + + /* Interlaced inits based on final vert inits */ +@@ -845,7 +1004,7 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) + { + const struct dc_plane_state *plane_state = pipe_ctx->plane_state; + struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; +- struct view recout_skip = { 0 }; ++ struct rect recout_full = { 0 }; + bool res = false; + DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); + /* Important: scaling ratio calculation requires pixel format, +@@ -865,7 +1024,7 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) + if (pipe_ctx->plane_res.scl_data.viewport.height < 16 || pipe_ctx->plane_res.scl_data.viewport.width < 16) + return false; + +- calculate_recout(pipe_ctx, &recout_skip); ++ calculate_recout(pipe_ctx, &recout_full); + + /** + * Setting line buffer pixel depth to 24bpp yields banding +@@ -909,7 +1068,7 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) + + if (res) + /* May need to re-check lb size after this in some obscure scenario */ +- calculate_inits_and_adj_vp(pipe_ctx, &recout_skip); ++ calculate_inits_and_adj_vp(pipe_ctx, &recout_full); + + DC_LOG_SCALER( + "%s: Viewport:\nheight:%d width:%d x:%d " +-- +2.7.4 + |