mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
drm/amd/display: add KUnit tests for DM atomic state helpers
[WHAT] Add KUnit tests for the DM atomic private-state accessors (dm_atomic_get_new_state, dm_atomic_destroy_state), the native cursor-mode selector (dm_should_update_native_cursor) and amdgpu_dm_smu_write_watermarks_table. Cover the empty and matching private-object lookups, the NULL-context destroy path, the NULL, native and overlay cursor-mode paths, and the non-Navi1x watermark table early return. Assisted-by: Copilot:Claude-Opus-4.8 Reviewed-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Wayne Lin <wayne.lin@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
9e5b9ead75
commit
1b3a4c2b17
|
|
@ -1404,7 +1404,7 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
|
|||
drm_connector_list_iter_end(&iter);
|
||||
}
|
||||
|
||||
static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
|
||||
STATIC_IFN_KUNIT int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -1454,6 +1454,7 @@ static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_smu_write_watermarks_table);
|
||||
|
||||
static int dm_oem_i2c_hw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
|
|
@ -2284,7 +2285,7 @@ int dm_atomic_get_state(struct drm_atomic_commit *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_atomic_state *
|
||||
STATIC_IFN_KUNIT struct dm_atomic_state *
|
||||
dm_atomic_get_new_state(struct drm_atomic_commit *state)
|
||||
{
|
||||
struct drm_device *dev = state->dev;
|
||||
|
|
@ -2301,6 +2302,7 @@ dm_atomic_get_new_state(struct drm_atomic_commit *state)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_IF_KUNIT(dm_atomic_get_new_state);
|
||||
|
||||
static struct drm_private_state *
|
||||
dm_atomic_duplicate_state(struct drm_private_obj *obj)
|
||||
|
|
@ -2326,8 +2328,8 @@ dm_atomic_duplicate_state(struct drm_private_obj *obj)
|
|||
return &new_state->base;
|
||||
}
|
||||
|
||||
static void dm_atomic_destroy_state(struct drm_private_obj *obj,
|
||||
struct drm_private_state *state)
|
||||
STATIC_IFN_KUNIT void dm_atomic_destroy_state(struct drm_private_obj *obj,
|
||||
struct drm_private_state *state)
|
||||
{
|
||||
struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
|
||||
|
||||
|
|
@ -2336,6 +2338,7 @@ static void dm_atomic_destroy_state(struct drm_private_obj *obj,
|
|||
|
||||
kfree(dm_state);
|
||||
}
|
||||
EXPORT_IF_KUNIT(dm_atomic_destroy_state);
|
||||
|
||||
static struct drm_private_state *
|
||||
dm_atomic_create_state(struct drm_private_obj *obj)
|
||||
|
|
@ -6363,10 +6366,10 @@ static int dm_check_native_cursor_state(struct drm_crtc *new_plane_crtc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool dm_should_update_native_cursor(struct drm_atomic_commit *state,
|
||||
struct drm_crtc *old_plane_crtc,
|
||||
struct drm_crtc *new_plane_crtc,
|
||||
bool enable)
|
||||
STATIC_IFN_KUNIT bool dm_should_update_native_cursor(struct drm_atomic_commit *state,
|
||||
struct drm_crtc *old_plane_crtc,
|
||||
struct drm_crtc *new_plane_crtc,
|
||||
bool enable)
|
||||
{
|
||||
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
|
||||
|
|
@ -6391,6 +6394,7 @@ static bool dm_should_update_native_cursor(struct drm_atomic_commit *state,
|
|||
return dm_new_crtc_state->cursor_mode == DM_CURSOR_NATIVE_MODE;
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(dm_should_update_native_cursor);
|
||||
|
||||
static int dm_update_plane_state(struct dc *dc,
|
||||
struct drm_atomic_commit *state,
|
||||
|
|
|
|||
|
|
@ -1152,6 +1152,14 @@ void dm_bandwidth_update(struct amdgpu_device *adev);
|
|||
u32 dm_vblank_get_counter(struct amdgpu_device *adev, int crtc);
|
||||
int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
|
||||
u32 *vbl, u32 *position);
|
||||
struct dm_atomic_state *dm_atomic_get_new_state(struct drm_atomic_commit *state);
|
||||
void dm_atomic_destroy_state(struct drm_private_obj *obj,
|
||||
struct drm_private_state *state);
|
||||
int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev);
|
||||
bool dm_should_update_native_cursor(struct drm_atomic_commit *state,
|
||||
struct drm_crtc *old_plane_crtc,
|
||||
struct drm_crtc *new_plane_crtc,
|
||||
bool enable);
|
||||
int dm_plane_layer_index_cmp(const void *a, const void *b);
|
||||
int fill_plane_color_attributes(const struct drm_plane_state *plane_state,
|
||||
const enum surface_pixel_format format,
|
||||
|
|
|
|||
|
|
@ -183,6 +183,154 @@ static void dm_test_crtc_get_scanoutpos_no_stream(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, position, 0U);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_atomic_get_new_state_empty - Test empty atomic state has no DM state
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_atomic_get_new_state_empty(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
|
||||
struct drm_atomic_commit *state;
|
||||
|
||||
state = kunit_kzalloc(test, sizeof(*state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state);
|
||||
state->dev = &adev->ddev;
|
||||
|
||||
KUNIT_EXPECT_NULL(test, dm_atomic_get_new_state(state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_atomic_get_new_state_match - Test atomic state returns matching DM private state
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_atomic_get_new_state_match(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
|
||||
struct dm_atomic_state *dm_state;
|
||||
struct drm_atomic_commit *state;
|
||||
|
||||
state = kunit_kzalloc(test, sizeof(*state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state);
|
||||
|
||||
dm_state = kunit_kzalloc(test, sizeof(*dm_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, dm_state);
|
||||
|
||||
state->private_objs = kunit_kzalloc(test, sizeof(*state->private_objs),
|
||||
GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state->private_objs);
|
||||
|
||||
state->dev = &adev->ddev;
|
||||
state->num_private_objs = 1;
|
||||
state->private_objs[0].ptr = &adev->dm.atomic_obj;
|
||||
state->private_objs[0].new_state = &dm_state->base;
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, dm_atomic_get_new_state(state), dm_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_should_update_native_cursor_without_crtc - Test NULL crtc cases update native cursor
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_should_update_native_cursor_without_crtc(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_TRUE(test, dm_should_update_native_cursor(NULL, NULL, NULL, false));
|
||||
KUNIT_EXPECT_TRUE(test, dm_should_update_native_cursor(NULL, NULL, NULL, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_should_update_native_cursor_disable_native - Test disable path reads old crtc cursor mode
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_should_update_native_cursor_disable_native(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state *dm_crtc_state;
|
||||
struct drm_atomic_commit *state;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
state = kunit_kzalloc(test, sizeof(*state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state);
|
||||
|
||||
crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, crtc);
|
||||
|
||||
dm_crtc_state = kunit_kzalloc(test, sizeof(*dm_crtc_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, dm_crtc_state);
|
||||
|
||||
state->crtcs = kunit_kzalloc(test, sizeof(*state->crtcs), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state->crtcs);
|
||||
|
||||
crtc->index = 0;
|
||||
dm_crtc_state->cursor_mode = DM_CURSOR_NATIVE_MODE;
|
||||
state->crtcs[0].old_state = &dm_crtc_state->base;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
dm_should_update_native_cursor(state, crtc, NULL, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_should_update_native_cursor_enable_overlay - Test enable path reads new crtc cursor mode
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_should_update_native_cursor_enable_overlay(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state *dm_crtc_state;
|
||||
struct drm_atomic_commit *state;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
state = kunit_kzalloc(test, sizeof(*state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state);
|
||||
|
||||
crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, crtc);
|
||||
|
||||
dm_crtc_state = kunit_kzalloc(test, sizeof(*dm_crtc_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, dm_crtc_state);
|
||||
|
||||
state->crtcs = kunit_kzalloc(test, sizeof(*state->crtcs), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state->crtcs);
|
||||
|
||||
crtc->index = 0;
|
||||
dm_crtc_state->cursor_mode = DM_CURSOR_OVERLAY_MODE;
|
||||
state->crtcs[0].new_state = &dm_crtc_state->base;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
dm_should_update_native_cursor(state, NULL, crtc, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_atomic_destroy_state_no_context - Test destroying DM atomic state without a DC context
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_atomic_destroy_state_no_context(struct kunit *test)
|
||||
{
|
||||
struct dm_atomic_state *dm_state;
|
||||
|
||||
/*
|
||||
* Use kzalloc(), not kunit_kzalloc(): dm_atomic_destroy_state() frees
|
||||
* the state itself, so KUnit-managed memory would be double-freed.
|
||||
*/
|
||||
dm_state = kzalloc(sizeof(*dm_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, dm_state);
|
||||
|
||||
/* context == NULL: dc_state_release() is skipped and the state is freed. */
|
||||
dm_atomic_destroy_state(NULL, &dm_state->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_smu_write_watermarks_table_default - Test watermarks table skips non-Navi1x IP versions
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_smu_write_watermarks_table_default(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
|
||||
|
||||
/*
|
||||
* A zeroed adev reports DCE IP version 0, which is not one of the
|
||||
* Navi1x versions handled by the switch, so the function returns early.
|
||||
*/
|
||||
KUNIT_EXPECT_EQ(test, amdgpu_dm_smu_write_watermarks_table(adev), 0);
|
||||
}
|
||||
|
||||
/* Tests for dm_plane_layer_index_cmp() */
|
||||
|
||||
/**
|
||||
|
|
@ -1069,6 +1217,13 @@ static struct kunit_case amdgpu_dm_tests[] = {
|
|||
KUNIT_CASE(dm_test_vblank_get_counter_no_stream),
|
||||
KUNIT_CASE(dm_test_crtc_get_scanoutpos_invalid_crtc),
|
||||
KUNIT_CASE(dm_test_crtc_get_scanoutpos_no_stream),
|
||||
KUNIT_CASE(dm_test_atomic_get_new_state_empty),
|
||||
KUNIT_CASE(dm_test_atomic_get_new_state_match),
|
||||
KUNIT_CASE(dm_test_should_update_native_cursor_without_crtc),
|
||||
KUNIT_CASE(dm_test_should_update_native_cursor_disable_native),
|
||||
KUNIT_CASE(dm_test_should_update_native_cursor_enable_overlay),
|
||||
KUNIT_CASE(dm_test_atomic_destroy_state_no_context),
|
||||
KUNIT_CASE(dm_test_smu_write_watermarks_table_default),
|
||||
/* dm_plane_layer_index_cmp */
|
||||
KUNIT_CASE(dm_test_plane_layer_index_cmp_equal),
|
||||
KUNIT_CASE(dm_test_plane_layer_index_cmp_descending),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user