Verdin-imx95 LVDS on custom carrier board

Hi all,

we are currently evaluating verdin-imx95 for a new product line. How do we enable LVDS?
I used the Capacitive Touch Display 10.1” LVDS as a reference, but do not see any results on screen (backlight works though).

Our setup:

  • Verdin iMX95 H 8GB WB IT
  • custom made carrier board
    • with native LVDS (works with Verdin AM62P)
  • Torizon OS 7.4.0 build 28
  • torizon/weston-imx95:4.7.0

I derived the following device tree (used as overlay):

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
 * Copyright (C) 2025 Toradex
 *
 * Capacitive Touch Display 10.1" LVDS.
 *
 * https://developer.toradex.com/hardware/accessories/displays/capacitive-touch-display-101inch-lvds/
 * https://www.toradex.com/accessories/capacitive-touch-display-10.1-inch-lvds
 */

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/fsl,imx95-clock.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pwm/pwm.h>

/ {
	compatible = "toradex,verdin-imx95";
};

&{/} {
	backlight_lvds0: backlight {
		compatible = "pwm-backlight";
		brightness-levels = <0 45 63 88 119 158 203 255>;
		default-brightness-level = <4>;
		/* Verdin GPIO_10_DSI (SODIMM 21) */
		enable-gpios = <&som_gpio_expander 3 GPIO_ACTIVE_HIGH>;
		/* Verdin PWM_3_DSI (SODIMM 19) */
		pwms = <&tpm6 2 666667 0>;
	};

	panel_lvds0: panel-lvds {
		compatible = "panel-lvds";
		#address-cells = <1>;
		#size-cells = <0>;
		backlight = <&backlight_lvds0>;
		data-mapping = "vesa-24";
		height-mm = <86>;
		width-mm = <154>;

		status = "okay";

		panel-timing {
			clock-frequency = <54000000>;
			de-active = <1>;
			hactive = <1024>;
			hback-porch = <160>;
			hfront-porch = <160>;
			hsync-active = <0>;
			hsync-len = <70>;
			pixelclk-active = <1>; /* positive edge */
			vactive = <600>;
			vback-porch = <23>;
			vfront-porch = <12>;
			vsync-active = <0>;
			vsync-len = <5>;
		};

		port@0 {
			reg = <0>;

			panel_lvds0_in: endpoint {
				remote-endpoint = <&lvds0_out>;
			};
		};
	};
};


&display_pixel_link {
	status = "okay";
};

&displaymix_irqsteer {
	status = "okay";
};

&dpu {
	status = "okay";
};

&ldb {
	#address-cells = <1>;
	#size-cells = <0>;
	assigned-clocks = <&scmi_clk IMX95_CLK_LDBPLL_VCO>,
			  <&scmi_clk IMX95_CLK_LDBPLL>;
	//assigned-clocks = <&lvds_csr IMX95_CLK_DISPMIX_LVDS_CH0_GATE>;
	//		  <&lvds_csr IMX95_CLK_DISPMIX_LVDS_CH1_GATE>;
	/* 4*7*pixelclk and 7*pixelclk */
	assigned-clock-rates = <2982000000>, <497000000>;
	//assigned-clock-rates = <1134000000>;
	status = "okay";

	channel@0 {
		reg = <1>;
		#address-cells = <1>;
		#size-cells = <0>;
		status = "okay";

		fsl,data-mapping = "vesa";
		fsl,data-width = <24>;

		port@1 {
			reg = <1>;

			lvds0_out: endpoint {
				remote-endpoint = <&panel_lvds0_in>;
			};
		};
	};
};

&ldb0_phy {
	status = "okay";
};

&ldb1_phy {
	status = "okay";
};

/* Verdin I2C_1 */
&lpi2c4 {
	//#address-cells = <1>;
	//#size-cells = <0>;
	status = "okay";

	touch@41 {
		compatible = "ilitek,ili251x";
		reg = <0x41>;
		//pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>;
		/* Verdin GPIO_2 (SODIMM 208) */
		interrupt-parent = <&gpio2>;
		interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
		/* Verdin GPIO_1 (SODIMM 206) */
		reset-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;

		status = "okay";
	};
};

&pixel_interleaver {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	channel@0 {
		reg = <0>;
		status = "okay";
	};
};

/* Verdin PWM_3_DSI */
&tpm6 {
	status = "okay";
};

Kernel boot shows:

U-Boot SPL 2024.04-7.4.0+git.cf50ed467107 (Jan 01 1970 - 00:00:00 +0000)
SOC: 0xa1009500
LC: 0x40010
Trying to boot from MMC1
Primary set selected
Load image from MMC/SD 0xbe800
NOTICE:  BL31: v2.10.0  (release):lf-6.6.52-2.2.1-dirty
NOTICE:  BL31: Built : 00:00:00, Jan  1 1970


U-Boot 2024.04-7.4.0+git.cf50ed467107 (Jan 01 1970 - 00:00:00 +0000)

CPU:   i.MX95 rev1.1 at 1800MHz
CPU:   Automotive temperature grade (-40C to 125C) at 79C
LM Boot reason: sw, origin: 2, errid: 1
LM shutdown reason: sw, origin: 2, errid: 1
DRAM:  Delete node /pcie@4ca00000/ethernet@10,0
7.8 GiB
Core:  323 devices, 32 uclasses, devicetree: separate
MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Model: Toradex 0089 Verdin iMX95 Hexa 8GB WB IT V1.0A
Serial#: 12594093

BuildInfo:
  - SM firmware Build 509, Commit f73086cf, Oct 21 2025 21:07:16
  - ELE firmware version 2.0.2-4e395675

Setting variant to wifi
flash target is MMC:0
Net:   WARNING: no MAC address assigned for MAC0
imx_get_mac_from_fuse: fuse read err: 0
eth0: enetc-0 [PRIME]Could not get PHY for emdio-0: addr 7

