diff options
| author | Bhawanpreet Lakha <bhawanpreet.lakha@amd.com> | 2026-06-25 14:53:11 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-07-15 09:15:38 -0400 |
| commit | 9ce016cfdc6e7bc87faf42f723c54f5bca5ea028 (patch) | |
| tree | 1d561e95d71c2b2dbda710a53be62adb6fb73022 | |
| parent | 9790ecb376309173ba7cb7194954d42d81f553e3 (diff) | |
| download | linux-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>
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), |
