Received: by 10.223.185.116 with SMTP id b49csp188630wrg; Thu, 8 Mar 2018 15:25:52 -0800 (PST) X-Google-Smtp-Source: AG47ELtuEpw+WBrhSBAIMtaXBQPeNoELRfhJUiZQL+cGBFr8eLHo60KM5H+fkGtw4MiYk4YlDATw X-Received: by 2002:a17:902:bd46:: with SMTP id b6-v6mr20112378plx.247.1520551552094; Thu, 08 Mar 2018 15:25:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520551552; cv=none; d=google.com; s=arc-20160816; b=xvEkTE1s+PgNftKVD1ceVzoUN1oZ6aif9OYkDP6MIAGeeQc511sIAr7f0MPxt6LMbB 0Stzo8Yvr7tE39BHq6lORibO9c7vbm6C0Wx3iaxF9UZtbY4kRqcD2XciAqkCxUgvznKq 6sIwFaAXlxTkl86BYZZJhXLvE7p/JtoDFdfW0T4OhDGe/qtpRnpL566Ivv4sokzL945S R7B8uTUhKoUSyWj6v4dfpDyOidTS6cK7xFJEl+HjzjaIb0P/RBx3UyP7MKZYwrMTD2sV 0nrH4oMMunaasp0k/aE6+hhO6bTJimEBYWCESi+JcSqYtpRnlwq2uc+HQLhp0P6O0JWo 3beQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=1hK3Rhj+SgQNzoBCO43wXRALndB84fuEKFL8zou7OAk=; b=AFIB7a04MX2hcgsuS6fe5sKblShQ/O/6EZzR1ws6AKAcdlI3gfiTmEoAMZXTAWPcTp 3e+o14SIoh62IIrLO+eB2t7i+Kj/BaXPUQmBhUleUdkxJSQOKO8w9NmvzQnj5wzoMSNY +d9Vlba9W6j8OwqWQMCmrCQJSWth4pIqQTTKSLtgYO/S3pUjDMoNXsv7kycb2F3MSl0N DAPZcg0IIP3A6R5jqiWa5jt7/YLgxRJog36kjM8/owmiuPJL2LC9Yv0GItn2BKu2qpNI ljgvCD+s1LFE7HlX7fvoCGz24at19XSC2piLKNVNoDjZCOXv8F8PpUcGTtAvQu4tNpHA kCYg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n63si13683328pga.432.2018.03.08.15.25.36; Thu, 08 Mar 2018 15:25:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751333AbeCHXYe (ORCPT + 99 others); Thu, 8 Mar 2018 18:24:34 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:43066 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751277AbeCHXYb (ORCPT ); Thu, 8 Mar 2018 18:24:31 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B92AEEC000; Thu, 8 Mar 2018 23:24:30 +0000 (UTC) Received: from malachite.bss.redhat.com (dhcp-10-20-1-75.bss.redhat.com [10.20.1.75]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4CC36202322A; Thu, 8 Mar 2018 23:24:30 +0000 (UTC) From: Lyude Paul To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: Manasi Navare , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Gustavo Padovan , Maarten Lankhorst , Sean Paul , David Airlie , linux-kernel@vger.kernel.org Subject: [PATCH 4/6] drm/dp_mst: Add drm_dp_mst_topology_mgr_lower_link_rate() Date: Thu, 8 Mar 2018 18:24:18 -0500 Message-Id: <20180308232421.14049-5-lyude@redhat.com> In-Reply-To: <20180308232421.14049-1-lyude@redhat.com> References: <20180308232421.14049-1-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Thu, 08 Mar 2018 23:24:30 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Thu, 08 Mar 2018 23:24:30 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'lyude@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Unlike SST, MST can have far more then a single display hooked up on a single port. What this also means however, is that if the DisplayPort link to the top-level MST branch device becomes unstable then every single branch device also has an unstable link. Additionally, MST has a few more steps that must be taken in order to properly retrain the entire topology under a lower link rate. Since the VCID allocations for each mstb is determined based off the link rate for the top of the topology, we also have to recalculate all of the VCID allocations for the downstream ports as well to ensure that we still have enough link bandwidth to drive each mstb. Additionally, since we have multiple downstream connectors per port, setting the link status of the parent mstb's port to bad isn't enough: all of the downstream mstb ports have to have their link status set to bad. This basically follows the same paradigm that our DP link status logic in DRM does, in that we simply tell userspace that all of the mstb ports need retraining and additionally applying the new lower bandwidth constraints to all of the atomic commits on the topology that follow. Since the work of figuring out which connectors live downstream on an MST topology and updating their link status is something that any driver supporting MST is going to need to do in order to retrain MST links properly, we add the drm_dp_mst_topology_mgr_lower_link_rate() helper which simply recalculates the pbn_div for a given mst topology, then marks the link status of all connectors living in that topology as bad. We'll make use of it in i915 later in this series. Signed-off-by: Lyude Paul Cc: Manasi Navare Cc: Ville Syrjälä --- drivers/gpu/drm/drm_dp_mst_topology.c | 73 ++++++++++++++++++++++++++++++++++- include/drm/drm_dp_mst_helper.h | 3 ++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 6fac4129e6a2..0d6604500b29 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -2076,7 +2076,7 @@ static bool drm_dp_get_vc_payload_bw(int dp_link_bw, { switch (dp_link_bw) { default: - DRM_DEBUG_KMS("invalid link bandwidth in DPCD: %x (link count: %d)\n", + DRM_DEBUG_KMS("invalid link bandwidth: %x (link count: %d)\n", dp_link_bw, dp_link_count); return false; @@ -2096,6 +2096,77 @@ static bool drm_dp_get_vc_payload_bw(int dp_link_bw, return true; } +static void drm_dp_set_mstb_link_status(struct drm_dp_mst_branch *mstb, + enum drm_link_status status) +{ + struct drm_dp_mst_branch *rmstb; + struct drm_dp_mst_port *port; + + list_for_each_entry(port, &mstb->ports, next) { + rmstb = drm_dp_get_validated_mstb_ref(mstb->mgr, port->mstb); + if (rmstb) { + drm_dp_set_mstb_link_status(rmstb, status); + drm_dp_put_mst_branch_device(rmstb); + } + + if (port->connector) + port->connector->state->link_status = status; + } +} + +/** + * drm_dp_mst_topology_mgr_lower_link_rate() - Override the DP link bw/count + * for all connectors in a given MST topology + * @mgr: manager to set state for + * @dp_link_bw: The new DP link bandwidth + * @dp_link_count: The new DP link count + * + * This is called by the driver when it detects that the current DP link for + * the given topology manager is unstable, and needs to be retrained at a + * lower link rate. + * + * This takes care of updating the link status on all downstream connectors + * along with recalculating the VC payloads. The driver should send a hotplug + * event after calling this function to notify userspace of the link status + * change. + * + * RETURNS: + * + * True for success, or negative error code on failure. + */ +int drm_dp_mst_topology_mgr_lower_link_rate(struct drm_dp_mst_topology_mgr *mgr, + int dp_link_bw, int dp_link_count) +{ + struct drm_device *dev = mgr->dev; + struct drm_dp_mst_branch *mst_primary; + int new_pbn_div; + int ret = 0; + + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + + if (!drm_dp_get_vc_payload_bw(drm_dp_link_rate_to_bw_code(dp_link_bw), + dp_link_count, &new_pbn_div)) { + ret = -EINVAL; + goto out; + } + + mst_primary = drm_dp_get_validated_mstb_ref(mgr, mgr->mst_primary); + if (!mst_primary) + goto out; + + DRM_DEBUG_KMS("MST link failed to retrain, lowering pbn_div to %d\n", + new_pbn_div); + mgr->pbn_div = new_pbn_div; + + drm_dp_set_mstb_link_status(mst_primary, DRM_MODE_LINK_STATUS_BAD); + + drm_dp_put_mst_branch_device(mst_primary); +out: + drm_modeset_unlock(&dev->mode_config.connection_mutex); + return ret; +} +EXPORT_SYMBOL(drm_dp_mst_topology_mgr_lower_link_rate); + /** * drm_dp_mst_topology_mgr_set_mst() - Set the MST state for a topology manager * @mgr: manager to set state for diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 7f78d26a0766..6261ec43a2c0 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -634,4 +634,7 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, bool power_up); +int drm_dp_mst_topology_mgr_lower_link_rate(struct drm_dp_mst_topology_mgr *mgr, + int dp_link_bw, int dp_link_count); + #endif -- 2.14.3