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

Commit 171c7c7d authored by Jeevan Shriram's avatar Jeevan Shriram
Browse files

mdss: mdp: Add programmable fetch for mdp



Currently, MDP fetches only at the vertical backporch.
All through the vertical front porch, hardware sits idle
doing nothing. Starting from MDP v1.5, hardware has the
capability to fetch at the programmable line in the vertical
front porch.

Change-Id: Ib2482fa610acdfc5cbf944415a344c11f313bc81
Signed-off-by: default avatarJeevan Shriram <jshriram@codeaurora.org>
parent b23bf381
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#define HORSCALER_NUM_FILTER_TAPS	8
#define HORSCALER_COEFF_NUM		17
#define MDP_MIN_VBP		4
#define MDP_MIN_FETCH		9
#define MAX_FREE_LIST_SIZE	12

#define C3_ALPHA	3	/* alpha */
@@ -216,6 +217,7 @@ struct mdss_mdp_ctl {

	void *priv_data;
	u32 wb_type;
	bool prg_fet;
};

struct mdss_mdp_mixer {
+5 −0
Original line number Diff line number Diff line
@@ -650,6 +650,9 @@ static u32 mdss_mdp_get_vbp_factor(struct mdss_mdp_ctl *ctl)
	fps = mdss_panel_get_framerate(pinfo);
	v_total = mdss_panel_get_vtotal(pinfo);
	vbp = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width;
	if (ctl->prg_fet)
		vbp += mdss_mdp_max_fetch_lines(pinfo);

	vbp_fac = (vbp) ? fps * v_total / vbp : 0;
	pr_debug("vbp_fac=%d vbp=%d v_total=%d\n", vbp_fac, vbp, v_total);

@@ -732,6 +735,8 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl,
	}

	perf->bw_ctl = max(perf->bw_prefill, perf->bw_overlap);
	pr_debug("ctl=%d, prefill bw=%llu, overlap bw=%llu\n",
			ctl->num, perf->bw_prefill, perf->bw_overlap);
}

int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
+1 −0
Original line number Diff line number Diff line
@@ -538,6 +538,7 @@ enum mdss_mpd_intf_index {
#define MDSS_MDP_REG_INTF_TPG_INITIAL_VALUE		0x114
#define MDSS_MDP_REG_INTF_TPG_BLK_WHITE_PATTERN_FRAMES	0x118
#define MDSS_MDP_REG_INTF_TPG_RGB_MAPPING		0x11C
#define MDSS_MDP_REG_INTF_PROG_FETCH_START		0x170

#define MDSS_MDP_REG_INTF_FRAME_LINE_COUNT_EN		0x0A8
#define MDSS_MDP_REG_INTF_FRAME_COUNT			0x0AC
+57 −0
Original line number Diff line number Diff line
@@ -854,6 +854,62 @@ int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl,
	return ret;
}

static bool mdss_mdp_fetch_programable(struct mdss_mdp_ctl *ctl)
{
	struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info;
	struct mdss_data_type *mdata;
	bool ret;

	mdata = ctl->mdata;

	if (mdata->mdp_rev >= MDSS_MDP_HW_REV_105) {
		if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch) <
				MDP_MIN_FETCH) {
			pr_warn("low vbp+vfp may lead to perf issues in some cases\n");
		}
		ret = true;

		if (pinfo->lcdc.v_back_porch > MDP_MIN_FETCH)
			ret = false;
	} else {
		if (pinfo->lcdc.v_back_porch < MDP_MIN_FETCH)
			pr_warn("low vbp may lead to display performance issues");
		ret = false;
	}

	return ret;
}

static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx,
		struct mdss_mdp_ctl *ctl)
{
	int fetch_start, fetch_enable, v_total, h_total;
	struct mdss_data_type *mdata;
	struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info;

	mdata = ctl->mdata;

	if (!mdss_mdp_fetch_programable(ctl)) {
		pr_debug("programmable fetch is not needed/supported\n");
		ctl->prg_fet = false;
		return;
	}

	/*
	 * Fetch should always be outside the active lines. If the fetching
	 * is programmed within active region, hardware behavior is unknown.
	 */
	v_total = mdss_panel_get_vtotal(pinfo);
	h_total = mdss_panel_get_htotal(pinfo, true);
	fetch_start = (v_total - mdss_mdp_max_fetch_lines(pinfo)) * h_total;
	fetch_enable = BIT(31);
	ctl->prg_fet = true;

	pr_debug("ctl:%d, fetch start=%d\n", ctl->num, fetch_start);
	mdp_video_write(ctx, MDSS_MDP_REG_INTF_PROG_FETCH_START, fetch_start);
	mdp_video_write(ctx, MDSS_MDP_REG_INTF_CONFIG, fetch_enable);
}

static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl,
	struct mdss_panel_data *pdata, int inum)
{
@@ -935,6 +991,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl,
		return -EINVAL;
	}

	mdss_mdp_fetch_start_config(ctx, ctl);
	mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format);

	return 0;
+28 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ struct panel_id {
#define DEFAULT_FRAME_RATE	60
#define DEFAULT_ROTATOR_FRAME_RATE 120
#define MDSS_DSI_RST_SEQ_LEN	10
#define MDSS_MDP_MAX_FETCH 12

/* panel type list */
#define NO_PANEL		0xffff	/* No Panel */
@@ -495,6 +496,33 @@ static inline int mdss_panel_get_htotal(struct mdss_panel_info *pinfo, bool
		pinfo->lcdc.h_pulse_width;
}

/**
 * mdss_mdp_max_fetch_lines: - Number of fetch lines in vertical front porch
 * @pinfo:	Pointer to panel info containing all panel information
 *
 * Returns the number of fetch lines in vertical front porch at which mdp
 * can start fetching the next frame.
 *
 * In some cases, vertical front porch is too high. In such cases limit
 * the mdp fetch lines  as the last 12 lines of vertical front porch.
 */
static inline int mdss_mdp_max_fetch_lines(struct mdss_panel_info *pinfo)
{
	int fetch_lines;
	int v_total, vfp_start;

	v_total = mdss_panel_get_vtotal(pinfo);
	vfp_start = (pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width +
			pinfo->yres + 1);

	fetch_lines = v_total - vfp_start;

	if (fetch_lines > MDSS_MDP_MAX_FETCH)
		fetch_lines = MDSS_MDP_MAX_FETCH;

	return fetch_lines;
}

int mdss_register_panel(struct platform_device *pdev,
	struct mdss_panel_data *pdata);