[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