Fastboot: Normal
Normal Boot
Hit any key to stop autoboot:  0
Setting bus to 1
Valid chip addresses:
starting USB...
Bus usb@4c100000: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.10
Bus usb@4c200000: Port not available.
scanning bus usb@4c100000 for devices... 1 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
** Bad device specification usb 0 **
Couldn't find partition usb 0:1
Can't set block device

Device 0: unknown device
switch to partitions #0, OK
mmc0(part 0) is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
969 bytes read in 2 ms (472.7 KiB/s)
## Executing script at 9c600000
Saving Environment to MMC... Writing to MMC(0)... OK
7046 bytes read in 4 ms (1.7 MiB/s)
97635 bytes read in 5 ms (18.6 MiB/s)
144 bytes read in 3 ms (46.9 KiB/s)
Working FDT set to 9c400000
Applying Overlay: verdin-imx95_spidev_overlay.dtbo
534 bytes read in 4 ms (129.9 KiB/s)
Applying Overlay: model_overlay.dtbo
182 bytes read in 4 ms (43.9 KiB/s)
Applying Overlay: display-MI0700BNT-4CP2-B_overlay.dtbo
4019 bytes read in 4 ms (980.5 KiB/s)
Applying Overlay: rtc_overlay.dtbo
455 bytes read in 4 ms (110.4 KiB/s)
Applying Overlay: pwm-beeper_overlay.dtbo
701 bytes read in 4 ms (170.9 KiB/s)
11547999 bytes read in 41 ms (268.6 MiB/s)
13007535 bytes read in 44 ms (281.9 MiB/s)
   Uncompressing Kernel Image to 0
## Flattened Device Tree blob at 9c400000
   Booting using the fdt blob at 0x9c400000
Working FDT set to 9c400000
   Loading Ramdisk to fc277000, end fcedeaaf ... OK
   Loading Device Tree to 00000000fc23c000, end 00000000fc276fff ... OK
Working FDT set to fc23c000
Delete node /soc/pcie@4c380000
Delete node /soc/pcie@4ca00000/ethernet@10,0
disabling SMMU

Starting kernel ...

[    0.600355] cpu cpu0: EM: invalid power: 0
[    0.681669] fsl_enetc_mdio 0002:01:00.0: Cannot get IERB init status: -517
[    0.681813] pcieport 0002:01:01.0: of_irq_parse_pci: failed with rc=-22
[    0.746278] pca953x 1-0021: failed writing register
[    0.908413] fsl_enetc4 0001:00:10.0: Failed to get PHY mode
[    1.042045] mdio_bus 0002:01:00.0: MDIO device at address 7 is missing.
[    1.058632] debugfs: Directory 'wakeup' with parent 'pm_genpd' already present!
[    1.065965] debugfs: Directory 'vpu' with parent 'pm_genpd' already present!
[    1.073032] debugfs: Directory 'npu' with parent 'pm_genpd' already present!
[    1.080126] debugfs: Directory 'noc' with parent 'pm_genpd' already present!
[    1.087195] debugfs: Directory 'm7' with parent 'pm_genpd' already present!
[    1.094194] debugfs: Directory 'gpu' with parent 'pm_genpd' already present!
Starting systemd-udevd version 255.21^
sysroot.readonly configuration value: 0 (fs writable: 1)
Using legacy ostree bind mount for /
[   10.496650] ili2511_i2c 1-0041: ili251x_read_reg_common failed: -5
[   11.460227] ina2xx 1-0040: error configuring the device: -5
[   11.474082] nau8822 1-001a: Failed to issue reset: -5
[   11.575412] imx95-ldb 4b0c0000.syscon:ldb@4: Failed to create device link (0x180) with 4b010000.syscon:bridge@8
[   11.648364] mali 4d900000.gpu: recalculation of power model mali-simple-power-model returned error -517
[   11.658046] mali 4d900000.gpu: IPA initialization failed
[   11.664462] mali 4d900000.gpu: Continuing without devfreq
[   11.859070] debugfs: File ':soc:display-controller@4b400000' in directory 'domains' already present!
[   11.868747] debugfs: File ':soc:display-controller@4b400000' in directory 'domains' already present!
[   12.059077] debugfs: File ':soc:display-controller@4b400000' in directory 'domains' already present!
[   12.068675] debugfs: File ':soc:display-controller@4b400000' in directory 'domains' already present!
[   12.167326] imx95-pixel-interleaver 4b0d0000.bridge: Failed to create device link (0x180) with 4b400000.display-controller
[   14.157831] net ethernet1: could not attach to PHY
[   19.489675] mali 4d900000.gpu: Protected memory allocator not found, Firmware protected mode entry will not be supported

Torizon OS 7.4.0+build.28 verdin-imx95-12594093 ttyLP2

The display stays white (backlight works) but does not show any image. Weston (docker logs) show:

Switching VT tty1 to text mode if currently in graphics mode
Switching to VT 7
SoC is: 'i.MX95'
SoC has GPU: true
SoC has DPU: true
Certificates for screen sharing not found in /var/volatile
Certificate request self-signature ok
subject=C = CH, ST = Luzern, L = Luzern, O = Toradex, CN = www.toradex.com
Certificate for screen sharing successfully generated
Removing previously created '.X*-lock' entries under /tmp before starting Weston. Pass 'IGNORE_X_LOCKS=1' environment variable to Weston container to disable this behavior.
dos2unix: converting file /etc/xdg/weston/weston.ini to Unix format...
dos2unix: converting file /etc/xdg/weston-dev/weston.ini to Unix format...
00:00:00.000 [INFO] [seatd/seat.c:39] Created VT-bound seat seat0
00:00:00.000 [INFO] [seatd/seatd.c:194] seatd started
Date: 2026-01-16 UTC
[15:01:32.954] weston 12.0.4
               https://wayland.freedesktop.org
               Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
               Build: 12.0.4
