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

Commit df838caa authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: enable source split with dual-dsi partial update"

parents 88fd8f05 128fd8c1
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -312,6 +312,15 @@ struct mdss_mdp_mixer {
	u16 cursor_hoty;
	u8 rotator_mode;

	/*
	 * src_split_req is valid only for right layer mixer.
	 *
	 * VIDEO mode panels: Always true if source split is enabled.
	 * CMD mode panels: Only true if source split is enabled and
	 *                  for a given commit left and right both ROIs
	 *                  are valid.
	 */
	bool src_split_req;
	bool is_right_mixer;
	struct mdss_mdp_ctl *ctl;
	struct mdss_mdp_pipe *stage_pipe[MAX_PIPES_PER_LM];
@@ -475,6 +484,8 @@ struct mdss_mdp_pipe {

	u32 flags;
	u32 bwc_mode;

	/* valid only when pipe's output is crossing both layer mixers */
	bool src_split_req;
	bool is_right_blend;

@@ -1053,13 +1064,18 @@ void mdss_mdp_data_free(struct mdss_mdp_data *data);

u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd);
int mdss_mdp_calc_phase_step(u32 src, u32 dst, u32 *out_phase);

void mdss_mdp_intersect_rect(struct mdss_rect *res_rect,
	const struct mdss_rect *dst_rect,
	const struct mdss_rect *sci_rect);
void mdss_mdp_crop_rect(struct mdss_rect *src_rect,
	struct mdss_rect *dst_rect,
	const struct mdss_rect *sci_rect);

void rect_copy_mdss_to_mdp(struct mdp_rect *user, struct mdss_rect *kernel);
void rect_copy_mdp_to_mdss(struct mdp_rect *user, struct mdss_rect *kernel);
bool mdss_rect_overlap_check(struct mdss_rect *rect1, struct mdss_rect *rect2);
void mdss_rect_split(struct mdss_rect *in_roi, struct mdss_rect *l_roi,
	struct mdss_rect *r_roi, u32 splitpoint);

int mdss_mdp_wb_kickoff(struct msm_fb_data_type *mfd,
		struct mdss_mdp_commit_cb *commit_cb);
@@ -1080,7 +1096,7 @@ int mdss_mdp_writeback_display_commit(struct mdss_mdp_ctl *ctl, void *arg);
struct mdss_mdp_ctl *mdss_mdp_ctl_mixer_switch(struct mdss_mdp_ctl *ctl,
					       u32 return_type);
void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
					struct mdp_display_commit *data);
	struct mdss_rect *l_roi, struct mdss_rect *r_roi);

int mdss_mdp_wb_set_format(struct msm_fb_data_type *mfd, u32 dst_format);
int mdss_mdp_wb_get_format(struct msm_fb_data_type *mfd,
+29 −31
Original line number Diff line number Diff line
@@ -2716,7 +2716,8 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl)
	return 0;
}

void mdss_mdp_set_mixer_roi(struct mdss_mdp_ctl *ctl, struct mdss_rect *roi)
static void mdss_mdp_set_mixer_roi(struct mdss_mdp_ctl *ctl,
	struct mdss_rect *roi)
{
	struct mdss_rect mixer_roi;

@@ -2753,39 +2754,29 @@ static inline u32 mdss_mdp_mpq_pipe_num_map(u32 pipe_num)
}

void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
		struct mdp_display_commit *data)
	struct mdss_rect *l_roi, struct mdss_rect *r_roi)
{
	struct mdss_rect l_roi, r_roi;

	l_roi.x = data->l_roi.x;
	l_roi.y = data->l_roi.y;
	l_roi.w = data->l_roi.w;
	l_roi.h = data->l_roi.h;

	r_roi.x = data->r_roi.x;
	r_roi.y = data->r_roi.y;
	r_roi.w = data->r_roi.w;
	r_roi.h = data->r_roi.h;

