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>
This commit is contained in:
Jeevan Shriram 2015-05-01 18:08:11 -07:00 committed by David Keitel
parent 50b9827d5b
commit a9416e66c1
6 changed files with 75 additions and 5 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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");

View file

@ -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");
}

View file

@ -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 {