From patchwork Wed Sep 7 00:13:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Navare, Manasi" X-Patchwork-Id: 9318065 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9603360869 for ; Wed, 7 Sep 2016 00:14:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 853AE28E0E for ; Wed, 7 Sep 2016 00:14:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7A18F28E3C; Wed, 7 Sep 2016 00:14:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 31FDB28E0E for ; Wed, 7 Sep 2016 00:14:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 008156E7F2; Wed, 7 Sep 2016 00:14:09 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id E49336E7F0 for ; Wed, 7 Sep 2016 00:14:07 +0000 (UTC) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga105.jf.intel.com with ESMTP; 06 Sep 2016 17:14:06 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.30,294,1470726000"; d="scan'208"; a="1046541959" Received: from manasi-otcmedia.jf.intel.com ([10.7.199.175]) by orsmga002.jf.intel.com with ESMTP; 06 Sep 2016 17:14:06 -0700 From: Manasi Navare To: intel-gfx@lists.freedesktop.org Date: Tue, 6 Sep 2016 17:13:58 -0700 Message-Id: <1473207238-3490-5-git-send-email-manasi.d.navare@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1473207238-3490-1-git-send-email-manasi.d.navare@intel.com> References: <1473207238-3490-1-git-send-email-manasi.d.navare@intel.com> In-Reply-To: <1472767699-31211-15-git-send-email-manasi.d.navare@intel.com> References: <1472767699-31211-15-git-send-email-manasi.d.navare@intel.com> Subject: [Intel-gfx] [PATCH v2 14/14] drm/i915/dp/mst: Add support for upfront link training for DP MST X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 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-Virus-Scanned: ClamAV using ClamSMTP From: Jim Bride Add upfront link training to intel_dp_mst_mode_valid() so that we know topology constraints before we validate the legality of modes to be checked. Call the function that loops through the link rates and lane counts starting from highest supported link rate and lane count for training the link in compliance with DP spec v2: * Rebased on new revision of link training patch (Manasi Navare) Signed-off-by: Manasi Navare Signed-off-by: Jim Bride Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/intel_dp.c | 9 ++--- drivers/gpu/drm/i915/intel_dp_mst.c | 74 +++++++++++++++++++++++++++---------- drivers/gpu/drm/i915/intel_drv.h | 3 ++ 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7794180..0c7674f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -131,7 +131,7 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe); static void intel_dp_unset_edid(struct intel_dp *intel_dp); -static int +int intel_dp_max_link_bw(struct intel_dp *intel_dp) { int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE]; @@ -150,7 +150,7 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) return max_link_bw; } -static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp) +u8 intel_dp_max_lane_count(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); u8 temp, source_max, sink_max; @@ -312,8 +312,7 @@ static int intersect_rates(const int *source_rates, int source_len, return k; } -static int intel_dp_common_rates(struct intel_dp *intel_dp, - int *common_rates) +int intel_dp_common_rates(struct intel_dp *intel_dp, int *common_rates) { const int *source_rates, *sink_rates; int source_len, sink_len; @@ -336,7 +335,7 @@ static int intel_dp_common_rates(struct intel_dp *intel_dp, common_rates); } -static bool intel_dp_upfront_link_train(struct intel_dp *intel_dp) +bool intel_dp_upfront_link_train(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 54a9d76..98d45a4 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -41,21 +41,30 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, int bpp; int lane_count, slots; const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; - int mst_pbn; + int mst_pbn, common_len; + int common_rates[DP_MAX_SUPPORTED_RATES] = {}; pipe_config->dp_encoder_is_mst = true; pipe_config->has_pch_encoder = false; - bpp = 24; + /* - * for MST we always configure max link bw - the spec doesn't - * seem to suggest we should do otherwise. + * For MST we always configure for the maximum trainable link bw - + * the spec doesn't seem to suggest we should do otherwise. The + * calls to intel_dp_max_lane_count() and intel_dp_common_rates() + * both take successful upfront link training into account, and + * return the DisplayPort max supported values in the event that + * upfront link training was not done. */ - lane_count = drm_dp_max_lane_count(intel_dp->dpcd); + lane_count = intel_dp_max_lane_count(intel_dp); pipe_config->lane_count = lane_count; - pipe_config->pipe_bpp = 24; - pipe_config->port_clock = intel_dp_max_link_rate(intel_dp); + pipe_config->pipe_bpp = bpp = 24; + common_len = intel_dp_common_rates(intel_dp, common_rates); + pipe_config->port_clock = common_rates[common_len - 1]; + + DRM_DEBUG_KMS("DP MST link configured for %d lanes @ %d.\n", + pipe_config->lane_count, pipe_config->port_clock); state = pipe_config->base.state; @@ -137,6 +146,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, enum port port = intel_dig_port->port; struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_shared_dpll *pll = pipe_config->shared_dpll; + struct intel_shared_dpll_config tmp_pll_config; int ret; uint32_t temp; int slots; @@ -150,21 +161,23 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); if (intel_dp->active_mst_links == 0) { - intel_ddi_clk_select(&intel_dig_port->base, - pipe_config->shared_dpll); - - intel_prepare_dp_ddi_buffers(&intel_dig_port->base); - intel_dp_set_link_params(intel_dp, - pipe_config->port_clock, - pipe_config->lane_count, - true); - - intel_ddi_init_dp_buf_reg(&intel_dig_port->base); - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); + /* Disable the PLL since we need to acquire the PLL + * based on the link rate in the link training sequence + */ + tmp_pll_config = pll->config; + pll->funcs.disable(dev_priv, pll); + pll->config.crtc_mask = 0; + + /* If Link Training fails, send a uevent to generate a + *hotplug + */ + if (!(intel_ddi_link_train(intel_dp, pipe_config->port_clock, + pipe_config->lane_count, true, + false))) + drm_kms_helper_hotplug_event(encoder->base.dev); + pll->config = tmp_pll_config; - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); } ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr, @@ -336,6 +349,27 @@ intel_dp_mst_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; + struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_dp *intel_dp = intel_connector->mst_port; + + if (intel_dp->upfront_link_train && !intel_dp->upfront_done) { + bool do_upfront_link_train; + + do_upfront_link_train = intel_dp->compliance_test_type != + DP_TEST_LINK_TRAINING; + if (do_upfront_link_train) { + intel_dp->upfront_done = + intel_dp_upfront_link_train(intel_dp); + if (intel_dp->upfront_done) { + DRM_DEBUG_KMS("MST upfront trained at " + "%d lanes @ %d.", + intel_dp->max_lanes_upfront, + intel_dp->max_link_rate_upfront); + } else + DRM_DEBUG_KMS("MST upfront link training " + "failed."); + } + } /* TODO - validate mode against available PBN for link */ if (mode->clock < 10000) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a2bbf68..34af3e8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1416,6 +1416,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp); void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector); void intel_dp_mst_suspend(struct drm_device *dev); void intel_dp_mst_resume(struct drm_device *dev); +u8 intel_dp_max_lane_count(struct intel_dp *intel_dp); int intel_dp_max_link_rate(struct intel_dp *intel_dp); int intel_dp_link_rate_index(struct intel_dp *intel_dp, int *common_rates, int link_rate); @@ -1448,6 +1449,8 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing); void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, uint8_t *link_bw, uint8_t *rate_select); bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); +int intel_dp_common_rates(struct intel_dp *intel_dp, int *common_rates); +bool intel_dp_upfront_link_train(struct intel_dp *intel_dp); bool intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]);