From 9992efa7a0d156216a1b78de33f648353bf18323 Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Sat, 14 Mar 2020 01:41:05 -0400 Subject: [PATCH] disp: msm: sde: separate horz/vert max downscale checks Separate the horizontal and vertical max downscale checks as pre-downscale introduced different limits on different axes. Also cleanup the variable names for max downscale limit when pre-downscale is not enabled. Change-Id: If01aac1844d0bd5133502a50dbc38197e11da5d5 Signed-off-by: Steve Cohen --- msm/sde/sde_hw_catalog.c | 4 +- msm/sde/sde_hw_catalog.h | 10 ++-- msm/sde/sde_plane.c | 116 ++++++++++++++++++++++++--------------- 3 files changed, 79 insertions(+), 51 deletions(-) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index be3e3d25cb..201711e626 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -1407,9 +1407,9 @@ static int _sde_sspp_setup_vigs(struct device_node *np, MAX_DOWNSCALE_RATIO_INROT_PD_RT_DENOMINATOR; sblk->in_rot_maxdwnscale_nrt = MAX_DOWNSCALE_RATIO_INROT_NRT_DEFAULT; - sblk->in_rot_minpredwnscale_num = + sblk->in_rot_maxdwnscale_rt_nopd_num = MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_NUMERATOR; - sblk->in_rot_minpredwnscale_denom = + sblk->in_rot_maxdwnscale_rt_nopd_denom = MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_DENOMINATOR; } else if (IS_SDE_INLINE_ROT_REV_100( sde_cfg->true_inline_rot_rev)) { diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index fd6314e8c6..eb34239723 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -680,8 +680,10 @@ enum sde_qos_lut_usage { * @in_rot_maxdwnscale_rt_denom: max downscale ratio for inline rotation * rt clients - denominator * @in_rot_maxdwnscale_nrt: max downscale ratio for inline rotation nrt clients - * @in_rot_minpredwnscale_num: min downscale ratio to enable pre-downscale - * @in_rot_minpredwnscale_denom: min downscale ratio to enable pre-downscale + * @in_rot_maxdwnscale_rt_nopd_num: downscale threshold for when pre-downscale + * must be enabled on HW with this support. + * @in_rot_maxdwnscale_rt_nopd_denom: downscale threshold for when pre-downscale + * must be enabled on HW with this support. * @in_rot_maxheight: max pre rotated height for inline rotation * @llcc_scid: scid for the system cache * @llcc_slice size: slice size of the system cache @@ -718,8 +720,8 @@ struct sde_sspp_sub_blks { u32 in_rot_maxdwnscale_rt_num; u32 in_rot_maxdwnscale_rt_denom; u32 in_rot_maxdwnscale_nrt; - u32 in_rot_minpredwnscale_num; - u32 in_rot_minpredwnscale_denom; + u32 in_rot_maxdwnscale_rt_nopd_num; + u32 in_rot_maxdwnscale_rt_nopd_denom; u32 in_rot_maxheight; int llcc_scid; size_t llcc_slice_size; diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index edfd96bcfc..1bb68488c1 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -2275,11 +2275,17 @@ static int _sde_atomic_check_pre_downscale(struct sde_plane *psde, int ret = 0; u32 min_ratio_numer, min_ratio_denom; struct sde_hw_inline_pre_downscale_cfg *pd_cfg = &pstate->pre_down; - bool pd_x = pd_cfg->pre_downscale_x_0 > 1; - bool pd_y = pd_cfg->pre_downscale_y_0 > 1; + bool pd_x; + bool pd_y; - min_ratio_numer = psde->pipe_sblk->in_rot_minpredwnscale_num; - min_ratio_denom = psde->pipe_sblk->in_rot_minpredwnscale_denom; + if (!_sde_plane_is_pre_downscale_enabled(pd_cfg)) + return ret; + + pd_x = pd_cfg->pre_downscale_x_0 > 1; + pd_y = pd_cfg->pre_downscale_y_0 > 1; + + min_ratio_numer = psde->pipe_sblk->in_rot_maxdwnscale_rt_nopd_num; + min_ratio_denom = psde->pipe_sblk->in_rot_maxdwnscale_rt_nopd_denom; if (pd_x && !_sde_plane_has_pre_downscale(psde)) { SDE_ERROR_PLANE(psde, @@ -2314,6 +2320,47 @@ static int _sde_atomic_check_pre_downscale(struct sde_plane *psde, return ret; } +static void _sde_plane_get_max_downscale_limits(struct sde_plane *psde, + struct sde_plane_state *pstate, bool rt_client, + u32 *max_numer_w, u32 *max_denom_w, + u32 *max_numer_h, u32 *max_denom_h) +{ + bool rotated, has_predown; + const struct sde_sspp_sub_blks *sblk; + struct sde_hw_inline_pre_downscale_cfg *pd; + + rotated = pstate->rotation & DRM_MODE_ROTATE_90; + sblk = psde->pipe_sblk; + *max_numer_w = sblk->maxdwnscale; + *max_denom_w = 1; + *max_numer_h = sblk->maxdwnscale; + *max_denom_h = 1; + + has_predown = _sde_plane_has_pre_downscale(psde); + if (has_predown) + pd = &pstate->pre_down; + + /** + * Inline rotation has different max vertical downscaling limits since + * the source-width becomes the scaler's pre-downscaled source-height. + **/ + if (rotated) { + if (rt_client && has_predown) { + *max_numer_h = pd->pre_downscale_x_0 ? + sblk->in_rot_maxdwnscale_rt_num : + sblk->in_rot_maxdwnscale_rt_nopd_num; + *max_denom_h = pd->pre_downscale_x_0 ? + sblk->in_rot_maxdwnscale_rt_denom : + sblk->in_rot_maxdwnscale_rt_nopd_denom; + } else if (rt_client) { + *max_numer_h = sblk->in_rot_maxdwnscale_rt_num; + *max_denom_h = sblk->in_rot_maxdwnscale_rt_denom; + } else { + *max_numer_h = sblk->in_rot_maxdwnscale_nrt; + } + } +} + static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, struct sde_plane *psde, const struct sde_format *fmt, struct sde_plane_state *pstate, struct sde_rect *src, @@ -2322,11 +2369,13 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, int ret = 0; uint32_t deci_w, deci_h, src_deci_w, src_deci_h; uint32_t scaler_src_w, scaler_src_h; - uint32_t max_downscale_num, max_downscale_denom; + uint32_t max_downscale_num_w, max_downscale_denom_w; + uint32_t max_downscale_num_h, max_downscale_denom_h; uint32_t max_upscale, max_linewidth; - bool inline_rotation, rt_client, has_predown, pre_down_en = false; + bool inline_rotation, rt_client; struct drm_crtc *crtc; struct drm_crtc_state *new_cstate; + const struct sde_sspp_sub_blks *sblk; if (!state || !state->state || !state->crtc) { SDE_ERROR_PLANE(psde, "invalid arguments\n"); @@ -2348,45 +2397,22 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, scaler_src_w = src_deci_w; scaler_src_h = src_deci_h; } - - max_upscale = psde->pipe_sblk->maxupscale; - max_linewidth = psde->pipe_sblk->maxlinewidth; - has_predown = _sde_plane_has_pre_downscale(psde); - if (has_predown) - pre_down_en = _sde_plane_is_pre_downscale_enabled( - &pstate->pre_down); + sblk = psde->pipe_sblk; + max_upscale = sblk->maxupscale; + max_linewidth = sblk->maxlinewidth; crtc = state->crtc; new_cstate = drm_atomic_get_new_crtc_state(state->state, crtc); - rt_client = sde_crtc_is_rt_client(crtc, new_cstate); - max_downscale_num = psde->pipe_sblk->maxdwnscale; - max_downscale_denom = 1; - /* inline rotation RT clients have a different max downscaling limit */ - if (inline_rotation) { - if (rt_client && has_predown) { - max_downscale_num = pre_down_en ? - psde->pipe_sblk->in_rot_maxdwnscale_rt_num : - psde->pipe_sblk->in_rot_minpredwnscale_num; - max_downscale_denom = pre_down_en ? - psde->pipe_sblk->in_rot_maxdwnscale_rt_denom : - psde->pipe_sblk->in_rot_minpredwnscale_denom; - } else if (rt_client) { - max_downscale_num = - psde->pipe_sblk->in_rot_maxdwnscale_rt_num; - max_downscale_denom = - psde->pipe_sblk->in_rot_maxdwnscale_rt_denom; - } else { - max_downscale_num = - psde->pipe_sblk->in_rot_maxdwnscale_nrt; - } - } + _sde_plane_get_max_downscale_limits(psde, pstate, rt_client, + &max_downscale_num_w, &max_downscale_denom_w, + &max_downscale_num_h, &max_downscale_denom_h); /* decimation validation */ if ((deci_w || deci_h) - && ((deci_w > psde->pipe_sblk->maxhdeciexp) - || (deci_h > psde->pipe_sblk->maxvdeciexp))) { + && ((deci_w > sblk->maxhdeciexp) + || (deci_h > sblk->maxvdeciexp))) { SDE_ERROR_PLANE(psde, "too much decimation requested\n"); ret = -EINVAL; @@ -2412,21 +2438,21 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, /* check max scaler capability */ } else if (((scaler_src_w * max_upscale) < dst->w) || ((scaler_src_h * max_upscale) < dst->h) || - (mult_frac(dst->w, max_downscale_num, max_downscale_denom) + (mult_frac(dst->w, max_downscale_num_w, max_downscale_denom_w) < scaler_src_w) || - (mult_frac(dst->h, max_downscale_num, max_downscale_denom) + (mult_frac(dst->h, max_downscale_num_h, max_downscale_denom_h) < scaler_src_h)) { SDE_ERROR_PLANE(psde, - "too much scaling %ux%u->%ux%u rot:%d dwn:%d/%d\n", + "too much scaling %ux%u->%ux%u rot:%d dwn:%d/%d %d/%d\n", scaler_src_w, scaler_src_h, dst->w, dst->h, - inline_rotation, max_downscale_num, - max_downscale_denom); + inline_rotation, max_downscale_num_w, + max_downscale_denom_w, max_downscale_num_h, + max_downscale_denom_h); ret = -E2BIG; /* check inline pre-downscale support */ - } else if (inline_rotation && pre_down_en && - _sde_atomic_check_pre_downscale(psde, pstate, dst, - src_deci_w, src_deci_h)) { + } else if (inline_rotation && _sde_atomic_check_pre_downscale(psde, + pstate, dst, src_deci_w, src_deci_h)) { ret = -EINVAL; /* QSEED validation */