#!/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[1].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) if __name__ == '__main__': BRxAllocTest().execute()