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

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

drm/msm/sde: reclaim buffers for inline rotation res change



Move the check for reallocating the intermediate buffer for
inline rotation to the atomic check phase. This allows the
buffer reclaim logic to correctly clean up any freed buffers
so that a new buffer can be created during the prepare.

Change-Id: I9d3c8bdbaa3054717f6be83cd56c305c63cc734d
Signed-off-by: default avatarClarence Ip <cip@codeaurora.org>
parent 299fa60b
Loading
Loading
Loading
Loading
+53 −50
Original line number Diff line number Diff line
@@ -1777,6 +1777,15 @@ static void sde_plane_rot_calc_cfg(struct drm_plane *plane,
			drm_rect_height(&rstate->out_rot_rect) >> 16,
			rstate->out_rot_rect.x1 >> 16,
			rstate->out_rot_rect.y1 >> 16);
	SDE_EVT32_VERBOSE(DRMID(plane), rstate->sequence_id,
			rstate->out_xpos, rstate->nplane,
			in_rot->x1 >> 16, in_rot->y1 >> 16,
			drm_rect_width(in_rot) >> 16,
			drm_rect_height(in_rot) >> 16,
			rstate->out_rot_rect.x1 >> 16,
			rstate->out_rot_rect.y1 >> 16,
			drm_rect_width(&rstate->out_rot_rect) >> 16,
			drm_rect_height(&rstate->out_rot_rect) >> 16);
}

