summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeevan Shriram <jshriram@codeaurora.org>2015-05-01 18:08:11 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:43:23 -0700
commita9416e66c1678fd6daadd7849b84a705ff11cec8 (patch)
treec3fe38b46b70d2c1e9b7c2d373a0ec19412d35dc
parent50b9827d5bf63a5348845abdacedc122bc04693b (diff)
msm: mdss: dsi: Add dsi event to reset panel write pointer
There are instances where the mdp wants to reset to full screen especially during frame timeouts. Add event to s/w reset the dsi core and reset the panel's ram write coordinates to full screen. Change-Id: I43e5cb12126837330f3ed72386f87f5c7fabd2c0 Signed-off-by: Siddhartha Agrawal <agrawals@codeaurora.org> Signed-off-by: Ujwal Patel <ujwalp@codeaurora.org> Signed-off-by: Naseer Ahmed <naseer@codeaurora.org> Signed-off-by: Jeevan Shriram <jshriram@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c58
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c7
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_panel.c7
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h3
6 files changed, 75 insertions, 5 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 60c697b1b5fb..04b2241fadf1 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1805,11 +1805,14 @@ static int mdss_dsi_ctl_partial_roi(struct mdss_panel_data *pdata)
return -EINVAL;
}
+ if (!pdata->panel_info.partial_update_enabled)
+ return 0;
+
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
if (ctrl_pdata->set_col_page_addr)
- rc = ctrl_pdata->set_col_page_addr(pdata);
+ rc = ctrl_pdata->set_col_page_addr(pdata, false);
return rc;
}
@@ -1882,6 +1885,56 @@ static int mdss_dsi_set_stream_size(struct mdss_panel_data *pdata)
return 0;
}
+static int mdss_dsi_reset_write_ptr(struct mdss_panel_data *pdata)
+{
+
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ struct mdss_panel_info *pinfo;
+ int rc = 0;
+
+ if (pdata == NULL) {
+ pr_err("%s: Invalid input data\n", __func__);
+ return -EINVAL;
+ }
+
+ ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+ panel_data);
+
+ pinfo = &ctrl_pdata->panel_data.panel_info;
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
+ /* Need to reset the DSI core since the pixel stream was stopped. */
+ mdss_dsi_sw_reset(ctrl_pdata, true);
+
+ /*
+ * Reset the partial update co-ordinates to the panel height and
+ * width
+ */
+ if (pinfo->dcs_cmd_by_left && (ctrl_pdata->ndx == 1))
+ goto skip_cmd_send;
+
+ pinfo->roi.x = 0;
+ pinfo->roi.y = 0;
+ pinfo->roi.w = pinfo->xres;
+ if (pinfo->dcs_cmd_by_left)
+ pinfo->roi.w = pinfo->xres;
+ if (pdata->next)
+ pinfo->roi.w += pdata->next->panel_info.xres;
+ pinfo->roi.h = pinfo->yres;
+
+ mdss_dsi_set_stream_size(pdata);
+
+ if (ctrl_pdata->set_col_page_addr)
+ rc = ctrl_pdata->set_col_page_addr(pdata, true);
+
+skip_cmd_send:
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
+
+ pr_debug("%s: DSI%d write ptr reset finished\n", __func__,
+ ctrl_pdata->ndx);
+
+ return rc;
+}
+
int mdss_dsi_register_recovery_handler(struct mdss_dsi_ctrl_pdata *ctrl,
struct mdss_intf_recovery *recovery)
{
@@ -2001,6 +2054,9 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
case MDSS_EVENT_ENABLE_PARTIAL_ROI:
rc = mdss_dsi_ctl_partial_roi(pdata);
break;
+ case MDSS_EVENT_DSI_RESET_WRITE_PTR:
+ rc = mdss_dsi_reset_write_ptr(pdata);
+ break;
case MDSS_EVENT_DSI_STREAM_SIZE:
rc = mdss_dsi_set_stream_size(pdata);
break;
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index 858231f95b4f..d00d79bc8ece 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -348,7 +348,7 @@ struct mdss_dsi_ctrl_pdata {
int (*post_panel_on)(struct mdss_panel_data *pdata);
int (*off) (struct mdss_panel_data *pdata);
int (*low_power_config) (struct mdss_panel_data *pdata, int enable);
- int (*set_col_page_addr) (struct mdss_panel_data *pdata);
+ int (*set_col_page_addr)(struct mdss_panel_data *pdata, bool force);
int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
int (*check_read_status) (struct mdss_dsi_ctrl_pdata *pdata);
int (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index 7b58ae8c5300..ad94090b47b4 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -436,6 +436,7 @@ void mdss_dsi_set_tx_power_mode(int mode, struct mdss_panel_data *pdata)
void mdss_dsi_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl, bool restore)
{
u32 data0;
+ unsigned long flag;
if (!ctrl) {
pr_err("%s: Invalid input data\n", __func__);
@@ -464,6 +465,12 @@ void mdss_dsi_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl, bool restore)
MIPI_OUTP(ctrl->ctrl_base + 0x0004, data0);
wmb(); /* make sure dsi controller enabled again */
}
+
+ /* It is safe to clear mdp_busy as reset is happening */
+ spin_lock_irqsave(&ctrl->mdp_lock, flag);
+ ctrl->mdp_busy = false;
+ complete_all(&ctrl->mdp_comp);
+ spin_unlock_irqrestore(&ctrl->mdp_lock, flag);
}
static void mdss_dsi_cfg_lane_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index 7a94e53521b1..85abaadd3d79 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -448,7 +448,8 @@ static void mdss_dsi_send_col_page_addr(struct mdss_dsi_ctrl_pdata *ctrl,
mdss_dsi_cmdlist_put(ctrl, &cmdreq);
}
-static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata)
+static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata,
+ bool force_send)
{
struct mdss_panel_info *pinfo;
struct mdss_rect roi = {0};
@@ -487,7 +488,7 @@ static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata)
}
/* roi had changed, do col_page update */
- if (!mdss_rect_cmp(c_roi, &roi)) {
+ if (force_send || !mdss_rect_cmp(c_roi, &roi)) {
pr_debug("%s: ndx=%d x=%d y=%d w=%d h=%d\n",
__func__, ctrl->ndx, p_roi->x,
p_roi->y, p_roi->w, p_roi->h);
@@ -1572,8 +1573,8 @@ static int mdss_dsi_parse_panel_features(struct device_node *np,
pinfo->partial_update_enabled = pinfo->partial_update_supported;
pr_info("%s: partial_update_enabled=%d\n", __func__,
pinfo->partial_update_enabled);
+ ctrl->set_col_page_addr = mdss_dsi_set_col_page_addr;
if (pinfo->partial_update_enabled) {
- ctrl->set_col_page_addr = mdss_dsi_set_col_page_addr;
pinfo->partial_update_roi_merge =
of_property_read_bool(np,
"qcom,partial-update-roi-merge");
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 197961315efb..d4f2f6a082d9 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -4206,6 +4206,9 @@ int mdss_mdp_display_wait4pingpong(struct mdss_mdp_ctl *ctl, bool use_lock)
if (sctl)
mdss_mdp_ctl_reset(sctl);
+ mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_DSI_RESET_WRITE_PTR, NULL);
+
pr_debug("pingpong timeout recovery finished\n");
}
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index 7cf1afcf6963..a2069218d1e5 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -214,6 +214,8 @@ struct mdss_intf_recovery {
* @MDSS_EVENT_DSI_RECONFIG_CMD: Setup DSI controller in new mode
* - MIPI_VIDEO_PANEL: switch to video mode
* - MIPI_CMD_PANEL: switch to command mode
+ * @MDSS_EVENT_DSI_RESET_WRITE_PTR: Reset the write pointer coordinates on
+ * the panel.
*/
enum mdss_intf_events {
MDSS_EVENT_RESET = 1,
@@ -240,6 +242,7 @@ enum mdss_intf_events {
MDSS_EVENT_DSI_PANEL_STATUS,
MDSS_EVENT_DSI_DYNAMIC_SWITCH,
MDSS_EVENT_DSI_RECONFIG_CMD,
+ MDSS_EVENT_DSI_RESET_WRITE_PTR,
};
struct lcd_panel_info {