The dual-display mode for the native LVDS does not work after switching from 5.5 to 6.6 Kernel

Hi,

we have a custom board with imx8mp SOM running native LVDS with fsl,dual-channel. After upgrading to 6.6 Kernel the dual-channel mode only uses a half of display slit vertically, with very small and blurred
text. It seems that only one lvds channel works. When we disable fsl,dual-channel, the display is back to normal. We have not changed any timing for the display in 6.6.

root@arm-aarch64-cortexa53:~# uname -a
Linux arm-aarch64-cortexa53 6.6.84-0 #1 SMP PREEMPT Wed Apr 30 17:53:10 UTC 2025 aarch64 GNU/Linux

We have following custom clock rate enabled:

--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -752,7 +752,7 @@ clk: clock-controller@30380000 {
 						       <800000000>,
 						       <393216000>,
 						       <361267200>,
-						       <1039500000>;
+						       <840000000>;
 			};
 
 			src: reset-controller@30390000 {
@@ -1502,7 +1502,7 @@ media_blk_ctrl: blk-ctrl@32ec0000 {
 							 <&clk IMX8MP_VIDEO_PLL1_OUT>,
 							 <&clk IMX8MP_VIDEO_PLL1_OUT>;
 				assigned-clock-rates = <500000000>, <200000000>,
-						       <0>, <0>, <1039500000>;
+						       <0>, <0>, <840000000>;
 				#power-domain-cells = <1>;
 			};
 
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index 6c17786ecb9f..74a4e3978b1e 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -60,10 +60,15 @@ static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
 };
 
 static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
-	PLL_1443X_RATE(1039500000U, 173, 2, 1, 16384),
-	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
-	PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
-	PLL_1443X_RATE(519750000U, 173, 2, 2, 16384),
+	PLL_1443X_RATE(1039500000U, 173, 2, 1, 16384),
+	PLL_1443X_RATE(840000000U, 140, 2, 1, 0),		// VCO=1680, PLL=840 (for LVDS)
+	PLL_1443X_RATE(650000000U, 325, 3, 2, 0),		
+	PLL_1443X_RATE(594000000U, 198, 2, 2, 0),		
+	PLL_1443X_RATE(519750000U, 173, 2, 2, 16384),	
 	PLL_1443X_RATE(393216000U, 262, 2, 3, 9437),

Our panel dts entry:

	panel_lvds: panel-lvds {

		compatible = "panel-lvds";
		backlight = <&backlight_lvds>;
		data-mapping = "vesa-24";
		width-mm = <199>;
		height-mm = <112>;
		status = "okay";

		panel-timing {
			clock-frequency = <60000000>;

			hactive = <1280>;
			hback-porch = <29>;
			hfront-porch = <35>;
			hsync-len = <7>;

			vactive = <720>;
			vback-porch = <9>;
			vfront-porch = <9>;
			vsync-len = <1>;
		};

		port {
			panel_in_lvds0: endpoint {
				remote-endpoint = <&ldb_lvds_ch0>;
			};
		};
	};
};

&ldb {
	status = "okay";
	/* dual channel does not work for now */
	/* fsl,dual-channel; */

	lvds-channel@0 {
		fsl,data-mapping = "spwg";
		fsl,data-width = <0x18>;
		status = "okay";
		port@1 {
			reg = <1>;
			ldb_lvds_ch0: endpoint {
				remote-endpoint = <&panel_in_lvds0>;
			};
		};
	};
};

Comparing the clk_summary, we found one discrepancy for dual-channel mode media_ldb 420000000 in 5.5 vs 210000000 in 6.6

5.5 Kernel

video_pll1_ref_sel                1        1        0    24000000          0     0  50000
   video_pll1                     1        1        0   840000000          0     0  50000
      video_pll1_bypass           1        1        0   840000000          0     0  50000
         video_pll1_out           2        2        0   840000000          0     0  50000
            media_ldb             1        1        0   420000000          0     0  50000
               media_ldb_root_clk       1        1        0   420000000          0     0  50000
            media_disp2_pix       1        1        0    60000000          0     0  50000

6.6 Kernel

video_pll1_ref_sel               1       1        0        24000000    0          0     50000      Y      deviceless                      no_connection_id         
   video_pll1                    1       1        0        840000000   0          0     50000      Y         deviceless                      no_connection_id         
      video_pll1_bypass          1       1        0        840000000   0          0     50000      Y            deviceless                      no_connection_id         
         video_pll1_out          2       2        0        840000000   0          0     50000      Y               deviceless                      no_connection_id         
            media_ldb            1       1        0        210000000   0          0     50000      Y                  deviceless                      no_connection_id         
               media_ldb_root_clk 1       1        0        210000000   0          0     50000      Y                     ldb-display-controller          ldb                      
                                                                                                                         deviceless                      no_connection_id   

When we disable the dual-channel mode in 6.6 the output of video clocks matches one from 5.5, and we have a full screen available:

