LCD flickering on i.MX7D Colibri after kernel upgrade

We are observing LCD flickering on an i.MX7D Colibri module after migrating from an older kernel to Linux 6.x.y. The same hardware and display configuration worked correctly with the previous kernel version.

The issue appears only after the kernel upgrade and persists across reboots.

We would like to understand what kernel,LCDIF, clock, or device-tree changes in Linux 6.x could cause this behavior and what configurations should be verified or adjusted to resolve the flickering.

Hi, I’m the Toradex AI Assistant.

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


I’d be glad to help troubleshoot the LCD flickering issue on your i.MX7D Colibri module! To provide the most accurate guidance for your specific setup, could you let me know which OS and version you are running?

Additionally, please run the tdx-info command on your device to get detailed hardware and software information. You can find more details about this command at Getting Device Information with Tdx-Info | Toradex Developer Center

Common Kernel 6.x Display-Related Changes

Based on the available documentation, here are key areas that commonly affect display functionality when upgrading to newer kernels:

Device Tree Bridge Requirements

One significant change in newer kernels is the requirement for proper bridge declarations in device trees (1). The LCDIF driver now expects explicit bridge and display chain node definitions, which may not have been required in older kernels (1).

For kernel 6.x, you need to ensure:

  • Both the controller (&lcdif) and any bridge nodes are set to status = "okay" (1)
  • Proper ports and endpoints are defined to connect the controller to the display chain (1)

Device Tree Display Configuration

For i.MX7 platforms, the display configuration typically involves the &lcdif node (1). A proper configuration should include:

&lcdif {
    status = "okay";
    display = <&display0>;
    
    display0: lcd-display {
        bits-per-pixel = <24>;
        bus-width = <18>;
        
        display-timings {
            native-mode = <&timing_wvga>;
            
            timing_wvga: 800x480 {
                clock-frequency = <33260000>;
                hactive = <800>;
                vactive = <480>;
                hback-porch = <40>;
                hfront-porch = <88>;
                vback-porch = <33>;
                vfront-porch = <10>;
                hsync-len = <154>;
                vsync-len = <2>;
                de-active = <1>;
                hsync-active = <0>;
                vsync-active = <1>;
                pixelclk-active = <1>;
            };
        };
    };
};

(1)

Key Areas to Verify

  1. Display Timing Parameters: Ensure your clock frequency and timing parameters match your display specifications (1)
  2. Bridge Connections: Verify that any display bridges are properly declared and connected (1)
  3. Pin Configuration: Check that display pins are correctly configured in the device tree (2)

Device Tree Customization Process

If you need to modify your device tree configuration, you can follow the process outlined in the documentation (2):

  1. Identify the base device tree for your i.MX7D Colibri module (2)
  2. Create a custom device tree with the necessary modifications (2)
  3. Compile the device tree using the appropriate make commands (2)
  4. Deploy the updated device tree to your system (2)

Once you provide your specific OS version and hardware details, I can offer more targeted guidance for your exact configuration.

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.

Provided Which OS and Version below.

cat /etc/os-release
PRETTY_NAME=“Ubuntu 22.04.5 LTS”
NAME=“Ubuntu”
VERSION_ID=“22.04”
VERSION=“22.04.5 LTS (Jammy Jellyfish)”
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL=“https://www.ubuntu.com/

UBUNTU_CODENAME=jammy
medha@C2662:~/Desktop/YOCTO-NXP/oe-core/build$ uname -a
Linux C2662 6.8.0-90-generic #91~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 20 15:20:45 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
medha@C2662:~/Desktop/YOCTO-NXP/oe-core/build$ uname -r
6.8.0-90-generic
medha@C2662:~/Desktop/YOCTO-NXP/oe-core/build$

root@colibri-imx7-emmc-mcp:~# uname -a
Linux colibri-imx7-emmc-mcp 6.1.154-6.8.4-de

Thank you for providing the system information! I can see you’re running a Colibri iMX7 with Linux kernel 6.1.154 on what appears to be a Yocto-based system.

Understanding the LCD Flickering Issue

Based on the kernel version transition you’ve described, there are several key areas that commonly cause display issues when upgrading to Linux 6.x kernels, particularly related to device tree configuration changes.

Device Tree Bridge Requirements in Newer Kernels

One of the most significant changes in newer kernels is the stricter requirement for proper bridge declarations in device trees(1). The LCDIF driver now expects explicit bridge and display chain node definitions, which may not have been required in older kernels(1).

For kernel 6.x, you need to ensure:

  • Both the controller (&lcdif) and any bridge nodes are set to status = "okay"(1)
  • Proper ports and endpoints are defined to connect the controller to the display chain(1)

Device Tree Configuration for i.MX7

The display configuration for i.MX7 platforms typically involves the &lcdif node(1). Here’s an example of a proper configuration:

