Commit 94a4ffd1 authored by Gloria Li's avatar Gloria Li Committed by Alex Deucher

drm/amd/display: fix PIP bugs on Dal3

[Why]
There are outstanding bugs for PIP in Dal3:
-Crash when toggling PIP visibility
-Global Alpha is not working, Adjusting global alpha
 doesn’t have an effect
-Cursor is not working with pip plane and pipe splits
-One flash occurs when cursor enters PIP plane from
 top/bottom
-Crash when moving PIP plane off the screen

[How]
Resolve divide by 0 error
Implement global alpha
Program cursor on all pipes
Add dst rects' x and y offests into cursor position
Disable cursor when it is beyond bottom/top edge
Signed-off-by: default avatarGloria Li <geling.li@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f1220c87
...@@ -1106,6 +1106,9 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa ...@@ -1106,6 +1106,9 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha) if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha)
update_flags->bits.per_pixel_alpha_change = 1; update_flags->bits.per_pixel_alpha_change = 1;
if (u->plane_info->global_alpha_value != u->surface->global_alpha_value)
update_flags->bits.global_alpha_change = 1;
if (u->plane_info->dcc.enable != u->surface->dcc.enable if (u->plane_info->dcc.enable != u->surface->dcc.enable
|| u->plane_info->dcc.grph.independent_64b_blks != u->surface->dcc.grph.independent_64b_blks || u->plane_info->dcc.grph.independent_64b_blks != u->surface->dcc.grph.independent_64b_blks
|| u->plane_info->dcc.grph.meta_pitch != u->surface->dcc.grph.meta_pitch) || u->plane_info->dcc.grph.meta_pitch != u->surface->dcc.grph.meta_pitch)
......
...@@ -589,8 +589,10 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) ...@@ -589,8 +589,10 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
data->viewport.width = (data->viewport.width + 1) / 2; data->viewport.width = (data->viewport.width + 1) / 2;
data->viewport_c.width = (data->viewport_c.width + 1) / 2; data->viewport_c.width = (data->viewport_c.width + 1) / 2;
} else if (pri_split) { } else if (pri_split) {
data->viewport.width /= 2; if (data->viewport.width > 1)
data->viewport_c.width /= 2; data->viewport.width /= 2;
if (data->viewport_c.width > 1)
data->viewport_c.width /= 2;
} }
if (plane_state->rotation == ROTATION_ANGLE_90 || if (plane_state->rotation == ROTATION_ANGLE_90 ||
...@@ -670,7 +672,8 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct rect *recout_full ...@@ -670,7 +672,8 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct rect *recout_full
pipe_ctx->plane_res.scl_data.recout.width = pipe_ctx->plane_res.scl_data.recout.width =
(pipe_ctx->plane_res.scl_data.recout.width + 1) / 2; (pipe_ctx->plane_res.scl_data.recout.width + 1) / 2;
} else { } else {
pipe_ctx->plane_res.scl_data.recout.width /= 2; if (pipe_ctx->plane_res.scl_data.recout.width > 1)
pipe_ctx->plane_res.scl_data.recout.width /= 2;
} }
} }
/* Unclipped recout offset = stream dst offset + ((surf dst offset - stream surf_src offset) /* Unclipped recout offset = stream dst offset + ((surf dst offset - stream surf_src offset)
......
...@@ -205,8 +205,6 @@ bool dc_stream_set_cursor_attributes( ...@@ -205,8 +205,6 @@ bool dc_stream_set_cursor_attributes(
if (pipe_ctx->stream != stream) if (pipe_ctx->stream != stream)
continue; continue;
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
continue;
if (!pipe_to_program) { if (!pipe_to_program) {
pipe_to_program = pipe_ctx; pipe_to_program = pipe_ctx;
......
...@@ -442,6 +442,7 @@ union surface_update_flags { ...@@ -442,6 +442,7 @@ union surface_update_flags {
uint32_t color_space_change:1; uint32_t color_space_change:1;
uint32_t horizontal_mirror_change:1; uint32_t horizontal_mirror_change:1;
uint32_t per_pixel_alpha_change:1; uint32_t per_pixel_alpha_change:1;
uint32_t global_alpha_change:1;
uint32_t rotation_change:1; uint32_t rotation_change:1;
uint32_t swizzle_change:1; uint32_t swizzle_change:1;
uint32_t scaling_change:1; uint32_t scaling_change:1;
...@@ -496,6 +497,8 @@ struct dc_plane_state { ...@@ -496,6 +497,8 @@ struct dc_plane_state {
bool is_tiling_rotated; bool is_tiling_rotated;
bool per_pixel_alpha; bool per_pixel_alpha;
bool global_alpha;
int global_alpha_value;
bool visible; bool visible;
bool flip_immediate; bool flip_immediate;
bool horizontal_mirror; bool horizontal_mirror;
...@@ -522,6 +525,8 @@ struct dc_plane_info { ...@@ -522,6 +525,8 @@ struct dc_plane_info {
bool horizontal_mirror; bool horizontal_mirror;
bool visible; bool visible;
bool per_pixel_alpha; bool per_pixel_alpha;
bool global_alpha;
int global_alpha_value;
bool input_csc_enabled; bool input_csc_enabled;
}; };
......
...@@ -444,10 +444,12 @@ void dpp1_set_cursor_position( ...@@ -444,10 +444,12 @@ void dpp1_set_cursor_position(
struct dpp *dpp_base, struct dpp *dpp_base,
const struct dc_cursor_position *pos, const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param, const struct dc_cursor_mi_param *param,
uint32_t width) uint32_t width,
uint32_t height)
{ {
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
uint32_t cur_en = pos->enable ? 1 : 0; uint32_t cur_en = pos->enable ? 1 : 0;
if (src_x_offset >= (int)param->viewport.width) if (src_x_offset >= (int)param->viewport.width)
...@@ -456,6 +458,12 @@ void dpp1_set_cursor_position( ...@@ -456,6 +458,12 @@ void dpp1_set_cursor_position(
if (src_x_offset + (int)width <= 0) if (src_x_offset + (int)width <= 0)
cur_en = 0; /* not visible beyond left edge*/ cur_en = 0; /* not visible beyond left edge*/
if (src_y_offset >= (int)param->viewport.height)
cur_en = 0; /* not visible beyond bottom edge*/
if (src_y_offset < 0)
cur_en = 0; /* not visible beyond top edge*/
REG_UPDATE(CURSOR0_CONTROL, REG_UPDATE(CURSOR0_CONTROL,
CUR0_ENABLE, cur_en); CUR0_ENABLE, cur_en);
......
...@@ -1374,7 +1374,8 @@ void dpp1_set_cursor_position( ...@@ -1374,7 +1374,8 @@ void dpp1_set_cursor_position(
struct dpp *dpp_base, struct dpp *dpp_base,
const struct dc_cursor_position *pos, const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param, const struct dc_cursor_mi_param *param,
uint32_t width); uint32_t width,
uint32_t height);
void dpp1_cnv_set_optional_cursor_attributes( void dpp1_cnv_set_optional_cursor_attributes(
struct dpp *dpp_base, struct dpp *dpp_base,
......
...@@ -1070,6 +1070,7 @@ void hubp1_cursor_set_position( ...@@ -1070,6 +1070,7 @@ void hubp1_cursor_set_position(
{ {
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
int x_hotspot = pos->x_hotspot; int x_hotspot = pos->x_hotspot;
int y_hotspot = pos->y_hotspot; int y_hotspot = pos->y_hotspot;
uint32_t dst_x_offset; uint32_t dst_x_offset;
...@@ -1113,6 +1114,12 @@ void hubp1_cursor_set_position( ...@@ -1113,6 +1114,12 @@ void hubp1_cursor_set_position(
if (src_x_offset + (int)hubp->curs_attr.width <= 0) if (src_x_offset + (int)hubp->curs_attr.width <= 0)
cur_en = 0; /* not visible beyond left edge*/ cur_en = 0; /* not visible beyond left edge*/
if (src_y_offset >= (int)param->viewport.height)
cur_en = 0; /* not visible beyond bottom edge*/
if (src_y_offset < 0) //+ (int)hubp->curs_attr.height
cur_en = 0; /* not visible beyond top edge*/
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr); hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
......
...@@ -1932,9 +1932,13 @@ static void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) ...@@ -1932,9 +1932,13 @@ static void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA; blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
blnd_cfg.overlap_only = false; blnd_cfg.overlap_only = false;
blnd_cfg.global_alpha = 0xff;
blnd_cfg.global_gain = 0xff; blnd_cfg.global_gain = 0xff;
if (pipe_ctx->plane_state->global_alpha)
blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
else
blnd_cfg.global_alpha = 0xff;
/* DCN1.0 has output CM before MPC which seems to screw with /* DCN1.0 has output CM before MPC which seems to screw with
* pre-multiplied alpha. * pre-multiplied alpha.
*/ */
...@@ -2049,11 +2053,13 @@ static void update_dchubp_dpp( ...@@ -2049,11 +2053,13 @@ static void update_dchubp_dpp(
update_dpp(dpp, plane_state); update_dpp(dpp, plane_state);
if (plane_state->update_flags.bits.full_update || if (plane_state->update_flags.bits.full_update ||
plane_state->update_flags.bits.per_pixel_alpha_change) plane_state->update_flags.bits.per_pixel_alpha_change ||
plane_state->update_flags.bits.global_alpha_change)
dc->hwss.update_mpcc(dc, pipe_ctx); dc->hwss.update_mpcc(dc, pipe_ctx);
if (plane_state->update_flags.bits.full_update || if (plane_state->update_flags.bits.full_update ||
plane_state->update_flags.bits.per_pixel_alpha_change || plane_state->update_flags.bits.per_pixel_alpha_change ||
plane_state->update_flags.bits.global_alpha_change ||
plane_state->update_flags.bits.scaling_change || plane_state->update_flags.bits.scaling_change ||
plane_state->update_flags.bits.position_change) { plane_state->update_flags.bits.position_change) {
update_scaler(pipe_ctx); update_scaler(pipe_ctx);
...@@ -2597,15 +2603,15 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) ...@@ -2597,15 +2603,15 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
.mirror = pipe_ctx->plane_state->horizontal_mirror .mirror = pipe_ctx->plane_state->horizontal_mirror
}; };
pos_cpy.x -= pipe_ctx->plane_state->dst_rect.x;
pos_cpy.y -= pipe_ctx->plane_state->dst_rect.y;
if (pipe_ctx->plane_state->address.type if (pipe_ctx->plane_state->address.type
== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
pos_cpy.enable = false; pos_cpy.enable = false;
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
pos_cpy.enable = false;
hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param); hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width); dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width, hubp->curs_attr.height);
} }
static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx) static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
......
...@@ -147,7 +147,8 @@ struct dpp_funcs { ...@@ -147,7 +147,8 @@ struct dpp_funcs {
struct dpp *dpp_base, struct dpp *dpp_base,
const struct dc_cursor_position *pos, const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param, const struct dc_cursor_mi_param *param,
uint32_t width uint32_t width,
uint32_t height
); );
void (*dpp_set_hdr_multiplier)( void (*dpp_set_hdr_multiplier)(
struct dpp *dpp_base, struct dpp *dpp_base,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment