From: Alex Hung <[email protected]>

[WHAT]
Add KUnit coverage for dm_helpers_dp_mst_start_top_mgr and
dm_helpers_dp_mst_stop_top_mgr, dm_helpers_dp_write_hblank_reduction,
get_dsc_max_slices, dm_helpers_init_panel_settings,
dm_helpers_override_panel_settings and
fill_dc_mst_payload_table_from_drm.

Assisted-by: Copilot:Claude-Opus-4.8
Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
Signed-off-by: George Zhang <[email protected]>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |   8 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.h |   5 +
 .../amdgpu_dm/tests/amdgpu_dm_helpers_test.c  | 295 ++++++++++++++++++
 3 files changed, 306 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 804a95a19acf..aa4bd99528a3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -240,7 +240,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
 }
 EXPORT_IF_KUNIT(dm_helpers_parse_edid_caps);

-static void
+STATIC_IFN_KUNIT void
 fill_dc_mst_payload_table_from_drm(struct dc_link *link,
                                   bool enable,
                                   struct drm_dp_mst_atomic_payload 
*target_payload,
@@ -290,6 +290,7 @@ fill_dc_mst_payload_table_from_drm(struct dc_link *link,
        /* Overwrite the old table */
        *table = new_table;
 }
+EXPORT_IF_KUNIT(fill_dc_mst_payload_table_from_drm);

 void dm_helpers_dp_update_branch_info(
        struct dc_context *ctx,
@@ -1149,7 +1150,7 @@ STATIC_IFN_KUNIT uint8_t get_max_frl_rate(uint8_t 
max_lanes, uint8_t max_rate_pe
 }
 EXPORT_IF_KUNIT(get_max_frl_rate);

-static uint8_t get_dsc_max_slices(uint8_t max_slices, int clk_per_slice)
+STATIC_IFN_KUNIT uint8_t get_dsc_max_slices(uint8_t max_slices, int 
clk_per_slice)
 {
        uint8_t dsc_max_slices;

@@ -1172,6 +1173,7 @@ static uint8_t get_dsc_max_slices(uint8_t max_slices, int 
clk_per_slice)

        return dsc_max_slices;
 }
+EXPORT_IF_KUNIT(get_dsc_max_slices);

 void populate_hdmi_info_from_connector(bool enable_frl, struct drm_hdmi_info 
*hdmi, struct dc_edid_caps *edid_caps)
 {
@@ -1354,6 +1356,7 @@ void dm_helpers_init_panel_settings(
        panel_config->dsc.disable_dsc_edp = false;
        panel_config->dsc.force_dsc_edp_policy = 0;
 }
+EXPORT_IF_KUNIT(dm_helpers_init_panel_settings);

 void dm_helpers_override_panel_settings(
        struct dc_context *ctx,
@@ -1371,6 +1374,7 @@ void dm_helpers_override_panel_settings(
                link->panel_config.psr.disallow_replay = true;
        }
 }
+EXPORT_IF_KUNIT(dm_helpers_override_panel_settings);

 void *dm_helpers_allocate_gpu_mem(
                struct dc_context *ctx,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.h
index 343650b50707..e256e1e12422 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.h
@@ -25,9 +25,14 @@ u32 edid_extract_panel_id(struct edid *edid);
 void apply_edid_quirks(struct dc_link *link, struct edid *edid,
                       struct dc_edid_caps *edid_caps);
 uint8_t get_max_frl_rate(uint8_t max_lanes, uint8_t max_rate_per_lane);
+uint8_t get_dsc_max_slices(uint8_t max_slices, int clk_per_slice);
 bool dm_is_freesync_pcon_whitelist(const uint32_t branch_dev_id);
 extern const uint32_t dm_freesync_pcon_whitelist[];
 uint32_t dm_freesync_pcon_whitelist_count(void);
+void fill_dc_mst_payload_table_from_drm(struct dc_link *link,
+                                        bool enable,
+                                        struct drm_dp_mst_atomic_payload 
*target_payload,
+                                        struct 
dc_dp_mst_stream_allocation_table *table);
 bool dm_helpers_dp_write_dsc_enable(struct dc_context *ctx,
                                    const struct dc_stream_state *stream,
                                    bool enable);
diff --git 
a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
index eed941a889e9..599de8240bee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
@@ -1746,6 +1746,282 @@ static void 
dm_test_dp_write_hblank_reduction_false(struct kunit *test)
        KUNIT_EXPECT_FALSE(test, dm_helpers_dp_write_hblank_reduction(NULL, 
NULL));
 }

+/* Tests for get_dsc_max_slices() */
+
+/**
+ * dm_test_get_dsc_max_slices_1_340 - Test 1 slice at 340 MHz
+ * @test: The KUnit test context
+ */
+static void dm_test_get_dsc_max_slices_1_340(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(1, 340), 1);
+}
+
+/**
+ * dm_test_get_dsc_max_slices_2_340 - Test 2 slices at 340 MHz
+ * @test: The KUnit test context
+ */
+static void dm_test_get_dsc_max_slices_2_340(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(2, 340), 2);
+}
+
+/**
+ * dm_test_get_dsc_max_slices_4_340 - Test 4 slices at 340 MHz
+ * @test: The KUnit test context
+ */
+static void dm_test_get_dsc_max_slices_4_340(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(4, 340), 3);
+}
+
+/**
+ * dm_test_get_dsc_max_slices_8_340 - Test 8 slices at 340 MHz
+ * @test: The KUnit test context
+ */
+static void dm_test_get_dsc_max_slices_8_340(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(8, 340), 4);
+}
+
+/**
+ * dm_test_get_dsc_max_slices_8_400 - Test 8 slices at 400 MHz
+ * @test: The KUnit test context
+ */
+static void dm_test_get_dsc_max_slices_8_400(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(8, 400), 5);
+}
+
+/**
+ * dm_test_get_dsc_max_slices_12_400 - Test 12 slices at 400 MHz
+ * @test: The KUnit test context
+ */
+static void dm_test_get_dsc_max_slices_12_400(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(12, 400), 6);
+}
+
+/**
+ * dm_test_get_dsc_max_slices_16_400 - Test 16 slices at 400 MHz
+ * @test: The KUnit test context
+ */
+static void dm_test_get_dsc_max_slices_16_400(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(16, 400), 7);
+}
+
+/**
+ * dm_test_get_dsc_max_slices_unknown - Test unknown combination returns 0
+ * @test: The KUnit test context
+ */
+static void dm_test_get_dsc_max_slices_unknown(struct kunit *test)
+{
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(3, 340), 0);
+       KUNIT_EXPECT_EQ(test, get_dsc_max_slices(1, 400), 0);
+}
+
+/* Tests for dm_helpers_init_panel_settings() */
+
+/**
+ * dm_test_init_panel_settings_pps - Test panel power sequence settings init
+ * @test: The KUnit test context
+ */
+static void dm_test_init_panel_settings_pps(struct kunit *test)
+{
+       struct dc_panel_config panel_config = {0};
+       struct dc_sink *sink;
+
+       sink = kunit_kzalloc(test, sizeof(*sink), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, sink);
+
+       sink->edid_caps.panel_patch.extra_t3_ms = 100;
+       sink->edid_caps.panel_patch.extra_t7_ms = 200;
+       sink->edid_caps.panel_patch.extra_delay_backlight_off = 50;
+       sink->edid_caps.panel_patch.extra_t12_ms = 300;
+
+       dm_helpers_init_panel_settings(NULL, &panel_config, sink);
+
+       KUNIT_EXPECT_EQ(test, panel_config.pps.extra_t3_ms, 100U);
+       KUNIT_EXPECT_EQ(test, panel_config.pps.extra_t7_ms, 200U);
+       KUNIT_EXPECT_EQ(test, panel_config.pps.extra_delay_backlight_off, 50U);
+       KUNIT_EXPECT_EQ(test, panel_config.pps.extra_post_t7_ms, 0U);
+       KUNIT_EXPECT_EQ(test, panel_config.pps.extra_pre_t11_ms, 0U);
+       KUNIT_EXPECT_EQ(test, panel_config.pps.extra_t12_ms, 300U);
+       KUNIT_EXPECT_EQ(test, panel_config.pps.extra_post_OUI_ms, 0U);
+}
+
+/**
+ * dm_test_init_panel_settings_dsc - Test DSC defaults in panel settings init
+ * @test: The KUnit test context
+ */
+static void dm_test_init_panel_settings_dsc(struct kunit *test)
+{
+       struct dc_panel_config panel_config;
+       struct dc_sink *sink;
+
+       memset(&panel_config, 0xFF, sizeof(panel_config));
+
+       sink = kunit_kzalloc(test, sizeof(*sink), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, sink);
+
+       dm_helpers_init_panel_settings(NULL, &panel_config, sink);
+
+       KUNIT_EXPECT_FALSE(test, panel_config.dsc.disable_dsc_edp);
+       KUNIT_EXPECT_EQ(test, panel_config.dsc.force_dsc_edp_policy, 0U);
+}
+
+/* Tests for dm_helpers_override_panel_settings() */
+
+/**
+ * dm_test_override_panel_settings_debug_mask_disables_dsc - Test DSC mask
+ * @test: The KUnit test context
+ */
+static void dm_test_override_panel_settings_debug_mask_disables_dsc(struct 
kunit *test)
+{
+       struct dc_context *ctx;
+       struct dc_link *link;
+       struct dc *dc;
+       uint old_debug_mask;
+
+       ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, ctx);
+       dc = kunit_kzalloc(test, sizeof(*dc), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, dc);
+       link = dm_kunit_alloc_link(test);
+       ctx->dc = dc;
+       link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
+
+       old_debug_mask = dm_helpers_get_dc_debug_mask();
+       dm_helpers_set_dc_debug_mask(old_debug_mask | DC_DISABLE_DSC);
+       dm_helpers_override_panel_settings(ctx, link);
+       dm_helpers_set_dc_debug_mask(old_debug_mask);
+
+       KUNIT_EXPECT_TRUE(test, link->panel_config.dsc.disable_dsc_edp);
+}
+
+/**
+ * dm_test_override_panel_settings_second_edp_disables_psr - Test eDP index 1
+ * @test: The KUnit test context
+ */
+static void dm_test_override_panel_settings_second_edp_disables_psr(struct 
kunit *test)
+{
+       struct dc_context *ctx;
+       struct dc_link *first_link;
+       struct dc_link *second_link;
+       struct dc *dc;
+
+       ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, ctx);
+       dc = kunit_kzalloc(test, sizeof(*dc), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, dc);
+       first_link = dm_kunit_alloc_link(test);
+       second_link = dm_kunit_alloc_link(test);
+
+       ctx->dc = dc;
+       dc->link_count = 2;
+       dc->links[0] = first_link;
+       dc->links[1] = second_link;
+       first_link->connector_signal = SIGNAL_TYPE_EDP;
+       second_link->connector_signal = SIGNAL_TYPE_EDP;
+
+       dm_helpers_override_panel_settings(ctx, second_link);
+
+       KUNIT_EXPECT_TRUE(test, second_link->panel_config.psr.disable_psr);
+       KUNIT_EXPECT_TRUE(test, second_link->panel_config.psr.disallow_psrsu);
+       KUNIT_EXPECT_TRUE(test, second_link->panel_config.psr.disallow_replay);
+}
+
+/* Tests for fill_dc_mst_payload_table_from_drm() */
+
+/**
+ * dm_test_fill_mst_payload_table_enable - Test payload table fill on enable
+ * @test: The KUnit test context
+ */
+static void dm_test_fill_mst_payload_table_enable(struct kunit *test)
+{
+       struct dc_link *link;
+       struct drm_dp_mst_atomic_payload payload = {0};
+       struct dc_dp_mst_stream_allocation_table table = {0};
+
+       link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, link);
+
+       /* Pre-existing allocation in the link table */
+       link->mst_stream_alloc_table.stream_count = 1;
+       link->mst_stream_alloc_table.stream_allocations[0].vcp_id = 1;
+       link->mst_stream_alloc_table.stream_allocations[0].slot_count = 4;
+
+       /* New payload to add */
+       payload.vcpi = 2;
+       payload.time_slots = 8;
+
+       fill_dc_mst_payload_table_from_drm(link, true, &payload, &table);
+
+       /* Should contain both the pre-existing and new allocation */
+       KUNIT_EXPECT_EQ(test, table.stream_count, 2);
+       KUNIT_EXPECT_EQ(test, table.stream_allocations[0].vcp_id, 1);
+       KUNIT_EXPECT_EQ(test, table.stream_allocations[0].slot_count, 4);
+       KUNIT_EXPECT_EQ(test, table.stream_allocations[1].vcp_id, 2);
+       KUNIT_EXPECT_EQ(test, table.stream_allocations[1].slot_count, 8);
+}
+
+/**
+ * dm_test_fill_mst_payload_table_disable - Test payload table fill on disable
+ * @test: The KUnit test context
+ */
+static void dm_test_fill_mst_payload_table_disable(struct kunit *test)
+{
+       struct dc_link *link;
+       struct drm_dp_mst_atomic_payload payload = {0};
+       struct dc_dp_mst_stream_allocation_table table = {0};
+
+       link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, link);
+
+       /* Two existing allocations in the link table */
+       link->mst_stream_alloc_table.stream_count = 2;
+       link->mst_stream_alloc_table.stream_allocations[0].vcp_id = 1;
+       link->mst_stream_alloc_table.stream_allocations[0].slot_count = 4;
+       link->mst_stream_alloc_table.stream_allocations[1].vcp_id = 2;
+       link->mst_stream_alloc_table.stream_allocations[1].slot_count = 8;
+
+       /* Remove vcp_id 1 */
+       payload.vcpi = 1;
+       payload.time_slots = 4;
+
+       fill_dc_mst_payload_table_from_drm(link, false, &payload, &table);
+
+       /* Only vcp_id 2 should remain */
+       KUNIT_EXPECT_EQ(test, table.stream_count, 1);
+       KUNIT_EXPECT_EQ(test, table.stream_allocations[0].vcp_id, 2);
+       KUNIT_EXPECT_EQ(test, table.stream_allocations[0].slot_count, 8);
+}
+
+/**
+ * dm_test_fill_mst_payload_table_empty - Test payload table fill when empty
+ * @test: The KUnit test context
+ */
+static void dm_test_fill_mst_payload_table_empty(struct kunit *test)
+{
+       struct dc_link *link;
+       struct drm_dp_mst_atomic_payload payload = {0};
+       struct dc_dp_mst_stream_allocation_table table = {0};
+
+       link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, link);
+
+       /* Enable on an empty table */
+       payload.vcpi = 5;
+       payload.time_slots = 12;
+
+       fill_dc_mst_payload_table_from_drm(link, true, &payload, &table);
+
+       KUNIT_EXPECT_EQ(test, table.stream_count, 1);
+       KUNIT_EXPECT_EQ(test, table.stream_allocations[0].vcp_id, 5);
+       KUNIT_EXPECT_EQ(test, table.stream_allocations[0].slot_count, 12);
+}
+
 static struct kunit_case amdgpu_dm_helpers_test_cases[] = {
        /* edid_extract_panel_id */
        KUNIT_CASE(dm_test_edid_extract_panel_id_basic),
@@ -1832,6 +2108,25 @@ static struct kunit_case amdgpu_dm_helpers_test_cases[] 
= {
        KUNIT_CASE(dm_test_mst_start_top_mgr_boot),
        /* dm_helpers_dp_write_hblank_reduction */
        KUNIT_CASE(dm_test_dp_write_hblank_reduction_false),
+       /* get_dsc_max_slices */
+       KUNIT_CASE(dm_test_get_dsc_max_slices_1_340),
+       KUNIT_CASE(dm_test_get_dsc_max_slices_2_340),
+       KUNIT_CASE(dm_test_get_dsc_max_slices_4_340),
+       KUNIT_CASE(dm_test_get_dsc_max_slices_8_340),
+       KUNIT_CASE(dm_test_get_dsc_max_slices_8_400),
+       KUNIT_CASE(dm_test_get_dsc_max_slices_12_400),
+       KUNIT_CASE(dm_test_get_dsc_max_slices_16_400),
+       KUNIT_CASE(dm_test_get_dsc_max_slices_unknown),
+       /* dm_helpers_init_panel_settings */
+       KUNIT_CASE(dm_test_init_panel_settings_pps),
+       KUNIT_CASE(dm_test_init_panel_settings_dsc),
+       /* dm_helpers_override_panel_settings */
+       KUNIT_CASE(dm_test_override_panel_settings_debug_mask_disables_dsc),
+       KUNIT_CASE(dm_test_override_panel_settings_second_edp_disables_psr),
+       /* fill_dc_mst_payload_table_from_drm */
+       KUNIT_CASE(dm_test_fill_mst_payload_table_enable),
+       KUNIT_CASE(dm_test_fill_mst_payload_table_disable),
+       KUNIT_CASE(dm_test_fill_mst_payload_table_empty),
        {}
 };

--
2.55.0

Reply via email to