Per customer's request, we demonstrated four-screen display on MX6Q ARM2 board, the following table is
customer's requirements.
video stream UI output resolution
Disp0(LVDS0) 720P 3D@60fps LDB_XGA(1024x768)
Disp1(LVDS1) none 2D LDB_XGA(1024x768)
Disp2(LCD) none 2D CLAA_WVGA(800x480)
Disp3(HDMI) 1080P 3D@30fps 1080P(1920x1080)
Here are steps to config multi-display
1. Hardware environment
MX6Q ARM2 board
TV set with HDMI port
Two LVDS panel
One LCD panel
2, Linux Release packages
L3.0.15_12.05.01_ER_source.tar.gz
fsl-mm-codeclib-2.0.9.tar.gz
gst-fsl-plugin-2.0.9.tar.gz
3. Software configuration
3.1 Frame buffer allocation
Video and UI will be blended on hdmi and lvds0, it is processed in DP. For lvds1 and lcd, the data goes through DC.
Configuration in arch/arm/mach-mx6/board-mx6q_arm2.c:
static struct ipuv3_fb_platform_data sabr_fb_data[] = {
{ /*fb0*/
.disp_dev = "ldb",
.interface_pix_fmt = IPU_PIX_FMT_RGB666,
.mode_str = "LDB-XGA",
.default_bpp = 32,
.int_clk = false,
}, {
.disp_dev = "ldb",
.interface_pix_fmt = IPU_PIX_FMT_RGB666,
.mode_str = "LDB-XGA",
.default_bpp = 16,
.int_clk = false,
}, {
.disp_dev = "hdmi",
.interface_pix_fmt = IPU_PIX_FMT_RGB24,
.mode_str = "1920x1080M@60",
.default_bpp = 32,
.int_clk = false,
}, {
.disp_dev = "lcd",
.interface_pix_fmt = IPU_PIX_FMT_RGB565,
.mode_str = "CLAA-WVGA",
.default_bpp = 16,
.int_clk = false,
}
};
static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = {
.ipu_id = 0,
.disp_id = 1,
};
static struct fsl_mxc_lcd_platform_data lcdif_data = {
.ipu_id = 0,
.disp_id = 0,
.default_ifmt = IPU_PIX_FMT_RGB565,
};
static struct fsl_mxc_ldb_platform_data ldb_data = {
.ipu_id = 1,
.disp_id = 0,
.ext_ref = 1,
.mode = LDB_SEP0,
.sec_ipu_id = 1,
.sec_disp_id = 1,
};
It results in frame buffer allocation as below:
+--------> IPU1 DP-BG : /dev/fb0 <----> /dev/video16
LVDS0 -------+
+--------> IPU1 DP-FG : /dev/fb1 <-----> /dev/video17
LVDS1 --------> IPU1 DC : /dev/fb2 <-----> /dev/video18
+--------> IPU0 DP-BG : /dev/fb3 <----> /dev/video19
HDMI -------+
+--------> IPU0 DP-FG : /dev/fb4 <-----> /dev/video20
LCD --------> IPU0 DC : /dev/fb5 <-----> /dev/video21
3.2 3D on video overlay
3D UI is blended on video, so it goes through DP-FG, and video goes through DP-BG. In 3D sample code,
fbGetDisplay() is used to get default display. In order to show 3D to different display,fbGetDisplayByIndex(index) should be used, here index 0 for fb0, index 1 for fb1, index 2 for fb2, index3 for fb3, index 4 for fb4, index 5 for fb5.
For 3D on LVDS0, use fbGetDisplayByIndex(1);
For 3D on HDMI, use fbGetDisplayByIndex(4);
3.3 3D UI frame rate
To fix 3D UI frame rate at 30 or 60, sample code should be changed as it runs as fast as possible by default.
cube
Attached cube could be used for test, with which fb and framerate can be set, it is used like this.
insmod /lib/modules/3.0.15-1453-g5ac8a7a/kernel/drivers/mxc/gpu-viv/galcore.ko;
./cube fb=* framerate=*
fb can be 0,1,2,3,4,5.
3.4 Alpha in pixel process
ARGB format image can be overlayed with alpha in pixel, and fb should be configed as below.
int fd;
struct fb_var_screeninfo fbvar;
fd = open("/dev/fb1", O_RDWR);
if (ioctl(fd, FBIOGET_VSCREENINFO, &fbvar) < 0)
{
printf("error ioctl\n");
return -1;
}
fbvar.bits_per_pixel = 32;
fbvar.xres = 1024;
fbvar.yres = 768;
fbvar.nonstd = v4l2_fourcc('B', 'G', 'R', 'A');
fbvar.transp.offset = 24;
fbvar.transp.length = 8;
fbvar.red.offset = 16;
fbvar.red.length = 8;
fbvar.green.offset = 8;
fbvar.green.length = 8;
fbvar.blue.offset = 0;
fbvar.blue.length = 8;
fbvar.activate = FB_ACTIVATE_FORCE;
if (ioctl(fd, FBIOPUT_VSCREENINFO, &fbvar) < 0)
{
printf("error ioctl\n");
return -1;
}
struct mxcfb_gbl_alpha ga;
ga.enable = 0;
ioctl(fd, MXCFB_SET_GBL_ALPHA, &ga);
struct mxcfb_loc_alpha la;
la.enable = 1;
la.alpha_in_pixel = 1;
ioctl(fd, MXCFB_SET_LOC_ALPHA, &la);
ioctl(fd, FBIOBLANK, FB_BLANK_UNBLANK);
close(fd);
4. Script to run multi-display
#!/bin/bash
# HDMI
gst-launch filesrc location=/unit_tests/1080P.mov typefind=true ! aiurdemux name=demux demux. ! queue
max-size-buffers=0 max-size-time=0 ! vpudec ! mfw_v4lsink device="/dev/video19" disp-width=1920 disp-
height=1080 demux. ! queue max-size-buffers=0 max-size-time=0 ! beepdec ! audioconvert ! 'audio/x-raw-
int, channels=2' ! alsasink &
sleep 8
insmod /lib/modules/3.0.15-1453-g5ac8a7a/kernel/drivers/mxc/gpu-viv/galcore.ko ; /cube2/cube &
# LVDS0
gst-launch filesrc location=/unit_tests/720P.mp4 typefind=true ! aiurdemux name=demux demux. ! queue max
-size-buffers=0 max-size-time=0 ! vpudec ! mfw_v4lsink device="/dev/video16" demux. ! queue max-size-
buffers=0 max-size-time=0 ! beepdec ! audioconvert ! 'audio/x-raw-int, channels=2' ! alsasink &
sleep 5
cd /cube1 ; ./cube &
# LVDS1
cd /unit_tests ; cat ui_test.bmp > /dev/fb2
# LCD
cd /unit_tests ; cat test.bmp > /dev/fb5