summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-06-17 19:04:30 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-06-18 21:07:47 +0300
commit3cd7e6814ceacb53602e97893fb5e5bb7b2b1dcf (patch)
tree7b349f7c2633fe568a834ca98036cb211106b32c
parent6f6528df8b6de771ad4dab5ac32d81cb6e858454 (diff)
kmstest.py: Fix CRTC disabling
The KMSTest.atomic_crtc_disable() method deactivates a CRTC but doesn't fully disable it, which requires setting the MODE_ID to 0. Furthermore it doesn't de-associate the CRTC from connectors and planes, which causes atomic check failures as a fully disabled CRTC can't be associated with connectors. It can also lead to the next test failing due to resources still being allocated to the CRTC. To fix this, introduce an AtomicRequest class that wraps around pykms.AtomicReq, and stores a copy of all the properties. When the request is committed the properties are added to a global state, which is then used to locate and release connectors and planes associated with the CRTC in KMSTest.atomic_crtc_disable(). Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
-rwxr-xr-xtests/kms-test-crc.py2
-rwxr-xr-xtests/kmstest.py66
2 files changed, 61 insertions, 7 deletions
diff --git a/tests/kms-test-crc.py b/tests/kms-test-crc.py
index 30d8bea..29147e5 100755
--- a/tests/kms-test-crc.py
+++ b/tests/kms-test-crc.py
@@ -56,7 +56,7 @@ class CRCTest(kmstest.KMSTest):
self.fail("atomic mode set failed with %d" % ret)
continue
- req = pykms.AtomicReq(self.card)
+ req = kmstest.AtomicRequest(self.card)
offset = 100
for plane in planes:
diff --git a/tests/kmstest.py b/tests/kmstest.py
index 12454df..706ba91 100755
--- a/tests/kmstest.py
+++ b/tests/kmstest.py
@@ -1,5 +1,6 @@
#!/usr/bin/python3
+import collections.abc
import errno
import fcntl
import os
@@ -208,6 +209,41 @@ class Rect(object):
self.height = height
+class AtomicRequest(pykms.AtomicReq):
+ """pymkms.AtomicReq wrapper to track state changes"""
+ def __init__(self, test):
+ super().__init__(test.card)
+ self.__test = test
+ self.__props = {}
+
+ def add(self, obj, *kwargs):
+ if obj.id not in self.__props:
+ self.__props[obj.id] = {}
+ props = self.__props[obj.id]
+
+ if len(kwargs) == 1 and isinstance(kwargs[0], collections.abc.Mapping):
+ props.update(kwargs[0])
+ elif len(kwargs) == 2:
+ props[kwargs[0]] = kwargs[1]
+
+ super().add(obj, *kwargs)
+
+ def commit(self, data=0, allow_modeset=False):
+ ret = super().commit(data, allow_modeset)
+ if ret == 0:
+ self.__test._props.update(self.__props)
+ return ret
+
+ def commit_sync(self, allow_modeset=False):
+ ret = super().commit_sync(allow_modeset)
+ if ret == 0:
+ self.__test._props.update(self.__props)
+ return ret
+
+ def __repr__(self):
+ return repr(self.__props)
+
+
class KMSTest(object):
def __init__(self, use_default_key_handler=False):
if not getattr(self, 'main', None):
@@ -217,6 +253,8 @@ class KMSTest(object):
if not self.card.has_atomic:
raise RuntimeError("Device doesn't support the atomic API")
+ self._props = {}
+
logname = self.__class__.__name__
self.logger = Logger(logname)
@@ -233,8 +271,24 @@ class KMSTest(object):
return {k: v & ((1 << 64) - 1) for k, v in props.items()}
def atomic_crtc_disable(self, crtc, sync=True):
- req = pykms.AtomicReq(self.card)
- req.add(crtc, 'ACTIVE', False)
+ req = AtomicRequest(self)
+ req.add(crtc, {'ACTIVE': 0, 'MODE_ID': 0})
+ for connector in self.card.connectors:
+ if connector.id in self._props:
+ props = self._props[connector.id]
+ try:
+ if props['CRTC_ID'] == crtc.id:
+ req.add(connector, 'CRTC_ID', 0)
+ except KeyError:
+ pass
+ for plane in self.card.planes:
+ if plane.id in self._props:
+ props = self._props[plane.id]
+ try:
+ if props['CRTC_ID'] == crtc.id:
+ req.add(plane, {'CRTC_ID': 0, 'FB_ID': 0})
+ except KeyError:
+ pass
if sync:
return req.commit_sync(True)
else:
@@ -249,7 +303,7 @@ class KMSTest(object):
# the commit completes.
mode_blob = mode.to_blob(self.card)
- req = pykms.AtomicReq(self.card)
+ req = AtomicRequest(self)
req.add(connector, 'CRTC_ID', crtc.id)
req.add(crtc, { 'ACTIVE': 1, 'MODE_ID': mode_blob.id })
if fb:
@@ -271,7 +325,7 @@ class KMSTest(object):
return req.commit(0, True)
def atomic_plane_set(self, plane, crtc, source, destination, fb, sync=False):
- req = pykms.AtomicReq(self.card)
+ req = AtomicRequest(self)
req.add(plane, self.__format_props({
'FB_ID': fb.id,
'CRTC_ID': crtc.id,
@@ -290,7 +344,7 @@ class KMSTest(object):
return req.commit(0)
def atomic_plane_disable(self, plane, sync=True):
- req = pykms.AtomicReq(self.card)
+ req = AtomicRequest(self)
req.add(plane, { "FB_ID": 0, 'CRTC_ID': 0 })
if sync:
@@ -299,7 +353,7 @@ class KMSTest(object):
return req.commit(0)
def atomic_planes_disable(self, sync=True):
- req = pykms.AtomicReq(self.card)
+ req = AtomicRequest(self)
for plane in self.card.planes:
req.add(plane, { "FB_ID": 0, 'CRTC_ID': 0 })