summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>2026-01-15 23:05:39 +0300
committerDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>2026-01-21 03:10:43 +0300
commit42f62cd795782ab29eca6ca3572d98e392fc9408 (patch)
treee323144243f43235a8bf8d0d74f0797816bead10
parent98c8f146f5744347f15c824fb9442867c71c4d32 (diff)
downloadlinux-42f62cd795782ab29eca6ca3572d98e392fc9408.tar.xz
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 <dmitry.baryshkov@oss.qualcomm.com> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Patchwork: https://patchwork.freedesktop.org/patch/698773/ Link: https://lore.kernel.org/r/20260115-dpu-fix-dspp-v1-2-b73152c147b3@oss.qualcomm.com
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c52
1 files 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 7e77d88f8959..451a4fcf3e65 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]] =