diff --git a/include/uapi/display/drm/sde_drm.h b/include/uapi/display/drm/sde_drm.h index e7095379f2..41e53d2a1c 100644 --- a/include/uapi/display/drm/sde_drm.h +++ b/include/uapi/display/drm/sde_drm.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ @@ -261,6 +262,9 @@ struct sde_drm_de_v1 { /* Disable dynamic expansion */ #define SDE_DYN_EXP_DISABLE 0x1 +#define SDE_DE_LPF_BLEND_FILT +#define SDE_DE_LPF_BLEND_FLAG_EN (1 << 0) + #define SDE_DRM_QSEED3LITE #define SDE_DRM_QSEED4 #define SDE_DRM_INLINE_PREDOWNSCALE @@ -301,6 +305,10 @@ struct sde_drm_de_v1 { * @pre_downscale_x_1 Pre-downscale ratio, x-direction, plane 1(UV) * @pre_downscale_y_0 Pre-downscale ratio, y-direction, plane 0(Y/RGB) * @pre_downscale_y_1 Pre-downscale ratio, y-direction, plane 1(UV) + * @de_lpf_flags: Detail enhancer lpf blned configuration flags + * @de_lpf_h: Detail enhancer lpf blend high + * @de_lpf_l: Detail enhancer lpf blend low + * @de_lpf_m: Detail enhancer lpf blend medium */ struct sde_drm_scaler_v2 { /* @@ -366,6 +374,11 @@ struct sde_drm_scaler_v2 { __u32 pre_downscale_x_1; __u32 pre_downscale_y_0; __u32 pre_downscale_y_1; + + __u32 de_lpf_flags; + __u32 de_lpf_h; + __u32 de_lpf_l; + __u32 de_lpf_m; }; /* Number of dest scalers supported */ diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index ef04800fcb..01c6b5d5b8 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -2442,7 +2442,7 @@ static void _sde_crtc_dest_scaler_setup(struct drm_crtc *crtc) if (cfg->flags & SDE_DRM_DESTSCALER_ENABLE) op_mode |= BIT(hw_ds->idx - DS_0); - if ((i == count-1) && hw_ds->ops.setup_opmode) { + if (hw_ds->ops.setup_opmode) { op_mode |= (cstate->num_ds_enabled == CRTC_DUAL_MIXERS_ONLY) ? SDE_DS_OP_MODE_DUAL : 0; diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 7252734edb..da9dd52460 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -1875,6 +1875,9 @@ static void sde_sspp_set_features(struct sde_mdss_cfg *sde_cfg, if (test_bit(SDE_FEATURE_UBWC_STATS, sde_cfg->features)) set_bit(SDE_SSPP_UBWC_STATS, &sspp->features); + + if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_900)) + set_bit(SDE_SSPP_SCALER_DE_LPF_BLEND, &sspp->features); } } @@ -3087,6 +3090,10 @@ static int sde_ds_parse_dt(struct device_node *np, else if (sde_cfg->qseed_sw_lib_rev == SDE_SSPP_SCALER_QSEED3LITE) set_bit(SDE_SSPP_SCALER_QSEED3LITE, &ds->features); + if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_900)) { + set_bit(SDE_DS_DE_LPF_BLEND, &ds->features); + set_bit(SDE_DS_MERGE_CTRL, &ds->features); + } } end: diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index f6a32b9a1e..13d280e487 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -293,6 +293,7 @@ enum { * @SDE_SSPP_FP16_CSC FP16 CSC color processing block support * @SDE_SSPP_FP16_UNMULT FP16 alpha unmult color processing block support * @SDE_SSPP_UBWC_STATS: Support for ubwc stats + * @SDE_SSPP_SCALER_DE_LPF_BLEND: Support for detail enhancer * @SDE_SSPP_MAX maximum value */ enum { @@ -328,6 +329,7 @@ enum { SDE_SSPP_FP16_CSC, SDE_SSPP_FP16_UNMULT, SDE_SSPP_UBWC_STATS, + SDE_SSPP_SCALER_DE_LPF_BLEND, SDE_SSPP_MAX }; @@ -381,6 +383,18 @@ enum { SDE_MIXER_MAX }; +/** + * Destination scalar features + * @SDE_DS_DE_LPF_BLEND DE_LPF blend supports for destination scalar block + * @SDE_DS_MERGE_CTRL mode operation support for destination scalar block + * @SDE_DS_DE_LPF_MAX maximum value + */ +enum { + SDE_DS_DE_LPF_BLEND = 0x1, + SDE_DS_MERGE_CTRL, + SDE_DS_DE_LPF_MAX +}; + /** * DSPP sub-blocks * @SDE_DSPP_IGC DSPP Inverse gamma correction block diff --git a/msm/sde/sde_hw_ds.c b/msm/sde/sde_hw_ds.c index 55ae3635ca..c6032d2de5 100644 --- a/msm/sde/sde_hw_ds.c +++ b/msm/sde/sde_hw_ds.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ @@ -11,21 +12,36 @@ /* Destination scaler TOP registers */ #define DEST_SCALER_OP_MODE 0x00 #define DEST_SCALER_HW_VERSION 0x10 +#define DEST_SCALER_MERGE_CTRL 0x0C -static void sde_hw_ds_setup_opmode(struct sde_hw_ds *hw_ds, - u32 op_mode) +#define DEST_SCALER_DUAL_PIPE 1 +#define DEST_SCALER_QUAD_PIPE 3 + +static void sde_hw_ds_setup_opmode(struct sde_hw_ds *hw_ds, u32 op_mode) { struct sde_hw_blk_reg_map *hw = &hw_ds->hw; SDE_REG_WRITE(hw, DEST_SCALER_OP_MODE, op_mode); } +static void sde_hw_ds_setup_opmode_v1(struct sde_hw_ds *hw_ds, u32 op_mode) +{ + struct sde_hw_blk_reg_map *hw = &hw_ds->hw; + + if (op_mode & SDE_DS_OP_MODE_DUAL) { + op_mode = DEST_SCALER_DUAL_PIPE; + SDE_REG_WRITE(hw, DEST_SCALER_MERGE_CTRL + hw_ds->scl->base, op_mode); + } +} + static void sde_hw_ds_setup_scaler3(struct sde_hw_ds *hw_ds, void *scaler_cfg, void *scaler_lut_cfg) { struct sde_hw_scaler3_cfg *scl3_cfg = scaler_cfg; struct sde_hw_scaler3_lut_cfg *scl3_lut_cfg = scaler_lut_cfg; + bool de_lpf_en = false; + if (!hw_ds || !hw_ds->scl || !scl3_cfg || !scl3_lut_cfg) return; @@ -41,14 +57,21 @@ static void sde_hw_ds_setup_scaler3(struct sde_hw_ds *hw_ds, scl3_cfg->sep_len = scl3_lut_cfg->sep_len; } + + if (test_bit(SDE_DS_DE_LPF_BLEND, &hw_ds->scl->features)) + de_lpf_en = true; sde_hw_setup_scaler3(&hw_ds->hw, scl3_cfg, hw_ds->scl->version, hw_ds->scl->base, - sde_get_sde_format(DRM_FORMAT_XBGR2101010)); + sde_get_sde_format(DRM_FORMAT_XBGR2101010), de_lpf_en); } static void _setup_ds_ops(struct sde_hw_ds_ops *ops, unsigned long features) { - ops->setup_opmode = sde_hw_ds_setup_opmode; + + if (test_bit(SDE_DS_MERGE_CTRL, &features)) + ops->setup_opmode = sde_hw_ds_setup_opmode_v1; + else + ops->setup_opmode = sde_hw_ds_setup_opmode; if (test_bit(SDE_SSPP_SCALER_QSEED3, &features) || test_bit(SDE_SSPP_SCALER_QSEED3LITE, &features)) diff --git a/msm/sde/sde_hw_sspp.c b/msm/sde/sde_hw_sspp.c index 859915fc51..2276de5c20 100644 --- a/msm/sde/sde_hw_sspp.c +++ b/msm/sde/sde_hw_sspp.c @@ -760,6 +760,7 @@ static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx, void *scaler_cfg) { u32 idx; + bool de_lpf_en = false; struct sde_hw_scaler3_cfg *scaler3_cfg = scaler_cfg; (void)pe; @@ -767,8 +768,11 @@ static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx, || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk) return; + if (test_bit(SDE_SSPP_SCALER_DE_LPF_BLEND, &ctx->cap->features)) + de_lpf_en = true; + sde_hw_setup_scaler3(&ctx->hw, scaler3_cfg, - ctx->cap->sblk->scaler_blk.version, idx, sspp->layout.format); + ctx->cap->sblk->scaler_blk.version, idx, sspp->layout.format, de_lpf_en); } static void sde_hw_sspp_setup_pre_downscale(struct sde_hw_pipe *ctx, diff --git a/msm/sde/sde_hw_util.c b/msm/sde/sde_hw_util.c index f0ad45b47a..2dd798e728 100644 --- a/msm/sde/sde_hw_util.c +++ b/msm/sde/sde_hw_util.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -30,6 +31,7 @@ static u32 sde_hw_util_log_mask = SDE_DBG_MASK_NONE; #define QSEED3_DE_ADJUST_DATA_0 0x34 #define QSEED3_DE_ADJUST_DATA_1 0x38 #define QSEED3_DE_ADJUST_DATA_2 0x3C +#define QSEED3_DE_LPF_BLEND 0x64 #define QSEED3_SRC_SIZE_Y_RGB_A 0x40 #define QSEED3_SRC_SIZE_UV 0x44 #define QSEED3_DST_SIZE 0x48 @@ -152,6 +154,9 @@ void sde_set_scaler_v2(struct sde_hw_scaler3_cfg *cfg, cfg->de.thr_low = scale_v2->de.thr_low; cfg->de.thr_high = scale_v2->de.thr_high; cfg->de.blend = scale_v2->de_blend; + cfg->de_lpf_h = scale_v2->de_lpf_h; + cfg->de_lpf_l = scale_v2->de_lpf_l; + cfg->de_lpf_m = scale_v2->de_lpf_m; for (i = 0; i < SDE_MAX_DE_CURVES; i++) { cfg->de.adjust_a[i] = scale_v2->de.adjust_a[i]; @@ -348,11 +353,12 @@ static inline scaler_lut_type get_scaler_lut( void sde_hw_setup_scaler3(struct sde_hw_blk_reg_map *c, struct sde_hw_scaler3_cfg *scaler3_cfg, u32 scaler_version, - u32 scaler_offset, const struct sde_format *format) + u32 scaler_offset, const struct sde_format *format, bool de_lpf) { u32 op_mode = 0; u32 phase_init, preload, src_y_rgb, src_uv, dst; scaler_lut_type setup_lut = NULL; + u32 de_lpf_blend = 0; if (!scaler3_cfg->enable) goto end; @@ -431,6 +437,13 @@ void sde_hw_setup_scaler3(struct sde_hw_blk_reg_map *c, SDE_REG_WRITE(c, QSEED3_DST_SIZE + scaler_offset, dst); + if (de_lpf && (scaler3_cfg->de_lpf_flags & SDE_DYN_EXP_DISABLE)) { + de_lpf_blend = (scaler3_cfg->de_lpf_h & 0x3FF) | + ((scaler3_cfg->de_lpf_l & 0x3FF) << 10) | + ((scaler3_cfg->de_lpf_m & 0x3FF) << 20); + SDE_REG_WRITE(c, QSEED3_DE_LPF_BLEND, de_lpf_blend); + } + end: if (format && !SDE_FORMAT_IS_DX(format)) op_mode |= BIT(14); diff --git a/msm/sde/sde_hw_util.h b/msm/sde/sde_hw_util.h index b07876dde1..730cd64703 100644 --- a/msm/sde/sde_hw_util.h +++ b/msm/sde/sde_hw_util.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -109,6 +110,10 @@ struct sde_hw_scaler3_de_cfg { * @ de: detail enhancer configuration * @ dir_weight: Directional Weight * @dyn_exp_disabled: Dynamic expansion disabled + * @de_lpf_flags: Detail enhancer lpf blned configuration flags + * @de_lpf_h: Detail enhancer lpf blend high + * @de_lpf_l: Detail enhancer lpf blend low + * @de_lpf_m: Detail enhancer lpf blend medium */ struct sde_hw_scaler3_cfg { u32 enable; @@ -151,6 +156,11 @@ struct sde_hw_scaler3_cfg { struct sde_hw_scaler3_de_cfg de; uint32_t dir_weight; uint32_t dyn_exp_disabled; + + __u32 de_lpf_flags; + __u32 de_lpf_h; + __u32 de_lpf_l; + __u32 de_lpf_m; }; struct sde_hw_scaler3_lut_cfg { @@ -197,7 +207,7 @@ void sde_set_scaler_v2(struct sde_hw_scaler3_cfg *cfg, void sde_hw_setup_scaler3(struct sde_hw_blk_reg_map *c, struct sde_hw_scaler3_cfg *scaler3_cfg, u32 scaler_version, - u32 scaler_offset, const struct sde_format *format); + u32 scaler_offset, const struct sde_format *format, bool de_lpf); void sde_hw_csc_matrix_coeff_setup(struct sde_hw_blk_reg_map *c, u32 csc_reg_off, struct sde_csc_cfg *data,