dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Andrei Rusu de Castro <arc@empyreal.works>
To: amd-gfx@lists.freedesktop.org
Cc: harry.wentland@amd.com, sunpeng.li@amd.com, siqueira@igalia.com,
	alexander.deucher@amd.com, christian.koenig@amd.com,
	airlied@gmail.com, simona@ffwll.ch, alex.hung@amd.com,
	roman.li@amd.com, mario.limonciello@amd.com,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	chen-yu.chen@amd.com, ray.wu@amd.com
Subject: [PATCH 4/4] drm/amd/display: test power module brightness input domain
Date: Wed, 02 Sep 2026 12:33:01 +0000	[thread overview]
Message-ID: <20260902-brightness-4-abf809f2@empyreal.works> (raw)
In-Reply-To: <20260902-brightness-cover-abf809f2@empyreal.works>

Exercise the exact value selected for the power module on PWM and AUX
panels. Cover non-zero and zero PWM minimums, both endpoints, an
interior value, clamping, invalid caps, and retention of the AUX custom
curve and source-unit brightness mask.

The PWM case carries valid ATIF points to prove that the display manager
passes the userspace percentage without applying that curve before the
power module applies its own lookup table. Additional cases prove that
the brightness mask follows the effective control type: true AUX remains
unchanged, while ordinary PWM and AUX fallback-to-PWM are masked. The
selected panel's linear-curve bypass is covered independently.

The cases were verified under UML KUnit.

Signed-off-by: Andrei Rusu de Castro <arc@empyreal.works>
---
 .../tests/amdgpu_dm_backlight_test.c          | 159 +++++++++++++++++-
 1 file changed, 156 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c
index a6fa052a8272..e0d46635130b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c
@@ -23,6 +23,7 @@
 #include "amdgpu_dm_kunit_test_helpers.h"
 #include "amd_shared.h"
 #include "link_service.h"
+#include "modules/power/power_helpers.h"
 #include "dc/inc/hw/panel_cntl.h"
 
 struct dm_backlight_connector_fixture {
@@ -1019,6 +1020,151 @@ static void dm_test_brightness_from_user_aux(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, convert_brightness_from_user(&caps, max), (u32)max);
 }
 
