diff --git a/arch/arm/include/asm/mach-imx/fbpanel.h b/arch/arm/include/asm/mach-imx/fbpanel.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5465c3c8033061bf5c7d287b5c65985d7e2e165
--- /dev/null
+++ b/arch/arm/include/asm/mach-imx/fbpanel.h
@@ -0,0 +1,1170 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __IMX_VIDEO_H_
+#define __IMX_VIDEO_H_
+
+#include <linux/fb.h>
+#include <ipu_pixfmt.h>
+
+struct display_info_t {
+	int	bus;	/* (bus >> 8) is gpio to enable bus if <>0 */
+	int	addr;
+	int	pixfmt;
+	int	(*detect)(struct display_info_t const *dev);
+	void	(*enable)(struct display_info_t const *dev, int enable);
+	void	(*pre_enable)(struct display_info_t const *dev);
+	int	pwm_period;
+#define FB_HDMI		0
+#define FB_LCD		1
+#define FB_LCD2		2
+#define FB_LVDS		3
+#define FB_LVDS2	4
+#define FB_COUNT	5
+	int	fbtype;
+
+#define FBF_MODESTR	1
+#define FBF_JEIDA	2
+#define FBF_SPLITMODE	4
+#define FBF_SPI		8
+#define FBF_BKLIT_LOW_ACTIVE	0x10
+#define FBF_BKLIT_DTB		0x20
+	int	fbflags;
+	struct	fb_videomode mode;
+};
+int ipu_set_ldb_clock(int rate);
+
+void board_enable_hdmi(const struct display_info_t *di, int enable);
+void board_enable_lcd(const struct display_info_t *di, int enable);
+void board_enable_lvds(const struct display_info_t *di, int enable);
+void board_enable_lvds2(const struct display_info_t *di, int enable);
+
+void fbp_enable_fb(struct display_info_t const *di, int enable);
+int fbp_detect_i2c(struct display_info_t const *di);
+void fbp_setup_display(const struct display_info_t *displays, int cnt);
+
+#define VD_1280_720M_60(_mode, _detect, _bus, _addr)	VDF_1280_720M_60(_mode, "1280x720M@60", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_1920_1080M_60(_mode, _detect, _bus, _addr)	VDF_1920_1080M_60(_mode, "1920x1080M@60", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_1024_768M_60(_mode, _detect, _bus, _addr)	VDF_1024_768M_60(_mode, "1024x768M@60", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_800_600MR_60(_mode, _detect, _bus, _addr)	VDF_800_600MR_60(_mode, "800x600MR@60", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_640_480M_60(_mode, _detect, _bus, _addr)	VDF_640_480M_60(_mode, "640x480M@60", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_720_480M_60(_mode, _detect, _bus, _addr)	VDF_720_480M_60(_mode, "720x480M@60", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_CLAA_WVGA(_mode, _detect, _bus, _addr)	VDF_CLAA_WVGA(_mode, "CLAA-WVGA", RGB666, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_SHARP_WVGA(_mode, _detect, _bus, _addr)	VDF_SHARP_WVGA(_mode, "sharp-wvga", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_TFC_A9700LTWV35TC_C1(_mode, _detect, _bus, _addr)	VDF_TFC_A9700LTWV35TC_C1(_mode, "tfc-a9700ltwv35tc-c1", RGB24, 0, _detect, _bus, _addr)
+#define VD_800X300_565(_mode, _detect, _bus, _addr)	VDF_800X300(_mode, "800x300rgb565", RGB565, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_HITACHI_HVGA(_mode, _detect, _bus, _addr)	VDF_HITACHI_HVGA(_mode, "hitachi_hvga", RGB666, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_HITACHI_HVGA565(_mode, _detect, _bus, _addr)	VDF_HITACHI_HVGA(_mode, "hitachi_hvga565", RGB565, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_NEON_TOUCH640X240(_mode, _detect, _bus, _addr) VDF_NEON_TOUCH640X240(_mode, "NeonTouch640x240", RGB565, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_DC050WX(_mode, _detect, _bus, _addr)		VDF_DC050WX(_mode, "DC050WX", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_INNOLUX_WXGA_14IN_12V(_mode, _detect, _bus, _addr) VDF_INNOLUX_WXGA_14IN_12V(_mode, "INNOLUX-WXGA-IN14-12V", RGB666, 0, _detect, _bus, _addr)
+#define VD_AUO_WXGA_11IN_12V(_mode, _detect, _bus, _addr) VDF_AUO_WXGA_11IN_12V(_mode, "AUO-WXGA-IN11-12V", RGB24, 0, _detect, _bus, _addr)
+#define VD_OSD_WSVGA(_mode, _detect, _bus, _addr)	VDF_OSD_WSVGA(_mode, "OSD-WSVGA", RGB666, 0, _detect, _bus, _addr)
+#define VD_INNOLUX_WVGA(_mode, _detect, _bus, _addr)	VDF_INNOLUX_WVGA(_mode, "INNOLUX-WVGA", RGB666, 0, _detect, _bus, _addr)
+#define VD_INNOLUX_WVGA_12V(_mode, _detect, _bus, _addr) VDF_INNOLUX_WVGA(_mode, "INNOLUX-WVGA-12V", RGB666, 0, _detect, _bus, _addr)
+#define VD_INNOLUX_WVGA_M(_mode, _detect, _bus, _addr)	VDF_INNOLUX_WVGA(_mode, "INNOLUX-WVGA", RGB666, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_OKAYA_480_272(_mode, _detect, _bus, _addr)	VDF_OKAYA_480_272(_mode, "okaya_480x272", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_QVGA(_mode, _detect, _bus, _addr)		VDF_QVGA(_mode, "qvga", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_AT035GT_07ET3(_mode, _detect, _bus, _addr)	VDF_AT035GT_07ET3(_mode, "AT035GT-07ET3", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_AMP1024_600(_mode, _detect, _bus, _addr)	VDF_AMP1024_600(_mode, "amp1024x600", RGB666, 0, _detect, _bus, _addr)
+#define VD_ND1024_600(_mode, _detect, _bus, _addr)	VDF_ND1024_600(_mode, "ND-070PCAP-1024x600", RGB24, 0, _detect, _bus, _addr)
+#define VD_TM070JDHG30(_mode, _detect, _bus, _addr)	VDF_TM070JDHG30(_mode, "tm070jdhg30", RGB24, 0, _detect, _bus, _addr)
+#define VD_AUO_B101EW05(_mode, _detect, _bus, _addr)	VDF_AUO_B101EW05(_mode, "auo_b101ew05", RGB666, 0, _detect, _bus, _addr)
+#define VD_HANNSTAR7(_mode, _detect, _bus, _addr)	VDF_HANNSTAR7(_mode, "hannstar7", RGB666, 0, _detect, _bus, _addr)
+#define VD_LG1280_800(_mode, _detect, _bus, _addr)	VDF_HANNSTAR7(_mode, "lg1280x800", RGB666, 0, _detect, _bus, _addr)
+#define VD_M101NWWB(_mode, _detect, _bus, _addr)	VDF_HANNSTAR7(_mode, "M101NWWB", RGB24, 0, _detect, _bus, _addr)
+#define VD_LD101WX1(_mode, _detect, _bus, _addr)	VDF_HANNSTAR7(_mode, "ld101wx1", RGB24, 0, _detect, _bus, _addr)
+#define VD_DT070BTFT(_mode, _detect, _bus, _addr)	VDF_DT070BTFT(_mode, "dt070btft", RGB24, FBF_JEIDA, _detect, _bus, _addr)
+#define VD_WSVGA(_mode, _detect, _bus, _addr)		VDF_WSVGA(_mode, "wsvga", RGB666, 0, _detect, _bus, _addr)
+#define VD_ASIT500MA6F5D(_mode, _detect, _bus, _addr)	VDF_ASIT500MA6F5D(_mode, "ASIT500MA6F5D", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_FUSION7(_mode, _detect, _bus, _addr)		VDF_FUSION7(_mode, "fusion7", RGB666, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_HANNSTAR(_mode, _detect, _bus, _addr)	VDF_HANNSTAR(_mode, "hannstar", RGB666, 0, _detect, _bus, _addr)
+#define VD_1024_600(_mode, _detect, _bus, _addr)	VDF_1024_600(_mode, "1024x600", RGB666, 0, _detect, _bus, _addr)
+#define VD_AFK1024600A02(_mode, _detect, _bus, _addr)	VDF_AFK1024600A02(_mode, "AFK1024600A02", RGB24, 0, _detect, _bus, _addr)
+#define VD_LG9_7(_mode, _detect, _bus, _addr)		VDF_LG9_7(_mode, "lg9.7", RGB666, 0, _detect, _bus, _addr)
+#define VD_1080P60(_mode, _detect, _bus, _addr)		VDF_1080P60(_mode, "1080P60", RGB24, FBF_SPLITMODE, _detect, _bus, _addr)
+#define VD_1080P60_J(_mode, _detect, _bus, _addr)	VDF_1080P60(_mode, "1080P60_J", RGB24, FBF_SPLITMODE | FBF_JEIDA, _detect, _bus, _addr)
+#define VD_DV210FBM(_mode, _detect, _bus, _addr)	VDF_DV210FBM(_mode, "dv210fbm", RGB24, FBF_SPLITMODE, _detect, _bus, _addr)
+#define VD_SHARP_LQ101K1LY04(_mode, _detect, _bus, _addr) VDF_SHARP_LQ101K1LY04(_mode, "sharp-LQ101K1LY04", RGB24, FBF_JEIDA, _detect, _bus, _addr)
+#define VD_WXGA(_mode, _detect, _bus, _addr)		VDF_WXGA(_mode, "wxga", RGB24, 0, _detect, _bus, _addr)
+#define VD_WXGA_J(_mode, _detect, _bus, _addr)		VDF_WXGA(_mode, "wxga_j", RGB24, FBF_JEIDA, _detect, _bus, _addr)
+#define VD_LD070WSVGA(_mode, _detect, _bus, _addr)	VDF_LD070WSVGA(_mode, "ld070wsvga", RGB24, 0, _detect, _bus, _addr)
+#define VD_SVGA(_mode, _detect, _bus, _addr)		VDF_SVGA(_mode, "svga", RGB666, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_WVGA_TX23D200_24(_mode, _detect, _bus, _addr) VDF_WVGA_TX23D200(_mode, "tx23d200_24", RGB24, 0, _detect, _bus, _addr)
+#define VD_WVGA_TX23D200_24H(_mode, _detect, _bus, _addr) VDF_WVGA_TX23D200(_mode, "tx23d200_24h", RGB24, FBF_BKLIT_DTB, _detect, _bus, _addr)
+#define VD_WVGA_TX23D200_24L(_mode, _detect, _bus, _addr) VDF_WVGA_TX23D200(_mode, "tx23d200_24l", RGB24, FBF_BKLIT_DTB | FBF_BKLIT_LOW_ACTIVE, _detect, _bus, _addr)
+#define VD_WVGA_TX23D200_18(_mode, _detect, _bus, _addr) VDF_WVGA_TX23D200(_mode, "tx23d200_18", RGB666, 0, _detect, _bus, _addr)
+#define VD_WVGA_TX23D200_18H(_mode, _detect, _bus, _addr) VDF_WVGA_TX23D200(_mode, "tx23d200_18h", RGB666, FBF_BKLIT_DTB, _detect, _bus, _addr)
+#define VD_WVGA_TX23D200_18L(_mode, _detect, _bus, _addr) VDF_WVGA_TX23D200(_mode, "tx23d200_18l", RGB666, FBF_BKLIT_DTB | FBF_BKLIT_LOW_ACTIVE, _detect, _bus, _addr)
+#define VD_WVGA(_mode, _detect, _bus, _addr)		VDF_WVGA(_mode, "wvga", RGB666, 0, _detect, _bus, _addr)
+#define VD_WVGA_J(_mode, _detect, _bus, _addr)		VDF_WVGA(_mode, "wvga_j", RGB24, FBF_JEIDA, _detect, _bus, _addr)
+#define VD_AA065VE11(_mode, _detect, _bus, _addr)	VDF_AA065VE11(_mode, "AA065VE11", RGB24, 0, _detect, _bus, _addr)
+#define VD_VGA(_mode, _detect, _bus, _addr)		VDF_VGA(_mode, "vga", RGB24, 0, _detect, _bus, _addr)
+#define VD_LSA40AT9001(_mode, _detect, _bus, _addr)	VDF_LSA40AT9001(_mode, "LSA40AT9001", RGB24, FBF_MODESTR, _detect, _bus, _addr)
+#define VD_AUO_G050(_mode, _detect, _bus, _addr)	VDF_AUO_G050(_mode, "AUO_G050", RGB24, FBF_MODESTR | FBF_SPI, _detect, _bus, _addr)
+#define VD_A030JN01_UPS051(_mode, _detect, _bus, _addr)	VDF_A030JN01_UPS051(_mode, "A030JN01_UPS051", UPS051, FBF_MODESTR | FBF_SPI, _detect, _bus, _addr)
+#define VD_A030JN01_YUV720(_mode, _detect, _bus, _addr) VDF_A030JN01_YUV720(_mode, "A030JN01_YUV720", YUYV, FBF_MODESTR | FBF_SPI, _detect, _bus, _addr)
+#define VD_KD024FM(_mode, _detect, _bus, _addr)		VDF_KD024FM(_mode, "KD024FM", RGB666, FBF_MODESTR, _detect, _bus, _addr)
+
+#define VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr) \
+	.bus	= _bus,\
+	.addr	= _addr,\
+	.pixfmt	= IPU_PIX_FMT_##_fmt,\
+	.detect	= _detect,\
+	.enable	= fbp_enable_fb,\
+	.fbtype = FB_##_mode,\
+	.fbflags = _flags
+
+/* hdmi settings */
+#define VDF_1280_720M_60(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1280,\
+		.yres           = 720,\
+		.pixclock       = 1000000000000ULL/((1280+216+72+80)*(720+22+3+5)*60),\
+		.left_margin    = 220,\
+		.right_margin   = 110,\
+		.upper_margin   = 20,\
+		.lower_margin   = 5,\
+		.hsync_len      = 40,\
+		.vsync_len      = 5,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_1920_1080M_60(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1920,\
+		.yres           = 1080,\
+		.pixclock       = 1000000000000ULL/((1920+148+88+44)*(1080+36+4+5)*60),\
+		.left_margin    = 148,\
+		.right_margin   = 88,\
+		.upper_margin   = 36,\
+		.lower_margin   = 4,\
+		.hsync_len      = 44,\
+		.vsync_len      = 5,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+
+#define VDF_1024_768M_60(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 768,\
+		.pixclock       = 1000000000000ULL/((1024+220+40+60)*(768+21+7+10)*60),\
+		.left_margin    = 220,\
+		.right_margin   = 40,\
+		.upper_margin   = 21,\
+		.lower_margin   = 7,\
+		.hsync_len      = 60,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_800_600MR_60(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 600,\
+		.pixclock       = 1000000000000ULL/((800+88+40+128)*(600+23+2+3)*60),\
+		.left_margin    = 88,\
+		.right_margin   = 40,\
+		.upper_margin   = 23,\
+		.lower_margin   = 2,	/* must be >=2 */\
+		.hsync_len      = 128,\
+		.vsync_len      = 3,\
+		.sync           = FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_640_480M_60(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 640,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((640+48+16+96)*(480+33+10+2)*60),\
+		.left_margin    = 48,\
+		.right_margin   = 16,\
+		.upper_margin   = 33,\
+		.lower_margin   = 10,\
+		.hsync_len      = 96,\
+		.vsync_len      = 2,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_720_480M_60(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 720,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((720+60+16+62)*(480+30+9+6)*60),\
+		.left_margin    = 60,\
+		.right_margin   = 16,\
+		.upper_margin   = 30,\
+		.lower_margin   = 9,\
+		.hsync_len      = 62,\
+		.vsync_len      = 6,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* tsc2004 */
+#define VDF_CLAA_WVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 57,\
+		.xres           = 800,\
+		.yres           = 480,\
+		.pixclock       = 37037,\
+		.left_margin    = 40,\
+		.right_margin   = 60,\
+		.upper_margin   = 10,\
+		.lower_margin   = 10,\
+		.hsync_len      = 20,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* tsc2004 */
+/* keep compatible with LQ050Y3DC01 */
+#define VDF_SHARP_WVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((800+40+40+48)*(480+31+11+3)*60),\
+		.left_margin    = 40,\
+		.right_margin   = 40,\
+		.upper_margin   = 31,\
+		.lower_margin   = 11,\
+		.hsync_len      = 48,\
+		.vsync_len      = 3,\
+		.sync           = FB_SYNC_EXT |FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_TFC_A9700LTWV35TC_C1(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((800+40+40+48)*(480+29+13+3)*60),\
+		.left_margin    = 40,\
+		.right_margin   = 40,\
+		.upper_margin   = 29,\
+		.lower_margin   = 13,\
+		.hsync_len      = 48,\
+		.vsync_len      = 3,\
+		.sync           = FB_SYNC_EXT |FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+
+/*
+ * 800x300
+ * vsync = 60
+ * hsync = 260 * vsync = 15.6 Khz
+ * pixclk = 800 * hsync = 12.48 MHz
+ */
+#define VDF_800X300(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name		= _name,\
+		.refresh	= 60,\
+		.xres		= 800,\
+		.yres		= 300,\
+		.pixclock	= 1000000000000ULL / (800+50+1+110) / (300+8+3+1) / 60,\
+		.left_margin	= 50,\
+		.right_margin	= 1,\
+		.upper_margin	= 8,\
+		.lower_margin	= 3,\
+		.hsync_len	= 110,\
+		.vsync_len	= 1,\
+		.sync           = FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/*
+ * hitachi 640x240
+ * vsync = 60
+ * hsync = 260 * vsync = 15.6 Khz
+ * pixclk = 800 * hsync = 12.48 MHz
+ */
+#define VDF_HITACHI_HVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name		= _name,\
+		.refresh	= 60,\
+		.xres		= 640,\
+		.yres		= 240,\
+		.pixclock	= 1000000000000ULL / (640+34+1+125) / (240+8+3+9) / 60,\
+		.left_margin	= 34,\
+		.right_margin	= 1,\
+		.upper_margin	= 8,\
+		.lower_margin	= 3,\
+		.hsync_len	= 125,\
+		.vsync_len	= 9,\
+		.sync           = FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_NEON_TOUCH640X240(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name		= _name,\
+		.refresh	= 60,\
+		.xres		= 640,\
+		.yres		= 240,\
+		.pixclock	= 1000000000000ULL / (640+34+1+125) / (240+8+3+9) / 60,\
+		.left_margin	= 34,\
+		.right_margin	= 1,\
+		.upper_margin	= 8,\
+		.lower_margin	= 3,\
+		.hsync_len	= 125,\
+		.vsync_len	= 9,\
+		.sync           = FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* tsc2004 */
+#define VDF_DC050WX(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 480,\
+		.pixclock       = 33898,\
+		.left_margin    = 96,\
+		.right_margin   = 24,\
+		.upper_margin   = 3,\
+		.lower_margin   = 10,\
+		.hsync_len      = 40,\
+		.vsync_len      = 32,\
+		.sync           = FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+
+/* INNOLUX model N140BGE, 18 bit LVDS */
+#define VDF_INNOLUX_WXGA_14IN_12V(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name		= _name,\
+		.refresh	= 60,\
+		.xres		= 1366,\
+		.yres		= 768,\
+		.pixclock	= 1000000000000ULL / (1366+108+108+10) / (768+8+8+16) / 60,\
+		.left_margin	= 108,\
+		.right_margin	= 108,\
+		.upper_margin	= 8,\
+		.lower_margin	= 8,\
+		.hsync_len	= 10,\
+		.vsync_len	= 16,\
+		.sync		= FB_SYNC_EXT,\
+		.vmode		= FB_VMODE_NONINTERLACED,\
+	}\
+}
+
+/* AUO model B116XAN03.0, 11.6", 1366x768, 24 bit lvds */
+#define VDF_AUO_WXGA_11IN_12V(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name		= _name,\
+		.refresh	= 60,\
+		.xres		= 1366,\
+		.yres		= 768,\
+		.pixclock	= 1000000000000ULL / (1366+67+67+100) / (768+10+10+6) / 60,\
+		.left_margin	= 67,\
+		.right_margin	= 67,\
+		.upper_margin	= 10,\
+		.lower_margin	= 10,\
+		.hsync_len	= 100,\
+		.vsync_len	= 6,\
+		.sync		= FB_SYNC_EXT,\
+		.vmode		= FB_VMODE_NONINTERLACED,\
+	}\
+}
+
+/* OSD model OSD101T1315-45, 18 bit LVDS*/
+#define VDF_OSD_WSVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name		= _name,\
+		.refresh	= 60,\
+		.xres		= 1024,\
+		.yres		= 600,\
+		.pixclock	= 1000000000000ULL / (1024+45+210+1) / (600+22+132+1) / 60,\
+		.left_margin	= 45,\
+		.right_margin	= 210,\
+		.upper_margin	= 22,\
+		.lower_margin	= 132,\
+		.hsync_len	= 1,\
+		.vsync_len	= 1,\
+		.sync		= FB_SYNC_EXT,\
+		.vmode		= FB_VMODE_NONINTERLACED,\
+	}\
+}
+
+/* INNOLUX model AT070TN83, 800x480  18 bit RGB with or without LVDS converter board */
+#define VDF_INNOLUX_WVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name		= _name,\
+		.refresh	= 60,\
+		.xres		= 800,\
+		.yres		= 480,\
+		.pixclock	= 1000000000000ULL / (800+45+16+1) / (480+22+125+1) / 60,\
+		.left_margin	= 45,\
+		.right_margin	= 16,\
+		.upper_margin	= 22,\
+		.lower_margin	= 125,\
+		.hsync_len	= 1,\
+		.vsync_len	= 1,\
+		.sync		= FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode		= FB_VMODE_NONINTERLACED,\
+	}\
+}
+
+#define VDF_LB043(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 57,\
+		.xres           = 480,\
+		.yres           = 800,\
+		.pixclock       = 37037,\
+		.left_margin    = 40,\
+		.right_margin   = 60,\
+		.upper_margin   = 10,\
+		.lower_margin   = 10,\
+		.hsync_len      = 20,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	},\
+}
+
+#define VDF_OKAYA_480_272(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name		= _name,\
+		.refresh	= 57,\
+		.xres		= 480,\
+		.yres		= 272,\
+		.pixclock	= 97786,\
+		.left_margin	= 2,\
+		.right_margin	= 1,\
+		.upper_margin	= 3,\
+		.lower_margin	= 2,\
+		.hsync_len	= 41,\
+		.vsync_len	= 10,\
+		.sync		= FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode		= FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* tsc2004 */
+#define VDF_QVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 320,\
+		.yres           = 240,\
+		.pixclock       = 1000000000000ULL/((320+38+37+30)*(240+16+15+3)*60),\
+		.left_margin    = 38,\
+		.right_margin   = 37,\
+		.upper_margin   = 16,\
+		.lower_margin   = 15,\
+		.hsync_len      = 30,\
+		.vsync_len      = 3,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_SPI_QVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 320,\
+		.yres           = 240,\
+		.pixclock       = 1000000000000ULL/((320+16+20+52)*(240+16+4+2)*60),\
+		.left_margin    = 16,\
+		.right_margin   = 20,\
+		.upper_margin   = 16,\
+		.lower_margin   = 4,\
+		.hsync_len      = 52,\
+		.vsync_len      = 2,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* tsc2004 */
+#define VDF_AT035GT_07ET3(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 320,\
+		.yres           = 240,\
+		.pixclock       = 1000000000000ULL/((320+40+18+30)*(240+10+9+3)*60),\
+		.left_margin    = 40,\
+		.right_margin   = 18,\
+		.upper_margin   = 10,\
+		.lower_margin   = 9,\
+		.hsync_len      = 30,\
+		.vsync_len      = 3,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* ili210x touch screen */
+#define VDF_AMP1024_600(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 600,\
+		.pixclock       = 1000000000000ULL/((1024+220+40+60)*(600+21+7+10)*60),\
+		.left_margin    = 220,\
+		.right_margin   = 40,\
+		.upper_margin   = 21,\
+		.lower_margin   = 7,\
+		.hsync_len      = 60,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* ft5x06 touch screen */
+#define VDF_ND1024_600(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 600,\
+		.pixclock       = 1000000000000ULL/((1024+160+80+80)*(600+19+8+8)*60),\
+		.left_margin    = 160,\
+		.right_margin   = 80,\
+		.upper_margin   = 19,\
+		.lower_margin   = 8,\
+		.hsync_len      = 80,\
+		.vsync_len      = 8,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* ft5x06 touch screen */
+/* Tianma panel TM070JDHG30 is a 24 bit spwg panel */
+#define VDF_TM070JDHG30(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1280,\
+		.yres           = 800,\
+		.pixclock       = 1000000000000ULL/((1280+5+63+1)*(800+2+39+1)*60),\
+		.left_margin    = 5,\
+		.right_margin   = 63,\
+		.upper_margin   = 2,\
+		.lower_margin   = 39,\
+		.hsync_len      = 1,\
+		.vsync_len      = 1,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_AUO_B101EW05(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1280,\
+		.yres           = 800,\
+		.pixclock       = 1000000000000ULL/((1280+48+48+32)*(800+8+2+6)*60),\
+		.left_margin    = 48,\
+		.right_margin   = 48,\
+		.upper_margin   = 8,\
+		.lower_margin   = 2,\
+		.hsync_len      = 32,\
+		.vsync_len      = 6,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* ft5x06_ts */
+/* lg1280x800(LP101WX1) == hannstar7 */
+/* LG panel LD101WX1 is a 24 bit spwg panel */
+#define VDF_HANNSTAR7(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1280,\
+		.yres           = 800,\
+		.pixclock       = 1000000000000ULL/((1280+80+48+32)*(800+15+2+6)*60),\
+		.left_margin    = 80,\
+		.right_margin   = 48,\
+		.upper_margin   = 15,\
+		.lower_margin   = 2,\
+		.hsync_len      = 32,\
+		.vsync_len      = 6,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* ft5x06_ts */
+#define VDF_DT070BTFT(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 600,\
+		.pixclock       = 1000000000000ULL/((1024+220+40+60)*(600+21+4+10)*60),\
+		.left_margin    = 220,\
+		.right_margin   = 40,\
+		.upper_margin   = 21,\
+		.lower_margin   = 4,\
+		.hsync_len      = 60,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* ft5x06_ts */
+#define VDF_WSVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 600,\
+		.pixclock       = 1000000000000ULL/((1024+220+40+60)*(600+21+7+10)*60),\
+		.left_margin    = 220,\
+		.right_margin   = 40,\
+		.upper_margin   = 21,\
+		.lower_margin   = 7,\
+		.hsync_len      = 60,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* Also works for ER-TFT050-3 */
+#define VDF_ASIT500MA6F5D(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.pwm_period = 100000, \
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL / (800+88+40+48) / (480+32+13+3) / 60,\
+		.left_margin    = 88,\
+		.right_margin   = 40,\
+		.upper_margin   = 32,\
+		.lower_margin   = 13,\
+		.hsync_len      = 48,\
+		.vsync_len      = 3,\
+		.sync           = FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* fusion7 */
+#define VDF_FUSION7(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((800+96+24+136)*(480+31+11+3)*60),\
+		.left_margin    = 96,\
+		.right_margin   = 24,\
+		.upper_margin   = 31,\
+		.lower_margin   = 11,\
+		.hsync_len      = 136,\
+		.vsync_len      = 3,\
+		.sync           = FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* egalax_ts */
+#define VDF_HANNSTAR(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 768,\
+		.pixclock       = 1000000000000ULL/((1024+220+40+60)*(768+21+7+10)*60),\
+		.left_margin    = 220,\
+		.right_margin   = 40,\
+		.upper_margin   = 21,\
+		.lower_margin   = 7,\
+		.hsync_len      = 60,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_1024_600(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 600,\
+		.pixclock       = 20408,\
+		.left_margin    = 144,\
+		.right_margin   = 40,\
+		.upper_margin   = 3,\
+		.lower_margin   = 11,\
+		.hsync_len      = 104,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_AFK1024600A02(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 600,\
+		.pixclock       = 1000000000000ULL/((1024+160+80+80)*(600+19+8+8)*60),\
+		.left_margin    = 160,\
+		.right_margin   = 80,\
+		.upper_margin   = 19,\
+		.lower_margin   = 8,\
+		.hsync_len      = 80,\
+		.vsync_len      = 8,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* egalax_ts */
+#define VDF_LG9_7(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1024,\
+		.yres           = 768,\
+		.pixclock       = 1000000000000ULL/((1024+480+260+250)*(768+16+6+10)*60),\
+		.left_margin    = 480,\
+		.right_margin   = 260,\
+		.upper_margin   = 16,\
+		.lower_margin   = 6,\
+		.hsync_len      = 250,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_1080P60(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1920,\
+		.yres           = 1080,\
+		.pixclock       = 1000000000000ULL/((1920+148+88+44)*(1080+36+4+5)*60),\
+		.left_margin    = 148,\
+		.right_margin   = 88,\
+		.upper_margin   = 36,\
+		.lower_margin   = 4,\
+		.hsync_len      = 44,\
+		.vsync_len      = 5,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_DV210FBM(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1920,\
+		.yres           = 1080, /* really 132 */\
+		.pixclock       = 1000000000000ULL/((1920+120+120+40)*(1080+22+22+1)*60),\
+		.left_margin    = 120,\
+		.right_margin   = 120,\
+		.upper_margin   = 22,\
+		.lower_margin   = 22,\
+		.hsync_len      = 44,\
+		.vsync_len      = 1,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_SHARP_LQ101K1LY04(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1280,\
+		.yres           = 800,\
+		.pixclock       = 1000000000000ULL/((1280+20+20+10)*(800+4+4+4)*60),\
+		.left_margin    = 20,\
+		.right_margin   = 20,\
+		.upper_margin   = 4,\
+		.lower_margin   = 4,\
+		.hsync_len      = 10,\
+		.vsync_len      = 4,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_WXGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 1280,\
+		.yres           = 800,\
+		.pixclock       = 1000000000000ULL/((1280+40+40+10)*(800+3+80+10)*60),\
+		.left_margin    = 40,\
+		.right_margin   = 40,\
+		.upper_margin   = 3,\
+		.lower_margin   = 80,\
+		.hsync_len      = 10,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_LD070WSVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 55,\
+		.xres           = 1024,\
+		.yres           = 600,\
+		.pixclock       = 1000000000000ULL/((1024+160+160+10)*(600+23+12+3)*55),\
+		.left_margin    = 160,\
+		.right_margin   = 160,\
+		.upper_margin   = 23,\
+		.lower_margin   = 12,\
+		.hsync_len      = 10,\
+		.vsync_len      = 3,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_SVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 600,\
+		.pixclock       = 15385,\
+		.left_margin    = 220,\
+		.right_margin   = 40,\
+		.upper_margin   = 21,\
+		.lower_margin   = 7,\
+		.hsync_len      = 60,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* 40.0 ns (25 Mhz) to 28.6 ns (34.965 MHz)
+ * 35.35 ns(28.28 Mhz)
+ * 1000000000/1056/525/40 =  45.094 frames/second
+ * 1000000000/1056/525/35.35 = 51 frames/second
+ * 1000000000/1056/525/28.6 =  63.068 frames/second
+ */
+#define VDF_WVGA_TX23D200(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((800+220+18+18)*(480+21+14+10)*52),\
+		.left_margin    = 220,\
+		.right_margin   = 18,\
+		.upper_margin   = 21,\
+		.lower_margin   = 14,\
+		.hsync_len      = 18,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_WVGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((800+220+40+60)*(480+21+7+10)*60),\
+		.left_margin    = 220,\
+		.right_margin   = 40,\
+		.upper_margin   = 21,\
+		.lower_margin   = 7,\
+		.hsync_len      = 60,\
+		.vsync_len      = 10,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_AA065VE11(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 70,\
+		.xres           = 640,\
+		.yres           = 480,\
+		.pixclock       = 22858,	/* 23000 works 23100 doesn't */\
+		.left_margin    = 48 + 100,\
+		.right_margin   = 16 + 100,\
+		.upper_margin   = 33 + 50,\
+		.lower_margin   = 10 + 50,\
+		.hsync_len      = 96,\
+		.vsync_len      = 2,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_VGA(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 640,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((640+48+16+96)*(480+33+10+2)*60),\
+		.left_margin    = 48,\
+		.right_margin   = 16,\
+		.upper_margin   = 33,\
+		.lower_margin   = 10,\
+		.hsync_len      = 96,\
+		.vsync_len      = 2,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_LSA40AT9001(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 800,\
+		.yres           = 600,\
+		.pixclock       = 1000000000000ULL/((800+46+210+10)*(600+23+12+1)*60),\
+		.left_margin    = 46,\
+		.right_margin   = 210,\
+		.upper_margin   = 23,\
+		.lower_margin   = 12,\
+		.hsync_len      = 10,\
+		.vsync_len      = 1,\
+		.sync           = FB_SYNC_EXT | FB_SYNC_CLK_LAT_FALL,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* spi panels */
+#define VDF_AUO_G050(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 480,\
+		.yres           = 800,\
+		.pixclock       = 1000000000000ULL/((480+18+16+2)*(800+18+16+2)*60),\
+		.left_margin    = 18,\
+		.right_margin   = 16,\
+		.upper_margin   = 18,\
+		.lower_margin   = 16,\
+		.hsync_len      = 2,\
+		.vsync_len      = 2,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+//640 * 3/2 = 960, (1.5 clocks per pixel)
+//33.7M
+#define VDF_A030JN01_UPS051(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode	= {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 640,\
+		.yres           = 480,\
+		.pixclock       = 1000000000000ULL/((960+40+48+20)*(480+27+18+1)*60),\
+		.left_margin    = 40,\
+		.right_margin   = 48,\
+		.upper_margin   = 27,\
+		.lower_margin   = 18,\
+		.hsync_len      = 20,\
+		.vsync_len      = 1,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+/* 27.11 MHz pixel clock */
+#define VDF_A030JN01_YUV720(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.mode   = {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 720,\
+		.yres           = 480,\
+		.pixclock       =  1000000000000ULL/((720+40+98+1)*(480+27+18+1)*60),\
+		.left_margin    = 40,\
+		.right_margin   = 98,\
+		.upper_margin   = 27,\
+		.lower_margin   = 18,\
+		.hsync_len      = 1,\
+		.vsync_len      = 1,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+
+#define VDF_KD024FM(_mode, _name, _fmt, _flags, _detect, _bus, _addr) \
+{\
+	VD_HEADER(_mode, _fmt, _flags, _detect, _bus, _addr),\
+	.pre_enable = board_pre_enable, \
+	.pwm_period = 100000, \
+	.mode   = {\
+		.name           = _name,\
+		.refresh        = 60,\
+		.xres           = 240,\
+		.yres           = 320,\
+		.pixclock       =  1000000000000ULL/((240+10+38+10)*(320+4+8+4)*60),\
+		.left_margin    = 10,\
+		.right_margin   = 38,\
+		.upper_margin   = 4,\
+		.lower_margin   = 8,\
+		.hsync_len      = 10,\
+		.vsync_len      = 4,\
+		.sync           = FB_SYNC_EXT,\
+		.vmode          = FB_VMODE_NONINTERLACED\
+	}\
+}
+#endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d860c425a1ed9aa711eb5b590f28bc46eb3cae4d..d0e2b4962c70eba293a1df757f1374962efea318 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -32,6 +32,11 @@ obj-y 	+= cpu.o
 obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o
 endif
+
+ifeq ($(SOC),$(filter $(SOC),mx5 mx6 mx7))
+obj-$(CONFIG_CMD_FBPANEL) += fbpanel.o
+endif
+
 ifeq ($(SOC),$(filter $(SOC),mx6 mx7))
 obj-y 	+= cache.o init.o
 obj-$(CONFIG_FEC_MAC_FUSE) += mac.o
diff --git a/arch/arm/mach-imx/fbpanel.c b/arch/arm/mach-imx/fbpanel.c
new file mode 100644
index 0000000000000000000000000000000000000000..f172f1543470cec9392dd85086e75cd00272978c
--- /dev/null
+++ b/arch/arm/mach-imx/fbpanel.c
@@ -0,0 +1,1437 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/crm_regs.h>
+#if !defined(CONFIG_MX51) && !defined(CONFIG_MX53) && !defined(CONFIG_MX7D)
+#include <asm/arch/mxc_hdmi.h>
+#endif
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/fbpanel.h>
+#include <asm/io.h>
+#include <div64.h>
+#include <i2c.h>
+#include <malloc.h>
+#include <video_fb.h>
+/*
+ * This creates commands strings to work on dtb files.
+ * i.e. if you define the following environment variables
+ *
+ * setenv fb_hdmi 1920x1080M@60
+ * setenv fb_lcd *off
+ * setenv fb_lvds lg1280x800
+ *
+ * Note: the "*" means u-boot should enable this display, in this case none.
+ *
+ * you'll get the follow strings if cmd_frozen is not defined.
+ * cmd_hdmi=fdt set fb_hdmi status okay;fdt set fb_hdmi mode_str 1920x1080M@60;
+ *
+ * cmd_lcd=fdt set fb_lcd status disabled
+ *
+ * cmd_lvds=fdt set fb_lvds status okay;
+ * 	fdt set fb_lvds interface_pix_fmt RGB24;
+ * 	fdt set ldb/lvds-channel@0 fsl,data-width <24>;
+ * 	fdt set ldb/lvds-channel@0 fsl,data-mapping jeida;
+ * 	fdt rm ldb split-mode;
+ * 	fdt set t_lvds clock-frequency <71107200>;
+ * 	fdt set t_lvds hactive <1280>;
+ * 	fdt set t_lvds vactive <800>;
+ * 	fdt set t_lvds hback-porch <48>;
+ * 	fdt set t_lvds hfront-porch <80>;
+ * 	fdt set t_lvds vback-porch <15>;
+ * 	fdt set t_lvds vfront-porch <2>;
+ * 	fdt set t_lvds hsync-len <32>;
+ * 	fdt set t_lvds vsync-len <6>;
+ *
+ * cmd_lvds2=fdt set fb_lvds2 status disabled
+ *
+ *
+ * These strings are then used in 6x_bootscript to configure displays
+ *
+ * The following aliases should be defined in the dtb if possible
+ * fb_hdmi, fb_lcd, fb_lvds, fb_lvds2
+ * lcd
+ * ldb
+ * t_lvds, t_lvds2
+ */
+static const char *const fbnames[] = {
+[FB_HDMI] = "fb_hdmi",
+[FB_LCD] = "fb_lcd",
+[FB_LCD2] = "fb_lcd2",
+[FB_LVDS] = "fb_lvds",
+[FB_LVDS2] = "fb_lvds2"
+};
+
+static const char *const timings_names[] = {
+[FB_HDMI] = "t_hdmi",
+[FB_LCD] = "t_lcd",
+[FB_LCD2] = "t_lcd2",
+[FB_LVDS] = "t_lvds",
+[FB_LVDS2] = "t_lvds2"
+};
+
+static const char *const ch_names[] = {
+[FB_HDMI] = "",
+[FB_LCD] = "",
+[FB_LCD2] = "",
+[FB_LVDS] = "ldb/lvds-channel@0",
+[FB_LVDS2] = "ldb/lvds-channel@1"
+};
+
+static const char *const cmd_fbnames[] = {
+[FB_HDMI] = "cmd_hdmi",
+[FB_LCD] = "cmd_lcd",
+[FB_LCD2] = "cmd_lcd2",
+[FB_LVDS] = "cmd_lvds",
+[FB_LVDS2] = "cmd_lvds2"
+};
+
+static const char *const backlight_names[] = {
+[FB_HDMI] = "backlight_hdmi",
+[FB_LCD] = "backlight_lcd",
+[FB_LCD2] = "backlight_lcd2",
+[FB_LVDS] = "backlight_lvds",
+[FB_LVDS2] = "backlight_lvds2"
+};
+
+static const char *const pwm_names[] = {
+[FB_HDMI] = "pwm_hdmi",
+[FB_LCD] = "pwm_lcd",
+[FB_LCD2] = "pwm_lcd2",
+[FB_LVDS] = "pwm_lvds",
+[FB_LVDS2] = "pwm_lvds2"
+};
+
+static const char *const short_names[] = {
+[FB_HDMI] = "hdmi",
+[FB_LCD] = "lcd",
+[FB_LCD2] = "lcd2",
+[FB_LVDS] = "lvds",
+[FB_LVDS2] = "lvds2"
+};
+
+static const char *const timings_properties[] = {
+"clock-frequency",
+"hactive",
+"vactive",
+"hback-porch",
+"hfront-porch",
+"vback-porch",
+"vfront-porch",
+"hsync-len",
+"vsync-len",
+};
+
+static const int timings_offsets[] = {
+	offsetof(struct fb_videomode, pixclock),
+	offsetof(struct fb_videomode, xres),
+	offsetof(struct fb_videomode, yres),
+	offsetof(struct fb_videomode, left_margin),
+	offsetof(struct fb_videomode, right_margin),
+	offsetof(struct fb_videomode, upper_margin),
+	offsetof(struct fb_videomode, lower_margin),
+	offsetof(struct fb_videomode, hsync_len),
+	offsetof(struct fb_videomode, vsync_len),
+};
+
+static void __board_pre_enable(const struct display_info_t *di)
+{
+}
+
+static void __board_enable_hdmi(const struct display_info_t *di, int enable)
+{
+}
+
+static void __board_enable_lcd(const struct display_info_t *di, int enable)
+{
+}
+
+static void __board_enable_lvds(const struct display_info_t *di, int enable)
+{
+}
+
+static void __board_enable_lvds2(const struct display_info_t *di, int enable)
+{
+}
+
+void board_pre_enable(const struct display_info_t *di)
+	__attribute__((weak, alias("__board_pre_enable")));
+void board_enable_hdmi(const struct display_info_t *di, int enable)
+	__attribute__((weak, alias("__board_enable_hdmi")));
+void board_enable_lcd(const struct display_info_t *di, int enable)
+	__attribute__((weak, alias("__board_enable_lcd")));
+void board_enable_lvds(const struct display_info_t *di, int enable)
+	__attribute__((weak, alias("__board_enable_lvds")));
+void board_enable_lvds2(const struct display_info_t *di, int enable)
+	__attribute__((weak, alias("__board_enable_lvds2")));
+
+static unsigned get_fb_available_mask(const struct display_info_t *di, int cnt)
+{
+	unsigned mask = 0;
+	int i;
+
+	for (i = 0; i < cnt; i++, di++)
+		mask |= (1 << di->fbtype);
+
+	return mask;
+}
+static const char rgb24[] = "RGB24";
+static const char rgb565[] = "RGB565";
+static const char rgb666[] = "RGB666";
+static const char yuyv16[] = "YUYV16";
+
+static char lvds_enabled;
+static const char brightness_levels_low_active[] = "<10 9 8 7 6 5 4 3 2 1 0>";
+static const char brightness_levels_high_active[] = "<0 1 2 3 4 5 6 7 8 9 10>";
+
+static u32 period_to_freq(u32 freq)
+{
+	u64 lval = 1000000000000ULL;
+
+	if (freq < (233 * 16))
+		freq = (233 * 16);	/* ensure result * 16 fits in u32 */
+	do_div(lval, freq);
+	return (u32)lval;
+}
+
+static u32 freq_to_period(u32 val)
+{
+	u64 lval = 1000000000000ULL;
+
+	if (val < (233 * 16)) {
+		val = 233 * 16;
+		printf("invalid pixel clock frequency\n");
+	}
+	do_div(lval, val);
+	return (u32)lval;
+}
+
+static void setup_cmd_fb(unsigned fb, const struct display_info_t *di, char *buf, int size)
+{
+	const char *mode_str = NULL;
+	int i;
+	int sz;
+	const char *buf_start = buf;
+	const struct fb_videomode *mode;
+	const char * fmt;
+
+	if (getenv("cmd_frozen") && getenv(cmd_fbnames[fb]))
+		return;		/* don't override if already set */
+
+	if (fb == FB_LVDS)
+		lvds_enabled = 0;
+	if (!di) {
+		const char *name = getenv(fbnames[fb]);
+		if (name) {
+			if (name[0] == '*')
+				name++;
+			if (strcmp(name, "off")) {
+				/* Not off and not in list, assume mode_str value */
+				mode_str = name;
+			}
+		}
+		if (!mode_str) {
+			sz = snprintf(buf, size, "fdt set %s status disabled", fbnames[fb]);
+			buf += sz;
+			size -= sz;
+			if (fb == FB_LCD)
+				sz = snprintf(buf, size, ";fdt set lcd status disabled");
+			if ((fb == FB_LVDS) || (fb == FB_LVDS2)) {
+				sz = snprintf(buf, size, ";fdt set ldb/lvds-channel@%d status disabled", fb - FB_LVDS);
+			}
+			setenv(cmd_fbnames[fb], buf_start);
+			return;
+		}
+	} else {
+		if (di->fbflags & FBF_MODESTR)
+			mode_str = di->mode.name;
+	}
+
+	if (fb == FB_LVDS)
+		lvds_enabled = 1;
+	sz = snprintf(buf, size, "fdt set %s status okay;", fbnames[fb]);
+	buf += sz;
+	size -= sz;
+	if ((fb == FB_LVDS2) && !lvds_enabled) {
+		sz = snprintf(buf, size, "fdt set ldb/lvds-channel@1 primary;");
+		buf += sz;
+		size -= sz;
+	}
+
+	if (di->pixfmt == IPU_PIX_FMT_RGB24)
+		fmt = rgb24;
+	else if (di->pixfmt == IPU_PIX_FMT_YUYV)
+		fmt = yuyv16;
+	else if (di->pixfmt == IPU_PIX_FMT_RGB565)
+		fmt = rgb565;
+	else
+		fmt = rgb666;
+
+	if (di && (fb >= FB_LCD)) {
+#if defined(CONFIG_MX6SX) || defined(CONFIG_MX7D)
+		sz = snprintf(buf, size, "fdt set %s bus-width <%u>;", short_names[fb],
+				(di->pixfmt == IPU_PIX_FMT_RGB24) ? 24 : 18);
+
+#else
+		sz = snprintf(buf, size, "fdt set %s interface_pix_fmt %s;",
+				fbnames[fb], fmt);
+#endif
+		buf += sz;
+		size -= sz;
+	}
+
+	if (di && ((fb == FB_LCD) || (fb == FB_LCD2))) {
+		sz = snprintf(buf, size, "fdt set %s default_ifmt %s;",
+				short_names[fb], fmt);
+		buf += sz;
+		size -= sz;
+
+		sz = snprintf(buf, size, "fdt set %s status okay;",
+				short_names[fb]);
+		buf += sz;
+		size -= sz;
+	}
+
+	if (di && ((fb == FB_LVDS) || (fb == FB_LVDS2))) {
+
+		sz = snprintf(buf, size, "fdt set %s fsl,data-width <%u>;",
+				ch_names[fb],
+				(di->pixfmt == IPU_PIX_FMT_RGB24) ? 24 : 18);
+		buf += sz;
+		size -= sz;
+
+		sz = snprintf(buf, size, "fdt set %s fsl,data-mapping %s;",
+				ch_names[fb],
+				(di->fbflags & FBF_JEIDA) ? "jeida" : "spwg");
+		buf += sz;
+		size -= sz;
+
+		if (di->fbflags & FBF_SPLITMODE) {
+			sz = snprintf(buf, size, "fdt set ldb split-mode 1;");
+			buf += sz;
+			size -= sz;
+		}
+	}
+
+	if (di && di->pwm_period) {
+		sz = snprintf(buf, size, "fdt get value pwm %s phandle; fdt set %s pwms <${pwm} 0x%x 0x%x>;",
+				pwm_names[fb], backlight_names[fb], 0, di->pwm_period);
+		buf += sz;
+		size -= sz;
+	}
+	if (di && (di->fbflags & FBF_BKLIT_DTB)) {
+		sz = snprintf(buf, size, "fdt set %s brightness-levels %s;",
+			backlight_names[fb],
+			(di->fbflags & FBF_BKLIT_LOW_ACTIVE) ?
+				brightness_levels_low_active :
+				brightness_levels_high_active);
+		buf += sz;
+		size -= sz;
+	}
+
+	if (mode_str) {
+		snprintf(buf, size, "fdt set %s mode_str %s;", fbnames[fb], mode_str);
+		setenv(cmd_fbnames[fb], buf_start);
+		return;
+	}
+
+	mode = &di->mode;
+	for (i = 0; i < ARRAY_SIZE(timings_properties); i++) {
+		u32 *p = (u32 *)((char *)mode + timings_offsets[i]);
+		u32 val;
+
+		if (i == 0) {
+			val = period_to_freq(mode->pixclock);
+		} else {
+			val = *p;
+		}
+		sz = snprintf(buf, size, "fdt set %s %s <%u>;", timings_names[fb], timings_properties[i], val);
+		buf += sz;
+		size -= sz;
+	}
+	setenv(cmd_fbnames[fb], buf_start);
+}
+
+static const struct display_info_t *find_panel(const struct display_info_t *di, int cnt, unsigned fb, const char *name)
+{
+	int i;
+
+	for (i = 0; i < cnt; i++, di++) {
+		if ((fb == di->fbtype) && !strcmp(name, di->mode.name))
+			return di;
+	}
+	return NULL;
+}
+
+static char g_mode_str[FB_COUNT][80];
+static struct display_info_t g_di_temp[FB_COUNT];
+
+int fbp_detect_i2c(struct display_info_t const *di)
+{
+	int ret;
+	int gp = di->bus >> 8;
+
+	if (gp)
+		gpio_set_value(gp, 1);
+	ret = i2c_set_bus_num(di->bus & 0xff);
+	if (ret == 0)
+		ret = i2c_probe(di->addr);
+	if (gp)
+		gpio_set_value(gp, 0);
+	return (ret == 0);
+}
+
+int calc_gcd(int a, int b)
+{
+	int n;
+
+	while (b) {
+		if (a > b) {
+			n = a;
+			a = b;
+			b = n;
+		}
+		n = b / a;
+		b -= n * a;
+	}
+	return a;
+}
+
+#ifdef CONFIG_MX6SX
+void reparent_lvds(int fbtype, int new_parent)
+{
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	int ldb_sel_shift = 9;
+	u32 reg = readl(&ccm->cs2cdr);
+
+	reg &= ~(7 << ldb_sel_shift);
+
+	reg |= new_parent << ldb_sel_shift;
+	writel(reg, &ccm->cs2cdr);
+	readl(&ccm->cs2cdr);	/* wait for write */
+}
+
+#elif !defined(CONFIG_MX51) && !defined(CONFIG_MX53) && !defined(CONFIG_MX7D)
+void reparent_lvds(int fbtype, int new_parent)
+{
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	int ldb_sel_shift = (fbtype == FB_LVDS2) ? 12 : 9;
+	u32 reg;
+
+	reg = readl(&ccm->cbcmr);
+	reg &= ~MXC_CCM_CBCMR_PERIPH2_CLK2_SEL;
+	writel(reg, &ccm->cbcmr);
+
+	/* Set MMDC_CH1 mask bit */
+	reg = readl(&ccm->ccdr);
+	reg |= MXC_CCM_CCDR_MMDC_CH1_HS_MASK;
+	writel(reg, &ccm->ccdr);
+
+	/*
+	 * Set the periph2_clk_sel to the top mux so that
+	 * mmdc_ch1 is from pll3_sw_clk.
+	 */
+	reg = readl(&ccm->cbcdr);
+	reg |= MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
+	writel(reg, &ccm->cbcdr);
+
+	/* Wait for the clock switch */
+	while (readl(&ccm->cdhipr) != 0) {
+		udelay(100);
+	}
+
+	/* Disable pll3_sw_clk by selecting the bypass clock source */
+	reg = readl(&ccm->ccsr);
+	reg |= MXC_CCM_CCSR_PLL3_SW_CLK_SEL;
+	writel(reg, &ccm->ccsr);
+
+	/* Set the ldb_di0/1_clk to 1xxb, to change to lower mux */
+	reg = readl(&ccm->cs2cdr);
+	reg |= (4 << ldb_sel_shift);
+	writel(reg, &ccm->cs2cdr);
+	readl(&ccm->cs2cdr);	/* wait for write */
+
+	/* Set the ldb_di0/1_clk to 100b, change upper mux to pll5 */
+	reg &= ~(3 << ldb_sel_shift);
+	reg |= new_parent << ldb_sel_shift;
+	writel(reg, &ccm->cs2cdr);
+	readl(&ccm->cs2cdr);	/* wait for write */
+
+	/* select upper mux, pll 5 clock */
+	reg &= ~(4 << ldb_sel_shift);
+	writel(reg, &ccm->cs2cdr);
+	readl(&ccm->cs2cdr);	/* wait for write */
+
+	/* Unbypass pll3_sw_clk */
+	reg = readl(&ccm->ccsr);
+	reg &= ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL;
+	writel(reg, &ccm->ccsr);
+
+	/*
+	 * Set the periph2_clk_sel back to the bottom mux so that
+	 * mmdc_ch1 is from its original parent.
+	 */
+	reg = readl(&ccm->cbcdr);
+	reg &= ~MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
+	writel(reg, &ccm->cbcdr);
+
+	/* Wait for the clock switch */
+	while (readl(&ccm->cdhipr)) {
+		udelay(100);
+	}
+
+	/* Clear MMDC_CH1 mask bit */
+	reg = readl(&ccm->ccdr);
+	reg &= ~MXC_CCM_CCDR_MMDC_CH1_HS_MASK;
+	writel(reg, &ccm->ccdr);
+}
+#endif
+
+#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
+int get_pll3_clock(void);
+
+void setup_clock(struct display_info_t const *di)
+{
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	u32 desired_freq, freq;
+	u32 pll3_freq = get_pll3_clock();
+	u32 n, m;
+	u32 i;
+	u32 best = 8;
+	u32 best_diff = ~0;
+	u32 diff;
+	u32 reg;
+
+	if (!(di->mode.sync & FB_SYNC_EXT))
+		return;
+
+	desired_freq = period_to_freq(di->mode.pixclock) * 16;
+
+	for (i = 8; i > 0 ; i--) {
+		n = pll3_freq / i;
+		m = n / desired_freq;
+		if (!m || (m & 1))
+			continue;
+		if (m > 16)
+			break;
+		freq = n / m;
+		if (freq >= desired_freq)
+			diff = freq - desired_freq;
+		else
+			diff = desired_freq - freq;
+
+		if (best_diff > diff) {
+			best_diff = diff;
+			best = i;
+		}
+	}
+	reg = readl(&ccm->cdcdr);
+	reg &= ~(7 << 6);
+	reg |= (best - 1) << 6;
+	writel(reg, &ccm->cdcdr);
+
+#ifndef CONFIG_MX6SX
+	ipu_set_ldb_clock(pll3_freq / best);	/* used for all ext clocks */
+#endif
+}
+
+#else
+void setup_clock(struct display_info_t const *di)
+{
+#if defined(CONFIG_MX7D)
+	struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *)
+						 ANATOP_BASE_ADDR;
+	u32 target;
+#else
+	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	u32 reg;
+	u32 pll_video;
+#if !defined(CONFIG_MX6SX)
+	u32 out_freq;
+#endif
+#endif
+	u32 desired_freq;
+	int post_div = 2;	/* 0: /4, 1: /2, 2: /1 */
+	int misc2_div = 0;	/* 0: /1, 1: /2, 3: /4 */
+	int lvds = ((di->fbtype == FB_LVDS) | (di->fbtype == FB_LVDS2)) ? 1 : 0;
+	int timeout = 1000;
+	int multiplier;
+	int gcd;
+	int num, denom;
+	int ipu_div = 7;
+	int x = 1;
+
+	if (!(di->mode.sync & FB_SYNC_EXT))
+		return;
+
+#if defined(CONFIG_MX6SX)
+	clrbits_le32(&ccm->CCGR2, MXC_CCM_CCGR2_LCD_MASK);
+	/* gate LCDIF2/LCDIF1/LDB_DI0 */
+	clrbits_le32(&ccm->CCGR3, 0x3f << 8);
+#elif defined(CONFIG_MX7D)
+	clock_enable(CCGR_LCDIF, 0);
+#else
+	/* gate ipu1_di0_clk */
+	clrbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK |
+			MXC_CCM_CCGR3_LDB_DI1_MASK |
+			MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
+#endif
+
+#if defined(CONFIG_MX7D)
+	/* Power up video PLL and disable its output */
+	writel(CCM_ANALOG_PLL_VIDEO_CLR_ENABLE_CLK_MASK |
+		CCM_ANALOG_PLL_VIDEO_CLR_POWERDOWN_MASK |
+		CCM_ANALOG_PLL_VIDEO_CLR_BYPASS_MASK |
+		CCM_ANALOG_PLL_VIDEO_CLR_DIV_SELECT_MASK |
+		CCM_ANALOG_PLL_VIDEO_CLR_POST_DIV_SEL_MASK |
+		CCM_ANALOG_PLL_VIDEO_CLR_TEST_DIV_SELECT_MASK,
+		&ccm_anatop->pll_video_clr);
+#else
+	pll_video = readl(&ccm->analog_pll_video);
+	pll_video &= BM_ANADIG_PLL_VIDEO_ENABLE;
+	pll_video |= BM_ANADIG_PLL_VIDEO_POWERDOWN;
+	writel(pll_video, &ccm->analog_pll_video);
+#endif
+
+	desired_freq = period_to_freq(di->mode.pixclock);
+	debug("desired_freq=%d\n", desired_freq);
+#if !defined(CONFIG_MX6SX) && !defined(CONFIG_MX7D)
+	out_freq = desired_freq;
+#endif
+
+#if !defined(CONFIG_MX7D)
+	if (lvds) {
+		reparent_lvds(di->fbtype, 0);
+		desired_freq *= 7;
+		if (di->fbflags & FBF_SPLITMODE)
+			desired_freq >>= 1;
+
+	}
+#endif
+	debug("desired_freq=%d\n", desired_freq);
+
+#define MIN_FREQ 648000000	/* 24000000 * 27 */
+
+	if (!(is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) ||
+			soc_rev() > CHIP_REV_1_0) {
+		while (desired_freq < MIN_FREQ) {
+			desired_freq <<= 1;
+			if (--post_div <= 0)
+				break;
+		}
+		debug("desired_freq=%d\n", desired_freq);
+
+		while (desired_freq < MIN_FREQ) {
+			desired_freq <<= 1;
+			misc2_div = (misc2_div << 1) + 1;
+			if (misc2_div >= 3)
+				break;
+		}
+		debug("desired_freq=%d\n", desired_freq);
+	};
+
+	if (!lvds) {
+		num = (MIN_FREQ - 1) / desired_freq + 1;
+		x = (num + 7) / 8;
+		ipu_div =  (num - 1) / x + 1;
+		desired_freq *= ipu_div * x;
+#if defined(CONFIG_MX6SX)
+		if (x > 8) {
+			printf("div changed from %d to 64\n", num);
+			ipu_div = 8;
+			x = 8;
+			desired_freq = MIN_FREQ;
+		}
+#endif
+	} else if (desired_freq < MIN_FREQ) {
+		printf("desired_freq=%d is too low\n", desired_freq);
+	}
+#if !defined(CONFIG_MX6SX) && !defined(CONFIG_MX7D)
+	ipu_set_ldb_clock(out_freq * x);	/* used for all ext clocks */
+#endif
+	debug("desired_freq=%d ipu div=%d x=%d\n", desired_freq, ipu_div, x);
+
+	multiplier = desired_freq / 24000000;
+	if (multiplier > 54) {
+		multiplier = 54;
+		desired_freq = 24000000 * 54;
+	}
+
+#if defined(CONFIG_MX7D)
+	writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(multiplier) |
+		CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(post_div) |
+		CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(misc2_div),
+		&ccm_anatop->pll_video_set);
+#else
+	reg = readl(&ccm->pmu_misc2);
+	reg &= ~(BF_PMU_MISC2_VIDEO_DIV(3));
+	reg |= BF_PMU_MISC2_VIDEO_DIV(misc2_div);
+	writel(reg, &ccm->pmu_misc2);
+
+	pll_video &= ~(BM_ANADIG_PLL_VIDEO_DIV_SELECT |
+		 BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT);
+	pll_video |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(multiplier) |
+		BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(post_div);
+	writel(pll_video, &ccm->analog_pll_video);
+#endif
+	desired_freq -= multiplier * 24000000;
+	gcd = calc_gcd(desired_freq, 24000000);
+	debug("gcd=%d desired_freq=%d 24000000\n", gcd, desired_freq);
+	num = desired_freq / gcd;
+	denom = 24000000 / gcd;
+	debug("desired_freq=%d multiplier=%d %d/%d\n", desired_freq, multiplier, num, denom);
+
+#if defined(CONFIG_MX7D)
+	writel(num, &ccm_anatop->pll_video_num);
+	writel(denom, &ccm_anatop->pll_video_denom);
+
+	while (!(readl(&ccm_anatop->pll_video) & CCM_ANALOG_PLL_VIDEO_LOCK_MASK)) {
+		udelay(100);
+		if (--timeout < 0) {
+			printf("Warning: video pll lock timeout!\n");
+			break;
+		}
+	}
+
+	/* Enable PLL out */
+	writel(CCM_ANALOG_PLL_VIDEO_CLR_ENABLE_CLK_MASK,
+			&ccm_anatop->pll_video_set);
+#else
+	writel(num, &ccm->analog_pll_video_num);
+	writel(denom, &ccm->analog_pll_video_denom);
+
+	pll_video &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
+	writel(pll_video, &ccm->analog_pll_video);
+
+	while (!(readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)) {
+		udelay(100);
+		if (--timeout < 0) {
+			printf("Warning: video pll lock timeout!\n");
+			break;
+		}
+	}
+
+	pll_video &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
+	pll_video |= BM_ANADIG_PLL_VIDEO_ENABLE;
+	writel(pll_video, &ccm->analog_pll_video);
+#endif
+
+#if defined(CONFIG_MX6SX)
+	/* Select pll5 clock for ldb di0 */
+	clrbits_le32(&ccm->cs2cdr, MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK);
+
+	/* lvds:
+	 *   lcdif1 from ldb_di0
+	 * lcd:
+	 *   lcdif1 from pre-muxed lcdif1 clock / ipu_div
+	 *   pre-muxed from PLL5
+	 */
+	clrsetbits_le32(&ccm->cscdr2,
+		(MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK |
+		MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_MASK |
+		MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_MASK),
+		(((lvds ? 3 : 0) << MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_OFFSET) |
+		((ipu_div - 1) << MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_OFFSET) |
+		(2 << MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_OFFSET)));
+
+	/* Set the post divider */
+	clrsetbits_le32(&ccm->cbcmr,
+			MXC_CCM_CBCMR_LCDIF1_PODF_MASK,
+			((x - 1) <<
+			MXC_CCM_CBCMR_LCDIF1_PODF_OFFSET));
+
+	setbits_le32(&ccm->CCGR2, MXC_CCM_CCGR2_LCD_MASK);
+	/* enable lcdif1/ ldb_di0 (if lvds)*/
+	setbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LCDIF1_PIX_MASK |
+		MXC_CCM_CCGR3_DISP_AXI_MASK |
+		(lvds ? MXC_CCM_CCGR3_LDB_DI0_MASK : 0));
+
+#elif defined(CONFIG_MX7D)
+	target = CLK_ROOT_ON | LCDIF_PIXEL_CLK_ROOT_FROM_PLL_VIDEO_MAIN_CLK |
+		 CLK_ROOT_PRE_DIV((ipu_div - 1)) | CLK_ROOT_POST_DIV((x - 1));
+	clock_set_target_val(LCDIF_PIXEL_CLK_ROOT, target);
+	clock_enable(CCGR_LCDIF, 1);
+
+#else
+	reg = readl(&ccm->chsccdr);
+	reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK |
+		 MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK |
+		 MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK);
+	reg |= ((lvds ? ((di->fbtype == FB_LVDS2) ?
+			 CHSCCDR_CLK_SEL_LDB_DI1 : CHSCCDR_CLK_SEL_LDB_DI0)
+		: CHSCCDR_CLK_SEL_IPU1_DI0)
+			<< MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET) |
+		((ipu_div - 1) << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) |
+		(CHSCCDR_IPU_PRE_CLK_PLL5 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
+	writel(reg, &ccm->chsccdr);
+
+	/* enable ipu1_di0_clk */
+	setbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK |
+			(lvds ? ((di->fbtype == FB_LVDS2) ?
+				 MXC_CCM_CCGR3_LDB_DI1_MASK : MXC_CCM_CCGR3_LDB_DI0_MASK)
+			 : 0));
+#endif
+}
+#endif
+
+void fbp_enable_fb(struct display_info_t const *di, int enable)
+{
+#if !defined(CONFIG_MX51) && !defined(CONFIG_MX53) && !defined(CONFIG_MX7D)
+	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+	u32 reg, cscmr2;
+	u32 tmp;
+#endif
+	switch (di->fbtype) {
+#ifdef CONFIG_IMX_HDMI
+	case FB_HDMI:
+		imx_enable_hdmi_phy();
+		board_enable_hdmi(di, enable);
+		break;
+#endif
+	case FB_LCD2:
+	case FB_LCD:
+		board_enable_lcd(di, enable);
+		break;
+#if !defined(CONFIG_MX51) && !defined(CONFIG_MX53) && !defined(CONFIG_MX7D)
+	case FB_LVDS:
+#ifdef CONFIG_MX6SX
+#define GPR_LDB	6
+#else
+#define GPR_LDB	2
+#endif
+		reg = readl(&iomux->gpr[GPR_LDB]);
+		cscmr2 = readl(&mxc_ccm->cscmr2);
+		reg &= ~(IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT |
+			 IOMUXC_GPR2_BIT_MAPPING_CH0_JEIDA |
+			 IOMUXC_GPR2_DATA_WIDTH_CH1_24BIT |
+ 			 IOMUXC_GPR2_BIT_MAPPING_CH1_JEIDA |
+			 IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
+			 IOMUXC_GPR2_LVDS_CH1_MODE_MASK |
+			 IOMUXC_GPR2_SPLIT_MODE_EN_MASK);
+		tmp = 0;
+		if (di->pixfmt == IPU_PIX_FMT_RGB24)
+			tmp |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
+		if (di->fbflags & FBF_JEIDA)
+			tmp |= IOMUXC_GPR2_BIT_MAPPING_CH0_JEIDA;
+		if (di->fbflags & FBF_SPLITMODE) {
+			tmp |= tmp << 2;
+			tmp |= IOMUXC_GPR2_SPLIT_MODE_EN_MASK |
+			       IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
+
+			cscmr2 &= ~(MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV |
+				 MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV);
+
+		} else {
+			cscmr2 |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
+		}
+		writel(cscmr2, &mxc_ccm->cscmr2);
+		if (enable)
+			reg |= tmp | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
+
+		writel(reg, &iomux->gpr[GPR_LDB]);
+		board_enable_lvds(di, enable);
+		break;
+#ifndef CONFIG_MX6SX
+	case FB_LVDS2:
+		reg = readl(&iomux->gpr[2]);
+		cscmr2 = readl(&mxc_ccm->cscmr2);
+		reg &= ~(IOMUXC_GPR2_DATA_WIDTH_CH1_24BIT |
+			 IOMUXC_GPR2_BIT_MAPPING_CH1_JEIDA |
+			 IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
+			 IOMUXC_GPR2_LVDS_CH1_MODE_MASK |
+			 IOMUXC_GPR2_SPLIT_MODE_EN_MASK);
+		if (di->pixfmt == IPU_PIX_FMT_RGB24)
+			reg |= IOMUXC_GPR2_DATA_WIDTH_CH1_24BIT;
+		if (di->fbflags & FBF_JEIDA)
+			reg |= IOMUXC_GPR2_BIT_MAPPING_CH1_JEIDA;
+
+		cscmr2 |= MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
+		writel(cscmr2, &mxc_ccm->cscmr2);
+
+		if (enable)
+			reg |= IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
+		writel(reg, &iomux->gpr[2]);
+		board_enable_lvds2(di, enable);
+		break;
+#endif
+#endif
+	}
+}
+
+static void imx_prepare_display(void)
+{
+#if !defined(CONFIG_MX51) && !defined(CONFIG_MX53) && \
+		!defined(CONFIG_MX7D)
+	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	int reg;
+#if !defined(CONFIG_MX6SX)
+	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+	enable_ipu_clock();
+#ifdef CONFIG_IMX_HDMI
+	imx_setup_hdmi();
+#endif
+#endif
+	/* Turn on LDB0,IPU,IPU DI0 clocks */
+	reg = __raw_readl(&mxc_ccm->CCGR3);
+	reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK;
+	writel(reg, &mxc_ccm->CCGR3);
+
+	reg = readl(&mxc_ccm->cs2cdr);
+	reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
+		| MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
+#ifdef CONFIG_MX6SX
+	/* Select pll5 clock for ldb di0 */
+#else
+	/* set LDB0, LDB1 clk select to 011/011 */
+	reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
+	      |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
+#endif
+	writel(reg, &mxc_ccm->cs2cdr);
+
+#ifndef CONFIG_MX6SX
+	reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
+	     |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
+	     |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
+	     |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
+	     |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
+	     |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
+	     |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT;
+	writel(reg, &iomux->gpr[2]);
+
+	reg = readl(&iomux->gpr[3]);
+	reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
+			|IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
+	    | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
+	       <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
+	writel(reg, &iomux->gpr[3]);
+#endif
+#endif
+}
+
+static const struct display_info_t * parse_mode(
+		const struct display_info_t *gdi, int cnt, const char *p,
+		unsigned fb, unsigned *prefer)
+{
+	char c;
+	char *endp;
+	unsigned value;
+	int i;
+	struct display_info_t *di;
+	char *mode_str = g_mode_str[fb];
+
+	if (*p == '*') {
+		p++;
+		*prefer = 1;
+	}
+	if (!strcmp(p, "off")) {
+		*prefer |= 2;
+		return NULL;
+	}
+
+	i = 0;
+	while (i < 80 - 1) {
+		c = *p;
+		if (c)
+			p++;
+		if (!c || (c == ':')) {
+			break;
+		}
+		mode_str[i++] = c;
+	}
+	mode_str[i] = 0;
+	c = *p;
+	if (!c) {
+		return find_panel(gdi, cnt, fb, mode_str);
+	}
+	di = &g_di_temp[fb];
+	memset(di, 0, sizeof(*di));
+
+	di->fbtype = fb;
+	di->mode.name = mode_str;
+	di->enable = fbp_enable_fb;
+
+	if (c == 'm') {
+		di->fbflags |= FBF_MODESTR;
+		p++;
+		c = *p;
+	}
+	if (c == 'j') {
+		di->fbflags |= FBF_JEIDA;
+		p++;
+		c = *p;
+	}
+	if (c == 's') {
+		di->fbflags |= FBF_SPLITMODE;
+		p++;
+		c = *p;
+	}
+	value = simple_strtoul(p, &endp, 10);
+	if (endp <= p) {
+		printf("expecting 18|24\n");
+		return NULL;
+	}
+	if ((value != 18) && (value != 24)) {
+		printf("expecting 18|24, found %d\n", value);
+		return NULL;
+	}
+	p = endp;
+	di->pixfmt = (value == 24) ? IPU_PIX_FMT_RGB24 : IPU_PIX_FMT_RGB666;
+	c = *p;
+
+	if (c == 'S') {
+		di->fbflags |= FBF_SPI;
+		p++;
+		c = *p;
+	}
+	if (c == 'D') {
+		di->fbflags |= FBF_BKLIT_DTB;
+		p++;
+		c = *p;
+	}
+	if (c == 'b') {
+		di->fbflags |= FBF_BKLIT_LOW_ACTIVE;
+		p++;
+		c = *p;
+	}
+	if (c == 'e') {
+		di->pre_enable = board_pre_enable;
+		p++;
+		c = *p;
+	}
+	if (c == 'x') {
+		p++;
+		value = simple_strtoul(p, &endp, 16);
+		if (endp <= p) {
+			printf("expecting bus\n");
+			return NULL;
+		}
+		p = endp;
+		di->bus = value;
+		c = *p;
+		if (c == ',') {
+			p++;
+			value = simple_strtoul(p, &endp, 16);
+			if (endp <= p) {
+				printf("expecting bus addr\n");
+				return NULL;
+			}
+			p = endp;
+			di->addr = value;
+			c = *p;
+		}
+	}
+	if (c == 'p') {
+		p++;
+		value = simple_strtoul(p, &endp, 10);
+		if (endp <= p) {
+			printf("expecting period of pwm\n");
+			return NULL;
+		}
+		p = endp;
+		di->pwm_period = value;
+		c = *p;
+	}
+	if (c != ':') {
+		printf("expected ':', %s\n", p);
+		return NULL;
+	}
+	p++;
+
+	for (i = 0; i < ARRAY_SIZE(timings_properties); i++) {
+		u32 *dest = (u32 *)((char *)&di->mode + timings_offsets[i]);
+		u32 val;
+
+		val = simple_strtoul(p, &endp, 10);
+		if (endp <= p) {
+			printf("expecting integer:%s\n", p);
+			return NULL;
+		}
+		if (i == 0)
+			val = freq_to_period(val);
+		*dest = val;
+		p = endp;
+		if (*p == ',')
+			p++;
+		if (*p == ' ')
+			p++;
+	}
+
+	di->mode.sync |= FB_SYNC_EXT;
+	if (*p) {
+		printf("extra parameters found:%s\n", p);
+		return NULL;
+	}
+	return di;
+}
+
+static const struct display_info_t *find_disp(const struct display_info_t *di,
+		int cnt, unsigned fb, unsigned *prefer)
+{
+	int i;
+	const char *name = getenv(fbnames[fb]);
+
+	if (name) {
+		di = parse_mode(di, cnt, name, fb, prefer);
+		if (di)
+			return di;
+		if (!(*prefer & 2))
+			printf("No match, assuming mode_str: %s\n", name);
+		return NULL;
+	}
+	/* No specific name requested, lets probe */
+	for (i = 0; i < cnt; i++, di++) {
+		if (fb == di->fbtype) {
+			if (di->detect && di->detect(di)) {
+				printf("auto-detected panel %s\n", di->mode.name);
+				return di;
+			}
+		}
+	}
+	return NULL;
+}
+
+static const struct display_info_t *find_first_disp(
+		const struct display_info_t *di, int cnt)
+{
+	int i;
+	unsigned skip_mask = 0;
+
+	for (i = 0; i < cnt; i++, di++) {
+		if (di->fbtype >= FB_COUNT)
+			continue;
+		if (skip_mask & (1 << di->fbtype))
+			continue;
+		if (getenv(fbnames[di->fbtype])) {
+			skip_mask |= (1 << di->fbtype);
+			continue;
+		}
+		return di;
+	}
+	return NULL;
+}
+
+static void str_mode(char *p, int size, const struct display_info_t *di, unsigned prefer)
+{
+	int count;
+	int i;
+
+	if (prefer) {
+		*p++ = '*';
+		size--;
+	}
+	if (!di) {
+		count = snprintf(p, size, "off");
+		if (size > count) {
+			p += count;
+			size -= count;
+		}
+		*p = 0;
+		return;
+	}
+	count = snprintf(p, size, "%s:", di->mode.name);
+	if (size > count) {
+		p += count;
+		size -= count;
+	}
+	if (di->fbflags & FBF_MODESTR) {
+		*p++ = 'm';
+		size--;
+	}
+	if (di->fbflags & FBF_JEIDA) {
+		*p++ = 'j';
+		size--;
+	}
+	if (di->fbflags & FBF_SPLITMODE) {
+		*p++ = 's';
+		size--;
+	}
+	count = snprintf(p, size, "%d", (di->pixfmt == IPU_PIX_FMT_RGB24) ? 24 : 18);
+	if (size > count) {
+		p += count;
+		size -= count;
+	}
+	if (di->fbflags & FBF_SPI) {
+		*p++ = 'S';
+		size--;
+	}
+	if (di->fbflags & FBF_BKLIT_DTB) {
+		*p++ = 'D';
+		size--;
+	}
+	if (di->fbflags & FBF_BKLIT_LOW_ACTIVE) {
+		*p++ = 'b';
+		size--;
+	}
+	if (di->pre_enable) {
+		*p++ = 'e';
+		size--;
+	}
+	if (di->bus || di->addr) {
+		count = snprintf(p, size, "x%x,%x", di->bus, di->addr);
+		if (size > count) {
+			p += count;
+			size -= count;
+		}
+	}
+	if (di->pwm_period) {
+		count = snprintf(p, size, "p%d", di->pwm_period);
+		if (size > count) {
+			p += count;
+			size -= count;
+		}
+	}
+	*p++ = ':';
+	size--;
+
+	for (i = 0; i < ARRAY_SIZE(timings_properties); i++) {
+		u32 *src = (u32 *)((char *)&di->mode + timings_offsets[i]);
+		u32 val;
+
+		if (i == 0) {
+			val = period_to_freq(di->mode.pixclock);
+		} else {
+			val = *src;
+			if (size > 1) {
+				*p++ = ',';
+				size--;
+			}
+		}
+		count = snprintf(p, size, "%d", val);
+		if (size > count) {
+			p += count;
+			size -= count;
+		}
+	}
+	*p = 0;
+}
+
+static void print_mode(const struct display_info_t *di, int *len)
+{
+	int i;
+	char format_buf[16];
+	const struct fb_videomode* mode = &di->mode;
+	int fb = di->fbtype;
+	char buf[256];
+
+	str_mode(buf, sizeof(buf), di, 0);
+	printf("%s: %s\n\x09", short_names[fb], buf);
+
+
+	for (i = 0; i < ARRAY_SIZE(timings_properties); i++) {
+		u32 *p = (u32 *)((char *)mode + timings_offsets[i]);
+		u32 val;
+
+		if (i == 0) {
+			val = period_to_freq(mode->pixclock);
+		} else {
+			val = *p;
+		}
+		snprintf(format_buf, sizeof(format_buf), " %c%du", '%', len[i]);
+		printf(format_buf, val);
+	}
+	printf("\n");
+}
+
+static void print_modes(const struct display_info_t *di, int cnt, unsigned mask)
+{
+	int i;
+	int len[ARRAY_SIZE(timings_properties)];
+
+	/* Print heading */
+	printf("\x09");
+	for (i = 0; i < ARRAY_SIZE(timings_properties); i++) {
+		printf(" %s", timings_properties[i]);
+		len[i] = strlen(timings_properties[i]);
+	}
+	printf("\n");
+
+	for (i = 0; i < cnt; i++, di++) {
+		if (mask & (1 << di->fbtype))
+			print_mode(di, len);
+	}
+}
+
+static const struct display_info_t *select_display(
+		const struct display_info_t *gdi, int cnt)
+{
+	const struct display_info_t *disp[FB_COUNT];
+	const struct display_info_t *di = NULL;
+	unsigned prefer_mask = 0;
+	unsigned fb;
+	char *buf = malloc(4096);
+
+	for (fb = 0; fb < ARRAY_SIZE(disp); fb++) {
+		unsigned prefer = 0;
+
+		disp[fb] = find_disp(gdi, cnt, fb, &prefer);
+		if (prefer & 1)
+			prefer_mask |= (1 << fb);
+	}
+	fb = ffs(prefer_mask) - 1;
+	if (fb < ARRAY_SIZE(disp)) {
+		di = disp[fb];
+	} else {
+		/* default to the 1st one in the list*/
+		for (fb = 0; fb < ARRAY_SIZE(disp); fb++) {
+			if (!di) {
+				di = disp[fb];
+			} else {
+				if (disp[fb] && ((unsigned)disp[fb]
+						< (unsigned)di))
+					di = disp[fb];
+			}
+		}
+		if (!di) {
+			di = find_first_disp(gdi, cnt);
+			if (di)
+				disp[di->fbtype] = di;
+		}
+	}
+
+	if (buf) {
+		unsigned mask = get_fb_available_mask(gdi, cnt);
+
+		for (fb = 0; fb < ARRAY_SIZE(disp); fb++) {
+			if (mask & (1 << fb))
+				setup_cmd_fb(fb, disp[fb], buf, 4096);
+		}
+		free(buf);
+	}
+	return di;
+}
+
+static const struct display_info_t *g_displays;
+static int g_display_cnt;
+
+static const struct display_info_t *g_di_active;
+
+void board_video_enable(void)
+{
+	const struct display_info_t *di = g_di_active;
+	if (di && di->enable)
+		di->enable(di, 1);
+}
+
+static int init_display(const struct display_info_t *di)
+{
+	int ret;
+
+	if (di->pre_enable)
+		di->pre_enable(di);
+	setup_clock(di);
+#if defined(CONFIG_MX6SX) || defined(CONFIG_MX7D)
+	ret = mxsfb_init(&di->mode, di->pixfmt);
+#else
+	ret = ipuv3_fb_init(&di->mode, (di->fbtype == FB_LCD2) ? 1 : 0,
+			di->pixfmt);
+#endif
+	if (ret) {
+		printf("LCD %s cannot be configured: %d\n", di->mode.name, ret);
+		return -EINVAL;
+	}
+	printf("Display: %s:%s (%ux%u)\n", short_names[di->fbtype],
+			di->mode.name, di->mode.xres, di->mode.yres);
+	g_di_active = di;
+	return 0;
+}
+
+static int do_fbpanel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int i;
+	const char *fbname;
+	int fb = -1;
+	const char *p;
+	char *buf;
+	unsigned prefer;
+	int ret = 0;
+	const struct display_info_t* di = g_displays;
+	int cnt = g_display_cnt;
+
+	if (argc < 2) {
+		print_modes(di, cnt, 0xf);
+                return 0;
+	}
+	fbname = argv[1];
+	for (i = 0; i < ARRAY_SIZE(short_names); i++) {
+		if (!strcmp(short_names[i], fbname)) {
+			fb = i;
+			break;
+		}
+	}
+	if (fb < 0)
+		return CMD_RET_USAGE;
+
+	if (argc < 3) {
+		print_modes(di, cnt, 1 << fb);
+		return 0;
+	}
+	p = argv[2];
+	di = parse_mode(di, cnt, p, fb, &prefer);
+	if (!di && !(prefer & 2))
+		return 1;
+
+	buf = malloc(4096);
+	if (buf) {
+		str_mode(buf, 256, di, prefer & 1);
+		setenv(fbnames[fb], buf);
+
+		setup_cmd_fb(fb, di, buf, 4096);
+		free(buf);
+	}
+	if (!(prefer & 1))
+		return 0;
+	{
+		const struct display_info_t* di1;
+		di1 = g_di_active;
+		if (di1 && di1->enable) {
+			di1->enable(di1, 0);
+			g_di_active = NULL;
+		}
+	}
+#if !defined(CONFIG_MX6SX) && !defined(CONFIG_MX7D)
+	ipuv3_fb_shutdown();
+	if (!di)
+		return 0;
+	ret = init_display(di);
+	if (ret)
+		return ret;
+	ipuv3_fb_init2();
+#else
+	lcdif_power_down();
+	if (!di)
+		return 0;
+	ret = init_display(di);
+	if (ret)
+		return ret;
+	mxsfb_init2();
+#endif
+	return ret;
+}
+
+U_BOOT_CMD(fbpanel, 3, 0, do_fbpanel,
+           "show/set panel names available",
+           "fbpanel [hdmi|lcd|lvds|lvds2] [\"[*]mode_str[:[m][j][s][18|24][S][e][xhexbus,hexaddr][pnnn]:pixclkfreq,xres,yres,hback-porch,hfront-porch,vback-porch,vfront-porch,hsync,vsync]\"]\n"
+           "\n"
+           "fbpanel  - show all panels");
+
+int board_video_skip(void)
+{
+	const struct display_info_t *di = select_display(g_displays, g_display_cnt);
+
+	if (!di)
+		return -EINVAL;
+	return init_display(di);
+}
+
+void fbp_setup_display(const struct display_info_t *displays, int cnt)
+{
+	g_displays = displays;
+	g_display_cnt = cnt;
+	imx_prepare_display();
+}