From: Xi Zhang <[email protected]>

Consider the scenario with 4 crtcs, 3 encoders/displays are
connected. DPU resources is nearly maxed-out, and mode set is
performed on a display which has acquired many dpu resources.
A new crtc is selected by kernel drm for the mode set,
and during atomic_check, the previous crtc won't have a chance
to release its old resources from global_state before the new
crtc tries to allocate new ones. Leading to atomic_check failure.

By having the same crtc for encoder when possible, during
atomic_check each individual crtc will always be able to release
old resources before allocating new ones.

Signed-off-by: Xi Zhang <[email protected]>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index da3556eb6ecc..13099d6e3ac9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -879,9 +879,18 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
                }
        }
 
-       /* All CRTCs are compatible with all encoders */
-       drm_for_each_encoder(encoder, dev)
-               encoder->possible_crtcs = (1 << dev->mode_config.num_crtc) - 1;
+       /* All CRTCs are compatible with all encoders.
+        * Nevertheless, if enough CRTCs are available, pair up crtc/encoder
+        * for better resource re-assignments during atomic_check
+        * from userspace mode set.
+        */
+       i = 0;
+       drm_for_each_encoder(encoder, dev) {
+               if (dev->mode_config.num_crtc >= num_encoders)
+                       encoder->possible_crtcs = 1 << i++;
+               else
+                       encoder->possible_crtcs = (1 << 
dev->mode_config.num_crtc) - 1;
+       }
 
        return 0;
 }

-- 
2.55.0


Reply via email to