+/* Tests for convert_brightness_for_power_module() */
+
+/**
+ * dm_test_power_module_brightness_invalid_caps - Test invalid PWM range
+ * @test: The KUnit test context
+ */
+static void dm_test_power_module_brightness_invalid_caps(struct kunit *test)
+{
+	struct amdgpu_dm_backlight_caps caps = {};
+
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(NULL, 100), 100U);
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, 100), 0U);
+}
+
+/**
+ * dm_test_power_module_pwm_uses_user_domain - Test PWM input domain
+ * @test: The KUnit test context
+ *
+ * The power module owns the ATIF luminance-to-PWM curve. The display manager
+ * must therefore pass the original userspace percentage rather than first
+ * converting it to a firmware PWM level.
+ */
+static void dm_test_power_module_pwm_uses_user_domain(struct kunit *test)
+{
+	struct amdgpu_dm_backlight_caps caps = {};
+	unsigned int min, max;
+
+	caps.min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT;
+	caps.max_input_signal = AMDGPU_DM_DEFAULT_MAX_BACKLIGHT;
+	caps.data_points = 3;
+	caps.luminance_data[0].input_signal = 50;
+	caps.luminance_data[0].luminance = 20;
+	caps.luminance_data[1].input_signal = 128;
+	caps.luminance_data[1].luminance = 50;
+	caps.luminance_data[2].input_signal = 230;
+	caps.luminance_data[2].luminance = 90;
+	get_brightness_range(&caps, &min, &max);
+
+	KUNIT_EXPECT_EQ(test, min, 3084U);
+	KUNIT_EXPECT_EQ(test, max, 65535U);
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, 0), 0U);
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, 25700), 39216U);
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, 32768), 50001U);
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, max), 100000U);
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, max + 1), 100000U);
+}
+
+/**
+ * dm_test_power_module_pwm_zero_min - Test zero-minimum range
+ * @test: The KUnit test context
+ */
+static void dm_test_power_module_pwm_zero_min(struct kunit *test)
+{
+	struct amdgpu_dm_backlight_caps caps = {};
+	unsigned int min, max;
+
+	caps.min_input_signal = 0;
+	caps.max_input_signal = AMDGPU_DM_DEFAULT_MAX_BACKLIGHT;
+	get_brightness_range(&caps, &min, &max);
+
+	KUNIT_EXPECT_EQ(test, min, 0U);
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, 0), 0U);
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, max), 100000U);
+}
+
+/**
+ * dm_test_power_module_mask_follows_effective_control - Test mask handoff
+ * @test: The KUnit test context
+ */
+static void dm_test_power_module_mask_follows_effective_control(struct kunit *test)
+{
+	struct set_backlight_level_params params = {};
+	struct core_power core_power = {};
+
+	core_power.bl_prop[0].brightness_mask = 3;
+	fill_backlight_level_params(&core_power, &params, 0, 0, 3084,
+				    BACKLIGHT_CONTROL_PWM, 0, 0, false);
+	KUNIT_EXPECT_EQ(test, params.backlight_pwm_u16_16, 3087U);
+
+	fill_backlight_level_params(&core_power, &params, 0, 0, 32896,
+				    BACKLIGHT_CONTROL_PWM, 0, 0, false);
+	KUNIT_EXPECT_EQ(test, params.backlight_pwm_u16_16, 32899U);
+
+	fill_backlight_level_params(&core_power, &params, 0, 0, 65535,
+				    BACKLIGHT_CONTROL_PWM, 0, 0, false);
+	KUNIT_EXPECT_EQ(test, params.backlight_pwm_u16_16, 65535U);
+
+	fill_backlight_level_params(&core_power, &params, 0, 0, 3084,
+				    BACKLIGHT_CONTROL_AMD_AUX, 0, 0, true);
+	KUNIT_EXPECT_EQ(test, params.control_type, BACKLIGHT_CONTROL_AMD_AUX);
+	KUNIT_EXPECT_EQ(test, params.backlight_pwm_u16_16, 3084U);
+
+	fill_backlight_level_params(&core_power, &params, 0, 0, 3084,
+				    BACKLIGHT_CONTROL_AMD_AUX, 0, 0, false);
+	KUNIT_EXPECT_EQ(test, params.control_type, BACKLIGHT_CONTROL_PWM);
+	KUNIT_EXPECT_EQ(test, params.backlight_pwm_u16_16, 3087U);
+}
+
+/**
+ * dm_test_power_module_linear_curve_uses_panel_instance - Test linear bypass
+ * @test: The KUnit test context
+ */
+static void dm_test_power_module_linear_curve_uses_panel_instance(struct kunit *test)
+{
+	struct core_power core_power = {};
+	unsigned int backlight_lut[101] = {};
+
+	core_power.bl_prop[0].backlight_lut = backlight_lut;
+	core_power.bl_prop[0].num_backlight_levels = ARRAY_SIZE(backlight_lut);
+	core_power.bl_prop[1].min_backlight_pwm = 3084;
+	core_power.bl_prop[1].max_backlight_pwm = 65535;
+	core_power.bl_prop[1].backlight_range = 62451;
+	core_power.bl_prop[1].use_linear_backlight_curve = true;
+	backlight_lut[50] = 12345;
+
+	KUNIT_EXPECT_EQ(test, backlight_millipercent_to_pwm(&core_power, 50000, 1),
+			34309U);
+}
+
+/**
+ * dm_test_power_module_aux_keeps_curve_and_mask - Test AUX conversion path
+ * @test: The KUnit test context
+ */
+static void dm_test_power_module_aux_keeps_curve_and_mask(struct kunit *test)
+{
+	struct amdgpu_dm_backlight_caps caps = {};
+	uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+	amdgpu_dm_set_dc_debug_mask(saved_mask & ~DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+	caps.aux_support = true;
+	caps.aux_min_input_signal = 1;
+	caps.aux_max_input_signal = 512;
+	caps.brightness_mask = 3;
+	caps.data_points = 2;
+	caps.luminance_data[0].input_signal = 50;
+	caps.luminance_data[0].luminance = 20;
+	caps.luminance_data[1].input_signal = 200;
+	caps.luminance_data[1].luminance = 80;
+
+	KUNIT_EXPECT_EQ(test, convert_brightness_for_power_module(&caps, 200000),
+			81159U);
+
+	amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
 /* Tests for convert_custom_brightness() */
 
 /**
@@ -1590,7 +1736,7 @@ static void dm_test_curve_from_user_monotonic(struct kunit *test)
 	for (i = 0; i <= max; i += 1023) {
 		u32 level = convert_brightness_from_user(&caps, i);
 
-		KUNIT_ASSERT_GE(test, level, previous);
+		KUNIT_EXPECT_GE(test, level, previous);
 		previous = level;
 	}
 
@@ -1619,8 +1765,8 @@ static void dm_test_curve_from_user_within_range(struct kunit *test)
 	for (i = 0; i <= max; i += 1023) {
 		u32 level = convert_brightness_from_user(&caps, i);
 
-		KUNIT_ASSERT_GE(test, level, (u32)min);
-		KUNIT_ASSERT_LE(test, level, (u32)max);
+		KUNIT_EXPECT_GE(test, level, (u32)min);
+		KUNIT_EXPECT_LE(test, level, (u32)max);
 	}
 
 	KUNIT_EXPECT_LE(test, convert_brightness_from_user(&caps, max), (u32)max);
@@ -2198,6 +2344,13 @@ static struct kunit_case dm_backlight_test_cases[] = {
 	KUNIT_CASE(dm_test_brightness_from_user_zero),
 	KUNIT_CASE(dm_test_brightness_from_user_max),
 	KUNIT_CASE(dm_test_brightness_from_user_aux),
+	/* convert_brightness_for_power_module */
+	KUNIT_CASE(dm_test_power_module_brightness_invalid_caps),
+	KUNIT_CASE(dm_test_power_module_pwm_uses_user_domain),
+	KUNIT_CASE(dm_test_power_module_pwm_zero_min),
+	KUNIT_CASE(dm_test_power_module_mask_follows_effective_control),
+	KUNIT_CASE(dm_test_power_module_linear_curve_uses_panel_instance),
+	KUNIT_CASE(dm_test_power_module_aux_keeps_curve_and_mask),
 	/* convert_custom_brightness */
 	KUNIT_CASE(dm_test_custom_brightness_no_data_points),
 	KUNIT_CASE(dm_test_custom_brightness_debug_mask_disables),


  parent reply	other threads:[~2026-09-03  7:34 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02 12:31 [PATCH 0/4] drm/amd/display: fix brightness ownership through power module Andrei Rusu de Castro
2026-09-02 12:31 ` [PATCH 1/4] drm/amd/display: keep custom brightness curve in userspace domain Andrei Rusu de Castro
2026-09-02 12:31 ` [PATCH 2/4] drm/amd/display: test custom brightness with non-zero minimum Andrei Rusu de Castro
2026-09-02 12:32 ` [PATCH 3/4] drm/amd/display: pass userspace brightness to power module Andrei Rusu de Castro
2026-09-02 12:57   ` sashiko-bot
2026-09-02 12:33 ` Andrei Rusu de Castro [this message]
2026-09-02 22:31 ` [PATCH v2 0/4] drm/amd/display: fix brightness ownership through " Andrei Rusu de Castro
2026-09-02 22:31   ` [PATCH v2 1/4] drm/amd/display: keep custom brightness curve in userspace domain Andrei Rusu de Castro
2026-09-02 22:31   ` [PATCH v2 2/4] drm/amd/display: test custom brightness with non-zero minimum Andrei Rusu de Castro
2026-09-02 22:31   ` [PATCH v2 3/4] drm/amd/display: pass userspace brightness to power module Andrei Rusu de Castro
2026-09-03  7:50     ` sashiko-bot
2026-09-02 22:32   ` [PATCH v2 4/4] drm/amd/display: test power module brightness input domain Andrei Rusu de Castro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260902-brightness-4-abf809f2@empyreal.works \
    --to=arc@empyreal.works \
    --cc=airlied@gmail.com \
    --cc=alex.hung@amd.com \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=chen-yu.chen@amd.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=harry.wentland@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mario.limonciello@amd.com \
    --cc=ray.wu@amd.com \
    --cc=roman.li@amd.com \
    --cc=simona@ffwll.ch \
    --cc=siqueira@igalia.com \
    --cc=sunpeng.li@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox