Add parallel RGB panel for TechNexion i.MX6 product

Difficulty Levels: Intermediate
Date added: December 19, 2018

1. LCD panel technologies

Each LCD segment only gates reflected or generated light
– Color filters allow generation of specific colors (RGB) at a segment
– To generate a real world color, 3 segments are needed – these 3 segments individually pass light through a red, green, and blue filter to make a group of segments, or a RGB pixel
– For a 320×240 RGB LCD display, there are actually 320*3=960 segments (columns) and 240 rows

1.1 LCD signals and timing

LCDs require the following basic timing signals:
– VSYNC (Vertical Sync for TFT) or FP (Frame Pulse for STN)
• Used to reset the LCD row pointer to top of the display
– HSYNC (Horizontal sync for TFT) or LP (Line Pulse for STN)
• Used to reset the LCD column pointer to the edge of the display
– D0..dXX (1 or more data lines)
• Data line function varies in STN and TFT modes and panel type
– LCDCLK (LCD clock)
• Used to panel control refresh rate

  • Horizontal Back Porch(HBP): Number of pixel clk pulses between HSYNC signal and the first valid pixel data.
  • Horizontal Front porch(HFP): Number of pixel clk pulses between the last valid pixel data in the line and the next hsync pulse.
  • Vertical back porch(VBP): Number of lines (HSYNC pulses) from a VSYNC signal to the first valid line.
  • Vertical Front Porch(VFP): Number of lines (HSYNC pulses) between the last valid line of the frame and the next VSYNC pulse.
  • VSYNC pulse width: Number of HSYNC pulses when a VSYNC signal is active.
  • HSYNC pulse width: Number of pixel clk pulses when a HSYNC signal is active.
  • Active frame width: Horizontal resolution.
  • Active frame height: Vertical resolution.
  • Screen width: Number of pixel clk between the last HSYNC and the new HSYNC. Screen width = Active frame width + HBP + HFP
  • Screen height: Number of lines between VSYNC pulses. Screen Height = Active frame height + VBP + VFP
  • VSYNC polarity: Value of VSYNC to indicate the start of a new frame (active LOW or HIGH)
  • HSYNC polarity: Value of HSYNC to indicate the start of a new line (active LOW or HIGH).

2. Display system in NXP i.MX6

The NXP i.MX6 Solo / DualLite implements a robust muxing logic on the two display ports (2x per IPU), to the external interfaces, either direct, or via bridges (MIPI, LVDS, HDMI), per description below:
• Two parallel – driven directly by IPU; pixel clock at least up to 200 MHz (for
external load of up to 10 pF).
• Parallel interface works up to 200 MHz
• HDMI interface works up to 270 MHz
• Two LVDS channels, driven by the LDB; pixel clock up to 170 MHz.
• One HDMI port (ver. 1.4) – driven by the HDMI transmitter: pixel clock up to 270MHz (gated by the IPU capabilities)
• One MIPI/DSI port – driven by the MIPI/DSI transmitter; 2 data lanes at 1 GHz
• IPU display port (DI) can be connected to each of the above ports

3. Change software settings to add new parallel RGB panel support

3.1 Add panel support in u-boot for boot splash screen

Here, we take u-boot 2017.03 for pico-imx6 as an example:

3.1.1 Fill in the timing parameters of panel

The array of display defines the displays that are supported.
In PICO-IMX6 board file (board/technexion/pico-imx6/pico-imx6.c):

struct display_info_t const displays[] = {{
	.bus	= 1,
	.addr	= 0x38,
	.pixfmt	= IPU_PIX_FMT_RGB24,
	.detect	= detect_i2c,
	.enable	= enable_ft5x06_wvga,
	.mode	= {
		.name           = "FT5x06-WVGA",
		.refresh        = 60,
		.xres           = 800,
		.yres           = 480,
		.pixclock       = 30303,  //unit: pico second
		.left_margin    = 45,
		.right_margin   = 210,
		.upper_margin   = 22,
		.lower_margin   = 22,
		.hsync_len      = 1,
		.vsync_len      = 1,
		.sync           = 0,
		.vmode          = FB_VMODE_NONINTERLACED

Here, we demonstrate how to add support for INONOLUX display – EJ050NA:

  • xres: Number of horizontal pixels, resolution in the x axis.
  • yres: Number of vertical lines or pixels, resolution in the y axis.
  • pixclock: Pixel clock, dot clock or just clock, usually in MHz. It needs to be entered in picoseconds (pixclock in ps= 10 ^(-12) / dot-clock in MHz)
  • left margin: This is Horizontal Back Porch (HBP).
  • right margin: This is Horizontal Front porch (HFP).
  • upper margin: This is Vertical back porch (VBP).
  • lower margin: This is Vertical Front Porch (VFP).
  • hsync length: This is HSYNC pulse width.
  • vsync length: This is VSYNC pulse width.
  • sync: This refers to the clock polarity.
  • vmode: This is the video mode. FB_VMODE_INTERLACED, FB_VMODE_NONINTERLACED etc.

Figure out corresponding values from panel datasheet , then fill them in the struct – “display_info_t”.
In u-boot, the unit for “pixclock” is “ps”.
So, we need to calculate it from “DCLK frequency” listed in panel datasheet:
pixclock = 1012 / (33.3 MHz) = 30030 ps
The function “enable_ft5x06_wvga” implements the control of GPIO to activate LCD_enable pins and manipulate PWM as GPIO to enable backlight.
The function “detect_i2c” defines the behavior to detect panel. If you only use one panel for output, we suggest to take it out to force to output to a specific panel.

3.2 Add panel support in linux kernel

The NXP MXC graphics driver uses:
LCD for parallel LCD displays (./drivers/video/fbdev/mxc/mxc_lcdif.c)

static struct fb_videomode lcdif_modedb[] = {
	/* 800x480 @ 57 Hz , pixel clk @ 27MHz */
	"CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10,
	/* 800x480 @ 60 Hz , pixel clk @ 32MHz */
	"SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,

Add additional a custom mode in lcdif_modedb. (The elements are listed below.)

struct fb_videomode {
	const char *name;	/* optional */
	u32 refresh;		/* optional */
	u32 xres;
	u32 yres;
	u32 pixclock;
	u32 left_margin;
	u32 right_margin;
	u32 upper_margin;
	u32 lower_margin;
	u32 hsync_len;
	u32 vsync_len;
	u32 sync;
	u32 vmode;
	u32 flag;

Modify the frame buffer settings in device tree:

	mxcfb3: fb@2 {
		compatible = "fsl,mxc_sdc_fb";
		disp_dev = "lcd";
		interface_pix_fmt = "RGB565";
		mode_str ="CLAA-WVGA";
		default_bpp = <16>;
		int_clk = <0>;
		late_init = <0>;
		status = "disabled";

Change boot argument in the uEnv.txt to specify the modedb.
The uEnv.txt is under the first FAT partition of storage (eMMC/SD).

displayinfo=video=mxcfb0:dev=lcd,CLAA-WVGA ,if=RGB565

Stay up to date with all the latest TechNexion news...

Sign-up for our Newsletter