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

Commit 070edbc0 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: stage border fill after ctl start timeout"

parents 867e3828 fb29f691
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -757,6 +757,25 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc,

	return true;
}
static int _sde_crtc_get_ctlstart_timeout(struct drm_crtc *crtc)
{
	struct drm_encoder *encoder;
	int rc = 0;

	if (!crtc || !crtc->dev)
		return 0;

	list_for_each_entry(encoder,
			&crtc->dev->mode_config.encoder_list, head) {
		if (encoder->crtc != crtc)
			continue;

		if (sde_encoder_get_intf_mode(encoder) == INTF_MODE_CMD)
			rc += sde_encoder_get_ctlstart_timeout_state(encoder);
	}

	return rc;
}

static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer,
	struct sde_plane_state *pstate, struct sde_format *format)
@@ -3184,7 +3203,13 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
	if (unlikely(!sde_crtc->num_mixers))
		return;

	if (_sde_crtc_get_ctlstart_timeout(crtc)) {
		_sde_crtc_blend_setup(crtc, old_state, false);
		SDE_ERROR("border fill only commit after ctlstart timeout\n");
	} else {
		_sde_crtc_blend_setup(crtc, old_state, true);
	}

	_sde_crtc_dest_scaler_setup(crtc);

	/* cancel the idle notify delayed work */
+18 −0
Original line number Diff line number Diff line
@@ -3229,6 +3229,24 @@ int sde_encoder_idle_request(struct drm_encoder *drm_enc)
	return 0;
}

int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc = NULL;
	int i, count = 0;

	if (!drm_enc)
		return 0;

	sde_enc = to_sde_encoder_virt(drm_enc);

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		count += atomic_read(&sde_enc->phys_encs[i]->ctlstart_timeout);
		atomic_set(&sde_enc->phys_encs[i]->ctlstart_timeout, 0);
	}

	return count;
}

/**
 * _sde_encoder_trigger_flush - trigger flush for a physical encoder
 * drm_enc: Pointer to drm encoder structure
+7 −0
Original line number Diff line number Diff line
@@ -266,4 +266,11 @@ int sde_encoder_in_clone_mode(struct drm_encoder *enc);
 */
void sde_encoder_control_idle_pc(struct drm_encoder *enc, bool enable);

/**
 * sde_encoder_get_ctlstart_timeout_state - checks if ctl start timeout happened
 * @drm_enc:    Pointer to drm encoder structure
 * @Return:     non zero value if ctl start timeout occurred
 */
int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *enc);

#endif /* __SDE_ENCODER_H__ */
+2 −0
Original line number Diff line number Diff line
@@ -267,6 +267,7 @@ struct sde_encoder_irq {
 * @pending_retire_fence_cnt:   Atomic counter tracking the pending retire
 *                              fences that have to be signalled.
 * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
 * @ctlstart_timeout:		Indicates if ctl start timeout occurred
 * @irq:			IRQ tracking structures
 * @cont_splash_single_flush	Variable to check if single flush is enabled.
 * @cont_splash_settings	Variable to store continuous splash settings.
@@ -301,6 +302,7 @@ struct sde_encoder_phys {
	atomic_t pending_kickoff_cnt;
	atomic_t pending_retire_fence_cnt;
	wait_queue_head_t pending_kickoff_wq;
	atomic_t ctlstart_timeout;
	struct sde_encoder_irq irq[INTR_IDX_MAX];
	u32 cont_splash_single_flush;
	bool cont_splash_settings;
+8 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -193,6 +193,7 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
				phys_enc,
				SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE);
		atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
		atomic_set(&phys_enc->ctlstart_timeout, 0);
	}

	/* notify all synchronous clients first, then asynchronous clients */
@@ -292,6 +293,7 @@ static void sde_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx)

	ctl = phys_enc->hw_ctl;
	atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
	atomic_set(&phys_enc->ctlstart_timeout, 0);

	time_diff_us = ktime_us_delta(ktime_get(), cmd_enc->rd_ptr_timestamp);

@@ -1054,6 +1056,7 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc)
		SDE_ERROR("invalid encoder\n");
		return;
	}
	atomic_set(&phys_enc->ctlstart_timeout, 0);
	SDE_DEBUG_CMDENC(cmd_enc, "pp %d state %d\n",
			phys_enc->hw_pp->idx - PINGPONG_0,
			phys_enc->enable_state);
@@ -1176,6 +1179,9 @@ static int _sde_encoder_phys_cmd_wait_for_ctl_start(
					"ctl start interrupt wait failed\n");
		else
			ret = 0;

		if (sde_encoder_phys_cmd_is_master(phys_enc))
			atomic_inc_return(&phys_enc->ctlstart_timeout);
	}

	return ret;
@@ -1476,6 +1482,7 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init(
	atomic_set(&phys_enc->pending_retire_fence_cnt, 0);
	atomic_set(&cmd_enc->pending_rd_ptr_cnt, 0);
	atomic_set(&cmd_enc->pending_vblank_cnt, 0);
	atomic_set(&phys_enc->ctlstart_timeout, 0);
	init_waitqueue_head(&phys_enc->pending_kickoff_wq);
	init_waitqueue_head(&cmd_enc->pending_vblank_wq);
	atomic_set(&cmd_enc->autorefresh.kickoff_cnt, 0);