aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/sde/sde_color_processing.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/sde/sde_color_processing.c')
-rw-r--r--drivers/gpu/drm/msm/sde/sde_color_processing.c71
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;
+ }
+ }
+}