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.
Change-Id: Idd87272fe4d4c0a26fcb405154c0605af1edf1ba
Signed-off-by: Jeykumar Sankaran <jsanka@xxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_connector.c | 143 +------
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 | 266 ++++--------
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +
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 ---
10 files changed, 90 insertions(+), 1009 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..6478e89 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,14 +461,7 @@ 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);
+ DPU_EVT32_VERBOSE(connector->base.id);
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)
@@ -850,13 +726,7 @@ static int
dpu_connector_atomic_set_property(struct drm_connector *connector,
break;
default:
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) {
@@ -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..68cf16a 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,27 +879,9 @@ 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 pic_width, pic_height;
int this_frame_slices;
int intf_ip_w, enc_ip_w;
int ich_res, dsc_common_mode = 0;
@@ -917,18 +889,22 @@ static int
_dpu_encoder_dsc_n_lm_1_enc_1_intf(struct dpu_encoder_virt *dpu_enc)
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 dpu_hw_mdp *hw_mdp_top = enc_master->hw_mdptop;
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) {
+ if (dsc == NULL || hw_dsc == NULL || hw_pp == NULL ||
+ hw_mdp_top == NULL) {