summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBhawanpreet Lakha <bhawanpreet.lakha@amd.com>2026-06-25 14:53:11 -0400
committerAlex Deucher <alexander.deucher@amd.com>2026-07-15 09:15:38 -0400
commit9ce016cfdc6e7bc87faf42f723c54f5bca5ea028 (patch)
tree1d561e95d71c2b2dbda710a53be62adb6fb73022 /drivers
parent9790ecb376309173ba7cb7194954d42d81f553e3 (diff)
downloadlinux-next-9ce016cfdc6e7bc87faf42f723c54f5bca5ea028.tar.gz
linux-next-9ce016cfdc6e7bc87faf42f723c54f5bca5ea028.zip
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h1
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c142
3 files changed, 145 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
index 1a1c3642c456..b24a4afb9153 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
@@ -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);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
index ca0fdb0dc41a..ecf23d0fb72e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
@@ -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,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
index 91f9543dd7bb..782a22e4f074 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
@@ -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),