From patchwork Mon Jun 2 14:29:58 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 4282691 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 740D89F1D6 for ; Mon, 2 Jun 2014 14:30:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 40B0D203DC for ; Mon, 2 Jun 2014 14:30:22 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id A4F20203E1 for ; Mon, 2 Jun 2014 14:30:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9BDB76E592; Mon, 2 Jun 2014 07:30:11 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qg0-f52.google.com (mail-qg0-f52.google.com [209.85.192.52]) by gabe.freedesktop.org (Postfix) with ESMTP id 28BB16E590 for ; Mon, 2 Jun 2014 07:30:08 -0700 (PDT) Received: by mail-qg0-f52.google.com with SMTP id a108so11007087qge.11 for ; Mon, 02 Jun 2014 07:30:07 -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; bh=88nf//L5jSdURxRn4HBHUp5zU90WRNe1kTnD11aJT80=; b=MHS2Nd8kn0KX4BSdWbGGoG0MrY565bbPZUZkOLudL066xlJkg+bvOo5ubpbxiyXZ+d cxUJckVVUAGe+fOXtxS3GoHMiEukIKy+vAPZxG9oZ/axutUOpMuvy6ugNVt9qiw23M50 aoMODuatgua096uVeixwUVImbSP666DlETri6jZJZQg4mh7FrBXVv3Kq7fsWrbraiSqA o4Aj1glN/6nPgdszp4GimKgHx9R82e1LPFbVfUU2hEdfNBmH9jZ3EKvo1ejSbzZabEud iAM9hWGly4s/GXcEUhUMyZJNY1PkuIkX+AU22w13LLgHxrzU3THLiM0ddLTVxAjhnSVo BDVQ== X-Received: by 10.224.161.10 with SMTP id p10mr42860474qax.12.1401719407750; Mon, 02 Jun 2014 07:30:07 -0700 (PDT) Received: from localhost.localdomain (static-74-96-105-49.washdc.fios.verizon.net. [74.96.105.49]) by mx.google.com with ESMTPSA id b5sm8440211qgb.16.2014.06.02.07.30.07 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Jun 2014 07:30:07 -0700 (PDT) From: Alex Deucher X-Google-Original-From: Alex Deucher To: dri-devel@lists.freedesktop.org Subject: [PATCH 6/7] drm/edid: Parse and handle HDMI deep color modes. Date: Mon, 2 Jun 2014 10:29:58 -0400 Message-Id: <1401719399-6951-6-git-send-email-alexander.deucher@amd.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1401719399-6951-1-git-send-email-alexander.deucher@amd.com> References: <1401719399-6951-1-git-send-email-alexander.deucher@amd.com> Cc: Alex Deucher X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.7 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=ham 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 From: Mario Kleiner Check the HDMI cea block for deep color mode bits. If available, assign the highest supported bpc for a hdmi display, corresponding to the given deep color modes. Signed-off-by: Mario Kleiner Signed-off-by: Alex Deucher --- drivers/gpu/drm/drm_edid.c | 110 ++++++++++++++++++++++++++++++++++++++++++++- include/drm/drm_edid.h | 5 +++ 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index d74239f..3989c18 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3423,16 +3423,116 @@ bool drm_rgb_quant_range_selectable(struct edid *edid) EXPORT_SYMBOL(drm_rgb_quant_range_selectable); /** + * drm_assign_hdmi_deep_color_info - detect whether monitor supports + * hdmi deep color modes and update drm_display_info if so. + * + * @edid: monitor EDID information + * @info: Updated with maximum supported deep color bpc and color format + * if deep color supported. + * + * Parse the CEA extension according to CEA-861-B. + * Return true if HDMI deep color supported, false if not or unknown. + */ +static bool drm_assign_hdmi_deep_color_info(struct edid *edid, + struct drm_display_info *info, + struct drm_connector *connector) +{ + u8 *edid_ext, *hdmi; + int i; + int start_offset, end_offset; + unsigned int dc_bpc = 0; + + edid_ext = drm_find_cea_extension(edid); + if (!edid_ext) + return false; + + if (cea_db_offsets(edid_ext, &start_offset, &end_offset)) + return false; + + /* + * Because HDMI identifier is in Vendor Specific Block, + * search it from all data blocks of CEA extension. + */ + for_each_cea_db(edid_ext, i, start_offset, end_offset) { + if (cea_db_is_hdmi_vsdb(&edid_ext[i])) { + /* HDMI supports at least 8 bpc */ + info->bpc = 8; + + hdmi = &edid_ext[i]; + if (cea_db_payload_len(hdmi) < 6) + return false; + + if (hdmi[6] & DRM_EDID_HDMI_DC_30) { + dc_bpc = 10; + DRM_DEBUG("%s: HDMI sink does deep color 30.\n", + drm_get_connector_name(connector)); + } + + if (hdmi[6] & DRM_EDID_HDMI_DC_36) { + dc_bpc = 12; + DRM_DEBUG("%s: HDMI sink does deep color 36.\n", + drm_get_connector_name(connector)); + } + + if (hdmi[6] & DRM_EDID_HDMI_DC_48) { + dc_bpc = 16; + DRM_DEBUG("%s: HDMI sink does deep color 48.\n", + drm_get_connector_name(connector)); + } + + if (dc_bpc > 0) { + DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n", + drm_get_connector_name(connector), dc_bpc); + info->bpc = dc_bpc; + + /* + * Deep color support mandates RGB444 support for all video + * modes and forbids YCRCB422 support for all video modes per + * HDMI 1.3 spec. + */ + info->color_formats = DRM_COLOR_FORMAT_RGB444; + + /* YCRCB444 is optional according to spec. */ + if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) { + info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; + DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n", + drm_get_connector_name(connector)); + } + + /* + * Spec says that if any deep color mode is supported at all, + * then deep color 36 bit must be supported. + */ + if (!(hdmi[6] & DRM_EDID_HDMI_DC_36)) { + DRM_DEBUG("%s: HDMI sink should do DC_36, but does not!\n", + drm_get_connector_name(connector)); + } + + return true; + } + else { + DRM_DEBUG("%s: No deep color support on this HDMI sink.\n", + drm_get_connector_name(connector)); + } + } + } + + return false; +} + +/** * drm_add_display_info - pull display info out if present * @edid: EDID data * @info: display info (attached to connector) + * @connector: connector whose edid is used to build display info * * Grab any available display info and stuff it into the drm_display_info * structure that's part of the connector. Useful for tracking bpp and * color spaces. */ static void drm_add_display_info(struct edid *edid, - struct drm_display_info *info) + struct drm_display_info *info, + struct drm_connector *connector) { u8 *edid_ext; @@ -3462,6 +3562,9 @@ static void drm_add_display_info(struct edid *edid, info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; } + /* HDMI deep color modes supported? Assign to info, if so */ + drm_assign_hdmi_deep_color_info(edid, info, connector); + /* Only defined for 1.4 with digital displays */ if (edid->revision < 4) return; @@ -3491,6 +3594,9 @@ static void drm_add_display_info(struct edid *edid, break; } + DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n", + drm_get_connector_name(connector), info->bpc); + info->color_formats |= DRM_COLOR_FORMAT_RGB444; if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444) info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; @@ -3549,7 +3655,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) edid_fixup_preferred(connector, quirks); - drm_add_display_info(edid, &connector->display_info); + drm_add_display_info(edid, &connector->display_info, connector); if (quirks & EDID_QUIRK_FORCE_8BPC) connector->display_info.bpc = 8; diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index a1441c5..b96031d 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -202,6 +202,11 @@ struct detailed_timing { #define DRM_EDID_FEATURE_PM_SUSPEND (1 << 6) #define DRM_EDID_FEATURE_PM_STANDBY (1 << 7) +#define DRM_EDID_HDMI_DC_48 (1 << 6) +#define DRM_EDID_HDMI_DC_36 (1 << 5) +#define DRM_EDID_HDMI_DC_30 (1 << 4) +#define DRM_EDID_HDMI_DC_Y444 (1 << 3) + struct edid { u8 header[8]; /* Vendor & product info */