forked from mirrors/linux
		
	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: Gloria Li <geling.li@amd.com> Reviewed-by: Aric Cyr <Aric.Cyr@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									f1220c876d
								
							
						
					
					
						commit
						94a4ffd1d4
					
				
					 9 changed files with 46 additions and 14 deletions
				
			
		| 
						 | 
					@ -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,7 +589,9 @@ 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) {
 | 
				
			||||||
 | 
							if (data->viewport.width > 1)
 | 
				
			||||||
			data->viewport.width /= 2;
 | 
								data->viewport.width /= 2;
 | 
				
			||||||
 | 
							if (data->viewport_c.width > 1)
 | 
				
			||||||
			data->viewport_c.width /= 2;
 | 
								data->viewport_c.width /= 2;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -670,6 +672,7 @@ 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 {
 | 
				
			||||||
 | 
								if (pipe_ctx->plane_res.scl_data.recout.width > 1)
 | 
				
			||||||
				pipe_ctx->plane_res.scl_data.recout.width /= 2;
 | 
									pipe_ctx->plane_res.scl_data.recout.width /= 2;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 {
 | 
				
			||||||
		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 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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 {
 | 
				
			||||||
	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(
 | 
				
			||||||
		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(
 | 
				
			||||||
	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(
 | 
				
			||||||
		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(
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	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(
 | 
				
			||||||
	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)
 | 
				
			||||||
		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(
 | 
				
			||||||
		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)
 | 
				
			||||||
		.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, ¶m);
 | 
						hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m);
 | 
				
			||||||
	dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width);
 | 
						dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, 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 {
 | 
				
			||||||
			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,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue