Browse Source

disp: msm: sde: add check to avoid multiple active CWB

Add check to avoid more than 1 CWB active per commit as
hardware doesn't support multiple CWB even if they are
on different OP.

Change-Id: I13416cc2af881de0d8bdd6544a4fdc180fb7a050
Signed-off-by: Amine Najahi <[email protected]>
Amine Najahi 3 years ago
parent
commit
91e45e818f
3 changed files with 47 additions and 1 deletions
  1. 1 0
      msm/sde/sde_hw_catalog.c
  2. 3 0
      msm/sde/sde_hw_catalog.h
  3. 43 1
      msm/sde/sde_kms.c

+ 1 - 0
msm/sde/sde_hw_catalog.c

@@ -5248,6 +5248,7 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg,
 
 
 	sde_cfg->min_display_height = MIN_DISPLAY_HEIGHT;
 	sde_cfg->min_display_height = MIN_DISPLAY_HEIGHT;
 	sde_cfg->min_display_width = MIN_DISPLAY_WIDTH;
 	sde_cfg->min_display_width = MIN_DISPLAY_WIDTH;
+	sde_cfg->max_cwb = min_t(u32, sde_cfg->wb_count, MAX_CWB_SESSIONS);
 
 
 	rc = _sde_hw_dnsc_blur_filter_caps(sde_cfg);
 	rc = _sde_hw_dnsc_blur_filter_caps(sde_cfg);
 
 

+ 3 - 0
msm/sde/sde_hw_catalog.h

@@ -106,6 +106,7 @@
 
 
 #define MAX_XIN_COUNT 16
 #define MAX_XIN_COUNT 16
 #define SSPP_SUBBLK_COUNT_MAX 2
 #define SSPP_SUBBLK_COUNT_MAX 2
+#define MAX_CWB_SESSIONS 1
 
 
 #define SDE_CTL_CFG_VERSION_1_0_0       0x100
 #define SDE_CTL_CFG_VERSION_1_0_0       0x100
 #define MAX_INTF_PER_CTL_V1                 2
 #define MAX_INTF_PER_CTL_V1                 2
@@ -1804,6 +1805,7 @@ struct sde_perf_cfg {
  * @max_dsc_width       max dsc line width
  * @max_dsc_width       max dsc line width
  * @max_mixer_width     max layer mixer line width
  * @max_mixer_width     max layer mixer line width
  * @max_mixer_blendstages       max layer mixer blend stages (z orders)
  * @max_mixer_blendstages       max layer mixer blend stages (z orders)
+ * @max_cwb             max number of cwb supported
  * @vbif_qos_nlvl       number of vbif QoS priority levels
  * @vbif_qos_nlvl       number of vbif QoS priority levels
  * @qos_target_time_ns  normalized qos target time for line-based qos
  * @qos_target_time_ns  normalized qos target time for line-based qos
  * @macrotile_mode      UBWC parameter for macro tile channel distribution
  * @macrotile_mode      UBWC parameter for macro tile channel distribution
@@ -1913,6 +1915,7 @@ struct sde_mdss_cfg {
 	u32 max_dsc_width;
 	u32 max_dsc_width;
 	u32 max_mixer_width;
 	u32 max_mixer_width;
 	u32 max_mixer_blendstages;
 	u32 max_mixer_blendstages;
+	u32 max_cwb;
 
 
 	/* Configs */
 	/* Configs */
 	u32 vbif_qos_nlvl;
 	u32 vbif_qos_nlvl;

+ 43 - 1
msm/sde/sde_kms.c

@@ -2968,7 +2968,6 @@ static int sde_kms_check_vm_request(struct msm_kms *kms,
 	return rc;
 	return rc;
 }
 }
 
 
-
 static int sde_kms_check_secure_transition(struct msm_kms *kms,
 static int sde_kms_check_secure_transition(struct msm_kms *kms,
 		struct drm_atomic_state *state)
 		struct drm_atomic_state *state)
 {
 {
@@ -3083,6 +3082,44 @@ static void sde_kms_vm_res_release(struct msm_kms *kms,
 	sde_vm_unlock(sde_kms);
 	sde_vm_unlock(sde_kms);
 }
 }
 
 
+static int sde_kms_check_cwb_concurreny(struct msm_kms *kms,
+		struct drm_atomic_state *state)
+{
+	struct sde_kms *sde_kms;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+	struct drm_encoder *encoder;
+	struct sde_crtc_state *cstate;
+	int i = 0, cnt = 0, max_cwb = 0;
+
+	if (!kms || !state) {
+		SDE_ERROR("invalid arguments\n");
+		return -EINVAL;
+	}
+
+	sde_kms = to_sde_kms(kms);
+	max_cwb = sde_kms->catalog->max_cwb;
+	if (!max_cwb)
+		return 0;
+
+	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+		cstate = to_sde_crtc_state(new_crtc_state);
+		drm_for_each_encoder_mask(encoder, crtc->dev, cstate->cwb_enc_mask) {
+			cnt++;
+			SDE_DEBUG("crtc%d has cwb%d attached to it\n", crtc->base.id,
+					encoder->base.id);
+		}
+
+		if (cnt > max_cwb) {
+			SDE_ERROR("found %d cwb in the atomic state, max supported %d\n",
+					cnt, max_cwb);
+			return -EOPNOTSUPP;
+		}
+	}
+
+	return 0;
+}
+
 static int sde_kms_atomic_check(struct msm_kms *kms,
 static int sde_kms_atomic_check(struct msm_kms *kms,
 		struct drm_atomic_state *state)
 		struct drm_atomic_state *state)
 {
 {
@@ -3123,6 +3160,11 @@ static int sde_kms_atomic_check(struct msm_kms *kms,
 	if (ret)
 	if (ret)
 		goto vm_clean_up;
 		goto vm_clean_up;
 
 
+
+	ret = sde_kms_check_cwb_concurreny(kms, state);
+	if (ret)
+		goto vm_clean_up;
+
 	goto end;
 	goto end;
 
 
 vm_clean_up:
 vm_clean_up: