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

Commit 5e8aea7d authored by Ujwal Patel's avatar Ujwal Patel
Browse files

msm: mdss: issue panic if pipe halt is requested while in use



Pipe halt is requested when pipe is no longer in use or when pipe
is initialized to be used. Now if there is a mismatch between SW state
of pipe being use and HW state then it can lead undesirable issues.
Issue panic if halt is requested while pipe is still in use by HW.

Change-Id: I11d20611eeb3cb991a4dc3e580fb83d86289b68d
Signed-off-by: default avatarUjwal Patel <ujwalp@codeaurora.org>
parent c4251672
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -712,6 +712,7 @@ 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_fb_stride(u32 fb_index, u32 xres, int bpp);

int mdss_panel_register_done(struct mdss_panel_data *pdata);
+9 −0
Original line number Diff line number Diff line
@@ -2702,6 +2702,15 @@ static inline int __mdss_mdp_ctl_get_mixer_off(struct mdss_mdp_mixer *mixer)
	}
}

u32 mdss_mdp_get_mixercfg(struct mdss_mdp_mixer *mixer)
{
	if (!mixer && !mixer->ctl)
		return 0;

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

static int __mdss_mdp_mixer_handoff_helper(struct mdss_mdp_mixer *mixer,
	struct mdss_mdp_pipe *pipe)
{
+43 −2
Original line number Diff line number Diff line
@@ -720,6 +720,43 @@ static int mdss_mdp_pipe_free(struct mdss_mdp_pipe *pipe)
	return 0;
}

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);
	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);

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
	for (i = 0; i < mdata->nctl; i++) {
		ctl = mdata->ctl_off + i;
		if (!ctl || !ctl->ref_cnt)
			continue;

		mixer = ctl->mixer_left;
		if (mixer && mixer->rotator_mode)
			continue;

		mixercfg = mdss_mdp_get_mixercfg(mixer);
		if ((mixercfg & stage_off_mask) && ctl->play_cnt) {
			pr_err("BUG. pipe%d is active. mcfg:0x%x mask:0x%x\n",
				pipe->num, mixercfg, stage_off_mask);
			BUG();
		}
	}
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);

	return in_use;
}

static int mdss_mdp_is_pipe_idle(struct mdss_mdp_pipe *pipe,
	bool ignore_force_on)
{
@@ -781,7 +818,7 @@ exit:
 */
int mdss_mdp_pipe_fetch_halt(struct mdss_mdp_pipe *pipe)
{
	bool is_idle;
	bool is_idle, in_use = false;
	int rc = 0;
	u32 reg_val, idle_mask, status;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
@@ -790,7 +827,11 @@ int mdss_mdp_pipe_fetch_halt(struct mdss_mdp_pipe *pipe)
	u32 clk_ctrl_off = pipe->clk_ctrl.reg_off;

	is_idle = mdss_mdp_is_pipe_idle(pipe, true);
	if (!is_idle) {
	if (!is_idle)
		in_use = mdss_mdp_check_pipe_in_use(pipe);

	if (!is_idle && !in_use) {

		pr_err("%pS: pipe%d is not idle. xin_id=%d\n",
			__builtin_return_address(0), pipe->num, pipe->xin_id);