&lcdif {
    status = "okay";
    display = <&display0>;
    
    display0: lcd-display {
        bits-per-pixel = <24>;
        bus-width = <18>;
        
        display-timings {
            native-mode = <&timing_1024_600>;
            
            timing_1024_600: 1024x600 {
                clock-frequency = <51450000>;
                hactive = <1024>;
                vactive = <600>;
                hback-porch = <156>;
                hfront-porch = <156>;
                vback-porch = <16>;
                vfront-porch = <16>;
                hsync-len = <8>;
                vsync-len = <6>;
                de-active = <1>;
                hsync-active = <0>;
                vsync-active = <0>;
                pixelclk-active = <0>;
            };
        };
    };
};

(1)

Troubleshooting Steps for Your Setup

  1. Verify Display Timing Parameters: Ensure your clock frequency and timing parameters exactly match your display specifications(1)

  2. Check Bridge Configuration: If you’re using any display bridges (like RGB-to-LVDS converters), verify they are properly declared in the device tree(1)

  3. Pin Configuration: Ensure display pins are correctly configured in the device tree(2)

Device Tree Customization Process

Since you’re using a Yocto-based system, you can modify your device tree by following these steps(2):

  1. Choose the Base Device Tree: Locate the device tree source (DTS) file for your Colibri iMX7 platform in the kernel source(2)

  2. Create Custom Device Tree: Copy the base device tree and create your custom version(2):

    $ cp ./arch/arm/boot/dts/nxp/imx7d-colibri-eval-v3.dts ./arch/arm/boot/dts/nxp/imx7d-colibri-eval-v3-custom.dts
    

    (2)

  3. Compile the Device Tree: Use the make command to compile your custom device tree(2):

    $ make DTC_FLAGS="-@" <device-tree>.dtb
    

    (2)

Key Areas to Focus On

Given your kernel upgrade scenario, pay particular attention to:

  • Display timing parameters: Clock frequencies and sync parameters may need adjustment(1)
  • Bridge connections: Ensure any display bridges are properly connected in the device tree(1)
  • Panel configuration: Verify that your panel node is correctly configured with the right compatible string(1)

The flickering you’re experiencing is likely due to one of these device tree configuration changes that became stricter in the newer kernel version.

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.

@ToradexAI
Provided my nodes for your reference.

panel: panel {

compatible = “panel-dpi”;
power-supply = <&reg_3v3>;
backlight = <&backlight>;

    /* Timings for Winstar 1024x600 */
    panel-timing {
        clock-frequency = <51200000>;
        hactive = <1024>;
        vactive = <600>;
        hfront-porch = <160>;
        hback-porch = <160>;
        hsync-len = <20>;
        vfront-porch = <12>;
        vback-porch = <23>;
        vsync-len = <3>;
        de-active = <1>;
	hsync-active = <0>;
	vsync-active = <0>;
	pixelclk-active = <1>;
    };

    port {
        panel_in: endpoint {
            remote-endpoint = <&display_out>;
        };
    };
};