video_pll1_ref_sel               1       1        0        24000000    0          0     50000      Y      deviceless                      no_connection_id         
   video_pll1                    1       1        0        840000000   0          0     50000      Y         deviceless                      no_connection_id         
      video_pll1_bypass          1       1        0        840000000   0          0     50000      Y            deviceless                      no_connection_id         
         video_pll1_out          2       2        0        840000000   0          0     50000      Y               deviceless                      no_connection_id         
            media_ldb            1       1        0        420000000   0          0     50000      Y                  deviceless                      no_connection_id         
               media_ldb_root_clk 1       1        0        420000000   0          0     50000      Y                     ldb-display-controller          ldb     

Except the differnce in media_ldb for dual-channel mode we could not find any difference, but dual-channel does not provide the same output as in 5.5. Can you help to understand why?

Hi, I’m the Toradex AI Assistant.

I might make mistakes or occasionally get you wrong. Our support team will step in if needed.


LVDS Dual-Channel Configuration Issue on i.MX 8M Plus

Based on your description, you’re experiencing an issue where dual-channel LVDS mode is not working correctly after upgrading from kernel 5.5 to 6.6. The key observation is that the media_ldb clock frequency is different between the two kernel versions when dual-channel is enabled.

Understanding the Clock Frequency Difference

The clock frequency difference you’ve observed is significant (1):

  • Kernel 5.5: media_ldb runs at 420000000 Hz (420 MHz)
  • Kernel 6.6: media_ldb runs at 210000000 Hz (210 MHz) in dual-channel mode

This suggests that in kernel 6.6, the dual-channel mode is dividing the clock by 2, which is expected behavior for dual-channel LVDS where each channel handles alternate pixels (1).

Device Tree Configuration Requirements

For proper dual-channel LVDS configuration on i.MX 8M Plus, the documentation shows specific requirements (1):

Color Mapping and Data Width Configuration

The ldb node and its lvds-channel child nodes must be configured correctly (1):

&ldb2 {
        status = "okay";
        fsl,dual-channel;

        lvds-channel@0 {
                fsl,data-mapping = "spwg";
                fsl,data-width = <18>;
                status = "okay";

                port@1 {
                        reg = <1>;

                        lvds1_out: endpoint {
                                remote-endpoint = <&panel_lvds1_in>;
                        };
                };
        };
};

(1)

Valid Data Mapping Combinations

According to the documentation, valid combinations are (1):

fsl,data-mapping fsl,data-width data-mapping (panel-lvds node)
spwg 18 jeida-18
spwg 24 vesa-24
jeida 24 jeida-24

Potential Issues in Your Configuration

  1. Data Width Specification: In your configuration, you’re using fsl,data-width = <0x18> (24 in decimal), but you should verify this matches your panel’s requirements and the data-mapping = "vesa-24" in your panel node (1).

  2. Clock Frequency Workaround: There’s a known issue with LVDS clock frequencies on Verdin iMX8M Plus that may be relevant (1). The documentation mentions that the current LVDS driver implementation only supports specific frequencies, and workarounds may be needed for different frequencies.

Recommended Troubleshooting Steps

  1. Verify Panel Timing Configuration: Ensure your panel timing matches the dual-channel requirements. For dual-channel displays, the full panel specifications need to be provided, and the clock and horizontal timings are divided by two when configuring the two channels (1).

  2. Check Data Mapping Consistency: Verify that the fsl,data-mapping and fsl,data-width in your lvds-channel node are compatible with the data-mapping specified in your panel node (1).

  3. Review Clock Configuration: The difference in media_ldb clock frequency suggests the kernel 6.6 implementation may have changed how dual-channel clocking works. You may need to adjust your custom clock rates accordingly.

Additional Considerations

The documentation indicates that LVDS configuration should primarily be done through device tree and overlays rather than command line parameters (1). Since you’re using a custom board, ensure all timing and mapping parameters are correctly specified in your device tree.

If the issue persists, you may need to investigate whether the kernel 6.6 LVDS driver implementation has changed the dual-channel handling compared to kernel 5.5, particularly regarding clock division and pixel distribution between channels.

Best regards, Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.

simply changing

panel-timing {
			clock-frequency = <60000000>;

to

panel-timing {
			clock-frequency = <120000000>;

does match fix ldb_media clock to 42Mhz, but the screen output is incorrect, split into 3 parts.

video_pll1_ref_sel               1       1        0        24000000    0          0     50000      Y      deviceless                      no_connection_id         
       video_pll1                    1       1        0        840000000   0          0     50000      Y         deviceless                      no_connection_id         
          video_pll1_bypass          1       1        0        840000000   0          0     50000      Y            deviceless                      no_connection_id         
             video_pll1_out          2       2        0        840000000   0          0     50000      Y               deviceless                      no_connection_id         
                media_ldb            1       1        0        420000000   0          0     50000      Y                  deviceless                      no_connection_id         
                   media_ldb_root_clk 1       1        0        420000000   0          0     50000      Y                     ldb-display-controller          ldb                      
                                                                                                                             deviceless                      no_connection_id         
                media_disp2_pix      1       1        0        120000000   0          0     50000      Y                  deviceless                      no_connection_id         
                   media_disp2_pix_root_clk 1       1        0        120000000   0          0     50000