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

Commit 2d07aa47 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: ensure retire fences are signaled during panel off"

parents ffeb8875 f3dfb26c
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd);
static void __overlay_kickoff_requeue(struct msm_fb_data_type *mfd);
static int __mdss_mdp_overlay_check_zorder(struct mdss_data_type *mdata,
	struct mdp_overlay *req);
static void __vsync_retire_signal(struct msm_fb_data_type *mfd, int val);

static inline bool is_ov_right_blend(struct mdp_rect *left_blend,
	struct mdp_rect *right_blend, u32 left_lm_w)
{
@@ -3278,6 +3280,20 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
		mdss_mdp_overlay_kickoff(mfd, NULL);
	}

	/*
	 * If retire fences are still active wait for a vsync time
	 * for retire fence to be updated.
	 * As a last resort signal the timeline if vsync doesn't arrive.
	 */
	if (mdp5_data->retire_cnt) {
		u32 fps = mdss_panel_get_framerate(mfd->panel_info);
		u32 vsync_time = 1000 / (fps ? : DEFAULT_FRAME_RATE);

		msleep(vsync_time);

		__vsync_retire_signal(mfd, mdp5_data->retire_cnt);
	}

	mutex_lock(&mdp5_data->ov_lock);
	rc = mdss_mdp_ctl_stop(mdp5_data->ctl);
	if (rc == 0) {
@@ -3460,7 +3476,6 @@ static void __vsync_retire_work_handler(struct work_struct *work)
{
	struct mdss_overlay_private *mdp5_data =
		container_of(work, typeof(*mdp5_data), retire_work);
	struct msm_sync_pt_data *sync_pt_data;

	if (!mdp5_data->ctl || !mdp5_data->ctl->mfd)
		return;
@@ -3468,12 +3483,18 @@ static void __vsync_retire_work_handler(struct work_struct *work)
	if (!mdp5_data->ctl->remove_vsync_handler)
		return;

	sync_pt_data = &mdp5_data->ctl->mfd->mdp_sync_pt_data;
	mutex_lock(&sync_pt_data->sync_mutex);
	__vsync_retire_signal(mdp5_data->ctl->mfd, 1);
}

static void __vsync_retire_signal(struct msm_fb_data_type *mfd, int val)
{
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);

	mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex);
	if (mdp5_data->retire_cnt > 0) {
		sw_sync_timeline_inc(mdp5_data->vsync_timeline, 1);
		sw_sync_timeline_inc(mdp5_data->vsync_timeline, val);

		mdp5_data->retire_cnt--;
		mdp5_data->retire_cnt -= min(val, mdp5_data->retire_cnt);
		if (mdp5_data->retire_cnt == 0) {
			mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
			mdp5_data->ctl->remove_vsync_handler(mdp5_data->ctl,
@@ -3481,7 +3502,7 @@ static void __vsync_retire_work_handler(struct work_struct *work)
			mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
		}
	}
	mutex_unlock(&sync_pt_data->sync_mutex);
	mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex);
}

static struct sync_fence *
@@ -3507,7 +3528,7 @@ __vsync_retire_get_fence(struct msm_sync_pt_data *sync_pt_data)
		return ERR_PTR(-EPERM);
	}

	if (mdp5_data->retire_cnt == 0) {
	if (!mdp5_data->vsync_retire_handler.enabled) {
		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
		rc = ctl->add_vsync_handler(ctl,
				&mdp5_data->vsync_retire_handler);