Feasibility of Hardware Screen Mirroring on MediaTek DRM (DSI + HDMI)

Follow-up: Additional DRM-Level Testing Results for DSI + HDMI Mirroring

Hello,

I would like to provide additional results from low-level DRM testing (with Weston fully stopped) to clarify the feasibility of hardware mirroring between DSI and HDMI on the Genio 510.


1 Simultaneous Mode Setting Works

After stopping Weston and weston.socket:

systemctl stop weston
systemctl stop weston.socket

I successfully set independent modes on both CRTCs:

modetest -M mediatek -s 32@47:1200x1920 -s 34@56:1920x1080

Both modes were applied successfully, confirming:

  • CRTC 47 → DSI (1200x1920)

  • CRTC 56 → HDMI (1920x1080)

  • Dual pipeline operation works correctly.


2 Mode Compatibility Limitation

From modetest -pc:

  • DSI panel exposes only 1200x1920

  • HDMI does not support 1200x1920

  • HDMI supports 1920x1080, 1280x720, etc.

Attempting:

modetest -M mediatek -s 34@56:1200x1920

failed to find mode "1200x1920" for connector 34
failed to create dumb buffer: Invalid argument

Fails because the HDMI EDID does not advertise that mode.

Therefore, there is no common resolution between DSI and HDMI.


3 Plane Capabilities

From modetest -p:

modetest -p
trying to open device 'i915'...failed
trying to open device 'amdgpu'...failed
trying to open device 'radeon'...failed
trying to open device 'nouveau'...failed
trying to open device 'vmwgfx'...failed
trying to open device 'omapdrm'...failed
trying to open device 'exynos'...failed
trying to open device 'tilcdc'...failed
trying to open device 'msm'...failed
trying to open device 'sti'...failed
trying to open device 'tegra'...failed
trying to open device 'imx-drm'...failed
trying to open device 'rockchip'...failed
trying to open device 'atmel-hlcdc'...failed
trying to open device 'fsl-dcu-drm'...failed
trying to open device 'vc4'...failed
trying to open device 'virtio_gpu'...failed
trying to open device 'mediatek'...done
CRTCs:
id	fb	pos	size
47	57	(0,0)	(1200x1920)
  #0 1200x1920 60.00 1200 1250 1260 1330 1920 1945 1949 1969 157126 flags: ; type: preferred, driver
  props:
	24 VRR_ENABLED:
		flags: range
		values: 0 1
		value: 0
	27 CTM:
		flags: blob
		blobs:

		value:
	28 GAMMA_LUT:
		flags: blob
		blobs:

		value:
	29 GAMMA_LUT_SIZE:
		flags: immutable range
		values: 0 4294967295
		value: 512
56	57	(0,0)	(800x480)
  #0 800x480 60.00 800 844 932 1056 480 483 489 535 33900 flags: phsync, pvsync; type: preferred, driver
  props:
	24 VRR_ENABLED:
		flags: range
		values: 0 1
		value: 0

Planes:
id	crtc	fb	CRTC x,y	x,y	gamma size	possible crtcs
35	47	57	0,0		0,0	0       	0x00000001
  formats: XR24 AR24 BX24 BA24 AB24 XB24 RG24 BG24 RG16 UYVY YUYV
  props:
	8 type:
		flags: immutable enum
		enums: Overlay=0 Primary=1 Cursor=2
		value: 1
	30 IN_FORMATS:
		flags: immutable blob
		blobs:

		value:
			01000000000000000b00000018000000
			02000000480000005852323441523234
			42583234424132344142323458423234
			52473234424732345247313655595659
			5955595600000000ff07000000000000
			00000000000000000000000000000000
			ff000000000000000000000000000000
			6200000000000008
		in_formats blob decoded:
			 XR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BX24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BA24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 XB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG16:  LINEAR(0x0)
			 UYVY:  LINEAR(0x0)
			 YUYV:  LINEAR(0x0)
	37 rotation:
		flags: bitmask
		values: rotate-0=0x1 rotate-180=0x4 reflect-x=0x10 reflect-y=0x20
		value: 0
