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

Commit f04daa23 authored by Abhijit Kulkarni's avatar Abhijit Kulkarni
Browse files

msm: mdss: enable dest_scaler data protection



This change enables the mutex for driver dest_scaler data structure.
Before this change display_thread could be updating the registers
based on the dest scaler data for the previous commit and the user
thread could go ahead and update the same data strcture for the
same commit. This could cause incorrect register programming.
This change necessitated moving the dest scaler update
out of pp updates so that we don't block the mutex till the end of
the commit.

CRs-Fixed: 1105994
Change-Id: I75d6f159e02fb1c0ed95bc5b6224843c61ec2da2
Signed-off-by: default avatarAbhijit Kulkarni <kabhijit@codeaurora.org>
parent ea4719da
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -555,6 +555,7 @@ struct mdss_mdp_ctl {
	bool switch_with_handoff;
	struct mdss_mdp_avr_info avr_info;
	bool commit_in_progress;
	struct mutex ds_lock;
};

struct mdss_mdp_mixer {
@@ -1969,6 +1970,7 @@ void mdss_mdp_enable_hw_irq(struct mdss_data_type *mdata);
void mdss_mdp_disable_hw_irq(struct mdss_data_type *mdata);

void mdss_mdp_set_supported_formats(struct mdss_data_type *mdata);
int mdss_mdp_dest_scaler_setup_locked(struct mdss_mdp_mixer *mixer);

#ifdef CONFIG_FB_MSM_MDP_NONE
struct mdss_data_type *mdss_mdp_get_mdata(void)
+1 −0
Original line number Diff line number Diff line
@@ -2407,6 +2407,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata,
			mutex_init(&ctl->flush_lock);
			mutex_init(&ctl->rsrc_lock);
			spin_lock_init(&ctl->spin_lock);
			mutex_init(&ctl->ds_lock);
			BLOCKING_INIT_NOTIFIER_HEAD(&ctl->notifier_head);
			pr_debug("alloc ctl_num=%d\n", ctl->num);
			break;
+6 −1
Original line number Diff line number Diff line
@@ -399,6 +399,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
		ctl   = mfd_to_ctl(mfd);
		sctl  = mdss_mdp_get_split_ctl(ctl);

		mutex_lock(&ctl->ds_lock);
		if (ctl->mixer_left)
			ds_left = ctl->mixer_left->ds;

@@ -412,6 +413,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
		case DS_DUAL_MODE:
			if (!ds_left || !ds_right) {
				pr_err("Cannot support DUAL mode dest scaling\n");
				mutex_unlock(&ctl->ds_lock);
				return -EINVAL;
			}

@@ -457,6 +459,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
		case DS_LEFT:
			if (!ds_left) {
				pr_err("LM in ctl does not support Destination Scaler\n");
				mutex_unlock(&ctl->ds_lock);
				return -EINVAL;
			}
			ds_left->flags &= ~(DS_DUAL_MODE|DS_RIGHT);
@@ -486,6 +489,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
		case DS_RIGHT:
			if (!ds_right) {
				pr_err("Cannot setup DS_RIGHT because only single DS assigned to ctl\n");
				mutex_unlock(&ctl->ds_lock);
				return -EINVAL;
			}

@@ -522,7 +526,6 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
					ds_right->src_height, ds_right->flags);
			break;
		}

	} else {
		pr_err("NULL destionation scaler data\n");
		return -EFAULT;
@@ -559,6 +562,7 @@ static int mdss_mdp_validate_destination_scaler(struct msm_fb_data_type *mfd,
		goto reset_mixer;
	}

	mutex_unlock(&ctl->ds_lock);
	return ret;

reset_mixer:
@@ -592,6 +596,7 @@ reset_mixer:
				ctl->mixer_right->height);
	}

	mutex_unlock(&ctl->ds_lock);
	return ret;
}

+20 −0
Original line number Diff line number Diff line
@@ -1471,6 +1471,23 @@ static void __unstage_pipe_and_clean_buf(struct msm_fb_data_type *mfd,
		__pipe_buf_mark_cleanup(mfd, buf);
}

static int __dest_scaler_setup(struct msm_fb_data_type *mfd)
{
	struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);

	mutex_lock(&ctl->ds_lock);

	if (ctl->mixer_left)
		mdss_mdp_dest_scaler_setup_locked(ctl->mixer_left);

	if (ctl->mixer_right)
		mdss_mdp_dest_scaler_setup_locked(ctl->mixer_right);

	mutex_unlock(&ctl->ds_lock);

	return 0;
}

static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
{
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
@@ -2394,6 +2411,9 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	mutex_unlock(&mdp5_data->list_lock);

	mdp5_data->kickoff_released = false;
	ATRACE_BEGIN("dest_scaler_programming");
	ret = __dest_scaler_setup(mfd);
	ATRACE_END("dest_scaler_programming");

	if (mfd->panel.type == WRITEBACK_PANEL) {
		ATRACE_BEGIN("wb_kickoff");
+5 −9
Original line number Diff line number Diff line
@@ -2559,7 +2559,7 @@ dspp_exit:
	return ret;
}

static int pp_dest_scaler_setup(struct mdss_mdp_mixer *mixer)
int mdss_mdp_dest_scaler_setup_locked(struct mdss_mdp_mixer *mixer)
{
	struct mdss_mdp_ctl *ctl;
	struct mdss_data_type *mdata;
@@ -2618,7 +2618,8 @@ static int pp_dest_scaler_setup(struct mdss_mdp_mixer *mixer)

	writel_relaxed(op_mode, MDSS_MDP_REG_DEST_SCALER_OP_MODE + ds_offset);

	if (ds->flags & DS_SCALE_UPDATE) {
	if ((ds->flags & DS_SCALE_UPDATE) ||
			(ds->flags & DS_ENHANCER_UPDATE)) {
		ret = mdss_mdp_qseed3_setup(&ds->scaler,
				ds->scaler_base, ds->lut_base,
				&dest_scaler_fmt);
@@ -2631,11 +2632,6 @@ static int pp_dest_scaler_setup(struct mdss_mdp_mixer *mixer)
		 * for each commit if there is no change.
		 */
		ds->flags &= ~DS_SCALE_UPDATE;
	}

	if (ds->flags & DS_ENHANCER_UPDATE) {
		mdss_mdp_scaler_detail_enhance_cfg(&ds->scaler.detail_enhance,
						ds->scaler_base);
		ds->flags &= ~DS_ENHANCER_UPDATE;
	}

@@ -2643,7 +2639,9 @@ static int pp_dest_scaler_setup(struct mdss_mdp_mixer *mixer)
	if (ds->flags & (DS_ENABLE | DS_VALIDATE)) {
		pr_debug("FLUSH[%d]: flags:%X, op_mode:%x\n",
				ds->num, ds->flags, op_mode);
		mutex_lock(&ctl->flush_lock);
		ctl->flush_bits |= BIT(13 + ds->num);
		mutex_unlock(&ctl->flush_lock);
	}

	ds->flags &= ~DS_VALIDATE;
@@ -2760,13 +2758,11 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
	}

	if (ctl->mixer_left) {
		pp_dest_scaler_setup(ctl->mixer_left);
		pp_mixer_setup(ctl->mixer_left);
		pp_dspp_setup(disp_num, ctl->mixer_left);
		pp_ppb_setup(ctl->mixer_left);
	}
	if (ctl->mixer_right) {
		pp_dest_scaler_setup(ctl->mixer_right);
		pp_mixer_setup(ctl->mixer_right);
		pp_dspp_setup(disp_num, ctl->mixer_right);
		pp_ppb_setup(ctl->mixer_right);