[PATCH 19/41] drm/amd/display: Add KUnit tests for crtc set_vupdate_irq

<[email protected]> Fri, 31 Jul 2026 17:12:40 -0400
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Bhawanpreet Lakha <[email protected]>

Add dm_test_crtc_set_vupdate_irq_dc_busy and
dm_test_crtc_set_vupdate_irq_enable to cover the previously untested
paths in amdgpu_dm_crtc_set_vupdate_irq() where an OTG instance is
assigned: dc_interrupt_set() failing (returns -EBUSY) and succeeding
via a mock IRQ service (returns 0 for enable and disable).

Assisted-by: Copilot:Claude-Opus-4.8
Reviewed-by: Alex Hung <[email protected]>
Signed-off-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Roman Li <[email protected]>
---
 .../amdgpu_dm/tests/amdgpu_dm_crtc_test.c     | 99 +++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
index 6bc4f932c839..db98e42c561b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
@@ -12,6 +12,8 @@
 #include <drm/drm_vblank.h>
 
 #include "dc.h"
+#include "inc/core_types.h"
+#include "irq/irq_service.h"
 #include "amdgpu.h"
 #include "amdgpu_mode.h"
 #include "amdgpu_dm.h"
@@ -430,6 +432,101 @@ static void dm_test_crtc_set_vupdate_irq_no_otg(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, amdgpu_dm_crtc_set_vupdate_irq(&acrtc->base, false), 0);
 }
 
+/**
+ * dm_test_crtc_set_vupdate_irq_dc_busy - Test vupdate irq when DC rejects request
+ * @test: The KUnit test context
+ *
+ * With an OTG instance assigned but no DC attached, dc_interrupt_set() returns
+ * false and the function must report the request as busy (-EBUSY).
+ */
+static void dm_test_crtc_set_vupdate_irq_dc_busy(struct kunit *test)
+{
+	struct amdgpu_crtc *acrtc;
+	struct amdgpu_device *adev;
+
+	adev = dm_kunit_alloc_adev(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
+
+	acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, acrtc);
+
+	acrtc->base.dev = &adev->ddev;
+	acrtc->otg_inst = 0;
+
+	/* adev->dm.dc is NULL, so dc_interrupt_set() returns false. */
+	KUNIT_EXPECT_EQ(test,
+			amdgpu_dm_crtc_set_vupdate_irq(&acrtc->base, true), -EBUSY);
+}
+
+/* Per-source funcs let dc_interrupt_set() succeed without register access. */
+static bool dm_test_vupdate_irq_src_set(struct irq_service *irq_service,
+					const struct irq_source_info *info,
+					bool enable)
+{
+	return true;
+}
+
+static bool dm_test_vupdate_irq_src_ack(struct irq_service *irq_service,
+					const struct irq_source_info *info)
+{
+	return true;
+}
+
+static struct irq_source_info_funcs dm_test_vupdate_irq_src_funcs = {
+	.set = dm_test_vupdate_irq_src_set,
+	.ack = dm_test_vupdate_irq_src_ack,
+};
+
+/**
+ * dm_test_crtc_set_vupdate_irq_enable - Test vupdate irq enable/disable success
+ * @test: The KUnit test context
+ *
+ * With an OTG instance assigned and a DC whose IRQ service accepts the request,
+ * enabling and disabling the vupdate IRQ must both succeed (return 0).
+ */
+static void dm_test_crtc_set_vupdate_irq_enable(struct kunit *test)
+{
+	struct irq_source_info *info;
+	struct resource_pool *res_pool;
+	struct irq_service *irqs;
+	struct amdgpu_crtc *acrtc;
+	struct amdgpu_device *adev;
+	struct dc *dc;
+	int i;
+
+	adev = dm_kunit_alloc_adev(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
+
+	acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, acrtc);
+
+	dc = dm_kunit_alloc_dc_with_ctx(test);
+	res_pool = kunit_kzalloc(test, sizeof(*res_pool), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res_pool);
+	irqs = kunit_kzalloc(test, sizeof(*irqs), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, irqs);
+
+	/* Populate the per-source info table so dc_interrupt_set() succeeds. */
+	info = kunit_kzalloc(test, sizeof(*info) * DAL_IRQ_SOURCES_NUMBER,
+			     GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, info);
+	for (i = 0; i < DAL_IRQ_SOURCES_NUMBER; i++)
+		info[i].funcs = &dm_test_vupdate_irq_src_funcs;
+
+	irqs->info = info;
+	res_pool->irqs = irqs;
+	dc->res_pool = res_pool;
+	adev->dm.dc = dc;
+
+	acrtc->base.dev = &adev->ddev;
+	acrtc->otg_inst = 0;
+
+	KUNIT_EXPECT_EQ(test,
+			amdgpu_dm_crtc_set_vupdate_irq(&acrtc->base, true), 0);
+	KUNIT_EXPECT_EQ(test,
+			amdgpu_dm_crtc_set_vupdate_irq(&acrtc->base, false), 0);
+}
+
 /* Tests for idle_create_workqueue() */
 
 /**
@@ -1187,6 +1284,8 @@ static struct kunit_case amdgpu_dm_crtc_tests[] = {
 	KUNIT_CASE(dm_test_crtc_helper_mode_fixup_returns_true),
 	/* amdgpu_dm_crtc_set_vupdate_irq */
 	KUNIT_CASE(dm_test_crtc_set_vupdate_irq_no_otg),
+	KUNIT_CASE(dm_test_crtc_set_vupdate_irq_dc_busy),
+	KUNIT_CASE(dm_test_crtc_set_vupdate_irq_enable),
 	/* idle_create_workqueue */
 	KUNIT_CASE(dm_test_idle_create_workqueue),
 	/* amdgpu_dm_idle_worker */
-- 
2.34.1