[PATCH 54/59] drm/amd/display: Test DC plane attributes

Alex Hung <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
[WHAT]
Add KUnit tests for fill_dc_plane_attributes(), covering the copy of the
plane info into the DC plane state and the scaling, pixel format and 3D
LUT rejection paths.

[HOW]
Reuse the plane info fixture and add a CRTC state complete enough for
the colour management update. A scaling factor of 1 in the plane caps
means no scaling, which matches the 1:1 geometry of the fixture.

Assisted-by: Copilot:Claude-Opus-5 GPT-5.6-Sol
Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   9 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
 .../display/amdgpu_dm/tests/amdgpu_dm_test.c  | 126 ++++++++++++++++++
 3 files changed, 134 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8a87677b46b8..a97caf7e1d33 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3074,10 +3074,10 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
 }
 EXPORT_IF_KUNIT(fill_dc_plane_info_and_addr);
 
-static int fill_dc_plane_attributes(struct amdgpu_device *adev,
-				    struct dc_plane_state *dc_plane_state,
-				    struct drm_plane_state *plane_state,
-				    struct drm_crtc_state *crtc_state)
+STATIC_IFN_KUNIT int fill_dc_plane_attributes(struct amdgpu_device *adev,
+					      struct dc_plane_state *dc_plane_state,
+					      struct drm_plane_state *plane_state,
+					      struct drm_crtc_state *crtc_state)
 {
 	struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
 	struct amdgpu_framebuffer *afb = (struct amdgpu_framebuffer *)plane_state->fb;
@@ -3130,6 +3130,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
 
 	return 0;
 }
+EXPORT_IF_KUNIT(fill_dc_plane_attributes);
 
 static inline void fill_dc_dirty_rect(struct drm_plane *plane,
 				      struct rect *dirty_rect, int32_t x,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 09ecca519b3b..b1db78e79015 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -1268,6 +1268,9 @@ int amdgpu_dm_mode_config_init(struct amdgpu_device *adev);
 int initialize_plane(struct amdgpu_display_manager *dm, struct amdgpu_mode_info *mode_info,
 		     int plane_id, enum drm_plane_type plane_type,
 		     const struct dc_plane_cap *plane_cap);
+int fill_dc_plane_attributes(struct amdgpu_device *adev, struct dc_plane_state *dc_plane_state,
+			     struct drm_plane_state *plane_state,
+			     struct drm_crtc_state *crtc_state);
 #endif
 
 #endif /* __AMDGPU_DM_H__ */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
index 0fe19a66e6f9..f8c540a6cdee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
@@ -3964,6 +3964,127 @@ static void dm_test_early_init_unsupported_version(struct kunit *test)
 	KUNIT_EXPECT_FALSE(test, adev->dc_enabled);
 }
 