[15:01:32.955] Command line: weston -Bdrm-backend.so -Swayland-0
[15:01:32.955] OS: Linux, 6.6.101-7.4.0-g557af2783d91, #1-Torizon SMP PREEMPT Thu Sep 25 07:49:28 UTC 2025, aarch64
[15:01:32.955] Flight recorder: enabled
[15:01:32.956] Using config file '/etc/xdg/weston/weston.ini'
[15:01:32.960] Output repaint window is 7 ms maximum.
[15:01:32.962] Loading module '/usr/lib/aarch64-linux-gnu/libweston-12/drm-backend.so'
[15:01:33.172] initializing drm backend
[15:01:33.173] Trying libseat launcher...
00:00:00.279 [INFO] [seatd/server.c:145] New client connected (pid: 48, uid: 1000, gid: 1000)
00:00:00.279 [INFO] [seatd/seat.c:170] Added client 7 to seat0
00:00:00.280 [INFO] [seatd/seat.c:480] Opened client 7 on seat0
[15:01:33.174] [libseat/libseat.c:73] Seat opened with backend 'seatd'
[15:01:33.174] [libseat/backend/seatd.c:212] Enabling seat
[15:01:33.174] libseat: session control granted
[15:01:33.177] using /dev/dri/card0
[15:01:33.177] DRM: supports atomic modesetting
[15:01:33.177] DRM: supports GBM modifiers
[15:01:33.177] DRM: does not support async page flipping
[15:01:33.177] DRM: supports picture aspect ratio
[15:01:33.186] Loading module '/usr/lib/aarch64-linux-gnu/libweston-12/gl-renderer.so'
[15:01:33.242] Using rendering device: /dev/dri/renderD128
[15:01:33.242] EGL version: 1.5 Valhall-"r50p0-00eac0"
[15:01:33.242] EGL vendor: ARM
[15:01:33.242] EGL client APIs: OpenGL_ES
[15:01:33.242] EGL features:
               EGL Wayland extension: yes
               context priority: yes
               buffer age: no
               partial update: yes
               swap buffers with damage: no
               configless context: yes
               surfaceless context: yes
               dmabuf support: modifiers
[15:01:33.263] GL version: OpenGL ES 3.2 r50p0-00eac0.39604c3.f79ba06690d28605439a4bf5912cedf7
[15:01:33.263] GLSL version: OpenGL ES GLSL ES 3.20
[15:01:33.263] GL vendor: ARM
[15:01:33.263] GL renderer: Mali-G310
[15:01:33.471] GL ES 3.2 - renderer features:
               read-back format: ARGB8888
               glReadPixels supports y-flip: no
               wl_shm 10 bpc formats: yes
               wl_shm 16 bpc formats: yes
               wl_shm half-float formats: yes
               internal R and RG formats: yes
               OES_EGL_image_external: yes
[15:01:33.472] Using GL renderer
[15:01:33.495] event3  - pwm-beeper: not tagged as supported input device
[15:01:33.609] event3  - not using input device '/dev/input/event3'
[15:01:33.612] event0  - scmi_dev.11: is tagged by udev as: Keyboard
[15:01:33.612] event0  - scmi_dev.11: device is a keyboard
[15:01:33.615] event1  - gpio-keys: is tagged by udev as: Keyboard
[15:01:33.615] event1  - gpio-keys: device is a keyboard
[15:01:33.618] event2  - ILI210x Touchscreen: is tagged by udev as: Touchscreen
[15:01:33.619] event2  - ILI210x Touchscreen: device is a touch device
[15:01:33.619] event2  - ILI210x Touchscreen: applying calibration: 1.017099 0.014009 -0.013443 0.034105 1.049112 -0.040834
[15:01:33.661] libinput: configuring device "scmi_dev.11".
[15:01:33.661] libinput: configuring device "gpio-keys".
[15:01:33.661] Touchscreen - ILI210x Touchscreen - /sys/devices/platform/soc/42000000.bus/42540000.i2c/i2c-1/1-0041/input/input2/event2
[15:01:33.661] libinput: configuring device "ILI210x Touchscreen".
[15:01:33.662] DRM: head 'LVDS-1' found, connector 41 is connected, EDID make 'unknown', model 'unknown', serial 'unknown'
               Supported EOTF modes: SDR
[15:01:33.663] Registered plugin API 'weston_drm_output_api_v1' of size 40
[15:01:33.663] Registered plugin API 'weston_drm_virtual_output_api_v2' of size 48
[15:01:33.663] Color manager: no-op
[15:01:33.664] Loading module '/usr/lib/aarch64-linux-gnu/libgbm.so'
[15:01:33.664] Failed to load module: /usr/lib/aarch64-linux-gnu/libgbm.so: cannot open shared object file: No such file or directory
[15:01:33.665] Output 'LVDS-1' attempts EOTF mode: SDR
[15:01:33.665] Output 'LVDS-1' using color profile: built-in default sRGB SDR profile
[15:01:33.665] Chosen EGL config details: id:   1 rgba: 8 8 8 0 buf: 24 dep:  0 stcl: 0 int: 0-0 type: win|pbf|swap_preserved vis_id: XRGB8888 (0x34325258)
[15:01:33.666] Initialized backlight for head 'LVDS-1', device /sys/class/backlight/backlight
[15:01:33.666] Output LVDS-1 (crtc 39) video modes:
               1024x600@59.7, preferred, current, 54.0 MHz
[15:01:33.666] associating input device event0 with output LVDS-1 (none by udev)
[15:01:33.666] associating input device event1 with output LVDS-1 (none by udev)
[15:01:33.666] associating input device event2 with output LVDS-1 (none by udev)
[15:01:33.666] Output 'LVDS-1' enabled with head(s) LVDS-1
[15:01:33.666] Compositor capabilities:
               arbitrary surface rotation: yes
               screen capture uses y-flip: yes
               cursor planes: yes
               arbitrary resolutions: no
               view mask clipping: yes
               explicit sync: yes
               color operations: yes
               presentation clock: CLOCK_MONOTONIC, id 1
               presentation clock resolution: 0.000000001 s
