LVDS split mode vs. dual mode / IMX6 / EGLFS

Hello,

we have a strange problem with our LVDS displays.
Our goal is to display one QT application on two LVDS displays (each shows different content).
Imagine the top half of the QT application on display 1 shows the top side of the application and the second half on display two shows the second half of the application.

  1. Can we use the dual modus for this or do we need to use the split mode?
  2. Is it possible to do this in one application or do we need to start two separate applications with different frame buffers?
  3. We have tested images with dual mode and the CinematicExperienceDemo looks great being mirrored on both displays. Since we thought the split mode is required for two individual displays, we just changed the mode in the overlay two “split-mode”. Split Mode doesn’t start correctly. Displays simultaneously start to become white during the stat. Then they fade to black and do not change. Here, no terminal is visible. What’s wrong here and how can we debug it?
  4. Do we have to change anything else than the overlay to successfully start the split-mode?

Thank you very much for your help!

The patch for the overlay:

From 0e7e5a693ecb95d763aaa28d5f3ed173e8972d5f Mon Sep 17 00:00:00 2001
From: b b <b.b@yahoo.de>
Date: Fri, 2 Feb 2018 14:14:16 +0100
Subject: [PATCH 1/1] Add support for the CD-Tech S08-DC08

Add timings and 24-bit-lvds for the CD-Tech S08-DC08.
Set the LCD to fb0 and the LDB (LVDS) to fb1.
Enable both.
---
 arch/arm/boot/dts/imx6qdl-apalis.dtsi | 63 +++++++++++++++++++++++++----------
 1 file changed, 46 insertions(+), 17 deletions(-)

diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index f093b93..76e8dfc 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -89,29 +89,29 @@
 	mxcfb1: fb@0 {
 		compatible = "fsl,mxc_sdc_fb";
 		disp_dev = "ldb";
-		interface_pix_fmt = "RGB666";
-		default_bpp = <16>;
+		interface_pix_fmt = "RGB24";
+		default_bpp = <32>;
 		int_clk = <0>;
 		late_init = <0>;
-		status = "disabled";
+		status = "okay";
 	};
 
 	mxcfb2: fb@1 {
 		compatible = "fsl,mxc_sdc_fb";
-		disp_dev = "hdmi";
+		disp_dev = "lcd";
 		interface_pix_fmt = "RGB24";
-		mode_str ="1920x1080M@60";
-		default_bpp = <16>;
+		mode_str ="CLAA-WVGA";
+		default_bpp = <32>;
 		int_clk = <0>;
 		late_init = <0>;
-		status = "disabled";
+		status = "okay";
 	};
 
 	mxcfb3: fb@2 {
 		compatible = "fsl,mxc_sdc_fb";
-		disp_dev = "lcd";
-		interface_pix_fmt = "RGB565";
-		mode_str ="CLAA-WVGA";
+		disp_dev = "hdmi";
+		interface_pix_fmt = "RGB24";
+		mode_str ="1920x1080M@60";
 		default_bpp = <16>;
 		int_clk = <0>;
 		late_init = <0>;
@@ -508,19 +508,34 @@
 
 &ldb {
 	status = "okay";
-//	split-mode;
-//	dual-mode;
+//https://git.congatec.com/arm/qmx6_kernel/blob/b8a5656180f4eee73437263c58d1973a89454843/Documentation/devicetree/bindings/video/fsl,ldb.txt#L24 //https://www.toradex.cn/community/questions/16754/imx-6-lvds-display-configuration-problem.html
+	dual-mode;
 
 	lvds-channel@0 {
 		reg = <0>;
 		fsl,data-mapping = "spwg"; /* "jeida"; */
-		fsl,data-width = <18>;
+		fsl,data-width = <24>; /* "18"; */
 		crtc = "ipu2-di1";
 		primary;
 		status = "okay";
 
 		display-timings {
-			native-mode = <&timing_xga>;
+			native-mode = <&timing_S08_DC08_ch1>;
+			/* CD-Tech S08-DC08 */
+			timing_S08_DC08_ch1: 1280x320 {
+				clock-frequency = <36000000>;
+				hactive = <1280>; 
+				vactive = <320>; 
+				hback-porch = <20>;
+				hfront-porch = <72>;
+				vback-porch = <70>;
+				vfront-porch = <20>;
+				hsync-len = <10>;
+				vsync-len = <10>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				pixelclk-active = <0>;
+			};
 			/* LDB-AM-800600LTNQW-A0H */
 			timing_svga: 800x600 {
 				clock-frequency = <55000000>;
@@ -585,13 +600,27 @@
 	lvds-channel@1 {
 		reg = <1>;
 		fsl,data-mapping = "spwg";
-		fsl,data-width = <18>;
+		fsl,data-width = <24>; /* "18"; */
 		crtc = "ipu1-di0";
 		status = "okay";
 
 		display-timings {
-/*			native-mode = <&timing_svga_ch2>;*/
-			/* LDB-AM-800600LTNQW-A0H */
+			native-mode = <&timing_S08_DC08_ch2>;
+			/* CD-Tech S08-DC08 */
+			timing_S08_DC08_ch2: 1280x320 {
+				clock-frequency = <36000000>;
+				hactive = <1280>;
+				vactive = <320>;
+				hback-porch = <20>;
+				hfront-porch = <72>;
+				vback-porch = <70>;
+				vfront-porch = <20>;
+				hsync-len = <10>;
+				vsync-len = <10>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				pixelclk-active = <0>;
+			};
 			timing_svga_ch2: 800x600 {
 				clock-frequency = <55000000>;
 				hactive = <800>;
-- 
2.7.4

Can you post the complete kernel log output (e.g. via dmesg > kernel.log)?

I have created two files with the startup, fbset and dmesg (one split-mode, one dual-mode):
If you need any more please tell me what.

I think dmesg show now difference. Only the split mode and dual mode is correct detected.

link text

The LVDS modes are somewhat confusing. There are some hints in the NXP BSP documentation (the i.MX_Linux_Reference_Manual.pdf and i.MX_BSP_Porting_Guide.pdf), but the most complete description can be found in i.MX 6Dual/6Qual Application Reference Manual.

Chapter 39.4.2 says: The LVDS ports may be used as follows:

  • Single channel output
  • Dual channel output (one input source, two channels outputs for two displays) (=> dual-mode)
  • Split channel output (one input source, splitted to 2 channels on output) (=> split-mode)
  • Separate 2 channel output (2 input sources from IPU).

At first split channel output sounds promising, but I don’t think that is what is needed here. Chapter 39.5.1 Mapping of Input Data Busses says that the two channels are splitted by pixel…

So the fourth option is most likely what is needed.

  1. As far as I understand this needs no property set (no split-mode, no dual-mode). The assigned IPU framebuffers in lvds-channel@0 and lvds-channel@1 respectively should then represent the two displays.

  2. As far as I know the Qt EGLFS backend with Vivante drivers cannot handle two framebuffers at the moment. So this have to be two applications, or there needs to be another layer of abstraction in between (X11/Wayland).

  3. Likely due to timing. I guess mostly because split-mode is really meant to drive one display as far as I understand.

Hello Stefan,

thanks for your Answer. I have read the guides a little bit and found them also very confusing too. I think also I need the separate mode for my application. I have successfully created a device-tree without split-mode and dual-mode. I think this is maybe the separate mode, because on one Display Linux starts and the other Display is Black (I think this is ok, because it has no input source).

To your Answers:

  1. This is a little bit strange for me. How can I add a framebuffer to ONE lvds channel. In the imx6qdl-apalis.dtsi I set:

    aliases {
    	mxcfb0 = &mxcfb1;
    	mxcfb1 = &mxcfb2;
    	mxcfb2 = &mxcfb3;
    	mxcfb3 = &mxcfb4;
    };
    
    mxcfb1: fb@0 {
    	compatible = "fsl,mxc_sdc_fb";
    	disp_dev = "ldb";
    	interface_pix_fmt = "RGB24";
    	default_bpp = <32>;
    	int_clk = <0>;
    	late_init = <0>;
    	status = "okay";
    };
    
    mxcfb2: fb@1 {
    	compatible = "fsl,mxc_sdc_fb";
    	disp_dev = "lcd";
    	interface_pix_fmt = "RGB24";
    	mode_str ="CLAA-WVGA";
    	default_bpp = <32>;
    	int_clk = <0>;
    	late_init = <0>;
    	status = "okay";
    };
    

Should I change this to something like:

	mxcfb1: fb@0 {
		compatible = "fsl,mxc_sdc_fb";
		disp_dev = "ldb,lvds-channel@0";
		interface_pix_fmt = "RGB24";
		default_bpp = <32>;
		int_clk = <0>;
		late_init = <0>;
		status = "okay";
	};

	mxcfb2: fb@1 {
		compatible = "fsl,mxc_sdc_fb";
		disp_dev = "ldb,lvds-channel@1";
		default_bpp = <32>;
		int_clk = <0>;
		late_init = <0>;
		status = "okay";
	};

and if yes what should I set in the vidargs in u-boot? My vidargs are: setenv vidargs 'video=mxcfb0:dev=ldb video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off fbmem=512M'. Is it possible to set this just with the vidargs ?

  1. Thanks, I will try to create a Wayland Image and ask QT, what is best way to connect two applications.

  2. I think this is more a clock problem. Do you have any Idea how I can debug it?

Thank you very much and have a nice day.

With fbdev devices you can rather easily test which device belongs to which display by simply write random data to a framebuffer device:

dd if=/dev/urandom of=/dev/fb0

There is some valuable information also in our Display Output, Resolution and Timings (Linux) article, especially the mxcfbX to /dev/fbX assignment!

Since I do not have the setup I cannot test here, so my instructions are based on my understanding and my best guesses…

The 4 framebuffer devices mxcfb0-3 are connected to IPU 1 Display 1, IPU 1 Display 2, IPU 2 Display 1 and IPU 2 Display 2 (note that often a zero based ID is used). The LVDS peripheral LDB allows to route its channels to any of those four IPU displays. By default lvds-channel@0 is configured to use ipu2-di1 hence should be available on mxcfb3 and lvds-channel@1 to ipu1-di0 hence should be on mxcfb0.

With that I would assume that setenv vidargs 'video=mxcfb0:dev=ldb video=mxcfb1:off video=mxcfb2:off video=mxcfb3:dev=ldb fbmem=512M' should enable mxcfb0 and mxcfb3.

This works pretty good.Thank you so much.

The display with the mxcfb3 framebuffer has the wrong colour depth and I will check how to fix that, (Do you have any Idea why that could happen?) but now I can see two different applications on both screens with 62fps from the “Cinematic Experience Demo”.

I have also tried to switch to the mxcfb2, but this doesn’t seem to work. I think this is because of the overlapping frame buffers mxcfb0 and mxcfb2.

Last but not least: I get the following error: [ X.X] mmc2: Switching to 3.3V signalling voltage failed . Should I open a new thread for that?

I have change in the device tree in every mxcfb the interface_pix_fmt = "RGB24" and default_bpp = <32>; now the colour depth works great too.

A little bit strange is that: I set: setenv vidargs 'video=mxcfb0:dev=ldb video=mxcfb1:off video=mxcfb2:off video=mxcfb3:dev=ldb fbmem=512M' dmesg | grep fb shows: [ 0.000000] Kernel command line: vmalloc=400M user_debug=30 ip=off root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait fec_mac=00:14:2d:4d:e1:39 consoleblank=0 no_console_suspend=1 console=tty1 console=ttymxc0,115200n8 video=mxcfb0:dev=ldb video=mxcfb1:off video=mxcfb2:off video=mxcfb3:dev=ldb fbmem=512M [ 0.575284] mxc_sdc_fb fb@0: registered mxc display driver ldb [ 0.583538] mxc_sdc_fb fb@0: 1280x320 h_sync,r,l: 10,72,20 v_sync,l,u: 10,20,70 pixclock=36001000 Hz [ 0.658081] mxc_sdc_fb fb@0: 1280x320 h_sync,r,l: 10,72,20 v_sync,l,u: 10,20,70 pixclock=36001000 Hz [ 0.744544] mxc_sdc_fb fb@1: mxcfb1 is turned off! [ 0.746989] mxc_sdc_fb fb@2: mxcfb2 is turned off! [ 0.749348] mxc_sdc_fb fb@3: registered mxc display driver ldb [ 0.759921] mxc_sdc_fb fb@3: 1280x320 h_sync,r,l: 10,72,20 v_sync,l,u: 10,20,70 pixclock=36001000 Hz [ 147.583815] mxc_sdc_fb fb@3: 1280x320 h_sync,r,l: 10,72,20 v_sync,l,u: 10,20,70 pixclock=36001000 Hz

But I get only to run two apications on fullscreen in framebuffer 0 AND 2. This is realy strange. But it works great. If I start the Aplication in the framebuffer 3 it is extrem small. something like 480*480.

If you like I can make some pictures for you.

But all in all now everything works GREAT.

There is no 1:1 relationship between the mxcfbX devices you specify on the command line and the /dev/fbY device files.

The i.MX6D/Q has two IPU’s, each capable of driving two display interfaces DI0 and DI1. DI0 allows to use addionally an overlay framebuffer while DI1 does not. The IPU driver will create two /dev/fbX devices for DI0 while it will only create one for DI1.

I guess your device tree uses ‘crtc = “ipu2-di1”;’ for the first LDB channel and ‘crtc = “ipu1-di0”;’ for the second. Thus mxcfb0 will be mapped /dev/fb0 (DI1 → one device file) and mxcfb3 will be mapped to /dev/fb1 and /dev/fb2.

/dev/fb2 will by default only have a small resolution. The application using the overlay can then change its size and the position on /dev/fb1 which it wants to use.