tests/kms_flip: Check the dpms confusion
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 3 Oct 2013 16:30:56 +0000 (18:30 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 3 Oct 2013 20:31:11 +0000 (22:31 +0200)
Some kernels inadvertedly forwarded dpms changes to crtcs connected to
shared encoders even though that specific output wasn't enabled.
Hilarity ensued.

Note that we only have shared encoders on hsw (DP+HDMI) and with sdvo
cards (multi-function encoders).

v2: Do a full OFF->ON->OFF transition to make sure something actually
happens.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
tests/kms_flip.c

index ee75ee8..0ac54ea 100644 (file)
@@ -61,6 +61,8 @@
 #define TEST_FB_BAD_TILING     (1 << 17)
 #define TEST_SINGLE_BUFFER     (1 << 18)
 #define TEST_DPMS_OFF          (1 << 19)
+#define TEST_NO_2X_OUTPUT      (1 << 20)
+#define TEST_DPMS_OFF_OTHERS   (1 << 21)
 
 #define EVENT_FLIP             (1 << 0)
 #define EVENT_VBLANK           (1 << 1)
@@ -272,6 +274,29 @@ static int set_connector_dpms(drmModeConnector *connector, int mode)
                                           dpms, mode);
 }
 
+static void dpms_off_other_outputs(struct test_output *o)
+{
+       int i, n;
+       drmModeConnector *connector;
+       uint32_t connector_id;
+
+       for (i = 0; i < resources->count_connectors; i++) {
+               connector_id = resources->connectors[i];
+
+               for (n = 0; n < o->count; n++) {
+                       if (connector_id == o->kconnector[n]->connector_id)
+                               goto next;
+               }
+
+               connector = drmModeGetConnector(drm_fd, connector_id);
+
+               do_or_die(set_connector_dpms(connector,  DRM_MODE_DPMS_ON));
+               do_or_die(set_connector_dpms(connector,  DRM_MODE_DPMS_OFF));
+next:
+               ;
+       }
+}
+
 static int set_dpms(struct test_output *o, int mode)
 {
        int n;
@@ -759,6 +784,9 @@ static unsigned int run_test_step(struct test_output *o)
        do_vblank = (o->flags & TEST_VBLANK) &&
                    !(o->pending_events & EVENT_VBLANK);
 
+       if (o->flags & TEST_DPMS_OFF_OTHERS)
+               dpms_off_other_outputs(o);
+
        if (o->flags & TEST_WITH_DUMMY_BCS)
                emit_dummy_load__bcs(o);
 
@@ -1485,6 +1513,7 @@ int main(int argc, char **argv)
                                        "flip-vs-dpms-off-vs-modeset" },
                { 1, TEST_DPMS_OFF | TEST_MODESET | TEST_FLIP | TEST_SINGLE_BUFFER,
                                        "single-buffer-flip-vs-dpms-off-vs-modeset" },
+               { 30, TEST_FLIP | TEST_NO_2X_OUTPUT | TEST_DPMS_OFF_OTHERS , "dpms-off-confusion" },
        };
        int i;
 
@@ -1507,6 +1536,9 @@ int main(int argc, char **argv)
                igt_subtest(tests[i].name)
                        run_test(tests[i].duration, tests[i].flags);
 
+               if (tests[i].flags & TEST_NO_2X_OUTPUT)
+                       continue;
+
                igt_subtest_f( "2x-%s", tests[i].name)
                        run_pair(tests[i].duration, tests[i].flags);
        }
@@ -1522,6 +1554,9 @@ int main(int argc, char **argv)
                igt_subtest_f( "%s-interruptible", tests[i].name)
                        run_test(tests[i].duration, tests[i].flags);
 
+               if (tests[i].flags & TEST_NO_2X_OUTPUT)
+                       continue;
+
                igt_subtest_f( "2x-%s-interruptible", tests[i].name)
                        run_pair(tests[i].duration, tests[i].flags);
        }