From: Bhawanpreet Lakha <[email protected]>
Add KUnit tests for amdgpu_dm_connector_get_modes() covering the
no-EDID default modes, the extra modes added for 128b/132b and analog
links, and the path that adds modes from a valid EDID.
Assisted-by: Copilot:Claude-Opus-4.8
Reviewed-by: Alex Hung <[email protected]>
Signed-off-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Ivan Lipski <[email protected]>
---
.../display/amdgpu_dm/amdgpu_dm_connector.c | 5 +-
.../display/amdgpu_dm/amdgpu_dm_connector.h | 1 +
.../tests/amdgpu_dm_connector_test.c | 178 ++++++++++++++++++
3 files changed, 182 insertions(+), 2 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 44c223b178c50..45ac4e2b5029b 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
@@ -256,7 +256,7 @@ STATIC_IFN_KUNIT void update_subconnector_property(struct amdgpu_dm_connector *a
}
EXPORT_IF_KUNIT(update_subconnector_property);
-static int amdgpu_dm_connector_get_modes(struct drm_connector *connector);
+STATIC_IFN_KUNIT int amdgpu_dm_connector_get_modes(struct drm_connector *connector);
STATIC_IFN_KUNIT void amdgpu_dm_fbc_init(struct drm_connector *connector)
{
@@ -3038,7 +3038,7 @@ STATIC_IFN_KUNIT void amdgpu_dm_connector_add_freesync_modes(struct drm_connecto
}
EXPORT_IF_KUNIT(amdgpu_dm_connector_add_freesync_modes);
-static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
+STATIC_IFN_KUNIT int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
{
struct amdgpu_dm_connector *amdgpu_dm_connector =
to_amdgpu_dm_connector(connector);
@@ -3077,6 +3077,7 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
return amdgpu_dm_connector->num_modes;
}
+EXPORT_IF_KUNIT(amdgpu_dm_connector_get_modes);
static const u32 supported_colorspaces =
BIT(DRM_MODE_COLORIMETRY_BT709_YCC) |
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 3571378654fd7..91b8434ba591d 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
@@ -168,6 +168,7 @@ void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder,
struct drm_connector *connector);
void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
const struct drm_edid *drm_edid);
+int amdgpu_dm_connector_get_modes(struct drm_connector *connector);
uint add_fs_modes(struct amdgpu_dm_connector *aconnector);
void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connector,
const struct drm_edid *drm_edid);
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 3a5edf84fbc0a..fc6b6013d1188 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
@@ -7171,6 +7171,179 @@ static void dm_test_funcs_force_reads_edid(struct kunit *test)
ctx->aconnector->drm_edid = NULL;
}
+/* Tests for amdgpu_dm_connector_get_modes() */
+
+static enum dp_link_encoding dm_test_gm_enc_8b10b(const struct dc_link_settings *s)
+{
+ return DP_8b_10b_ENCODING;
+}
+
+static enum dp_link_encoding dm_test_gm_enc_128b(const struct dc_link_settings *s)
+{
+ return DP_128b_132b_ENCODING;
+}
+
+/*
+ * Build an amdgpu_dm_connector on an amdgpu_device-backed drm device (so
+ * drm_to_adev() resolves for amdgpu_dm_fbc_init()) with an attached encoder
+ * and a dc/dc_link whose link_srv reports a non-128b encoding by default. The
+ * fbc compressor is left NULL so amdgpu_dm_fbc_init() early-returns.
+ */
+struct dm_test_gm_ctx {
+ struct amdgpu_device *adev;
+ struct drm_device *drm;
+ struct amdgpu_dm_connector *aconnector;
+ struct amdgpu_encoder *aenc;
+ struct dc *dc;
+ struct link_service *link_srv;
+ struct dc_link *link;
+};
+
+static struct dm_test_gm_ctx *
+dm_test_gm_ctx_alloc(struct kunit *test, int connector_type)
+{
+ struct dm_test_gm_ctx *ctx;
+ struct device *dev;
+ int ret;
+
+ ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, ctx);
+
+ dev = drm_kunit_helper_alloc_device(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+ ctx->drm = __drm_kunit_helper_alloc_drm_device(test, dev,
+ sizeof(*ctx->adev),
+ offsetof(struct amdgpu_device, ddev),
+ DRIVER_MODESET);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->drm);
+ ctx->adev = drm_to_adev(ctx->drm);
+
+ ctx->aconnector = drmm_kzalloc(ctx->drm, sizeof(*ctx->aconnector),
+ GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
+ ret = drmm_connector_init(ctx->drm, &ctx->aconnector->base,
+ &dm_test_connector_funcs, connector_type,
+ NULL);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ ctx->aenc = drmm_kzalloc(ctx->drm, sizeof(*ctx->aenc), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, ctx->aenc);
+ ret = drmm_encoder_init(ctx->drm, &ctx->aenc->base, NULL,
+ DRM_MODE_ENCODER_TMDS, NULL);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ ret = drm_connector_attach_encoder(&ctx->aconnector->base,
+ &ctx->aenc->base);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ ctx->dc = kunit_kzalloc(test, sizeof(*ctx->dc), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, ctx->dc);
+ ctx->link_srv = kunit_kzalloc(test, sizeof(*ctx->link_srv), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, ctx->link_srv);
+ ctx->link = kunit_kzalloc(test, sizeof(*ctx->link), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, ctx->link);
+
+ ctx->link_srv->dp_get_encoding_format = dm_test_gm_enc_8b10b;
+ ctx->dc->link_srv = ctx->link_srv;
+ ctx->adev->dm.dc = ctx->dc;
+ ctx->link->dc = ctx->dc;
+ ctx->aconnector->dc_link = ctx->link;
+
+ return ctx;
+}
+
+/**
+ * dm_test_get_modes_noedid_default - Test synthesized modes without an EDID
+ * @test: The KUnit test context
+ *
+ * With no cached EDID and a non-128b link, get_modes() synthesizes the default
+ * 640x480 fallback mode(s) and reports a non-zero count.
+ */
+static void dm_test_get_modes_noedid_default(struct kunit *test)
+{
+ struct dm_test_gm_ctx *ctx =
+ dm_test_gm_ctx_alloc(test, DRM_MODE_CONNECTOR_DisplayPort);
+
+ KUNIT_EXPECT_GT(test,
+ amdgpu_dm_connector_get_modes(&ctx->aconnector->base), 0);
+}
+
+/**
+ * dm_test_get_modes_noedid_128b_adds_more - Test 128b links add 1080p modes
+ * @test: The KUnit test context
+ *
+ * A 128b/132b link synthesizes the extra 1920x1080 fallback modes, so the mode
+ * count is strictly greater than for an 8b/10b link.
+ */
+static void dm_test_get_modes_noedid_128b_adds_more(struct kunit *test)
+{
+ struct dm_test_gm_ctx *ctx =
+ dm_test_gm_ctx_alloc(test, DRM_MODE_CONNECTOR_DisplayPort);
+ int n_8b, n_128b;
+
+ n_8b = amdgpu_dm_connector_get_modes(&ctx->aconnector->base);
+
+ ctx->link_srv->dp_get_encoding_format = dm_test_gm_enc_128b;
+ n_128b = amdgpu_dm_connector_get_modes(&ctx->aconnector->base);
+
+ KUNIT_EXPECT_GT(test, n_128b, n_8b);
+}
+
+/**
+ * dm_test_get_modes_noedid_analog_adds_common - Test analog sinks add common modes
+ * @test: The KUnit test context
+ *
+ * An analog VGA sink detected by load detection adds the common fallback modes
+ * on top of the default 640x480 mode(s).
+ */
+static void dm_test_get_modes_noedid_analog_adds_common(struct kunit *test)
+{
+ struct dm_test_gm_ctx *ctx =
+ dm_test_gm_ctx_alloc(test, DRM_MODE_CONNECTOR_VGA);
+ struct dc_sink *sink;
+ int n_base, n_analog;
+
+ n_base = amdgpu_dm_connector_get_modes(&ctx->aconnector->base);
+
+ sink = kunit_kzalloc(test, sizeof(*sink), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, sink);
+ sink->edid_caps.analog = true;
+ ctx->aconnector->dc_sink = sink;
+ ctx->link->link_id.id = CONNECTOR_ID_VGA;
+
+ n_analog = amdgpu_dm_connector_get_modes(&ctx->aconnector->base);
+
+ KUNIT_EXPECT_GT(test, n_analog, n_base);
+}
+
+/**
+ * dm_test_get_modes_with_edid - Test the cached-EDID path adds common modes
+ * @test: The KUnit test context
+ *
+ * With a cached EDID on an eDP connector, get_modes() takes the DDC path and
+ * adds the common downscaled modes derived from the encoder native mode.
+ */
+static void dm_test_get_modes_with_edid(struct kunit *test)
+{
+ struct dm_test_gm_ctx *ctx =
+ dm_test_gm_ctx_alloc(test, DRM_MODE_CONNECTOR_eDP);
+ const struct drm_edid *drm_edid;
+
+ drm_edid = drm_edid_alloc(dm_test_uad_edid, sizeof(dm_test_uad_edid));
+ KUNIT_ASSERT_NOT_NULL(test, drm_edid);
+ drm_edid_connector_update(&ctx->aconnector->base, drm_edid);
+ ctx->aconnector->drm_edid = drm_edid;
+
+ ctx->aenc->native_mode.hdisplay = 1920;
+ ctx->aenc->native_mode.vdisplay = 1200;
+
+ KUNIT_EXPECT_GT(test,
+ amdgpu_dm_connector_get_modes(&ctx->aconnector->base), 0);
+
+ drm_edid_free(drm_edid);
+ ctx->aconnector->drm_edid = NULL;
+}
+
/* Tests for amdgpu_dm_update_stream_scaling_settings() */
/**
@@ -7634,6 +7807,11 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
/* amdgpu_dm_connector_funcs_force */
KUNIT_CASE(dm_test_funcs_force_no_edid),
KUNIT_CASE(dm_test_funcs_force_reads_edid),
+ /* amdgpu_dm_connector_get_modes */
+ KUNIT_CASE(dm_test_get_modes_noedid_default),
+ KUNIT_CASE(dm_test_get_modes_noedid_128b_adds_more),
+ KUNIT_CASE(dm_test_get_modes_noedid_analog_adds_common),
+ KUNIT_CASE(dm_test_get_modes_with_edid),
/* dm_validate_stream_and_context */
KUNIT_CASE(dm_test_validate_stream_null_stream),
KUNIT_CASE(dm_test_validate_stream_dc_ok_no_pipe),
--
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.