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