From c6bdb5db3a36061eb1b0548ed983dd32bc5d1483 Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Tue, 25 Apr 2023 12:25:29 -0400 Subject: [PATCH] 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 --- msm/sde/sde_connector.c | 2 ++ msm/sde/sde_connector.h | 3 +++ msm/sde/sde_encoder.c | 16 ++++++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 4269db7b96..68bb0ed784 100644 --- a/msm/sde/sde_connector.c +++ b/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); diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index ee9b92062a..0b826eb3c7 100644 --- a/msm/sde/sde_connector.h +++ b/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; }; /** diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 9bcc15d430..149c93980b 100644 --- a/msm/sde/sde_encoder.c +++ b/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 {