38	0	0	0,0		0,0	0       	0x00000001
  formats: XR24 AR24 BX24 BA24 AB24 XB24 RG24 BG24 RG16 UYVY YUYV
  props:
	8 type:
		flags: immutable enum
		enums: Overlay=0 Primary=1 Cursor=2
		value: 0
	30 IN_FORMATS:
		flags: immutable blob
		blobs:

		value:
			01000000000000000b00000018000000
			02000000480000005852323441523234
			42583234424132344142323458423234
			52473234424732345247313655595659
			5955595600000000ff07000000000000
			00000000000000000000000000000000
			ff000000000000000000000000000000
			6200000000000008
		in_formats blob decoded:
			 XR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BX24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BA24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 XB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG16:  LINEAR(0x0)
			 UYVY:  LINEAR(0x0)
			 YUYV:  LINEAR(0x0)
	40 rotation:
		flags: bitmask
		values: rotate-0=0x1 rotate-180=0x4 reflect-x=0x10 reflect-y=0x20
		value: 1
41	0	0	0,0		0,0	0       	0x00000001
  formats: XR24 AR24 BX24 BA24 AB24 XB24 RG24 BG24 RG16 UYVY YUYV
  props:
	8 type:
		flags: immutable enum
		enums: Overlay=0 Primary=1 Cursor=2
		value: 0
	30 IN_FORMATS:
		flags: immutable blob
		blobs:

		value:
			01000000000000000b00000018000000
			02000000480000005852323441523234
			42583234424132344142323458423234
			52473234424732345247313655595659
			5955595600000000ff07000000000000
			00000000000000000000000000000000
			ff000000000000000000000000000000
			6200000000000008
		in_formats blob decoded:
			 XR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BX24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BA24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 XB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG16:  LINEAR(0x0)
			 UYVY:  LINEAR(0x0)
			 YUYV:  LINEAR(0x0)
	43 rotation:
		flags: bitmask
		values: rotate-0=0x1 rotate-180=0x4 reflect-x=0x10 reflect-y=0x20
		value: 1
44	0	0	0,0		0,0	0       	0x00000001
  formats: XR24 AR24 BX24 BA24 AB24 XB24 RG24 BG24 RG16 UYVY YUYV
  props:
	8 type:
		flags: immutable enum
		enums: Overlay=0 Primary=1 Cursor=2
		value: 2
	30 IN_FORMATS:
		flags: immutable blob
		blobs:

		value:
			01000000000000000b00000018000000
			02000000480000005852323441523234
			42583234424132344142323458423234
			52473234424732345247313655595659
			5955595600000000ff07000000000000
			00000000000000000000000000000000
			ff000000000000000000000000000000
			6200000000000008
		in_formats blob decoded:
			 XR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BX24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BA24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 XB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG16:  LINEAR(0x0)
			 UYVY:  LINEAR(0x0)
			 YUYV:  LINEAR(0x0)
	46 rotation:
		flags: bitmask
		values: rotate-0=0x1 rotate-180=0x4 reflect-x=0x10 reflect-y=0x20
		value: 1
48	56	57	0,0		0,0	0       	0x00000002
  formats: XR24 AR24 BX24 BA24 AB24 XB24 RG24 BG24 RG16 UYVY YUYV
  props:
	8 type:
		flags: immutable enum
		enums: Overlay=0 Primary=1 Cursor=2
		value: 1
	30 IN_FORMATS:
		flags: immutable blob
		blobs:

		value:
			01000000000000000b00000018000000
			02000000480000005852323441523234
			42583234424132344142323458423234
			52473234424732345247313655595659
			5955595600000000ff07000000000000
			00000000000000000000000000000000
			ff000000000000000000000000000000
			6200000000000008
		in_formats blob decoded:
			 XR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BX24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BA24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 XB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG16:  LINEAR(0x0)
			 UYVY:  LINEAR(0x0)
			 YUYV:  LINEAR(0x0)