[15:01:33.668] Loading module '/usr/lib/aarch64-linux-gnu/weston/desktop-shell.so'
[15:01:33.671] Loading module '/usr/lib/aarch64-linux-gnu/libweston-12/xwayland.so'
[15:01:33.787] Registered plugin API 'weston_xwayland_v1' of size 32
[15:01:33.788] Registered plugin API 'weston_xwayland_surface_v1' of size 16
[15:01:33.788] xserver listening on display :0
[15:01:33.789] Loading module '/usr/lib/aarch64-linux-gnu/weston/screen-share.so'
Date: 2026-01-16 UTC
[15:01:33.809] weston 12.0.4
               https://wayland.freedesktop.org
               Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
               Build: 12.0.4
[15:01:33.809] Command line: /usr/bin/weston --no-config --backend=rdp-backend.so --shell=fullscreen-shell.so --rdp-tls-key=/var/volatile/tls.key --rdp-tls-cert=/var/volatile/tls.crt --no-clients-resize --force-no-compression
[15:01:33.809] OS: Linux, 6.6.101-7.4.0-g557af2783d91, #1-Torizon SMP PREEMPT Thu Sep 25 07:49:28 UTC 2025, aarch64
[15:01:33.809] Flight recorder: enabled
[15:01:33.810] Starting with no config file.
[15:01:33.810] Output repaint window is 7 ms maximum.
[15:01:33.811] Loading module '/usr/lib/aarch64-linux-gnu/libweston-12/rdp-backend.so'
[15:01:33.972] Failed to load module: libOpenCL.so.1: cannot open shared object file: No such file or directory
[15:01:33.972] fatal: failed to create compositor backend
[15:01:33.974] Screen share failed: No wl_shm found
[15:01:33.975] launching '/usr/lib/aarch64-linux-gnu/weston-keyboard'
[15:01:33.978] launching '/usr/lib/aarch64-linux-gnu/weston-desktop-shell'
could not load cursor 'dnd-move'
could not load cursor 'dnd-move'
could not load cursor 'dnd-copy'
could not load cursor 'dnd-copy'
could not load cursor 'dnd-none'
could not load cursor 'dnd-none'

Weston is configured via docker-compose.yml:

services:
  weston:
    cap_add:
    - CAP_SYS_TTY_CONFIG
    container_name: weston
    device_cgroup_rules:
    - c 4:* rmw
    - c 10:* rmw
    - c 13:* rmw
    - c 199:0 rmw
    - c 226:* rmw
    - c 253:* rmw
    environment:
    - ACCEPT_FSL_EULA=1
    - ENABLE_RDP=1
    image: torizon/weston-imx95:4.7.0
    network_mode: host
    platform: linux/arm64
    restart: unless-stopped
    volumes:
    - /tmp:/tmp:rw
    - /dev:/dev:rw
    - /run/udev:/run/udev:rw
    - /etc/udev/rules.d:/etc/udev/rules.d:rw
    - /etc/xdg/weston/:/etc/xdg/weston/:rw

When connecting via RDP we can see the weston desktop, but on LVDS the screen stays white.

I am trying to figure out a way to properly debug this - maybe one of you has an idea what I missed in configuration to make it work out.

Best regards,

Bgo

Hi, I’m the Toradex AI Assistant.

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


Checking Applied Overlays

First, let’s verify if your overlay is being applied correctly. You can check if the overlays specified in overlays.txt were applied successfully by looking at /proc/device-tree/chosen/overlays(1). For each overlay that we try to apply, a device tree property is created and can be checked at this location as a file named <device_tree_overlay_name>.dtbo(1). This property will have a value, and if it is 0 it means that this overlay was applied successfully(1).

# ls /proc/device-tree/chosen/overlays/
# cat /proc/device-tree/chosen/overlays/display-MI0700BNT-4CP2-B_overlay.dtbo

(1)

Available LVDS Overlays for Verdin iMX95

According to the documentation, for Verdin iMX95 there are several pre-built LVDS overlays available(2):

Native Interface:

  • verdin-imx95_panel-cap-touch-10inch-lvds_overlay.dtbo - Starting from version 7.3.0(2)

Using DSI to LVDS adapter:

  • verdin-imx95_dsi-to-lvds_panel-cap-touch-10inch-lvds_overlay.dtbo - Starting from version 7.3.0(2)

Using Mezzanine add-on boards:

  • verdin-imx95_mezzanine_panel-cap-touch-10inch-lvds_overlay.dtbo - Starting from version 7.3.0(2)

Troubleshooting Your Custom Overlay

Based on your boot log, I can see that your custom overlay display-MI0700BNT-4CP2-B_overlay.dtbo is being applied. However, there are some potential issues to investigate:

1. Check Device Tree Compatibility

Your overlay uses compatible = "toradex,verdin-imx95"; which appears correct for the Verdin iMX95(2).

2. Verify Clock Configuration

I notice in your kernel log there’s a message about the LDB (LVDS Display Bridge):

[   11.575412] imx95-ldb 4b0c0000.syscon:ldb@4: Failed to create device link (0x180) with 4b010000.syscon:bridge@8

This suggests there might be an issue with the display pipeline configuration.

3. Test with Pre-built Overlay

Before using your custom overlay, I recommend testing with the pre-built Toradex overlay to ensure the hardware setup is correct(3):

# sudo sh -c "echo 'fdt_overlays=verdin-imx95_panel-cap-touch-10inch-lvds_overlay.dtbo' > /sysroot/boot/ostree/torizon-*/dtb/overlays.txt"
# sync
# sudo reboot

