disp: msm: sde: fix min pre-downscale check

De-couple the horizontal and vertical pre-downscale checks since
this block can be used in cases where only X-axis downscaling
is needed.

Change-Id: I2e7d30863baed98e9f7fa0a328837691f0bc75a5
Signed-off-by: Steve Cohen <cohens@codeaurora.org>
This commit is contained in:
Steve Cohen
2020-01-07 11:50:55 -08:00
parent bfbb5f63e7
commit 5a24970f70
2 changed files with 28 additions and 13 deletions

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*/ */
#ifndef _SDE_HW_CATALOG_H #ifndef _SDE_HW_CATALOG_H
@@ -218,6 +218,7 @@ enum {
* @SDE_SSPP_SCALER_QSEED3LITE Qseed3lite algorithm support * @SDE_SSPP_SCALER_QSEED3LITE Qseed3lite algorithm support
* @SDE_SSPP_TRUE_INLINE_ROT Support of SSPP true inline rotation v1 * @SDE_SSPP_TRUE_INLINE_ROT Support of SSPP true inline rotation v1
* @SDE_SSPP_PREDOWNSCALE Support pre-downscale X-direction by 2 for inline * @SDE_SSPP_PREDOWNSCALE Support pre-downscale X-direction by 2 for inline
* @SDE_SSPP_PREDOWNSCALE_Y Support pre-downscale Y-direction for inline
* @SDE_SSPP_INLINE_CONST_CLR Inline rotation requires const clr disabled * @SDE_SSPP_INLINE_CONST_CLR Inline rotation requires const clr disabled
* @SDE_SSPP_MAX maximum value * @SDE_SSPP_MAX maximum value
*/ */
@@ -248,6 +249,7 @@ enum {
SDE_SSPP_SCALER_QSEED3LITE, SDE_SSPP_SCALER_QSEED3LITE,
SDE_SSPP_TRUE_INLINE_ROT, SDE_SSPP_TRUE_INLINE_ROT,
SDE_SSPP_PREDOWNSCALE, SDE_SSPP_PREDOWNSCALE,
SDE_SSPP_PREDOWNSCALE_Y,
SDE_SSPP_INLINE_CONST_CLR, SDE_SSPP_INLINE_CONST_CLR,
SDE_SSPP_MAX SDE_SSPP_MAX
}; };

View File

@@ -2425,17 +2425,25 @@ static int _sde_plane_validate_scaler_v2(struct sde_plane *psde,
static int _sde_atomic_check_pre_downscale(struct sde_plane *psde, static int _sde_atomic_check_pre_downscale(struct sde_plane *psde,
struct sde_plane_state *pstate, struct sde_rect *dst, struct sde_plane_state *pstate, struct sde_rect *dst,
u32 scaler_src_w, u32 scaler_src_h) u32 src_w, u32 src_h)
{ {
int ret = 0; int ret = 0;
u32 min_ratio_numer, min_ratio_denom; 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;
min_ratio_numer = psde->pipe_sblk->in_rot_minpredwnscale_num; min_ratio_numer = psde->pipe_sblk->in_rot_minpredwnscale_num;
min_ratio_denom = psde->pipe_sblk->in_rot_minpredwnscale_denom; min_ratio_denom = psde->pipe_sblk->in_rot_minpredwnscale_denom;
if (!(psde->features & BIT(SDE_SSPP_PREDOWNSCALE))) { if (pd_x && !(psde->features & BIT(SDE_SSPP_PREDOWNSCALE))) {
SDE_ERROR_PLANE(psde, SDE_ERROR_PLANE(psde,
"hw does not support pre-downscaler: 0x%x\n", "hw does not support pre-downscale X: 0x%x\n",
psde->features);
ret = -EINVAL;
} else if (pd_y && !(psde->features & BIT(SDE_SSPP_PREDOWNSCALE_Y))) {
SDE_ERROR_PLANE(psde,
"hw does not support pre-downscale Y: 0x%x\n",
psde->features); psde->features);
ret = -EINVAL; ret = -EINVAL;
} else if (!min_ratio_numer || !min_ratio_denom) { } else if (!min_ratio_numer || !min_ratio_denom) {
@@ -2443,13 +2451,18 @@ static int _sde_atomic_check_pre_downscale(struct sde_plane *psde,
"min downscale ratio not set! %u / %u\n", "min downscale ratio not set! %u / %u\n",
min_ratio_numer, min_ratio_denom); min_ratio_numer, min_ratio_denom);
ret = -EINVAL; ret = -EINVAL;
} else if ((scaler_src_w < mult_frac(dst->w, min_ratio_numer, /* compare pre-rotated src w/h with post-rotated dst h/w resp. */
min_ratio_denom)) || (scaler_src_h < mult_frac( } else if (pd_x && (src_w < mult_frac(dst->h, min_ratio_numer,
dst->h, min_ratio_numer, min_ratio_denom))) { min_ratio_denom))) {
SDE_ERROR_PLANE(psde, SDE_ERROR_PLANE(psde,
"failed min downscale check %ux%u->%ux%u, %u/%u\n", "failed min downscale-x check %u->%u, %u/%u\n",
scaler_src_w, scaler_src_h, dst->w, dst->h, src_w, dst->h, min_ratio_numer, min_ratio_denom);
min_ratio_numer, min_ratio_denom); ret = -EINVAL;
} else if (pd_y && (src_h < mult_frac(dst->w, min_ratio_numer,
min_ratio_denom))) {
SDE_ERROR_PLANE(psde,
"failed min downscale-y check %u->%u, %u/%u\n",
src_h, dst->w, min_ratio_numer, min_ratio_denom);
ret = -EINVAL; ret = -EINVAL;
} }
@@ -2551,9 +2564,9 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state,
/* check max scaler capability */ /* check max scaler capability */
} else if (((scaler_src_w * max_upscale) < dst->w) || } else if (((scaler_src_w * max_upscale) < dst->w) ||
((scaler_src_h * max_upscale) < dst->h) || ((scaler_src_h * max_upscale) < dst->h) ||
(((dst->w * max_downscale_num) / max_downscale_denom) (mult_frac(dst->w, max_downscale_num, max_downscale_denom)
< scaler_src_w) || < scaler_src_w) ||
(((dst->h * max_downscale_num) / max_downscale_denom) (mult_frac(dst->h, max_downscale_num, max_downscale_denom)
< scaler_src_h)) { < scaler_src_h)) {
SDE_ERROR_PLANE(psde, 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\n",
@@ -2565,7 +2578,7 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state,
/* check inline pre-downscale support */ /* check inline pre-downscale support */
} else if (inline_rotation && pre_down_en && } else if (inline_rotation && pre_down_en &&
_sde_atomic_check_pre_downscale(psde, pstate, dst, _sde_atomic_check_pre_downscale(psde, pstate, dst,
scaler_src_w, scaler_src_h)) { src_deci_w, src_deci_h)) {
ret = -EINVAL; ret = -EINVAL;
/* QSEED validation */ /* QSEED validation */