[WHAT]
Add KUnit tests for dm_update_pflip_irq_state() covering DCN, where there
is nothing to reapply, and DCE, where the current interrupt state is
reapplied to the pageflip source.

[HOW]
Add a spy for the pageflip IRQ source. amdgpu_irq_update() always
dispatches through src->funcs->set(), which needs a registered IH ring on
real hardware, so the spy records the requested type and state instead.

Assisted-by: Copilot:Claude-Opus-5 GPT-5.6-Sol
Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  5 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 78 +++++++++++++++++++
 3 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1eb2f0973aac..4650b5f09c08 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3419,8 +3419,8 @@ static void manage_dm_interrupts(struct amdgpu_device 
*adev,
        }
 }
 
-static void dm_update_pflip_irq_state(struct amdgpu_device *adev,
-                                     struct amdgpu_crtc *acrtc)
+STATIC_IFN_KUNIT void dm_update_pflip_irq_state(struct amdgpu_device *adev,
+                                               struct amdgpu_crtc *acrtc)
 {
        int irq_type =
                amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id);
@@ -3435,6 +3435,7 @@ static void dm_update_pflip_irq_state(struct 
amdgpu_device *adev,
         */
        amdgpu_irq_update(adev, &adev->pageflip_irq, irq_type);
 }
+EXPORT_IF_KUNIT(dm_update_pflip_irq_state);
 
 STATIC_IFN_KUNIT bool
 is_scaling_state_different(const struct dm_connector_state *dm_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index e4b67a0b98c3..c22266f534e3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1172,6 +1172,8 @@ struct dm_atomic_state *dm_atomic_get_new_state(struct 
drm_atomic_commit *state)
 struct drm_private_state *dm_atomic_duplicate_state(struct drm_private_obj 
*obj);
 void dm_atomic_destroy_state(struct drm_private_obj *obj,
                             struct drm_private_state *state);
+void dm_update_pflip_irq_state(struct amdgpu_device *adev,
+                              struct amdgpu_crtc *acrtc);
 void amdgpu_dm_commit_cursors(struct drm_atomic_commit *state);
 void amdgpu_dm_update_cursor(struct drm_plane *plane,
                             struct drm_plane_state *old_plane_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
index 648db4a58509..845638fed223 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
@@ -1729,6 +1729,81 @@ static void dm_test_arm_vblank_event_cursor(struct kunit 
*test)
                        (int)AMDGPU_FLIP_NONE);
 }
 
+/**
+ * dm_test_update_pflip_irq_state_dcn - Test DCN skips the GRPH_PFLIP reapply
+ * @test: The KUnit test context
+ */
+static void dm_test_update_pflip_irq_state_dcn(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct amdgpu_crtc *acrtc;
+
+       acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, acrtc);
+
+       adev->mode_info.num_crtc = 1;
+       adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 2, 0);
+
+       dm_update_pflip_irq_state(adev, acrtc);
+}
+
+/*
+ * Spy for the pageflip IRQ source: amdgpu_irq_update() always dispatches
+ * through src->funcs->set(), which needs a registered IH ring on real
+ * hardware. Recording the requested state instead keeps the DCE reapply path
+ * reachable and observable.
+ */
+struct dm_test_irq_spy {
+       unsigned int set_count;
+       unsigned int last_type;
+       enum amdgpu_interrupt_state last_state;
+};
+
+static struct dm_test_irq_spy dm_test_irq_spy_data;
+
+static int dm_test_irq_set(struct amdgpu_device *adev,
+                          struct amdgpu_irq_src *src, unsigned int type,
+                          enum amdgpu_interrupt_state state)
+{
+       dm_test_irq_spy_data.set_count++;
+       dm_test_irq_spy_data.last_type = type;
+       dm_test_irq_spy_data.last_state = state;
+
+       return 0;
+}
+
+static const struct amdgpu_irq_src_funcs dm_test_irq_funcs = {
+       .set = dm_test_irq_set,
+};
+
+/**
+ * dm_test_update_pflip_irq_state_dce - Test DCE reapplies the GRPH_PFLIP state
+ * @test: The KUnit test context
+ */
+static void dm_test_update_pflip_irq_state_dce(struct kunit *test)
+{
+       struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+       struct amdgpu_crtc *acrtc;
+
+       acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, acrtc);
+
+       memset(&dm_test_irq_spy_data, 0, sizeof(dm_test_irq_spy_data));
+       adev->mode_info.num_crtc = 2;
+       adev->ip_versions[DCE_HWIP][0] = 0;
+       adev->pageflip_irq.funcs = &dm_test_irq_funcs;
+       acrtc->crtc_id = 1;
+       spin_lock_init(&adev->irq.lock);
+
+       dm_update_pflip_irq_state(adev, acrtc);
+
+       KUNIT_EXPECT_EQ(test, dm_test_irq_spy_data.set_count, 1U);
+       KUNIT_EXPECT_EQ(test, dm_test_irq_spy_data.last_type,
+                       (unsigned int)AMDGPU_CRTC_IRQ_VBLANK2);
+       KUNIT_EXPECT_EQ(test, (int)dm_test_irq_spy_data.last_state,
+                       (int)AMDGPU_IRQ_STATE_DISABLE);
+}
+
 static struct kunit_case amdgpu_dm_tests[] = {
        /* Simple DM callbacks */
        KUNIT_CASE(dm_test_wait_for_idle),
@@ -1822,6 +1897,9 @@ static struct kunit_case amdgpu_dm_tests[] = {
        KUNIT_CASE(dm_test_arm_vblank_pre_programming_no_event),
        KUNIT_CASE(dm_test_arm_vblank_pre_programming_no_planes),
        KUNIT_CASE(dm_test_arm_vblank_pre_programming_update),
+       /* dm_update_pflip_irq_state */
+       KUNIT_CASE(dm_test_update_pflip_irq_state_dcn),
+       KUNIT_CASE(dm_test_update_pflip_irq_state_dce),
        {}
 };
 
-- 
2.43.0

Reply via email to