drm/amd/display: Add subconnector property tests for connector

Add KUnit coverage for update_subconnector_property() on the
amdgpu_dm_connector suite:

- DP connector with a sink: subconnector property is resolved from
  the dongle type (VGA converter -> VGA).
- DP connector without a sink: dongle type is ignored and the
  property stays Unknown.
- Non-DP connector: function early-returns and leaves a pre-seeded
  property value untouched.

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: George Zhang <george.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Bhawanpreet Lakha
2026-06-25 14:53:11 -04:00
committed by Alex Deucher
parent 9790ecb376
commit 9ce016cfdc
3 changed files with 145 additions and 1 deletions

View File

@@ -235,7 +235,7 @@ STATIC_IFN_KUNIT enum drm_mode_subconnector get_subconnector_type(struct dc_link
}
EXPORT_IF_KUNIT(get_subconnector_type);
static void update_subconnector_property(struct amdgpu_dm_connector *aconnector)
STATIC_IFN_KUNIT void update_subconnector_property(struct amdgpu_dm_connector *aconnector)
{
struct dc_link *link = aconnector->dc_link;
struct drm_connector *connector = &aconnector->base;
@@ -251,6 +251,7 @@ static void update_subconnector_property(struct amdgpu_dm_connector *aconnector)
connector->dev->mode_config.dp_subconnector_property,
subconnector);
}
EXPORT_IF_KUNIT(update_subconnector_property);
static int amdgpu_dm_connector_get_modes(struct drm_connector *connector);

View File

@@ -147,6 +147,7 @@ int amdgpu_dm_encoder_init(struct drm_device *dev,
#if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
enum drm_mode_subconnector get_subconnector_type(struct dc_link *link);
void update_subconnector_property(struct amdgpu_dm_connector *aconnector);
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,

View File

@@ -2527,6 +2527,144 @@ static void dm_test_set_panel_type_defaults_to_lcd(struct kunit *test)
(int)PANEL_TYPE_LCD);
}
/* Tests for update_subconnector_property() */
/**
* dm_test_update_subconnector_dp_with_sink - Test subconnector property is set
* from the dongle type for a DisplayPort connector with a sink
* @test: The KUnit test context
*/
static void dm_test_update_subconnector_dp_with_sink(struct kunit *test)
{
struct device *dev;
struct drm_device *drm;
struct amdgpu_dm_connector *aconnector;
struct dc_link *link;
uint64_t val = 0;
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(*drm), 0,
DRIVER_MODESET);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, aconnector);
link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, link);
drmm_connector_init(drm, &aconnector->base, &dm_test_connector_funcs,
DRM_MODE_CONNECTOR_DisplayPort, NULL);
drm_connector_attach_dp_subconnector_property(&aconnector->base);
link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
aconnector->dc_link = link;
/* Any non-NULL sink enables dongle-type resolution */
aconnector->dc_sink = kunit_kzalloc(test, sizeof(*aconnector->dc_sink), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, aconnector->dc_sink);
update_subconnector_property(aconnector);
KUNIT_EXPECT_EQ(test, drm_object_property_get_value(&aconnector->base.base,
aconnector->base.dev->mode_config.dp_subconnector_property,
&val), 0);
KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SUBCONNECTOR_VGA);
}
/**
* dm_test_update_subconnector_dp_no_sink - Test subconnector property stays
* unknown for a DisplayPort connector without a sink
* @test: The KUnit test context
*/
static void dm_test_update_subconnector_dp_no_sink(struct kunit *test)
{
struct device *dev;
struct drm_device *drm;
struct amdgpu_dm_connector *aconnector;
struct dc_link *link;
uint64_t val = 0;
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(*drm), 0,
DRIVER_MODESET);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, aconnector);
link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, link);
drmm_connector_init(drm, &aconnector->base, &dm_test_connector_funcs,
DRM_MODE_CONNECTOR_DisplayPort, NULL);
drm_connector_attach_dp_subconnector_property(&aconnector->base);
/* Dongle type is set, but no sink means it must not be consulted */
link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_HDMI_CONVERTER;
aconnector->dc_link = link;
aconnector->dc_sink = NULL;
update_subconnector_property(aconnector);
KUNIT_EXPECT_EQ(test, drm_object_property_get_value(&aconnector->base.base,
aconnector->base.dev->mode_config.dp_subconnector_property,
&val), 0);
KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SUBCONNECTOR_Unknown);
}
/**
* dm_test_update_subconnector_non_dp_noop - Test non-DisplayPort connector is
* left untouched (early return)
* @test: The KUnit test context
*/
static void dm_test_update_subconnector_non_dp_noop(struct kunit *test)
{
struct device *dev;
struct drm_device *drm;
struct amdgpu_dm_connector *aconnector;
struct dc_link *link;
uint64_t val = 0;
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(*drm), 0,
DRIVER_MODESET);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, aconnector);
link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, link);
drmm_connector_init(drm, &aconnector->base, &dm_test_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA, NULL);
drm_connector_attach_dp_subconnector_property(&aconnector->base);
/* Pre-seed the property to a non-default value */
drm_object_property_set_value(&aconnector->base.base,
aconnector->base.dev->mode_config.dp_subconnector_property,
DRM_MODE_SUBCONNECTOR_VGA);
link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_HDMI_CONVERTER;
aconnector->dc_link = link;
aconnector->dc_sink = kunit_kzalloc(test, sizeof(*aconnector->dc_sink), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, aconnector->dc_sink);
update_subconnector_property(aconnector);
/* Non-DP connector: value must remain what we seeded */
KUNIT_EXPECT_EQ(test, drm_object_property_get_value(&aconnector->base.base,
aconnector->base.dev->mode_config.dp_subconnector_property,
&val), 0);
KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SUBCONNECTOR_VGA);
}
static struct kunit_case amdgpu_dm_connector_tests[] = {
/* get_subconnector_type */
KUNIT_CASE(dm_test_subconnector_type_none),
@@ -2664,6 +2802,10 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
KUNIT_CASE(dm_test_is_freesync_video_mode_null_mode),
KUNIT_CASE(dm_test_is_freesync_video_mode_match),
KUNIT_CASE(dm_test_is_freesync_video_mode_no_match),
/* update_subconnector_property */
KUNIT_CASE(dm_test_update_subconnector_dp_with_sink),
KUNIT_CASE(dm_test_update_subconnector_dp_no_sink),
KUNIT_CASE(dm_test_update_subconnector_non_dp_noop),
/* amdgpu_dm_update_cacp_caps */
KUNIT_CASE(dm_test_cacp_caps_unsupported_ip),
KUNIT_CASE(dm_test_cacp_caps_excluded_ip_316),