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

Commit be3a5c8b authored by Jin Li's avatar Jin Li Committed by Gerrit - the friendly Code Review server
Browse files

drm/sde: always use two hw physical pipes as defined in dtsi



When two hardware physical pipes are defined in dtsi for one virtual
plane, driver should always use them and calculate correct source
and destination rectangles.

CRs-Fixed: 1084262
Change-Id: I0bfa69316889e5b3c35c2ca2c1884a19092f364c
Signed-off-by: default avatarJin Li <jinl@codeaurora.org>
parent 625a5a57
Loading
Loading
Loading
Loading
+9 −15
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ static u32 blend_config_per_mixer(struct drm_crtc *crtc,
	struct sde_hw_mixer *lm = mixer->hw_lm;

	u32 flush_mask = 0, crtc_split_width;
	bool is_right_lm = 0;
	bool dual_pipe = false;

	mode = &crtc->state->adjusted_mode;
	crtc_split_width = sde_crtc_mixer_width(sde_crtc, mode);
@@ -190,23 +190,17 @@ static u32 blend_config_per_mixer(struct drm_crtc *crtc,
		 * Always program right lm first if in dual mixer mode,
		 * it could be overwrote later.
		 */
		if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS)
		dual_pipe = (sde_crtc->num_mixers == CRTC_DUAL_MIXERS) ||
				(sde_plane_num_of_phy_pipe(plane) > 1);
		if (dual_pipe)
			sde_crtc->stage_cfg.stage[pstate->stage][1] =
				sde_plane_pipe(plane, 1);
		is_right_lm = plane->state->crtc_x >= crtc_split_width ?
						true : false;
		sde_crtc->stage_cfg.stage[pstate->stage][is_right_lm] =
			sde_plane_pipe(plane, is_right_lm ? 1 : 0);

		/* stage layer on right lm if it crosses the boundary */
		if (plane->state->crtc_x + plane->state->crtc_w >
							crtc_split_width)
			sde_crtc->stage_cfg.stage[pstate->stage][is_right_lm] =
				sde_plane_pipe(plane, is_right_lm ? 1 : 0);
		sde_crtc->stage_cfg.stage[pstate->stage][0] =
			sde_plane_pipe(plane, 0);

		SDE_DEBUG("crtc_id %d pipe %d at stage %d\n",
			crtc->base.id,
			sde_plane_pipe(plane, is_right_lm ? 1 : 0),
			sde_plane_pipe(plane, 0),
			pstate->stage);

		/**
@@ -214,11 +208,11 @@ static u32 blend_config_per_mixer(struct drm_crtc *crtc,
		 * sourcesplit is always enabled, so this layer will
		 * be staged on both the mixers
		 */
		if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS)
		if (dual_pipe)
			ctl->ops.get_bitmask_sspp(ctl, &flush_mask,
					sde_plane_pipe(plane, 1));
		ctl->ops.get_bitmask_sspp(ctl, &flush_mask,
				sde_plane_pipe(plane, is_right_lm ? 1 : 0));
				sde_plane_pipe(plane, 0));

		/* blend config */
		sde_crtc_get_blend_cfg(&blend, pstate);
+1 −0
Original line number Diff line number Diff line
@@ -496,6 +496,7 @@ void sde_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
 * Plane functions
 */
