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 <quic_ngunabal@quicinc.com>
This commit is contained in:
Nilaan Gunabalachandran
2023-04-25 12:25:29 -04:00
parent 825dd16313
commit c6bdb5db3a
3 changed files with 15 additions and 6 deletions

View File

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

View File

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

View File

@@ -1437,7 +1437,7 @@ static void _sde_encoder_update_ppb_size(struct drm_encoder *drm_enc)
struct sde_hw_mdp *hw_mdp; struct sde_hw_mdp *hw_mdp;
struct drm_display_mode *mode; struct drm_display_mode *mode;
struct sde_encoder_virt *sde_enc; 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; int i;
if (!drm_enc) { 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", 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); i, num_lm_or_pp, pixels_per_pp);
} else if (hw_mdp->ops.set_ppb_fifo_size) { } else if (hw_mdp->ops.set_ppb_fifo_size) {
maxw = sde_conn_get_max_mode_width(sde_enc->cur_master->connector); struct sde_connector *sde_conn =
if (!maxw) { 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"); SDE_DEBUG_ENC(sde_enc, "failed to get max horizantal resolution\n");
return; 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); 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_EVT32(DRMID(drm_enc), i, hw_pp->idx, sde_conn->max_mode_width,
sde_kms->catalog->ppb_sz_program, SDE_EVTLOG_FUNC_CASE2); 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", 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); i, num_lm_or_pp, pixels_per_pp);
} else { } else {