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

Commit cbdc2976 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran
Browse files

msm: mdss: fix pipe_in_use to check layer extn registers



Previously, only the base mixercfg was used to determine if the pipe
is in use. The extn registers were not checked, resulting in faulty
checks for cursor and any pipe staged in stage6. Fix validation to
include checks for extn registers. And refactor, to get the mixer mask
from utility functions.

Change-Id: Id356fa3255d796abdc596cbfbae6604aa7cf57f0
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent 7b141a87
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1243,7 +1243,9 @@ int mdss_mdp_wb_kickoff(struct msm_fb_data_type *mfd,
int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);

int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id);
u32 mdss_mdp_get_mixercfg(struct mdss_mdp_mixer *mixer);
u32 mdss_mdp_get_mixer_mask(u32 pipe_num, u32 stage);
u32 mdss_mdp_get_mixer_extn_mask(u32 pipe_num, u32 stage);
u32 mdss_mdp_get_mixercfg(struct mdss_mdp_mixer *mixer, bool extn);
u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp);
void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval);

+61 −43
Original line number Diff line number Diff line
@@ -3522,6 +3522,48 @@ void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
		mdss_mdp_set_mixer_roi(ctl->mixer_right->ctl, r_roi);
}

u32 mdss_mdp_get_mixer_mask(u32 pipe_num, u32 stage)
{
	u32 mask = 0;

	if ((pipe_num == MDSS_MDP_SSPP_VIG3 ||
			pipe_num == MDSS_MDP_SSPP_RGB3)) {
		/* Add 2 to account for Cursor & Border bits */
		mask = stage << ((3 * pipe_num) + 2);
	} else {
		mask = stage << (3 * pipe_num);
	}
	return mask;
}

u32 mdss_mdp_get_mixer_extn_mask(u32 pipe_num, u32 stage)
{
	u32 mask = 0;

	/*
	 * The ctl layer extension bits are ordered
	 * VIG0-3, RGB0-3, DMA0-1
	 */
	if (pipe_num < MDSS_MDP_SSPP_RGB0) {
		mask = BIT(pipe_num << 1);
	} else if (pipe_num >= MDSS_MDP_SSPP_RGB0 &&
			pipe_num < MDSS_MDP_SSPP_DMA0) {
		mask = BIT((pipe_num + 1) << 1);
	} else if (pipe_num >= MDSS_MDP_SSPP_DMA0 &&
			pipe_num < MDSS_MDP_SSPP_VIG3) {
		mask = BIT((pipe_num + 2) << 1);
	} else if (pipe_num >= MDSS_MDP_SSPP_CURSOR0 &&
			pipe_num <= MDSS_MDP_SSPP_CURSOR1) {
		mask = stage << (20 + (6 * (pipe_num - MDSS_MDP_SSPP_CURSOR0)));
	} else if (pipe_num == MDSS_MDP_SSPP_VIG3) {
		mask = BIT(6);
	} else if (pipe_num == MDSS_MDP_SSPP_RGB3) {
		mask = BIT(14);
	}

	return mask;
}

static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
	int mixer_mux)
{
@@ -3572,16 +3614,12 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
	if (pipe == NULL) {
		mixercfg = MDSS_MDP_LM_BORDER_COLOR;
	} else {
		if (pipe->num == MDSS_MDP_SSPP_VIG3 ||
			pipe->num == MDSS_MDP_SSPP_RGB3) {
			/* Add 2 to account for Cursor & Border bits */
			mixercfg = 1 << ((3 * pipe->num)+2);
		} else if (pipe->type == MDSS_MDP_PIPE_TYPE_CURSOR) {
			mixercfg_extn = BIT(20 + (6 *
					(pipe->num - MDSS_MDP_SSPP_CURSOR0)));
		} else {
			mixercfg = 1 << (3 * pipe->num);
		}
		if (pipe->type == MDSS_MDP_PIPE_TYPE_CURSOR)
			mixercfg_extn |= mdss_mdp_get_mixer_extn_mask(
						pipe->num, 1);
		else
			mixercfg  |= mdss_mdp_get_mixer_mask(pipe->num, 1);

		if (pipe->src_fmt->alpha_enable)
			bg_alpha_enable = 1;
	}
@@ -3681,36 +3719,11 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
			mixer_op_mode = 0;

		if ((stage < MDSS_MDP_STAGE_6) &&
			(pipe->num == MDSS_MDP_SSPP_VIG3 ||
			 pipe->num == MDSS_MDP_SSPP_RGB3)) {
			/*
			 * STAGE_6 require extension register
			 * Add 2 to account for Cursor & Border bits
			 */
			mixercfg |= stage << ((3 * pipe->num)+2);
		} else if (pipe->type == MDSS_MDP_PIPE_TYPE_CURSOR) {
			mixercfg_extn |= stage << (20 + (6 *
					(pipe->num - MDSS_MDP_SSPP_CURSOR0)));
		} else if (stage < MDSS_MDP_STAGE_6) {
			mixercfg |= stage << (3 * pipe->num);
		} else {
			/*
			 * The ctl layer extension bits are ordered
			 * VIG0-3, RGB0-3, DMA0-1
			 */
			if (pipe->num < MDSS_MDP_SSPP_RGB0)
				mixercfg_extn |= BIT(pipe->num << 1);
			else if (pipe->num >= MDSS_MDP_SSPP_RGB0  &&
					pipe->num < MDSS_MDP_SSPP_DMA0)
				mixercfg_extn |= BIT((pipe->num + 1) << 1);
			else if (pipe->num >= MDSS_MDP_SSPP_DMA0 &&
					pipe->num < MDSS_MDP_SSPP_VIG3)
				mixercfg_extn |= BIT((pipe->num + 2) << 1);
			else if (pipe->num == MDSS_MDP_SSPP_VIG3)
				mixercfg_extn |= BIT(6);
			(pipe->type != MDSS_MDP_PIPE_TYPE_CURSOR))
			mixercfg |= mdss_mdp_get_mixer_mask(pipe->num, stage);
		else
				mixercfg_extn |= BIT(14);
		}
			mixercfg_extn |= mdss_mdp_get_mixer_extn_mask(
						pipe->num, stage);

		trace_mdp_sspp_change(pipe);

