Commit df92b1e6 authored by Daniel Vetter's avatar Daniel Vetter

drm/i915: track dp target_clock in pipe_config

We need it in the fdi m_n computation, which nicely kills almost
all ugly special cases in there.

It looks like we also need this to handle 12bpc hdmi correctly.

Eventually it might be better to switch things around and put the
target clock into adjusted_mode->clock and create a new pipe_config
parameter for the port link clock.

v2: Add a massive comment in the code to explain this mess.

v3: s/dp_target_clock/pixel_target_clock in anticipation of the hdmi
use-case.
Reviewed-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 03afc4a2
...@@ -5415,25 +5415,9 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc) ...@@ -5415,25 +5415,9 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_display_mode *adjusted_mode = struct drm_display_mode *adjusted_mode =
&intel_crtc->config.adjusted_mode; &intel_crtc->config.adjusted_mode;
struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
struct intel_encoder *intel_encoder, *edp_encoder = NULL;
struct intel_link_m_n m_n = {0}; struct intel_link_m_n m_n = {0};
int target_clock, lane, link_bw; int target_clock, lane, link_bw;
bool is_dp = false, is_cpu_edp = false; uint32_t bps;
for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
switch (intel_encoder->type) {
case INTEL_OUTPUT_DISPLAYPORT:
is_dp = true;
break;
case INTEL_OUTPUT_EDP:
is_dp = true;
if (!intel_encoder_is_pch_edp(&intel_encoder->base))
is_cpu_edp = true;
edp_encoder = intel_encoder;
break;
}
}
/* FDI is a binary signal running at ~2.7GHz, encoding /* FDI is a binary signal running at ~2.7GHz, encoding
* each output octet as 10 bits. The actual frequency * each output octet as 10 bits. The actual frequency
...@@ -5444,11 +5428,8 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc) ...@@ -5444,11 +5428,8 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc)
*/ */
link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
/* [e]DP over FDI requires target mode clock instead of link clock. */ if (intel_crtc->config.pixel_target_clock)
if (edp_encoder) target_clock = intel_crtc->config.pixel_target_clock;
target_clock = intel_edp_target_clock(edp_encoder, mode);
else if (is_dp)
target_clock = mode->clock;
else else
target_clock = adjusted_mode->clock; target_clock = adjusted_mode->clock;
......
...@@ -762,6 +762,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, ...@@ -762,6 +762,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
intel_dp->lane_count = lane_count; intel_dp->lane_count = lane_count;
adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
pipe_config->pipe_bpp = bpp; pipe_config->pipe_bpp = bpp;
pipe_config->pixel_target_clock = target_clock;
DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
intel_dp->link_bw, intel_dp->lane_count, intel_dp->link_bw, intel_dp->lane_count,
......
...@@ -196,7 +196,12 @@ struct intel_crtc_config { ...@@ -196,7 +196,12 @@ struct intel_crtc_config {
bool dither; bool dither;
int pipe_bpp; int pipe_bpp;
struct intel_link_m_n dp_m_n; struct intel_link_m_n dp_m_n;
/**
* This is currently used by DP and HDMI encoders since those can have a
* target pixel clock != the port link clock (which is currently stored
* in adjusted_mode->clock).
*/
int pixel_target_clock;
/* Used by SDVO (and if we ever fix it, HDMI). */ /* Used by SDVO (and if we ever fix it, HDMI). */
unsigned pixel_multiplier; unsigned pixel_multiplier;
}; };
......
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