From patchwork Tue Aug 23 14:50:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aaron Ma X-Patchwork-Id: 1669316 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=A6Mc0s7A; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MBsbz1FZGz1yhF for ; Wed, 24 Aug 2022 00:50:54 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1oQVEq-0004wG-9z; Tue, 23 Aug 2022 14:50:44 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1oQVEm-0004v0-6G for kernel-team@lists.ubuntu.com; Tue, 23 Aug 2022 14:50:40 +0000 Received: from localhost.localdomain (unknown [222.129.34.149]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id CA7EA3F13E for ; Tue, 23 Aug 2022 14:50:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1661266239; bh=rrlP8V0xkQn3Ge7W7YtVQIIqCpY+AzujDuEjMHGiof8=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=A6Mc0s7AuLDP4m1xVPLxPa2GzNmn0ct4jgmNdgdKlq5do72+Gw7HF8VyAduqZmAgf 7PbCTfPPH4jvObxQrZRpUjshKNamo7kNnFEgX8WGRw1BH2aaGs9/JvJWEQI8gYncp5 R12ARWyjVGgmMiMWDAqR625UATHMemD5lxemoS/xDyvj7hrY9ezNqKA+fKD6J/XFJE FTwNk2J++3m9F/SmZbzhvlVAWrE+po58Du0BLMSs5re/eNoij7gu3J8pLfabnXxICm yoal2/g/ng1BHOnyj44bQsY5pwJYWPQbkeGcDFc8JOJpAZkf4Hi9GU+1/r/D3DlSJa hYMCs6hmtl/MQ== From: Aaron Ma To: kernel-team@lists.ubuntu.com Subject: [OEM-5.17][PATCH 1/3] UBUNTU: SAUCE: drm: New function to get luminance range based on static hdr metadata Date: Tue, 23 Aug 2022 22:50:20 +0800 Message-Id: <20220823145022.1424144-3-aaron.ma@canonical.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220823145022.1424144-1-aaron.ma@canonical.com> References: <20220823145022.1424144-1-aaron.ma@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Jouni Högander BugLink: https://bugs.launchpad.net/bugs/1978986 Split luminance min/max calculation using static hdr metadata from drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:update_connector_ext_caps into drm/drm_edid.c and use it during edid parsing. Calculated range is stored into connector->display_info->luminance_range. Add new data structure (drm_luminance_range_inf) to store luminance range calculated using data from EDID's static hdr metadata block. Add this new struct as a part of drm_display_info struct. v3: Squashed adding drm_luminance_range_info patch here v2: Calculate range during edid parsing Cc: Roman Li Cc: Rodrigo Siqueira Cc: Harry Wentland Cc: Lyude Paul Cc: Mika Kahola Cc: Jani Nikula Cc: Manasi Navare Signed-off-by: Jouni Högander Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20220719095700.14923-2-jouni.hogander@intel.com (backported from commit 82068edeb5090b6f999457483623b39b6546ef74 https://anongit.freedesktop.org/git/drm/drm-misc.git drm-misc-next) [ aaron.ma: context adjustments ] Signed-off-by: Aaron Ma --- drivers/gpu/drm/drm_edid.c | 52 ++++++++++++++++++++++++++++++++++++- include/drm/drm_connector.h | 21 +++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 502ef71dac68..eaca4c348529 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -4409,6 +4409,51 @@ static bool cea_db_is_hdmi_hdr_metadata_block(const u8 *db) return true; } +static void drm_calculate_luminance_range(struct drm_connector *connector) +{ + struct hdr_static_metadata *hdr_metadata = &connector->hdr_sink_metadata.hdmi_type1; + struct drm_luminance_range_info *luminance_range = + &connector->display_info.luminance_range; + static const u8 pre_computed_values[] = { + 50, 51, 52, 53, 55, 56, 57, 58, 59, 61, 62, 63, 65, 66, 68, 69, + 71, 72, 74, 75, 77, 79, 81, 82, 84, 86, 88, 90, 92, 94, 96, 98 + }; + u32 max_avg, min_cll, max, min, q, r; + + if (!(hdr_metadata->metadata_type & BIT(HDMI_STATIC_METADATA_TYPE1))) + return; + + max_avg = hdr_metadata->max_fall; + min_cll = hdr_metadata->min_cll; + + /* + * From the specification (CTA-861-G), for calculating the maximum + * luminance we need to use: + * Luminance = 50*2**(CV/32) + * Where CV is a one-byte value. + * For calculating this expression we may need float point precision; + * to avoid this complexity level, we take advantage that CV is divided + * by a constant. From the Euclids division algorithm, we know that CV + * can be written as: CV = 32*q + r. Next, we replace CV in the + * Luminance expression and get 50*(2**q)*(2**(r/32)), hence we just + * need to pre-compute the value of r/32. For pre-computing the values + * We just used the following Ruby line: + * (0...32).each {|cv| puts (50*2**(cv/32.0)).round} + * The results of the above expressions can be verified at + * pre_computed_values. + */ + q = max_avg >> 5; + r = max_avg % 32; + max = (1 << q) * pre_computed_values[r]; + + /* min luminance: maxLum * (CV/255)^2 / 100 */ + q = DIV_ROUND_CLOSEST(min_cll, 255); + min = max * DIV_ROUND_CLOSEST((q * q), 100); + + luminance_range->min_luminance = min; + luminance_range->max_luminance = max; +} + static uint8_t eotf_supported(const u8 *edid_ext) { return edid_ext[2] & @@ -4440,8 +4485,12 @@ drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db) connector->hdr_sink_metadata.hdmi_type1.max_cll = db[4]; if (len >= 5) connector->hdr_sink_metadata.hdmi_type1.max_fall = db[5]; - if (len >= 6) + if (len >= 6) { connector->hdr_sink_metadata.hdmi_type1.min_cll = db[6]; + + /* Calculate only when all values are available */ + drm_calculate_luminance_range(connector); + } } static void @@ -5309,6 +5358,7 @@ drm_reset_display_info(struct drm_connector *connector) info->non_desktop = 0; memset(&info->monitor_range, 0, sizeof(info->monitor_range)); + memset(&info->luminance_range, 0, sizeof(info->luminance_range)); info->mso_stream_count = 0; info->mso_pixel_overlap = 0; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 5f88e484515a..24c26c8aaf87 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -322,6 +322,22 @@ struct drm_monitor_range_info { u8 max_vfreq; }; +/** + * struct drm_luminance_range_info - Panel's luminance range for + * &drm_display_info. Calculated using data in EDID + * + * This struct is used to store a luminance range supported by panel + * as calculated using data from EDID's static hdr metadata. + * + * @min_luminance: This is the min supported luminance value + * + * @max_luminance: This is the max supported luminance value + */ +struct drm_luminance_range_info { + u32 min_luminance; + u32 max_luminance; +}; + /** * enum drm_privacy_screen_status - privacy screen status * @@ -623,6 +639,11 @@ struct drm_display_info { */ struct drm_monitor_range_info monitor_range; + /** + * @luminance_range: Luminance range supported by panel + */ + struct drm_luminance_range_info luminance_range; + /** * @mso_stream_count: eDP Multi-SST Operation (MSO) stream count from * the DisplayID VESA vendor block. 0 for conventional Single-Stream