xref: /linux/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c (revision 7fca7acd60a228b62b4e9efa5f184738041e9564)
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /*
3  * KUnit tests for amdgpu_dm_connector.c
4  *
5  * Copyright 2026 Advanced Micro Devices, Inc.
6  */
7 
8 #include <kunit/test.h>
9 #include <drm/drm_atomic.h>
10 #include <drm/drm_atomic_state_helper.h>
11 #include <drm/drm_connector.h>
12 #include <drm/drm_crtc.h>
13 #include <drm/drm_edid.h>
14 #include <drm/drm_encoder.h>
15 #include <drm/drm_kunit_helpers.h>
16 #include <drm/drm_managed.h>
17 #include <drm/drm_mode_object.h>
18 #include <drm/drm_modes.h>
19 #include <drm/drm_property.h>
20 #include <linux/hdmi.h>
21 #include <linux/i2c.h>
22 
23 #include "dc.h"
24 #include "amdgpu.h"
25 #include "amdgpu_mode.h"
26 #include "amdgpu_display.h"
27 #include "amdgpu_dm.h"
28 #include "amdgpu_dm_connector.h"
29 #include "amdgpu_dm_backlight.h"
30 #include "include/grph_object_id.h"
31 #include "amdgpu_dm_kunit_test_helpers.h"
32 
33 /* Tests for get_subconnector_type() */
34 
35 /**
36  * dm_test_subconnector_type_none - Test Subconnector type none
37  * @test: The KUnit test context
38  */
39 static void dm_test_subconnector_type_none(struct kunit *test)
40 {
41 	struct dc_link *link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
42 
43 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link);
44 
45 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
46 	KUNIT_EXPECT_EQ(test, (int)get_subconnector_type(link), (int)DRM_MODE_SUBCONNECTOR_Native);
47 }
48 
49 /**
50  * dm_test_subconnector_type_vga - Test Subconnector type vga
51  * @test: The KUnit test context
52  */
53 static void dm_test_subconnector_type_vga(struct kunit *test)
54 {
55 	struct dc_link *link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
56 
57 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link);
58 
59 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
60 	KUNIT_EXPECT_EQ(test, (int)get_subconnector_type(link), (int)DRM_MODE_SUBCONNECTOR_VGA);
61 }
62 
63 /**
64  * dm_test_subconnector_type_dvi_converter - Test Subconnector type dvi converter
65  * @test: The KUnit test context
66  */
67 static void dm_test_subconnector_type_dvi_converter(struct kunit *test)
68 {
69 	struct dc_link *link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
70 
71 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link);
72 
73 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
74 	KUNIT_EXPECT_EQ(test, (int)get_subconnector_type(link), (int)DRM_MODE_SUBCONNECTOR_DVID);
75 }
76 
77 /**
78  * dm_test_subconnector_type_dvi_dongle - Test Subconnector type dvi dongle
79  * @test: The KUnit test context
80  */
81 static void dm_test_subconnector_type_dvi_dongle(struct kunit *test)
82 {
83 	struct dc_link *link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
84 
85 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link);
86 
87 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_DONGLE;
88 	KUNIT_EXPECT_EQ(test, (int)get_subconnector_type(link), (int)DRM_MODE_SUBCONNECTOR_DVID);
89 }
90 
91 /**
92  * dm_test_subconnector_type_hdmi_converter - Test Subconnector type hdmi converter
93  * @test: The KUnit test context
94  */
95 static void dm_test_subconnector_type_hdmi_converter(struct kunit *test)
96 {
97 	struct dc_link *link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
98 
99 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link);
100 
101 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_HDMI_CONVERTER;
102 	KUNIT_EXPECT_EQ(test, (int)get_subconnector_type(link), (int)DRM_MODE_SUBCONNECTOR_HDMIA);
103 }
104 
105 /**
106  * dm_test_subconnector_type_hdmi_dongle - Test Subconnector type hdmi dongle
107  * @test: The KUnit test context
108  */
109 static void dm_test_subconnector_type_hdmi_dongle(struct kunit *test)
110 {
111 	struct dc_link *link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
112 
113 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link);
114 
115 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_HDMI_DONGLE;
116 	KUNIT_EXPECT_EQ(test, (int)get_subconnector_type(link), (int)DRM_MODE_SUBCONNECTOR_HDMIA);
117 }
118 
119 /**
120  * dm_test_subconnector_type_mismatched - Test Subconnector type mismatched
121  * @test: The KUnit test context
122  */
123 static void dm_test_subconnector_type_mismatched(struct kunit *test)
124 {
125 	struct dc_link *link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
126 
127 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link);
128 
129 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
130 	KUNIT_EXPECT_EQ(test, (int)get_subconnector_type(link), (int)DRM_MODE_SUBCONNECTOR_Unknown);
131 }
132 
133 /**
134  * dm_test_subconnector_type_default_unknown - Test Subconnector type default unknown
135  * @test: The KUnit test context
136  */
137 static void dm_test_subconnector_type_default_unknown(struct kunit *test)
138 {
139 	struct dc_link *link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
140 
141 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link);
142 
143 	link->dpcd_caps.dongle_type = (typeof(link->dpcd_caps.dongle_type))0x7f;
144 	KUNIT_EXPECT_EQ(test, (int)get_subconnector_type(link), (int)DRM_MODE_SUBCONNECTOR_Unknown);
145 }
146 
147 /* Tests for get_output_content_type() */
148 
149 /**
150  * dm_test_content_type_no_data - Test Content type no data
151  * @test: The KUnit test context
152  */
153 static void dm_test_content_type_no_data(struct kunit *test)
154 {
155 	struct drm_connector_state state = {};
156 
157 	state.content_type = DRM_MODE_CONTENT_TYPE_NO_DATA;
158 	KUNIT_EXPECT_EQ(test, (int)get_output_content_type(&state), (int)DISPLAY_CONTENT_TYPE_NO_DATA);
159 }
160 
161 /**
162  * dm_test_content_type_graphics - Test Content type graphics
163  * @test: The KUnit test context
164  */
165 static void dm_test_content_type_graphics(struct kunit *test)
166 {
167 	struct drm_connector_state state = {};
168 
169 	state.content_type = DRM_MODE_CONTENT_TYPE_GRAPHICS;
170 	KUNIT_EXPECT_EQ(test, (int)get_output_content_type(&state), (int)DISPLAY_CONTENT_TYPE_GRAPHICS);
171 }
172 
173 /**
174  * dm_test_content_type_photo - Test Content type photo
175  * @test: The KUnit test context
176  */
177 static void dm_test_content_type_photo(struct kunit *test)
178 {
179 	struct drm_connector_state state = {};
180 
181 	state.content_type = DRM_MODE_CONTENT_TYPE_PHOTO;
182 	KUNIT_EXPECT_EQ(test, (int)get_output_content_type(&state), (int)DISPLAY_CONTENT_TYPE_PHOTO);
183 }
184 
185 /**
186  * dm_test_content_type_cinema - Test Content type cinema
187  * @test: The KUnit test context
188  */
189 static void dm_test_content_type_cinema(struct kunit *test)
190 {
191 	struct drm_connector_state state = {};
192 
193 	state.content_type = DRM_MODE_CONTENT_TYPE_CINEMA;
194 	KUNIT_EXPECT_EQ(test, (int)get_output_content_type(&state), (int)DISPLAY_CONTENT_TYPE_CINEMA);
195 }
196 
197 /**
198  * dm_test_content_type_game - Test Content type game
199  * @test: The KUnit test context
200  */
201 static void dm_test_content_type_game(struct kunit *test)
202 {
203 	struct drm_connector_state state = {};
204 
205 	state.content_type = DRM_MODE_CONTENT_TYPE_GAME;
206 	KUNIT_EXPECT_EQ(test, (int)get_output_content_type(&state), (int)DISPLAY_CONTENT_TYPE_GAME);
207 }
208 
209 /**
210  * dm_test_content_type_unknown_defaults_no_data - Test unknown content type defaults to no data
211  * @test: The KUnit test context
212  */
213 static void dm_test_content_type_unknown_defaults_no_data(struct kunit *test)
214 {
215 	struct drm_connector_state state = {};
216 
217 	state.content_type = 0x7f;
218 	KUNIT_EXPECT_EQ(test, (int)get_output_content_type(&state),
219 			(int)DISPLAY_CONTENT_TYPE_NO_DATA);
220 }
221 
222 /* Tests for adjust_colour_depth_from_display_info() */
223 
224 /**
225  * dm_test_adjust_colour_depth_fits_at_888 - Test Adjust colour depth fits at 888
226  * @test: The KUnit test context
227  */
228 static void dm_test_adjust_colour_depth_fits_at_888(struct kunit *test)
229 {
230 	struct dc_crtc_timing timing = {};
231 	struct drm_display_info info = {};
232 
233 	/* 1080p @ 148500 KHz = 1485000 in 100Hz units */
234 	timing.pix_clk_100hz = 1485000;
235 	timing.display_color_depth = COLOR_DEPTH_888;
236 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
237 	info.max_tmds_clock = 150000; /* 150 MHz */
238 
239 	KUNIT_EXPECT_TRUE(test, adjust_colour_depth_from_display_info(&timing, &info));
240 	KUNIT_EXPECT_EQ(test, (int)timing.display_color_depth, (int)COLOR_DEPTH_888);
241 }
242 
243 /**
244  * dm_test_adjust_colour_depth_reduces_to_888 - Test Adjust colour depth reduces to 888
245  * @test: The KUnit test context
246  */
247 static void dm_test_adjust_colour_depth_reduces_to_888(struct kunit *test)
248 {
249 	struct dc_crtc_timing timing = {};
250 	struct drm_display_info info = {};
251 
252 	/* Request 10bpc but TMDS limit only allows 8bpc */
253 	timing.pix_clk_100hz = 1485000;
254 	timing.display_color_depth = COLOR_DEPTH_101010;
255 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
256 	/* 10bpc would need 148500*30/24 = 185625 KHz, exceeds limit */
257 	info.max_tmds_clock = 160000;
258 
259 	KUNIT_EXPECT_TRUE(test, adjust_colour_depth_from_display_info(&timing, &info));
260 	KUNIT_EXPECT_EQ(test, (int)timing.display_color_depth, (int)COLOR_DEPTH_888);
261 }
262 
263 /**
264  * dm_test_adjust_colour_depth_10bpc_passes - Test Adjust colour depth 10bpc passes
265  * @test: The KUnit test context
266  */
267 static void dm_test_adjust_colour_depth_10bpc_passes(struct kunit *test)
268 {
269 	struct dc_crtc_timing timing = {};
270 	struct drm_display_info info = {};
271 
272 	timing.pix_clk_100hz = 1485000;
273 	timing.display_color_depth = COLOR_DEPTH_101010;
274 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
275 	/* 10bpc needs 185625 KHz, allow it */
276 	info.max_tmds_clock = 200000;
277 
278 	KUNIT_EXPECT_TRUE(test, adjust_colour_depth_from_display_info(&timing, &info));
279 	KUNIT_EXPECT_EQ(test, (int)timing.display_color_depth, (int)COLOR_DEPTH_101010);
280 }
281 
282 /**
283  * dm_test_adjust_colour_depth_420_halves_clk - Test Adjust colour depth 420 halves clk
284  * @test: The KUnit test context
285  */
286 static void dm_test_adjust_colour_depth_420_halves_clk(struct kunit *test)
287 {
288 	struct dc_crtc_timing timing = {};
289 	struct drm_display_info info = {};
290 
291 	/* 4K @ 594000 KHz = 5940000 in 100Hz units */
292 	timing.pix_clk_100hz = 5940000;
293 	timing.display_color_depth = COLOR_DEPTH_101010;
294 	timing.pixel_encoding = PIXEL_ENCODING_YCBCR420;
295 	/* With 420: effective = 594000/2 = 297000, 10bpc = 297000*30/24 = 371250 */
296 	info.max_tmds_clock = 400000;
297 
298 	KUNIT_EXPECT_TRUE(test, adjust_colour_depth_from_display_info(&timing, &info));
299 	KUNIT_EXPECT_EQ(test, (int)timing.display_color_depth, (int)COLOR_DEPTH_101010);
300 }
301 
302 /**
303  * dm_test_adjust_colour_depth_420_reduces - Test Adjust colour depth 420 reduces
304  * @test: The KUnit test context
305  */
306 static void dm_test_adjust_colour_depth_420_reduces(struct kunit *test)
307 {
308 	struct dc_crtc_timing timing = {};
309 	struct drm_display_info info = {};
310 
311 	/* 4K @ 594000 KHz = 5940000 in 100Hz units */
312 	timing.pix_clk_100hz = 5940000;
313 	timing.display_color_depth = COLOR_DEPTH_121212;
314 	timing.pixel_encoding = PIXEL_ENCODING_YCBCR420;
315 	/*
316 	 * With 420: effective = 594000/2 = 297000.
317 	 * 12bpc = 297000*36/24 = 445500 (exceeds limit),
318 	 * 10bpc = 297000*30/24 = 371250 (fits).
319 	 */
320 	info.max_tmds_clock = 400000;
321 
322 	KUNIT_EXPECT_TRUE(test, adjust_colour_depth_from_display_info(&timing, &info));
323 	KUNIT_EXPECT_EQ(test, (int)timing.display_color_depth, (int)COLOR_DEPTH_101010);
324 }
325 
326 /**
327  * dm_test_adjust_colour_depth_reduces_12bpc_to_10bpc - Test Adjust colour
328  * depth reduces 12bpc to 10bpc
329  * @test: The KUnit test context
330  */
331 static void dm_test_adjust_colour_depth_reduces_12bpc_to_10bpc(struct kunit *test)
332 {
333 	struct dc_crtc_timing timing = {};
334 	struct drm_display_info info = {};
335 
336 	timing.pix_clk_100hz = 1485000;
337 	timing.display_color_depth = COLOR_DEPTH_121212;
338 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
339 	info.max_tmds_clock = 190000;
340 
341 	KUNIT_EXPECT_TRUE(test, adjust_colour_depth_from_display_info(&timing, &info));
342 	KUNIT_EXPECT_EQ(test, (int)timing.display_color_depth, (int)COLOR_DEPTH_101010);
343 }
344 
345 /**
346  * dm_test_adjust_colour_depth_16bpc_no_fallback - Test Adjust colour depth
347  * 16bpc cannot fall back
348  * @test: The KUnit test context
349  */
350 static void dm_test_adjust_colour_depth_16bpc_no_fallback(struct kunit *test)
351 {
352 	struct dc_crtc_timing timing = {};
353 	struct drm_display_info info = {};
354 
355 	/* 16bpc that exceeds limit cannot reduce because the next enum
356 	 * value (COLOR_DEPTH_141414) is not a valid HDMI depth.
357 	 */
358 	timing.pix_clk_100hz = 1485000;
359 	timing.display_color_depth = COLOR_DEPTH_161616;
360 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
361 	info.max_tmds_clock = 230000;
362 
363 	KUNIT_EXPECT_FALSE(test, adjust_colour_depth_from_display_info(&timing, &info));
364 }
365 
366 /**
367  * dm_test_adjust_colour_depth_none_fits - Test Adjust colour depth none fits
368  * @test: The KUnit test context
369  */
370 static void dm_test_adjust_colour_depth_none_fits(struct kunit *test)
371 {
372 	struct dc_crtc_timing timing = {};
373 	struct drm_display_info info = {};
374 
375 	/* Even 8bpc doesn't fit */
376 	timing.pix_clk_100hz = 1485000;
377 	timing.display_color_depth = COLOR_DEPTH_888;
378 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
379 	info.max_tmds_clock = 100000; /* Too low */
380 
381 	KUNIT_EXPECT_FALSE(test, adjust_colour_depth_from_display_info(&timing, &info));
382 }
383 
384 /**
385  * dm_test_adjust_colour_depth_invalid_depth - Test Adjust colour depth invalid depth
386  * @test: The KUnit test context
387  */
388 static void dm_test_adjust_colour_depth_invalid_depth(struct kunit *test)
389 {
390 	struct dc_crtc_timing timing = {};
391 	struct drm_display_info info = {};
392 
393 	timing.pix_clk_100hz = 1485000;
394 	timing.display_color_depth = COLOR_DEPTH_141414;
395 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
396 	info.max_tmds_clock = 400000;
397 
398 	KUNIT_EXPECT_FALSE(test, adjust_colour_depth_from_display_info(&timing, &info));
399 	KUNIT_EXPECT_EQ(test, (int)timing.display_color_depth, (int)COLOR_DEPTH_141414);
400 }
401 
402 /* Tests for amdgpu_dm_get_output_color_space() */
403 
404 /**
405  * dm_test_output_color_space_default_rgb_full - Test Output color space default rgb full
406  * @test: The KUnit test context
407  */
408 static void dm_test_output_color_space_default_rgb_full(struct kunit *test)
409 {
410 	struct dc_crtc_timing timing = {};
411 	struct drm_connector_state state = {};
412 
413 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
414 	state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
415 	state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
416 
417 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
418 			(int)COLOR_SPACE_SRGB);
419 }
420 
421 /**
422  * dm_test_output_color_space_default_rgb_limited - Test Output color space default rgb limited
423  * @test: The KUnit test context
424  */
425 static void dm_test_output_color_space_default_rgb_limited(struct kunit *test)
426 {
427 	struct dc_crtc_timing timing = {};
428 	struct drm_connector_state state = {};
429 
430 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
431 	state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
432 	state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
433 
434 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
435 			(int)COLOR_SPACE_SRGB_LIMITED);
436 }
437 
438 /**
439  * dm_test_output_color_space_default_ycbcr709 - Test Output color space default ycbcr709
440  * @test: The KUnit test context
441  */
442 static void dm_test_output_color_space_default_ycbcr709(struct kunit *test)
443 {
444 	struct dc_crtc_timing timing = {};
445 	struct drm_connector_state state = {};
446 
447 	timing.pixel_encoding = PIXEL_ENCODING_YCBCR444;
448 	timing.pix_clk_100hz = 300000;
449 	timing.flags.Y_ONLY = 0;
450 	state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
451 
452 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
453 			(int)COLOR_SPACE_YCBCR709);
454 }
455 
456 /**
457  * dm_test_output_color_space_default_ycbcr601_limited - Test Output color space
458  * default ycbcr601 limited
459  * @test: The KUnit test context
460  */
461 static void dm_test_output_color_space_default_ycbcr601_limited(struct kunit *test)
462 {
463 	struct dc_crtc_timing timing = {};
464 	struct drm_connector_state state = {};
465 
466 	timing.pixel_encoding = PIXEL_ENCODING_YCBCR444;
467 	timing.pix_clk_100hz = 270300;
468 	timing.flags.Y_ONLY = 1;
469 	state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
470 
471 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
472 			(int)COLOR_SPACE_YCBCR601_LIMITED);
473 }
474 
475 /**
476  * dm_test_output_color_space_bt601_y_only - Test Output color space bt601 y only
477  * @test: The KUnit test context
478  */
479 static void dm_test_output_color_space_bt601_y_only(struct kunit *test)
480 {
481 	struct dc_crtc_timing timing = {};
482 	struct drm_connector_state state = {};
483 
484 	timing.flags.Y_ONLY = 1;
485 	state.colorspace = DRM_MODE_COLORIMETRY_BT601_YCC;
486 
487 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
488 			(int)COLOR_SPACE_YCBCR601_LIMITED);
489 }
490 
491 /**
492  * dm_test_output_color_space_bt601 - Test Output color space bt601
493  * @test: The KUnit test context
494  */
495 static void dm_test_output_color_space_bt601(struct kunit *test)
496 {
497 	struct dc_crtc_timing timing = {};
498 	struct drm_connector_state state = {};
499 
500 	timing.flags.Y_ONLY = 0;
501 	state.colorspace = DRM_MODE_COLORIMETRY_BT601_YCC;
502 
503 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
504 			(int)COLOR_SPACE_YCBCR601);
505 }
506 
507 /**
508  * dm_test_output_color_space_bt709 - Test Output color space bt709
509  * @test: The KUnit test context
510  */
511 static void dm_test_output_color_space_bt709(struct kunit *test)
512 {
513 	struct dc_crtc_timing timing = {};
514 	struct drm_connector_state state = {};
515 
516 	timing.flags.Y_ONLY = 0;
517 	state.colorspace = DRM_MODE_COLORIMETRY_BT709_YCC;
518 
519 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
520 			(int)COLOR_SPACE_YCBCR709);
521 }
522 
523 /**
524  * dm_test_output_color_space_bt709_y_only - Test Output color space bt709 y only
525  * @test: The KUnit test context
526  */
527 static void dm_test_output_color_space_bt709_y_only(struct kunit *test)
528 {
529 	struct dc_crtc_timing timing = {};
530 	struct drm_connector_state state = {};
531 
532 	timing.flags.Y_ONLY = 1;
533 	state.colorspace = DRM_MODE_COLORIMETRY_BT709_YCC;
534 
535 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
536 			(int)COLOR_SPACE_YCBCR709_LIMITED);
537 }
538 
539 /**
540  * dm_test_output_color_space_oprgb - Test Output color space oprgb
541  * @test: The KUnit test context
542  */
543 static void dm_test_output_color_space_oprgb(struct kunit *test)
544 {
545 	struct dc_crtc_timing timing = {};
546 	struct drm_connector_state state = {};
547 
548 	state.colorspace = DRM_MODE_COLORIMETRY_OPRGB;
549 
550 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
551 			(int)COLOR_SPACE_ADOBERGB);
552 }
553 
554 /**
555  * dm_test_output_color_space_bt2020_rgb - Test Output color space bt2020 rgb
556  * @test: The KUnit test context
557  */
558 static void dm_test_output_color_space_bt2020_rgb(struct kunit *test)
559 {
560 	struct dc_crtc_timing timing = {};
561 	struct drm_connector_state state = {};
562 
563 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
564 	state.colorspace = DRM_MODE_COLORIMETRY_BT2020_RGB;
565 
566 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
567 			(int)COLOR_SPACE_2020_RGB_FULLRANGE);
568 }
569 
570 /**
571  * dm_test_output_color_space_bt2020_rgb_limited - Test limited BT.2020 RGB
572  * @test: The KUnit test context
573  */
574 static void dm_test_output_color_space_bt2020_rgb_limited(struct kunit *test)
575 {
576 	struct dc_crtc_timing timing = {};
577 	struct drm_connector_state state = {};
578 
579 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
580 	state.colorspace = DRM_MODE_COLORIMETRY_BT2020_RGB;
581 	state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
582 
583 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
584 			(int)COLOR_SPACE_2020_RGB_LIMITEDRANGE);
585 }
586 
587 /**
588  * dm_test_output_color_space_bt2020_ycc - Test Output color space bt2020 ycc
589  * @test: The KUnit test context
590  */
591 static void dm_test_output_color_space_bt2020_ycc(struct kunit *test)
592 {
593 	struct dc_crtc_timing timing = {};
594 	struct drm_connector_state state = {};
595 
596 	timing.pixel_encoding = PIXEL_ENCODING_YCBCR422;
597 	state.colorspace = DRM_MODE_COLORIMETRY_BT2020_YCC;
598 
599 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
600 			(int)COLOR_SPACE_2020_YCBCR_LIMITED);
601 }
602 
603 /**
604  * dm_test_output_color_space_default_ycbcr709_y_only - Test Output color space
605  * default ycbcr709 limited via Y_ONLY at high pixel clock
606  * @test: The KUnit test context
607  */
608 static void dm_test_output_color_space_default_ycbcr709_y_only(struct kunit *test)
609 {
610 	struct dc_crtc_timing timing = {};
611 	struct drm_connector_state state = {};
612 
613 	timing.pixel_encoding = PIXEL_ENCODING_YCBCR444;
614 	timing.pix_clk_100hz = 300000;
615 	timing.flags.Y_ONLY = 1;
616 	state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
617 
618 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
619 			(int)COLOR_SPACE_YCBCR709_LIMITED);
620 }
621 
622 /**
623  * dm_test_output_color_space_default_ycbcr601 - Test Output color space default
624  * ycbcr601 full range at low pixel clock
625  * @test: The KUnit test context
626  */
627 static void dm_test_output_color_space_default_ycbcr601(struct kunit *test)
628 {
629 	struct dc_crtc_timing timing = {};
630 	struct drm_connector_state state = {};
631 
632 	timing.pixel_encoding = PIXEL_ENCODING_YCBCR444;
633 	timing.pix_clk_100hz = 270300;
634 	timing.flags.Y_ONLY = 0;
635 	state.colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
636 
637 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
638 			(int)COLOR_SPACE_YCBCR601);
639 }
640 
641 /**
642  * dm_test_output_color_space_bt2020_ycc_rgb_encoding - Test Output color space
643  * bt2020 ycc with rgb pixel encoding falls back to full range rgb
644  * @test: The KUnit test context
645  */
646 static void dm_test_output_color_space_bt2020_ycc_rgb_encoding(struct kunit *test)
647 {
648 	struct dc_crtc_timing timing = {};
649 	struct drm_connector_state state = {};
650 
651 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
652 	state.colorspace = DRM_MODE_COLORIMETRY_BT2020_YCC;
653 
654 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
655 			(int)COLOR_SPACE_2020_RGB_FULLRANGE);
656 }
657 
658 /**
659  * dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited - Test limited
660  * BT.2020 RGB output selected through the BT.2020 YCC connector colorspace
661  * @test: The KUnit test context
662  */
663 static void dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited(struct kunit *test)
664 {
665 	struct dc_crtc_timing timing = {};
666 	struct drm_connector_state state = {};
667 
668 	timing.pixel_encoding = PIXEL_ENCODING_RGB;
669 	state.colorspace = DRM_MODE_COLORIMETRY_BT2020_YCC;
670 	state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
671 
672 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
673 			(int)COLOR_SPACE_2020_RGB_LIMITEDRANGE);
674 }
675 
676 /**
677  * dm_test_output_color_space_bt2020_rgb_ycc_encoding - Test Output color space
678  * bt2020 rgb with non-rgb pixel encoding falls back to limited ycbcr
679  * @test: The KUnit test context
680  */
681 static void dm_test_output_color_space_bt2020_rgb_ycc_encoding(struct kunit *test)
682 {
683 	struct dc_crtc_timing timing = {};
684 	struct drm_connector_state state = {};
685 
686 	timing.pixel_encoding = PIXEL_ENCODING_YCBCR444;
687 	state.colorspace = DRM_MODE_COLORIMETRY_BT2020_RGB;
688 
689 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
690 			(int)COLOR_SPACE_2020_YCBCR_LIMITED);
691 }
692 
693 /* Tests for amdgpu_dm_convert_dc_color_depth_into_bpc() */
694 
695 /**
696  * dm_test_convert_color_depth_bpc_mappings - Test Convert color depth bpc mappings
697  * @test: The KUnit test context
698  */
699 static void dm_test_convert_color_depth_bpc_mappings(struct kunit *test)
700 {
701 	KUNIT_EXPECT_EQ(test, amdgpu_dm_convert_dc_color_depth_into_bpc(COLOR_DEPTH_666), 6);
702 	KUNIT_EXPECT_EQ(test, amdgpu_dm_convert_dc_color_depth_into_bpc(COLOR_DEPTH_888), 8);
703 	KUNIT_EXPECT_EQ(test, amdgpu_dm_convert_dc_color_depth_into_bpc(COLOR_DEPTH_101010), 10);
704 	KUNIT_EXPECT_EQ(test, amdgpu_dm_convert_dc_color_depth_into_bpc(COLOR_DEPTH_121212), 12);
705 	KUNIT_EXPECT_EQ(test, amdgpu_dm_convert_dc_color_depth_into_bpc(COLOR_DEPTH_141414), 14);
706 	KUNIT_EXPECT_EQ(test, amdgpu_dm_convert_dc_color_depth_into_bpc(COLOR_DEPTH_161616), 16);
707 }
708 
709 /**
710  * dm_test_convert_color_depth_bpc_unknown - Test Convert color depth bpc unknown
711  * @test: The KUnit test context
712  */
713 static void dm_test_convert_color_depth_bpc_unknown(struct kunit *test)
714 {
715 	KUNIT_EXPECT_EQ(test, amdgpu_dm_convert_dc_color_depth_into_bpc(COLOR_DEPTH_UNDEFINED), 0);
716 }
717 
718 /* Tests for amdgpu_dm_convert_color_depth_from_display_info() */
719 
720 /**
721  * dm_test_color_depth_from_info_bpc8 - Test Color depth from info bpc8
722  * @test: The KUnit test context
723  */
724 static void dm_test_color_depth_from_info_bpc8(struct kunit *test)
725 {
726 	struct drm_connector *connector;
727 
728 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
729 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
730 
731 	connector->display_info.bpc = 8;
732 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, false, 0),
733 			(int)COLOR_DEPTH_888);
734 }
735 
736 /**
737  * dm_test_color_depth_from_info_bpc10 - Test Color depth from info bpc10
738  * @test: The KUnit test context
739  */
740 static void dm_test_color_depth_from_info_bpc10(struct kunit *test)
741 {
742 	struct drm_connector *connector;
743 
744 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
745 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
746 
747 	connector->display_info.bpc = 10;
748 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, false, 0),
749 			(int)COLOR_DEPTH_101010);
750 }
751 
752 /**
753  * dm_test_color_depth_from_info_zero_bpc_defaults_888 - Test Color depth from
754  * info zero bpc defaults 888
755  * @test: The KUnit test context
756  */
757 static void dm_test_color_depth_from_info_zero_bpc_defaults_888(struct kunit *test)
758 {
759 	struct drm_connector *connector;
760 
761 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
762 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
763 
764 	connector->display_info.bpc = 0;
765 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, false, 0),
766 			(int)COLOR_DEPTH_888);
767 }
768 
769 /**
770  * dm_test_color_depth_from_info_requested_bpc_caps - Test Color depth from info requested bpc caps
771  * @test: The KUnit test context
772  */
773 static void dm_test_color_depth_from_info_requested_bpc_caps(struct kunit *test)
774 {
775 	struct drm_connector *connector;
776 
777 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
778 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
779 
780 	/* Display supports 12bpc but user requests max 10 */
781 	connector->display_info.bpc = 12;
782 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, false, 10),
783 			(int)COLOR_DEPTH_101010);
784 }
785 
786 /**
787  * dm_test_color_depth_from_info_y420_default - Test Color depth from info y420 default
788  * @test: The KUnit test context
789  */
790 static void dm_test_color_depth_from_info_y420_default(struct kunit *test)
791 {
792 	struct drm_connector *connector;
793 
794 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
795 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
796 
797 	/* No Y420 DC modes set → 8bpc */
798 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, true, 0),
799 			(int)COLOR_DEPTH_888);
800 }
801 
802 /**
803  * dm_test_color_depth_from_info_y420_10bpc - Test Color depth from info y420 10bpc
804  * @test: The KUnit test context
805  */
806 static void dm_test_color_depth_from_info_y420_10bpc(struct kunit *test)
807 {
808 	struct drm_connector *connector;
809 
810 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
811 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
812 
813 	connector->display_info.hdmi.y420_dc_modes = DRM_EDID_YCBCR420_DC_30;
814 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, true, 0),
815 			(int)COLOR_DEPTH_101010);
816 }
817 
818 /**
819  * dm_test_color_depth_from_info_y420_12bpc - Test Color depth from info y420 12bpc
820  * @test: The KUnit test context
821  */
822 static void dm_test_color_depth_from_info_y420_12bpc(struct kunit *test)
823 {
824 	struct drm_connector *connector;
825 
826 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
827 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
828 
829 	connector->display_info.hdmi.y420_dc_modes = DRM_EDID_YCBCR420_DC_36;
830 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, true, 0),
831 			(int)COLOR_DEPTH_121212);
832 }
833 
834 /**
835  * dm_test_color_depth_from_info_y420_16bpc - Test Color depth from info y420 16bpc
836  * @test: The KUnit test context
837  */
838 static void dm_test_color_depth_from_info_y420_16bpc(struct kunit *test)
839 {
840 	struct drm_connector *connector;
841 
842 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
843 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
844 
845 	connector->display_info.hdmi.y420_dc_modes = DRM_EDID_YCBCR420_DC_48;
846 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, true, 0),
847 			(int)COLOR_DEPTH_161616);
848 }
849 
850 /**
851  * dm_test_color_depth_from_info_requested_odd_bpc - Test Color depth from info requested odd bpc
852  * @test: The KUnit test context
853  */
854 static void dm_test_color_depth_from_info_requested_odd_bpc(struct kunit *test)
855 {
856 	struct drm_connector *connector;
857 
858 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
859 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
860 
861 	connector->display_info.bpc = 12;
862 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, false, 11),
863 			(int)COLOR_DEPTH_101010);
864 }
865 
866 /**
867  * dm_test_color_depth_from_info_unsupported_bpc - Test Color depth from info unsupported bpc
868  * @test: The KUnit test context
869  */
870 static void dm_test_color_depth_from_info_unsupported_bpc(struct kunit *test)
871 {
872 	struct drm_connector *connector;
873 
874 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
875 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector);
876 
877 	connector->display_info.bpc = 9;
878 	KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_convert_color_depth_from_display_info(connector, false, 0),
879 			(int)COLOR_DEPTH_UNDEFINED);
880 }
881 
882 /* Tests for to_drm_connector_type() */
883 
884 /**
885  * dm_test_to_connector_type_hdmi - Test To connector type hdmi
886  * @test: The KUnit test context
887  */
888 static void dm_test_to_connector_type_hdmi(struct kunit *test)
889 {
890 	KUNIT_EXPECT_EQ(test, to_drm_connector_type(SIGNAL_TYPE_HDMI_TYPE_A, 0),
891 			DRM_MODE_CONNECTOR_HDMIA);
892 }
893 
894 /**
895  * dm_test_to_connector_type_edp - Test To connector type edp
896  * @test: The KUnit test context
897  */
898 static void dm_test_to_connector_type_edp(struct kunit *test)
899 {
900 	KUNIT_EXPECT_EQ(test, to_drm_connector_type(SIGNAL_TYPE_EDP, 0),
901 			DRM_MODE_CONNECTOR_eDP);
902 }
903 
904 /**
905  * dm_test_to_connector_type_lvds - Test To connector type lvds
906  * @test: The KUnit test context
907  */
908 static void dm_test_to_connector_type_lvds(struct kunit *test)
909 {
910 	KUNIT_EXPECT_EQ(test, to_drm_connector_type(SIGNAL_TYPE_LVDS, 0),
911 			DRM_MODE_CONNECTOR_LVDS);
912 }
913 
914 /**
915  * dm_test_to_connector_type_rgb - Test To connector type rgb
916  * @test: The KUnit test context
917  */
918 static void dm_test_to_connector_type_rgb(struct kunit *test)
919 {
920 	KUNIT_EXPECT_EQ(test, to_drm_connector_type(SIGNAL_TYPE_RGB, 0),
921 			DRM_MODE_CONNECTOR_VGA);
922 }
923 
924 /**
925  * dm_test_to_connector_type_dp - Test To connector type dp
926  * @test: The KUnit test context
927  */
928 static void dm_test_to_connector_type_dp(struct kunit *test)
929 {
930 	KUNIT_EXPECT_EQ(test, to_drm_connector_type(SIGNAL_TYPE_DISPLAY_PORT, 0),
931 			DRM_MODE_CONNECTOR_DisplayPort);
932 }
933 
934 /**
935  * dm_test_to_connector_type_dp_mst - Test To connector type dp mst
936  * @test: The KUnit test context
937  */
938 static void dm_test_to_connector_type_dp_mst(struct kunit *test)
939 {
940 	KUNIT_EXPECT_EQ(test, to_drm_connector_type(SIGNAL_TYPE_DISPLAY_PORT_MST, 0),
941 			DRM_MODE_CONNECTOR_DisplayPort);
942 }
943 
944 /**
945  * dm_test_to_connector_type_dvi_dvii - Test To connector type dvi dvii
946  * @test: The KUnit test context
947  */
948 static void dm_test_to_connector_type_dvi_dvii(struct kunit *test)
949 {
950 	int type = to_drm_connector_type(SIGNAL_TYPE_DVI_SINGLE_LINK, CONNECTOR_ID_SINGLE_LINK_DVII);
951 
952 	KUNIT_EXPECT_EQ(test, type, DRM_MODE_CONNECTOR_DVII);
953 }
954 
955 /**
956  * dm_test_to_connector_type_dual_link_dvii - Test To connector type dual link dvii
957  * @test: The KUnit test context
958  */
959 static void dm_test_to_connector_type_dual_link_dvii(struct kunit *test)
960 {
961 	int type = to_drm_connector_type(SIGNAL_TYPE_DVI_DUAL_LINK, CONNECTOR_ID_DUAL_LINK_DVII);
962 
963 	KUNIT_EXPECT_EQ(test, type, DRM_MODE_CONNECTOR_DVII);
964 }
965 
966 /**
967  * dm_test_to_connector_type_dvi_dvid - Test To connector type dvi dvid
968  * @test: The KUnit test context
969  */
970 static void dm_test_to_connector_type_dvi_dvid(struct kunit *test)
971 {
972 	int type = to_drm_connector_type(SIGNAL_TYPE_DVI_SINGLE_LINK, CONNECTOR_ID_SINGLE_LINK_DVID);
973 
974 	KUNIT_EXPECT_EQ(test, type, DRM_MODE_CONNECTOR_DVID);
975 }
976 
977 /**
978  * dm_test_to_connector_type_dual_link_dvid - Test To connector type dual link dvid
979  * @test: The KUnit test context
980  */
981 static void dm_test_to_connector_type_dual_link_dvid(struct kunit *test)
982 {
983 	int type = to_drm_connector_type(SIGNAL_TYPE_DVI_DUAL_LINK, CONNECTOR_ID_DUAL_LINK_DVID);
984 
985 	KUNIT_EXPECT_EQ(test, type, DRM_MODE_CONNECTOR_DVID);
986 }
987 
988 /**
989  * dm_test_to_connector_type_virtual - Test To connector type virtual
990  * @test: The KUnit test context
991  */
992 static void dm_test_to_connector_type_virtual(struct kunit *test)
993 {
994 	KUNIT_EXPECT_EQ(test, to_drm_connector_type(SIGNAL_TYPE_VIRTUAL, 0),
995 			DRM_MODE_CONNECTOR_VIRTUAL);
996 }
997 
998 /**
999  * dm_test_to_connector_type_unknown - Test To connector type unknown
1000  * @test: The KUnit test context
1001  */
1002 static void dm_test_to_connector_type_unknown(struct kunit *test)
1003 {
1004 	KUNIT_EXPECT_EQ(test, to_drm_connector_type(SIGNAL_TYPE_NONE, 0),
1005 			DRM_MODE_CONNECTOR_Unknown);
1006 }
1007 
1008 /* Tests for is_duplicate_mode() */
1009 
1010 /**
1011  * dm_test_is_duplicate_mode_empty_list - Test Is duplicate mode empty list
1012  * @test: The KUnit test context
1013  */
1014 static void dm_test_is_duplicate_mode_empty_list(struct kunit *test)
1015 {
1016 	struct amdgpu_dm_connector *aconnector;
1017 	struct drm_display_mode mode = {};
1018 
1019 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
1020 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, aconnector);
1021 
1022 	INIT_LIST_HEAD(&aconnector->base.probed_modes);
1023 	mode.hdisplay = 1920;
1024 	mode.vdisplay = 1080;
1025 
1026 	KUNIT_EXPECT_FALSE(test, is_duplicate_mode(aconnector, &mode));
1027 }
1028 
1029 /**
1030  * dm_test_is_duplicate_mode_match - Test Is duplicate mode match
1031  * @test: The KUnit test context
1032  */
1033 static void dm_test_is_duplicate_mode_match(struct kunit *test)
1034 {
1035 	struct amdgpu_dm_connector *aconnector;
1036 	struct drm_display_mode existing = {};
1037 	struct drm_display_mode candidate = {};
1038 
1039 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
1040 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, aconnector);
1041 
1042 	INIT_LIST_HEAD(&aconnector->base.probed_modes);
1043 	existing.hdisplay = 1920;
1044 	existing.vdisplay = 1080;
1045 	existing.clock = 148500;
1046 	list_add_tail(&existing.head, &aconnector->base.probed_modes);
1047 
1048 	candidate.hdisplay = 1920;
1049 	candidate.vdisplay = 1080;
1050 	candidate.clock = 148500;
1051 
1052 	KUNIT_EXPECT_TRUE(test, is_duplicate_mode(aconnector, &candidate));
1053 }
1054 
1055 /**
1056  * dm_test_is_duplicate_mode_no_match - Test Is duplicate mode no match
1057  * @test: The KUnit test context
1058  */
1059 static void dm_test_is_duplicate_mode_no_match(struct kunit *test)
1060 {
1061 	struct amdgpu_dm_connector *aconnector;
1062 	struct drm_display_mode existing = {};
1063 	struct drm_display_mode candidate = {};
1064 
1065 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
1066 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, aconnector);
1067 
1068 	INIT_LIST_HEAD(&aconnector->base.probed_modes);
1069 	existing.hdisplay = 1920;
1070 	existing.vdisplay = 1080;
1071 	existing.clock = 148500;
1072 	list_add_tail(&existing.head, &aconnector->base.probed_modes);
1073 
1074 	candidate.hdisplay = 2560;
1075 	candidate.vdisplay = 1440;
1076 	candidate.clock = 241500;
1077 
1078 	KUNIT_EXPECT_FALSE(test, is_duplicate_mode(aconnector, &candidate));
1079 }
1080 
1081 /**
1082  * dm_test_is_duplicate_mode_same_size_different_clock - Test Is duplicate mode
1083  * same size different clock
1084  * @test: The KUnit test context
1085  */
1086 static void dm_test_is_duplicate_mode_same_size_different_clock(struct kunit *test)
1087 {
1088 	struct amdgpu_dm_connector *aconnector;
1089 	struct drm_display_mode existing = {};
1090 	struct drm_display_mode candidate = {};
1091 
1092 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
1093 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, aconnector);
1094 
1095 	INIT_LIST_HEAD(&aconnector->base.probed_modes);
1096 	existing.hdisplay = 1920;
1097 	existing.vdisplay = 1080;
1098 	existing.clock = 148500;
1099 	list_add_tail(&existing.head, &aconnector->base.probed_modes);
1100 
1101 	candidate.hdisplay = 1920;
1102 	candidate.vdisplay = 1080;
1103 	candidate.clock = 74250;
1104 
1105 	KUNIT_EXPECT_FALSE(test, is_duplicate_mode(aconnector, &candidate));
1106 }
1107 
1108 /* Tests for amdgpu_dm_get_encoder_crtc_mask() */
1109 
1110 /**
1111  * dm_test_encoder_crtc_mask_1 - Test Encoder crtc mask 1
1112  * @test: The KUnit test context
1113  */
1114 static void dm_test_encoder_crtc_mask_1(struct kunit *test)
1115 {
1116 	struct amdgpu_device *adev;
1117 
1118 	adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
1119 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
1120 
1121 	adev->mode_info.num_crtc = 1;
1122 	KUNIT_EXPECT_EQ(test, amdgpu_dm_get_encoder_crtc_mask(adev), 0x1);
1123 }
1124 
1125 /**
1126  * dm_test_encoder_crtc_mask_2 - Test Encoder crtc mask 2
1127  * @test: The KUnit test context
1128  */
1129 static void dm_test_encoder_crtc_mask_2(struct kunit *test)
1130 {
1131 	struct amdgpu_device *adev;
1132 
1133 	adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
1134 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
1135 
1136 	adev->mode_info.num_crtc = 2;
1137 	KUNIT_EXPECT_EQ(test, amdgpu_dm_get_encoder_crtc_mask(adev), 0x3);
1138 }
1139 
1140 /**
1141  * dm_test_encoder_crtc_mask_3 - Test Encoder crtc mask 3
1142  * @test: The KUnit test context
1143  */
1144 static void dm_test_encoder_crtc_mask_3(struct kunit *test)
1145 {
1146 	struct amdgpu_device *adev;
1147 
1148 	adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
1149 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
1150 
1151 	adev->mode_info.num_crtc = 3;
1152 	KUNIT_EXPECT_EQ(test, amdgpu_dm_get_encoder_crtc_mask(adev), 0x7);
1153 }
1154 
1155 /**
1156  * dm_test_encoder_crtc_mask_4 - Test Encoder crtc mask 4
1157  * @test: The KUnit test context
1158  */
1159 static void dm_test_encoder_crtc_mask_4(struct kunit *test)
1160 {
1161 	struct amdgpu_device *adev;
1162 
1163 	adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
1164 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
1165 
1166 	adev->mode_info.num_crtc = 4;
1167 	KUNIT_EXPECT_EQ(test, amdgpu_dm_get_encoder_crtc_mask(adev), 0xf);
1168 }
1169 
1170 /**
1171  * dm_test_encoder_crtc_mask_5 - Test Encoder crtc mask 5
1172  * @test: The KUnit test context
1173  */
1174 static void dm_test_encoder_crtc_mask_5(struct kunit *test)
1175 {
1176 	struct amdgpu_device *adev;
1177 
1178 	adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
1179 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
1180 
1181 	adev->mode_info.num_crtc = 5;
1182 	KUNIT_EXPECT_EQ(test, amdgpu_dm_get_encoder_crtc_mask(adev), 0x1f);
1183 }
1184 
1185 /**
1186  * dm_test_encoder_crtc_mask_6 - Test Encoder crtc mask 6
1187  * @test: The KUnit test context
1188  */
1189 static void dm_test_encoder_crtc_mask_6(struct kunit *test)
1190 {
1191 	struct amdgpu_device *adev;
1192 
1193 	adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
1194 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
1195 
1196 	adev->mode_info.num_crtc = 6;
1197 	KUNIT_EXPECT_EQ(test, amdgpu_dm_get_encoder_crtc_mask(adev), 0x3f);
1198 }
1199 
1200 /**
1201  * dm_test_encoder_crtc_mask_default - Test Encoder crtc mask default
1202  * @test: The KUnit test context
1203  */
1204 static void dm_test_encoder_crtc_mask_default(struct kunit *test)
1205 {
1206 	struct amdgpu_device *adev;
1207 
1208 	adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
1209 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
1210 
1211 	/* Values > 6 use the default case */
1212 	adev->mode_info.num_crtc = 8;
1213 	KUNIT_EXPECT_EQ(test, amdgpu_dm_get_encoder_crtc_mask(adev), 0x3f);
1214 }
1215 
1216 /* Tests for get_aspect_ratio() */
1217 
1218 /**
1219  * dm_test_aspect_ratio_no_data - Test Aspect ratio no data
1220  * @test: The KUnit test context
1221  */
1222 static void dm_test_aspect_ratio_no_data(struct kunit *test)
1223 {
1224 	struct drm_display_mode mode = {};
1225 
1226 	mode.picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
1227 	KUNIT_EXPECT_EQ(test, (int)get_aspect_ratio(&mode), (int)ASPECT_RATIO_NO_DATA);
1228 }
1229 
1230 /**
1231  * dm_test_aspect_ratio_4_3 - Test Aspect ratio 4 3
1232  * @test: The KUnit test context
1233  */
1234 static void dm_test_aspect_ratio_4_3(struct kunit *test)
1235 {
1236 	struct drm_display_mode mode = {};
1237 
1238 	mode.picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
1239 	KUNIT_EXPECT_EQ(test, (int)get_aspect_ratio(&mode), (int)ASPECT_RATIO_4_3);
1240 }
1241 
1242 /**
1243  * dm_test_aspect_ratio_16_9 - Test Aspect ratio 16 9
1244  * @test: The KUnit test context
1245  */
1246 static void dm_test_aspect_ratio_16_9(struct kunit *test)
1247 {
1248 	struct drm_display_mode mode = {};
1249 
1250 	mode.picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
1251 	KUNIT_EXPECT_EQ(test, (int)get_aspect_ratio(&mode), (int)ASPECT_RATIO_16_9);
1252 }
1253 
1254 /**
1255  * dm_test_aspect_ratio_64_27 - Test Aspect ratio 64 27
1256  * @test: The KUnit test context
1257  */
1258 static void dm_test_aspect_ratio_64_27(struct kunit *test)
1259 {
1260 	struct drm_display_mode mode = {};
1261 
1262 	mode.picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27;
1263 	KUNIT_EXPECT_EQ(test, (int)get_aspect_ratio(&mode), (int)ASPECT_RATIO_64_27);
1264 }
1265 
1266 /**
1267  * dm_test_aspect_ratio_256_135 - Test Aspect ratio 256 135
1268  * @test: The KUnit test context
1269  */
1270 static void dm_test_aspect_ratio_256_135(struct kunit *test)
1271 {
1272 	struct drm_display_mode mode = {};
1273 
1274 	mode.picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135;
1275 	KUNIT_EXPECT_EQ(test, (int)get_aspect_ratio(&mode), (int)ASPECT_RATIO_256_135);
1276 }
1277 
1278 /* Tests for copy_crtc_timing_for_drm_display_mode() */
1279 
1280 /**
1281  * dm_test_copy_crtc_timing_copies_all_fields - Test all crtc timing fields copied
1282  * @test: The KUnit test context
1283  */
1284 static void dm_test_copy_crtc_timing_copies_all_fields(struct kunit *test)
1285 {
1286 	struct drm_display_mode src = {};
1287 	struct drm_display_mode dst = {};
1288 
1289 	src.crtc_hdisplay = 1920;
1290 	src.crtc_vdisplay = 1080;
1291 	src.crtc_clock = 148500;
1292 	src.crtc_hblank_start = 1920;
1293 	src.crtc_hblank_end = 2200;
1294 	src.crtc_hsync_start = 2008;
1295 	src.crtc_hsync_end = 2052;
1296 	src.crtc_htotal = 2200;
1297 	src.crtc_hskew = 1;
1298 	src.crtc_vblank_start = 1080;
1299 	src.crtc_vblank_end = 1125;
1300 	src.crtc_vsync_start = 1084;
1301 	src.crtc_vsync_end = 1089;
1302 	src.crtc_vtotal = 1125;
1303 
1304 	copy_crtc_timing_for_drm_display_mode(&src, &dst);
1305 
1306 	KUNIT_EXPECT_EQ(test, dst.crtc_hdisplay, 1920);
1307 	KUNIT_EXPECT_EQ(test, dst.crtc_vdisplay, 1080);
1308 	KUNIT_EXPECT_EQ(test, dst.crtc_clock, 148500);
1309 	KUNIT_EXPECT_EQ(test, dst.crtc_hblank_start, 1920);
1310 	KUNIT_EXPECT_EQ(test, dst.crtc_hblank_end, 2200);
1311 	KUNIT_EXPECT_EQ(test, dst.crtc_hsync_start, 2008);
1312 	KUNIT_EXPECT_EQ(test, dst.crtc_hsync_end, 2052);
1313 	KUNIT_EXPECT_EQ(test, dst.crtc_htotal, 2200);
1314 	KUNIT_EXPECT_EQ(test, dst.crtc_hskew, 1);
1315 	KUNIT_EXPECT_EQ(test, dst.crtc_vblank_start, 1080);
1316 	KUNIT_EXPECT_EQ(test, dst.crtc_vblank_end, 1125);
1317 	KUNIT_EXPECT_EQ(test, dst.crtc_vsync_start, 1084);
1318 	KUNIT_EXPECT_EQ(test, dst.crtc_vsync_end, 1089);
1319 	KUNIT_EXPECT_EQ(test, dst.crtc_vtotal, 1125);
1320 }
1321 
1322 /**
1323  * dm_test_copy_crtc_timing_leaves_non_crtc_fields - Test non-crtc fields untouched
1324  * @test: The KUnit test context
1325  */
1326 static void dm_test_copy_crtc_timing_leaves_non_crtc_fields(struct kunit *test)
1327 {
1328 	struct drm_display_mode src = {};
1329 	struct drm_display_mode dst = {};
1330 
1331 	src.crtc_hdisplay = 1280;
1332 	src.crtc_vdisplay = 720;
1333 
1334 	/* Non-crtc geometry on dst must be preserved by the copy */
1335 	dst.hdisplay = 1920;
1336 	dst.vdisplay = 1080;
1337 	dst.clock = 148500;
1338 
1339 	copy_crtc_timing_for_drm_display_mode(&src, &dst);
1340 
1341 	KUNIT_EXPECT_EQ(test, dst.crtc_hdisplay, 1280);
1342 	KUNIT_EXPECT_EQ(test, dst.crtc_vdisplay, 720);
1343 	KUNIT_EXPECT_EQ(test, dst.hdisplay, 1920);
1344 	KUNIT_EXPECT_EQ(test, dst.vdisplay, 1080);
1345 	KUNIT_EXPECT_EQ(test, dst.clock, 148500);
1346 }
1347 
1348 /* Tests for decide_crtc_timing_for_drm_display_mode() */
1349 
1350 /**
1351  * dm_test_decide_crtc_timing_scale_enabled - Test Decide crtc timing scale enabled
1352  * @test: The KUnit test context
1353  */
1354 static void dm_test_decide_crtc_timing_scale_enabled(struct kunit *test)
1355 {
1356 	struct drm_display_mode drm_mode = {};
1357 	struct drm_display_mode native_mode = {};
1358 
1359 	native_mode.crtc_clock = 148500;
1360 	native_mode.crtc_hdisplay = 1920;
1361 	native_mode.crtc_vdisplay = 1080;
1362 	native_mode.crtc_htotal = 2200;
1363 	native_mode.crtc_vtotal = 1125;
1364 	native_mode.crtc_hsync_start = 2008;
1365 	native_mode.crtc_hsync_end = 2052;
1366 	native_mode.crtc_vsync_start = 1084;
1367 	native_mode.crtc_vsync_end = 1089;
1368 
1369 	/* Different clock/htotal/vtotal, but scale_enabled forces copy */
1370 	drm_mode.clock = 74250;
1371 	drm_mode.htotal = 1650;
1372 	drm_mode.vtotal = 750;
1373 
1374 	decide_crtc_timing_for_drm_display_mode(&drm_mode, &native_mode, true);
1375 
1376 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_clock, 148500);
1377 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_hdisplay, 1920);
1378 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_vdisplay, 1080);
1379 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_htotal, 2200);
1380 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_vtotal, 1125);
1381 }
1382 
1383 /**
1384  * dm_test_decide_crtc_timing_matching_mode - Test Decide crtc timing matching mode
1385  * @test: The KUnit test context
1386  */
1387 static void dm_test_decide_crtc_timing_matching_mode(struct kunit *test)
1388 {
1389 	struct drm_display_mode drm_mode = {};
1390 	struct drm_display_mode native_mode = {};
1391 
1392 	native_mode.clock = 148500;
1393 	native_mode.htotal = 2200;
1394 	native_mode.vtotal = 1125;
1395 	native_mode.crtc_clock = 148500;
1396 	native_mode.crtc_hdisplay = 1920;
1397 	native_mode.crtc_vdisplay = 1080;
1398 	native_mode.crtc_htotal = 2200;
1399 	native_mode.crtc_vtotal = 1125;
1400 
1401 	/* Matching clock/htotal/vtotal triggers copy */
1402 	drm_mode.clock = 148500;
1403 	drm_mode.htotal = 2200;
1404 	drm_mode.vtotal = 1125;
1405 
1406 	decide_crtc_timing_for_drm_display_mode(&drm_mode, &native_mode, false);
1407 
1408 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_clock, 148500);
1409 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_hdisplay, 1920);
1410 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_vtotal, 1125);
1411 }
1412 
1413 /**
1414  * dm_test_decide_crtc_timing_no_copy - Test Decide crtc timing no copy
1415  * @test: The KUnit test context
1416  */
1417 static void dm_test_decide_crtc_timing_no_copy(struct kunit *test)
1418 {
1419 	struct drm_display_mode drm_mode = {};
1420 	struct drm_display_mode native_mode = {};
1421 
1422 	native_mode.clock = 148500;
1423 	native_mode.htotal = 2200;
1424 	native_mode.vtotal = 1125;
1425 	native_mode.crtc_clock = 148500;
1426 	native_mode.crtc_hdisplay = 1920;
1427 
1428 	/* Different timings, no scaling → no copy */
1429 	drm_mode.clock = 74250;
1430 	drm_mode.htotal = 1650;
1431 	drm_mode.vtotal = 750;
1432 
1433 	decide_crtc_timing_for_drm_display_mode(&drm_mode, &native_mode, false);
1434 
1435 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_clock, 0);
1436 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_hdisplay, 0);
1437 }
1438 
1439 /**
1440  * dm_test_decide_crtc_timing_no_crtc_clock - Test Decide crtc timing no crtc clock
1441  * @test: The KUnit test context
1442  */
1443 static void dm_test_decide_crtc_timing_no_crtc_clock(struct kunit *test)
1444 {
1445 	struct drm_display_mode drm_mode = {};
1446 	struct drm_display_mode native_mode = {};
1447 
1448 	/* Matching timings but native crtc_clock is 0 → no copy */
1449 	native_mode.clock = 148500;
1450 	native_mode.htotal = 2200;
1451 	native_mode.vtotal = 1125;
1452 	native_mode.crtc_clock = 0;
1453 	native_mode.crtc_hdisplay = 1920;
1454 
1455 	drm_mode.clock = 148500;
1456 	drm_mode.htotal = 2200;
1457 	drm_mode.vtotal = 1125;
1458 
1459 	decide_crtc_timing_for_drm_display_mode(&drm_mode, &native_mode, false);
1460 
1461 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_clock, 0);
1462 	KUNIT_EXPECT_EQ(test, drm_mode.crtc_hdisplay, 0);
1463 }
1464 
1465 /* Tests for amdgpu_dm_connector_funcs_reset() */
1466 
1467 static const struct drm_connector_funcs dm_test_connector_funcs = {
1468 	.reset = amdgpu_dm_connector_funcs_reset,
1469 	.atomic_duplicate_state = amdgpu_dm_connector_atomic_duplicate_state,
1470 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1471 };
1472 
1473 /**
1474  * dm_test_funcs_reset_sets_defaults - Test funcs_reset sets defaults
1475  * @test: The KUnit test context
1476  */
1477 static void dm_test_funcs_reset_sets_defaults(struct kunit *test)
1478 {
1479 	struct device *dev;
1480 	struct drm_device *drm;
1481 	struct drm_connector *connector;
1482 	struct dm_connector_state *dm_state;
1483 
1484 	dev = drm_kunit_helper_alloc_device(test);
1485 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1486 
1487 	drm = __drm_kunit_helper_alloc_drm_device(test, dev,
1488 						   sizeof(*drm), 0,
1489 						   DRIVER_MODESET);
1490 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1491 
1492 	connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
1493 	KUNIT_ASSERT_NOT_NULL(test, connector);
1494 
1495 	drmm_connector_init(drm, connector, &dm_test_connector_funcs,
1496 			    DRM_MODE_CONNECTOR_DisplayPort, NULL);
1497 
1498 	amdgpu_dm_connector_funcs_reset(connector);
1499 
1500 	KUNIT_ASSERT_NOT_NULL(test, connector->state);
1501 	dm_state = to_dm_connector_state(connector->state);
1502 	KUNIT_EXPECT_EQ(test, (int)dm_state->scaling, (int)RMX_OFF);
1503 	KUNIT_EXPECT_FALSE(test, dm_state->underscan_enable);
1504 	KUNIT_EXPECT_EQ(test, (int)dm_state->underscan_hborder, 0);
1505 	KUNIT_EXPECT_EQ(test, (int)dm_state->underscan_vborder, 0);
1506 	KUNIT_EXPECT_EQ(test, (int)dm_state->base.max_requested_bpc, 8);
1507 	KUNIT_EXPECT_EQ(test, dm_state->vcpi_slots, 0);
1508 	KUNIT_EXPECT_EQ(test, (int)dm_state->pbn, 0);
1509 }
1510 
1511 /**
1512  * dm_test_funcs_reset_edp_abm_level - Test funcs_reset eDP sets ABM
1513  * @test: The KUnit test context
1514  */
1515 static void dm_test_funcs_reset_edp_abm_level(struct kunit *test)
1516 {
1517 	struct device *dev;
1518 	struct drm_device *drm;
1519 	struct drm_connector *connector;
1520 	struct dm_connector_state *dm_state;
1521 	int saved_abm_level = amdgpu_dm_get_abm_level_param();
1522 
1523 	dev = drm_kunit_helper_alloc_device(test);
1524 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1525 
1526 	drm = __drm_kunit_helper_alloc_drm_device(test, dev,
1527 						   sizeof(*drm), 0,
1528 						   DRIVER_MODESET);
1529 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1530 
1531 	connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
1532 	KUNIT_ASSERT_NOT_NULL(test, connector);
1533 
1534 	drmm_connector_init(drm, connector, &dm_test_connector_funcs,
1535 			    DRM_MODE_CONNECTOR_eDP, NULL);
1536 
1537 	/* Test with abm_level > 0 */
1538 	amdgpu_dm_set_abm_level_param(3);
1539 	amdgpu_dm_connector_funcs_reset(connector);
1540 
1541 	KUNIT_ASSERT_NOT_NULL(test, connector->state);
1542 	dm_state = to_dm_connector_state(connector->state);
1543 	KUNIT_EXPECT_EQ(test, (int)dm_state->abm_level, 3);
1544 
1545 	amdgpu_dm_set_abm_level_param(saved_abm_level);
1546 }
1547 
1548 /**
1549  * dm_test_funcs_reset_edp_abm_disabled - Test funcs_reset eDP ABM
1550  * disabled
1551  * @test: The KUnit test context
1552  */
1553 static void dm_test_funcs_reset_edp_abm_disabled(struct kunit *test)
1554 {
1555 	struct device *dev;
1556 	struct drm_device *drm;
1557 	struct drm_connector *connector;
1558 	struct dm_connector_state *dm_state;
1559 	int saved_abm_level = amdgpu_dm_get_abm_level_param();
1560 
1561 	dev = drm_kunit_helper_alloc_device(test);
1562 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1563 
1564 	drm = __drm_kunit_helper_alloc_drm_device(test, dev,
1565 						   sizeof(*drm), 0,
1566 						   DRIVER_MODESET);
1567 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1568 
1569 	connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
1570 	KUNIT_ASSERT_NOT_NULL(test, connector);
1571 
1572 	drmm_connector_init(drm, connector, &dm_test_connector_funcs,
1573 			    DRM_MODE_CONNECTOR_eDP, NULL);
1574 
1575 	/* Test with abm_level <= 0 → immediate disable */
1576 	amdgpu_dm_set_abm_level_param(-1);
1577 	amdgpu_dm_connector_funcs_reset(connector);
1578 
1579 	KUNIT_ASSERT_NOT_NULL(test, connector->state);
1580 	dm_state = to_dm_connector_state(connector->state);
1581 	KUNIT_EXPECT_EQ(test, (int)dm_state->abm_level,
1582 			(int)ABM_LEVEL_IMMEDIATE_DISABLE);
1583 
1584 	amdgpu_dm_set_abm_level_param(saved_abm_level);
1585 }
1586 
1587 /* Tests for amdgpu_dm_connector_atomic_duplicate_state() */
1588 
1589 /**
1590  * dm_test_atomic_dup_state_copies_fields - Test atomic_duplicate copies
1591  * fields
1592  * @test: The KUnit test context
1593  */
1594 static void dm_test_atomic_dup_state_copies_fields(struct kunit *test)
1595 {
1596 	struct device *dev;
1597 	struct drm_device *drm;
1598 	struct drm_connector *connector;
1599 	struct dm_connector_state *dm_state;
1600 	struct dm_connector_state *new_dm_state;
1601 	struct drm_connector_state *new_state;
1602 
1603 	dev = drm_kunit_helper_alloc_device(test);
1604 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1605 
1606 	drm = __drm_kunit_helper_alloc_drm_device(test, dev,
1607 						   sizeof(*drm), 0,
1608 						   DRIVER_MODESET);
1609 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1610 
1611 	connector = drmm_kzalloc(drm, sizeof(*connector), GFP_KERNEL);
1612 	KUNIT_ASSERT_NOT_NULL(test, connector);
1613 
1614 	drmm_connector_init(drm, connector, &dm_test_connector_funcs,
1615 			    DRM_MODE_CONNECTOR_HDMIA, NULL);
1616 
1617 	amdgpu_dm_connector_funcs_reset(connector);
1618 	KUNIT_ASSERT_NOT_NULL(test, connector->state);
1619 
1620 	/* Modify original state fields */
1621 	dm_state = to_dm_connector_state(connector->state);
1622 	dm_state->scaling = RMX_CENTER;
1623 	dm_state->underscan_enable = true;
1624 	dm_state->underscan_hborder = 10;
1625 	dm_state->underscan_vborder = 20;
1626 	dm_state->freesync_capable = true;
1627 	dm_state->abm_level = 2;
1628 	dm_state->vcpi_slots = 4;
1629 	dm_state->pbn = 1234;
1630 
1631 	/* Duplicate */
1632 	new_state = amdgpu_dm_connector_atomic_duplicate_state(connector);
1633 	KUNIT_ASSERT_NOT_NULL(test, new_state);
1634 	new_dm_state = to_dm_connector_state(new_state);
1635 
1636 	/* Verify all fields copied */
1637 	KUNIT_EXPECT_EQ(test, (int)new_dm_state->scaling, (int)RMX_CENTER);
1638 	KUNIT_EXPECT_TRUE(test, new_dm_state->underscan_enable);
1639 	KUNIT_EXPECT_EQ(test, (int)new_dm_state->underscan_hborder, 10);
1640 	KUNIT_EXPECT_EQ(test, (int)new_dm_state->underscan_vborder, 20);
1641 	KUNIT_EXPECT_TRUE(test, new_dm_state->freesync_capable);
1642 	KUNIT_EXPECT_EQ(test, (int)new_dm_state->abm_level, 2);
1643 	KUNIT_EXPECT_EQ(test, new_dm_state->vcpi_slots, 4);
1644 	KUNIT_EXPECT_EQ(test, (int)new_dm_state->pbn, 1234);
1645 
1646 	kfree(new_dm_state);
1647 }
1648 
1649 /* Tests for amdgpu_dm_fill_hdr_info_packet() */
1650 
1651 /**
1652  * dm_test_fill_hdr_null_metadata - Test fill_hdr returns 0 with no
1653  * metadata
1654  * @test: The KUnit test context
1655  */
1656 static void dm_test_fill_hdr_null_metadata(struct kunit *test)
1657 {
1658 	struct drm_connector_state state = {};
1659 	struct dc_info_packet out = {};
1660 
1661 	/* No hdr_output_metadata → early return 0, out stays zeroed */
1662 	state.hdr_output_metadata = NULL;
1663 	KUNIT_EXPECT_EQ(test, amdgpu_dm_fill_hdr_info_packet(&state, &out), 0);
1664 	KUNIT_EXPECT_FALSE(test, out.valid);
1665 }
1666 
1667 /**
1668  * dm_test_fill_hdr_zeroes_output - Test fill_hdr zeroes output with no
1669  * metadata
1670  * @test: The KUnit test context
1671  */
1672 static void dm_test_fill_hdr_zeroes_output(struct kunit *test)
1673 {
1674 	struct drm_connector_state state = {};
1675 	struct dc_info_packet out;
1676 
1677 	/* Pre-fill out with nonzero to verify memset(0) */
1678 	memset(&out, 0xAA, sizeof(out));
1679 
1680 	state.hdr_output_metadata = NULL;
1681 	KUNIT_EXPECT_EQ(test, amdgpu_dm_fill_hdr_info_packet(&state, &out), 0);
1682 	KUNIT_EXPECT_FALSE(test, out.valid);
1683 	KUNIT_EXPECT_EQ(test, (int)out.hb0, 0);
1684 	KUNIT_EXPECT_EQ(test, (int)out.hb1, 0);
1685 	KUNIT_EXPECT_EQ(test, (int)out.hb2, 0);
1686 	KUNIT_EXPECT_EQ(test, (int)out.hb3, 0);
1687 }
1688 
1689 /* Tests for amdgpu_dm_connector_atomic_set_property() */
1690 
1691 /*
1692  * Build a connector wired to a kunit-allocated amdgpu_device so that
1693  * drm_to_adev() resolves correctly, together with old/new dm states and
1694  * the set of properties used by the get/set property handlers.
1695  */
1696 struct dm_test_prop_ctx {
1697 	struct amdgpu_device *adev;
1698 	struct drm_connector *connector;
1699 	struct dm_connector_state *old_state;
1700 	struct dm_connector_state *new_state;
1701 	struct drm_property *scaling_prop;
1702 	struct drm_property *hborder_prop;
1703 	struct drm_property *vborder_prop;
1704 	struct drm_property *underscan_prop;
1705 	struct drm_property *abm_prop;
1706 };
1707 
1708 static struct dm_test_prop_ctx *dm_test_prop_ctx_alloc(struct kunit *test)
1709 {
1710 	struct dm_test_prop_ctx *ctx;
1711 
1712 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
1713 	KUNIT_ASSERT_NOT_NULL(test, ctx);
1714 
1715 	ctx->adev = kunit_kzalloc(test, sizeof(*ctx->adev), GFP_KERNEL);
1716 	KUNIT_ASSERT_NOT_NULL(test, ctx->adev);
1717 	ctx->connector = kunit_kzalloc(test, sizeof(*ctx->connector), GFP_KERNEL);
1718 	KUNIT_ASSERT_NOT_NULL(test, ctx->connector);
1719 	ctx->old_state = kunit_kzalloc(test, sizeof(*ctx->old_state), GFP_KERNEL);
1720 	KUNIT_ASSERT_NOT_NULL(test, ctx->old_state);
1721 	ctx->new_state = kunit_kzalloc(test, sizeof(*ctx->new_state), GFP_KERNEL);
1722 	KUNIT_ASSERT_NOT_NULL(test, ctx->new_state);
1723 	ctx->scaling_prop = kunit_kzalloc(test, sizeof(*ctx->scaling_prop), GFP_KERNEL);
1724 	KUNIT_ASSERT_NOT_NULL(test, ctx->scaling_prop);
1725 	ctx->hborder_prop = kunit_kzalloc(test, sizeof(*ctx->hborder_prop), GFP_KERNEL);
1726 	KUNIT_ASSERT_NOT_NULL(test, ctx->hborder_prop);
1727 	ctx->vborder_prop = kunit_kzalloc(test, sizeof(*ctx->vborder_prop), GFP_KERNEL);
1728 	KUNIT_ASSERT_NOT_NULL(test, ctx->vborder_prop);
1729 	ctx->underscan_prop = kunit_kzalloc(test, sizeof(*ctx->underscan_prop), GFP_KERNEL);
1730 	KUNIT_ASSERT_NOT_NULL(test, ctx->underscan_prop);
1731 	ctx->abm_prop = kunit_kzalloc(test, sizeof(*ctx->abm_prop), GFP_KERNEL);
1732 	KUNIT_ASSERT_NOT_NULL(test, ctx->abm_prop);
1733 
1734 	ctx->connector->dev = &ctx->adev->ddev;
1735 	ctx->connector->state = &ctx->old_state->base;
1736 
1737 	ctx->adev->ddev.mode_config.scaling_mode_property = ctx->scaling_prop;
1738 	ctx->adev->mode_info.underscan_hborder_property = ctx->hborder_prop;
1739 	ctx->adev->mode_info.underscan_vborder_property = ctx->vborder_prop;
1740 	ctx->adev->mode_info.underscan_property = ctx->underscan_prop;
1741 	ctx->adev->mode_info.abm_level_property = ctx->abm_prop;
1742 
1743 	return ctx;
1744 }
1745 
1746 /**
1747  * dm_test_set_property_scaling_center - Test set scaling property to center
1748  * @test: The KUnit test context
1749  */
1750 static void dm_test_set_property_scaling_center(struct kunit *test)
1751 {
1752 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1753 
1754 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1755 				ctx->connector, &ctx->new_state->base,
1756 				ctx->scaling_prop, DRM_MODE_SCALE_CENTER), 0);
1757 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->scaling, (int)RMX_CENTER);
1758 }
1759 
1760 /**
1761  * dm_test_set_property_scaling_aspect - Test set scaling property to aspect
1762  * @test: The KUnit test context
1763  */
1764 static void dm_test_set_property_scaling_aspect(struct kunit *test)
1765 {
1766 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1767 
1768 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1769 				ctx->connector, &ctx->new_state->base,
1770 				ctx->scaling_prop, DRM_MODE_SCALE_ASPECT), 0);
1771 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->scaling, (int)RMX_ASPECT);
1772 }
1773 
1774 /**
1775  * dm_test_set_property_scaling_fullscreen - Test set scaling property to full
1776  * @test: The KUnit test context
1777  */
1778 static void dm_test_set_property_scaling_fullscreen(struct kunit *test)
1779 {
1780 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1781 
1782 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1783 				ctx->connector, &ctx->new_state->base,
1784 				ctx->scaling_prop, DRM_MODE_SCALE_FULLSCREEN), 0);
1785 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->scaling, (int)RMX_FULL);
1786 }
1787 
1788 /**
1789  * dm_test_set_property_scaling_none - Test set scaling property to none
1790  * @test: The KUnit test context
1791  */
1792 static void dm_test_set_property_scaling_none(struct kunit *test)
1793 {
1794 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1795 
1796 	/* old scaling is RMX_CENTER so RMX_OFF is a real change */
1797 	ctx->old_state->scaling = RMX_CENTER;
1798 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1799 				ctx->connector, &ctx->new_state->base,
1800 				ctx->scaling_prop, DRM_MODE_SCALE_NONE), 0);
1801 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->scaling, (int)RMX_OFF);
1802 }
1803 
1804 /**
1805  * dm_test_set_property_scaling_unchanged - Test set scaling property unchanged
1806  * @test: The KUnit test context
1807  */
1808 static void dm_test_set_property_scaling_unchanged(struct kunit *test)
1809 {
1810 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1811 
1812 	/* old already RMX_OFF, requesting NONE/OFF returns 0 without write */
1813 	ctx->old_state->scaling = RMX_OFF;
1814 	ctx->new_state->scaling = RMX_CENTER;
1815 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1816 				ctx->connector, &ctx->new_state->base,
1817 				ctx->scaling_prop, DRM_MODE_SCALE_NONE), 0);
1818 	/* new_state untouched because of early return */
1819 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->scaling, (int)RMX_CENTER);
1820 }
1821 
1822 /**
1823  * dm_test_set_property_underscan_hborder - Test set underscan hborder
1824  * @test: The KUnit test context
1825  */
1826 static void dm_test_set_property_underscan_hborder(struct kunit *test)
1827 {
1828 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1829 
1830 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1831 				ctx->connector, &ctx->new_state->base,
1832 				ctx->hborder_prop, 42), 0);
1833 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->underscan_hborder, 42);
1834 }
1835 
1836 /**
1837  * dm_test_set_property_underscan_vborder - Test set underscan vborder
1838  * @test: The KUnit test context
1839  */
1840 static void dm_test_set_property_underscan_vborder(struct kunit *test)
1841 {
1842 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1843 
1844 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1845 				ctx->connector, &ctx->new_state->base,
1846 				ctx->vborder_prop, 24), 0);
1847 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->underscan_vborder, 24);
1848 }
1849 
1850 /**
1851  * dm_test_set_property_underscan_enable - Test set underscan enable
1852  * @test: The KUnit test context
1853  */
1854 static void dm_test_set_property_underscan_enable(struct kunit *test)
1855 {
1856 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1857 
1858 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1859 				ctx->connector, &ctx->new_state->base,
1860 				ctx->underscan_prop, 1), 0);
1861 	KUNIT_EXPECT_TRUE(test, ctx->new_state->underscan_enable);
1862 }
1863 
1864 /**
1865  * dm_test_set_property_abm_sysfs_control - Test set abm sysfs control
1866  * @test: The KUnit test context
1867  */
1868 static void dm_test_set_property_abm_sysfs_control(struct kunit *test)
1869 {
1870 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1871 
1872 	ctx->new_state->abm_sysfs_forbidden = true;
1873 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1874 				ctx->connector, &ctx->new_state->base,
1875 				ctx->abm_prop, ABM_SYSFS_CONTROL), 0);
1876 	KUNIT_EXPECT_FALSE(test, ctx->new_state->abm_sysfs_forbidden);
1877 }
1878 
1879 /**
1880  * dm_test_set_property_abm_level_off - Test set abm level off
1881  * @test: The KUnit test context
1882  */
1883 static void dm_test_set_property_abm_level_off(struct kunit *test)
1884 {
1885 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1886 
1887 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1888 				ctx->connector, &ctx->new_state->base,
1889 				ctx->abm_prop, ABM_LEVEL_OFF), 0);
1890 	KUNIT_EXPECT_TRUE(test, ctx->new_state->abm_sysfs_forbidden);
1891 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->abm_level,
1892 			(int)ABM_LEVEL_IMMEDIATE_DISABLE);
1893 }
1894 
1895 /**
1896  * dm_test_set_property_abm_level_value - Test set abm level to a value
1897  * @test: The KUnit test context
1898  */
1899 static void dm_test_set_property_abm_level_value(struct kunit *test)
1900 {
1901 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1902 
1903 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1904 				ctx->connector, &ctx->new_state->base,
1905 				ctx->abm_prop, 3), 0);
1906 	KUNIT_EXPECT_TRUE(test, ctx->new_state->abm_sysfs_forbidden);
1907 	KUNIT_EXPECT_EQ(test, (int)ctx->new_state->abm_level, 3);
1908 }
1909 
1910 /**
1911  * dm_test_set_property_unknown - Test set unknown property returns -EINVAL
1912  * @test: The KUnit test context
1913  */
1914 static void dm_test_set_property_unknown(struct kunit *test)
1915 {
1916 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1917 	struct drm_property *other;
1918 
1919 	other = kunit_kzalloc(test, sizeof(*other), GFP_KERNEL);
1920 	KUNIT_ASSERT_NOT_NULL(test, other);
1921 
1922 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_set_property(
1923 				ctx->connector, &ctx->new_state->base,
1924 				other, 0), -EINVAL);
1925 }
1926 
1927 /* Tests for amdgpu_dm_connector_atomic_get_property() */
1928 
1929 /**
1930  * dm_test_get_property_scaling_center - Test get scaling property center
1931  * @test: The KUnit test context
1932  */
1933 static void dm_test_get_property_scaling_center(struct kunit *test)
1934 {
1935 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1936 	uint64_t val = 0;
1937 
1938 	ctx->new_state->scaling = RMX_CENTER;
1939 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
1940 				ctx->connector, &ctx->new_state->base,
1941 				ctx->scaling_prop, &val), 0);
1942 	KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SCALE_CENTER);
1943 }
1944 
1945 /**
1946  * dm_test_get_property_scaling_aspect - Test get scaling property aspect
1947  * @test: The KUnit test context
1948  */
1949 static void dm_test_get_property_scaling_aspect(struct kunit *test)
1950 {
1951 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1952 	uint64_t val = 0;
1953 
1954 	ctx->new_state->scaling = RMX_ASPECT;
1955 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
1956 				ctx->connector, &ctx->new_state->base,
1957 				ctx->scaling_prop, &val), 0);
1958 	KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SCALE_ASPECT);
1959 }
1960 
1961 /**
1962  * dm_test_get_property_scaling_full - Test get scaling property fullscreen
1963  * @test: The KUnit test context
1964  */
1965 static void dm_test_get_property_scaling_full(struct kunit *test)
1966 {
1967 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1968 	uint64_t val = 0;
1969 
1970 	ctx->new_state->scaling = RMX_FULL;
1971 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
1972 				ctx->connector, &ctx->new_state->base,
1973 				ctx->scaling_prop, &val), 0);
1974 	KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SCALE_FULLSCREEN);
1975 }
1976 
1977 /**
1978  * dm_test_get_property_scaling_off - Test get scaling property off/none
1979  * @test: The KUnit test context
1980  */
1981 static void dm_test_get_property_scaling_off(struct kunit *test)
1982 {
1983 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
1984 	uint64_t val = 0;
1985 
1986 	ctx->new_state->scaling = RMX_OFF;
1987 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
1988 				ctx->connector, &ctx->new_state->base,
1989 				ctx->scaling_prop, &val), 0);
1990 	KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SCALE_NONE);
1991 }
1992 
1993 /**
1994  * dm_test_get_property_underscan_borders - Test get underscan borders/enable
1995  * @test: The KUnit test context
1996  */
1997 static void dm_test_get_property_underscan_borders(struct kunit *test)
1998 {
1999 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
2000 	uint64_t val = 0;
2001 
2002 	ctx->new_state->underscan_hborder = 12;
2003 	ctx->new_state->underscan_vborder = 34;
2004 	ctx->new_state->underscan_enable = true;
2005 
2006 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
2007 				ctx->connector, &ctx->new_state->base,
2008 				ctx->hborder_prop, &val), 0);
2009 	KUNIT_EXPECT_EQ(test, (int)val, 12);
2010 
2011 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
2012 				ctx->connector, &ctx->new_state->base,
2013 				ctx->vborder_prop, &val), 0);
2014 	KUNIT_EXPECT_EQ(test, (int)val, 34);
2015 
2016 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
2017 				ctx->connector, &ctx->new_state->base,
2018 				ctx->underscan_prop, &val), 0);
2019 	KUNIT_EXPECT_EQ(test, (int)val, 1);
2020 }
2021 
2022 /**
2023  * dm_test_get_property_abm_sysfs_allowed - Test get abm returns sysfs control
2024  * @test: The KUnit test context
2025  */
2026 static void dm_test_get_property_abm_sysfs_allowed(struct kunit *test)
2027 {
2028 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
2029 	uint64_t val = 0;
2030 
2031 	ctx->new_state->abm_sysfs_forbidden = false;
2032 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
2033 				ctx->connector, &ctx->new_state->base,
2034 				ctx->abm_prop, &val), 0);
2035 	KUNIT_EXPECT_EQ(test, (int)val, (int)ABM_SYSFS_CONTROL);
2036 }
2037 
2038 /**
2039  * dm_test_get_property_abm_level - Test get abm returns level when forbidden
2040  * @test: The KUnit test context
2041  */
2042 static void dm_test_get_property_abm_level(struct kunit *test)
2043 {
2044 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
2045 	uint64_t val = 0;
2046 
2047 	ctx->new_state->abm_sysfs_forbidden = true;
2048 	ctx->new_state->abm_level = 2;
2049 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
2050 				ctx->connector, &ctx->new_state->base,
2051 				ctx->abm_prop, &val), 0);
2052 	KUNIT_EXPECT_EQ(test, (int)val, 2);
2053 }
2054 
2055 /**
2056  * dm_test_get_property_abm_disabled_zero - Test get abm returns 0 when disabled
2057  * @test: The KUnit test context
2058  */
2059 static void dm_test_get_property_abm_disabled_zero(struct kunit *test)
2060 {
2061 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
2062 	uint64_t val = 0xdead;
2063 
2064 	ctx->new_state->abm_sysfs_forbidden = true;
2065 	ctx->new_state->abm_level = ABM_LEVEL_IMMEDIATE_DISABLE;
2066 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
2067 				ctx->connector, &ctx->new_state->base,
2068 				ctx->abm_prop, &val), 0);
2069 	KUNIT_EXPECT_EQ(test, (int)val, 0);
2070 }
2071 
2072 /**
2073  * dm_test_get_property_unknown - Test get unknown property returns -EINVAL
2074  * @test: The KUnit test context
2075  */
2076 static void dm_test_get_property_unknown(struct kunit *test)
2077 {
2078 	struct dm_test_prop_ctx *ctx = dm_test_prop_ctx_alloc(test);
2079 	struct drm_property *other;
2080 	uint64_t val = 0;
2081 
2082 	other = kunit_kzalloc(test, sizeof(*other), GFP_KERNEL);
2083 	KUNIT_ASSERT_NOT_NULL(test, other);
2084 
2085 	KUNIT_EXPECT_EQ(test, amdgpu_dm_connector_atomic_get_property(
2086 				ctx->connector, &ctx->new_state->base,
2087 				other, &val), -EINVAL);
2088 }
2089 
2090 /* Tests for amdgpu_dm_get_highest_refresh_rate_mode() */
2091 
2092 /**
2093  * dm_test_highest_refresh_writeback_null - Test writeback connector returns NULL
2094  * @test: The KUnit test context
2095  */
2096 static void dm_test_highest_refresh_writeback_null(struct kunit *test)
2097 {
2098 	struct amdgpu_dm_connector *aconnector;
2099 
2100 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
2101 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2102 
2103 	aconnector->base.connector_type = DRM_MODE_CONNECTOR_WRITEBACK;
2104 	KUNIT_EXPECT_NULL(test, amdgpu_dm_get_highest_refresh_rate_mode(aconnector, false));
2105 }
2106 
2107 /**
2108  * dm_test_highest_refresh_cached_base - Test cached freesync_vid_base is returned
2109  * @test: The KUnit test context
2110  */
2111 static void dm_test_highest_refresh_cached_base(struct kunit *test)
2112 {
2113 	struct amdgpu_dm_connector *aconnector;
2114 
2115 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
2116 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2117 
2118 	aconnector->base.connector_type = DRM_MODE_CONNECTOR_HDMIA;
2119 	aconnector->freesync_vid_base.clock = 148500;
2120 
2121 	KUNIT_EXPECT_PTR_EQ(test, amdgpu_dm_get_highest_refresh_rate_mode(aconnector, false),
2122 			    &aconnector->freesync_vid_base);
2123 }
2124 
2125 /**
2126  * dm_test_highest_refresh_preferred_mode - Test preferred mode is selected
2127  * @test: The KUnit test context
2128  */
2129 static void dm_test_highest_refresh_preferred_mode(struct kunit *test)
2130 {
2131 	struct amdgpu_dm_connector *aconnector;
2132 	struct drm_display_mode *mode;
2133 
2134 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
2135 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2136 	mode = kunit_kzalloc(test, sizeof(*mode), GFP_KERNEL);
2137 	KUNIT_ASSERT_NOT_NULL(test, mode);
2138 
2139 	aconnector->base.connector_type = DRM_MODE_CONNECTOR_HDMIA;
2140 	INIT_LIST_HEAD(&aconnector->base.modes);
2141 
2142 	mode->type = DRM_MODE_TYPE_PREFERRED;
2143 	mode->clock = 148500;
2144 	mode->hdisplay = 1920;
2145 	mode->vdisplay = 1080;
2146 	mode->htotal = 2200;
2147 	mode->vtotal = 1125;
2148 	list_add_tail(&mode->head, &aconnector->base.modes);
2149 
2150 	KUNIT_EXPECT_PTR_EQ(test, amdgpu_dm_get_highest_refresh_rate_mode(aconnector, false),
2151 			    mode);
2152 }
2153 
2154 /* Tests for amdgpu_dm_is_freesync_video_mode() */
2155 
2156 /**
2157  * dm_test_is_freesync_video_mode_null_mode - Test NULL mode returns false
2158  * @test: The KUnit test context
2159  */
2160 static void dm_test_is_freesync_video_mode_null_mode(struct kunit *test)
2161 {
2162 	struct amdgpu_dm_connector *aconnector;
2163 
2164 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
2165 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2166 
2167 	aconnector->base.connector_type = DRM_MODE_CONNECTOR_HDMIA;
2168 	aconnector->freesync_vid_base.clock = 148500;
2169 
2170 	KUNIT_EXPECT_FALSE(test, amdgpu_dm_is_freesync_video_mode(NULL, aconnector));
2171 }
2172 
2173 /**
2174  * dm_test_is_freesync_video_mode_match - Test matching mode returns true
2175  * @test: The KUnit test context
2176  */
2177 static void dm_test_is_freesync_video_mode_match(struct kunit *test)
2178 {
2179 	struct amdgpu_dm_connector *aconnector;
2180 	struct drm_display_mode candidate = {};
2181 
2182 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
2183 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2184 
2185 	/* Cached high mode acts as reference */
2186 	aconnector->base.connector_type = DRM_MODE_CONNECTOR_HDMIA;
2187 	aconnector->freesync_vid_base.clock = 148500;
2188 	aconnector->freesync_vid_base.hdisplay = 1920;
2189 	aconnector->freesync_vid_base.vdisplay = 1080;
2190 	aconnector->freesync_vid_base.hsync_start = 2008;
2191 	aconnector->freesync_vid_base.hsync_end = 2052;
2192 	aconnector->freesync_vid_base.htotal = 2200;
2193 	aconnector->freesync_vid_base.vsync_start = 1084;
2194 	aconnector->freesync_vid_base.vsync_end = 1089;
2195 	aconnector->freesync_vid_base.vtotal = 1125;
2196 
2197 	candidate.clock = 148500;
2198 	candidate.hdisplay = 1920;
2199 	candidate.vdisplay = 1080;
2200 	candidate.hsync_start = 2008;
2201 	candidate.hsync_end = 2052;
2202 	candidate.htotal = 2200;
2203 	candidate.vsync_start = 1084;
2204 	candidate.vsync_end = 1089;
2205 	candidate.vtotal = 1125;
2206 
2207 	KUNIT_EXPECT_TRUE(test, amdgpu_dm_is_freesync_video_mode(&candidate, aconnector));
2208 }
2209 
2210 /**
2211  * dm_test_is_freesync_video_mode_no_match - Test mismatched mode returns false
2212  * @test: The KUnit test context
2213  */
2214 static void dm_test_is_freesync_video_mode_no_match(struct kunit *test)
2215 {
2216 	struct amdgpu_dm_connector *aconnector;
2217 	struct drm_display_mode candidate = {};
2218 
2219 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
2220 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2221 
2222 	aconnector->base.connector_type = DRM_MODE_CONNECTOR_HDMIA;
2223 	aconnector->freesync_vid_base.clock = 148500;
2224 	aconnector->freesync_vid_base.hdisplay = 1920;
2225 	aconnector->freesync_vid_base.vdisplay = 1080;
2226 	aconnector->freesync_vid_base.htotal = 2200;
2227 	aconnector->freesync_vid_base.vtotal = 1125;
2228 
2229 	/* Different resolution → not a freesync video mode */
2230 	candidate.clock = 148500;
2231 	candidate.hdisplay = 1280;
2232 	candidate.vdisplay = 720;
2233 	candidate.htotal = 1650;
2234 	candidate.vtotal = 750;
2235 
2236 	KUNIT_EXPECT_FALSE(test, amdgpu_dm_is_freesync_video_mode(&candidate, aconnector));
2237 }
2238 
2239 /* Tests for amdgpu_dm_update_cacp_caps() */
2240 
2241 struct dm_cacp_fixture {
2242 	struct amdgpu_device *adev;
2243 	struct amdgpu_dm_connector *aconnector;
2244 	struct dc_link *link;
2245 };
2246 
2247 static void setup_cacp_fixture(struct kunit *test,
2248 			       struct dm_cacp_fixture *fixture,
2249 			       enum signal_type signal,
2250 			       enum dc_panel_type panel_type)
2251 {
2252 	fixture->adev = kunit_kzalloc(test, sizeof(*fixture->adev), GFP_KERNEL);
2253 	fixture->aconnector = kunit_kzalloc(test, sizeof(*fixture->aconnector),
2254 					    GFP_KERNEL);
2255 	fixture->link = kunit_kzalloc(test, sizeof(*fixture->link), GFP_KERNEL);
2256 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->adev);
2257 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->aconnector);
2258 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->link);
2259 
2260 	fixture->aconnector->dc_link = fixture->link;
2261 	fixture->aconnector->base.dev = &fixture->adev->ddev;
2262 	fixture->link->connector_signal = signal;
2263 	fixture->link->panel_type = panel_type;
2264 }
2265 
2266 /**
2267  * dm_test_cacp_caps_unsupported_ip - Test CACP disabled on old DCE IP
2268  * @test: The KUnit test context
2269  *
2270  * A DCE IP version below 3.1.4 does not support CACP, so cacp_supported
2271  * must remain false regardless of signal or panel type.
2272  */
2273 static void dm_test_cacp_caps_unsupported_ip(struct kunit *test)
2274 {
2275 	struct dm_cacp_fixture fixture = {};
2276 
2277 	setup_cacp_fixture(test, &fixture, SIGNAL_TYPE_EDP, PANEL_TYPE_OLED);
2278 	fixture.adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 1, 2);
2279 
2280 	amdgpu_dm_update_cacp_caps(fixture.aconnector);
2281 
2282 	KUNIT_EXPECT_FALSE(test, fixture.link->panel_config.cacp.cacp_supported);
2283 }
2284 
2285 /**
2286  * dm_test_cacp_caps_excluded_ip_316 - Test CACP disabled on DCE IP 3.1.6
2287  * @test: The KUnit test context
2288  *
2289  * DCE IP version 3.1.6 is explicitly excluded from CACP support.
2290  */
2291 static void dm_test_cacp_caps_excluded_ip_316(struct kunit *test)
2292 {
2293 	struct dm_cacp_fixture fixture = {};
2294 
2295 	setup_cacp_fixture(test, &fixture, SIGNAL_TYPE_EDP, PANEL_TYPE_OLED);
2296 	fixture.adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 1, 6);
2297 
2298 	amdgpu_dm_update_cacp_caps(fixture.aconnector);
2299 
2300 	KUNIT_EXPECT_FALSE(test, fixture.link->panel_config.cacp.cacp_supported);
2301 }
2302 
2303 /**
2304  * dm_test_cacp_caps_edp_oled_supported - Test CACP enabled on eDP OLED
2305  * @test: The KUnit test context
2306  *
2307  * A supported DCE IP version on an eDP OLED panel must enable CACP.
2308  */
2309 static void dm_test_cacp_caps_edp_oled_supported(struct kunit *test)
2310 {
2311 	struct dm_cacp_fixture fixture = {};
2312 
2313 	setup_cacp_fixture(test, &fixture, SIGNAL_TYPE_EDP, PANEL_TYPE_OLED);
2314 	fixture.adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 1, 4);
2315 
2316 	amdgpu_dm_update_cacp_caps(fixture.aconnector);
2317 
2318 	KUNIT_EXPECT_TRUE(test, fixture.link->panel_config.cacp.cacp_supported);
2319 }
2320 
2321 /**
2322  * dm_test_cacp_caps_lvds_oled_supported - Test CACP enabled on LVDS OLED
2323  * @test: The KUnit test context
2324  *
2325  * LVDS is an accepted connector signal for CACP support.
2326  */
2327 static void dm_test_cacp_caps_lvds_oled_supported(struct kunit *test)
2328 {
2329 	struct dm_cacp_fixture fixture = {};
2330 
2331 	setup_cacp_fixture(test, &fixture, SIGNAL_TYPE_LVDS, PANEL_TYPE_OLED);
2332 	fixture.adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 5, 0);
2333 
2334 	amdgpu_dm_update_cacp_caps(fixture.aconnector);
2335 
2336 	KUNIT_EXPECT_TRUE(test, fixture.link->panel_config.cacp.cacp_supported);
2337 }
2338 
2339 /**
2340  * dm_test_cacp_caps_non_edp_signal - Test CACP disabled on non-eDP/LVDS signal
2341  * @test: The KUnit test context
2342  *
2343  * External DisplayPort is neither eDP nor LVDS, so CACP must be disabled.
2344  */
2345 static void dm_test_cacp_caps_non_edp_signal(struct kunit *test)
2346 {
2347 	struct dm_cacp_fixture fixture = {};
2348 
2349 	setup_cacp_fixture(test, &fixture, SIGNAL_TYPE_DISPLAY_PORT,
2350 			   PANEL_TYPE_OLED);
2351 	fixture.adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 1, 4);
2352 
2353 	amdgpu_dm_update_cacp_caps(fixture.aconnector);
2354 
2355 	KUNIT_EXPECT_FALSE(test, fixture.link->panel_config.cacp.cacp_supported);
2356 }
2357 
2358 /**
2359  * dm_test_cacp_caps_lcd_panel - Test CACP disabled on LCD panel
2360  * @test: The KUnit test context
2361  *
2362  * Plain LCD panels do not benefit from CACP, so it must be disabled even
2363  * on a supported IP version and eDP signal.
2364  */
2365 static void dm_test_cacp_caps_lcd_panel(struct kunit *test)
2366 {
2367 	struct dm_cacp_fixture fixture = {};
2368 
2369 	setup_cacp_fixture(test, &fixture, SIGNAL_TYPE_EDP, PANEL_TYPE_LCD);
2370 	fixture.adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 1, 4);
2371 
2372 	amdgpu_dm_update_cacp_caps(fixture.aconnector);
2373 
2374 	KUNIT_EXPECT_FALSE(test, fixture.link->panel_config.cacp.cacp_supported);
2375 }
2376 
2377 /* Tests for amdgpu_dm_set_panel_type() */
2378 
2379 struct dm_panel_type_fixture {
2380 	struct amdgpu_device *adev;
2381 	struct drm_device *drm;
2382 	struct amdgpu_dm_connector *aconnector;
2383 	struct dc_link *link;
2384 	struct dc_sink *sink;
2385 };
2386 
2387 static void setup_panel_type_fixture(struct kunit *test,
2388 				     struct dm_panel_type_fixture *fixture)
2389 {
2390 	struct device *dev;
2391 
2392 	dev = drm_kunit_helper_alloc_device(test);
2393 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
2394 
2395 	fixture->drm = __drm_kunit_helper_alloc_drm_device(test, dev,
2396 							   sizeof(*fixture->adev),
2397 							   offsetof(struct amdgpu_device, ddev),
2398 							   DRIVER_MODESET);
2399 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->drm);
2400 	fixture->adev = drm_to_adev(fixture->drm);
2401 
2402 	fixture->aconnector = drmm_kzalloc(fixture->drm, sizeof(*fixture->aconnector),
2403 					   GFP_KERNEL);
2404 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->aconnector);
2405 	fixture->link = kunit_kzalloc(test, sizeof(*fixture->link), GFP_KERNEL);
2406 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->link);
2407 	fixture->sink = kunit_kzalloc(test, sizeof(*fixture->sink), GFP_KERNEL);
2408 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fixture->sink);
2409 
2410 	fixture->aconnector->dc_link = fixture->link;
2411 	drmm_connector_init(fixture->drm, &fixture->aconnector->base,
2412 			    &dm_test_connector_funcs, DRM_MODE_CONNECTOR_eDP,
2413 			    NULL);
2414 }
2415 
2416 /**
2417  * dm_test_set_panel_type_vsdb_oled - Test VSDB OLED maps to PANEL_TYPE_OLED
2418  * @test: The KUnit test context
2419  */
2420 static void dm_test_set_panel_type_vsdb_oled(struct kunit *test)
2421 {
2422 	struct dm_panel_type_fixture fixture = {};
2423 
2424 	setup_panel_type_fixture(test, &fixture);
2425 	fixture.aconnector->base.display_info.amd_vsdb.panel_type =
2426 		AMD_VSDB_PANEL_TYPE_OLED;
2427 
2428 	amdgpu_dm_set_panel_type(fixture.aconnector);
2429 
2430 	KUNIT_EXPECT_EQ(test, (int)fixture.link->panel_type,
2431 			(int)PANEL_TYPE_OLED);
2432 }
2433 
2434 /**
2435  * dm_test_set_panel_type_vsdb_miniled - Test VSDB MINILED maps to PANEL_TYPE_MINILED
2436  * @test: The KUnit test context
2437  */
2438 static void dm_test_set_panel_type_vsdb_miniled(struct kunit *test)
2439 {
2440 	struct dm_panel_type_fixture fixture = {};
2441 
2442 	setup_panel_type_fixture(test, &fixture);
2443 	fixture.aconnector->base.display_info.amd_vsdb.panel_type =
2444 		AMD_VSDB_PANEL_TYPE_MINILED;
2445 
2446 	amdgpu_dm_set_panel_type(fixture.aconnector);
2447 
2448 	KUNIT_EXPECT_EQ(test, (int)fixture.link->panel_type,
2449 			(int)PANEL_TYPE_MINILED);
2450 }
2451 
2452 /**
2453  * dm_test_set_panel_type_dpcd_oled - Test DPCD oled bit maps to PANEL_TYPE_OLED
2454  * @test: The KUnit test context
2455  */
2456 static void dm_test_set_panel_type_dpcd_oled(struct kunit *test)
2457 {
2458 	struct dm_panel_type_fixture fixture = {};
2459 
2460 	setup_panel_type_fixture(test, &fixture);
2461 	fixture.link->dpcd_sink_ext_caps.bits.oled = 1;
2462 
2463 	amdgpu_dm_set_panel_type(fixture.aconnector);
2464 
2465 	KUNIT_EXPECT_EQ(test, (int)fixture.link->panel_type,
2466 			(int)PANEL_TYPE_OLED);
2467 }
2468 
2469 /**
2470  * dm_test_set_panel_type_dpcd_miniled - Test DPCD miniled bit maps to PANEL_TYPE_MINILED
2471  * @test: The KUnit test context
2472  */
2473 static void dm_test_set_panel_type_dpcd_miniled(struct kunit *test)
2474 {
2475 	struct dm_panel_type_fixture fixture = {};
2476 
2477 	setup_panel_type_fixture(test, &fixture);
2478 	fixture.link->dpcd_sink_ext_caps.bits.miniled = 1;
2479 
2480 	amdgpu_dm_set_panel_type(fixture.aconnector);
2481 
2482 	KUNIT_EXPECT_EQ(test, (int)fixture.link->panel_type,
2483 			(int)PANEL_TYPE_MINILED);
2484 }
2485 
2486 /**
2487  * dm_test_set_panel_type_did_oled - Test DID OLED maps to PANEL_TYPE_OLED
2488  * @test: The KUnit test context
2489  *
2490  * When VSDB and DPCD do not identify the panel, a DID panel type of
2491  * DRM_MODE_PANEL_TYPE_OLED must map to PANEL_TYPE_OLED.
2492  */
2493 static void dm_test_set_panel_type_did_oled(struct kunit *test)
2494 {
2495 	struct dm_panel_type_fixture fixture = {};
2496 
2497 	setup_panel_type_fixture(test, &fixture);
2498 	fixture.aconnector->base.display_info.panel_type =
2499 		DRM_MODE_PANEL_TYPE_OLED;
2500 
2501 	amdgpu_dm_set_panel_type(fixture.aconnector);
2502 
2503 	KUNIT_EXPECT_EQ(test, (int)fixture.link->panel_type,
2504 			(int)PANEL_TYPE_OLED);
2505 }
2506 
2507 /**
2508  * dm_test_set_panel_type_did_lcd - Test DID LCD maps to PANEL_TYPE_LCD
2509  * @test: The KUnit test context
2510  *
2511  * When VSDB and DPCD do not identify the panel, a DID panel type of
2512  * DRM_MODE_PANEL_TYPE_LCD must map to PANEL_TYPE_LCD.
2513  */
2514 static void dm_test_set_panel_type_did_lcd(struct kunit *test)
2515 {
2516 	struct dm_panel_type_fixture fixture = {};
2517 
2518 	setup_panel_type_fixture(test, &fixture);
2519 	fixture.aconnector->base.display_info.panel_type =
2520 		DRM_MODE_PANEL_TYPE_LCD;
2521 
2522 	amdgpu_dm_set_panel_type(fixture.aconnector);
2523 
2524 	KUNIT_EXPECT_EQ(test, (int)fixture.link->panel_type,
2525 			(int)PANEL_TYPE_LCD);
2526 }
2527 
2528 /**
2529  * dm_test_set_panel_type_vendor_lum_heuristic - Test vendor luminance heuristic maps to MINILED
2530  * @test: The KUnit test context
2531  *
2532  * A panel from the specific vendor whose first luminance range is at least
2533  * 1.5x the second is treated as a mini-LED panel.
2534  */
2535 static void dm_test_set_panel_type_vendor_lum_heuristic(struct kunit *test)
2536 {
2537 	struct dm_panel_type_fixture fixture = {};
2538 	struct drm_amd_vsdb_info *vsdb;
2539 
2540 	setup_panel_type_fixture(test, &fixture);
2541 	fixture.link->local_sink = fixture.sink;
2542 	fixture.sink->edid_caps.manufacturer_id = DDC_MANUFACTURERNAME_SAMSUNG;
2543 
2544 	vsdb = &fixture.aconnector->base.display_info.amd_vsdb;
2545 	vsdb->version = 1;
2546 	vsdb->luminance_range1.max_luminance = 3000;
2547 	vsdb->luminance_range2.max_luminance = 1000;
2548 
2549 	amdgpu_dm_set_panel_type(fixture.aconnector);
2550 
2551 	KUNIT_EXPECT_EQ(test, (int)fixture.link->panel_type,
2552 			(int)PANEL_TYPE_MINILED);
2553 }
2554 
2555 /**
2556  * dm_test_set_panel_type_defaults_to_lcd - Test undetermined panel defaults to LCD
2557  * @test: The KUnit test context
2558  *
2559  * When no source identifies the panel, the type now defaults to
2560  * PANEL_TYPE_LCD instead of remaining PANEL_TYPE_NONE.
2561  */
2562 static void dm_test_set_panel_type_defaults_to_lcd(struct kunit *test)
2563 {
2564 	struct dm_panel_type_fixture fixture = {};
2565 
2566 	setup_panel_type_fixture(test, &fixture);
2567 
2568 	amdgpu_dm_set_panel_type(fixture.aconnector);
2569 
2570 	KUNIT_EXPECT_EQ(test, (int)fixture.link->panel_type,
2571 			(int)PANEL_TYPE_LCD);
2572 }
2573 
2574 /* Tests for update_subconnector_property() */
2575 
2576 /**
2577  * dm_test_update_subconnector_dp_with_sink - Test subconnector property is set
2578  * from the dongle type for a DisplayPort connector with a sink
2579  * @test: The KUnit test context
2580  */
2581 static void dm_test_update_subconnector_dp_with_sink(struct kunit *test)
2582 {
2583 	struct device *dev;
2584 	struct drm_device *drm;
2585 	struct amdgpu_dm_connector *aconnector;
2586 	struct dc_link *link;
2587 	uint64_t val = 0;
2588 
2589 	dev = drm_kunit_helper_alloc_device(test);
2590 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
2591 
2592 	drm = __drm_kunit_helper_alloc_drm_device(test, dev,
2593 						   sizeof(*drm), 0,
2594 						   DRIVER_MODESET);
2595 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
2596 
2597 	aconnector = drmm_kzalloc(drm, sizeof(*aconnector), GFP_KERNEL);
2598 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2599 	link = drmm_kzalloc(drm, sizeof(*link), GFP_KERNEL);
2600 	KUNIT_ASSERT_NOT_NULL(test, link);
2601 
2602 	drmm_connector_init(drm, &aconnector->base, &dm_test_connector_funcs,
2603 			    DRM_MODE_CONNECTOR_DisplayPort, NULL);
2604 	drm_connector_attach_dp_subconnector_property(&aconnector->base);
2605 
2606 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
2607 	aconnector->dc_link = link;
2608 	/* Any non-NULL sink enables dongle-type resolution */
2609 	aconnector->dc_sink = kunit_kzalloc(test, sizeof(*aconnector->dc_sink), GFP_KERNEL);
2610 	KUNIT_ASSERT_NOT_NULL(test, aconnector->dc_sink);
2611 
2612 	update_subconnector_property(aconnector);
2613 
2614 	KUNIT_EXPECT_EQ(test, drm_object_property_get_value(&aconnector->base.base,
2615 				aconnector->base.dev->mode_config.dp_subconnector_property,
2616 				&val), 0);
2617 	KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SUBCONNECTOR_VGA);
2618 }
2619 
2620 /**
2621  * dm_test_update_subconnector_dp_no_sink - Test subconnector property stays
2622  * unknown for a DisplayPort connector without a sink
2623  * @test: The KUnit test context
2624  */
2625 static void dm_test_update_subconnector_dp_no_sink(struct kunit *test)
2626 {
2627 	struct device *dev;
2628 	struct drm_device *drm;
2629 	struct amdgpu_dm_connector *aconnector;
2630 	struct dc_link *link;
2631 	uint64_t val = 0;
2632 
2633 	dev = drm_kunit_helper_alloc_device(test);
2634 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
2635 
2636 	drm = __drm_kunit_helper_alloc_drm_device(test, dev,
2637 						   sizeof(*drm), 0,
2638 						   DRIVER_MODESET);
2639 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
2640 
2641 	aconnector = drmm_kzalloc(drm, sizeof(*aconnector), GFP_KERNEL);
2642 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2643 	link = drmm_kzalloc(drm, sizeof(*link), GFP_KERNEL);
2644 	KUNIT_ASSERT_NOT_NULL(test, link);
2645 
2646 	drmm_connector_init(drm, &aconnector->base, &dm_test_connector_funcs,
2647 			    DRM_MODE_CONNECTOR_DisplayPort, NULL);
2648 	drm_connector_attach_dp_subconnector_property(&aconnector->base);
2649 
2650 	/* Dongle type is set, but no sink means it must not be consulted */
2651 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_HDMI_CONVERTER;
2652 	aconnector->dc_link = link;
2653 	aconnector->dc_sink = NULL;
2654 
2655 	update_subconnector_property(aconnector);
2656 
2657 	KUNIT_EXPECT_EQ(test, drm_object_property_get_value(&aconnector->base.base,
2658 				aconnector->base.dev->mode_config.dp_subconnector_property,
2659 				&val), 0);
2660 	KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SUBCONNECTOR_Unknown);
2661 }
2662 
2663 /**
2664  * dm_test_update_subconnector_non_dp_noop - Test non-DisplayPort connector is
2665  * left untouched (early return)
2666  * @test: The KUnit test context
2667  */
2668 static void dm_test_update_subconnector_non_dp_noop(struct kunit *test)
2669 {
2670 	struct device *dev;
2671 	struct drm_device *drm;
2672 	struct amdgpu_dm_connector *aconnector;
2673 	struct dc_link *link;
2674 	uint64_t val = 0;
2675 
2676 	dev = drm_kunit_helper_alloc_device(test);
2677 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
2678 
2679 	drm = __drm_kunit_helper_alloc_drm_device(test, dev,
2680 						   sizeof(*drm), 0,
2681 						   DRIVER_MODESET);
2682 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
2683 
2684 	aconnector = drmm_kzalloc(drm, sizeof(*aconnector), GFP_KERNEL);
2685 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2686 	link = drmm_kzalloc(drm, sizeof(*link), GFP_KERNEL);
2687 	KUNIT_ASSERT_NOT_NULL(test, link);
2688 
2689 	drmm_connector_init(drm, &aconnector->base, &dm_test_connector_funcs,
2690 			    DRM_MODE_CONNECTOR_HDMIA, NULL);
2691 	drm_connector_attach_dp_subconnector_property(&aconnector->base);
2692 
2693 	/* Pre-seed the property to a non-default value */
2694 	drm_object_property_set_value(&aconnector->base.base,
2695 			aconnector->base.dev->mode_config.dp_subconnector_property,
2696 			DRM_MODE_SUBCONNECTOR_VGA);
2697 
2698 	link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_HDMI_CONVERTER;
2699 	aconnector->dc_link = link;
2700 	aconnector->dc_sink = drmm_kzalloc(drm, sizeof(*aconnector->dc_sink), GFP_KERNEL);
2701 	KUNIT_ASSERT_NOT_NULL(test, aconnector->dc_sink);
2702 
2703 	update_subconnector_property(aconnector);
2704 
2705 	/* Non-DP connector: value must remain what we seeded */
2706 	KUNIT_EXPECT_EQ(test, drm_object_property_get_value(&aconnector->base.base,
2707 				aconnector->base.dev->mode_config.dp_subconnector_property,
2708 				&val), 0);
2709 	KUNIT_EXPECT_EQ(test, (int)val, (int)DRM_MODE_SUBCONNECTOR_VGA);
2710 }
2711 
2712 /* Tests for amdgpu_dm_fbc_init() */
2713 
2714 /*
2715  * Build an amdgpu_dm_connector wired to a kunit-allocated amdgpu_device so
2716  * that drm_to_adev() and to_amdgpu_dm_connector() resolve correctly, with a
2717  * dc, dc_link and an empty modes list ready for amdgpu_dm_fbc_init().
2718  */
2719 struct dm_test_fbc_ctx {
2720 	struct amdgpu_device *adev;
2721 	struct amdgpu_dm_connector *aconnector;
2722 	struct dc *dc;
2723 	struct dc_link *link;
2724 };
2725 
2726 static struct dm_test_fbc_ctx *dm_test_fbc_ctx_alloc(struct kunit *test)
2727 {
2728 	struct dm_test_fbc_ctx *ctx;
2729 
2730 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
2731 	KUNIT_ASSERT_NOT_NULL(test, ctx);
2732 
2733 	ctx->adev = kunit_kzalloc(test, sizeof(*ctx->adev), GFP_KERNEL);
2734 	KUNIT_ASSERT_NOT_NULL(test, ctx->adev);
2735 	ctx->aconnector = kunit_kzalloc(test, sizeof(*ctx->aconnector), GFP_KERNEL);
2736 	KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
2737 	ctx->dc = kunit_kzalloc(test, sizeof(*ctx->dc), GFP_KERNEL);
2738 	KUNIT_ASSERT_NOT_NULL(test, ctx->dc);
2739 	ctx->link = kunit_kzalloc(test, sizeof(*ctx->link), GFP_KERNEL);
2740 	KUNIT_ASSERT_NOT_NULL(test, ctx->link);
2741 
2742 	ctx->aconnector->base.dev = &ctx->adev->ddev;
2743 	INIT_LIST_HEAD(&ctx->aconnector->base.modes);
2744 	ctx->adev->dm.dc = ctx->dc;
2745 	ctx->aconnector->dc_link = ctx->link;
2746 
2747 	/* Default to the fully-enabled path so each test only flips one knob */
2748 	ctx->link->connector_signal = SIGNAL_TYPE_EDP;
2749 	ctx->dc->fbc_compressor =
2750 		(struct compressor *)kunit_kzalloc(test, sizeof(void *), GFP_KERNEL);
2751 	KUNIT_ASSERT_NOT_NULL(test, ctx->dc->fbc_compressor);
2752 
2753 	return ctx;
2754 }
2755 
2756 /**
2757  * dm_test_fbc_init_no_compressor - Test fbc_init is a no-op without a compressor
2758  * @test: The KUnit test context
2759  */
2760 static void dm_test_fbc_init_no_compressor(struct kunit *test)
2761 {
2762 	struct dm_test_fbc_ctx *ctx = dm_test_fbc_ctx_alloc(test);
2763 
2764 	ctx->dc->fbc_compressor = NULL;
2765 
2766 	amdgpu_dm_fbc_init(&ctx->aconnector->base);
2767 
2768 	KUNIT_EXPECT_NULL(test, ctx->adev->dm.compressor.bo_ptr);
2769 }
2770 
2771 /**
2772  * dm_test_fbc_init_non_edp - Test fbc_init is a no-op for non-eDP links
2773  * @test: The KUnit test context
2774  */
2775 static void dm_test_fbc_init_non_edp(struct kunit *test)
2776 {
2777 	struct dm_test_fbc_ctx *ctx = dm_test_fbc_ctx_alloc(test);
2778 
2779 	ctx->link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
2780 
2781 	amdgpu_dm_fbc_init(&ctx->aconnector->base);
2782 
2783 	KUNIT_EXPECT_NULL(test, ctx->adev->dm.compressor.bo_ptr);
2784 }
2785 
2786 /**
2787  * dm_test_fbc_init_already_allocated - Test fbc_init keeps an existing buffer
2788  * @test: The KUnit test context
2789  */
2790 static void dm_test_fbc_init_already_allocated(struct kunit *test)
2791 {
2792 	struct dm_test_fbc_ctx *ctx = dm_test_fbc_ctx_alloc(test);
2793 	struct amdgpu_bo *existing;
2794 
2795 	existing = kunit_kzalloc(test, sizeof(void *), GFP_KERNEL);
2796 	KUNIT_ASSERT_NOT_NULL(test, existing);
2797 	ctx->adev->dm.compressor.bo_ptr = existing;
2798 
2799 	amdgpu_dm_fbc_init(&ctx->aconnector->base);
2800 
2801 	/* Buffer already present → left untouched, no reallocation */
2802 	KUNIT_EXPECT_PTR_EQ(test, ctx->adev->dm.compressor.bo_ptr, existing);
2803 }
2804 
2805 /**
2806  * dm_test_fbc_init_no_modes - Test fbc_init skips allocation with no modes
2807  * @test: The KUnit test context
2808  */
2809 static void dm_test_fbc_init_no_modes(struct kunit *test)
2810 {
2811 	struct dm_test_fbc_ctx *ctx = dm_test_fbc_ctx_alloc(test);
2812 
2813 	/* All prerequisites met but the modes list is empty → max_size 0 */
2814 	amdgpu_dm_fbc_init(&ctx->aconnector->base);
2815 
2816 	KUNIT_EXPECT_NULL(test, ctx->adev->dm.compressor.bo_ptr);
2817 }
2818 
2819 /* Tests for amdgpu_dm_detect_mst_link_for_all_connectors() */
2820 
2821 /* Allocate a bare drm_device suitable for registering connectors against. */
2822 static struct drm_device *dm_test_alloc_drm(struct kunit *test)
2823 {
2824 	struct device *dev;
2825 	struct drm_device *drm;
2826 
2827 	dev = drm_kunit_helper_alloc_device(test);
2828 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
2829 
2830 	drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0,
2831 						  DRIVER_MODESET);
2832 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
2833 
2834 	return drm;
2835 }
2836 
2837 /*
2838  * Allocate an amdgpu_dm_connector and register its embedded drm_connector with
2839  * @drm so that drm_for_each_connector_iter() and to_amdgpu_dm_connector() both
2840  * resolve to it.
2841  */
2842 static struct amdgpu_dm_connector *dm_test_add_connector(struct kunit *test,
2843 		struct drm_device *drm, int connector_type)
2844 {
2845 	struct amdgpu_dm_connector *aconnector;
2846 
2847 	aconnector = drmm_kzalloc(drm, sizeof(*aconnector), GFP_KERNEL);
2848 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
2849 
2850 	KUNIT_ASSERT_EQ(test,
2851 		drmm_connector_init(drm, &aconnector->base,
2852 				    &dm_test_connector_funcs, connector_type,
2853 				    NULL), 0);
2854 
2855 	return aconnector;
2856 }
2857 
2858 /**
2859  * dm_test_detect_mst_no_connectors - Test the no-op path on an empty device
2860  * @test: The KUnit test context
2861  */
2862 static void dm_test_detect_mst_no_connectors(struct kunit *test)
2863 {
2864 	struct drm_device *drm = dm_test_alloc_drm(test);
2865 
2866 	/* No connectors registered → iteration body never runs */
2867 	KUNIT_EXPECT_EQ(test,
2868 		amdgpu_dm_detect_mst_link_for_all_connectors(drm), 0);
2869 }
2870 
2871 /**
2872  * dm_test_detect_mst_skips_writeback - Test writeback connectors are skipped
2873  * @test: The KUnit test context
2874  *
2875  * A writeback connector is hit by the early ``continue`` before its dc_link is
2876  * ever dereferenced, so leaving dc_link NULL must not crash.
2877  */
2878 static void dm_test_detect_mst_skips_writeback(struct kunit *test)
2879 {
2880 	struct drm_device *drm = dm_test_alloc_drm(test);
2881 	struct amdgpu_dm_connector *aconnector;
2882 
2883 	aconnector = dm_test_add_connector(test, drm,
2884 					   DRM_MODE_CONNECTOR_WRITEBACK);
2885 	/* dc_link intentionally left NULL: it must not be touched */
2886 	aconnector->dc_link = NULL;
2887 
2888 	KUNIT_EXPECT_EQ(test,
2889 		amdgpu_dm_detect_mst_link_for_all_connectors(drm), 0);
2890 }
2891 
2892 /**
2893  * dm_test_detect_mst_non_mst_link - Test a non-MST link starts no topology
2894  * @test: The KUnit test context
2895  */
2896 static void dm_test_detect_mst_non_mst_link(struct kunit *test)
2897 {
2898 	struct drm_device *drm = dm_test_alloc_drm(test);
2899 	struct amdgpu_dm_connector *aconnector;
2900 	struct dc_link *link;
2901 
2902 	aconnector = dm_test_add_connector(test, drm,
2903 					   DRM_MODE_CONNECTOR_DisplayPort);
2904 	link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
2905 	KUNIT_ASSERT_NOT_NULL(test, link);
2906 
2907 	/* Not an MST branch → the topology manager is never started */
2908 	link->type = dc_connection_single;
2909 	aconnector->dc_link = link;
2910 
2911 	KUNIT_EXPECT_EQ(test,
2912 		amdgpu_dm_detect_mst_link_for_all_connectors(drm), 0);
2913 }
2914 
2915 /**
2916  * dm_test_detect_mst_branch_without_aux - Test an MST branch with no aux is
2917  * skipped
2918  * @test: The KUnit test context
2919  *
2920  * The condition short-circuits on a NULL mst_mgr.aux, so the real
2921  * drm_dp_mst_topology_mgr_set_mst() path is never reached.
2922  */
2923 static void dm_test_detect_mst_branch_without_aux(struct kunit *test)
2924 {
2925 	struct drm_device *drm = dm_test_alloc_drm(test);
2926 	struct amdgpu_dm_connector *aconnector;
2927 	struct dc_link *link;
2928 
2929 	aconnector = dm_test_add_connector(test, drm,
2930 					   DRM_MODE_CONNECTOR_DisplayPort);
2931 	link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
2932 	KUNIT_ASSERT_NOT_NULL(test, link);
2933 
2934 	link->type = dc_connection_mst_branch;
2935 	aconnector->dc_link = link;
2936 	/* mst_mgr.aux is NULL (kzalloc) → second half of the && is false */
2937 	KUNIT_ASSERT_NULL(test, aconnector->mst_mgr.aux);
2938 
2939 	KUNIT_EXPECT_EQ(test,
2940 		amdgpu_dm_detect_mst_link_for_all_connectors(drm), 0);
2941 }
2942 
2943 /* Tests for amdgpu_dm_find_first_crtc_matching_connector() */
2944 
2945 /*
2946  * Build a minimal drm_atomic_commit holding @count connector slots. The
2947  * function under test only reads num_connector, connectors[i].ptr and
2948  * connectors[i].new_state, so a hand-rolled state is sufficient.
2949  */
2950 static struct drm_atomic_commit *
2951 dm_test_alloc_atomic_state(struct kunit *test, int count)
2952 {
2953 	struct drm_atomic_commit *state;
2954 
2955 	state = kunit_kzalloc(test, sizeof(*state), GFP_KERNEL);
2956 	KUNIT_ASSERT_NOT_NULL(test, state);
2957 
2958 	state->num_connector = count;
2959 	if (count) {
2960 		state->connectors = kunit_kcalloc(test, count,
2961 						  sizeof(*state->connectors),
2962 						  GFP_KERNEL);
2963 		KUNIT_ASSERT_NOT_NULL(test, state->connectors);
2964 	}
2965 
2966 	return state;
2967 }
2968 
2969 /**
2970  * dm_test_find_first_crtc_match - Test find_first_crtc returns matching connector
2971  * @test: The KUnit test context
2972  */
2973 static void dm_test_find_first_crtc_match(struct kunit *test)
2974 {
2975 	struct drm_atomic_commit *state = dm_test_alloc_atomic_state(test, 1);
2976 	struct drm_connector *connector;
2977 	struct drm_connector_state *con_state;
2978 	struct drm_crtc *crtc;
2979 
2980 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
2981 	KUNIT_ASSERT_NOT_NULL(test, connector);
2982 	con_state = kunit_kzalloc(test, sizeof(*con_state), GFP_KERNEL);
2983 	KUNIT_ASSERT_NOT_NULL(test, con_state);
2984 	crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
2985 	KUNIT_ASSERT_NOT_NULL(test, crtc);
2986 
2987 	con_state->crtc = crtc;
2988 	state->connectors[0].ptr = connector;
2989 	state->connectors[0].new_state = con_state;
2990 
2991 	KUNIT_EXPECT_PTR_EQ(test,
2992 		amdgpu_dm_find_first_crtc_matching_connector(state, crtc),
2993 		connector);
2994 }
2995 
2996 /**
2997  * dm_test_find_first_crtc_no_match - Test find_first_crtc returns NULL when no crtc matches
2998  * @test: The KUnit test context
2999  */
3000 static void dm_test_find_first_crtc_no_match(struct kunit *test)
3001 {
3002 	struct drm_atomic_commit *state = dm_test_alloc_atomic_state(test, 1);
3003 	struct drm_connector *connector;
3004 	struct drm_connector_state *con_state;
3005 	struct drm_crtc *crtc;
3006 	struct drm_crtc *other_crtc;
3007 
3008 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
3009 	KUNIT_ASSERT_NOT_NULL(test, connector);
3010 	con_state = kunit_kzalloc(test, sizeof(*con_state), GFP_KERNEL);
3011 	KUNIT_ASSERT_NOT_NULL(test, con_state);
3012 	crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
3013 	KUNIT_ASSERT_NOT_NULL(test, crtc);
3014 	other_crtc = kunit_kzalloc(test, sizeof(*other_crtc), GFP_KERNEL);
3015 	KUNIT_ASSERT_NOT_NULL(test, other_crtc);
3016 
3017 	con_state->crtc = other_crtc;
3018 	state->connectors[0].ptr = connector;
3019 	state->connectors[0].new_state = con_state;
3020 
3021 	KUNIT_EXPECT_NULL(test,
3022 		amdgpu_dm_find_first_crtc_matching_connector(state, crtc));
3023 }
3024 
3025 /**
3026  * dm_test_find_first_crtc_empty_state - Test find_first_crtc returns NULL with no connectors
3027  * @test: The KUnit test context
3028  */
3029 static void dm_test_find_first_crtc_empty_state(struct kunit *test)
3030 {
3031 	struct drm_atomic_commit *state = dm_test_alloc_atomic_state(test, 0);
3032 	struct drm_crtc *crtc;
3033 
3034 	crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
3035 	KUNIT_ASSERT_NOT_NULL(test, crtc);
3036 
3037 	KUNIT_EXPECT_NULL(test,
3038 		amdgpu_dm_find_first_crtc_matching_connector(state, crtc));
3039 }
3040 
3041 /**
3042  * dm_test_find_first_crtc_skips_null_ptr - Test find_first_crtc skips empty connector slots
3043  * @test: The KUnit test context
3044  */
3045 static void dm_test_find_first_crtc_skips_null_ptr(struct kunit *test)
3046 {
3047 	struct drm_atomic_commit *state = dm_test_alloc_atomic_state(test, 2);
3048 	struct drm_connector *connector;
3049 	struct drm_connector_state *con_state;
3050 	struct drm_crtc *crtc;
3051 
3052 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
3053 	KUNIT_ASSERT_NOT_NULL(test, connector);
3054 	con_state = kunit_kzalloc(test, sizeof(*con_state), GFP_KERNEL);
3055 	KUNIT_ASSERT_NOT_NULL(test, con_state);
3056 	crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
3057 	KUNIT_ASSERT_NOT_NULL(test, crtc);
3058 
3059 	/* Slot 0 has no connector (ptr == NULL) and must be skipped. */
3060 	con_state->crtc = crtc;
3061 	state->connectors[1].ptr = connector;
3062 	state->connectors[1].new_state = con_state;
3063 
3064 	KUNIT_EXPECT_PTR_EQ(test,
3065 		amdgpu_dm_find_first_crtc_matching_connector(state, crtc),
3066 		connector);
3067 }
3068 
3069 /**
3070  * dm_test_find_first_crtc_returns_first - Test find_first_crtc returns the first match
3071  * @test: The KUnit test context
3072  */
3073 static void dm_test_find_first_crtc_returns_first(struct kunit *test)
3074 {
3075 	struct drm_atomic_commit *state = dm_test_alloc_atomic_state(test, 2);
3076 	struct drm_connector *first;
3077 	struct drm_connector *second;
3078 	struct drm_connector_state *first_state;
3079 	struct drm_connector_state *second_state;
3080 	struct drm_crtc *crtc;
3081 
3082 	first = kunit_kzalloc(test, sizeof(*first), GFP_KERNEL);
3083 	KUNIT_ASSERT_NOT_NULL(test, first);
3084 	second = kunit_kzalloc(test, sizeof(*second), GFP_KERNEL);
3085 	KUNIT_ASSERT_NOT_NULL(test, second);
3086 	first_state = kunit_kzalloc(test, sizeof(*first_state), GFP_KERNEL);
3087 	KUNIT_ASSERT_NOT_NULL(test, first_state);
3088 	second_state = kunit_kzalloc(test, sizeof(*second_state), GFP_KERNEL);
3089 	KUNIT_ASSERT_NOT_NULL(test, second_state);
3090 	crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
3091 	KUNIT_ASSERT_NOT_NULL(test, crtc);
3092 
3093 	/* Both connectors target the same crtc; the first one must win. */
3094 	first_state->crtc = crtc;
3095 	second_state->crtc = crtc;
3096 	state->connectors[0].ptr = first;
3097 	state->connectors[0].new_state = first_state;
3098 	state->connectors[1].ptr = second;
3099 	state->connectors[1].new_state = second_state;
3100 
3101 	KUNIT_EXPECT_PTR_EQ(test,
3102 		amdgpu_dm_find_first_crtc_matching_connector(state, crtc),
3103 		first);
3104 }
3105 
3106 /* Tests for amdgpu_dm_set_panel_type() */
3107 
3108 /*
3109  * Build an amdgpu_dm_connector registered against a real kunit drm_device that
3110  * is embedded in an amdgpu_device, so drm_to_adev()/adev_to_drm() resolve and
3111  * the panel_type property can be created, attached and updated for real.
3112  */
3113 struct dm_test_panel_ctx {
3114 	struct amdgpu_device *adev;
3115 	struct drm_device *drm;
3116 	struct amdgpu_dm_connector *aconnector;
3117 	struct dc_link *link;
3118 	struct drm_display_info *display_info;
3119 };
3120 
3121 static struct dm_test_panel_ctx *dm_test_panel_ctx_alloc(struct kunit *test)
3122 {
3123 	struct dm_test_panel_ctx *ctx;
3124 	struct drm_property *prop;
3125 	struct device *dev;
3126 
3127 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
3128 	KUNIT_ASSERT_NOT_NULL(test, ctx);
3129 
3130 	dev = drm_kunit_helper_alloc_device(test);
3131 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
3132 
3133 	ctx->drm = __drm_kunit_helper_alloc_drm_device(test, dev,
3134 						       sizeof(*ctx->adev),
3135 						       offsetof(struct amdgpu_device, ddev),
3136 						       DRIVER_MODESET);
3137 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->drm);
3138 	ctx->adev = drm_to_adev(ctx->drm);
3139 
3140 	/* The function under test writes through this property. */
3141 	prop = drm_property_create_range(ctx->drm, DRM_MODE_PROP_IMMUTABLE,
3142 					 "panel_type", 0, 0xff);
3143 	KUNIT_ASSERT_NOT_NULL(test, prop);
3144 	ctx->drm->mode_config.panel_type_property = prop;
3145 
3146 	ctx->aconnector = drmm_kzalloc(ctx->drm, sizeof(*ctx->aconnector), GFP_KERNEL);
3147 	KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
3148 	KUNIT_ASSERT_EQ(test,
3149 		drmm_connector_init(ctx->drm, &ctx->aconnector->base,
3150 				    &dm_test_connector_funcs,
3151 				    DRM_MODE_CONNECTOR_eDP, NULL), 0);
3152 	drm_object_attach_property(&ctx->aconnector->base.base, prop,
3153 				   DRM_MODE_PANEL_TYPE_UNKNOWN);
3154 
3155 	ctx->link = drmm_kzalloc(ctx->drm, sizeof(*ctx->link), GFP_KERNEL);
3156 	KUNIT_ASSERT_NOT_NULL(test, ctx->link);
3157 	ctx->aconnector->dc_link = ctx->link;
3158 
3159 	ctx->display_info = &ctx->aconnector->base.display_info;
3160 
3161 	return ctx;
3162 }
3163 
3164 static uint64_t dm_test_panel_prop_value(struct kunit *test,
3165 					 struct dm_test_panel_ctx *ctx)
3166 {
3167 	uint64_t val = ~0ULL;
3168 
3169 	KUNIT_EXPECT_EQ(test,
3170 		drm_object_property_get_value(&ctx->aconnector->base.base,
3171 			ctx->drm->mode_config.panel_type_property, &val), 0);
3172 	return val;
3173 }
3174 
3175 /**
3176  * dm_test_set_panel_type_samsung_miniled - Test Samsung luminance heuristic
3177  * @test: The KUnit test context
3178  *
3179  * When no VSDB or DPCD hint is present, a Samsung sink whose first luminance
3180  * range is at least 1.5x the second is treated as mini-LED.
3181  */
3182 static void dm_test_set_panel_type_samsung_miniled(struct kunit *test)
3183 {
3184 	struct dm_test_panel_ctx *ctx = dm_test_panel_ctx_alloc(test);
3185 	struct dc_sink *sink;
3186 
3187 	sink = kunit_kzalloc(test, sizeof(*sink), GFP_KERNEL);
3188 	KUNIT_ASSERT_NOT_NULL(test, sink);
3189 	sink->edid_caps.manufacturer_id = DDC_MANUFACTURERNAME_SAMSUNG;
3190 	ctx->link->local_sink = sink;
3191 
3192 	ctx->display_info->amd_vsdb.version = 1;
3193 	ctx->display_info->amd_vsdb.luminance_range1.max_luminance = 1500;
3194 	ctx->display_info->amd_vsdb.luminance_range2.max_luminance = 1000;
3195 
3196 	amdgpu_dm_set_panel_type(ctx->aconnector);
3197 
3198 	KUNIT_EXPECT_EQ(test, (int)ctx->link->panel_type, (int)PANEL_TYPE_MINILED);
3199 }
3200 
3201 /**
3202  * dm_test_set_panel_type_samsung_below_threshold - Test Samsung sink below the
3203  * mini-LED luminance threshold falls back to LCD
3204  * @test: The KUnit test context
3205  */
3206 static void dm_test_set_panel_type_samsung_below_threshold(struct kunit *test)
3207 {
3208 	struct dm_test_panel_ctx *ctx = dm_test_panel_ctx_alloc(test);
3209 	struct dc_sink *sink;
3210 
3211 	sink = kunit_kzalloc(test, sizeof(*sink), GFP_KERNEL);
3212 	KUNIT_ASSERT_NOT_NULL(test, sink);
3213 	sink->edid_caps.manufacturer_id = DDC_MANUFACTURERNAME_SAMSUNG;
3214 	ctx->link->local_sink = sink;
3215 
3216 	ctx->display_info->amd_vsdb.version = 1;
3217 	ctx->display_info->amd_vsdb.luminance_range1.max_luminance = 1000;
3218 	ctx->display_info->amd_vsdb.luminance_range2.max_luminance = 1000;
3219 
3220 	amdgpu_dm_set_panel_type(ctx->aconnector);
3221 
3222 	KUNIT_EXPECT_EQ(test, (int)ctx->link->panel_type, (int)PANEL_TYPE_LCD);
3223 }
3224 
3225 /**
3226  * dm_test_set_panel_type_default_lcd - Test default fallback is LCD
3227  * @test: The KUnit test context
3228  *
3229  * With no VSDB, DPCD or DID hints the panel type defaults to LCD.
3230  */
3231 static void dm_test_set_panel_type_default_lcd(struct kunit *test)
3232 {
3233 	struct dm_test_panel_ctx *ctx = dm_test_panel_ctx_alloc(test);
3234 
3235 	amdgpu_dm_set_panel_type(ctx->aconnector);
3236 
3237 	KUNIT_EXPECT_EQ(test, (int)ctx->link->panel_type, (int)PANEL_TYPE_LCD);
3238 	KUNIT_EXPECT_EQ(test, dm_test_panel_prop_value(test, ctx),
3239 			(uint64_t)DRM_MODE_PANEL_TYPE_LCD);
3240 }
3241 
3242 /* Tests for amdgpu_dm_update_cacp_caps() */
3243 
3244 /*
3245  * Build an amdgpu_dm_connector wired to a real kunit drm_device embedded in an
3246  * amdgpu_device, so drm_to_adev() resolves and drm_dbg_kms() has a valid
3247  * device. Defaults are seeded to the fully-supported configuration so each
3248  * test only flips a single knob.
3249  */
3250 struct dm_test_cacp_ctx {
3251 	struct amdgpu_device *adev;
3252 	struct amdgpu_dm_connector *aconnector;
3253 	struct dc_link *link;
3254 };
3255 
3256 static struct dm_test_cacp_ctx *dm_test_cacp_ctx_alloc(struct kunit *test)
3257 {
3258 	struct dm_test_cacp_ctx *ctx;
3259 	struct drm_device *drm;
3260 	struct device *dev;
3261 
3262 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
3263 	KUNIT_ASSERT_NOT_NULL(test, ctx);
3264 
3265 	dev = drm_kunit_helper_alloc_device(test);
3266 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
3267 
3268 	drm = __drm_kunit_helper_alloc_drm_device(test, dev,
3269 						  sizeof(*ctx->adev),
3270 						  offsetof(struct amdgpu_device, ddev),
3271 						  DRIVER_MODESET);
3272 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
3273 	ctx->adev = drm_to_adev(drm);
3274 
3275 	ctx->aconnector = kunit_kzalloc(test, sizeof(*ctx->aconnector), GFP_KERNEL);
3276 	KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
3277 	ctx->aconnector->base.dev = drm;
3278 
3279 	ctx->link = kunit_kzalloc(test, sizeof(*ctx->link), GFP_KERNEL);
3280 	KUNIT_ASSERT_NOT_NULL(test, ctx->link);
3281 	ctx->aconnector->dc_link = ctx->link;
3282 
3283 	/* Fully-supported defaults: new enough DCE, eDP, non-LCD panel. */
3284 	ctx->adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 1, 4);
3285 	ctx->link->connector_signal = SIGNAL_TYPE_EDP;
3286 	ctx->link->panel_type = PANEL_TYPE_OLED;
3287 
3288 	return ctx;
3289 }
3290 
3291 /**
3292  * dm_test_cacp_caps_edp_supported - Test CACP supported on a new eDP panel
3293  * @test: The KUnit test context
3294  */
3295 static void dm_test_cacp_caps_edp_supported(struct kunit *test)
3296 {
3297 	struct dm_test_cacp_ctx *ctx = dm_test_cacp_ctx_alloc(test);
3298 
3299 	amdgpu_dm_update_cacp_caps(ctx->aconnector);
3300 
3301 	KUNIT_EXPECT_TRUE(test, ctx->link->panel_config.cacp.cacp_supported);
3302 }
3303 
3304 /**
3305  * dm_test_cacp_caps_lvds_supported - Test CACP supported on an LVDS panel
3306  * @test: The KUnit test context
3307  */
3308 static void dm_test_cacp_caps_lvds_supported(struct kunit *test)
3309 {
3310 	struct dm_test_cacp_ctx *ctx = dm_test_cacp_ctx_alloc(test);
3311 
3312 	ctx->link->connector_signal = SIGNAL_TYPE_LVDS;
3313 
3314 	amdgpu_dm_update_cacp_caps(ctx->aconnector);
3315 
3316 	KUNIT_EXPECT_TRUE(test, ctx->link->panel_config.cacp.cacp_supported);
3317 }
3318 
3319 /**
3320  * dm_test_cacp_caps_old_ip_unsupported - Test CACP unsupported on old DCE
3321  * @test: The KUnit test context
3322  *
3323  * DCE versions older than 3.1.4 do not support CACP.
3324  */
3325 static void dm_test_cacp_caps_old_ip_unsupported(struct kunit *test)
3326 {
3327 	struct dm_test_cacp_ctx *ctx = dm_test_cacp_ctx_alloc(test);
3328 
3329 	ctx->adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 1, 3);
3330 
3331 	amdgpu_dm_update_cacp_caps(ctx->aconnector);
3332 
3333 	KUNIT_EXPECT_FALSE(test, ctx->link->panel_config.cacp.cacp_supported);
3334 }
3335 
3336 /**
3337  * dm_test_cacp_caps_ip_3_1_6_unsupported - Test CACP unsupported on DCE 3.1.6
3338  * @test: The KUnit test context
3339  *
3340  * DCE 3.1.6 is explicitly excluded even though it is newer than 3.1.4.
3341  */
3342 static void dm_test_cacp_caps_ip_3_1_6_unsupported(struct kunit *test)
3343 {
3344 	struct dm_test_cacp_ctx *ctx = dm_test_cacp_ctx_alloc(test);
3345 
3346 	ctx->adev->ip_versions[DCE_HWIP][0] = IP_VERSION(3, 1, 6);
3347 
3348 	amdgpu_dm_update_cacp_caps(ctx->aconnector);
3349 
3350 	KUNIT_EXPECT_FALSE(test, ctx->link->panel_config.cacp.cacp_supported);
3351 }
3352 
3353 /**
3354  * dm_test_cacp_caps_non_edp_lvds_unsupported - Test CACP unsupported on a
3355  * non-eDP/LVDS signal
3356  * @test: The KUnit test context
3357  */
3358 static void dm_test_cacp_caps_non_edp_lvds_unsupported(struct kunit *test)
3359 {
3360 	struct dm_test_cacp_ctx *ctx = dm_test_cacp_ctx_alloc(test);
3361 
3362 	ctx->link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
3363 
3364 	amdgpu_dm_update_cacp_caps(ctx->aconnector);
3365 
3366 	KUNIT_EXPECT_FALSE(test, ctx->link->panel_config.cacp.cacp_supported);
3367 }
3368 
3369 /**
3370  * dm_test_cacp_caps_lcd_unsupported - Test CACP unsupported on an LCD panel
3371  * @test: The KUnit test context
3372  */
3373 static void dm_test_cacp_caps_lcd_unsupported(struct kunit *test)
3374 {
3375 	struct dm_test_cacp_ctx *ctx = dm_test_cacp_ctx_alloc(test);
3376 
3377 	ctx->link->panel_type = PANEL_TYPE_LCD;
3378 
3379 	amdgpu_dm_update_cacp_caps(ctx->aconnector);
3380 
3381 	KUNIT_EXPECT_FALSE(test, ctx->link->panel_config.cacp.cacp_supported);
3382 }
3383 
3384 /* Tests for fill_stream_properties_from_drm_display_mode() */
3385 
3386 /*
3387  * Build the inputs for fill_stream_properties_from_drm_display_mode(). The
3388  * connector is registered against a real kunit drm_device so that
3389  * to_amdgpu_dm_connector(), connector->display_info and the drm debug helpers
3390  * all resolve. Large structs are heap-allocated to keep the stack small.
3391  *
3392  * The stream signal defaults to DisplayPort so the HDMI infoframe paths are
3393  * skipped, keeping the exercised behaviour deterministic.
3394  */
3395 struct dm_test_fill_ctx {
3396 	struct drm_device *drm;
3397 	struct amdgpu_dm_connector *aconnector;
3398 	struct drm_connector_state *conn_state;
3399 	struct dc_stream_state *stream;
3400 	struct drm_display_mode *mode;
3401 };
3402 
3403 static struct dm_test_fill_ctx *dm_test_fill_ctx_alloc(struct kunit *test)
3404 {
3405 	struct dm_test_fill_ctx *ctx;
3406 	struct device *dev;
3407 
3408 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
3409 	KUNIT_ASSERT_NOT_NULL(test, ctx);
3410 
3411 	dev = drm_kunit_helper_alloc_device(test);
3412 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
3413 
3414 	ctx->drm = __drm_kunit_helper_alloc_drm_device(test, dev,
3415 						       sizeof(*ctx->drm), 0,
3416 						       DRIVER_MODESET);
3417 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->drm);
3418 
3419 	ctx->aconnector = drmm_kzalloc(ctx->drm, sizeof(*ctx->aconnector), GFP_KERNEL);
3420 	KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
3421 	KUNIT_ASSERT_EQ(test,
3422 		drmm_connector_init(ctx->drm, &ctx->aconnector->base,
3423 				    &dm_test_connector_funcs,
3424 				    DRM_MODE_CONNECTOR_DisplayPort, NULL), 0);
3425 
3426 	ctx->conn_state = drmm_kzalloc(ctx->drm, sizeof(*ctx->conn_state), GFP_KERNEL);
3427 	KUNIT_ASSERT_NOT_NULL(test, ctx->conn_state);
3428 	ctx->stream = kunit_kzalloc(test, sizeof(*ctx->stream), GFP_KERNEL);
3429 	KUNIT_ASSERT_NOT_NULL(test, ctx->stream);
3430 	ctx->mode = kunit_kzalloc(test, sizeof(*ctx->mode), GFP_KERNEL);
3431 	KUNIT_ASSERT_NOT_NULL(test, ctx->mode);
3432 
3433 	ctx->stream->signal = SIGNAL_TYPE_DISPLAY_PORT;
3434 
3435 	return ctx;
3436 }
3437 
3438 /**
3439  * dm_test_fill_stream_borders_zeroed - Test the timing borders are cleared
3440  * @test: The KUnit test context
3441  */
3442 static void dm_test_fill_stream_borders_zeroed(struct kunit *test)
3443 {
3444 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3445 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3446 
3447 	/* Pre-seed nonzero borders to prove they get reset. */
3448 	timing->h_border_left = 5;
3449 	timing->h_border_right = 6;
3450 	timing->v_border_top = 7;
3451 	timing->v_border_bottom = 8;
3452 
3453 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3454 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3455 		PIXEL_ENCODING_RGB, false);
3456 
3457 	KUNIT_EXPECT_EQ(test, (int)timing->h_border_left, 0);
3458 	KUNIT_EXPECT_EQ(test, (int)timing->h_border_right, 0);
3459 	KUNIT_EXPECT_EQ(test, (int)timing->v_border_top, 0);
3460 	KUNIT_EXPECT_EQ(test, (int)timing->v_border_bottom, 0);
3461 }
3462 
3463 /**
3464  * dm_test_fill_stream_rgb_defaults - Test the default RGB/sRGB output
3465  * @test: The KUnit test context
3466  *
3467  * A plain DisplayPort sink with no YCbCr color formats produces RGB encoding
3468  * and the sRGB color space, with a predefined sRGB transfer function.
3469  */
3470 static void dm_test_fill_stream_rgb_defaults(struct kunit *test)
3471 {
3472 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3473 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3474 
3475 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3476 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3477 		PIXEL_ENCODING_RGB, false);
3478 
3479 	KUNIT_EXPECT_EQ(test, (int)timing->pixel_encoding, (int)PIXEL_ENCODING_RGB);
3480 	KUNIT_EXPECT_EQ(test, (int)timing->timing_3d_format,
3481 			(int)TIMING_3D_FORMAT_NONE);
3482 	KUNIT_EXPECT_EQ(test, (int)timing->scan_type, (int)SCANNING_TYPE_NODATA);
3483 	KUNIT_EXPECT_EQ(test, (int)ctx->stream->output_color_space,
3484 			(int)COLOR_SPACE_SRGB);
3485 	KUNIT_EXPECT_EQ(test, (int)ctx->stream->out_transfer_func.type,
3486 			(int)TF_TYPE_PREDEFINED);
3487 	KUNIT_EXPECT_EQ(test, (int)ctx->stream->out_transfer_func.tf,
3488 			(int)TRANSFER_FUNCTION_SRGB);
3489 }
3490 
3491 /**
3492  * dm_test_fill_stream_sync_polarity_positive - Test sync polarity from mode flags
3493  * @test: The KUnit test context
3494  */
3495 static void dm_test_fill_stream_sync_polarity_positive(struct kunit *test)
3496 {
3497 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3498 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3499 
3500 	ctx->mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC;
3501 
3502 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3503 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3504 		PIXEL_ENCODING_RGB, false);
3505 
3506 	KUNIT_EXPECT_EQ(test, (int)timing->flags.HSYNC_POSITIVE_POLARITY, 1);
3507 	KUNIT_EXPECT_EQ(test, (int)timing->flags.VSYNC_POSITIVE_POLARITY, 1);
3508 }
3509 
3510 /**
3511  * dm_test_fill_stream_sync_polarity_negative - Test negative sync polarity default
3512  * @test: The KUnit test context
3513  */
3514 static void dm_test_fill_stream_sync_polarity_negative(struct kunit *test)
3515 {
3516 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3517 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3518 
3519 	/* No sync flags set on the mode → polarity stays negative (0). */
3520 	ctx->mode->flags = 0;
3521 
3522 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3523 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3524 		PIXEL_ENCODING_RGB, false);
3525 
3526 	KUNIT_EXPECT_EQ(test, (int)timing->flags.HSYNC_POSITIVE_POLARITY, 0);
3527 	KUNIT_EXPECT_EQ(test, (int)timing->flags.VSYNC_POSITIVE_POLARITY, 0);
3528 }
3529 
3530 /**
3531  * dm_test_fill_stream_inherits_old_stream - Test vic/polarity copied from old stream
3532  * @test: The KUnit test context
3533  *
3534  * When an old stream is supplied its vic and sync polarities are reused instead
3535  * of being derived from the mode.
3536  */
3537 static void dm_test_fill_stream_inherits_old_stream(struct kunit *test)
3538 {
3539 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3540 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3541 	struct dc_stream_state *old_stream;
3542 
3543 	old_stream = kunit_kzalloc(test, sizeof(*old_stream), GFP_KERNEL);
3544 	KUNIT_ASSERT_NOT_NULL(test, old_stream);
3545 	old_stream->timing.vic = 16;
3546 	old_stream->timing.flags.HSYNC_POSITIVE_POLARITY = 1;
3547 	old_stream->timing.flags.VSYNC_POSITIVE_POLARITY = 0;
3548 
3549 	/* Mode flags would force positive polarity if the old stream were ignored. */
3550 	ctx->mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC;
3551 
3552 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3553 		&ctx->aconnector->base, ctx->conn_state, old_stream, 8,
3554 		PIXEL_ENCODING_RGB, false);
3555 
3556 	KUNIT_EXPECT_EQ(test, (int)timing->vic, 16);
3557 	KUNIT_EXPECT_EQ(test, (int)timing->flags.HSYNC_POSITIVE_POLARITY, 1);
3558 	KUNIT_EXPECT_EQ(test, (int)timing->flags.VSYNC_POSITIVE_POLARITY, 0);
3559 }
3560 
3561 /**
3562  * dm_test_fill_stream_timing_from_crtc - Test timing taken from crtc_* fields
3563  * @test: The KUnit test context
3564  *
3565  * Without a freesync video match the function uses the mode's crtc_* timing
3566  * fields and scales the pixel clock to 100Hz units.
3567  */
3568 static void dm_test_fill_stream_timing_from_crtc(struct kunit *test)
3569 {
3570 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3571 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3572 
3573 	ctx->mode->crtc_hdisplay = 1920;
3574 	ctx->mode->crtc_htotal = 2200;
3575 	ctx->mode->crtc_hsync_start = 2008;
3576 	ctx->mode->crtc_hsync_end = 2052;
3577 	ctx->mode->crtc_vdisplay = 1080;
3578 	ctx->mode->crtc_vtotal = 1125;
3579 	ctx->mode->crtc_vsync_start = 1084;
3580 	ctx->mode->crtc_vsync_end = 1089;
3581 	ctx->mode->crtc_clock = 148500;
3582 
3583 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3584 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3585 		PIXEL_ENCODING_RGB, false);
3586 
3587 	KUNIT_EXPECT_EQ(test, (int)timing->h_addressable, 1920);
3588 	KUNIT_EXPECT_EQ(test, (int)timing->h_total, 2200);
3589 	KUNIT_EXPECT_EQ(test, (int)timing->h_sync_width, 44);
3590 	KUNIT_EXPECT_EQ(test, (int)timing->h_front_porch, 88);
3591 	KUNIT_EXPECT_EQ(test, (int)timing->v_addressable, 1080);
3592 	KUNIT_EXPECT_EQ(test, (int)timing->v_total, 1125);
3593 	KUNIT_EXPECT_EQ(test, (int)timing->v_sync_width, 5);
3594 	KUNIT_EXPECT_EQ(test, (int)timing->v_front_porch, 4);
3595 	KUNIT_EXPECT_EQ(test, (int)timing->pix_clk_100hz, 1485000);
3596 }
3597 
3598 /**
3599  * dm_test_fill_stream_color_depth_requested_bpc - Test bpc capping
3600  * @test: The KUnit test context
3601  *
3602  * The requested bpc caps the display bpc and is rounded down to an even value.
3603  */
3604 static void dm_test_fill_stream_color_depth_requested_bpc(struct kunit *test)
3605 {
3606 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3607 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3608 
3609 	ctx->aconnector->base.display_info.bpc = 12;
3610 
3611 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3612 		&ctx->aconnector->base, ctx->conn_state, NULL, 10,
3613 		PIXEL_ENCODING_RGB, false);
3614 
3615 	KUNIT_EXPECT_EQ(test, (int)timing->display_color_depth,
3616 			(int)COLOR_DEPTH_101010);
3617 }
3618 
3619 /**
3620  * dm_test_fill_stream_content_type - Test content type forwarded from state
3621  * @test: The KUnit test context
3622  */
3623 static void dm_test_fill_stream_content_type(struct kunit *test)
3624 {
3625 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3626 
3627 	ctx->conn_state->content_type = DRM_MODE_CONTENT_TYPE_GRAPHICS;
3628 
3629 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3630 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3631 		PIXEL_ENCODING_RGB, false);
3632 
3633 	KUNIT_EXPECT_EQ(test, (int)ctx->stream->content_type,
3634 			(int)DISPLAY_CONTENT_TYPE_GRAPHICS);
3635 }
3636 
3637 /**
3638  * dm_test_fill_stream_aspect_ratio - Test aspect ratio mapped from the mode
3639  * @test: The KUnit test context
3640  */
3641 static void dm_test_fill_stream_aspect_ratio(struct kunit *test)
3642 {
3643 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3644 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3645 
3646 	ctx->mode->picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
3647 
3648 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3649 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3650 		PIXEL_ENCODING_RGB, false);
3651 
3652 	KUNIT_EXPECT_EQ(test, (int)timing->aspect_ratio,
3653 			(int)ASPECT_RATIO_16_9);
3654 }
3655 
3656 /**
3657  * dm_test_fill_stream_encoding_from_caller_ycbcr420 - Test caller-selected 420
3658  * @test: The KUnit test context
3659  *
3660  * The helper no longer derives the pixel encoding from the display info; it
3661  * applies whatever the caller selected. Passing YCbCr420 must be honoured even
3662  * though the DisplayPort sink advertises no YCbCr color formats.
3663  */
3664 static void dm_test_fill_stream_encoding_from_caller_ycbcr420(struct kunit *test)
3665 {
3666 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3667 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3668 
3669 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3670 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3671 		PIXEL_ENCODING_YCBCR420, false);
3672 
3673 	KUNIT_EXPECT_EQ(test, (int)timing->pixel_encoding,
3674 			(int)PIXEL_ENCODING_YCBCR420);
3675 }
3676 
3677 /**
3678  * dm_test_fill_stream_encoding_from_caller_ycbcr422 - Test caller-selected 422
3679  * @test: The KUnit test context
3680  *
3681  * A caller-selected YCbCr422 encoding is applied verbatim.
3682  */
3683 static void dm_test_fill_stream_encoding_from_caller_ycbcr422(struct kunit *test)
3684 {
3685 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3686 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3687 
3688 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3689 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3690 		PIXEL_ENCODING_YCBCR422, false);
3691 
3692 	KUNIT_EXPECT_EQ(test, (int)timing->pixel_encoding,
3693 			(int)PIXEL_ENCODING_YCBCR422);
3694 }
3695 
3696 /**
3697  * dm_test_fill_stream_encoding_from_caller_ycbcr444 - Test caller-selected 444
3698  * @test: The KUnit test context
3699  *
3700  * A caller-selected YCbCr444 encoding is applied verbatim.
3701  */
3702 static void dm_test_fill_stream_encoding_from_caller_ycbcr444(struct kunit *test)
3703 {
3704 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3705 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3706 
3707 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3708 		&ctx->aconnector->base, ctx->conn_state, NULL, 8,
3709 		PIXEL_ENCODING_YCBCR444, false);
3710 
3711 	KUNIT_EXPECT_EQ(test, (int)timing->pixel_encoding,
3712 			(int)PIXEL_ENCODING_YCBCR444);
3713 }
3714 
3715 /**
3716  * dm_test_fill_stream_hdmi_ep_clamps_depth - Test HDMI TMDS depth clamp applied
3717  * @test: The KUnit test context
3718  *
3719  * With is_hdmi_ep set the colour depth is clamped to what the sink's max TMDS
3720  * clock allows: a 10bpc request that exceeds the limit is reduced to 8bpc.
3721  */
3722 static void dm_test_fill_stream_hdmi_ep_clamps_depth(struct kunit *test)
3723 {
3724 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3725 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3726 
3727 	ctx->aconnector->base.display_info.bpc = 10;
3728 	/* 10bpc RGB needs 185625 KHz, over the sink's 160 MHz TMDS limit. */
3729 	ctx->aconnector->base.display_info.max_tmds_clock = 160000;
3730 	ctx->mode->crtc_clock = 148500;
3731 
3732 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3733 		&ctx->aconnector->base, ctx->conn_state, NULL, 10,
3734 		PIXEL_ENCODING_RGB, true);
3735 
3736 	KUNIT_EXPECT_EQ(test, (int)timing->display_color_depth,
3737 			(int)COLOR_DEPTH_888);
3738 }
3739 
3740 /**
3741  * dm_test_fill_stream_non_hdmi_ep_keeps_depth - Test no TMDS clamp off HDMI
3742  * @test: The KUnit test context
3743  *
3744  * With is_hdmi_ep clear the TMDS clamp is skipped, so the same over-limit
3745  * 10bpc request is left untouched. The clamp is HDMI-specific.
3746  */
3747 static void dm_test_fill_stream_non_hdmi_ep_keeps_depth(struct kunit *test)
3748 {
3749 	struct dm_test_fill_ctx *ctx = dm_test_fill_ctx_alloc(test);
3750 	struct dc_crtc_timing *timing = &ctx->stream->timing;
3751 
3752 	ctx->aconnector->base.display_info.bpc = 10;
3753 	ctx->aconnector->base.display_info.max_tmds_clock = 160000;
3754 	ctx->mode->crtc_clock = 148500;
3755 
3756 	fill_stream_properties_from_drm_display_mode(ctx->stream, ctx->mode,
3757 		&ctx->aconnector->base, ctx->conn_state, NULL, 10,
3758 		PIXEL_ENCODING_RGB, false);
3759 
3760 	KUNIT_EXPECT_EQ(test, (int)timing->display_color_depth,
3761 			(int)COLOR_DEPTH_101010);
3762 }
3763 
3764 /* Tests for create_stream_for_sink() */
3765 
3766 /*
3767  * Build the inputs for create_stream_for_sink(). The connector is registered
3768  * against a real kunit drm_device so that to_amdgpu_dm_connector() and the drm
3769  * debug helpers resolve. The DC link carries a zeroed dc_context so that
3770  * dc_create_stream_for_sink() can allocate and construct a stream.
3771  *
3772  * By default no dc_sink is attached, so create_stream_for_sink() builds a fake
3773  * VIRTUAL sink. The VIRTUAL signal keeps the DSC, audio and DP/HDMI infoframe
3774  * paths as no-ops, making the exercised behaviour deterministic.
3775  */
3776 struct dm_test_stream_ctx {
3777 	struct drm_device *drm;
3778 	struct amdgpu_dm_connector *aconnector;
3779 	struct dc_context *dc_ctx;
3780 	struct dc_link *link;
3781 	struct dm_connector_state *dm_state;
3782 	struct drm_display_mode *mode;
3783 };
3784 
3785 static struct dm_test_stream_ctx *dm_test_stream_ctx_alloc(struct kunit *test)
3786 {
3787 	struct dm_test_stream_ctx *ctx;
3788 	struct device *dev;
3789 
3790 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
3791 	KUNIT_ASSERT_NOT_NULL(test, ctx);
3792 
3793 	dev = drm_kunit_helper_alloc_device(test);
3794 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
3795 
3796 	ctx->drm = __drm_kunit_helper_alloc_drm_device(test, dev,
3797 						       sizeof(*ctx->drm), 0,
3798 						       DRIVER_MODESET);
3799 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->drm);
3800 
3801 	ctx->aconnector = drmm_kzalloc(ctx->drm, sizeof(*ctx->aconnector), GFP_KERNEL);
3802 	KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
3803 	KUNIT_ASSERT_EQ(test,
3804 		drmm_connector_init(ctx->drm, &ctx->aconnector->base,
3805 				    &dm_test_connector_funcs,
3806 				    DRM_MODE_CONNECTOR_DisplayPort, NULL), 0);
3807 
3808 	ctx->dc_ctx = kunit_kzalloc(test, sizeof(*ctx->dc_ctx), GFP_KERNEL);
3809 	KUNIT_ASSERT_NOT_NULL(test, ctx->dc_ctx);
3810 
3811 	ctx->link = kunit_kzalloc(test, sizeof(*ctx->link), GFP_KERNEL);
3812 	KUNIT_ASSERT_NOT_NULL(test, ctx->link);
3813 	ctx->link->ctx = ctx->dc_ctx;
3814 	ctx->link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
3815 
3816 	ctx->aconnector->dc_link = ctx->link;
3817 	ctx->aconnector->dc_sink = NULL;
3818 
3819 	ctx->dm_state = kunit_kzalloc(test, sizeof(*ctx->dm_state), GFP_KERNEL);
3820 	KUNIT_ASSERT_NOT_NULL(test, ctx->dm_state);
3821 	ctx->dm_state->scaling = RMX_OFF;
3822 
3823 	ctx->mode = kunit_kzalloc(test, sizeof(*ctx->mode), GFP_KERNEL);
3824 	KUNIT_ASSERT_NOT_NULL(test, ctx->mode);
3825 	ctx->mode->hdisplay = 1920;
3826 	ctx->mode->vdisplay = 1080;
3827 	ctx->mode->clock = 148500;
3828 
3829 	return ctx;
3830 }
3831 
3832 /**
3833  * dm_test_create_stream_fake_sink_success - Test a stream is built from a fake sink
3834  * @test: The KUnit test context
3835  */
3836 static void dm_test_create_stream_fake_sink_success(struct kunit *test)
3837 {
3838 	struct dm_test_stream_ctx *ctx = dm_test_stream_ctx_alloc(test);
3839 	struct dc_stream_state *stream;
3840 
3841 	stream = create_stream_for_sink(&ctx->aconnector->base, ctx->mode,
3842 					ctx->dm_state, NULL, 8,
3843 					PIXEL_ENCODING_RGB, false);
3844 
3845 	KUNIT_ASSERT_NOT_NULL(test, stream);
3846 	dc_stream_release(stream);
3847 }
3848 
3849 /**
3850  * dm_test_create_stream_sets_dm_context - Test dm_stream_context points to aconnector
3851  * @test: The KUnit test context
3852  */
3853 static void dm_test_create_stream_sets_dm_context(struct kunit *test)
3854 {
3855 	struct dm_test_stream_ctx *ctx = dm_test_stream_ctx_alloc(test);
3856 	struct dc_stream_state *stream;
3857 
3858 	stream = create_stream_for_sink(&ctx->aconnector->base, ctx->mode,
3859 					ctx->dm_state, NULL, 8,
3860 					PIXEL_ENCODING_RGB, false);
3861 
3862 	KUNIT_ASSERT_NOT_NULL(test, stream);
3863 	KUNIT_EXPECT_PTR_EQ(test, stream->dm_stream_context, ctx->aconnector);
3864 	dc_stream_release(stream);
3865 }
3866 
3867 /**
3868  * dm_test_create_stream_virtual_signal - Test the fake sink yields a VIRTUAL signal
3869  * @test: The KUnit test context
3870  */
3871 static void dm_test_create_stream_virtual_signal(struct kunit *test)
3872 {
3873 	struct dm_test_stream_ctx *ctx = dm_test_stream_ctx_alloc(test);
3874 	struct dc_stream_state *stream;
3875 
3876 	stream = create_stream_for_sink(&ctx->aconnector->base, ctx->mode,
3877 					ctx->dm_state, NULL, 8,
3878 					PIXEL_ENCODING_RGB, false);
3879 
3880 	KUNIT_ASSERT_NOT_NULL(test, stream);
3881 	KUNIT_EXPECT_EQ(test, (int)stream->signal, (int)SIGNAL_TYPE_VIRTUAL);
3882 	dc_stream_release(stream);
3883 }
3884 
3885 /**
3886  * dm_test_create_stream_scaling_src - Test the source rect follows the mode
3887  * @test: The KUnit test context
3888  *
3889  * With scaling off the full-screen source viewport matches the requested mode.
3890  */
3891 static void dm_test_create_stream_scaling_src(struct kunit *test)
3892 {
3893 	struct dm_test_stream_ctx *ctx = dm_test_stream_ctx_alloc(test);
3894 	struct dc_stream_state *stream;
3895 
3896 	stream = create_stream_for_sink(&ctx->aconnector->base, ctx->mode,
3897 					ctx->dm_state, NULL, 8,
3898 					PIXEL_ENCODING_RGB, false);
3899 
3900 	KUNIT_ASSERT_NOT_NULL(test, stream);
3901 	KUNIT_EXPECT_EQ(test, (int)stream->src.width, 1920);
3902 	KUNIT_EXPECT_EQ(test, (int)stream->src.height, 1080);
3903 	dc_stream_release(stream);
3904 }
3905 
3906 /**
3907  * dm_test_create_stream_existing_sink - Test the existing-sink retain path
3908  * @test: The KUnit test context
3909  *
3910  * When the connector already has a dc_sink, create_stream_for_sink() reuses it
3911  * instead of building a fake sink.
3912  */
3913 static void dm_test_create_stream_existing_sink(struct kunit *test)
3914 {
3915 	struct dm_test_stream_ctx *ctx = dm_test_stream_ctx_alloc(test);
3916 	struct dc_sink_init_data sink_init = { 0 };
3917 	struct dc_stream_state *stream;
3918 	struct dc_sink *sink;
3919 
3920 	sink_init.link = ctx->link;
3921 	sink_init.sink_signal = SIGNAL_TYPE_VIRTUAL;
3922 	sink = dc_sink_create(&sink_init);
3923 	KUNIT_ASSERT_NOT_NULL(test, sink);
3924 	sink->sink_signal = SIGNAL_TYPE_VIRTUAL;
3925 
3926 	ctx->aconnector->dc_sink = sink;
3927 
3928 	stream = create_stream_for_sink(&ctx->aconnector->base, ctx->mode,
3929 					ctx->dm_state, NULL, 8,
3930 					PIXEL_ENCODING_RGB, false);
3931 
3932 	KUNIT_ASSERT_NOT_NULL(test, stream);
3933 	KUNIT_EXPECT_PTR_EQ(test, stream->sink, sink);
3934 
3935 	dc_stream_release(stream);
3936 	dc_sink_release(sink);
3937 }
3938 
3939 /* Tests for amdgpu_dm_connector_detect() */
3940 
3941 /*
3942  * A non-DisplayPort connector keeps update_subconnector_property() a no-op and,
3943  * because the kunit thread is not the poll worker, the analog poll branch is
3944  * skipped. That leaves the forced-state and dc_sink presence branches as the
3945  * deterministic behaviour to exercise.
3946  */
3947 static struct amdgpu_dm_connector *dm_test_detect_connector(struct kunit *test)
3948 {
3949 	struct drm_device *drm = dm_test_alloc_drm(test);
3950 
3951 	return dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA);
3952 }
3953 
3954 /**
3955  * dm_test_detect_force_on - Test DRM_FORCE_ON reports connected
3956  * @test: The KUnit test context
3957  */
3958 static void dm_test_detect_force_on(struct kunit *test)
3959 {
3960 	struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
3961 
3962 	aconnector->base.force = DRM_FORCE_ON;
3963 
3964 	KUNIT_EXPECT_EQ(test,
3965 		(int)amdgpu_dm_connector_detect(&aconnector->base, false),
3966 		(int)connector_status_connected);
3967 }
3968 
3969 /**
3970  * dm_test_detect_force_on_digital - Test DRM_FORCE_ON_DIGITAL reports connected
3971  * @test: The KUnit test context
3972  */
3973 static void dm_test_detect_force_on_digital(struct kunit *test)
3974 {
3975 	struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
3976 
3977 	aconnector->base.force = DRM_FORCE_ON_DIGITAL;
3978 
3979 	KUNIT_EXPECT_EQ(test,
3980 		(int)amdgpu_dm_connector_detect(&aconnector->base, false),
3981 		(int)connector_status_connected);
3982 }
3983 
3984 /**
3985  * dm_test_detect_force_off - Test DRM_FORCE_OFF reports disconnected
3986  * @test: The KUnit test context
3987  */
3988 static void dm_test_detect_force_off(struct kunit *test)
3989 {
3990 	struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
3991 
3992 	aconnector->base.force = DRM_FORCE_OFF;
3993 
3994 	KUNIT_EXPECT_EQ(test,
3995 		(int)amdgpu_dm_connector_detect(&aconnector->base, false),
3996 		(int)connector_status_disconnected);
3997 }
3998 
3999 /**
4000  * dm_test_detect_sink_present - Test a present dc_sink reports connected
4001  * @test: The KUnit test context
4002  */
4003 static void dm_test_detect_sink_present(struct kunit *test)
4004 {
4005 	struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
4006 	struct dc_sink *sink;
4007 
4008 	sink = kunit_kzalloc(test, sizeof(*sink), GFP_KERNEL);
4009 	KUNIT_ASSERT_NOT_NULL(test, sink);
4010 
4011 	aconnector->base.force = DRM_FORCE_UNSPECIFIED;
4012 	aconnector->dc_sink = sink;
4013 
4014 	KUNIT_EXPECT_EQ(test,
4015 		(int)amdgpu_dm_connector_detect(&aconnector->base, false),
4016 		(int)connector_status_connected);
4017 }
4018 
4019 /**
4020  * dm_test_detect_no_sink - Test a missing dc_sink reports disconnected
4021  * @test: The KUnit test context
4022  */
4023 static void dm_test_detect_no_sink(struct kunit *test)
4024 {
4025 	struct amdgpu_dm_connector *aconnector = dm_test_detect_connector(test);
4026 
4027 	aconnector->base.force = DRM_FORCE_UNSPECIFIED;
4028 	aconnector->dc_sink = NULL;
4029 
4030 	KUNIT_EXPECT_EQ(test,
4031 		(int)amdgpu_dm_connector_detect(&aconnector->base, false),
4032 		(int)connector_status_disconnected);
4033 }
4034 
4035 /* Tests for amdgpu_dm_connector_poll() */
4036 
4037 /**
4038  * dm_test_poll_dac_load_returns_cached - Test the DAC load detection shortcut
4039  * @test: The KUnit test context
4040  *
4041  * When the previous connection was established by analog DAC load detection and
4042  * polling is not forced, the connector is not re-detected and its cached status
4043  * is returned unchanged. The connector is embedded in an amdgpu_device so that
4044  * drm_to_adev() resolves.
4045  */
4046 static void dm_test_poll_dac_load_returns_cached(struct kunit *test)
4047 {
4048 	struct amdgpu_device *adev;
4049 	struct amdgpu_dm_connector *aconnector;
4050 	struct dc_link *link;
4051 	struct dc_sink *local_sink;
4052 	struct drm_device *drm;
4053 	struct device *dev;
4054 
4055 	dev = drm_kunit_helper_alloc_device(test);
4056 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
4057 
4058 	drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*adev),
4059 						  offsetof(struct amdgpu_device, ddev),
4060 						  DRIVER_MODESET);
4061 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
4062 	adev = drm_to_adev(drm);
4063 
4064 	aconnector = drmm_kzalloc(drm, sizeof(*aconnector), GFP_KERNEL);
4065 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4066 	KUNIT_ASSERT_EQ(test,
4067 		drmm_connector_init(drm, &aconnector->base,
4068 				    &dm_test_connector_funcs,
4069 				    DRM_MODE_CONNECTOR_VGA, NULL), 0);
4070 
4071 	link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
4072 	KUNIT_ASSERT_NOT_NULL(test, link);
4073 	local_sink = kunit_kzalloc(test, sizeof(*local_sink), GFP_KERNEL);
4074 	KUNIT_ASSERT_NOT_NULL(test, local_sink);
4075 
4076 	link->local_sink = local_sink;
4077 	link->type = dc_connection_analog_load;
4078 	aconnector->dc_link = link;
4079 
4080 	/* The cached status that the shortcut must return unchanged. */
4081 	aconnector->base.status = connector_status_connected;
4082 
4083 	KUNIT_EXPECT_EQ(test,
4084 		(int)amdgpu_dm_connector_poll(aconnector, false),
4085 		(int)connector_status_connected);
4086 }
4087 
4088 /* Tests for amdgpu_dm_connector_late_register() and _unregister() */
4089 
4090 /*
4091  * Build an amdgpu_dm_connector embedded in an amdgpu_device so drm_to_adev()
4092  * resolves. A VGA connector keeps amdgpu_dm_should_create_sysfs() false (sysfs
4093  * and DP AUX branches skipped) and bl_idx == -1 turns backlight registration
4094  * into a no-op, leaving the register/unregister bookkeeping safe to exercise.
4095  */
4096 static struct amdgpu_dm_connector *dm_test_reg_connector(struct kunit *test)
4097 {
4098 	struct amdgpu_device *adev;
4099 	struct amdgpu_dm_connector *aconnector;
4100 	struct drm_device *drm;
4101 	struct device *dev;
4102 
4103 	dev = drm_kunit_helper_alloc_device(test);
4104 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
4105 
4106 	drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*adev),
4107 						  offsetof(struct amdgpu_device, ddev),
4108 						  DRIVER_MODESET);
4109 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
4110 
4111 	aconnector = drmm_kzalloc(drm, sizeof(*aconnector), GFP_KERNEL);
4112 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4113 	KUNIT_ASSERT_EQ(test,
4114 		drmm_connector_init(drm, &aconnector->base,
4115 				    &dm_test_connector_funcs,
4116 				    DRM_MODE_CONNECTOR_VGA, NULL), 0);
4117 
4118 	aconnector->bl_idx = -1;
4119 
4120 	return aconnector;
4121 }
4122 
4123 /**
4124  * dm_test_late_register_non_dp_succeeds - Test late_register on a plain connector
4125  * @test: The KUnit test context
4126  *
4127  * With sysfs, backlight and DP AUX registration all skipped, late_register
4128  * completes successfully.
4129  */
4130 static void dm_test_late_register_non_dp_succeeds(struct kunit *test)
4131 {
4132 	struct amdgpu_dm_connector *aconnector = dm_test_reg_connector(test);
4133 
4134 	KUNIT_EXPECT_EQ(test,
4135 		amdgpu_dm_connector_late_register(&aconnector->base), 0);
4136 }
4137 
4138 /**
4139  * dm_test_unregister_non_dp_noop - Test unregister tolerates an unregistered connector
4140  * @test: The KUnit test context
4141  *
4142  * No sysfs group was created, the CEC notifier is NULL and the DP AUX channel
4143  * was never registered, so unregister must be a safe no-op.
4144  */
4145 static void dm_test_unregister_non_dp_noop(struct kunit *test)
4146 {
4147 	struct amdgpu_dm_connector *aconnector = dm_test_reg_connector(test);
4148 
4149 	KUNIT_EXPECT_FALSE(test, amdgpu_dm_should_create_sysfs(aconnector));
4150 
4151 	amdgpu_dm_connector_unregister(&aconnector->base);
4152 }
4153 
4154 /* Tests for amdgpu_dm_connector_destroy() */
4155 
4156 /*
4157  * amdgpu_dm_connector_destroy() ends with drm_connector_cleanup() followed by
4158  * kfree(connector), so the connector must be initialised with the unmanaged
4159  * drm_connector_init() and allocated with kzalloc() (the function frees it, so
4160  * kunit_kzalloc() would double free at teardown). It is embedded in an
4161  * amdgpu_device so drm_to_adev() resolves and a dc_link carries a dc_context so
4162  * dc_sink_create() works for the sink-release branches.
4163  */
4164 struct dm_test_destroy_ctx {
4165 	struct drm_device *drm;
4166 	struct dc_context *dc_ctx;
4167 	struct dc_link *link;
4168 };
4169 
4170 static struct dm_test_destroy_ctx *dm_test_destroy_ctx_alloc(struct kunit *test)
4171 {
4172 	struct dm_test_destroy_ctx *ctx;
4173 	struct amdgpu_device *adev;
4174 	struct device *dev;
4175 
4176 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
4177 	KUNIT_ASSERT_NOT_NULL(test, ctx);
4178 
4179 	dev = drm_kunit_helper_alloc_device(test);
4180 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
4181 
4182 	ctx->drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*adev),
4183 						       offsetof(struct amdgpu_device, ddev),
4184 						       DRIVER_MODESET);
4185 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->drm);
4186 
4187 	ctx->dc_ctx = kunit_kzalloc(test, sizeof(*ctx->dc_ctx), GFP_KERNEL);
4188 	KUNIT_ASSERT_NOT_NULL(test, ctx->dc_ctx);
4189 
4190 	ctx->link = kunit_kzalloc(test, sizeof(*ctx->link), GFP_KERNEL);
4191 	KUNIT_ASSERT_NOT_NULL(test, ctx->link);
4192 	ctx->link->ctx = ctx->dc_ctx;
4193 
4194 	return ctx;
4195 }
4196 
4197 /*
4198  * Allocate a connector the destroy path can free. Uses kzalloc() (not
4199  * kunit_kzalloc) and the unmanaged drm_connector_init() because the function
4200  * under test calls drm_connector_cleanup() + kfree(connector).
4201  *
4202  * drm_connector_init() requires funcs->destroy to be set, so a dedicated funcs
4203  * table wires it to amdgpu_dm_connector_destroy() (the test invokes it
4204  * directly; the connector is removed from the device before teardown).
4205  */
4206 static const struct drm_connector_funcs dm_test_destroy_funcs = {
4207 	.reset = amdgpu_dm_connector_funcs_reset,
4208 	.atomic_duplicate_state = amdgpu_dm_connector_atomic_duplicate_state,
4209 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
4210 	.destroy = amdgpu_dm_connector_destroy,
4211 };
4212 
4213 static struct amdgpu_dm_connector *
4214 dm_test_destroy_connector(struct kunit *test, struct drm_device *drm)
4215 {
4216 	struct amdgpu_dm_connector *aconnector;
4217 
4218 	aconnector = kzalloc_obj(*aconnector);
4219 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4220 
4221 	KUNIT_ASSERT_EQ(test,
4222 		drm_connector_init(drm, &aconnector->base,
4223 				   &dm_test_destroy_funcs,
4224 				   DRM_MODE_CONNECTOR_VGA), 0);
4225 	aconnector->bl_idx = -1;
4226 
4227 	return aconnector;
4228 }
4229 
4230 /**
4231  * dm_test_destroy_minimal - Test destroy tears down a bare connector
4232  * @test: The KUnit test context
4233  *
4234  * With no MST, backlight, sinks or registered AUX/CEC, destroy must clean up
4235  * and free the connector without crashing.
4236  */
4237 static void dm_test_destroy_minimal(struct kunit *test)
4238 {
4239 	struct dm_test_destroy_ctx *ctx = dm_test_destroy_ctx_alloc(test);
4240 	struct amdgpu_dm_connector *aconnector =
4241 		dm_test_destroy_connector(test, ctx->drm);
4242 
4243 	amdgpu_dm_connector_destroy(&aconnector->base);
4244 }
4245 
4246 /**
4247  * dm_test_destroy_releases_dc_sink - Test destroy releases the dc_sink
4248  * @test: The KUnit test context
4249  */
4250 static void dm_test_destroy_releases_dc_sink(struct kunit *test)
4251 {
4252 	struct dm_test_destroy_ctx *ctx = dm_test_destroy_ctx_alloc(test);
4253 	struct amdgpu_dm_connector *aconnector =
4254 		dm_test_destroy_connector(test, ctx->drm);
4255 	struct dc_sink_init_data sink_init = { 0 };
4256 	struct dc_sink *sink;
4257 
4258 	sink_init.link = ctx->link;
4259 	sink_init.sink_signal = SIGNAL_TYPE_VIRTUAL;
4260 	sink = dc_sink_create(&sink_init);
4261 	KUNIT_ASSERT_NOT_NULL(test, sink);
4262 
4263 	/* Extra reference so the sink survives destroy for inspection. */
4264 	dc_sink_retain(sink);
4265 	aconnector->dc_sink = sink;
4266 
4267 	amdgpu_dm_connector_destroy(&aconnector->base);
4268 
4269 	KUNIT_EXPECT_EQ(test, (int)kref_read(&sink->refcount), 1);
4270 	dc_sink_release(sink);
4271 }
4272 
4273 /**
4274  * dm_test_destroy_releases_dc_em_sink - Test destroy releases the emulated sink
4275  * @test: The KUnit test context
4276  */
4277 static void dm_test_destroy_releases_dc_em_sink(struct kunit *test)
4278 {
4279 	struct dm_test_destroy_ctx *ctx = dm_test_destroy_ctx_alloc(test);
4280 	struct amdgpu_dm_connector *aconnector =
4281 		dm_test_destroy_connector(test, ctx->drm);
4282 	struct dc_sink_init_data sink_init = { 0 };
4283 	struct dc_sink *sink;
4284 
4285 	sink_init.link = ctx->link;
4286 	sink_init.sink_signal = SIGNAL_TYPE_VIRTUAL;
4287 	sink = dc_sink_create(&sink_init);
4288 	KUNIT_ASSERT_NOT_NULL(test, sink);
4289 
4290 	dc_sink_retain(sink);
4291 	aconnector->dc_em_sink = sink;
4292 
4293 	amdgpu_dm_connector_destroy(&aconnector->base);
4294 
4295 	KUNIT_EXPECT_EQ(test, (int)kref_read(&sink->refcount), 1);
4296 	dc_sink_release(sink);
4297 }
4298 
4299 /* Tests for dm_encoder_helper_disable() */
4300 
4301 /**
4302  * dm_test_encoder_disable_noop - Test the disable hook is a no-op
4303  * @test: The KUnit test context
4304  *
4305  * dm_encoder_helper_disable() has an empty body; calling it must neither touch
4306  * the encoder nor crash.
4307  */
4308 static void dm_test_encoder_disable_noop(struct kunit *test)
4309 {
4310 	struct drm_encoder *encoder;
4311 
4312 	encoder = kunit_kzalloc(test, sizeof(*encoder), GFP_KERNEL);
4313 	KUNIT_ASSERT_NOT_NULL(test, encoder);
4314 
4315 	dm_encoder_helper_disable(encoder);
4316 }
4317 
4318 /* Tests for dm_encoder_helper_atomic_check() */
4319 
4320 /*
4321  * dm_encoder_helper_atomic_check() reads back through to_amdgpu_encoder(),
4322  * to_amdgpu_dm_connector() and to_dm_connector_state(), so the encoder,
4323  * connector and connector-state are stacked in their containers and wired
4324  * together through conn_state->connector.
4325  */
4326 struct dm_test_atomic_check_ctx {
4327 	struct drm_device *drm;
4328 	struct amdgpu_encoder *aenc;
4329 	struct amdgpu_dm_connector *aconnector;
4330 	struct dm_connector_state *dm_state;
4331 	struct drm_crtc_state *crtc_state;
4332 };
4333 
4334 static struct dm_test_atomic_check_ctx *
4335 dm_test_atomic_check_ctx_alloc(struct kunit *test, int connector_type)
4336 {
4337 	struct dm_test_atomic_check_ctx *ctx;
4338 
4339 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
4340 	KUNIT_ASSERT_NOT_NULL(test, ctx);
4341 
4342 	ctx->drm = dm_test_alloc_drm(test);
4343 
4344 	ctx->aenc = kunit_kzalloc(test, sizeof(*ctx->aenc), GFP_KERNEL);
4345 	KUNIT_ASSERT_NOT_NULL(test, ctx->aenc);
4346 	ctx->aenc->base.dev = ctx->drm;
4347 
4348 	ctx->aconnector = kunit_kzalloc(test, sizeof(*ctx->aconnector), GFP_KERNEL);
4349 	KUNIT_ASSERT_NOT_NULL(test, ctx->aconnector);
4350 	ctx->aconnector->base.connector_type = connector_type;
4351 
4352 	ctx->dm_state = kunit_kzalloc(test, sizeof(*ctx->dm_state), GFP_KERNEL);
4353 	KUNIT_ASSERT_NOT_NULL(test, ctx->dm_state);
4354 	ctx->dm_state->base.connector = &ctx->aconnector->base;
4355 
4356 	ctx->crtc_state = kunit_kzalloc(test, sizeof(*ctx->crtc_state), GFP_KERNEL);
4357 	KUNIT_ASSERT_NOT_NULL(test, ctx->crtc_state);
4358 
4359 	return ctx;
4360 }
4361 
4362 /**
4363  * dm_test_atomic_check_edp_native_keeps_scaling - Test native eDP mode is left alone
4364  * @test: The KUnit test context
4365  *
4366  * On an eDP connector whose adjusted mode matches the panel's native mode,
4367  * drm_crtc_helper_mode_valid_fixed() returns MODE_OK so scaling is untouched.
4368  */
4369 static void dm_test_atomic_check_edp_native_keeps_scaling(struct kunit *test)
4370 {
4371 	struct dm_test_atomic_check_ctx *ctx =
4372 		dm_test_atomic_check_ctx_alloc(test, DRM_MODE_CONNECTOR_eDP);
4373 
4374 	ctx->aenc->native_mode.hdisplay = 1920;
4375 	ctx->aenc->native_mode.vdisplay = 1080;
4376 	ctx->crtc_state->adjusted_mode.hdisplay = 1920;
4377 	ctx->crtc_state->adjusted_mode.vdisplay = 1080;
4378 	ctx->dm_state->scaling = RMX_OFF;
4379 
4380 	KUNIT_EXPECT_EQ(test,
4381 		dm_encoder_helper_atomic_check(&ctx->aenc->base,
4382 					       ctx->crtc_state,
4383 					       &ctx->dm_state->base), 0);
4384 	KUNIT_EXPECT_EQ(test, (int)ctx->dm_state->scaling, (int)RMX_OFF);
4385 }
4386 
4387 /**
4388  * dm_test_atomic_check_lvds_non_native_enables_scaling - Test non-native LVDS turns on scaling
4389  * @test: The KUnit test context
4390  *
4391  * On an LVDS connector whose adjusted mode differs from the native mode and is
4392  * currently RMX_OFF, the check enables RMX_ASPECT scaling and still returns 0.
4393  */
4394 static void dm_test_atomic_check_lvds_non_native_enables_scaling(struct kunit *test)
4395 {
4396 	struct dm_test_atomic_check_ctx *ctx =
4397 		dm_test_atomic_check_ctx_alloc(test, DRM_MODE_CONNECTOR_LVDS);
4398 
4399 	ctx->aenc->native_mode.hdisplay = 1920;
4400 	ctx->aenc->native_mode.vdisplay = 1080;
4401 	ctx->crtc_state->adjusted_mode.hdisplay = 1280;
4402 	ctx->crtc_state->adjusted_mode.vdisplay = 720;
4403 	ctx->dm_state->scaling = RMX_OFF;
4404 
4405 	KUNIT_EXPECT_EQ(test,
4406 		dm_encoder_helper_atomic_check(&ctx->aenc->base,
4407 					       ctx->crtc_state,
4408 					       &ctx->dm_state->base), 0);
4409 	KUNIT_EXPECT_EQ(test, (int)ctx->dm_state->scaling, (int)RMX_ASPECT);
4410 }
4411 
4412 /**
4413  * dm_test_atomic_check_non_mst_returns_zero - Test non-MST connectors short-circuit
4414  * @test: The KUnit test context
4415  *
4416  * A non-eDP/LVDS connector with no MST output port hits the early ``return 0``
4417  * before any topology state is touched.
4418  */
4419 static void dm_test_atomic_check_non_mst_returns_zero(struct kunit *test)
4420 {
4421 	struct dm_test_atomic_check_ctx *ctx =
4422 		dm_test_atomic_check_ctx_alloc(test, DRM_MODE_CONNECTOR_HDMIA);
4423 
4424 	ctx->aconnector->mst_output_port = NULL;
4425 
4426 	KUNIT_EXPECT_EQ(test,
4427 		dm_encoder_helper_atomic_check(&ctx->aenc->base,
4428 					       ctx->crtc_state,
4429 					       &ctx->dm_state->base), 0);
4430 }
4431 
4432 /* Tests for hdmi_cec_unset_edid() */
4433 
4434 /**
4435  * dm_test_hdmi_cec_unset_edid_no_notifier - Test the no-notifier no-op path
4436  * @test: The KUnit test context
4437  *
4438  * With aconnector->notifier NULL the function returns early and must not crash.
4439  */
4440 static void dm_test_hdmi_cec_unset_edid_no_notifier(struct kunit *test)
4441 {
4442 	struct amdgpu_dm_connector *aconnector;
4443 
4444 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
4445 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4446 
4447 	hdmi_cec_unset_edid(aconnector);
4448 }
4449 
4450 /* Tests for create_eml_sink() and handle_edid_mgmt() */
4451 
4452 /*
4453  * create_eml_sink() reads EDID off the connector's DDC. Forcing the connector
4454  * DRM_FORCE_OFF makes drm_edid_read_ddc() return NULL before touching any i2c
4455  * adapter, exercising the "no EDID" branch without real hardware. aux_mode is
4456  * set so the embedded DP AUX ddc is selected (no i2c adapter pointer needed).
4457  */
4458 struct dm_test_edid_ctx {
4459 	struct drm_device *drm;
4460 	struct amdgpu_dm_connector *aconnector;
4461 	struct dc_link *link;
4462 };
4463 
4464 static struct dm_test_edid_ctx *
4465 dm_test_edid_ctx_alloc(struct kunit *test, int connector_type)
4466 {
4467 	struct dm_test_edid_ctx *ctx;
4468 
4469 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
4470 	KUNIT_ASSERT_NOT_NULL(test, ctx);
4471 
4472 	ctx->drm = dm_test_alloc_drm(test);
4473 	ctx->aconnector = dm_test_add_connector(test, ctx->drm, connector_type);
4474 
4475 	ctx->link = kunit_kzalloc(test, sizeof(*ctx->link), GFP_KERNEL);
4476 	KUNIT_ASSERT_NOT_NULL(test, ctx->link);
4477 	ctx->link->aux_mode = true;
4478 	ctx->aconnector->dc_link = ctx->link;
4479 
4480 	ctx->aconnector->base.force = DRM_FORCE_OFF;
4481 
4482 	return ctx;
4483 }
4484 
4485 /**
4486  * dm_test_create_eml_sink_no_edid - Test the no-EDID branch creates no sink
4487  * @test: The KUnit test context
4488  *
4489  * When no EDID can be read the function logs an error and returns without
4490  * allocating an emulated sink.
4491  */
4492 static void dm_test_create_eml_sink_no_edid(struct kunit *test)
4493 {
4494 	struct dm_test_edid_ctx *ctx =
4495 		dm_test_edid_ctx_alloc(test, DRM_MODE_CONNECTOR_DisplayPort);
4496 
4497 	create_eml_sink(ctx->aconnector);
4498 
4499 	KUNIT_EXPECT_NULL(test, ctx->aconnector->dc_em_sink);
4500 }
4501 
4502 /**
4503  * dm_test_handle_edid_mgmt_dp_sets_link_caps - Test DP seeds verified link caps
4504  * @test: The KUnit test context
4505  *
4506  * For a DisplayPort link the function primes verified_link_cap before reading
4507  * EDID so a headless force-on connector can still modeset.
4508  */
4509 static void dm_test_handle_edid_mgmt_dp_sets_link_caps(struct kunit *test)
4510 {
4511 	struct dm_test_edid_ctx *ctx =
4512 		dm_test_edid_ctx_alloc(test, DRM_MODE_CONNECTOR_DisplayPort);
4513 
4514 	ctx->link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
4515 
4516 	handle_edid_mgmt(ctx->aconnector);
4517 
4518 	KUNIT_EXPECT_EQ(test, (int)ctx->link->verified_link_cap.lane_count,
4519 			(int)LANE_COUNT_FOUR);
4520 	KUNIT_EXPECT_EQ(test, (int)ctx->link->verified_link_cap.link_rate,
4521 			(int)LINK_RATE_HIGH2);
4522 	KUNIT_EXPECT_NULL(test, ctx->aconnector->dc_em_sink);
4523 }
4524 
4525 /**
4526  * dm_test_handle_edid_mgmt_non_dp_leaves_caps - Test non-DP links keep zeroed caps
4527  * @test: The KUnit test context
4528  *
4529  * A non-DisplayPort link skips the verified_link_cap seeding entirely.
4530  */
4531 static void dm_test_handle_edid_mgmt_non_dp_leaves_caps(struct kunit *test)
4532 {
4533 	struct dm_test_edid_ctx *ctx =
4534 		dm_test_edid_ctx_alloc(test, DRM_MODE_CONNECTOR_HDMIA);
4535 
4536 	ctx->link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
4537 
4538 	handle_edid_mgmt(ctx->aconnector);
4539 
4540 	KUNIT_EXPECT_EQ(test, (int)ctx->link->verified_link_cap.lane_count, 0);
4541 	KUNIT_EXPECT_EQ(test, (int)ctx->link->verified_link_cap.link_rate, 0);
4542 }
4543 
4544 /*
4545  * Context for the connector funcs / modes tests: a managed DRM device with a
4546  * registered connector and a managed encoder attached to it, so helpers that
4547  * walk connector->encoder relationships resolve correctly.
4548  */
4549 struct dm_test_modes_ctx {
4550 	struct drm_device *drm;
4551 	struct amdgpu_dm_connector *aconnector;
4552 	struct amdgpu_encoder *aenc;
4553 };
4554 
4555 static struct dm_test_modes_ctx *
4556 dm_test_modes_ctx_alloc(struct kunit *test, int connector_type)
4557 {
4558 	struct dm_test_modes_ctx *ctx;
4559 
4560 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
4561 	KUNIT_ASSERT_NOT_NULL(test, ctx);
4562 
4563 	ctx->drm = dm_test_alloc_drm(test);
4564 	ctx->aconnector = dm_test_add_connector(test, ctx->drm, connector_type);
4565 
4566 	ctx->aenc = drmm_kzalloc(ctx->drm, sizeof(*ctx->aenc), GFP_KERNEL);
4567 	KUNIT_ASSERT_NOT_NULL(test, ctx->aenc);
4568 	KUNIT_ASSERT_EQ(test,
4569 			drmm_encoder_init(ctx->drm, &ctx->aenc->base, NULL,
4570 					  DRM_MODE_ENCODER_TMDS, NULL), 0);
4571 	KUNIT_ASSERT_EQ(test,
4572 			drm_connector_attach_encoder(&ctx->aconnector->base,
4573 						     &ctx->aenc->base), 0);
4574 
4575 	return ctx;
4576 }
4577 
4578 /**
4579  * dm_test_funcs_force_no_edid - Test force() leaves drm_edid NULL when no EDID
4580  * @test: The KUnit test context
4581  *
4582  * A headless force-on DisplayPort connector reads no EDID, so the cached
4583  * drm_edid pointer must stay NULL after the force callback runs.
4584  */
4585 static void dm_test_funcs_force_no_edid(struct kunit *test)
4586 {
4587 	struct dm_test_edid_ctx *ctx =
4588 		dm_test_edid_ctx_alloc(test, DRM_MODE_CONNECTOR_DisplayPort);
4589 
4590 	amdgpu_dm_connector_funcs_force(&ctx->aconnector->base);
4591 
4592 	KUNIT_EXPECT_NULL(test, ctx->aconnector->drm_edid);
4593 }
4594 
4595 /**
4596  * dm_test_validate_stream_null_stream - Test NULL stream returns unexpected
4597  * @test: The KUnit test context
4598  *
4599  * With a NULL stream the validation jumps straight to cleanup without ever
4600  * dereferencing the dc handle and reports DC_ERROR_UNEXPECTED.
4601  */
4602 static void dm_test_validate_stream_null_stream(struct kunit *test)
4603 {
4604 	KUNIT_EXPECT_EQ(test,
4605 			(int)dm_validate_stream_and_context(NULL, NULL),
4606 			(int)DC_ERROR_UNEXPECTED);
4607 }
4608 
4609 /**
4610  * dm_test_to_encoder_no_encoder - Test connector with no encoder returns NULL
4611  * @test: The KUnit test context
4612  */
4613 static void dm_test_to_encoder_no_encoder(struct kunit *test)
4614 {
4615 	struct drm_device *drm = dm_test_alloc_drm(test);
4616 	struct amdgpu_dm_connector *aconnector =
4617 		dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA);
4618 
4619 	KUNIT_EXPECT_NULL(test,
4620 			  amdgpu_dm_connector_to_encoder(&aconnector->base));
4621 }
4622 
4623 /**
4624  * dm_test_to_encoder_returns_attached - Test the attached encoder is returned
4625  * @test: The KUnit test context
4626  */
4627 static void dm_test_to_encoder_returns_attached(struct kunit *test)
4628 {
4629 	struct dm_test_modes_ctx *ctx =
4630 		dm_test_modes_ctx_alloc(test, DRM_MODE_CONNECTOR_HDMIA);
4631 
4632 	KUNIT_EXPECT_PTR_EQ(test,
4633 			    amdgpu_dm_connector_to_encoder(&ctx->aconnector->base),
4634 			    &ctx->aenc->base);
4635 }
4636 
4637 /**
4638  * dm_test_native_mode_no_encoder - Test native mode resolution is a no-op
4639  * @test: The KUnit test context
4640  *
4641  * Without an encoder there is nothing to copy into, so the call must return
4642  * cleanly without dereferencing a NULL encoder.
4643  */
4644 static void dm_test_native_mode_no_encoder(struct kunit *test)
4645 {
4646 	struct drm_device *drm = dm_test_alloc_drm(test);
4647 	struct amdgpu_dm_connector *aconnector =
4648 		dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA);
4649 
4650 	amdgpu_dm_get_native_mode(&aconnector->base);
4651 }
4652 
4653 /**
4654  * dm_test_native_mode_empty_probed_zeroes_clock - Test empty probed list clears mode
4655  * @test: The KUnit test context
4656  *
4657  * With no probed modes there is no preferred mode to copy, so the encoder's
4658  * native mode is memset to zero (clock becomes 0).
4659  */
4660 static void dm_test_native_mode_empty_probed_zeroes_clock(struct kunit *test)
4661 {
4662 	struct dm_test_modes_ctx *ctx =
4663 		dm_test_modes_ctx_alloc(test, DRM_MODE_CONNECTOR_eDP);
4664 
4665 	ctx->aenc->native_mode.clock = 148500;
4666 
4667 	amdgpu_dm_get_native_mode(&ctx->aconnector->base);
4668 
4669 	KUNIT_EXPECT_EQ(test, ctx->aenc->native_mode.clock, 0);
4670 }
4671 
4672 /**
4673  * dm_test_native_mode_copies_preferred - Test the preferred mode is copied
4674  * @test: The KUnit test context
4675  *
4676  * The preferred probed mode is duplicated into the encoder's native mode.
4677  */
4678 static void dm_test_native_mode_copies_preferred(struct kunit *test)
4679 {
4680 	struct dm_test_modes_ctx *ctx =
4681 		dm_test_modes_ctx_alloc(test, DRM_MODE_CONNECTOR_eDP);
4682 	struct drm_display_mode *mode;
4683 
4684 	mode = drm_mode_create(ctx->drm);
4685 	KUNIT_ASSERT_NOT_NULL(test, mode);
4686 	mode->type = DRM_MODE_TYPE_PREFERRED;
4687 	mode->clock = 148500;
4688 	mode->hdisplay = 1920;
4689 	mode->vdisplay = 1080;
4690 	drm_mode_probed_add(&ctx->aconnector->base, mode);
4691 
4692 	amdgpu_dm_get_native_mode(&ctx->aconnector->base);
4693 
4694 	KUNIT_EXPECT_EQ(test, ctx->aenc->native_mode.hdisplay, 1920);
4695 	KUNIT_EXPECT_EQ(test, ctx->aenc->native_mode.vdisplay, 1080);
4696 	KUNIT_EXPECT_EQ(test, ctx->aenc->native_mode.clock, 148500);
4697 }
4698 
4699 /**
4700  * dm_test_create_common_mode_overrides - Test common mode inherits native timing
4701  * @test: The KUnit test context
4702  *
4703  * A new common mode takes its pixel clock and porches from the encoder's
4704  * native mode but overrides the visible resolution and clears PREFERRED.
4705  */
4706 static void dm_test_create_common_mode_overrides(struct kunit *test)
4707 {
4708 	struct dm_test_modes_ctx *ctx =
4709 		dm_test_modes_ctx_alloc(test, DRM_MODE_CONNECTOR_eDP);
4710 	struct drm_display_mode *mode;
4711 
4712 	ctx->aenc->native_mode.clock = 148500;
4713 	ctx->aenc->native_mode.htotal = 2200;
4714 	ctx->aenc->native_mode.type = DRM_MODE_TYPE_PREFERRED;
4715 
4716 	mode = amdgpu_dm_create_common_mode(&ctx->aenc->base, "800x600",
4717 					    800, 600);
4718 	KUNIT_ASSERT_NOT_NULL(test, mode);
4719 
4720 	KUNIT_EXPECT_EQ(test, mode->hdisplay, 800);
4721 	KUNIT_EXPECT_EQ(test, mode->vdisplay, 600);
4722 	KUNIT_EXPECT_EQ(test, mode->clock, 148500);
4723 	KUNIT_EXPECT_EQ(test, mode->htotal, 2200);
4724 	KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
4725 	KUNIT_EXPECT_STREQ(test, mode->name, "800x600");
4726 
4727 	drm_mode_destroy(ctx->drm, mode);
4728 }
4729 
4730 /**
4731  * dm_test_add_common_modes_non_edp_noop - Test non-eDP/LVDS adds no modes
4732  * @test: The KUnit test context
4733  *
4734  * Common scaled modes are only added for eDP/LVDS panels; an HDMI connector
4735  * is left untouched.
4736  */
4737 static void dm_test_add_common_modes_non_edp_noop(struct kunit *test)
4738 {
4739 	struct dm_test_modes_ctx *ctx =
4740 		dm_test_modes_ctx_alloc(test, DRM_MODE_CONNECTOR_HDMIA);
4741 
4742 	ctx->aenc->native_mode.hdisplay = 1920;
4743 	ctx->aenc->native_mode.vdisplay = 1200;
4744 
4745 	amdgpu_dm_connector_add_common_modes(&ctx->aenc->base,
4746 					     &ctx->aconnector->base);
4747 
4748 	KUNIT_EXPECT_EQ(test, ctx->aconnector->num_modes, 0);
4749 }
4750 
4751 /**
4752  * dm_test_add_common_modes_edp_adds - Test eDP adds the smaller common modes
4753  * @test: The KUnit test context
4754  *
4755  * For an eDP panel with a 1920x1200 native mode every common mode strictly
4756  * smaller than the native one is added (10 of the 11 entries).
4757  */
4758 static void dm_test_add_common_modes_edp_adds(struct kunit *test)
4759 {
4760 	struct dm_test_modes_ctx *ctx =
4761 		dm_test_modes_ctx_alloc(test, DRM_MODE_CONNECTOR_eDP);
4762 
4763 	ctx->aenc->native_mode.hdisplay = 1920;
4764 	ctx->aenc->native_mode.vdisplay = 1200;
4765 
4766 	amdgpu_dm_connector_add_common_modes(&ctx->aenc->base,
4767 					     &ctx->aconnector->base);
4768 
4769 	KUNIT_EXPECT_EQ(test, ctx->aconnector->num_modes, 10);
4770 }
4771 
4772 /**
4773  * dm_test_ddc_get_modes_null_edid - Test a NULL EDID resets the mode count
4774  * @test: The KUnit test context
4775  */
4776 static void dm_test_ddc_get_modes_null_edid(struct kunit *test)
4777 {
4778 	struct drm_device *drm = dm_test_alloc_drm(test);
4779 	struct amdgpu_dm_connector *aconnector =
4780 		dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA);
4781 
4782 	aconnector->num_modes = 5;
4783 
4784 	amdgpu_dm_connector_ddc_get_modes(&aconnector->base, NULL);
4785 
4786 	KUNIT_EXPECT_EQ(test, aconnector->num_modes, 0);
4787 }
4788 
4789 /**
4790  * dm_test_add_fs_modes_no_preferred_mode - Test no preferred mode yields no modes
4791  * @test: The KUnit test context
4792  *
4793  * A writeback connector has no highest-refresh-rate mode, so add_fs_modes()
4794  * cannot build any FreeSync video modes and returns 0.
4795  */
4796 static void dm_test_add_fs_modes_no_preferred_mode(struct kunit *test)
4797 {
4798 	struct amdgpu_dm_connector *aconnector;
4799 
4800 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
4801 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4802 
4803 	aconnector->base.connector_type = DRM_MODE_CONNECTOR_WRITEBACK;
4804 
4805 	KUNIT_EXPECT_EQ(test, (int)add_fs_modes(aconnector), 0);
4806 }
4807 
4808 /**
4809  * dm_test_add_freesync_modes_null_edid_noop - Test NULL EDID adds no modes
4810  * @test: The KUnit test context
4811  *
4812  * Without an EDID the FreeSync video modes cannot be derived, so the mode
4813  * count is left unchanged.
4814  */
4815 static void dm_test_add_freesync_modes_null_edid_noop(struct kunit *test)
4816 {
4817 	struct amdgpu_dm_connector *aconnector;
4818 
4819 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
4820 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4821 
4822 	aconnector->num_modes = 7;
4823 
4824 	amdgpu_dm_connector_add_freesync_modes(&aconnector->base, NULL);
4825 
4826 	KUNIT_EXPECT_EQ(test, aconnector->num_modes, 7);
4827 }
4828 
4829 /* EDID extension block tag values (avoids pulling in private drm headers). */
4830 #define DM_TEST_CEA_EXT		0x02
4831 #define DM_TEST_DISPLAYID_EXT	0x70
4832 
4833 /**
4834  * dm_test_i2c_func_returns_flags - Test the i2c functionality flags
4835  * @test: The KUnit test context
4836  *
4837  * The algorithm advertises plain I2C plus emulated SMBUS regardless of the
4838  * adapter argument, which it never dereferences.
4839  */
4840 static void dm_test_i2c_func_returns_flags(struct kunit *test)
4841 {
4842 	KUNIT_EXPECT_EQ(test, amdgpu_dm_i2c_func(NULL),
4843 			I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL);
4844 }
4845 
4846 /**
4847  * dm_test_i2c_xfer_no_ddc_pin - Test transfers without a DDC pin are rejected
4848  * @test: The KUnit test context
4849  *
4850  * When the backing ddc_service has no ddc_pin the transfer bails out early
4851  * with -EIO before touching the message buffers or the dc handle.
4852  */
4853 static void dm_test_i2c_xfer_no_ddc_pin(struct kunit *test)
4854 {
4855 	struct amdgpu_i2c_adapter *i2c;
4856 	struct ddc_service *ddc;
4857 
4858 	i2c = kunit_kzalloc(test, sizeof(*i2c), GFP_KERNEL);
4859 	KUNIT_ASSERT_NOT_NULL(test, i2c);
4860 	ddc = kunit_kzalloc(test, sizeof(*ddc), GFP_KERNEL);
4861 	KUNIT_ASSERT_NOT_NULL(test, ddc);
4862 
4863 	i2c->ddc_service = ddc;
4864 	i2c_set_adapdata(&i2c->base, i2c);
4865 
4866 	/* ddc->ddc_pin is NULL -> transfer is rejected with -EIO. */
4867 	KUNIT_EXPECT_EQ(test, amdgpu_dm_i2c_xfer(&i2c->base, NULL, 0), -EIO);
4868 }
4869 
4870 /**
4871  * dm_test_get_amd_vsdb_unsupported - Test a zero VSDB version reports no support
4872  * @test: The KUnit test context
4873  */
4874 static void dm_test_get_amd_vsdb_unsupported(struct kunit *test)
4875 {
4876 	struct amdgpu_dm_connector *aconnector;
4877 	struct amdgpu_hdmi_vsdb_info vsdb_info = {0};
4878 
4879 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
4880 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4881 
4882 	aconnector->base.display_info.amd_vsdb.version = 0;
4883 	aconnector->base.display_info.amd_vsdb.replay_mode = false;
4884 
4885 	KUNIT_EXPECT_EQ(test, get_amd_vsdb(aconnector, &vsdb_info), 0);
4886 	KUNIT_EXPECT_EQ(test, vsdb_info.amd_vsdb_version, 0);
4887 }
4888 
4889 /**
4890  * dm_test_get_amd_vsdb_supported - Test a non-zero VSDB version is reported
4891  * @test: The KUnit test context
4892  *
4893  * The display info's VSDB version and replay mode are copied out and a
4894  * non-zero version reports support.
4895  */
4896 static void dm_test_get_amd_vsdb_supported(struct kunit *test)
4897 {
4898 	struct amdgpu_dm_connector *aconnector;
4899 	struct amdgpu_hdmi_vsdb_info vsdb_info = {0};
4900 
4901 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
4902 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4903 
4904 	aconnector->base.display_info.amd_vsdb.version = 2;
4905 	aconnector->base.display_info.amd_vsdb.replay_mode = true;
4906 
4907 	KUNIT_EXPECT_EQ(test, get_amd_vsdb(aconnector, &vsdb_info), 1);
4908 	KUNIT_EXPECT_EQ(test, vsdb_info.amd_vsdb_version, 2);
4909 	KUNIT_EXPECT_TRUE(test, vsdb_info.replay_mode);
4910 }
4911 
4912 /**
4913  * dm_test_parse_hdmi_amd_vsdb_null_edid - Test NULL EDID returns -ENODEV
4914  * @test: The KUnit test context
4915  */
4916 static void dm_test_parse_hdmi_amd_vsdb_null_edid(struct kunit *test)
4917 {
4918 	struct amdgpu_dm_connector *aconnector;
4919 	struct amdgpu_hdmi_vsdb_info vsdb_info = {0};
4920 
4921 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
4922 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4923 
4924 	KUNIT_EXPECT_EQ(test,
4925 			parse_hdmi_amd_vsdb(aconnector, NULL, &vsdb_info),
4926 			-ENODEV);
4927 }
4928 
4929 /**
4930  * dm_test_parse_hdmi_amd_vsdb_no_extensions - Test EDID without extensions
4931  * @test: The KUnit test context
4932  *
4933  * An EDID that declares no extension blocks has no CEA block to parse.
4934  */
4935 static void dm_test_parse_hdmi_amd_vsdb_no_extensions(struct kunit *test)
4936 {
4937 	struct amdgpu_dm_connector *aconnector;
4938 	struct amdgpu_hdmi_vsdb_info vsdb_info = {0};
4939 	struct edid *edid;
4940 
4941 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
4942 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4943 	edid = kunit_kzalloc(test, sizeof(*edid), GFP_KERNEL);
4944 	KUNIT_ASSERT_NOT_NULL(test, edid);
4945 
4946 	edid->extensions = 0;
4947 
4948 	KUNIT_EXPECT_EQ(test,
4949 			parse_hdmi_amd_vsdb(aconnector, edid, &vsdb_info),
4950 			-ENODEV);
4951 }
4952 
4953 /**
4954  * dm_test_parse_hdmi_amd_vsdb_no_cea_ext - Test EDID with no CEA extension
4955  * @test: The KUnit test context
4956  *
4957  * An extension block that is not a CEA block leaves no VSDB to parse.
4958  */
4959 static void dm_test_parse_hdmi_amd_vsdb_no_cea_ext(struct kunit *test)
4960 {
4961 	struct amdgpu_dm_connector *aconnector;
4962 	struct amdgpu_hdmi_vsdb_info vsdb_info = {0};
4963 	struct edid *edid;
4964 	u8 *raw;
4965 
4966 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
4967 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
4968 
4969 	/* Base block + one extension block that is NOT a CEA extension. */
4970 	raw = kunit_kzalloc(test, 2 * EDID_LENGTH, GFP_KERNEL);
4971 	KUNIT_ASSERT_NOT_NULL(test, raw);
4972 	edid = (struct edid *)raw;
4973 	edid->extensions = 1;
4974 	raw[EDID_LENGTH] = DM_TEST_DISPLAYID_EXT;
4975 
4976 	KUNIT_EXPECT_EQ(test,
4977 			parse_hdmi_amd_vsdb(aconnector, edid, &vsdb_info),
4978 			-ENODEV);
4979 }
4980 
4981 /**
4982  * dm_test_parse_displayid_vrr_null_edid - Test NULL EDID leaves range untouched
4983  * @test: The KUnit test context
4984  */
4985 static void dm_test_parse_displayid_vrr_null_edid(struct kunit *test)
4986 {
4987 	struct drm_connector *connector;
4988 
4989 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
4990 	KUNIT_ASSERT_NOT_NULL(test, connector);
4991 
4992 	parse_edid_displayid_vrr(connector, NULL);
4993 
4994 	KUNIT_EXPECT_EQ(test, connector->display_info.monitor_range.max_vfreq, 0);
4995 	KUNIT_EXPECT_EQ(test, connector->display_info.monitor_range.min_vfreq, 0);
4996 }
4997 
4998 /**
4999  * dm_test_parse_displayid_vrr_no_displayid - Test EDID without a DisplayID ext
5000  * @test: The KUnit test context
5001  *
5002  * Without a DisplayID extension block there is no dynamic range to extract.
5003  */
5004 static void dm_test_parse_displayid_vrr_no_displayid(struct kunit *test)
5005 {
5006 	struct drm_connector *connector;
5007 	struct edid *edid;
5008 	u8 *raw;
5009 
5010 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
5011 	KUNIT_ASSERT_NOT_NULL(test, connector);
5012 	raw = kunit_kzalloc(test, 2 * EDID_LENGTH, GFP_KERNEL);
5013 	KUNIT_ASSERT_NOT_NULL(test, raw);
5014 	edid = (struct edid *)raw;
5015 	edid->extensions = 1;
5016 	raw[EDID_LENGTH] = DM_TEST_CEA_EXT;
5017 
5018 	parse_edid_displayid_vrr(connector, edid);
5019 
5020 	KUNIT_EXPECT_EQ(test, connector->display_info.monitor_range.max_vfreq, 0);
5021 }
5022 
5023 /**
5024  * dm_test_parse_displayid_vrr_sets_range - Test a DisplayID VRR block is parsed
5025  * @test: The KUnit test context
5026  *
5027  * A DisplayID dynamic video timing range descriptor populates the connector's
5028  * monitor refresh range.
5029  */
5030 static void dm_test_parse_displayid_vrr_sets_range(struct kunit *test)
5031 {
5032 	struct drm_connector *connector;
5033 	struct edid *edid;
5034 	u8 *raw, *ext;
5035 
5036 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL);
5037 	KUNIT_ASSERT_NOT_NULL(test, connector);
5038 	raw = kunit_kzalloc(test, 2 * EDID_LENGTH, GFP_KERNEL);
5039 	KUNIT_ASSERT_NOT_NULL(test, raw);
5040 	edid = (struct edid *)raw;
5041 	edid->extensions = 1;
5042 
5043 	ext = raw + EDID_LENGTH;
5044 	ext[0] = DM_TEST_DISPLAYID_EXT;
5045 	/*
5046 	 * DisplayID dynamic video timing range descriptor, parsed from offset
5047 	 * 1: tag 0x25, flags 0 (single-byte max), payload length 9, then the
5048 	 * min/max vfreq bytes.
5049 	 */
5050 	ext[1] = 0x25;
5051 	ext[2] = 0x00;
5052 	ext[3] = 9;
5053 	ext[10] = 40;
5054 	ext[11] = 144;
5055 
5056 	parse_edid_displayid_vrr(connector, edid);
5057 
5058 	KUNIT_EXPECT_EQ(test, connector->display_info.monitor_range.min_vfreq, 40);
5059 	KUNIT_EXPECT_EQ(test, connector->display_info.monitor_range.max_vfreq, 144);
5060 }
5061 
5062 /**
5063  * dm_test_mode_valid_interlace_rejected - Test interlaced modes are rejected
5064  * @test: The KUnit test context
5065  *
5066  * Interlaced modes are rejected up front with MODE_ERROR before any sink or
5067  * stream validation is attempted.
5068  */
5069 static void dm_test_mode_valid_interlace_rejected(struct kunit *test)
5070 {
5071 	struct amdgpu_dm_connector *aconnector;
5072 	struct drm_display_mode *mode;
5073 
5074 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
5075 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
5076 	mode = kunit_kzalloc(test, sizeof(*mode), GFP_KERNEL);
5077 	KUNIT_ASSERT_NOT_NULL(test, mode);
5078 
5079 	mode->flags = DRM_MODE_FLAG_INTERLACE;
5080 
5081 	KUNIT_EXPECT_EQ(test,
5082 			amdgpu_dm_connector_mode_valid(&aconnector->base, mode),
5083 			MODE_ERROR);
5084 }
5085 
5086 /**
5087  * dm_test_mode_valid_dblscan_rejected - Test doublescan modes are rejected
5088  * @test: The KUnit test context
5089  *
5090  * Doublescan modes are rejected up front with MODE_ERROR.
5091  */
5092 static void dm_test_mode_valid_dblscan_rejected(struct kunit *test)
5093 {
5094 	struct amdgpu_dm_connector *aconnector;
5095 	struct drm_display_mode *mode;
5096 
5097 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
5098 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
5099 	mode = kunit_kzalloc(test, sizeof(*mode), GFP_KERNEL);
5100 	KUNIT_ASSERT_NOT_NULL(test, mode);
5101 
5102 	mode->flags = DRM_MODE_FLAG_DBLSCAN;
5103 
5104 	KUNIT_EXPECT_EQ(test,
5105 			amdgpu_dm_connector_mode_valid(&aconnector->base, mode),
5106 			MODE_ERROR);
5107 }
5108 
5109 /**
5110  * dm_test_hdmi_cec_set_edid_no_notifier - Test the no-notifier no-op path
5111  * @test: The KUnit test context
5112  *
5113  * With aconnector->notifier NULL the function returns early and must not crash.
5114  */
5115 static void dm_test_hdmi_cec_set_edid_no_notifier(struct kunit *test)
5116 {
5117 	struct amdgpu_dm_connector *aconnector;
5118 
5119 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
5120 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
5121 
5122 	amdgpu_dm_hdmi_cec_set_edid(aconnector);
5123 }
5124 
5125 /**
5126  * dm_test_s3_handle_hdmi_cec_suspend - Test the suspend pass over connectors
5127  * @test: The KUnit test context
5128  *
5129  * Suspend iterates all connectors, skipping writeback ones and calling the
5130  * unset path on the rest; with NULL notifiers this is a crash-free no-op.
5131  */
5132 static void dm_test_s3_handle_hdmi_cec_suspend(struct kunit *test)
5133 {
5134 	struct drm_device *drm = dm_test_alloc_drm(test);
5135 
5136 	dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_WRITEBACK);
5137 	dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA);
5138 
5139 	amdgpu_dm_s3_handle_hdmi_cec(drm, true);
5140 }
5141 
5142 /**
5143  * dm_test_s3_handle_hdmi_cec_resume - Test the resume pass over connectors
5144  * @test: The KUnit test context
5145  *
5146  * Resume iterates all connectors, skipping writeback ones and calling the set
5147  * path on the rest; with NULL notifiers this is a crash-free no-op.
5148  */
5149 static void dm_test_s3_handle_hdmi_cec_resume(struct kunit *test)
5150 {
5151 	struct drm_device *drm = dm_test_alloc_drm(test);
5152 
5153 	dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_WRITEBACK);
5154 	dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA);
5155 
5156 	amdgpu_dm_s3_handle_hdmi_cec(drm, false);
5157 }
5158 
5159 /**
5160  * dm_test_create_validate_stream_null_dm_state - Test NULL state returns NULL
5161  * @test: The KUnit test context
5162  *
5163  * Without a connector state there is nothing to validate against, so the
5164  * helper bails out with NULL before touching the dc handle.
5165  */
5166 static void dm_test_create_validate_stream_null_dm_state(struct kunit *test)
5167 {
5168 	struct amdgpu_dm_connector *aconnector;
5169 
5170 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
5171 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
5172 
5173 	KUNIT_EXPECT_NULL(test,
5174 			  amdgpu_dm_create_validate_stream_for_sink(&aconnector->base,
5175 								    NULL, NULL, NULL));
5176 }
5177 
5178 /**
5179  * dm_test_update_after_detect_mst_noop - Test MST connectors are left to drm_mst
5180  * @test: The KUnit test context
5181  *
5182  * An MST connector is handled by the drm_mst framework, so the function
5183  * returns immediately and never dereferences the (NULL) dc_link.
5184  */
5185 static void dm_test_update_after_detect_mst_noop(struct kunit *test)
5186 {
5187 	struct amdgpu_dm_connector *aconnector;
5188 
5189 	aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
5190 	KUNIT_ASSERT_NOT_NULL(test, aconnector);
5191 
5192 	aconnector->mst_mgr.mst_state = true;
5193 
5194 	amdgpu_dm_update_connector_after_detect(aconnector);
5195 }
5196 
5197 /**
5198  * dm_test_update_after_detect_sink_unchanged - Test the short-pulse no-op path
5199  * @test: The KUnit test context
5200  *
5201  * When the link reports no local sink and the connector already has no
5202  * dc_sink, the "sink didn't change" path returns without touching DC.
5203  */
5204 static void dm_test_update_after_detect_sink_unchanged(struct kunit *test)
5205 {
5206 	struct drm_device *drm = dm_test_alloc_drm(test);
5207 	struct amdgpu_dm_connector *aconnector;
5208 	struct dc_link *link;
5209 
5210 	aconnector = dm_test_add_connector(test, drm, DRM_MODE_CONNECTOR_HDMIA);
5211 	link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
5212 	KUNIT_ASSERT_NOT_NULL(test, link);
5213 
5214 	aconnector->dc_link = link;
5215 
5216 	/* link->local_sink and aconnector->dc_sink are both NULL. */
5217 	amdgpu_dm_update_connector_after_detect(aconnector);
5218 
5219 	KUNIT_EXPECT_NULL(test, aconnector->dc_sink);
5220 }
5221 
5222 /* Tests for amdgpu_dm_update_stream_scaling_settings() */
5223 
5224 /**
5225  * dm_test_update_scaling_null_mode - Test NULL mode leaves the stream rects untouched
5226  * @test: The KUnit test context
5227  */
5228 static void dm_test_update_scaling_null_mode(struct kunit *test)
5229 {
5230 	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
5231 	struct dc_stream_state *stream = dm_kunit_alloc_stream(test, NULL);
5232 
5233 	stream->timing.h_addressable = 1920;
5234 	stream->timing.v_addressable = 1080;
5235 
5236 	amdgpu_dm_update_stream_scaling_settings(&adev->ddev, NULL, NULL, stream);
5237 
5238 	/* NULL mode: early return before touching src/dst */
5239 	KUNIT_EXPECT_EQ(test, stream->src.width, 0);
5240 	KUNIT_EXPECT_EQ(test, stream->dst.width, 0);
5241 }
5242 
5243 /**
5244  * dm_test_update_scaling_fullscreen_default - Test full-screen default with no dm_state
5245  * @test: The KUnit test context
5246  */
5247 static void dm_test_update_scaling_fullscreen_default(struct kunit *test)
5248 {
5249 	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
5250 	struct dc_stream_state *stream = dm_kunit_alloc_stream(test, NULL);
5251 	struct drm_display_mode mode = { 0 };
5252 
5253 	mode.hdisplay = 1920;
5254 	mode.vdisplay = 1080;
5255 	stream->timing.h_addressable = 2560;
5256 	stream->timing.v_addressable = 1440;
5257 
5258 	amdgpu_dm_update_stream_scaling_settings(&adev->ddev, &mode, NULL, stream);
5259 
5260 	/* src = mode, dst = timing addressable, no centering without dm_state */
5261 	KUNIT_EXPECT_EQ(test, stream->src.width, 1920);
5262 	KUNIT_EXPECT_EQ(test, stream->src.height, 1080);
5263 	KUNIT_EXPECT_EQ(test, stream->dst.width, 2560);
5264 	KUNIT_EXPECT_EQ(test, stream->dst.height, 1440);
5265 	KUNIT_EXPECT_EQ(test, stream->dst.x, 0);
5266 	KUNIT_EXPECT_EQ(test, stream->dst.y, 0);
5267 }
5268 
5269 /**
5270  * dm_test_update_scaling_rmx_full - Test RMX_FULL keeps a full-size, centered dst
5271  * @test: The KUnit test context
5272  */
5273 static void dm_test_update_scaling_rmx_full(struct kunit *test)
5274 {
5275 	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
5276 	struct dc_stream_state *stream = dm_kunit_alloc_stream(test, NULL);
5277 	struct dm_connector_state *dm_state;
5278 	struct drm_display_mode mode = { 0 };
5279 
5280 	dm_state = kunit_kzalloc(test, sizeof(*dm_state), GFP_KERNEL);
5281 	KUNIT_ASSERT_NOT_NULL(test, dm_state);
5282 
5283 	mode.hdisplay = 1280;
5284 	mode.vdisplay = 720;
5285 	stream->timing.h_addressable = 1920;
5286 	stream->timing.v_addressable = 1080;
5287 	dm_state->scaling = RMX_FULL;
5288 
5289 	amdgpu_dm_update_stream_scaling_settings(&adev->ddev, &mode, dm_state, stream);
5290 
5291 	/* RMX_FULL: dst stays full addressable, offset 0 */
5292 	KUNIT_EXPECT_EQ(test, stream->dst.width, 1920);
5293 	KUNIT_EXPECT_EQ(test, stream->dst.height, 1080);
5294 	KUNIT_EXPECT_EQ(test, stream->dst.x, 0);
5295 	KUNIT_EXPECT_EQ(test, stream->dst.y, 0);
5296 }
5297 
5298 /**
5299  * dm_test_update_scaling_rmx_aspect_pillarbox - Test RMX_ASPECT preserves aspect ratio
5300  * @test: The KUnit test context
5301  */
5302 static void dm_test_update_scaling_rmx_aspect_pillarbox(struct kunit *test)
5303 {
5304 	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
5305 	struct dc_stream_state *stream = dm_kunit_alloc_stream(test, NULL);
5306 	struct dm_connector_state *dm_state;
5307 	struct drm_display_mode mode = { 0 };
5308 
5309 	dm_state = kunit_kzalloc(test, sizeof(*dm_state), GFP_KERNEL);
5310 	KUNIT_ASSERT_NOT_NULL(test, dm_state);
5311 
5312 	/* 4:3 source on a 16:9 panel -> pillarboxed */
5313 	mode.hdisplay = 1024;
5314 	mode.vdisplay = 768;
5315 	stream->timing.h_addressable = 1920;
5316 	stream->timing.v_addressable = 1080;
5317 	dm_state->scaling = RMX_ASPECT;
5318 
5319 	amdgpu_dm_update_stream_scaling_settings(&adev->ddev, &mode, dm_state, stream);
5320 
5321 	/*
5322 	 * src.width*dst.height (1024*1080) < src.height*dst.width (768*1920):
5323 	 * width scaled to src.width*dst.height/src.height = 1440, height stays
5324 	 * 1080, centered horizontally at (1920-1440)/2 = 240.
5325 	 */
5326 	KUNIT_EXPECT_EQ(test, stream->dst.width, 1440);
5327 	KUNIT_EXPECT_EQ(test, stream->dst.height, 1080);
5328 	KUNIT_EXPECT_EQ(test, stream->dst.x, 240);
5329 	KUNIT_EXPECT_EQ(test, stream->dst.y, 0);
5330 }
5331 
5332 /**
5333  * dm_test_update_scaling_rmx_aspect_letterbox - Test RMX_ASPECT letterboxes wide sources
5334  * @test: The KUnit test context
5335  */
5336 static void dm_test_update_scaling_rmx_aspect_letterbox(struct kunit *test)
5337 {
5338 	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
5339 	struct dc_stream_state *stream = dm_kunit_alloc_stream(test, NULL);
5340 	struct dm_connector_state *dm_state;
5341 	struct drm_display_mode mode = { 0 };
5342 
5343 	dm_state = kunit_kzalloc(test, sizeof(*dm_state), GFP_KERNEL);
5344 	KUNIT_ASSERT_NOT_NULL(test, dm_state);
5345 
5346 	/* 16:9 source on a 4:3 panel -> letterboxed */
5347 	mode.hdisplay = 1920;
5348 	mode.vdisplay = 1080;
5349 	stream->timing.h_addressable = 1024;
5350 	stream->timing.v_addressable = 768;
5351 	dm_state->scaling = RMX_ASPECT;
5352 
5353 	amdgpu_dm_update_stream_scaling_settings(&adev->ddev, &mode, dm_state, stream);
5354 
5355 	KUNIT_EXPECT_EQ(test, stream->dst.width, 1024);
5356 	KUNIT_EXPECT_EQ(test, stream->dst.height, 576);
5357 	KUNIT_EXPECT_EQ(test, stream->dst.x, 0);
5358 	KUNIT_EXPECT_EQ(test, stream->dst.y, 96);
5359 }
5360 
5361 /**
5362  * dm_test_update_scaling_rmx_center - Test RMX_CENTER centers a 1:1 dst
5363  * @test: The KUnit test context
5364  */
5365 static void dm_test_update_scaling_rmx_center(struct kunit *test)
5366 {
5367 	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
5368 	struct dc_stream_state *stream = dm_kunit_alloc_stream(test, NULL);
5369 	struct dm_connector_state *dm_state;
5370 	struct drm_display_mode mode = { 0 };
5371 
5372 	dm_state = kunit_kzalloc(test, sizeof(*dm_state), GFP_KERNEL);
5373 	KUNIT_ASSERT_NOT_NULL(test, dm_state);
5374 
5375 	mode.hdisplay = 1280;
5376 	mode.vdisplay = 720;
5377 	stream->timing.h_addressable = 1920;
5378 	stream->timing.v_addressable = 1080;
5379 	dm_state->scaling = RMX_CENTER;
5380 
5381 	amdgpu_dm_update_stream_scaling_settings(&adev->ddev, &mode, dm_state, stream);
5382 
5383 	/* RMX_CENTER: dst = src, centered on the addressable area */
5384 	KUNIT_EXPECT_EQ(test, stream->dst.width, 1280);
5385 	KUNIT_EXPECT_EQ(test, stream->dst.height, 720);
5386 	KUNIT_EXPECT_EQ(test, stream->dst.x, 320);
5387 	KUNIT_EXPECT_EQ(test, stream->dst.y, 180);
5388 }
5389 
5390 /**
5391  * dm_test_update_scaling_underscan - Test underscan borders shrink and offset dst
5392  * @test: The KUnit test context
5393  */
5394 static void dm_test_update_scaling_underscan(struct kunit *test)
5395 {
5396 	struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
5397 	struct dc_stream_state *stream = dm_kunit_alloc_stream(test, NULL);
5398 	struct dm_connector_state *dm_state;
5399 	struct drm_display_mode mode = { 0 };
5400 
5401 	dm_state = kunit_kzalloc(test, sizeof(*dm_state), GFP_KERNEL);
5402 	KUNIT_ASSERT_NOT_NULL(test, dm_state);
5403 
5404 	mode.hdisplay = 1920;
5405 	mode.vdisplay = 1080;
5406 	stream->timing.h_addressable = 1920;
5407 	stream->timing.v_addressable = 1080;
5408 	dm_state->scaling = RMX_FULL;
5409 	dm_state->underscan_enable = true;
5410 	dm_state->underscan_hborder = 64;
5411 	dm_state->underscan_vborder = 32;
5412 
5413 	amdgpu_dm_update_stream_scaling_settings(&adev->ddev, &mode, dm_state, stream);
5414 
5415 	/* Full dst, then underscan: x/y += border/2, width/height -= border */
5416 	KUNIT_EXPECT_EQ(test, stream->dst.x, 32);
5417 	KUNIT_EXPECT_EQ(test, stream->dst.y, 16);
5418 	KUNIT_EXPECT_EQ(test, stream->dst.width, 1856);
5419 	KUNIT_EXPECT_EQ(test, stream->dst.height, 1048);
5420 }
5421 
5422 static struct kunit_case amdgpu_dm_connector_tests[] = {
5423 	/* get_subconnector_type */
5424 	KUNIT_CASE(dm_test_subconnector_type_none),
5425 	KUNIT_CASE(dm_test_subconnector_type_vga),
5426 	KUNIT_CASE(dm_test_subconnector_type_dvi_converter),
5427 	KUNIT_CASE(dm_test_subconnector_type_dvi_dongle),
5428 	KUNIT_CASE(dm_test_subconnector_type_hdmi_converter),
5429 	KUNIT_CASE(dm_test_subconnector_type_hdmi_dongle),
5430 	KUNIT_CASE(dm_test_subconnector_type_mismatched),
5431 	KUNIT_CASE(dm_test_subconnector_type_default_unknown),
5432 	/* get_output_content_type */
5433 	KUNIT_CASE(dm_test_content_type_no_data),
5434 	KUNIT_CASE(dm_test_content_type_graphics),
5435 	KUNIT_CASE(dm_test_content_type_photo),
5436 	KUNIT_CASE(dm_test_content_type_cinema),
5437 	KUNIT_CASE(dm_test_content_type_game),
5438 	KUNIT_CASE(dm_test_content_type_unknown_defaults_no_data),
5439 	/* adjust_colour_depth_from_display_info */
5440 	KUNIT_CASE(dm_test_adjust_colour_depth_fits_at_888),
5441 	KUNIT_CASE(dm_test_adjust_colour_depth_reduces_to_888),
5442 	KUNIT_CASE(dm_test_adjust_colour_depth_10bpc_passes),
5443 	KUNIT_CASE(dm_test_adjust_colour_depth_420_halves_clk),
5444 	KUNIT_CASE(dm_test_adjust_colour_depth_420_reduces),
5445 	KUNIT_CASE(dm_test_adjust_colour_depth_reduces_12bpc_to_10bpc),
5446 	KUNIT_CASE(dm_test_adjust_colour_depth_16bpc_no_fallback),
5447 	KUNIT_CASE(dm_test_adjust_colour_depth_none_fits),
5448 	KUNIT_CASE(dm_test_adjust_colour_depth_invalid_depth),
5449 	/* amdgpu_dm_get_output_color_space */
5450 	KUNIT_CASE(dm_test_output_color_space_default_rgb_full),
5451 	KUNIT_CASE(dm_test_output_color_space_default_rgb_limited),
5452 	KUNIT_CASE(dm_test_output_color_space_default_ycbcr709),
5453 	KUNIT_CASE(dm_test_output_color_space_default_ycbcr601_limited),
5454 	KUNIT_CASE(dm_test_output_color_space_bt601_y_only),
5455 	KUNIT_CASE(dm_test_output_color_space_bt601),
5456 	KUNIT_CASE(dm_test_output_color_space_bt709),
5457 	KUNIT_CASE(dm_test_output_color_space_bt709_y_only),
5458 	KUNIT_CASE(dm_test_output_color_space_oprgb),
5459 	KUNIT_CASE(dm_test_output_color_space_bt2020_rgb),
5460 	KUNIT_CASE(dm_test_output_color_space_bt2020_rgb_limited),
5461 	KUNIT_CASE(dm_test_output_color_space_bt2020_ycc),
5462 	KUNIT_CASE(dm_test_output_color_space_default_ycbcr709_y_only),
5463 	KUNIT_CASE(dm_test_output_color_space_default_ycbcr601),
5464 	KUNIT_CASE(dm_test_output_color_space_bt2020_ycc_rgb_encoding),
5465 	KUNIT_CASE(dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited),
5466 	KUNIT_CASE(dm_test_output_color_space_bt2020_rgb_ycc_encoding),
5467 	/* Tests for amdgpu_dm_convert_dc_color_depth_into_bpc */
5468 	KUNIT_CASE(dm_test_convert_color_depth_bpc_mappings),
5469 	KUNIT_CASE(dm_test_convert_color_depth_bpc_unknown),
5470 	/* amdgpu_dm_convert_color_depth_from_display_info */
5471 	KUNIT_CASE(dm_test_color_depth_from_info_bpc8),
5472 	KUNIT_CASE(dm_test_color_depth_from_info_bpc10),
5473 	KUNIT_CASE(dm_test_color_depth_from_info_zero_bpc_defaults_888),
5474 	KUNIT_CASE(dm_test_color_depth_from_info_requested_bpc_caps),
5475 	KUNIT_CASE(dm_test_color_depth_from_info_y420_default),
5476 	KUNIT_CASE(dm_test_color_depth_from_info_y420_10bpc),
5477 	KUNIT_CASE(dm_test_color_depth_from_info_y420_12bpc),
5478 	KUNIT_CASE(dm_test_color_depth_from_info_y420_16bpc),
5479 	KUNIT_CASE(dm_test_color_depth_from_info_requested_odd_bpc),
5480 	KUNIT_CASE(dm_test_color_depth_from_info_unsupported_bpc),
5481 	/* to_drm_connector_type */
5482 	KUNIT_CASE(dm_test_to_connector_type_hdmi),
5483 	KUNIT_CASE(dm_test_to_connector_type_edp),
5484 	KUNIT_CASE(dm_test_to_connector_type_lvds),
5485 	KUNIT_CASE(dm_test_to_connector_type_rgb),
5486 	KUNIT_CASE(dm_test_to_connector_type_dp),
5487 	KUNIT_CASE(dm_test_to_connector_type_dp_mst),
5488 	KUNIT_CASE(dm_test_to_connector_type_dvi_dvii),
5489 	KUNIT_CASE(dm_test_to_connector_type_dual_link_dvii),
5490 	KUNIT_CASE(dm_test_to_connector_type_dvi_dvid),
5491 	KUNIT_CASE(dm_test_to_connector_type_dual_link_dvid),
5492 	KUNIT_CASE(dm_test_to_connector_type_virtual),
5493 	KUNIT_CASE(dm_test_to_connector_type_unknown),
5494 	/* is_duplicate_mode */
5495 	KUNIT_CASE(dm_test_is_duplicate_mode_empty_list),
5496 	KUNIT_CASE(dm_test_is_duplicate_mode_match),
5497 	KUNIT_CASE(dm_test_is_duplicate_mode_no_match),
5498 	KUNIT_CASE(dm_test_is_duplicate_mode_same_size_different_clock),
5499 	/* amdgpu_dm_get_encoder_crtc_mask */
5500 	KUNIT_CASE(dm_test_encoder_crtc_mask_1),
5501 	KUNIT_CASE(dm_test_encoder_crtc_mask_2),
5502 	KUNIT_CASE(dm_test_encoder_crtc_mask_3),
5503 	KUNIT_CASE(dm_test_encoder_crtc_mask_4),
5504 	KUNIT_CASE(dm_test_encoder_crtc_mask_5),
5505 	KUNIT_CASE(dm_test_encoder_crtc_mask_6),
5506 	KUNIT_CASE(dm_test_encoder_crtc_mask_default),
5507 	/* get_aspect_ratio */
5508 	KUNIT_CASE(dm_test_aspect_ratio_no_data),
5509 	KUNIT_CASE(dm_test_aspect_ratio_4_3),
5510 	KUNIT_CASE(dm_test_aspect_ratio_16_9),
5511 	KUNIT_CASE(dm_test_aspect_ratio_64_27),
5512 	KUNIT_CASE(dm_test_aspect_ratio_256_135),
5513 	/* copy_crtc_timing_for_drm_display_mode */
5514 	KUNIT_CASE(dm_test_copy_crtc_timing_copies_all_fields),
5515 	KUNIT_CASE(dm_test_copy_crtc_timing_leaves_non_crtc_fields),
5516 	/* decide_crtc_timing_for_drm_display_mode */
5517 	KUNIT_CASE(dm_test_decide_crtc_timing_scale_enabled),
5518 	KUNIT_CASE(dm_test_decide_crtc_timing_matching_mode),
5519 	KUNIT_CASE(dm_test_decide_crtc_timing_no_copy),
5520 	KUNIT_CASE(dm_test_decide_crtc_timing_no_crtc_clock),
5521 	/* amdgpu_dm_connector_funcs_reset */
5522 	KUNIT_CASE(dm_test_funcs_reset_sets_defaults),
5523 	KUNIT_CASE(dm_test_funcs_reset_edp_abm_level),
5524 	KUNIT_CASE(dm_test_funcs_reset_edp_abm_disabled),
5525 	/* amdgpu_dm_connector_atomic_duplicate_state */
5526 	KUNIT_CASE(dm_test_atomic_dup_state_copies_fields),
5527 	/* amdgpu_dm_fill_hdr_info_packet */
5528 	KUNIT_CASE(dm_test_fill_hdr_null_metadata),
5529 	KUNIT_CASE(dm_test_fill_hdr_zeroes_output),
5530 	/* amdgpu_dm_connector_atomic_set_property */
5531 	KUNIT_CASE(dm_test_set_property_scaling_center),
5532 	KUNIT_CASE(dm_test_set_property_scaling_aspect),
5533 	KUNIT_CASE(dm_test_set_property_scaling_fullscreen),
5534 	KUNIT_CASE(dm_test_set_property_scaling_none),
5535 	KUNIT_CASE(dm_test_set_property_scaling_unchanged),
5536 	KUNIT_CASE(dm_test_set_property_underscan_hborder),
5537 	KUNIT_CASE(dm_test_set_property_underscan_vborder),
5538 	KUNIT_CASE(dm_test_set_property_underscan_enable),
5539 	KUNIT_CASE(dm_test_set_property_abm_sysfs_control),
5540 	KUNIT_CASE(dm_test_set_property_abm_level_off),
5541 	KUNIT_CASE(dm_test_set_property_abm_level_value),
5542 	KUNIT_CASE(dm_test_set_property_unknown),
5543 	/* amdgpu_dm_connector_atomic_get_property */
5544 	KUNIT_CASE(dm_test_get_property_scaling_center),
5545 	KUNIT_CASE(dm_test_get_property_scaling_aspect),
5546 	KUNIT_CASE(dm_test_get_property_scaling_full),
5547 	KUNIT_CASE(dm_test_get_property_scaling_off),
5548 	KUNIT_CASE(dm_test_get_property_underscan_borders),
5549 	KUNIT_CASE(dm_test_get_property_abm_sysfs_allowed),
5550 	KUNIT_CASE(dm_test_get_property_abm_level),
5551 	KUNIT_CASE(dm_test_get_property_abm_disabled_zero),
5552 	KUNIT_CASE(dm_test_get_property_unknown),
5553 	/* amdgpu_dm_get_highest_refresh_rate_mode */
5554 	KUNIT_CASE(dm_test_highest_refresh_writeback_null),
5555 	KUNIT_CASE(dm_test_highest_refresh_cached_base),
5556 	KUNIT_CASE(dm_test_highest_refresh_preferred_mode),
5557 	/* amdgpu_dm_is_freesync_video_mode */
5558 	KUNIT_CASE(dm_test_is_freesync_video_mode_null_mode),
5559 	KUNIT_CASE(dm_test_is_freesync_video_mode_match),
5560 	KUNIT_CASE(dm_test_is_freesync_video_mode_no_match),
5561 	/* update_subconnector_property */
5562 	KUNIT_CASE(dm_test_update_subconnector_dp_with_sink),
5563 	KUNIT_CASE(dm_test_update_subconnector_dp_no_sink),
5564 	KUNIT_CASE(dm_test_update_subconnector_non_dp_noop),
5565 	/* amdgpu_dm_update_cacp_caps */
5566 	KUNIT_CASE(dm_test_cacp_caps_unsupported_ip),
5567 	KUNIT_CASE(dm_test_cacp_caps_excluded_ip_316),
5568 	KUNIT_CASE(dm_test_cacp_caps_edp_oled_supported),
5569 	KUNIT_CASE(dm_test_cacp_caps_lvds_oled_supported),
5570 	KUNIT_CASE(dm_test_cacp_caps_non_edp_signal),
5571 	KUNIT_CASE(dm_test_cacp_caps_lcd_panel),
5572 	/* amdgpu_dm_set_panel_type */
5573 	KUNIT_CASE(dm_test_set_panel_type_vsdb_oled),
5574 	KUNIT_CASE(dm_test_set_panel_type_vsdb_miniled),
5575 	KUNIT_CASE(dm_test_set_panel_type_dpcd_oled),
5576 	KUNIT_CASE(dm_test_set_panel_type_dpcd_miniled),
5577 	KUNIT_CASE(dm_test_set_panel_type_did_oled),
5578 	KUNIT_CASE(dm_test_set_panel_type_did_lcd),
5579 	KUNIT_CASE(dm_test_set_panel_type_vendor_lum_heuristic),
5580 	KUNIT_CASE(dm_test_set_panel_type_defaults_to_lcd),
5581 	/* amdgpu_dm_fbc_init */
5582 	KUNIT_CASE(dm_test_fbc_init_no_compressor),
5583 	KUNIT_CASE(dm_test_fbc_init_non_edp),
5584 	KUNIT_CASE(dm_test_fbc_init_already_allocated),
5585 	KUNIT_CASE(dm_test_fbc_init_no_modes),
5586 	/* amdgpu_dm_detect_mst_link_for_all_connectors */
5587 	KUNIT_CASE(dm_test_detect_mst_no_connectors),
5588 	KUNIT_CASE(dm_test_detect_mst_skips_writeback),
5589 	KUNIT_CASE(dm_test_detect_mst_non_mst_link),
5590 	KUNIT_CASE(dm_test_detect_mst_branch_without_aux),
5591 	/* amdgpu_dm_find_first_crtc_matching_connector */
5592 	KUNIT_CASE(dm_test_find_first_crtc_match),
5593 	KUNIT_CASE(dm_test_find_first_crtc_no_match),
5594 	KUNIT_CASE(dm_test_find_first_crtc_empty_state),
5595 	KUNIT_CASE(dm_test_find_first_crtc_skips_null_ptr),
5596 	KUNIT_CASE(dm_test_find_first_crtc_returns_first),
5597 	/* amdgpu_dm_set_panel_type */
5598 	KUNIT_CASE(dm_test_set_panel_type_samsung_miniled),
5599 	KUNIT_CASE(dm_test_set_panel_type_samsung_below_threshold),
5600 	KUNIT_CASE(dm_test_set_panel_type_default_lcd),
5601 	/* amdgpu_dm_update_cacp_caps */
5602 	KUNIT_CASE(dm_test_cacp_caps_edp_supported),
5603 	KUNIT_CASE(dm_test_cacp_caps_lvds_supported),
5604 	KUNIT_CASE(dm_test_cacp_caps_old_ip_unsupported),
5605 	KUNIT_CASE(dm_test_cacp_caps_ip_3_1_6_unsupported),
5606 	KUNIT_CASE(dm_test_cacp_caps_non_edp_lvds_unsupported),
5607 	KUNIT_CASE(dm_test_cacp_caps_lcd_unsupported),
5608 	/* fill_stream_properties_from_drm_display_mode */
5609 	KUNIT_CASE(dm_test_fill_stream_borders_zeroed),
5610 	KUNIT_CASE(dm_test_fill_stream_rgb_defaults),
5611 	KUNIT_CASE(dm_test_fill_stream_sync_polarity_positive),
5612 	KUNIT_CASE(dm_test_fill_stream_sync_polarity_negative),
5613 	KUNIT_CASE(dm_test_fill_stream_inherits_old_stream),
5614 	KUNIT_CASE(dm_test_fill_stream_timing_from_crtc),
5615 	KUNIT_CASE(dm_test_fill_stream_color_depth_requested_bpc),
5616 	KUNIT_CASE(dm_test_fill_stream_content_type),
5617 	KUNIT_CASE(dm_test_fill_stream_aspect_ratio),
5618 	KUNIT_CASE(dm_test_fill_stream_encoding_from_caller_ycbcr420),
5619 	KUNIT_CASE(dm_test_fill_stream_encoding_from_caller_ycbcr422),
5620 	KUNIT_CASE(dm_test_fill_stream_encoding_from_caller_ycbcr444),
5621 	KUNIT_CASE(dm_test_fill_stream_hdmi_ep_clamps_depth),
5622 	KUNIT_CASE(dm_test_fill_stream_non_hdmi_ep_keeps_depth),
5623 	/* create_stream_for_sink */
5624 	KUNIT_CASE(dm_test_create_stream_fake_sink_success),
5625 	KUNIT_CASE(dm_test_create_stream_sets_dm_context),
5626 	KUNIT_CASE(dm_test_create_stream_virtual_signal),
5627 	KUNIT_CASE(dm_test_create_stream_scaling_src),
5628 	KUNIT_CASE(dm_test_create_stream_existing_sink),
5629 	/* amdgpu_dm_connector_detect */
5630 	KUNIT_CASE(dm_test_detect_force_on),
5631 	KUNIT_CASE(dm_test_detect_force_on_digital),
5632 	KUNIT_CASE(dm_test_detect_force_off),
5633 	KUNIT_CASE(dm_test_detect_sink_present),
5634 	KUNIT_CASE(dm_test_detect_no_sink),
5635 	/* amdgpu_dm_connector_poll */
5636 	KUNIT_CASE(dm_test_poll_dac_load_returns_cached),
5637 	/* amdgpu_dm_connector_late_register */
5638 	KUNIT_CASE(dm_test_late_register_non_dp_succeeds),
5639 	/* amdgpu_dm_connector_unregister */
5640 	KUNIT_CASE(dm_test_unregister_non_dp_noop),
5641 	/* amdgpu_dm_connector_destroy */
5642 	KUNIT_CASE(dm_test_destroy_minimal),
5643 	KUNIT_CASE(dm_test_destroy_releases_dc_sink),
5644 	KUNIT_CASE(dm_test_destroy_releases_dc_em_sink),
5645 	/* dm_encoder_helper_disable */
5646 	KUNIT_CASE(dm_test_encoder_disable_noop),
5647 	/* dm_encoder_helper_atomic_check */
5648 	KUNIT_CASE(dm_test_atomic_check_edp_native_keeps_scaling),
5649 	KUNIT_CASE(dm_test_atomic_check_lvds_non_native_enables_scaling),
5650 	KUNIT_CASE(dm_test_atomic_check_non_mst_returns_zero),
5651 	/* hdmi_cec_unset_edid */
5652 	KUNIT_CASE(dm_test_hdmi_cec_unset_edid_no_notifier),
5653 	/* create_eml_sink */
5654 	KUNIT_CASE(dm_test_create_eml_sink_no_edid),
5655 	/* handle_edid_mgmt */
5656 	KUNIT_CASE(dm_test_handle_edid_mgmt_dp_sets_link_caps),
5657 	KUNIT_CASE(dm_test_handle_edid_mgmt_non_dp_leaves_caps),
5658 	/* amdgpu_dm_connector_funcs_force */
5659 	KUNIT_CASE(dm_test_funcs_force_no_edid),
5660 	/* dm_validate_stream_and_context */
5661 	KUNIT_CASE(dm_test_validate_stream_null_stream),
5662 	/* amdgpu_dm_connector_to_encoder */
5663 	KUNIT_CASE(dm_test_to_encoder_no_encoder),
5664 	KUNIT_CASE(dm_test_to_encoder_returns_attached),
5665 	/* amdgpu_dm_get_native_mode */
5666 	KUNIT_CASE(dm_test_native_mode_no_encoder),
5667 	KUNIT_CASE(dm_test_native_mode_empty_probed_zeroes_clock),
5668 	KUNIT_CASE(dm_test_native_mode_copies_preferred),
5669 	/* amdgpu_dm_create_common_mode */
5670 	KUNIT_CASE(dm_test_create_common_mode_overrides),
5671 	/* amdgpu_dm_connector_add_common_modes */
5672 	KUNIT_CASE(dm_test_add_common_modes_non_edp_noop),
5673 	KUNIT_CASE(dm_test_add_common_modes_edp_adds),
5674 	/* amdgpu_dm_connector_ddc_get_modes */
5675 	KUNIT_CASE(dm_test_ddc_get_modes_null_edid),
5676 	/* add_fs_modes */
5677 	KUNIT_CASE(dm_test_add_fs_modes_no_preferred_mode),
5678 	/* amdgpu_dm_connector_add_freesync_modes */
5679 	KUNIT_CASE(dm_test_add_freesync_modes_null_edid_noop),
5680 	/* amdgpu_dm_i2c_func */
5681 	KUNIT_CASE(dm_test_i2c_func_returns_flags),
5682 	/* amdgpu_dm_i2c_xfer */
5683 	KUNIT_CASE(dm_test_i2c_xfer_no_ddc_pin),
5684 	/* get_amd_vsdb */
5685 	KUNIT_CASE(dm_test_get_amd_vsdb_unsupported),
5686 	KUNIT_CASE(dm_test_get_amd_vsdb_supported),
5687 	/* parse_hdmi_amd_vsdb */
5688 	KUNIT_CASE(dm_test_parse_hdmi_amd_vsdb_null_edid),
5689 	KUNIT_CASE(dm_test_parse_hdmi_amd_vsdb_no_extensions),
5690 	KUNIT_CASE(dm_test_parse_hdmi_amd_vsdb_no_cea_ext),
5691 	/* parse_edid_displayid_vrr */
5692 	KUNIT_CASE(dm_test_parse_displayid_vrr_null_edid),
5693 	KUNIT_CASE(dm_test_parse_displayid_vrr_no_displayid),
5694 	KUNIT_CASE(dm_test_parse_displayid_vrr_sets_range),
5695 	/* amdgpu_dm_connector_mode_valid */
5696 	KUNIT_CASE(dm_test_mode_valid_interlace_rejected),
5697 	KUNIT_CASE(dm_test_mode_valid_dblscan_rejected),
5698 	/* amdgpu_dm_hdmi_cec_set_edid */
5699 	KUNIT_CASE(dm_test_hdmi_cec_set_edid_no_notifier),
5700 	/* amdgpu_dm_s3_handle_hdmi_cec */
5701 	KUNIT_CASE(dm_test_s3_handle_hdmi_cec_suspend),
5702 	KUNIT_CASE(dm_test_s3_handle_hdmi_cec_resume),
5703 	/* amdgpu_dm_create_validate_stream_for_sink */
5704 	KUNIT_CASE(dm_test_create_validate_stream_null_dm_state),
5705 	/* amdgpu_dm_update_connector_after_detect */
5706 	KUNIT_CASE(dm_test_update_after_detect_mst_noop),
5707 	KUNIT_CASE(dm_test_update_after_detect_sink_unchanged),
5708 	/* amdgpu_dm_update_stream_scaling_settings */
5709 	KUNIT_CASE(dm_test_update_scaling_null_mode),
5710 	KUNIT_CASE(dm_test_update_scaling_fullscreen_default),
5711 	KUNIT_CASE(dm_test_update_scaling_rmx_full),
5712 	KUNIT_CASE(dm_test_update_scaling_rmx_aspect_pillarbox),
5713 	KUNIT_CASE(dm_test_update_scaling_rmx_aspect_letterbox),
5714 	KUNIT_CASE(dm_test_update_scaling_rmx_center),
5715 	KUNIT_CASE(dm_test_update_scaling_underscan),
5716 	{}
5717 };
5718 
5719 static struct kunit_suite amdgpu_dm_connector_test_suite = {
5720 	.name = "amdgpu_dm_connector",
5721 	.test_cases = amdgpu_dm_connector_tests,
5722 };
5723 
5724 kunit_test_suite(amdgpu_dm_connector_test_suite);
5725 
5726 MODULE_AUTHOR("AMD");
5727 MODULE_DESCRIPTION("KUnit tests for amdgpu_dm_connector");
5728 MODULE_LICENSE("Dual MIT/GPL");
5729