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