diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index c88a6810c49f..03de219f7a64 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -411,8 +411,6 @@ static int __intel_crtc_init(struct intel_display *display, enum pipe pipe) cpu_latency_qos_add_request(&crtc->vblank_pm_qos, PM_QOS_DEFAULT_VALUE); - drm_WARN_ON(display->drm, drm_crtc_index(&crtc->base) != crtc->pipe); - if (HAS_CASF(display) && crtc->num_scalers >= 2) drm_crtc_create_sharpness_strength_property(&crtc->base); @@ -426,6 +424,31 @@ static int __intel_crtc_init(struct intel_display *display, enum pipe pipe) return ret; } +#define HAS_PIPE(display, pipe) (DISPLAY_RUNTIME_INFO(display)->pipe_mask & BIT(pipe)) + +/* + * Expose the pipes in order A, C, B, D on discrete platforms to trick user + * space into using pipes that are more likely to be available for both a) user + * space if pipe B has been reserved for the joiner, and b) the joiner if pipe A + * doesn't need the joiner. + * + * Swap pipes B and C only if both are available i.e. not fused off. + */ +static enum pipe reorder_pipe(struct intel_display *display, enum pipe pipe) +{ + if (!display->platform.dgfx || !HAS_PIPE(display, PIPE_B) || !HAS_PIPE(display, PIPE_C)) + return pipe; + + switch (pipe) { + case PIPE_B: + return PIPE_C; + case PIPE_C: + return PIPE_B; + default: + return pipe; + } +} + int intel_crtc_init(struct intel_display *display) { enum pipe pipe; @@ -435,7 +458,7 @@ int intel_crtc_init(struct intel_display *display) INTEL_NUM_PIPES(display), str_plural(INTEL_NUM_PIPES(display))); for_each_pipe(display, pipe) { - ret = __intel_crtc_init(display, pipe); + ret = __intel_crtc_init(display, reorder_pipe(display, pipe)); if (ret) return ret; }