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

Commit dfaeec94 authored by Jeykumar Sankaran's avatar Jeykumar Sankaran
Browse files

drm/msm/sde: add KMS hook to wait for panel transfer complete



Some of the SDE features mandates the current frame to be flushed
out from the SDE HW before programming the next one. This change adds
hook for panel transfer complete in KMS so that atomic commit can wait
on the SDE to complete transfer of the frame to the panel.

Change-Id: I0d873c94ef29be38ed2002c357b18e15bbea698a
Signed-off-by: default avatarJeykumar Sankaran <jsanka@codeaurora.org>
parent ffd90498
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -205,6 +205,16 @@ enum msm_display_caps {
	MSM_DISPLAY_CAP_EDID		= BIT(3),
};

/**
 * enum msm_event_wait - type of HW events to wait for
 * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW
 * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel
 */
enum msm_event_wait {
	MSM_ENC_COMMIT_DONE = 0,
	MSM_ENC_TX_COMPLETE,
};

/**
 * struct msm_roi_alignment - region of interest alignment restrictions
 * @xstart_pix_align: left x offset alignment restriction
+3 −0
Original line number Diff line number Diff line
@@ -62,6 +62,9 @@ struct msm_kms_funcs {
	/* functions to wait for atomic commit completed on each CRTC */
	void (*wait_for_crtc_commit_done)(struct msm_kms *kms,
					struct drm_crtc *crtc);
	/* function pointer to wait for pixel transfer to panel to complete*/
	void (*wait_for_tx_complete)(struct msm_kms *kms,
					struct drm_crtc *crtc);
	/* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */
	const struct msm_format *(*get_format)(struct msm_kms *kms,
					const uint32_t format,
+14 −3
Original line number Diff line number Diff line
@@ -2812,8 +2812,10 @@ struct drm_encoder *sde_encoder_init(
	return ERR_PTR(ret);
}

int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
int sde_encoder_wait_for_event(struct drm_encoder *drm_enc,
	enum msm_event_wait event)
{
	int (*fn_wait)(struct sde_encoder_phys *phys_enc) = NULL;
	struct sde_encoder_virt *sde_enc = NULL;
	int i, ret = 0;

@@ -2827,8 +2829,17 @@ int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys && phys->ops.wait_for_commit_done) {
			ret = phys->ops.wait_for_commit_done(phys);
		switch (event) {
		case MSM_ENC_COMMIT_DONE:
			fn_wait = phys->ops.wait_for_commit_done;
			break;
		case MSM_ENC_TX_COMPLETE:
			fn_wait = phys->ops.wait_for_tx_complete;
			break;
		};

		if (phys && fn_wait) {
			ret = fn_wait(phys);
			if (ret)
				return ret;
		}
+15 −5
Original line number Diff line number Diff line
@@ -128,14 +128,24 @@ void sde_encoder_trigger_kickoff_pending(struct drm_encoder *encoder);
void sde_encoder_kickoff(struct drm_encoder *encoder);

/**
 * sde_encoder_wait_nxt_committed - Wait for hardware to have flushed the
 *	current pending frames to hardware at a vblank or ctl_start
 *	Encoders will map this differently depending on irqs
 *	vid mode -> vsync_irq
 * sde_encoder_wait_for_event - Waits for encoder events
 * @encoder:	encoder pointer
 * @event:      event to wait for
 * MSM_ENC_COMMIT_DONE -  Wait for hardware to have flushed the current pending
 *                        frames to hardware at a vblank or ctl_start
 *                        Encoders will map this differently depending on the
 *                        panel type.
 *	                  vid mode -> vsync_irq
 *                        cmd mode -> ctl_start
 * MSM_ENC_TX_COMPLETE -  Wait for the hardware to transfer all the pixels to
 *                        the panel. Encoders will map this differently
 *                        depending on the panel type.
 *                        vid mode -> vsync_irq
 *                        cmd mode -> pp_done
 * Returns: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
 */
int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder);
int sde_encoder_wait_for_event(struct drm_encoder *drm_encoder,
						enum msm_event_wait event);

/*
 * sde_encoder_get_intf_mode - get interface mode of the given encoder
+3 −0
Original line number Diff line number Diff line
@@ -111,6 +111,8 @@ struct sde_encoder_virt_ops {
 * @control_vblank_irq		Register/Deregister for VBLANK IRQ
 * @wait_for_commit_done:	Wait for hardware to have flushed the
 *				current pending frames to hardware
 * @wait_for_tx_complete:	Wait for hardware to transfer the pixels
 *				to the panel
 * @prepare_for_kickoff:	Do any work necessary prior to a kickoff
 *				For CMD encoder, may wait for previous tx done
 * @handle_post_kickoff:	Do any work necessary post-kickoff work
@@ -147,6 +149,7 @@ struct sde_encoder_phys_ops {
			struct drm_connector_state *conn_state);
	int (*control_vblank_irq)(struct sde_encoder_phys *enc, bool enable);
	int (*wait_for_commit_done)(struct sde_encoder_phys *phys_enc);
	int (*wait_for_tx_complete)(struct sde_encoder_phys *phys_enc);
	void (*prepare_for_kickoff)(struct sde_encoder_phys *phys_enc,
			struct sde_encoder_kickoff_params *params);
	void (*handle_post_kickoff)(struct sde_encoder_phys *phys_enc);
Loading