From patchwork Mon Sep 2 11:31:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 11126467 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4F56114F7 for ; Mon, 2 Sep 2019 11:32:09 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3708622D6D for ; Mon, 2 Sep 2019 11:32:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3708622D6D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 13F0C89C2C; Mon, 2 Sep 2019 11:32:08 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by gabe.freedesktop.org (Postfix) with ESMTPS id 34A2C89C2C for ; Mon, 2 Sep 2019 11:32:06 +0000 (UTC) Received: by mail-wm1-x343.google.com with SMTP id k2so12750449wmj.4 for ; Mon, 02 Sep 2019 04:32:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ke8ei2MWYM73AcHvjLqyuqbcohrAAivQ3mJlayP9epM=; b=j+Vnv03q0K2OSU/RSlj35Lw8K+EhgrT93X226o/66t6QSOL43FdBuI6Jkt3HEH7PC0 w7nZHpr8cG3/E3t381KIjHmrAuBIUBA+ijxu1Kd0DAjxD22NXbWfS8Ntjmmp2poRLsmf RgUd5XCBWEYjdCnvqUwQWUIieVi2bkC/Oa2rIOoCPs1CeQ7aJE9QPFNgAdxyDxtAPvP0 2ZQZrljM+l0hcyRnFgoVGN98lOwK93nz44COE2l9vWLbeVA4l8VTEwmTkQEoFl/39m9/ SvPO6qhby4pxwX8B/VRrhZI1yC+yw55u1gZrJ5lcju9m9JgBWmYQRaM3guAZA2XKSDND ZeqA== X-Gm-Message-State: APjAAAWPyuSlzyXfwVImzafmGQyEwOG1oi+FvqHDAd5MsbjcqK9UiFI8 HsnaQLRMrLKVvwAVUjj87XX9yfFE X-Google-Smtp-Source: APXvYqxhhOdlHp7yKBd9Zst/22Y9JKOpdnoX7tUyepJ6czuQ3EtNgVRnJFiuhQ5/FlNJflhr8cvWWA== X-Received: by 2002:a7b:cb03:: with SMTP id u3mr35825845wmj.58.1567423924432; Mon, 02 Sep 2019 04:32:04 -0700 (PDT) Received: from localhost (pD9E51890.dip0.t-ipconnect.de. [217.229.24.144]) by smtp.gmail.com with ESMTPSA id f66sm1132438wmg.2.2019.09.02.04.32.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Sep 2019 04:32:03 -0700 (PDT) From: Thierry Reding To: dri-devel@lists.freedesktop.org Subject: [PATCH v2 19/21] drm/dp: Add support for eDP link rates Date: Mon, 2 Sep 2019 13:31:19 +0200 Message-Id: <20190902113121.31323-20-thierry.reding@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190902113121.31323-1-thierry.reding@gmail.com> References: <20190902113121.31323-1-thierry.reding@gmail.com> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ke8ei2MWYM73AcHvjLqyuqbcohrAAivQ3mJlayP9epM=; b=qNyDYj2yqjNO2rl9ZP+sLMKFQKZ3oEtLXimMOlWaXFeLhhC6Hc2NQ2rm6CnDk8ZRk1 JZQPR5fmX6ta0dpiu520A/2jgW4gp4XN0kPfuuePB6SgdxHsT++cvcv2/pXN4eR8Qi16 +yn0oVhN7z3a2aRgI63XS45BUMWn2MhgUIB+NpQTuboZpVeKwxuSmgBnk9gKlfM197Fz VYNS2e4+mZv2kq5LkD2uvSCPXTw1G0etRt4LXvzzvfd7QTBk3e21ncSpSnvv32Y89m5U tI05vtF+wvofyjfSvRJ86XVCUSaVGcDh1br3J+yVGYiakb5999mhiCopjVPEag6PvG8f 1MwA== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Thierry Reding Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_dp_helper.c | 121 ++++++++++++++++++++++++++++++++ include/drm/drm_dp_helper.h | 9 +++ 2 files changed, 130 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 01d34f33c658..136ee609f2ee 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -385,6 +385,107 @@ static void drm_dp_link_reset(struct drm_dp_link *link) link->lanes = 0; } +/** + * drm_dp_link_add_rate() - add a rate to the list of supported rates + * @link: the link to add the rate to + * @rate: the rate to add + * + * Add a link rate to the list of supported link rates. + * + * Returns: + * 0 on success or one of the following negative error codes on failure: + * - ENOSPC if the maximum number of supported rates has been reached + * - EEXISTS if the link already supports this rate + * + * See also: + * drm_dp_link_remove_rate() + */ +int drm_dp_link_add_rate(struct drm_dp_link *link, unsigned long rate) +{ + unsigned int i, pivot; + + if (link->num_rates == DP_MAX_SUPPORTED_RATES) + return -ENOSPC; + + for (pivot = 0; pivot < link->num_rates; pivot++) + if (rate <= link->rates[pivot]) + break; + + if (pivot != link->num_rates && rate == link->rates[pivot]) + return -EEXIST; + + for (i = link->num_rates; i > pivot; i--) + link->rates[i] = link->rates[i - 1]; + + link->rates[pivot] = rate; + link->num_rates++; + + return 0; +} +EXPORT_SYMBOL(drm_dp_link_add_rate); + +/** + * drm_dp_link_remove_rate() - remove a rate from the list of supported rates + * @link: the link from which to remove the rate + * @rate: the rate to remove + * + * Removes a link rate from the list of supported link rates. + * + * Returns: + * 0 on success or one of the following negative error codes on failure: + * - EINVAL if the specified rate is not among the supported rates + * + * See also: + * drm_dp_link_add_rate() + */ +int drm_dp_link_remove_rate(struct drm_dp_link *link, unsigned long rate) +{ + unsigned int i; + + for (i = 0; i < link->num_rates; i++) + if (rate == link->rates[i]) + break; + + if (i == link->num_rates) + return -EINVAL; + + link->num_rates--; + + for (i = i; i < link->num_rates; i++) + link->rates[i] = link->rates[i + 1]; + + return 0; +} +EXPORT_SYMBOL(drm_dp_link_remove_rate); + +/** + * drm_dp_link_update_rates() - normalize the supported link rates array + * @link: the link for which to normalize the supported link rates + * + * Users should call this function after they've manually modified the array + * of supported link rates. This function removes any stale entries, compacts + * the array and updates the supported link rate count. Note that calling the + * drm_dp_link_remove_rate() function already does this janitorial work. + * + * See also: + * drm_dp_link_add_rate(), drm_dp_link_remove_rate() + */ +void drm_dp_link_update_rates(struct drm_dp_link *link) +{ + unsigned int i, count = 0; + + for (i = 0; i < link->num_rates; i++) { + if (link->rates[i] != 0) + link->rates[count++] = link->rates[i]; + } + + for (i = count; i < link->num_rates; i++) + link->rates[i] = 0; + + link->num_rates = count; +} +EXPORT_SYMBOL(drm_dp_link_update_rates); + /** * drm_dp_link_probe() - probe a DisplayPort link for capabilities * @aux: DisplayPort AUX channel @@ -437,6 +538,26 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link) link->rate = link->max_rate; link->lanes = link->max_lanes; + /* Parse SUPPORTED_LINK_RATES from eDP 1.4 */ + if (link->edp >= 0x14) { + u8 supported_rates[DP_MAX_SUPPORTED_RATES * 2]; + unsigned int i; + u16 rate; + + err = drm_dp_dpcd_read(aux, DP_SUPPORTED_LINK_RATES, + supported_rates, + sizeof(supported_rates)); + if (err < 0) + return err; + + for (i = 0; i < DP_MAX_SUPPORTED_RATES; i++) { + rate = supported_rates[i * 2 + 1] << 8 | + supported_rates[i * 2 + 0]; + + drm_dp_link_add_rate(link, rate * 200); + } + } + return 0; } EXPORT_SYMBOL(drm_dp_link_probe); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 817231e38053..dfe16069e029 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1453,6 +1453,8 @@ void drm_dp_link_caps_copy(struct drm_dp_link_caps *dest, * @edp: eDP revision (0x11: eDP 1.1, 0x12: eDP 1.2, ...) * @rate: currently configured link rate * @lanes: currently configured number of lanes + * @rates: additional supported link rates in kHz (eDP 1.4) + * @num_rates: number of additional supported link rates (eDP 1.4) */ struct drm_dp_link { unsigned char revision; @@ -1465,8 +1467,15 @@ struct drm_dp_link { unsigned int rate; unsigned int lanes; + + unsigned long rates[DP_MAX_SUPPORTED_RATES]; + unsigned int num_rates; }; +int drm_dp_link_add_rate(struct drm_dp_link *link, unsigned long rate); +int drm_dp_link_remove_rate(struct drm_dp_link *link, unsigned long rate); +void drm_dp_link_update_rates(struct drm_dp_link *link); + int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link);