diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index 2ba508928790..ac2310062aca 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -72,13 +72,14 @@ static void dspp_hist_install_property(struct drm_crtc *crtc); static void dspp_dither_install_property(struct drm_crtc *crtc); +static void dspp_demura_install_property(struct drm_crtc *crtc); + typedef void (*dspp_prop_install_func_t)(struct drm_crtc *crtc); static dspp_prop_install_func_t dspp_prop_install_func[SDE_DSPP_MAX]; static void sde_cp_update_list(struct sde_cp_node *prop_node, struct sde_crtc *crtc, bool dirty_list); - static int sde_cp_ad_validate_prop(struct sde_cp_node *prop_node, struct sde_crtc *crtc); @@ -118,6 +119,7 @@ do { \ func[SDE_DSPP_HIST] = dspp_hist_install_property; \ func[SDE_DSPP_DITHER] = dspp_dither_install_property; \ func[SDE_DSPP_RC] = dspp_rc_install_property; \ + func[SDE_DSPP_DEMURA] = dspp_demura_install_property; \ } while (0) typedef void (*lm_prop_install_func_t)(struct drm_crtc *crtc); @@ -168,6 +170,8 @@ enum sde_cp_crtc_features { SDE_CP_CRTC_DSPP_SB, SDE_CP_CRTC_DSPP_RC_MASK, SDE_CP_CRTC_DSPP_SPR_INIT, + SDE_CP_CRTC_DSPP_DEMURA_INIT, + SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT, SDE_CP_CRTC_DSPP_MAX, /* DSPP features end */ @@ -2741,6 +2745,31 @@ static void dspp_dither_install_property(struct drm_crtc *crtc) } } +static void dspp_demura_install_property(struct drm_crtc *crtc) +{ + struct sde_kms *kms = NULL; + struct sde_mdss_cfg *catalog = NULL; + u32 version; + + kms = get_kms(crtc); + catalog = kms->catalog; + + version = catalog->dspp[0].sblk->demura.version >> 28; + switch (version) { + case 1: + sde_cp_crtc_install_blob_property(crtc, "DEMURA_INIT_V1", + SDE_CP_CRTC_DSPP_DEMURA_INIT, + sizeof(struct drm_msm_dem_cfg)); + sde_cp_crtc_install_range_property(crtc, "DEMURA_BACKLIGHT", + SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT, + 0, 1024, 0); + break; + default: + DRM_ERROR("version %d not supported\n", version); + break; + } +} + static void sde_cp_update_list(struct sde_cp_node *prop_node, struct sde_crtc *crtc, bool dirty_list) { diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 20d8fa78f465..44d08f596f4d 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -407,6 +407,13 @@ enum { SPR_PROP_MAX, }; +enum { + DEMURA_OFF, + DEMURA_LEN, + DEMURA_VERSION, + DEMURA_PROP_MAX, +}; + enum { MIXER_OFF, MIXER_LEN, @@ -872,6 +879,15 @@ static struct sde_prop_type limit_usecase_prop[] = { PROP_TYPE_BIT_OFFSET_ARRAY}, }; +static struct sde_prop_type demura_prop[] = { + [DEMURA_OFF] = {DEMURA_OFF, "qcom,sde-dspp-demura-off", false, + PROP_TYPE_U32_ARRAY}, + [DEMURA_LEN] = {DEMURA_LEN, "qcom,sde-dspp-demura-size", false, + PROP_TYPE_U32}, + [DEMURA_VERSION] = {DEMURA_VERSION, "qcom,sde-dspp-demura-version", + false, PROP_TYPE_U32}, +}; + /************************************************************* * static API list *************************************************************/ @@ -2529,6 +2545,46 @@ end: return rc; } +static int _sde_dspp_demura_parse_dt(struct device_node *np, + struct sde_mdss_cfg *sde_cfg) +{ + int off_count, i; + struct sde_dt_props *props; + struct sde_dspp_cfg *dspp; + struct sde_dspp_sub_blks *sblk; + + props = sde_get_dt_props(np, DEMURA_PROP_MAX, demura_prop, + ARRAY_SIZE(demura_prop), &off_count); + if (IS_ERR(props)) + return PTR_ERR(props); + + sde_cfg->demura_count = off_count; + if (off_count > sde_cfg->dspp_count) { + SDE_ERROR("limiting %d demura blocks to %d DSPP instances\n", + off_count, sde_cfg->dspp_count); + sde_cfg->demura_count = sde_cfg->dspp_count; + } + + for (i = 0; i < sde_cfg->dspp_count; i++) { + dspp = &sde_cfg->dspp[i]; + sblk = sde_cfg->dspp[i].sblk; + + sblk->demura.id = SDE_DSPP_DEMURA; + if (props->exists[DEMURA_OFF] && i < off_count) { + sblk->demura.base = PROP_VALUE_ACCESS(props->values, + DEMURA_OFF, i); + sblk->demura.len = PROP_VALUE_ACCESS(props->values, + DEMURA_LEN, 0); + sblk->demura.version = PROP_VALUE_ACCESS(props->values, + DEMURA_VERSION, 0); + set_bit(SDE_DSPP_DEMURA, &dspp->features); + } + } + + sde_put_dt_props(props); + return 0; +} + static int _sde_dspp_spr_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) { @@ -2753,6 +2809,10 @@ static int sde_dspp_parse_dt(struct device_node *np, if (rc) goto end; + rc = _sde_dspp_demura_parse_dt(np, sde_cfg); + if (rc) + goto end; + rc = _sde_rc_parse_dt(np, sde_cfg); end: return rc; @@ -4510,7 +4570,7 @@ static void _sde_hw_setup_uidle(struct sde_uidle_cfg *uidle_cfg) static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) { - int rc = 0; + int rc = 0, i; if (!sde_cfg) return -EINVAL; @@ -4519,6 +4579,11 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->has_mixer_combined_alpha = true; sde_cfg->mdss_hw_block_size = DEFAULT_MDSS_HW_BLOCK_SIZE; + for (i = 0; i < SSPP_MAX; i++) { + sde_cfg->demura_supported[i][0] = ~0x0; + sde_cfg->demura_supported[i][1] = ~0x0; + } + /* target specific settings */ if (IS_MSM8996_TARGET(hw_rev)) { sde_cfg->perf.min_prefill_lines = 21; @@ -4685,6 +4750,10 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->vbif_disable_inner_outer_shareable = true; } else if (IS_LAHAINA_TARGET(hw_rev)) { sde_cfg->has_demura = true; + sde_cfg->demura_supported[SSPP_DMA1][0] = 0; + sde_cfg->demura_supported[SSPP_DMA1][1] = 1; + sde_cfg->demura_supported[SSPP_DMA3][0] = 0; + sde_cfg->demura_supported[SSPP_DMA3][1] = 1; sde_cfg->has_cwb_support = true; sde_cfg->has_wb_ubwc = true; sde_cfg->has_qsync = true; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 58f6b2a80f44..6fae2cc26148 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -770,6 +770,7 @@ struct sde_dspp_sub_blks { struct sde_pp_blk spr; struct sde_pp_blk vlut; struct sde_dspp_rc rc; + struct sde_pp_blk demura; }; struct sde_pingpong_sub_blks { @@ -1418,6 +1419,7 @@ struct sde_limit_cfg { * @inline_disable_const_clr Disable constant color during inline rotate * @dither_luma_mode_support Enables dither luma mode * @has_base_layer Supports staging layer as base layer + * @demura_supported Demura pipe support flag(~0x00 - Not supported) * @sc_cfg: system cache configuration * @uidle_cfg Settings for uidle feature * @sui_misr_supported indicate if secure-ui-misr is supported @@ -1436,6 +1438,7 @@ struct sde_limit_cfg { * @inline_rot_formats formats supported by the inline rotator feature * @irq_offset_list list of sde_intr_irq_offsets to initialize irq table * @rc_count number of rounded corner hardware instances + * @demura_count number of demura hardware instances */ struct sde_mdss_cfg { u32 hwversion; @@ -1481,6 +1484,7 @@ struct sde_mdss_cfg { bool dither_luma_mode_support; bool has_base_layer; bool has_demura; + u32 demura_supported[SSPP_MAX][2]; struct sde_sc_cfg sc_cfg; @@ -1552,6 +1556,7 @@ struct sde_mdss_cfg { u32 ltm_count; u32 rc_count; u32 spr_count; + u32 demura_count; u32 merge_3d_count; struct sde_merge_3d_cfg merge_3d[MAX_BLOCKS]; diff --git a/msm/sde/sde_hw_dspp.c b/msm/sde/sde_hw_dspp.c index a349abcbfa77..09de82b7e6ea 100644 --- a/msm/sde/sde_hw_dspp.c +++ b/msm/sde/sde_hw_dspp.c @@ -390,6 +390,16 @@ struct sde_hw_dspp *sde_hw_dspp_init(enum sde_dspp idx, c->hw.blk_off + cfg->sblk->spr.base + cfg->sblk->spr.len, c->hw.xin_id); } + + if ((cfg->sblk->demura.id == SDE_DSPP_DEMURA) && + cfg->sblk->demura.base) { + snprintf(buf, ARRAY_SIZE(buf), "%s_%d", "demura", + c->idx - DSPP_0); + sde_dbg_reg_register_dump_range(SDE_DBG_NAME, buf, + c->hw.blk_off + cfg->sblk->demura.base, + c->hw.blk_off + cfg->sblk->demura.base + + cfg->sblk->demura.len, c->hw.xin_id); + } return c; blk_init_error: diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index c03171bdd5a8..298c20310e61 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -3444,6 +3444,7 @@ static void _sde_plane_install_properties(struct drm_plane *plane, int zpos_max = 255; int zpos_def = 0; char feature_name[256]; + uint32_t index; if (!plane || !psde) { SDE_ERROR("invalid plane\n"); @@ -3562,6 +3563,10 @@ static void _sde_plane_install_properties(struct drm_plane *plane, psde->pipe_sblk->max_per_pipe_bw * 1000LL); sde_kms_info_add_keyint(info, "max_per_pipe_bw_high", psde->pipe_sblk->max_per_pipe_bw_high * 1000LL); + index = (master_plane_id == 0) ? 0 : 1; + if (catalog->has_demura && + catalog->demura_supported[psde->pipe][index] != ~0x0) + sde_kms_info_add_keyint(info, "demura_block", index); if ((is_master && (psde->features & BIT(SDE_SSPP_INVERSE_PMA))) ||