File Index
Files and directories
Sign in
FILE

drm_connector_test.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/tests/drm_connector_test.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Kunit test for drm_modes functions
   4 */
   5
   6#include <linux/i2c.h>
   7
   8#include <drm/drm_atomic_state_helper.h>
   9#include <drm/drm_connector.h>
  10#include <drm/drm_drv.h>
  11#include <drm/drm_edid.h>
  12#include <drm/drm_file.h>
  13#include <drm/drm_kunit_helpers.h>
  14#include <drm/drm_modes.h>
  15
  16#include <drm/display/drm_hdmi_helper.h>
  17
  18#include <kunit/test.h>
  19
  20#include "../drm_crtc_internal.h"
  21
  22struct drm_connector_init_priv {
  23	struct drm_device drm;
  24	struct drm_connector connector;
  25	struct i2c_adapter ddc;
  26};
  27
  28static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
  29};
  30
  31static const struct drm_connector_funcs dummy_funcs = {
  32	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
  33	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
  34	.reset			= drm_atomic_helper_connector_reset,
  35};
  36
  37static int dummy_ddc_xfer(struct i2c_adapter *adapter,
  38			  struct i2c_msg *msgs, int num)
  39{
  40	return num;
  41}
  42
  43static u32 dummy_ddc_func(struct i2c_adapter *adapter)
  44{
  45	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
  46}
  47
  48static const struct i2c_algorithm dummy_ddc_algorithm = {
  49	.master_xfer = dummy_ddc_xfer,
  50	.functionality = dummy_ddc_func,
  51};
  52
  53static void i2c_del_adapter_wrapper(void *ptr)
  54{
  55	struct i2c_adapter *adap = ptr;
  56
  57	i2c_del_adapter(adap);
  58}
  59
  60static int drm_test_connector_init(struct kunit *test)
  61{
  62	struct drm_connector_init_priv *priv;
  63	struct device *dev;
  64	int ret;
  65
  66	dev = drm_kunit_helper_alloc_device(test);
  67	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
  68
  69	priv = drm_kunit_helper_alloc_drm_device(test, dev,
  70						 struct drm_connector_init_priv, drm,
  71						 DRIVER_MODESET | DRIVER_ATOMIC);
  72	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
  73
  74	strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name));
  75	priv->ddc.owner = THIS_MODULE;
  76	priv->ddc.algo = &dummy_ddc_algorithm;
  77	priv->ddc.dev.parent = dev;
  78
  79	ret = i2c_add_adapter(&priv->ddc);
  80	KUNIT_ASSERT_EQ(test, ret, 0);
  81
  82	ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc);
  83	KUNIT_ASSERT_EQ(test, ret, 0);
  84
  85	test->priv = priv;
  86	return 0;
  87}
  88
  89/*
  90 * Test that the registration of a bog standard connector works as
  91 * expected and doesn't report any error.
  92 */
  93static void drm_test_drmm_connector_init(struct kunit *test)
  94{
  95	struct drm_connector_init_priv *priv = test->priv;
  96	int ret;
  97
  98	ret = drmm_connector_init(&priv->drm, &priv->connector,
  99				  &dummy_funcs,
 100				  DRM_MODE_CONNECTOR_HDMIA,
 101				  &priv->ddc);
 102	KUNIT_EXPECT_EQ(test, ret, 0);
 103}
 104
 105/*
 106 * Test that the registration of a connector without a DDC adapter
 107 * doesn't report any error.
 108 */
 109static void drm_test_drmm_connector_init_null_ddc(struct kunit *test)
 110{
 111	struct drm_connector_init_priv *priv = test->priv;
 112	int ret;
 113
 114	ret = drmm_connector_init(&priv->drm, &priv->connector,
 115				  &dummy_funcs,
 116				  DRM_MODE_CONNECTOR_HDMIA,
 117				  NULL);
 118	KUNIT_EXPECT_EQ(test, ret, 0);
 119}
 120
 121/*
 122 * Test that the registration of a connector succeeds for all possible
 123 * connector types.
 124 */
 125static void drm_test_drmm_connector_init_type_valid(struct kunit *test)
 126{
 127	struct drm_connector_init_priv *priv = test->priv;
 128	unsigned int connector_type = *(unsigned int *)test->param_value;
 129	int ret;
 130
 131	ret = drmm_connector_init(&priv->drm, &priv->connector,
 132				  &dummy_funcs,
 133				  connector_type,
 134				  &priv->ddc);
 135	KUNIT_EXPECT_EQ(test, ret, 0);
 136}
 137
 138static const unsigned int drm_connector_init_type_valid_tests[] = {
 139	DRM_MODE_CONNECTOR_Unknown,
 140	DRM_MODE_CONNECTOR_VGA,
 141	DRM_MODE_CONNECTOR_DVII,
 142	DRM_MODE_CONNECTOR_DVID,
 143	DRM_MODE_CONNECTOR_DVIA,
 144	DRM_MODE_CONNECTOR_Composite,
 145	DRM_MODE_CONNECTOR_SVIDEO,
 146	DRM_MODE_CONNECTOR_LVDS,
 147	DRM_MODE_CONNECTOR_Component,
 148	DRM_MODE_CONNECTOR_9PinDIN,
 149	DRM_MODE_CONNECTOR_DisplayPort,
 150	DRM_MODE_CONNECTOR_HDMIA,
 151	DRM_MODE_CONNECTOR_HDMIB,
 152	DRM_MODE_CONNECTOR_TV,
 153	DRM_MODE_CONNECTOR_eDP,
 154	DRM_MODE_CONNECTOR_VIRTUAL,
 155	DRM_MODE_CONNECTOR_DSI,
 156	DRM_MODE_CONNECTOR_DPI,
 157	DRM_MODE_CONNECTOR_WRITEBACK,
 158	DRM_MODE_CONNECTOR_SPI,
 159	DRM_MODE_CONNECTOR_USB,
 160};
 161
 162static void drm_connector_init_type_desc(const unsigned int *type, char *desc)
 163{
 164	sprintf(desc, "%s", drm_get_connector_type_name(*type));
 165}
 166
 167KUNIT_ARRAY_PARAM(drm_connector_init_type_valid,
 168		  drm_connector_init_type_valid_tests,
 169		  drm_connector_init_type_desc);
 170
 171static struct kunit_case drmm_connector_init_tests[] = {
 172	KUNIT_CASE(drm_test_drmm_connector_init),
 173	KUNIT_CASE(drm_test_drmm_connector_init_null_ddc),
 174	KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid,
 175			 drm_connector_init_type_valid_gen_params),
 176	{ }
 177};
 178
 179static struct kunit_suite drmm_connector_init_test_suite = {
 180	.name = "drmm_connector_init",
 181	.init = drm_test_connector_init,
 182	.test_cases = drmm_connector_init_tests,
 183};
 184
 185static const struct drm_connector_funcs dummy_dynamic_init_funcs = {
 186	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 187	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
 188	.reset			= drm_atomic_helper_connector_reset,
 189	.destroy		= drm_connector_cleanup,
 190};
 191
 192/*
 193 * Test that the initialization of a bog standard dynamic connector works
 194 * as expected and doesn't report any error.
 195 */
 196static void drm_test_drm_connector_dynamic_init(struct kunit *test)
 197{
 198	struct drm_connector_init_priv *priv = test->priv;
 199	struct drm_connector *connector = &priv->connector;
 200	int ret;
 201
 202	ret = drm_connector_dynamic_init(&priv->drm, connector,
 203					 &dummy_dynamic_init_funcs,
 204					 DRM_MODE_CONNECTOR_DisplayPort,
 205					 &priv->ddc);
 206	KUNIT_ASSERT_EQ(test, ret, 0);
 207}
 208
 209static void drm_test_connector_dynamic_init_cleanup(struct kunit *test)
 210{
 211	struct drm_connector_init_priv *priv = test->priv;
 212	struct drm_connector *connector = &priv->connector;
 213
 214	drm_connector_cleanup(connector);
 215}
 216
 217/*
 218 * Test that the initialization of a dynamic connector without a DDC adapter
 219 * doesn't report any error.
 220 */
 221static void drm_test_drm_connector_dynamic_init_null_ddc(struct kunit *test)
 222{
 223	struct drm_connector_init_priv *priv = test->priv;
 224	struct drm_connector *connector = &priv->connector;
 225	int ret;
 226
 227	ret = drm_connector_dynamic_init(&priv->drm, connector,
 228					 &dummy_dynamic_init_funcs,
 229					 DRM_MODE_CONNECTOR_DisplayPort,
 230					 NULL);
 231	KUNIT_ASSERT_EQ(test, ret, 0);
 232}
 233
 234/*
 235 * Test that the initialization of a dynamic connector doesn't add the
 236 * connector to the connector list.
 237 */
 238static void drm_test_drm_connector_dynamic_init_not_added(struct kunit *test)
 239{
 240	struct drm_connector_init_priv *priv = test->priv;
 241	struct drm_connector *connector = &priv->connector;
 242	int ret;
 243
 244	ret = drm_connector_dynamic_init(&priv->drm, connector,
 245					 &dummy_dynamic_init_funcs,
 246					 DRM_MODE_CONNECTOR_DisplayPort,
 247					 &priv->ddc);
 248	KUNIT_ASSERT_EQ(test, ret, 0);
 249	KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &connector->head);
 250}
 251
 252static void test_connector_property(struct kunit *test,
 253				    struct drm_connector *connector,
 254				    const struct drm_property *expected_prop)
 255{
 256	struct drm_property *prop;
 257	uint64_t val;
 258	int ret;
 259
 260	KUNIT_ASSERT_NOT_NULL(test, expected_prop);
 261	prop = drm_mode_obj_find_prop_id(&connector->base, expected_prop->base.id);
 262	KUNIT_ASSERT_PTR_EQ_MSG(test, prop, expected_prop,
 263				"Can't find property %s", expected_prop->name);
 264
 265	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
 266	KUNIT_EXPECT_EQ(test, ret, 0);
 267	KUNIT_EXPECT_EQ(test, val, 0);
 268
 269	/* TODO: Check property value in the connector state. */
 270}
 271
 272/*
 273 * Test that the initialization of a dynamic connector adds all the expected
 274 * properties to it.
 275 */
 276static void drm_test_drm_connector_dynamic_init_properties(struct kunit *test)
 277{
 278	struct drm_connector_init_priv *priv = test->priv;
 279	struct drm_connector *connector = &priv->connector;
 280	struct drm_mode_config *config = &priv->drm.mode_config;
 281	const struct drm_property *props[] = {
 282		config->edid_property,
 283		config->dpms_property,
 284		config->link_status_property,
 285		config->non_desktop_property,
 286		config->tile_property,
 287		config->prop_crtc_id,
 288	};
 289	int ret;
 290	int i;
 291
 292	ret = drm_connector_dynamic_init(&priv->drm, connector,
 293					 &dummy_dynamic_init_funcs,
 294					 DRM_MODE_CONNECTOR_DisplayPort,
 295					 &priv->ddc);
 296	KUNIT_ASSERT_EQ(test, ret, 0);
 297
 298	for (i = 0; i < ARRAY_SIZE(props); i++)
 299		test_connector_property(test, connector, props[i]);
 300}
 301
 302/*
 303 * Test that the initialization of a dynamic connector succeeds for all
 304 * possible connector types.
 305 */
 306static void drm_test_drm_connector_dynamic_init_type_valid(struct kunit *test)
 307{
 308	struct drm_connector_init_priv *priv = test->priv;
 309	struct drm_connector *connector = &priv->connector;
 310	unsigned int connector_type = *(unsigned int *)test->param_value;
 311	int ret;
 312
 313	ret = drm_connector_dynamic_init(&priv->drm, connector,
 314					 &dummy_dynamic_init_funcs,
 315					 connector_type,
 316					 &priv->ddc);
 317	KUNIT_ASSERT_EQ(test, ret, 0);
 318}
 319
 320/*
 321 * Test that the initialization of a dynamic connector sets the expected name
 322 * for it for all possible connector types.
 323 */
 324static void drm_test_drm_connector_dynamic_init_name(struct kunit *test)
 325{
 326	struct drm_connector_init_priv *priv = test->priv;
 327	struct drm_connector *connector = &priv->connector;
 328	unsigned int connector_type = *(unsigned int *)test->param_value;
 329	char expected_name[128];
 330	int ret;
 331
 332	ret = drm_connector_dynamic_init(&priv->drm, connector,
 333					 &dummy_dynamic_init_funcs,
 334					 connector_type,
 335					 &priv->ddc);
 336	KUNIT_ASSERT_EQ(test, ret, 0);
 337
 338	snprintf(expected_name, sizeof(expected_name), "%s-%d",
 339		 drm_get_connector_type_name(connector_type), connector->connector_type_id);
 340	KUNIT_ASSERT_STREQ(test, connector->name, expected_name);
 341}
 342
 343static struct kunit_case drm_connector_dynamic_init_tests[] = {
 344	KUNIT_CASE(drm_test_drm_connector_dynamic_init),
 345	KUNIT_CASE(drm_test_drm_connector_dynamic_init_null_ddc),
 346	KUNIT_CASE(drm_test_drm_connector_dynamic_init_not_added),
 347	KUNIT_CASE(drm_test_drm_connector_dynamic_init_properties),
 348	KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_type_valid,
 349			 drm_connector_init_type_valid_gen_params),
 350	KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_name,
 351			 drm_connector_init_type_valid_gen_params),
 352	{}
 353};
 354
 355static struct kunit_suite drm_connector_dynamic_init_test_suite = {
 356	.name = "drm_connector_dynamic_init",
 357	.init = drm_test_connector_init,
 358	.exit = drm_test_connector_dynamic_init_cleanup,
 359	.test_cases = drm_connector_dynamic_init_tests,
 360};
 361
 362static int drm_test_connector_dynamic_register_early_init(struct kunit *test)
 363{
 364	struct drm_connector_init_priv *priv;
 365	int ret;
 366
 367	ret = drm_test_connector_init(test);
 368	KUNIT_ASSERT_EQ(test, ret, 0);
 369
 370	priv = test->priv;
 371
 372	ret = drm_connector_dynamic_init(&priv->drm, &priv->connector,
 373					 &dummy_dynamic_init_funcs,
 374					 DRM_MODE_CONNECTOR_DisplayPort,
 375					 &priv->ddc);
 376	KUNIT_ASSERT_EQ(test, ret, 0);
 377
 378	return 0;
 379}
 380
 381static void drm_test_connector_dynamic_register_early_cleanup(struct kunit *test)
 382{
 383	struct drm_connector_init_priv *priv = test->priv;
 384	struct drm_connector *connector = &priv->connector;
 385
 386	drm_connector_unregister(connector);
 387	drm_connector_put(connector);
 388}
 389
 390/*
 391 * Test that registration of a dynamic connector adds it to the connector list.
 392 */
 393static void drm_test_drm_connector_dynamic_register_early_on_list(struct kunit *test)
 394{
 395	struct drm_connector_init_priv *priv = test->priv;
 396	struct drm_connector *connector = &priv->connector;
 397	int ret;
 398
 399	KUNIT_ASSERT_TRUE(test, list_empty(&connector->head));
 400
 401	ret = drm_connector_dynamic_register(connector);
 402	KUNIT_ASSERT_EQ(test, ret, 0);
 403
 404	KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &priv->drm.mode_config.connector_list);
 405}
 406
 407/*
 408 * Test that the registration of a dynamic connector before the drm device is
 409 * registered results in deferring the connector's user interface registration.
 410 */
 411static void drm_test_drm_connector_dynamic_register_early_defer(struct kunit *test)
 412{
 413	struct drm_connector_init_priv *priv = test->priv;
 414	struct drm_connector *connector = &priv->connector;
 415	int ret;
 416
 417	ret = drm_connector_dynamic_register(connector);
 418	KUNIT_ASSERT_EQ(test, ret, 0);
 419
 420	KUNIT_ASSERT_EQ(test, connector->registration_state, DRM_CONNECTOR_INITIALIZING);
 421}
 422
 423/*
 424 * Test that the registration of a dynamic connector fails, if this is done before
 425 * the connector is initialized.
 426 */
 427static void drm_test_drm_connector_dynamic_register_early_no_init(struct kunit *test)
 428{
 429	struct drm_connector *connector;
 430	int ret;
 431
 432	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */
 433	KUNIT_ASSERT_NOT_NULL(test, connector);
 434
 435	ret = drm_connector_dynamic_register(connector);
 436	KUNIT_ASSERT_EQ(test, ret, -EINVAL);
 437}
 438
 439/*
 440 * Test that the registration of a dynamic connector before the drm device is
 441 * registered results in deferring adding a mode object for the connector.
 442 */
 443static void drm_test_drm_connector_dynamic_register_early_no_mode_object(struct kunit *test)
 444{
 445	struct drm_connector_init_priv *priv = test->priv;
 446	struct drm_connector *connector = &priv->connector;
 447	struct drm_connector *tmp_connector;
 448	int ret;
 449
 450	ret = drm_connector_dynamic_register(&priv->connector);
 451	KUNIT_ASSERT_EQ(test, ret, 0);
 452
 453	tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
 454	KUNIT_ASSERT_NULL(test, tmp_connector);
 455}
 456
 457static struct kunit_case drm_connector_dynamic_register_early_tests[] = {
 458	KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_on_list),
 459	KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_defer),
 460	KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_init),
 461	KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_mode_object),
 462	{ }
 463};
 464
 465static struct kunit_suite drm_connector_dynamic_register_early_test_suite = {
 466	.name = "drm_connector_dynamic_register_early",
 467	.init = drm_test_connector_dynamic_register_early_init,
 468	.exit = drm_test_connector_dynamic_register_early_cleanup,
 469	.test_cases = drm_connector_dynamic_register_early_tests,
 470};
 471
 472static int drm_test_connector_dynamic_register_init(struct kunit *test)
 473{
 474	struct drm_connector_init_priv *priv;
 475	int ret;
 476
 477	ret = drm_test_connector_dynamic_register_early_init(test);
 478	KUNIT_ASSERT_EQ(test, ret, 0);
 479
 480	priv = test->priv;
 481
 482	ret = drm_dev_register(priv->connector.dev, 0);
 483	KUNIT_ASSERT_EQ(test, ret, 0);
 484
 485	return 0;
 486}
 487
 488static void drm_test_connector_dynamic_register_cleanup(struct kunit *test)
 489{
 490	struct drm_connector_init_priv *priv = test->priv;
 491	struct drm_device *dev = priv->connector.dev;
 492
 493	drm_connector_unregister(&priv->connector);
 494	drm_connector_put(&priv->connector);
 495
 496	drm_dev_unregister(dev);
 497
 498	drm_test_connector_dynamic_register_early_cleanup(test);
 499}
 500
 501static void drm_test_drm_connector_dynamic_register_on_list(struct kunit *test)
 502{
 503	struct drm_connector_init_priv *priv = test->priv;
 504	int ret;
 505
 506	KUNIT_ASSERT_TRUE(test, list_empty(&priv->connector.head));
 507
 508	ret = drm_connector_dynamic_register(&priv->connector);
 509	KUNIT_ASSERT_EQ(test, ret, 0);
 510
 511	KUNIT_ASSERT_PTR_EQ(test, priv->connector.head.next, &priv->drm.mode_config.connector_list);
 512}
 513
 514/*
 515 * Test that the registration of a dynamic connector doesn't get deferred if
 516 * this is done after the drm device is registered.
 517 */
 518static void drm_test_drm_connector_dynamic_register_no_defer(struct kunit *test)
 519{
 520	struct drm_connector_init_priv *priv = test->priv;
 521	int ret;
 522
 523	KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_INITIALIZING);
 524
 525	ret = drm_connector_dynamic_register(&priv->connector);
 526	KUNIT_ASSERT_EQ(test, ret, 0);
 527
 528	KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_REGISTERED);
 529}
 530
 531/*
 532 * Test that the registration of a dynamic connector fails if this is done after the
 533 * drm device is registered, but before the connector is initialized.
 534 */
 535static void drm_test_drm_connector_dynamic_register_no_init(struct kunit *test)
 536{
 537	struct drm_connector *connector;
 538	int ret;
 539
 540	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */
 541	KUNIT_ASSERT_NOT_NULL(test, connector);
 542
 543	ret = drm_connector_dynamic_register(connector);
 544	KUNIT_ASSERT_EQ(test, ret, -EINVAL);
 545}
 546
 547/*
 548 * Test that the registration of a dynamic connector after the drm device is
 549 * registered adds the mode object for the connector.
 550 */
 551static void drm_test_drm_connector_dynamic_register_mode_object(struct kunit *test)
 552{
 553	struct drm_connector_init_priv *priv = test->priv;
 554	struct drm_connector *connector = &priv->connector;
 555	struct drm_connector *tmp_connector;
 556	int ret;
 557
 558	tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
 559	KUNIT_ASSERT_NULL(test, tmp_connector);
 560
 561	ret = drm_connector_dynamic_register(&priv->connector);
 562	KUNIT_ASSERT_EQ(test, ret, 0);
 563
 564	tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
 565	KUNIT_ASSERT_PTR_EQ(test, tmp_connector, connector);
 566}
 567
 568/*
 569 * Test that the registration of a dynamic connector after the drm device is
 570 * registered adds the connector to sysfs.
 571 */
 572static void drm_test_drm_connector_dynamic_register_sysfs(struct kunit *test)
 573{
 574	struct drm_connector_init_priv *priv = test->priv;
 575	struct drm_connector *connector = &priv->connector;
 576	int ret;
 577
 578	KUNIT_ASSERT_NULL(test, connector->kdev);
 579
 580	ret = drm_connector_dynamic_register(connector);
 581	KUNIT_ASSERT_EQ(test, ret, 0);
 582
 583	KUNIT_ASSERT_NOT_NULL(test, connector->kdev);
 584}
 585
 586/*
 587 * Test that the registration of a dynamic connector after the drm device is
 588 * registered sets the connector's sysfs name as expected.
 589 */
 590static void drm_test_drm_connector_dynamic_register_sysfs_name(struct kunit *test)
 591{
 592	struct drm_connector_init_priv *priv = test->priv;
 593	struct drm_connector *connector = &priv->connector;
 594	char expected_name[128];
 595	int ret;
 596
 597	ret = drm_connector_dynamic_register(connector);
 598	KUNIT_ASSERT_EQ(test, ret, 0);
 599
 600	snprintf(expected_name, sizeof(expected_name), "card%d-%s",
 601		 connector->dev->primary->index, connector->name);
 602
 603	KUNIT_ASSERT_STREQ(test, dev_name(connector->kdev), expected_name);
 604}
 605
 606/*
 607 * Test that the registration of a dynamic connector after the drm device is
 608 * registered adds the connector to debugfs.
 609 */
 610static void drm_test_drm_connector_dynamic_register_debugfs(struct kunit *test)
 611{
 612	struct drm_connector_init_priv *priv = test->priv;
 613	int ret;
 614
 615	KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry);
 616
 617	ret = drm_connector_dynamic_register(&priv->connector);
 618	KUNIT_ASSERT_EQ(test, ret, 0);
 619
 620	if (IS_ENABLED(CONFIG_DEBUG_FS))
 621		KUNIT_ASSERT_NOT_NULL(test, priv->connector.debugfs_entry);
 622	else
 623		KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry);
 624}
 625
 626static struct kunit_case drm_connector_dynamic_register_tests[] = {
 627	KUNIT_CASE(drm_test_drm_connector_dynamic_register_on_list),
 628	KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_defer),
 629	KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_init),
 630	KUNIT_CASE(drm_test_drm_connector_dynamic_register_mode_object),
 631	KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs),
 632	KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs_name),
 633	KUNIT_CASE(drm_test_drm_connector_dynamic_register_debugfs),
 634	{ }
 635};
 636
 637static struct kunit_suite drm_connector_dynamic_register_test_suite = {
 638	.name = "drm_connector_dynamic_register",
 639	.init = drm_test_connector_dynamic_register_init,
 640	.exit = drm_test_connector_dynamic_register_cleanup,
 641	.test_cases = drm_connector_dynamic_register_tests,
 642};
 643
 644/*
 645 * Test that the registration of a bog standard connector works as
 646 * expected and doesn't report any error.
 647 */
 648static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 649{
 650	struct drm_connector_init_priv *priv = test->priv;
 651	int ret;
 652
 653	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 654				       "Vendor", "Product",
 655				       &dummy_funcs,
 656				       &dummy_hdmi_funcs,
 657				       DRM_MODE_CONNECTOR_HDMIA,
 658				       &priv->ddc,
 659				       BIT(HDMI_COLORSPACE_RGB),
 660				       8);
 661	KUNIT_EXPECT_EQ(test, ret, 0);
 662}
 663
 664/*
 665 * Test that the registration of a connector without a DDC adapter
 666 * doesn't report any error.
 667 */
 668static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 669{
 670	struct drm_connector_init_priv *priv = test->priv;
 671	int ret;
 672
 673	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 674				       "Vendor", "Product",
 675				       &dummy_funcs,
 676				       &dummy_hdmi_funcs,
 677				       DRM_MODE_CONNECTOR_HDMIA,
 678				       NULL,
 679				       BIT(HDMI_COLORSPACE_RGB),
 680				       8);
 681	KUNIT_EXPECT_EQ(test, ret, 0);
 682}
 683
 684/*
 685 * Test that the registration of an HDMI connector with a NULL vendor
 686 * fails.
 687 */
 688static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
 689{
 690	struct drm_connector_init_priv *priv = test->priv;
 691	int ret;
 692
 693	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 694				       NULL, "Product",
 695				       &dummy_funcs,
 696				       &dummy_hdmi_funcs,
 697				       DRM_MODE_CONNECTOR_HDMIA,
 698				       &priv->ddc,
 699				       BIT(HDMI_COLORSPACE_RGB),
 700				       8);
 701	KUNIT_EXPECT_LT(test, ret, 0);
 702}
 703
 704/*
 705 * Test that the registration of an HDMI connector with a NULL product
 706 * fails.
 707 */
 708static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
 709{
 710	struct drm_connector_init_priv *priv = test->priv;
 711	int ret;
 712
 713	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 714				       "Vendor", NULL,
 715				       &dummy_funcs,
 716				       &dummy_hdmi_funcs,
 717				       DRM_MODE_CONNECTOR_HDMIA,
 718				       &priv->ddc,
 719				       BIT(HDMI_COLORSPACE_RGB),
 720				       8);
 721	KUNIT_EXPECT_LT(test, ret, 0);
 722}
 723
 724/*
 725 * Test that the registration of a connector with a valid, shorter than
 726 * the max length, product name succeeds, and is stored padded with 0.
 727 */
 728static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
 729{
 730	struct drm_connector_init_priv *priv = test->priv;
 731	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
 732		'P', 'r', 'o', 'd',
 733	};
 734	const char *product_name = "Prod";
 735	int ret;
 736
 737	KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
 738
 739	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 740				       "Vendor", product_name,
 741				       &dummy_funcs,
 742				       &dummy_hdmi_funcs,
 743				       DRM_MODE_CONNECTOR_HDMIA,
 744				       &priv->ddc,
 745				       BIT(HDMI_COLORSPACE_RGB),
 746				       8);
 747	KUNIT_EXPECT_EQ(test, ret, 0);
 748	KUNIT_EXPECT_MEMEQ(test,
 749			   priv->connector.hdmi.product,
 750			   expected_product,
 751			   sizeof(priv->connector.hdmi.product));
 752}
 753
 754/*
 755 * Test that the registration of a connector with a valid, at max
 756 * length, product name succeeds, and is stored padded without any
 757 * trailing \0.
 758 */
 759static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test)
 760{
 761	struct drm_connector_init_priv *priv = test->priv;
 762	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
 763		'P', 'r', 'o', 'd', 'u', 'c', 't',
 764		'P', 'r', 'o', 'd', 'u', 'c', 't',
 765		'P', 'r',
 766	};
 767	const char *product_name = "ProductProductPr";
 768	int ret;
 769
 770	KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
 771
 772	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 773				       "Vendor", product_name,
 774				       &dummy_funcs,
 775				       &dummy_hdmi_funcs,
 776				       DRM_MODE_CONNECTOR_HDMIA,
 777				       &priv->ddc,
 778				       BIT(HDMI_COLORSPACE_RGB),
 779				       8);
 780	KUNIT_EXPECT_EQ(test, ret, 0);
 781	KUNIT_EXPECT_MEMEQ(test,
 782			   priv->connector.hdmi.product,
 783			   expected_product,
 784			   sizeof(priv->connector.hdmi.product));
 785}
 786
 787/*
 788 * Test that the registration of a connector with a product name larger
 789 * than the maximum length fails.
 790 */
 791static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test)
 792{
 793	struct drm_connector_init_priv *priv = test->priv;
 794	const char *product_name = "ProductProductProduct";
 795	int ret;
 796
 797	KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
 798
 799	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 800				       "Vendor", product_name,
 801				       &dummy_funcs,
 802				       &dummy_hdmi_funcs,
 803				       DRM_MODE_CONNECTOR_HDMIA,
 804				       &priv->ddc,
 805				       BIT(HDMI_COLORSPACE_RGB),
 806				       8);
 807	KUNIT_EXPECT_LT(test, ret, 0);
 808}
 809
 810/*
 811 * Test that the registration of a connector with a vendor name smaller
 812 * than the maximum length succeeds, and is stored padded with zeros.
 813 */
 814static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test)
 815{
 816	struct drm_connector_init_priv *priv = test->priv;
 817	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
 818		'V', 'e', 'n', 'd',
 819	};
 820	const char *vendor_name = "Vend";
 821	int ret;
 822
 823	KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
 824
 825	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 826				       vendor_name, "Product",
 827				       &dummy_funcs,
 828				       &dummy_hdmi_funcs,
 829				       DRM_MODE_CONNECTOR_HDMIA,
 830				       &priv->ddc,
 831				       BIT(HDMI_COLORSPACE_RGB),
 832				       8);
 833	KUNIT_EXPECT_EQ(test, ret, 0);
 834	KUNIT_EXPECT_MEMEQ(test,
 835			   priv->connector.hdmi.vendor,
 836			   expected_vendor,
 837			   sizeof(priv->connector.hdmi.vendor));
 838}
 839
 840/*
 841 * Test that the registration of a connector with a vendor name at the
 842 * maximum length succeeds, and is stored padded without the trailing
 843 * zero.
 844 */
 845static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test)
 846{
 847	struct drm_connector_init_priv *priv = test->priv;
 848	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
 849		'V', 'e', 'n', 'd', 'o', 'r',
 850		'V', 'e',
 851	};
 852	const char *vendor_name = "VendorVe";
 853	int ret;
 854
 855	KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
 856
 857	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 858				       vendor_name, "Product",
 859				       &dummy_funcs,
 860				       &dummy_hdmi_funcs,
 861				       DRM_MODE_CONNECTOR_HDMIA,
 862				       &priv->ddc,
 863				       BIT(HDMI_COLORSPACE_RGB),
 864				       8);
 865	KUNIT_EXPECT_EQ(test, ret, 0);
 866	KUNIT_EXPECT_MEMEQ(test,
 867			   priv->connector.hdmi.vendor,
 868			   expected_vendor,
 869			   sizeof(priv->connector.hdmi.vendor));
 870}
 871
 872/*
 873 * Test that the registration of a connector with a vendor name larger
 874 * than the maximum length fails.
 875 */
 876static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test)
 877{
 878	struct drm_connector_init_priv *priv = test->priv;
 879	const char *vendor_name = "VendorVendor";
 880	int ret;
 881
 882	KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
 883
 884	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 885				       vendor_name, "Product",
 886				       &dummy_funcs,
 887				       &dummy_hdmi_funcs,
 888				       DRM_MODE_CONNECTOR_HDMIA,
 889				       &priv->ddc,
 890				       BIT(HDMI_COLORSPACE_RGB),
 891				       8);
 892	KUNIT_EXPECT_LT(test, ret, 0);
 893}
 894
 895/*
 896 * Test that the registration of a connector with an invalid maximum bpc
 897 * count fails.
 898 */
 899static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
 900{
 901	struct drm_connector_init_priv *priv = test->priv;
 902	int ret;
 903
 904	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 905				       "Vendor", "Product",
 906				       &dummy_funcs,
 907				       &dummy_hdmi_funcs,
 908				       DRM_MODE_CONNECTOR_HDMIA,
 909				       &priv->ddc,
 910				       BIT(HDMI_COLORSPACE_RGB),
 911				       9);
 912	KUNIT_EXPECT_LT(test, ret, 0);
 913}
 914
 915/*
 916 * Test that the registration of a connector with a null maximum bpc
 917 * count fails.
 918 */
 919static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
 920{
 921	struct drm_connector_init_priv *priv = test->priv;
 922	int ret;
 923
 924	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 925				       "Vendor", "Product",
 926				       &dummy_funcs,
 927				       &dummy_hdmi_funcs,
 928				       DRM_MODE_CONNECTOR_HDMIA,
 929				       &priv->ddc,
 930				       BIT(HDMI_COLORSPACE_RGB),
 931				       0);
 932	KUNIT_EXPECT_LT(test, ret, 0);
 933}
 934
 935/*
 936 * Test that the registration of a connector with a maximum bpc count of
 937 * 8 succeeds, registers the max bpc property, but doesn't register the
 938 * HDR output metadata one.
 939 */
 940static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
 941{
 942	struct drm_connector_init_priv *priv = test->priv;
 943	struct drm_connector_state *state;
 944	struct drm_connector *connector = &priv->connector;
 945	struct drm_property *prop;
 946	uint64_t val;
 947	int ret;
 948
 949	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 950				       "Vendor", "Product",
 951				       &dummy_funcs,
 952				       &dummy_hdmi_funcs,
 953				       DRM_MODE_CONNECTOR_HDMIA,
 954				       &priv->ddc,
 955				       BIT(HDMI_COLORSPACE_RGB),
 956				       8);
 957	KUNIT_EXPECT_EQ(test, ret, 0);
 958
 959	prop = connector->max_bpc_property;
 960	KUNIT_ASSERT_NOT_NULL(test, prop);
 961	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
 962
 963	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
 964	KUNIT_EXPECT_EQ(test, ret, 0);
 965	KUNIT_EXPECT_EQ(test, val, 8);
 966
 967	state = connector->state;
 968	KUNIT_EXPECT_EQ(test, state->max_bpc, 8);
 969	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 8);
 970
 971	prop = priv->drm.mode_config.hdr_output_metadata_property;
 972	KUNIT_ASSERT_NOT_NULL(test, prop);
 973	KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
 974}
 975
 976/*
 977 * Test that the registration of a connector with a maximum bpc count of
 978 * 10 succeeds and registers the max bpc and HDR output metadata
 979 * properties.
 980 */
 981static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
 982{
 983	struct drm_connector_init_priv *priv = test->priv;
 984	struct drm_connector_state *state;
 985	struct drm_connector *connector = &priv->connector;
 986	struct drm_property *prop;
 987	uint64_t val;
 988	int ret;
 989
 990	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 991				       "Vendor", "Product",
 992				       &dummy_funcs,
 993				       &dummy_hdmi_funcs,
 994				       DRM_MODE_CONNECTOR_HDMIA,
 995				       &priv->ddc,
 996				       BIT(HDMI_COLORSPACE_RGB),
 997				       10);
 998	KUNIT_EXPECT_EQ(test, ret, 0);
 999
