mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 09:20:13 -04:00
drm/amd/display: Add EDID management tests for connector
Add KUnit coverage for hdmi_cec_unset_edid(), create_eml_sink() and handle_edid_mgmt(): unset edid with no notifier, eml sink with no edid, and DP vs non-DP edid management link caps handling. 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: 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:
committed by
Alex Deucher
parent
1f235b05f6
commit
27be8a5159
@@ -334,7 +334,7 @@ int amdgpu_dm_detect_mst_link_for_all_connectors(struct drm_device *dev)
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_detect_mst_link_for_all_connectors);
|
||||
|
||||
static void hdmi_cec_unset_edid(struct amdgpu_dm_connector *aconnector)
|
||||
STATIC_IFN_KUNIT void hdmi_cec_unset_edid(struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
struct cec_notifier *n = aconnector->notifier;
|
||||
|
||||
@@ -343,6 +343,7 @@ static void hdmi_cec_unset_edid(struct amdgpu_dm_connector *aconnector)
|
||||
|
||||
cec_notifier_phys_addr_invalidate(n);
|
||||
}
|
||||
EXPORT_IF_KUNIT(hdmi_cec_unset_edid);
|
||||
|
||||
void amdgpu_dm_hdmi_cec_set_edid(struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
@@ -2007,7 +2008,7 @@ static int get_modes(struct drm_connector *connector)
|
||||
return amdgpu_dm_connector_get_modes(connector);
|
||||
}
|
||||
|
||||
static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
|
||||
STATIC_IFN_KUNIT void create_eml_sink(struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
struct drm_connector *connector = &aconnector->base;
|
||||
struct dc_link *dc_link = aconnector->dc_link;
|
||||
@@ -2052,8 +2053,9 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
|
||||
dc_sink_retain(aconnector->dc_sink);
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(create_eml_sink);
|
||||
|
||||
static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
|
||||
STATIC_IFN_KUNIT void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
struct dc_link *link = (struct dc_link *)aconnector->dc_link;
|
||||
|
||||
@@ -2068,6 +2070,7 @@ static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
|
||||
|
||||
create_eml_sink(aconnector);
|
||||
}
|
||||
EXPORT_IF_KUNIT(handle_edid_mgmt);
|
||||
|
||||
static enum dc_status dm_validate_stream_and_context(struct dc *dc,
|
||||
struct dc_stream_state *stream)
|
||||
|
||||
@@ -146,6 +146,9 @@ int amdgpu_dm_encoder_init(struct drm_device *dev,
|
||||
uint32_t link_index);
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
|
||||
void hdmi_cec_unset_edid(struct amdgpu_dm_connector *aconnector);
|
||||
void create_eml_sink(struct amdgpu_dm_connector *aconnector);
|
||||
void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector);
|
||||
void dm_encoder_helper_disable(struct drm_encoder *encoder);
|
||||
int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
|
||||
@@ -4267,6 +4267,118 @@ static void dm_test_atomic_check_non_mst_returns_zero(struct kunit *test)
|
||||
&ctx->dm_state->base), 0);
|
||||
}
|
||||
|
||||
/* Tests for hdmi_cec_unset_edid() */
|
||||
|
||||
/**
|
||||
* dm_test_hdmi_cec_unset_edid_no_notifier - Test the no-notifier no-op path
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* With aconnector->notifier NULL the function returns early and must not crash.
|
||||
*/
|
||||
static void dm_test_hdmi_cec_unset_edid_no_notifier(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
|
||||
aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, aconnector);
|
||||
|
||||
hdmi_cec_unset_edid(aconnector);
|
||||
}
|
||||
|
||||
/* Tests for create_eml_sink() and handle_edid_mgmt() */
|
||||
|
||||
/*
|
||||
* create_eml_sink() reads EDID off the connector's DDC. Forcing the connector
|
||||
* DRM_FORCE_OFF makes drm_edid_read_ddc() return NULL before touching any i2c
|
||||
* adapter, exercising the "no EDID" branch without real hardware. aux_mode is
|
||||
* set so the embedded DP AUX ddc is selected (no i2c adapter pointer needed).
|
||||
*/
|
||||
struct dm_test_edid_ctx {
|
||||
struct drm_device *drm;
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
struct dc_link *link;
|
||||
};
|
||||
|
||||
static struct dm_test_edid_ctx *
|
||||
dm_test_edid_ctx_alloc(struct kunit *test, int connector_type)
|
||||
{
|
||||
struct dm_test_edid_ctx *ctx;
|
||||
|
||||
ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, ctx);
|
||||
|
||||
ctx->drm = dm_test_alloc_drm(test);
|
||||
ctx->aconnector = dm_test_add_connector(test, ctx->drm, connector_type);
|
||||
|
||||
ctx->link = kunit_kzalloc(test, sizeof(*ctx->link), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, ctx->link);
|
||||
ctx->link->aux_mode = true;
|
||||
ctx->aconnector->dc_link = ctx->link;
|
||||
|
||||
ctx->aconnector->base.force = DRM_FORCE_OFF;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_create_eml_sink_no_edid - Test the no-EDID branch creates no sink
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* When no EDID can be read the function logs an error and returns without
|
||||
* allocating an emulated sink.
|
||||
*/
|
||||
static void dm_test_create_eml_sink_no_edid(struct kunit *test)
|
||||
{
|
||||
struct dm_test_edid_ctx *ctx =
|
||||
dm_test_edid_ctx_alloc(test, DRM_MODE_CONNECTOR_DisplayPort);
|
||||
|
||||
create_eml_sink(ctx->aconnector);
|
||||
|
||||
KUNIT_EXPECT_NULL(test, ctx->aconnector->dc_em_sink);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_handle_edid_mgmt_dp_sets_link_caps - Test DP seeds verified link caps
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* For a DisplayPort link the function primes verified_link_cap before reading
|
||||
* EDID so a headless force-on connector can still modeset.
|
||||
*/
|
||||
static void dm_test_handle_edid_mgmt_dp_sets_link_caps(struct kunit *test)
|
||||
{
|
||||
struct dm_test_edid_ctx *ctx =
|
||||
dm_test_edid_ctx_alloc(test, DRM_MODE_CONNECTOR_DisplayPort);
|
||||
|
||||
ctx->link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
|
||||
|
||||
handle_edid_mgmt(ctx->aconnector);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)ctx->link->verified_link_cap.lane_count,
|
||||
(int)LANE_COUNT_FOUR);
|
||||
KUNIT_EXPECT_EQ(test, (int)ctx->link->verified_link_cap.link_rate,
|
||||
(int)LINK_RATE_HIGH2);
|
||||
KUNIT_EXPECT_NULL(test, ctx->aconnector->dc_em_sink);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_handle_edid_mgmt_non_dp_leaves_caps - Test non-DP links keep zeroed caps
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* A non-DisplayPort link skips the verified_link_cap seeding entirely.
|
||||
*/
|
||||
static void dm_test_handle_edid_mgmt_non_dp_leaves_caps(struct kunit *test)
|
||||
{
|
||||
struct dm_test_edid_ctx *ctx =
|
||||
dm_test_edid_ctx_alloc(test, DRM_MODE_CONNECTOR_HDMIA);
|
||||
|
||||
ctx->link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
|
||||
handle_edid_mgmt(ctx->aconnector);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, (int)ctx->link->verified_link_cap.lane_count, 0);
|
||||
KUNIT_EXPECT_EQ(test, (int)ctx->link->verified_link_cap.link_rate, 0);
|
||||
}
|
||||
|
||||
static struct kunit_case amdgpu_dm_connector_tests[] = {
|
||||
/* get_subconnector_type */
|
||||
KUNIT_CASE(dm_test_subconnector_type_none),
|
||||
@@ -4489,6 +4601,13 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
|
||||
KUNIT_CASE(dm_test_atomic_check_edp_native_keeps_scaling),
|
||||
KUNIT_CASE(dm_test_atomic_check_lvds_non_native_enables_scaling),
|
||||
KUNIT_CASE(dm_test_atomic_check_non_mst_returns_zero),
|
||||
/* hdmi_cec_unset_edid */
|
||||
KUNIT_CASE(dm_test_hdmi_cec_unset_edid_no_notifier),
|
||||
/* create_eml_sink */
|
||||
KUNIT_CASE(dm_test_create_eml_sink_no_edid),
|
||||
/* handle_edid_mgmt */
|
||||
KUNIT_CASE(dm_test_handle_edid_mgmt_dp_sets_link_caps),
|
||||
KUNIT_CASE(dm_test_handle_edid_mgmt_non_dp_leaves_caps),
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user