From patchwork Wed Jul 6 10:05:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 9216019 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 B3E2060752 for ; Wed, 6 Jul 2016 10:06:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A4B16287CB for ; Wed, 6 Jul 2016 10:06:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 99B11287EB; Wed, 6 Jul 2016 10:06:33 +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.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 32008287CB for ; Wed, 6 Jul 2016 10:06:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 239796E613; Wed, 6 Jul 2016 10:06:32 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x242.google.com (mail-wm0-x242.google.com [IPv6:2a00:1450:400c:c09::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7FF806E613 for ; Wed, 6 Jul 2016 10:06:30 +0000 (UTC) Received: by mail-wm0-x242.google.com with SMTP id a66so34470843wme.2 for ; Wed, 06 Jul 2016 03:06:30 -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 :mime-version:content-transfer-encoding; bh=xaT8/kP/kNCo/ceFxU8z9kB+BveKWCvPaVnqUM4qvpo=; b=wkN2Q4+tvnbsTzhETij32sbz3V7HWf86oHM9Y1skYUNE3TU6B2L/MhW0TqdwY3MsQ1 UpqdfTD+SscHGA7e1SVZvPlzq5XSBhkodrHIR1VYoi5B2kL36fdXriqZ+MCYY4yyzyqs MXUS8I0aOdzXvIaUdjeytqbkgMG9UcipZjaJ6xud6YWLiFoNEj7fWveA/nYymPH9KulO ElhvqVAB9QWyLjNgzzm54XmsHdUAjgrledAV97ERwxJbWPPfYokwcQJ/XTo4ia2GOqZO fb6zsNqD3hrUVAc+cBBSRpeBs6X+wcs4afghsHMBHQ4XNxgdAI36vwIE4CYf3kq5QCC4 TnCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xaT8/kP/kNCo/ceFxU8z9kB+BveKWCvPaVnqUM4qvpo=; b=RROPNrm73QeFtrDGiLMqjnPEoExGzmpYw6mUNGCo7TEgjLSw+hxcIh+so9lT1bqjnD MVAGE5nCrO6ro7DDyhR35bieyXs1ULmSzPAKBmfkPZhRn4rGzkvl6BVDghm4sbawLszK HKX5zbaB8teTVSIPYxa6a0WR7p3oGvDi/m6bXUdUybxXw2eglyoXw+PpYmcot5WAK9Mv GvpyoYA3Kpdx5bmavanZO04K2+e4RqrEedM5xuTEjR+OzmExg/LD1H0P+fbsWgM2HbxQ 4KOta87no2FzGBpecsPJ5l8DZPugM0O1vFU4UBo4XiNC7976pbtDEHhAGiqkE0tZIY5U T9Qg== X-Gm-Message-State: ALyK8tL5LZAz2xhbV54/2FEaCBuRpfURSBPqSKzk1Ye6+PoJJJx4GrjWuP+EWORX0jTvsA== X-Received: by 10.194.234.103 with SMTP id ud7mr19616729wjc.39.1467799588782; Wed, 06 Jul 2016 03:06:28 -0700 (PDT) Received: from twisty.fritz.box (x4d02cd4b.dyn.telefonica.de. [77.2.205.75]) by smtp.gmail.com with ESMTPSA id ze10sm2261276wjb.2.2016.07.06.03.06.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 Jul 2016 03:06:28 -0700 (PDT) From: Mario Kleiner To: dri-devel@lists.freedesktop.org Subject: [PATCH 3/5] drm/dp: Add helper to find bpc of a connected DP sink. Date: Wed, 6 Jul 2016 12:05:46 +0200 Message-Id: <1467799548-13229-4-git-send-email-mario.kleiner.de@gmail.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1467799548-13229-1-git-send-email-mario.kleiner.de@gmail.com> References: <1467799548-13229-1-git-send-email-mario.kleiner.de@gmail.com> MIME-Version: 1.0 Cc: Jani Nikula , Daniel Vetter X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 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" X-Virus-Scanned: ClamAV using ClamSMTP drm_dp_sink_bpc() is meant as a fallback to be used by kms drivers if a DP sink doesn't provide supported color depth bpc via EDID. It parses dpcd registers and optionally downstream port registers read by the driver from DP AUX and passed to the function to find out what the bpc of the connected sink likely is. For a DP sink without downstream ports it assumes it is a native DP display sink and applies the 6 bpc / 18 bpp fallback as required by the DP spec. For a DP sink with downstream ports, e.g., a DP -> legacy converter it makes the following assignment: If the converter is DP->DVI or DP->HDMI, it assumes 8 bpc depth. If the converter is DP->VGA it assumes at least 8 bpc, but tries to get a more accurate value (8, 10, 12 or 16 bpc) if the converter exposes this info. Tested with MiniDP->DP adapter, MiniDP->HDMI adapter, MiniDP->single-link DVI adapter, MiniDP->dual-link DVI active adapter, and a Apple MiniDP->VGA active adapter. Signed-off-by: Mario Kleiner Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Jani Nikula --- drivers/gpu/drm/drm_dp_helper.c | 90 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_dp_helper.h | 6 +++ 2 files changed, 96 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 091053e..2cf0289 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -160,6 +160,96 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw) } EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate); +/** + * drm_dp_sink_bpc - Parse dpcd to derive bpc of a DP sink. + * + * @dpcd: dpcd registers, starting at offset 0 + * @downstream_ports: downstream port info registers, starting at + * offset DP_DOWNSTREAM_PORT_0 + * @index: Index of the downstream port to query + * + * Derive color depth bpc of the connected DP sink. This is meant as + * a fallback for getting the sink bpc if the DP sink doesn't provide + * a useable bpc via EDID. It returns 6 bpc for a native DP sink + * without any downstream ports, as the spec mandates to assume 6 bpc + * if the true bpc of a native DP sink can't be found out from EDID. + * + * If the sink has multiple downstream ports then @index selects the + * downstream port to query, otherwise the first and only one is + * queried. + * + * The function can return 0 to signal that it can't derive bpc from the + * given information. + */ +int drm_dp_sink_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS], + unsigned int index) +{ + uint8_t type; + bool detail = false; + int bpc = 0; + + /* + * If there isn't any downstream port then this is a native DP sink. + * The standard requires to fall back to 6 bpc / 18 bpp for native DP + * sinks which don't provide bit depth via EDID. + */ + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) + return 6; + + /* Basic type of downstream ports? */ + type = dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK; + + /* + * Lacking other info, 8 bpc is a reasonable start for analog out. + * E.g., Apple MiniDP->VGA adaptors don't provide more info than + * that. Despite having DP_DPCD_REV == 0x11, their downstream_ports + * descriptor is empty - all zeros. DVI and HDMI also support at least + * 8 bpc, so a TMDS port type also implies 8 bpc. + */ + if (type == DP_DWN_STRM_PORT_TYPE_ANALOG || + type == DP_DWN_STRM_PORT_TYPE_TMDS) + bpc = 8; + + if (dpcd[DP_DPCD_REV] < 0x11) + return bpc; + + /* Rev 1.1+. More specific info available per downstream port. */ + + /* Detailed info of 4 Bytes per downstream port available? */ + if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) { + index *= 4; + detail = true; + } + + type = downstream_ports[index] & DP_DS_PORT_TYPE_MASK; + + /* VGA, DVI and HDMI support at least 8 bpc */ + if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_DVI || + type == DP_DS_PORT_TYPE_HDMI) + bpc = 8; + + /* As of DP interop v1.1a only VGA defines additional detail */ + if (detail && (type == DP_DS_PORT_TYPE_VGA)) { + /* VGA with detail provides bpc info */ + switch (downstream_ports[index + 2] & + DP_DS_VGA_MAX_BPC_MASK) { + default: + case DP_DS_VGA_8BPC: + return 8; + case DP_DS_VGA_10BPC: + return 10; + case DP_DS_VGA_12BPC: + return 12; + case DP_DS_VGA_16BPC: + return 16; + } + } + + return bpc; +} +EXPORT_SYMBOL(drm_dp_sink_bpc); + #define AUX_RETRY_INTERVAL 500 /* us */ /** diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 4d85cf2..0737cd0 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -203,6 +203,8 @@ * DP interop v1.1a only VGA defines additional detail. */ +#define DP_MAX_DOWNSTREAM_PORTS 0x10 + /* offset 0 */ #define DP_DOWNSTREAM_PORT_0 0x80 # define DP_DS_PORT_TYPE_MASK (7 << 0) @@ -630,6 +632,10 @@ void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]); u8 drm_dp_link_rate_to_bw_code(int link_rate); int drm_dp_bw_code_to_link_rate(u8 link_bw); +int drm_dp_sink_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS], + unsigned int index); + struct edp_sdp_header { u8 HB0; /* Secondary Data Packet ID */ u8 HB1; /* Secondary Data Packet Type */