disp: msm: sde: update cwb checks for destination scaler

Current validation checks for cwb are not complete for
destination scaler concurrency. This change fixes cwb
checks to handle wb roi and frame buffer bounds checks
based on tap point and the destination scaler use.

Change-Id: I4a0277fea262621e73459243f60d3018bc475a67
Signed-off-by: Prabhanjan Kandula <pkandula@codeaurora.org>
This commit is contained in:
Prabhanjan Kandula 2020-06-17 18:50:50 -07:00 committed by Gerrit - the friendly Code Review server
parent 5c92c5ac78
commit 4a54016d44

View File

@ -604,59 +604,102 @@ static void _sde_enc_phys_wb_detect_cwb(struct sde_encoder_phys *phys_enc,
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_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;
}
/* validate conn roi against pu rect */
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;
}
/* 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;
}