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

Commit 4aacd538 authored by Alan Kwong's avatar Alan Kwong
Browse files

drm/msm/sde: add inline rotation prefill for video mode



In video mode, rotation stream buffer needs to be filled
before source pipe starts processing in order to fulfill
latency requirement. Inline rotation calculates prefill
start trigger and configures video interface engine
accordingly.

CRs-Fixed: 2009714
Change-Id: I9bfa4d49e24db1db101de4065e221d641e90f3f4
Signed-off-by: default avatarAlan Kwong <akwong@codeaurora.org>
parent 54125bbd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ enum msm_mdp_crtc_property {
	CRTC_PROP_CORE_CLK,
	CRTC_PROP_CORE_AB,
	CRTC_PROP_CORE_IB,
	CRTC_PROP_ROT_PREFILL_BW,

	/* total # of properties */
	CRTC_PROP_COUNT
+12 −1
Original line number Diff line number Diff line
@@ -365,9 +365,11 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
		if (!sbuf_mode) {
			cstate->sbuf_cfg.rot_op_mode =
					SDE_CTL_ROT_OP_MODE_OFFLINE;
			cstate->sbuf_prefill_line = 0;
		} else {
			cstate->sbuf_cfg.rot_op_mode =
					SDE_CTL_ROT_OP_MODE_INLINE_SYNC;
			cstate->sbuf_prefill_line = prefill;
		}

		ctl->ops.setup_sbuf_cfg(ctl, &cstate->sbuf_cfg);
@@ -1024,6 +1026,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc)
	struct sde_crtc *sde_crtc;
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	struct sde_crtc_state *cstate;

	if (!crtc) {
		SDE_ERROR("invalid argument\n");
@@ -1033,8 +1036,11 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc)
	sde_crtc = to_sde_crtc(crtc);
	sde_kms = _sde_crtc_get_kms(crtc);
	priv = sde_kms->dev->dev_private;
	cstate = to_sde_crtc_state(crtc->state);

	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
		struct sde_encoder_kickoff_params params = { 0 };

		if (encoder->crtc != crtc)
			continue;

@@ -1042,7 +1048,8 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc)
		 * Encoder will flush/start now, unless it has a tx pending.
		 * If so, it may delay and flush at an irq event (e.g. ppdone)
		 */
		sde_encoder_prepare_for_kickoff(encoder);
		params.inline_rotate_prefill = cstate->sbuf_prefill_line;
		sde_encoder_prepare_for_kickoff(encoder, &params);
	}

	if (atomic_read(&sde_crtc->frame_pending) > 2) {
@@ -1715,6 +1722,10 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
			"core_ib", 0x0, 0, U64_MAX,
			SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA,
			CRTC_PROP_CORE_IB);
	msm_property_install_range(&sde_crtc->property_info,
			"rot_prefill_bw", 0, 0, U64_MAX,
			catalog->perf.max_bw_high * 1000ULL,
			CRTC_PROP_ROT_PREFILL_BW);

	msm_property_install_blob(&sde_crtc->property_info, "capabilities",
		DRM_MODE_PROP_IMMUTABLE, CRTC_PROP_INFO);
+2 −0
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ struct sde_crtc {
 * @cur_perf: current performance state
 * @new_perf: new performance state
 * @sbuf_cfg: stream buffer configuration
 * @sbuf_prefill_line: number of line for inline rotator prefetch
 */
struct sde_crtc_state {
	struct drm_crtc_state base;
@@ -221,6 +222,7 @@ struct sde_crtc_state {
	struct sde_core_perf_params cur_perf;
	struct sde_core_perf_params new_perf;
	struct sde_ctl_sbuf_cfg sbuf_cfg;
	u64 sbuf_prefill_line;
};

#define to_sde_crtc_state(x) \
+3 −2
Original line number Diff line number Diff line
@@ -1203,7 +1203,8 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
	spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
}

void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc)
void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
		struct sde_encoder_kickoff_params *params)
{
	struct sde_encoder_virt *sde_enc;
	struct sde_encoder_phys *phys;
@@ -1224,7 +1225,7 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc)
		phys = sde_enc->phys_encs[i];
		if (phys) {
			if (phys->ops.prepare_for_kickoff)
				phys->ops.prepare_for_kickoff(phys);
				phys->ops.prepare_for_kickoff(phys, params);
			if (phys->enable_state == SDE_ENC_ERR_NEEDS_HW_RESET)
				needs_hw_reset = true;
		}
+29 −1
Original line number Diff line number Diff line
@@ -44,6 +44,14 @@ struct sde_encoder_hw_resources {
	u32 display_num_of_h_tiles;
};

/**
 * sde_encoder_kickoff_params - info encoder requires at kickoff
 * @inline_rotate_prefill: number of lines to prefill for inline rotation
 */
struct sde_encoder_kickoff_params {
	u32 inline_rotate_prefill;
};

/**
 * sde_encoder_get_hw_resources - Populate table of required hardware resources
 * @encoder:	encoder pointer
@@ -89,8 +97,10 @@ struct sde_rsc_client *sde_encoder_update_rsc_client(
 *	Immediately: if no previous commit is outstanding.
 *	Delayed: Block until next trigger can be issued.
 * @encoder:	encoder pointer
 * @params:	kickoff time parameters
 */
void sde_encoder_prepare_for_kickoff(struct drm_encoder *encoder);
void sde_encoder_prepare_for_kickoff(struct drm_encoder *encoder,
		struct sde_encoder_kickoff_params *params);

/**
 * sde_encoder_kickoff - trigger a double buffer flip of the ctl path
@@ -115,6 +125,24 @@ int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder);
 */
enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder);

/**
 * enum sde_encoder_property - property tags for sde enoder
 * @SDE_ENCODER_PROPERTY_INLINE_ROTATE_REFILL: # of prefill line, 0 to disable
 */
enum sde_encoder_property {
	SDE_ENCODER_PROPERTY_INLINE_ROTATE_PREFILL,
	SDE_ENCODER_PROPERTY_MAX,
};

/*
 * sde_encoder_set_property - set the property tag to the given value
 * @encoder: Pointer to drm encoder object
 * @tag: property tag
 * @val: property value
 * return: 0 if success; errror code otherwise
 */
int sde_encoder_set_property(struct drm_encoder *encoder, u32 tag, u64 val);

/**
 * sde_encoder_init - initialize virtual encoder object
 * @dev:        Pointer to drm device structure
Loading