Test the curve check in amdgpu_dm_validate_backlight_caps():

- the GV301QH curve stays as it is
- a luminance over 100% becomes 100%
- a falling luminance rises to the point before
- a curve whose signals fall gets dropped
- a repeated signal stays
- a curve with more points than luminance_data holds is cut to fit

Also check the brightness the PWM and AUX paths give on the checked
curves

Signed-off-by: Hugo Sales <[email protected]>
---
KUnit: dm_test_validate_custom_curve_unsorted and the luminance checks
in the falling test fail without patch 1
---
 .../amdgpu_dm/tests/amdgpu_dm_backlight_test.c     | 184 +++++++++++++++++++++
 1 file changed, 184 insertions(+)

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 b3e6a96320164..d76527e49acf2 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
@@ -1696,6 +1696,185 @@ static void 
dm_test_brightness_curve_pwm_luminance_over_100(struct kunit *test)
        KUNIT_EXPECT_EQ(test, convert_brightness_from_user(&caps, 225000), 
255000U);
 }
 
+/* Tests for the custom curve check in amdgpu_dm_validate_backlight_caps() */
+
+static struct amdgpu_display_manager *alloc_validate_dm(struct kunit *test)
+{
+       struct amdgpu_display_manager *dm = dm_kunit_alloc_dm(test);
+
+       dm->adev = dm_kunit_alloc_adev(test);
+       /* drm_warn() prints the curve warnings against this device */
+       KUNIT_ASSERT_NOT_NULL(test, adev_to_drm(dm->adev)->dev);
+
+       return dm;
+}
+
+static struct amdgpu_dm_backlight_caps *
+validate_custom_curve(struct amdgpu_display_manager *dm,
+                     const struct amdgpu_dm_luminance_data *points, int n)
+{
+       struct amdgpu_dm_backlight_caps *caps = &dm->backlight_caps[0];
+
+       set_custom_curve_caps(caps, points, n);
+       caps->caps_valid = true;
+       amdgpu_dm_validate_backlight_caps(dm, 0);
+
+       return caps;
+}
+
+/**
+ * dm_test_validate_custom_curve_gv301qh - Test a good ATIF curve is left alone
+ * @test: The KUnit test context
+ *
+ * The GV301QH curve rises and stays within 100%, so the check must keep
+ * every point as it is
+ */
+static void dm_test_validate_custom_curve_gv301qh(struct kunit *test)
+{
+       struct amdgpu_display_manager *dm = alloc_validate_dm(test);
+       struct amdgpu_dm_backlight_caps *caps = &dm->backlight_caps[0];
+
+       set_gv301qh_caps(caps, false);
+       caps->caps_valid = true;
+       amdgpu_dm_validate_backlight_caps(dm, 0);
+
+       KUNIT_EXPECT_TRUE(test, caps->caps_valid);
+       KUNIT_ASSERT_EQ(test, caps->data_points, ARRAY_SIZE(gv301qh_curve));
+       KUNIT_EXPECT_MEMEQ(test, caps->luminance_data, gv301qh_curve, 
sizeof(gv301qh_curve));
+}
+
+/**
+ * dm_test_validate_custom_curve_luminance_over_100 - Test ATIF luminance over 
100% becomes 100%
+ * @test: The KUnit test context
+ *
+ * Points (100, 50), (200, 150) and (250, 120) become (100, 50), (200, 100)
+ * and (250, 100). Level 150 is then 50 + 50 * 50 / 100 = 75% and level 200
+ * is full brightness. Over AUX, 301176 of 512000 is just below signal 150,
+ * so it lands one below 75% of 1000..512000, at 384249
+ */
+static void dm_test_validate_custom_curve_luminance_over_100(struct kunit 
*test)
+{
+       static const struct amdgpu_dm_luminance_data points[] = {
+               { .input_signal = 100, .luminance = 50 },
+               { .input_signal = 200, .luminance = 150 },
+               { .input_signal = 250, .luminance = 120 },
+       };
+       struct amdgpu_display_manager *dm = alloc_validate_dm(test);
+       struct amdgpu_dm_backlight_caps *caps;
+
+       dm_test_enable_custom_curve(test);
+       caps = validate_custom_curve(dm, points, ARRAY_SIZE(points));
+
+       KUNIT_ASSERT_EQ(test, caps->data_points, 3);
+       KUNIT_EXPECT_EQ(test, caps->luminance_data[0].luminance, 50);
+       KUNIT_EXPECT_EQ(test, caps->luminance_data[1].luminance, 100);
+       KUNIT_EXPECT_EQ(test, caps->luminance_data[2].luminance, 100);
+
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(caps, 150 * 0x101), 
49151U);
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(caps, 200 * 0x101), 
65535U);
+       KUNIT_EXPECT_EQ(test, convert_brightness_to_millipercent(caps, 150 * 
0x101), 75000U);
+       KUNIT_EXPECT_EQ(test, convert_brightness_to_millipercent(caps, 200 * 
0x101), 100000U);
+
+       caps->aux_support = true;
+       caps->aux_min_input_signal = 1;
+       caps->aux_max_input_signal = 512;
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(caps, 301176), 
384249U);
+}
+
+/**
+ * dm_test_validate_custom_curve_falling - Test a falling ATIF point is raised
+ * @test: The KUnit test context
+ *
+ * In (50, 30), (100, 60), (150, 40) and (200, 80), the point at 150 is
+ * raised to 60%, so the curve is flat from 100 to 150. Level 125 is 60% on
+ * both paths, which over AUX is 307600 in 1000..512000
+ */
+static void dm_test_validate_custom_curve_falling(struct kunit *test)
+{
+       static const struct amdgpu_dm_luminance_data points[] = {
+               { .input_signal = 50, .luminance = 30 },
+               { .input_signal = 100, .luminance = 60 },
+               { .input_signal = 150, .luminance = 40 },
+               { .input_signal = 200, .luminance = 80 },
+       };
+       struct amdgpu_display_manager *dm = alloc_validate_dm(test);
+       struct amdgpu_dm_backlight_caps *caps;
+
+       dm_test_enable_custom_curve(test);
+       caps = validate_custom_curve(dm, points, ARRAY_SIZE(points));
+
+       KUNIT_ASSERT_EQ(test, caps->data_points, 4);
+       KUNIT_EXPECT_EQ(test, caps->luminance_data[1].luminance, 60);
+       KUNIT_EXPECT_EQ(test, caps->luminance_data[2].luminance, 60);
+       KUNIT_EXPECT_EQ(test, caps->luminance_data[3].luminance, 80);
+
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(caps, 125 * 0x101), 
39321U);
+       KUNIT_EXPECT_EQ(test, convert_brightness_to_millipercent(caps, 125 * 
0x101), 60000U);
+
+       caps->aux_support = true;
+       caps->aux_min_input_signal = 1;
+       caps->aux_max_input_signal = 512;
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(caps, 250980), 
307600U);
+}
+
+/**
+ * dm_test_validate_custom_curve_unsorted - Test a curve whose signals fall is 
dropped
+ * @test: The KUnit test context
+ *
+ * A signal below the one before leaves no curve, so the mapping is
+ * linear. A repeated signal is a step: the curve stays, and level 100 is
+ * at the later point's 60%
+ */
+static void dm_test_validate_custom_curve_unsorted(struct kunit *test)
+{
+       static const struct amdgpu_dm_luminance_data falling[] = {
+               { .input_signal = 100, .luminance = 40 },
+               { .input_signal = 80, .luminance = 60 },
+       };
+       static const struct amdgpu_dm_luminance_data repeated[] = {
+               { .input_signal = 50, .luminance = 20 },
+               { .input_signal = 100, .luminance = 40 },
+               { .input_signal = 100, .luminance = 60 },
+       };
+       struct amdgpu_display_manager *dm = alloc_validate_dm(test);
+       struct amdgpu_dm_backlight_caps *caps;
+
+       dm_test_enable_custom_curve(test);
+
+       caps = validate_custom_curve(dm, falling, ARRAY_SIZE(falling));
+       KUNIT_EXPECT_EQ(test, caps->data_points, 0);
+       KUNIT_EXPECT_EQ(test, convert_brightness_from_user(caps, 32768), 
32768U);
+
+       caps = validate_custom_curve(dm, repeated, ARRAY_SIZE(repeated));
+       KUNIT_EXPECT_EQ(test, caps->data_points, 3);
+       KUNIT_EXPECT_EQ(test, convert_brightness_to_millipercent(caps, 100 * 
0x101), 60000U);
+}
+
+/**
+ * dm_test_validate_custom_curve_too_many_points - Test data_points is cut to 
the array
+ * @test: The KUnit test context
+ *
+ * data_points is a u8 from firmware, so it can claim more points than
+ * luminance_data holds. The check keeps the points that fit
+ */
+static void dm_test_validate_custom_curve_too_many_points(struct kunit *test)
+{
+       struct amdgpu_display_manager *dm = alloc_validate_dm(test);
+       struct amdgpu_dm_backlight_caps *caps = &dm->backlight_caps[0];
+       int i;
+
+       set_gv301qh_caps(caps, false);
+       for (i = 0; i < ARRAY_SIZE(caps->luminance_data); i++) {
+               caps->luminance_data[i].input_signal = 2 * i;
+               caps->luminance_data[i].luminance = i;
+       }
+       caps->data_points = 255;
+       caps->caps_valid = true;
+       amdgpu_dm_validate_backlight_caps(dm, 0);
+
+       KUNIT_EXPECT_EQ(test, caps->data_points, 
ARRAY_SIZE(caps->luminance_data));
+}
+
 /**
  * dm_test_brightness_range_zero_signals - Test Brightness range with zero min 
and max signals
  * @test: The KUnit test context
@@ -2365,6 +2544,11 @@ static struct kunit_case dm_backlight_test_cases[] = {
        KUNIT_CASE(dm_test_backlight_caps_aux_support_noop),
        /* amdgpu_dm_validate_backlight_caps */
        KUNIT_CASE_PARAM(dm_test_validate_backlight_caps, 
dm_validate_caps_gen_params),
+       KUNIT_CASE(dm_test_validate_custom_curve_gv301qh),
+       KUNIT_CASE(dm_test_validate_custom_curve_luminance_over_100),
+       KUNIT_CASE(dm_test_validate_custom_curve_falling),
+       KUNIT_CASE(dm_test_validate_custom_curve_unsorted),
+       KUNIT_CASE(dm_test_validate_custom_curve_too_many_points),
        /* get_brightness_range */
        KUNIT_CASE(dm_test_brightness_range_null_caps),
        KUNIT_CASE(dm_test_brightness_range_pwm),

-- 
2.56.0

Reply via email to