mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
drm/amd/display: Add detect and poll tests for connector
Add KUnit coverage for amdgpu_dm_connector_detect() and amdgpu_dm_connector_poll(): force on (analog/digital), force off, sink present/absent, and the DAC-load cached status path. 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:
parent
128729b707
commit
ab9fb27380
|
|
@ -1583,7 +1583,7 @@ EXPORT_IF_KUNIT(create_stream_for_sink);
|
|||
*
|
||||
* Return: The probed connector status (connected/disconnected/unknown).
|
||||
*/
|
||||
static enum drm_connector_status
|
||||
STATIC_IFN_KUNIT enum drm_connector_status
|
||||
amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force)
|
||||
{
|
||||
struct drm_connector *connector = &aconnector->base;
|
||||
|
|
@ -1635,6 +1635,7 @@ amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force)
|
|||
mutex_unlock(&aconnector->hpd_lock);
|
||||
return status;
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_connector_poll);
|
||||
|
||||
/**
|
||||
* amdgpu_dm_connector_detect() - Detect whether a DRM connector is connected to a display
|
||||
|
|
@ -1658,7 +1659,7 @@ amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force)
|
|||
* Return: The connector status (connected, disconnected, or unknown).
|
||||
*
|
||||
*/
|
||||
static enum drm_connector_status
|
||||
STATIC_IFN_KUNIT enum drm_connector_status
|
||||
amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
||||
|
|
@ -1682,6 +1683,7 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
|
|||
return (aconnector->dc_sink ? connector_status_connected :
|
||||
connector_status_disconnected);
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_connector_detect);
|
||||
|
||||
int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector,
|
||||
struct drm_connector_state *connector_state,
|
||||
|
|
|
|||
|
|
@ -164,6 +164,10 @@ create_stream_for_sink(struct drm_connector *connector,
|
|||
const struct dm_connector_state *dm_state,
|
||||
const struct dc_stream_state *old_stream,
|
||||
int requested_bpc);
|
||||
enum drm_connector_status
|
||||
amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force);
|
||||
enum drm_connector_status
|
||||
amdgpu_dm_connector_detect(struct drm_connector *connector, bool force);
|
||||
enum display_content_type
|
||||
get_output_content_type(const struct drm_connector_state *connector_state);
|
||||
bool adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out,
|
||||
|
|
|
|||
|
|
@ -3774,6 +3774,155 @@ static void dm_test_create_stream_existing_sink(struct kunit *test)
|
|||
dc_sink_release(sink);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_connector_detect() */
|
||||
|
||||
/*
|
||||
* A non-DisplayPort connector keeps update_subconnector_property() a no-op and,
|
||||
* because the kunit thread is not the poll worker, the analog poll branch is
|
||||
* skipped. That leaves the forced-state and dc_sink presence branches as the
|
||||
* deterministic behaviour to exercise.
|
||||
*/
|
||||
static struct amdgpu_dm_connector *dm_test_detect_connector(struct kunit *test)
|
||||
{
|
||||
struct drm_device *drm = dm_test_alloc_drm(test);
|
||||
|
||||
return dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_detect_force_on - Test DRM_FORCE_ON reports connected
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_detect_force_on(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
|
||||
|
||||
aconnector->base.force = DRM_FORCE_ON;
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
(int)amdgpu_dm_connector_detect(&aconnector->base, false),
|
||||
(int)connector_status_connected);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_detect_force_on_digital - Test DRM_FORCE_ON_DIGITAL reports connected
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_detect_force_on_digital(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
|
||||
|
||||
aconnector->base.force = DRM_FORCE_ON_DIGITAL;
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
(int)amdgpu_dm_connector_detect(&aconnector->base, false),
|
||||
(int)connector_status_connected);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_detect_force_off - Test DRM_FORCE_OFF reports disconnected
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_detect_force_off(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
|
||||
|
||||
aconnector->base.force = DRM_FORCE_OFF;
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
(int)amdgpu_dm_connector_detect(&aconnector->base, false),
|
||||
(int)connector_status_disconnected);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_detect_sink_present - Test a present dc_sink reports connected
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_detect_sink_present(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
|
||||
struct dc_sink *sink;
|
||||
|
||||
sink = kunit_kzalloc(test, sizeof(*sink), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, sink);
|
||||
|
||||
aconnector->base.force = DRM_FORCE_UNSPECIFIED;
|
||||
aconnector->dc_sink = sink;
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
(int)amdgpu_dm_connector_detect(&aconnector->base, false),
|
||||
(int)connector_status_connected);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_detect_no_sink - Test a missing dc_sink reports disconnected
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_detect_no_sink(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
|
||||
|
||||
aconnector->base.force = DRM_FORCE_UNSPECIFIED;
|
||||
aconnector->dc_sink = NULL;
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
(int)amdgpu_dm_connector_detect(&aconnector->base, false),
|
||||
(int)connector_status_disconnected);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_connector_poll() */
|
||||
|
||||
/**
|
||||
* dm_test_poll_dac_load_returns_cached - Test the DAC load detection shortcut
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* When the previous connection was established by analog DAC load detection and
|
||||
* polling is not forced, the connector is not re-detected and its cached status
|
||||
* is returned unchanged. The connector is embedded in an amdgpu_device so that
|
||||
* drm_to_adev() resolves.
|
||||
*/
|
||||
static void dm_test_poll_dac_load_returns_cached(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
struct dc_link *link;
|
||||
struct dc_sink *local_sink;
|
||||
struct drm_device *drm;
|
||||
struct device *dev;
|
||||
|
||||
dev = drm_kunit_helper_alloc_device(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*adev),
|
||||
offsetof(struct amdgpu_device, ddev),
|
||||
DRIVER_MODESET);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
|
||||
adev = drm_to_adev(drm);
|
||||
|
||||
aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, aconnector);
|
||||
KUNIT_ASSERT_EQ(test,
|
||||
drmm_connector_init(drm, &aconnector->base,
|
||||
&dm_test_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA, NULL), 0);
|
||||
|
||||
link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, link);
|
||||
local_sink = kunit_kzalloc(test, sizeof(*local_sink), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, local_sink);
|
||||
|
||||
link->local_sink = local_sink;
|
||||
link->type = dc_connection_analog_load;
|
||||
aconnector->dc_link = link;
|
||||
|
||||
/* The cached status that the shortcut must return unchanged. */
|
||||
aconnector->base.status = connector_status_connected;
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
(int)amdgpu_dm_connector_poll(aconnector, false),
|
||||
(int)connector_status_connected);
|
||||
}
|
||||
|
||||
static struct kunit_case amdgpu_dm_connector_tests[] = {
|
||||
/* get_subconnector_type */
|
||||
KUNIT_CASE(dm_test_subconnector_type_none),
|
||||
|
|
@ -3974,6 +4123,14 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
|
|||
KUNIT_CASE(dm_test_create_stream_virtual_signal),
|
||||
KUNIT_CASE(dm_test_create_stream_scaling_src),
|
||||
KUNIT_CASE(dm_test_create_stream_existing_sink),
|
||||
/* amdgpu_dm_connector_detect */
|
||||
KUNIT_CASE(dm_test_detect_force_on),
|
||||
KUNIT_CASE(dm_test_detect_force_on_digital),
|
||||
KUNIT_CASE(dm_test_detect_force_off),
|
||||
KUNIT_CASE(dm_test_detect_sink_present),
|
||||
KUNIT_CASE(dm_test_detect_no_sink),
|
||||
/* amdgpu_dm_connector_poll */
|
||||
KUNIT_CASE(dm_test_poll_dac_load_returns_cached),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user