From patchwork Fri Oct 7 23:32:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Navare, Manasi" X-Patchwork-Id: 9367829 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 50408600C8 for ; Fri, 7 Oct 2016 23:32:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4AA352984C for ; Fri, 7 Oct 2016 23:32:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3E86F2984E; Fri, 7 Oct 2016 23:32:16 +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 C45932984C for ; Fri, 7 Oct 2016 23:32:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 063996E36A; Fri, 7 Oct 2016 23:32:10 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 95E936E367 for ; Fri, 7 Oct 2016 23:32:08 +0000 (UTC) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 07 Oct 2016 16:32:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.31,457,1473145200"; d="scan'208"; a="1041871686" Received: from manasi-otcmedia.jf.intel.com ([10.7.199.175]) by orsmga001.jf.intel.com with ESMTP; 07 Oct 2016 16:32:07 -0700 From: Manasi Navare To: intel-gfx@lists.freedesktop.org Date: Fri, 7 Oct 2016 16:32:47 -0700 Message-Id: <1475883169-7960-4-git-send-email-manasi.d.navare@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1475883169-7960-1-git-send-email-manasi.d.navare@intel.com> References: <1475883169-7960-1-git-send-email-manasi.d.navare@intel.com> Cc: daniel.vetter@intel.com Subject: [Intel-gfx] [PATCH RFC v2 3/5] drm/i915: Add support for DP link training compliance 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 This patch adds support to handle automated DP compliance link training test requests. This patch has been tested with Unigraf DPR-120 DP Compliance device for testing Link Training Compliance. After we get a short pulse Compliance test request, test request values are read and hotplug uevent is sent in order to trigger another modeset during which the pipe is configured and link is enabled for link parameters requested by the test. Signed-off-by: Manasi Navare Cc: Jani Nikula Cc: Daniel Vetter Cc: Ville Syrjala --- drivers/gpu/drm/i915/intel_dp.c | 71 ++++++++++++++++++++++++++++++++++------ drivers/gpu/drm/i915/intel_drv.h | 2 ++ 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4ab4aa1..610316f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1567,6 +1567,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, /* Conveniently, the link BW constants become indices with a shift...*/ int min_clock = 0; int max_clock; + int link_rate_index; int bpp, mode_rate; int link_avail, link_clock; int common_rates[DP_MAX_SUPPORTED_RATES] = {}; @@ -1608,6 +1609,20 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) return false; + /* Use values requested by Compliance Test Request */ + if (intel_dp->compliance_test_link_rate && + intel_dp->compliance_test_lane_count) { + link_rate_index = intel_dp_link_rate_index(intel_dp, + common_rates, + drm_dp_bw_code_to_link_rate(intel_dp->compliance_test_link_rate)); + if (link_rate_index >= 0) + min_clock = max_clock = link_rate_index; + min_lane_count = max_lane_count = intel_dp->compliance_test_lane_count; + + intel_dp->compliance_test_link_rate = 0; + intel_dp->compliance_test_lane_count = 0; + } + DRM_DEBUG_KMS("DP link computation with max lane count %i " "max bw %d pixel clock %iKHz\n", max_lane_count, common_rates[max_clock], @@ -1655,6 +1670,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, } } } + } return false; @@ -3835,6 +3851,29 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector) static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp) { uint8_t test_result = DP_TEST_ACK; + int status = 0; + /* (DP CTS 1.2) + * 4.3.1.11 + */ + /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */ + status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT, + &intel_dp->compliance_test_lane_count); + + if (status <= 0) { + DRM_DEBUG_KMS("Could not read test lane count from " + "reference sink\n"); + return 0; + } + intel_dp->compliance_test_lane_count &= DP_MAX_LANE_COUNT_MASK; + + status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE, + &intel_dp->compliance_test_link_rate); + if (status <= 0) { + DRM_DEBUG_KMS("Could not read test link rate from " + "refernce sink\n"); + return 0; + } + return test_result; } @@ -3935,11 +3974,14 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp) } update_status: - status = drm_dp_dpcd_write(&intel_dp->aux, - DP_TEST_RESPONSE, - &response, 1); - if (status <= 0) - DRM_DEBUG_KMS("Could not write test response to sink\n"); + if (intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) { + status = drm_dp_dpcd_write(&intel_dp->aux, + DP_TEST_RESPONSE, + &response, 1); + if (status <= 0) + DRM_DEBUG_KMS("Could not write test response " + "to sink\n"); + } } static int @@ -4019,9 +4061,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) if (!to_intel_crtc(intel_encoder->base.crtc)->active) return; - /* if link training is requested we should perform it always */ - if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) || - (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { + if ((!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count))) { DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", intel_encoder->base.name); intel_dp_start_link_train(intel_dp); @@ -4046,6 +4086,7 @@ static bool intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; u8 sink_irq_vector = 0; u8 old_sink_count = intel_dp->sink_count; bool ret; @@ -4080,8 +4121,9 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) DP_DEVICE_SERVICE_IRQ_VECTOR, sink_irq_vector); - if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST) - DRM_DEBUG_DRIVER("Test request in short pulse not handled\n"); + if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST) { + intel_dp_handle_test_request(intel_dp); + } if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ)) DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); } @@ -4089,6 +4131,10 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); intel_dp_check_link_status(intel_dp); drm_modeset_unlock(&dev->mode_config.connection_mutex); + if ((intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING)) { + /* Send a Hotplug Uevent to userspace to start modeset */ + drm_kms_helper_hotplug_event(intel_encoder->base.dev); + } return true; } @@ -4366,6 +4412,11 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) /* Can't disconnect eDP, but you can close the lid... */ if (is_edp(intel_dp)) status = edp_detect(intel_dp); + else if (intel_dp->compliance_test_type == DP_TEST_LINK_TRAINING) { + status = connector_status_disconnected; + intel_dp->compliance_test_type = 0; + goto out; + } else if (intel_digital_port_connected(to_i915(dev), dp_to_dig_port(intel_dp))) status = intel_dp_detect_dpcd(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f48e79a..82fc4fe 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -951,6 +951,8 @@ struct intel_dp { unsigned long compliance_test_type; unsigned long compliance_test_data; bool compliance_test_active; + u8 compliance_test_lane_count; + u8 compliance_test_link_rate; }; struct intel_digital_port {