1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 Bootlin
4 */
5
6#define pr_fmt(fmt) "drm_cmdline: " fmt
7
8#include <linux/kernel.h>
9#include <linux/module.h>
10
11#include <drm/drm_connector.h>
12#include <drm/drm_modes.h>
13
14#define TESTS "drm_cmdline_selftests.h"
15#include "drm_selftest.h"
16#include "test-drm_modeset_common.h"
17
18static const struct drm_connector no_connector = {};
19
20static int drm_cmdline_test_force_e_only(void *ignored)
21{
22	struct drm_cmdline_mode mode = { };
23
24	FAIL_ON(!drm_mode_parse_command_line_for_connector("e",
25							   &no_connector,
26							   &mode));
27	FAIL_ON(mode.specified);
28	FAIL_ON(mode.refresh_specified);
29	FAIL_ON(mode.bpp_specified);
30
31	FAIL_ON(mode.rb);
32	FAIL_ON(mode.cvt);
33	FAIL_ON(mode.interlace);
34	FAIL_ON(mode.margins);
35	FAIL_ON(mode.force != DRM_FORCE_ON);
36
37	return 0;
38}
39
40static int drm_cmdline_test_force_D_only_not_digital(void *ignored)
41{
42	struct drm_cmdline_mode mode = { };
43
44	FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
45							   &no_connector,
46							   &mode));
47	FAIL_ON(mode.specified);
48	FAIL_ON(mode.refresh_specified);
49	FAIL_ON(mode.bpp_specified);
50
51	FAIL_ON(mode.rb);
52	FAIL_ON(mode.cvt);
53	FAIL_ON(mode.interlace);
54	FAIL_ON(mode.margins);
55	FAIL_ON(mode.force != DRM_FORCE_ON);
56
57	return 0;
58}
59
60static const struct drm_connector connector_hdmi = {
61	.connector_type	= DRM_MODE_CONNECTOR_HDMIB,
62};
63
64static int drm_cmdline_test_force_D_only_hdmi(void *ignored)
65{
66	struct drm_cmdline_mode mode = { };
67
68	FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
69							   &connector_hdmi,
70							   &mode));
71	FAIL_ON(mode.specified);
72	FAIL_ON(mode.refresh_specified);
73	FAIL_ON(mode.bpp_specified);
74
75	FAIL_ON(mode.rb);
76	FAIL_ON(mode.cvt);
77	FAIL_ON(mode.interlace);
78	FAIL_ON(mode.margins);
79	FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
80
81	return 0;
82}
83
84static const struct drm_connector connector_dvi = {
85	.connector_type	= DRM_MODE_CONNECTOR_DVII,
86};
87
88static int drm_cmdline_test_force_D_only_dvi(void *ignored)
89{
90	struct drm_cmdline_mode mode = { };
91
92	FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
93							   &connector_dvi,
94							   &mode));
95	FAIL_ON(mode.specified);
96	FAIL_ON(mode.refresh_specified);
97	FAIL_ON(mode.bpp_specified);
98
99	FAIL_ON(mode.rb);
100	FAIL_ON(mode.cvt);
101	FAIL_ON(mode.interlace);
102	FAIL_ON(mode.margins);
103	FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
104
105	return 0;
106}
107
108static int drm_cmdline_test_force_d_only(void *ignored)
109{
110	struct drm_cmdline_mode mode = { };
111
112	FAIL_ON(!drm_mode_parse_command_line_for_connector("d",
113							   &no_connector,
114							   &mode));
115	FAIL_ON(mode.specified);
116	FAIL_ON(mode.refresh_specified);
117	FAIL_ON(mode.bpp_specified);
118
119	FAIL_ON(mode.rb);
120	FAIL_ON(mode.cvt);
121	FAIL_ON(mode.interlace);
122	FAIL_ON(mode.margins);
123	FAIL_ON(mode.force != DRM_FORCE_OFF);
124
125	return 0;
126}
127
128static int drm_cmdline_test_margin_only(void *ignored)
129{
130	struct drm_cmdline_mode mode = { };
131
132	FAIL_ON(drm_mode_parse_command_line_for_connector("m",
133							  &no_connector,
134							  &mode));
135
136	return 0;
137}
138
139static int drm_cmdline_test_interlace_only(void *ignored)
140{
141	struct drm_cmdline_mode mode = { };
142
143	FAIL_ON(drm_mode_parse_command_line_for_connector("i",
144							  &no_connector,
145							  &mode));
146
147	return 0;
148}
149
150static int drm_cmdline_test_res(void *ignored)
151{
152	struct drm_cmdline_mode mode = { };
153
154	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480",
155							   &no_connector,
156							   &mode));
157	FAIL_ON(!mode.specified);
158	FAIL_ON(mode.xres != 720);
159	FAIL_ON(mode.yres != 480);
160
161	FAIL_ON(mode.refresh_specified);
162
163	FAIL_ON(mode.bpp_specified);
164
165	FAIL_ON(mode.rb);
166	FAIL_ON(mode.cvt);
167	FAIL_ON(mode.interlace);
168	FAIL_ON(mode.margins);
169	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
170
171	return 0;
172}
173
174static int drm_cmdline_test_res_missing_x(void *ignored)
175{
176	struct drm_cmdline_mode mode = { };
177
178	FAIL_ON(drm_mode_parse_command_line_for_connector("x480",
179							  &no_connector,
180							  &mode));
181
182	return 0;
183}
184
185static int drm_cmdline_test_res_missing_y(void *ignored)
186{
187	struct drm_cmdline_mode mode = { };
188
189	FAIL_ON(drm_mode_parse_command_line_for_connector("1024x",
190							  &no_connector,
191							  &mode));
192
193	return 0;
194}
195
196static int drm_cmdline_test_res_bad_y(void *ignored)
197{
198	struct drm_cmdline_mode mode = { };
199
200	FAIL_ON(drm_mode_parse_command_line_for_connector("1024xtest",
201							  &no_connector,
202							  &mode));
203
204	return 0;
205}
206
207static int drm_cmdline_test_res_missing_y_bpp(void *ignored)
208{
209	struct drm_cmdline_mode mode = { };
210
211	FAIL_ON(drm_mode_parse_command_line_for_connector("1024x-24",
212							  &no_connector,
213							  &mode));
214
215	return 0;
216}
217
218static int drm_cmdline_test_res_vesa(void *ignored)
219{
220	struct drm_cmdline_mode mode = { };
221
222	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480M",
223							   &no_connector,
224							   &mode));
225	FAIL_ON(!mode.specified);
226	FAIL_ON(mode.xres != 720);
227	FAIL_ON(mode.yres != 480);
228
229	FAIL_ON(mode.refresh_specified);
230
231	FAIL_ON(mode.bpp_specified);
232
233	FAIL_ON(mode.rb);
234	FAIL_ON(!mode.cvt);
235	FAIL_ON(mode.interlace);
236	FAIL_ON(mode.margins);
237	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
238
239	return 0;
240}
241
242static int drm_cmdline_test_res_vesa_rblank(void *ignored)
243{
244	struct drm_cmdline_mode mode = { };
245
246	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480MR",
247							   &no_connector,
248							   &mode));
249	FAIL_ON(!mode.specified);
250	FAIL_ON(mode.xres != 720);
251	FAIL_ON(mode.yres != 480);
252
253	FAIL_ON(mode.refresh_specified);
254
255	FAIL_ON(mode.bpp_specified);
256
257	FAIL_ON(!mode.rb);
258	FAIL_ON(!mode.cvt);
259	FAIL_ON(mode.interlace);
260	FAIL_ON(mode.margins);
261	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
262
263	return 0;
264}
265
266static int drm_cmdline_test_res_rblank(void *ignored)
267{
268	struct drm_cmdline_mode mode = { };
269
270	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480R",
271							   &no_connector,
272							   &mode));
273	FAIL_ON(!mode.specified);
274	FAIL_ON(mode.xres != 720);
275	FAIL_ON(mode.yres != 480);
276
277	FAIL_ON(mode.refresh_specified);
278
279	FAIL_ON(mode.bpp_specified);
280
281	FAIL_ON(!mode.rb);
282	FAIL_ON(mode.cvt);
283	FAIL_ON(mode.interlace);
284	FAIL_ON(mode.margins);
285	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
286
287	return 0;
288}
289
290static int drm_cmdline_test_res_bpp(void *ignored)
291{
292	struct drm_cmdline_mode mode = { };
293
294	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24",
295							   &no_connector,
296							   &mode));
297	FAIL_ON(!mode.specified);
298	FAIL_ON(mode.xres != 720);
299	FAIL_ON(mode.yres != 480);
300
301	FAIL_ON(mode.refresh_specified);
302
303	FAIL_ON(!mode.bpp_specified);
304	FAIL_ON(mode.bpp != 24);
305
306	FAIL_ON(mode.rb);
307	FAIL_ON(mode.cvt);
308	FAIL_ON(mode.interlace);
309	FAIL_ON(mode.margins);
310	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
311
312	return 0;
313}
314
315static int drm_cmdline_test_res_bad_bpp(void *ignored)
316{
317	struct drm_cmdline_mode mode = { };
318
319	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480-test",
320							  &no_connector,
321							  &mode));
322
323	return 0;
324}
325
326static int drm_cmdline_test_res_refresh(void *ignored)
327{
328	struct drm_cmdline_mode mode = { };
329
330	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480@60",
331							   &no_connector,
332							   &mode));
333	FAIL_ON(!mode.specified);
334	FAIL_ON(mode.xres != 720);
335	FAIL_ON(mode.yres != 480);
336
337	FAIL_ON(!mode.refresh_specified);
338	FAIL_ON(mode.refresh != 60);
339
340	FAIL_ON(mode.bpp_specified);
341
342	FAIL_ON(mode.rb);
343	FAIL_ON(mode.cvt);
344	FAIL_ON(mode.interlace);
345	FAIL_ON(mode.margins);
346	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
347
348	return 0;
349}
350
351static int drm_cmdline_test_res_bad_refresh(void *ignored)
352{
353	struct drm_cmdline_mode mode = { };
354
355	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480@refresh",
356							  &no_connector,
357							  &mode));
358
359	return 0;
360}
361
362static int drm_cmdline_test_res_bpp_refresh(void *ignored)
363{
364	struct drm_cmdline_mode mode = { };
365
366	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60",
367							   &no_connector,
368							   &mode));
369	FAIL_ON(!mode.specified);
370	FAIL_ON(mode.xres != 720);
371	FAIL_ON(mode.yres != 480);
372
373	FAIL_ON(!mode.refresh_specified);
374	FAIL_ON(mode.refresh != 60);
375
376	FAIL_ON(!mode.bpp_specified);
377	FAIL_ON(mode.bpp != 24);
378
379	FAIL_ON(mode.rb);
380	FAIL_ON(mode.cvt);
381	FAIL_ON(mode.interlace);
382	FAIL_ON(mode.margins);
383	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
384
385	return 0;
386}
387
388static int drm_cmdline_test_res_bpp_refresh_interlaced(void *ignored)
389{
390	struct drm_cmdline_mode mode = { };
391
392	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60i",
393							   &no_connector,
394							   &mode));
395	FAIL_ON(!mode.specified);
396	FAIL_ON(mode.xres != 720);
397	FAIL_ON(mode.yres != 480);
398
399	FAIL_ON(!mode.refresh_specified);
400	FAIL_ON(mode.refresh != 60);
401
402	FAIL_ON(!mode.bpp_specified);
403	FAIL_ON(mode.bpp != 24);
404
405	FAIL_ON(mode.rb);
406	FAIL_ON(mode.cvt);
407	FAIL_ON(!mode.interlace);
408	FAIL_ON(mode.margins);
409	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
410
411	return 0;
412}
413
414static int drm_cmdline_test_res_bpp_refresh_margins(void *ignored)
415{
416	struct drm_cmdline_mode mode = { };
417
418	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60m",
419							   &no_connector,
420							   &mode));
421	FAIL_ON(!mode.specified);
422	FAIL_ON(mode.xres != 720);
423	FAIL_ON(mode.yres != 480);
424
425	FAIL_ON(!mode.refresh_specified);
426	FAIL_ON(mode.refresh != 60);
427
428	FAIL_ON(!mode.bpp_specified);
429	FAIL_ON(mode.bpp != 24);
430
431	FAIL_ON(mode.rb);
432	FAIL_ON(mode.cvt);
433	FAIL_ON(mode.interlace);
434	FAIL_ON(!mode.margins);
435	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
436
437	return 0;
438}
439
440static int drm_cmdline_test_res_bpp_refresh_force_off(void *ignored)
441{
442	struct drm_cmdline_mode mode = { };
443
444	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60d",
445							   &no_connector,
446							   &mode));
447	FAIL_ON(!mode.specified);
448	FAIL_ON(mode.xres != 720);
449	FAIL_ON(mode.yres != 480);
450
451	FAIL_ON(!mode.refresh_specified);
452	FAIL_ON(mode.refresh != 60);
453
454	FAIL_ON(!mode.bpp_specified);
455	FAIL_ON(mode.bpp != 24);
456
457	FAIL_ON(mode.rb);
458	FAIL_ON(mode.cvt);
459	FAIL_ON(mode.interlace);
460	FAIL_ON(mode.margins);
461	FAIL_ON(mode.force != DRM_FORCE_OFF);
462
463	return 0;
464}
465
466static int drm_cmdline_test_res_bpp_refresh_force_on_off(void *ignored)
467{
468	struct drm_cmdline_mode mode = { };
469
470	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480-24@60de",
471							  &no_connector,
472							  &mode));
473
474	return 0;
475}
476
477static int drm_cmdline_test_res_bpp_refresh_force_on(void *ignored)
478{
479	struct drm_cmdline_mode mode = { };
480
481	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60e",
482							   &no_connector,
483							   &mode));
484	FAIL_ON(!mode.specified);
485	FAIL_ON(mode.xres != 720);
486	FAIL_ON(mode.yres != 480);
487
488	FAIL_ON(!mode.refresh_specified);
489	FAIL_ON(mode.refresh != 60);
490
491	FAIL_ON(!mode.bpp_specified);
492	FAIL_ON(mode.bpp != 24);
493
494	FAIL_ON(mode.rb);
495	FAIL_ON(mode.cvt);
496	FAIL_ON(mode.interlace);
497	FAIL_ON(mode.margins);
498	FAIL_ON(mode.force != DRM_FORCE_ON);
499
500	return 0;
501}
502
503static int drm_cmdline_test_res_bpp_refresh_force_on_analog(void *ignored)
504{
505	struct drm_cmdline_mode mode = { };
506
507	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60D",
508							   &no_connector,
509							   &mode));
510	FAIL_ON(!mode.specified);
511	FAIL_ON(mode.xres != 720);
512	FAIL_ON(mode.yres != 480);
513
514	FAIL_ON(!mode.refresh_specified);
515	FAIL_ON(mode.refresh != 60);
516
517	FAIL_ON(!mode.bpp_specified);
518	FAIL_ON(mode.bpp != 24);
519
520	FAIL_ON(mode.rb);
521	FAIL_ON(mode.cvt);
522	FAIL_ON(mode.interlace);
523	FAIL_ON(mode.margins);
524	FAIL_ON(mode.force != DRM_FORCE_ON);
525
526	return 0;
527}
528
529static int drm_cmdline_test_res_bpp_refresh_force_on_digital(void *ignored)
530{
531	struct drm_cmdline_mode mode = { };
532	static const struct drm_connector connector = {
533		.connector_type = DRM_MODE_CONNECTOR_DVII,
534	};
535
536	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60D",
537							   &connector,
538							   &mode));
539	FAIL_ON(!mode.specified);
540	FAIL_ON(mode.xres != 720);
541	FAIL_ON(mode.yres != 480);
542
543	FAIL_ON(!mode.refresh_specified);
544	FAIL_ON(mode.refresh != 60);
545
546	FAIL_ON(!mode.bpp_specified);
547	FAIL_ON(mode.bpp != 24);
548
549	FAIL_ON(mode.rb);
550	FAIL_ON(mode.cvt);
551	FAIL_ON(mode.interlace);
552	FAIL_ON(mode.margins);
553	FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
554
555	return 0;
556}
557
558static int drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on(void *ignored)
559{
560	struct drm_cmdline_mode mode = { };
561
562	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60ime",
563							   &no_connector,
564							   &mode));
565	FAIL_ON(!mode.specified);
566	FAIL_ON(mode.xres != 720);
567	FAIL_ON(mode.yres != 480);
568
569	FAIL_ON(!mode.refresh_specified);
570	FAIL_ON(mode.refresh != 60);
571
572	FAIL_ON(!mode.bpp_specified);
573	FAIL_ON(mode.bpp != 24);
574
575	FAIL_ON(mode.rb);
576	FAIL_ON(mode.cvt);
577	FAIL_ON(!mode.interlace);
578	FAIL_ON(!mode.margins);
579	FAIL_ON(mode.force != DRM_FORCE_ON);
580
581	return 0;
582}
583
584static int drm_cmdline_test_res_margins_force_on(void *ignored)
585{
586	struct drm_cmdline_mode mode = { };
587
588	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480me",
589							   &no_connector,
590							   &mode));
591	FAIL_ON(!mode.specified);
592	FAIL_ON(mode.xres != 720);
593	FAIL_ON(mode.yres != 480);
594
595	FAIL_ON(mode.refresh_specified);
596
597	FAIL_ON(mode.bpp_specified);
598
599	FAIL_ON(mode.rb);
600	FAIL_ON(mode.cvt);
601	FAIL_ON(mode.interlace);
602	FAIL_ON(!mode.margins);
603	FAIL_ON(mode.force != DRM_FORCE_ON);
604
605	return 0;
606}
607
608static int drm_cmdline_test_res_vesa_margins(void *ignored)
609{
610	struct drm_cmdline_mode mode = { };
611
612	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480Mm",
613							   &no_connector,
614							   &mode));
615	FAIL_ON(!mode.specified);
616	FAIL_ON(mode.xres != 720);
617	FAIL_ON(mode.yres != 480);
618
619	FAIL_ON(mode.refresh_specified);
620
621	FAIL_ON(mode.bpp_specified);
622
623	FAIL_ON(mode.rb);
624	FAIL_ON(!mode.cvt);
625	FAIL_ON(mode.interlace);
626	FAIL_ON(!mode.margins);
627	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
628
629	return 0;
630}
631
632static int drm_cmdline_test_res_invalid_mode(void *ignored)
633{
634	struct drm_cmdline_mode mode = { };
635
636	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480f",
637							  &no_connector,
638							  &mode));
639
640	return 0;
641}
642
643static int drm_cmdline_test_res_bpp_wrong_place_mode(void *ignored)
644{
645	struct drm_cmdline_mode mode = { };
646
647	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480e-24",
648							  &no_connector,
649							  &mode));
650
651	return 0;
652}
653
654static int drm_cmdline_test_name(void *ignored)
655{
656	struct drm_cmdline_mode mode = { };
657
658	FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC",
659							   &no_connector,
660							   &mode));
661	FAIL_ON(strcmp(mode.name, "NTSC"));
662	FAIL_ON(mode.refresh_specified);
663	FAIL_ON(mode.bpp_specified);
664
665	return 0;
666}
667
668static int drm_cmdline_test_name_bpp(void *ignored)
669{
670	struct drm_cmdline_mode mode = { };
671
672	FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC-24",
673							   &no_connector,
674							   &mode));
675	FAIL_ON(strcmp(mode.name, "NTSC"));
676
677	FAIL_ON(mode.refresh_specified);
678
679	FAIL_ON(!mode.bpp_specified);
680	FAIL_ON(mode.bpp != 24);
681
682	return 0;
683}
684
685static int drm_cmdline_test_name_bpp_refresh(void *ignored)
686{
687	struct drm_cmdline_mode mode = { };
688
689	FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC-24@60",
690							  &no_connector,
691							  &mode));
692
693	return 0;
694}
695
696static int drm_cmdline_test_name_refresh(void *ignored)
697{
698	struct drm_cmdline_mode mode = { };
699
700	FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60",
701							  &no_connector,
702							  &mode));
703
704	return 0;
705}
706
707static int drm_cmdline_test_name_refresh_wrong_mode(void *ignored)
708{
709	struct drm_cmdline_mode mode = { };
710
711	FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60m",
712							  &no_connector,
713							  &mode));
714
715	return 0;
716}
717
718static int drm_cmdline_test_name_refresh_invalid_mode(void *ignored)
719{
720	struct drm_cmdline_mode mode = { };
721
722	FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60f",
723							  &no_connector,
724							  &mode));
725
726	return 0;
727}
728
729static int drm_cmdline_test_name_option(void *ignored)
730{
731	struct drm_cmdline_mode mode = { };
732
733	FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC,rotate=180",
734							   &no_connector,
735							   &mode));
736	FAIL_ON(!mode.specified);
737	FAIL_ON(strcmp(mode.name, "NTSC"));
738	FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180);
739
740	return 0;
741}
742
743static int drm_cmdline_test_name_bpp_option(void *ignored)
744{
745	struct drm_cmdline_mode mode = { };
746
747	FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC-24,rotate=180",
748							   &no_connector,
749							   &mode));
750	FAIL_ON(!mode.specified);
751	FAIL_ON(strcmp(mode.name, "NTSC"));
752	FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180);
753	FAIL_ON(!mode.bpp_specified);
754	FAIL_ON(mode.bpp != 24);
755
756	return 0;
757}
758
759static int drm_cmdline_test_rotate_0(void *ignored)
760{
761	struct drm_cmdline_mode mode = { };
762
763	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=0",
764							   &no_connector,
765							   &mode));
766	FAIL_ON(!mode.specified);
767	FAIL_ON(mode.xres != 720);
768	FAIL_ON(mode.yres != 480);
769	FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_0);
770
771	FAIL_ON(mode.refresh_specified);
772
773	FAIL_ON(mode.bpp_specified);
774
775	FAIL_ON(mode.rb);
776	FAIL_ON(mode.cvt);
777	FAIL_ON(mode.interlace);
778	FAIL_ON(mode.margins);
779	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
780
781	return 0;
782}
783
784static int drm_cmdline_test_rotate_90(void *ignored)
785{
786	struct drm_cmdline_mode mode = { };
787
788	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=90",
789							   &no_connector,
790							   &mode));
791	FAIL_ON(!mode.specified);
792	FAIL_ON(mode.xres != 720);
793	FAIL_ON(mode.yres != 480);
794	FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_90);
795
796	FAIL_ON(mode.refresh_specified);
797
798	FAIL_ON(mode.bpp_specified);
799
800	FAIL_ON(mode.rb);
801	FAIL_ON(mode.cvt);
802	FAIL_ON(mode.interlace);
803	FAIL_ON(mode.margins);
804	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
805
806	return 0;
807}
808
809static int drm_cmdline_test_rotate_180(void *ignored)
810{
811	struct drm_cmdline_mode mode = { };
812
813	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=180",
814							   &no_connector,
815							   &mode));
816	FAIL_ON(!mode.specified);
817	FAIL_ON(mode.xres != 720);
818	FAIL_ON(mode.yres != 480);
819	FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180);
820
821	FAIL_ON(mode.refresh_specified);
822
823	FAIL_ON(mode.bpp_specified);
824
825	FAIL_ON(mode.rb);
826	FAIL_ON(mode.cvt);
827	FAIL_ON(mode.interlace);
828	FAIL_ON(mode.margins);
829	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
830
831	return 0;
832}
833
834static int drm_cmdline_test_rotate_270(void *ignored)
835{
836	struct drm_cmdline_mode mode = { };
837
838	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=270",
839							   &no_connector,
840							   &mode));
841	FAIL_ON(!mode.specified);
842	FAIL_ON(mode.xres != 720);
843	FAIL_ON(mode.yres != 480);
844	FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_270);
845
846	FAIL_ON(mode.refresh_specified);
847
848	FAIL_ON(mode.bpp_specified);
849
850	FAIL_ON(mode.rb);
851	FAIL_ON(mode.cvt);
852	FAIL_ON(mode.interlace);
853	FAIL_ON(mode.margins);
854	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
855
856	return 0;
857}
858
859static int drm_cmdline_test_rotate_multiple(void *ignored)
860{
861	struct drm_cmdline_mode mode = { };
862
863	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=0,rotate=90",
864							  &no_connector,
865							  &mode));
866
867	return 0;
868}
869
870static int drm_cmdline_test_rotate_invalid_val(void *ignored)
871{
872	struct drm_cmdline_mode mode = { };
873
874	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=42",
875							  &no_connector,
876							  &mode));
877
878	return 0;
879}
880
881static int drm_cmdline_test_rotate_truncated(void *ignored)
882{
883	struct drm_cmdline_mode mode = { };
884
885	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=",
886							  &no_connector,
887							  &mode));
888
889	return 0;
890}
891
892static int drm_cmdline_test_hmirror(void *ignored)
893{
894	struct drm_cmdline_mode mode = { };
895
896	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,reflect_x",
897							   &no_connector,
898							   &mode));
899	FAIL_ON(!mode.specified);
900	FAIL_ON(mode.xres != 720);
901	FAIL_ON(mode.yres != 480);
902	FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X));
903
904	FAIL_ON(mode.refresh_specified);
905
906	FAIL_ON(mode.bpp_specified);
907
908	FAIL_ON(mode.rb);
909	FAIL_ON(mode.cvt);
910	FAIL_ON(mode.interlace);
911	FAIL_ON(mode.margins);
912	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
913
914	return 0;
915}
916
917static int drm_cmdline_test_vmirror(void *ignored)
918{
919	struct drm_cmdline_mode mode = { };
920
921	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,reflect_y",
922							   &no_connector,
923							   &mode));
924	FAIL_ON(!mode.specified);
925	FAIL_ON(mode.xres != 720);
926	FAIL_ON(mode.yres != 480);
927	FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y));
928
929	FAIL_ON(mode.refresh_specified);
930
931	FAIL_ON(mode.bpp_specified);
932
933	FAIL_ON(mode.rb);
934	FAIL_ON(mode.cvt);
935	FAIL_ON(mode.interlace);
936	FAIL_ON(mode.margins);
937	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
938
939	return 0;
940}
941
942static int drm_cmdline_test_margin_options(void *ignored)
943{
944	struct drm_cmdline_mode mode = { };
945
946	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42",
947							   &no_connector,
948							   &mode));
949	FAIL_ON(!mode.specified);
950	FAIL_ON(mode.xres != 720);
951	FAIL_ON(mode.yres != 480);
952	FAIL_ON(mode.tv_margins.right != 14);
953	FAIL_ON(mode.tv_margins.left != 24);
954	FAIL_ON(mode.tv_margins.bottom != 36);
955	FAIL_ON(mode.tv_margins.top != 42);
956
957	FAIL_ON(mode.refresh_specified);
958
959	FAIL_ON(mode.bpp_specified);
960
961	FAIL_ON(mode.rb);
962	FAIL_ON(mode.cvt);
963	FAIL_ON(mode.interlace);
964	FAIL_ON(mode.margins);
965	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
966
967	return 0;
968}
969
970static int drm_cmdline_test_multiple_options(void *ignored)
971{
972	struct drm_cmdline_mode mode = { };
973
974	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=270,reflect_x",
975							   &no_connector,
976							   &mode));
977	FAIL_ON(!mode.specified);
978	FAIL_ON(mode.xres != 720);
979	FAIL_ON(mode.yres != 480);
980	FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X));
981
982	FAIL_ON(mode.refresh_specified);
983
984	FAIL_ON(mode.bpp_specified);
985
986	FAIL_ON(mode.rb);
987	FAIL_ON(mode.cvt);
988	FAIL_ON(mode.interlace);
989	FAIL_ON(mode.margins);
990	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
991
992	return 0;
993}
994
995static int drm_cmdline_test_invalid_option(void *ignored)
996{
997	struct drm_cmdline_mode mode = { };
998
999	FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,test=42",
1000							  &no_connector,
1001							  &mode));
1002
1003	return 0;
1004}
1005
1006static int drm_cmdline_test_bpp_extra_and_option(void *ignored)
1007{
1008	struct drm_cmdline_mode mode = { };
1009
1010	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24e,rotate=180",
1011							   &no_connector,
1012							   &mode));
1013	FAIL_ON(!mode.specified);
1014	FAIL_ON(mode.xres != 720);
1015	FAIL_ON(mode.yres != 480);
1016	FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180);
1017
1018	FAIL_ON(mode.refresh_specified);
1019
1020	FAIL_ON(!mode.bpp_specified);
1021	FAIL_ON(mode.bpp != 24);
1022
1023	FAIL_ON(mode.rb);
1024	FAIL_ON(mode.cvt);
1025	FAIL_ON(mode.interlace);
1026	FAIL_ON(mode.margins);
1027	FAIL_ON(mode.force != DRM_FORCE_ON);
1028
1029	return 0;
1030}
1031
1032static int drm_cmdline_test_extra_and_option(void *ignored)
1033{
1034	struct drm_cmdline_mode mode = { };
1035
1036	FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480e,rotate=180",
1037							   &no_connector,
1038							   &mode));
1039	FAIL_ON(!mode.specified);
1040	FAIL_ON(mode.xres != 720);
1041	FAIL_ON(mode.yres != 480);
1042	FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180);
1043
1044	FAIL_ON(mode.refresh_specified);
1045	FAIL_ON(mode.bpp_specified);
1046
1047	FAIL_ON(mode.rb);
1048	FAIL_ON(mode.cvt);
1049	FAIL_ON(mode.interlace);
1050	FAIL_ON(mode.margins);
1051	FAIL_ON(mode.force != DRM_FORCE_ON);
1052
1053	return 0;
1054}
1055
1056static int drm_cmdline_test_freestanding_options(void *ignored)
1057{
1058	struct drm_cmdline_mode mode = { };
1059
1060	FAIL_ON(!drm_mode_parse_command_line_for_connector("margin_right=14,margin_left=24,margin_bottom=36,margin_top=42",
1061							   &no_connector,
1062							   &mode));
1063	FAIL_ON(mode.specified);
1064	FAIL_ON(mode.refresh_specified);
1065	FAIL_ON(mode.bpp_specified);
1066
1067	FAIL_ON(mode.tv_margins.right != 14);
1068	FAIL_ON(mode.tv_margins.left != 24);
1069	FAIL_ON(mode.tv_margins.bottom != 36);
1070	FAIL_ON(mode.tv_margins.top != 42);
1071
1072	FAIL_ON(mode.rb);
1073	FAIL_ON(mode.cvt);
1074	FAIL_ON(mode.interlace);
1075	FAIL_ON(mode.margins);
1076	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
1077
1078	return 0;
1079}
1080
1081static int drm_cmdline_test_freestanding_force_e_and_options(void *ignored)
1082{
1083	struct drm_cmdline_mode mode = { };
1084
1085	FAIL_ON(!drm_mode_parse_command_line_for_connector("e,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42",
1086							   &no_connector,
1087							   &mode));
1088	FAIL_ON(mode.specified);
1089	FAIL_ON(mode.refresh_specified);
1090	FAIL_ON(mode.bpp_specified);
1091
1092	FAIL_ON(mode.tv_margins.right != 14);
1093	FAIL_ON(mode.tv_margins.left != 24);
1094	FAIL_ON(mode.tv_margins.bottom != 36);
1095	FAIL_ON(mode.tv_margins.top != 42);
1096
1097	FAIL_ON(mode.rb);
1098	FAIL_ON(mode.cvt);
1099	FAIL_ON(mode.interlace);
1100	FAIL_ON(mode.margins);
1101	FAIL_ON(mode.force != DRM_FORCE_ON);
1102
1103	return 0;
1104}
1105
1106static int drm_cmdline_test_panel_orientation(void *ignored)
1107{
1108	struct drm_cmdline_mode mode = { };
1109
1110	FAIL_ON(!drm_mode_parse_command_line_for_connector("panel_orientation=upside_down",
1111							   &no_connector,
1112							   &mode));
1113	FAIL_ON(mode.specified);
1114	FAIL_ON(mode.refresh_specified);
1115	FAIL_ON(mode.bpp_specified);
1116
1117	FAIL_ON(mode.panel_orientation != DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP);
1118
1119	FAIL_ON(mode.rb);
1120	FAIL_ON(mode.cvt);
1121	FAIL_ON(mode.interlace);
1122	FAIL_ON(mode.margins);
1123	FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
1124
1125	return 0;
1126}
1127
1128#include "drm_selftest.c"
1129
1130static int __init test_drm_cmdline_init(void)
1131{
1132	int err;
1133
1134	err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
1135
1136	return err > 0 ? 0 : err;
1137}
1138module_init(test_drm_cmdline_init);
1139
1140MODULE_AUTHOR("Maxime Ripard <maxime.ripard@bootlin.com>");
1141MODULE_LICENSE("GPL");
1142