diff --git a/drivers/video/mxc_ipuv3_fb.c b/drivers/video/mxc_ipuv3_fb.c
index 44c3dac3837be99e0e72e705f3e0870de6b0cef8..3b5965a6260245019d48e0312144460e47ef369d 100644
--- a/drivers/video/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc_ipuv3_fb.c
@@ -27,7 +27,6 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 static int mxcfb_map_video_memory(struct fb_info *fbi);
-static int mxcfb_unmap_video_memory(struct fb_info *fbi);
 
 /* graphics setup */
 static GraphicDevice panel;
@@ -221,9 +220,6 @@ static int mxcfb_set_par(struct fb_info *fbi)
 
 	mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
 	if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) {
-		if (fbi->fix.smem_start)
-			mxcfb_unmap_video_memory(fbi);
-
 		if (mxcfb_map_video_memory(fbi) < 0)
 			return -ENOMEM;
 	}
@@ -396,25 +392,38 @@ static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
 static int mxcfb_map_video_memory(struct fb_info *fbi)
 {
-	if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length) {
-		fbi->fix.smem_len = fbi->var.yres_virtual *
-				    fbi->fix.line_length;
+	unsigned smem_len = fbi->var.yres_virtual * fbi->fix.line_length;
+	unsigned min = 1920 * 1080 * 2;
+
+	fbi->screen_size = smem_len;
+	if (smem_len < min)
+		smem_len = min;
+	smem_len = roundup(smem_len, ARCH_DMA_MINALIGN);
+	if (fbi->fix.smem_len < smem_len) {
+		debug("smem_len %d %d, %lx\n", fbi->fix.smem_len, smem_len, fbi->fix.smem_start);
+		if (fbi->fix.smem_start) {
+			free((void *)fbi->fix.smem_start);
+			fbi->fix.smem_start = 0;
+			fbi->screen_base = NULL;
+			fbi->fix.smem_len = 0;
+		}
 	}
-	fbi->fix.smem_len = roundup(fbi->fix.smem_len, ARCH_DMA_MINALIGN);
-	fbi->screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
-					    fbi->fix.smem_len);
-	fbi->fix.smem_start = (unsigned long)fbi->screen_base;
-	if (fbi->screen_base == 0) {
-		puts("Unable to allocate framebuffer memory\n");
-		fbi->fix.smem_len = 0;
-		fbi->fix.smem_start = 0;
-		return -EBUSY;
+	if (!fbi->fix.smem_start) {
+		fbi->screen_base = memalign(ARCH_DMA_MINALIGN, smem_len);
+		fbi->fix.smem_start = (unsigned long)fbi->screen_base;
+		debug("screen_base = %p\n", fbi->screen_base);
+		if (!fbi->screen_base) {
+			puts("Unable to allocate framebuffer memory\n");
+			fbi->fix.smem_len = 0;
+			fbi->fix.smem_start = 0;
+			return -EBUSY;
+		}
+		fbi->fix.smem_len = smem_len;
 	}
 
 	debug("allocated fb @ paddr=0x%08X, size=%d.\n",
 		(uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
 
-	fbi->screen_size = fbi->fix.smem_len;
 
 	gd->fb_base = fbi->fix.smem_start;
 
@@ -424,14 +433,6 @@ static int mxcfb_map_video_memory(struct fb_info *fbi)
 	return 0;
 }
 
-static int mxcfb_unmap_video_memory(struct fb_info *fbi)
-{
-	fbi->screen_base = 0;
-	fbi->fix.smem_start = 0;
-	fbi->fix.smem_len = 0;
-	return 0;
-}
-
 /*
  * Initializes the framebuffer information pointer. After allocating
  * sufficient memory for the framebuffer structure, the fields are
@@ -447,7 +448,6 @@ static struct fb_info *mxcfb_init_fbinfo(void)
 #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
 	struct fb_info *fbi;
 	struct mxcfb_info *mxcfbi;
-	char *p;
 	int size = sizeof(struct mxcfb_info) + PADDING +
 		sizeof(struct fb_info);
 
@@ -461,14 +461,12 @@ static struct fb_info *mxcfb_init_fbinfo(void)
 	 * Allocate sufficient memory for the fb structure
 	 */
 
-	p = malloc(size);
-	if (!p)
+	fbi = malloc(size);
+	if (!fbi)
 		return NULL;
+	memset(fbi, 0, size);
 
-	memset(p, 0, size);
-
-	fbi = (struct fb_info *)p;
-	fbi->par = p + sizeof(struct fb_info) + PADDING;
+	fbi->par = ((char *)fbi) + sizeof(struct fb_info) + PADDING;
 
 	mxcfbi = (struct mxcfb_info *)fbi->par;
 	debug("Framebuffer structures at: fbi=0x%x mxcfbi=0x%x\n",
@@ -513,12 +511,17 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
 	/*
 	 * Initialize FB structures
 	 */
-	fbi = mxcfb_init_fbinfo();
+	fbi = mxcfb_info[disp];
 	if (!fbi) {
-		ret = -ENOMEM;
-		goto err0;
+		fbi = mxcfb_init_fbinfo();
+		if (!fbi) {
+			ret = -ENOMEM;
+			goto err0;
+		}
+		mxcfb_info[disp] = fbi;
 	}
 	mxcfbi = (struct mxcfb_info *)fbi->par;
+	mxcfbi->ipu_di = disp;
 
 	if (!g_dp_in_use) {
 		mxcfbi->ipu_ch = MEM_BG_SYNC;
@@ -528,15 +531,12 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
 		mxcfbi->blank = FB_BLANK_POWERDOWN;
 	}
 
-	mxcfbi->ipu_di = disp;
-
 	ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80);
 	ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0);
 	strcpy(fbi->fix.id, "DISP3 BG");
 
 	g_dp_in_use = 1;
 
-	mxcfb_info[mxcfbi->ipu_di] = fbi;
 
 	/* Need dummy values until real panel is configured */
 
@@ -544,7 +544,6 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
 	fb_videomode_to_var(&fbi->var, mode);
 	fbi->var.bits_per_pixel = 16;
 	fbi->fix.line_length = fbi->var.xres * (fbi->var.bits_per_pixel / 8);
-	fbi->fix.smem_len = fbi->var.yres_virtual * fbi->fix.line_length;
 
 	mxcfb_check_var(&fbi->var, fbi);
 
@@ -578,6 +577,8 @@ err0:
 	return ret;
 }
 
