mirror of
https://github.com/torvalds/linux.git
synced 2026-10-14 11:54:03 +02:00
drm/amd/display: Add KUnit tests for amdgpu_dm
Add KUnit tests for pure helper functions in amdgpu_dm.c. Tests cover: - dm_plane_layer_index_cmp(): equal, ascending, and descending layer_index ordering - fill_plane_color_attributes(): RGB plus BT601/BT709/BT2020 full- and limited-range YCbCr, and invalid encoding - modereset_required(): active vs inactive stream states with and without a mode change - dm_get_oriented_plane_size(): 0/90/180/270 degree rotations - dm_get_plane_scale(): identity, rotated identity, and division-by-zero guard - is_scaling_state_different(): identical state, scaling mode change, and underscan enable/border changes - is_timing_unchanged_for_freesync(): NULL args, identical modes, VRR vtotal/vsync shift, and pixel clock change - set_freesync_fixed_config(): fixed refresh-rate computation - is_dc_timing_adjust_needed(): pending hw adjust, VRR active-fixed, VRR active-state toggle, and steady state - set_multisync_trigger_params(): disabled trigger and rising/falling edge selection by vsync polarity - set_master_stream(): highest refresh-rate selection and the default-to-first-stream case 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: Chenyu Chen <chen-yu.chen@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
fcf4919cd8
commit
c26b643aa3
|
|
@ -70,6 +70,7 @@
|
|||
#include "amdgpu_dm_audio.h"
|
||||
#include "amdgpu_dm_dmub.h"
|
||||
#include "amdgpu_dm_connector.h"
|
||||
#include "amdgpu_dm_kunit_helpers.h"
|
||||
|
||||
#include "ivsrcid/ivsrcid_vislands30.h"
|
||||
|
||||
|
|
@ -146,7 +147,7 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context);
|
|||
static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
struct drm_atomic_commit *state);
|
||||
|
||||
static bool
|
||||
STATIC_IFN_KUNIT bool
|
||||
is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
|
||||
struct drm_crtc_state *new_crtc_state);
|
||||
|
||||
|
|
@ -247,8 +248,8 @@ static int dm_soft_reset(struct amdgpu_ip_block *ip_block)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state,
|
||||
struct dm_crtc_state *new_state)
|
||||
STATIC_IFN_KUNIT bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state,
|
||||
struct dm_crtc_state *new_state)
|
||||
{
|
||||
if (new_state->stream->adjust.timing_adjust_pending)
|
||||
return true;
|
||||
|
|
@ -259,13 +260,14 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state,
|
|||
else
|
||||
return false;
|
||||
}
|
||||
EXPORT_IF_KUNIT(is_dc_timing_adjust_needed);
|
||||
|
||||
/*
|
||||
* DC will program planes with their z-order determined by their ordering
|
||||
* in the dc_surface_updates array. This comparator is used to sort them
|
||||
* by descending zpos.
|
||||
*/
|
||||
static int dm_plane_layer_index_cmp(const void *a, const void *b)
|
||||
STATIC_IFN_KUNIT int dm_plane_layer_index_cmp(const void *a, const void *b)
|
||||
{
|
||||
const struct dc_surface_update *sa = (struct dc_surface_update *)a;
|
||||
const struct dc_surface_update *sb = (struct dc_surface_update *)b;
|
||||
|
|
@ -273,6 +275,7 @@ static int dm_plane_layer_index_cmp(const void *a, const void *b)
|
|||
/* Sort by descending dc_plane layer_index (i.e. normalized_zpos) */
|
||||
return sb->surface->layer_index - sa->surface->layer_index;
|
||||
}
|
||||
EXPORT_IF_KUNIT(dm_plane_layer_index_cmp);
|
||||
|
||||
/**
|
||||
* update_planes_and_stream_adapter() - Send planes to be updated in DC
|
||||
|
|
@ -2980,12 +2983,13 @@ static int dm_early_init(struct amdgpu_ip_block *ip_block)
|
|||
return dm_init_microcode(adev);
|
||||
}
|
||||
|
||||
static bool modereset_required(struct drm_crtc_state *crtc_state)
|
||||
STATIC_IFN_KUNIT bool modereset_required(struct drm_crtc_state *crtc_state)
|
||||
{
|
||||
return !crtc_state->active && drm_atomic_crtc_needs_modeset(crtc_state);
|
||||
}
|
||||
EXPORT_IF_KUNIT(modereset_required);
|
||||
|
||||
static int
|
||||
STATIC_IFN_KUNIT int
|
||||
fill_plane_color_attributes(const struct drm_plane_state *plane_state,
|
||||
const enum surface_pixel_format format,
|
||||
enum dc_color_space *color_space)
|
||||
|
|
@ -3032,6 +3036,7 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_IF_KUNIT(fill_plane_color_attributes);
|
||||
|
||||
static int
|
||||
fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
||||
|
|
@ -3600,7 +3605,7 @@ static void dm_update_pflip_irq_state(struct amdgpu_device *adev,
|
|||
amdgpu_irq_update(adev, &adev->pageflip_irq, irq_type);
|
||||
}
|
||||
|
||||
static bool
|
||||
STATIC_IFN_KUNIT bool
|
||||
is_scaling_state_different(const struct dm_connector_state *dm_state,
|
||||
const struct dm_connector_state *old_dm_state)
|
||||
{
|
||||
|
|
@ -3617,6 +3622,7 @@ is_scaling_state_different(const struct dm_connector_state *dm_state,
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
EXPORT_IF_KUNIT(is_scaling_state_different);
|
||||
|
||||
static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state,
|
||||
struct drm_crtc_state *old_crtc_state,
|
||||
|
|
@ -5079,7 +5085,7 @@ static int amdgpu_dm_atomic_setup_commit(struct drm_atomic_commit *state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void set_multisync_trigger_params(
|
||||
STATIC_IFN_KUNIT void set_multisync_trigger_params(
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
struct dc_stream_state *master = NULL;
|
||||
|
|
@ -5092,9 +5098,10 @@ static void set_multisync_trigger_params(
|
|||
stream->triggered_crtc_reset.delay = TRIGGER_DELAY_NEXT_PIXEL;
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(set_multisync_trigger_params);
|
||||
|
||||
static void set_master_stream(struct dc_stream_state *stream_set[],
|
||||
int stream_count)
|
||||
STATIC_IFN_KUNIT void set_master_stream(struct dc_stream_state *stream_set[],
|
||||
int stream_count)
|
||||
{
|
||||
int j, highest_rfr = 0, master_stream = 0;
|
||||
|
||||
|
|
@ -5115,6 +5122,7 @@ static void set_master_stream(struct dc_stream_state *stream_set[],
|
|||
stream_set[j]->triggered_crtc_reset.event_source = stream_set[master_stream];
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(set_master_stream);
|
||||
|
||||
static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context)
|
||||
{
|
||||
|
|
@ -5560,7 +5568,7 @@ static void reset_freesync_config_for_crtc(
|
|||
sizeof(new_crtc_state->vrr_infopacket));
|
||||
}
|
||||
|
||||
static bool
|
||||
STATIC_IFN_KUNIT bool
|
||||
is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
|
||||
struct drm_crtc_state *new_crtc_state)
|
||||
{
|
||||
|
|
@ -5589,8 +5597,9 @@ is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
|
|||
|
||||
return false;
|
||||
}
|
||||
EXPORT_IF_KUNIT(is_timing_unchanged_for_freesync);
|
||||
|
||||
static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state)
|
||||
STATIC_IFN_KUNIT void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state)
|
||||
{
|
||||
u64 num, den, res;
|
||||
struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base;
|
||||
|
|
@ -5604,6 +5613,7 @@ static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state)
|
|||
res = div_u64(num, den);
|
||||
dm_new_crtc_state->freesync_config.fixed_refresh_in_uhz = res;
|
||||
}
|
||||
EXPORT_IF_KUNIT(set_freesync_fixed_config);
|
||||
|
||||
static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
||||
struct drm_atomic_commit *state,
|
||||
|
|
@ -6339,8 +6349,8 @@ static int dm_update_plane_state(struct dc *dc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void dm_get_oriented_plane_size(struct drm_plane_state *plane_state,
|
||||
int *src_w, int *src_h)
|
||||
STATIC_IFN_KUNIT void dm_get_oriented_plane_size(struct drm_plane_state *plane_state,
|
||||
int *src_w, int *src_h)
|
||||
{
|
||||
switch (plane_state->rotation & DRM_MODE_ROTATE_MASK) {
|
||||
case DRM_MODE_ROTATE_90:
|
||||
|
|
@ -6356,8 +6366,9 @@ static void dm_get_oriented_plane_size(struct drm_plane_state *plane_state,
|
|||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(dm_get_oriented_plane_size);
|
||||
|
||||
static void
|
||||
STATIC_IFN_KUNIT void
|
||||
dm_get_plane_scale(struct drm_plane_state *plane_state,
|
||||
int *out_plane_scale_w, int *out_plane_scale_h)
|
||||
{
|
||||
|
|
@ -6367,6 +6378,7 @@ dm_get_plane_scale(struct drm_plane_state *plane_state,
|
|||
*out_plane_scale_w = plane_src_w ? plane_state->crtc_w * 1000 / plane_src_w : 0;
|
||||
*out_plane_scale_h = plane_src_h ? plane_state->crtc_h * 1000 / plane_src_h : 0;
|
||||
}
|
||||
EXPORT_IF_KUNIT(dm_get_plane_scale);
|
||||
|
||||
/*
|
||||
* The normalized_zpos value cannot be used by this iterator directly. It's only
|
||||
|
|
|
|||
|
|
@ -1126,4 +1126,25 @@ void amdgpu_dm_emulated_link_detect(struct dc_link *link);
|
|||
void amdgpu_dm_apply_delay_after_dpcd_poweroff(struct amdgpu_device *adev,
|
||||
struct dc_sink *sink);
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
|
||||
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,
|
||||
enum dc_color_space *color_space);
|
||||
bool modereset_required(struct drm_crtc_state *crtc_state);
|
||||
void dm_get_oriented_plane_size(struct drm_plane_state *plane_state,
|
||||
int *src_w, int *src_h);
|
||||
void dm_get_plane_scale(struct drm_plane_state *plane_state,
|
||||
int *out_plane_scale_w, int *out_plane_scale_h);
|
||||
bool is_scaling_state_different(const struct dm_connector_state *dm_state,
|
||||
const struct dm_connector_state *old_dm_state);
|
||||
bool is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
|
||||
struct drm_crtc_state *new_crtc_state);
|
||||
void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state);
|
||||
bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state,
|
||||
struct dm_crtc_state *new_state);
|
||||
void set_multisync_trigger_params(struct dc_stream_state *stream);
|
||||
void set_master_stream(struct dc_stream_state *stream_set[], int stream_count);
|
||||
#endif
|
||||
|
||||
#endif /* __AMDGPU_DM_H__ */
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#define STATIC_IFN_KUNIT
|
||||
#define INLINE_IFN_KUNIT inline
|
||||
#define EXPORT_IF_KUNIT(symbol) EXPORT_SYMBOL(symbol)
|
||||
|
||||
#else
|
||||
#define STATIC_IFN_KUNIT static
|
||||
#define INLINE_IFN_KUNIT
|
||||
|
|
|
|||
|
|
@ -20,3 +20,4 @@ obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_ism_test.o
|
|||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_wb_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_mst_types_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_pp_smu_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_test.o
|
||||
|
|
|
|||
929
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
Normal file
929
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
Normal file
|
|
@ -0,0 +1,929 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
/*
|
||||
* KUnit tests for amdgpu_dm.c
|
||||
*
|
||||
* Copyright 2026 Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
#include <kunit/test.h>
|
||||
|
||||
#include "dc.h"
|
||||
#include "amdgpu_mode.h"
|
||||
#include "amdgpu_dm.h"
|
||||
|
||||
/* Tests for dm_plane_layer_index_cmp() */
|
||||
|
||||
/**
|
||||
* dm_test_plane_layer_index_cmp_equal - Test Plane layer index cmp equal
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_plane_layer_index_cmp_equal(struct kunit *test)
|
||||
{
|
||||
struct dc_plane_state *plane_a;
|
||||
struct dc_plane_state *plane_b;
|
||||
struct dc_surface_update sa, sb;
|
||||
|
||||
plane_a = kunit_kzalloc(test, sizeof(*plane_a), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_a);
|
||||
plane_b = kunit_kzalloc(test, sizeof(*plane_b), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_b);
|
||||
|
||||
plane_a->layer_index = 5;
|
||||
plane_b->layer_index = 5;
|
||||
sa.surface = plane_a;
|
||||
sb.surface = plane_b;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, dm_plane_layer_index_cmp(&sa, &sb), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_plane_layer_index_cmp_descending - Test Plane layer index cmp descending
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_plane_layer_index_cmp_descending(struct kunit *test)
|
||||
{
|
||||
struct dc_plane_state *plane_a;
|
||||
struct dc_plane_state *plane_b;
|
||||
struct dc_surface_update sa, sb;
|
||||
|
||||
plane_a = kunit_kzalloc(test, sizeof(*plane_a), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_a);
|
||||
plane_b = kunit_kzalloc(test, sizeof(*plane_b), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_b);
|
||||
|
||||
plane_a->layer_index = 3;
|
||||
plane_b->layer_index = 7;
|
||||
sa.surface = plane_a;
|
||||
sb.surface = plane_b;
|
||||
|
||||
/* b has higher index, so cmp(a,b) = b - a > 0 (b sorts first) */
|
||||
KUNIT_EXPECT_GT(test, dm_plane_layer_index_cmp(&sa, &sb), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_plane_layer_index_cmp_ascending - Test Plane layer index cmp ascending
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_plane_layer_index_cmp_ascending(struct kunit *test)
|
||||
{
|
||||
struct dc_plane_state *plane_a;
|
||||
struct dc_plane_state *plane_b;
|
||||
struct dc_surface_update sa, sb;
|
||||
|
||||
plane_a = kunit_kzalloc(test, sizeof(*plane_a), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_a);
|
||||
plane_b = kunit_kzalloc(test, sizeof(*plane_b), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_b);
|
||||
|
||||
plane_a->layer_index = 9;
|
||||
plane_b->layer_index = 2;
|
||||
sa.surface = plane_a;
|
||||
sb.surface = plane_b;
|
||||
|
||||
/* a has higher index, so cmp(a,b) = b - a < 0 (a sorts first) */
|
||||
KUNIT_EXPECT_LT(test, dm_plane_layer_index_cmp(&sa, &sb), 0);
|
||||
}
|
||||
|
||||
/* Tests for fill_plane_color_attributes() */
|
||||
|
||||
/**
|
||||
* dm_test_fill_color_attr_rgb_format - Test Fill color attr rgb format
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_fill_color_attr_rgb_format(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
/* RGB format: should return 0 and set SRGB regardless of encoding */
|
||||
plane_state.color_encoding = DRM_COLOR_YCBCR_BT709;
|
||||
plane_state.color_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
|
||||
ret = fill_plane_color_attributes(&plane_state,
|
||||
SURFACE_PIXEL_FORMAT_GRPH_ARGB8888,
|
||||
&color_space);
|
||||
KUNIT_EXPECT_EQ(test, ret, 0);
|
||||
KUNIT_EXPECT_EQ(test, (int)color_space, (int)COLOR_SPACE_SRGB);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_fill_color_attr_bt601_full - Test Fill color attr bt601 full
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_fill_color_attr_bt601_full(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
plane_state.color_encoding = DRM_COLOR_YCBCR_BT601;
|
||||
plane_state.color_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
|
||||
ret = fill_plane_color_attributes(&plane_state,
|
||||
SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr,
|
||||
&color_space);
|
||||
KUNIT_EXPECT_EQ(test, ret, 0);
|
||||
KUNIT_EXPECT_EQ(test, (int)color_space, (int)COLOR_SPACE_YCBCR601);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_fill_color_attr_bt601_limited - Test Fill color attr bt601 limited
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_fill_color_attr_bt601_limited(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
plane_state.color_encoding = DRM_COLOR_YCBCR_BT601;
|
||||
plane_state.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
|
||||
|
||||
ret = fill_plane_color_attributes(&plane_state,
|
||||
SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr,
|
||||
&color_space);
|
||||
KUNIT_EXPECT_EQ(test, ret, 0);
|
||||
KUNIT_EXPECT_EQ(test, (int)color_space,
|
||||
(int)COLOR_SPACE_YCBCR601_LIMITED);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_fill_color_attr_bt709_full - Test Fill color attr bt709 full
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_fill_color_attr_bt709_full(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
plane_state.color_encoding = DRM_COLOR_YCBCR_BT709;
|
||||
plane_state.color_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
|
||||
ret = fill_plane_color_attributes(&plane_state,
|
||||
SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr,
|
||||
&color_space);
|
||||
KUNIT_EXPECT_EQ(test, ret, 0);
|
||||
KUNIT_EXPECT_EQ(test, (int)color_space, (int)COLOR_SPACE_YCBCR709);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_fill_color_attr_bt709_limited - Test Fill color attr bt709 limited
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_fill_color_attr_bt709_limited(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
plane_state.color_encoding = DRM_COLOR_YCBCR_BT709;
|
||||
plane_state.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
|
||||
|
||||
ret = fill_plane_color_attributes(&plane_state,
|
||||
SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr,
|
||||
&color_space);
|
||||
KUNIT_EXPECT_EQ(test, ret, 0);
|
||||
KUNIT_EXPECT_EQ(test, (int)color_space,
|
||||
(int)COLOR_SPACE_YCBCR709_LIMITED);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_fill_color_attr_bt2020_full - Test Fill color attr bt2020 full
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_fill_color_attr_bt2020_full(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
plane_state.color_encoding = DRM_COLOR_YCBCR_BT2020;
|
||||
plane_state.color_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
|
||||
ret = fill_plane_color_attributes(&plane_state,
|
||||
SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr,
|
||||
&color_space);
|
||||
KUNIT_EXPECT_EQ(test, ret, 0);
|
||||
KUNIT_EXPECT_EQ(test, (int)color_space,
|
||||
(int)COLOR_SPACE_2020_YCBCR_FULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_fill_color_attr_bt2020_limited - Test Fill color attr bt2020 limited
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_fill_color_attr_bt2020_limited(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
plane_state.color_encoding = DRM_COLOR_YCBCR_BT2020;
|
||||
plane_state.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
|
||||
|
||||
ret = fill_plane_color_attributes(&plane_state,
|
||||
SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr,
|
||||
&color_space);
|
||||
KUNIT_EXPECT_EQ(test, ret, 0);
|
||||
KUNIT_EXPECT_EQ(test, (int)color_space,
|
||||
(int)COLOR_SPACE_2020_YCBCR_LIMITED);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_fill_color_attr_invalid_encoding - Test Fill color attr invalid encoding
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_fill_color_attr_invalid_encoding(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
plane_state.color_encoding = 99;
|
||||
plane_state.color_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
|
||||
ret = fill_plane_color_attributes(&plane_state,
|
||||
SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr,
|
||||
&color_space);
|
||||
KUNIT_EXPECT_EQ(test, ret, -EINVAL);
|
||||
}
|
||||
|
||||
/* Tests for modereset_required() */
|
||||
|
||||
/**
|
||||
* dm_test_modereset_required_when_inactive_and_modeset - Test Modereset required when inactive and modeset
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_modereset_required_when_inactive_and_modeset(struct kunit *test)
|
||||
{
|
||||
struct drm_crtc_state crtc_state = { 0 };
|
||||
|
||||
crtc_state.active = false;
|
||||
crtc_state.mode_changed = true;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, modereset_required(&crtc_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_modereset_not_required_when_active_and_modeset - Test Modereset not required when active and modeset
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_modereset_not_required_when_active_and_modeset(struct kunit *test)
|
||||
{
|
||||
struct drm_crtc_state crtc_state = { 0 };
|
||||
|
||||
crtc_state.active = true;
|
||||
crtc_state.mode_changed = true;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, modereset_required(&crtc_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_modereset_not_required_when_inactive_without_modeset - Test Modereset not required when inactive without modeset
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_modereset_not_required_when_inactive_without_modeset(struct kunit *test)
|
||||
{
|
||||
struct drm_crtc_state crtc_state = { 0 };
|
||||
|
||||
crtc_state.active = false;
|
||||
crtc_state.mode_changed = false;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, modereset_required(&crtc_state));
|
||||
}
|
||||
|
||||
/* Tests for dm_get_oriented_plane_size() */
|
||||
|
||||
/**
|
||||
* dm_test_oriented_plane_size_rotate_0 - Test Oriented plane size rotate 0
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_oriented_plane_size_rotate_0(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
int src_w = 0;
|
||||
int src_h = 0;
|
||||
|
||||
plane_state.rotation = DRM_MODE_ROTATE_0;
|
||||
plane_state.src_w = 1920 << 16;
|
||||
plane_state.src_h = 1080 << 16;
|
||||
|
||||
dm_get_oriented_plane_size(&plane_state, &src_w, &src_h);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, src_w, 1920);
|
||||
KUNIT_EXPECT_EQ(test, src_h, 1080);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_oriented_plane_size_rotate_90 - Test Oriented plane size rotate 90
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_oriented_plane_size_rotate_90(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
int src_w = 0;
|
||||
int src_h = 0;
|
||||
|
||||
plane_state.rotation = DRM_MODE_ROTATE_90;
|
||||
plane_state.src_w = 1920 << 16;
|
||||
plane_state.src_h = 1080 << 16;
|
||||
|
||||
dm_get_oriented_plane_size(&plane_state, &src_w, &src_h);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, src_w, 1080);
|
||||
KUNIT_EXPECT_EQ(test, src_h, 1920);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_oriented_plane_size_rotate_180 - Test Oriented plane size rotate 180
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_oriented_plane_size_rotate_180(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
int src_w = 0;
|
||||
int src_h = 0;
|
||||
|
||||
plane_state.rotation = DRM_MODE_ROTATE_180;
|
||||
plane_state.src_w = 1920 << 16;
|
||||
plane_state.src_h = 1080 << 16;
|
||||
|
||||
dm_get_oriented_plane_size(&plane_state, &src_w, &src_h);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, src_w, 1920);
|
||||
KUNIT_EXPECT_EQ(test, src_h, 1080);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_oriented_plane_size_rotate_270 - Test Oriented plane size rotate 270
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_oriented_plane_size_rotate_270(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
int src_w = 0;
|
||||
int src_h = 0;
|
||||
|
||||
plane_state.rotation = DRM_MODE_ROTATE_270;
|
||||
plane_state.src_w = 1920 << 16;
|
||||
plane_state.src_h = 1080 << 16;
|
||||
|
||||
dm_get_oriented_plane_size(&plane_state, &src_w, &src_h);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, src_w, 1080);
|
||||
KUNIT_EXPECT_EQ(test, src_h, 1920);
|
||||
}
|
||||
|
||||
/* Tests for dm_get_plane_scale() */
|
||||
|
||||
/**
|
||||
* dm_test_get_plane_scale_identity - Test Get plane scale identity
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_get_plane_scale_identity(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
int scale_w = 0;
|
||||
int scale_h = 0;
|
||||
|
||||
plane_state.rotation = DRM_MODE_ROTATE_0;
|
||||
plane_state.src_w = 1920 << 16;
|
||||
plane_state.src_h = 1080 << 16;
|
||||
plane_state.crtc_w = 1920;
|
||||
plane_state.crtc_h = 1080;
|
||||
|
||||
dm_get_plane_scale(&plane_state, &scale_w, &scale_h);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, scale_w, 1000);
|
||||
KUNIT_EXPECT_EQ(test, scale_h, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_get_plane_scale_rotate_90_identity - Test Get plane scale rotate 90 identity
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_get_plane_scale_rotate_90_identity(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
int scale_w = 0;
|
||||
int scale_h = 0;
|
||||
|
||||
plane_state.rotation = DRM_MODE_ROTATE_90;
|
||||
plane_state.src_w = 1920 << 16;
|
||||
plane_state.src_h = 1080 << 16;
|
||||
plane_state.crtc_w = 1080;
|
||||
plane_state.crtc_h = 1920;
|
||||
|
||||
dm_get_plane_scale(&plane_state, &scale_w, &scale_h);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, scale_w, 1000);
|
||||
KUNIT_EXPECT_EQ(test, scale_h, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_get_plane_scale_zero_src_width - Test Get plane scale zero src width
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_get_plane_scale_zero_src_width(struct kunit *test)
|
||||
{
|
||||
struct drm_plane_state plane_state = { 0 };
|
||||
int scale_w = 0;
|
||||
int scale_h = 0;
|
||||
|
||||
plane_state.rotation = DRM_MODE_ROTATE_0;
|
||||
plane_state.src_w = 0;
|
||||
plane_state.src_h = 1080 << 16;
|
||||
plane_state.crtc_w = 100;
|
||||
plane_state.crtc_h = 200;
|
||||
|
||||
dm_get_plane_scale(&plane_state, &scale_w, &scale_h);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, scale_w, 0);
|
||||
KUNIT_EXPECT_EQ(test, scale_h, 185);
|
||||
}
|
||||
|
||||
/* Tests for is_scaling_state_different() */
|
||||
|
||||
/**
|
||||
* dm_test_scaling_state_same - Test identical scaling states compare equal
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_scaling_state_same(struct kunit *test)
|
||||
{
|
||||
struct dm_connector_state a = { 0 };
|
||||
struct dm_connector_state b = { 0 };
|
||||
|
||||
a.scaling = RMX_FULL;
|
||||
a.underscan_enable = false;
|
||||
b = a;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, is_scaling_state_different(&a, &b));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_scaling_state_scaling_changed - Test differing scaling mode is detected
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_scaling_state_scaling_changed(struct kunit *test)
|
||||
{
|
||||
struct dm_connector_state a = { 0 };
|
||||
struct dm_connector_state b = { 0 };
|
||||
|
||||
a.scaling = RMX_FULL;
|
||||
b.scaling = RMX_CENTER;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, is_scaling_state_different(&a, &b));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_scaling_state_underscan_enabled - Test enabling underscan with borders differs
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_scaling_state_underscan_enabled(struct kunit *test)
|
||||
{
|
||||
struct dm_connector_state old_state = { 0 };
|
||||
struct dm_connector_state new_state = { 0 };
|
||||
|
||||
/* new enables underscan with non-zero borders, old has it disabled */
|
||||
new_state.underscan_enable = true;
|
||||
new_state.underscan_hborder = 16;
|
||||
new_state.underscan_vborder = 16;
|
||||
old_state.underscan_enable = false;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, is_scaling_state_different(&new_state, &old_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_scaling_state_underscan_border_changed - Test changed underscan borders differ
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_scaling_state_underscan_border_changed(struct kunit *test)
|
||||
{
|
||||
struct dm_connector_state a = { 0 };
|
||||
struct dm_connector_state b = { 0 };
|
||||
|
||||
a.underscan_enable = true;
|
||||
a.underscan_hborder = 16;
|
||||
a.underscan_vborder = 16;
|
||||
b = a;
|
||||
b.underscan_hborder = 32;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, is_scaling_state_different(&a, &b));
|
||||
}
|
||||
|
||||
/* Tests for is_timing_unchanged_for_freesync() */
|
||||
|
||||
/**
|
||||
* dm_test_timing_unchanged_null_args - Test NULL crtc states return false
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_timing_unchanged_null_args(struct kunit *test)
|
||||
{
|
||||
struct drm_crtc_state crtc_state = { 0 };
|
||||
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
is_timing_unchanged_for_freesync(NULL, &crtc_state));
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
is_timing_unchanged_for_freesync(&crtc_state, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_timing_unchanged_identical_modes - Test identical modes are not "unchanged"
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* The helper only returns true when vtotal/vsync shift (vrr) while the rest
|
||||
* of the timing stays fixed, so identical modes must return false.
|
||||
*/
|
||||
static void dm_test_timing_unchanged_identical_modes(struct kunit *test)
|
||||
{
|
||||
struct drm_crtc_state old_state = { 0 };
|
||||
struct drm_crtc_state new_state = { 0 };
|
||||
|
||||
old_state.mode.clock = 148500;
|
||||
old_state.mode.hdisplay = 1920;
|
||||
old_state.mode.vdisplay = 1080;
|
||||
old_state.mode.htotal = 2200;
|
||||
old_state.mode.vtotal = 1125;
|
||||
new_state.mode = old_state.mode;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
is_timing_unchanged_for_freesync(&old_state, &new_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_timing_unchanged_vrr_shift - Test vrr-style vtotal/vsync shift is detected
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_timing_unchanged_vrr_shift(struct kunit *test)
|
||||
{
|
||||
struct drm_crtc_state old_state = { 0 };
|
||||
struct drm_crtc_state new_state = { 0 };
|
||||
|
||||
old_state.mode.clock = 148500;
|
||||
old_state.mode.hdisplay = 1920;
|
||||
old_state.mode.vdisplay = 1080;
|
||||
old_state.mode.htotal = 2200;
|
||||
old_state.mode.vtotal = 1125;
|
||||
old_state.mode.hsync_start = 2008;
|
||||
old_state.mode.vsync_start = 1084;
|
||||
old_state.mode.hsync_end = 2052;
|
||||
old_state.mode.vsync_end = 1089;
|
||||
|
||||
/* Same horizontal timing, vertical totals/sync shifted by 125 lines */
|
||||
new_state.mode = old_state.mode;
|
||||
new_state.mode.vtotal = 1250;
|
||||
new_state.mode.vsync_start = 1209;
|
||||
new_state.mode.vsync_end = 1214;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
is_timing_unchanged_for_freesync(&old_state, &new_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_timing_unchanged_clock_changed - Test pixel clock change returns false
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_timing_unchanged_clock_changed(struct kunit *test)
|
||||
{
|
||||
struct drm_crtc_state old_state = { 0 };
|
||||
struct drm_crtc_state new_state = { 0 };
|
||||
|
||||
old_state.mode.clock = 148500;
|
||||
old_state.mode.htotal = 2200;
|
||||
old_state.mode.vtotal = 1125;
|
||||
old_state.mode.vsync_start = 1084;
|
||||
old_state.mode.vsync_end = 1089;
|
||||
|
||||
new_state.mode = old_state.mode;
|
||||
new_state.mode.clock = 297000;
|
||||
new_state.mode.vtotal = 1250;
|
||||
new_state.mode.vsync_start = 1209;
|
||||
new_state.mode.vsync_end = 1214;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
is_timing_unchanged_for_freesync(&old_state, &new_state));
|
||||
}
|
||||
|
||||
/* Tests for set_freesync_fixed_config() */
|
||||
|
||||
/**
|
||||
* dm_test_set_freesync_fixed_config_60hz - Test fixed refresh computed for 1080p60
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_set_freesync_fixed_config_60hz(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state dm_crtc_state = { 0 };
|
||||
|
||||
dm_crtc_state.base.mode.clock = 148500;
|
||||
dm_crtc_state.base.mode.htotal = 2200;
|
||||
dm_crtc_state.base.mode.vtotal = 1125;
|
||||
|
||||
set_freesync_fixed_config(&dm_crtc_state);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)dm_crtc_state.freesync_config.state,
|
||||
(int)VRR_STATE_ACTIVE_FIXED);
|
||||
/* 148500 kHz / (2200 * 1125) = 60 Hz = 60000000 uHz */
|
||||
KUNIT_EXPECT_EQ(test, dm_crtc_state.freesync_config.fixed_refresh_in_uhz,
|
||||
60000000U);
|
||||
}
|
||||
|
||||
/* Tests for is_dc_timing_adjust_needed() */
|
||||
|
||||
/**
|
||||
* dm_test_dc_timing_adjust_pending - Test a pending hw timing adjust forces true
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_dc_timing_adjust_pending(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state *old_state, *new_state;
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
old_state = kunit_kzalloc(test, sizeof(*old_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_state);
|
||||
new_state = kunit_kzalloc(test, sizeof(*new_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_state);
|
||||
stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
|
||||
|
||||
new_state->stream = stream;
|
||||
stream->adjust.timing_adjust_pending = 1;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, is_dc_timing_adjust_needed(old_state, new_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_dc_timing_adjust_active_fixed - Test VRR active-fixed forces true
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_dc_timing_adjust_active_fixed(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state *old_state, *new_state;
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
old_state = kunit_kzalloc(test, sizeof(*old_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_state);
|
||||
new_state = kunit_kzalloc(test, sizeof(*new_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_state);
|
||||
stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
|
||||
|
||||
new_state->stream = stream;
|
||||
new_state->freesync_config.state = VRR_STATE_ACTIVE_FIXED;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, is_dc_timing_adjust_needed(old_state, new_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_dc_timing_adjust_vrr_toggle - Test a change in vrr active state forces true
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_dc_timing_adjust_vrr_toggle(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state *old_state, *new_state;
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
old_state = kunit_kzalloc(test, sizeof(*old_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_state);
|
||||
new_state = kunit_kzalloc(test, sizeof(*new_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_state);
|
||||
stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
|
||||
|
||||
new_state->stream = stream;
|
||||
old_state->freesync_config.state = VRR_STATE_ACTIVE_VARIABLE;
|
||||
new_state->freesync_config.state = VRR_STATE_INACTIVE;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, is_dc_timing_adjust_needed(old_state, new_state));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_dc_timing_adjust_not_needed - Test steady-state timing needs no adjust
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_dc_timing_adjust_not_needed(struct kunit *test)
|
||||
{
|
||||
struct dm_crtc_state *old_state, *new_state;
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
old_state = kunit_kzalloc(test, sizeof(*old_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_state);
|
||||
new_state = kunit_kzalloc(test, sizeof(*new_state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_state);
|
||||
stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
|
||||
|
||||
new_state->stream = stream;
|
||||
old_state->freesync_config.state = VRR_STATE_INACTIVE;
|
||||
new_state->freesync_config.state = VRR_STATE_INACTIVE;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, is_dc_timing_adjust_needed(old_state, new_state));
|
||||
}
|
||||
|
||||
/* Tests for set_multisync_trigger_params() */
|
||||
|
||||
/**
|
||||
* dm_test_multisync_trigger_disabled - Test disabled reset leaves params untouched
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_multisync_trigger_disabled(struct kunit *test)
|
||||
{
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
|
||||
|
||||
stream->triggered_crtc_reset.enabled = false;
|
||||
stream->triggered_crtc_reset.event = CRTC_EVENT_VSYNC_FALLING;
|
||||
stream->triggered_crtc_reset.delay = TRIGGER_DELAY_NEXT_LINE;
|
||||
|
||||
set_multisync_trigger_params(stream);
|
||||
|
||||
/* Nothing should change when the reset trigger is disabled */
|
||||
KUNIT_EXPECT_EQ(test, (int)stream->triggered_crtc_reset.event,
|
||||
(int)CRTC_EVENT_VSYNC_FALLING);
|
||||
KUNIT_EXPECT_EQ(test, (int)stream->triggered_crtc_reset.delay,
|
||||
(int)TRIGGER_DELAY_NEXT_LINE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_multisync_trigger_rising - Test positive vsync polarity selects rising edge
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_multisync_trigger_rising(struct kunit *test)
|
||||
{
|
||||
struct dc_stream_state *stream;
|
||||
struct dc_stream_state *master;
|
||||
|
||||
stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
|
||||
master = kunit_kzalloc(test, sizeof(*master), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, master);
|
||||
|
||||
master->timing.flags.VSYNC_POSITIVE_POLARITY = 1;
|
||||
stream->triggered_crtc_reset.enabled = true;
|
||||
stream->triggered_crtc_reset.event_source = master;
|
||||
|
||||
set_multisync_trigger_params(stream);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)stream->triggered_crtc_reset.event,
|
||||
(int)CRTC_EVENT_VSYNC_RISING);
|
||||
KUNIT_EXPECT_EQ(test, (int)stream->triggered_crtc_reset.delay,
|
||||
(int)TRIGGER_DELAY_NEXT_PIXEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_multisync_trigger_falling - Test negative vsync polarity selects falling edge
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_multisync_trigger_falling(struct kunit *test)
|
||||
{
|
||||
struct dc_stream_state *stream;
|
||||
struct dc_stream_state *master;
|
||||
|
||||
stream = kunit_kzalloc(test, sizeof(*stream), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
|
||||
master = kunit_kzalloc(test, sizeof(*master), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, master);
|
||||
|
||||
master->timing.flags.VSYNC_POSITIVE_POLARITY = 0;
|
||||
stream->triggered_crtc_reset.enabled = true;
|
||||
stream->triggered_crtc_reset.event_source = master;
|
||||
|
||||
set_multisync_trigger_params(stream);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)stream->triggered_crtc_reset.event,
|
||||
(int)CRTC_EVENT_VSYNC_FALLING);
|
||||
KUNIT_EXPECT_EQ(test, (int)stream->triggered_crtc_reset.delay,
|
||||
(int)TRIGGER_DELAY_NEXT_PIXEL);
|
||||
}
|
||||
|
||||
/* Tests for set_master_stream() */
|
||||
|
||||
/**
|
||||
* dm_test_master_stream_highest_refresh - Test highest refresh-rate stream becomes master
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_master_stream_highest_refresh(struct kunit *test)
|
||||
{
|
||||
struct dc_stream_state *stream0, *stream1;
|
||||
struct dc_stream_state *stream_set[2];
|
||||
|
||||
stream0 = kunit_kzalloc(test, sizeof(*stream0), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream0);
|
||||
stream1 = kunit_kzalloc(test, sizeof(*stream1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream1);
|
||||
stream_set[0] = stream0;
|
||||
stream_set[1] = stream1;
|
||||
|
||||
/* stream0: 60Hz, stream1: 120Hz -> stream1 is master */
|
||||
stream0->triggered_crtc_reset.enabled = true;
|
||||
stream0->timing.pix_clk_100hz = 1485000;
|
||||
stream0->timing.h_total = 2200;
|
||||
stream0->timing.v_total = 1125;
|
||||
|
||||
stream1->triggered_crtc_reset.enabled = true;
|
||||
stream1->timing.pix_clk_100hz = 2970000;
|
||||
stream1->timing.h_total = 2200;
|
||||
stream1->timing.v_total = 1125;
|
||||
|
||||
set_master_stream(stream_set, 2);
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, stream0->triggered_crtc_reset.event_source,
|
||||
stream1);
|
||||
KUNIT_EXPECT_PTR_EQ(test, stream1->triggered_crtc_reset.event_source,
|
||||
stream1);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_master_stream_defaults_to_first - Test default master when none triggered
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* When no stream has the reset trigger enabled, master_stream stays 0 and all
|
||||
* streams point at the first stream as their event source.
|
||||
*/
|
||||
static void dm_test_master_stream_defaults_to_first(struct kunit *test)
|
||||
{
|
||||
struct dc_stream_state *stream0, *stream1;
|
||||
struct dc_stream_state *stream_set[2];
|
||||
|
||||
stream0 = kunit_kzalloc(test, sizeof(*stream0), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream0);
|
||||
stream1 = kunit_kzalloc(test, sizeof(*stream1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream1);
|
||||
stream_set[0] = stream0;
|
||||
stream_set[1] = stream1;
|
||||
|
||||
set_master_stream(stream_set, 2);
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, stream0->triggered_crtc_reset.event_source,
|
||||
stream0);
|
||||
KUNIT_EXPECT_PTR_EQ(test, stream1->triggered_crtc_reset.event_source,
|
||||
stream0);
|
||||
}
|
||||
|
||||
static struct kunit_case amdgpu_dm_tests[] = {
|
||||
/* dm_plane_layer_index_cmp */
|
||||
KUNIT_CASE(dm_test_plane_layer_index_cmp_equal),
|
||||
KUNIT_CASE(dm_test_plane_layer_index_cmp_descending),
|
||||
KUNIT_CASE(dm_test_plane_layer_index_cmp_ascending),
|
||||
/* fill_plane_color_attributes */
|
||||
KUNIT_CASE(dm_test_fill_color_attr_rgb_format),
|
||||
KUNIT_CASE(dm_test_fill_color_attr_bt601_full),
|
||||
KUNIT_CASE(dm_test_fill_color_attr_bt601_limited),
|
||||
KUNIT_CASE(dm_test_fill_color_attr_bt709_full),
|
||||
KUNIT_CASE(dm_test_fill_color_attr_bt709_limited),
|
||||
KUNIT_CASE(dm_test_fill_color_attr_bt2020_full),
|
||||
KUNIT_CASE(dm_test_fill_color_attr_bt2020_limited),
|
||||
KUNIT_CASE(dm_test_fill_color_attr_invalid_encoding),
|
||||
/* modereset_required */
|
||||
KUNIT_CASE(dm_test_modereset_required_when_inactive_and_modeset),
|
||||
KUNIT_CASE(dm_test_modereset_not_required_when_active_and_modeset),
|
||||
KUNIT_CASE(dm_test_modereset_not_required_when_inactive_without_modeset),
|
||||
/* dm_get_oriented_plane_size */
|
||||
KUNIT_CASE(dm_test_oriented_plane_size_rotate_0),
|
||||
KUNIT_CASE(dm_test_oriented_plane_size_rotate_90),
|
||||
KUNIT_CASE(dm_test_oriented_plane_size_rotate_180),
|
||||
KUNIT_CASE(dm_test_oriented_plane_size_rotate_270),
|
||||
/* dm_get_plane_scale */
|
||||
KUNIT_CASE(dm_test_get_plane_scale_identity),
|
||||
KUNIT_CASE(dm_test_get_plane_scale_rotate_90_identity),
|
||||
KUNIT_CASE(dm_test_get_plane_scale_zero_src_width),
|
||||
/* is_scaling_state_different */
|
||||
KUNIT_CASE(dm_test_scaling_state_same),
|
||||
KUNIT_CASE(dm_test_scaling_state_scaling_changed),
|
||||
KUNIT_CASE(dm_test_scaling_state_underscan_enabled),
|
||||
KUNIT_CASE(dm_test_scaling_state_underscan_border_changed),
|
||||
/* is_timing_unchanged_for_freesync */
|
||||
KUNIT_CASE(dm_test_timing_unchanged_null_args),
|
||||
KUNIT_CASE(dm_test_timing_unchanged_identical_modes),
|
||||
KUNIT_CASE(dm_test_timing_unchanged_vrr_shift),
|
||||
KUNIT_CASE(dm_test_timing_unchanged_clock_changed),
|
||||
/* set_freesync_fixed_config */
|
||||
KUNIT_CASE(dm_test_set_freesync_fixed_config_60hz),
|
||||
/* is_dc_timing_adjust_needed */
|
||||
KUNIT_CASE(dm_test_dc_timing_adjust_pending),
|
||||
KUNIT_CASE(dm_test_dc_timing_adjust_active_fixed),
|
||||
KUNIT_CASE(dm_test_dc_timing_adjust_vrr_toggle),
|
||||
KUNIT_CASE(dm_test_dc_timing_adjust_not_needed),
|
||||
/* set_multisync_trigger_params */
|
||||
KUNIT_CASE(dm_test_multisync_trigger_disabled),
|
||||
KUNIT_CASE(dm_test_multisync_trigger_rising),
|
||||
KUNIT_CASE(dm_test_multisync_trigger_falling),
|
||||
/* set_master_stream */
|
||||
KUNIT_CASE(dm_test_master_stream_highest_refresh),
|
||||
KUNIT_CASE(dm_test_master_stream_defaults_to_first),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite amdgpu_dm_test_suite = {
|
||||
.name = "amdgpu_dm",
|
||||
.test_cases = amdgpu_dm_tests,
|
||||
};
|
||||
|
||||
kunit_test_suite(amdgpu_dm_test_suite);
|
||||
|
||||
MODULE_AUTHOR("AMD");
|
||||
MODULE_DESCRIPTION("KUnit tests for amdgpu_dm");
|
||||
MODULE_LICENSE("Dual MIT/GPL");
|
||||
Loading…
Reference in New Issue
Block a user