xref: /openbmc/linux/drivers/gpu/drm/tests/drm_cmdline_parser_test.c (revision 035c6e60074f7b5dccc90bfb64816bc82cde7239)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Bootlin
4  * Copyright (c) 2022 Maíra Canal <mairacanal@riseup.net>
5  */
6 
7 #include <kunit/test.h>
8 
9 #include <drm/drm_connector.h>
10 #include <drm/drm_kunit_helpers.h>
11 #include <drm/drm_modes.h>
12 
13 static const struct drm_connector no_connector = {};
14 
15 static void drm_test_cmdline_force_e_only(struct kunit *test)
16 {
17 	struct drm_cmdline_mode mode = { };
18 	const char *cmdline = "e";
19 
20 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
21 									  &no_connector, &mode));
22 	KUNIT_EXPECT_FALSE(test, mode.specified);
23 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
24 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
25 
26 	KUNIT_EXPECT_FALSE(test, mode.rb);
27 	KUNIT_EXPECT_FALSE(test, mode.cvt);
28 	KUNIT_EXPECT_FALSE(test, mode.interlace);
29 	KUNIT_EXPECT_FALSE(test, mode.margins);
30 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
31 }
32 
33 static void drm_test_cmdline_force_D_only_not_digital(struct kunit *test)
34 {
35 	struct drm_cmdline_mode mode = { };
36 	const char *cmdline = "D";
37 
38 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
39 									  &no_connector, &mode));
40 	KUNIT_EXPECT_FALSE(test, mode.specified);
41 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
42 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
43 
44 	KUNIT_EXPECT_FALSE(test, mode.rb);
45 	KUNIT_EXPECT_FALSE(test, mode.cvt);
46 	KUNIT_EXPECT_FALSE(test, mode.interlace);
47 	KUNIT_EXPECT_FALSE(test, mode.margins);
48 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
49 }
50 
51 static const struct drm_connector connector_hdmi = {
52 	.connector_type	= DRM_MODE_CONNECTOR_HDMIB,
53 };
54 
55 static void drm_test_cmdline_force_D_only_hdmi(struct kunit *test)
56 {
57 	struct drm_cmdline_mode mode = { };
58 	const char *cmdline = "D";
59 
60 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
61 									  &connector_hdmi, &mode));
62 	KUNIT_EXPECT_FALSE(test, mode.specified);
63 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
64 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
65 
66 	KUNIT_EXPECT_FALSE(test, mode.rb);
67 	KUNIT_EXPECT_FALSE(test, mode.cvt);
68 	KUNIT_EXPECT_FALSE(test, mode.interlace);
69 	KUNIT_EXPECT_FALSE(test, mode.margins);
70 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON_DIGITAL);
71 }
72 
73 static const struct drm_connector connector_dvi = {
74 	.connector_type	= DRM_MODE_CONNECTOR_DVII,
75 };
76 
77 static void drm_test_cmdline_force_D_only_dvi(struct kunit *test)
78 {
79 	struct drm_cmdline_mode mode = { };
80 	const char *cmdline = "D";
81 
82 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
83 									  &connector_dvi, &mode));
84 	KUNIT_EXPECT_FALSE(test, mode.specified);
85 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
86 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
87 
88 	KUNIT_EXPECT_FALSE(test, mode.rb);
89 	KUNIT_EXPECT_FALSE(test, mode.cvt);
90 	KUNIT_EXPECT_FALSE(test, mode.interlace);
91 	KUNIT_EXPECT_FALSE(test, mode.margins);
92 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON_DIGITAL);
93 }
94 
95 static void drm_test_cmdline_force_d_only(struct kunit *test)
96 {
97 	struct drm_cmdline_mode mode = { };
98 	const char *cmdline = "d";
99 
100 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
101 									  &no_connector, &mode));
102 	KUNIT_EXPECT_FALSE(test, mode.specified);
103 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
104 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
105 
106 	KUNIT_EXPECT_FALSE(test, mode.rb);
107 	KUNIT_EXPECT_FALSE(test, mode.cvt);
108 	KUNIT_EXPECT_FALSE(test, mode.interlace);
109 	KUNIT_EXPECT_FALSE(test, mode.margins);
110 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_OFF);
111 }
112 
113 static void drm_test_cmdline_res(struct kunit *test)
114 {
115 	struct drm_cmdline_mode mode = { };
116 	const char *cmdline = "720x480";
117 
118 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
119 									  &no_connector, &mode));
120 	KUNIT_EXPECT_TRUE(test, mode.specified);
121 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
122 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
123 
124 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
125 
126 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
127 
128 	KUNIT_EXPECT_FALSE(test, mode.rb);
129 	KUNIT_EXPECT_FALSE(test, mode.cvt);
130 	KUNIT_EXPECT_FALSE(test, mode.interlace);
131 	KUNIT_EXPECT_FALSE(test, mode.margins);
132 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
133 }
134 
135 static void drm_test_cmdline_res_vesa(struct kunit *test)
136 {
137 	struct drm_cmdline_mode mode = { };
138 	const char *cmdline = "720x480M";
139 
140 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
141 									  &no_connector, &mode));
142 	KUNIT_EXPECT_TRUE(test, mode.specified);
143 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
144 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
145 
146 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
147 
148 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
149 
150 	KUNIT_EXPECT_FALSE(test, mode.rb);
151 	KUNIT_EXPECT_TRUE(test, mode.cvt);
152 	KUNIT_EXPECT_FALSE(test, mode.interlace);
153 	KUNIT_EXPECT_FALSE(test, mode.margins);
154 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
155 }
156 
157 static void drm_test_cmdline_res_vesa_rblank(struct kunit *test)
158 {
159 	struct drm_cmdline_mode mode = { };
160 	const char *cmdline = "720x480MR";
161 
162 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
163 									  &no_connector, &mode));
164 	KUNIT_EXPECT_TRUE(test, mode.specified);
165 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
166 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
167 
168 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
169 
170 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
171 
172 	KUNIT_EXPECT_TRUE(test, mode.rb);
173 	KUNIT_EXPECT_TRUE(test, mode.cvt);
174 	KUNIT_EXPECT_FALSE(test, mode.interlace);
175 	KUNIT_EXPECT_FALSE(test, mode.margins);
176 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
177 }
178 
179 static void drm_test_cmdline_res_rblank(struct kunit *test)
180 {
181 	struct drm_cmdline_mode mode = { };
182 	const char *cmdline = "720x480R";
183 
184 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
185 									  &no_connector, &mode));
186 	KUNIT_EXPECT_TRUE(test, mode.specified);
187 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
188 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
189 
190 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
191 
192 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
193 
194 	KUNIT_EXPECT_TRUE(test, mode.rb);
195 	KUNIT_EXPECT_FALSE(test, mode.cvt);
196 	KUNIT_EXPECT_FALSE(test, mode.interlace);
197 	KUNIT_EXPECT_FALSE(test, mode.margins);
198 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
199 }
200 
201 static void drm_test_cmdline_res_bpp(struct kunit *test)
202 {
203 	struct drm_cmdline_mode mode = { };
204 	const char *cmdline = "720x480-24";
205 
206 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
207 									  &no_connector, &mode));
208 	KUNIT_EXPECT_TRUE(test, mode.specified);
209 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
210 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
211 
212 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
213 
214 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
215 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
216 
217 	KUNIT_EXPECT_FALSE(test, mode.rb);
218 	KUNIT_EXPECT_FALSE(test, mode.cvt);
219 	KUNIT_EXPECT_FALSE(test, mode.interlace);
220 	KUNIT_EXPECT_FALSE(test, mode.margins);
221 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
222 }
223 
224 static void drm_test_cmdline_res_refresh(struct kunit *test)
225 {
226 	struct drm_cmdline_mode mode = { };
227 	const char *cmdline = "720x480@60";
228 
229 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
230 									  &no_connector, &mode));
231 	KUNIT_EXPECT_TRUE(test, mode.specified);
232 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
233 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
234 
235 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
236 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
237 
238 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
239 
240 	KUNIT_EXPECT_FALSE(test, mode.rb);
241 	KUNIT_EXPECT_FALSE(test, mode.cvt);
242 	KUNIT_EXPECT_FALSE(test, mode.interlace);
243 	KUNIT_EXPECT_FALSE(test, mode.margins);
244 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
245 }
246 
247 static void drm_test_cmdline_res_bpp_refresh(struct kunit *test)
248 {
249 	struct drm_cmdline_mode mode = { };
250 	const char *cmdline = "720x480-24@60";
251 
252 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
253 									  &no_connector, &mode));
254 	KUNIT_EXPECT_TRUE(test, mode.specified);
255 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
256 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
257 
258 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
259 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
260 
261 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
262 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
263 
264 	KUNIT_EXPECT_FALSE(test, mode.rb);
265 	KUNIT_EXPECT_FALSE(test, mode.cvt);
266 	KUNIT_EXPECT_FALSE(test, mode.interlace);
267 	KUNIT_EXPECT_FALSE(test, mode.margins);
268 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
269 }
270 
271 static void drm_test_cmdline_res_bpp_refresh_interlaced(struct kunit *test)
272 {
273 	struct drm_cmdline_mode mode = { };
274 	const char *cmdline = "720x480-24@60i";
275 
276 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
277 									  &no_connector, &mode));
278 	KUNIT_EXPECT_TRUE(test, mode.specified);
279 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
280 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
281 
282 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
283 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
284 
285 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
286 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
287 
288 	KUNIT_EXPECT_FALSE(test, mode.rb);
289 	KUNIT_EXPECT_FALSE(test, mode.cvt);
290 	KUNIT_EXPECT_TRUE(test, mode.interlace);
291 	KUNIT_EXPECT_FALSE(test, mode.margins);
292 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
293 }
294 
295 static void drm_test_cmdline_res_bpp_refresh_margins(struct kunit *test)
296 {
297 	struct drm_cmdline_mode mode = { };
298 	const char *cmdline = "720x480-24@60m";
299 
300 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
301 									  &no_connector, &mode));
302 	KUNIT_EXPECT_TRUE(test, mode.specified);
303 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
304 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
305 
306 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
307 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
308 
309 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
310 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
311 
312 	KUNIT_EXPECT_FALSE(test, mode.rb);
313 	KUNIT_EXPECT_FALSE(test, mode.cvt);
314 	KUNIT_EXPECT_FALSE(test, mode.interlace);
315 	KUNIT_EXPECT_TRUE(test, mode.margins);
316 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
317 }
318 
319 static void drm_test_cmdline_res_bpp_refresh_force_off(struct kunit *test)
320 {
321 	struct drm_cmdline_mode mode = { };
322 	const char *cmdline = "720x480-24@60d";
323 
324 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
325 									  &no_connector, &mode));
326 	KUNIT_EXPECT_TRUE(test, mode.specified);
327 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
328 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
329 
330 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
331 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
332 
333 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
334 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
335 
336 	KUNIT_EXPECT_FALSE(test, mode.rb);
337 	KUNIT_EXPECT_FALSE(test, mode.cvt);
338 	KUNIT_EXPECT_FALSE(test, mode.interlace);
339 	KUNIT_EXPECT_FALSE(test, mode.margins);
340 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_OFF);
341 }
342 
343 static void drm_test_cmdline_res_bpp_refresh_force_on(struct kunit *test)
344 {
345 	struct drm_cmdline_mode mode = { };
346 	const char *cmdline = "720x480-24@60e";
347 
348 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
349 									  &no_connector, &mode));
350 	KUNIT_EXPECT_TRUE(test, mode.specified);
351 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
352 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
353 
354 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
355 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
356 
357 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
358 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
359 
360 	KUNIT_EXPECT_FALSE(test, mode.rb);
361 	KUNIT_EXPECT_FALSE(test, mode.cvt);
362 	KUNIT_EXPECT_FALSE(test, mode.interlace);
363 	KUNIT_EXPECT_FALSE(test, mode.margins);
364 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
365 }
366 
367 static void drm_test_cmdline_res_bpp_refresh_force_on_analog(struct kunit *test)
368 {
369 	struct drm_cmdline_mode mode = { };
370 	const char *cmdline = "720x480-24@60D";
371 
372 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
373 									  &no_connector, &mode));
374 	KUNIT_EXPECT_TRUE(test, mode.specified);
375 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
376 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
377 
378 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
379 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
380 
381 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
382 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
383 
384 	KUNIT_EXPECT_FALSE(test, mode.rb);
385 	KUNIT_EXPECT_FALSE(test, mode.cvt);
386 	KUNIT_EXPECT_FALSE(test, mode.interlace);
387 	KUNIT_EXPECT_FALSE(test, mode.margins);
388 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
389 }
390 
391 static void drm_test_cmdline_res_bpp_refresh_force_on_digital(struct kunit *test)
392 {
393 	struct drm_cmdline_mode mode = { };
394 	static const struct drm_connector connector = {
395 		.connector_type = DRM_MODE_CONNECTOR_DVII,
396 	};
397 	const char *cmdline = "720x480-24@60D";
398 
399 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
400 									  &connector, &mode));
401 	KUNIT_EXPECT_TRUE(test, mode.specified);
402 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
403 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
404 
405 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
406 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
407 
408 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
409 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
410 
411 	KUNIT_EXPECT_FALSE(test, mode.rb);
412 	KUNIT_EXPECT_FALSE(test, mode.cvt);
413 	KUNIT_EXPECT_FALSE(test, mode.interlace);
414 	KUNIT_EXPECT_FALSE(test, mode.margins);
415 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON_DIGITAL);
416 }
417 
418 static void drm_test_cmdline_res_bpp_refresh_interlaced_margins_force_on(struct kunit *test)
419 {
420 	struct drm_cmdline_mode mode = { };
421 	const char *cmdline = "720x480-24@60ime";
422 
423 	KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
424 									  &no_connector, &mode));
425 	KUNIT_EXPECT_TRUE(test, mode.specified);
426 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
427 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
428 
429 	KUNIT_EXPECT_TRUE(test, mode.refresh_specified);
430 	KUNIT_EXPECT_EQ(test, mode.refresh, 60);
431 
432 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
433 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
434 
435 	KUNIT_EXPECT_FALSE(test, mode.rb);
436 	KUNIT_EXPECT_FALSE(test, mode.cvt);
437 	KUNIT_EXPECT_TRUE(test, mode.interlace);
438 	KUNIT_EXPECT_TRUE(test, mode.margins);
439 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
440 }
441 
442 static void drm_test_cmdline_res_margins_force_on(struct kunit *test)
443 {
444 	struct drm_cmdline_mode mode = { };
445 	const char *cmdline = "720x480me";
446 
447 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
448 									  &no_connector, &mode));
449 	KUNIT_EXPECT_TRUE(test, mode.specified);
450 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
451 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
452 
453 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
454 
455 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
456 
457 	KUNIT_EXPECT_FALSE(test, mode.rb);
458 	KUNIT_EXPECT_FALSE(test, mode.cvt);
459 	KUNIT_EXPECT_FALSE(test, mode.interlace);
460 	KUNIT_EXPECT_TRUE(test, mode.margins);
461 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
462 }
463 
464 static void drm_test_cmdline_res_vesa_margins(struct kunit *test)
465 {
466 	struct drm_cmdline_mode mode = { };
467 	const char *cmdline = "720x480Mm";
468 
469 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
470 									  &no_connector, &mode));
471 	KUNIT_EXPECT_TRUE(test, mode.specified);
472 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
473 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
474 
475 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
476 
477 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
478 
479 	KUNIT_EXPECT_FALSE(test, mode.rb);
480 	KUNIT_EXPECT_TRUE(test, mode.cvt);
481 	KUNIT_EXPECT_FALSE(test, mode.interlace);
482 	KUNIT_EXPECT_TRUE(test, mode.margins);
483 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
484 }
485 
486 static void drm_test_cmdline_name(struct kunit *test)
487 {
488 	struct drm_cmdline_mode mode = { };
489 	const char *cmdline = "NTSC";
490 
491 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
492 									  &no_connector, &mode));
493 	KUNIT_EXPECT_STREQ(test, mode.name, "NTSC");
494 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
495 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
496 }
497 
498 static void drm_test_cmdline_name_bpp(struct kunit *test)
499 {
500 	struct drm_cmdline_mode mode = { };
501 	const char *cmdline = "NTSC-24";
502 
503 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
504 									  &no_connector, &mode));
505 	KUNIT_EXPECT_STREQ(test, mode.name, "NTSC");
506 
507 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
508 
509 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
510 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
511 }
512 
513 static void drm_test_cmdline_name_option(struct kunit *test)
514 {
515 	struct drm_cmdline_mode mode = { };
516 	const char *cmdline = "NTSC,rotate=180";
517 
518 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
519 									  &no_connector, &mode));
520 	KUNIT_EXPECT_TRUE(test, mode.specified);
521 	KUNIT_EXPECT_STREQ(test, mode.name, "NTSC");
522 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180);
523 }
524 
525 static void drm_test_cmdline_name_bpp_option(struct kunit *test)
526 {
527 	struct drm_cmdline_mode mode = { };
528 	const char *cmdline = "NTSC-24,rotate=180";
529 
530 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
531 									  &no_connector, &mode));
532 	KUNIT_EXPECT_TRUE(test, mode.specified);
533 	KUNIT_EXPECT_STREQ(test, mode.name, "NTSC");
534 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180);
535 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
536 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
537 }
538 
539 static void drm_test_cmdline_rotate_0(struct kunit *test)
540 {
541 	struct drm_cmdline_mode mode = { };
542 	const char *cmdline = "720x480,rotate=0";
543 
544 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
545 									  &no_connector, &mode));
546 	KUNIT_EXPECT_TRUE(test, mode.specified);
547 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
548 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
549 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_0);
550 
551 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
552 
553 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
554 
555 	KUNIT_EXPECT_FALSE(test, mode.rb);
556 	KUNIT_EXPECT_FALSE(test, mode.cvt);
557 	KUNIT_EXPECT_FALSE(test, mode.interlace);
558 	KUNIT_EXPECT_FALSE(test, mode.margins);
559 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
560 }
561 
562 static void drm_test_cmdline_rotate_90(struct kunit *test)
563 {
564 	struct drm_cmdline_mode mode = { };
565 	const char *cmdline = "720x480,rotate=90";
566 
567 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
568 									  &no_connector, &mode));
569 	KUNIT_EXPECT_TRUE(test, mode.specified);
570 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
571 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
572 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_90);
573 
574 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
575 
576 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
577 
578 	KUNIT_EXPECT_FALSE(test, mode.rb);
579 	KUNIT_EXPECT_FALSE(test, mode.cvt);
580 	KUNIT_EXPECT_FALSE(test, mode.interlace);
581 	KUNIT_EXPECT_FALSE(test, mode.margins);
582 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
583 }
584 
585 static void drm_test_cmdline_rotate_180(struct kunit *test)
586 {
587 	struct drm_cmdline_mode mode = { };
588 	const char *cmdline = "720x480,rotate=180";
589 
590 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
591 									  &no_connector, &mode));
592 	KUNIT_EXPECT_TRUE(test, mode.specified);
593 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
594 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
595 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180);
596 
597 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
598 
599 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
600 
601 	KUNIT_EXPECT_FALSE(test, mode.rb);
602 	KUNIT_EXPECT_FALSE(test, mode.cvt);
603 	KUNIT_EXPECT_FALSE(test, mode.interlace);
604 	KUNIT_EXPECT_FALSE(test, mode.margins);
605 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
606 }
607 
608 static void drm_test_cmdline_rotate_270(struct kunit *test)
609 {
610 	struct drm_cmdline_mode mode = { };
611 	const char *cmdline = "720x480,rotate=270";
612 
613 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
614 									  &no_connector, &mode));
615 	KUNIT_EXPECT_TRUE(test, mode.specified);
616 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
617 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
618 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_270);
619 
620 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
621 
622 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
623 
624 	KUNIT_EXPECT_FALSE(test, mode.rb);
625 	KUNIT_EXPECT_FALSE(test, mode.cvt);
626 	KUNIT_EXPECT_FALSE(test, mode.interlace);
627 	KUNIT_EXPECT_FALSE(test, mode.margins);
628 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
629 }
630 
631 static void drm_test_cmdline_hmirror(struct kunit *test)
632 {
633 	struct drm_cmdline_mode mode = { };
634 	const char *cmdline = "720x480,reflect_x";
635 
636 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
637 									  &no_connector, &mode));
638 	KUNIT_EXPECT_TRUE(test, mode.specified);
639 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
640 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
641 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X));
642 
643 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
644 
645 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
646 
647 	KUNIT_EXPECT_FALSE(test, mode.rb);
648 	KUNIT_EXPECT_FALSE(test, mode.cvt);
649 	KUNIT_EXPECT_FALSE(test, mode.interlace);
650 	KUNIT_EXPECT_FALSE(test, mode.margins);
651 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
652 }
653 
654 static void drm_test_cmdline_vmirror(struct kunit *test)
655 {
656 	struct drm_cmdline_mode mode = { };
657 	const char *cmdline = "720x480,reflect_y";
658 
659 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
660 									  &no_connector, &mode));
661 	KUNIT_EXPECT_TRUE(test, mode.specified);
662 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
663 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
664 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y));
665 
666 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
667 
668 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
669 
670 	KUNIT_EXPECT_FALSE(test, mode.rb);
671 	KUNIT_EXPECT_FALSE(test, mode.cvt);
672 	KUNIT_EXPECT_FALSE(test, mode.interlace);
673 	KUNIT_EXPECT_FALSE(test, mode.margins);
674 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
675 }
676 
677 static void drm_test_cmdline_margin_options(struct kunit *test)
678 {
679 	struct drm_cmdline_mode mode = { };
680 	const char *cmdline =
681 		"720x480,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42";
682 
683 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
684 									  &no_connector, &mode));
685 	KUNIT_EXPECT_TRUE(test, mode.specified);
686 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
687 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
688 	KUNIT_EXPECT_EQ(test, mode.tv_margins.right, 14);
689 	KUNIT_EXPECT_EQ(test, mode.tv_margins.left, 24);
690 	KUNIT_EXPECT_EQ(test, mode.tv_margins.bottom, 36);
691 	KUNIT_EXPECT_EQ(test, mode.tv_margins.top, 42);
692 
693 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
694 
695 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
696 
697 	KUNIT_EXPECT_FALSE(test, mode.rb);
698 	KUNIT_EXPECT_FALSE(test, mode.cvt);
699 	KUNIT_EXPECT_FALSE(test, mode.interlace);
700 	KUNIT_EXPECT_FALSE(test, mode.margins);
701 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
702 }
703 
704 static void drm_test_cmdline_multiple_options(struct kunit *test)
705 {
706 	struct drm_cmdline_mode mode = { };
707 	const char *cmdline = "720x480,rotate=270,reflect_x";
708 
709 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
710 									  &no_connector, &mode));
711 	KUNIT_EXPECT_TRUE(test, mode.specified);
712 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
713 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
714 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, (DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X));
715 
716 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
717 
718 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
719 
720 	KUNIT_EXPECT_FALSE(test, mode.rb);
721 	KUNIT_EXPECT_FALSE(test, mode.cvt);
722 	KUNIT_EXPECT_FALSE(test, mode.interlace);
723 	KUNIT_EXPECT_FALSE(test, mode.margins);
724 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
725 }
726 
727 static void drm_test_cmdline_bpp_extra_and_option(struct kunit *test)
728 {
729 	struct drm_cmdline_mode mode = { };
730 	const char *cmdline = "720x480-24e,rotate=180";
731 
732 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
733 									  &no_connector, &mode));
734 	KUNIT_EXPECT_TRUE(test, mode.specified);
735 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
736 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
737 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180);
738 
739 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
740 
741 	KUNIT_EXPECT_TRUE(test, mode.bpp_specified);
742 	KUNIT_EXPECT_EQ(test, mode.bpp, 24);
743 
744 	KUNIT_EXPECT_FALSE(test, mode.rb);
745 	KUNIT_EXPECT_FALSE(test, mode.cvt);
746 	KUNIT_EXPECT_FALSE(test, mode.interlace);
747 	KUNIT_EXPECT_FALSE(test, mode.margins);
748 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
749 }
750 
751 static void drm_test_cmdline_extra_and_option(struct kunit *test)
752 {
753 	struct drm_cmdline_mode mode = { };
754 	const char *cmdline = "720x480e,rotate=180";
755 
756 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
757 									  &no_connector, &mode));
758 	KUNIT_EXPECT_TRUE(test, mode.specified);
759 	KUNIT_EXPECT_EQ(test, mode.xres, 720);
760 	KUNIT_EXPECT_EQ(test, mode.yres, 480);
761 	KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180);
762 
763 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
764 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
765 
766 	KUNIT_EXPECT_FALSE(test, mode.rb);
767 	KUNIT_EXPECT_FALSE(test, mode.cvt);
768 	KUNIT_EXPECT_FALSE(test, mode.interlace);
769 	KUNIT_EXPECT_FALSE(test, mode.margins);
770 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
771 }
772 
773 static void drm_test_cmdline_freestanding_options(struct kunit *test)
774 {
775 	struct drm_cmdline_mode mode = { };
776 	const char *cmdline = "margin_right=14,margin_left=24,margin_bottom=36,margin_top=42";
777 
778 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
779 									  &no_connector, &mode));
780 	KUNIT_EXPECT_FALSE(test, mode.specified);
781 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
782 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
783 
784 	KUNIT_EXPECT_EQ(test, mode.tv_margins.right, 14);
785 	KUNIT_EXPECT_EQ(test, mode.tv_margins.left, 24);
786 	KUNIT_EXPECT_EQ(test, mode.tv_margins.bottom, 36);
787 	KUNIT_EXPECT_EQ(test, mode.tv_margins.top, 42);
788 
789 	KUNIT_EXPECT_FALSE(test, mode.rb);
790 	KUNIT_EXPECT_FALSE(test, mode.cvt);
791 	KUNIT_EXPECT_FALSE(test, mode.interlace);
792 	KUNIT_EXPECT_FALSE(test, mode.margins);
793 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
794 }
795 
796 static void drm_test_cmdline_freestanding_force_e_and_options(struct kunit *test)
797 {
798 	struct drm_cmdline_mode mode = { };
799 	const char *cmdline = "e,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42";
800 
801 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
802 									  &no_connector, &mode));
803 	KUNIT_EXPECT_FALSE(test, mode.specified);
804 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
805 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
806 
807 	KUNIT_EXPECT_EQ(test, mode.tv_margins.right, 14);
808 	KUNIT_EXPECT_EQ(test, mode.tv_margins.left, 24);
809 	KUNIT_EXPECT_EQ(test, mode.tv_margins.bottom, 36);
810 	KUNIT_EXPECT_EQ(test, mode.tv_margins.top, 42);
811 
812 	KUNIT_EXPECT_FALSE(test, mode.rb);
813 	KUNIT_EXPECT_FALSE(test, mode.cvt);
814 	KUNIT_EXPECT_FALSE(test, mode.interlace);
815 	KUNIT_EXPECT_FALSE(test, mode.margins);
816 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
817 }
818 
819 static void drm_test_cmdline_panel_orientation(struct kunit *test)
820 {
821 	struct drm_cmdline_mode mode = { };
822 	const char *cmdline = "panel_orientation=upside_down";
823 
824 	KUNIT_ASSERT_TRUE(test, drm_mode_parse_command_line_for_connector(cmdline,
825 									  &no_connector, &mode));
826 	KUNIT_EXPECT_FALSE(test, mode.specified);
827 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
828 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
829 
830 	KUNIT_EXPECT_EQ(test, mode.panel_orientation, DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP);
831 
832 	KUNIT_EXPECT_FALSE(test, mode.rb);
833 	KUNIT_EXPECT_FALSE(test, mode.cvt);
834 	KUNIT_EXPECT_FALSE(test, mode.interlace);
835 	KUNIT_EXPECT_FALSE(test, mode.margins);
836 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
837 }
838 
839 struct drm_cmdline_invalid_test {
840 	const char *name;
841 	const char *cmdline;
842 };
843 
844 static void drm_test_cmdline_invalid(struct kunit *test)
845 {
846 	const struct drm_cmdline_invalid_test *params = test->param_value;
847 	struct drm_cmdline_mode mode = { };
848 
849 	KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector(params->cmdline,
850 									   &no_connector,
851 									   &mode));
852 }
853 
854 static const struct drm_cmdline_invalid_test drm_cmdline_invalid_tests[] = {
855 	{
856 		.name = "margin_only",
857 		.cmdline = "m",
858 	},
859 	{
860 		.name = "interlace_only",
861 		.cmdline = "i",
862 	},
863 	{
864 		.name = "res_missing_x",
865 		.cmdline = "x480",
866 	},
867 	{
868 		.name = "res_missing_y",
869 		.cmdline = "1024x",
870 	},
871 	{
872 		.name = "res_bad_y",
873 		.cmdline = "1024xtest",
874 	},
875 	{
876 		.name = "res_missing_y_bpp",
877 		.cmdline = "1024x-24",
878 	},
879 	{
880 		.name = "res_bad_bpp",
881 		.cmdline = "720x480-test",
882 	},
883 	{
884 		.name = "res_bad_refresh",
885 		.cmdline = "720x480@refresh",
886 	},
887 	{
888 		.name = "res_bpp_refresh_force_on_off",
889 		.cmdline = "720x480-24@60de",
890 	},
891 	{
892 		.name = "res_invalid_mode",
893 		.cmdline = "720x480f",
894 	},
895 	{
896 		.name = "res_bpp_wrong_place_mode",
897 		.cmdline = "720x480e-24",
898 	},
899 	{
900 		.name = "name_bpp_refresh",
901 		.cmdline = "NTSC-24@60",
902 	},
903 	{
904 		.name = "name_refresh",
905 		.cmdline = "NTSC@60",
906 	},
907 	{
908 		.name = "name_refresh_wrong_mode",
909 		.cmdline = "NTSC@60m",
910 	},
911 	{
912 		.name = "name_refresh_invalid_mode",
913 		.cmdline = "NTSC@60f",
914 	},
915 	{
916 		.name = "rotate_multiple",
917 		.cmdline = "720x480,rotate=0,rotate=90",
918 	},
919 	{
920 		.name = "rotate_invalid_val",
921 		.cmdline = "720x480,rotate=42",
922 	},
923 	{
924 		.name = "rotate_truncated",
925 		.cmdline = "720x480,rotate=",
926 	},
927 	{
928 		.name = "invalid_option",
929 		.cmdline = "720x480,test=42",
930 	},
931 	{
932 		.name = "invalid_tv_option",
933 		.cmdline = "720x480i,tv_mode=invalid",
934 	},
935 	{
936 		.name = "truncated_tv_option",
937 		.cmdline = "720x480i,tv_mode=NTS",
938 	},
939 };
940 
941 static void drm_cmdline_invalid_desc(const struct drm_cmdline_invalid_test *t,
942 				     char *desc)
943 {
944 	sprintf(desc, "%s", t->name);
945 }
946 
947 KUNIT_ARRAY_PARAM(drm_cmdline_invalid, drm_cmdline_invalid_tests, drm_cmdline_invalid_desc);
948 
949 struct drm_cmdline_tv_option_test {
950 	const char *name;
951 	const char *cmdline;
952 	struct drm_display_mode *(*mode_fn)(struct drm_device *dev);
953 	enum drm_connector_tv_mode tv_mode;
954 };
955 
956 static void drm_test_cmdline_tv_options(struct kunit *test)
957 {
958 	const struct drm_cmdline_tv_option_test *params = test->param_value;
959 	struct drm_display_mode *expected_mode;
960 	struct drm_cmdline_mode mode = { };
961 	int ret;
962 
963 	expected_mode = params->mode_fn(NULL);
964 	KUNIT_ASSERT_NOT_NULL(test, expected_mode);
965 
966 	ret = drm_kunit_add_mode_destroy_action(test, expected_mode);
967 	KUNIT_ASSERT_EQ(test, ret, 0);
968 
969 	KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector(params->cmdline,
970 									  &no_connector, &mode));
971 	KUNIT_EXPECT_TRUE(test, mode.specified);
972 	KUNIT_EXPECT_EQ(test, mode.xres, expected_mode->hdisplay);
973 	KUNIT_EXPECT_EQ(test, mode.yres, expected_mode->vdisplay);
974 	KUNIT_EXPECT_EQ(test, mode.tv_mode, params->tv_mode);
975 
976 	KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
977 
978 	KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
979 
980 	KUNIT_EXPECT_FALSE(test, mode.rb);
981 	KUNIT_EXPECT_FALSE(test, mode.cvt);
982 	KUNIT_EXPECT_EQ(test, mode.interlace, !!(expected_mode->flags & DRM_MODE_FLAG_INTERLACE));
983 	KUNIT_EXPECT_FALSE(test, mode.margins);
984 	KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
985 }
986 
987 #define TV_OPT_TEST(_opt, _cmdline, _mode_fn)		\
988 	{						\
989 		.name = #_opt,				\
990 		.cmdline = _cmdline,			\
991 		.mode_fn = _mode_fn,			\
992 		.tv_mode = DRM_MODE_TV_MODE_ ## _opt,	\
993 	}
994 
995 static const struct drm_cmdline_tv_option_test drm_cmdline_tv_option_tests[] = {
996 	TV_OPT_TEST(NTSC, "720x480i,tv_mode=NTSC", drm_mode_analog_ntsc_480i),
997 	TV_OPT_TEST(NTSC_443, "720x480i,tv_mode=NTSC-443", drm_mode_analog_ntsc_480i),
998 	TV_OPT_TEST(NTSC_J, "720x480i,tv_mode=NTSC-J", drm_mode_analog_ntsc_480i),
999 	TV_OPT_TEST(PAL, "720x576i,tv_mode=PAL", drm_mode_analog_pal_576i),
1000 	TV_OPT_TEST(PAL_M, "720x480i,tv_mode=PAL-M", drm_mode_analog_ntsc_480i),
1001 	TV_OPT_TEST(PAL_N, "720x576i,tv_mode=PAL-N", drm_mode_analog_pal_576i),
1002 	TV_OPT_TEST(SECAM, "720x576i,tv_mode=SECAM", drm_mode_analog_pal_576i),
1003 };
1004 
1005 static void drm_cmdline_tv_option_desc(const struct drm_cmdline_tv_option_test *t,
1006 				       char *desc)
1007 {
1008 	sprintf(desc, "%s", t->name);
1009 }
1010 
1011 KUNIT_ARRAY_PARAM(drm_cmdline_tv_option,
1012 		  drm_cmdline_tv_option_tests,
1013 		  drm_cmdline_tv_option_desc);
1014 
1015 static struct kunit_case drm_cmdline_parser_tests[] = {
1016 	KUNIT_CASE(drm_test_cmdline_force_d_only),
1017 	KUNIT_CASE(drm_test_cmdline_force_D_only_dvi),
1018 	KUNIT_CASE(drm_test_cmdline_force_D_only_hdmi),
1019 	KUNIT_CASE(drm_test_cmdline_force_D_only_not_digital),
1020 	KUNIT_CASE(drm_test_cmdline_force_e_only),
1021 	KUNIT_CASE(drm_test_cmdline_res),
1022 	KUNIT_CASE(drm_test_cmdline_res_vesa),
1023 	KUNIT_CASE(drm_test_cmdline_res_vesa_rblank),
1024 	KUNIT_CASE(drm_test_cmdline_res_rblank),
1025 	KUNIT_CASE(drm_test_cmdline_res_bpp),
1026 	KUNIT_CASE(drm_test_cmdline_res_refresh),
1027 	KUNIT_CASE(drm_test_cmdline_res_bpp_refresh),
1028 	KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_interlaced),
1029 	KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_margins),
1030 	KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_force_off),
1031 	KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_force_on),
1032 	KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_force_on_analog),
1033 	KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_force_on_digital),
1034 	KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_interlaced_margins_force_on),
1035 	KUNIT_CASE(drm_test_cmdline_res_margins_force_on),
1036 	KUNIT_CASE(drm_test_cmdline_res_vesa_margins),
1037 	KUNIT_CASE(drm_test_cmdline_name),
1038 	KUNIT_CASE(drm_test_cmdline_name_bpp),
1039 	KUNIT_CASE(drm_test_cmdline_name_option),
1040 	KUNIT_CASE(drm_test_cmdline_name_bpp_option),
1041 	KUNIT_CASE(drm_test_cmdline_rotate_0),
1042 	KUNIT_CASE(drm_test_cmdline_rotate_90),
1043 	KUNIT_CASE(drm_test_cmdline_rotate_180),
1044 	KUNIT_CASE(drm_test_cmdline_rotate_270),
1045 	KUNIT_CASE(drm_test_cmdline_hmirror),
1046 	KUNIT_CASE(drm_test_cmdline_vmirror),
1047 	KUNIT_CASE(drm_test_cmdline_margin_options),
1048 	KUNIT_CASE(drm_test_cmdline_multiple_options),
1049 	KUNIT_CASE(drm_test_cmdline_bpp_extra_and_option),
1050 	KUNIT_CASE(drm_test_cmdline_extra_and_option),
1051 	KUNIT_CASE(drm_test_cmdline_freestanding_options),
1052 	KUNIT_CASE(drm_test_cmdline_freestanding_force_e_and_options),
1053 	KUNIT_CASE(drm_test_cmdline_panel_orientation),
1054 	KUNIT_CASE_PARAM(drm_test_cmdline_invalid, drm_cmdline_invalid_gen_params),
1055 	KUNIT_CASE_PARAM(drm_test_cmdline_tv_options, drm_cmdline_tv_option_gen_params),
1056 	{}
1057 };
1058 
1059 static struct kunit_suite drm_cmdline_parser_test_suite = {
1060 	.name = "drm_cmdline_parser",
1061 	.test_cases = drm_cmdline_parser_tests
1062 };
1063 
1064 kunit_test_suite(drm_cmdline_parser_test_suite);
1065 
1066 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@bootlin.com>");
1067 MODULE_LICENSE("GPL");
1068