disp: msm: sde: use crtc_width instead of hdisplay for crtc/lm

The interface resolution can be different from crtc/layer-mixer WxH
when certain features like destination scaler are enabled. Use the
sde_crtc_get_width/sde_crtc_get_mixer_width functions throughout
to get the correct crtc/lm size based on different features enabled.
This will help in validating/configuring lm & plane correctly.

Change-Id: I45de5844bf7465a3389cf723479c5449a835fb0a
Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
此提交包含在:
Veera Sundaram Sankaran
2021-06-30 14:14:33 -07:00
父節點 e1c71c86e5
當前提交 76e7c6acd3
共有 3 個檔案被更改,包括 83 行新增73 行删除

查看文件

@@ -830,10 +830,10 @@ static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc,
struct sde_crtc_state *crtc_state; struct sde_crtc_state *crtc_state;
struct sde_rect *crtc_roi; struct sde_rect *crtc_roi;
struct msm_mode_info mode_info; struct msm_mode_info mode_info;
int i = 0; int i = 0, rc;
int rc; bool is_crtc_roi_dirty, is_conn_roi_dirty;
bool is_crtc_roi_dirty; u32 crtc_width, crtc_height;
bool is_conn_roi_dirty; struct drm_display_mode *adj_mode;
if (!crtc || !state) if (!crtc || !state)
return -EINVAL; return -EINVAL;
@@ -904,15 +904,16 @@ static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc,
sde_kms_rect_merge_rectangles(&crtc_state->user_roi_list, crtc_roi); sde_kms_rect_merge_rectangles(&crtc_state->user_roi_list, crtc_roi);
/* clear the ROI to null if it matches full screen anyways */ /* clear the ROI to null if it matches full screen anyways */
adj_mode = &state->adjusted_mode;
crtc_width = sde_crtc_get_width(sde_crtc, crtc_state, adj_mode);
crtc_height = sde_crtc_get_mixer_height(sde_crtc, crtc_state, adj_mode);
if (crtc_roi->x == 0 && crtc_roi->y == 0 && if (crtc_roi->x == 0 && crtc_roi->y == 0 &&
crtc_roi->w == state->adjusted_mode.hdisplay && crtc_roi->w == crtc_width && crtc_roi->h == crtc_height)
crtc_roi->h == state->adjusted_mode.vdisplay)
memset(crtc_roi, 0, sizeof(*crtc_roi)); memset(crtc_roi, 0, sizeof(*crtc_roi));
SDE_DEBUG("%s: crtc roi (%d,%d,%d,%d)\n", sde_crtc->name, SDE_DEBUG("%s: crtc roi (%d,%d,%d,%d)\n", sde_crtc->name,
crtc_roi->x, crtc_roi->y, crtc_roi->w, crtc_roi->h); crtc_roi->x, crtc_roi->y, crtc_roi->w, crtc_roi->h);
SDE_EVT32_VERBOSE(DRMID(crtc), crtc_roi->x, crtc_roi->y, crtc_roi->w, SDE_EVT32_VERBOSE(DRMID(crtc), crtc_roi->x, crtc_roi->y, crtc_roi->w, crtc_roi->h);
crtc_roi->h);
return 0; return 0;
} }
@@ -3299,7 +3300,7 @@ static int _sde_crtc_check_dest_scaler_data(struct drm_crtc *crtc,
} }
/* Display resolution */ /* Display resolution */
hdisplay = mode->hdisplay/sde_crtc->num_mixers; hdisplay = mode->hdisplay / sde_crtc->num_mixers;
/* Validate the DS data */ /* Validate the DS data */
ret = _sde_crtc_check_dest_scaler_validate_ds(crtc, sde_crtc, cstate, ret = _sde_crtc_check_dest_scaler_validate_ds(crtc, sde_crtc, cstate,
@@ -3472,13 +3473,12 @@ static void _sde_crtc_setup_is_ppsplit(struct drm_crtc_state *state)
} }
} }
static void _sde_crtc_setup_lm_bounds(struct drm_crtc *crtc, static void _sde_crtc_setup_lm_bounds(struct drm_crtc *crtc, struct drm_crtc_state *state)
struct drm_crtc_state *state)
{ {
struct sde_crtc *sde_crtc; struct sde_crtc *sde_crtc;
struct sde_crtc_state *cstate; struct sde_crtc_state *cstate;
struct drm_display_mode *adj_mode; struct drm_display_mode *adj_mode;
u32 crtc_split_width; u32 mixer_width, mixer_height;
int i; int i;
if (!crtc || !state) { if (!crtc || !state) {
@@ -3490,16 +3490,15 @@ static void _sde_crtc_setup_lm_bounds(struct drm_crtc *crtc,
cstate = to_sde_crtc_state(state); cstate = to_sde_crtc_state(state);
adj_mode = &state->adjusted_mode; adj_mode = &state->adjusted_mode;
crtc_split_width = sde_crtc_get_mixer_width(sde_crtc, cstate, adj_mode); mixer_width = sde_crtc_get_mixer_width(sde_crtc, cstate, adj_mode);
mixer_height = sde_crtc_get_mixer_height(sde_crtc, cstate, adj_mode);
for (i = 0; i < sde_crtc->num_mixers; i++) { for (i = 0; i < sde_crtc->num_mixers; i++) {
cstate->lm_bounds[i].x = crtc_split_width * i; cstate->lm_bounds[i].x = mixer_width * i;
cstate->lm_bounds[i].y = 0; cstate->lm_bounds[i].y = 0;
cstate->lm_bounds[i].w = crtc_split_width; cstate->lm_bounds[i].w = mixer_width;
cstate->lm_bounds[i].h = cstate->lm_bounds[i].h = mixer_height;
sde_crtc_get_mixer_height(sde_crtc, cstate, adj_mode); memcpy(&cstate->lm_roi[i], &cstate->lm_bounds[i], sizeof(cstate->lm_roi[i]));
memcpy(&cstate->lm_roi[i], &cstate->lm_bounds[i],
sizeof(cstate->lm_roi[i]));
SDE_EVT32_VERBOSE(DRMID(crtc), i, SDE_EVT32_VERBOSE(DRMID(crtc), i,
cstate->lm_bounds[i].x, cstate->lm_bounds[i].y, cstate->lm_bounds[i].x, cstate->lm_bounds[i].y,
cstate->lm_bounds[i].w, cstate->lm_bounds[i].h); cstate->lm_bounds[i].w, cstate->lm_bounds[i].h);
@@ -4720,28 +4719,27 @@ static int _sde_crtc_excl_dim_layer_check(struct drm_crtc_state *state,
struct plane_state pstates[], int cnt) struct plane_state pstates[], int cnt)
{ {
struct sde_crtc_state *cstate = to_sde_crtc_state(state); struct sde_crtc_state *cstate = to_sde_crtc_state(state);
struct sde_crtc *sde_crtc = to_sde_crtc(state->crtc);
struct drm_display_mode *mode = &state->adjusted_mode; struct drm_display_mode *mode = &state->adjusted_mode;
const struct drm_plane_state *pstate; const struct drm_plane_state *pstate;
struct sde_plane_state *sde_pstate; struct sde_plane_state *sde_pstate;
int rc = 0, i; int rc = 0, i;
struct sde_rect *rect;
u32 crtc_width, crtc_height;
crtc_width = sde_crtc_get_width(sde_crtc, cstate, mode);
crtc_height = sde_crtc_get_mixer_height(sde_crtc, cstate, mode);
/* Check dim layer rect bounds and stage */ /* Check dim layer rect bounds and stage */
for (i = 0; i < cstate->num_dim_layers; i++) { for (i = 0; i < cstate->num_dim_layers; i++) {
if ((CHECK_LAYER_BOUNDS(cstate->dim_layer[i].rect.y, rect = &cstate->dim_layer[i].rect;
cstate->dim_layer[i].rect.h, mode->vdisplay)) || if ((CHECK_LAYER_BOUNDS(rect->y, rect->h, crtc_height)) ||
(CHECK_LAYER_BOUNDS(cstate->dim_layer[i].rect.x, (CHECK_LAYER_BOUNDS(rect->x, rect->w, crtc_width)) ||
cstate->dim_layer[i].rect.w, mode->hdisplay)) || (cstate->dim_layer[i].stage >= SDE_STAGE_MAX) || (!rect->w) || (!rect->h)) {
(cstate->dim_layer[i].stage >= SDE_STAGE_MAX) || SDE_ERROR("crtc:%d wxh:%dx%d, invalid dim_layer:{%d,%d,%d,%d}, stage:%d\n",
(!cstate->dim_layer[i].rect.w) || DRMID(state->crtc), crtc_width, crtc_height,
(!cstate->dim_layer[i].rect.h)) { rect->x, rect->y, rect->w, rect->h,
SDE_ERROR("invalid dim_layer:{%d,%d,%d,%d}, stage:%d\n",
cstate->dim_layer[i].rect.x,
cstate->dim_layer[i].rect.y,
cstate->dim_layer[i].rect.w,
cstate->dim_layer[i].rect.h,
cstate->dim_layer[i].stage); cstate->dim_layer[i].stage);
SDE_ERROR("display: %dx%d\n", mode->hdisplay,
mode->vdisplay);
rc = -E2BIG; rc = -E2BIG;
goto end; goto end;
} }
@@ -4752,9 +4750,8 @@ static int _sde_crtc_excl_dim_layer_check(struct drm_crtc_state *state,
pstate = pstates[i].drm_pstate; pstate = pstates[i].drm_pstate;
sde_pstate = to_sde_plane_state(pstate); sde_pstate = to_sde_plane_state(pstate);
SDE_DEBUG("p %d z %d src{%d,%d,%d,%d} excl_rect{%d,%d,%d,%d}\n", SDE_DEBUG("p %d z %d src{%d,%d,%d,%d} excl_rect{%d,%d,%d,%d}\n",
pstate->plane->base.id, pstates[i].stage, DRMID(pstate->plane), pstates[i].stage,
pstate->crtc_x, pstate->crtc_y, pstate->crtc_x, pstate->crtc_y, pstate->crtc_w, pstate->crtc_h,
pstate->crtc_w, pstate->crtc_h,
sde_pstate->excl_rect.x, sde_pstate->excl_rect.y, sde_pstate->excl_rect.x, sde_pstate->excl_rect.y,
sde_pstate->excl_rect.w, sde_pstate->excl_rect.h); sde_pstate->excl_rect.w, sde_pstate->excl_rect.h);
} }
@@ -5034,7 +5031,7 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
struct sde_crtc_state *cstate; struct sde_crtc_state *cstate;
const struct drm_plane_state *pstate; const struct drm_plane_state *pstate;
const struct drm_plane_state *pipe_staged[SSPP_MAX]; const struct drm_plane_state *pipe_staged[SSPP_MAX];
int rc = 0, multirect_count = 0, i, mixer_width, mixer_height; int rc = 0, multirect_count = 0, i, crtc_width, crtc_height;
int inc_sde_stage = 0; int inc_sde_stage = 0;
struct sde_kms *kms; struct sde_kms *kms;
u32 blend_type; u32 blend_type;
@@ -5050,11 +5047,8 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
memset(pipe_staged, 0, sizeof(pipe_staged)); memset(pipe_staged, 0, sizeof(pipe_staged));
mixer_width = sde_crtc_get_mixer_width(sde_crtc, cstate, mode); crtc_width = sde_crtc_get_width(sde_crtc, cstate, mode);
mixer_height = sde_crtc_get_mixer_height(sde_crtc, cstate, mode); crtc_height = sde_crtc_get_mixer_height(sde_crtc, cstate, mode);
if (cstate->num_ds_enabled)
mixer_width = mixer_width * cstate->num_ds_enabled;
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
if (IS_ERR_OR_NULL(pstate)) { if (IS_ERR_OR_NULL(pstate)) {
@@ -5103,23 +5097,18 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
(*cnt)++; (*cnt)++;
if (CHECK_LAYER_BOUNDS(pstate->crtc_y, pstate->crtc_h, if (CHECK_LAYER_BOUNDS(pstate->crtc_y, pstate->crtc_h, crtc_height) ||
mode->vdisplay) || CHECK_LAYER_BOUNDS(pstate->crtc_x, pstate->crtc_w, crtc_width)) {
CHECK_LAYER_BOUNDS(pstate->crtc_x, pstate->crtc_w, SDE_ERROR("invalid dest - y:%d h:%d crtc_h:%d x:%d w:%d crtc_w:%d\n",
mode->hdisplay)) { pstate->crtc_y, pstate->crtc_h, crtc_height,
SDE_ERROR("invalid vertical/horizontal destination\n"); pstate->crtc_x, pstate->crtc_w, crtc_width);
SDE_ERROR("y:%d h:%d vdisp:%d x:%d w:%d hdisp:%d\n",
pstate->crtc_y, pstate->crtc_h, mode->vdisplay,
pstate->crtc_x, pstate->crtc_w, mode->hdisplay);
return -E2BIG; return -E2BIG;
} }
if (blend_type != SDE_DRM_BLEND_OP_SKIP && cstate->num_ds_enabled && if (blend_type != SDE_DRM_BLEND_OP_SKIP && cstate->num_ds_enabled &&
((pstate->crtc_h > mixer_height) || ((pstate->crtc_h > crtc_height) || (pstate->crtc_w > crtc_width))) {
(pstate->crtc_w > mixer_width))) {
SDE_ERROR("plane w/h:%x*%x > mixer w/h:%x*%x\n", SDE_ERROR("plane w/h:%x*%x > mixer w/h:%x*%x\n",
pstate->crtc_w, pstate->crtc_h, pstate->crtc_w, pstate->crtc_h, crtc_width, crtc_height);
mixer_width, mixer_height);
return -E2BIG; return -E2BIG;
} }
} }
@@ -5303,6 +5292,9 @@ static int _sde_crtc_check_plane_layout(struct drm_crtc *crtc,
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *plane_state; struct drm_plane_state *plane_state;
struct sde_plane_state *pstate; struct sde_plane_state *pstate;
struct drm_display_mode *mode;
struct sde_crtc *sde_crtc;
struct sde_crtc_state *cstate;
int layout_split; int layout_split;
kms = _sde_crtc_get_kms(crtc); kms = _sde_crtc_get_kms(crtc);
@@ -5316,6 +5308,9 @@ static int _sde_crtc_check_plane_layout(struct drm_crtc *crtc,
SDE_RM_TOPOLOGY_GROUP_QUADPIPE)) SDE_RM_TOPOLOGY_GROUP_QUADPIPE))
return 0; return 0;
mode = &crtc->state->adjusted_mode;
sde_crtc = to_sde_crtc(crtc);
cstate = to_sde_crtc_state(crtc->state);
drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
plane_state = drm_atomic_get_existing_plane_state( plane_state = drm_atomic_get_existing_plane_state(
crtc_state->state, plane); crtc_state->state, plane);
@@ -5323,7 +5318,7 @@ static int _sde_crtc_check_plane_layout(struct drm_crtc *crtc,
continue; continue;
pstate = to_sde_plane_state(plane_state); pstate = to_sde_plane_state(plane_state);
layout_split = crtc_state->mode.hdisplay >> 1; layout_split = sde_crtc_get_width(sde_crtc, cstate, mode) >> 1;
if (plane_state->crtc_x >= layout_split) { if (plane_state->crtc_x >= layout_split) {
plane_state->crtc_x -= layout_split; plane_state->crtc_x -= layout_split;
@@ -6325,15 +6320,13 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data)
struct sde_crtc *sde_crtc; struct sde_crtc *sde_crtc;
struct sde_plane_state *pstate = NULL; struct sde_plane_state *pstate = NULL;
struct sde_crtc_mixer *m; struct sde_crtc_mixer *m;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_display_mode *mode; struct drm_display_mode *mode;
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
struct drm_plane_state *state; struct drm_plane_state *state;
struct sde_crtc_state *cstate; struct sde_crtc_state *cstate;
int i, mixer_width, mixer_height;
int i, out_width, out_height;
if (!s || !s->private) if (!s || !s->private)
return -EINVAL; return -EINVAL;
@@ -6344,11 +6337,11 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data)
mutex_lock(&sde_crtc->crtc_lock); mutex_lock(&sde_crtc->crtc_lock);
mode = &crtc->state->adjusted_mode; mode = &crtc->state->adjusted_mode;
out_width = sde_crtc_get_mixer_width(sde_crtc, cstate, mode); mixer_width = sde_crtc_get_mixer_width(sde_crtc, cstate, mode);
out_height = sde_crtc_get_mixer_height(sde_crtc, cstate, mode); mixer_height = sde_crtc_get_mixer_height(sde_crtc, cstate, mode);
seq_printf(s, "crtc:%d width:%d height:%d\n", crtc->base.id, seq_printf(s, "crtc:%d width:%d height:%d\n", DRMID(crtc),
mode->hdisplay, mode->vdisplay); mixer_width * sde_crtc->num_mixers, mixer_height);
seq_puts(s, "\n"); seq_puts(s, "\n");
@@ -6361,7 +6354,7 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data)
else else
seq_printf(s, "\tmixer:%d ctl:%d width:%d height:%d\n", seq_printf(s, "\tmixer:%d ctl:%d width:%d height:%d\n",
m->hw_lm->idx - LM_0, m->hw_ctl->idx - CTL_0, m->hw_lm->idx - LM_0, m->hw_ctl->idx - CTL_0,
out_width, out_height); mixer_width, mixer_height);
} }
seq_puts(s, "\n"); seq_puts(s, "\n");

查看文件

@@ -599,6 +599,25 @@ static inline int sde_crtc_get_mixer_height(struct sde_crtc *sde_crtc,
cstate->ds_cfg[0].lm_height : mode->vdisplay); cstate->ds_cfg[0].lm_height : mode->vdisplay);
} }
/**
* sde_crtc_get_width - get the correct crtc width based on the features enabled
*/
static inline int sde_crtc_get_width(struct sde_crtc *sde_crtc,
struct sde_crtc_state *cstate, struct drm_display_mode *mode)
{
u32 width;
if (!sde_crtc || !cstate || !mode)
return 0;
if (cstate->num_ds_enabled)
width = cstate->ds_cfg[0].lm_width * cstate->num_ds_enabled;
else
width = mode->hdisplay;
return width;
}
/** /**
* sde_crtc_frame_pending - retun the number of pending frames * sde_crtc_frame_pending - retun the number of pending frames
* @crtc: Pointer to drm crtc object * @crtc: Pointer to drm crtc object

查看文件

@@ -923,11 +923,11 @@ static int _sde_encoder_atomic_check_phys_enc(struct sde_encoder_virt *sde_enc,
} }
static int _sde_encoder_atomic_check_pu_roi(struct sde_encoder_virt *sde_enc, static int _sde_encoder_atomic_check_pu_roi(struct sde_encoder_virt *sde_enc,
struct drm_crtc_state *crtc_state, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state,
struct drm_connector_state *conn_state, struct sde_connector_state *sde_conn_state, struct sde_crtc_state *sde_crtc_state)
struct sde_connector_state *sde_conn_state,
struct sde_crtc_state *sde_crtc_state)
{ {
struct sde_crtc *sde_crtc = to_sde_crtc(crtc_state->crtc);
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
int ret = 0; int ret = 0;
if (crtc_state->mode_changed || crtc_state->active_changed) { if (crtc_state->mode_changed || crtc_state->active_changed) {
@@ -935,12 +935,11 @@ static int _sde_encoder_atomic_check_pu_roi(struct sde_encoder_virt *sde_enc,
mode_roi.x = 0; mode_roi.x = 0;
mode_roi.y = 0; mode_roi.y = 0;
mode_roi.w = crtc_state->adjusted_mode.hdisplay; mode_roi.w = sde_crtc_get_width(sde_crtc, sde_crtc_state, mode);
mode_roi.h = crtc_state->adjusted_mode.vdisplay; mode_roi.h = sde_crtc_get_mixer_height(sde_crtc, sde_crtc_state, mode);
if (sde_conn_state->rois.num_rects) { if (sde_conn_state->rois.num_rects) {
sde_kms_rect_merge_rectangles( sde_kms_rect_merge_rectangles(&sde_conn_state->rois, &roi);
&sde_conn_state->rois, &roi);
if (!sde_kms_rect_is_equal(&mode_roi, &roi)) { if (!sde_kms_rect_is_equal(&mode_roi, &roi)) {
SDE_ERROR_ENC(sde_enc, SDE_ERROR_ENC(sde_enc,
"roi (%d,%d,%d,%d) on connector invalid during modeset\n", "roi (%d,%d,%d,%d) on connector invalid during modeset\n",
@@ -950,8 +949,7 @@ static int _sde_encoder_atomic_check_pu_roi(struct sde_encoder_virt *sde_enc,
} }
if (sde_crtc_state->user_roi_list.num_rects) { if (sde_crtc_state->user_roi_list.num_rects) {
sde_kms_rect_merge_rectangles( sde_kms_rect_merge_rectangles(&sde_crtc_state->user_roi_list, &roi);
&sde_crtc_state->user_roi_list, &roi);
if (!sde_kms_rect_is_equal(&mode_roi, &roi)) { if (!sde_kms_rect_is_equal(&mode_roi, &roi)) {
SDE_ERROR_ENC(sde_enc, SDE_ERROR_ENC(sde_enc,
"roi (%d,%d,%d,%d) on crtc invalid during modeset\n", "roi (%d,%d,%d,%d) on crtc invalid during modeset\n",