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

Commit 5e96441e authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: sde: delay cwb done wait for last frame"

parents 4063d019 8d6fea83
Loading
Loading
Loading
Loading
+4 −53
Original line number Diff line number Diff line
@@ -142,50 +142,16 @@ static void msm_atomic_wait_for_commit_done(
	}
}

static bool
msm_disable_outputs_for_clone_conn(struct drm_device *dev,
		struct drm_atomic_state *old_state)
{
	struct drm_connector *connector;
	struct drm_connector_state *old_conn_state;
	struct drm_crtc_state *old_crtc_state;
	struct drm_crtc *crtc = NULL;
	int i;
	bool clone_state = false;

	for_each_old_connector_in_state(old_state, connector,
			old_conn_state, i) {

		if (!old_conn_state->crtc)
			continue;

		old_crtc_state = drm_atomic_get_old_crtc_state(old_state,
							old_conn_state->crtc);
		if (!old_crtc_state->active ||
		    !old_conn_state->crtc->state->connectors_changed ||
		    (!_msm_seamless_for_conn(connector, old_conn_state,
				 false) && (connector->connector_type !=
						DRM_MODE_CONNECTOR_VIRTUAL)))
			return false;

		if (crtc)
			clone_state = (crtc == old_conn_state->crtc)
				? true : false;

		crtc = old_conn_state->crtc;
	}

	return clone_state;
}

static void
msm_disable_connector_outputs(struct drm_device *dev,
		struct drm_atomic_state *old_state)
msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
{
	struct drm_connector *connector;
	struct drm_connector_state *old_conn_state;
	struct drm_crtc *crtc;
	struct drm_crtc_state *old_crtc_state;
	int i;

	SDE_ATRACE_BEGIN("msm_disable");
	for_each_old_connector_in_state(old_state, connector,
			old_conn_state, i) {
		const struct drm_encoder_helper_funcs *funcs;
@@ -238,18 +204,6 @@ msm_disable_connector_outputs(struct drm_device *dev,

		drm_bridge_post_disable(encoder->bridge);
	}
}

static void
msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
{
	struct drm_crtc *crtc;
	struct drm_crtc_state *old_crtc_state;
	int i;

	SDE_ATRACE_BEGIN("msm_disable");
	if (!msm_disable_outputs_for_clone_conn(dev, old_state))
		msm_disable_connector_outputs(dev, old_state);

	for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
		const struct drm_crtc_helper_funcs *funcs;
@@ -568,9 +522,6 @@ static void complete_commit(struct msm_commit *c)

	kms->funcs->complete_commit(kms, state);

	if (msm_disable_outputs_for_clone_conn(dev, state))
		msm_disable_connector_outputs(dev, state);

	drm_atomic_state_put(state);

	commit_destroy(c);
+23 −0
Original line number Diff line number Diff line
@@ -756,6 +756,29 @@ bool sde_encoder_in_clone_mode(struct drm_encoder *drm_enc)
	return false;
}

bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc,
	struct drm_crtc *crtc)
{
	struct sde_encoder_virt *sde_enc;
	int i;

	if (!drm_enc)
		return false;

	sde_enc = to_sde_encoder_virt(drm_enc);
	if (sde_enc->disp_info.intf_type != DRM_MODE_CONNECTOR_VIRTUAL)
		return false;

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (sde_encoder_phys_is_cwb_disabling(phys, crtc))
			return true;
	}

	return false;
}

static int _sde_encoder_atomic_check_phys_enc(struct sde_encoder_virt *sde_enc,
	struct drm_crtc_state *crtc_state,
	struct drm_connector_state *conn_state)
+9 −0
Original line number Diff line number Diff line
@@ -495,6 +495,15 @@ void sde_encoder_recovery_events_handler(struct drm_encoder *encoder,
 */
bool sde_encoder_in_clone_mode(struct drm_encoder *enc);

/*
 * sde_encoder_is_cwb_disabling - check if cwb encoder disable is pending
 * @drm_enc:    Pointer to drm encoder structure
 * @drm_crtc:    Pointer to drm crtc structure
 * @Return: true if cwb encoder disable is pending
 */
bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc,
	struct drm_crtc *drm_crtc);

/**
 * sde_encoder_is_primary_display - checks if underlying display is primary
 *     display or not.
+20 −0
Original line number Diff line number Diff line
@@ -641,6 +641,26 @@ static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode(
	return BLEND_3D_NONE;
}

/**
 * sde_encoder_phys_is_cwb_disabling - Check if CWB encoder attached to this
 *	 CRTC and it is in SDE_ENC_DISABLING state.
 * @phys_enc: Pointer to physical encoder structure
 * @crtc: drm crtc
 * @Return: true if cwb encoder is in disabling state
 */
static inline bool sde_encoder_phys_is_cwb_disabling(
	struct sde_encoder_phys *phys, struct drm_crtc *crtc)
{
	struct sde_encoder_phys_wb *wb_enc;

