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

Commit aaa7ca42 authored by Dhaval Patel's avatar Dhaval Patel
Browse files

drm/msm/sde: delay reset frame by a frame for posted trigger



Posted frame trigger method triggers the frame without
checking for frame done for previous frame. However,
it waits for current frame trigger. It should iniatiate
the recovery sequence only if current frame trigger
fails.

Change-Id: I3eac35ba722ac01a57504e78c628e82b3dcfb526
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 56a0a47e
Loading
Loading
Loading
Loading
+10 −11
Original line number Diff line number Diff line
@@ -3111,14 +3111,13 @@ static void _sde_crtc_remove_pipe_flush(struct drm_crtc *crtc)
}

/**
 * _sde_crtc_reset_hw - attempt hardware reset on errors
 * sde_crtc_reset_hw - attempt hardware reset on errors
 * @crtc: Pointer to DRM crtc instance
 * @old_state: Pointer to crtc state for previous commit
 * @recovery_events: Whether or not recovery events are enabled
 * Returns: Zero if current commit should still be attempted
 */
static int _sde_crtc_reset_hw(struct drm_crtc *crtc,
		struct drm_crtc_state *old_state,
int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
	bool recovery_events)
{
	struct drm_plane *plane_halt[MAX_PLANES];
@@ -3228,9 +3227,10 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	struct sde_crtc_state *cstate;
	bool is_error = false, reset_req, recovery_events;
	bool is_error = false, reset_req;
	unsigned long flags;
	enum sde_crtc_idle_pc_state idle_pc_state;
	struct sde_encoder_kickoff_params params = { 0 };

	if (!crtc) {
		SDE_ERROR("invalid argument\n");
@@ -3262,8 +3262,6 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
	idle_pc_state = sde_crtc_get_property(cstate, CRTC_PROP_IDLE_PC_STATE);

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

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

@@ -3276,9 +3274,6 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
		if (sde_encoder_prepare_for_kickoff(encoder, &params))
			reset_req = true;

		recovery_events =
			sde_encoder_recovery_events_enabled(encoder);

		if (idle_pc_state != IDLE_PC_NONE)
			sde_encoder_control_idle_pc(encoder,
			    (idle_pc_state == IDLE_PC_ENABLE) ? true : false);
@@ -3289,7 +3284,11 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
	 * preparing for the kickoff
	 */
	if (reset_req) {
		if (_sde_crtc_reset_hw(crtc, old_state, recovery_events))
		sde_crtc->frame_trigger_mode = params.frame_trigger_mode;
		if (sde_crtc->frame_trigger_mode
					!= FRAME_DONE_WAIT_POSTED_START &&
		    sde_crtc_reset_hw(crtc, old_state,
						params.recovery_events_enabled))
			is_error = true;
	}

+26 −0
Original line number Diff line number Diff line
@@ -219,6 +219,7 @@ struct sde_crtc_fps_info {
 * @power_event   : registered power event handle
 * @cur_perf      : current performance committed to clock/bandwidth driver
 * @plane_mask_old: keeps track of the planes used in the previous commit
 * @frame_trigger_mode: frame trigger mode
 */
struct sde_crtc {
	struct drm_crtc base;
@@ -289,6 +290,7 @@ struct sde_crtc {

	/* blob for histogram data */
	struct drm_property_blob *hist_blob;
	enum frame_trigger_mode_type frame_trigger_mode;
};

#define to_sde_crtc(x) container_of(x, struct sde_crtc, base)
@@ -441,6 +443,30 @@ static inline int sde_crtc_frame_pending(struct drm_crtc *crtc)
	return atomic_read(&sde_crtc->frame_pending);
}

/**
 * sde_crtc_reset_hw - attempt hardware reset on errors
 * @crtc: Pointer to DRM crtc instance
 * @old_state: Pointer to crtc state for previous commit
 * @recovery_events: Whether or not recovery events are enabled
 * Returns: Zero if current commit should still be attempted
 */
int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
	bool recovery_events);

/**
 * sde_crtc_request_frame_reset - requests for next frame reset
 * @crtc: Pointer to drm crtc object
 */
static inline int sde_crtc_request_frame_reset(struct drm_crtc *crtc)
{
	struct sde_crtc *sde_crtc = to_sde_crtc(crtc);

	if (sde_crtc->frame_trigger_mode == FRAME_DONE_WAIT_POSTED_START)
		sde_crtc_reset_hw(crtc, crtc->state, false);

	return 0;
}

/**
 * sde_crtc_vblank - enable or disable vblanks for this crtc
 * @crtc: Pointer to drm crtc object
+3 −0
Original line number Diff line number Diff line
@@ -4346,6 +4346,9 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		phys = sde_enc->phys_encs[i];
		params->is_primary = sde_enc->disp_info.is_primary;
		params->frame_trigger_mode = sde_enc->frame_trigger_mode;
		params->recovery_events_enabled =
					sde_enc->recovery_events_enabled;
		if (phys) {
			if (phys->ops.prepare_for_kickoff) {
				rc = phys->ops.prepare_for_kickoff(
+2 −0
Original line number Diff line number Diff line
@@ -59,11 +59,13 @@ struct sde_encoder_hw_resources {
 * @affected_displays:  bitmask, bit set means the ROI of the commit lies within
 *                      the bounds of the physical display at the bit index
 * @recovery_events_enabled: indicates status of client for recoovery events
 * @frame_trigger_mode: indicates frame trigger mode
 */
struct sde_encoder_kickoff_params {
	u32 is_primary;
	unsigned long affected_displays;
	bool recovery_events_enabled;
	enum frame_trigger_mode_type frame_trigger_mode;
};

/**
+1 −0
Original line number Diff line number Diff line
@@ -1198,6 +1198,7 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
		ret = sde_encoder_wait_for_event(encoder, MSM_ENC_COMMIT_DONE);
		if (ret && ret != -EWOULDBLOCK) {
			SDE_ERROR("wait for commit done returned %d\n", ret);
			sde_crtc_request_frame_reset(crtc);
			break;
		}