@@ -4676,13 +4689,18 @@ static inline int __mdss_mdp_ctl_get_mixer_off(struct mdss_mdp_mixer *mixer)
	}
}

u32 mdss_mdp_get_mixercfg(struct mdss_mdp_mixer *mixer)
u32 mdss_mdp_get_mixercfg(struct mdss_mdp_mixer *mixer, bool extn)
{
	u32 mixer_off;

	if (!mixer || !mixer->ctl)
		return 0;

	return mdss_mdp_ctl_read(mixer->ctl,
		__mdss_mdp_ctl_get_mixer_off(mixer));
	mixer_off = __mdss_mdp_ctl_get_mixer_off(mixer);
	mixer_off = extn ? (mixer_off + MDSS_MDP_REG_CTL_LAYER_EXTN_OFFSET) :
				mixer_off;

	return mdss_mdp_ctl_read(mixer->ctl, mixer_off);
}

static int __mdss_mdp_mixer_handoff_helper(struct mdss_mdp_mixer *mixer,
+18 −14
Original line number Diff line number Diff line
@@ -1336,17 +1336,15 @@ static void mdss_mdp_pipe_free(struct kref *kref)
static bool mdss_mdp_check_pipe_in_use(struct mdss_mdp_pipe *pipe)
{
	int i;
	u32 mixercfg, stage_off_mask = BIT(0) | BIT(1) | BIT(2);
	u32 mixercfg, mixercfg_extn, stage_off_mask, stage_off_extn_mask;
	u32 stage = BIT(0) | BIT(1) | BIT(2);
	bool in_use = false;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	struct mdss_mdp_ctl *ctl;
	struct mdss_mdp_mixer *mixer;

	if (pipe->num == MDSS_MDP_SSPP_VIG3 ||
	    pipe->num == MDSS_MDP_SSPP_RGB3)
		stage_off_mask = stage_off_mask << ((3 * pipe->num) + 2);
	else
		stage_off_mask = stage_off_mask << (3 * pipe->num);
	stage_off_mask = mdss_mdp_get_mixer_mask(pipe->num, stage);
	stage_off_extn_mask = mdss_mdp_get_mixer_extn_mask(pipe->num, stage);

	for (i = 0; i < mdata->nctl; i++) {
		ctl = mdata->ctl_off + i;
@@ -1357,21 +1355,27 @@ static bool mdss_mdp_check_pipe_in_use(struct mdss_mdp_pipe *pipe)
		if (mixer && mixer->rotator_mode)
			continue;

		mixercfg = mdss_mdp_get_mixercfg(mixer);
		if (mixercfg & stage_off_mask) {
			pr_err("IN USE: mixer=%d pipe=%d mcfg:0x%x mask:0x%x\n",
		mixercfg = mdss_mdp_get_mixercfg(mixer, false);
		mixercfg_extn = mdss_mdp_get_mixercfg(mixer, true);
		if ((mixercfg & stage_off_mask) ||
			(mixercfg_extn & stage_off_extn_mask)) {
			pr_err("IN USE: mixer=%d pipe=%d mcfg:0x%x mask:0x%x mcfg_extn:0x%x mask_ext:0x%x\n",
				mixer->num, pipe->num,
				mixercfg, stage_off_mask);
				mixercfg, stage_off_mask,
				mixercfg_extn, stage_off_extn_mask);
			MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt",
				"dbg_bus", "vbif_dbg_bus", "panic");
		}

		mixer = ctl->mixer_right;
		mixercfg = mdss_mdp_get_mixercfg(mixer);
		if (mixercfg & stage_off_mask) {
			pr_err("IN USE: mixer=%d pipe=%d mcfg:0x%x mask:0x%x\n",
		mixercfg = mdss_mdp_get_mixercfg(mixer, false);
		mixercfg_extn = mdss_mdp_get_mixercfg(mixer, true);
		if ((mixercfg & stage_off_mask) ||
			(mixercfg_extn & stage_off_extn_mask)) {
			pr_err("IN USE: mixer=%d pipe=%d mcfg:0x%x mask:0x%x mcfg_extn:0x%x mask_ext:0x%x\n",
				mixer->num, pipe->num,
				mixercfg, stage_off_mask);
				mixercfg, stage_off_mask,
				mixercfg_extn, stage_off_extn_mask);
			MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt",
				"dbg_bus", "vbif_dbg_bus", "panic");
		}