	if (!phys || !phys->in_clone_mode ||
				phys->enable_state != SDE_ENC_DISABLING)
		return false;

	wb_enc = container_of(phys, struct sde_encoder_phys_wb, base);
	return (wb_enc->crtc == crtc) ? true : false;
}

/**
 * sde_encoder_helper_split_config - split display configuration helper function
 *	This helper function may be used by physical encoders to configure
+47 −23
Original line number Diff line number Diff line
@@ -1074,7 +1074,8 @@ static void _sde_encoder_phys_wb_frame_done_helper(void *arg, bool frame_error)
	SDE_DEBUG("[wb:%d,%u]\n", hw_wb->idx - WB_0, wb_enc->frame_count);

	/* don't notify upper layer for internal commit */
	if (phys_enc->enable_state == SDE_ENC_DISABLING)
	if (phys_enc->enable_state == SDE_ENC_DISABLING &&
			!phys_enc->in_clone_mode)
		goto complete;

	if (phys_enc->parent_ops.handle_frame_done &&
@@ -1272,6 +1273,31 @@ static bool _sde_encoder_phys_wb_is_idle(

	return ret;
}
static void _sde_encoder_phys_wb_reset_state(
		struct sde_encoder_phys *phys_enc)
{
	struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);

	/*
	 * frame count and kickoff count are only used for debug purpose. Frame
	 * count can be more than kickoff count at the end of disable call due
	 * to extra frame_done wait. It does not cause any issue because
	 * frame_done wait is based on retire_fence count. Leaving these
	 * counters for debugging purpose.
	 */
	if (wb_enc->frame_count != wb_enc->kickoff_count) {
		SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc),
			wb_enc->kickoff_count, wb_enc->frame_count,
			phys_enc->in_clone_mode);
		wb_enc->frame_count = wb_enc->kickoff_count;
	}

	phys_enc->enable_state = SDE_ENC_DISABLED;
	wb_enc->crtc = NULL;
	phys_enc->hw_cdm = NULL;
	phys_enc->hw_ctl = NULL;
	phys_enc->in_clone_mode = false;
}

static int _sde_encoder_phys_wb_wait_for_commit_done(
		struct sde_encoder_phys *phys_enc, bool is_disable)
@@ -1358,7 +1384,17 @@ static int _sde_encoder_phys_wb_wait_for_commit_done(
static int sde_encoder_phys_wb_wait_for_commit_done(
		struct sde_encoder_phys *phys_enc)
{
	return _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false);
	int rc;

	if (phys_enc->enable_state == SDE_ENC_DISABLING &&
			phys_enc->in_clone_mode) {
		rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true);
		_sde_encoder_phys_wb_reset_state(phys_enc);
	} else {
		rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false);
	}

	return rc;
}

static int sde_encoder_phys_wb_wait_for_tx_complete(
@@ -1625,6 +1661,8 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc)
	SDE_DEBUG("[wait_for_done: wb:%d, frame:%u, kickoff:%u]\n",
			hw_wb->idx - WB_0, wb_enc->frame_count,
			wb_enc->kickoff_count);

	if (!phys_enc->in_clone_mode || !wb_enc->crtc->state->active)
		_sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true);

	if (!phys_enc->hw_ctl || !phys_enc->parent ||
@@ -1633,11 +1671,14 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc)
		goto exit;
	}

	/* avoid reset frame for CWB */
	if (phys_enc->in_clone_mode) {
		_sde_encoder_phys_wb_setup_cwb(phys_enc, false);
		_sde_encoder_phys_wb_update_cwb_flush(phys_enc, false);
		phys_enc->in_clone_mode = false;
		phys_enc->enable_state = SDE_ENC_DISABLING;

		if (wb_enc->crtc->state->active)
			return;

		goto exit;
	}

@@ -1670,24 +1711,7 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc)
	sde_encoder_phys_wb_irq_ctrl(phys_enc, false);

exit:
	/*
	 * frame count and kickoff count are only used for debug purpose. Frame
	 * count can be more than kickoff count at the end of disable call due
	 * to extra frame_done wait. It does not cause any issue because
	 * frame_done wait is based on retire_fence count. Leaving these
	 * counters for debugging purpose.
	 */
	if (wb_enc->frame_count != wb_enc->kickoff_count) {
		SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc),
			wb_enc->kickoff_count, wb_enc->frame_count,
			phys_enc->in_clone_mode);
		wb_enc->frame_count = wb_enc->kickoff_count;
	}

	phys_enc->enable_state = SDE_ENC_DISABLED;
	wb_enc->crtc = NULL;
	phys_enc->hw_cdm = NULL;
	phys_enc->hw_ctl = NULL;
	_sde_encoder_phys_wb_reset_state(phys_enc);
}

/**
Loading