Loading drivers/gpu/drm/msm/sde/sde_ad4.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ enum ad_property { AD_IPC_SUSPEND, AD_IPC_RESUME, AD_IPC_RESET, AD_VSYNC_UPDATE, AD_PROPMAX, }; Loading drivers/gpu/drm/msm/sde/sde_color_processing.c +70 −1 Original line number Diff line number Diff line Loading @@ -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 { \ Loading Loading @@ -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 */ Loading Loading @@ -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); Loading Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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; Loading Loading @@ -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]; Loading Loading @@ -1449,6 +1478,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); Loading Loading @@ -1867,6 +1899,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); Loading Loading @@ -2118,3 +2155,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; } } } drivers/gpu/drm/msm/sde/sde_color_processing.h +8 −1 Original line number Diff line number Diff line /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -146,4 +146,11 @@ void sde_cp_crtc_post_ipc(struct drm_crtc *crtc); */ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en, struct sde_irq_callback *hist_irq); /** * sde_cp_update_ad_vsync_count: Api to update AD vsync count * @crtc: Pointer to crtc. * @val: vsync count value */ void sde_cp_update_ad_vsync_count(struct drm_crtc *crtc, u32 val); #endif /*_SDE_COLOR_PROCESSING_H */ drivers/gpu/drm/msm/sde/sde_crtc.c +1 −0 Original line number Diff line number Diff line Loading @@ -4144,6 +4144,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) event.type = DRM_EVENT_CRTC_POWER; event.length = sizeof(u32); sde_cp_crtc_suspend(crtc); sde_cp_update_ad_vsync_count(crtc, 0); power_on = 0; msm_mode_object_event_notify(&crtc->base, crtc->dev, &event, (u8 *)&power_on); Loading drivers/gpu/drm/msm/sde/sde_crtc.h +2 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ struct sde_crtc_event { * @dirty_list : list of color processing features are dirty * @ad_dirty: list containing ad properties that are dirty * @ad_active: list containing ad properties that are active * @ad_vsync_count : count of vblank since last reset for AD * @crtc_lock : crtc lock around create, destroy and access. * @frame_pending : Whether or not an update is pending * @frame_events : static allocation of in-flight frame events Loading Loading @@ -224,6 +225,7 @@ struct sde_crtc { struct list_head ad_dirty; struct list_head ad_active; struct list_head user_event_list; u32 ad_vsync_count; struct mutex crtc_lock; struct mutex crtc_cp_lock; Loading Loading
drivers/gpu/drm/msm/sde/sde_ad4.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ enum ad_property { AD_IPC_SUSPEND, AD_IPC_RESUME, AD_IPC_RESET, AD_VSYNC_UPDATE, AD_PROPMAX, }; Loading
drivers/gpu/drm/msm/sde/sde_color_processing.c +70 −1 Original line number Diff line number Diff line Loading @@ -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 { \ Loading Loading @@ -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 */ Loading Loading @@ -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); Loading Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading @@ -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; Loading Loading @@ -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]; Loading Loading @@ -1449,6 +1478,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); Loading Loading @@ -1867,6 +1899,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); Loading Loading @@ -2118,3 +2155,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; } } }
drivers/gpu/drm/msm/sde/sde_color_processing.h +8 −1 Original line number Diff line number Diff line /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -146,4 +146,11 @@ void sde_cp_crtc_post_ipc(struct drm_crtc *crtc); */ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en, struct sde_irq_callback *hist_irq); /** * sde_cp_update_ad_vsync_count: Api to update AD vsync count * @crtc: Pointer to crtc. * @val: vsync count value */ void sde_cp_update_ad_vsync_count(struct drm_crtc *crtc, u32 val); #endif /*_SDE_COLOR_PROCESSING_H */
drivers/gpu/drm/msm/sde/sde_crtc.c +1 −0 Original line number Diff line number Diff line Loading @@ -4144,6 +4144,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) event.type = DRM_EVENT_CRTC_POWER; event.length = sizeof(u32); sde_cp_crtc_suspend(crtc); sde_cp_update_ad_vsync_count(crtc, 0); power_on = 0; msm_mode_object_event_notify(&crtc->base, crtc->dev, &event, (u8 *)&power_on); Loading
drivers/gpu/drm/msm/sde/sde_crtc.h +2 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ struct sde_crtc_event { * @dirty_list : list of color processing features are dirty * @ad_dirty: list containing ad properties that are dirty * @ad_active: list containing ad properties that are active * @ad_vsync_count : count of vblank since last reset for AD * @crtc_lock : crtc lock around create, destroy and access. * @frame_pending : Whether or not an update is pending * @frame_events : static allocation of in-flight frame events Loading Loading @@ -224,6 +225,7 @@ struct sde_crtc { struct list_head ad_dirty; struct list_head ad_active; struct list_head user_event_list; u32 ad_vsync_count; struct mutex crtc_lock; struct mutex crtc_cp_lock; Loading