Skip to main content
Version: BSP 6.x.y

Display Output, Resolution and Timings (Linux)

Introduction

A monitor or embedded display requires a certain display mode to operate correctly. Monitors often support various modes whereas embedded displays are usually a bit pickier. Display modes specify a combination of parameters, not only the display resolution but also refresh rate, color depth, and signal timings. On personal computers, the monitor passes the supported modes to the connected host system (Extended display identification data, EDID, transmitted through the Display Data Channel, DDC). The operating system presents the available modes to the user, typically as a list of available resolutions since the resolution is the parameter of primary interest. Embedded displays often do not have a dedicated DDC (e.g. parallel RGB, LVDS, or similar display links), and therefore the system needs to be told what exact display resolution and timings have to be supplied.

info

In version 5.x of the Reference Images for Yocto Project, most display interfaces don't enable in the Linux Device Tree by default. Therefore, to use them, one should apply the required Device Tree Overlay. The most straightforward way to do that is to edit the overlays.txt file available on the boot partition of the board. As for the current BSP 5.x, the boot partition is mounted on: /boot/. You can learn more about it on the Device Tree Overlays (Linux) Technical Article provided by Toradex.

Embedded displays without DDC channel (parallel RGB/LVDS) use a fixed mode provided by the driver, this can be either:

  • Display modes provided through machine-specific code (arch/arm/mach..., e.g. Tegra)
  • Display modes as part of the device tree (display-timings node, e.g. i.MX 6/Vybrid fbdev driver)
  • Display modes provided through modedb entry or calculated video modes (e.g. Tegra/i.MX 6/Vybrid fbdev driver)
  • Display modes from a display driver (used for kernel mode settings (KMS) e.g. from panel-simple.c, e.g. Vybrid DRM driver)
  • Display modes from a specific devicetree overlay (for BSP 5.x and newer)

If there are multiple display modes available (either through EDID/DDC or multiple display modes specified for an embedded display), the system allows choosing between them. In Linux, various subsystems deal with display modes. Depending on the display controller and driver used, different ways of configuring the mode are available. Available interfaces are for instance:

  • fbdev interface (fbset utility or kernel argument, internal modedb)
  • KMS interface (Kernel Mode Setting, part of the Direct Rendering Manager (DRM) interface, kernel argument, through Xorg/RandR using modesetting driver)
  • Classic X modes (using xorg.conf modelines, X driver-specific backend)
  • X modes through RandR extensions (RandR: Resize and Rotate Extension, implemented by libXrandr/xrandr utility, X driver-specific backend)
  • Wayland Compositors (the Wayland protocol does not deal with modes, the compositor handles modes directly. E.g. the reference compositor Weston uses the KMS interface)

Which mode setting interfaces are available and how to configure the timings for embedded display depends on the display controller driver. Toradex modules use different display controllers and therefore a different driver. Additionally, newer BSP versions might provide different drivers for the same controller. Refer to the module sections below on what implementations are available and how to use them.

i.MX 8 Series Based Modules

All drivers on the i.MX 8, i.MX 8M Mini and i.MX 8X family modules are integrated into the Linux kernel's DRM/KMS subsystem.

Apalis iMX8

The Apalis iMX8 provides display signals over HDMI and LVDS. The Apalis LVDS1 can be used as two single-channel LVDS or one dual-channel LVDS. A third single-channel LVDS can be connected on type-specific Apalis pins.

Additionally, the HW can provide display port signals on the HDMI connector and MIPI DSI signals on type-specific pins, but these interfaces have not been brought up in Linux as of yet.

DescriptionHDMI1LVDS1Type-Specific
Device-Tree Node Referencehdmildb2ldb1
DRM Connector Name 1)HDMI-A-1LVDS-1(N/A)
Connector on EvalBoardX11 (DVI-D)X13X38 (Mezzanine Connector)
Connector on IxoraX17 (HDMI)X19N/A
Supports EDID (Software)Yes(Yes) 2)(Yes) 2)
  1. This depends on the configuration, here one HDMI and one LVDS are configured.
  2. The common use case is to hard-code the mode information in the device-tree/panel-driver or the overlay.
    info

    You can learn more about overlays on the Device Tree Overlays (Linux) Technical Article provided by Toradex.

Colibri iMX8X

The i.MX 8X SoC has one single display controller with two independent outputs which may be routed to two LVDS/DSI PHYs as well as parallel RGB. The two LVDS/DSI PHYs can either provide independent MIPI DSI or single-channel LVDS. The two PHYs can also be combined to provide one single dual-channel LVDS. On the Colibri iMX8X, only the parallel RGB is available on the SODIMM edge connector which is also depicted in the default device tree imx8qxp-colibri-eval-v3.dtb. The two LVDS/DSI PHYs are routed to an FFC receptacle X2 on the backside of the module.

DescriptionParallel RGBDSI-to-HDMI
Adapter 1)
LVDS 2)
Device-Tree Node Referencepanel_dpilt8912_hdmi{not exist}
DRM Drivermxsfb-drmimx-drmimx-drm
DRM Cardcard1card0card0
DRM Connector Name 3)DPI-1HDMI-A-1LVDS-1
Connector on EvalBoardX18 (LVDS) 4)
X20 or X34
X24 (VGA) 5)
X5 (DVI-D)N/A
Connector on IrisX3
X7 (LVDS) 4)
X4 (DVI-D)N/A
Connector on ViolaX7N/A 6)N/A
Connector on AsterX12
X13 (VGA) 5)
N/A 6)N/A
Supports EDID (Software)(Yes) 7)Yes(Yes) 7)
  1. The DSI-to-HDMI adapter is optional and requires a specific devicetree overlay colibri-imx8x_dsihdmi_overlay.dtbo.
  2. LVDS is optional and requires a custom adapter/cable and custom device tree like e.g. imx8qxp-colibri-lvds-single-eval-v3.dtb or imx8qxp-colibri-lvds-dual-eval-v3.dtb.
    info

    You can learn more about overlays on the Device Tree Overlays (Linux) Technical Article provided by Toradex.

  3. This depends on the configuration. In addition to parallel RGB only either HDMI or LVDS may be configured.
  4. LVDS is provided via an on-carrier LVDS transceiver chip.
  5. Analogue VGA is provided via an on-carrier RAM-DAC chip.
  6. Could be realized using an additional optional Colibri HDMI adapter daisy-chained to the DSI-to-HDMI adapter.
  7. The common use case is to hard-code the mode information in the overlay/device-tree/panel-driver.

Verdin iMX8M Mini

The i.MX 8M Mini SoC has one single display controller with one MIPI DSI output. It neither features a native HDMI nor LVDS output.

The MIPI DSI output can be converted using one of the available Verdin display adapters.

By default, the HDMI display adapter is enabled with the overlay. To use the LVDS adapter, one should disable the HDMI bridge overlay and enable the LVDS one instead.

DescriptionDSI-HDMIDSI-LVDS
Device-Tree Node Referencehdmi_lontium_lt8912lvds_ti_sn65dsi83
DRM Connector NameHDMI-A-1LVDS-1
Supports EDID (Software)YesYes (Obs-1)

Obs-1: The common use case is to hard-code the mode information in the overlay or device-tree/panel-driver.

info

You can learn more about overlays on the Device Tree Overlays (Linux) Technical Article provided by Toradex.

