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

Commit b2620cbd authored by Clarence Ip's avatar Clarence Ip Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: update inline prefill programming



Rotator start programming for inline prefill doesn't take
effect on the next frame, but rather all subsequent frames
after the next one. However, prefill bandwidth calculations
are based on the requirements for the next frame, so the
calculated prefill bandwidth and rotator start programming
can be mismatched whenever the rotator start is adjusted.

This patch avoids this issue by fixing the rotator start
to a constant value, and adjusting the prefill bandwidth
for each frame instead.

Change-Id: I5410f63856248a035d627126962dd407f01a8f0d
Signed-off-by: default avatarClarence Ip <cip@codeaurora.org>
[cohens@codeaurora.org: Resolved trivial merge conflict]
Signed-off-by: default avatarSteve Cohen <cohens@codeaurora.org>
parent 7af7db44
Loading
Loading
Loading
Loading
+28 −5
Original line number Diff line number Diff line
@@ -1403,6 +1403,29 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
	}
}

/**
 * _sde_crtc_calc_inline_prefill - calculate rotator start prefill
 * @crtc: Pointer to drm crtc
 * return: prefill time in lines
 */
static u32 _sde_crtc_calc_inline_prefill(struct drm_crtc *crtc)
{
	struct sde_kms *sde_kms;

	if (!crtc) {
		SDE_ERROR("invalid parameters\n");
		return 0;
	}

	sde_kms = _sde_crtc_get_kms(crtc);
	if (!sde_kms || !sde_kms->catalog) {
		SDE_ERROR("invalid kms\n");
		return 0;
	}

	return sde_kms->catalog->sbuf_prefill + sde_kms->catalog->sbuf_headroom;
}

static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
		struct drm_crtc_state *old_state, struct sde_crtc *sde_crtc,
		struct sde_crtc_mixer *mixer)