+void ipu_dmfc_uninit(void);
+
 void ipuv3_fb_shutdown(void)
 {
 	int i;
@@ -598,6 +599,16 @@ void ipuv3_fb_shutdown(void)
 		__raw_writel(__raw_readl(&stat->int_stat[i]),
 			     &stat->int_stat[i]);
 	}
+	ipu_dmfc_uninit();
+	g_dp_in_use = 0;
+}
+
+void *ipuv3_fb_init2(void)
+{
+	mxcfb_probe(gpixfmt, gdisp, gmode);
+
+	debug("Framebuffer at 0x%x\n", (unsigned int)panel.frameAdrs);
+	return (void *)&panel;
 }
 
 void *video_hw_init(void)
@@ -607,11 +618,7 @@ void *video_hw_init(void)
 	ret = ipu_probe();
 	if (ret)
 		puts("Error initializing IPU\n");
-
-	ret = mxcfb_probe(gpixfmt, gdisp, gmode);
-	debug("Framebuffer at 0x%x\n", (unsigned int)panel.frameAdrs);
-
-	return (void *)&panel;
+	return ipuv3_fb_init2();
 }
 
 int ipuv3_fb_init(struct fb_videomode const *mode,
diff --git a/include/ipu_pixfmt.h b/include/ipu_pixfmt.h
index c7cbca753c532ae40e2aa02044297eb408a9a8a8..a8ff55afc139174bd7edaa91cb8ecae1fdabd74a 100644
--- a/include/ipu_pixfmt.h
+++ b/include/ipu_pixfmt.h
@@ -63,6 +63,7 @@
 int ipuv3_fb_init(struct fb_videomode const *mode,
 		  uint8_t disp,
 		  uint32_t pixfmt);
+void *ipuv3_fb_init2(void);
 void ipuv3_fb_shutdown(void);
 
 #endif