Kaynağa Gözat

disp: msm: sde: avoid concurrency while calculating max mode width

With DP plug-ins, it is possible for the connector fill modes API
to be called to update available modes on the connector and at the
same time have the commit thread calculate the max mode width
on the available modes. As a result, it is possible to access
pruned modes from the modelist.

This change moves the calculation into the fill modes call-flow,
so that the max mode width is determined once, and stored to be
used during virt enable.

Change-Id: I6c332c57e6e98ed98444a303add97d163a2031bf
Signed-off-by: Nilaan Gunabalachandran <[email protected]>
Nilaan Gunabalachandran 2 yıl önce
ebeveyn
işleme
c6bdb5db3a
3 değiştirilmiş dosya ile 15 ekleme ve 6 silme
  1. 2 0
      msm/sde/sde_connector.c
  2. 3 0
      msm/sde/sde_connector.h
  3. 10 6
      msm/sde/sde_encoder.c

+ 2 - 0
msm/sde/sde_connector.c

@@ -2583,6 +2583,8 @@ static int sde_connector_fill_modes(struct drm_connector *connector,
 	mode_count = drm_helper_probe_single_connector_modes(connector,
 			max_width, max_height);
 
+	sde_conn->max_mode_width = sde_conn_get_max_mode_width(connector);
+
 	if (sde_conn->ops.set_allowed_mode_switch)
 		sde_conn->ops.set_allowed_mode_switch(connector,
 				sde_conn->display);

+ 3 - 0
msm/sde/sde_connector.h

@@ -577,6 +577,7 @@ struct sde_misr_sign {
  * @misr_event_notify_enabled: Flag to indicate if misr event notify is enabled or not
  * @previous_misr_sign: store previous misr signature
  * @hwfence_wb_retire_fences_enable: enable hw-fences for wb retire-fence
+ * @max_mode_width: max width of all available modes
  */
 struct sde_connector {
 	struct drm_connector base;
@@ -657,6 +658,8 @@ struct sde_connector {
 	struct sde_misr_sign previous_misr_sign;
 
 	bool hwfence_wb_retire_fences_enable;
+
+	u32 max_mode_width;
 };
 
 /**

+ 10 - 6
msm/sde/sde_encoder.c

@@ -1437,7 +1437,7 @@ static void _sde_encoder_update_ppb_size(struct drm_encoder *drm_enc)
 	struct sde_hw_mdp *hw_mdp;
 	struct drm_display_mode *mode;
 	struct sde_encoder_virt *sde_enc;
-	u32 maxw, pixels_per_pp, num_lm_or_pp, latency_lines;
+	u32 pixels_per_pp, num_lm_or_pp, latency_lines;
 	int i;
 
 	if (!drm_enc) {
@@ -1491,17 +1491,21 @@ static void _sde_encoder_update_ppb_size(struct drm_encoder *drm_enc)
 			SDE_DEBUG_ENC(sde_enc, "hw-pp i:%d pp_cnt:%d pixels_per_pp:%d\n",
 					i, num_lm_or_pp, pixels_per_pp);
 		} else if (hw_mdp->ops.set_ppb_fifo_size) {
-			maxw = sde_conn_get_max_mode_width(sde_enc->cur_master->connector);
-			if (!maxw) {
+			struct sde_connector *sde_conn =
+					to_sde_connector(sde_enc->cur_master->connector);
+
+			if (!sde_conn || !sde_conn->max_mode_width) {
 				SDE_DEBUG_ENC(sde_enc, "failed to get max horizantal resolution\n");
 				return;
 			}
 
-			pixels_per_pp = mult_frac(maxw, latency_lines, num_lm_or_pp);
+			pixels_per_pp = mult_frac(sde_conn->max_mode_width,
+					latency_lines, num_lm_or_pp);
 			hw_mdp->ops.set_ppb_fifo_size(hw_mdp, hw_pp->idx, pixels_per_pp);
 
-			SDE_EVT32(DRMID(drm_enc), i, hw_pp->idx, maxw, pixels_per_pp,
-					sde_kms->catalog->ppb_sz_program, SDE_EVTLOG_FUNC_CASE2);
+			SDE_EVT32(DRMID(drm_enc), i, hw_pp->idx, sde_conn->max_mode_width,
+					pixels_per_pp, sde_kms->catalog->ppb_sz_program,
+					SDE_EVTLOG_FUNC_CASE2);
 			SDE_DEBUG_ENC(sde_enc, "hw-pp i:%d pp_cnt:%d pixels_per_pp:%d\n",
 					i, num_lm_or_pp, pixels_per_pp);
 		} else {