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

This commit is contained in:
Linux Build Service Account 2020-07-10 12:35:48 -07:00 • committed by Gerrit - the friendly Code Review server
commit 6db21fc335

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;
}