enum sde_sspp sde_plane_pipe(struct drm_plane *plane, uint32_t index);
u32 sde_plane_num_of_phy_pipe(struct drm_plane *plane);
void sde_plane_flush(struct drm_plane *plane);
struct drm_plane *sde_plane_init(struct drm_device *dev,
		uint32_t pipe, bool primary_plane,
+33 −28
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ struct sde_plane {
	char pipe_name[SDE_NAME_SIZE];

	struct list_head phy_planes;
	u32 num_of_phy_planes;

	struct msm_property_info property_info;
	struct msm_property_data property_data[PLANE_PROP_COUNT];
@@ -696,10 +697,9 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
	const struct sde_format *fmt;
	struct drm_crtc *crtc;
	struct drm_framebuffer *fb;
	struct sde_rect src, dst;
	struct sde_rect src, dst, src_tmp, dst_tmp;
	bool q16_data = true;
	struct sde_phy_plane *pp;
	uint32_t num_of_phy_planes = 0, maxlinewidth = 0xFFFF;

	if (!plane || !plane->state) {
		SDE_ERROR("invalid plane/state\n");
@@ -750,34 +750,27 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
		src.y &= ~0x1;
	}

	list_for_each_entry(pp, &psde->phy_planes, list) {
		if (maxlinewidth > pp->pipe_sblk->maxlinewidth)
			maxlinewidth = pp->pipe_sblk->maxlinewidth;
		num_of_phy_planes++;
	if (!psde->num_of_phy_planes) {
		SDE_ERROR("No physical pipe for this plane=%s\n",
			psde->pipe_name);
		return -EINVAL;
	}

	/*
	 * Only need to use one physical plane if plane width is still within
	 * the limitation.
	 */
	if (maxlinewidth >= (src.x + src.w))
		num_of_phy_planes = 1;

	if (num_of_phy_planes > 1) {
	/* Adjust width for multi-pipe */
		src.w /= num_of_phy_planes;
		dst.w /= num_of_phy_planes;
	}
	src.w /= psde->num_of_phy_planes;
	dst.w /= psde->num_of_phy_planes;

	list_for_each_entry(pp, &psde->phy_planes, list) {
		memset(&(pp->pipe_cfg), 0, sizeof(struct sde_hw_pipe_cfg));
		src_tmp = src;
		dst_tmp = dst;

		/* Adjust offset for multi-pipe */
		src.x += src.w * pp->index;
		dst.x += dst.w * pp->index;
		src_tmp.x = src.x + src.w * pp->index;
		dst_tmp.x = dst.x + dst.w * pp->index;

		pp->pipe_cfg.src_rect = src;
		pp->pipe_cfg.dst_rect = dst;
		pp->pipe_cfg.src_rect = src_tmp;
		pp->pipe_cfg.dst_rect = dst_tmp;

		/* check for color fill */
		pp->color_fill = (uint32_t)sde_plane_get_property(pstate,
@@ -958,7 +951,6 @@ static int sde_plane_atomic_check(struct drm_plane *plane,
	uint32_t max_upscale, max_downscale, min_src_size, max_linewidth;
	bool q16_data = true;
	struct sde_phy_plane *pp;
	uint32_t num_of_phy_planes = 0;

	if (!plane || !state) {
		SDE_ERROR("invalid plane/state\n");
@@ -969,9 +961,6 @@ static int sde_plane_atomic_check(struct drm_plane *plane,
	psde = to_sde_plane(plane);
	pstate = to_sde_plane_state(state);

	list_for_each_entry(pp, &psde->phy_planes, list)
		num_of_phy_planes++;

	valid_scale_data = __get_scale_data(psde, pstate, sc_u, &sc_u_size);
	deci_w = valid_scale_data && sc_u ? sc_u->v1.horz_decimate : 0;
	deci_h = valid_scale_data && sc_u ? sc_u->v1.vert_decimate : 0;
@@ -1054,11 +1043,12 @@ static int sde_plane_atomic_check(struct drm_plane *plane,
			ret = -EINVAL;

		/* check decimated source width */
		} else if (src_deci_w > max_linewidth * num_of_phy_planes) {
		} else if (src_deci_w >
				max_linewidth * psde->num_of_phy_planes) {
			SDE_ERROR("invalid source width:%u, deci wid:%u, line\"\
					wid:%u num_of_phy_plane=%u\n",
					src.w, src_deci_w, max_linewidth,
					num_of_phy_planes);
					psde->num_of_phy_planes);
			ret = -E2BIG;

		/* check max scaler capability */
@@ -1507,6 +1497,19 @@ enum sde_sspp sde_plane_pipe(struct drm_plane *plane, uint32_t index)
	return default_sspp;
}

u32 sde_plane_num_of_phy_pipe(struct drm_plane *plane)
{
	struct sde_plane *sde_plane = to_sde_plane(plane);

	if (!plane || !sde_plane) {
		SDE_ERROR("plane=%p or sde_plane=%p is NULL\n",
			plane, sde_plane);
		return 0;
	}

	return sde_plane->num_of_phy_planes;
}

static void _sde_plane_init_debugfs(struct sde_plane *psde, struct sde_kms *kms)
{
	const struct sde_sspp_sub_blks *sblk = NULL;
@@ -1686,6 +1689,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev,
			}
			list_add_tail(&pp->list, &psde->phy_planes);
			index++;
			psde->num_of_phy_planes++;
		}
	} else {
		pp = kzalloc(sizeof(*pp), GFP_KERNEL);
@@ -1706,6 +1710,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev,
		memcpy(formats, pp->formats,
			sizeof(uint32_t) * 64);
		list_add_tail(&pp->list, &psde->phy_planes);
		psde->num_of_phy_planes++;
	}

	if (kms->catalog && kms->catalog->mixer_count && kms->catalog->mixer)