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