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

Commit f238d6bc 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: Separate PP programming to advanced and deferred modes"

parents 0bdf562c 0afc86ca
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -142,6 +142,25 @@

#define BITS_TO_BYTES(x) DIV_ROUND_UP(x, BITS_PER_BYTE)

#define PP_PROGRAM_PA		0x1
#define PP_PROGRAM_PCC		0x2
#define PP_PROGRAM_IGC		0x4
#define PP_PROGRAM_ARGC	0x8
#define PP_PROGRAM_HIST	0x10
#define PP_PROGRAM_DITHER	0x20
#define PP_PROGRAM_GAMUT	0x40
#define PP_PROGRAM_PGC		0x100
#define PP_PROGRAM_PA_DITHER	0x400
#define PP_PROGRAM_AD		0x800

#define PP_NORMAL_PROGRAM_MASK	(PP_PROGRAM_AD | PP_PROGRAM_PCC | \
				PP_PROGRAM_HIST)
#define PP_DEFER_PROGRAM_MASK	(PP_PROGRAM_IGC | PP_PROGRAM_PGC | \
				PP_PROGRAM_ARGC | PP_PROGRAM_GAMUT | \
				PP_PROGRAM_PA | PP_PROGRAM_DITHER | \
						PP_PROGRAM_PA_DITHER)
#define PP_PROGRAM_ALL	(PP_NORMAL_PROGRAM_MASK | PP_DEFER_PROGRAM_MASK)

enum mdss_mdp_perf_state_type {
	PERF_SW_COMMIT_STATE = 0,
	PERF_HW_MDP_STATE,
@@ -773,6 +792,12 @@ struct mdss_pipe_pp_res {
	void *hist_lut_cfg_payload;
};

struct mdss_mdp_pp_program_info {
	u32 pp_program_mask;
	u32 pp_opmode_left;
	u32 pp_opmode_right;
};

struct mdss_mdp_pipe_smp_map {
	DECLARE_BITMAP(reserved, MAX_DRV_SUP_MMB_BLKS);
	DECLARE_BITMAP(allocated, MAX_DRV_SUP_MMB_BLKS);
@@ -1803,7 +1828,8 @@ int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd);
void mdss_mdp_pp_dest_scaler_resume(struct mdss_mdp_ctl *ctl);

int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl);
int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl);
int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl,
				struct mdss_mdp_pp_program_info *info);
