From: Ray Wu <ray.wu@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: Harry Wentland <harry.wentland@amd.com>,
Leo Li <sunpeng.li@amd.com>,
Aurabindo Pillai <aurabindo.pillai@amd.com>,
Roman Li <roman.li@amd.com>, Wayne Lin <wayne.lin@amd.com>,
Tom Chung <chiahsuan.chung@amd.com>,
"Fangzhi Zuo" <jerry.zuo@amd.com>,
Dan Wheeler <daniel.wheeler@amd.com>, Ray Wu <Ray.Wu@amd.com>,
Ivan Lipski <ivan.lipski@amd.com>, Alex Hung <alex.hung@amd.com>,
James Lin <PingLei.Lin@amd.com>,
Chenyu Chen <Chen-Yu.Chen@amd.com>,
Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>,
Ray Wu <ray.wu@amd.com>
Subject: [PATCH 11/40] drm/amd/display: Test atomic validation guards
Date: Wed, 2 Sep 2026 12:58:33 +0800 [thread overview]
Message-ID: <20260902050411.3473916-12-ray.wu@amd.com> (raw)
In-Reply-To: <20260902050411.3473916-1-ray.wu@amd.com>
From: Alex Hung <alex.hung@amd.com>
[Why]
Add KUnit tests for an empty amdgpu_dm_atomic_check(), an unchanged
CRTC update, and a detached plane update.
[How]
Use standard DRM KUnit objects and existing state fixtures so each
helper reaches its software-only early return without DC hardware
programming.
Assisted-by: Copilot:Claude-Opus-5 GPT-5.6 Sol
Reviewed-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 40 +++++-----
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 17 +++++
.../display/amdgpu_dm/tests/amdgpu_dm_test.c | 76 +++++++++++++++++++
3 files changed, 116 insertions(+), 17 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 d94d18e884ef..9f64bea15ea1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -145,8 +145,10 @@ STATIC_IFN_KUNIT int amdgpu_dm_atomic_setup_commit(struct drm_atomic_commit *sta
static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_commit *state);
STATIC_IFN_KUNIT void dm_enable_per_frame_crtc_master_sync(struct dc_state *context);
+#if !IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
static int amdgpu_dm_atomic_check(struct drm_device *dev,
struct drm_atomic_commit *state);
+#endif
static inline void amdgpu_dm_exit_ips_for_hw_access(struct dc *dc)
{
@@ -5428,13 +5430,13 @@ STATIC_IFN_KUNIT int do_aquire_global_lock(struct drm_device *dev,
}
EXPORT_IF_KUNIT(do_aquire_global_lock);
-static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
- struct drm_atomic_commit *state,
- struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state,
- struct drm_crtc_state *new_crtc_state,
- bool enable,
- bool *lock_and_validation_needed)
+STATIC_IFN_KUNIT int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+ struct drm_atomic_commit *state,
+ struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state,
+ struct drm_crtc_state *new_crtc_state,
+ bool enable,
+ bool *lock_and_validation_needed)
{
struct dm_atomic_state *dm_state = NULL;
struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
@@ -5703,6 +5705,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
dc_stream_release(new_stream);
return ret;
}
+EXPORT_IF_KUNIT(dm_update_crtc_state);
STATIC_IFN_KUNIT bool should_reset_plane(struct drm_atomic_commit *state,
struct drm_plane *plane,
@@ -5869,14 +5872,15 @@ STATIC_IFN_KUNIT bool should_reset_plane(struct drm_atomic_commit *state,
}
EXPORT_IF_KUNIT(should_reset_plane);
-static int dm_update_plane_state(struct dc *dc,
- struct drm_atomic_commit *state,
- struct drm_plane *plane,
- struct drm_plane_state *old_plane_state,
- struct drm_plane_state *new_plane_state,
- bool enable,
- bool *lock_and_validation_needed,
- bool *is_top_most_overlay)
+STATIC_IFN_KUNIT int
+dm_update_plane_state(struct dc *dc,
+ struct drm_atomic_commit *state,
+ struct drm_plane *plane,
+ struct drm_plane_state *old_plane_state,
+ struct drm_plane_state *new_plane_state,
+ bool enable,
+ bool *lock_and_validation_needed,
+ bool *is_top_most_overlay)
{
struct dm_atomic_state *dm_state = NULL;
@@ -6040,6 +6044,7 @@ static int dm_update_plane_state(struct dc *dc,
return ret;
}
+EXPORT_IF_KUNIT(dm_update_plane_state);
/*
* The normalized_zpos value cannot be used by this iterator directly. It's only
@@ -6166,8 +6171,8 @@ EXPORT_IF_KUNIT(amdgpu_dm_crtc_mem_type_changed);
*
* Return: -Error code if validation failed.
*/
-static int amdgpu_dm_atomic_check(struct drm_device *dev,
- struct drm_atomic_commit *state)
+STATIC_IFN_KUNIT int amdgpu_dm_atomic_check(struct drm_device *dev,
+ struct drm_atomic_commit *state)
{
struct amdgpu_device *adev = drm_to_adev(dev);
struct dm_atomic_state *dm_state = NULL;
@@ -6678,6 +6683,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
return ret;
}
+EXPORT_IF_KUNIT(amdgpu_dm_atomic_check);
void amdgpu_dm_trigger_timing_sync(struct drm_device *dev)
{
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 3c63dfcc2343..c99a84bb040e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1208,6 +1208,23 @@ void amdgpu_dm_update_hdcp(struct drm_atomic_commit *state);
int amdgpu_dm_atomic_setup_commit(struct drm_atomic_commit *state);
int do_aquire_global_lock(struct drm_device *dev,
struct drm_atomic_commit *state);
+int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+ struct drm_atomic_commit *state,
+ struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state,
+ struct drm_crtc_state *new_crtc_state,
+ bool enable,
+ bool *lock_and_validation_needed);
+int dm_update_plane_state(struct dc *dc,
+ struct drm_atomic_commit *state,
+ struct drm_plane *plane,
+ struct drm_plane_state *old_plane_state,
+ struct drm_plane_state *new_plane_state,
+ bool enable,
+ bool *lock_and_validation_needed,
+ bool *is_top_most_overlay);
+int amdgpu_dm_atomic_check(struct drm_device *dev,
+ struct drm_atomic_commit *state);
void amdgpu_dm_mod_power_update_streams(struct drm_atomic_commit *state,
struct amdgpu_display_manager *dm);
void amdgpu_dm_mod_power_setup_streams(struct drm_atomic_commit *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 3209608a41b8..6335fc23e977 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
@@ -2990,6 +2990,21 @@ static void dm_test_atomic_setup_commit_empty(struct kunit *test)
0);
}
+/**
+ * dm_test_atomic_check_empty - Test an empty atomic commit needs no DC validation
+ * @test: The KUnit test context
+ */
+static void dm_test_atomic_check_empty(struct kunit *test)
+{
+ struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+ struct drm_atomic_commit *state = dm_test_alloc_commit(test, adev);
+
+ adev->dm.dc = dm_kunit_alloc_dc_with_ctx(test);
+
+ KUNIT_EXPECT_EQ(test, amdgpu_dm_atomic_check(&adev->ddev, state), 0);
+ KUNIT_EXPECT_EQ(test, state->num_private_objs, 0U);
+}
+
/*
* A commit with one connector of @type bound to a CRTC that keeps its stream.
* The content protection state is unchanged, so amdgpu_dm_update_hdcp() walks
@@ -3172,6 +3187,64 @@ static void dm_test_aquire_global_lock_waits_commit(struct kunit *test)
KUNIT_EXPECT_EQ(test, ret, 0);
}
+/**
+ * dm_test_update_crtc_state_unchanged - Test unchanged state needs no validation
+ * @test: The KUnit test context
+ */
+static void dm_test_update_crtc_state_unchanged(struct kunit *test)
+{
+ struct dm_test_reset_plane_ctx *ctx = dm_test_reset_plane_ctx_alloc(test);
+ bool lock_and_validation_needed = false;
+
+ ctx->adev->dm.adev = ctx->adev;
+ KUNIT_EXPECT_EQ(test,
+ dm_update_crtc_state(&ctx->adev->dm, ctx->state, ctx->crtc,
+ &ctx->old_crtc_state->base,
+ &ctx->new_crtc_state->base, true,
+ &lock_and_validation_needed),
+ 0);
+ KUNIT_EXPECT_FALSE(test, lock_and_validation_needed);
+ KUNIT_EXPECT_NULL(test, ctx->new_crtc_state->stream);
+}
+
+/**
+ * dm_test_update_plane_state_detached - Test a detached plane needs no DC update
+ * @test: The KUnit test context
+ */
+static void dm_test_update_plane_state_detached(struct kunit *test)
+{
+ struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+ struct dm_plane_state *old_plane_state;
+ struct dm_plane_state *new_plane_state;
+ struct drm_plane *plane;
+ bool lock_and_validation_needed = false;
+ bool is_top_most_overlay = true;
+
+ old_plane_state = kunit_kzalloc(test, sizeof(*old_plane_state), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, old_plane_state);
+ new_plane_state = kunit_kzalloc(test, sizeof(*new_plane_state), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, new_plane_state);
+ plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, plane);
+ adev->reset_domain = kunit_kzalloc(test, sizeof(*adev->reset_domain), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, adev->reset_domain);
+
+ adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 2, 0);
+ plane->dev = &adev->ddev;
+ plane->type = DRM_PLANE_TYPE_PRIMARY;
+
+ KUNIT_EXPECT_EQ(test,
+ dm_update_plane_state(NULL, dm_test_alloc_commit(test, adev), plane,
+ &old_plane_state->base,
+ &new_plane_state->base, false,
+ &lock_and_validation_needed,
+ &is_top_most_overlay),
+ 0);
+ KUNIT_EXPECT_FALSE(test, lock_and_validation_needed);
+ KUNIT_EXPECT_TRUE(test, is_top_most_overlay);
+ KUNIT_EXPECT_NULL(test, new_plane_state->dc_state);
+}
+
/**
* dm_test_mod_power_update_streams_empty - Test an empty commit updates no streams
* @test: The KUnit test context
@@ -5251,9 +5324,12 @@ static struct kunit_case amdgpu_dm_tests[] = {
KUNIT_CASE(dm_test_atomic_setup_commit_color_mgmt),
KUNIT_CASE(dm_test_atomic_setup_commit_modeset),
KUNIT_CASE(dm_test_atomic_setup_commit_bad_lut),
+ KUNIT_CASE(dm_test_atomic_check_empty),
KUNIT_CASE(dm_test_aquire_global_lock_no_crtc),
KUNIT_CASE(dm_test_aquire_global_lock_no_commit),
KUNIT_CASE(dm_test_aquire_global_lock_waits_commit),
+ KUNIT_CASE(dm_test_update_crtc_state_unchanged),
+ KUNIT_CASE(dm_test_update_plane_state_detached),
KUNIT_CASE(dm_test_mod_power_update_streams_empty),
KUNIT_CASE(dm_test_mod_power_update_streams_no_modeset),
KUNIT_CASE(dm_test_mod_power_update_streams_enable),
--
2.43.0
next prev parent reply other threads:[~2026-09-02 5:06 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 4:58 [PATCH 00/40] DC Patches September 7, 2026 Ray Wu
2026-09-02 4:58 ` [PATCH 01/40] drm/amd/display: Ensure requested LSDMA BW is within the SOP bound Ray Wu
2026-09-02 4:58 ` [PATCH 02/40] drm/amd/display: Refactor DC_SEND_CURSOR_INFO_TO_DMU to drop pipe_ctx Ray Wu
2026-09-02 4:58 ` [PATCH 03/40] drm/amd/display: Test vblank IRQ handling Ray Wu
2026-09-02 4:58 ` [PATCH 04/40] drm/amd/display: Test self refresh entry Ray Wu
2026-09-02 4:58 ` [PATCH 05/40] drm/amd/display: Test GPU reset helpers Ray Wu
2026-09-02 4:58 ` [PATCH 06/40] drm/amd/display: Add override for LSDMA BW in QoS table Ray Wu
2026-09-02 4:58 ` [PATCH 07/40] drm/amd/display: Test plane update adapter Ray Wu
2026-09-02 4:58 ` [PATCH 08/40] drm/amd/display: Test MST resume guards Ray Wu
2026-09-02 4:58 ` [PATCH 09/40] drm/amd/display: Test cached suspend state Ray Wu
2026-09-02 4:58 ` [PATCH 10/40] drm/amd/display: Test writeback state transitions Ray Wu
2026-09-02 4:58 ` Ray Wu [this message]
2026-09-02 4:58 ` [PATCH 12/40] drm/amd/display: Cover dm_restore_drm_connector_state Ray Wu
2026-09-02 4:58 ` [PATCH 13/40] drm/amd/display: Cover EDID CEA parsing helpers Ray Wu
2026-09-02 4:58 ` [PATCH 14/40] drm/amd/display: Make sure streamclk gating is off when enabling streamclk Ray Wu
2026-09-02 4:58 ` [PATCH 15/40] drm/amd/display: Remove unnecessary includes Ray Wu
2026-09-02 4:58 ` [PATCH 16/40] drm/amd/display: Set mpc_tree_params->opp_id during OPP resource construct Ray Wu
2026-09-02 4:58 ` [PATCH 17/40] drm/amd/display: Add override capability for UTM table params Ray Wu
2026-09-02 4:58 ` [PATCH 18/40] drm/amd/display: Add immediate restore to FAMS2 for DRR Ray Wu
2026-09-02 4:58 ` [PATCH 19/40] drm/amd/display: Fix missing APG regs for DCN60 HDMI Ray Wu
2026-09-02 4:58 ` [PATCH 20/40] drm/amd/display: Exit IPS before connector detection on resume Ray Wu
2026-09-02 4:58 ` [PATCH 21/40] drm/amd/display: Fix HF-VSDB DSC bpc detection to be cumulative Ray Wu
2026-09-02 4:58 ` [PATCH 22/40] drm/amd/display: Fix unused params in flip sched Ray Wu
2026-09-02 4:58 ` [PATCH 23/40] drm/amd/display: Enable FW locality check in DCN6 Ray Wu
2026-09-02 4:58 ` [PATCH 24/40] drm/amd/display: Fix DC Hub reference frequency assert range Ray Wu
2026-09-02 4:58 ` [PATCH 25/40] drm/amd/display: Dump clock registers in HW init instead of SW init Ray Wu
2026-09-02 4:58 ` [PATCH 26/40] drm/amd/display: Validate irq source in DM IRQ handler Ray Wu
2026-09-02 4:58 ` [PATCH 27/40] drm/amd/display: Test DM IRQ handler source guard Ray Wu
2026-09-02 4:58 ` [PATCH 28/40] Revert "drm/amd/display: Fix CalculateFlipSchedule Calculation" Ray Wu
2026-09-02 4:58 ` [PATCH 29/40] drm/amd/display: Set DISPCLK per surface in DML Ray Wu
2026-09-02 4:58 ` [PATCH 30/40] drm/amd/display: Update Urgent Burst Calculation To Account For Unbounded Requests Ray Wu
2026-09-02 4:58 ` [PATCH 31/40] drm/amd/display: Add stressed peak bandwidth probe with DMA contention Ray Wu
2026-09-02 4:58 ` [PATCH 32/40] Revert "drm/amd/display: Unify CalculateFlipSchedule Logic" Ray Wu
2026-09-02 4:58 ` [PATCH 33/40] drm/amd/display: Add dml2_core_dcn6_calcs function pointer table Ray Wu
2026-09-02 4:58 ` [PATCH 34/40] drm/amd/display: Route DCN6 mode support calcs through " Ray Wu
2026-09-02 4:58 ` [PATCH 35/40] drm/amd/display: Route DCN6 mode programming " Ray Wu
2026-09-02 4:58 ` [PATCH 36/40] drm/amd/display: Update DML fields used for mode support Ray Wu
2026-09-02 4:58 ` [PATCH 37/40] drm/amd/display: Fix NULL deref of new_stream->sink in VTEM guard Ray Wu
2026-09-02 4:59 ` [PATCH 38/40] drm/amd/display: Fix signedness mismatches in cm3 Ray Wu
2026-09-02 4:59 ` [PATCH 39/40] drm/amd/display: [FW Promotion] Release 0.1.74.0 Ray Wu
2026-09-02 4:59 ` [PATCH 40/40] drm/amd/display: Promote DC to 3.2.397 Ray Wu
2026-09-09 13:17 ` [PATCH 00/40] DC Patches September 7, 2026 Wheeler, Daniel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260902050411.3473916-12-ray.wu@amd.com \
--to=ray.wu@amd.com \
--cc=Chen-Yu.Chen@amd.com \
--cc=PingLei.Lin@amd.com \
--cc=alex.hung@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=aurabindo.pillai@amd.com \
--cc=bhawanpreet.lakha@amd.com \
--cc=chiahsuan.chung@amd.com \
--cc=daniel.wheeler@amd.com \
--cc=harry.wentland@amd.com \
--cc=ivan.lipski@amd.com \
--cc=jerry.zuo@amd.com \
--cc=roman.li@amd.com \
--cc=sunpeng.li@amd.com \
--cc=wayne.lin@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.