From 60133f5ebbe2a5fb14afce71ef2aff151e42a8b7 Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Thu, 1 Aug 2019 12:18:14 -0400 Subject: [PATCH] disp: msm: sde: pre-downscale support for inline rotation v2 Add support for enabling pre-downscale block to increase the maximum downscale capability for true inline rotation use cases. Change-Id: Ifa544bb0ae69439abef4bd427134290090fe7230 Signed-off-by: Steve Cohen --- msm/sde/sde_hw_catalog.c | 46 ++++++++----- msm/sde/sde_hw_catalog.h | 10 ++- msm/sde/sde_hw_sspp.c | 22 ++++++- msm/sde/sde_hw_sspp.h | 8 +++ msm/sde/sde_hw_util.h | 7 ++ msm/sde/sde_plane.c | 139 +++++++++++++++++++++++++++++++++------ msm/sde/sde_plane.h | 1 + 7 files changed, 193 insertions(+), 40 deletions(-) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index d8f365dc29..11b21b7f8e 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -69,9 +69,12 @@ #define MAX_DOWNSCALE_RATIO 4 #define SSPP_UNITY_SCALE 1 -#define MAX_DOWNSCALE_RATIO_INLINE_ROT_RT_NUMERATOR 11 -#define MAX_DOWNSCALE_RATIO_INLINE_ROT_RT_DENOMINATOR 5 -#define MAX_DOWNSCALE_RATIO_INLINE_ROT_NRT_DEFAULT 4 +#define MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_NUMERATOR 11 +#define MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_DENOMINATOR 5 +#define MAX_DOWNSCALE_RATIO_INROT_PD_RT_NUMERATOR 4 +#define MAX_DOWNSCALE_RATIO_INROT_PD_RT_DENOMINATOR 1 +#define MAX_DOWNSCALE_RATIO_INROT_NRT_DEFAULT 4 + #define MAX_PRE_ROT_HEIGHT_INLINE_ROT_DEFAULT 1088 #define MAX_HORZ_DECIMATION 4 @@ -1255,8 +1258,10 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg, sblk->format_list = sde_cfg->vig_formats; sblk->virt_format_list = sde_cfg->virt_vig_formats; - if (IS_SDE_INLINE_ROT_REV_100(sde_cfg->true_inline_rot_rev)) { - set_bit(SDE_SSPP_TRUE_INLINE_ROT_V1, &sspp->features); + if (IS_SDE_INLINE_ROT_REV_100(sde_cfg->true_inline_rot_rev) || + IS_SDE_INLINE_ROT_REV_200( + sde_cfg->true_inline_rot_rev)) { + set_bit(SDE_SSPP_TRUE_INLINE_ROT, &sspp->features); sblk->in_rot_format_list = sde_cfg->inline_rot_formats; sblk->in_rot_maxdwnscale_rt_num = sde_cfg->true_inline_dwnscale_rt_num; @@ -1274,6 +1279,14 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg, sde_cfg->true_inline_prefill_lines; } + if (IS_SDE_INLINE_ROT_REV_200(sde_cfg->true_inline_rot_rev)) { + set_bit(SDE_SSPP_PREDOWNSCALE, &sspp->features); + sblk->in_rot_minpredwnscale_num = + MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_NUMERATOR; + sblk->in_rot_minpredwnscale_denom = + MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_DENOMINATOR; + } + if (sde_cfg->sc_cfg.has_sys_cache) { set_bit(SDE_PERF_SSPP_SYS_CACHE, &sspp->perf_features); sblk->llcc_scid = sde_cfg->sc_cfg.llcc_scid; @@ -2311,8 +2324,7 @@ static int sde_rot_parse_dt(struct device_node *np, if (rc) { /* * This is not a fatal error, system cache can be disabled - * in device tree, anyways recommendation is to have it - * enabled, so print an error but don't fail + * in device tree */ SDE_DEBUG("sys cache will be disabled rc:%d\n", rc); rc = 0; @@ -4310,11 +4322,11 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->has_vig_p010 = true; sde_cfg->true_inline_rot_rev = SDE_INLINE_ROT_VERSION_1_0_0; sde_cfg->true_inline_dwnscale_rt_num = - MAX_DOWNSCALE_RATIO_INLINE_ROT_RT_NUMERATOR; + MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_NUMERATOR; sde_cfg->true_inline_dwnscale_rt_denom = - MAX_DOWNSCALE_RATIO_INLINE_ROT_RT_DENOMINATOR; + MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_DENOMINATOR; sde_cfg->true_inline_dwnscale_nrt = - MAX_DOWNSCALE_RATIO_INLINE_ROT_NRT_DEFAULT; + MAX_DOWNSCALE_RATIO_INROT_NRT_DEFAULT; sde_cfg->true_inline_prefill_fudge_lines = 2; sde_cfg->true_inline_prefill_lines_nv12 = 32; sde_cfg->true_inline_prefill_lines = 48; @@ -4341,11 +4353,11 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->has_vig_p010 = true; sde_cfg->true_inline_rot_rev = SDE_INLINE_ROT_VERSION_1_0_0; sde_cfg->true_inline_dwnscale_rt_num = - MAX_DOWNSCALE_RATIO_INLINE_ROT_RT_NUMERATOR; + MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_NUMERATOR; sde_cfg->true_inline_dwnscale_rt_denom = - MAX_DOWNSCALE_RATIO_INLINE_ROT_RT_DENOMINATOR; + MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_DENOMINATOR; sde_cfg->true_inline_dwnscale_nrt = - MAX_DOWNSCALE_RATIO_INLINE_ROT_NRT_DEFAULT; + MAX_DOWNSCALE_RATIO_INROT_NRT_DEFAULT; sde_cfg->true_inline_prefill_fudge_lines = 2; sde_cfg->true_inline_prefill_lines_nv12 = 32; sde_cfg->true_inline_prefill_lines = 48; @@ -4395,13 +4407,13 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->has_hdr_plus = true; set_bit(SDE_MDP_DHDR_MEMPOOL, &sde_cfg->mdp[0].features); sde_cfg->has_vig_p010 = true; - sde_cfg->true_inline_rot_rev = SDE_INLINE_ROT_VERSION_1_0_0; + sde_cfg->true_inline_rot_rev = SDE_INLINE_ROT_VERSION_2_0_0; sde_cfg->true_inline_dwnscale_rt_num = - MAX_DOWNSCALE_RATIO_INLINE_ROT_RT_NUMERATOR; + MAX_DOWNSCALE_RATIO_INROT_PD_RT_NUMERATOR; sde_cfg->true_inline_dwnscale_rt_denom = - MAX_DOWNSCALE_RATIO_INLINE_ROT_RT_DENOMINATOR; + MAX_DOWNSCALE_RATIO_INROT_PD_RT_DENOMINATOR; sde_cfg->true_inline_dwnscale_nrt = - MAX_DOWNSCALE_RATIO_INLINE_ROT_NRT_DEFAULT; + MAX_DOWNSCALE_RATIO_INROT_NRT_DEFAULT; sde_cfg->true_inline_prefill_fudge_lines = 2; sde_cfg->true_inline_prefill_lines_nv12 = 32; sde_cfg->true_inline_prefill_lines = 48; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index e6d2fe7c70..81e4a7d0f7 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -216,7 +216,8 @@ enum { * @SDE_SSPP_SEC_UI_ALLOWED Allows secure-ui layers * @SDE_SSPP_BLOCK_SEC_UI Blocks secure-ui layers * @SDE_SSPP_SCALER_QSEED3LITE Qseed3lite algorithm support - * @SDE_SSPP_TRUE_INLINE_ROT_V1, 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_INLINE_CONST_CLR Inline rotation requires const clr disabled * @SDE_SSPP_MAX maximum value */ @@ -245,7 +246,8 @@ enum { SDE_SSPP_SEC_UI_ALLOWED, SDE_SSPP_BLOCK_SEC_UI, SDE_SSPP_SCALER_QSEED3LITE, - SDE_SSPP_TRUE_INLINE_ROT_V1, + SDE_SSPP_TRUE_INLINE_ROT, + SDE_SSPP_PREDOWNSCALE, SDE_SSPP_INLINE_CONST_CLR, SDE_SSPP_MAX }; @@ -622,6 +624,8 @@ struct sde_qos_lut_tbl { * @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_maxheight: max pre rotated height for inline rotation * @in_rot_prefill_fudge_lines: prefill fudge lines for inline rotation * @in_rot_prefill_lines_mv12: prefill lines for nv12 format inline rotation @@ -661,6 +665,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_maxheight; u32 in_rot_prefill_fudge_lines; u32 in_rot_prefill_lines_nv12; diff --git a/msm/sde/sde_hw_sspp.c b/msm/sde/sde_hw_sspp.c index e0801049ec..10cc110a6b 100644 --- a/msm/sde/sde_hw_sspp.c +++ b/msm/sde/sde_hw_sspp.c @@ -67,7 +67,8 @@ #define SSPP_SRC_CONSTANT_COLOR 0x3c #define SSPP_EXCL_REC_CTL 0x40 #define SSPP_UBWC_STATIC_CTRL 0x44 -#define SSPP_FETCH_CONFIG 0x048 +#define SSPP_FETCH_CONFIG 0x48 +#define SSPP_PRE_DOWN_SCALE 0x50 #define SSPP_DANGER_LUT 0x60 #define SSPP_SAFE_LUT 0x64 #define SSPP_CREQ_LUT 0x68 @@ -596,6 +597,22 @@ static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx, ctx->cap->sblk->scaler_blk.version, idx, sspp->layout.format); } +static void sde_hw_sspp_setup_pre_downscale(struct sde_hw_pipe *ctx, + struct sde_hw_inline_pre_downscale_cfg *pre_down) +{ + u32 idx, val; + + if (!ctx || !pre_down || _sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx)) + return; + + val = pre_down->pre_downscale_x_0 | + (pre_down->pre_downscale_x_1 << 4) | + (pre_down->pre_downscale_y_0 << 8) | + (pre_down->pre_downscale_y_1 << 12); + + SDE_REG_WRITE(&ctx->hw, SSPP_PRE_DOWN_SCALE + idx, val); +} + static u32 _sde_hw_sspp_get_scaler3_ver(struct sde_hw_pipe *ctx) { u32 idx; @@ -1242,6 +1259,9 @@ static void _setup_layer_ops(struct sde_hw_pipe *c, c->ops.setup_scaler = reg_dmav1_setup_vig_qseed3; } + if (test_bit(SDE_SSPP_PREDOWNSCALE, &features)) + c->ops.setup_pre_downscale = sde_hw_sspp_setup_pre_downscale; + if (test_bit(SDE_PERF_SSPP_SYS_CACHE, &perf_features)) c->ops.setup_sys_cache = sde_hw_sspp_setup_sys_cache; diff --git a/msm/sde/sde_hw_sspp.h b/msm/sde/sde_hw_sspp.h index fab6282d46..5f06ec42e2 100644 --- a/msm/sde/sde_hw_sspp.h +++ b/msm/sde/sde_hw_sspp.h @@ -516,6 +516,14 @@ struct sde_hw_sspp_ops { struct sde_hw_scaler3_cfg *scaler3_cfg, u32 offset); + /** + * setup_pre_downscale - setup pre-downscaler for inline rotation + * @ctx: Pointer to pipe context + * @pre_down: Pointer to pre-downscaler configuration + */ + void (*setup_pre_downscale)(struct sde_hw_pipe *ctx, + struct sde_hw_inline_pre_downscale_cfg *pre_down); + /** * get_scaler_ver - get scaler h/w version * @ctx: Pointer to pipe context diff --git a/msm/sde/sde_hw_util.h b/msm/sde/sde_hw_util.h index d89ac706f5..e162d38665 100644 --- a/msm/sde/sde_hw_util.h +++ b/msm/sde/sde_hw_util.h @@ -160,6 +160,13 @@ struct sde_hw_scaler3_lut_cfg { size_t sep_len; }; +struct sde_hw_inline_pre_downscale_cfg { + u32 pre_downscale_x_0; + u32 pre_downscale_x_1; + u32 pre_downscale_y_0; + u32 pre_downscale_y_1; +}; + u32 *sde_hw_util_get_log_mask_ptr(void); void sde_reg_write(struct sde_hw_blk_reg_map *c, diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index ad0f7d1861..0dd1e548c7 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -1512,6 +1512,10 @@ static void _sde_plane_setup_scaler(struct sde_plane *psde, pe->btm_ftch[i] = pe->num_ext_pxls_btm[i]; } } + + if (psde->pipe_hw->ops.setup_pre_downscale) + psde->pipe_hw->ops.setup_pre_downscale(psde->pipe_hw, + &pstate->pre_down); } /** @@ -1652,7 +1656,7 @@ static int sde_plane_rot_atomic_check(struct drm_plane *plane, !psde->pipe_sblk->in_rot_maxdwnscale_nrt || !psde->pipe_sblk->in_rot_maxheight || !psde->pipe_sblk->in_rot_format_list || - !(psde->features & BIT(SDE_SSPP_TRUE_INLINE_ROT_V1))) { + !(psde->features & BIT(SDE_SSPP_TRUE_INLINE_ROT))) { SDE_ERROR_PLANE(psde, "wrong config rt:%d/%d nrt:%d fmt:%d h:%d 0x%x\n", !psde->pipe_sblk->in_rot_maxdwnscale_rt_num, @@ -1787,7 +1791,7 @@ static void sde_plane_rot_install_properties(struct drm_plane *plane, return; } - if (psde->features & BIT(SDE_SSPP_TRUE_INLINE_ROT_V1)) + if (psde->features & BIT(SDE_SSPP_TRUE_INLINE_ROT)) supported_rotations |= DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; @@ -2269,6 +2273,12 @@ int sde_plane_validate_src_addr(struct drm_plane *plane, return ret; } +static inline bool _sde_plane_is_pre_downscale_enabled( + struct sde_hw_inline_pre_downscale_cfg *pre_down) +{ + return pre_down->pre_downscale_x_0 || pre_down->pre_downscale_y_0; +} + static int _sde_plane_validate_scaler_v2(struct sde_plane *psde, struct sde_plane_state *pstate, const struct sde_format *fmt, @@ -2276,6 +2286,8 @@ static int _sde_plane_validate_scaler_v2(struct sde_plane *psde, uint32_t src_w, uint32_t src_h, uint32_t deci_w, uint32_t deci_h) { + struct sde_hw_inline_pre_downscale_cfg *pd_cfg; + bool pre_down_en; int i; if (!psde || !pstate || !fmt) { @@ -2288,6 +2300,9 @@ static int _sde_plane_validate_scaler_v2(struct sde_plane *psde, pstate->scaler_check_state != SDE_PLANE_SCLCHECK_SCALER_V2_CHECK)) return 0; + pd_cfg = &pstate->pre_down; + pre_down_en = _sde_plane_is_pre_downscale_enabled(pd_cfg); + pstate->scaler_check_state = SDE_PLANE_SCLCHECK_INVALID; for (i = 0; i < SDE_MAX_PLANES; i++) { @@ -2295,12 +2310,26 @@ static int _sde_plane_validate_scaler_v2(struct sde_plane *psde, uint32_t vert_req_pixels, vert_fetch_pixels; uint32_t src_w_tmp, src_h_tmp; uint32_t scaler_w, scaler_h; + uint32_t pre_down_ratio_x = 1, pre_down_ratio_y = 1; bool rot; /* re-use color plane 1's config for plane 2 */ if (i == 2) continue; + if (pre_down_en) { + if (i == 0 && pd_cfg->pre_downscale_x_0) + pre_down_ratio_x = pd_cfg->pre_downscale_x_0; + if (i == 0 && pd_cfg->pre_downscale_y_0) + pre_down_ratio_y = pd_cfg->pre_downscale_y_0; + if ((i == 1 || i == 2) && pd_cfg->pre_downscale_x_1) + pre_down_ratio_x = pd_cfg->pre_downscale_x_1; + if ((i == 1 || i == 2) && pd_cfg->pre_downscale_y_1) + pre_down_ratio_y = pd_cfg->pre_downscale_y_1; + SDE_DEBUG_PLANE(psde, "pre_down[%d]: x:%d, y:%d\n", + i, pre_down_ratio_x, pre_down_ratio_y); + } + src_w_tmp = src_w; src_h_tmp = src_h; @@ -2359,13 +2388,14 @@ static int _sde_plane_validate_scaler_v2(struct sde_plane *psde, * repeat/drop, src_width and src_height are only specified * for Y and UV plane */ - if (i != 3 && (hor_req_pixels != scaler_w || - vert_req_pixels != scaler_h)) { + if (i != 3 && (hor_req_pixels / pre_down_ratio_x != scaler_w || + vert_req_pixels / pre_down_ratio_y != + scaler_h)) { SDE_ERROR_PLANE(psde, - "roi[%d] roi:%dx%d scaler:%dx%d src:%dx%d rot:%d\n", + "roi[%d] roi:%dx%d scaler:%dx%d src:%dx%d rot:%d pd:%d/%d\n", i, pstate->pixel_ext.roi_w[i], - pstate->pixel_ext.roi_h[i], - scaler_w, scaler_h, src_w, src_h, rot); + pstate->pixel_ext.roi_h[i], scaler_w, scaler_h, + src_w, src_h, rot, pre_down_ratio_x, pre_down_ratio_y); return -EINVAL; } @@ -2393,6 +2423,39 @@ static int _sde_plane_validate_scaler_v2(struct sde_plane *psde, return 0; } +static int _sde_atomic_check_pre_downscale(struct sde_plane *psde, + struct sde_plane_state *pstate, struct sde_rect *dst, + u32 scaler_src_w, u32 scaler_src_h) +{ + int ret = 0; + u32 min_ratio_numer, min_ratio_denom; + + min_ratio_numer = psde->pipe_sblk->in_rot_minpredwnscale_num; + min_ratio_denom = psde->pipe_sblk->in_rot_minpredwnscale_denom; + + if (!(psde->features & BIT(SDE_SSPP_PREDOWNSCALE))) { + SDE_ERROR_PLANE(psde, + "hw does not support pre-downscaler: 0x%x\n", + psde->features); + ret = -EINVAL; + } else if (!min_ratio_numer || !min_ratio_denom) { + SDE_ERROR_PLANE(psde, + "min downscale ratio not set! %u / %u\n", + min_ratio_numer, min_ratio_denom); + ret = -EINVAL; + } else if ((scaler_src_w < mult_frac(dst->w, min_ratio_numer, + min_ratio_denom)) || (scaler_src_h < mult_frac( + dst->h, min_ratio_numer, min_ratio_denom))) { + SDE_ERROR_PLANE(psde, + "failed min downscale check %ux%u->%ux%u, %u/%u\n", + scaler_src_w, scaler_src_h, dst->w, dst->h, + min_ratio_numer, min_ratio_denom); + ret = -EINVAL; + } + + return ret; +} + 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, @@ -2403,7 +2466,7 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, uint32_t scaler_src_w, scaler_src_h; uint32_t max_downscale_num, max_downscale_denom; uint32_t max_upscale, max_linewidth; - bool inline_rotation, rt_client; + bool inline_rotation, rt_client, pre_down_en = false; struct drm_crtc *crtc; struct drm_crtc_state *new_cstate; @@ -2430,16 +2493,25 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, max_upscale = psde->pipe_sblk->maxupscale; max_linewidth = psde->pipe_sblk->maxlinewidth; + if (psde->features & BIT(SDE_SSPP_PREDOWNSCALE)) + pre_down_en = _sde_plane_is_pre_downscale_enabled( + &pstate->pre_down); 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) { + if (rt_client && !pre_down_en) { + max_downscale_num = + psde->pipe_sblk->in_rot_minpredwnscale_num; + max_downscale_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 = @@ -2448,8 +2520,6 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, max_downscale_num = psde->pipe_sblk->in_rot_maxdwnscale_nrt; } - } else { - max_downscale_num = psde->pipe_sblk->maxdwnscale; } /* decimation validation */ @@ -2477,23 +2547,31 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, "invalid src w:%u, deci w:%u, line w:%u\n", src->w, src_deci_w, max_linewidth); ret = -E2BIG; - } /* 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) || (((dst->w * max_downscale_num) / max_downscale_denom) < scaler_src_w) || (((dst->h * max_downscale_num) / max_downscale_denom) < scaler_src_h)) { SDE_ERROR_PLANE(psde, - "too much scaling requested %ux%u->%ux%u rot:%d\n", + "too much scaling %ux%u->%ux%u rot:%d dwn:%d/%d\n", scaler_src_w, scaler_src_h, dst->w, dst->h, - inline_rotation); + inline_rotation, max_downscale_num, + max_downscale_denom); ret = -E2BIG; + + /* check inline pre-downscale support */ + } else if (inline_rotation && pre_down_en && + _sde_atomic_check_pre_downscale(psde, pstate, dst, + scaler_src_w, scaler_src_h)) { + ret = -EINVAL; + + /* QSEED validation */ } else if (_sde_plane_validate_scaler_v2(psde, pstate, fmt, - width, height, - src->w, src->h, deci_w, deci_h)) { + width, height, src->w, src->h, + deci_w, deci_h)) { ret = -EINVAL; } @@ -3571,10 +3649,11 @@ static void _sde_plane_install_properties(struct drm_plane *plane, if (psde->features & BIT(SDE_SSPP_BLOCK_SEC_UI)) sde_kms_info_add_keyint(info, "block_sec_ui", 1); - if (psde->features & BIT(SDE_SSPP_TRUE_INLINE_ROT_V1)) { + if (psde->features & BIT(SDE_SSPP_TRUE_INLINE_ROT)) { const struct sde_format_extended *inline_rot_fmt_list; - sde_kms_info_add_keyint(info, "true_inline_rot_rev", 1); + sde_kms_info_add_keyint(info, "true_inline_rot_rev", + catalog->true_inline_rot_rev); sde_kms_info_add_keyint(info, "true_inline_dwnscale_rt", (int) (psde->pipe_sblk->in_rot_maxdwnscale_rt_num / @@ -3769,6 +3848,15 @@ static inline void _sde_plane_set_scaler_v1(struct sde_plane *psde, SDE_DEBUG_PLANE(psde, "user property data copied\n"); } +static void _sde_plane_clear_predownscale_settings( + struct sde_plane_state *pstate) +{ + pstate->pre_down.pre_downscale_x_0 = 0; + pstate->pre_down.pre_downscale_x_1 = 0; + pstate->pre_down.pre_downscale_y_0 = 0; + pstate->pre_down.pre_downscale_y_1 = 0; +} + static inline void _sde_plane_set_scaler_v2(struct sde_plane *psde, struct sde_plane_state *pstate, void __user *usr) { @@ -3776,6 +3864,7 @@ static inline void _sde_plane_set_scaler_v2(struct sde_plane *psde, struct sde_hw_pixel_ext *pe; int i; struct sde_hw_scaler3_cfg *cfg; + struct sde_hw_inline_pre_downscale_cfg *pd_cfg; if (!psde || !pstate) { SDE_ERROR("invalid argument(s)\n"); @@ -3783,10 +3872,12 @@ static inline void _sde_plane_set_scaler_v2(struct sde_plane *psde, } cfg = &pstate->scaler3_cfg; + pd_cfg = &pstate->pre_down; pstate->scaler_check_state = SDE_PLANE_SCLCHECK_NONE; if (!usr) { SDE_DEBUG_PLANE(psde, "scale data removed\n"); cfg->enable = 0; + _sde_plane_clear_predownscale_settings(pstate); goto end; } @@ -3799,12 +3890,20 @@ static inline void _sde_plane_set_scaler_v2(struct sde_plane *psde, if (!scale_v2.enable) { SDE_DEBUG_PLANE(psde, "scale data removed\n"); cfg->enable = 0; + _sde_plane_clear_predownscale_settings(pstate); goto end; } /* populate from user space */ sde_set_scaler_v2(cfg, &scale_v2); + if (psde->features & BIT(SDE_SSPP_PREDOWNSCALE)) { + pd_cfg->pre_downscale_x_0 = scale_v2.pre_downscale_x_0; + pd_cfg->pre_downscale_x_1 = scale_v2.pre_downscale_x_1; + pd_cfg->pre_downscale_y_0 = scale_v2.pre_downscale_y_0; + pd_cfg->pre_downscale_y_1 = scale_v2.pre_downscale_y_1; + } + pe = &pstate->pixel_ext; memset(pe, 0, sizeof(struct sde_hw_pixel_ext)); @@ -4311,7 +4410,7 @@ static int _sde_plane_init_debugfs(struct drm_plane *plane) psde->debugfs_root, &psde->debugfs_default_scale); - if (cfg->features & BIT(SDE_SSPP_TRUE_INLINE_ROT_V1)) { + if (cfg->features & BIT(SDE_SSPP_TRUE_INLINE_ROT)) { debugfs_create_u32("in_rot_max_downscale_rt_num", 0600, psde->debugfs_root, diff --git a/msm/sde/sde_plane.h b/msm/sde/sde_plane.h index e4a45bfe77..ed16e69d5b 100644 --- a/msm/sde/sde_plane.h +++ b/msm/sde/sde_plane.h @@ -102,6 +102,7 @@ struct sde_plane_state { struct sde_hw_scaler3_cfg scaler3_cfg; struct sde_hw_pixel_ext pixel_ext; enum sde_plane_sclcheck_state scaler_check_state; + struct sde_hw_inline_pre_downscale_cfg pre_down; /* @sc_cfg: system_cache configuration */ struct sde_hw_pipe_sc_cfg sc_cfg;