mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
drm/amd/display: Add KUnit tests for more crtc functions
Expand KUnit coverage for amdgpu_dm_crtc.c with tests for functions that are easy to exercise in isolation: - amdgpu_dm_crtc_set_static_screen_optimze(): the !allow_sr_entry early return. - amdgpu_dm_crtc_enable_vblank(): rejection with -EINVAL when enabling vblank on an unconfigured CRTC. - amdgpu_dm_crtc_update_crtc_active_planes(): the no-stream branch that resets active_planes to zero. - amdgpu_dm_crtc_duplicate_state(): DM-specific fields are carried over. - amdgpu_dm_crtc_reset_state(): a fresh state is allocated and installed. - amdgpu_dm_crtc_destroy_state(): a stream-less state is freed cleanly. Expose amdgpu_dm_crtc_destroy_state(), amdgpu_dm_crtc_duplicate_state(), amdgpu_dm_crtc_reset_state() and amdgpu_dm_crtc_update_crtc_active_planes() to the tests via STATIC_IFN_KUNIT/EXPORT_IF_KUNIT. 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: Roman Li <roman.li@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
73efd24e21
commit
d1db1a99fc
|
|
@ -134,6 +134,7 @@ void amdgpu_dm_crtc_set_static_screen_optimze(
|
|||
amdgpu_dm_psr_set_event(dm, stream,
|
||||
set_vsync_event, psr_event_vsync, set_vsync_event);
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_crtc_set_static_screen_optimze);
|
||||
|
||||
bool amdgpu_dm_is_headless(struct amdgpu_device *adev)
|
||||
{
|
||||
|
|
@ -393,13 +394,14 @@ int amdgpu_dm_crtc_enable_vblank(struct drm_crtc *crtc)
|
|||
{
|
||||
return amdgpu_dm_crtc_set_vblank(crtc, true);
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_crtc_enable_vblank);
|
||||
|
||||
void amdgpu_dm_crtc_disable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
amdgpu_dm_crtc_set_vblank(crtc, false);
|
||||
}
|
||||
|
||||
static void amdgpu_dm_crtc_destroy_state(struct drm_crtc *crtc,
|
||||
STATIC_IFN_KUNIT void amdgpu_dm_crtc_destroy_state(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
struct dm_crtc_state *cur = to_dm_crtc_state(state);
|
||||
|
|
@ -414,8 +416,9 @@ static void amdgpu_dm_crtc_destroy_state(struct drm_crtc *crtc,
|
|||
|
||||
kfree(state);
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_crtc_destroy_state);
|
||||
|
||||
static struct drm_crtc_state *amdgpu_dm_crtc_duplicate_state(struct drm_crtc *crtc)
|
||||
STATIC_IFN_KUNIT struct drm_crtc_state *amdgpu_dm_crtc_duplicate_state(struct drm_crtc *crtc)
|
||||
{
|
||||
struct dm_crtc_state *state, *cur;
|
||||
|
||||
|
|
@ -450,6 +453,7 @@ static struct drm_crtc_state *amdgpu_dm_crtc_duplicate_state(struct drm_crtc *cr
|
|||
|
||||
return &state->base;
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_crtc_duplicate_state);
|
||||
|
||||
static void amdgpu_dm_crtc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
|
|
@ -463,7 +467,7 @@ static void amdgpu_dm_crtc_destroy(struct drm_crtc *crtc)
|
|||
kfree(crtc);
|
||||
}
|
||||
|
||||
static void amdgpu_dm_crtc_reset_state(struct drm_crtc *crtc)
|
||||
STATIC_IFN_KUNIT void amdgpu_dm_crtc_reset_state(struct drm_crtc *crtc)
|
||||
{
|
||||
struct dm_crtc_state *state;
|
||||
|
||||
|
|
@ -476,6 +480,7 @@ static void amdgpu_dm_crtc_reset_state(struct drm_crtc *crtc)
|
|||
|
||||
__drm_atomic_helper_crtc_reset(crtc, &state->base);
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_crtc_reset_state);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
|
||||
|
|
@ -610,7 +615,7 @@ static int amdgpu_dm_crtc_count_crtc_active_planes(struct drm_crtc_state *new_cr
|
|||
return num_active;
|
||||
}
|
||||
|
||||
static void amdgpu_dm_crtc_update_crtc_active_planes(struct drm_crtc *crtc,
|
||||
STATIC_IFN_KUNIT void amdgpu_dm_crtc_update_crtc_active_planes(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *new_crtc_state)
|
||||
{
|
||||
struct dm_crtc_state *dm_new_crtc_state =
|
||||
|
|
@ -624,6 +629,7 @@ static void amdgpu_dm_crtc_update_crtc_active_planes(struct drm_crtc *crtc,
|
|||
dm_new_crtc_state->active_planes =
|
||||
amdgpu_dm_crtc_count_crtc_active_planes(new_crtc_state);
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_crtc_update_crtc_active_planes);
|
||||
|
||||
STATIC_IFN_KUNIT bool amdgpu_dm_crtc_helper_mode_fixup(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ bool amdgpu_dm_crtc_vrr_active_irq(struct amdgpu_crtc *acrtc);
|
|||
bool amdgpu_dm_crtc_helper_mode_fixup(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
void amdgpu_dm_crtc_destroy_state(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state);
|
||||
struct drm_crtc_state *amdgpu_dm_crtc_duplicate_state(struct drm_crtc *crtc);
|
||||
void amdgpu_dm_crtc_reset_state(struct drm_crtc *crtc);
|
||||
void amdgpu_dm_crtc_update_crtc_active_planes(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *new_crtc_state);
|
||||
#endif
|
||||
|
||||
bool amdgpu_dm_crtc_vrr_active(const struct dm_crtc_state *dm_state);
|
||||
|
|
|
|||
|
|
@ -456,6 +456,171 @@ static void dm_test_idle_create_workqueue(struct kunit *test)
|
|||
kfree(idle_work);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_crtc_set_static_screen_optimze() */
|
||||
|
||||
/**
|
||||
* dm_test_crtc_set_static_screen_optimze_no_sr_entry - Test early return when SR entry disallowed
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* When self-refresh entry is not allowed the function must return immediately
|
||||
* without touching replay or PSR events, regardless of the requested SSO state.
|
||||
*/
|
||||
static void dm_test_crtc_set_static_screen_optimze_no_sr_entry(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_display_manager *dm;
|
||||
struct dc_link *link;
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
dm = kunit_kzalloc(test, sizeof(*dm), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dm);
|
||||
|
||||
link = dm_kunit_alloc_link(test);
|
||||
stream = dm_kunit_alloc_stream(test, link);
|
||||
|
||||
/* allow_sr_entry == false -> returns before any event is set. */
|
||||
amdgpu_dm_crtc_set_static_screen_optimze(dm, stream, true, false);
|
||||
amdgpu_dm_crtc_set_static_screen_optimze(dm, stream, false, false);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_crtc_enable_vblank() */
|
||||
|
||||
/**
|
||||
* dm_test_crtc_enable_vblank_rejects_unconfigured - Test vblank enable on disabled CRTC
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* Enabling vblank on a CRTC that is not enabled must be rejected with -EINVAL
|
||||
* before any interrupt state is touched.
|
||||
*/
|
||||
static void dm_test_crtc_enable_vblank_rejects_unconfigured(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_ERR_OR_NULL(test, acrtc);
|
||||
|
||||
acrtc->base.dev = &adev->ddev;
|
||||
acrtc->base.enabled = false;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, amdgpu_dm_crtc_enable_vblank(&acrtc->base), -EINVAL);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_crtc_update_crtc_active_planes() */
|
||||
|
||||
/**
|
||||
* dm_test_crtc_update_active_planes_no_stream - Test active plane reset without a stream
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* Without a DC stream attached the active plane count must be reset to zero
|
||||
* and the plane-counting path must be skipped.
|
||||
*/
|
||||
static void dm_test_crtc_update_active_planes_no_stream(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state *dm_state;
|
||||
|
||||
dm_state = kunit_kzalloc(test, sizeof(*dm_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dm_state);
|
||||
|
||||
dm_state->stream = NULL;
|
||||
dm_state->active_planes = 5;
|
||||
|
||||
amdgpu_dm_crtc_update_crtc_active_planes(NULL, &dm_state->base);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, dm_state->active_planes, 0);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_crtc_duplicate_state() */
|
||||
|
||||
/**
|
||||
* dm_test_crtc_duplicate_state_copies_fields - Test duplicated state carries DM fields
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* Duplicating a CRTC state without a stream must produce a new state that
|
||||
* carries over the DM-specific fields from the current state.
|
||||
*/
|
||||
static void dm_test_crtc_duplicate_state_copies_fields(struct kunit *test)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
struct dm_crtc_state *cur;
|
||||
struct drm_crtc_state *dup;
|
||||
struct dm_crtc_state *dm_dup;
|
||||
|
||||
crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
|
||||
cur = kunit_kzalloc(test, sizeof(*cur), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cur);
|
||||
|
||||
cur->abm_level = 3;
|
||||
cur->active_planes = 2;
|
||||
cur->vrr_supported = true;
|
||||
cur->cm_has_degamma = true;
|
||||
cur->cm_is_degamma_srgb = true;
|
||||
cur->crc_skip_count = 7;
|
||||
cur->mpo_requested = true;
|
||||
crtc->state = &cur->base;
|
||||
|
||||
dup = amdgpu_dm_crtc_duplicate_state(crtc);
|
||||
KUNIT_ASSERT_NOT_NULL(test, dup);
|
||||
|
||||
dm_dup = to_dm_crtc_state(dup);
|
||||
KUNIT_EXPECT_EQ(test, dm_dup->abm_level, 3);
|
||||
KUNIT_EXPECT_EQ(test, dm_dup->active_planes, 2);
|
||||
KUNIT_EXPECT_TRUE(test, dm_dup->vrr_supported);
|
||||
KUNIT_EXPECT_TRUE(test, dm_dup->cm_has_degamma);
|
||||
KUNIT_EXPECT_TRUE(test, dm_dup->cm_is_degamma_srgb);
|
||||
KUNIT_EXPECT_EQ(test, dm_dup->crc_skip_count, 7);
|
||||
KUNIT_EXPECT_TRUE(test, dm_dup->mpo_requested);
|
||||
|
||||
amdgpu_dm_crtc_destroy_state(crtc, dup);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_crtc_reset_state() */
|
||||
|
||||
/**
|
||||
* dm_test_crtc_reset_state_allocates_state - Test reset installs a fresh state
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* Resetting a CRTC with no existing state must allocate and install a new
|
||||
* drm_crtc_state.
|
||||
*/
|
||||
static void dm_test_crtc_reset_state_allocates_state(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
|
||||
crtc->dev = &adev->ddev;
|
||||
crtc->state = NULL;
|
||||
|
||||
amdgpu_dm_crtc_reset_state(crtc);
|
||||
|
||||
KUNIT_EXPECT_NOT_NULL(test, crtc->state);
|
||||
|
||||
if (crtc->state)
|
||||
amdgpu_dm_crtc_destroy_state(crtc, crtc->state);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_crtc_destroy_state() */
|
||||
|
||||
/**
|
||||
* dm_test_crtc_destroy_state_no_stream - Test destroy frees a stream-less state
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* Destroying a CRTC state with no stream attached must free the state without
|
||||
* attempting to release a DC stream.
|
||||
*/
|
||||
static void dm_test_crtc_destroy_state_no_stream(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state *dm_state;
|
||||
|
||||
/* destroy_state kfree()s the state, so use a plain (unmanaged) alloc. */
|
||||
dm_state = kzalloc_obj(*dm_state, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dm_state);
|
||||
|
||||
amdgpu_dm_crtc_destroy_state(NULL, &dm_state->base);
|
||||
}
|
||||
|
||||
static struct kunit_case amdgpu_dm_crtc_tests[] = {
|
||||
/* amdgpu_dm_crtc_modeset_required */
|
||||
KUNIT_CASE(dm_test_crtc_modeset_required_active_mode_changed),
|
||||
|
|
@ -488,6 +653,18 @@ static struct kunit_case amdgpu_dm_crtc_tests[] = {
|
|||
KUNIT_CASE(dm_test_crtc_set_vupdate_irq_no_otg),
|
||||
/* idle_create_workqueue */
|
||||
KUNIT_CASE(dm_test_idle_create_workqueue),
|
||||
/* amdgpu_dm_crtc_set_static_screen_optimze */
|
||||
KUNIT_CASE(dm_test_crtc_set_static_screen_optimze_no_sr_entry),
|
||||
/* amdgpu_dm_crtc_enable_vblank */
|
||||
KUNIT_CASE(dm_test_crtc_enable_vblank_rejects_unconfigured),
|
||||
/* amdgpu_dm_crtc_update_crtc_active_planes */
|
||||
KUNIT_CASE(dm_test_crtc_update_active_planes_no_stream),
|
||||
/* amdgpu_dm_crtc_duplicate_state */
|
||||
KUNIT_CASE(dm_test_crtc_duplicate_state_copies_fields),
|
||||
/* amdgpu_dm_crtc_reset_state */
|
||||
KUNIT_CASE(dm_test_crtc_reset_state_allocates_state),
|
||||
/* amdgpu_dm_crtc_destroy_state */
|
||||
KUNIT_CASE(dm_test_crtc_destroy_state_no_stream),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user