blob: 6d6ea21ca97499c4530a80f81f183e3c2ad71f87 [file] [log] [blame]
Ville Syrjälä8c1566e2013-10-29 18:17:39 +02001/*
2 * Copyright © 2014 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25#include <assert.h>
26#include <fcntl.h>
27#include <getopt.h>
28#include <unistd.h>
29#include <signal.h>
30#include <stdbool.h>
31#include <stdlib.h>
32#include <stdio.h>
33#include <err.h>
34#include <string.h>
35#include "intel_chipset.h"
36#include "intel_io.h"
37#include "igt_debugfs.h"
38#include "drmtest.h"
Thomas Woodbe4710a2014-10-10 11:20:35 +010039#include "igt_aux.h"
Ville Syrjälä8c1566e2013-10-29 18:17:39 +020040
41enum test {
42 TEST_INVALID,
43 TEST_PIPESTAT,
44 TEST_IIR,
45 TEST_IIR_GEN2,
46 TEST_IIR_GEN3,
47 TEST_DEIIR,
48 TEST_FRAMECOUNT,
49 TEST_FRAMECOUNT_GEN3,
50 TEST_FRAMECOUNT_G4X,
51 TEST_FLIPCOUNT,
52 TEST_PAN,
53 TEST_FLIP,
54 TEST_SURFLIVE,
55 TEST_WRAP,
56 TEST_FIELD,
57};
58
59static uint32_t vlv_offset;
60
61static volatile bool quit;
62
63static void sighandler(int x)
64{
65 quit = true;
66}
67
68static uint16_t read_reg_16(uint32_t reg)
69{
Jani Nikula33c2e8b2015-04-28 13:25:35 +030070 return INREG16(vlv_offset + reg);
Ville Syrjälä8c1566e2013-10-29 18:17:39 +020071}
72
73static uint32_t read_reg(uint32_t reg)
74{
Jani Nikula33c2e8b2015-04-28 13:25:35 +030075 return INREG(vlv_offset + reg);
Ville Syrjälä8c1566e2013-10-29 18:17:39 +020076}
77
78static void write_reg_16(uint32_t reg, uint16_t val)
79{
Jani Nikula33c2e8b2015-04-28 13:25:35 +030080 OUTREG16(vlv_offset + reg, val);
Ville Syrjälä8c1566e2013-10-29 18:17:39 +020081}
82
83static void write_reg(uint32_t reg, uint32_t val)
84{
Jani Nikula33c2e8b2015-04-28 13:25:35 +030085 OUTREG(vlv_offset + reg, val);
Ville Syrjälä8c1566e2013-10-29 18:17:39 +020086}
87
88static int pipe_to_plane(uint32_t devid, int pipe)
89{
90 if (!IS_GEN2(devid) && !IS_GEN3(devid))
91 return pipe;
92
93 switch (pipe) {
94 case 0:
95 if ((read_reg(DSPACNTR) & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_B)
96 return 1;
97 return 0;
98 case 1:
99 if ((read_reg(DSPACNTR) & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_A)
100 return 0;
101 return 1;
102 }
103
104 assert(0);
105
106 return 0;
107}
108
109static uint32_t dspoffset_reg(uint32_t devid, int pipe)
110{
111 bool use_tileoff;
112
113 pipe = pipe_to_plane(devid, pipe);
114
115 if (IS_GEN2(devid) || IS_GEN3(devid))
116 use_tileoff = false;
117 if (IS_HASWELL(devid) || IS_BROADWELL(devid))
118 use_tileoff = true;
119 else {
120 switch (pipe) {
121 case 0:
122 use_tileoff = read_reg(DSPACNTR) & DISPLAY_PLANE_TILED;
123 break;
124 case 1:
125 use_tileoff = read_reg(DSPBCNTR) & DISPLAY_PLANE_TILED;
126 break;
127 case 2:
128 use_tileoff = read_reg(DSPCCNTR) & DISPLAY_PLANE_TILED;
129 break;
130 }
131 }
132
133 if (use_tileoff) {
134 switch (pipe) {
135 case 0:
136 return DSPATILEOFF;
137 case 1:
138 return DSPBTILEOFF;
139 case 2:
140 return DSPCTILEOFF;
141 }
142 } else {
143 switch (pipe) {
144 case 0:
145 return DSPABASE;
146 case 1:
147 return DSPBBASE;
148 case 2:
149 return DSPCBASE;
150 }
151 }
152
153 assert(0);
154
155 return 0;
156}
157
158static uint32_t dspsurf_reg(uint32_t devid, int pipe)
159{
160 pipe = pipe_to_plane(devid, pipe);
161
162 if (IS_GEN2(devid) || IS_GEN3(devid)) {
163 switch (pipe) {
164 case 0:
165 return DSPABASE;
166 case 1:
167 return DSPBBASE;
168 case 2:
169 return DSPCBASE;
170 }
171 } else {
172 switch (pipe) {
173 case 0:
174 return DSPASURF;
175 case 1:
176 return DSPBSURF;
177 case 2:
178 return DSPCSURF;
179 }
180 }
181
182 assert(0);
183
184 return 0;
185}
186
187static uint32_t dsl_reg(int pipe)
188{
189 switch (pipe) {
190 case 0:
191 return PIPEA_DSL;
192 case 1:
193 return PIPEB_DSL;
194 case 2:
195 return PIPEC_DSL;
196 }
197
198 assert(0);
199
200 return 0;
201}
202
203static void poll_pixel_pipestat(int pipe, int bit, uint32_t *min, uint32_t *max, const int count)
204{
205 uint32_t pix, pix1, pix2, iir, iir1, iir2, iir_bit, iir_mask;
206 int i = 0;
207
208 switch (pipe) {
209 case 0:
210 pix = PIPEAFRAMEPIXEL;
211 iir_bit = 1 << bit;
212 iir = PIPEASTAT;
213 break;
214 case 1:
215 pix = PIPEBFRAMEPIXEL;
216 iir_bit = 1 << bit;
217 iir = PIPEBSTAT;
218 break;
219 default:
220 return;
221 }
222
223 iir_mask = read_reg(iir) & 0x7fff0000;
224
225 write_reg(iir, iir_mask | iir_bit);
226
227 while (!quit) {
228 pix1 = read_reg(pix);
229 iir1 = read_reg(iir);
230 iir2 = read_reg(iir);
231 pix2 = read_reg(pix);
232
233 if (!(iir2 & iir_bit))
234 continue;
235
236 if (iir1 & iir_bit) {
237 write_reg(iir, iir_mask | iir_bit);
238 continue;
239 }
240
241 pix1 &= PIPE_PIXEL_MASK;
242 pix2 &= PIPE_PIXEL_MASK;
243
244 min[i] = pix1;
245 max[i] = pix2;
246 if (++i >= count)
247 break;
248 }
249}
250
251static void poll_pixel_iir_gen3(int pipe, int bit, uint32_t *min, uint32_t *max, const int count)
252{
253 uint32_t pix, pix1, pix2, iir1, iir2, imr_save, ier_save;
254 int i = 0;
255
256 bit = 1 << bit;
257
258 switch (pipe) {
259 case 0:
260 pix = PIPEAFRAMEPIXEL;
261 break;
262 case 1:
263 pix = PIPEBFRAMEPIXEL;
264 break;
265 default:
266 return;
267 }
268
269 imr_save = read_reg(IMR);
270 ier_save = read_reg(IER);
271
272 write_reg(IER, ier_save & ~bit);
273 write_reg(IMR, imr_save & ~bit);
274
275 write_reg(IIR, bit);
276
277 while (!quit) {
278 pix1 = read_reg(pix);
279 iir1 = read_reg(IIR);
280 iir2 = read_reg(IIR);
281 pix2 = read_reg(pix);
282
283 if (!(iir2 & bit))
284 continue;
285
286 write_reg(IIR, bit);
287
288 if (iir1 & bit)
289 continue;
290
291 pix1 &= PIPE_PIXEL_MASK;
292 pix2 &= PIPE_PIXEL_MASK;
293
294 min[i] = pix1;
295 max[i] = pix2;
296 if (++i >= count)
297 break;
298 }
299
300 write_reg(IMR, imr_save);
301 write_reg(IER, ier_save);
302}
303
304static void poll_pixel_framecount_gen3(int pipe, uint32_t *min, uint32_t *max, const int count)
305{
306 uint32_t pix, pix1, pix2, frm1, frm2;
307 int i = 0;
308
309 switch (pipe) {
310 case 0:
311 pix = PIPEAFRAMEPIXEL;
312 break;
313 case 1:
314 pix = PIPEBFRAMEPIXEL;
315 break;
316 default:
317 return;
318 }
319
320 while (!quit) {
321 pix1 = read_reg(pix);
322 pix2 = read_reg(pix);
323
324 frm1 = pix1 >> 24;
325 frm2 = pix2 >> 24;
326
327 if (frm1 + 1 != frm2)
328 continue;
329
330 pix1 &= PIPE_PIXEL_MASK;
331 pix2 &= PIPE_PIXEL_MASK;
332
333 min[i] = pix1;
334 max[i] = pix2;
335 if (++i >= count)
336 break;
337 }
338}
339
340static void poll_pixel_pan(uint32_t devid, int pipe, int target_pixel, int target_fuzz,
341 uint32_t *min, uint32_t *max, const int count)
342{
343 uint32_t pix, pix1 = 0, pix2 = 0;
344 uint32_t saved, surf = 0;
345 int i = 0;
346
347 switch (pipe) {
348 case 0:
349 pix = PIPEAFRAMEPIXEL;
350 break;
351 case 1:
352 pix = PIPEBFRAMEPIXEL;
353 break;
354 default:
355 return;
356 }
357
358 surf = dspoffset_reg(devid, pipe);
359
360 saved = read_reg(surf);
361
362 while (!quit) {
363 while (!quit){
364 pix1 = read_reg(pix) & PIPE_PIXEL_MASK;
365 if (pix1 == target_pixel)
366 break;
367 }
368
369 write_reg(surf, saved+256);
370
371 while (!quit){
372 pix2 = read_reg(pix) & PIPE_PIXEL_MASK;
373 if (pix2 >= target_pixel + target_fuzz)
374 break;
375 }
376
377 write_reg(surf, saved);
378
379 min[i] = pix1;
380 max[i] = pix2;
381 if (++i >= count)
382 break;
383 }
384
385 write_reg(surf, saved);
386}
387
388static void poll_pixel_flip(uint32_t devid, int pipe, int target_pixel, int target_fuzz,
389 uint32_t *min, uint32_t *max, const int count)
390{
391 uint32_t pix, pix1, pix2;
392 uint32_t saved, surf = 0;
393 int i = 0;
394
395 switch (pipe) {
396 case 0:
397 pix = PIPEAFRAMEPIXEL;
398 case 1:
399 pix = PIPEBFRAMEPIXEL;
400 default:
401 return;
402 }
403
404 surf = dspsurf_reg(devid, pipe);
405
406 saved = read_reg(surf);
407
408 while (!quit) {
409 while (!quit){
410 pix1 = read_reg(pix) & PIPE_PIXEL_MASK;
411 if (pix1 == target_pixel)
412 break;
413 }
414
415 write_reg(surf, saved+4096);
416
417 while (!quit){
418 pix2 = read_reg(pix) & PIPE_PIXEL_MASK;
419 if (pix2 >= target_pixel + target_fuzz)
420 break;
421 }
422
423 write_reg(surf, saved);
424
425 min[i] = pix1;
426 max[i] = pix2;
427 if (++i >= count)
428 break;
429 }
430
431 write_reg(surf, saved);
432}
433
434static void poll_pixel_wrap(int pipe, uint32_t *min, uint32_t *max, const int count)
435{
436 uint32_t pix, pix1, pix2;
437 int i = 0;
438
439 switch (pipe) {
440 case 0:
441 pix = PIPEAFRAMEPIXEL;
442 break;
443 case 1:
444 pix = PIPEBFRAMEPIXEL;
445 break;
446 default:
447 return;
448 }
449
450 while (!quit) {
451 pix1 = read_reg(pix);
452 pix2 = read_reg(pix);
453
454 pix1 &= PIPE_PIXEL_MASK;
455 pix2 &= PIPE_PIXEL_MASK;
456
457 if (pix2 >= pix1)
458 continue;
459
460 min[i] = pix1;
461 max[i] = pix2;
462 if (++i >= count)
463 break;
464 }
465}
466
467static void poll_dsl_pipestat(int pipe, int bit,
468 uint32_t *min, uint32_t *max, const int count)
469{
470 uint32_t dsl, dsl1, dsl2, iir, iir1, iir2, iir_bit, iir_mask;
471 bool field1, field2;
472 int i[2] = {};
473
474 switch (pipe) {
475 case 0:
476 iir_bit = 1 << bit;
477 iir = PIPEASTAT;
478 break;
479 case 1:
480 iir_bit = 1 << bit;
481 iir = PIPEBSTAT;
482 break;
483 default:
484 return;
485 }
486
487 dsl = dsl_reg(pipe);
488
489 iir_mask = read_reg(iir) & 0x7fff0000;
490
491 write_reg(iir, iir_mask | iir_bit);
492
493 while (!quit) {
494 dsl1 = read_reg(dsl);
495 iir1 = read_reg(iir);
496 iir2 = read_reg(iir);
497 dsl2 = read_reg(dsl);
498
499 field1 = dsl1 & 0x80000000;
500 field2 = dsl2 & 0x80000000;
501 dsl1 &= ~0x80000000;
502 dsl2 &= ~0x80000000;
503
504 if (!(iir2 & iir_bit))
505 continue;
506
507 if (iir1 & iir_bit) {
508 write_reg(iir, iir_mask | iir_bit);
509 continue;
510 }
511
512 if (field1 != field2)
513 printf("fields are different (%u:%u -> %u:%u)\n",
514 field1, dsl1, field2, dsl2);
515
516 min[field1*count+i[field1]] = dsl1;
517 max[field1*count+i[field1]] = dsl2;
518 if (++i[field1] >= count)
519 break;
520 }
521}
522
523static void poll_dsl_iir_gen2(int pipe, int bit,
524 uint32_t *min, uint32_t *max, const int count)
525{
526 uint32_t dsl, dsl1, dsl2, iir1, iir2, imr_save, ier_save;
527 bool field1, field2;
528 int i[2] = {};
529
530 bit = 1 << bit;
531
532 dsl = dsl_reg(pipe);
533
534 imr_save = read_reg_16(IMR);
535 ier_save = read_reg_16(IER);
536
537 write_reg_16(IER, ier_save & ~bit);
538 write_reg_16(IMR, imr_save & ~bit);
539
540 write_reg_16(IIR, bit);
541
542 while (!quit) {
543 dsl1 = read_reg(dsl);
544 iir1 = read_reg_16(IIR);
545 iir2 = read_reg_16(IIR);
546 dsl2 = read_reg(dsl);
547
548 field1 = dsl1 & 0x80000000;
549 field2 = dsl2 & 0x80000000;
550 dsl1 &= ~0x80000000;
551 dsl2 &= ~0x80000000;
552
553 if (!(iir2 & bit))
554 continue;
555
556 write_reg_16(IIR, bit);
557
558 if (iir1 & bit)
559 continue;
560
561 if (field1 != field2)
562 printf("fields are different (%u:%u -> %u:%u)\n",
563 field1, dsl1, field2, dsl2);
564
565 min[field1*count+i[field1]] = dsl1;
566 max[field1*count+i[field1]] = dsl2;
567 if (++i[field1] >= count)
568 break;
569 }
570
571 write_reg_16(IMR, imr_save);
572 write_reg_16(IER, ier_save);
573}
574
575static void poll_dsl_iir_gen3(int pipe, int bit,
576 uint32_t *min, uint32_t *max, const int count)
577{
578 uint32_t dsl, dsl1, dsl2, iir1, iir2, imr_save, ier_save;
579 bool field1, field2;
580 int i[2] = {};
581
582 bit = 1 << bit;
583
584 dsl = dsl_reg(pipe);
585
586 imr_save = read_reg(IMR);
587 ier_save = read_reg(IER);
588
589 write_reg(IER, ier_save & ~bit);
590 write_reg(IMR, imr_save & ~bit);
591
592 write_reg(IIR, bit);
593
594 while (!quit) {
595 dsl1 = read_reg(dsl);
596 iir1 = read_reg(IIR);
597 iir2 = read_reg(IIR);
598 dsl2 = read_reg(dsl);
599
600 field1 = dsl1 & 0x80000000;
601 field2 = dsl2 & 0x80000000;
602 dsl1 &= ~0x80000000;
603 dsl2 &= ~0x80000000;
604
605 if (!(iir2 & bit))
606 continue;
607
608 write_reg(IIR, bit);
609
610 if (iir1 & bit)
611 continue;
612
613 if (field1 != field2)
614 printf("fields are different (%u:%u -> %u:%u)\n",
615 field1, dsl1, field2, dsl2);
616
617 min[field1*count+i[field1]] = dsl1;
618 max[field1*count+i[field1]] = dsl2;
619 if (++i[field1] >= count)
620 break;
621 }
622
623 write_reg(IMR, imr_save);
624 write_reg(IER, ier_save);
625}
626
627static void poll_dsl_deiir(uint32_t devid, int pipe, int bit,
628 uint32_t *min, uint32_t *max, const int count)
629{
630 uint32_t dsl, dsl1, dsl2, iir1, iir2, imr_save, ier_save;
631 bool field1, field2;
632 uint32_t iir, ier, imr;
633 int i[2] = {};
634
635 bit = 1 << bit;
636
637 dsl = dsl_reg(pipe);
638
639 if (IS_GEN8(devid)) {
640 iir = GEN8_DE_PIPE_IIR(pipe);
641 ier = GEN8_DE_PIPE_IER(pipe);
642 imr = GEN8_DE_PIPE_IMR(pipe);
643 } else {
644 iir = DEIIR;
645 ier = DEIER;
646 imr = DEIMR;
647 }
648
649 imr_save = read_reg(imr);
650 ier_save = read_reg(ier);
651
652 write_reg(ier, ier_save & ~bit);
653 write_reg(imr, imr_save & ~bit);
654
655 write_reg(iir, bit);
656
657 while (!quit) {
658 dsl1 = read_reg(dsl);
659 iir1 = read_reg(iir);
660 iir2 = read_reg(iir);
661 dsl2 = read_reg(dsl);
662
663 field1 = dsl1 & 0x80000000;
664 field2 = dsl2 & 0x80000000;
665 dsl1 &= ~0x80000000;
666 dsl2 &= ~0x80000000;
667
668 if (!(iir2 & bit))
669 continue;
670
671 write_reg(iir, bit);
672
673 if (iir1 & bit)
674 continue;
675
676 if (field1 != field2)
677 printf("fields are different (%u:%u -> %u:%u)\n",
678 field1, dsl1, field2, dsl2);
679
680 min[field1*count+i[field1]] = dsl1;
681 max[field1*count+i[field1]] = dsl2;
682 if (++i[field1] >= count)
683 break;
684 }
685
686 write_reg(imr, imr_save);
687 write_reg(ier, ier_save);
688}
689
690static void poll_dsl_framecount_g4x(int pipe, uint32_t *min, uint32_t *max, const int count)
691{
692 uint32_t dsl, dsl1, dsl2, frm, frm1, frm2;
693 bool field1, field2;
694 int i[2] = {};
695
696 switch (pipe) {
697 case 0:
698 frm = PIPEAFRMCOUNT_G4X;
699 break;
700 case 1:
701 frm = PIPEBFRMCOUNT_G4X;
702 break;
703 case 2:
704 frm = PIPECFRMCOUNT_G4X;
705 break;
706 default:
707 return;
708 }
709
710 dsl = dsl_reg(pipe);
711
712 while (!quit) {
713 dsl1 = read_reg(dsl);
714 frm1 = read_reg(frm);
715 frm2 = read_reg(frm);
716 dsl2 = read_reg(dsl);
717
718 field1 = dsl1 & 0x80000000;
719 field2 = dsl2 & 0x80000000;
720 dsl1 &= ~0x80000000;
721 dsl2 &= ~0x80000000;
722
723 if (frm1 + 1 != frm2)
724 continue;
725
726 if (field1 != field2)
727 printf("fields are different (%u:%u -> %u:%u)\n",
728 field1, dsl1, field2, dsl2);
729
730 min[field1*count+i[field1]] = dsl1;
731 max[field1*count+i[field1]] = dsl2;
732 if (++i[field1] >= count)
733 break;
734 }
735}
736
737static void poll_dsl_flipcount_g4x(uint32_t devid, int pipe,
738 uint32_t *min, uint32_t *max, const int count)
739{
740 uint32_t dsl, dsl1, dsl2, flp, flp1, flp2, surf;
741 bool field1, field2;
742 int i[2] = {};
743
744 switch (pipe) {
745 case 0:
746 flp = PIPEAFLIPCOUNT_G4X;
747 break;
748 case 1:
749 flp = PIPEBFLIPCOUNT_G4X;
750 break;
751 case 2:
752 flp = PIPECFLIPCOUNT_G4X;
753 break;
754 default:
755 return;
756 }
757
758 dsl = dsl_reg(pipe);
759 surf = dspsurf_reg(devid, pipe);
760
761 while (!quit) {
762 usleep(10);
763 dsl1 = read_reg(dsl);
764 flp1 = read_reg(flp);
765 dsl2 = read_reg(dsl);
766
767 field1 = dsl1 & 0x80000000;
768 field2 = dsl2 & 0x80000000;
769 dsl1 &= ~0x80000000;
770 dsl2 &= ~0x80000000;
771
772 if (field1 != field2)
773 printf("fields are different (%u:%u -> %u:%u)\n",
774 field1, dsl1, field2, dsl2);
775
776 min[field1*count+i[field1]] = dsl1;
777 max[field1*count+i[field1]] = dsl2;
778 if (++i[field1] >= count)
779 return;
780
781 write_reg(surf, read_reg(surf));
782
783 while (!quit) {
784 dsl1 = read_reg(dsl);
785 flp2 = read_reg(flp);
786 dsl2 = read_reg(dsl);
787
788 field1 = dsl1 & 0x80000000;
789 field2 = dsl2 & 0x80000000;
790 dsl1 &= ~0x80000000;
791 dsl2 &= ~0x80000000;
792
793 if (flp1 == flp2)
794 continue;
795
796 if (field1 != field2)
797 printf("fields are different (%u:%u -> %u:%u)\n",
798 field1, dsl1, field2, dsl2);
799
800 min[field1*count+i[field1]] = dsl1;
801 max[field1*count+i[field1]] = dsl2;
802 if (++i[field1] >= count)
803 break;
804 }
805 if (i[field1] >= count)
806 break;
807 }
808}
809
810static void poll_dsl_framecount_gen3(int pipe, uint32_t *min, uint32_t *max, const int count)
811{
812 uint32_t dsl, dsl1, dsl2, frm, frm1, frm2;
813 bool field1, field2;
814 int i[2] = {};
815
816 switch (pipe) {
817 case 0:
818 frm = PIPEAFRAMEPIXEL;
819 break;
820 case 1:
821 frm = PIPEBFRAMEPIXEL;
822 break;
823 default:
824 return;
825 }
826
827 dsl = dsl_reg(pipe);
828
829 while (!quit) {
830 dsl1 = read_reg(dsl);
831 frm1 = read_reg(frm) >> 24;
832 frm2 = read_reg(frm) >> 24;
833 dsl2 = read_reg(dsl);
834
835 field1 = dsl1 & 0x80000000;
836 field2 = dsl2 & 0x80000000;
837 dsl1 &= ~0x80000000;
838 dsl2 &= ~0x80000000;
839
840 if (frm1 + 1 != frm2)
841 continue;
842
843 if (field1 != field2)
844 printf("fields are different (%u:%u -> %u:%u)\n",
845 field1, dsl1, field2, dsl2);
846
847 min[field1*count+i[field1]] = dsl1;
848 max[field1*count+i[field1]] = dsl2;
849 if (++i[field1] >= count)
850 break;
851 }
852}
853
854static void poll_dsl_pan(uint32_t devid, int pipe, int target_scanline, int target_fuzz,
855 uint32_t *min, uint32_t *max, const int count)
856{
857 uint32_t dsl, dsl1 = 0, dsl2 = 0;
858 bool field1 = false, field2 = false;
859 uint32_t saved, surf = 0;
860 int i[2] = {};
861
862 dsl = dsl_reg(pipe);
863 surf = dspoffset_reg(devid, pipe);
864
865 saved = read_reg(surf);
866
867 while (!quit) {
868 while (!quit) {
869 dsl1 = read_reg(dsl);
870 field1 = dsl1 & 0x80000000;
871 dsl1 &= ~0x80000000;
872 if (dsl1 == target_scanline)
873 break;
874 }
875
876 write_reg(surf, saved+256);
877
878 while (!quit) {
879 dsl2 = read_reg(dsl);
880 field2 = dsl1 & 0x80000000;
881 dsl2 &= ~0x80000000;
882 if (dsl2 == target_scanline + target_fuzz)
883 break;
884 }
885
886 write_reg(surf, saved);
887
888 if (field1 != field2)
889 printf("fields are different (%u:%u -> %u:%u)\n",
890 field1, dsl1, field2, dsl2);
891
892 min[field1*count+i[field1]] = dsl1;
893 max[field1*count+i[field1]] = dsl2;
894 if (++i[field1] >= count)
895 break;
896 }
897
898 write_reg(surf, saved);
899}
900
901static void poll_dsl_flip(uint32_t devid, int pipe, int target_scanline, int target_fuzz,
902 uint32_t *min, uint32_t *max, const int count)
903{
904 uint32_t dsl, dsl1 = 0, dsl2 = 0;
905 bool field1 = false, field2 = false;
906 uint32_t saved, surf = 0;
907 int i[2] = {};
908
909 dsl = dsl_reg(pipe);
910 surf = dspsurf_reg(devid, pipe);
911
912 saved = read_reg(surf);
913
914 while (!quit) {
915 while (!quit) {
916 dsl1 = read_reg(dsl);
917 field1 = dsl1 & 0x80000000;
918 dsl1 &= ~0x80000000;
919 if (dsl1 == target_scanline)
920 break;
921 }
922
923 write_reg(surf, saved+4096);
924
925 while (!quit) {
926 dsl2 = read_reg(dsl);
927 field2 = dsl1 & 0x80000000;
928 dsl2 &= ~0x80000000;
929 if (dsl2 == target_scanline + target_fuzz)
930 break;
931 }
932
933 write_reg(surf, saved);
934
935 if (field1 != field2)
936 printf("fields are different (%u:%u -> %u:%u)\n",
937 field1, dsl1, field2, dsl2);
938
939 min[field1*count+i[field1]] = dsl1;
940 max[field1*count+i[field1]] = dsl2;
941 if (++i[field1] >= count)
942 break;
943 }
944
945 write_reg(surf, saved);
946}
947
948static void poll_dsl_surflive(uint32_t devid, int pipe,
949 uint32_t *min, uint32_t *max, const int count)
950{
951 uint32_t dsl, dsl1 = 0, dsl2 = 0, surf, surf1, surf2, surflive, surfl1 = 0, surfl2, saved, tmp;
952 bool field1 = false, field2 = false;
953 int i[2] = {};
954
955 switch (pipe) {
956 case 0:
957 surflive = DSPASURFLIVE;
958 break;
959 case 1:
960 surflive = DSPBSURFLIVE;
961 break;
962 case 2:
963 surflive = DSPCSURFLIVE;
964 break;
965 default:
966 return;
967 }
968
969 dsl = dsl_reg(pipe);
970 surf = dspsurf_reg(devid, pipe);
971
972 saved = read_reg(surf);
973
974 surf1 = saved & ~0xfff;
975 surf2 = surf1 + 4096;
976
977 while (!quit) {
978 write_reg(surf, surf2);
979
980 while (!quit) {
981 dsl1 = read_reg(dsl);
982 surfl1 = read_reg(surflive) & ~0xfff;
983 surfl2 = read_reg(surflive) & ~0xfff;
984 dsl2 = read_reg(dsl);
985
986 field1 = dsl1 & 0x80000000;
987 field2 = dsl2 & 0x80000000;
988 dsl1 &= ~0x80000000;
989 dsl2 &= ~0x80000000;
990
991 if (surfl2 == surf2)
992 break;
993 }
994
995 if (surfl1 != surf2) {
996 if (field1 != field2)
997 printf("fields are different (%u:%u -> %u:%u)\n",
998 field1, dsl1, field2, dsl2);
999
1000 min[field1*count+i[field1]] = dsl1;
1001 max[field1*count+i[field1]] = dsl2;
1002 if (++i[field1] >= count)
1003 break;
1004 }
1005
1006 tmp = surf1;
1007 surf1 = surf2;
1008 surf2 = tmp;
1009 }
1010
1011 write_reg(surf, saved);
1012}
1013
1014static void poll_dsl_wrap(int pipe, uint32_t *min, uint32_t *max, const int count)
1015{
1016 uint32_t dsl, dsl1, dsl2;
1017 bool field1, field2;
1018 int i[2] = {};
1019
1020 dsl = dsl_reg(pipe);
1021
1022 while (!quit) {
1023 dsl1 = read_reg(dsl);
1024 dsl2 = read_reg(dsl);
1025
1026 field1 = dsl1 & 0x80000000;
1027 field2 = dsl2 & 0x80000000;
1028 dsl1 &= ~0x80000000;
1029 dsl2 &= ~0x80000000;
1030
1031 if (dsl2 >= dsl1)
1032 continue;
1033
1034 if (field1 != field2)
1035 printf("fields are different (%u:%u -> %u:%u)\n",
1036 field1, dsl1, field2, dsl2);
1037
1038 min[field1*count+i[field1]] = dsl1;
1039 max[field1*count+i[field1]] = dsl2;
1040 if (++i[field1] >= count)
1041 break;
1042 }
1043}
1044
1045static void poll_dsl_field(int pipe, uint32_t *min, uint32_t *max, const int count)
1046{
1047 uint32_t dsl, dsl1, dsl2;
1048 bool field1, field2;
1049 int i[2] = {};
1050
1051 dsl = dsl_reg(pipe);
1052
1053 while (!quit) {
1054 dsl1 = read_reg(dsl);
1055 dsl2 = read_reg(dsl);
1056
1057 field1 = dsl1 & 0x80000000;
1058 field2 = dsl2 & 0x80000000;
1059 dsl1 &= ~0x80000000;
1060 dsl2 &= ~0x80000000;
1061
1062 if (field1 == field2)
1063 continue;
1064
1065 min[field1*count+i[field1]] = dsl1;
1066 max[field1*count+i[field1]] = dsl2;
1067 if (++i[field1] >= count)
1068 break;
1069 }
1070}
1071
1072static char pipe_name(int pipe)
1073{
1074 return pipe + 'A';
1075}
1076
1077static const char *test_name(enum test test, int pipe, int bit, bool test_pixel_count)
1078{
1079 static char str[32];
1080 const char *type = test_pixel_count ? "pixel" : "dsl";
1081
1082 switch (test) {
1083 case TEST_PIPESTAT:
1084 snprintf(str, sizeof str, "%s / pipe %c / PIPESTAT[%d] (gmch)", type, pipe_name(pipe), bit);
1085 return str;
1086 case TEST_IIR_GEN2:
1087 snprintf(str, sizeof str, "%s / pipe %c / IIR[%d] (gen2)", type, pipe_name(pipe), bit);
1088 return str;
1089 case TEST_IIR_GEN3:
1090 snprintf(str, sizeof str, "%s / pipe %c / IIR[%d] (gen3+)", type, pipe_name(pipe), bit);
1091 return str;
1092 case TEST_DEIIR:
1093 snprintf(str, sizeof str, "%s / pipe %c / DEIIR[%d] (pch)", type, pipe_name(pipe), bit);
1094 return str;
1095 case TEST_FRAMECOUNT_GEN3:
1096 snprintf(str, sizeof str, "%s / pipe %c / Frame count (gen3/4)", type, pipe_name(pipe));
1097 return str;
1098 case TEST_FRAMECOUNT_G4X:
1099 snprintf(str, sizeof str, "%s / pipe %c / Frame count (g4x+)", type, pipe_name(pipe));
1100 return str;
1101 case TEST_FLIPCOUNT:
1102 snprintf(str, sizeof str, "%s / pipe %c / Flip count (g4x+)", type, pipe_name(pipe));
1103 return str;
1104 case TEST_PAN:
1105 snprintf(str, sizeof str, "%s / pipe %c / Pan", type, pipe_name(pipe));
1106 return str;
1107 case TEST_FLIP:
1108 snprintf(str, sizeof str, "%s / pipe %c / Flip", type, pipe_name(pipe));
1109 return str;
1110 case TEST_SURFLIVE:
1111 snprintf(str, sizeof str, "%s / pipe %c / Surflive", type, pipe_name(pipe));
1112 return str;
1113 case TEST_WRAP:
1114 snprintf(str, sizeof str, "%s / pipe %c / Wrap", type, pipe_name(pipe));
1115 return str;
1116 case TEST_FIELD:
1117 snprintf(str, sizeof str, "%s / pipe %c / Field", type, pipe_name(pipe));
1118 return str;
1119 default:
1120 return "";
1121 }
1122}
1123
1124static void usage(const char *name)
1125{
1126 fprintf(stderr, "Usage: %s [options]\n"
1127 " -t,--test <pipestat|iir|framecount|flipcount|pan|flip|surflive|wrap|field>\n"
1128 " -p,--pipe <pipe>\n"
1129 " -b,--bit <bit>\n"
1130 " -l,--line <target scanline/pixel>\n"
1131 " -f,--fuzz <target fuzz>\n"
1132 " -x,--pixel\n",
1133 name);
1134 exit(1);
1135}
1136
1137int main(int argc, char *argv[])
1138{
1139 int fd, i;
1140 int pipe = 0, bit = 0, target_scanline = 0, target_fuzz = 1;
1141 bool test_pixelcount = false;
1142 uint32_t devid;
1143 uint32_t min[2*128] = {};
1144 uint32_t max[2*128] = {};
1145 uint32_t a, b;
1146 enum test test = TEST_INVALID;
1147 const int count = ARRAY_SIZE(min)/2;
1148
1149 for (;;) {
1150 static const struct option long_options[] = {
1151 { .name = "test", .has_arg = required_argument, },
1152 { .name = "pipe", .has_arg = required_argument, },
1153 { .name = "bit", .has_arg = required_argument, },
1154 { .name = "line", .has_arg = required_argument, },
1155 { .name = "fuzz", .has_arg = required_argument, },
1156 { .name = "pixel", .has_arg = no_argument, },
1157 { },
1158 };
1159
1160 int opt = getopt_long(argc, argv, "t:p:b:l:f:x", long_options, NULL);
1161 if (opt == -1)
1162 break;
1163
1164 switch (opt) {
1165 case 't':
1166 if (!strcmp(optarg, "pipestat"))
1167 test = TEST_PIPESTAT;
1168 else if (!strcmp(optarg, "iir"))
1169 test = TEST_IIR;
1170 else if (!strcmp(optarg, "framecount"))
1171 test = TEST_FRAMECOUNT;
1172 else if (!strcmp(optarg, "flipcount"))
1173 test = TEST_FLIPCOUNT;
1174 else if (!strcmp(optarg, "pan"))
1175 test = TEST_PAN;
1176 else if (!strcmp(optarg, "flip"))
1177 test = TEST_FLIP;
1178 else if (!strcmp(optarg, "surflive"))
1179 test = TEST_SURFLIVE;
1180 else if (!strcmp(optarg, "wrap"))
1181 test = TEST_WRAP;
1182 else if (!strcmp(optarg, "field"))
1183 test = TEST_FIELD;
1184 else
1185 usage(argv[0]);
1186 break;
1187 case 'p':
1188 pipe = atoi(optarg);
1189 if (pipe < 0 || pipe > 2)
1190 usage(argv[0]);
1191 break;
1192 case 'b':
1193 bit = atoi(optarg);
1194 if (bit < 0 || bit > 31)
1195 usage(argv[0]);
1196 break;
1197 case 'l':
1198 target_scanline = atoi(optarg);
1199 if (target_scanline < 0)
1200 usage(argv[0]);
1201 break;
1202 case 'f':
1203 target_fuzz = atoi(optarg);
1204 if (target_fuzz <= 0)
1205 usage(argv[0]);
1206 break;
1207 case 'x':
1208 test_pixelcount = true;
1209 break;
1210 }
1211 }
1212
1213 fd = drm_open_any();
1214 devid = intel_get_drm_devid(fd);
1215 close(fd);
1216
1217 /*
1218 * check if the requires registers are
1219 * avilable on the current platform.
1220 */
1221 if (IS_GEN2(devid)) {
1222 if (pipe > 1)
1223 usage(argv[0]);
1224
1225 if (test_pixelcount)
1226 usage(argv[0]);
1227
1228 switch (test) {
1229 case TEST_IIR:
1230 test = TEST_IIR_GEN2;
1231 break;
1232 case TEST_PIPESTAT:
1233 case TEST_PAN:
1234 break;
1235 case TEST_FLIP:
1236 test = TEST_PAN;
1237 break;
1238 default:
1239 usage(argv[0]);
1240 }
1241 } else if (IS_GEN3(devid) ||
1242 (IS_GEN4(devid) && !IS_G4X(devid))) {
1243 if (pipe > 1)
1244 usage(argv[0]);
1245
1246 switch (test) {
1247 case TEST_IIR:
1248 test = TEST_IIR_GEN3;
1249 break;
1250 case TEST_FRAMECOUNT:
1251 test = TEST_FRAMECOUNT_GEN3;
1252 break;
1253 case TEST_PIPESTAT:
1254 case TEST_PAN:
1255 case TEST_WRAP:
1256 case TEST_FIELD:
1257 break;
1258 case TEST_FLIP:
1259 if (IS_GEN3(devid))
1260 test = TEST_PAN;
1261 break;
1262 default:
1263 usage(argv[0]);
1264 }
1265 } else if (IS_G4X(devid) || IS_VALLEYVIEW(devid)) {
1266 if (IS_VALLEYVIEW(devid))
1267 vlv_offset = 0x180000;
1268
1269 if (pipe > 1)
1270 usage(argv[0]);
1271
1272 if (test_pixelcount)
1273 usage(argv[0]);
1274
1275 switch (test) {
1276 case TEST_IIR:
1277 test = TEST_IIR_GEN3;
1278 break;
1279 case TEST_FRAMECOUNT:
1280 test = TEST_FRAMECOUNT_G4X;
1281 break;
1282 case TEST_FLIPCOUNT:
1283 case TEST_PIPESTAT:
1284 case TEST_PAN:
1285 case TEST_FLIP:
1286 case TEST_SURFLIVE:
1287 case TEST_WRAP:
1288 case TEST_FIELD:
1289 break;
1290 default:
1291 usage(argv[0]);
1292 }
1293 } else if (HAS_PCH_SPLIT(devid) &&
1294 (IS_GEN5(devid) || IS_GEN6(devid) || IS_GEN7(devid))) {
1295 if (pipe > 1 &&
1296 (IS_GEN5(devid) || IS_GEN6(devid)))
1297 usage(argv[0]);
1298
1299 if (test_pixelcount)
1300 usage(argv[0]);
1301
1302 switch (test) {
1303 case TEST_IIR:
1304 test = TEST_DEIIR;
1305 break;
1306 case TEST_FRAMECOUNT:
1307 test = TEST_FRAMECOUNT_G4X;
1308 break;
1309 case TEST_FLIPCOUNT:
1310 case TEST_PAN:
1311 case TEST_FLIP:
1312 case TEST_SURFLIVE:
1313 case TEST_WRAP:
1314 case TEST_FIELD:
1315 break;
1316 default:
1317 usage(argv[0]);
1318 }
1319 } else if (IS_GEN8(devid)) {
1320 if (test_pixelcount)
1321 usage(argv[0]);
1322
1323 switch (test) {
1324 case TEST_IIR:
1325 test = TEST_DEIIR;
1326 break;
1327 case TEST_FRAMECOUNT:
1328 test = TEST_FRAMECOUNT_G4X;
1329 break;
1330 case TEST_FLIPCOUNT:
1331 case TEST_PAN:
1332 case TEST_FLIP:
1333 case TEST_SURFLIVE:
1334 case TEST_WRAP:
1335 case TEST_FIELD:
1336 break;
1337 default:
1338 usage(argv[0]);
1339 }
1340 } else {
1341 usage(argv[0]);
1342 }
1343
1344 switch (test) {
1345 case TEST_IIR:
1346 case TEST_FRAMECOUNT:
1347 /* should no longer have the generic tests here */
1348 assert(0);
1349 default:
1350 break;
1351 }
1352
1353 intel_register_access_init(intel_get_pci_device(), 0);
1354
1355 printf("%s?\n", test_name(test, pipe, bit, test_pixelcount));
1356
1357 signal(SIGHUP, sighandler);
1358 signal(SIGINT, sighandler);
1359 signal(SIGTERM, sighandler);
1360
1361 switch (test) {
1362 case TEST_PIPESTAT:
1363 if (test_pixelcount)
1364 poll_pixel_pipestat(pipe, bit, min, max, count);
1365 else
1366 poll_dsl_pipestat(pipe, bit, min, max, count);
1367 break;
1368 case TEST_IIR_GEN2:
1369 assert(!test_pixelcount);
1370 poll_dsl_iir_gen2(pipe, bit, min, max, count);
1371 break;
1372 case TEST_IIR_GEN3:
1373 if (test_pixelcount)
1374 poll_pixel_iir_gen3(pipe, bit, min, max, count);
1375 else
1376 poll_dsl_iir_gen3(pipe, bit, min, max, count);
1377 break;
1378 case TEST_DEIIR:
1379 assert(!test_pixelcount);
1380 poll_dsl_deiir(devid, pipe, bit, min, max, count);
1381 break;
1382 case TEST_FRAMECOUNT_GEN3:
1383 if (test_pixelcount)
1384 poll_pixel_framecount_gen3(pipe, min, max, count);
1385 else
1386 poll_dsl_framecount_gen3(pipe, min, max, count);
1387 break;
1388 case TEST_FRAMECOUNT_G4X:
1389 assert(!test_pixelcount);
1390 poll_dsl_framecount_g4x(pipe, min, max, count);
1391 break;
1392 case TEST_FLIPCOUNT:
1393 assert(!test_pixelcount);
1394 poll_dsl_flipcount_g4x(devid, pipe, min, max, count);
1395 break;
1396 case TEST_PAN:
1397 if (test_pixelcount)
1398 poll_pixel_pan(devid, pipe, target_scanline, target_fuzz,
1399 min, max, count);
1400 else
1401 poll_dsl_pan(devid, pipe, target_scanline, target_fuzz,
1402 min, max, count);
1403 break;
1404 case TEST_FLIP:
1405 if (test_pixelcount)
1406 poll_pixel_flip(devid, pipe, target_scanline, target_fuzz,
1407 min, max, count);
1408 else
1409 poll_dsl_flip(devid, pipe, target_scanline, target_fuzz,
1410 min, max, count);
1411 break;
1412 case TEST_SURFLIVE:
1413 poll_dsl_surflive(devid, pipe, min, max, count);
1414 break;
1415 case TEST_WRAP:
1416 if (test_pixelcount)
1417 poll_pixel_wrap(pipe, min, max, count);
1418 else
1419 poll_dsl_wrap(pipe, min, max, count);
1420 break;
1421 case TEST_FIELD:
1422 poll_dsl_field(pipe, min, max, count);
1423 break;
1424 default:
1425 assert(0);
1426 }
1427
1428 intel_register_access_fini();
1429
1430 if (quit)
1431 return 0;
1432
1433 for (i = 0; i < count; i++) {
1434 if (min[0*count+i] == 0 && max[0*count+i] == 0)
1435 break;
1436 printf("[%u] %4u - %4u (%4u)\n", 0, min[0*count+i], max[0*count+i],
1437 (min[0*count+i] + max[0*count+i] + 1) >> 1);
1438 }
1439 for (i = 0; i < count; i++) {
1440 if (min[1*count+i] == 0 && max[1*count+i] == 0)
1441 break;
1442 printf("[%u] %4u - %4u (%4u)\n", 1, min[1*count+i], max[1*count+i],
1443 (min[1*count+i] + max[1*count+i] + 1) >> 1);
1444 }
1445
1446 a = 0;
1447 b = 0xffffffff;
1448 for (i = 0; i < count; i++) {
1449 if (min[0*count+i] == 0 && max[0*count+i] == 0)
1450 break;
1451 a = max(a, min[0*count+i]);
1452 b = min(b, max[0*count+i]);
1453 }
1454
1455 printf("%s: [%u] %6u - %6u\n", test_name(test, pipe, bit, test_pixelcount), 0, a, b);
1456
1457 a = 0;
1458 b = 0xffffffff;
1459 for (i = 0; i < count; i++) {
1460 if (min[1*count+i] == 0 && max[1*count+i] == 0)
1461 break;
1462 a = max(a, min[1*count+i]);
1463 b = min(b, max[1*count+i]);
1464 }
1465
1466 printf("%s: [%u] %6u - %6u\n", test_name(test, pipe, bit, test_pixelcount), 1, a, b);
1467
1468 return 0;
1469}