Panel Timings for Subpanel

I have a bit of a unique situation that I have been unable to find support for on my searches.

I have a custom LCD panel that is a 480x480 sub-section of an 800x600 panel. I can use the panel timings for the 800x600 panel and get video that is cutoff, but I’m trying to figure out if I can edit the panel timings to get the image drawn on the 480x480 subsection instead.

Is this possible? I’ve included a drawing of what im trying to do as well as the timing chart from the panel datasheet.

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 with your custom LCD panel configuration! To provide you with the most accurate guidance for your specific setup, could you let me know which hardware platform and OS version you’re using?

Please run the tdx-info command on your device and share the output. You can find more information about this command at tdx-info documentation.

This will help me understand:

  • Which SoM you’re using (Verdin i.MX8M Plus, Colibri iMX8X, Apalis iMX6, etc.)
  • Your carrier board configuration
  • The OS version (Torizon OS, Yocto BSP, etc.)

The approach for configuring custom panel timings varies significantly between different Toradex platforms, so knowing your exact setup is essential for providing the correct device tree overlay modifications and timing parameter adjustments.

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

Software summary

Bootloader: U-Boot
Kernel version: 6.6.101-7.4.0-g557af2783d91 #1-Torizon SMP PREEMPT Thu Sep 25 07:49:28 UTC 2025
Kernel command line: root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo v t.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ost ree=/ostree/boot.1/torizon/674bfb0dce701df54151ed29f44524f9bcf45f58f0f77b995d383 54558a0c3a5/0
Distro name: NAME=“Torizon OS”
Distro version: VERSION_ID=7.4.0-build.28
Distro variant: VARIANT=“Docker”
Hostname: verdin-imx8mp-08626606

Hardware info

HW model: Toradex Verdin iMX8M Plus WB on Mallow Board
Toradex version: 0070 V1.1A
Serial number: 08626606
Processor arch: aarch64

Thank you for providing the system information! With your Verdin iMX8M Plus on Torizon OS 7.4.0, I can help you configure your custom 480x480 LCD panel subsection.

Display Configuration for Verdin iMX8M Plus

Your Verdin iMX8M Plus supports multiple display interfaces (1). The i.MX 8M Plus SoC features three display controllers (LCDIF) that can drive MIPI DSI, LVDS, and HDMI outputs (1).

Approach for Custom Panel Timing

Yes, it’s possible to configure your 480x480 subsection by modifying the panel timings in a device tree overlay. Here’s the approach:

1. Create a Custom Device Tree Overlay

You’ll need to create a device tree overlay that defines your custom panel timing (2). Device tree overlays allow you to modify device configurations without rebuilding the entire device tree (2).

2. Panel Timing Configuration

For LVDS displays, you can specify detailed timings using the panel-lvds driver (1):

