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

Commit 2606dd63 authored by Clarence Ip's avatar Clarence Ip
Browse files

drm/msm/sde: add plane support for halt and rotate reset



Add functions to the SDE plane driver to allow for halting
outstanding VBIF transactions and resetting the inline
rotation driver.

Change-Id: I7abf98cd26092e3166001cfa18d84be14570651f
Signed-off-by: default avatarClarence Ip <cip@codeaurora.org>
parent 19339b3f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -588,6 +588,10 @@ static int sde_hw_rot_commit(struct sde_hw_rot *hw, struct sde_hw_rot_cmd *data,
		cmd_type = SDE_ROTATOR_INLINE_CMD_CLEANUP;
		priv_handle = data->priv_handle;
		break;
	case SDE_HW_ROT_CMD_RESET:
		cmd_type = SDE_ROTATOR_INLINE_CMD_ABORT;
		priv_handle = data->priv_handle;
		break;
	default:
		SDE_ERROR("invalid hw rotator command %d\n", hw_cmd);
		return -EINVAL;
+2 −0
Original line number Diff line number Diff line
@@ -28,12 +28,14 @@ struct sde_hw_rot;
 * @SDE_HW_ROT_CMD_COMMIT: commit/execute rotator command
 * @SDE_HW_ROT_CMD_START: mdp is ready to start
 * @SDE_HW_ROT_CMD_CLEANUP: cleanup rotator command after it is done
 * @SDE_HW_ROT_CMD_RESET: request rotator h/w reset
 */
enum sde_hw_rot_cmd_type {
	SDE_HW_ROT_CMD_VALIDATE,
	SDE_HW_ROT_CMD_COMMIT,
	SDE_HW_ROT_CMD_START,
	SDE_HW_ROT_CMD_CLEANUP,
	SDE_HW_ROT_CMD_RESET,
};

/**
+107 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ enum sde_plane_qos {
 * @sbuf_mode: force stream buffer mode if set
 * @sbuf_writeback: force stream buffer writeback if set
 * @revalidate: force revalidation of all the plane properties
 * @xin_halt_forced_clk: whether or not clocks were forced on for xin halt
 * @blob_rot_caps: Pointer to rotator capability blob
 */
struct sde_plane {
@@ -128,6 +129,7 @@ struct sde_plane {
	u32 sbuf_mode;
	u32 sbuf_writeback;
	bool revalidate;
	bool xin_halt_forced_clk;

	struct sde_csc_cfg csc_cfg;
	struct sde_csc_cfg *csc_usr_ptr;
@@ -2489,6 +2491,111 @@ static void sde_plane_rot_atomic_update(struct drm_plane *plane,
	msm_framebuffer_cleanup(state->fb, pstate->aspace);
}

static bool _sde_plane_halt_requests(struct drm_plane *plane,
		uint32_t xin_id, bool halt_forced_clk, bool enable)
{
	struct sde_plane *psde;
	struct msm_drm_private *priv;
	struct sde_vbif_set_xin_halt_params halt_params;

	if (!plane || !plane->dev) {
		SDE_ERROR("invalid arguments\n");
		return false;
	}

	psde = to_sde_plane(plane);
	if (!psde->pipe_hw || !psde->pipe_hw->cap) {
		SDE_ERROR("invalid pipe reference\n");
		return false;
	}

	priv = plane->dev->dev_private;
	if (!priv || !priv->kms) {
		SDE_ERROR("invalid KMS reference\n");
		return false;
	}

	memset(&halt_params, 0, sizeof(halt_params));
	halt_params.vbif_idx = VBIF_RT;
	halt_params.xin_id = xin_id;
	halt_params.clk_ctrl = psde->pipe_hw->cap->clk_ctrl;
	halt_params.forced_on = halt_forced_clk;
	halt_params.enable = enable;

	return sde_vbif_set_xin_halt(to_sde_kms(priv->kms), &halt_params);
}

void sde_plane_halt_requests(struct drm_plane *plane, bool enable)
{
	struct sde_plane *psde;

	if (!plane) {
		SDE_ERROR("invalid plane\n");
		return;
	}

	psde = to_sde_plane(plane);
	if (!psde->pipe_hw || !psde->pipe_hw->cap) {
		SDE_ERROR("invalid pipe reference\n");
		return;
	}

	SDE_EVT32(DRMID(plane), psde->xin_halt_forced_clk, enable);

	psde->xin_halt_forced_clk =
		_sde_plane_halt_requests(plane, psde->pipe_hw->cap->xin_id,
				psde->xin_halt_forced_clk, enable);
}

int sde_plane_reset_rot(struct drm_plane *plane, struct drm_plane_state *state)
{
	struct sde_plane *psde;
	struct sde_plane_state *pstate;
	struct sde_plane_rot_state *rstate;
	bool halt_ret[MAX_BLOCKS] = {false};
	signed int i, count;

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

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

	/* do nothing if not master rotator plane */
	if (!rstate->out_sbuf || !rstate->rot_hw ||
			!rstate->rot_hw->caps || (rstate->out_xpos != 0))
		return 0;

	count = (signed int)rstate->rot_hw->caps->xin_count;
	if (count > ARRAY_SIZE(halt_ret))
		count = ARRAY_SIZE(halt_ret);

	SDE_DEBUG_PLANE(psde, "issuing reset for rotator\n");
	SDE_EVT32(DRMID(plane), count);

	for (i = 0; i < count; i++) {
		const struct sde_rot_vbif_cfg *cfg =
				&rstate->rot_hw->caps->vbif_cfg[i];

		halt_ret[i] = _sde_plane_halt_requests(plane, cfg->xin_id,
				false, true);
	}

	sde_plane_rot_submit_command(plane, state, SDE_HW_ROT_CMD_RESET);

	for (i = count - 1; i >= 0; --i) {
		const struct sde_rot_vbif_cfg *cfg =
				&rstate->rot_hw->caps->vbif_cfg[i];

		_sde_plane_halt_requests(plane, cfg->xin_id,
				halt_ret[i], false);
	}
	return 0;
}

int sde_plane_kickoff_rot(struct drm_plane *plane)
{
	struct sde_plane_state *pstate;
+17 −0
Original line number Diff line number Diff line
@@ -227,6 +227,23 @@ void sde_plane_restore(struct drm_plane *plane);
 */
void sde_plane_flush(struct drm_plane *plane);

/**
 * sde_plane_halt_requests - control halting of vbif transactions for this plane
 *	This function isn't thread safe. Plane halt enable/disable requests
 *	should always be made from the same commit cycle.
 * @plane: Pointer to drm plane structure
 * @enable: Whether to enable/disable halting of vbif transactions
 */
void sde_plane_halt_requests(struct drm_plane *plane, bool enable);

/**
 * sde_plane_reset_rot - reset rotator operations before commit kickoff
 * @plane: Pointer to drm plane structure
 * @state: Pointer to plane state associated with reset request
 * Returns: Zero on success
 */
int sde_plane_reset_rot(struct drm_plane *plane, struct drm_plane_state *state);

/**
 * sde_plane_kickoff_rot - final plane rotator operations before commit kickoff
 * @plane: Pointer to drm plane structure