From: Alex Hung <[email protected]>

Add KUnit tests for the backlight helpers in amdgpu_dm_backlight.c.

Tests cover:
- amdgpu_dm_update_backlight_caps(): short-circuit on populated caps
  and default value assignment
- get_brightness_range(): NULL, PWM-only, and AUX backlight paths
- convert_brightness_to_user(): minimum clamp, maximum passthrough,
  and mid-range rescaling
- convert_brightness_from_user(): linear rescaling, AUX path, and
  custom-curve mapping
- convert_custom_brightness(): exact match, below-first, interpolation,
  above-last, single data point, zero lower luminance, and the
  debug-mask and no-data-point guards
- amdgpu_dm_update_connector_ext_caps(): negative bl_idx and non-eDP
  early returns, OLED defaults, luminance range copy, and the
  amdgpu_backlight force-AUX/force-PWM overrides
- amdgpu_dm_should_create_sysfs(): forced ABM, non-eDP, missing
  backlight index, and AUX vs PWM backlight
- amdgpu_dm_setup_backlight_device(): non-eDP/LVDS skip, disconnected
  link skip, eDP-count limit, and the successful eDP setup path

Assisted-by: Copilot:Claude-Opus-4.8

Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
Signed-off-by: Chenyu Chen <[email protected]>
---
 .../display/amdgpu_dm/amdgpu_dm_backlight.c   |   71 +-
 .../display/amdgpu_dm/amdgpu_dm_backlight.h   |   18 +
 .../drm/amd/display/amdgpu_dm/tests/Makefile  |    2 +
 .../tests/amdgpu_dm_backlight_test.c          | 1128 +++++++++++++++++
 4 files changed, 1210 insertions(+), 9 deletions(-)
 create mode 100644 
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
index 3770e8dafdbf..f101aed75bb3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
@@ -47,6 +47,7 @@
 
 #include "amdgpu_dm_trace.h"
 #include "amd_shared.h"
+#include "amdgpu_dm_kunit_helpers.h"
 
 #define AMDGPU_DM_DEFAULT_MIN_BACKLIGHT 12
 #define AMDGPU_DM_DEFAULT_MAX_BACKLIGHT 255
@@ -92,9 +93,11 @@ void amdgpu_dm_update_backlight_caps(struct 
amdgpu_display_manager *dm,
        caps->caps_valid = true;
 #endif
 }
+EXPORT_IF_KUNIT(amdgpu_dm_update_backlight_caps);
 
-static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
-                               unsigned int *min, unsigned int *max)
+STATIC_IFN_KUNIT
+int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
+                        unsigned int *min, unsigned int *max)
 {
        if (!caps)
                return 0;
@@ -110,6 +113,7 @@ static int get_brightness_range(const struct 
amdgpu_dm_backlight_caps *caps,
        }
        return 1;
 }
+EXPORT_IF_KUNIT(get_brightness_range);
 
 /* Rescale from [min..max] to [0..AMDGPU_MAX_BL_LEVEL] */
 static inline u32 scale_input_to_fw(int min, int max, u64 input)
@@ -123,9 +127,10 @@ static inline u32 scale_fw_to_input(int min, int max, u64 
input)
        return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), 
AMDGPU_MAX_BL_LEVEL);
 }
 
-static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps 
*caps,
-                                     unsigned int min, unsigned int max,
-                                     uint32_t *user_brightness)
+STATIC_IFN_KUNIT
+void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
+                              unsigned int min, unsigned int max,
+                              uint32_t *user_brightness)
 {
        u32 brightness = scale_input_to_fw(min, max, *user_brightness);
        u8 lower_signal, upper_signal, upper_lum, lower_lum, lum;
@@ -187,8 +192,11 @@ static void convert_custom_brightness(const struct 
amdgpu_dm_backlight_caps *cap
                                             DIV_ROUND_CLOSEST(lum * 
brightness, 101));
 }
 
-static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps 
*caps,
-                                       uint32_t brightness)
+EXPORT_IF_KUNIT(convert_custom_brightness);
+
+STATIC_IFN_KUNIT
+u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
+                               uint32_t brightness)
 {
        unsigned int min, max;
 
@@ -201,8 +209,11 @@ static u32 convert_brightness_from_user(const struct 
amdgpu_dm_backlight_caps *c
        return min + DIV_ROUND_CLOSEST_ULL((u64)(max - min) * brightness, max);
 }
 
-static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps 
*caps,
-                                     uint32_t brightness)
+EXPORT_IF_KUNIT(convert_brightness_from_user);
+
+STATIC_IFN_KUNIT
+u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps,
+                             uint32_t brightness)
 {
        unsigned int min, max;
 
@@ -215,6 +226,7 @@ static u32 convert_brightness_to_user(const struct 
amdgpu_dm_backlight_caps *cap
        return DIV_ROUND_CLOSEST_ULL((u64)max * (brightness - min),
                                 max - min);
 }
+EXPORT_IF_KUNIT(convert_brightness_to_user);
 
 static struct dc_stream_state *dm_find_stream_with_link(
        struct amdgpu_display_manager *dm,
@@ -529,6 +541,7 @@ void amdgpu_dm_update_connector_ext_caps(struct 
amdgpu_dm_connector *aconnector)
                }
        }
 }
+EXPORT_IF_KUNIT(amdgpu_dm_update_connector_ext_caps);
 
 void amdgpu_dm_setup_backlight_device(struct amdgpu_display_manager *dm,
                            struct amdgpu_dm_connector *aconnector)
@@ -561,6 +574,7 @@ void amdgpu_dm_setup_backlight_device(struct 
amdgpu_display_manager *dm,
                                           
dm->adev->mode_info.abm_level_property,
                                           ABM_SYSFS_CONTROL);
 }
