Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: GPL-2.0
   2
   3/*
   4 * Kunit test for drm_hdmi_state_helper functions
   5 */
   6
   7#include <drm/drm_atomic.h>
   8#include <drm/drm_atomic_state_helper.h>
   9#include <drm/drm_atomic_uapi.h>
  10#include <drm/drm_drv.h>
  11#include <drm/drm_edid.h>
  12#include <drm/drm_connector.h>
  13#include <drm/drm_fourcc.h>
  14#include <drm/drm_kunit_helpers.h>
  15#include <drm/drm_managed.h>
  16#include <drm/drm_modeset_helper_vtables.h>
  17#include <drm/drm_print.h>
  18#include <drm/drm_probe_helper.h>
  19
  20#include <drm/display/drm_hdmi_helper.h>
  21#include <drm/display/drm_hdmi_state_helper.h>
  22
  23#include "../drm_crtc_internal.h"
  24
  25#include <kunit/test.h>
  26
  27#include "drm_kunit_edid.h"
  28
  29struct drm_atomic_helper_connector_hdmi_priv {
  30	struct drm_device drm;
  31	struct drm_plane *plane;
  32	struct drm_crtc *crtc;
  33	struct drm_encoder encoder;
  34	struct drm_connector connector;
  35
  36	const char *current_edid;
  37	size_t current_edid_len;
  38};
  39
  40#define connector_to_priv(c) \
  41	container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector)
  42
  43static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector)
  44{
  45	struct drm_device *drm = connector->dev;
  46	struct drm_display_mode *mode, *preferred;
  47
  48	mutex_lock(&drm->mode_config.mutex);
  49	preferred = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head);
  50	list_for_each_entry(mode, &connector->modes, head)
  51		if (mode->type & DRM_MODE_TYPE_PREFERRED)
  52			preferred = mode;
  53	mutex_unlock(&drm->mode_config.mutex);
  54
  55	return preferred;
  56}
  57
  58static int light_up_connector(struct kunit *test,
  59			      struct drm_device *drm,
  60			      struct drm_crtc *crtc,
  61			      struct drm_connector *connector,
  62			      struct drm_display_mode *mode,
  63			      struct drm_modeset_acquire_ctx *ctx)
  64{
  65	struct drm_atomic_state *state;
  66	struct drm_connector_state *conn_state;
  67	struct drm_crtc_state *crtc_state;
  68	int ret;
  69
  70	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
  71	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
  72
  73retry:
  74	conn_state = drm_atomic_get_connector_state(state, connector);
  75	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
  76
  77	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
  78	if (ret == -EDEADLK) {
  79		drm_atomic_state_clear(state);
  80		ret = drm_modeset_backoff(ctx);
  81		if (!ret)
  82			goto retry;
  83	}
  84	KUNIT_EXPECT_EQ(test, ret, 0);
  85
  86	crtc_state = drm_atomic_get_crtc_state(state, crtc);
  87	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
  88
  89	ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
  90	KUNIT_EXPECT_EQ(test, ret, 0);
  91
  92	crtc_state->enable = true;
  93	crtc_state->active = true;
  94
  95	ret = drm_atomic_commit(state);
  96	KUNIT_ASSERT_EQ(test, ret, 0);
  97
  98	return 0;
  99}
 100
 101static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
 102			      const char *edid, size_t edid_len)
 103{
 104	struct drm_atomic_helper_connector_hdmi_priv *priv =
 105		connector_to_priv(connector);
 106	struct drm_device *drm = connector->dev;
 107	int ret;
 108
 109	priv->current_edid = edid;
 110	priv->current_edid_len = edid_len;
 111
 112	mutex_lock(&drm->mode_config.mutex);
 113	ret = connector->funcs->fill_modes(connector, 4096, 4096);
 114	mutex_unlock(&drm->mode_config.mutex);
 115
 116	return ret;
 117}
 118
 119static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
 120};
 121
 122static enum drm_mode_status
 123reject_connector_tmds_char_rate_valid(const struct drm_connector *connector,
 124				      const struct drm_display_mode *mode,
 125				      unsigned long long tmds_rate)
 126{
 127	return MODE_BAD;
 128}
 129
 130static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {
 131	.tmds_char_rate_valid	= reject_connector_tmds_char_rate_valid,
 132};
 133
 134static int dummy_connector_get_modes(struct drm_connector *connector)
 135{
 136	struct drm_atomic_helper_connector_hdmi_priv *priv =
 137		connector_to_priv(connector);
 138	const struct drm_edid *edid;
 139	unsigned int num_modes;
 140
 141	edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len);
 142	if (!edid)
 143		return -EINVAL;
 144
 145	drm_edid_connector_update(connector, edid);
 146	num_modes = drm_edid_connector_add_modes(connector);
 147
 148	drm_edid_free(edid);
 149
 150	return num_modes;
 151}
 152
 153static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = {
 154	.atomic_check	= drm_atomic_helper_connector_hdmi_check,
 155	.get_modes	= dummy_connector_get_modes,
 156};
 157
 158static void dummy_hdmi_connector_reset(struct drm_connector *connector)
 159{
 160	drm_atomic_helper_connector_reset(connector);
 161	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
 162}
 163
 164static const struct drm_connector_funcs dummy_connector_funcs = {
 165	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 166	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
 167	.fill_modes		= drm_helper_probe_single_connector_modes,
 168	.reset			= dummy_hdmi_connector_reset,
 169};
 170
 171static
 172struct drm_atomic_helper_connector_hdmi_priv *
 173drm_atomic_helper_connector_hdmi_init(struct kunit *test,
 174				      unsigned int formats,
 175				      unsigned int max_bpc)
 176{
 177	struct drm_atomic_helper_connector_hdmi_priv *priv;
 178	struct drm_connector *conn;
 179	struct drm_encoder *enc;
 180	struct drm_device *drm;
 181	struct device *dev;
 182	int ret;
 183
 184	dev = drm_kunit_helper_alloc_device(test);
 185	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
 186
 187	priv = drm_kunit_helper_alloc_drm_device(test, dev,
 188						 struct drm_atomic_helper_connector_hdmi_priv, drm,
 189						 DRIVER_MODESET | DRIVER_ATOMIC);
 190	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
 191	test->priv = priv;
 192
 193	drm = &priv->drm;
 194	priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
 195							    NULL,
 196							    NULL,
 197							    NULL, 0,
 198							    NULL);
 199	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane);
 200
 201	priv->crtc = drm_kunit_helper_create_crtc(test, drm,
 202						  priv->plane, NULL,
 203						  NULL,
 204						  NULL);
 205	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc);
 206
 207	enc = &priv->encoder;
 208	ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
 209	KUNIT_ASSERT_EQ(test, ret, 0);
 210
 211	enc->possible_crtcs = drm_crtc_mask(priv->crtc);
 212
 213	conn = &priv->connector;
 214	ret = drmm_connector_hdmi_init(drm, conn,
 215				       "Vendor", "Product",
 216				       &dummy_connector_funcs,
 217				       &dummy_connector_hdmi_funcs,
 218				       DRM_MODE_CONNECTOR_HDMIA,
 219				       NULL,
 220				       formats,
 221				       max_bpc);
 222	KUNIT_ASSERT_EQ(test, ret, 0);
 223
 224	drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
 225	drm_connector_attach_encoder(conn, enc);
 226
 227	drm_mode_config_reset(drm);
 228
 229	ret = set_connector_edid(test, conn,
 230				 test_edid_hdmi_1080p_rgb_max_200mhz,
 231				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
 232	KUNIT_ASSERT_GT(test, ret, 0);
 233
 234	return priv;
 235}
 236
 237/*
 238 * Test that if we change the RGB quantization property to a different
 239 * value, we trigger a mode change on the connector's CRTC, which will
 240 * in turn disable/enable the connector.
 241 */
 242static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
 243{
 244	struct drm_atomic_helper_connector_hdmi_priv *priv;
 245	struct drm_modeset_acquire_ctx *ctx;
 246	struct drm_connector_state *old_conn_state;
 247	struct drm_connector_state *new_conn_state;
 248	struct drm_crtc_state *crtc_state;
 249	struct drm_atomic_state *state;
 250	struct drm_display_mode *preferred;
 251	struct drm_connector *conn;
 252	struct drm_device *drm;
 253	struct drm_crtc *crtc;
 254	int ret;
 255
 256	priv = drm_atomic_helper_connector_hdmi_init(test,
 257						     BIT(HDMI_COLORSPACE_RGB),
 258						     8);
 259	KUNIT_ASSERT_NOT_NULL(test, priv);
 260
 261	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 262	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 263
 264	conn = &priv->connector;
 265	preferred = find_preferred_mode(conn);
 266	KUNIT_ASSERT_NOT_NULL(test, preferred);
 267
 268	drm = &priv->drm;
 269	crtc = priv->crtc;
 270	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 271	KUNIT_ASSERT_EQ(test, ret, 0);
 272
 273	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 274	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 275
 276	new_conn_state = drm_atomic_get_connector_state(state, conn);
 277	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
 278
 279	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 280	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 281
 282	new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
 283
 284	KUNIT_ASSERT_NE(test,
 285			old_conn_state->hdmi.broadcast_rgb,
 286			new_conn_state->hdmi.broadcast_rgb);
 287
 288	ret = drm_atomic_check_only(state);
 289	KUNIT_ASSERT_EQ(test, ret, 0);
 290
 291	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
 292	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
 293	KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL);
 294
 295	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 296	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
 297	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
 298}
 299
 300/*
 301 * Test that if we set the RGB quantization property to the same value,
 302 * we don't trigger a mode change on the connector's CRTC and leave the
 303 * connector unaffected.
 304 */
 305static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test)
 306{
 307	struct drm_atomic_helper_connector_hdmi_priv *priv;
 308	struct drm_modeset_acquire_ctx *ctx;
 309	struct drm_connector_state *old_conn_state;
 310	struct drm_connector_state *new_conn_state;
 311	struct drm_crtc_state *crtc_state;
 312	struct drm_atomic_state *state;
 313	struct drm_display_mode *preferred;
 314	struct drm_connector *conn;
 315	struct drm_device *drm;
 316	struct drm_crtc *crtc;
 317	int ret;
 318
 319	priv = drm_atomic_helper_connector_hdmi_init(test,
 320						     BIT(HDMI_COLORSPACE_RGB),
 321						     8);
 322	KUNIT_ASSERT_NOT_NULL(test, priv);
 323
 324	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 325	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 326
 327	conn = &priv->connector;
 328	preferred = find_preferred_mode(conn);
 329	KUNIT_ASSERT_NOT_NULL(test, preferred);
 330
 331	drm = &priv->drm;
 332	crtc = priv->crtc;
 333	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 334	KUNIT_ASSERT_EQ(test, ret, 0);
 335
 336	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 337	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 338
 339	new_conn_state = drm_atomic_get_connector_state(state, conn);
 340	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
 341
 342	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 343	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 344
 345	new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb;
 346
 347	ret = drm_atomic_check_only(state);
 348	KUNIT_ASSERT_EQ(test, ret, 0);
 349
 350	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 351	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 352
 353	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
 354	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
 355
 356	KUNIT_EXPECT_EQ(test,
 357			old_conn_state->hdmi.broadcast_rgb,
 358			new_conn_state->hdmi.broadcast_rgb);
 359
 360	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 361	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
 362	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 363}
 364
 365/*
 366 * Test that for an HDMI connector, with an HDMI monitor, if the
 367 * Broadcast RGB property is set to auto with a mode that isn't the
 368 * VIC-1 mode, we will get a limited RGB Quantization Range.
 369 */
 370static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
 371{
 372	struct drm_atomic_helper_connector_hdmi_priv *priv;
 373	struct drm_modeset_acquire_ctx *ctx;
 374	struct drm_connector_state *conn_state;
 375	struct drm_atomic_state *state;
 376	struct drm_display_mode *preferred;
 377	struct drm_connector *conn;
 378	struct drm_device *drm;
 379	struct drm_crtc *crtc;
 380	int ret;
 381
 382	priv = drm_atomic_helper_connector_hdmi_init(test,
 383						     BIT(HDMI_COLORSPACE_RGB),
 384						     8);
 385	KUNIT_ASSERT_NOT_NULL(test, priv);
 386
 387	conn = &priv->connector;
 388	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
 389
 390	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 391	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 392
 393	preferred = find_preferred_mode(conn);
 394	KUNIT_ASSERT_NOT_NULL(test, preferred);
 395	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
 396
 397	drm = &priv->drm;
 398	crtc = priv->crtc;
 399	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 400	KUNIT_ASSERT_EQ(test, ret, 0);
 401
 402	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 403	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 404
 405	conn_state = drm_atomic_get_connector_state(state, conn);
 406	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 407
 408	KUNIT_ASSERT_EQ(test,
 409			conn_state->hdmi.broadcast_rgb,
 410			DRM_HDMI_BROADCAST_RGB_AUTO);
 411
 412	ret = drm_atomic_check_only(state);
 413	KUNIT_ASSERT_EQ(test, ret, 0);
 414
 415	conn_state = drm_atomic_get_connector_state(state, conn);
 416	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 417
 418	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
 419}
 420
 421/*
 422 * Test that for an HDMI connector, with an HDMI monitor, if the
 423 * Broadcast RGB property is set to auto with a VIC-1 mode, we will get
 424 * a full RGB Quantization Range.
 425 */
 426static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
 427{
 428	struct drm_atomic_helper_connector_hdmi_priv *priv;
 429	struct drm_modeset_acquire_ctx *ctx;
 430	struct drm_connector_state *conn_state;
 431	struct drm_atomic_state *state;
 432	struct drm_display_mode *mode;
 433	struct drm_connector *conn;
 434	struct drm_device *drm;
 435	struct drm_crtc *crtc;
 436	int ret;
 437
 438	priv = drm_atomic_helper_connector_hdmi_init(test,
 439						     BIT(HDMI_COLORSPACE_RGB),
 440						     8);
 441	KUNIT_ASSERT_NOT_NULL(test, priv);
 442
 443	drm = &priv->drm;
 444	conn = &priv->connector;
 445	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
 446
 447	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 448	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 449
 450	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
 451	KUNIT_ASSERT_NOT_NULL(test, mode);
 452
 453	drm = &priv->drm;
 454	crtc = priv->crtc;
 455	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
 456	KUNIT_ASSERT_EQ(test, ret, 0);
 457
 458	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 459	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 460
 461	conn_state = drm_atomic_get_connector_state(state, conn);
 462	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 463
 464	KUNIT_ASSERT_EQ(test,
 465			conn_state->hdmi.broadcast_rgb,
 466			DRM_HDMI_BROADCAST_RGB_AUTO);
 467
 468	ret = drm_atomic_check_only(state);
 469	KUNIT_ASSERT_EQ(test, ret, 0);
 470
 471	conn_state = drm_atomic_get_connector_state(state, conn);
 472	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 473
 474	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
 475}
 476
 477/*
 478 * Test that for an HDMI connector, with an HDMI monitor, if the
 479 * Broadcast RGB property is set to full with a mode that isn't the
 480 * VIC-1 mode, we will get a full RGB Quantization Range.
 481 */
 482static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
 483{
 484	struct drm_atomic_helper_connector_hdmi_priv *priv;
 485	struct drm_modeset_acquire_ctx *ctx;
 486	struct drm_connector_state *conn_state;
 487	struct drm_atomic_state *state;
 488	struct drm_display_mode *preferred;
 489	struct drm_connector *conn;
 490	struct drm_device *drm;
 491	struct drm_crtc *crtc;
 492	int ret;
 493
 494	priv = drm_atomic_helper_connector_hdmi_init(test,
 495						     BIT(HDMI_COLORSPACE_RGB),
 496						     8);
 497	KUNIT_ASSERT_NOT_NULL(test, priv);
 498
 499	conn = &priv->connector;
 500	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
 501
 502	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 503	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 504
 505	preferred = find_preferred_mode(conn);
 506	KUNIT_ASSERT_NOT_NULL(test, preferred);
 507	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
 508
 509	drm = &priv->drm;
 510	crtc = priv->crtc;
 511	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 512	KUNIT_ASSERT_EQ(test, ret, 0);
 513
 514	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 515	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 516
 517	conn_state = drm_atomic_get_connector_state(state, conn);
 518	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 519
 520	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
 521
 522	ret = drm_atomic_check_only(state);
 523	KUNIT_ASSERT_EQ(test, ret, 0);
 524
 525	conn_state = drm_atomic_get_connector_state(state, conn);
 526	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 527
 528	KUNIT_ASSERT_EQ(test,
 529			conn_state->hdmi.broadcast_rgb,
 530			DRM_HDMI_BROADCAST_RGB_FULL);
 531
 532	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
 533}
 534
 535/*
 536 * Test that for an HDMI connector, with an HDMI monitor, if the
 537 * Broadcast RGB property is set to full with a VIC-1 mode, we will get
 538 * a full RGB Quantization Range.
 539 */
 540static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
 541{
 542	struct drm_atomic_helper_connector_hdmi_priv *priv;
 543	struct drm_modeset_acquire_ctx *ctx;
 544	struct drm_connector_state *conn_state;
 545	struct drm_atomic_state *state;
 546	struct drm_display_mode *mode;
 547	struct drm_connector *conn;
 548	struct drm_device *drm;
 549	struct drm_crtc *crtc;
 550	int ret;
 551
 552	priv = drm_atomic_helper_connector_hdmi_init(test,
 553						     BIT(HDMI_COLORSPACE_RGB),
 554						     8);
 555	KUNIT_ASSERT_NOT_NULL(test, priv);
 556
 557	drm = &priv->drm;
 558	conn = &priv->connector;
 559	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
 560
 561	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 562	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 563
 564	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
 565	KUNIT_ASSERT_NOT_NULL(test, mode);
 566
 567	drm = &priv->drm;
 568	crtc = priv->crtc;
 569	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
 570	KUNIT_ASSERT_EQ(test, ret, 0);
 571
 572	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 573	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 574
 575	conn_state = drm_atomic_get_connector_state(state, conn);
 576	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 577
 578	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
 579
 580	ret = drm_atomic_check_only(state);
 581	KUNIT_ASSERT_EQ(test, ret, 0);
 582
 583	conn_state = drm_atomic_get_connector_state(state, conn);
 584	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 585
 586	KUNIT_ASSERT_EQ(test,
 587			conn_state->hdmi.broadcast_rgb,
 588			DRM_HDMI_BROADCAST_RGB_FULL);
 589
 590	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
 591}
 592
 593/*
 594 * Test that for an HDMI connector, with an HDMI monitor, if the
 595 * Broadcast RGB property is set to limited with a mode that isn't the
 596 * VIC-1 mode, we will get a limited RGB Quantization Range.
 597 */
 598static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
 599{
 600	struct drm_atomic_helper_connector_hdmi_priv *priv;
 601	struct drm_modeset_acquire_ctx *ctx;
 602	struct drm_connector_state *conn_state;
 603	struct drm_atomic_state *state;
 604	struct drm_display_mode *preferred;
 605	struct drm_connector *conn;
 606	struct drm_device *drm;
 607	struct drm_crtc *crtc;
 608	int ret;
 609
 610	priv = drm_atomic_helper_connector_hdmi_init(test,
 611						     BIT(HDMI_COLORSPACE_RGB),
 612						     8);
 613	KUNIT_ASSERT_NOT_NULL(test, priv);
 614
 615	conn = &priv->connector;
 616	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
 617
 618	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 619	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 620
 621	preferred = find_preferred_mode(conn);
 622	KUNIT_ASSERT_NOT_NULL(test, preferred);
 623	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
 624
 625	drm = &priv->drm;
 626	crtc = priv->crtc;
 627	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 628	KUNIT_ASSERT_EQ(test, ret, 0);
 629
 630	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 631	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 632
 633	conn_state = drm_atomic_get_connector_state(state, conn);
 634	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 635
 636	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
 637
 638	ret = drm_atomic_check_only(state);
 639	KUNIT_ASSERT_EQ(test, ret, 0);
 640
 641	conn_state = drm_atomic_get_connector_state(state, conn);
 642	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 643
 644	KUNIT_ASSERT_EQ(test,
 645			conn_state->hdmi.broadcast_rgb,
 646			DRM_HDMI_BROADCAST_RGB_LIMITED);
 647
 648	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
 649}
 650
 651/*
 652 * Test that for an HDMI connector, with an HDMI monitor, if the
 653 * Broadcast RGB property is set to limited with a VIC-1 mode, we will
 654 * get a limited RGB Quantization Range.
 655 */
 656static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test)
 657{
 658	struct drm_atomic_helper_connector_hdmi_priv *priv;
 659	struct drm_modeset_acquire_ctx *ctx;
 660	struct drm_connector_state *conn_state;
 661	struct drm_atomic_state *state;
 662	struct drm_display_mode *mode;
 663	struct drm_connector *conn;
 664	struct drm_device *drm;
 665	struct drm_crtc *crtc;
 666	int ret;
 667
 668	priv = drm_atomic_helper_connector_hdmi_init(test,
 669						     BIT(HDMI_COLORSPACE_RGB),
 670						     8);
 671	KUNIT_ASSERT_NOT_NULL(test, priv);
 672
 673	drm = &priv->drm;
 674	conn = &priv->connector;
 675	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
 676
 677	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 678	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 679
 680	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
 681	KUNIT_ASSERT_NOT_NULL(test, mode);
 682
 683	drm = &priv->drm;
 684	crtc = priv->crtc;
 685	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
 686	KUNIT_ASSERT_EQ(test, ret, 0);
 687
 688	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 689	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 690
 691	conn_state = drm_atomic_get_connector_state(state, conn);
 692	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 693
 694	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
 695
 696	ret = drm_atomic_check_only(state);
 697	KUNIT_ASSERT_EQ(test, ret, 0);
 698
 699	conn_state = drm_atomic_get_connector_state(state, conn);
 700	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 701
 702	KUNIT_ASSERT_EQ(test,
 703			conn_state->hdmi.broadcast_rgb,
 704			DRM_HDMI_BROADCAST_RGB_LIMITED);
 705
 706	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
 707}
 708
 709/*
 710 * Test that if we change the maximum bpc property to a different value,
 711 * we trigger a mode change on the connector's CRTC, which will in turn
 712 * disable/enable the connector.
 713 */
 714static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
 715{
 716	struct drm_atomic_helper_connector_hdmi_priv *priv;
 717	struct drm_modeset_acquire_ctx *ctx;
 718	struct drm_connector_state *old_conn_state;
 719	struct drm_connector_state *new_conn_state;
 720	struct drm_crtc_state *crtc_state;
 721	struct drm_atomic_state *state;
 722	struct drm_display_mode *preferred;
 723	struct drm_connector *conn;
 724	struct drm_device *drm;
 725	struct drm_crtc *crtc;
 726	int ret;
 727
 728	priv = drm_atomic_helper_connector_hdmi_init(test,
 729						     BIT(HDMI_COLORSPACE_RGB),
 730						     10);
 731	KUNIT_ASSERT_NOT_NULL(test, priv);
 732
 733	conn = &priv->connector;
 734	ret = set_connector_edid(test, conn,
 735				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
 736				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
 737	KUNIT_ASSERT_GT(test, ret, 0);
 738
 739	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 740	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 741
 742	preferred = find_preferred_mode(conn);
 743	KUNIT_ASSERT_NOT_NULL(test, preferred);
 744
 745	drm = &priv->drm;
 746	crtc = priv->crtc;
 747	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 748	KUNIT_ASSERT_EQ(test, ret, 0);
 749
 750	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 751	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 752
 753	new_conn_state = drm_atomic_get_connector_state(state, conn);
 754	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
 755
 756	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 757	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 758
 759	new_conn_state->max_requested_bpc = 8;
 760
 761	KUNIT_ASSERT_NE(test,
 762			old_conn_state->max_requested_bpc,
 763			new_conn_state->max_requested_bpc);
 764
 765	ret = drm_atomic_check_only(state);
 766	KUNIT_ASSERT_EQ(test, ret, 0);
 767
 768	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 769	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 770
 771	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
 772	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
 773
 774	KUNIT_ASSERT_NE(test,
 775			old_conn_state->hdmi.output_bpc,
 776			new_conn_state->hdmi.output_bpc);
 777
 778	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 779	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
 780	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
 781}
 782
 783/*
 784 * Test that if we set the output bpc property to the same value, we
 785 * don't trigger a mode change on the connector's CRTC and leave the
 786 * connector unaffected.
 787 */
 788static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 789{
 790	struct drm_atomic_helper_connector_hdmi_priv *priv;
 791	struct drm_modeset_acquire_ctx *ctx;
 792	struct drm_connector_state *old_conn_state;
 793	struct drm_connector_state *new_conn_state;
 794	struct drm_crtc_state *crtc_state;
 795	struct drm_atomic_state *state;
 796	struct drm_display_mode *preferred;
 797	struct drm_connector *conn;
 798	struct drm_device *drm;
 799	struct drm_crtc *crtc;
 800	int ret;
 801
 802	priv = drm_atomic_helper_connector_hdmi_init(test,
 803						     BIT(HDMI_COLORSPACE_RGB),
 804						     10);
 805	KUNIT_ASSERT_NOT_NULL(test, priv);
 806
 807	conn = &priv->connector;
 808	ret = set_connector_edid(test, conn,
 809				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
 810				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
 811	KUNIT_ASSERT_GT(test, ret, 0);
 812
 813	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 814	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 815
 816	preferred = find_preferred_mode(conn);
 817	KUNIT_ASSERT_NOT_NULL(test, preferred);
 818
 819	drm = &priv->drm;
 820	crtc = priv->crtc;
 821	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 822	KUNIT_ASSERT_EQ(test, ret, 0);
 823
 824	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
 825	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 826
 827	new_conn_state = drm_atomic_get_connector_state(state, conn);
 828	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
 829
 830	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 831	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 832
 833	KUNIT_ASSERT_EQ(test,
 834			new_conn_state->hdmi.output_bpc,
 835			old_conn_state->hdmi.output_bpc);
 836
 837	ret = drm_atomic_check_only(state);
 838	KUNIT_ASSERT_EQ(test, ret, 0);
 839
 840	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 841	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 842
 843	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
 844	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
 845
 846	KUNIT_EXPECT_EQ(test,
 847			old_conn_state->hdmi.output_bpc,
 848			new_conn_state->hdmi.output_bpc);
 849
 850	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 851	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
 852	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 853}
 854
 855/*
 856 * Test that if we have an HDMI connector but a !HDMI display, we always
 857 * output RGB with 8 bpc.
 858 */
 859static void drm_test_check_output_bpc_dvi(struct kunit *test)
 860{
 861	struct drm_atomic_helper_connector_hdmi_priv *priv;
 862	struct drm_modeset_acquire_ctx *ctx;
 863	struct drm_connector_state *conn_state;
 864	struct drm_display_info *info;
 865	struct drm_display_mode *preferred;
 866	struct drm_connector *conn;
 867	struct drm_device *drm;
 868	struct drm_crtc *crtc;
 869	int ret;
 870
 871	priv = drm_atomic_helper_connector_hdmi_init(test,
 872						     BIT(HDMI_COLORSPACE_RGB) |
 873						     BIT(HDMI_COLORSPACE_YUV422) |
 874						     BIT(HDMI_COLORSPACE_YUV444),
 875						     12);
 876	KUNIT_ASSERT_NOT_NULL(test, priv);
 877
 878	conn = &priv->connector;
 879	ret = set_connector_edid(test, conn,
 880				 test_edid_dvi_1080p,
 881				 ARRAY_SIZE(test_edid_dvi_1080p));
 882	KUNIT_ASSERT_GT(test, ret, 0);
 883
 884	info = &conn->display_info;
 885	KUNIT_ASSERT_FALSE(test, info->is_hdmi);
 886
 887	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 888	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 889
 890	preferred = find_preferred_mode(conn);
 891	KUNIT_ASSERT_NOT_NULL(test, preferred);
 892
 893	drm = &priv->drm;
 894	crtc = priv->crtc;
 895	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 896	KUNIT_ASSERT_EQ(test, ret, 0);
 897
 898	conn_state = conn->state;
 899	KUNIT_ASSERT_NOT_NULL(test, conn_state);
 900
 901	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
 902	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
 903}
 904
 905/*
 906 * Test that when doing a commit which would use RGB 8bpc, the TMDS
 907 * clock rate stored in the connector state is equal to the mode clock
 908 */
 909static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
 910{
 911	struct drm_atomic_helper_connector_hdmi_priv *priv;
 912	struct drm_modeset_acquire_ctx *ctx;
 913	struct drm_connector_state *conn_state;
 914	struct drm_display_mode *preferred;
 915	struct drm_connector *conn;
 916	struct drm_device *drm;
 917	struct drm_crtc *crtc;
 918	int ret;
 919
 920	priv = drm_atomic_helper_connector_hdmi_init(test,
 921						     BIT(HDMI_COLORSPACE_RGB),
 922						     8);
 923	KUNIT_ASSERT_NOT_NULL(test, priv);
 924
 925	conn = &priv->connector;
 926	ret = set_connector_edid(test, conn,
 927				 test_edid_hdmi_1080p_rgb_max_200mhz,
 928				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
 929	KUNIT_ASSERT_GT(test, ret, 0);
 930
 931	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 932	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 933
 934	preferred = find_preferred_mode(conn);
 935	KUNIT_ASSERT_NOT_NULL(test, preferred);
 936	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
 937
 938	drm = &priv->drm;
 939	crtc = priv->crtc;
 940	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 941	KUNIT_ASSERT_EQ(test, ret, 0);
 942
 943	conn_state = conn->state;
 944	KUNIT_ASSERT_NOT_NULL(test, conn_state);
 945
 946	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8);
 947	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
 948	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
 949}
 950
 951/*
 952 * Test that when doing a commit which would use RGB 10bpc, the TMDS
 953 * clock rate stored in the connector state is equal to 1.25 times the
 954 * mode pixel clock
 955 */
 956static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
 957{
 958	struct drm_atomic_helper_connector_hdmi_priv *priv;
 959	struct drm_modeset_acquire_ctx *ctx;
 960	struct drm_connector_state *conn_state;
 961	struct drm_display_mode *preferred;
 962	struct drm_connector *conn;
 963	struct drm_device *drm;
 964	struct drm_crtc *crtc;
 965	int ret;
 966
 967	priv = drm_atomic_helper_connector_hdmi_init(test,
 968						     BIT(HDMI_COLORSPACE_RGB),
 969						     10);
 970	KUNIT_ASSERT_NOT_NULL(test, priv);
 971
 972	conn = &priv->connector;
 973	ret = set_connector_edid(test, conn,
 974				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
 975				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
 976	KUNIT_ASSERT_GT(test, ret, 0);
 977
 978	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 979	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 980
 981	preferred = find_preferred_mode(conn);
 982	KUNIT_ASSERT_NOT_NULL(test, preferred);
 983	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
 984
 985	drm = &priv->drm;
 986	crtc = priv->crtc;
 987	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
 988	KUNIT_ASSERT_EQ(test, ret, 0);
 989
 990	conn_state = conn->state;
 991	KUNIT_ASSERT_NOT_NULL(test, conn_state);
 992
 993	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10);
 994	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
 995	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
 996}
 997
 998/*
 999 * Test that when doing a commit which would use RGB 12bpc, the TMDS
1000 * clock rate stored in the connector state is equal to 1.5 times the
1001 * mode pixel clock
1002 */
1003static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
1004{
1005	struct drm_atomic_helper_connector_hdmi_priv *priv;
1006	struct drm_modeset_acquire_ctx *ctx;
1007	struct drm_connector_state *conn_state;
1008	struct drm_display_mode *preferred;
1009	struct drm_connector *conn;
1010	struct drm_device *drm;
1011	struct drm_crtc *crtc;
1012	int ret;
1013
1014	priv = drm_atomic_helper_connector_hdmi_init(test,
1015						     BIT(HDMI_COLORSPACE_RGB),
1016						     12);
1017	KUNIT_ASSERT_NOT_NULL(test, priv);
1018
1019	conn = &priv->connector;
1020	ret = set_connector_edid(test, conn,
1021				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
1022				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
1023	KUNIT_ASSERT_GT(test, ret, 0);
1024
1025	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1026	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1027
1028	preferred = find_preferred_mode(conn);
1029	KUNIT_ASSERT_NOT_NULL(test, preferred);
1030	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1031
1032	drm = &priv->drm;
1033	crtc = priv->crtc;
1034	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1035	KUNIT_ASSERT_EQ(test, ret, 0);
1036
1037	conn_state = conn->state;
1038	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1039
1040	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12);
1041	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1042	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
1043}
1044
1045/*
1046 * Test that if we filter a rate through our hook, it's indeed rejected
1047 * by the whole atomic_check logic.
1048 *
1049 * We do so by first doing a commit on the pipeline to make sure that it
1050 * works, change the HDMI helpers pointer, and then try the same commit
1051 * again to see if it fails as it should.
1052 */
1053static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
1054{
1055	struct drm_atomic_helper_connector_hdmi_priv *priv;
1056	struct drm_modeset_acquire_ctx *ctx;
1057	struct drm_atomic_state *state;
1058	struct drm_display_mode *preferred;
1059	struct drm_crtc_state *crtc_state;
1060	struct drm_connector *conn;
1061	struct drm_device *drm;
1062	struct drm_crtc *crtc;
1063	int ret;
1064
1065	priv = drm_atomic_helper_connector_hdmi_init(test,
1066						     BIT(HDMI_COLORSPACE_RGB),
1067						     8);
1068	KUNIT_ASSERT_NOT_NULL(test, priv);
1069
1070	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1071	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1072
1073	conn = &priv->connector;
1074	preferred = find_preferred_mode(conn);
1075	KUNIT_ASSERT_NOT_NULL(test, preferred);
1076
1077	drm = &priv->drm;
1078	crtc = priv->crtc;
1079	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1080	KUNIT_ASSERT_EQ(test, ret, 0);
1081
1082	/* You shouldn't be doing that at home. */
1083	conn->hdmi.funcs = &reject_connector_hdmi_funcs;
1084
1085	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
1086	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1087
1088	crtc_state = drm_atomic_get_crtc_state(state, crtc);
1089	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
1090
1091	crtc_state->connectors_changed = true;
1092
1093	ret = drm_atomic_check_only(state);
1094	KUNIT_EXPECT_LT(test, ret, 0);
1095}
1096
1097/*
1098 * Test that if:
1099 * - We have an HDMI connector supporting RGB only
1100 * - The chosen mode has a TMDS character rate higher than the display
1101 *   supports in RGB/12bpc
1102 * - The chosen mode has a TMDS character rate lower than the display
1103 *   supports in RGB/10bpc.
1104 *
1105 * Then we will pick the latter, and the computed TMDS character rate
1106 * will be equal to 1.25 times the mode pixel clock.
1107 */
1108static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)
1109{
1110	struct drm_atomic_helper_connector_hdmi_priv *priv;
1111	struct drm_modeset_acquire_ctx *ctx;
1112	struct drm_connector_state *conn_state;
1113	struct drm_display_info *info;
1114	struct drm_display_mode *preferred;
1115	unsigned long long rate;
1116	struct drm_connector *conn;
1117	struct drm_device *drm;
1118	struct drm_crtc *crtc;
1119	int ret;
1120
1121	priv = drm_atomic_helper_connector_hdmi_init(test,
1122						     BIT(HDMI_COLORSPACE_RGB),
1123						     12);
1124	KUNIT_ASSERT_NOT_NULL(test, priv);
1125
1126	conn = &priv->connector;
1127	ret = set_connector_edid(test, conn,
1128				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1129				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1130	KUNIT_ASSERT_GT(test, ret, 0);
1131
1132	info = &conn->display_info;
1133	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1134	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1135
1136	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1137	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1138
1139	preferred = find_preferred_mode(conn);
1140	KUNIT_ASSERT_NOT_NULL(test, preferred);
1141	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1142
1143	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1144	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1145
1146	rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
1147	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1148
1149	drm = &priv->drm;
1150	crtc = priv->crtc;
1151	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1152	KUNIT_EXPECT_EQ(test, ret, 0);
1153
1154	conn_state = conn->state;
1155	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1156
1157	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1158	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1159	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
1160}
1161
1162/*
1163 * Test that if:
1164 * - We have an HDMI connector supporting both RGB and YUV422 and up to
1165 *   12 bpc
1166 * - The chosen mode has a TMDS character rate higher than the display
1167 *   supports in RGB/12bpc but lower than the display supports in
1168 *   RGB/10bpc
1169 * - The chosen mode has a TMDS character rate lower than the display
1170 *   supports in YUV422/12bpc.
1171 *
1172 * Then we will prefer to keep the RGB format with a lower bpc over
1173 * picking YUV422.
1174 */
1175static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)
1176{
1177	struct drm_atomic_helper_connector_hdmi_priv *priv;
1178	struct drm_modeset_acquire_ctx *ctx;
1179	struct drm_connector_state *conn_state;
1180	struct drm_display_info *info;
1181	struct drm_display_mode *preferred;
1182	unsigned long long rate;
1183	struct drm_connector *conn;
1184	struct drm_device *drm;
1185	struct drm_crtc *crtc;
1186	int ret;
1187
1188	priv = drm_atomic_helper_connector_hdmi_init(test,
1189						     BIT(HDMI_COLORSPACE_RGB) |
1190						     BIT(HDMI_COLORSPACE_YUV422) |
1191						     BIT(HDMI_COLORSPACE_YUV444),
1192						     12);
1193	KUNIT_ASSERT_NOT_NULL(test, priv);
1194
1195	conn = &priv->connector;
1196	ret = set_connector_edid(test, conn,
1197				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1198				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1199	KUNIT_ASSERT_GT(test, ret, 0);
1200
1201	info = &conn->display_info;
1202	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1203	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1204
1205	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1206	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1207
1208	preferred = find_preferred_mode(conn);
1209	KUNIT_ASSERT_NOT_NULL(test, preferred);
1210	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1211
1212	rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
1213	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1214
1215	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1216	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1217
1218	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1219	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1220
1221	drm = &priv->drm;
1222	crtc = priv->crtc;
1223	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1224	KUNIT_EXPECT_EQ(test, ret, 0);
1225
1226	conn_state = conn->state;
1227	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1228
1229	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1230	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1231}
1232
1233/*
1234 * Test that if a driver and screen supports RGB and YUV formats, and we
1235 * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could
1236 * have had a higher bpc.
1237 */
1238static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
1239{
1240	struct drm_atomic_helper_connector_hdmi_priv *priv;
1241	struct drm_modeset_acquire_ctx *ctx;
1242	struct drm_connector_state *conn_state;
1243	struct drm_display_info *info;
1244	struct drm_display_mode *mode;
1245	unsigned long long rate;
1246	struct drm_connector *conn;
1247	struct drm_device *drm;
1248	struct drm_crtc *crtc;
1249	int ret;
1250
1251	priv = drm_atomic_helper_connector_hdmi_init(test,
1252						     BIT(HDMI_COLORSPACE_RGB) |
1253						     BIT(HDMI_COLORSPACE_YUV422) |
1254						     BIT(HDMI_COLORSPACE_YUV444),
1255						     12);
1256	KUNIT_ASSERT_NOT_NULL(test, priv);
1257
1258	drm = &priv->drm;
1259	conn = &priv->connector;
1260	ret = set_connector_edid(test, conn,
1261				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1262				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1263	KUNIT_ASSERT_GT(test, ret, 0);
1264
1265	info = &conn->display_info;
1266	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1267	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1268
1269	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1270	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1271
1272	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1273	KUNIT_ASSERT_NOT_NULL(test, mode);
1274
1275	/*
1276	 * NOTE: We can't use drm_hdmi_compute_mode_clock()
1277	 * here because we're trying to get the rate of an invalid
1278	 * configuration.
1279	 *
1280	 * Thus, we have to calculate the rate by hand.
1281	 */
1282	rate = mode->clock * 1500;
1283	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1284
1285	drm = &priv->drm;
1286	crtc = priv->crtc;
1287	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
1288	KUNIT_EXPECT_EQ(test, ret, 0);
1289
1290	conn_state = conn->state;
1291	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1292
1293	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1294	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1295}
1296
1297/*
1298 * Test that if a driver supports only RGB but the screen also supports
1299 * YUV formats, we only end up with an RGB format.
1300 */
1301static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)
1302{
1303	struct drm_atomic_helper_connector_hdmi_priv *priv;
1304	struct drm_modeset_acquire_ctx *ctx;
1305	struct drm_connector_state *conn_state;
1306	struct drm_display_info *info;
1307	struct drm_display_mode *preferred;
1308	unsigned long long rate;
1309	struct drm_connector *conn;
1310	struct drm_device *drm;
1311	struct drm_crtc *crtc;
1312	int ret;
1313
1314	priv = drm_atomic_helper_connector_hdmi_init(test,
1315						     BIT(HDMI_COLORSPACE_RGB),
1316						     12);
1317	KUNIT_ASSERT_NOT_NULL(test, priv);
1318
1319	conn = &priv->connector;
1320	ret = set_connector_edid(test, conn,
1321				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1322				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1323	KUNIT_ASSERT_GT(test, ret, 0);
1324
1325	info = &conn->display_info;
1326	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1327	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1328
1329	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1330	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1331
1332	preferred = find_preferred_mode(conn);
1333	KUNIT_ASSERT_NOT_NULL(test, preferred);
1334
1335	/*
1336	 * We're making sure that YUV422 would be the preferred option
1337	 * here: we're always favouring higher bpc, we can't have RGB
1338	 * because the TMDS character rate exceeds the maximum supported
1339	 * by the display, and YUV422 works for that display.
1340	 *
1341	 * But since the driver only supports RGB, we should fallback to
1342	 * a lower bpc with RGB.
1343	 */
1344	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1345	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1346
1347	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1348	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1349
1350	drm = &priv->drm;
1351	crtc = priv->crtc;
1352	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1353	KUNIT_EXPECT_EQ(test, ret, 0);
1354
1355	conn_state = conn->state;
1356	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1357
1358	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
1359	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1360}
1361
1362/*
1363 * Test that if a screen supports only RGB but the driver also supports
1364 * YUV formats, we only end up with an RGB format.
1365 */
1366static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test)
1367{
1368	struct drm_atomic_helper_connector_hdmi_priv *priv;
1369	struct drm_modeset_acquire_ctx *ctx;
1370	struct drm_connector_state *conn_state;
1371	struct drm_display_info *info;
1372	struct drm_display_mode *preferred;
1373	unsigned long long rate;
1374	struct drm_connector *conn;
1375	struct drm_device *drm;
1376	struct drm_crtc *crtc;
1377	int ret;
1378
1379	priv = drm_atomic_helper_connector_hdmi_init(test,
1380						     BIT(HDMI_COLORSPACE_RGB) |
1381						     BIT(HDMI_COLORSPACE_YUV422) |
1382						     BIT(HDMI_COLORSPACE_YUV444),
1383						     12);
1384	KUNIT_ASSERT_NOT_NULL(test, priv);
1385
1386	conn = &priv->connector;
1387	ret = set_connector_edid(test, conn,
1388				 test_edid_hdmi_1080p_rgb_max_200mhz,
1389				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
1390	KUNIT_ASSERT_GT(test, ret, 0);
1391
1392	info = &conn->display_info;
1393	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1394	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1395
1396	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1397	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1398
1399	preferred = find_preferred_mode(conn);
1400	KUNIT_ASSERT_NOT_NULL(test, preferred);
1401
1402	/*
1403	 * We're making sure that YUV422 would be the preferred option
1404	 * here: we're always favouring higher bpc, we can't have RGB
1405	 * because the TMDS character rate exceeds the maximum supported
1406	 * by the display, and YUV422 works for that display.
1407	 *
1408	 * But since the display only supports RGB, we should fallback to
1409	 * a lower bpc with RGB.
1410	 */
1411	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1412	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1413
1414	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1415	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1416
1417	drm = &priv->drm;
1418	crtc = priv->crtc;
1419	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1420	KUNIT_EXPECT_EQ(test, ret, 0);
1421
1422	conn_state = conn->state;
1423	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1424
1425	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
1426	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1427}
1428
1429/*
1430 * Test that if a display supports higher bpc but the driver only
1431 * supports 8 bpc, we only end up with 8 bpc even if we could have had a
1432 * higher bpc.
1433 */
1434static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test)
1435{
1436	struct drm_atomic_helper_connector_hdmi_priv *priv;
1437	struct drm_modeset_acquire_ctx *ctx;
1438	struct drm_connector_state *conn_state;
1439	struct drm_display_info *info;
1440	struct drm_display_mode *preferred;
1441	unsigned long long rate;
1442	struct drm_connector *conn;
1443	struct drm_device *drm;
1444	struct drm_crtc *crtc;
1445	int ret;
1446
1447	priv = drm_atomic_helper_connector_hdmi_init(test,
1448						     BIT(HDMI_COLORSPACE_RGB),
1449						     8);
1450	KUNIT_ASSERT_NOT_NULL(test, priv);
1451
1452	conn = &priv->connector;
1453	ret = set_connector_edid(test, conn,
1454				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
1455				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
1456	KUNIT_ASSERT_GT(test, ret, 0);
1457
1458	info = &conn->display_info;
1459	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1460	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1461
1462	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1463	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1464
1465	preferred = find_preferred_mode(conn);
1466	KUNIT_ASSERT_NOT_NULL(test, preferred);
1467
1468	/*
1469	 * We're making sure that we have headroom on the TMDS character
1470	 * clock to actually use 12bpc.
1471	 */
1472	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1473	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1474
1475	drm = &priv->drm;
1476	crtc = priv->crtc;
1477	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1478	KUNIT_EXPECT_EQ(test, ret, 0);
1479
1480	conn_state = conn->state;
1481	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1482
1483	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1484	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1485}
1486
1487/*
1488 * Test that if a driver supports higher bpc but the display only
1489 * supports 8 bpc, we only end up with 8 bpc even if we could have had a
1490 * higher bpc.
1491 */
1492static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test)
1493{
1494	struct drm_atomic_helper_connector_hdmi_priv *priv;
1495	struct drm_modeset_acquire_ctx *ctx;
1496	struct drm_connector_state *conn_state;
1497	struct drm_display_info *info;
1498	struct drm_display_mode *preferred;
1499	unsigned long long rate;
1500	struct drm_connector *conn;
1501	struct drm_device *drm;
1502	struct drm_crtc *crtc;
1503	int ret;
1504
1505	priv = drm_atomic_helper_connector_hdmi_init(test,
1506						     BIT(HDMI_COLORSPACE_RGB) |
1507						     BIT(HDMI_COLORSPACE_YUV422) |
1508						     BIT(HDMI_COLORSPACE_YUV444),
1509						     12);
1510	KUNIT_ASSERT_NOT_NULL(test, priv);
1511
1512	conn = &priv->connector;
1513	ret = set_connector_edid(test, conn,
1514				 test_edid_hdmi_1080p_rgb_max_340mhz,
1515				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz));
1516	KUNIT_ASSERT_GT(test, ret, 0);
1517
1518	info = &conn->display_info;
1519	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1520	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1521
1522	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1523	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1524
1525	preferred = find_preferred_mode(conn);
1526	KUNIT_ASSERT_NOT_NULL(test, preferred);
1527
1528	/*
1529	 * We're making sure that we have headroom on the TMDS character
1530	 * clock to actually use 12bpc.
1531	 */
1532	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1533	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1534
1535	drm = &priv->drm;
1536	crtc = priv->crtc;
1537	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1538	KUNIT_EXPECT_EQ(test, ret, 0);
1539
1540	conn_state = conn->state;
1541	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1542
1543	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1544	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1545}
1546
1547static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
1548	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
1549	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
1550	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode),
1551	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),
1552	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),
1553	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
1554	/*
1555	 * TODO: When we'll have YUV output support, we need to check
1556	 * that the limited range is always set to limited no matter
1557	 * what the value of Broadcast RGB is.
1558	 */
1559	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
1560	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
1561	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
1562	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback),
1563	KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback),
1564	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
1565	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
1566	KUNIT_CASE(drm_test_check_output_bpc_dvi),
1567	KUNIT_CASE(drm_test_check_output_bpc_format_vic_1),
1568	KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only),
1569	KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only),
1570	KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only),
1571	KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only),
1572	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
1573	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
1574	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
1575	/*
1576	 * TODO: We should have tests to check that a change in the
1577	 * format triggers a CRTC mode change just like we do for the
1578	 * RGB Quantization and BPC.
1579	 *
1580	 * However, we don't have any way to control which format gets
1581	 * picked up aside from changing the BPC or mode which would
1582	 * already trigger a mode change.
1583	 */
1584	{ }
1585};
1586
1587static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
1588	.name		= "drm_atomic_helper_connector_hdmi_check",
1589	.test_cases	= drm_atomic_helper_connector_hdmi_check_tests,
1590};
1591
1592/*
1593 * Test that the value of the Broadcast RGB property out of reset is set
1594 * to auto.
1595 */
1596static void drm_test_check_broadcast_rgb_value(struct kunit *test)
1597{
1598	struct drm_atomic_helper_connector_hdmi_priv *priv;
1599	struct drm_connector_state *conn_state;
1600	struct drm_connector *conn;
1601
1602	priv = drm_atomic_helper_connector_hdmi_init(test,
1603						     BIT(HDMI_COLORSPACE_RGB),
1604						     8);
1605	KUNIT_ASSERT_NOT_NULL(test, priv);
1606
1607	conn = &priv->connector;
1608	conn_state = conn->state;
1609	KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO);
1610}
1611
1612/*
1613 * Test that if the connector was initialised with a maximum bpc of 8,
1614 * the value of the max_bpc and max_requested_bpc properties out of
1615 * reset are also set to 8, and output_bpc is set to 0 and will be
1616 * filled at atomic_check time.
1617 */
1618static void drm_test_check_bpc_8_value(struct kunit *test)
1619{
1620	struct drm_atomic_helper_connector_hdmi_priv *priv;
1621	struct drm_connector_state *conn_state;
1622	struct drm_connector *conn;
1623
1624	priv = drm_atomic_helper_connector_hdmi_init(test,
1625						     BIT(HDMI_COLORSPACE_RGB),
1626						     8);
1627	KUNIT_ASSERT_NOT_NULL(test, priv);
1628
1629	conn = &priv->connector;
1630	conn_state = conn->state;
1631	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8);
1632	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8);
1633	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1634}
1635
1636/*
1637 * Test that if the connector was initialised with a maximum bpc of 10,
1638 * the value of the max_bpc and max_requested_bpc properties out of
1639 * reset are also set to 10, and output_bpc is set to 0 and will be
1640 * filled at atomic_check time.
1641 */
1642static void drm_test_check_bpc_10_value(struct kunit *test)
1643{
1644	struct drm_atomic_helper_connector_hdmi_priv *priv;
1645	struct drm_connector_state *conn_state;
1646	struct drm_connector *conn;
1647
1648	priv = drm_atomic_helper_connector_hdmi_init(test,
1649						     BIT(HDMI_COLORSPACE_RGB),
1650						     10);
1651	KUNIT_ASSERT_NOT_NULL(test, priv);
1652
1653	conn = &priv->connector;
1654	conn_state = conn->state;
1655	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10);
1656	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10);
1657	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1658}
1659
1660/*
1661 * Test that if the connector was initialised with a maximum bpc of 12,
1662 * the value of the max_bpc and max_requested_bpc properties out of
1663 * reset are also set to 12, and output_bpc is set to 0 and will be
1664 * filled at atomic_check time.
1665 */
1666static void drm_test_check_bpc_12_value(struct kunit *test)
1667{
1668	struct drm_atomic_helper_connector_hdmi_priv *priv;
1669	struct drm_connector_state *conn_state;
1670	struct drm_connector *conn;
1671
1672	priv = drm_atomic_helper_connector_hdmi_init(test,
1673						     BIT(HDMI_COLORSPACE_RGB),
1674						     12);
1675	KUNIT_ASSERT_NOT_NULL(test, priv);
1676
1677	conn = &priv->connector;
1678	conn_state = conn->state;
1679	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12);
1680	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12);
1681	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1682}
1683
1684/*
1685 * Test that the value of the output format property out of reset is set
1686 * to RGB, even if the driver supports more than that.
1687 */
1688static void drm_test_check_format_value(struct kunit *test)
1689{
1690	struct drm_atomic_helper_connector_hdmi_priv *priv;
1691	struct drm_connector_state *conn_state;
1692	struct drm_connector *conn;
1693
1694	priv = drm_atomic_helper_connector_hdmi_init(test,
1695						     BIT(HDMI_COLORSPACE_RGB) |
1696						     BIT(HDMI_COLORSPACE_YUV422) |
1697						     BIT(HDMI_COLORSPACE_YUV444),
1698						     8);
1699	KUNIT_ASSERT_NOT_NULL(test, priv);
1700
1701	conn = &priv->connector;
1702	conn_state = conn->state;
1703	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0);
1704}
1705
1706/*
1707 * Test that the value of the output format property out of reset is set
1708 * to 0, and will be computed at atomic_check time.
1709 */
1710static void drm_test_check_tmds_char_value(struct kunit *test)
1711{
1712	struct drm_atomic_helper_connector_hdmi_priv *priv;
1713	struct drm_connector_state *conn_state;
1714	struct drm_connector *conn;
1715
1716	priv = drm_atomic_helper_connector_hdmi_init(test,
1717						     BIT(HDMI_COLORSPACE_RGB) |
1718						     BIT(HDMI_COLORSPACE_YUV422) |
1719						     BIT(HDMI_COLORSPACE_YUV444),
1720						     12);
1721	KUNIT_ASSERT_NOT_NULL(test, priv);
1722
1723	conn = &priv->connector;
1724	conn_state = conn->state;
1725	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, 0);
1726}
1727
1728static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
1729	KUNIT_CASE(drm_test_check_broadcast_rgb_value),
1730	KUNIT_CASE(drm_test_check_bpc_8_value),
1731	KUNIT_CASE(drm_test_check_bpc_10_value),
1732	KUNIT_CASE(drm_test_check_bpc_12_value),
1733	KUNIT_CASE(drm_test_check_format_value),
1734	KUNIT_CASE(drm_test_check_tmds_char_value),
1735	{ }
1736};
1737
1738static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = {
1739	.name		= "drm_atomic_helper_connector_hdmi_reset",
1740	.test_cases	= drm_atomic_helper_connector_hdmi_reset_tests,
1741};
1742
1743kunit_test_suites(
1744	&drm_atomic_helper_connector_hdmi_check_test_suite,
1745	&drm_atomic_helper_connector_hdmi_reset_test_suite,
1746);
1747
1748MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
1749MODULE_DESCRIPTION("Kunit test for drm_hdmi_state_helper functions");
1750MODULE_LICENSE("GPL");