summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c34
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c11
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c11
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c23
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h3
5 files changed, 71 insertions, 11 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index c7cac996e5c0..797c8b4a2eb1 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1815,6 +1815,18 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata)
return 0;
}
+irqreturn_t test_hw_vsync_handler(int irq, void *data)
+{
+ struct mdss_panel_data *pdata = (struct mdss_panel_data *)data;
+
+ pr_debug("HW VSYNC\n");
+ MDSS_XLOG(0xaaa, irq);
+ complete_all(&pdata->te_done);
+ if (pdata->next)
+ complete_all(&pdata->next->te_done);
+ return IRQ_HANDLED;
+}
+
int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata)
{
int ret = 0;
@@ -3296,6 +3308,8 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
struct device_node *dsi_pan_node = NULL;
const char *ctrl_name;
struct mdss_util_intf *util;
+ static int te_irq_registered;
+ struct mdss_panel_data *pdata;
if (!pdev || !pdev->dev.of_node) {
pr_err("%s: pdev not found for DSI controller\n", __func__);
@@ -3421,6 +3435,23 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
disable_irq(gpio_to_irq(ctrl_pdata->disp_te_gpio));
}
+ pdata = &ctrl_pdata->panel_data;
+ init_completion(&pdata->te_done);
+ if (pdata->panel_info.type == MIPI_CMD_PANEL) {
+ if (!te_irq_registered) {
+ rc = devm_request_irq(&pdev->dev,
+ gpio_to_irq(pdata->panel_te_gpio),
+ test_hw_vsync_handler, IRQF_TRIGGER_FALLING,
+ "VSYNC_GPIO", &ctrl_pdata->panel_data);
+ if (rc) {
+ pr_err("%s: TE request_irq failed\n", __func__);
+ goto error_shadow_clk_deinit;
+ }
+ te_irq_registered = 1;
+ disable_irq_nosync(gpio_to_irq(pdata->panel_te_gpio));
+ }
+ }
+
rc = mdss_dsi_get_bridge_chip_params(pinfo, ctrl_pdata, pdev);
if (rc) {
pr_err("%s: Failed to get bridge params\n", __func__);
@@ -4241,6 +4272,8 @@ static int mdss_dsi_parse_gpio_params(struct platform_device *ctrl_pdev,
* If disp_en_gpio has been set previously (disp_en_gpio > 0)
* while parsing the panel node, then do not override it
*/
+ struct mdss_panel_data *pdata = &ctrl_pdata->panel_data;
+
if (ctrl_pdata->disp_en_gpio <= 0) {
ctrl_pdata->disp_en_gpio = of_get_named_gpio(
ctrl_pdev->dev.of_node,
@@ -4257,6 +4290,7 @@ static int mdss_dsi_parse_gpio_params(struct platform_device *ctrl_pdev,
if (!gpio_is_valid(ctrl_pdata->disp_te_gpio))
pr_err("%s:%d, TE gpio not specified\n",
__func__, __LINE__);
+ pdata->panel_te_gpio = ctrl_pdata->disp_te_gpio;
ctrl_pdata->bklt_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
"qcom,platform-bklight-en-gpio", 0);
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index 1a471155072b..007272dabae2 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -2558,15 +2558,8 @@ void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl)
if (!ctrl->mdp_busy)
rc = 1;
spin_unlock_irqrestore(&ctrl->mdp_lock, flags);
- if (!rc) {
- if (mdss_dsi_mdp_busy_tout_check(ctrl)) {
- pr_err("%s: timeout error\n", __func__);
- MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl",
- "dsi0_phy", "dsi1_ctrl", "dsi1_phy",
- "vbif", "vbif_nrt", "dbg_bus",
- "vbif_dbg_bus", "dsi_dbg_bus", "panic");
- }
- }
+ if (!rc && mdss_dsi_mdp_busy_tout_check(ctrl))
+ pr_err("%s: timeout error\n", __func__);
}
pr_debug("%s: done pid=%d\n", __func__, current->pid);
MDSS_XLOG(ctrl->ndx, ctrl->mdp_busy, current->pid, XLOG_FUNC_EXIT);
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 4eca9cb39223..c0fd48519124 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -4630,6 +4630,7 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
struct mdp_output_layer __user *output_layer_user;
struct mdp_destination_scaler_data *ds_data = NULL;
struct mdp_destination_scaler_data __user *ds_data_user;
+ struct msm_fb_data_type *mfd;
ret = copy_from_user(&commit, argp, sizeof(struct mdp_layer_commit));
if (ret) {
@@ -4637,6 +4638,16 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
return ret;
}
+ mfd = (struct msm_fb_data_type *)info->par;
+ if (!mfd)
+ return -EINVAL;
+
+ if (mfd->panel_info->panel_dead) {
+ pr_debug("early commit return\n");
+ MDSS_XLOG(mfd->panel_info->panel_dead);
+ return 0;
+ }
+
output_layer_user = commit.commit_v1.output_layer;
if (output_layer_user) {
buffer_size = sizeof(struct mdp_output_layer);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index bdbec0b4e721..2e017fe5ec02 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -21,6 +21,7 @@
#include "mdss_debug.h"
#include "mdss_mdp_trace.h"
#include "mdss_dsi_clk.h"
+#include <linux/interrupt.h>
#define MAX_RECOVERY_TRIALS 10
#define MAX_SESSIONS 2
@@ -2090,7 +2091,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
struct mdss_mdp_cmd_ctx *ctx;
struct mdss_panel_data *pdata;
unsigned long flags;
- int rc = 0;
+ int rc = 0, te_irq;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX];
if (!ctx) {
@@ -2144,7 +2145,21 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
__func__,
ctl->num, rc, ctx->pp_timeout_report_cnt,
atomic_read(&ctx->koff_cnt));
- if (ctx->pp_timeout_report_cnt == 0) {
+
+ /* enable TE irq to check if it is coming from the panel */
+ te_irq = gpio_to_irq(pdata->panel_te_gpio);
+ enable_irq(te_irq);
+
+ /* wait for 20ms to ensure we are getting the next TE */
+ usleep_range(20000, 20010);
+
+ reinit_completion(&pdata->te_done);
+ rc = wait_for_completion_timeout(&pdata->te_done, KOFF_TIMEOUT);
+
+ if (!rc) {
+ MDSS_XLOG(0xbac);
+ mdss_fb_report_panel_dead(ctl->mfd);
+ } else if (ctx->pp_timeout_report_cnt == 0) {
MDSS_XLOG(0xbad);
MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl", "dsi0_phy",
"dsi1_ctrl", "dsi1_phy", "vbif", "vbif_nrt",
@@ -2158,6 +2173,10 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
"dsi_dbg_bus", "panic");
mdss_fb_report_panel_dead(ctl->mfd);
}
+
+ /* disable te irq */
+ disable_irq_nosync(te_irq);
+
ctx->pp_timeout_report_cnt++;
rc = -EPERM;
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index fa1df94976f9..37b0ca7aa44b 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -997,6 +997,9 @@ struct mdss_panel_data {
* are still on; panel will recover after unblank
*/
bool panel_disable_mode;
+
+ int panel_te_gpio;
+ struct completion te_done;
};
struct mdss_panel_debugfs_info {