summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandeep Panda <spanda@codeaurora.org>2017-03-06 14:27:48 +0530
committerSandeep Panda <spanda@codeaurora.org>2017-03-16 13:03:50 +0530
commit0c48b2fcf88cc95606ffe47e7e6a07436627ac4a (patch)
tree2136f5d14afd95f42ea36466debb3b417cd44b2c
parent6f55033ecf068f77136caac2e7c4a7869b3ec2bd (diff)
msm: mdss: read active line count before triggering BTA
In the current implementation before triggering BTA, DSI SW waits for extra time to skip display blanking period. Add an additional check for active line count to ensure that BTA is always triggered during display active region only. Change-Id: Ife67f5a38fa9e8df6f8431e9d2b0179c207adeb2 Signed-off-by: Sandeep Panda <spanda@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c25
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c60
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h1
3 files changed, 84 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index 98c5eda02f5b..982e7a02ffa3 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -41,6 +41,8 @@
#define LANE_SWAP_CTRL 0x0B0
#define LOGICAL_LANE_SWAP_CTRL 0x310
+#define MAX_BTA_WAIT_RETRY 5
+
#define CEIL(x, y) (((x) + ((y)-1)) / (y))
struct mdss_dsi_ctrl_pdata *ctrl_list[DSI_CTRL_MAX];
@@ -1451,8 +1453,7 @@ static int mdss_dsi_wait4video_eng_busy(struct mdss_dsi_ctrl_pdata *ctrl)
if (ctrl->ctrl_state & CTRL_STATE_MDP_ACTIVE) {
mdss_dsi_wait4video_done(ctrl);
v_total = mdss_panel_get_vtotal(pinfo);
- v_blank = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch +
- pinfo->lcdc.v_pulse_width;
+ v_blank = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width;
if (pinfo->dynamic_fps && pinfo->current_fps)
fps = pinfo->current_fps;
else
@@ -1483,6 +1484,8 @@ int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
int ret = 0;
unsigned long flag;
int ignore_underflow = 0;
+ int retry_count = 0;
+ int in_blanking = 0;
if (ctrl_pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -1508,7 +1511,25 @@ int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
reinit_completion(&ctrl_pdata->bta_comp);
mdss_dsi_enable_irq(ctrl_pdata, DSI_BTA_TERM);
spin_unlock_irqrestore(&ctrl_pdata->mdp_lock, flag);
+wait:
mdss_dsi_wait4video_eng_busy(ctrl_pdata);
+ if (ctrl_pdata->panel_mode == DSI_VIDEO_MODE) {
+ in_blanking = ctrl_pdata->mdp_callback->fxn(
+ ctrl_pdata->mdp_callback->data,
+ MDP_INTF_CALLBACK_CHECK_LINE_COUNT);
+ /* Try for maximum of 5 attempts */
+ if (in_blanking && (retry_count < MAX_BTA_WAIT_RETRY)) {
+ pr_debug("%s: not in active region\n", __func__);
+ retry_count++;
+ goto wait;
+ }
+ }
+ if (retry_count == MAX_BTA_WAIT_RETRY)
+ MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl",
+ "dsi0_phy", "dsi1_ctrl", "dsi1_phy",
+ "vbif", "vbif_nrt", "dbg_bus",
+ "vbif_dbg_bus", "panic");
+
/* mask out overflow errors */
if (ignore_underflow)
mdss_dsi_set_reg(ctrl_pdata, 0x10c, 0x0f0000, 0x0f0000);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index 67cbf076b8ac..7537ca13d2c0 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -83,6 +83,7 @@ struct mdss_mdp_video_ctx {
struct mutex vsync_mtx;
struct list_head vsync_handlers;
struct mdss_intf_recovery intf_recovery;
+ struct mdss_intf_recovery intf_mdp_callback;
struct work_struct early_wakeup_dfps_work;
atomic_t lineptr_ref;
@@ -1896,6 +1897,58 @@ static void mdss_mdp_handoff_programmable_fetch(struct mdss_mdp_ctl *ctl,
}
}
+static int mdss_mdp_video_intf_callback(void *data, int event)
+{
+ struct mdss_mdp_video_ctx *ctx;
+ struct mdss_mdp_ctl *ctl = data;
+ struct mdss_panel_info *pinfo;
+ u32 line_cnt, min_ln_cnt, active_lns_cnt, line_buff = 50;
+
+ if (!data) {
+ pr_err("%s: invalid ctl\n", __func__);
+ return -EINVAL;
+ }
+
+ ctx = ctl->intf_ctx[MASTER_CTX];
+ pr_debug("%s: ctl num = %d, event = %d\n",
+ __func__, ctl->num, event);
+
+ if (!ctl->is_video_mode)
+ return 0;
+
+ pinfo = &ctl->panel_data->panel_info;
+ min_ln_cnt = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width;
+ active_lns_cnt = pinfo->yres;
+
+ switch (event) {
+ case MDP_INTF_CALLBACK_CHECK_LINE_COUNT:
+ if (!ctl || !ctx || !ctx->timegen_en) {
+ pr_debug("%s: no need to check for active line\n",
+ __func__);
+ goto end;
+ }
+
+ line_cnt = mdss_mdp_video_line_count(ctl);
+
+ if ((line_cnt >= min_ln_cnt) && (line_cnt <
+ (min_ln_cnt + active_lns_cnt - line_buff))) {
+ pr_debug("%s: line count is within active range=%d\n",
+ __func__, line_cnt);
+ goto end;
+ } else {
+ pr_debug("line count is less. line_cnt = %d\n",
+ line_cnt);
+ return -EPERM;
+ }
+ break;
+ default:
+ pr_debug("%s: unhandled event!\n", __func__);
+ break;
+ }
+end:
+ return 0;
+}
+
static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_video_ctx *ctx, struct mdss_panel_info *pinfo)
{
@@ -1929,6 +1982,13 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl,
pr_err("Failed to register intf recovery handler\n");
return -EINVAL;
}
+
+ ctx->intf_mdp_callback.fxn = mdss_mdp_video_intf_callback;
+ ctx->intf_mdp_callback.data = ctl;
+ mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_REGISTER_MDP_CALLBACK,
+ (void *)&ctx->intf_mdp_callback,
+ CTL_INTF_EVENT_FLAG_DEFAULT);
} else {
ctx->intf_recovery.fxn = NULL;
ctx->intf_recovery.data = NULL;
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index e75c4a3a7cc1..d5de8807f7a6 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -186,6 +186,7 @@ struct mdss_panel_cfg {
enum {
MDP_INTF_CALLBACK_DSI_WAIT,
+ MDP_INTF_CALLBACK_CHECK_LINE_COUNT,
};
struct mdss_intf_recovery {