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

Commit 249a626c authored by Jeevan Shriram's avatar Jeevan Shriram
Browse files

msm: mdss: reset panel when wait4pingpong timeout is received



Due to various reasons wait4pingpong timeout can be observed and
this usually results in split screen behaviour for the end user.
Split screen is manifested because for a given frame only half of
the pixel data was sent and then some kind of hang was observed.
So unless the panel and display pipeline is restarted, next frames
will start from the location where it hanged. Improve user behavior
by resetting the display pipeline including panel by sending panel
dead event to user-space. Upon receiving this event user-space should
issue blank and un-blank which should recover the display pipeline.

Change-Id: Iec674a61229cbc037d24cf4f62ceb02a977b219c
Signed-off-by: default avatarUjwal Patel <ujwalp@codeaurora.org>
Signed-off-by: default avatarNaseer Ahmed <naseer@codeaurora.org>
Signed-off-by: default avatarJeevan Shriram <jshriram@codeaurora.org>
parent f0331928
Loading
Loading
Loading
Loading
+1 −28
Original line number Diff line number Diff line
@@ -18,33 +18,6 @@
#include "mdss_dsi.h"
#include "mdss_mdp.h"

/*
 * mdss_report_panel_dead() - Sends the PANEL_ALIVE=0 status to HAL layer.
 * @pstatus_data   : dsi status data
 *
 * This function is called if the panel fails to respond as expected to
 * the register read/BTA or if the TE signal is not coming as expected
 * from the panel. The function sends the PANEL_ALIVE=0 status to HAL
 * layer.
 */
static void mdss_report_panel_dead(struct dsi_status_data *pstatus_data)
{
	char *envp[2] = {"PANEL_ALIVE=0", NULL};
	struct mdss_panel_data *pdata =
		dev_get_platdata(&pstatus_data->mfd->pdev->dev);
	if (!pdata) {
		pr_err("%s: Panel data not available\n", __func__);
		return;
	}

	pdata->panel_info.panel_dead = true;
	kobject_uevent_env(&pstatus_data->mfd->fbi->dev->kobj,
		KOBJ_CHANGE, envp);
	pr_err("%s: Panel has gone bad, sending uevent - %s\n",
		__func__, envp[0]);
	return;
}

/*
 * mdss_check_te_status() - Check the status of panel for TE based ESD.
 * @ctrl_pdata   : dsi controller data
@@ -210,5 +183,5 @@ void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval)
	return;

status_dead:
	mdss_report_panel_dead(pstatus_data);
	mdss_fb_report_panel_dead(pstatus_data->mfd);
}
+25 −0
Original line number Diff line number Diff line
@@ -4333,3 +4333,28 @@ int mdss_fb_suspres_panel(struct device *dev, void *data)
	}
	return rc;
}

/*
 * mdss_fb_report_panel_dead() - Sends the PANEL_ALIVE=0 status to HAL layer.
 * @mfd   : frame buffer structure associated with fb device.
 *
 * This function is called if the panel fails to respond as expected to
 * the register read/BTA or if the TE signal is not coming as expected
 * from the panel. The function sends the PANEL_ALIVE=0 status to HAL
 * layer.
 */
void mdss_fb_report_panel_dead(struct msm_fb_data_type *mfd)
{
	char *envp[2] = {"PANEL_ALIVE=0", NULL};
	struct mdss_panel_data *pdata =
		dev_get_platdata(&mfd->pdev->dev);
	if (!pdata) {
		pr_err("Panel data not available\n");
		return;
	}

	pdata->panel_info.panel_dead = true;
	kobject_uevent_env(&mfd->fbi->dev->kobj,
		KOBJ_CHANGE, envp);
	pr_err("Panel has gone bad, sending uevent - %s\n", envp[0]);
}
+1 −0
Original line number Diff line number Diff line
@@ -435,4 +435,5 @@ int mdss_fb_async_position_update(struct fb_info *info,
		struct mdp_position_update *update_pos);

u32 mdss_fb_get_mode_switch(struct msm_fb_data_type *mfd);
void mdss_fb_report_panel_dead(struct msm_fb_data_type *mfd);
#endif /* MDSS_FB_H */
+1 −0
Original line number Diff line number Diff line
@@ -694,6 +694,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
					rc, ctl->num);
			MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl", "dsi0_phy",
				"dsi1_ctrl", "dsi1_phy", "panic");
			mdss_fb_report_panel_dead(ctl->mfd);
		}
		ctx->pp_timeout_report_cnt++;
		rc = -EPERM;