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

Commit 509a9e8b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: Issue ctl sw reset when underrun happens"

parents 3ae6d56f cb78c355
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -186,6 +186,9 @@ struct mdss_mdp_ctl {

	struct mdss_panel_data *panel_data;
	struct mdss_mdp_vsync_handler vsync_handler;
	struct mdss_mdp_vsync_handler recover_underrun_handler;
	struct work_struct recover_work;
	struct work_struct remove_underrun_handler;

	struct mdss_mdp_img_rect roi;
	struct mdss_mdp_img_rect roi_bkup;
+19 −0
Original line number Diff line number Diff line
@@ -468,6 +468,21 @@ static int mdss_mdp_video_wait4comp(struct mdss_mdp_ctl *ctl, void *arg)
	return rc;
}

static void recover_underrun_work(struct work_struct *work)
{
	struct mdss_mdp_ctl *ctl =
		container_of(work, typeof(*ctl), recover_work);

	if (!ctl || !ctl->add_vsync_handler) {
		pr_err("ctl or vsync handler is NULL\n");
		return;
	}

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
	ctl->add_vsync_handler(ctl, &ctl->recover_underrun_handler);
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
}

static void mdss_mdp_video_underrun_intr_done(void *arg)
{
	struct mdss_mdp_ctl *ctl = arg;
@@ -479,6 +494,9 @@ static void mdss_mdp_video_underrun_intr_done(void *arg)
	MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0", "dsi1", "edp", "hdmi", "panic");
	pr_debug("display underrun detected for ctl=%d count=%d\n", ctl->num,
			ctl->underrun_cnt);

	if (ctl->opmode & MDSS_MDP_CTL_OP_PACK_3D_ENABLE)
		schedule_work(&ctl->recover_work);
}

static int mdss_mdp_video_vfp_fps_update(struct mdss_mdp_ctl *ctl, int new_fps)
@@ -804,6 +822,7 @@ int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl)
	spin_lock_init(&ctx->vsync_lock);
	mutex_init(&ctx->vsync_mtx);
	atomic_set(&ctx->vsync_ref, 0);
	INIT_WORK(&ctl->recover_work, recover_underrun_work);

	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num,
				   mdss_mdp_video_vsync_intr_done, ctl);
+36 −0
Original line number Diff line number Diff line
@@ -1873,6 +1873,35 @@ pan_display_error:
	mutex_unlock(&mdp5_data->ov_lock);
}

static void remove_underrun_vsync_handler(struct work_struct *work)
{
	int rc;
	struct mdss_mdp_ctl *ctl =
		container_of(work, typeof(*ctl), remove_underrun_handler);

	if (!ctl || !ctl->remove_vsync_handler) {
		pr_err("ctl or vsync handler is NULL\n");
		return;
	}

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
	rc = ctl->remove_vsync_handler(ctl,
			&ctl->recover_underrun_handler);
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
}

static void mdss_mdp_recover_underrun_handler(struct mdss_mdp_ctl *ctl,
						ktime_t t)
{
	if (!ctl) {
		pr_err("ctl is NULL\n");
		return;
	}

	mdss_mdp_ctl_reset(ctl);
	schedule_work(&ctl->remove_underrun_handler);
}

/* function is called in irq context should have minimum processing */
static void mdss_mdp_overlay_handle_vsync(struct mdss_mdp_ctl *ctl,
						ktime_t t)
@@ -3041,6 +3070,13 @@ static struct mdss_mdp_ctl *__mdss_mdp_overlay_ctl_init(
					mdss_mdp_overlay_handle_vsync;
	ctl->vsync_handler.cmd_post_flush = false;

	ctl->recover_underrun_handler.vsync_handler =
			mdss_mdp_recover_underrun_handler;
	ctl->recover_underrun_handler.cmd_post_flush = false;

	INIT_WORK(&ctl->remove_underrun_handler,
				remove_underrun_vsync_handler);

	if (mfd->split_display && pdata->next) {
		/* enable split display */
		rc = mdss_mdp_ctl_split_display_setup(ctl, pdata->next);