[Intel-gfx] [PATCH i-g-t] tools/intel_display_poller: Poll DSPARB across mixed pipe vblank
ville.syrjala at linux.intel.com
ville.syrjala at linux.intel.com
Wed Aug 10 13:35:44 UTC 2016
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Add another mode which changes the DSPARB registers at specific
scanlines, to determine if the individual bits get latches only
on the vblank of the relevant pipe, of if other pipes would cause
premature latching to happen when their vblank happens first.
The results I got on my CHV were that there is no premature latching.
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
lib/intel_reg.h | 2 +
tools/intel_display_poller.c | 180 +++++++++++++++++++++++++++++++++++++++----
2 files changed, 167 insertions(+), 15 deletions(-)
diff --git a/lib/intel_reg.h b/lib/intel_reg.h
index 3a28c08c3595..f2e6d1d60216 100644
--- a/lib/intel_reg.h
+++ b/lib/intel_reg.h
@@ -2223,6 +2223,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPARB_BSTART_SHIFT 0
#define DSPARB_BEND_SHIFT 9 /* on 855 */
#define DSPARB_AEND_SHIFT 0
+#define DSPARB2 0x70060
+#define DSPARB3 0x7006c
#define DSPFW1 0x70034
#define DSPFW2 0x70038
#define DSPFW3 0x7003c
diff --git a/tools/intel_display_poller.c b/tools/intel_display_poller.c
index eab17c52428e..9a6ec3d2af36 100644
--- a/tools/intel_display_poller.c
+++ b/tools/intel_display_poller.c
@@ -54,6 +54,7 @@ enum test {
TEST_SURFLIVE,
TEST_WRAP,
TEST_FIELD,
+ TEST_DSPARB,
};
static uint32_t vlv_offset;
@@ -899,6 +900,111 @@ static void poll_dsl_field(int pipe, uint32_t *min, uint32_t *max, const int cou
}
}
+static void poll_frm_dsparb(uint32_t devid, int pipe, int pipe_2,
+ int target_scanline_a, int target_scanline_b,
+ uint32_t *min, uint32_t *max, const int count)
+{
+ uint32_t dsl[2], frm[2];
+
+ if ((read_reg(PIPE_REG(pipe, PIPEACONF)) & (1 << 31)) == 0 ||
+ (read_reg(PIPE_REG(pipe_2, PIPEACONF)) & (1 << 31)) == 0) {
+ fprintf(stderr, "pipe %c & %c should be enabled for the test\n",
+ pipe_name(pipe), pipe_name(pipe_2));
+ return;
+ }
+ if (IS_CHERRYVIEW(devid)) {
+ int pipe_3 = 3 - pipe - pipe_2;
+
+ if ((read_reg(PIPE_REG(pipe_3, PIPEACONF)) & (1 << 31)) != 0) {
+ fprintf(stderr, "pipe %c enabled, which might interfere with the test\n",
+ pipe_name(pipe_3));
+ return;
+ }
+ }
+
+ dsl[0] = PIPE_REG(pipe, PIPEA_DSL);
+ dsl[1] = PIPE_REG(pipe_2, PIPEA_DSL);
+ frm[0] = PIPE_REG(pipe, PIPEAFRMCOUNT_G4X);
+ frm[1] = PIPE_REG(pipe_2, PIPEAFRMCOUNT_G4X);
+
+ for (int n = 0; n < 20; n++)
+ printf("pipe %c %d pipe %c %d\n",
+ pipe_name(pipe), read_reg(dsl[0]),
+ pipe_name(pipe_2), read_reg(dsl[1]));
+
+ while (!quit) {
+ uint32_t saved, saved2;
+ uint32_t wr, wr2;
+ uint32_t dsl_pre[2];
+ uint32_t dsl_post[2];
+ uint32_t frm_pre[2];
+ uint32_t frm_post[2];
+
+ while (!quit) {
+ uint32_t d = read_reg(dsl[0]);
+ d &= ~0x80000000;
+ if (d == target_scanline_a)
+ break;
+ }
+
+ dsl_pre[0] = read_reg(dsl[0]);
+ frm_pre[0] = read_reg(frm[0]);
+ dsl_pre[1] = read_reg(dsl[1]);
+ frm_pre[1] = read_reg(frm[1]);
+
+ saved = read_reg(DSPARB);
+ saved2 = read_reg(DSPARB2);
+ switch (pipe) {
+ case 0:
+ //write_reg(DSPARB, (saved & ~0xff) | 0x1);
+ write_reg(DSPARB2, (saved2 & ~0x1) | 0x0);
+ break;
+ case 1:
+ //write_reg(DSPARB, (saved & ~0xff0000) | 0x10000);
+ write_reg(DSPARB2, (saved2 & ~0x100) | 0x000);
+ break;
+ case 2:
+ //write_reg(DSPARB3, (saved & ~0xff) | 0x1);
+ write_reg(DSPARB2, (saved2 & ~0x10000) | 0x00000);
+ break;
+ }
+ wr = read_reg(DSPARB);
+ wr2 = read_reg(DSPARB2);
+
+ while (!quit) {
+ uint32_t d = read_reg(dsl[1]);
+ d &= ~0x80000000;
+ if (d == target_scanline_b)
+ break;
+ }
+
+ write_reg(DSPARB, saved);
+ write_reg(DSPARB2, saved2);
+
+ dsl_post[0] = read_reg(dsl[0]);
+ frm_post[0] = read_reg(frm[0]);
+ dsl_post[1] = read_reg(dsl[1]);
+ frm_post[1] = read_reg(frm[1]);
+
+ if (frm_pre[0] == frm_post[0] &&
+ frm_pre[1] != frm_post[1]) {
+ printf("\nhit it %c %d->%d %c %d->%d\n",
+ pipe_name(pipe), frm_pre[0], frm_post[0],
+ pipe_name(pipe_2), frm_pre[1], frm_post[1]);
+ } else {
+ printf("\ndidn't hit it %c %d->%d %c %d->%d\n",
+ pipe_name(pipe), frm_pre[0], frm_post[0],
+ pipe_name(pipe_2), frm_pre[1], frm_post[1]);
+ }
+ printf("dsl %c %d->%d %c %d->%d\n",
+ pipe_name(pipe), dsl_pre[0], dsl_post[0],
+ pipe_name(pipe_2), dsl_pre[1], dsl_post[1]);
+ printf("dsparb %x -> %x -> %x, dsparb2 %x -> %x -> %x\n",
+ saved, wr, read_reg(DSPARB), saved2, wr2, read_reg(DSPARB2));
+ sleep(1);
+ }
+}
+
static const char *test_name(enum test test, int pipe, int bit, bool test_pixel_count)
{
static char str[32];
@@ -941,6 +1047,9 @@ static const char *test_name(enum test test, int pipe, int bit, bool test_pixel_
case TEST_FIELD:
snprintf(str, sizeof str, "%s / pipe %c / Field", type, pipe_name(pipe));
return str;
+ case TEST_DSPARB:
+ snprintf(str, sizeof str, "%s / DSPARB", type);
+ return str;
default:
return "";
}
@@ -949,20 +1058,46 @@ static const char *test_name(enum test test, int pipe, int bit, bool test_pixel_
static void __attribute__((noreturn)) usage(const char *name)
{
fprintf(stderr, "Usage: %s [options]\n"
- " -t,--test <pipestat|iir|framecount|flipcount|pan|flip|surflive|wrap|field>\n"
+ " -t,--test <pipestat|iir|framecount|flipcount|pan|flip|surflive|wrap|field|dsparb>\n"
" -p,--pipe <pipe>\n"
+ " -P,--Pipe <second pipe (dsparb test only)>\n"
" -b,--bit <bit>\n"
" -l,--line <target scanline/pixel>\n"
+ " -L,--Line <second target scanline (dsparb test only)>\n"
" -f,--fuzz <target fuzz>\n"
" -x,--pixel\n",
name);
exit(1);
}
+static int parse_pipe(const char *str)
+{
+ int pipe;
+
+ if (str[0] == '\0' || str[1] != '\0')
+ return -1;
+
+ pipe = str[0];
+ if (pipe >= 'a')
+ pipe -= 'a';
+ else if (pipe >= 'A')
+ pipe -= 'A';
+ else if (pipe >= '0')
+ pipe -= '0';
+ else
+ return -1;
+
+ if (pipe < 0 || pipe > 2)
+ return -1;
+
+ return pipe;
+}
+
int main(int argc, char *argv[])
{
int fd, i;
int pipe = 0, bit = 0, target_scanline = 0, target_fuzz = 1;
+ int pipe_2 = 0, target_scanline_2 = 0;
bool test_pixelcount = false;
uint32_t devid;
uint32_t min[2*128] = {};
@@ -975,14 +1110,16 @@ int main(int argc, char *argv[])
static const struct option long_options[] = {
{ .name = "test", .has_arg = required_argument, },
{ .name = "pipe", .has_arg = required_argument, },
+ { .name = "Pipe", .has_arg = required_argument, },
{ .name = "bit", .has_arg = required_argument, },
{ .name = "line", .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);
+ int opt = getopt_long(argc, argv, "t:p:P:b:l:L:f:x", long_options, NULL);
if (opt == -1)
break;
@@ -1006,22 +1143,19 @@ int main(int argc, char *argv[])
test = TEST_WRAP;
else if (!strcmp(optarg, "field"))
test = TEST_FIELD;
- else
+ else if (!strcmp(optarg, "dsparb"))
+ test = TEST_DSPARB;
+ else
usage(argv[0]);
break;
case 'p':
- if (optarg[1] != '\0')
+ pipe = parse_pipe(optarg);
+ if (pipe < 0)
usage(argv[0]);
- pipe = optarg[0];
- if (pipe >= 'a')
- pipe -= 'a';
- else if (pipe >= 'A')
- pipe -= 'A';
- else if (pipe >= '0')
- pipe -= '0';
- else
- usage(argv[0]);
- if (pipe < 0 || pipe > 2)
+ break;
+ case 'P':
+ pipe_2 = parse_pipe(optarg);
+ if (pipe_2 < 0)
usage(argv[0]);
break;
case 'b':
@@ -1034,6 +1168,11 @@ int main(int argc, char *argv[])
if (target_scanline < 0)
usage(argv[0]);
break;
+ case 'L':
+ target_scanline_2 = atoi(optarg);
+ if (target_scanline_2 < 0)
+ usage(argv[0]);
+ break;
case 'f':
target_fuzz = atoi(optarg);
if (target_fuzz <= 0)
@@ -1099,12 +1238,13 @@ int main(int argc, char *argv[])
}
} else if (IS_G4X(devid) ||
IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid)) {
+ int num_pipes = IS_CHERRYVIEW(devid) ? 3 : 2;
if (IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid))
vlv_offset = 0x180000;
if (IS_CHERRYVIEW(devid))
pipe_offset[2] = 0x4000;
- if (pipe > 1 && !IS_CHERRYVIEW(devid))
+ if (pipe >= num_pipes)
usage(argv[0]);
if (test_pixelcount)
@@ -1125,6 +1265,12 @@ int main(int argc, char *argv[])
case TEST_WRAP:
case TEST_FIELD:
break;
+ case TEST_DSPARB:
+ if (!IS_VALLEYVIEW(devid) && !IS_CHERRYVIEW(devid))
+ usage(argv[0]);
+ if (pipe_2 == pipe || pipe_2 >= num_pipes)
+ usage(argv[0]);
+ break;
default:
usage(argv[0]);
}
@@ -1259,6 +1405,10 @@ int main(int argc, char *argv[])
case TEST_FIELD:
poll_dsl_field(pipe, min, max, count);
break;
+ case TEST_DSPARB:
+ poll_frm_dsparb(devid, pipe, pipe_2,
+ target_scanline, target_scanline_2, min, max, count);
+ break;
default:
assert(0);
}
--
2.7.4
More information about the Intel-gfx
mailing list