(3)

4. Development Approach

For production use, consider using TorizonCore Builder to properly integrate your custom overlay(4). The TorizonCore Builder Tool is the recommended method for customizing Torizon OS for development and production(4).

Quick Debugging Steps

  1. Check if overlay applied successfully:

    # ls /proc/device-tree/chosen/overlays/
    # cat /proc/device-tree/chosen/overlays/display-MI0700BNT-4CP2-B_overlay.dtbo
    

    (1)

  2. Verify display pipeline in kernel log:
    Look for any error messages related to DPU, LDB, or display controllers.

  3. Test with known working overlay:
    Try the pre-built verdin-imx95_panel-cap-touch-10inch-lvds_overlay.dtbo first(2).

Since Weston can detect the LVDS-1 output and shows it’s enabled with the correct resolution (1024x600@59.7), the issue might be in the display pipeline configuration or clock settings in your custom overlay.

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

Could you please provide the specifications of your LVDS display - such as the resolution and also whether it is a single or dual channel LVDS? If possible, please share the vendor and model number.

Hi @rudhi.tx ,

sure thing!

LCD Module Specification

Model: MACHMI0700BNT-14CP1-B
Vendor: Marelcom AG
LCD Type: FFS TFT / Transmissive / Normally black
Size: 7.0 Inch
LCM (W × H × D): 199.50 × 131.90 × 15.64 mm³
Active Area (W × H): 154.21 × 85.92 mm²
Pixel Pitch: 0.1506 × 0.1432 mm²
Number of Dots: 1024 (RGB) × 600
Interface Type: 4-lane LVDS
Color Depth: 16.7M
Input Voltage: 3.3 V

Input Timing Table (DE Mode)

Parameter Symbol Min. Typ. Max. Unit
DCLK Frequency fclk 40.8 51.2 67.2 MHz
Horizontal Display Area thd 1024 1024 1024 DCLK
HSD Period th 1114 1344 1600 DCLK DCLK
HSD Blanking Thb+thfp 90 320 376 DCLK
Vertical Display Area tvd 600 600 600 TH
VSD Period tvbp 610 635 800 TH
VSD Blanking Tvbp+tvfp 10 35 200 TH

As mentioned, I am struggling to get this running with a Verdin-iMX95.
Our custom carrier board with the display attached works perfectly fine when using a Verdin-AM62P with the following (customized) device-tree overlay:

// Marelcom MACHMI0700BNT-14CP1-B LVDS display (7 inch) with a resolution of 1024x600 pixels.
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pwm/pwm.h>
//#include "k3-pinctrl.h"

/dts-v1/;
/plugin/;

/ {
	compatible = "toradex,verdin-am62p";
};


&{/} {
	backlight_lvds_native: backlight {
		compatible = "pwm-backlight";
                brightness-levels = <1 34 55 83 116 156 202 255>;
		default-brightness-level = <7>;
		/* Verdin GPIO_10_DSI / DSI_1_BKL_EN / GPIO0_39 */
		enable-gpios = <&main_gpio0 39 GPIO_ACTIVE_HIGH>;
		//pinctrl-names = "default";
		//pinctrl-0 = <&pinctrl_epwm0_b>;
		pwms = <&epwm0 1 50000 0>;
		status = "okay";
	};


	panel-lvds-native {
		compatible = "panel-lvds";
		#address-cells = <1>;
		#size-cells = <0>;
		backlight = <&backlight_lvds_native>;

		status = "okay";

		data-mapping = "vesa-24";
		width-mm = <154>;
		height-mm = <86>;

		panel-timing {
			clock-frequency = <54000000>;
			de-active = <1>;
			hactive = <1024>;
			vactive = <600>;
			hback-porch = <160>;
			hfront-porch = <160>;
			vback-porch = <23>;
			vfront-porch = <12>;
			hsync-len = <70>;
			vsync-len = <5>;
			hsync-active = <0>;
			vsync-active = <0>;
			pixelclk-active = <1>; /* positive edge */
		};

		port@0 {
			reg = <0>;

			panel_lvds_in0: endpoint {
				remote-endpoint = <&oldi0_dss0_out>;
			};
		};

		/* HACK to make oldi1 happy */
		port@1 {
			reg = <1>;

			panel_lvds_in1: endpoint {
				remote-endpoint = <&oldi1_dss0_out>;
			};
		};
	};
};

&dss0 {
	status = "okay";
};

&dss0_ports {
	/* VP1: LVDS Output (OLDI TX 0) */
	port@0 {
		reg = <0>;
		#address-cells = <1>;
		#size-cells = <0>;

		dss0_dpi0_out0: endpoint@0 {
			reg = <0>;
			remote-endpoint = <&oldi0_dss0_in>;
		};

		dss0_dpi0_out1: endpoint@1 {
			reg = <1>;
			remote-endpoint = <&oldi1_dss0_in>;
		};
	};
};

/* Verdin PWM_3_DSI */
&epwm0 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_epwm0_b>;
	status = "okay";
};

/* Verdin PWM_1, PWM_2 */
&epwm2 {
	status = "okay";
};

/* Verdin I2C_1 */
&main_i2c0 {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	touchscreen@41 {
		compatible = "ilitek,ili251x";
		reg = <0x41>;
		interrupt-parent = <&mcu_gpio0>; 
		interrupts = <2 IRQ_TYPE_EDGE_FALLING>; 	/* GPIO_2 */
		reset-gpios = <&mcu_gpio0 1 GPIO_ACTIVE_LOW>; 	/* GPIO_1 */
	};
};

&oldi0_dss0 {
	status = "okay";
};

