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

Commit 036e7a9c authored by Adrian Salido-Moreno's avatar Adrian Salido-Moreno
Browse files

msm: mdss: push wait for fences and ping pong done as late as possible



All the configuration up until MDP flush is double buffered. This means
we are able to do all hardware programming without settings taking
effect until flush happens. Perform all programming, wait for fences
and wait for previous frame is done just before the flush in order to
reduce the time between last frame done and kickoff of next one.

Change-Id: I1fd0c7a65309a3b148c8efef61819bfe9a248f29
Signed-off-by: default avatarAdrian Salido-Moreno <adrianm@codeaurora.org>
parent c64144d1
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1875,6 +1875,11 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
		}
	}

	mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_READY);

	if (ctl->wait_pingpong)
		ctl->wait_pingpong(ctl, NULL);

	/* postprocessing setup, including dspp */
	mdss_mdp_pp_setup_locked(ctl);

+18 −1
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ struct mdss_mdp_cmd_ctx {
	struct mutex clk_mtx;
	spinlock_t clk_lock;
	struct work_struct clk_work;
	struct work_struct pp_done_work;
	atomic_t pp_done_cnt;
	struct mdss_panel_recovery recovery;
};

@@ -292,6 +294,8 @@ static void mdss_mdp_cmd_pingpong_done(void *arg)
	complete_all(&ctx->pp_comp);

	if (ctx->koff_cnt) {
		atomic_inc(&ctx->pp_done_cnt);
		schedule_work(&ctx->pp_done_work);
		ctx->koff_cnt--;
		if (ctx->koff_cnt) {
			pr_err("%s: too many kickoffs=%d!\n", __func__,
@@ -307,6 +311,16 @@ static void mdss_mdp_cmd_pingpong_done(void *arg)
	spin_unlock(&ctx->clk_lock);
}

static void pingpong_done_work(struct work_struct *work)
{
	struct mdss_mdp_cmd_ctx *ctx =
		container_of(work, typeof(*ctx), pp_done_work);

	if (ctx->ctl)
		while (atomic_add_unless(&ctx->pp_done_cnt, -1, 0))
			mdss_mdp_ctl_notify(ctx->ctl, MDP_NOTIFY_FRAME_DONE);
}

static void clk_ctrl_work(struct work_struct *work)
{
	struct mdss_mdp_cmd_ctx *ctx =
@@ -426,7 +440,6 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
			rc = -EPERM;
			mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT);
		} else {
			mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_DONE);
			rc = 0;
		}
	}
@@ -527,6 +540,8 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)

	mdss_mdp_cmd_clk_off(ctx);

	flush_work(&ctx->pp_done_work);

	ctx->panel_on = 0;

	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num,
@@ -593,6 +608,8 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl)
	spin_lock_init(&ctx->clk_lock);
	mutex_init(&ctx->clk_mtx);
	INIT_WORK(&ctx->clk_work, clk_ctrl_work);
	INIT_WORK(&ctx->pp_done_work, pingpong_done_work);
	atomic_set(&ctx->pp_done_cnt, 0);
	INIT_LIST_HEAD(&ctx->vsync_handlers);

	ctx->recovery.fxn = mdss_mdp_cmd_underflow_recovery;
+1 −15
Original line number Diff line number Diff line
@@ -885,14 +885,6 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
	mutex_lock(&mdp5_data->ov_lock);
	mutex_lock(&mfd->lock);

	ret = mdss_mdp_display_wait4pingpong(mdp5_data->ctl);
	if (ret) {
		mutex_unlock(&mfd->lock);
		mutex_unlock(&mdp5_data->ov_lock);
		if (ctl->shared_lock)
			mutex_unlock(ctl->shared_lock);
		return ret;
	}
	/*
	 * check if there is a secure display session
	 */
@@ -1016,13 +1008,6 @@ commit_fail:
	if (ctl->shared_lock)
		mutex_unlock(ctl->shared_lock);

	if (!IS_ERR_VALUE(ret)) {
		ret = mdss_mdp_display_wait4pingpong(mdp5_data->ctl);
		if (ret)
			pr_warn("wait for ping pong on fb%d failed!\n",
					mfd->index);
	}

	return ret;
}

@@ -2514,6 +2499,7 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
			goto init_fail;
		}
	}
	mfd->mdp_sync_pt_data.async_wait_fences = true;

	pm_runtime_set_suspended(&mfd->pdev->dev);
	pm_runtime_enable(&mfd->pdev->dev);