From patchwork Fri Feb 22 00:04:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 2173851 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 896ADDF215 for ; Fri, 22 Feb 2013 00:08:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5F7B4E61F1 for ; Thu, 21 Feb 2013 16:08:51 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ee0-f46.google.com (mail-ee0-f46.google.com [74.125.83.46]) by gabe.freedesktop.org (Postfix) with ESMTP id B355BE612B for ; Thu, 21 Feb 2013 16:05:23 -0800 (PST) Received: by mail-ee0-f46.google.com with SMTP id e49so41265eek.19 for ; Thu, 21 Feb 2013 16:05:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=yQvUy0iSXJ/1AU9eMNp01kYtSqvwme3yN5rJK3OY4N4=; b=ZqBHWumzGPUJirMFRrpxgqWP7l4s4hjuNv1x/EHFHBbeW0ZIYWpOUh1xFuf2HXxaSq AL9q+npH+LsSrc3uUUEN6bpIetpqu8BlIK9n6bxY8Xo7eiHOdDZSYCq6pmFQ+2UIZMQu fe9TaIEMtbc0XIT6fv41zzFKA5+7MWl5dhBgk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=yQvUy0iSXJ/1AU9eMNp01kYtSqvwme3yN5rJK3OY4N4=; b=nQ3wv5lssvdEm1GrJa/HLHnvf4TJHOf0OnuBFsIZoAwYLoZCUXewQSBxWqqYOA8k9L Kud3dtCy8AxO/ErS/kYYQm/jE9Sd+oKxOKn0ILLU9ojiw1KyXY4nlgF35K6ZBbVhAmpr X2Y+z+N5g5Nthp40Shud3Rcs2de7q/eBlAkAJ6Votlmp6zCqKPhj4fMgtwU6aLa45OkU KGqcBzAts0g9zi/qR/FVzxVuMOkbwm6QiyIsPfO2IulBp8BRINUwoOdK2FQZDv+aVmp8 Vvm8+Kx1ToOq16yAtNhFQ9yDtXeNDSvms7AwJ20mMCxCSOffKQ7Cb4ztxU7iTV+/NA6V aa8A== X-Received: by 10.14.0.135 with SMTP id 7mr80930eeb.5.1361491522883; Thu, 21 Feb 2013 16:05:22 -0800 (PST) Received: from bremse.ffwll.local (178-83-130-250.dynamic.hispeed.ch. [178.83.130.250]) by mx.google.com with ESMTPS id s3sm508871eem.4.2013.02.21.16.05.21 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 21 Feb 2013 16:05:22 -0800 (PST) From: Daniel Vetter To: Intel Graphics Development Date: Fri, 22 Feb 2013 01:04:56 +0100 Message-Id: <1361491513-14231-2-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.7.11.4 In-Reply-To: <1361491513-14231-1-git-send-email-daniel.vetter@ffwll.ch> References: <1361491513-14231-1-git-send-email-daniel.vetter@ffwll.ch> X-Gm-Message-State: ALoCoQmQ0QZXzuxFrdVpEFtkxo//dIEpk9c205ZYC5r1L1DUIcIEjJGBZdoswlAkbQ22j0F+aDLN Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH 1/8] drm/i915: clear up the fdi/dp set_m_n confusion X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org There's a rather decent confusion going on around transcoder m_n values. So let's clarify: - All dp encoders need this, either on the pch transcoder if it's a pch port, or on the cpu transcoder/pipe if it's a cpu port. - fdi links need to have the right m_n values for the fdi link set in the cpu transcoder. To handle the pch vs transcoder stuff a bit better, extract transcoder set_m_n helpers. To make them simpler, set intel_crtc->cpu_transcoder als in ironlake_crtc_mode_set, so that gen5+ (where the cpu m_n registers are all at the same offset) can use it. Haswell modeset is decently confused about dp vs. edp vs. fdi. dp vs. edp works exactly the same as dp (since there's no pch dp any more), so use that as a check. And only set up the fdi m_n values if we really have a pch encoder present (which means we have a VGA encoder). On ilk+ we've called ironlake_set_m_n both for cpu_edp and for pch encoders. Now that dp_set_m_n handles all dp links (thanks to the pch encoder check), we can ditch the cpu_edp stuff from the fdi_set_m_n function. Since the dp_m_n values are not readily available, we need to carefully coax the edp values out of the encoder. Hence we can't (yet) kill this superflous complexity. v2: Rebase on top of the ivb fdi B/C check patch - we need to properly clear intel_crtc->fdi_lane, otherwise those checks will misfire. v3: Rebased on top of a s/IS_HASWELL/HAS_DDI/ patch from Paulo Zanoni. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 86 +++++++++++++++++++++++------------- drivers/gpu/drm/i915/intel_dp.c | 30 ++----------- drivers/gpu/drm/i915/intel_drv.h | 8 ++++ 3 files changed, 67 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f1d47dd..8335fd5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5255,15 +5255,47 @@ int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp) return bps / (link_bw * 8) + 1; } -static void ironlake_set_m_n(struct drm_crtc *crtc) +void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, + struct intel_link_m_n *m_n) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = crtc->pipe; + + I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); + I915_WRITE(TRANSDATA_N1(pipe), m_n->gmch_n); + I915_WRITE(TRANSDPLINK_M1(pipe), m_n->link_m); + I915_WRITE(TRANSDPLINK_N1(pipe), m_n->link_n); +} + +void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, + struct intel_link_m_n *m_n) +{ + struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = crtc->pipe; + enum transcoder transcoder = crtc->cpu_transcoder; + + if (INTEL_INFO(dev)->gen >= 5) { + I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m); + I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n); + I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m); + I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n); + } else { + I915_WRITE(PIPE_GMCH_DATA_M(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); + I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n->gmch_n); + I915_WRITE(PIPE_DP_LINK_M(pipe), m_n->link_m); + I915_WRITE(PIPE_DP_LINK_N(pipe), m_n->link_n); + } +} + +static void ironlake_fdi_set_m_n(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_display_mode *adjusted_mode = &intel_crtc->config.adjusted_mode; struct drm_display_mode *mode = &intel_crtc->config.requested_mode; - enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; struct intel_encoder *intel_encoder, *edp_encoder = NULL; struct intel_link_m_n m_n = {0}; int target_clock, lane, link_bw; @@ -5283,22 +5315,14 @@ static void ironlake_set_m_n(struct drm_crtc *crtc) } } - /* FDI link */ - lane = 0; - /* CPU eDP doesn't require FDI link, so just set DP M/N - according to current link config */ - if (is_cpu_edp) { - intel_edp_link_config(edp_encoder, &lane, &link_bw); - } else { - /* FDI is a binary signal running at ~2.7GHz, encoding - * each output octet as 10 bits. The actual frequency - * is stored as a divider into a 100MHz clock, and the - * mode pixel clock is stored in units of 1KHz. - * Hence the bw of each lane in terms of the mode signal - * is: - */ - link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; - } + /* FDI is a binary signal running at ~2.7GHz, encoding + * each output octet as 10 bits. The actual frequency + * is stored as a divider into a 100MHz clock, and the + * mode pixel clock is stored in units of 1KHz. + * Hence the bw of each lane in terms of the mode signal + * is: + */ + 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 (edp_encoder) @@ -5308,9 +5332,8 @@ static void ironlake_set_m_n(struct drm_crtc *crtc) else target_clock = adjusted_mode->clock; - if (!lane) - lane = ironlake_get_lanes_required(target_clock, link_bw, - intel_crtc->config.pipe_bpp); + lane = ironlake_get_lanes_required(target_clock, link_bw, + intel_crtc->config.pipe_bpp); intel_crtc->fdi_lanes = lane; @@ -5319,10 +5342,7 @@ static void ironlake_set_m_n(struct drm_crtc *crtc) intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane, target_clock, link_bw, &m_n); - I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m); - I915_WRITE(PIPE_DATA_N1(cpu_transcoder), m_n.gmch_n); - I915_WRITE(PIPE_LINK_M1(cpu_transcoder), m_n.link_m); - I915_WRITE(PIPE_LINK_N1(cpu_transcoder), m_n.link_n); + intel_cpu_transcoder_set_m_n(intel_crtc, &m_n); } static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, @@ -5469,6 +5489,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); + intel_crtc->cpu_transcoder = pipe; + ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, &has_reduced_clock, &reduced_clock); if (!ok) { @@ -5507,7 +5529,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, } else intel_put_pch_pll(intel_crtc); - if (is_dp && !is_cpu_edp) + if (is_dp) intel_dp_set_m_n(crtc, mode, adjusted_mode); for_each_encoder_on_crtc(dev, crtc, encoder) @@ -5543,7 +5565,9 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, /* Note, this also computes intel_crtc->fdi_lanes which is used below in * ironlake_check_fdi_lanes. */ - ironlake_set_m_n(crtc); + intel_crtc->fdi_lanes = 0; + if (intel_crtc->config.has_pch_encoder) + ironlake_fdi_set_m_n(crtc); fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc); @@ -5650,15 +5674,15 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); drm_mode_debug_printmodeline(mode); - if (is_dp && !is_cpu_edp) + if (is_dp) intel_dp_set_m_n(crtc, mode, adjusted_mode); intel_crtc->lowfreq_avail = false; intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); - if (!is_dp || is_cpu_edp) - ironlake_set_m_n(crtc); + if (intel_crtc->config.has_pch_encoder) + ironlake_fdi_set_m_n(crtc); haswell_set_pipeconf(crtc, adjusted_mode, dither); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a4c9858..a4caf1e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -766,12 +766,9 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_device *dev = crtc->dev; struct intel_encoder *intel_encoder; struct intel_dp *intel_dp; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int lane_count = 4; struct intel_link_m_n m_n; - int pipe = intel_crtc->pipe; - enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; /* * Find the lane count in the intel_encoder private @@ -795,29 +792,10 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane_count, mode->clock, adjusted_mode->clock, &m_n); - if (HAS_DDI(dev)) { - I915_WRITE(PIPE_DATA_M1(cpu_transcoder), - TU_SIZE(m_n.tu) | m_n.gmch_m); - I915_WRITE(PIPE_DATA_N1(cpu_transcoder), m_n.gmch_n); - I915_WRITE(PIPE_LINK_M1(cpu_transcoder), m_n.link_m); - I915_WRITE(PIPE_LINK_N1(cpu_transcoder), m_n.link_n); - } else if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m); - I915_WRITE(TRANSDATA_N1(pipe), m_n.gmch_n); - I915_WRITE(TRANSDPLINK_M1(pipe), m_n.link_m); - I915_WRITE(TRANSDPLINK_N1(pipe), m_n.link_n); - } else if (IS_VALLEYVIEW(dev)) { - I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m); - I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n); - I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); - I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); - } else { - I915_WRITE(PIPE_GMCH_DATA_M(pipe), - TU_SIZE(m_n.tu) | m_n.gmch_m); - I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n.gmch_n); - I915_WRITE(PIPE_DP_LINK_M(pipe), m_n.link_m); - I915_WRITE(PIPE_DP_LINK_N(pipe), m_n.link_n); - } + if (intel_crtc->config.has_pch_encoder) + intel_pch_transcoder_set_m_n(intel_crtc, &m_n); + else + intel_cpu_transcoder_set_m_n(intel_crtc, &m_n); } void intel_dp_init_link_config(struct intel_dp *intel_dp) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e43155a..aa4dee4 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -191,8 +191,12 @@ struct intel_crtc_config { */ bool limited_color_range; + /* DP has a bunch of special case unfortunately, so mark the pipe + * accordingly. */ + bool has_dp_encoder; bool dither; int pipe_bpp; + struct intel_link_m_n dp_m_n; /* Used by SDVO (and if we ever fix it, HDMI). */ unsigned pixel_multiplier; @@ -635,6 +639,10 @@ extern void intel_init_clock_gating(struct drm_device *dev); extern void intel_write_eld(struct drm_encoder *encoder, struct drm_display_mode *mode); extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe); +extern void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, + struct intel_link_m_n *m_n); +extern void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, + struct intel_link_m_n *m_n); extern void intel_prepare_ddi(struct drm_device *dev); extern void hsw_fdi_link_train(struct drm_crtc *crtc); extern void intel_ddi_init(struct drm_device *dev, enum port port);