diff options
Diffstat (limited to 'drivers/gpu/drm/msm/sde/sde_color_processing.c')
-rw-r--r-- | drivers/gpu/drm/msm/sde/sde_color_processing.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c index 8dc31d1e0872..0faae5a551bc 100644 --- a/drivers/gpu/drm/msm/sde/sde_color_processing.c +++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c @@ -88,6 +88,7 @@ static void sde_cp_ad_set_prop(struct sde_crtc *sde_crtc, enum ad_property ad_prop); static void sde_cp_notify_hist_event(struct drm_crtc *crtc_drm, void *arg); +static void sde_cp_update_ad_vsync_prop(struct sde_crtc *sde_crtc, u32 val); #define setup_dspp_prop_install_funcs(func) \ do { \ @@ -138,6 +139,7 @@ enum { SDE_CP_CRTC_DSPP_AD_ASSERTIVENESS, SDE_CP_CRTC_DSPP_AD_BACKLIGHT, SDE_CP_CRTC_DSPP_AD_STRENGTH, + SDE_CP_CRTC_DSPP_AD_VSYNC_COUNT, SDE_CP_CRTC_DSPP_MAX, /* DSPP features end */ @@ -407,6 +409,7 @@ void sde_cp_crtc_init(struct drm_crtc *crtc) if (IS_ERR(sde_crtc->hist_blob)) sde_crtc->hist_blob = NULL; + sde_crtc->ad_vsync_count = 0; mutex_init(&sde_crtc->crtc_cp_lock); INIT_LIST_HEAD(&sde_crtc->active_list); INIT_LIST_HEAD(&sde_crtc->dirty_list); @@ -789,6 +792,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, ad_cfg.prop = AD_MODE; ad_cfg.hw_cfg = &hw_cfg; hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg); + sde_crtc->ad_vsync_count = 0; + sde_cp_update_ad_vsync_prop(sde_crtc, + sde_crtc->ad_vsync_count); break; case SDE_CP_CRTC_DSPP_AD_INIT: if (!hw_dspp || !hw_dspp->ops.setup_ad) { @@ -798,6 +804,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, ad_cfg.prop = AD_INIT; ad_cfg.hw_cfg = &hw_cfg; hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg); + sde_crtc->ad_vsync_count = 0; + sde_cp_update_ad_vsync_prop(sde_crtc, + sde_crtc->ad_vsync_count); break; case SDE_CP_CRTC_DSPP_AD_CFG: if (!hw_dspp || !hw_dspp->ops.setup_ad) { @@ -807,6 +816,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, ad_cfg.prop = AD_CFG; ad_cfg.hw_cfg = &hw_cfg; hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg); + sde_crtc->ad_vsync_count = 0; + sde_cp_update_ad_vsync_prop(sde_crtc, + sde_crtc->ad_vsync_count); break; case SDE_CP_CRTC_DSPP_AD_INPUT: if (!hw_dspp || !hw_dspp->ops.setup_ad) { @@ -816,6 +828,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, ad_cfg.prop = AD_INPUT; ad_cfg.hw_cfg = &hw_cfg; hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg); + sde_crtc->ad_vsync_count = 0; + sde_cp_update_ad_vsync_prop(sde_crtc, + sde_crtc->ad_vsync_count); break; case SDE_CP_CRTC_DSPP_AD_ASSERTIVENESS: if (!hw_dspp || !hw_dspp->ops.setup_ad) { @@ -825,6 +840,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, ad_cfg.prop = AD_ASSERTIVE; ad_cfg.hw_cfg = &hw_cfg; hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg); + sde_crtc->ad_vsync_count = 0; + sde_cp_update_ad_vsync_prop(sde_crtc, + sde_crtc->ad_vsync_count); break; case SDE_CP_CRTC_DSPP_AD_BACKLIGHT: if (!hw_dspp || !hw_dspp->ops.setup_ad) { @@ -834,6 +852,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, ad_cfg.prop = AD_BACKLIGHT; ad_cfg.hw_cfg = &hw_cfg; hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg); + sde_crtc->ad_vsync_count = 0; + sde_cp_update_ad_vsync_prop(sde_crtc, + sde_crtc->ad_vsync_count); break; case SDE_CP_CRTC_DSPP_AD_STRENGTH: if (!hw_dspp || !hw_dspp->ops.setup_ad) { @@ -843,6 +864,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, ad_cfg.prop = AD_STRENGTH; ad_cfg.hw_cfg = &hw_cfg; hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg); + sde_crtc->ad_vsync_count = 0; + sde_cp_update_ad_vsync_prop(sde_crtc, + sde_crtc->ad_vsync_count); break; default: ret = -EINVAL; @@ -924,10 +948,15 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) DRM_DEBUG_DRIVER("Dirty list is empty\n"); goto exit; } - sde_cp_ad_set_prop(sde_crtc, AD_IPC_RESET); set_dspp_flush = true; } + if (!list_empty(&sde_crtc->ad_active)) { + sde_cp_ad_set_prop(sde_crtc, AD_IPC_RESET); + sde_cp_ad_set_prop(sde_crtc, AD_VSYNC_UPDATE); + sde_cp_update_ad_vsync_prop(sde_crtc, sde_crtc->ad_vsync_count); + } + list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list, dirty_list) { sde_dspp_feature = crtc_feature_map[prop_node->feature]; @@ -1444,6 +1473,9 @@ static void dspp_ad_install_property(struct drm_crtc *crtc) "SDE_DSPP_AD_V4_BACKLIGHT", SDE_CP_CRTC_DSPP_AD_BACKLIGHT, 0, (BIT(16) - 1), 0); + sde_cp_crtc_install_range_property(crtc, + "SDE_DSPP_AD_V4_VSYNC_COUNT", + SDE_CP_CRTC_DSPP_AD_VSYNC_COUNT, 0, U32_MAX, 0); break; default: DRM_ERROR("version %d not supported\n", version); @@ -1862,6 +1894,11 @@ static void sde_cp_ad_set_prop(struct sde_crtc *sde_crtc, hw_cfg.displayh = num_mixers * hw_lm->cfg.out_width; hw_cfg.displayv = hw_lm->cfg.out_height; hw_cfg.mixer_info = hw_lm; + + if (ad_prop == AD_VSYNC_UPDATE) { + hw_cfg.payload = &sde_crtc->ad_vsync_count; + hw_cfg.len = sizeof(sde_crtc->ad_vsync_count); + } ad_cfg.prop = ad_prop; ad_cfg.hw_cfg = &hw_cfg; ret = hw_dspp->ops.validate_ad(hw_dspp, (u32 *)&ad_prop); @@ -2113,3 +2150,35 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en, exit: return ret; } + +void sde_cp_update_ad_vsync_count(struct drm_crtc *crtc, u32 val) +{ + struct sde_crtc *sde_crtc; + + if (!crtc) { + DRM_ERROR("invalid crtc %pK\n", crtc); + return; + } + + sde_crtc = to_sde_crtc(crtc); + if (!sde_crtc) { + DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc); + return; + } + + sde_crtc->ad_vsync_count = val; + sde_cp_update_ad_vsync_prop(sde_crtc, val); +} + +static void sde_cp_update_ad_vsync_prop(struct sde_crtc *sde_crtc, u32 val) +{ + struct sde_cp_node *prop_node = NULL; + + list_for_each_entry(prop_node, &sde_crtc->feature_list, feature_list) { + if (prop_node->feature == SDE_CP_CRTC_DSPP_AD_VSYNC_COUNT) { + prop_node->prop_val = val; + pr_debug("AD vsync count updated to %d\n", val); + return; + } + } +} |