From: Daniel Vetter <daniel@ffwll.ch>
To: ville.syrjala@linux.intel.com
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH igt 4/4] tools/intel_poller: Add a new tool that will poll various display registers
Date: Thu, 12 Jun 2014 09:21:29 +0200 [thread overview]
Message-ID: <20140612072129.GT5821@phenom.ffwll.local> (raw)
In-Reply-To: <1402504880-27525-4-git-send-email-ville.syrjala@linux.intel.com>
On Wed, Jun 11, 2014 at 07:41:20PM +0300, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> intel_poller can be used to poll various display registers
> (IIR,scanline/pixel/flip/frame counter, live address, etc.).
>
> It can be used to determine eg. at which scanline or pixel count certain
> events occur.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>
> Ideas for a better name are welcome!
intel_display_poller maybe since the use-case is display specific. But
not really important imo.
-Daniel
>
>
> lib/intel_reg.h | 22 +-
> tools/Makefile.sources | 1 +
> tools/intel_poller.c | 1471 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 1491 insertions(+), 3 deletions(-)
> create mode 100644 tools/intel_poller.c
>
> diff --git a/lib/intel_reg.h b/lib/intel_reg.h
> index 84e05e4..87a14c9 100644
> --- a/lib/intel_reg.h
> +++ b/lib/intel_reg.h
> @@ -2248,7 +2248,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> */
> #define PIPE_PIXEL_MASK 0x00ffffff
> #define PIPE_PIXEL_SHIFT 0
> -
> +/*
> + * g4x+ frame/flip counters
> + */
> +#define PIPEAFRMCOUNT_G4X 0x70040
> +#define PIPEAFLIPCOUNT_G4X 0x70044
> /*
> * Computing GMCH M and N values.
> *
> @@ -2296,20 +2300,24 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> #define PIPEBSTAT 0x71024
> #define PIPEBFRAMEHIGH 0x71040
> #define PIPEBFRAMEPIXEL 0x71044
> +#define PIPEBFRMCOUNT_G4X 0x71040
> +#define PIPEBFLIPCOUNT_G4X 0x71044
>
> #define PIPEB_GMCH_DATA_M 0x71050
> #define PIPEB_GMCH_DATA_N 0x71054
> #define PIPEB_DP_LINK_M 0x71060
> #define PIPEB_DP_LINK_N 0x71064
>
> +#define PIPEC_DSL 0x72000
> +
> #define PIPECCONF 0x72008
>
> #define PIPECGCMAXRED 0x72010
> #define PIPECGCMAXGREEN 0x72014
> #define PIPECGCMAXBLUE 0x72018
> #define PIPECSTAT 0x72024
> -#define PIPECFRAMEHIGH 0x72040
> -#define PIPECFRAMEPIXEL 0x72044
> +#define PIPECFRMCOUNT_G4X 0x72040
> +#define PIPECFLIPCOUNT_G4X 0x72044
>
> #define PIPEC_GMCH_DATA_M 0x72050
> #define PIPEC_GMCH_DATA_N 0x72054
> @@ -2370,12 +2378,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>
> #define DSPASURF 0x7019C
> #define DSPATILEOFF 0x701A4
> +#define DSPASURFLIVE 0x701AC
>
> #define DSPBSURF 0x7119C
> #define DSPBTILEOFF 0x711A4
> +#define DSPBSURFLIVE 0x711AC
>
> #define DSPCSURF 0x7219C
> #define DSPCTILEOFF 0x721A4
> +#define DSPCSURFLIVE 0x721AC
>
> #define VGACNTRL 0x71400
> # define VGA_DISP_DISABLE (1 << 31)
> @@ -2879,6 +2890,11 @@ typedef enum {
> #define DEIIR 0x44008
> #define DEIER 0x4400c
>
> +#define GEN8_DE_PIPE_ISR(pipe) (0x44400 + 0x10 * (pipe))
> +#define GEN8_DE_PIPE_IMR(pipe) (0x44404 + 0x10 * (pipe))
> +#define GEN8_DE_PIPE_IIR(pipe) (0x44408 + 0x10 * (pipe))
> +#define GEN8_DE_PIPE_IER(pipe) (0x4440c + 0x10 * (pipe))
> +
> /* GT interrupt */
> #define GT_SYNC_STATUS (1 << 2)
> #define GT_USER_INTERRUPT (1 << 0)
> diff --git a/tools/Makefile.sources b/tools/Makefile.sources
> index c2535e7..6f6ca4a 100644
> --- a/tools/Makefile.sources
> +++ b/tools/Makefile.sources
> @@ -12,6 +12,7 @@ bin_PROGRAMS = \
> intel_iosf_sb_write \
> intel_opregion_decode \
> intel_perf_counters \
> + intel_poller \
> intel_stepping \
> intel_reg_checker \
> intel_reg_dumper \
> diff --git a/tools/intel_poller.c b/tools/intel_poller.c
> new file mode 100644
> index 0000000..ebc594a
> --- /dev/null
> +++ b/tools/intel_poller.c
> @@ -0,0 +1,1471 @@
> +/*
> + * Copyright © 2014 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + */
> +
> +#include <assert.h>
> +#include <fcntl.h>
> +#include <getopt.h>
> +#include <unistd.h>
> +#include <signal.h>
> +#include <stdbool.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <err.h>
> +#include <string.h>
> +#include "intel_chipset.h"
> +#include "intel_io.h"
> +#include "igt_debugfs.h"
> +#include "drmtest.h"
> +
> +#define min(a,b) ((a) < (b) ? (a) : (b))
> +#define max(a,b) ((a) > (b) ? (a) : (b))
> +
> +enum test {
> + TEST_INVALID,
> + TEST_PIPESTAT,
> + TEST_IIR,
> + TEST_IIR_GEN2,
> + TEST_IIR_GEN3,
> + TEST_DEIIR,
> + TEST_FRAMECOUNT,
> + TEST_FRAMECOUNT_GEN3,
> + TEST_FRAMECOUNT_G4X,
> + TEST_FLIPCOUNT,
> + TEST_PAN,
> + TEST_FLIP,
> + TEST_SURFLIVE,
> + TEST_WRAP,
> + TEST_FIELD,
> +};
> +
> +static uint32_t vlv_offset;
> +
> +static volatile bool quit;
> +
> +static void sighandler(int x)
> +{
> + quit = true;
> +}
> +
> +static uint16_t read_reg_16(uint32_t reg)
> +{
> + return *(volatile uint16_t *)((volatile char*)mmio + vlv_offset + reg);
> +}
> +
> +static uint32_t read_reg(uint32_t reg)
> +{
> + return *(volatile uint32_t *)((volatile char*)mmio + vlv_offset + reg);
> +}
> +
> +static void write_reg_16(uint32_t reg, uint16_t val)
> +{
> + *(volatile uint16_t *)((volatile char*)mmio + vlv_offset + reg) = val;
> +}
> +
> +static void write_reg(uint32_t reg, uint32_t val)
> +{
> + *(volatile uint32_t *)((volatile char*)mmio + vlv_offset + reg) = val;
> +}
> +
> +static int pipe_to_plane(uint32_t devid, int pipe)
> +{
> + if (!IS_GEN2(devid) && !IS_GEN3(devid))
> + return pipe;
> +
> + switch (pipe) {
> + case 0:
> + if ((read_reg(DSPACNTR) & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_B)
> + return 1;
> + return 0;
> + case 1:
> + if ((read_reg(DSPACNTR) & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_A)
> + return 0;
> + return 1;
> + }
> +
> + assert(0);
> +
> + return 0;
> +}
> +
> +static uint32_t dspoffset_reg(uint32_t devid, int pipe)
> +{
> + bool use_tileoff;
> +
> + pipe = pipe_to_plane(devid, pipe);
> +
> + if (IS_GEN2(devid) || IS_GEN3(devid))
> + use_tileoff = false;
> + if (IS_HASWELL(devid) || IS_BROADWELL(devid))
> + use_tileoff = true;
> + else {
> + switch (pipe) {
> + case 0:
> + use_tileoff = read_reg(DSPACNTR) & DISPLAY_PLANE_TILED;
> + break;
> + case 1:
> + use_tileoff = read_reg(DSPBCNTR) & DISPLAY_PLANE_TILED;
> + break;
> + case 2:
> + use_tileoff = read_reg(DSPCCNTR) & DISPLAY_PLANE_TILED;
> + break;
> + }
> + }
> +
> + if (use_tileoff) {
> + switch (pipe) {
> + case 0:
> + return DSPATILEOFF;
> + case 1:
> + return DSPBTILEOFF;
> + case 2:
> + return DSPCTILEOFF;
> + }
> + } else {
> + switch (pipe) {
> + case 0:
> + return DSPABASE;
> + case 1:
> + return DSPBBASE;
> + case 2:
> + return DSPCBASE;
> + }
> + }
> +
> + assert(0);
> +
> + return 0;
> +}
> +
> +static uint32_t dspsurf_reg(uint32_t devid, int pipe)
> +{
> + pipe = pipe_to_plane(devid, pipe);
> +
> + if (IS_GEN2(devid) || IS_GEN3(devid)) {
> + switch (pipe) {
> + case 0:
> + return DSPABASE;
> + case 1:
> + return DSPBBASE;
> + case 2:
> + return DSPCBASE;
> + }
> + } else {
> + switch (pipe) {
> + case 0:
> + return DSPASURF;
> + case 1:
> + return DSPBSURF;
> + case 2:
> + return DSPCSURF;
> + }
> + }
> +
> + assert(0);
> +
> + return 0;
> +}
> +
> +static uint32_t dsl_reg(int pipe)
> +{
> + switch (pipe) {
> + case 0:
> + return PIPEA_DSL;
> + case 1:
> + return PIPEB_DSL;
> + case 2:
> + return PIPEC_DSL;
> + }
> +
> + assert(0);
> +
> + return 0;
> +}
> +
> +static void poll_pixel_pipestat(int pipe, int bit, uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t pix, pix1, pix2, iir, iir1, iir2, iir_bit, iir_mask;
> + int i = 0;
> +
> + switch (pipe) {
> + case 0:
> + pix = PIPEAFRAMEPIXEL;
> + iir_bit = 1 << bit;
> + iir = PIPEASTAT;
> + break;
> + case 1:
> + pix = PIPEBFRAMEPIXEL;
> + iir_bit = 1 << bit;
> + iir = PIPEBSTAT;
> + break;
> + default:
> + return;
> + }
> +
> + iir_mask = read_reg(iir) & 0x7fff0000;
> +
> + write_reg(iir, iir_mask | iir_bit);
> +
> + while (!quit) {
> + pix1 = read_reg(pix);
> + iir1 = read_reg(iir);
> + iir2 = read_reg(iir);
> + pix2 = read_reg(pix);
> +
> + if (!(iir2 & iir_bit))
> + continue;
> +
> + if (iir1 & iir_bit) {
> + write_reg(iir, iir_mask | iir_bit);
> + continue;
> + }
> +
> + pix1 &= PIPE_PIXEL_MASK;
> + pix2 &= PIPE_PIXEL_MASK;
> +
> + min[i] = pix1;
> + max[i] = pix2;
> + if (++i >= count)
> + break;
> + }
> +}
> +
> +static void poll_pixel_iir_gen3(int pipe, int bit, uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t pix, pix1, pix2, iir1, iir2, imr_save, ier_save;
> + int i = 0;
> +
> + bit = 1 << bit;
> +
> + switch (pipe) {
> + case 0:
> + pix = PIPEAFRAMEPIXEL;
> + break;
> + case 1:
> + pix = PIPEBFRAMEPIXEL;
> + break;
> + default:
> + return;
> + }
> +
> + imr_save = read_reg(IMR);
> + ier_save = read_reg(IER);
> +
> + write_reg(IER, ier_save & ~bit);
> + write_reg(IMR, imr_save & ~bit);
> +
> + write_reg(IIR, bit);
> +
> + while (!quit) {
> + pix1 = read_reg(pix);
> + iir1 = read_reg(IIR);
> + iir2 = read_reg(IIR);
> + pix2 = read_reg(pix);
> +
> + if (!(iir2 & bit))
> + continue;
> +
> + write_reg(IIR, bit);
> +
> + if (iir1 & bit)
> + continue;
> +
> + pix1 &= PIPE_PIXEL_MASK;
> + pix2 &= PIPE_PIXEL_MASK;
> +
> + min[i] = pix1;
> + max[i] = pix2;
> + if (++i >= count)
> + break;
> + }
> +
> + write_reg(IMR, imr_save);
> + write_reg(IER, ier_save);
> +}
> +
> +static void poll_pixel_framecount_gen3(int pipe, uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t pix, pix1, pix2, frm1, frm2;
> + int i = 0;
> +
> + switch (pipe) {
> + case 0:
> + pix = PIPEAFRAMEPIXEL;
> + break;
> + case 1:
> + pix = PIPEBFRAMEPIXEL;
> + break;
> + default:
> + return;
> + }
> +
> + while (!quit) {
> + pix1 = read_reg(pix);
> + pix2 = read_reg(pix);
> +
> + frm1 = pix1 >> 24;
> + frm2 = pix2 >> 24;
> +
> + if (frm1 + 1 != frm2)
> + continue;
> +
> + pix1 &= PIPE_PIXEL_MASK;
> + pix2 &= PIPE_PIXEL_MASK;
> +
> + min[i] = pix1;
> + max[i] = pix2;
> + if (++i >= count)
> + break;
> + }
> +}
> +
> +static void poll_pixel_pan(uint32_t devid, int pipe, int target_pixel, int target_fuzz,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t pix, pix1 = 0, pix2 = 0;
> + uint32_t saved, surf = 0;
> + int i = 0;
> +
> + switch (pipe) {
> + case 0:
> + pix = PIPEAFRAMEPIXEL;
> + break;
> + case 1:
> + pix = PIPEBFRAMEPIXEL;
> + break;
> + default:
> + return;
> + }
> +
> + surf = dspoffset_reg(devid, pipe);
> +
> + saved = read_reg(surf);
> +
> + while (!quit) {
> + while (!quit){
> + pix1 = read_reg(pix) & PIPE_PIXEL_MASK;
> + if (pix1 == target_pixel)
> + break;
> + }
> +
> + write_reg(surf, saved+256);
> +
> + while (!quit){
> + pix2 = read_reg(pix) & PIPE_PIXEL_MASK;
> + if (pix2 >= target_pixel + target_fuzz)
> + break;
> + }
> +
> + write_reg(surf, saved);
> +
> + min[i] = pix1;
> + max[i] = pix2;
> + if (++i >= count)
> + break;
> + }
> +
> + write_reg(surf, saved);
> +}
> +
> +static void poll_pixel_flip(uint32_t devid, int pipe, int target_pixel, int target_fuzz,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t pix, pix1, pix2;
> + uint32_t saved, surf = 0;
> + int i = 0;
> +
> + switch (pipe) {
> + case 0:
> + pix = PIPEAFRAMEPIXEL;
> + case 1:
> + pix = PIPEBFRAMEPIXEL;
> + default:
> + return;
> + }
> +
> + surf = dspsurf_reg(devid, pipe);
> +
> + saved = read_reg(surf);
> +
> + while (!quit) {
> + while (!quit){
> + pix1 = read_reg(pix) & PIPE_PIXEL_MASK;
> + if (pix1 == target_pixel)
> + break;
> + }
> +
> + write_reg(surf, saved+4096);
> +
> + while (!quit){
> + pix2 = read_reg(pix) & PIPE_PIXEL_MASK;
> + if (pix2 >= target_pixel + target_fuzz)
> + break;
> + }
> +
> + write_reg(surf, saved);
> +
> + min[i] = pix1;
> + max[i] = pix2;
> + if (++i >= count)
> + break;
> + }
> +
> + write_reg(surf, saved);
> +}
> +
> +static void poll_pixel_wrap(int pipe, uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t pix, pix1, pix2;
> + int i = 0;
> +
> + switch (pipe) {
> + case 0:
> + pix = PIPEAFRAMEPIXEL;
> + break;
> + case 1:
> + pix = PIPEBFRAMEPIXEL;
> + break;
> + default:
> + return;
> + }
> +
> + while (!quit) {
> + pix1 = read_reg(pix);
> + pix2 = read_reg(pix);
> +
> + pix1 &= PIPE_PIXEL_MASK;
> + pix2 &= PIPE_PIXEL_MASK;
> +
> + if (pix2 >= pix1)
> + continue;
> +
> + min[i] = pix1;
> + max[i] = pix2;
> + if (++i >= count)
> + break;
> + }
> +}
> +
> +static void poll_dsl_pipestat(int pipe, int bit,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2, iir, iir1, iir2, iir_bit, iir_mask;
> + bool field1, field2;
> + int i[2] = {};
> +
> + switch (pipe) {
> + case 0:
> + iir_bit = 1 << bit;
> + iir = PIPEASTAT;
> + break;
> + case 1:
> + iir_bit = 1 << bit;
> + iir = PIPEBSTAT;
> + break;
> + default:
> + return;
> + }
> +
> + dsl = dsl_reg(pipe);
> +
> + iir_mask = read_reg(iir) & 0x7fff0000;
> +
> + write_reg(iir, iir_mask | iir_bit);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + iir1 = read_reg(iir);
> + iir2 = read_reg(iir);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (!(iir2 & iir_bit))
> + continue;
> +
> + if (iir1 & iir_bit) {
> + write_reg(iir, iir_mask | iir_bit);
> + continue;
> + }
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +}
> +
> +static void poll_dsl_iir_gen2(int pipe, int bit,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2, iir1, iir2, imr_save, ier_save;
> + bool field1, field2;
> + int i[2] = {};
> +
> + bit = 1 << bit;
> +
> + dsl = dsl_reg(pipe);
> +
> + imr_save = read_reg_16(IMR);
> + ier_save = read_reg_16(IER);
> +
> + write_reg_16(IER, ier_save & ~bit);
> + write_reg_16(IMR, imr_save & ~bit);
> +
> + write_reg_16(IIR, bit);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + iir1 = read_reg_16(IIR);
> + iir2 = read_reg_16(IIR);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (!(iir2 & bit))
> + continue;
> +
> + write_reg_16(IIR, bit);
> +
> + if (iir1 & bit)
> + continue;
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +
> + write_reg_16(IMR, imr_save);
> + write_reg_16(IER, ier_save);
> +}
> +
> +static void poll_dsl_iir_gen3(int pipe, int bit,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2, iir1, iir2, imr_save, ier_save;
> + bool field1, field2;
> + int i[2] = {};
> +
> + bit = 1 << bit;
> +
> + dsl = dsl_reg(pipe);
> +
> + imr_save = read_reg(IMR);
> + ier_save = read_reg(IER);
> +
> + write_reg(IER, ier_save & ~bit);
> + write_reg(IMR, imr_save & ~bit);
> +
> + write_reg(IIR, bit);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + iir1 = read_reg(IIR);
> + iir2 = read_reg(IIR);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (!(iir2 & bit))
> + continue;
> +
> + write_reg(IIR, bit);
> +
> + if (iir1 & bit)
> + continue;
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +
> + write_reg(IMR, imr_save);
> + write_reg(IER, ier_save);
> +}
> +
> +static void poll_dsl_deiir(uint32_t devid, int pipe, int bit,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2, iir1, iir2, imr_save, ier_save;
> + bool field1, field2;
> + uint32_t iir, ier, imr;
> + int i[2] = {};
> +
> + bit = 1 << bit;
> +
> + dsl = dsl_reg(pipe);
> +
> + if (IS_GEN8(devid)) {
> + iir = GEN8_DE_PIPE_IIR(pipe);
> + ier = GEN8_DE_PIPE_IER(pipe);
> + imr = GEN8_DE_PIPE_IMR(pipe);
> + } else {
> + iir = DEIIR;
> + ier = DEIER;
> + imr = DEIMR;
> + }
> +
> + imr_save = read_reg(imr);
> + ier_save = read_reg(ier);
> +
> + write_reg(ier, ier_save & ~bit);
> + write_reg(imr, imr_save & ~bit);
> +
> + write_reg(iir, bit);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + iir1 = read_reg(iir);
> + iir2 = read_reg(iir);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (!(iir2 & bit))
> + continue;
> +
> + write_reg(iir, bit);
> +
> + if (iir1 & bit)
> + continue;
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +
> + write_reg(imr, imr_save);
> + write_reg(ier, ier_save);
> +}
> +
> +static void poll_dsl_framecount_g4x(int pipe, uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2, frm, frm1, frm2;
> + bool field1, field2;
> + int i[2] = {};
> +
> + switch (pipe) {
> + case 0:
> + frm = PIPEAFRMCOUNT_G4X;
> + break;
> + case 1:
> + frm = PIPEBFRMCOUNT_G4X;
> + break;
> + case 2:
> + frm = PIPECFRMCOUNT_G4X;
> + break;
> + default:
> + return;
> + }
> +
> + dsl = dsl_reg(pipe);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + frm1 = read_reg(frm);
> + frm2 = read_reg(frm);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (frm1 + 1 != frm2)
> + continue;
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +}
> +
> +static void poll_dsl_flipcount_g4x(uint32_t devid, int pipe,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2, flp, flp1, flp2, surf;
> + bool field1, field2;
> + int i[2] = {};
> +
> + switch (pipe) {
> + case 0:
> + flp = PIPEAFLIPCOUNT_G4X;
> + break;
> + case 1:
> + flp = PIPEBFLIPCOUNT_G4X;
> + break;
> + case 2:
> + flp = PIPECFLIPCOUNT_G4X;
> + break;
> + default:
> + return;
> + }
> +
> + dsl = dsl_reg(pipe);
> + surf = dspsurf_reg(devid, pipe);
> +
> + while (!quit) {
> + usleep(10);
> + dsl1 = read_reg(dsl);
> + flp1 = read_reg(flp);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + return;
> +
> + write_reg(surf, read_reg(surf));
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + flp2 = read_reg(flp);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (flp1 == flp2)
> + continue;
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> + if (i[field1] >= count)
> + break;
> + }
> +}
> +
> +static void poll_dsl_framecount_gen3(int pipe, uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2, frm, frm1, frm2;
> + bool field1, field2;
> + int i[2] = {};
> +
> + switch (pipe) {
> + case 0:
> + frm = PIPEAFRAMEPIXEL;
> + break;
> + case 1:
> + frm = PIPEBFRAMEPIXEL;
> + break;
> + default:
> + return;
> + }
> +
> + dsl = dsl_reg(pipe);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + frm1 = read_reg(frm) >> 24;
> + frm2 = read_reg(frm) >> 24;
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (frm1 + 1 != frm2)
> + continue;
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +}
> +
> +static void poll_dsl_pan(uint32_t devid, int pipe, int target_scanline, int target_fuzz,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1 = 0, dsl2 = 0;
> + bool field1 = false, field2 = false;
> + uint32_t saved, surf = 0;
> + int i[2] = {};
> +
> + dsl = dsl_reg(pipe);
> + surf = dspoffset_reg(devid, pipe);
> +
> + saved = read_reg(surf);
> +
> + while (!quit) {
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + field1 = dsl1 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + if (dsl1 == target_scanline)
> + break;
> + }
> +
> + write_reg(surf, saved+256);
> +
> + while (!quit) {
> + dsl2 = read_reg(dsl);
> + field2 = dsl1 & 0x80000000;
> + dsl2 &= ~0x80000000;
> + if (dsl2 == target_scanline + target_fuzz)
> + break;
> + }
> +
> + write_reg(surf, saved);
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +
> + write_reg(surf, saved);
> +}
> +
> +static void poll_dsl_flip(uint32_t devid, int pipe, int target_scanline, int target_fuzz,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1 = 0, dsl2 = 0;
> + bool field1 = false, field2 = false;
> + uint32_t saved, surf = 0;
> + int i[2] = {};
> +
> + dsl = dsl_reg(pipe);
> + surf = dspsurf_reg(devid, pipe);
> +
> + saved = read_reg(surf);
> +
> + while (!quit) {
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + field1 = dsl1 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + if (dsl1 == target_scanline)
> + break;
> + }
> +
> + write_reg(surf, saved+4096);
> +
> + while (!quit) {
> + dsl2 = read_reg(dsl);
> + field2 = dsl1 & 0x80000000;
> + dsl2 &= ~0x80000000;
> + if (dsl2 == target_scanline + target_fuzz)
> + break;
> + }
> +
> + write_reg(surf, saved);
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +
> + write_reg(surf, saved);
> +}
> +
> +static void poll_dsl_surflive(uint32_t devid, int pipe,
> + uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1 = 0, dsl2 = 0, surf, surf1, surf2, surflive, surfl1 = 0, surfl2, saved, tmp;
> + bool field1 = false, field2 = false;
> + int i[2] = {};
> +
> + switch (pipe) {
> + case 0:
> + surflive = DSPASURFLIVE;
> + break;
> + case 1:
> + surflive = DSPBSURFLIVE;
> + break;
> + case 2:
> + surflive = DSPCSURFLIVE;
> + break;
> + default:
> + return;
> + }
> +
> + dsl = dsl_reg(pipe);
> + surf = dspsurf_reg(devid, pipe);
> +
> + saved = read_reg(surf);
> +
> + surf1 = saved & ~0xfff;
> + surf2 = surf1 + 4096;
> +
> + while (!quit) {
> + write_reg(surf, surf2);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + surfl1 = read_reg(surflive) & ~0xfff;
> + surfl2 = read_reg(surflive) & ~0xfff;
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (surfl2 == surf2)
> + break;
> + }
> +
> + if (surfl1 != surf2) {
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +
> + tmp = surf1;
> + surf1 = surf2;
> + surf2 = tmp;
> + }
> +
> + write_reg(surf, saved);
> +}
> +
> +static void poll_dsl_wrap(int pipe, uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2;
> + bool field1, field2;
> + int i[2] = {};
> +
> + dsl = dsl_reg(pipe);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (dsl2 >= dsl1)
> + continue;
> +
> + if (field1 != field2)
> + printf("fields are different (%u:%u -> %u:%u)\n",
> + field1, dsl1, field2, dsl2);
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +}
> +
> +static void poll_dsl_field(int pipe, uint32_t *min, uint32_t *max, const int count)
> +{
> + uint32_t dsl, dsl1, dsl2;
> + bool field1, field2;
> + int i[2] = {};
> +
> + dsl = dsl_reg(pipe);
> +
> + while (!quit) {
> + dsl1 = read_reg(dsl);
> + dsl2 = read_reg(dsl);
> +
> + field1 = dsl1 & 0x80000000;
> + field2 = dsl2 & 0x80000000;
> + dsl1 &= ~0x80000000;
> + dsl2 &= ~0x80000000;
> +
> + if (field1 == field2)
> + continue;
> +
> + min[field1*count+i[field1]] = dsl1;
> + max[field1*count+i[field1]] = dsl2;
> + if (++i[field1] >= count)
> + break;
> + }
> +}
> +
> +static char pipe_name(int pipe)
> +{
> + return pipe + 'A';
> +}
> +
> +static const char *test_name(enum test test, int pipe, int bit, bool test_pixel_count)
> +{
> + static char str[32];
> + const char *type = test_pixel_count ? "pixel" : "dsl";
> +
> + switch (test) {
> + case TEST_PIPESTAT:
> + snprintf(str, sizeof str, "%s / pipe %c / PIPESTAT[%d] (gmch)", type, pipe_name(pipe), bit);
> + return str;
> + case TEST_IIR_GEN2:
> + snprintf(str, sizeof str, "%s / pipe %c / IIR[%d] (gen2)", type, pipe_name(pipe), bit);
> + return str;
> + case TEST_IIR_GEN3:
> + snprintf(str, sizeof str, "%s / pipe %c / IIR[%d] (gen3+)", type, pipe_name(pipe), bit);
> + return str;
> + case TEST_DEIIR:
> + snprintf(str, sizeof str, "%s / pipe %c / DEIIR[%d] (pch)", type, pipe_name(pipe), bit);
> + return str;
> + case TEST_FRAMECOUNT_GEN3:
> + snprintf(str, sizeof str, "%s / pipe %c / Frame count (gen3/4)", type, pipe_name(pipe));
> + return str;
> + case TEST_FRAMECOUNT_G4X:
> + snprintf(str, sizeof str, "%s / pipe %c / Frame count (g4x+)", type, pipe_name(pipe));
> + return str;
> + case TEST_FLIPCOUNT:
> + snprintf(str, sizeof str, "%s / pipe %c / Flip count (g4x+)", type, pipe_name(pipe));
> + return str;
> + case TEST_PAN:
> + snprintf(str, sizeof str, "%s / pipe %c / Pan", type, pipe_name(pipe));
> + return str;
> + case TEST_FLIP:
> + snprintf(str, sizeof str, "%s / pipe %c / Flip", type, pipe_name(pipe));
> + return str;
> + case TEST_SURFLIVE:
> + snprintf(str, sizeof str, "%s / pipe %c / Surflive", type, pipe_name(pipe));
> + return str;
> + case TEST_WRAP:
> + snprintf(str, sizeof str, "%s / pipe %c / Wrap", type, pipe_name(pipe));
> + return str;
> + case TEST_FIELD:
> + snprintf(str, sizeof str, "%s / pipe %c / Field", type, pipe_name(pipe));
> + return str;
> + default:
> + return "";
> + }
> +}
> +
> +static void usage(const char *name)
> +{
> + fprintf(stderr, "Usage: %s [options]\n"
> + " -t,--test <pipestat|iir|framecount|flipcount|pan|flip|surflive|wrap|field>\n"
> + " -p,--pipe <pipe>\n"
> + " -b,--bit <bit>\n"
> + " -l,--line <target scanline/pixel>\n"
> + " -f,--fuzz <target fuzz>\n"
> + " -x,--pixel\n",
> + name);
> + exit(1);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + int fd, i;
> + int pipe = 0, bit = 0, target_scanline = 0, target_fuzz = 1;
> + bool test_pixelcount = false;
> + uint32_t devid;
> + uint32_t min[2*128] = {};
> + uint32_t max[2*128] = {};
> + uint32_t a, b;
> + enum test test = TEST_INVALID;
> + const int count = ARRAY_SIZE(min)/2;
> +
> + for (;;) {
> + static const struct option long_options[] = {
> + { .name = "test", .has_arg = required_argument, },
> + { .name = "pipe", .has_arg = required_argument, },
> + { .name = "bit", .has_arg = required_argument, },
> + { .name = "line", .has_arg = required_argument, },
> + { .name = "fuzz", .has_arg = required_argument, },
> + { .name = "pixel", .has_arg = no_argument, },
> + { },
> + };
> +
> + int opt = getopt_long(argc, argv, "t:p:b:l:f:x", long_options, NULL);
> + if (opt == -1)
> + break;
> +
> + switch (opt) {
> + case 't':
> + if (!strcmp(optarg, "pipestat"))
> + test = TEST_PIPESTAT;
> + else if (!strcmp(optarg, "iir"))
> + test = TEST_IIR;
> + else if (!strcmp(optarg, "framecount"))
> + test = TEST_FRAMECOUNT;
> + else if (!strcmp(optarg, "flipcount"))
> + test = TEST_FLIPCOUNT;
> + else if (!strcmp(optarg, "pan"))
> + test = TEST_PAN;
> + else if (!strcmp(optarg, "flip"))
> + test = TEST_FLIP;
> + else if (!strcmp(optarg, "surflive"))
> + test = TEST_SURFLIVE;
> + else if (!strcmp(optarg, "wrap"))
> + test = TEST_WRAP;
> + else if (!strcmp(optarg, "field"))
> + test = TEST_FIELD;
> + else
> + usage(argv[0]);
> + break;
> + case 'p':
> + pipe = atoi(optarg);
> + if (pipe < 0 || pipe > 2)
> + usage(argv[0]);
> + break;
> + case 'b':
> + bit = atoi(optarg);
> + if (bit < 0 || bit > 31)
> + usage(argv[0]);
> + break;
> + case 'l':
> + target_scanline = atoi(optarg);
> + if (target_scanline < 0)
> + usage(argv[0]);
> + break;
> + case 'f':
> + target_fuzz = atoi(optarg);
> + if (target_fuzz <= 0)
> + usage(argv[0]);
> + break;
> + case 'x':
> + test_pixelcount = true;
> + break;
> + }
> + }
> +
> + fd = drm_open_any();
> + devid = intel_get_drm_devid(fd);
> + close(fd);
> +
> + /*
> + * check if the requires registers are
> + * avilable on the current platform.
> + */
> + if (IS_GEN2(devid)) {
> + if (pipe > 1)
> + usage(argv[0]);
> +
> + if (test_pixelcount)
> + usage(argv[0]);
> +
> + switch (test) {
> + case TEST_IIR:
> + test = TEST_IIR_GEN2;
> + break;
> + case TEST_PIPESTAT:
> + case TEST_PAN:
> + break;
> + case TEST_FLIP:
> + test = TEST_PAN;
> + break;
> + default:
> + usage(argv[0]);
> + }
> + } else if (IS_GEN3(devid) ||
> + (IS_GEN4(devid) && !IS_G4X(devid))) {
> + if (pipe > 1)
> + usage(argv[0]);
> +
> + switch (test) {
> + case TEST_IIR:
> + test = TEST_IIR_GEN3;
> + break;
> + case TEST_FRAMECOUNT:
> + test = TEST_FRAMECOUNT_GEN3;
> + break;
> + case TEST_PIPESTAT:
> + case TEST_PAN:
> + case TEST_WRAP:
> + case TEST_FIELD:
> + break;
> + case TEST_FLIP:
> + if (IS_GEN3(devid))
> + test = TEST_PAN;
> + break;
> + default:
> + usage(argv[0]);
> + }
> + } else if (IS_G4X(devid) || IS_VALLEYVIEW(devid)) {
> + if (IS_VALLEYVIEW(devid))
> + vlv_offset = 0x180000;
> +
> + if (pipe > 1)
> + usage(argv[0]);
> +
> + if (test_pixelcount)
> + usage(argv[0]);
> +
> + switch (test) {
> + case TEST_IIR:
> + test = TEST_IIR_GEN3;
> + break;
> + case TEST_FRAMECOUNT:
> + test = TEST_FRAMECOUNT_G4X;
> + break;
> + case TEST_FLIPCOUNT:
> + case TEST_PIPESTAT:
> + case TEST_PAN:
> + case TEST_FLIP:
> + case TEST_SURFLIVE:
> + case TEST_WRAP:
> + case TEST_FIELD:
> + break;
> + default:
> + usage(argv[0]);
> + }
> + } else if (HAS_PCH_SPLIT(devid) &&
> + (IS_GEN5(devid) || IS_GEN6(devid) || IS_GEN7(devid))) {
> + if (pipe > 1 &&
> + (IS_GEN5(devid) || IS_GEN6(devid)))
> + usage(argv[0]);
> +
> + if (test_pixelcount)
> + usage(argv[0]);
> +
> + switch (test) {
> + case TEST_IIR:
> + test = TEST_DEIIR;
> + break;
> + case TEST_FRAMECOUNT:
> + test = TEST_FRAMECOUNT_G4X;
> + break;
> + case TEST_FLIPCOUNT:
> + case TEST_PAN:
> + case TEST_FLIP:
> + case TEST_SURFLIVE:
> + case TEST_WRAP:
> + case TEST_FIELD:
> + break;
> + default:
> + usage(argv[0]);
> + }
> + } else if (IS_GEN8(devid)) {
> + if (test_pixelcount)
> + usage(argv[0]);
> +
> + switch (test) {
> + case TEST_IIR:
> + test = TEST_DEIIR;
> + break;
> + case TEST_FRAMECOUNT:
> + test = TEST_FRAMECOUNT_G4X;
> + break;
> + case TEST_FLIPCOUNT:
> + case TEST_PAN:
> + case TEST_FLIP:
> + case TEST_SURFLIVE:
> + case TEST_WRAP:
> + case TEST_FIELD:
> + break;
> + default:
> + usage(argv[0]);
> + }
> + } else {
> + usage(argv[0]);
> + }
> +
> + switch (test) {
> + case TEST_IIR:
> + case TEST_FRAMECOUNT:
> + /* should no longer have the generic tests here */
> + assert(0);
> + default:
> + break;
> + }
> +
> + intel_register_access_init(intel_get_pci_device(), 0);
> +
> + printf("%s?\n", test_name(test, pipe, bit, test_pixelcount));
> +
> + signal(SIGHUP, sighandler);
> + signal(SIGINT, sighandler);
> + signal(SIGTERM, sighandler);
> +
> + switch (test) {
> + case TEST_PIPESTAT:
> + if (test_pixelcount)
> + poll_pixel_pipestat(pipe, bit, min, max, count);
> + else
> + poll_dsl_pipestat(pipe, bit, min, max, count);
> + break;
> + case TEST_IIR_GEN2:
> + assert(!test_pixelcount);
> + poll_dsl_iir_gen2(pipe, bit, min, max, count);
> + break;
> + case TEST_IIR_GEN3:
> + if (test_pixelcount)
> + poll_pixel_iir_gen3(pipe, bit, min, max, count);
> + else
> + poll_dsl_iir_gen3(pipe, bit, min, max, count);
> + break;
> + case TEST_DEIIR:
> + assert(!test_pixelcount);
> + poll_dsl_deiir(devid, pipe, bit, min, max, count);
> + break;
> + case TEST_FRAMECOUNT_GEN3:
> + if (test_pixelcount)
> + poll_pixel_framecount_gen3(pipe, min, max, count);
> + else
> + poll_dsl_framecount_gen3(pipe, min, max, count);
> + break;
> + case TEST_FRAMECOUNT_G4X:
> + assert(!test_pixelcount);
> + poll_dsl_framecount_g4x(pipe, min, max, count);
> + break;
> + case TEST_FLIPCOUNT:
> + assert(!test_pixelcount);
> + poll_dsl_flipcount_g4x(devid, pipe, min, max, count);
> + break;
> + case TEST_PAN:
> + if (test_pixelcount)
> + poll_pixel_pan(devid, pipe, target_scanline, target_fuzz,
> + min, max, count);
> + else
> + poll_dsl_pan(devid, pipe, target_scanline, target_fuzz,
> + min, max, count);
> + break;
> + case TEST_FLIP:
> + if (test_pixelcount)
> + poll_pixel_flip(devid, pipe, target_scanline, target_fuzz,
> + min, max, count);
> + else
> + poll_dsl_flip(devid, pipe, target_scanline, target_fuzz,
> + min, max, count);
> + break;
> + case TEST_SURFLIVE:
> + poll_dsl_surflive(devid, pipe, min, max, count);
> + break;
> + case TEST_WRAP:
> + if (test_pixelcount)
> + poll_pixel_wrap(pipe, min, max, count);
> + else
> + poll_dsl_wrap(pipe, min, max, count);
> + break;
> + case TEST_FIELD:
> + poll_dsl_field(pipe, min, max, count);
> + break;
> + default:
> + assert(0);
> + }
> +
> + intel_register_access_fini();
> +
> + if (quit)
> + return 0;
> +
> + for (i = 0; i < count; i++) {
> + if (min[0*count+i] == 0 && max[0*count+i] == 0)
> + break;
> + printf("[%u] %4u - %4u (%4u)\n", 0, min[0*count+i], max[0*count+i],
> + (min[0*count+i] + max[0*count+i] + 1) >> 1);
> + }
> + for (i = 0; i < count; i++) {
> + if (min[1*count+i] == 0 && max[1*count+i] == 0)
> + break;
> + printf("[%u] %4u - %4u (%4u)\n", 1, min[1*count+i], max[1*count+i],
> + (min[1*count+i] + max[1*count+i] + 1) >> 1);
> + }
> +
> + a = 0;
> + b = 0xffffffff;
> + for (i = 0; i < count; i++) {
> + if (min[0*count+i] == 0 && max[0*count+i] == 0)
> + break;
> + a = max(a, min[0*count+i]);
> + b = min(b, max[0*count+i]);
> + }
> +
> + printf("%s: [%u] %6u - %6u\n", test_name(test, pipe, bit, test_pixelcount), 0, a, b);
> +
> + a = 0;
> + b = 0xffffffff;
> + for (i = 0; i < count; i++) {
> + if (min[1*count+i] == 0 && max[1*count+i] == 0)
> + break;
> + a = max(a, min[1*count+i]);
> + b = min(b, max[1*count+i]);
> + }
> +
> + printf("%s: [%u] %6u - %6u\n", test_name(test, pipe, bit, test_pixelcount), 1, a, b);
> +
> + return 0;
> +}
> --
> 1.8.5.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
next prev parent reply other threads:[~2014-06-12 7:21 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-11 16:41 [PATCH igt 1/4] lib/igt_debugfs: Don't fail if debugfs is already mounted ville.syrjala
2014-06-11 16:41 ` [PATCH igt 2/4] lib/igt_debufs: Add IGT_NO_FORCEWAKE environment variable ville.syrjala
2014-06-11 16:41 ` [PATCH igt 3/4] tools: Add intel_iosf_sb_{read, write} tools ville.syrjala
2014-06-11 16:41 ` [PATCH igt 4/4] tools/intel_poller: Add a new tool that will poll various display registers ville.syrjala
2014-06-12 7:21 ` Daniel Vetter [this message]
2014-06-12 7:20 ` [PATCH igt 1/4] lib/igt_debugfs: Don't fail if debugfs is already mounted Daniel Vetter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140612072129.GT5821@phenom.ffwll.local \
--to=daniel@ffwll.ch \
--cc=intel-gfx@lists.freedesktop.org \
--cc=ville.syrjala@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.