ソースを参照

Merge "disp: msm: sde: handle rc feature disable for all instances"

qctecmdr 2 年 前
コミット
bd05d05fc2
1 ファイル変更69 行追加2 行削除
  1. 69 2
      msm/sde/sde_color_processing.c

+ 69 - 2
msm/sde/sde_color_processing.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -713,6 +713,37 @@ static int _set_ltm_hist_crtl_feature(struct sde_hw_dspp *hw_dspp,
 	return ret;
 }
 
+static int _disable_rc_mask_feature(struct sde_hw_dspp *hw_dspp,
+				 struct sde_hw_cp_cfg *hw_cfg,
+				 struct sde_crtc *sde_crtc)
+{
+	int ret = 0;
+
+	if (!hw_dspp || !hw_cfg || !sde_crtc) {
+		DRM_ERROR("invalid arguments");
+		return -EINVAL;
+	}
+
+	if (!hw_dspp->ops.setup_rc_mask) {
+		DRM_ERROR("invalid rc ops\n");
+		return -EINVAL;
+	}
+
+	DRM_DEBUG_DRIVER("dspp %d setup mask for rc instance %u\n",
+			hw_dspp->idx, hw_dspp->cap->sblk->rc.idx);
+
+	/* send empty payload to disable rc feature */
+	hw_cfg->len = 0;
+	hw_cfg->payload = NULL;
+	ret = hw_dspp->ops.setup_rc_mask(hw_dspp, hw_cfg);
+
+	if (ret)
+		DRM_ERROR("failed to disable rc feature, ret %d\n", ret);
+
+	_update_pu_feature_enable(sde_crtc, SDE_CP_CRTC_DSPP_RC_PU, false);
+	return ret;
+}
+
 static int _check_rc_mask_feature(struct sde_hw_dspp *hw_dspp,
 				 struct sde_hw_cp_cfg *hw_cfg,
 				 struct sde_crtc *sde_crtc)
@@ -1006,6 +1037,13 @@ static int _feature_unsupported(struct sde_hw_dspp *hw_dspp,
 	return 0;
 }
 
+feature_wrapper crtc_feature_disable_wrappers[SDE_CP_CRTC_MAX_FEATURES];
+#define setup_crtc_feature_disable_wrappers(wrappers) \
+do { \
+	memset(wrappers, 0, sizeof(wrappers)); \
+	wrappers[SDE_CP_CRTC_DSPP_RC_MASK] = _disable_rc_mask_feature; \
+} while (0)
+
 feature_wrapper check_crtc_feature_wrappers[SDE_CP_CRTC_MAX_FEATURES];
 #define setup_check_crtc_feature_wrappers(wrappers) \
 do { \
@@ -1797,7 +1835,7 @@ static void _sde_cp_crtc_commit_feature(struct sde_cp_node *prop_node,
 			DRM_ERROR("failed to %s feature %d\n",
 				((feature_enabled) ? "enable" : "disable"),
 				prop_node->feature);
-			return;
+			goto disable_feature;
 		}
 	}
 
@@ -1812,6 +1850,34 @@ static void _sde_cp_crtc_commit_feature(struct sde_cp_node *prop_node,
 	}
 	/* Programming of feature done remove from dirty list */
 	list_del_init(&prop_node->cp_dirty_list);
+	return;
+
+disable_feature:
+	ret = 0;
+
+	if (crtc_feature_disable_wrappers[prop_node->feature] != NULL) {
+		feature_wrapper disable_handler =
+					crtc_feature_disable_wrappers[prop_node->feature];
+
+		for (i = 0; i < num_mixers && !ret; i++) {
+			hw_lm = sde_crtc->mixers[i].hw_lm;
+			hw_dspp = sde_crtc->mixers[i].hw_dspp;
+			if (!hw_lm) {
+				ret = -EINVAL;
+				continue;
+			}
+			hw_cfg.ctl = sde_crtc->mixers[i].hw_ctl;
+			hw_cfg.mixer_info = hw_lm;
+			hw_cfg.displayh = num_mixers * hw_lm->cfg.out_width;
+			hw_cfg.displayv = hw_lm->cfg.out_height;
+
+			ret = disable_handler(hw_dspp, &hw_cfg, sde_crtc);
+		}
+
+		/* Remove feature from active and dirty list */
+		list_del_init(&prop_node->cp_active_list);
+		list_del_init(&prop_node->cp_dirty_list);
+	}
 }
 
 static const int dspp_feature_to_sub_blk_tbl[SDE_CP_CRTC_MAX_FEATURES] = {
@@ -2402,6 +2468,7 @@ void sde_cp_crtc_install_properties(struct drm_crtc *crtc)
 		setup_lm_prop_install_funcs(lm_prop_install_func);
 		setup_set_crtc_feature_wrappers(set_crtc_feature_wrappers);
 		setup_check_crtc_feature_wrappers(check_crtc_feature_wrappers);
+		setup_crtc_feature_disable_wrappers(crtc_feature_disable_wrappers);
 		setup_set_crtc_pu_feature_wrappers(
 				set_crtc_pu_feature_wrappers);
 		setup_check_crtc_pu_feature_wrappers(