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

Commit 2cccedc2 authored by Jeykumar Sankaran's avatar Jeykumar Sankaran
Browse files

msm: mdss: Fix concurrent writeback failures in end-to-end use cases



User space may request of concurrent writeback (CWB) on the previously
programmed frame where input HW reprogramming may not be needed.
This change make sure mdp control flush is force triggered when
CWB is requested. Since signaling of fence timeline mandates a non-zero
commit count on the display, this change tracks a separate commit count
each time CWB is requested for the frame.

Change-Id: I7f6a134af9e5ad245a53063a90f1d7b625882a15
Signed-off-by: default avatarJeykumar Sankaran <jsanka@codeaurora.org>
parent c1cd824a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -410,7 +410,7 @@ struct mdss_mdp_cwb {
	struct list_head data_queue;
	int valid;
	u32 wb_idx;
	struct mdp_output_layer *layer;
	struct mdp_output_layer layer;
	void *priv_data;
	struct msm_sync_pt_data cwb_sync_pt_data;
	struct blocking_notifier_head notifier_head;
+8 −3
Original line number Diff line number Diff line
@@ -3424,6 +3424,7 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl)
	mutex_lock(&cwb->queue_lock);
	cwb_data = list_first_entry_or_null(&cwb->data_queue,
			struct mdss_mdp_wb_data, next);
	__list_del_entry(&cwb_data->next);
	mutex_unlock(&cwb->queue_lock);
	if (cwb_data == NULL) {
		pr_err("no output buffer for cwb\n");
@@ -3453,14 +3454,14 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl)
		sctl->opmode |= MDSS_MDP_CTL_OP_WFD_MODE;

	/* Select CWB data point */
	data_point = (cwb->layer->flags & MDP_COMMIT_CWB_DSPP) ? 0x4 : 0;
	data_point = (cwb->layer.flags & MDP_COMMIT_CWB_DSPP) ? 0x4 : 0;
	writel_relaxed(data_point, mdata->mdp_base + mdata->ppb_ctl[2]);
	if (sctl)
		writel_relaxed(data_point + 1,
				mdata->mdp_base + mdata->ppb_ctl[3]);

	/* Flush WB */
	ctl->flush_bits |= BIT(16);
	/* Flush WB and CTL */
	ctl->flush_bits |= BIT(16) | BIT(17);

	opmode = mdss_mdp_ctl_read(ctl, MDSS_MDP_REG_CTL_TOP) | ctl->opmode;
	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, opmode);
@@ -3469,6 +3470,10 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl)
			sctl->opmode;
		mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_TOP, opmode);
	}

	/* Increase commit count to signal CWB release fence */
	atomic_inc(&cwb->cwb_sync_pt_data.commit_cnt);

	goto cwb_setup_done;

cwb_setup_fail:
+1 −1
Original line number Diff line number Diff line
@@ -471,7 +471,7 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl,
	cwb = &mdp5_data->cwb;
	ctx = (struct mdss_mdp_writeback_ctx *)cwb->priv_data;

	buffer = &cwb->layer->buffer;
	buffer = &cwb->layer.buffer;

	ctx->opmode = 0;
	ctx->img_width = buffer->width;
+5 −5
Original line number Diff line number Diff line
@@ -2285,12 +2285,12 @@ end:
	return ret;
}

int __is_cwb_requested(uint32_t output_layer_flags)
int __is_cwb_requested(uint32_t commit_flags)
{
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	int req = 0;

	req = output_layer_flags & MDP_COMMIT_CWB_EN;
	req = commit_flags & MDP_COMMIT_CWB_EN;
	if (req && !test_bit(MDSS_CAPS_CWB_SUPPORTED, mdata->mdss_caps_map)) {
		pr_err("CWB not supported");
		return -ENODEV;
@@ -2330,7 +2330,7 @@ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd,
		return -EINVAL;

	if (commit->output_layer) {
		ret = __is_cwb_requested(commit->output_layer->flags);
		ret = __is_cwb_requested(commit->flags);
		if (IS_ERR_VALUE(ret)) {
			return ret;
		} else if (ret) {
@@ -2493,7 +2493,7 @@ int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd,
	}

	if (commit->output_layer) {
		rc = __is_cwb_requested(commit->output_layer->flags);
		rc = __is_cwb_requested(commit->flags);
		if (IS_ERR_VALUE(rc)) {
			return rc;
		} else if (rc) {
@@ -2553,7 +2553,7 @@ int mdss_mdp_layer_pre_commit_cwb(struct msm_fb_data_type *mfd,
		return rc;
	}

	mdp5_data->cwb.layer = commit->output_layer;
	mdp5_data->cwb.layer = *commit->output_layer;
	mdp5_data->cwb.wb_idx = commit->output_layer->writeback_ndx;

	mutex_lock(&mdp5_data->cwb.queue_lock);