From 42f62cd795782ab29eca6ca3572d98e392fc9408 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 15 Jan 2026 22:05:39 +0200 Subject: [PATCH] drm/msm/dpu: try reserving the DSPP-less LM first On most of the platforms only some mixers have connected DSPP blocks. If DSPP is not required for the CRTC, try looking for the LM with no DSSP block, leaving DSPP-enabled LMs to CRTCs which actually require those. Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/698773/ Link: https://lore.kernel.org/r/20260115-dpu-fix-dspp-v1-2-b73152c147b3@oss.qualcomm.com --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 52 +++++++++++++++++++------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 7e77d88f89592..451a4fcf3e653 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -350,28 +350,26 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, return true; } -static int _dpu_rm_reserve_lms(struct dpu_rm *rm, - struct dpu_global_state *global_state, - uint32_t crtc_id, - struct msm_display_topology *topology) +static bool dpu_rm_find_lms(struct dpu_rm *rm, + struct dpu_global_state *global_state, + uint32_t crtc_id, bool skip_dspp, + struct msm_display_topology *topology, + int *lm_idx, int *pp_idx, int *dspp_idx) { - int lm_idx[MAX_BLOCKS]; - int pp_idx[MAX_BLOCKS]; - int dspp_idx[MAX_BLOCKS] = {0}; int i, lm_count = 0; - if (!topology->num_lm) { - DPU_ERROR("zero LMs in topology\n"); - return -EINVAL; - } - /* Find a primary mixer */ for (i = 0; i < ARRAY_SIZE(rm->mixer_blks) && lm_count < topology->num_lm; i++) { if (!rm->mixer_blks[i]) continue; + if (skip_dspp && to_dpu_hw_mixer(rm->mixer_blks[i])->cap->dspp) { + DPU_DEBUG("Skipping LM_%d, skipping LMs with DSPPs\n", i); + continue; + } + /* * Reset lm_count to an even index. This will drop the previous * primary mixer if failed to find its peer. @@ -410,12 +408,38 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, } } - if (lm_count != topology->num_lm) { + return lm_count == topology->num_lm; +} + +static int _dpu_rm_reserve_lms(struct dpu_rm *rm, + struct dpu_global_state *global_state, + uint32_t crtc_id, + struct msm_display_topology *topology) + +{ + int lm_idx[MAX_BLOCKS]; + int pp_idx[MAX_BLOCKS]; + int dspp_idx[MAX_BLOCKS] = {0}; + int i; + bool found; + + if (!topology->num_lm) { + DPU_ERROR("zero LMs in topology\n"); + return -EINVAL; + } + + /* Try using non-DSPP LM blocks first */ + found = dpu_rm_find_lms(rm, global_state, crtc_id, !topology->num_dspp, + topology, lm_idx, pp_idx, dspp_idx); + if (!found && !topology->num_dspp) + found = dpu_rm_find_lms(rm, global_state, crtc_id, false, + topology, lm_idx, pp_idx, dspp_idx); + if (!found) { DPU_DEBUG("unable to find appropriate mixers\n"); return -ENAVAIL; } - for (i = 0; i < lm_count; i++) { + for (i = 0; i < topology->num_lm; i++) { global_state->mixer_to_crtc_id[lm_idx[i]] = crtc_id; global_state->pingpong_to_crtc_id[pp_idx[i]] = crtc_id; global_state->dspp_to_crtc_id[dspp_idx[i]] = -- 2.47.3