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

Commit 62ea85df authored by Dhaval Patel's avatar Dhaval Patel
Browse files

mdss: mdp: fix pipe/mixer stage information during free



MDSS driver stages the pipe on certain mixer but does not
update the stage index to unused after un-stagging the pipe
from kickoff. It is better that pipe free api checks the
mixer stage before setting pipe mixer null. This helps
to catch the bugs where pipe is getting staged without
commit call.

This change tries to update the pipe free API with proper
error checks. It also avoids mixer free twice from ctl
destroy to avoid error messages at each suspend/resume.

Change-Id: I6facef86b0816378d79fd17737b0f335c59ebfa6
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent d9642cc2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ static void check_dsi_ctrl_status(struct work_struct *work)

	if (mdss_panel_is_power_off(pdsi_status->mfd->panel_power_state) ||
			pdsi_status->mfd->shutdown_pending) {
		pr_err("%s: panel off\n", __func__);
		pr_debug("%s: panel off\n", __func__);
		return;
	}

+1 −1
Original line number Diff line number Diff line
@@ -545,7 +545,7 @@ struct mdss_mdp_pipe {
	/* compression ratio from the source format */
	struct mult_factor comp_ratio;

	u8 mixer_stage;
	enum mdss_mdp_stage_index mixer_stage;
	u8 is_fg;
	u8 alpha;
	u8 blend_op;
+16 −19
Original line number Diff line number Diff line
@@ -2017,18 +2017,14 @@ int mdss_mdp_ctl_free(struct mdss_mdp_ctl *ctl)
		return -EINVAL;
	}

	if (ctl->mixer_left) {
	if (ctl->mixer_left && ctl->mixer_left->ref_cnt)
		mdss_mdp_mixer_free(ctl->mixer_left);
		ctl->mixer_left = NULL;
	}
	if (ctl->mixer_right) {

	if (ctl->mixer_right && ctl->mixer_right->ref_cnt)
		mdss_mdp_mixer_free(ctl->mixer_right);
		ctl->mixer_right = NULL;
	}
	if (ctl->wb) {

	if (ctl->wb)
		mdss_mdp_wb_free(ctl->wb);
		ctl->wb = NULL;
	}

	mutex_lock(&mdss_mdp_ctl_lock);
	ctl->ref_cnt--;
@@ -2036,6 +2032,9 @@ int mdss_mdp_ctl_free(struct mdss_mdp_ctl *ctl)
	ctl->intf_type = MDSS_MDP_NO_INTF;
	ctl->is_secure = false;
	ctl->power_state = MDSS_PANEL_POWER_OFF;
	ctl->mixer_left = NULL;
	ctl->mixer_right = NULL;
	ctl->wb = NULL;
	memset(&ctl->ops, 0, sizeof(ctl->ops));
	mutex_unlock(&mdss_mdp_ctl_lock);

@@ -3368,18 +3367,13 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl)
	 * it takes around 30us to have mdp finish resetting its ctl path
	 * poll every 50us so that reset should be completed at 1st poll
	 */

	do {
		udelay(50);
		status = mdss_mdp_ctl_read(ctl, MDSS_MDP_REG_CTL_SW_RESET);
		status &= 0x01;
		pr_debug("status=%x\n", status);
		cnt--;
		if (cnt == 0) {
			pr_err("ctl%d reset timedout\n", ctl->num);
			return -EAGAIN;
		}
	} while (status);
	} while (cnt > 0 && status);

	if (mixer) {
		mdss_mdp_pipe_reset(mixer);
@@ -3388,7 +3382,10 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl)
			mdss_mdp_pipe_reset(ctl->mixer_right);
	}

	return 0;
	if (!cnt)
		pr_err("ctl%d reset timedout\n", ctl->num);

	return (!cnt) ? -EAGAIN : 0;
}

static void mdss_mdp_set_mixer_roi(struct mdss_mdp_ctl *ctl,
@@ -3551,8 +3548,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);
			pr_err("pipe%d mixer:%d stage mismatch. pipe->mixer_stage=%d, mixer->stage_pipe=%d. skip staging it\n",
			    pipe->num, mixer->num, pipe->mixer_stage, stage);
			mixer->stage_pipe[i] = NULL;
			continue;
		}
@@ -4065,7 +4062,7 @@ int mdss_mdp_mixer_pipe_unstage(struct mdss_mdp_pipe *pipe,
		!(pipe->src_split_req && mixer->is_right_mixer);
	index = (pipe->mixer_stage * MAX_PIPES_PER_STAGE) + right_blend_index;

	if (pipe == mixer->stage_pipe[index]) {
	if (index < MAX_PIPES_PER_LM && pipe == mixer->stage_pipe[index]) {
		pr_debug("unstage p%d from %s side of stage=%d lm=%d ndx=%d\n",
			pipe->num, pipe->is_right_blend ? "right" : "left",
			pipe->mixer_stage, mixer->num, index);
+4 −1
Original line number Diff line number Diff line
@@ -1061,7 +1061,7 @@ static void __handle_free_list(struct mdss_overlay_private *mdp5_data,
static int __validate_layers(struct msm_fb_data_type *mfd,
	struct file *file, struct mdp_layer_commit_v1 *commit)
{
	int ret, i, release_ndx = 0;
	int ret, i, release_ndx = 0, inputndx = 0;
	u32 left_lm_layers = 0, right_lm_layers = 0;
	u32 left_cnt = 0, right_cnt = 0;
	u32 left_lm_w = left_lm_w_from_mfd(mfd);
@@ -1097,6 +1097,7 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
			ret = -EINVAL;
			goto end;
		}
		inputndx |= layer_list[i].pipe_ndx;
	}

	for (i = 0; i < layer_count; i++) {
@@ -1249,6 +1250,8 @@ validate_exit:
	pr_debug("err=%d total_layer:%d left:%d right:%d release_ndx=0x%x processed=%d\n",
		ret, layer_count, left_lm_layers, right_lm_layers,
		release_ndx, i);
	MDSS_XLOG(inputndx, layer_count, left_lm_layers, right_lm_layers,
		release_ndx, ret);
	mutex_lock(&mdp5_data->list_lock);
	list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
		if (IS_ERR_VALUE(ret)) {
+9 −1
Original line number Diff line number Diff line
@@ -1248,6 +1248,7 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd,
		if (recovery_mode) {
			mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left);
			mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right);
			pipe->mixer_stage = MDSS_MDP_STAGE_UNUSED;
		}
		__overlay_pipe_cleanup(mfd, pipe);
		ctl->mixer_left->next_pipe_map &= ~pipe->ndx;
@@ -1901,6 +1902,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
		mdss_mdp_pipe_queue_data(pipe, NULL);
		mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left);
		mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right);
		pipe->mixer_stage = MDSS_MDP_STAGE_UNUSED;
		list_move(&pipe->list, &destroy_pipes);
		need_cleanup = true;
	}
@@ -2017,8 +2019,14 @@ int mdss_mdp_overlay_release(struct msm_fb_data_type *mfd, int ndx)
				list_del_init(&pipe->list);

			mdss_mdp_pipe_unmap(pipe);
			if (destroy_pipe)
			if (destroy_pipe) {
				mdss_mdp_mixer_pipe_unstage(pipe,
					pipe->mixer_left);
				mdss_mdp_mixer_pipe_unstage(pipe,
					pipe->mixer_right);
				pipe->mixer_stage = MDSS_MDP_STAGE_UNUSED;
				__overlay_pipe_cleanup(mfd, pipe);
			}

			if (unset_ndx == ndx)
				break;
Loading