+/* Tests for fill_dc_plane_attributes() */
+
+struct dm_test_plane_attr_ctx {
+	struct amdgpu_device *adev;
+	struct dm_crtc_state *crtc_state;
+	struct dm_test_plane_info_ctx *plane;
+	struct dc_plane_state *dc_plane;
+};
+
+/*
+ * A DC plane, plus a CRTC state complete enough for the colour management
+ * update at the end of fill_dc_plane_attributes(). A scaling factor of 1 in the
+ * plane caps means "no scaling", which is what the 1:1 geometry of the plane
+ * info context needs.
+ */
+static struct dm_test_plane_attr_ctx *
+dm_test_plane_attr_ctx_alloc(struct kunit *test, u32 drm_format)
+{
+	struct dm_test_plane_attr_ctx *ctx;
+
+	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, ctx);
+	ctx->crtc_state = kunit_kzalloc(test, sizeof(*ctx->crtc_state), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, ctx->crtc_state);
+	ctx->dc_plane = kunit_kzalloc(test, sizeof(*ctx->dc_plane), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, ctx->dc_plane);
+
+	ctx->adev = dm_kunit_alloc_adev(test);
+	ctx->adev->dm.dc = dm_kunit_alloc_dc_with_ctx(test);
+	ctx->adev->dm.dc->caps.planes[0].max_upscale_factor.argb8888 = 1;
+	ctx->adev->dm.dc->caps.planes[0].max_downscale_factor.argb8888 = 1;
+
+	ctx->crtc_state->stream = dm_kunit_alloc_stream(test, NULL);
+	/* Colour management resolves the device through the commit backpointer. */
+	ctx->crtc_state->base.state = dm_test_alloc_commit(test, ctx->adev);
+	ctx->plane = dm_test_plane_info_ctx_alloc(test, ctx->adev, drm_format);
+
+	return ctx;
+}
+
+static int dm_test_fill_plane_attr(struct dm_test_plane_attr_ctx *ctx)
+{
+	return fill_dc_plane_attributes(ctx->adev, ctx->dc_plane,
+					ctx->plane->plane_state, &ctx->crtc_state->base);
+}
+
+/**
+ * dm_test_plane_attributes_success - Test plane info is copied into the DC plane
+ * @test: The KUnit test context
+ */
+static void dm_test_plane_attributes_success(struct kunit *test)
+{
+	struct dm_test_plane_attr_ctx *ctx;
+
+	ctx = dm_test_plane_attr_ctx_alloc(test, DRM_FORMAT_ARGB8888);
+	ctx->plane->plane_state->normalized_zpos = 2;
+
+	KUNIT_EXPECT_EQ(test, dm_test_fill_plane_attr(ctx), 0);
+	KUNIT_EXPECT_EQ(test, (int)ctx->dc_plane->format,
+			(int)SURFACE_PIXEL_FORMAT_GRPH_ARGB8888);
+	KUNIT_EXPECT_EQ(test, (int)ctx->dc_plane->color_space, (int)COLOR_SPACE_SRGB);
+	KUNIT_EXPECT_EQ(test, (int)ctx->dc_plane->rotation, (int)ROTATION_ANGLE_0);
+	KUNIT_EXPECT_EQ(test, ctx->dc_plane->src_rect.width, 1920U);
+	KUNIT_EXPECT_EQ(test, ctx->dc_plane->dst_rect.width, 1920U);
+	KUNIT_EXPECT_EQ(test, ctx->dc_plane->layer_index, 2);
+	KUNIT_EXPECT_TRUE(test, ctx->dc_plane->visible);
+	KUNIT_EXPECT_TRUE(test, ctx->dc_plane->flip_int_enabled);
+}
+
+/**
+ * dm_test_plane_attributes_bad_scaling - Test an empty source rectangle is rejected
+ * @test: The KUnit test context
+ */
+static void dm_test_plane_attributes_bad_scaling(struct kunit *test)
+{
+	struct dm_test_plane_attr_ctx *ctx;
+
+	ctx = dm_test_plane_attr_ctx_alloc(test, DRM_FORMAT_ARGB8888);
+	ctx->plane->plane_state->src_w = 0;
+
+	KUNIT_EXPECT_EQ(test, dm_test_fill_plane_attr(ctx), -EINVAL);
+}
+
+/**
+ * dm_test_plane_attributes_bad_format - Test an unsupported format is rejected
+ * @test: The KUnit test context
+ */
+static void dm_test_plane_attributes_bad_format(struct kunit *test)
+{
+	struct dm_test_plane_attr_ctx *ctx;
+
+	ctx = dm_test_plane_attr_ctx_alloc(test, DRM_FORMAT_YUYV);
+
+	KUNIT_EXPECT_EQ(test, dm_test_fill_plane_attr(ctx), -EINVAL);
+}
+
+/**
+ * dm_test_plane_attributes_bad_color_mgmt - Test a bad 3D LUT is rejected
+ * @test: The KUnit test context
+ */
+static void dm_test_plane_attributes_bad_color_mgmt(struct kunit *test)
+{
+	struct dm_test_plane_attr_ctx *ctx;
+	struct drm_property_blob *blob;
+	struct drm_color_lut *lut;
+
+	ctx = dm_test_plane_attr_ctx_alloc(test, DRM_FORMAT_ARGB8888);
+	blob = kunit_kzalloc(test, sizeof(*blob), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, blob);
+	lut = kunit_kcalloc(test, 16, sizeof(*lut), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, lut);
+
+	/* A 3D LUT that is not a perfect cube fails validation. */
+	blob->data = lut;
+	blob->length = 16 * sizeof(*lut);
+	ctx->adev->dm.dc->caps.color.dpp.hw_3d_lut = true;
+	ctx->plane->dm_plane_state->lut3d = blob;
+
+	KUNIT_EXPECT_EQ(test, dm_test_fill_plane_attr(ctx), -EINVAL);
+}
+
 /* Tests for load_dmcu_fw() */
 
 /**
@@ -4505,6 +4626,11 @@ static struct kunit_case amdgpu_dm_tests[] = {
 	KUNIT_CASE(dm_test_early_init_legacy_asics),
 	KUNIT_CASE(dm_test_early_init_dcn_versions),
 	KUNIT_CASE(dm_test_early_init_unsupported_version),
+	/* fill_dc_plane_attributes */
+	KUNIT_CASE(dm_test_plane_attributes_success),
+	KUNIT_CASE(dm_test_plane_attributes_bad_scaling),
+	KUNIT_CASE(dm_test_plane_attributes_bad_format),
+	KUNIT_CASE(dm_test_plane_attributes_bad_color_mgmt),
 	/* load_dmcu_fw */
 	KUNIT_CASE(dm_test_load_dmcu_fw_no_dmcu),
 	KUNIT_CASE(dm_test_load_dmcu_fw_dcn),
-- 
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.