diff options
| author | Alex Hung <alex.hung@amd.com> | 2026-09-04 00:00:59 -0600 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-09-23 13:27:36 -0400 |
| commit | eaf681630590c2fb609bb0a06993cdf6af28a758 (patch) | |
| tree | 3b5fddc3a7d2e73cf33ad864e5547eb179eb9d53 | |
| parent | ed32f69ac516f0f1ce0a01e5dd7608dbb1b85da8 (diff) | |
| download | linux-next-eaf681630590c2fb609bb0a06993cdf6af28a758.tar.gz linux-next-eaf681630590c2fb609bb0a06993cdf6af28a758.zip | |
drm/amd/display: Test HPD handler HDCP and detect
[WHAT]
handle_hpd_irq_helper() never ran its HDCP reset, its forced
connector branch or its successful re-detect branch.
[HOW]
Add a minimal HDCP work queue fixture and three tests: an HPD on
a driver that carries an HDCP work queue, which must reset the display
and flag the connector state; a connector forced on that reports no
connection and is emulated instead of detected; and a successful
re-detect that notifies userspace.
Assisted-by: Copilot:Claude-Opus-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>
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/tests/amdgpu_dm_irq_test.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c index dbbb7ed377b8..ae68aa34818a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c @@ -21,6 +21,7 @@ #include "amdgpu.h" #include "amdgpu_mode.h" #include "amdgpu_dm.h" +#include "amdgpu_dm_hdcp.h" #include "amdgpu_dm_irq.h" #include "amdgpu_dm_kunit_test_helpers.h" #include "dc_dmub_srv.h" @@ -547,6 +548,39 @@ static void dm_test_register_drm_dev(struct kunit *test, struct amdgpu_device *a &adev->ddev), 0); } +static void dm_test_hdcp_dummy_work(struct work_struct *work) +{ +} + +/* + * Allocate the minimal hdcp_workqueue that hdcp_reset_display() and + * hdcp_handle_cpirq() touch: the per-link mutex, the delayed works + * process_output() re-arms, and the CP IRQ work item. + */ +static struct hdcp_workqueue *dm_test_alloc_hdcp_workqueue(struct kunit *test) +{ + struct hdcp_workqueue *hdcp_work; + + hdcp_work = kunit_kzalloc(test, sizeof(*hdcp_work), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hdcp_work); + + mutex_init(&hdcp_work->mutex); + INIT_WORK(&hdcp_work->cpirq_work, dm_test_hdcp_dummy_work); + INIT_DELAYED_WORK(&hdcp_work->callback_dwork, dm_test_hdcp_dummy_work); + INIT_DELAYED_WORK(&hdcp_work->watchdog_timer_dwork, dm_test_hdcp_dummy_work); + INIT_DELAYED_WORK(&hdcp_work->property_validate_dwork, dm_test_hdcp_dummy_work); + + return hdcp_work; +} + +static void dm_test_flush_hdcp_workqueue(struct hdcp_workqueue *hdcp_work) +{ + flush_work(&hdcp_work->cpirq_work); + cancel_delayed_work_sync(&hdcp_work->callback_dwork); + cancel_delayed_work_sync(&hdcp_work->watchdog_timer_dwork); + cancel_delayed_work_sync(&hdcp_work->property_validate_dwork); +} + /* Tests for amdgpu_dm_hpd_to_dal_irq_source() */ /** @@ -3207,6 +3241,88 @@ static void dm_test_handle_hpd_irq_helper_detect_type_fails(struct kunit *test) } /** + * dm_test_handle_hpd_irq_helper_hdcp_reset - Test the HDCP reset branch + * @test: The KUnit test context + * + * An HPD invalidates the link's HDCP authentication, so a driver carrying an + * HDCP work queue must reset the display and flag the connector state for a + * property update. + */ +static void dm_test_handle_hpd_irq_helper_hdcp_reset(struct kunit *test) +{ + struct amdgpu_dm_connector *aconn; + struct hdcp_workqueue *hdcp_work; + struct link_service *link_srv; + + aconn = dm_test_setup_hpd_irq_helper(test, &link_srv); + link_srv->detect_link = dm_test_detect_link_false; + + hdcp_work = dm_test_alloc_hdcp_workqueue(test); + drm_to_adev(aconn->base.dev)->dm.hdcp_workqueue = hdcp_work; + + handle_hpd_irq_helper(aconn, DETECT_REASON_HPD); + + KUNIT_EXPECT_TRUE(test, to_dm_connector_state(aconn->base.state)->update_hdcp); + + dm_test_flush_hdcp_workqueue(hdcp_work); +} + +/** + * dm_test_handle_hpd_irq_helper_forced_detect - Test the forced-connector branch + * @test: The KUnit test context + * + * A connector forced on but reporting no connection is emulated rather than + * detected, and an HPD RX always notifies userspace. An unset connector signal + * keeps amdgpu_dm_emulated_link_detect() to its unsupported-signal early + * return. + */ +static void dm_test_handle_hpd_irq_helper_forced_detect(struct kunit *test) +{ + struct amdgpu_dm_connector *aconn; + struct link_service *link_srv; + + dm_test_detect_link_count = 0; + + aconn = dm_test_setup_hpd_irq_helper(test, &link_srv); + dm_test_register_drm_dev(test, drm_to_adev(aconn->base.dev)); + + link_srv->detect_link = dm_test_detect_link_false_count; + aconn->base.force = DRM_FORCE_ON; + aconn->dc_link->ctx->driver_context = drm_to_adev(aconn->base.dev); + + handle_hpd_irq_helper(aconn, DETECT_REASON_HPDRX); + + /* The emulated path replaces detection entirely. */ + KUNIT_EXPECT_EQ(test, dm_test_detect_link_count, 0); +} + +/** + * dm_test_handle_hpd_irq_helper_detect_true - Test the connected detect branch + * @test: The KUnit test context + * + * A successful re-detect refreshes the connector state and notifies userspace. + * An MST-state connector keeps amdgpu_dm_update_connector_after_detect() to its + * early return. + */ +static void dm_test_handle_hpd_irq_helper_detect_true(struct kunit *test) +{ + struct amdgpu_dm_connector *aconn; + struct link_service *link_srv; + + aconn = dm_test_setup_hpd_irq_helper(test, &link_srv); + dm_test_register_drm_dev(test, drm_to_adev(aconn->base.dev)); + + link_srv->detect_connection_type = dm_test_detect_connection_single; + link_srv->detect_link = dm_test_detect_link_true; + aconn->mst_mgr.mst_state = true; + aconn->fake_enable = true; + + handle_hpd_irq_helper(aconn, DETECT_REASON_HPD); + + KUNIT_EXPECT_FALSE(test, aconn->fake_enable); +} + +/** * dm_test_handle_hpd_irq_helper_debounce_pending - Test pending-debounce exit * @test: The KUnit test context * @@ -5419,6 +5535,9 @@ static struct kunit_case amdgpu_dm_irq_tests[] = { KUNIT_CASE(dm_test_handle_hpd_irq_helper_detect_false), KUNIT_CASE(dm_test_handle_hpd_irq_helper_detect_type_fails), KUNIT_CASE(dm_test_handle_hpd_irq_helper_debounce_pending), + KUNIT_CASE(dm_test_handle_hpd_irq_helper_hdcp_reset), + KUNIT_CASE(dm_test_handle_hpd_irq_helper_forced_detect), + KUNIT_CASE(dm_test_handle_hpd_irq_helper_detect_true), /* handle_hpd_rx_irq/schedule_hpd_rx_offload_work */ KUNIT_CASE(dm_test_handle_hpd_rx_irq_disabled), KUNIT_CASE(dm_test_handle_hpd_rx_irq_no_left_work), |
