summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Hung <alex.hung@amd.com>2026-06-12 17:20:27 -0600
committerAlex Deucher <alexander.deucher@amd.com>2026-07-01 11:31:16 -0400
commit703e3ae7565d0b7eeaa91d679b4ef3e38f257735 (patch)
tree1d7e42e14869178968b7778131102469f7ca29e4
parent7a39b1c3b2e6b27f4230a20ccf9ac5a2737fa8b0 (diff)
downloadlinux-703e3ae7565d0b7eeaa91d679b4ef3e38f257735.tar.gz
linux-703e3ae7565d0b7eeaa91d679b4ef3e38f257735.zip
drm/amd/display: Extract backlight helpers for KUnit tests
[WHAT] Extract shared backlight device index lookup and property setup into testable helpers. The duplicated bd-to-index scan in update_status/get_brightness is replaced by amdgpu_dm_backlight_get_device_index(), and the inline backlight_properties calculation is replaced by amdgpu_dm_backlight_fill_props(). Add KUnit coverage for both new helpers. Keep the runtime power_supply_is_system_supplied() call at the caller so the helpers remain pure and deterministic under test. Assisted-by: Copilot:GPT-5.5 Reviewed-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: George Zhang <george.zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c84
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.h8
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c123
3 files changed, 184 insertions, 31 deletions
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 f19092a3237e..33f4be403a65 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
@@ -236,6 +236,21 @@ static struct dc_stream_state *dm_find_stream_with_link(
return NULL;
}
+STATIC_IFN_KUNIT
+int amdgpu_dm_backlight_get_device_index(struct amdgpu_display_manager *dm,
+ struct backlight_device *bd)
+{
+ int i;
+
+ for (i = 0; i < dm->num_of_edps; i++) {
+ if (bd == dm->backlight_dev[i])
+ return i;
+ }
+
+ return 0;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_backlight_get_device_index);
+
void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
int bl_idx,
u32 user_brightness)
@@ -335,14 +350,8 @@ void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
{
struct amdgpu_display_manager *dm = bl_get_data(bd);
- int i;
+ int i = amdgpu_dm_backlight_get_device_index(dm, bd);
- for (i = 0; i < dm->num_of_edps; i++) {
- if (bd == dm->backlight_dev[i])
- break;
- }
- if (i >= AMDGPU_DM_MAX_NUM_EDP)
- i = 0;
amdgpu_dm_backlight_set_level(dm, i, bd->props.brightness);
return 0;
@@ -377,14 +386,8 @@ static u32 amdgpu_dm_backlight_get_level(struct amdgpu_display_manager *dm,
static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)
{
struct amdgpu_display_manager *dm = bl_get_data(bd);
- int i;
+ int i = amdgpu_dm_backlight_get_device_index(dm, bd);
- for (i = 0; i < dm->num_of_edps; i++) {
- if (bd == dm->backlight_dev[i])
- break;
- }
- if (i >= AMDGPU_DM_MAX_NUM_EDP)
- i = 0;
return amdgpu_dm_backlight_get_level(dm, i);
}
@@ -394,6 +397,35 @@ static const struct backlight_ops amdgpu_dm_backlight_ops = {
.update_status = amdgpu_dm_backlight_update_status,
};
+STATIC_IFN_KUNIT
+void amdgpu_dm_backlight_fill_props(const struct amdgpu_dm_backlight_caps *caps,
+ bool is_system_supplied,
+ bool custom_curve_enabled,
+ struct backlight_properties *props)
+{
+ unsigned int min, max;
+
+ if (get_brightness_range(caps, &min, &max)) {
+ if (is_system_supplied)
+ props->brightness = DIV_ROUND_CLOSEST((max - min) * caps->ac_level,
+ 100);
+ else
+ props->brightness = DIV_ROUND_CLOSEST((max - min) * caps->dc_level,
+ 100);
+ props->max_brightness = max - min;
+ } else {
+ props->brightness = MAX_BACKLIGHT_LEVEL;
+ props->max_brightness = MAX_BACKLIGHT_LEVEL;
+ }
+
+ if (caps && caps->data_points && custom_curve_enabled)
+ props->scale = BACKLIGHT_SCALE_NON_LINEAR;
+ else
+ props->scale = BACKLIGHT_SCALE_LINEAR;
+ props->type = BACKLIGHT_RAW;
+}
+EXPORT_IF_KUNIT(amdgpu_dm_backlight_fill_props);
+
void
amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
{
@@ -402,7 +434,6 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
struct backlight_properties props = { 0 };
struct amdgpu_dm_backlight_caps *caps;
char bl_name[16];
- int min, max;
int real_brightness;
int init_brightness;
@@ -417,26 +448,17 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
}
caps = &dm->backlight_caps[aconnector->bl_idx];
- if (get_brightness_range(caps, &min, &max)) {
- if (power_supply_is_system_supplied() > 0)
- props.brightness = DIV_ROUND_CLOSEST((max - min) * caps->ac_level, 100);
- else
- props.brightness = DIV_ROUND_CLOSEST((max - min) * caps->dc_level, 100);
- /* min is zero, so max needs to be adjusted */
- props.max_brightness = max - min;
- drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max,
- caps->ac_level, caps->dc_level);
- } else
- props.brightness = props.max_brightness = MAX_BACKLIGHT_LEVEL;
+ amdgpu_dm_backlight_fill_props(caps, power_supply_is_system_supplied() > 0,
+ !(amdgpu_dc_debug_mask &
+ DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE),
+ &props);
+ drm_dbg(drm, "Backlight caps: max_brightness: %d, ac %d, dc %d\n",
+ props.max_brightness, caps->ac_level, caps->dc_level);
init_brightness = props.brightness;
- if (caps->data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)) {
+ if (props.scale == BACKLIGHT_SCALE_NON_LINEAR)
drm_info(drm, "Using custom brightness curve\n");
- props.scale = BACKLIGHT_SCALE_NON_LINEAR;
- } else
- props.scale = BACKLIGHT_SCALE_LINEAR;
- props.type = BACKLIGHT_RAW;
snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d",
drm->primary->index + aconnector->bl_idx);
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 a6c01b7ccab3..98d612c60ae9 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
@@ -26,6 +26,8 @@
struct amdgpu_display_manager;
struct amdgpu_dm_connector;
+struct backlight_device;
+struct backlight_properties;
struct drm_connector;
struct attribute_group;
@@ -56,6 +58,12 @@ 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);
+int amdgpu_dm_backlight_get_device_index(struct amdgpu_display_manager *dm,
+ struct backlight_device *bd);
+void amdgpu_dm_backlight_fill_props(const struct amdgpu_dm_backlight_caps *caps,
+ bool is_system_supplied,
+ bool custom_curve_enabled,
+ struct backlight_properties *props);
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);
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 8763cd635ae1..0e9de940e5a8 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
@@ -6,6 +6,7 @@
*/
#include <kunit/test.h>
+#include <linux/backlight.h>
#include "dc.h"
#include "amdgpu.h"
@@ -13,6 +14,7 @@
#include "amdgpu_dm.h"
#include "amdgpu_dm_backlight.h"
#include "amd_shared.h"
+#include "dc/inc/hw/panel_cntl.h"
struct dm_backlight_connector_fixture {
struct amdgpu_device *adev;
@@ -47,6 +49,51 @@ static void setup_test_connector(struct kunit *test,
fixture->link->connector_signal = signal;
}
+/* Tests for amdgpu_dm_backlight_get_device_index() */
+
+/**
+ * dm_test_backlight_device_index_matches_second - Test matching second backlight device
+ * @test: The KUnit test context
+ */
+static void dm_test_backlight_device_index_matches_second(struct kunit *test)
+{
+ struct amdgpu_display_manager *dm = alloc_test_dm(test);
+ struct backlight_device *bd0;
+ struct backlight_device *bd1;
+
+ bd0 = kunit_kzalloc(test, sizeof(*bd0), GFP_KERNEL);
+ bd1 = kunit_kzalloc(test, sizeof(*bd1), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, bd0);
+ KUNIT_ASSERT_NOT_NULL(test, bd1);
+
+ dm->num_of_edps = 2;
+ dm->backlight_dev[0] = bd0;
+ dm->backlight_dev[1] = bd1;
+
+ KUNIT_EXPECT_EQ(test, amdgpu_dm_backlight_get_device_index(dm, bd1), 1);
+}
+
+/**
+ * dm_test_backlight_device_index_missing_fallback - Test missing backlight device fallback
+ * @test: The KUnit test context
+ */
+static void dm_test_backlight_device_index_missing_fallback(struct kunit *test)
+{
+ struct amdgpu_display_manager *dm = alloc_test_dm(test);
+ struct backlight_device *known_bd;
+ struct backlight_device *unknown_bd;
+
+ known_bd = kunit_kzalloc(test, sizeof(*known_bd), GFP_KERNEL);
+ unknown_bd = kunit_kzalloc(test, sizeof(*unknown_bd), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, known_bd);
+ KUNIT_ASSERT_NOT_NULL(test, unknown_bd);
+
+ dm->num_of_edps = 1;
+ dm->backlight_dev[0] = known_bd;
+
+ KUNIT_EXPECT_EQ(test, amdgpu_dm_backlight_get_device_index(dm, unknown_bd), 0);
+}
+
/* Tests for amdgpu_dm_update_backlight_caps() */
/**
@@ -740,6 +787,75 @@ static void dm_test_brightness_range_zero_signals(struct kunit *test)
KUNIT_EXPECT_EQ(test, max, 0U);
}
+/* Tests for amdgpu_dm_backlight_fill_props() */
+
+/**
+ * dm_test_backlight_fill_props_ac_linear - Test AC brightness and linear scale
+ * @test: The KUnit test context
+ */
+static void dm_test_backlight_fill_props_ac_linear(struct kunit *test)
+{
+ struct backlight_properties props = {};
+ struct amdgpu_dm_backlight_caps caps = {};
+ unsigned int min, max;
+
+ caps.min_input_signal = 12;
+ caps.max_input_signal = 255;
+ caps.ac_level = 40;
+ caps.dc_level = 20;
+
+ get_brightness_range(&caps, &min, &max);
+ amdgpu_dm_backlight_fill_props(&caps, true, false, &props);
+
+ KUNIT_EXPECT_EQ(test, props.brightness,
+ DIV_ROUND_CLOSEST((max - min) * caps.ac_level, 100));
+ KUNIT_EXPECT_EQ(test, props.max_brightness, max - min);
+ KUNIT_EXPECT_EQ(test, props.scale, BACKLIGHT_SCALE_LINEAR);
+ KUNIT_EXPECT_EQ(test, props.type, BACKLIGHT_RAW);
+}
+
+/**
+ * dm_test_backlight_fill_props_dc_nonlinear - Test DC brightness and non-linear scale
+ * @test: The KUnit test context
+ */
+static void dm_test_backlight_fill_props_dc_nonlinear(struct kunit *test)
+{
+ struct backlight_properties props = {};
+ struct amdgpu_dm_backlight_caps caps = {};
+ unsigned int min, max;
+
+ caps.min_input_signal = 12;
+ caps.max_input_signal = 255;
+ caps.ac_level = 40;
+ caps.dc_level = 20;
+ caps.data_points = 2;
+
+ get_brightness_range(&caps, &min, &max);
+ amdgpu_dm_backlight_fill_props(&caps, false, true, &props);
+
+ KUNIT_EXPECT_EQ(test, props.brightness,
+ DIV_ROUND_CLOSEST((max - min) * caps.dc_level, 100));
+ KUNIT_EXPECT_EQ(test, props.max_brightness, max - min);
+ KUNIT_EXPECT_EQ(test, props.scale, BACKLIGHT_SCALE_NON_LINEAR);
+ KUNIT_EXPECT_EQ(test, props.type, BACKLIGHT_RAW);
+}
+
+/**
+ * dm_test_backlight_fill_props_default_range - Test default properties without caps
+ * @test: The KUnit test context
+ */
+static void dm_test_backlight_fill_props_default_range(struct kunit *test)
+{
+ struct backlight_properties props = {};
+
+ amdgpu_dm_backlight_fill_props(NULL, false, true, &props);
+
+ KUNIT_EXPECT_EQ(test, props.brightness, MAX_BACKLIGHT_LEVEL);
+ KUNIT_EXPECT_EQ(test, props.max_brightness, MAX_BACKLIGHT_LEVEL);
+ KUNIT_EXPECT_EQ(test, props.scale, BACKLIGHT_SCALE_LINEAR);
+ KUNIT_EXPECT_EQ(test, props.type, BACKLIGHT_RAW);
+}
+
/* Tests for amdgpu_dm_update_connector_ext_caps() */
/**
@@ -1062,6 +1178,9 @@ static void dm_test_setup_backlight_device_oled_success(struct kunit *test)
}
static struct kunit_case dm_backlight_test_cases[] = {
+ /* amdgpu_dm_backlight_get_device_index */
+ KUNIT_CASE(dm_test_backlight_device_index_matches_second),
+ KUNIT_CASE(dm_test_backlight_device_index_missing_fallback),
KUNIT_CASE(dm_test_backlight_caps_valid_short_circuit),
#if !defined(CONFIG_ACPI)
KUNIT_CASE(dm_test_backlight_caps_aux_support_noop),
@@ -1095,6 +1214,10 @@ static struct kunit_case dm_backlight_test_cases[] = {
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_backlight_fill_props */
+ KUNIT_CASE(dm_test_backlight_fill_props_ac_linear),
+ KUNIT_CASE(dm_test_backlight_fill_props_dc_nonlinear),
+ KUNIT_CASE(dm_test_backlight_fill_props_default_range),
/* 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),