1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-or-later
# SPDX-FileCopyrightText: 2018-2019 Renesas Electronics Corporation
import kmstest
import pykms
import time
class Output(object):
def __init__(self):
self.crtc = None
self.connector = None
self.fb = None
class BRxAllocTest(kmstest.KMSTest):
"""Test dynamic BRU and BRS allocation in the VSP."""
def main(self):
# This test requires usage of two CRTCs connected to the same VSPDL
# instance to test dynamic assignment of the BRU and BRS to pipelines.
# This is only occurs on H3 ES2.0 and M3-N. Check the SoC model through
# sysfs as we can't detected it through the DRM/KMS API.
soc = open('/sys/devices/soc0/soc_id', 'rb').read().strip().decode()
if soc not in ['r8a7795', 'r8a77965']:
self.skip('VSPDL (BRU+BRS) not available')
return
outputs = [Output(), Output()]
# Get the first and last CRTCs
for crtc in self.card.crtcs:
if outputs[0].crtc == None or crtc.id < outputs[0].crtc.id:
outputs[0].crtc = crtc
if outputs[1].crtc == None or crtc.id > outputs[1].crtc.id:
outputs[1].crtc = crtc
# Verify that the two CRTCs share the same planes
planes = outputs[0].crtc.possible_planes
if planes != outputs[1].crtc.possible_planes:
self.skip(f'Planes differ for CRTCs {outputs[0].crtc.id} and {outputs[1].crtc.id}')
return
self.logger.log(f'Found {len(planes)} planes for CRTCs {outputs[0].crtc.id} '
f'and {outputs[1].crtc.id}')
# Get one connector for each CRTC
for connector in self.output_connectors():
# Skip disconnected connectors
if not connector.connected():
continue
for crtc in connector.get_possible_crtcs():
if crtc == outputs[0].crtc:
outputs[0].connector = connector
if crtc == outputs[1].crtc:
outputs[1].connector = connector
if not outputs[0].connector or not outputs[1].connector:
self.skip(f'No connected connectors for CRTCs {outputs[0].crtc.id} '
f'and {outputs[1].crtc.id}')
return
self.start(f'Moving {len(planes)} planes from {outputs[0].connector.fullname} '
f'to {outputs[0].connector.fullname}')
# Set the initial mode for both outputs and wait 5s for the monitors to
# wake up.
for output in outputs:
# Get the default mode and create a framebuffer
mode = output.connector.get_default_mode()
output.fb = pykms.DumbFramebuffer(self.card, mode.hdisplay, mode.vdisplay, 'XR24')
pykms.draw_test_pattern(output.fb)
# Set the mode with no plane
ret = self.atomic_crtc_mode_set(output.crtc, output.connector, mode, sync=True)
if ret < 0:
self.fail(f'atomic mode set on {output.connector.fullname} failed with {ret}')
return
self.logger.log('Initial atomic mode set completed')
time.sleep(5)
# Add all planes
offset = 0
output = outputs[0]
for plane in planes:
self.logger.log(f'Adding plane {plane.id} to {output.connector.fullname}')
source = kmstest.Rect(0, 0, output.fb.width, output.fb.height)
destination = kmstest.Rect(offset, offset, output.fb.width, output.fb.height)
ret = self.atomic_plane_set(plane, output.crtc, source, destination, output.fb, sync=True)
if ret < 0:
self.fail(f'atomic plane set failed with {ret}')
return
offset += 50
time.sleep(2)
# Move all planes one by one
offset = 0
output = outputs[1]
for plane in planes:
self.logger.log(f'Moving plane {plane.id} to {output.connector.fullname}')
# Switching CRTC directly is not supported by DRM, start by
# disabling the plane.
ret = self.atomic_plane_disable(plane)
if ret < 0:
self.fail(f'atomic plane disable failed with {ret}')
return
source = kmstest.Rect(0, 0, output.fb.width, output.fb.height)
destination = kmstest.Rect(offset, offset, output.fb.width, output.fb.height)
ret = self.atomic_plane_set(plane, output.crtc, source, destination, output.fb)
if ret < 0:
self.fail(f'atomic plane set failed with {ret}')
return
self.run(1)
offset += 50
self.success()
self.atomic_crtc_disable(outputs[0].crtc)
self.atomic_crtc_disable(outputs[1].crtc)
BRxAllocTest().execute()
|