	/* Reset ROI when we have (1) invalid ROI (2) feature disabled */
	if ((!l_roi.w && l_roi.h) || (l_roi.w && !l_roi.h) ||
		(!r_roi.w && r_roi.h) || (r_roi.w && !r_roi.h) ||
		(!l_roi.w && !l_roi.h && !r_roi.w && !r_roi.h) ||
	if ((!l_roi->w && l_roi->h) || (l_roi->w && !l_roi->h) ||
	    (!r_roi->w && r_roi->h) || (r_roi->w && !r_roi->h) ||
	    (!l_roi->w && !l_roi->h && !r_roi->w && !r_roi->h) ||
	    !ctl->panel_data->panel_info.partial_update_enabled) {
		l_roi = (struct mdss_rect)
		{0, 0, ctl->mixer_left->width, ctl->mixer_left->height};

		*l_roi = (struct mdss_rect) {0, 0,
				ctl->mixer_left->width,
				ctl->mixer_left->height};

		if (ctl->mixer_right) {
			r_roi = (struct mdss_rect)
				{0, 0, ctl->mixer_right->width,
			*r_roi = (struct mdss_rect) {0, 0,
					ctl->mixer_right->width,
					ctl->mixer_right->height};
		}
	}

	mdss_mdp_set_mixer_roi(ctl, &l_roi);
	mdss_mdp_set_mixer_roi(ctl, l_roi);

	if (ctl->mixer_right)
		mdss_mdp_set_mixer_roi(ctl->mixer_right->ctl, &r_roi);
		mdss_mdp_set_mixer_roi(ctl->mixer_right->ctl, r_roi);
}

static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
@@ -2807,7 +2798,7 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
		return;

	ctl = mixer->ctl;
	if (!ctl)
	if (!ctl || !ctl->valid_roi)
		return;

	mixer->params_changed = 0;
@@ -2834,7 +2825,7 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
	if (pipe == NULL) {
		mixercfg = MDSS_MDP_LM_BORDER_COLOR;
	} else {
		if (ctl->mdata->mdp_rev == MDSS_MDP_HW_REV_200) {
		if (mdata->mdp_rev == MDSS_MDP_HW_REV_200) {
			mpq_num = mdss_mdp_mpq_pipe_num_map(pipe->num);
			mixercfg = 1 << (3 * mpq_num);
		} else if (pipe->num == MDSS_MDP_SSPP_VIG3 ||
@@ -2859,6 +2850,8 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,

		stage = i / MAX_PIPES_PER_STAGE;
		if (stage != pipe->mixer_stage) {
			pr_err("pipe%d stage mismatch. pipe->mixer_stage=%d, mixer->stage_pipe=%d. skip staging it\n",
				pipe->num, pipe->mixer_stage, stage);
			mixer->stage_pipe[i] = NULL;
			continue;
		}
@@ -2936,7 +2929,7 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
		if (!pipe->src_fmt->alpha_enable && bg_alpha_enable)
			mixer_op_mode = 0;

		if (ctl->mdata->mdp_rev == MDSS_MDP_HW_REV_200) {
		if (mdata->mdp_rev == MDSS_MDP_HW_REV_200) {
			mpq_num = mdss_mdp_mpq_pipe_num_map(pipe->num);
			mixercfg |= stage << (3 * mpq_num);
		} else if ((stage < MDSS_MDP_STAGE_6) &&
@@ -2997,7 +2990,7 @@ update_mixer:
	mixer_op_mode |=
		(mdp_mixer_read(mixer, MDSS_MDP_REG_LM_OP_MODE) & BIT(0));

	if (mdata->has_src_split && mixer_mux == MDSS_MDP_MIXER_MUX_RIGHT)
	if (mixer->src_split_req && mixer_mux == MDSS_MDP_MIXER_MUX_RIGHT)
		mixer_op_mode |= BIT(31);

	mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OP_MODE, mixer_op_mode);
@@ -3007,8 +3000,9 @@ update_mixer:
	mdss_mdp_ctl_write(ctl, off + MDSS_MDP_REG_CTL_LAYER_EXTN_OFFSET,
		mixercfg_extn);

	pr_debug("mixer=%d mixer_cfg=0%x mixercfg_extn=0x%x\n",
		mixer->num, mixercfg, mixercfg_extn);
	pr_debug("mixer=%d cfg=0%08x cfg_extn=0x%08x op_mode=0x%08x w=%d h=%d\n",
		mixer->num, mixercfg, mixercfg_extn,
		mixer_op_mode, mixer->roi.w, mixer->roi.h);
}

int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata,
@@ -3530,6 +3524,10 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
			PERF_SW_COMMIT_STATE, PERF_STATUS_BUSY);
	}

	if (sctl && mdata->has_src_split)
		sctl->mixer_left->src_split_req =
			(ctl->valid_roi == sctl->valid_roi);

	if (is_bw_released || ctl->force_screen_state ||
		(ctl->mixer_left && ctl->mixer_left->params_changed) ||
		(ctl->mixer_right && ctl->mixer_right->params_changed)) {
+125 −77
Original line number Diff line number Diff line
@@ -1575,37 +1575,59 @@ static int mdss_mdp_commit_cb(enum mdp_commit_stage_type commit_stage,
/**
 * __is_roi_valid() - Check if ctl roi is valid for a given pipe.
 * @pipe: pipe to check against.
 * @ctl_roi: roi of the ctl path.
 * @l_roi: roi of the left ctl path.
 * @r_roi: roi of the right ctl path.
 *
 * Validate ctl roi against pipe's destination rectangle by checking following
 * Validate roi against pipe's destination rectangle by checking following
 * conditions. If any of these conditions are met then return failure,
 * success otherwise.
 *
 * 1. Pipe has scaling and pipe's destination is intersecting with ctl roi.
 * 2. Pipe's destination and ctl roi overlap, meaning pipe's output is
 *    intersecting or within ctl roi. In such cases, pipe should not be
 *    part of used list and should have been omitted by user-land program.
 * 1. Pipe has scaling and pipe's destination is intersecting with roi.
 * 2. Pipe's destination and roi do not overlap, In such cases, pipe should
 *    not be part of used list and should have been omitted by user program.
 */
static bool __is_roi_valid(struct mdss_mdp_pipe *pipe,
	struct mdss_rect *ctl_roi)
	struct mdss_rect *l_roi, struct mdss_rect *r_roi)
{
	bool ret = true;
	bool is_right_mixer = pipe->mixer_left->is_right_mixer;
	struct mdss_rect roi = is_right_mixer ? *r_roi : *l_roi;
	struct mdss_rect dst = pipe->dst;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	u32 left_lm_w = left_lm_w_from_mfd(pipe->mfd);

	if (pipe->src_split_req)
		roi.w += r_roi->w;

	if (mdata->has_src_split && is_right_mixer)
		dst.x -= left_lm_w;

	/* condition #1 above */
	if (pipe->scale.enable_pxl_ext ||
	    (pipe->src.w != pipe->dst.w) ||
	    (pipe->src.h != pipe->dst.h)) {
	if ((pipe->scale.enable_pxl_ext) ||
	    (pipe->src.w != dst.w) || (pipe->src.h != dst.h)) {
		struct mdss_rect res;

		struct mdss_rect res = pipe->dst;
		mdss_mdp_intersect_rect(&res, &pipe->dst, ctl_roi);
		mdss_mdp_intersect_rect(&res, &dst, &roi);

		if (!mdss_rect_cmp(&res, &pipe->dst))
			return false;
		if (!mdss_rect_cmp(&res, &dst)) {
			pr_err("error. pipe%d has scaling and its output is interesecting with roi.\n",
				pipe->num);
			pr_err("pipe_dst:-> %d %d %d %d roi:-> %d %d %d %d\n",
				dst.x, dst.y, dst.w, dst.h,
				roi.x, roi.y, roi.w, roi.h);
			ret = false;
			goto end;
		}
	}

	/* condition #2 above */
	if (mdss_rect_overlap_check(&pipe->dst, ctl_roi))
		return false;

	return true;
	if (!mdss_rect_overlap_check(&dst, &roi)) {
		pr_err("error. pipe%d's output is outside of ROI.\n",
			pipe->num);
		ret = false;
	}
end:
	return ret;
}

void mdss_pend_mode_switch(struct msm_fb_data_type *mfd, bool pend_switch)
@@ -1616,7 +1638,7 @@ void mdss_pend_mode_switch(struct msm_fb_data_type *mfd, bool pend_switch)

int mdss_mode_switch(struct msm_fb_data_type *mfd, u32 mode)
{
	struct mdp_display_commit temp_data;
	struct mdss_rect l_roi, r_roi;
	struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
	int rc;

@@ -1628,14 +1650,15 @@ int mdss_mode_switch(struct msm_fb_data_type *mfd, u32 mode)
		 * Need to reset roi if there was partial update in previous
		 * Command frame
		 */
		temp_data.l_roi = (struct mdp_rect){0, 0,
			ctl->mixer_left->width, ctl->mixer_left->height};
		l_roi = (struct mdss_rect){0, 0,
				ctl->mixer_left->width,
				ctl->mixer_left->height};
		if (ctl->mixer_right) {
			temp_data.r_roi = (struct mdp_rect) {0, 0,
			r_roi = (struct mdss_rect) {0, 0,
				ctl->mixer_right->width,
				ctl->mixer_right->height};
		}
		mdss_mdp_set_roi(ctl, &temp_data);
		mdss_mdp_set_roi(ctl, &l_roi, &r_roi);
		mdss_mdp_switch_roi_reset(ctl);

		mdss_mdp_switch_to_cmd_mode(ctl, 1);
@@ -1698,16 +1721,92 @@ int mdss_mode_switch_post(struct msm_fb_data_type *mfd, u32 mode)
	return rc;
}

static void __validate_and_set_roi(struct msm_fb_data_type *mfd,
	struct mdp_display_commit *commit)
{
	struct mdss_mdp_pipe *pipe;
	struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
	struct mdss_rect l_roi, r_roi;
	bool skip_partial_update = true;

	if (commit) {
		rect_copy_mdp_to_mdss(&commit->l_roi, &l_roi);
		rect_copy_mdp_to_mdss(&commit->r_roi, &r_roi);

		pr_debug("input: l_roi:-> %d %d %d %d r_roi:-> %d %d %d %d\n",
			l_roi.x, l_roi.y, l_roi.w, l_roi.h,
			r_roi.x, r_roi.y, r_roi.w, r_roi.h);

		if (!ctl->panel_data->panel_info.partial_update_enabled)
			goto set_roi;

		skip_partial_update = false;

		if (is_split_lm(mfd) && mdp5_data->mdata->has_src_split) {
			u32 left_lm_w = left_lm_w_from_mfd(mfd);
			struct mdss_rect merged_roi = l_roi;

			/*
			 * When source split is enabled on split LM displays,
			 * user program merges left and right ROI and sends
			 * it through l_roi. Split this merged ROI into
			 * left/right ROI for validation.
			 */
			mdss_rect_split(&merged_roi, &l_roi, &r_roi, left_lm_w);

			/*
			 * When source split is enabled on split LM displays,
			 * it is a HW requirement that both LM have same width
			 * if update is on both sides. Since ROIs are
			 * generated by user-land program, validate against
			 * this requirement.
			 */
			if (l_roi.w && r_roi.w && (l_roi.w != r_roi.w)) {
				pr_err("error. ROI's do not match. violating src_split requirement\n");
				pr_err("l_roi:-> %d %d %d %d r_roi:-> %d %d %d %d\n",
					l_roi.x, l_roi.y, l_roi.w, l_roi.h,
					r_roi.x, r_roi.y, r_roi.w, r_roi.h);
				skip_partial_update = true;
				goto set_roi;
			}
		}

		list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
			if (!__is_roi_valid(pipe, &l_roi, &r_roi)) {
				skip_partial_update = true;
				pr_err("error. invalid pu config for pipe%d: %d,%d,%d,%d\n",
					pipe->num,
					pipe->dst.x, pipe->dst.y,
					pipe->dst.w, pipe->dst.h);
				break;
			}
		}
	}

set_roi:
	if (skip_partial_update) {
		l_roi = (struct mdss_rect){0, 0,
				ctl->mixer_left->width,
				ctl->mixer_left->height};
		if (ctl->mixer_right) {
			r_roi = (struct mdss_rect) {0, 0,
					ctl->mixer_right->width,
					ctl->mixer_right->height};
		}
	}
	mdss_mdp_set_roi(ctl, &l_roi, &r_roi);
}

int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
				struct mdp_display_commit *data)
{
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
	struct mdss_mdp_pipe *pipe, *tmp;
	struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
	struct mdp_display_commit temp_data;
	int ret = 0;
	int sd_in_pipe = 0;
	bool need_cleanup = false, skip_partial_update = true;
	bool need_cleanup = false;
	struct mdss_mdp_commit_cb commit_cb;
	LIST_HEAD(destroy_pipes);

@@ -1771,55 +1870,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);

	__vsync_set_vsync_handler(mfd);


	/*
	 * partial update should not be enabled if the source pipe has
	 * scaling enabled and that pipe's dst roi is intersecting with
	 * final roi. If this condition is detected then it is too late
	 * to return an error and force fallback strategy. Instead change
	 * the ROI to be full screen and continue with the update.
	 */
	if (data && ctl->panel_data->panel_info.partial_update_enabled) {
		struct mdss_rect ctl_roi;
		struct mdp_rect *in_roi;

		skip_partial_update = false;
		list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
			in_roi = pipe->mixer_left->is_right_mixer ?
				&data->r_roi : &data->l_roi;

			ctl_roi.x = in_roi->x;
			ctl_roi.y = in_roi->y;
			ctl_roi.w = in_roi->w;
			ctl_roi.h = in_roi->h;

			if (!__is_roi_valid(pipe, &ctl_roi)) {
				skip_partial_update = true;
				pr_debug("error. invalid config with partial update for pipe%d\n",
					pipe->num);
				pr_debug("ctl_roi: %d,%d,%d,%d pipe->dst: %d,%d,%d,%d\n",
					ctl_roi.x, ctl_roi.y, ctl_roi.w,
					ctl_roi.h, pipe->dst.x, pipe->dst.y,
					pipe->dst.w, pipe->dst.h);
				break;
			}
		}
	}

	if (!skip_partial_update) {
		mdss_mdp_set_roi(ctl, data);
	} else {
		memset(&temp_data, 0, sizeof(temp_data));

		temp_data.l_roi = (struct mdp_rect){0, 0,
			ctl->mixer_left->width, ctl->mixer_left->height};
		if (ctl->mixer_right) {
			temp_data.r_roi = (struct mdp_rect) {0, 0,
			ctl->mixer_right->width, ctl->mixer_right->height};
		}
		mdss_mdp_set_roi(ctl, &temp_data);
	}
	__validate_and_set_roi(mfd, data);

	if (ctl->ops.wait_pingpong && mdp5_data->mdata->serialize_wait4pp)
		mdss_mdp_display_wait4pingpong(ctl, true);
@@ -4797,9 +4848,6 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
	if (is_panel_split(mfd) && mdp5_data->mdata->has_pingpong_split)
		mfd->split_mode = MDP_PINGPONG_SPLIT;

	if (mfd->panel_info->partial_update_enabled && is_split_lm(mfd))
		mdp5_data->mdata->has_src_split = false;

	if (mfd->panel_info->partial_update_enabled)
		mdp5_data->mdata->pp_enable = MDP_PP_DISABLE;
	else
+25 −6
Original line number Diff line number Diff line
@@ -1355,8 +1355,8 @@ static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe,
	u32 decimation, reg_data;
	u32 tmp_src_xy, tmp_src_size;
	int ret = 0;
	struct mdss_rect dst, src;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	struct mdss_rect sci, dst, src;
	bool rotation = false;

	pr_debug("ctl: %d pnum=%d wh=%dx%d src={%d,%d,%d,%d} dst={%d,%d,%d,%d}\n",
@@ -1395,14 +1395,33 @@ static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe,
		pr_debug("Image decimation h=%d v=%d\n",
				pipe->horz_deci, pipe->vert_deci);

	sci = pipe->mixer_left->ctl->roi;
	dst = pipe->dst;
	src = pipe->src;

	if ((pipe->mixer_left->type != MDSS_MDP_MIXER_TYPE_WRITEBACK) &&
		!pipe->mixer_left->ctl->is_video_mode &&
		!pipe->src_split_req) {
		mdss_mdp_crop_rect(&src, &dst, &sci);
	if (!pipe->mixer_left->ctl->is_video_mode &&
	    (pipe->mixer_left->type != MDSS_MDP_MIXER_TYPE_WRITEBACK)) {
		struct mdss_rect ctl_roi = pipe->mixer_left->ctl->roi;
		bool is_right_mixer = pipe->mixer_left->is_right_mixer;
		/* sctl can be NULL, check validity before use */
		struct mdss_mdp_ctl *sctl =
			mdss_mdp_get_split_ctl(pipe->mixer_left->ctl);
		/* main_ctl can be NULL, check validity before use */
		struct mdss_mdp_ctl *main_ctl =
			mdss_mdp_get_main_ctl(pipe->mixer_left->ctl);

		if (pipe->src_split_req && sctl)
			ctl_roi.w += sctl->roi.w;
		else if (mdata->has_src_split && is_right_mixer && main_ctl)
			dst.x -= main_ctl->mixer_left->width;

		mdss_mdp_crop_rect(&src, &dst, &ctl_roi);

		if (is_right_mixer && main_ctl) {
			/* left + right */
			if (main_ctl->valid_roi)
				dst.x += main_ctl->roi.w;
		}

		if (pipe->flags & MDP_FLIP_LR) {
			src.x = pipe->src.x + (pipe->src.x + pipe->src.w)
				- (src.x + src.w);
+105 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include "mdss_mdp.h"
#include "mdss_mdp_formats.h"
#include "mdss_debug.h"
#include "mdss_panel.h"

enum {
	MDP_INTR_VSYNC_INTF_0,
@@ -283,6 +284,110 @@ void mdss_mdp_crop_rect(struct mdss_rect *src_rect,
	}
}

/*
 * rect_copy_mdp_to_mdss() - copy mdp_rect struct to mdss_rect
 * @mdp  - pointer to mdp_rect, destination of the copy
 * @mdss - pointer to mdss_rect, source of the copy
 */
void rect_copy_mdss_to_mdp(struct mdp_rect *mdp, struct mdss_rect *mdss)
{
	mdp->x = mdss->x;
	mdp->y = mdss->y;
	mdp->w = mdss->w;
	mdp->h = mdss->h;
}

/*
 * rect_copy_mdp_to_mdss() - copy mdp_rect struct to mdss_rect
 * @mdp  - pointer to mdp_rect, source of the copy
 * @mdss - pointer to mdss_rect, destination of the copy
 */
void rect_copy_mdp_to_mdss(struct mdp_rect *mdp, struct mdss_rect *mdss)
{
	mdss->x = mdp->x;
	mdss->y = mdp->y;
	mdss->w = mdp->w;
	mdss->h = mdp->h;
}

/*
 * mdss_rect_cmp() - compares two rects
 * @rect1 - rect value to compare
 * @rect2 - rect value to compare
 *
 * Returns 1 if the rects are same, 0 otherwise.
 */
int mdss_rect_cmp(struct mdss_rect *rect1, struct mdss_rect *rect2)
{
	return rect1->x == rect2->x && rect1->y == rect2->y &&
	       rect1->w == rect2->w && rect1->h == rect2->h;
}

/*
 * mdss_rect_overlap_check() - compare two rects and check if they overlap
 * @rect1 - rect value to compare
 * @rect2 - rect value to compare
 *
 * Returns true if rects overlap, false otherwise.
 */
bool mdss_rect_overlap_check(struct mdss_rect *rect1, struct mdss_rect *rect2)
{
	u32 rect1_left = rect1->x, rect1_right = rect1->x + rect1->w;
	u32 rect1_top = rect1->y, rect1_bottom = rect1->y + rect1->h;
	u32 rect2_left = rect2->x, rect2_right = rect2->x + rect2->w;
	u32 rect2_top = rect2->y, rect2_bottom = rect2->y + rect2->h;

	if ((rect1_right <= rect2_left) ||
	    (rect1_left >= rect2_right) ||
	    (rect1_bottom <= rect2_top) ||
	    (rect1_top >= rect2_bottom))
		return false;

	return true;
}

/*
 * mdss_rect_split() - split roi into two with regards to split-point.
 * @in_roi - input roi, non-split
 * @l_roi  - left roi after split
 * @r_roi  - right roi after split
 *
 * Split input ROI into left and right ROIs with respect to split-point. This
 * is useful during partial update with ping-pong split enabled, where user-land
 * program is aware of only one frame-buffer but physically there are two
 * distinct panels which requires their own ROIs.
 */
void mdss_rect_split(struct mdss_rect *in_roi, struct mdss_rect *l_roi,
	struct mdss_rect *r_roi, u32 splitpoint)
{
	memset(l_roi, 0x0, sizeof(*l_roi));
	memset(r_roi, 0x0, sizeof(*r_roi));

	/* left update needed */
	if (in_roi->x < splitpoint) {
		*l_roi = *in_roi;

		if ((l_roi->x + l_roi->w) >= splitpoint)
			l_roi->w = splitpoint - in_roi->x;
	}

	/* right update needed */
	if ((in_roi->x + in_roi->w) > splitpoint) {
		*r_roi = *in_roi;

		if (in_roi->x < splitpoint) {
			r_roi->x = 0;
			r_roi->w = in_roi->x + in_roi->w - splitpoint;
		} else {
			r_roi->x = in_roi->x - splitpoint;
		}
	}

	pr_debug("left: %d,%d,%d,%d right: %d,%d,%d,%d\n",
		l_roi->x, l_roi->y, l_roi->w, l_roi->h,
		r_roi->x, r_roi->y, r_roi->w, r_roi->h);
}

int mdss_mdp_get_rau_strides(u32 w, u32 h,
			       struct mdss_mdp_format_params *fmt,
			       struct mdss_mdp_plane_sizes *ps)
Loading