int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
void mdss_mdp_pipe_pp_clear(struct mdss_mdp_pipe *pipe);
int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
+17 −3
Original line number Diff line number Diff line
@@ -5752,6 +5752,9 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
	bool is_bw_released, split_lm_valid;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	u32 ctl_flush_bits = 0, sctl_flush_bits = 0;
	/* Must initialize pp_program_info */
	struct mdss_mdp_pp_program_info pp_program_info = {
						PP_PROGRAM_ALL, 0, 0};

	if (!ctl) {
		pr_err("display function not set\n");
@@ -5864,9 +5867,13 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
		mdss_mdp_ctl_split_display_enable(split_lm_valid, ctl, sctl);

	ATRACE_BEGIN("postproc_programming");
	if (ctl->is_video_mode && ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER)
	if (ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) {
		/* postprocessing setup, including dspp */
		mdss_mdp_pp_setup_locked(ctl);
		if (!ctl->is_video_mode)
			pp_program_info.pp_program_mask =
							PP_NORMAL_PROGRAM_MASK;
		mdss_mdp_pp_setup_locked(ctl, &pp_program_info);
	}

	if (sctl) {
		if (ctl->split_flush_en) {
@@ -5922,11 +5929,17 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
	}

	/* Moved pp programming to post ping pong */
	ATRACE_BEGIN("postproc_programming_deferred");
	if (!ctl->is_video_mode && ctl->mfd &&
			ctl->mfd->dcm_state != DTM_ENTER) {
		/* postprocessing setup, including dspp */
		mutex_lock(&ctl->flush_lock);
		mdss_mdp_pp_setup_locked(ctl);
		pp_program_info.pp_program_mask = PP_DEFER_PROGRAM_MASK;
		/*
		 * pp_program_info should not be modified beween normal and
		 * deferred stage calls.
		 */
		mdss_mdp_pp_setup_locked(ctl, &pp_program_info);
		if (sctl) {
			if (ctl->split_flush_en) {
				ctl->flush_bits |= sctl->flush_bits;
@@ -5939,6 +5952,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
		ctl_flush_bits |= ctl->flush_bits;
		mutex_unlock(&ctl->flush_lock);
	}
	ATRACE_END("postproc_programming_deferred");
	/*
	 * if serialize_wait4pp is false then roi_bkup used in wait4pingpong
	 * will be of previous frame as expected.
+111 −53
Original line number Diff line number Diff line
@@ -2322,7 +2322,9 @@ static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num,
		*opmode |= MDSS_MDP_DSPP_OP_ARGC_LUT_EN;
}

static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer,
					u32 pp_program_mask, int *op_mode)

{
	u32 ad_flags, flags, dspp_num, opmode = 0, ad_bypass;
	struct mdp_pgc_lut_data *pgc_config;
@@ -2338,6 +2340,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
	u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
	int side;

	opmode = *op_mode;

	if (!mixer || !mixer->ctl || !mixer->ctl->mdata)
		return -EINVAL;
	ctl = mixer->ctl;
@@ -2358,19 +2362,23 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
	}

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
	if (pp_program_mask & PP_PROGRAM_GAMUT) {
		if ((mdata->pp_block_off.dspp_gamut_off != U32_MAX) &&
				(pp_driver_ops.gamut_clk_gate_en))
			pp_driver_ops.gamut_clk_gate_en(base +
					mdata->pp_block_off.dspp_gamut_off);

	}
	if (disp_num < MDSS_BLOCK_DISP_NUM) {
		pp_sts = &mdss_pp_res->pp_disp_sts[disp_num];
		pp_sts->side_sts = side;

		ret = pp_hist_setup(&opmode, MDSS_PP_DSPP_CFG | dspp_num, mixer,
		if (pp_program_mask & PP_PROGRAM_HIST) {
			ret = pp_hist_setup(&opmode,
					MDSS_PP_DSPP_CFG | dspp_num, mixer,
					pp_sts);
			if (ret)
				goto dspp_exit;
		}

		flags = mdss_pp_res->pp_disp_flags[disp_num];
	} else {
@@ -2391,7 +2399,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
	if ((!flags) && (!(opmode)) && (!ad_flags))
		goto dspp_exit;

	if (flags & PP_FLAGS_DIRTY_PA) {
	if ((flags & PP_FLAGS_DIRTY_PA) &&
		(pp_program_mask & PP_PROGRAM_PA)) {
		if (!pp_ops[PA].pp_set_config) {
			if (mdata->mdp_rev >= MDSS_MDP_HW_REV_103) {
				pa_v2_cfg_data =
@@ -2412,7 +2421,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
					DSPP);
		}
	}
	if (flags & PP_FLAGS_DIRTY_PCC) {
	if ((flags & PP_FLAGS_DIRTY_PCC) &&
		(pp_program_mask & PP_PROGRAM_PCC)) {
		if (!pp_ops[PCC].pp_set_config)
			pp_pcc_config(flags, base + MDSS_MDP_REG_DSPP_PCC_BASE,
					pp_sts,
@@ -2429,7 +2439,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
		}
	}

	if (flags & PP_FLAGS_DIRTY_IGC) {
	if ((flags & PP_FLAGS_DIRTY_IGC) &&
		(pp_program_mask & PP_PROGRAM_IGC)) {
		if (!pp_ops[IGC].pp_set_config) {
			pp_igc_config(flags,
			      mdata->mdp_base + MDSS_MDP_REG_IGC_DSPP_BASE,
@@ -2449,7 +2460,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
				DSPP);
	}

	if (flags & PP_FLAGS_DIRTY_ENHIST) {
	if ((flags & PP_FLAGS_DIRTY_ENHIST) &&
		(pp_program_mask & PP_PROGRAM_HIST)) {
		if (!pp_ops[HIST_LUT].pp_set_config) {
			pp_enhist_config(flags,
				base + MDSS_MDP_REG_DSPP_HIST_LUT_BASE,
@@ -2473,7 +2485,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
		}
	}

	if (flags & PP_FLAGS_DIRTY_DITHER) {
	if ((flags & PP_FLAGS_DIRTY_DITHER) &&
		(pp_program_mask & PP_PROGRAM_DITHER)) {
		if (!pp_ops[DITHER].pp_set_config && addr) {
			pp_dither_config(addr, pp_sts,
				&mdss_pp_res->dither_disp_cfg[disp_num]);
@@ -2483,7 +2496,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
			      &mdss_pp_res->dither_disp_cfg[disp_num], DSPP);
		}
	}
	if (flags & PP_FLAGS_DIRTY_GAMUT) {
	if ((flags & PP_FLAGS_DIRTY_GAMUT) &&
		(pp_program_mask & PP_PROGRAM_GAMUT)) {
		if (!pp_ops[GAMUT].pp_set_config) {
			pp_gamut_config(&mdss_pp_res->gamut_disp_cfg[disp_num],
					 base, pp_sts);
@@ -2500,7 +2514,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
		}
	}

	if (flags & PP_FLAGS_DIRTY_PGC) {
	if ((flags & PP_FLAGS_DIRTY_PGC) &&
		(pp_program_mask & PP_PROGRAM_PGC)) {
		pgc_config = &mdss_pp_res->pgc_disp_cfg[disp_num];
		if (pp_ops[GC].pp_set_config) {
			if (mdata->pp_block_off.dspp_pgc_off == U32_MAX) {
@@ -2526,6 +2541,7 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
		}
	}
	if (flags & PP_FLAGS_DIRTY_PA_DITHER &&
		(pp_program_mask & PP_PROGRAM_PA_DITHER) &&
		pp_ops[PA_DITHER].pp_set_config) {
		pp_ops[PA_DITHER].pp_set_config(base, pp_sts,
					&mdss_pp_res->pa_dither_cfg[disp_num],
@@ -2536,7 +2552,7 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
		pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev,
					&opmode);

	if (ad_hw) {
	if (ad_hw && (pp_program_mask & PP_PROGRAM_AD)) {
		mutex_lock(&ad->lock);
		ad_flags = ad->reg_sts;
		if (ad_flags & PP_AD_STS_DIRTY_DATA)
@@ -2566,6 +2582,9 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
		ctl->flush_bits |= BIT(13 + dspp_num);

	wmb();

	*op_mode = opmode;

dspp_exit:
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
	return ret;
@@ -2684,6 +2703,8 @@ void mdss_mdp_pp_dest_scaler_resume(struct mdss_mdp_ctl *ctl)
int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
{
	int ret = 0;
	struct mdss_mdp_pp_program_info pp_program_info = {
							PP_PROGRAM_ALL, 0, 0};

	if ((!ctl->mfd) || (!mdss_pp_res))
		return -EINVAL;
@@ -2695,14 +2716,15 @@ int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl)
		ret = -EPERM;
		goto error;
	}
	ret = mdss_mdp_pp_setup_locked(ctl);
	ret = mdss_mdp_pp_setup_locked(ctl, &pp_program_info);
error:
	mutex_unlock(&ctl->lock);

	return ret;
}

int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl,
				struct mdss_mdp_pp_program_info *info)
{
	struct mdss_data_type *mdata;
	int ret = 0, i;
@@ -2715,6 +2737,16 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
	bool valid_ad_panel = true;
	if ((!ctl) || (!ctl->mfd) || (!mdss_pp_res) || (!ctl->mdata))
		return -EINVAL;
	if (!info) {
		pr_err("pp_program_info is NULL");
		return -EINVAL;
	}
	if (!(info->pp_program_mask == PP_NORMAL_PROGRAM_MASK ||
		info->pp_program_mask == PP_DEFER_PROGRAM_MASK ||
		info->pp_program_mask == PP_PROGRAM_ALL)) {
		pr_err("Invalid pp program mask : %x ", info->pp_program_mask);
		return -EINVAL;
	}

	mdata = ctl->mdata;
	/* treat fb_num the same as block logical id*/
@@ -2748,7 +2780,11 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)

	mutex_lock(&mdss_pp_mutex);

	if (disp_num < MDSS_BLOCK_DISP_NUM)
		flags = mdss_pp_res->pp_disp_flags[disp_num];
	else
		flags = 0;

	if (pp_ops[PA].pp_set_config)
		pa_v2_flags = mdss_pp_res->pa_v2_disp_cfg[disp_num].flags;
	else
@@ -2759,6 +2795,7 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
	 * increase the register bus bandwidth to maximum frequency
	 * in order to speed up the register reprogramming.
	 */
	if (info->pp_program_mask & PP_DEFER_PROGRAM_MASK) {
		max_bw_needed = (IS_PP_RESUME_COMMIT(flags) &&
					(IS_PP_LUT_DIRTY(flags) ||
					IS_SIX_ZONE_DIRTY(flags, pa_v2_flags)));
@@ -2766,27 +2803,46 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
			ret = mdss_update_reg_bus_vote(mdata->pp_reg_bus_clt,
					VOTE_INDEX_HIGH);
			if (ret)
			pr_err("Updated reg_bus_scale failed, ret = %d", ret);
				pr_err("Updated reg_bus_scale failed, ret = %d",
									ret);
		}
	}

	if (ctl->mixer_left) {
		if (info->pp_program_mask & PP_DEFER_PROGRAM_MASK) {
			pp_mixer_setup(ctl->mixer_left);
		pp_dspp_setup(disp_num, ctl->mixer_left);
			pp_dspp_setup(disp_num, ctl->mixer_left,
				info->pp_program_mask, &info->pp_opmode_left);
			pp_ppb_setup(ctl->mixer_left);
		} else {
			pp_dspp_setup(disp_num, ctl->mixer_left,
				info->pp_program_mask, &info->pp_opmode_left);
		}
	}
	if (ctl->mixer_right) {
		if (info->pp_program_mask & PP_DEFER_PROGRAM_MASK) {
			pp_mixer_setup(ctl->mixer_right);
		pp_dspp_setup(disp_num, ctl->mixer_right);
			pp_dspp_setup(disp_num, ctl->mixer_right,
				info->pp_program_mask, &info->pp_opmode_right);
			pp_ppb_setup(ctl->mixer_right);
		} else {
			pp_dspp_setup(disp_num, ctl->mixer_right,
				info->pp_program_mask, &info->pp_opmode_right);
		}
	}

	if (valid_mixers && (mixer_cnt <= mdata->nmax_concurrent_ad_hw) &&
	if (info->pp_program_mask & PP_PROGRAM_AD) {
		if (valid_mixers &&
			(mixer_cnt <= mdata->nmax_concurrent_ad_hw) &&
			valid_ad_panel) {
			ret = mdss_mdp_ad_ipc_reset(ctl->mfd);
			if (ret < 0)
			pr_warn("ad_setup(disp%d) returns %d\n", disp_num, ret);
				pr_warn("ad_setup(disp%d) returns %d\n",
							disp_num, ret);
		}
	}

	if (info->pp_program_mask & PP_DEFER_PROGRAM_MASK) {
		/* clear dirty flag */
		if (disp_num < MDSS_BLOCK_DISP_NUM) {
			mdss_pp_res->pp_disp_flags[disp_num] = 0;
@@ -2798,11 +2854,13 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
			ret = mdss_update_reg_bus_vote(mdata->pp_reg_bus_clt,
					VOTE_INDEX_DISABLE);
			if (ret)
			pr_err("Updated reg_bus_scale failed, ret = %d", ret);
				pr_err("Updated reg_bus_scale failed, ret = %d",
									ret);
		}
		if (IS_PP_RESUME_COMMIT(flags))
			mdss_pp_res->pp_disp_flags[disp_num] &=
				~PP_FLAGS_RESUME_COMMIT;
	}
	mutex_unlock(&mdss_pp_mutex);
exit:
	return ret;