panel_lvds: panel-lvds {  
    compatible = "panel-lvds";  
    backlight = <&backlight>;  

    data-mapping = "jeida-18";  
    width-mm = <345>;  
    height-mm = <194>;  

    panel-timing {  
        clock-frequency = <138500000>;  
        hactive = <1920>;  
        vactive = <1080>;  
        hfront-porch = <48>;  
        hsync-len = <32>;  
        hback-porch = <80>;  
        vfront-porch = <3>;  
        vsync-len = <5>;  
        vback-porch = <23>;  
        hsync-active = <0>;  
        vsync-active = <0>;  
        pixelclk-active = <0>;  
    };  

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

(1)

3. Key Parameters for Your 480x480 Subsection

Based on your diagram, you’ll need to modify these timing parameters:

  • hactive: Set to 480 (your desired horizontal active pixels)
  • vactive: Set to 480 (your desired vertical active pixels)
  • hfront-porch/hback-porch: Adjust to position your 480px window horizontally within the 800px total
  • vfront-porch/vback-porch: Adjust to position your 480px window vertically within the 600px total

4. Overlay Deployment

To deploy your custom overlay (2):

  1. Compile your device tree overlay source (.dtso) to binary format (.dtbo)
  2. Copy the overlay to /boot/overlays/ on your device
  3. Enable it by editing /boot/overlays.txt

5. Display Interface Selection

For your Verdin iMX8M Plus, you can use (1):

  • Native HDMI: Direct HDMI output
  • Native LVDS: Direct LVDS connection
  • DSI-HDMI: MIPI DSI to HDMI adapter
  • DSI-LVDS: MIPI DSI to LVDS adapter

Choose the interface that matches your panel connection method.

The key to your subsection approach is calculating the correct porch values to center or position your 480x480 active area within the full 800x600 timing structure that your panel expects.

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
I’ve tried the following panel timing adjustments and captured the rendering output:

1. Default panel timing:
panel-timing {
clock-frequency = <30000000 40000000 50000000>;
de-active = <1>;
hactive = <800>;
hback-porch = <88>;
hfront-porch = <40>;
hsync-active = <0>;
hsync-len = <128>;
pixelclk-active = <1>;
vactive = <600 600 600>;
vback-porch = <23>;
vfront-porch = <1>;
vsync-active = <0>;
vsync-len = <4>;
};

2. Move 50 from hactive to hback-porch
panel-timing {
clock-frequency = <30000000 40000000 50000000>;
de-active = <1>;
hactive = <750>;
hback-porch = <138>;
hfront-porch = <40>;
hsync-active = <0>;
hsync-len = <128>;
pixelclk-active = <1>;
vactive = <600 600 600>;
vback-porch = <23>;
vfront-porch = <1>;
vsync-active = <0>;
vsync-len = <4>;
};

3. Move 50 from hactive to hfront-porch
panel-timing {
clock-frequency = <30000000 40000000 50000000>;
de-active = <1>;
hactive = <750>;
hback-porch = <88>;
hfront-porch = <90>;
hsync-active = <0>;
hsync-len = <128>;
pixelclk-active = <1>;
vactive = <600 600 600>;
vback-porch = <23>;
vfront-porch = <1>;
vsync-active = <0>;
vsync-len = <4>;
};

This test appears to show that adjusting the front/back porch doesn’t shift the image, but reducing the hactive does “shrink” the viewable area towards the left.

Analysis of Your Panel Timing Tests

Your test results confirm the expected behavior of display timing parameters. The key insight is that reducing hactive shrinks the viewable area from the right side, which aligns with how display controllers work (1).

Understanding Display Timing Parameters

For i.MX 8 series modules like your Verdin iMX8M Plus, display timing works as follows (1):

  • hactive/vactive: Define the actual pixel data transmission area
  • hfront-porch/hback-porch: Control timing but don’t shift the image position
  • hsync-len/vsync-len: Synchronization pulse widths

Achieving Your 480x480 Subsection

Based on your test results and the goal of displaying content in a 480x480 subsection of your 800x600 panel, here’s the approach:

Method 1: Reduce Active Area Only

panel-timing {
    clock-frequency = <30000000 40000000 50000000>;
    de-active = <1>;
    hactive = <480>;  /* Your target width */
    hback-porch = <88>;
    hfront-porch = <40>;
    hsync-active = <0>;
    hsync-len = <128>;
    pixelclk-active = <1>;
    vactive = <480>;  /* Your target height */
    vback-porch = <23>;
    vfront-porch = <1>;
    vsync-active = <0>;
    vsync-len = <4>;
};

This will give you a 480x480 active area positioned at the top-left of your physical panel.

Method 2: Adjust Porch Values for Positioning

If you need to center or reposition the 480x480 area within your panel, you’ll need to increase the porch values to account for the “unused” pixels:

panel-timing {
    clock-frequency = <30000000 40000000 50000000>;
    de-active = <1>;
    hactive = <480>;
    hback-porch = <248>;  /* 88 + (800-480)/2 = 248 to center horizontally */
    hfront-porch = <200>; /* 40 + (800-480)/2 = 200 to center horizontally */
    hsync-active = <0>;
    hsync-len = <128>;
    pixelclk-active = <1>;
    vactive = <480>;
    vback-porch = <83>;   /* 23 + (600-480)/2 = 83 to center vertically */
    vfront-porch = <61>;  /* 1 + (600-480)/2 = 61 to center vertically */
    vsync-active = <0>;
    vsync-len = <4>;
};

Important Considerations

  1. Total Timing Must Match: The sum of hactive + hback-porch + hfront-porch + hsync-len should remain close to your panel’s expected horizontal total timing (1).

  2. Clock Frequency: You may need to adjust the clock frequency proportionally when changing the active area size.

  3. Panel Compatibility: Some panels may not respond well to significantly altered timing parameters.

Alternative Approach: Software Scaling

If the hardware timing approach doesn’t work optimally, consider using software scaling where you:

  • Keep the full 800x600 panel timing
  • Configure your graphics stack to render content in a 480x480 area
  • Use framebuffer or compositor settings to position the content

This approach maintains the panel’s native timing while achieving your display layout goals through software.

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

Here is the base panel timing for the 800x600 panel that works:

panel-lvds-native {
		compatible = "panel-lvds";
		backlight = <&backlight_lvds_native>;
		data-mapping = "vesa-24";
		height-mm = <136>;
		width-mm = <217>;

		panel-timing {
            clock-frequency = <30000000 40000000 50000000>;
            de-active = <1>;
            hactive = <800>;
            hback-porch = <88>;
            hfront-porch = <40>;
            hsync-active = <0>;
            hsync-len = <128>;
            pixelclk-active = <0>;
            vactive = <600>;
            vback-porch = <23>;
            vfront-porch = <1>;
            vsync-active = <0>;
            vsync-len = <4>;
        };

		port {
			panel_lvds_native_in: endpoint {
				remote-endpoint = <&lvds_out>;
			};
		};
	};

I’ve modified it by removing 320 from hactive and adding it to either hfront-porch or hback-porch. Both result in the same image. Moving pixels to the porches does not seem to shift the image at all.
Here’s the 2 modified panel timings I’ve tried that both result in the exact same rendering on the panel:

Timing 1

panel-lvds-native {
		compatible = "panel-lvds";
		backlight = <&backlight_lvds_native>;
		data-mapping = "vesa-24";
		height-mm = <136>;
		width-mm = <217>;

		panel-timing {
            clock-frequency = <30000000 40000000 50000000>;
            de-active = <1>;
            hactive = <480>;
            hback-porch = <88>;
            hfront-porch = <360>;
            hsync-active = <0>;
            hsync-len = <128>;
            pixelclk-active = <0>;
            vactive = <480>;
            vback-porch = <23>;
            vfront-porch = <121>;
            vsync-active = <0>;
            vsync-len = <4>;
        };

		port {
			panel_lvds_native_in: endpoint {
				remote-endpoint = <&lvds_out>;
			};
		};
	};

Timing 2

panel-lvds-native {
		compatible = "panel-lvds";
		backlight = <&backlight_lvds_native>;
		data-mapping = "vesa-24";
		height-mm = <136>;
		width-mm = <217>;

		panel-timing {
            clock-frequency = <30000000 40000000 50000000>;
            de-active = <1>;
            hactive = <480>;
            hback-porch = <408>;
            hfront-porch = <40>;
            hsync-active = <0>;
            hsync-len = <128>;
            pixelclk-active = <0>;
            vactive = <480>;
            vback-porch = <23>;
            vfront-porch = <121>;
            vsync-active = <0>;
            vsync-len = <4>;
        };

		port {
			panel_lvds_native_in: endpoint {
				remote-endpoint = <&lvds_out>;
			};
		};
	};

Understanding LVDS Display Behavior on Verdin iMX8M Plus

Your observations are correct and align with how LVDS displays work on the Verdin iMX8M Plus (1). The behavior you’re seeing is expected for LVDS panel configurations.

Why Porch Adjustments Don’t Shift the Image

For LVDS displays on i.MX 8 series modules, the hfront-porch and hback-porch parameters control timing relationships but don’t physically shift the active display area (1). The LVDS controller sends pixel data sequentially, and the active area (hactive and vactive) defines where actual pixel data is transmitted.

Current Timing Analysis

Both your modified timings are identical and maintain the correct total horizontal timing:

  • Total horizontal: 480 + 88 + 360 + 128 = 1056 pixels
  • Total vertical: 480 + 23 + 121 + 4 = 628 pixels

This preserves the panel’s expected timing structure while reducing the active area to 480x480 (1).

Positioning the 480x480 Area

Unfortunately, with LVDS panels, you cannot easily shift the active display area to a different physical location on the panel using device tree timing parameters alone (1). The LVDS interface transmits pixel data in a fixed sequence, and the active area will always start from the same physical position on the panel.

Alternative Approaches

1. Software-Based Positioning

Instead of modifying hardware timings, consider using software approaches:

  • Configure your application to render content in the desired 480x480 area
  • Use framebuffer positioning or compositor settings
  • Implement viewport scaling at the application level

2. Full Panel Utilization

Keep the original 800x600 timing and use software to:

  • Render your content in the specific 480x480 region you need
  • Fill the remaining area with a background color or pattern
  • Use graphics libraries that support viewport positioning

Recommended Configuration

For your use case, I recommend using your current 480x480 timing configuration, which gives you a clean 480x480 active area positioned at the top-left of your panel (1):

hactive = <480>;
vactive = <480>;

This approach maintains proper LVDS timing while providing the reduced active area you need. The positioning within your physical panel layout should be handled through software rather than hardware timing modifications.

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

So leave my panel timing as below, which moves the extra horizontal/vertical pixels to their respective front porches?

I’m bundling my image with the torizon/weston-imx8:4 wayland compositor. Is there anyway I can pre-package this “framebuffer position” with my OS?

panel-lvds-native {
		compatible = "panel-lvds";
		backlight = <&backlight_lvds_native>;
		data-mapping = "vesa-24";
		height-mm = <136>;
		width-mm = <217>;

		panel-timing {
            clock-frequency = <30000000 40000000 50000000>;
            de-active = <1>;
            hactive = <480>;
            hback-porch = <88>;
            hfront-porch = <360>;
            hsync-active = <0>;
            hsync-len = <128>;
            pixelclk-active = <0>;
            vactive = <480>;
            vback-porch = <23>;
            vfront-porch = <121>;
            vsync-active = <0>;
            vsync-len = <4>;
        };

		port {
			panel_lvds_native_in: endpoint {
				remote-endpoint = <&lvds_out>;
			};
		};
	};

Panel Timing Configuration

Yes, your panel timing configuration looks correct for creating a 480x480 active area. The timing preserves the total horizontal and vertical periods while reducing the active display area.

Weston Configuration for Display Positioning

Since you’re using torizon/weston-imx8:4, you can configure Weston to handle display positioning through its configuration file (1). Weston supports various customization options that can be pre-packaged with your OS (2).

Weston Configuration Options

You can customize Weston behavior by modifying the weston.ini configuration file (2). For display configuration, you can set fixed display resolution and positioning (2):

[output]
name=HDMI-A-1
transform=rotate-90

(2)

Pre-packaging Configuration

To pre-package your Weston configuration with your OS, you can:

  1. Create a custom Weston container that includes your specific weston.ini configuration
  2. Use TorizonCore Builder to customize the base OS image with your display settings
  3. Mount configuration files when running the Weston container

Running Weston with Custom Configuration

For your Verdin iMX8M Plus, you would run the Weston container like this (1):

# docker container run -d --name=weston --net=host \
    --cap-add CAP_SYS_TTY_CONFIG \
   -v /dev:/dev -v /tmp:/tmp -v /run/udev/:/run/udev/ \
    --device-cgroup-rule="c 4:* rmw" --device-cgroup-rule="c 253:* rmw" \
    --device-cgroup-rule="c 13:* rmw" --device-cgroup-rule="c 226:* rmw" \
    --device-cgroup-rule="c 10:223 rmw" --device-cgroup-rule="c 199:0 rmw" \
    torizon/weston-imx8:4 \
    --developer

(1)

Alternative: Fixed Display Resolution

Weston supports setting the resolution in the configuration file (2). You can check the Weston configuration files weston.ini and weston-dev.ini which include comments illustrating how to configure fixed display resolution (2).

Recommendation

Keep your panel timing as configured - it correctly creates a 480x480 active area. For positioning and framebuffer management, leverage Weston’s configuration capabilities rather than trying to achieve this through hardware timing modifications.

The combination of your custom panel timing and Weston configuration should give you the display behavior you’re looking for while maintaining proper LVDS timing compatibility.

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 @JosephG ,

Talking internally we believe you may have to reach out to the display manufacturer.
Editing the device tree would be something we mention but if that doesn’t work then it could be at a lower level.

What is your latest line of thinking here?

Best,