Commit d4b1931c authored by Paulo Zanoni's avatar Paulo Zanoni Committed by Daniel Vetter

drm/i915: reject modes the LPT FDI receiver can't handle

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: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 248138b5
...@@ -198,6 +198,11 @@ static int intel_crt_mode_valid(struct drm_connector *connector, ...@@ -198,6 +198,11 @@ static int intel_crt_mode_valid(struct drm_connector *connector,
if (mode->clock > max_clock) if (mode->clock > max_clock)
return MODE_CLOCK_HIGH; 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; return MODE_OK;
} }
......
...@@ -5228,6 +5228,17 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) ...@@ -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, static void ironlake_set_m_n(struct drm_crtc *crtc,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
...@@ -5281,15 +5292,9 @@ static void ironlake_set_m_n(struct drm_crtc *crtc, ...@@ -5281,15 +5292,9 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
else else
target_clock = adjusted_mode->clock; target_clock = adjusted_mode->clock;
if (!lane) { if (!lane)
/* lane = ironlake_get_lanes_required(target_clock, link_bw,
* Account for spread spectrum to avoid intel_crtc->bpp);
* 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;
}
intel_crtc->fdi_lanes = lane; intel_crtc->fdi_lanes = lane;
......
...@@ -559,6 +559,7 @@ intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, ...@@ -559,6 +559,7 @@ intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
enum pipe pipe); enum pipe pipe);
extern void intel_wait_for_vblank(struct drm_device *dev, int 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 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 intel_load_detect_pipe {
struct drm_framebuffer *release_fb; struct drm_framebuffer *release_fb;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment