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

Commit 6db21fc3 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: sde: update cwb checks for destination scaler" into display-kernel.lnx.5.4

parents 026b9de2 4a54016d
Loading
Loading
Loading
Loading
+72 −25
Original line number Diff line number Diff line
@@ -606,57 +606,100 @@ static int _sde_enc_phys_wb_validate_cwb(struct sde_encoder_phys *phys_enc,
			struct drm_crtc_state *crtc_state,
			struct drm_connector_state *conn_state)
{
	struct drm_framebuffer *fb;
	struct sde_crtc_state *cstate = to_sde_crtc_state(crtc_state);
	const struct drm_display_mode *mode = &crtc_state->mode;
	struct sde_rect wb_roi = {0,};
	struct sde_rect pu_roi = {0,};
	int out_width = 0, out_height = 0;
	int ds_srcw = 0, ds_srch = 0, ds_outw = 0, ds_outh = 0;
	int data_pt;
	int ds_outw = 0;
	int ds_outh = 0;
	int ds_in_use = false;
	int i = 0;
	int ret = 0;

	if (!phys_enc->in_clone_mode) {
		SDE_DEBUG("not in CWB mode. early return\n");
		goto exit;
	fb = sde_wb_connector_state_get_output_fb(conn_state);
	if (!fb) {
		SDE_DEBUG("no output framebuffer\n");
		return 0;
	}

	ret = sde_wb_connector_state_get_output_roi(conn_state, &wb_roi);
	if (ret) {
		SDE_ERROR("failed to get roi %d\n", ret);
		goto exit;
		return ret;
	}

	if (!wb_roi.w || !wb_roi.h) {
		SDE_ERROR("cwb roi is not set wxh:%dx%d\n", wb_roi.w, wb_roi.h);
		return -EINVAL;
	}

	data_pt = sde_crtc_get_property(cstate, CRTC_PROP_CAPTURE_OUTPUT);

	/* compute cumulative ds output dimensions if in use */
	for (i = 0; i < cstate->num_ds; i++)
	for (i = 0; i < cstate->num_ds; i++) {
		if (cstate->ds_cfg[i].scl3_cfg.enable) {
			ds_in_use = true;
			ds_outw += cstate->ds_cfg[i].scl3_cfg.dst_width;
			ds_outh = cstate->ds_cfg[i].scl3_cfg.dst_height;
			ds_srcw +=  cstate->ds_cfg[i].lm_width;
			ds_srch =  cstate->ds_cfg[i].lm_height;
		}
	}

	/* if ds in use check wb roi against ds output dimensions */
	if ((data_pt == CAPTURE_DSPP_OUT) &&  ds_in_use &&
			((wb_roi.w != ds_outw) || (wb_roi.h != ds_outh))) {
		SDE_ERROR("invalid wb roi with dest scalar [%dx%d vs %dx%d]\n",
				wb_roi.w, wb_roi.h, ds_outw, ds_outh);
		ret = -EINVAL;
		goto exit;
	if ((ds_in_use && (!ds_outw || !ds_outh || !ds_srcw || !ds_srch))) {
		SDE_ERROR("invalid ds cfg src:%dx%d dst:%dx%d\n",
				ds_srcw, ds_srch, ds_outw, ds_outh);
		return -EINVAL;
	}

	/* validate conn roi against pu rect */
	/* 1) No DS case: same restrictions for LM & DSSPP tap point
	 *	a) wb-roi should be inside FB
	 *	b) mode resolution & wb-roi should be same
	 * 2) With DS case: restrictions would change based on tap point
	 *	2.1) LM Tap Point:
	 *		a) wb-roi should be inside FB
	 *		b) wb-roi should be same as crtc-LM bounds
	 *	2.2) DSPP Tap point: same as No DS case
	 *		a) wb-roi should be inside FB
	 *		b) mode resolution & wb-roi should be same
	 */
	if (ds_in_use && data_pt == CAPTURE_DSPP_OUT) {
		out_width = ds_outw;
		out_height = ds_outh;
	} else if (ds_in_use) { /* LM tap point */
		out_width = ds_srcw;
		out_height = ds_srch;
	} else {
		out_width = mode->hdisplay;
		out_height = mode->vdisplay;
	}

	if ((wb_roi.w != out_width) || (wb_roi.h != out_height)) {
		SDE_ERROR("invalid wb roi[%dx%d] with ds_use:%d out[%dx%d]\n",
				wb_roi.w, wb_roi.h, out_width, out_height);
		return -EINVAL;
	}

	if (((wb_roi.x + wb_roi.w) > fb->width) ||
			((wb_roi.y + wb_roi.h) > fb->height)) {
		SDE_ERROR("invalid wb roi[%d,%d,%d,%d] fb[%dx%d]\n",
				wb_roi.x, wb_roi.y, wb_roi.w, wb_roi.h,
				fb->width, fb->height);
		return -EINVAL;
	}

	/* validate wb roi against pu rect */
	if (cstate->user_roi_list.num_rects) {
		sde_kms_rect_merge_rectangles(&cstate->user_roi_list, &pu_roi);
		if (wb_roi.w != pu_roi.w || wb_roi.h != pu_roi.h) {
			SDE_ERROR("invalid wb roi with pu [%dx%d vs %dx%d]\n",
					wb_roi.w, wb_roi.h, pu_roi.w, pu_roi.h);
			ret = -EINVAL;
			goto exit;
			return -EINVAL;
		}
	}
exit:

	return ret;
}

@@ -742,6 +785,16 @@ static int sde_encoder_phys_wb_atomic_check(
	if (SDE_FORMAT_IS_YUV(fmt) != !!phys_enc->hw_cdm)
		crtc_state->mode_changed = true;

	/* if in clone mode, return after cwb validation */
	if (phys_enc->in_clone_mode) {
		rc = _sde_enc_phys_wb_validate_cwb(phys_enc, crtc_state,
				conn_state);
		if (rc)
			SDE_ERROR("failed in cwb validation %d\n", rc);

		return rc;
	}

	if (wb_roi.w && wb_roi.h) {
		if (wb_roi.w != mode->hdisplay) {
			SDE_ERROR("invalid roi w=%d, mode w=%d\n", wb_roi.w,
@@ -786,12 +839,6 @@ static int sde_encoder_phys_wb_atomic_check(
		}
	}

	rc = _sde_enc_phys_wb_validate_cwb(phys_enc, crtc_state, conn_state);
	if (rc) {
		SDE_ERROR("failed in cwb validation %d\n", rc);
		return rc;
	}

	return rc;
}