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

Commit fdd66c7e authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: enforce pipe priority restrictions" into msm-4.8

parents ab3dd30d 629ce1fe
Loading
Loading
Loading
Loading
+60 −9
Original line number Diff line number Diff line
@@ -1231,11 +1231,10 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,

	int cnt = 0, rc = 0, mixer_width, i, z_pos;

	int left_crtc_zpos_cnt[SDE_STAGE_MAX] = {0};
	int right_crtc_zpos_cnt[SDE_STAGE_MAX] = {0};
	struct sde_multirect_plane_states multirect_plane[SDE_STAGE_MAX * 2];
	int multirect_count = 0;
	const struct drm_plane_state *pipe_staged[SSPP_MAX];
	int left_zpos_cnt = 0, right_zpos_cnt = 0;

	if (!crtc) {
		SDE_ERROR("invalid crtc\n");
@@ -1342,11 +1341,12 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
		}
	}

	/* assign mixer stages based on sorted zpos property */
	sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL);

	if (!sde_is_custom_client()) {
		int stage_old = pstates[0].stage;

		/* assign mixer stages based on sorted zpos property */
		sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL);
		z_pos = 0;
		for (i = 0; i < cnt; i++) {
			if (stage_old != pstates[i].stage)
@@ -1356,8 +1356,14 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
		}
	}

	z_pos = -1;
	for (i = 0; i < cnt; i++) {
		/* reset counts at every new blend stage */
		if (pstates[i].stage != z_pos) {
			left_zpos_cnt = 0;
			right_zpos_cnt = 0;
			z_pos = pstates[i].stage;
		}

		/* verify z_pos setting before using it */
		if (z_pos >= SDE_STAGE_MAX - SDE_STAGE_0) {
@@ -1366,22 +1372,24 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
			rc = -EINVAL;
			goto end;
		} else if (pstates[i].drm_pstate->crtc_x < mixer_width) {
			if (left_crtc_zpos_cnt[z_pos] == 2) {
			if (left_zpos_cnt == 2) {
				SDE_ERROR("> 2 planes @ stage %d on left\n",
					z_pos);
				rc = -EINVAL;
				goto end;
			}
			left_crtc_zpos_cnt[z_pos]++;
			left_zpos_cnt++;

		} else {
			if (right_crtc_zpos_cnt[z_pos] == 2) {
			if (right_zpos_cnt == 2) {
				SDE_ERROR("> 2 planes @ stage %d on right\n",
					z_pos);
				rc = -EINVAL;
				goto end;
			}
			right_crtc_zpos_cnt[z_pos]++;
			right_zpos_cnt++;
		}

		pstates[i].sde_pstate->stage = z_pos + SDE_STAGE_0;
		SDE_DEBUG("%s: zpos %d", sde_crtc->name, z_pos);
	}
@@ -1404,6 +1412,49 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
		goto end;
	}

	/*
	 * enforce pipe priority restrictions
	 * use pstates sorted by stage to check planes on same stage
	 * we assume that all pipes are in source split so its valid to compare
	 * without taking into account left/right mixer placement
	 */
	for (i = 1; i < cnt; i++) {
		struct plane_state *prv_pstate, *cur_pstate;
		int32_t prv_x, cur_x, prv_id, cur_id;

		prv_pstate = &pstates[i - 1];
		cur_pstate = &pstates[i];
		if (prv_pstate->stage != cur_pstate->stage)
			continue;

		prv_x = prv_pstate->drm_pstate->crtc_x;
		cur_x = cur_pstate->drm_pstate->crtc_x;
		prv_id = prv_pstate->sde_pstate->base.plane->base.id;
		cur_id = cur_pstate->sde_pstate->base.plane->base.id;

		/*
		 * Planes are enumerated in pipe-priority order such that planes
		 * with lower drm_id must be left-most in a shared blend-stage
		 * when using source split.
		 */
		if (cur_x > prv_x && cur_id < prv_id) {
			SDE_ERROR(
				"shared z_pos %d lower id plane%d @ x%d should be left of plane%d @ x %d\n",
				cur_pstate->stage, cur_id, cur_x,
				prv_id, prv_x);
			rc = -EINVAL;
			goto end;
		} else if (cur_x < prv_x && cur_id > prv_id) {
			SDE_ERROR(
				"shared z_pos %d lower id plane%d @ x%d should be left of plane%d @ x %d\n",
				cur_pstate->stage, prv_id, prv_x,
				cur_id, cur_x);
			rc = -EINVAL;
			goto end;
		}
	}


end:
	return rc;
}