From 98821c438468394fbf0f7f84dbca3c843d0adcca Mon Sep 17 00:00:00 2001 From: Ping Li Date: Wed, 8 Jul 2020 15:20:14 -0700 Subject: [PATCH] disp: msm: sde: add handoff implementation for color processing features Add handoff implementation for color processing features when switching from primary VM to trusted VM. Change-Id: I9c3a168f70f3981e912bf37533f212880ab30924 Signed-off-by: Ping Li --- msm/sde/sde_color_processing.c | 80 ++++++++++++++++++++++++++++++++++ msm/sde/sde_color_processing.h | 8 ++++ msm/sde/sde_crtc.c | 6 ++- msm/sde/sde_kms.c | 6 +++ 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index c628b450ff90..7ec9f5cf4317 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -195,6 +195,21 @@ static enum sde_cp_crtc_pu_features (enum sde_cp_crtc_pu_features) SDE_CP_CRTC_DSPP_RC_MASK, }; +/* explicitly set the features that needs to be treated during handoff */ +static bool feature_handoff_mask[SDE_CP_CRTC_MAX_FEATURES] = { + [SDE_CP_CRTC_DSPP_IGC] = 1, + [SDE_CP_CRTC_DSPP_PCC] = 1, + [SDE_CP_CRTC_DSPP_GC] = 1, + [SDE_CP_CRTC_DSPP_HSIC] = 1, + [SDE_CP_CRTC_DSPP_MEMCOL_SKIN] = 1, + [SDE_CP_CRTC_DSPP_MEMCOL_SKY] = 1, + [SDE_CP_CRTC_DSPP_MEMCOL_FOLIAGE] = 1, + [SDE_CP_CRTC_DSPP_MEMCOL_PROT] = 1, + [SDE_CP_CRTC_DSPP_SIXZONE] = 1, + [SDE_CP_CRTC_DSPP_GAMUT] = 1, + [SDE_CP_CRTC_DSPP_DITHER] = 1, +}; + static void _sde_cp_crtc_enable_hist_irq(struct sde_crtc *sde_crtc); typedef int (*feature_wrapper)(struct sde_hw_dspp *hw_dspp, @@ -4144,3 +4159,68 @@ void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm) } mutex_unlock(&crtc->crtc_cp_lock); } + +/* this func needs to be called within crtc_cp_lock mutex */ +static bool _sde_cp_feature_in_dirtylist(u32 feature, struct list_head *list) +{ + struct sde_cp_node *node = NULL; + + list_for_each_entry(node, list, dirty_list) { + if (feature == node->feature) + return true; + } + + return false; +} + +/* this func needs to be called within crtc_cp_lock mutex */ +static bool _sde_cp_feature_in_activelist(u32 feature, struct list_head *list) +{ + struct sde_cp_node *node = NULL; + + list_for_each_entry(node, list, active_list) { + if (feature == node->feature) + return true; + } + + return false; +} + +void sde_cp_crtc_vm_primary_handoff(struct drm_crtc *crtc) +{ + struct sde_crtc *sde_crtc = NULL; + struct sde_cp_node *prop_node = NULL; + + if (!crtc) { + DRM_ERROR("crtc %pK\n", crtc); + return; + } + + sde_crtc = to_sde_crtc(crtc); + if (!sde_crtc) { + DRM_ERROR("sde_crtc %pK\n", sde_crtc); + return; + } + + mutex_lock(&sde_crtc->crtc_cp_lock); + + list_for_each_entry(prop_node, &sde_crtc->feature_list, feature_list) { + if (!feature_handoff_mask[prop_node->feature]) + continue; + + if (_sde_cp_feature_in_dirtylist(prop_node->feature, + &sde_crtc->dirty_list)) + continue; + + if (_sde_cp_feature_in_activelist(prop_node->feature, + &sde_crtc->active_list)) { + sde_cp_update_list(prop_node, sde_crtc, true); + list_del_init(&prop_node->active_list); + continue; + } + + sde_cp_update_list(prop_node, sde_crtc, true); + } + + mutex_unlock(&sde_crtc->crtc_cp_lock); +} diff --git a/msm/sde/sde_color_processing.h b/msm/sde/sde_color_processing.h index 45f7781cb32d..ef943c3358df 100644 --- a/msm/sde/sde_color_processing.h +++ b/msm/sde/sde_color_processing.h @@ -205,4 +205,12 @@ int sde_cp_ltm_off_event_handler(struct drm_crtc *crtc_drm, bool en, * @crtc_drm: Pointer to crtc. */ void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm); + +/** + * sde_cp_crtc_vm_primary_handoff: Properly handoff CRTC color mode features + * when switching from primary VM to trusted VM + * @crtc: Pointer to crtc. + */ +void sde_cp_crtc_vm_primary_handoff(struct drm_crtc *crtc); + #endif /*_SDE_COLOR_PROCESSING_H */ diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 43fe3530164b..7fbf1c163a66 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -3202,7 +3202,7 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_device *dev; struct sde_kms *sde_kms; struct sde_splash_display *splash_display; - bool cont_splash_enabled = false; + bool cont_splash_enabled = false, apply_cp_prop = false; size_t i; if (!crtc) { @@ -3274,8 +3274,10 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, cont_splash_enabled = true; } + apply_cp_prop = sde_kms->catalog->trusted_vm_env ? + true : sde_crtc->enabled; if (sde_kms_is_cp_operation_allowed(sde_kms) && - (cont_splash_enabled || sde_crtc->enabled)) + (cont_splash_enabled || apply_cp_prop)) sde_cp_crtc_apply_properties(crtc); /* diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 34f7b72c2750..65ac88e70842 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -46,6 +46,7 @@ #include "sde_encoder.h" #include "sde_plane.h" #include "sde_crtc.h" +#include "sde_color_processing.h" #include "sde_reg_dma.h" #include "sde_connector.h" #include "sde_vm.h" @@ -1321,6 +1322,7 @@ int sde_kms_vm_primary_post_commit(struct sde_kms *sde_kms, { struct sde_vm_ops *vm_ops; struct sde_crtc_state *cstate; + struct drm_crtc *crtc; enum sde_crtc_vm_req vm_req; int rc = 0; @@ -1329,6 +1331,7 @@ int sde_kms_vm_primary_post_commit(struct sde_kms *sde_kms, vm_ops = &sde_kms->vm->vm_ops; + crtc = state->crtcs[0].ptr; cstate = to_sde_crtc_state(state->crtcs[0].new_state); vm_req = sde_crtc_get_property(cstate, CRTC_PROP_VM_REQ_STATE); @@ -1338,6 +1341,9 @@ int sde_kms_vm_primary_post_commit(struct sde_kms *sde_kms, /* handle SDE pre-release */ sde_kms_vm_pre_release(sde_kms, state); + /* properly handoff color processing features */ + sde_cp_crtc_vm_primary_handoff(crtc); + /* program the current drm mode info to scratch reg */ _sde_kms_program_mode_info(sde_kms);