drm/i915: reject modes the LPT FDI receiver can't handle
authorPaulo Zanoni <paulo.r.zanoni@intel.com>
Thu, 29 Nov 2012 13:29:32 +0000 (11:29 -0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sat, 8 Dec 2012 13:00:35 +0000 (14:00 +0100)
More specifically, the LPT FDI RX only supports 8bpc and a maximum of
2 lanes, so anything above that won't work and should be rejected.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h

index 5c7774396e107641a536aab0cf674ce428a16ece..3084d018c740e14594564c0022ef5c7671a51bf9 100644 (file)
@@ -198,6 +198,11 @@ static int intel_crt_mode_valid(struct drm_connector *connector,
        if (mode->clock > max_clock)
                return MODE_CLOCK_HIGH;
 
+       /* The FDI receiver on LPT only supports 8bpc and only has 2 lanes. */
+       if (HAS_PCH_LPT(dev) &&
+           (ironlake_get_lanes_required(mode->clock, 270000, 24) > 2))
+               return MODE_CLOCK_HIGH;
+
        return MODE_OK;
 }
 
index f8ee3d16109ce250c7d740a90471523465ad1f9b..41e2d9508ef6757111552a7f29238c20bd79e5fc 100644 (file)
@@ -5228,6 +5228,17 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc)
        }
 }
 
+int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
+{
+       /*
+        * Account for spread spectrum to avoid
+        * oversubscribing the link. Max center spread
+        * is 2.5%; use 5% for safety's sake.
+        */
+       u32 bps = target_clock * bpp * 21 / 20;
+       return bps / (link_bw * 8) + 1;
+}
+
 static void ironlake_set_m_n(struct drm_crtc *crtc,
                             struct drm_display_mode *mode,
                             struct drm_display_mode *adjusted_mode)
@@ -5281,15 +5292,9 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
        else
                target_clock = adjusted_mode->clock;
 
-       if (!lane) {
-               /*
-                * Account for spread spectrum to avoid
-                * oversubscribing the link. Max center spread
-                * is 2.5%; use 5% for safety's sake.
-                */
-               u32 bps = target_clock * intel_crtc->bpp * 21 / 20;
-               lane = bps / (link_bw * 8) + 1;
-       }
+       if (!lane)
+               lane = ironlake_get_lanes_required(target_clock, link_bw,
+                                                  intel_crtc->bpp);
 
        intel_crtc->fdi_lanes = lane;
 
index 3915ca9abd414aec7d821134eb4c1240d863b392..8a1bd4a3ad0dc724ba4a166f7b0915d5e1795208 100644 (file)
@@ -559,6 +559,7 @@ intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
                             enum pipe pipe);
 extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
 extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe);
+extern int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp);
 
 struct intel_load_detect_pipe {
        struct drm_framebuffer *release_fb;