diff options
| author | Bhawanpreet Lakha <bhawanpreet.lakha@amd.com> | 2026-06-25 11:14:25 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-07-28 18:34:57 -0400 |
| commit | ec3938e1a9bd741a80074264b4f702cc8af0b1dc (patch) | |
| tree | 563027556695608aef52cf149f547c747cdff394 | |
| parent | 6be28c11dcb739cd3b2782ec36d035879805fedc (diff) | |
| download | linux-stable-ec3938e1a9bd741a80074264b4f702cc8af0b1dc.tar.gz linux-stable-ec3938e1a9bd741a80074264b4f702cc8af0b1dc.zip | |
drm/amd/display: Add mode validation and CEC tests for connector
Add KUnit coverage for connector mode validation and HDMI CEC:
mode_valid rejects interlaced and doublescan modes, set_edid with no
notifier, and the S3 suspend/resume CEC handlers.
Assisted-by: Copilot:Claude-Opus-4.8
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c | 105 |
2 files changed, 108 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c index 01352fc9445e..0b97fbaf8f5a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c @@ -356,6 +356,7 @@ void amdgpu_dm_hdmi_cec_set_edid(struct amdgpu_dm_connector *aconnector) cec_notifier_set_phys_addr(n, connector->display_info.source_physical_address); } +EXPORT_IF_KUNIT(amdgpu_dm_hdmi_cec_set_edid); void amdgpu_dm_s3_handle_hdmi_cec(struct drm_device *ddev, bool suspend) { @@ -376,6 +377,7 @@ void amdgpu_dm_s3_handle_hdmi_cec(struct drm_device *ddev, bool suspend) } drm_connector_list_iter_end(&conn_iter); } +EXPORT_IF_KUNIT(amdgpu_dm_s3_handle_hdmi_cec); struct drm_connector * @@ -2327,6 +2329,7 @@ fail: /* TODO: error handling*/ return result; } +EXPORT_IF_KUNIT(amdgpu_dm_connector_mode_valid); int amdgpu_dm_fill_hdr_info_packet(const struct drm_connector_state *state, struct dc_info_packet *out) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c index c56efbc1f26b..ee20f2c2a80b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c @@ -4900,6 +4900,103 @@ static void dm_test_parse_displayid_vrr_sets_range(struct kunit *test) KUNIT_EXPECT_EQ(test, connector->display_info.monitor_range.max_vfreq, 144); } +/** + * dm_test_mode_valid_interlace_rejected - Test interlaced modes are rejected + * @test: The KUnit test context + * + * Interlaced modes are rejected up front with MODE_ERROR before any sink or + * stream validation is attempted. + */ +static void dm_test_mode_valid_interlace_rejected(struct kunit *test) +{ + struct amdgpu_dm_connector *aconnector; + struct drm_display_mode *mode; + + aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + mode = kunit_kzalloc(test, sizeof(*mode), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, mode); + + mode->flags = DRM_MODE_FLAG_INTERLACE; + + KUNIT_EXPECT_EQ(test, + amdgpu_dm_connector_mode_valid(&aconnector->base, mode), + MODE_ERROR); +} + +/** + * dm_test_mode_valid_dblscan_rejected - Test doublescan modes are rejected + * @test: The KUnit test context + * + * Doublescan modes are rejected up front with MODE_ERROR. + */ +static void dm_test_mode_valid_dblscan_rejected(struct kunit *test) +{ + struct amdgpu_dm_connector *aconnector; + struct drm_display_mode *mode; + + aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + mode = kunit_kzalloc(test, sizeof(*mode), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, mode); + + mode->flags = DRM_MODE_FLAG_DBLSCAN; + + KUNIT_EXPECT_EQ(test, + amdgpu_dm_connector_mode_valid(&aconnector->base, mode), + MODE_ERROR); +} + +/** + * dm_test_hdmi_cec_set_edid_no_notifier - Test the no-notifier no-op path + * @test: The KUnit test context + * + * With aconnector->notifier NULL the function returns early and must not crash. + */ +static void dm_test_hdmi_cec_set_edid_no_notifier(struct kunit *test) +{ + struct amdgpu_dm_connector *aconnector; + + aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + + amdgpu_dm_hdmi_cec_set_edid(aconnector); +} + +/** + * dm_test_s3_handle_hdmi_cec_suspend - Test the suspend pass over connectors + * @test: The KUnit test context + * + * Suspend iterates all connectors, skipping writeback ones and calling the + * unset path on the rest; with NULL notifiers this is a crash-free no-op. + */ +static void dm_test_s3_handle_hdmi_cec_suspend(struct kunit *test) +{ + struct drm_device *drm = dm_test_alloc_drm(test); + + dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_WRITEBACK); + dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA); + + amdgpu_dm_s3_handle_hdmi_cec(drm, true); +} + +/** + * dm_test_s3_handle_hdmi_cec_resume - Test the resume pass over connectors + * @test: The KUnit test context + * + * Resume iterates all connectors, skipping writeback ones and calling the set + * path on the rest; with NULL notifiers this is a crash-free no-op. + */ +static void dm_test_s3_handle_hdmi_cec_resume(struct kunit *test) +{ + struct drm_device *drm = dm_test_alloc_drm(test); + + dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_WRITEBACK); + dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA); + + amdgpu_dm_s3_handle_hdmi_cec(drm, false); +} + static struct kunit_case amdgpu_dm_connector_tests[] = { /* get_subconnector_type */ KUNIT_CASE(dm_test_subconnector_type_none), @@ -5166,6 +5263,14 @@ static struct kunit_case amdgpu_dm_connector_tests[] = { KUNIT_CASE(dm_test_parse_displayid_vrr_null_edid), KUNIT_CASE(dm_test_parse_displayid_vrr_no_displayid), KUNIT_CASE(dm_test_parse_displayid_vrr_sets_range), + /* amdgpu_dm_connector_mode_valid */ + KUNIT_CASE(dm_test_mode_valid_interlace_rejected), + KUNIT_CASE(dm_test_mode_valid_dblscan_rejected), + /* amdgpu_dm_hdmi_cec_set_edid */ + KUNIT_CASE(dm_test_hdmi_cec_set_edid_no_notifier), + /* amdgpu_dm_s3_handle_hdmi_cec */ + KUNIT_CASE(dm_test_s3_handle_hdmi_cec_suspend), + KUNIT_CASE(dm_test_s3_handle_hdmi_cec_resume), {} }; |