&lcdif {
status = “okay”;
pinctrl-names = “default”;
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl
&pinctrl_lcdif_dat_24>;
/* Force LCD to use VIDEO PLL */
assigned-clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_SRC>,
<&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_VIDEO_POST_DIV>;
assigned-clock-rates = <0>, <51200000>;
lcd-supply = <&reg_3v3>;
port {
display_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};

Thank you for providing your device tree configuration! Your setup looks well-structured with proper bridge connections between the LCDIF controller and panel. Let me analyze the configuration and suggest potential solutions for the LCD flickering issue.

Analysis of Your Configuration

Your device tree configuration follows the modern Linux kernel requirements with proper port/endpoint connections between the LCDIF controller and panel. This is good practice for kernel 6.x compatibility.

Potential Issues and Solutions

1. Clock Configuration Verification

Your current clock assignment looks correct, but there might be precision issues with the video PLL configuration. Based on similar display timing issues documented in the community, clock precision can significantly impact display stability(1).

The key area to verify is whether your assigned clock rate of 51200000 Hz is achievable with the video PLL configuration(1). In some cases, the actual pixel clock may differ slightly from the requested frequency, causing display artifacts(1).

2. Display Timing Parameter Adjustments

Your current panel timing configuration shows:

clock-frequency = <51200000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hback-porch = <160>;
hsync-len = <20>;
vfront-porch = <12>;
vback-porch = <23>;
vsync-len = <3>;

For troubleshooting flickering issues, try adjusting the porch values slightly. Based on community experience with similar display issues, small adjustments to front/back porch values can resolve timing-related flickering(1).

3. Pin Configuration Verification

Ensure your pinctrl configuration (pinctrl_lcdif_dat_24) properly configures all 24-bit RGB data lines. According to the Colibri iMX7 datasheet, the parallel RGB LCD interface supports up to 24-bit color(2).

The standard parallel RGB LCD interface pins are defined in the datasheet(2), and proper pin configuration is critical for stable display operation.

4. Kernel-Specific Considerations

For Linux 6.x kernels, there have been changes in how display drivers handle pixel clock generation and timing validation(1). The issue you’re experiencing might be related to stricter timing validation in newer kernel versions.

Recommended Troubleshooting Steps

  1. Verify Actual Pixel Clock: Check if the actual pixel clock matches your requested 51.2 MHz using kernel debugging or measurement tools.

  2. Test with Conservative Timings: Try reducing the clock frequency slightly (e.g., to 50 MHz) to see if this resolves the flickering.

  3. Adjust Porch Values: Experiment with slightly different front/back porch values while maintaining the same total horizontal/vertical periods.

  4. Monitor Kernel Messages: Check dmesg for any LCDIF or display-related warnings that might indicate timing or configuration issues.

  5. Validate Pin Configuration: Ensure all RGB data pins, sync signals, and clock pins are properly configured in your pinctrl settings.

The configuration structure you’ve provided follows the correct modern kernel approach with proper port/endpoint connections, which suggests the issue is likely related to timing parameters or clock precision rather than structural device tree problems.

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.

After verifying ,I observed that actual pixel clock doesn’t matches our requested 51.2 MHz.
Tell me the solution @ToradexAI .

Great! Now that you’ve confirmed the pixel clock mismatch, let’s address this issue. Based on the available documentation, there are several approaches to resolve pixel clock precision problems in Linux 6.x kernels.

Clock Configuration Solutions

1. Dynamic Clock Rate Configuration

Based on community experience with similar pixel clock issues, newer kernels support dynamic PLL configuration that can provide more precise clock frequencies(1). The key is to enable the pixel clock to reconfigure its parent PLL to achieve the exact frequency needed(1).

For your i.MX7D setup, you can try modifying your device tree to allow dynamic clock rate adjustment:

&lcdif {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_lcdif_dat
                 &pinctrl_lcdif_ctrl
                 &pinctrl_lcdif_dat_24>;
    
    /* Allow dynamic PLL reconfiguration */
    assigned-clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_SRC>,
                      <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
    assigned-clock-parents = <&clks IMX7D_PLL_VIDEO_POST_DIV>;
    assigned-clock-rates = <0>, <51200000>;
    
    lcd-supply = <&reg_3v3>;
    
    port {
        display_out: endpoint {
            remote-endpoint = <&panel_in>;
        };
    };
};

(1)

2. Alternative Clock Frequencies

If the exact 51.2 MHz cannot be achieved, try frequencies that the video PLL can generate more accurately. Common frequencies that work well with i.MX7D video PLL include:

  • 50.0 MHz - Often achievable with better precision
  • 49.5 MHz - Alternative that may provide stable timing
  • 52.0 MHz - Slightly higher frequency option

Update your panel timing accordingly:

panel-timing {
    clock-frequency = <50000000>;  /* Try 50 MHz instead */
    hactive = <1024>;
    vactive = <600>;
    /* Adjust porch values proportionally if needed */
    hfront-porch = <160>;
    hback-porch = <160>;
    hsync-len = <20>;
    vfront-porch = <12>;
    vback-porch = <23>;
    vsync-len = <3>;
    de-active = <1>;
    hsync-active = <0>;
    vsync-active = <0>;
    pixelclk-active = <1>;
};

3. Video PLL Configuration Verification

The video PLL on i.MX7D has specific multiplication factors that determine which frequencies can be generated precisely(1). The issue often occurs when the requested frequency doesn’t align well with the PLL’s available output frequencies(1).

4. Kernel Clock Framework Debugging

To verify the actual clock being generated, you can check the kernel clock framework output:

# Check actual clock rates
cat /sys/kernel/debug/clk/clk_summary | grep -i lcdif

This will show you the actual frequencies being generated versus what you requested.

5. Device Tree Compilation and Deployment

After making changes to your device tree, ensure proper compilation(2):

# Compile your custom device tree
make DTC_FLAGS="-@" imx7d-colibri-eval-v3-custom.dtb

(2)

6. Alternative Approach: Clock Source Selection

If the video PLL cannot provide the exact frequency needed, consider using an alternative clock source that might offer better precision for your specific frequency requirement.

Recommended Testing Sequence

  1. Start with 50 MHz: This frequency is often more achievable with the video PLL
  2. Verify actual vs. requested frequency: Use the clock debugging tools
  3. Gradually adjust: If 50 MHz works, try frequencies closer to your target
  4. Monitor display stability: Test each configuration thoroughly

The pixel clock precision issue you’re experiencing is a known challenge when upgrading to newer kernels, as they have stricter timing validation(1). The solution typically involves finding a frequency that the video PLL can generate accurately rather than forcing an imprecise frequency.

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.

Hi @RAKESH_BOINI ,
Please share the output of tdx-info.
Are you simply copying the device tree node used in your older BSP and then testing in newer BSP?
What was the older BSP you were using?

Hello Rakesh,

Is this issue also solved or need help?

Sahil Malian
Toradex