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

Commit 968c3e82 authored by Dhaval Patel's avatar Dhaval Patel Committed by Gerrit - the friendly Code Review server
Browse files

msm: mdss: generate panic if HW recovery fails during underrun



HW recovery is triggered when underrun happens. If pipe
XIN halt status is checked during the recovery time frame, it
would fail as the hw is in the recovery process. Check for the
ctl reset status before every frame update and if it is set,
add the same polling mechanism used while sw reset is triggered
to ensure hw reset is complete before checking the pipe status.
And add panic if hw fails to recover within the max polling time.

Change-Id: Ia672195b519e76bc4560d4555222c26fde094a64
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent 9f7af2ec
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1209,6 +1209,7 @@ int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl,
int mdss_mdp_cmd_reconfigure_splash_done(struct mdss_mdp_ctl *ctl,
		bool handoff);
int mdss_mdp_ctl_splash_finish(struct mdss_mdp_ctl *ctl, bool handoff);
void mdss_mdp_check_ctl_reset_status(struct mdss_mdp_ctl *ctl);
int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl);
int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl,
		struct mdss_panel_data *pdata);
+53 −17
Original line number Diff line number Diff line
@@ -3857,6 +3857,54 @@ static void mdss_mdp_pipe_reset(struct mdss_mdp_mixer *mixer, bool is_recovery)
	}
}

static u32 mdss_mdp_poll_ctl_reset_status(struct mdss_mdp_ctl *ctl, u32 cnt)
{
	u32 status;
	/*
	 * 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, count=%d\n", status, cnt);
		cnt--;
	} while (cnt > 0 && status);

	return status;
}

/*
 * mdss_mdp_check_ctl_reset_status() - checks ctl reset status
 * @ctl: mdp controller
 *
 * This function checks the ctl reset status before every frame update.
 * If the reset bit is set, it keeps polling the status till the hw
 * reset is complete. And does a panic if hw fails to complet the reset
 * with in the max poll interval.
 */
void mdss_mdp_check_ctl_reset_status(struct mdss_mdp_ctl *ctl)
{
	u32 status;

	if (!ctl)
		return;

	status = mdss_mdp_ctl_read(ctl, MDSS_MDP_REG_CTL_SW_RESET);
	status &= 0x01;
	if (!status)
		return;

	pr_debug("hw ctl reset is set for ctl:%d\n", ctl->num);
	status = mdss_mdp_poll_ctl_reset_status(ctl, 5);
	if (status) {
		pr_err("hw recovery is not complete for ctl:%d\n", ctl->num);
		MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt", "dbg_bus",
			"vbif_dbg_bus", "panic");
	}
}

/*
 * mdss_mdp_ctl_reset() - reset mdp ctl path.
 * @ctl: mdp controller.
@@ -3867,8 +3915,7 @@ static void mdss_mdp_pipe_reset(struct mdss_mdp_mixer *mixer, bool is_recovery)
 */
int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl, bool is_recovery)
{
	u32 status = 1;
	int cnt = 20;
	u32 status;
	struct mdss_mdp_mixer *mixer;

	if (!ctl) {
@@ -3879,17 +3926,9 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl, bool is_recovery)
	mixer = ctl->mixer_left;
	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_SW_RESET, 1);

	/*
	 * 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--;
	} while (cnt > 0 && status);
	status = mdss_mdp_poll_ctl_reset_status(ctl, 20);
	if (status)
		pr_err("sw ctl:%d reset timedout\n", ctl->num);

	if (mixer) {
		mdss_mdp_pipe_reset(mixer, is_recovery);
@@ -3898,10 +3937,7 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl, bool is_recovery)
			mdss_mdp_pipe_reset(ctl->mixer_right, is_recovery);
	}

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

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

/*
+1 −0
Original line number Diff line number Diff line
@@ -1953,6 +1953,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);

	mdss_mdp_check_ctl_reset_status(ctl);
	__vsync_set_vsync_handler(mfd);
	__validate_and_set_roi(mfd, data);