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

Commit a8a93eb4 authored by Clarence Ip's avatar Clarence Ip
Browse files

drm/msm/sde: persist inline rotate if not updated



Explicitly persist inline rotation reservations if the
rotated plane is not included in subsequent atomic commits.
This prevents the rotator hardware from being prematurely
released while the composition is still using the rotated
layers.

Configure both master and slave CTL paths for inline
rotation to prevent issues with atomic flushing of hardware
configurations in video mode.

Change-Id: Id082b24589869d4bdfdba8e1e4a8d2a00e59ec6d
Signed-off-by: default avatarClarence Ip <cip@codeaurora.org>
parent 51115737
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -3353,12 +3353,13 @@ static int _sde_crtc_commit_kickoff_rot(struct drm_crtc *crtc,

		if (!master_ctl || master_ctl->idx > ctl->idx)
			master_ctl = ctl;

		if (ctl->ops.setup_sbuf_cfg)
			ctl->ops.setup_sbuf_cfg(ctl, &cstate->sbuf_cfg);
	}

	/* only update sbuf_cfg and flush for master ctl */
	if (master_ctl && master_ctl->ops.setup_sbuf_cfg &&
			master_ctl->ops.update_pending_flush) {
		master_ctl->ops.setup_sbuf_cfg(master_ctl, &cstate->sbuf_cfg);
	if (master_ctl && master_ctl->ops.update_pending_flush) {
		master_ctl->ops.update_pending_flush(master_ctl, flush_mask);

		/* explicitly trigger rotator for async modes */
@@ -3484,7 +3485,7 @@ static int _sde_crtc_reset_hw(struct drm_crtc *crtc,
	}

	/* reset both previous... */
	for_each_plane_in_state(old_state->state, plane, pstate, i) {
	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, old_state) {
		if (pstate->crtc != crtc)
			continue;

@@ -4495,6 +4496,17 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
					sde_crtc->name, plane->base.id, rc);
			goto end;
		}

		/* identify attached planes that are not in the delta state */
		if (!drm_atomic_get_existing_plane_state(state->state, plane)) {
			rc = sde_plane_confirm_hw_rsvps(plane, pstate);
			if (rc) {
				SDE_ERROR("crtc%d confirmation hw failed %d\n",
						crtc->base.id, rc);
				goto end;
			}
		}

		if (cnt >= SDE_PSTATES_MAX)
			continue;

+44 −0
Original line number Diff line number Diff line
@@ -2958,6 +2958,50 @@ int sde_plane_validate_multirect_v2(struct sde_multirect_plane_states *plane)
	return 0;
}

int sde_plane_confirm_hw_rsvps(struct drm_plane *plane,
		const struct drm_plane_state *state)
{
	struct drm_crtc_state *cstate;
	struct sde_plane_state *pstate;
	struct sde_plane_rot_state *rstate;
	struct sde_hw_blk *hw_blk;

	if (!plane || !state) {
		SDE_ERROR("invalid plane/state\n");
		return -EINVAL;
	}

	pstate = to_sde_plane_state(state);
	rstate = &pstate->rot;

	/* cstate will be null if crtc is disconnected from plane */
	cstate = _sde_plane_get_crtc_state((struct drm_plane_state *)state);
	if (IS_ERR_OR_NULL(cstate)) {
		SDE_ERROR("invalid crtc state\n");
		return -EINVAL;
	}

	if (sde_plane_enabled((struct drm_plane_state *)state) &&
			rstate->out_sbuf) {
		SDE_DEBUG("plane%d.%d acquire rotator, fb %d\n",
				plane->base.id, rstate->sequence_id,
				state->fb ? state->fb->base.id : -1);

		hw_blk = sde_crtc_res_get(cstate, SDE_HW_BLK_ROT,
				(u64) state->fb);
		if (!hw_blk) {
			SDE_ERROR("plane%d.%d no available rotator, fb %d\n",
					plane->base.id, rstate->sequence_id,
					state->fb ? state->fb->base.id : -1);
			SDE_EVT32(DRMID(plane), rstate->sequence_id,
					state->fb ? state->fb->base.id : -1,
					SDE_EVTLOG_ERROR);
			return -EINVAL;
		}
	}
	return 0;
}

/**
 * sde_plane_get_ctl_flush - get control flush for the given plane
 * @plane: Pointer to drm plane structure
+9 −0
Original line number Diff line number Diff line
@@ -198,6 +198,15 @@ enum sde_sspp sde_plane_pipe(struct drm_plane *plane);
 */
bool is_sde_plane_virtual(struct drm_plane *plane);

/**
 * sde_plane_confirm_hw_rsvps - reserve an sbuf resource, if needed
 * @plane: Pointer to DRM plane object
 * @state: Pointer to plane state
 * Returns: Zero on success
 */
int sde_plane_confirm_hw_rsvps(struct drm_plane *plane,
		const struct drm_plane_state *state);

/**
 * sde_plane_get_ctl_flush - get control flush mask
 * @plane:   Pointer to DRM plane object