From patchwork Fri May 6 17:42:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 9034981 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D88EDBF29F for ; Fri, 6 May 2016 17:42:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A9C252039D for ; Fri, 6 May 2016 17:42:31 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 8DA312026D for ; Fri, 6 May 2016 17:42:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C795D6EB21; Fri, 6 May 2016 17:42:29 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x230.google.com (mail-wm0-x230.google.com [IPv6:2a00:1450:400c:c09::230]) by gabe.freedesktop.org (Postfix) with ESMTPS id C51C66EB1F for ; Fri, 6 May 2016 17:42:27 +0000 (UTC) Received: by mail-wm0-x230.google.com with SMTP id e201so66251006wme.0 for ; Fri, 06 May 2016 10:42:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:references:to:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding; bh=Bkg6CMy9rIgcAVHHTeqaKlsbs/psmqkAeO4inoLDLUI=; b=E82FipoYOGViMUTl9uB6aWBZpELigQ3Wu7+v4zElxpEW/x/EKs5T3Bul7GmsxQm27k wczk2RZyL7Fm1f6r1MfIqiaatXgloatS64IDvfJ/682Lp7GgErGigtURDTEyO2LlV7/f 7amacZkze4b80/zQyWIZfgmF3Qb3bZbVWKVq/fmKsHjr31fnTscLuvsZLsDGv5eggYHE XzKjNafPaoWHO6yWAgmJ+YWztg/Tw+4WeowzQFBOvC9+UCk1qiorse1hx3ud3zkK+dnn mVigcf5aHASrZX055WzXsf6QwzrrucvkHH1tOyr030Z6KqLpKPOLmFiT9G+IcTpjludT uZbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:references:to:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=Bkg6CMy9rIgcAVHHTeqaKlsbs/psmqkAeO4inoLDLUI=; b=kWC9pz6WDwSAJkwiIfVjWK6MA/DkfPZl1v3LIov7GnLcMMjnUVLd/NqyzUau4UsANA I5NSih72gLX/8uJ1RhYxjJh871rf/YcDKD3B+j0TFp3TAQSbIl7dj3GSpVsGKJ5BjdGQ nV3mdE0gqbAfIR0iq0l0uZik2VPgvVu+O8pcM2E4931q4zDluFWZ9f1X5ul0pLQc5843 hAaRzTnJ7EkbpHC0KpOUT2FkH1EdsrQHGbIfdIyyp74g83GIA73MPsEXGW363UxbpyiL xKILJxtgStviNaFE2g4tZGadJyoRkabgu4t78weRsmimAXHu1/TS2CFJSCo8RcRg2eQW PoxA== X-Gm-Message-State: AOPr4FUbkw1GlBJJhh4tSJwymoqTD+BZXQz52dDlsIhfkiE0EVRQNBmdE6Akq3BwXMGDiQ== X-Received: by 10.28.226.213 with SMTP id z204mr10205221wmg.99.1462556546430; Fri, 06 May 2016 10:42:26 -0700 (PDT) Received: from [172.25.199.14] (cin-11.medizin.uni-tuebingen.de. [134.2.118.242]) by smtp.gmail.com with ESMTPSA id i3sm16005619wjx.30.2016.05.06.10.42.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 May 2016 10:42:25 -0700 (PDT) Subject: Fwd: [PATCH 2/3] drm/i915/dp: Try to find proper bpc for DP->legacy converters. References: <1459122767-13314-3-git-send-email-mario.kleiner.de@gmail.com> To: Jani Nikula , =?UTF-8?B?VmlsbGUgU3lyasOkbMOk?= , Daniel Vetter , "dri-devel@lists.freedesktop.org" From: Mario Kleiner X-Forwarded-Message-Id: <1459122767-13314-3-git-send-email-mario.kleiner.de@gmail.com> Message-ID: <572CD780.70606@gmail.com> Date: Fri, 6 May 2016 19:42:24 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.2 MIME-Version: 1.0 In-Reply-To: <1459122767-13314-3-git-send-email-mario.kleiner.de@gmail.com> 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-Spam-Status: No, score=-6.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP -------- Forwarded Message -------- Subject: [PATCH 2/3] drm/i915/dp: Try to find proper bpc for DP->legacy converters. Date: Mon, 28 Mar 2016 01:52:46 +0200 From: Mario Kleiner To: dri-devel@lists.freedesktop.org CC: mario.kleiner.de@gmail.com, Jani Nikula , Ville Syrjälä , Daniel Vetter , stable@vger.kernel.org This fixes a regression in output precision for DVI and VGA video sinks connected to Intel hw via active DisplayPort->DVI/VGA converters. The regression was indirectly introduced by commit 013dd9e03872 ("drm/i915/dp: fall back to 18 bpp when sink capability is unknown"). Our current drm edid 1.3 handling can't reliably assign a proper minimum supported display depth of 8 bpc to all DVI sinks, as mandated by DVI 1.0 spec, section 2.2.11.2 "Monitor data format support", but returns 0 bpc = "Don't know" instead. For analog VGA sinks it also returns 0 bpc, although those sinks themselves have infinite color depth, only restricted by the DAC resolution of the encoder. If a VGA or dual-link DVI display is connected via DisplayPort connector then due to above commit the driver would fall back to only 6 bpc, which would cause degradation for DVI and VGA displays, annoying in general, but especially harmful for application of display devices used in neuroscience research and for medical diagnosic which absolutely need native non-dithered 8 bpc at a minimum to operate correctly. For DP connectors with bpc == 0 according to EDID, fix this problem by checking the dpcd data to find out if a DP->legacy converter is connected. If the converter is DP->DVI/HDMI assume 8 bpc depth. If the converter is DP->VGA assume at least 8 bpc, but try to get a more accurate value (8, 10, 12 or 16 bpc) if the converter exposes this info. As the "fall back to 18 bpp" patch was backported to stable we should include this one also into stable to fix the regression in color depth for such panels. Tested with MiniDP->DP adapter, MiniDP->HDMI adapter, MiniDP->single-link DVI adapter, MiniDP->dual-link DVI active adapter, and Apple MiniDP->VGA active adapter. Signed-off-by: Mario Kleiner Cc: Jani Nikula Cc: Ville Syrjälä Cc: Daniel Vetter Cc: stable@vger.kernel.org --- drivers/gpu/drm/i915/intel_display.c | 12 ++++++++ drivers/gpu/drm/i915/intel_dp.c | 56 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + 3 files changed, 69 insertions(+) void intel_dp_hot_plug(struct intel_encoder *intel_encoder); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6e0d828..9903949 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12018,12 +12018,24 @@ connected_sink_compute_bpp(struct intel_connector *connector, if (connector->base.display_info.bpc == 0) { int type = connector->base.connector_type; int clamp_bpp = 24; + int legacy_bpc = 0; /* Fall back to 18 bpp when DP sink capability is unknown. */ if (type == DRM_MODE_CONNECTOR_DisplayPort || type == DRM_MODE_CONNECTOR_eDP) clamp_bpp = 18; + /* On DP to legacy converter, try harder to find sink bpc */ + if (type == DRM_MODE_CONNECTOR_DisplayPort) { + legacy_bpc = intel_dp_legacy_bpc(&connector->base); + + if (legacy_bpc) { + DRM_DEBUG_KMS("DP to VGA/DVI/HDMI converter with bpc %d\n", + legacy_bpc); + clamp_bpp = 3 * legacy_bpc; + } + } + if (bpp > clamp_bpp) { DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of %d\n", bpp, clamp_bpp); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f069a82..963a8f8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6117,3 +6117,59 @@ void intel_dp_mst_resume(struct drm_device *dev) } } } + +/* XXX Needs work for more than 1 downstream port */ +int intel_dp_legacy_bpc(struct drm_connector *connector) +{ + struct intel_dp *intel_dp = intel_attached_dp(connector); + uint8_t *dpcd = intel_dp->dpcd; + uint8_t type; + int bpc = 0; + + /* if there's no downstream port, then this can't be DP->legacy */ + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) + return bpc; + + /* Basic type of downstream ports */ + type = intel_dp->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. + */ + if (type == DP_DWN_STRM_PORT_TYPE_ANALOG) + bpc = 8; + + if (intel_dp->dpcd[DP_DPCD_REV] < 0x11) + return bpc; + + /* Rev 1.1+. More specific downstream port type available */ + type = intel_dp->downstream_ports[0] & 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 (type != DP_DS_PORT_TYPE_VGA || + !(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE)) + return bpc; + + /* VGA with DP_DETAILED_CAP_INFO_AVAILABLE provides bpc info */ + switch (intel_dp->downstream_ports[2] & DP_DS_VGA_MAX_BPC_MASK) { + 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; +} diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4c027d6..6692788 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1253,6 +1253,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); +int intel_dp_legacy_bpc(struct drm_connector *connector); int intel_dp_max_link_rate(struct intel_dp *intel_dp); int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);