1000	prop = connector->max_bpc_property;
1001	KUNIT_ASSERT_NOT_NULL(test, prop);
1002	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1003
1004	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
1005	KUNIT_EXPECT_EQ(test, ret, 0);
1006	KUNIT_EXPECT_EQ(test, val, 10);
1007
1008	state = connector->state;
1009	KUNIT_EXPECT_EQ(test, state->max_bpc, 10);
1010	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 10);
1011
1012	prop = priv->drm.mode_config.hdr_output_metadata_property;
1013	KUNIT_ASSERT_NOT_NULL(test, prop);
1014	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1015}
1016
1017/*
1018 * Test that the registration of a connector with a maximum bpc count of
1019 * 12 succeeds and registers the max bpc and HDR output metadata
1020 * properties.
1021 */
1022static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
1023{
1024	struct drm_connector_init_priv *priv = test->priv;
1025	struct drm_connector_state *state;
1026	struct drm_connector *connector = &priv->connector;
1027	struct drm_property *prop;
1028	uint64_t val;
1029	int ret;
1030
1031	ret = drmm_connector_hdmi_init(&priv->drm, connector,
1032				       "Vendor", "Product",
1033				       &dummy_funcs,
1034				       &dummy_hdmi_funcs,
1035				       DRM_MODE_CONNECTOR_HDMIA,
1036				       &priv->ddc,
1037				       BIT(HDMI_COLORSPACE_RGB),
1038				       12);
1039	KUNIT_EXPECT_EQ(test, ret, 0);
1040
1041	prop = connector->max_bpc_property;
1042	KUNIT_ASSERT_NOT_NULL(test, prop);
1043	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1044
1045	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
1046	KUNIT_EXPECT_EQ(test, ret, 0);
1047	KUNIT_EXPECT_EQ(test, val, 12);
1048
1049	state = connector->state;
1050	KUNIT_EXPECT_EQ(test, state->max_bpc, 12);
1051	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 12);
1052
1053	prop = priv->drm.mode_config.hdr_output_metadata_property;
1054	KUNIT_ASSERT_NOT_NULL(test, prop);
1055	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1056}
1057
1058/*
1059 * Test that the registration of an HDMI connector with no supported
1060 * format fails.
1061 */
1062static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
1063{
1064	struct drm_connector_init_priv *priv = test->priv;
1065	int ret;
1066
1067	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1068				       "Vendor", "Product",
1069				       &dummy_funcs,
1070				       &dummy_hdmi_funcs,
1071				       DRM_MODE_CONNECTOR_HDMIA,
1072				       &priv->ddc,
1073				       0,
1074				       8);
1075	KUNIT_EXPECT_LT(test, ret, 0);
1076}
1077
1078/*
1079 * Test that the registration of an HDMI connector not listing RGB as a
1080 * supported format fails.
1081 */
1082static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
1083{
1084	struct drm_connector_init_priv *priv = test->priv;
1085	int ret;
1086
1087	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1088				       "Vendor", "Product",
1089				       &dummy_funcs,
1090				       &dummy_hdmi_funcs,
1091				       DRM_MODE_CONNECTOR_HDMIA,
1092				       &priv->ddc,
1093				       BIT(HDMI_COLORSPACE_YUV422),
1094				       8);
1095	KUNIT_EXPECT_LT(test, ret, 0);
1096}
1097
1098struct drm_connector_hdmi_init_formats_yuv420_allowed_test {
1099	unsigned long supported_formats;
1100	bool yuv420_allowed;
1101	int expected_result;
1102};
1103
1104#define YUV420_ALLOWED_TEST(_formats, _allowed, _result)			\
1105	{									\
1106		.supported_formats = BIT(HDMI_COLORSPACE_RGB) | (_formats),	\
1107		.yuv420_allowed = _allowed,					\
1108		.expected_result = _result,					\
1109	}
1110
1111static const struct drm_connector_hdmi_init_formats_yuv420_allowed_test
1112drm_connector_hdmi_init_formats_yuv420_allowed_tests[] = {
1113	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), true, 0),
1114	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), false, -EINVAL),
1115	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), true, -EINVAL),
1116	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), false, 0),
1117};
1118
1119static void
1120drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *t,
1121						    char *desc)
1122{
1123	sprintf(desc, "supported_formats=0x%lx yuv420_allowed=%d",
1124		t->supported_formats, t->yuv420_allowed);
1125}
1126
1127KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_formats_yuv420_allowed,
1128		  drm_connector_hdmi_init_formats_yuv420_allowed_tests,
1129		  drm_connector_hdmi_init_formats_yuv420_allowed_desc);
1130
1131/*
1132 * Test that the registration of an HDMI connector succeeds only when
1133 * the presence of YUV420 in the supported formats matches the value
1134 * of the ycbcr_420_allowed flag.
1135 */
1136static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *test)
1137{
1138	const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *params;
1139	struct drm_connector_init_priv *priv = test->priv;
1140	int ret;
1141
1142	params = test->param_value;
1143	priv->connector.ycbcr_420_allowed = params->yuv420_allowed;
1144
1145	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1146				       "Vendor", "Product",
1147				       &dummy_funcs,
1148				       &dummy_hdmi_funcs,
1149				       DRM_MODE_CONNECTOR_HDMIA,
1150				       &priv->ddc,
1151				       params->supported_formats,
1152				       8);
1153	KUNIT_EXPECT_EQ(test, ret, params->expected_result);
1154}
1155
1156/*
1157 * Test that the registration of an HDMI connector with an HDMI
1158 * connector type succeeds.
1159 */
1160static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
1161{
1162	struct drm_connector_init_priv *priv = test->priv;
1163	unsigned int connector_type = *(unsigned int *)test->param_value;
1164	int ret;
1165
1166	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1167				       "Vendor", "Product",
1168				       &dummy_funcs,
1169				       &dummy_hdmi_funcs,
1170				       connector_type,
1171				       &priv->ddc,
1172				       BIT(HDMI_COLORSPACE_RGB),
1173				       8);
1174	KUNIT_EXPECT_EQ(test, ret, 0);
1175}
1176
1177static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
1178	DRM_MODE_CONNECTOR_HDMIA,
1179	DRM_MODE_CONNECTOR_HDMIB,
1180};
1181
1182static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc)
1183{
1184	sprintf(desc, "%s", drm_get_connector_type_name(*type));
1185}
1186
1187KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
1188		  drm_connector_hdmi_init_type_valid_tests,
1189		  drm_connector_hdmi_init_type_desc);
1190
1191/*
1192 * Test that the registration of an HDMI connector with an !HDMI
1193 * connector type fails.
1194 */
1195static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
1196{
1197	struct drm_connector_init_priv *priv = test->priv;
1198	unsigned int connector_type = *(unsigned int *)test->param_value;
1199	int ret;
1200
1201	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1202				       "Vendor", "Product",
1203				       &dummy_funcs,
1204				       &dummy_hdmi_funcs,
1205				       connector_type,
1206				       &priv->ddc,
1207				       BIT(HDMI_COLORSPACE_RGB),
1208				       8);
1209	KUNIT_EXPECT_LT(test, ret, 0);
1210}
1211
1212static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
1213	DRM_MODE_CONNECTOR_Unknown,
1214	DRM_MODE_CONNECTOR_VGA,
1215	DRM_MODE_CONNECTOR_DVII,
1216	DRM_MODE_CONNECTOR_DVID,
1217	DRM_MODE_CONNECTOR_DVIA,
1218	DRM_MODE_CONNECTOR_Composite,
1219	DRM_MODE_CONNECTOR_SVIDEO,
1220	DRM_MODE_CONNECTOR_LVDS,
1221	DRM_MODE_CONNECTOR_Component,
1222	DRM_MODE_CONNECTOR_9PinDIN,
1223	DRM_MODE_CONNECTOR_DisplayPort,
1224	DRM_MODE_CONNECTOR_TV,
1225	DRM_MODE_CONNECTOR_eDP,
1226	DRM_MODE_CONNECTOR_VIRTUAL,
1227	DRM_MODE_CONNECTOR_DSI,
1228	DRM_MODE_CONNECTOR_DPI,
1229	DRM_MODE_CONNECTOR_WRITEBACK,
1230	DRM_MODE_CONNECTOR_SPI,
1231	DRM_MODE_CONNECTOR_USB,
1232};
1233
1234KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
1235		  drm_connector_hdmi_init_type_invalid_tests,
1236		  drm_connector_hdmi_init_type_desc);
1237
1238static struct kunit_case drmm_connector_hdmi_init_tests[] = {
1239	KUNIT_CASE(drm_test_connector_hdmi_init_valid),
1240	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8),
1241	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10),
1242	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
1243	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
1244	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
1245	KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
1246	KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
1247	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_formats_yuv420_allowed,
1248			 drm_connector_hdmi_init_formats_yuv420_allowed_gen_params),
1249	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
1250	KUNIT_CASE(drm_test_connector_hdmi_init_null_product),
1251	KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
1252	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact),
1253	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long),
1254	KUNIT_CASE(drm_test_connector_hdmi_init_product_valid),
1255	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact),
1256	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long),
1257	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid),
1258	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
1259			 drm_connector_hdmi_init_type_valid_gen_params),
1260	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
1261			 drm_connector_hdmi_init_type_invalid_gen_params),
1262	{ }
1263};
1264
1265static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
1266	.name = "drmm_connector_hdmi_init",
1267	.init = drm_test_connector_init,
1268	.test_cases = drmm_connector_hdmi_init_tests,
1269};
1270
1271struct drm_get_tv_mode_from_name_test {
1272	const char *name;
1273	enum drm_connector_tv_mode expected_mode;
1274};
1275
1276#define TV_MODE_NAME(_name, _mode)		\
1277	{					\
1278		.name = _name,			\
1279		.expected_mode = _mode,		\
1280	}
1281
1282static void drm_test_get_tv_mode_from_name_valid(struct kunit *test)
1283{
1284	const struct drm_get_tv_mode_from_name_test *params = test->param_value;
1285
1286	KUNIT_EXPECT_EQ(test,
1287			drm_get_tv_mode_from_name(params->name, strlen(params->name)),
1288			params->expected_mode);
1289}
1290
1291static const
1292struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = {
1293	TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC),
1294	TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443),
1295	TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J),
1296	TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL),
1297	TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M),
1298	TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N),
1299	TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM),
1300	TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME),
1301};
1302
1303static void
1304drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t,
1305				     char *desc)
1306{
1307	sprintf(desc, "%s", t->name);
1308}
1309
1310KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid,
1311		  drm_get_tv_mode_from_name_valid_tests,
1312		  drm_get_tv_mode_from_name_valid_desc);
1313
1314static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test)
1315{
1316	const char *name = "NTS";
1317	int ret;
1318
1319	ret = drm_get_tv_mode_from_name(name, strlen(name));
1320	KUNIT_EXPECT_LT(test, ret, 0);
1321};
1322
1323static struct kunit_case drm_get_tv_mode_from_name_tests[] = {
1324	KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid,
1325			 drm_get_tv_mode_from_name_valid_gen_params),
1326	KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated),
1327	{ }
1328};
1329
1330static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
1331	.name = "drm_get_tv_mode_from_name",
1332	.test_cases = drm_get_tv_mode_from_name_tests,
1333};
1334
1335struct drm_hdmi_connector_get_broadcast_rgb_name_test {
1336	unsigned int kind;
1337	const char *expected_name;
1338};
1339
1340#define BROADCAST_RGB_TEST(_kind, _name)	\
1341	{					\
1342		.kind = _kind,			\
1343		.expected_name = _name,		\
1344	}
1345
1346static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test)
1347{
1348	const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params =
1349		test->param_value;
1350
1351	KUNIT_EXPECT_STREQ(test,
1352			   drm_hdmi_connector_get_broadcast_rgb_name(params->kind),
1353			   params->expected_name);
1354}
1355
1356static const
1357struct drm_hdmi_connector_get_broadcast_rgb_name_test
1358drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = {
1359	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"),
1360	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"),
1361	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"),
1362};
1363
1364static void
1365drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t,
1366						     char *desc)
1367{
1368	sprintf(desc, "%s", t->expected_name);
1369}
1370
1371KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid,
1372		  drm_hdmi_connector_get_broadcast_rgb_name_valid_tests,
1373		  drm_hdmi_connector_get_broadcast_rgb_name_valid_desc);
1374
1375static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test)
1376{
1377	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3));
1378};
1379
1380static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = {
1381	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name,
1382			 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params),
1383	KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid),
1384	{ }
1385};
1386
1387static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = {
1388	.name = "drm_hdmi_connector_get_broadcast_rgb_name",
1389	.test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
1390};
1391
1392struct drm_hdmi_connector_get_output_format_name_test {
1393	unsigned int kind;
1394	const char *expected_name;
1395};
1396
1397#define OUTPUT_FORMAT_TEST(_kind, _name)	\
1398	{					\
1399		.kind = _kind,			\
1400		.expected_name = _name,		\
1401	}
1402
1403static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test)
1404{
1405	const struct drm_hdmi_connector_get_output_format_name_test *params =
1406		test->param_value;
1407
1408	KUNIT_EXPECT_STREQ(test,
1409			   drm_hdmi_connector_get_output_format_name(params->kind),
1410			   params->expected_name);
1411}
1412
1413static const
1414struct drm_hdmi_connector_get_output_format_name_test
1415drm_hdmi_connector_get_output_format_name_valid_tests[] = {
1416	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"),
1417	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"),
1418	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"),
1419	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"),
1420};
1421
1422static void
1423drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t,
1424						     char *desc)
1425{
1426	sprintf(desc, "%s", t->expected_name);
1427}
1428
1429KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid,
1430		  drm_hdmi_connector_get_output_format_name_valid_tests,
1431		  drm_hdmi_connector_get_output_format_name_valid_desc);
1432
1433static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test)
1434{
1435	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4));
1436};
1437
1438static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = {
1439	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name,
1440			 drm_hdmi_connector_get_output_format_name_valid_gen_params),
1441	KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid),
1442	{ }
1443};
1444
1445static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = {
1446	.name = "drm_hdmi_connector_get_output_format_name",
1447	.test_cases = drm_hdmi_connector_get_output_format_name_tests,
1448};
1449
1450static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
1451{
1452	struct drm_connector_init_priv *priv = test->priv;
1453	struct drm_connector *connector = &priv->connector;
1454	struct drm_property *prop;
1455	int ret;
1456
1457	ret = drmm_connector_init(&priv->drm, connector,
1458				  &dummy_funcs,
1459				  DRM_MODE_CONNECTOR_HDMIA,
1460				  &priv->ddc);
1461	KUNIT_ASSERT_EQ(test, ret, 0);
1462
1463	ret = drm_connector_attach_broadcast_rgb_property(connector);
1464	KUNIT_ASSERT_EQ(test, ret, 0);
1465
1466	prop = connector->broadcast_rgb_property;
1467	KUNIT_ASSERT_NOT_NULL(test, prop);
1468	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1469}
1470
1471static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test)
1472{
1473	struct drm_connector_init_priv *priv = test->priv;
1474	struct drm_connector *connector = &priv->connector;
1475	struct drm_property *prop;
1476	int ret;
1477
1478	ret = drmm_connector_hdmi_init(&priv->drm, connector,
1479				       "Vendor", "Product",
1480				       &dummy_funcs,
1481				       &dummy_hdmi_funcs,
1482				       DRM_MODE_CONNECTOR_HDMIA,
1483				       &priv->ddc,
1484				       BIT(HDMI_COLORSPACE_RGB),
1485				       8);
1486	KUNIT_EXPECT_EQ(test, ret, 0);
1487
1488	ret = drm_connector_attach_broadcast_rgb_property(connector);
1489	KUNIT_ASSERT_EQ(test, ret, 0);
1490
1491	prop = connector->broadcast_rgb_property;
1492	KUNIT_ASSERT_NOT_NULL(test, prop);
1493	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1494}
1495
1496static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = {
1497	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property),
1498	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector),
1499	{ }
1500};
1501
1502static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = {
1503	.name = "drm_connector_attach_broadcast_rgb_property",
1504	.init = drm_test_connector_init,
1505	.test_cases = drm_connector_attach_broadcast_rgb_property_tests,
1506};
1507
1508/*
1509 * Test that for a given mode, with 8bpc and an RGB output the TMDS
1510 * character rate is equal to the mode pixel clock.
1511 */
1512static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test)
1513{
1514	struct drm_connector_init_priv *priv = test->priv;
1515	const struct drm_display_mode *mode;
1516	unsigned long long rate;
1517	struct drm_device *drm = &priv->drm;
1518
1519	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1520	KUNIT_ASSERT_NOT_NULL(test, mode);
1521
1522	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1523
1524	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
1525	KUNIT_ASSERT_GT(test, rate, 0);
1526	KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
1527}
1528
1529/*
1530 * Test that for a given mode, with 10bpc and an RGB output the TMDS
1531 * character rate is equal to 1.25 times the mode pixel clock.
1532 */
1533static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
1534{
1535	struct drm_connector_init_priv *priv = test->priv;
1536	const struct drm_display_mode *mode;
1537	unsigned long long rate;
1538	struct drm_device *drm = &priv->drm;
1539
1540	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1541	KUNIT_ASSERT_NOT_NULL(test, mode);
1542
1543	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1544
1545	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
1546	KUNIT_ASSERT_GT(test, rate, 0);
1547	KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
1548}
1549
1550/*
1551 * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
1552 * character rate computation fails.
1553 */
1554static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test)
1555{
1556	struct drm_connector_init_priv *priv = test->priv;
1557	const struct drm_display_mode *mode;
1558	unsigned long long rate;
1559	struct drm_device *drm = &priv->drm;
1560
1561	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1562	KUNIT_ASSERT_NOT_NULL(test, mode);
1563
1564	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
1565	KUNIT_EXPECT_EQ(test, rate, 0);
1566}
1567
1568/*
1569 * Test that for a given mode, with 12bpc and an RGB output the TMDS
1570 * character rate is equal to 1.5 times the mode pixel clock.
1571 */
1572static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
1573{
1574	struct drm_connector_init_priv *priv = test->priv;
1575	const struct drm_display_mode *mode;
1576	unsigned long long rate;
1577	struct drm_device *drm = &priv->drm;
1578
1579	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1580	KUNIT_ASSERT_NOT_NULL(test, mode);
1581
1582	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1583
1584	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
1585	KUNIT_ASSERT_GT(test, rate, 0);
1586	KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
1587}
1588
1589/*
1590 * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
1591 * character rate computation fails.
1592 */
1593static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test)
1594{
1595	struct drm_connector_init_priv *priv = test->priv;
1596	const struct drm_display_mode *mode;
1597	unsigned long long rate;
1598	struct drm_device *drm = &priv->drm;
1599
1600	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1601	KUNIT_ASSERT_NOT_NULL(test, mode);
1602
1603	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
1604	KUNIT_EXPECT_EQ(test, rate, 0);
1605}
1606
1607/*
1608 * Test that for a mode with the pixel repetition flag, the TMDS
1609 * character rate is indeed double the mode pixel clock.
1610 */
1611static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
1612{
1613	struct drm_connector_init_priv *priv = test->priv;
1614	const struct drm_display_mode *mode;
1615	unsigned long long rate;
1616	struct drm_device *drm = &priv->drm;
1617
1618	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6);
1619	KUNIT_ASSERT_NOT_NULL(test, mode);
1620
1621	KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1622
1623	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
1624	KUNIT_ASSERT_GT(test, rate, 0);
1625	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate);
1626}
1627
1628/*
1629 * Test that the TMDS character rate computation for the VIC modes
1630 * explicitly listed in the spec as supporting YUV420 succeed and return
1631 * half the mode pixel clock.
1632 */
1633static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test)
1634{
1635	struct drm_connector_init_priv *priv = test->priv;
1636	const struct drm_display_mode *mode;
1637	struct drm_device *drm = &priv->drm;
1638	unsigned long long rate;
1639	unsigned int vic = *(unsigned int *)test->param_value;
1640
1641	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1642	KUNIT_ASSERT_NOT_NULL(test, mode);
1643
1644	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1645
1646	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
1647	KUNIT_ASSERT_GT(test, rate, 0);
1648	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate);
1649}
1650
1651static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = {
1652	96, 97, 101, 102, 106, 107,
1653};
1654
1655static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc)
1656{
1657	sprintf(desc, "VIC %u", *vic);
1658}
1659
1660KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid,
1661		  drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests,
1662		  drm_hdmi_compute_mode_clock_yuv420_vic_desc);
1663
1664/*
1665 * Test that for a given mode listed supporting it and an YUV420 output
1666 * with 10bpc, the TMDS character rate is equal to 0.625 times the mode
1667 * pixel clock.
1668 */
1669static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test)
1670{
1671	struct drm_connector_init_priv *priv = test->priv;
1672	const struct drm_display_mode *mode;
1673	struct drm_device *drm = &priv->drm;
1674	unsigned int vic =
1675		drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
1676	unsigned long long rate;
1677
1678	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1679	KUNIT_ASSERT_NOT_NULL(test, mode);
1680
1681	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1682
1683	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420);
1684	KUNIT_ASSERT_GT(test, rate, 0);
1685
1686	KUNIT_EXPECT_EQ(test, mode->clock * 625, rate);
1687}
1688
1689/*
1690 * Test that for a given mode listed supporting it and an YUV420 output
1691 * with 12bpc, the TMDS character rate is equal to 0.75 times the mode
1692 * pixel clock.
1693 */
1694static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test)
1695{
1696	struct drm_connector_init_priv *priv = test->priv;
1697	const struct drm_display_mode *mode;
1698	struct drm_device *drm = &priv->drm;
1699	unsigned int vic =
1700		drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
1701	unsigned long long rate;
1702
1703	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1704	KUNIT_ASSERT_NOT_NULL(test, mode);
1705
1706	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1707
1708	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420);
1709	KUNIT_ASSERT_GT(test, rate, 0);
1710
1711	KUNIT_EXPECT_EQ(test, mode->clock * 750, rate);
1712}
1713
1714/*
1715 * Test that for a given mode, the computation of the TMDS character
1716 * rate with 8bpc and a YUV422 output succeeds and returns a rate equal
1717 * to the mode pixel clock.
1718 */
1719static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test)
1720{
1721	struct drm_connector_init_priv *priv = test->priv;
1722	const struct drm_display_mode *mode;
1723	struct drm_device *drm = &priv->drm;
1724	unsigned long long rate;
1725
1726	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1727	KUNIT_ASSERT_NOT_NULL(test, mode);
1728
1729	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1730
1731	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422);
1732	KUNIT_ASSERT_GT(test, rate, 0);
1733	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1734}
1735
1736/*
1737 * Test that for a given mode, the computation of the TMDS character
1738 * rate with 10bpc and a YUV422 output succeeds and returns a rate equal
1739 * to the mode pixel clock.
1740 */
1741static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test)
1742{
1743	struct drm_connector_init_priv *priv = test->priv;
1744	const struct drm_display_mode *mode;
1745	struct drm_device *drm = &priv->drm;
1746	unsigned long long rate;
1747
1748	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1749	KUNIT_ASSERT_NOT_NULL(test, mode);
1750
1751	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1752
1753	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422);
1754	KUNIT_ASSERT_GT(test, rate, 0);
1755	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1756}
1757
1758/*
1759 * Test that for a given mode, the computation of the TMDS character
1760 * rate with 12bpc and a YUV422 output succeeds and returns a rate equal
1761 * to the mode pixel clock.
1762 */
1763static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test)
1764{
1765	struct drm_connector_init_priv *priv = test->priv;
1766	const struct drm_display_mode *mode;
1767	struct drm_device *drm = &priv->drm;
1768	unsigned long long rate;
1769
1770	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1771	KUNIT_ASSERT_NOT_NULL(test, mode);
1772
1773	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1774
1775	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422);
1776	KUNIT_ASSERT_GT(test, rate, 0);
1777	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1778}
1779
1780static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = {
1781	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb),
1782	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc),
1783	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1),
1784	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc),
1785	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1),
1786	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double),
1787	KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid,
1788			 drm_hdmi_compute_mode_clock_yuv420_valid_gen_params),
1789	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc),
1790	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc),
1791	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc),
1792	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc),
1793	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc),
1794	{ }
1795};
1796
1797static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = {
1798	.name = "drm_test_connector_hdmi_compute_mode_clock",
1799	.init = drm_test_connector_init,
1800	.test_cases = drm_hdmi_compute_mode_clock_tests,
1801};
1802
1803kunit_test_suites(
1804	&drmm_connector_hdmi_init_test_suite,
1805	&drmm_connector_init_test_suite,
1806	&drm_connector_dynamic_init_test_suite,
1807	&drm_connector_dynamic_register_early_test_suite,
1808	&drm_connector_dynamic_register_test_suite,
1809	&drm_connector_attach_broadcast_rgb_property_test_suite,
1810	&drm_get_tv_mode_from_name_test_suite,
1811	&drm_hdmi_compute_mode_clock_test_suite,
1812	&drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
1813	&drm_hdmi_connector_get_output_format_name_test_suite
1814);
1815
1816MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
1817MODULE_DESCRIPTION("Kunit test for drm_modes functions");
1818MODULE_LICENSE("GPL");
~/ Read-only file preview.