50	0	0	0,0		0,0	0       	0x00000002
  formats: XR24 AR24 BX24 BA24 AB24 XB24 RG24 BG24 RG16 UYVY YUYV
  props:
	8 type:
		flags: immutable enum
		enums: Overlay=0 Primary=1 Cursor=2
		value: 0
	30 IN_FORMATS:
		flags: immutable blob
		blobs:

		value:
			01000000000000000b00000018000000
			02000000480000005852323441523234
			42583234424132344142323458423234
			52473234424732345247313655595659
			5955595600000000ff07000000000000
			00000000000000000000000000000000
			ff000000000000000000000000000000
			6200000000000008
		in_formats blob decoded:
			 XR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BX24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BA24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 XB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG16:  LINEAR(0x0)
			 UYVY:  LINEAR(0x0)
			 YUYV:  LINEAR(0x0)
52	0	0	0,0		0,0	0       	0x00000002
  formats: XR24 AR24 BX24 BA24 AB24 XB24 RG24 BG24 RG16 UYVY YUYV
  props:
	8 type:
		flags: immutable enum
		enums: Overlay=0 Primary=1 Cursor=2
		value: 0
	30 IN_FORMATS:
		flags: immutable blob
		blobs:

		value:
			01000000000000000b00000018000000
			02000000480000005852323441523234
			42583234424132344142323458423234
			52473234424732345247313655595659
			5955595600000000ff07000000000000
			00000000000000000000000000000000
			ff000000000000000000000000000000
			6200000000000008
		in_formats blob decoded:
			 XR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BX24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BA24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 XB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG16:  LINEAR(0x0)
			 UYVY:  LINEAR(0x0)
			 YUYV:  LINEAR(0x0)
54	0	0	0,0		0,0	0       	0x00000002
  formats: XR24 AR24 BX24 BA24 AB24 XB24 RG24 BG24 RG16 UYVY YUYV
  props:
	8 type:
		flags: immutable enum
		enums: Overlay=0 Primary=1 Cursor=2
		value: 2
	30 IN_FORMATS:
		flags: immutable blob
		blobs:

		value:
			01000000000000000b00000018000000
			02000000480000005852323441523234
			42583234424132344142323458423234
			52473234424732345247313655595659
			5955595600000000ff07000000000000
			00000000000000000000000000000000
			ff000000000000000000000000000000
			6200000000000008
		in_formats blob decoded:
			 XR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AR24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BX24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BA24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 AB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 XB24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 BG24:  LINEAR(0x0) ARM_BLOCK_SIZE=32x8,MODE=SPLIT|SPARSE(0x800000000000062)
			 RG16:  LINEAR(0x0)
			 UYVY:  LINEAR(0x0)
			 YUYV:  LINEAR(0x0)


  • DSI planes → possible_crtcs = 0x1

  • HDMI planes → possible_crtcs = 0x2

  • No plane supports 0x3 (shared across CRTCs)

  • No SRC_W / CRTC_W scaling properties are exposed

Both pipelines support identical pixel formats (including ARM modifiers), but scaling properties are not visible through DRM.


4 Experimental Shared Framebuffer Test

Using modetest -P, I verified that both CRTCs can be active simultaneously and independently drive their respective planes.

However, I observed that each plane receives its own dumb buffer allocation. The two displays showed different random patterns, indicating that separate framebuffers were being scanned out rather than a single shared framebuffer.

Therefore, I could not conclusively verify true cross-CRTC shared framebuffer scanout using modetest alone.

modetest -M mediatek -a   -s 32@47:1200x1920   -s 34@56:1920x1080   -P 35@47:1200x1920   -P 48@56:1200x1920
setting mode 1200x1920-60.00Hz on connectors 32, crtc 47
setting mode 1920x1080-60.00Hz on connectors 34, crtc 56
testing 1200x1920@XR24 on plane 35, crtc 47
testing 1200x1920@XR24 on plane 48, crtc 56


Clarification Requested

Given the above:

  1. Does the MediaTek display engine support hardware clone mode internally?

  2. Is hardware scaling between outputs supported but not exposed via DRM?

  3. Is there any driver configuration or patch required to enable hardware mirroring?

  4. Or is application/compositor-level dual rendering the only supported approach?

Thank you for your guidance.