diff options
Diffstat (limited to 'drivers/gpu/drm/tests')
| -rw-r--r-- | drivers/gpu/drm/tests/Makefile | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/tests/drm_bridge_test.c | 176 | ||||
| -rw-r--r-- | drivers/gpu/drm/tests/drm_format_helper_test.c | 266 | ||||
| -rw-r--r-- | drivers/gpu/drm/tests/drm_framebuffer_test.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 651 | ||||
| -rw-r--r-- | drivers/gpu/drm/tests/drm_kunit_edid.h | 374 | ||||
| -rw-r--r-- | drivers/gpu/drm/tests/drm_kunit_helpers.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/tests/drm_sysfb_modeset_test.c | 168 | 
8 files changed, 1133 insertions, 507 deletions
| diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 3afd6587df08..c0e952293ad0 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST) += \  	drm_modes_test.o \  	drm_plane_helper_test.o \  	drm_probe_helper_test.o \ -	drm_rect_test.o +	drm_rect_test.o \ +	drm_sysfb_modeset_test.o  CFLAGS_drm_mm_test.o := $(DISABLE_STRUCTLEAK_PLUGIN) diff --git a/drivers/gpu/drm/tests/drm_bridge_test.c b/drivers/gpu/drm/tests/drm_bridge_test.c index ff88ec2e911c..887020141c7f 100644 --- a/drivers/gpu/drm/tests/drm_bridge_test.c +++ b/drivers/gpu/drm/tests/drm_bridge_test.c @@ -8,36 +8,64 @@  #include <drm/drm_bridge_helper.h>  #include <drm/drm_kunit_helpers.h> +#include <kunit/device.h>  #include <kunit/test.h> +/* + * Mimick the typical "private" struct defined by a bridge driver, which + * embeds a bridge plus other fields. + * + * Having at least one member before @bridge ensures we test non-zero + * @bridge offset. + */ +struct drm_bridge_priv { +	unsigned int enable_count; +	unsigned int disable_count; +	struct drm_bridge bridge; +	void *data; +}; +  struct drm_bridge_init_priv {  	struct drm_device drm; +	/** @dev: device, only for tests not needing a whole drm_device */ +	struct device *dev;  	struct drm_plane *plane;  	struct drm_crtc *crtc;  	struct drm_encoder encoder; -	struct drm_bridge bridge; +	struct drm_bridge_priv *test_bridge;  	struct drm_connector *connector; -	unsigned int enable_count; -	unsigned int disable_count; +	bool destroyed;  }; +static struct drm_bridge_priv *bridge_to_priv(struct drm_bridge *bridge) +{ +	return container_of(bridge, struct drm_bridge_priv, bridge); +} + +static void drm_test_bridge_priv_destroy(struct drm_bridge *bridge) +{ +	struct drm_bridge_priv *bridge_priv = bridge_to_priv(bridge); +	struct drm_bridge_init_priv *priv = (struct drm_bridge_init_priv *)bridge_priv->data; + +	priv->destroyed = true; +} +  static void drm_test_bridge_enable(struct drm_bridge *bridge)  { -	struct drm_bridge_init_priv *priv = -		container_of(bridge, struct drm_bridge_init_priv, bridge); +	struct drm_bridge_priv *priv = bridge_to_priv(bridge);  	priv->enable_count++;  }  static void drm_test_bridge_disable(struct drm_bridge *bridge)  { -	struct drm_bridge_init_priv *priv = -		container_of(bridge, struct drm_bridge_init_priv, bridge); +	struct drm_bridge_priv *priv = bridge_to_priv(bridge);  	priv->disable_count++;  }  static const struct drm_bridge_funcs drm_test_bridge_legacy_funcs = { +	.destroy		= drm_test_bridge_priv_destroy,  	.enable			= drm_test_bridge_enable,  	.disable		= drm_test_bridge_disable,  }; @@ -45,8 +73,7 @@ static const struct drm_bridge_funcs drm_test_bridge_legacy_funcs = {  static void drm_test_bridge_atomic_enable(struct drm_bridge *bridge,  					  struct drm_atomic_state *state)  { -	struct drm_bridge_init_priv *priv = -		container_of(bridge, struct drm_bridge_init_priv, bridge); +	struct drm_bridge_priv *priv = bridge_to_priv(bridge);  	priv->enable_count++;  } @@ -54,13 +81,13 @@ static void drm_test_bridge_atomic_enable(struct drm_bridge *bridge,  static void drm_test_bridge_atomic_disable(struct drm_bridge *bridge,  					   struct drm_atomic_state *state)  { -	struct drm_bridge_init_priv *priv = -		container_of(bridge, struct drm_bridge_init_priv, bridge); +	struct drm_bridge_priv *priv = bridge_to_priv(bridge);  	priv->disable_count++;  }  static const struct drm_bridge_funcs drm_test_bridge_atomic_funcs = { +	.destroy		= drm_test_bridge_priv_destroy,  	.atomic_enable		= drm_test_bridge_atomic_enable,  	.atomic_disable		= drm_test_bridge_atomic_disable,  	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state, @@ -102,6 +129,12 @@ drm_test_bridge_init(struct kunit *test, const struct drm_bridge_funcs *funcs)  	if (IS_ERR(priv))  		return ERR_CAST(priv); +	priv->test_bridge = devm_drm_bridge_alloc(dev, struct drm_bridge_priv, bridge, funcs); +	if (IS_ERR(priv->test_bridge)) +		return ERR_CAST(priv->test_bridge); + +	priv->test_bridge->data = priv; +  	drm = &priv->drm;  	priv->plane = drm_kunit_helper_create_primary_plane(test, drm,  							    NULL, @@ -125,9 +158,8 @@ drm_test_bridge_init(struct kunit *test, const struct drm_bridge_funcs *funcs)  	enc->possible_crtcs = drm_crtc_mask(priv->crtc); -	bridge = &priv->bridge; +	bridge = &priv->test_bridge->bridge;  	bridge->type = DRM_MODE_CONNECTOR_VIRTUAL; -	bridge->funcs = funcs;  	ret = drm_kunit_bridge_add(test, bridge);  	if (ret) @@ -173,7 +205,7 @@ static void drm_test_drm_bridge_get_current_state_atomic(struct kunit *test)  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);  retry_commit: -	bridge = &priv->bridge; +	bridge = &priv->test_bridge->bridge;  	bridge_state = drm_atomic_get_bridge_state(state, bridge);  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bridge_state); @@ -228,7 +260,7 @@ static void drm_test_drm_bridge_get_current_state_legacy(struct kunit *test)  	 * locking. The function would return NULL in all cases anyway,  	 * so we don't really have any concurrency to worry about.  	 */ -	bridge = &priv->bridge; +	bridge = &priv->test_bridge->bridge;  	KUNIT_EXPECT_NULL(test, drm_bridge_get_current_state(bridge));  } @@ -253,7 +285,7 @@ static void drm_test_drm_bridge_helper_reset_crtc_atomic(struct kunit *test)  	struct drm_modeset_acquire_ctx ctx;  	struct drm_bridge_init_priv *priv;  	struct drm_display_mode *mode; -	struct drm_bridge *bridge; +	struct drm_bridge_priv *bridge_priv;  	int ret;  	priv = drm_test_bridge_init(test, &drm_test_bridge_atomic_funcs); @@ -279,14 +311,14 @@ retry_commit:  	drm_modeset_drop_locks(&ctx);  	drm_modeset_acquire_fini(&ctx); -	bridge = &priv->bridge; -	KUNIT_ASSERT_EQ(test, priv->enable_count, 1); -	KUNIT_ASSERT_EQ(test, priv->disable_count, 0); +	bridge_priv = priv->test_bridge; +	KUNIT_ASSERT_EQ(test, bridge_priv->enable_count, 1); +	KUNIT_ASSERT_EQ(test, bridge_priv->disable_count, 0);  	drm_modeset_acquire_init(&ctx, 0);  retry_reset: -	ret = drm_bridge_helper_reset_crtc(bridge, &ctx); +	ret = drm_bridge_helper_reset_crtc(&bridge_priv->bridge, &ctx);  	if (ret == -EDEADLK) {  		drm_modeset_backoff(&ctx);  		goto retry_reset; @@ -296,8 +328,8 @@ retry_reset:  	drm_modeset_drop_locks(&ctx);  	drm_modeset_acquire_fini(&ctx); -	KUNIT_EXPECT_EQ(test, priv->enable_count, 2); -	KUNIT_EXPECT_EQ(test, priv->disable_count, 1); +	KUNIT_EXPECT_EQ(test, bridge_priv->enable_count, 2); +	KUNIT_EXPECT_EQ(test, bridge_priv->disable_count, 1);  }  /* @@ -309,7 +341,7 @@ static void drm_test_drm_bridge_helper_reset_crtc_atomic_disabled(struct kunit *  	struct drm_modeset_acquire_ctx ctx;  	struct drm_bridge_init_priv *priv;  	struct drm_display_mode *mode; -	struct drm_bridge *bridge; +	struct drm_bridge_priv *bridge_priv;  	int ret;  	priv = drm_test_bridge_init(test, &drm_test_bridge_atomic_funcs); @@ -318,14 +350,14 @@ static void drm_test_drm_bridge_helper_reset_crtc_atomic_disabled(struct kunit *  	mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); -	bridge = &priv->bridge; -	KUNIT_ASSERT_EQ(test, priv->enable_count, 0); -	KUNIT_ASSERT_EQ(test, priv->disable_count, 0); +	bridge_priv = priv->test_bridge; +	KUNIT_ASSERT_EQ(test, bridge_priv->enable_count, 0); +	KUNIT_ASSERT_EQ(test, bridge_priv->disable_count, 0);  	drm_modeset_acquire_init(&ctx, 0);  retry_reset: -	ret = drm_bridge_helper_reset_crtc(bridge, &ctx); +	ret = drm_bridge_helper_reset_crtc(&bridge_priv->bridge, &ctx);  	if (ret == -EDEADLK) {  		drm_modeset_backoff(&ctx);  		goto retry_reset; @@ -335,8 +367,8 @@ retry_reset:  	drm_modeset_drop_locks(&ctx);  	drm_modeset_acquire_fini(&ctx); -	KUNIT_EXPECT_EQ(test, priv->enable_count, 0); -	KUNIT_EXPECT_EQ(test, priv->disable_count, 0); +	KUNIT_EXPECT_EQ(test, bridge_priv->enable_count, 0); +	KUNIT_EXPECT_EQ(test, bridge_priv->disable_count, 0);  }  /* @@ -348,7 +380,7 @@ static void drm_test_drm_bridge_helper_reset_crtc_legacy(struct kunit *test)  	struct drm_modeset_acquire_ctx ctx;  	struct drm_bridge_init_priv *priv;  	struct drm_display_mode *mode; -	struct drm_bridge *bridge; +	struct drm_bridge_priv *bridge_priv;  	int ret;  	priv = drm_test_bridge_init(test, &drm_test_bridge_legacy_funcs); @@ -374,14 +406,14 @@ retry_commit:  	drm_modeset_drop_locks(&ctx);  	drm_modeset_acquire_fini(&ctx); -	bridge = &priv->bridge; -	KUNIT_ASSERT_EQ(test, priv->enable_count, 1); -	KUNIT_ASSERT_EQ(test, priv->disable_count, 0); +	bridge_priv = priv->test_bridge; +	KUNIT_ASSERT_EQ(test, bridge_priv->enable_count, 1); +	KUNIT_ASSERT_EQ(test, bridge_priv->disable_count, 0);  	drm_modeset_acquire_init(&ctx, 0);  retry_reset: -	ret = drm_bridge_helper_reset_crtc(bridge, &ctx); +	ret = drm_bridge_helper_reset_crtc(&bridge_priv->bridge, &ctx);  	if (ret == -EDEADLK) {  		drm_modeset_backoff(&ctx);  		goto retry_reset; @@ -391,8 +423,8 @@ retry_reset:  	drm_modeset_drop_locks(&ctx);  	drm_modeset_acquire_fini(&ctx); -	KUNIT_EXPECT_EQ(test, priv->enable_count, 2); -	KUNIT_EXPECT_EQ(test, priv->disable_count, 1); +	KUNIT_EXPECT_EQ(test, bridge_priv->enable_count, 2); +	KUNIT_EXPECT_EQ(test, bridge_priv->disable_count, 1);  }  static struct kunit_case drm_bridge_helper_reset_crtc_tests[] = { @@ -407,11 +439,83 @@ static struct kunit_suite drm_bridge_helper_reset_crtc_test_suite = {  	.test_cases = drm_bridge_helper_reset_crtc_tests,  }; +static int drm_test_bridge_alloc_init(struct kunit *test) +{ +	struct drm_bridge_init_priv *priv; + +	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + +	priv->dev = kunit_device_register(test, "drm-bridge-dev"); +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev); + +	test->priv = priv; + +	priv->test_bridge = devm_drm_bridge_alloc(priv->dev, struct drm_bridge_priv, bridge, +						  &drm_test_bridge_atomic_funcs); +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->test_bridge); + +	priv->test_bridge->data = priv; + +	KUNIT_ASSERT_FALSE(test, priv->destroyed); + +	return 0; +} + +/* + * Test that a bridge is freed when the device is destroyed in lack of + * other drm_bridge_get/put() operations. + */ +static void drm_test_drm_bridge_alloc_basic(struct kunit *test) +{ +	struct drm_bridge_init_priv *priv = test->priv; + +	KUNIT_ASSERT_FALSE(test, priv->destroyed); + +	kunit_device_unregister(test, priv->dev); +	KUNIT_EXPECT_TRUE(test, priv->destroyed); +} + +/* + * Test that a bridge is not freed when the device is destroyed when there + * is still a reference to it, and freed when that reference is put. + */ +static void drm_test_drm_bridge_alloc_get_put(struct kunit *test) +{ +	struct drm_bridge_init_priv *priv = test->priv; + +	KUNIT_ASSERT_FALSE(test, priv->destroyed); + +	drm_bridge_get(&priv->test_bridge->bridge); +	KUNIT_EXPECT_FALSE(test, priv->destroyed); + +	kunit_device_unregister(test, priv->dev); +	KUNIT_EXPECT_FALSE(test, priv->destroyed); + +	drm_bridge_put(&priv->test_bridge->bridge); +	KUNIT_EXPECT_TRUE(test, priv->destroyed); +} + +static struct kunit_case drm_bridge_alloc_tests[] = { +	KUNIT_CASE(drm_test_drm_bridge_alloc_basic), +	KUNIT_CASE(drm_test_drm_bridge_alloc_get_put), +	{ } +}; + +static struct kunit_suite drm_bridge_alloc_test_suite = { +	.name = "drm_bridge_alloc", +	.init = drm_test_bridge_alloc_init, +	.test_cases = drm_bridge_alloc_tests, +}; +  kunit_test_suites(  	&drm_bridge_get_current_state_test_suite,  	&drm_bridge_helper_reset_crtc_test_suite, +	&drm_bridge_alloc_test_suite,  );  MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>"); +MODULE_AUTHOR("Luca Ceresoli <luca.ceresoli@bootlin.com>"); +  MODULE_DESCRIPTION("Kunit test for drm_bridge functions");  MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c index 35cd3405d045..7299fa8971ce 100644 --- a/drivers/gpu/drm/tests/drm_format_helper_test.c +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c @@ -279,9 +279,9 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {  			.dst_pitch = TEST_USE_DEFAULT_PITCH,  			.expected = {  				0xFF, 0x00, -				0x4C, 0x99, -				0x19, 0x66, -				0xE5, 0xB2, +				0x4C, 0x95, +				0x1C, 0x69, +				0xE2, 0xB2,  			},  		},  		.rgb332_result = { @@ -430,9 +430,9 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {  		.gray8_result = {  			.dst_pitch = 5,  			.expected = { -				0x3C, 0x33, 0xC4, 0x00, 0x00, -				0xBB, 0x3C, 0x33, 0x00, 0x00, -				0x34, 0xBB, 0x3C, 0x00, 0x00, +				0x3D, 0x32, 0xC1, 0x00, 0x00, +				0xBA, 0x3D, 0x32, 0x00, 0x00, +				0x34, 0xBA, 0x3D, 0x00, 0x00,  			},  		},  		.rgb332_result = { @@ -735,27 +735,22 @@ static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)  		NULL : &result->dst_pitch;  	drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, ¶ms->clip, -				  &fmtcnv_state, false); +				  &fmtcnv_state);  	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  	buf = dst.vaddr; /* restore original value of buf */ -	drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, -				  &fmtcnv_state, true); +	drm_fb_xrgb8888_to_rgb565be(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, +				    &fmtcnv_state);  	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);  	buf = dst.vaddr;  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB565, &src, &fb, ¶ms->clip, +	drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, ¶ms->clip,  				  &fmtcnv_state); -  	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -795,14 +790,8 @@ static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB1555, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); - +	drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -842,14 +831,8 @@ static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB1555, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); - +	drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -889,14 +872,8 @@ static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGBA5551, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); - +	drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -939,12 +916,7 @@ static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB888, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); - -	KUNIT_EXPECT_FALSE(test, blit_result); +	drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -985,12 +957,8 @@ static void drm_test_fb_xrgb8888_to_bgr888(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, &result->dst_pitch, DRM_FORMAT_BGR888, &src, &fb, ¶ms->clip, +	drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip,  				  &fmtcnv_state); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -1030,14 +998,8 @@ static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB8888, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); - +	drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -1077,12 +1039,7 @@ static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB2101010, &src, &fb, -				  ¶ms->clip, &fmtcnv_state); - -	KUNIT_EXPECT_FALSE(test, blit_result); +	drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -1122,14 +1079,8 @@ static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB2101010, &src, &fb, -				  ¶ms->clip, &fmtcnv_state); - +	drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -1202,23 +1153,15 @@ static void drm_test_fb_swab(struct kunit *test)  	buf = dst.vaddr; /* restore original value of buf */  	memset(buf, 0, dst_size); -	int blit_result; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888 | DRM_FORMAT_BIG_ENDIAN, -				  &src, &fb, ¶ms->clip, &fmtcnv_state); +	drm_fb_swab(&dst, dst_pitch, &src, &fb, ¶ms->clip, false, &fmtcnv_state);  	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  	buf = dst.vaddr;  	memset(buf, 0, dst_size); -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_BGRX8888, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); +	drm_fb_xrgb8888_to_bgrx8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  	buf = dst.vaddr; @@ -1229,11 +1172,8 @@ static void drm_test_fb_swab(struct kunit *test)  	mock_format.format |= DRM_FORMAT_BIG_ENDIAN;  	fb.format = &mock_format; -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); +	drm_fb_swab(&dst, dst_pitch, &src, &fb, ¶ms->clip, false, &fmtcnv_state);  	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -1266,14 +1206,8 @@ static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)  	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?  		NULL : &result->dst_pitch; -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ABGR8888, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); - +	drm_fb_xrgb8888_to_abgr8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -1306,14 +1240,8 @@ static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)  	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?  		NULL : &result->dst_pitch; -	int blit_result = 0; - -	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XBGR8888, &src, &fb, ¶ms->clip, -				  &fmtcnv_state); - +	drm_fb_xrgb8888_to_xbgr8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);  	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); - -	KUNIT_EXPECT_FALSE(test, blit_result);  	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);  } @@ -1407,147 +1335,6 @@ static void drm_test_fb_clip_offset(struct kunit *test)  	KUNIT_EXPECT_EQ(test, offset, params->expected_offset);  } -struct fb_build_fourcc_list_case { -	const char *name; -	u32 native_fourccs[TEST_BUF_SIZE]; -	size_t native_fourccs_size; -	u32 expected[TEST_BUF_SIZE]; -	size_t expected_fourccs_size; -}; - -static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = { -	{ -		.name = "no native formats", -		.native_fourccs = { }, -		.native_fourccs_size = 0, -		.expected = { DRM_FORMAT_XRGB8888 }, -		.expected_fourccs_size = 1, -	}, -	{ -		.name = "XRGB8888 as native format", -		.native_fourccs = { DRM_FORMAT_XRGB8888 }, -		.native_fourccs_size = 1, -		.expected = { DRM_FORMAT_XRGB8888 }, -		.expected_fourccs_size = 1, -	}, -	{ -		.name = "remove duplicates", -		.native_fourccs = { -			DRM_FORMAT_XRGB8888, -			DRM_FORMAT_XRGB8888, -			DRM_FORMAT_RGB888, -			DRM_FORMAT_RGB888, -			DRM_FORMAT_RGB888, -			DRM_FORMAT_XRGB8888, -			DRM_FORMAT_RGB888, -			DRM_FORMAT_RGB565, -			DRM_FORMAT_RGB888, -			DRM_FORMAT_XRGB8888, -			DRM_FORMAT_RGB565, -			DRM_FORMAT_RGB565, -			DRM_FORMAT_XRGB8888, -		}, -		.native_fourccs_size = 11, -		.expected = { -			DRM_FORMAT_XRGB8888, -			DRM_FORMAT_RGB888, -			DRM_FORMAT_RGB565, -		}, -		.expected_fourccs_size = 3, -	}, -	{ -		.name = "convert alpha formats", -		.native_fourccs = { -			DRM_FORMAT_ARGB1555, -			DRM_FORMAT_ABGR1555, -			DRM_FORMAT_RGBA5551, -			DRM_FORMAT_BGRA5551, -			DRM_FORMAT_ARGB8888, -			DRM_FORMAT_ABGR8888, -			DRM_FORMAT_RGBA8888, -			DRM_FORMAT_BGRA8888, -			DRM_FORMAT_ARGB2101010, -			DRM_FORMAT_ABGR2101010, -			DRM_FORMAT_RGBA1010102, -			DRM_FORMAT_BGRA1010102, -		}, -		.native_fourccs_size = 12, -		.expected = { -			DRM_FORMAT_XRGB1555, -			DRM_FORMAT_XBGR1555, -			DRM_FORMAT_RGBX5551, -			DRM_FORMAT_BGRX5551, -			DRM_FORMAT_XRGB8888, -			DRM_FORMAT_XBGR8888, -			DRM_FORMAT_RGBX8888, -			DRM_FORMAT_BGRX8888, -			DRM_FORMAT_XRGB2101010, -			DRM_FORMAT_XBGR2101010, -			DRM_FORMAT_RGBX1010102, -			DRM_FORMAT_BGRX1010102, -		}, -		.expected_fourccs_size = 12, -	}, -	{ -		.name = "random formats", -		.native_fourccs = { -			DRM_FORMAT_Y212, -			DRM_FORMAT_ARGB1555, -			DRM_FORMAT_ABGR16161616F, -			DRM_FORMAT_C8, -			DRM_FORMAT_BGR888, -			DRM_FORMAT_XRGB1555, -			DRM_FORMAT_RGBA5551, -			DRM_FORMAT_BGR565_A8, -			DRM_FORMAT_R10, -			DRM_FORMAT_XYUV8888, -		}, -		.native_fourccs_size = 10, -		.expected = { -			DRM_FORMAT_Y212, -			DRM_FORMAT_XRGB1555, -			DRM_FORMAT_ABGR16161616F, -			DRM_FORMAT_C8, -			DRM_FORMAT_BGR888, -			DRM_FORMAT_RGBX5551, -			DRM_FORMAT_BGR565_A8, -			DRM_FORMAT_R10, -			DRM_FORMAT_XYUV8888, -			DRM_FORMAT_XRGB8888, -		}, -		.expected_fourccs_size = 10, -	}, -}; - -static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case *t, char *desc) -{ -	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); -} - -KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc); - -static void drm_test_fb_build_fourcc_list(struct kunit *test) -{ -	const struct fb_build_fourcc_list_case *params = test->param_value; -	u32 fourccs_out[TEST_BUF_SIZE] = {0}; -	size_t nfourccs_out; -	struct drm_device *drm; -	struct device *dev; - -	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); - -	nfourccs_out = drm_fb_build_fourcc_list(drm, params->native_fourccs, -						params->native_fourccs_size, -						fourccs_out, TEST_BUF_SIZE); - -	KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size); -	KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE); -} -  struct fb_memcpy_case {  	const char *name;  	u32 format; @@ -1910,12 +1697,8 @@ static void drm_test_fb_memcpy(struct kunit *test)  		memset(buf[i], 0, dst_size[i]);  	} -	int blit_result; - -	blit_result = drm_fb_blit(dst, dst_pitches, params->format, src, &fb, ¶ms->clip, -				  &fmtcnv_state); +	drm_fb_memcpy(dst, dst_pitches, src, &fb, ¶ms->clip); -	KUNIT_EXPECT_FALSE(test, blit_result);  	for (size_t i = 0; i < fb.format->num_planes; i++) {  		expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);  		KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i], @@ -1940,7 +1723,6 @@ static struct kunit_case drm_format_helper_test_cases[] = {  	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params),  	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params),  	KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params), -	KUNIT_CASE_PARAM(drm_test_fb_build_fourcc_list, fb_build_fourcc_list_gen_params),  	KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_gen_params),  	{}  }; diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 6ea04cc8f324..9b8e01e8cd91 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -363,6 +363,7 @@ struct drm_framebuffer_test_priv {  static struct drm_framebuffer *fb_create_mock(struct drm_device *dev,  					      struct drm_file *file_priv, +					      const struct drm_format_info *info,  					      const struct drm_mode_fb_cmd2 *mode_cmd)  {  	struct drm_framebuffer_test_priv *priv = container_of(dev, typeof(*priv), dev); diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c index 7ffd666753b1..8bd412735000 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -33,7 +33,7 @@ struct drm_atomic_helper_connector_hdmi_priv {  	struct drm_encoder encoder;  	struct drm_connector connector; -	const char *current_edid; +	const void *current_edid;  	size_t current_edid_len;  }; @@ -56,7 +56,7 @@ static struct drm_display_mode *find_preferred_mode(struct drm_connector *connec  }  static int set_connector_edid(struct kunit *test, struct drm_connector *connector, -			      const char *edid, size_t edid_len) +			      const void *edid, size_t edid_len)  {  	struct drm_atomic_helper_connector_hdmi_priv *priv =  		connector_to_priv(connector); @@ -89,15 +89,15 @@ static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {  };  static enum drm_mode_status -reject_100MHz_connector_tmds_char_rate_valid(const struct drm_connector *connector, +reject_100mhz_connector_tmds_char_rate_valid(const struct drm_connector *connector,  					     const struct drm_display_mode *mode,  					     unsigned long long tmds_rate)  {  	return (tmds_rate > 100ULL * 1000 * 1000) ? MODE_BAD : MODE_OK;  } -static const struct drm_connector_hdmi_funcs reject_100_MHz_connector_hdmi_funcs = { -	.tmds_char_rate_valid	= reject_100MHz_connector_tmds_char_rate_valid, +static const struct drm_connector_hdmi_funcs reject_100mhz_connector_hdmi_funcs = { +	.tmds_char_rate_valid	= reject_100mhz_connector_tmds_char_rate_valid,  };  static int dummy_connector_get_modes(struct drm_connector *connector) @@ -140,10 +140,11 @@ static const struct drm_connector_funcs dummy_connector_funcs = {  static  struct drm_atomic_helper_connector_hdmi_priv * -drm_kunit_helper_connector_hdmi_init_funcs(struct kunit *test, -					   unsigned int formats, -					   unsigned int max_bpc, -					   const struct drm_connector_hdmi_funcs *hdmi_funcs) +__connector_hdmi_init(struct kunit *test, +		      unsigned int formats, +		      unsigned int max_bpc, +		      const struct drm_connector_hdmi_funcs *hdmi_funcs, +		      const void *edid_data, size_t edid_len)  {  	struct drm_atomic_helper_connector_hdmi_priv *priv;  	struct drm_connector *conn; @@ -182,6 +183,8 @@ drm_kunit_helper_connector_hdmi_init_funcs(struct kunit *test,  	enc->possible_crtcs = drm_crtc_mask(priv->crtc);  	conn = &priv->connector; +	conn->ycbcr_420_allowed = !!(formats & BIT(HDMI_COLORSPACE_YUV420)); +  	ret = drmm_connector_hdmi_init(drm, conn,  				       "Vendor", "Product",  				       &dummy_connector_funcs, @@ -197,29 +200,28 @@ drm_kunit_helper_connector_hdmi_init_funcs(struct kunit *test,  	drm_mode_config_reset(drm); +	if (edid_data && edid_len) { +		ret = set_connector_edid(test, &priv->connector, edid_data, edid_len); +		KUNIT_ASSERT_GT(test, ret, 0); +	} +  	return priv;  } +#define drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, formats, max_bpc, funcs, edid) \ +	__connector_hdmi_init(test, formats, max_bpc, funcs, edid, ARRAY_SIZE(edid)) +  static  struct drm_atomic_helper_connector_hdmi_priv *  drm_kunit_helper_connector_hdmi_init(struct kunit *test,  				     unsigned int formats,  				     unsigned int max_bpc)  { -	struct drm_atomic_helper_connector_hdmi_priv *priv; -	int ret; - -	priv = drm_kunit_helper_connector_hdmi_init_funcs(test, -							  formats, max_bpc, -							  &dummy_connector_hdmi_funcs); -	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); - -	ret = set_connector_edid(test, &priv->connector, -				 test_edid_hdmi_1080p_rgb_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); - -	return priv; +	return drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				formats, +				max_bpc, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_max_200mhz);  }  /* @@ -414,7 +416,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)  	ret = drm_atomic_check_only(state);  	KUNIT_ASSERT_EQ(test, ret, 0); -	conn_state = drm_atomic_get_connector_state(state, conn); +	conn_state = drm_atomic_get_new_connector_state(state, conn);  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);  	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range); @@ -474,7 +476,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)  	ret = drm_atomic_check_only(state);  	KUNIT_ASSERT_EQ(test, ret, 0); -	conn_state = drm_atomic_get_connector_state(state, conn); +	conn_state = drm_atomic_get_new_connector_state(state, conn);  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);  	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range); @@ -533,7 +535,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)  	ret = drm_atomic_check_only(state);  	KUNIT_ASSERT_EQ(test, ret, 0); -	conn_state = drm_atomic_get_connector_state(state, conn); +	conn_state = drm_atomic_get_new_connector_state(state, conn);  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);  	KUNIT_ASSERT_EQ(test, @@ -595,7 +597,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)  	ret = drm_atomic_check_only(state);  	KUNIT_ASSERT_EQ(test, ret, 0); -	conn_state = drm_atomic_get_connector_state(state, conn); +	conn_state = drm_atomic_get_new_connector_state(state, conn);  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);  	KUNIT_ASSERT_EQ(test, @@ -658,7 +660,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)  	ret = drm_atomic_check_only(state);  	KUNIT_ASSERT_EQ(test, ret, 0); -	conn_state = drm_atomic_get_connector_state(state, conn); +	conn_state = drm_atomic_get_new_connector_state(state, conn);  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);  	KUNIT_ASSERT_EQ(test, @@ -720,7 +722,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te  	ret = drm_atomic_check_only(state);  	KUNIT_ASSERT_EQ(test, ret, 0); -	conn_state = drm_atomic_get_connector_state(state, conn); +	conn_state = drm_atomic_get_new_connector_state(state, conn);  	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);  	KUNIT_ASSERT_EQ(test, @@ -734,6 +736,107 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te  }  /* + * Test that for an HDMI connector, with an HDMI monitor, we will + * get a limited RGB Quantization Range with a YUV420 mode, no + * matter what the value of the Broadcast RGB property is set to. + */ +static void drm_test_check_broadcast_rgb_cea_mode_yuv420(struct kunit *test) +{ +	struct drm_atomic_helper_connector_hdmi_priv *priv; +	enum drm_hdmi_broadcast_rgb broadcast_rgb; +	struct drm_modeset_acquire_ctx ctx; +	struct drm_connector_state *conn_state; +	struct drm_atomic_state *state; +	struct drm_display_mode *mode; +	struct drm_connector *conn; +	struct drm_device *drm; +	struct drm_crtc *crtc; +	int ret; + +	broadcast_rgb = *(enum drm_hdmi_broadcast_rgb *)test->param_value; + +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB) | +				BIT(HDMI_COLORSPACE_YUV420), +				8, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz); +	KUNIT_ASSERT_NOT_NULL(test, priv); + +	drm = &priv->drm; +	crtc = priv->crtc; +	conn = &priv->connector; +	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); + +	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 95); +	KUNIT_ASSERT_NOT_NULL(test, mode); + +	drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: +	ret = drm_kunit_helper_enable_crtc_connector(test, drm, crtc, conn, +						     mode, &ctx); +	if (ret == -EDEADLK) { +		ret = drm_modeset_backoff(&ctx); +		if (!ret) +			goto retry_conn_enable; +	} +	KUNIT_ASSERT_EQ(test, ret, 0); + +	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_conn_state: +	conn_state = drm_atomic_get_connector_state(state, conn); +	if (PTR_ERR(conn_state) == -EDEADLK) { +		drm_atomic_state_clear(state); +		ret = drm_modeset_backoff(&ctx); +		if (!ret) +			goto retry_conn_state; +	} +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + +	conn_state->hdmi.broadcast_rgb = broadcast_rgb; + +	ret = drm_atomic_check_only(state); +	if (ret == -EDEADLK) { +		drm_atomic_state_clear(state); +		ret = drm_modeset_backoff(&ctx); +		if (!ret) +			goto retry_conn_state; +	} +	KUNIT_ASSERT_EQ(test, ret, 0); + +	conn_state = drm_atomic_get_new_connector_state(state, conn); +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + +	KUNIT_ASSERT_EQ(test, conn_state->hdmi.broadcast_rgb, broadcast_rgb); +	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV420); + +	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range); + +	drm_modeset_drop_locks(&ctx); +	drm_modeset_acquire_fini(&ctx); +} + +static const enum drm_hdmi_broadcast_rgb check_broadcast_rgb_cea_mode_yuv420_tests[] = { +	DRM_HDMI_BROADCAST_RGB_AUTO, +	DRM_HDMI_BROADCAST_RGB_FULL, +	DRM_HDMI_BROADCAST_RGB_LIMITED, +}; + +static void +check_broadcast_rgb_cea_mode_yuv420_desc(const enum drm_hdmi_broadcast_rgb *broadcast_rgb, +					 char *desc) +{ +	sprintf(desc, "%s", drm_hdmi_connector_get_broadcast_rgb_name(*broadcast_rgb)); +} + +KUNIT_ARRAY_PARAM(check_broadcast_rgb_cea_mode_yuv420, +		  check_broadcast_rgb_cea_mode_yuv420_tests, +		  check_broadcast_rgb_cea_mode_yuv420_desc); + +/*   * Test that if we change the maximum bpc property to a different value,   * we trigger a mode change on the connector's CRTC, which will in turn   * disable/enable the connector. @@ -752,19 +855,16 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    10); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				10, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	preferred = find_preferred_mode(conn);  	KUNIT_ASSERT_NOT_NULL(test, preferred); @@ -831,19 +931,16 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    10); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				10, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	preferred = find_preferred_mode(conn);  	KUNIT_ASSERT_NOT_NULL(test, preferred); @@ -905,21 +1002,18 @@ static void drm_test_check_output_bpc_dvi(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB) | -						    BIT(HDMI_COLORSPACE_YUV422) | -						    BIT(HDMI_COLORSPACE_YUV444), -						    12); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB) | +				BIT(HDMI_COLORSPACE_YUV422) | +				BIT(HDMI_COLORSPACE_YUV444), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_dvi_1080p);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_dvi_1080p, -				 ARRAY_SIZE(test_edid_dvi_1080p)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	info = &conn->display_info;  	KUNIT_ASSERT_FALSE(test, info->is_hdmi); @@ -959,19 +1053,16 @@ static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    8); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				8, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	preferred = find_preferred_mode(conn);  	KUNIT_ASSERT_NOT_NULL(test, preferred);  	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); @@ -1011,19 +1102,16 @@ static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    10); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				10, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	preferred = find_preferred_mode(conn);  	KUNIT_ASSERT_NOT_NULL(test, preferred);  	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); @@ -1063,19 +1151,16 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    12); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	preferred = find_preferred_mode(conn);  	KUNIT_ASSERT_NOT_NULL(test, preferred);  	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); @@ -1168,7 +1253,7 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)   * Then we will pick the latter, and the computed TMDS character rate   * will be equal to 1.25 times the mode pixel clock.   */ -static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) +static void drm_test_check_max_tmds_rate_bpc_fallback_rgb(struct kunit *test)  {  	struct drm_atomic_helper_connector_hdmi_priv *priv;  	struct drm_modeset_acquire_ctx ctx; @@ -1181,19 +1266,16 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    12); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	info = &conn->display_info;  	KUNIT_ASSERT_TRUE(test, info->is_hdmi);  	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); @@ -1229,6 +1311,80 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)  /*   * Test that if: + * - We have an HDMI connector and a display supporting both RGB and YUV420 + * - The chosen mode can be supported in YUV420 output format only + * - The chosen mode has a TMDS character rate higher than the display + *   supports in YUV420/12bpc + * - The chosen mode has a TMDS character rate lower than the display + *   supports in YUV420/10bpc. + * + * Then we will pick the latter, and the computed TMDS character rate + * will be equal to 1.25 * 0.5 times the mode pixel clock. + */ +static void drm_test_check_max_tmds_rate_bpc_fallback_yuv420(struct kunit *test) +{ +	struct drm_atomic_helper_connector_hdmi_priv *priv; +	struct drm_modeset_acquire_ctx ctx; +	struct drm_connector_state *conn_state; +	struct drm_display_info *info; +	struct drm_display_mode *yuv420_only_mode; +	unsigned long long rate; +	struct drm_connector *conn; +	struct drm_device *drm; +	struct drm_crtc *crtc; +	int ret; + +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB) | +				BIT(HDMI_COLORSPACE_YUV420), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz); +	KUNIT_ASSERT_NOT_NULL(test, priv); + +	drm = &priv->drm; +	crtc = priv->crtc; +	conn = &priv->connector; +	info = &conn->display_info; +	KUNIT_ASSERT_TRUE(test, info->is_hdmi); +	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); +	KUNIT_ASSERT_TRUE(test, conn->ycbcr_420_allowed); + +	yuv420_only_mode = drm_kunit_display_mode_from_cea_vic(test, drm, 95); +	KUNIT_ASSERT_NOT_NULL(test, yuv420_only_mode); +	KUNIT_ASSERT_TRUE(test, drm_mode_is_420_only(info, yuv420_only_mode)); + +	rate = drm_hdmi_compute_mode_clock(yuv420_only_mode, 12, HDMI_COLORSPACE_YUV420); +	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); + +	rate = drm_hdmi_compute_mode_clock(yuv420_only_mode, 10, HDMI_COLORSPACE_YUV420); +	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + +	drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: +	ret = drm_kunit_helper_enable_crtc_connector(test, drm, crtc, conn, +						     yuv420_only_mode, &ctx); +	if (ret == -EDEADLK) { +		ret = drm_modeset_backoff(&ctx); +		if (!ret) +			goto retry_conn_enable; +	} +	KUNIT_EXPECT_EQ(test, ret, 0); + +	conn_state = conn->state; +	KUNIT_ASSERT_NOT_NULL(test, conn_state); + +	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10); +	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV420); +	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, yuv420_only_mode->clock * 625); + +	drm_modeset_drop_locks(&ctx); +	drm_modeset_acquire_fini(&ctx); +} + +/* + * Test that if:   * - We have an HDMI connector supporting both RGB and YUV422 and up to   *   12 bpc   * - The chosen mode has a TMDS character rate higher than the display @@ -1240,7 +1396,7 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)   * Then we will prefer to keep the RGB format with a lower bpc over   * picking YUV422.   */ -static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) +static void drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv422(struct kunit *test)  {  	struct drm_atomic_helper_connector_hdmi_priv *priv;  	struct drm_modeset_acquire_ctx ctx; @@ -1253,21 +1409,18 @@ static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB) | -						    BIT(HDMI_COLORSPACE_YUV422) | -						    BIT(HDMI_COLORSPACE_YUV444), -						    12); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB) | +				BIT(HDMI_COLORSPACE_YUV422) | +				BIT(HDMI_COLORSPACE_YUV444), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	info = &conn->display_info;  	KUNIT_ASSERT_TRUE(test, info->is_hdmi);  	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); @@ -1304,6 +1457,170 @@ static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)  }  /* + * Test that if: + * - We have an HDMI connector supporting both RGB and YUV420 and up to + *   12 bpc + * - The chosen mode has a TMDS character rate higher than the display + *   supports in RGB/10bpc but lower than the display supports in + *   RGB/8bpc + * - The chosen mode has a TMDS character rate lower than the display + *   supports in YUV420/12bpc. + * + * Then we will prefer to keep the RGB format with a lower bpc over + * picking YUV420. + */ +static void drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv420(struct kunit *test) +{ +	struct drm_atomic_helper_connector_hdmi_priv *priv; +	struct drm_modeset_acquire_ctx ctx; +	struct drm_connector_state *conn_state; +	struct drm_display_info *info; +	struct drm_display_mode *preferred; +	unsigned long long rate; +	struct drm_connector *conn; +	struct drm_device *drm; +	struct drm_crtc *crtc; +	int ret; + +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB) | +				BIT(HDMI_COLORSPACE_YUV420), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz); +	KUNIT_ASSERT_NOT_NULL(test, priv); + +	drm = &priv->drm; +	crtc = priv->crtc; +	conn = &priv->connector; +	info = &conn->display_info; +	KUNIT_ASSERT_TRUE(test, info->is_hdmi); +	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); +	KUNIT_ASSERT_TRUE(test, conn->ycbcr_420_allowed); + +	preferred = find_preferred_mode(conn); +	KUNIT_ASSERT_NOT_NULL(test, preferred); +	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); +	KUNIT_ASSERT_TRUE(test, drm_mode_is_420_also(info, preferred)); + +	rate = drm_hdmi_compute_mode_clock(preferred, 8, HDMI_COLORSPACE_RGB); +	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + +	rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB); +	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); + +	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV420); +	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + +	drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: +	ret = drm_kunit_helper_enable_crtc_connector(test, drm, crtc, conn, +						     preferred, &ctx); +	if (ret == -EDEADLK) { +		ret = drm_modeset_backoff(&ctx); +		if (!ret) +			goto retry_conn_enable; +	} +	KUNIT_EXPECT_EQ(test, ret, 0); + +	conn_state = conn->state; +	KUNIT_ASSERT_NOT_NULL(test, conn_state); + +	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); +	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + +	drm_modeset_drop_locks(&ctx); +	drm_modeset_acquire_fini(&ctx); +} + +/* + * Test that if a driver supports only RGB, but the chosen mode can be + * supported by the screen only in YUV420 output format, we end up with + * unsuccessful fallback attempts. + */ +static void drm_test_check_driver_unsupported_fallback_yuv420(struct kunit *test) +{ +	struct drm_atomic_helper_connector_hdmi_priv *priv; +	struct drm_modeset_acquire_ctx ctx; +	struct drm_connector_state *conn_state; +	struct drm_crtc_state *crtc_state; +	struct drm_atomic_state *state; +	struct drm_display_info *info; +	struct drm_display_mode *preferred, *yuv420_only_mode; +	struct drm_connector *conn; +	struct drm_device *drm; +	struct drm_crtc *crtc; +	int ret; + +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz); +	KUNIT_ASSERT_NOT_NULL(test, priv); + +	drm = &priv->drm; +	crtc = priv->crtc; +	conn = &priv->connector; +	info = &conn->display_info; +	KUNIT_ASSERT_TRUE(test, info->is_hdmi); +	KUNIT_ASSERT_FALSE(test, conn->ycbcr_420_allowed); + +	preferred = find_preferred_mode(conn); +	KUNIT_ASSERT_NOT_NULL(test, preferred); +	KUNIT_ASSERT_FALSE(test, drm_mode_is_420_also(info, preferred)); + +	yuv420_only_mode = drm_kunit_display_mode_from_cea_vic(test, drm, 95); +	KUNIT_ASSERT_NOT_NULL(test, yuv420_only_mode); +	KUNIT_ASSERT_TRUE(test, drm_mode_is_420_only(info, yuv420_only_mode)); + +	drm_modeset_acquire_init(&ctx, 0); + +retry_conn_enable: +	ret = drm_kunit_helper_enable_crtc_connector(test, drm, crtc, conn, +						     preferred, &ctx); +	if (ret == -EDEADLK) { +		ret = drm_modeset_backoff(&ctx); +		if (!ret) +			goto retry_conn_enable; +	} +	KUNIT_EXPECT_EQ(test, ret, 0); + +	conn_state = conn->state; +	KUNIT_ASSERT_NOT_NULL(test, conn_state); +	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + +	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_crtc_state: +	crtc_state = drm_atomic_get_crtc_state(state, crtc); +	if (PTR_ERR(crtc_state) == -EDEADLK) { +		drm_atomic_state_clear(state); +		ret = drm_modeset_backoff(&ctx); +		if (!ret) +			goto retry_crtc_state; +	} +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + +	ret = drm_atomic_set_mode_for_crtc(crtc_state, yuv420_only_mode); +	KUNIT_EXPECT_EQ(test, ret, 0); + +	ret = drm_atomic_check_only(state); +	if (ret == -EDEADLK) { +		drm_atomic_state_clear(state); +		ret = drm_modeset_backoff(&ctx); +		if (!ret) +			goto retry_crtc_state; +	} +	KUNIT_ASSERT_LT(test, ret, 0); + +	drm_modeset_drop_locks(&ctx); +	drm_modeset_acquire_fini(&ctx); +} + +/*   * Test that if a driver and screen supports RGB and YUV formats, and we   * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could   * have had a higher bpc. @@ -1321,20 +1638,17 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB) | -						    BIT(HDMI_COLORSPACE_YUV422) | -						    BIT(HDMI_COLORSPACE_YUV444), -						    12); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB) | +				BIT(HDMI_COLORSPACE_YUV422) | +				BIT(HDMI_COLORSPACE_YUV444), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	info = &conn->display_info;  	KUNIT_ASSERT_TRUE(test, info->is_hdmi);  	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); @@ -1388,19 +1702,16 @@ static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    12); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	info = &conn->display_info;  	KUNIT_ASSERT_TRUE(test, info->is_hdmi);  	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); @@ -1458,21 +1769,18 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB) | -						    BIT(HDMI_COLORSPACE_YUV422) | -						    BIT(HDMI_COLORSPACE_YUV444), -						    12); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB) | +				BIT(HDMI_COLORSPACE_YUV422) | +				BIT(HDMI_COLORSPACE_YUV444), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	info = &conn->display_info;  	KUNIT_ASSERT_TRUE(test, info->is_hdmi);  	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); @@ -1531,19 +1839,16 @@ static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    8); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				8, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	info = &conn->display_info;  	KUNIT_ASSERT_TRUE(test, info->is_hdmi);  	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); @@ -1594,21 +1899,18 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes  	struct drm_crtc *crtc;  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB) | -						    BIT(HDMI_COLORSPACE_YUV422) | -						    BIT(HDMI_COLORSPACE_YUV444), -						    12); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB) | +				BIT(HDMI_COLORSPACE_YUV422) | +				BIT(HDMI_COLORSPACE_YUV444), +				12, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_max_340mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	drm = &priv->drm;  	crtc = priv->crtc;  	conn = &priv->connector; -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_max_340mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	info = &conn->display_info;  	KUNIT_ASSERT_TRUE(test, info->is_hdmi);  	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); @@ -1704,17 +2006,17 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {  	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),  	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),  	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1), -	/* -	 * TODO: When we'll have YUV output support, we need to check -	 * that the limited range is always set to limited no matter -	 * what the value of Broadcast RGB is. -	 */ +	KUNIT_CASE_PARAM(drm_test_check_broadcast_rgb_cea_mode_yuv420, +			 check_broadcast_rgb_cea_mode_yuv420_gen_params),  	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),  	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),  	KUNIT_CASE(drm_test_check_disable_connector),  	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate), -	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback), -	KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback), +	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback_rgb), +	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback_yuv420), +	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv422), +	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv420), +	KUNIT_CASE(drm_test_check_driver_unsupported_fallback_yuv420),  	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),  	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),  	KUNIT_CASE(drm_test_check_output_bpc_dvi), @@ -1927,28 +2229,20 @@ static void drm_test_check_mode_valid(struct kunit *test)  static void drm_test_check_mode_valid_reject_rate(struct kunit *test)  {  	struct drm_atomic_helper_connector_hdmi_priv *priv; -	struct drm_connector *conn;  	struct drm_display_mode *preferred; -	int ret; -	priv = drm_kunit_helper_connector_hdmi_init_funcs(test, -							  BIT(HDMI_COLORSPACE_RGB), -							  8, -							  &reject_100_MHz_connector_hdmi_funcs); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +					BIT(HDMI_COLORSPACE_RGB), +					8, +					&reject_100mhz_connector_hdmi_funcs, +					test_edid_hdmi_1080p_rgb_max_200mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv); -	conn = &priv->connector; - -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_max_200mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	/*  	 * Unlike the drm_test_check_mode_valid() here 1080p is rejected, but  	 * 480p is allowed.  	 */ -	preferred = find_preferred_mode(conn); +	preferred = find_preferred_mode(&priv->connector);  	KUNIT_ASSERT_NOT_NULL(test, preferred);  	KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640);  	KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480); @@ -1966,12 +2260,14 @@ static void drm_test_check_mode_valid_reject(struct kunit *test)  	struct drm_atomic_helper_connector_hdmi_priv *priv;  	struct drm_connector *conn;  	struct drm_display_mode *preferred; +	unsigned char no_edid[] = {};  	int ret; -	priv = drm_kunit_helper_connector_hdmi_init_funcs(test, -							  BIT(HDMI_COLORSPACE_RGB), -							  8, -							  &reject_connector_hdmi_funcs); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +					BIT(HDMI_COLORSPACE_RGB), +					8, +					&reject_connector_hdmi_funcs, +					no_edid);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	conn = &priv->connector; @@ -1996,20 +2292,15 @@ static void drm_test_check_mode_valid_reject_max_clock(struct kunit *test)  	struct drm_atomic_helper_connector_hdmi_priv *priv;  	struct drm_connector *conn;  	struct drm_display_mode *preferred; -	int ret; -	priv = drm_kunit_helper_connector_hdmi_init(test, -						    BIT(HDMI_COLORSPACE_RGB), -						    8); +	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, +				BIT(HDMI_COLORSPACE_RGB), +				8, +				&dummy_connector_hdmi_funcs, +				test_edid_hdmi_1080p_rgb_max_100mhz);  	KUNIT_ASSERT_NOT_NULL(test, priv);  	conn = &priv->connector; - -	ret = set_connector_edid(test, conn, -				 test_edid_hdmi_1080p_rgb_max_100mhz, -				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_100mhz)); -	KUNIT_ASSERT_GT(test, ret, 0); -  	KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 100 * 1000);  	preferred = find_preferred_mode(conn); diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h index 6358397a5d7a..c59c8528a3f7 100644 --- a/drivers/gpu/drm/tests/drm_kunit_edid.h +++ b/drivers/gpu/drm/tests/drm_kunit_edid.h @@ -46,6 +46,13 @@   *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz   *     Dummy Descriptor:   * Checksum: 0xab + * + * ---------------- + * + * edid-decode 1.30.0-5367 + * edid-decode SHA: 41ebf7135691 2025-05-01 10:19:22 + * + * EDID conformity: PASS   */  static const unsigned char test_edid_dvi_1080p[] = {  	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, @@ -62,6 +69,10 @@ static const unsigned char test_edid_dvi_1080p[] = {  };  /* + * + * This edid is intentionally broken with the 100MHz limit. It's meant + * to be used only with tests in unusual situations. + *   * edid-decode (hex):   *   * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 @@ -73,14 +84,14 @@ static const unsigned char test_edid_dvi_1080p[] = {   * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92   * - * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c - * 00 12 34 00 14 20 00 00 00 00 00 00 00 00 00 00 + * 02 03 15 81 e3 05 00 20 41 10 e2 00 4a 67 03 0c + * 00 12 34 00 14 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e4 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10   *   * ----------------   * @@ -135,8 +146,19 @@ static const unsigned char test_edid_dvi_1080p[] = {   *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:   *     Source physical address: 1.2.3.4   *     Maximum TMDS clock: 100 MHz - *     Extended HDMI video details: - * Checksum: 0xe4  Unused space in Extension Block: 100 bytes + * Checksum: 0x10  Unused space in Extension Block: 106 bytes + * + * ---------------- + * + * edid-decode 1.30.0-5367 + * edid-decode SHA: 41ebf7135691 2025-05-01 10:19:22 + * + * Failures: + * + * EDID: + *   CTA-861: The maximum HDMI TMDS clock is 100000 kHz, but one or more video timings go up to 148500 kHz. + * + * EDID conformity: FAIL   */  static const unsigned char test_edid_hdmi_1080p_rgb_max_100mhz[] = {  	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, @@ -147,11 +169,11 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_100mhz[] = {  	0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,  	0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,  	0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, -	0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +	0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,  	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81, -	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c, -	0x00, 0x12, 0x34, 0x00, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, 0x02, 0x03, 0x15, 0x81, +	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x67, 0x03, 0x0c, +	0x00, 0x12, 0x34, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -160,7 +182,7 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_100mhz[] = {  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0xe4 +	0x00, 0x00, 0x00, 0x10  };  /* @@ -175,14 +197,14 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_100mhz[] = {   * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92   * - * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c - * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00 + * 02 03 15 81 e3 05 00 20 41 10 e2 00 4a 67 03 0c + * 00 12 34 00 28 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc   *   * ----------------   * @@ -237,8 +259,14 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_100mhz[] = {   *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:   *     Source physical address: 1.2.3.4   *     Maximum TMDS clock: 200 MHz - *     Extended HDMI video details: - * Checksum: 0xd0  Unused space in Extension Block: 100 bytes + * Checksum: 0xfc  Unused space in Extension Block: 106 bytes + * + * ---------------- + * + * edid-decode 1.30.0-5367 + * edid-decode SHA: 41ebf7135691 2025-05-01 10:19:22 + * + * EDID conformity: PASS   */  static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {  	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, @@ -249,11 +277,11 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {  	0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,  	0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,  	0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, -	0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +	0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,  	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81, -	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c, -	0x00, 0x12, 0x34, 0x00, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, 0x02, 0x03, 0x15, 0x81, +	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x67, 0x03, 0x0c, +	0x00, 0x12, 0x34, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -262,7 +290,7 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0xd0 +	0x00, 0x00, 0x00, 0xfc  };  /* @@ -277,14 +305,14 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {   * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92   * - * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c - * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00 + * 02 03 15 81 e3 05 00 20 41 10 e2 00 4a 67 03 0c + * 00 12 34 00 44 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0   *   * ----------------   * @@ -339,8 +367,14 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {   *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:   *     Source physical address: 1.2.3.4   *     Maximum TMDS clock: 340 MHz - *     Extended HDMI video details: - * Checksum: 0xd0  Unused space in Extension Block: 100 bytes + * Checksum: 0xe0  Unused space in Extension Block: 106 bytes + * + * ---------------- + * + * edid-decode 1.30.0-5367 + * edid-decode SHA: 41ebf7135691 2025-05-01 10:19:22 + * + * EDID conformity: PASS   */  static const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {  	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, @@ -351,11 +385,11 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {  	0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,  	0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,  	0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, -	0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +	0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,  	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81, -	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c, -	0x00, 0x12, 0x34, 0x00, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, 0x02, 0x03, 0x15, 0x81, +	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x67, 0x03, 0x0c, +	0x00, 0x12, 0x34, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -364,7 +398,7 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0xd0 +	0x00, 0x00, 0x00, 0xe0  };  /* @@ -379,14 +413,14 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {   * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 7a   * - * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c - * 00 12 34 78 28 20 00 00 00 00 00 00 00 00 00 00 + * 02 03 15 b1 e3 05 00 20 41 10 e2 00 ca 67 03 0c + * 00 12 34 78 28 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a8 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d4   *   * ----------------   * @@ -447,8 +481,14 @@ static const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {   *     DC_30bit   *     DC_Y444   *     Maximum TMDS clock: 200 MHz - *     Extended HDMI video details: - * Checksum: 0xa8  Unused space in Extension Block: 100 bytes + * Checksum: 0xd4  Unused space in Extension Block: 106 bytes + * + * ---------------- + * + * edid-decode 1.30.0-5367 + * edid-decode SHA: 41ebf7135691 2025-05-01 10:19:22 + * + * EDID conformity: PASS   */  static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {  	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, @@ -461,9 +501,9 @@ static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {  	0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,  	0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,  	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7a, 0x02, 0x03, 0x1b, 0xb1, -	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c, -	0x00, 0x12, 0x34, 0x78, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7a, 0x02, 0x03, 0x15, 0xb1, +	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x67, 0x03, 0x0c, +	0x00, 0x12, 0x34, 0x78, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -472,7 +512,7 @@ static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0xa8 +	0x00, 0x00, 0x00, 0xd4  };  /* @@ -487,14 +527,14 @@ static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {   * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 8a   * - * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c - * 00 12 34 78 44 20 00 00 00 00 00 00 00 00 00 00 + * 02 03 15 b1 e3 05 00 20 41 10 e2 00 ca 67 03 0c + * 00 12 34 78 44 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8c + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8   *   * ----------------   * @@ -555,8 +595,14 @@ static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {   *     DC_30bit   *     DC_Y444   *     Maximum TMDS clock: 340 MHz - *     Extended HDMI video details: - * Checksum: 0x8c  Unused space in Extension Block: 100 bytes + * Checksum: 0xb8  Unused space in Extension Block: 106 bytes + * + * ---------------- + * + * edid-decode 1.30.0-5367 + * edid-decode SHA: 41ebf7135691 2025-05-01 10:19:22 + * + * EDID conformity: PASS   */  static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz[] = {  	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, @@ -569,18 +615,250 @@ static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz[] = {  	0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,  	0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,  	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a, 0x02, 0x03, 0x1b, 0xb1, -	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c, -	0x00, 0x12, 0x34, 0x78, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a, 0x02, 0x03, 0x15, 0xb1, +	0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x67, 0x03, 0x0c, +	0x00, 0x12, 0x34, 0x78, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0xb8 +}; + +/* + * Max resolution: + * - 1920x1080@60Hz with RGB, YUV444, YUV422 + * - 3840x2160@30Hz with YUV420 only + * Max BPC:         16 for all modes + * Max TMDS clock:  200 MHz + * + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 34 00 00 00 00 00 + * ff 23 01 03 80 60 36 78 0f ee 91 a3 54 4c 99 26 + * 0f 50 54 20 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c + * 45 00 c0 1c 32 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 18 + * 55 18 5e 11 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 bb + * + * 02 03 29 31 42 90 5f 6c 03 0c 00 10 00 78 28 20 + * 00 00 01 03 6d d8 5d c4 01 28 80 07 00 00 00 00 + * 00 00 e3 0f 00 00 e2 0e 5f 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ca + * + * ---------------- + * + * Block 0, Base EDID: + *   EDID Structure Version & Revision: 1.3 + *   Vendor & Product Identification: + *     Manufacturer: LNX + *     Model: 52 + *     Model year: 2025 + *   Basic Display Parameters & Features: + *     Digital display + *     Maximum image size: 96 cm x 54 cm + *     Gamma: 2.20 + *     RGB color display + *     Default (sRGB) color space is primary color space + *     First detailed timing is the preferred timing + *     Supports GTF timings within operating range + *   Color Characteristics: + *     Red  : 0.6396, 0.3300 + *     Green: 0.2998, 0.5996 + *     Blue : 0.1503, 0.0595 + *     White: 0.3125, 0.3291 + *   Established Timings I & II: + *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz + *   Standard Timings: none + *   Detailed Timing Descriptors: + *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (960 mm x 540 mm) + *                  Hfront   88 Hsync  44 Hback  148 Hpol P + *                  Vfront    4 Vsync   5 Vback   36 Vpol P + *     Display Product Name: 'Test EDID' + *     Display Range Limits: + *       Monitor ranges (GTF): 24-85 Hz V, 24-94 kHz H, max dotclock 170 MHz + *     Dummy Descriptor: + *   Extension blocks: 1 + * Checksum: 0xbb + * + * ---------------- + * + * Block 1, CTA-861 Extension Block: + *   Revision: 3 + *   Supports YCbCr 4:4:4 + *   Supports YCbCr 4:2:2 + *   Native detailed modes: 1 + *   Video Data Block: + *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (native) + *     VIC  95:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz + *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03: + *     Source physical address: 1.0.0.0 + *     DC_48bit + *     DC_36bit + *     DC_30bit + *     DC_Y444 + *     Maximum TMDS clock: 200 MHz + *     Extended HDMI video details: + *   Vendor-Specific Data Block (HDMI Forum), OUI C4-5D-D8: + *     Version: 1 + *     Maximum TMDS Character Rate: 200 MHz + *     SCDC Present + *     Supports 16-bits/component Deep Color 4:2:0 Pixel Encoding + *     Supports 12-bits/component Deep Color 4:2:0 Pixel Encoding + *     Supports 10-bits/component Deep Color 4:2:0 Pixel Encoding + *   YCbCr 4:2:0 Capability Map Data Block: + *     Empty Capability Map + *   YCbCr 4:2:0 Video Data Block: + *     VIC  95:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz + * Checksum: 0xca + */ +static const unsigned char test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz[] = { +	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x34, 0x00, +	0x00, 0x00, 0x00, 0x00, 0xff, 0x23, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78, +	0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54, 0x20, +	0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, +	0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e, +	0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, +	0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, +	0x55, 0x18, 0x5e, 0x11, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbb, 0x02, 0x03, 0x29, 0x31, +	0x42, 0x90, 0x5f, 0x6c, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x78, 0x28, 0x20, +	0x00, 0x00, 0x01, 0x03, 0x6d, 0xd8, 0x5d, 0xc4, 0x01, 0x28, 0x80, 0x07, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x0f, 0x00, 0x00, 0xe2, 0x0e, +	0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0xca +}; + +/* + * Max resolution: 3840x2160@30Hz with RGB, YUV444, YUV422, YUV420 + * Max BPC:        16 for all modes + * Max TMDS clock: 340 MHz + * + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 34 00 00 00 00 00 + * ff 23 01 03 80 60 36 78 0f ee 91 a3 54 4c 99 26 + * 0f 50 54 20 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 04 74 00 30 f2 70 5a 80 b0 58 + * 8a 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 18 + * 55 18 5e 22 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ce + * + * 02 03 27 31 41 5f 6c 03 0c 00 10 00 78 44 20 00 + * 00 01 03 6d d8 5d c4 01 44 80 07 00 00 00 00 00 + * 00 e3 0f 01 00 e1 0e 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 84 + * + * ---------------- + * + * Block 0, Base EDID: + *   EDID Structure Version & Revision: 1.3 + *   Vendor & Product Identification: + *     Manufacturer: LNX + *     Model: 52 + *     Model year: 2025 + *   Basic Display Parameters & Features: + *     Digital display + *     Maximum image size: 96 cm x 54 cm + *     Gamma: 2.20 + *     RGB color display + *     Default (sRGB) color space is primary color space + *     First detailed timing is the preferred timing + *     Supports GTF timings within operating range + *   Color Characteristics: + *     Red  : 0.6396, 0.3300 + *     Green: 0.2998, 0.5996 + *     Blue : 0.1503, 0.0595 + *     White: 0.3125, 0.3291 + *   Established Timings I & II: + *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz + *   Standard Timings: none + *   Detailed Timing Descriptors: + *     DTD 1:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz (1600 mm x 900 mm) + *                  Hfront  176 Hsync  88 Hback  296 Hpol P + *                  Vfront    8 Vsync  10 Vback   72 Vpol P + *     Display Product Name: 'Test EDID' + *     Display Range Limits: + *       Monitor ranges (GTF): 24-85 Hz V, 24-94 kHz H, max dotclock 340 MHz + *     Dummy Descriptor: + *   Extension blocks: 1 + * Checksum: 0xce + * + * ---------------- + * + * Block 1, CTA-861 Extension Block: + *   Revision: 3 + *   Supports YCbCr 4:4:4 + *   Supports YCbCr 4:2:2 + *   Native detailed modes: 1 + *   Video Data Block: + *     VIC  95:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz + *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03: + *     Source physical address: 1.0.0.0 + *     DC_48bit + *     DC_36bit + *     DC_30bit + *     DC_Y444 + *     Maximum TMDS clock: 340 MHz + *     Extended HDMI video details: + *   Vendor-Specific Data Block (HDMI Forum), OUI C4-5D-D8: + *     Version: 1 + *     Maximum TMDS Character Rate: 340 MHz + *     SCDC Present + *     Supports 16-bits/component Deep Color 4:2:0 Pixel Encoding + *     Supports 12-bits/component Deep Color 4:2:0 Pixel Encoding + *     Supports 10-bits/component Deep Color 4:2:0 Pixel Encoding + *   YCbCr 4:2:0 Capability Map Data Block: + *     VIC  95:  3840x2160   30.000000 Hz  16:9     67.500 kHz    297.000000 MHz + *   YCbCr 4:2:0 Video Data Block: + * Checksum: 0x84 + */ +static const unsigned char test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz[] = { +	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x34, 0x00, +	0x00, 0x00, 0x00, 0x00, 0xff, 0x23, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78, +	0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54, 0x20, +	0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x74, 0x00, 0x30, 0xf2, 0x70, +	0x5a, 0x80, 0xb0, 0x58, 0x8a, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, +	0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, +	0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, +	0x55, 0x18, 0x5e, 0x22, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xce, 0x02, 0x03, 0x27, 0x31, +	0x41, 0x5f, 0x6c, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x78, 0x44, 0x20, 0x00, +	0x00, 0x01, 0x03, 0x6d, 0xd8, 0x5d, 0xc4, 0x01, 0x44, 0x80, 0x07, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x0f, 0x01, 0x00, 0xe1, 0x0e, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x8c +	0x00, 0x00, 0x00, 0x84  };  #endif // DRM_KUNIT_EDID_H_ diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c index 5f7257840d8e..04edb6079c0d 100644 --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c @@ -13,6 +13,7 @@  #include <kunit/resource.h>  #include <linux/device.h> +#include <linux/export.h>  #include <linux/platform_device.h>  #define KUNIT_DEVICE_NAME	"drm-kunit-mock-device" diff --git a/drivers/gpu/drm/tests/drm_sysfb_modeset_test.c b/drivers/gpu/drm/tests/drm_sysfb_modeset_test.c new file mode 100644 index 000000000000..e875d876118f --- /dev/null +++ b/drivers/gpu/drm/tests/drm_sysfb_modeset_test.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <kunit/test.h> + +#include <drm/drm_fourcc.h> +#include <drm/drm_kunit_helpers.h> + +#include "../sysfb/drm_sysfb_helper.h" + +#define TEST_BUF_SIZE 50 + +struct sysfb_build_fourcc_list_case { +	const char *name; +	u32 native_fourccs[TEST_BUF_SIZE]; +	size_t native_fourccs_size; +	u32 expected[TEST_BUF_SIZE]; +	size_t expected_fourccs_size; +}; + +static struct sysfb_build_fourcc_list_case sysfb_build_fourcc_list_cases[] = { +	{ +		.name = "no native formats", +		.native_fourccs = { }, +		.native_fourccs_size = 0, +		.expected = { DRM_FORMAT_XRGB8888 }, +		.expected_fourccs_size = 1, +	}, +	{ +		.name = "XRGB8888 as native format", +		.native_fourccs = { DRM_FORMAT_XRGB8888 }, +		.native_fourccs_size = 1, +		.expected = { DRM_FORMAT_XRGB8888 }, +		.expected_fourccs_size = 1, +	}, +	{ +		.name = "remove duplicates", +		.native_fourccs = { +			DRM_FORMAT_XRGB8888, +			DRM_FORMAT_XRGB8888, +			DRM_FORMAT_RGB888, +			DRM_FORMAT_RGB888, +			DRM_FORMAT_RGB888, +			DRM_FORMAT_XRGB8888, +			DRM_FORMAT_RGB888, +			DRM_FORMAT_RGB565, +			DRM_FORMAT_RGB888, +			DRM_FORMAT_XRGB8888, +			DRM_FORMAT_RGB565, +			DRM_FORMAT_RGB565, +			DRM_FORMAT_XRGB8888, +		}, +		.native_fourccs_size = 11, +		.expected = { +			DRM_FORMAT_XRGB8888, +			DRM_FORMAT_RGB888, +			DRM_FORMAT_RGB565, +		}, +		.expected_fourccs_size = 3, +	}, +	{ +		.name = "convert alpha formats", +		.native_fourccs = { +			DRM_FORMAT_ARGB1555, +			DRM_FORMAT_ABGR1555, +			DRM_FORMAT_RGBA5551, +			DRM_FORMAT_BGRA5551, +			DRM_FORMAT_ARGB8888, +			DRM_FORMAT_ABGR8888, +			DRM_FORMAT_RGBA8888, +			DRM_FORMAT_BGRA8888, +			DRM_FORMAT_ARGB2101010, +			DRM_FORMAT_ABGR2101010, +			DRM_FORMAT_RGBA1010102, +			DRM_FORMAT_BGRA1010102, +		}, +		.native_fourccs_size = 12, +		.expected = { +			DRM_FORMAT_XRGB1555, +			DRM_FORMAT_XBGR1555, +			DRM_FORMAT_RGBX5551, +			DRM_FORMAT_BGRX5551, +			DRM_FORMAT_XRGB8888, +			DRM_FORMAT_XBGR8888, +			DRM_FORMAT_RGBX8888, +			DRM_FORMAT_BGRX8888, +			DRM_FORMAT_XRGB2101010, +			DRM_FORMAT_XBGR2101010, +			DRM_FORMAT_RGBX1010102, +			DRM_FORMAT_BGRX1010102, +		}, +		.expected_fourccs_size = 12, +	}, +	{ +		.name = "random formats", +		.native_fourccs = { +			DRM_FORMAT_Y212, +			DRM_FORMAT_ARGB1555, +			DRM_FORMAT_ABGR16161616F, +			DRM_FORMAT_C8, +			DRM_FORMAT_BGR888, +			DRM_FORMAT_XRGB1555, +			DRM_FORMAT_RGBA5551, +			DRM_FORMAT_BGR565_A8, +			DRM_FORMAT_R10, +			DRM_FORMAT_XYUV8888, +		}, +		.native_fourccs_size = 10, +		.expected = { +			DRM_FORMAT_Y212, +			DRM_FORMAT_XRGB1555, +			DRM_FORMAT_ABGR16161616F, +			DRM_FORMAT_C8, +			DRM_FORMAT_BGR888, +			DRM_FORMAT_RGBX5551, +			DRM_FORMAT_BGR565_A8, +			DRM_FORMAT_R10, +			DRM_FORMAT_XYUV8888, +			DRM_FORMAT_XRGB8888, +		}, +		.expected_fourccs_size = 10, +	}, +}; + +static void sysfb_build_fourcc_list_case_desc(struct sysfb_build_fourcc_list_case *t, char *desc) +{ +	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); +} + +KUNIT_ARRAY_PARAM(sysfb_build_fourcc_list, sysfb_build_fourcc_list_cases, +		  sysfb_build_fourcc_list_case_desc); + +static void drm_test_sysfb_build_fourcc_list(struct kunit *test) +{ +	const struct sysfb_build_fourcc_list_case *params = test->param_value; +	u32 fourccs_out[TEST_BUF_SIZE] = {0}; +	size_t nfourccs_out; +	struct drm_device *drm; +	struct device *dev; + +	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); + +	nfourccs_out = drm_sysfb_build_fourcc_list(drm, params->native_fourccs, +						   params->native_fourccs_size, +						   fourccs_out, TEST_BUF_SIZE); + +	KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size); +	KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE); +} + +static struct kunit_case drm_sysfb_modeset_test_cases[] = { +	KUNIT_CASE_PARAM(drm_test_sysfb_build_fourcc_list, sysfb_build_fourcc_list_gen_params), +	{} +}; + +static struct kunit_suite drm_sysfb_modeset_test_suite = { +	.name = "drm_sysfb_modeset_test", +	.test_cases = drm_sysfb_modeset_test_cases, +}; + +kunit_test_suite(drm_sysfb_modeset_test_suite); + +MODULE_DESCRIPTION("KUnit tests for the drm_sysfb_modeset APIs"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>"); | 