/**
@@ -1975,7 +1984,7 @@ static void _sde_plane_rot_get_fb(struct drm_plane *plane,
	struct sde_kms_fbo *fbo;
	struct drm_framebuffer *fb;

	if (!plane || !cstate || !rstate)
	if (!plane || !cstate || !rstate || !rstate->rot_hw)
		return;

	fbo = sde_crtc_res_get(cstate, SDE_CRTC_RES_ROT_OUT_FBO,
@@ -2038,27 +2047,6 @@ static int sde_plane_rot_prepare_fb(struct drm_plane *plane,
	if (sde_plane_enabled(new_state) && !new_rstate->out_fb)
		_sde_plane_rot_get_fb(plane, cstate, new_rstate);

	/* release buffer if output format configuration changes */
	if (new_rstate->out_fb &&
		((new_rstate->out_fb_height != new_rstate->out_fb->height) ||
		(new_rstate->out_fb_width != new_rstate->out_fb->width) ||
		(new_rstate->out_fb_pixel_format !=
				new_rstate->out_fb->pixel_format) ||
		(new_rstate->out_fb_modifier[0] !=
				new_rstate->out_fb->modifier[0]) ||
		(new_rstate->out_fb_flags != new_rstate->out_fb->flags))) {

		SDE_DEBUG("plane%d.%d release fb/fbo\n", plane->base.id,
				new_rstate->sequence_id);

		sde_crtc_res_put(cstate, SDE_CRTC_RES_ROT_OUT_FB,
				(u64) &new_rstate->rot_hw->base);
		new_rstate->out_fb = NULL;
		sde_crtc_res_put(cstate, SDE_CRTC_RES_ROT_OUT_FBO,
				(u64) &new_rstate->rot_hw->base);
		new_rstate->out_fbo = NULL;
	}

	/* create new stream buffer if it is not available */
	if (sde_plane_enabled(new_state) && !new_rstate->out_fb) {
		u32 fb_w = drm_rect_width(&new_rstate->out_rot_rect) >> 16;
@@ -2093,6 +2081,8 @@ static int sde_plane_rot_prepare_fb(struct drm_plane *plane,
			ret = -EINVAL;
			goto error_create_fb;
		}
		SDE_EVT32_VERBOSE(DRMID(plane), new_rstate->sequence_id,
				new_rstate->out_fb->base.id);

		ret = sde_crtc_res_add(cstate, SDE_CRTC_RES_ROT_OUT_FB,
				(u64) &new_rstate->rot_hw->base,
@@ -2246,22 +2236,24 @@ static int sde_plane_rot_atomic_check(struct drm_plane *plane,
	rstate->out_sbuf = psde->sbuf_mode || rstate->rot90;

	if (sde_plane_enabled(state) && rstate->out_sbuf) {
		SDE_DEBUG("plane%d.%d acquire rotator\n",
				plane->base.id, rstate->sequence_id);
		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 no available rotator\n",
					plane->base.id);
			SDE_ERROR("plane%d.%d no available rotator, fb %d\n",
					plane->base.id, rstate->sequence_id,
					state->fb ? state->fb->base.id : -1);
			return -EINVAL;
		}

		rstate->rot_hw = to_sde_hw_rot(hw_blk);

		if (!rstate->rot_hw->ops.commit) {
			SDE_ERROR("plane%d invalid rotator ops\n",
					plane->base.id);
			SDE_ERROR("plane%d.%d invalid rotator ops\n",
					plane->base.id, rstate->sequence_id);
			sde_crtc_res_put(cstate,
					SDE_HW_BLK_ROT, (u64) state->fb);
			rstate->rot_hw = NULL;
@@ -2275,19 +2267,44 @@ static int sde_plane_rot_atomic_check(struct drm_plane *plane,
	}

	if (sde_plane_enabled(state) && rstate->out_sbuf && rstate->rot_hw) {
		uint32_t fb_id;

		SDE_DEBUG("plane%d.%d use rotator\n",
				plane->base.id, rstate->sequence_id);
		fb_id = state->fb ? state->fb->base.id : -1;
		SDE_DEBUG("plane%d.%d use rotator, fb %d\n",
				plane->base.id, rstate->sequence_id, fb_id);

		sde_plane_rot_calc_cfg(plane, state);

		/* attempt to reuse stream buffer if already available */
		if (sde_plane_enabled(state))
			_sde_plane_rot_get_fb(plane, cstate, rstate);

		ret = sde_plane_rot_submit_command(plane, state,
				SDE_HW_ROT_CMD_VALIDATE);
		if (ret)
			return ret;

		/* check if stream buffer is already attached to rotator */
		_sde_plane_rot_get_fb(plane, cstate, rstate);

		/* release buffer if output format configuration changes */
		if (rstate->out_fb &&
			((rstate->out_fb_height != rstate->out_fb->height) ||
			(rstate->out_fb_width != rstate->out_fb->width) ||
			(rstate->out_fb_pixel_format !=
					rstate->out_fb->pixel_format) ||
			(rstate->out_fb_modifier[0] !=
					rstate->out_fb->modifier[0]) ||
			(rstate->out_fb_flags != rstate->out_fb->flags))) {

			SDE_DEBUG("plane%d.%d release fb/fbo\n", plane->base.id,
					rstate->sequence_id);
			SDE_EVT32_VERBOSE(DRMID(plane),
					rstate->sequence_id, fb_id);

			sde_crtc_res_put(cstate, SDE_CRTC_RES_ROT_OUT_FB,
					(u64) &rstate->rot_hw->base);
			rstate->out_fb = NULL;
			sde_crtc_res_put(cstate, SDE_CRTC_RES_ROT_OUT_FBO,
					(u64) &rstate->rot_hw->base);
			rstate->out_fbo = NULL;
		}
	} else {

		SDE_DEBUG("plane%d.%d bypass rotator\n", plane->base.id,
@@ -2406,8 +2423,6 @@ static int sde_plane_rot_duplicate_state(struct drm_plane *plane,
{
	struct sde_plane_state *pstate  = to_sde_plane_state(new_state);
	struct sde_plane_rot_state *rstate = &pstate->rot;
	struct drm_crtc_state *cstate;
	int ret;

	rstate->sequence_id++;

@@ -2415,19 +2430,7 @@ static int sde_plane_rot_duplicate_state(struct drm_plane *plane,
			rstate->sequence_id,
			!!rstate->out_sbuf, !!rstate->rot_hw);

	cstate = _sde_plane_get_crtc_state(new_state);
	if (IS_ERR(cstate)) {
		ret = PTR_ERR(cstate);
		SDE_ERROR("invalid crtc state %d\n", ret);
		return -EINVAL;
	}

	if (rstate->rot_hw && cstate)
		sde_crtc_res_get(cstate, SDE_HW_BLK_ROT, (u64) rstate->in_fb);
	else if (rstate->rot_hw && !cstate)
		SDE_ERROR("plane%d.%d zombie rotator hw\n",
				plane->base.id, rstate->sequence_id);

	rstate->rot_hw = NULL;
	rstate->out_fb = NULL;
	rstate->out_fbo = NULL;

@@ -3465,7 +3468,7 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane,
		}

		if (psde->pipe_hw->ops.setup_sys_cache) {
			if (rstate->out_sbuf) {
			if (rstate->out_sbuf && rstate->rot_hw) {
				if (rstate->nplane < 2)
					pstate->sc_cfg.op_mode =
					SDE_PIPE_SC_OP_MODE_INLINE_SINGLE;