The Verdin DSI to HDMI Adapter and Verdin DSI to LVDS Adapter disabled in the Linux Device Tree by default. Therefore, to use them, one should apply the required Device Tree Overlay.

The most straightforward way to do that is to edit the overlays.txt file available on the `/boot" partition of the Verdin iMX8M Mini.

The overlays.txt contains the fdt_overlays field that lists the overlays the system will load on the boot, separated by space.

Note that the required overlay files are already available at /boot/overlays.

To see what overlays to use for each video output:

  • For using the DSI-HDMI Adapter: check the HDMI section with Accessory on the Device Tree Overlay page.
  • For using the DSI-LVDS Adapter: check the Capacitive Touch Display 10.1" LVDS section with Accessory on the Device Tree Overlay page.
caution

If after activating the overlay for the DSI-HDMI adapter you still don't see a video output (considering that you are running a graphical application, please check your HDMI cable, and try with a different TV or Monitor.

DescriptionMIPI DSI Mezzanine Connector
DevBoardX48
DahliaX17

Verdin iMX8M Plus

The i.MX 8M Plus SoC features a total of three display controllers called LCDIF. It supports up to 1920x1200p60 display per LCDIF if no more than 2 instances are used simultaneously, or 2x 1080p60 + 1x 4kp30 on HDMI if all 3 instances are used simultaneously:

  • One LCDIF drives MIPI DSI, up to UWHD and WUXGA
  • One LCDIF drives LVDS Tx, up to 1920x1080p60
  • One LCDIF drives HDMI Tx, up to 4kp30

The MIPI DSI and the HDMI port are Reserved Verdin interfaces and therefore compatible with other Verdin modules. The LVDS is not part of the Always Compatible interfaces, its signals are located on the module-specific pins. This means using the LVDS interface can prevent compatibility with other Verdin modules. Therefore, the MIPI DSI and HDMI ports are the preferred display interfaces.

If an LVDS display is used and compatibility with other Verdin modules is required, a MIPI DSI to LVDS bridge on the carrier board should be considered. You can check more information in the Verdin Family Specification.

All these video outputs are managed with overlays in order to be enabled.

info

You can learn more about overlays on the Device Tree Overlays (Linux) Technical Article provided by Toradex.

Unlike native HDMI and LVDS outputs, the MIPI DSI output can be converted using one of the available Verdin display adapters.

By default, the Verdin DSI to HDMI Adapter overlay is enabled. To use the Verdin DSI to LVDS Adapter, one should disable the HDMI bridge overlay and enable the LVDS one instead.

DescriptionNative HDMINative LVDSDSI-HDMIDSI-LVDS
Device-Tree Node Referencelcdif3 + hdmilcdif2 + ldbhdmi_lontium_lt8912lvds_ti_sn65dsi83
DRM Connector Name (Obs-1)HDMI-A-1LVDS-1HDMI-B-1LVDS-2
Supports EDID (Software)YesYes (Obs-2)YesYes (Obs-2)

Obs-1: This depends on the configuration. Here both native HDMI and LVDS are configured, as well as the DSI-to-HDMI/LVDS adapters.

Obs-2: The common use case is to hard-code the mode information in the overlay or, alternatively, in the device-tree/panel-driver.

DescriptionHDMIMezzanine Connector
(native LVDS)
MIPI DSI Mezzanine Connector
DevBoardX37X52X48
Dahlia V1.0--X17
Dahlia V1.1X21-X17

The most straightforward way to enable the desired overlay is to edit the overlays.txt file available on the /boot partition of the Verdin iMX8M Plus.

The overlays.txt contains the fdt_overlays field that lists the overlays the system will load on the boot, separated by space.

Note that the required overlay files are already available at /boot/overlays.

To see what overlays to use for each video output:

  • For using the Native HDMI: check the HDMI section on the Device Tree Overlay page.
  • For using the DSI-HDMI Adapter: check the HDMI section with Accessory on the Device Tree Overlay page.
  • For using the DSI-LVDS Adapter: check the Capacitive Touch Display 10.1" LVDS section with Accessory on the Device Tree Overlay page.

After changing the overlays.txt, reboot your board to activate the overlay in the next boot.

caution

If after activating the overlay for the DSI-HDMI adapter you still don't see a video output, and considering that you are running a graphical application, please check your HDMI cable, and try with a different TV or Monitor.

Verdin iMX8M Plus LVDS Known issues

This issue only applies if you are using the native LVDS from Verdin iMX8M Plus (not the DSI to LVDS adapter) and you want to use a different frequency from 74.25MHz for single channel and 148.5Mhz for dual channel.

danger

Be aware that even though it's possible to change the pixel clock frequency as shown in this section, we have noticed that some harmonics may appear with certain pixel clock selections and it can cause some issues with the display image.

The current LVDS driver implementation from the NXP kernel only supports 74.25 MHz single channel and 148.5 MHz dual channel LVDS. If a different frequency is set, the value will default to one of the previously mentioned frequencies.

To workaround this issue, the device driver requires some modifications. These modifications can be applied to kernel 5.4 (BSP 5) and kernel 5.15 (BSP 6) as well. The only difference is the files that will be changed.

  1. First, removed the following code inside drivers/gpu/drm/imx/imx8mp-ldb.c, as the patch shows.
diff --git a/drivers/gpu/drm/imx/imx8mp-ldb.c b/drivers/gpu/drm/imx/imx8mp-ldb.c
index c26f8dc83b89..4287d8b31cce 100644
--- a/drivers/gpu/drm/imx/imx8mp-ldb.c
+++ b/drivers/gpu/drm/imx/imx8mp-ldb.c
@@ -193,15 +193,6 @@ imx8mp_ldb_encoder_atomic_check(struct drm_encoder *encoder,
return -EINVAL;
}

- /*
- * Due to limited video PLL frequency points on i.MX8mp,
- * we do mode fixup here in case any mode is unsupported.
- */
- if (ldb->dual)
- mode->clock = mode->clock > 100000 ? 148500 : 74250;
- else
- mode->clock = 74250;
-
return 0;
}

@@ -219,16 +210,6 @@ imx8mp_ldb_encoder_mode_valid(struct drm_encoder *encoder,
if (ldb_ch->panel)
return MODE_OK;

- /*
- * Due to limited video PLL frequency points on i.MX8mp,
- * we do mode valid check here.
- */
- if (ldb->dual && mode->clock != 74250 && mode->clock != 148500)
- return MODE_NOCLOCK;
-
- if (!ldb->dual && mode->clock != 74250)
- return MODE_NOCLOCK;
-
return MODE_OK;
}
  1. Next, update the imx8mp.dtsi device tree with the clock desired value times 7. The internal divider will always divide the output LVDS clock by 7, so if, let's say, we want an output clock of 92 MHz, we should select 650000000 in the device tree. The last clock of assigned-clock-rates (inside clk: clock-controller@30380000 node) should be updated. This value is linked to the IMX8MP_VIDEO_PLL1 variable.
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 34ebc97e144d..e1c2b719d437 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -723,7 +723,7 @@
<400000000>,
<393216000>,
<361267200>,
- <1039500000>;
+ <650000000>>;
};

src: src@30390000 {
  1. Finally, compile the new kernel and update your image. Follow the guide Build U-Boot and Linux Kernel from Source Code for more information.

The clock frequency can be checked by running the following command in your terminal:

# cat /sys/kernel/debug/clk/clk_summary | grep -C 5 video

The currently supported frequencies are described in the following code, inside drivers/clk/imx/clk-imx8mp.c.

/*#define PLL_1443X_RATE(_rate, _m, _p, _s, _k)     \
{ \
.rate = (_rate), \
.mdiv = (_m), \
.pdiv = (_p), \
.sdiv = (_s), \
.kdiv = (_k), \
}*/

static const struct imx_pll14xx_rate_table imx8mp_videopll_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),
};

Therefore, the driver supports frequencies of 148.5 MHz, 92 MHz (approximately), 84 MHz (approximately) and 74.25 MHz (these are the rate values from the code divided by 7).

Now, if you want to enable a custom frequency which is not listed, let's say 40 MHz, you need to manually add a new value to the struct shown above, so the driver will be able to generate this new value.

Checking the iMX8M Plus Reference Manual, section 5.1.5.4.4 SSCG and Fractional PLLs, a formula to calculate the desired frequency is shown:

Fout=((m + k/65536) × Fin) / (p × 2^s)
  • Where, 1 ≤ p ≤ 63, 64 ≤ m ≤ 1023, 0 ≤ s ≤ 6, -32768 ≤ k ≤ 32767.
  • p, m, and s are unsigned integers. k is a two's complement integer.
  • Fout is the output frequency, Fin is the input frequency, and p,m,s and k are division values for the pre-divider, main divider, scaler, and DSM respectively.
  • The input frequency is 24 MHz.

Let's take our 40 MHz. We can start by defining our k, p, and s values. To makes thing simple, we can start by putting reasonable values into k, p, and s that will facilitate the calculation. Note that they must follow the previous rules.

If we say that k is 0, p is 2 and s is 2, we will end up with:

Fout= m x Fin / 8

Fin is 24 MHz and Fout is 40 MHz x 7, which is 280 MHz. So calculating m we have approximately 93. Then, we can add our new value to the driver:

diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index a92cf772720a..38333f1a8c64 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -59,6 +59,7 @@ static const struct imx_pll14xx_rate_table imx8mp_videopll_tbl[] = {
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(280000000U, 93, 2, 2, 0),
};

static const struct imx_pll14xx_rate_table imx8mp_drampll_tbl[] = {

And then select it in the device tree:

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 34ebc97e144d..50b4505385e9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -723,7 +723,7 @@
<400000000>,
<393216000>,
<361267200>,
- <1039500000>;
+ <280000000>;
};

src: src@30390000 {

After that, compile the new kernel and add it to your image. The desired native LVDS clock will be displayed.

The clock frequency can be checked by running the following command in your terminal:

# cat /sys/kernel/debug/clk/clk_summary | grep -C 5 video

i.MX 8 HDMI Output

Enabling the HDMI overlay is needed, like:

# cp /boot/overlays.txt ~/overlays_backup.txt
# echo "fdt_overlays=apalis-imx8_hdmi_overlay.dtbo" > /boot/overlays.txt
# sync
# reboot
info

You can learn more about overlays on the Device Tree Overlays (Linux) Technical Article provided by Toradex.

A connected monitor provides the modes it is capable of displaying and its preferred mode through DDC/EDID. The kernel then decides on the mode depending on the capabilities of the monitor and the SoM.

To force one of the possible modes add the desired mode on the kernel command line:

video=HDMI-A-1:1280x720

Note that Weston, depending on its configuration might change the chosen mode again, see below.

i.MX 8 LVDS Output

LVDS is configured from the device tree and the overlays. While it is possible to override the mode (timing and resolution) from the command line we recommend configuring everything in the device tree and/or the overlay file.

info

You can learn more about overlays on the Device Tree Overlays (Linux) Technical Article provided by Toradex.

Note that also for a dual-channel display the full panel needs to be specified. The clock and the horizontal timings are divided by two when split configuring the two channels.

Note that Weston, depending on its configuration might change the chosen mode again, see below.

Colour Mapping and Colour Depth, Single vs. Dual-Channel

The ldb node and its lvds-channel child nodes represent the bridge that creates the LVDS signals.

Set fsl,data-mapping and fsl,data-width in the lvds-channel node according to the color mapping and color depth of your panel.

Valid combinations are:

fsl,data-mappingfsl,data-widthdata-mapping (panel-lvds node)
spwg18jeida-18
spwg24vesa-24
jeida24jeida-24

(If your display is jeida 18, use the identical spwg 18 combinations)

Specify the property 'fsl,dual-channel;' in the ldb node if you want the ldb in dual channel mode, don't specify it for single-channel mode.

&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>;
};
};
};
};

Panel Timings

The connected panel is represented in the device tree in its own node. That node references the used LDB/LVDS channel through its node 'port'.

One can either use the panel-simple or the panel-lvds driver, both options are outlined below.

Panel Simple for Kernel 4.14.x
Panel Simple

Set the property 'compatible' to an existing or newly added panel from the panel-simple driver. Compare with drivers/gpu/drm/panel/panel-simple.c.

Compatible StringDescription
logictechno,lt170410-2whcCapacitive Touch Display 10.1" LVDS
        lvds1_panel {
compatible = "lg,lp156wf1";
backlight = <&backlight>;

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

Specify detailed timings in the panel node:

With the "panel-lvds" you can specify detailed timings in the device tree. This driver additionally requires you to specify the property 'data-mapping'. See the required value in the color mapping table above.

        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>;
};
};
};

DRM/KMS

Collect Information

The modetest utility prints information on the current DRM state.

    modetest -M imx-drm
modetest -M mxsfb-drm

The latter one may be used for parallel RGB on Apalis/Colibri iMX8X.

Find from the output:

Output sectionInformation
Connectors:DRM names, e.g. HDMI-A-1, LVDS-1
List of detected possible modes, ID numbers
CRTCs:Currently used mode

Force a Connector State

The sysfs allows changing the connector state. This may be useful to switch the state of a display that does not have a hotplug detection.

    echo off > /sys/class/drm/card0-LVDS-1/status
echo on > /sys/class/drm/card0-LVDS-1/status

Draw a Testpattern

The modetest utility from libdrm/test can set an available mode and draw a test pattern which might be useful in board bring-up and debugging. Use connector_id@crtc_id:mode.

    systemctl stop weston@root
#systemctl stop weston # For older BSPs
modetest -M imx-drm -s 82@32:1280x720-50
modetest -M imx-drm -s 85@71:1280x800-60

Injecting a Binary EDID Blob

If the kernel has CONFIG_DRM_LOAD_EDID_FIRMWARE defined, one can inject a binary EDID blob to override the one which otherwise would be read from the DDC channel. Copy the binary blob to /lib/firmware/edid/ and set the following parameter on the kernel command line.
For older kernels < 5.4 replace drm.edid_firmware with drm_kms_helper.edid_firmware.

    drm.edid_firmware=edid/1920x1080.bin

or connector specific

    drm.edid_firmware=LVDS-1:edid/1920x1080.bin

DRM References

Presentation Bootlin
Kernel Userspace API
DRM KMS Overview by ST
Injecting a Binary EDID Blob

Weston

The configuration is set in /etc/xdg/weston/weston.ini per connector:

[output]
name=HDMI-A-1
# mode=800x600@75.0
# mode=dotclock hdisp hsyncstart hsyncend htotal vdisp vsyncstart vsyncend vtotal hflag vflag
# mode=49.00 800 840 920 1040 600 603 607 629 -hsync +vsync
mode=current
# mode=preferred

Note that unless you use a detailed mode you can only change to a mode out of the list of known modes.

i.MX 6 Based Modules

The iMX6 based modules use the fbdev interface for mode setting and output configuration. The Apalis iMX6 can have up to four video outputs with corresponding framebuffers while the Colibri iMX6 can have two.

The Vivante X driver can only make use of the first framebuffer /dev/fb0 while the others can be used through the fbdev framebuffer interface.

The assignment of the possible display outputs to the framebuffers (scan-out engines) and their timing configuration can be done either on the Kernel command line or from within the device tree. The command line settings take precedence over the device tree.

The first and third video output has an additional overlay framebuffer configured.

Video OutputIPU CoreFramebuffer boot nameFramebuffer DeviceOverlay Framebuffer Device
FirstIPU1mxcfb0/dev/fb0/dev/fb1
SecondIPU1mxcfb1/dev/fb2
Third (Apalis only)IPU2mxcfb2/dev/fb3/dev/fb4
Fourth (Apalis only)IPU2mxcfb3/dev/fb5

i.MX 6 Framebuffer Boot Configuration

The command line parameter takes the following form, use off for unused framebuffers:

    "video=mxcfb<number>:dev=<Output>,<Mode Specifier>,if=<Output Format>,[bpp=<Framebuffer Depth>]"

e.g.:

video=mxcfb0:dev=lcd,EDT-WVGA,if=RGB24
video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24
video=mxcfb1:off

<Output> can be one of the following options

Output DeviceOutputOutput Format
Parallel RGBlcdApalis: RGB24, Colibri: RGB666
HDMIhdmiRGB24
VGA (Apalis only)vdacRGB565
LVDS (Apalis only)ldbdepends on attached display

Note: The LVDS and VGA connectors available on the Colibri Evaluation Board, as well as the LVDS and the analog part of the DVI-I connector of the Colibri Iris have converted outputs from the Parallel RGB signals of the Colibri module. Therefore use the Output specifier "lcd" to specify their settings.

<Mode Specifier> can be a named mode from the kernel sources (e.g. EDT-WVGA) or calculated modes using the VESA CVT formula (e.g. 1920x1080M@60). For the calculated modes refer to: modedb.txt.

<Framebuffer Depth> if omitted is set to 16 bits per pixel in our device trees. Use bpp=32 if you want a higher color depth. Note that while bpp=24 is legal some accelerated drivers stop working correctly (e.g. the OpenGL ES driver with framebuffer backend).

The following sets up the U-Boot environment variable "vidargs" which becomes part of the Kernel command line:

setenv vidargs 'mxc_hdmi.only_cea=1 video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24
video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off fbmem=32M'
saveenv

Some tested mode specifiers are:

Mode SpecifierDescription
EDT-VGAEDT 5.7" TFT VGA
640x480M@60VGA, default mode, also for EDT 5.7" TFT VGA
EDT-WVGAEDT 7.0" TFT WVGA
800x480M@60EDT 7.0" TFT WVGA
FusionF07ACapacitive Touch Display 7" Parallel
FusionF07AFusion Multi-Touch Display 7"
FusionF07AResistive Touch Display 7" Parallel
800x600M@60SVGA
FusionF10AFusion Multi-Touch Display 10"
1024x600M@60Fusion Multi-Touch Display 10"
1024x768M@60XGA
1280x720M@60720p (HD)
1920x1080M@601080p (full HD)
info

Some named mode specifiers are only available in the latest Kernel.

i.MX 6 HDMI Output

For the HDMI Output the i.MX 6 reads EDID information from an attached monitor which provides the monitor's capabilities. The i.MX 6 then chooses a video mode that the monitor is capable of displaying and is closest to the one requested on the command line.

The additional command line parameter mxc_hdmi.only_cea=1 limits the modes considered valid to CEA defined ones, e.g. 480p, 720p, 1080p. Some monitors do only work with this parameter set while others do only work without the parameter, however most monitors do work either way.

i.MX 6 LVDS Output (Apalis only)

The i.MX6 has a single/dual-channel LVDS display interface which is accessible on the Apalis iMX6 and can be used in different configurations.

The display resolution sets from the kernel command line. If no resolution is given on the command line, the setting from the overlay and the device tree is taken.

Channel and color mapping configuration needs to be done in the device-tree e.g. shown for our Capacitive Touch Display 10.1" LVDS.

info

Since BSP 5.1 LVDS should be enabled by loading a proper overlay file. Find more information about overlays here: Device Tree Overlays (Linux)

i.MX6 Multiple Outputs

If multiple framebuffers get configured there might be issues in setting up the pixelclocks of the individual framebuffers. Clock settings of already configured framebuffers might get changed by subsequently configured framebuffers. Usually, this is only an issue when using different timings on different outputs. In such a case one might have to tweak the framebuffer timings or adapt the kernel sources to use different clock parents for the different framebuffers. The clock tree in /sys/kernel/debug/clk/clk_summary can be used to debug the issue.

The following sets up four outputs, each with a resolution of 640x480.

setenv vidargs video=mxcfb0:dev=lcd,640x480M@60,if=RGB24 video=mxcfb1:dev=vdac,640x480M@60,if=RGB565 
video=mxcfb2:dev=hdmi,640x480M@60,if=RGB24 video=mxcfb3:dev=ldb,640x480M@60,if=RGB666 ldb=sin0 fbmem=32M

And to stress, the X driver restriction lets repeat a sentence from the i.MX 6 introduction above:

The Vivante X driver can only make use of the first framebuffer /dev/fb0 while the others can be used through the fbdev framebuffer interface.

i.MX 6ULL and i.MX 7 based modules

The i.MX 6ULL and iMX 7 make use of the eLCDIF display controller. Our current BSP provides the fbdev based driver mxsfb (drivers/video/fbdev/mxsfb.c).

fbdev driver mxsfb

DescriptionOutput 1
Framebuffer boot namemxsfb
Framebuffer device/dev/fb0
X-Server driverfbdev
X-Server output namedefault
Connector on EvalBoardLVDS/RGB/VGA
Connector on IrisDVI-A
Supports EDID (Software)No

i.MX 6ULL and i.MX 7 Framebuffer Boot Configuration

info

Up to BSP 2.7b2, the driver does not support specifying display resolutions via kernel parameter (modedb or calculated via timing formulas).

Beginning with BSP 2.7b3 our BSP supports configuration of framebuffer resolution from the kernel command line using the kernel internal modedb. If no resolution is given on the command line (e.g. cleared vidargs doing setenv vidargs from within U-Boot) the native-mode from the device tree is taken. The pixelclock and output enable polarity can be changed from their default with the parameters pixclockpol=1, outputen=1.

The following sets the output with a resolution of 800x480 (e.g. for our EDT 7.0" TFT WVGA):

setenv vidargs video='mxsfb:800x480M-16@60'

Some tested mode specifiers are:

Mode SpecifierDescription
640x480M-16@60VGA, default mode, also for EDT 5.7" TFT VGA
800x480M-16@60EDT 7.0" TFT WVGA
800x480M-16@60,pixclockpol=1Capacitive Touch Display 7" Parallel
800x480M-16@60,pixclockpol=1Fusion Multi-Touch Display 7"
800x480M-16@60,pixclockpol=1Resistive Touch Display 7" Parallel
1024x600M-16@60Fusion Multi-Touch Display 10"

To support a specific display we recommend using the device tree to specify the exact display resolution and timings while also specifying the `native-mode` property. See the carrier board device tree file, e.g. `arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi`:
    &lcdif {
display = <&display0>;
status = "okay";

display0: lcd-display {
bits-per-pixel = <16>;
bus-width = <18>;

display-timings {
native-mode = <&timing_vga>;

/* Standard VGA timing */
timing_vga: 640x480 {
clock-frequency = <25175000>;
hactive = <640>;
vactive = <480>;
hback-porch = <40>;
hfront-porch = <24>;
vback-porch = <32>;
vfront-porch = <11>;
hsync-len = <96>;
vsync-len = <2>;

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

Tegra K1 based modules

The Apalis TK1 display controller subsystem features two independent display controllers which support DSI, eDP, HDMI, and LVDS. Each display controller can run at different clock rates and drive panels at different resolutions.

DescriptionOutput 1Output 2
Framebuffer boot nametegrafb0tegrafb1
Framebuffer device/dev/fb0/dev/fb1
X-Server nameLVDS-0HDMI-0
Connector on EvalBoardLVDSDVI-D
Connector on IxoraLVDSHDMI
Supports EDID (Software)NoYes

Apalis TK1 Device Tree Configuration

Starting with the BSP release 2.8b2 display outputs can be fully configured using the device tree. Configuration can be found in a dtsi file, depending on the module version:

    arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi /* for Apalis TK1 V1.2A and later */
arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-displays.dtsi /* for Apalis TK1 V1.0A, V1.0B and V1.1A */
    dc@54200000 {
status = "okay";
nvidia,dc-connection = <&lvds>;
nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
nvidia,emc-clk-rate = <300000000>;
nvidia,fb-bpp = <32>; /* bits per pixel */
nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
avdd-supply = <&as3722_ldo4>;
};

dc@54240000 {
status = "okay";
nvidia,dc-connection = <&hdmi>;
nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
nvidia,emc-clk-rate = <300000000>;
nvidia,fb-bpp = <32>; /* bits per pixel */
nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
avdd_hdmi-supply = <&as3722_sd4>;
};
};

nvidia,dc-connection points to an entry in the same file that describes the interface. Possible combinations:

dc@54200000dc@54240000
&lvds&hdmi
&hdmi&lvds
&hdmi&edp

if you're using only one display output, the status property for dc@54240000 can be set to disabled.

Apalis TK1 LVDS Output

The LVDS display configuration can be found in a dtsi file, depending on the module version:

    arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi /* for Apalis TK1 V1.2A and later */
arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-displays.dtsi /* for Apalis TK1 V1.0A, V1.0B and V1.1A */

The lvds parent node has three child nodes of interest:

disp-default-out

This node includes color depth, mode and resolution:

nvidia,out-depth = <24>; /* 18 and 24 are the only accepted values */
nvidia,out-lvds-mode = <TEGRA_DC_LVDS_24_1>; /* TEGRA_DC_LVDS_24_0 and TEGRA_DC_LVDS_24_1 depending on the mode your screen supports */
nvidia,out-xres = <1280>;
nvidia,out-yres = <800>;

display-timings

This node includes the timing configuration of your display. This node may include multiple configurations of which a selection is made based on the order and resolution chosen via the disp-default-out node.

                display-timings {
timing_1280_800: 1280x800 {
clock-frequency = <71100000>;
nvidia,h-ref-to-sync = <1>;
nvidia,v-ref-to-sync = <1>;
hsync-len = <40>;
vsync-len = <9>;
hback-porch = <60>;
vback-porch = <7>;
hactive = <1280>;
vactive = <800>;
hfront-porch = <60>;
vfront-porch = <7>;
};
};

out-pins

This node is used to set control signal polarity.

                out-pins {
hsync {
pin-name = <TEGRA_DC_OUT_PIN_H_SYNC>;
pol = <TEGRA_DC_OUT_PIN_POL_LOW>;
};
vsync {
pin-name = <TEGRA_DC_OUT_PIN_V_SYNC>;
pol = <TEGRA_DC_OUT_PIN_POL_LOW>;
};
pix-clk {
pin-name = <TEGRA_DC_OUT_PIN_PIXEL_CLOCK>;
pol = <TEGRA_DC_OUT_PIN_POL_HIGH>;
};
data-enable {
pin-name = <TEGRA_DC_OUT_PIN_DATA_ENABLE>;
pol = <TEGRA_DC_OUT_PIN_POL_HIGH>;
};
};

The U-Boot vidargs variable needs to be cleared for the device tree LVDS configuration to work correctly.

Apalis TK1 HDMI Output

Since Tegra K1 supports EDID, if a monitor that provides EDID information is connected via DVI-D (aka HDMI), the framebuffer driver queries the monitor and selects an appropriate resolution. Changing resolution is possible using XrandR, see X-Server for more information.

Apalis TK1 eDP Output

In order to connect an eDP screen, you'll need a custom carrier board or an eval board with a mezzanine and a custom cable. To enable eDP modify arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi or tegra124-apalis-displays.dtsi depending on module revision:

@@ -190,7 +190,7 @@

dc@54200000 {
status = "okay";
- nvidia,dc-connection = <&lvds>;
+ nvidia,dc-connection = <&hdmi>;
nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
nvidia,emc-clk-rate = <300000000>;
nvidia,fb-bpp = <32>; /* bits per pixel */
@@ -200,7 +200,7 @@

dc@54240000 {
status = "okay";
- nvidia,dc-connection = <&hdmi>;
+ nvidia,dc-connection = <&edp>;
nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
nvidia,emc-clk-rate = <300000000>;
nvidia,fb-bpp = <32>; /* bits per pixel */

and arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-gpio.dtsi or tegra124-apalis-gpio.dtsi

@@ -31,7 +31,7 @@
TEGRA_GPIO(DD, 6) /* 13 Apalis GPIO6 */
TEGRA_GPIO(EE, 3) /* 220 HDMI1_CEC */
TEGRA_GPIO(EE, 5) /* 156 MMC1_D6 */
-#ifndef APALIS_TK1_EDP /* used as optional eDP hot-plug pin */
+#if 0 /* used as optional eDP hot-plug pin */
TEGRA_GPIO(FF, 0) /* 3 Apalis GPIO2 */
#endif
TEGRA_GPIO(FF, 1) /* 158 MMC1_D7 */

U-Boot vidargs variable needs to be cleared for eDP to work correctly.

Depending on your eDP bridge resp. screen you may need to hack the eDP link training to use higher drive current, lane preemphasis and post cursor e.g. by further modifying arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-v1.2-displays.dtsi or tegra124-apalis-displays.dtsi depending on module revision:

@@ -83,22 +83,22 @@
};
dp-lt-config {
dp-config@0 {
- drive-current = <0 0 0 0>;
- lane-preemphasis = <0 0 0 0>;
- post-cursor = <0 0 0 0>;
+ drive-current = <2 2 2 2>;
+ lane-preemphasis = <1 1 1 1>;
+ post-cursor = <2 2 2 2>;
tx-pu = <0>;
load-adj = <0x03>;
};
dp-config@1 {
- drive-current = <0 0 0 0>;
- lane-preemphasis = <0 0 0 0>;
- post-cursor = <0 0 0 0>;
+ drive-current = <1 1 1 1>;
+ lane-preemphasis = <2 2 2 2>;
+ post-cursor = <1 1 1 1>;
tx-pu = <0>;
load-adj = <0x04>;
};
dp-config@2 {
drive-current = <0 0 0 0>;
- lane-preemphasis = <1 1 1 1>;
+ lane-preemphasis = <3 3 3 3>;
post-cursor = <0 0 0 0>;
tx-pu = <0>;
load-adj = <0x06>;

Tegra 2 & 3 based module

The Tegra 2 (Colibri T20) and Tegra 3 (Colibri T30/Apalis T30) based modules provide two display outputs.

The X-Server driver labels the outputs differently than the framebuffer:

DescriptionOutput 1Output 2
Framebuffer boot nametegrafb0tegrafb1
Framebuffer device/dev/fb0/dev/fb1
X-Server nameLVDS-1HDMI-1
Connector on EvalBoardLVDS/RGB/VGADVI-D
Connector on IrisDVI-ADVI-D
Supports EDID (Software)NoYes

The Tegra X driver provides (partial) support for the X RandR extension. On the DVI/HDMI output, the Tegra driver supports reading display modes from EDID via the Display Data Channel (DDC). Toradex also enhanced the driver to use the fbdev modedb and kernel argument support for the parallel RGP/LVDS output.

Tegra Framebuffer Boot Configuration

Note: Up to BSP V2.1Beta1 (released before 2014), the boot resolution of the framebuffer device is fixed in the kernel board initialization. See Tegra Framebuffer Boot Configuration (up to BSP V2.1Beta1).

Beginning with BSP V2.1 Beta 2 release in February 2014 our BSP supports the configuration of framebuffer resolution from the kernel command line using the kernel internal modedb.

The framebuffer driver registers two boot driver names (tegrafb0/tegrafb1) to allow different resolutions to be configured from the kernel command line. Using these two names, one can set the resolution of the framebuffer (and chose the initial display resolution) from the U-Boot command line.

setenv vidargs 'video=tegrafb0:1280x1024-16@60 video=tegrafb1:1680x1050-16@60'
saveenv
info

Should the use of vidargs be prohibited to you for whatever reason the kernel will fall back to using the default_mode string as hardcoded in resp. board panel file e.g for Colibri T20:

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/board-colibri_t20-panel.c?h=tegra#n252

Depending on your display, the kernel-provided modes might not work as expected. Also, some pixelclocks cannot be set very exactly due to hardware restrictions (especially on Tegra 2 based devices). Thus, different timings might lead to different results.

info

Should your display truly require custom timings then you may do so by modifying the source code here:

https://git.toradex.cn/cgit/linux-toradex.git/tree/drivers/video/tegra/dc/mode.c?h=tegra#n30

The additional letter M allows to calculate margins using the common timing formula, the letter R calculates reduced margins. If you experience problems with your display, those options might be worth a try. We tested several displays and can recommend the following settings:

Mode SpecifierDescription
640x480-16@60VGA, default mode, also for EDT 5.7" TFT VGA
800x480-16@60EDT 7.0" TFT WVGA
pixclockpol:0,800x480-16@60Capacitive Touch Display 7" Parallel
pixclockpol:0,800x480-16@60Fusion Multi-Touch Display 7"
pixclockpol:0,800x480-16@60Resistive Touch Display 7" Parallel
800x600M-16@60SVGA
1024x600-16@60Fusion Multi-Touch Display 10"
1024x768R-16@60XGA
1280x720M-16@60720p (HD)
1280x800-16@60Capacitive Touch Display 10.1" LVDS
1280x1024-16@60SXGA
1366x768-16@60
1600x1200-16@60UXGA
1680x1050-16@60
1920x1080-16@601080p (full HD)
1920x1200M-16@60

Note, however, on the DVI-D (aka HDMI) our BSP supports EDID. If a monitor provides EDID information, the framebuffer driver queries the monitor and selects an appropriate resolution. Also, the X-Server driver tegra later on queries EDID for the resolution list provided by XrandR, see X-Server).

For embedded LCD/TFT displays, additional parameters allow altering signal polarities. These configurations are only supported on Output 1:

DescriptionParameter NameValue 0Value 1
Pixelclock PolaritypixclockpolDisplay samples data on falling edgeDisplay samples data on the rising edge (default)
VSync PolarityvsyncActive low (default)Active high
HSync PolarityhsyncActive low (default)Active high
Data/Output EnableoutputenActive low (default)Active high

For example, the Fusion Multi-Touch Display 7" requires an inverted clock polarity:

setenv vidargs 'video=tegrafb0:pixclockpol:1,800x480@60'
saveenv

Framebuffer Bit/Colour Depth aka Bit Per Pixel (BPP)

By default, our BSPs are configured for 16 bpp being rather economic in terms of memory bandwidth and space occupation. However one can easily configure the framebuffer and X driver for 24/32 bpp as well.

info

The framebuffer and X driver configuration are two separate things.

Default 16 bpp
root@colibri-t30:~# cat /proc/cmdline 
core_edp_mv=1300 usb_high_speed=1 ip=off root=/dev/mmcblk0p2 rw,noatime rootfstype=ext3 rootwait asix_mac=00:14:2d:28:39:fe consoleblank=0 no_console_suspend=1 console=tty1 console=ttyS0,115200n8 debug_uartport=lsport,0 vmalloc=128M mem=1012M@2048M fbmem=12M@3060M video=tegrafb0:640x480-16@60

root@colibri-t30:~# fbset

mode "640x480-61"
# D: 25.176 MHz, H: 31.469 kHz, V: 60.987 Hz
geometry 640 480 640 960 16
timings 39721 48 16 33 1 96 2
rgba 5/11,6/5,5/0,0/0
endmode

root@colibri-t30:~# cat /var/log/Xorg.0.log | grep Depth
[4215611.541] (**) TEGRA(0): Depth 16, (--) framebuffer bpp 16
24 bpp

This actually sets up a 32 bit per pixel framebuffer.

root@colibri-t30:~# fw_setenv vidargs 'video=tegrafb0:640x480-24@60'

root@colibri-t30:~# mv /etc/X11/xorg.conf /etc/X11/xorg.conf.orig
root@colibri-t30:~# cat /etc/X11/xorg.conf.orig | sed 's/16/24/' > /etc/X11/xorg.conf

root@colibri-t30:~# cat /proc/cmdline
core_edp_mv=1300 usb_high_speed=1 ip=off root=/dev/mmcblk0p2 rw,noatime rootfstype=ext3 rootwait asix_mac=00:14:2d:28:39:fe consoleblank=0 no_console_suspend=1 console=tty1 console=ttyS0,115200n8 debug_uartport=lsport,0 vmalloc=128M mem=1012M@2048M fbmem=12M@3060M video=tegrafb0:640x480-24@60

root@colibri-t30:~# fbset

mode "640x480-61"
# D: 25.176 MHz, H: 31.469 kHz, V: 60.987 Hz
geometry 640 480 640 960 32
timings 39721 48 16 33 1 96 2
rgba 8/0,8/8,8/16,8/24
endmode

root@colibri-t30:~# cat /var/log/Xorg.0.log | grep Depth
[4220070.472] (**) TEGRA(0): Depth 24, (--) framebuffer bpp 32
[4220070.487] (--) Depth 24 pixmap format is 32 bpp
32 bpp

From a framebuffer perspective 24 and 32 bpp are actually the same:

root@colibri-t30:~# fw_setenv vidargs 'video=tegrafb0:640x480-32@60'

root@colibri-t30:~# cat /proc/cmdline
core_edp_mv=1300 usb_high_speed=1 ip=off root=/dev/mmcblk0p2 rw,noatime rootfstype=ext3 rootwait asix_mac=00:14:2d:28:39:fe consoleblank=0 no_console_suspend=1 console=tty1 console=ttyS0,115200n8 debug_uartport=lsport,0 vmalloc=128M mem=1012M@2048M fbmem=12M@3060M video=tegrafb0:640x480-32@60

root@colibri-t30:~# fbset

mode "640x480-61"
# D: 25.176 MHz, H: 31.469 kHz, V: 60.987 Hz
geometry 640 480 640 960 32
timings 39721 48 16 33 1 96 2
rgba 8/0,8/8,8/16,8/24
endmode

However, on the X driver side of things, this is not the case and the X driver refuses to load with the following error message:

root@colibri-t30:~# mv /etc/X11/xorg.conf /etc/X11/xorg.conf.orig
root@colibri-t30:~# cat /etc/X11/xorg.conf.orig | sed 's/16/32/' > /etc/X11/xorg.conf

root@colibri-t30:~# systemctl restart lxdm

root@colibri-t30:~# cat /var/log/Xorg.0.log | grep -i depth
"Common Screen" for depth/fbbpp 32/32
[4220292.352] (EE) TEGRA(0): Given depth (32) is not supported by this driver
info

Above settings are purely about the internal color representation of the framebuffer and have nothing to do with how any of this ends up on the actual external display interface signals which are rather a display controller output configuration and pin muxing thematic.

Given the Apalis Standard defaulting to a 24-bit display interface the Apalis T30 defaults to that. However, the Colibri Standard defaults to an 18-bit display interface, and the Colibri T20 and Colibri T30, therefore, require changing this configuration if desired:

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/board-apalis_t30-panel.c?h=tegra#n248

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/board-colibri_t20-panel.c?h=tegra#n245

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/board-colibri_t30-panel.c?h=tegra#n249

The Tegras are hardcoded in their resp. board pinmux files for 24 bit parallel RGB interfaces:

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/board-apalis_t30-pinmux.c?h=tegra#n315

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/board-colibri_t20-pinmux.c?h=tegra#n99

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/board-colibri_t20-pinmux.c?h=tegra#n229

https://git.toradex.cn/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/board-colibri_t30-pinmux.c?h=tegra#n405

Tegra Framebuffer Configuration at Runtime

The fbset is able to change display timings at runtime, however running X-Server on top of the framebuffer will not be able to cope with such changes.

Currently, we do advise to not use fbset.

Apalis T30 LVDS Transceiver Configuration

The Apalis T30 module comes with a flexible THine THC63LVD827 LVDS transceiver which can be configured via GPIOs:

root@apalis-t30:~# cat /sys/kernel/debug/gpio | grep LVDS
gpio-216 (LVDS: Single/Dual Ch) out lo
gpio-219 (LVDS: 18/24 Bit Mode) out hi
gpio-220 (LVDS: Output Enable ) out hi
gpio-221 (LVDS: Power Down ) out hi
gpio-222 (LVDS: Clock Polarity) out hi
gpio-223 (LVDS: Colour Mapping) out hi
gpio-225 (LVDS: Swing Mode ) out hi
gpio-226 (LVDS: DDRclk Disable) out hi

Our BSP comes with three scripts that can be used for that configuration:

/usr/bin/lvds-single-channel-24bit-mode2.sh
/usr/bin/lvds-single-channel.sh
/usr/bin/lvds-dual-channel.sh
info

The single-channel 24-bit mode2 one is applicable for our Capacitive Touch Display 10.1" LVDS.

To have this automatically configured upon boot one of the scripts can be put into the LXDE autostart as explained here:

https://developer.toradex.cn/knowledge-base/how-to-autorun-application-at-the-start-up-in-linux#lxsession-autostart-file

Tegra Framebuffer Boot Configuration (up to BSP V2.1Beta1)

Should you need to change the resolution/timing of the parallel RGB display controller/interface you have to:

a) Modify the Kernel Sources:

In the arch/arm/mach-tegra/board-colibri_t20-panel.c file:

  • colibri_t20_panel_modes[]

    • The first entry in that array defines the used timings.
    • Note: arch/arm/mach-tegra/board-colibri_t20.h defines TEGRA_FB_VGA by default.
    • A number of standard resolutions to choose from are already provided.
  • colibri_t20_fb_data

    • Adjust the resolution.
    • Adjust the colour depth (bits_per_pixel).
  • colibri_t20_dc_out_pins[]

    • You might require different H_SYNC, V_SYNC polarities.

b) Re-compile the Kernel:

Kernel compilation is explained in the following article:

Build U-Boot and Linux Kernel from Source Code

info

The display mode has to be defined within the kernel, "xrandr --newmode" does not work.

Vybrid based modules

Vybrids display controller (DCU, Display Control Unit) supports only one output. Depending on the BSP version, the Linux kernel uses a different driver for the display controller.

  • fbdev driver: BSP Version 2.5 and earlier (BSP with Linux kernel 4.1 and older)
  • DRM driver: BSP Version 2.6 and later (BSP with Linux kernel 4.4 and newer)

fbdev driver

DescriptionOutput 1
Framebuffer boot namedcufb
Framebuffer device/dev/fb0
X-Server driverfbdev
X-Server output namedefault
Connector on EvalBoardLVDS/RGB/VGA
Connector on IrisDVI-A
Supports EDID (Software)No

Display Mode Boot Configuration

Beginning with BSP V2.1 Beta 3 release in March 2014 our BSP supports the configuration of framebuffer resolution from the kernel command line using the kernel internal modedb.

The framebuffer driver registers one boot driver named dcufb to set resolutions using kernel parameters.

setenv vidargs 'video=dcufb:1024x600-16@60'
saveenv

For embedded LCD/TFT displays, additional parameters allow altering signal polarities.

DescriptionParameter NameValue 0Value 1
Pixelclock PolaritypixclockpolDisplay samples data on falling edgeDisplay samples data on the rising edge (default)
VSync PolarityvsyncActive low (default)Active high
HSync PolarityhsyncActive low (default)Active high

The Vybrid DCU driver not only allows selecting the kernel internal modes from the table of modedb.c but also the modes specified in the device tree. This is helpful if multiple modes are specified in the device tree. For instance, the standard device tree carrier board file arch/arm/boot/dts/vf-colibri-eval-v3.dtsi has a set of display specifications for the displays available through the Toradex webshop. One can use the kernel parameters to select one of them:

Mode SpecifierDescription
640x480-16@60VGA, default mode, also for EDT 5.7" TFT VGA
800x480-16@60EDT 7.0" TFT WVGA
pixclockpol:0,800x480-16@60Fusion Multi-Touch Display 7"
800x600-16@60SVGA
1024x600-16@60Fusion Multi-Touch Display 10"
1024x768-16@60XGA

To support a specific display we recommend using the device tree to specify the exact display resolution and timings while also specifying the native-mode property. See the carrier board device tree file arch/arm/boot/dts/vf-colibri-eval-v3.dtsi:

...
display: display@0 {
bits-per-pixel = <16>;
display-timings {
native-mode = <timing_vga>;
/* Standard VGA timing */
timing_vga: 640x480 {
clock-frequency = <25175000>;
hactive = <640>;
vactive = <480>;
hback-porch = <40>;
hfront-porch = <24>;
vback-porch = <32>;
vfront-porch = <11>;
hsync-len = <96>;
vsync-len = <2>;
hsync-active = <0>;
vsync-active = <0>;
pixelclk-active = <0>;
};
};
};
...

Make sure to clear the U-Boot's vidargs display specification, since settings supplied through the kernels command line parameters take precedence over the device tree specifications. For more information on how to alter the device tree, refer to the Device Tree Customization article.

info

At XGA resolution (1024x768), the only 16-bit color depth is supported. Higher color depth leads to flickering issues likely due to memory bandwidth limitations.

Multiple Layers and Alpha Blending

How to Use multiple layers and alpha blending on Vybrid's display controller is explained in the following article.

Synchronise Page Flip on Vertical Blanking Period

Screen tearing is an effect that appears when the frame is updated while it is scanned out to the display. This results in a horizontal break where the upper half shows the old frame and the lower half the new frame. A method to avoid screen tearing is using two buffers aka double buffering and synchronize the swapping (page flip) of them to the vertical blanking period (V-sync).

When using the Linux kernels fbdev subsystem this is usually realized by doubling the vertical screen size and panning the scanned out screen between the left half and the right half of the framebuffer. The userspace application needs to make sure not to alter the framebuffer which is currently scanned out. The framebuffer subsystem provides two ioctls to achieve this, FBIOPAN_DISPLAY to the pan (page flip) and FBIO_WAITFORVSYNC to wait until the next vertical blanking period starts.

Note that the panning operation is not executed immediately. The Vybrid's display controller DCU implements a mechanism that makes sure that all configuration changes are synchronized to vertical blanking periods, including the new framebuffer pointer offset (panning). Hence after issuing the ioctl FBIOPAN_DISPLAY requesting the pan to the second framebuffer the first framebuffer could still be scanning out at that time. To make sure the first framebuffer is not scanned out anymore use FBIO_WAITFORVSYNC to wait for the next vertical blanking period. At that point, it is safe to update the first framebuffer. The small test utility fb-test.c illustrates this approach and can be used to test vertical synchronization.

info

The ioctl FBIO_WAITFORVSYNC is available in images after V2.4 Beta 1.

DRM driver

DescriptionOutput 1
KMS output nameLVDS-1
Framebuffer device/dev/fb0
X-Server drivermodesetting
X-Server output nameLVDS-0*
Connector on EvalBoardLVDS/RGB/VGA
Connector on IrisDVI-A
Supports EDID (Software)No
  • The inconsistency with the KMS output name will be addressed with the next X-Server release (see this mailing list post).

Display Mode Boot Configuration

The DRM driver uses the display mode/timings provided by the associated panel driver in the device tree. Most panels are part of the panel-simple driver, displays supported by the panel-simple can be selected by using the respective compatible string. Toradex displays are supported by the following compatible strings:

Compatible StringDescription
edt,et057090dhuDefault mode, EDT 5.7" TFT VGA
edt,et070080dh6EDT 7.0" TFT WVGA
logic,lt161010-2nhcCapacitive Touch Display 7" Parallel
logic,lt161010-2nhcResistive Touch Display 7" Parallel
tpk,f07a-0102Fusion Multi-Touch Display 7"
tpk,f10a-0102Fusion Multi-Touch Display 10"
info

The compatible strings for Fusion displays are available in BSP after V2.6 Beta 1.

To change the display mode/timings permanently, use the compatible string of your display in the carrier board level device tree to specify the connected display (see Device Tree Customization). To select a certain compatible string temporarily, the U-Boot environment fdt_fixup can be used:

Colibri VFxx # setenv fdt_fixup 'fdt addr ${fdt_addr_r} && fdt resize && fdt set /panel compatible "tpk,f07a-0102"'
Colibri VFxx # saveenv

If your display is missing in the list, you can add a new entry in the drivers' source file (drivers/gpu/drm/panel/panel-simple.c). Make sure to use an appropriate compatible string.

To set specific display timing, the video kernel parameter can be used. The syntax is similar to the fbdev kernel parameter syntax, however, timings always get calculated using timing formulas (CVT or GTF).

setenv vidargs 'video=LVDS-1:1024x600M-16@60'
saveenv

The kernel will always select the "best" display timings, which is the higher resolution. Therefore, if a resolution below the currently selected panel (by default VGA) is specified, the output will still be VGA. One can use XrandR to select the lower resolution. To permanently configure a certain display timing, using the panel-simple driver is the recommended approach.

VSync and HSync are selected based on the rules of the formulas (CVT/GTF). There is no option to chose the pixel clock polarity using a kernel parameter. Use the panel-simple driver to specify those options explicitly.

Background about the reasons why display timings should not be part of the device tree can be found in Thierry Reding's blog post Display panels are not special.

Colour depth of framebuffer device

The DRM driver supports emulation for the fbdev display interface (CONFIG_DRM_FBDEV_EMULATION). The mode is "inherited" from the DRM/KMS driver and cannot be changed using the fbdev device (e.g. fbset does not work). The default depth is 24 bit with a standard RGB 8:8:8 pixel format (24 bits per pixel). Releases after V2.6.1 Beta 1 have a new kernel parameter to change the fbdev depth: E.g. fsl_dcu_drm.legacyfb_depth=16 can be used to configure the fbdev framebuffer to use RGB 5:6:5 (16 bits per pixel).

Add Modes at Runtime using XrandR

The package xserver-xorg comes with the cvt utility which allows calculating display timings according to the VESA CVT formula (Coordinated Video Timing).

cvt 800 480 60
# 800x480 59.48 Hz (CVT) hsync: 29.74 kHz; pclk: 29.50 MHz
Modeline "800x480_60.00" 29.50 800 824 896 992 480 483 493 500 -hsync +vsync

Copy the string after "Modeline" and use XrandR to create a new mode

xrandr --newmode "800x480_60.00"   29.50  800 824 896 992  480 483 493 500 -hsync +vsync
xrandr --addmode LVDS-0 800x480_60.00
xrandr --output LVDS-0 --mode 800x480_60.00

Alternative Pixel Clock Source

By default, the pixel clock is generated from PLL1_PFD2, which has a base clock of 452 MHz. A single divider breaks down the clock to the actual pixel clock. Depending on the requested pixel clock, the divided clock might not be accurate enough. As an alternative clock source PLL3 can be chosen, which provides a base clock of 480 MHz. To select PLL3 as a base clock, use the following device tree properties in the nfc node:

assigned-clocks = <clks VF610_CLK_DCU0_SEL>;
assigned-clock-parents = <clks VF610_CLK_PLL3_USB_OTG>;


Send Feedback!