+EXPORT_IF_KUNIT(amdgpu_dm_setup_backlight_device);
 
 /**
  * DOC: panel power savings
@@ -658,3 +672,42 @@ amdgpu_dm_should_create_sysfs(struct amdgpu_dm_connector 
*amdgpu_dm_connector)
 
        return true;
 }
+EXPORT_IF_KUNIT(amdgpu_dm_should_create_sysfs);
+
+#if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
+uint amdgpu_dm_get_dc_debug_mask(void)
+{
+       return amdgpu_dc_debug_mask;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_get_dc_debug_mask);
+
+void amdgpu_dm_set_dc_debug_mask(uint val)
+{
+       amdgpu_dc_debug_mask = val;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_set_dc_debug_mask);
+
+int amdgpu_dm_get_abm_level_param(void)
+{
+       return amdgpu_dm_abm_level;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_get_abm_level_param);
+
+void amdgpu_dm_set_abm_level_param(int val)
+{
+       amdgpu_dm_abm_level = val;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_set_abm_level_param);
+
+int amdgpu_dm_get_backlight_param(void)
+{
+       return amdgpu_backlight;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_get_backlight_param);
+
+void amdgpu_dm_set_backlight_param(int val)
+{
+       amdgpu_backlight = val;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_set_backlight_param);
+#endif
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.h
index acff23f9feef..5234da6ae484 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.h
@@ -41,4 +41,22 @@ bool amdgpu_dm_should_create_sysfs(struct 
amdgpu_dm_connector *aconnector);
 
 extern const struct attribute_group amdgpu_group;
 
+#if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
+int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
+                        unsigned int *min, unsigned int *max);
+void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
+                              unsigned int min, unsigned int max,
+                              uint32_t *user_brightness);
+u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
+                                uint32_t brightness);
+u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps,
+                              uint32_t brightness);
+uint amdgpu_dm_get_dc_debug_mask(void);
+void amdgpu_dm_set_dc_debug_mask(uint val);
+int amdgpu_dm_get_abm_level_param(void);
+void amdgpu_dm_set_abm_level_param(int val);
+int amdgpu_dm_get_backlight_param(void);
+void amdgpu_dm_set_backlight_param(int val);
+#endif
+
 #endif /* __AMDGPU_DM_BACKLIGHT_H__ */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Makefile 
b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Makefile
index 4365d4024f70..ddd9fce66232 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/Makefile
@@ -8,12 +8,14 @@ ccflags-y += -I$(src)/../../include
 ccflags-y += -I$(src)/../../modules/inc
 ccflags-y += -I$(src)/../../dc
 ccflags-y += -I$(src)/../../../amdgpu
+ccflags-y += -I$(src)/../../../amdkfd
 ccflags-y += -I$(src)/../../../include
 
 obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_crc_test.o
 obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_hdcp_test.o
 obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_color_test.o
 obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_colorop_test.o
+obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_backlight_test.o
 obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_psr_test.o
 obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_replay_test.o
 obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_ism_test.o
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
new file mode 100644
index 000000000000..2f4293cfd478
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c
@@ -0,0 +1,1128 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * KUnit tests for amdgpu_dm_backlight.c
+ *
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#include <kunit/test.h>
+
+#include "dc.h"
+#include "amdgpu.h"
+#include "amdgpu_mode.h"
+#include "amdgpu_dm.h"
+#include "amdgpu_dm_backlight.h"
+#include "amd_shared.h"
+
+struct dm_backlight_connector_fixture {
+       struct amdgpu_device *adev;
+       struct amdgpu_dm_connector *aconnector;
+       struct dc_link *link;
+};
+
+static struct amdgpu_display_manager *alloc_test_dm(struct kunit *test)
+{
+       struct amdgpu_display_manager *dm;
+
+       dm = kunit_kzalloc(test, sizeof(*dm), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, dm);
+
+       return dm;
+}
+
+static void setup_test_connector(struct kunit *test,
+                                struct dm_backlight_connector_fixture *fixture,
+                                int bl_idx, enum signal_type signal)
+{
+       fixture->adev = kunit_kzalloc(test, sizeof(*fixture->adev), GFP_KERNEL);
+       fixture->aconnector = kunit_kzalloc(test, sizeof(*fixture->aconnector), 
GFP_KERNEL);
+       fixture->link = kunit_kzalloc(test, sizeof(*fixture->link), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->adev);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->aconnector);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->link);
+
+       fixture->aconnector->bl_idx = bl_idx;
+       fixture->aconnector->dc_link = fixture->link;
+       fixture->aconnector->base.dev = &fixture->adev->ddev;
+       fixture->link->connector_signal = signal;
+}
+
+/* Tests for amdgpu_dm_update_backlight_caps() */
+
+/**
+ * dm_test_backlight_caps_valid_short_circuit - Test Backlight caps valid 
short circuit
+ * @test: The KUnit test context
+ */
+static void dm_test_backlight_caps_valid_short_circuit(struct kunit *test)
+{
+       struct amdgpu_display_manager *dm = alloc_test_dm(test);
+       struct amdgpu_dm_backlight_caps *caps = &dm->backlight_caps[0];
+
+       caps->caps_valid = true;
+       caps->aux_support = false;
+       caps->min_input_signal = 42;
+       caps->max_input_signal = 199;
+
+       amdgpu_dm_update_backlight_caps(dm, 0);
+
+       KUNIT_EXPECT_TRUE(test, caps->caps_valid);
+       KUNIT_EXPECT_EQ(test, caps->min_input_signal, 42);
+       KUNIT_EXPECT_EQ(test, caps->max_input_signal, 199);
+}
+
+#if !defined(CONFIG_ACPI)
+
+/**
+ * dm_test_backlight_caps_aux_support_noop - Test Backlight caps aux support 
noop
+ * @test: The KUnit test context
+ */
+static void dm_test_backlight_caps_aux_support_noop(struct kunit *test)
+{
+       struct amdgpu_display_manager *dm = alloc_test_dm(test);
+       struct amdgpu_dm_backlight_caps *caps = &dm->backlight_caps[0];
+
+       caps->caps_valid = false;
+       caps->aux_support = true;
+       caps->min_input_signal = 11;
+       caps->max_input_signal = 222;
+
+       amdgpu_dm_update_backlight_caps(dm, 0);
+
+       KUNIT_EXPECT_FALSE(test, caps->caps_valid);
+       KUNIT_EXPECT_EQ(test, caps->min_input_signal, 11);
+       KUNIT_EXPECT_EQ(test, caps->max_input_signal, 222);
+}
+
+/**
+ * dm_test_backlight_caps_non_aux_sets_defaults - Test Backlight caps non aux 
sets defaults
+ * @test: The KUnit test context
+ */
+static void dm_test_backlight_caps_non_aux_sets_defaults(struct kunit *test)
+{
+       struct amdgpu_display_manager *dm = alloc_test_dm(test);
+       struct amdgpu_dm_backlight_caps *caps = &dm->backlight_caps[0];
+
+       caps->caps_valid = false;
+       caps->aux_support = false;
+       caps->min_input_signal = 0;
+       caps->max_input_signal = 0;
+
+       amdgpu_dm_update_backlight_caps(dm, 0);
+
+       KUNIT_EXPECT_TRUE(test, caps->caps_valid);
+       KUNIT_EXPECT_EQ(test, caps->min_input_signal, 12);
+       KUNIT_EXPECT_EQ(test, caps->max_input_signal, 255);
+}
+#endif
+
+/* Tests for get_brightness_range() */
+
+/**
+ * dm_test_brightness_range_null_caps - Test Brightness range null caps
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_range_null_caps(struct kunit *test)
+{
+       unsigned int min = 99, max = 99;
+
+       KUNIT_EXPECT_EQ(test, get_brightness_range(NULL, &min, &max), 0);
+       /* min/max should remain untouched */
+       KUNIT_EXPECT_EQ(test, min, 99U);
+       KUNIT_EXPECT_EQ(test, max, 99U);
+}
+
+/**
+ * dm_test_brightness_range_pwm - Test Brightness range pwm
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_range_pwm(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+
+       KUNIT_EXPECT_EQ(test, get_brightness_range(&caps, &min, &max), 1);
+       /* 0x101 * 12 = 3084, 0x101 * 255 = 65535 */
+       KUNIT_EXPECT_EQ(test, min, 0x101U * 12);
+       KUNIT_EXPECT_EQ(test, max, 0x101U * 255);
+}
+
+/**
+ * dm_test_brightness_range_aux - Test Brightness range aux
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_range_aux(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+
+       caps.aux_support = true;
+       caps.aux_min_input_signal = 1;
+       caps.aux_max_input_signal = 512;
+
+       KUNIT_EXPECT_EQ(test, get_brightness_range(&caps, &min, &max), 1);
+       /* millinits: 1000 * value */
+       KUNIT_EXPECT_EQ(test, min, 1000U);
+       KUNIT_EXPECT_EQ(test, max, 512000U);
+}
+
+/* Tests for convert_brightness_to_user() */
+
+/**
+ * dm_test_brightness_to_user_null_caps - Test Brightness to user null caps
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_to_user_null_caps(struct kunit *test)
+{
+       /*
+        * With NULL caps, get_brightness_range fails → passthrough.
+        * We simulate this by passing a zeroed caps struct where
+        * max_input_signal=0 makes max=0 and the function hits
+        * get_brightness_range returning 0 since caps is NULL.
+        */
+       KUNIT_EXPECT_EQ(test, convert_brightness_to_user(NULL, 42), 42U);
+}
+
+/**
+ * dm_test_brightness_to_user_below_min - Test Brightness to user below min
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_to_user_below_min(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+
+       /* brightness < min (0x101*12 = 3084), should return 0 */
+       KUNIT_EXPECT_EQ(test, convert_brightness_to_user(&caps, 100), 0U);
+}
+
+/**
+ * dm_test_brightness_to_user_at_max - Test Brightness to user at max
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_to_user_at_max(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /* At max → should return max */
+       KUNIT_EXPECT_EQ(test, convert_brightness_to_user(&caps, max), max);
+}
+
+/**
+ * dm_test_brightness_to_user_at_min - Test Brightness to user at min
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_to_user_at_min(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /* At min → should return 0 */
+       KUNIT_EXPECT_EQ(test, convert_brightness_to_user(&caps, min), 0U);
+}
+
+/**
+ * dm_test_brightness_to_user_midpoint_pwm - Test Brightness to user midpoint 
pwm
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_to_user_midpoint_pwm(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max, mid_hw, result;
+       u64 expected;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /* midpoint of hw range */
+       mid_hw = min + (max - min) / 2;
+       /* expected = DIV_ROUND_CLOSEST_ULL((u64)max * (mid_hw - min), max - 
min) */
+       expected = DIV_ROUND_CLOSEST_ULL((u64)max * (mid_hw - min), max - min);
+       result = convert_brightness_to_user(&caps, mid_hw);
+
+       KUNIT_EXPECT_EQ(test, result, (u32)expected);
+}
+
+/* Tests for convert_brightness_from_user() — no custom curve */
+
+/**
+ * dm_test_brightness_from_user_null_caps - Test Brightness from user null caps
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_from_user_null_caps(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(NULL, 100), 100U);
+}
+
+/**
+ * dm_test_brightness_from_user_zero - Test Brightness from user zero
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_from_user_zero(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+       /* no custom curve */
+       caps.data_points = 0;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /* brightness=0 → min + 0 = min */
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(&caps, 0), (u32)min);
+}
+
+/**
+ * dm_test_brightness_from_user_max - Test Brightness from user max
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_from_user_max(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+       caps.data_points = 0;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /*
+        * brightness=max → min + DIV_ROUND_CLOSEST((max-min)*max, max)
+        *               = min + (max - min) = max
+        */
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(&caps, max), 
(u32)max);
+}
+
+/**
+ * dm_test_brightness_from_user_aux - Test Brightness from user aux
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_from_user_aux(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+
+       caps.aux_support = true;
+       caps.aux_min_input_signal = 1;
+       caps.aux_max_input_signal = 512;
+       caps.data_points = 0;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /* brightness=0 → min */
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(&caps, 0), (u32)min);
+       /* brightness=max → max */
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(&caps, max), 
(u32)max);
+}
+
+/* Tests for convert_custom_brightness() */
+
+/**
+ * dm_test_custom_brightness_no_data_points - Test Custom brightness no data 
points
+ * @test: The KUnit test context
+ */
+static void dm_test_custom_brightness_no_data_points(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       uint32_t brightness = 128;
+       uint32_t saved = brightness;
+
+       caps.data_points = 0;
+
+       convert_custom_brightness(&caps, 3084, 65535, &brightness);
+
+       /* No data points → no-op */
+       KUNIT_EXPECT_EQ(test, brightness, saved);
+}
+
+/**
+ * dm_test_custom_brightness_debug_mask_disables - Test Custom brightness 
debug mask disables
+ * @test: The KUnit test context
+ */
+static void dm_test_custom_brightness_debug_mask_disables(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       uint32_t brightness = 128;
+       uint32_t saved = brightness;
+       uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+       caps.data_points = 3;
+       caps.luminance_data[0].input_signal = 50;
+       caps.luminance_data[0].luminance = 10;
+
+       /* Set the disable flag */
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() | 
DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+
+       convert_custom_brightness(&caps, 3084, 65535, &brightness);
+
+       /* Should be no-op due to debug mask */
+       KUNIT_EXPECT_EQ(test, brightness, saved);
+
+       amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
+/**
+ * dm_test_custom_brightness_exact_match - Test Custom brightness exact match
+ * @test: The KUnit test context
+ */
+static void dm_test_custom_brightness_exact_match(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       uint32_t brightness;
+       unsigned int min, max;
+       uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() & 
~DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+
+       caps.aux_support = false;
+       caps.min_input_signal = 0;
+       caps.max_input_signal = 255;
+       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 = 200;
+       caps.luminance_data[2].luminance = 90;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /*
+        * Set brightness so that scale_input_to_fw yields exactly 128.
+        * scale_input_to_fw(min, max, x) = DIV_ROUND_CLOSEST(x * 255, max - 
min)
+        * With min=0, max=0x101*255=65535:
+        * We need x such that DIV_ROUND_CLOSEST(x * 255, 65535) = 128
+        * → x = 128 * 65535 / 255 = 32896
+        */
+       brightness = 32896;
+
+       convert_custom_brightness(&caps, min, max, &brightness);
+
+       /*
+        * Exact match: lum=50, brightness_scaled=128
+        * result = scale_fw_to_input(min, max, DIV_ROUND_CLOSEST(50*128, 101))
+        *        = scale_fw_to_input(0, 65535, DIV_ROUND_CLOSEST(6400, 101))
+        *        = scale_fw_to_input(0, 65535, 63)
+        *        = 0 + DIV_ROUND_CLOSEST(63 * 65535, 255) = 16191 (approx)
+        */
+       KUNIT_EXPECT_TRUE(test, brightness != 32896);
+       KUNIT_EXPECT_TRUE(test, brightness < 32896);
+
+       amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
+/**
+ * dm_test_custom_brightness_below_first - Test Custom brightness below first
+ * @test: The KUnit test context
+ */
+static void dm_test_custom_brightness_below_first(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       uint32_t brightness;
+       unsigned int min, max;
+       uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() & 
~DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+
+       caps.aux_support = false;
+       caps.min_input_signal = 0;
+       caps.max_input_signal = 255;
+       caps.data_points = 2;
+       caps.luminance_data[0].input_signal = 100;
+       caps.luminance_data[0].luminance = 40;
+       caps.luminance_data[1].input_signal = 200;
+       caps.luminance_data[1].luminance = 80;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /*
+        * Set brightness low enough that scaled value < 100.
+        * scale_input_to_fw(0, 65535, x) = DIV_ROUND_CLOSEST(x*255, 65535)
+        * For result=50: x = 50*65535/255 = 12850
+        */
+       brightness = 12850;
+
+       convert_custom_brightness(&caps, min, max, &brightness);
+
+       /*
+        * Below first data point: lum = DIV_ROUND_CLOSEST(40 * 50, 100) = 20
+        * Then: scale_fw_to_input(0, 65535, DIV_ROUND_CLOSEST(20 * 50, 101))
+        *      = scale_fw_to_input(0, 65535, DIV_ROUND_CLOSEST(1000, 101))
+        *      = scale_fw_to_input(0, 65535, 10)
+        * The output should be significantly less than input.
+        */
+       KUNIT_EXPECT_TRUE(test, brightness < 12850);
+
+       amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
+/**
+ * dm_test_custom_brightness_interpolation - Test Custom brightness 
interpolation
+ * @test: The KUnit test context
+ */
+static void dm_test_custom_brightness_interpolation(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       uint32_t brightness;
+       unsigned int min, max;
+       uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() & 
~DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+
+       caps.aux_support = false;
+       caps.min_input_signal = 0;
+       caps.max_input_signal = 255;
+       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;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /*
+        * Choose a value between data points 50 and 200.
+        * scale_input_to_fw(0, 65535, x) = 125 when x = 125*65535/255 = 32125
+        */
+       brightness = 32125;
+
+       convert_custom_brightness(&caps, min, max, &brightness);
+
+       /*
+        * The function should interpolate between data points and produce
+        * a remapped value different from the input.
+        */
+       KUNIT_EXPECT_TRUE(test, brightness != 32125);
+
+       amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
+/**
+ * dm_test_custom_brightness_above_last - Test Custom brightness above last 
data point
+ * @test: The KUnit test context
+ */
+static void dm_test_custom_brightness_above_last(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       uint32_t brightness;
+       unsigned int min, max;
+       uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() & 
~DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+
+       caps.aux_support = false;
+       caps.min_input_signal = 0;
+       caps.max_input_signal = 255;
+       caps.data_points = 2;
+       caps.luminance_data[0].input_signal = 50;
+       caps.luminance_data[0].luminance = 20;
+       caps.luminance_data[1].input_signal = 150;
+       caps.luminance_data[1].luminance = 60;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /*
+        * Choose brightness above the last data point (150).
+        * scale_input_to_fw(0, 65535, x) = 220 when x = 220*65535/255 = 56533
+        * After binary search, left >= data_points, clamped → right==left,
+        * so lum = upper_lum = 60.
+        */
+       brightness = 56533;
+
+       convert_custom_brightness(&caps, min, max, &brightness);
+
+       /* Output should differ from input (remapped via curve) */
+       KUNIT_EXPECT_TRUE(test, brightness != 56533);
+       KUNIT_EXPECT_TRUE(test, brightness < 56533);
+
+       amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
+/**
+ * dm_test_custom_brightness_single_data_point - Test Custom brightness with 
single data point
+ * @test: The KUnit test context
+ */
+static void dm_test_custom_brightness_single_data_point(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       uint32_t brightness;
+       unsigned int min, max;
+       uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() & 
~DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+
+       caps.aux_support = false;
+       caps.min_input_signal = 0;
+       caps.max_input_signal = 255;
+       caps.data_points = 1;
+       caps.luminance_data[0].input_signal = 128;
+       caps.luminance_data[0].luminance = 50;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /*
+        * Brightness below the single data point triggers the
+        * "below first" path: lum = DIV_ROUND_CLOSEST(50 * scaled, 128).
+        * scale_input_to_fw(0, 65535, x) = 64 when x = 64*65535/255 = 16448
+        */
+       brightness = 16448;
+
+       convert_custom_brightness(&caps, min, max, &brightness);
+
+       KUNIT_EXPECT_TRUE(test, brightness < 16448);
+
+       amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
+/**
+ * dm_test_custom_brightness_lower_lum_zero - Test Custom brightness with zero 
lower luminance
+ * @test: The KUnit test context
+ */
+static void dm_test_custom_brightness_lower_lum_zero(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       uint32_t brightness;
+       unsigned int min, max;
+       uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() & 
~DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+
+       caps.aux_support = false;
+       caps.min_input_signal = 0;
+       caps.max_input_signal = 255;
+       caps.data_points = 2;
+       caps.luminance_data[0].input_signal = 50;
+       caps.luminance_data[0].luminance = 0;   /* zero lower luminance */
+       caps.luminance_data[1].input_signal = 200;
+       caps.luminance_data[1].luminance = 80;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /*
+        * Choose brightness between data points to trigger interpolation.
+        * scale_input_to_fw(0, 65535, x) = 125 when x = 125*65535/255 = 32125
+        * With lower_lum == 0, code takes shortcut: lum = upper_lum = 80.
+        */
+       brightness = 32125;
+
+       convert_custom_brightness(&caps, min, max, &brightness);
+
+       /* Should remap; result should differ from input */
+       KUNIT_EXPECT_TRUE(test, brightness != 32125);
+
+       amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
+/**
+ * dm_test_brightness_to_user_above_max - Test Brightness to user above max
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_to_user_above_max(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max, result;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /* brightness above max → result > max (linear extrapolation) */
+       result = convert_brightness_to_user(&caps, max + 1000);
+
+       KUNIT_EXPECT_GT(test, result, max);
+}
+
+/**
+ * dm_test_brightness_from_user_midrange - Test Brightness from user mid-range 
value
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_from_user_midrange(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+       u32 result;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 12;
+       caps.max_input_signal = 255;
+       caps.data_points = 0;
+
+       get_brightness_range(&caps, &min, &max);
+
+       /* Mid-range brightness should map to between min and max */
+       result = convert_brightness_from_user(&caps, max / 2);
+
+       KUNIT_EXPECT_GE(test, result, min);
+       KUNIT_EXPECT_LE(test, result, max);
+}
+
+/**
+ * dm_test_brightness_from_user_with_curve - Test Brightness from user with 
custom curve active
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_from_user_with_curve(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min, max;
+       u32 with_curve, without_curve;
+       uint saved_mask = amdgpu_dm_get_dc_debug_mask();
+
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() & 
~DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+
+       caps.aux_support = false;
+       caps.min_input_signal = 0;
+       caps.max_input_signal = 255;
+       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;
+
+       get_brightness_range(&caps, &min, &max);
+
+       with_curve = convert_brightness_from_user(&caps, max / 2);
+
+       /* Now disable the curve and compare */
+       amdgpu_dm_set_dc_debug_mask(amdgpu_dm_get_dc_debug_mask() | 
DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE);
+       without_curve = convert_brightness_from_user(&caps, max / 2);
+
+       /* Custom curve should produce a different mapping */
+       KUNIT_EXPECT_NE(test, with_curve, without_curve);
+
+       amdgpu_dm_set_dc_debug_mask(saved_mask);
+}
+
+/**
+ * dm_test_brightness_range_zero_signals - Test Brightness range with zero min 
and max signals
+ * @test: The KUnit test context
+ */
+static void dm_test_brightness_range_zero_signals(struct kunit *test)
+{
+       struct amdgpu_dm_backlight_caps caps = {};
+       unsigned int min = 99, max = 99;
+
+       caps.aux_support = false;
+       caps.min_input_signal = 0;
+       caps.max_input_signal = 0;
+
+       /* Both signals zero → min=max=0 */
+       KUNIT_EXPECT_EQ(test, get_brightness_range(&caps, &min, &max), 1);
+       KUNIT_EXPECT_EQ(test, min, 0U);
+       KUNIT_EXPECT_EQ(test, max, 0U);
+}
+
+/* Tests for amdgpu_dm_update_connector_ext_caps() */
+
+/**
+ * dm_test_update_connector_ext_caps_negative_bl_idx - Test negative backlight 
index early return
+ * @test: The KUnit test context
+ */
+static void dm_test_update_connector_ext_caps_negative_bl_idx(struct kunit 
*test)
+{
+       struct amdgpu_dm_connector *aconnector;
+
+       aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, aconnector);
+
+       aconnector->bl_idx = -1;
+
+       amdgpu_dm_update_connector_ext_caps(aconnector);
+
+       KUNIT_SUCCEED(test);
+}
+
+/**
+ * dm_test_update_connector_ext_caps_non_edp - Test non-eDP connector early 
return
+ * @test: The KUnit test context
+ */
+static void dm_test_update_connector_ext_caps_non_edp(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_HDMI_TYPE_A);
+       fixture.adev->dm.backlight_caps[0].aux_support = true;
+
+       amdgpu_dm_update_connector_ext_caps(fixture.aconnector);
+
+       KUNIT_EXPECT_TRUE(test, fixture.adev->dm.backlight_caps[0].aux_support);
+       KUNIT_EXPECT_PTR_EQ(test, fixture.adev->dm.backlight_caps[0].ext_caps, 
NULL);
+}
+
+/**
+ * dm_test_update_connector_ext_caps_oled_defaults - Test OLED eDP defaults to 
AUX backlight
+ * @test: The KUnit test context
+ */
+static void dm_test_update_connector_ext_caps_oled_defaults(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_backlight = amdgpu_dm_get_backlight_param();
+
+       amdgpu_dm_set_backlight_param(-1);
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_EDP);
+       fixture.link->dpcd_sink_ext_caps.bits.oled = 1;
+
+       amdgpu_dm_update_connector_ext_caps(fixture.aconnector);
+
+       KUNIT_EXPECT_PTR_EQ(test, fixture.adev->dm.backlight_caps[0].ext_caps,
+                           &fixture.link->dpcd_sink_ext_caps);
+       KUNIT_EXPECT_TRUE(test, fixture.adev->dm.backlight_caps[0].aux_support);
+       KUNIT_EXPECT_EQ(test, fixture.link->backlight_control_type,
+                       BACKLIGHT_CONTROL_AMD_AUX);
+       KUNIT_EXPECT_EQ(test, 
fixture.adev->dm.backlight_caps[0].aux_max_input_signal, 512);
+       KUNIT_EXPECT_EQ(test, 
fixture.adev->dm.backlight_caps[0].aux_min_input_signal, 1);
+
+       amdgpu_dm_set_backlight_param(saved_backlight);
+}
+
+/**
+ * dm_test_update_connector_ext_caps_luminance_values - Test luminance range 
copy
+ * @test: The KUnit test context
+ */
+static void dm_test_update_connector_ext_caps_luminance_values(struct kunit 
*test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_backlight = amdgpu_dm_get_backlight_param();
+
+       amdgpu_dm_set_backlight_param(-1);
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_EDP);
+       fixture.aconnector->base.display_info.luminance_range.min_luminance = 2;
+       fixture.aconnector->base.display_info.luminance_range.max_luminance = 
400;
+
+       amdgpu_dm_update_connector_ext_caps(fixture.aconnector);
+
+       KUNIT_EXPECT_FALSE(test, 
fixture.adev->dm.backlight_caps[0].aux_support);
+       KUNIT_EXPECT_EQ(test, 
fixture.adev->dm.backlight_caps[0].aux_max_input_signal, 400);
+       KUNIT_EXPECT_EQ(test, 
fixture.adev->dm.backlight_caps[0].aux_min_input_signal, 2);
+
+       amdgpu_dm_set_backlight_param(saved_backlight);
+}
+
+/**
+ * dm_test_update_connector_ext_caps_force_aux - Test module parameter forces 
AUX backlight
+ * @test: The KUnit test context
+ */
+static void dm_test_update_connector_ext_caps_force_aux(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_backlight = amdgpu_dm_get_backlight_param();
+
+       amdgpu_dm_set_backlight_param(1);
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_EDP);
+
+       amdgpu_dm_update_connector_ext_caps(fixture.aconnector);
+
+       KUNIT_EXPECT_TRUE(test, fixture.adev->dm.backlight_caps[0].aux_support);
+       KUNIT_EXPECT_EQ(test, fixture.link->backlight_control_type,
+                       BACKLIGHT_CONTROL_AMD_AUX);
+
+       amdgpu_dm_set_backlight_param(saved_backlight);
+}
+
+/**
+ * dm_test_update_connector_ext_caps_force_pwm - Test module parameter forces 
PWM backlight
+ * @test: The KUnit test context
+ */
+static void dm_test_update_connector_ext_caps_force_pwm(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_backlight = amdgpu_dm_get_backlight_param();
+
+       amdgpu_dm_set_backlight_param(0);
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_EDP);
+       fixture.link->dpcd_sink_ext_caps.bits.oled = 1;
+
+       amdgpu_dm_update_connector_ext_caps(fixture.aconnector);
+
+       KUNIT_EXPECT_FALSE(test, 
fixture.adev->dm.backlight_caps[0].aux_support);
+       KUNIT_EXPECT_NE(test, fixture.link->backlight_control_type,
+                       BACKLIGHT_CONTROL_AMD_AUX);
+
+       amdgpu_dm_set_backlight_param(saved_backlight);
+}
+
+/* Tests for amdgpu_dm_should_create_sysfs() */
+
+/**
+ * dm_test_should_create_sysfs_abm_forced - Test forced ABM disables sysfs
+ * @test: The KUnit test context
+ */
+static void dm_test_should_create_sysfs_abm_forced(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_abm_level = amdgpu_dm_get_abm_level_param();
+
+       amdgpu_dm_set_abm_level_param(1);
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_EDP);
+       fixture.aconnector->base.connector_type = DRM_MODE_CONNECTOR_eDP;
+
+       KUNIT_EXPECT_FALSE(test, 
amdgpu_dm_should_create_sysfs(fixture.aconnector));
+
+       amdgpu_dm_set_abm_level_param(saved_abm_level);
+}
+
+/**
+ * dm_test_should_create_sysfs_non_edp - Test non-eDP connector disables sysfs
+ * @test: The KUnit test context
+ */
+static void dm_test_should_create_sysfs_non_edp(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_abm_level = amdgpu_dm_get_abm_level_param();
+
+       amdgpu_dm_set_abm_level_param(-1);
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_HDMI_TYPE_A);
+       fixture.aconnector->base.connector_type = DRM_MODE_CONNECTOR_HDMIA;
+
+       KUNIT_EXPECT_FALSE(test, 
amdgpu_dm_should_create_sysfs(fixture.aconnector));
+
+       amdgpu_dm_set_abm_level_param(saved_abm_level);
+}
+
+/**
+ * dm_test_should_create_sysfs_no_backlight_index - Test eDP without backlight 
index enables sysfs
+ * @test: The KUnit test context
+ */
+static void dm_test_should_create_sysfs_no_backlight_index(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_abm_level = amdgpu_dm_get_abm_level_param();
+
+       amdgpu_dm_set_abm_level_param(-1);
+       setup_test_connector(test, &fixture, -1, SIGNAL_TYPE_EDP);
+       fixture.aconnector->base.connector_type = DRM_MODE_CONNECTOR_eDP;
+
+       KUNIT_EXPECT_TRUE(test, 
amdgpu_dm_should_create_sysfs(fixture.aconnector));
+
+       amdgpu_dm_set_abm_level_param(saved_abm_level);
+}
+
+/**
+ * dm_test_should_create_sysfs_aux_backlight - Test AUX backlight disables 
sysfs
+ * @test: The KUnit test context
+ */
+static void dm_test_should_create_sysfs_aux_backlight(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_abm_level = amdgpu_dm_get_abm_level_param();
+
+       amdgpu_dm_set_abm_level_param(-1);
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_EDP);
+       fixture.aconnector->base.connector_type = DRM_MODE_CONNECTOR_eDP;
+       fixture.adev->dm.backlight_caps[0].aux_support = true;
+
+       KUNIT_EXPECT_FALSE(test, 
amdgpu_dm_should_create_sysfs(fixture.aconnector));
+
+       amdgpu_dm_set_abm_level_param(saved_abm_level);
+}
+
+/**
+ * dm_test_should_create_sysfs_pwm_backlight - Test PWM backlight enables sysfs
+ * @test: The KUnit test context
+ */
+static void dm_test_should_create_sysfs_pwm_backlight(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       int saved_abm_level = amdgpu_dm_get_abm_level_param();
+
+       amdgpu_dm_set_abm_level_param(-1);
+       setup_test_connector(test, &fixture, 0, SIGNAL_TYPE_EDP);
+       fixture.aconnector->base.connector_type = DRM_MODE_CONNECTOR_eDP;
+       fixture.adev->dm.backlight_caps[0].aux_support = false;
+
+       KUNIT_EXPECT_TRUE(test, 
amdgpu_dm_should_create_sysfs(fixture.aconnector));
+
+       amdgpu_dm_set_abm_level_param(saved_abm_level);
+}
+
+/* Tests for amdgpu_dm_setup_backlight_device() */
+
+/**
+ * dm_test_setup_backlight_device_non_edp - Test non-eDP/LVDS link is skipped
+ * @test: The KUnit test context
+ */
+static void dm_test_setup_backlight_device_non_edp(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       struct amdgpu_display_manager *dm;
+
+       setup_test_connector(test, &fixture, -1, SIGNAL_TYPE_HDMI_TYPE_A);
+       fixture.link->type = dc_connection_single;
+       dm = &fixture.adev->dm;
+       dm->adev = fixture.adev;
+       dm->num_of_edps = 0;
+
+       amdgpu_dm_setup_backlight_device(dm, fixture.aconnector);
+
+       /* Non-eDP/LVDS signal → no backlight setup */
+       KUNIT_EXPECT_EQ(test, dm->num_of_edps, 0);
+       KUNIT_EXPECT_EQ(test, fixture.aconnector->bl_idx, -1);
+}
+
+/**
+ * dm_test_setup_backlight_device_connection_none - Test disconnected link is 
skipped
+ * @test: The KUnit test context
+ */
+static void dm_test_setup_backlight_device_connection_none(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       struct amdgpu_display_manager *dm;
+
+       setup_test_connector(test, &fixture, -1, SIGNAL_TYPE_EDP);
+       fixture.link->type = dc_connection_none;
+       dm = &fixture.adev->dm;
+       dm->adev = fixture.adev;
+       dm->num_of_edps = 0;
+
+       amdgpu_dm_setup_backlight_device(dm, fixture.aconnector);
+
+       /* Disconnected link → no backlight setup */
+       KUNIT_EXPECT_EQ(test, dm->num_of_edps, 0);
+       KUNIT_EXPECT_EQ(test, fixture.aconnector->bl_idx, -1);
+}
+
+/**
+ * dm_test_setup_backlight_device_max_edps - Test setup is skipped when at eDP 
limit
+ * @test: The KUnit test context
+ */
+static void dm_test_setup_backlight_device_max_edps(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       struct amdgpu_display_manager *dm;
+
+       setup_test_connector(test, &fixture, -1, SIGNAL_TYPE_EDP);
+       fixture.link->type = dc_connection_single;
+       dm = &fixture.adev->dm;
+       dm->adev = fixture.adev;
+       dm->num_of_edps = AMDGPU_DM_MAX_NUM_EDP;
+
+       amdgpu_dm_setup_backlight_device(dm, fixture.aconnector);
+
+       /* Already at the eDP limit → no additional setup */
+       KUNIT_EXPECT_EQ(test, dm->num_of_edps, AMDGPU_DM_MAX_NUM_EDP);
+       KUNIT_EXPECT_EQ(test, fixture.aconnector->bl_idx, -1);
+}
+
+/**
+ * dm_test_setup_backlight_device_oled_success - Test successful eDP backlight 
setup
+ * @test: The KUnit test context
+ */
+static void dm_test_setup_backlight_device_oled_success(struct kunit *test)
+{
+       struct dm_backlight_connector_fixture fixture = {};
+       struct amdgpu_display_manager *dm;
+       int saved_backlight = amdgpu_dm_get_backlight_param();
+
+       amdgpu_dm_set_backlight_param(-1);
+       setup_test_connector(test, &fixture, -1, SIGNAL_TYPE_EDP);
+       fixture.link->type = dc_connection_single;
+       /* OLED panel avoids the ABM property attach path */
+       fixture.link->dpcd_sink_ext_caps.bits.oled = 1;
+       dm = &fixture.adev->dm;
+       dm->adev = fixture.adev;
+       dm->num_of_edps = 0;
+
+       amdgpu_dm_setup_backlight_device(dm, fixture.aconnector);
+
+       KUNIT_EXPECT_EQ(test, dm->num_of_edps, 1);
+       KUNIT_EXPECT_EQ(test, fixture.aconnector->bl_idx, 0);
+       KUNIT_EXPECT_PTR_EQ(test, (void *)dm->backlight_link[0],
+                           (void *)fixture.link);
+       KUNIT_EXPECT_TRUE(test, dm->backlight_caps[0].aux_support);
+
+       amdgpu_dm_set_backlight_param(saved_backlight);
+}
+
+static struct kunit_case dm_backlight_test_cases[] = {
+       KUNIT_CASE(dm_test_backlight_caps_valid_short_circuit),
+#if !defined(CONFIG_ACPI)
+       KUNIT_CASE(dm_test_backlight_caps_aux_support_noop),
+       KUNIT_CASE(dm_test_backlight_caps_non_aux_sets_defaults),
+#endif
+       /* get_brightness_range */
+       KUNIT_CASE(dm_test_brightness_range_null_caps),
+       KUNIT_CASE(dm_test_brightness_range_pwm),
+       KUNIT_CASE(dm_test_brightness_range_aux),
+       /* convert_brightness_to_user */
+       KUNIT_CASE(dm_test_brightness_to_user_null_caps),
+       KUNIT_CASE(dm_test_brightness_to_user_below_min),
+       KUNIT_CASE(dm_test_brightness_to_user_at_max),
+       KUNIT_CASE(dm_test_brightness_to_user_at_min),
+       KUNIT_CASE(dm_test_brightness_to_user_midpoint_pwm),
+       /* convert_brightness_from_user */
+       KUNIT_CASE(dm_test_brightness_from_user_null_caps),
+       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_custom_brightness */
+       KUNIT_CASE(dm_test_custom_brightness_no_data_points),
+       KUNIT_CASE(dm_test_custom_brightness_debug_mask_disables),
+       KUNIT_CASE(dm_test_custom_brightness_exact_match),
+       KUNIT_CASE(dm_test_custom_brightness_below_first),
+       KUNIT_CASE(dm_test_custom_brightness_interpolation),
+       KUNIT_CASE(dm_test_custom_brightness_above_last),
+       KUNIT_CASE(dm_test_custom_brightness_single_data_point),
+       KUNIT_CASE(dm_test_custom_brightness_lower_lum_zero),
+       KUNIT_CASE(dm_test_brightness_to_user_above_max),
+       KUNIT_CASE(dm_test_brightness_from_user_midrange),
+       KUNIT_CASE(dm_test_brightness_from_user_with_curve),
+       KUNIT_CASE(dm_test_brightness_range_zero_signals),
+       /* amdgpu_dm_update_connector_ext_caps */
+       KUNIT_CASE(dm_test_update_connector_ext_caps_negative_bl_idx),
+       KUNIT_CASE(dm_test_update_connector_ext_caps_non_edp),
+       KUNIT_CASE(dm_test_update_connector_ext_caps_oled_defaults),
+       KUNIT_CASE(dm_test_update_connector_ext_caps_luminance_values),
+       KUNIT_CASE(dm_test_update_connector_ext_caps_force_aux),
+       KUNIT_CASE(dm_test_update_connector_ext_caps_force_pwm),
+       /* amdgpu_dm_should_create_sysfs */
+       KUNIT_CASE(dm_test_should_create_sysfs_abm_forced),
+       KUNIT_CASE(dm_test_should_create_sysfs_non_edp),
+       KUNIT_CASE(dm_test_should_create_sysfs_no_backlight_index),
+       KUNIT_CASE(dm_test_should_create_sysfs_aux_backlight),
+       KUNIT_CASE(dm_test_should_create_sysfs_pwm_backlight),
+       /* amdgpu_dm_setup_backlight_device */
+       KUNIT_CASE(dm_test_setup_backlight_device_non_edp),
+       KUNIT_CASE(dm_test_setup_backlight_device_connection_none),
+       KUNIT_CASE(dm_test_setup_backlight_device_max_edps),
+       KUNIT_CASE(dm_test_setup_backlight_device_oled_success),
+       {}
+};
+
+static struct kunit_suite dm_backlight_test_suite = {
+       .name = "amdgpu_dm_backlight",
+       .test_cases = dm_backlight_test_cases,
+};
+
+kunit_test_suite(dm_backlight_test_suite);
+
+MODULE_LICENSE("Dual MIT/GPL");
+MODULE_DESCRIPTION("KUnit tests for amdgpu_dm_backlight");
+MODULE_AUTHOR("AMD");
-- 
2.43.0

Reply via email to