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

Commit 4e1764fb 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: add check for inline rotation source split cfg"

parents 32216c93 05109758
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -685,10 +685,8 @@ static int sde_hw_rot_commit(struct sde_hw_rot *hw, struct sde_hw_rot_cmd *data,
				hw_cmd);

		rc = sde_rotator_inline_commit(hw->rot_ctx, &rot_cmd, cmd_type);
		if (rc) {
			SDE_ERROR("failed to commit inline rotation %d\n", rc);
		if (rc)
			return rc;
		}

		/* return to caller */
		data->priv_handle = rot_cmd.priv_handle;
+80 −19
Original line number Diff line number Diff line
@@ -1575,14 +1575,13 @@ bool sde_plane_is_sbuf_mode(struct drm_plane *plane, u32 *prefill)
 *	enumerating over all planes attached to the same rotator
 * @plane: Pointer to drm plane
 * @state: Pointer to drm state to be updated
 * return: none
 * return: 0 if success; error code otherwise
 */
static void sde_plane_rot_calc_cfg(struct drm_plane *plane,
static int sde_plane_rot_calc_cfg(struct drm_plane *plane,
		struct drm_plane_state *state)
{
	struct sde_plane_state *pstate;
	struct sde_plane_rot_state *rstate;
	struct sde_hw_blk *hw_blk;
	struct drm_crtc_state *cstate;
	struct drm_rect *in_rot, *out_rot;
	struct drm_plane *attached_plane;
@@ -1593,24 +1592,19 @@ static void sde_plane_rot_calc_cfg(struct drm_plane *plane,

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

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

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

	if (!rstate->rot_hw) {
		SDE_ERROR("invalid rotator hw\n");
		return;
	}

	in_rot = &rstate->in_rot_rect;
	in_rot->x1 = state->src_x;
	in_rot->y1 = state->src_y;
@@ -1636,8 +1630,6 @@ static void sde_plane_rot_calc_cfg(struct drm_plane *plane,

	rstate->out_src_rect = rstate->out_rot_rect;

	hw_blk = &rstate->rot_hw->base;

	/* enumerating over all planes attached to the same rotator */
	drm_atomic_crtc_state_for_each_plane(attached_plane, cstate) {
		struct drm_plane_state *attached_state;
@@ -1710,6 +1702,71 @@ static void sde_plane_rot_calc_cfg(struct drm_plane *plane,
			attached_out_rect.y2 = dst_y + dst_h;
		}

		/* check source split left/right mismatch */
		if (attached_out_rect.y1 != rstate->out_src_rect.y1 ||
			attached_out_rect.y2 != rstate->out_src_rect.y2) {
			SDE_ERROR(
				"plane%d.%u src:%dx%d+%d+%d rot:0x%llx fb:%d plane%d.%u src:%dx%d+%d+%d rot:0x%llx fb:%d mismatch\n",
					plane->base.id,
					rstate->sequence_id,
					state->src_w >> 16,
					state->src_h >> 16,
					state->src_x >> 16,
					state->src_y >> 16,
					sde_plane_get_property(pstate,
							PLANE_PROP_ROTATION),
					state->fb ?
						state->fb->base.id :
						-1,
					attached_plane->base.id,
					attached_rstate->sequence_id,
					attached_state->src_w >> 16,
					attached_state->src_h >> 16,
					attached_state->src_x >> 16,
					attached_state->src_y >> 16,
					sde_plane_get_property(attached_pstate,
							PLANE_PROP_ROTATION),
					attached_state->fb ?
						attached_state->fb->base.id :
						-1);
			SDE_ERROR(
				"plane%d.%u sspp:%dx%d+%d+%d plane%d.%u sspp:%dx%d+%d+%d\n",
					plane->base.id,
					rstate->sequence_id,
					(rstate->out_src_rect.x2 -
						rstate->out_src_rect.x1) >> 16,
					(rstate->out_src_rect.y2 -
						rstate->out_src_rect.y1) >> 16,
					rstate->out_src_rect.x1 >> 16,
					rstate->out_src_rect.y1 >> 16,
					attached_plane->base.id,
					attached_rstate->sequence_id,
					(attached_out_rect.x2 -
						attached_out_rect.x1) >> 16,
					(attached_out_rect.y2 -
						attached_out_rect.y1) >> 16,
					attached_out_rect.x1 >> 16,
					attached_out_rect.y1 >> 16);
			SDE_EVT32(DRMID(plane),
					rstate->sequence_id,
					rstate->out_src_rect.x1 >> 16,
					rstate->out_src_rect.y1 >> 16,
					(rstate->out_src_rect.x2 -
						rstate->out_src_rect.x1) >> 16,
					(rstate->out_src_rect.y2 -
						rstate->out_src_rect.y1) >> 16,
					attached_plane->base.id,
					attached_rstate->sequence_id,
					attached_out_rect.x1 >> 16,
					attached_out_rect.y1 >> 16,
					(attached_out_rect.x2 -
						attached_out_rect.x1) >> 16,
					(attached_out_rect.y2 -
						attached_out_rect.y1) >> 16,
					SDE_EVTLOG_ERROR);
			return -EINVAL;
		}

		/* find relative sspp position */
		if (attached_out_rect.x1 < rstate->out_src_rect.x1)
			xpos++;
@@ -1762,6 +1819,8 @@ static void sde_plane_rot_calc_cfg(struct drm_plane *plane,
			rstate->out_rot_rect.y1 >> 16,
			drm_rect_width(&rstate->out_rot_rect) >> 16,
			drm_rect_height(&rstate->out_rot_rect) >> 16);

	return 0;
}

/**
@@ -1840,8 +1899,8 @@ static int sde_plane_rot_submit_command(struct drm_plane *plane,
	rot_cmd->src_rect_y = rstate->in_rot_rect.y1 >> 16;
	rot_cmd->src_rect_w = drm_rect_width(&rstate->in_rot_rect) >> 16;
	rot_cmd->src_rect_h = drm_rect_height(&rstate->in_rot_rect) >> 16;
	rot_cmd->dst_rect_x = rstate->out_rot_rect.x1 >> 16;
	rot_cmd->dst_rect_y = rstate->out_rot_rect.y1 >> 16;
	rot_cmd->dst_rect_x = 0;
	rot_cmd->dst_rect_y = 0;
	rot_cmd->dst_rect_w = drm_rect_width(&rstate->out_rot_rect) >> 16;
	rot_cmd->dst_rect_h = drm_rect_height(&rstate->out_rot_rect) >> 16;

@@ -1886,10 +1945,8 @@ static int sde_plane_rot_submit_command(struct drm_plane *plane,
	}

	ret = rstate->rot_hw->ops.commit(rstate->rot_hw, rot_cmd, hw_cmd);
	if (ret) {
		SDE_ERROR("failed to commit rotator %d\n", ret);
	if (ret)
		return ret;
	}

	rstate->out_rotation = rstate->in_rotation;
	rstate->out_fb_flags = rot_cmd->dst_modifier ?
@@ -2017,7 +2074,9 @@ static int sde_plane_rot_prepare_fb(struct drm_plane *plane,
	}

	/* need to re-calc based on all newly validated plane states */
	sde_plane_rot_calc_cfg(plane, new_state);
	ret = sde_plane_rot_calc_cfg(plane, new_state);
	if (ret)
		return ret;

	/* check if stream buffer is already attached to rotator */
	if (sde_plane_enabled(new_state) && !new_rstate->out_fb)
@@ -2251,7 +2310,9 @@ static int sde_plane_rot_atomic_check(struct drm_plane *plane,
		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);
		ret = sde_plane_rot_calc_cfg(plane, state);
		if (ret)
			return ret;

		ret = sde_plane_rot_submit_command(plane, state,
				SDE_HW_ROT_CMD_VALIDATE);
+17 −9
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@
 *
 */

#define pr_fmt(fmt)	"%s: " fmt, __func__
#define pr_fmt(fmt)	"%s:%d: " fmt, __func__, __LINE__

#include <linux/platform_device.h>
#include <linux/module.h>
@@ -1663,18 +1663,20 @@ static void sde_rotator_done_handler(struct kthread_work *work)

static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr,
	struct sde_mdp_format_params *in_fmt,
	struct sde_mdp_format_params *out_fmt, bool rotation)
	struct sde_mdp_format_params *out_fmt, bool rotation, u32 mode)
{
	u8 in_v_subsample, in_h_subsample;
	u8 out_v_subsample, out_h_subsample;

	if (!sde_rotator_is_valid_pixfmt(mgr, in_fmt->format, true)) {
		SDEROT_ERR("Invalid input format %x\n", in_fmt->format);
	if (!sde_rotator_is_valid_pixfmt(mgr, in_fmt->format, true, mode)) {
		SDEROT_ERR("Invalid input format 0x%x (%4.4s)\n",
				in_fmt->format, (char *)&in_fmt->format);
		goto verify_error;
	}

	if (!sde_rotator_is_valid_pixfmt(mgr, out_fmt->format, false)) {
		SDEROT_ERR("Invalid output format %x\n", out_fmt->format);
	if (!sde_rotator_is_valid_pixfmt(mgr, out_fmt->format, false, mode)) {
		SDEROT_ERR("Invalid output format 0x%x (%4.4s)\n",
				out_fmt->format, (char *)&out_fmt->format);
		goto verify_error;
	}

@@ -1723,8 +1725,10 @@ static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr,
	return true;

verify_error:
	SDEROT_ERR("in_fmt=0x%x, out_fmt=0x%x\n",
			in_fmt->format, out_fmt->format);
	SDEROT_ERR("in_fmt=0x%x (%4.4s), out_fmt=0x%x (%4.4s), mode=%d\n",
			in_fmt->format, (char *)&in_fmt->format,
			out_fmt->format, (char *)&out_fmt->format,
			mode);
	return false;
}

@@ -1843,6 +1847,7 @@ int sde_rotator_verify_config_all(struct sde_rot_mgr *mgr,
{
	struct sde_mdp_format_params *in_fmt, *out_fmt;
	bool rotation;
	u32 mode;

	if (!mgr || !config) {
		SDEROT_ERR("null parameters\n");
@@ -1851,6 +1856,9 @@ int sde_rotator_verify_config_all(struct sde_rot_mgr *mgr,

	rotation = (config->flags & SDE_ROTATION_90) ? true : false;

	mode = config->output.sbuf ? SDE_ROTATOR_MODE_SBUF :
				SDE_ROTATOR_MODE_OFFLINE;

	in_fmt = __verify_input_config(mgr, config);
	if (!in_fmt)
		return -EINVAL;
@@ -1859,7 +1867,7 @@ int sde_rotator_verify_config_all(struct sde_rot_mgr *mgr,
	if (!out_fmt)
		return -EINVAL;

	if (!sde_rotator_verify_format(mgr, in_fmt, out_fmt, rotation)) {
	if (!sde_rotator_verify_format(mgr, in_fmt, out_fmt, rotation, mode)) {
		SDEROT_ERR(
			"Rot format pairing invalid, in_fmt:0x%x, out_fmt:0x%x\n",
					config->input.format,
+12 −6
Original line number Diff line number Diff line
@@ -141,6 +141,12 @@ enum sde_rotator_trigger {
	SDE_ROTATOR_TRIGGER_COMMAND,
};

enum sde_rotator_mode {
	SDE_ROTATOR_MODE_OFFLINE,
	SDE_ROTATOR_MODE_SBUF,
	SDE_ROTATOR_MODE_MAX,
};

struct sde_rotation_item {
	/* rotation request flag */
	uint32_t	flags;
@@ -463,9 +469,9 @@ struct sde_rot_mgr {
	int (*ops_hw_validate_entry)(struct sde_rot_mgr *mgr,
			struct sde_rot_entry *entry);
	u32 (*ops_hw_get_pixfmt)(struct sde_rot_mgr *mgr, int index,
			bool input);
			bool input, u32 mode);
	int (*ops_hw_is_valid_pixfmt)(struct sde_rot_mgr *mgr, u32 pixfmt,
			bool input);
			bool input, u32 mode);
	int (*ops_hw_get_downscale_caps)(struct sde_rot_mgr *mgr, char *caps,
			int len);
	int (*ops_hw_get_maxlinewidth)(struct sde_rot_mgr *mgr);
@@ -474,19 +480,19 @@ struct sde_rot_mgr {
};

static inline int sde_rotator_is_valid_pixfmt(struct sde_rot_mgr *mgr,
		u32 pixfmt, bool input)
		u32 pixfmt, bool input, u32 mode)
{
	if (mgr && mgr->ops_hw_is_valid_pixfmt)
		return mgr->ops_hw_is_valid_pixfmt(mgr, pixfmt, input);
		return mgr->ops_hw_is_valid_pixfmt(mgr, pixfmt, input, mode);

	return false;
}

static inline u32 sde_rotator_get_pixfmt(struct sde_rot_mgr *mgr,
		int index, bool input)
		int index, bool input, u32 mode)
{
	if (mgr && mgr->ops_hw_get_pixfmt)
		return mgr->ops_hw_get_pixfmt(mgr, index, input);
		return mgr->ops_hw_get_pixfmt(mgr, index, input, mode);

	return 0;
}
+9 −6
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#define pr_fmt(fmt)	"%s: " fmt, __func__
#define pr_fmt(fmt)	"%s:%d: " fmt, __func__, __LINE__

#include <linux/vmalloc.h>
#include <linux/kernel.h>
@@ -1433,7 +1433,8 @@ int sde_rotator_inline_get_pixfmt_caps(struct platform_device *pdev,

	sde_rot_mgr_lock(rot_dev->mgr);
	for (i = 0;; i++) {
		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, input);
		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, input,
				SDE_ROTATOR_MODE_SBUF);
		if (!pixfmt)
			break;
		if (pixfmts && i < len)
@@ -1610,7 +1611,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd,
			ret = sde_rotator_session_config(rot_dev->mgr,
					ctx->private, &rotcfg);
			if (ret) {
				SDEROT_ERR("fail session config s:%d\n",
				SDEROT_WARN("fail session config s:%d\n",
						ctx->session_id);
				goto error_session_config;
			}
@@ -1621,7 +1622,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd,
		ret = sde_rotator_validate_request(rot_dev->mgr, ctx->private,
				req);
		if (ret) {
			SDEROT_ERR("fail validate request s:%d\n",
			SDEROT_WARN("fail validate request s:%d\n",
					ctx->session_id);
			goto error_validate_request;
		}
@@ -1857,7 +1858,8 @@ static int sde_rotator_enum_fmt_vid_cap(struct file *file,
	bool found = false;

	for (i = 0, index = 0; index <= f->index; i++) {
		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, false);
		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, false,
				SDE_ROTATOR_MODE_OFFLINE);
		if (!pixfmt)
			return -EINVAL;

@@ -1901,7 +1903,8 @@ static int sde_rotator_enum_fmt_vid_out(struct file *file,
	bool found = false;

	for (i = 0, index = 0; index <= f->index; i++) {
		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, true);
		pixfmt = sde_rotator_get_pixfmt(rot_dev->mgr, i, true,
				SDE_ROTATOR_MODE_OFFLINE);
		if (!pixfmt)
			return -EINVAL;

Loading