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