@@ -1418,12 +1441,11 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
	struct sde_hw_stage_cfg *stage_cfg;
	struct sde_rect plane_crtc_roi;

	u32 flush_mask, flush_sbuf;
	u32 flush_mask, flush_sbuf, prefill;
	uint32_t stage_idx, lm_idx;
	int zpos_cnt[SDE_STAGE_MAX + 1] = { 0 };
	int i;
	bool bg_alpha_enable = false;
	u32 prefill = 0;

	if (!sde_crtc || !crtc->state || !mixer) {
		SDE_ERROR("invalid sde_crtc or mixer\n");
@@ -1435,7 +1457,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
	stage_cfg = &sde_crtc->stage_cfg;
	cstate = to_sde_crtc_state(crtc->state);

	cstate->sbuf_prefill_line = 0;
	cstate->sbuf_prefill_line = _sde_crtc_calc_inline_prefill(crtc);
	sde_crtc->sbuf_flush_mask_old = sde_crtc->sbuf_flush_mask_all;
	sde_crtc->sbuf_flush_mask_all = 0x0;
	sde_crtc->sbuf_flush_mask_delta = 0x0;
@@ -1453,8 +1475,9 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
		pstate = to_sde_plane_state(state);
		fb = state->fb;

		prefill = sde_plane_rot_calc_prefill(plane);
		if (prefill > cstate->sbuf_prefill_line)
		/* assume all rotated planes report the same prefill amount */
		prefill = sde_plane_rot_get_prefill(plane);
		if (prefill)
			cstate->sbuf_prefill_line = prefill;

		sde_plane_get_ctl_flush(plane, ctl, &flush_mask, &flush_sbuf);
+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@
#define PROP_BITVALUE_ACCESS(p, i, j, k)	((p + i)->bit_value[j][k])

#define DEFAULT_SBUF_HEADROOM		(20)
#define DEFAULT_SBUF_PREFILL		(128)

/*
 * Default parameter values
@@ -1953,6 +1954,7 @@ static int sde_rot_parse_dt(struct device_node *np,
	if (sde_cfg->rot_count) {
		sde_cfg->has_sbuf = true;
		sde_cfg->sbuf_headroom = DEFAULT_SBUF_HEADROOM;
		sde_cfg->sbuf_prefill = DEFAULT_SBUF_PREFILL;
	}

end:
+2 −0
Original line number Diff line number Diff line
@@ -924,6 +924,7 @@ struct sde_perf_cfg {
 * @ubwc_version       UBWC feature version (0x0 for not supported)
 * @has_sbuf           indicate if stream buffer is available
 * @sbuf_headroom      stream buffer headroom in lines
 * @sbuf_prefill       stream buffer prefill default in lines
 * @has_idle_pc        indicate if idle power collapse feature is supported
 * @has_hdr            HDR feature support
 * @dma_formats        Supported formats for dma pipe
@@ -950,6 +951,7 @@ struct sde_mdss_cfg {
	u32 ubwc_version;
	bool has_sbuf;
	u32 sbuf_headroom;
	u32 sbuf_prefill;
	bool has_idle_pc;
	u32 vbif_qos_nlvl;
	u32 ts_prefill_rev;
+25 −0
Original line number Diff line number Diff line
@@ -551,6 +551,28 @@ static void sde_hw_rot_to_v4l2_buffer(u32 drm_pixfmt, u64 drm_modifier,
	}
}

/**
 * sde_hw_rot_adjust_prefill_bw - update prefill bw based on pipe config
 * @hw: Pointer to rotator hardware driver
 * @data: Pointer to command descriptor
 * @prefill_bw: adjusted prefill bw (output)
 * return: 0 if success; error code otherwise
 */
static int sde_hw_rot_adjust_prefill_bw(struct sde_hw_rot *hw,
		struct sde_hw_rot_cmd *data, u64 *prefill_bw)
{
	if (!hw || !data || !prefill_bw) {
		SDE_ERROR("invalid parameter(s)\n");
		return -EINVAL;
	}

	/* adjust bw for scaling */
	if (data->dst_rect_h)
		*prefill_bw = mult_frac(data->prefill_bw, data->crtc_h,
				data->dst_rect_h);
	return 0;
}

/**
 * sde_hw_rot_commit - commit/execute given rotator command
 * @hw: Pointer to rotator hardware driver
@@ -683,6 +705,8 @@ static int sde_hw_rot_commit(struct sde_hw_rot *hw, struct sde_hw_rot_cmd *data,
				&rot_cmd.dst_planes);
	}

	sde_hw_rot_adjust_prefill_bw(hw, data, &rot_cmd.prefill_bw);

	/* only process any command if client is master or for validation */
	if (data->master || hw_cmd == SDE_HW_ROT_CMD_VALIDATE) {
		SDE_DEBUG("dispatch seq:%d cmd:%d\n", data->sequence_id,
@@ -918,6 +942,7 @@ struct sde_hw_rot *sde_hw_rot_init(enum sde_rot idx,
	/* Assign ops */
	c->idx = idx;
	c->caps = cfg;
	c->catalog = m;
	_setup_rot_ops(&c->ops, c->caps->features);
	snprintf(c->name, ARRAY_SIZE(c->name), "sde_rot_%d", idx - ROT_0);

+4 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ enum sde_hw_rot_cmd_type {
 * @dst_rect_y: destination rectangle y coordinate
 * @dst_rect_w: destination rectangle width
 * @dst_rect_h: destination rectangle height
 * @crtc_h: sspp output height
 * @priv_handle: private handle of rotator driver (output)
 */
struct sde_hw_rot_cmd {
@@ -110,6 +111,7 @@ struct sde_hw_rot_cmd {
	u32 dst_rect_y;
	u32 dst_rect_w;
	u32 dst_rect_h;
	u32 crtc_h;
	void *priv_handle;
};

@@ -133,6 +135,7 @@ struct sde_hw_rot_ops {
 * @hw: hardware address map
 * @idx: instance index
 * @caps: capabilities bitmask
 * @catalog: pointer to hardware catalog
 * @ops: operation table
 * @rot_ctx: pointer to private rotator context
 * @format_caps: pointer to pixel format capability  array
@@ -144,6 +147,7 @@ struct sde_hw_rot {
	char name[SDE_HW_ROT_NAME_SIZE];
	int idx;
	const struct sde_rot_cfg *caps;
	struct sde_mdss_cfg *catalog;
	struct sde_hw_rot_ops ops;
	void *rot_ctx;
	struct sde_format_extended *format_caps;
Loading