&oldi0_dss0_ports {
	#address-cells = <1>;
	#size-cells = <0>;

	port@0 {
		reg = <0>;
		oldi0_dss0_in: endpoint {
			remote-endpoint = <&dss0_dpi0_out0>;
		};
	}; 

	port@1 {
		reg = <1>;
		oldi0_dss0_out: endpoint {
			remote-endpoint = <&panel_lvds_in0>;
		};
	};
};

/*
 * HACK: With oldi1 disable oldi always returns EAGAIN making the panel not
 * show anything, so pretend we are in clone mode.
 */
&oldi1_dss0 {
	status = "okay";
};

&oldi1_dss0_ports {
	#address-cells = <1>;
	#size-cells = <0>;

	port@0 {
		reg = <0>;
		oldi1_dss0_in: endpoint {
			remote-endpoint = <&dss0_dpi0_out1>;
		};
	};

	port@1 {
		reg = <1>;
		oldi1_dss0_out: endpoint {
			remote-endpoint = <&panel_lvds_in1>;
		};
	};
};

The working verdin-am62p gives me the impression of correctly wired hardware and leaves open questions about how to correctly set up a native 4-lane LVDS (single channel) as device-tree overlay for Verdin iMX95.

Maybe I am almost there and just a bit too blind to see my mistake in the dts, so I am hoping you can help me out here.

Thanks and best regards,

Hi @bgo,

I tested our 10.1" LVDS display with a verdin imx95 running Torizon OS 7.4.0, with the device tree overlay verdin-imx95_panel-cap-touch-10inch-lvds_overlay.dtbo enabled. I can confirm that the display works - as it shows the Torizon easy pairing app. Therefore the device tree overlay source that you are referring to, is the right place.

I looked into your device tree overlay file for verdin iMX95. Overall, it looks good, assuming that you have configured the GPIO and PWM pins correctly for your backlight (it should be correct since you said the backlight works). Therefore, I would assume that the most likely cause is an incorrect LDB channel configuration - which is the LVDS data path. Comparing your overlay with ours, I find the following difference:

Toradex overlay:

&ldb {
    channel@0 {
        reg = <0>;
        ...
    };
};

your overlay:

&ldb {
    channel@0 {
        reg = <1>;
        ...
    };
};

Could you please try changing the reg value to 0? I think this is the culprit since I could reproduce your issue by changing the reg value to 1.

1 Like

Hi @rudhi.tx ,

thank you for investigating and spotting that error on my side! I changed the .dts accordingly, and now the display shows something on screen:

My guess here is, that I need to adapt the assigned-clock-rates for IMX95_CL_LDBPLL_VC0, or maybe re-check data-mapping - I will paste the final working device tree here.
Thanks again for your help!

Best regards,
Bernhard

Hi @bgo,

It looks like a timing mismatch issue. Could you try changing the hsync-len and vsync-len to 0?

hactive = <1024>;
hfront-porch = <160>;  
hback-porch = <160>;  
hsync-len = <0>;

vactive = <600>;
vfront-porch = <12>;
vback-porch  = <23>;
vsync-len    = <0>;

So the total horizontal timing would match the HSD Period value 1344, and the vertical value would match the VSD Period value 635 on the datasheet.

If that does not fix it, I would also try to verify the assigned-clock-rates value in your device tree. You wrote that assigned clock rates should be 47pixelclk and 7*pixelclk, but the values you have assigned do not look consistent to that.

1 Like

Hi @rudhi.tx ,

thank you for hinting the HSD and VSD, I will try it out.
About the clock rates, I did play around with the assigned-clock-rates and it is a left-over comment. Your overlay example suggests the formula 6*7*pixelclk and 7*pixelclk, so I reverted it to the default values at one point and forgot to revert the comment. The values I currently work with are:

assigned-clock-rates = <2280499200>, <380083200>;

which were calculated from the clock-frequency used by the panel (~54.3MHz). Or is that another value one should not touch? I am still learning :wink:

Best regards,
Bernhard

Honestly, I am also not very experienced on the calculation of assigned-clock-rates. However, I found a reference from NXP which says the Fvco should be in range 2.5Ghz to 5Ghz. So, inorder to satisfy with that, I would try to increase the pixel clock to 60MHz and then try with the assigned clock rates:
LDBPLL = 60 × 7 = 420 MHz
VCO = 420 × 6 = 2520 MHz

In the device tree, these values would be:

clock-frequency = <60000000>;
assigned-clock-rates = <2520000000>, <420000000>;
1 Like

Hi @rudhi.tx ,

thank you very much again for sharing the information from NXP!
Although I still see only flickering stripes, I wanted to share the current state of panel-timings and assigned-clock-rates:

		data-mapping = "vesa-24";
		width-mm = <154>;
		height-mm = <86>;

		panel-timing {
			clock-frequency = <66024000>;	/* within 20..67.2 MHz */

			hactive       = <1024>;
			hback-porch   =  <160>;
			hfront-porch  =  <215>;		/* within 16..216 */
			hsync-len     =    <1>;		/* within 1..140 */

			vactive       =  <600>;
			vback-porch   =   <23>;
			vfront-porch  =  <162>;		/* within 1..127 */
			vsync-len     =    <1>;		/* within 1..20  */

			de-active       =  <1>;
			hsync-active    =  <0>;
			vsync-active    =  <0>;
			pixelclk-active =  <1>;
		};
