Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c48b2fc authored by Sandeep Panda's avatar Sandeep Panda
Browse files

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: default avatarSandeep Panda <spanda@codeaurora.org>
parent 6f55033e
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -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);
+60 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ struct mdss_panel_cfg {

enum {
	MDP_INTF_CALLBACK_DSI_WAIT,
	MDP_INTF_CALLBACK_CHECK_LINE_COUNT,
};

struct mdss_intf_recovery {