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