From a9416e66c1678fd6daadd7849b84a705ff11cec8 Mon Sep 17 00:00:00 2001 From: Jeevan Shriram Date: Fri, 1 May 2015 18:08:11 -0700 Subject: [PATCH] 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 Signed-off-by: Ujwal Patel Signed-off-by: Naseer Ahmed Signed-off-by: Jeevan Shriram --- drivers/video/fbdev/msm/mdss_dsi.c | 58 +++++++++++++++++++++++- drivers/video/fbdev/msm/mdss_dsi.h | 2 +- drivers/video/fbdev/msm/mdss_dsi_host.c | 7 +++ drivers/video/fbdev/msm/mdss_dsi_panel.c | 7 +-- drivers/video/fbdev/msm/mdss_mdp_ctl.c | 3 ++ drivers/video/fbdev/msm/mdss_panel.h | 3 ++ 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 {