From: Alex Hung <[email protected]> [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 <[email protected]> Signed-off-by: Alex Hung <[email protected]> Signed-off-by: George Zhang <[email protected]> --- .../display/amdgpu_dm/amdgpu_dm_backlight.c | 84 +++++++----- .../display/amdgpu_dm/amdgpu_dm_backlight.h | 8 ++ .../tests/amdgpu_dm_backlight_test.c | 123 ++++++++++++++++++ 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), -- 2.53.0
