Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb4306e6 authored by Ujwal Patel's avatar Ujwal Patel Committed by Matt Wagantall
Browse files

msm: mdss: add support to validate pixel extension calculations



If a layer needs a scaling than its pixel extension values are calculated
in the user-space library and passed down to driver. Currently driver
blindly programs these settings to HW without validating for correctness.
This leads to HW hangs and stability issues. Add a proper sanitization
checks for pixel extension and report error back to user-space if any.

Change-Id: I086cf0b23fbccd37a23bb509f067bffdf396c247
Signed-off-by: default avatarUjwal Patel <ujwalp@codeaurora.org>
Signed-off-by: default avatarJeevan Shriram <jshriram@codeaurora.org>
parent ef83408b
Loading
Loading
Loading
Loading
+69 −2
Original line number Diff line number Diff line
@@ -430,6 +430,70 @@ static int __mdp_pipe_tune_perf(struct mdss_mdp_pipe *pipe,
	return 0;
}

static int __mdss_mdp_validate_pxl_extn(struct mdss_mdp_pipe *pipe)
{
	int plane;

	for (plane = 0; plane < MAX_PLANES; plane++) {
		u32 hor_req_pixels, hor_fetch_pixels;
		u32 vert_req_pixels, vert_fetch_pixels;
		u32 src_w = pipe->src.w >> pipe->horz_deci;
		u32 src_h = pipe->src.h >> pipe->vert_deci;

		/*
		 * plane 1 and 2 are for chroma and are same. While configuring
		 * HW, programming only one of the chroma components is
		 * sufficient.
		 */
		if (plane == 2)
			continue;

		/*
		 * For chroma plane, width is half for the following sub sampled
		 * formats
		 */
		if (plane == 1 &&
		    ((pipe->src_fmt->chroma_sample == MDSS_MDP_CHROMA_420) ||
		     (pipe->src_fmt->chroma_sample == MDSS_MDP_CHROMA_H2V1)))
			src_w >>= 1;

		if (plane == 1 &&
		    ((pipe->src_fmt->chroma_sample == MDSS_MDP_CHROMA_420) ||
		     (pipe->src_fmt->chroma_sample == MDSS_MDP_CHROMA_H1V2)))
			src_h >>= 1;

		hor_req_pixels = pipe->scale.roi_w[plane] +
			pipe->scale.num_ext_pxls_left[plane] +
			pipe->scale.num_ext_pxls_right[plane];

		hor_fetch_pixels = src_w +
			pipe->scale.left_ftch[plane] +
			pipe->scale.left_rpt[plane] +
			pipe->scale.right_ftch[plane] +
			pipe->scale.right_rpt[plane];

		vert_req_pixels = src_h + pipe->scale.num_ext_pxls_top[plane] +
			pipe->scale.num_ext_pxls_btm[plane];

		vert_fetch_pixels = src_h + pipe->scale.top_ftch[plane] +
			pipe->scale.top_rpt[plane] +
			pipe->scale.btm_ftch[plane] +
			pipe->scale.btm_rpt[plane];

		if ((hor_req_pixels != hor_fetch_pixels) ||
			(hor_fetch_pixels > pipe->img_width) ||
			(vert_req_pixels != vert_fetch_pixels) ||
			(vert_fetch_pixels > pipe->img_height)) {
			pr_err("err: h_req:%d h_fetch:%d v_req:%d v_fetch:%d\n",
					hor_req_pixels, hor_fetch_pixels,
					vert_req_pixels, vert_fetch_pixels);
			return -EINVAL;
		}
	}

	return 0;
}

static int __mdss_mdp_overlay_setup_scaling(struct mdss_mdp_pipe *pipe)
{
	u32 src;
@@ -437,8 +501,11 @@ static int __mdss_mdp_overlay_setup_scaling(struct mdss_mdp_pipe *pipe)

	src = pipe->src.w >> pipe->horz_deci;

	if (pipe->scale.enable_pxl_ext)
		return 0;
	if (pipe->scale.enable_pxl_ext) {
		rc = __mdss_mdp_validate_pxl_extn(pipe);
		return rc;
	}

	memset(&pipe->scale, 0, sizeof(struct mdp_scale_data));
	rc = mdss_mdp_calc_phase_step(src, pipe->dst.w,
			&pipe->scale.phase_step_x[0]);