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
