On Thu, Mar 01, 2018 at 04:52:35PM -0800, Jeykumar Sankaran wrote: > Implementation of partial update in DPU DRM is heavily > dependent on custom properties and dsi hooks. Removing the > support for now. We may need to revisit the support in the > future. > > changes since v1: > - get away with unwanted parameter validation > - code style fixes > - remove header file definitions for partial update > > changes since v2: > - remove compilation flag for DPU_AD4. > > Signed-off-by: Jeykumar Sankaran <jsanka@xxxxxxxxxxxxxx> Thanks for the revised patches. I've applied them to both for-next and mtp-testing staging branches. I had some trouble applying this patch cleanly, I resolved the conflicts for this one, but probably a good idea to update your local branch. Sean > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c | 139 +------ > drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h | 7 +- > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 544 +------------------------- > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 18 - > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 277 ++++--------- > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 8 - > drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c | 42 -- > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 13 - > drivers/gpu/drm/msm/msm_drv.h | 56 --- > 9 files changed, 87 insertions(+), 1017 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c > index 57b8627..c5e6c53 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c > @@ -424,8 +424,7 @@ int dpu_connector_pre_kickoff(struct drm_connector *connector) > { > struct dpu_connector *c_conn; > struct dpu_connector_state *c_state; > - struct msm_display_kickoff_params params; > - int idx, rc; > + int idx, rc = 0; > > if (!connector) { > DPU_ERROR("invalid argument\n"); > @@ -462,15 +461,8 @@ int dpu_connector_pre_kickoff(struct drm_connector *connector) > } > } > > - if (!c_conn->ops.pre_kickoff) > - return 0; > - > - params.rois = &c_state->rois; > - > DPU_EVT32_VERBOSE(connector->base.id); > > - rc = c_conn->ops.pre_kickoff(connector, c_conn->display, ¶ms); > - > return rc; > } > > @@ -645,122 +637,6 @@ static void dpu_connector_atomic_reset(struct drm_connector *connector) > return &c_state->base; > } > > -static int _dpu_connector_roi_v1_check_roi( > - struct dpu_connector *c_conn, > - struct drm_clip_rect *roi_conn, > - const struct msm_roi_caps *caps) > -{ > - const struct msm_roi_alignment *align = &caps->align; > - int w = roi_conn->x2 - roi_conn->x1; > - int h = roi_conn->y2 - roi_conn->y1; > - > - if (w <= 0 || h <= 0) { > - DPU_ERROR_CONN(c_conn, "invalid conn roi w %d h %d\n", w, h); > - return -EINVAL; > - } > - > - if (w < align->min_width || w % align->width_pix_align) { > - DPU_ERROR_CONN(c_conn, > - "invalid conn roi width %d min %d align %d\n", > - w, align->min_width, align->width_pix_align); > - return -EINVAL; > - } > - > - if (h < align->min_height || h % align->height_pix_align) { > - DPU_ERROR_CONN(c_conn, > - "invalid conn roi height %d min %d align %d\n", > - h, align->min_height, align->height_pix_align); > - return -EINVAL; > - } > - > - if (roi_conn->x1 % align->xstart_pix_align) { > - DPU_ERROR_CONN(c_conn, "invalid conn roi x1 %d align %d\n", > - roi_conn->x1, align->xstart_pix_align); > - return -EINVAL; > - } > - > - if (roi_conn->y1 % align->ystart_pix_align) { > - DPU_ERROR_CONN(c_conn, "invalid conn roi y1 %d align %d\n", > - roi_conn->y1, align->ystart_pix_align); > - return -EINVAL; > - } > - > - return 0; > -} > - > -static int _dpu_connector_set_roi_v1( > - struct dpu_connector *c_conn, > - struct dpu_connector_state *c_state, > - void *usr_ptr) > -{ > - struct dpu_drm_roi_v1 roi_v1; > - struct msm_display_info display_info; > - struct msm_roi_caps *caps; > - int i, rc; > - > - if (!c_conn || !c_state) { > - DPU_ERROR("invalid args\n"); > - return -EINVAL; > - } > - > - rc = dpu_connector_get_info(&c_conn->base, &display_info); > - if (rc) { > - DPU_ERROR_CONN(c_conn, "display get info error: %d\n", rc); > - return rc; > - } > - > - caps = &display_info.roi_caps; > - if (!caps->enabled) { > - DPU_ERROR_CONN(c_conn, "display roi capability is disabled\n"); > - return -ENOTSUPP; > - } > - > - memset(&c_state->rois, 0, sizeof(c_state->rois)); > - > - if (!usr_ptr) { > - DPU_DEBUG_CONN(c_conn, "rois cleared\n"); > - return 0; > - } > - > - if (copy_from_user(&roi_v1, usr_ptr, sizeof(roi_v1))) { > - DPU_ERROR_CONN(c_conn, "failed to copy roi_v1 data\n"); > - return -EINVAL; > - } > - > - DPU_DEBUG_CONN(c_conn, "num_rects %d\n", roi_v1.num_rects); > - > - if (roi_v1.num_rects == 0) { > - DPU_DEBUG_CONN(c_conn, "rois cleared\n"); > - return 0; > - } > - > - if (roi_v1.num_rects > DPU_MAX_ROI_V1 || > - roi_v1.num_rects > caps->num_roi) { > - DPU_ERROR_CONN(c_conn, "too many rects specified: %d\n", > - roi_v1.num_rects); > - return -EINVAL; > - } > - > - c_state->rois.num_rects = roi_v1.num_rects; > - for (i = 0; i < roi_v1.num_rects; ++i) { > - int rc; > - > - rc = _dpu_connector_roi_v1_check_roi(c_conn, &roi_v1.roi[i], > - caps); > - if (rc) > - return rc; > - > - c_state->rois.roi[i] = roi_v1.roi[i]; > - DPU_DEBUG_CONN(c_conn, "roi%d: roi (%d,%d) (%d,%d)\n", i, > - c_state->rois.roi[i].x1, > - c_state->rois.roi[i].y1, > - c_state->rois.roi[i].x2, > - c_state->rois.roi[i].y2); > - } > - > - return 0; > -} > - > static int _dpu_connector_update_bl_scale(struct dpu_connector *c_conn, > int idx, > uint64_t value) > @@ -852,12 +728,6 @@ static int dpu_connector_atomic_set_property(struct drm_connector *connector, > break; > } > > - if (idx == CONNECTOR_PROP_ROI_V1) { > - rc = _dpu_connector_set_roi_v1(c_conn, c_state, (void *)val); > - if (rc) > - DPU_ERROR_CONN(c_conn, "invalid roi_v1, rc: %d\n", rc); > - } > - > /* check for custom property handling */ > if (!rc && c_conn->ops.set_property) { > rc = c_conn->ops.set_property(connector, > @@ -1304,13 +1174,6 @@ struct drm_connector *dpu_connector_init(struct drm_device *dev, > CONNECTOR_PROP_AD_BL_SCALE); > #endif > > - rc = dpu_connector_get_info(&c_conn->base, &display_info); > - if (!rc && display_info.roi_caps.enabled) { > - msm_property_install_volatile_range( > - &c_conn->property_info, "dpu_drm_roi_v1", 0x0, > - 0, ~0, 0, CONNECTOR_PROP_ROI_V1); > - } > - > msm_property_install_range(&c_conn->property_info, "RETIRE_FENCE", > 0x0, 0, INR_OPEN_MAX, 0, CONNECTOR_PROP_RETIRE_FENCE); > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h > index 573a0c8..981f459 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_connector.h > @@ -163,13 +163,10 @@ struct dpu_connector_ops { > * pre_kickoff - trigger display to program kickoff-time features > * @connector: Pointer to drm connector structure > * @display: Pointer to private display structure > - * @params: Parameter bundle of connector-stored information for > - * kickoff-time programming into the display > * Returns: Zero on success > */ > int (*pre_kickoff)(struct drm_connector *connector, > - void *display, > - struct msm_display_kickoff_params *params); > + void *display); > > /** > * clk_ctrl - perform clk enable/disable on the connector > @@ -340,7 +337,6 @@ struct dpu_connector { > * @out_fb: Pointer to output frame buffer, if applicable > * @property_state: Local storage for msm_prop properties > * @property_values: Local cache of current connector property values > - * @rois: Regions of interest structure for mapping CRTC to Connector output > * @property_blobs: blob properties > */ > struct dpu_connector_state { > @@ -349,7 +345,6 @@ struct dpu_connector_state { > struct msm_property_state property_state; > struct msm_property_value property_values[CONNECTOR_PROP_COUNT]; > > - struct msm_roi_list rois; > struct drm_property_blob *property_blobs[CONNECTOR_PROP_BLOBCOUNT]; > }; > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > index 3cdf1e3..ab36578 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > @@ -782,465 +782,24 @@ static void _dpu_crtc_setup_dim_layer_cfg(struct drm_crtc *crtc, > } > } > > -void dpu_crtc_get_crtc_roi(struct drm_crtc_state *state, > - const struct dpu_rect **crtc_roi) > -{ > - struct dpu_crtc_state *crtc_state; > - > - if (!state || !crtc_roi) > - return; > - > - crtc_state = to_dpu_crtc_state(state); > - *crtc_roi = &crtc_state->crtc_roi; > -} > - > -static int _dpu_crtc_set_roi_v1(struct drm_crtc_state *state, > - void __user *usr_ptr) > -{ > - struct drm_crtc *crtc; > - struct dpu_crtc_state *cstate; > - struct dpu_drm_roi_v1 roi_v1; > - int i; > - > - if (!state) { > - DPU_ERROR("invalid args\n"); > - return -EINVAL; > - } > - > - cstate = to_dpu_crtc_state(state); > - crtc = cstate->base.crtc; > - > - memset(&cstate->user_roi_list, 0, sizeof(cstate->user_roi_list)); > - > - if (!usr_ptr) { > - DPU_DEBUG("crtc%d: rois cleared\n", DRMID(crtc)); > - return 0; > - } > - > - if (copy_from_user(&roi_v1, usr_ptr, sizeof(roi_v1))) { > - DPU_ERROR("crtc%d: failed to copy roi_v1 data\n", DRMID(crtc)); > - return -EINVAL; > - } > - > - DPU_DEBUG("crtc%d: num_rects %d\n", DRMID(crtc), roi_v1.num_rects); > - > - if (roi_v1.num_rects == 0) { > - DPU_DEBUG("crtc%d: rois cleared\n", DRMID(crtc)); > - return 0; > - } > - > - if (roi_v1.num_rects > DPU_MAX_ROI_V1) { > - DPU_ERROR("crtc%d: too many rects specified: %d\n", DRMID(crtc), > - roi_v1.num_rects); > - return -EINVAL; > - } > - > - cstate->user_roi_list.num_rects = roi_v1.num_rects; > - for (i = 0; i < roi_v1.num_rects; ++i) { > - cstate->user_roi_list.roi[i] = roi_v1.roi[i]; > - DPU_DEBUG("crtc%d: roi%d: roi (%d,%d) (%d,%d)\n", > - DRMID(crtc), i, > - cstate->user_roi_list.roi[i].x1, > - cstate->user_roi_list.roi[i].y1, > - cstate->user_roi_list.roi[i].x2, > - cstate->user_roi_list.roi[i].y2); > - } > - > - return 0; > -} > - > -static bool _dpu_crtc_setup_is_3dmux_dsc(struct drm_crtc_state *state) > -{ > - int i; > - struct dpu_crtc_state *cstate; > - bool is_3dmux_dsc = false; > - > - cstate = to_dpu_crtc_state(state); > - > - for (i = 0; i < cstate->num_connectors; i++) { > - struct drm_connector *conn = cstate->connectors[i]; > - > - if (dpu_connector_get_topology_name(conn) == > - DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC) > - is_3dmux_dsc = true; > - } > - > - return is_3dmux_dsc; > -} > - > -static int _dpu_crtc_set_crtc_roi(struct drm_crtc *crtc, > - struct drm_crtc_state *state) > -{ > - struct drm_connector *conn; > - struct drm_connector_state *conn_state; > - struct dpu_crtc *dpu_crtc; > - struct dpu_crtc_state *crtc_state; > - struct dpu_rect *crtc_roi; > - int i, num_attached_conns = 0; > - > - if (!crtc || !state) > - return -EINVAL; > - > - dpu_crtc = to_dpu_crtc(crtc); > - crtc_state = to_dpu_crtc_state(state); > - crtc_roi = &crtc_state->crtc_roi; > - > - for_each_old_connector_in_state(state->state, conn, conn_state, i) { > - struct dpu_connector_state *dpu_conn_state; > - > - if (!conn_state || conn_state->crtc != crtc) > - continue; > - > - if (num_attached_conns) { > - DPU_ERROR( > - "crtc%d: unsupported: roi on crtc w/ >1 connectors\n", > - DRMID(crtc)); > - return -EINVAL; > - } > - ++num_attached_conns; > - > - dpu_conn_state = to_dpu_connector_state(conn_state); > - > - /* > - * current driver only supports same connector and crtc size, > - * but if support for different sizes is added, driver needs > - * to check the connector roi here to make sure is full screen > - * for dsc 3d-mux topology that doesn't support partial update. > - */ > - if (memcmp(&dpu_conn_state->rois, &crtc_state->user_roi_list, > - sizeof(crtc_state->user_roi_list))) { > - DPU_ERROR("%s: crtc -> conn roi scaling unsupported\n", > - dpu_crtc->name); > - return -EINVAL; > - } > - } > - > - dpu_kms_rect_merge_rectangles(&crtc_state->user_roi_list, crtc_roi); > - > - DPU_DEBUG("%s: crtc roi (%d,%d,%d,%d)\n", dpu_crtc->name, > - crtc_roi->x, crtc_roi->y, crtc_roi->w, crtc_roi->h); > - > - return 0; > -} > - > -static int _dpu_crtc_check_autorefresh(struct drm_crtc *crtc, > - struct drm_crtc_state *state) > -{ > - struct dpu_crtc *dpu_crtc; > - struct dpu_crtc_state *crtc_state; > - struct drm_connector *conn; > - struct drm_connector_state *conn_state; > - int i; > - > - if (!crtc || !state) > - return -EINVAL; > - > - dpu_crtc = to_dpu_crtc(crtc); > - crtc_state = to_dpu_crtc_state(state); > - > - if (dpu_kms_rect_is_null(&crtc_state->crtc_roi)) > - return 0; > - > - /* partial update active, check if autorefresh is also requested */ > - for_each_old_connector_in_state(state->state, conn, conn_state, i) { > - uint64_t autorefresh; > - > - if (!conn_state || conn_state->crtc != crtc) > - continue; > - > - autorefresh = dpu_connector_get_property(conn_state, > - CONNECTOR_PROP_AUTOREFRESH); > - if (autorefresh) { > - DPU_ERROR( > - "%s: autorefresh & partial crtc roi incompatible %llu\n", > - dpu_crtc->name, autorefresh); > - return -EINVAL; > - } > - } > - > - return 0; > -} > - > -static int _dpu_crtc_set_lm_roi(struct drm_crtc *crtc, > - struct drm_crtc_state *state, int lm_idx) > -{ > - struct dpu_crtc *dpu_crtc; > - struct dpu_crtc_state *crtc_state; > - const struct dpu_rect *crtc_roi; > - const struct dpu_rect *lm_bounds; > - struct dpu_rect *lm_roi; > - > - if (!crtc || !state || lm_idx >= ARRAY_SIZE(crtc_state->lm_bounds)) > - return -EINVAL; > - > - dpu_crtc = to_dpu_crtc(crtc); > - crtc_state = to_dpu_crtc_state(state); > - crtc_roi = &crtc_state->crtc_roi; > - lm_bounds = &crtc_state->lm_bounds[lm_idx]; > - lm_roi = &crtc_state->lm_roi[lm_idx]; > - > - if (dpu_kms_rect_is_null(crtc_roi)) > - memcpy(lm_roi, lm_bounds, sizeof(*lm_roi)); > - else > - dpu_kms_rect_intersect(crtc_roi, lm_bounds, lm_roi); > - > - DPU_DEBUG("%s: lm%d roi (%d,%d,%d,%d)\n", dpu_crtc->name, lm_idx, > - lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h); > - > - /* > - * partial update is not supported with 3dmux dsc or dest scaler. > - * hence, crtc roi must match the mixer dimensions. > - */ > - if (crtc_state->num_ds_enabled || > - _dpu_crtc_setup_is_3dmux_dsc(state)) { > - if (memcmp(lm_roi, lm_bounds, sizeof(struct dpu_rect))) { > - DPU_ERROR("Unsupported: Dest scaler/3d mux DSC + PU\n"); > - return -EINVAL; > - } > - } > - > - /* if any dimension is zero, clear all dimensions for clarity */ > - if (dpu_kms_rect_is_null(lm_roi)) > - memset(lm_roi, 0, sizeof(*lm_roi)); > - > - return 0; > -} > - > -static u32 _dpu_crtc_get_displays_affected(struct drm_crtc *crtc, > - struct drm_crtc_state *state) > -{ > - struct dpu_crtc *dpu_crtc; > - struct dpu_crtc_state *crtc_state; > - u32 disp_bitmask = 0; > - int i; > - > - dpu_crtc = to_dpu_crtc(crtc); > - crtc_state = to_dpu_crtc_state(state); > - > - /* pingpong split: one ROI, one LM, two physical displays */ > - if (crtc_state->is_ppsplit) { > - u32 lm_split_width = crtc_state->lm_bounds[0].w / 2; > - struct dpu_rect *roi = &crtc_state->lm_roi[0]; > - > - if (dpu_kms_rect_is_null(roi)) > - disp_bitmask = 0; > - else if ((u32)roi->x + (u32)roi->w <= lm_split_width) > - disp_bitmask = BIT(0); /* left only */ > - else if (roi->x >= lm_split_width) > - disp_bitmask = BIT(1); /* right only */ > - else > - disp_bitmask = BIT(0) | BIT(1); /* left and right */ > - } else { > - for (i = 0; i < dpu_crtc->num_mixers; i++) { > - if (!dpu_kms_rect_is_null(&crtc_state->lm_roi[i])) > - disp_bitmask |= BIT(i); > - } > - } > - > - DPU_DEBUG("affected displays 0x%x\n", disp_bitmask); > - > - return disp_bitmask; > -} > - > -static int _dpu_crtc_check_rois_centered_and_symmetric(struct drm_crtc *crtc, > - struct drm_crtc_state *state) > -{ > - struct dpu_crtc *dpu_crtc; > - struct dpu_crtc_state *crtc_state; > - const struct dpu_rect *roi[CRTC_DUAL_MIXERS]; > - > - if (!crtc || !state) > - return -EINVAL; > - > - dpu_crtc = to_dpu_crtc(crtc); > - crtc_state = to_dpu_crtc_state(state); > - > - if (dpu_crtc->num_mixers > CRTC_DUAL_MIXERS) { > - DPU_ERROR("%s: unsupported number of mixers: %d\n", > - dpu_crtc->name, dpu_crtc->num_mixers); > - return -EINVAL; > - } > - > - /* > - * If using pingpong split: one ROI, one LM, two physical displays > - * then the ROI must be centered on the panel split boundary and > - * be of equal width across the split. > - */ > - if (crtc_state->is_ppsplit) { > - u16 panel_split_width; > - u32 display_mask; > - > - roi[0] = &crtc_state->lm_roi[0]; > - > - if (dpu_kms_rect_is_null(roi[0])) > - return 0; > - > - display_mask = _dpu_crtc_get_displays_affected(crtc, state); > - if (display_mask != (BIT(0) | BIT(1))) > - return 0; > - > - panel_split_width = crtc_state->lm_bounds[0].w / 2; > - if (roi[0]->x + roi[0]->w / 2 != panel_split_width) { > - DPU_ERROR("%s: roi x %d w %d split %d\n", > - dpu_crtc->name, roi[0]->x, roi[0]->w, > - panel_split_width); > - return -EINVAL; > - } > - > - return 0; > - } > - > - /* > - * On certain HW, if using 2 LM, ROIs must be split evenly between the > - * LMs and be of equal width. > - */ > - if (dpu_crtc->num_mixers < 2) > - return 0; > - > - roi[0] = &crtc_state->lm_roi[0]; > - roi[1] = &crtc_state->lm_roi[1]; > - > - /* if one of the roi is null it's a left/right-only update */ > - if (dpu_kms_rect_is_null(roi[0]) || dpu_kms_rect_is_null(roi[1])) > - return 0; > - > - /* check lm rois are equal width & first roi ends at 2nd roi */ > - if (roi[0]->x + roi[0]->w != roi[1]->x || roi[0]->w != roi[1]->w) { > - DPU_ERROR( > - "%s: rois not centered and symmetric: roi0 x %d w %d roi1 x %d w %d\n", > - dpu_crtc->name, roi[0]->x, roi[0]->w, > - roi[1]->x, roi[1]->w); > - return -EINVAL; > - } > - > - return 0; > -} > - > -static int _dpu_crtc_check_planes_within_crtc_roi(struct drm_crtc *crtc, > - struct drm_crtc_state *state) > -{ > - struct dpu_crtc *dpu_crtc; > - struct dpu_crtc_state *crtc_state; > - const struct dpu_rect *crtc_roi; > - struct drm_plane_state *pstate; > - struct drm_plane *plane; > - > - if (!crtc || !state) > - return -EINVAL; > - > - /* > - * Reject commit if a Plane CRTC destination coordinates fall outside > - * the partial CRTC ROI. LM output is determined via connector ROIs, > - * if they are specified, not Plane CRTC ROIs. > - */ > - > - dpu_crtc = to_dpu_crtc(crtc); > - crtc_state = to_dpu_crtc_state(state); > - crtc_roi = &crtc_state->crtc_roi; > - > - if (dpu_kms_rect_is_null(crtc_roi)) > - return 0; > - > - drm_atomic_crtc_state_for_each_plane(plane, state) { > - struct dpu_rect plane_roi, intersection; > - > - pstate = drm_atomic_get_plane_state(state->state, plane); > - if (IS_ERR_OR_NULL(pstate)) { > - int rc = PTR_ERR(pstate); > - > - DPU_ERROR("%s: failed to get plane%d state, %d\n", > - dpu_crtc->name, plane->base.id, rc); > - return rc; > - } > - > - plane_roi.x = pstate->crtc_x; > - plane_roi.y = pstate->crtc_y; > - plane_roi.w = pstate->crtc_w; > - plane_roi.h = pstate->crtc_h; > - dpu_kms_rect_intersect(crtc_roi, &plane_roi, &intersection); > - if (!dpu_kms_rect_is_equal(&plane_roi, &intersection)) { > - DPU_ERROR( > - "%s: plane%d crtc roi (%d,%d,%d,%d) outside crtc roi (%d,%d,%d,%d)\n", > - dpu_crtc->name, plane->base.id, > - plane_roi.x, plane_roi.y, > - plane_roi.w, plane_roi.h, > - crtc_roi->x, crtc_roi->y, > - crtc_roi->w, crtc_roi->h); > - return -E2BIG; > - } > - } > - > - return 0; > -} > - > -static int _dpu_crtc_check_rois(struct drm_crtc *crtc, > - struct drm_crtc_state *state) > -{ > - struct dpu_crtc *dpu_crtc; > - int lm_idx; > - int rc; > - > - if (!crtc || !state) > - return -EINVAL; > - > - dpu_crtc = to_dpu_crtc(crtc); > - > - rc = _dpu_crtc_set_crtc_roi(crtc, state); > - if (rc) > - return rc; > - > - rc = _dpu_crtc_check_autorefresh(crtc, state); > - if (rc) > - return rc; > - > - for (lm_idx = 0; lm_idx < dpu_crtc->num_mixers; lm_idx++) { > - rc = _dpu_crtc_set_lm_roi(crtc, state, lm_idx); > - if (rc) > - return rc; > - } > - > - rc = _dpu_crtc_check_rois_centered_and_symmetric(crtc, state); > - if (rc) > - return rc; > - > - rc = _dpu_crtc_check_planes_within_crtc_roi(crtc, state); > - if (rc) > - return rc; > - > - return 0; > -} > - > static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc) > { > struct dpu_crtc *dpu_crtc; > struct dpu_crtc_state *crtc_state; > - const struct dpu_rect *lm_roi; > - struct dpu_hw_mixer *hw_lm; > int lm_idx, lm_horiz_position; > > - if (!crtc) > - return; > - > dpu_crtc = to_dpu_crtc(crtc); > crtc_state = to_dpu_crtc_state(crtc->state); > > lm_horiz_position = 0; > for (lm_idx = 0; lm_idx < dpu_crtc->num_mixers; lm_idx++) { > + const struct dpu_rect *lm_roi = &crtc_state->lm_bounds[lm_idx]; > + struct dpu_hw_mixer *hw_lm = dpu_crtc->mixers[lm_idx].hw_lm; > struct dpu_hw_mixer_cfg cfg; > > - lm_roi = &crtc_state->lm_roi[lm_idx]; > - hw_lm = dpu_crtc->mixers[lm_idx].hw_lm; > - > - DPU_EVT32(DRMID(crtc_state->base.crtc), lm_idx, > - lm_roi->x, lm_roi->y, lm_roi->w, lm_roi->h); > - > if (dpu_kms_rect_is_null(lm_roi)) > continue; > > - hw_lm->cfg.out_width = lm_roi->w; > - hw_lm->cfg.out_height = lm_roi->h; > - hw_lm->cfg.right_mixer = lm_horiz_position; > - > cfg.out_width = lm_roi->w; > cfg.out_height = lm_roi->h; > cfg.right_mixer = lm_horiz_position++; > @@ -1361,70 +920,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, > mixer, &cstate->dim_layer[i]); > } > > - _dpu_crtc_program_lm_output_roi(crtc); > -} > - > -static void _dpu_crtc_swap_mixers_for_right_partial_update( > - struct drm_crtc *crtc) > -{ > - struct dpu_crtc *dpu_crtc; > - struct dpu_crtc_state *cstate; > - struct drm_encoder *drm_enc; > - bool is_right_only; > - bool encoder_in_dsc_merge = false; > - > - if (!crtc || !crtc->state) > - return; > - > - dpu_crtc = to_dpu_crtc(crtc); > - cstate = to_dpu_crtc_state(crtc->state); > - > - if (dpu_crtc->num_mixers != CRTC_DUAL_MIXERS) > - return; > - > - drm_for_each_encoder(drm_enc, crtc->dev) { > - if (drm_enc->crtc == crtc && > - dpu_encoder_is_dsc_merge(drm_enc)) { > - encoder_in_dsc_merge = true; > - break; > - } > - } > - > - /** > - * For right-only partial update with DSC merge, we swap LM0 & LM1. > - * This is due to two reasons: > - * - On 8996, there is a DSC HW requirement that in DSC Merge Mode, > - * the left DSC must be used, right DSC cannot be used alone. > - * For right-only partial update, this means swap layer mixers to map > - * Left LM to Right INTF. On later HW this was relaxed. > - * - In DSC Merge mode, the physical encoder has already registered > - * PP0 as the master, to switch to right-only we would have to > - * reprogram to be driven by PP1 instead. > - * To support both cases, we prefer to support the mixer swap solution. > - */ > - if (!encoder_in_dsc_merge) > - return; > - > - is_right_only = dpu_kms_rect_is_null(&cstate->lm_roi[0]) && > - !dpu_kms_rect_is_null(&cstate->lm_roi[1]); > - > - if (is_right_only && !dpu_crtc->mixers_swapped) { > - /* right-only update swap mixers */ > - swap(dpu_crtc->mixers[0], dpu_crtc->mixers[1]); > - dpu_crtc->mixers_swapped = true; > - } else if (!is_right_only && dpu_crtc->mixers_swapped) { > - /* left-only or full update, swap back */ > - swap(dpu_crtc->mixers[0], dpu_crtc->mixers[1]); > - dpu_crtc->mixers_swapped = false; > - } > - > - DPU_DEBUG("%s: right_only %d swapped %d, mix0->lm%d, mix1->lm%d\n", > - dpu_crtc->name, is_right_only, dpu_crtc->mixers_swapped, > - dpu_crtc->mixers[0].hw_lm->idx - LM_0, > - dpu_crtc->mixers[1].hw_lm->idx - LM_0); > - DPU_EVT32(DRMID(crtc), is_right_only, dpu_crtc->mixers_swapped, > - dpu_crtc->mixers[0].hw_lm->idx - LM_0, > - dpu_crtc->mixers[1].hw_lm->idx - LM_0); > + _dpu_crtc_program_lm_output_roi(crtc); > } > > /** > @@ -1472,27 +968,15 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) > lm->ops.clear_dim_layer(lm); > } > > - _dpu_crtc_swap_mixers_for_right_partial_update(crtc); > - > /* initialize stage cfg */ > memset(&dpu_crtc->stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg)); > > _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer); > > for (i = 0; i < dpu_crtc->num_mixers; i++) { > - const struct dpu_rect *lm_roi = &dpu_crtc_state->lm_roi[i]; > - > ctl = mixer[i].hw_ctl; > lm = mixer[i].hw_lm; > > - if (dpu_kms_rect_is_null(lm_roi)) { > - DPU_DEBUG( > - "%s: lm%d leave ctl%d mask 0 since null roi\n", > - dpu_crtc->name, lm->idx - LM_0, > - ctl->idx - CTL_0); > - continue; > - } > - > lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode); > > mixer[i].flush_mask |= ctl->ops.get_bitmask_mixer(ctl, > @@ -1510,8 +994,6 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) > ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, > &dpu_crtc->stage_cfg); > } > - > - _dpu_crtc_program_lm_output_roi(crtc); > } > > /** > @@ -2664,14 +2146,9 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, > cstate->lm_bounds[i].w = crtc_split_width; > cstate->lm_bounds[i].h = > dpu_crtc_get_mixer_height(dpu_crtc, cstate, adj_mode); > - memcpy(&cstate->lm_roi[i], &cstate->lm_bounds[i], > - sizeof(cstate->lm_roi[i])); > DPU_EVT32_VERBOSE(DRMID(crtc), i, > cstate->lm_bounds[i].x, cstate->lm_bounds[i].y, > cstate->lm_bounds[i].w, cstate->lm_bounds[i].h); > - DPU_DEBUG("%s: lm%d bnd&roi (%d,%d,%d,%d)\n", dpu_crtc->name, i, > - cstate->lm_roi[i].x, cstate->lm_roi[i].y, > - cstate->lm_roi[i].w, cstate->lm_roi[i].h); > } > > drm_mode_debug_printmodeline(adj_mode); > @@ -3019,8 +2496,6 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) > * If so, it may delay and flush at an irq event (e.g. ppdone) > */ > params.inline_rotate_prefill = cstate->sbuf_prefill_line; > - params.affected_displays = _dpu_crtc_get_displays_affected(crtc, > - crtc->state); > dpu_encoder_prepare_for_kickoff(encoder, ¶ms); > > /* > @@ -3931,12 +3406,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, > } > } > > - rc = _dpu_crtc_check_rois(crtc, state); > - if (rc) { > - DPU_ERROR("crtc%d failed roi check %d\n", crtc->base.id, rc); > - goto end; > - } > - > end: > _dpu_crtc_rp_free_unused(&cstate->rp); > return rc; > @@ -4066,9 +3535,6 @@ static void dpu_crtc_install_properties(struct drm_crtc *crtc, > msm_property_install_blob(&dpu_crtc->property_info, "capabilities", > DRM_MODE_PROP_IMMUTABLE, CRTC_PROP_INFO); > > - msm_property_install_volatile_range(&dpu_crtc->property_info, > - "dpu_drm_roi_v1", 0x0, 0, ~0, 0, CRTC_PROP_ROI_V1); > - > dpu_kms_info_reset(info); > > if (catalog->has_dim_layer) { > @@ -4217,10 +3683,6 @@ static int dpu_crtc_atomic_set_property(struct drm_crtc *crtc, > _dpu_crtc_set_dim_layer_v1(cstate, > (void __user *)val); > break; > - case CRTC_PROP_ROI_V1: > - ret = _dpu_crtc_set_roi_v1(state, > - (void __user *)val); > - break; > case CRTC_PROP_DEST_SCALER: > ret = _dpu_crtc_set_dest_scaler(dpu_crtc, > cstate, (void __user *)val); > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h > index b63df24..15e3eb6 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h > @@ -345,13 +345,8 @@ struct dpu_crtc_respool { > * @is_ppsplit : Whether current topology requires PPSplit special handling > * @bw_control : true if bw/clk controlled by core bw/clk properties > * @bw_split_vote : true if bw controlled by llcc/dram bw properties > - * @crtc_roi : Current CRTC ROI. Possibly sub-rectangle of mode. > - * Origin top left of CRTC. > * @lm_bounds : LM boundaries based on current mode full resolution, no ROI. > * Origin top left of CRTC. > - * @lm_roi : Current LM ROI, possibly sub-rectangle of mode. > - * Origin top left of CRTC. > - * @user_roi_list : List of user's requested ROIs as from set property > * @property_state: Local storage for msm_prop properties > * @property_values: Current crtc property values > * @input_fence_timeout_ns : Cached input fence timeout, in ns > @@ -376,10 +371,7 @@ struct dpu_crtc_state { > bool bw_split_vote; > > bool is_ppsplit; > - struct dpu_rect crtc_roi; > struct dpu_rect lm_bounds[CRTC_DUAL_MIXERS]; > - struct dpu_rect lm_roi[CRTC_DUAL_MIXERS]; > - struct msm_roi_list user_roi_list; > > struct msm_property_state property_state; > struct msm_property_value property_values[CRTC_PROP_COUNT]; > @@ -605,14 +597,4 @@ int dpu_crtc_res_add(struct drm_crtc_state *state, u32 type, u64 tag, > */ > void dpu_crtc_res_put(struct drm_crtc_state *state, u32 type, u64 tag); > > -/** > - * dpu_crtc_get_crtc_roi - retrieve the crtc_roi from the given state object > - * used to allow the planes to adjust their final lm out_xy value in the > - * case of partial update > - * @crtc_state: Pointer to crtc state > - * @crtc_roi: Output pointer to crtc roi in the given state > - */ > -void dpu_crtc_get_crtc_roi(struct drm_crtc_state *state, > - const struct dpu_rect **crtc_roi); > - > #endif /* _DPU_CRTC_H_ */ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index 3d168fa0..91b9e07 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -195,8 +195,6 @@ enum dpu_enc_rc_states { > * @topology: topology of the display > * @mode_set_complete: flag to indicate modeset completion > * @rsc_config: rsc configuration for display vtotal, fps, etc. > - * @cur_conn_roi: current connector roi > - * @prv_conn_roi: previous connector roi to optimize if unchanged > * @idle_timeout: idle timeout duration in milliseconds > */ > struct dpu_encoder_virt { > @@ -243,8 +241,6 @@ struct dpu_encoder_virt { > bool mode_set_complete; > > struct dpu_rsc_cmd_config rsc_config; > - struct dpu_rect cur_conn_roi; > - struct dpu_rect prv_conn_roi; > > u32 idle_timeout; > }; > @@ -868,14 +864,8 @@ static bool _dpu_encoder_dsc_ich_reset_override_needed(bool pu_en, > > static void _dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, > struct dpu_hw_pingpong *hw_pp, struct msm_display_dsc_info *dsc, > - u32 common_mode, bool ich_reset, bool enable) > + u32 common_mode, bool ich_reset) > { > - if (!enable) { > - if (hw_pp->ops.disable_dsc) > - hw_pp->ops.disable_dsc(hw_pp); > - return; > - } > - > if (hw_dsc->ops.dsc_config) > hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, ich_reset); > > @@ -889,46 +879,27 @@ static void _dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, > hw_pp->ops.enable_dsc(hw_pp); > } > > -static void _dpu_encoder_get_connector_roi( > - struct dpu_encoder_virt *dpu_enc, > - struct dpu_rect *merged_conn_roi) > -{ > - struct drm_connector *drm_conn; > - struct dpu_connector_state *c_state; > - > - if (!dpu_enc || !merged_conn_roi) > - return; > - > - drm_conn = dpu_enc->phys_encs[0]->connector; > - > - if (!drm_conn || !drm_conn->state) > - return; > - > - c_state = to_dpu_connector_state(drm_conn->state); > - dpu_kms_rect_merge_rectangles(&c_state->rois, merged_conn_roi); > -} > - > static int _dpu_encoder_dsc_n_lm_1_enc_1_intf(struct dpu_encoder_virt *dpu_enc) > { > int this_frame_slices; > int intf_ip_w, enc_ip_w; > int ich_res, dsc_common_mode = 0; > + int rc = 0; > > struct dpu_hw_pingpong *hw_pp = dpu_enc->hw_pp[0]; > struct dpu_hw_dsc *hw_dsc = dpu_enc->hw_dsc[0]; > struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; > - const struct dpu_rect *roi = &dpu_enc->cur_conn_roi; > struct msm_display_dsc_info *dsc = > &dpu_enc->mode_info.comp_info.dsc_info; > > - if (dsc == NULL || hw_dsc == NULL || hw_pp == NULL || !enc_master) { > - DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n"); > - return -EINVAL; > + rc = _dpu_encoder_dsc_update_pic_dim(dsc, dsc->pic_width, > + dsc->pic_height); > + if (rc) { > + DPU_ERROR_ENC(dpu_enc, "failed to update DSC pic dim\n"); > + return rc; > } > > - _dpu_encoder_dsc_update_pic_dim(dsc, roi->w, roi->h); > - > - this_frame_slices = roi->w / dsc->slice_width; > + this_frame_slices = dsc->pic_width / dsc->slice_width; > intf_ip_w = this_frame_slices * dsc->slice_width; > _dpu_encoder_dsc_pclk_param_calc(dsc, intf_ip_w); > > @@ -941,205 +912,126 @@ static int _dpu_encoder_dsc_n_lm_1_enc_1_intf(struct dpu_encoder_virt *dpu_enc) > dsc_common_mode = DSC_MODE_VIDEO; > > DPU_DEBUG_ENC(dpu_enc, "pic_w: %d pic_h: %d mode:%d\n", > - roi->w, roi->h, dsc_common_mode); > - DPU_EVT32(DRMID(&dpu_enc->base), roi->w, roi->h, dsc_common_mode); > + dsc->pic_width, dsc->pic_height, dsc_common_mode); > + DPU_EVT32(DRMID(&dpu_enc->base), dsc->pic_width, dsc->pic_height, > + dsc_common_mode); > > _dpu_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode, > - ich_res, true); > + ich_res); > > return 0; > } > - > -static int _dpu_encoder_dsc_2_lm_2_enc_2_intf(struct dpu_encoder_virt *dpu_enc, > - struct dpu_encoder_kickoff_params *params) > +static int _dpu_encoder_dsc_2_lm_2_enc_2_intf(struct dpu_encoder_virt *dpu_enc) > { > int this_frame_slices; > int intf_ip_w, enc_ip_w; > int ich_res, dsc_common_mode; > + int rc = 0; > > struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; > - const struct dpu_rect *roi = &dpu_enc->cur_conn_roi; > - struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; > - struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; > - struct msm_display_dsc_info dsc[MAX_CHANNELS_PER_ENC]; > - bool half_panel_partial_update; > - int i; > - > - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { > - hw_pp[i] = dpu_enc->hw_pp[i]; > - hw_dsc[i] = dpu_enc->hw_dsc[i]; > + struct dpu_hw_dsc *l_hw_dsc = dpu_enc->hw_dsc[0]; > + struct dpu_hw_dsc *r_hw_dsc = dpu_enc->hw_dsc[1]; > + struct dpu_hw_pingpong *l_hw_pp = dpu_enc->hw_pp[0]; > + struct dpu_hw_pingpong *r_hw_pp = dpu_enc->hw_pp[1]; > + struct msm_display_dsc_info *dsc = > + &dpu_enc->mode_info.comp_info.dsc_info; > > - if (!hw_pp[i] || !hw_dsc[i]) { > - DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n"); > - return -EINVAL; > - } > + rc = _dpu_encoder_dsc_update_pic_dim(dsc, > + dsc->pic_width * dpu_enc->display_num_of_h_tiles, > + dsc->pic_height); > + if (rc) { > + DPU_ERROR_ENC(dpu_enc, "failed to update DSC pic dim\n"); > + return rc; > } > > - half_panel_partial_update = > - hweight_long(params->affected_displays) == 1; > - > - dsc_common_mode = 0; > - if (!half_panel_partial_update) > - dsc_common_mode |= DSC_MODE_SPLIT_PANEL; > - if (enc_master->intf_mode == INTF_MODE_VIDEO) > - dsc_common_mode |= DSC_MODE_VIDEO; > - > - memcpy(&dsc[0], &dpu_enc->mode_info.comp_info.dsc_info, sizeof(dsc[0])); > - memcpy(&dsc[1], &dpu_enc->mode_info.comp_info.dsc_info, sizeof(dsc[1])); > > - /* > - * Since both DSC use same pic dimension, set same pic dimension > - * to both DSC structures. > - */ > - _dpu_encoder_dsc_update_pic_dim(&dsc[0], roi->w, roi->h); > - _dpu_encoder_dsc_update_pic_dim(&dsc[1], roi->w, roi->h); > - > - this_frame_slices = roi->w / dsc[0].slice_width; > - intf_ip_w = this_frame_slices * dsc[0].slice_width; > - > - if (!half_panel_partial_update) > - intf_ip_w /= 2; > + this_frame_slices = dsc->pic_width / dsc->slice_width; > + intf_ip_w = this_frame_slices * dsc->slice_width; > > - /* > - * In this topology when both interfaces are active, they have same > - * load so intf_ip_w will be same. > - */ > - _dpu_encoder_dsc_pclk_param_calc(&dsc[0], intf_ip_w); > - _dpu_encoder_dsc_pclk_param_calc(&dsc[1], intf_ip_w); > + intf_ip_w /= 2; > + _dpu_encoder_dsc_pclk_param_calc(dsc, intf_ip_w); > > - /* > - * In this topology, since there is no dsc_merge, uncompressed input > - * to encoder and interface is same. > - */ > enc_ip_w = intf_ip_w; > - _dpu_encoder_dsc_initial_line_calc(&dsc[0], enc_ip_w); > - _dpu_encoder_dsc_initial_line_calc(&dsc[1], enc_ip_w); > + _dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); > > - /* > - * __is_ich_reset_override_needed should be called only after > - * updating pic dimension, mdss_panel_dsc_update_pic_dim. > - */ > - ich_res = _dpu_encoder_dsc_ich_reset_override_needed( > - half_panel_partial_update, &dsc[0]); > + ich_res = _dpu_encoder_dsc_ich_reset_override_needed(false, dsc); > > - DPU_DEBUG_ENC(dpu_enc, "pic_w: %d pic_h: %d mode:%d\n", > - roi->w, roi->h, dsc_common_mode); > + dsc_common_mode = DSC_MODE_SPLIT_PANEL; > + if (enc_master->intf_mode == INTF_MODE_VIDEO) > + dsc_common_mode |= DSC_MODE_VIDEO; > > - for (i = 0; i < dpu_enc->num_phys_encs; i++) { > - bool active = !!((1 << i) & params->affected_displays); > + DPU_DEBUG_ENC(dpu_enc, "pic_w: %d pic_h: %d mode:%d\n", > + dsc->pic_width, dsc->pic_height, dsc_common_mode); > + DPU_EVT32(DRMID(&dpu_enc->base), dsc->pic_width, dsc->pic_height, > + dsc_common_mode); > > - DPU_EVT32(DRMID(&dpu_enc->base), roi->w, roi->h, > - dsc_common_mode, i, active); > - _dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], &dsc[i], > - dsc_common_mode, ich_res, active); > - } > + _dpu_encoder_dsc_pipe_cfg(l_hw_dsc, l_hw_pp, dsc, dsc_common_mode, > + ich_res); > + _dpu_encoder_dsc_pipe_cfg(r_hw_dsc, r_hw_pp, dsc, dsc_common_mode, > + ich_res); > > return 0; > } > > -static int _dpu_encoder_dsc_2_lm_2_enc_1_intf(struct dpu_encoder_virt *dpu_enc, > - struct dpu_encoder_kickoff_params *params) > +static int _dpu_encoder_dsc_2_lm_2_enc_1_intf(struct dpu_encoder_virt *dpu_enc) > { > int this_frame_slices; > int intf_ip_w, enc_ip_w; > int ich_res, dsc_common_mode; > + int rc = 0; > > struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; > - const struct dpu_rect *roi = &dpu_enc->cur_conn_roi; > - struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; > - struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; > + struct dpu_hw_dsc *l_hw_dsc = dpu_enc->hw_dsc[0]; > + struct dpu_hw_dsc *r_hw_dsc = dpu_enc->hw_dsc[1]; > + struct dpu_hw_pingpong *l_hw_pp = dpu_enc->hw_pp[0]; > + struct dpu_hw_pingpong *r_hw_pp = dpu_enc->hw_pp[1]; > struct msm_display_dsc_info *dsc = > &dpu_enc->mode_info.comp_info.dsc_info; > - bool half_panel_partial_update; > - int i; > - > - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { > - hw_pp[i] = dpu_enc->hw_pp[i]; > - hw_dsc[i] = dpu_enc->hw_dsc[i]; > > - if (!hw_pp[i] || !hw_dsc[i]) { > - DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n"); > - return -EINVAL; > - } > + rc = _dpu_encoder_dsc_update_pic_dim(dsc, dsc->pic_width, > + dsc->pic_height); > + if (rc) { > + DPU_ERROR_ENC(dpu_enc, "failed to update DSC pic dim\n"); > + return rc; > } > > - half_panel_partial_update = > - hweight_long(params->affected_displays) == 1; > - > - dsc_common_mode = 0; > - if (!half_panel_partial_update) > - dsc_common_mode |= DSC_MODE_SPLIT_PANEL | DSC_MODE_MULTIPLEX; > - if (enc_master->intf_mode == INTF_MODE_VIDEO) > - dsc_common_mode |= DSC_MODE_VIDEO; > - > - _dpu_encoder_dsc_update_pic_dim(dsc, roi->w, roi->h); > - > - this_frame_slices = roi->w / dsc->slice_width; > + this_frame_slices = dsc->pic_width / dsc->slice_width; > intf_ip_w = this_frame_slices * dsc->slice_width; > _dpu_encoder_dsc_pclk_param_calc(dsc, intf_ip_w); > > /* > - * dsc merge case: when using 2 encoders for the same stream, > - * no. of slices need to be same on both the encoders. > + * when using 2 encoders for the same stream, no. of slices > + * need to be same on both the encoders. > */ > enc_ip_w = intf_ip_w / 2; > _dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); > > - ich_res = _dpu_encoder_dsc_ich_reset_override_needed( > - half_panel_partial_update, dsc); > - > - DPU_DEBUG_ENC(dpu_enc, "pic_w: %d pic_h: %d mode:%d\n", > - roi->w, roi->h, dsc_common_mode); > - DPU_EVT32(DRMID(&dpu_enc->base), roi->w, roi->h, > - dsc_common_mode, i, params->affected_displays); > - > - _dpu_encoder_dsc_pipe_cfg(hw_dsc[0], hw_pp[0], dsc, dsc_common_mode, > - ich_res, true); > - _dpu_encoder_dsc_pipe_cfg(hw_dsc[1], hw_pp[1], dsc, dsc_common_mode, > - ich_res, !half_panel_partial_update); > - > - return 0; > -} > - > -static int _dpu_encoder_update_roi(struct drm_encoder *drm_enc) > -{ > - struct dpu_encoder_virt *dpu_enc; > - struct drm_connector *drm_conn; > - struct drm_display_mode *adj_mode; > - struct dpu_rect roi; > - > - if (!drm_enc || !drm_enc->crtc || !drm_enc->crtc->state) > - return -EINVAL; > - dpu_enc = to_dpu_encoder_virt(drm_enc); > - > - if (!dpu_enc->cur_master) > - return -EINVAL; > + ich_res = _dpu_encoder_dsc_ich_reset_override_needed(false, dsc); > > - adj_mode = &dpu_enc->base.crtc->state->adjusted_mode; > - drm_conn = dpu_enc->cur_master->connector; > + dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL; > + if (enc_master->intf_mode == INTF_MODE_VIDEO) > + dsc_common_mode |= DSC_MODE_VIDEO; > > - _dpu_encoder_get_connector_roi(dpu_enc, &roi); > - if (dpu_kms_rect_is_null(&roi)) { > - roi.w = adj_mode->hdisplay; > - roi.h = adj_mode->vdisplay; > - } > + DPU_DEBUG_ENC(dpu_enc, "pic_w: %d pic_h: %d mode:%d\n", > + dsc->pic_width, dsc->pic_height, dsc_common_mode); > + DPU_EVT32(DRMID(&dpu_enc->base), dsc->pic_width, dsc->pic_height, > + dsc_common_mode); > > - memcpy(&dpu_enc->prv_conn_roi, &dpu_enc->cur_conn_roi, > - sizeof(dpu_enc->prv_conn_roi)); > - memcpy(&dpu_enc->cur_conn_roi, &roi, sizeof(dpu_enc->cur_conn_roi)); > + _dpu_encoder_dsc_pipe_cfg(l_hw_dsc, l_hw_pp, dsc, dsc_common_mode, > + ich_res); > + _dpu_encoder_dsc_pipe_cfg(r_hw_dsc, r_hw_pp, dsc, dsc_common_mode, > + ich_res); > > return 0; > } > > -static int _dpu_encoder_dsc_setup(struct dpu_encoder_virt *dpu_enc, > - struct dpu_encoder_kickoff_params *params) > +static int _dpu_encoder_dsc_setup(struct dpu_encoder_virt *dpu_enc) > { > enum dpu_rm_topology_name topology; > struct drm_connector *drm_conn; > int ret = 0; > > - if (!dpu_enc || !params || !dpu_enc->phys_encs[0] || > - !dpu_enc->phys_encs[0]->connector) > + if (!dpu_enc) > return -EINVAL; > > drm_conn = dpu_enc->phys_encs[0]->connector; > @@ -1153,20 +1045,16 @@ static int _dpu_encoder_dsc_setup(struct dpu_encoder_virt *dpu_enc, > DPU_DEBUG_ENC(dpu_enc, "topology:%d\n", topology); > DPU_EVT32(DRMID(&dpu_enc->base)); > > - if (dpu_kms_rect_is_equal(&dpu_enc->cur_conn_roi, > - &dpu_enc->prv_conn_roi)) > - return ret; > - > switch (topology) { > case DPU_RM_TOPOLOGY_SINGLEPIPE_DSC: > case DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC: > ret = _dpu_encoder_dsc_n_lm_1_enc_1_intf(dpu_enc); > break; > case DPU_RM_TOPOLOGY_DUALPIPE_DSCMERGE: > - ret = _dpu_encoder_dsc_2_lm_2_enc_1_intf(dpu_enc, params); > + ret = _dpu_encoder_dsc_2_lm_2_enc_1_intf(dpu_enc); > break; > case DPU_RM_TOPOLOGY_DUALPIPE_DSC: > - ret = _dpu_encoder_dsc_2_lm_2_enc_2_intf(dpu_enc, params); > + ret = _dpu_encoder_dsc_2_lm_2_enc_2_intf(dpu_enc); > break; > default: > DPU_ERROR_ENC(dpu_enc, "No DSC support for topology %d", > @@ -1429,7 +1317,8 @@ static int _dpu_encoder_update_rsc_client( > } > > if (crtc->base.id != wait_vblank_crtc_id) { > - primary_crtc = drm_crtc_find(drm_enc->dev, NULL, wait_vblank_crtc_id); > + primary_crtc = drm_crtc_find(drm_enc->dev, NULL, > + wait_vblank_crtc_id); > if (!primary_crtc) { > DPU_ERROR_ENC(dpu_enc, > "failed to find primary crtc id %d\n", > @@ -2073,9 +1962,6 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) > dpu_kms->catalog); > > _dpu_encoder_update_vsync_source(dpu_enc, &dpu_enc->disp_info, false); > - > - memset(&dpu_enc->prv_conn_roi, 0, sizeof(dpu_enc->prv_conn_roi)); > - memset(&dpu_enc->cur_conn_roi, 0, sizeof(dpu_enc->cur_conn_roi)); > } > > void dpu_encoder_virt_restore(struct drm_encoder *drm_enc) > @@ -2945,7 +2831,8 @@ static int _dpu_encoder_wakeup_time(struct drm_encoder *drm_enc, > > static void dpu_encoder_vsync_event_handler(struct timer_list *t) > { > - struct dpu_encoder_virt *dpu_enc = from_timer(dpu_enc, t, vsync_event_timer); > + struct dpu_encoder_virt *dpu_enc = from_timer(dpu_enc, t, > + vsync_event_timer); > struct drm_encoder *drm_enc = &dpu_enc->base; > struct msm_drm_private *priv; > struct msm_drm_thread *event_thread; > @@ -3053,8 +2940,6 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, > > _dpu_encoder_update_master(drm_enc, params); > > - _dpu_encoder_update_roi(drm_enc); > - > if (dpu_enc->cur_master && dpu_enc->cur_master->connector) { > rc = dpu_connector_pre_kickoff(dpu_enc->cur_master->connector); > if (rc) > @@ -3064,7 +2949,7 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, > } > > if (dpu_encoder_is_dsc_enabled(drm_enc)) { > - rc = _dpu_encoder_dsc_setup(dpu_enc, params); > + rc = _dpu_encoder_dsc_setup(dpu_enc); > if (rc) > DPU_ERROR_ENC(dpu_enc, "failed to setup DSC: %d\n", rc); > } > @@ -3654,7 +3539,8 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, > > static void dpu_encoder_frame_done_timeout(struct timer_list *t) > { > - struct dpu_encoder_virt *dpu_enc = from_timer(dpu_enc, t, frame_done_timer); > + struct dpu_encoder_virt *dpu_enc = from_timer(dpu_enc, t, > + frame_done_timer); > struct drm_encoder *drm_enc = &dpu_enc->base; > struct msm_drm_private *priv; > u32 event; > @@ -3726,7 +3612,8 @@ struct drm_encoder *dpu_encoder_init( > drm_encoder_helper_add(drm_enc, &dpu_encoder_helper_funcs); > > atomic_set(&dpu_enc->frame_done_timeout, 0); > - timer_setup(&dpu_enc->frame_done_timer, dpu_encoder_frame_done_timeout, 0); > + timer_setup(&dpu_enc->frame_done_timer, > + dpu_encoder_frame_done_timeout, 0); > > if ((disp_info->intf_type == DRM_MODE_CONNECTOR_DSI) && > disp_info->is_primary) > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h > index 62e7c5c..d11fb1d 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h > @@ -454,14 +454,6 @@ void dpu_kms_rect_intersect(const struct dpu_rect *r1, > struct dpu_rect *result); > > /** > - * dpu_kms_rect_merge_rectangles - merge a rectangle list into one rect > - * @rois: pointer to the list of rois > - * @result: output rectangle, all 0 on error > - */ > -void dpu_kms_rect_merge_rectangles(const struct msm_roi_list *rois, > - struct dpu_rect *result); > - > -/** > * dpu_kms_rect_is_equal - compares two rects > * @r1: rect value to compare > * @r2: rect value to compare > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c > index 006d7ad..40e0162 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c > @@ -176,45 +176,3 @@ void dpu_kms_rect_intersect(const struct dpu_rect *r1, > } > } > > -void dpu_kms_rect_merge_rectangles(const struct msm_roi_list *rois, > - struct dpu_rect *result) > -{ > - struct drm_clip_rect clip; > - const struct drm_clip_rect *roi_rect; > - int i; > - > - if (!rois || !result) > - return; > - > - memset(result, 0, sizeof(*result)); > - > - /* init to invalid range maxes */ > - clip.x1 = ~0; > - clip.y1 = ~0; > - clip.x2 = 0; > - clip.y2 = 0; > - > - /* aggregate all clipping rectangles together for overall roi */ > - for (i = 0; i < rois->num_rects; i++) { > - roi_rect = &rois->roi[i]; > - > - clip.x1 = min(clip.x1, roi_rect->x1); > - clip.y1 = min(clip.y1, roi_rect->y1); > - clip.x2 = max(clip.x2, roi_rect->x2); > - clip.y2 = max(clip.y2, roi_rect->y2); > - > - DPU_DEBUG("roi%d (%d,%d),(%d,%d) -> crtc (%d,%d),(%d,%d)\n", i, > - roi_rect->x1, roi_rect->y1, > - roi_rect->x2, roi_rect->y2, > - clip.x1, clip.y1, > - clip.x2, clip.y2); > - } > - > - if (clip.x2 && clip.y2) { > - result->x = clip.x1; > - result->y = clip.y1; > - result->w = clip.x2 - clip.x1; > - result->h = clip.y2 - clip.y1; > - } > -} > - > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > index 834dcc0..9e9c9d2 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > @@ -3243,7 +3243,6 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane, > struct drm_crtc *crtc; > struct drm_framebuffer *fb; > struct dpu_rect src, dst; > - const struct dpu_rect *crtc_roi; > bool q16_data = true; > int idx; > > @@ -3357,11 +3356,6 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane, > _dpu_plane_sspp_atomic_check_mode_changed(pdpu, state, > old_state); > > - /* re-program the output rects always in the case of partial update */ > - dpu_crtc_get_crtc_roi(crtc->state, &crtc_roi); > - if (!dpu_kms_rect_is_null(crtc_roi)) > - pstate->dirty |= DPU_PLANE_DIRTY_RECTS; > - > if (pstate->dirty & DPU_PLANE_DIRTY_RECTS) > memset(&(pdpu->pipe_cfg), 0, sizeof(struct dpu_hw_pipe_cfg)); > > @@ -3399,13 +3393,6 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane, > src.y &= ~0x1; > } > > - /* > - * adjust layer mixer position of the sspp in the presence > - * of a partial update to the active lm origin > - */ > - dst.x -= crtc_roi->x; > - dst.y -= crtc_roi->y; > - > pdpu->pipe_cfg.src_rect = src; > pdpu->pipe_cfg.dst_rect = dst; > > diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h > index d8e090f..8574f30 100644 > --- a/drivers/gpu/drm/msm/msm_drv.h > +++ b/drivers/gpu/drm/msm/msm_drv.h > @@ -144,7 +144,6 @@ enum msm_mdp_crtc_property { > CRTC_PROP_DRAM_IB, > CRTC_PROP_ROT_PREFILL_BW, > CRTC_PROP_ROT_CLK, > - CRTC_PROP_ROI_V1, > CRTC_PROP_IDLE_TIMEOUT, > CRTC_PROP_DEST_SCALER, > > @@ -168,7 +167,6 @@ enum msm_mdp_conn_property { > CONNECTOR_PROP_DST_Y, > CONNECTOR_PROP_DST_W, > CONNECTOR_PROP_DST_H, > - CONNECTOR_PROP_ROI_V1, > CONNECTOR_PROP_BL_SCALE, > CONNECTOR_PROP_AD_BL_SCALE, > > @@ -228,38 +226,6 @@ enum msm_event_wait { > }; > > /** > - * struct msm_roi_alignment - region of interest alignment restrictions > - * @xstart_pix_align: left x offset alignment restriction > - * @width_pix_align: width alignment restriction > - * @ystart_pix_align: top y offset alignment restriction > - * @height_pix_align: height alignment restriction > - * @min_width: minimum width restriction > - * @min_height: minimum height restriction > - */ > -struct msm_roi_alignment { > - uint32_t xstart_pix_align; > - uint32_t width_pix_align; > - uint32_t ystart_pix_align; > - uint32_t height_pix_align; > - uint32_t min_width; > - uint32_t min_height; > -}; > - > -/** > - * struct msm_roi_caps - display's region of interest capabilities > - * @enabled: true if some region of interest is supported > - * @merge_rois: merge rois before sending to display > - * @num_roi: maximum number of rois supported > - * @align: roi alignment restrictions > - */ > -struct msm_roi_caps { > - bool enabled; > - bool merge_rois; > - uint32_t num_roi; > - struct msm_roi_alignment align; > -}; > - > -/** > * struct msm_display_dsc_info - defines dsc configuration > * @version: DSC version. > * @scr_rev: DSC revision. > @@ -427,7 +393,6 @@ struct msm_mode_info { > * @is_primary: Set to true if display is primary display > * @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is > * used instead of panel TE in cmd mode panels > - * @roi_caps: Region of interest capability info > */ > struct msm_display_info { > int intf_type; > @@ -446,27 +411,6 @@ struct msm_display_info { > > bool is_primary; > bool is_te_using_watchdog_timer; > - struct msm_roi_caps roi_caps; > -}; > - > -#define MSM_MAX_ROI 4 > - > -/** > - * struct msm_roi_list - list of regions of interest for a drm object > - * @num_rects: number of valid rectangles in the roi array > - * @roi: list of roi rectangles > - */ > -struct msm_roi_list { > - uint32_t num_rects; > - struct drm_clip_rect roi[MSM_MAX_ROI]; > -}; > - > -/** > - * struct - msm_display_kickoff_params - info for display features at kickoff > - * @rois: Regions of interest structure for mapping CRTC to Connector output > - */ > -struct msm_display_kickoff_params { > - struct msm_roi_list *rois; > }; > > /** > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project > -- Sean Paul, Software Engineer, Google / Chromium OS -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html