&ldb {
	/* 6*7*pixelclk and 7*pixelclk */
	assigned-clock-rates = <2773008000>, <462168000>;
	status = "okay";

Best regards,
Bernhard

Hi @bgo,

I just discussed with a colleague of mine. He said you should try the following:

  • Try to set the pixel clock values to min typ and max values for your display as you see in the toradex reference overlay file
  • Increase the sync duration to e.g. 4 for h-sync and v-sync
  • Provide the clock summary cat /sys/kernel/debug/clk/clk_summary
  • Provide the full device tree overlay again.

Hi @rudhi.tx ,

thank you again for you help. I added values for min., typ., and max. into the device tree overlay. Here is the current result:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
 * Copyright (C) 2025 Toradex
 */

// Marelcom MACHMI0700BNT-4CP2-B LVDS display (7 inch) with a resolution of 1024x600 pixels.
#include <dt-bindings/clock/fsl,imx95-clock.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pwm/pwm.h>

/dts-v1/;
/plugin/;

/ {
	compatible = "toradex,verdin-imx95";
};

&{/} {
	backlight_lvds_native: backlight {
		compatible = "pwm-backlight";
		//brightness-levels = <0 45 63 88 119 158 203 255>;
		/* PM requested 100 levels of brightness */
		/* brightness-levels[i] = PWM duty for perceived i% (gamma ≈ 2.2) */
	        brightness-levels = <
			/*  0% */   0   1   1   1   2   2   2   3   3   4
			/* 10% */   4   5   5   6   6   7   7   8   8   9
			/* 20% */   9  10  10  11  12  12  13  14  15  17
			/* 30% */  18  19  21  22  24  25  27  29  30  32
			/* 40% */  34  36  38  40  42  44  46  48  51  53
			/* 50% */  55  58  60  63  66  68  71  74  77  80
			/* 60% */  83  86  89  92  96  99 102 106 109 113
			/* 70% */ 116 120 124 128 131 135 139 143 148 152
			/* 80% */ 156 160 165 169 174 178 183 188 192 197
			/* 90% */ 202 207 212 217 223 228 233 238 244 249
			/*100% */ 255
		>;

		default-brightness-level = <80>;
		/* GPIO_10_DSI / DSI_BKL_EN via expander index 3 (SODIMM 21) */
		enable-gpios = <&som_gpio_expander 3 GPIO_ACTIVE_HIGH>;
		//pinctrl-names = "default";
		//pinctrl-0 = <&pinctrl_gpio_bkl_on>;
		/* PWM_3_DSI on TPM6 channel 0 on Verdin iMX95 with 20kHz
		 *  -> we use IMX95_PAD_GPIO_IO19__TPM6_CH2 here, as refered to in
		 * https://git.toradex.com/linux-toradex.git/tree/arch/arm64/boot/dts/freescale/imx95-verdin.dtsi?h=toradex_6.6-2.2.x-imx#n965
		 */
		pwms = <&tpm6 2 50000 0>;
		status = "okay";
	};

	panel-lvds-native {
		compatible = "panel-lvds";
		#address-cells = <1>;
		#size-cells = <0>;
		backlight = <&backlight_lvds_native>;

		status = "okay";

		data-mapping = "vesa-24";
		width-mm = <154>;
		height-mm = <86>;

		/* DE-mode, Min., Typ., and Max. */
		panel-timing {
			clock-frequency = <40800000 51200000 67200000>;

			hactive       = <1024 1024 1024>;
			hback-porch   = <  45  160  160>;
			hfront-porch  = <  42  157  215>;		/* within 16..216 */
			hsync-len     = <   4    4  200>;		/* within 1..140 */

			vactive       = < 600  600  600>;
			vback-porch   = <   5   23   23>;
			vfront-porch  = <   2    9  176>;		/* within 1..200 */
			vsync-len     = <   4    4    1>;		/* within 1..20  */

			de-active       =  <1>;
			hsync-active    =  <0>;
			vsync-active    =  <0>;
			pixelclk-active =  <1>;
		};


		port@0 {
			reg = <0>;
			panel_lvds0_in: endpoint {
				remote-endpoint = <&lvds0_out>;
			};
		};
	};
};

&display_pixel_link {
	status = "okay";
};

&displaymix_irqsteer {
	status = "okay";
};

&dpu {
	status = "okay";
};

&lvds_csr {
	status = "okay";
};

&ldb {
	/* 6*7*pixelclk and 7*pixelclk */
	assigned-clock-rates = <1713600000 2150400000 2822400000>, <285600000 358400000 470400000>;
	status = "okay";

	channel@0 {
		reg = <0>;
		status = "okay";

		fsl,data-mapping = "vesa";
		fsl,data-width = <24>;

		port@1 {
			reg = <1>;

			lvds0_out: endpoint {
				remote-endpoint = <&panel_lvds0_in>;
			};
		};
	};
};

&ldb0_phy {
	status = "okay";
};

/* Verdin I2C_1 */
&lpi2c4 {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	touchscreen@41 {
		compatible = "ilitek,ili251x";
		reg = <0x41>;
		interrupt-parent = <&gpio2>; 
		interrupts = <18 IRQ_TYPE_EDGE_FALLING>; 	/* GPIO_2 (SODIMM 208) */
		reset-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; 	/* GPIO_1 (SODIMM 206) */

		/* Make sure pads are muxed to GPIO for IRQ + RESET */
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2>;

		touchscreen-size-x = <1024>;
		touchscreen-size-y = <600>;
	};
};

&pixel_interleaver {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	channel@0 {
		reg = <0>;
		status = "okay";
	};
};

/* Verdin PWM_3_DSI - BKL_PWM */
&tpm6 {
	status = "okay";
};

With this device tree overlay applied the touchscreen stays black (no flickering and no stripes anymore, but also no image on screen).

~# ls /proc/device-tree/chosen/overlays/
display-MI0700BNT-4CP2-B_overlay.dtbo  model_overlay.dtbo  name  pwm-beeper_overlay.dtbo  rtc_overlay.dtbo

I added the output of cat /sys/kernel/debug/clk/clk_summary as attachment, as it has quite a lot of characters and chat is limited.

clk_summary.txt (48.8 KB)

I am not sure what to expect to see - should we be able to find the configured “assigned-clock-rates” in here?

I hope this information is useful

Best regards,
Bernhard

Hi @bgo,

Rudhi ask me to write you. You can’t specify several clocks for the assigned-clock-rates. This driver will not support it. Please try the attached device tree overlay.

Also please always send us the following information, this makes it easier to debug the problem:

  • kernel log (dmesg)
  • clock summary (/sys/kernel/debug/clk/clk_summary)
  • The current device tree overlay in use

Regards,
Stefan

verdin-imx95_panel-cap-touch-customer-lvds_overlay.dts (4.0 KB)

1 Like

Hi @stefan_e.tx ,

thank you for reaching out and providing a working overlay for our custom touch panel! I just tested it and it works like a charm!

I managed to get a working version myself yesterday evening with a build for HV-Mode and I want to share it too:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
 * Copyright (C) 2025 Toradex
 * Copyright (C) 2026 SOTAX AG
 */

// Marelcom MACHMI0700BNT-4CP2-B LVDS display (7 inch) with a resolution of 1024x600 pixels.
#include <dt-bindings/clock/fsl,imx95-clock.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pwm/pwm.h>

/dts-v1/;
/plugin/;

/ {
	compatible = "toradex,verdin-imx95";
};

&{/} {
	backlight_lvds_native: backlight {
		compatible = "pwm-backlight";
		//brightness-levels = <0 45 63 88 119 158 203 255>;

		/* brightness-levels[i] = PWM duty for perceived i% (gamma ≈ 2.2) */
	        brightness-levels = <
			/*  0% */   0   1   1   1   2   2   2   3   3   4
			/* 10% */   4   5   5   6   6   7   7   8   8   9
			/* 20% */   9  10  10  11  12  12  13  14  15  17
			/* 30% */  18  19  21  22  24  25  27  29  30  32
			/* 40% */  34  36  38  40  42  44  46  48  51  53
			/* 50% */  55  58  60  63  66  68  71  74  77  80
			/* 60% */  83  86  89  92  96  99 102 106 109 113
			/* 70% */ 116 120 124 128 131 135 139 143 148 152
			/* 80% */ 156 160 165 169 174 178 183 188 192 197
			/* 90% */ 202 207 212 217 223 228 233 238 244 249
			/*100% */ 255
		>;

		default-brightness-level = <80>;
		/* GPIO_10_DSI / DSI_BKL_EN via expander index 3 (SODIMM 21) */
		enable-gpios = <&som_gpio_expander 3 GPIO_ACTIVE_HIGH>;
		//pinctrl-names = "default";
		//pinctrl-0 = <&pinctrl_gpio_bkl_on>;
		/* PWM_3_DSI on TPM6 channel 0 on Verdin iMX95 with 20kHz
		 *  -> we use IMX95_PAD_GPIO_IO19__TPM6_CH2 here, as refered to in
		 * https://git.toradex.com/linux-toradex.git/tree/arch/arm64/boot/dts/freescale/imx95-verdin.dtsi?h=toradex_6.6-2.2.x-imx#n965
		 */
		pwms = <&tpm6 2 50000 0>;
		status = "okay";
	};

	panel-lvds-native {
		compatible = "panel-lvds";
		#address-cells = <1>;
		#size-cells = <0>;
		backlight = <&backlight_lvds_native>;

		status = "okay";

		data-mapping = "vesa-24";
		width-mm = <154>;
		height-mm = <86>;

		/* HV-mode, EXACT 60.000 Hz using smaller totals (lower dot-clock) */
		panel-timing {
			clock-frequency = <63000000>;	/* P = 63 MHz */

			hactive       = <1024>;
			hback-porch   =  <160>;
			hfront-porch  =   <96>;		/* within 16..216 */
			hsync-len     =  <140>;		/* within  1..140 */

			vactive       =  <600>;
			vback-porch   =   <23>;
			vfront-porch  =  <107>;		/* within 1..127 */
			vsync-len     =   <20>;		/* within 1..20  */

			de-active       =  <0>;
			hsync-active    =  <0>;
			vsync-active    =  <0>;
			pixelclk-active =  <1>;
		};


		port@0 {
			reg = <0>;
			panel_lvds0_in: endpoint {
				remote-endpoint = <&lvds0_out>;
			};
		};
	};
};

&display_pixel_link {
	status = "okay";
};

&displaymix_irqsteer {
	status = "okay";
};

&dpu {
	status = "okay";
};

&lvds_csr {
	status = "okay";
};

&ldb {
	assigned-clocks = <&scmi_clk IMX95_CLK_LDBPLL_VCO>,
			  <&scmi_clk IMX95_CLK_LDBPLL>;
	/* 6*7*pixelclk and 7*pixelclk */
	assigned-clock-rates = <2646000000>, <441000000>;
	status = "okay";

	channel@0 {
		reg = <0>;
		status = "okay";

		fsl,data-mapping = "vesa";
		fsl,data-width = <24>;

		port@1 {
			reg = <1>;

			lvds0_out: endpoint {
				remote-endpoint = <&panel_lvds0_in>;
			};
		};
	};
};

&ldb0_phy {
	status = "okay";
};

/* Verdin I2C_1 */
&lpi2c4 {
	#address-cells = <1>;

	touchscreen@41 {
		compatible = "ilitek,ili251x";
		reg = <0x41>;
		interrupt-parent = <&gpio2>; 
		interrupts = <18 IRQ_TYPE_EDGE_FALLING>; 	/* GPIO_2 (SODIMM 208) */
		reset-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; 	/* GPIO_1 (SODIMM 206) */

		/* Make sure pads are muxed to GPIO for IRQ + RESET */
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2>;
	};
};

&pixel_interleaver {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	channel@0 {
		reg = <0>;
		status = "okay";
	};
};

/* Verdin PWM_3_DSI - BKL_PWM */
&tpm6 {
	status = "okay";
};

Thank you both for your help and commitment @rudhi.tx and @stefan_e.tx ! :folded_hands:

Best wishes,

Bernhard

1 Like

Hi @bgo,

Glad to hear that it works now. Thanks for confirming!