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 <cohens@codeaurora.org>
This commit is contained in:
Steve Cohen
2020-03-14 01:41:05 -04:00
parent 973788d311
commit 9992efa7a0
3 changed files with 79 additions and 51 deletions

View File

@@ -1407,9 +1407,9 @@ static int _sde_sspp_setup_vigs(struct device_node *np,
MAX_DOWNSCALE_RATIO_INROT_PD_RT_DENOMINATOR; MAX_DOWNSCALE_RATIO_INROT_PD_RT_DENOMINATOR;
sblk->in_rot_maxdwnscale_nrt = sblk->in_rot_maxdwnscale_nrt =
MAX_DOWNSCALE_RATIO_INROT_NRT_DEFAULT; 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; 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; MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_DENOMINATOR;
} else if (IS_SDE_INLINE_ROT_REV_100( } else if (IS_SDE_INLINE_ROT_REV_100(
sde_cfg->true_inline_rot_rev)) { sde_cfg->true_inline_rot_rev)) {

View File

@@ -680,8 +680,10 @@ enum sde_qos_lut_usage {
* @in_rot_maxdwnscale_rt_denom: max downscale ratio for inline rotation * @in_rot_maxdwnscale_rt_denom: max downscale ratio for inline rotation
* rt clients - denominator * rt clients - denominator
* @in_rot_maxdwnscale_nrt: max downscale ratio for inline rotation nrt clients * @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_maxdwnscale_rt_nopd_num: downscale threshold for when pre-downscale
* @in_rot_minpredwnscale_denom: min downscale ratio to enable 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 * @in_rot_maxheight: max pre rotated height for inline rotation
* @llcc_scid: scid for the system cache * @llcc_scid: scid for the system cache
* @llcc_slice size: slice size of 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_num;
u32 in_rot_maxdwnscale_rt_denom; u32 in_rot_maxdwnscale_rt_denom;
u32 in_rot_maxdwnscale_nrt; u32 in_rot_maxdwnscale_nrt;
u32 in_rot_minpredwnscale_num; u32 in_rot_maxdwnscale_rt_nopd_num;
u32 in_rot_minpredwnscale_denom; u32 in_rot_maxdwnscale_rt_nopd_denom;
u32 in_rot_maxheight; u32 in_rot_maxheight;
int llcc_scid; int llcc_scid;
size_t llcc_slice_size; size_t llcc_slice_size;

View File

@@ -2275,11 +2275,17 @@ static int _sde_atomic_check_pre_downscale(struct sde_plane *psde,
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; struct sde_hw_inline_pre_downscale_cfg *pd_cfg = &pstate->pre_down;
bool pd_x = pd_cfg->pre_downscale_x_0 > 1; bool pd_x;
bool pd_y = pd_cfg->pre_downscale_y_0 > 1; bool pd_y;
min_ratio_numer = psde->pipe_sblk->in_rot_minpredwnscale_num; if (!_sde_plane_is_pre_downscale_enabled(pd_cfg))
min_ratio_denom = psde->pipe_sblk->in_rot_minpredwnscale_denom; 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)) { if (pd_x && !_sde_plane_has_pre_downscale(psde)) {
SDE_ERROR_PLANE(psde, SDE_ERROR_PLANE(psde,
@@ -2314,6 +2320,47 @@ static int _sde_atomic_check_pre_downscale(struct sde_plane *psde,
return ret; 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, static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state,
struct sde_plane *psde, const struct sde_format *fmt, struct sde_plane *psde, const struct sde_format *fmt,
struct sde_plane_state *pstate, struct sde_rect *src, 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; int ret = 0;
uint32_t deci_w, deci_h, src_deci_w, src_deci_h; uint32_t deci_w, deci_h, src_deci_w, src_deci_h;
uint32_t scaler_src_w, scaler_src_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; 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 *crtc;
struct drm_crtc_state *new_cstate; struct drm_crtc_state *new_cstate;
const struct sde_sspp_sub_blks *sblk;
if (!state || !state->state || !state->crtc) { if (!state || !state->state || !state->crtc) {
SDE_ERROR_PLANE(psde, "invalid arguments\n"); 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_w = src_deci_w;
scaler_src_h = src_deci_h; scaler_src_h = src_deci_h;
} }
sblk = psde->pipe_sblk;
max_upscale = psde->pipe_sblk->maxupscale; max_upscale = sblk->maxupscale;
max_linewidth = psde->pipe_sblk->maxlinewidth; max_linewidth = 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);
crtc = state->crtc; crtc = state->crtc;
new_cstate = drm_atomic_get_new_crtc_state(state->state, crtc); new_cstate = drm_atomic_get_new_crtc_state(state->state, crtc);
rt_client = sde_crtc_is_rt_client(crtc, new_cstate); rt_client = sde_crtc_is_rt_client(crtc, new_cstate);
max_downscale_num = psde->pipe_sblk->maxdwnscale; _sde_plane_get_max_downscale_limits(psde, pstate, rt_client,
max_downscale_denom = 1; &max_downscale_num_w, &max_downscale_denom_w,
/* inline rotation RT clients have a different max downscaling limit */ &max_downscale_num_h, &max_downscale_denom_h);
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;
}
}
/* decimation validation */ /* decimation validation */
if ((deci_w || deci_h) if ((deci_w || deci_h)
&& ((deci_w > psde->pipe_sblk->maxhdeciexp) && ((deci_w > sblk->maxhdeciexp)
|| (deci_h > psde->pipe_sblk->maxvdeciexp))) { || (deci_h > sblk->maxvdeciexp))) {
SDE_ERROR_PLANE(psde, "too much decimation requested\n"); SDE_ERROR_PLANE(psde, "too much decimation requested\n");
ret = -EINVAL; ret = -EINVAL;
@@ -2412,21 +2438,21 @@ 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) ||
(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) || < 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)) { < 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 %d/%d\n",
scaler_src_w, scaler_src_h, dst->w, dst->h, scaler_src_w, scaler_src_h, dst->w, dst->h,
inline_rotation, max_downscale_num, inline_rotation, max_downscale_num_w,
max_downscale_denom); max_downscale_denom_w, max_downscale_num_h,
max_downscale_denom_h);
ret = -E2BIG; ret = -E2BIG;
/* check inline pre-downscale support */ /* check inline pre-downscale support */
} else if (inline_rotation && pre_down_en && } else if (inline_rotation && _sde_atomic_check_pre_downscale(psde,
_sde_atomic_check_pre_downscale(psde, pstate, dst, pstate, dst, src_deci_w, src_deci_h)) {
src_deci_w, src_deci_h)) {
ret = -EINVAL; ret = -EINVAL;
/* QSEED validation */ /* QSEED validation */