From patchwork Thu Apr 24 21:22:58 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Zanoni X-Patchwork-Id: 4054051 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 577E29F319 for ; Thu, 24 Apr 2014 21:23:22 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5F71720351 for ; Thu, 24 Apr 2014 21:23:21 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 59871201B9 for ; Thu, 24 Apr 2014 21:23:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CDA4D6E0F3; Thu, 24 Apr 2014 14:23:19 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-yk0-f178.google.com (mail-yk0-f178.google.com [209.85.160.178]) by gabe.freedesktop.org (Postfix) with ESMTP id D9FA66E0F3 for ; Thu, 24 Apr 2014 14:23:17 -0700 (PDT) Received: by mail-yk0-f178.google.com with SMTP id 200so1177161ykr.37 for ; Thu, 24 Apr 2014 14:23:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=f4TgvoRA7dqn2uefXkKRG4FNPaKHcJn6Zn/q+8rBbug=; b=X+/PYSLFWCj/EN5wZXgq1DAGsQz3ofvy84H3bd17X/CHAVRlFZ6KegqsZiGDC0TFS/ KYYIfApkC2sxrcCaSZQ0UKQxMNXS5AHnLb5QTKn/TvVyT0vanYH4MqjNTJ195qggxFhV 12T5b+/9K/Z1nKO4IjmAxzxizPQXVF5qwCbI9mA9AQCfmF92V8PusNn4a4KDb/RpR/AJ Rs9VVGENBheJabjqGa4Unwz6sgkLB6wlJT3ZiGNR3mTfwVa+VmVrMq19PdRfPXORegNc SRFO4Ny98Lecm/gABScgQPV2/OjaRyYQ7NTqYxe0bHYW8laPaVGfLJ+33Z/viksouchu r/PA== X-Received: by 10.236.91.170 with SMTP id h30mr5845963yhf.143.1398374597335; Thu, 24 Apr 2014 14:23:17 -0700 (PDT) Received: from localhost.localdomain ([177.16.38.220]) by mx.google.com with ESMTPSA id c27sm9740860yhm.35.2014.04.24.14.23.15 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 Apr 2014 14:23:16 -0700 (PDT) From: Paulo Zanoni To: intel-gfx@lists.freedesktop.org Date: Thu, 24 Apr 2014 18:22:58 -0300 Message-Id: <1398374579-5697-2-git-send-email-przanoni@gmail.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1398374579-5697-1-git-send-email-przanoni@gmail.com> References: <1398374579-5697-1-git-send-email-przanoni@gmail.com> Cc: Paulo Zanoni Subject: [Intel-gfx] [PATCH 2/3] drm/i915: extract intel_dp_compute_link_config X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Paulo Zanoni Extract this function to make the input and output parameters more clear to the code reader. I also have plans to allow ways to change the current parameters, so the code will get even more complicated without the refactor. I also have plans to add alternative implementations to intel_dp_compute_link_config() and, again, the refactor makes it easier. Another change worth noticing is that now we will print all our "attempts" in dmesg (see the debug code at link_config_is_possible()). This will allow us to quickly identify if the user is trying fast and narrow, or wide and slow, and also identify the minimum and maximum BW and lane count values used by the code. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_dp.c | 94 +++++++++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 19537a6..884166b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -768,6 +768,52 @@ intel_dp_set_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n) I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n); } +static bool link_config_is_possible(int mode_rate, int lanes, int bw) +{ + int link_clock, link_avail; + + link_clock = drm_dp_bw_code_to_link_rate(bw); + link_avail = intel_dp_max_data_rate(link_clock, lanes); + + DRM_DEBUG_KMS("DP link avail with 0x%x bw and %d lanes: %d. Required: %d (%d%%)\n", + bw, lanes, link_avail, mode_rate, + mode_rate * 100 / link_avail); + + return (mode_rate <= link_avail); +} + +/* + * This function tries to find the minimal number of lanes and BW required based + * on the parameters given. If not possible, it returns false. + */ +static bool intel_dp_compute_link_config(int mode_clock, int bpp, + int min_lanes, int max_lanes, + int min_bw, int max_bw, + int *lanes_used, int *bw_used) +{ + /* Conveniently, the link BW constants become indices with a shift...*/ + static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; + int min_bw_index = min_bw >> 3; + int max_bw_index = max_bw >> 3; + int mode_rate; + int lanes, bw_it; + + mode_rate = intel_dp_link_required(mode_clock, bpp); + + for (lanes = min_lanes; lanes <= max_lanes; lanes <<= 1) + for (bw_it = min_bw_index; bw_it <= max_bw_index; bw_it++) + if (link_config_is_possible(mode_rate, lanes, + bws[bw_it])) + goto found; + + return false; + +found: + *lanes_used = lanes; + *bw_used = bws[bw_it]; + return true; +} + bool intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config) @@ -779,13 +825,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, enum port port = dp_to_dig_port(intel_dp)->port; struct intel_crtc *intel_crtc = encoder->new_crtc; struct intel_connector *intel_connector = intel_dp->attached_connector; - int lane_count, clock; + int lanes_used, bw_used; int max_lane_count = intel_dp_max_lane_count(intel_dp); - /* Conveniently, the link BW constants become indices with a shift...*/ - int max_clock = intel_dp_max_link_bw(intel_dp) >> 3; - int bpp, mode_rate; - static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; - int link_avail, link_clock; + int max_bw = intel_dp_max_link_bw(intel_dp); + int bpp; if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A) pipe_config->has_pch_encoder = true; @@ -808,7 +851,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, DRM_DEBUG_KMS("DP link computation with max lane count %i " "max bw %02x pixel clock %iKHz\n", - max_lane_count, bws[max_clock], + max_lane_count, max_bw, adjusted_mode->crtc_clock); /* Walk through all bpp values. Luckily they're all nicely spaced with 2 @@ -821,26 +864,17 @@ intel_dp_compute_config(struct intel_encoder *encoder, bpp = dev_priv->vbt.edp_bpp; } - for (; bpp >= 6*3; bpp -= 2*3) { - mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, - bpp); - - for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { - for (clock = 0; clock <= max_clock; clock++) { - link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); - link_avail = intel_dp_max_data_rate(link_clock, - lane_count); - - if (mode_rate <= link_avail) { - goto found; - } - } - } - } + for (; bpp >= 6*3; bpp -= 2*3) + if (intel_dp_compute_link_config(adjusted_mode->crtc_clock, bpp, + 1, max_lane_count, + DP_LINK_BW_1_62, + max_bw, + &lanes_used, &bw_used)) + break; - return false; + if (bpp < 6*3) + return false; -found: if (intel_dp->color_range_auto) { /* * See: @@ -856,25 +890,23 @@ found: if (intel_dp->color_range) pipe_config->limited_color_range = true; - intel_dp->link_bw = bws[clock]; - intel_dp->lane_count = lane_count; + intel_dp->link_bw = bw_used; + intel_dp->lane_count = lanes_used; pipe_config->pipe_bpp = bpp; pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", intel_dp->link_bw, intel_dp->lane_count, pipe_config->port_clock, bpp); - DRM_DEBUG_KMS("DP link bw required %i available %i\n", - mode_rate, link_avail); - intel_link_compute_m_n(bpp, lane_count, + intel_link_compute_m_n(bpp, lanes_used, adjusted_mode->crtc_clock, pipe_config->port_clock, &pipe_config->dp_m_n); if (intel_connector->panel.downclock_mode != NULL && intel_dp->drrs_state.type == SEAMLESS_DRRS_SUPPORT) { - intel_link_compute_m_n(bpp, lane_count, + intel_link_compute_m_n(bpp, lanes_used, intel_connector->panel.downclock_mode->clock, pipe_config->port_clock, &pipe_config->dp_m2_n2);