Update kgsl and msm_fb from caf jb_chocolate

Current as of 9f50d27978515e62323231539cdb44f897386b29
msm_fb: hdmi: Correct checksum value

Signed-off-by: Evan McClain <aeroevan@gmail.com>
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 3bfe31c..376d68c 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -11,7 +11,7 @@
 endif
 
 obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
-obj-y += proc_comm.o
+obj-y += proc_comm.o subsystem_map.o
 obj-$(CONFIG_ARCH_MSM_ARM11) += acpuclock-arm11.o idle.o
 obj-$(CONFIG_ARCH_QSD8X50) += arch-init-scorpion.o acpuclock-scorpion.o
 obj-$(CONFIG_ARCH_MSM7X30) += acpuclock-7x30.o internal_power_rail.o
diff --git a/arch/arm/mach-msm/board-vivow-panel.c b/arch/arm/mach-msm/board-vivow-panel.c
index 94ebc62..886ff8c 100644
--- a/arch/arm/mach-msm/board-vivow-panel.c
+++ b/arch/arm/mach-msm/board-vivow-panel.c
@@ -24,13 +24,13 @@
 #include <linux/err.h>
 #include <linux/gpio.h>
 
+#include <mach/msm_panel.h>
 #include <asm/io.h>
 #include <asm/mach-types.h>
 #include <mach/msm_fb.h>
 #include <mach/msm_iomap.h>
 #include <mach/vreg.h>
 #include <mach/panel_id.h>
-#include "../../../drivers/video/msm/mdp_hw.h"
 
 #include "pmic.h"
 #include "board-vivow.h"
@@ -70,7 +70,6 @@
         .len = sizeof((u8 []){__VA_ARGS__}) / sizeof(u8)        \
 }
 static struct clk *axi_clk;
-static int color_enhancement = 0;
 
 static struct vreg *V_LCMIO_1V8, *V_LCM_2V85;
 static struct cabc_t {
@@ -401,20 +400,6 @@
 
 enum led_brightness vivow_brightness_value = DEFAULT_BRIGHTNESS;// multiple definition of `brightness_value' in board-glacier-panel.c
 
-void vivow_mdp_color_enhancement(struct mdp_device *mdp_dev)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	mdp->write_regs(mdp, vivow_mdp_init_color, ARRAY_SIZE(vivow_mdp_init_color));
-}
-
-static struct msm_mdp_platform_data mdp_pdata = {
-	.overrides = MSM_MDP4_MDDI_DMA_SWITCH
-#ifdef CONFIG_OVERLAY_FORCE_UPDATE
-	| MSM_MDP_FORCE_UPDATE
-#endif
-	,
-};
-
 static void
 do_renesas_cmd(struct msm_mddi_client_data *client_data, struct mddi_cmd *cmd_table, ssize_t size)
 {
@@ -513,7 +498,6 @@
 static enum led_brightness
 vivow_get_brightness(struct led_classdev *led_cdev)
 {
-	/*FIXME:workaround for NOVATEK driver IC*/
 #if 0
 	struct msm_mddi_client_data *client = cabc.client_data;
 	return client->remote_read(client, 0x5100);
@@ -928,14 +912,8 @@
 			struct msm_mddi_client_data *client_data)
 {
 	B(KERN_DEBUG "%s(%d)\n", __func__, __LINE__);
-
-
 	client_data->auto_hibernate(client_data, 0);
 	if(panel_type == PANEL_VIVOW_HITACHI) {
-		if (color_enhancement == 0) {
-			vivow_mdp_color_enhancement(mdp_pdata.mdp_dev);
-			color_enhancement = 1;
-		}
 		client_data->remote_write(client_data, 0x0, 0x11);
 		hr_msleep(125);
 		vivow_backlight_switch(LED_FULL);
@@ -1099,21 +1077,40 @@
 	},
 };
 
+static struct msm_mdp_platform_data mdp_pdata = {
+#ifdef CONFIG_MDP4_HW_VSYNC
+	.xres = 480,
+	.yres = 800,
+	.back_porch = 2,
+	.front_porch = 42,
+	.pulse_width = 2,
+#else
+	.overrides = MSM_MDP4_MDDI_DMA_SWITCH,
+#endif
+};
+
+static struct msm_mdp_platform_data mdp_pdata_sony = {
+#ifdef CONFIG_MDP4_HW_VSYNC
+	.xres = 480,
+	.yres = 800,
+	.back_porch = 4,
+	.front_porch = 2,
+	.pulse_width = 4,
+#else
+	.overrides = MSM_MDP4_MDDI_DMA_SWITCH,
+#endif
+};
 
 int __init vivow_init_panel(unsigned int sys_rev)
 {
 	int rc;
 
 	B(KERN_INFO "%s(%d): enter. panel_type 0x%08x\n", __func__, __LINE__, panel_type);
+	if (panel_type == PANEL_VIVOW_HITACHI)
+		msm_device_mdp.dev.platform_data = &mdp_pdata;
+	else
+		msm_device_mdp.dev.platform_data = &mdp_pdata_sony;
 
-	//use dmap for hitachi panel
-	if(panel_type == PANEL_VIVOW_HITACHI)
-	{
-		mdp_pdata.overrides = 0;
-		pr_err("%s: mdp_pdata.overrides = 0\n", __func__);
-	}
-
-	msm_device_mdp.dev.platform_data = &mdp_pdata;
 	rc = platform_device_register(&msm_device_mdp);
 	if (rc)
 		return rc;
diff --git a/arch/arm/mach-msm/devices_htc.c b/arch/arm/mach-msm/devices_htc.c
index e6b076b..08c43e4 100644
--- a/arch/arm/mach-msm/devices_htc.c
+++ b/arch/arm/mach-msm/devices_htc.c
@@ -182,14 +182,8 @@
 	.set_grp_async = set_grp3d_async,
 	.idle_timeout = HZ/20,
 	.nap_allowed = true,
-	.clk = {
-		.clk = "grp_clk",
-		.pclk = "grp_pclk",
-	},
-	.imem_clk_name = {
-		.clk = "imem_clk",
-		.pclk = NULL,
-	},
+	.clk_map = KGSL_CLK_SRC | KGSL_CLK_CORE |
+		KGSL_CLK_IFACE | KGSL_CLK_MEM,
 };
 
 static struct platform_device msm_kgsl_3d0 = {
@@ -231,10 +225,7 @@
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/10,
 	.nap_allowed = true,
-	.clk = {
-		.clk = "grp_2d_clk",
-		.pclk = "grp_2d_pclk",
-	},
+	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 };
 
 static struct platform_device msm_kgsl_2d0 = {
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index b10f483..3d9993f 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -315,6 +315,19 @@
 	struct dec_instance_table *dec_instance_list;
 };
 
+enum msm_mdp_hw_revision {
+	MDP_REV_20 = 1,
+	MDP_REV_22,
+	MDP_REV_30,
+	MDP_REV_303,
+	MDP_REV_31,
+	MDP_REV_40,
+	MDP_REV_41,
+	MDP_REV_42,
+	MDP_REV_43,
+	MDP_REV_44,
+};
+
 struct msm_panel_common_pdata {
 	uintptr_t hw_revision_addr;
 	int gpio;
@@ -324,14 +337,15 @@
 	void (*panel_config_gpio)(int);
 	int (*vga_switch)(int select_vga);
 	int *gpio_num;
-	int mdp_core_clk_rate;
-	unsigned num_mdp_clk;
-	int *mdp_core_clk_table;
-	int (*rgb_format)(void);
-	unsigned char (*shrink_pwm)(int val);
+	u32 mdp_max_clk;
 #ifdef CONFIG_MSM_BUS_SCALING
 	struct msm_bus_scale_pdata *mdp_bus_scale_table;
 #endif
+	int mdp_rev;
+	u32 ov0_wb_size;  /* overlay0 writeback size */
+	u32 ov1_wb_size;  /* overlay1 writeback size */
+	u32 mem_hid;
+	char cont_splash_enabled;
 };
 
 struct lcdc_platform_data {
@@ -362,10 +376,13 @@
 	int (*dsi_power_save)(int on);
 };
 
+#define PANEL_NAME_MAX_LEN 50
 struct msm_fb_platform_data {
 	int (*detect_client)(const char *name);
 	int mddi_prescan;
 	int (*allow_set_offset)(void);
+	char prim_panel_name[PANEL_NAME_MAX_LEN];
+	char ext_panel_name[PANEL_NAME_MAX_LEN];
 };
 
 struct msm_hdmi_platform_data {
@@ -417,6 +434,19 @@
 void __init msm_clock_init(void);
 #endif
 
+struct msm_vidc_platform_data {
+	int memtype;
+	u32 enable_ion;
+	int disable_dmx;
+	int disable_fullhd;
+	u32 cp_enabled;
+#ifdef CONFIG_MSM_BUS_SCALING
+	struct msm_bus_scale_pdata *vidc_bus_client_pdata;
+#endif
+	int disable_turbo;
+        int cont_mode_dpb_count;
+};
+
 void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *);
 
 struct msm_usb_host_platform_data;
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index 48eae0c..f3e24d1 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -14,14 +14,17 @@
 #define _ARCH_IOMMU_DOMAINS_H
 
 enum {
-	GLOBAL_DOMAIN,
+	VIDEO_DOMAIN,
+	CAMERA_DOMAIN,
+	DISPLAY_DOMAIN,
+	ROTATOR_DOMAIN,
 	MAX_DOMAINS
 };
 
 enum {
 	VIDEO_FIRMWARE_POOL,
-	LOW_256MB_POOL,
-	HIGH_POOL,
+	VIDEO_MAIN_POOL,
+	GEN_POOL,
 };
 
 
@@ -48,8 +51,14 @@
 extern int msm_iommu_map_extra(struct iommu_domain *domain,
 						unsigned long start_iova,
 						unsigned long size,
+						unsigned long page_size,
 						int cached);
 
+extern void msm_iommu_unmap_extra(struct iommu_domain *domain,
+						unsigned long start_iova,
+						unsigned long size,
+						unsigned long page_size);
+
 #else
 static inline struct iommu_domain
 	*msm_get_iommu_domain(int subsys_id) { return NULL; }
@@ -84,10 +93,18 @@
 static inline int msm_iommu_map_extra(struct iommu_domain *domain,
 						unsigned long start_iova,
 						unsigned long size,
+						unsigned long page_size,
 						int cached)
 {
 	return -ENODEV;
 }
+
+static inline void msm_iommu_unmap_extra(struct iommu_domain *domain,
+						unsigned long start_iova,
+						unsigned long size,
+						unsigned long page_size)
+{
+}
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/ion.h b/arch/arm/mach-msm/include/mach/ion.h
index 4d12249..fffb552 100644
--- a/arch/arm/mach-msm/include/mach/ion.h
+++ b/arch/arm/mach-msm/include/mach/ion.h
@@ -20,4 +20,10 @@
 	ION_SMI_TYPE,
 };
 
+enum ion_permission_type {
+	IPT_TYPE_MM_CARVEOUT = 0,
+	IPT_TYPE_MFC_SHAREDMEM = 1,
+	IPT_TYPE_MDP_WRITEBACK = 2,
+};
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h
index 526a29a..77ce2bf 100644
--- a/arch/arm/mach-msm/include/mach/msm_fb.h
+++ b/arch/arm/mach-msm/include/mach/msm_fb.h
@@ -408,11 +408,12 @@
 extern int display_notifier_call_chain(unsigned long val, void *data);
 
 #define display_notifier(fn, pri) {                     \
-	static struct notifier_block fn##_nb =          \
-	{ .notifier_call = fn, .priority = pri };       \
-	register_display_notifier(&fn##_nb);		\
+       static struct notifier_block fn##_nb =          \
+       { .notifier_call = fn, .priority = pri };       \
+       register_display_notifier(&fn##_nb);            \
 }
 
+
 #if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR))
 /* For USB Projector to quick access the frame buffer info */
 struct msm_fb_info {
diff --git a/arch/arm/mach-msm/include/mach/msm_subsystem_map.h b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
new file mode 100644
index 0000000..ebb2327
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_subsystem_map.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ARCH_MACH_MSM_SUBSYSTEM_MAP_H
+#define __ARCH_MACH_MSM_SUBSYSTEM_MAP_H
+
+#include <linux/iommu.h>
+#include <mach/iommu_domains.h>
+
+/* map the physical address in the kernel vaddr space */
+#define MSM_SUBSYSTEM_MAP_KADDR		0x1
+/* map the physical address in the iova address space */
+#define MSM_SUBSYSTEM_MAP_IOVA		0x2
+/* ioremaps in the kernel address space are cached */
+#define	MSM_SUBSYSTEM_MAP_CACHED	0x4
+/* ioremaps in the kernel address space are uncached */
+#define MSM_SUBSYSTEM_MAP_UNCACHED	0x8
+/*
+ * Will map 2x the length requested.
+ */
+#define MSM_SUBSYSTEM_MAP_IOMMU_2X 0x10
+
+/*
+ * Shortcut flags for alignment.
+ * The flag must be equal to the alignment requested.
+ * e.g. for 8k alignment the flags must be (0x2000 | other flags)
+ */
+#define	MSM_SUBSYSTEM_ALIGN_IOVA_8K	SZ_8K
+#define MSM_SUBSYSTEM_ALIGN_IOVA_1M	SZ_1M
+
+
+enum msm_subsystem_id {
+	INVALID_SUBSYS_ID = -1,
+	MSM_SUBSYSTEM_VIDEO,
+	MSM_SUBSYSTEM_VIDEO_FWARE,
+	MSM_SUBSYSTEM_CAMERA,
+	MSM_SUBSYSTEM_DISPLAY,
+	MSM_SUBSYSTEM_ROTATOR,
+	MAX_SUBSYSTEM_ID
+};
+
+static inline int msm_subsystem_check_id(int subsys_id)
+{
+	return subsys_id > INVALID_SUBSYS_ID && subsys_id < MAX_SUBSYSTEM_ID;
+}
+
+struct msm_mapped_buffer {
+	/*
+	 * VA mapped in the kernel address space. This field shall be NULL if
+	 * MSM_SUBSYSTEM_MAP_KADDR was not passed to the map buffer function.
+	 */
+	void *vaddr;
+	/*
+	 * iovas mapped in the iommu address space. The ith entry of this array
+	 * corresponds to the iova mapped in the ith subsystem in the array
+	 * pased in to msm_subsystem_map_buffer. This field shall be NULL if
+	 * MSM_SUBSYSTEM_MAP_IOVA was not passed to the map buffer function,
+	 */
+	unsigned long *iova;
+};
+
+extern struct msm_mapped_buffer *msm_subsystem_map_buffer(
+				unsigned long phys,
+				unsigned int length,
+				unsigned int flags,
+				int *subsys_ids,
+				unsigned int nsubsys);
+
+extern int msm_subsystem_unmap_buffer(struct msm_mapped_buffer *buf);
+
+extern phys_addr_t msm_subsystem_check_iova_mapping(int subsys_id,
+						unsigned long iova);
+
+#endif /* __ARCH_MACH_MSM_SUBSYSTEM_MAP_H */
diff --git a/arch/arm/mach-msm/include/mach/scm-io.h b/arch/arm/mach-msm/include/mach/scm-io.h
new file mode 100644
index 0000000..5393da1
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/scm-io.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __MACH_SCM_IO_H
+#define __MACH_SCM_IO_H
+
+#include <linux/types.h>
+
+#ifdef CONFIG_MSM_SECURE_IO
+
+extern u32 secure_readl(void __iomem *c);
+extern void secure_writel(u32 v, void __iomem *c);
+
+#else
+
+#define secure_readl(c) readl(c)
+#define secure_writel(v, c) writel(v, c)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
new file mode 100644
index 0000000..7fbc8f6
--- /dev/null
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -0,0 +1,403 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <mach/msm_subsystem_map.h>
+#include <linux/memory_alloc.h>
+#include <linux/iommu.h>
+#include <linux/vmalloc.h>
+#include <asm/sizes.h>
+#include <asm/page.h>
+#include <linux/init.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
+#include <mach/socinfo.h>
+
+/* dummy 64K for overmapping */
+char iommu_dummy[2*SZ_64K-4];
+
+struct msm_iommu_domain {
+	/* iommu domain to map in */
+	struct iommu_domain *domain;
+	/* total number of allocations from this domain */
+	atomic_t allocation_cnt;
+	/* number of iova pools */
+	int npools;
+	/*
+	 * array of gen_pools for allocating iovas.
+	 * behavior is undefined if these overlap
+	 */
+	struct mem_pool *iova_pools;
+
+};
+
+
+struct {
+	char *name;
+	int  domain;
+} msm_iommu_ctx_names[] = {
+	/* Camera */
+	{
+		.name = "vpe_src",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "vpe_dst",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "vfe_imgwr",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "vfe_misc",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "ijpeg_src",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "ijpeg_dst",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "jpegd_src",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "jpegd_dst",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Rotator */
+	{
+		.name = "rot_src",
+		.domain = ROTATOR_DOMAIN,
+	},
+	/* Rotator */
+	{
+		.name = "rot_dst",
+		.domain = ROTATOR_DOMAIN,
+	},
+	/* Video */
+	{
+		.name = "vcodec_a_mm1",
+		.domain = VIDEO_DOMAIN,
+	},
+	/* Video */
+	{
+		.name = "vcodec_b_mm2",
+		.domain = VIDEO_DOMAIN,
+	},
+	/* Video */
+	{
+		.name = "vcodec_a_stream",
+		.domain = VIDEO_DOMAIN,
+	},
+};
+
+static struct mem_pool video_pools[] =  {
+	/*
+	 * Video hardware has the following requirements:
+	 * 1. All video addresses used by the video hardware must be at a higher
+	 *    address than video firmware address.
+	 * 2. Video hardware can only access a range of 256MB from the base of
+	 *    the video firmware.
+	*/
+	[VIDEO_FIRMWARE_POOL] =
+	/* Low addresses, intended for video firmware */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_16M - SZ_128K,
+		},
+	[VIDEO_MAIN_POOL] =
+	/* Main video pool */
+		{
+			.paddr	= SZ_16M,
+			.size	= SZ_256M - SZ_16M,
+		},
+	[GEN_POOL] =
+	/* Remaining address space up to 2G */
+		{
+			.paddr	= SZ_256M,
+			.size	= SZ_2G - SZ_256M,
+		},
+};
+
+static struct mem_pool camera_pools[] =  {
+	[GEN_POOL] =
+	/* One address space for camera */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_2G - SZ_128K,
+		},
+};
+
+static struct mem_pool display_pools[] =  {
+	[GEN_POOL] =
+	/* One address space for display */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_2G - SZ_128K,
+		},
+};
+
+static struct mem_pool rotator_pools[] =  {
+	[GEN_POOL] =
+	/* One address space for rotator */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_2G - SZ_128K,
+		},
+};
+
+static struct msm_iommu_domain msm_iommu_domains[] = {
+		[VIDEO_DOMAIN] = {
+			.iova_pools = video_pools,
+			.npools = ARRAY_SIZE(video_pools),
+		},
+		[CAMERA_DOMAIN] = {
+			.iova_pools = camera_pools,
+			.npools = ARRAY_SIZE(camera_pools),
+		},
+		[DISPLAY_DOMAIN] = {
+			.iova_pools = display_pools,
+			.npools = ARRAY_SIZE(display_pools),
+		},
+		[ROTATOR_DOMAIN] = {
+			.iova_pools = rotator_pools,
+			.npools = ARRAY_SIZE(rotator_pools),
+		},
+};
+
+int msm_iommu_map_extra(struct iommu_domain *domain,
+				unsigned long start_iova,
+				unsigned long size,
+				unsigned long page_size,
+				int cached)
+{
+	int i, ret_value = 0;
+	unsigned long order = get_order(page_size);
+	unsigned long aligned_size = ALIGN(size, page_size);
+	unsigned long nrpages = aligned_size >> (PAGE_SHIFT + order);
+	unsigned long phy_addr = ALIGN(virt_to_phys(iommu_dummy), page_size);
+	unsigned long temp_iova = start_iova;
+
+	for (i = 0; i < nrpages; i++) {
+		int ret = iommu_map(domain, temp_iova, phy_addr, order, cached);
+		if (ret) {
+			pr_err("%s: could not map %lx in domain %p, error: %d\n",
+				__func__, start_iova, domain, ret);
+			ret_value = -EAGAIN;
+			goto out;
+		}
+		temp_iova += page_size;
+	}
+	return ret_value;
+out:
+	for (; i > 0; --i) {
+		temp_iova -= page_size;
+		iommu_unmap(domain, start_iova, order);
+	}
+	return ret_value;
+}
+
+void msm_iommu_unmap_extra(struct iommu_domain *domain,
+				unsigned long start_iova,
+				unsigned long size,
+				unsigned long page_size)
+{
+	int i;
+	unsigned long order = get_order(page_size);
+	unsigned long aligned_size = ALIGN(size, page_size);
+	unsigned long nrpages =  aligned_size >> (PAGE_SHIFT + order);
+	unsigned long temp_iova = start_iova;
+
+	for (i = 0; i < nrpages; ++i) {
+		iommu_unmap(domain, temp_iova, order);
+		temp_iova += page_size;
+	}
+}
+
+
+struct iommu_domain *msm_get_iommu_domain(int domain_num)
+{
+	if (domain_num >= 0 && domain_num < MAX_DOMAINS)
+		return msm_iommu_domains[domain_num].domain;
+	else
+		return NULL;
+}
+
+static unsigned long subsystem_to_domain_tbl[] = {
+	VIDEO_DOMAIN,
+	VIDEO_DOMAIN,
+	CAMERA_DOMAIN,
+	DISPLAY_DOMAIN,
+	ROTATOR_DOMAIN,
+	0xFFFFFFFF
+};
+
+unsigned long msm_subsystem_get_domain_no(int subsys_id)
+{
+	if (subsys_id > INVALID_SUBSYS_ID && subsys_id <= MAX_SUBSYSTEM_ID &&
+	    subsys_id < ARRAY_SIZE(subsystem_to_domain_tbl))
+		return subsystem_to_domain_tbl[subsys_id];
+	else
+		return subsystem_to_domain_tbl[MAX_SUBSYSTEM_ID];
+}
+
+unsigned long msm_subsystem_get_partition_no(int subsys_id)
+{
+	switch (subsys_id) {
+	case MSM_SUBSYSTEM_VIDEO_FWARE:
+		return VIDEO_FIRMWARE_POOL;
+	case MSM_SUBSYSTEM_VIDEO:
+		return VIDEO_MAIN_POOL;
+	case MSM_SUBSYSTEM_CAMERA:
+	case MSM_SUBSYSTEM_DISPLAY:
+	case MSM_SUBSYSTEM_ROTATOR:
+		return GEN_POOL;
+	default:
+		return 0xFFFFFFFF;
+	}
+}
+
+unsigned long msm_allocate_iova_address(unsigned int iommu_domain,
+					unsigned int partition_no,
+					unsigned long size,
+					unsigned long align)
+{
+	struct mem_pool *pool;
+	unsigned long iova;
+
+	if (iommu_domain >= MAX_DOMAINS)
+		return 0;
+
+	if (partition_no >= msm_iommu_domains[iommu_domain].npools)
+		return 0;
+
+	pool = &msm_iommu_domains[iommu_domain].iova_pools[partition_no];
+
+	if (!pool->gpool)
+		return 0;
+
+	iova = gen_pool_alloc_aligned(pool->gpool, size, ilog2(align));
+	if (iova)
+		pool->free -= size;
+
+	return iova;
+}
+
+void msm_free_iova_address(unsigned long iova,
+			   unsigned int iommu_domain,
+			   unsigned int partition_no,
+			   unsigned long size)
+{
+	struct mem_pool *pool;
+
+	if (iommu_domain >= MAX_DOMAINS) {
+		WARN(1, "Invalid domain %d\n", iommu_domain);
+		return;
+	}
+
+	if (partition_no >= msm_iommu_domains[iommu_domain].npools) {
+		WARN(1, "Invalid partition %d for domain %d\n",
+			partition_no, iommu_domain);
+		return;
+	}
+
+	pool = &msm_iommu_domains[iommu_domain].iova_pools[partition_no];
+
+	if (!pool)
+		return;
+
+	pool->free += size;
+	gen_pool_free(pool->gpool, iova, size);
+}
+
+int msm_use_iommu()
+{
+	return iommu_found();
+}
+
+static int __init msm_subsystem_iommu_init(void)
+{
+	int i, j;
+
+	for (i = 0; i < ARRAY_SIZE(msm_iommu_domains); i++) {
+		msm_iommu_domains[i].domain = iommu_domain_alloc(0);
+		if (!msm_iommu_domains[i].domain)
+			continue;
+
+		for (j = 0; j < msm_iommu_domains[i].npools; j++) {
+			struct mem_pool *pool = &msm_iommu_domains[i].
+							iova_pools[j];
+			mutex_init(&pool->pool_mutex);
+			if (pool->size) {
+				pool->gpool = gen_pool_create(PAGE_SHIFT, -1);
+
+				if (!pool->gpool) {
+					pr_err("%s: could not allocate pool\n",
+						__func__);
+					pr_err("%s: domain %d iova space %d\n",
+						__func__, i, j);
+					continue;
+				}
+
+				if (gen_pool_add(pool->gpool, pool->paddr,
+						pool->size, -1)) {
+					pr_err("%s: could not add memory\n",
+						__func__);
+					pr_err("%s: domain %d pool %d\n",
+						__func__, i, j);
+					gen_pool_destroy(pool->gpool);
+					pool->gpool = NULL;
+					continue;
+				}
+			} else {
+				pool->gpool = NULL;
+			}
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_names); i++) {
+		int domain_idx;
+		struct device *ctx = msm_iommu_get_ctx(
+						msm_iommu_ctx_names[i].name);
+
+		if (!ctx)
+			continue;
+
+		domain_idx = msm_iommu_ctx_names[i].domain;
+
+		if (!msm_iommu_domains[domain_idx].domain)
+			continue;
+
+		if (iommu_attach_device(msm_iommu_domains[domain_idx].domain,
+					ctx)) {
+			WARN(1, "%s: could not attach domain %d to context %s."
+				" iommu programming will not occur.\n",
+				__func__, domain_idx,
+				msm_iommu_ctx_names[i].name);
+			continue;
+		}
+	}
+
+	return 0;
+}
+device_initcall(msm_subsystem_iommu_init);
diff --git a/arch/arm/mach-msm/msm_pm_qos.c b/arch/arm/mach-msm/msm_pm_qos.c
index e9ca886..145c721 100644
--- a/arch/arm/mach-msm/msm_pm_qos.c
+++ b/arch/arm/mach-msm/msm_pm_qos.c
@@ -20,17 +20,6 @@
 #include <linux/err.h>
 #include <mach/msm_reqs.h>
 
-struct pm_qos_request_list {
-        struct list_head list;
-        union {
-                s32 value;
-                s32 usec;
-                s32 kbps;
-        };
-        int pm_qos_class;
-};
-
-
 struct pm_qos_object {
         struct pm_qos_request_list requests;
         struct blocking_notifier_head *notifiers;
diff --git a/arch/arm/mach-msm/subsystem_map.c b/arch/arm/mach-msm/subsystem_map.c
new file mode 100644
index 0000000..d37da30
--- /dev/null
+++ b/arch/arm/mach-msm/subsystem_map.c
@@ -0,0 +1,506 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/memory_alloc.h>
+#include <linux/module.h>
+#include <mach/iommu.h>
+#include <mach/iommu_domains.h>
+#include <mach/msm_subsystem_map.h>
+
+struct msm_buffer_node {
+	struct rb_node rb_node_all_buffer;
+	struct rb_node rb_node_paddr;
+	struct msm_mapped_buffer *buf;
+	unsigned long length;
+	unsigned int *subsystems;
+	unsigned int nsubsys;
+	unsigned int phys;
+};
+
+static struct rb_root buffer_root;
+static struct rb_root phys_root;
+DEFINE_MUTEX(msm_buffer_mutex);
+
+static struct msm_buffer_node *find_buffer(void *key)
+{
+	struct rb_root *root = &buffer_root;
+	struct rb_node *p = root->rb_node;
+
+	mutex_lock(&msm_buffer_mutex);
+
+	while (p) {
+		struct msm_buffer_node *node;
+
+		node = rb_entry(p, struct msm_buffer_node, rb_node_all_buffer);
+		if (node->buf->vaddr) {
+			if (key < node->buf->vaddr)
+				p = p->rb_left;
+			else if (key > node->buf->vaddr)
+				p = p->rb_right;
+			else {
+				mutex_unlock(&msm_buffer_mutex);
+				return node;
+			}
+		} else {
+			if (key < (void *)node->buf)
+				p = p->rb_left;
+			else if (key > (void *)node->buf)
+				p = p->rb_right;
+			else {
+				mutex_unlock(&msm_buffer_mutex);
+				return node;
+			}
+		}
+	}
+	mutex_unlock(&msm_buffer_mutex);
+	return NULL;
+}
+
+static struct msm_buffer_node *find_buffer_phys(unsigned int phys)
+{
+	struct rb_root *root = &phys_root;
+	struct rb_node *p = root->rb_node;
+
+	mutex_lock(&msm_buffer_mutex);
+
+	while (p) {
+		struct msm_buffer_node *node;
+
+		node = rb_entry(p, struct msm_buffer_node, rb_node_paddr);
+		if (phys < node->phys)
+			p = p->rb_left;
+		else if (phys > node->phys)
+			p = p->rb_right;
+		else {
+			mutex_unlock(&msm_buffer_mutex);
+			return node;
+		}
+	}
+	mutex_unlock(&msm_buffer_mutex);
+	return NULL;
+
+}
+
+static int add_buffer(struct msm_buffer_node *node)
+{
+	struct rb_root *root = &buffer_root;
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+	void *key;
+
+	if (node->buf->vaddr)
+		key = node->buf->vaddr;
+	else
+		key = node->buf;
+
+	mutex_lock(&msm_buffer_mutex);
+	while (*p) {
+		struct msm_buffer_node *tmp;
+		parent = *p;
+
+		tmp = rb_entry(parent, struct msm_buffer_node,
+						rb_node_all_buffer);
+
+		if (tmp->buf->vaddr) {
+			if (key < tmp->buf->vaddr)
+				p = &(*p)->rb_left;
+			else if (key > tmp->buf->vaddr)
+				p = &(*p)->rb_right;
+			else {
+				WARN(1, "tried to add buffer twice! buf = %p"
+					" vaddr = %p iova = %p", tmp->buf,
+					tmp->buf->vaddr,
+					tmp->buf->iova);
+				mutex_unlock(&msm_buffer_mutex);
+				return -EINVAL;
+
+			}
+		} else {
+			if (key < (void *)tmp->buf)
+				p = &(*p)->rb_left;
+			else if (key > (void *)tmp->buf)
+				p = &(*p)->rb_right;
+			else {
+				WARN(1, "tried to add buffer twice! buf = %p"
+					" vaddr = %p iova = %p", tmp->buf,
+					tmp->buf->vaddr,
+					tmp->buf->iova);
+				mutex_unlock(&msm_buffer_mutex);
+				return -EINVAL;
+			}
+		}
+	}
+	rb_link_node(&node->rb_node_all_buffer, parent, p);
+	rb_insert_color(&node->rb_node_all_buffer, root);
+	mutex_unlock(&msm_buffer_mutex);
+	return 0;
+}
+
+static int add_buffer_phys(struct msm_buffer_node *node)
+{
+	struct rb_root *root = &phys_root;
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+
+	mutex_lock(&msm_buffer_mutex);
+	while (*p) {
+		struct msm_buffer_node *tmp;
+		parent = *p;
+
+		tmp = rb_entry(parent, struct msm_buffer_node, rb_node_paddr);
+
+			if (node->phys < tmp->phys)
+				p = &(*p)->rb_left;
+			else if (node->phys > tmp->phys)
+				p = &(*p)->rb_right;
+			else {
+				WARN(1, "tried to add buffer twice! buf = %p"
+					" vaddr = %p iova = %p", tmp->buf,
+					tmp->buf->vaddr,
+					tmp->buf->iova);
+				mutex_unlock(&msm_buffer_mutex);
+				return -EINVAL;
+
+			}
+	}
+	rb_link_node(&node->rb_node_paddr, parent, p);
+	rb_insert_color(&node->rb_node_paddr, root);
+	mutex_unlock(&msm_buffer_mutex);
+	return 0;
+}
+
+static int remove_buffer(struct msm_buffer_node *victim_node)
+{
+	struct rb_root *root = &buffer_root;
+
+	if (!victim_node)
+		return -EINVAL;
+
+	mutex_lock(&msm_buffer_mutex);
+	rb_erase(&victim_node->rb_node_all_buffer, root);
+	mutex_unlock(&msm_buffer_mutex);
+	return 0;
+}
+
+static int remove_buffer_phys(struct msm_buffer_node *victim_node)
+{
+	struct rb_root *root = &phys_root;
+
+	if (!victim_node)
+		return -EINVAL;
+
+	mutex_lock(&msm_buffer_mutex);
+	rb_erase(&victim_node->rb_node_paddr, root);
+	mutex_unlock(&msm_buffer_mutex);
+	return 0;
+}
+
+phys_addr_t msm_subsystem_check_iova_mapping(int subsys_id, unsigned long iova)
+{
+	struct iommu_domain *subsys_domain;
+
+	if (!msm_use_iommu())
+		/*
+		 * If there is no iommu, Just return the iova in this case.
+		 */
+		return iova;
+
+	subsys_domain = msm_get_iommu_domain(msm_subsystem_get_domain_no
+								(subsys_id));
+
+	return iommu_iova_to_phys(subsys_domain, iova);
+}
+EXPORT_SYMBOL(msm_subsystem_check_iova_mapping);
+
+struct msm_mapped_buffer *msm_subsystem_map_buffer(unsigned long phys,
+						unsigned int length,
+						unsigned int flags,
+						int *subsys_ids,
+						unsigned int nsubsys)
+{
+	struct msm_mapped_buffer *buf, *err;
+	struct msm_buffer_node *node;
+	int i = 0, j = 0, ret;
+	unsigned long iova_start = 0, temp_phys, temp_va = 0;
+	struct iommu_domain *d = NULL;
+	int map_size = length;
+
+	if (!((flags & MSM_SUBSYSTEM_MAP_KADDR) ||
+		(flags & MSM_SUBSYSTEM_MAP_IOVA))) {
+		pr_warn("%s: no mapping flag was specified. The caller"
+			" should explicitly specify what to map in the"
+			" flags.\n", __func__);
+		err = ERR_PTR(-EINVAL);
+		goto outret;
+	}
+
+	buf = kzalloc(sizeof(*buf), GFP_ATOMIC);
+	if (!buf) {
+		err = ERR_PTR(-ENOMEM);
+		goto outret;
+	}
+
+	node = kzalloc(sizeof(*node), GFP_ATOMIC);
+	if (!node) {
+		err = ERR_PTR(-ENOMEM);
+		goto outkfreebuf;
+	}
+
+	node->phys = phys;
+
+	if (flags & MSM_SUBSYSTEM_MAP_KADDR) {
+		struct msm_buffer_node *old_buffer;
+
+		old_buffer = find_buffer_phys(phys);
+
+		if (old_buffer) {
+			WARN(1, "%s: Attempting to map %lx twice in the kernel"
+				" virtual space. Don't do that!\n", __func__,
+				phys);
+			err = ERR_PTR(-EINVAL);
+			goto outkfreenode;
+		}
+
+		if (flags & MSM_SUBSYSTEM_MAP_CACHED)
+			buf->vaddr = ioremap(phys, length);
+		else if (flags & MSM_SUBSYSTEM_MAP_KADDR)
+			buf->vaddr = ioremap_nocache(phys, length);
+		else {
+			pr_warn("%s: no cachability flag was indicated. Caller"
+				" must specify a cachability flag.\n",
+				__func__);
+			err = ERR_PTR(-EINVAL);
+			goto outkfreenode;
+		}
+
+		if (!buf->vaddr) {
+			pr_err("%s: could not ioremap\n", __func__);
+			err = ERR_PTR(-EINVAL);
+			goto outkfreenode;
+		}
+
+		if (add_buffer_phys(node)) {
+			err = ERR_PTR(-EINVAL);
+			goto outiounmap;
+		}
+	}
+
+	if ((flags & MSM_SUBSYSTEM_MAP_IOVA) && subsys_ids) {
+		int min_align;
+
+		length = round_up(length, SZ_4K);
+
+		if (flags & MSM_SUBSYSTEM_MAP_IOMMU_2X)
+			map_size = 2 * length;
+		else
+			map_size = length;
+
+		buf->iova = kzalloc(sizeof(unsigned long)*nsubsys, GFP_ATOMIC);
+		if (!buf->iova) {
+			err = ERR_PTR(-ENOMEM);
+			goto outremovephys;
+		}
+
+		/*
+		 * The alignment must be specified as the exact value wanted
+		 * e.g. 8k alignment must pass (0x2000 | other flags)
+		 */
+		min_align = flags & ~(SZ_4K - 1);
+
+		for (i = 0; i < nsubsys; i++) {
+			unsigned int domain_no, partition_no;
+
+			if (!msm_use_iommu()) {
+				buf->iova[i] = phys;
+				continue;
+			}
+
+			d = msm_get_iommu_domain(
+				msm_subsystem_get_domain_no(subsys_ids[i]));
+
+			if (!d) {
+				pr_err("%s: could not get domain for subsystem"
+					" %d\n", __func__, subsys_ids[i]);
+				continue;
+			}
+
+			domain_no = msm_subsystem_get_domain_no(subsys_ids[i]);
+			partition_no = msm_subsystem_get_partition_no(
+								subsys_ids[i]);
+
+			iova_start = msm_allocate_iova_address(domain_no,
+						partition_no,
+						map_size,
+						max(min_align, SZ_4K));
+
+			if (!iova_start) {
+				pr_err("%s: could not allocate iova address\n",
+					__func__);
+				continue;
+			}
+
+			temp_phys = phys;
+			temp_va = iova_start;
+			for (j = length; j > 0; j -= SZ_4K,
+					temp_phys += SZ_4K,
+					temp_va += SZ_4K) {
+				ret = iommu_map(d, temp_va, temp_phys,
+						get_order(SZ_4K),
+						(IOMMU_READ | IOMMU_WRITE));
+				if (ret) {
+					pr_err("%s: could not map iommu for"
+						" domain %p, iova %lx,"
+						" phys %lx\n", __func__, d,
+						temp_va, temp_phys);
+					err = ERR_PTR(-EINVAL);
+					goto outdomain;
+				}
+			}
+			buf->iova[i] = iova_start;
+
+			if (flags & MSM_SUBSYSTEM_MAP_IOMMU_2X)
+				msm_iommu_map_extra
+					(d, temp_va, length, SZ_4K,
+					(IOMMU_READ | IOMMU_WRITE));
+		}
+
+	}
+
+	node->buf = buf;
+	node->subsystems = subsys_ids;
+	node->length = map_size;
+	node->nsubsys = nsubsys;
+
+	if (add_buffer(node)) {
+		err = ERR_PTR(-EINVAL);
+		goto outiova;
+	}
+
+	return buf;
+
+outiova:
+	if (flags & MSM_SUBSYSTEM_MAP_IOVA)
+		iommu_unmap(d, temp_va, get_order(SZ_4K));
+outdomain:
+	if (flags & MSM_SUBSYSTEM_MAP_IOVA) {
+		/* Unmap the rest of the current domain, i */
+		for (j -= SZ_4K, temp_va -= SZ_4K;
+			j > 0; temp_va -= SZ_4K, j -= SZ_4K)
+			iommu_unmap(d, temp_va, get_order(SZ_4K));
+
+		/* Unmap all the other domains */
+		for (i--; i >= 0; i--) {
+			unsigned int domain_no, partition_no;
+			if (!msm_use_iommu())
+				continue;
+			domain_no = msm_subsystem_get_domain_no(subsys_ids[i]);
+			partition_no = msm_subsystem_get_partition_no(
+								subsys_ids[i]);
+
+			temp_va = buf->iova[i];
+			for (j = length; j > 0; j -= SZ_4K,
+						temp_va += SZ_4K)
+				iommu_unmap(d, temp_va, get_order(SZ_4K));
+			msm_free_iova_address(buf->iova[i], domain_no,
+					partition_no, length);
+		}
+
+		kfree(buf->iova);
+	}
+
+outremovephys:
+	if (flags & MSM_SUBSYSTEM_MAP_KADDR)
+		remove_buffer_phys(node);
+outiounmap:
+	if (flags & MSM_SUBSYSTEM_MAP_KADDR)
+		iounmap(buf->vaddr);
+outkfreenode:
+	kfree(node);
+outkfreebuf:
+	kfree(buf);
+outret:
+	return err;
+}
+EXPORT_SYMBOL(msm_subsystem_map_buffer);
+
+int msm_subsystem_unmap_buffer(struct msm_mapped_buffer *buf)
+{
+	struct msm_buffer_node *node;
+	int i, j, ret;
+	unsigned long temp_va;
+
+	if (IS_ERR_OR_NULL(buf))
+		goto out;
+
+	if (buf->vaddr)
+		node = find_buffer(buf->vaddr);
+	else
+		node = find_buffer(buf);
+
+	if (!node)
+		goto out;
+
+	if (node->buf != buf) {
+		pr_err("%s: caller must pass in the same buffer structure"
+			" returned from map_buffer when freeding\n", __func__);
+		goto out;
+	}
+
+	if (buf->iova) {
+		if (msm_use_iommu())
+			for (i = 0; i < node->nsubsys; i++) {
+				struct iommu_domain *subsys_domain;
+				unsigned int domain_no, partition_no;
+
+				subsys_domain = msm_get_iommu_domain(
+						msm_subsystem_get_domain_no(
+						node->subsystems[i]));
+
+				domain_no = msm_subsystem_get_domain_no(
+							node->subsystems[i]);
+				partition_no = msm_subsystem_get_partition_no(
+							node->subsystems[i]);
+
+				temp_va = buf->iova[i];
+				for (j = node->length; j > 0; j -= SZ_4K,
+					temp_va += SZ_4K) {
+					ret = iommu_unmap(subsys_domain,
+							temp_va,
+							get_order(SZ_4K));
+					WARN(ret, "iommu_unmap returned a "
+						" non-zero value.\n");
+				}
+				msm_free_iova_address(buf->iova[i], domain_no,
+						partition_no, node->length);
+			}
+		kfree(buf->iova);
+
+	}
+
+	if (buf->vaddr) {
+		remove_buffer_phys(node);
+		iounmap(buf->vaddr);
+	}
+
+	remove_buffer(node);
+	kfree(node);
+	kfree(buf);
+
+	return 0;
+out:
+	return -EINVAL;
+}
+EXPORT_SYMBOL(msm_subsystem_unmap_buffer);
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index baafb17..ce351bf 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -800,7 +800,7 @@
 
 		if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
 			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
-			if (get_fb_phys_info(start, len, fb_num))
+			if (get_fb_phys_info(start, len, fb_num, DISPLAY_SUBSYSTEM_ID))
 				ret = -1;
 			else {
 				*p_file = file;
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 820cc61..d38528a 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -17,7 +17,6 @@
 #include <linux/sched.h>
 
 #include <mach/socinfo.h>
-#include <mach/internal_power_rail.h>
 
 #include "kgsl.h"
 #include "kgsl_pwrscale.h"
@@ -94,8 +93,6 @@
 		.pwrctrl = {
 			.regulator_name = "fs_gfx3d",
 			.irq_name = KGSL_3D0_IRQ,
-			.src_clk_name = "grp_src_clk",
-			.pwr_rail = PWR_RAIL_GRP_CLK,
 		},
 		.mutex = __MUTEX_INITIALIZER(device_3d0.dev.mutex),
 		.state = KGSL_STATE_INIT,
@@ -269,6 +266,7 @@
 }
 
 static void adreno_setstate(struct kgsl_device *device,
+					unsigned int context_id,
 					uint32_t flags)
 {
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
@@ -276,6 +274,8 @@
 	unsigned int *cmds = &link[0];
 	int sizedwords = 0;
 	unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */
+	struct kgsl_context *context;
+	struct adreno_context *adreno_ctx = NULL;
 
 	/*
 	 * If possible, then set the state via the command stream to avoid
@@ -284,6 +284,9 @@
 	 * easier to filter out the mmu accesses from the dump
 	 */
 	if (!kgsl_cff_dump_enable && adreno_dev->drawctxt_active) {
+		context = idr_find(&device->context_idr, context_id);
+		adreno_ctx = context->devctxt;
+
 		if (flags & KGSL_MMUFLAGS_PTUPDATE) {
 			/* wait for graphics pipe to be idle */
 			*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
@@ -356,7 +359,8 @@
 			sizedwords += 2;
 		}
 
-		adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+		adreno_ringbuffer_issuecmds(device, adreno_ctx,
+					KGSL_CMD_FLAGS_PMODE,
 					&link[0], sizedwords);
 	} else {
 		kgsl_mmu_device_setstate(device, flags);
@@ -466,6 +470,8 @@
 	kgsl_pwrscale_init(device);
 	kgsl_pwrscale_attach_policy(device, ADRENO_DEFAULT_PWRSCALE_POLICY);
 
+	INIT_WORK(&device->print_fault_ib, adreno_print_fault_ib_work);
+
 	device->flags &= ~KGSL_FLAGS_SOFT_RESET;
 	return 0;
 
@@ -499,7 +505,8 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	int init_reftimestamp = 0x7fffffff;
 
-	kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
+	if (KGSL_STATE_DUMP_AND_RECOVER != device->state)
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 
 	/* Power up the device */
 	kgsl_pwrctrl_enable(device);
@@ -592,13 +599,15 @@
 	device->ftbl->irqctrl(device, 1);
 
 	status = adreno_ringbuffer_start(&adreno_dev->ringbuffer, init_ram);
-	if (status != 0)
-		goto error_irq_off;
 
-	mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
-	return status;
+	if (status == 0) {
+		/* While recovery is on we do not want timer to
+		 * fire and attempt to change any device state */
+		if (KGSL_STATE_DUMP_AND_RECOVER != device->state)
+			mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
+		return 0;
+	}
 
-error_irq_off:
 	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
 	kgsl_mmu_stop(device);
 error_clk_off:
@@ -627,53 +636,74 @@
 	return 0;
 }
 
+static void adreno_mark_context_status(struct kgsl_device *device,
+					int recovery_status)
+{
+	struct kgsl_context *context;
+	int next = 0;
+	/*
+	 * Set the reset status of all contexts to
+	 * INNOCENT_CONTEXT_RESET_EXT except for the bad context
+	 * since thats the guilty party, if recovery failed then
+	 * mark all as guilty
+	 */
+	while ((context = idr_get_next(&device->context_idr, &next))) {
+		struct adreno_context *adreno_context = context->devctxt;
+		if (recovery_status) {
+			context->reset_status =
+					KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT;
+			adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
+		} else if (KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT !=
+			context->reset_status) {
+			if (adreno_context->flags & (CTXT_FLAGS_GPU_HANG ||
+				CTXT_FLAGS_GPU_HANG_RECOVERED))
+				context->reset_status =
+				KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT;
+			else
+				context->reset_status =
+				KGSL_CTX_STAT_INNOCENT_CONTEXT_RESET_EXT;
+		}
+		next = next + 1;
+	}
+}
+
 static int
-adreno_recover_hang(struct kgsl_device *device)
+adreno_recover_hang(struct kgsl_device *device,
+			struct adreno_recovery_data *rec_data)
 {
 	int ret;
-	unsigned int *rb_buffer;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
 	unsigned int timestamp;
-	unsigned int num_rb_contents;
-	unsigned int bad_context;
-	unsigned int reftimestamp;
-	unsigned int enable_ts;
-	unsigned int soptimestamp;
-	unsigned int eoptimestamp;
-	struct adreno_context *drawctxt;
 	struct kgsl_context *context;
-	int next = 0;
+	struct adreno_context *adreno_context;
 
-	KGSL_DRV_ERR(device, "Starting recovery from 3D GPU hang....\n");
-	rb_buffer = vmalloc(rb->buffer_desc.size);
-	if (!rb_buffer) {
-		KGSL_MEM_ERR(device,
-			"Failed to allocate memory for recovery: %x\n",
-			rb->buffer_desc.size);
-		return -ENOMEM;
+	KGSL_DRV_ERR(device,
+	"Starting recovery from 3D GPU hang. Recovery parameters: IB1: 0x%X, "
+	"Bad context_id: %u, global_eop: 0x%x\n", rec_data->ib1,
+	rec_data->context_id, rec_data->global_eop);
+
+	context = idr_find(&device->context_idr, rec_data->context_id);
+	if (context == NULL) {
+		KGSL_DRV_ERR(device, "Last context unknown id:%d\n",
+				rec_data->context_id);
+		rec_data->context_id = 0;
+	} else {
+		adreno_context = context->devctxt;
+		adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
 	}
-	/* Extract valid contents from rb which can stil be executed after
+	/* Extract valid contents from rb which can still be executed after
 	 * hang */
-	ret = adreno_ringbuffer_extract(rb, rb_buffer, &num_rb_contents);
+	ret = adreno_ringbuffer_extract(rb, rec_data);
 	if (ret)
 		goto done;
+
 	timestamp = rb->timestamp;
-	KGSL_DRV_ERR(device, "Last issued timestamp: %x\n", timestamp);
-	kgsl_sharedmem_readl(&device->memstore, &bad_context,
-				KGSL_DEVICE_MEMSTORE_OFFSET(current_context));
-	kgsl_sharedmem_readl(&device->memstore, &reftimestamp,
-				KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts));
-	kgsl_sharedmem_readl(&device->memstore, &enable_ts,
-				KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable));
-	kgsl_sharedmem_readl(&device->memstore, &soptimestamp,
-				KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp));
-	kgsl_sharedmem_readl(&device->memstore, &eoptimestamp,
-				KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp));
+	KGSL_DRV_ERR(device, "Last issued global timestamp: %x\n", timestamp);
+
 	/* Make sure memory is synchronized before restarting the GPU */
 	mb();
-	KGSL_CTXT_ERR(device,
-		"Context that caused a GPU hang: %x\n", bad_context);
+
 	/* restart device */
 	ret = adreno_stop(device);
 	if (ret)
@@ -682,66 +712,76 @@
 	if (ret)
 		goto done;
 	KGSL_DRV_ERR(device, "Device has been restarted after hang\n");
-	/* Restore timestamp states */
-	kgsl_sharedmem_writel(&device->memstore,
-			KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp),
-			soptimestamp);
-	kgsl_sharedmem_writel(&device->memstore,
-			KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp),
-			eoptimestamp);
-	kgsl_sharedmem_writel(&device->memstore,
-			KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp),
-			soptimestamp);
-	if (num_rb_contents) {
-		kgsl_sharedmem_writel(&device->memstore,
-			KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
-			reftimestamp);
-		kgsl_sharedmem_writel(&device->memstore,
-			KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
-			enable_ts);
-	}
-	/* Make sure all writes are posted before the GPU reads them */
-	wmb();
-	/* Mark the invalid context so no more commands are accepted from
-	 * that context */
-
-	drawctxt = (struct adreno_context *) bad_context;
-
-	KGSL_CTXT_ERR(device,
-		"Context that caused a GPU hang: %x\n", bad_context);
-
-	drawctxt->flags |= CTXT_FLAGS_GPU_HANG;
-
-	/*
-	 * Set the reset status of all contexts to
-	 * INNOCENT_CONTEXT_RESET_EXT except for the bad context
-	 * since thats the guilty party
-	 */
-	while ((context = idr_get_next(&device->context_idr, &next))) {
-		if (KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT !=
-			context->reset_status) {
-			if (context->devctxt != drawctxt)
-				context->reset_status =
-				KGSL_CTX_STAT_INNOCENT_CONTEXT_RESET_EXT;
-			else
-				context->reset_status =
-				KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT;
-		}
-		next = next + 1;
-	}
 
 	/* Restore valid commands in ringbuffer */
-	adreno_ringbuffer_restore(rb, rb_buffer, num_rb_contents);
+	adreno_ringbuffer_restore(rb, rec_data->rb_buffer, rec_data->rb_size);
 	rb->timestamp = timestamp;
+
+	/* wait for idle */
+	ret = adreno_idle(device, KGSL_TIMEOUT_DEFAULT);
 done:
-	vfree(rb_buffer);
+	kgsl_sharedmem_writel(&device->memstore,
+			KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp),
+			rb->timestamp);
+	adreno_mark_context_status(device, ret);
 	return ret;
 }
 
-static int
-adreno_dump_and_recover(struct kgsl_device *device)
+static void adreno_destroy_recovery_data(struct adreno_recovery_data *rec_data)
+{
+	vfree(rec_data->rb_buffer);
+	vfree(rec_data->bad_rb_buffer);
+}
+
+static int adreno_setup_recovery_data(struct kgsl_device *device,
+					struct adreno_recovery_data *rec_data)
+{
+	int ret = 0;
+	unsigned int ib1_sz, ib2_sz;
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
+
+	memset(rec_data, 0, sizeof(*rec_data));
+
+	adreno_regread(device, REG_CP_IB1_BUFSZ, &ib1_sz);
+	adreno_regread(device, REG_CP_IB2_BUFSZ, &ib2_sz);
+	if (ib1_sz || ib2_sz)
+		adreno_regread(device, REG_CP_IB1_BASE, &rec_data->ib1);
+
+	kgsl_sharedmem_readl(&device->memstore, &rec_data->context_id,
+			KGSL_DEVICE_MEMSTORE_OFFSET(current_context));
+
+	kgsl_sharedmem_readl(&device->memstore,
+				&rec_data->global_eop,
+				KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp));
+
+	rec_data->rb_buffer = vmalloc(rb->buffer_desc.size);
+	if (!rec_data->rb_buffer) {
+		KGSL_MEM_ERR(device, "vmalloc(%d) failed\n",
+				rb->buffer_desc.size);
+		return -ENOMEM;
+	}
+
+	rec_data->bad_rb_buffer = vmalloc(rb->buffer_desc.size);
+	if (!rec_data->bad_rb_buffer) {
+		KGSL_MEM_ERR(device, "vmalloc(%d) failed\n",
+				rb->buffer_desc.size);
+		ret = -ENOMEM;
+		goto done;
+	}
+
+done:
+	if (ret) {
+		vfree(rec_data->rb_buffer);
+		vfree(rec_data->bad_rb_buffer);
+	}
+	return ret;
+}
+
+int adreno_dump_and_recover(struct kgsl_device *device)
 {
 	int result = -ETIMEDOUT;
+	struct adreno_recovery_data rec_data;
 
 	if (device->state == KGSL_STATE_HUNG)
 		goto done;
@@ -756,7 +796,8 @@
 		INIT_COMPLETION(device->recovery_gate);
 		/* Detected a hang */
 
-
+		/* Get the recovery data as soon as hang is detected */
+		result = adreno_setup_recovery_data(device, &rec_data);
 		/*
 		 * Trigger an automatic dump of the state to
 		 * the console
@@ -769,16 +810,20 @@
 		 */
 		kgsl_device_snapshot(device, 1);
 
-		result = adreno_recover_hang(device);
-		if (result)
+		result = adreno_recover_hang(device, &rec_data);
+		adreno_destroy_recovery_data(&rec_data);
+		if (result) {
 			kgsl_pwrctrl_set_state(device, KGSL_STATE_HUNG);
-		else
+		} else {
 			kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
+			mod_timer(&device->idle_timer, jiffies + FIRST_TIMEOUT);
+		}
 		complete_all(&device->recovery_gate);
 	}
 done:
 	return result;
 }
+EXPORT_SYMBOL(adreno_dump_and_recover);
 
 static int adreno_getproperty(struct kgsl_device *device,
 				enum kgsl_property_type type,
@@ -893,7 +938,11 @@
 	unsigned int rbbm_status;
 	unsigned long wait_timeout =
 		msecs_to_jiffies(adreno_dev->wait_timeout);
-	unsigned long wait_time = jiffies + wait_timeout;
+	unsigned long wait_time;
+	unsigned long wait_time_part;
+	unsigned int msecs;
+	unsigned int msecs_first;
+	unsigned int msecs_part;
 
 	kgsl_cffdump_regpoll(device->id, REG_RBBM_STATUS << 2,
 		0x00000000, 0x80000000);
@@ -902,8 +951,18 @@
 	 */
 retry:
 	if (rb->flags & KGSL_FLAGS_STARTED) {
+		msecs = adreno_dev->wait_timeout;
+		msecs_first = (msecs <= 100) ? ((msecs + 4) / 5) : 100;
+		msecs_part = (msecs - msecs_first + 3) / 4;
+		wait_time = jiffies + wait_timeout;
+		wait_time_part = jiffies + msecs_to_jiffies(msecs_first);
 		adreno_poke(device);
 		do {
+			if (time_after(jiffies, wait_time_part)) {
+				adreno_poke(device);
+				wait_time_part = jiffies +
+					msecs_to_jiffies(msecs_part);
+			}
 			GSL_RB_GET_READPTR(rb, &rb->rptr);
 			if (time_after(jiffies, wait_time)) {
 				KGSL_DRV_ERR(device, "rptr: %x, wptr: %x\n",
@@ -923,7 +982,8 @@
 
 err:
 	KGSL_DRV_ERR(device, "spun too long waiting for RB to idle\n");
-	if (!adreno_dump_and_recover(device)) {
+	if (KGSL_STATE_DUMP_AND_RECOVER != device->state &&
+		!adreno_dump_and_recover(device)) {
 		wait_time = jiffies + wait_timeout;
 		goto retry;
 	}
@@ -1091,6 +1151,8 @@
 	int status;
 	unsigned int ref_ts, enableflag;
 
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
 	status = kgsl_check_timestamp(device, timestamp);
 	if (!status) {
 		mutex_lock(&device->mutex);
@@ -1123,8 +1185,15 @@
 			* get an interrupt */
 			cmds[0] = cp_type3_packet(CP_NOP, 1);
 			cmds[1] = 0;
-			adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
-				&cmds[0], 2);
+
+			if (adreno_dev->drawctxt_active)
+				adreno_ringbuffer_issuecmds(device,
+					adreno_dev->drawctxt_active,
+					KGSL_CMD_FLAGS_NONE, &cmds[0], 2);
+			else
+				/* We would never call this function if there
+				 * was no active contexts running */
+				BUG();
 		}
 		mutex_unlock(&device->mutex);
 	}
@@ -1218,6 +1287,14 @@
 		}
 		/*this wait timed out*/
 	}
+
+	/* Check if timestamp has retired here because we may have hit
+	 * recovery which can take some time and cause waiting threads
+	 * to timeout
+	 */
+	if (kgsl_check_timestamp(device, timestamp))
+		goto done;
+
 	status = -ETIMEDOUT;
 	KGSL_DRV_ERR(device,
 		     "Device hang detected while waiting for timestamp: %x,"
@@ -1225,10 +1302,9 @@
 		      timestamp, adreno_dev->ringbuffer.timestamp,
 		      adreno_dev->ringbuffer.wptr);
 	if (!adreno_dump_and_recover(device)) {
-		/* wait for idle after recovery as the
-		 * timestamp that this process wanted
-		 * to wait on may be invalid */
-		if (!adreno_idle(device, KGSL_TIMEOUT_DEFAULT))
+		/* The timestamp that this process wanted
+		 * to wait on may be invalid or expired now
+		 * after successful recovery */
 			status = 0;
 	}
 done:
@@ -1339,17 +1415,10 @@
 	adreno_dev->gpudev->irq_control(adreno_dev, state);
 }
 
-static unsigned int adreno_gpuid(struct kgsl_device *device,
-	unsigned int *chipid)
+static unsigned int adreno_gpuid(struct kgsl_device *device)
 {
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 
-	/* Some applications need to know the chip ID too, so pass
-	 * that as a parameter */
-
-	if (chipid != NULL)
-		*chipid = adreno_dev->chip_id;
-
 	/* Standard KGSL gpuid format:
 	 * top word is 0x0002 for 2D or 0x0003 for 3D
 	 * Bottom word is core specific identifer
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 1259507..9c75f6d 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -27,11 +27,12 @@
 #define KGSL_CMD_FLAGS_NONE             0x00000000
 #define KGSL_CMD_FLAGS_PMODE		0x00000001
 #define KGSL_CMD_FLAGS_NO_TS_CMP	0x00000002
-#define KGSL_CMD_FLAGS_NOT_KERNEL_CMD	0x00000004
 
 /* Command identifiers */
 #define KGSL_CONTEXT_TO_MEM_IDENTIFIER	0xDEADBEEF
 #define KGSL_CMD_IDENTIFIER		0xFEEDFACE
+#define KGSL_START_OF_IB_IDENTIFIER    0x2EADEABE
+#define KGSL_END_OF_IB_IDENTIFIER      0x2ABEDEAD
 
 #ifdef CONFIG_MSM_SCM
 #define ADRENO_DEFAULT_PWRSCALE_POLICY  (&kgsl_pwrscale_policy_tz)
@@ -85,12 +86,36 @@
 	int (*ctxt_create)(struct adreno_device *, struct adreno_context *);
 	void (*ctxt_save)(struct adreno_device *, struct adreno_context *);
 	void (*ctxt_restore)(struct adreno_device *, struct adreno_context *);
-	void (*ctxt_draw_workaround)(struct adreno_device *);
+	void (*ctxt_draw_workaround)(struct adreno_device *, struct adreno_context *);
 	irqreturn_t (*irq_handler)(struct adreno_device *);
 	void (*irq_control)(struct adreno_device *, int);
 	void * (*snapshot)(struct adreno_device *, void *, int *, int);
 };
 
+/*
+ * struct adreno_recovery_data - Structure that contains all information to
+ * perform gpu recovery from hangs
+ * @ib1 - IB1 that the GPU was executing when hang happened
+ * @context_id - Context which caused the hang
+ * @global_eop - eoptimestamp at time of hang
+ * @rb_buffer - Buffer that holds the commands from good contexts
+ * @rb_size - Number of valid dwords in rb_buffer
+ * @bad_rb_buffer - Buffer that holds commands from the hanging context
+ * bad_rb_size - Number of valid dwords in bad_rb_buffer
+ * @last_valid_ctx_id - The last context from which commands were placed in
+ * ringbuffer before the GPU hung
+ */
+struct adreno_recovery_data {
+	unsigned int ib1;
+	unsigned int context_id;
+	unsigned int global_eop;
+	unsigned int *rb_buffer;
+	unsigned int rb_size;
+	unsigned int *bad_rb_buffer;
+	unsigned int bad_rb_size;
+	unsigned int last_valid_ctx_id;
+};
+
 extern struct adreno_gpudev adreno_a2xx_gpudev;
 
 /* A2XX register sets defined in adreno_a2xx.c */
@@ -116,6 +141,8 @@
 void *adreno_snapshot(struct kgsl_device *device, void *snapshot, int *remain,
 		int hang);
 
+int adreno_dump_and_recover(struct kgsl_device *device);
+
 static inline int adreno_is_a200(struct adreno_device *adreno_dev)
 {
 	return (adreno_dev->gpurev == ADRENO_REV_A200);
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 62628e4..9efd587 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1421,55 +1421,45 @@
 	return ret;
 }
 
-static void a2xx_drawctxt_workaround(struct adreno_device *adreno_dev)
+static void a2xx_drawctxt_draw_workaround(struct adreno_device *adreno_dev,
+			struct adreno_context *context)
 {
 	struct kgsl_device *device = &adreno_dev->dev;
 	unsigned int cmd[11];
 	unsigned int *cmds = &cmd[0];
 
-	if (adreno_is_a225(adreno_dev)) {
-		adreno_dev->gpudev->ctx_switches_since_last_draw++;
-		/* If there have been > than
-		 * ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW calls to context
-		 * switches w/o gmem being saved then we need to execute
-		 * this workaround */
-		if (adreno_dev->gpudev->ctx_switches_since_last_draw >
-				ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW)
-			adreno_dev->gpudev->ctx_switches_since_last_draw = 0;
-		else
-			return;
-		/*
-		 * Issue an empty draw call to avoid possible hangs due to
-		 * repeated idles without intervening draw calls.
-		 * On adreno 225 the PC block has a cache that is only
-		 * flushed on draw calls and repeated idles can make it
-		 * overflow. The gmem save path contains draw calls so
-		 * this workaround isn't needed there.
-		 */
-		*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
-		*cmds++ = (0x4 << 16) | (REG_PA_SU_SC_MODE_CNTL - 0x2000);
-		*cmds++ = 0;
-		*cmds++ = cp_type3_packet(CP_DRAW_INDX, 5);
-		*cmds++ = 0;
-		*cmds++ = 1<<14;
-		*cmds++ = 0;
-		*cmds++ = device->mmu.setstate_memory.gpuaddr;
-		*cmds++ = 0;
-		*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-		*cmds++ = 0x00000000;
-	} else {
-		/* On Adreno 20x/220, if the events for shader space reuse
-		 * gets dropped, the CP block would wait indefinitely.
-		 * Sending CP_SET_SHADER_BASES packet unblocks the CP from
-		 * this wait.
-		 */
-		*cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
-		*cmds++ = adreno_encode_istore_size(adreno_dev)
-					| adreno_dev->pix_shader_start;
-	}
+	adreno_dev->gpudev->ctx_switches_since_last_draw++;
+	/* If there have been > than ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW
+	 * calls to context switches w/o gmem being saved then we need to
+	 * execute this workaround */
+	if (adreno_dev->gpudev->ctx_switches_since_last_draw >
+		ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW)
+		adreno_dev->gpudev->ctx_switches_since_last_draw = 0;
+	else
+		return;
+	/*
+	 * Issue an empty draw call to avoid possible hangs due to
+	 * repeated idles without intervening draw calls.
+	 * On adreno 225 the PC block has a cache that is only
+	 * flushed on draw calls and repeated idles can make it
+	 * overflow. The gmem save path contains draw calls so
+	 * this workaround isn't needed there.
+	 */
+	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
+	*cmds++ = (0x4 << 16) | (REG_PA_SU_SC_MODE_CNTL - 0x2000);
+	*cmds++ = 0;
+	*cmds++ = cp_type3_packet(CP_DRAW_INDX, 5);
+	*cmds++ = 0;
+	*cmds++ = 1<<14;
+	*cmds++ = 0;
+	*cmds++ = device->mmu.setstate_memory.gpuaddr;
+	*cmds++ = 0;
+	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
+	*cmds++ = 0x00000000;
 
-	adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
-			&cmd[0], cmds - cmd);
+	adreno_ringbuffer_issuecmds(device, context,
+				    KGSL_CMD_FLAGS_PMODE,
+				    &cmd[0], 11);
 }
 
 static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
@@ -1487,12 +1477,13 @@
 	if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
 
 		/* save registers and constants. */
-		adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+		adreno_ringbuffer_issuecmds(device, context,
+			KGSL_CMD_FLAGS_NONE,
 			context->reg_save, 3);
 
 		if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
 			/* save shader partitioning and instructions. */
-			adreno_ringbuffer_issuecmds(device,
+			adreno_ringbuffer_issuecmds(device, context,
 				KGSL_CMD_FLAGS_PMODE,
 				context->shader_save, 3);
 
@@ -1500,7 +1491,8 @@
 			 * fixup shader partitioning parameter for
 			 *  SET_SHADER_BASES.
 			 */
-			adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+			adreno_ringbuffer_issuecmds(device, context,
+				KGSL_CMD_FLAGS_NONE,
 				context->shader_fixup, 3);
 
 			context->flags |= CTXT_FLAGS_SHADER_RESTORE;
@@ -1512,19 +1504,21 @@
 		/* save gmem.
 		 * (note: changes shader. shader must already be saved.)
 		 */
-		adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+		adreno_ringbuffer_issuecmds(device, context,
+			KGSL_CMD_FLAGS_PMODE,
 			context->context_gmem_shadow.gmem_save, 3);
 
 		/* Restore TP0_CHICKEN */
 		if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
-			adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+			adreno_ringbuffer_issuecmds(device, context,
+				KGSL_CMD_FLAGS_NONE,
 				context->chicken_restore, 3);
 		}
 		adreno_dev->gpudev->ctx_switches_since_last_draw = 0;
 
 		context->flags |= CTXT_FLAGS_GMEM_RESTORE;
-	} else if (adreno_is_a2xx(adreno_dev))
-		a2xx_drawctxt_workaround(adreno_dev);
+	} else if (adreno_is_a225(adreno_dev))
+		a2xx_drawctxt_draw_workaround(adreno_dev, context);
 }
 
 static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
@@ -1535,7 +1529,8 @@
 
 	if (context == NULL) {
 		/* No context - set the default apgetable and thats it */
-		kgsl_mmu_setstate(device, device->mmu.defaultpagetable);
+		kgsl_mmu_setstate(device, device->mmu.defaultpagetable,
+				adreno_dev->drawctxt_active->id);
 		return;
 	}
 
@@ -1547,8 +1542,9 @@
 	cmds[3] = device->memstore.gpuaddr +
 		KGSL_DEVICE_MEMSTORE_OFFSET(current_context);
 	cmds[4] = (unsigned int) context;
-	adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
-	kgsl_mmu_setstate(device, context->pagetable);
+	adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE,
+					cmds, 5);
+	kgsl_mmu_setstate(device, context->pagetable, context->id);
 
 #ifndef CONFIG_MSM_KGSL_CFF_DUMP_NO_CONTEXT_MEM_DUMP
 	kgsl_cffdump_syncmem(NULL, &context->gpustate,
@@ -1560,12 +1556,14 @@
 	 *  (note: changes shader. shader must not already be restored.)
 	 */
 	if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
-		adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
+		adreno_ringbuffer_issuecmds(device, context,
+			KGSL_CMD_FLAGS_PMODE,
 			context->context_gmem_shadow.gmem_restore, 3);
 
 		if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
 			/* Restore TP0_CHICKEN */
-			adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
+			adreno_ringbuffer_issuecmds(device, context,
+				KGSL_CMD_FLAGS_NONE,
 				context->chicken_restore, 3);
 		}
 
@@ -1575,12 +1573,12 @@
 	if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
 
 		/* restore registers and constants. */
-		adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
-			context->reg_restore, 3);
+		adreno_ringbuffer_issuecmds(device, context,
+			KGSL_CMD_FLAGS_NONE, context->reg_restore, 3);
 
 		/* restore shader instructions & partitioning. */
 		if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
-			adreno_ringbuffer_issuecmds(device,
+			adreno_ringbuffer_issuecmds(device, context,
 				KGSL_CMD_FLAGS_NONE,
 				context->shader_restore, 3);
 		}
@@ -1589,8 +1587,8 @@
 	if (adreno_is_a20x(adreno_dev)) {
 		cmds[0] = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1);
 		cmds[1] = context->bin_base_offset;
-		adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
-			cmds, 2);
+		adreno_ringbuffer_issuecmds(device, context,
+			KGSL_CMD_FLAGS_NONE, cmds, 2);
 	}
 }
 
@@ -1785,7 +1783,7 @@
 	.ctxt_create = a2xx_drawctxt_create,
 	.ctxt_save = a2xx_drawctxt_save,
 	.ctxt_restore = a2xx_drawctxt_restore,
-	.ctxt_draw_workaround = a2xx_drawctxt_workaround,
+	.ctxt_draw_workaround = a2xx_drawctxt_draw_workaround,
 	.irq_handler = a2xx_irq_handler,
 	.irq_control = a2xx_irq_control,
 	.snapshot = a2xx_snapshot,
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index 566efa1..81d3419 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -24,6 +24,7 @@
 
 unsigned int kgsl_cff_dump_enable;
 int kgsl_pm_regs_enabled;
+int adreno_ib_dump_on_pagef_enabled;
 
 static struct dentry *pm_d_debugfs;
 
@@ -60,6 +61,21 @@
 			pm_regs_enabled_get,
 			pm_regs_enabled_set, "%llu\n");
 
+static int ib_dump_on_pagef_enabled_get(void *data, u64 *val)
+{
+	*val = adreno_ib_dump_on_pagef_enabled;
+	return 0;
+}
+
+static int ib_dump_on_pagef_enabled_set(void *data, u64 val)
+{
+	adreno_ib_dump_on_pagef_enabled = val ? 1 : 0;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ib_dump_on_pagef_enabled_fops,
+			ib_dump_on_pagef_enabled_get,
+			ib_dump_on_pagef_enabled_set, "%llu\n");
 
 static int kgsl_cff_dump_enable_set(void *data, u64 val)
 {
@@ -359,4 +375,7 @@
 			    &pm_dump_fops);
 	debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
 			    &pm_regs_enabled_fops);
+
+	debugfs_create_file("ib_dump_on_pagefault", 0644, device->d_debugfs,
+				device, &ib_dump_on_pagef_enabled_fops);
 }
diff --git a/drivers/gpu/msm/adreno_debugfs.h b/drivers/gpu/msm/adreno_debugfs.h
index 0356ac6..be73ef7 100644
--- a/drivers/gpu/msm/adreno_debugfs.h
+++ b/drivers/gpu/msm/adreno_debugfs.h
@@ -18,6 +18,7 @@
 int adreno_debugfs_init(struct kgsl_device *device);
 
 extern int kgsl_pm_regs_enabled;
+extern int adreno_ib_dump_on_pagef_enabled;
 
 static inline int kgsl_pmregs_enabled(void)
 {
@@ -35,6 +36,12 @@
 	/* If debugfs is turned off, then always print registers */
 	return 1;
 }
+
 #endif
 
+static inline int is_adreno_ib_dump_on_pagef_enabled(struct kgsl_device *device)
+{
+	return adreno_ib_dump_on_pagef_enabled;
+}
+
 #endif /* __ADRENO_DEBUGFS_H */
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index ab70ece..990af5f 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -138,6 +138,7 @@
 
 	drawctxt->pagetable = pagetable;
 	drawctxt->bin_base_offset = 0;
+	drawctxt->id = context->id;
 
 	if (flags & KGSL_CONTEXT_PREAMBLE)
 		drawctxt->flags |= CTXT_FLAGS_PREAMBLE;
@@ -171,11 +172,13 @@
 			  struct kgsl_context *context)
 {
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-	struct adreno_context *drawctxt = context->devctxt;
+	struct adreno_context *drawctxt;
 
 	if (context == NULL || context->devctxt == NULL)
 		return;
 
+	drawctxt = context->devctxt;
+
 	/* deactivate context */
 	if (adreno_dev->drawctxt_active == drawctxt) {
 		/* no need to save GMEM or shader, the context is
@@ -247,7 +250,7 @@
 		if (adreno_dev->gpudev->ctxt_draw_workaround &&
 			adreno_is_a225(adreno_dev))
 				adreno_dev->gpudev->ctxt_draw_workaround(
-					adreno_dev);
+					adreno_dev, drawctxt);
 		return;
 	}
 
@@ -258,6 +261,8 @@
 	adreno_dev->gpudev->ctxt_save(adreno_dev, adreno_dev->drawctxt_active);
 
 	/* Set the new context */
-	adreno_dev->drawctxt_active = drawctxt;
 	adreno_dev->gpudev->ctxt_restore(adreno_dev, drawctxt);
+	adreno_dev->drawctxt_active = drawctxt;
 }
+
+
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index 3047660..763d0a1 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -40,6 +40,12 @@
 #define CTXT_FLAGS_GPU_HANG		0x00008000
 /* Specifies there is no need to save GMEM */
 #define CTXT_FLAGS_NOGMEMALLOC          0x00010000
+/* Trash state for context */
+#define CTXT_FLAGS_TRASHSTATE		0x00020000
+/* per context timestamps enabled */
+#define CTXT_FLAGS_PER_CONTEXT_TS	0x00040000
+/* Context has caused a GPU hang and recovered properly */
+#define CTXT_FLAGS_GPU_HANG_RECOVERED	0x00008000
 
 struct kgsl_device;
 struct adreno_device;
@@ -69,6 +75,7 @@
 };
 
 struct adreno_context {
+	unsigned int id;
 	uint32_t flags;
 	struct kgsl_pagetable *pagetable;
 	struct kgsl_memdesc gpustate;
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 63f5caa..af4bb85 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -156,7 +156,7 @@
 	}
 }
 
-static void dump_ib(struct kgsl_device *device, char* buffId, uint32_t pt_base,
+void dump_ib(struct kgsl_device *device, char *buffId, uint32_t pt_base,
 	uint32_t base_offset, uint32_t ib_base, uint32_t ib_size, bool dump)
 {
 	uint8_t *base_addr = adreno_convertaddr(device, pt_base,
@@ -172,15 +172,7 @@
 			base_addr ? "" : " [Invalid]");
 }
 
-#define IB_LIST_SIZE	64
-struct ib_list {
-	int count;
-	uint32_t bases[IB_LIST_SIZE];
-	uint32_t sizes[IB_LIST_SIZE];
-	uint32_t offsets[IB_LIST_SIZE];
-};
-
-static void dump_ib1(struct kgsl_device *device, uint32_t pt_base,
+void dump_ib1(struct kgsl_device *device, uint32_t pt_base,
 			uint32_t base_offset,
 			uint32_t ib1_base, uint32_t ib1_size,
 			struct ib_list *ib_list, bool dump)
@@ -547,7 +539,8 @@
 		" %08X\n", r1, r2, pt_base);
 	cur_pt_base = pt_base;
 
-	KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ", KGSL_PAGETABLE_SIZE);
+	KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ",
+		kgsl_mmu_get_ptsize());
 
 	kgsl_regread(device, MH_MMU_TRAN_ERROR, &r1);
 	KGSL_LOG_DUMP(device, "        TRAN_ERROR = %08X\n", r1);
diff --git a/drivers/gpu/msm/adreno_postmortem.h b/drivers/gpu/msm/adreno_postmortem.h
index b677800..c652558 100644
--- a/drivers/gpu/msm/adreno_postmortem.h
+++ b/drivers/gpu/msm/adreno_postmortem.h
@@ -16,6 +16,22 @@
 
 struct kgsl_device;
 
+#define IB_LIST_SIZE    64
+struct ib_list {
+	int count;
+	uint32_t bases[IB_LIST_SIZE];
+	uint32_t sizes[IB_LIST_SIZE];
+	uint32_t offsets[IB_LIST_SIZE];
+};
+
 int adreno_postmortem_dump(struct kgsl_device *device, int manual);
 
+void dump_ib(struct kgsl_device *device, char *buffId, uint32_t pt_base,
+	uint32_t base_offset, uint32_t ib_base, uint32_t ib_size, bool dump);
+
+void dump_ib1(struct kgsl_device *device, uint32_t pt_base,
+			uint32_t base_offset,
+			uint32_t ib1_base, uint32_t ib1_size,
+			struct ib_list *ib_list, bool dump);
+
 #endif /* __ADRENO_POSTMORTEM_H */
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 57883fd..f9d9df1 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -23,6 +23,7 @@
 #include "adreno_pm4types.h"
 #include "adreno_ringbuffer.h"
 #include "adreno_debugfs.h"
+#include "adreno_postmortem.h"
 
 #include "a2xx_reg.h"
 
@@ -70,6 +71,9 @@
 	unsigned int freecmds;
 	unsigned int *cmds;
 	uint cmds_gpu;
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(rb->device);
+	unsigned long wait_timeout = msecs_to_jiffies(adreno_dev->wait_timeout);
+	unsigned long wait_time;
 
 	/* if wptr ahead, fill the remaining with NOPs */
 	if (wptr_ahead) {
@@ -96,15 +100,58 @@
 		rb->wptr = 0;
 	}
 
+	wait_time = jiffies + wait_timeout;
 	/* wait for space in ringbuffer */
-	do {
+	while (1) {
 		GSL_RB_GET_READPTR(rb, &rb->rptr);
 
 		freecmds = rb->rptr - rb->wptr;
 
-	} while ((freecmds != 0) && (freecmds <= numcmds));
+		if (freecmds == 0 || freecmds > numcmds)
+			break;
+
+		if (time_after(jiffies, wait_time)) {
+			KGSL_DRV_ERR(rb->device,
+			"Timed out while waiting for freespace in ringbuffer "
+			"rptr: 0x%x, wptr: 0x%x\n", rb->rptr, rb->wptr);
+			if (!adreno_dump_and_recover(rb->device))
+				wait_time = jiffies + wait_timeout;
+			else
+				/* GPU is hung and we cannot recover */
+				BUG();
+		}
+	}
 }
 
+static unsigned int find_faulting_ib1_size(struct adreno_ringbuffer *rb,
+				unsigned int rptr, unsigned int ib1)
+{
+	unsigned int value;
+	unsigned int temp_rptr = rptr * sizeof(unsigned int);
+	unsigned int rb_size = rb->buffer_desc.size;
+
+	do {
+		temp_rptr = adreno_ringbuffer_dec_wrapped(temp_rptr, rb_size);
+		kgsl_sharedmem_readl(&rb->buffer_desc, &value, temp_rptr);
+
+		if (ib1 == value) {
+			temp_rptr = adreno_ringbuffer_dec_wrapped(temp_rptr,
+								rb_size);
+			kgsl_sharedmem_readl(&rb->buffer_desc, &value,
+						temp_rptr);
+			if (adreno_cmd_is_ib(value)) {
+				temp_rptr += 2 * sizeof(unsigned int);
+				kgsl_sharedmem_readl(&rb->buffer_desc, &value,
+						temp_rptr);
+				return value;
+			} else {
+				temp_rptr += sizeof(unsigned int);
+			}
+		}
+	} while (temp_rptr != rptr);
+
+	return 0;
+}
 
 static unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb,
 					     unsigned int numcmds)
@@ -461,6 +508,7 @@
 
 static uint32_t
 adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
+				struct adreno_context *context,
 				unsigned int flags, unsigned int *cmds,
 				int sizedwords)
 {
@@ -475,16 +523,25 @@
 	*/
 	total_sizedwords += flags & KGSL_CMD_FLAGS_PMODE ? 4 : 0;
 	total_sizedwords += !(flags & KGSL_CMD_FLAGS_NO_TS_CMP) ? 7 : 0;
-	total_sizedwords += !(flags & KGSL_CMD_FLAGS_NOT_KERNEL_CMD) ? 2 : 0;
+	/* 2 dwords to store the start of command sequence */
+	total_sizedwords += 2;
 
 	ringcmds = adreno_ringbuffer_allocspace(rb, total_sizedwords);
+	/* GPU may hang during space allocation, if thats the case the current
+	 * context may have hung the GPU */
+	if (context->flags & CTXT_FLAGS_GPU_HANG) {
+		KGSL_CTXT_WARN(rb->device,
+		"Context %p caused a gpu hang. Will not accept commands for context %d\n",
+		context, context->id);
+		return rb->timestamp;
+	}
+
 	rcmd_gpu = rb->buffer_desc.gpuaddr
 		+ sizeof(uint)*(rb->wptr-total_sizedwords);
 
-	if (!(flags & KGSL_CMD_FLAGS_NOT_KERNEL_CMD)) {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_IDENTIFIER);
-	}
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
+	GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_IDENTIFIER);
+
 	if (flags & KGSL_CMD_FLAGS_PMODE) {
 		/* disable protected mode error checking */
 		GSL_RB_WRITE(ringcmds, rcmd_gpu,
@@ -541,6 +598,7 @@
 
 void
 adreno_ringbuffer_issuecmds(struct kgsl_device *device,
+						struct adreno_context *drawctxt,
 						unsigned int flags,
 						unsigned int *cmds,
 						int sizedwords)
@@ -550,7 +608,8 @@
 
 	if (device->state & KGSL_STATE_HUNG)
 		return;
-	adreno_ringbuffer_addcmds(rb, flags, cmds, sizedwords);
+
+	adreno_ringbuffer_addcmds(rb, drawctxt, flags, cmds, sizedwords);
 }
 
 static bool _parse_ibs(struct kgsl_device_private *dev_priv, uint gpuaddr,
@@ -802,14 +861,14 @@
 		*cmds++ = ibdesc[i].sizedwords;
 	}
 
-	kgsl_setstate(device,
+	kgsl_setstate(device, context->id,
 		      kgsl_mmu_pt_get_flags(device->mmu.hwpagetable,
-					device->id));
+			device->id));
 
 	adreno_drawctxt_switch(adreno_dev, drawctxt, flags);
 
 	*timestamp = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer,
-					KGSL_CMD_FLAGS_NOT_KERNEL_CMD,
+					drawctxt, 0,
 					&link[0], (cmds - link));
 
 	KGSL_CMD_INFO(device, "ctxt %d g %08x numibs %d ts %d\n",
@@ -829,185 +888,329 @@
 	return 0;
 }
 
-int adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
-				unsigned int *temp_rb_buffer,
-				int *rb_size)
+static int _find_start_of_cmd_seq(struct adreno_ringbuffer *rb,
+					unsigned int *ptr,
+					bool inc)
 {
-	struct kgsl_device *device = rb->device;
-	unsigned int rb_rptr;
-	unsigned int retired_timestamp;
-	unsigned int temp_idx = 0;
-	unsigned int value;
+	int status = -EINVAL;
 	unsigned int val1;
-	unsigned int val2;
-	unsigned int val3;
-	unsigned int copy_rb_contents = 0;
-	unsigned int cur_context;
-	unsigned int j;
+	unsigned int size = rb->buffer_desc.size;
+	unsigned int start_ptr = *ptr;
 
-	GSL_RB_GET_READPTR(rb, &rb->rptr);
-
-	retired_timestamp = device->ftbl->readtimestamp(device,
-		KGSL_TIMESTAMP_RETIRED);
-	KGSL_DRV_ERR(device, "GPU successfully executed till ts: %x\n",
-			retired_timestamp);
-	/*
-	 * We need to go back in history by 4 dwords from the current location
-	 * of read pointer as 4 dwords are read to match the end of a command.
-	 * Also, take care of wrap around when moving back
-	 */
-	if (rb->rptr >= 4)
-		rb_rptr = (rb->rptr - 4) * sizeof(unsigned int);
-	else
-		rb_rptr = rb->buffer_desc.size -
-			((4 - rb->rptr) * sizeof(unsigned int));
-	/* Read the rb contents going backwards to locate end of last
-	 * sucessfully executed command */
-	while ((rb_rptr / sizeof(unsigned int)) != rb->wptr) {
-		kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
-		if (value == retired_timestamp) {
-			rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
-							rb->buffer_desc.size);
-			kgsl_sharedmem_readl(&rb->buffer_desc, &val1, rb_rptr);
-			rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
-							rb->buffer_desc.size);
-			kgsl_sharedmem_readl(&rb->buffer_desc, &val2, rb_rptr);
-			rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
-							rb->buffer_desc.size);
-			kgsl_sharedmem_readl(&rb->buffer_desc, &val3, rb_rptr);
-			/* match the pattern found at the end of a command */
-			if ((val1 == 2 &&
-				val2 == cp_type3_packet(CP_INTERRUPT, 1)
-				&& val3 == CP_INT_CNTL__RB_INT_MASK) ||
-				(val1 == cp_type3_packet(CP_EVENT_WRITE, 3)
-				&& val2 == CACHE_FLUSH_TS &&
-				val3 == (rb->device->memstore.gpuaddr +
-				KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp)))) {
-				rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
-							rb->buffer_desc.size);
-				KGSL_DRV_ERR(device,
-					"Found end of last executed "
-					"command at offset: %x\n",
-					rb_rptr / sizeof(unsigned int));
+	while ((start_ptr / sizeof(unsigned int)) != rb->wptr) {
+		if (inc)
+			start_ptr = adreno_ringbuffer_inc_wrapped(start_ptr,
+									size);
+		else
+			start_ptr = adreno_ringbuffer_dec_wrapped(start_ptr,
+									size);
+		kgsl_sharedmem_readl(&rb->buffer_desc, &val1, start_ptr);
+		if (KGSL_CMD_IDENTIFIER == val1) {
+			if ((start_ptr / sizeof(unsigned int)) != rb->wptr)
+				start_ptr = adreno_ringbuffer_dec_wrapped(
+							start_ptr, size);
+				*ptr = start_ptr;
+				status = 0;
 				break;
-			} else {
-				if (rb_rptr < (3 * sizeof(unsigned int)))
-					rb_rptr = rb->buffer_desc.size -
-						(3 * sizeof(unsigned int))
-							+ rb_rptr;
-				else
-					rb_rptr -= (3 * sizeof(unsigned int));
+		}
+	}
+	return status;
+}
+
+static int _find_cmd_seq_after_eop_ts(struct adreno_ringbuffer *rb,
+					unsigned int *rb_rptr,
+					unsigned int global_eop,
+					bool inc)
+{
+	int status = -EINVAL;
+	unsigned int temp_rb_rptr = *rb_rptr;
+	unsigned int size = rb->buffer_desc.size;
+	unsigned int val[3];
+	int i = 0;
+	bool check = false;
+
+	if (inc && temp_rb_rptr / sizeof(unsigned int) != rb->wptr)
+		return status;
+
+	do {
+		/* when decrementing we need to decrement first and
+		 * then read make sure we cover all the data */
+		if (!inc)
+			temp_rb_rptr = adreno_ringbuffer_dec_wrapped(
+					temp_rb_rptr, size);
+		kgsl_sharedmem_readl(&rb->buffer_desc, &val[i],
+					temp_rb_rptr);
+
+		if (check && ((inc && val[i] == global_eop) ||
+			(!inc && (val[i] ==
+			cp_type3_packet(CP_MEM_WRITE, 2) ||
+			val[i] == CACHE_FLUSH_TS)))) {
+			/* decrement i, i.e i = (i - 1 + 3) % 3 if
+			 * we are going forward, else increment i */
+			i = (i + 2) % 3;
+			if (val[i] == rb->device->memstore.gpuaddr +
+				KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp)) {
+				int j = ((i + 2) % 3);
+				if ((inc && (val[j] == CACHE_FLUSH_TS ||
+						val[j] == cp_type3_packet(
+							CP_MEM_WRITE, 2))) ||
+					(!inc && val[j] == global_eop)) {
+						/* Found the global eop */
+						status = 0;
+						break;
+				}
 			}
+			/* if no match found then increment i again
+			 * since we decremented before matching */
+			i = (i + 1) % 3;
+		}
+		if (inc)
+			temp_rb_rptr = adreno_ringbuffer_inc_wrapped(
+						temp_rb_rptr, size);
+
+		i = (i + 1) % 3;
+		if (2 == i)
+			check = true;
+	} while (temp_rb_rptr / sizeof(unsigned int) != rb->wptr);
+	/* temp_rb_rptr points to the command stream after global eop,
+	 * move backward till the start of command sequence */
+	if (!status) {
+		status = _find_start_of_cmd_seq(rb, &temp_rb_rptr, false);
+		if (!status) {
+			*rb_rptr = temp_rb_rptr;
+			KGSL_DRV_ERR(rb->device,
+			"Offset of cmd sequence after eop timestamp: 0x%x\n",
+			temp_rb_rptr / sizeof(unsigned int));
+		}
+	}
+	return status;
+}
+
+static int _find_hanging_ib_sequence(struct adreno_ringbuffer *rb,
+				unsigned int *rb_rptr,
+				unsigned int ib1)
+{
+	int status = -EINVAL;
+	unsigned int temp_rb_rptr = *rb_rptr;
+	unsigned int size = rb->buffer_desc.size;
+	unsigned int val[2];
+	int i = 0;
+	bool check = false;
+	bool ctx_switch = false;
+
+	while (temp_rb_rptr / sizeof(unsigned int) != rb->wptr) {
+		kgsl_sharedmem_readl(&rb->buffer_desc, &val[i], temp_rb_rptr);
+
+		if (check && val[i] == ib1) {
+			/* decrement i, i.e i = (i - 1 + 2) % 2 */
+			i = (i + 1) % 2;
+			if (adreno_cmd_is_ib(val[i])) {
+				/* go till start of command sequence */
+				status = _find_start_of_cmd_seq(rb,
+						&temp_rb_rptr, false);
+				KGSL_DRV_ERR(rb->device,
+				"Found the hanging IB at offset 0x%x\n",
+				temp_rb_rptr / sizeof(unsigned int));
+				break;
+			}
+			/* if no match the increment i since we decremented
+			 * before checking */
+			i = (i + 1) % 2;
+		}
+		/* Make sure you do not encounter a context switch twice, we can
+		 * encounter it once for the bad context as the start of search
+		 * can point to the context switch */
+		if (val[i] == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
+			if (ctx_switch) {
+				KGSL_DRV_ERR(rb->device,
+				"Context switch encountered before bad "
+				"IB found\n");
+				break;
+			}
+			ctx_switch = true;
+		}
+		i = (i + 1) % 2;
+		if (1 == i)
+			check = true;
+		temp_rb_rptr = adreno_ringbuffer_inc_wrapped(temp_rb_rptr,
+								size);
+	}
+	if  (!status)
+		*rb_rptr = temp_rb_rptr;
+	return status;
+}
+
+static void _turn_preamble_on_for_ib_seq(struct adreno_ringbuffer *rb,
+				unsigned int rb_rptr)
+{
+	unsigned int temp_rb_rptr = rb_rptr;
+	unsigned int size = rb->buffer_desc.size;
+	unsigned int val[2];
+	int i = 0;
+	bool check = false;
+	bool cmd_start = false;
+
+	/* Go till the start of the ib sequence and turn on preamble */
+	while (temp_rb_rptr / sizeof(unsigned int) != rb->wptr) {
+		kgsl_sharedmem_readl(&rb->buffer_desc, &val[i], temp_rb_rptr);
+		if (check && KGSL_START_OF_IB_IDENTIFIER == val[i]) {
+			/* decrement i */
+			i = (i + 1) % 2;
+			if (val[i] == cp_nop_packet(4)) {
+				temp_rb_rptr = adreno_ringbuffer_dec_wrapped(
+						temp_rb_rptr, size);
+				kgsl_sharedmem_writel(&rb->buffer_desc,
+					temp_rb_rptr, cp_nop_packet(1));
+			}
+			KGSL_DRV_ERR(rb->device,
+			"Turned preamble on at offset 0x%x\n",
+			temp_rb_rptr / 4);
+			break;
+		}
+		/* If you reach beginning of next command sequence then exit
+		 * First command encountered is the current one so don't break
+		 * on that. */
+		if (KGSL_CMD_IDENTIFIER == val[i]) {
+			if (cmd_start)
+				break;
+			cmd_start = true;
 		}
 
-		if (rb_rptr == 0)
-			rb_rptr = rb->buffer_desc.size - sizeof(unsigned int);
-		else
-			rb_rptr -= sizeof(unsigned int);
+		i = (i + 1) % 2;
+		if (1 == i)
+			check = true;
+		temp_rb_rptr = adreno_ringbuffer_inc_wrapped(temp_rb_rptr,
+								size);
 	}
+}
 
-	if ((rb_rptr / sizeof(unsigned int)) == rb->wptr) {
-		KGSL_DRV_ERR(device,
-			"GPU recovery from hang not possible because last"
-			" successful timestamp is overwritten\n");
-		return -EINVAL;
-	}
-	/* rb_rptr is now pointing to the first dword of the command following
-	 * the last sucessfully executed command sequence. Assumption is that
-	 * GPU is hung in the command sequence pointed by rb_rptr */
-	/* make sure the GPU is not hung in a command submitted by kgsl
-	 * itself */
-	kgsl_sharedmem_readl(&rb->buffer_desc, &val1, rb_rptr);
-	kgsl_sharedmem_readl(&rb->buffer_desc, &val2,
-				adreno_ringbuffer_inc_wrapped(rb_rptr,
-							rb->buffer_desc.size));
-	if (val1 == cp_nop_packet(1) && val2 == KGSL_CMD_IDENTIFIER) {
-		KGSL_DRV_ERR(device,
-			"GPU recovery from hang not possible because "
-			"of hang in kgsl command\n");
-		return -EINVAL;
-	}
+static void _copy_valid_rb_content(struct adreno_ringbuffer *rb,
+		unsigned int rb_rptr, unsigned int *temp_rb_buffer,
+		int *rb_size, unsigned int *bad_rb_buffer,
+		int *bad_rb_size,
+		int *last_valid_ctx_id)
+{
+	unsigned int good_rb_idx = 0, cmd_start_idx = 0;
+	unsigned int val1 = 0;
+	struct kgsl_context *k_ctxt;
+	struct adreno_context *a_ctxt;
+	unsigned int bad_rb_idx = 0;
+	int copy_rb_contents = 0;
+	unsigned int temp_rb_rptr;
+	unsigned int size = rb->buffer_desc.size;
+	unsigned int good_cmd_start_idx = 0;
 
-	/* current_context is the context that is presently active in the
-	 * GPU, i.e the context in which the hang is caused */
-	kgsl_sharedmem_readl(&device->memstore, &cur_context,
-		KGSL_DEVICE_MEMSTORE_OFFSET(current_context));
+	/* Walk the rb from the context switch. Omit any commands
+	 * for an invalid context. */
 	while ((rb_rptr / sizeof(unsigned int)) != rb->wptr) {
-		kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
-		rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
-						rb->buffer_desc.size);
+		kgsl_sharedmem_readl(&rb->buffer_desc, &val1, rb_rptr);
+
+		if (KGSL_CMD_IDENTIFIER == val1) {
+			/* Start is the NOP dword that comes before
+			 * KGSL_CMD_IDENTIFIER */
+			cmd_start_idx = bad_rb_idx - 1;
+			if (copy_rb_contents)
+				good_cmd_start_idx = good_rb_idx - 1;
+		}
+
 		/* check for context switch indicator */
-		if (value == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
-			kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
-			rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
-							rb->buffer_desc.size);
-			BUG_ON(value != cp_type3_packet(CP_MEM_WRITE, 2));
-			kgsl_sharedmem_readl(&rb->buffer_desc, &val1, rb_rptr);
-			rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
-							rb->buffer_desc.size);
-			BUG_ON(val1 != (device->memstore.gpuaddr +
-				KGSL_DEVICE_MEMSTORE_OFFSET(current_context)));
-			kgsl_sharedmem_readl(&rb->buffer_desc, &value, rb_rptr);
-			rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr,
-							rb->buffer_desc.size);
+		if (val1 == KGSL_CONTEXT_TO_MEM_IDENTIFIER) {
+			unsigned int temp_idx, val2;
+			/* increment by 3 to get to the context_id */
+			temp_rb_rptr = rb_rptr + (3 * sizeof(unsigned int)) %
+					size;
+			kgsl_sharedmem_readl(&rb->buffer_desc, &val2,
+						temp_rb_rptr);
 
-			/*
-			 * If other context switches were already lost and
-			 * and the current context is the one that is hanging,
-			 * then we cannot recover.  Print an error message
-			 * and leave.
-			 */
-
-			if ((copy_rb_contents == 0) && (value == cur_context)) {
-				KGSL_DRV_ERR(device, "GPU recovery could not "
-					"find the previous context\n");
-				return -EINVAL;
-			}
-
-			/*
-			 * If we were copying the commands and got to this point
-			 * then we need to remove the 3 commands that appear
-			 * before KGSL_CONTEXT_TO_MEM_IDENTIFIER
-			 */
-			if (temp_idx)
-				temp_idx -= 3;
 			/* if context switches to a context that did not cause
 			 * hang then start saving the rb contents as those
 			 * commands can be executed */
-			if (value != cur_context) {
+			k_ctxt = idr_find(&rb->device->context_idr, val2);
+			if (k_ctxt) {
+				a_ctxt = k_ctxt->devctxt;
+
+			/* If we are changing to a good context and were not
+			 * copying commands then copy over commands to the good
+			 * context */
+			if (!copy_rb_contents && ((k_ctxt &&
+				!(a_ctxt->flags & CTXT_FLAGS_GPU_HANG)) ||
+				!k_ctxt)) {
+				for (temp_idx = cmd_start_idx;
+					temp_idx < bad_rb_idx;
+					temp_idx++)
+					temp_rb_buffer[good_rb_idx++] =
+						bad_rb_buffer[temp_idx];
+				*last_valid_ctx_id = val2;
 				copy_rb_contents = 1;
-				temp_rb_buffer[temp_idx++] = cp_nop_packet(1);
-				temp_rb_buffer[temp_idx++] =
-						KGSL_CMD_IDENTIFIER;
-				temp_rb_buffer[temp_idx++] = cp_nop_packet(1);
-				temp_rb_buffer[temp_idx++] =
-						KGSL_CONTEXT_TO_MEM_IDENTIFIER;
-				temp_rb_buffer[temp_idx++] =
-					cp_type3_packet(CP_MEM_WRITE, 2);
-				temp_rb_buffer[temp_idx++] = val1;
-				temp_rb_buffer[temp_idx++] = value;
-			} else {
+			} else if (copy_rb_contents && k_ctxt &&
+				(a_ctxt->flags & CTXT_FLAGS_GPU_HANG)) {
+				/* If we are changing to bad context then remove
+				 * the dwords we copied for this sequence from
+				 * the good buffer */
+				good_rb_idx = good_cmd_start_idx;
 				copy_rb_contents = 0;
 			}
-		} else if (copy_rb_contents)
-			temp_rb_buffer[temp_idx++] = value;
+			}
+		}
+
+		if (copy_rb_contents)
+			temp_rb_buffer[good_rb_idx++] = val1;
+		/* Copy both good and bad commands for replay to the bad
+		 * buffer */
+		bad_rb_buffer[bad_rb_idx++] = val1;
+
+		rb_rptr = adreno_ringbuffer_inc_wrapped(rb_rptr, size);
+	}
+	*rb_size = good_rb_idx;
+	*bad_rb_size = bad_rb_idx;
+}
+
+int adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
+				struct adreno_recovery_data *rec_data)
+{
+	int status;
+	struct kgsl_device *device = rb->device;
+	unsigned int rb_rptr = rb->wptr * sizeof(unsigned int);
+	struct kgsl_context *context;
+	struct adreno_context *adreno_context;
+
+	context = idr_find(&device->context_idr, rec_data->context_id);
+
+	/* Look for the command stream that is right after the global eop */
+	status = _find_cmd_seq_after_eop_ts(rb, &rb_rptr,
+			rec_data->global_eop + 1, false);
+
+	if (status)
+		goto done;
+
+	if (context) {
+		adreno_context = context->devctxt;
+
+		if (adreno_context->flags & CTXT_FLAGS_PREAMBLE) {
+			if (rec_data->ib1) {
+				status = _find_hanging_ib_sequence(rb, &rb_rptr,
+								rec_data->ib1);
+				if (status)
+					goto copy_rb_contents;
+			}
+			_turn_preamble_on_for_ib_seq(rb, rb_rptr);
+		}
 	}
 
-	*rb_size = temp_idx;
-	KGSL_DRV_ERR(device, "Extracted rb contents, size: %x\n", *rb_size);
-	for (temp_idx = 0; temp_idx < *rb_size;) {
-		char str[80];
-		int idx = 0;
-		if ((temp_idx + 8) <= *rb_size)
-			j = 8;
-		else
-			j = *rb_size - temp_idx;
-		for (; j != 0; j--)
-			idx += scnprintf(str + idx, 80 - idx,
-				"%8.8X ", temp_rb_buffer[temp_idx++]);
-		printk(KERN_ALERT "%s", str);
+copy_rb_contents:
+	_copy_valid_rb_content(rb, rb_rptr, rec_data->rb_buffer,
+				&rec_data->rb_size,
+				rec_data->bad_rb_buffer,
+				&rec_data->bad_rb_size,
+				&rec_data->last_valid_ctx_id);
+	/* If we failed to get the hanging IB sequence then we cannot execute
+	 * commands from the bad context */
+	if (status) {
+		rec_data->bad_rb_size = 0;
+		status = 0;
 	}
-	return 0;
+done:
+	return status;
 }
 
 void
@@ -1033,3 +1236,52 @@
 	rb->wptr += num_rb_contents;
 	adreno_ringbuffer_submit(rb);
 }
+
+void adreno_print_fault_ib_work(struct work_struct *work)
+{
+	struct kgsl_device *device = container_of(work, struct kgsl_device,
+				print_fault_ib);
+	mutex_lock(&device->mutex);
+	adreno_print_fault_ib(device);
+	mutex_unlock(&device->mutex);
+}
+
+void adreno_print_fault_ib(struct kgsl_device *device)
+{
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+	struct ib_list ib_list;
+	int i;
+
+	unsigned int ib_sz;
+
+	if (!device->page_fault_ptbase ||
+		!is_adreno_ib_dump_on_pagef_enabled(device))
+		goto done;
+
+	ib_sz = find_faulting_ib1_size(&adreno_dev->ringbuffer,
+					device->page_fault_rptr,
+					device->page_fault_ib1);
+	if (!ib_sz) {
+		KGSL_DRV_ERR(device, "Could not find size of fault ib 0x%x\n",
+				device->page_fault_ib1);
+		goto done;
+	}
+	ib_list.count = 0;
+
+	KGSL_DRV_ERR(device, "Page faulting IB1 0x%x, size 0x%x\n",
+			device->page_fault_ib1, ib_sz);
+	dump_ib1(device, device->page_fault_ptbase, 0,
+		device->page_fault_ib1, ib_sz, &ib_list, true);
+
+	/* print ib2's in faulting ib1 */
+	for (i = 0; i < ib_list.count; i++) {
+		KGSL_DRV_ERR(device, "IB2 0x%x, size 0x%x\n",
+			ib_list.bases[i], ib_list.sizes[i]);
+		dump_ib(device, "IB2:", device->page_fault_ptbase,
+			ib_list.offsets[i], ib_list.bases[i], ib_list.sizes[i],
+			true);
+	}
+	KGSL_DRV_ERR(device, "Finished printing fault IB\n");
+done:
+	device->page_fault_ptbase = 0;
+}
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index 6c4926d..a30a930 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -31,6 +31,7 @@
 
 struct kgsl_device;
 struct kgsl_device_private;
+struct adreno_recovery_data;
 
 #define GSL_RB_MEMPTRS_SCRATCH_COUNT	 8
 struct kgsl_rbmemptrs {
@@ -122,6 +123,7 @@
 void adreno_ringbuffer_close(struct adreno_ringbuffer *rb);
 
 void adreno_ringbuffer_issuecmds(struct kgsl_device *device,
+					struct adreno_context *drawctxt,
 					unsigned int flags,
 					unsigned int *cmdaddr,
 					int sizedwords);
@@ -129,13 +131,16 @@
 void kgsl_cp_intrcallback(struct kgsl_device *device);
 
 int adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
-				unsigned int *temp_rb_buffer,
-				int *rb_size);
+				struct adreno_recovery_data *rec_data);
 
 void
 adreno_ringbuffer_restore(struct adreno_ringbuffer *rb, unsigned int *rb_buff,
 			int num_rb_contents);
 
+void adreno_print_fault_ib_work(struct work_struct *work);
+
+void adreno_print_fault_ib(struct kgsl_device *device);
+
 static inline int adreno_ringbuffer_count(struct adreno_ringbuffer *rb,
 	unsigned int rptr)
 {
@@ -151,4 +156,11 @@
 	return (val + sizeof(unsigned int)) % size;
 }
 
+/* Decrement a value by 4 bytes with wrap-around based on size */
+static inline unsigned int adreno_ringbuffer_dec_wrapped(unsigned int val,
+							unsigned int size)
+{
+	return (val + size - sizeof(unsigned int)) % size;
+}
+
 #endif  /* __ADRENO_RINGBUFFER_H */
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index c43c9c5..ba13f35 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -25,7 +25,6 @@
 #include <linux/ashmem.h>
 #include <linux/major.h>
 #include <linux/ion.h>
-#include <mach/socinfo.h>
 
 #include "kgsl.h"
 #include "kgsl_debugfs.h"
@@ -536,8 +535,8 @@
 					struct kgsl_device, display_off);
 	KGSL_PWR_WARN(device, "late resume start\n");
 	mutex_lock(&device->mutex);
-	kgsl_pwrctrl_wake(device);
 	device->pwrctrl.restore_slumber = 0;
+	kgsl_pwrctrl_wake(device);
 	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_TURBO);
 	mutex_unlock(&device->mutex);
 	kgsl_check_idle(device);
@@ -1166,7 +1165,7 @@
 		goto error;
 	}
 
-	result = kgsl_sharedmem_page_alloc_user(&entry->memdesc,
+	result = kgsl_sharedmem_vmalloc_user(&entry->memdesc,
 					     private->pagetable, len,
 					     param->flags);
 	if (result != 0)
@@ -1177,7 +1176,7 @@
 	result = kgsl_sharedmem_map_vma(vma, &entry->memdesc);
 	if (result) {
 		KGSL_CORE_ERR("kgsl_sharedmem_map_vma failed: %d\n", result);
-		goto error_free_alloc;
+		goto error_free_vmalloc;
 	}
 
 	param->gpuaddr = entry->memdesc.gpuaddr;
@@ -1192,7 +1191,7 @@
 	kgsl_check_idle(dev_priv->device);
 	return 0;
 
-error_free_alloc:
+error_free_vmalloc:
 	kgsl_sharedmem_free(&entry->memdesc);
 
 error_free_entry:
@@ -1491,8 +1490,11 @@
 	struct scatterlist *s;
 	unsigned long flags;
 
-	if (IS_ERR_OR_NULL(kgsl_ion_client))
-		return -ENODEV;
+	if (kgsl_ion_client == NULL) {
+		kgsl_ion_client = msm_ion_client_create(UINT_MAX, KGSL_NAME);
+		if (kgsl_ion_client == NULL)
+			return -ENODEV;
+	}
 
 	handle = ion_import_fd(kgsl_ion_client, fd);
 	if (IS_ERR_OR_NULL(handle))
@@ -2110,8 +2112,7 @@
 	kgsl_cffdump_close(device->id);
 	kgsl_pwrctrl_uninit_sysfs(device);
 
-	if (cpu_is_msm8x60())
-		wake_lock_destroy(&device->idle_wakelock);
+	wake_lock_destroy(&device->idle_wakelock);
 
 	idr_destroy(&device->context_idr);
 
@@ -2202,9 +2203,8 @@
 	if (ret != 0)
 		goto err_close_mmu;
 
-	if (cpu_is_msm8x60())
-		wake_lock_init(&device->idle_wakelock,
-					   WAKE_LOCK_IDLE, device->name);
+	wake_lock_init(&device->idle_wakelock, WAKE_LOCK_IDLE, device->name);
+	pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
 
 	idr_init(&device->context_idr);
 
@@ -2250,8 +2250,6 @@
 	if (status)
 		goto error;
 
-	kgsl_ion_client = msm_ion_client_create(UINT_MAX, KGSL_NAME);
-
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 					   device->iomemname);
 	if (res == NULL) {
@@ -2340,8 +2338,8 @@
 static int __devinit
 kgsl_ptdata_init(void)
 {
-	kgsl_driver.ptpool = kgsl_mmu_ptpool_init(KGSL_PAGETABLE_SIZE,
-						kgsl_pagetable_count);
+	kgsl_driver.ptpool = kgsl_mmu_ptpool_init(kgsl_pagetable_count);
+
 	if (!kgsl_driver.ptpool)
 		return -ENOMEM;
 	return 0;
@@ -2349,30 +2347,22 @@
 
 static void kgsl_core_exit(void)
 {
-	kgsl_mmu_ptpool_destroy(kgsl_driver.ptpool);
+	unregister_chrdev_region(kgsl_driver.major, KGSL_DEVICE_MAX);
+
+	kgsl_mmu_ptpool_destroy(&kgsl_driver.ptpool);
 	kgsl_driver.ptpool = NULL;
 
-	kgsl_drm_exit();
-	kgsl_cffdump_destroy();
-	kgsl_core_debugfs_close();
-
-	/*
-	 * We call kgsl_sharedmem_uninit_sysfs() and device_unregister()
-	 * only if kgsl_driver.virtdev has been populated.
-	 * We check at least one member of kgsl_driver.virtdev to
-	 * see if it is not NULL (and thus, has been populated).
-	 */
-	if (kgsl_driver.virtdev.class) {
-		kgsl_sharedmem_uninit_sysfs();
-		device_unregister(&kgsl_driver.virtdev);
-	}
+	device_unregister(&kgsl_driver.virtdev);
 
 	if (kgsl_driver.class) {
 		class_destroy(kgsl_driver.class);
 		kgsl_driver.class = NULL;
 	}
 
-	unregister_chrdev_region(kgsl_driver.major, KGSL_DEVICE_MAX);
+	kgsl_drm_exit();
+	kgsl_cffdump_destroy();
+	kgsl_core_debugfs_close();
+	kgsl_sharedmem_uninit_sysfs();
 }
 
 static int __init kgsl_core_init(void)
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 4df509d..25c4827 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -44,10 +44,6 @@
 #define KGSL_PAGETABLE_ENTRIES(_sz) (((_sz) >> PAGE_SHIFT) + \
 				     KGSL_PT_EXTRA_ENTRIES)
 
-#define KGSL_PAGETABLE_SIZE \
-ALIGN(KGSL_PAGETABLE_ENTRIES(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE) * \
-KGSL_PAGETABLE_ENTRY_SIZE, PAGE_SIZE)
-
 #ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
 #define KGSL_PAGETABLE_COUNT (CONFIG_MSM_KGSL_PAGE_TABLE_COUNT)
 #else
@@ -95,8 +91,6 @@
 	struct {
 		unsigned int vmalloc;
 		unsigned int vmalloc_max;
-		unsigned int page_alloc;
-		unsigned int page_alloc_max;
 		unsigned int coherent;
 		unsigned int coherent_max;
 		unsigned int mapped;
@@ -118,8 +112,6 @@
 	int (*map_kernel_mem)(struct kgsl_memdesc *);
 };
 
-#define KGSL_MEMDESC_GUARD_PAGE BIT(0)
-
 /* shared memory allocation */
 struct kgsl_memdesc {
 	struct kgsl_pagetable *pagetable;
@@ -131,7 +123,6 @@
 	struct scatterlist *sg;
 	unsigned int sglen;
 	struct kgsl_memdesc_ops *ops;
-	int flags;
 };
 
 /* List of different memory entry types */
@@ -211,14 +202,13 @@
 static inline uint8_t *kgsl_gpuaddr_to_vaddr(struct kgsl_memdesc *memdesc,
 					     unsigned int gpuaddr)
 {
-	if (memdesc->gpuaddr == 0 ||
-		gpuaddr < memdesc->gpuaddr ||
-		gpuaddr >= (memdesc->gpuaddr + memdesc->size) ||
-		(NULL == memdesc->hostptr && memdesc->ops->map_kernel_mem &&
-			memdesc->ops->map_kernel_mem(memdesc)))
-			return NULL;
+	void *hostptr = NULL;
 
-	return memdesc->hostptr + (gpuaddr - memdesc->gpuaddr);
+	if ((gpuaddr >= memdesc->gpuaddr) &&
+		(gpuaddr < (memdesc->gpuaddr + memdesc->size)))
+		hostptr = kgsl_memdesc_map(memdesc);
+
+	return hostptr != NULL ? hostptr + (gpuaddr - memdesc->gpuaddr) : NULL;
 }
 
 static inline int timestamp_cmp(unsigned int a, unsigned int b)
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index 77aef1f..4e354d0 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -359,7 +359,7 @@
 void kgsl_cffdump_open(enum kgsl_deviceid device_id)
 {
 	kgsl_cffdump_memory_base(device_id, KGSL_PAGETABLE_BASE,
-			CONFIG_MSM_KGSL_PAGE_TABLE_SIZE, SZ_256K);
+			kgsl_mmu_get_ptsize(), SZ_256K);
 }
 
 void kgsl_cffdump_memory_base(enum kgsl_deviceid device_id, unsigned int base,
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index bd74a51..fdb4a6e 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -15,6 +15,7 @@
 
 #include <linux/idr.h>
 #include <linux/wakelock.h>
+#include <linux/pm_qos_params.h>
 #include <linux/earlysuspend.h>
 
 #include "kgsl.h"
@@ -89,13 +90,14 @@
 	void (*power_stats)(struct kgsl_device *device,
 		struct kgsl_power_stats *stats);
 	void (*irqctrl)(struct kgsl_device *device, int state);
-	unsigned int (*gpuid)(struct kgsl_device *device, unsigned int *chipid);
+	unsigned int (*gpuid)(struct kgsl_device *device);
 	void * (*snapshot)(struct kgsl_device *device, void *snapshot,
 		int *remain, int hang);
 	/* Optional functions - these functions are not mandatory.  The
 	   driver will check that the function pointer is not NULL before
 	   calling the hook */
-	void (*setstate) (struct kgsl_device *device, uint32_t flags);
+	void (*setstate) (struct kgsl_device *device, unsigned int context_id,
+			uint32_t flags);
 	int (*drawctxt_create) (struct kgsl_device *device,
 		struct kgsl_pagetable *pagetable, struct kgsl_context *context,
 		uint32_t flags);
@@ -184,9 +186,16 @@
 	struct wake_lock idle_wakelock;
 	struct kgsl_pwrscale pwrscale;
 	struct kobject pwrscale_kobj;
+	struct pm_qos_request_list pm_qos_req_dma;
 	struct work_struct ts_expired_ws;
 	struct list_head events;
 	s64 on_time;
+
+	/* page fault debugging parameters */
+	struct work_struct print_fault_ib;
+	unsigned int page_fault_ptbase;
+	unsigned int page_fault_ib1;
+	unsigned int page_fault_rptr;
 };
 
 struct kgsl_context {
@@ -258,10 +267,9 @@
 	return device->ftbl->idle(device, timeout);
 }
 
-static inline unsigned int kgsl_gpuid(struct kgsl_device *device,
-	unsigned int *chipid)
+static inline unsigned int kgsl_gpuid(struct kgsl_device *device)
 {
-	return device->ftbl->gpuid(device, chipid);
+	return device->ftbl->gpuid(device);
 }
 
 static inline int kgsl_create_device_sysfs_files(struct device *root,
diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c
index ba48f9c..051fcfc 100644
--- a/drivers/gpu/msm/kgsl_drm.c
+++ b/drivers/gpu/msm/kgsl_drm.c
@@ -295,9 +295,8 @@
 		priv->memdesc.size = obj->size * priv->bufcount;
 
 	} else if (TYPE_IS_MEM(priv->type)) {
-		result = kgsl_sharedmem_page_alloc(&priv->memdesc,
-					priv->pagetable,
-					obj->size * priv->bufcount, 0);
+		priv->memdesc.hostptr =
+			vmalloc_user(obj->size * priv->bufcount);
 
 		if (priv->memdesc.hostptr == NULL) {
 			DRM_ERROR("Unable to allocate vmalloc memory\n");
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index f038f04..7458cf2 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -21,6 +21,11 @@
 #include "kgsl_mmu.h"
 #include "kgsl_device.h"
 #include "kgsl_sharedmem.h"
+#include "a2xx_reg.h"
+
+#define KGSL_PAGETABLE_SIZE \
+	ALIGN(KGSL_PAGETABLE_ENTRIES(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE) * \
+	KGSL_PAGETABLE_ENTRY_SIZE, PAGE_SIZE)
 
 static ssize_t
 sysfs_show_ptpool_entries(struct kobject *kobj,
@@ -310,16 +315,15 @@
 /**
  * kgsl_ptpool_init
  * @pool:  A pointer to a ptpool structure to initialize
- * @ptsize: The size of each pagetable entry
  * @entries:  The number of inital entries to add to the pool
  *
  * Initalize a pool and allocate an initial chunk of entries.
  */
-void *kgsl_gpummu_ptpool_init(int ptsize, int entries)
+void *kgsl_gpummu_ptpool_init(int entries)
 {
+	int ptsize = KGSL_PAGETABLE_SIZE;
 	struct kgsl_ptpool *pool;
 	int ret = 0;
-	BUG_ON(ptsize == 0);
 
 	pool = kzalloc(sizeof(struct kgsl_ptpool), GFP_KERNEL);
 	if (!pool) {
@@ -354,8 +358,8 @@
 int kgsl_gpummu_pt_equal(struct kgsl_pagetable *pt,
 					unsigned int pt_base)
 {
-	struct kgsl_gpummu_pt *gpummu_pt = pt ? pt->priv : NULL;
-	return gpummu_pt && pt_base && (gpummu_pt->base.gpuaddr == pt_base);
+	struct kgsl_gpummu_pt *gpummu_pt = pt->priv;
+	return pt && pt_base && (gpummu_pt->base.gpuaddr == pt_base);
 }
 
 void kgsl_gpummu_destroy_pagetable(void *mmu_specific_pt)
@@ -421,11 +425,42 @@
 	kgsl_regread(device, MH_MMU_PAGE_FAULT, &reg);
 	kgsl_regread(device, MH_MMU_PT_BASE, &ptbase);
 
-	KGSL_MEM_CRIT(device,
-			"mmu page fault: page=0x%lx pt=%d op=%s axi=%d\n",
+	if (KGSL_DEVICE_3D0 == device->id) {
+		unsigned int ib1;
+		unsigned int ib1_sz;
+		unsigned int ib2;
+		unsigned int ib2_sz;
+		unsigned int rptr;
+		kgsl_regread(device, REG_CP_IB1_BASE, &ib1);
+		kgsl_regread(device, REG_CP_IB1_BUFSZ, &ib1_sz);
+		kgsl_regread(device, REG_CP_IB2_BASE, &ib2);
+		kgsl_regread(device, REG_CP_IB2_BUFSZ, &ib2_sz);
+		kgsl_regread(device, REG_CP_RB_RPTR, &rptr);
+
+		/* queue a work which will print the IB that caused the
+		 * pagefault, if we are in recovery then no need to q
+		 * work as the recovery routine will mess with the ringbuffer
+		 * contents and then the information will become stale
+		 * anyways */
+		if (!device->page_fault_ptbase &&
+			KGSL_STATE_DUMP_AND_RECOVER != device->state) {
+			device->page_fault_ptbase = ptbase;
+			device->page_fault_ib1 = ib1;
+			device->page_fault_rptr = rptr;
+
+			queue_work(device->work_queue,
+				&device->print_fault_ib);
+		}
+
+		KGSL_MEM_CRIT(device,
+			"mmu page fault: page=0x%lx pt=%d op=%s axi=%d "
+			"ptbase=0x%x IB1=0x%x IB1_SZ=0x%x "
+			"IB2=0x%x IB2_SZ=0x%x\n",
 			reg & ~(PAGE_SIZE - 1),
 			kgsl_mmu_get_ptname_from_ptbase(ptbase),
-			reg & 0x02 ? "WRITE" : "READ", (reg >> 4) & 0xF);
+			reg & 0x02 ? "WRITE" : "READ", (reg >> 4) & 0xF,
+			ptbase, ib1, ib1_sz, ib2, ib2_sz);
+	}
 }
 
 static void *kgsl_gpummu_create_pagetable(void)
@@ -498,7 +533,8 @@
 }
 
 static void kgsl_gpummu_setstate(struct kgsl_device *device,
-				struct kgsl_pagetable *pagetable)
+				struct kgsl_pagetable *pagetable,
+				unsigned int context_id)
 {
 	struct kgsl_mmu *mmu = &device->mmu;
 	struct kgsl_gpummu_pt *gpummu_pt;
@@ -515,7 +551,8 @@
 			spin_unlock(&mmu->hwpagetable->lock);
 
 			/* call device specific set page table */
-			kgsl_setstate(mmu->device, KGSL_MMUFLAGS_TLBFLUSH |
+			kgsl_setstate(mmu->device, context_id,
+				KGSL_MMUFLAGS_TLBFLUSH |
 				KGSL_MMUFLAGS_PTUPDATE);
 		}
 	}
@@ -610,7 +647,7 @@
 	kgsl_regwrite(device, MH_MMU_VA_RANGE,
 		      (KGSL_PAGETABLE_BASE |
 		      (CONFIG_MSM_KGSL_PAGE_TABLE_SIZE >> 16)));
-	kgsl_setstate(device, KGSL_MMUFLAGS_TLBFLUSH);
+	kgsl_setstate(device, 0, KGSL_MMUFLAGS_TLBFLUSH);
 	mmu->flags |= KGSL_FLAGS_STARTED;
 
 	return 0;
diff --git a/drivers/gpu/msm/kgsl_gpummu.h b/drivers/gpu/msm/kgsl_gpummu.h
index 46466a8..cac6930 100644
--- a/drivers/gpu/msm/kgsl_gpummu.h
+++ b/drivers/gpu/msm/kgsl_gpummu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -73,8 +73,7 @@
 	int chunks;
 };
 
-void *kgsl_gpummu_ptpool_init(int ptsize,
-			int entries);
+void *kgsl_gpummu_ptpool_init(int entries);
 void kgsl_gpummu_ptpool_destroy(void *ptpool);
 
 static inline unsigned int kgsl_pt_get_base_addr(struct kgsl_pagetable *pt)
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index a36739d..81e237f 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -34,8 +34,8 @@
 static int kgsl_iommu_pt_equal(struct kgsl_pagetable *pt,
 					unsigned int pt_base)
 {
-	struct iommu_domain *domain = pt ? pt->priv : NULL;
-	return domain && pt_base && ((unsigned int)domain == pt_base);
+	struct iommu_domain *domain = pt->priv;
+	return pt && pt_base && ((unsigned int)domain == pt_base);
 }
 
 static void kgsl_iommu_destroy_pagetable(void *mmu_specific_pt)
@@ -144,7 +144,8 @@
 }
 
 static void kgsl_iommu_setstate(struct kgsl_device *device,
-				struct kgsl_pagetable *pagetable)
+				struct kgsl_pagetable *pagetable,
+				unsigned int context_id)
 {
 	struct kgsl_mmu *mmu = &device->mmu;
 
@@ -262,7 +263,7 @@
 	iommu_virt_addr = memdesc->gpuaddr;
 
 	ret = iommu_map_range(domain, iommu_virt_addr, memdesc->sg,
-				memdesc->size, 0);
+				memdesc->size, (IOMMU_READ | IOMMU_WRITE));
 	if (ret) {
 		KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %d, %d) "
 				"failed with err: %d\n", domain,
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 36248ef..975aa83 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -147,9 +147,10 @@
 
 	pt = _get_pt_from_kobj(kobj);
 
-	if (pt)
+	if (pt) {
 		ret += snprintf(buf, PAGE_SIZE, "0x%x\n",
-			CONFIG_MSM_KGSL_PAGE_TABLE_SIZE);
+			kgsl_mmu_get_ptsize());
+	}
 
 	kgsl_put_pagetable(pt);
 	return ret;
@@ -267,6 +268,22 @@
 	return ret;
 }
 
+unsigned int kgsl_mmu_get_ptsize(void)
+{
+	/*
+	 * For IOMMU, we could do up to 4G virtual range if we wanted to, but
+	 * it makes more sense to return a smaller range and leave the rest of
+	 * the virtual range for future improvements
+	 */
+
+	if (KGSL_MMU_TYPE_GPU == kgsl_mmu_type)
+		return CONFIG_MSM_KGSL_PAGE_TABLE_SIZE;
+	else if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_type)
+		return SZ_2G;
+	else
+		return 0;
+}
+
 unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_device *device)
 {
 	struct kgsl_mmu *mmu = &device->mmu;
@@ -297,7 +314,8 @@
 EXPORT_SYMBOL(kgsl_mmu_get_ptname_from_ptbase);
 
 void kgsl_mmu_setstate(struct kgsl_device *device,
-			struct kgsl_pagetable *pagetable)
+			struct kgsl_pagetable *pagetable,
+			unsigned int context_id)
 {
 	struct kgsl_mmu *mmu = &device->mmu;
 
@@ -305,7 +323,7 @@
 		return;
 	else
 		mmu->mmu_ops->mmu_setstate(device,
-					pagetable);
+					pagetable, context_id);
 }
 EXPORT_SYMBOL(kgsl_mmu_setstate);
 
@@ -391,6 +409,7 @@
 	int status = 0;
 	struct kgsl_pagetable *pagetable = NULL;
 	unsigned long flags;
+	unsigned int ptsize;
 
 	pagetable = kzalloc(sizeof(struct kgsl_pagetable), GFP_KERNEL);
 	if (pagetable == NULL) {
@@ -402,9 +421,11 @@
 	kref_init(&pagetable->refcount);
 
 	spin_lock_init(&pagetable->lock);
+
+	ptsize = kgsl_mmu_get_ptsize();
+
 	pagetable->name = name;
-	pagetable->max_entries = KGSL_PAGETABLE_ENTRIES(
-					CONFIG_MSM_KGSL_PAGE_TABLE_SIZE);
+	pagetable->max_entries = KGSL_PAGETABLE_ENTRIES(ptsize);
 
 	pagetable->pool = gen_pool_create(PAGE_SHIFT, -1);
 	if (pagetable->pool == NULL) {
@@ -413,7 +434,7 @@
 	}
 
 	if (gen_pool_add(pagetable->pool, KGSL_PAGETABLE_BASE,
-				CONFIG_MSM_KGSL_PAGE_TABLE_SIZE, -1)) {
+				ptsize, -1)) {
 		KGSL_CORE_ERR("gen_pool_add failed\n");
 		goto err_pool;
 	}
@@ -477,13 +498,14 @@
 }
 EXPORT_SYMBOL(kgsl_mmu_putpagetable);
 
-void kgsl_setstate(struct kgsl_device *device, uint32_t flags)
+void kgsl_setstate(struct kgsl_device *device, unsigned int context_id,
+			uint32_t flags)
 {
 	struct kgsl_mmu *mmu = &device->mmu;
 	if (KGSL_MMU_TYPE_NONE == kgsl_mmu_type)
 		return;
 	else if (device->ftbl->setstate)
-		device->ftbl->setstate(device, flags);
+		device->ftbl->setstate(device, context_id, flags);
 	else if (mmu->mmu_ops->mmu_device_setstate)
 		mmu->mmu_ops->mmu_device_setstate(device, flags);
 }
@@ -676,10 +698,10 @@
 }
 EXPORT_SYMBOL(kgsl_mmu_ptpool_destroy);
 
-void *kgsl_mmu_ptpool_init(int ptsize, int entries)
+void *kgsl_mmu_ptpool_init(int entries)
 {
 	if (KGSL_MMU_TYPE_GPU == kgsl_mmu_type)
-		return kgsl_gpummu_ptpool_init(ptsize, entries);
+		return kgsl_gpummu_ptpool_init(entries);
 	else
 		return (void *)(-1);
 }
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 1338d0d..870f771 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -112,7 +112,8 @@
 	int (*mmu_start) (struct kgsl_device *device);
 	int (*mmu_stop) (struct kgsl_device *device);
 	void (*mmu_setstate) (struct kgsl_device *device,
-		struct kgsl_pagetable *pagetable);
+		struct kgsl_pagetable *pagetable,
+		unsigned int context_id);
 	void (*mmu_device_setstate) (struct kgsl_device *device,
 					uint32_t flags);
 	void (*mmu_pagefault) (struct kgsl_device *device);
@@ -168,20 +169,21 @@
 int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
 		    struct kgsl_memdesc *memdesc);
 unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
-void kgsl_setstate(struct kgsl_device *device, uint32_t flags);
+void kgsl_setstate(struct kgsl_device *device, unsigned int context_id,
+			uint32_t flags);
 void kgsl_mmu_device_setstate(struct kgsl_device *device, uint32_t flags);
 void kgsl_mmu_setstate(struct kgsl_device *device,
-			struct kgsl_pagetable *pt);
+			struct kgsl_pagetable *pt, unsigned int context_id);
 int kgsl_mmu_get_ptname_from_ptbase(unsigned int pt_base);
 int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
 			enum kgsl_deviceid id);
-
 void kgsl_mmu_ptpool_destroy(void *ptpool);
-void *kgsl_mmu_ptpool_init(int ptsize, int entries);
+void *kgsl_mmu_ptpool_init(int entries);
 int kgsl_mmu_enabled(void);
 int kgsl_mmu_pt_equal(struct kgsl_pagetable *pt,
 			unsigned int pt_base);
 void kgsl_mmu_set_mmutype(char *mmutype);
 unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_device *device);
 enum kgsl_mmutype kgsl_mmu_get_mmutype(void);
+unsigned int kgsl_mmu_get_ptsize(void);
 #endif /* __KGSL_MMU_H */
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index fb49c31..e9f2143 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -13,8 +13,6 @@
 #include <linux/interrupt.h>
 #include <mach/msm_iomap.h>
 #include <mach/msm_bus.h>
-#include <mach/socinfo.h>
-#include <mach/internal_power_rail.h>
 
 #include "kgsl.h"
 #include "kgsl_pwrscale.h"
@@ -26,9 +24,38 @@
 #define KGSL_PWRFLAGS_AXI_ON   2
 #define KGSL_PWRFLAGS_IRQ_ON   3
 
+#define GPU_SWFI_LATENCY	3
 #define UPDATE_BUSY_VAL		1000000
 #define UPDATE_BUSY		50
 
+struct clk_pair {
+	const char *name;
+	uint map;
+};
+
+struct clk_pair clks[KGSL_MAX_CLKS] = {
+	{
+		.name = "src_clk",
+		.map = KGSL_CLK_SRC,
+	},
+	{
+		.name = "core_clk",
+		.map = KGSL_CLK_CORE,
+	},
+	{
+		.name = "iface_clk",
+		.map = KGSL_CLK_IFACE,
+	},
+	{
+		.name = "mem_clk",
+		.map = KGSL_CLK_MEM,
+	},
+	{
+		.name = "mem_iface_clk",
+		.map = KGSL_CLK_MEM_IFACE,
+	},
+};
+
 void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
 				unsigned int new_level)
 {
@@ -257,7 +284,7 @@
 DEVICE_ATTR(gpuclk, 0644, kgsl_pwrctrl_gpuclk_show, kgsl_pwrctrl_gpuclk_store);
 DEVICE_ATTR(max_gpuclk, 0644, kgsl_pwrctrl_max_gpuclk_show,
 	kgsl_pwrctrl_max_gpuclk_store);
-DEVICE_ATTR(pwrnap, 0666, kgsl_pwrctrl_pwrnap_show, kgsl_pwrctrl_pwrnap_store);
+DEVICE_ATTR(pwrnap, 0664, kgsl_pwrctrl_pwrnap_show, kgsl_pwrctrl_pwrnap_store);
 DEVICE_ATTR(idle_timer, 0644, kgsl_pwrctrl_idle_timer_show,
 	kgsl_pwrctrl_idle_timer_store);
 DEVICE_ATTR(gpubusy, 0644, kgsl_pwrctrl_gpubusy_show,
@@ -387,34 +414,16 @@
 	if (state == KGSL_PWRFLAGS_OFF) {
 		if (test_and_clear_bit(KGSL_PWRFLAGS_POWER_ON,
 			&pwr->power_flags)) {
-			internal_pwr_rail_ctl(pwr->pwr_rail, 0);
 			trace_kgsl_rail(device, state);
-			if (pwr->gpu_dig)
-				regulator_disable(pwr->gpu_dig);
 			if (pwr->gpu_reg)
 				regulator_disable(pwr->gpu_reg);
 		}
 	} else if (state == KGSL_PWRFLAGS_ON) {
 		if (!test_and_set_bit(KGSL_PWRFLAGS_POWER_ON,
 			&pwr->power_flags)) {
-			internal_pwr_rail_ctl(pwr->pwr_rail, 1);
 			trace_kgsl_rail(device, state);
-			if (pwr->gpu_reg) {
-				int status = regulator_enable(pwr->gpu_reg);
-				if (status)
-					KGSL_DRV_ERR(device,
-							"core regulator_enable "
-							"failed: %d\n",
-							status);
-			}
-			if (pwr->gpu_dig) {
-				int status = regulator_enable(pwr->gpu_dig);
-				if (status)
-					KGSL_DRV_ERR(device,
-							"cx regulator_enable "
-							"failed: %d\n",
-							status);
-			}
+			if (pwr->gpu_reg)
+				regulator_enable(pwr->gpu_reg);
 		}
 	}
 }
@@ -451,16 +460,10 @@
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 	struct kgsl_device_platform_data *pdata = pdev->dev.platform_data;
 
-	const char *clk_names[KGSL_MAX_CLKS] = {pwr->src_clk_name,
-		pdata->clk.clk,
-		pdata->clk.pclk,
-		pdata->imem_clk_name.clk,
-		pdata->imem_clk_name.pclk};
-
 	/*acquire clocks */
 	for (i = 0; i < KGSL_MAX_CLKS; i++) {
-		if (clk_names[i]) {
-			clk = clk_get(&pdev->dev, clk_names[i]);
+		if (pdata->clk_map & clks[i].map) {
+			clk = clk_get(&pdev->dev, clks[i].name);
 			if (IS_ERR(clk))
 				goto clk_err;
 			pwr->grp_clks[i] = clk;
@@ -502,28 +505,12 @@
 	if (IS_ERR(pwr->gpu_reg))
 		pwr->gpu_reg = NULL;
 
-	if (pwr->gpu_reg) {
-		pwr->gpu_dig = regulator_get(&pdev->dev, "vdd_dig");
-		if (IS_ERR(pwr->gpu_dig))
-			pwr->gpu_dig = NULL;
-	} else
-		pwr->gpu_dig = NULL;
-
 	pwr->power_flags = 0;
 
 	pwr->nap_allowed = pdata->nap_allowed;
 	pwr->idle_needed = pdata->idle_needed;
 	pwr->interval_timeout = pdata->idle_timeout;
-	pwr->strtstp_sleepwake = pdata->strtstp_sleepwake;
-
-	if (internal_pwr_rail_mode(pwr->pwr_rail,
-			PWR_RAIL_CTL_MANUAL)) {
-		KGSL_PWR_ERR(device, "call internal_pwr_rail_mode failed\n");
-		result = -EINVAL;
-		goto done;
-	}
-
-	pwr->ebi1_clk = clk_get(NULL, "ebi1_kgsl_clk");
+	pwr->ebi1_clk = clk_get(&pdev->dev, "bus_clk");
 	if (IS_ERR(pwr->ebi1_clk))
 		pwr->ebi1_clk = NULL;
 	else
@@ -560,7 +547,7 @@
 clk_err:
 	result = PTR_ERR(clk);
 	KGSL_PWR_ERR(device, "clk_get(%s) failed: %d\n",
-				 clk_names[i], result);
+				 clks[i].name, result);
 
 done:
 	return result;
@@ -595,11 +582,6 @@
 		pwr->gpu_reg = NULL;
 	}
 
-	if (pwr->gpu_dig) {
-		regulator_put(pwr->gpu_dig);
-		pwr->gpu_dig = NULL;
-	}
-
 	for (i = 1; i < KGSL_MAX_CLKS; i++)
 		if (pwr->grp_clks[i]) {
 			clk_put(pwr->grp_clks[i]);
@@ -650,8 +632,7 @@
 
 	KGSL_PWR_INFO(device, "idle timer expired device %d\n", device->id);
 	if (device->requested_state != KGSL_STATE_SUSPEND) {
-		if (device->pwrctrl.restore_slumber ||
-					device->pwrctrl.strtstp_sleepwake)
+		if (device->pwrctrl.restore_slumber)
 			kgsl_pwrctrl_request_state(device, KGSL_STATE_SLUMBER);
 		else
 			kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
@@ -763,8 +744,9 @@
 		_sleep_accounting(device);
 		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF, KGSL_STATE_SLEEP);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLEEP);
-		if (device->idle_wakelock.name)
-			wake_unlock(&device->idle_wakelock);
+		wake_unlock(&device->idle_wakelock);
+		pm_qos_update_request(&device->pm_qos_req_dma,
+					PM_QOS_DEFAULT_VALUE);
 		break;
 	case KGSL_STATE_SLEEP:
 	case KGSL_STATE_SLUMBER:
@@ -791,16 +773,16 @@
 	case KGSL_STATE_NAP:
 	case KGSL_STATE_SLEEP:
 		del_timer_sync(&device->idle_timer);
-		if (!device->pwrctrl.strtstp_sleepwake)
-			kgsl_pwrctrl_pwrlevel_change(device,
-					KGSL_PWRLEVEL_NOMINAL);
+		kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
+		device->pwrctrl.restore_slumber = true;
 		device->ftbl->suspend_context(device);
 		device->ftbl->stop(device);
-		device->pwrctrl.restore_slumber = true;
 		_sleep_accounting(device);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
 		if (device->idle_wakelock.name)
 			wake_unlock(&device->idle_wakelock);
+		pm_qos_update_request(&device->pm_qos_req_dma,
+						PM_QOS_DEFAULT_VALUE);
 		break;
 	case KGSL_STATE_SLUMBER:
 		break;
@@ -869,9 +851,10 @@
 		/* Re-enable HW access */
 		mod_timer(&device->idle_timer,
 				jiffies + device->pwrctrl.interval_timeout);
-
-		if (device->idle_wakelock.name)
-			wake_lock(&device->idle_wakelock);
+		wake_lock(&device->idle_wakelock);
+		if (device->pwrctrl.restore_slumber == false)
+			pm_qos_update_request(&device->pm_qos_req_dma,
+						GPU_SWFI_LATENCY);
 	case KGSL_STATE_ACTIVE:
 		break;
 	default:
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 5e09b5b..f474c21 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -47,19 +47,15 @@
 	int thermal_pwrlevel;
 	unsigned int num_pwrlevels;
 	unsigned int interval_timeout;
-	bool strtstp_sleepwake;
 	struct regulator *gpu_reg;
-	struct regulator *gpu_dig;
 	uint32_t pcl;
 	unsigned int nap_allowed;
 	unsigned int idle_needed;
 	const char *regulator_name;
 	const char *irq_name;
-	const char *src_clk_name;
 	s64 time;
 	struct kgsl_busy busy;
 	unsigned int restore_slumber;
-	unsigned int pwr_rail;
 };
 
 void kgsl_pwrctrl_irq(struct kgsl_device *device, int state);
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index 4c9a239..d0b2a41 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -90,7 +90,7 @@
 	return ret;
 }
 
-PWRSCALE_ATTR(policy, 0666, pwrscale_policy_show, pwrscale_policy_store);
+PWRSCALE_ATTR(policy, 0664, pwrscale_policy_show, pwrscale_policy_store);
 
 static ssize_t pwrscale_avail_policies_show(struct kgsl_device *device,
 					    char *buf)
diff --git a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
index 7c54936..2976b0b 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_idlestats.c
@@ -89,7 +89,6 @@
 			struct kgsl_pwrscale *pwrscale)
 {
 	struct idlestats_priv *priv = pwrscale->priv;
-	struct kgsl_power_stats stats;
 	int i, busy, nr_cpu = 1;
 
 	if (priv->pulse.busy_start_time != 0) {
@@ -112,19 +111,6 @@
 			spin_unlock(&priv->cpu_info.lock);
 		}
 		priv->pulse.wait_interval /= nr_cpu;
-
-		/* This is called from within a mutex protected function, so
-		   no additional locking required */
-		device->ftbl->power_stats(device, &stats);
-
-		/* If total_time is zero, then we don't have
-		   any interesting statistics to store */
-		if (stats.total_time == 0) {
-			priv->pulse.busy_start_time = 0;
-			return;
-		}
-
-		priv->pulse.busy_interval = stats.busy_time;
 		msm_idle_stats_idle_end(&priv->idledev, &priv->pulse);
 	}
 	priv->pulse.busy_start_time = ktime_to_us(ktime_get());
@@ -134,8 +120,21 @@
 			struct kgsl_pwrscale *pwrscale)
 {
 	int i, nr_cpu;
+	struct kgsl_power_stats stats;
 	struct idlestats_priv *priv = pwrscale->priv;
 
+	/* This is called from within a mutex protected function, so
+	   no additional locking required */
+	device->ftbl->power_stats(device, &stats);
+
+	/* If total_time is zero, then we don't have
+	   any interesting statistics to store */
+	if (stats.total_time == 0) {
+		priv->pulse.busy_start_time = 0;
+		return;
+	}
+
+	priv->pulse.busy_interval   = stats.busy_time;
 	nr_cpu = num_possible_cpus();
 	for (i = 0; i < nr_cpu; i++)
 		if (cpu_online(i))
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 5d2e787..bafb1c0 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -63,13 +63,6 @@
 }
 
 
-/*
- * One page allocation for a guard region to protect against over-zealous
- * GPU pre-fetch
- */
-
-static struct page *kgsl_guard_page;
-
 /**
  * Given a kobj, find the process structure attached to it
  */
@@ -160,7 +153,7 @@
 	MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, user),
 #ifdef CONFIG_ION
 	MEM_ENTRY_STAT(KGSL_MEM_ENTRY_USER, ion),
-#endif    
+#endif
 };
 
 void
@@ -210,10 +203,6 @@
 		val = kgsl_driver.stats.vmalloc;
 	else if (!strncmp(attr->attr.name, "vmalloc_max", 11))
 		val = kgsl_driver.stats.vmalloc_max;
-	else if (!strncmp(attr->attr.name, "page_alloc", 10))
-		val = kgsl_driver.stats.page_alloc;
-	else if (!strncmp(attr->attr.name, "page_alloc_max", 14))
-		val = kgsl_driver.stats.page_alloc_max;
 	else if (!strncmp(attr->attr.name, "coherent", 8))
 		val = kgsl_driver.stats.coherent;
 	else if (!strncmp(attr->attr.name, "coherent_max", 12))
@@ -243,8 +232,6 @@
 
 DEVICE_ATTR(vmalloc, 0444, kgsl_drv_memstat_show, NULL);
 DEVICE_ATTR(vmalloc_max, 0444, kgsl_drv_memstat_show, NULL);
-DEVICE_ATTR(page_alloc, 0444, kgsl_drv_memstat_show, NULL);
-DEVICE_ATTR(page_alloc_max, 0444, kgsl_drv_memstat_show, NULL);
 DEVICE_ATTR(coherent, 0444, kgsl_drv_memstat_show, NULL);
 DEVICE_ATTR(coherent_max, 0444, kgsl_drv_memstat_show, NULL);
 DEVICE_ATTR(mapped, 0444, kgsl_drv_memstat_show, NULL);
@@ -254,8 +241,6 @@
 static const struct device_attribute *drv_attr_list[] = {
 	&dev_attr_vmalloc,
 	&dev_attr_vmalloc_max,
-	&dev_attr_page_alloc,
-	&dev_attr_page_alloc_max,
 	&dev_attr_coherent,
 	&dev_attr_coherent_max,
 	&dev_attr_mapped,
@@ -310,7 +295,7 @@
 }
 #endif
 
-static int kgsl_page_alloc_vmfault(struct kgsl_memdesc *memdesc,
+static int kgsl_vmalloc_vmfault(struct kgsl_memdesc *memdesc,
 				struct vm_area_struct *vma,
 				struct vm_fault *vmf)
 {
@@ -331,29 +316,20 @@
 	return 0;
 }
 
-static int kgsl_page_alloc_vmflags(struct kgsl_memdesc *memdesc)
+static int kgsl_vmalloc_vmflags(struct kgsl_memdesc *memdesc)
 {
 	return VM_RESERVED | VM_DONTEXPAND;
 }
 
-static void kgsl_page_alloc_free(struct kgsl_memdesc *memdesc)
+static void kgsl_vmalloc_free(struct kgsl_memdesc *memdesc)
 {
 	int i = 0;
 	struct scatterlist *sg;
-	int sglen = memdesc->sglen;
-
-	/* Don't free the guard page if it was used */
-	if (memdesc->flags & KGSL_MEMDESC_GUARD_PAGE)
-		sglen--;
-
-	kgsl_driver.stats.page_alloc -= memdesc->size;
-
-	if (memdesc->hostptr) {
+	kgsl_driver.stats.vmalloc -= memdesc->size;
+	if (memdesc->hostptr)
 		vunmap(memdesc->hostptr);
-		kgsl_driver.stats.vmalloc -= memdesc->size;
-	}
 	if (memdesc->sg)
-		for_each_sg(memdesc->sg, sg, sglen, i)
+		for_each_sg(memdesc->sg, sg, memdesc->sglen, i)
 			__free_page(sg_page(sg));
 }
 
@@ -363,39 +339,30 @@
 }
 
 /*
- * kgsl_page_alloc_map_kernel - Map the memory in memdesc to kernel address
- * space
+ * kgsl_vmalloc_map_kernel - Map the memory in memdesc to kernel address space
  *
  * @memdesc - The memory descriptor which contains information about the memory
  *
  * Return: 0 on success else error code
  */
-static int kgsl_page_alloc_map_kernel(struct kgsl_memdesc *memdesc)
+static int kgsl_vmalloc_map_kernel(struct kgsl_memdesc *memdesc)
 {
 	if (!memdesc->hostptr) {
 		pgprot_t page_prot = pgprot_writecombine(PAGE_KERNEL);
 		struct page **pages = NULL;
 		struct scatterlist *sg;
-		int sglen = memdesc->sglen;
 		int i;
-
-		/* Don't map the guard page if it exists */
-		if (memdesc->flags & KGSL_MEMDESC_GUARD_PAGE)
-			sglen--;
-
 		/* create a list of pages to call vmap */
-		pages = vmalloc(sglen * sizeof(struct page *));
+		pages = vmalloc(memdesc->sglen * sizeof(struct page *));
 		if (!pages) {
 			KGSL_CORE_ERR("vmalloc(%d) failed\n",
-				sglen * sizeof(struct page *));
+				memdesc->sglen * sizeof(struct page *));
 			return -ENOMEM;
 		}
-		for_each_sg(memdesc->sg, sg, sglen, i)
+		for_each_sg(memdesc->sg, sg, memdesc->sglen, i)
 			pages[i] = sg_page(sg);
-		memdesc->hostptr = vmap(pages, sglen,
+		memdesc->hostptr = vmap(pages, memdesc->sglen,
 					VM_IOREMAP, page_prot);
-		KGSL_STATS_ADD(memdesc->size, kgsl_driver.stats.vmalloc,
-				kgsl_driver.stats.vmalloc_max);
 		vfree(pages);
 	}
 	if (!memdesc->hostptr)
@@ -443,13 +410,13 @@
 }
 
 /* Global - also used by kgsl_drm.c */
-struct kgsl_memdesc_ops kgsl_page_alloc_ops = {
-	.free = kgsl_page_alloc_free,
-	.vmflags = kgsl_page_alloc_vmflags,
-	.vmfault = kgsl_page_alloc_vmfault,
-	.map_kernel_mem = kgsl_page_alloc_map_kernel,
+struct kgsl_memdesc_ops kgsl_vmalloc_ops = {
+	.free = kgsl_vmalloc_free,
+	.vmflags = kgsl_vmalloc_vmflags,
+	.vmfault = kgsl_vmalloc_vmfault,
+	.map_kernel_mem = kgsl_vmalloc_map_kernel,
 };
-EXPORT_SYMBOL(kgsl_page_alloc_ops);
+EXPORT_SYMBOL(kgsl_vmalloc_ops);
 
 static struct kgsl_memdesc_ops kgsl_ebimem_ops = {
 	.free = kgsl_ebimem_free,
@@ -483,7 +450,7 @@
 EXPORT_SYMBOL(kgsl_cache_range_op);
 
 static int
-_kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc,
+_kgsl_sharedmem_vmalloc(struct kgsl_memdesc *memdesc,
 			struct kgsl_pagetable *pagetable,
 			size_t size, unsigned int protflags)
 {
@@ -491,24 +458,14 @@
 	int sglen = PAGE_ALIGN(size) / PAGE_SIZE;
 	int i;
 
-	/*
-	 * Add guard page to the end of the allocation when the
-	 * IOMMU is in use.
-	 */
-
-	if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_IOMMU)
-		sglen++;
-
 	memdesc->size = size;
 	memdesc->pagetable = pagetable;
 	memdesc->priv = KGSL_MEMFLAGS_CACHED;
-	memdesc->ops = &kgsl_page_alloc_ops;
+	memdesc->ops = &kgsl_vmalloc_ops;
 
 	memdesc->sg = kgsl_sg_alloc(sglen);
 
 	if (memdesc->sg == NULL) {
-		KGSL_CORE_ERR("vmalloc(%d) failed\n",
-			sglen * sizeof(struct scatterlist));
 		ret = -ENOMEM;
 		goto done;
 	}
@@ -518,7 +475,7 @@
 	memdesc->sglen = sglen;
 	sg_init_table(memdesc->sg, sglen);
 
-	for (i = 0; i < PAGE_ALIGN(size) / PAGE_SIZE; i++) {
+	for (i = 0; i < memdesc->sglen; i++) {
 		struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO |
 						__GFP_HIGHMEM);
 		if (!page) {
@@ -529,22 +486,6 @@
 		flush_dcache_page(page);
 		sg_set_page(&memdesc->sg[i], page, PAGE_SIZE, 0);
 	}
-
-	/* ADd the guard page to the end of the sglist */
-
-	if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_IOMMU) {
-		if (kgsl_guard_page == NULL)
-			kgsl_guard_page = alloc_page(GFP_KERNEL | __GFP_ZERO |
-				__GFP_HIGHMEM);
-
-		if (kgsl_guard_page != NULL) {
-			sg_set_page(&memdesc->sg[sglen - 1], kgsl_guard_page,
-				PAGE_SIZE, 0);
-			memdesc->flags |= KGSL_MEMDESC_GUARD_PAGE;
-		} else
-			memdesc->sglen--;
-	}
-
 	outer_cache_range_op_sg(memdesc->sg, memdesc->sglen,
 				KGSL_CACHE_OP_FLUSH);
 
@@ -553,8 +494,8 @@
 	if (ret)
 		goto done;
 
-	KGSL_STATS_ADD(size, kgsl_driver.stats.page_alloc,
-		kgsl_driver.stats.page_alloc_max);
+	KGSL_STATS_ADD(size, kgsl_driver.stats.vmalloc,
+		kgsl_driver.stats.vmalloc_max);
 
 	order = get_order(size);
 
@@ -569,7 +510,7 @@
 }
 
 int
-kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc,
+kgsl_sharedmem_vmalloc(struct kgsl_memdesc *memdesc,
 		       struct kgsl_pagetable *pagetable, size_t size)
 {
 	int ret = 0;
@@ -577,18 +518,18 @@
 
 	size = ALIGN(size, PAGE_SIZE * 2);
 
-	ret =  _kgsl_sharedmem_page_alloc(memdesc, pagetable, size,
+	ret =  _kgsl_sharedmem_vmalloc(memdesc, pagetable, size,
 		GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
 	if (!ret)
-		ret = kgsl_page_alloc_map_kernel(memdesc);
+		ret = kgsl_vmalloc_map_kernel(memdesc);
 	if (ret)
 		kgsl_sharedmem_free(memdesc);
 	return ret;
 }
-EXPORT_SYMBOL(kgsl_sharedmem_page_alloc);
+EXPORT_SYMBOL(kgsl_sharedmem_vmalloc);
 
 int
-kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc,
+kgsl_sharedmem_vmalloc_user(struct kgsl_memdesc *memdesc,
 			    struct kgsl_pagetable *pagetable,
 			    size_t size, int flags)
 {
@@ -600,10 +541,10 @@
 	if (!(flags & KGSL_MEMFLAGS_GPUREADONLY))
 		protflags |= GSL_PT_PAGE_WV;
 
-	return _kgsl_sharedmem_page_alloc(memdesc, pagetable, size,
+	return _kgsl_sharedmem_vmalloc(memdesc, pagetable, size,
 		protflags);
 }
-EXPORT_SYMBOL(kgsl_sharedmem_page_alloc_user);
+EXPORT_SYMBOL(kgsl_sharedmem_vmalloc_user);
 
 int
 kgsl_sharedmem_alloc_coherent(struct kgsl_memdesc *memdesc, size_t size)
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index a67d9c6..9f8ac08 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -30,12 +30,12 @@
 /** Set if the memdesc describes cached memory */
 #define KGSL_MEMFLAGS_CACHED    0x00000001
 
-extern struct kgsl_memdesc_ops kgsl_page_alloc_ops;
+extern struct kgsl_memdesc_ops kgsl_vmalloc_ops;
 
-int kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc,
+int kgsl_sharedmem_vmalloc(struct kgsl_memdesc *memdesc,
 			   struct kgsl_pagetable *pagetable, size_t size);
 
-int kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc,
+int kgsl_sharedmem_vmalloc_user(struct kgsl_memdesc *memdesc,
 				struct kgsl_pagetable *pagetable,
 				size_t size, int flags);
 
@@ -132,7 +132,7 @@
 {
 	if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_NONE)
 		return kgsl_sharedmem_ebimem(memdesc, pagetable, size);
-	return kgsl_sharedmem_page_alloc(memdesc, pagetable, size);
+	return kgsl_sharedmem_vmalloc(memdesc, pagetable, size);
 }
 
 static inline int
@@ -143,7 +143,7 @@
 	if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_NONE)
 		return kgsl_sharedmem_ebimem_user(memdesc, pagetable, size,
 						  flags);
-	return kgsl_sharedmem_page_alloc_user(memdesc, pagetable, size, flags);
+	return kgsl_sharedmem_vmalloc_user(memdesc, pagetable, size, flags);
 }
 
 static inline int
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index b07a462..394bc83 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -258,7 +258,7 @@
 
 	header->magic = SNAPSHOT_MAGIC;
 
-	header->gpuid = kgsl_gpuid(device, NULL);
+	header->gpuid = kgsl_gpuid(device);
 
 	/* Get a pointer to the first section (right after the header) */
 	snapshot = ((void *) device->snapshot) + sizeof(*header);
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index ae83c1d..1b1ca0b 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -12,8 +12,6 @@
  */
 #include <linux/uaccess.h>
 
-#include <mach/internal_power_rail.h>
-
 #include "kgsl.h"
 #include "kgsl_cffdump.h"
 #include "kgsl_sharedmem.h"
@@ -153,7 +151,6 @@
 		.pwrctrl = {
 			.regulator_name = "fs_gfx2d0",
 			.irq_name = KGSL_2D0_IRQ,
-			.pwr_rail = PWR_RAIL_GRP_2D_CLK,
 		},
 		.mutex = __MUTEX_INITIALIZER(device_2d0.dev.mutex),
 		.state = KGSL_STATE_INIT,
@@ -446,12 +443,13 @@
 	    (ctrl & KGSL_CONTEXT_CTX_SWITCH)) {
 		KGSL_CMD_INFO(device, "context switch %d -> %d\n",
 			context->id, z180_dev->ringbuffer.prevctx);
-		kgsl_mmu_setstate(device, pagetable);
+		kgsl_mmu_setstate(device, pagetable,
+				0);
 		cnt = PACKETSIZE_STATESTREAM;
 		ofs = 0;
 	}
-	kgsl_setstate(device, kgsl_mmu_pt_get_flags(device->mmu.hwpagetable,
-						    device->id));
+	kgsl_setstate(device, 0, kgsl_mmu_pt_get_flags(device->mmu.hwpagetable,
+			device->id));
 
 	result = wait_event_interruptible_timeout(device->wait_queue,
 				  room_in_rb(z180_dev),
@@ -866,7 +864,8 @@
 	if (z180_dev->ringbuffer.prevctx == context->id) {
 		z180_dev->ringbuffer.prevctx = Z180_INVALID_CONTEXT;
 		device->mmu.hwpagetable = device->mmu.defaultpagetable;
-		kgsl_setstate(device, KGSL_MMUFLAGS_PTUPDATE);
+		kgsl_setstate(device, 0,
+				KGSL_MMUFLAGS_PTUPDATE);
 	}
 }
 
@@ -901,11 +900,8 @@
 	}
 }
 
-static unsigned int z180_gpuid(struct kgsl_device *device, unsigned int *chipid)
+static unsigned int z180_gpuid(struct kgsl_device *device)
 {
-	if (chipid != NULL)
-		*chipid = 0;
-
 	/* Standard KGSL gpuid format:
 	 * top word is 0x0002 for 2D or 0x0003 for 3D
 	 * Bottom word is core specific identifer
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index d3870fe..1aa9393 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -1,100 +1,821 @@
+
+source "drivers/video/msm/vidc/Kconfig"
+
 config FB_MSM
-	tristate
+	tristate "MSM Framebuffer support"
 	depends on FB && ARCH_MSM
+	select FB_BACKLIGHT if FB_MSM_BACKLIGHT
+	select NEW_LEDS
+	select LEDS_CLASS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	default y
+	---help---
+	  Support for MSM Framebuffer.
 
-config FB_MSM_LEGACY_MDP
+if FB_MSM
+
+config FB_MSM_BACKLIGHT
+	bool "Support for backlight control"
+	default y
+	---help---
+	  Say Y here if you want to control the backlight of your display.
+
+config FB_MSM_LOGO
+	bool "MSM Frame Buffer Logo"
+	default n
+	---help---
+	  Show /initlogo.rle during boot.
+
+config FB_MSM_LCDC_HW
 	bool
-	depends on FB_MSM && (MSM_MDP30 || MSM_MDP31 || MSM_MDP302)
-	default y
-
-config FB_MSM_MDP_PPP
-	bool
-	depends on FB_MSM_LEGACY_MDP
-	default y
-
-config FB_MSM_LCDC
-	bool "Support for integrated LCD controller in qsd8x50 ,MSM7x27 and MSM7x30"
-	depends on FB_MSM && (MSM_MDP31 || MSM_MDP302 || MSM_MDP40)
-	default y
-
-config FB_MSM_DTV
-	bool "Support for TV-Out in qsd8x50"
-	depends on FB_MSM && MSM_MDP40
 	default n
 
-config FB_MSM_TVOUT
-	bool "Support for TV-Out in qsd8x50"
-	depends on FB_MSM && (MSM_MDP31 || MSM_MDP40)
+config FB_MSM_TRIPLE_BUFFER
+	bool "Support for triple frame buffer"
+	default n
+
+config FB_MSM_MDP_HW
+	bool
+	default n
+
+choice
+	prompt "MDP HW version"
+	default FB_MSM_MDP22
+
+config FB_MSM_MDP22
+	select FB_MSM_MDP_HW
+	bool "MDP HW ver2.2"
+	---help---
+	  Support for MSM MDP HW revision 2.2
+	  Say Y here if this is msm7201 variant platform.
+
+config FB_MSM_MDP30
+	select FB_MSM_LCDC_HW
+	bool "MDP HW ver3.0"
+	---help---
+	  Support for MSM MDP HW revision 3.0
+	  Say Y here if this is msm7x25 variant platform.
+
+config FB_MSM_MDP303
+	depends on FB_MSM_MDP30
+	select FB_MSM_MDP_HW
+	bool "MDP HW ver3.03"
+	default n
+	---help---
+	  Support for MSM MDP HW revision 3.03. This is a new version of
+	  MDP3.0 which has the required functionality to support the features
+	  required for msm7x2xA platform.
+	  Say Y here if this is msm7x2xA variant platform.
+
+config FB_MSM_MDP31
+	select FB_MSM_LCDC_HW
+	select FB_MSM_MDP_HW
+	bool "MDP HW ver3.1"
+	---help---
+	  Support for MSM MDP HW revision 3.1
+	  Say Y here if this is msm8x50 variant platform.
+
+config FB_MSM_MDP40
+	select FB_MSM_LCDC_HW
+	select FB_MSM_MDP_HW
+	bool "MDP HW ver4.0"
+	---help---
+	  Support for MSM MDP HW revision 4.0
+	  Say Y here if this is msm7x30 variant platform.
+
+config FB_MSM_MDP_NONE
+	bool "MDP HW None"
+	---help---
+	  Say Y here if this is mdm platform.
+
+endchoice
+
+config FB_MSM_EBI2
+	bool
+	default n
+
+config FB_MSM_MDDI
+	bool
+	default n
+
+config FB_MSM_MIPI_DSI
+	bool
+	default n
+
+config FB_MSM_LCDC
+	bool
 	default n
 
 config FB_MSM_OVERLAY
-	bool "Support for overlay in MSM7X30"
-	depends on FB_MSM && MSM_MDP40
-	default y
+	depends on FB_MSM_MDP40 && ANDROID_PMEM
+	bool "MDP4 overlay support"
+	default n
 
 config FB_MSM_DTV
 	depends on FB_MSM_OVERLAY
 	bool
 	default n
 
-config FB_MSM_MDP_ABL
-        bool "Support QCT auto backlight scaling"
-        depends on FB_MSM && (MSM_MDP40)
+config FB_MSM_EXTMDDI
+	bool
+	default n
+
+config FB_MSM_TVOUT
+	bool
+	default n
+
+config FB_MSM_MDDI_TOSHIBA_COMMON
+	bool
+	select FB_MSM_MDDI
+	default n
+
+config FB_MSM_MDDI_TOSHIBA_COMMON_VGA
+	bool
+	select FB_MSM_MDDI_TOSHIBA_COMMON
+	default n
+
+config FB_MSM_MDDI_ORISE
+	bool
+	select FB_MSM_MDDI
+	default n
+
+config FB_MSM_MDDI_QUICKVX
+	bool
+	select FB_MSM_MDDI
+	default n
+
+config FB_MSM_MDDI_AUTO_DETECT
+	bool
+	select FB_MSM_MDDI
+	default n
+
+config FB_MSM_LCDC_AUTO_DETECT
+	bool
+	select FB_MSM_LCDC
+	default n
+
+config FB_MSM_LCDC_PANEL
+	bool
+	select FB_MSM_LCDC
+	default n
+
+config FB_MSM_MIPI_DSI_TOSHIBA
+	bool
+	select FB_MSM_MIPI_DSI
+	default n
+
+config FB_MSM_MIPI_DSI_RENESAS
+	bool
+	select FB_MSM_MIPI_DSI
+	default n
+
+config FB_MSM_MIPI_DSI_TRULY
+	bool
+	select FB_MSM_MIPI_DSI
+
+config FB_MSM_MIPI_DSI_SIMULATOR
+	bool
+	select FB_MSM_MIPI_DSI
+	default n
+
+config FB_MSM_MIPI_DSI_NOVATEK
+        bool
+        select FB_MSM_MIPI_DSI
         default n
 
-config MSM_ROTATOR
-        tristate "MSM Offline Image Rotator Driver"
-        depends on ARCH_MSM7X30 && ANDROID_PMEM
+config FB_MSM_MIPI_DSI_ORISE
+        bool
+        select FB_MSM_MIPI_DSI
+        default n
+
+config FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
+	bool
+	select FB_MSM_MIPI_DSI
+	---help---
+	  Support for Toshiba MIPI DSI-to-LVDS bridge.
+	  The chip supports 1366x768 24-bit
+	  using a single LVDS link
+	  and up to WUXGA 1920x1200 18-bit
+	  using a dual LVDS link.
+
+config FB_MSM_LCDC_ST15_WXGA
+    bool
+    select FB_MSM_LCDC_PANEL
+    default n
+
+config FB_MSM_LCDC_ST15_PANEL
+    depends on FB_MSM_LCDC_HW
+    bool "LCDC ST1.5 Panel"
+    select FB_MSM_LCDC_ST15_WXGA
+    ---help---
+      Support for ST1.5 WXGA (1366x768) panel
+
+config FB_MSM_LCDC_PRISM_WVGA
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_SAMSUNG_WSVGA
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_CHIMEI_WXGA
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_GORDON_VGA
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_TOSHIBA_WVGA_PT
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_TOSHIBA_FWVGA_PT
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_SHARP_WVGA_PT
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_AUO_WVGA
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_SAMSUNG_OLED_PT
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_NT35582_WVGA
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_LCDC_WXGA
+	bool
+	select FB_MSM_LCDC_PANEL
+	default n
+
+config FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
+	bool
+	select FB_MSM_MIPI_DSI_TOSHIBA
+	default n
+
+config FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+	bool
+	select FB_MSM_MIPI_DSI_TOSHIBA
+	default n
+
+config FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
+	bool
+	select FB_MSM_MIPI_DSI_TOSHIBA
+	default n
+
+config FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
+	bool
+	select FB_MSM_MIPI_DSI_NOVATEK
+	default n
+
+config FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+	bool
+	select FB_MSM_MIPI_DSI_NOVATEK
+	default n
+
+config FB_MSM_MIPI_ORISE_VIDEO_720P_PT
+	bool
+	select FB_MSM_MIPI_DSI_ORISE
+	default n
+
+config FB_MSM_MIPI_ORISE_CMD_720P_PT
+	bool
+	select FB_MSM_MIPI_DSI_ORISE
+	default n
+
+config FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
+	bool
+	select FB_MSM_MIPI_DSI_RENESAS
+	default n
+
+config FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
+	bool
+	select FB_MSM_MIPI_DSI_RENESAS
+	default n
+
+config FB_MSM_MIPI_CHIMEI_WXGA
+	bool "LVDS Chimei WXGA Panel using Toshiba MIPI DSI-to-LVDS bridge."
+	select FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
+	---help---
+	  Support for Chimei WXGA (1366x768) panel.
+	  The panel is using a serial LVDS input.
+	  The panel is connected to the host
+	  via Toshiba DSI-to-LVDS bridge.
+
+config FB_MSM_MIPI_CHIMEI_WUXGA
+	bool "LVDS Chimei WUXGA Panel using Toshiba MIPI DSI-to-LVDS bridge."
+	select FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
+	---help---
+	  Support for Chimei WUXGA (1920x1200) panel.
+	  The panel is using a serial LVDS input.
+	  The panel is connected to the host
+	  via Toshiba DSI-to-LVDS bridge.
+
+config FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
+	bool
+	select FB_MSM_MIPI_DSI_TRULY
+
+config FB_MSM_MIPI_SIMULATOR_VIDEO
+	bool
+	select FB_MSM_MIPI_DSI_SIMULATOR
+	default n
+
+config FB_MSM_NO_MDP_PIPE_CTRL
+	depends on FB_MSM_OVERLAY
+	bool "Do not use mdp_pipe_ctrl"
+	---help---
+	  Saying 'Y' here obsoletes the mdp_pipe_ctrl function,
+	  which was used to control mdp-related clocks. MDP4 vsync-driven
+	  screen updates will use a different clock control mechanism if
+	  this is selected.
+
+config FB_MSM_OVERLAY0_WRITEBACK
+	depends on FB_MSM_OVERLAY
+        bool "MDP overlay0 write back mode enable"
+	---help---
+	  Support for MDP4 OVERLAY0 write back mode
+
+
+config FB_MSM_OVERLAY1_WRITEBACK
+        depends on FB_MSM_OVERLAY
+        bool "MDP overlay1 write back mode enable"
+        ---help---
+          Support for MDP4 OVERLAY1 write back mode
+
+config FB_MSM_WRITEBACK_MSM_PANEL
+	depends on FB_MSM_OVERLAY
+        bool "MDP overlay write back panel enable"
+	---help---
+	  Support for MDP4 OVERLAY write back mode
+choice
+	prompt "LCD Panel"
+	default FB_MSM_MDDI_AUTO_DETECT
+
+config FB_MSM_LCDC_PRISM_WVGA_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC Prism WVGA Panel"
+	select FB_MSM_LCDC_PRISM_WVGA
+	---help---
+	  Support for LCDC Prism WVGA (800x480) panel
+
+config FB_MSM_LCDC_SAMSUNG_WSVGA_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC Samsung WSVGA Panel"
+	select FB_MSM_LCDC_SAMSUNG_WSVGA
+	---help---
+	  Support for LCDC Samsung WSVGA (1024x600) panel
+
+config FB_MSM_LCDC_CHIMEI_WXGA_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC Chimei WXGA Panel"
+	select FB_MSM_LCDC_CHIMEI_WXGA
+	---help---
+	  Support for LCDC Chimei WXGA (1366x768) panel
+
+config FB_MSM_LCDC_GORDON_VGA_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC Gordon VGA Panel"
+	select FB_MSM_LCDC_GORDON_VGA
+	---help---
+	  Support for LCDC Gordon VGA (480x640) panel
+
+config FB_MSM_LCDC_TOSHIBA_WVGA_PT_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC Toshiba WVGA PT Panel"
+	select FB_MSM_LCDC_TOSHIBA_WVGA_PT
+	---help---
+	  Support for LCDC Toshiba WVGA PT (480x800) panel
+
+config FB_MSM_LCDC_TOSHIBA_FWVGA_PT_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC Toshiba FWVGA PT Panel"
+	select FB_MSM_LCDC_TOSHIBA_FWVGA_PT
+	---help---
+	  Support for LCDC Toshiba FWVGA PT (480x864) panel. This
+	  configuration has to be selected to support the Toshiba
+	  FWVGA (480x864) portrait panel.
+
+config FB_MSM_LCDC_SHARP_WVGA_PT_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC Sharp WVGA PT Panel"
+	select FB_MSM_LCDC_SHARP_WVGA_PT
+	---help---
+	  Support for LCDC Sharp WVGA PT (480x800) panel
+
+config FB_MSM_LCDC_AUO_WVGA_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC AUO WVGA Panel"
+	select FB_MSM_LCDC_AUO_WVGA
+	---help---
+	  Support for LCDC AUO WVGA(480x800) panel
+
+config FB_MSM_LCDC_NT35582_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC NT35582 WVGA Panel"
+	select FB_MSM_LCDC_NT35582_WVGA
+	---help---
+	  Support for LCDC NT35582 WVGA(480x800) panel
+
+config FB_MSM_LCDC_SAMSUNG_OLED_PT_PANEL
+	depends on FB_MSM_LCDC_HW
+	bool "LCDC Samsung OLED PT Panel"
+	select FB_MSM_LCDC_SAMSUNG_OLED_PT
+	---help---
+	  Support for LCDC Samsung OLED PT (480x800) panel
+
+config FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
+	depends on FB_MSM_LCDC_HW
+	bool "MDDI Panel Auto Detect + LCDC Prism WVGA"
+	select FB_MSM_MDDI_AUTO_DETECT
+	select FB_MSM_LCDC_PRISM_WVGA
+	select FB_MSM_LCDC_GORDON_VGA
+	select FB_MSM_LCDC_WXGA
+	select FB_MSM_LCDC_TOSHIBA_WVGA_PT
+	select FB_MSM_LCDC_TOSHIBA_FWVGA_PT
+	select FB_MSM_LCDC_SHARP_WVGA_PT
+	select FB_MSM_LCDC_ST15_WXGA
+	---help---
+	  Support for MDDI panel auto detect.
+	  If it can't find any MDDI panel, it will load an LCDC panel.
+
+config FB_MSM_MIPI_PANEL_DETECT
+	bool "MIPI Panel Detect"
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
+	select FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
+	select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
+	select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
+	select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
+	select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+	select FB_MSM_MIPI_ORISE_VIDEO_720P_PT
+	select FB_MSM_MIPI_ORISE_CMD_720P_PT
+	select FB_MSM_MIPI_SIMULATOR_VIDEO
+	select FB_MSM_MIPI_CHIMEI_WXGA
+	select FB_MSM_MIPI_CHIMEI_WUXGA
+	---help---
+	  Support for MIPI panel auto detect
+
+config FB_MSM_MDDI_PANEL_AUTO_DETECT
+	bool "MDDI Panel Auto Detect"
+	select FB_MSM_MDDI_AUTO_DETECT
+	---help---
+	  Support for MDDI panel auto detect
+
+config FB_MSM_LCDC_PANEL_AUTO_DETECT
+	bool "LCDC Panel Auto Detect"
+	select FB_MSM_LCDC_AUTO_DETECT
+	select FB_MSM_LCDC_SAMSUNG_WSVGA
+	select FB_MSM_LCDC_AUO_WVGA
+	select FB_MSM_LCDC_NT35582_WVGA
+	select FB_MSM_LCDC_SAMSUNG_OLED_PT
+	---help---
+	  Support for LCDC panel auto detect
+
+config FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT
+	bool "LCDC + MIPI Panel Auto Detect"
+	select FB_MSM_LCDC_AUTO_DETECT
+	select FB_MSM_LCDC_SAMSUNG_WSVGA
+	select FB_MSM_LCDC_AUO_WVGA
+	select FB_MSM_LCDC_SAMSUNG_OLED_PT
+	select FB_MSM_LCDC_NT35582_WVGA
+	select FB_MSM_LCDC_TOSHIBA_FWVGA_PT
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+	select FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
+	select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
+	select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
+	select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+	select FB_MSM_MIPI_SIMULATOR_VIDEO
+	---help---
+	  Support for LCDC + MIPI panel auto detect
+
+config FB_MSM_MDDI_PRISM_WVGA
+	bool "MDDI Prism WVGA Panel"
+	select FB_MSM_MDDI
+	---help---
+	  Support for MDDI Prism WVGA (800x480) panel
+
+config FB_MSM_MDDI_TOSHIBA_WVGA_PORTRAIT
+	bool "MDDI Toshiba WVGA Portrait Panel"
+	select FB_MSM_MDDI_TOSHIBA_COMMON
+	---help---
+	  Support for MDDI Toshiba WVGA (480x800) panel
+
+config FB_MSM_MDDI_TOSHIBA_VGA
+	bool "MDDI Toshiba VGA Panel"
+	select FB_MSM_MDDI_TOSHIBA_COMMON_VGA
+	---help---
+	  Support for MDDI Toshiba VGA (480x640) and QCIF (176x220) panel
+
+config FB_MSM_MDDI_TOSHIBA_WVGA
+	bool "MDDI Toshiba WVGA panel"
+	select FB_MSM_MDDI_TOSHIBA_COMMON
+	---help---
+	  Support for MDDI Toshiba (800x480) WVGA panel
+
+config FB_MSM_MDDI_SHARP_QVGA_128x128
+	bool "MDDI Sharp QVGA Dual Panel"
+	select FB_MSM_MDDI
+	---help---
+	  Support for MDDI Sharp QVGA (240x320) and 128x128 dual panel
+
+config FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT_PANEL
+	bool "MIPI Toshiba WVGA PT Panel"
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
+
+config FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT_PANEL
+	bool "MIPI Toshiba WSVGA PT Panel"
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+
+config FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA_PANEL
+	bool "MIPI Toshiba WUXGA (1920x1200) Panel"
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
+
+config FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT_PANEL
+	bool "MIPI NOVATEK VIDEO QHD PT Panel"
+	select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
+
+config FB_MSM_MIPI_NOVATEK_CMD_QHD_PT_PANEL
+	bool "MIPI NOVATEK CMD QHD PT Panel"
+	select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+
+config FB_MSM_MIPI_ORISE_VIDEO_720P_PT_PANEL
+	bool "MIPI ORISE VIDEO 720P PT Panel"
+	select FB_MSM_MIPI_ORISE_VIDEO_720P_PT
+
+config FB_MSM_MIPI_ORISE_CMD_720P_PT_PANEL
+	bool "MIPI ORISE CMD 720P PT Panel"
+	select FB_MSM_MIPI_ORISE_CMD_720P_PT
+
+config FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT_PANEL
+	bool "MIPI Renesas Video FWVGA PT Panel"
+	select FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
+
+config FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT_PANEL
+	bool "MIPI Renesas Command FWVGA PT Panel"
+	select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
+
+config FB_MSM_MIPI_CHIMEI_WXGA_PANEL
+	bool "MIPI Chimei WXGA PT Panel"
+	select FB_MSM_MIPI_CHIMEI_WXGA
+
+config FB_MSM_MIPI_CHIMEI_WUXGA_PANEL
+	bool "MIPI Chimei WUXGA Panel"
+	select FB_MSM_MIPI_CHIMEI_WUXGA
+
+config FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT_PANEL
+	bool "MIPI Truly Video WVGA PT Panel"
+	select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
+
+config FB_MSM_MIPI_SIMULATOR_VIDEO_PANEL
+	bool "MIPI Simulator Video Panel"
+	select FB_MSM_MIPI_SIMULATOR_VIDEO
+
+config FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF
+	bool "EBI2 TMD QVGA Epson QCIF Dual Panel"
+	select FB_MSM_EBI2
+	---help---
+	  Support for EBI2 TMD QVGA (240x320) and Epson QCIF (176x220) panel
+
+config FB_MSM_HDMI_AS_PRIMARY
+	depends on FB_MSM_HDMI_COMMON
+	bool "Use HDMI as primary panel"
+	---help---
+	Support for using HDMI as primary
+
+config FB_MSM_PANEL_NONE
+	bool "NONE"
+	---help---
+	  This will disable LCD panel
+endchoice
+
+choice
+	prompt "Secondary LCD Panel"
+	depends on  FB_MSM_MDP31
+	default FB_MSM_SECONDARY_PANEL_NONE
+
+config FB_MSM_LCDC_EXTERNAL_WXGA
+	depends on FB_MSM_MDP31
+	bool "External WXGA on LCDC"
+	select FB_MSM_LCDC_PANEL
+	---help---
+	  Support for external WXGA display (1280x720)
+
+config FB_MSM_HDMI_SII_EXTERNAL_720P
+	depends on FB_MSM_MDP31
+	bool "External SiI9022 HDMI 720P"
+	select FB_MSM_LCDC_PANEL
+	---help---
+	  Support for external HDMI 720p display (1280x720p)
+	  Using SiI9022 chipset
+
+config FB_MSM_SECONDARY_PANEL_NONE
+	bool "NONE"
+	---help---
+	  No secondary panel
+endchoice
+
+config FB_MSM_LCDC_DSUB
+	depends on FB_MSM_LCDC_SAMSUNG_WSVGA && FB_MSM_MDP40 && FB_MSM_LCDC_HW
+	bool "External DSUB support"
+	default n
+	---help---
+	  Support for external DSUB (VGA) display up to 1440x900.  The DSUB
+	  display shares the same video bus as the primary LCDC attached display.
+	  Typically only one of the two displays can be used at one time.
+
+config FB_MSM_EXT_INTERFACE_COMMON
+	bool
+	default n
+
+config FB_MSM_HDMI_COMMON
+	bool
+	default n
+
+config FB_MSM_HDMI_3D
+	bool
+	default n
+
+config FB_MSM_HDMI_ADV7520_PANEL
+	depends on FB_MSM_MDP40 && FB_MSM_OVERLAY
+        bool "LCDC HDMI ADV7520 720p Panel"
+        select FB_MSM_DTV
+        select FB_MSM_EXT_INTERFACE_COMMON
+	select FB_MSM_HDMI_COMMON
+	default n
+        ---help---
+        Support for LCDC 720p HDMI panel attached to ADV7520
+
+config FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+        depends on FB_MSM_HDMI_ADV7520_PANEL
+        bool "Use HDCP mode"
         default y
-        help
-          This driver provides support for the image rotator HW block in the
-          MSM 7x30 SoC.
+        ---help---
+          Support for HDCP mode for ADV7520 HDMI 720p Panel
+          Choose to enable HDCP
 
-config MSM_ROTATOR_USE_IMEM
-        bool "Enable rotator driver to use iMem"
-        depends on MSM_ROTATOR
-        default y
-        help
-          This option enables the msm_rotator driver to use the move efficient
-          iMem.  Some MSM platforms may not have iMem available for the rotator
-          block.  Or some systems may want the iMem to be dedicated to a
-          different function.
 
-config MSM_HDMI_COMMON
-	bool "Turn on HDMI common interface"
-	depends on FB_MSM_OVERLAY && MSM_MDP40
-	bool
+config FB_MSM_HDMI_MSM_PANEL
+	depends on FB_MSM_MDP40
+	bool "MSM HDMI 1080p Panel"
+	select FB_MSM_DTV
+        select FB_MSM_EXT_INTERFACE_COMMON
+	select FB_MSM_HDMI_COMMON
+	select FB_MSM_HDMI_3D
 	default n
+	---help---
+	  Support for 480p/720p/1080i/1080p output through MSM HDMI
 
-config MSM_HDMI
-	bool "Support for HDMI in QCT platform"
-	depends on MSM_MDP31 || MSM_MDP40
+config FB_MSM_HDMI_MSM_PANEL_DVI_SUPPORT
+	depends on FB_MSM_HDMI_MSM_PANEL
+	bool "Use DVI mode"
 	default n
+	---help---
+	  Support for DVI mode for MSM HDMI 1080p Panel
 
-config MSM_HDMI_MHL
-	bool "Turn on MHL chip driver"
-	depends on FB_MSM_OVERLAY && MSM_MDP40
-	bool
+config FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	depends on FB_MSM_HDMI_MSM_PANEL
+	bool "Use HDCP mode"
+	default y
+	---help---
+	  Support for HDCP mode for MSM HDMI 1080p Panel
+	  Choose to enable HDCP
+
+config FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	depends on FB_MSM_HDMI_MSM_PANEL
+	bool "Enable CEC"
 	default n
+	---help---
+	  Support for HDMI CEC Feature
+	  Choose to enable CEC
 
-config MSM_HDMI_MHL_SII9232
-	bool "support sii9232 driver"
-	depends on MSM_HDMI_MHL && MSM_MDP40
-	bool
+config FB_MSM_HDMI_MHL
+	depends on FB_MSM_HDMI_MSM_PANEL
+	bool 'HDMI to MHL support'
 	default n
+	---help---
+	  Support the HDMI to MHL conversion.
+	  MHL (Mobile High-Definition Link) technology
+	  uses USB connector to output HDMI content
 
-config MDP_UNDERRUN_WORKAROUND_DISABLED
-	bool "Disable MDP workaround"
-	depends on FB_MSM
+choice
+	depends on  (FB_MSM_MDP22 || FB_MSM_MDP31 || FB_MSM_MDP40)
+	prompt "TVOut Region"
+	default FB_MSM_TVOUT_NONE
+
+config FB_MSM_TVOUT_NTSC_M
+	bool "NTSC M"
+	select FB_MSM_TVOUT
+        select FB_MSM_EXT_INTERFACE_COMMON
+	---help---
+	  Support for NTSC M region (North American and Korea)
+
+config FB_MSM_TVOUT_NTSC_J
+	bool "NTSC J"
+	select FB_MSM_TVOUT
+        select FB_MSM_EXT_INTERFACE_COMMON
+	---help---
+	  Support for NTSC J region (Japan)
+
+config FB_MSM_TVOUT_PAL_BDGHIN
+	bool "PAL BDGHIN"
+	select FB_MSM_TVOUT
+        select FB_MSM_EXT_INTERFACE_COMMON
+	---help---
+	  Support for PAL BDGHIN region (Non-argentina PAL-N)
+
+config FB_MSM_TVOUT_PAL_M
+	bool "PAL M"
+	select FB_MSM_TVOUT
+        select FB_MSM_EXT_INTERFACE_COMMON
+	---help---
+	  Support for PAL M region
+
+config FB_MSM_TVOUT_PAL_N
+	bool "PAL N"
+	select FB_MSM_TVOUT
+        select FB_MSM_EXT_INTERFACE_COMMON
+	---help---
+	  Support for PAL N region (Argentina PAL-N)
+
+config FB_MSM_TVOUT_NONE
+	bool "NONE"
+	---help---
+	  This will disable TV Out functionality.
+endchoice
+
+config FB_MSM_TVOUT_SVIDEO
+	bool "TVOut on S-video"
+	depends on FB_MSM_TVOUT
 	default n
+	---help---
+	  Selects whether the TVOut signal uses S-video.
+	  Choose n for composite output.
 
-config MDP4_HW_VSYNC
-	bool "QCT hardware TE"
-	depends on MSM_MDP40
+choice
+	depends on  FB_MSM_MDP22
+	prompt "External MDDI"
+	default FB_MSM_EXTMDDI_SVGA
+
+config FB_MSM_EXTMDDI_SVGA
+	bool "External MDDI SVGA"
+	select FB_MSM_MDDI
+	select FB_MSM_EXTMDDI
+	---help---
+	  Support for MSM SVGA (800x600) external MDDI panel
+
+config FB_MSM_EXTMDDI_NONE
+	bool "NONE"
+	---help---
+	  This will disable External MDDI functionality.
+endchoice
+
+choice
+	prompt "Default framebuffer color depth"
+	depends on FB_MSM_MDP40 || FB_MSM_MDP31 || FB_MSM_MDP303
+	default FB_MSM_DEFAULT_DEPTH_RGBA8888
+
+config FB_MSM_DEFAULT_DEPTH_RGB565
+	bool "16 bits per pixel (RGB565)"
+
+config FB_MSM_DEFAULT_DEPTH_ARGB8888
+	bool "32 bits per pixel (ARGB8888)"
+
+config FB_MSM_DEFAULT_DEPTH_RGBA8888
+	bool "32 bits per pixel (RGBA8888)"
+
+endchoice
+
+config FB_MSM_EBI2_EPSON_S1D_QVGA_PANEL
+	bool "EBI2 Epson QVGA Panel"
+	select FB_MSM_EBI2
 	default n
+	---help---
+	  Support for EBI2 Epson QVGA (240x320) panel
 
-source "drivers/video/msm/vidc/Kconfig"
+config FB_MSM_EBI2_PANEL_DETECT
+	bool "EBI2 Panel Detect"
+	select FB_MSM_EBI2_EPSON_S1D_QVGA_PANEL
+	default n
+	---help---
+	  Support for EBI2 panel auto detect
+endif
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index bf8b1cd..f3fe161 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -1,45 +1,176 @@
+obj-y := msm_fb.o
 
-# core framebuffer
-#
-obj-y := msm_fb.o logo.o
-ifeq ($(CONFIG_FB_MSM_LOGO),y)
-obj-y += logo.o
-endif
+obj-$(CONFIG_FB_MSM_LOGO) += logo.o
+obj-$(CONFIG_FB_BACKLIGHT) += msm_fb_bl.o
 
-# MDP DMA/PPP engine
-#
+ifeq ($(CONFIG_FB_MSM_MDP_HW),y)
+
+# MDP
 obj-y += mdp.o
-obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_util.o
-obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_overlay.o
-obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_overlay_mddi.o
 
-obj-$(CONFIG_FB_MSM_LEGACY_MDP) += mdp_hw_legacy.o
+obj-$(CONFIG_DEBUG_FS) += mdp_debugfs.o
 
-obj-$(CONFIG_FB_MSM_MDP_PPP) += mdp_ppp.o
-obj-$(CONFIG_MSM_MDP22) += mdp_ppp22.o
-obj-$(CONFIG_MSM_MDP30) += mdp_ppp22.o
-obj-$(CONFIG_MSM_MDP302)+= mdp_ppp22.o
-obj-$(CONFIG_MSM_MDP31) += mdp_ppp31.o
-
-# MDDI interface
-#
-obj-y += mddi.o
-
-# MDDI client/panel drivers
-#
-ifdef CONFIG_ARCH_MSM7X30
-obj-y += mddi_client_dummy.o
-obj-y += mddi_client_toshiba.o
-obj-y += mddi_client_novb9f6_5580.o
-obj-y += mddi_client_novb9f6_5560.o
-obj-y += mddi_client_renesas_R61408.o
-obj-y += mddi_client_hx8356.o mddi_himax_cabc.o
+ifeq ($(CONFIG_FB_MSM_MDP40),y)
+obj-y += mdp4_util.o
+obj-y += mdp4_hsic.o
+else
+obj-y += mdp_hw_init.o
+obj-y += mdp_ppp.o
+ifeq ($(CONFIG_FB_MSM_MDP31),y)
+obj-y += mdp_ppp_v31.o
+else
+obj-y += mdp_ppp_v20.o
+endif
 endif
 
-# MDP LCD controller driver
-obj-$(CONFIG_FB_MSM_LCDC) += mdp_lcdc.o
-obj-$(CONFIG_FB_MSM_DTV) += mdp_dtv.o
-obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o tvfb.o
+ifeq ($(CONFIG_FB_MSM_OVERLAY),y)
+obj-y += mdp4_overlay.o
+obj-y += mdp4_overlay_lcdc.o
+ifeq ($(CONFIG_FB_MSM_MIPI_DSI),y)
+obj-y += mdp4_overlay_dsi_video.o
+obj-y += mdp4_overlay_dsi_cmd.o
+else
+obj-y += mdp4_overlay_mddi.o
+endif
+else
+obj-y += mdp_dma_lcdc.o
+endif
 
+obj-$(CONFIG_FB_MSM_MDP303) += mdp_dma_dsi_video.o
+
+ifeq ($(CONFIG_FB_MSM_DTV),y)
+obj-y += mdp4_dtv.o
+obj-y += mdp4_overlay_dtv.o
+endif
+
+obj-y += mdp_dma.o
+obj-y += mdp_dma_s.o
+obj-y += mdp_vsync.o
+obj-y += mdp_cursor.o
+obj-y += mdp_dma_tv.o
+obj-$(CONFIG_ARCH_MSM7X27A) += msm_dss_io_7x27a.o
+obj-$(CONFIG_ARCH_MSM8X60) += msm_dss_io_8x60.o
+obj-$(CONFIG_ARCH_MSM8960) += msm_dss_io_8960.o
+
+# EBI2
+obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o
+
+# LCDC
+obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o
+
+# MDDI
+msm_mddi-objs := mddi.o mddihost.o mddihosti.o
+obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o
+
+# External MDDI
+msm_mddi_ext-objs := mddihost_e.o mddi_ext.o
+obj-$(CONFIG_FB_MSM_EXTMDDI) += msm_mddi_ext.o
+
+# MIPI gereric
+msm_mipi-objs := mipi_dsi.o mipi_dsi_host.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI) += msm_mipi.o
+
+# MIPI manufacture
+obj-$(CONFIG_FB_MSM_MIPI_DSI_TOSHIBA) += mipi_toshiba.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_NOVATEK) += mipi_novatek.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_ORISE) += mipi_orise.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_RENESAS) += mipi_renesas.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_TRULY) += mipi_truly.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_SIMULATOR) += mipi_simulator.o
+
+# MIPI Bridge
+obj-$(CONFIG_FB_MSM_MIPI_DSI_TC358764_DSI2LVDS) += mipi_tc358764_dsi2lvds.o
+
+# TVEnc
+obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o
+ifeq ($(CONFIG_FB_MSM_OVERLAY),y)
+obj-$(CONFIG_FB_MSM_TVOUT) += mdp4_overlay_atv.o
+endif
+
+# MSM FB Panel
+obj-y += msm_fb_panel.o
+obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_tmd20.o
+obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_l2f.o
+
+ifeq ($(CONFIG_FB_MSM_MDDI_AUTO_DETECT),y)
+obj-y += mddi_prism.o
+obj-y += mddi_toshiba.o
+obj-y += mddi_toshiba_vga.o
+obj-y += mddi_toshiba_wvga_pt.o
+obj-y += mddi_toshiba_wvga.o
+obj-y += mddi_sharp.o
+obj-y += mddi_orise.o
+obj-y += mddi_quickvx.o
+else
+obj-$(CONFIG_FB_MSM_MDDI_PRISM_WVGA) += mddi_prism.o
+obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON) += mddi_toshiba.o
+obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON_VGA) += mddi_toshiba_vga.o
+obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA_PORTRAIT) += mddi_toshiba_wvga_pt.o
+obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA) += mddi_toshiba_wvga.o
+obj-$(CONFIG_FB_MSM_MDDI_SHARP_QVGA_128x128) += mddi_sharp.o
+obj-$(CONFIG_FB_MSM_MDDI_ORISE) += mddi_orise.o
+obj-$(CONFIG_FB_MSM_MDDI_QUICKVX) += mddi_quickvx.o
+endif
+
+ifeq ($(CONFIG_FB_MSM_MIPI_PANEL_DETECT),y)
+obj-y += mipi_toshiba_video_wvga_pt.o mipi_toshiba_video_wsvga_pt.o mipi_toshiba_video_wuxga.o
+obj-y += mipi_novatek_video_qhd_pt.o mipi_novatek_cmd_qhd_pt.o
+obj-y += mipi_orise_video_720p_pt.o mipi_orise_cmd_720p_pt.o
+obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_pt.o
+obj-y += mipi_chimei_wxga_pt.o
+obj-y += mipi_chimei_wuxga.o
+obj-y += mipi_truly_video_wvga_pt.o
+else
+obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT) += mipi_toshiba_video_wvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT) += mipi_toshiba_video_wsvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA) += mipi_toshiba_video_wuxga.o
+obj-$(CONFIG_FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT) += mipi_novatek_video_qhd_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_ORISE_VIDEO_720P_PT) += mipi_orise_video_720p_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_ORISE_CMD_720P_PT) += mipi_orise_cmd_720p_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_NOVATEK_CMD_QHD_PT) += mipi_novatek_cmd_qhd_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT) += mipi_renesas_video_fwvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT) += mipi_renesas_cmd_fwvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT) += mipi_truly_video_wvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_SIMULATOR_VIDEO) += mipi_simulator_video.o
+obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WXGA) += mipi_chimei_wxga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WUXGA) += mipi_chimei_wuxga.o
+endif
+
+obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
+obj-$(CONFIG_FB_MSM_LCDC_PRISM_WVGA) += lcdc_prism.o
+obj-$(CONFIG_FB_MSM_LCDC_SAMSUNG_WSVGA) += lcdc_samsung_wsvga.o
+obj-$(CONFIG_FB_MSM_LCDC_CHIMEI_WXGA) += lcdc_chimei_wxga.o
+obj-$(CONFIG_FB_MSM_LCDC_NT35582_WVGA) += lcdc_nt35582_wvga.o
+obj-$(CONFIG_FB_MSM_LCDC_EXTERNAL_WXGA) += lcdc_external.o
+obj-$(CONFIG_FB_MSM_HDMI_SII_EXTERNAL_720P) += hdmi_sii9022.o
+obj-$(CONFIG_FB_MSM_LCDC_GORDON_VGA) += lcdc_gordon.o
+obj-$(CONFIG_FB_MSM_LCDC_WXGA) += lcdc_wxga.o
+obj-$(CONFIG_FB_MSM_LCDC_TOSHIBA_WVGA_PT) += lcdc_toshiba_wvga_pt.o
+obj-$(CONFIG_FB_MSM_LCDC_TOSHIBA_FWVGA_PT) += lcdc_toshiba_fwvga_pt.o
+obj-$(CONFIG_FB_MSM_LCDC_SHARP_WVGA_PT) += lcdc_sharp_wvga_pt.o
+obj-$(CONFIG_FB_MSM_LCDC_AUO_WVGA) += lcdc_auo_wvga.o
+obj-$(CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT) += lcdc_samsung_oled_pt.o
+obj-$(CONFIG_FB_MSM_HDMI_ADV7520_PANEL) += adv7520.o
+obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o
+obj-$(CONFIG_FB_MSM_HDMI_MSM_PANEL) += hdmi_msm.o
+obj-$(CONFIG_FB_MSM_EXT_INTERFACE_COMMON) += external_common.o
+
+obj-$(CONFIG_FB_MSM_TVOUT) += tvout_msm.o
+
+obj-$(CONFIG_FB_MSM_EXTMDDI_SVGA) += mddi_ext_lcd.o
+
+obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_wfd_writeback_panel.o
+obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_wfd_writeback.o
+obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_overlay_writeback.o
+
+obj-$(CONFIG_MSM_VIDC_1080P) += vidc/
 obj-$(CONFIG_MSM_VIDC_720P) += vidc/
+else
+obj-$(CONFIG_FB_MSM_EBI2) += ebi2_host.o
+obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o
+obj-y += msm_fb_panel.o
+obj-$(CONFIG_FB_MSM_EBI2_EPSON_S1D_QVGA_PANEL) += ebi2_epson_s1d_qvga.o
+endif
 
+clean:
+	rm *.o .*cmd
diff --git a/drivers/video/msm/adv7520.c b/drivers/video/msm/adv7520.c
new file mode 100644
index 0000000..c0fb370
--- /dev/null
+++ b/drivers/video/msm/adv7520.c
@@ -0,0 +1,1029 @@
+/* Copyright (c) 2010,2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/i2c.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/adv7520.h>
+#include <linux/time.h>
+#include <linux/completion.h>
+#include <linux/wakelock.h>
+#include <linux/clk.h>
+#include <asm/atomic.h>
+#include "msm_fb.h"
+
+#define DEBUG
+#define DEV_DBG_PREFIX "HDMI: "
+
+#include "external_common.h"
+
+/* #define PORT_DEBUG */
+/* #define TESTING_FORCE_480p */
+
+#define HPD_DUTY_CYCLE	4 /*secs*/
+
+static struct external_common_state_type hdmi_common;
+
+static struct i2c_client *hclient;
+static struct clk *tv_enc_clk;
+
+static bool chip_power_on = FALSE;	/* For chip power on/off */
+static bool enable_5v_on = FALSE;
+static bool hpd_power_on = FALSE;
+static atomic_t comm_power_on;	/* For dtv power on/off (I2C) */
+static int suspend_count;
+
+static u8 reg[256];	/* HDMI panel registers */
+
+struct hdmi_data {
+	struct msm_hdmi_platform_data *pd;
+	struct work_struct isr_work;
+};
+static struct hdmi_data *dd;
+static struct work_struct hpd_timer_work;
+
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+static struct work_struct hdcp_handle_work;
+static int hdcp_activating;
+static DEFINE_MUTEX(hdcp_state_mutex);
+static int has_hdcp_hw_support = true;
+#endif
+
+static struct timer_list hpd_timer;
+static struct timer_list hpd_duty_timer;
+static struct work_struct hpd_duty_work;
+static unsigned int monitor_sense;
+static boolean hpd_cable_chg_detected;
+
+struct wake_lock wlock;
+
+/* Change HDMI state */
+static void change_hdmi_state(int online)
+{
+	if (!external_common_state)
+		return;
+
+	mutex_lock(&external_common_state_hpd_mutex);
+	external_common_state->hpd_state = online;
+	mutex_unlock(&external_common_state_hpd_mutex);
+
+	if (!external_common_state->uevent_kobj)
+		return;
+
+	if (online) {
+		kobject_uevent(external_common_state->uevent_kobj,
+			KOBJ_ONLINE);
+		switch_set_state(&external_common_state->sdev, 1);
+	} else {
+		kobject_uevent(external_common_state->uevent_kobj,
+			KOBJ_OFFLINE);
+		switch_set_state(&external_common_state->sdev, 0);
+	}
+	DEV_INFO("adv7520_uevent: %d [suspend# %d]\n", online, suspend_count);
+}
+
+
+/*
+ * Read a value from a register on ADV7520 device
+ * If sucessfull returns value read , otherwise error.
+ */
+static u8 adv7520_read_reg(struct i2c_client *client, u8 reg)
+{
+	int err;
+	struct i2c_msg msg[2];
+	u8 reg_buf[] = { reg };
+	u8 data_buf[] = { 0 };
+
+	if (!client->adapter)
+		return -ENODEV;
+	if (!atomic_read(&comm_power_on)) {
+		DEV_WARN("%s: WARN: missing GPIO power\n", __func__);
+		return -ENODEV;
+	}
+
+	msg[0].addr = client->addr;
+	msg[0].flags = 0;
+	msg[0].len = 1;
+	msg[0].buf = reg_buf;
+
+	msg[1].addr = client->addr;
+	msg[1].flags = I2C_M_RD;
+	msg[1].len = 1;
+	msg[1].buf = data_buf;
+
+	err = i2c_transfer(client->adapter, msg, 2);
+
+	if (err < 0) {
+		DEV_INFO("%s: I2C err: %d\n", __func__, err);
+		return err;
+	}
+
+#ifdef PORT_DEBUG
+	DEV_INFO("HDMI[%02x] [R] %02x\n", reg, data);
+#endif
+	return *data_buf;
+}
+
+/*
+ * Write a value to a register on adv7520 device.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int adv7520_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+	int err;
+	struct i2c_msg msg[1];
+	unsigned char data[2];
+
+	if (!client->adapter)
+		return -ENODEV;
+	if (!atomic_read(&comm_power_on)) {
+		DEV_WARN("%s: WARN: missing GPIO power\n", __func__);
+		return -ENODEV;
+	}
+
+	msg->addr = client->addr;
+	msg->flags = 0;
+	msg->len = 2;
+	msg->buf = data;
+	data[0] = reg;
+	data[1] = val;
+
+	err = i2c_transfer(client->adapter, msg, 1);
+	if (err >= 0)
+		return 0;
+#ifdef PORT_DEBUG
+	DEV_INFO("HDMI[%02x] [W] %02x [%d]\n", reg, val, err);
+#endif
+	return err;
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+static void adv7520_close_hdcp_link(void)
+{
+	if (!external_common_state->hdcp_active && !hdcp_activating)
+		return;
+
+	DEV_INFO("HDCP: Close link\n");
+
+	reg[0xD5] = adv7520_read_reg(hclient, 0xD5);
+	reg[0xD5] &= 0xFE;
+	adv7520_write_reg(hclient, 0xD5, (u8)reg[0xD5]);
+
+	reg[0x16] = adv7520_read_reg(hclient, 0x16);
+	reg[0x16] &= 0xFE;
+	adv7520_write_reg(hclient, 0x16, (u8)reg[0x16]);
+
+	/* UnMute Audio */
+	adv7520_write_reg(hclient, 0x0C, (u8)0x84);
+
+	external_common_state->hdcp_active = FALSE;
+	mutex_lock(&hdcp_state_mutex);
+	hdcp_activating = FALSE;
+	mutex_unlock(&hdcp_state_mutex);
+}
+
+static void adv7520_comm_power(int on, int show);
+static void adv7520_hdcp_enable(struct work_struct *work)
+{
+	DEV_INFO("HDCP: Start reg[0xaf]=%02x (mute audio)\n", reg[0xaf]);
+
+	adv7520_comm_power(1, 1);
+
+	/* Mute Audio */
+	adv7520_write_reg(hclient, 0x0C, (u8)0xC3);
+
+	msleep(200);
+	/* Wait for BKSV ready interrupt */
+	/* Read BKSV's keys from HDTV */
+	reg[0xBF] = adv7520_read_reg(hclient, 0xBF);
+	reg[0xC0] = adv7520_read_reg(hclient, 0xC0);
+	reg[0xC1] = adv7520_read_reg(hclient, 0xC1);
+	reg[0xC2] = adv7520_read_reg(hclient, 0xC2);
+	reg[0xc3] = adv7520_read_reg(hclient, 0xC3);
+
+	DEV_DBG("HDCP: BKSV={%02x,%02x,%02x,%02x,%02x}\n", reg[0xbf], reg[0xc0],
+		reg[0xc1], reg[0xc2], reg[0xc3]);
+
+	/* Is SINK repeater */
+	reg[0xBE] = adv7520_read_reg(hclient, 0xBE);
+	if (~(reg[0xBE] & 0x40)) {
+		; /* compare with revocation list */
+		/* Check 20 1's and 20 zero's */
+	} else {
+		/* Don't implement HDCP if sink as a repeater */
+		adv7520_write_reg(hclient, 0x0C, (u8)0x84);
+		mutex_lock(&hdcp_state_mutex);
+		hdcp_activating = FALSE;
+		mutex_unlock(&hdcp_state_mutex);
+		DEV_WARN("HDCP: Sink Repeater (%02x), (unmute audio)\n",
+			reg[0xbe]);
+
+		adv7520_comm_power(0, 1);
+		return;
+	}
+
+	msleep(200);
+	reg[0xB8] = adv7520_read_reg(hclient, 0xB8);
+	DEV_INFO("HDCP: Status reg[0xB8] is %02x\n", reg[0xb8]);
+	if (reg[0xb8] & 0x40) {
+		/* UnMute Audio */
+		adv7520_write_reg(hclient, 0x0C, (u8)0x84);
+		DEV_INFO("HDCP: A/V content Encrypted (unmute audio)\n");
+		external_common_state->hdcp_active = TRUE;
+	}
+	adv7520_comm_power(0, 1);
+
+	mutex_lock(&hdcp_state_mutex);
+	hdcp_activating = FALSE;
+	mutex_unlock(&hdcp_state_mutex);
+}
+#endif
+
+static int adv7520_read_edid_block(int block, uint8 *edid_buf)
+{
+	u8 r = 0;
+	int ret;
+	struct i2c_msg msg[] = {
+		{ .addr = reg[0x43] >> 1,
+		  .flags = 0,
+		  .len = 1,
+		  .buf = &r },
+		{ .addr = reg[0x43] >> 1,
+		  .flags = I2C_M_RD,
+		  .len = 0x100,
+		  .buf = edid_buf } };
+
+	if (block > 0)
+		return 0;
+	ret = i2c_transfer(hclient->adapter, msg, 2);
+	DEV_DBG("EDID block: addr=%02x, ret=%d\n", reg[0x43] >> 1, ret);
+	return (ret < 2) ? -ENODEV : 0;
+}
+
+static void adv7520_read_edid(void)
+{
+	external_common_state->read_edid_block = adv7520_read_edid_block;
+	if (hdmi_common_read_edid()) {
+		u8 timeout;
+		DEV_INFO("%s: retry\n", __func__);
+		adv7520_write_reg(hclient, 0xc9, 0x13);
+		msleep(500);
+		timeout = (adv7520_read_reg(hclient, 0x96) & (1 << 2));
+		if (timeout) {
+			hdmi_common_read_edid();
+		}
+	}
+}
+
+static void adv7520_chip_on(void)
+{
+	if (!chip_power_on) {
+		/* Get the current register holding the power bit. */
+		unsigned long reg0xaf = adv7520_read_reg(hclient, 0xaf);
+
+		dd->pd->core_power(1, 1);
+
+		/* Set the HDMI select bit. */
+		set_bit(1, &reg0xaf);
+		DEV_INFO("%s: turn on chip power\n", __func__);
+		adv7520_write_reg(hclient, 0x41, 0x10);
+		adv7520_write_reg(hclient, 0xaf, (u8)reg0xaf);
+		chip_power_on = TRUE;
+	} else
+		DEV_INFO("%s: chip already has power\n", __func__);
+}
+
+static void adv7520_chip_off(void)
+{
+	if (chip_power_on) {
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+		if (has_hdcp_hw_support)
+			adv7520_close_hdcp_link();
+#endif
+
+		DEV_INFO("%s: turn off chip power\n", __func__);
+		adv7520_write_reg(hclient, 0x41, 0x50);
+		dd->pd->core_power(0, 1);
+		chip_power_on = FALSE;
+	} else
+		DEV_INFO("%s: chip is already off\n", __func__);
+
+	monitor_sense = 0;
+	hpd_cable_chg_detected = FALSE;
+
+	if (enable_5v_on) {
+		dd->pd->enable_5v(0);
+		enable_5v_on = FALSE;
+	}
+}
+
+/*  Power ON/OFF  ADV7520 chip */
+static void adv7520_isr_w(struct work_struct *work);
+static void adv7520_comm_power(int on, int show)
+{
+	if (!on)
+		atomic_dec(&comm_power_on);
+	dd->pd->comm_power(on, 0/*show*/);
+	if (on)
+		atomic_inc(&comm_power_on);
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+static void adv7520_start_hdcp(void);
+#endif
+static int adv7520_power_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+
+	clk_prepare_enable(tv_enc_clk);
+	external_common_state->dev = &pdev->dev;
+	if (mfd != NULL) {
+		DEV_INFO("adv7520_power: ON (%dx%d %d)\n",
+			mfd->var_xres, mfd->var_yres, mfd->var_pixclock);
+		hdmi_common_get_video_format_from_drv_data(mfd);
+	}
+
+	adv7520_comm_power(1, 1);
+	/* Check if HPD is signaled */
+	if (adv7520_read_reg(hclient, 0x42) & (1 << 6)) {
+		DEV_INFO("power_on: cable detected\n");
+		monitor_sense = adv7520_read_reg(hclient, 0xC6);
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+		if (has_hdcp_hw_support) {
+			if (!hdcp_activating)
+				adv7520_start_hdcp();
+		}
+#endif
+	} else
+		DEV_INFO("power_on: cable NOT detected\n");
+	adv7520_comm_power(0, 1);
+	wake_lock(&wlock);
+
+	return 0;
+}
+
+static int adv7520_power_off(struct platform_device *pdev)
+{
+	DEV_INFO("power_off\n");
+	adv7520_comm_power(1, 1);
+	adv7520_chip_off();
+	wake_unlock(&wlock);
+	adv7520_comm_power(0, 1);
+	clk_disable_unprepare(tv_enc_clk);
+	return 0;
+}
+
+
+/* AV7520 chip specific initialization */
+static void adv7520_chip_init(void)
+{
+	/* Initialize the variables used to read/write the ADV7520 chip. */
+	memset(&reg, 0xff, sizeof(reg));
+
+	/* Get the values from the "Fixed Registers That Must Be Set". */
+	reg[0x98] = adv7520_read_reg(hclient, 0x98);
+	reg[0x9c] = adv7520_read_reg(hclient, 0x9c);
+	reg[0x9d] = adv7520_read_reg(hclient, 0x9d);
+	reg[0xa2] = adv7520_read_reg(hclient, 0xa2);
+	reg[0xa3] = adv7520_read_reg(hclient, 0xa3);
+	reg[0xde] = adv7520_read_reg(hclient, 0xde);
+
+	/* Get the "HDMI/DVI Selection" register. */
+	reg[0xaf] = adv7520_read_reg(hclient, 0xaf);
+
+	/* Read Packet Memory I2C Address */
+	reg[0x45] = adv7520_read_reg(hclient, 0x45);
+
+	/* Hard coded values provided by ADV7520 data sheet. */
+	reg[0x98] = 0x03;
+	reg[0x9c] = 0x38;
+	reg[0x9d] = 0x61;
+	reg[0xa2] = 0x94;
+	reg[0xa3] = 0x94;
+	reg[0xde] = 0x88;
+
+	/* Set the HDMI select bit. */
+	reg[0xaf] |= 0x16;
+
+	/* Set the audio related registers. */
+	reg[0x01] = 0x00;
+	reg[0x02] = 0x2d;
+	reg[0x03] = 0x80;
+	reg[0x0a] = 0x4d;
+	reg[0x0b] = 0x0e;
+	reg[0x0c] = 0x84;
+	reg[0x0d] = 0x10;
+	reg[0x12] = 0x00;
+	reg[0x14] = 0x00;
+	reg[0x15] = 0x20;
+	reg[0x44] = 0x79;
+	reg[0x73] = 0x01;
+	reg[0x76] = 0x00;
+
+	/* Set 720p display related registers */
+	reg[0x16] = 0x00;
+
+	reg[0x18] = 0x46;
+	reg[0x55] = 0x00;
+	reg[0x3c] = 0x04;
+
+	/* Set Interrupt Mask register for HPD/HDCP */
+	reg[0x94] = 0xC0;
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+	if (has_hdcp_hw_support)
+		reg[0x95] = 0xC0;
+	else
+		reg[0x95] = 0x00;
+#else
+	reg[0x95] = 0x00;
+#endif
+	adv7520_write_reg(hclient, 0x94, reg[0x94]);
+	adv7520_write_reg(hclient, 0x95, reg[0x95]);
+
+	/* Set Packet Memory I2C Address */
+	reg[0x45] = 0x74;
+
+	/* Set the values from the "Fixed Registers That Must Be Set". */
+	adv7520_write_reg(hclient, 0x98, reg[0x98]);
+	adv7520_write_reg(hclient, 0x9c, reg[0x9c]);
+	adv7520_write_reg(hclient, 0x9d, reg[0x9d]);
+	adv7520_write_reg(hclient, 0xa2, reg[0xa2]);
+	adv7520_write_reg(hclient, 0xa3, reg[0xa3]);
+	adv7520_write_reg(hclient, 0xde, reg[0xde]);
+
+	/* Set the "HDMI/DVI Selection" register. */
+	adv7520_write_reg(hclient, 0xaf, reg[0xaf]);
+
+	/* Set EDID Monitor address */
+	reg[0x43] = 0x7E;
+	adv7520_write_reg(hclient, 0x43, reg[0x43]);
+
+	/* Enable the i2s audio input. */
+	adv7520_write_reg(hclient, 0x01, reg[0x01]);
+	adv7520_write_reg(hclient, 0x02, reg[0x02]);
+	adv7520_write_reg(hclient, 0x03, reg[0x03]);
+	adv7520_write_reg(hclient, 0x0a, reg[0x0a]);
+	adv7520_write_reg(hclient, 0x0b, reg[0x0b]);
+	adv7520_write_reg(hclient, 0x0c, reg[0x0c]);
+	adv7520_write_reg(hclient, 0x0d, reg[0x0d]);
+	adv7520_write_reg(hclient, 0x12, reg[0x12]);
+	adv7520_write_reg(hclient, 0x14, reg[0x14]);
+	adv7520_write_reg(hclient, 0x15, reg[0x15]);
+	adv7520_write_reg(hclient, 0x44, reg[0x44]);
+	adv7520_write_reg(hclient, 0x73, reg[0x73]);
+	adv7520_write_reg(hclient, 0x76, reg[0x76]);
+
+	/* Enable 720p display */
+	adv7520_write_reg(hclient, 0x16, reg[0x16]);
+	adv7520_write_reg(hclient, 0x18, reg[0x18]);
+	adv7520_write_reg(hclient, 0x55, reg[0x55]);
+	adv7520_write_reg(hclient, 0x3c, reg[0x3c]);
+
+	/* Set Packet Memory address to avoid conflict
+	with Bosch Accelerometer */
+	adv7520_write_reg(hclient, 0x45, reg[0x45]);
+
+	/* Ensure chip is in low-power state */
+	adv7520_write_reg(hclient, 0x41, 0x50);
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+static void adv7520_start_hdcp(void)
+{
+	mutex_lock(&hdcp_state_mutex);
+	if (hdcp_activating) {
+		DEV_WARN("adv7520_timer: HDCP already"
+			" activating, skipping\n");
+		mutex_unlock(&hdcp_state_mutex);
+		return;
+	}
+	hdcp_activating = TRUE;
+	mutex_unlock(&hdcp_state_mutex);
+
+	del_timer(&hpd_duty_timer);
+
+	adv7520_comm_power(1, 1);
+
+	if (!enable_5v_on) {
+		dd->pd->enable_5v(1);
+		enable_5v_on = TRUE;
+		adv7520_chip_on();
+	}
+
+	/* request for HDCP */
+	reg[0xaf] = adv7520_read_reg(hclient, 0xaf);
+	reg[0xaf] |= 0x90;
+	adv7520_write_reg(hclient, 0xaf, reg[0xaf]);
+	reg[0xaf] = adv7520_read_reg(hclient, 0xaf);
+
+	reg[0xba] = adv7520_read_reg(hclient, 0xba);
+	reg[0xba] |= 0x10;
+	adv7520_write_reg(hclient, 0xba, reg[0xba]);
+	reg[0xba] = adv7520_read_reg(hclient, 0xba);
+	adv7520_comm_power(0, 1);
+
+	DEV_INFO("HDCP: reg[0xaf]=0x%02x, reg[0xba]=0x%02x, waiting for BKSV\n",
+				reg[0xaf], reg[0xba]);
+
+	/* will check for HDCP Error or BKSV ready */
+	mod_timer(&hpd_duty_timer, jiffies + HZ/2);
+}
+#endif
+
+static void adv7520_hpd_timer_w(struct work_struct *work)
+{
+	if (!external_common_state->hpd_feature_on) {
+		DEV_INFO("adv7520_timer: skipping, feature off\n");
+		return;
+	}
+
+	if ((monitor_sense & 0x4) && !external_common_state->hpd_state) {
+		int timeout;
+		DEV_DBG("adv7520_timer: Cable Detected\n");
+		adv7520_comm_power(1, 1);
+		adv7520_chip_on();
+
+		if (hpd_cable_chg_detected) {
+			hpd_cable_chg_detected = FALSE;
+			/* Ensure 5V to read EDID */
+			if (!enable_5v_on) {
+				dd->pd->enable_5v(1);
+				enable_5v_on = TRUE;
+			}
+			msleep(500);
+			timeout = (adv7520_read_reg(hclient, 0x96) & (1 << 2));
+			if (timeout) {
+				DEV_DBG("adv7520_timer: EDID-Ready..\n");
+				adv7520_read_edid();
+			} else
+				DEV_DBG("adv7520_timer: EDID TIMEOUT (C9=%02x)"
+					"\n", adv7520_read_reg(hclient, 0xC9));
+		}
+#ifdef TESTING_FORCE_480p
+		external_common_state->disp_mode_list.num_of_elements = 1;
+		external_common_state->disp_mode_list.disp_mode_list[0] =
+			HDMI_VFRMT_720x480p60_16_9;
+#endif
+		adv7520_comm_power(0, 1);
+#ifndef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+		/* HDMI_5V_EN not needed anymore */
+		if (enable_5v_on) {
+			DEV_DBG("adv7520_timer: EDID done, no HDCP, 5V not "
+				"needed anymore\n");
+			dd->pd->enable_5v(0);
+			enable_5v_on = FALSE;
+		}
+#endif
+		change_hdmi_state(1);
+	} else if (external_common_state->hpd_state) {
+		adv7520_comm_power(1, 1);
+		adv7520_chip_off();
+		adv7520_comm_power(0, 1);
+		DEV_DBG("adv7520_timer: Cable Removed\n");
+		change_hdmi_state(0);
+	}
+}
+
+static void adv7520_hpd_timer_f(unsigned long data)
+{
+	schedule_work(&hpd_timer_work);
+}
+
+static void adv7520_isr_w(struct work_struct *work)
+{
+	static int state_count;
+	static u8 last_reg0x96;
+	u8 reg0xc8;
+	u8 reg0x96;
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+	static u8 last_reg0x97;
+	u8 reg0x97 = 0;
+#endif
+	if (!external_common_state->hpd_feature_on) {
+		DEV_DBG("adv7520_irq: skipping, hpd off\n");
+		return;
+	}
+
+	adv7520_comm_power(1, 1);
+	reg0x96 = adv7520_read_reg(hclient, 0x96);
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+	if (has_hdcp_hw_support) {
+		reg0x97 = adv7520_read_reg(hclient, 0x97);
+		/* Clearing the Interrupts */
+		adv7520_write_reg(hclient, 0x97, reg0x97);
+	}
+#endif
+	/* Clearing the Interrupts */
+	adv7520_write_reg(hclient, 0x96, reg0x96);
+
+	if ((reg0x96 == 0xC0) || (reg0x96 & 0x40)) {
+#ifdef DEBUG
+		unsigned int hpd_state = adv7520_read_reg(hclient, 0x42);
+#endif
+		monitor_sense = adv7520_read_reg(hclient, 0xC6);
+		DEV_DBG("adv7520_irq: reg[0x42]=%02x && reg[0xC6]=%02x\n",
+			hpd_state, monitor_sense);
+
+		if (!enable_5v_on) {
+			dd->pd->enable_5v(1);
+			enable_5v_on = TRUE;
+		}
+		if (!hpd_power_on) {
+			dd->pd->core_power(1, 1);
+			hpd_power_on = TRUE;
+		}
+
+		/* Timer for catching interrupt debouning */
+		DEV_DBG("adv7520_irq: Timer in .5sec\n");
+		hpd_cable_chg_detected = TRUE;
+		mod_timer(&hpd_timer, jiffies + HZ/2);
+	}
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+	if (has_hdcp_hw_support) {
+		if (hdcp_activating) {
+			/* HDCP controller error Interrupt */
+			if (reg0x97 & 0x80) {
+				DEV_ERR("adv7520_irq: HDCP_ERROR\n");
+				state_count = 0;
+				adv7520_close_hdcp_link();
+			/* BKSV Ready interrupts */
+			} else if (reg0x97 & 0x40) {
+				DEV_INFO("adv7520_irq: BKSV keys ready, Begin"
+					" HDCP encryption\n");
+				state_count = 0;
+				schedule_work(&hdcp_handle_work);
+			} else if (++state_count > 2 && (monitor_sense & 0x4)) {
+				DEV_INFO("adv7520_irq: Still waiting for BKSV,"
+				"restart HDCP\n");
+				hdcp_activating = FALSE;
+				state_count = 0;
+				adv7520_chip_off();
+				adv7520_start_hdcp();
+			}
+			reg0xc8 = adv7520_read_reg(hclient, 0xc8);
+			DEV_INFO("adv7520_irq: DDC controller reg[0xC8]=0x%02x,"
+				"state_count=%d, monitor_sense=%x\n",
+				reg0xc8, state_count, monitor_sense);
+		} else if (!external_common_state->hdcp_active
+			&& (monitor_sense & 0x4)) {
+			DEV_INFO("adv7520_irq: start HDCP with"
+				" monitor sense\n");
+			state_count = 0;
+			adv7520_start_hdcp();
+		} else
+			state_count = 0;
+		if (last_reg0x97 != reg0x97 || last_reg0x96 != reg0x96)
+			DEV_DBG("adv7520_irq: reg[0x96]=%02x "
+				"reg[0x97]=%02x: HDCP: %d\n", reg0x96, reg0x97,
+				external_common_state->hdcp_active);
+		last_reg0x97 = reg0x97;
+	} else {
+		if (last_reg0x96 != reg0x96)
+			DEV_DBG("adv7520_irq: reg[0x96]=%02x\n", reg0x96);
+	}
+#else
+	if (last_reg0x96 != reg0x96)
+		DEV_DBG("adv7520_irq: reg[0x96]=%02x\n", reg0x96);
+#endif
+	last_reg0x96 = reg0x96;
+	adv7520_comm_power(0, 1);
+}
+
+static void adv7520_hpd_duty_work(struct work_struct *work)
+{
+	if (!external_common_state->hpd_feature_on) {
+		DEV_WARN("%s: hpd feature is off, skipping\n", __func__);
+		return;
+	}
+
+	dd->pd->core_power(1, 0);
+	msleep(10);
+	adv7520_isr_w(NULL);
+	dd->pd->core_power(0, 0);
+}
+
+static void adv7520_hpd_duty_timer_f(unsigned long data)
+{
+	if (!external_common_state->hpd_feature_on) {
+		DEV_WARN("%s: hpd feature is off, skipping\n", __func__);
+		return;
+	}
+
+	mod_timer(&hpd_duty_timer, jiffies + HPD_DUTY_CYCLE*HZ);
+	schedule_work(&hpd_duty_work);
+}
+
+static const struct i2c_device_id adv7520_id[] = {
+	{ ADV7520_DRV_NAME , 0},
+	{}
+};
+
+static struct msm_fb_panel_data hdmi_panel_data = {
+	.on  = adv7520_power_on,
+	.off = adv7520_power_off,
+};
+
+static struct platform_device hdmi_device = {
+	.name = ADV7520_DRV_NAME ,
+	.id   = 2,
+	.dev  = {
+		.platform_data = &hdmi_panel_data,
+		}
+};
+
+static void adv7520_ensure_init(void)
+{
+	static boolean init_done;
+	if (!init_done) {
+		int rc = dd->pd->init_irq();
+		if (rc) {
+			DEV_ERR("adv7520_init: init_irq: %d\n", rc);
+			return;
+		}
+
+		init_done = TRUE;
+	}
+	DEV_INFO("adv7520_init: chip init\n");
+	adv7520_comm_power(1, 1);
+	adv7520_chip_init();
+	adv7520_comm_power(0, 1);
+}
+
+static int adv7520_hpd_feature(int on)
+{
+	int rc = 0;
+
+	if (!on) {
+		if (enable_5v_on) {
+			dd->pd->enable_5v(0);
+			enable_5v_on = FALSE;
+		}
+		if (hpd_power_on) {
+			dd->pd->core_power(0, 1);
+			hpd_power_on = FALSE;
+		}
+
+		DEV_DBG("adv7520_hpd: %d: stop duty timer\n", on);
+		del_timer(&hpd_timer);
+		del_timer(&hpd_duty_timer);
+		external_common_state->hpd_state = 0;
+	}
+
+	if (on) {
+		dd->pd->core_power(1, 0);
+		adv7520_ensure_init();
+
+		adv7520_comm_power(1, 1);
+		monitor_sense = adv7520_read_reg(hclient, 0xC6);
+		DEV_DBG("adv7520_irq: reg[0xC6]=%02x\n", monitor_sense);
+		adv7520_comm_power(0, 1);
+		dd->pd->core_power(0, 0);
+
+		if (monitor_sense & 0x4) {
+			if (!enable_5v_on) {
+				dd->pd->enable_5v(1);
+				enable_5v_on = TRUE;
+			}
+			if (!hpd_power_on) {
+				dd->pd->core_power(1, 1);
+				hpd_power_on = TRUE;
+			}
+
+			hpd_cable_chg_detected = TRUE;
+			mod_timer(&hpd_timer, jiffies + HZ/2);
+		}
+
+		DEV_DBG("adv7520_hpd: %d start duty timer\n", on);
+		mod_timer(&hpd_duty_timer, jiffies + HZ/100);
+	}
+
+	DEV_INFO("adv7520_hpd: %d\n", on);
+	return rc;
+}
+
+static int __devinit
+	adv7520_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	int rc;
+	struct platform_device *fb_dev;
+
+	dd = kzalloc(sizeof *dd, GFP_KERNEL);
+	if (!dd) {
+		rc = -ENOMEM;
+		goto probe_exit;
+	}
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+		return -ENODEV;
+
+	external_common_state->dev = &client->dev;
+
+	/* Init real i2c_client */
+	hclient = client;
+
+	i2c_set_clientdata(client, dd);
+	dd->pd = client->dev.platform_data;
+	if (!dd->pd) {
+		rc = -ENODEV;
+		goto probe_free;
+	}
+
+	INIT_WORK(&dd->isr_work, adv7520_isr_w);
+	INIT_WORK(&hpd_timer_work, adv7520_hpd_timer_w);
+#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
+	if (dd->pd->check_hdcp_hw_support)
+		has_hdcp_hw_support = dd->pd->check_hdcp_hw_support();
+
+	if (has_hdcp_hw_support)
+		INIT_WORK(&hdcp_handle_work, adv7520_hdcp_enable);
+	else
+		DEV_INFO("%s: no hdcp hw support.\n", __func__);
+#endif
+
+	init_timer(&hpd_timer);
+	hpd_timer.function = adv7520_hpd_timer_f;
+	hpd_timer.data = (unsigned long)NULL;
+	hpd_timer.expires = 0xffffffff;
+	add_timer(&hpd_timer);
+
+	external_common_state->hpd_feature = adv7520_hpd_feature;
+	DEV_INFO("adv7520_probe: HPD detection on request\n");
+	init_timer(&hpd_duty_timer);
+	hpd_duty_timer.function = adv7520_hpd_duty_timer_f;
+	hpd_duty_timer.data = (unsigned long)NULL;
+	hpd_duty_timer.expires = 0xffffffff;
+	add_timer(&hpd_duty_timer);
+	INIT_WORK(&hpd_duty_work, adv7520_hpd_duty_work);
+	DEV_INFO("adv7520_probe: HPD detection ON (duty)\n");
+
+	fb_dev = msm_fb_add_device(&hdmi_device);
+
+	if (fb_dev) {
+		rc = external_common_state_create(fb_dev);
+		if (rc)
+			goto probe_free;
+	} else
+		DEV_ERR("adv7520_probe: failed to add fb device\n");
+
+	if (hdmi_prim_display)
+		external_common_state->sdev.name = "hdmi_as_primary";
+	else
+		external_common_state->sdev.name = "hdmi";
+
+	if (switch_dev_register(&external_common_state->sdev) < 0)
+		DEV_ERR("Hdmi switch registration failed\n");
+
+	return 0;
+
+probe_free:
+	kfree(dd);
+	dd = NULL;
+probe_exit:
+	return rc;
+
+}
+
+static int __devexit adv7520_remove(struct i2c_client *client)
+{
+	if (!client->adapter) {
+		DEV_ERR("%s: No HDMI Device\n", __func__);
+		return -ENODEV;
+	}
+	switch_dev_unregister(&external_common_state->sdev);
+	wake_lock_destroy(&wlock);
+	kfree(dd);
+	dd = NULL;
+	return 0;
+}
+
+#ifdef CONFIG_SUSPEND
+static int adv7520_i2c_suspend(struct device *dev)
+{
+	DEV_INFO("%s\n", __func__);
+
+	++suspend_count;
+
+	if (external_common_state->hpd_feature_on) {
+		DEV_DBG("%s: stop duty timer\n", __func__);
+		del_timer(&hpd_duty_timer);
+		del_timer(&hpd_timer);
+	}
+
+	/* Turn off LDO8 and go into low-power state */
+	if (chip_power_on) {
+		DEV_DBG("%s: turn off power\n", __func__);
+		adv7520_comm_power(1, 1);
+		adv7520_write_reg(hclient, 0x41, 0x50);
+		adv7520_comm_power(0, 1);
+		dd->pd->core_power(0, 1);
+	}
+
+	return 0;
+}
+
+static int adv7520_i2c_resume(struct device *dev)
+{
+	DEV_INFO("%s\n", __func__);
+
+	/* Turn on LDO8 and go into normal-power state */
+	if (chip_power_on) {
+		DEV_DBG("%s: turn on power\n", __func__);
+		dd->pd->core_power(1, 1);
+		adv7520_comm_power(1, 1);
+		adv7520_write_reg(hclient, 0x41, 0x10);
+		adv7520_comm_power(0, 1);
+	}
+
+	if (external_common_state->hpd_feature_on) {
+		DEV_DBG("%s: start duty timer\n", __func__);
+		mod_timer(&hpd_duty_timer, jiffies + HPD_DUTY_CYCLE*HZ);
+	}
+
+	return 0;
+}
+#else
+#define adv7520_i2c_suspend	NULL
+#define adv7520_i2c_resume	NULL
+#endif
+
+static const struct dev_pm_ops adv7520_device_pm_ops = {
+	.suspend = adv7520_i2c_suspend,
+	.resume = adv7520_i2c_resume,
+};
+
+static struct i2c_driver hdmi_i2c_driver = {
+	.driver		= {
+		.name   = ADV7520_DRV_NAME,
+		.owner  = THIS_MODULE,
+		.pm     = &adv7520_device_pm_ops,
+	},
+	.probe		= adv7520_probe,
+	.id_table	= adv7520_id,
+	.remove		= __devexit_p(adv7520_remove),
+};
+
+static int __init adv7520_init(void)
+{
+	int rc;
+
+	pr_info("%s\n", __func__);
+	external_common_state = &hdmi_common;
+	external_common_state->video_resolution = HDMI_VFRMT_1280x720p60_16_9;
+
+	tv_enc_clk = clk_get(NULL, "tv_enc_clk");
+	if (IS_ERR(tv_enc_clk)) {
+		printk(KERN_ERR "error: can't get tv_enc_clk!\n");
+		return IS_ERR(tv_enc_clk);
+	}
+
+	HDMI_SETUP_LUT(640x480p60_4_3);		/* 25.20MHz */
+	HDMI_SETUP_LUT(720x480p60_16_9);	/* 27.03MHz */
+	HDMI_SETUP_LUT(1280x720p60_16_9);	/* 74.25MHz */
+
+	HDMI_SETUP_LUT(720x576p50_16_9);	/* 27.00MHz */
+	HDMI_SETUP_LUT(1280x720p50_16_9);	/* 74.25MHz */
+
+	hdmi_common_init_panel_info(&hdmi_panel_data.panel_info);
+
+	rc = i2c_add_driver(&hdmi_i2c_driver);
+	if (rc) {
+		pr_err("hdmi_init FAILED: i2c_add_driver rc=%d\n", rc);
+		goto init_exit;
+	}
+
+	if (machine_is_msm7x30_surf() || machine_is_msm8x55_surf()) {
+		short *hdtv_mux = (short *)ioremap(0x8e000170 , 0x100);
+		*hdtv_mux++ = 0x020b;
+		*hdtv_mux = 0x8000;
+		iounmap(hdtv_mux);
+	}
+	wake_lock_init(&wlock, WAKE_LOCK_IDLE, "hdmi_active");
+
+	return 0;
+
+init_exit:
+	if (tv_enc_clk)
+		clk_put(tv_enc_clk);
+	return rc;
+}
+
+static void __exit adv7520_exit(void)
+{
+	i2c_del_driver(&hdmi_i2c_driver);
+}
+
+module_init(adv7520_init);
+module_exit(adv7520_exit);
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
+MODULE_DESCRIPTION("ADV7520 HDMI driver");
diff --git a/drivers/video/msm/ebi2_epson_s1d_qvga.c b/drivers/video/msm/ebi2_epson_s1d_qvga.c
new file mode 100644
index 0000000..8821eab
--- /dev/null
+++ b/drivers/video/msm/ebi2_epson_s1d_qvga.c
@@ -0,0 +1,374 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+
+#include <linux/memory.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include "linux/proc_fs.h"
+
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#define CMD_NOP_C							0x00
+#define CMD_SOFT_RESET_C					0x99
+#define CMD_DISPLAY_ON_C					0xAF
+#define CMD_DISPLAY_OFF_C					0xAE
+#define CMD_SET_DISPLAY_C					0xCA
+#define CMD_SET_DISPLAY_TIMING_C			0xA1
+#define CMD_SET_DATA_C						0xBC
+#define CMD_SET_START_ADDRESS_C				0x15
+#define CMD_SET_END_ADDRESS_C				0x75
+#define CMD_RAM_WRITE_C						0x5C
+#define CMD_RAM_READ_C						0x5D
+#define CMD_SET_AREA_SCROLLING_C			0xAA
+#define CMD_SET_DISPLAY_START_LINE_C		0xAB
+#define CMD_PARTIAL_DISPLAY_IN_C			0xA8
+#define CMD_PARTIAL_DISPLAY_OUT_C			0xA9
+#define CMD_SET_DISPLAY_DATA_INTERFACE_C	0x31
+#define CMD_SET_DISPLAY_COLOR_MODE_C		0x8B
+#define CMD_SELECT_MTP_ROM_MODE_C			0x65
+#define CMD_MTP_ROM_MODE_IN_C				0x67
+#define CMD_MTP_ROM_MODE_OUT_C				0x68
+#define CMD_MTP_ROM_OPERATION_IN_C			0x69
+#define CMD_MTP_ROM_OPERATION_OUT_C			0x70
+#define CMD_GATE_LINE_SCAN_MODE_C			0x6F
+#define CMD_SET_AC_OPERATION_DRIVE_C		0x8C
+#define CMD_SET_ELECTRONIC_CONTROL_C		0x20
+#define CMD_SET_POSITIVE_CORRECTION_CHARS_C	0x22
+#define CMD_SET_NEGATIVE_CORRECTION_CHARS_C	0x25
+#define CMD_SET_POWER_CONTROL_C				0x21
+#define CMD_SET_PARTIAL_POWER_CONTROL_C		0x23
+#define CMD_SET_8_COLOR_CONTROL_C			0x24
+#define CMD_SLEEP_IN_C						0x95
+#define CMD_SLEEP_OUT_C						0x94
+#define CMD_VDD_OFF_C						0x97
+#define CMD_VDD_ON_C						0x96
+#define CMD_STOP_OSCILLATION_C				0x93
+#define CMD_START_OSCILLATION_C				0x92
+#define CMD_TEST_SOURCE_C					0xFD
+#define CMD_TEST_FUSE_C						0xFE
+#define CMD_TEST_C							0xFF
+#define CMD_STATUS_READ_C					0xE8
+#define CMD_REVISION_READ_C					0xE9
+
+#define PANEL_WIDTH			240
+#define PANEL_HEIGHT		320
+#define ACTIVE_WIN_WIDTH	PANEL_WIDTH
+#define ACTIVE_WIN_HEIGHT	PANEL_HEIGHT
+
+#define ACTIVE_WIN_H_START	0
+#define ACTIVE_WIN_V_START	0
+
+#define DISP_CMD_OUT(cmd) outpw(DISP_CMD_PORT, (cmd << 1));
+#define DISP_DATA_OUT(data) outpw(DISP_DATA_PORT, (data << 1));
+#define DISP_DATA_IN() inpw(DISP_DATA_PORT);
+
+static void *DISP_CMD_PORT;
+static void *DISP_DATA_PORT;
+static boolean disp_initialized;
+static boolean display_on;
+static struct msm_panel_common_pdata *ebi2_epson_pdata;
+
+static void epson_s1d_disp_init(struct platform_device *pdev);
+static int epson_s1d_disp_off(struct platform_device *pdev);
+static int epson_s1d_disp_on(struct platform_device *pdev);
+static void epson_s1d_disp_set_rect(int x, int y, int xres, int yres);
+
+static void epson_s1d_disp_set_rect(int x, int y, int xres, int yres)
+{
+	int right, bottom;
+
+	if (!disp_initialized)
+		return;
+
+	right = x + xres - 1;
+	bottom = y + yres - 1;
+
+	x += ACTIVE_WIN_H_START;
+	y += ACTIVE_WIN_V_START;
+	right += ACTIVE_WIN_H_START;
+	bottom += ACTIVE_WIN_V_START;
+
+	if ((PANEL_WIDTH  > x) &&
+		(PANEL_HEIGHT > y) &&
+		(PANEL_WIDTH > right) &&
+		(PANEL_HEIGHT > bottom)) {
+		DISP_CMD_OUT(CMD_SET_START_ADDRESS_C);
+		DISP_DATA_OUT((uint8)x);
+		DISP_DATA_OUT((uint8)(y>>8));
+		DISP_DATA_OUT((uint8)y);
+
+		DISP_CMD_OUT(CMD_SET_END_ADDRESS_C);
+		DISP_DATA_OUT((uint8)right);
+		DISP_DATA_OUT((uint8)(bottom>>8));
+		DISP_DATA_OUT((uint8)bottom);
+		DISP_CMD_OUT(CMD_RAM_WRITE_C);
+	}
+}
+
+static void epson_s1d_disp_init(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	if (disp_initialized)
+		return;
+
+	mfd = platform_get_drvdata(pdev);
+
+	DISP_CMD_PORT = mfd->cmd_port;
+	DISP_DATA_PORT = mfd->data_port;
+
+	disp_initialized = TRUE;
+}
+
+static int epson_s1d_disp_off(struct platform_device *pdev)
+{
+	if (!disp_initialized)
+		epson_s1d_disp_init(pdev);
+
+	if (display_on) {
+		DISP_CMD_OUT(CMD_SOFT_RESET_C);
+		DISP_CMD_OUT(CMD_VDD_OFF_C);
+		display_on = FALSE;
+	}
+
+	return 0;
+}
+
+static int epson_s1d_disp_on(struct platform_device *pdev)
+{
+	int i;
+	if (!disp_initialized)
+		epson_s1d_disp_init(pdev);
+
+	if (!display_on) {
+		/* Enable Vdd regulator */
+		DISP_CMD_OUT(CMD_VDD_ON_C);
+		msleep(20);
+
+		/* Soft Reset before configuring display */
+		DISP_CMD_OUT(CMD_SOFT_RESET_C);
+		msleep(20);
+
+		/* Set display attributes */
+
+		/* GATESCAN */
+		DISP_CMD_OUT(CMD_GATE_LINE_SCAN_MODE_C);
+		DISP_DATA_OUT(0x0);
+
+		/* DISSET */
+		DISP_CMD_OUT(CMD_SET_DISPLAY_C);
+		DISP_DATA_OUT(0x31);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT((uint8)((PANEL_HEIGHT - 1)>>8));
+		DISP_DATA_OUT((uint8)(PANEL_HEIGHT - 1));
+		DISP_DATA_OUT(0x03);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x08);
+
+		/* VOLSET */
+		DISP_CMD_OUT(
+				   CMD_SET_ELECTRONIC_CONTROL_C);
+		DISP_DATA_OUT(0x10);
+		DISP_DATA_OUT(0x80);
+		DISP_DATA_OUT(0x11);
+		DISP_DATA_OUT(0x1B);
+		DISP_DATA_OUT(0x02);
+		DISP_DATA_OUT(0x0D);
+		DISP_DATA_OUT(0x00);
+
+		/* PWRCTL */
+		DISP_CMD_OUT(CMD_SET_POWER_CONTROL_C);
+		DISP_DATA_OUT(0x01);
+		DISP_DATA_OUT(0x24);
+		DISP_DATA_OUT(0x0F);
+		DISP_DATA_OUT(0xFE);
+		DISP_DATA_OUT(0x33);
+		DISP_DATA_OUT(0x31);
+		DISP_DATA_OUT(0xFF);
+		DISP_DATA_OUT(0x03);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x77);
+		DISP_DATA_OUT(0x33);
+		DISP_DATA_OUT(0x11);
+		DISP_DATA_OUT(0x44);
+		DISP_DATA_OUT(0x00);
+
+		/* PPWRCTL */
+		DISP_CMD_OUT(CMD_SET_PARTIAL_POWER_CONTROL_C);
+		DISP_DATA_OUT(0x33);
+		DISP_DATA_OUT(0xFF);
+		DISP_DATA_OUT(0x03);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x44);
+		DISP_DATA_OUT(0x00);
+
+		/* SPLOUT */
+		DISP_CMD_OUT(CMD_SLEEP_OUT_C);
+		msleep(100);
+
+		/* DATSET */
+		DISP_CMD_OUT(CMD_SET_DATA_C);
+		DISP_DATA_OUT(0x00);
+
+		/* DISTMEMSET */
+		DISP_CMD_OUT(CMD_SET_DISPLAY_TIMING_C);
+		DISP_DATA_OUT(0x01);
+		DISP_DATA_OUT(0x2E);
+		DISP_DATA_OUT(0x0A);
+		DISP_DATA_OUT(0x2C);
+		DISP_DATA_OUT(0x23);
+		DISP_DATA_OUT(0x2F);
+		DISP_DATA_OUT(0x00);
+
+		/* GAMSETP */
+		DISP_CMD_OUT(CMD_SET_POSITIVE_CORRECTION_CHARS_C);
+		DISP_DATA_OUT(0x37);
+		DISP_DATA_OUT(0xFF);
+		DISP_DATA_OUT(0x7F);
+		DISP_DATA_OUT(0x15);
+		DISP_DATA_OUT(0x37);
+		DISP_DATA_OUT(0x05);
+
+		/* GAMSETN */
+		DISP_CMD_OUT(CMD_SET_NEGATIVE_CORRECTION_CHARS_C);
+		DISP_DATA_OUT(0x37);
+		DISP_DATA_OUT(0xFF);
+		DISP_DATA_OUT(0x7F);
+		DISP_DATA_OUT(0x15);
+		DISP_DATA_OUT(0x37);
+		DISP_DATA_OUT(0x05);
+
+		/* ACDRIVE */
+		DISP_CMD_OUT(CMD_SET_AC_OPERATION_DRIVE_C);
+		DISP_DATA_OUT(0x00);
+
+		/* TEST */
+		DISP_CMD_OUT(CMD_TEST_C);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x01);
+
+		/* COLMOD */
+		DISP_CMD_OUT(CMD_SET_DISPLAY_COLOR_MODE_C);
+		DISP_DATA_OUT(0x00);
+
+		/* STADDSET */
+		DISP_CMD_OUT(CMD_SET_START_ADDRESS_C);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x00);
+
+		/* EDADDSET */
+		DISP_CMD_OUT(CMD_SET_END_ADDRESS_C);
+		DISP_DATA_OUT(0xEF);
+		DISP_DATA_OUT(0x01);
+		DISP_DATA_OUT(0x3F);
+
+		/* Set Display Start Line */
+		DISP_CMD_OUT(CMD_SET_DISPLAY_START_LINE_C);
+		DISP_DATA_OUT(0x00);
+
+		/* Set Display Data Interface */
+		DISP_CMD_OUT(CMD_SET_DISPLAY_DATA_INTERFACE_C);
+		DISP_DATA_OUT(0x00);
+		DISP_DATA_OUT(0x04);
+
+		epson_s1d_disp_set_rect(0,
+						 0,
+						 ACTIVE_WIN_WIDTH,
+						 ACTIVE_WIN_HEIGHT);
+
+		for (i = 0; i < (ACTIVE_WIN_WIDTH * ACTIVE_WIN_HEIGHT); i++)
+			outpdw(DISP_DATA_PORT, 0);
+
+		/* DISON */
+		DISP_CMD_OUT(CMD_DISPLAY_ON_C);
+		msleep(60);
+
+		display_on = TRUE;
+	}
+
+	return 0;
+}
+
+static int epson_s1d_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		ebi2_epson_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	msm_fb_add_device(pdev);
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = epson_s1d_probe,
+	.driver = {
+		.name   = "ebi2_epson_s1d_qvga",
+	},
+};
+
+static struct msm_fb_panel_data epson_s1d_panel_data = {
+	.on = epson_s1d_disp_on,
+	.off = epson_s1d_disp_off,
+	.set_rect = epson_s1d_disp_set_rect,
+};
+
+static struct platform_device this_device = {
+	.name   = "ebi2_epson_s1d_qvga",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &epson_s1d_panel_data,
+	}
+};
+
+static int __init epson_s1d_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	ret = platform_driver_register(&this_driver);
+	if (!ret) {
+		pinfo = &epson_s1d_panel_data.panel_info;
+		pinfo->xres = PANEL_WIDTH;
+		pinfo->yres = PANEL_HEIGHT;
+		MSM_FB_SINGLE_MODE_PANEL(pinfo);
+		pinfo->type = EBI2_PANEL;
+		pinfo->pdest = DISPLAY_1;
+		pinfo->wait_cycle = 0x048423E8;
+		pinfo->bpp = 18;
+		pinfo->fb_num = 2;
+		pinfo->lcd.vsync_enable = FALSE;
+
+		ret = platform_device_register(&this_device);
+		if (ret)
+			platform_driver_unregister(&this_driver);
+	}
+
+	return ret;
+}
+
+module_init(epson_s1d_init);
diff --git a/drivers/video/msm/ebi2_host.c b/drivers/video/msm/ebi2_host.c
new file mode 100644
index 0000000..8ba5506
--- /dev/null
+++ b/drivers/video/msm/ebi2_host.c
@@ -0,0 +1,307 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/hrtimer.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/clk.h>
+#include <mach/hardware.h>
+#include "msm_fb.h"
+
+struct mdp_ccs mdp_ccs_rgb2yuv;
+struct mdp_ccs mdp_ccs_yuv2rgb;
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+static int ebi2_host_resource_initialized;
+static struct msm_panel_common_pdata *ebi2_host_pdata;
+
+static int ebi2_host_probe(struct platform_device *pdev);
+static int ebi2_host_remove(struct platform_device *pdev);
+
+static int ebi2_host_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int ebi2_host_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+
+static const struct dev_pm_ops ebi2_host_dev_pm_ops = {
+	.runtime_suspend = ebi2_host_runtime_suspend,
+	.runtime_resume = ebi2_host_runtime_resume,
+};
+
+
+static struct platform_driver ebi2_host_driver = {
+	.probe = ebi2_host_probe,
+	.remove = ebi2_host_remove,
+	.shutdown = NULL,
+	.driver = {
+		/*
+		 * Simulate mdp hw
+		 */
+		.name = "mdp",
+		.pm = &ebi2_host_dev_pm_ops,
+	},
+};
+
+void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
+		   boolean isr)
+{
+	return;
+}
+int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req)
+{
+	return 0;
+}
+int mdp_start_histogram(struct fb_info *info)
+{
+	return 0;
+}
+int mdp_stop_histogram(struct fb_info *info)
+{
+	return 0;
+}
+void mdp_refresh_screen(unsigned long data)
+{
+	return;
+}
+
+static int ebi2_host_off(struct platform_device *pdev)
+{
+	int ret;
+	ret = panel_next_off(pdev);
+	return ret;
+}
+
+static int ebi2_host_on(struct platform_device *pdev)
+{
+	int ret;
+	ret = panel_next_on(pdev);
+	return ret;
+}
+
+
+static int ebi2_host_probe(struct platform_device *pdev)
+{
+	struct platform_device *msm_fb_dev = NULL;
+	struct msm_fb_data_type *mfd;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc;
+
+	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
+
+		ebi2_host_pdata = pdev->dev.platform_data;
+
+		ebi2_host_resource_initialized = 1;
+		return 0;
+	}
+
+	ebi2_host_resource_initialized = 1;
+	if (!ebi2_host_resource_initialized)
+		return -EPERM;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	msm_fb_dev = platform_device_alloc("msm_fb", pdev->id);
+	if (!msm_fb_dev)
+		return -ENOMEM;
+
+	/* link to the latest pdev */
+	mfd->pdev = msm_fb_dev;
+
+	if (ebi2_host_pdata) {
+		mfd->mdp_rev = ebi2_host_pdata->mdp_rev;
+		mfd->mem_hid = ebi2_host_pdata->mem_hid;
+	}
+
+	/* add panel data */
+	if (platform_device_add_data
+	    (msm_fb_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		pr_err("ebi2_host_probe: platform_device_add_data failed!\n");
+		rc = -ENOMEM;
+		goto ebi2_host_probe_err;
+	}
+	/* data chain */
+	pdata = msm_fb_dev->dev.platform_data;
+	pdata->on = ebi2_host_on;
+	pdata->off = ebi2_host_off;
+	pdata->next = pdev;
+
+	/* set driver data */
+	platform_set_drvdata(msm_fb_dev, mfd);
+
+	rc = platform_device_add(msm_fb_dev);
+	if (rc)
+		goto ebi2_host_probe_err;
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	pdev_list[pdev_list_cnt++] = pdev;
+	return 0;
+
+ebi2_host_probe_err:
+	platform_device_put(msm_fb_dev);
+	return rc;
+}
+
+void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
+			  boolean sync)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct fb_info *fbi = mfd->fbi;
+	struct msm_panel_info *panel_info = &mfd->panel_info;
+	MDPIBUF *iBuf;
+	int bpp = info->var.bits_per_pixel / 8;
+	int yres, remainder;
+
+	if (panel_info->mode2_yres != 0) {
+		yres = panel_info->mode2_yres;
+		remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+	} else {
+		yres = panel_info->yres;
+		remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+	}
+
+	if (!remainder)
+		remainder = PAGE_SIZE;
+
+	down(&mfd->sem);
+
+	iBuf = &mfd->ibuf;
+	/* use virtual address */
+	iBuf->buf = (uint8 *) fbi->screen_base;
+
+	if (fbi->var.yoffset < yres) {
+		iBuf->buf += fbi->var.xoffset * bpp;
+	} else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+		iBuf->buf += fbi->var.xoffset * bpp + yres *
+		fbi->fix.line_length + PAGE_SIZE - remainder;
+	} else {
+		iBuf->buf += fbi->var.xoffset * bpp + 2 * yres *
+		fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+	}
+
+	iBuf->ibuf_width = info->var.xres_virtual;
+	iBuf->bpp = bpp;
+
+	iBuf->vsync_enable = sync;
+
+	if (dirty) {
+		/*
+		 * ToDo: dirty region check inside var.xoffset+xres
+		 * <-> var.yoffset+yres
+		 */
+		iBuf->dma_x = dirty->xoffset % info->var.xres;
+		iBuf->dma_y = dirty->yoffset % info->var.yres;
+		iBuf->dma_w = dirty->width;
+		iBuf->dma_h = dirty->height;
+	} else {
+		iBuf->dma_x = 0;
+		iBuf->dma_y = 0;
+		iBuf->dma_w = info->var.xres;
+		iBuf->dma_h = info->var.yres;
+	}
+	mfd->ibuf_flushed = FALSE;
+	up(&mfd->sem);
+}
+
+void mdp_dma_pan_update(struct fb_info *info)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	MDPIBUF *iBuf;
+	int i, j;
+	uint32 data;
+	uint8 *src;
+	struct msm_fb_panel_data *pdata =
+	    (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+	struct fb_info *fbi = mfd->fbi;
+
+	iBuf = &mfd->ibuf;
+
+	invalidate_caches((unsigned long)fbi->screen_base,
+		(unsigned long)info->fix.smem_len,
+		(unsigned long)info->fix.smem_start);
+
+	pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
+			iBuf->dma_h);
+	for (i = 0; i < iBuf->dma_h; i++) {
+		src = iBuf->buf + (fbi->fix.line_length * (iBuf->dma_y + i))
+			+ (iBuf->dma_x * iBuf->bpp);
+		for (j = 0; j < iBuf->dma_w; j++) {
+			data = (uint32)(*src++ >> 2) << 12;
+			data |= (uint32)(*src++ >> 2) << 6;
+			data |= (uint32)(*src++ >> 2);
+			data = ((data&0x1FF)<<16) | ((data&0x3FE00)>>9);
+			outpdw(mfd->data_port, data);
+		}
+	}
+}
+
+static int ebi2_host_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static int ebi2_host_register_driver(void)
+{
+	return platform_driver_register(&ebi2_host_driver);
+}
+
+static int __init ebi2_host_driver_init(void)
+{
+	int ret;
+
+	ret = ebi2_host_register_driver();
+	if (ret) {
+		pr_err("ebi2_host_register_driver() failed!\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+module_init(ebi2_host_driver_init);
diff --git a/drivers/video/msm/ebi2_l2f.c b/drivers/video/msm/ebi2_l2f.c
new file mode 100644
index 0000000..767b802
--- /dev/null
+++ b/drivers/video/msm/ebi2_l2f.c
@@ -0,0 +1,566 @@
+/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+
+#include <linux/memory.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include "linux/proc_fs.h"
+
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+/* The following are for MSM5100 on Gator
+*/
+#ifdef FEATURE_PM1000
+#include "pm1000.h"
+#endif /* FEATURE_PM1000 */
+/* The following are for MSM6050 on Bambi
+*/
+#ifdef FEATURE_PMIC_LCDKBD_LED_DRIVER
+#include "pm.h"
+#endif /* FEATURE_PMIC_LCDKBD_LED_DRIVER */
+
+#ifdef DISP_DEVICE_18BPP
+#undef DISP_DEVICE_18BPP
+#define DISP_DEVICE_16BPP
+#endif
+
+#define QCIF_WIDTH        176
+#define QCIF_HEIGHT       220
+
+static void *DISP_CMD_PORT;
+static void *DISP_DATA_PORT;
+
+#define DISP_CMD_DISON    0xaf
+#define DISP_CMD_DISOFF   0xae
+#define DISP_CMD_DISNOR   0xa6
+#define DISP_CMD_DISINV   0xa7
+#define DISP_CMD_DISCTL   0xca
+#define DISP_CMD_GCP64    0xcb
+#define DISP_CMD_GCP16    0xcc
+#define DISP_CMD_GSSET    0xcd
+#define DISP_GS_2       0x02
+#define DISP_GS_16      0x01
+#define DISP_GS_64      0x00
+#define DISP_CMD_SLPIN    0x95
+#define DISP_CMD_SLPOUT   0x94
+#define DISP_CMD_SD_PSET  0x75
+#define DISP_CMD_MD_PSET  0x76
+#define DISP_CMD_SD_CSET  0x15
+#define DISP_CMD_MD_CSET  0x16
+#define DISP_CMD_DATCTL   0xbc
+#define DISP_DATCTL_666 0x08
+#define DISP_DATCTL_565 0x28
+#define DISP_DATCTL_444 0x38
+#define DISP_CMD_RAMWR    0x5c
+#define DISP_CMD_RAMRD    0x5d
+#define DISP_CMD_PTLIN    0xa8
+#define DISP_CMD_PTLOUT   0xa9
+#define DISP_CMD_ASCSET   0xaa
+#define DISP_CMD_SCSTART  0xab
+#define DISP_CMD_VOLCTL   0xc6
+#define DISP_VOLCTL_TONE 0x80
+#define DISP_CMD_NOp      0x25
+#define DISP_CMD_OSSEL    0xd0
+#define DISP_CMD_3500KSET 0xd1
+#define DISP_CMD_3500KEND 0xd2
+#define DISP_CMD_14MSET   0xd3
+#define DISP_CMD_14MEND   0xd4
+
+#define DISP_CMD_OUT(cmd) outpw(DISP_CMD_PORT, cmd);
+
+#define DISP_DATA_OUT(data) outpw(DISP_DATA_PORT, data);
+
+#define DISP_DATA_IN() inpw(DISP_DATA_PORT);
+
+/* Epson device column number starts at 2
+*/
+#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \
+	  DISP_CMD_OUT(DISP_CMD_SD_PSET) \
+	  DISP_DATA_OUT((ulhc_row) & 0xFF) \
+	  DISP_DATA_OUT((ulhc_row) >> 8) \
+	  DISP_DATA_OUT((lrhc_row) & 0xFF) \
+	  DISP_DATA_OUT((lrhc_row) >> 8) \
+	  DISP_CMD_OUT(DISP_CMD_SD_CSET) \
+	  DISP_DATA_OUT(((ulhc_col)+2) & 0xFF) \
+	  DISP_DATA_OUT(((ulhc_col)+2) >> 8) \
+	  DISP_DATA_OUT(((lrhc_col)+2) & 0xFF) \
+	  DISP_DATA_OUT(((lrhc_col)+2) >> 8)
+
+#define DISP_MIN_CONTRAST      0
+#define DISP_MAX_CONTRAST      127
+#define DISP_DEFAULT_CONTRAST  80
+
+#define DISP_MIN_BACKLIGHT     0
+#define DISP_MAX_BACKLIGHT     15
+#define DISP_DEFAULT_BACKLIGHT 2
+
+#define WAIT_SEC(sec) mdelay((sec)/1000)
+
+static word disp_area_start_row;
+static word disp_area_end_row;
+static byte disp_contrast = DISP_DEFAULT_CONTRAST;
+static boolean disp_powered_up;
+static boolean disp_initialized = FALSE;
+/* For some reason the contrast set at init time is not good. Need to do
+ * it again
+ */
+static boolean display_on = FALSE;
+static void epsonQcif_disp_init(struct platform_device *pdev);
+static void epsonQcif_disp_set_contrast(word contrast);
+static void epsonQcif_disp_set_display_area(word start_row, word end_row);
+static int epsonQcif_disp_off(struct platform_device *pdev);
+static int epsonQcif_disp_on(struct platform_device *pdev);
+static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres);
+
+volatile word databack;
+static void epsonQcif_disp_init(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	int i;
+
+	if (disp_initialized)
+		return;
+
+	mfd = platform_get_drvdata(pdev);
+
+	DISP_CMD_PORT = mfd->cmd_port;
+	DISP_DATA_PORT = mfd->data_port;
+
+	/* Sleep in */
+	DISP_CMD_OUT(DISP_CMD_SLPIN);
+
+	/* Display off */
+	DISP_CMD_OUT(DISP_CMD_DISOFF);
+
+	/* Display normal */
+	DISP_CMD_OUT(DISP_CMD_DISNOR);
+
+	/* Set data mode */
+	DISP_CMD_OUT(DISP_CMD_DATCTL);
+	DISP_DATA_OUT(DISP_DATCTL_565);
+
+	/* Set display timing */
+	DISP_CMD_OUT(DISP_CMD_DISCTL);
+	DISP_DATA_OUT(0x1c);	/* p1 */
+	DISP_DATA_OUT(0x02);	/* p1 */
+	DISP_DATA_OUT(0x82);	/* p2 */
+	DISP_DATA_OUT(0x00);	/* p3 */
+	DISP_DATA_OUT(0x00);	/* p4 */
+	DISP_DATA_OUT(0xe0);	/* p5 */
+	DISP_DATA_OUT(0x00);	/* p5 */
+	DISP_DATA_OUT(0xdc);	/* p6 */
+	DISP_DATA_OUT(0x00);	/* p6 */
+	DISP_DATA_OUT(0x02);	/* p7 */
+	DISP_DATA_OUT(0x00);	/* p8 */
+
+	/* Set 64 gray scale level */
+	DISP_CMD_OUT(DISP_CMD_GCP64);
+	DISP_DATA_OUT(0x08);	/* p01 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0x2a);	/* p02 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0x4e);	/* p03 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0x6b);	/* p04 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0x88);	/* p05 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0xa3);	/* p06 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0xba);	/* p07 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0xd1);	/* p08 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0xe5);	/* p09 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0xf3);	/* p10 */
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0x03);	/* p11 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x13);	/* p12 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x22);	/* p13 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x2f);	/* p14 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x3b);	/* p15 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x46);	/* p16 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x51);	/* p17 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x5b);	/* p18 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x64);	/* p19 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x6c);	/* p20 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x74);	/* p21 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x7c);	/* p22 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x83);	/* p23 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x8a);	/* p24 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x91);	/* p25 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x98);	/* p26 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x9f);	/* p27 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xa6);	/* p28 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xac);	/* p29 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xb2);	/* p30 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xb7);	/* p31 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xbc);	/* p32 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xc1);	/* p33 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xc6);	/* p34 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xcb);	/* p35 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xd0);	/* p36 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xd4);	/* p37 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xd8);	/* p38 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xdc);	/* p39 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xe0);	/* p40 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xe4);	/* p41 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xe8);	/* p42 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xec);	/* p43 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xf0);	/* p44 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xf4);	/* p45 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xf8);	/* p46 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xfb);	/* p47 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xfe);	/* p48 */
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0x01);	/* p49 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x03);	/* p50 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x05);	/* p51 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x07);	/* p52 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x09);	/* p53 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x0b);	/* p54 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x0d);	/* p55 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x0f);	/* p56 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x11);	/* p57 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x13);	/* p58 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x15);	/* p59 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x17);	/* p60 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x19);	/* p61 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x1b);	/* p62 */
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x1c);	/* p63 */
+	DISP_DATA_OUT(0x02);
+
+	/* Set 16 gray scale level */
+	DISP_CMD_OUT(DISP_CMD_GCP16);
+	DISP_DATA_OUT(0x1a);	/* p01 */
+	DISP_DATA_OUT(0x32);	/* p02 */
+	DISP_DATA_OUT(0x42);	/* p03 */
+	DISP_DATA_OUT(0x4c);	/* p04 */
+	DISP_DATA_OUT(0x58);	/* p05 */
+	DISP_DATA_OUT(0x5f);	/* p06 */
+	DISP_DATA_OUT(0x66);	/* p07 */
+	DISP_DATA_OUT(0x6b);	/* p08 */
+	DISP_DATA_OUT(0x70);	/* p09 */
+	DISP_DATA_OUT(0x74);	/* p10 */
+	DISP_DATA_OUT(0x78);	/* p11 */
+	DISP_DATA_OUT(0x7b);	/* p12 */
+	DISP_DATA_OUT(0x7e);	/* p13 */
+	DISP_DATA_OUT(0x80);	/* p14 */
+	DISP_DATA_OUT(0x82);	/* p15 */
+
+	/* Set DSP column */
+	DISP_CMD_OUT(DISP_CMD_MD_CSET);
+	DISP_DATA_OUT(0xff);
+	DISP_DATA_OUT(0x03);
+	DISP_DATA_OUT(0xff);
+	DISP_DATA_OUT(0x03);
+
+	/* Set DSP page */
+	DISP_CMD_OUT(DISP_CMD_MD_PSET);
+	DISP_DATA_OUT(0xff);
+	DISP_DATA_OUT(0x01);
+	DISP_DATA_OUT(0xff);
+	DISP_DATA_OUT(0x01);
+
+	/* Set ARM column */
+	DISP_CMD_OUT(DISP_CMD_SD_CSET);
+	DISP_DATA_OUT(0x02);
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT((QCIF_WIDTH + 1) & 0xFF);
+	DISP_DATA_OUT((QCIF_WIDTH + 1) >> 8);
+
+	/* Set ARM page */
+	DISP_CMD_OUT(DISP_CMD_SD_PSET);
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT(0x00);
+	DISP_DATA_OUT((QCIF_HEIGHT - 1) & 0xFF);
+	DISP_DATA_OUT((QCIF_HEIGHT - 1) >> 8);
+
+	/* Set 64 gray scales */
+	DISP_CMD_OUT(DISP_CMD_GSSET);
+	DISP_DATA_OUT(DISP_GS_64);
+
+	DISP_CMD_OUT(DISP_CMD_OSSEL);
+	DISP_DATA_OUT(0);
+
+	/* Sleep out */
+	DISP_CMD_OUT(DISP_CMD_SLPOUT);
+
+	WAIT_SEC(40000);
+
+	/* Initialize power IC */
+	DISP_CMD_OUT(DISP_CMD_VOLCTL);
+	DISP_DATA_OUT(DISP_VOLCTL_TONE);
+
+	WAIT_SEC(40000);
+
+	/* Set electronic volume, d'xx */
+	DISP_CMD_OUT(DISP_CMD_VOLCTL);
+	DISP_DATA_OUT(DISP_DEFAULT_CONTRAST);	/* value from 0 to 127 */
+
+	/* Initialize display data */
+	DISP_SET_RECT(0, (QCIF_HEIGHT - 1), 0, (QCIF_WIDTH - 1));
+	DISP_CMD_OUT(DISP_CMD_RAMWR);
+	for (i = 0; i < QCIF_HEIGHT * QCIF_WIDTH; i++)
+		DISP_DATA_OUT(0xffff);
+
+	DISP_CMD_OUT(DISP_CMD_RAMRD);
+	databack = DISP_DATA_IN();
+	databack = DISP_DATA_IN();
+	databack = DISP_DATA_IN();
+	databack = DISP_DATA_IN();
+
+	WAIT_SEC(80000);
+
+	DISP_CMD_OUT(DISP_CMD_DISON);
+
+	disp_area_start_row = 0;
+	disp_area_end_row = QCIF_HEIGHT - 1;
+	disp_powered_up = TRUE;
+	disp_initialized = TRUE;
+	epsonQcif_disp_set_display_area(0, QCIF_HEIGHT - 1);
+	display_on = TRUE;
+}
+
+static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres)
+{
+	if (!disp_initialized)
+		return;
+
+	DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1);
+	DISP_CMD_OUT(DISP_CMD_RAMWR);
+}
+
+static void epsonQcif_disp_set_display_area(word start_row, word end_row)
+{
+	if (!disp_initialized)
+		return;
+
+	if ((start_row == disp_area_start_row)
+	    && (end_row == disp_area_end_row))
+		return;
+	disp_area_start_row = start_row;
+	disp_area_end_row = end_row;
+
+	/* Range checking
+	 */
+	if (end_row >= QCIF_HEIGHT)
+		end_row = QCIF_HEIGHT - 1;
+	if (start_row > end_row)
+		start_row = end_row;
+
+	/* When display is not the full screen, gray scale is set to
+	 ** 2; otherwise it is set to 64.
+	 */
+	if ((start_row == 0) && (end_row == (QCIF_HEIGHT - 1))) {
+		/* The whole screen */
+		DISP_CMD_OUT(DISP_CMD_PTLOUT);
+		WAIT_SEC(10000);
+		DISP_CMD_OUT(DISP_CMD_DISOFF);
+		WAIT_SEC(100000);
+		DISP_CMD_OUT(DISP_CMD_GSSET);
+		DISP_DATA_OUT(DISP_GS_64);
+		WAIT_SEC(100000);
+		DISP_CMD_OUT(DISP_CMD_DISON);
+	} else {
+		/* partial screen */
+		DISP_CMD_OUT(DISP_CMD_PTLIN);
+		DISP_DATA_OUT(start_row);
+		DISP_DATA_OUT(start_row >> 8);
+		DISP_DATA_OUT(end_row);
+		DISP_DATA_OUT(end_row >> 8);
+		DISP_CMD_OUT(DISP_CMD_GSSET);
+		DISP_DATA_OUT(DISP_GS_2);
+	}
+}
+
+static int epsonQcif_disp_off(struct platform_device *pdev)
+{
+	if (!disp_initialized)
+		epsonQcif_disp_init(pdev);
+
+	if (display_on) {
+		DISP_CMD_OUT(DISP_CMD_DISOFF);
+		DISP_CMD_OUT(DISP_CMD_SLPIN);
+		display_on = FALSE;
+	}
+
+	return 0;
+}
+
+static int epsonQcif_disp_on(struct platform_device *pdev)
+{
+	if (!disp_initialized)
+		epsonQcif_disp_init(pdev);
+
+	if (!display_on) {
+		DISP_CMD_OUT(DISP_CMD_SLPOUT);
+		WAIT_SEC(40000);
+		DISP_CMD_OUT(DISP_CMD_DISON);
+		epsonQcif_disp_set_contrast(disp_contrast);
+		display_on = TRUE;
+	}
+
+	return 0;
+}
+
+static void epsonQcif_disp_set_contrast(word contrast)
+{
+	if (!disp_initialized)
+		return;
+
+	/* Initialize power IC, d'24 */
+	DISP_CMD_OUT(DISP_CMD_VOLCTL);
+	DISP_DATA_OUT(DISP_VOLCTL_TONE);
+
+	WAIT_SEC(40000);
+
+	/* Set electronic volume, d'xx */
+	DISP_CMD_OUT(DISP_CMD_VOLCTL);
+	if (contrast > 127)
+		contrast = 127;
+	DISP_DATA_OUT(contrast);	/* value from 0 to 127 */
+	disp_contrast = (byte) contrast;
+}				/* End disp_set_contrast */
+
+static void epsonQcif_disp_clear_screen_area(
+	word start_row, word end_row, word start_column, word end_column) {
+	int32 i;
+
+	/* Clear the display screen */
+	DISP_SET_RECT(start_row, end_row, start_column, end_column);
+	DISP_CMD_OUT(DISP_CMD_RAMWR);
+	i = (end_row - start_row + 1) * (end_column - start_column + 1);
+	for (; i > 0; i--)
+		DISP_DATA_OUT(0xffff);
+}
+
+static int __init epsonQcif_probe(struct platform_device *pdev)
+{
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = epsonQcif_probe,
+	.driver = {
+		.name   = "ebi2_epson_qcif",
+	},
+};
+
+static struct msm_fb_panel_data epsonQcif_panel_data = {
+	.on = epsonQcif_disp_on,
+	.off = epsonQcif_disp_off,
+	.set_rect = epsonQcif_disp_set_rect,
+};
+
+static struct platform_device this_device = {
+	.name   = "ebi2_epson_qcif",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &epsonQcif_panel_data,
+	}
+};
+
+static int __init epsonQcif_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	ret = platform_driver_register(&this_driver);
+	if (!ret) {
+		pinfo = &epsonQcif_panel_data.panel_info;
+		pinfo->xres = QCIF_WIDTH;
+		pinfo->yres = QCIF_HEIGHT;
+		MSM_FB_SINGLE_MODE_PANEL(pinfo);
+		pinfo->type = EBI2_PANEL;
+		pinfo->pdest = DISPLAY_2;
+		pinfo->wait_cycle = 0x808000;
+		pinfo->bpp = 16;
+		pinfo->fb_num = 2;
+		pinfo->lcd.vsync_enable = FALSE;
+
+		ret = platform_device_register(&this_device);
+		if (ret)
+			platform_driver_unregister(&this_driver);
+	}
+
+	return ret;
+}
+
+module_init(epsonQcif_init);
diff --git a/drivers/video/msm/ebi2_lcd.c b/drivers/video/msm/ebi2_lcd.c
new file mode 100644
index 0000000..966f974
--- /dev/null
+++ b/drivers/video/msm/ebi2_lcd.c
@@ -0,0 +1,308 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/uaccess.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <linux/debugfs.h>
+
+#include "msm_fb.h"
+
+static int ebi2_lcd_probe(struct platform_device *pdev);
+static int ebi2_lcd_remove(struct platform_device *pdev);
+
+static int ebi2_lcd_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int ebi2_lcd_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+
+static struct dev_pm_ops ebi2_lcd_dev_pm_ops = {
+	.runtime_suspend = ebi2_lcd_runtime_suspend,
+	.runtime_resume = ebi2_lcd_runtime_resume,
+};
+
+static struct platform_driver ebi2_lcd_driver = {
+	.probe = ebi2_lcd_probe,
+	.remove = ebi2_lcd_remove,
+	.suspend = NULL,
+	.resume = NULL,
+	.shutdown = NULL,
+	.driver = {
+		   .name = "ebi2_lcd",
+		   .pm = &ebi2_lcd_dev_pm_ops,
+		   },
+};
+
+static void *ebi2_base;
+static void *ebi2_lcd_cfg0;
+static void *ebi2_lcd_cfg1;
+static void __iomem *lcd01_base;
+static void __iomem *lcd02_base;
+static int lcd01_base_phys;
+static int ebi2_lcd_resource_initialized;
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+static struct lcdc_platform_data *ebi2_pdata;
+
+static int ebi2_lcd_on(struct platform_device *pdev)
+{
+	int ret;
+
+	if (ebi2_pdata && ebi2_pdata->lcdc_power_save)
+		ebi2_pdata->lcdc_power_save(1);
+
+	ret = panel_next_on(pdev);
+	return ret;
+}
+
+static int ebi2_lcd_off(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = panel_next_off(pdev);
+
+	if (ebi2_pdata && ebi2_pdata->lcdc_power_save)
+		ebi2_pdata->lcdc_power_save(0);
+
+	return ret;
+}
+
+static int ebi2_lcd_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct platform_device *mdp_dev = NULL;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc, i, hw_version;
+
+	if (pdev->id == 0) {
+		for (i = 0; i < pdev->num_resources; i++) {
+			if (!strncmp(pdev->resource[i].name, "base", 4)) {
+				ebi2_base = ioremap(pdev->resource[i].start,
+						pdev->resource[i].end -
+						pdev->resource[i].start + 1);
+				if (!ebi2_base) {
+					printk(KERN_ERR
+						"ebi2_base ioremap failed!\n");
+					return -ENOMEM;
+				}
+				ebi2_lcd_cfg0 = (void *)(ebi2_base + 0x20);
+				ebi2_lcd_cfg1 = (void *)(ebi2_base + 0x24);
+			} else if (!strncmp(pdev->resource[i].name,
+						"lcd01", 5)) {
+				lcd01_base_phys = pdev->resource[i].start;
+				lcd01_base = ioremap(pdev->resource[i].start,
+						pdev->resource[i].end -
+						pdev->resource[i].start + 1);
+				if (!lcd01_base) {
+					printk(KERN_ERR
+						"lcd01_base ioremap failed!\n");
+					return -ENOMEM;
+				}
+			} else if (!strncmp(pdev->resource[i].name,
+						"lcd02", 5)) {
+				lcd02_base = ioremap(pdev->resource[i].start,
+						pdev->resource[i].end -
+						pdev->resource[i].start + 1);
+				if (!lcd02_base) {
+					printk(KERN_ERR
+						"lcd02_base ioremap failed!\n");
+					return -ENOMEM;
+				}
+			}
+		}
+		ebi2_pdata = pdev->dev.platform_data;
+		ebi2_lcd_resource_initialized = 1;
+
+		return 0;
+	}
+
+	if (!ebi2_lcd_resource_initialized)
+		return -EPERM;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	if (ebi2_base == NULL)
+		return -ENOMEM;
+
+	mdp_dev = platform_device_alloc("mdp", pdev->id);
+	if (!mdp_dev)
+		return -ENOMEM;
+
+	/* link to the latest pdev */
+	mfd->pdev = mdp_dev;
+	mfd->dest = DISPLAY_LCD;
+
+	/* add panel data */
+	if (platform_device_add_data
+	    (mdp_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		printk(KERN_ERR "ebi2_lcd_probe: platform_device_add_data failed!\n");
+		platform_device_put(mdp_dev);
+		return -ENOMEM;
+	}
+
+	/* data chain */
+	pdata = mdp_dev->dev.platform_data;
+	pdata->on = ebi2_lcd_on;
+	pdata->off = ebi2_lcd_off;
+	pdata->next = pdev;
+
+	/* get/set panel specific fb info */
+	mfd->panel_info = pdata->panel_info;
+
+	hw_version = inp32((int)ebi2_base + 8);
+
+	if (mfd->panel_info.bpp == 24)
+		mfd->fb_imgType = MDP_RGB_888;
+	else if (mfd->panel_info.bpp == 18)
+		mfd->fb_imgType = MDP_RGB_888;
+	else
+		mfd->fb_imgType = MDP_RGB_565;
+
+	/* config msm ebi2 lcd register */
+	if (mfd->panel_info.pdest == DISPLAY_1) {
+		outp32(ebi2_base,
+		       (inp32(ebi2_base) & (~(EBI2_PRIM_LCD_CLR))) |
+		       EBI2_PRIM_LCD_SEL);
+		/*
+		 * current design has one set of cfg0/1 register to control
+		 * both EBI2 channels. so, we're using the PRIM channel to
+		 * configure both.
+		 */
+		outp32(ebi2_lcd_cfg0, mfd->panel_info.wait_cycle);
+		if (hw_version < 0x2020) {
+			if (mfd->panel_info.bpp == 18)
+				outp32(ebi2_lcd_cfg1, 0x01000000);
+			else
+				outp32(ebi2_lcd_cfg1, 0x0);
+		}
+	} else {
+#ifdef DEBUG_EBI2_LCD
+		/*
+		 * confliting with QCOM SURF FPGA CS.
+		 * OEM should enable below for their CS mapping
+		 */
+		 outp32(ebi2_base, (inp32(ebi2_base)&(~(EBI2_SECD_LCD_CLR)))
+					|EBI2_SECD_LCD_SEL);
+#endif
+	}
+
+	/*
+	 * map cs (chip select) address
+	 */
+	if (mfd->panel_info.pdest == DISPLAY_1) {
+		mfd->cmd_port = lcd01_base;
+		if (hw_version >= 0x2020) {
+			mfd->data_port =
+				(void *)((uint32) mfd->cmd_port + 0x80);
+			mfd->data_port_phys =
+				(void *)(lcd01_base_phys + 0x80);
+		} else {
+			mfd->data_port =
+			    (void *)((uint32) mfd->cmd_port +
+				    EBI2_PRIM_LCD_RS_PIN);
+			mfd->data_port_phys =
+			    (void *)(LCD_PRIM_BASE_PHYS + EBI2_PRIM_LCD_RS_PIN);
+		}
+	} else {
+		mfd->cmd_port = lcd01_base;
+		mfd->data_port =
+		    (void *)((uint32) mfd->cmd_port + EBI2_SECD_LCD_RS_PIN);
+		mfd->data_port_phys =
+		    (void *)(LCD_SECD_BASE_PHYS + EBI2_SECD_LCD_RS_PIN);
+	}
+
+	/*
+	 * set driver data
+	 */
+	platform_set_drvdata(mdp_dev, mfd);
+
+	/*
+	 * register in mdp driver
+	 */
+	rc = platform_device_add(mdp_dev);
+	if (rc) {
+		goto ebi2_lcd_probe_err;
+	}
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+
+	pdev_list[pdev_list_cnt++] = pdev;
+	return 0;
+
+      ebi2_lcd_probe_err:
+	platform_device_put(mdp_dev);
+	return rc;
+}
+
+static int ebi2_lcd_remove(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return 0;
+
+	if (mfd->key != MFD_KEY)
+		return 0;
+
+	iounmap(mfd->cmd_port);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static int ebi2_lcd_register_driver(void)
+{
+	return platform_driver_register(&ebi2_lcd_driver);
+}
+
+static int __init ebi2_lcd_driver_init(void)
+{
+	return ebi2_lcd_register_driver();
+}
+
+module_init(ebi2_lcd_driver_init);
diff --git a/drivers/video/msm/ebi2_tmd20.c b/drivers/video/msm/ebi2_tmd20.c
new file mode 100644
index 0000000..280373f
--- /dev/null
+++ b/drivers/video/msm/ebi2_tmd20.c
@@ -0,0 +1,1120 @@
+/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+
+#include <linux/memory.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include "linux/proc_fs.h"
+
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+/* #define TMD20QVGA_LCD_18BPP */
+#define QVGA_WIDTH        240
+#define QVGA_HEIGHT       320
+
+#ifdef TMD20QVGA_LCD_18BPP
+#define DISP_QVGA_18BPP(x)  ((((x)<<2) & 0x3FC00)|(( (x)<<1)& 0x1FE))
+#define DISP_REG(name)  uint32 register_##name;
+#define OUTPORT(x, y)  outpdw(x, y)
+#define INPORT(x)   inpdw(x)
+#else
+#define DISP_QVGA_18BPP(x)  (x)
+#define DISP_REG(name)  uint16 register_##name;
+#define OUTPORT(x, y)  outpw(x, y)
+#define INPORT(x)   intpw(x)
+#endif
+
+static void *DISP_CMD_PORT;
+static void *DISP_DATA_PORT;
+
+#define DISP_RNTI         0x10
+
+#define DISP_CMD_OUT(cmd) OUTPORT(DISP_CMD_PORT, DISP_QVGA_18BPP(cmd))
+#define DISP_DATA_OUT(data) OUTPORT(DISP_DATA_PORT, data)
+#define DISP_DATA_IN() INPORT(DISP_DATA_PORT)
+
+#if (defined(TMD20QVGA_LCD_18BPP))
+#define DISP_DATA_OUT_16TO18BPP(x) \
+	DISP_DATA_OUT((((x)&0xf800)<<2|((x)&0x80000)>>3) \
+		     | (((x)&0x7e0)<<1) \
+		     | (((x)&0x1F)<<1|((x)&0x10)>>4))
+#else
+#define DISP_DATA_OUT_16TO18BPP(x) \
+	DISP_DATA_OUT(x)
+#endif
+
+#define DISP_WRITE_OUT(addr, data) \
+   register_##addr = DISP_QVGA_18BPP(data); \
+   DISP_CMD_OUT(addr); \
+   DISP_DATA_OUT(register_##addr);
+
+#define DISP_UPDATE_VALUE(addr, bitmask, data) \
+   DISP_WRITE_OUT(##addr, (register_##addr & ~(bitmask)) | (data));
+
+#define DISP_VAL_IF(bitvalue, bitmask) \
+   ((bitvalue) ? (bitmask) : 0)
+
+/* QVGA = 256 x 320 */
+/* actual display is 240 x 320...offset by 0x10 */
+#define DISP_ROW_COL_TO_ADDR(row, col) ((row) * 0x100 + col)
+#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \
+   { \
+   DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_1_ADDR, (ulhc_col) + tmd20qvga_panel_offset); \
+   DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_2_ADDR, (lrhc_col) + tmd20qvga_panel_offset); \
+   DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_1_ADDR, (ulhc_row)); \
+   DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_2_ADDR, (lrhc_row)); \
+   DISP_WRITE_OUT(DISP_RAM_ADDR_SET_1_ADDR, (ulhc_col) + tmd20qvga_panel_offset); \
+   DISP_WRITE_OUT(DISP_RAM_ADDR_SET_2_ADDR, (ulhc_row)); \
+   }
+
+#define WAIT_MSEC(msec) mdelay(msec)
+
+/*
+ * TMD QVGA Address
+ */
+/* Display Control */
+#define DISP_START_OSCILLATION_ADDR     0x000
+DISP_REG(DISP_START_OSCILLATION_ADDR)
+#define DISP_DRIVER_OUTPUT_CTL_ADDR     0x001
+    DISP_REG(DISP_DRIVER_OUTPUT_CTL_ADDR)
+#define DISP_LCD_DRIVING_SIG_ADDR     0x002
+    DISP_REG(DISP_LCD_DRIVING_SIG_ADDR)
+#define DISP_ENTRY_MODE_ADDR            0x003
+    DISP_REG(DISP_ENTRY_MODE_ADDR)
+#define DISP_DISPLAY_CTL_1_ADDR         0x007
+    DISP_REG(DISP_DISPLAY_CTL_1_ADDR)
+#define DISP_DISPLAY_CTL_2_ADDR         0x008
+    DISP_REG(DISP_DISPLAY_CTL_2_ADDR)
+
+/* DISPLAY MODE 0x009 partial display not supported */
+#define DISP_POWER_SUPPLY_INTF_ADDR     0x00A
+    DISP_REG(DISP_POWER_SUPPLY_INTF_ADDR)
+
+/* DISPLAY MODE 0x00B xZoom feature is not supported */
+#define DISP_EXT_DISPLAY_CTL_1_ADDR     0x00C
+    DISP_REG(DISP_EXT_DISPLAY_CTL_1_ADDR)
+
+#define DISP_FRAME_CYCLE_CTL_ADDR       0x00D
+    DISP_REG(DISP_FRAME_CYCLE_CTL_ADDR)
+
+#define DISP_EXT_DISPLAY_CTL_2_ADDR     0x00E
+    DISP_REG(DISP_EXT_DISPLAY_CTL_2_ADDR)
+
+#define DISP_EXT_DISPLAY_CTL_3_ADDR     0x00F
+    DISP_REG(DISP_EXT_DISPLAY_CTL_3_ADDR)
+
+#define DISP_LTPS_CTL_1_ADDR            0x012
+    DISP_REG(DISP_LTPS_CTL_1_ADDR)
+#define DISP_LTPS_CTL_2_ADDR            0x013
+    DISP_REG(DISP_LTPS_CTL_2_ADDR)
+#define DISP_LTPS_CTL_3_ADDR            0x014
+    DISP_REG(DISP_LTPS_CTL_3_ADDR)
+#define DISP_LTPS_CTL_4_ADDR            0x018
+    DISP_REG(DISP_LTPS_CTL_4_ADDR)
+#define DISP_LTPS_CTL_5_ADDR            0x019
+    DISP_REG(DISP_LTPS_CTL_5_ADDR)
+#define DISP_LTPS_CTL_6_ADDR            0x01A
+    DISP_REG(DISP_LTPS_CTL_6_ADDR)
+#define DISP_AMP_SETTING_ADDR           0x01C
+    DISP_REG(DISP_AMP_SETTING_ADDR)
+#define DISP_MODE_SETTING_ADDR          0x01D
+    DISP_REG(DISP_MODE_SETTING_ADDR)
+#define DISP_POFF_LN_SETTING_ADDR       0x01E
+    DISP_REG(DISP_POFF_LN_SETTING_ADDR)
+/* Power Contol */
+#define DISP_POWER_CTL_1_ADDR           0x100
+    DISP_REG(DISP_POWER_CTL_1_ADDR)
+#define DISP_POWER_CTL_2_ADDR           0x101
+    DISP_REG(DISP_POWER_CTL_2_ADDR)
+#define DISP_POWER_CTL_3_ADDR           0x102
+    DISP_REG(DISP_POWER_CTL_3_ADDR)
+#define DISP_POWER_CTL_4_ADDR           0x103
+    DISP_REG(DISP_POWER_CTL_4_ADDR)
+#define DISP_POWER_CTL_5_ADDR           0x104
+    DISP_REG(DISP_POWER_CTL_5_ADDR)
+#define DISP_POWER_CTL_6_ADDR           0x105
+    DISP_REG(DISP_POWER_CTL_6_ADDR)
+#define DISP_POWER_CTL_7_ADDR           0x106
+    DISP_REG(DISP_POWER_CTL_7_ADDR)
+/* RAM Access */
+#define DISP_RAM_ADDR_SET_1_ADDR        0x200
+    DISP_REG(DISP_RAM_ADDR_SET_1_ADDR)
+#define DISP_RAM_ADDR_SET_2_ADDR        0x201
+    DISP_REG(DISP_RAM_ADDR_SET_2_ADDR)
+#define DISP_CMD_RAMRD                  DISP_CMD_RAMWR
+#define DISP_CMD_RAMWR                  0x202
+    DISP_REG(DISP_CMD_RAMWR)
+#define DISP_RAM_DATA_MASK_1_ADDR       0x203
+    DISP_REG(DISP_RAM_DATA_MASK_1_ADDR)
+#define DISP_RAM_DATA_MASK_2_ADDR       0x204
+    DISP_REG(DISP_RAM_DATA_MASK_2_ADDR)
+/* Gamma Control, Contrast, Gray Scale Setting */
+#define DISP_GAMMA_CONTROL_1_ADDR       0x300
+    DISP_REG(DISP_GAMMA_CONTROL_1_ADDR)
+#define DISP_GAMMA_CONTROL_2_ADDR       0x301
+    DISP_REG(DISP_GAMMA_CONTROL_2_ADDR)
+#define DISP_GAMMA_CONTROL_3_ADDR       0x302
+    DISP_REG(DISP_GAMMA_CONTROL_3_ADDR)
+#define DISP_GAMMA_CONTROL_4_ADDR       0x303
+    DISP_REG(DISP_GAMMA_CONTROL_4_ADDR)
+#define DISP_GAMMA_CONTROL_5_ADDR       0x304
+    DISP_REG(DISP_GAMMA_CONTROL_5_ADDR)
+/* Coordinate Control */
+#define DISP_VERT_SCROLL_CTL_1_ADDR     0x400
+    DISP_REG(DISP_VERT_SCROLL_CTL_1_ADDR)
+#define DISP_VERT_SCROLL_CTL_2_ADDR     0x401
+    DISP_REG(DISP_VERT_SCROLL_CTL_2_ADDR)
+#define DISP_SCREEN_1_DRV_POS_1_ADDR    0x402
+    DISP_REG(DISP_SCREEN_1_DRV_POS_1_ADDR)
+#define DISP_SCREEN_1_DRV_POS_2_ADDR    0x403
+    DISP_REG(DISP_SCREEN_1_DRV_POS_2_ADDR)
+#define DISP_SCREEN_2_DRV_POS_1_ADDR    0x404
+    DISP_REG(DISP_SCREEN_2_DRV_POS_1_ADDR)
+#define DISP_SCREEN_2_DRV_POS_2_ADDR    0x405
+    DISP_REG(DISP_SCREEN_2_DRV_POS_2_ADDR)
+#define DISP_HORZ_RAM_ADDR_POS_1_ADDR   0x406
+    DISP_REG(DISP_HORZ_RAM_ADDR_POS_1_ADDR)
+#define DISP_HORZ_RAM_ADDR_POS_2_ADDR   0x407
+    DISP_REG(DISP_HORZ_RAM_ADDR_POS_2_ADDR)
+#define DISP_VERT_RAM_ADDR_POS_1_ADDR   0x408
+    DISP_REG(DISP_VERT_RAM_ADDR_POS_1_ADDR)
+#define DISP_VERT_RAM_ADDR_POS_2_ADDR   0x409
+    DISP_REG(DISP_VERT_RAM_ADDR_POS_2_ADDR)
+#define DISP_TMD_700_ADDR               0x700	/*  0x700 */
+    DISP_REG(DISP_TMD_700_ADDR)
+#define DISP_TMD_015_ADDR               0x015	/*  0x700 */
+    DISP_REG(DISP_TMD_015_ADDR)
+#define DISP_TMD_305_ADDR               0x305	/*  0x700 */
+    DISP_REG(DISP_TMD_305_ADDR)
+
+/*
+ * TMD QVGA Bit Definations
+ */
+
+#define DISP_BIT_IB15              0x8000
+#define DISP_BIT_IB14              0x4000
+#define DISP_BIT_IB13              0x2000
+#define DISP_BIT_IB12              0x1000
+#define DISP_BIT_IB11              0x0800
+#define DISP_BIT_IB10              0x0400
+#define DISP_BIT_IB09              0x0200
+#define DISP_BIT_IB08              0x0100
+#define DISP_BIT_IB07              0x0080
+#define DISP_BIT_IB06              0x0040
+#define DISP_BIT_IB05              0x0020
+#define DISP_BIT_IB04              0x0010
+#define DISP_BIT_IB03              0x0008
+#define DISP_BIT_IB02              0x0004
+#define DISP_BIT_IB01              0x0002
+#define DISP_BIT_IB00              0x0001
+/*
+ * Display Control
+ * DISP_START_OSCILLATION_ADDR     Start Oscillation
+ * DISP_DRIVER_OUTPUT_CTL_ADDR     Driver Output Control
+ */
+#define DISP_BITMASK_SS            DISP_BIT_IB08
+#define DISP_BITMASK_NL5           DISP_BIT_IB05
+#define DISP_BITMASK_NL4           DISP_BIT_IB04
+#define DISP_BITMASK_NL3           DISP_BIT_IB03
+#define DISP_BITMASK_NL2           DISP_BIT_IB02
+#define DISP_BITMASK_NL1           DISP_BIT_IB01
+#define DISP_BITMASK_NL0           DISP_BIT_IB00
+/* DISP_LCD_DRIVING_SIG_ADDR       LCD Driving Signal Setting */
+#define DISP_BITMASK_BC            DISP_BIT_IB09
+/* DISP_ENTRY_MODE_ADDR            Entry Mode */
+#define DISP_BITMASK_TRI           DISP_BIT_IB15
+#define DISP_BITMASK_DFM1          DISP_BIT_IB14
+#define DISP_BITMASK_DFM0          DISP_BIT_IB13
+#define DISP_BITMASK_BGR           DISP_BIT_IB12
+#define DISP_BITMASK_HWM0          DISP_BIT_IB08
+#define DISP_BITMASK_ID1           DISP_BIT_IB05
+#define DISP_BITMASK_ID0           DISP_BIT_IB04
+#define DISP_BITMASK_AM            DISP_BIT_IB03
+/* DISP_DISPLAY_CTL_1_ADDR         Display Control (1) */
+#define DISP_BITMASK_COL1          DISP_BIT_IB15
+#define DISP_BITMASK_COL0          DISP_BIT_IB14
+#define DISP_BITMASK_VLE2          DISP_BIT_IB10
+#define DISP_BITMASK_VLE1          DISP_BIT_IB09
+#define DISP_BITMASK_SPT           DISP_BIT_IB08
+#define DISP_BITMASK_PT1           DISP_BIT_IB07
+#define DISP_BITMASK_PT0           DISP_BIT_IB06
+#define DISP_BITMASK_REV           DISP_BIT_IB02
+/* DISP_DISPLAY_CTL_2_ADDR         Display Control (2) */
+#define DISP_BITMASK_FP3           DISP_BIT_IB11
+#define DISP_BITMASK_FP2           DISP_BIT_IB10
+#define DISP_BITMASK_FP1           DISP_BIT_IB09
+#define DISP_BITMASK_FP0           DISP_BIT_IB08
+#define DISP_BITMASK_BP3           DISP_BIT_IB03
+#define DISP_BITMASK_BP2           DISP_BIT_IB02
+#define DISP_BITMASK_BP1           DISP_BIT_IB01
+#define DISP_BITMASK_BP0           DISP_BIT_IB00
+/* DISP_POWER_SUPPLY_INTF_ADDR     Power Supply IC Interface Control */
+#define DISP_BITMASK_CSE           DISP_BIT_IB12
+#define DISP_BITMASK_TE            DISP_BIT_IB08
+#define DISP_BITMASK_IX3           DISP_BIT_IB03
+#define DISP_BITMASK_IX2           DISP_BIT_IB02
+#define DISP_BITMASK_IX1           DISP_BIT_IB01
+#define DISP_BITMASK_IX0           DISP_BIT_IB00
+/* DISP_EXT_DISPLAY_CTL_1_ADDR     External Display Interface Control (1) */
+#define DISP_BITMASK_RM            DISP_BIT_IB08
+#define DISP_BITMASK_DM1           DISP_BIT_IB05
+#define DISP_BITMASK_DM0           DISP_BIT_IB04
+#define DISP_BITMASK_RIM1          DISP_BIT_IB01
+#define DISP_BITMASK_RIM0          DISP_BIT_IB00
+/* DISP_FRAME_CYCLE_CTL_ADDR       Frame Frequency Adjustment Control */
+#define DISP_BITMASK_DIVI1         DISP_BIT_IB09
+#define DISP_BITMASK_DIVI0         DISP_BIT_IB08
+#define DISP_BITMASK_RTNI4         DISP_BIT_IB04
+#define DISP_BITMASK_RTNI3         DISP_BIT_IB03
+#define DISP_BITMASK_RTNI2         DISP_BIT_IB02
+#define DISP_BITMASK_RTNI1         DISP_BIT_IB01
+#define DISP_BITMASK_RTNI0         DISP_BIT_IB00
+/* DISP_EXT_DISPLAY_CTL_2_ADDR     External Display Interface Control (2) */
+#define DISP_BITMASK_DIVE1         DISP_BIT_IB09
+#define DISP_BITMASK_DIVE0         DISP_BIT_IB08
+#define DISP_BITMASK_RTNE7         DISP_BIT_IB07
+#define DISP_BITMASK_RTNE6         DISP_BIT_IB06
+#define DISP_BITMASK_RTNE5         DISP_BIT_IB05
+#define DISP_BITMASK_RTNE4         DISP_BIT_IB04
+#define DISP_BITMASK_RTNE3         DISP_BIT_IB03
+#define DISP_BITMASK_RTNE2         DISP_BIT_IB02
+#define DISP_BITMASK_RTNE1         DISP_BIT_IB01
+#define DISP_BITMASK_RTNE0         DISP_BIT_IB00
+/* DISP_EXT_DISPLAY_CTL_3_ADDR     External Display Interface Control (3) */
+#define DISP_BITMASK_VSPL          DISP_BIT_IB04
+#define DISP_BITMASK_HSPL          DISP_BIT_IB03
+#define DISP_BITMASK_VPL           DISP_BIT_IB02
+#define DISP_BITMASK_EPL           DISP_BIT_IB01
+#define DISP_BITMASK_DPL           DISP_BIT_IB00
+/* DISP_LTPS_CTL_1_ADDR            LTPS Interface Control (1) */
+#define DISP_BITMASK_CLWI3         DISP_BIT_IB11
+#define DISP_BITMASK_CLWI2         DISP_BIT_IB10
+#define DISP_BITMASK_CLWI1         DISP_BIT_IB09
+#define DISP_BITMASK_CLWI0         DISP_BIT_IB08
+#define DISP_BITMASK_CLTI1         DISP_BIT_IB01
+#define DISP_BITMASK_CLTI0         DISP_BIT_IB00
+/* DISP_LTPS_CTL_2_ADDR            LTPS Interface Control (2) */
+#define DISP_BITMASK_OEVBI1        DISP_BIT_IB09
+#define DISP_BITMASK_OEVBI0        DISP_BIT_IB08
+#define DISP_BITMASK_OEVFI1        DISP_BIT_IB01
+#define DISP_BITMASK_OEVFI0        DISP_BIT_IB00
+/* DISP_LTPS_CTL_3_ADDR            LTPS Interface Control (3) */
+#define DISP_BITMASK_SHI1          DISP_BIT_IB01
+#define DISP_BITMASK_SHI0          DISP_BIT_IB00
+/* DISP_LTPS_CTL_4_ADDR            LTPS Interface Control (4) */
+#define DISP_BITMASK_CLWE5         DISP_BIT_IB13
+#define DISP_BITMASK_CLWE4         DISP_BIT_IB12
+#define DISP_BITMASK_CLWE3         DISP_BIT_IB11
+#define DISP_BITMASK_CLWE2         DISP_BIT_IB10
+#define DISP_BITMASK_CLWE1         DISP_BIT_IB09
+#define DISP_BITMASK_CLWE0         DISP_BIT_IB08
+#define DISP_BITMASK_CLTE3         DISP_BIT_IB03
+#define DISP_BITMASK_CLTE2         DISP_BIT_IB02
+#define DISP_BITMASK_CLTE1         DISP_BIT_IB01
+#define DISP_BITMASK_CLTE0         DISP_BIT_IB00
+/* DISP_LTPS_CTL_5_ADDR            LTPS Interface Control (5) */
+#define DISP_BITMASK_OEVBE3        DISP_BIT_IB11
+#define DISP_BITMASK_OEVBE2        DISP_BIT_IB10
+#define DISP_BITMASK_OEVBE1        DISP_BIT_IB09
+#define DISP_BITMASK_OEVBE0        DISP_BIT_IB08
+#define DISP_BITMASK_OEVFE3        DISP_BIT_IB03
+#define DISP_BITMASK_OEVFE2        DISP_BIT_IB02
+#define DISP_BITMASK_OEVFE1        DISP_BIT_IB01
+#define DISP_BITMASK_OEVFE0        DISP_BIT_IB00
+/* DISP_LTPS_CTL_6_ADDR            LTPS Interface Control (6) */
+#define DISP_BITMASK_SHE3          DISP_BIT_IB03
+#define DISP_BITMASK_SHE2          DISP_BIT_IB02
+#define DISP_BITMASK_SHE1          DISP_BIT_IB01
+#define DISP_BITMASK_SHE0          DISP_BIT_IB00
+/* DISP_AMP_SETTING_ADDR           Amplify Setting */
+#define DISP_BITMASK_ABSW1         DISP_BIT_IB01
+#define DISP_BITMASK_ABSW0         DISP_BIT_IB00
+/* DISP_MODE_SETTING_ADDR          Mode Setting */
+#define DISP_BITMASK_DSTB          DISP_BIT_IB02
+#define DISP_BITMASK_STB           DISP_BIT_IB00
+/* DISP_POFF_LN_SETTING_ADDR       Power Off Line Setting */
+#define DISP_BITMASK_POFH3         DISP_BIT_IB03
+#define DISP_BITMASK_POFH2         DISP_BIT_IB02
+#define DISP_BITMASK_POFH1         DISP_BIT_IB01
+#define DISP_BITMASK_POFH0         DISP_BIT_IB00
+
+/* Power Contol */
+/* DISP_POWER_CTL_1_ADDR           Power Control (1) */
+#define DISP_BITMASK_PO            DISP_BIT_IB11
+#define DISP_BITMASK_VCD           DISP_BIT_IB09
+#define DISP_BITMASK_VSC           DISP_BIT_IB08
+#define DISP_BITMASK_CON           DISP_BIT_IB07
+#define DISP_BITMASK_ASW1          DISP_BIT_IB06
+#define DISP_BITMASK_ASW0          DISP_BIT_IB05
+#define DISP_BITMASK_OEV           DISP_BIT_IB04
+#define DISP_BITMASK_OEVE          DISP_BIT_IB03
+#define DISP_BITMASK_FR            DISP_BIT_IB02
+#define DISP_BITMASK_D1            DISP_BIT_IB01
+#define DISP_BITMASK_D0            DISP_BIT_IB00
+/* DISP_POWER_CTL_2_ADDR           Power Control (2) */
+#define DISP_BITMASK_DC4           DISP_BIT_IB15
+#define DISP_BITMASK_DC3           DISP_BIT_IB14
+#define DISP_BITMASK_SAP2          DISP_BIT_IB13
+#define DISP_BITMASK_SAP1          DISP_BIT_IB12
+#define DISP_BITMASK_SAP0          DISP_BIT_IB11
+#define DISP_BITMASK_BT2           DISP_BIT_IB10
+#define DISP_BITMASK_BT1           DISP_BIT_IB09
+#define DISP_BITMASK_BT0           DISP_BIT_IB08
+#define DISP_BITMASK_DC2           DISP_BIT_IB07
+#define DISP_BITMASK_DC1           DISP_BIT_IB06
+#define DISP_BITMASK_DC0           DISP_BIT_IB05
+#define DISP_BITMASK_AP2           DISP_BIT_IB04
+#define DISP_BITMASK_AP1           DISP_BIT_IB03
+#define DISP_BITMASK_AP0           DISP_BIT_IB02
+/* DISP_POWER_CTL_3_ADDR           Power Control (3) */
+#define DISP_BITMASK_VGL4          DISP_BIT_IB10
+#define DISP_BITMASK_VGL3          DISP_BIT_IB09
+#define DISP_BITMASK_VGL2          DISP_BIT_IB08
+#define DISP_BITMASK_VGL1          DISP_BIT_IB07
+#define DISP_BITMASK_VGL0          DISP_BIT_IB06
+#define DISP_BITMASK_VGH4          DISP_BIT_IB04
+#define DISP_BITMASK_VGH3          DISP_BIT_IB03
+#define DISP_BITMASK_VGH2          DISP_BIT_IB02
+#define DISP_BITMASK_VGH1          DISP_BIT_IB01
+#define DISP_BITMASK_VGH0          DISP_BIT_IB00
+/* DISP_POWER_CTL_4_ADDR           Power Control (4) */
+#define DISP_BITMASK_VC2           DISP_BIT_IB02
+#define DISP_BITMASK_VC1           DISP_BIT_IB01
+#define DISP_BITMASK_VC0           DISP_BIT_IB00
+/* DISP_POWER_CTL_5_ADDR           Power Control (5) */
+#define DISP_BITMASK_VRL3          DISP_BIT_IB11
+#define DISP_BITMASK_VRL2          DISP_BIT_IB10
+#define DISP_BITMASK_VRL1          DISP_BIT_IB09
+#define DISP_BITMASK_VRL0          DISP_BIT_IB08
+#define DISP_BITMASK_PON           DISP_BIT_IB04
+#define DISP_BITMASK_VRH3          DISP_BIT_IB03
+#define DISP_BITMASK_VRH2          DISP_BIT_IB02
+#define DISP_BITMASK_VRH1          DISP_BIT_IB01
+#define DISP_BITMASK_VRH0          DISP_BIT_IB00
+/* DISP_POWER_CTL_6_ADDR           Power Control (6) */
+#define DISP_BITMASK_VCOMG         DISP_BIT_IB13
+#define DISP_BITMASK_VDV4          DISP_BIT_IB12
+#define DISP_BITMASK_VDV3          DISP_BIT_IB11
+#define DISP_BITMASK_VDV2          DISP_BIT_IB10
+#define DISP_BITMASK_VDV1          DISP_BIT_IB09
+#define DISP_BITMASK_VDV0          DISP_BIT_IB08
+#define DISP_BITMASK_VCM4          DISP_BIT_IB04
+#define DISP_BITMASK_VCM3          DISP_BIT_IB03
+#define DISP_BITMASK_VCM2          DISP_BIT_IB02
+#define DISP_BITMASK_VCM1          DISP_BIT_IB01
+#define DISP_BITMASK_VCM0          DISP_BIT_IB00
+/* RAM Access */
+/* DISP_RAM_ADDR_SET_1_ADDR        RAM Address Set (1) */
+#define DISP_BITMASK_AD7           DISP_BIT_IB07
+#define DISP_BITMASK_AD6           DISP_BIT_IB06
+#define DISP_BITMASK_AD5           DISP_BIT_IB05
+#define DISP_BITMASK_AD4           DISP_BIT_IB04
+#define DISP_BITMASK_AD3           DISP_BIT_IB03
+#define DISP_BITMASK_AD2           DISP_BIT_IB02
+#define DISP_BITMASK_AD1           DISP_BIT_IB01
+#define DISP_BITMASK_AD0           DISP_BIT_IB00
+/* DISP_RAM_ADDR_SET_2_ADDR        RAM Address Set (2) */
+#define DISP_BITMASK_AD16          DISP_BIT_IB08
+#define DISP_BITMASK_AD15          DISP_BIT_IB07
+#define DISP_BITMASK_AD14          DISP_BIT_IB06
+#define DISP_BITMASK_AD13          DISP_BIT_IB05
+#define DISP_BITMASK_AD12          DISP_BIT_IB04
+#define DISP_BITMASK_AD11          DISP_BIT_IB03
+#define DISP_BITMASK_AD10          DISP_BIT_IB02
+#define DISP_BITMASK_AD9           DISP_BIT_IB01
+#define DISP_BITMASK_AD8           DISP_BIT_IB00
+/*
+ * DISP_CMD_RAMWR       RAM Data Read/Write
+ * Use Data Bit Configuration
+ */
+/* DISP_RAM_DATA_MASK_1_ADDR       RAM Write Data Mask (1) */
+#define DISP_BITMASK_WM11          DISP_BIT_IB13
+#define DISP_BITMASK_WM10          DISP_BIT_IB12
+#define DISP_BITMASK_WM9           DISP_BIT_IB11
+#define DISP_BITMASK_WM8           DISP_BIT_IB10
+#define DISP_BITMASK_WM7           DISP_BIT_IB09
+#define DISP_BITMASK_WM6           DISP_BIT_IB08
+#define DISP_BITMASK_WM5           DISP_BIT_IB05
+#define DISP_BITMASK_WM4           DISP_BIT_IB04
+#define DISP_BITMASK_WM3           DISP_BIT_IB03
+#define DISP_BITMASK_WM2           DISP_BIT_IB02
+#define DISP_BITMASK_WM1           DISP_BIT_IB01
+#define DISP_BITMASK_WM0           DISP_BIT_IB00
+/* DISP_RAM_DATA_MASK_2_ADDR       RAM Write Data Mask (2) */
+#define DISP_BITMASK_WM17          DISP_BIT_IB05
+#define DISP_BITMASK_WM16          DISP_BIT_IB04
+#define DISP_BITMASK_WM15          DISP_BIT_IB03
+#define DISP_BITMASK_WM14          DISP_BIT_IB02
+#define DISP_BITMASK_WM13          DISP_BIT_IB01
+#define DISP_BITMASK_WM12          DISP_BIT_IB00
+/*Gamma Control */
+/* DISP_GAMMA_CONTROL_1_ADDR       Gamma Control (1) */
+#define DISP_BITMASK_PKP12         DISP_BIT_IB10
+#define DISP_BITMASK_PKP11         DISP_BIT_IB08
+#define DISP_BITMASK_PKP10         DISP_BIT_IB09
+#define DISP_BITMASK_PKP02         DISP_BIT_IB02
+#define DISP_BITMASK_PKP01         DISP_BIT_IB01
+#define DISP_BITMASK_PKP00         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_2_ADDR       Gamma Control (2) */
+#define DISP_BITMASK_PKP32         DISP_BIT_IB10
+#define DISP_BITMASK_PKP31         DISP_BIT_IB09
+#define DISP_BITMASK_PKP30         DISP_BIT_IB08
+#define DISP_BITMASK_PKP22         DISP_BIT_IB02
+#define DISP_BITMASK_PKP21         DISP_BIT_IB01
+#define DISP_BITMASK_PKP20         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_3_ADDR       Gamma Control (3) */
+#define DISP_BITMASK_PKP52         DISP_BIT_IB10
+#define DISP_BITMASK_PKP51         DISP_BIT_IB09
+#define DISP_BITMASK_PKP50         DISP_BIT_IB08
+#define DISP_BITMASK_PKP42         DISP_BIT_IB02
+#define DISP_BITMASK_PKP41         DISP_BIT_IB01
+#define DISP_BITMASK_PKP40         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_4_ADDR       Gamma Control (4) */
+#define DISP_BITMASK_PRP12         DISP_BIT_IB10
+#define DISP_BITMASK_PRP11         DISP_BIT_IB08
+#define DISP_BITMASK_PRP10         DISP_BIT_IB09
+#define DISP_BITMASK_PRP02         DISP_BIT_IB02
+#define DISP_BITMASK_PRP01         DISP_BIT_IB01
+#define DISP_BITMASK_PRP00         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_5_ADDR       Gamma Control (5) */
+#define DISP_BITMASK_VRP14         DISP_BIT_IB12
+#define DISP_BITMASK_VRP13         DISP_BIT_IB11
+#define DISP_BITMASK_VRP12         DISP_BIT_IB10
+#define DISP_BITMASK_VRP11         DISP_BIT_IB08
+#define DISP_BITMASK_VRP10         DISP_BIT_IB09
+#define DISP_BITMASK_VRP03         DISP_BIT_IB03
+#define DISP_BITMASK_VRP02         DISP_BIT_IB02
+#define DISP_BITMASK_VRP01         DISP_BIT_IB01
+#define DISP_BITMASK_VRP00         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_6_ADDR       Gamma Control (6) */
+#define DISP_BITMASK_PKN12         DISP_BIT_IB10
+#define DISP_BITMASK_PKN11         DISP_BIT_IB08
+#define DISP_BITMASK_PKN10         DISP_BIT_IB09
+#define DISP_BITMASK_PKN02         DISP_BIT_IB02
+#define DISP_BITMASK_PKN01         DISP_BIT_IB01
+#define DISP_BITMASK_PKN00         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_7_ADDR       Gamma Control (7) */
+#define DISP_BITMASK_PKN32         DISP_BIT_IB10
+#define DISP_BITMASK_PKN31         DISP_BIT_IB08
+#define DISP_BITMASK_PKN30         DISP_BIT_IB09
+#define DISP_BITMASK_PKN22         DISP_BIT_IB02
+#define DISP_BITMASK_PKN21         DISP_BIT_IB01
+#define DISP_BITMASK_PKN20         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_8_ADDR       Gamma Control (8) */
+#define DISP_BITMASK_PKN52         DISP_BIT_IB10
+#define DISP_BITMASK_PKN51         DISP_BIT_IB08
+#define DISP_BITMASK_PKN50         DISP_BIT_IB09
+#define DISP_BITMASK_PKN42         DISP_BIT_IB02
+#define DISP_BITMASK_PKN41         DISP_BIT_IB01
+#define DISP_BITMASK_PKN40         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_9_ADDR       Gamma Control (9) */
+#define DISP_BITMASK_PRN12         DISP_BIT_IB10
+#define DISP_BITMASK_PRN11         DISP_BIT_IB08
+#define DISP_BITMASK_PRN10         DISP_BIT_IB09
+#define DISP_BITMASK_PRN02         DISP_BIT_IB02
+#define DISP_BITMASK_PRN01         DISP_BIT_IB01
+#define DISP_BITMASK_PRN00         DISP_BIT_IB00
+/* DISP_GAMMA_CONTROL_10_ADDR      Gamma Control (10) */
+#define DISP_BITMASK_VRN14         DISP_BIT_IB12
+#define DISP_BITMASK_VRN13         DISP_BIT_IB11
+#define DISP_BITMASK_VRN12         DISP_BIT_IB10
+#define DISP_BITMASK_VRN11         DISP_BIT_IB08
+#define DISP_BITMASK_VRN10         DISP_BIT_IB09
+#define DISP_BITMASK_VRN03         DISP_BIT_IB03
+#define DISP_BITMASK_VRN02         DISP_BIT_IB02
+#define DISP_BITMASK_VRN01         DISP_BIT_IB01
+#define DISP_BITMASK_VRN00         DISP_BIT_IB00
+/* Coordinate Control */
+/* DISP_VERT_SCROLL_CTL_1_ADDR     Vertical Scroll Control (1) */
+#define DISP_BITMASK_VL18          DISP_BIT_IB08
+#define DISP_BITMASK_VL17          DISP_BIT_IB07
+#define DISP_BITMASK_VL16          DISP_BIT_IB06
+#define DISP_BITMASK_VL15          DISP_BIT_IB05
+#define DISP_BITMASK_VL14          DISP_BIT_IB04
+#define DISP_BITMASK_VL13          DISP_BIT_IB03
+#define DISP_BITMASK_VL12          DISP_BIT_IB02
+#define DISP_BITMASK_VL11          DISP_BIT_IB01
+#define DISP_BITMASK_VL10          DISP_BIT_IB00
+/* DISP_VERT_SCROLL_CTL_2_ADDR     Vertical Scroll Control (2) */
+#define DISP_BITMASK_VL28          DISP_BIT_IB08
+#define DISP_BITMASK_VL27          DISP_BIT_IB07
+#define DISP_BITMASK_VL26          DISP_BIT_IB06
+#define DISP_BITMASK_VL25          DISP_BIT_IB05
+#define DISP_BITMASK_VL24          DISP_BIT_IB04
+#define DISP_BITMASK_VL23          DISP_BIT_IB03
+#define DISP_BITMASK_VL22          DISP_BIT_IB02
+#define DISP_BITMASK_VL21          DISP_BIT_IB01
+#define DISP_BITMASK_VL20          DISP_BIT_IB00
+/* DISP_SCREEN_1_DRV_POS_1_ADDR    First Screen Driving Position (1) */
+#define DISP_BITMASK_SS18          DISP_BIT_IB08
+#define DISP_BITMASK_SS17          DISP_BIT_IB07
+#define DISP_BITMASK_SS16          DISP_BIT_IB06
+#define DISP_BITMASK_SS15          DISP_BIT_IB05
+#define DISP_BITMASK_SS14          DISP_BIT_IB04
+#define DISP_BITMASK_SS13          DISP_BIT_IB03
+#define DISP_BITMASK_SS12          DISP_BIT_IB02
+#define DISP_BITMASK_SS11          DISP_BIT_IB01
+#define DISP_BITMASK_SS10          DISP_BIT_IB00
+/* DISP_SCREEN_1_DRV_POS_2_ADDR    First Screen Driving Position (2) */
+#define DISP_BITMASK_SE18          DISP_BIT_IB08
+#define DISP_BITMASK_SE17          DISP_BIT_IB07
+#define DISP_BITMASK_SE16          DISP_BIT_IB06
+#define DISP_BITMASK_SE15          DISP_BIT_IB05
+#define DISP_BITMASK_SE14          DISP_BIT_IB04
+#define DISP_BITMASK_SE13          DISP_BIT_IB03
+#define DISP_BITMASK_SE12          DISP_BIT_IB02
+#define DISP_BITMASK_SE11          DISP_BIT_IB01
+#define DISP_BITMASK_SE10          DISP_BIT_IB00
+/* DISP_SCREEN_2_DRV_POS_1_ADDR    Second Screen Driving Position (1) */
+#define DISP_BITMASK_SS28          DISP_BIT_IB08
+#define DISP_BITMASK_SS27          DISP_BIT_IB07
+#define DISP_BITMASK_SS26          DISP_BIT_IB06
+#define DISP_BITMASK_SS25          DISP_BIT_IB05
+#define DISP_BITMASK_SS24          DISP_BIT_IB04
+#define DISP_BITMASK_SS23          DISP_BIT_IB03
+#define DISP_BITMASK_SS22          DISP_BIT_IB02
+#define DISP_BITMASK_SS21          DISP_BIT_IB01
+#define DISP_BITMASK_SS20          DISP_BIT_IB00
+/* DISP_SCREEN_3_DRV_POS_2_ADDR    Second Screen Driving Position (2) */
+#define DISP_BITMASK_SE28          DISP_BIT_IB08
+#define DISP_BITMASK_SE27          DISP_BIT_IB07
+#define DISP_BITMASK_SE26          DISP_BIT_IB06
+#define DISP_BITMASK_SE25          DISP_BIT_IB05
+#define DISP_BITMASK_SE24          DISP_BIT_IB04
+#define DISP_BITMASK_SE23          DISP_BIT_IB03
+#define DISP_BITMASK_SE22          DISP_BIT_IB02
+#define DISP_BITMASK_SE21          DISP_BIT_IB01
+#define DISP_BITMASK_SE20          DISP_BIT_IB00
+/* DISP_HORZ_RAM_ADDR_POS_1_ADDR   Horizontal RAM Address Position (1) */
+#define DISP_BITMASK_HSA7          DISP_BIT_IB07
+#define DISP_BITMASK_HSA6          DISP_BIT_IB06
+#define DISP_BITMASK_HSA5          DISP_BIT_IB05
+#define DISP_BITMASK_HSA4          DISP_BIT_IB04
+#define DISP_BITMASK_HSA3          DISP_BIT_IB03
+#define DISP_BITMASK_HSA2          DISP_BIT_IB02
+#define DISP_BITMASK_HSA1          DISP_BIT_IB01
+#define DISP_BITMASK_HSA0          DISP_BIT_IB00
+/* DISP_HORZ_RAM_ADDR_POS_2_ADDR   Horizontal RAM Address Position (2) */
+#define DISP_BITMASK_HEA7          DISP_BIT_IB07
+#define DISP_BITMASK_HEA6          DISP_BIT_IB06
+#define DISP_BITMASK_HEA5          DISP_BIT_IB05
+#define DISP_BITMASK_HEA4          DISP_BIT_IB04
+#define DISP_BITMASK_HEA3          DISP_BIT_IB03
+#define DISP_BITMASK_HEA2          DISP_BIT_IB02
+#define DISP_BITMASK_HEA1          DISP_BIT_IB01
+#define DISP_BITMASK_HEA0          DISP_BIT_IB00
+/* DISP_VERT_RAM_ADDR_POS_1_ADDR   Vertical RAM Address Position (1) */
+#define DISP_BITMASK_VSA8          DISP_BIT_IB08
+#define DISP_BITMASK_VSA7          DISP_BIT_IB07
+#define DISP_BITMASK_VSA6          DISP_BIT_IB06
+#define DISP_BITMASK_VSA5          DISP_BIT_IB05
+#define DISP_BITMASK_VSA4          DISP_BIT_IB04
+#define DISP_BITMASK_VSA3          DISP_BIT_IB03
+#define DISP_BITMASK_VSA2          DISP_BIT_IB02
+#define DISP_BITMASK_VSA1          DISP_BIT_IB01
+#define DISP_BITMASK_VSA0          DISP_BIT_IB00
+/* DISP_VERT_RAM_ADDR_POS_2_ADDR   Vertical RAM Address Position (2) */
+#define DISP_BITMASK_VEA8          DISP_BIT_IB08
+#define DISP_BITMASK_VEA7          DISP_BIT_IB07
+#define DISP_BITMASK_VEA6          DISP_BIT_IB06
+#define DISP_BITMASK_VEA5          DISP_BIT_IB05
+#define DISP_BITMASK_VEA4          DISP_BIT_IB04
+#define DISP_BITMASK_VEA3          DISP_BIT_IB03
+#define DISP_BITMASK_VEA2          DISP_BIT_IB02
+#define DISP_BITMASK_VEA1          DISP_BIT_IB01
+#define DISP_BITMASK_VEA0          DISP_BIT_IB00
+static word disp_area_start_row;
+static word disp_area_end_row;
+static boolean disp_initialized = FALSE;
+/* For some reason the contrast set at init time is not good. Need to do
+* it again
+*/
+static boolean display_on = FALSE;
+
+static uint32 tmd20qvga_lcd_rev;
+uint16 tmd20qvga_panel_offset;
+
+#ifdef DISP_DEVICE_8BPP
+static word convert_8_to_16_tbl[256] = {
+	0x0000, 0x2000, 0x4000, 0x6000, 0x8000, 0xA000, 0xC000, 0xE000,
+	0x0100, 0x2100, 0x4100, 0x6100, 0x8100, 0xA100, 0xC100, 0xE100,
+	0x0200, 0x2200, 0x4200, 0x6200, 0x8200, 0xA200, 0xC200, 0xE200,
+	0x0300, 0x2300, 0x4300, 0x6300, 0x8300, 0xA300, 0xC300, 0xE300,
+	0x0400, 0x2400, 0x4400, 0x6400, 0x8400, 0xA400, 0xC400, 0xE400,
+	0x0500, 0x2500, 0x4500, 0x6500, 0x8500, 0xA500, 0xC500, 0xE500,
+	0x0600, 0x2600, 0x4600, 0x6600, 0x8600, 0xA600, 0xC600, 0xE600,
+	0x0700, 0x2700, 0x4700, 0x6700, 0x8700, 0xA700, 0xC700, 0xE700,
+	0x0008, 0x2008, 0x4008, 0x6008, 0x8008, 0xA008, 0xC008, 0xE008,
+	0x0108, 0x2108, 0x4108, 0x6108, 0x8108, 0xA108, 0xC108, 0xE108,
+	0x0208, 0x2208, 0x4208, 0x6208, 0x8208, 0xA208, 0xC208, 0xE208,
+	0x0308, 0x2308, 0x4308, 0x6308, 0x8308, 0xA308, 0xC308, 0xE308,
+	0x0408, 0x2408, 0x4408, 0x6408, 0x8408, 0xA408, 0xC408, 0xE408,
+	0x0508, 0x2508, 0x4508, 0x6508, 0x8508, 0xA508, 0xC508, 0xE508,
+	0x0608, 0x2608, 0x4608, 0x6608, 0x8608, 0xA608, 0xC608, 0xE608,
+	0x0708, 0x2708, 0x4708, 0x6708, 0x8708, 0xA708, 0xC708, 0xE708,
+	0x0010, 0x2010, 0x4010, 0x6010, 0x8010, 0xA010, 0xC010, 0xE010,
+	0x0110, 0x2110, 0x4110, 0x6110, 0x8110, 0xA110, 0xC110, 0xE110,
+	0x0210, 0x2210, 0x4210, 0x6210, 0x8210, 0xA210, 0xC210, 0xE210,
+	0x0310, 0x2310, 0x4310, 0x6310, 0x8310, 0xA310, 0xC310, 0xE310,
+	0x0410, 0x2410, 0x4410, 0x6410, 0x8410, 0xA410, 0xC410, 0xE410,
+	0x0510, 0x2510, 0x4510, 0x6510, 0x8510, 0xA510, 0xC510, 0xE510,
+	0x0610, 0x2610, 0x4610, 0x6610, 0x8610, 0xA610, 0xC610, 0xE610,
+	0x0710, 0x2710, 0x4710, 0x6710, 0x8710, 0xA710, 0xC710, 0xE710,
+	0x0018, 0x2018, 0x4018, 0x6018, 0x8018, 0xA018, 0xC018, 0xE018,
+	0x0118, 0x2118, 0x4118, 0x6118, 0x8118, 0xA118, 0xC118, 0xE118,
+	0x0218, 0x2218, 0x4218, 0x6218, 0x8218, 0xA218, 0xC218, 0xE218,
+	0x0318, 0x2318, 0x4318, 0x6318, 0x8318, 0xA318, 0xC318, 0xE318,
+	0x0418, 0x2418, 0x4418, 0x6418, 0x8418, 0xA418, 0xC418, 0xE418,
+	0x0518, 0x2518, 0x4518, 0x6518, 0x8518, 0xA518, 0xC518, 0xE518,
+	0x0618, 0x2618, 0x4618, 0x6618, 0x8618, 0xA618, 0xC618, 0xE618,
+	0x0718, 0x2718, 0x4718, 0x6718, 0x8718, 0xA718, 0xC718, 0xE718
+};
+#endif /* DISP_DEVICE_8BPP */
+
+static void tmd20qvga_disp_set_rect(int x, int y, int xres, int yres);
+static void tmd20qvga_disp_init(struct platform_device *pdev);
+static void tmd20qvga_disp_set_contrast(void);
+static void tmd20qvga_disp_set_display_area(word start_row, word end_row);
+static int tmd20qvga_disp_off(struct platform_device *pdev);
+static int tmd20qvga_disp_on(struct platform_device *pdev);
+static void tmd20qvga_set_revId(int);
+
+/* future use */
+void tmd20qvga_disp_clear_screen_area(word start_row, word end_row,
+				      word start_column, word end_column);
+
+static void tmd20qvga_set_revId(int id)
+{
+
+	tmd20qvga_lcd_rev = id;
+
+	if (tmd20qvga_lcd_rev == 1)
+		tmd20qvga_panel_offset = 0x10;
+	else
+		tmd20qvga_panel_offset = 0;
+}
+
+static void tmd20qvga_disp_init(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	if (disp_initialized)
+		return;
+
+	mfd = platform_get_drvdata(pdev);
+
+	DISP_CMD_PORT = mfd->cmd_port;
+	DISP_DATA_PORT = mfd->data_port;
+
+#ifdef TMD20QVGA_LCD_18BPP
+	tmd20qvga_set_revId(2);
+#else
+	tmd20qvga_set_revId(1);
+#endif
+
+	disp_initialized = TRUE;
+	tmd20qvga_disp_set_contrast();
+	tmd20qvga_disp_set_display_area(0, QVGA_HEIGHT - 1);
+}
+
+static void tmd20qvga_disp_set_rect(int x, int y, int xres, int yres)
+{
+	if (!disp_initialized)
+		return;
+
+	DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1);
+
+	DISP_CMD_OUT(DISP_CMD_RAMWR);
+}
+
+static void tmd20qvga_disp_set_display_area(word start_row, word end_row)
+{
+	word start_driving = start_row;
+	word end_driving = end_row;
+
+	if (!disp_initialized)
+		return;
+
+	/* Range checking
+	 */
+	if (end_driving >= QVGA_HEIGHT)
+		end_driving = QVGA_HEIGHT - 1;
+	if (start_driving > end_driving) {
+		/* Probably Backwards Switch */
+		start_driving = end_driving;
+		end_driving = start_row;	/* Has not changed */
+		if (end_driving >= QVGA_HEIGHT)
+			end_driving = QVGA_HEIGHT - 1;
+	}
+
+	if ((start_driving == disp_area_start_row)
+	    && (end_driving == disp_area_end_row))
+		return;
+
+	disp_area_start_row = start_driving;
+	disp_area_end_row = end_driving;
+
+	DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR,
+		       DISP_VAL_IF(start_driving & 0x100,
+				   DISP_BITMASK_SS18) |
+		       DISP_VAL_IF(start_driving & 0x080,
+				   DISP_BITMASK_SS17) |
+		       DISP_VAL_IF(start_driving & 0x040,
+				   DISP_BITMASK_SS16) |
+		       DISP_VAL_IF(start_driving & 0x020,
+				   DISP_BITMASK_SS15) |
+		       DISP_VAL_IF(start_driving & 0x010,
+				   DISP_BITMASK_SS14) |
+		       DISP_VAL_IF(start_driving & 0x008,
+				   DISP_BITMASK_SS13) |
+		       DISP_VAL_IF(start_driving & 0x004,
+				   DISP_BITMASK_SS12) |
+		       DISP_VAL_IF(start_driving & 0x002,
+				   DISP_BITMASK_SS11) |
+		       DISP_VAL_IF(start_driving & 0x001, DISP_BITMASK_SS10));
+
+	DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR,
+			DISP_VAL_IF(end_driving & 0x100, DISP_BITMASK_SE18) |
+			DISP_VAL_IF(end_driving & 0x080, DISP_BITMASK_SE17) |
+			DISP_VAL_IF(end_driving & 0x040, DISP_BITMASK_SE16) |
+			DISP_VAL_IF(end_driving & 0x020, DISP_BITMASK_SE15) |
+			DISP_VAL_IF(end_driving & 0x010, DISP_BITMASK_SE14) |
+			DISP_VAL_IF(end_driving & 0x008, DISP_BITMASK_SE13) |
+			DISP_VAL_IF(end_driving & 0x004, DISP_BITMASK_SE12) |
+			DISP_VAL_IF(end_driving & 0x002, DISP_BITMASK_SE11) |
+			DISP_VAL_IF(end_driving & 0x001, DISP_BITMASK_SE10));
+}
+
+static int tmd20qvga_disp_off(struct platform_device *pdev)
+{
+	if (!disp_initialized)
+		tmd20qvga_disp_init(pdev);
+
+	if (display_on) {
+		if (tmd20qvga_lcd_rev == 2) {
+			DISP_WRITE_OUT(DISP_POFF_LN_SETTING_ADDR, 0x000A);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xFFEE);
+			WAIT_MSEC(40);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xF812);
+			WAIT_MSEC(40);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xE811);
+			WAIT_MSEC(40);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xC011);
+			WAIT_MSEC(40);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x4011);
+			WAIT_MSEC(20);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0010);
+
+		} else {
+			DISP_WRITE_OUT(DISP_POFF_LN_SETTING_ADDR, 0x000F);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BFE);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
+			WAIT_MSEC(40);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BED);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
+			WAIT_MSEC(40);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x00CD);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
+			WAIT_MSEC(20);
+			DISP_WRITE_OUT(DISP_START_OSCILLATION_ADDR, 0x0);
+		}
+
+		DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0004);
+		DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0000);
+
+		display_on = FALSE;
+	}
+
+	return 0;
+}
+
+static int tmd20qvga_disp_on(struct platform_device *pdev)
+{
+	if (!disp_initialized)
+		tmd20qvga_disp_init(pdev);
+
+	if (!display_on) {
+		/* Deep Stand-by -> Stand-by */
+		DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR);
+		WAIT_MSEC(1);
+		DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR);
+		WAIT_MSEC(1);
+		DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR);
+		WAIT_MSEC(1);
+
+		/* OFF -> Deep Stan-By -> Stand-by */
+		/* let's change the state from "Stand-by" to "Sleep" */
+		DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0005);
+		WAIT_MSEC(1);
+
+		/* Sleep -> Displaying */
+		DISP_WRITE_OUT(DISP_START_OSCILLATION_ADDR, 0x0001);
+		DISP_WRITE_OUT(DISP_DRIVER_OUTPUT_CTL_ADDR, 0x0127);
+		DISP_WRITE_OUT(DISP_LCD_DRIVING_SIG_ADDR, 0x200);
+		/* fast write mode */
+		DISP_WRITE_OUT(DISP_ENTRY_MODE_ADDR, 0x0130);
+		if (tmd20qvga_lcd_rev == 2)
+			DISP_WRITE_OUT(DISP_TMD_700_ADDR, 0x0003);
+		/* back porch = 14 + front porch = 2 --> 16 lines */
+		if (tmd20qvga_lcd_rev == 2) {
+#ifdef TMD20QVGA_LCD_18BPP
+			/* 256k color */
+			DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x0000);
+#else
+			/* 65k color */
+			DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x4000);
+#endif
+			DISP_WRITE_OUT(DISP_DISPLAY_CTL_2_ADDR, 0x0302);
+		} else {
+#ifdef TMD20QVGA_LCD_18BPP
+			/* 256k color */
+			DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x0004);
+#else
+			/* 65k color */
+			DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x4004);
+#endif
+			DISP_WRITE_OUT(DISP_DISPLAY_CTL_2_ADDR, 0x020E);
+		}
+		/* 16 bit one transfer */
+		if (tmd20qvga_lcd_rev == 2) {
+			DISP_WRITE_OUT(DISP_EXT_DISPLAY_CTL_1_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_FRAME_CYCLE_CTL_ADDR, 0x0010);
+			DISP_WRITE_OUT(DISP_LTPS_CTL_1_ADDR, 0x0302);
+			DISP_WRITE_OUT(DISP_LTPS_CTL_2_ADDR, 0x0102);
+			DISP_WRITE_OUT(DISP_LTPS_CTL_3_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_TMD_015_ADDR, 0x2000);
+
+			DISP_WRITE_OUT(DISP_AMP_SETTING_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0304);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0403);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0101);
+			DISP_WRITE_OUT(DISP_TMD_305_ADDR, 0);
+
+			DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR, 0x013F);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_3_ADDR, 0x077D);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_4_ADDR, 0x0005);
+			DISP_WRITE_OUT(DISP_POWER_CTL_5_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_POWER_CTL_6_ADDR, 0x0015);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xC010);
+			WAIT_MSEC(1);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x0001);
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xFFFE);
+			WAIT_MSEC(60);
+		} else {
+			DISP_WRITE_OUT(DISP_EXT_DISPLAY_CTL_1_ADDR, 0x0001);
+			DISP_WRITE_OUT(DISP_FRAME_CYCLE_CTL_ADDR, 0x0010);
+			DISP_WRITE_OUT(DISP_LTPS_CTL_1_ADDR, 0x0301);
+			DISP_WRITE_OUT(DISP_LTPS_CTL_2_ADDR, 0x0001);
+			DISP_WRITE_OUT(DISP_LTPS_CTL_3_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_AMP_SETTING_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0507);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0405);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0607);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0502);
+			DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0301);
+			DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR, 0x013F);
+			DISP_WRITE_OUT(DISP_POWER_CTL_3_ADDR, 0x0795);
+
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0102);
+			WAIT_MSEC(1);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_4_ADDR, 0x0450);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0103);
+			WAIT_MSEC(1);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_5_ADDR, 0x0008);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0104);
+			WAIT_MSEC(1);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_6_ADDR, 0x0C00);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0105);
+			WAIT_MSEC(1);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_7_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0106);
+			WAIT_MSEC(1);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0801);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
+			WAIT_MSEC(1);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x001F);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0101);
+			WAIT_MSEC(60);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x009F);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0101);
+			WAIT_MSEC(10);
+
+			DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_1_ADDR, 0x0010);
+			DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_2_ADDR, 0x00FF);
+			DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_1_ADDR, 0x0000);
+			DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_2_ADDR, 0x013F);
+			/* RAM starts at address 0x10 */
+			DISP_WRITE_OUT(DISP_RAM_ADDR_SET_1_ADDR, 0x0010);
+			DISP_WRITE_OUT(DISP_RAM_ADDR_SET_2_ADDR, 0x0000);
+
+			/* lcd controller uses internal clock, not ext. vsync */
+			DISP_CMD_OUT(DISP_CMD_RAMWR);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0881);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
+			WAIT_MSEC(40);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BE1);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
+			WAIT_MSEC(40);
+
+			DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BFF);
+			DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100);
+		}
+		display_on = TRUE;
+	}
+
+	return 0;
+}
+
+static void tmd20qvga_disp_set_contrast(void)
+{
+#if (defined(TMD20QVGA_LCD_18BPP))
+
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403);
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0302);
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0403);
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303);
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0F07);
+
+#else
+	int newcontrast = 0x46;
+
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403);
+
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR,
+			DISP_VAL_IF(newcontrast & 0x0001, DISP_BITMASK_PKP20) |
+			DISP_VAL_IF(newcontrast & 0x0002, DISP_BITMASK_PKP21) |
+			DISP_VAL_IF(newcontrast & 0x0004, DISP_BITMASK_PKP22) |
+			DISP_VAL_IF(newcontrast & 0x0010, DISP_BITMASK_PKP30) |
+			DISP_VAL_IF(newcontrast & 0x0020, DISP_BITMASK_PKP31) |
+			DISP_VAL_IF(newcontrast & 0x0040, DISP_BITMASK_PKP32));
+
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR,
+			DISP_VAL_IF(newcontrast & 0x0010, DISP_BITMASK_PKP40) |
+			DISP_VAL_IF(newcontrast & 0x0020, DISP_BITMASK_PKP41) |
+			DISP_VAL_IF(newcontrast & 0x0040, DISP_BITMASK_PKP42) |
+			DISP_VAL_IF(newcontrast & 0x0001, DISP_BITMASK_PKP50) |
+			DISP_VAL_IF(newcontrast & 0x0002, DISP_BITMASK_PKP51) |
+			DISP_VAL_IF(newcontrast & 0x0004, DISP_BITMASK_PKP52));
+
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303);
+	DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0F07);
+
+#endif /* defined(TMD20QVGA_LCD_18BPP) */
+
+}	/* End disp_set_contrast */
+
+void tmd20qvga_disp_clear_screen_area
+    (word start_row, word end_row, word start_column, word end_column) {
+	int32 i;
+
+	/* Clear the display screen */
+	DISP_SET_RECT(start_row, end_row, start_column, end_column);
+	DISP_CMD_OUT(DISP_CMD_RAMWR);
+	i = (end_row - start_row + 1) * (end_column - start_column + 1);
+	for (; i > 0; i--)
+		DISP_DATA_OUT_16TO18BPP(0x0);
+}
+
+static int __init tmd20qvga_probe(struct platform_device *pdev)
+{
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = tmd20qvga_probe,
+	.driver = {
+		.name   = "ebi2_tmd_qvga",
+	},
+};
+
+static struct msm_fb_panel_data tmd20qvga_panel_data = {
+	.on = tmd20qvga_disp_on,
+	.off = tmd20qvga_disp_off,
+	.set_rect = tmd20qvga_disp_set_rect,
+};
+
+static struct platform_device this_device = {
+	.name   = "ebi2_tmd_qvga",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &tmd20qvga_panel_data,
+	}
+};
+
+static int __init tmd20qvga_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	ret = platform_driver_register(&this_driver);
+	if (!ret) {
+		pinfo = &tmd20qvga_panel_data.panel_info;
+		pinfo->xres = 240;
+		pinfo->yres = 320;
+		MSM_FB_SINGLE_MODE_PANEL(pinfo);
+		pinfo->type = EBI2_PANEL;
+		pinfo->pdest = DISPLAY_1;
+		pinfo->wait_cycle = 0x808000;
+#ifdef TMD20QVGA_LCD_18BPP
+		pinfo->bpp = 18;
+#else
+		pinfo->bpp = 16;
+#endif
+		pinfo->fb_num = 2;
+		pinfo->lcd.vsync_enable = TRUE;
+		pinfo->lcd.refx100 = 6000;
+		pinfo->lcd.v_back_porch = 16;
+		pinfo->lcd.v_front_porch = 4;
+		pinfo->lcd.v_pulse_width = 0;
+		pinfo->lcd.hw_vsync_mode = FALSE;
+		pinfo->lcd.vsync_notifier_period = 0;
+
+		ret = platform_device_register(&this_device);
+		if (ret)
+			platform_driver_unregister(&this_driver);
+	}
+
+	return ret;
+}
+
+module_init(tmd20qvga_init);
+
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
new file mode 100644
index 0000000..c0e9145
--- /dev/null
+++ b/drivers/video/msm/external_common.c
@@ -0,0 +1,2108 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/mutex.h>
+
+/* #define DEBUG */
+#define DEV_DBG_PREFIX "EXT_COMMON: "
+
+/* The start of the data block collection within the CEA Extension Version 3 */
+#define DBC_START_OFFSET 4
+
+#include "msm_fb.h"
+#include "hdmi_msm.h"
+#include "external_common.h"
+#include "mhl_api.h"
+
+#include "mdp.h"
+
+struct external_common_state_type *external_common_state;
+EXPORT_SYMBOL(external_common_state);
+DEFINE_MUTEX(external_common_state_hpd_mutex);
+EXPORT_SYMBOL(external_common_state_hpd_mutex);
+
+
+static int atoi(const char *name)
+{
+	int val = 0;
+
+	for (;; name++) {
+		switch (*name) {
+		case '0' ... '9':
+			val = 10*val+(*name-'0');
+			break;
+		default:
+			return val;
+		}
+	}
+}
+
+#ifdef DEBUG_EDID
+/*
+ * Block 0 - 1920x1080p, 1360x768p
+ * Block 1 - 1280x720p, 1920x540i, 720x480p
+ */
+const char edid_blk0[0x100] = {
+0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x4C, 0x2D, 0x03, 0x05, 0x00,
+0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78, 0x0A, 0xEE,
+0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54, 0xBD, 0xEF, 0x80, 0x71,
+0x4F, 0x81, 0x00, 0x81, 0x40, 0x81, 0x80, 0x95, 0x00, 0x95, 0x0F, 0xB3, 0x00,
+0xA9, 0x40, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, 0x45,
+0x00, 0xA0, 0x5A, 0x00, 0x00, 0x00, 0x1E, 0x66, 0x21, 0x50, 0xB0, 0x51, 0x00,
+0x1B, 0x30, 0x40, 0x70, 0x36, 0x00, 0xA0, 0x5A, 0x00, 0x00, 0x00, 0x1E, 0x00,
+0x00, 0x00, 0xFD, 0x00, 0x18, 0x4B, 0x1A, 0x51, 0x17, 0x00, 0x0A, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x53, 0x41, 0x4D, 0x53,
+0x55, 0x4E, 0x47, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x8F};
+
+const char edid_blk1[0x100] = {
+0x02, 0x03, 0x1E, 0xF1, 0x46, 0x90, 0x04, 0x05, 0x03, 0x20, 0x22, 0x23, 0x09,
+0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0xE2, 0x00, 0x0F, 0x67, 0x03, 0x0C, 0x00,
+0x10, 0x00, 0xB8, 0x2D, 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20, 0x6E,
+0x28, 0x55, 0x00, 0xA0, 0x5A, 0x00, 0x00, 0x00, 0x1E, 0x01, 0x1D, 0x80, 0x18,
+0x71, 0x1C, 0x16, 0x20, 0x58, 0x2C, 0x25, 0x00, 0xA0, 0x5A, 0x00, 0x00, 0x00,
+0x9E, 0x8C, 0x0A, 0xD0, 0x8A, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x3E, 0x96, 0x00,
+0xA0, 0x5A, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF};
+#endif /* DEBUG_EDID */
+
+#ifdef CONFIG_FB_MSM_HDMI_MHL
+#define DMA_E_BASE 0xB0000
+void mdp_vid_quant_set(void)
+{
+	if ((external_common_state->video_resolution == \
+		HDMI_VFRMT_720x480p60_4_3) || \
+		(external_common_state->video_resolution == \
+		HDMI_VFRMT_720x480p60_16_9)) {
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x70, 0x00EB0010);
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x74, 0x00EB0010);
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x78, 0x00EB0010);
+	} else {
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x70, 0x00FF0000);
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x74, 0x00FF0000);
+		MDP_OUTP(MDP_BASE + DMA_E_BASE + 0x78, 0x00FF0000);
+	}
+}
+#else
+void mdp_vid_quant_set(void)
+{
+	/*
+	 * Support for quantization to be added
+	 * only when MHL support is included.
+	 */
+}
+#endif
+
+const char *video_format_2string(uint32 format)
+{
+	switch (format) {
+	default:
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+	case HDMI_VFRMT_640x480p60_4_3:    return " 640x 480 p60  4/3";
+	case HDMI_VFRMT_720x480p60_4_3:    return " 720x 480 p60  4/3";
+	case HDMI_VFRMT_720x480p60_16_9:   return " 720x 480 p60 16/9";
+	case HDMI_VFRMT_1280x720p60_16_9:  return "1280x 720 p60 16/9";
+	case HDMI_VFRMT_1920x1080i60_16_9: return "1920x1080 i60 16/9";
+	case HDMI_VFRMT_1440x480i60_4_3:   return "1440x 480 i60  4/3";
+	case HDMI_VFRMT_1440x480i60_16_9:  return "1440x 480 i60 16/9";
+	case HDMI_VFRMT_1440x240p60_4_3:   return "1440x 240 p60  4/3";
+	case HDMI_VFRMT_1440x240p60_16_9:  return "1440x 240 p60 16/9";
+	case HDMI_VFRMT_2880x480i60_4_3:   return "2880x 480 i60  4/3";
+	case HDMI_VFRMT_2880x480i60_16_9:  return "2880x 480 i60 16/9";
+	case HDMI_VFRMT_2880x240p60_4_3:   return "2880x 240 p60  4/3";
+	case HDMI_VFRMT_2880x240p60_16_9:  return "2880x 240 p60 16/9";
+	case HDMI_VFRMT_1440x480p60_4_3:   return "1440x 480 p60  4/3";
+	case HDMI_VFRMT_1440x480p60_16_9:  return "1440x 480 p60 16/9";
+	case HDMI_VFRMT_1920x1080p60_16_9: return "1920x1080 p60 16/9";
+	case HDMI_VFRMT_720x576p50_4_3:    return " 720x 576 p50  4/3";
+	case HDMI_VFRMT_720x576p50_16_9:   return " 720x 576 p50 16/9";
+	case HDMI_VFRMT_1280x720p50_16_9:  return "1280x 720 p50 16/9";
+	case HDMI_VFRMT_1920x1080i50_16_9: return "1920x1080 i50 16/9";
+	case HDMI_VFRMT_1440x576i50_4_3:   return "1440x 576 i50  4/3";
+	case HDMI_VFRMT_1440x576i50_16_9:  return "1440x 576 i50 16/9";
+	case HDMI_VFRMT_1440x288p50_4_3:   return "1440x 288 p50  4/3";
+	case HDMI_VFRMT_1440x288p50_16_9:  return "1440x 288 p50 16/9";
+	case HDMI_VFRMT_2880x576i50_4_3:   return "2880x 576 i50  4/3";
+	case HDMI_VFRMT_2880x576i50_16_9:  return "2880x 576 i50 16/9";
+	case HDMI_VFRMT_2880x288p50_4_3:   return "2880x 288 p50  4/3";
+	case HDMI_VFRMT_2880x288p50_16_9:  return "2880x 288 p50 16/9";
+	case HDMI_VFRMT_1440x576p50_4_3:   return "1440x 576 p50  4/3";
+	case HDMI_VFRMT_1440x576p50_16_9:  return "1440x 576 p50 16/9";
+	case HDMI_VFRMT_1920x1080p50_16_9: return "1920x1080 p50 16/9";
+	case HDMI_VFRMT_1920x1080p24_16_9: return "1920x1080 p24 16/9";
+	case HDMI_VFRMT_1920x1080p25_16_9: return "1920x1080 p25 16/9";
+	case HDMI_VFRMT_1920x1080p30_16_9: return "1920x1080 p30 16/9";
+	case HDMI_VFRMT_2880x480p60_4_3:   return "2880x 480 p60  4/3";
+	case HDMI_VFRMT_2880x480p60_16_9:  return "2880x 480 p60 16/9";
+	case HDMI_VFRMT_2880x576p50_4_3:   return "2880x 576 p50  4/3";
+	case HDMI_VFRMT_2880x576p50_16_9:  return "2880x 576 p50 16/9";
+	case HDMI_VFRMT_1920x1250i50_16_9: return "1920x1250 i50 16/9";
+	case HDMI_VFRMT_1920x1080i100_16_9:return "1920x1080 i100 16/9";
+	case HDMI_VFRMT_1280x720p100_16_9: return "1280x 720 p100 16/9";
+	case HDMI_VFRMT_720x576p100_4_3:   return " 720x 576 p100  4/3";
+	case HDMI_VFRMT_720x576p100_16_9:  return " 720x 576 p100 16/9";
+	case HDMI_VFRMT_1440x576i100_4_3:  return "1440x 576 i100  4/3";
+	case HDMI_VFRMT_1440x576i100_16_9: return "1440x 576 i100 16/9";
+	case HDMI_VFRMT_1920x1080i120_16_9:return "1920x1080 i120 16/9";
+	case HDMI_VFRMT_1280x720p120_16_9: return "1280x 720 p120 16/9";
+	case HDMI_VFRMT_720x480p120_4_3:   return " 720x 480 p120  4/3";
+	case HDMI_VFRMT_720x480p120_16_9:  return " 720x 480 p120 16/9";
+	case HDMI_VFRMT_1440x480i120_4_3:  return "1440x 480 i120  4/3";
+	case HDMI_VFRMT_1440x480i120_16_9: return "1440x 480 i120 16/9";
+	case HDMI_VFRMT_720x576p200_4_3:   return " 720x 576 p200  4/3";
+	case HDMI_VFRMT_720x576p200_16_9:  return " 720x 576 p200 16/9";
+	case HDMI_VFRMT_1440x576i200_4_3:  return "1440x 576 i200  4/3";
+	case HDMI_VFRMT_1440x576i200_16_9: return "1440x 576 i200 16/9";
+	case HDMI_VFRMT_720x480p240_4_3:   return " 720x 480 p240  4/3";
+	case HDMI_VFRMT_720x480p240_16_9:  return " 720x 480 p240 16/9";
+	case HDMI_VFRMT_1440x480i240_4_3:  return "1440x 480 i240  4/3";
+	case HDMI_VFRMT_1440x480i240_16_9: return "1440x 480 i240 16/9";
+#elif defined(CONFIG_FB_MSM_TVOUT)
+	case TVOUT_VFRMT_NTSC_M_720x480i:     return "NTSC_M_720x480i";
+	case TVOUT_VFRMT_NTSC_J_720x480i:     return "NTSC_J_720x480i";
+	case TVOUT_VFRMT_PAL_BDGHIN_720x576i: return "PAL_BDGHIN_720x576i";
+	case TVOUT_VFRMT_PAL_M_720x480i:      return "PAL_M_720x480i";
+	case TVOUT_VFRMT_PAL_N_720x480i:      return "PAL_N_720x480i";
+#endif
+
+	}
+}
+EXPORT_SYMBOL(video_format_2string);
+
+static ssize_t external_common_rda_video_mode_str(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%s\n",
+		video_format_2string(external_common_state->video_resolution));
+	DEV_DBG("%s: '%s'\n", __func__,
+		video_format_2string(external_common_state->video_resolution));
+	return ret;
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+struct hdmi_disp_mode_timing_type
+	hdmi_common_supported_video_mode_lut[HDMI_VFRMT_MAX] = {
+	HDMI_SETTINGS_640x480p60_4_3,
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x240p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x240p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480i60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480i60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x240p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x240p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x288p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x288p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576i50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576i50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x288p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x288p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p24_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p25_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p30_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1250i50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i100_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p100_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p100_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p100_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i100_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i100_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i120_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p120_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p120_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p120_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i120_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i120_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p200_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p200_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i200_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i200_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_16_9),
+};
+EXPORT_SYMBOL(hdmi_common_supported_video_mode_lut);
+
+struct hdmi_disp_mode_timing_type
+	hdmi_mhl_supported_video_mode_lut[HDMI_VFRMT_MAX] = {
+	HDMI_SETTINGS_640x480p60_4_3,
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_16_9),
+	HDMI_SETTINGS_1280x720p60_16_9,
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x240p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x240p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480i60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480i60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x240p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x240p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x288p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x288p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576i50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576i50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x288p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x288p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p50_16_9),
+	HDMI_SETTINGS_1920x1080p24_16_9,
+	HDMI_SETTINGS_1920x1080p25_16_9,
+	HDMI_SETTINGS_1920x1080p30_16_9,
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1250i50_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i100_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p100_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p100_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p100_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i100_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i100_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i120_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p120_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p120_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p120_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i120_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i120_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p200_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p200_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i200_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i200_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_16_9),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_4_3),
+	VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_16_9),
+};
+EXPORT_SYMBOL(hdmi_mhl_supported_video_mode_lut);
+
+static ssize_t hdmi_common_rda_edid_modes(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = 0;
+	int i;
+
+	buf[0] = 0;
+	if (external_common_state->disp_mode_list.num_of_elements) {
+		uint32 *video_mode = external_common_state->disp_mode_list
+			.disp_mode_list;
+		for (i = 0; i < external_common_state->disp_mode_list
+			.num_of_elements; ++i) {
+			if (ret > 0)
+				ret += snprintf(buf+ret, PAGE_SIZE-ret, ",%d",
+					*video_mode++ + 1);
+			else
+				ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
+					*video_mode++ + 1);
+		}
+	} else
+		ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
+			external_common_state->video_resolution+1);
+
+	DEV_DBG("%s: '%s'\n", __func__, buf);
+	ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n");
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_edid_physical_address(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->physical_address);
+
+	DEV_DBG("%s: '%d'\n", __func__,
+			external_common_state->physical_address);
+	return ret;
+}
+
+
+static ssize_t hdmi_common_rda_edid_scan_info(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d, %d, %d\n",
+		external_common_state->pt_scan_info,
+		external_common_state->it_scan_info,
+		external_common_state->ce_scan_info);
+	DEV_DBG("%s: '%s'\n", __func__, buf);
+	return ret;
+}
+
+static ssize_t hdmi_common_wta_vendor_name(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	uint8 *s = (uint8 *) buf;
+	uint8 *d = external_common_state->spd_vendor_name;
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	ret = (ret > 8) ? 8 : ret;
+
+	memset(external_common_state->spd_vendor_name, 0, 8);
+	while (*s) {
+		if (*s & 0x60 && *s ^ 0x7f) {
+			*d = *s;
+		} else {
+			/* stop copying if control character found */
+			break;
+		}
+
+		if (++s > (uint8 *) (buf + ret))
+			break;
+
+		d++;
+	}
+
+	DEV_DBG("%s: '%s'\n", __func__,
+			external_common_state->spd_vendor_name);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_vendor_name(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%s\n",
+		external_common_state->spd_vendor_name);
+	DEV_DBG("%s: '%s'\n", __func__,
+			external_common_state->spd_vendor_name);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_wta_product_description(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	uint8 *s = (uint8 *) buf;
+	uint8 *d = external_common_state->spd_product_description;
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	ret = (ret > 16) ? 16 : ret;
+
+	memset(external_common_state->spd_product_description, 0, 16);
+	while (*s) {
+		if (*s & 0x60 && *s ^ 0x7f) {
+			*d = *s;
+		} else {
+			/* stop copying if control character found */
+			break;
+		}
+
+		if (++s > (uint8 *) (buf + ret))
+			break;
+
+		d++;
+	}
+
+	DEV_DBG("%s: '%s'\n", __func__,
+			external_common_state->spd_product_description);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_product_description(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%s\n",
+		external_common_state->spd_product_description);
+	DEV_DBG("%s: '%s'\n", __func__,
+			external_common_state->spd_product_description);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_edid_3d_modes(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = 0;
+	int i;
+	char buff_3d[128];
+
+	buf[0] = 0;
+	if (external_common_state->disp_mode_list.num_of_elements) {
+		uint32 *video_mode = external_common_state->disp_mode_list
+			.disp_mode_list;
+		uint32 *video_3d_mode = external_common_state->disp_mode_list
+			.disp_3d_mode_list;
+		for (i = 0; i < external_common_state->disp_mode_list
+			.num_of_elements; ++i) {
+			video_3d_format_2string(*video_3d_mode++, buff_3d);
+			if (ret > 0)
+				ret += snprintf(buf+ret, PAGE_SIZE-ret,
+					",%d=%s",
+					*video_mode++ + 1, buff_3d);
+			else
+				ret += snprintf(buf+ret, PAGE_SIZE-ret,
+					"%d=%s",
+					*video_mode++ + 1, buff_3d);
+		}
+	} else
+		ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
+			external_common_state->video_resolution+1);
+
+	DEV_DBG("%s: '%s'\n", __func__, buf);
+	ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n");
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_hdcp(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->hdcp_active);
+	DEV_DBG("%s: '%d'\n", __func__,
+		external_common_state->hdcp_active);
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_hpd(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret;
+	if (external_common_state->hpd_feature) {
+		ret = snprintf(buf, PAGE_SIZE, "%d\n",
+			external_common_state->hpd_feature_on);
+		DEV_DBG("%s: '%d'\n", __func__,
+			external_common_state->hpd_feature_on);
+	} else {
+		ret = snprintf(buf, PAGE_SIZE, "-1\n");
+		DEV_DBG("%s: 'not supported'\n", __func__);
+	}
+	return ret;
+}
+
+static ssize_t hdmi_common_wta_hpd(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	int hpd;
+	if (hdmi_prim_display)
+		hpd = 1;
+	else
+		hpd = atoi(buf);
+
+	if (external_common_state->hpd_feature) {
+		if (hpd == 0 && external_common_state->hpd_feature_on) {
+			external_common_state->hpd_feature(0);
+			external_common_state->hpd_feature_on = 0;
+			DEV_DBG("%s: '%d'\n", __func__,
+				external_common_state->hpd_feature_on);
+		} else if (hpd == 1 && !external_common_state->hpd_feature_on) {
+			external_common_state->hpd_feature(1);
+			external_common_state->hpd_feature_on = 1;
+			DEV_DBG("%s: '%d'\n", __func__,
+				external_common_state->hpd_feature_on);
+		} else {
+			DEV_DBG("%s: '%d' (unchanged)\n", __func__,
+				external_common_state->hpd_feature_on);
+		}
+	} else {
+		DEV_DBG("%s: 'not supported'\n", __func__);
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+/*
+ * This interface for CEC feature is defined to suit
+ * the current requirements. However, the actual functionality is
+ * added to accommodate different interfaces
+ */
+static ssize_t hdmi_msm_rda_cec(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	/* 0x028C CEC_CTRL */
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		(HDMI_INP(0x028C) & BIT(0)));
+	return ret;
+}
+
+static ssize_t hdmi_msm_wta_cec(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	int cec = atoi(buf);
+
+	if (cec != 0) {
+		mutex_lock(&hdmi_msm_state_mutex);
+		hdmi_msm_state->cec_enabled = true;
+		hdmi_msm_state->cec_logical_addr = 4;
+		mutex_unlock(&hdmi_msm_state_mutex);
+		hdmi_msm_cec_init();
+		hdmi_msm_cec_write_logical_addr(
+			hdmi_msm_state->cec_logical_addr);
+		DEV_DBG("CEC enabled\n");
+	} else {
+		mutex_lock(&hdmi_msm_state_mutex);
+		hdmi_msm_state->cec_enabled = false;
+		hdmi_msm_state->cec_logical_addr = 15;
+		mutex_unlock(&hdmi_msm_state_mutex);
+		hdmi_msm_cec_write_logical_addr(
+			hdmi_msm_state->cec_logical_addr);
+		/* 0x028C CEC_CTRL */
+		HDMI_OUTP(0x028C, 0);
+		DEV_DBG("CEC disabled\n");
+	}
+	return ret;
+}
+
+static ssize_t hdmi_msm_rda_cec_logical_addr(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	ssize_t ret;
+
+	mutex_lock(&hdmi_msm_state_mutex);
+	ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		hdmi_msm_state->cec_logical_addr);
+	mutex_unlock(&hdmi_msm_state_mutex);
+	return ret;
+}
+
+static ssize_t hdmi_msm_wta_cec_logical_addr(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+
+#ifdef DRVR_ONLY_CECT_NO_DAEMON
+	/*
+	 * Only for testing
+	 */
+	hdmi_msm_cec_one_touch_play();
+	return 0;
+#else
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	int logical_addr = atoi(buf);
+
+	if (logical_addr < 0 || logical_addr > 15)
+		return -EINVAL;
+
+	mutex_lock(&hdmi_msm_state_mutex);
+	hdmi_msm_state->cec_logical_addr = logical_addr;
+	mutex_unlock(&hdmi_msm_state_mutex);
+
+	hdmi_msm_cec_write_logical_addr(logical_addr);
+
+	return ret;
+#endif
+}
+
+static ssize_t hdmi_msm_rda_cec_frame(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->cec_queue_rd == hdmi_msm_state->cec_queue_wr
+	    && !hdmi_msm_state->cec_queue_full) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_ERR("CEC message queue is empty\n");
+		return -EBUSY;
+	}
+	memcpy(buf, hdmi_msm_state->cec_queue_rd++,
+		sizeof(struct hdmi_msm_cec_msg));
+	hdmi_msm_state->cec_queue_full = false;
+	if (hdmi_msm_state->cec_queue_rd == CEC_QUEUE_END)
+		hdmi_msm_state->cec_queue_rd = hdmi_msm_state->cec_queue_start;
+	mutex_unlock(&hdmi_msm_state_mutex);
+
+	return sizeof(struct hdmi_msm_cec_msg);
+}
+
+static ssize_t hdmi_msm_wta_cec_frame(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	int i;
+	int retry = ((struct hdmi_msm_cec_msg *) buf)->retransmit;
+
+	for (i = 0; i < RETRANSMIT_MAX_NUM; i++) {
+		hdmi_msm_cec_msg_send((struct hdmi_msm_cec_msg *) buf);
+		if (hdmi_msm_state->cec_frame_wr_status
+		    & CEC_STATUS_WR_ERROR && retry--) {
+			mutex_lock(&hdmi_msm_state_mutex);
+			if (hdmi_msm_state->fsm_reset_done)
+				retry++;
+			mutex_unlock(&hdmi_msm_state_mutex);
+			msleep(360);
+		} else
+			break;
+	}
+
+	if (hdmi_msm_state->cec_frame_wr_status & CEC_STATUS_WR_DONE)
+		return sizeof(struct hdmi_msm_cec_msg);
+	else
+		return -EINVAL;
+}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+
+static ssize_t hdmi_common_rda_3d_present(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->present_3d);
+	DEV_DBG("%s: '%d'\n", __func__,
+			external_common_state->present_3d);
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_hdcp_present(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->present_hdcp);
+	DEV_DBG("%s: '%d'\n", __func__,
+			external_common_state->present_hdcp);
+	return ret;
+}
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_3D
+static ssize_t hdmi_3d_rda_format_3d(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->format_3d);
+	DEV_DBG("%s: '%d'\n", __func__,
+		external_common_state->format_3d);
+	return ret;
+}
+
+static ssize_t hdmi_3d_wta_format_3d(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	int format_3d = atoi(buf);
+
+	if (format_3d >= 0 && format_3d <= 2) {
+		if (format_3d != external_common_state->format_3d) {
+			external_common_state->format_3d = format_3d;
+			if (external_common_state->switch_3d)
+				external_common_state->switch_3d(format_3d);
+			DEV_DBG("%s: '%d'\n", __func__,
+				external_common_state->format_3d);
+		} else {
+			DEV_DBG("%s: '%d' (unchanged)\n", __func__,
+				external_common_state->format_3d);
+		}
+	} else {
+		DEV_DBG("%s: '%d' (unknown)\n", __func__, format_3d);
+	}
+
+	return ret;
+}
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+static DEVICE_ATTR(cec, S_IRUGO | S_IWUSR,
+	hdmi_msm_rda_cec,
+	hdmi_msm_wta_cec);
+
+static DEVICE_ATTR(cec_logical_addr, S_IRUGO | S_IWUSR,
+	hdmi_msm_rda_cec_logical_addr,
+	hdmi_msm_wta_cec_logical_addr);
+
+static DEVICE_ATTR(cec_rd_frame, S_IRUGO,
+	hdmi_msm_rda_cec_frame,	NULL);
+
+static DEVICE_ATTR(cec_wr_frame, S_IWUSR,
+	NULL, hdmi_msm_wta_cec_frame);
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+
+
+static ssize_t external_common_rda_video_mode(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->video_resolution+1);
+	DEV_DBG("%s: '%d'\n", __func__,
+			external_common_state->video_resolution+1);
+	return ret;
+}
+
+static ssize_t external_common_wta_video_mode(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	uint32 video_mode;
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+	const struct hdmi_disp_mode_timing_type *disp_mode;
+#endif
+	mutex_lock(&external_common_state_hpd_mutex);
+	if (!external_common_state->hpd_state) {
+		mutex_unlock(&external_common_state_hpd_mutex);
+		DEV_INFO("%s: FAILED: display off or cable disconnected\n",
+			__func__);
+		return ret;
+	}
+	mutex_unlock(&external_common_state_hpd_mutex);
+
+	video_mode = atoi(buf)-1;
+	DEV_INFO("%s: video_mode is %d\n", __func__, video_mode);
+	kobject_uevent(external_common_state->uevent_kobj, KOBJ_OFFLINE);
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+	disp_mode = hdmi_common_get_supported_mode(video_mode);
+	if (!disp_mode) {
+		DEV_INFO("%s: FAILED: mode not supported (%d)\n",
+			__func__, video_mode);
+		return ret;
+	}
+	external_common_state->disp_mode_list.num_of_elements = 1;
+	external_common_state->disp_mode_list.disp_mode_list[0] = video_mode;
+#elif defined(CONFIG_FB_MSM_TVOUT)
+	external_common_state->video_resolution = video_mode;
+#endif
+	DEV_DBG("%s: 'mode=%d %s' successful (sending OFF/ONLINE)\n", __func__,
+		video_mode, video_format_2string(video_mode));
+	kobject_uevent(external_common_state->uevent_kobj, KOBJ_ONLINE);
+	return ret;
+}
+
+static ssize_t external_common_rda_connected(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret;
+	mutex_lock(&external_common_state_hpd_mutex);
+	ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->hpd_state);
+	DEV_DBG("%s: '%d'\n", __func__,
+		external_common_state->hpd_state);
+	mutex_unlock(&external_common_state_hpd_mutex);
+	return ret;
+}
+
+static ssize_t external_common_rda_hdmi_mode(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret;
+
+	ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		external_common_state->hdmi_sink);
+
+	DEV_DBG("%s: '%d'\n", __func__,
+		external_common_state->hdmi_sink);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_hdmi_primary(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		hdmi_prim_display);
+	DEV_DBG("%s: '%d'\n", __func__,	hdmi_prim_display);
+	return ret;
+}
+
+static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUGO,
+	external_common_rda_video_mode, external_common_wta_video_mode);
+static DEVICE_ATTR(video_mode_str, S_IRUGO, external_common_rda_video_mode_str,
+	NULL);
+static DEVICE_ATTR(connected, S_IRUGO, external_common_rda_connected, NULL);
+static DEVICE_ATTR(hdmi_mode, S_IRUGO, external_common_rda_hdmi_mode, NULL);
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+static DEVICE_ATTR(edid_modes, S_IRUGO, hdmi_common_rda_edid_modes, NULL);
+static DEVICE_ATTR(hpd, S_IRUGO | S_IWUGO, hdmi_common_rda_hpd,
+	hdmi_common_wta_hpd);
+static DEVICE_ATTR(hdcp, S_IRUGO, hdmi_common_rda_hdcp, NULL);
+static DEVICE_ATTR(pa, S_IRUGO,
+	hdmi_common_rda_edid_physical_address, NULL);
+static DEVICE_ATTR(scan_info, S_IRUGO,
+	hdmi_common_rda_edid_scan_info, NULL);
+static DEVICE_ATTR(vendor_name, S_IRUGO | S_IWUSR, hdmi_common_rda_vendor_name,
+	hdmi_common_wta_vendor_name);
+static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR,
+	hdmi_common_rda_product_description,
+	hdmi_common_wta_product_description);
+static DEVICE_ATTR(edid_3d_modes, S_IRUGO,
+	hdmi_common_rda_edid_3d_modes, NULL);
+static DEVICE_ATTR(3d_present, S_IRUGO, hdmi_common_rda_3d_present, NULL);
+static DEVICE_ATTR(hdcp_present, S_IRUGO, hdmi_common_rda_hdcp_present, NULL);
+#endif
+#ifdef CONFIG_FB_MSM_HDMI_3D
+static DEVICE_ATTR(format_3d, S_IRUGO | S_IWUGO, hdmi_3d_rda_format_3d,
+	hdmi_3d_wta_format_3d);
+#endif
+static DEVICE_ATTR(hdmi_primary, S_IRUGO, hdmi_common_rda_hdmi_primary, NULL);
+
+static struct attribute *external_common_fs_attrs[] = {
+	&dev_attr_video_mode.attr,
+	&dev_attr_video_mode_str.attr,
+	&dev_attr_connected.attr,
+	&dev_attr_hdmi_mode.attr,
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+	&dev_attr_edid_modes.attr,
+	&dev_attr_hdcp.attr,
+	&dev_attr_hpd.attr,
+	&dev_attr_pa.attr,
+	&dev_attr_scan_info.attr,
+	&dev_attr_vendor_name.attr,
+	&dev_attr_product_description.attr,
+	&dev_attr_edid_3d_modes.attr,
+	&dev_attr_3d_present.attr,
+	&dev_attr_hdcp_present.attr,
+#endif
+#ifdef CONFIG_FB_MSM_HDMI_3D
+	&dev_attr_format_3d.attr,
+#endif
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	&dev_attr_cec.attr,
+	&dev_attr_cec_logical_addr.attr,
+	&dev_attr_cec_rd_frame.attr,
+	&dev_attr_cec_wr_frame.attr,
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+	&dev_attr_hdmi_primary.attr,
+	NULL,
+};
+static struct attribute_group external_common_fs_attr_group = {
+	.attrs = external_common_fs_attrs,
+};
+
+/* create external interface kobject and initialize */
+int external_common_state_create(struct platform_device *pdev)
+{
+	int rc;
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+	if (!mfd) {
+		DEV_ERR("%s: mfd not found\n", __func__);
+		return -ENODEV;
+	}
+	if (!mfd->fbi) {
+		DEV_ERR("%s: mfd->fbi not found\n", __func__);
+		return -ENODEV;
+	}
+	if (!mfd->fbi->dev) {
+		DEV_ERR("%s: mfd->fbi->dev not found\n", __func__);
+		return -ENODEV;
+	}
+	rc = sysfs_create_group(&mfd->fbi->dev->kobj,
+		&external_common_fs_attr_group);
+	if (rc) {
+		DEV_ERR("%s: sysfs group creation failed, rc=%d\n", __func__,
+			rc);
+		return rc;
+	}
+	external_common_state->uevent_kobj = &mfd->fbi->dev->kobj;
+	DEV_ERR("%s: sysfs group %p\n", __func__,
+		external_common_state->uevent_kobj);
+
+	kobject_uevent(external_common_state->uevent_kobj, KOBJ_ADD);
+	DEV_DBG("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
+	return 0;
+}
+EXPORT_SYMBOL(external_common_state_create);
+
+void external_common_state_remove(void)
+{
+	if (external_common_state->uevent_kobj)
+		sysfs_remove_group(external_common_state->uevent_kobj,
+			&external_common_fs_attr_group);
+	external_common_state->uevent_kobj = NULL;
+}
+EXPORT_SYMBOL(external_common_state_remove);
+
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+/* The Logic ID for HDMI TX Core. Currently only support 1 HDMI TX Core. */
+struct hdmi_edid_video_mode_property_type {
+	uint32	video_code;
+	uint32	active_h;
+	uint32	active_v;
+	boolean	interlaced;
+	uint32	total_h;
+	uint32	total_blank_h;
+	uint32	total_v;
+	uint32	total_blank_v;
+	/* Must divide by 1000 to get the frequency */
+	uint32	freq_h;
+	/* Must divide by 1000 to get the frequency */
+	uint32	freq_v;
+	/* Must divide by 1000 to get the frequency */
+	uint32	pixel_freq;
+	/* Must divide by 1000 to get the frequency */
+	uint32	refresh_rate;
+	boolean	aspect_ratio_4_3;
+};
+
+/* LUT is sorted from lowest Active H to highest Active H - ease searching */
+static struct hdmi_edid_video_mode_property_type
+	hdmi_edid_disp_mode_lut[] = {
+
+	/* All 640 H Active */
+	{HDMI_VFRMT_640x480p60_4_3, 640, 480, FALSE, 800, 160, 525, 45,
+	 31465, 59940, 25175, 59940, TRUE},
+	{HDMI_VFRMT_640x480p60_4_3, 640, 480, FALSE, 800, 160, 525, 45,
+	 31500, 60000, 25200, 60000, TRUE},
+
+	/* All 720 H Active */
+	{HDMI_VFRMT_720x576p50_4_3,  720, 576, FALSE, 864, 144, 625, 49,
+	 31250, 50000, 27000, 50000, TRUE},
+	{HDMI_VFRMT_720x480p60_4_3,  720, 480, FALSE, 858, 138, 525, 45,
+	 31465, 59940, 27000, 59940, TRUE},
+	{HDMI_VFRMT_720x480p60_4_3,  720, 480, FALSE, 858, 138, 525, 45,
+	 31500, 60000, 27030, 60000, TRUE},
+	{HDMI_VFRMT_720x576p100_4_3, 720, 576, FALSE, 864, 144, 625, 49,
+	 62500, 100000, 54000, 100000, TRUE},
+	{HDMI_VFRMT_720x480p120_4_3, 720, 480, FALSE, 858, 138, 525, 45,
+	 62937, 119880, 54000, 119880, TRUE},
+	{HDMI_VFRMT_720x480p120_4_3, 720, 480, FALSE, 858, 138, 525, 45,
+	 63000, 120000, 54054, 120000, TRUE},
+	{HDMI_VFRMT_720x576p200_4_3, 720, 576, FALSE, 864, 144, 625, 49,
+	 125000, 200000, 108000, 200000, TRUE},
+	{HDMI_VFRMT_720x480p240_4_3, 720, 480, FALSE, 858, 138, 525, 45,
+	 125874, 239760, 108000, 239000, TRUE},
+	{HDMI_VFRMT_720x480p240_4_3, 720, 480, FALSE, 858, 138, 525, 45,
+	 126000, 240000, 108108, 240000, TRUE},
+
+	/* All 1280 H Active */
+	{HDMI_VFRMT_1280x720p50_16_9,  1280, 720, FALSE, 1980, 700, 750, 30,
+	 37500, 50000, 74250, 50000, FALSE},
+	{HDMI_VFRMT_1280x720p60_16_9,  1280, 720, FALSE, 1650, 370, 750, 30,
+	 44955, 59940, 74176, 59940, FALSE},
+	{HDMI_VFRMT_1280x720p60_16_9,  1280, 720, FALSE, 1650, 370, 750, 30,
+	 45000, 60000, 74250, 60000, FALSE},
+	{HDMI_VFRMT_1280x720p100_16_9, 1280, 720, FALSE, 1980, 700, 750, 30,
+	 75000, 100000, 148500, 100000, FALSE},
+	{HDMI_VFRMT_1280x720p120_16_9, 1280, 720, FALSE, 1650, 370, 750, 30,
+	 89909, 119880, 148352, 119880, FALSE},
+	{HDMI_VFRMT_1280x720p120_16_9, 1280, 720, FALSE, 1650, 370, 750, 30,
+	 90000, 120000, 148500, 120000, FALSE},
+
+	/* All 1440 H Active */
+	{HDMI_VFRMT_1440x576i50_4_3, 1440, 576, TRUE,  1728, 288, 625, 24,
+	 15625, 50000, 27000, 50000, TRUE},
+	{HDMI_VFRMT_720x288p50_4_3,  1440, 288, FALSE, 1728, 288, 312, 24,
+	 15625, 50080, 27000, 50000, TRUE},
+	{HDMI_VFRMT_720x288p50_4_3,  1440, 288, FALSE, 1728, 288, 313, 25,
+	 15625, 49920, 27000, 50000, TRUE},
+	{HDMI_VFRMT_720x288p50_4_3,  1440, 288, FALSE, 1728, 288, 314, 26,
+	 15625, 49761, 27000, 50000, TRUE},
+	{HDMI_VFRMT_1440x576p50_4_3, 1440, 576, FALSE, 1728, 288, 625, 49,
+	 31250, 50000, 54000, 50000, TRUE},
+	{HDMI_VFRMT_1440x480i60_4_3, 1440, 480, TRUE,  1716, 276, 525, 22,
+	 15734, 59940, 27000, 59940, TRUE},
+	{HDMI_VFRMT_1440x240p60_4_3, 1440, 240, FALSE, 1716, 276, 262, 22,
+	 15734, 60054, 27000, 59940, TRUE},
+	{HDMI_VFRMT_1440x240p60_4_3, 1440, 240, FALSE, 1716, 276, 263, 23,
+	 15734, 59826, 27000, 59940, TRUE},
+	{HDMI_VFRMT_1440x480p60_4_3, 1440, 480, FALSE, 1716, 276, 525, 45,
+	 31469, 59940, 54000, 59940, TRUE},
+	{HDMI_VFRMT_1440x480i60_4_3, 1440, 480, TRUE,  1716, 276, 525, 22,
+	 15750, 60000, 27027, 60000, TRUE},
+	{HDMI_VFRMT_1440x240p60_4_3, 1440, 240, FALSE, 1716, 276, 262, 22,
+	 15750, 60115, 27027, 60000, TRUE},
+	{HDMI_VFRMT_1440x240p60_4_3, 1440, 240, FALSE, 1716, 276, 263, 23,
+	 15750, 59886, 27027, 60000, TRUE},
+	{HDMI_VFRMT_1440x480p60_4_3, 1440, 480, FALSE, 1716, 276, 525, 45,
+	 31500, 60000, 54054, 60000, TRUE},
+	{HDMI_VFRMT_1440x576i100_4_3, 1440, 576, TRUE,  1728, 288, 625, 24,
+	 31250, 100000, 54000, 100000, TRUE},
+	{HDMI_VFRMT_1440x480i120_4_3, 1440, 480, TRUE,  1716, 276, 525, 22,
+	 31469, 119880, 54000, 119880, TRUE},
+	{HDMI_VFRMT_1440x480i120_4_3, 1440, 480, TRUE,  1716, 276, 525, 22,
+	 31500, 120000, 54054, 120000, TRUE},
+	{HDMI_VFRMT_1440x576i200_4_3, 1440, 576, TRUE,  1728, 288, 625, 24,
+	 62500, 200000, 108000, 200000, TRUE},
+	{HDMI_VFRMT_1440x480i240_4_3, 1440, 480, TRUE,  1716, 276, 525, 22,
+	 62937, 239760, 108000, 239000, TRUE},
+	{HDMI_VFRMT_1440x480i240_4_3, 1440, 480, TRUE,  1716, 276, 525, 22,
+	 63000, 240000, 108108, 240000, TRUE},
+
+	/* All 1920 H Active */
+	{HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, FALSE, 2200, 280, 1125,
+	 45, 67433, 59940, 148352, 59940, FALSE},
+	{HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, TRUE,  2200, 280, 1125,
+	 45, 67500, 60000, 148500, 60000, FALSE},
+	{HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, FALSE, 2640, 720, 1125,
+	 45, 56250, 50000, 148500, 50000, FALSE},
+	{HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, FALSE, 2750, 830, 1125,
+	 45, 26973, 23976, 74176, 24000, FALSE},
+	{HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, FALSE, 2750, 830, 1125,
+	 45, 27000, 24000, 74250, 24000, FALSE},
+	{HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, FALSE, 2640, 720, 1125,
+	 45, 28125, 25000, 74250, 25000, FALSE},
+	{HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, FALSE, 2200, 280, 1125,
+	 45, 33716, 29970, 74176, 30000, FALSE},
+	{HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, FALSE, 2200, 280, 1125,
+	 45, 33750, 30000, 74250, 30000, FALSE},
+	{HDMI_VFRMT_1920x1080i50_16_9, 1920, 1080, TRUE,  2304, 384, 1250,
+	 85, 31250, 50000, 72000, 50000, FALSE},
+	{HDMI_VFRMT_1920x1080i60_16_9, 1920, 1080, TRUE,  2200, 280, 1125,
+	 22, 33716, 59940, 74176, 59940, FALSE},
+	{HDMI_VFRMT_1920x1080i60_16_9, 1920, 1080, TRUE,  2200, 280, 1125,
+	 22, 33750, 60000, 74250, 60000, FALSE},
+	{HDMI_VFRMT_1920x1080i100_16_9, 1920, 1080, TRUE,  2640, 720, 1125,
+	 22, 56250, 100000, 148500, 100000, FALSE},
+	{HDMI_VFRMT_1920x1080i120_16_9, 1920, 1080, TRUE,  2200, 280, 1125,
+	 22, 67432, 119880, 148352, 119980, FALSE},
+	{HDMI_VFRMT_1920x1080i120_16_9, 1920, 1080, TRUE,  2200, 280, 1125,
+	 22, 67500, 120000, 148500, 120000, FALSE},
+
+	/* All 2880 H Active */
+	{HDMI_VFRMT_2880x576i50_4_3, 2880, 576, TRUE,  3456, 576, 625, 24,
+	 15625, 50000, 54000, 50000, TRUE},
+	{HDMI_VFRMT_2880x288p50_4_3, 2880, 576, FALSE, 3456, 576, 312, 24,
+	 15625, 50080, 54000, 50000, TRUE},
+	{HDMI_VFRMT_2880x288p50_4_3, 2880, 576, FALSE, 3456, 576, 313, 25,
+	 15625, 49920, 54000, 50000, TRUE},
+	{HDMI_VFRMT_2880x288p50_4_3, 2880, 576, FALSE, 3456, 576, 314, 26,
+	 15625, 49761, 54000, 50000, TRUE},
+	{HDMI_VFRMT_2880x576p50_4_3, 2880, 576, FALSE, 3456, 576, 625, 49,
+	 31250, 50000, 108000, 50000, TRUE},
+	{HDMI_VFRMT_2880x480i60_4_3, 2880, 480, TRUE,  3432, 552, 525, 22,
+	 15734, 59940, 54000, 59940, TRUE},
+	{HDMI_VFRMT_2880x240p60_4_3, 2880, 480, FALSE, 3432, 552, 262, 22,
+	 15734, 60054, 54000, 59940, TRUE},
+	{HDMI_VFRMT_2880x240p60_4_3, 2880, 480, FALSE, 3432, 552, 263, 23,
+	 15734, 59940, 54000, 59940, TRUE},
+	{HDMI_VFRMT_2880x480p60_4_3, 2880, 480, FALSE, 3432, 552, 525, 45,
+	 31469, 59940, 108000, 59940, TRUE},
+	{HDMI_VFRMT_2880x480i60_4_3, 2880, 480, TRUE,  3432, 552, 525, 22,
+	 15750, 60000, 54054, 60000, TRUE},
+	{HDMI_VFRMT_2880x240p60_4_3, 2880, 240, FALSE, 3432, 552, 262, 22,
+	 15750, 60115, 54054, 60000, TRUE},
+	{HDMI_VFRMT_2880x240p60_4_3, 2880, 240, FALSE, 3432, 552, 262, 23,
+	 15750, 59886, 54054, 60000, TRUE},
+	{HDMI_VFRMT_2880x480p60_4_3, 2880, 480, FALSE, 3432, 552, 525, 45,
+	 31500, 60000, 108108, 60000, TRUE},
+};
+
+static const uint8 *hdmi_edid_find_block(const uint8 *in_buf,
+		uint32 start_offset, uint8 type, uint8 *len)
+{
+	/* the start of data block collection, start of Video Data Block */
+	uint32 offset = start_offset;
+	uint32 end_dbc_offset = in_buf[2];
+
+	*len = 0;
+
+	/*edid buffer 1, byte 2 being 4 means no non-DTD/Data block collection
+	  present.
+	  edid buffer 1, byte 2 being 0 menas no non-DTD/DATA block collection
+	  present and no DTD data present.*/
+	if ((end_dbc_offset == 0) || (end_dbc_offset == 4)) {
+		DEV_WARN("EDID: no DTD or non-DTD data present\n");
+		return NULL;
+	}
+	while (offset < end_dbc_offset) {
+		uint8 block_len = in_buf[offset] & 0x1F;
+		if ((in_buf[offset] >> 5) == type) {
+			*len = block_len;
+			DEV_DBG("EDID: block=%d found @ %d with length=%d\n",
+				type, offset, block_len);
+			return in_buf+offset;
+		}
+		offset += 1 + block_len;
+	}
+	DEV_WARN("EDID: type=%d block not found in EDID block\n", type);
+	return NULL;
+}
+
+static void hdmi_edid_extract_vendor_id(const uint8 *in_buf,
+	char *vendor_id)
+{
+	uint32 id_codes = ((uint32)in_buf[8] << 8) + in_buf[9];
+
+	vendor_id[0] = 'A' - 1 + ((id_codes >> 10) & 0x1F);
+	vendor_id[1] = 'A' - 1 + ((id_codes >> 5) & 0x1F);
+	vendor_id[2] = 'A' - 1 + (id_codes & 0x1F);
+	vendor_id[3] = 0;
+}
+
+static uint32 hdmi_edid_extract_ieee_reg_id(const uint8 *in_buf)
+{
+	uint8 len;
+	const uint8 *vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 3,
+			&len);
+
+	if (vsd == NULL)
+		return 0;
+
+	DEV_DBG("EDID: VSD PhyAddr=%04x, MaxTMDS=%dMHz\n",
+		((uint32)vsd[4] << 8) + (uint32)vsd[5], (uint32)vsd[7] * 5);
+	external_common_state->physical_address =
+		((uint16)vsd[4] << 8) + (uint16)vsd[5];
+	return ((uint32)vsd[3] << 16) + ((uint32)vsd[2] << 8) + (uint32)vsd[1];
+}
+
+#define HDMI_VSDB_3D_DATA_OFFSET(vsd) \
+	(!((vsd)[8] & BIT(7)) ? 9 : (!((vsd)[8] & BIT(6)) ? 11 : 13))
+
+static void hdmi_edid_extract_3d_present(const uint8 *in_buf)
+{
+	uint8 len, offset;
+	const uint8 *vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 3,
+			&len);
+
+	external_common_state->present_3d = 0;
+	if (vsd == NULL || len < 9) {
+		DEV_DBG("EDID[3D]: block-id 3 not found or not long enough\n");
+		return;
+	}
+
+	offset = HDMI_VSDB_3D_DATA_OFFSET(vsd);
+	DEV_DBG("EDID: 3D present @ %d = %02x\n", offset, vsd[offset]);
+	if (vsd[offset] >> 7) { /* 3D format indication present */
+		DEV_INFO("EDID: 3D present, 3D-len=%d\n", vsd[offset+1] & 0x1F);
+		external_common_state->present_3d = 1;
+	}
+}
+
+
+static void hdmi_edid_extract_latency_fields(const uint8 *in_buf)
+{
+	uint8 len;
+	const uint8 *vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 3,
+			&len);
+
+	if (vsd == NULL || len < 12 || !(vsd[8] & BIT(7))) {
+		external_common_state->video_latency = (uint16)-1;
+		external_common_state->audio_latency = (uint16)-1;
+		DEV_DBG("EDID: No audio/video latency present\n");
+	} else {
+		external_common_state->video_latency = vsd[9];
+		external_common_state->audio_latency = vsd[10];
+		DEV_DBG("EDID: video-latency=%04x, audio-latency=%04x\n",
+			external_common_state->video_latency,
+			external_common_state->audio_latency);
+	}
+}
+
+static void hdmi_edid_extract_speaker_allocation_data(const uint8 *in_buf)
+{
+	uint8 len;
+	const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 4,
+			&len);
+
+	if (sad == NULL)
+		return;
+
+	external_common_state->speaker_allocation_block = sad[1];
+	DEV_DBG("EDID: speaker allocation data SP byte = %08x %s%s%s%s%s%s%s\n",
+		sad[1],
+		(sad[1] & BIT(0)) ? "FL/FR," : "",
+		(sad[1] & BIT(1)) ? "LFE," : "",
+		(sad[1] & BIT(2)) ? "FC," : "",
+		(sad[1] & BIT(3)) ? "RL/RR," : "",
+		(sad[1] & BIT(4)) ? "RC," : "",
+		(sad[1] & BIT(5)) ? "FLC/FRC," : "",
+		(sad[1] & BIT(6)) ? "RLC/RRC," : "");
+}
+
+static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf)
+{
+	uint8 len;
+	const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 1,
+			&len);
+	uint32 *adb = external_common_state->audio_data_blocks;
+
+	if (sad == NULL)
+		return;
+
+	external_common_state->audio_data_block_cnt = 0;
+	while (len >= 3 && external_common_state->audio_data_block_cnt < 16) {
+		DEV_DBG("EDID: Audio Data Block=<ch=%d, format=%d "
+			"sampling=0x%02x bit-depth=0x%02x>\n",
+			(sad[1] & 0x7)+1, sad[1] >> 3, sad[2], sad[3]);
+		*adb++ = (uint32)sad[1] + ((uint32)sad[2] << 8)
+			+ ((uint32)sad[2] << 16);
+		++external_common_state->audio_data_block_cnt;
+		len -= 3;
+		sad += 3;
+	}
+}
+
+static void hdmi_edid_extract_extended_data_blocks(const uint8 *in_buf)
+{
+	uint8 len = 0;
+	uint32 start_offset = DBC_START_OFFSET;
+
+	/* A Tage code of 7 identifies extended data blocks */
+	uint8 const *etag = hdmi_edid_find_block(in_buf, start_offset, 7, &len);
+
+	while (etag != NULL) {
+		/* The extended data block should at least be 2 bytes long */
+		if (len < 2) {
+			DEV_DBG("EDID: Found an extended data block of length"
+				"less than 2 bytes. Ignoring ...\n");
+		} else {
+			/*
+			 * The second byte of the extended data block has the
+			 * extended tag code
+			 */
+			switch (etag[1]) {
+			case 0:
+				/* Video Capability Data Block */
+				DEV_DBG("EDID: VCDB=%02X %02X\n", etag[1],
+						etag[2]);
+
+				/*
+				 * Check if the sink specifies underscan
+				 * support for:
+				 * BIT 5: preferred video format
+				 * BIT 3: IT video format
+				 * BIT 1: CE video format
+				 */
+				external_common_state->pt_scan_info = (etag[2] &
+							(BIT(4) | BIT(5))) >> 4;
+				external_common_state->it_scan_info = (etag[2] &
+							(BIT(3) | BIT(2))) >> 2;
+				external_common_state->ce_scan_info = etag[2] &
+							(BIT(1) | BIT(0));
+				DEV_DBG("EDID: Scan Information (pt|it|ce): "
+					"(%d|%d|%d)",
+					external_common_state->pt_scan_info,
+					external_common_state->it_scan_info,
+					external_common_state->ce_scan_info);
+				break;
+			default:
+				DEV_DBG("EDID: Extend Tag Code %d not"
+						"supported\n", etag[1]);
+				break;
+			}
+		}
+
+		/* There could be more that one extended data block */
+		start_offset = etag - in_buf + len + 1;
+		etag = hdmi_edid_find_block(in_buf, start_offset, 7, &len);
+	}
+}
+
+static void hdmi_edid_detail_desc(const uint8 *data_buf, uint32 *disp_mode)
+{
+	boolean	aspect_ratio_4_3    = FALSE;
+	boolean	interlaced          = FALSE;
+	uint32	active_h            = 0;
+	uint32	active_v            = 0;
+	uint32	blank_h             = 0;
+	uint32	blank_v             = 0;
+	uint32	ndx                 = 0;
+	uint32	max_num_of_elements = 0;
+	uint32	img_size_h          = 0;
+	uint32	img_size_v          = 0;
+
+	/* See VESA Spec */
+	/* EDID_TIMING_DESC_UPPER_H_NIBBLE[0x4]: Relative Offset to the EDID
+	 *   detailed timing descriptors - Upper 4 bit for each H active/blank
+	 *   field */
+	/* EDID_TIMING_DESC_H_ACTIVE[0x2]: Relative Offset to the EDID detailed
+	 *   timing descriptors - H active */
+	active_h = ((((uint32)data_buf[0x4] >> 0x4) & 0xF) << 8)
+		| data_buf[0x2];
+
+	/* EDID_TIMING_DESC_H_BLANK[0x3]: Relative Offset to the EDID detailed
+	 *   timing descriptors - H blank */
+	blank_h = (((uint32)data_buf[0x4] & 0xF) << 8)
+		| data_buf[0x3];
+
+	/* EDID_TIMING_DESC_UPPER_V_NIBBLE[0x7]: Relative Offset to the EDID
+	 *   detailed timing descriptors - Upper 4 bit for each V active/blank
+	 *   field */
+	/* EDID_TIMING_DESC_V_ACTIVE[0x5]: Relative Offset to the EDID detailed
+	 *   timing descriptors - V active */
+	active_v = ((((uint32)data_buf[0x7] >> 0x4) & 0xF) << 8)
+		| data_buf[0x5];
+
+	/* EDID_TIMING_DESC_V_BLANK[0x6]: Relative Offset to the EDID detailed
+	 *   timing descriptors - V blank */
+	blank_v = (((uint32)data_buf[0x7] & 0xF) << 8)
+		| data_buf[0x6];
+
+	/* EDID_TIMING_DESC_IMAGE_SIZE_UPPER_NIBBLE[0xE]: Relative Offset to the
+	 *   EDID detailed timing descriptors - Image Size upper nibble
+	 *   V and H */
+	/* EDID_TIMING_DESC_H_IMAGE_SIZE[0xC]: Relative Offset to the EDID
+	 *   detailed timing descriptors - H image size */
+	/* EDID_TIMING_DESC_V_IMAGE_SIZE[0xD]: Relative Offset to the EDID
+	 *   detailed timing descriptors - V image size */
+	img_size_h = ((((uint32)data_buf[0xE] >> 0x4) & 0xF) << 8)
+		| data_buf[0xC];
+	img_size_v = (((uint32)data_buf[0xE] & 0xF) << 8)
+		| data_buf[0xD];
+
+	/*
+	 * aspect ratio as 4:3 if within specificed range , rathaer than being
+	 * absolute value
+	 */
+	aspect_ratio_4_3 = (abs(img_size_h * 3 - img_size_v * 4) < 5) ? 1 : 0;
+
+	max_num_of_elements  = sizeof(hdmi_edid_disp_mode_lut)
+		/ sizeof(*hdmi_edid_disp_mode_lut);
+
+	/* EDID_TIMING_DESC_INTERLACE[0x11:7]: Relative Offset to the EDID
+	 *   detailed timing descriptors - Interlace flag */
+	DEV_DBG("Interlaced mode byte data_buf[0x11]=[%x]\n", data_buf[0x11]);
+	/*
+	 * CEA 861-D: interlaced bit is bit[7] of byte[0x11]
+	 */
+	interlaced = (data_buf[0x11] & 0x80) >> 7;
+
+	DEV_DBG("%s: A[%ux%u] B[%ux%u] V[%ux%u] %s\n", __func__,
+		active_h, active_v, blank_h, blank_v, img_size_h, img_size_v,
+		interlaced ? "i" : "p");
+
+	*disp_mode = HDMI_VFRMT_FORCE_32BIT;
+	while (ndx < max_num_of_elements) {
+		const struct hdmi_edid_video_mode_property_type *edid =
+			hdmi_edid_disp_mode_lut+ndx;
+
+		if ((interlaced    == edid->interlaced)    &&
+			(active_h  == edid->active_h)      &&
+			(blank_h   == edid->total_blank_h) &&
+			(blank_v   == edid->total_blank_v) &&
+			((active_v == edid->active_v) ||
+			 (active_v == (edid->active_v + 1)))
+		) {
+			if (edid->aspect_ratio_4_3 && !aspect_ratio_4_3)
+				/* Aspect ratio 16:9 */
+				*disp_mode = edid->video_code + 1;
+			else
+				/* Aspect ratio 4:3 */
+				*disp_mode = edid->video_code;
+
+			DEV_DBG("%s: mode found:%d\n", __func__, *disp_mode);
+			break;
+		}
+		++ndx;
+	}
+	if (ndx == max_num_of_elements)
+		DEV_INFO("%s: *no mode* found\n", __func__);
+}
+
+static void add_supported_video_format(
+	struct hdmi_disp_mode_list_type *disp_mode_list,
+	uint32 video_format)
+{
+	const struct hdmi_disp_mode_timing_type *timing =
+		hdmi_common_get_supported_mode(video_format);
+	boolean supported = timing != NULL;
+
+	if (video_format >= HDMI_VFRMT_MAX)
+		return;
+
+	DEV_DBG("EDID: format: %d [%s], %s\n",
+		video_format, video_format_2string(video_format),
+		supported ? "Supported" : "Not-Supported");
+	if (supported) {
+		if (mhl_is_connected()) {
+			const struct hdmi_disp_mode_timing_type *mhl_timing =
+				hdmi_mhl_get_supported_mode(video_format);
+			boolean mhl_supported = mhl_timing != NULL;
+			DEV_DBG("EDID: format: %d [%s], %s by MHL\n",
+			video_format, video_format_2string(video_format),
+				mhl_supported ? "Supported" : "Not-Supported");
+			if (mhl_supported)
+				disp_mode_list->disp_mode_list[
+			disp_mode_list->num_of_elements++] = video_format;
+		} else
+			disp_mode_list->disp_mode_list[
+			disp_mode_list->num_of_elements++] = video_format;
+	}
+}
+
+const char *single_video_3d_format_2string(uint32 format)
+{
+	switch (format) {
+	case TOP_AND_BOTTOM: return "TAB";
+	case FRAME_PACKING: return "FP";
+	case SIDE_BY_SIDE_HALF: return "SSH";
+	}
+	return "";
+}
+
+ssize_t video_3d_format_2string(uint32 format, char *buf)
+{
+	ssize_t ret, len = 0;
+	ret = snprintf(buf, PAGE_SIZE, "%s",
+		single_video_3d_format_2string(format & FRAME_PACKING));
+	len += ret;
+
+	if (len && (format & TOP_AND_BOTTOM))
+		ret = snprintf(buf + len, PAGE_SIZE, ":%s",
+			single_video_3d_format_2string(
+				format & TOP_AND_BOTTOM));
+	else
+		ret = snprintf(buf + len, PAGE_SIZE, "%s",
+			single_video_3d_format_2string(
+				format & TOP_AND_BOTTOM));
+	len += ret;
+
+	if (len && (format & SIDE_BY_SIDE_HALF))
+		ret = snprintf(buf + len, PAGE_SIZE, ":%s",
+			single_video_3d_format_2string(
+				format & SIDE_BY_SIDE_HALF));
+	else
+		ret = snprintf(buf + len, PAGE_SIZE, "%s",
+			single_video_3d_format_2string(
+				format & SIDE_BY_SIDE_HALF));
+	len += ret;
+
+	return len;
+}
+
+static void add_supported_3d_format(
+	struct hdmi_disp_mode_list_type *disp_mode_list,
+	uint32 video_format,
+	uint32 video_3d_format)
+{
+	char string[128];
+	boolean added = FALSE;
+	int i;
+	for (i = 0; i < disp_mode_list->num_of_elements; ++i) {
+		if (disp_mode_list->disp_mode_list[i] == video_format) {
+			disp_mode_list->disp_3d_mode_list[i] |=
+				video_3d_format;
+			added = TRUE;
+			break;
+		}
+	}
+	video_3d_format_2string(video_3d_format, string);
+	DEV_DBG("EDID[3D]: format: %d [%s], %s %s\n",
+		video_format, video_format_2string(video_format),
+		string, added ? "added" : "NOT added");
+}
+
+static void hdmi_edid_get_display_vsd_3d_mode(const uint8 *data_buf,
+	struct hdmi_disp_mode_list_type *disp_mode_list,
+	uint32 num_og_cea_blocks)
+{
+	uint8 len, offset, present_multi_3d, hdmi_vic_len, hdmi_3d_len;
+	uint16 structure_all, structure_mask;
+	const uint8 *vsd = num_og_cea_blocks ?
+		hdmi_edid_find_block(data_buf+0x80, DBC_START_OFFSET,
+				3, &len) : NULL;
+	int i;
+
+	offset = HDMI_VSDB_3D_DATA_OFFSET(vsd);
+	present_multi_3d = (vsd[offset] & 0x60) >> 5;
+
+	offset += 1;
+	hdmi_vic_len = (vsd[offset] >> 5) & 0x7;
+	hdmi_3d_len = vsd[offset] & 0x1F;
+	DEV_DBG("EDID[3D]: HDMI_VIC_LEN = %d, HDMI_3D_LEN = %d\n",
+		hdmi_vic_len, hdmi_3d_len);
+
+	offset += (hdmi_vic_len + 1);
+	if (present_multi_3d == 1 || present_multi_3d == 2) {
+		DEV_DBG("EDID[3D]: multi 3D present (%d)\n", present_multi_3d);
+		/* 3d_structure_all */
+		structure_all = (vsd[offset] << 8) | vsd[offset + 1];
+		offset += 2;
+		hdmi_3d_len -= 2;
+		if (present_multi_3d == 2) {
+			/* 3d_structure_mask */
+			structure_mask = (vsd[offset] << 8) | vsd[offset + 1];
+			offset += 2;
+			hdmi_3d_len -= 2;
+		} else
+			structure_mask = 0xffff;
+
+		i = 0;
+		while (i < 16) {
+			if (i >= disp_mode_list->disp_multi_3d_mode_list_cnt)
+				break;
+
+			if (!(structure_mask & BIT(i))) {
+				++i;
+				continue;
+			}
+
+			/* BIT0: FRAME PACKING */
+			if (structure_all & BIT(0))
+				add_supported_3d_format(disp_mode_list,
+					disp_mode_list->
+						disp_multi_3d_mode_list[i],
+					FRAME_PACKING);
+
+			/* BIT6: TOP AND BOTTOM */
+			if (structure_all & BIT(6))
+				add_supported_3d_format(disp_mode_list,
+					disp_mode_list->
+						disp_multi_3d_mode_list[i],
+					TOP_AND_BOTTOM);
+
+			/* BIT8: SIDE BY SIDE HALF */
+			if (structure_all & BIT(8))
+				add_supported_3d_format(disp_mode_list,
+					disp_mode_list->
+						disp_multi_3d_mode_list[i],
+					SIDE_BY_SIDE_HALF);
+
+			++i;
+		}
+	}
+
+	i = 0;
+	while (hdmi_3d_len > 0) {
+		DEV_DBG("EDID[3D]: 3D_Structure_%d @ %d: %02x\n",
+			i + 1, offset, vsd[offset]);
+
+		if ((vsd[offset] >> 4) >=
+			disp_mode_list->disp_multi_3d_mode_list_cnt) {
+			if ((vsd[offset] & 0x0F) >= 8) {
+				offset += 1;
+				hdmi_3d_len -= 1;
+				DEV_DBG("EDID[3D]: 3D_Detail_%d @ %d: %02x\n",
+					i + 1, offset, vsd[offset]);
+			}
+			i += 1;
+			offset += 1;
+			hdmi_3d_len -= 1;
+			continue;
+		}
+
+		switch (vsd[offset] & 0x0F) {
+		case 0:
+			/* 0000b: FRAME PACKING */
+			add_supported_3d_format(disp_mode_list,
+				disp_mode_list->disp_multi_3d_mode_list
+					[vsd[offset] >> 4],
+				FRAME_PACKING);
+			break;
+		case 6:
+			/* 0110b: TOP AND BOTTOM */
+			add_supported_3d_format(disp_mode_list,
+				disp_mode_list->disp_multi_3d_mode_list
+					[vsd[offset] >> 4],
+				TOP_AND_BOTTOM);
+			break;
+		case 8:
+			/* 1000b: SIDE BY SIDE HALF */
+			add_supported_3d_format(disp_mode_list,
+				disp_mode_list->disp_multi_3d_mode_list
+					[vsd[offset] >> 4],
+				SIDE_BY_SIDE_HALF);
+			break;
+		}
+		if ((vsd[offset] & 0x0F) >= 8) {
+			offset += 1;
+			hdmi_3d_len -= 1;
+			DEV_DBG("EDID[3D]: 3D_Detail_%d @ %d: %02x\n",
+				i + 1, offset, vsd[offset]);
+		}
+		i += 1;
+		offset += 1;
+		hdmi_3d_len -= 1;
+	}
+}
+
+static void hdmi_edid_get_display_mode(const uint8 *data_buf,
+	struct hdmi_disp_mode_list_type *disp_mode_list,
+	uint32 num_og_cea_blocks)
+{
+	uint8 i			= 0;
+	uint32 video_format	= HDMI_VFRMT_640x480p60_4_3;
+	boolean has480p		= FALSE;
+	uint8 len;
+	const uint8 *edid_blk0 = &data_buf[0x0];
+	const uint8 *edid_blk1 = &data_buf[0x80];
+	const uint8 *svd = num_og_cea_blocks ?
+		hdmi_edid_find_block(data_buf+0x80, DBC_START_OFFSET,
+				2, &len) : NULL;
+	boolean has60hz_mode	= FALSE;
+	boolean has50hz_mode	= FALSE;
+
+
+	disp_mode_list->num_of_elements = 0;
+	disp_mode_list->disp_multi_3d_mode_list_cnt = 0;
+	if (svd != NULL) {
+		++svd;
+		for (i = 0; i < len; ++i, ++svd) {
+			/* Subtract 1 because it is zero based in the driver,
+			 * while the Video identification code is 1 based in the
+			 * CEA_861D spec */
+			video_format = (*svd & 0x7F) - 1;
+			add_supported_video_format(disp_mode_list,
+				video_format);
+			/* Make a note of the preferred video format */
+			if (i == 0) {
+				external_common_state->preferred_video_format =
+					video_format;
+			}
+			if (i < 16) {
+				disp_mode_list->disp_multi_3d_mode_list[i]
+					= video_format;
+				disp_mode_list->disp_multi_3d_mode_list_cnt++;
+			}
+
+			if (video_format <= HDMI_VFRMT_1920x1080p60_16_9 ||
+				video_format == HDMI_VFRMT_2880x480p60_4_3 ||
+				video_format == HDMI_VFRMT_2880x480p60_16_9)
+				has60hz_mode = TRUE;
+
+			if ((video_format >= HDMI_VFRMT_720x576p50_4_3 &&
+				video_format <= HDMI_VFRMT_1920x1080p50_16_9) ||
+				video_format == HDMI_VFRMT_2880x576p50_4_3 ||
+				video_format == HDMI_VFRMT_2880x576p50_16_9 ||
+				video_format == HDMI_VFRMT_1920x1250i50_16_9)
+				has50hz_mode = TRUE;
+			if (video_format == HDMI_VFRMT_640x480p60_4_3)
+				has480p = TRUE;
+		}
+	} else if (!num_og_cea_blocks) {
+		/* Detailed timing descriptors */
+		uint32 desc_offset = 0;
+		/* Maximum 4 timing descriptor in block 0 - No CEA
+		 * extension in this case */
+		/* EDID_FIRST_TIMING_DESC[0x36] - 1st detailed timing
+		 *   descriptor */
+		/* EDID_DETAIL_TIMING_DESC_BLCK_SZ[0x12] - Each detailed timing
+		 *   descriptor has block size of 18 */
+		while (4 > i && 0 != edid_blk0[0x36+desc_offset]) {
+			hdmi_edid_detail_desc(edid_blk0+0x36+desc_offset,
+				&video_format);
+			DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n",
+				__func__, __LINE__,
+				video_format_2string(video_format));
+			add_supported_video_format(disp_mode_list,
+				video_format);
+			if (video_format == HDMI_VFRMT_640x480p60_4_3)
+				has480p = TRUE;
+			/* Make a note of the preferred video format */
+			if (i == 0) {
+				external_common_state->preferred_video_format =
+					video_format;
+			}
+			desc_offset += 0x12;
+			++i;
+		}
+	} else if (1 == num_og_cea_blocks) {
+		uint32 desc_offset = 0;
+
+		/*
+		 * Read from both block 0 and block 1
+		 * Read EDID block[0] as above
+		 */
+		while (4 > i && 0 != edid_blk0[0x36+desc_offset]) {
+			hdmi_edid_detail_desc(edid_blk0+0x36+desc_offset,
+				&video_format);
+			DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n",
+				__func__, __LINE__,
+				video_format_2string(video_format));
+			add_supported_video_format(disp_mode_list,
+				video_format);
+			if (video_format == HDMI_VFRMT_640x480p60_4_3)
+				has480p = TRUE;
+			/* Make a note of the preferred video format */
+			if (i == 0) {
+				external_common_state->preferred_video_format =
+					video_format;
+			}
+			desc_offset += 0x12;
+			++i;
+		}
+
+		/* Parse block 1 - CEA extension byte offset of first
+		 * detailed timing generation - offset is relevant to
+		 * the offset of block 1 */
+
+		/* EDID_CEA_EXTENSION_FIRST_DESC[0x82]: Offset to CEA
+		 * extension first timing desc - indicate the offset of
+		 * the first detailed timing descriptor */
+		 /* EDID_BLOCK_SIZE = 0x80  Each page size in the EDID ROM */
+		desc_offset = edid_blk1[0x02];
+		while (0 != edid_blk1[desc_offset]) {
+			hdmi_edid_detail_desc(edid_blk1+desc_offset,
+				&video_format);
+			DEV_DBG("[%s:%d] Block-1 Adding vid fmt = [%s]\n",
+				__func__, __LINE__,
+				video_format_2string(video_format));
+			add_supported_video_format(disp_mode_list,
+				video_format);
+			if (video_format == HDMI_VFRMT_640x480p60_4_3)
+				has480p = TRUE;
+			/* Make a note of the preferred video format */
+			if (i == 0) {
+				external_common_state->preferred_video_format =
+					video_format;
+			}
+			desc_offset += 0x12;
+			++i;
+		}
+	}
+
+	/* mandaroty 3d format */
+	if (external_common_state->present_3d) {
+		if (has60hz_mode) {
+			add_supported_3d_format(disp_mode_list,
+				HDMI_VFRMT_1920x1080p24_16_9,
+				FRAME_PACKING | TOP_AND_BOTTOM);
+			add_supported_3d_format(disp_mode_list,
+				HDMI_VFRMT_1280x720p60_16_9,
+				FRAME_PACKING | TOP_AND_BOTTOM);
+			add_supported_3d_format(disp_mode_list,
+				HDMI_VFRMT_1920x1080i60_16_9,
+				SIDE_BY_SIDE_HALF);
+		}
+		if (has50hz_mode) {
+			add_supported_3d_format(disp_mode_list,
+				HDMI_VFRMT_1920x1080p24_16_9,
+				FRAME_PACKING | TOP_AND_BOTTOM);
+			add_supported_3d_format(disp_mode_list,
+				HDMI_VFRMT_1280x720p50_16_9,
+				FRAME_PACKING | TOP_AND_BOTTOM);
+			add_supported_3d_format(disp_mode_list,
+				HDMI_VFRMT_1920x1080i50_16_9,
+				SIDE_BY_SIDE_HALF);
+		}
+
+		/* 3d format described in Vendor Specific Data */
+		hdmi_edid_get_display_vsd_3d_mode(data_buf, disp_mode_list,
+			num_og_cea_blocks);
+	}
+
+	if (!has480p)
+		/* Need to add default 640 by 480 timings, in case not described
+		 * in the EDID structure.
+		 * All DTV sink devices should support this mode */
+		add_supported_video_format(disp_mode_list,
+			HDMI_VFRMT_640x480p60_4_3);
+}
+
+static int hdmi_common_read_edid_block(int block, uint8 *edid_buf)
+{
+	uint32 ndx, check_sum, print_len;
+#ifdef DEBUG
+	const u8 *b = edid_buf;
+#endif
+	int status = external_common_state->read_edid_block(block, edid_buf);
+	if (status)
+		goto error;
+
+	/* Calculate checksum */
+	check_sum = 0;
+	for (ndx = 0; ndx < 0x80; ++ndx)
+		check_sum += edid_buf[ndx];
+
+	if (check_sum & 0xFF) {
+		DEV_ERR("%s: failed CHECKSUM (read:%x, expected:%x)\n",
+			__func__, (uint8)edid_buf[0x7F], (uint8)check_sum);
+#ifdef DEBUG
+		for (ndx = 0; ndx < 0x100; ndx += 16)
+			DEV_DBG("EDID[%02x-%02x] %02x %02x %02x %02x  "
+				"%02x %02x %02x %02x    %02x %02x %02x %02x  "
+				"%02x %02x %02x %02x\n", ndx, ndx+15,
+				b[ndx+0], b[ndx+1], b[ndx+2], b[ndx+3],
+				b[ndx+4], b[ndx+5], b[ndx+6], b[ndx+7],
+				b[ndx+8], b[ndx+9], b[ndx+10], b[ndx+11],
+				b[ndx+12], b[ndx+13], b[ndx+14], b[ndx+15]);
+#endif
+		status = -EPROTO;
+		goto error;
+	}
+	print_len = 0x80;
+	for (ndx = 0; ndx < print_len; ndx += 16)
+		DEV_DBG("EDID[%02x-%02x] %02x %02x %02x %02x  "
+			"%02x %02x %02x %02x    %02x %02x %02x %02x  "
+			"%02x %02x %02x %02x\n", ndx, ndx+15,
+			b[ndx+0], b[ndx+1], b[ndx+2], b[ndx+3],
+			b[ndx+4], b[ndx+5], b[ndx+6], b[ndx+7],
+			b[ndx+8], b[ndx+9], b[ndx+10], b[ndx+11],
+			b[ndx+12], b[ndx+13], b[ndx+14], b[ndx+15]);
+
+
+error:
+	return status;
+}
+
+static boolean check_edid_header(const uint8 *edid_buf)
+{
+	return (edid_buf[0] == 0x00) && (edid_buf[1] == 0xff)
+		&& (edid_buf[2] == 0xff) && (edid_buf[3] == 0xff)
+		&& (edid_buf[4] == 0xff) && (edid_buf[5] == 0xff)
+		&& (edid_buf[6] == 0xff) && (edid_buf[7] == 0x00);
+}
+
+int hdmi_common_read_edid(void)
+{
+	int status = 0;
+	uint32 cea_extension_ver = 0;
+	uint32 num_og_cea_blocks  = 0;
+	uint32 ieee_reg_id = 0;
+	uint32 i = 1;
+	char vendor_id[5];
+	/* EDID_BLOCK_SIZE[0x80] Each page size in the EDID ROM */
+	uint8 edid_buf[0x80 * 4];
+
+	external_common_state->pt_scan_info = 0;
+	external_common_state->it_scan_info = 0;
+	external_common_state->ce_scan_info = 0;
+	external_common_state->preferred_video_format = 0;
+	external_common_state->present_3d = 0;
+	memset(&external_common_state->disp_mode_list, 0,
+		sizeof(external_common_state->disp_mode_list));
+	memset(edid_buf, 0, sizeof(edid_buf));
+
+	status = hdmi_common_read_edid_block(0, edid_buf);
+	if (status || !check_edid_header(edid_buf)) {
+		if (!status)
+			status = -EPROTO;
+		DEV_ERR("%s: edid read block(0) failed: %d "
+			"[%02x%02x%02x%02x%02x%02x%02x%02x]\n", __func__,
+			status,
+			edid_buf[0], edid_buf[1], edid_buf[2], edid_buf[3],
+			edid_buf[4], edid_buf[5], edid_buf[6], edid_buf[7]);
+		goto error;
+	}
+	hdmi_edid_extract_vendor_id(edid_buf, vendor_id);
+
+	/* EDID_CEA_EXTENSION_FLAG[0x7E] - CEC extension byte */
+	num_og_cea_blocks = edid_buf[0x7E];
+
+	DEV_DBG("[JSR] (%s): No. of CEA blocks is  [%u]\n", __func__,
+		num_og_cea_blocks);
+	/* Find out any CEA extension blocks following block 0 */
+	switch (num_og_cea_blocks) {
+	case 0: /* No CEA extension */
+		external_common_state->hdmi_sink = false;
+		DEV_DBG("HDMI DVI mode: %s\n",
+			external_common_state->hdmi_sink ? "no" : "yes");
+		break;
+	case 1: /* Read block 1 */
+		status = hdmi_common_read_edid_block(1, &edid_buf[0x80]);
+		if (status) {
+			DEV_ERR("%s: ddc read block(1) failed: %d\n", __func__,
+				status);
+			goto error;
+		}
+		if (edid_buf[0x80] != 2)
+			num_og_cea_blocks = 0;
+		if (num_og_cea_blocks) {
+			ieee_reg_id =
+				hdmi_edid_extract_ieee_reg_id(edid_buf+0x80);
+			if (ieee_reg_id == 0x0c03)
+				external_common_state->hdmi_sink = TRUE ;
+			else
+				external_common_state->hdmi_sink = FALSE ;
+			hdmi_edid_extract_latency_fields(edid_buf+0x80);
+			hdmi_edid_extract_speaker_allocation_data(
+				edid_buf+0x80);
+			hdmi_edid_extract_audio_data_blocks(edid_buf+0x80);
+			hdmi_edid_extract_3d_present(edid_buf+0x80);
+			hdmi_edid_extract_extended_data_blocks(edid_buf+0x80);
+		}
+		break;
+	case 2:
+	case 3:
+	case 4:
+		for (i = 1; i <= num_og_cea_blocks; i++) {
+			if (!(i % 2)) {
+					status = hdmi_common_read_edid_block(i,
+								edid_buf+0x00);
+					if (status) {
+						DEV_ERR("%s: ddc read block(%d)"
+						"failed: %d\n", __func__, i,
+							status);
+						goto error;
+					}
+			} else {
+				status = hdmi_common_read_edid_block(i,
+							edid_buf+0x80);
+				if (status) {
+					DEV_ERR("%s: ddc read block(%d)"
+					"failed:%d\n", __func__, i,
+						status);
+					goto error;
+				}
+			}
+		}
+		break;
+	default:
+		DEV_ERR("%s: ddc read failed, not supported multi-blocks: %d\n",
+			__func__, num_og_cea_blocks);
+		status = -EPROTO;
+		goto error;
+	}
+
+	if (num_og_cea_blocks) {
+		/* EDID_CEA_EXTENSION_VERSION[0x81]: Offset to CEA extension
+		 * version number - v1,v2,v3 (v1 is seldom, v2 is obsolete,
+		 * v3 most common) */
+		cea_extension_ver = edid_buf[0x81];
+	}
+
+	/* EDID_VERSION[0x12] - EDID Version */
+	/* EDID_REVISION[0x13] - EDID Revision */
+	DEV_INFO("EDID (V=%d.%d, #CEABlocks=%d[V%d], ID=%s, IEEE=%04x, "
+		"EDID-Ext=0x%02x)\n", edid_buf[0x12], edid_buf[0x13],
+		num_og_cea_blocks, cea_extension_ver, vendor_id, ieee_reg_id,
+		edid_buf[0x80]);
+
+	hdmi_edid_get_display_mode(edid_buf,
+		&external_common_state->disp_mode_list, num_og_cea_blocks);
+
+	return 0;
+
+error:
+	external_common_state->disp_mode_list.num_of_elements = 1;
+	external_common_state->disp_mode_list.disp_mode_list[0] =
+		external_common_state->video_resolution;
+	return status;
+}
+EXPORT_SYMBOL(hdmi_common_read_edid);
+
+bool hdmi_common_get_video_format_from_drv_data(struct msm_fb_data_type *mfd)
+{
+	uint32 format;
+	struct fb_var_screeninfo *var = &mfd->fbi->var;
+	bool changed = TRUE;
+
+	if (var->reserved[3]) {
+		format = var->reserved[3]-1;
+		DEV_DBG("reserved format is %d\n", format);
+	} else {
+		DEV_DBG("detecting resolution from %dx%d use var->reserved[3]"
+			" to specify mode", mfd->var_xres, mfd->var_yres);
+		switch (mfd->var_xres) {
+		default:
+		case  640:
+			format = HDMI_VFRMT_640x480p60_4_3;
+			break;
+		case  720:
+			format = (mfd->var_yres == 480)
+				? HDMI_VFRMT_720x480p60_16_9
+				: HDMI_VFRMT_720x576p50_16_9;
+			break;
+		case 1280:
+			format = HDMI_VFRMT_1280x720p60_16_9;
+			break;
+		case 1440:
+			format = (mfd->var_yres == 480)
+				? HDMI_VFRMT_1440x480i60_16_9
+				: HDMI_VFRMT_1440x576i50_16_9;
+			break;
+		case 1920:
+			format = HDMI_VFRMT_1920x1080p60_16_9;
+			break;
+		}
+	}
+
+	changed = external_common_state->video_resolution != format;
+	if (external_common_state->video_resolution != format)
+		DEV_DBG("switching %s => %s", video_format_2string(
+			external_common_state->video_resolution),
+			video_format_2string(format));
+	else
+		DEV_DBG("resolution %s", video_format_2string(
+			external_common_state->video_resolution));
+	external_common_state->video_resolution = format;
+	return changed;
+}
+EXPORT_SYMBOL(hdmi_common_get_video_format_from_drv_data);
+
+const struct hdmi_disp_mode_timing_type *hdmi_common_get_mode(uint32 mode)
+{
+	if (mode >= HDMI_VFRMT_MAX)
+		return NULL;
+
+	return &hdmi_common_supported_video_mode_lut[mode];
+}
+EXPORT_SYMBOL(hdmi_common_get_mode);
+
+const struct hdmi_disp_mode_timing_type *hdmi_common_get_supported_mode(
+	uint32 mode)
+{
+	const struct hdmi_disp_mode_timing_type *ret
+		= hdmi_common_get_mode(mode);
+
+	if (ret == NULL || !ret->supported)
+		return NULL;
+	return ret;
+}
+EXPORT_SYMBOL(hdmi_common_get_supported_mode);
+
+const struct hdmi_disp_mode_timing_type *hdmi_mhl_get_mode(uint32 mode)
+{
+	if (mode >= HDMI_VFRMT_MAX)
+		return NULL;
+
+	return &hdmi_mhl_supported_video_mode_lut[mode];
+}
+EXPORT_SYMBOL(hdmi_mhl_get_mode);
+
+const struct hdmi_disp_mode_timing_type *hdmi_mhl_get_supported_mode(
+	uint32 mode)
+{
+	const struct hdmi_disp_mode_timing_type *ret
+		= hdmi_mhl_get_mode(mode);
+
+	if (ret == NULL || !ret->supported)
+		return NULL;
+	return ret;
+}
+EXPORT_SYMBOL(hdmi_mhl_get_supported_mode);
+
+void hdmi_common_init_panel_info(struct msm_panel_info *pinfo)
+{
+	const struct hdmi_disp_mode_timing_type *timing =
+		hdmi_common_get_supported_mode(
+		external_common_state->video_resolution);
+
+	if (timing == NULL)
+		return;
+
+	pinfo->xres = timing->active_h;
+	pinfo->yres = timing->active_v;
+	pinfo->clk_rate = timing->pixel_freq*1000;
+	pinfo->frame_rate = 60;
+
+	pinfo->lcdc.h_back_porch = timing->back_porch_h;
+	pinfo->lcdc.h_front_porch = timing->front_porch_h;
+	pinfo->lcdc.h_pulse_width = timing->pulse_width_h;
+	pinfo->lcdc.v_back_porch = timing->back_porch_v;
+	pinfo->lcdc.v_front_porch = timing->front_porch_v;
+	pinfo->lcdc.v_pulse_width = timing->pulse_width_v;
+
+	pinfo->type = DTV_PANEL;
+	pinfo->pdest = DISPLAY_2;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24;
+	if (hdmi_prim_display)
+		pinfo->fb_num = 2;
+	else
+		pinfo->fb_num = 1;
+
+	/* blk */
+	pinfo->lcdc.border_clr = 0;
+	/* blue */
+	pinfo->lcdc.underflow_clr = 0xff;
+	pinfo->lcdc.hsync_skew = 0;
+}
+EXPORT_SYMBOL(hdmi_common_init_panel_info);
+#endif
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
new file mode 100644
index 0000000..57c0804
--- /dev/null
+++ b/drivers/video/msm/external_common.h
@@ -0,0 +1,272 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __EXTERNAL_COMMON_H__
+#define __EXTERNAL_COMMON_H__
+#include <linux/switch.h>
+
+#ifdef DEBUG
+#ifndef DEV_DBG_PREFIX
+#define DEV_DBG_PREFIX "EXT_INTERFACE: "
+#endif
+#define DEV_DBG(args...)	pr_debug(DEV_DBG_PREFIX args)
+#else
+#define DEV_DBG(args...)	(void)0
+#endif /* DEBUG */
+#define DEV_INFO(args...)	dev_info(external_common_state->dev, args)
+#define DEV_WARN(args...)	dev_warn(external_common_state->dev, args)
+#define DEV_ERR(args...)	dev_err(external_common_state->dev, args)
+
+#ifdef CONFIG_FB_MSM_TVOUT
+#define TVOUT_VFRMT_NTSC_M_720x480i		0
+#define TVOUT_VFRMT_NTSC_J_720x480i		1
+#define TVOUT_VFRMT_PAL_BDGHIN_720x576i		2
+#define TVOUT_VFRMT_PAL_M_720x480i		3
+#define TVOUT_VFRMT_PAL_N_720x480i		4
+#elif defined(CONFIG_FB_MSM_HDMI_COMMON)
+/* all video formats defined by EIA CEA 861D */
+#define HDMI_VFRMT_640x480p60_4_3	0
+#define HDMI_VFRMT_720x480p60_4_3	1
+#define HDMI_VFRMT_720x480p60_16_9	2
+#define HDMI_VFRMT_1280x720p60_16_9	3
+#define HDMI_VFRMT_1920x1080i60_16_9	4
+#define HDMI_VFRMT_720x480i60_4_3	5
+#define HDMI_VFRMT_1440x480i60_4_3	HDMI_VFRMT_720x480i60_4_3
+#define HDMI_VFRMT_720x480i60_16_9	6
+#define HDMI_VFRMT_1440x480i60_16_9	HDMI_VFRMT_720x480i60_16_9
+#define HDMI_VFRMT_720x240p60_4_3	7
+#define HDMI_VFRMT_1440x240p60_4_3	HDMI_VFRMT_720x240p60_4_3
+#define HDMI_VFRMT_720x240p60_16_9	8
+#define HDMI_VFRMT_1440x240p60_16_9	HDMI_VFRMT_720x240p60_16_9
+#define HDMI_VFRMT_2880x480i60_4_3	9
+#define HDMI_VFRMT_2880x480i60_16_9	10
+#define HDMI_VFRMT_2880x240p60_4_3	11
+#define HDMI_VFRMT_2880x240p60_16_9	12
+#define HDMI_VFRMT_1440x480p60_4_3	13
+#define HDMI_VFRMT_1440x480p60_16_9	14
+#define HDMI_VFRMT_1920x1080p60_16_9	15
+#define HDMI_VFRMT_720x576p50_4_3	16
+#define HDMI_VFRMT_720x576p50_16_9	17
+#define HDMI_VFRMT_1280x720p50_16_9	18
+#define HDMI_VFRMT_1920x1080i50_16_9	19
+#define HDMI_VFRMT_720x576i50_4_3	20
+#define HDMI_VFRMT_1440x576i50_4_3	HDMI_VFRMT_720x576i50_4_3
+#define HDMI_VFRMT_720x576i50_16_9	21
+#define HDMI_VFRMT_1440x576i50_16_9	HDMI_VFRMT_720x576i50_16_9
+#define HDMI_VFRMT_720x288p50_4_3	22
+#define HDMI_VFRMT_1440x288p50_4_3	HDMI_VFRMT_720x288p50_4_3
+#define HDMI_VFRMT_720x288p50_16_9	23
+#define HDMI_VFRMT_1440x288p50_16_9	HDMI_VFRMT_720x288p50_16_9
+#define HDMI_VFRMT_2880x576i50_4_3	24
+#define HDMI_VFRMT_2880x576i50_16_9	25
+#define HDMI_VFRMT_2880x288p50_4_3	26
+#define HDMI_VFRMT_2880x288p50_16_9	27
+#define HDMI_VFRMT_1440x576p50_4_3	28
+#define HDMI_VFRMT_1440x576p50_16_9	29
+#define HDMI_VFRMT_1920x1080p50_16_9	30
+#define HDMI_VFRMT_1920x1080p24_16_9	31
+#define HDMI_VFRMT_1920x1080p25_16_9	32
+#define HDMI_VFRMT_1920x1080p30_16_9	33
+#define HDMI_VFRMT_2880x480p60_4_3	34
+#define HDMI_VFRMT_2880x480p60_16_9	35
+#define HDMI_VFRMT_2880x576p50_4_3	36
+#define HDMI_VFRMT_2880x576p50_16_9	37
+#define HDMI_VFRMT_1920x1250i50_16_9	38
+#define HDMI_VFRMT_1920x1080i100_16_9	39
+#define HDMI_VFRMT_1280x720p100_16_9	40
+#define HDMI_VFRMT_720x576p100_4_3	41
+#define HDMI_VFRMT_720x576p100_16_9	42
+#define HDMI_VFRMT_720x576i100_4_3	43
+#define HDMI_VFRMT_1440x576i100_4_3	HDMI_VFRMT_720x576i100_4_3
+#define HDMI_VFRMT_720x576i100_16_9	44
+#define HDMI_VFRMT_1440x576i100_16_9	HDMI_VFRMT_720x576i100_16_9
+#define HDMI_VFRMT_1920x1080i120_16_9	45
+#define HDMI_VFRMT_1280x720p120_16_9	46
+#define HDMI_VFRMT_720x480p120_4_3	47
+#define HDMI_VFRMT_720x480p120_16_9	48
+#define HDMI_VFRMT_720x480i120_4_3	49
+#define HDMI_VFRMT_1440x480i120_4_3	HDMI_VFRMT_720x480i120_4_3
+#define HDMI_VFRMT_720x480i120_16_9	50
+#define HDMI_VFRMT_1440x480i120_16_9	HDMI_VFRMT_720x480i120_16_9
+#define HDMI_VFRMT_720x576p200_4_3	51
+#define HDMI_VFRMT_720x576p200_16_9	52
+#define HDMI_VFRMT_720x576i200_4_3	53
+#define HDMI_VFRMT_1440x576i200_4_3	HDMI_VFRMT_720x576i200_4_3
+#define HDMI_VFRMT_720x576i200_16_9	54
+#define HDMI_VFRMT_1440x576i200_16_9	HDMI_VFRMT_720x576i200_16_9
+#define HDMI_VFRMT_720x480p240_4_3	55
+#define HDMI_VFRMT_720x480p240_16_9	56
+#define HDMI_VFRMT_720x480i240_4_3	57
+#define HDMI_VFRMT_1440x480i240_4_3	HDMI_VFRMT_720x480i240_4_3
+#define HDMI_VFRMT_720x480i240_16_9	58
+#define HDMI_VFRMT_1440x480i240_16_9	HDMI_VFRMT_720x480i240_16_9
+#define HDMI_VFRMT_MAX			59
+#define HDMI_VFRMT_FORCE_32BIT		0x7FFFFFFF
+
+struct hdmi_disp_mode_timing_type {
+	uint32	video_format;
+	uint32	active_h;
+	uint32	front_porch_h;
+	uint32	pulse_width_h;
+	uint32	back_porch_h;
+	boolean	active_low_h;
+	uint32	active_v;
+	uint32	front_porch_v;
+	uint32	pulse_width_v;
+	uint32	back_porch_v;
+	boolean	active_low_v;
+	/* Must divide by 1000 to get the actual frequency in MHZ */
+	uint32	pixel_freq;
+	/* Must divide by 1000 to get the actual frequency in HZ */
+	uint32	refresh_rate;
+	boolean	interlaced;
+	boolean	supported;
+};
+
+#define HDMI_SETTINGS_640x480p60_4_3					\
+	{HDMI_VFRMT_640x480p60_4_3,      640,  16,  96,  48,  TRUE,	\
+	 480, 10, 2, 33, TRUE, 25200, 60000, FALSE, TRUE}
+#define HDMI_SETTINGS_720x480p60_4_3					\
+	{HDMI_VFRMT_720x480p60_4_3,      720,  16,  62,  60,  TRUE,	\
+	 480, 9, 6, 30,  TRUE, 27030, 60000, FALSE, TRUE}
+#define HDMI_SETTINGS_720x480p60_16_9					\
+	{HDMI_VFRMT_720x480p60_16_9,     720,  16,  62,  60,  TRUE,	\
+	 480, 9, 6, 30,  TRUE, 27030, 60000, FALSE, TRUE}
+#define HDMI_SETTINGS_1280x720p60_16_9					\
+	{HDMI_VFRMT_1280x720p60_16_9,    1280, 110, 40,  220, FALSE,	\
+	 720, 5, 5, 20, FALSE, 74250, 60000, FALSE, TRUE}
+#define HDMI_SETTINGS_1920x1080i60_16_9					\
+	{HDMI_VFRMT_1920x1080i60_16_9,   1920, 88,  44,  148, FALSE,	\
+	 540, 2, 5, 5, FALSE, 74250, 60000, FALSE, TRUE}
+#define HDMI_SETTINGS_1440x480i60_4_3					\
+	{HDMI_VFRMT_1440x480i60_4_3,     1440, 38,  124, 114, TRUE,	\
+	 240, 4, 3, 15, TRUE, 27000, 60000, TRUE, TRUE}
+#define HDMI_SETTINGS_1440x480i60_16_9					\
+	{HDMI_VFRMT_1440x480i60_16_9,    1440, 38,  124, 114, TRUE,	\
+	 240, 4, 3, 15, TRUE, 27000, 60000, TRUE, TRUE}
+#define HDMI_SETTINGS_1920x1080p60_16_9					\
+	{HDMI_VFRMT_1920x1080p60_16_9,   1920, 88,  44,  148,  FALSE,	\
+	 1080, 4, 5, 36, FALSE, 148500, 60000, FALSE, TRUE}
+#define HDMI_SETTINGS_720x576p50_4_3					\
+	{HDMI_VFRMT_720x576p50_4_3,      720,  12,  64,  68,   TRUE,	\
+	 576,  5, 5, 39, TRUE, 27000, 50000, FALSE, TRUE}
+#define HDMI_SETTINGS_720x576p50_16_9					\
+	{HDMI_VFRMT_720x576p50_16_9,     720,  12,  64,  68,   TRUE,	\
+	 576,  5, 5, 39, TRUE, 27000, 50000, FALSE, TRUE}
+#define HDMI_SETTINGS_1280x720p50_16_9					\
+	{HDMI_VFRMT_1280x720p50_16_9,    1280, 440, 40,  220,  FALSE,	\
+	 720,  5, 5, 20, FALSE, 74250, 50000, FALSE, TRUE}
+#define HDMI_SETTINGS_1440x576i50_4_3					\
+	{HDMI_VFRMT_1440x576i50_4_3,     1440, 24,  126, 138,  TRUE,	\
+	 288,  2, 3, 19, TRUE, 27000, 50000, TRUE, TRUE}
+#define HDMI_SETTINGS_1440x576i50_16_9					\
+	{HDMI_VFRMT_1440x576i50_16_9,    1440, 24,  126, 138,  TRUE,	\
+	 288,  2, 3, 19, TRUE, 27000, 50000, TRUE, TRUE}
+#define HDMI_SETTINGS_1920x1080p50_16_9					\
+	{HDMI_VFRMT_1920x1080p50_16_9,   1920,  528,  44,  148,  FALSE,	\
+	 1080, 4, 5, 36, FALSE, 148500, 50000, FALSE, TRUE}
+#define HDMI_SETTINGS_1920x1080p24_16_9					\
+	{HDMI_VFRMT_1920x1080p24_16_9,   1920,  638,  44,  148,  FALSE,	\
+	 1080, 4, 5, 36, FALSE, 74250, 24000, FALSE, TRUE}
+#define HDMI_SETTINGS_1920x1080p25_16_9					\
+	{HDMI_VFRMT_1920x1080p25_16_9,   1920,  528,  44,  148,  FALSE,	\
+	 1080, 4, 5, 36, FALSE, 74250, 25000, FALSE, TRUE}
+#define HDMI_SETTINGS_1920x1080p30_16_9					\
+	{HDMI_VFRMT_1920x1080p30_16_9,   1920,  88,   44,  148,  FALSE,	\
+	 1080, 4, 5, 36, FALSE, 74250, 30000, FALSE, TRUE}
+
+/* A lookup table for all the supported display modes by the HDMI
+ * hardware and driver.  Use HDMI_SETUP_LUT in the module init to
+ * setup the LUT with the supported modes. */
+extern struct hdmi_disp_mode_timing_type
+	hdmi_common_supported_video_mode_lut[HDMI_VFRMT_MAX];
+
+/* Structure that encapsulates all the supported display modes by the HDMI sink
+ * device */
+struct hdmi_disp_mode_list_type {
+	uint32	disp_mode_list[HDMI_VFRMT_MAX];
+#define TOP_AND_BOTTOM		0x10
+#define FRAME_PACKING		0x20
+#define SIDE_BY_SIDE_HALF	0x40
+	uint32	disp_3d_mode_list[HDMI_VFRMT_MAX];
+	uint32	disp_multi_3d_mode_list[16];
+	uint32	disp_multi_3d_mode_list_cnt;
+	uint32	num_of_elements;
+};
+#endif
+
+struct external_common_state_type {
+	boolean hpd_state;
+	struct kobject *uevent_kobj;
+	uint32 video_resolution;
+	struct device *dev;
+	struct switch_dev sdev;
+#ifdef CONFIG_FB_MSM_HDMI_3D
+	boolean format_3d;
+	void (*switch_3d)(boolean on);
+#endif
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+	boolean hdcp_active;
+	boolean hpd_feature_on;
+	boolean hdmi_sink;
+	struct hdmi_disp_mode_list_type disp_mode_list;
+	uint8 speaker_allocation_block;
+	uint16 video_latency, audio_latency;
+	uint8 audio_data_block_cnt;
+	uint16 physical_address;
+	uint32 preferred_video_format;
+	uint8 pt_scan_info;
+	uint8 it_scan_info;
+	uint8 ce_scan_info;
+	uint8 spd_vendor_name[8];
+	uint8 spd_product_description[16];
+	boolean present_3d;
+	boolean present_hdcp;
+	uint32 audio_data_blocks[16];
+	int (*read_edid_block)(int block, uint8 *edid_buf);
+	int (*hpd_feature)(int on);
+#endif
+};
+
+/* The external interface driver needs to initialize the common state. */
+extern struct external_common_state_type *external_common_state;
+extern struct mutex external_common_state_hpd_mutex;
+extern struct mutex hdmi_msm_state_mutex;
+
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+#define VFRMT_NOT_SUPPORTED(VFRMT) \
+	{VFRMT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FALSE}
+#define HDMI_SETUP_LUT(MODE) do {					\
+		struct hdmi_disp_mode_timing_type mode			\
+			= HDMI_SETTINGS_ ## MODE;			\
+		hdmi_common_supported_video_mode_lut[mode.video_format]	\
+			= mode;						\
+	} while (0)
+
+int hdmi_common_read_edid(void);
+const char *video_format_2string(uint32 format);
+bool hdmi_common_get_video_format_from_drv_data(struct msm_fb_data_type *mfd);
+const struct hdmi_disp_mode_timing_type *hdmi_common_get_mode(uint32 mode);
+const struct hdmi_disp_mode_timing_type *hdmi_common_get_supported_mode(
+	uint32 mode);
+const struct hdmi_disp_mode_timing_type *hdmi_mhl_get_mode(uint32 mode);
+const struct hdmi_disp_mode_timing_type *hdmi_mhl_get_supported_mode(
+	uint32 mode);
+void hdmi_common_init_panel_info(struct msm_panel_info *pinfo);
+
+ssize_t video_3d_format_2string(uint32 format, char *buf);
+#endif
+
+int external_common_state_create(struct platform_device *pdev);
+void external_common_state_remove(void);
+
+#endif /* __EXTERNAL_COMMON_H__ */
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
new file mode 100644
index 0000000..1eae516
--- /dev/null
+++ b/drivers/video/msm/hdmi_msm.c
@@ -0,0 +1,4833 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/* #define DEBUG */
+#define DEV_DBG_PREFIX "HDMI: "
+/* #define REG_DUMP */
+
+#define CEC_MSG_PRINT
+#define TOGGLE_CEC_HARDWARE_FSM
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <mach/msm_hdmi_audio.h>
+#include <mach/clk.h>
+#include <mach/msm_iomap.h>
+#include <mach/socinfo.h>
+
+#include "msm_fb.h"
+#include "hdmi_msm.h"
+
+/* Supported HDMI Audio channels */
+#define MSM_HDMI_AUDIO_CHANNEL_2		0
+#define MSM_HDMI_AUDIO_CHANNEL_4		1
+#define MSM_HDMI_AUDIO_CHANNEL_6		2
+#define MSM_HDMI_AUDIO_CHANNEL_8		3
+#define MSM_HDMI_AUDIO_CHANNEL_MAX		4
+#define MSM_HDMI_AUDIO_CHANNEL_FORCE_32BIT	0x7FFFFFFF
+
+/* Supported HDMI Audio sample rates */
+#define MSM_HDMI_SAMPLE_RATE_32KHZ		0
+#define MSM_HDMI_SAMPLE_RATE_44_1KHZ		1
+#define MSM_HDMI_SAMPLE_RATE_48KHZ		2
+#define MSM_HDMI_SAMPLE_RATE_88_2KHZ		3
+#define MSM_HDMI_SAMPLE_RATE_96KHZ		4
+#define MSM_HDMI_SAMPLE_RATE_176_4KHZ		5
+#define MSM_HDMI_SAMPLE_RATE_192KHZ		6
+#define MSM_HDMI_SAMPLE_RATE_MAX		7
+#define MSM_HDMI_SAMPLE_RATE_FORCE_32BIT	0x7FFFFFFF
+
+static int msm_hdmi_sample_rate = MSM_HDMI_SAMPLE_RATE_48KHZ;
+
+/* HDMI/HDCP Registers */
+#define HDCP_DDC_STATUS		0x0128
+#define HDCP_DDC_CTRL_0		0x0120
+#define HDCP_DDC_CTRL_1		0x0124
+#define HDMI_DDC_CTRL		0x020C
+
+struct workqueue_struct *hdmi_work_queue;
+struct hdmi_msm_state_type *hdmi_msm_state;
+
+DEFINE_MUTEX(hdmi_msm_state_mutex);
+EXPORT_SYMBOL(hdmi_msm_state_mutex);
+static DEFINE_MUTEX(hdcp_auth_state_mutex);
+
+static void hdmi_msm_dump_regs(const char *prefix);
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+static void hdmi_msm_hdcp_enable(void);
+#else
+static inline void hdmi_msm_hdcp_enable(void) {}
+#endif
+
+static void hdmi_msm_turn_on(void);
+static int hdmi_msm_audio_off(void);
+static int hdmi_msm_read_edid(void);
+static void hdmi_msm_hpd_off(void);
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+
+static void hdmi_msm_cec_line_latch_detect(void);
+
+#ifdef TOGGLE_CEC_HARDWARE_FSM
+static boolean msg_send_complete = TRUE;
+static boolean msg_recv_complete = TRUE;
+#endif
+
+#define HDMI_MSM_CEC_REFTIMER_REFTIMER_ENABLE	BIT(16)
+#define HDMI_MSM_CEC_REFTIMER_REFTIMER(___t)	(((___t)&0xFFFF) << 0)
+
+#define HDMI_MSM_CEC_TIME_SIGNAL_FREE_TIME(___t)	(((___t)&0x1FF) << 7)
+#define HDMI_MSM_CEC_TIME_ENABLE			BIT(0)
+
+#define HDMI_MSM_CEC_ADDR_LOGICAL_ADDR(___la)	(((___la)&0xFF) << 0)
+
+#define HDMI_MSM_CEC_CTRL_LINE_OE			BIT(9)
+#define HDMI_MSM_CEC_CTRL_FRAME_SIZE(___sz)		(((___sz)&0x1F) << 4)
+#define HDMI_MSM_CEC_CTRL_SOFT_RESET		BIT(2)
+#define HDMI_MSM_CEC_CTRL_SEND_TRIG			BIT(1)
+#define HDMI_MSM_CEC_CTRL_ENABLE			BIT(0)
+
+#define HDMI_MSM_CEC_INT_FRAME_RD_DONE_MASK		BIT(7)
+#define HDMI_MSM_CEC_INT_FRAME_RD_DONE_ACK		BIT(6)
+#define HDMI_MSM_CEC_INT_FRAME_RD_DONE_INT		BIT(6)
+#define HDMI_MSM_CEC_INT_MONITOR_MASK		BIT(5)
+#define HDMI_MSM_CEC_INT_MONITOR_ACK		BIT(4)
+#define HDMI_MSM_CEC_INT_MONITOR_INT		BIT(4)
+#define HDMI_MSM_CEC_INT_FRAME_ERROR_MASK		BIT(3)
+#define HDMI_MSM_CEC_INT_FRAME_ERROR_ACK		BIT(2)
+#define HDMI_MSM_CEC_INT_FRAME_ERROR_INT		BIT(2)
+#define HDMI_MSM_CEC_INT_FRAME_WR_DONE_MASK		BIT(1)
+#define HDMI_MSM_CEC_INT_FRAME_WR_DONE_ACK		BIT(0)
+#define HDMI_MSM_CEC_INT_FRAME_WR_DONE_INT		BIT(0)
+
+#define HDMI_MSM_CEC_FRAME_WR_SUCCESS(___st)         (((___st)&0xB) ==\
+		(HDMI_MSM_CEC_INT_FRAME_WR_DONE_INT |\
+			HDMI_MSM_CEC_INT_FRAME_WR_DONE_MASK |\
+			HDMI_MSM_CEC_INT_FRAME_ERROR_MASK))
+
+#define HDMI_MSM_CEC_RETRANSMIT_NUM(___num)		(((___num)&0xF) << 4)
+#define HDMI_MSM_CEC_RETRANSMIT_ENABLE		BIT(0)
+
+#define HDMI_MSM_CEC_WR_DATA_DATA(___d)		(((___d)&0xFF) << 8)
+
+
+void hdmi_msm_cec_init(void)
+{
+	/* 0x02A8 CEC_REFTIMER */
+	HDMI_OUTP(0x02A8,
+		HDMI_MSM_CEC_REFTIMER_REFTIMER_ENABLE
+		| HDMI_MSM_CEC_REFTIMER_REFTIMER(27 * 50)
+		);
+
+	/* 0x02A4 CEC_TIME */
+	HDMI_OUTP(0x02A4,
+		HDMI_MSM_CEC_TIME_SIGNAL_FREE_TIME(350)
+		| HDMI_MSM_CEC_TIME_ENABLE
+		);
+
+	/*
+	 * 0x02A0 CEC_ADDR
+	 * Starting with a default address of 4
+	 */
+	HDMI_OUTP(0x02A0, HDMI_MSM_CEC_ADDR_LOGICAL_ADDR(4));
+
+	hdmi_msm_state->first_monitor = 0;
+	hdmi_msm_state->fsm_reset_done = false;
+
+	/* 0x029C CEC_INT */
+	/* Enable CEC interrupts */
+	HDMI_OUTP(0x029C,					\
+		  HDMI_MSM_CEC_INT_FRAME_WR_DONE_MASK		\
+		  | HDMI_MSM_CEC_INT_FRAME_ERROR_MASK		\
+		  | HDMI_MSM_CEC_INT_MONITOR_MASK		\
+		  | HDMI_MSM_CEC_INT_FRAME_RD_DONE_MASK);
+
+	HDMI_OUTP(0x02B0, 0x7FF << 4 | 1);
+
+	/*
+	 * Slight adjustment to logic 1 low periods on read,
+	 * CEC Test 8.2-3 was failing, 8 for the
+	 * BIT_1_ERR_RANGE_HI = 8 => 750us, the test used 775us,
+	 * so increased this to 9 which => 800us.
+	 */
+	/*
+	 * CEC latch up issue - To fire monitor interrupt
+	 * for every start of message
+	 */
+	HDMI_OUTP(0x02E0, 0x880000);
+
+	/*
+	 * Slight adjustment to logic 0 low period on write
+	 */
+	HDMI_OUTP(0x02DC, 0x8888A888);
+
+	/*
+	 * Enable Signal Free Time counter and set to 7 bit periods
+	 */
+	HDMI_OUTP(0x02A4, 0x1 | (7 * 0x30) << 7);
+
+	/* 0x028C CEC_CTRL */
+	HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+}
+
+void hdmi_msm_cec_write_logical_addr(int addr)
+{
+	/* 0x02A0 CEC_ADDR
+	 *   LOGICAL_ADDR       7:0  NUM
+	 */
+	HDMI_OUTP(0x02A0, addr & 0xFF);
+}
+
+void hdmi_msm_dump_cec_msg(struct hdmi_msm_cec_msg *msg)
+{
+#ifdef CEC_MSG_PRINT
+	int i;
+	DEV_DBG("sender_id     : %d", msg->sender_id);
+	DEV_DBG("recvr_id     : %d", msg->recvr_id);
+	if (msg->frame_size < 2) {
+		DEV_DBG("polling message");
+		return;
+	}
+	DEV_DBG("opcode      : %02x", msg->opcode);
+	for (i = 0; i < msg->frame_size - 2; i++)
+		DEV_DBG("operand(%2d) : %02x", i + 1, msg->operand[i]);
+#endif /* CEC_MSG_PRINT */
+}
+
+void hdmi_msm_cec_msg_send(struct hdmi_msm_cec_msg *msg)
+{
+	int i;
+	uint32 timeout_count = 1;
+	int retry = 10;
+
+	boolean frameType = (msg->recvr_id == 15 ? BIT(0) : 0);
+
+	mutex_lock(&hdmi_msm_state_mutex);
+	hdmi_msm_state->fsm_reset_done = false;
+	mutex_unlock(&hdmi_msm_state_mutex);
+#ifdef TOGGLE_CEC_HARDWARE_FSM
+	msg_send_complete = FALSE;
+#endif
+
+	INIT_COMPLETION(hdmi_msm_state->cec_frame_wr_done);
+	hdmi_msm_state->cec_frame_wr_status = 0;
+
+	/* 0x0294 HDMI_MSM_CEC_RETRANSMIT */
+	HDMI_OUTP(0x0294,
+		HDMI_MSM_CEC_RETRANSMIT_NUM(msg->retransmit)
+		| (msg->retransmit > 0) ? HDMI_MSM_CEC_RETRANSMIT_ENABLE : 0);
+
+	/* 0x028C CEC_CTRL */
+	HDMI_OUTP(0x028C, 0x1 | msg->frame_size << 4);
+
+	/* 0x0290 CEC_WR_DATA */
+
+	/* header block */
+	HDMI_OUTP(0x0290,
+		HDMI_MSM_CEC_WR_DATA_DATA(msg->sender_id << 4 | msg->recvr_id)
+		| frameType);
+
+	/* data block 0 : opcode */
+	HDMI_OUTP(0x0290,
+		HDMI_MSM_CEC_WR_DATA_DATA(msg->frame_size < 2 ? 0 : msg->opcode)
+		| frameType);
+
+	/* data block 1-14 : operand 0-13 */
+	for (i = 0; i < msg->frame_size - 1; i++)
+		HDMI_OUTP(0x0290,
+			HDMI_MSM_CEC_WR_DATA_DATA(msg->operand[i])
+			| (msg->recvr_id == 15 ? BIT(0) : 0));
+
+	for (; i < 14; i++)
+		HDMI_OUTP(0x0290,
+			HDMI_MSM_CEC_WR_DATA_DATA(0)
+			| (msg->recvr_id == 15 ? BIT(0) : 0));
+
+	while ((HDMI_INP(0x0298) & 1) && retry--) {
+		DEV_DBG("CEC line is busy(%d)\n", retry);
+		schedule();
+	}
+
+	/* 0x028C CEC_CTRL */
+	HDMI_OUTP(0x028C,
+		  HDMI_MSM_CEC_CTRL_LINE_OE
+		  | HDMI_MSM_CEC_CTRL_FRAME_SIZE(msg->frame_size)
+		  | HDMI_MSM_CEC_CTRL_SEND_TRIG
+		  | HDMI_MSM_CEC_CTRL_ENABLE);
+
+	timeout_count = wait_for_completion_interruptible_timeout(
+		&hdmi_msm_state->cec_frame_wr_done, HZ);
+
+	if (!timeout_count) {
+		hdmi_msm_state->cec_frame_wr_status |= CEC_STATUS_WR_TMOUT;
+		DEV_ERR("%s: timedout", __func__);
+		hdmi_msm_dump_cec_msg(msg);
+	} else {
+		DEV_DBG("CEC write frame done (frame len=%d)",
+			msg->frame_size);
+		hdmi_msm_dump_cec_msg(msg);
+	}
+
+#ifdef TOGGLE_CEC_HARDWARE_FSM
+	if (!msg_recv_complete) {
+		/* Toggle CEC hardware FSM */
+		HDMI_OUTP(0x028C, 0x0);
+		HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+		msg_recv_complete = TRUE;
+	}
+	msg_send_complete = TRUE;
+#else
+	HDMI_OUTP(0x028C, 0x0);
+	HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+#endif
+}
+
+void hdmi_msm_cec_line_latch_detect(void)
+{
+	/*
+	 * CECT 9-5-1
+	 * The timer period needs to be changed to appropriate value
+	 */
+	/*
+	 * Timedout without RD_DONE, WR_DONE or ERR_INT
+	 * Toggle CEC hardware FSM
+	 */
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->first_monitor == 1) {
+		DEV_WARN("CEC line is probably latched up - CECT 9-5-1");
+		if (!msg_recv_complete)
+			hdmi_msm_state->fsm_reset_done = true;
+		HDMI_OUTP(0x028C, 0x0);
+		HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+		hdmi_msm_state->first_monitor = 0;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+}
+
+void hdmi_msm_cec_msg_recv(void)
+{
+	uint32 data;
+	int i;
+#ifdef DRVR_ONLY_CECT_NO_DAEMON
+	struct hdmi_msm_cec_msg temp_msg;
+#endif
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->cec_queue_wr == hdmi_msm_state->cec_queue_rd
+		&& hdmi_msm_state->cec_queue_full) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_ERR("CEC message queue is overflowing\n");
+#ifdef DRVR_ONLY_CECT_NO_DAEMON
+		/*
+		 * Without CEC daemon:
+		 * Compliance tests fail once the queue gets filled up.
+		 * so reset the pointers to the start of the queue.
+		 */
+		hdmi_msm_state->cec_queue_wr = hdmi_msm_state->cec_queue_start;
+		hdmi_msm_state->cec_queue_rd = hdmi_msm_state->cec_queue_start;
+		hdmi_msm_state->cec_queue_full = false;
+#else
+		return;
+#endif
+	}
+	if (hdmi_msm_state->cec_queue_wr == NULL) {
+		DEV_ERR("%s: wp is NULL\n", __func__);
+		return;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+
+	/* 0x02AC CEC_RD_DATA */
+	data = HDMI_INP(0x02AC);
+
+	hdmi_msm_state->cec_queue_wr->sender_id = (data & 0xF0) >> 4;
+	hdmi_msm_state->cec_queue_wr->recvr_id = (data & 0x0F);
+	hdmi_msm_state->cec_queue_wr->frame_size = (data & 0x1F00) >> 8;
+	DEV_DBG("Recvd init=[%u] dest=[%u] size=[%u]\n",
+		hdmi_msm_state->cec_queue_wr->sender_id,
+		hdmi_msm_state->cec_queue_wr->recvr_id,
+		hdmi_msm_state->cec_queue_wr->frame_size);
+
+	if (hdmi_msm_state->cec_queue_wr->frame_size < 1) {
+		DEV_ERR("%s: invalid message (frame length = %d)",
+			__func__, hdmi_msm_state->cec_queue_wr->frame_size);
+		return;
+	} else if (hdmi_msm_state->cec_queue_wr->frame_size == 1) {
+		DEV_DBG("%s: polling message (dest[%x] <- init[%x])",
+			__func__,
+			hdmi_msm_state->cec_queue_wr->recvr_id,
+			hdmi_msm_state->cec_queue_wr->sender_id);
+		return;
+	}
+
+	/* data block 0 : opcode */
+	data = HDMI_INP(0x02AC);
+	hdmi_msm_state->cec_queue_wr->opcode = data & 0xFF;
+
+	/* data block 1-14 : operand 0-13 */
+	for (i = 0; i < hdmi_msm_state->cec_queue_wr->frame_size - 2; i++) {
+		data = HDMI_INP(0x02AC);
+		hdmi_msm_state->cec_queue_wr->operand[i] = data & 0xFF;
+	}
+
+	for (; i < 14; i++)
+		hdmi_msm_state->cec_queue_wr->operand[i] = 0;
+
+	DEV_DBG("CEC read frame done\n");
+	DEV_DBG("=======================================\n");
+	hdmi_msm_dump_cec_msg(hdmi_msm_state->cec_queue_wr);
+	DEV_DBG("=======================================\n");
+
+#ifdef DRVR_ONLY_CECT_NO_DAEMON
+	switch (hdmi_msm_state->cec_queue_wr->opcode) {
+	case 0x64:
+		/* Set OSD String */
+		DEV_INFO("Recvd OSD Str=[%x]\n",\
+			hdmi_msm_state->cec_queue_wr->operand[3]);
+		break;
+	case 0x83:
+		/* Give Phy Addr */
+		DEV_INFO("Recvd a Give Phy Addr cmd\n");
+		memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+		/* Setup a frame for sending out phy addr */
+		temp_msg.sender_id = 0x4;
+
+		/* Broadcast */
+		temp_msg.recvr_id = 0xf;
+		temp_msg.opcode = 0x84;
+		i = 0;
+		temp_msg.operand[i++] = 0x10;
+		temp_msg.operand[i++] = 0x00;
+		temp_msg.operand[i++] = 0x04;
+		temp_msg.frame_size = i + 2;
+		hdmi_msm_cec_msg_send(&temp_msg);
+		break;
+	case 0xFF:
+		/* Abort */
+		DEV_INFO("Recvd an abort cmd 0xFF\n");
+		memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+		temp_msg.sender_id = 0x4;
+		temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
+		i = 0;
+
+		/*feature abort */
+		temp_msg.opcode = 0x00;
+		temp_msg.operand[i++] =
+			hdmi_msm_state->cec_queue_wr->opcode;
+
+		/*reason for abort = "Refused" */
+		temp_msg.operand[i++] = 0x04;
+		temp_msg.frame_size = i + 2;
+		hdmi_msm_dump_cec_msg(&temp_msg);
+		hdmi_msm_cec_msg_send(&temp_msg);
+		break;
+	case 0x046:
+		/* Give OSD name */
+		DEV_INFO("Recvd cmd 0x046\n");
+		memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+		temp_msg.sender_id = 0x4;
+		temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
+		i = 0;
+
+		/* OSD Name */
+		temp_msg.opcode = 0x47;
+
+		/* Display control byte */
+		temp_msg.operand[i++] = 0x00;
+		temp_msg.operand[i++] = 'H';
+		temp_msg.operand[i++] = 'e';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'o';
+		temp_msg.operand[i++] = ' ';
+		temp_msg.operand[i++] = 'W';
+		temp_msg.operand[i++] = 'o';
+		temp_msg.operand[i++] = 'r';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'd';
+		temp_msg.frame_size = i + 2;
+		hdmi_msm_cec_msg_send(&temp_msg);
+		break;
+	case 0x08F:
+		/* Give Device Power status */
+		DEV_INFO("Recvd a Power status message\n");
+		memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+		temp_msg.sender_id = 0x4;
+		temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
+		i = 0;
+
+		/* OSD String */
+		temp_msg.opcode = 0x90;
+		temp_msg.operand[i++] = 'H';
+		temp_msg.operand[i++] = 'e';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'o';
+		temp_msg.operand[i++] = ' ';
+		temp_msg.operand[i++] = 'W';
+		temp_msg.operand[i++] = 'o';
+		temp_msg.operand[i++] = 'r';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'd';
+		temp_msg.frame_size = i + 2;
+		hdmi_msm_cec_msg_send(&temp_msg);
+		break;
+	case 0x080:
+		/* Routing Change cmd */
+	case 0x086:
+		/* Set Stream Path */
+		DEV_INFO("Recvd Set Stream\n");
+		memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+		temp_msg.sender_id = 0x4;
+
+		/*Broadcast this message*/
+		temp_msg.recvr_id = 0xf;
+		i = 0;
+		temp_msg.opcode = 0x82; /* Active Source */
+		temp_msg.operand[i++] = 0x10;
+		temp_msg.operand[i++] = 0x00;
+		temp_msg.frame_size = i + 2;
+		hdmi_msm_cec_msg_send(&temp_msg);
+
+		/*
+		 * sending <Image View On> message
+		 */
+		memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+		temp_msg.sender_id = 0x4;
+		temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
+		i = 0;
+		/* opcode for Image View On */
+		temp_msg.opcode = 0x04;
+		temp_msg.frame_size = i + 2;
+		hdmi_msm_cec_msg_send(&temp_msg);
+		break;
+	case 0x44:
+		/* User Control Pressed */
+		DEV_INFO("User Control Pressed\n");
+		break;
+	case 0x45:
+		/* User Control Released */
+		DEV_INFO("User Control Released\n");
+		break;
+	default:
+		DEV_INFO("Recvd an unknown cmd = [%u]\n",
+			hdmi_msm_state->cec_queue_wr->opcode);
+#ifdef __SEND_ABORT__
+		memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+		temp_msg.sender_id = 0x4;
+		temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
+		i = 0;
+		/* opcode for feature abort */
+		temp_msg.opcode = 0x00;
+		temp_msg.operand[i++] =
+			hdmi_msm_state->cec_queue_wr->opcode;
+		/*reason for abort = "Unrecognized opcode" */
+		temp_msg.operand[i++] = 0x00;
+		temp_msg.frame_size = i + 2;
+		hdmi_msm_cec_msg_send(&temp_msg);
+		break;
+#else
+		memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+		temp_msg.sender_id = 0x4;
+		temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
+		i = 0;
+		/* OSD String */
+		temp_msg.opcode = 0x64;
+		temp_msg.operand[i++] = 0x0;
+		temp_msg.operand[i++] = 'H';
+		temp_msg.operand[i++] = 'e';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'o';
+		temp_msg.operand[i++] = ' ';
+		temp_msg.operand[i++] = 'W';
+		temp_msg.operand[i++] = 'o';
+		temp_msg.operand[i++] = 'r';
+		temp_msg.operand[i++] = 'l';
+		temp_msg.operand[i++] = 'd';
+		temp_msg.frame_size = i + 2;
+		hdmi_msm_cec_msg_send(&temp_msg);
+		break;
+#endif /* __SEND_ABORT__ */
+	}
+
+#endif /* DRVR_ONLY_CECT_NO_DAEMON */
+	mutex_lock(&hdmi_msm_state_mutex);
+	hdmi_msm_state->cec_queue_wr++;
+	if (hdmi_msm_state->cec_queue_wr == CEC_QUEUE_END)
+		hdmi_msm_state->cec_queue_wr = hdmi_msm_state->cec_queue_start;
+	if (hdmi_msm_state->cec_queue_wr == hdmi_msm_state->cec_queue_rd)
+		hdmi_msm_state->cec_queue_full = true;
+	mutex_unlock(&hdmi_msm_state_mutex);
+	DEV_DBG("Exiting %s()\n", __func__);
+}
+
+void hdmi_msm_cec_one_touch_play(void)
+{
+	struct hdmi_msm_cec_msg temp_msg;
+	uint32 i = 0;
+	memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+	temp_msg.sender_id = 0x4;
+	/*
+	 * Broadcast this message
+	 */
+	temp_msg.recvr_id = 0xf;
+	i = 0;
+	/* Active Source */
+	temp_msg.opcode = 0x82;
+	temp_msg.operand[i++] = 0x10;
+	temp_msg.operand[i++] = 0x00;
+	/*temp_msg.operand[i++] = 0x04;*/
+	temp_msg.frame_size = i + 2;
+	hdmi_msm_cec_msg_send(&temp_msg);
+	/*
+	 * sending <Image View On> message
+	 */
+	memset(&temp_msg, 0x00, sizeof(struct hdmi_msm_cec_msg));
+	temp_msg.sender_id = 0x4;
+	temp_msg.recvr_id = hdmi_msm_state->cec_queue_wr->sender_id;
+	i = 0;
+	/* Image View On */
+	temp_msg.opcode = 0x04;
+	temp_msg.frame_size = i + 2;
+	hdmi_msm_cec_msg_send(&temp_msg);
+
+}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+
+uint32 hdmi_msm_get_io_base(void)
+{
+	return (uint32)MSM_HDMI_BASE;
+}
+EXPORT_SYMBOL(hdmi_msm_get_io_base);
+
+/* Table indicating the video format supported by the HDMI TX Core v1.0 */
+/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
+static void hdmi_msm_setup_video_mode_lut(void)
+{
+	HDMI_SETUP_LUT(640x480p60_4_3);
+	HDMI_SETUP_LUT(720x480p60_4_3);
+	HDMI_SETUP_LUT(720x480p60_16_9);
+	HDMI_SETUP_LUT(1280x720p60_16_9);
+	HDMI_SETUP_LUT(1920x1080i60_16_9);
+	HDMI_SETUP_LUT(1440x480i60_4_3);
+	HDMI_SETUP_LUT(1440x480i60_16_9);
+	HDMI_SETUP_LUT(1920x1080p60_16_9);
+	HDMI_SETUP_LUT(720x576p50_4_3);
+	HDMI_SETUP_LUT(720x576p50_16_9);
+	HDMI_SETUP_LUT(1280x720p50_16_9);
+	HDMI_SETUP_LUT(1440x576i50_4_3);
+	HDMI_SETUP_LUT(1440x576i50_16_9);
+	HDMI_SETUP_LUT(1920x1080p50_16_9);
+	HDMI_SETUP_LUT(1920x1080p24_16_9);
+	HDMI_SETUP_LUT(1920x1080p25_16_9);
+	HDMI_SETUP_LUT(1920x1080p30_16_9);
+}
+
+#ifdef PORT_DEBUG
+const char *hdmi_msm_name(uint32 offset)
+{
+	switch (offset) {
+	case 0x0000: return "CTRL";
+	case 0x0020: return "AUDIO_PKT_CTRL1";
+	case 0x0024: return "ACR_PKT_CTRL";
+	case 0x0028: return "VBI_PKT_CTRL";
+	case 0x002C: return "INFOFRAME_CTRL0";
+#ifdef CONFIG_FB_MSM_HDMI_3D
+	case 0x0034: return "GEN_PKT_CTRL";
+#endif
+	case 0x003C: return "ACP";
+	case 0x0040: return "GC";
+	case 0x0044: return "AUDIO_PKT_CTRL2";
+	case 0x0048: return "ISRC1_0";
+	case 0x004C: return "ISRC1_1";
+	case 0x0050: return "ISRC1_2";
+	case 0x0054: return "ISRC1_3";
+	case 0x0058: return "ISRC1_4";
+	case 0x005C: return "ISRC2_0";
+	case 0x0060: return "ISRC2_1";
+	case 0x0064: return "ISRC2_2";
+	case 0x0068: return "ISRC2_3";
+	case 0x006C: return "AVI_INFO0";
+	case 0x0070: return "AVI_INFO1";
+	case 0x0074: return "AVI_INFO2";
+	case 0x0078: return "AVI_INFO3";
+#ifdef CONFIG_FB_MSM_HDMI_3D
+	case 0x0084: return "GENERIC0_HDR";
+	case 0x0088: return "GENERIC0_0";
+	case 0x008C: return "GENERIC0_1";
+#endif
+	case 0x00C4: return "ACR_32_0";
+	case 0x00C8: return "ACR_32_1";
+	case 0x00CC: return "ACR_44_0";
+	case 0x00D0: return "ACR_44_1";
+	case 0x00D4: return "ACR_48_0";
+	case 0x00D8: return "ACR_48_1";
+	case 0x00E4: return "AUDIO_INFO0";
+	case 0x00E8: return "AUDIO_INFO1";
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	case 0x0110: return "HDCP_CTRL";
+	case 0x0114: return "HDCP_DEBUG_CTRL";
+	case 0x0118: return "HDCP_INT_CTRL";
+	case 0x011C: return "HDCP_LINK0_STATUS";
+	case 0x012C: return "HDCP_ENTROPY_CTRL0";
+	case 0x0130: return "HDCP_RESET";
+	case 0x0134: return "HDCP_RCVPORT_DATA0";
+	case 0x0138: return "HDCP_RCVPORT_DATA1";
+	case 0x013C: return "HDCP_RCVPORT_DATA2";
+	case 0x0144: return "HDCP_RCVPORT_DATA3";
+	case 0x0148: return "HDCP_RCVPORT_DATA4";
+	case 0x014C: return "HDCP_RCVPORT_DATA5";
+	case 0x0150: return "HDCP_RCVPORT_DATA6";
+	case 0x0168: return "HDCP_RCVPORT_DATA12";
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+	case 0x01D0: return "AUDIO_CFG";
+	case 0x0208: return "USEC_REFTIMER";
+	case 0x020C: return "DDC_CTRL";
+	case 0x0214: return "DDC_INT_CTRL";
+	case 0x0218: return "DDC_SW_STATUS";
+	case 0x021C: return "DDC_HW_STATUS";
+	case 0x0220: return "DDC_SPEED";
+	case 0x0224: return "DDC_SETUP";
+	case 0x0228: return "DDC_TRANS0";
+	case 0x022C: return "DDC_TRANS1";
+	case 0x0238: return "DDC_DATA";
+	case 0x0250: return "HPD_INT_STATUS";
+	case 0x0254: return "HPD_INT_CTRL";
+	case 0x0258: return "HPD_CTRL";
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	case 0x025C: return "HDCP_ENTROPY_CTRL1";
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+	case 0x027C: return "DDC_REF";
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	case 0x0284: return "HDCP_SW_UPPER_AKSV";
+	case 0x0288: return "HDCP_SW_LOWER_AKSV";
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+	case 0x02B4: return "ACTIVE_H";
+	case 0x02B8: return "ACTIVE_V";
+	case 0x02BC: return "ACTIVE_V_F2";
+	case 0x02C0: return "TOTAL";
+	case 0x02C4: return "V_TOTAL_F2";
+	case 0x02C8: return "FRAME_CTRL";
+	case 0x02CC: return "AUD_INT";
+	case 0x0300: return "PHY_REG0";
+	case 0x0304: return "PHY_REG1";
+	case 0x0308: return "PHY_REG2";
+	case 0x030C: return "PHY_REG3";
+	case 0x0310: return "PHY_REG4";
+	case 0x0314: return "PHY_REG5";
+	case 0x0318: return "PHY_REG6";
+	case 0x031C: return "PHY_REG7";
+	case 0x0320: return "PHY_REG8";
+	case 0x0324: return "PHY_REG9";
+	case 0x0328: return "PHY_REG10";
+	case 0x032C: return "PHY_REG11";
+	case 0x0330: return "PHY_REG12";
+	default: return "???";
+	}
+}
+
+void hdmi_outp(uint32 offset, uint32 value)
+{
+	uint32 in_val;
+
+	outpdw(MSM_HDMI_BASE+offset, value);
+	in_val = inpdw(MSM_HDMI_BASE+offset);
+	DEV_DBG("HDMI[%04x] => %08x [%08x] %s\n",
+		offset, value, in_val, hdmi_msm_name(offset));
+}
+
+uint32 hdmi_inp(uint32 offset)
+{
+	uint32 value = inpdw(MSM_HDMI_BASE+offset);
+	DEV_DBG("HDMI[%04x] <= %08x %s\n",
+		offset, value, hdmi_msm_name(offset));
+	return value;
+}
+#endif /* DEBUG */
+
+static void hdmi_msm_turn_on(void);
+static int hdmi_msm_audio_off(void);
+static int hdmi_msm_read_edid(void);
+static void hdmi_msm_hpd_off(void);
+
+static void hdmi_msm_send_event(boolean on)
+{
+	char *envp[2];
+
+	/* QDSP OFF preceding the HPD event notification */
+	envp[0] = "HDCP_STATE=FAIL";
+	envp[1] = NULL;
+	DEV_ERR("hdmi: HDMI HPD: QDSP OFF\n");
+	kobject_uevent_env(external_common_state->uevent_kobj,
+			   KOBJ_CHANGE, envp);
+
+	if (on) {
+		/* Build EDID table */
+		hdmi_msm_read_edid();
+		switch_set_state(&external_common_state->sdev, 1);
+		DEV_INFO("Hdmi state switched to %d: %s\n",
+			external_common_state->sdev.state,  __func__);
+
+		DEV_INFO("HDMI HPD: CONNECTED: send ONLINE\n");
+		kobject_uevent(external_common_state->uevent_kobj, KOBJ_ONLINE);
+#ifndef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+		/* Send Audio for HDMI Compliance Cases*/
+		envp[0] = "HDCP_STATE=PASS";
+		envp[1] = NULL;
+		DEV_INFO("HDMI HPD: sense : send HDCP_PASS\n");
+		kobject_uevent_env(external_common_state->uevent_kobj,
+			KOBJ_CHANGE, envp);
+#endif
+	} else {
+		switch_set_state(&external_common_state->sdev, 0);
+		DEV_INFO("hdmi: Hdmi state switch to %d: %s\n",
+			external_common_state->sdev.state,  __func__);
+		DEV_INFO("hdmi: HDMI HPD: sense DISCONNECTED: send OFFLINE\n");
+		kobject_uevent(external_common_state->uevent_kobj,
+			KOBJ_OFFLINE);
+	}
+}
+
+static void hdmi_msm_hpd_state_work(struct work_struct *work)
+{
+	boolean hpd_state;
+
+	if (!hdmi_msm_state || !hdmi_msm_state->hpd_initialized ||
+		!MSM_HDMI_BASE) {
+		DEV_ERR("hdmi: %s: ignored, probe failed\n", __func__);
+		return;
+	}
+
+	mutex_lock(&hdmi_msm_state_mutex);
+	DEV_DBG("%s: Handling HPD event in the workqueue\n", __func__);
+
+	if (!hdmi_msm_state->hpd_cable_chg_detected) {
+		/* The work item got called from outside the ISR */
+		mutex_unlock(&hdmi_msm_state_mutex);
+		if (external_common_state->hpd_state) {
+			if (!external_common_state->
+					disp_mode_list.num_of_elements)
+				hdmi_msm_read_edid();
+		}
+	} else {
+		hdmi_msm_state->hpd_cable_chg_detected = FALSE;
+		mutex_unlock(&hdmi_msm_state_mutex);
+		mutex_lock(&external_common_state_hpd_mutex);
+		/*
+		 * Handle the connect event only if the cable is
+		 * still connected. This check is needed for the case
+		 * where we get a connect event followed by a disconnect
+		 * event in quick succession. In this case, there is no need
+		 * to process the connect event.
+		 */
+		if ((external_common_state->hpd_state) &&
+				!((HDMI_INP(0x0250) & 0x2) >> 1)) {
+			external_common_state->hpd_state = 0;
+			hdmi_msm_state->hpd_state_in_isr = 0;
+			mutex_unlock(&external_common_state_hpd_mutex);
+			DEV_DBG("%s: Ignoring HPD connect event\n", __func__);
+			return;
+		}
+		mutex_unlock(&external_common_state_hpd_mutex);
+		hdmi_msm_send_event(external_common_state->hpd_state);
+	}
+
+	/*
+	 * Wait for a short time before checking for
+	 * any changes in the connection status
+	 */
+	udelay(100);
+
+	mutex_lock(&external_common_state_hpd_mutex);
+	/* HPD_INT_STATUS[0x0250] */
+	hpd_state = (HDMI_INP(0x0250) & 0x2) >> 1;
+
+	if (external_common_state->hpd_state != hpd_state) {
+		external_common_state->hpd_state = hpd_state;
+		hdmi_msm_state->hpd_state_in_isr = hpd_state;
+		mutex_unlock(&external_common_state_hpd_mutex);
+		hdmi_msm_send_event(hpd_state);
+	} else {
+		mutex_unlock(&external_common_state_hpd_mutex);
+	}
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+static void hdmi_msm_cec_latch_work(struct work_struct *work)
+{
+	hdmi_msm_cec_line_latch_detect();
+}
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+static void hdcp_deauthenticate(void);
+static void hdmi_msm_hdcp_reauth_work(struct work_struct *work)
+{
+
+	/* Don't process recursive actions */
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->hdcp_activating) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		return;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+
+	/*
+	 * Reauth=>deauth, hdcp_auth
+	 * hdcp_auth=>turn_on() which calls
+	 * HDMI Core reset without informing the Audio QDSP
+	 * this can do bad things to video playback on the HDTV
+	 * Therefore, as surprising as it may sound do reauth
+	 * only if the device is HDCP-capable
+	 */
+	if (external_common_state->present_hdcp) {
+		hdcp_deauthenticate();
+		mutex_lock(&hdcp_auth_state_mutex);
+		hdmi_msm_state->reauth = TRUE;
+		mutex_unlock(&hdcp_auth_state_mutex);
+		mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
+	}
+}
+
+static void hdmi_msm_hdcp_work(struct work_struct *work)
+{
+	/* Only re-enable if cable still connected */
+	mutex_lock(&external_common_state_hpd_mutex);
+	if (external_common_state->hpd_state &&
+	    !(hdmi_msm_state->full_auth_done)) {
+		mutex_unlock(&external_common_state_hpd_mutex);
+		if (hdmi_msm_state->reauth == TRUE) {
+			DEV_DBG("%s: Starting HDCP re-authentication\n",
+					__func__);
+			hdmi_msm_turn_on();
+		} else {
+			DEV_DBG("%s: Starting HDCP authentication\n", __func__);
+			hdmi_msm_hdcp_enable();
+		}
+	} else {
+		mutex_unlock(&external_common_state_hpd_mutex);
+		DEV_DBG("%s: HDMI not connected or HDCP already active\n",
+				__func__);
+		hdmi_msm_state->reauth = FALSE;
+	}
+}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+static irqreturn_t hdmi_msm_isr(int irq, void *dev_id)
+{
+	uint32 hpd_int_status;
+	uint32 hpd_int_ctrl;
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	uint32 cec_intr_status;
+#endif
+	uint32 ddc_int_ctrl;
+	uint32 audio_int_val;
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	uint32 hdcp_int_val;
+	char *envp[2];
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+	static uint32 fifo_urun_int_occurred;
+	static uint32 sample_drop_int_occurred;
+	const uint32 occurrence_limit = 5;
+
+	if (!hdmi_msm_state || !hdmi_msm_state->hpd_initialized ||
+		!MSM_HDMI_BASE) {
+		DEV_DBG("ISR ignored, probe failed\n");
+		return IRQ_HANDLED;
+	}
+
+	/* Process HPD Interrupt */
+	/* HDMI_HPD_INT_STATUS[0x0250] */
+	hpd_int_status = HDMI_INP_ND(0x0250);
+	/* HDMI_HPD_INT_CTRL[0x0254] */
+	hpd_int_ctrl = HDMI_INP_ND(0x0254);
+	if ((hpd_int_ctrl & (1 << 2)) && (hpd_int_status & (1 << 0))) {
+		boolean cable_detected = (hpd_int_status & 2) >> 1;
+		DEV_DBG("%s: HPD IRQ, Ctrl=%04x, State=%04x\n", __func__,
+				hpd_int_ctrl, hpd_int_status);
+
+		/* Ack the interrupt */
+		HDMI_OUTP(0x0254, (hpd_int_ctrl | (1 << 0)));
+
+		mutex_lock(&external_common_state_hpd_mutex);
+		if (hdmi_msm_state->hpd_state_in_isr == cable_detected) {
+			DEV_INFO("%s: HPD has the same state. Ignoring\n",
+					__func__);
+			mutex_unlock(&external_common_state_hpd_mutex);
+		} else {
+			if (!mod_timer(&hdmi_msm_state->hpd_state_timer,
+						jiffies + HZ/2)) {
+				hdmi_msm_state->hpd_state_in_isr =
+					cable_detected;
+				hdmi_msm_state->hpd_cable_chg_detected = TRUE;
+				DEV_DBG("%s: Scheduled work to handle HPD %s\n",
+						__func__,
+						cable_detected ? "connect"
+						: "disconnect");
+			}
+
+			mutex_unlock(&external_common_state_hpd_mutex);
+			/*
+			 * HDCP Compliance 1A-01:
+			 * The Quantum Data Box 882 triggers two consecutive
+			 * HPD events very close to each other as a part of this
+			 * test which can trigger two parallel HDCP auth threads
+			 * if HDCP authentication is going on and we get ISR
+			 * then stop the authentication , rather than
+			 * reauthenticating it again
+			 */
+			if (hdmi_msm_state->hdcp_activating &&
+					!(hdmi_msm_state->full_auth_done)) {
+				DEV_DBG("%s getting hpd while authenticating\n",
+					    __func__);
+				mutex_lock(&hdcp_auth_state_mutex);
+				hdmi_msm_state->hpd_during_auth = TRUE;
+				mutex_unlock(&hdcp_auth_state_mutex);
+			}
+		}
+
+		/* Set up HPD_CTRL to sense HPD event */
+		HDMI_OUTP(0x0254, 4 | (cable_detected ? 0 : 2));
+		DEV_DBG("%s: Setting HPD_CTRL=%d\n", __func__,
+				HDMI_INP(0x0254));
+
+		return IRQ_HANDLED;
+	}
+
+	/* Process DDC Interrupts */
+	/* HDMI_DDC_INT_CTRL[0x0214] */
+	ddc_int_ctrl = HDMI_INP_ND(0x0214);
+	if ((ddc_int_ctrl & (1 << 2)) && (ddc_int_ctrl & (1 << 0))) {
+		/* SW_DONE INT occured, clr it */
+		HDMI_OUTP_ND(0x0214, ddc_int_ctrl | (1 << 1));
+		complete(&hdmi_msm_state->ddc_sw_done);
+		return IRQ_HANDLED;
+	}
+
+	/* FIFO Underrun Int is enabled */
+	/* HDMI_AUD_INT[0x02CC]
+	 *   [3] AUD_SAM_DROP_MASK [R/W]
+	 *   [2] AUD_SAM_DROP_ACK [W], AUD_SAM_DROP_INT [R]
+	 *   [1] AUD_FIFO_URUN_MASK [R/W]
+	 *   [0] AUD_FIFO_URUN_ACK [W], AUD_FIFO_URUN_INT [R] */
+	audio_int_val = HDMI_INP_ND(0x02CC);
+	if ((audio_int_val & (1 << 1)) && (audio_int_val & (1 << 0))) {
+		/* FIFO Underrun occured, clr it */
+		HDMI_OUTP(0x02CC, audio_int_val | (1 << 0));
+
+		++fifo_urun_int_occurred;
+		DEV_INFO("HDMI AUD_FIFO_URUN: %d\n", fifo_urun_int_occurred);
+
+		if (fifo_urun_int_occurred >= occurrence_limit) {
+			HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) & ~(1 << 1));
+			DEV_INFO("HDMI AUD_FIFO_URUN: INT has been disabled "
+				"by the ISR after %d occurences...\n",
+				fifo_urun_int_occurred);
+		}
+		return IRQ_HANDLED;
+	}
+
+	/* Audio Sample Drop int is enabled */
+	if ((audio_int_val & (1 << 3)) && (audio_int_val & (1 << 2))) {
+		/* Audio Sample Drop occured, clr it */
+		HDMI_OUTP(0x02CC, audio_int_val | (1 << 2));
+		DEV_DBG("%s: AUD_SAM_DROP", __func__);
+
+		++sample_drop_int_occurred;
+		if (sample_drop_int_occurred >= occurrence_limit) {
+			HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) & ~(1 << 3));
+			DEV_INFO("HDMI AUD_SAM_DROP: INT has been disabled "
+				"by the ISR after %d occurences...\n",
+				sample_drop_int_occurred);
+		}
+		return IRQ_HANDLED;
+	}
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	/* HDCP_INT_CTRL[0x0118]
+	 *    [0] AUTH_SUCCESS_INT	[R]	HDCP Authentication Success
+	 *		interrupt status
+	 *    [1] AUTH_SUCCESS_ACK	[W]	Acknowledge bit for HDCP
+	 *		Authentication Success bit - write 1 to clear
+	 *    [2] AUTH_SUCCESS_MASK	[R/W]	Mask bit for HDCP Authentication
+	 *		Success interrupt - set to 1 to enable interrupt */
+	hdcp_int_val = HDMI_INP_ND(0x0118);
+	if ((hdcp_int_val & (1 << 2)) && (hdcp_int_val & (1 << 0))) {
+		/* AUTH_SUCCESS_INT */
+		HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 1)) & ~(1 << 0));
+		DEV_INFO("HDCP: AUTH_SUCCESS_INT received\n");
+		complete_all(&hdmi_msm_state->hdcp_success_done);
+		return IRQ_HANDLED;
+	}
+	/*    [4] AUTH_FAIL_INT		[R]	HDCP Authentication Lost
+	 *		interrupt Status
+	 *    [5] AUTH_FAIL_ACK		[W]	Acknowledge bit for HDCP
+	 *		Authentication Lost bit - write 1 to clear
+	 *    [6] AUTH_FAIL_MASK	[R/W]	Mask bit fo HDCP Authentication
+	 *		Lost interrupt set to 1 to enable interrupt
+	 *    [7] AUTH_FAIL_INFO_ACK	[W]	Acknowledge bit for HDCP
+	 *		Authentication Failure Info field - write 1 to clear */
+	if ((hdcp_int_val & (1 << 6)) && (hdcp_int_val & (1 << 4))) {
+		/* AUTH_FAIL_INT */
+		/* Clear and Disable */
+		uint32 link_status = HDMI_INP_ND(0x011C);
+		HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 5))
+			& ~((1 << 6) | (1 << 4)));
+		DEV_INFO("HDCP: AUTH_FAIL_INT received, LINK0_STATUS=0x%08x\n",
+			link_status);
+		if (hdmi_msm_state->full_auth_done) {
+			switch_set_state(&external_common_state->sdev, 0);
+			DEV_INFO("Hdmi state switched to %d: %s\n",
+				external_common_state->sdev.state,  __func__);
+
+			envp[0] = "HDCP_STATE=FAIL";
+			envp[1] = NULL;
+			DEV_INFO("HDMI HPD:QDSP OFF\n");
+			kobject_uevent_env(external_common_state->uevent_kobj,
+			KOBJ_CHANGE, envp);
+
+			mutex_lock(&hdcp_auth_state_mutex);
+			hdmi_msm_state->full_auth_done = FALSE;
+			mutex_unlock(&hdcp_auth_state_mutex);
+			/* Calling reauth only when authentication
+			 * is sucessful or else we always go into
+			 * the reauth loop. Also, No need to reauthenticate
+			 * if authentication failed because of cable disconnect
+			 */
+			if (((link_status & 0xF0) >> 4) != 0x7) {
+				DEV_DBG("Reauthenticate From %s HDCP FAIL INT ",
+					__func__);
+				queue_work(hdmi_work_queue,
+				    &hdmi_msm_state->hdcp_reauth_work);
+			} else {
+				DEV_INFO("HDCP: HDMI cable disconnected\n");
+			}
+		}
+
+		/* Clear AUTH_FAIL_INFO as well */
+		HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 7)));
+		return IRQ_HANDLED;
+	}
+	/*    [8] DDC_XFER_REQ_INT	[R]	HDCP DDC Transfer Request
+	 *		interrupt status
+	 *    [9] DDC_XFER_REQ_ACK	[W]	Acknowledge bit for HDCP DDC
+	 *		Transfer Request bit - write 1 to clear
+	 *   [10] DDC_XFER_REQ_MASK	[R/W]	Mask bit for HDCP DDC Transfer
+	 *		Request interrupt - set to 1 to enable interrupt */
+	if ((hdcp_int_val & (1 << 10)) && (hdcp_int_val & (1 << 8))) {
+		/* DDC_XFER_REQ_INT */
+		HDMI_OUTP_ND(0x0118, (hdcp_int_val | (1 << 9)) & ~(1 << 8));
+		if (!(hdcp_int_val & (1 << 12)))
+			return IRQ_HANDLED;
+	}
+	/*   [12] DDC_XFER_DONE_INT	[R]	HDCP DDC Transfer done interrupt
+	 *		status
+	 *   [13] DDC_XFER_DONE_ACK	[W]	Acknowledge bit for HDCP DDC
+	 *		Transfer done bit - write 1 to clear
+	 *   [14] DDC_XFER_DONE_MASK	[R/W]	Mask bit for HDCP DDC Transfer
+	 *		done interrupt - set to 1 to enable interrupt */
+	if ((hdcp_int_val & (1 << 14)) && (hdcp_int_val & (1 << 12))) {
+		/* DDC_XFER_DONE_INT */
+		HDMI_OUTP_ND(0x0118, (hdcp_int_val | (1 << 13)) & ~(1 << 12));
+		DEV_INFO("HDCP: DDC_XFER_DONE received\n");
+		return IRQ_HANDLED;
+	}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	/* Process CEC Interrupt */
+	/* HDMI_MSM_CEC_INT[0x029C] */
+	cec_intr_status = HDMI_INP_ND(0x029C);
+
+	DEV_DBG("cec interrupt status is [%u]\n", cec_intr_status);
+
+	if (HDMI_MSM_CEC_FRAME_WR_SUCCESS(cec_intr_status)) {
+		DEV_DBG("CEC_IRQ_FRAME_WR_DONE\n");
+		HDMI_OUTP(0x029C, cec_intr_status |
+			HDMI_MSM_CEC_INT_FRAME_WR_DONE_ACK);
+		mutex_lock(&hdmi_msm_state_mutex);
+		hdmi_msm_state->cec_frame_wr_status |= CEC_STATUS_WR_DONE;
+		hdmi_msm_state->first_monitor = 0;
+		del_timer(&hdmi_msm_state->cec_read_timer);
+		mutex_unlock(&hdmi_msm_state_mutex);
+		complete(&hdmi_msm_state->cec_frame_wr_done);
+		return IRQ_HANDLED;
+	}
+	if ((cec_intr_status & (1 << 2)) && (cec_intr_status & (1 << 3))) {
+		DEV_DBG("CEC_IRQ_FRAME_ERROR\n");
+#ifdef TOGGLE_CEC_HARDWARE_FSM
+		/* Toggle CEC hardware FSM */
+		HDMI_OUTP(0x028C, 0x0);
+		HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+#endif
+		HDMI_OUTP(0x029C, cec_intr_status);
+		mutex_lock(&hdmi_msm_state_mutex);
+		hdmi_msm_state->first_monitor = 0;
+		del_timer(&hdmi_msm_state->cec_read_timer);
+		hdmi_msm_state->cec_frame_wr_status |= CEC_STATUS_WR_ERROR;
+		mutex_unlock(&hdmi_msm_state_mutex);
+		complete(&hdmi_msm_state->cec_frame_wr_done);
+		return IRQ_HANDLED;
+	}
+
+	if ((cec_intr_status & (1 << 4)) && (cec_intr_status & (1 << 5))) {
+		DEV_DBG("CEC_IRQ_MONITOR\n");
+		HDMI_OUTP(0x029C, cec_intr_status |
+			  HDMI_MSM_CEC_INT_MONITOR_ACK);
+
+		/*
+		 * CECT 9-5-1
+		 * On the first occassion start a timer
+		 * for few hundred ms, if it expires then
+		 * reset the CEC block else go on with
+		 * frame transactions as usual.
+		 * Below adds hdmi_msm_cec_msg_recv() as an
+		 * item into the work queue instead of running in
+		 * interrupt context
+		 */
+		mutex_lock(&hdmi_msm_state_mutex);
+		if (hdmi_msm_state->first_monitor == 0) {
+			/* This timer might have to be changed
+			 * worst case theoritical =
+			 * 16 bytes * 8 * 2.7msec = 346 msec
+			 */
+			mod_timer(&hdmi_msm_state->cec_read_timer,
+					jiffies + HZ/2);
+			hdmi_msm_state->first_monitor = 1;
+		}
+		mutex_unlock(&hdmi_msm_state_mutex);
+		return IRQ_HANDLED;
+	}
+
+	if ((cec_intr_status & (1 << 6)) && (cec_intr_status & (1 << 7))) {
+		DEV_DBG("CEC_IRQ_FRAME_RD_DONE\n");
+
+		mutex_lock(&hdmi_msm_state_mutex);
+		hdmi_msm_state->first_monitor = 0;
+		del_timer(&hdmi_msm_state->cec_read_timer);
+		mutex_unlock(&hdmi_msm_state_mutex);
+		HDMI_OUTP(0x029C, cec_intr_status |
+			HDMI_MSM_CEC_INT_FRAME_RD_DONE_ACK);
+		hdmi_msm_cec_msg_recv();
+
+#ifdef TOGGLE_CEC_HARDWARE_FSM
+		if (!msg_send_complete)
+			msg_recv_complete = FALSE;
+		else {
+			/* Toggle CEC hardware FSM */
+			HDMI_OUTP(0x028C, 0x0);
+			HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+		}
+#else
+		HDMI_OUTP(0x028C, 0x0);
+		HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+#endif
+
+		return IRQ_HANDLED;
+	}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+
+	DEV_DBG("%s: HPD<Ctrl=%04x, State=%04x>, ddc_int_ctrl=%04x, "
+		"aud_int=%04x, cec_intr_status=%04x\n", __func__, hpd_int_ctrl,
+		hpd_int_status, ddc_int_ctrl, audio_int_val,
+		HDMI_INP_ND(0x029C));
+
+	return IRQ_HANDLED;
+}
+
+static int check_hdmi_features(void)
+{
+	/* RAW_FEAT_CONFIG_ROW0_LSB */
+	uint32 val = inpdw(QFPROM_BASE + 0x0238);
+	/* HDMI_DISABLE */
+	boolean hdmi_disabled = (val & 0x00200000) >> 21;
+	/* HDCP_DISABLE */
+	boolean hdcp_disabled = (val & 0x00400000) >> 22;
+
+	DEV_DBG("Features <val:0x%08x, HDMI:%s, HDCP:%s>\n", val,
+		hdmi_disabled ? "OFF" : "ON", hdcp_disabled ? "OFF" : "ON");
+	if (hdmi_disabled) {
+		DEV_ERR("ERROR: HDMI disabled\n");
+		return -ENODEV;
+	}
+
+	if (hdcp_disabled)
+		DEV_WARN("WARNING: HDCP disabled\n");
+
+	return 0;
+}
+
+static boolean hdmi_msm_has_hdcp(void)
+{
+	/* RAW_FEAT_CONFIG_ROW0_LSB, HDCP_DISABLE */
+	return (inpdw(QFPROM_BASE + 0x0238) & 0x00400000) ? FALSE : TRUE;
+}
+
+static boolean hdmi_msm_is_power_on(void)
+{
+	/* HDMI_CTRL, ENABLE */
+	return (HDMI_INP_ND(0x0000) & 0x00000001) ? TRUE : FALSE;
+}
+
+/* 1.2.1.2.1 DVI Operation
+ * HDMI compliance requires the HDMI core to support DVI as well. The
+ * HDMI core also supports DVI. In DVI operation there are no preambles
+ * and guardbands transmitted. THe TMDS encoding of video data remains
+ * the same as HDMI. There are no VBI or audio packets transmitted. In
+ * order to enable DVI mode in HDMI core, HDMI_DVI_SEL field of
+ * HDMI_CTRL register needs to be programmed to 0. */
+static boolean hdmi_msm_is_dvi_mode(void)
+{
+	/* HDMI_CTRL, HDMI_DVI_SEL */
+	return (HDMI_INP_ND(0x0000) & 0x00000002) ? FALSE : TRUE;
+}
+
+void hdmi_msm_set_mode(boolean power_on)
+{
+	uint32 reg_val = 0;
+	if (power_on) {
+		/* ENABLE */
+		reg_val |= 0x00000001; /* Enable the block */
+		if (external_common_state->hdmi_sink == 0) {
+			/* HDMI_DVI_SEL */
+			reg_val |= 0x00000002;
+			if (external_common_state->present_hdcp)
+				/* HDMI Encryption */
+				reg_val |= 0x00000004;
+			/* HDMI_CTRL */
+			HDMI_OUTP(0x0000, reg_val);
+			/* HDMI_DVI_SEL */
+			reg_val &= ~0x00000002;
+		} else {
+			if (external_common_state->present_hdcp)
+				/* HDMI_Encryption_ON */
+				reg_val |= 0x00000006;
+			else
+				reg_val |= 0x00000002;
+		}
+	} else
+		reg_val = 0x00000002;
+
+	/* HDMI_CTRL */
+	HDMI_OUTP(0x0000, reg_val);
+	DEV_DBG("HDMI Core: %s, HDMI_CTRL=0x%08x\n",
+			power_on ? "Enable" : "Disable", reg_val);
+}
+
+static void msm_hdmi_init_ddc(void)
+{
+	/* 0x0220 HDMI_DDC_SPEED
+	   [31:16] PRESCALE prescale = (m * xtal_frequency) /
+		(desired_i2c_speed), where m is multiply
+		factor, default: m = 1
+	   [1:0]   THRESHOLD Select threshold to use to determine whether value
+		sampled on SDA is a 1 or 0. Specified in terms of the ratio
+		between the number of sampled ones and the total number of times
+		SDA is sampled.
+		* 0x0: >0
+		* 0x1: 1/4 of total samples
+		* 0x2: 1/2 of total samples
+		* 0x3: 3/4 of total samples */
+	/* Configure the Pre-Scale multiplier
+	 * Configure the Threshold */
+	HDMI_OUTP_ND(0x0220, (10 << 16) | (2 << 0));
+
+	/*
+	 * 0x0224 HDMI_DDC_SETUP
+	 * Setting 31:24 bits : Time units to wait before timeout
+	 * when clock is being stalled by external sink device
+	 */
+	HDMI_OUTP_ND(0x0224, 0xff000000);
+
+	/* 0x027C HDMI_DDC_REF
+	   [6] REFTIMER_ENABLE	Enable the timer
+		* 0: Disable
+		* 1: Enable
+	   [15:0] REFTIMER	Value to set the register in order to generate
+		DDC strobe. This register counts on HDCP application clock */
+	/* Enable reference timer
+	 * 27 micro-seconds */
+	HDMI_OUTP_ND(0x027C, (1 << 16) | (27 << 0));
+}
+
+static int hdmi_msm_ddc_clear_irq(const char *what)
+{
+	const uint32 time_out = 0xFFFF;
+	uint32 time_out_count, reg_val;
+
+	/* clear pending and enable interrupt */
+	time_out_count = time_out;
+	do {
+		--time_out_count;
+		/* HDMI_DDC_INT_CTRL[0x0214]
+		   [2] SW_DONE_MK Mask bit for SW_DONE_INT. Set to 1 to enable
+		       interrupt.
+		   [1] SW_DONE_ACK WRITE ONLY. Acknowledge bit for SW_DONE_INT.
+		       Write 1 to clear interrupt.
+		   [0] SW_DONE_INT READ ONLY. SW_DONE interrupt status */
+		/* Clear and Enable DDC interrupt */
+		/* Write */
+		HDMI_OUTP_ND(0x0214, (1 << 2) | (1 << 1));
+		/* Read back */
+		reg_val = HDMI_INP_ND(0x0214);
+	} while ((reg_val & 0x1) && time_out_count);
+	if (!time_out_count) {
+		DEV_ERR("%s[%s]: timedout\n", __func__, what);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+static int hdmi_msm_ddc_write(uint32 dev_addr, uint32 offset,
+	const uint8 *data_buf, uint32 data_len, const char *what)
+{
+	uint32 reg_val, ndx;
+	int status = 0, retry = 10;
+	uint32 time_out_count;
+
+	if (NULL == data_buf) {
+		status = -EINVAL;
+		DEV_ERR("%s[%s]: invalid input paramter\n", __func__, what);
+		goto error;
+	}
+
+again:
+	status = hdmi_msm_ddc_clear_irq(what);
+	if (status)
+		goto error;
+
+	/* Ensure Device Address has LSB set to 0 to indicate Slave addr read */
+	dev_addr &= 0xFE;
+
+	/* 0x0238 HDMI_DDC_DATA
+	   [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to
+		1 while writing HDMI_DDC_DATA.
+	   [23:16] INDEX Use to set index into DDC buffer for next read or
+		current write, or to read index of current read or next write.
+		Writable only when INDEX_WRITE=1.
+	   [15:8] DATA Use to fill or read the DDC buffer
+	   [0] DATA_RW Select whether buffer access will be a read or write.
+		For writes, address auto-increments on write to HDMI_DDC_DATA.
+		For reads, address autoincrements on reads to HDMI_DDC_DATA.
+		* 0: Write
+		* 1: Read */
+
+	/* 1. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #1
+	 *    DATA_RW = 0x1 (write)
+	 *    DATA = linkAddress (primary link address and writing)
+	 *    INDEX = 0x0 (initial offset into buffer)
+	 *    INDEX_WRITE = 0x1 (setting initial offset) */
+	HDMI_OUTP_ND(0x0238, (0x1UL << 31) | (dev_addr << 8));
+
+	/* 2. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #2
+	 *    DATA_RW = 0x0 (write)
+	 *    DATA = offsetAddress
+	 *    INDEX = 0x0
+	 *    INDEX_WRITE = 0x0 (auto-increment by hardware) */
+	HDMI_OUTP_ND(0x0238, offset << 8);
+
+	/* 3. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #3
+	 *    DATA_RW = 0x0 (write)
+	 *    DATA = data_buf[ndx]
+	 *    INDEX = 0x0
+	 *    INDEX_WRITE = 0x0 (auto-increment by hardware) */
+	for (ndx = 0; ndx < data_len; ++ndx)
+		HDMI_OUTP_ND(0x0238, ((uint32)data_buf[ndx]) << 8);
+
+	/* Data setup is complete, now setup the transaction characteristics */
+
+	/* 0x0228 HDMI_DDC_TRANS0
+	   [23:16] CNT0 Byte count for first transaction (excluding the first
+		byte, which is usually the address).
+	   [13] STOP0 Determines whether a stop bit will be sent after the first
+		transaction
+		* 0: NO STOP
+		* 1: STOP
+	   [12] START0 Determines whether a start bit will be sent before the
+		first transaction
+		* 0: NO START
+		* 1: START
+	   [8] STOP_ON_NACK0 Determines whether the current transfer will stop
+		if a NACK is received during the first transaction (current
+		transaction always stops).
+		* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+		* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+	   [0] RW0 Read/write indicator for first transaction - set to 0 for
+		write, 1 for read. This bit only controls HDMI_DDC behaviour -
+		the R/W bit in the transaction is programmed into the DDC buffer
+		as the LSB of the address byte.
+		* 0: WRITE
+		* 1: READ */
+
+	/* 4. Write to HDMI_I2C_TRANSACTION0 with the following fields set in
+	      order to handle characteristics of portion #1 and portion #2
+	 *    RW0 = 0x0 (write)
+	 *    START0 = 0x1 (insert START bit)
+	 *    STOP0 = 0x0 (do NOT insert STOP bit)
+	 *    CNT0 = 0x1 (single byte transaction excluding address) */
+	HDMI_OUTP_ND(0x0228, (1 << 12) | (1 << 16));
+
+	/* 0x022C HDMI_DDC_TRANS1
+	  [23:16] CNT1 Byte count for second transaction (excluding the first
+		byte, which is usually the address).
+	  [13] STOP1 Determines whether a stop bit will be sent after the second
+		transaction
+		* 0: NO STOP
+		* 1: STOP
+	  [12] START1 Determines whether a start bit will be sent before the
+		second transaction
+		* 0: NO START
+		* 1: START
+	  [8] STOP_ON_NACK1 Determines whether the current transfer will stop if
+		a NACK is received during the second transaction (current
+		transaction always stops).
+		* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+		* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+	  [0] RW1 Read/write indicator for second transaction - set to 0 for
+		write, 1 for read. This bit only controls HDMI_DDC behaviour -
+		the R/W bit in the transaction is programmed into the DDC buffer
+		as the LSB of the address byte.
+		* 0: WRITE
+		* 1: READ */
+
+	/* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
+	      order to handle characteristics of portion #3
+	 *    RW1 = 0x1 (read)
+	 *    START1 = 0x1 (insert START bit)
+	 *    STOP1 = 0x1 (insert STOP bit)
+	 *    CNT1 = data_len   (0xN (write N bytes of data))
+	 *    Byte count for second transition (excluding the first
+	 *    Byte which is usually the address) */
+	HDMI_OUTP_ND(0x022C, (1 << 13) | ((data_len-1) << 16));
+
+	/* Trigger the I2C transfer */
+	/* 0x020C HDMI_DDC_CTRL
+	   [21:20] TRANSACTION_CNT
+		Number of transactions to be done in current transfer.
+		* 0x0: transaction0 only
+		* 0x1: transaction0, transaction1
+		* 0x2: transaction0, transaction1, transaction2
+		* 0x3: transaction0, transaction1, transaction2, transaction3
+	   [3] SW_STATUS_RESET
+		Write 1 to reset HDMI_DDC_SW_STATUS flags, will reset SW_DONE,
+		ABORTED, TIMEOUT, SW_INTERRUPTED, BUFFER_OVERFLOW,
+		STOPPED_ON_NACK, NACK0, NACK1, NACK2, NACK3
+	   [2] SEND_RESET Set to 1 to send reset sequence (9 clocks with no
+		data) at start of transfer.  This sequence is sent after GO is
+		written to 1, before the first transaction only.
+	   [1] SOFT_RESET Write 1 to reset DDC controller
+	   [0] GO WRITE ONLY. Write 1 to start DDC transfer. */
+
+	/* 6. Write to HDMI_I2C_CONTROL to kick off the hardware.
+	 *    Note that NOTHING has been transmitted on the DDC lines up to this
+	 *    point.
+	 *    TRANSACTION_CNT = 0x1 (execute transaction0 followed by
+	 *    transaction1)
+	 *    GO = 0x1 (kicks off hardware) */
+	INIT_COMPLETION(hdmi_msm_state->ddc_sw_done);
+	HDMI_OUTP_ND(0x020C, (1 << 0) | (1 << 20));
+
+	time_out_count = wait_for_completion_interruptible_timeout(
+		&hdmi_msm_state->ddc_sw_done, HZ/2);
+	HDMI_OUTP_ND(0x0214, 0x2);
+	if (!time_out_count) {
+		if (retry-- > 0) {
+			DEV_INFO("%s[%s]: failed timout, retry=%d\n", __func__,
+				what, retry);
+			goto again;
+		}
+		status = -ETIMEDOUT;
+		DEV_ERR("%s[%s]: timedout, DDC SW Status=%08x, HW "
+			"Status=%08x, Int Ctrl=%08x\n", __func__, what,
+			HDMI_INP_ND(0x0218), HDMI_INP_ND(0x021C),
+			HDMI_INP_ND(0x0214));
+		goto error;
+	}
+
+	/* Read DDC status */
+	reg_val = HDMI_INP_ND(0x0218);
+	reg_val &= 0x00001000 | 0x00002000 | 0x00004000 | 0x00008000;
+
+	/* Check if any NACK occurred */
+	if (reg_val) {
+		if (retry > 1)
+			HDMI_OUTP_ND(0x020C, BIT(3)); /* SW_STATUS_RESET */
+		else
+			HDMI_OUTP_ND(0x020C, BIT(1)); /* SOFT_RESET */
+		if (retry-- > 0) {
+			DEV_DBG("%s[%s]: failed NACK=%08x, retry=%d\n",
+				__func__, what, reg_val, retry);
+			msleep(100);
+			goto again;
+		}
+		status = -EIO;
+		DEV_ERR("%s[%s]: failed NACK: %08x\n", __func__, what, reg_val);
+		goto error;
+	}
+
+	DEV_DBG("%s[%s] success\n", __func__, what);
+
+error:
+	return status;
+}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+static int hdmi_msm_ddc_read_retry(uint32 dev_addr, uint32 offset,
+	uint8 *data_buf, uint32 data_len, uint32 request_len, int retry,
+	const char *what)
+{
+	uint32 reg_val, ndx;
+	int status = 0;
+	uint32 time_out_count;
+	int log_retry_fail = retry != 1;
+
+	if (NULL == data_buf) {
+		status = -EINVAL;
+		DEV_ERR("%s: invalid input paramter\n", __func__);
+		goto error;
+	}
+
+again:
+	status = hdmi_msm_ddc_clear_irq(what);
+	if (status)
+		goto error;
+
+	/* Ensure Device Address has LSB set to 0 to indicate Slave addr read */
+	dev_addr &= 0xFE;
+
+	/* 0x0238 HDMI_DDC_DATA
+	   [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to
+		1 while writing HDMI_DDC_DATA.
+	   [23:16] INDEX Use to set index into DDC buffer for next read or
+		current write, or to read index of current read or next write.
+		Writable only when INDEX_WRITE=1.
+	   [15:8] DATA Use to fill or read the DDC buffer
+	   [0] DATA_RW Select whether buffer access will be a read or write.
+		For writes, address auto-increments on write to HDMI_DDC_DATA.
+		For reads, address autoincrements on reads to HDMI_DDC_DATA.
+		* 0: Write
+		* 1: Read */
+
+	/* 1. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #1
+	 *    DATA_RW = 0x0 (write)
+	 *    DATA = linkAddress (primary link address and writing)
+	 *    INDEX = 0x0 (initial offset into buffer)
+	 *    INDEX_WRITE = 0x1 (setting initial offset) */
+	HDMI_OUTP_ND(0x0238, (0x1UL << 31) | (dev_addr << 8));
+
+	/* 2. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #2
+	 *    DATA_RW = 0x0 (write)
+	 *    DATA = offsetAddress
+	 *    INDEX = 0x0
+	 *    INDEX_WRITE = 0x0 (auto-increment by hardware) */
+	HDMI_OUTP_ND(0x0238, offset << 8);
+
+	/* 3. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #3
+	 *    DATA_RW = 0x0 (write)
+	 *    DATA = linkAddress + 1 (primary link address 0x74 and reading)
+	 *    INDEX = 0x0
+	 *    INDEX_WRITE = 0x0 (auto-increment by hardware) */
+	HDMI_OUTP_ND(0x0238, (dev_addr | 1) << 8);
+
+	/* Data setup is complete, now setup the transaction characteristics */
+
+	/* 0x0228 HDMI_DDC_TRANS0
+	   [23:16] CNT0 Byte count for first transaction (excluding the first
+		byte, which is usually the address).
+	   [13] STOP0 Determines whether a stop bit will be sent after the first
+		transaction
+		* 0: NO STOP
+		* 1: STOP
+	   [12] START0 Determines whether a start bit will be sent before the
+		first transaction
+		* 0: NO START
+		* 1: START
+	   [8] STOP_ON_NACK0 Determines whether the current transfer will stop
+		if a NACK is received during the first transaction (current
+		transaction always stops).
+		* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+		* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+	   [0] RW0 Read/write indicator for first transaction - set to 0 for
+		write, 1 for read. This bit only controls HDMI_DDC behaviour -
+		the R/W bit in the transaction is programmed into the DDC buffer
+		as the LSB of the address byte.
+		* 0: WRITE
+		* 1: READ */
+
+	/* 4. Write to HDMI_I2C_TRANSACTION0 with the following fields set in
+	      order to handle characteristics of portion #1 and portion #2
+	 *    RW0 = 0x0 (write)
+	 *    START0 = 0x1 (insert START bit)
+	 *    STOP0 = 0x0 (do NOT insert STOP bit)
+	 *    CNT0 = 0x1 (single byte transaction excluding address) */
+	HDMI_OUTP_ND(0x0228, (1 << 12) | (1 << 16));
+
+	/* 0x022C HDMI_DDC_TRANS1
+	  [23:16] CNT1 Byte count for second transaction (excluding the first
+		byte, which is usually the address).
+	  [13] STOP1 Determines whether a stop bit will be sent after the second
+		transaction
+		* 0: NO STOP
+		* 1: STOP
+	  [12] START1 Determines whether a start bit will be sent before the
+		second transaction
+		* 0: NO START
+		* 1: START
+	  [8] STOP_ON_NACK1 Determines whether the current transfer will stop if
+		a NACK is received during the second transaction (current
+		transaction always stops).
+		* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+		* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+	  [0] RW1 Read/write indicator for second transaction - set to 0 for
+		write, 1 for read. This bit only controls HDMI_DDC behaviour -
+		the R/W bit in the transaction is programmed into the DDC buffer
+		as the LSB of the address byte.
+		* 0: WRITE
+		* 1: READ */
+
+	/* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
+	      order to handle characteristics of portion #3
+	 *    RW1 = 0x1 (read)
+	 *    START1 = 0x1 (insert START bit)
+	 *    STOP1 = 0x1 (insert STOP bit)
+	 *    CNT1 = data_len   (it's 128 (0x80) for a blk read) */
+	HDMI_OUTP_ND(0x022C, 1 | (1 << 12) | (1 << 13) | (request_len << 16));
+
+	/* Trigger the I2C transfer */
+	/* 0x020C HDMI_DDC_CTRL
+	   [21:20] TRANSACTION_CNT
+		Number of transactions to be done in current transfer.
+		* 0x0: transaction0 only
+		* 0x1: transaction0, transaction1
+		* 0x2: transaction0, transaction1, transaction2
+		* 0x3: transaction0, transaction1, transaction2, transaction3
+	   [3] SW_STATUS_RESET
+		Write 1 to reset HDMI_DDC_SW_STATUS flags, will reset SW_DONE,
+		ABORTED, TIMEOUT, SW_INTERRUPTED, BUFFER_OVERFLOW,
+		STOPPED_ON_NACK, NACK0, NACK1, NACK2, NACK3
+	   [2] SEND_RESET Set to 1 to send reset sequence (9 clocks with no
+		data) at start of transfer.  This sequence is sent after GO is
+		written to 1, before the first transaction only.
+	   [1] SOFT_RESET Write 1 to reset DDC controller
+	   [0] GO WRITE ONLY. Write 1 to start DDC transfer. */
+
+	/* 6. Write to HDMI_I2C_CONTROL to kick off the hardware.
+	 *    Note that NOTHING has been transmitted on the DDC lines up to this
+	 *    point.
+	 *    TRANSACTION_CNT = 0x1 (execute transaction0 followed by
+	 *    transaction1)
+	 *    SEND_RESET = Set to 1 to send reset sequence
+	 *    GO = 0x1 (kicks off hardware) */
+	INIT_COMPLETION(hdmi_msm_state->ddc_sw_done);
+	HDMI_OUTP_ND(0x020C, (1 << 0) | (1 << 20));
+
+	time_out_count = wait_for_completion_interruptible_timeout(
+		&hdmi_msm_state->ddc_sw_done, HZ/2);
+	HDMI_OUTP_ND(0x0214, 0x2);
+	if (!time_out_count) {
+		if (retry-- > 0) {
+			DEV_INFO("%s: failed timout, retry=%d\n", __func__,
+				retry);
+			goto again;
+		}
+		status = -ETIMEDOUT;
+		DEV_ERR("%s: timedout(7), DDC SW Status=%08x, HW "
+			"Status=%08x, Int Ctrl=%08x\n", __func__,
+			HDMI_INP(0x0218), HDMI_INP(0x021C), HDMI_INP(0x0214));
+		goto error;
+	}
+
+	/* Read DDC status */
+	reg_val = HDMI_INP_ND(0x0218);
+	reg_val &= 0x00001000 | 0x00002000 | 0x00004000 | 0x00008000;
+
+	/* Check if any NACK occurred */
+	if (reg_val) {
+		HDMI_OUTP_ND(0x020C, BIT(3)); /* SW_STATUS_RESET */
+		if (retry == 1)
+			HDMI_OUTP_ND(0x020C, BIT(1)); /* SOFT_RESET */
+		if (retry-- > 0) {
+			DEV_DBG("%s(%s): failed NACK=0x%08x, retry=%d, "
+				"dev-addr=0x%02x, offset=0x%02x, "
+				"length=%d\n", __func__, what,
+				reg_val, retry, dev_addr,
+				offset, data_len);
+			goto again;
+		}
+		status = -EIO;
+		if (log_retry_fail)
+			DEV_ERR("%s(%s): failed NACK=0x%08x, dev-addr=0x%02x, "
+				"offset=0x%02x, length=%d\n", __func__, what,
+				reg_val, dev_addr, offset, data_len);
+		goto error;
+	}
+
+	/* 0x0238 HDMI_DDC_DATA
+	   [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to 1
+		while writing HDMI_DDC_DATA.
+	   [23:16] INDEX Use to set index into DDC buffer for next read or
+		current write, or to read index of current read or next write.
+		Writable only when INDEX_WRITE=1.
+	   [15:8] DATA Use to fill or read the DDC buffer
+	   [0] DATA_RW Select whether buffer access will be a read or write.
+		For writes, address auto-increments on write to HDMI_DDC_DATA.
+		For reads, address autoincrements on reads to HDMI_DDC_DATA.
+		* 0: Write
+		* 1: Read */
+
+	/* 8. ALL data is now available and waiting in the DDC buffer.
+	 *    Read HDMI_I2C_DATA with the following fields set
+	 *    RW = 0x1 (read)
+	 *    DATA = BCAPS (this is field where data is pulled from)
+	 *    INDEX = 0x3 (where the data has been placed in buffer by hardware)
+	 *    INDEX_WRITE = 0x1 (explicitly define offset) */
+	/* Write this data to DDC buffer */
+	HDMI_OUTP_ND(0x0238, 0x1 | (3 << 16) | (1 << 31));
+
+	/* Discard first byte */
+	HDMI_INP_ND(0x0238);
+	for (ndx = 0; ndx < data_len; ++ndx) {
+		reg_val = HDMI_INP_ND(0x0238);
+		data_buf[ndx] = (uint8) ((reg_val & 0x0000FF00) >> 8);
+	}
+
+	DEV_DBG("%s[%s] success\n", __func__, what);
+
+error:
+	return status;
+}
+
+static int hdmi_msm_ddc_read_edid_seg(uint32 dev_addr, uint32 offset,
+	uint8 *data_buf, uint32 data_len, uint32 request_len, int retry,
+	const char *what)
+{
+	uint32 reg_val, ndx;
+	int status = 0;
+	uint32 time_out_count;
+	int log_retry_fail = retry != 1;
+	int seg_addr = 0x60, seg_num = 0x01;
+
+	if (NULL == data_buf) {
+		status = -EINVAL;
+		DEV_ERR("%s: invalid input paramter\n", __func__);
+		goto error;
+	}
+
+again:
+	status = hdmi_msm_ddc_clear_irq(what);
+	if (status)
+		goto error;
+
+	/* Ensure Device Address has LSB set to 0 to indicate Slave addr read */
+	dev_addr &= 0xFE;
+
+	/* 0x0238 HDMI_DDC_DATA
+	   [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to
+		1 while writing HDMI_DDC_DATA.
+	   [23:16] INDEX Use to set index into DDC buffer for next read or
+		current write, or to read index of current read or next write.
+		Writable only when INDEX_WRITE=1.
+	   [15:8] DATA Use to fill or read the DDC buffer
+	   [0] DATA_RW Select whether buffer access will be a read or write.
+		For writes, address auto-increments on write to HDMI_DDC_DATA.
+		For reads, address autoincrements on reads to HDMI_DDC_DATA.
+		* 0: Write
+		* 1: Read */
+
+	/* 1. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #1
+	 *    DATA_RW = 0x0 (write)
+	 *    DATA = linkAddress (primary link address and writing)
+	 *    INDEX = 0x0 (initial offset into buffer)
+	 *    INDEX_WRITE = 0x1 (setting initial offset) */
+	HDMI_OUTP_ND(0x0238, (0x1UL << 31) | (seg_addr << 8));
+
+	/* 2. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #2
+	 *    DATA_RW = 0x0 (write)
+	 *    DATA = offsetAddress
+	 *    INDEX = 0x0
+	 *    INDEX_WRITE = 0x0 (auto-increment by hardware) */
+	HDMI_OUTP_ND(0x0238, seg_num << 8);
+
+	/* 3. Write to HDMI_I2C_DATA with the following fields set in order to
+	 *    handle portion #3
+	 *    DATA_RW = 0x0 (write)
+	 *    DATA = linkAddress + 1 (primary link address 0x74 and reading)
+	 *    INDEX = 0x0
+	 *    INDEX_WRITE = 0x0 (auto-increment by hardware) */
+	HDMI_OUTP_ND(0x0238, dev_addr << 8);
+	HDMI_OUTP_ND(0x0238, offset << 8);
+	HDMI_OUTP_ND(0x0238, (dev_addr | 1) << 8);
+
+	/* Data setup is complete, now setup the transaction characteristics */
+
+	/* 0x0228 HDMI_DDC_TRANS0
+	   [23:16] CNT0 Byte count for first transaction (excluding the first
+		byte, which is usually the address).
+	   [13] STOP0 Determines whether a stop bit will be sent after the first
+		transaction
+		* 0: NO STOP
+		* 1: STOP
+	   [12] START0 Determines whether a start bit will be sent before the
+		first transaction
+		* 0: NO START
+		* 1: START
+	   [8] STOP_ON_NACK0 Determines whether the current transfer will stop
+		if a NACK is received during the first transaction (current
+		transaction always stops).
+		* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+		* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+	   [0] RW0 Read/write indicator for first transaction - set to 0 for
+		write, 1 for read. This bit only controls HDMI_DDC behaviour -
+		the R/W bit in the transaction is programmed into the DDC buffer
+		as the LSB of the address byte.
+		* 0: WRITE
+		* 1: READ */
+
+	/* 4. Write to HDMI_I2C_TRANSACTION0 with the following fields set in
+	      order to handle characteristics of portion #1 and portion #2
+	 *    RW0 = 0x0 (write)
+	 *    START0 = 0x1 (insert START bit)
+	 *    STOP0 = 0x0 (do NOT insert STOP bit)
+	 *    CNT0 = 0x1 (single byte transaction excluding address) */
+	HDMI_OUTP_ND(0x0228, (1 << 12) | (1 << 16));
+
+	/* 0x022C HDMI_DDC_TRANS1
+	  [23:16] CNT1 Byte count for second transaction (excluding the first
+		byte, which is usually the address).
+	  [13] STOP1 Determines whether a stop bit will be sent after the second
+		transaction
+		* 0: NO STOP
+		* 1: STOP
+	  [12] START1 Determines whether a start bit will be sent before the
+		second transaction
+		* 0: NO START
+		* 1: START
+	  [8] STOP_ON_NACK1 Determines whether the current transfer will stop if
+		a NACK is received during the second transaction (current
+		transaction always stops).
+		* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+		* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+	  [0] RW1 Read/write indicator for second transaction - set to 0 for
+		write, 1 for read. This bit only controls HDMI_DDC behaviour -
+		the R/W bit in the transaction is programmed into the DDC buffer
+		as the LSB of the address byte.
+		* 0: WRITE
+		* 1: READ */
+
+	/* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
+	      order to handle characteristics of portion #3
+	 *    RW1 = 0x1 (read)
+	 *    START1 = 0x1 (insert START bit)
+	 *    STOP1 = 0x1 (insert STOP bit)
+	 *    CNT1 = data_len   (it's 128 (0x80) for a blk read) */
+	HDMI_OUTP_ND(0x022C, (1 << 12) | (1 << 16));
+
+	/* 0x022C HDMI_DDC_TRANS2
+	  [23:16] CNT1 Byte count for second transaction (excluding the first
+		byte, which is usually the address).
+	  [13] STOP1 Determines whether a stop bit will be sent after the second
+		transaction
+		* 0: NO STOP
+		* 1: STOP
+	  [12] START1 Determines whether a start bit will be sent before the
+		second transaction
+		* 0: NO START
+		* 1: START
+	  [8] STOP_ON_NACK1 Determines whether the current transfer will stop if
+		a NACK is received during the second transaction (current
+		transaction always stops).
+		* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+		* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+	  [0] RW1 Read/write indicator for second transaction - set to 0 for
+		write, 1 for read. This bit only controls HDMI_DDC behaviour -
+		the R/W bit in the transaction is programmed into the DDC buffer
+		as the LSB of the address byte.
+		* 0: WRITE
+		* 1: READ */
+
+	/* 5. Write to HDMI_I2C_TRANSACTION1 with the following fields set in
+	      order to handle characteristics of portion #3
+	 *    RW1 = 0x1 (read)
+	 *    START1 = 0x1 (insert START bit)
+	 *    STOP1 = 0x1 (insert STOP bit)
+	 *    CNT1 = data_len   (it's 128 (0x80) for a blk read) */
+	HDMI_OUTP_ND(0x0230, 1 | (1 << 12) | (1 << 13) | (request_len << 16));
+
+	/* Trigger the I2C transfer */
+	/* 0x020C HDMI_DDC_CTRL
+	   [21:20] TRANSACTION_CNT
+		Number of transactions to be done in current transfer.
+		* 0x0: transaction0 only
+		* 0x1: transaction0, transaction1
+		* 0x2: transaction0, transaction1, transaction2
+		* 0x3: transaction0, transaction1, transaction2, transaction3
+	   [3] SW_STATUS_RESET
+		Write 1 to reset HDMI_DDC_SW_STATUS flags, will reset SW_DONE,
+		ABORTED, TIMEOUT, SW_INTERRUPTED, BUFFER_OVERFLOW,
+		STOPPED_ON_NACK, NACK0, NACK1, NACK2, NACK3
+	   [2] SEND_RESET Set to 1 to send reset sequence (9 clocks with no
+		data) at start of transfer.  This sequence is sent after GO is
+		written to 1, before the first transaction only.
+	   [1] SOFT_RESET Write 1 to reset DDC controller
+	   [0] GO WRITE ONLY. Write 1 to start DDC transfer. */
+
+	/* 6. Write to HDMI_I2C_CONTROL to kick off the hardware.
+	 *    Note that NOTHING has been transmitted on the DDC lines up to this
+	 *    point.
+	 *    TRANSACTION_CNT = 0x2 (execute transaction0 followed by
+	 *    transaction1)
+	 *    GO = 0x1 (kicks off hardware) */
+	INIT_COMPLETION(hdmi_msm_state->ddc_sw_done);
+	HDMI_OUTP_ND(0x020C, (1 << 0) | (2 << 20));
+
+	time_out_count = wait_for_completion_interruptible_timeout(
+		&hdmi_msm_state->ddc_sw_done, HZ/2);
+	HDMI_OUTP_ND(0x0214, 0x2);
+	if (!time_out_count) {
+		if (retry-- > 0) {
+			DEV_INFO("%s: failed timout, retry=%d\n", __func__,
+				retry);
+			goto again;
+		}
+		status = -ETIMEDOUT;
+		DEV_ERR("%s: timedout(7), DDC SW Status=%08x, HW "
+			"Status=%08x, Int Ctrl=%08x\n", __func__,
+			HDMI_INP(0x0218), HDMI_INP(0x021C), HDMI_INP(0x0214));
+		goto error;
+	}
+
+	/* Read DDC status */
+	reg_val = HDMI_INP_ND(0x0218);
+	reg_val &= 0x00001000 | 0x00002000 | 0x00004000 | 0x00008000;
+
+	/* Check if any NACK occurred */
+	if (reg_val) {
+		HDMI_OUTP_ND(0x020C, BIT(3)); /* SW_STATUS_RESET */
+		if (retry == 1)
+			HDMI_OUTP_ND(0x020C, BIT(1)); /* SOFT_RESET */
+		if (retry-- > 0) {
+			DEV_DBG("%s(%s): failed NACK=0x%08x, retry=%d, "
+				"dev-addr=0x%02x, offset=0x%02x, "
+				"length=%d\n", __func__, what,
+				reg_val, retry, dev_addr,
+				offset, data_len);
+			goto again;
+		}
+		status = -EIO;
+		if (log_retry_fail)
+			DEV_ERR("%s(%s): failed NACK=0x%08x, dev-addr=0x%02x, "
+				"offset=0x%02x, length=%d\n", __func__, what,
+				reg_val, dev_addr, offset, data_len);
+		goto error;
+	}
+
+	/* 0x0238 HDMI_DDC_DATA
+	   [31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to 1
+		while writing HDMI_DDC_DATA.
+	   [23:16] INDEX Use to set index into DDC buffer for next read or
+		current write, or to read index of current read or next write.
+		Writable only when INDEX_WRITE=1.
+	   [15:8] DATA Use to fill or read the DDC buffer
+	   [0] DATA_RW Select whether buffer access will be a read or write.
+		For writes, address auto-increments on write to HDMI_DDC_DATA.
+		For reads, address autoincrements on reads to HDMI_DDC_DATA.
+		* 0: Write
+		* 1: Read */
+
+	/* 8. ALL data is now available and waiting in the DDC buffer.
+	 *    Read HDMI_I2C_DATA with the following fields set
+	 *    RW = 0x1 (read)
+	 *    DATA = BCAPS (this is field where data is pulled from)
+	 *    INDEX = 0x5 (where the data has been placed in buffer by hardware)
+	 *    INDEX_WRITE = 0x1 (explicitly define offset) */
+	/* Write this data to DDC buffer */
+	HDMI_OUTP_ND(0x0238, 0x1 | (5 << 16) | (1 << 31));
+
+	/* Discard first byte */
+	HDMI_INP_ND(0x0238);
+
+	for (ndx = 0; ndx < data_len; ++ndx) {
+		reg_val = HDMI_INP_ND(0x0238);
+		data_buf[ndx] = (uint8) ((reg_val & 0x0000FF00) >> 8);
+	}
+
+	DEV_DBG("%s[%s] success\n", __func__, what);
+
+error:
+	return status;
+}
+
+
+static int hdmi_msm_ddc_read(uint32 dev_addr, uint32 offset, uint8 *data_buf,
+	uint32 data_len, int retry, const char *what, boolean no_align)
+{
+	int ret = hdmi_msm_ddc_read_retry(dev_addr, offset, data_buf, data_len,
+		data_len, retry, what);
+	if (!ret)
+		return 0;
+	if (no_align) {
+		return hdmi_msm_ddc_read_retry(dev_addr, offset, data_buf,
+			data_len, data_len, retry, what);
+	} else {
+		return hdmi_msm_ddc_read_retry(dev_addr, offset, data_buf,
+			data_len, 32 * ((data_len + 31) / 32), retry, what);
+	}
+}
+
+
+static int hdmi_msm_read_edid_block(int block, uint8 *edid_buf)
+{
+	int i, rc = 0;
+	int block_size = 0x80;
+
+	do {
+		DEV_DBG("EDID: reading block(%d) with block-size=%d\n",
+			block, block_size);
+		for (i = 0; i < 0x80; i += block_size) {
+			/*Read EDID twice with 32bit alighnment too */
+			if (block < 2) {
+				rc = hdmi_msm_ddc_read(0xA0, block*0x80 + i,
+					edid_buf+i, block_size, 1,
+					"EDID", FALSE);
+			} else {
+				rc = hdmi_msm_ddc_read_edid_seg(0xA0,
+				block*0x80 + i, edid_buf+i, block_size,
+				block_size, 1, "EDID");
+			}
+			if (rc)
+				break;
+		}
+
+		block_size /= 2;
+	} while (rc && (block_size >= 16));
+
+	return rc;
+}
+
+static int hdmi_msm_read_edid(void)
+{
+	int status;
+
+	msm_hdmi_init_ddc();
+	/* Looks like we need to turn on HDMI engine before any
+	 * DDC transaction */
+	if (!hdmi_msm_is_power_on()) {
+		DEV_ERR("%s: failed: HDMI power is off", __func__);
+		status = -ENXIO;
+		goto error;
+	}
+
+	external_common_state->read_edid_block = hdmi_msm_read_edid_block;
+	status = hdmi_common_read_edid();
+	if (!status)
+		DEV_DBG("EDID: successfully read\n");
+
+error:
+	return status;
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+static void hdcp_auth_info(uint32 auth_info)
+{
+	switch (auth_info) {
+	case 0:
+		DEV_INFO("%s: None", __func__);
+		break;
+	case 1:
+		DEV_INFO("%s: Software Disabled Authentication", __func__);
+		break;
+	case 2:
+		DEV_INFO("%s: An Written", __func__);
+		break;
+	case 3:
+		DEV_INFO("%s: Invalid Aksv", __func__);
+		break;
+	case 4:
+		DEV_INFO("%s: Invalid Bksv", __func__);
+		break;
+	case 5:
+		DEV_INFO("%s: RI Mismatch (including RO)", __func__);
+		break;
+	case 6:
+		DEV_INFO("%s: consecutive Pj Mismatches", __func__);
+		break;
+	case 7:
+		DEV_INFO("%s: HPD Disconnect", __func__);
+		break;
+	case 8:
+	default:
+		DEV_INFO("%s: Reserved", __func__);
+		break;
+	}
+}
+
+static void hdcp_key_state(uint32 key_state)
+{
+	switch (key_state) {
+	case 0:
+		DEV_WARN("%s: No HDCP Keys", __func__);
+		break;
+	case 1:
+		DEV_WARN("%s: Not Checked", __func__);
+		break;
+	case 2:
+		DEV_DBG("%s: Checking", __func__);
+		break;
+	case 3:
+		DEV_DBG("%s: HDCP Keys Valid", __func__);
+		break;
+	case 4:
+		DEV_WARN("%s: AKSV not valid", __func__);
+		break;
+	case 5:
+		DEV_WARN("%s: Checksum Mismatch", __func__);
+		break;
+	case 6:
+		DEV_DBG("%s: Production AKSV"
+			"with ENABLE_USER_DEFINED_AN=1", __func__);
+		break;
+	case 7:
+	default:
+		DEV_INFO("%s: Reserved", __func__);
+		break;
+	}
+}
+
+static int hdmi_msm_count_one(uint8 *array, uint8 len)
+{
+	int i, j, count = 0;
+	for (i = 0; i < len; i++)
+		for (j = 0; j < 8; j++)
+			count += (((array[i] >> j) & 0x1) ? 1 : 0);
+	return count;
+}
+
+static void hdcp_deauthenticate(void)
+{
+	int hdcp_link_status = HDMI_INP(0x011C);
+
+	/* Disable HDCP interrupts */
+	HDMI_OUTP(0x0118, 0x0);
+
+	mutex_lock(&hdcp_auth_state_mutex);
+	external_common_state->hdcp_active = FALSE;
+	mutex_unlock(&hdcp_auth_state_mutex);
+	/* 0x0130 HDCP_RESET
+	  [0] LINK0_DEAUTHENTICATE */
+	HDMI_OUTP(0x0130, 0x1);
+
+	/* 0x0110 HDCP_CTRL
+	  [8] ENCRYPTION_ENABLE
+	  [0] ENABLE */
+	/* encryption_enable = 0 | hdcp block enable = 1 */
+	HDMI_OUTP(0x0110, 0x0);
+
+	if (hdcp_link_status & 0x00000004)
+		hdcp_auth_info((hdcp_link_status & 0x000000F0) >> 4);
+}
+
+static void check_and_clear_HDCP_DDC_Failure(void)
+{
+	int hdcp_ddc_ctrl1_reg;
+	int hdcp_ddc_status;
+	int failure;
+	int nack0;
+
+	/*
+	 * Check for any DDC transfer failures
+	 * 0x0128 HDCP_DDC_STATUS
+	 * [16] FAILED		Indicates that the last HDCP HW DDC transer
+	 *			failed. This occurs when a transfer is
+	 *			attempted with HDCP DDC disabled
+	 *			(HDCP_DDC_DISABLE=1) or the number of retries
+	 *			match HDCP_DDC_RETRY_CNT
+	 *
+	 * [14] NACK0		Indicates that the last HDCP HW DDC transfer
+	 *			was aborted due to a NACK on the first
+	 *			transaction - cleared by writing 0 to GO bit
+	 */
+	hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+	failure = (hdcp_ddc_status >> 16) & 0x1;
+	nack0 = (hdcp_ddc_status >> 14) & 0x1;
+	DEV_DBG("%s: On Entry: HDCP_DDC_STATUS = 0x%x, FAILURE = %d,"
+		"NACK0 = %d\n", __func__ , hdcp_ddc_status, failure, nack0);
+
+	if (failure == 0x1) {
+		/*
+		 * Indicates that the last HDCP HW DDC transfer failed.
+		 * This occurs when a transfer is attempted with HDCP DDC
+		 * disabled (HDCP_DDC_DISABLE=1) or the number of retries
+		 * matches HDCP_DDC_RETRY_CNT.
+		 * Failure occured,  let's clear it.
+		 */
+		DEV_INFO("%s: DDC failure detected. HDCP_DDC_STATUS=0x%08x\n",
+			 __func__, hdcp_ddc_status);
+		/*
+		 * First, Disable DDC
+		 * 0x0120 HDCP_DDC_CTRL_0
+		 * [0] DDC_DISABLE	Determines whether HDCP Ri and Pj reads
+		 *			are done unassisted by hardware or by
+		 *			software via HDMI_DDC (HDCP provides
+		 *			interrupts to request software
+		 *			transfers)
+		 *     0 : Use Hardware DDC
+		 *     1 : Use Software DDC
+		 */
+		HDMI_OUTP(HDCP_DDC_CTRL_0, 0x1);
+
+		/*
+		 * ACK the Failure to Clear it
+		 * 0x0124 HDCP_DDC_CTRL_1
+		 * [0] DDC_FAILED_ACK	Write 1 to clear
+		 *			HDCP_STATUS.HDCP_DDC_FAILED
+		 */
+		hdcp_ddc_ctrl1_reg = HDMI_INP(HDCP_DDC_CTRL_1);
+		HDMI_OUTP(HDCP_DDC_CTRL_1, hdcp_ddc_ctrl1_reg | 0x1);
+
+		/* Check if the FAILURE got Cleared */
+		hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+		hdcp_ddc_status = (hdcp_ddc_status >> 16) & 0x1;
+		if (hdcp_ddc_status == 0x0) {
+			DEV_INFO("%s: HDCP DDC Failure has been cleared\n",
+				  __func__);
+		} else {
+			DEV_WARN("%s: Error: HDCP DDC Failure DID NOT get"
+				 "cleared\n", __func__);
+		}
+
+		/* Re-Enable HDCP DDC */
+		HDMI_OUTP(HDCP_DDC_CTRL_0, 0x0);
+	}
+
+	if (nack0 == 0x1) {
+		/*
+		 * 0x020C HDMI_DDC_CTRL
+		 * [3] SW_STATUS_RESET	Write 1 to reset HDMI_DDC_SW_STATUS
+		 *			flags, will reset SW_DONE, ABORTED,
+		 *			TIMEOUT, SW_INTERRUPTED,
+		 *			BUFFER_OVERFLOW, STOPPED_ON_NACK, NACK0,
+		 *			NACK1, NACK2, NACK3
+		 */
+		HDMI_OUTP_ND(HDMI_DDC_CTRL,
+			     HDMI_INP(HDMI_DDC_CTRL) | (0x1 << 3));
+		msleep(20);
+		HDMI_OUTP_ND(HDMI_DDC_CTRL,
+			     HDMI_INP(HDMI_DDC_CTRL) & ~(0x1 << 3));
+	}
+
+	hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+
+	failure = (hdcp_ddc_status >> 16) & 0x1;
+	nack0 = (hdcp_ddc_status >> 14) & 0x1;
+	DEV_DBG("%s: On Exit: HDCP_DDC_STATUS = 0x%x, FAILURE = %d,"
+		"NACK0 = %d\n", __func__ , hdcp_ddc_status, failure, nack0);
+}
+
+
+static int hdcp_authentication_part1(void)
+{
+	int ret = 0;
+	boolean is_match;
+	boolean is_part1_done = FALSE;
+	uint32 timeout_count;
+	uint8 bcaps;
+	uint8 aksv[5];
+	uint32 qfprom_aksv_0, qfprom_aksv_1, link0_aksv_0, link0_aksv_1;
+	uint8 bksv[5];
+	uint32 link0_bksv_0, link0_bksv_1;
+	uint8 an[8];
+	uint32 link0_an_0, link0_an_1;
+	uint32 hpd_int_status, hpd_int_ctrl;
+
+
+	static uint8 buf[0xFF];
+	memset(buf, 0, sizeof(buf));
+
+	if (!is_part1_done) {
+		is_part1_done = TRUE;
+
+		/* Fetch aksv from QFprom, this info should be public. */
+		qfprom_aksv_0 = inpdw(QFPROM_BASE + 0x000060D8);
+		qfprom_aksv_1 = inpdw(QFPROM_BASE + 0x000060DC);
+
+		/* copy an and aksv to byte arrays for transmission */
+		aksv[0] =  qfprom_aksv_0        & 0xFF;
+		aksv[1] = (qfprom_aksv_0 >> 8)  & 0xFF;
+		aksv[2] = (qfprom_aksv_0 >> 16) & 0xFF;
+		aksv[3] = (qfprom_aksv_0 >> 24) & 0xFF;
+		aksv[4] =  qfprom_aksv_1        & 0xFF;
+		/* check there are 20 ones in AKSV */
+		if (hdmi_msm_count_one(aksv, 5) != 20) {
+			DEV_ERR("HDCP: AKSV read from QFPROM doesn't have "
+				"20 1's and 20 0's, FAIL (AKSV=%02x%08x)\n",
+			qfprom_aksv_1, qfprom_aksv_0);
+			ret = -EINVAL;
+			goto error;
+		}
+		DEV_DBG("HDCP: AKSV=%02x%08x\n", qfprom_aksv_1, qfprom_aksv_0);
+
+		/* 0x0288 HDCP_SW_LOWER_AKSV
+			[31:0] LOWER_AKSV */
+		/* 0x0284 HDCP_SW_UPPER_AKSV
+			[7:0] UPPER_AKSV */
+
+		/* This is the lower 32 bits of the SW
+		 * injected AKSV value(AKSV[31:0]) read
+		 * from the EFUSE. It is needed for HDCP
+		 * authentication and must be written
+		 * before enabling HDCP. */
+		HDMI_OUTP(0x0288, qfprom_aksv_0);
+		HDMI_OUTP(0x0284, qfprom_aksv_1);
+
+		msm_hdmi_init_ddc();
+
+		/* Read Bksv 5 bytes at 0x00 in HDCP port */
+		ret = hdmi_msm_ddc_read(0x74, 0x00, bksv, 5, 5, "Bksv", TRUE);
+		if (ret) {
+			DEV_ERR("%s(%d): Read BKSV failed", __func__, __LINE__);
+			goto error;
+		}
+		/* check there are 20 ones in BKSV */
+		if (hdmi_msm_count_one(bksv, 5) != 20) {
+			DEV_ERR("HDCP: BKSV read from Sink doesn't have "
+				"20 1's and 20 0's, FAIL (BKSV="
+				"%02x%02x%02x%02x%02x)\n",
+				bksv[4], bksv[3], bksv[2], bksv[1], bksv[0]);
+			ret = -EINVAL;
+			goto error;
+		}
+
+		link0_bksv_0 = bksv[3];
+		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[2];
+		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[1];
+		link0_bksv_0 = (link0_bksv_0 << 8) | bksv[0];
+		link0_bksv_1 = bksv[4];
+		DEV_DBG("HDCP: BKSV=%02x%08x\n", link0_bksv_1, link0_bksv_0);
+
+		/* read Bcaps at 0x40 in HDCP Port */
+		ret = hdmi_msm_ddc_read(0x74, 0x40, &bcaps, 1, 5, "Bcaps",
+			TRUE);
+		if (ret) {
+			DEV_ERR("%s(%d): Read Bcaps failed", __func__,
+			    __LINE__);
+			goto error;
+		}
+		DEV_DBG("HDCP: Bcaps=%02x\n", bcaps);
+
+		/* HDCP setup prior to HDCP enabled */
+
+		/* 0x0148 HDCP_RCVPORT_DATA4
+			[15:8] LINK0_AINFO
+			[7:0] LINK0_AKSV_1 */
+		/* LINK0_AINFO	= 0x2 FEATURE 1.1 on.
+		 *		= 0x0 FEATURE 1.1 off*/
+		HDMI_OUTP(0x0148, 0x0);
+
+		/* 0x012C HDCP_ENTROPY_CTRL0
+			[31:0] BITS_OF_INFLUENCE_0 */
+		/* 0x025C HDCP_ENTROPY_CTRL1
+			[31:0] BITS_OF_INFLUENCE_1 */
+		HDMI_OUTP(0x012C, 0xB1FFB0FF);
+		HDMI_OUTP(0x025C, 0xF00DFACE);
+
+		/* 0x0114 HDCP_DEBUG_CTRL
+			[2]	DEBUG_RNG_CIPHER
+			else default 0 */
+		HDMI_OUTP(0x0114, HDMI_INP(0x0114) & 0xFFFFFFFB);
+
+		/* 0x0110 HDCP_CTRL
+			[8] ENCRYPTION_ENABLE
+			[0] ENABLE */
+		/* encryption_enable | enable  */
+		HDMI_OUTP(0x0110, (1 << 8) | (1 << 0));
+
+		/*
+		 * Check to see if a HDCP DDC Failure is indicated in
+		 * HDCP_DDC_STATUS. If yes, clear it.
+		 */
+		check_and_clear_HDCP_DDC_Failure();
+
+		/* 0x0118 HDCP_INT_CTRL
+		 *    [2] AUTH_SUCCESS_MASK	[R/W]	Mask bit for\
+		 *					HDCP Authentication
+		 *		Success interrupt - set to 1 to enable interrupt
+		 *
+		 *    [6] AUTH_FAIL_MASK	[R/W]	Mask bit for HDCP
+		 *					Authentication
+		 *		Lost interrupt set to 1 to enable interrupt
+		 *
+		 *    [7] AUTH_FAIL_INFO_ACK	[W]	Acknwledge bit for HDCP
+		 *		Auth Failure Info field - write 1 to clear
+		 *
+		 *   [10] DDC_XFER_REQ_MASK	[R/W]	Mask bit for HDCP\
+		 *					DDC Transfer
+		 *		Request interrupt - set to 1 to enable interrupt
+		 *
+		 *   [14] DDC_XFER_DONE_MASK	[R/W]	Mask bit for HDCP\
+		 *					DDC Transfer
+		 *		done interrupt - set to 1 to enable interrupt */
+		/* enable all HDCP ints */
+		HDMI_OUTP(0x0118, (1 << 2) | (1 << 6) | (1 << 7));
+
+		/* 0x011C HDCP_LINK0_STATUS
+		[8] AN_0_READY
+		[9] AN_1_READY */
+		/* wait for an0 and an1 ready bits to be set in LINK0_STATUS */
+
+		mutex_lock(&hdcp_auth_state_mutex);
+		timeout_count = 100;
+		while (((HDMI_INP_ND(0x011C) & (0x3 << 8)) != (0x3 << 8))
+			&& timeout_count--)
+			msleep(20);
+		if (!timeout_count) {
+			ret = -ETIMEDOUT;
+			DEV_ERR("%s(%d): timedout, An0=%d, An1=%d\n",
+				__func__, __LINE__,
+			(HDMI_INP_ND(0x011C) & BIT(8)) >> 8,
+			(HDMI_INP_ND(0x011C) & BIT(9)) >> 9);
+			mutex_unlock(&hdcp_auth_state_mutex);
+			goto error;
+		}
+
+		/*
+		 * A small delay is needed here to avoid device crash observed
+		 * during reauthentication in MSM8960
+		 */
+		msleep(20);
+
+		/* 0x0168 HDCP_RCVPORT_DATA12
+		   [23:8] BSTATUS
+		   [7:0] BCAPS */
+		HDMI_OUTP(0x0168, bcaps);
+
+		/* 0x014C HDCP_RCVPORT_DATA5
+		   [31:0] LINK0_AN_0 */
+		/* read an0 calculation */
+		link0_an_0 = HDMI_INP(0x014C);
+
+		/* 0x0150 HDCP_RCVPORT_DATA6
+		   [31:0] LINK0_AN_1 */
+		/* read an1 calculation */
+		link0_an_1 = HDMI_INP(0x0150);
+		mutex_unlock(&hdcp_auth_state_mutex);
+
+		/* three bits 28..30 */
+		hdcp_key_state((HDMI_INP(0x011C) >> 28) & 0x7);
+
+		/* 0x0144 HDCP_RCVPORT_DATA3
+		[31:0] LINK0_AKSV_0 public key
+		0x0148 HDCP_RCVPORT_DATA4
+		[15:8] LINK0_AINFO
+		[7:0]  LINK0_AKSV_1 public key */
+		link0_aksv_0 = HDMI_INP(0x0144);
+		link0_aksv_1 = HDMI_INP(0x0148);
+
+		/* copy an and aksv to byte arrays for transmission */
+		aksv[0] =  link0_aksv_0        & 0xFF;
+		aksv[1] = (link0_aksv_0 >> 8)  & 0xFF;
+		aksv[2] = (link0_aksv_0 >> 16) & 0xFF;
+		aksv[3] = (link0_aksv_0 >> 24) & 0xFF;
+		aksv[4] =  link0_aksv_1        & 0xFF;
+
+		an[0] =  link0_an_0        & 0xFF;
+		an[1] = (link0_an_0 >> 8)  & 0xFF;
+		an[2] = (link0_an_0 >> 16) & 0xFF;
+		an[3] = (link0_an_0 >> 24) & 0xFF;
+		an[4] =  link0_an_1        & 0xFF;
+		an[5] = (link0_an_1 >> 8)  & 0xFF;
+		an[6] = (link0_an_1 >> 16) & 0xFF;
+		an[7] = (link0_an_1 >> 24) & 0xFF;
+
+		/* Write An 8 bytes to offset 0x18 */
+		ret = hdmi_msm_ddc_write(0x74, 0x18, an, 8, "An");
+		if (ret) {
+			DEV_ERR("%s(%d): Write An failed", __func__, __LINE__);
+			goto error;
+		}
+
+		/* Write Aksv 5 bytes to offset 0x10 */
+		ret = hdmi_msm_ddc_write(0x74, 0x10, aksv, 5, "Aksv");
+		if (ret) {
+			DEV_ERR("%s(%d): Write Aksv failed", __func__,
+			    __LINE__);
+			goto error;
+		}
+		DEV_DBG("HDCP: Link0-AKSV=%02x%08x\n",
+			link0_aksv_1 & 0xFF, link0_aksv_0);
+
+		/* 0x0134 HDCP_RCVPORT_DATA0
+		   [31:0] LINK0_BKSV_0 */
+		HDMI_OUTP(0x0134, link0_bksv_0);
+		/* 0x0138 HDCP_RCVPORT_DATA1
+		   [31:0] LINK0_BKSV_1 */
+		HDMI_OUTP(0x0138, link0_bksv_1);
+		DEV_DBG("HDCP: Link0-BKSV=%02x%08x\n", link0_bksv_1,
+		    link0_bksv_0);
+
+		/* HDMI_HPD_INT_STATUS[0x0250] */
+		hpd_int_status = HDMI_INP_ND(0x0250);
+		/* HDMI_HPD_INT_CTRL[0x0254] */
+		hpd_int_ctrl = HDMI_INP_ND(0x0254);
+		DEV_DBG("[SR-DEUG]: HPD_INTR_CTRL=[%u] HPD_INTR_STATUS=[%u] "
+			"before reading R0'\n", hpd_int_ctrl, hpd_int_status);
+
+		/*
+		* HDCP Compliace Test case 1B-01:
+		* Wait here until all the ksv bytes have been
+		* read from the KSV FIFO register.
+		*/
+		msleep(125);
+
+		/* Reading R0' 2 bytes at offset 0x08 */
+		ret = hdmi_msm_ddc_read(0x74, 0x08, buf, 2, 5, "RO'", TRUE);
+		if (ret) {
+			DEV_ERR("%s(%d): Read RO's failed", __func__,
+			    __LINE__);
+			goto error;
+		}
+
+		DEV_DBG("HDCP: R0'=%02x%02x\n", buf[1], buf[0]);
+		INIT_COMPLETION(hdmi_msm_state->hdcp_success_done);
+		/* 0x013C HDCP_RCVPORT_DATA2_0
+		[15:0] LINK0_RI */
+		HDMI_OUTP(0x013C, (((uint32)buf[1]) << 8) | buf[0]);
+
+		timeout_count = wait_for_completion_interruptible_timeout(
+			&hdmi_msm_state->hdcp_success_done, HZ*2);
+
+		if (!timeout_count) {
+			ret = -ETIMEDOUT;
+			is_match = HDMI_INP(0x011C) & BIT(12);
+			DEV_ERR("%s(%d): timedout, Link0=<%s>\n", __func__,
+			  __LINE__,
+			  is_match ? "RI_MATCH" : "No RI Match INTR in time");
+			if (!is_match)
+				goto error;
+		}
+
+		/* 0x011C HDCP_LINK0_STATUS
+		[12] RI_MATCHES	[0] MISMATCH, [1] MATCH
+		[0] AUTH_SUCCESS */
+		/* Checking for RI, R0 Match */
+		/* RI_MATCHES */
+		if ((HDMI_INP(0x011C) & BIT(12)) != BIT(12)) {
+			ret = -EINVAL;
+			DEV_ERR("%s: HDCP_LINK0_STATUS[RI_MATCHES]: MISMATCH\n",
+			    __func__);
+			goto error;
+		}
+
+		DEV_INFO("HDCP: authentication part I, successful\n");
+		is_part1_done = FALSE;
+		return 0;
+error:
+		DEV_ERR("[%s]: HDCP Reauthentication\n", __func__);
+		is_part1_done = FALSE;
+		return ret;
+	} else {
+		return 1;
+	}
+}
+
+static int hdmi_msm_transfer_v_h(void)
+{
+	/* Read V'.HO 4 Byte at offset 0x20 */
+	char what[20];
+	int ret;
+	uint8 buf[4];
+
+	snprintf(what, sizeof(what), "V' H0");
+	ret = hdmi_msm_ddc_read(0x74, 0x20, buf, 4, 5, what, TRUE);
+	if (ret) {
+		DEV_ERR("%s: Read %s failed", __func__, what);
+		return ret;
+	}
+	DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
+			buf[0] , buf[1] , buf[2] , buf[3]);
+
+	/* 0x0154 HDCP_RCVPORT_DATA7
+	   [31:0] V_HO */
+	HDMI_OUTP(0x0154 ,
+		(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
+
+	snprintf(what, sizeof(what), "V' H1");
+	ret = hdmi_msm_ddc_read(0x74, 0x24, buf, 4, 5, what, TRUE);
+	if (ret) {
+		DEV_ERR("%s: Read %s failed", __func__, what);
+		return ret;
+	}
+	DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
+			buf[0] , buf[1] , buf[2] , buf[3]);
+
+	/* 0x0158 HDCP_RCVPORT_ DATA8
+	   [31:0] V_H1 */
+	HDMI_OUTP(0x0158,
+		(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
+
+
+	snprintf(what, sizeof(what), "V' H2");
+	ret = hdmi_msm_ddc_read(0x74, 0x28, buf, 4, 5, what, TRUE);
+	if (ret) {
+		DEV_ERR("%s: Read %s failed", __func__, what);
+		return ret;
+	}
+	DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
+			buf[0] , buf[1] , buf[2] , buf[3]);
+
+	/* 0x015c HDCP_RCVPORT_DATA9
+	   [31:0] V_H2 */
+	HDMI_OUTP(0x015c ,
+		(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
+
+	snprintf(what, sizeof(what), "V' H3");
+	ret = hdmi_msm_ddc_read(0x74, 0x2c, buf, 4, 5, what, TRUE);
+	if (ret) {
+		DEV_ERR("%s: Read %s failed", __func__, what);
+		return ret;
+	}
+	DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
+			buf[0] , buf[1] , buf[2] , buf[3]);
+
+	/* 0x0160 HDCP_RCVPORT_DATA10
+	   [31:0] V_H3 */
+	HDMI_OUTP(0x0160,
+		(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
+
+	snprintf(what, sizeof(what), "V' H4");
+	ret = hdmi_msm_ddc_read(0x74, 0x30, buf, 4, 5, what, TRUE);
+	if (ret) {
+		DEV_ERR("%s: Read %s failed", __func__, what);
+		return ret;
+	}
+	DEV_DBG("buf[0]= %x , buf[1] = %x , buf[2] = %x , buf[3] = %x\n ",
+			buf[0] , buf[1] , buf[2] , buf[3]);
+	/* 0x0164 HDCP_RCVPORT_DATA11
+	   [31:0] V_H4 */
+	HDMI_OUTP(0x0164,
+		(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
+
+	return 0;
+}
+
+static int hdcp_authentication_part2(void)
+{
+	int ret = 0;
+	uint32 timeout_count;
+	int i = 0;
+	int cnt = 0;
+	uint bstatus;
+	uint8 bcaps;
+	uint32 down_stream_devices;
+	uint32 ksv_bytes;
+
+	static uint8 buf[0xFF];
+	static uint8 kvs_fifo[5 * 127];
+
+	boolean max_devs_exceeded = 0;
+	boolean max_cascade_exceeded = 0;
+
+	boolean ksv_done = FALSE;
+
+	memset(buf, 0, sizeof(buf));
+	memset(kvs_fifo, 0, sizeof(kvs_fifo));
+
+	/* wait until READY bit is set in bcaps */
+	timeout_count = 50;
+	do {
+		timeout_count--;
+		/* read bcaps 1 Byte at offset 0x40 */
+		ret = hdmi_msm_ddc_read(0x74, 0x40, &bcaps, 1, 1,
+		    "Bcaps", FALSE);
+		if (ret) {
+			DEV_ERR("%s(%d): Read Bcaps failed", __func__,
+			    __LINE__);
+			goto error;
+		}
+		msleep(100);
+	} while ((0 == (bcaps & 0x20)) && timeout_count); /* READY (Bit 5) */
+	if (!timeout_count) {
+		ret = -ETIMEDOUT;
+		DEV_ERR("%s:timedout(1)", __func__);
+		goto error;
+	}
+
+	/* read bstatus 2 bytes at offset 0x41 */
+
+	ret = hdmi_msm_ddc_read(0x74, 0x41, buf, 2, 5, "Bstatus", FALSE);
+	if (ret) {
+		DEV_ERR("%s(%d): Read Bstatus failed", __func__, __LINE__);
+		goto error;
+	}
+	bstatus = buf[1];
+	bstatus = (bstatus << 8) | buf[0];
+	/* 0x0168 DCP_RCVPORT_DATA12
+	[7:0] BCAPS
+	[23:8 BSTATUS */
+	HDMI_OUTP(0x0168, bcaps | (bstatus << 8));
+	/* BSTATUS [6:0] DEVICE_COUNT Number of HDMI device attached to repeater
+	* - see HDCP spec */
+	down_stream_devices = bstatus & 0x7F;
+
+	if (down_stream_devices == 0x0) {
+		/* There isn't any devices attaced to the Repeater */
+		DEV_ERR("%s: there isn't any devices attached to the "
+		    "Repeater\n", __func__);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	/*
+	* HDCP Compliance 1B-05:
+	* Check if no. of devices connected to repeater
+	* exceed max_devices_connected from bit 7 of Bstatus.
+	*/
+	max_devs_exceeded = (bstatus & 0x80) >> 7;
+	if (max_devs_exceeded == 0x01) {
+		DEV_ERR("%s: Number of devs connected to repeater "
+		    "exceeds max_devs\n", __func__);
+		ret = -EINVAL;
+		goto hdcp_error;
+	}
+
+	/*
+	* HDCP Compliance 1B-06:
+	* Check if no. of cascade connected to repeater
+	* exceed max_cascade_connected from bit 11 of Bstatus.
+	*/
+	max_cascade_exceeded = (bstatus & 0x800) >> 11;
+	if (max_cascade_exceeded == 0x01) {
+		DEV_ERR("%s: Number of cascade connected to repeater "
+		    "exceeds max_cascade\n", __func__);
+		ret = -EINVAL;
+		goto hdcp_error;
+	}
+
+	/* Read KSV FIFO over DDC
+	* Key Slection vector FIFO
+	* Used to pull downstream KSVs from HDCP Repeaters.
+	* All bytes (DEVICE_COUNT * 5) must be read in a single,
+	*   auto incrementing access.
+	* All bytes read as 0x00 for HDCP Receivers that are not
+	*   HDCP Repeaters (REPEATER == 0). */
+	ksv_bytes = 5 * down_stream_devices;
+	/* Reading KSV FIFO / KSV FIFO */
+	ksv_done = FALSE;
+
+	ret = hdmi_msm_ddc_read(0x74, 0x43, kvs_fifo, ksv_bytes, 5,
+	"KSV FIFO", TRUE);
+	do {
+		if (ret) {
+			DEV_ERR("%s(%d): Read KSV FIFO failed",
+			    __func__, __LINE__);
+			/*
+			* HDCP Compliace Test case 1B-01:
+			* Wait here until all the ksv bytes have been
+			* read from the KSV FIFO register.
+			*/
+			msleep(25);
+		} else {
+			ksv_done = TRUE;
+		}
+		cnt++;
+	} while (!ksv_done && cnt != 20);
+
+	if (ksv_done == FALSE)
+		goto error;
+
+	ret = hdmi_msm_transfer_v_h();
+	if (ret)
+		goto error;
+
+	/* Next: Write KSV FIFO to HDCP_SHA_DATA.
+	* This is done 1 byte at time starting with the LSB.
+	* On the very last byte write,
+	* the HDCP_SHA_DATA_DONE bit[0]
+	*/
+
+	/* 0x023C HDCP_SHA_CTRL
+	[0] RESET	[0] Enable, [1] Reset
+	[4] SELECT	[0] DIGA_HDCP, [1] DIGB_HDCP */
+	/* reset SHA engine */
+	HDMI_OUTP(0x023C, 1);
+	/* enable SHA engine, SEL=DIGA_HDCP */
+	HDMI_OUTP(0x023C, 0);
+
+	for (i = 0; i < ksv_bytes - 1; i++) {
+		/* Write KSV byte and do not set DONE bit[0] */
+		HDMI_OUTP_ND(0x0244, kvs_fifo[i] << 16);
+
+		/* Once 64 bytes have been written, we need to poll for
+		 * HDCP_SHA_BLOCK_DONE before writing any further
+		 */
+		if (i && !((i+1)%64)) {
+			timeout_count = 100;
+			while (!(HDMI_INP_ND(0x0240) & 0x1)
+					&& (--timeout_count)) {
+				DEV_DBG("HDCP Auth Part II: Waiting for the "
+					"computation of the current 64 byte to "
+					"complete. HDCP_SHA_STATUS=%08x. "
+					"timeout_count=%d\n",
+					 HDMI_INP_ND(0x0240), timeout_count);
+				msleep(20);
+			}
+			if (!timeout_count) {
+				ret = -ETIMEDOUT;
+				DEV_ERR("%s(%d): timedout", __func__, __LINE__);
+				goto error;
+			}
+		}
+
+	}
+
+	/* Write l to DONE bit[0] */
+	HDMI_OUTP_ND(0x0244, (kvs_fifo[ksv_bytes - 1] << 16) | 0x1);
+
+	/* 0x0240 HDCP_SHA_STATUS
+	[4] COMP_DONE */
+	/* Now wait for HDCP_SHA_COMP_DONE */
+	timeout_count = 100;
+	while ((0x10 != (HDMI_INP_ND(0x0240) & 0xFFFFFF10)) && --timeout_count)
+		msleep(20);
+
+	if (!timeout_count) {
+		ret = -ETIMEDOUT;
+		DEV_ERR("%s(%d): timedout", __func__, __LINE__);
+		goto error;
+	}
+
+	/* 0x011C HDCP_LINK0_STATUS
+	[20] V_MATCHES */
+	timeout_count = 100;
+	while (((HDMI_INP_ND(0x011C) & (1 << 20)) != (1 << 20))
+	    && --timeout_count) {
+		msleep(20);
+	}
+
+	if (!timeout_count) {
+		ret = -ETIMEDOUT;
+		DEV_ERR("%s(%d): timedout", __func__, __LINE__);
+		goto error;
+	}
+
+	DEV_INFO("HDCP: authentication part II, successful\n");
+
+hdcp_error:
+error:
+	return ret;
+}
+
+static int hdcp_authentication_part3(uint32 found_repeater)
+{
+	int ret = 0;
+	int poll = 3000;
+	while (poll) {
+		/* 0x011C HDCP_LINK0_STATUS
+		    [30:28]  KEYS_STATE = 3 = "Valid"
+		    [24] RO_COMPUTATION_DONE	[0] Not Done, [1] Done
+		    [20] V_MATCHES		[0] Mismtach, [1] Match
+		    [12] RI_MATCHES		[0] Mismatch, [1] Match
+		    [0] AUTH_SUCCESS */
+		if (HDMI_INP_ND(0x011C) != (0x31001001 |
+		    (found_repeater << 20))) {
+			DEV_ERR("HDCP: autentication part III, FAILED, "
+			    "Link Status=%08x\n", HDMI_INP(0x011C));
+			ret = -EINVAL;
+			goto error;
+		}
+		poll--;
+	}
+
+	DEV_INFO("HDCP: authentication part III, successful\n");
+
+error:
+	return ret;
+}
+
+static void hdmi_msm_hdcp_enable(void)
+{
+	int ret = 0;
+	uint8 bcaps;
+	uint32 found_repeater = 0x0;
+	char *envp[2];
+
+	if (!hdmi_msm_has_hdcp()) {
+		DEV_INFO("%s: HDCP NOT ENABLED\n", __func__);
+		return;
+	}
+
+	mutex_lock(&hdmi_msm_state_mutex);
+	hdmi_msm_state->hdcp_activating = TRUE;
+	mutex_unlock(&hdmi_msm_state_mutex);
+
+	fill_black_screen();
+
+	mutex_lock(&hdcp_auth_state_mutex);
+	/*
+	 * Initialize this to zero here to make
+	 * sure HPD has not happened yet
+	 */
+	hdmi_msm_state->hpd_during_auth = FALSE;
+	/* This flag prevents other threads from re-authenticating
+	* after we've just authenticated (i.e., finished part3)
+	* We probably need to protect this in a mutex lock */
+	hdmi_msm_state->full_auth_done = FALSE;
+	mutex_unlock(&hdcp_auth_state_mutex);
+
+	/* PART I Authentication*/
+	ret = hdcp_authentication_part1();
+	if (ret)
+		goto error;
+
+	/* PART II Authentication*/
+	/* read Bcaps at 0x40 in HDCP Port */
+	ret = hdmi_msm_ddc_read(0x74, 0x40, &bcaps, 1, 5, "Bcaps", FALSE);
+	if (ret) {
+		DEV_ERR("%s(%d): Read Bcaps failed\n", __func__, __LINE__);
+		goto error;
+	}
+	DEV_DBG("HDCP: Bcaps=0x%02x (%s)\n", bcaps,
+		(bcaps & BIT(6)) ? "repeater" : "no repeater");
+
+	/* if REPEATER (Bit 6), perform Part2 Authentication */
+	if (bcaps & BIT(6)) {
+		found_repeater = 0x1;
+		ret = hdcp_authentication_part2();
+		if (ret)
+			goto error;
+	} else
+		DEV_INFO("HDCP: authentication part II skipped, no repeater\n");
+
+	/* PART III Authentication*/
+	ret = hdcp_authentication_part3(found_repeater);
+	if (ret)
+		goto error;
+
+	unfill_black_screen();
+
+	mutex_lock(&hdmi_msm_state_mutex);
+	hdmi_msm_state->hdcp_activating = FALSE;
+	mutex_unlock(&hdmi_msm_state_mutex);
+
+	mutex_lock(&hdcp_auth_state_mutex);
+	/*
+	 * This flag prevents other threads from re-authenticating
+	 * after we've just authenticated (i.e., finished part3)
+	 */
+	hdmi_msm_state->full_auth_done = TRUE;
+	external_common_state->hdcp_active = TRUE;
+	mutex_unlock(&hdcp_auth_state_mutex);
+
+	if (!hdmi_msm_is_dvi_mode()) {
+		DEV_INFO("HDMI HPD: sense : send HDCP_PASS\n");
+		envp[0] = "HDCP_STATE=PASS";
+		envp[1] = NULL;
+		kobject_uevent_env(external_common_state->uevent_kobj,
+		    KOBJ_CHANGE, envp);
+	}
+
+	switch_set_state(&external_common_state->sdev, 1);
+	DEV_INFO("Hdmi state switched to %d: %s\n",
+		external_common_state->sdev.state, __func__);
+	return;
+
+error:
+	mutex_lock(&hdmi_msm_state_mutex);
+	hdmi_msm_state->hdcp_activating = FALSE;
+	mutex_unlock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->hpd_during_auth) {
+		DEV_WARN("Calling Deauthentication: HPD occured during "
+			 "authentication  from [%s]\n", __func__);
+		hdcp_deauthenticate();
+		mutex_lock(&hdcp_auth_state_mutex);
+		hdmi_msm_state->hpd_during_auth = FALSE;
+		mutex_unlock(&hdcp_auth_state_mutex);
+	} else {
+		DEV_WARN("[DEV_DBG]: Calling reauth from [%s]\n", __func__);
+		if (hdmi_msm_state->panel_power_on)
+			queue_work(hdmi_work_queue,
+			    &hdmi_msm_state->hdcp_reauth_work);
+	}
+	switch_set_state(&external_common_state->sdev, 0);
+	DEV_INFO("Hdmi state switched to %d: %s\n",
+		external_common_state->sdev.state, __func__);
+}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+static void hdmi_msm_video_setup(int video_format)
+{
+	uint32 total_v   = 0;
+	uint32 total_h   = 0;
+	uint32 start_h   = 0;
+	uint32 end_h     = 0;
+	uint32 start_v   = 0;
+	uint32 end_v     = 0;
+	const struct hdmi_disp_mode_timing_type *timing =
+		hdmi_common_get_supported_mode(video_format);
+
+	/* timing register setup */
+	if (timing == NULL) {
+		DEV_ERR("video format not supported: %d\n", video_format);
+		return;
+	}
+
+	/* Hsync Total and Vsync Total */
+	total_h = timing->active_h + timing->front_porch_h
+		+ timing->back_porch_h + timing->pulse_width_h - 1;
+	total_v = timing->active_v + timing->front_porch_v
+		+ timing->back_porch_v + timing->pulse_width_v - 1;
+	/* 0x02C0 HDMI_TOTAL
+	   [27:16] V_TOTAL Vertical Total
+	   [11:0]  H_TOTAL Horizontal Total */
+	HDMI_OUTP(0x02C0, ((total_v << 16) & 0x0FFF0000)
+		| ((total_h << 0) & 0x00000FFF));
+
+	/* Hsync Start and Hsync End */
+	start_h = timing->back_porch_h + timing->pulse_width_h;
+	end_h   = (total_h + 1) - timing->front_porch_h;
+	/* 0x02B4 HDMI_ACTIVE_H
+	   [27:16] END Horizontal end
+	   [11:0]  START Horizontal start */
+	HDMI_OUTP(0x02B4, ((end_h << 16) & 0x0FFF0000)
+		| ((start_h << 0) & 0x00000FFF));
+
+	start_v = timing->back_porch_v + timing->pulse_width_v - 1;
+	end_v   = total_v - timing->front_porch_v;
+	/* 0x02B8 HDMI_ACTIVE_V
+	   [27:16] END Vertical end
+	   [11:0]  START Vertical start */
+	HDMI_OUTP(0x02B8, ((end_v << 16) & 0x0FFF0000)
+		| ((start_v << 0) & 0x00000FFF));
+
+	if (timing->interlaced) {
+		/* 0x02C4 HDMI_V_TOTAL_F2
+		   [11:0] V_TOTAL_F2 Vertical total for field2 */
+		HDMI_OUTP(0x02C4, ((total_v + 1) << 0) & 0x00000FFF);
+
+		/* 0x02BC HDMI_ACTIVE_V_F2
+		   [27:16] END_F2 Vertical end for field2
+		   [11:0]  START_F2 Vertical start for Field2 */
+		HDMI_OUTP(0x02BC,
+			  (((start_v + 1) << 0) & 0x00000FFF)
+			| (((end_v + 1) << 16) & 0x0FFF0000));
+	} else {
+		/* HDMI_V_TOTAL_F2 */
+		HDMI_OUTP(0x02C4, 0);
+		/* HDMI_ACTIVE_V_F2 */
+		HDMI_OUTP(0x02BC, 0);
+	}
+
+	hdmi_frame_ctrl_cfg(timing);
+}
+
+struct hdmi_msm_audio_acr {
+	uint32 n;	/* N parameter for clock regeneration */
+	uint32 cts;	/* CTS parameter for clock regeneration */
+};
+
+struct hdmi_msm_audio_arcs {
+	uint32 pclk;
+	struct hdmi_msm_audio_acr lut[MSM_HDMI_SAMPLE_RATE_MAX];
+};
+
+#define HDMI_MSM_AUDIO_ARCS(pclk, ...) { pclk, __VA_ARGS__ }
+
+/* Audio constants lookup table for hdmi_msm_audio_acr_setup */
+/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
+static const struct hdmi_msm_audio_arcs hdmi_msm_audio_acr_lut[] = {
+	/*  25.200MHz  */
+	HDMI_MSM_AUDIO_ARCS(25200, {
+		{4096, 25200}, {6272, 28000}, {6144, 25200}, {12544, 28000},
+		{12288, 25200}, {25088, 28000}, {24576, 25200} }),
+	/*  27.000MHz  */
+	HDMI_MSM_AUDIO_ARCS(27000, {
+		{4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
+		{12288, 27000}, {25088, 30000}, {24576, 27000} }),
+	/*  27.027MHz */
+	HDMI_MSM_AUDIO_ARCS(27030, {
+		{4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030},
+		{12288, 27027}, {25088, 30030}, {24576, 27027} }),
+	/*  74.250MHz */
+	HDMI_MSM_AUDIO_ARCS(74250, {
+		{4096, 74250}, {6272, 82500}, {6144, 74250}, {12544, 82500},
+		{12288, 74250}, {25088, 82500}, {24576, 74250} }),
+	/* 148.500MHz */
+	HDMI_MSM_AUDIO_ARCS(148500, {
+		{4096, 148500}, {6272, 165000}, {6144, 148500}, {12544, 165000},
+		{12288, 148500}, {25088, 165000}, {24576, 148500} }),
+};
+
+static void hdmi_msm_audio_acr_setup(boolean enabled, int video_format,
+	int audio_sample_rate, int num_of_channels)
+{
+	/* Read first before writing */
+	/* HDMI_ACR_PKT_CTRL[0x0024] */
+	uint32 acr_pck_ctrl_reg = HDMI_INP(0x0024);
+
+	if (enabled) {
+		const struct hdmi_disp_mode_timing_type *timing =
+			hdmi_common_get_supported_mode(video_format);
+		const struct hdmi_msm_audio_arcs *audio_arc =
+			&hdmi_msm_audio_acr_lut[0];
+		const int lut_size = sizeof(hdmi_msm_audio_acr_lut)
+			/sizeof(*hdmi_msm_audio_acr_lut);
+		uint32 i, n, cts, layout, multiplier, aud_pck_ctrl_2_reg;
+
+		if (timing == NULL) {
+			DEV_WARN("%s: video format %d not supported\n",
+				__func__, video_format);
+			return;
+		}
+
+		for (i = 0; i < lut_size;
+			audio_arc = &hdmi_msm_audio_acr_lut[++i]) {
+			if (audio_arc->pclk == timing->pixel_freq)
+				break;
+		}
+		if (i >= lut_size) {
+			DEV_WARN("%s: pixel clock %d not supported\n", __func__,
+				timing->pixel_freq);
+			return;
+		}
+
+		n = audio_arc->lut[audio_sample_rate].n;
+		cts = audio_arc->lut[audio_sample_rate].cts;
+		layout = (MSM_HDMI_AUDIO_CHANNEL_2 == num_of_channels) ? 0 : 1;
+
+		if ((MSM_HDMI_SAMPLE_RATE_192KHZ == audio_sample_rate) ||
+		    (MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio_sample_rate)) {
+			multiplier = 4;
+			n >>= 2; /* divide N by 4 and use multiplier */
+		} else if ((MSM_HDMI_SAMPLE_RATE_96KHZ == audio_sample_rate) ||
+			  (MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio_sample_rate)) {
+			multiplier = 2;
+			n >>= 1; /* divide N by 2 and use multiplier */
+		} else {
+			multiplier = 1;
+		}
+		DEV_DBG("%s: n=%u, cts=%u, layout=%u\n", __func__, n, cts,
+			layout);
+
+		/* AUDIO_PRIORITY | SOURCE */
+		acr_pck_ctrl_reg |= 0x80000100;
+		/* N_MULTIPLE(multiplier) */
+		acr_pck_ctrl_reg |= (multiplier & 7) << 16;
+
+		if ((MSM_HDMI_SAMPLE_RATE_48KHZ == audio_sample_rate) ||
+		    (MSM_HDMI_SAMPLE_RATE_96KHZ == audio_sample_rate) ||
+		    (MSM_HDMI_SAMPLE_RATE_192KHZ == audio_sample_rate)) {
+			/* SELECT(3) */
+			acr_pck_ctrl_reg |= 3 << 4;
+			/* CTS_48 */
+			cts <<= 12;
+
+			/* CTS: need to determine how many fractional bits */
+			/* HDMI_ACR_48_0 */
+			HDMI_OUTP(0x00D4, cts);
+			/* N */
+			/* HDMI_ACR_48_1 */
+			HDMI_OUTP(0x00D8, n);
+		} else if ((MSM_HDMI_SAMPLE_RATE_44_1KHZ == audio_sample_rate)
+			   || (MSM_HDMI_SAMPLE_RATE_88_2KHZ ==
+			       audio_sample_rate)
+			   || (MSM_HDMI_SAMPLE_RATE_176_4KHZ ==
+			       audio_sample_rate)) {
+			/* SELECT(2) */
+			acr_pck_ctrl_reg |= 2 << 4;
+			/* CTS_44 */
+			cts <<= 12;
+
+			/* CTS: need to determine how many fractional bits */
+			/* HDMI_ACR_44_0 */
+			HDMI_OUTP(0x00CC, cts);
+			/* N */
+			/* HDMI_ACR_44_1 */
+			HDMI_OUTP(0x00D0, n);
+		} else {	/* default to 32k */
+			/* SELECT(1) */
+			acr_pck_ctrl_reg |= 1 << 4;
+			/* CTS_32 */
+			cts <<= 12;
+
+			/* CTS: need to determine how many fractional bits */
+			/* HDMI_ACR_32_0 */
+			HDMI_OUTP(0x00C4, cts);
+			/* N */
+			/* HDMI_ACR_32_1 */
+			HDMI_OUTP(0x00C8, n);
+		}
+		/* Payload layout depends on number of audio channels */
+		/* LAYOUT_SEL(layout) */
+		aud_pck_ctrl_2_reg = 1 | (layout << 1);
+		/* override | layout */
+		/* HDMI_AUDIO_PKT_CTRL2[0x00044] */
+		HDMI_OUTP(0x00044, aud_pck_ctrl_2_reg);
+
+		/* SEND | CONT */
+		acr_pck_ctrl_reg |= 0x00000003;
+	} else {
+		/* ~(SEND | CONT) */
+		acr_pck_ctrl_reg &= ~0x00000003;
+	}
+	/* HDMI_ACR_PKT_CTRL[0x0024] */
+	HDMI_OUTP(0x0024, acr_pck_ctrl_reg);
+}
+
+static void hdmi_msm_outpdw_chk(uint32 offset, uint32 data)
+{
+	uint32 check, i = 0;
+
+#ifdef DEBUG
+	HDMI_OUTP(offset, data);
+#endif
+	do {
+		outpdw(MSM_HDMI_BASE+offset, data);
+		check = inpdw(MSM_HDMI_BASE+offset);
+	} while (check != data && i++ < 10);
+
+	if (check != data)
+		DEV_ERR("%s: failed addr=%08x, data=%x, check=%x",
+			__func__, offset, data, check);
+}
+
+static void hdmi_msm_rmw32or(uint32 offset, uint32 data)
+{
+	uint32 reg_data;
+	reg_data = inpdw(MSM_HDMI_BASE+offset);
+	reg_data = inpdw(MSM_HDMI_BASE+offset);
+	hdmi_msm_outpdw_chk(offset, reg_data | data);
+}
+
+
+#define HDMI_AUDIO_CFG				0x01D0
+#define HDMI_AUDIO_ENGINE_ENABLE		1
+#define HDMI_AUDIO_FIFO_MASK			0x000000F0
+#define HDMI_AUDIO_FIFO_WATERMARK_SHIFT		4
+#define HDMI_AUDIO_FIFO_MAX_WATER_MARK		8
+
+
+int hdmi_audio_enable(bool on , u32 fifo_water_mark)
+{
+	u32 hdmi_audio_config;
+
+	hdmi_audio_config = HDMI_INP(HDMI_AUDIO_CFG);
+
+	if (on) {
+
+		if (fifo_water_mark > HDMI_AUDIO_FIFO_MAX_WATER_MARK) {
+			pr_err("%s : HDMI audio fifo water mark can not be more"
+				" than %u\n", __func__,
+				HDMI_AUDIO_FIFO_MAX_WATER_MARK);
+			return -EINVAL;
+		}
+
+		/*
+		 *  Enable HDMI Audio engine.
+		 *  MUST be enabled after Audio DMA is enabled.
+		*/
+		hdmi_audio_config &= ~(HDMI_AUDIO_FIFO_MASK);
+
+		hdmi_audio_config |= (HDMI_AUDIO_ENGINE_ENABLE |
+			 (fifo_water_mark << HDMI_AUDIO_FIFO_WATERMARK_SHIFT));
+
+	} else
+		 hdmi_audio_config &= ~(HDMI_AUDIO_ENGINE_ENABLE);
+
+	HDMI_OUTP(HDMI_AUDIO_CFG, hdmi_audio_config);
+
+	mb();
+	pr_info("%s :HDMI_AUDIO_CFG 0x%08x\n", __func__,
+		HDMI_INP(HDMI_AUDIO_CFG));
+
+	return 0;
+}
+EXPORT_SYMBOL(hdmi_audio_enable);
+
+#define HDMI_AUDIO_PKT_CTRL			0x0020
+#define HDMI_AUDIO_SAMPLE_SEND_ENABLE		1
+
+int hdmi_audio_packet_enable(bool on)
+{
+	u32 hdmi_audio_pkt_ctrl;
+	hdmi_audio_pkt_ctrl = HDMI_INP(HDMI_AUDIO_PKT_CTRL);
+
+	if (on)
+		hdmi_audio_pkt_ctrl |= HDMI_AUDIO_SAMPLE_SEND_ENABLE;
+	else
+		hdmi_audio_pkt_ctrl &= ~(HDMI_AUDIO_SAMPLE_SEND_ENABLE);
+
+	HDMI_OUTP(HDMI_AUDIO_PKT_CTRL, hdmi_audio_pkt_ctrl);
+
+	mb();
+	pr_info("%s : HDMI_AUDIO_PKT_CTRL 0x%08x\n", __func__,
+	HDMI_INP(HDMI_AUDIO_PKT_CTRL));
+	return 0;
+}
+EXPORT_SYMBOL(hdmi_audio_packet_enable);
+
+
+/* TO-DO: return -EINVAL when num_of_channels and channel_allocation
+ *  does not match CEA 861-D spec.
+*/
+int hdmi_msm_audio_info_setup(bool enabled, u32 num_of_channels,
+	u32 channel_allocation, u32 level_shift, bool down_mix)
+{
+	uint32 channel_count = 1;	/* Default to 2 channels
+					   -> See Table 17 in CEA-D spec */
+	uint32 check_sum, audio_info_0_reg, audio_info_1_reg;
+	uint32 audio_info_ctrl_reg;
+	u32 aud_pck_ctrl_2_reg;
+	u32 layout;
+
+	layout = (MSM_HDMI_AUDIO_CHANNEL_2 == num_of_channels) ? 0 : 1;
+	aud_pck_ctrl_2_reg = 1 | (layout << 1);
+	HDMI_OUTP(0x00044, aud_pck_ctrl_2_reg);
+
+	/* Please see table 20 Audio InfoFrame in HDMI spec
+	   FL  = front left
+	   FC  = front Center
+	   FR  = front right
+	   FLC = front left center
+	   FRC = front right center
+	   RL  = rear left
+	   RC  = rear center
+	   RR  = rear right
+	   RLC = rear left center
+	   RRC = rear right center
+	   LFE = low frequency effect
+	 */
+
+	/* Read first then write because it is bundled with other controls */
+	/* HDMI_INFOFRAME_CTRL0[0x002C] */
+	audio_info_ctrl_reg = HDMI_INP(0x002C);
+
+	if (enabled) {
+		switch (num_of_channels) {
+		case MSM_HDMI_AUDIO_CHANNEL_2:
+			channel_allocation = 0;	/* Default to FR,FL */
+			break;
+		case MSM_HDMI_AUDIO_CHANNEL_4:
+			channel_count = 3;
+			/* FC,LFE,FR,FL */
+			channel_allocation = 0x3;
+			break;
+		case MSM_HDMI_AUDIO_CHANNEL_6:
+			channel_count = 5;
+			/* RR,RL,FC,LFE,FR,FL */
+			channel_allocation = 0xB;
+			break;
+		case MSM_HDMI_AUDIO_CHANNEL_8:
+			channel_count = 7;
+			/* FRC,FLC,RR,RL,FC,LFE,FR,FL */
+			channel_allocation = 0x1f;
+			break;
+		default:
+			pr_err("%s(): Unsupported num_of_channels = %u\n",
+					__func__, num_of_channels);
+			return -EINVAL;
+			break;
+		}
+
+		/* Program the Channel-Speaker allocation */
+		audio_info_1_reg = 0;
+		/* CA(channel_allocation) */
+		audio_info_1_reg |= channel_allocation & 0xff;
+		/* Program the Level shifter */
+		/* LSV(level_shift) */
+		audio_info_1_reg |= (level_shift << 11) & 0x00007800;
+		/* Program the Down-mix Inhibit Flag */
+		/* DM_INH(down_mix) */
+		audio_info_1_reg |= (down_mix << 15) & 0x00008000;
+
+		/* HDMI_AUDIO_INFO1[0x00E8] */
+		HDMI_OUTP(0x00E8, audio_info_1_reg);
+
+		/* Calculate CheckSum
+		   Sum of all the bytes in the Audio Info Packet bytes
+		   (See table 8.4 in HDMI spec) */
+		check_sum = 0;
+		/* HDMI_AUDIO_INFO_FRAME_PACKET_HEADER_TYPE[0x84] */
+		check_sum += 0x84;
+		/* HDMI_AUDIO_INFO_FRAME_PACKET_HEADER_VERSION[0x01] */
+		check_sum += 1;
+		/* HDMI_AUDIO_INFO_FRAME_PACKET_LENGTH[0x0A] */
+		check_sum += 0x0A;
+		check_sum += channel_count;
+		check_sum += channel_allocation;
+		/* See Table 8.5 in HDMI spec */
+		check_sum += (level_shift & 0xF) << 3 | (down_mix & 0x1) << 7;
+		check_sum &= 0xFF;
+		check_sum = (uint8) (256 - check_sum);
+
+		audio_info_0_reg = 0;
+		/* CHECKSUM(check_sum) */
+		audio_info_0_reg |= check_sum & 0xff;
+		/* CC(channel_count) */
+		audio_info_0_reg |= (channel_count << 8) & 0x00000700;
+
+		/* HDMI_AUDIO_INFO0[0x00E4] */
+		HDMI_OUTP(0x00E4, audio_info_0_reg);
+
+		/* Set these flags */
+		/* AUDIO_INFO_UPDATE | AUDIO_INFO_SOURCE | AUDIO_INFO_CONT
+		 | AUDIO_INFO_SEND */
+		audio_info_ctrl_reg |= 0x000000F0;
+	} else {
+		/* Clear these flags */
+		/* ~(AUDIO_INFO_UPDATE | AUDIO_INFO_SOURCE | AUDIO_INFO_CONT
+		   | AUDIO_INFO_SEND) */
+		audio_info_ctrl_reg &= ~0x000000F0;
+	}
+	/* HDMI_INFOFRAME_CTRL0[0x002C] */
+	HDMI_OUTP(0x002C, audio_info_ctrl_reg);
+
+
+	hdmi_msm_dump_regs("HDMI-AUDIO-ON: ");
+
+	return 0;
+
+}
+EXPORT_SYMBOL(hdmi_msm_audio_info_setup);
+
+static void hdmi_msm_en_gc_packet(boolean av_mute_is_requested)
+{
+	/* HDMI_GC[0x0040] */
+	HDMI_OUTP(0x0040, av_mute_is_requested ? 1 : 0);
+
+	/* GC packet enable (every frame) */
+	/* HDMI_VBI_PKT_CTRL[0x0028] */
+	hdmi_msm_rmw32or(0x0028, 3 << 4);
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_ISRC_ACP_SUPPORT
+static void hdmi_msm_en_isrc_packet(boolean isrc_is_continued)
+{
+	static const char isrc_psuedo_data[] =
+					"ISRC1:0123456789isrc2=ABCDEFGHIJ";
+	const uint32 * isrc_data = (const uint32 *) isrc_psuedo_data;
+
+	/* ISRC_STATUS =0b010 | ISRC_CONTINUE | ISRC_VALID */
+	/* HDMI_ISRC1_0[0x00048] */
+	HDMI_OUTP(0x00048, 2 | (isrc_is_continued ? 1 : 0) << 6 | 0 << 7);
+
+	/* HDMI_ISRC1_1[0x004C] */
+	HDMI_OUTP(0x004C, *isrc_data++);
+	/* HDMI_ISRC1_2[0x0050] */
+	HDMI_OUTP(0x0050, *isrc_data++);
+	/* HDMI_ISRC1_3[0x0054] */
+	HDMI_OUTP(0x0054, *isrc_data++);
+	/* HDMI_ISRC1_4[0x0058] */
+	HDMI_OUTP(0x0058, *isrc_data++);
+
+	/* HDMI_ISRC2_0[0x005C] */
+	HDMI_OUTP(0x005C, *isrc_data++);
+	/* HDMI_ISRC2_1[0x0060] */
+	HDMI_OUTP(0x0060, *isrc_data++);
+	/* HDMI_ISRC2_2[0x0064] */
+	HDMI_OUTP(0x0064, *isrc_data++);
+	/* HDMI_ISRC2_3[0x0068] */
+	HDMI_OUTP(0x0068, *isrc_data);
+
+	/* HDMI_VBI_PKT_CTRL[0x0028] */
+	/* ISRC Send + Continuous */
+	hdmi_msm_rmw32or(0x0028, 3 << 8);
+}
+#else
+static void hdmi_msm_en_isrc_packet(boolean isrc_is_continued)
+{
+	/*
+	 * Until end-to-end support for various audio packets
+	 */
+}
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_ISRC_ACP_SUPPORT
+static void hdmi_msm_en_acp_packet(uint32 byte1)
+{
+	/* HDMI_ACP[0x003C] */
+	HDMI_OUTP(0x003C, 2 | 1 << 8 | byte1 << 16);
+
+	/* HDMI_VBI_PKT_CTRL[0x0028] */
+	/* ACP send, s/w source */
+	hdmi_msm_rmw32or(0x0028, 3 << 12);
+}
+#else
+static void hdmi_msm_en_acp_packet(uint32 byte1)
+{
+	/*
+	 * Until end-to-end support for various audio packets
+	 */
+}
+#endif
+
+int hdmi_msm_audio_get_sample_rate(void)
+{
+	return msm_hdmi_sample_rate;
+}
+EXPORT_SYMBOL(hdmi_msm_audio_get_sample_rate);
+
+void hdmi_msm_audio_sample_rate_reset(int rate)
+{
+	msm_hdmi_sample_rate = rate;
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	if (hdmi_msm_has_hdcp())
+		hdcp_deauthenticate();
+	else
+#endif
+		hdmi_msm_turn_on();
+}
+EXPORT_SYMBOL(hdmi_msm_audio_sample_rate_reset);
+
+static void hdmi_msm_audio_setup(void)
+{
+	const int channels = MSM_HDMI_AUDIO_CHANNEL_2;
+
+	/* (0) for clr_avmute, (1) for set_avmute */
+	hdmi_msm_en_gc_packet(0);
+	/* (0) for isrc1 only, (1) for isrc1 and isrc2 */
+	hdmi_msm_en_isrc_packet(1);
+	/* arbitrary bit pattern for byte1 */
+	hdmi_msm_en_acp_packet(0x5a);
+	DEV_DBG("Not setting ACP, ISRC1, ISRC2 packets\n");
+	hdmi_msm_audio_acr_setup(TRUE,
+		external_common_state->video_resolution,
+		msm_hdmi_sample_rate, channels);
+	hdmi_msm_audio_info_setup(TRUE, channels, 0, 0, FALSE);
+
+	/* Turn on Audio FIFO and SAM DROP ISR */
+	HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) | BIT(1) | BIT(3));
+	DEV_INFO("HDMI Audio: Enabled\n");
+}
+
+static int hdmi_msm_audio_off(void)
+{
+	uint32 audio_pkt_ctrl, audio_cfg;
+	 /* Number of wait iterations */
+	int i = 10;
+	audio_pkt_ctrl = HDMI_INP_ND(0x0020);
+	audio_cfg = HDMI_INP_ND(0x01D0);
+
+	/* Checking BIT[0] of AUDIO PACKET CONTROL and */
+	/* AUDIO CONFIGURATION register */
+	while (((audio_pkt_ctrl & 0x00000001) || (audio_cfg & 0x00000001))
+		&& (i--)) {
+		audio_pkt_ctrl = HDMI_INP_ND(0x0020);
+		audio_cfg = HDMI_INP_ND(0x01D0);
+		DEV_DBG("%d times :: HDMI AUDIO PACKET is %08x and "
+		"AUDIO CFG is %08x", i, audio_pkt_ctrl, audio_cfg);
+		msleep(100);
+		if (!i) {
+			DEV_ERR("%s:failed to set BIT[0] AUDIO PACKET"
+			"CONTROL or AUDIO CONFIGURATION REGISTER\n",
+				__func__);
+			return -ETIMEDOUT;
+		}
+	}
+	hdmi_msm_audio_info_setup(FALSE, 0, 0, 0, FALSE);
+	hdmi_msm_audio_acr_setup(FALSE, 0, 0, 0);
+	DEV_INFO("HDMI Audio: Disabled\n");
+	return 0;
+}
+
+
+static uint8 hdmi_msm_avi_iframe_lut[][16] = {
+/*	480p60	480i60	576p50	576i50	720p60	 720p50	1080p60	1080i60	1080p50
+	1080i50	1080p24	1080p30	1080p25	640x480p 480p60_16_9 576p50_4_3 */
+	{0x10,	0x10,	0x10,	0x10,	0x10,	 0x10,	0x10,	0x10,	0x10,
+	 0x10,	0x10,	0x10,	0x10,	0x10, 0x10, 0x10}, /*00*/
+	{0x18,	0x18,	0x28,	0x28,	0x28,	 0x28,	0x28,	0x28,	0x28,
+	 0x28,	0x28,	0x28,	0x28,	0x18, 0x28, 0x18}, /*01*/
+	{0x04,	0x04,	0x04,	0x04,	0x04,	 0x04,	0x04,	0x04,	0x04,
+	 0x04,	0x04,	0x04,	0x04,	0x88, 0x04, 0x04}, /*02*/
+	{0x02,	0x06,	0x11,	0x15,	0x04,	 0x13,	0x10,	0x05,	0x1F,
+	 0x14,	0x20,	0x22,	0x21,	0x01, 0x03, 0x11}, /*03*/
+	{0x00,	0x01,	0x00,	0x01,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*04*/
+	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*05*/
+	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*06*/
+	{0xE1,	0xE1,	0x41,	0x41,	0xD1,	 0xd1,	0x39,	0x39,	0x39,
+	 0x39,	0x39,	0x39,	0x39,	0xe1, 0xE1, 0x41}, /*07*/
+	{0x01,	0x01,	0x02,	0x02,	0x02,	 0x02,	0x04,	0x04,	0x04,
+	 0x04,	0x04,	0x04,	0x04,	0x01, 0x01, 0x02}, /*08*/
+	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*09*/
+	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*10*/
+	{0xD1,	0xD1,	0xD1,	0xD1,	0x01,	 0x01,	0x81,	0x81,	0x81,
+	 0x81,	0x81,	0x81,	0x81,	0x81, 0xD1, 0xD1}, /*11*/
+	{0x02,	0x02,	0x02,	0x02,	0x05,	 0x05,	0x07,	0x07,	0x07,
+	 0x07,	0x07,	0x07,	0x07,	0x02, 0x02, 0x02}  /*12*/
+};
+
+static void hdmi_msm_avi_info_frame(void)
+{
+	/* two header + length + 13 data */
+	uint8 aviInfoFrame[16];
+	uint8 checksum;
+	uint32 sum;
+	uint32 regVal;
+	int i;
+	int mode = 0;
+	boolean use_ce_scan_info = TRUE;
+
+	switch (external_common_state->video_resolution) {
+	case HDMI_VFRMT_720x480p60_4_3:
+		mode = 0;
+		break;
+	case HDMI_VFRMT_720x480i60_16_9:
+		mode = 1;
+		break;
+	case HDMI_VFRMT_720x576p50_16_9:
+		mode = 2;
+		break;
+	case HDMI_VFRMT_720x576i50_16_9:
+		mode = 3;
+		break;
+	case HDMI_VFRMT_1280x720p60_16_9:
+		mode = 4;
+		break;
+	case HDMI_VFRMT_1280x720p50_16_9:
+		mode = 5;
+		break;
+	case HDMI_VFRMT_1920x1080p60_16_9:
+		mode = 6;
+		break;
+	case HDMI_VFRMT_1920x1080i60_16_9:
+		mode = 7;
+		break;
+	case HDMI_VFRMT_1920x1080p50_16_9:
+		mode = 8;
+		break;
+	case HDMI_VFRMT_1920x1080i50_16_9:
+		mode = 9;
+		break;
+	case HDMI_VFRMT_1920x1080p24_16_9:
+		mode = 10;
+		break;
+	case HDMI_VFRMT_1920x1080p30_16_9:
+		mode = 11;
+		break;
+	case HDMI_VFRMT_1920x1080p25_16_9:
+		mode = 12;
+		break;
+	case HDMI_VFRMT_640x480p60_4_3:
+		mode = 13;
+		break;
+	case HDMI_VFRMT_720x480p60_16_9:
+		mode = 14;
+		break;
+	case HDMI_VFRMT_720x576p50_4_3:
+		mode = 15;
+		break;
+	default:
+		DEV_INFO("%s: mode %d not supported\n", __func__,
+			external_common_state->video_resolution);
+		return;
+	}
+
+	/* InfoFrame Type = 82 */
+	aviInfoFrame[0]  = 0x82;
+	/* Version = 2 */
+	aviInfoFrame[1]  = 2;
+	/* Length of AVI InfoFrame = 13 */
+	aviInfoFrame[2]  = 13;
+
+	/* Data Byte 01: 0 Y1 Y0 A0 B1 B0 S1 S0 */
+	aviInfoFrame[3]  = hdmi_msm_avi_iframe_lut[0][mode];
+
+	/*
+	 * If the sink specified support for both underscan/overscan
+	 * then, by default, set the underscan bit.
+	 * Only checking underscan support for preferred format and cea formats
+	 */
+	if ((external_common_state->video_resolution ==
+			external_common_state->preferred_video_format)) {
+		use_ce_scan_info = FALSE;
+		switch (external_common_state->pt_scan_info) {
+		case 0:
+			/*
+			 * Need to use the info specified for the corresponding
+			 * IT or CE format
+			 */
+			DEV_DBG("%s: No underscan information specified for the"
+				" preferred video format\n", __func__);
+			use_ce_scan_info = TRUE;
+			break;
+		case 3:
+			DEV_DBG("%s: Setting underscan bit for the preferred"
+				" video format\n", __func__);
+			aviInfoFrame[3] |= 0x02;
+			break;
+		default:
+			DEV_DBG("%s: Underscan information not set for the"
+				" preferred video format\n", __func__);
+			break;
+		}
+	}
+
+	if (use_ce_scan_info) {
+		if (3 == external_common_state->ce_scan_info) {
+			DEV_DBG("%s: Setting underscan bit for the CE video"
+					" format\n", __func__);
+			aviInfoFrame[3] |= 0x02;
+		} else {
+			DEV_DBG("%s: Not setting underscan bit for the CE video"
+				       " format\n", __func__);
+		}
+	}
+
+	/* Data Byte 02: C1 C0 M1 M0 R3 R2 R1 R0 */
+	aviInfoFrame[4]  = hdmi_msm_avi_iframe_lut[1][mode];
+	/* Data Byte 03: ITC EC2 EC1 EC0 Q1 Q0 SC1 SC0 */
+	aviInfoFrame[5]  = hdmi_msm_avi_iframe_lut[2][mode];
+	/* Data Byte 04: 0 VIC6 VIC5 VIC4 VIC3 VIC2 VIC1 VIC0 */
+	aviInfoFrame[6]  = hdmi_msm_avi_iframe_lut[3][mode];
+	/* Data Byte 05: 0 0 0 0 PR3 PR2 PR1 PR0 */
+	aviInfoFrame[7]  = hdmi_msm_avi_iframe_lut[4][mode];
+	/* Data Byte 06: LSB Line No of End of Top Bar */
+	aviInfoFrame[8]  = hdmi_msm_avi_iframe_lut[5][mode];
+	/* Data Byte 07: MSB Line No of End of Top Bar */
+	aviInfoFrame[9]  = hdmi_msm_avi_iframe_lut[6][mode];
+	/* Data Byte 08: LSB Line No of Start of Bottom Bar */
+	aviInfoFrame[10] = hdmi_msm_avi_iframe_lut[7][mode];
+	/* Data Byte 09: MSB Line No of Start of Bottom Bar */
+	aviInfoFrame[11] = hdmi_msm_avi_iframe_lut[8][mode];
+	/* Data Byte 10: LSB Pixel Number of End of Left Bar */
+	aviInfoFrame[12] = hdmi_msm_avi_iframe_lut[9][mode];
+	/* Data Byte 11: MSB Pixel Number of End of Left Bar */
+	aviInfoFrame[13] = hdmi_msm_avi_iframe_lut[10][mode];
+	/* Data Byte 12: LSB Pixel Number of Start of Right Bar */
+	aviInfoFrame[14] = hdmi_msm_avi_iframe_lut[11][mode];
+	/* Data Byte 13: MSB Pixel Number of Start of Right Bar */
+	aviInfoFrame[15] = hdmi_msm_avi_iframe_lut[12][mode];
+
+	sum = 0;
+	for (i = 0; i < 16; i++)
+		sum += aviInfoFrame[i];
+	sum &= 0xFF;
+	sum = 256 - sum;
+	checksum = (uint8) sum;
+
+	regVal = aviInfoFrame[5];
+	regVal = regVal << 8 | aviInfoFrame[4];
+	regVal = regVal << 8 | aviInfoFrame[3];
+	regVal = regVal << 8 | checksum;
+	HDMI_OUTP(0x006C, regVal);
+
+	regVal = aviInfoFrame[9];
+	regVal = regVal << 8 | aviInfoFrame[8];
+	regVal = regVal << 8 | aviInfoFrame[7];
+	regVal = regVal << 8 | aviInfoFrame[6];
+	HDMI_OUTP(0x0070, regVal);
+
+	regVal = aviInfoFrame[13];
+	regVal = regVal << 8 | aviInfoFrame[12];
+	regVal = regVal << 8 | aviInfoFrame[11];
+	regVal = regVal << 8 | aviInfoFrame[10];
+	HDMI_OUTP(0x0074, regVal);
+
+	regVal = aviInfoFrame[1];
+	regVal = regVal << 16 | aviInfoFrame[15];
+	regVal = regVal << 8 | aviInfoFrame[14];
+	HDMI_OUTP(0x0078, regVal);
+
+	/* INFOFRAME_CTRL0[0x002C] */
+	/* 0x3 for AVI InfFrame enable (every frame) */
+	HDMI_OUTP(0x002C, HDMI_INP(0x002C) | 0x00000003L);
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_3D
+static void hdmi_msm_vendor_infoframe_packetsetup(void)
+{
+	uint32 packet_header      = 0;
+	uint32 check_sum          = 0;
+	uint32 packet_payload     = 0;
+
+	if (!external_common_state->format_3d) {
+		HDMI_OUTP(0x0034, 0);
+		return;
+	}
+
+	/* 0x0084 GENERIC0_HDR
+	 *   HB0             7:0  NUM
+	 *   HB1            15:8  NUM
+	 *   HB2           23:16  NUM */
+	/* Setup Packet header and payload */
+	/* 0x81 VS_INFO_FRAME_ID
+	   0x01 VS_INFO_FRAME_VERSION
+	   0x1B VS_INFO_FRAME_PAYLOAD_LENGTH */
+	packet_header  = 0x81 | (0x01 << 8) | (0x1B << 16);
+	HDMI_OUTP(0x0084, packet_header);
+
+	check_sum  = packet_header & 0xff;
+	check_sum += (packet_header >> 8) & 0xff;
+	check_sum += (packet_header >> 16) & 0xff;
+
+	/* 0x008C GENERIC0_1
+	 *   BYTE4           7:0  NUM
+	 *   BYTE5          15:8  NUM
+	 *   BYTE6         23:16  NUM
+	 *   BYTE7         31:24  NUM */
+	/* 0x02 VS_INFO_FRAME_3D_PRESENT */
+	packet_payload  = 0x02 << 5;
+	switch (external_common_state->format_3d) {
+	case 1:
+		/* 0b1000 VIDEO_3D_FORMAT_SIDE_BY_SIDE_HALF */
+		packet_payload |= (0x08 << 8) << 4;
+		break;
+	case 2:
+		/* 0b0110 VIDEO_3D_FORMAT_TOP_AND_BOTTOM_HALF */
+		packet_payload |= (0x06 << 8) << 4;
+		break;
+	}
+	HDMI_OUTP(0x008C, packet_payload);
+
+	check_sum += packet_payload & 0xff;
+	check_sum += (packet_payload >> 8) & 0xff;
+
+	#define IEEE_REGISTRATION_ID	0xC03
+	/* Next 3 bytes are IEEE Registration Identifcation */
+	/* 0x0088 GENERIC0_0
+	 *   BYTE0           7:0  NUM (checksum)
+	 *   BYTE1          15:8  NUM
+	 *   BYTE2         23:16  NUM
+	 *   BYTE3         31:24  NUM */
+	check_sum += IEEE_REGISTRATION_ID & 0xff;
+	check_sum += (IEEE_REGISTRATION_ID >> 8) & 0xff;
+	check_sum += (IEEE_REGISTRATION_ID >> 16) & 0xff;
+
+	HDMI_OUTP(0x0088, (0x100 - (0xff & check_sum))
+		| ((IEEE_REGISTRATION_ID & 0xff) << 8)
+		| (((IEEE_REGISTRATION_ID >> 8) & 0xff) << 16)
+		| (((IEEE_REGISTRATION_ID >> 16) & 0xff) << 24));
+
+	/* 0x0034 GEN_PKT_CTRL
+	 *   GENERIC0_SEND   0      0 = Disable Generic0 Packet Transmission
+	 *                          1 = Enable Generic0 Packet Transmission
+	 *   GENERIC0_CONT   1      0 = Send Generic0 Packet on next frame only
+	 *                          1 = Send Generic0 Packet on every frame
+	 *   GENERIC0_UPDATE 2      NUM
+	 *   GENERIC1_SEND   4      0 = Disable Generic1 Packet Transmission
+	 *                          1 = Enable Generic1 Packet Transmission
+	 *   GENERIC1_CONT   5      0 = Send Generic1 Packet on next frame only
+	 *                          1 = Send Generic1 Packet on every frame
+	 *   GENERIC0_LINE   21:16  NUM
+	 *   GENERIC1_LINE   29:24  NUM
+	 */
+	/* GENERIC0_LINE | GENERIC0_UPDATE | GENERIC0_CONT | GENERIC0_SEND
+	 * Setup HDMI TX generic packet control
+	 * Enable this packet to transmit every frame
+	 * Enable this packet to transmit every frame
+	 * Enable HDMI TX engine to transmit Generic packet 0 */
+	HDMI_OUTP(0x0034, (1 << 16) | (1 << 2) | BIT(1) | BIT(0));
+}
+
+static void hdmi_msm_switch_3d(boolean on)
+{
+	mutex_lock(&external_common_state_hpd_mutex);
+	if (external_common_state->hpd_state)
+		hdmi_msm_vendor_infoframe_packetsetup();
+	mutex_unlock(&external_common_state_hpd_mutex);
+}
+#endif
+
+#define IFRAME_CHECKSUM_32(d) \
+	((d & 0xff) + ((d >> 8) & 0xff) + \
+	((d >> 16) & 0xff) + ((d >> 24) & 0xff))
+
+static void hdmi_msm_spd_infoframe_packetsetup(void)
+{
+	uint32 packet_header  = 0;
+	uint32 check_sum      = 0;
+	uint32 packet_payload = 0;
+	uint32 packet_control = 0;
+
+	uint8 *vendor_name = external_common_state->spd_vendor_name;
+	uint8 *product_description =
+		external_common_state->spd_product_description;
+
+	/* 0x00A4 GENERIC1_HDR
+	 *   HB0             7:0  NUM
+	 *   HB1            15:8  NUM
+	 *   HB2           23:16  NUM */
+	/* Setup Packet header and payload */
+	/* 0x83 InfoFrame Type Code
+	   0x01 InfoFrame Version Number
+	   0x19 Length of Source Product Description InfoFrame
+	*/
+	packet_header  = 0x83 | (0x01 << 8) | (0x19 << 16);
+	HDMI_OUTP(0x00A4, packet_header);
+	check_sum += IFRAME_CHECKSUM_32(packet_header);
+
+	/* 0x00AC GENERIC1_1
+	 *   BYTE4           7:0  VENDOR_NAME[3]
+	 *   BYTE5          15:8  VENDOR_NAME[4]
+	 *   BYTE6         23:16  VENDOR_NAME[5]
+	 *   BYTE7         31:24  VENDOR_NAME[6] */
+	packet_payload = (vendor_name[3] & 0x7f)
+		| ((vendor_name[4] & 0x7f) << 8)
+		| ((vendor_name[5] & 0x7f) << 16)
+		| ((vendor_name[6] & 0x7f) << 24);
+	HDMI_OUTP(0x00AC, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* Product Description (7-bit ASCII code) */
+	/* 0x00B0 GENERIC1_2
+	 *   BYTE8           7:0  VENDOR_NAME[7]
+	 *   BYTE9          15:8  PRODUCT_NAME[ 0]
+	 *   BYTE10        23:16  PRODUCT_NAME[ 1]
+	 *   BYTE11        31:24  PRODUCT_NAME[ 2] */
+	packet_payload = (vendor_name[7] & 0x7f)
+		| ((product_description[0] & 0x7f) << 8)
+		| ((product_description[1] & 0x7f) << 16)
+		| ((product_description[2] & 0x7f) << 24);
+	HDMI_OUTP(0x00B0, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* 0x00B4 GENERIC1_3
+	 *   BYTE12          7:0  PRODUCT_NAME[ 3]
+	 *   BYTE13         15:8  PRODUCT_NAME[ 4]
+	 *   BYTE14        23:16  PRODUCT_NAME[ 5]
+	 *   BYTE15        31:24  PRODUCT_NAME[ 6] */
+	packet_payload = (product_description[3] & 0x7f)
+		| ((product_description[4] & 0x7f) << 8)
+		| ((product_description[5] & 0x7f) << 16)
+		| ((product_description[6] & 0x7f) << 24);
+	HDMI_OUTP(0x00B4, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* 0x00B8 GENERIC1_4
+	 *   BYTE16          7:0  PRODUCT_NAME[ 7]
+	 *   BYTE17         15:8  PRODUCT_NAME[ 8]
+	 *   BYTE18        23:16  PRODUCT_NAME[ 9]
+	 *   BYTE19        31:24  PRODUCT_NAME[10] */
+	packet_payload = (product_description[7] & 0x7f)
+		| ((product_description[8] & 0x7f) << 8)
+		| ((product_description[9] & 0x7f) << 16)
+		| ((product_description[10] & 0x7f) << 24);
+	HDMI_OUTP(0x00B8, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* 0x00BC GENERIC1_5
+	 *   BYTE20          7:0  PRODUCT_NAME[11]
+	 *   BYTE21         15:8  PRODUCT_NAME[12]
+	 *   BYTE22        23:16  PRODUCT_NAME[13]
+	 *   BYTE23        31:24  PRODUCT_NAME[14] */
+	packet_payload = (product_description[11] & 0x7f)
+		| ((product_description[12] & 0x7f) << 8)
+		| ((product_description[13] & 0x7f) << 16)
+		| ((product_description[14] & 0x7f) << 24);
+	HDMI_OUTP(0x00BC, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* 0x00C0 GENERIC1_6
+	 *   BYTE24          7:0  PRODUCT_NAME[15]
+	 *   BYTE25         15:8  Source Device Information
+	 *   BYTE26        23:16  NUM
+	 *   BYTE27        31:24  NUM */
+	/* Source Device Information
+	 * 00h unknown
+	 * 01h Digital STB
+	 * 02h DVD
+	 * 03h D-VHS
+	 * 04h HDD Video
+	 * 05h DVC
+	 * 06h DSC
+	 * 07h Video CD
+	 * 08h Game
+	 * 09h PC general */
+	packet_payload = (product_description[15] & 0x7f) | 0x00 << 8;
+	HDMI_OUTP(0x00C0, packet_payload);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+
+	/* Vendor Name (7bit ASCII code) */
+	/* 0x00A8 GENERIC1_0
+	 *   BYTE0           7:0  CheckSum
+	 *   BYTE1          15:8  VENDOR_NAME[0]
+	 *   BYTE2         23:16  VENDOR_NAME[1]
+	 *   BYTE3         31:24  VENDOR_NAME[2] */
+	packet_payload = ((vendor_name[0] & 0x7f) << 8)
+		| ((vendor_name[1] & 0x7f) << 16)
+		| ((vendor_name[2] & 0x7f) << 24);
+	check_sum += IFRAME_CHECKSUM_32(packet_payload);
+	packet_payload |= ((0x100 - (0xff & check_sum)) & 0xff);
+	HDMI_OUTP(0x00A8, packet_payload);
+
+	/* GENERIC1_LINE | GENERIC1_CONT | GENERIC1_SEND
+	 * Setup HDMI TX generic packet control
+	 * Enable this packet to transmit every frame
+	 * Enable HDMI TX engine to transmit Generic packet 1 */
+	packet_control = HDMI_INP_ND(0x0034);
+	packet_control |= ((0x1 << 24) | (1 << 5) | (1 << 4));
+	HDMI_OUTP(0x0034, packet_control);
+}
+
+int hdmi_msm_clk(int on)
+{
+	int rc;
+
+	DEV_DBG("HDMI Clk: %s\n", on ? "Enable" : "Disable");
+	if (on) {
+		rc = clk_prepare_enable(hdmi_msm_state->hdmi_app_clk);
+		if (rc) {
+			DEV_ERR("'hdmi_app_clk' clock enable failed, rc=%d\n",
+				rc);
+			return rc;
+		}
+
+		rc = clk_prepare_enable(hdmi_msm_state->hdmi_m_pclk);
+		if (rc) {
+			DEV_ERR("'hdmi_m_pclk' clock enable failed, rc=%d\n",
+				rc);
+			return rc;
+		}
+
+		rc = clk_prepare_enable(hdmi_msm_state->hdmi_s_pclk);
+		if (rc) {
+			DEV_ERR("'hdmi_s_pclk' clock enable failed, rc=%d\n",
+				rc);
+			return rc;
+		}
+	} else {
+		clk_disable_unprepare(hdmi_msm_state->hdmi_app_clk);
+		clk_disable_unprepare(hdmi_msm_state->hdmi_m_pclk);
+		clk_disable_unprepare(hdmi_msm_state->hdmi_s_pclk);
+	}
+
+	return 0;
+}
+
+static void hdmi_msm_turn_on(void)
+{
+	uint32 audio_pkt_ctrl, audio_cfg;
+	/*
+	 * Number of wait iterations for QDSP to disable Audio Engine
+	 * before resetting HDMI core
+	 */
+	int i = 10;
+	audio_pkt_ctrl = HDMI_INP_ND(0x0020);
+	audio_cfg = HDMI_INP_ND(0x01D0);
+
+	/*
+	 * Checking BIT[0] of AUDIO PACKET CONTROL and
+	 * AUDIO CONFIGURATION register
+	 */
+	while (((audio_pkt_ctrl & 0x00000001) || (audio_cfg & 0x00000001))
+		&& (i--)) {
+		audio_pkt_ctrl = HDMI_INP_ND(0x0020);
+		audio_cfg = HDMI_INP_ND(0x01D0);
+		DEV_DBG("%d times :: HDMI AUDIO PACKET is %08x and "
+			"AUDIO CFG is %08x", i, audio_pkt_ctrl, audio_cfg);
+		msleep(20);
+	}
+
+	hdmi_msm_set_mode(FALSE);
+	mutex_lock(&hdcp_auth_state_mutex);
+	hdmi_msm_reset_core();
+	mutex_unlock(&hdcp_auth_state_mutex);
+
+	hdmi_msm_init_phy(external_common_state->video_resolution);
+	/* HDMI_USEC_REFTIMER[0x0208] */
+	HDMI_OUTP(0x0208, 0x0001001B);
+
+	hdmi_msm_set_mode(TRUE);
+
+	hdmi_msm_video_setup(external_common_state->video_resolution);
+	if (!hdmi_msm_is_dvi_mode())
+		hdmi_msm_audio_setup();
+	hdmi_msm_avi_info_frame();
+#ifdef CONFIG_FB_MSM_HDMI_3D
+	hdmi_msm_vendor_infoframe_packetsetup();
+#endif
+	hdmi_msm_spd_infoframe_packetsetup();
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	if (hdmi_msm_state->reauth) {
+		hdmi_msm_hdcp_enable();
+		hdmi_msm_state->reauth = FALSE ;
+	}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	/* re-initialize CEC if enabled */
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->cec_enabled == true) {
+		hdmi_msm_cec_init();
+		hdmi_msm_cec_write_logical_addr(
+			hdmi_msm_state->cec_logical_addr);
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+	DEV_INFO("HDMI Core: Initialized\n");
+}
+
+static void hdmi_msm_hpd_state_timer(unsigned long data)
+{
+	if (!work_busy(&hdmi_msm_state->hpd_state_work)) {
+		/*
+		 * There is no event currently queued.
+		 * Only queue the work if this event has not already
+		 * been processed.
+		 */
+		if (external_common_state->hpd_state !=
+				hdmi_msm_state->hpd_state_in_isr) {
+			/*
+			 * There is no need to use any synchronization
+			 * construct for safeguarding these state vairables
+			 * here since the only other place these are modified
+			 * is in the HPD work thread, which is known to be not
+			 * pending/running.
+			 */
+			external_common_state->hpd_state =
+				hdmi_msm_state->hpd_state_in_isr;
+			DEV_DBG("%s: Queuing work to handle HPD %s event\n",
+					__func__,
+					external_common_state->hpd_state ?
+					"connect" : "disconnect");
+			queue_work(hdmi_work_queue,
+					&hdmi_msm_state->hpd_state_work);
+			return;
+		}
+	}
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+static void hdmi_msm_hdcp_timer(unsigned long data)
+{
+	queue_work(hdmi_work_queue, &hdmi_msm_state->hdcp_work);
+}
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+static void hdmi_msm_cec_read_timer_func(unsigned long data)
+{
+	queue_work(hdmi_work_queue, &hdmi_msm_state->cec_latch_detect_work);
+}
+#endif
+
+static void hdmi_msm_hpd_off(void)
+{
+	int rc = 0;
+
+	if (!hdmi_msm_state->hpd_initialized) {
+		DEV_DBG("%s: HPD is already OFF, returning\n", __func__);
+		return;
+	}
+
+	DEV_DBG("%s: (timer, 5V, IRQ off)\n", __func__);
+	del_timer(&hdmi_msm_state->hpd_state_timer);
+	disable_irq(hdmi_msm_state->irq);
+
+	/* Disable HPD interrupt */
+	HDMI_OUTP(0x0254, 0);
+	DEV_DBG("%s: Disabling HPD_CTRLd\n", __func__);
+
+	hdmi_msm_set_mode(FALSE);
+	hdmi_msm_state->pd->enable_5v(0);
+	hdmi_msm_clk(0);
+	rc = hdmi_msm_state->pd->gpio_config(0);
+	if (rc != 0)
+		DEV_INFO("%s: Failed to disable GPIOs. Error=%d\n",
+				__func__, rc);
+	hdmi_msm_state->hpd_initialized = FALSE;
+}
+
+static void hdmi_msm_dump_regs(const char *prefix)
+{
+#ifdef REG_DUMP
+	print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 32, 4,
+		(void *)MSM_HDMI_BASE, 0x0334, false);
+#endif
+}
+
+static int hdmi_msm_hpd_on(void)
+{
+	static int phy_reset_done;
+	uint32 hpd_ctrl;
+	int rc = 0;
+
+	if (hdmi_msm_state->hpd_initialized) {
+		DEV_DBG("%s: HPD is already ON\n", __func__);
+	} else {
+		rc = hdmi_msm_state->pd->gpio_config(1);
+		if (rc) {
+			DEV_ERR("%s: Failed to enable GPIOs. Error=%d\n",
+					__func__, rc);
+			goto error1;
+		}
+
+		rc = hdmi_msm_clk(1);
+		if (rc) {
+			DEV_ERR("%s: Failed to enable clocks. Error=%d\n",
+					__func__, rc);
+			goto error2;
+		}
+
+		rc = hdmi_msm_state->pd->enable_5v(1);
+		if (rc) {
+			DEV_ERR("%s: Failed to enable 5V regulator. Error=%d\n",
+					__func__, rc);
+			goto error3;
+		}
+		hdmi_msm_dump_regs("HDMI-INIT: ");
+
+		hdmi_msm_set_mode(FALSE);
+		if (!phy_reset_done) {
+			hdmi_phy_reset();
+			phy_reset_done = 1;
+		}
+		hdmi_msm_set_mode(TRUE);
+
+		/* HDMI_USEC_REFTIMER[0x0208] */
+		HDMI_OUTP(0x0208, 0x0001001B);
+
+		/* Set up HPD state variables */
+		mutex_lock(&external_common_state_hpd_mutex);
+		external_common_state->hpd_state = 0;
+		hdmi_msm_state->hpd_state_in_isr = 0;
+		mutex_unlock(&external_common_state_hpd_mutex);
+		mutex_lock(&hdmi_msm_state_mutex);
+		hdmi_msm_state->hpd_cable_chg_detected = TRUE;
+		mutex_unlock(&hdmi_msm_state_mutex);
+
+		/* Set up HPD_CTRL to sense HPD event */
+		HDMI_OUTP(0x0254, 0x6);
+		DEV_DBG("%s: Setting HPD_CTRL=%d\n", __func__,
+				HDMI_INP(0x0254));
+
+		hdmi_msm_state->hpd_initialized = TRUE;
+
+		enable_irq(hdmi_msm_state->irq);
+
+		/* set timeout to 4.1ms (max) for hardware debounce */
+		hpd_ctrl = HDMI_INP(0x0258) | 0x1FFF;
+
+		/* Toggle HPD circuit to trigger HPD sense */
+		HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
+		HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
+	}
+
+	DEV_DBG("%s: (IRQ, 5V on)\n", __func__);
+	return 0;
+
+error3:
+	hdmi_msm_clk(0);
+error2:
+	hdmi_msm_state->pd->gpio_config(0);
+error1:
+	return rc;
+}
+
+static int hdmi_msm_power_ctrl(boolean enable)
+{
+	int rc = 0;
+
+	if (enable) {
+		/*
+		 * Enable HPD only if the UI option is on or if
+		 * HDMI is configured as the primary display
+		 */
+		if (hdmi_prim_display ||
+			external_common_state->hpd_feature_on) {
+			DEV_DBG("%s: Turning HPD ciruitry on\n", __func__);
+			rc = hdmi_msm_hpd_on();
+		}
+	} else {
+		DEV_DBG("%s: Turning HPD ciruitry off\n", __func__);
+		hdmi_msm_hpd_off();
+	}
+
+	return rc;
+}
+
+static int hdmi_msm_power_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+	bool changed;
+
+	if (!hdmi_msm_state || !hdmi_msm_state->hdmi_app_clk || !MSM_HDMI_BASE)
+		return -ENODEV;
+
+	DEV_INFO("power: ON (%dx%d %d)\n", mfd->var_xres, mfd->var_yres,
+		mfd->var_pixclock);
+
+	changed = hdmi_common_get_video_format_from_drv_data(mfd);
+	hdmi_msm_audio_info_setup(TRUE, 0, 0, 0, FALSE);
+
+	mutex_lock(&external_common_state_hpd_mutex);
+	hdmi_msm_state->panel_power_on = TRUE;
+	if (external_common_state->hpd_state && hdmi_msm_is_power_on()) {
+		DEV_DBG("%s: Turning HDMI on\n", __func__);
+		mutex_unlock(&external_common_state_hpd_mutex);
+		hdmi_msm_turn_on();
+
+		/* Kick off HDCP Authentication */
+		mutex_lock(&hdcp_auth_state_mutex);
+		hdmi_msm_state->reauth = FALSE;
+		hdmi_msm_state->full_auth_done = FALSE;
+		mutex_unlock(&hdcp_auth_state_mutex);
+		mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
+	} else
+		mutex_unlock(&external_common_state_hpd_mutex);
+
+	hdmi_msm_dump_regs("HDMI-ON: ");
+
+	DEV_INFO("power=%s DVI= %s\n",
+		hdmi_msm_is_power_on() ? "ON" : "OFF" ,
+		hdmi_msm_is_dvi_mode() ? "ON" : "OFF");
+	return 0;
+}
+
+/* Note that power-off will also be called when the cable-remove event is
+ * processed on the user-space and as a result the framebuffer is powered
+ * down.  However, we are still required to be able to detect a cable-insert
+ * event; so for now leave the HDMI engine running; so that the HPD IRQ is
+ * still being processed.
+ */
+static int hdmi_msm_power_off(struct platform_device *pdev)
+{
+	if (!hdmi_msm_state->hdmi_app_clk)
+		return -ENODEV;
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->hdcp_activating) {
+		hdmi_msm_state->panel_power_on = FALSE;
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_INFO("HDCP: activating, returning\n");
+		return 0;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+	DEV_INFO("power: OFF (audio off, Reset Core)\n");
+	hdmi_msm_audio_off();
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	hdcp_deauthenticate();
+#endif
+	hdmi_msm_powerdown_phy();
+
+	hdmi_msm_state->panel_power_on = FALSE;
+	return 0;
+}
+
+static int __devinit hdmi_msm_probe(struct platform_device *pdev)
+{
+	int rc;
+	struct platform_device *fb_dev;
+
+	if (cpu_is_apq8064())
+		return -ENODEV;
+
+	if (!hdmi_msm_state) {
+		pr_err("%s: hdmi_msm_state is NULL\n", __func__);
+		return -ENOMEM;
+	}
+
+	external_common_state->dev = &pdev->dev;
+	DEV_DBG("probe\n");
+	if (pdev->id == 0) {
+		struct resource *res;
+
+		#define GET_RES(name, mode) do {			\
+			res = platform_get_resource_byname(pdev, mode, name); \
+			if (!res) {					\
+				DEV_ERR("'" name "' resource not found\n"); \
+				rc = -ENODEV;				\
+				goto error;				\
+			}						\
+		} while (0)
+
+		#define IO_REMAP(var, name) do {			\
+			GET_RES(name, IORESOURCE_MEM);			\
+			var = ioremap(res->start, resource_size(res));	\
+			if (!var) {					\
+				DEV_ERR("'" name "' ioremap failed\n");	\
+				rc = -ENOMEM;				\
+				goto error;				\
+			}						\
+		} while (0)
+
+		#define GET_IRQ(var, name) do {				\
+			GET_RES(name, IORESOURCE_IRQ);			\
+			var = res->start;				\
+		} while (0)
+
+		IO_REMAP(hdmi_msm_state->qfprom_io, "hdmi_msm_qfprom_addr");
+		hdmi_msm_state->hdmi_io = MSM_HDMI_BASE;
+		GET_IRQ(hdmi_msm_state->irq, "hdmi_msm_irq");
+
+		hdmi_msm_state->pd = pdev->dev.platform_data;
+
+		#undef GET_RES
+		#undef IO_REMAP
+		#undef GET_IRQ
+		return 0;
+	}
+
+	hdmi_msm_state->hdmi_app_clk = clk_get(&pdev->dev, "core_clk");
+	if (IS_ERR(hdmi_msm_state->hdmi_app_clk)) {
+		DEV_ERR("'core_clk' clk not found\n");
+		rc = IS_ERR(hdmi_msm_state->hdmi_app_clk);
+		goto error;
+	}
+
+	hdmi_msm_state->hdmi_m_pclk = clk_get(&pdev->dev, "master_iface_clk");
+	if (IS_ERR(hdmi_msm_state->hdmi_m_pclk)) {
+		DEV_ERR("'master_iface_clk' clk not found\n");
+		rc = IS_ERR(hdmi_msm_state->hdmi_m_pclk);
+		goto error;
+	}
+
+	hdmi_msm_state->hdmi_s_pclk = clk_get(&pdev->dev, "slave_iface_clk");
+	if (IS_ERR(hdmi_msm_state->hdmi_s_pclk)) {
+		DEV_ERR("'slave_iface_clk' clk not found\n");
+		rc = IS_ERR(hdmi_msm_state->hdmi_s_pclk);
+		goto error;
+	}
+
+	rc = check_hdmi_features();
+	if (rc) {
+		DEV_ERR("Init FAILED: check_hdmi_features rc=%d\n", rc);
+		goto error;
+	}
+
+	if (!hdmi_msm_state->pd->core_power) {
+		DEV_ERR("Init FAILED: core_power function missing\n");
+		rc = -ENODEV;
+		goto error;
+	}
+	if (!hdmi_msm_state->pd->enable_5v) {
+		DEV_ERR("Init FAILED: enable_5v function missing\n");
+		rc = -ENODEV;
+		goto error;
+	}
+
+	if (!hdmi_msm_state->pd->cec_power) {
+		DEV_ERR("Init FAILED: cec_power function missing\n");
+		rc = -ENODEV;
+		goto error;
+	}
+
+	rc = request_threaded_irq(hdmi_msm_state->irq, NULL, &hdmi_msm_isr,
+		IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "hdmi_msm_isr", NULL);
+	if (rc) {
+		DEV_ERR("Init FAILED: IRQ request, rc=%d\n", rc);
+		goto error;
+	}
+	disable_irq(hdmi_msm_state->irq);
+
+	init_timer(&hdmi_msm_state->hpd_state_timer);
+	hdmi_msm_state->hpd_state_timer.function =
+		hdmi_msm_hpd_state_timer;
+	hdmi_msm_state->hpd_state_timer.data = (uint32)NULL;
+
+	hdmi_msm_state->hpd_state_timer.expires = 0xffffffffL;
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	init_timer(&hdmi_msm_state->hdcp_timer);
+	hdmi_msm_state->hdcp_timer.function =
+		hdmi_msm_hdcp_timer;
+	hdmi_msm_state->hdcp_timer.data = (uint32)NULL;
+
+	hdmi_msm_state->hdcp_timer.expires = 0xffffffffL;
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	init_timer(&hdmi_msm_state->cec_read_timer);
+	hdmi_msm_state->cec_read_timer.function =
+		hdmi_msm_cec_read_timer_func;
+	hdmi_msm_state->cec_read_timer.data = (uint32)NULL;
+
+	hdmi_msm_state->cec_read_timer.expires = 0xffffffffL;
+ #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+
+	fb_dev = msm_fb_add_device(pdev);
+	if (fb_dev) {
+		rc = external_common_state_create(fb_dev);
+		if (rc) {
+			DEV_ERR("Init FAILED: hdmi_msm_state_create, rc=%d\n",
+				rc);
+			goto error;
+		}
+	} else
+		DEV_ERR("Init FAILED: failed to add fb device\n");
+
+	if (hdmi_prim_display) {
+		rc = hdmi_msm_hpd_on();
+		if (rc)
+			goto error;
+	}
+
+	if (hdmi_msm_has_hdcp()) {
+		/* Don't Set Encryption in case of non HDCP builds */
+		external_common_state->present_hdcp = FALSE;
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+		external_common_state->present_hdcp = TRUE;
+#endif
+	} else {
+		external_common_state->present_hdcp = FALSE;
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+		/*
+		 * If the device is not hdcp capable do
+		 * not start hdcp timer.
+		 */
+		del_timer(&hdmi_msm_state->hdcp_timer);
+#endif
+	}
+
+	/* Initialize hdmi node and register with switch driver */
+	if (hdmi_prim_display)
+		external_common_state->sdev.name = "hdmi_as_primary";
+	else
+		external_common_state->sdev.name = "hdmi";
+	if (switch_dev_register(&external_common_state->sdev) < 0)
+		DEV_ERR("Hdmi switch registration failed\n");
+
+	return 0;
+
+error:
+	if (hdmi_msm_state->qfprom_io)
+		iounmap(hdmi_msm_state->qfprom_io);
+	hdmi_msm_state->qfprom_io = NULL;
+
+	if (hdmi_msm_state->hdmi_io)
+		iounmap(hdmi_msm_state->hdmi_io);
+	hdmi_msm_state->hdmi_io = NULL;
+
+	external_common_state_remove();
+
+	if (hdmi_msm_state->hdmi_app_clk)
+		clk_put(hdmi_msm_state->hdmi_app_clk);
+	if (hdmi_msm_state->hdmi_m_pclk)
+		clk_put(hdmi_msm_state->hdmi_m_pclk);
+	if (hdmi_msm_state->hdmi_s_pclk)
+		clk_put(hdmi_msm_state->hdmi_s_pclk);
+
+	hdmi_msm_state->hdmi_app_clk = NULL;
+	hdmi_msm_state->hdmi_m_pclk = NULL;
+	hdmi_msm_state->hdmi_s_pclk = NULL;
+
+	return rc;
+}
+
+static int __devexit hdmi_msm_remove(struct platform_device *pdev)
+{
+	DEV_INFO("HDMI device: remove\n");
+
+	DEV_INFO("HDMI HPD: OFF\n");
+
+	/* Unregister hdmi node from switch driver */
+	switch_dev_unregister(&external_common_state->sdev);
+
+	hdmi_msm_hpd_off();
+	free_irq(hdmi_msm_state->irq, NULL);
+
+	if (hdmi_msm_state->qfprom_io)
+		iounmap(hdmi_msm_state->qfprom_io);
+	hdmi_msm_state->qfprom_io = NULL;
+
+	if (hdmi_msm_state->hdmi_io)
+		iounmap(hdmi_msm_state->hdmi_io);
+	hdmi_msm_state->hdmi_io = NULL;
+
+	external_common_state_remove();
+
+	if (hdmi_msm_state->hdmi_app_clk)
+		clk_put(hdmi_msm_state->hdmi_app_clk);
+	if (hdmi_msm_state->hdmi_m_pclk)
+		clk_put(hdmi_msm_state->hdmi_m_pclk);
+	if (hdmi_msm_state->hdmi_s_pclk)
+		clk_put(hdmi_msm_state->hdmi_s_pclk);
+
+	hdmi_msm_state->hdmi_app_clk = NULL;
+	hdmi_msm_state->hdmi_m_pclk = NULL;
+	hdmi_msm_state->hdmi_s_pclk = NULL;
+
+	kfree(hdmi_msm_state);
+	hdmi_msm_state = NULL;
+
+	return 0;
+}
+
+static int hdmi_msm_hpd_feature(int on)
+{
+	int rc = 0;
+
+	DEV_INFO("%s: %d\n", __func__, on);
+	if (on) {
+		rc = hdmi_msm_hpd_on();
+	} else {
+		hdmi_msm_hpd_off();
+		/* Set HDMI switch node to 0 on HPD feature disable */
+		switch_set_state(&external_common_state->sdev, 0);
+	}
+
+	return rc;
+}
+
+static struct platform_driver this_driver = {
+	.probe = hdmi_msm_probe,
+	.remove = hdmi_msm_remove,
+	.driver.name = "hdmi_msm",
+};
+
+static struct msm_fb_panel_data hdmi_msm_panel_data = {
+	.on = hdmi_msm_power_on,
+	.off = hdmi_msm_power_off,
+	.power_ctrl = hdmi_msm_power_ctrl,
+};
+
+static struct platform_device this_device = {
+	.name = "hdmi_msm",
+	.id = 1,
+	.dev.platform_data = &hdmi_msm_panel_data,
+};
+
+static int __init hdmi_msm_init(void)
+{
+	int rc;
+
+	if (cpu_is_msm8930())
+		return 0;
+
+	if (msm_fb_detect_client("hdmi_msm"))
+		return 0;
+
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+	hdmi_prim_display = 1;
+#endif
+
+	hdmi_msm_setup_video_mode_lut();
+	hdmi_msm_state = kzalloc(sizeof(*hdmi_msm_state), GFP_KERNEL);
+	if (!hdmi_msm_state) {
+		pr_err("hdmi_msm_init FAILED: out of memory\n");
+		rc = -ENOMEM;
+		goto init_exit;
+	}
+
+	external_common_state = &hdmi_msm_state->common;
+	external_common_state->video_resolution = HDMI_VFRMT_1920x1080p60_16_9;
+#ifdef CONFIG_FB_MSM_HDMI_3D
+	external_common_state->switch_3d = hdmi_msm_switch_3d;
+#endif
+	memset(external_common_state->spd_vendor_name, 0,
+			sizeof(external_common_state->spd_vendor_name));
+	memset(external_common_state->spd_product_description, 0,
+			sizeof(external_common_state->spd_product_description));
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	hdmi_msm_state->cec_queue_start =
+		kzalloc(sizeof(struct hdmi_msm_cec_msg)*CEC_QUEUE_SIZE,
+			GFP_KERNEL);
+	if (!hdmi_msm_state->cec_queue_start) {
+		pr_err("hdmi_msm_init FAILED: CEC queue out of memory\n");
+		rc = -ENOMEM;
+		goto init_exit;
+	}
+
+	hdmi_msm_state->cec_queue_wr = hdmi_msm_state->cec_queue_start;
+	hdmi_msm_state->cec_queue_rd = hdmi_msm_state->cec_queue_start;
+	hdmi_msm_state->cec_queue_full = false;
+#endif
+
+	/*
+	 * Create your work queue
+	 * allocs and returns ptr
+	*/
+	hdmi_work_queue = create_workqueue("hdmi_hdcp");
+	external_common_state->hpd_feature = hdmi_msm_hpd_feature;
+
+	rc = platform_driver_register(&this_driver);
+	if (rc) {
+		pr_err("hdmi_msm_init FAILED: platform_driver_register rc=%d\n",
+		       rc);
+		goto init_exit;
+	}
+
+	hdmi_common_init_panel_info(&hdmi_msm_panel_data.panel_info);
+	init_completion(&hdmi_msm_state->ddc_sw_done);
+	INIT_WORK(&hdmi_msm_state->hpd_state_work, hdmi_msm_hpd_state_work);
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	init_completion(&hdmi_msm_state->hdcp_success_done);
+	INIT_WORK(&hdmi_msm_state->hdcp_reauth_work, hdmi_msm_hdcp_reauth_work);
+	INIT_WORK(&hdmi_msm_state->hdcp_work, hdmi_msm_hdcp_work);
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	INIT_WORK(&hdmi_msm_state->cec_latch_detect_work,
+		  hdmi_msm_cec_latch_work);
+	init_completion(&hdmi_msm_state->cec_frame_wr_done);
+	init_completion(&hdmi_msm_state->cec_line_latch_wait);
+#endif
+
+	rc = platform_device_register(&this_device);
+	if (rc) {
+		pr_err("hdmi_msm_init FAILED: platform_device_register rc=%d\n",
+		       rc);
+		platform_driver_unregister(&this_driver);
+		goto init_exit;
+	}
+
+	pr_debug("%s: success:"
+#ifdef DEBUG
+		" DEBUG"
+#else
+		" RELEASE"
+#endif
+		" AUDIO EDID HPD HDCP"
+#ifndef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+		":0"
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+		" DVI"
+#ifndef CONFIG_FB_MSM_HDMI_MSM_PANEL_DVI_SUPPORT
+		":0"
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_DVI_SUPPORT */
+		"\n", __func__);
+
+	return 0;
+
+init_exit:
+	kfree(hdmi_msm_state);
+	hdmi_msm_state = NULL;
+
+	return rc;
+}
+
+static void __exit hdmi_msm_exit(void)
+{
+	platform_device_unregister(&this_device);
+	platform_driver_unregister(&this_driver);
+}
+
+module_init(hdmi_msm_init);
+module_exit(hdmi_msm_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.3");
+MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
+MODULE_DESCRIPTION("HDMI MSM TX driver");
diff --git a/drivers/video/msm/hdmi_msm.h b/drivers/video/msm/hdmi_msm.h
new file mode 100644
index 0000000..ede21dc
--- /dev/null
+++ b/drivers/video/msm/hdmi_msm.h
@@ -0,0 +1,137 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __HDMI_MSM_H__
+#define __HDMI_MSM_H__
+
+#include <mach/msm_iomap.h>
+#include "external_common.h"
+/* #define PORT_DEBUG */
+
+#ifdef PORT_DEBUG
+const char *hdmi_msm_name(uint32 offset);
+void hdmi_outp(uint32 offset, uint32 value);
+uint32 hdmi_inp(uint32 offset);
+
+#define HDMI_OUTP_ND(offset, value)	outpdw(MSM_HDMI_BASE+(offset), (value))
+#define HDMI_OUTP(offset, value)	hdmi_outp((offset), (value))
+#define HDMI_INP_ND(offset)		inpdw(MSM_HDMI_BASE+(offset))
+#define HDMI_INP(offset)		hdmi_inp((offset))
+#else
+#define HDMI_OUTP_ND(offset, value)	outpdw(MSM_HDMI_BASE+(offset), (value))
+#define HDMI_OUTP(offset, value)	outpdw(MSM_HDMI_BASE+(offset), (value))
+#define HDMI_INP_ND(offset)		inpdw(MSM_HDMI_BASE+(offset))
+#define HDMI_INP(offset)		inpdw(MSM_HDMI_BASE+(offset))
+#endif
+
+
+/*
+ * Ref. HDMI 1.4a
+ * Supplement-1 CEC Section 6, 7
+ */
+struct hdmi_msm_cec_msg {
+	uint8 sender_id;
+	uint8 recvr_id;
+	uint8 opcode;
+	uint8 operand[15];
+	uint8 frame_size;
+	uint8 retransmit;
+};
+
+#define QFPROM_BASE		((uint32)hdmi_msm_state->qfprom_io)
+#define HDMI_BASE		((uint32)hdmi_msm_state->hdmi_io)
+
+struct hdmi_msm_state_type {
+	boolean panel_power_on;
+	boolean hpd_initialized;
+	boolean hpd_state_in_isr;
+#ifdef CONFIG_SUSPEND
+	boolean pm_suspended;
+#endif
+	boolean hpd_cable_chg_detected;
+	boolean full_auth_done;
+	boolean hpd_during_auth;
+	struct work_struct hpd_state_work;
+	struct timer_list hpd_state_timer;
+	struct completion ddc_sw_done;
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	boolean hdcp_activating;
+	boolean reauth ;
+	struct work_struct hdcp_reauth_work, hdcp_work;
+	struct completion hdcp_success_done;
+	struct timer_list hdcp_timer;
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+	boolean cec_enabled;
+	unsigned int first_monitor;
+	int cec_logical_addr;
+	struct completion cec_frame_wr_done;
+	struct timer_list cec_read_timer;
+#define CEC_STATUS_WR_ERROR	0x0001
+#define CEC_STATUS_WR_DONE	0x0002
+#define CEC_STATUS_WR_TMOUT	0x0004
+	uint32 cec_frame_wr_status;
+
+	struct hdmi_msm_cec_msg *cec_queue_start;
+	struct hdmi_msm_cec_msg *cec_queue_wr;
+	struct hdmi_msm_cec_msg *cec_queue_rd;
+	boolean cec_queue_full;
+	boolean fsm_reset_done;
+
+	/*
+	 * CECT 9-5-1
+	 */
+	struct completion cec_line_latch_wait;
+	struct work_struct cec_latch_detect_work;
+
+#define CEC_QUEUE_SIZE		16
+#define CEC_QUEUE_END	 (hdmi_msm_state->cec_queue_start + CEC_QUEUE_SIZE)
+#define RETRANSMIT_MAX_NUM	7
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+
+	int irq;
+	struct msm_hdmi_platform_data *pd;
+	struct clk *hdmi_app_clk;
+	struct clk *hdmi_m_pclk;
+	struct clk *hdmi_s_pclk;
+	void __iomem *qfprom_io;
+	void __iomem *hdmi_io;
+
+	struct external_common_state_type common;
+};
+
+extern struct hdmi_msm_state_type *hdmi_msm_state;
+
+uint32 hdmi_msm_get_io_base(void);
+
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+void hdmi_msm_set_mode(boolean power_on);
+int hdmi_msm_clk(int on);
+void hdmi_phy_reset(void);
+void hdmi_msm_reset_core(void);
+void hdmi_msm_init_phy(int video_format);
+void hdmi_msm_powerdown_phy(void);
+void hdmi_frame_ctrl_cfg(const struct hdmi_disp_mode_timing_type *timing);
+void hdmi_msm_phy_status_poll(void);
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+void hdmi_msm_cec_init(void);
+void hdmi_msm_cec_write_logical_addr(int addr);
+void hdmi_msm_cec_msg_recv(void);
+void hdmi_msm_cec_one_touch_play(void);
+void hdmi_msm_cec_msg_send(struct hdmi_msm_cec_msg *msg);
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+
+#endif /* __HDMI_MSM_H__ */
diff --git a/drivers/video/msm/hdmi_sii9022.c b/drivers/video/msm/hdmi_sii9022.c
new file mode 100644
index 0000000..3d27488
--- /dev/null
+++ b/drivers/video/msm/hdmi_sii9022.c
@@ -0,0 +1,245 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include "msm_fb.h"
+
+#define DEVICE_NAME "sii9022"
+#define SII9022_DEVICE_ID   0xB0
+
+struct sii9022_i2c_addr_data{
+	u8 addr;
+	u8 data;
+};
+
+/* video mode data */
+static u8 video_mode_data[] = {
+	0x00,
+	0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
+};
+
+static u8 avi_io_format[] = {
+	0x09,
+	0x00, 0x00,
+};
+
+/* power state */
+static struct sii9022_i2c_addr_data regset0[] = {
+	{ 0x60, 0x04 },
+	{ 0x63, 0x00 },
+	{ 0x1E, 0x00 },
+};
+
+static u8 video_infoframe[] = {
+	0x0C,
+	0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
+	0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
+};
+
+/* configure audio */
+static struct sii9022_i2c_addr_data regset1[] = {
+	{ 0x26, 0x90 },
+	{ 0x20, 0x90 },
+	{ 0x1F, 0x80 },
+	{ 0x26, 0x80 },
+	{ 0x24, 0x02 },
+	{ 0x25, 0x0B },
+	{ 0xBC, 0x02 },
+	{ 0xBD, 0x24 },
+	{ 0xBE, 0x02 },
+};
+
+/* enable audio */
+static u8 misc_infoframe[] = {
+	0xBF,
+	0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+/* set HDMI, active */
+static struct sii9022_i2c_addr_data regset2[] = {
+	{ 0x1A, 0x01 },
+	{ 0x3D, 0x00 },
+};
+
+static int send_i2c_data(struct i2c_client *client,
+			 struct sii9022_i2c_addr_data *regset,
+			 int size)
+{
+	int i;
+	int rc = 0;
+
+	for (i = 0; i < size; i++) {
+		rc = i2c_smbus_write_byte_data(
+			client,
+			regset[i].addr, regset[i].data);
+		if (rc)
+			break;
+	}
+	return rc;
+}
+
+static int hdmi_sii_enable(struct i2c_client *client)
+{
+	int rc;
+	int retries = 10;
+	int count;
+
+	rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
+	if (rc)
+		goto enable_exit;
+
+	do {
+		msleep(1);
+		rc = i2c_smbus_read_byte_data(client, 0x1B);
+	} while ((rc != SII9022_DEVICE_ID) && retries--);
+
+	if (rc != SII9022_DEVICE_ID)
+		return -ENODEV;
+
+	rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
+	if (rc)
+		goto enable_exit;
+
+	count = ARRAY_SIZE(video_mode_data);
+	rc = i2c_master_send(client, video_mode_data, count);
+	if (rc != count) {
+		rc = -EIO;
+		goto enable_exit;
+	}
+
+	rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
+	if (rc)
+		goto enable_exit;
+	count = ARRAY_SIZE(avi_io_format);
+	rc = i2c_master_send(client, avi_io_format, count);
+	if (rc != count) {
+		rc = -EIO;
+		goto enable_exit;
+	}
+
+	rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
+	if (rc)
+		goto enable_exit;
+
+	count = ARRAY_SIZE(video_infoframe);
+	rc = i2c_master_send(client, video_infoframe, count);
+	if (rc != count) {
+		rc = -EIO;
+		goto enable_exit;
+	}
+
+	rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
+	if (rc)
+		goto enable_exit;
+
+	count = ARRAY_SIZE(misc_infoframe);
+	rc = i2c_master_send(client, misc_infoframe, count);
+	if (rc != count) {
+		rc = -EIO;
+		goto enable_exit;
+	}
+
+	rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
+	if (rc)
+		goto enable_exit;
+
+	return 0;
+enable_exit:
+	printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
+	return rc;
+}
+
+static const struct i2c_device_id hmdi_sii_id[] = {
+	{ DEVICE_NAME, 0 },
+	{ }
+};
+
+static int hdmi_sii_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	int rc;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
+		return -ENODEV;
+	rc = hdmi_sii_enable(client);
+	return rc;
+}
+
+
+static struct i2c_driver hdmi_sii_i2c_driver = {
+	.driver = {
+		.name = DEVICE_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = hdmi_sii_probe,
+	.remove =  __exit_p(hdmi_sii_remove),
+	.id_table = hmdi_sii_id,
+};
+
+static int __init hdmi_sii_init(void)
+{
+	int ret;
+	struct msm_panel_info pinfo;
+
+	if (msm_fb_detect_client("hdmi_sii9022"))
+		return 0;
+
+	pinfo.xres = 1280;
+	pinfo.yres = 720;
+	MSM_FB_SINGLE_MODE_PANEL(&pinfo);
+	pinfo.type = HDMI_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 18;
+	pinfo.fb_num = 2;
+	pinfo.clk_rate = 74250000;
+
+	pinfo.lcdc.h_back_porch = 124;
+	pinfo.lcdc.h_front_porch = 110;
+	pinfo.lcdc.h_pulse_width = 136;
+	pinfo.lcdc.v_back_porch = 19;
+	pinfo.lcdc.v_front_porch = 5;
+	pinfo.lcdc.v_pulse_width = 6;
+	pinfo.lcdc.border_clr = 0;
+	pinfo.lcdc.underflow_clr = 0xff;
+	pinfo.lcdc.hsync_skew = 0;
+
+	ret = lcdc_device_register(&pinfo);
+	if (ret) {
+		printk(KERN_ERR "%s: failed to register device\n", __func__);
+		goto init_exit;
+	}
+
+	ret = i2c_add_driver(&hdmi_sii_i2c_driver);
+	if (ret)
+		printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
+
+init_exit:
+	return ret;
+}
+
+static void __exit hdmi_sii_exit(void)
+{
+	i2c_del_driver(&hdmi_sii_i2c_driver);
+}
+
+module_init(hdmi_sii_init);
+module_exit(hdmi_sii_exit);
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
+MODULE_DESCRIPTION("SiI9022 HDMI driver");
+MODULE_ALIAS("platform:hdmi-sii9022");
diff --git a/drivers/video/msm/lcdc.c b/drivers/video/msm/lcdc.c
new file mode 100644
index 0000000..863d59d
--- /dev/null
+++ b/drivers/video/msm/lcdc.c
@@ -0,0 +1,289 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include "msm_fb.h"
+
+static int lcdc_probe(struct platform_device *pdev);
+static int lcdc_remove(struct platform_device *pdev);
+
+static int lcdc_off(struct platform_device *pdev);
+static int lcdc_on(struct platform_device *pdev);
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+
+static struct clk *pixel_mdp_clk; /* drives the lcdc block in mdp */
+static struct clk *pixel_lcdc_clk; /* drives the lcdc interface */
+
+static struct platform_driver lcdc_driver = {
+	.probe = lcdc_probe,
+	.remove = lcdc_remove,
+	.suspend = NULL,
+	.resume = NULL,
+	.shutdown = NULL,
+	.driver = {
+		   .name = "lcdc",
+		   },
+};
+
+static struct lcdc_platform_data *lcdc_pdata;
+
+static int lcdc_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+	ret = panel_next_off(pdev);
+
+	clk_disable_unprepare(pixel_mdp_clk);
+	clk_disable_unprepare(pixel_lcdc_clk);
+
+	if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
+		lcdc_pdata->lcdc_power_save(0);
+
+	if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
+		ret = lcdc_pdata->lcdc_gpio_config(0);
+
+#ifndef CONFIG_MSM_BUS_SCALING
+	if (mfd->ebi1_clk) {
+		if (mdp_rev == MDP_REV_303) {
+			if (clk_set_rate(mfd->ebi1_clk, 0))
+				pr_err("%s: ebi1_lcdc_clk set rate failed\n",
+					__func__);
+		}
+		clk_disable_unprepare(mfd->ebi1_clk);
+	}
+#else
+	mdp_bus_scale_update_request(0);
+#endif
+
+	return ret;
+}
+
+static int lcdc_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_data_type *mfd;
+	unsigned long panel_pixclock_freq = 0;
+#ifndef CONFIG_MSM_BUS_SCALING
+	unsigned long pm_qos_rate;
+#endif
+	mfd = platform_get_drvdata(pdev);
+
+	if (lcdc_pdata && lcdc_pdata->lcdc_get_clk)
+		panel_pixclock_freq = lcdc_pdata->lcdc_get_clk();
+
+	if (!panel_pixclock_freq)
+		panel_pixclock_freq = mfd->fbi->var.pixclock;
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(2);
+#else
+	if (panel_pixclock_freq > 65000000)
+		/* pm_qos_rate should be in Khz */
+		pm_qos_rate = panel_pixclock_freq / 1000 ;
+	else
+		pm_qos_rate = 65000;
+
+	if (mfd->ebi1_clk) {
+		if (mdp_rev == MDP_REV_303) {
+			if (clk_set_rate(mfd->ebi1_clk, 65000000))
+				pr_err("%s: ebi1_lcdc_clk set rate failed\n",
+					__func__);
+		} else {
+			clk_set_rate(mfd->ebi1_clk, pm_qos_rate * 1000);
+		}
+		clk_prepare_enable(mfd->ebi1_clk);
+	}
+
+#endif
+	mfd = platform_get_drvdata(pdev);
+
+	mfd->fbi->var.pixclock = clk_round_rate(pixel_mdp_clk,
+					mfd->fbi->var.pixclock);
+	ret = clk_set_rate(pixel_mdp_clk, mfd->fbi->var.pixclock);
+	if (ret) {
+		pr_err("%s: Can't set MDP LCDC pixel clock to rate %u\n",
+			__func__, mfd->fbi->var.pixclock);
+		goto out;
+	}
+
+	clk_prepare_enable(pixel_mdp_clk);
+	clk_prepare_enable(pixel_lcdc_clk);
+
+	if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
+		lcdc_pdata->lcdc_power_save(1);
+	if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
+		ret = lcdc_pdata->lcdc_gpio_config(1);
+
+	ret = panel_next_on(pdev);
+
+out:
+	return ret;
+}
+
+static int lcdc_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct fb_info *fbi;
+	struct platform_device *mdp_dev = NULL;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc;
+	struct clk *ebi1_clk = NULL;
+
+	if (pdev->id == 0) {
+		lcdc_pdata = pdev->dev.platform_data;
+		pixel_mdp_clk = clk_get(&pdev->dev, "mdp_clk");
+		if (IS_ERR(pixel_mdp_clk)) {
+			pr_err("Couldnt find pixel_mdp_clk\n");
+			return -EINVAL;
+		}
+
+		pixel_lcdc_clk = clk_get(&pdev->dev, "lcdc_clk");
+		if (IS_ERR(pixel_lcdc_clk)) {
+			pr_err("Couldnt find pixel_lcdc_clk\n");
+			return -EINVAL;
+		}
+
+#ifndef CONFIG_MSM_BUS_SCALING
+		ebi1_clk = clk_get(&pdev->dev, "mem_clk");
+		if (IS_ERR(ebi1_clk))
+			return PTR_ERR(ebi1_clk);
+#endif
+
+		return 0;
+	}
+
+	mfd = platform_get_drvdata(pdev);
+	mfd->ebi1_clk = ebi1_clk;
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	mdp_dev = platform_device_alloc("mdp", pdev->id);
+	if (!mdp_dev)
+		return -ENOMEM;
+
+	/*
+	 * link to the latest pdev
+	 */
+	mfd->pdev = mdp_dev;
+	mfd->dest = DISPLAY_LCDC;
+
+	/*
+	 * alloc panel device data
+	 */
+	if (platform_device_add_data
+	    (mdp_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		pr_err("lcdc_probe: platform_device_add_data failed!\n");
+		platform_device_put(mdp_dev);
+		return -ENOMEM;
+	}
+	/*
+	 * data chain
+	 */
+	pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data;
+	pdata->on = lcdc_on;
+	pdata->off = lcdc_off;
+	pdata->next = pdev;
+
+	/*
+	 * get/set panel specific fb info
+	 */
+	mfd->panel_info = pdata->panel_info;
+
+	if (mfd->index == 0)
+		mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
+	else
+		mfd->fb_imgType = MDP_RGB_565;
+
+	fbi = mfd->fbi;
+	fbi->var.pixclock = clk_round_rate(pixel_mdp_clk,
+					mfd->panel_info.clk_rate);
+	fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
+	fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
+	fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
+	fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch;
+	fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width;
+	fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width;
+
+	/*
+	 * set driver data
+	 */
+	platform_set_drvdata(mdp_dev, mfd);
+	/*
+	 * register in mdp driver
+	 */
+	rc = platform_device_add(mdp_dev);
+	if (rc)
+		goto lcdc_probe_err;
+
+	pdev_list[pdev_list_cnt++] = pdev;
+
+	return 0;
+
+lcdc_probe_err:
+	platform_device_put(mdp_dev);
+	return rc;
+}
+
+static int lcdc_remove(struct platform_device *pdev)
+{
+#ifndef CONFIG_MSM_BUS_SCALING
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	clk_put(mfd->ebi1_clk);
+#endif
+	return 0;
+}
+
+static int lcdc_register_driver(void)
+{
+	return platform_driver_register(&lcdc_driver);
+}
+
+static int __init lcdc_driver_init(void)
+{
+
+	return lcdc_register_driver();
+}
+
+module_init(lcdc_driver_init);
diff --git a/drivers/video/msm/lcdc_auo_wvga.c b/drivers/video/msm/lcdc_auo_wvga.c
new file mode 100644
index 0000000..6b0733f
--- /dev/null
+++ b/drivers/video/msm/lcdc_auo_wvga.c
@@ -0,0 +1,411 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#ifdef CONFIG_SPI_QUP
+#include <linux/spi/spi.h>
+#else
+#include <mach/gpio.h>
+#endif
+#include "msm_fb.h"
+
+#define MAX_BACKLIGHT_LEVEL			15
+#define PANEL_CMD_BACKLIGHT_LEVEL	0x6A18
+#define PANEL_CMD_FORMAT			0x3A00
+#define PANEL_CMD_RGBCTRL			0x3B00
+#define PANEL_CMD_BCTRL				0x5300
+#define PANEL_CMD_PWM_EN			0x6A17
+
+#define PANEL_CMD_SLEEP_OUT			0x1100
+#define PANEL_CMD_DISP_ON			0x2900
+#define PANEL_CMD_DISP_OFF			0x2800
+#define PANEL_CMD_SLEEP_IN			0x1000
+
+#define LCDC_AUO_PANEL_NAME			"lcdc_auo_wvga"
+
+#ifdef CONFIG_SPI_QUP
+#define LCDC_AUO_SPI_DEVICE_NAME	"lcdc_auo_nt35582"
+static struct spi_device *lcdc_spi_client;
+#else
+static int spi_cs;
+static int spi_sclk;
+static int spi_mosi;
+#endif
+
+struct auo_state_type {
+	boolean display_on;
+	int bl_level;
+};
+
+
+static struct auo_state_type auo_state = { .bl_level = 10 };
+static struct msm_panel_common_pdata *lcdc_auo_pdata;
+
+#ifndef CONFIG_SPI_QUP
+static void auo_spi_write_byte(u8 data)
+{
+	uint32 bit;
+	int bnum;
+
+	bnum = 8;			/* 8 data bits */
+	bit = 0x80;
+	while (bnum--) {
+		gpio_set_value(spi_sclk, 0); /* clk low */
+		gpio_set_value(spi_mosi, (data & bit) ? 1 : 0);
+		udelay(1);
+		gpio_set_value(spi_sclk, 1); /* clk high */
+		udelay(1);
+		bit >>= 1;
+	}
+	gpio_set_value(spi_mosi, 0);
+}
+
+static void auo_spi_read_byte(u16 cmd_16, u8 *data)
+{
+	int bnum;
+	u8 cmd_hi = (u8)(cmd_16 >> 8);
+	u8 cmd_low = (u8)(cmd_16);
+
+	/* Chip Select - low */
+	gpio_set_value(spi_cs, 0);
+	udelay(2);
+
+	/* command byte first */
+	auo_spi_write_byte(0x20);
+	udelay(2);
+	auo_spi_write_byte(cmd_hi);
+	udelay(2);
+	auo_spi_write_byte(0x00);
+	udelay(2);
+	auo_spi_write_byte(cmd_low);
+	udelay(2);
+	auo_spi_write_byte(0xc0);
+	udelay(2);
+
+	gpio_direction_input(spi_mosi);
+
+	/* followed by data bytes */
+	bnum = 1 * 8;	/* number of bits */
+	*data = 0;
+	while (bnum) {
+		gpio_set_value(spi_sclk, 0); /* clk low */
+		udelay(1);
+		*data <<= 1;
+		*data |= gpio_get_value(spi_mosi) ? 1 : 0;
+		gpio_set_value(spi_sclk, 1); /* clk high */
+		udelay(1);
+		--bnum;
+		if ((bnum % 8) == 0)
+			++data;
+	}
+
+	gpio_direction_output(spi_mosi, 0);
+
+	/* Chip Select - high */
+	udelay(2);
+	gpio_set_value(spi_cs, 1);
+}
+#endif
+
+static int auo_serigo(u8 *input_data, int input_len)
+{
+#ifdef CONFIG_SPI_QUP
+	int                 rc;
+	struct spi_message  m;
+	struct spi_transfer t;
+
+	if (!lcdc_spi_client) {
+		pr_err("%s lcdc_spi_client is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(&t, 0, sizeof t);
+
+	t.tx_buf = input_data;
+	t.len = input_len;
+	t.bits_per_word = 16;
+
+	spi_setup(lcdc_spi_client);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	rc = spi_sync(lcdc_spi_client, &m);
+
+	return rc;
+#else
+	int i;
+
+	/* Chip Select - low */
+	gpio_set_value(spi_cs, 0);
+	udelay(2);
+
+	for (i = 0; i < input_len; ++i) {
+		auo_spi_write_byte(input_data[i]);
+		udelay(2);
+	}
+
+	/* Chip Select - high */
+	gpio_set_value(spi_cs, 1);
+
+	return 0;
+#endif
+}
+
+#ifndef CONFIG_SPI_QUP
+static void auo_spi_init(void)
+{
+	spi_sclk = *(lcdc_auo_pdata->gpio_num);
+	spi_cs   = *(lcdc_auo_pdata->gpio_num + 1);
+	spi_mosi = *(lcdc_auo_pdata->gpio_num + 2);
+
+	/* Set the output so that we don't disturb the slave device */
+	gpio_set_value(spi_sclk, 1);
+	gpio_set_value(spi_mosi, 0);
+
+	/* Set the Chip Select deasserted (active low) */
+	gpio_set_value(spi_cs, 1);
+}
+#endif
+
+static struct work_struct disp_on_delayed_work;
+static void auo_write_cmd(u16  cmd)
+{
+	u8  local_data[4];
+
+	local_data[0] = 0x20;
+	local_data[1] = (u8)(cmd >> 8);
+	local_data[2] = 0;
+	local_data[3] = (u8)cmd;
+	auo_serigo(local_data, 4);
+}
+static void auo_write_cmd_1param(u16  cmd, u8  para1)
+{
+	u8  local_data[6];
+
+	local_data[0] = 0x20;
+	local_data[1] = (u8)(cmd >> 8);
+	local_data[2] = 0;
+	local_data[3] = (u8)cmd;
+	local_data[4] = 0x40;
+	local_data[5] = para1;
+	auo_serigo(local_data, 6);
+}
+static void lcdc_auo_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int bl_level;
+
+	bl_level = mfd->bl_level;
+	if (auo_state.display_on) {
+		auo_write_cmd_1param(PANEL_CMD_BACKLIGHT_LEVEL,
+			bl_level * 255 / MAX_BACKLIGHT_LEVEL);
+		auo_state.bl_level = bl_level;
+	}
+
+}
+static void auo_disp_on_delayed_work(struct work_struct *work_ptr)
+{
+	/* 0x1100: Sleep Out */
+	auo_write_cmd(PANEL_CMD_SLEEP_OUT);
+
+	msleep(180);
+
+	/* SET_PIXEL_FORMAT: Set how many bits per pixel are used (3A00h)*/
+	auo_write_cmd_1param(PANEL_CMD_FORMAT, 0x66); /* 18 bits */
+
+	/* RGBCTRL: RGB Interface Signal Control (3B00h) */
+	auo_write_cmd_1param(PANEL_CMD_RGBCTRL, 0x2B);
+
+	/* Display ON command */
+	auo_write_cmd(PANEL_CMD_DISP_ON);
+	msleep(20);
+
+	/*Backlight on */
+	auo_write_cmd_1param(PANEL_CMD_BCTRL, 0x24); /*BCTRL, BL */
+	auo_write_cmd_1param(PANEL_CMD_PWM_EN, 0x01); /*Enable PWM Level */
+
+	msleep(20);
+}
+
+static void auo_disp_on(void)
+{
+	if (!auo_state.display_on) {
+		INIT_WORK(&disp_on_delayed_work, auo_disp_on_delayed_work);
+#ifdef CONFIG_SPI_QUP
+		if (lcdc_spi_client)
+#endif
+			schedule_work(&disp_on_delayed_work);
+		auo_state.display_on = TRUE;
+	}
+}
+
+static int lcdc_auo_panel_on(struct platform_device *pdev)
+{
+	pr_info("%s\n", __func__);
+	if (!auo_state.display_on) {
+#ifndef CONFIG_SPI_QUP
+		lcdc_auo_pdata->panel_config_gpio(1);
+		auo_spi_init();
+#endif
+		auo_disp_on();
+	}
+	return 0;
+}
+
+static int lcdc_auo_panel_off(struct platform_device *pdev)
+{
+	pr_info("%s\n", __func__);
+	if (auo_state.display_on) {
+		/* 0x2800: Display Off */
+		auo_write_cmd(PANEL_CMD_DISP_OFF);
+		msleep(120);
+		/* 0x1000: Sleep In */
+		auo_write_cmd(PANEL_CMD_SLEEP_IN);
+		msleep(120);
+
+		auo_state.display_on = FALSE;
+	}
+	return 0;
+}
+
+static int auo_probe(struct platform_device *pdev)
+{
+	pr_info("%s: id=%d\n", __func__, pdev->id);
+	if (pdev->id == 0) {
+		lcdc_auo_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+#ifdef CONFIG_SPI_QUP
+static int __devinit lcdc_auo_spi_probe(struct spi_device *spi)
+{
+	pr_info("%s\n", __func__);
+	lcdc_spi_client = spi;
+	lcdc_spi_client->bits_per_word = 32;
+	if (auo_state.display_on)
+		schedule_work(&disp_on_delayed_work);
+	return 0;
+}
+static int __devexit lcdc_auo_spi_remove(struct spi_device *spi)
+{
+	lcdc_spi_client = NULL;
+	return 0;
+}
+static struct spi_driver lcdc_auo_spi_driver = {
+	.driver.name   = LCDC_AUO_SPI_DEVICE_NAME,
+	.driver.owner  = THIS_MODULE,
+	.probe         = lcdc_auo_spi_probe,
+	.remove        = __devexit_p(lcdc_auo_spi_remove),
+};
+#endif
+
+static struct platform_driver this_driver = {
+	.probe		= auo_probe,
+	.driver.name	= LCDC_AUO_PANEL_NAME,
+};
+
+static struct msm_fb_panel_data auo_panel_data = {
+	.on = lcdc_auo_panel_on,
+	.off = lcdc_auo_panel_off,
+	.set_backlight = lcdc_auo_set_backlight,
+};
+
+static struct platform_device this_device = {
+	.name	= LCDC_AUO_PANEL_NAME,
+	.id	= 1,
+	.dev.platform_data = &auo_panel_data,
+};
+
+static int __init lcdc_auo_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	if (msm_fb_detect_client(LCDC_AUO_PANEL_NAME)) {
+		pr_err("%s: detect failed\n", __func__);
+		return 0;
+	}
+
+	ret = platform_driver_register(&this_driver);
+	if (ret) {
+		pr_err("%s: driver register failed, rc=%d\n", __func__, ret);
+		return ret;
+	}
+
+	pinfo = &auo_panel_data.panel_info;
+	pinfo->xres = 480;
+	pinfo->yres = 800;
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 18;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 25600000;
+	pinfo->bl_max = MAX_BACKLIGHT_LEVEL;
+	pinfo->bl_min = 1;
+
+	pinfo->lcdc.h_back_porch = 16-2;	/* HBP-HLW */
+	pinfo->lcdc.h_front_porch = 16;
+	pinfo->lcdc.h_pulse_width = 2;
+
+	pinfo->lcdc.v_back_porch = 3-2;		/* VBP-VLW */
+	pinfo->lcdc.v_front_porch = 28;
+	pinfo->lcdc.v_pulse_width = 2;
+
+	pinfo->lcdc.border_clr = 0;
+	pinfo->lcdc.underflow_clr = 0xff;
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret) {
+		pr_err("%s: device register failed, rc=%d\n", __func__, ret);
+		goto fail_driver;
+	}
+#ifdef CONFIG_SPI_QUP
+	ret = spi_register_driver(&lcdc_auo_spi_driver);
+
+	if (ret) {
+		pr_err("%s: spi register failed: rc=%d\n", __func__, ret);
+		goto fail_device;
+	}
+	pr_info("%s: SUCCESS (SPI)\n", __func__);
+#else
+	pr_info("%s: SUCCESS (BitBang)\n", __func__);
+#endif
+	return ret;
+
+#ifdef CONFIG_SPI_QUP
+fail_device:
+	platform_device_unregister(&this_device);
+#endif
+fail_driver:
+	platform_driver_unregister(&this_driver);
+
+	return ret;
+}
+
+module_init(lcdc_auo_panel_init);
+static void __exit lcdc_auo_panel_exit(void)
+{
+	pr_info("%s\n", __func__);
+	platform_device_unregister(&this_device);
+	platform_driver_unregister(&this_driver);
+#ifdef CONFIG_SPI_QUP
+	spi_unregister_driver(&lcdc_auo_spi_driver);
+#endif
+}
+module_exit(lcdc_auo_panel_exit);
diff --git a/drivers/video/msm/lcdc_chimei_wxga.c b/drivers/video/msm/lcdc_chimei_wxga.c
new file mode 100644
index 0000000..7453ecb
--- /dev/null
+++ b/drivers/video/msm/lcdc_chimei_wxga.c
@@ -0,0 +1,231 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#ifdef CONFIG_PMIC8058_PWM
+#include <linux/mfd/pmic8058.h>
+#include <linux/pmic8058-pwm.h>
+#endif
+#include <mach/gpio.h>
+#include "msm_fb.h"
+
+
+
+
+static struct pwm_device *bl_pwm;
+
+#define PWM_FREQ_HZ 210
+#define PWM_PERIOD_USEC (USEC_PER_SEC / PWM_FREQ_HZ)
+#define PWM_DUTY_LEVEL (PWM_PERIOD_USEC / PWM_LEVEL)
+#define PWM_LEVEL 15
+
+static struct msm_panel_common_pdata *cm_pdata;
+static struct platform_device *cm_fbpdev;
+static int led_pwm;		/* pm8058 gpio 24, channel 0 */
+static int led_en;		/* pm8058 gpio 1 */
+static int lvds_pwr_down;	/* msm gpio 30 */
+static int chimei_bl_level = 1;
+
+
+static void lcdc_chimei_set_backlight(int level)
+{
+	int ret;
+
+	if (bl_pwm) {
+		ret = pwm_config(bl_pwm, PWM_DUTY_LEVEL * level,
+			PWM_PERIOD_USEC);
+		if (ret) {
+			pr_err("%s: pwm_config on pwm failed %d\n",
+					__func__, ret);
+			return;
+		}
+
+		ret = pwm_enable(bl_pwm);
+		if (ret) {
+			pr_err("%s: pwm_enable on pwm failed %d\n",
+					__func__, ret);
+			return;
+		}
+	}
+
+	chimei_bl_level = level;
+}
+
+static int lcdc_chimei_panel_on(struct platform_device *pdev)
+{
+	int ret;
+
+	/* panel powered on here */
+
+	ret = gpio_request(lvds_pwr_down, "lvds_pwr_down");
+	if (ret == 0) {
+		/* output, pull high to enable */
+		gpio_direction_output(lvds_pwr_down, 1);
+	} else {
+		pr_err("%s: lvds_pwr_down=%d, gpio_request failed\n",
+			__func__, lvds_pwr_down);
+	}
+
+	msleep(200);
+	/* power on led pwm power >= 200 ms */
+
+	if (chimei_bl_level == 0)
+		chimei_bl_level = 1;
+	lcdc_chimei_set_backlight(chimei_bl_level);
+
+	msleep(10);
+
+	ret = gpio_request(led_en, "led_en");
+	if (ret == 0) {
+		/* output, pull high */
+		gpio_direction_output(led_en, 1);
+	} else {
+		pr_err("%s: led_en=%d, gpio_request failed\n",
+			__func__, led_en);
+	}
+	return ret;
+}
+
+static int lcdc_chimei_panel_off(struct platform_device *pdev)
+{
+	/* pull low to disable */
+	gpio_set_value_cansleep(led_en, 0);
+	gpio_free(led_en);
+
+	msleep(10);
+
+	lcdc_chimei_set_backlight(0);
+
+	msleep(200);
+	/* power off led pwm power >= 200 ms */
+
+	/* pull low to shut down lvds */
+	gpio_set_value_cansleep(lvds_pwr_down, 0);
+	gpio_free(lvds_pwr_down);
+
+	/* panel power off here */
+
+	return 0;
+}
+
+static void lcdc_chimei_panel_backlight(struct msm_fb_data_type *mfd)
+{
+	lcdc_chimei_set_backlight(mfd->bl_level);
+}
+
+static int __devinit chimei_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	if (pdev->id == 0) {
+		cm_pdata = pdev->dev.platform_data;
+		if (cm_pdata == NULL) {
+			pr_err("%s: no PWM gpio specified\n", __func__);
+			return 0;
+		}
+		led_pwm = cm_pdata->gpio_num[0];
+		led_en = cm_pdata->gpio_num[1];
+		lvds_pwr_down = cm_pdata->gpio_num[2];
+		pr_info("%s: led_pwm=%d led_en=%d lvds_pwr_down=%d\n",
+			__func__, led_pwm, led_en, lvds_pwr_down);
+		return 0;
+	}
+
+	if (cm_pdata == NULL)
+		return -ENODEV;
+
+	bl_pwm = pwm_request(led_pwm, "backlight");
+	if (bl_pwm == NULL || IS_ERR(bl_pwm)) {
+		pr_err("%s pwm_request() failed\n", __func__);
+		bl_pwm = NULL;
+	}
+
+	cm_fbpdev = msm_fb_add_device(pdev);
+	if (!cm_fbpdev) {
+		dev_err(&pdev->dev, "failed to add msm_fb device\n");
+		rc = -ENODEV;
+		goto probe_exit;
+	}
+
+probe_exit:
+	return rc;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = chimei_probe,
+	.driver = {
+		.name   = "lcdc_chimei_lvds_wxga",
+	},
+};
+
+static struct msm_fb_panel_data chimei_panel_data = {
+	.on = lcdc_chimei_panel_on,
+	.off = lcdc_chimei_panel_off,
+	.set_backlight = lcdc_chimei_panel_backlight,
+};
+
+static struct platform_device this_device = {
+	.name   = "lcdc_chimei_lvds_wxga",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &chimei_panel_data,
+	}
+};
+
+static int __init lcdc_chimei_lvds_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	if (msm_fb_detect_client("lcdc_chimei_wxga"))
+		return 0;
+
+	ret = platform_driver_register(&this_driver);
+	if (ret)
+		return ret;
+
+	pinfo = &chimei_panel_data.panel_info;
+	pinfo->xres = 1366;
+	pinfo->yres = 768;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 18;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 69300000;
+	pinfo->bl_max = PWM_LEVEL;
+	pinfo->bl_min = 1;
+
+	/*
+	 * this panel is operated by de,
+	 * vsycn and hsync are ignored
+	 */
+	pinfo->lcdc.h_back_porch = 108;
+	pinfo->lcdc.h_front_porch = 0;
+	pinfo->lcdc.h_pulse_width = 1;
+	pinfo->lcdc.v_back_porch = 0;
+	pinfo->lcdc.v_front_porch = 16;
+	pinfo->lcdc.v_pulse_width = 1;
+	pinfo->lcdc.border_clr = 0;
+	pinfo->lcdc.underflow_clr = 0xff;
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret)
+		platform_driver_unregister(&this_driver);
+
+	return ret;
+}
+
+module_init(lcdc_chimei_lvds_panel_init);
diff --git a/drivers/video/msm/lcdc_external.c b/drivers/video/msm/lcdc_external.c
new file mode 100644
index 0000000..ca82def
--- /dev/null
+++ b/drivers/video/msm/lcdc_external.c
@@ -0,0 +1,51 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+
+static int __init lcdc_external_init(void)
+{
+	int ret;
+	struct msm_panel_info pinfo;
+
+	if (msm_fb_detect_client("lcdc_external"))
+		return 0;
+
+	pinfo.xres = 1280;
+	pinfo.yres = 720;
+	MSM_FB_SINGLE_MODE_PANEL(&pinfo);
+	pinfo.type = LCDC_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.fb_num = 2;
+	pinfo.clk_rate = 74250000;
+
+	pinfo.lcdc.h_back_porch = 124;
+	pinfo.lcdc.h_front_porch = 110;
+	pinfo.lcdc.h_pulse_width = 136;
+	pinfo.lcdc.v_back_porch = 19;
+	pinfo.lcdc.v_front_porch = 5;
+	pinfo.lcdc.v_pulse_width = 6;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+
+	ret = lcdc_device_register(&pinfo);
+	if (ret)
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(lcdc_external_init);
diff --git a/drivers/video/msm/lcdc_gordon.c b/drivers/video/msm/lcdc_gordon.c
new file mode 100644
index 0000000..f9532b4
--- /dev/null
+++ b/drivers/video/msm/lcdc_gordon.c
@@ -0,0 +1,443 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <mach/gpio.h>
+#include "msm_fb.h"
+
+/* registers */
+#define GORDON_REG_NOP          0x00
+#define GORDON_REG_IMGCTL1      0x10
+#define GORDON_REG_IMGCTL2      0x11
+#define GORDON_REG_IMGSET1      0x12
+#define GORDON_REG_IMGSET2      0x13
+#define GORDON_REG_IVBP1        0x14
+#define GORDON_REG_IHBP1        0x15
+#define GORDON_REG_IVNUM1       0x16
+#define GORDON_REG_IHNUM1       0x17
+#define GORDON_REG_IVBP2        0x18
+#define GORDON_REG_IHBP2        0x19
+#define GORDON_REG_IVNUM2       0x1A
+#define GORDON_REG_IHNUM2       0x1B
+#define GORDON_REG_LCDIFCTL1    0x30
+#define GORDON_REG_VALTRAN      0x31
+#define GORDON_REG_AVCTL        0x33
+#define GORDON_REG_LCDIFCTL2    0x34
+#define GORDON_REG_LCDIFCTL3    0x35
+#define GORDON_REG_LCDIFSET1    0x36
+#define GORDON_REG_PCCTL        0x3C
+#define GORDON_REG_TPARAM1      0x40
+#define GORDON_REG_TLCDIF1      0x41
+#define GORDON_REG_TSSPB_ST1    0x42
+#define GORDON_REG_TSSPB_ED1    0x43
+#define GORDON_REG_TSCK_ST1     0x44
+#define GORDON_REG_TSCK_WD1     0x45
+#define GORDON_REG_TGSPB_VST1   0x46
+#define GORDON_REG_TGSPB_VED1   0x47
+#define GORDON_REG_TGSPB_CH1    0x48
+#define GORDON_REG_TGCK_ST1     0x49
+#define GORDON_REG_TGCK_ED1     0x4A
+#define GORDON_REG_TPCTL_ST1    0x4B
+#define GORDON_REG_TPCTL_ED1    0x4C
+#define GORDON_REG_TPCHG_ED1    0x4D
+#define GORDON_REG_TCOM_CH1     0x4E
+#define GORDON_REG_THBP1        0x4F
+#define GORDON_REG_TPHCTL1      0x50
+#define GORDON_REG_EVPH1        0x51
+#define GORDON_REG_EVPL1        0x52
+#define GORDON_REG_EVNH1        0x53
+#define GORDON_REG_EVNL1        0x54
+#define GORDON_REG_TBIAS1       0x55
+#define GORDON_REG_TPARAM2      0x56
+#define GORDON_REG_TLCDIF2      0x57
+#define GORDON_REG_TSSPB_ST2    0x58
+#define GORDON_REG_TSSPB_ED2    0x59
+#define GORDON_REG_TSCK_ST2     0x5A
+#define GORDON_REG_TSCK_WD2     0x5B
+#define GORDON_REG_TGSPB_VST2   0x5C
+#define GORDON_REG_TGSPB_VED2   0x5D
+#define GORDON_REG_TGSPB_CH2    0x5E
+#define GORDON_REG_TGCK_ST2     0x5F
+#define GORDON_REG_TGCK_ED2     0x60
+#define GORDON_REG_TPCTL_ST2    0x61
+#define GORDON_REG_TPCTL_ED2    0x62
+#define GORDON_REG_TPCHG_ED2    0x63
+#define GORDON_REG_TCOM_CH2     0x64
+#define GORDON_REG_THBP2        0x65
+#define GORDON_REG_TPHCTL2      0x66
+#define GORDON_REG_POWCTL       0x80
+
+static int lcdc_gordon_panel_off(struct platform_device *pdev);
+
+static int spi_cs;
+static int spi_sclk;
+static int spi_sdo;
+static int spi_sdi;
+static int spi_dac;
+static unsigned char bit_shift[8] = { (1 << 7),	/* MSB */
+	(1 << 6),
+	(1 << 5),
+	(1 << 4),
+	(1 << 3),
+	(1 << 2),
+	(1 << 1),
+	(1 << 0)		               /* LSB */
+};
+
+struct gordon_state_type{
+	boolean disp_initialized;
+	boolean display_on;
+	boolean disp_powered_up;
+};
+
+static struct gordon_state_type gordon_state = { 0 };
+static struct msm_panel_common_pdata *lcdc_gordon_pdata;
+
+static void serigo(uint16 reg, uint8 data)
+{
+	unsigned int tx_val = ((0x00FF & reg) << 8) | data;
+	unsigned char i, val = 0;
+
+	/* Enable the Chip Select */
+	gpio_set_value(spi_cs, 1);
+	udelay(33);
+
+	/* Transmit it in two parts, Higher Byte first, then Lower Byte */
+	val = (unsigned char)((tx_val & 0xFF00) >> 8);
+
+	/* Clock should be Low before entering ! */
+	for (i = 0; i < 8; i++) {
+		/* #1: Drive the Data (High or Low) */
+		if (val & bit_shift[i])
+			gpio_set_value(spi_sdi, 1);
+		else
+			gpio_set_value(spi_sdi, 0);
+
+		/* #2: Drive the Clk High and then Low */
+		udelay(33);
+		gpio_set_value(spi_sclk, 1);
+		udelay(33);
+		gpio_set_value(spi_sclk, 0);
+	}
+
+	/* Idle state of SDO (MOSI) is Low */
+	gpio_set_value(spi_sdi, 0);
+	/* ..then Lower Byte */
+	val = (uint8) (tx_val & 0x00FF);
+	/* Before we enter here the Clock should be Low ! */
+
+	for (i = 0; i < 8; i++) {
+		/* #1: Drive the Data (High or Low) */
+		if (val & bit_shift[i])
+			gpio_set_value(spi_sdi, 1);
+		else
+			gpio_set_value(spi_sdi, 0);
+
+		/* #2: Drive the Clk High and then Low */
+		udelay(33);
+
+		gpio_set_value(spi_sclk, 1);
+		udelay(33);
+		gpio_set_value(spi_sclk, 0);
+	}
+
+	/* Idle state of SDO (MOSI) is Low */
+	gpio_set_value(spi_sdi, 0);
+
+	/* Now Disable the Chip Select */
+	udelay(33);
+	gpio_set_value(spi_cs, 0);
+}
+
+static void spi_init(void)
+{
+	/* Setting the Default GPIO's */
+	spi_sclk = *(lcdc_gordon_pdata->gpio_num);
+	spi_cs   = *(lcdc_gordon_pdata->gpio_num + 1);
+	spi_sdi  = *(lcdc_gordon_pdata->gpio_num + 2);
+	spi_sdo  = *(lcdc_gordon_pdata->gpio_num + 3);
+
+	/* Set the output so that we dont disturb the slave device */
+	gpio_set_value(spi_sclk, 0);
+	gpio_set_value(spi_sdi, 0);
+
+	/* Set the Chip Select De-asserted */
+	gpio_set_value(spi_cs, 0);
+
+}
+
+static void gordon_disp_powerup(void)
+{
+	if (!gordon_state.disp_powered_up && !gordon_state.display_on) {
+		/* Reset the hardware first */
+		/* Include DAC power up implementation here */
+	      gordon_state.disp_powered_up = TRUE;
+	}
+}
+
+static void gordon_init(void)
+{
+	/* Image interface settings */
+	serigo(GORDON_REG_IMGCTL2, 0x00);
+	serigo(GORDON_REG_IMGSET1, 0x00);
+
+	/* Exchange the RGB signal for J510(Softbank mobile) */
+	serigo(GORDON_REG_IMGSET2, 0x12);
+	serigo(GORDON_REG_LCDIFSET1, 0x00);
+
+	/* Pre-charge settings */
+	serigo(GORDON_REG_PCCTL, 0x09);
+	serigo(GORDON_REG_LCDIFCTL2, 0x7B);
+
+	mdelay(1);
+}
+
+static void gordon_disp_on(void)
+{
+	if (gordon_state.disp_powered_up && !gordon_state.display_on) {
+		gordon_init();
+		mdelay(20);
+		/* gordon_dispmode setting */
+		serigo(GORDON_REG_TPARAM1, 0x30);
+		serigo(GORDON_REG_TLCDIF1, 0x00);
+		serigo(GORDON_REG_TSSPB_ST1, 0x8B);
+		serigo(GORDON_REG_TSSPB_ED1, 0x93);
+		serigo(GORDON_REG_TSCK_ST1, 0x88);
+		serigo(GORDON_REG_TSCK_WD1, 0x00);
+		serigo(GORDON_REG_TGSPB_VST1, 0x01);
+		serigo(GORDON_REG_TGSPB_VED1, 0x02);
+		serigo(GORDON_REG_TGSPB_CH1, 0x5E);
+		serigo(GORDON_REG_TGCK_ST1, 0x80);
+		serigo(GORDON_REG_TGCK_ED1, 0x3C);
+		serigo(GORDON_REG_TPCTL_ST1, 0x50);
+		serigo(GORDON_REG_TPCTL_ED1, 0x74);
+		serigo(GORDON_REG_TPCHG_ED1, 0x78);
+		serigo(GORDON_REG_TCOM_CH1, 0x50);
+		serigo(GORDON_REG_THBP1, 0x84);
+		serigo(GORDON_REG_TPHCTL1, 0x00);
+		serigo(GORDON_REG_EVPH1, 0x70);
+		serigo(GORDON_REG_EVPL1, 0x64);
+		serigo(GORDON_REG_EVNH1, 0x56);
+		serigo(GORDON_REG_EVNL1, 0x48);
+		serigo(GORDON_REG_TBIAS1, 0x88);
+
+		/* QVGA settings */
+		serigo(GORDON_REG_TPARAM2, 0x28);
+		serigo(GORDON_REG_TLCDIF2, 0x14);
+		serigo(GORDON_REG_TSSPB_ST2, 0x49);
+		serigo(GORDON_REG_TSSPB_ED2, 0x4B);
+		serigo(GORDON_REG_TSCK_ST2, 0x4A);
+		serigo(GORDON_REG_TSCK_WD2, 0x02);
+		serigo(GORDON_REG_TGSPB_VST2, 0x02);
+		serigo(GORDON_REG_TGSPB_VED2, 0x03);
+		serigo(GORDON_REG_TGSPB_CH2, 0x2F);
+		serigo(GORDON_REG_TGCK_ST2, 0x40);
+		serigo(GORDON_REG_TGCK_ED2, 0x1E);
+		serigo(GORDON_REG_TPCTL_ST2, 0x2C);
+		serigo(GORDON_REG_TPCTL_ED2, 0x3A);
+		serigo(GORDON_REG_TPCHG_ED2, 0x3C);
+		serigo(GORDON_REG_TCOM_CH2, 0x28);
+		serigo(GORDON_REG_THBP2, 0x4D);
+		serigo(GORDON_REG_TPHCTL2, 0x1A);
+
+		/* VGA settings */
+		serigo(GORDON_REG_IVBP1, 0x02);
+		serigo(GORDON_REG_IHBP1, 0x90);
+		serigo(GORDON_REG_IVNUM1, 0xA0);
+		serigo(GORDON_REG_IHNUM1, 0x78);
+
+		/* QVGA settings */
+		serigo(GORDON_REG_IVBP2, 0x02);
+		serigo(GORDON_REG_IHBP2, 0x48);
+		serigo(GORDON_REG_IVNUM2, 0x50);
+		serigo(GORDON_REG_IHNUM2, 0x3C);
+
+		/* Gordon Charge pump settings and ON */
+		serigo(GORDON_REG_POWCTL, 0x03);
+		mdelay(15);
+		serigo(GORDON_REG_POWCTL, 0x07);
+		mdelay(15);
+
+		serigo(GORDON_REG_POWCTL, 0x0F);
+		mdelay(15);
+
+		serigo(GORDON_REG_AVCTL, 0x03);
+		mdelay(15);
+
+		serigo(GORDON_REG_POWCTL, 0x1F);
+		mdelay(15);
+
+		serigo(GORDON_REG_POWCTL, 0x5F);
+		mdelay(15);
+
+		serigo(GORDON_REG_POWCTL, 0x7F);
+		mdelay(15);
+
+		serigo(GORDON_REG_LCDIFCTL1, 0x02);
+		mdelay(15);
+
+		serigo(GORDON_REG_IMGCTL1, 0x00);
+		mdelay(15);
+
+		serigo(GORDON_REG_LCDIFCTL3, 0x00);
+		mdelay(15);
+
+		serigo(GORDON_REG_VALTRAN, 0x01);
+		mdelay(15);
+
+		serigo(GORDON_REG_LCDIFCTL1, 0x03);
+		mdelay(1);
+		gordon_state.display_on = TRUE;
+	}
+}
+
+static int lcdc_gordon_panel_on(struct platform_device *pdev)
+{
+	if (!gordon_state.disp_initialized) {
+		/* Configure reset GPIO that drives DAC */
+		lcdc_gordon_pdata->panel_config_gpio(1);
+		spi_dac = *(lcdc_gordon_pdata->gpio_num + 4);
+		gpio_set_value(spi_dac, 0);
+		udelay(15);
+		gpio_set_value(spi_dac, 1);
+		spi_init();	/* LCD needs SPI */
+		gordon_disp_powerup();
+		gordon_disp_on();
+		gordon_state.disp_initialized = TRUE;
+	}
+	return 0;
+}
+
+static int lcdc_gordon_panel_off(struct platform_device *pdev)
+{
+	if (gordon_state.disp_powered_up && gordon_state.display_on) {
+		serigo(GORDON_REG_LCDIFCTL2, 0x7B);
+		serigo(GORDON_REG_VALTRAN, 0x01);
+		serigo(GORDON_REG_LCDIFCTL1, 0x02);
+		serigo(GORDON_REG_LCDIFCTL3, 0x01);
+		mdelay(20);
+		serigo(GORDON_REG_VALTRAN, 0x01);
+		serigo(GORDON_REG_IMGCTL1, 0x01);
+		serigo(GORDON_REG_LCDIFCTL1, 0x00);
+		mdelay(20);
+
+		serigo(GORDON_REG_POWCTL, 0x1F);
+		mdelay(40);
+
+		serigo(GORDON_REG_POWCTL, 0x07);
+		mdelay(40);
+
+		serigo(GORDON_REG_POWCTL, 0x03);
+		mdelay(40);
+
+		serigo(GORDON_REG_POWCTL, 0x00);
+		mdelay(40);
+		lcdc_gordon_pdata->panel_config_gpio(0);
+		gordon_state.display_on = FALSE;
+		gordon_state.disp_initialized = FALSE;
+	}
+	return 0;
+}
+
+static void lcdc_gordon_set_backlight(struct msm_fb_data_type *mfd)
+{
+		int bl_level = mfd->bl_level;
+
+		if (bl_level <= 1) {
+			/* keep back light OFF */
+			serigo(GORDON_REG_LCDIFCTL2, 0x0B);
+			udelay(15);
+			serigo(GORDON_REG_VALTRAN, 0x01);
+		} else {
+			/* keep back light ON */
+			serigo(GORDON_REG_LCDIFCTL2, 0x7B);
+			udelay(15);
+			serigo(GORDON_REG_VALTRAN, 0x01);
+		}
+}
+
+static int __devinit gordon_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		lcdc_gordon_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+	msm_fb_add_device(pdev);
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = gordon_probe,
+	.driver = {
+		.name   = "lcdc_gordon_vga",
+	},
+};
+
+static struct msm_fb_panel_data gordon_panel_data = {
+	.on = lcdc_gordon_panel_on,
+	.off = lcdc_gordon_panel_off,
+	.set_backlight = lcdc_gordon_set_backlight,
+};
+
+static struct platform_device this_device = {
+	.name   = "lcdc_gordon_vga",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &gordon_panel_data,
+	}
+};
+
+static int __init lcdc_gordon_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
+	if (msm_fb_detect_client("lcdc_gordon_vga"))
+		return 0;
+#endif
+	ret = platform_driver_register(&this_driver);
+	if (ret)
+		return ret;
+
+	pinfo = &gordon_panel_data.panel_info;
+	pinfo->xres = 480;
+	pinfo->yres = 640;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 24500000;
+	pinfo->bl_max = 4;
+	pinfo->bl_min = 1;
+
+	pinfo->lcdc.h_back_porch = 84;
+	pinfo->lcdc.h_front_porch = 33;
+	pinfo->lcdc.h_pulse_width = 60;
+	pinfo->lcdc.v_back_porch = 0;
+	pinfo->lcdc.v_front_porch = 2;
+	pinfo->lcdc.v_pulse_width = 2;
+	pinfo->lcdc.border_clr = 0;     /* blk */
+	pinfo->lcdc.underflow_clr = 0xff;       /* blue */
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret)
+		platform_driver_unregister(&this_driver);
+
+	return ret;
+}
+
+module_init(lcdc_gordon_panel_init);
diff --git a/drivers/video/msm/lcdc_nt35582_wvga.c b/drivers/video/msm/lcdc_nt35582_wvga.c
new file mode 100644
index 0000000..9ecf4b9
--- /dev/null
+++ b/drivers/video/msm/lcdc_nt35582_wvga.c
@@ -0,0 +1,472 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#ifdef CONFIG_SPI_QUP
+#include <linux/spi/spi.h>
+#endif
+#include <mach/gpio.h>
+#include <mach/pmic.h>
+#include "msm_fb.h"
+
+#define LCDC_NT35582_PANEL_NAME		"lcdc_nt35582_wvga"
+
+#define WRITE_FIRST_TRANS	0x20
+#define WRITE_SECOND_TRANS	0x00
+#define WRITE_THIRD_TRANS	0x40
+#define READ_FIRST_TRANS	0x20
+#define READ_SECOND_TRANS	0x00
+#define READ_THIRD_TRANS	0xC0
+
+#ifdef CONFIG_SPI_QUP
+#define LCDC_NT35582_SPI_DEVICE_NAME		"lcdc_nt35582_spi"
+static struct spi_device *spi_client;
+#endif
+
+struct nt35582_state_type {
+	boolean display_on;
+	int bl_level;
+};
+
+static struct nt35582_state_type nt35582_state = { 0 };
+static int gpio_backlight_en;
+static struct msm_panel_common_pdata *lcdc_nt35582_pdata;
+
+static int spi_write_2bytes(struct spi_device *spi,
+	unsigned char reg_high_addr, unsigned char reg_low_addr)
+{
+	char tx_buf[4];
+	int rc;
+	struct spi_message m;
+	struct spi_transfer t;
+
+	memset(&t, 0, sizeof t);
+	t.tx_buf = tx_buf;
+
+	spi_setup(spi);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	tx_buf[0] = WRITE_FIRST_TRANS;
+	tx_buf[1] = reg_high_addr;
+	tx_buf[2] = WRITE_SECOND_TRANS;
+	tx_buf[3] = reg_low_addr;
+	t.rx_buf = NULL;
+	t.len = 4;
+	t.bits_per_word = 16;
+	rc = spi_sync(spi, &m);
+	if (rc)
+		pr_err("write spi command failed!\n");
+
+	return rc;
+}
+
+static int spi_write_3bytes(struct spi_device *spi, unsigned char reg_high_addr,
+	unsigned char reg_low_addr, unsigned char write_data)
+{
+	char tx_buf[6];
+	int rc;
+	struct spi_message  m;
+	struct spi_transfer t;
+
+	memset(&t, 0, sizeof t);
+	t.tx_buf = tx_buf;
+
+	spi_setup(spi);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	tx_buf[0] = WRITE_FIRST_TRANS;
+	tx_buf[1] = reg_high_addr;
+	tx_buf[2] = WRITE_SECOND_TRANS;
+	tx_buf[3] = reg_low_addr;
+	tx_buf[4] = WRITE_THIRD_TRANS;
+	tx_buf[5] = write_data;
+	t.rx_buf = NULL;
+	t.len = 6;
+	t.bits_per_word = 16;
+	rc = spi_sync(spi, &m);
+
+	if (rc)
+		pr_err("write spi command failed!\n");
+
+	return rc;
+}
+
+static int spi_read_bytes(struct spi_device *spi, unsigned char reg_high_addr,
+	unsigned char reg_low_addr, unsigned char *read_value)
+{
+	char tx_buf[6];
+	char rx_buf[6];
+	int rc;
+	struct spi_message m;
+	struct spi_transfer t;
+
+	memset(&t, 0, sizeof t);
+	t.tx_buf = tx_buf;
+
+	spi_setup(spi);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	tx_buf[0] = READ_FIRST_TRANS;
+	tx_buf[1] = reg_high_addr;
+	tx_buf[2] = READ_SECOND_TRANS;
+	tx_buf[3] = reg_low_addr;
+	tx_buf[4] = READ_THIRD_TRANS;
+	tx_buf[5] = 0x00;
+
+	t.rx_buf = rx_buf;
+	t.len = 6;
+	t.bits_per_word = 16;
+	rc = spi_sync(spi, &m);
+
+	if (rc)
+		pr_err("write spi command failed!\n");
+	else
+		*read_value = rx_buf[5];
+
+	return rc;
+}
+
+static void nt35582_disp_on(void)
+{
+	uint32 panel_id1 = 0, panel_id2 = 0;
+
+	if (!nt35582_state.display_on) {
+
+		/* GVDD setting */
+		spi_write_3bytes(spi_client, 0xC0, 0x00, 0xC0);
+		spi_write_3bytes(spi_client, 0xC0, 0x01, 0x00);
+		spi_write_3bytes(spi_client, 0xC0, 0x02, 0xC0);
+		spi_write_3bytes(spi_client, 0xC0, 0x03, 0x00);
+		/* Power setting */
+		spi_write_3bytes(spi_client, 0xC1, 0x00, 0x40);
+		spi_write_3bytes(spi_client, 0xC2, 0x00, 0x21);
+		spi_write_3bytes(spi_client, 0xC2, 0x02, 0x02);
+
+		/* Gamma setting */
+		spi_write_3bytes(spi_client, 0xE0, 0x00, 0x0E);
+		spi_write_3bytes(spi_client, 0xE0, 0x01, 0x54);
+		spi_write_3bytes(spi_client, 0xE0, 0x02, 0x63);
+		spi_write_3bytes(spi_client, 0xE0, 0x03, 0x76);
+		spi_write_3bytes(spi_client, 0xE0, 0x04, 0x1F);
+		spi_write_3bytes(spi_client, 0xE0, 0x05, 0x31);
+		spi_write_3bytes(spi_client, 0xE0, 0x06, 0x62);
+		spi_write_3bytes(spi_client, 0xE0, 0x07, 0x78);
+		spi_write_3bytes(spi_client, 0xE0, 0x08, 0x1F);
+		spi_write_3bytes(spi_client, 0xE0, 0x09, 0x25);
+		spi_write_3bytes(spi_client, 0xE0, 0x0A, 0xB3);
+		spi_write_3bytes(spi_client, 0xE0, 0x0B, 0x17);
+		spi_write_3bytes(spi_client, 0xE0, 0x0C, 0x38);
+		spi_write_3bytes(spi_client, 0xE0, 0x0D, 0x5A);
+		spi_write_3bytes(spi_client, 0xE0, 0x0E, 0xA2);
+		spi_write_3bytes(spi_client, 0xE0, 0x0F, 0xA2);
+		spi_write_3bytes(spi_client, 0xE0, 0x10, 0x24);
+		spi_write_3bytes(spi_client, 0xE0, 0x11, 0x57);
+
+		spi_write_3bytes(spi_client, 0xE1, 0x00, 0x0E);
+		spi_write_3bytes(spi_client, 0xE1, 0x01, 0x54);
+		spi_write_3bytes(spi_client, 0xE1, 0x02, 0x63);
+		spi_write_3bytes(spi_client, 0xE1, 0x03, 0x76);
+		spi_write_3bytes(spi_client, 0xE1, 0x04, 0x1F);
+		spi_write_3bytes(spi_client, 0xE1, 0x05, 0x31);
+		spi_write_3bytes(spi_client, 0xE1, 0x06, 0X62);
+		spi_write_3bytes(spi_client, 0xE1, 0x07, 0x78);
+		spi_write_3bytes(spi_client, 0xE1, 0x08, 0x1F);
+		spi_write_3bytes(spi_client, 0xE1, 0x09, 0x25);
+		spi_write_3bytes(spi_client, 0xE1, 0x0A, 0xB3);
+		spi_write_3bytes(spi_client, 0xE1, 0x0B, 0x17);
+		spi_write_3bytes(spi_client, 0xE1, 0x0C, 0x38);
+		spi_write_3bytes(spi_client, 0xE1, 0x0D, 0x5A);
+		spi_write_3bytes(spi_client, 0xE1, 0x0E, 0xA2);
+		spi_write_3bytes(spi_client, 0xE1, 0x0F, 0xA2);
+		spi_write_3bytes(spi_client, 0xE1, 0x10, 0x24);
+		spi_write_3bytes(spi_client, 0xE1, 0x11, 0x57);
+
+		spi_write_3bytes(spi_client, 0xE2, 0x00, 0x0E);
+		spi_write_3bytes(spi_client, 0xE2, 0x01, 0x54);
+		spi_write_3bytes(spi_client, 0xE2, 0x02, 0x63);
+		spi_write_3bytes(spi_client, 0xE2, 0x03, 0x76);
+		spi_write_3bytes(spi_client, 0xE2, 0x04, 0x1F);
+		spi_write_3bytes(spi_client, 0xE2, 0x05, 0x31);
+		spi_write_3bytes(spi_client, 0xE2, 0x06, 0x62);
+		spi_write_3bytes(spi_client, 0xE2, 0x07, 0x78);
+		spi_write_3bytes(spi_client, 0xE2, 0x08, 0x1F);
+		spi_write_3bytes(spi_client, 0xE2, 0x09, 0x25);
+		spi_write_3bytes(spi_client, 0xE2, 0x0A, 0xB3);
+		spi_write_3bytes(spi_client, 0xE2, 0x0B, 0x17);
+		spi_write_3bytes(spi_client, 0xE2, 0x0C, 0x38);
+		spi_write_3bytes(spi_client, 0xE2, 0x0D, 0x5A);
+		spi_write_3bytes(spi_client, 0xE2, 0x0E, 0xA2);
+		spi_write_3bytes(spi_client, 0xE2, 0x0F, 0xA2);
+		spi_write_3bytes(spi_client, 0xE2, 0x10, 0x24);
+		spi_write_3bytes(spi_client, 0xE2, 0x11, 0x57);
+
+		spi_write_3bytes(spi_client, 0xE3, 0x00, 0x0E);
+		spi_write_3bytes(spi_client, 0xE3, 0x01, 0x54);
+		spi_write_3bytes(spi_client, 0xE3, 0x02, 0x63);
+		spi_write_3bytes(spi_client, 0xE3, 0x03, 0x76);
+		spi_write_3bytes(spi_client, 0xE3, 0x04, 0x1F);
+		spi_write_3bytes(spi_client, 0xE3, 0x05, 0x31);
+		spi_write_3bytes(spi_client, 0xE3, 0x06, 0x62);
+		spi_write_3bytes(spi_client, 0xE3, 0x07, 0x78);
+		spi_write_3bytes(spi_client, 0xE3, 0x08, 0x1F);
+		spi_write_3bytes(spi_client, 0xE3, 0x09, 0x25);
+		spi_write_3bytes(spi_client, 0xE3, 0x0A, 0xB3);
+		spi_write_3bytes(spi_client, 0xE3, 0x0B, 0x17);
+		spi_write_3bytes(spi_client, 0xE3, 0x0C, 0x38);
+		spi_write_3bytes(spi_client, 0xE3, 0x0D, 0x5A);
+		spi_write_3bytes(spi_client, 0xE3, 0x0E, 0xA2);
+		spi_write_3bytes(spi_client, 0xE3, 0x0F, 0xA2);
+		spi_write_3bytes(spi_client, 0xE3, 0x10, 0x24);
+		spi_write_3bytes(spi_client, 0xE3, 0x11, 0x57);
+
+		spi_write_3bytes(spi_client, 0xE4, 0x00, 0x48);
+		spi_write_3bytes(spi_client, 0xE4, 0x01, 0x6B);
+		spi_write_3bytes(spi_client, 0xE4, 0x02, 0x84);
+		spi_write_3bytes(spi_client, 0xE4, 0x03, 0x9B);
+		spi_write_3bytes(spi_client, 0xE4, 0x04, 0x1F);
+		spi_write_3bytes(spi_client, 0xE4, 0x05, 0x31);
+		spi_write_3bytes(spi_client, 0xE4, 0x06, 0x62);
+		spi_write_3bytes(spi_client, 0xE4, 0x07, 0x78);
+		spi_write_3bytes(spi_client, 0xE4, 0x08, 0x1F);
+		spi_write_3bytes(spi_client, 0xE4, 0x09, 0x25);
+		spi_write_3bytes(spi_client, 0xE4, 0x0A, 0xB3);
+		spi_write_3bytes(spi_client, 0xE4, 0x0B, 0x17);
+		spi_write_3bytes(spi_client, 0xE4, 0x0C, 0x38);
+		spi_write_3bytes(spi_client, 0xE4, 0x0D, 0x5A);
+		spi_write_3bytes(spi_client, 0xE4, 0x0E, 0xA2);
+		spi_write_3bytes(spi_client, 0xE4, 0x0F, 0xA2);
+		spi_write_3bytes(spi_client, 0xE4, 0x10, 0x24);
+		spi_write_3bytes(spi_client, 0xE4, 0x11, 0x57);
+
+		spi_write_3bytes(spi_client, 0xE5, 0x00, 0x48);
+		spi_write_3bytes(spi_client, 0xE5, 0x01, 0x6B);
+		spi_write_3bytes(spi_client, 0xE5, 0x02, 0x84);
+		spi_write_3bytes(spi_client, 0xE5, 0x03, 0x9B);
+		spi_write_3bytes(spi_client, 0xE5, 0x04, 0x1F);
+		spi_write_3bytes(spi_client, 0xE5, 0x05, 0x31);
+		spi_write_3bytes(spi_client, 0xE5, 0x06, 0x62);
+		spi_write_3bytes(spi_client, 0xE5, 0x07, 0x78);
+		spi_write_3bytes(spi_client, 0xE5, 0x08, 0x1F);
+		spi_write_3bytes(spi_client, 0xE5, 0x09, 0x25);
+		spi_write_3bytes(spi_client, 0xE5, 0x0A, 0xB3);
+		spi_write_3bytes(spi_client, 0xE5, 0x0B, 0x17);
+		spi_write_3bytes(spi_client, 0xE5, 0x0C, 0x38);
+		spi_write_3bytes(spi_client, 0xE5, 0x0D, 0x5A);
+		spi_write_3bytes(spi_client, 0xE5, 0x0E, 0xA2);
+		spi_write_3bytes(spi_client, 0xE5, 0x0F, 0xA2);
+		spi_write_3bytes(spi_client, 0xE5, 0x10, 0x24);
+		spi_write_3bytes(spi_client, 0xE5, 0x11, 0x57);
+
+		/* Data format setting */
+		spi_write_3bytes(spi_client, 0x3A, 0x00, 0x70);
+
+		/* Reverse PCLK signal of LCM to meet Qualcomm's platform */
+		spi_write_3bytes(spi_client, 0x3B, 0x00, 0x2B);
+
+		/* Scan direstion setting */
+		spi_write_3bytes(spi_client, 0x36, 0x00, 0x00);
+
+		/* Sleep out */
+		spi_write_2bytes(spi_client, 0x11, 0x00);
+
+		msleep(120);
+
+		/* Display on */
+		spi_write_2bytes(spi_client, 0x29, 0x00);
+
+		pr_info("%s: LCM SPI display on CMD finished...\n", __func__);
+
+		msleep(200);
+
+		nt35582_state.display_on = TRUE;
+	}
+
+	/* Test to read RDDID. It should be 0x0055h and 0x0082h */
+	spi_read_bytes(spi_client, 0x10, 0x80, (unsigned char *)&panel_id1);
+	spi_read_bytes(spi_client, 0x11, 0x80, (unsigned char *)&panel_id2);
+
+	pr_info(KERN_INFO "nt35582_disp_on: LCM_ID=[0x%x, 0x%x]\n",
+		panel_id1, panel_id2);
+}
+
+static int lcdc_nt35582_panel_on(struct platform_device *pdev)
+{
+	nt35582_disp_on();
+	return 0;
+}
+
+static int lcdc_nt35582_panel_off(struct platform_device *pdev)
+{
+	nt35582_state.display_on = FALSE;
+	return 0;
+}
+
+static void lcdc_nt35582_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int bl_level;
+	int i = 0, step = 0;
+
+	bl_level = mfd->bl_level;
+	if (bl_level == nt35582_state.bl_level)
+		return;
+	else
+		nt35582_state.bl_level = bl_level;
+
+	if (bl_level == 0) {
+		gpio_set_value_cansleep(gpio_backlight_en, 0);
+		return;
+	}
+
+	/* Level:0~31 mapping to step 32~1 */
+	step = 32 - bl_level;
+	for (i = 0; i < step; i++) {
+		gpio_set_value_cansleep(gpio_backlight_en, 0);
+		ndelay(5);
+		gpio_set_value_cansleep(gpio_backlight_en, 1);
+		ndelay(5);
+	}
+}
+
+static int __devinit nt35582_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		lcdc_nt35582_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	gpio_backlight_en = *(lcdc_nt35582_pdata->gpio_num);
+
+	msm_fb_add_device(pdev);
+	return 0;
+}
+
+#ifdef CONFIG_SPI_QUP
+static int __devinit lcdc_nt35582_spi_probe(struct spi_device *spi)
+{
+	spi_client = spi;
+	spi_client->bits_per_word = 16;
+	spi_client->chip_select = 0;
+	spi_client->max_speed_hz = 1100000;
+	spi_client->mode = SPI_MODE_0;
+	spi_setup(spi_client);
+
+	return 0;
+}
+
+static int __devexit lcdc_nt35582_spi_remove(struct spi_device *spi)
+{
+	spi_client = NULL;
+	return 0;
+}
+
+static struct spi_driver lcdc_nt35582_spi_driver = {
+	.driver = {
+		.name = LCDC_NT35582_SPI_DEVICE_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = lcdc_nt35582_spi_probe,
+	.remove = __devexit_p(lcdc_nt35582_spi_remove),
+};
+#endif
+static struct platform_driver this_driver = {
+	.probe = nt35582_probe,
+	.driver = {
+		.name = LCDC_NT35582_PANEL_NAME,
+	},
+};
+
+static struct msm_fb_panel_data nt35582_panel_data = {
+	.on = lcdc_nt35582_panel_on,
+	.off = lcdc_nt35582_panel_off,
+	.set_backlight = lcdc_nt35582_set_backlight,
+};
+
+static struct platform_device this_device = {
+	.name = LCDC_NT35582_PANEL_NAME,
+	.id = 1,
+	.dev = {
+		.platform_data = &nt35582_panel_data,
+	}
+};
+
+static int __init lcdc_nt35582_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
+	if (msm_fb_detect_client(LCDC_NT35582_PANEL_NAME)) {
+		pr_err("detect failed\n");
+		return 0;
+	}
+#endif
+	ret = platform_driver_register(&this_driver);
+	if (ret) {
+		pr_err("Fails to platform_driver_register...\n");
+		return ret;
+	}
+
+	pinfo = &nt35582_panel_data.panel_info;
+	pinfo->xres = 480;
+	pinfo->yres = 800;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 25600000;
+	pinfo->bl_max = 31;
+	pinfo->bl_min = 1;
+
+	pinfo->lcdc.h_back_porch = 10;	/* hsw = 8 + hbp=184 */
+	pinfo->lcdc.h_front_porch = 10;
+	pinfo->lcdc.h_pulse_width = 2;
+	pinfo->lcdc.v_back_porch = 4;	/* vsw=1 + vbp = 2 */
+	pinfo->lcdc.v_front_porch = 10;
+	pinfo->lcdc.v_pulse_width = 2;
+	pinfo->lcdc.border_clr = 0;	/* blk */
+	pinfo->lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret) {
+		pr_err("not able to register the device\n");
+		goto fail_driver;
+	}
+#ifdef CONFIG_SPI_QUP
+	ret = spi_register_driver(&lcdc_nt35582_spi_driver);
+
+	if (ret) {
+		pr_err("not able to register spi\n");
+		goto fail_device;
+	}
+#endif
+	return ret;
+
+#ifdef CONFIG_SPI_QUP
+fail_device:
+	platform_device_unregister(&this_device);
+#endif
+fail_driver:
+	platform_driver_unregister(&this_driver);
+	return ret;
+}
+
+device_initcall(lcdc_nt35582_panel_init);
diff --git a/drivers/video/msm/lcdc_panel.c b/drivers/video/msm/lcdc_panel.c
new file mode 100644
index 0000000..5705325
--- /dev/null
+++ b/drivers/video/msm/lcdc_panel.c
@@ -0,0 +1,84 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+
+static int lcdc_panel_on(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int lcdc_panel_off(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int __devinit lcdc_panel_probe(struct platform_device *pdev)
+{
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = lcdc_panel_probe,
+	.driver = {
+		.name   = "lcdc_panel",
+	},
+};
+
+static struct msm_fb_panel_data lcdc_panel_data = {
+	.on = lcdc_panel_on,
+	.off = lcdc_panel_off,
+};
+
+static int lcdc_dev_id;
+
+int lcdc_device_register(struct msm_panel_info *pinfo)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	pdev = platform_device_alloc("lcdc_panel", ++lcdc_dev_id);
+	if (!pdev)
+		return -ENOMEM;
+
+	lcdc_panel_data.panel_info = *pinfo;
+	ret = platform_device_add_data(pdev, &lcdc_panel_data,
+		sizeof(lcdc_panel_data));
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int __init lcdc_panel_init(void)
+{
+	return platform_driver_register(&this_driver);
+}
+
+module_init(lcdc_panel_init);
diff --git a/drivers/video/msm/lcdc_prism.c b/drivers/video/msm/lcdc_prism.c
new file mode 100644
index 0000000..d127f63
--- /dev/null
+++ b/drivers/video/msm/lcdc_prism.c
@@ -0,0 +1,61 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+
+#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
+#include "mddihosti.h"
+#endif
+
+static int __init lcdc_prism_init(void)
+{
+	int ret;
+	struct msm_panel_info pinfo;
+
+#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
+	ret = msm_fb_detect_client("lcdc_prism_wvga");
+	if (ret == -ENODEV)
+		return 0;
+
+	if (ret && (mddi_get_client_id() != 0))
+		return 0;
+#endif
+
+	pinfo.xres = 800;
+	pinfo.yres = 480;
+	MSM_FB_SINGLE_MODE_PANEL(&pinfo);
+	pinfo.type = LCDC_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.fb_num = 2;
+	pinfo.clk_rate = 30720000;
+
+	pinfo.lcdc.h_back_porch = 21;
+	pinfo.lcdc.h_front_porch = 81;
+	pinfo.lcdc.h_pulse_width = 60;
+	pinfo.lcdc.v_back_porch = 18;
+	pinfo.lcdc.v_front_porch = 27;
+	pinfo.lcdc.v_pulse_width = 2;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+
+	ret = lcdc_device_register(&pinfo);
+	if (ret)
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(lcdc_prism_init);
diff --git a/drivers/video/msm/lcdc_samsung_oled_pt.c b/drivers/video/msm/lcdc_samsung_oled_pt.c
new file mode 100644
index 0000000..16790f3
--- /dev/null
+++ b/drivers/video/msm/lcdc_samsung_oled_pt.c
@@ -0,0 +1,588 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#ifdef CONFIG_SPI_QUP
+#include <linux/spi/spi.h>
+#else
+#include <mach/gpio.h>
+#endif
+#include "msm_fb.h"
+
+#define DEBUG
+/* #define SYSFS_DEBUG_CMD */
+
+#ifdef CONFIG_SPI_QUP
+#define LCDC_SAMSUNG_SPI_DEVICE_NAME	"lcdc_samsung_ams367pe02"
+static struct spi_device *lcdc_spi_client;
+#else
+static int spi_cs;
+static int spi_sclk;
+static int spi_mosi;
+#endif
+
+struct samsung_state_type {
+	boolean disp_initialized;
+	boolean display_on;
+	boolean disp_powered_up;
+	int brightness;
+};
+
+struct samsung_spi_data {
+	u8 addr;
+	u8 len;
+	u8 data[22];
+};
+
+static struct samsung_spi_data panel_sequence[] = {
+	{ .addr = 0xf8, .len = 14, .data = { 0x01, 0x27, 0x27, 0x07, 0x07,
+	 0x54, 0x9f, 0x63, 0x86, 0x1a, 0x33, 0x0d, 0x00, 0x00 } },
+};
+static struct samsung_spi_data display_sequence[] = {
+	{ .addr = 0xf2, .len = 5, .data = { 0x02, 0x03, 0x1c, 0x10, 0x10 } },
+	{ .addr = 0xf7, .len = 3, .data = { 0x00, 0x00, 0x30 } },
+};
+
+/* lum=300 cd/m2 */
+static struct samsung_spi_data gamma_sequence_300[] = {
+	{ .addr = 0xfa, .len = 22, .data = { 0x02, 0x18, 0x08, 0x24, 0x7d, 0x77,
+	 0x5b, 0xbe, 0xc1, 0xb1, 0xb3, 0xb7, 0xa6, 0xc3, 0xc5, 0xb9, 0x00, 0xb3,
+	 0x00, 0xaf, 0x00, 0xe8 } },
+	{ .addr = 0xFA, .len = 1, .data = { 0x03 } },
+};
+/* lum = 180 cd/m2*/
+static struct samsung_spi_data gamma_sequence_180[] = {
+	{ .addr = 0xfa, .len = 22, .data = { 0x02, 0x18, 0x08, 0x24, 0x83, 0x78,
+	 0x60, 0xc5, 0xc6, 0xb8, 0xba, 0xbe, 0xad, 0xcb, 0xcd, 0xc2, 0x00, 0x92,
+	 0x00, 0x8e, 0x00, 0xbc } },
+	{ .addr = 0xFA, .len = 1, .data = { 0x03 } },
+};
+/* lum = 80 cd/m2*/
+static struct samsung_spi_data gamma_sequence_80[] = {
+	{ .addr = 0xfa, .len = 22, .data = { 0x02, 0x18, 0x08, 0x24, 0x94, 0x73,
+	 0x6c, 0xcb, 0xca, 0xbe, 0xc4, 0xc7, 0xb8, 0xd3, 0xd5, 0xcb, 0x00, 0x6d,
+	 0x00, 0x69, 0x00, 0x8b } },
+	{ .addr = 0xFA, .len = 1, .data = { 0x03 } },
+};
+
+static struct samsung_spi_data etc_sequence[] = {
+	{ .addr = 0xF6, .len = 3, .data = { 0x00, 0x8e, 0x07 } },
+	{ .addr = 0xB3, .len = 1, .data = { 0x0C } },
+};
+
+static struct samsung_state_type samsung_state = { .brightness = 180 };
+static struct msm_panel_common_pdata *lcdc_samsung_pdata;
+
+#ifndef CONFIG_SPI_QUP
+static void samsung_spi_write_byte(boolean dc, u8 data)
+{
+	uint32 bit;
+	int bnum;
+
+	gpio_set_value(spi_sclk, 0);
+	gpio_set_value(spi_mosi, dc ? 1 : 0);
+	udelay(1);			/* at least 20 ns */
+	gpio_set_value(spi_sclk, 1);	/* clk high */
+	udelay(1);			/* at least 20 ns */
+
+	bnum = 8;			/* 8 data bits */
+	bit = 0x80;
+	while (bnum--) {
+		gpio_set_value(spi_sclk, 0); /* clk low */
+		gpio_set_value(spi_mosi, (data & bit) ? 1 : 0);
+		udelay(1);
+		gpio_set_value(spi_sclk, 1); /* clk high */
+		udelay(1);
+		bit >>= 1;
+	}
+	gpio_set_value(spi_mosi, 0);
+
+}
+
+static void samsung_spi_read_bytes(u8 cmd, u8 *data, int num)
+{
+	int bnum;
+
+	/* Chip Select - low */
+	gpio_set_value(spi_cs, 0);
+	udelay(2);
+
+	/* command byte first */
+	samsung_spi_write_byte(0, cmd);
+	udelay(2);
+
+	gpio_direction_input(spi_mosi);
+
+	if (num > 1) {
+		/* extra dummy clock */
+		gpio_set_value(spi_sclk, 0);
+		udelay(1);
+		gpio_set_value(spi_sclk, 1);
+		udelay(1);
+	}
+
+	/* followed by data bytes */
+	bnum = num * 8;	/* number of bits */
+	*data = 0;
+	while (bnum) {
+		gpio_set_value(spi_sclk, 0); /* clk low */
+		udelay(1);
+		*data <<= 1;
+		*data |= gpio_get_value(spi_mosi) ? 1 : 0;
+		gpio_set_value(spi_sclk, 1); /* clk high */
+		udelay(1);
+		--bnum;
+		if ((bnum % 8) == 0)
+			++data;
+	}
+
+	gpio_direction_output(spi_mosi, 0);
+
+	/* Chip Select - high */
+	udelay(2);
+	gpio_set_value(spi_cs, 1);
+}
+#endif
+
+#ifdef DEBUG
+static const char *byte_to_binary(const u8 *buf, int len)
+{
+	static char b[32*8+1];
+	char *p = b;
+	int i, z;
+
+	for (i = 0; i < len; ++i) {
+		u8 val = *buf++;
+		for (z = 1 << 7; z > 0; z >>= 1)
+			*p++ = (val & z) ? '1' : '0';
+	}
+	*p = 0;
+
+	return b;
+}
+#endif
+
+#define BIT_OFFSET	(bit_size % 8)
+#define ADD_BIT(val) do { \
+		tx_buf[bit_size / 8] |= \
+			(u8)((val ? 1 : 0) << (7 - BIT_OFFSET)); \
+		++bit_size; \
+	} while (0)
+
+#define ADD_BYTE(data) do { \
+		tx_buf[bit_size / 8] |= (u8)(data >> BIT_OFFSET); \
+		bit_size += 8; \
+		if (BIT_OFFSET != 0) \
+			tx_buf[bit_size / 8] |= (u8)(data << (8 - BIT_OFFSET));\
+	} while (0)
+
+static int samsung_serigo(struct samsung_spi_data data)
+{
+#ifdef CONFIG_SPI_QUP
+	char                tx_buf[32];
+	int                 bit_size = 0, i, rc;
+	struct spi_message  m;
+	struct spi_transfer t;
+
+	if (!lcdc_spi_client) {
+		pr_err("%s lcdc_spi_client is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(&t, 0, sizeof t);
+	memset(tx_buf, 0, sizeof tx_buf);
+	t.tx_buf = tx_buf;
+	spi_setup(lcdc_spi_client);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	ADD_BIT(FALSE);
+	ADD_BYTE(data.addr);
+	for (i = 0; i < data.len; ++i) {
+		ADD_BIT(TRUE);
+		ADD_BYTE(data.data[i]);
+	}
+
+	/* add padding bits so we round to next byte */
+	t.len = (bit_size+7) / 8;
+	if (t.len <= 4)
+		t.bits_per_word = bit_size;
+
+	rc = spi_sync(lcdc_spi_client, &m);
+#ifdef DEBUG
+	pr_info("%s: addr=0x%02x, #args=%d[%d] [%s], rc=%d\n",
+		__func__, data.addr, t.len, t.bits_per_word,
+		byte_to_binary(tx_buf, t.len), rc);
+#endif
+	return rc;
+#else
+	int i;
+
+	/* Chip Select - low */
+	gpio_set_value(spi_cs, 0);
+	udelay(2);
+
+	samsung_spi_write_byte(FALSE, data.addr);
+	udelay(2);
+
+	for (i = 0; i < data.len; ++i) {
+		samsung_spi_write_byte(TRUE, data.data[i]);
+		udelay(2);
+	}
+
+	/* Chip Select - high */
+	gpio_set_value(spi_cs, 1);
+#ifdef DEBUG
+	pr_info("%s: cmd=0x%02x, #args=%d\n", __func__, data.addr, data.len);
+#endif
+	return 0;
+#endif
+}
+
+static int samsung_write_cmd(u8 cmd)
+{
+#ifdef CONFIG_SPI_QUP
+	char                tx_buf[2];
+	int                 bit_size = 0, rc;
+	struct spi_message  m;
+	struct spi_transfer t;
+
+	if (!lcdc_spi_client) {
+		pr_err("%s lcdc_spi_client is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(&t, 0, sizeof t);
+	memset(tx_buf, 0, sizeof tx_buf);
+	t.tx_buf = tx_buf;
+	spi_setup(lcdc_spi_client);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	ADD_BIT(FALSE);
+	ADD_BYTE(cmd);
+
+	t.len = 2;
+	t.bits_per_word = 9;
+
+	rc = spi_sync(lcdc_spi_client, &m);
+#ifdef DEBUG
+	pr_info("%s: addr=0x%02x, #args=%d[%d] [%s], rc=%d\n",
+		__func__, cmd, t.len, t.bits_per_word,
+		byte_to_binary(tx_buf, t.len), rc);
+#endif
+	return rc;
+#else
+	/* Chip Select - low */
+	gpio_set_value(spi_cs, 0);
+	udelay(2);
+
+	samsung_spi_write_byte(FALSE, cmd);
+
+	/* Chip Select - high */
+	udelay(2);
+	gpio_set_value(spi_cs, 1);
+#ifdef DEBUG
+	pr_info("%s: cmd=0x%02x\n", __func__, cmd);
+#endif
+	return 0;
+#endif
+}
+
+static int samsung_serigo_list(struct samsung_spi_data *data, int count)
+{
+	int i, rc;
+	for (i = 0; i < count; ++i, ++data) {
+		rc = samsung_serigo(*data);
+		if (rc)
+			return rc;
+		msleep(10);
+	}
+	return 0;
+}
+
+#ifndef CONFIG_SPI_QUP
+static void samsung_spi_init(void)
+{
+	spi_sclk = *(lcdc_samsung_pdata->gpio_num);
+	spi_cs   = *(lcdc_samsung_pdata->gpio_num + 1);
+	spi_mosi = *(lcdc_samsung_pdata->gpio_num + 2);
+
+	/* Set the output so that we don't disturb the slave device */
+	gpio_set_value(spi_sclk, 1);
+	gpio_set_value(spi_mosi, 0);
+
+	/* Set the Chip Select deasserted (active low) */
+	gpio_set_value(spi_cs, 1);
+}
+#endif
+
+static void samsung_disp_powerup(void)
+{
+	if (!samsung_state.disp_powered_up && !samsung_state.display_on)
+		samsung_state.disp_powered_up = TRUE;
+}
+
+static struct work_struct disp_on_delayed_work;
+static void samsung_disp_on_delayed_work(struct work_struct *work_ptr)
+{
+	/* 0x01: Software Reset */
+	samsung_write_cmd(0x01);
+	msleep(120);
+
+	msleep(300);
+	samsung_serigo_list(panel_sequence,
+		sizeof(panel_sequence)/sizeof(*panel_sequence));
+	samsung_serigo_list(display_sequence,
+		sizeof(display_sequence)/sizeof(*display_sequence));
+
+	switch (samsung_state.brightness) {
+	case 300:
+		samsung_serigo_list(gamma_sequence_300,
+			sizeof(gamma_sequence_300)/sizeof(*gamma_sequence_300));
+		break;
+	case 180:
+	default:
+		samsung_serigo_list(gamma_sequence_180,
+			sizeof(gamma_sequence_180)/sizeof(*gamma_sequence_180));
+		break;
+	case 80:
+		samsung_serigo_list(gamma_sequence_80,
+			sizeof(gamma_sequence_80)/sizeof(*gamma_sequence_80));
+		break;
+	}
+
+	samsung_serigo_list(etc_sequence,
+		sizeof(etc_sequence)/sizeof(*etc_sequence));
+
+	/* 0x11: Sleep Out */
+	samsung_write_cmd(0x11);
+	msleep(120);
+	/* 0x13: Normal Mode On */
+	samsung_write_cmd(0x13);
+
+#ifndef CONFIG_SPI_QUP
+	{
+		u8 data;
+
+		msleep(120);
+		/* 0x0A: Read Display Power Mode */
+		samsung_spi_read_bytes(0x0A, &data, 1);
+		pr_info("%s: power=[%s]\n", __func__,
+			byte_to_binary(&data, 1));
+
+		msleep(120);
+		/* 0x0C: Read Display Pixel Format */
+		samsung_spi_read_bytes(0x0C, &data, 1);
+		pr_info("%s: pixel-format=[%s]\n", __func__,
+			byte_to_binary(&data, 1));
+	}
+#endif
+	msleep(120);
+	/* 0x29: Display On */
+	samsung_write_cmd(0x29);
+}
+
+static void samsung_disp_on(void)
+{
+	if (samsung_state.disp_powered_up && !samsung_state.display_on) {
+		INIT_WORK(&disp_on_delayed_work, samsung_disp_on_delayed_work);
+		schedule_work(&disp_on_delayed_work);
+
+		samsung_state.display_on = TRUE;
+	}
+}
+
+static int lcdc_samsung_panel_on(struct platform_device *pdev)
+{
+	pr_info("%s\n", __func__);
+	if (!samsung_state.disp_initialized) {
+#ifndef CONFIG_SPI_QUP
+		lcdc_samsung_pdata->panel_config_gpio(1);
+		samsung_spi_init();
+#endif
+		samsung_disp_powerup();
+		samsung_disp_on();
+		samsung_state.disp_initialized = TRUE;
+	}
+	return 0;
+}
+
+static int lcdc_samsung_panel_off(struct platform_device *pdev)
+{
+	pr_info("%s\n", __func__);
+	if (samsung_state.disp_powered_up && samsung_state.display_on) {
+		/* 0x10: Sleep In */
+		samsung_write_cmd(0x10);
+		msleep(120);
+
+		samsung_state.display_on = FALSE;
+		samsung_state.disp_initialized = FALSE;
+	}
+	return 0;
+}
+
+#ifdef SYSFS_DEBUG_CMD
+static ssize_t samsung_rda_cmd(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	ssize_t ret = snprintf(buf, PAGE_SIZE, "n/a\n");
+	pr_info("%s: 'n/a'\n", __func__);
+	return ret;
+}
+
+static ssize_t samsung_wta_cmd(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ssize_t ret = strnlen(buf, PAGE_SIZE);
+	uint32 cmd;
+
+	sscanf(buf, "%x", &cmd);
+	samsung_write_cmd((u8)cmd);
+
+	return ret;
+}
+
+static DEVICE_ATTR(cmd, S_IRUGO | S_IWUGO, samsung_rda_cmd, samsung_wta_cmd);
+static struct attribute *fs_attrs[] = {
+	&dev_attr_cmd.attr,
+	NULL,
+};
+static struct attribute_group fs_attr_group = {
+	.attrs = fs_attrs,
+};
+#endif
+
+static struct msm_fb_panel_data samsung_panel_data = {
+	.on = lcdc_samsung_panel_on,
+	.off = lcdc_samsung_panel_off,
+};
+
+static int __devinit samsung_probe(struct platform_device *pdev)
+{
+	struct msm_panel_info *pinfo;
+#ifdef SYSFS_DEBUG_CMD
+	struct platform_device *fb_dev;
+	struct msm_fb_data_type *mfd;
+	int rc;
+#endif
+
+	pr_info("%s: id=%d\n", __func__, pdev->id);
+	lcdc_samsung_pdata = pdev->dev.platform_data;
+
+	pinfo = &samsung_panel_data.panel_info;
+	pinfo->xres = 480;
+	pinfo->yres = 800;
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 25600000; /* Max 27.77MHz */
+	pinfo->bl_max = 15;
+	pinfo->bl_min = 1;
+
+	/* AMS367PE02 Operation Manual, Page 7 */
+	pinfo->lcdc.h_back_porch = 16-2;	/* HBP-HLW */
+	pinfo->lcdc.h_front_porch = 16;
+	pinfo->lcdc.h_pulse_width = 2;
+	/* AMS367PE02 Operation Manual, Page 6 */
+	pinfo->lcdc.v_back_porch = 3-2;		/* VBP-VLW */
+	pinfo->lcdc.v_front_porch = 28;
+	pinfo->lcdc.v_pulse_width = 2;
+
+	pinfo->lcdc.border_clr = 0;
+	pinfo->lcdc.underflow_clr = 0xff;
+	pinfo->lcdc.hsync_skew = 0;
+	pdev->dev.platform_data = &samsung_panel_data;
+
+#ifndef SYSFS_DEBUG_CMD
+	msm_fb_add_device(pdev);
+#else
+	fb_dev = msm_fb_add_device(pdev);
+	mfd = platform_get_drvdata(fb_dev);
+	rc = sysfs_create_group(&mfd->fbi->dev->kobj, &fs_attr_group);
+	if (rc) {
+		pr_err("%s: sysfs group creation failed, rc=%d\n", __func__,
+			rc);
+		return rc;
+	}
+#endif
+	return 0;
+}
+
+#ifdef CONFIG_SPI_QUP
+static int __devinit lcdc_samsung_spi_probe(struct spi_device *spi)
+{
+	pr_info("%s\n", __func__);
+	lcdc_spi_client = spi;
+	lcdc_spi_client->bits_per_word = 32;
+	return 0;
+}
+static int __devexit lcdc_samsung_spi_remove(struct spi_device *spi)
+{
+	lcdc_spi_client = NULL;
+	return 0;
+}
+static struct spi_driver lcdc_samsung_spi_driver = {
+	.driver.name   = LCDC_SAMSUNG_SPI_DEVICE_NAME,
+	.driver.owner  = THIS_MODULE,
+	.probe         = lcdc_samsung_spi_probe,
+	.remove        = __devexit_p(lcdc_samsung_spi_remove),
+};
+#endif
+
+static struct platform_driver this_driver = {
+	.probe		= samsung_probe,
+	.driver.name	= "lcdc_samsung_oled",
+};
+
+static int __init lcdc_samsung_panel_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("lcdc_samsung_oled")) {
+		pr_err("%s: detect failed\n", __func__);
+		return 0;
+	}
+
+	ret = platform_driver_register(&this_driver);
+	if (ret) {
+		pr_err("%s: driver register failed, rc=%d\n", __func__, ret);
+		return ret;
+	}
+
+#ifdef CONFIG_SPI_QUP
+	ret = spi_register_driver(&lcdc_samsung_spi_driver);
+
+	if (ret) {
+		pr_err("%s: spi register failed: rc=%d\n", __func__, ret);
+		platform_driver_unregister(&this_driver);
+	} else
+		pr_info("%s: SUCCESS (SPI)\n", __func__);
+#else
+	pr_info("%s: SUCCESS (BitBang)\n", __func__);
+#endif
+	return ret;
+}
+
+module_init(lcdc_samsung_panel_init);
+static void __exit lcdc_samsung_panel_exit(void)
+{
+	pr_info("%s\n", __func__);
+#ifdef CONFIG_SPI_QUP
+	spi_unregister_driver(&lcdc_samsung_spi_driver);
+#endif
+	platform_driver_unregister(&this_driver);
+}
+module_exit(lcdc_samsung_panel_exit);
diff --git a/drivers/video/msm/lcdc_samsung_wsvga.c b/drivers/video/msm/lcdc_samsung_wsvga.c
new file mode 100644
index 0000000..6b35e52
--- /dev/null
+++ b/drivers/video/msm/lcdc_samsung_wsvga.c
@@ -0,0 +1,270 @@
+/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#ifdef CONFIG_PMIC8058_PWM
+#include <linux/mfd/pmic8058.h>
+#include <linux/pmic8058-pwm.h>
+#endif
+#include <mach/gpio.h>
+#include "msm_fb.h"
+
+
+
+#ifdef CONFIG_PMIC8058_PWM
+static struct pwm_device *bl_pwm0;
+static struct pwm_device *bl_pwm1;
+
+/* for samsung panel 300hz was the minimum freq where flickering wasnt
+ * observed as the screen was dimmed
+ */
+
+#define PWM_FREQ_HZ 300
+#define PWM_PERIOD_USEC (USEC_PER_SEC / PWM_FREQ_HZ)
+#define PWM_LEVEL 100
+#define PWM_DUTY_LEVEL (PWM_PERIOD_USEC / PWM_LEVEL)
+#endif
+
+struct lcdc_samsung_data {
+	struct msm_panel_common_pdata *pdata;
+#ifdef CONFIG_FB_MSM_LCDC_DSUB
+	int vga_enabled;
+#endif
+	struct platform_device *fbpdev;
+};
+
+static struct lcdc_samsung_data *dd;
+
+
+static void lcdc_samsung_panel_set_backlight(struct msm_fb_data_type *mfd)
+{
+#ifdef CONFIG_PMIC8058_PWM
+	int bl_level;
+	int ret;
+
+	bl_level = mfd->bl_level;
+
+	if (bl_pwm0) {
+		ret = pwm_config(bl_pwm0, PWM_DUTY_LEVEL * bl_level,
+			PWM_PERIOD_USEC);
+		if (ret)
+			printk(KERN_ERR "pwm_config on pwm 0 failed %d\n", ret);
+	}
+
+	if (bl_pwm1) {
+		ret = pwm_config(bl_pwm1,
+			PWM_PERIOD_USEC - (PWM_DUTY_LEVEL * bl_level),
+			PWM_PERIOD_USEC);
+		if (ret)
+			printk(KERN_ERR "pwm_config on pwm 1 failed %d\n", ret);
+	}
+
+	if (bl_pwm0) {
+		ret = pwm_enable(bl_pwm0);
+		if (ret)
+			printk(KERN_ERR "pwm_enable on pwm 0 failed %d\n", ret);
+	}
+
+	if (bl_pwm1) {
+		ret = pwm_enable(bl_pwm1);
+		if (ret)
+			printk(KERN_ERR "pwm_enable on pwm 1 failed %d\n", ret);
+	}
+#endif
+
+}
+
+#ifdef CONFIG_FB_MSM_LCDC_DSUB
+static ssize_t show_vga_enable(struct device *device,
+			       struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", dd->vga_enabled);
+}
+
+static ssize_t store_vga_enable(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	unsigned long enable;
+	int rc;
+
+	rc = strict_strtoul(buf, 10, &enable);
+	if (rc)
+		return -EINVAL;
+
+	if (dd->pdata && dd->pdata->vga_switch)
+		rc = dd->pdata->vga_switch(enable);
+	else
+		rc = -ENODEV;
+	if (!rc) {
+		dd->vga_enabled = enable;
+		rc = count;
+	}
+	return rc;
+}
+
+static DEVICE_ATTR(vga_enable, S_IRUGO|S_IWUSR, show_vga_enable,
+		   store_vga_enable);
+static struct attribute *attrs[] = {
+	&dev_attr_vga_enable.attr,
+	NULL,
+};
+static struct attribute_group attr_group = {
+	.attrs = attrs,
+};
+#endif
+
+static int __devinit samsung_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+#ifdef CONFIG_FB_MSM_LCDC_DSUB
+	struct msm_fb_data_type *mfd;
+#endif
+
+	if (pdev->id == 0) {
+		dd = kzalloc(sizeof *dd, GFP_KERNEL);
+		if (!dd)
+			return -ENOMEM;
+#ifdef CONFIG_FB_MSM_LCDC_DSUB
+		dd->vga_enabled = 0;
+#endif
+		dd->pdata = pdev->dev.platform_data;
+		return 0;
+	} else if (!dd)
+		return -ENODEV;
+
+#ifdef CONFIG_PMIC8058_PWM
+	bl_pwm0 = pwm_request(dd->pdata->gpio_num[0], "backlight1");
+	if (bl_pwm0 == NULL || IS_ERR(bl_pwm0)) {
+		pr_err("%s pwm_request() failed\n", __func__);
+		bl_pwm0 = NULL;
+	}
+
+	bl_pwm1 = pwm_request(dd->pdata->gpio_num[1], "backlight2");
+	if (bl_pwm1 == NULL || IS_ERR(bl_pwm1)) {
+		pr_err("%s pwm_request() failed\n", __func__);
+		bl_pwm1 = NULL;
+	}
+
+	pr_debug("samsung_probe: bl_pwm0=%p LPG_chan0=%d "
+			"bl_pwm1=%p LPG_chan1=%d\n",
+			bl_pwm0, (int)dd->pdata->gpio_num[0],
+			bl_pwm1, (int)dd->pdata->gpio_num[1]
+			);
+#endif
+
+
+	dd->fbpdev = msm_fb_add_device(pdev);
+	if (!dd->fbpdev) {
+		dev_err(&pdev->dev, "failed to add msm_fb device\n");
+		rc = -ENODEV;
+		goto probe_exit;
+	}
+
+#ifdef CONFIG_FB_MSM_LCDC_DSUB
+	mfd = platform_get_drvdata(dd->fbpdev);
+	if (mfd && mfd->fbi && mfd->fbi->dev) {
+		rc = sysfs_create_group(&mfd->fbi->dev->kobj, &attr_group);
+		if (rc)
+			dev_err(&pdev->dev, "failed to create sysfs group\n");
+	} else {
+		dev_err(&pdev->dev, "no dev to create sysfs group\n");
+		rc = -ENODEV;
+	}
+#endif
+
+probe_exit:
+	return rc;
+}
+
+#ifdef CONFIG_FB_MSM_LCDC_DSUB
+static int __devexit samsung_remove(struct platform_device *pdev)
+{
+	sysfs_remove_group(&dd->fbpdev->dev.kobj, &attr_group);
+	return 0;
+}
+#endif
+
+static struct platform_driver this_driver = {
+	.probe  = samsung_probe,
+#ifdef CONFIG_FB_MSM_LCDC_DSUB
+	.remove = samsung_remove,
+#endif
+	.driver = {
+		.name   = "lcdc_samsung_wsvga",
+	},
+};
+
+static struct msm_fb_panel_data samsung_panel_data = {
+	.set_backlight = lcdc_samsung_panel_set_backlight,
+};
+
+static struct platform_device this_device = {
+	.name   = "lcdc_samsung_wsvga",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &samsung_panel_data,
+	}
+};
+
+static int __init lcdc_samsung_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	if (msm_fb_detect_client("lcdc_samsung_wsvga"))
+		return 0;
+
+	ret = platform_driver_register(&this_driver);
+	if (ret)
+		return ret;
+
+	pinfo = &samsung_panel_data.panel_info;
+	pinfo->xres = 1024;
+	pinfo->yres = 600;
+#ifdef CONFIG_FB_MSM_LCDC_DSUB
+	/* DSUB (VGA) is on the same bus, this allows us to allocate for the
+	 * max resolution of the DSUB display */
+	pinfo->mode2_xres = 1440;
+	pinfo->mode2_yres = 900;
+	pinfo->mode2_bpp = 16;
+#else
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+#endif
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 18;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 43192000;
+	pinfo->bl_max = PWM_LEVEL;
+	pinfo->bl_min = 1;
+
+	pinfo->lcdc.h_back_porch = 80;
+	pinfo->lcdc.h_front_porch = 48;
+	pinfo->lcdc.h_pulse_width = 32;
+	pinfo->lcdc.v_back_porch = 4;
+	pinfo->lcdc.v_front_porch = 3;
+	pinfo->lcdc.v_pulse_width = 1;
+	pinfo->lcdc.border_clr = 0;
+	pinfo->lcdc.underflow_clr = 0xff;
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret)
+		platform_driver_unregister(&this_driver);
+
+	return ret;
+}
+
+module_init(lcdc_samsung_panel_init);
diff --git a/drivers/video/msm/lcdc_sharp_wvga_pt.c b/drivers/video/msm/lcdc_sharp_wvga_pt.c
new file mode 100644
index 0000000..2ba2618
--- /dev/null
+++ b/drivers/video/msm/lcdc_sharp_wvga_pt.c
@@ -0,0 +1,414 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#ifdef CONFIG_PMIC8058_PWM
+#include <linux/mfd/pmic8058.h>
+#include <linux/pmic8058-pwm.h>
+#endif
+#ifdef CONFIG_SPI_QSD
+#include <linux/spi/spi.h>
+#endif
+#include <mach/gpio.h>
+#include "msm_fb.h"
+
+#ifdef CONFIG_SPI_QSD
+#define LCDC_SHARP_SPI_DEVICE_NAME	"lcdc_sharp_ls038y7dx01"
+static struct spi_device *lcdc_spi_client;
+#endif
+static int lcdc_sharp_panel_off(struct platform_device *pdev);
+
+#define BL_MAX		16
+
+#ifdef CONFIG_PMIC8058_PWM
+static struct pwm_device *bl_pwm;
+
+#define PWM_PERIOD	1000	/* us, period of 1Khz */
+#define DUTY_LEVEL	(PWM_PERIOD / BL_MAX)
+#endif
+
+#ifndef CONFIG_SPI_QSD
+static int spi_cs;
+static int spi_sclk;
+static int spi_mosi;
+static int spi_miso;
+static unsigned char bit_shift[8] = { (1 << 7),	/* MSB */
+	(1 << 6),
+	(1 << 5),
+	(1 << 4),
+	(1 << 3),
+	(1 << 2),
+	(1 << 1),
+	(1 << 0)		               /* LSB */
+};
+#endif
+
+struct sharp_state_type {
+	boolean disp_initialized;
+	boolean display_on;
+	boolean disp_powered_up;
+};
+
+struct sharp_spi_data {
+	u8 addr;
+	u8 data;
+};
+
+static struct sharp_spi_data init_sequence[] = {
+	{  15, 0x01 },
+	{   5, 0x01 },
+	{   7, 0x10 },
+	{   9, 0x1E },
+	{  10, 0x04 },
+	{  17, 0xFF },
+	{  21, 0x8A },
+	{  22, 0x00 },
+	{  23, 0x82 },
+	{  24, 0x24 },
+	{  25, 0x22 },
+	{  26, 0x6D },
+	{  27, 0xEB },
+	{  28, 0xB9 },
+	{  29, 0x3A },
+	{  49, 0x1A },
+	{  50, 0x16 },
+	{  51, 0x05 },
+	{  55, 0x7F },
+	{  56, 0x15 },
+	{  57, 0x7B },
+	{  60, 0x05 },
+	{  61, 0x0C },
+	{  62, 0x80 },
+	{  63, 0x00 },
+	{  92, 0x90 },
+	{  97, 0x01 },
+	{  98, 0xFF },
+	{ 113, 0x11 },
+	{ 114, 0x02 },
+	{ 115, 0x08 },
+	{ 123, 0xAB },
+	{ 124, 0x04 },
+	{   6, 0x02 },
+	{ 133, 0x00 },
+	{ 134, 0xFE },
+	{ 135, 0x22 },
+	{ 136, 0x0B },
+	{ 137, 0xFF },
+	{ 138, 0x0F },
+	{ 139, 0x00 },
+	{ 140, 0xFE },
+	{ 141, 0x22 },
+	{ 142, 0x0B },
+	{ 143, 0xFF },
+	{ 144, 0x0F },
+	{ 145, 0x00 },
+	{ 146, 0xFE },
+	{ 147, 0x22 },
+	{ 148, 0x0B },
+	{ 149, 0xFF },
+	{ 150, 0x0F },
+	{ 202, 0x30 },
+	{  30, 0x01 },
+	{   4, 0x01 },
+	{  31, 0x41 },
+};
+
+static struct sharp_state_type sharp_state = { 0 };
+static struct msm_panel_common_pdata *lcdc_sharp_pdata;
+
+#ifndef CONFIG_SPI_QSD
+static void sharp_spi_write_byte(u8 val)
+{
+	int i;
+
+	/* Clock should be Low before entering */
+	for (i = 0; i < 8; i++) {
+		/* #1: Drive the Data (High or Low) */
+		if (val & bit_shift[i])
+			gpio_set_value(spi_mosi, 1);
+		else
+			gpio_set_value(spi_mosi, 0);
+
+		/* #2: Drive the Clk High and then Low */
+		gpio_set_value(spi_sclk, 1);
+		gpio_set_value(spi_sclk, 0);
+	}
+}
+#endif
+
+static int serigo(u8 reg, u8 data)
+{
+#ifdef CONFIG_SPI_QSD
+	char                tx_buf[2];
+	int                 rc;
+	struct spi_message  m;
+	struct spi_transfer t;
+
+	if (!lcdc_spi_client) {
+		printk(KERN_ERR "%s lcdc_spi_client is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	memset(&t, 0, sizeof t);
+	t.tx_buf = tx_buf;
+	spi_setup(lcdc_spi_client);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	tx_buf[0] = reg;
+	tx_buf[1] = data;
+	t.rx_buf = NULL;
+	t.len = 2;
+	rc = spi_sync(lcdc_spi_client, &m);
+	return rc;
+#else
+	/* Enable the Chip Select - low */
+	gpio_set_value(spi_cs, 0);
+	udelay(1);
+
+	/* Transmit register address first, then data */
+	sharp_spi_write_byte(reg);
+
+	/* Idle state of MOSI is Low */
+	gpio_set_value(spi_mosi, 0);
+	udelay(1);
+	sharp_spi_write_byte(data);
+
+	gpio_set_value(spi_mosi, 0);
+	gpio_set_value(spi_cs, 1);
+	return 0;
+#endif
+}
+
+#ifndef CONFIG_SPI_QSD
+static void sharp_spi_init(void)
+{
+	spi_sclk = *(lcdc_sharp_pdata->gpio_num);
+	spi_cs   = *(lcdc_sharp_pdata->gpio_num + 1);
+	spi_mosi = *(lcdc_sharp_pdata->gpio_num + 2);
+	spi_miso = *(lcdc_sharp_pdata->gpio_num + 3);
+
+	/* Set the output so that we don't disturb the slave device */
+	gpio_set_value(spi_sclk, 0);
+	gpio_set_value(spi_mosi, 0);
+
+	/* Set the Chip Select deasserted (active low) */
+	gpio_set_value(spi_cs, 1);
+}
+#endif
+
+static void sharp_disp_powerup(void)
+{
+	if (!sharp_state.disp_powered_up && !sharp_state.display_on)
+		sharp_state.disp_powered_up = TRUE;
+}
+
+static void sharp_disp_on(void)
+{
+	int i;
+
+	if (sharp_state.disp_powered_up && !sharp_state.display_on) {
+		for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
+			serigo(init_sequence[i].addr,
+			       init_sequence[i].data);
+		}
+		mdelay(10);
+		serigo(31, 0xC1);
+		mdelay(10);
+		serigo(31, 0xD9);
+		serigo(31, 0xDF);
+
+		sharp_state.display_on = TRUE;
+	}
+}
+
+static int lcdc_sharp_panel_on(struct platform_device *pdev)
+{
+	if (!sharp_state.disp_initialized) {
+#ifndef CONFIG_SPI_QSD
+		lcdc_sharp_pdata->panel_config_gpio(1);
+		sharp_spi_init();
+#endif
+		sharp_disp_powerup();
+		sharp_disp_on();
+		sharp_state.disp_initialized = TRUE;
+	}
+	return 0;
+}
+
+static int lcdc_sharp_panel_off(struct platform_device *pdev)
+{
+	if (sharp_state.disp_powered_up && sharp_state.display_on) {
+		serigo(4, 0x00);
+		mdelay(40);
+		serigo(31, 0xC1);
+		mdelay(40);
+		serigo(31, 0x00);
+		msleep(16);
+		sharp_state.display_on = FALSE;
+		sharp_state.disp_initialized = FALSE;
+	}
+	return 0;
+}
+
+static void lcdc_sharp_panel_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int bl_level;
+
+	bl_level = mfd->bl_level;
+
+#ifdef CONFIG_PMIC8058_PWM
+	if (bl_pwm) {
+		pwm_config(bl_pwm, DUTY_LEVEL * bl_level, PWM_PERIOD);
+		pwm_enable(bl_pwm);
+	}
+#endif
+}
+
+static int __devinit sharp_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		lcdc_sharp_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+#ifdef CONFIG_PMIC8058_PWM
+	bl_pwm = pwm_request(lcdc_sharp_pdata->gpio, "backlight");
+	if (bl_pwm == NULL || IS_ERR(bl_pwm)) {
+		pr_err("%s pwm_request() failed\n", __func__);
+		bl_pwm = NULL;
+	}
+
+	printk(KERN_INFO "sharp_probe: bl_pwm=%x LPG_chan=%d\n",
+			(int) bl_pwm, (int)lcdc_sharp_pdata->gpio);
+#endif
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+#ifdef CONFIG_SPI_QSD
+static int __devinit lcdc_sharp_spi_probe(struct spi_device *spi)
+{
+	lcdc_spi_client = spi;
+	lcdc_spi_client->bits_per_word = 32;
+	return 0;
+}
+static int __devexit lcdc_sharp_spi_remove(struct spi_device *spi)
+{
+	lcdc_spi_client = NULL;
+	return 0;
+}
+static struct spi_driver lcdc_sharp_spi_driver = {
+	.driver = {
+		.name  = LCDC_SHARP_SPI_DEVICE_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe         = lcdc_sharp_spi_probe,
+	.remove        = __devexit_p(lcdc_sharp_spi_remove),
+};
+#endif
+static struct platform_driver this_driver = {
+	.probe  = sharp_probe,
+	.driver = {
+		.name   = "lcdc_sharp_wvga",
+	},
+};
+
+static struct msm_fb_panel_data sharp_panel_data = {
+	.on = lcdc_sharp_panel_on,
+	.off = lcdc_sharp_panel_off,
+	.set_backlight = lcdc_sharp_panel_set_backlight,
+};
+
+static struct platform_device this_device = {
+	.name   = "lcdc_sharp_wvga",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &sharp_panel_data,
+	}
+};
+
+static int __init lcdc_sharp_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	if (msm_fb_detect_client("lcdc_sharp_wvga_pt"))
+		return 0;
+#endif
+
+	ret = platform_driver_register(&this_driver);
+	if (ret)
+		return ret;
+
+	pinfo = &sharp_panel_data.panel_info;
+	pinfo->xres = 480;
+	pinfo->yres = 800;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 18;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 24500000;
+	pinfo->bl_max = BL_MAX;
+	pinfo->bl_min = 1;
+
+	pinfo->lcdc.h_back_porch = 20;
+	pinfo->lcdc.h_front_porch = 10;
+	pinfo->lcdc.h_pulse_width = 10;
+	pinfo->lcdc.v_back_porch = 2;
+	pinfo->lcdc.v_front_porch = 2;
+	pinfo->lcdc.v_pulse_width = 2;
+	pinfo->lcdc.border_clr = 0;
+	pinfo->lcdc.underflow_clr = 0xff;
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret) {
+		printk(KERN_ERR "%s not able to register the device\n",
+			__func__);
+		goto fail_driver;
+	}
+#ifdef CONFIG_SPI_QSD
+	ret = spi_register_driver(&lcdc_sharp_spi_driver);
+
+	if (ret) {
+		printk(KERN_ERR "%s not able to register spi\n", __func__);
+		goto fail_device;
+	}
+#endif
+	return ret;
+#ifdef CONFIG_SPI_QSD
+fail_device:
+	platform_device_unregister(&this_device);
+#endif
+fail_driver:
+		platform_driver_unregister(&this_driver);
+
+	return ret;
+}
+
+module_init(lcdc_sharp_panel_init);
+#ifdef CONFIG_SPI_QSD
+static void __exit lcdc_sharp_panel_exit(void)
+{
+	spi_unregister_driver(&lcdc_sharp_spi_driver);
+}
+module_exit(lcdc_sharp_panel_exit);
+#endif
+
diff --git a/drivers/video/msm/lcdc_st15.c b/drivers/video/msm/lcdc_st15.c
new file mode 100644
index 0000000..cdae358
--- /dev/null
+++ b/drivers/video/msm/lcdc_st15.c
@@ -0,0 +1,413 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include "msm_fb.h"
+
+#define DEVICE_NAME "sii9022"
+#define SII9022_DEVICE_ID   0xB0
+#define SII9022_ISR                   0x3D
+#define SII9022_ISR_RXS_STATUS        0x08
+
+static int lcdc_sii9022_panel_on(struct platform_device *pdev);
+static int lcdc_sii9022_panel_off(struct platform_device *pdev);
+
+static struct i2c_client *sii9022_i2c_client;
+
+struct sii9022_data {
+	struct msm_hdmi_platform_data *pd;
+	struct platform_device *pdev;
+	struct work_struct work;
+	int x_res;
+	int y_res;
+	int sysfs_entry_created;
+	int hdmi_attached;
+};
+static struct sii9022_data *dd;
+
+struct sii9022_i2c_addr_data{
+	u8 addr;
+	u8 data;
+};
+
+/* video mode data */
+static u8 video_mode_data[] = {
+	0x00,
+	0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
+};
+
+static u8 avi_io_format[] = {
+	0x09,
+	0x00, 0x00,
+};
+
+/* power state */
+static struct sii9022_i2c_addr_data regset0[] = {
+	{ 0x60, 0x04 },
+	{ 0x63, 0x00 },
+	{ 0x1E, 0x00 },
+};
+
+static u8 video_infoframe[] = {
+	0x0C,
+	0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
+	0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
+};
+
+/* configure audio */
+static struct sii9022_i2c_addr_data regset1[] = {
+	{ 0x26, 0x90 },
+	{ 0x20, 0x90 },
+	{ 0x1F, 0x80 },
+	{ 0x26, 0x80 },
+	{ 0x24, 0x02 },
+	{ 0x25, 0x0B },
+	{ 0xBC, 0x02 },
+	{ 0xBD, 0x24 },
+	{ 0xBE, 0x02 },
+};
+
+/* enable audio */
+static u8 misc_infoframe[] = {
+	0xBF,
+	0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+/* set HDMI, active */
+static struct sii9022_i2c_addr_data regset2[] = {
+	{ 0x1A, 0x01 },
+	{ 0x3D, 0x00 },
+	{ 0x3C, 0x02 },
+};
+
+static struct msm_fb_panel_data sii9022_panel_data = {
+	.on = lcdc_sii9022_panel_on,
+	.off = lcdc_sii9022_panel_off,
+};
+
+static struct platform_device sii9022_device = {
+	.name   = DEVICE_NAME,
+	.id	= 1,
+	.dev	= {
+		.platform_data = &sii9022_panel_data,
+	}
+};
+
+static int send_i2c_data(struct i2c_client *client,
+			 struct sii9022_i2c_addr_data *regset,
+			 int size)
+{
+	int i;
+	int rc = 0;
+
+	for (i = 0; i < size; i++) {
+		rc = i2c_smbus_write_byte_data(
+			client,
+			regset[i].addr, regset[i].data);
+		if (rc)
+			break;
+	}
+	return rc;
+}
+
+static void sii9022_work_f(struct work_struct *work)
+{
+	int isr;
+
+	isr = i2c_smbus_read_byte_data(sii9022_i2c_client, SII9022_ISR);
+	if (isr < 0) {
+		dev_err(&sii9022_i2c_client->dev,
+			"i2c read of isr failed rc = 0x%x\n", isr);
+		return;
+	}
+	if (isr == 0)
+		return;
+
+	/* reset any set bits */
+	i2c_smbus_write_byte_data(sii9022_i2c_client, SII9022_ISR, isr);
+	dd->hdmi_attached = isr & SII9022_ISR_RXS_STATUS;
+	if (dd->pd->cable_detect)
+		dd->pd->cable_detect(dd->hdmi_attached);
+	if (dd->hdmi_attached) {
+		dd->x_res = 1280;
+		dd->y_res = 720;
+	} else {
+		dd->x_res = sii9022_panel_data.panel_info.xres;
+		dd->y_res = sii9022_panel_data.panel_info.yres;
+	}
+}
+
+static irqreturn_t sii9022_interrupt(int irq, void *dev_id)
+{
+	struct sii9022_data *dd = dev_id;
+
+	schedule_work(&dd->work);
+	return IRQ_HANDLED;
+}
+
+static int hdmi_sii_enable(struct i2c_client *client)
+{
+	int rc;
+	int retries = 10;
+	int count;
+
+	rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
+	if (rc)
+		goto enable_exit;
+
+	do {
+		msleep(1);
+		rc = i2c_smbus_read_byte_data(client, 0x1B);
+	} while ((rc != SII9022_DEVICE_ID) && retries--);
+
+	if (rc != SII9022_DEVICE_ID)
+		return -ENODEV;
+
+	rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
+	if (rc)
+		goto enable_exit;
+
+	count = ARRAY_SIZE(video_mode_data);
+	rc = i2c_master_send(client, video_mode_data, count);
+	if (rc != count) {
+		rc = -EIO;
+		goto enable_exit;
+	}
+
+	rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
+	if (rc)
+		goto enable_exit;
+	count = ARRAY_SIZE(avi_io_format);
+	rc = i2c_master_send(client, avi_io_format, count);
+	if (rc != count) {
+		rc = -EIO;
+		goto enable_exit;
+	}
+
+	rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
+	if (rc)
+		goto enable_exit;
+
+	count = ARRAY_SIZE(video_infoframe);
+	rc = i2c_master_send(client, video_infoframe, count);
+	if (rc != count) {
+		rc = -EIO;
+		goto enable_exit;
+	}
+
+	rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
+	if (rc)
+		goto enable_exit;
+
+	count = ARRAY_SIZE(misc_infoframe);
+	rc = i2c_master_send(client, misc_infoframe, count);
+	if (rc != count) {
+		rc = -EIO;
+		goto enable_exit;
+	}
+
+	rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
+	if (rc)
+		goto enable_exit;
+
+	return 0;
+enable_exit:
+	printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
+	return rc;
+}
+
+static ssize_t show_res(struct device *device,
+			 struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%dx%d\n", dd->x_res, dd->y_res);
+}
+
+static struct device_attribute device_attrs[] = {
+	__ATTR(screen_resolution, S_IRUGO|S_IWUSR, show_res, NULL),
+};
+
+static int lcdc_sii9022_panel_on(struct platform_device *pdev)
+{
+	int rc;
+	if (!dd->sysfs_entry_created) {
+		dd->pdev = pdev;
+		rc = device_create_file(&pdev->dev, &device_attrs[0]);
+		if (!rc)
+			dd->sysfs_entry_created = 1;
+	}
+
+	rc = hdmi_sii_enable(sii9022_i2c_client);
+	if (rc) {
+		dd->hdmi_attached = 0;
+		dd->x_res = sii9022_panel_data.panel_info.xres;
+		dd->y_res = sii9022_panel_data.panel_info.yres;
+	}
+	if (dd->pd->irq)
+		enable_irq(dd->pd->irq);
+	/* Don't return the value from hdmi_sii_enable().
+	 * It may fail on some ST1.5s, but we must return 0 from this
+	 * function in order for the on-board display to turn on.
+	 */
+	return 0;
+}
+
+static int lcdc_sii9022_panel_off(struct platform_device *pdev)
+{
+	if (dd->pd->irq)
+		disable_irq(dd->pd->irq);
+	return 0;
+}
+
+static const struct i2c_device_id hmdi_sii_id[] = {
+	{ DEVICE_NAME, 0 },
+	{ }
+};
+
+static int hdmi_sii_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	int rc;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
+		return -ENODEV;
+
+	dd = kzalloc(sizeof *dd, GFP_KERNEL);
+	if (!dd) {
+		rc = -ENOMEM;
+		goto probe_exit;
+	}
+	sii9022_i2c_client = client;
+	i2c_set_clientdata(client, dd);
+	dd->pd = client->dev.platform_data;
+	if (!dd->pd) {
+		rc = -ENODEV;
+		goto probe_free;
+	}
+	if (dd->pd->irq) {
+		INIT_WORK(&dd->work, sii9022_work_f);
+		rc = request_irq(dd->pd->irq,
+				 &sii9022_interrupt,
+				 IRQF_TRIGGER_FALLING,
+				 "sii9022_cable", dd);
+		if (rc)
+			goto probe_free;
+		disable_irq(dd->pd->irq);
+	}
+	msm_fb_add_device(&sii9022_device);
+	dd->x_res = sii9022_panel_data.panel_info.xres;
+	dd->y_res = sii9022_panel_data.panel_info.yres;
+
+	return 0;
+
+probe_free:
+	i2c_set_clientdata(client, NULL);
+	kfree(dd);
+probe_exit:
+	return rc;
+}
+
+static int __devexit hdmi_sii_remove(struct i2c_client *client)
+{
+	int err = 0 ;
+	struct msm_hdmi_platform_data *pd;
+
+	if (dd->sysfs_entry_created)
+		device_remove_file(&dd->pdev->dev, &device_attrs[0]);
+	pd = client->dev.platform_data;
+	if (pd && pd->irq)
+		free_irq(pd->irq, dd);
+	i2c_set_clientdata(client, NULL);
+	kfree(dd);
+
+	return err ;
+}
+
+#ifdef CONFIG_PM
+static int sii9022_suspend(struct device *dev)
+{
+	if (dd && dd->pd && dd->pd->irq)
+		disable_irq(dd->pd->irq);
+	return 0;
+}
+
+static int sii9022_resume(struct device *dev)
+{
+	if (dd && dd->pd && dd->pd->irq)
+		enable_irq(dd->pd->irq);
+	return 0;
+}
+
+static struct dev_pm_ops sii9022_pm_ops = {
+	.suspend = sii9022_suspend,
+	.resume = sii9022_resume,
+};
+#endif
+
+static struct i2c_driver hdmi_sii_i2c_driver = {
+	.driver = {
+		.name = DEVICE_NAME,
+		.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm     = &sii9022_pm_ops,
+#endif
+	},
+	.probe = hdmi_sii_probe,
+	.remove =  __exit_p(hdmi_sii_remove),
+	.id_table = hmdi_sii_id,
+};
+
+static int __init lcdc_st15_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	if (msm_fb_detect_client("lcdc_st15"))
+		return 0;
+
+	pinfo = &sii9022_panel_data.panel_info;
+	pinfo->xres = 1366;
+	pinfo->yres = 768;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24;
+	pinfo->fb_num = 2;
+	pinfo->clk_rate = 74250000;
+
+	pinfo->lcdc.h_back_porch = 120;
+	pinfo->lcdc.h_front_porch = 20;
+	pinfo->lcdc.h_pulse_width = 40;
+	pinfo->lcdc.v_back_porch = 25;
+	pinfo->lcdc.v_front_porch = 1;
+	pinfo->lcdc.v_pulse_width = 7;
+	pinfo->lcdc.border_clr = 0;      /* blk */
+	pinfo->lcdc.underflow_clr = 0xff;        /* blue */
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = i2c_add_driver(&hdmi_sii_i2c_driver);
+	if (ret)
+		printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
+
+	return ret;
+}
+
+static void __exit hdmi_sii_exit(void)
+{
+	i2c_del_driver(&hdmi_sii_i2c_driver);
+}
+
+module_init(lcdc_st15_init);
+module_exit(hdmi_sii_exit);
diff --git a/drivers/video/msm/lcdc_toshiba_fwvga_pt.c b/drivers/video/msm/lcdc_toshiba_fwvga_pt.c
new file mode 100644
index 0000000..3e81471
--- /dev/null
+++ b/drivers/video/msm/lcdc_toshiba_fwvga_pt.c
@@ -0,0 +1,471 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <mach/gpio.h>
+#include <mach/pmic.h>
+#include <mach/socinfo.h>
+#include "msm_fb.h"
+
+static int spi_cs0_N;
+static int spi_sclk;
+static int spi_mosi;
+static int spi_miso;
+
+struct toshiba_state_type {
+	boolean disp_initialized;
+	boolean display_on;
+	boolean disp_powered_up;
+};
+
+static struct toshiba_state_type toshiba_state = { 0 };
+static struct msm_panel_common_pdata *lcdc_toshiba_pdata;
+
+static int toshiba_spi_write(char data1, char data2, int rs)
+{
+	uint32 bitdata = 0, bnum = 24, bmask = 0x800000;
+
+	gpio_set_value_cansleep(spi_cs0_N, 0);	/* cs* low */
+	udelay(1);
+
+	if (rs)
+		bitdata = (0x72 << 16);
+	else
+		bitdata = (0x70 << 16);
+
+	bitdata |= ((data1 << 8) | data2);
+
+	while (bnum) {
+		gpio_set_value_cansleep(spi_sclk, 0); /* clk low */
+		udelay(1);
+
+		if (bitdata & bmask)
+			gpio_set_value_cansleep(spi_mosi, 1);
+		else
+			gpio_set_value_cansleep(spi_mosi, 0);
+
+		udelay(1);
+		gpio_set_value_cansleep(spi_sclk, 1); /* clk high */
+		udelay(1);
+		bmask >>= 1;
+		bnum--;
+	}
+
+	gpio_set_value_cansleep(spi_cs0_N, 1);	/* cs* high */
+	udelay(1);
+	return 0;
+}
+
+static void spi_pin_assign(void)
+{
+	/* Setting the Default GPIO's */
+	spi_mosi  = *(lcdc_toshiba_pdata->gpio_num);
+	spi_miso  = *(lcdc_toshiba_pdata->gpio_num + 1);
+	spi_sclk  = *(lcdc_toshiba_pdata->gpio_num + 2);
+	spi_cs0_N = *(lcdc_toshiba_pdata->gpio_num + 3);
+}
+
+static void toshiba_disp_powerup(void)
+{
+	if (!toshiba_state.disp_powered_up && !toshiba_state.display_on) {
+		/* Reset the hardware first */
+		/* Include DAC power up implementation here */
+	      toshiba_state.disp_powered_up = TRUE;
+	}
+}
+
+static void toshiba_disp_on(void)
+{
+	if (toshiba_state.disp_powered_up && !toshiba_state.display_on) {
+		toshiba_spi_write(0x01, 0x00, 0);
+		toshiba_spi_write(0x30, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x01, 0x01, 0);
+		toshiba_spi_write(0x40, 0x10, 1);
+
+#ifdef TOSHIBA_FWVGA_FULL_INIT
+		udelay(500);
+		toshiba_spi_write(0x01, 0x06, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+		msleep(20);
+
+		toshiba_spi_write(0x00, 0x01, 0);
+		toshiba_spi_write(0x03, 0x10, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x02, 0);
+		toshiba_spi_write(0x01, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x03, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x07, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x08, 0);
+		toshiba_spi_write(0x00, 0x04, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x09, 0);
+		toshiba_spi_write(0x00, 0x0c, 1);
+#endif
+		udelay(500);
+		toshiba_spi_write(0x00, 0x0c, 0);
+		toshiba_spi_write(0x40, 0x10, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x0e, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x20, 0);
+		toshiba_spi_write(0x01, 0x3f, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x22, 0);
+		toshiba_spi_write(0x76, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x23, 0);
+		toshiba_spi_write(0x1c, 0x0a, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x24, 0);
+		toshiba_spi_write(0x1c, 0x2c, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x25, 0);
+		toshiba_spi_write(0x1c, 0x4e, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x27, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x28, 0);
+		toshiba_spi_write(0x76, 0x0c, 1);
+
+#ifdef TOSHIBA_FWVGA_FULL_INIT
+		udelay(500);
+		toshiba_spi_write(0x03, 0x00, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x01, 0);
+		toshiba_spi_write(0x05, 0x02, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x02, 0);
+		toshiba_spi_write(0x07, 0x05, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x03, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x04, 0);
+		toshiba_spi_write(0x02, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x05, 0);
+		toshiba_spi_write(0x07, 0x07, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x06, 0);
+		toshiba_spi_write(0x10, 0x10, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x07, 0);
+		toshiba_spi_write(0x02, 0x02, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x08, 0);
+		toshiba_spi_write(0x07, 0x04, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x09, 0);
+		toshiba_spi_write(0x07, 0x07, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x0a, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x0b, 0);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x0c, 0);
+		toshiba_spi_write(0x07, 0x07, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x0d, 0);
+		toshiba_spi_write(0x10, 0x10, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x10, 0);
+		toshiba_spi_write(0x01, 0x04, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x11, 0);
+		toshiba_spi_write(0x05, 0x03, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x12, 0);
+		toshiba_spi_write(0x03, 0x04, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x15, 0);
+		toshiba_spi_write(0x03, 0x04, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x16, 0);
+		toshiba_spi_write(0x03, 0x1c, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x17, 0);
+		toshiba_spi_write(0x02, 0x04, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x18, 0);
+		toshiba_spi_write(0x04, 0x02, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x19, 0);
+		toshiba_spi_write(0x03, 0x05, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x1c, 0);
+		toshiba_spi_write(0x07, 0x07, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x1d, 0);
+		toshiba_spi_write(0x02, 0x1f, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x20, 0);
+		toshiba_spi_write(0x05, 0x07, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x21, 0);
+		toshiba_spi_write(0x06, 0x04, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x22, 0);
+		toshiba_spi_write(0x04, 0x05, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x27, 0);
+		toshiba_spi_write(0x02, 0x03, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x28, 0);
+		toshiba_spi_write(0x03, 0x00, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x03, 0x29, 0);
+		toshiba_spi_write(0x00, 0x02, 1);
+
+#endif
+		udelay(500);
+		toshiba_spi_write(0x01, 0x00, 0);
+		toshiba_spi_write(0x36, 0x3c, 1);
+		udelay(500);
+
+		toshiba_spi_write(0x01, 0x01, 0);
+		toshiba_spi_write(0x40, 0x03, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x01, 0x02, 0);
+		toshiba_spi_write(0x00, 0x01, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x01, 0x03, 0);
+		toshiba_spi_write(0x3c, 0x58, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x01, 0x0c, 0);
+		toshiba_spi_write(0x01, 0x35, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x01, 0x06, 0);
+		toshiba_spi_write(0x00, 0x02, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x00, 0x29, 0);
+		toshiba_spi_write(0x03, 0xbf, 1);
+
+		udelay(500);
+		toshiba_spi_write(0x01, 0x06, 0);
+		toshiba_spi_write(0x00, 0x03, 1);
+		msleep(32);
+
+		toshiba_spi_write(0x01, 0x01, 0);
+		toshiba_spi_write(0x40, 0x10, 1);
+		msleep(80);
+
+		toshiba_state.display_on = TRUE;
+	}
+}
+
+static int lcdc_toshiba_panel_on(struct platform_device *pdev)
+{
+	if (!toshiba_state.disp_initialized) {
+		/* Configure reset GPIO that drives DAC */
+		if (lcdc_toshiba_pdata->panel_config_gpio)
+			lcdc_toshiba_pdata->panel_config_gpio(1);
+		toshiba_disp_powerup();
+		toshiba_disp_on();
+		toshiba_state.disp_initialized = TRUE;
+	}
+	return 0;
+}
+
+static int lcdc_toshiba_panel_off(struct platform_device *pdev)
+{
+	if (toshiba_state.disp_powered_up && toshiba_state.display_on) {
+		toshiba_spi_write(0x01, 0x06, 1);
+		toshiba_spi_write(0x00, 0x02, 1);
+		msleep(80);
+
+		toshiba_spi_write(0x01, 0x06, 1);
+		toshiba_spi_write(0x00, 0x00, 1);
+
+		toshiba_spi_write(0x00, 0x29, 1);
+		toshiba_spi_write(0x00, 0x02, 1);
+
+		toshiba_spi_write(0x01, 0x00, 1);
+		toshiba_spi_write(0x30, 0x00, 1);
+
+		if (lcdc_toshiba_pdata->panel_config_gpio)
+			lcdc_toshiba_pdata->panel_config_gpio(0);
+		toshiba_state.display_on = FALSE;
+		toshiba_state.disp_initialized = FALSE;
+	}
+
+	return 0;
+}
+
+static void lcdc_toshiba_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int ret;
+	int bl_level;
+
+	bl_level = mfd->bl_level;
+
+	if (lcdc_toshiba_pdata && lcdc_toshiba_pdata->pmic_backlight)
+		ret = lcdc_toshiba_pdata->pmic_backlight(bl_level);
+	else
+		pr_err("%s(): Backlight level set failed", __func__);
+
+	return;
+}
+
+static int __devinit toshiba_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		lcdc_toshiba_pdata = pdev->dev.platform_data;
+		spi_pin_assign();
+		return 0;
+	}
+	msm_fb_add_device(pdev);
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = toshiba_probe,
+	.driver = {
+		.name   = "lcdc_toshiba_fwvga_pt",
+	},
+};
+
+static struct msm_fb_panel_data toshiba_panel_data = {
+	.on = lcdc_toshiba_panel_on,
+	.off = lcdc_toshiba_panel_off,
+	.set_backlight = lcdc_toshiba_set_backlight,
+};
+
+static struct platform_device this_device = {
+	.name   = "lcdc_toshiba_fwvga_pt",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &toshiba_panel_data,
+	}
+};
+
+static int __init lcdc_toshiba_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	ret = msm_fb_detect_client("lcdc_toshiba_fwvga_pt");
+	if (ret)
+		return 0;
+
+
+	ret = platform_driver_register(&this_driver);
+	if (ret)
+		return ret;
+
+	pinfo = &toshiba_panel_data.panel_info;
+	pinfo->xres = 480;
+	pinfo->yres = 864;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 18;
+	pinfo->fb_num = 2;
+	/* 30Mhz mdp_lcdc_pclk and mdp_lcdc_pad_pcl */
+	pinfo->clk_rate = 30720000;
+	pinfo->bl_max = 100;
+	pinfo->bl_min = 1;
+
+	if (cpu_is_msm7x25a() || cpu_is_msm7x25aa()) {
+		pinfo->yres = 320;
+		pinfo->lcdc.h_back_porch = 10;
+		pinfo->lcdc.h_front_porch = 21;
+		pinfo->lcdc.h_pulse_width = 5;
+		pinfo->lcdc.v_back_porch = 8;
+		pinfo->lcdc.v_front_porch = 540;
+		pinfo->lcdc.v_pulse_width = 42;
+		pinfo->lcdc.border_clr = 0;     /* blk */
+		pinfo->lcdc.underflow_clr = 0xff;       /* blue */
+		pinfo->lcdc.hsync_skew = 0;
+	} else {
+		pinfo->lcdc.h_back_porch = 8;
+		pinfo->lcdc.h_front_porch = 16;
+		pinfo->lcdc.h_pulse_width = 8;
+		pinfo->lcdc.v_back_porch = 2;
+		pinfo->lcdc.v_front_porch = 2;
+		pinfo->lcdc.v_pulse_width = 2;
+		pinfo->lcdc.border_clr = 0;     /* blk */
+		pinfo->lcdc.underflow_clr = 0xff;       /* blue */
+		pinfo->lcdc.hsync_skew = 0;
+	}
+
+	ret = platform_device_register(&this_device);
+	if (ret) {
+		printk(KERN_ERR "%s not able to register the device\n",
+			 __func__);
+		platform_driver_unregister(&this_driver);
+	}
+	return ret;
+}
+
+device_initcall(lcdc_toshiba_panel_init);
diff --git a/drivers/video/msm/lcdc_toshiba_wvga_pt.c b/drivers/video/msm/lcdc_toshiba_wvga_pt.c
new file mode 100644
index 0000000..f0aa8f5
--- /dev/null
+++ b/drivers/video/msm/lcdc_toshiba_wvga_pt.c
@@ -0,0 +1,519 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#ifdef CONFIG_SPI_QSD
+#include <linux/spi/spi.h>
+#endif
+#include <mach/gpio.h>
+#include <mach/pmic.h>
+#include "msm_fb.h"
+
+#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
+#include "mddihosti.h"
+#endif
+
+#ifdef CONFIG_SPI_QSD
+#define LCDC_TOSHIBA_SPI_DEVICE_NAME "lcdc_toshiba_ltm030dd40"
+static struct spi_device *lcdc_toshiba_spi_client;
+#else
+static int spi_cs;
+static int spi_sclk;
+static int spi_mosi;
+static int spi_miso;
+#endif
+struct toshiba_state_type{
+	boolean disp_initialized;
+	boolean display_on;
+	boolean disp_powered_up;
+};
+
+static struct toshiba_state_type toshiba_state = { 0 };
+static struct msm_panel_common_pdata *lcdc_toshiba_pdata;
+
+#ifndef CONFIG_SPI_QSD
+static void toshiba_spi_write_byte(char dc, uint8 data)
+{
+	uint32 bit;
+	int bnum;
+
+	gpio_set_value(spi_sclk, 0); /* clk low */
+	/* dc: 0 for command, 1 for parameter */
+	gpio_set_value(spi_mosi, dc);
+	udelay(1);	/* at least 20 ns */
+	gpio_set_value(spi_sclk, 1); /* clk high */
+	udelay(1);	/* at least 20 ns */
+	bnum = 8;	/* 8 data bits */
+	bit = 0x80;
+	while (bnum) {
+		gpio_set_value(spi_sclk, 0); /* clk low */
+		if (data & bit)
+			gpio_set_value(spi_mosi, 1);
+		else
+			gpio_set_value(spi_mosi, 0);
+		udelay(1);
+		gpio_set_value(spi_sclk, 1); /* clk high */
+		udelay(1);
+		bit >>= 1;
+		bnum--;
+	}
+}
+#endif
+
+static int toshiba_spi_write(char cmd, uint32 data, int num)
+{
+	char *bp;
+#ifdef CONFIG_SPI_QSD
+	char                tx_buf[4];
+	int                 rc, i;
+	struct spi_message  m;
+	struct spi_transfer t;
+	uint32 final_data = 0;
+
+	if (!lcdc_toshiba_spi_client) {
+		printk(KERN_ERR "%s lcdc_toshiba_spi_client is NULL\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	memset(&t, 0, sizeof t);
+	t.tx_buf = tx_buf;
+	spi_setup(lcdc_toshiba_spi_client);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	/* command byte first */
+	final_data |= cmd << 23;
+	t.len = num + 2;
+	if (t.len < 4)
+		t.bits_per_word = 8 * t.len;
+	/* followed by parameter bytes */
+	if (num) {
+		bp = (char *)&data;;
+		bp += (num - 1);
+		i = 1;
+		while (num) {
+			final_data |= 1 << (((4 - i) << 3) - i - 1);
+			final_data |= *bp << (((4 - i - 1) << 3) - i - 1);
+			num--;
+			bp--;
+			i++;
+		}
+	}
+
+	bp = (char *)&final_data;
+	for (i = 0; i < t.len; i++)
+		tx_buf[i] = bp[3 - i];
+	t.rx_buf = NULL;
+	rc = spi_sync(lcdc_toshiba_spi_client, &m);
+	if (rc)
+		printk(KERN_ERR "spi_sync _write failed %d\n", rc);
+	return rc;
+#else
+	gpio_set_value(spi_cs, 1);	/* cs high */
+
+	/* command byte first */
+	toshiba_spi_write_byte(0, cmd);
+
+	/* followed by parameter bytes */
+	if (num) {
+		bp = (char *)&data;;
+		bp += (num - 1);
+		while (num) {
+			toshiba_spi_write_byte(1, *bp);
+			num--;
+			bp--;
+		}
+	}
+
+	gpio_set_value(spi_cs, 0);	/* cs low */
+	udelay(1);
+	return 0;
+#endif
+}
+
+static int toshiba_spi_read_bytes(char cmd, uint32 *data, int num)
+{
+#ifdef CONFIG_SPI_QSD
+	char            tx_buf[5];
+	char		    rx_buf[5];
+	int                 rc;
+	struct spi_message  m;
+	struct spi_transfer t;
+
+	if (!lcdc_toshiba_spi_client) {
+		printk(KERN_ERR "%s lcdc_toshiba_spi_client is NULL\n",
+			 __func__);
+		return -EINVAL;
+	}
+
+	memset(&t, 0, sizeof t);
+	t.tx_buf = tx_buf;
+	t.rx_buf = rx_buf;
+	spi_setup(lcdc_toshiba_spi_client);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	/* command byte first */
+	tx_buf[0] = 0 | ((cmd >> 1) & 0x7f);
+	tx_buf[1] = (cmd & 0x01) << 7;
+	tx_buf[2] = 0;
+	tx_buf[3] = 0;
+	tx_buf[4] = 0;
+
+	t.len = 5;
+
+	rc = spi_sync(lcdc_toshiba_spi_client, &m);
+	*data = 0;
+	*data = ((rx_buf[1] & 0x1f) << 19) | (rx_buf[2] << 11) |
+		(rx_buf[3] << 3) | ((rx_buf[4] & 0xe0) >> 5);
+	if (rc)
+		printk(KERN_ERR "spi_sync _read failed %d\n", rc);
+	return rc;
+#else
+	uint32 dbit, bits;
+	int bnum;
+
+	gpio_set_value(spi_cs, 1);	/* cs high */
+
+	/* command byte first */
+	toshiba_spi_write_byte(0, cmd);
+
+	if (num > 1) {
+		/* extra dc bit */
+		gpio_set_value(spi_sclk, 0); /* clk low */
+		udelay(1);
+		dbit = gpio_get_value(spi_miso);/* dc bit */
+		udelay(1);
+		gpio_set_value(spi_sclk, 1); /* clk high */
+	}
+
+	/* followed by data bytes */
+	bnum = num * 8;	/* number of bits */
+	bits = 0;
+	while (bnum) {
+		bits <<= 1;
+		gpio_set_value(spi_sclk, 0); /* clk low */
+		udelay(1);
+		dbit = gpio_get_value(spi_miso);
+		udelay(1);
+		gpio_set_value(spi_sclk, 1); /* clk high */
+		bits |= dbit;
+		bnum--;
+	}
+
+	*data = bits;
+
+	udelay(1);
+	gpio_set_value(spi_cs, 0);	/* cs low */
+	udelay(1);
+	return 0;
+#endif
+}
+
+#ifndef CONFIG_SPI_QSD
+static void spi_pin_assign(void)
+{
+	/* Setting the Default GPIO's */
+	spi_sclk = *(lcdc_toshiba_pdata->gpio_num);
+	spi_cs   = *(lcdc_toshiba_pdata->gpio_num + 1);
+	spi_mosi  = *(lcdc_toshiba_pdata->gpio_num + 2);
+	spi_miso  = *(lcdc_toshiba_pdata->gpio_num + 3);
+}
+#endif
+
+static void toshiba_disp_powerup(void)
+{
+	if (!toshiba_state.disp_powered_up && !toshiba_state.display_on) {
+		/* Reset the hardware first */
+		/* Include DAC power up implementation here */
+	      toshiba_state.disp_powered_up = TRUE;
+	}
+}
+
+static void toshiba_disp_on(void)
+{
+	uint32	data;
+
+#ifndef CONFIG_SPI_QSD
+	gpio_set_value(spi_cs, 0);	/* low */
+	gpio_set_value(spi_sclk, 1);	/* high */
+	gpio_set_value(spi_mosi, 0);
+	gpio_set_value(spi_miso, 0);
+#endif
+
+	if (toshiba_state.disp_powered_up && !toshiba_state.display_on) {
+		toshiba_spi_write(0, 0, 0);
+		mdelay(7);
+		toshiba_spi_write(0, 0, 0);
+		mdelay(7);
+		toshiba_spi_write(0, 0, 0);
+		mdelay(7);
+		toshiba_spi_write(0xba, 0x11, 1);
+		toshiba_spi_write(0x36, 0x00, 1);
+		mdelay(1);
+		toshiba_spi_write(0x3a, 0x60, 1);
+		toshiba_spi_write(0xb1, 0x5d, 1);
+		mdelay(1);
+		toshiba_spi_write(0xb2, 0x33, 1);
+		toshiba_spi_write(0xb3, 0x22, 1);
+		mdelay(1);
+		toshiba_spi_write(0xb4, 0x02, 1);
+		toshiba_spi_write(0xb5, 0x1e, 1); /* vcs -- adjust brightness */
+		mdelay(1);
+		toshiba_spi_write(0xb6, 0x27, 1);
+		toshiba_spi_write(0xb7, 0x03, 1);
+		mdelay(1);
+		toshiba_spi_write(0xb9, 0x24, 1);
+		toshiba_spi_write(0xbd, 0xa1, 1);
+		mdelay(1);
+		toshiba_spi_write(0xbb, 0x00, 1);
+		toshiba_spi_write(0xbf, 0x01, 1);
+		mdelay(1);
+		toshiba_spi_write(0xbe, 0x00, 1);
+		toshiba_spi_write(0xc0, 0x11, 1);
+		mdelay(1);
+		toshiba_spi_write(0xc1, 0x11, 1);
+		toshiba_spi_write(0xc2, 0x11, 1);
+		mdelay(1);
+		toshiba_spi_write(0xc3, 0x3232, 2);
+		mdelay(1);
+		toshiba_spi_write(0xc4, 0x3232, 2);
+		mdelay(1);
+		toshiba_spi_write(0xc5, 0x3232, 2);
+		mdelay(1);
+		toshiba_spi_write(0xc6, 0x3232, 2);
+		mdelay(1);
+		toshiba_spi_write(0xc7, 0x6445, 2);
+		mdelay(1);
+		toshiba_spi_write(0xc8, 0x44, 1);
+		toshiba_spi_write(0xc9, 0x52, 1);
+		mdelay(1);
+		toshiba_spi_write(0xca, 0x00, 1);
+		mdelay(1);
+		toshiba_spi_write(0xec, 0x02a4, 2);	/* 0x02a4 */
+		mdelay(1);
+		toshiba_spi_write(0xcf, 0x01, 1);
+		mdelay(1);
+		toshiba_spi_write(0xd0, 0xc003, 2);	/* c003 */
+		mdelay(1);
+		toshiba_spi_write(0xd1, 0x01, 1);
+		mdelay(1);
+		toshiba_spi_write(0xd2, 0x0028, 2);
+		mdelay(1);
+		toshiba_spi_write(0xd3, 0x0028, 2);
+		mdelay(1);
+		toshiba_spi_write(0xd4, 0x26a4, 2);
+		mdelay(1);
+		toshiba_spi_write(0xd5, 0x20, 1);
+		mdelay(1);
+		toshiba_spi_write(0xef, 0x3200, 2);
+		mdelay(32);
+		toshiba_spi_write(0xbc, 0x80, 1);	/* wvga pass through */
+		toshiba_spi_write(0x3b, 0x00, 1);
+		mdelay(1);
+		toshiba_spi_write(0xb0, 0x16, 1);
+		mdelay(1);
+		toshiba_spi_write(0xb8, 0xfff5, 2);
+		mdelay(1);
+		toshiba_spi_write(0x11, 0, 0);
+		mdelay(5);
+		toshiba_spi_write(0x29, 0, 0);
+		mdelay(5);
+		toshiba_state.display_on = TRUE;
+	}
+
+	data = 0;
+	toshiba_spi_read_bytes(0x04, &data, 3);
+	printk(KERN_INFO "toshiba_disp_on: id=%x\n", data);
+
+}
+
+static int lcdc_toshiba_panel_on(struct platform_device *pdev)
+{
+	if (!toshiba_state.disp_initialized) {
+		/* Configure reset GPIO that drives DAC */
+		if (lcdc_toshiba_pdata->panel_config_gpio)
+			lcdc_toshiba_pdata->panel_config_gpio(1);
+		toshiba_disp_powerup();
+		toshiba_disp_on();
+		toshiba_state.disp_initialized = TRUE;
+	}
+	return 0;
+}
+
+static int lcdc_toshiba_panel_off(struct platform_device *pdev)
+{
+	if (toshiba_state.disp_powered_up && toshiba_state.display_on) {
+		/* Main panel power off (Deep standby in) */
+
+		toshiba_spi_write(0x28, 0, 0);	/* display off */
+		mdelay(1);
+		toshiba_spi_write(0xb8, 0x8002, 2);	/* output control */
+		mdelay(1);
+		toshiba_spi_write(0x10, 0x00, 1);	/* sleep mode in */
+		mdelay(85);		/* wait 85 msec */
+		toshiba_spi_write(0xb0, 0x00, 1);	/* deep standby in */
+		mdelay(1);
+		if (lcdc_toshiba_pdata->panel_config_gpio)
+			lcdc_toshiba_pdata->panel_config_gpio(0);
+		toshiba_state.display_on = FALSE;
+		toshiba_state.disp_initialized = FALSE;
+	}
+	return 0;
+}
+
+static void lcdc_toshiba_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int bl_level;
+	int ret = -EPERM;
+	int i = 0;
+
+	bl_level = mfd->bl_level;
+
+	while (i++ < 3) {
+		ret = pmic_set_led_intensity(LED_LCD, bl_level);
+		if (ret == 0)
+			return;
+		msleep(10);
+	}
+
+	printk(KERN_WARNING "%s: can't set lcd backlight!\n",
+				__func__);
+}
+
+static int __devinit toshiba_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		lcdc_toshiba_pdata = pdev->dev.platform_data;
+#ifndef CONFIG_SPI_QSD
+		spi_pin_assign();
+#endif
+		return 0;
+	}
+	msm_fb_add_device(pdev);
+	return 0;
+}
+
+#ifdef CONFIG_SPI_QSD
+static int __devinit lcdc_toshiba_spi_probe(struct spi_device *spi)
+{
+	lcdc_toshiba_spi_client = spi;
+	lcdc_toshiba_spi_client->bits_per_word = 32;
+	return 0;
+}
+static int __devexit lcdc_toshiba_spi_remove(struct spi_device *spi)
+{
+	lcdc_toshiba_spi_client = NULL;
+	return 0;
+}
+
+static struct spi_driver lcdc_toshiba_spi_driver = {
+	.driver = {
+		.name  = LCDC_TOSHIBA_SPI_DEVICE_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe         = lcdc_toshiba_spi_probe,
+	.remove        = __devexit_p(lcdc_toshiba_spi_remove),
+};
+#endif
+static struct platform_driver this_driver = {
+	.probe  = toshiba_probe,
+	.driver = {
+		.name   = "lcdc_toshiba_wvga",
+	},
+};
+
+static struct msm_fb_panel_data toshiba_panel_data = {
+	.on = lcdc_toshiba_panel_on,
+	.off = lcdc_toshiba_panel_off,
+	.set_backlight = lcdc_toshiba_set_backlight,
+};
+
+static struct platform_device this_device = {
+	.name   = "lcdc_toshiba_wvga",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &toshiba_panel_data,
+	}
+};
+
+static int __init lcdc_toshiba_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
+	if (mddi_get_client_id() != 0)
+		return 0;
+
+	ret = msm_fb_detect_client("lcdc_toshiba_wvga_pt");
+	if (ret)
+		return 0;
+
+#endif
+
+	ret = platform_driver_register(&this_driver);
+	if (ret)
+		return ret;
+
+	pinfo = &toshiba_panel_data.panel_info;
+	pinfo->xres = 480;
+	pinfo->yres = 800;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 18;
+	pinfo->fb_num = 2;
+	/* 30Mhz mdp_lcdc_pclk and mdp_lcdc_pad_pcl */
+	pinfo->clk_rate = 30720000;
+	pinfo->bl_max = 15;
+	pinfo->bl_min = 1;
+
+	pinfo->lcdc.h_back_porch = 184;	/* hsw = 8 + hbp=184 */
+	pinfo->lcdc.h_front_porch = 4;
+	pinfo->lcdc.h_pulse_width = 8;
+	pinfo->lcdc.v_back_porch = 2;	/* vsw=1 + vbp = 2 */
+	pinfo->lcdc.v_front_porch = 3;
+	pinfo->lcdc.v_pulse_width = 1;
+	pinfo->lcdc.border_clr = 0;     /* blk */
+	pinfo->lcdc.underflow_clr = 0xff;       /* blue */
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret) {
+		printk(KERN_ERR "%s not able to register the device\n",
+			 __func__);
+		goto fail_driver;
+	}
+#ifdef CONFIG_SPI_QSD
+	ret = spi_register_driver(&lcdc_toshiba_spi_driver);
+
+	if (ret) {
+		printk(KERN_ERR "%s not able to register spi\n", __func__);
+		goto fail_device;
+	}
+#endif
+	return ret;
+
+#ifdef CONFIG_SPI_QSD
+fail_device:
+	platform_device_unregister(&this_device);
+#endif
+fail_driver:
+	platform_driver_unregister(&this_driver);
+	return ret;
+}
+
+device_initcall(lcdc_toshiba_panel_init);
diff --git a/drivers/video/msm/lcdc_wxga.c b/drivers/video/msm/lcdc_wxga.c
new file mode 100644
index 0000000..3204704
--- /dev/null
+++ b/drivers/video/msm/lcdc_wxga.c
@@ -0,0 +1,53 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+
+static int __init lcdc_wxga_init(void)
+{
+	int ret;
+	struct msm_panel_info pinfo;
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	if (msm_fb_detect_client("lcdc_wxga"))
+		return 0;
+#endif
+
+	pinfo.xres = 1280;
+	pinfo.yres = 720;
+	MSM_FB_SINGLE_MODE_PANEL(&pinfo);
+	pinfo.type = LCDC_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.fb_num = 2;
+	pinfo.clk_rate = 74250000;
+
+	pinfo.lcdc.h_back_porch = 124;
+	pinfo.lcdc.h_front_porch = 110;
+	pinfo.lcdc.h_pulse_width = 136;
+	pinfo.lcdc.v_back_porch = 19;
+	pinfo.lcdc.v_front_porch = 5;
+	pinfo.lcdc.v_pulse_width = 6;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+
+	ret = lcdc_device_register(&pinfo);
+	if (ret)
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(lcdc_wxga_init);
diff --git a/drivers/video/msm/logo.c b/drivers/video/msm/logo.c
index ac44ca9..57d754e 100644
--- a/drivers/video/msm/logo.c
+++ b/drivers/video/msm/logo.c
@@ -23,7 +23,6 @@
 
 #include <linux/irq.h>
 #include <asm/system.h>
-#include <mach/debug_display.h>
 
 #define fb_width(fb)	((fb)->var.xres)
 #define fb_height(fb)	((fb)->var.yres)
@@ -38,46 +37,51 @@
 }
 
 /* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
-int load_565rle_image(char *filename)
+int load_565rle_image(char *filename, bool bf_supported)
 {
 	struct fb_info *info;
-	int fd, err = 0;
-	unsigned count, max;
+	int fd, count, err = 0;
+	unsigned max;
 	unsigned short *data, *bits, *ptr;
 
 	info = registered_fb[0];
 	if (!info) {
-		PR_DISP_WARN("%s: Can not access framebuffer\n",
+		printk(KERN_WARNING "%s: Can not access framebuffer\n",
 			__func__);
 		return -ENODEV;
 	}
 
 	fd = sys_open(filename, O_RDONLY, 0);
 	if (fd < 0) {
-		PR_DISP_WARN("%s: Can not open %s\n",
+		printk(KERN_WARNING "%s: Can not open %s\n",
 			__func__, filename);
 		return -ENOENT;
 	}
-	count = (unsigned)sys_lseek(fd, (off_t)0, 2);
-	if (count == 0) {
-		sys_close(fd);
+	count = sys_lseek(fd, (off_t)0, 2);
+	if (count <= 0) {
 		err = -EIO;
 		goto err_logo_close_file;
 	}
 	sys_lseek(fd, (off_t)0, 0);
 	data = kmalloc(count, GFP_KERNEL);
 	if (!data) {
-		PR_DISP_WARN("%s: Can not alloc data\n", __func__);
+		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
 		err = -ENOMEM;
 		goto err_logo_close_file;
 	}
-	if ((unsigned)sys_read(fd, (char *)data, count) != count) {
+	if (sys_read(fd, (char *)data, count) != count) {
 		err = -EIO;
 		goto err_logo_free_data;
 	}
 
 	max = fb_width(info) * fb_height(info);
 	ptr = data;
+	if (bf_supported && (info->node == 1 || info->node == 2)) {
+		err = -EPERM;
+		pr_err("%s:%d no info->creen_base on fb%d!\n",
+		       __func__, __LINE__, info->node);
+		goto err_logo_free_data;
+	}
 	bits = (unsigned short *)(info->screen_base);
 	while (count > 3) {
 		unsigned n = ptr[0];
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index 7a6cf38..1154913 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -2,7 +2,7 @@
  * MSM MDDI Transport
  *
  * Copyright (C) 2007 Google Incorporated
- * Copyright (C) 2007 QUALCOMM Incorporated
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -10,1199 +10,581 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/clk.h>
-#include <linux/io.h>
 #include <linux/sched.h>
-#include <mach/msm_iomap.h>
-#include <mach/irqs.h>
-#include <mach/board.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
 #include <linux/delay.h>
-#include <linux/earlysuspend.h>
-#include <linux/wakelock.h>
-#include <linux/debugfs.h>
-#include <asm/uaccess.h>
-#include <mach/msm_fb.h>
-#include <mach/debug_display.h>
-#include "mddi_hw.h"
+#include <mach/hardware.h>
+#include <asm/io.h>
 
-#define FLAG_DISABLE_HIBERNATION 0x0001
-#define FLAG_HAVE_CAPS		 0x0002
-#define FLAG_HAS_VSYNC_IRQ	 0x0004
-#define FLAG_HAVE_STATUS	 0x0008
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include "msm_fb.h"
+#include "mddihosti.h"
+#include "mddihost.h"
+#include <mach/gpio.h>
+#include <mach/clk.h>
 
-#define CMD_GET_CLIENT_CAP     0x0601
-#define CMD_GET_CLIENT_STATUS  0x0602
+static int mddi_probe(struct platform_device *pdev);
+static int mddi_remove(struct platform_device *pdev);
 
-static uint32_t mddi_debug_flags;
-#ifdef CONFIG_MSM_MDP40
-static struct clk *mdp_clk;
+static int mddi_off(struct platform_device *pdev);
+static int mddi_on(struct platform_device *pdev);
+
+#ifdef CONFIG_PM
+static int mddi_suspend(struct platform_device *pdev, pm_message_t state);
+static int mddi_resume(struct platform_device *pdev);
 #endif
-#ifdef CONFIG_MDP4_HW_VSYNC
-static struct clk *mdp_vsync_clk;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mddi_early_suspend(struct early_suspend *h);
+static void mddi_early_resume(struct early_suspend *h);
 #endif
-union mddi_rev {
-	unsigned char raw[MDDI_REV_BUFFER_SIZE];
-	struct mddi_rev_packet hdr;
-	struct mddi_client_status status;
-	struct mddi_client_caps caps;
-	struct mddi_register_access reg;
+
+static void pmdh_clk_disable(void);
+static void pmdh_clk_enable(void);
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+static struct clk *mddi_clk;
+static struct clk *mddi_pclk;
+static struct mddi_platform_data *mddi_pdata;
+
+DEFINE_MUTEX(mddi_timer_lock);
+
+static int mddi_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int mddi_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+
+static int mddi_runtime_idle(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: idling...\n");
+	return 0;
+}
+
+static struct dev_pm_ops mddi_dev_pm_ops = {
+	.runtime_suspend = mddi_runtime_suspend,
+	.runtime_resume = mddi_runtime_resume,
+	.runtime_idle = mddi_runtime_idle,
 };
 
-struct reg_read_info {
-	struct completion done;
-	uint32_t reg;
-	uint32_t status;
-	uint32_t result;
-};
-
-struct mddi_info {
-	uint16_t flags;
-	uint16_t version;
-	char __iomem *base;
-	int irq;
-	struct clk *clk;
-	struct msm_mddi_client_data client_data;
-
-	/* buffer for rev encap packets */
-	void *rev_data;
-	dma_addr_t rev_addr;
-	struct mddi_llentry *reg_write_data;
-	dma_addr_t reg_write_addr;
-	struct mddi_llentry *reg_read_data;
-	dma_addr_t reg_read_addr;
-	size_t rev_data_curr;
-
-	spinlock_t int_lock;
-	uint32_t int_enable;
-	uint32_t got_int;
-	wait_queue_head_t int_wait;
-
-	struct mutex reg_write_lock;
-	struct mutex reg_read_lock;
-	struct reg_read_info *reg_read;
-
-	struct mddi_client_caps caps;
-	struct mddi_client_status status;
-
-	struct wake_lock idle_lock;
-	struct wake_lock link_active_idle_lock;
-
-	void (*power_client)(struct msm_mddi_client_data *, int);
-
-	/* client device published to bind us to the
-	 * appropriate mddi_client driver
-	 */
-	char client_name[20];
-
-	struct platform_device client_pdev;
-	unsigned type;
-	char debugfs_buf[32];
-};
-
-static void mddi_init_rev_encap(struct mddi_info *mddi);
-/* FIXME: Workaround for Novatek
-static void mddi_skew_calibration(struct mddi_info *mddi);
-*/
-
-#define mddi_readl(r) readl(mddi->base + (MDDI_##r))
-#define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r))
-
-void mddi_activate_link(struct msm_mddi_client_data *cdata)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	wake_lock(&mddi->link_active_idle_lock);
-	mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
-}
-
-static void mddi_handle_link_list_done(struct mddi_info *mddi)
-{
-}
-
-static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi)
-{
-	PR_DISP_INFO("mddi: resetting rev ptr\n");
-	mddi->rev_data_curr = 0;
-	mddi_writel(mddi->rev_addr, REV_PTR);
-	mddi_writel(mddi->rev_addr, REV_PTR);
-	mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
-}
-
-static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev)
-{
-	int i;
-	struct reg_read_info *ri;
-
-	if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) &&
-	   (rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) {
-		/* PR_DISP_INFO("rev: len=%04x type=%04x\n",
-		 * rev->hdr.length, rev->hdr.type); */
-
-		switch (rev->hdr.type) {
-		case TYPE_CLIENT_CAPS:
-			memcpy(&mddi->caps, &rev->caps,
-			       sizeof(struct mddi_client_caps));
-			mddi->flags |= FLAG_HAVE_CAPS;
-			wake_up(&mddi->int_wait);
-			break;
-		case TYPE_CLIENT_STATUS:
-			memcpy(&mddi->status, &rev->status,
-			       sizeof(struct mddi_client_status));
-			mddi->flags |= FLAG_HAVE_STATUS;
-			wake_up(&mddi->int_wait);
-			break;
-		case TYPE_REGISTER_ACCESS:
-			/* PR_DISP_INFO("rev: reg %x = %x\n",
-			 * rev->reg.register_address,
-			 * rev->reg.register_data_list); */
-			ri = mddi->reg_read;
-			if (ri == 0) {
-				PR_DISP_INFO("rev: got reg %x = %x without "
-						 " pending read\n",
-				       rev->reg.register_address,
-				       rev->reg.u.reg_data);
-				break;
-			}
-			if (ri->reg != rev->reg.register_address) {
-				PR_DISP_INFO("rev: got reg %x = %x for "
-						 "wrong register, expected "
-						 "%x\n",
-				       rev->reg.register_address,
-				       rev->reg.u.reg_data, ri->reg);
-				break;
-			}
-			mddi->reg_read = NULL;
-			ri->status = 0;
-			ri->result = rev->reg.u.reg_data;
-			complete(&ri->done);
-			break;
-		default:
-			PR_DISP_INFO("rev: unknown reverse packet: "
-					 "len=%04x type=%04x CURR_REV_PTR=%x\n",
-			       rev->hdr.length, rev->hdr.type,
-			       mddi_readl(CURR_REV_PTR));
-			for (i = 0; i < rev->hdr.length + 2; i++) {
-				if ((i % 16) == 0)
-					PR_DISP_INFO("\n");
-				PR_DISP_INFO(" %02x", rev->raw[i]);
-			}
-			PR_DISP_INFO("\n");
-			mddi_reset_rev_encap_ptr(mddi);
-		}
-	} else {
-		PR_DISP_INFO("bad rev length, %d, CURR_REV_PTR %x\n",
-		       rev->hdr.length, mddi_readl(CURR_REV_PTR));
-		mddi_reset_rev_encap_ptr(mddi);
-	}
-}
-
-static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
-
-static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
-{
-	union mddi_rev *rev = mddi->rev_data;
-	uint32_t rev_data_count;
-	uint32_t rev_crc_err_count;
-	int i;
-	struct reg_read_info *ri;
-	size_t prev_offset;
-	uint16_t length;
-
-	union mddi_rev *crev = mddi->rev_data + mddi->rev_data_curr;
-
-	/* clear the interrupt */
-	mddi_writel(MDDI_INT_REV_DATA_AVAIL, INT);
-	rev_data_count = mddi_readl(REV_PKT_CNT);
-	rev_crc_err_count = mddi_readl(REV_CRC_ERR);
-	if (rev_data_count > 1)
-		PR_DISP_INFO("rev_data_count %d\n", rev_data_count);
-	/* PR_DISP_INFO("rev_data_count %d, INT %x\n", rev_data_count,
-	 * mddi_readl(INT)); */
-
-	if (rev_crc_err_count) {
-		PR_DISP_INFO("rev_crc_err_count %d, INT %x\n",
-		       rev_crc_err_count,  mddi_readl(INT));
-		ri = mddi->reg_read;
-		if (ri == 0) {
-			PR_DISP_INFO("rev: got crc error without pending "
-			       "read\n");
-		} else {
-			mddi->reg_read = NULL;
-			ri->status = -EIO;
-			ri->result = -1;
-			complete(&ri->done);
-		}
-	}
-
-	if (rev_data_count == 0)
-		return;
-
-	if (mddi_debug_flags & 1) {
-		PR_DISP_INFO("INT %x, STAT %x, CURR_REV_PTR %x\n",
-		       mddi_readl(INT), mddi_readl(STAT),
-		       mddi_readl(CURR_REV_PTR));
-		for (i = 0; i < MDDI_REV_BUFFER_SIZE; i++) {
-			if ((i % 16) == 0)
-				PR_DISP_INFO("\n");
-			PR_DISP_INFO(" %02x", rev->raw[i]);
-		}
-		PR_DISP_INFO("\n");
-	}
-
-	/* PR_DISP_INFO("rev_data_curr %d + %d\n", mddi->rev_data_curr,
-	 * crev->hdr.length); */
-	prev_offset = mddi->rev_data_curr;
-
-	length = *((uint8_t *)mddi->rev_data + mddi->rev_data_curr);
-	mddi->rev_data_curr++;
-	if (mddi->rev_data_curr == MDDI_REV_BUFFER_SIZE)
-		mddi->rev_data_curr = 0;
-	length += *((uint8_t *)mddi->rev_data + mddi->rev_data_curr) << 8;
-	mddi->rev_data_curr += 1 + length;
-	if (mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE)
-		mddi->rev_data_curr =
-			mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE;
-
-	if (length > MDDI_REV_BUFFER_SIZE - 2) {
-		PR_DISP_INFO("mddi: rev data length greater than buffer"
-			"size\n");
-		mddi_reset_rev_encap_ptr(mddi);
-		return;
-	}
-
-	if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) {
-		union mddi_rev tmprev;
-		size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset;
-		memcpy(&tmprev.raw[0], mddi->rev_data + prev_offset, rem);
-		memcpy(&tmprev.raw[rem], mddi->rev_data, 2 + length - rem);
-		mddi_handle_rev_data(mddi, &tmprev);
-		if (mddi_debug_flags & 2) {
-			memset(mddi->rev_data + prev_offset, 0xee, rem);
-			memset(mddi->rev_data, 0xee, mddi->rev_data_curr);
-		}
-	} else {
-		mddi_handle_rev_data(mddi, crev);
-		if (mddi_debug_flags & 2)
-			memset(mddi->rev_data + prev_offset, 0xee,
-			       mddi->rev_data_curr - prev_offset);
-	}
-
-	/* if(mddi->rev_data_curr + MDDI_MAX_REV_PKT_SIZE >=
-	 * MDDI_REV_BUFFER_SIZE) { */
-	if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 &&
-	    mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) {
-		/* PR_DISP_INFO("passed buffer half full: rev_data_curr
-		 * %d\n", mddi->rev_data_curr); */
-		mddi_writel(mddi->rev_addr, REV_PTR);
-	}
-}
-
-static irqreturn_t mddi_isr(int irq, void *data)
-{
-	struct msm_mddi_client_data *cdata = data;
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	uint32_t active, status;
-
-	spin_lock(&mddi->int_lock);
-
-	active = mddi_readl(INT);
-	status = mddi_readl(STAT);
-
-	mddi_writel(active, INT);
-
-	/* PR_DISP_INFO("%s: isr a=%08x e=%08x s=%08x\n",
-		mddi->name, active, mddi->int_enable, status); */
-
-	/* ignore any interrupts we have disabled */
-	active &= mddi->int_enable;
-
-	mddi->got_int |= active;
-	wake_up(&mddi->int_wait);
-
-	if (active & MDDI_INT_PRI_LINK_LIST_DONE) {
-		mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE);
-		mddi_handle_link_list_done(mddi);
-	}
-	if (active & MDDI_INT_REV_DATA_AVAIL)
-		mddi_handle_rev_data_avail(mddi);
-
-	if (active & ~MDDI_INT_NEED_CLEAR)
-		mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR);
-
-	if (active & MDDI_INT_LINK_ACTIVE) {
-		mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE);
-		mddi->int_enable |= MDDI_INT_IN_HIBERNATION;
-		wake_lock(&mddi->link_active_idle_lock);
-	}
-
-	if (active & MDDI_INT_IN_HIBERNATION) {
-		mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION);
-		mddi->int_enable |= MDDI_INT_LINK_ACTIVE;
-		wake_unlock(&mddi->link_active_idle_lock);
-	}
-
-	mddi_writel(mddi->int_enable, INTEN);
-	spin_unlock(&mddi->int_lock);
-
-	return IRQ_HANDLED;
-}
-
-static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
-					uint32_t intmask, int timeout)
-{
-	unsigned long irq_flags = 0;
-
-	spin_lock_irqsave(&mddi->int_lock, irq_flags);
-	mddi->got_int &= ~intmask;
-	mddi->int_enable |= intmask;
-	mddi_writel(mddi->int_enable, INTEN);
-	spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
-	return wait_event_timeout(mddi->int_wait, mddi->got_int & intmask,
-				  timeout);
-}
-
-static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
-{
-	if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
-		printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout "
-		       "waiting for %x, INT = %x, STAT = %x gotint = %x\n",
-		       current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
-		       mddi->got_int);
-}
-
-static void mddi_init_rev_encap(struct mddi_info *mddi)
-{
-	memset(mddi->rev_data, 0xee, MDDI_REV_BUFFER_SIZE);
-	mddi_writel(mddi->rev_addr, REV_PTR);
-	mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-}
-
-void mddi_set_auto_hibernate(struct msm_mddi_client_data *cdata, int on)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	mddi_writel(MDDI_CMD_POWERDOWN, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION);
-	mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-}
-
-
-static uint16_t mddi_init_registers(struct mddi_info *mddi)
-{
-#ifdef CONFIG_MACH_MARVEL
-	mddi_writel(0x0000, VERSION);
-#else
-	mddi_writel(0x0001, VERSION);
-#endif
-
-	mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
-	mddi_writel(0x0003, SPM); /* subframes per media */
-	if (mddi->type == MSM_MDP_MDDI_TYPE_II)
-		mddi_writel(0x00C8, TA1_LEN);
-	else
-		mddi_writel(0x0005, TA1_LEN);
-	mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
-	mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
-	mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);
-	if (mddi->type == MSM_MDP_MDDI_TYPE_II)
-		mddi_writel(0x01, SF_LEN_CTL_REG);
-
-	mddi_writel(MDDI_REV_BUFFER_SIZE, REV_SIZE);
-	mddi_writel(MDDI_MAX_REV_PKT_SIZE, REV_ENCAP_SZ);
-
-	/* disable periodic rev encap */
-	mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-
-	if (mddi_readl(PAD_CTL) == 0) {
-		/* If we are turning on band gap, need to wait 5us before
-		 * turning on the rest of the PAD */
-		mddi_writel(0x08000, PAD_CTL);
-		udelay(5);
-	}
-
-	/* Recommendation from PAD hw team */
-	if (mddi->type == MSM_MDP_MDDI_TYPE_II)
-		mddi_writel(0x402a850f, PAD_CTL);
-	else
-		mddi_writel(0xa850f, PAD_CTL);
-
-#if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM7X30)
-	/* Only for novatek driver IC*/
-	mddi_writel(0x00C8, DRIVE_HI);
-	/* 0x32 normal, 0x50 for Toshiba display */
-	mddi_writel(0x0050, DRIVE_LO);
-	mddi_writel(0x00320000, PAD_IO_CTL);
-	if (mddi->type == MSM_MDP_MDDI_TYPE_II)
-		mddi_writel(0x40884020, PAD_CAL);
-	else
-		mddi_writel(0x00220020, PAD_CAL);
-#else
-	mddi_writel(0x0096, DRIVE_HI);
-	/* 0x32 normal, 0x50 for Toshiba display */
-	mddi_writel(0x0050, DRIVE_LO);
-#endif
-
-	/* Need an even number for counts */
-	mddi_writel(0x60006, DRIVER_START_CNT);
-
-	mddi_set_auto_hibernate(&mddi->client_data, 0);
-
-#if 1 /* ignore listen */
-	mddi_writel(MDDI_CMD_DISP_IGNORE, CMD);
-#else
-	mddi_writel(MDDI_CMD_DISP_LISTEN, CMD);
-#endif
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-
-	mddi_init_rev_encap(mddi);
-	return mddi_readl(CORE_VER) & 0xffff;
-}
-
-static void mddi_suspend(struct msm_mddi_client_data *cdata)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	wake_lock(&mddi->idle_lock);
-	/* turn off the client */
-	if (mddi->power_client)
-		mddi->power_client(&mddi->client_data, 0);
-	/* turn off the link */
-	mddi_writel(MDDI_CMD_RESET, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-	/* turn off the clock */
-	clk_disable(mddi->clk);
-#ifdef CONFIG_MDP4_HW_VSYNC
-	clk_disable(mdp_vsync_clk);
-#endif
-#ifdef CONFIG_MSM_MDP40
-	clk_disable(mdp_clk);
-#endif
-	wake_unlock(&mddi->idle_lock);
-}
-
-static void mddi_resume(struct msm_mddi_client_data *cdata)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	wake_lock(&mddi->idle_lock);
-	if (mddi->type == MSM_MDP_MDDI_TYPE_I)
-		mddi_set_auto_hibernate(&mddi->client_data, 0);
-	/* turn on the client */
-	if (mddi->power_client)
-		mddi->power_client(&mddi->client_data, 1);
-#ifdef CONFIG_MSM_MDP40
-	clk_enable(mdp_clk);
-#endif
-#ifdef CONFIG_MDP4_HW_VSYNC
-	clk_enable(mdp_vsync_clk);
-#endif
-	/* turn on the clock */
-	clk_enable(mddi->clk);
-	/* set up the local registers */
-	mddi->rev_data_curr = 0;
-	mddi_init_registers(mddi);
-/*	FIXME: Workaround for Novatek
-	if (mddi->type == MSM_MDP_MDDI_TYPE_II)
-		mddi_skew_calibration(mddi);
-*/
-	mddi_writel(mddi->int_enable, INTEN);
-	mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
-	if (mddi->type == MSM_MDP_MDDI_TYPE_I)
-		mddi_writel(MDDI_CMD_SEND_RTD, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-	if (mddi->type == MSM_MDP_MDDI_TYPE_I)
-		mddi_set_auto_hibernate(&mddi->client_data, 1);
-	wake_unlock(&mddi->idle_lock);
-}
-
-static int __init mddi_get_client_caps(struct mddi_info *mddi)
-{
-#if !defined(CONFIG_ARCH_MSM7X30)
-	int i, j;
-#endif
-	/* clear any stale interrupts */
-	mddi_writel(0xffffffff, INT);
-	mddi->int_enable = MDDI_INT_LINK_ACTIVE |
-			   MDDI_INT_IN_HIBERNATION |
-			   MDDI_INT_PRI_LINK_LIST_DONE |
-			   MDDI_INT_REV_DATA_AVAIL |
-			   MDDI_INT_REV_OVERFLOW |
-			   MDDI_INT_REV_OVERWRITE |
-			   MDDI_INT_RTD_FAILURE;
-	mddi_writel(mddi->int_enable, INTEN);
-
-	mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-	/*FIXME: mddi host can't get caps on MDDI type 2*/
-#if !defined(CONFIG_ARCH_MSM7X30)
-	if (mddi->type == MSM_MDP_MDDI_TYPE_I) {
-		for (j = 0; j < 3; j++) {
-			/* the toshiba vga panel does not respond to get
-			 * caps unless you SEND_RTD, but the first SEND_RTD
-			 * will fail...
-			 */
-			for (i = 0; i < 4; i++) {
-				uint32_t stat;
-
-				mddi_writel(MDDI_CMD_SEND_RTD, CMD);
-				mdelay(1);
-				mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-				stat = mddi_readl(STAT);
-				PR_DISP_INFO("mddi cmd send rtd: int %x, stat %x, "
-						"rtd val %x\n", mddi_readl(INT), stat,
-						mddi_readl(RTD_VAL));
-				if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0) {
-					mdelay(1);
-					break;
-				}
-				msleep(1);
-			}
-
-			mddi_writel(CMD_GET_CLIENT_CAP, CMD);
-			mdelay(1);
-			mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-			wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS,
-				   HZ / 100);
-
-			if (mddi->flags & FLAG_HAVE_CAPS)
-				break;
-			printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for "
-				"caps\n");
-		}
-		return (mddi->flags & FLAG_HAVE_CAPS);
-	} else
-		return 1;
-#endif
-		return 1;
-}
-
-/* link must be active when this is called */
-int mddi_check_status(struct mddi_info *mddi)
-{
-	int ret = -1, retry = 3;
-	mutex_lock(&mddi->reg_read_lock);
-	mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-
-	do {
-		mddi->flags &= ~FLAG_HAVE_STATUS;
-		mddi_writel(CMD_GET_CLIENT_STATUS, CMD);
-		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-		wait_event_timeout(mddi->int_wait,
-				   mddi->flags & FLAG_HAVE_STATUS,
-				   HZ / 100);
-
-		if (mddi->flags & FLAG_HAVE_STATUS) {
-			if (mddi->status.crc_error_count)
-				PR_DISP_INFO("mddi status: crc_error "
-					"count: %d\n",
-					mddi->status.crc_error_count);
-			else
-				ret = 0;
-			break;
-		} else
-			PR_DISP_INFO("mddi status: failed to get client "
-				"status\n");
-		mddi_writel(MDDI_CMD_SEND_RTD, CMD);
-		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-	} while (--retry);
-
-	mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-	mutex_unlock(&mddi->reg_read_lock);
-	return ret;
-}
-
-
-/*
- * mddi_remote_write_vals - send the register access packet
- *
- * @cdata: mddi layer dedicated structure, holding info needed by mddi
- * @val  : parameters
- * @reg  : cmd
- * @nr_bytes: size of parameters in bytes
- *
- * jay, Nov 13, 08'
- * extend the single parameter to multiple.
- */
-static void _mddi_remote_write_vals(struct msm_mddi_client_data *cdata, uint8_t *val,
-			uint32_t reg, unsigned int nr_bytes)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	struct mddi_llentry *ll;
-	struct mddi_register_access *ra;
-	dma_addr_t bus_addr = 0;
-
-	mutex_lock(&mddi->reg_write_lock);
-
-	ll = mddi->reg_write_data;
-
-	ra = &(ll->u.r);
-	ra->length = 14 + nr_bytes;
-	ra->type = TYPE_REGISTER_ACCESS;
-	ra->client_id = 0;
-	ra->read_write_info = MDDI_WRITE | (nr_bytes / 4);
-	ra->crc16 = 0;
-
-	ra->register_address = reg;
-
-	ll->flags = 1;
-	/* register access packet header occupies 14 bytes */
-	ll->header_count = 14;
-	ll->data_count = nr_bytes; /* num of bytes in the data field */
-
-	if (nr_bytes == 4) {
-		uint32_t *prm = (uint32_t *)val;
-
-		ll->data = mddi->reg_write_addr +
-			offsetof(struct mddi_llentry, u.r.u.reg_data);
-		ra->u.reg_data = *prm;
-	} else {
-		int dma_retry = 5;
-
-		while (dma_retry--) {
-			bus_addr = dma_map_single(NULL, (void *)val, nr_bytes,
-					DMA_TO_DEVICE);
-			if (dma_mapping_error(NULL, bus_addr) == 0)
-				break;
-			msleep(1);
-		}
-		if (dma_retry == 0) {
-			PR_DISP_ERR("%s: dma map fail!\n", __func__);
-			mutex_unlock(&mddi->reg_write_lock);
-			return;
-		}
-
-		ll->data = bus_addr;
-		ra->u.reg_data_list = (uint32_t *)bus_addr;
-	}
-	ll->next = 0;
-	ll->reserved = 0;
-
-	/* inform mddi to start */
-	mddi_writel(mddi->reg_write_addr, PRI_PTR);
-	mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
-	if (bus_addr)
-		dma_unmap_single(NULL, bus_addr, nr_bytes, DMA_TO_DEVICE);
-	mutex_unlock(&mddi->reg_write_lock);
-}
-
-void mddi_remote_write_vals(struct msm_mddi_client_data *cdata, uint8_t *val,
-			uint32_t reg, unsigned int nr_bytes)
-{
-	int sem_owned = overlay_semaphore_lock();
-	_mddi_remote_write_vals(cdata, val, reg, nr_bytes);
-	if (sem_owned == 0)
-		overlay_semaphore_unlock();
-}
-
-void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val,
-			uint32_t reg)
-{
-	uint8_t *p = (uint8_t *)&val;
-	mddi_remote_write_vals(cdata, p, reg, 4);
-}
-
-static uint32_t _mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	struct mddi_llentry *ll;
-	struct mddi_register_access *ra;
-	struct reg_read_info ri;
-	unsigned s;
-	int retry_count = 2;
-	unsigned long irq_flags = 0;
-
-	mutex_lock(&mddi->reg_read_lock);
-
-	ll = mddi->reg_read_data;
-
-	ra = &(ll->u.r);
-	ra->length = 14;
-	ra->type = TYPE_REGISTER_ACCESS;
-	ra->client_id = 0;
-	ra->read_write_info = MDDI_READ | 1;
-	ra->crc16 = 0;
-
-	ra->register_address = reg;
-
-	ll->flags = 0x11;
-	ll->header_count = 14;
-	ll->data_count = 0;
-	ll->data = 0;
-	ll->next = 0;
-	ll->reserved = 0;
-
-	s = mddi_readl(STAT);
-	/* PR_DISP_INFO("mddi_remote_read(%x), stat = %x\n", reg, s); */
-
-	ri.reg = reg;
-	ri.status = -1;
-	ri.result = -1;
-
-	do {
-		init_completion(&ri.done);
-		mddi->reg_read = &ri;
-		mddi_writel(mddi->reg_read_addr, PRI_PTR);
-
-		mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
-		/* s = mddi_readl(STAT); */
-		/* PR_DISP_INFO("mddi_remote_read(%x) sent, stat = %x\n",
-		 * reg, s); */
-
-		/* s = mddi_readl(STAT); */
-		/* while((s & MDDI_STAT_PRI_LINK_LIST_DONE) == 0){ */
-		/*	s = mddi_readl(STAT); */
-		/* } */
-
-		/* Enable Periodic Reverse Encapsulation. */
-		mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
-		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-		if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 &&
-		    !ri.done.done) {
-			PR_DISP_INFO("mddi_remote_read(%x) timeout "
-					 "(%d %d %d)\n",
-			       reg, ri.status, ri.result, ri.done.done);
-			spin_lock_irqsave(&mddi->int_lock, irq_flags);
-			mddi->reg_read = NULL;
-			spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
-			ri.status = -1;
-			ri.result = -1;
-		}
-		if (ri.status == 0)
-			break;
-
-		/* PR_DISP_INFO("mddi_remote_read: failed, sent
-		 * MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x\n",
-		 * mddi_readl(INT), mddi_readl(STAT), mddi_readl(RTD_VAL)); */
-		mddi_writel(MDDI_CMD_SEND_RTD, CMD);
-		mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
-		/* PR_DISP_INFO("mddi_remote_read: failed, sent
-		 * MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x\n",
-		 * mddi_readl(INT), mddi_readl(STAT), mddi_readl(RTD_VAL)); */
-		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-		PR_DISP_INFO("mddi_remote_read: failed, sent "
-		       "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x "
-		       "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT),
-		       mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR));
-	} while (retry_count-- > 0);
-	/* Disable Periodic Reverse Encapsulation. */
-	mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-	/* PR_DISP_INFO("mddi_remote_read(%x) done, stat = %x,
-	 * return %x\n", reg, s, ri.result); */
-	mddi->reg_read = NULL;
-	mutex_unlock(&mddi->reg_read_lock);
-	return ri.result;
-}
-
-uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
-{
-	uint32_t rtn_value;
-
-	int sem_owned = overlay_semaphore_lock();
-	rtn_value = _mddi_remote_read(cdata, reg);
-	if (sem_owned == 0)
-		overlay_semaphore_unlock();
-
-	return rtn_value;
-}
-
-/*FIXME: workaround for Novatek*/
-void mddi_send_powerdown(struct msm_mddi_client_data *cdata)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-
-	mddi_writel(MDDI_CMD_POWERDOWN, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION);
-}
-
-
-static struct mddi_info mddi_info[2];
-
-static int __init mddi_clk_setup(struct platform_device *pdev,
-				 struct mddi_info *mddi,
-				 unsigned long clk_rate)
-{
-	int ret;
-#ifdef CONFIG_MSM_MDP40
-	mdp_clk = clk_get(&pdev->dev, "mdp_clk");
-	if (IS_ERR(mdp_clk)) {
-		PR_DISP_INFO("mddi: failed to get mdp clk");
-		return PTR_ERR(mdp_clk);
-	}
-	ret =  clk_enable(mdp_clk);
-	if (ret)
-		goto fail;
-#endif
-#ifdef CONFIG_MDP4_HW_VSYNC
-	mdp_vsync_clk = clk_get(&pdev->dev, "mdp_vsync_clk");
-	if (IS_ERR(mdp_vsync_clk)) {
-		PR_DISP_INFO("mddi: failed to get mdp_vsync_clk");
-		return PTR_ERR(mdp_vsync_clk);
-	}
-	ret =  clk_enable(mdp_vsync_clk);
-	if (ret)
-		goto fail;
-#endif
-	/* set up the clocks */
-	mddi->clk = clk_get(&pdev->dev, "mddi_clk");
-	if (IS_ERR(mddi->clk)) {
-		PR_DISP_INFO("mddi: failed to get clock\n");
-		return PTR_ERR(mddi->clk);
-	}
-	ret =  clk_enable(mddi->clk);
-	if (ret)
-		goto fail;
-	ret = clk_set_rate(mddi->clk, clk_rate);
-	if (ret)
-		goto fail;
-	PR_DISP_DEBUG("mddi runs at %ld\n", clk_get_rate(mddi->clk));
-	return 0;
-
-fail:
-	clk_put(mddi->clk);
-	return ret;
-}
-
-static int __init mddi_rev_data_setup(struct mddi_info *mddi)
-{
-	void *dma;
-	dma_addr_t dma_addr;
-
-	/* set up dma buffer */
-	dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL);
-	if (dma == 0)
-		return -ENOMEM;
-	mddi->rev_data = dma;
-	mddi->rev_data_curr = 0;
-	mddi->rev_addr = dma_addr;
-	mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE;
-	mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE;
-	mddi->reg_read_data = mddi->reg_write_data + 1;
-	mddi->reg_read_addr = mddi->reg_write_addr +
-			      sizeof(*mddi->reg_write_data);
-	return 0;
-}
-/*	FIXME: Workaround for Novatek
-static void mddi_skew_calibration(struct mddi_info *mddi)
-{
-	struct msm_mddi_platform_data *pdata = mddi->client_pdev.dev.platform_data;
-
-	clk_set_rate( mddi->clk, 50000000);
-	mdelay(1);
-	mddi_writel(MDDI_CMD_SKEW_CALIBRATION, CMD);
-	mdelay(1);
-	clk_set_rate( mddi->clk, pdata->clk_rate);
-	mdelay(1);
-}
-*/
-
-static ssize_t mddi_reg_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t mddi_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
-{
-	struct mddi_info *mddi = (struct mddi_info *)file->private_data;
-
-	return simple_read_from_buffer(user_buf, count, ppos, mddi->debugfs_buf, strlen(mddi->debugfs_buf));
-}
-
-static ssize_t mddi_reg_write(struct file *file, const char __user *user_buf,
-		size_t count, loff_t *ppos)
-{
-	unsigned int reg, data;
-	char debug_buf[32], type;
-	int cnt, len;
-	struct mddi_info *mddi = file->private_data;
-
-	memset(debug_buf, 0x00, sizeof(debug_buf));
-
-	if (count >= sizeof(debug_buf))
-			return -EFAULT;
-
-	if (copy_from_user(debug_buf, user_buf, count))
-			return -EFAULT;
-
-	debug_buf[count] = 0;   /* end of string */
-
-	if (debug_buf[0] == 'w') {
-		cnt = sscanf(debug_buf, "%c %x %x", &type, &reg, &data);
-		mddi_set_auto_hibernate(&mddi->client_data, 0);
-		mddi_remote_write(&mddi->client_data, data, reg);
-		mddi_set_auto_hibernate(&mddi->client_data, 1);
-
-		len = snprintf(mddi->debugfs_buf, sizeof(mddi->debugfs_buf),
-			 "[W] reg=0x%x val=0x%x\n", reg, data);
-		PR_DISP_INFO("%s: reg=%x val=%x\n", __func__, reg, data);
-	} else {
-		cnt = sscanf(debug_buf, "%c %x", &type, &reg);
-
-		len = snprintf(mddi->debugfs_buf, sizeof(mddi->debugfs_buf),
-			 "[R] reg=0x%x val=0x%x\n", reg,
-			mddi_remote_read(&mddi->client_data, reg));
-
-		PR_DISP_INFO("%s: reg=%x val=%x buf=%s\n", __func__, reg,
-		mddi_remote_read(&mddi->client_data, reg), debug_buf);
-	}
-
-	return count;
-}
-
-static struct file_operations mddi_reg_debugfs_fops[] = {
-	{
-		.open  = mddi_reg_open,
-		.read = mddi_reg_read,
-		.write = mddi_reg_write,
-	}
-};
-
-int mddi_reg_debugfs_init(struct mddi_info *mddi)
-{
-	struct dentry *mddi_reg_dent;
-
-	mddi_reg_dent = debugfs_create_dir("mddi", 0);
-	if (IS_ERR(mddi_reg_dent))
-			return PTR_ERR(mddi_reg_dent);
-
-	debugfs_create_file("reg", 0600, mddi_reg_dent, mddi,
-			&mddi_reg_debugfs_fops[0]);
-
-	return 0;
-}
-
-static int mddi_probe(struct platform_device *pdev)
-{
-	struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
-	struct mddi_info *mddi = &mddi_info[pdev->id];
-	struct resource *resource;
-	int ret, i;
-
-	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!resource) {
-		PR_DISP_ERR("mddi: no associated mem resource!\n");
-		return -ENOMEM;
-	}
-	mddi->base = ioremap(resource->start, resource->end - resource->start);
-	if (!mddi->base) {
-		PR_DISP_ERR("mddi: failed to remap base!\n");
-		ret = -EINVAL;
-		goto error_ioremap;
-	}
-	resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!resource) {
-		PR_DISP_ERR("mddi: no associated irq resource!\n");
-		ret = -EINVAL;
-		goto error_get_irq_resource;
-	}
-	mddi->irq = resource->start;
-	PR_DISP_INFO("mddi: init() base=0x%p irq=%d\n", mddi->base,
-	       mddi->irq);
-	mddi->power_client = pdata->power_client;
-	if (pdata->type != MSM_MDP_MDDI_TYPE_I)
-		mddi->type = pdata->type;
-
-	mutex_init(&mddi->reg_write_lock);
-	mutex_init(&mddi->reg_read_lock);
-	spin_lock_init(&mddi->int_lock);
-	init_waitqueue_head(&mddi->int_wait);
-
-	wake_lock_init(&mddi->idle_lock, WAKE_LOCK_IDLE, "mddi_idle_lock");
-	wake_lock_init(&mddi->link_active_idle_lock, WAKE_LOCK_IDLE,
-		       "mddi_link_active_idle_lock");
-
-	ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate);
-	if (ret) {
-		PR_DISP_ERR("mddi: failed to setup clock!\n");
-		goto error_clk_setup;
-	}
-
-	ret = mddi_rev_data_setup(mddi);
-	if (ret) {
-		PR_DISP_ERR("mddi: failed to setup rev data!\n");
-		goto error_rev_data;
-	}
-
-	mddi->int_enable = 0;
-	mddi_writel(mddi->int_enable, INTEN);
-	ret = request_irq(mddi->irq, mddi_isr, IRQF_DISABLED, "mddi",
-			  &mddi->client_data);
-	if (ret) {
-		PR_DISP_ERR("mddi: failed to request enable irq!\n");
-		goto error_request_irq;
-	}
-
-	/* turn on the mddi client bridge chip */
-	#if 0 /*advised by SKY*/
-	if (mddi->power_client)
-		mddi->power_client(&mddi->client_data, 1);
-	#endif
-	/* initialize the mddi registers */
-	mddi_set_auto_hibernate(&mddi->client_data, 0);
-	mddi_writel(MDDI_CMD_RESET, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-	mddi->version = mddi_init_registers(mddi);
-	if (mddi->version < 0x20) {
-		PR_DISP_ERR("mddi: unsupported version 0x%x\n",
-		       mddi->version);
-		ret = -ENODEV;
-		goto error_mddi_version;
-	}
-
-	/* read the capabilities off the client */
-	if (!mddi_get_client_caps(mddi)) {
-		PR_DISP_INFO("mddi: no client found\n");
-		/* power down the panel */
-		mddi_writel(MDDI_CMD_POWERDOWN, CMD);
-		PR_DISP_INFO("mddi powerdown: stat %x\n", mddi_readl(STAT));
-		msleep(100);
-		PR_DISP_INFO("mddi powerdown: stat %x\n", mddi_readl(STAT));
-		goto dummy_client;
-	}
-
-	mddi_set_auto_hibernate(&mddi->client_data, 1);
-
-	/*
-	 * FIXME: User kernel defconfig to link dedicated mddi client driver.
-	 */
-	if (mddi->caps.Mfr_Name == 0)
-		pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code);
-
-	mddi->client_pdev.id = 0;
-	for (i = 0; i < pdata->num_clients; i++) {
-		if (pdata->client_platform_data[i].product_id ==
-		    (mddi->caps.Mfr_Name << 16 | mddi->caps.Product_Code)) {
-			mddi->client_data.private_client_data =
-				pdata->client_platform_data[i].client_data;
-			mddi->client_pdev.name =
-				pdata->client_platform_data[i].name;
-			mddi->client_pdev.id =
-				pdata->client_platform_data[i].id;
-			/* XXX: possibly set clock */
-			break;
-		}
-	}
-
-	if (i >= pdata->num_clients) {
-dummy_client:
-		mddi->client_data.private_client_data =
-			pdata->client_platform_data[0].client_data;
-		mddi->client_pdev.name =
-			pdata->client_platform_data[0].name;
-		mddi->client_pdev.id =
-			pdata->client_platform_data[0].id;
-		mddi->client_pdev.name = "mddi_c_dummy";
-		clk_disable(mddi->clk);
-	}
-	PR_DISP_INFO("mddi: registering panel %s\n",
-		mddi->client_pdev.name);
-
-	mddi->client_data.suspend = mddi_suspend;
-	mddi->client_data.resume = mddi_resume;
-	mddi->client_data.activate_link = mddi_activate_link;
-	mddi->client_data.remote_write = mddi_remote_write;
-	mddi->client_data.remote_write_vals = mddi_remote_write_vals;
-	mddi->client_data.remote_read = mddi_remote_read;
-	mddi->client_data.auto_hibernate = mddi_set_auto_hibernate;
-	mddi->client_data.fb_resource = pdata->fb_resource;
-	mddi->client_data.send_powerdown = mddi_send_powerdown;
-	if (pdev->id == 0)
-		mddi->client_data.interface_type = MSM_MDDI_PMDH_INTERFACE;
-	else if (pdev->id == 1)
-		mddi->client_data.interface_type = MSM_MDDI_EMDH_INTERFACE;
-	else {
-		PR_DISP_ERR("mddi: can not determine interface %d!\n",
-		       pdev->id);
-		ret = -EINVAL;
-		goto error_mddi_interface;
-	}
-
-	mddi->client_pdev.dev.platform_data = &mddi->client_data;
-	PR_DISP_INFO("mddi: publish: %s\n", mddi->client_name);
-	platform_device_register(&mddi->client_pdev);
-	mddi_reg_debugfs_init(mddi);
-
-	return 0;
-
-error_mddi_interface:
-error_mddi_version:
-	free_irq(mddi->irq, 0);
-error_request_irq:
-	dma_free_coherent(NULL, 0x1000, mddi->rev_data, mddi->rev_addr);
-error_rev_data:
-error_clk_setup:
-	wake_lock_destroy(&mddi->idle_lock);
-	wake_lock_destroy(&mddi->link_active_idle_lock);
-error_get_irq_resource:
-	iounmap(mddi->base);
-error_ioremap:
-
-	PR_DISP_INFO("mddi: mddi_init() failed (%d)\n", ret);
-	return ret;
-}
-
-#if 0 /* read/write mddi registers from userspace */
-module_param_named(debug, mddi_debug_flags, uint, 0644);
-
-static uint32_t selected_register;
-module_param_named(reg, selected_register, uint, 0644);
-
-static int set_reg(const char *val, struct kernel_param *kp)
-{
-	char *endp;
-	uint32_t l;
-
-	if (!val)
-		return -EINVAL;
-	l = strict_strtoul(val, &endp, 0);
-	if (endp == val || ((uint32_t)l != l))
-		return -EINVAL;
-	mddi_remote_write(kp->arg, l, selected_register);
-	return 0;
-}
-
-static int get_reg(char *buffer, struct kernel_param *kp)
-{
-	int val;
-	val = mddi_remote_read(kp->arg, selected_register);
-	return sprintf(buffer, "%x", val);
-}
-
-module_param_call(pmdh_val, set_reg, get_reg, &mddi_info[0], 0644);
-module_param_call(emdh_val, set_reg, get_reg, &mddi_info[1], 0644);
-
-#endif
+static int pmdh_clk_status;
+int irq_enabled;
+unsigned char mddi_timer_shutdown_flag;
 
 static struct platform_driver mddi_driver = {
 	.probe = mddi_probe,
-	.driver = { .name = "msm_mddi" },
+	.remove = mddi_remove,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+#ifdef CONFIG_PM
+	.suspend = mddi_suspend,
+	.resume = mddi_resume,
+#endif
+#endif
+	.shutdown = NULL,
+	.driver = {
+		.name = "mddi",
+		.pm = &mddi_dev_pm_ops,
+		   },
 };
 
-static int __init _mddi_init(void)
+extern int int_mddi_pri_flag;
+DEFINE_MUTEX(pmdh_clk_lock);
+
+int pmdh_clk_func(int value)
+{
+	int ret = 0;
+
+	switch (value) {
+	case 0:
+		pmdh_clk_disable();
+		break;
+	case 1:
+		pmdh_clk_enable();
+		break;
+	case 2:
+	default:
+		mutex_lock(&pmdh_clk_lock);
+		ret = pmdh_clk_status;
+		mutex_unlock(&pmdh_clk_lock);
+		break;
+	}
+	return ret;
+}
+
+static void pmdh_clk_disable()
+{
+	mutex_lock(&pmdh_clk_lock);
+	if (pmdh_clk_status == 0) {
+		mutex_unlock(&pmdh_clk_lock);
+		return;
+	}
+
+	if (mddi_host_timer.function) {
+		mutex_lock(&mddi_timer_lock);
+		mddi_timer_shutdown_flag = 1;
+		mutex_unlock(&mddi_timer_lock);
+		del_timer_sync(&mddi_host_timer);
+		mutex_lock(&mddi_timer_lock);
+		mddi_timer_shutdown_flag = 0;
+		mutex_unlock(&mddi_timer_lock);
+	}
+	if (int_mddi_pri_flag && irq_enabled) {
+		disable_irq(INT_MDDI_PRI);
+		irq_enabled = 0;
+	}
+
+	if (mddi_clk) {
+		clk_disable_unprepare(mddi_clk);
+		pmdh_clk_status = 0;
+	}
+	if (mddi_pclk)
+		clk_disable_unprepare(mddi_pclk);
+	mutex_unlock(&pmdh_clk_lock);
+}
+
+static void pmdh_clk_enable()
+{
+	mutex_lock(&pmdh_clk_lock);
+	if (pmdh_clk_status == 1) {
+		mutex_unlock(&pmdh_clk_lock);
+		return;
+	}
+
+	if (mddi_clk) {
+		clk_prepare_enable(mddi_clk);
+		pmdh_clk_status = 1;
+	}
+	if (mddi_pclk)
+		clk_prepare_enable(mddi_pclk);
+
+	if (int_mddi_pri_flag && !irq_enabled) {
+		enable_irq(INT_MDDI_PRI);
+		irq_enabled = 1;
+	}
+
+	if (mddi_host_timer.function)
+		mddi_host_timer_service(0);
+
+	mutex_unlock(&pmdh_clk_lock);
+}
+
+static int mddi_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	boolean dma_pending, dma_update_flag;
+	int ret, i;
+
+	mfd = platform_get_drvdata(pdev);
+
+	for (i = 0; i < 6; i++) {
+		dma_update_flag = mfd->dma_update_flag;
+		dma_pending = mfd->dma->busy;
+		if (dma_update_flag && !dma_pending)
+			break;
+		msleep(5);
+	}
+
+	pmdh_clk_enable();
+	ret = panel_next_off(pdev);
+	pmdh_clk_disable();
+
+	if (mddi_pdata && mddi_pdata->mddi_power_save)
+		mddi_pdata->mddi_power_save(0);
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(0);
+#else
+	if (mfd->ebi1_clk)
+		clk_disable_unprepare(mfd->ebi1_clk);
+#endif
+	pm_runtime_put(&pdev->dev);
+	return ret;
+}
+
+static int mddi_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	u32 clk_rate;
+	struct msm_fb_data_type *mfd;
+#ifdef ENABLE_FWD_LINK_SKEW_CALIBRATION
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+	u32 stat_reg;
+#endif
+
+	mfd = platform_get_drvdata(pdev);
+	pm_runtime_get(&pdev->dev);
+	if (mddi_pdata && mddi_pdata->mddi_power_save)
+		mddi_pdata->mddi_power_save(1);
+
+	pmdh_clk_enable();
+#ifdef ENABLE_FWD_LINK_SKEW_CALIBRATION
+	if (mddi_client_type < 2) {
+		/* For skew calibration, clock should be less than 50MHz */
+		clk_rate = clk_round_rate(mddi_clk, 49000000);
+		if (!clk_set_rate(mddi_clk, clk_rate)) {
+			stat_reg = mddi_host_reg_in(STAT);
+			printk(KERN_DEBUG "\n stat_reg = 0x%x", stat_reg);
+			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
+			if (stat_reg & (0x1 << 4))
+				mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
+
+			mddi_host_reg_out(CMD, MDDI_CMD_SEND_RTD);
+			mddi_send_fw_link_skew_cal(host_idx);
+			mddi_host_reg_out(CMD, MDDI_CMD_SEND_RTD);
+			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
+		} else {
+			printk(KERN_ERR "%s: clk_set_rate failed\n",
+				__func__);
+		}
+	}
+#endif
+
+	clk_rate = mfd->fbi->var.pixclock;
+	clk_rate = min(clk_rate, mfd->panel_info.clk_max);
+
+	if (mddi_pdata &&
+	    mddi_pdata->mddi_sel_clk &&
+	    mddi_pdata->mddi_sel_clk(&clk_rate))
+			printk(KERN_ERR
+			  "%s: can't select mddi io clk targate rate = %d\n",
+			  __func__, clk_rate);
+
+	clk_rate = clk_round_rate(mddi_clk, clk_rate);
+	if (clk_set_rate(mddi_clk, clk_rate) < 0)
+		printk(KERN_ERR "%s: clk_set_rate failed\n",
+			__func__);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(2);
+#else
+	if (mfd->ebi1_clk)
+		clk_prepare_enable(mfd->ebi1_clk);
+#endif
+	ret = panel_next_on(pdev);
+
+	return ret;
+}
+
+static int mddi_resource_initialized;
+
+static int mddi_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct platform_device *mdp_dev = NULL;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc;
+	resource_size_t size ;
+	u32 clk_rate;
+	unsigned long rate;
+	int ret;
+	struct clk *ebi1_clk = NULL;
+
+	if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
+		mddi_pdata = pdev->dev.platform_data;
+		pmdh_clk_status = 0;
+
+		mddi_clk = clk_get(&pdev->dev, "core_clk");
+		if (IS_ERR(mddi_clk)) {
+			pr_err("can't find mddi_clk\n");
+			return PTR_ERR(mddi_clk);
+		}
+		rate = clk_round_rate(mddi_clk, 49000000);
+		ret = clk_set_rate(mddi_clk, rate);
+		if (ret)
+			pr_err("Can't set mddi_clk min rate to %lu\n",
+									rate);
+
+		pr_info("mddi_clk init rate is %lu\n",
+			clk_get_rate(mddi_clk));
+		mddi_pclk = clk_get(&pdev->dev, "iface_clk");
+		if (IS_ERR(mddi_pclk))
+			mddi_pclk = NULL;
+		pmdh_clk_enable();
+
+#ifndef CONFIG_MSM_BUS_SCALING
+		ebi1_clk = clk_get(&pdev->dev, "mem_clk");
+		if (IS_ERR(ebi1_clk))
+			return PTR_ERR(ebi1_clk);
+		clk_set_rate(ebi1_clk, 65000000);
+#endif
+
+		size =  resource_size(&pdev->resource[0]);
+		msm_pmdh_base =  ioremap(pdev->resource[0].start, size);
+
+		MSM_FB_INFO("primary mddi base phy_addr = 0x%x virt = 0x%x\n",
+				pdev->resource[0].start, (int) msm_pmdh_base);
+
+		if (unlikely(!msm_pmdh_base))
+			return -ENOMEM;
+
+		if (mddi_pdata && mddi_pdata->mddi_power_save)
+			mddi_pdata->mddi_power_save(1);
+
+		mddi_resource_initialized = 1;
+		return 0;
+	}
+
+	if (!mddi_resource_initialized)
+		return -EPERM;
+
+	mfd = platform_get_drvdata(pdev);
+	mfd->ebi1_clk = ebi1_clk;
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	mdp_dev = platform_device_alloc("mdp", pdev->id);
+	if (!mdp_dev)
+		return -ENOMEM;
+
+	/*
+	 * link to the latest pdev
+	 */
+	mfd->pdev = mdp_dev;
+	mfd->dest = DISPLAY_LCD;
+
+	/*
+	 * alloc panel device data
+	 */
+	if (platform_device_add_data
+	    (mdp_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		printk(KERN_ERR "mddi_probe: platform_device_add_data failed!\n");
+		platform_device_put(mdp_dev);
+		return -ENOMEM;
+	}
+	/*
+	 * data chain
+	 */
+	pdata = mdp_dev->dev.platform_data;
+	pdata->on = mddi_on;
+	pdata->off = mddi_off;
+	pdata->next = pdev;
+	pdata->clk_func = pmdh_clk_func;
+	/*
+	 * get/set panel specific fb info
+	 */
+	mfd->panel_info = pdata->panel_info;
+
+	if (mfd->index == 0)
+		mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
+	else
+		mfd->fb_imgType = MDP_RGB_565;
+
+	clk_rate = mfd->panel_info.clk_max;
+	if (mddi_pdata &&
+	    mddi_pdata->mddi_sel_clk &&
+	    mddi_pdata->mddi_sel_clk(&clk_rate))
+			printk(KERN_ERR
+			  "%s: can't select mddi io clk targate rate = %d\n",
+			  __func__, clk_rate);
+
+	if (clk_set_max_rate(mddi_clk, clk_rate) < 0)
+		printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__);
+	mfd->panel_info.clk_rate = mfd->panel_info.clk_min;
+
+	if (!mddi_client_type)
+		mddi_client_type = mfd->panel_info.lcd.rev;
+	else if (!mfd->panel_info.lcd.rev)
+		printk(KERN_ERR
+		"%s: mddi client is trying to revert back to type 1	!!!\n",
+		__func__);
+
+	/*
+	 * set driver data
+	 */
+	platform_set_drvdata(mdp_dev, mfd);
+	rc = pm_runtime_set_active(&pdev->dev);
+	if (rc < 0)
+		printk(KERN_ERR "pm_runtime: fail to set active\n");
+
+	rc = 0;
+	pm_runtime_enable(&pdev->dev);
+	/*
+	 * register in mdp driver
+	 */
+	rc = platform_device_add(mdp_dev);
+	if (rc)
+		goto mddi_probe_err;
+
+	pdev_list[pdev_list_cnt++] = pdev;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	mfd->mddi_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
+	mfd->mddi_early_suspend.suspend = mddi_early_suspend;
+	mfd->mddi_early_suspend.resume = mddi_early_resume;
+	register_early_suspend(&mfd->mddi_early_suspend);
+#endif
+
+	return 0;
+
+mddi_probe_err:
+	platform_device_put(mdp_dev);
+	return rc;
+}
+
+static int mddi_pad_ctrl;
+static int mddi_power_locked;
+
+int mddi_client_power(unsigned int client_id)
+{
+	int ret = 0;
+	if (mddi_pdata && mddi_pdata->mddi_client_power)
+		ret = mddi_pdata->mddi_client_power(client_id);
+	return ret;
+}
+
+void mddi_disable(int lock)
+{
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+
+	if (mddi_power_locked)
+		return;
+
+	if (lock)
+		mddi_power_locked = 1;
+	pmdh_clk_enable();
+
+	mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL);
+	mddi_host_reg_out(PAD_CTL, 0x0);
+
+	pmdh_clk_disable();
+
+	if (mddi_pdata && mddi_pdata->mddi_power_save)
+		mddi_pdata->mddi_power_save(0);
+}
+
+#ifdef CONFIG_PM
+static int mddi_is_in_suspend;
+
+static int mddi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+	if (mddi_is_in_suspend)
+		return 0;
+
+	mddi_is_in_suspend = 1;
+
+	if (mddi_power_locked)
+		return 0;
+
+	pmdh_clk_enable();
+
+	mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL);
+	mddi_host_reg_out(PAD_CTL, 0x0);
+
+	pmdh_clk_disable();
+
+	return 0;
+}
+
+static int mddi_resume(struct platform_device *pdev)
+{
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+
+	if (!mddi_is_in_suspend)
+		return 0;
+
+	mddi_is_in_suspend = 0;
+
+	if (mddi_power_locked)
+		return 0;
+
+	pmdh_clk_enable();
+
+	mddi_host_reg_out(PAD_CTL, mddi_pad_ctrl);
+
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mddi_early_suspend(struct early_suspend *h)
+{
+	pm_message_t state;
+	struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
+							mddi_early_suspend);
+
+	state.event = PM_EVENT_SUSPEND;
+	mddi_suspend(mfd->pdev, state);
+}
+
+static void mddi_early_resume(struct early_suspend *h)
+{
+	struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
+							mddi_early_suspend);
+	mddi_resume(mfd->pdev);
+}
+#endif
+
+static int mddi_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+	if (mddi_host_timer.function) {
+		mutex_lock(&mddi_timer_lock);
+		mddi_timer_shutdown_flag = 1;
+		mutex_unlock(&mddi_timer_lock);
+		del_timer_sync(&mddi_host_timer);
+		mutex_lock(&mddi_timer_lock);
+		mddi_timer_shutdown_flag = 0;
+		mutex_unlock(&mddi_timer_lock);
+	}
+
+	iounmap(msm_pmdh_base);
+
+	return 0;
+}
+
+static int mddi_register_driver(void)
 {
 	return platform_driver_register(&mddi_driver);
 }
 
-module_init(_mddi_init);
+static int __init mddi_driver_init(void)
+{
+	int ret;
+
+	ret = mddi_register_driver();
+	if (ret) {
+		pmdh_clk_disable();
+		clk_put(mddi_clk);
+		if (mddi_pclk)
+			clk_put(mddi_pclk);
+		printk(KERN_ERR "mddi_register_driver() failed!\n");
+		return ret;
+	}
+
+	mddi_init();
+
+	return ret;
+}
+
+module_init(mddi_driver_init);
diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/msm/mddi_client_dummy.c
index 9fa819d..ebbae87 100644
--- a/drivers/video/msm/mddi_client_dummy.c
+++ b/drivers/video/msm/mddi_client_dummy.c
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/platform_device.h>
 
 #include <mach/msm_fb.h>
@@ -50,8 +49,6 @@
 static int mddi_dummy_probe(struct platform_device *pdev)
 {
 	struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
 	struct panel_info *panel =
 		kzalloc(sizeof(struct panel_info), GFP_KERNEL);
 	int ret;
@@ -67,7 +64,7 @@
 	panel->pdev.id = pdev->id;
 	platform_device_add_resources(&panel->pdev,
 				      client_data->fb_resource, 1);
-	panel->panel_data.fb_data = &bridge_data->fb_data;
+	panel->panel_data.fb_data = client_data->private_client_data;
 	panel->pdev.dev.platform_data = &panel->panel_data;
 	ret = platform_device_register(&panel->pdev);
 	if (ret) {
diff --git a/drivers/video/msm/mddi_client_eid.h b/drivers/video/msm/mddi_client_eid.h
deleted file mode 100644
index d31e031..0000000
--- a/drivers/video/msm/mddi_client_eid.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _MDDI_CLIENT_EID_H_
-#define _MDDI_CLIENT_EID_H_
-
-#define SLPIN		0x10
-#define SLPOUT 		0x11
-#define CASET		0x2a
-#define PASET		0x2b
-#define RAMWR		0x2c
-#define TEON		0x35
-#define MADCTL		0x36
-#define COLMOD		0x3a
-#define WRDISBV 	0x51
-#define RDDISBV		0x52
-#define WRCTRLD		0x53
-#define WRCABC		0x55
-#define WRCABCMB	0x5e
-#define MIECTL1		0xca
-#define BCMODE 		0xcb
-#define MIECTL2		0xcc
-#define MIECTL3		0xcd
-#define DCON		0xef
-#define DISCTL 		0xf2
-#define PWRCTL 		0xf3
-#define VCMCTL 		0xf4
-#define SRCCTL 		0xf5
-#define GAMCTL1		0xf7
-#define GAMCTL2		0xf8
-#define GATECTL		0xfd
-#define MDDICTL		0xe0
-#define DCON		0xef
-
-#endif
diff --git a/drivers/video/msm/mddi_client_hx8356.c b/drivers/video/msm/mddi_client_hx8356.c
deleted file mode 100644
index c9061e4..0000000
--- a/drivers/video/msm/mddi_client_hx8356.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/* drivers/video/msm_fb/mddi_client_hx8356.c
- *
- * Support for eid mddi client devices with Samsung S6D0154
- *
- * Copyright (C) 2007 HTC Incorporated
- * Author: Wade Wu (wade_wu@htc.com)
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/leds.h>
-#include <linux/kthread.h>
-#include <linux/wakelock.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-#include <asm/atomic.h>
-#include <asm/mach-types.h>
-#include "../../../arch/arm/mach-msm/proc_comm.h"
-#include <mach/msm_fb.h>
-#include <mach/msm_panel.h>
-#include <mach/msm_iomap.h>
-#include <mach/debug_display.h>
-
-
-#if 1
-#define B(s...) printk(s)
-#else
-#define B(s...) do {} while (0)
-#endif
-
-#define DEBUG_VSYNC_INT 0
-#define VSYNC_COUNTER 31
-
-#define VSYNC_CLEAR (MSM_GPIO1_BASE + 0x800 + 0x9c)
-#define VSYNC_STATUS (MSM_GPIO1_BASE + 0x800 + 0xac)
-#define VSYNC_EN (MSM_GPIO1_BASE + 0x800 + 0x8c)
-
-static DECLARE_WAIT_QUEUE_HEAD(himax_vsync_wait);
-
-#define INTERVAL_ADJUSTING	300
-
-struct panel_info {
-	struct msm_mddi_client_data *client_data;
-	struct platform_device pdev;
-	struct msm_panel_data panel_data;
-	struct work_struct adjust_panel_work;
-	struct msmfb_callback *fb_callback;
-	struct wake_lock idle_lock;
-	atomic_t frame_counter;
-	int himax_got_int;
-};
-
-static struct cabc_config cabc_config;
-static struct platform_device mddi_himax_cabc = {
-	.name = "himax_cabc",
-	.id = 0,
-	.dev = {
-		.platform_data = &cabc_config,
-	}
-};
-
-static struct clk *ebi1_clk;
-
-static void himax_dump_vsync(void)
-{
-	B(KERN_DEBUG "%s: enter.\n", __func__);
-}
-
-static void himax_adjust_work(struct work_struct *work)
-{
-	struct panel_info *panel = container_of(work, struct panel_info, adjust_panel_work);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-
-	if (bridge_data->adjust)
-		bridge_data->adjust(client_data);
-
-	atomic_set(&panel->frame_counter, INTERVAL_ADJUSTING);
-}
-
-static void
-himax_request_vsync(struct msm_panel_data *panel_data,
-		      struct msmfb_callback *callback)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	panel->fb_callback = callback;
-	if (panel->himax_got_int) {
-		panel->himax_got_int = 0;
-		client_data->activate_link(client_data); /* clears interrupt */
-	}
-}
-
-static void himax_wait_vsync(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	if (panel->himax_got_int) {
-		panel->himax_got_int = 0;
-		client_data->activate_link(client_data); /* clears interrupt */
-	}
-
-	if (wait_event_timeout(himax_vsync_wait, panel->himax_got_int,
-				HZ/2) == 0)
-		PR_DISP_ERR("timeout waiting for VSYNC\n");
-
-	panel->himax_got_int = 0;
-	/* interrupt clears when screen dma starts */
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-/* got called by msmfb_suspend */
-static int himax_suspend(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-	    client_data->private_client_data;
-	int ret;
-
-	wake_lock(&panel->idle_lock);
-	ret = bridge_data->uninit(bridge_data, client_data);
-	wake_unlock(&panel->idle_lock);
-
-	if (ret) {
-		B(KERN_INFO "mddi himax client: non zero return from "
-		  "uninit\n");
-		return ret;
-	}
-	client_data->suspend(client_data);
-	return 0;
-}
-
-/* got called by msmfb_resume */
-static int himax_resume(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-	    client_data->private_client_data;
-	int ret;
-
-	client_data->resume(client_data);
-
-	wake_lock(&panel->idle_lock);
-	ret = bridge_data->init(bridge_data, client_data);
-	wake_unlock(&panel->idle_lock);
-
-	if (ret)
-		return ret;
-	return 0;
-}
-
-static int himax_blank(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-	    client_data->private_client_data;
-
-	return bridge_data->blank(bridge_data, client_data);
-}
-
-static int himax_unblank(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-	    client_data->private_client_data;
-
-	if (cabc_config.bl_handle) {
-		mdelay(40);
-		cabc_config.bl_handle(&mddi_himax_cabc, LED_FULL);
-	}
-	return bridge_data->unblank(bridge_data, client_data);
-}
-
-static irqreturn_t himax_vsync_interrupt(int irq, void *data)
-{
-	struct panel_info *panel = data;
-
-	panel->himax_got_int = 1;
-
-	if (atomic_dec_and_test(&panel->frame_counter)) {
-		schedule_work(&panel->adjust_panel_work);
-		return IRQ_HANDLED;
-	}
-
-	if (panel->fb_callback  && atomic_read(&panel->frame_counter) > 0) {
-		panel->fb_callback->func(panel->fb_callback);
-		panel->fb_callback = NULL;
-	}
-	wake_up(&himax_vsync_wait);
-
-	return IRQ_HANDLED;
-}
-
-static int setup_vsync(struct panel_info *panel, int init)
-{
-	int ret;
-	int gpio = 97;
-	unsigned int irq;
-
-	if (!init) {
-		ret = 0;
-		goto uninit;
-	}
-	ret = gpio_request(gpio, "vsync");
-	if (ret)
-		goto err_request_gpio_failed;
-
-	ret = irq = gpio_to_irq(gpio);
-	if (ret < 0)
-		goto err_get_irq_num_failed;
-
-	ret = request_irq(irq, himax_vsync_interrupt, IRQF_TRIGGER_RISING,
-			"vsync", panel);
-	if (ret)
-		goto err_request_irq_failed;
-
-	PR_DISP_INFO("vsync on gpio %d now %d\n", gpio,
-			gpio_get_value(gpio));
-	return 0;
-
-uninit:
-	free_irq(gpio_to_irq(gpio), panel->client_data);
-err_request_irq_failed:
-err_get_irq_num_failed:
-	gpio_free(gpio);
-err_request_gpio_failed:
-	return ret;
-}
-
-static int mddi_himax_probe(struct platform_device *pdev)
-{
-	int ret, err = -EINVAL;
-	struct panel_info *panel;
-	struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-	    client_data->private_client_data;
-	struct panel_data *panel_data = &bridge_data->panel_conf;
-
-	B(KERN_DEBUG "%s: enter\n", __func__);
-
-	panel = kzalloc(sizeof(struct panel_info), GFP_KERNEL);
-	if (!panel) {
-		err = -ENOMEM;
-		goto err_out;
-	}
-
-	platform_set_drvdata(pdev, panel);
-	ret = setup_vsync(panel, 1);
-	if (ret) {
-		dev_err(&pdev->dev, "mddi_himax_setup_vsync failed\n");
-		err = -EIO;
-		goto err_panel;
-	}
-
-	cabc_config.pwm_data = panel_data->pwm;
-	cabc_config.min_level = panel_data->min_level;
-	cabc_config.shrink = panel_data->shrink;
-	cabc_config.shrink_br = panel_data->shrink_br;
-	cabc_config.change_cabcmode = panel_data->change_cabcmode;
-	if (panel_data->caps & MSMFB_CAP_CABC) {
-		PR_DISP_INFO("CABC enabled\n");
-		cabc_config.client = client_data;
-		platform_device_register(&mddi_himax_cabc);
-	}
-
-	panel->client_data = client_data;
-	panel->panel_data.suspend = himax_suspend;
-	panel->panel_data.resume = himax_resume;
-	panel->panel_data.wait_vsync = himax_wait_vsync;
-	panel->panel_data.request_vsync = himax_request_vsync;
-	panel->panel_data.blank = himax_blank;
-	panel->panel_data.unblank = himax_unblank;
-	panel->panel_data.dump_vsync = himax_dump_vsync;
-	panel->panel_data.fb_data = &bridge_data->fb_data;
-	panel->panel_data.caps = ~MSMFB_CAP_PARTIAL_UPDATES;
-	panel->pdev.name = "msm_panel";
-	panel->pdev.id = pdev->id;
-	panel->pdev.resource = client_data->fb_resource;
-	panel->pdev.num_resources = 1;
-	panel->pdev.dev.platform_data = &panel->panel_data;
-	platform_device_register(&panel->pdev);
-	wake_lock_init(&panel->idle_lock, WAKE_LOCK_IDLE, "eid_idle_lock");
-	/*for debugging vsync issue*/
-	ebi1_clk = clk_get(NULL, "ebi1_clk");
-
-	INIT_WORK(&panel->adjust_panel_work, himax_adjust_work);
-	atomic_set(&panel->frame_counter, INTERVAL_ADJUSTING);
-
-	return 0;
-
-err_panel:
-	kfree(panel);
-err_out:
-	return err;
-}
-
-static int mddi_himax_remove(struct platform_device *pdev)
-{
-	struct panel_info *panel = platform_get_drvdata(pdev);
-
-	setup_vsync(panel, 0);
-	kfree(panel);
-	return 0;
-}
-
-static struct platform_driver mddi_client_4858_0000 = {
-	.probe = mddi_himax_probe,
-	.remove = mddi_himax_remove,
-	.driver = {.name = "mddi_c_4858_8356"},
-};
-
-static int __init mddi_client_himax_init(void)
-{
-	return platform_driver_register(&mddi_client_4858_0000);
-}
-
-module_init(mddi_client_himax_init);
diff --git a/drivers/video/msm/mddi_client_novb9f6_5560.c b/drivers/video/msm/mddi_client_novb9f6_5560.c
deleted file mode 100644
index 16db47c..0000000
--- a/drivers/video/msm/mddi_client_novb9f6_5560.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2008 HTC Corporation.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/wakelock.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <mach/msm_fb.h>
-#include <mach/debug_display.h>
-#include <mach/panel_id.h>
-
-static DECLARE_WAIT_QUEUE_HEAD(novtec_vsync_wait);
-
-struct panel_info {
-	struct msm_mddi_client_data *client_data;
-	struct platform_device pdev;
-	struct msm_panel_data panel_data;
-	struct msmfb_callback *novtec_callback;
-	struct wake_lock idle_lock;
-	int novtec_got_int;
-	int vsync_gpio;
-};
-
-static struct platform_device mddi_nov_cabc = {
-	.name = "nov_cabc",
-	.id = 0,
-};
-
-static void novtec_request_vsync(struct msm_panel_data *panel_data,
-				  struct msmfb_callback *callback)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	panel->novtec_callback = callback;
-	if (panel->novtec_got_int) {
-		panel->novtec_got_int = 0;
-		client_data->activate_link(client_data);
-	}
-}
-
-static void novtec_clear_vsync(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	client_data->activate_link(client_data);
-}
-
-static void novtec_wait_vsync(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	if (panel->novtec_got_int) {
-		panel->novtec_got_int = 0;
-		client_data->activate_link(client_data); /* clears interrupt */
-	}
-	if (wait_event_timeout(novtec_vsync_wait, panel->novtec_got_int,
-				HZ/2) == 0)
-		PR_DISP_ERR("timeout waiting for VSYNC\n");
-	panel->novtec_got_int = 0;
-	/* interrupt clears when screen dma starts */
-}
-
-static int novtec_suspend(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	int ret;
-
-	wake_lock(&panel->idle_lock);
-	ret = bridge_data->uninit(bridge_data, client_data);
-	wake_unlock(&panel->idle_lock);
-	if (ret) {
-		PR_DISP_INFO("mddi novtec client: non zero return from "
-			"uninit\n");
-		return ret;
-	}
-	client_data->suspend(client_data);
-	return 0;
-}
-
-static int novtec_resume(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	int ret;
-
-	wake_lock(&panel->idle_lock);
-	client_data->resume(client_data);
-	wake_unlock(&panel->idle_lock);
-	ret = bridge_data->init(bridge_data, client_data);
-	if (ret)
-		return ret;
-	return 0;
-}
-
-static int novtec_blank(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-
-	return bridge_data->blank(bridge_data, client_data);
-}
-
-static int novtec_unblank(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-
-	return bridge_data->unblank(bridge_data, client_data);
-}
-
-static int novtec_recover(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	int ret;
-
-	ret = bridge_data->init(bridge_data, client_data);
-	if (ret)
-		return ret;
-	return 0;
-}
-
-static irqreturn_t novtec_vsync_interrupt(int irq, void *data)
-{
-	struct panel_info *panel = data;
-
-	panel->novtec_got_int = 1;
-	if (panel->novtec_callback) {
-		panel->novtec_callback->func(panel->novtec_callback);
-		panel->novtec_callback = 0;
-	}
-	wake_up(&novtec_vsync_wait);
-	return IRQ_HANDLED;
-}
-
-static int setup_vsync(struct panel_info *panel,
-		       int init)
-{
-	int ret;
-	int gpio = panel->vsync_gpio;
-	unsigned int irq;
-
-	if (!init) {
-		ret = 0;
-		goto uninit;
-	}
-	ret = gpio_request(gpio, "vsync");
-	if (ret)
-		goto err_request_gpio_failed;
-
-	ret = gpio_direction_input(gpio);
-	if (ret)
-		goto err_gpio_direction_input_failed;
-
-	ret = irq = gpio_to_irq(gpio);
-	if (ret < 0)
-		goto err_get_irq_num_failed;
-
-	register_gpio_int_mask(gpio, 1);
-
-	ret = request_irq(irq, novtec_vsync_interrupt, IRQF_TRIGGER_RISING,
-			  "vsync", panel);
-	if (ret)
-		goto err_request_irq_failed;
-	PR_DISP_INFO("vsync on gpio %d now %d\n",
-	       gpio, gpio_get_value(gpio));
-	return 0;
-
-uninit:
-	free_irq(gpio_to_irq(gpio), panel);
-err_request_irq_failed:
-err_get_irq_num_failed:
-err_gpio_direction_input_failed:
-	gpio_free(gpio);
-err_request_gpio_failed:
-	return ret;
-}
-
-static int mddi_novtec_probe(struct platform_device *pdev)
-{
-#ifndef CONFIG_MDP4_HW_VSYNC
-	int ret;
-#endif
-	struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	struct panel_data *panel_data = &bridge_data->panel_conf;
-	struct panel_info *panel =
-		kzalloc(sizeof(struct panel_info), GFP_KERNEL);
-
-	if (!panel)
-		return -ENOMEM;
-	platform_set_drvdata(pdev, panel);
-
-	PR_DISP_DEBUG("%s\n", __func__);
-
-	if (panel_data->caps & MSMFB_CAP_CABC) {
-		PR_DISP_INFO("CABC enabled\n");
-		mddi_nov_cabc.dev.platform_data = client_data;
-		platform_device_register(&mddi_nov_cabc);
-	}
-
-	if (panel_data->vsync_gpio == 0)
-#if defined(CONFIG_ARCH_MSM7X30)
-		panel->vsync_gpio = 30;
-#else
-		panel->vsync_gpio = 98;
-#endif
-	else
-		panel->vsync_gpio = panel_data->vsync_gpio;
-
-#ifndef CONFIG_MDP4_HW_VSYNC
-	ret = setup_vsync(panel, 1);
-	if (ret) {
-		dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n");
-		return ret;
-	}
-#endif
-	panel->client_data = client_data;
-	panel->panel_data.suspend = novtec_suspend;
-	panel->panel_data.resume = novtec_resume;
-	panel->panel_data.wait_vsync = novtec_wait_vsync;
-	panel->panel_data.request_vsync = novtec_request_vsync;
-	panel->panel_data.clear_vsync = novtec_clear_vsync;
-	panel->panel_data.blank = novtec_blank;
-	panel->panel_data.unblank = novtec_unblank;
-	panel->panel_data.fb_data =  &bridge_data->fb_data;
-	panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
-	panel->panel_data.recover_vsync = novtec_recover;
-
-	panel->pdev.name = "msm_panel";
-	panel->pdev.id = pdev->id;
-	panel->pdev.resource = client_data->fb_resource;
-	panel->pdev.num_resources = 1;
-	panel->pdev.dev.platform_data = &panel->panel_data;
-	platform_device_register(&panel->pdev);
-	wake_lock_init(&panel->idle_lock, WAKE_LOCK_IDLE, "nov_idle_lock");
-
-	return 0;
-}
-
-static int mddi_novtec_remove(struct platform_device *pdev)
-{
-	struct panel_info *panel = platform_get_drvdata(pdev);
-
-	setup_vsync(panel, 0);
-	kfree(panel);
-	return 0;
-}
-
-static struct platform_driver mddi_client_d263_0000 = {
-	.probe = mddi_novtec_probe,
-	.remove = mddi_novtec_remove,
-	.driver = { .name = "mddi_c_b9f6_5560" },
-};
-
-static int __init mddi_client_novtec_init(void)
-{
-	platform_driver_register(&mddi_client_d263_0000);
-	return 0;
-}
-
-module_init(mddi_client_novtec_init);
-
diff --git a/drivers/video/msm/mddi_client_novb9f6_5580.c b/drivers/video/msm/mddi_client_novb9f6_5580.c
deleted file mode 100644
index 9629dd2..0000000
--- a/drivers/video/msm/mddi_client_novb9f6_5580.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2008 HTC Corporation.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/wakelock.h>
-#include <linux/slab.h>
-#include <mach/msm_fb.h>
-#include <mach/debug_display.h>
-#include <mach/panel_id.h>
-
-static DECLARE_WAIT_QUEUE_HEAD(novtec_vsync_wait);
-
-struct panel_info {
-	struct msm_mddi_client_data *client_data;
-	struct platform_device pdev;
-	struct msm_panel_data panel_data;
-	struct msmfb_callback *novtec_callback;
-	struct wake_lock idle_lock;
-	int novtec_got_int;
-};
-
-static struct platform_device mddi_nov_cabc = {
-	.name = "nov_cabc",
-	.id = 0,
-};
-
-static void novtec_request_vsync(struct msm_panel_data *panel_data,
-				  struct msmfb_callback *callback)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	panel->novtec_callback = callback;
-	if (panel->novtec_got_int) {
-		panel->novtec_got_int = 0;
-		client_data->activate_link(client_data);
-	}
-}
-
-static void novtec_clear_vsync(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	client_data->activate_link(client_data);
-}
-
-static void novtec_wait_vsync(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	if (panel->novtec_got_int) {
-		panel->novtec_got_int = 0;
-		client_data->activate_link(client_data); /* clears interrupt */
-	}
-	if (wait_event_timeout(novtec_vsync_wait, panel->novtec_got_int,
-				HZ/2) == 0)
-		PR_DISP_ERR("timeout waiting for VSYNC\n");
-	panel->novtec_got_int = 0;
-	/* interrupt clears when screen dma starts */
-}
-
-static int novtec_suspend(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	int ret;
-
-	wake_lock(&panel->idle_lock);
-	ret = bridge_data->uninit(bridge_data, client_data);
-	wake_unlock(&panel->idle_lock);
-	if (ret) {
-		PR_DISP_INFO("mddi novtec client: non zero return from "
-			"uninit\n");
-		return ret;
-	}
-	client_data->suspend(client_data);
-	return 0;
-}
-
-static int novtec_resume(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	int ret;
-
-	wake_lock(&panel->idle_lock);
-	client_data->resume(client_data);
-	wake_unlock(&panel->idle_lock);
-	ret = bridge_data->init(bridge_data, client_data);
-	if (ret)
-		return ret;
-	return 0;
-}
-
-static int novtec_blank(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-
-	return bridge_data->blank(bridge_data, client_data);
-}
-
-static int novtec_unblank(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-
-	return bridge_data->unblank(bridge_data, client_data);
-}
-
-static irqreturn_t novtec_vsync_interrupt(int irq, void *data)
-{
-	struct panel_info *panel = data;
-
-	panel->novtec_got_int = 1;
-	if (panel->novtec_callback) {
-		panel->novtec_callback->func(panel->novtec_callback);
-		panel->novtec_callback = 0;
-	}
-	wake_up(&novtec_vsync_wait);
-	return IRQ_HANDLED;
-}
-
-static int setup_vsync(struct panel_info *panel,
-		       int init)
-{
-	int ret;
-#if defined(CONFIG_ARCH_MSM7X30)
-	int gpio = 30;
-#else
-	int gpio = 98;
-#endif
-	unsigned int irq;
-
-	if (!init) {
-		ret = 0;
-		goto uninit;
-	}
-	ret = gpio_request(gpio, "vsync");
-	if (ret)
-		goto err_request_gpio_failed;
-
-	ret = gpio_direction_input(gpio);
-	if (ret)
-		goto err_gpio_direction_input_failed;
-
-	ret = irq = gpio_to_irq(gpio);
-	if (ret < 0)
-		goto err_get_irq_num_failed;
-
-	ret = request_irq(irq, novtec_vsync_interrupt, IRQF_TRIGGER_FALLING,
-			  "vsync", panel);
-	if (ret)
-		goto err_request_irq_failed;
-	PR_DISP_INFO("vsync on gpio %d now %d\n",
-	       gpio, gpio_get_value(gpio));
-	return 0;
-
-uninit:
-	free_irq(gpio_to_irq(gpio), panel);
-err_request_irq_failed:
-err_get_irq_num_failed:
-err_gpio_direction_input_failed:
-	gpio_free(gpio);
-err_request_gpio_failed:
-	return ret;
-}
-
-static int mddi_novtec_probe(struct platform_device *pdev)
-{
-#ifndef CONFIG_MDP4_HW_VSYNC
-	int ret;
-#endif
-	struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	struct panel_data *panel_data = &bridge_data->panel_conf;
-	struct panel_info *panel =
-		kzalloc(sizeof(struct panel_info), GFP_KERNEL);
-
-	if (!panel)
-		return -ENOMEM;
-	platform_set_drvdata(pdev, panel);
-
-	PR_DISP_DEBUG("%s\n", __func__);
-
-	if (panel_data->caps & MSMFB_CAP_CABC) {
-		PR_DISP_INFO("CABC enabled\n");
-		mddi_nov_cabc.dev.platform_data = client_data;
-		platform_device_register(&mddi_nov_cabc);
-	}
-
-#ifndef CONFIG_MDP4_HW_VSYNC
-	ret = setup_vsync(panel, 1);
-	if (ret) {
-		dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n");
-		return ret;
-	}
-#endif
-	panel->client_data = client_data;
-	panel->panel_data.suspend = novtec_suspend;
-	panel->panel_data.resume = novtec_resume;
-	panel->panel_data.wait_vsync = novtec_wait_vsync;
-	panel->panel_data.request_vsync = novtec_request_vsync;
-	panel->panel_data.clear_vsync = novtec_clear_vsync;
-	panel->panel_data.blank = novtec_blank;
-	panel->panel_data.unblank = novtec_unblank;
-	panel->panel_data.fb_data =  &bridge_data->fb_data;
-	panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
-
-	panel->pdev.name = "msm_panel";
-	panel->pdev.id = pdev->id;
-	panel->pdev.resource = client_data->fb_resource;
-	panel->pdev.num_resources = 1;
-	panel->pdev.dev.platform_data = &panel->panel_data;
-	platform_device_register(&panel->pdev);
-	wake_lock_init(&panel->idle_lock, WAKE_LOCK_IDLE, "nov_idle_lock");
-
-	return 0;
-}
-
-static int mddi_novtec_remove(struct platform_device *pdev)
-{
-	struct panel_info *panel = platform_get_drvdata(pdev);
-
-	setup_vsync(panel, 0);
-	kfree(panel);
-	return 0;
-}
-
-static struct platform_driver mddi_client_d263_0000 = {
-	.probe = mddi_novtec_probe,
-	.remove = mddi_novtec_remove,
-	.driver = { .name = "mddi_c_b9f6_5580" },
-};
-
-static int __init mddi_client_novtec_init(void)
-{
-	platform_driver_register(&mddi_client_d263_0000);
-	return 0;
-}
-
-module_init(mddi_client_novtec_init);
-
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
new file mode 100644
index 0000000..c9e9349
--- /dev/null
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -0,0 +1,256 @@
+/* drivers/video/msm_fb/mddi_client_nt35399.c
+ *
+ * Support for Novatek NT35399 MDDI client of Sapphire
+ *
+ * Copyright (C) 2008 HTC Incorporated
+ * Author: Solomon Chiu (solomon_chiu@htc.com)
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/gpio.h>
+#include <mach/msm_fb.h>
+
+static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
+
+struct panel_info {
+	struct msm_mddi_client_data *client_data;
+	struct platform_device pdev;
+	struct msm_panel_data panel_data;
+	struct msmfb_callback *fb_callback;
+	struct work_struct panel_work;
+	struct workqueue_struct *fb_wq;
+	int nt35399_got_int;
+};
+
+static void
+nt35399_request_vsync(struct msm_panel_data *panel_data,
+		      struct msmfb_callback *callback)
+{
+	struct panel_info *panel = container_of(panel_data, struct panel_info,
+						panel_data);
+	struct msm_mddi_client_data *client_data = panel->client_data;
+
+	panel->fb_callback = callback;
+	if (panel->nt35399_got_int) {
+		panel->nt35399_got_int = 0;
+		client_data->activate_link(client_data); /* clears interrupt */
+	}
+}
+
+static void nt35399_wait_vsync(struct msm_panel_data *panel_data)
+{
+	struct panel_info *panel = container_of(panel_data, struct panel_info,
+						panel_data);
+	struct msm_mddi_client_data *client_data = panel->client_data;
+
+	if (panel->nt35399_got_int) {
+		panel->nt35399_got_int = 0;
+		client_data->activate_link(client_data); /* clears interrupt */
+	}
+
+	if (wait_event_timeout(nt35399_vsync_wait, panel->nt35399_got_int,
+				HZ/2) == 0)
+		printk(KERN_ERR "timeout waiting for VSYNC\n");
+
+	panel->nt35399_got_int = 0;
+	/* interrupt clears when screen dma starts */
+}
+
+static int nt35399_suspend(struct msm_panel_data *panel_data)
+{
+	struct panel_info *panel = container_of(panel_data, struct panel_info,
+						panel_data);
+	struct msm_mddi_client_data *client_data = panel->client_data;
+
+	struct msm_mddi_bridge_platform_data *bridge_data =
+		client_data->private_client_data;
+	int ret;
+
+	ret = bridge_data->uninit(bridge_data, client_data);
+	if (ret) {
+		printk(KERN_INFO "mddi nt35399 client: non zero return from "
+			"uninit\n");
+		return ret;
+	}
+	client_data->suspend(client_data);
+	return 0;
+}
+
+static int nt35399_resume(struct msm_panel_data *panel_data)
+{
+	struct panel_info *panel = container_of(panel_data, struct panel_info,
+						panel_data);
+	struct msm_mddi_client_data *client_data = panel->client_data;
+
+	struct msm_mddi_bridge_platform_data *bridge_data =
+		client_data->private_client_data;
+	int ret;
+
+	client_data->resume(client_data);
+	ret = bridge_data->init(bridge_data, client_data);
+	if (ret)
+		return ret;
+	return 0;
+}
+
+static int nt35399_blank(struct msm_panel_data *panel_data)
+{
+	struct panel_info *panel = container_of(panel_data, struct panel_info,
+						panel_data);
+	struct msm_mddi_client_data *client_data = panel->client_data;
+	struct msm_mddi_bridge_platform_data *bridge_data =
+		client_data->private_client_data;
+
+	return bridge_data->blank(bridge_data, client_data);
+}
+
+static int nt35399_unblank(struct msm_panel_data *panel_data)
+{
+	struct panel_info *panel = container_of(panel_data, struct panel_info,
+						panel_data);
+	struct msm_mddi_client_data *client_data = panel->client_data;
+	struct msm_mddi_bridge_platform_data *bridge_data =
+		client_data->private_client_data;
+
+	return bridge_data->unblank(bridge_data, client_data);
+}
+
+irqreturn_t nt35399_vsync_interrupt(int irq, void *data)
+{
+	struct panel_info *panel = data;
+
+	panel->nt35399_got_int = 1;
+
+	if (panel->fb_callback) {
+		panel->fb_callback->func(panel->fb_callback);
+		panel->fb_callback = NULL;
+	}
+
+	wake_up(&nt35399_vsync_wait);
+
+	return IRQ_HANDLED;
+}
+
+static int setup_vsync(struct panel_info *panel, int init)
+{
+	int ret;
+	int gpio = 97;
+	unsigned int irq;
+
+	if (!init) {
+		ret = 0;
+		goto uninit;
+	}
+	ret = gpio_request(gpio, "vsync");
+	if (ret)
+		goto err_request_gpio_failed;
+
+	ret = gpio_direction_input(gpio);
+	if (ret)
+		goto err_gpio_direction_input_failed;
+
+	ret = irq = gpio_to_irq(gpio);
+	if (ret < 0)
+		goto err_get_irq_num_failed;
+
+	ret = request_irq(irq, nt35399_vsync_interrupt, IRQF_TRIGGER_RISING,
+			  "vsync", panel);
+	if (ret)
+		goto err_request_irq_failed;
+
+	printk(KERN_INFO "vsync on gpio %d now %d\n",
+	       gpio, gpio_get_value(gpio));
+	return 0;
+
+uninit:
+	free_irq(gpio_to_irq(gpio), panel->client_data);
+err_request_irq_failed:
+err_get_irq_num_failed:
+err_gpio_direction_input_failed:
+	gpio_free(gpio);
+err_request_gpio_failed:
+	return ret;
+}
+
+static int mddi_nt35399_probe(struct platform_device *pdev)
+{
+	struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
+	struct msm_mddi_bridge_platform_data *bridge_data =
+		client_data->private_client_data;
+
+	int ret;
+
+	struct panel_info *panel = kzalloc(sizeof(struct panel_info),
+					   GFP_KERNEL);
+
+	printk(KERN_DEBUG "%s: enter.\n", __func__);
+
+	if (!panel)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, panel);
+
+	ret = setup_vsync(panel, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "mddi_nt35399_setup_vsync failed\n");
+		return ret;
+	}
+
+	panel->client_data = client_data;
+	panel->panel_data.suspend = nt35399_suspend;
+	panel->panel_data.resume = nt35399_resume;
+	panel->panel_data.wait_vsync = nt35399_wait_vsync;
+	panel->panel_data.request_vsync = nt35399_request_vsync;
+	panel->panel_data.blank = nt35399_blank;
+	panel->panel_data.unblank = nt35399_unblank;
+	panel->panel_data.fb_data = &bridge_data->fb_data;
+	panel->panel_data.caps = 0;
+
+	panel->pdev.name = "msm_panel";
+	panel->pdev.id = pdev->id;
+	panel->pdev.resource = client_data->fb_resource;
+	panel->pdev.num_resources = 1;
+	panel->pdev.dev.platform_data = &panel->panel_data;
+
+	if (bridge_data->init)
+		bridge_data->init(bridge_data, client_data);
+
+	platform_device_register(&panel->pdev);
+
+	return 0;
+}
+
+static int mddi_nt35399_remove(struct platform_device *pdev)
+{
+	struct panel_info *panel = platform_get_drvdata(pdev);
+
+	setup_vsync(panel, 0);
+	kfree(panel);
+	return 0;
+}
+
+static struct platform_driver mddi_client_0bda_8a47 = {
+	.probe = mddi_nt35399_probe,
+	.remove = mddi_nt35399_remove,
+	.driver = { .name = "mddi_c_0bda_8a47" },
+};
+
+static int __init mddi_client_nt35399_init(void)
+{
+	return platform_driver_register(&mddi_client_0bda_8a47);
+}
+
+module_init(mddi_client_nt35399_init);
+
diff --git a/drivers/video/msm/mddi_client_renesas_R61408.c b/drivers/video/msm/mddi_client_renesas_R61408.c
deleted file mode 100644
index 1e001b4..0000000
--- a/drivers/video/msm/mddi_client_renesas_R61408.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2008 HTC Corporation.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/wakelock.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <mach/msm_fb.h>
-#include <mach/debug_display.h>
-
-static DECLARE_WAIT_QUEUE_HEAD(renesas_vsync_wait);
-
-struct panel_info {
-	struct msm_mddi_client_data *client_data;
-	struct platform_device pdev;
-	struct msm_panel_data panel_data;
-	struct msmfb_callback *renesas_callback;
-	struct wake_lock idle_lock;
-	int renesas_got_int;
-	int vsync_gpio;
-};
-
-static struct platform_device mddi_renesas_backlight = {
-	.name = "renesas_backlight",
-	.id = 0,
-};
-
-static void renesas_request_vsync(struct msm_panel_data *panel_data,
-				  struct msmfb_callback *callback)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	panel->renesas_callback = callback;
-	if (panel->renesas_got_int) {
-		panel->renesas_got_int = 0;
-		client_data->activate_link(client_data);
-	}
-}
-
-static void renesas_clear_vsync(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	client_data->activate_link(client_data);
-}
-
-static void renesas_wait_vsync(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	if (panel->renesas_got_int) {
-		panel->renesas_got_int = 0;
-		client_data->activate_link(client_data); /* clears interrupt */
-	}
-	if (wait_event_timeout(renesas_vsync_wait, panel->renesas_got_int,
-				HZ/2) == 0)
-		PR_DISP_ERR("timeout waiting for VSYNC\n");
-	panel->renesas_got_int = 0;
-	/* interrupt clears when screen dma starts */
-}
-
-static int renesas_suspend(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	int ret;
-
-	wake_lock(&panel->idle_lock);
-	ret = bridge_data->uninit(bridge_data, client_data);
-	wake_unlock(&panel->idle_lock);
-	if (ret) {
-		PR_DISP_INFO("mddi renesas client: non zero return from "
-			"uninit\n");
-		return ret;
-	}
-	client_data->suspend(client_data);
-	return 0;
-}
-
-static int renesas_resume(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	int ret;
-
-	wake_lock(&panel->idle_lock);
-	client_data->resume(client_data);
-	wake_unlock(&panel->idle_lock);
-	ret = bridge_data->init(bridge_data, client_data);
-	if (ret)
-		return ret;
-	return 0;
-}
-
-static int renesas_blank(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-
-	return bridge_data->blank(bridge_data, client_data);
-}
-
-static int renesas_unblank(struct msm_panel_data *panel_data)
-{
-	struct panel_info *panel = container_of(panel_data, struct panel_info,
-						panel_data);
-	struct msm_mddi_client_data *client_data = panel->client_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-
-	return bridge_data->unblank(bridge_data, client_data);
-}
-
-static irqreturn_t renesas_vsync_interrupt(int irq, void *data)
-{
-	struct panel_info *panel = data;
-
-	panel->renesas_got_int = 1;
-	if (panel->renesas_callback) {
-		panel->renesas_callback->func(panel->renesas_callback);
-		panel->renesas_callback = 0;
-	}
-	wake_up(&renesas_vsync_wait);
-	return IRQ_HANDLED;
-}
-
-static int setup_vsync(struct panel_info *panel,
-		       int init)
-{
-	int ret;
-	int gpio = panel->vsync_gpio;
-	unsigned int irq;
-
-	if (!init) {
-		ret = 0;
-		goto uninit;
-	}
-	ret = gpio_request(gpio, "vsync");
-	if (ret)
-		goto err_request_gpio_failed;
-
-	ret = gpio_direction_input(gpio);
-	if (ret)
-		goto err_gpio_direction_input_failed;
-
-	ret = irq = gpio_to_irq(gpio);
-	if (ret < 0)
-		goto err_get_irq_num_failed;
-
-	register_gpio_int_mask(gpio, 1);
-
-	ret = request_irq(irq, renesas_vsync_interrupt, IRQF_TRIGGER_RISING,
-			  "vsync", panel);
-	if (ret)
-		goto err_request_irq_failed;
-	PR_DISP_INFO("vsync on gpio %d now %d\n",
-	       gpio, gpio_get_value(gpio));
-	return 0;
-
-uninit:
-	free_irq(gpio_to_irq(gpio), panel);
-err_request_irq_failed:
-err_get_irq_num_failed:
-err_gpio_direction_input_failed:
-	gpio_free(gpio);
-err_request_gpio_failed:
-	return ret;
-}
-
-static int mddi_renesas_probe(struct platform_device *pdev)
-{
-	int ret;
-	struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
-	struct msm_mddi_bridge_platform_data *bridge_data =
-		client_data->private_client_data;
-	struct panel_data *panel_data = &bridge_data->panel_conf;
-	struct panel_info *panel =
-		kzalloc(sizeof(struct panel_info), GFP_KERNEL);
-
-	if (!panel)
-		return -ENOMEM;
-	platform_set_drvdata(pdev, panel);
-
-	PR_DISP_DEBUG("%s\n", __func__);
-
-	mddi_renesas_backlight.dev.platform_data = client_data;
-	platform_device_register(&mddi_renesas_backlight);
-
-	if (panel_data->vsync_gpio == 0)
-#if defined(CONFIG_ARCH_MSM7X30)
-		panel->vsync_gpio = 30;
-#else
-		panel->vsync_gpio = 98;
-#endif
-	else
-		panel->vsync_gpio = panel_data->vsync_gpio;
-
-	ret = setup_vsync(panel, 1);
-	if (ret) {
-		dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n");
-		return ret;
-	}
-	panel->client_data = client_data;
-	panel->panel_data.suspend = renesas_suspend;
-	panel->panel_data.resume = renesas_resume;
-	panel->panel_data.wait_vsync = renesas_wait_vsync;
-	panel->panel_data.request_vsync = renesas_request_vsync;
-	panel->panel_data.clear_vsync = renesas_clear_vsync;
-	panel->panel_data.blank = renesas_blank;
-	panel->panel_data.unblank = renesas_unblank;
-	panel->panel_data.fb_data =  &bridge_data->fb_data;
-	panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
-	panel->pdev.name = "msm_panel";
-	panel->pdev.id = pdev->id;
-	panel->pdev.resource = client_data->fb_resource;
-	panel->pdev.num_resources = 1;
-	panel->pdev.dev.platform_data = &panel->panel_data;
-	platform_device_register(&panel->pdev);
-	wake_lock_init(&panel->idle_lock, WAKE_LOCK_IDLE, "renesas_idle_lock");
-
-	return 0;
-}
-
-static int mddi_renesas_remove(struct platform_device *pdev)
-{
-	struct panel_info *panel = platform_get_drvdata(pdev);
-
-	setup_vsync(panel, 0);
-	kfree(panel);
-	return 0;
-}
-
-static struct platform_driver mddi_client_b9f6_61408 = {
-	.probe = mddi_renesas_probe,
-	.remove = mddi_renesas_remove,
-	.driver = { .name = "mddi_renesas_b9f6_61408" },
-};
-
-static int __init mddi_client_renesas_init(void)
-{
-	platform_driver_register(&mddi_client_b9f6_61408);
-	return 0;
-}
-
-module_init(mddi_client_renesas_init);
-
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
index 2c8d73b..8868781 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -21,9 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <mach/msm_fb.h>
-#include <mach/debug_display.h>
 
 
 #define LCD_CONTROL_BLOCK_BASE 0x110000
@@ -61,6 +59,7 @@
 	struct msm_panel_data panel_data;
 	struct msmfb_callback *toshiba_callback;
 	int toshiba_got_int;
+	int irq;
 };
 
 
@@ -97,8 +96,9 @@
 		panel->toshiba_got_int = 0;
 		client_data->activate_link(client_data); /* clears interrupt */
 	}
-	if (wait_event_timeout(toshiba_vsync_wait, panel->toshiba_got_int, HZ/2) == 0)
-		PR_DISP_ERR("timeout waiting for VSYNC\n");
+	if (wait_event_timeout(toshiba_vsync_wait, panel->toshiba_got_int,
+				HZ/2) == 0)
+		printk(KERN_ERR "timeout waiting for VSYNC\n");
 	panel->toshiba_got_int = 0;
 	/* interrupt clears when screen dma starts */
 }
@@ -115,7 +115,7 @@
 
 	ret = bridge_data->uninit(bridge_data, client_data);
 	if (ret) {
-		PR_DISP_INFO("mddi toshiba client: non zero return from "
+		printk(KERN_INFO "mddi toshiba client: non zero return from "
 			"uninit\n");
 		return ret;
 	}
@@ -175,47 +175,6 @@
 	return IRQ_HANDLED;
 }
 
-static int setup_vsync(struct panel_info *panel,
-		       int init)
-{
-	int ret;
-	int gpio = 97;
-	unsigned int irq;
-
-	if (!init) {
-		ret = 0;
-		goto uninit;
-	}
-	ret = gpio_request(gpio, "vsync");
-	if (ret)
-		goto err_request_gpio_failed;
-
-	ret = gpio_direction_input(gpio);
-	if (ret)
-		goto err_gpio_direction_input_failed;
-
-	ret = irq = gpio_to_irq(gpio);
-	if (ret < 0)
-		goto err_get_irq_num_failed;
-
-	ret = request_irq(irq, toshiba_vsync_interrupt, IRQF_TRIGGER_RISING,
-			  "vsync", panel);
-	if (ret)
-		goto err_request_irq_failed;
-	PR_DISP_INFO("vsync on gpio %d now %d\n",
-	       gpio, gpio_get_value(gpio));
-	return 0;
-
-uninit:
-	free_irq(gpio_to_irq(gpio), panel);
-err_request_irq_failed:
-err_get_irq_num_failed:
-err_gpio_direction_input_failed:
-	gpio_free(gpio);
-err_request_gpio_failed:
-	return ret;
-}
-
 static int mddi_toshiba_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -232,10 +191,16 @@
 	client_data->remote_write(client_data, GPIOSEL_VWAKEINT, GPIOSEL);
 	client_data->remote_write(client_data, INTMASK_VWAKEOUT, INTMASK);
 
-	ret = setup_vsync(panel, 1);
+	ret = platform_get_irq_byname(pdev, "vsync");
+	if (ret < 0)
+		goto err_plat_get_irq;
+
+	panel->irq = ret;
+	ret = request_irq(panel->irq, toshiba_vsync_interrupt,
+			  IRQF_TRIGGER_RISING, "vsync", panel);
 	if (ret) {
 		dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n");
-		return ret;
+		goto err_req_irq;
 	}
 
 	panel->client_data = client_data;
@@ -258,13 +223,19 @@
 	platform_device_register(&panel->pdev);
 
 	return 0;
+
+err_req_irq:
+err_plat_get_irq:
+	kfree(panel);
+	return ret;
 }
 
 static int mddi_toshiba_remove(struct platform_device *pdev)
 {
 	struct panel_info *panel = platform_get_drvdata(pdev);
 
-	setup_vsync(panel, 0);
+	platform_set_drvdata(pdev, NULL);
+	free_irq(panel->irq, panel);
 	kfree(panel);
 	return 0;
 }
diff --git a/drivers/video/msm/mddi_ext.c b/drivers/video/msm/mddi_ext.c
new file mode 100644
index 0000000..dc79fed
--- /dev/null
+++ b/drivers/video/msm/mddi_ext.c
@@ -0,0 +1,354 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "msm_fb.h"
+#include "mddihosti.h"
+
+static int mddi_ext_probe(struct platform_device *pdev);
+static int mddi_ext_remove(struct platform_device *pdev);
+
+static int mddi_ext_off(struct platform_device *pdev);
+static int mddi_ext_on(struct platform_device *pdev);
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+
+static int mddi_ext_suspend(struct platform_device *pdev, pm_message_t state);
+static int mddi_ext_resume(struct platform_device *pdev);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mddi_ext_early_suspend(struct early_suspend *h);
+static void mddi_ext_early_resume(struct early_suspend *h);
+#endif
+
+static int mddi_ext_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int mddi_ext_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+
+static int mddi_ext_runtime_idle(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: idling...\n");
+	return 0;
+}
+static struct dev_pm_ops mddi_ext_dev_pm_ops = {
+	.runtime_suspend = mddi_ext_runtime_suspend,
+	.runtime_resume = mddi_ext_runtime_resume,
+	.runtime_idle = mddi_ext_runtime_idle,
+};
+
+static struct platform_driver mddi_ext_driver = {
+	.probe = mddi_ext_probe,
+	.remove = mddi_ext_remove,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+#ifdef CONFIG_PM
+	.suspend = mddi_ext_suspend,
+	.resume = mddi_ext_resume,
+#endif
+#endif
+	.resume_early = NULL,
+	.resume = NULL,
+	.shutdown = NULL,
+	.driver = {
+		.name = "mddi_ext",
+		.pm = &mddi_ext_dev_pm_ops,
+		   },
+};
+
+static struct clk *mddi_ext_clk;
+static struct clk *mddi_ext_pclk;
+static struct mddi_platform_data *mddi_ext_pdata;
+
+extern int int_mddi_ext_flag;
+
+static int mddi_ext_off(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	ret = panel_next_off(pdev);
+	mddi_host_stop_ext_display();
+	pm_runtime_put(&pdev->dev);
+	return ret;
+}
+
+static int mddi_ext_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	u32 clk_rate;
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+	pm_runtime_get(&pdev->dev);
+	clk_rate = mfd->fbi->var.pixclock;
+	clk_rate = min(clk_rate, mfd->panel_info.clk_max);
+
+	if (mddi_ext_pdata &&
+	    mddi_ext_pdata->mddi_sel_clk &&
+	    mddi_ext_pdata->mddi_sel_clk(&clk_rate))
+		printk(KERN_ERR
+			  "%s: can't select mddi io clk targate rate = %d\n",
+			  __func__, clk_rate);
+
+	clk_rate = clk_round_rate(mddi_ext_clk, clk_rate);
+	if (clk_set_rate(mddi_ext_clk, clk_rate) < 0)
+		printk(KERN_ERR "%s: clk_set_rate failed\n",
+			__func__);
+
+	mddi_host_start_ext_display();
+	ret = panel_next_on(pdev);
+
+	return ret;
+}
+
+static int mddi_ext_resource_initialized;
+
+static int mddi_ext_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct platform_device *mdp_dev = NULL;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc;
+	resource_size_t size ;
+	u32 clk_rate;
+
+	if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
+		mddi_ext_pdata = pdev->dev.platform_data;
+		mddi_ext_clk = clk_get(&pdev->dev, "core_clk");
+		if (IS_ERR(mddi_ext_clk)) {
+			pr_err("can't find emdh_clk\n");
+			return PTR_ERR(mddi_ext_clk);
+		}
+		clk_prepare_enable(mddi_ext_clk);
+
+		mddi_ext_pclk = clk_get(&pdev->dev, "iface_clk");
+		if (IS_ERR(mddi_ext_pclk))
+			mddi_ext_pclk = NULL;
+		else
+			clk_prepare_enable(mddi_ext_pclk);
+
+		size =  resource_size(&pdev->resource[0]);
+		msm_emdh_base = ioremap(pdev->resource[0].start, size);
+
+		MSM_FB_INFO("external mddi base address = 0x%x\n",
+				pdev->resource[0].start);
+
+		if (unlikely(!msm_emdh_base))
+			return -ENOMEM;
+
+		mddi_ext_resource_initialized = 1;
+		return 0;
+	}
+
+	if (!mddi_ext_resource_initialized)
+		return -EPERM;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	mdp_dev = platform_device_alloc("mdp", pdev->id);
+	if (!mdp_dev)
+		return -ENOMEM;
+
+	/*
+	 * link to the latest pdev
+	 */
+	mfd->pdev = mdp_dev;
+	mfd->dest = DISPLAY_EXT_MDDI;
+
+	/*
+	 * alloc panel device data
+	 */
+	if (platform_device_add_data
+	    (mdp_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		printk(KERN_ERR "mddi_ext_probe: platform_device_add_data failed!\n");
+		platform_device_put(mdp_dev);
+		return -ENOMEM;
+	}
+	/*
+	 * data chain
+	 */
+	pdata = mdp_dev->dev.platform_data;
+	pdata->on = mddi_ext_on;
+	pdata->off = mddi_ext_off;
+	pdata->next = pdev;
+
+	/*
+	 * get/set panel specific fb info
+	 */
+	mfd->panel_info = pdata->panel_info;
+	mfd->fb_imgType = MDP_RGB_565;
+
+	clk_rate = mfd->panel_info.clk_max;
+	if (mddi_ext_pdata &&
+	    mddi_ext_pdata->mddi_sel_clk &&
+	    mddi_ext_pdata->mddi_sel_clk(&clk_rate))
+			printk(KERN_ERR
+			  "%s: can't select mddi io clk targate rate = %d\n",
+			  __func__, clk_rate);
+
+	if (clk_set_max_rate(mddi_ext_clk, clk_rate) < 0)
+		printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__);
+	mfd->panel_info.clk_rate = mfd->panel_info.clk_min;
+
+	/*
+	 * set driver data
+	 */
+	platform_set_drvdata(mdp_dev, mfd);
+	rc = pm_runtime_set_active(&pdev->dev);
+	if (rc < 0)
+		printk(KERN_ERR "pm_runtime: fail to set active\n");
+
+	rc = 0;
+	pm_runtime_enable(&pdev->dev);
+	/*
+	 * register in mdp driver
+	 */
+	rc = platform_device_add(mdp_dev);
+	if (rc)
+		goto mddi_ext_probe_err;
+
+	pdev_list[pdev_list_cnt++] = pdev;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	mfd->mddi_ext_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
+	mfd->mddi_ext_early_suspend.suspend = mddi_ext_early_suspend;
+	mfd->mddi_ext_early_suspend.resume = mddi_ext_early_resume;
+	register_early_suspend(&mfd->mddi_ext_early_suspend);
+#endif
+
+	return 0;
+
+mddi_ext_probe_err:
+	platform_device_put(mdp_dev);
+	return rc;
+}
+
+static int mddi_ext_is_in_suspend;
+
+static int mddi_ext_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	if (mddi_ext_is_in_suspend)
+		return 0;
+
+	mddi_ext_is_in_suspend = 1;
+
+	clk_disable_unprepare(mddi_ext_clk);
+	if (mddi_ext_pclk)
+		clk_disable_unprepare(mddi_ext_pclk);
+
+	disable_irq(INT_MDDI_EXT);
+
+	return 0;
+}
+
+static int mddi_ext_resume(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mddi_ext_is_in_suspend)
+		return 0;
+
+	mddi_ext_is_in_suspend = 0;
+	enable_irq(INT_MDDI_EXT);
+
+	clk_prepare_enable(mddi_ext_clk);
+	if (mddi_ext_pclk)
+		clk_prepare_enable(mddi_ext_pclk);
+
+	return 0;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mddi_ext_early_suspend(struct early_suspend *h)
+{
+	pm_message_t state;
+	struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
+							mddi_ext_early_suspend);
+
+	state.event = PM_EVENT_SUSPEND;
+	mddi_ext_suspend(mfd->pdev, state);
+}
+
+static void mddi_ext_early_resume(struct early_suspend *h)
+{
+	struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
+							mddi_ext_early_suspend);
+	mddi_ext_resume(mfd->pdev);
+}
+#endif
+
+static int mddi_ext_remove(struct platform_device *pdev)
+{
+	pm_runtim_disable(&pdev->dev);
+	iounmap(msm_emdh_base);
+	return 0;
+}
+
+static int mddi_ext_register_driver(void)
+{
+	return platform_driver_register(&mddi_ext_driver);
+}
+
+static int __init mddi_ext_driver_init(void)
+{
+	int ret;
+
+	ret = mddi_ext_register_driver();
+	if (ret) {
+		printk(KERN_ERR "mddi_ext_register_driver() failed!\n");
+		return ret;
+	}
+	mddi_init();
+
+	return ret;
+}
+
+module_init(mddi_ext_driver_init);
diff --git a/drivers/video/msm/mddi_ext_lcd.c b/drivers/video/msm/mddi_ext_lcd.c
new file mode 100644
index 0000000..da79513
--- /dev/null
+++ b/drivers/video/msm/mddi_ext_lcd.c
@@ -0,0 +1,90 @@
+/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+
+static int mddi_ext_lcd_on(struct platform_device *pdev);
+static int mddi_ext_lcd_off(struct platform_device *pdev);
+
+static int mddi_ext_lcd_on(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int mddi_ext_lcd_off(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int __init mddi_ext_lcd_probe(struct platform_device *pdev)
+{
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mddi_ext_lcd_probe,
+	.driver = {
+		.name   = "extmddi_svga",
+	},
+};
+
+static struct msm_fb_panel_data mddi_ext_lcd_panel_data = {
+	.panel_info.xres = 800,
+	.panel_info.yres = 600,
+	.panel_info.mode2_xres = 0;
+	.panel_info.mode2_yres = 0;
+	.panel_info.mode2_bpp = 0;
+	.panel_info.type = EXT_MDDI_PANEL,
+	.panel_info.pdest = DISPLAY_1,
+	.panel_info.wait_cycle = 0,
+	.panel_info.bpp = 18,
+	.panel_info.fb_num = 2,
+	.panel_info.clk_rate = 122880000,
+	.panel_info.clk_min  = 120000000,
+	.panel_info.clk_max  = 125000000,
+	.on = mddi_ext_lcd_on,
+	.off = mddi_ext_lcd_off,
+};
+
+static struct platform_device this_device = {
+	.name   = "extmddi_svga",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &mddi_ext_lcd_panel_data,
+	}
+};
+
+static int __init mddi_ext_lcd_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	ret = platform_driver_register(&this_driver);
+	if (!ret) {
+		pinfo = &mddi_ext_lcd_panel_data.panel_info;
+		pinfo->lcd.vsync_enable = FALSE;
+		pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
+
+		ret = platform_device_register(&this_device);
+		if (ret)
+			platform_driver_unregister(&this_driver);
+	}
+
+	return ret;
+}
+
+module_init(mddi_ext_lcd_init);
diff --git a/drivers/video/msm/mddi_himax_cabc.c b/drivers/video/msm/mddi_himax_cabc.c
deleted file mode 100644
index 23db904..0000000
--- a/drivers/video/msm/mddi_himax_cabc.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2010 HTC Corporation.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#include <linux/module.h>
-#include <linux/leds.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <mach/msm_fb.h>
-#include <linux/wakelock.h>
-#include <mach/htc_pwrsink.h>
-#include <mach/msm_panel.h>
-#include "mddi_client_eid.h"
-#include <mach/debug_display.h>
-
-enum bc_mode {
-	BC_OFF = 0,
-	BC_MANUAL,
-	BC_AUTO,
-	BC_MERGED,
-	BC_UNDEF,
-};
-
-enum cabc_mode {
-	CABC_OFF = 0,
-	CABC_UI,
-	CABC_STILL,
-	CABC_MOVING,
-	CABC_UNDEF,
-};
-
-#if 0
-#define B(s...) printk(s)
-#else
-#define B(s...) do {} while (0)
-#endif
-
-#define DEBUG 0
-
-static int g_brightness;
-static char *str_bc_mode[] = {"BC_OFF", "BC_MANUAL", "BC_AUTO", "BC_MERGED"};
-static char *str_cabc_mode[] = {"CABC_OFF", "CABC_USER_INTERFACE",
-				"CABC_STILL_IMAGE", "CABC_MOVING"};
-
-static ssize_t
-himax_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t
-himax_store(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count);
-
-struct cabc {
-	struct cabc_config *cabc_config;
-	struct led_classdev lcd_backlight;	/* user */
-	struct mutex lock;
-	struct mutex data_lock;
-	struct work_struct lcd_changed_work;	/* lcd backlight */
-	struct work_struct set_auto_work;
-	struct wake_lock wakelock;
-	struct workqueue_struct *cabc_queue;
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	struct early_suspend early_suspend;
-#endif
-	unsigned long status;
-	enum cabc_mode mode_cabc;
-	enum bc_mode mode_bc;
-};
-
-enum {
-	LS_STATE,
-	GATE_ON,
-	ENFORCE_ON,
-	SUSPEND,
-	AUTO_SETTING,
-	LS_SWITCH,
-};
-
-#define to_cabc(p, m) container_of(p, struct cabc, m)
-
-static inline
-struct msm_mddi_client_data *cabc_get_client(struct cabc *cabc)
-{
-	struct cabc_config *data = cabc->cabc_config;
-	return data->client;
-}
-
-static inline int cabc_shrink(struct cabc *cabc, int brightness)
-{
-	struct cabc_config *config = cabc->cabc_config;
-
-	if (config->shrink) {
-		if (brightness <= 102) {
-			if (brightness <= 30)
-				brightness = 8;
-			else
-				brightness = 123 * (brightness - 30) / 72 + 8;
-		} else
-			brightness = 124 * (brightness - 102) / 153 + 131;
-	}
-	return brightness;
-}
-
-static int
-himax_change_cabcmode(struct msm_mddi_client_data *client_data,
-		int mode, u8 dimming)
-{
-	PR_DISP_DEBUG("+%s, mode=%d, dimming=%d\n", __func__, mode, dimming);
-	return 0;
-}
-
-static int
-__set_brightness(struct cabc *cabc, int brightness, u8 dimming)
-{
-	struct msm_mddi_client_data *client_data = cabc_get_client(cabc);
-
-	int shrink_br;
-	/* no need to check brightness > LED_FULL, the led class
-	 * already does */
-	PR_DISP_INFO("brightness = %d, %s ls-(%s)\n",
-		brightness, str_bc_mode[cabc->mode_bc],
-		(test_bit(LS_STATE, &cabc->status) ? "on" : "off"));
-
-	mutex_lock(&cabc->data_lock);
-	if (cabc->cabc_config->shrink && cabc->cabc_config->shrink_br)
-		shrink_br = cabc->cabc_config->shrink_br(brightness);
-	else
-		shrink_br = cabc_shrink(cabc, brightness);
-	client_data->remote_write(client_data, (u8)shrink_br, 0x94);
-	g_brightness = brightness;
-	mutex_unlock(&cabc->data_lock);
-	return 0;
-}
-
-#if DEBUG
-static void cabc_dump(unsigned long status)
-{
-	if (test_bit(LS_STATE, &status))
-		B("LS ");
-	if (test_bit(GATE_ON, &status))
-		B("GATE ");
-	if (test_bit(ENFORCE_ON, &status))
-		B("EN_ON ");
-	if (test_bit(SUSPEND, &status))
-		B("SUSPEND ");
-	if (test_bit(AUTO_SETTING, &status))
-		B("AUTO_SETTING ");
-	if (test_bit(LS_SWITCH, &status))
-		B("SWITCH ");
-	B("\n");
-}
-#endif
-
-static void cabc_lcd_work(struct work_struct *work)
-{
-	struct cabc *cabc = to_cabc(work, lcd_changed_work);
-	struct led_classdev *led_cdev = &cabc->lcd_backlight;
-	char event_string[30];
-	char *envp[] = { event_string, NULL };
-
-	/* check again, if we are doing early_suspend, but the check
-	 * already passed. */
-	if ((test_bit(SUSPEND, &cabc->status) == 0) &&
-	    (test_bit(ENFORCE_ON, &cabc->status) == 0)) {
-		if (led_cdev->brightness >= 0 && led_cdev->brightness <= 255)
-			__set_brightness(cabc, led_cdev->brightness, 1U << 3);
-
-		sprintf(event_string, "CABC_BRIGHTNESS=%d",
-			led_cdev->brightness);
-		kobject_uevent_env(&led_cdev->dev->kobj, KOBJ_CHANGE, envp);
-	}
-
-	wake_unlock(&cabc->wakelock);
-}
-
-static void
-himax_set_brightness(struct led_classdev *led_cdev,
-		       enum led_brightness brightness)
-{
-	struct cabc *cabc = to_cabc(led_cdev, lcd_backlight);
-
-	B(KERN_DEBUG "%s\n", __func__);
-
-	if ((test_bit(SUSPEND, &cabc->status))  ||
-	    (test_bit(ENFORCE_ON, &cabc->status)))
-		return;
-
-	wake_lock(&cabc->wakelock);
-	queue_work(cabc->cabc_queue, &cabc->lcd_changed_work);
-	wake_unlock(&cabc->wakelock);
-}
-
-static enum led_brightness
-himax_get_brightness(struct led_classdev *led_cdev)
-{
-	B(KERN_DEBUG "%s\n", __func__);
-
-	return led_cdev->brightness;
-}
-
-/*
- * for consistent with android UI,
- * 1: turn on, LABC
- * 0: turn off, Manual
- * */
-static void cabc_auto_work(struct work_struct *work)
-{
-	struct cabc *cabc = to_cabc(work, set_auto_work);
-	int on;
-
-	on = test_bit(LS_SWITCH, &cabc->status);
-	/* update on success */
-	mutex_lock(&cabc->data_lock);
-	if (on) {
-		cabc->mode_bc = BC_MERGED;
-		cabc->mode_cabc = CABC_MOVING;
-		set_bit(LS_STATE, &cabc->status);
-		mutex_unlock(&cabc->data_lock);
-	} else {
-		clear_bit(LS_STATE, &cabc->status);
-		cabc->mode_bc = BC_MANUAL;
-		cabc->mode_cabc = CABC_OFF;
-		mutex_unlock(&cabc->data_lock);
-	}
-	clear_bit(AUTO_SETTING, &cabc->status);
-}
-
-static int
-cabc_bl_handle(struct platform_device *pdev, int brightness)
-{
-	struct cabc *cabc = platform_get_drvdata(pdev);
-	struct led_classdev *lcd_cdev;
-
-	if (unlikely(cabc == NULL)) {
-			PR_DISP_ERR("%s: do not have cabc data\n", __func__);
-			return -ENOENT;
-	}
-
-	PR_DISP_DEBUG("turn %s backlight.\n",
-					brightness == LED_FULL ? "on" : "off");
-
-	lcd_cdev = &cabc->lcd_backlight;
-	wake_lock(&cabc->wakelock);
-
-	if (brightness != LED_FULL) {
-	/* enter screen off */
-	} else {
-		__set_brightness(cabc, (g_brightness >= 0 && g_brightness <= LED_FULL)?
-		    g_brightness : LED_FULL, 0);
-	}
-
-	wake_unlock(&cabc->wakelock);
-	return 0;
-}
-
-static int
-himax_auto_backlight(struct cabc *cabc, int on)
-{
-	B(KERN_DEBUG "%s: %s\n", __func__, on ? "ON" : "OFF");
-
-	if (test_bit(LS_STATE, &cabc->status) == on)
-		return 0;
-
-	if (on)
-		set_bit(LS_SWITCH, &cabc->status);
-	else
-		clear_bit(LS_SWITCH, &cabc->status);
-
-	if (test_bit(AUTO_SETTING, &cabc->status) == 0) {
-		set_bit(AUTO_SETTING, &cabc->status);
-
-		/* if we are not in suspend mode, we can
-		 * do it right away */
-		if (test_bit(SUSPEND, &cabc->status) == 0)
-			cabc_auto_work(&cabc->set_auto_work);
-	}
-
-	return 0;
-}
-
-#define CABC_ATTR(name) __ATTR(name, 0644, himax_show, himax_store)
-
-enum {
-	CABC_MODE = 0,
-	BC_MODE,
-	LIGHT_SENSOR,
-	AUTO_BACKLIGHT,
-};
-
-static struct device_attribute cabc_attrs[] = {
-	CABC_ATTR(cabc_mode),
-	CABC_ATTR(bc_mode),
-	CABC_ATTR(light_sensor),
-	CABC_ATTR(auto),
-};
-
-static ssize_t
-himax_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int i = 0;
-	const ptrdiff_t off = attr - cabc_attrs;
-	struct led_classdev *led_cdev = dev_get_drvdata(dev);
-	struct cabc *cabc = to_cabc(led_cdev, lcd_backlight);
-
-	mutex_lock(&cabc->lock);
-	switch (off) {
-	case CABC_MODE:
-		i += scnprintf(buf + i, PAGE_SIZE - 1, "%s\n",
-				str_cabc_mode[cabc->mode_cabc]);
-		break;
-	case BC_MODE:
-		i += scnprintf(buf + i, PAGE_SIZE - 1, "%s\n",
-				str_bc_mode[cabc->mode_bc]);
-		break;
-	case AUTO_BACKLIGHT:
-		i += scnprintf(buf + i, PAGE_SIZE - 1, "%d\n",
-				test_bit(LS_STATE, &cabc->status));
-		break;
-	default:
-		i = -EINVAL;
-		break;
-	}
-	mutex_unlock(&cabc->lock);
-	return i;
-}
-
-static ssize_t
-himax_store(struct device *dev, struct device_attribute *attr,
-	      const char *buf, size_t count)
-{
-	int rc;
-	unsigned long res;
-	const ptrdiff_t off = attr - cabc_attrs;
-	struct led_classdev *led_cdev = dev_get_drvdata(dev);
-	struct cabc *cabc = to_cabc(led_cdev, lcd_backlight);
-	struct msm_mddi_client_data *client_data = cabc_get_client(cabc);
-
-	rc = strict_strtoul(buf, 10, &res);
-	if (rc) {
-		PR_DISP_ERR("invalid parameter, %s %d\n", buf, rc);
-		count = -EINVAL;
-		goto err_out;
-	}
-
-	mutex_lock(&cabc->lock);
-	switch (off) {
-	case CABC_MODE:
-		if (res >= CABC_OFF && res < CABC_UNDEF) {
-			cabc->mode_cabc = res;
-			cabc->cabc_config->change_cabcmode(client_data, res, 0x25);
-		}
-		break;
-	case BC_MODE:
-		if (res >= BC_OFF && res < BC_UNDEF)
-			cabc->mode_bc = res;
-		break;
-	case AUTO_BACKLIGHT:
-		if (himax_auto_backlight(cabc, !!res))
-			count = -EIO;
-		break;
-	default:
-		count = -EINVAL;
-		break;
-	}
-	mutex_unlock(&cabc->lock);
-err_out:
-	return count;
-}
-
-
-static int himax_cabc_probe(struct platform_device *pdev)
-{
-	int i, err;
-	struct cabc *cabc;
-	struct cabc_config *data;
-
-	B(KERN_DEBUG "%s\n", __func__);
-	cabc = kzalloc(sizeof(struct cabc), GFP_KERNEL);
-	if (!cabc)
-		return -ENOMEM;
-	platform_set_drvdata(pdev, cabc);
-
-	data = pdev->dev.platform_data;
-	if (data == NULL || !data->client) {
-		PR_DISP_ERR("No CABC config data\n");
-		err = -EINVAL;
-		goto err_client;
-	}
-	g_brightness = LED_FULL;
-	cabc->cabc_config = data;
-	cabc->cabc_config->bl_handle = cabc_bl_handle;
-	if (!cabc->cabc_config->change_cabcmode)
-		cabc->cabc_config->change_cabcmode = himax_change_cabcmode;
-
-	INIT_WORK(&cabc->lcd_changed_work, cabc_lcd_work);
-	INIT_WORK(&cabc->set_auto_work, cabc_auto_work);
-	mutex_init(&cabc->lock);
-	mutex_init(&cabc->data_lock);
-	cabc->cabc_queue = create_singlethread_workqueue("cabc_work_q");
-	wake_lock_init(&cabc->wakelock, WAKE_LOCK_IDLE, "cabc_present");
-
-
-	cabc->lcd_backlight.name = "lcd-backlight";
-	cabc->lcd_backlight.brightness_set = himax_set_brightness;
-	cabc->lcd_backlight.brightness_get = himax_get_brightness;
-	cabc->lcd_backlight.brightness = LED_FULL;
-	err = led_classdev_register(&pdev->dev, &cabc->lcd_backlight);
-	if (err)
-		goto err_register_lcd_bl;
-
-	for (i = 0; i < ARRAY_SIZE(cabc_attrs); i++) {
-		err = device_create_file(cabc->lcd_backlight.dev,
-					&cabc_attrs[i]);
-		if (err)
-			goto err_out;
-	}
-
-	return 0;
-
-err_out:
-	while (i--)
-		device_remove_file(&pdev->dev, &cabc_attrs[i]);
-
-err_register_lcd_bl:
-	led_classdev_unregister(&cabc->lcd_backlight);
-err_client:
-	kfree(cabc);
-	return err;
-}
-
-static struct platform_driver himax_cabc_driver = {
-	.probe = himax_cabc_probe,
-	.driver = { .name = "himax_cabc" },
-};
-
-static int __init himax_cabc_init(void)
-{
-	return platform_driver_register(&himax_cabc_driver);
-}
-
-module_init(himax_cabc_init);
diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/msm/mddi_hw.h
index 632fe70..47bb449 100644
--- a/drivers/video/msm/mddi_hw.h
+++ b/drivers/video/msm/mddi_hw.h
@@ -53,9 +53,9 @@
 #define MDDI_MF_CNT             0x0084
 #define MDDI_CURR_REV_PTR       0x0088
 #define MDDI_CORE_VER           0x008c
-#define MDDI_SF_LEN_CTL_REG	0x0094
-#define MDDI_PAD_IO_CTL		0x00a0
-#define MDDI_PAD_CAL		0x00a4
+#define MDDI_FIFO_ALLOC         0x0090
+#define MDDI_PAD_IO_CTL         0x00a0
+#define MDDI_PAD_CAL            0x00a4
 
 #define MDDI_INT_PRI_PTR_READ       0x0001
 #define MDDI_INT_SEC_PTR_READ       0x0002
@@ -115,7 +115,9 @@
 #define MDDI_CMD_LINK_ACTIVE         0x0900
 #define MDDI_CMD_PERIODIC_REV_ENCAP  0x0A00
 #define MDDI_CMD_FORCE_NEW_REV_PTR   0x0C00
-#define MDDI_CMD_SKEW_CALIBRATION    0x0D00
+
+
+
 #define MDDI_VIDEO_REV_PKT_SIZE              0x40
 #define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE  0x60
 #define MDDI_MAX_REV_PKT_SIZE                0x60
@@ -126,20 +128,16 @@
 /* MDP sends 256 pixel packets, so lower value hibernates more without
  * significantly increasing latency of waiting for next subframe */
 #define MDDI_HOST_BYTES_PER_SUBFRAME  0x3C00
-#if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM7X30)
+
+#if defined(CONFIG_MSM_MDP31) || defined(CONFIG_MSM_MDP40)
 #define MDDI_HOST_TA2_LEN       0x001a
+#define MDDI_HOST_REV_RATE_DIV  0x0004
 #else
 #define MDDI_HOST_TA2_LEN       0x000c
-#endif
-
-#if defined(CONFIG_ARCH_QSD8X50)
-#define MDDI_HOST_REV_RATE_DIV  0x0004
-#elif defined(CONFIG_ARCH_MSM7X30)
-#define MDDI_HOST_REV_RATE_DIV  0x0010
-#else
 #define MDDI_HOST_REV_RATE_DIV  0x0002
 #endif
 
+
 struct __attribute__((packed)) mddi_rev_packet {
 	uint16_t length;
 	uint16_t type;
@@ -295,12 +293,8 @@
 
 	uint16_t crc16;
 
-	union {
-		uint32_t reg_data;
-		uint32_t *reg_data_list;
-	} u;
-
-	uint16_t crc_data;
+	uint32_t register_data_list;
+	/* list of 4-byte register data values for/from client registers */
 };
 
 struct __attribute__((packed)) mddi_llentry {
@@ -317,7 +311,4 @@
 	} u;
 };
 
-extern int overlay_semaphore_lock(void);
-extern void overlay_semaphore_unlock(void);
-
 #endif
diff --git a/drivers/video/msm/mddi_orise.c b/drivers/video/msm/mddi_orise.c
new file mode 100644
index 0000000..fa48c75
--- /dev/null
+++ b/drivers/video/msm/mddi_orise.c
@@ -0,0 +1,128 @@
+/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+
+#define MDDI_ORISE_1_2 1
+#define write_client_reg(__X, __Y, __Z) {\
+	mddi_queue_register_write(__X, __Y, TRUE, 0);\
+}
+
+static int mddi_orise_lcd_on(struct platform_device *pdev);
+static int mddi_orise_lcd_off(struct platform_device *pdev);
+static int __init mddi_orise_probe(struct platform_device *pdev);
+static int __init mddi_orise_init(void);
+
+/* function used to turn on the display */
+static void mddi_orise_prim_lcd_init(void)
+{
+	write_client_reg(0x00110000, 0, TRUE);
+	mddi_wait(150);
+	write_client_reg(0x00290000, 0, TRUE);
+}
+
+static struct platform_driver this_driver = {
+	.driver = {
+		.name   = "mddi_orise",
+	},
+};
+
+static struct msm_fb_panel_data mddi_orise_panel_data = {
+	.on = mddi_orise_lcd_on,
+	.off = mddi_orise_lcd_off,
+};
+
+static struct platform_device this_device = {
+	.name	= "mddi_orise",
+	.id	= MDDI_ORISE_1_2,
+	.dev	= {
+		.platform_data = &mddi_orise_panel_data,
+	}
+};
+
+static int mddi_orise_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mddi_orise_prim_lcd_init();
+
+	return 0;
+}
+
+static int mddi_orise_lcd_off(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int __init mddi_orise_probe(struct platform_device *pdev)
+{
+	msm_fb_add_device(pdev);
+	return 0;
+}
+
+static int __init mddi_orise_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	u32 id;
+	ret = msm_fb_detect_client("mddi_orise");
+	if (ret == -ENODEV)
+		return 0;
+
+	if (ret) {
+		id = mddi_get_client_id();
+		if (((id >> 16) != 0xbe8d) || ((id & 0xffff) != 0x8031))
+			return 0;
+	}
+#endif
+	ret = platform_driver_probe(&this_driver, mddi_orise_probe);
+	if (!ret) {
+		pinfo = &mddi_orise_panel_data.panel_info;
+		pinfo->xres = 480;
+		pinfo->yres = 800;
+		MSM_FB_SINGLE_MODE_PANEL(pinfo);
+		pinfo->type = MDDI_PANEL;
+		pinfo->pdest = DISPLAY_1;
+		pinfo->mddi.is_type1 = TRUE;
+		pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
+		pinfo->wait_cycle = 0;
+		pinfo->bpp = 18;
+		pinfo->fb_num = 2;
+		pinfo->clk_rate = 192000000;
+		pinfo->clk_min = 192000000;
+		pinfo->clk_max = 192000000;
+		pinfo->lcd.rev = 2;
+		pinfo->lcd.vsync_enable = FALSE;
+		pinfo->lcd.refx100 = 6050;
+		pinfo->lcd.v_back_porch = 2;
+		pinfo->lcd.v_front_porch = 2;
+		pinfo->lcd.v_pulse_width = 105;
+		pinfo->lcd.hw_vsync_mode = TRUE;
+		pinfo->lcd.vsync_notifier_period = 0;
+
+		ret = platform_device_register(&this_device);
+		if (ret)
+			platform_driver_unregister(&this_driver);
+	}
+	return ret;
+}
+module_init(mddi_orise_init);
diff --git a/drivers/video/msm/mddi_prism.c b/drivers/video/msm/mddi_prism.c
new file mode 100644
index 0000000..ec2bf57
--- /dev/null
+++ b/drivers/video/msm/mddi_prism.c
@@ -0,0 +1,112 @@
+/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+
+static int prism_lcd_on(struct platform_device *pdev);
+static int prism_lcd_off(struct platform_device *pdev);
+
+static int prism_lcd_on(struct platform_device *pdev)
+{
+	/* Set the MDP pixel data attributes for Primary Display */
+	mddi_host_write_pix_attr_reg(0x00C3);
+
+	return 0;
+}
+
+static int prism_lcd_off(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int __devinit prism_probe(struct platform_device *pdev)
+{
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = prism_probe,
+	.driver = {
+		.name   = "mddi_prism_wvga",
+	},
+};
+
+static struct msm_fb_panel_data prism_panel_data = {
+	.on = prism_lcd_on,
+	.off = prism_lcd_off,
+};
+
+static struct platform_device this_device = {
+	.name   = "mddi_prism_wvga",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &prism_panel_data,
+	}
+};
+
+static int __init prism_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	u32 id;
+
+	ret = msm_fb_detect_client("mddi_prism_wvga");
+	if (ret == -ENODEV)
+		return 0;
+
+	if (ret) {
+		id = mddi_get_client_id();
+
+		if (((id >> 16) != 0x4474) || ((id & 0xffff) == 0x8960))
+			return 0;
+	}
+#endif
+	ret = platform_driver_register(&this_driver);
+	if (!ret) {
+		pinfo = &prism_panel_data.panel_info;
+		pinfo->xres = 800;
+		pinfo->yres = 480;
+		MSM_FB_SINGLE_MODE_PANEL(pinfo);
+		pinfo->type = MDDI_PANEL;
+		pinfo->pdest = DISPLAY_1;
+		pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
+		pinfo->wait_cycle = 0;
+		pinfo->mddi.is_type1 = TRUE;
+		pinfo->bpp = 18;
+		pinfo->fb_num = 2;
+		pinfo->clk_rate = 153600000;
+		pinfo->clk_min = 140000000;
+		pinfo->clk_max = 160000000;
+		pinfo->lcd.vsync_enable = TRUE;
+		pinfo->lcd.refx100 = 6050;
+		pinfo->lcd.v_back_porch = 23;
+		pinfo->lcd.v_front_porch = 20;
+		pinfo->lcd.v_pulse_width = 105;
+		pinfo->lcd.hw_vsync_mode = TRUE;
+		pinfo->lcd.vsync_notifier_period = 0;
+
+		ret = platform_device_register(&this_device);
+		if (ret)
+			platform_driver_unregister(&this_driver);
+	}
+
+	return ret;
+}
+
+module_init(prism_init);
diff --git a/drivers/video/msm/mddi_quickvx.c b/drivers/video/msm/mddi_quickvx.c
new file mode 100644
index 0000000..95e7d41
--- /dev/null
+++ b/drivers/video/msm/mddi_quickvx.c
@@ -0,0 +1,719 @@
+/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <mach/pmic.h>
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+
+/* WVGA Primary Display */
+#define MDDI_QUICKVX_1_2		1
+/* MDDI Manufacturer Code */
+#define QUICKVX_MDDI_MFR_CODE	0xc583
+/* MDDI Product Code */
+#define QUICKVX_MDDI_PRD_CODE	0x5800
+
+/* Register Address Maps */
+/* MDDI Address Anti-fuse values for bits [31:22] */
+#define QUICKVX_ADDR_31_22_AF	(0X000 << 22)
+
+/* MDDI Address Maps */
+/* VEE Block Address Base */
+#define QUICKVX_VEE_BASE		(QUICKVX_ADDR_31_22_AF | 0x00000000)
+/* SPI Block Address Base */
+#define QUICKVX_SPI_BASE		(QUICKVX_ADDR_31_22_AF | 0x00010000)
+/* Clock and Reset (CAR) Address Base */
+#define QUICKVX_CAR_BASE		(QUICKVX_ADDR_31_22_AF | 0x00020000)
+/* Register Control Block (RCB) Address Base */
+#define QUICKVX_RCB_BASE		(QUICKVX_ADDR_31_22_AF | 0x00030000)
+/* Cellular RAM Address Base */
+#define QUICKVX_CELLRAM_BASE	(QUICKVX_ADDR_31_22_AF | 0x00100000)
+/* FB through A2F Address Base */
+#define QUICKVX_FB_A2F_BASE		(QUICKVX_ADDR_31_22_AF | 0x00200000)
+
+
+/***************************************************
+ * Common Registers in Register Control Block (RCB) Registers
+ ***************************************************/
+ /* CellRAM Configuration RCR Register */
+#define QUICKVX_RCB_RCR_REG			(QUICKVX_RCB_BASE | 0x00000000)
+/* Image Effect Register */
+#define QUICKVX_RCB_IER_REG			(QUICKVX_RCB_BASE | 0x00000004)
+/* Row Number Register */
+#define QUICKVX_RCB_ROWNUM_REG		(QUICKVX_RCB_BASE | 0x00000008)
+/* TCON Timing0 Register */
+#define QUICKVX_RCB_TCON0_REG		(QUICKVX_RCB_BASE | 0x0000000C)
+/* TCON Timing1 Register */
+#define QUICKVX_RCB_TCON1_REG		(QUICKVX_RCB_BASE | 0x00000010)
+/* TCON Timing2 Register */
+#define QUICKVX_RCB_TCON2_REG		(QUICKVX_RCB_BASE | 0x00000014)
+/* PWM Control Register */
+#define QUICKVX_RCB_PWMC_REG		(QUICKVX_RCB_BASE | 0x00000018)
+/* PWM Width Register */
+#define QUICKVX_RCB_PWMW_REG		(QUICKVX_RCB_BASE | 0x0000001C)
+/* VEE Configuration Register */
+#define QUICKVX_RCB_VEECONF_REG		(QUICKVX_RCB_BASE | 0x00000020)
+/* CellRAM Configuration BCR Register */
+#define QUICKVX_RCB_CELLBCR_REG		(QUICKVX_RCB_BASE | 0x00000024)
+/* CellRAM Configuration Control Register */
+#define QUICKVX_RCB_CELLCC_REG		(QUICKVX_RCB_BASE | 0x00000028)
+/* Use Case Register */
+#define QUICKVX_RCB_USECASE_REG		(QUICKVX_RCB_BASE | 0x00000100)
+/* Video Parameter Register */
+#define QUICKVX_RCB_VPARM_REG		(QUICKVX_RCB_BASE | 0x00000104)
+/* MDDI Client Wake-up Register */
+#define QUICKVX_RCB_MCW_REG			(QUICKVX_RCB_BASE | 0x00000108)
+/* Burst Length Register */
+#define QUICKVX_RCB_BURSTLN_REG		(QUICKVX_RCB_BASE | 0x0000010C)
+/* Display Attributes Register */
+#define QUICKVX_RCB_DISPATTR_REG	(QUICKVX_RCB_BASE | 0x00000110)
+/* Error Status Register */
+#define QUICKVX_RCB_ERRSTAT_REG		(QUICKVX_RCB_BASE | 0x00000114)
+/* Error Mask Register */
+#define QUICKVX_RCB_ERRMSK_REG		(QUICKVX_RCB_BASE | 0x00000118)
+/* MDDI ASSP FIFO Overflow Address Register */
+#define QUICKVX_RCB_ASSPFOA_REG		(QUICKVX_RCB_BASE | 0x0000011C)
+/* MDDI Fabric FIFO Overflow Address Register */
+#define QUICKVX_RCB_FABFOA_REG		(QUICKVX_RCB_BASE | 0x00000120)
+/* Incoming RGB FIFO Overflow Address Register */
+#define QUICKVX_RCB_IRFOA_REG		(QUICKVX_RCB_BASE | 0x00000124)
+/* SPI Overflow Address Register */
+#define QUICKVX_RCB_SPIOA_REG		(QUICKVX_RCB_BASE | 0x00000128)
+/* Ping Buffer Address Register */
+#define QUICKVX_RCB_PINGBA_REG		(QUICKVX_RCB_BASE | 0x0000012C)
+/* Pong Buffer Address Register */
+#define QUICKVX_RCB_PONGBA_REG		(QUICKVX_RCB_BASE | 0x00000130)
+/* Configuration Done Register */
+#define QUICKVX_RCB_CONFDONE_REG	(QUICKVX_RCB_BASE | 0x00000134)
+/* FIFO Flush Register */
+#define QUICKVX_RCB_FFLUSH_REG		(QUICKVX_RCB_BASE | 0x00000138)
+
+
+/***************************************************
+ * SPI Block Registers
+ ***************************************************/
+/* SPI Rx0 Register */
+#define QUICKVX_SPI_RX0_REG			(QUICKVX_SPI_BASE | 0x00000000)
+/* SPI Rx1 Register */
+#define QUICKVX_SPI_RX1_REG			(QUICKVX_SPI_BASE | 0x00000004)
+/* SPI Rx2 Register */
+#define QUICKVX_SPI_RX2_REG			(QUICKVX_SPI_BASE | 0x00000008)
+/* SPI Rx3 Register */
+#define QUICKVX_SPI_RX3_REG			(QUICKVX_SPI_BASE | 0x0000000C)
+/* SPI Rx4 Register */
+#define QUICKVX_SPI_RX4_REG			(QUICKVX_SPI_BASE | 0x00000010)
+/* SPI Rx5 Register */
+#define QUICKVX_SPI_RX5_REG			(QUICKVX_SPI_BASE | 0x00000014)
+/* SPI Rx6 Register */
+#define QUICKVX_SPI_RX6_REG			(QUICKVX_SPI_BASE | 0x00000018)
+/* SPI Rx7 Register */
+#define QUICKVX_SPI_RX7_REG			(QUICKVX_SPI_BASE | 0x0000001C)
+/* SPI Tx0 Register */
+#define QUICKVX_SPI_TX0_REG			(QUICKVX_SPI_BASE | 0x00000020)
+/* SPI Tx1 Register */
+#define QUICKVX_SPI_TX1_REG			(QUICKVX_SPI_BASE | 0x00000024)
+/* SPI Tx2 Register */
+#define QUICKVX_SPI_TX2_REG			(QUICKVX_SPI_BASE | 0x00000028)
+/* SPI Tx3 Register */
+#define QUICKVX_SPI_TX3_REG			(QUICKVX_SPI_BASE | 0x0000002C)
+/* SPI Tx4 Register */
+#define QUICKVX_SPI_TX4_REG			(QUICKVX_SPI_BASE | 0x00000030)
+/* SPI Tx5 Register */
+#define QUICKVX_SPI_TX5_REG			(QUICKVX_SPI_BASE | 0x00000034)
+/* SPI Tx6 Register */
+#define QUICKVX_SPI_TX6_REG			(QUICKVX_SPI_BASE | 0x00000038)
+/* SPI Tx7 Register */
+#define QUICKVX_SPI_TX7_REG			(QUICKVX_SPI_BASE | 0x0000003C)
+/* SPI Control Register */
+#define QUICKVX_SPI_CTRL_REG		(QUICKVX_SPI_BASE | 0x00000040)
+/* SPI Transfer Length Register */
+#define QUICKVX_SPI_TLEN_REG		(QUICKVX_SPI_BASE | 0x00000044)
+
+
+/***************************************************
+ * Clock and Reset (CAR) Block Registers
+ ***************************************************/
+/* ASSP Global Clock Enable Register */
+#define QUICKVX_CAR_ASSP_GCE_REG	(QUICKVX_CAR_BASE | 0x00000000)
+/* VLP Control1 Register */
+#define QUICKVX_CAR_VLPCTRL1_REG	(QUICKVX_CAR_BASE | 0x00000004)
+/* VLP Control2 Register */
+#define QUICKVX_CAR_VLPCTRL2_REG	(QUICKVX_CAR_BASE | 0x00000008)
+/* Clock Selection Register */
+#define QUICKVX_CAR_CLKSEL_REG		(QUICKVX_CAR_BASE | 0x0000000C)
+/* PLL Control Register */
+#define QUICKVX_CAR_PLLCTRL_REG		(QUICKVX_CAR_BASE | 0x00000010)
+/* PLL Clock Ratio Register */
+#define QUICKVX_CAR_PLLCLKRATIO_REG	(QUICKVX_CAR_BASE | 0x00000014)
+
+
+/***************************************************
+ * VEE Block Registers
+ ***************************************************/
+/* VEE Control Register */
+#define QUICKVX_VEE_VEECTRL_REG		(QUICKVX_VEE_BASE | 0x00000000)
+/* Strength Register */
+#define QUICKVX_VEE_STRENGTH_REG	(QUICKVX_VEE_BASE | 0x0000000C)
+/* Variance Register */
+#define QUICKVX_VEE_VARIANCE_REG	(QUICKVX_VEE_BASE | 0x00000010)
+/* Slope Register */
+#define QUICKVX_VEE_SLOPE_REG		(QUICKVX_VEE_BASE | 0x00000014)
+/* Sharpen Control0 Register */
+#define QUICKVX_VEE_SHRPCTRL0_REG	(QUICKVX_VEE_BASE | 0x0000001C)
+/* Sharpen Control1 Register */
+#define QUICKVX_VEE_SHRPCTRL1_REG	(QUICKVX_VEE_BASE | 0x00000020)
+/* Upper Horizontal Positon Register */
+#define QUICKVX_VEE_UHPOS_REG		(QUICKVX_VEE_BASE | 0x00000024)
+/* Lower Horizontal Positon Register */
+#define QUICKVX_VEE_LHPOS_REG		(QUICKVX_VEE_BASE | 0x00000028)
+/* Upper Vertical Positon Register */
+#define QUICKVX_VEE_UVPOS_REG		(QUICKVX_VEE_BASE | 0x0000002C)
+/* Lower Vertical Positon Register */
+#define QUICKVX_VEE_LVPOS_REG		(QUICKVX_VEE_BASE | 0x00000030)
+/* Upper Frame Width Register */
+#define QUICKVX_VEE_UFWDTH_REG		(QUICKVX_VEE_BASE | 0x00000034)
+/* Lower Frame Width Register */
+#define QUICKVX_VEE_LFWDTH_REG		(QUICKVX_VEE_BASE | 0x00000038)
+/* Upper Frame Height Register */
+#define QUICKVX_VEE_UFHGHT_REG		(QUICKVX_VEE_BASE | 0x0000003C)
+/* Lower Frame Height Register */
+#define QUICKVX_VEE_LFHGHT_REG		(QUICKVX_VEE_BASE | 0x00000040)
+/* Control0 Register */
+#define QUICKVX_VEE_CTRL0_REG		(QUICKVX_VEE_BASE | 0x00000044)
+/* Control1 Register */
+#define QUICKVX_VEE_CTRL1_REG		(QUICKVX_VEE_BASE | 0x00000048)
+/* Video Enhancement Enable Register */
+#define QUICKVX_VEE_VDOEEN_REG		(QUICKVX_VEE_BASE | 0x0000004C)
+/* Black Level Register */
+#define QUICKVX_VEE_BLCKLEV_REG		(QUICKVX_VEE_BASE | 0x00000050)
+/* White Level Register */
+#define QUICKVX_VEE_WHTLEV_REG		(QUICKVX_VEE_BASE | 0x00000054)
+/* Amplification Limits Register */
+#define QUICKVX_VEE_AMPLMTS_REG		(QUICKVX_VEE_BASE | 0x00000060)
+/* Dithering Mode Register */
+#define QUICKVX_VEE_DITHMOD_REG		(QUICKVX_VEE_BASE | 0x00000064)
+/* Upper Look-up Data Register */
+#define QUICKVX_VEE_ULUD_REG		(QUICKVX_VEE_BASE | 0x00000080)
+/* Lower Look-up Data Register */
+#define QUICKVX_VEE_LLUD_REG		(QUICKVX_VEE_BASE | 0x00000084)
+/* Look-up Address Register */
+#define QUICKVX_VEE_LUADDR_REG		(QUICKVX_VEE_BASE | 0x00000088)
+/* Look-up Write Enable Register */
+#define QUICKVX_VEE_LUWREN_REG		(QUICKVX_VEE_BASE | 0x0000008C)
+/* VEE ID Register */
+#define QUICKVX_VEE_VEEID_REG		(QUICKVX_VEE_BASE | 0x000003FC)
+/* M_11 Register */
+#define QUICKVX_VEE_M_11_REG		(QUICKVX_VEE_BASE | 0x000000C0)
+/* M_12 Register */
+#define QUICKVX_VEE_M_12_REG		(QUICKVX_VEE_BASE | 0x000000C4)
+/* M_13 Register */
+#define QUICKVX_VEE_M_13_REG		(QUICKVX_VEE_BASE | 0x000000C8)
+/* M_21 Register */
+#define QUICKVX_VEE_M_21_REG		(QUICKVX_VEE_BASE | 0x000000CC)
+/* M_22 Register */
+#define QUICKVX_VEE_M_22_REG		(QUICKVX_VEE_BASE | 0x000000D0)
+/* M_23 Register */
+#define QUICKVX_VEE_M_23_REG		(QUICKVX_VEE_BASE | 0x000000D4)
+/* M_31 Register */
+#define QUICKVX_VEE_M_31_REG		(QUICKVX_VEE_BASE | 0x000000D8)
+/* M_32 Register */
+#define QUICKVX_VEE_M_32_REG		(QUICKVX_VEE_BASE | 0x000000DC)
+/* M_33 Register */
+#define QUICKVX_VEE_M_33_REG		(QUICKVX_VEE_BASE | 0x000000E0)
+/* R Offset Register */
+#define QUICKVX_VEE_OFFSET_R_REG	(QUICKVX_VEE_BASE | 0x000000E8)
+/* G Offset Register */
+#define QUICKVX_VEE_OFFSET_G_REG	(QUICKVX_VEE_BASE | 0x000000EC)
+/* B Offset Register */
+#define QUICKVX_VEE_OFFSET_B_REG	(QUICKVX_VEE_BASE | 0x000000F0)
+
+/* LCD Reset Register */
+#define QUICKVX_FB_A2F_LCD_RESET_REG (QUICKVX_FB_A2F_BASE | 0x00000000)
+
+/* Register bit defines */
+/* PLL Lock bit in the PLL Control Register */
+#define QUICKVX_PLL_LOCK_BIT		(1 << 7)
+
+#define QL_SPI_CTRL_rSPISTart(x) (x)
+#define QL_SPI_CTRL_rCPHA(x) (x << 1)
+#define QL_SPI_CTRL_rCPOL(x) (x << 2)
+#define QL_SPI_CTRL_rLSB(x) (x << 3)
+#define QL_SPI_CTRL_rSLVSEL(x) (x << 4)
+#define QL_SPI_CTRL_MASK_rTxDone (1 << 9)
+
+#define QL_SPI_LCD_DEV_ID 0x1c
+#define QL_SPI_LCD_RS(x) (x << 1)
+#define QL_SPI_LCD_RW(x) (x)
+#define QL_SPI_LCD_INDEX_START_BYTE ((QL_SPI_LCD_DEV_ID << 2) | \
+	QL_SPI_LCD_RS(0) | QL_SPI_LCD_RW(0))
+#define QL_SPI_LCD_CMD_START_BYTE ((QL_SPI_LCD_DEV_ID << 2) | \
+	QL_SPI_LCD_RS(1) | QL_SPI_LCD_RW(0))
+#define QL_SPI_CTRL_LCD_START (QL_SPI_CTRL_rSPISTart(1) | \
+	QL_SPI_CTRL_rCPHA(1) | QL_SPI_CTRL_rCPOL(1) | \
+	QL_SPI_CTRL_rLSB(0) | QL_SPI_CTRL_rSLVSEL(0))
+
+int ql_mddi_write(uint32 address, uint32 value)
+{
+	uint32 regval = 0;
+	int ret = 0;
+
+	ret = mddi_queue_register_write(address, value, TRUE, 0);
+
+	if (!ret) {
+		ret = mddi_queue_register_read(address, &regval, TRUE, 0);
+		if (regval != value) {
+			MDDI_MSG_DEBUG("\nMismatch: ql_mddi_write[0x%x]->0x%x "
+				"r0x%x\n", address, value, regval);
+		} else {
+			MDDI_MSG_DEBUG("\nMatch: ql_mddi_write[0x%x]->0x%x "
+				"r0x%x\n", address, value, regval);
+		}
+	}
+
+	return ret;
+}
+
+int ql_mddi_read(uint32 address, uint32 *regval)
+{
+	int ret = 0;
+
+	ret = mddi_queue_register_read(address, regval, TRUE, 0);
+	MDDI_MSG_DEBUG("\nql_mddi_read[0x%x]=0x%x", address, *regval);
+
+	return ret;
+}
+
+int ql_send_spi_cmd_to_lcd(uint32 index, uint32 cmd)
+{
+	int retry, ret;
+	uint32 readval;
+
+	MDDI_MSG_DEBUG("\n %s(): index 0x%x, cmd 0x%x", __func__, index, cmd);
+	/* do the index phase */
+	/* send 24 bits in the index phase */
+	ql_mddi_write(QUICKVX_SPI_TLEN_REG, 23);
+
+	/* send 24 bits in the index phase, starting at bit 23 of TX0 reg */
+	ql_mddi_write(QUICKVX_SPI_TX0_REG,
+		(QL_SPI_LCD_INDEX_START_BYTE << 16) | index);
+
+	/* set start */
+	ql_mddi_write(QUICKVX_SPI_CTRL_REG,  QL_SPI_CTRL_LCD_START);
+	retry = 0;
+
+	do {
+		ret = ql_mddi_read(QUICKVX_SPI_CTRL_REG, &readval);
+
+		if (ret || ++retry > 5) {
+			MDDI_MSG_DEBUG("\n ql_send_spi_cmd_to_lcd: retry "
+				"timeout at index phase, ret = %d", ret);
+			return -EIO;
+		}
+		mddi_wait(1);
+	} while ((readval & QL_SPI_CTRL_MASK_rTxDone) == 0);
+
+	/* do the command phase */
+	/* send 24 bits in the cmd phase */
+	ql_mddi_write(QUICKVX_SPI_TLEN_REG, 23);
+
+	/* send 24 bits in the cmd phase, starting at bit 23 of TX0 reg. */
+	ql_mddi_write(QUICKVX_SPI_TX0_REG,
+		(QL_SPI_LCD_CMD_START_BYTE << 16) | cmd);
+
+	/* set start */
+	ql_mddi_write(QUICKVX_SPI_CTRL_REG,  QL_SPI_CTRL_LCD_START);
+	retry = 0;
+
+	do {
+		ret = ql_mddi_read(QUICKVX_SPI_CTRL_REG, &readval);
+
+		if (ret || ++retry > 5) {
+			MDDI_MSG_DEBUG("\n ql_send_spi_cmd_to_lcd: retry "
+				"timeout at cmd phase, ret = %d", ret);
+			return -EIO;
+		}
+		mddi_wait(1);
+	} while ((readval & QL_SPI_CTRL_MASK_rTxDone) == 0);
+
+	return 0;
+}
+
+
+int ql_send_spi_data_from_lcd(uint32 index, uint32 *value)
+{
+	int retry, ret;
+	uint32 readval;
+
+	MDDI_MSG_DEBUG("\n %s(): index 0x%x", __func__, index);
+	/* do the index phase */
+	/* send 24 bits in the index phase */
+	ql_mddi_write(QUICKVX_SPI_TLEN_REG, 23);
+
+	/* send 24 bits in the index phase, starting at bit 23 of TX0 reg */
+	ql_mddi_write(QUICKVX_SPI_TX0_REG,
+		(QL_SPI_LCD_INDEX_START_BYTE << 16) | index);
+
+	/* set start */
+	ql_mddi_write(QUICKVX_SPI_CTRL_REG,  QL_SPI_CTRL_LCD_START);
+	retry = 0;
+
+	do {
+		ret = ql_mddi_read(QUICKVX_SPI_CTRL_REG, &readval);
+
+		if (ret || ++retry > 5) {
+			MDDI_MSG_DEBUG("\n ql_send_spi_cmd_to_lcd: retry "
+				"timeout at index phase, ret = %d", ret);
+			return -EIO;
+		}
+		mddi_wait(1);
+	} while ((readval & QL_SPI_CTRL_MASK_rTxDone) == 0);
+
+	/* do the command phase */
+	/* send 8 bits  and read 24 bits in the cmd phase, so total 32 bits */
+	ql_mddi_write(QUICKVX_SPI_TLEN_REG, 31);
+
+	/* send 24 bits in the cmd phase, starting at bit 31 of TX0 reg */
+	ql_mddi_write(QUICKVX_SPI_TX0_REG,
+		((QL_SPI_LCD_CMD_START_BYTE << 16)) << 8);
+
+	/* set start */
+	ql_mddi_write(QUICKVX_SPI_CTRL_REG,  QL_SPI_CTRL_LCD_START);
+	retry = 0;
+
+	do {
+		ret = ql_mddi_read(QUICKVX_SPI_CTRL_REG, &readval);
+
+		if (ret || ++retry > 5) {
+			MDDI_MSG_DEBUG("\n ql_send_spi_cmd_to_lcd: retry "
+				"timeout at cmd phase, ret = %d", ret);
+			return -EIO;
+		}
+		mddi_wait(1);
+	} while ((readval & QL_SPI_CTRL_MASK_rTxDone) == 0);
+
+	/* value will appear at lower 16 bits */
+	ret = ql_mddi_read(QUICKVX_SPI_RX0_REG, value);
+
+	if (!ret) {
+		*value = *value & 0xffff;
+		MDDI_MSG_DEBUG("\n QUICKVX_SPI_RX0_REG value = 0x%x", *value);
+	} else
+		MDDI_MSG_DEBUG("\n Read QUICKVX_SPI_RX0_REG Failed");
+
+	return ret;
+}
+
+/* Global Variables */
+static uint32 mddi_quickvx_rows_per_second;
+static uint32 mddi_quickvx_usecs_per_refresh;
+static uint32 mddi_quickvx_rows_per_refresh;
+
+void mddi_quickvx_configure_registers(void)
+{
+	MDDI_MSG_DEBUG("\n%s(): ", __func__);
+	ql_mddi_write(QUICKVX_CAR_CLKSEL_REG, 0x00007000);
+
+	ql_mddi_write(QUICKVX_RCB_PWMW_REG, 0x0000FFFF);
+
+	ql_mddi_write(QUICKVX_RCB_PWMC_REG, 0x00000001);
+
+	ql_mddi_write(QUICKVX_RCB_CONFDONE_REG, 0x00000000);
+
+	/* display is x width = 480, y width = 864 */
+	ql_mddi_write(QUICKVX_RCB_TCON0_REG, 0x035f01df);
+
+	/* VFP=2, VBP=4, HFP=16, HBP=16 */
+	ql_mddi_write(QUICKVX_RCB_TCON1_REG, 0x01e301e1);
+
+	/* VSW =2, HSW=8 */
+	ql_mddi_write(QUICKVX_RCB_TCON2_REG, 0x000000e1);
+
+	ql_mddi_write(QUICKVX_RCB_DISPATTR_REG, 0x00000000);
+
+	ql_mddi_write(QUICKVX_RCB_USECASE_REG, 0x00000025);
+
+	ql_mddi_write(QUICKVX_RCB_VPARM_REG, 0x00000888);
+
+	ql_mddi_write(QUICKVX_RCB_VEECONF_REG, 0x00000001);
+
+	ql_mddi_write(QUICKVX_RCB_IER_REG, 0x00000000);
+
+	ql_mddi_write(QUICKVX_RCB_RCR_REG, 0x80000010);
+
+	ql_mddi_write(QUICKVX_RCB_CELLBCR_REG, 0x8008746F);
+
+	ql_mddi_write(QUICKVX_RCB_CELLCC_REG, 0x800000A3);
+
+	ql_mddi_write(QUICKVX_RCB_CONFDONE_REG, 0x00000001);
+}
+
+void mddi_quickvx_prim_lcd_init(void)
+{
+	uint32 value;
+
+	MDDI_MSG_DEBUG("\n%s(): ", __func__);
+	ql_send_spi_data_from_lcd(0, &value);
+
+	ql_send_spi_cmd_to_lcd(0x0100, 0x3000); /* power control1 */
+	ql_send_spi_cmd_to_lcd(0x0101, 0x4010); /* power control2 */
+	ql_send_spi_cmd_to_lcd(0x0106, 0x0000); /* auto seq setting */
+	mddi_wait(3);
+
+	ql_mddi_write(QUICKVX_FB_A2F_LCD_RESET_REG, 0x00000001);
+	mddi_wait(1);
+	ql_mddi_write(QUICKVX_FB_A2F_LCD_RESET_REG, 0x00000000);
+	mddi_wait(1);
+	ql_mddi_write(QUICKVX_FB_A2F_LCD_RESET_REG, 0x00000001);
+	mddi_wait(10);
+
+	ql_send_spi_cmd_to_lcd(0x0001, 0x0310); /* driver out control */
+	ql_send_spi_cmd_to_lcd(0x0002, 0x0100); /* lcd ac control */
+	ql_send_spi_cmd_to_lcd(0x0003, 0x0000); /* entry mode */
+	ql_send_spi_cmd_to_lcd(0x0007, 0x0000); /* disp cont1 */
+	ql_send_spi_cmd_to_lcd(0x0008, 0x0004); /* disp cont2 */
+	ql_send_spi_cmd_to_lcd(0x0009, 0x000C); /* disp cont3 */
+	ql_send_spi_cmd_to_lcd(0x000C, 0x4010); /* disp if cont1 */
+	ql_send_spi_cmd_to_lcd(0x000E, 0x0000); /* disp if cont2 */
+	ql_send_spi_cmd_to_lcd(0x0020, 0x013F); /* panel if cont1 */
+	ql_send_spi_cmd_to_lcd(0x0022, 0x7600); /* panel if cont3 */
+	ql_send_spi_cmd_to_lcd(0x0023, 0x1C0A); /* panel if cont4 */
+	ql_send_spi_cmd_to_lcd(0x0024, 0x1C2C); /* panel if cont5 */
+	ql_send_spi_cmd_to_lcd(0x0025, 0x1C4E); /* panel if cont6 */
+	ql_send_spi_cmd_to_lcd(0x0027, 0x0000); /* panel if cont8 */
+	ql_send_spi_cmd_to_lcd(0x0028, 0x760C); /* panel if cont9 */
+	ql_send_spi_cmd_to_lcd(0x0300, 0x0000); /* gamma adj0 */
+	ql_send_spi_cmd_to_lcd(0x0301, 0x0502); /* gamma adj1 */
+	ql_send_spi_cmd_to_lcd(0x0302, 0x0705); /* gamma adj2 */
+	ql_send_spi_cmd_to_lcd(0x0303, 0x0000); /* gamma adj3 */
+	ql_send_spi_cmd_to_lcd(0x0304, 0x0200); /* gamma adj4 */
+	ql_send_spi_cmd_to_lcd(0x0305, 0x0707); /* gamma adj5 */
+	ql_send_spi_cmd_to_lcd(0x0306, 0x1010); /* gamma adj6 */
+	ql_send_spi_cmd_to_lcd(0x0307, 0x0202); /* gamma adj7 */
+	ql_send_spi_cmd_to_lcd(0x0308, 0x0704); /* gamma adj8 */
+	ql_send_spi_cmd_to_lcd(0x0309, 0x0707); /* gamma adj9 */
+	ql_send_spi_cmd_to_lcd(0x030A, 0x0000); /* gamma adja */
+	ql_send_spi_cmd_to_lcd(0x030B, 0x0000); /* gamma adjb */
+	ql_send_spi_cmd_to_lcd(0x030C, 0x0707); /* gamma adjc */
+	ql_send_spi_cmd_to_lcd(0x030D, 0x1010); /* gamma adjd */
+	ql_send_spi_cmd_to_lcd(0x0310, 0x0104); /* gamma adj10 */
+	ql_send_spi_cmd_to_lcd(0x0311, 0x0503); /* gamma adj11 */
+	ql_send_spi_cmd_to_lcd(0x0312, 0x0304); /* gamma adj12 */
+	ql_send_spi_cmd_to_lcd(0x0315, 0x0304); /* gamma adj15 */
+	ql_send_spi_cmd_to_lcd(0x0316, 0x031C); /* gamma adj16 */
+	ql_send_spi_cmd_to_lcd(0x0317, 0x0204); /* gamma adj17 */
+	ql_send_spi_cmd_to_lcd(0x0318, 0x0402); /* gamma adj18 */
+	ql_send_spi_cmd_to_lcd(0x0319, 0x0305); /* gamma adj19 */
+	ql_send_spi_cmd_to_lcd(0x031C, 0x0707); /* gamma adj1c */
+	ql_send_spi_cmd_to_lcd(0x031D, 0x021F); /* gamma adj1d */
+	ql_send_spi_cmd_to_lcd(0x0320, 0x0507); /* gamma adj20 */
+	ql_send_spi_cmd_to_lcd(0x0321, 0x0604); /* gamma adj21 */
+	ql_send_spi_cmd_to_lcd(0x0322, 0x0405); /* gamma adj22 */
+	ql_send_spi_cmd_to_lcd(0x0327, 0x0203); /* gamma adj27 */
+	ql_send_spi_cmd_to_lcd(0x0328, 0x0300); /* gamma adj28 */
+	ql_send_spi_cmd_to_lcd(0x0329, 0x0002); /* gamma adj29 */
+	ql_send_spi_cmd_to_lcd(0x0100, 0x363C); /* power cont1 */
+	mddi_wait(1);
+	ql_send_spi_cmd_to_lcd(0x0101, 0x4003); /* power cont2 */
+	ql_send_spi_cmd_to_lcd(0x0102, 0x0001); /* power cont3 */
+	ql_send_spi_cmd_to_lcd(0x0103, 0x3C58); /* power cont4 */
+	ql_send_spi_cmd_to_lcd(0x010C, 0x0135); /* power cont6 */
+	ql_send_spi_cmd_to_lcd(0x0106, 0x0002); /* auto seq */
+	ql_send_spi_cmd_to_lcd(0x0029, 0x03BF); /* panel if cont10 */
+	ql_send_spi_cmd_to_lcd(0x0106, 0x0003); /* auto seq */
+	mddi_wait(5);
+	ql_send_spi_cmd_to_lcd(0x0101, 0x4010); /* power cont2 */
+	mddi_wait(10);
+}
+
+/* Function to Power On the Primary and Secondary LCD panels */
+static int mddi_quickvx_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	MDDI_MSG_DEBUG("\n%s(): ", __func__);
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd) {
+		MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_on: Device not found!");
+		return -ENODEV;
+	}
+
+	if (mfd->key != MFD_KEY) {
+		MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_on: Invalid MFD key!");
+		return -EINVAL;
+	}
+
+	mddi_host_client_cnt_reset();
+	mddi_quickvx_configure_registers();
+	mddi_quickvx_prim_lcd_init();
+
+	return 0;
+}
+
+
+/* Function to Power Off the Primary and Secondary LCD panels */
+static int mddi_quickvx_lcd_off(struct platform_device *pdev)
+{
+	MDDI_MSG_DEBUG("\n%s(): ", __func__);
+	mddi_wait(1);
+	ql_send_spi_cmd_to_lcd(0x0106, 0x0002); /* Auto Sequencer setting */
+	mddi_wait(10);
+	ql_send_spi_cmd_to_lcd(0x0106, 0x0000); /* Auto Sequencer setting */
+	ql_send_spi_cmd_to_lcd(0x0029, 0x0002); /* Panel IF control 10 */
+	ql_send_spi_cmd_to_lcd(0x0100, 0x300D); /* Power Control 1 */
+	mddi_wait(1);
+
+	return 0;
+}
+
+/* Function to set the Backlight brightness level */
+static void mddi_quickvx_lcd_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int32 level, i = 0, ret;
+
+	MDDI_MSG_DEBUG("%s(): ", __func__);
+
+	level = mfd->bl_level;
+	MDDI_MSG_DEBUG("\n level = %d", level);
+	if (level < 0) {
+		MDDI_MSG_DEBUG("mddi_quickvx_lcd_set_backlight: "
+			"Invalid backlight level (%d)!\n", level);
+		return;
+	}
+	while (i++ < 3) {
+		ret = pmic_set_led_intensity(LED_LCD, level);
+		if (ret == 0)
+			return;
+		msleep(10);
+	}
+
+	MDDI_MSG_DEBUG("%s: can't set lcd backlight!\n",
+				__func__);
+}
+
+/* Driver Probe function */
+static int __devinit mddi_quickvx_lcd_probe(struct platform_device *pdev)
+{
+	MDDI_MSG_DEBUG("\n%s(): id is %d", __func__, pdev->id);
+	msm_fb_add_device(pdev);
+	return 0;
+}
+
+/* Driver data structure */
+static struct platform_driver this_driver = {
+	.probe  = mddi_quickvx_lcd_probe,
+	.driver	= {
+		.name	= "mddi_quickvx",
+	},
+};
+
+
+/* Primary LCD panel data structure */
+static struct msm_fb_panel_data mddi_quickvx_panel_data0 = {
+	.on					= mddi_quickvx_lcd_on,
+	.off				= mddi_quickvx_lcd_off,
+	.set_backlight		= mddi_quickvx_lcd_set_backlight,
+};
+
+
+/* Primary LCD panel device structure */
+static struct platform_device this_device0 = {
+	.name   = "mddi_quickvx",
+	.id		= MDDI_QUICKVX_1_2,
+	.dev	= {
+		.platform_data = &mddi_quickvx_panel_data0,
+	}
+};
+
+/* Module init - driver main entry point */
+static int __init mddi_quickvx_lcd_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	u32 cid;
+	MDDI_MSG_DEBUG("\n%s(): ", __func__);
+
+	ret = msm_fb_detect_client("mddi_quickvx");
+
+	if (ret == -ENODEV)	{
+		/* Device not found */
+		MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_init: No device found!");
+		return 0;
+	}
+
+	if (ret) {
+		cid = mddi_get_client_id();
+
+		MDDI_MSG_DEBUG("\n cid = 0x%x", cid);
+		if (((cid >> 16) != QUICKVX_MDDI_MFR_CODE) ||
+			((cid & 0xFFFF) != QUICKVX_MDDI_PRD_CODE)) {
+			/* MDDI Client ID not matching */
+			MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_init: "
+				"Client ID missmatch!");
+
+			return 0;
+		}
+		MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_init: "
+			"QuickVX LCD panel detected!");
+	}
+
+#endif /* CONFIG_FB_MSM_MDDI_AUTO_DETECT */
+
+	mddi_quickvx_rows_per_refresh = 872;
+	mddi_quickvx_rows_per_second = 52364;
+	mddi_quickvx_usecs_per_refresh = 16574;
+
+	ret = platform_driver_register(&this_driver);
+
+	if (!ret) {
+		pinfo = &mddi_quickvx_panel_data0.panel_info;
+		pinfo->xres = 480;
+		pinfo->yres = 864;
+		MSM_FB_SINGLE_MODE_PANEL(pinfo);
+		pinfo->type = MDDI_PANEL;
+		pinfo->pdest = DISPLAY_1;
+		pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
+		pinfo->wait_cycle = 0;
+		pinfo->bpp = 24;
+		pinfo->fb_num = 2;
+
+		pinfo->clk_rate = 192000000;
+		pinfo->clk_min = 192000000;
+		pinfo->clk_max = 200000000;
+		pinfo->lcd.rev = 1;
+		pinfo->lcd.vsync_enable = TRUE;
+		pinfo->lcd.refx100 = (mddi_quickvx_rows_per_second \
+			* 100)/mddi_quickvx_rows_per_refresh;
+		pinfo->mddi.is_type1 = TRUE;
+		pinfo->lcd.v_back_porch = 4;
+		pinfo->lcd.v_front_porch = 2;
+		pinfo->lcd.v_pulse_width = 2;
+		pinfo->lcd.hw_vsync_mode = TRUE;
+		pinfo->lcd.vsync_notifier_period = (1 * HZ);
+		pinfo->bl_max = 10;
+		pinfo->bl_min = 0;
+
+		ret = platform_device_register(&this_device0);
+		if (ret) {
+			platform_driver_unregister(&this_driver);
+			MDDI_MSG_DEBUG("mddi_quickvx_lcd_init: "
+				"Primary device registration failed!\n");
+		}
+	}
+
+	return ret;
+}
+
+module_init(mddi_quickvx_lcd_init);
+
diff --git a/drivers/video/msm/mddi_sharp.c b/drivers/video/msm/mddi_sharp.c
new file mode 100644
index 0000000..6a9008f
--- /dev/null
+++ b/drivers/video/msm/mddi_sharp.c
@@ -0,0 +1,901 @@
+/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+
+#define SHARP_QVGA_PRIM 1
+#define SHARP_128X128_SECD 2
+
+extern uint32 mddi_host_core_version;
+static boolean mddi_debug_prim_wait = FALSE;
+static boolean mddi_sharp_vsync_wake = TRUE;
+static boolean mddi_sharp_monitor_refresh_value = TRUE;
+static boolean mddi_sharp_report_refresh_measurements = FALSE;
+static uint32 mddi_sharp_rows_per_second = 13830;	/* 5200000/376 */
+static uint32 mddi_sharp_rows_per_refresh = 338;
+static uint32 mddi_sharp_usecs_per_refresh = 24440;	/* (376+338)/5200000 */
+static boolean mddi_sharp_debug_60hz_refresh = FALSE;
+
+extern mddi_gpio_info_type mddi_gpio;
+extern boolean mddi_vsync_detect_enabled;
+static msm_fb_vsync_handler_type mddi_sharp_vsync_handler;
+static void *mddi_sharp_vsync_handler_arg;
+static uint16 mddi_sharp_vsync_attempts;
+
+static void mddi_sharp_prim_lcd_init(void);
+static void mddi_sharp_sub_lcd_init(void);
+static void mddi_sharp_lcd_set_backlight(struct msm_fb_data_type *mfd);
+static void mddi_sharp_vsync_set_handler(msm_fb_vsync_handler_type handler,
+					 void *);
+static void mddi_sharp_lcd_vsync_detected(boolean detected);
+static struct msm_panel_common_pdata *mddi_sharp_pdata;
+
+#define REG_SYSCTL    0x0000
+#define REG_INTR    0x0006
+#define REG_CLKCNF    0x000C
+#define REG_CLKDIV1    0x000E
+#define REG_CLKDIV2    0x0010
+
+#define REG_GIOD    0x0040
+#define REG_GIOA    0x0042
+
+#define REG_AGM      0x010A
+#define REG_FLFT    0x0110
+#define REG_FRGT    0x0112
+#define REG_FTOP    0x0114
+#define REG_FBTM    0x0116
+#define REG_FSTRX    0x0118
+#define REG_FSTRY    0x011A
+#define REG_VRAM    0x0202
+#define REG_SSDCTL    0x0330
+#define REG_SSD0    0x0332
+#define REG_PSTCTL1    0x0400
+#define REG_PSTCTL2    0x0402
+#define REG_PTGCTL    0x042A
+#define REG_PTHP    0x042C
+#define REG_PTHB    0x042E
+#define REG_PTHW    0x0430
+#define REG_PTHF    0x0432
+#define REG_PTVP    0x0434
+#define REG_PTVB    0x0436
+#define REG_PTVW    0x0438
+#define REG_PTVF    0x043A
+#define REG_VBLKS    0x0458
+#define REG_VBLKE    0x045A
+#define REG_SUBCTL    0x0700
+#define REG_SUBTCMD    0x0702
+#define REG_SUBTCMDD  0x0704
+#define REG_REVBYTE    0x0A02
+#define REG_REVCNT    0x0A04
+#define REG_REVATTR    0x0A06
+#define REG_REVFMT    0x0A08
+
+#define SHARP_SUB_UNKNOWN 0xffffffff
+#define SHARP_SUB_HYNIX 1
+#define SHARP_SUB_ROHM  2
+
+static uint32 sharp_subpanel_type = SHARP_SUB_UNKNOWN;
+
+static void sub_through_write(int sub_rs, uint32 sub_data)
+{
+	mddi_queue_register_write(REG_SUBTCMDD, sub_data, FALSE, 0);
+
+	/* CS=1,RD=1,WE=1,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, FALSE, 0);
+
+	/* CS=0,RD=1,WE=1,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
+
+	/* CS=0,RD=1,WE=0,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x0004 | sub_rs, FALSE, 0);
+
+	/* CS=0,RD=1,WE=1,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
+
+	/* CS=1,RD=1,WE=1,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, TRUE, 0);
+}
+
+static uint32 sub_through_read(int sub_rs)
+{
+	uint32 sub_data;
+
+	/* CS=1,RD=1,WE=1,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, FALSE, 0);
+
+	/* CS=0,RD=1,WE=1,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
+
+	/* CS=0,RD=1,WE=0,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x0002 | sub_rs, TRUE, 0);
+
+	mddi_queue_register_read(REG_SUBTCMDD, &sub_data, TRUE, 0);
+
+	/* CS=0,RD=1,WE=1,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0);
+
+	/* CS=1,RD=1,WE=1,RS=sub_rs */
+	mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, TRUE, 0);
+
+	return sub_data;
+}
+
+static void serigo(uint32 ssd)
+{
+	uint32 ssdctl;
+
+	mddi_queue_register_read(REG_SSDCTL, &ssdctl, TRUE, 0);
+	ssdctl = ((ssdctl & 0xE7) | 0x02);
+
+	mddi_queue_register_write(REG_SSD0, ssd, FALSE, 0);
+	mddi_queue_register_write(REG_SSDCTL, ssdctl, TRUE, 0);
+
+	do {
+		mddi_queue_register_read(REG_SSDCTL, &ssdctl, TRUE, 0);
+	} while ((ssdctl & 0x0002) != 0);
+
+	if (mddi_debug_prim_wait)
+		mddi_wait(2);
+}
+
+static void mddi_sharp_lcd_powerdown(void)
+{
+	serigo(0x0131);
+	serigo(0x0300);
+	mddi_wait(40);
+	serigo(0x0135);
+	mddi_wait(20);
+	serigo(0x2122);
+	mddi_wait(20);
+	serigo(0x0201);
+	mddi_wait(20);
+	serigo(0x2100);
+	mddi_wait(20);
+	serigo(0x2000);
+	mddi_wait(20);
+
+	mddi_queue_register_write(REG_PSTCTL1, 0x1, TRUE, 0);
+	mddi_wait(100);
+	mddi_queue_register_write(REG_PSTCTL1, 0x0, TRUE, 0);
+	mddi_wait(2);
+	mddi_queue_register_write(REG_SYSCTL, 0x1, TRUE, 0);
+	mddi_wait(2);
+	mddi_queue_register_write(REG_CLKDIV1, 0x3, TRUE, 0);
+	mddi_wait(2);
+	mddi_queue_register_write(REG_SSDCTL, 0x0000, TRUE, 0);	/* SSDRESET */
+	mddi_queue_register_write(REG_SYSCTL, 0x0, TRUE, 0);
+	mddi_wait(2);
+}
+
+static void mddi_sharp_lcd_set_backlight(struct msm_fb_data_type *mfd)
+{
+	uint32 regdata;
+	int32 level;
+	int max = mfd->panel_info.bl_max;
+	int min = mfd->panel_info.bl_min;
+
+	if (mddi_sharp_pdata && mddi_sharp_pdata->backlight_level) {
+		level = mddi_sharp_pdata->backlight_level(mfd->bl_level,
+							  max,
+							  min);
+
+		if (level < 0)
+			return;
+
+		/* use Rodem GPIO(2:0) to give 8 levels of backlight (7-0) */
+		/* Set lower 3 GPIOs as Outputs (set to 0) */
+		mddi_queue_register_read(REG_GIOA, &regdata, TRUE, 0);
+		mddi_queue_register_write(REG_GIOA, regdata & 0xfff8, TRUE, 0);
+
+		/* Set lower 3 GPIOs as level */
+		mddi_queue_register_read(REG_GIOD, &regdata, TRUE, 0);
+		mddi_queue_register_write(REG_GIOD,
+			  (regdata & 0xfff8) | (0x07 & level), TRUE, 0);
+	}
+}
+
+static void mddi_sharp_prim_lcd_init(void)
+{
+	mddi_queue_register_write(REG_SYSCTL, 0x4000, TRUE, 0);
+	mddi_wait(1);
+	mddi_queue_register_write(REG_SYSCTL, 0x0000, TRUE, 0);
+	mddi_wait(5);
+	mddi_queue_register_write(REG_SYSCTL, 0x0001, FALSE, 0);
+	mddi_queue_register_write(REG_CLKDIV1, 0x000b, FALSE, 0);
+
+	/* new reg write below */
+	if (mddi_sharp_debug_60hz_refresh)
+		mddi_queue_register_write(REG_CLKCNF, 0x070d, FALSE, 0);
+	else
+		mddi_queue_register_write(REG_CLKCNF, 0x0708, FALSE, 0);
+
+	mddi_queue_register_write(REG_SYSCTL, 0x0201, FALSE, 0);
+	mddi_queue_register_write(REG_PTGCTL, 0x0010, FALSE, 0);
+	mddi_queue_register_write(REG_PTHP, 4, FALSE, 0);
+	mddi_queue_register_write(REG_PTHB, 40, FALSE, 0);
+	mddi_queue_register_write(REG_PTHW, 240, FALSE, 0);
+	if (mddi_sharp_debug_60hz_refresh)
+		mddi_queue_register_write(REG_PTHF, 12, FALSE, 0);
+	else
+		mddi_queue_register_write(REG_PTHF, 92, FALSE, 0);
+
+	mddi_wait(1);
+
+	mddi_queue_register_write(REG_PTVP, 1, FALSE, 0);
+	mddi_queue_register_write(REG_PTVB, 2, FALSE, 0);
+	mddi_queue_register_write(REG_PTVW, 320, FALSE, 0);
+	mddi_queue_register_write(REG_PTVF, 15, FALSE, 0);
+
+	mddi_wait(1);
+
+	/* vram_color set REG_AGM???? */
+	mddi_queue_register_write(REG_AGM, 0x0000, TRUE, 0);
+
+	mddi_queue_register_write(REG_SSDCTL, 0x0000, FALSE, 0);
+	mddi_queue_register_write(REG_SSDCTL, 0x0001, TRUE, 0);
+	mddi_wait(1);
+	mddi_queue_register_write(REG_PSTCTL1, 0x0001, TRUE, 0);
+	mddi_wait(10);
+
+	serigo(0x0701);
+	/* software reset */
+	mddi_wait(1);
+	/* Wait over 50us */
+
+	serigo(0x0400);
+	/* DCLK~ACHSYNC~ACVSYNC polarity setting */
+	serigo(0x2900);
+	/* EEPROM start read address setting */
+	serigo(0x2606);
+	/* EEPROM start read register setting */
+	mddi_wait(20);
+	/* Wait over 20ms */
+
+	serigo(0x0503);
+	/* Horizontal timing setting */
+	serigo(0x062C);
+	/* Veritical timing setting */
+	serigo(0x2001);
+	/* power initialize setting(VDC2) */
+	mddi_wait(20);
+	/* Wait over 20ms */
+
+	serigo(0x2120);
+	/* Initialize power setting(CPS) */
+	mddi_wait(20);
+	/* Wait over 20ms */
+
+	serigo(0x2130);
+	/* Initialize power setting(CPS) */
+	mddi_wait(20);
+	/* Wait over 20ms */
+
+	serigo(0x2132);
+	/* Initialize power setting(CPS) */
+	mddi_wait(10);
+	/* Wait over 10ms */
+
+	serigo(0x2133);
+	/* Initialize power setting(CPS) */
+	mddi_wait(20);
+	/* Wait over 20ms */
+
+	serigo(0x0200);
+	/* Panel initialize release(INIT) */
+	mddi_wait(1);
+	/* Wait over 1ms */
+
+	serigo(0x0131);
+	/* Panel setting(CPS) */
+	mddi_wait(1);
+	/* Wait over 1ms */
+
+	mddi_queue_register_write(REG_PSTCTL1, 0x0003, TRUE, 0);
+
+	/* if (FFA LCD is upside down) -> serigo(0x0100); */
+	serigo(0x0130);
+
+	/* Black mask release(display ON) */
+	mddi_wait(1);
+	/* Wait over 1ms */
+
+	if (mddi_sharp_vsync_wake) {
+		mddi_queue_register_write(REG_VBLKS, 0x1001, TRUE, 0);
+		mddi_queue_register_write(REG_VBLKE, 0x1002, TRUE, 0);
+	}
+
+	/* Set the MDP pixel data attributes for Primary Display */
+	mddi_host_write_pix_attr_reg(0x00C3);
+	return;
+
+}
+
+void mddi_sharp_sub_lcd_init(void)
+{
+
+	mddi_queue_register_write(REG_SYSCTL, 0x4000, FALSE, 0);
+	mddi_queue_register_write(REG_SYSCTL, 0x0000, TRUE, 0);
+	mddi_wait(100);
+
+	mddi_queue_register_write(REG_SYSCTL, 0x0001, FALSE, 0);
+	mddi_queue_register_write(REG_CLKDIV1, 0x000b, FALSE, 0);
+	mddi_queue_register_write(REG_CLKCNF, 0x0708, FALSE, 0);
+	mddi_queue_register_write(REG_SYSCTL, 0x0201, FALSE, 0);
+	mddi_queue_register_write(REG_PTGCTL, 0x0010, FALSE, 0);
+	mddi_queue_register_write(REG_PTHP, 4, FALSE, 0);
+	mddi_queue_register_write(REG_PTHB, 40, FALSE, 0);
+	mddi_queue_register_write(REG_PTHW, 128, FALSE, 0);
+	mddi_queue_register_write(REG_PTHF, 92, FALSE, 0);
+	mddi_queue_register_write(REG_PTVP, 1, FALSE, 0);
+	mddi_queue_register_write(REG_PTVB, 2, FALSE, 0);
+	mddi_queue_register_write(REG_PTVW, 128, FALSE, 0);
+	mddi_queue_register_write(REG_PTVF, 15, FALSE, 0);
+
+	/* Now the sub display..... */
+	/* Reset High */
+	mddi_queue_register_write(REG_SUBCTL, 0x0200, FALSE, 0);
+	/* CS=1,RD=1,WE=1,RS=1 */
+	mddi_queue_register_write(REG_SUBTCMD, 0x000f, TRUE, 0);
+	mddi_wait(1);
+	/* Wait 5us */
+
+	if (sharp_subpanel_type == SHARP_SUB_UNKNOWN) {
+		uint32 data;
+
+		sub_through_write(1, 0x05);
+		sub_through_write(1, 0x6A);
+		sub_through_write(1, 0x1D);
+		sub_through_write(1, 0x05);
+		data = sub_through_read(1);
+		if (data == 0x6A) {
+			sharp_subpanel_type = SHARP_SUB_HYNIX;
+		} else {
+			sub_through_write(0, 0x36);
+			sub_through_write(1, 0xA8);
+			sub_through_write(0, 0x09);
+			data = sub_through_read(1);
+			data = sub_through_read(1);
+			if (data == 0x54) {
+				sub_through_write(0, 0x36);
+				sub_through_write(1, 0x00);
+				sharp_subpanel_type = SHARP_SUB_ROHM;
+			}
+		}
+	}
+
+	if (sharp_subpanel_type == SHARP_SUB_HYNIX) {
+		sub_through_write(1, 0x00);	/* Display setting 1 */
+		sub_through_write(1, 0x04);
+		sub_through_write(1, 0x01);
+		sub_through_write(1, 0x05);
+		sub_through_write(1, 0x0280);
+		sub_through_write(1, 0x0301);
+		sub_through_write(1, 0x0402);
+		sub_through_write(1, 0x0500);
+		sub_through_write(1, 0x0681);
+		sub_through_write(1, 0x077F);
+		sub_through_write(1, 0x08C0);
+		sub_through_write(1, 0x0905);
+		sub_through_write(1, 0x0A02);
+		sub_through_write(1, 0x0B00);
+		sub_through_write(1, 0x0C00);
+		sub_through_write(1, 0x0D00);
+		sub_through_write(1, 0x0E00);
+		sub_through_write(1, 0x0F00);
+
+		sub_through_write(1, 0x100B);	/* Display setting 2 */
+		sub_through_write(1, 0x1103);
+		sub_through_write(1, 0x1237);
+		sub_through_write(1, 0x1300);
+		sub_through_write(1, 0x1400);
+		sub_through_write(1, 0x1500);
+		sub_through_write(1, 0x1605);
+		sub_through_write(1, 0x1700);
+		sub_through_write(1, 0x1800);
+		sub_through_write(1, 0x192E);
+		sub_through_write(1, 0x1A00);
+		sub_through_write(1, 0x1B00);
+		sub_through_write(1, 0x1C00);
+
+		sub_through_write(1, 0x151A);	/* Power setting */
+
+		sub_through_write(1, 0x2002);	/* Gradation Palette setting */
+		sub_through_write(1, 0x2107);
+		sub_through_write(1, 0x220C);
+		sub_through_write(1, 0x2310);
+		sub_through_write(1, 0x2414);
+		sub_through_write(1, 0x2518);
+		sub_through_write(1, 0x261C);
+		sub_through_write(1, 0x2720);
+		sub_through_write(1, 0x2824);
+		sub_through_write(1, 0x2928);
+		sub_through_write(1, 0x2A2B);
+		sub_through_write(1, 0x2B2E);
+		sub_through_write(1, 0x2C31);
+		sub_through_write(1, 0x2D34);
+		sub_through_write(1, 0x2E37);
+		sub_through_write(1, 0x2F3A);
+		sub_through_write(1, 0x303C);
+		sub_through_write(1, 0x313E);
+		sub_through_write(1, 0x323F);
+		sub_through_write(1, 0x3340);
+		sub_through_write(1, 0x3441);
+		sub_through_write(1, 0x3543);
+		sub_through_write(1, 0x3646);
+		sub_through_write(1, 0x3749);
+		sub_through_write(1, 0x384C);
+		sub_through_write(1, 0x394F);
+		sub_through_write(1, 0x3A52);
+		sub_through_write(1, 0x3B59);
+		sub_through_write(1, 0x3C60);
+		sub_through_write(1, 0x3D67);
+		sub_through_write(1, 0x3E6E);
+		sub_through_write(1, 0x3F7F);
+		sub_through_write(1, 0x4001);
+		sub_through_write(1, 0x4107);
+		sub_through_write(1, 0x420C);
+		sub_through_write(1, 0x4310);
+		sub_through_write(1, 0x4414);
+		sub_through_write(1, 0x4518);
+		sub_through_write(1, 0x461C);
+		sub_through_write(1, 0x4720);
+		sub_through_write(1, 0x4824);
+		sub_through_write(1, 0x4928);
+		sub_through_write(1, 0x4A2B);
+		sub_through_write(1, 0x4B2E);
+		sub_through_write(1, 0x4C31);
+		sub_through_write(1, 0x4D34);
+		sub_through_write(1, 0x4E37);
+		sub_through_write(1, 0x4F3A);
+		sub_through_write(1, 0x503C);
+		sub_through_write(1, 0x513E);
+		sub_through_write(1, 0x523F);
+		sub_through_write(1, 0x5340);
+		sub_through_write(1, 0x5441);
+		sub_through_write(1, 0x5543);
+		sub_through_write(1, 0x5646);
+		sub_through_write(1, 0x5749);
+		sub_through_write(1, 0x584C);
+		sub_through_write(1, 0x594F);
+		sub_through_write(1, 0x5A52);
+		sub_through_write(1, 0x5B59);
+		sub_through_write(1, 0x5C60);
+		sub_through_write(1, 0x5D67);
+		sub_through_write(1, 0x5E6E);
+		sub_through_write(1, 0x5F7E);
+		sub_through_write(1, 0x6000);
+		sub_through_write(1, 0x6107);
+		sub_through_write(1, 0x620C);
+		sub_through_write(1, 0x6310);
+		sub_through_write(1, 0x6414);
+		sub_through_write(1, 0x6518);
+		sub_through_write(1, 0x661C);
+		sub_through_write(1, 0x6720);
+		sub_through_write(1, 0x6824);
+		sub_through_write(1, 0x6928);
+		sub_through_write(1, 0x6A2B);
+		sub_through_write(1, 0x6B2E);
+		sub_through_write(1, 0x6C31);
+		sub_through_write(1, 0x6D34);
+		sub_through_write(1, 0x6E37);
+		sub_through_write(1, 0x6F3A);
+		sub_through_write(1, 0x703C);
+		sub_through_write(1, 0x713E);
+		sub_through_write(1, 0x723F);
+		sub_through_write(1, 0x7340);
+		sub_through_write(1, 0x7441);
+		sub_through_write(1, 0x7543);
+		sub_through_write(1, 0x7646);
+		sub_through_write(1, 0x7749);
+		sub_through_write(1, 0x784C);
+		sub_through_write(1, 0x794F);
+		sub_through_write(1, 0x7A52);
+		sub_through_write(1, 0x7B59);
+		sub_through_write(1, 0x7C60);
+		sub_through_write(1, 0x7D67);
+		sub_through_write(1, 0x7E6E);
+		sub_through_write(1, 0x7F7D);
+
+		sub_through_write(1, 0x1851);	/* Display on */
+
+		mddi_queue_register_write(REG_AGM, 0x0000, TRUE, 0);
+
+		/* 1 pixel / 1 post clock */
+		mddi_queue_register_write(REG_CLKDIV2, 0x3b00, FALSE, 0);
+
+		/* SUB LCD select */
+		mddi_queue_register_write(REG_PSTCTL2, 0x0080, FALSE, 0);
+
+		/* RS=0,command initiate number=0,select master mode */
+		mddi_queue_register_write(REG_SUBCTL, 0x0202, FALSE, 0);
+
+		/* Sub LCD Data transform start */
+		mddi_queue_register_write(REG_PSTCTL1, 0x0003, FALSE, 0);
+
+	} else if (sharp_subpanel_type == SHARP_SUB_ROHM) {
+
+		sub_through_write(0, 0x01);	/* Display setting */
+		sub_through_write(1, 0x00);
+
+		mddi_wait(1);
+		/* Wait 100us  <----- ******* Update 2005/01/24 */
+
+		sub_through_write(0, 0xB6);
+		sub_through_write(1, 0x0C);
+		sub_through_write(1, 0x4A);
+		sub_through_write(1, 0x20);
+		sub_through_write(0, 0x3A);
+		sub_through_write(1, 0x05);
+		sub_through_write(0, 0xB7);
+		sub_through_write(1, 0x01);
+		sub_through_write(0, 0xBA);
+		sub_through_write(1, 0x20);
+		sub_through_write(1, 0x02);
+		sub_through_write(0, 0x25);
+		sub_through_write(1, 0x4F);
+		sub_through_write(0, 0xBB);
+		sub_through_write(1, 0x00);
+		sub_through_write(0, 0x36);
+		sub_through_write(1, 0x00);
+		sub_through_write(0, 0xB1);
+		sub_through_write(1, 0x05);
+		sub_through_write(0, 0xBE);
+		sub_through_write(1, 0x80);
+		sub_through_write(0, 0x26);
+		sub_through_write(1, 0x01);
+		sub_through_write(0, 0x2A);
+		sub_through_write(1, 0x02);
+		sub_through_write(1, 0x81);
+		sub_through_write(0, 0x2B);
+		sub_through_write(1, 0x00);
+		sub_through_write(1, 0x7F);
+
+		sub_through_write(0, 0x2C);
+		sub_through_write(0, 0x11);	/* Sleep mode off */
+
+		mddi_wait(1);
+		/* Wait 100 ms <----- ******* Update 2005/01/24 */
+
+		sub_through_write(0, 0x29);	/* Display on */
+		sub_through_write(0, 0xB3);
+		sub_through_write(1, 0x20);
+		sub_through_write(1, 0xAA);
+		sub_through_write(1, 0xA0);
+		sub_through_write(1, 0x20);
+		sub_through_write(1, 0x30);
+		sub_through_write(1, 0xA6);
+		sub_through_write(1, 0xFF);
+		sub_through_write(1, 0x9A);
+		sub_through_write(1, 0x9F);
+		sub_through_write(1, 0xAF);
+		sub_through_write(1, 0xBC);
+		sub_through_write(1, 0xCF);
+		sub_through_write(1, 0xDF);
+		sub_through_write(1, 0x20);
+		sub_through_write(1, 0x9C);
+		sub_through_write(1, 0x8A);
+
+		sub_through_write(0, 0x002C);	/* Display on */
+
+		/* 1 pixel / 2 post clock */
+		mddi_queue_register_write(REG_CLKDIV2, 0x7b00, FALSE, 0);
+
+		/* SUB LCD select */
+		mddi_queue_register_write(REG_PSTCTL2, 0x0080, FALSE, 0);
+
+		/* RS=1,command initiate number=0,select master mode */
+		mddi_queue_register_write(REG_SUBCTL, 0x0242, FALSE, 0);
+
+		/* Sub LCD Data transform start */
+		mddi_queue_register_write(REG_PSTCTL1, 0x0003, FALSE, 0);
+
+	}
+
+	/* Set the MDP pixel data attributes for Sub Display */
+	mddi_host_write_pix_attr_reg(0x00C0);
+}
+
+void mddi_sharp_lcd_vsync_detected(boolean detected)
+{
+	/* static timetick_type start_time = 0; */
+	static struct timeval start_time;
+	static boolean first_time = TRUE;
+	/* uint32 mdp_cnt_val = 0; */
+	/* timetick_type elapsed_us; */
+	struct timeval now;
+	uint32 elapsed_us;
+	uint32 num_vsyncs;
+
+	if ((detected) || (mddi_sharp_vsync_attempts > 5)) {
+		if ((detected) && (mddi_sharp_monitor_refresh_value)) {
+			/* if (start_time != 0) */
+			if (!first_time) {
+				jiffies_to_timeval(jiffies, &now);
+				elapsed_us =
+				    (now.tv_sec - start_time.tv_sec) * 1000000 +
+				    now.tv_usec - start_time.tv_usec;
+				/*
+				* LCD is configured for a refresh every usecs,
+				* so to determine the number of vsyncs that
+				* have occurred since the last measurement add
+				* half that to the time difference and divide
+				* by the refresh rate.
+				*/
+				num_vsyncs = (elapsed_us +
+					      (mddi_sharp_usecs_per_refresh >>
+					       1)) /
+				    mddi_sharp_usecs_per_refresh;
+				/*
+				 * LCD is configured for * hsyncs (rows) per
+				 * refresh cycle. Calculate new rows_per_second
+				 * value based upon these new measurements.
+				 * MDP can update with this new value.
+				 */
+				mddi_sharp_rows_per_second =
+				    (mddi_sharp_rows_per_refresh * 1000 *
+				     num_vsyncs) / (elapsed_us / 1000);
+			}
+			/* start_time = timetick_get(); */
+			first_time = FALSE;
+			jiffies_to_timeval(jiffies, &start_time);
+			if (mddi_sharp_report_refresh_measurements) {
+				/* mdp_cnt_val = MDP_LINE_COUNT; */
+			}
+		}
+		/* if detected = TRUE, client initiated wakeup was detected */
+		if (mddi_sharp_vsync_handler != NULL) {
+			(*mddi_sharp_vsync_handler)
+			    (mddi_sharp_vsync_handler_arg);
+			mddi_sharp_vsync_handler = NULL;
+		}
+		mddi_vsync_detect_enabled = FALSE;
+		mddi_sharp_vsync_attempts = 0;
+		/* need to clear this vsync wakeup */
+		if (!mddi_queue_register_write_int(REG_INTR, 0x0000)) {
+			MDDI_MSG_ERR("Vsync interrupt clear failed!\n");
+		}
+		if (!detected) {
+			/* give up after 5 failed attempts but show error */
+			MDDI_MSG_NOTICE("Vsync detection failed!\n");
+		} else if ((mddi_sharp_monitor_refresh_value) &&
+			(mddi_sharp_report_refresh_measurements)) {
+			MDDI_MSG_NOTICE("  Lines Per Second=%d!\n",
+				mddi_sharp_rows_per_second);
+		}
+	} else
+		/* if detected = FALSE, we woke up from hibernation, but did not
+		 * detect client initiated wakeup.
+		 */
+		mddi_sharp_vsync_attempts++;
+}
+
+/* ISR to be executed */
+void mddi_sharp_vsync_set_handler(msm_fb_vsync_handler_type handler, void *arg)
+{
+	boolean error = FALSE;
+	unsigned long flags;
+
+	/* Disable interrupts */
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+	/* INTLOCK(); */
+
+	if (mddi_sharp_vsync_handler != NULL)
+		error = TRUE;
+
+	/* Register the handler for this particular GROUP interrupt source */
+	mddi_sharp_vsync_handler = handler;
+	mddi_sharp_vsync_handler_arg = arg;
+
+	/* Restore interrupts */
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+	/* INTFREE(); */
+
+	if (error)
+		MDDI_MSG_ERR("MDDI: Previous Vsync handler never called\n");
+
+	/* Enable the vsync wakeup */
+	mddi_queue_register_write(REG_INTR, 0x8100, FALSE, 0);
+
+	mddi_sharp_vsync_attempts = 1;
+	mddi_vsync_detect_enabled = TRUE;
+}				/* mddi_sharp_vsync_set_handler */
+
+static int mddi_sharp_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mddi_host_client_cnt_reset();
+
+	if (mfd->panel.id == SHARP_QVGA_PRIM)
+		mddi_sharp_prim_lcd_init();
+	else
+		mddi_sharp_sub_lcd_init();
+
+	return 0;
+}
+
+static int mddi_sharp_lcd_off(struct platform_device *pdev)
+{
+	if (mddi_sharp_vsync_handler != NULL) {
+		(*mddi_sharp_vsync_handler)
+			    (mddi_sharp_vsync_handler_arg);
+		mddi_sharp_vsync_handler = NULL;
+		printk(KERN_INFO "%s: clean up vsyn_handler=%x\n", __func__,
+				(int)mddi_sharp_vsync_handler);
+	}
+
+	mddi_sharp_lcd_powerdown();
+	return 0;
+}
+
+static int __devinit mddi_sharp_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		mddi_sharp_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mddi_sharp_probe,
+	.driver = {
+		.name   = "mddi_sharp_qvga",
+	},
+};
+
+static struct msm_fb_panel_data mddi_sharp_panel_data0 = {
+	.on = mddi_sharp_lcd_on,
+	.off = mddi_sharp_lcd_off,
+	.set_backlight = mddi_sharp_lcd_set_backlight,
+	.set_vsync_notifier = mddi_sharp_vsync_set_handler,
+};
+
+static struct platform_device this_device_0 = {
+	.name   = "mddi_sharp_qvga",
+	.id	= SHARP_QVGA_PRIM,
+	.dev	= {
+		.platform_data = &mddi_sharp_panel_data0,
+	}
+};
+
+static struct msm_fb_panel_data mddi_sharp_panel_data1 = {
+	.on = mddi_sharp_lcd_on,
+	.off = mddi_sharp_lcd_off,
+};
+
+static struct platform_device this_device_1 = {
+	.name   = "mddi_sharp_qvga",
+	.id	= SHARP_128X128_SECD,
+	.dev	= {
+		.platform_data = &mddi_sharp_panel_data1,
+	}
+};
+
+static int __init mddi_sharp_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	u32 id;
+
+	ret = msm_fb_detect_client("mddi_sharp_qvga");
+	if (ret == -ENODEV)
+		return 0;
+
+	if (ret) {
+		id = mddi_get_client_id();
+
+		if (((id >> 16) != 0x0) || ((id & 0xffff) != 0x8835))
+			return 0;
+	}
+#endif
+	if (mddi_host_core_version > 8) {
+		/* can use faster refresh with newer hw revisions */
+		mddi_sharp_debug_60hz_refresh = TRUE;
+
+		/* Timing variables for tracking vsync */
+		/* dot_clock = 6.00MHz
+		 * horizontal count = 296
+		 * vertical count = 338
+		 * refresh rate = 6000000/(296+338) = 60Hz
+		 */
+		mddi_sharp_rows_per_second = 20270;	/* 6000000/296 */
+		mddi_sharp_rows_per_refresh = 338;
+		mddi_sharp_usecs_per_refresh = 16674;	/* (296+338)/6000000 */
+	} else {
+		/* Timing variables for tracking vsync */
+		/* dot_clock = 5.20MHz
+		 * horizontal count = 376
+		 * vertical count = 338
+		 * refresh rate = 5200000/(376+338) = 41Hz
+		 */
+		mddi_sharp_rows_per_second = 13830;	/* 5200000/376 */
+		mddi_sharp_rows_per_refresh = 338;
+		mddi_sharp_usecs_per_refresh = 24440;	/* (376+338)/5200000 */
+	}
+
+	ret = platform_driver_register(&this_driver);
+	if (!ret) {
+		pinfo = &mddi_sharp_panel_data0.panel_info;
+		pinfo->xres = 240;
+		pinfo->yres = 320;
+		MSM_FB_SINGLE_MODE_PANEL(pinfo);
+		pinfo->type = MDDI_PANEL;
+		pinfo->pdest = DISPLAY_1;
+		pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
+		pinfo->wait_cycle = 0;
+		pinfo->bpp = 18;
+		pinfo->fb_num = 2;
+		pinfo->clk_rate = 122880000;
+		pinfo->clk_min = 120000000;
+		pinfo->clk_max = 125000000;
+		pinfo->lcd.vsync_enable = TRUE;
+		pinfo->mddi.is_type1 = TRUE;
+		pinfo->lcd.refx100 =
+			(mddi_sharp_rows_per_second * 100) /
+			mddi_sharp_rows_per_refresh;
+		pinfo->lcd.v_back_porch = 12;
+		pinfo->lcd.v_front_porch = 6;
+		pinfo->lcd.v_pulse_width = 0;
+		pinfo->lcd.hw_vsync_mode = FALSE;
+		pinfo->lcd.vsync_notifier_period = (1 * HZ);
+		pinfo->bl_max = 7;
+		pinfo->bl_min = 1;
+
+		ret = platform_device_register(&this_device_0);
+		if (ret)
+			platform_driver_unregister(&this_driver);
+
+		pinfo = &mddi_sharp_panel_data1.panel_info;
+		pinfo->xres = 128;
+		pinfo->yres = 128;
+		MSM_FB_SINGLE_MODE_PANEL(pinfo);
+		pinfo->type = MDDI_PANEL;
+		pinfo->pdest = DISPLAY_2;
+		pinfo->mddi.vdopkt = 0x400;
+		pinfo->wait_cycle = 0;
+		pinfo->bpp = 18;
+		pinfo->clk_rate = 122880000;
+		pinfo->clk_min = 120000000;
+		pinfo->clk_max = 125000000;
+		pinfo->fb_num = 2;
+
+		ret = platform_device_register(&this_device_1);
+		if (ret) {
+			platform_device_unregister(&this_device_0);
+			platform_driver_unregister(&this_driver);
+		}
+	}
+
+	if (!ret)
+		mddi_lcd.vsync_detected = mddi_sharp_lcd_vsync_detected;
+
+	return ret;
+}
+
+module_init(mddi_sharp_init);
diff --git a/drivers/video/msm/mddi_toshiba.c b/drivers/video/msm/mddi_toshiba.c
new file mode 100644
index 0000000..9727453
--- /dev/null
+++ b/drivers/video/msm/mddi_toshiba.c
@@ -0,0 +1,1753 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+#include "mddi_toshiba.h"
+
+#define TM_GET_DID(id) ((id) & 0xff)
+#define TM_GET_PID(id) (((id) & 0xff00)>>8)
+
+#define MDDI_CLIENT_CORE_BASE  0x108000
+#define LCD_CONTROL_BLOCK_BASE 0x110000
+#define SPI_BLOCK_BASE         0x120000
+#define PWM_BLOCK_BASE         0x140000
+#define SYSTEM_BLOCK1_BASE     0x160000
+
+#define TTBUSSEL    (MDDI_CLIENT_CORE_BASE|0x18)
+#define DPSET0      (MDDI_CLIENT_CORE_BASE|0x1C)
+#define DPSET1      (MDDI_CLIENT_CORE_BASE|0x20)
+#define DPSUS       (MDDI_CLIENT_CORE_BASE|0x24)
+#define DPRUN       (MDDI_CLIENT_CORE_BASE|0x28)
+#define SYSCKENA    (MDDI_CLIENT_CORE_BASE|0x2C)
+
+#define BITMAP0     (MDDI_CLIENT_CORE_BASE|0x44)
+#define BITMAP1     (MDDI_CLIENT_CORE_BASE|0x48)
+#define BITMAP2     (MDDI_CLIENT_CORE_BASE|0x4C)
+#define BITMAP3     (MDDI_CLIENT_CORE_BASE|0x50)
+#define BITMAP4     (MDDI_CLIENT_CORE_BASE|0x54)
+
+#define SRST        (LCD_CONTROL_BLOCK_BASE|0x00)
+#define PORT_ENB    (LCD_CONTROL_BLOCK_BASE|0x04)
+#define START       (LCD_CONTROL_BLOCK_BASE|0x08)
+#define PORT        (LCD_CONTROL_BLOCK_BASE|0x0C)
+
+#define INTFLG      (LCD_CONTROL_BLOCK_BASE|0x18)
+#define INTMSK      (LCD_CONTROL_BLOCK_BASE|0x1C)
+#define MPLFBUF     (LCD_CONTROL_BLOCK_BASE|0x20)
+
+#define PXL         (LCD_CONTROL_BLOCK_BASE|0x30)
+#define HCYCLE      (LCD_CONTROL_BLOCK_BASE|0x34)
+#define HSW         (LCD_CONTROL_BLOCK_BASE|0x38)
+#define HDE_START   (LCD_CONTROL_BLOCK_BASE|0x3C)
+#define HDE_SIZE    (LCD_CONTROL_BLOCK_BASE|0x40)
+#define VCYCLE      (LCD_CONTROL_BLOCK_BASE|0x44)
+#define VSW         (LCD_CONTROL_BLOCK_BASE|0x48)
+#define VDE_START   (LCD_CONTROL_BLOCK_BASE|0x4C)
+#define VDE_SIZE    (LCD_CONTROL_BLOCK_BASE|0x50)
+#define WAKEUP      (LCD_CONTROL_BLOCK_BASE|0x54)
+#define REGENB      (LCD_CONTROL_BLOCK_BASE|0x5C)
+#define VSYNIF      (LCD_CONTROL_BLOCK_BASE|0x60)
+#define WRSTB       (LCD_CONTROL_BLOCK_BASE|0x64)
+#define RDSTB       (LCD_CONTROL_BLOCK_BASE|0x68)
+#define ASY_DATA    (LCD_CONTROL_BLOCK_BASE|0x6C)
+#define ASY_DATB    (LCD_CONTROL_BLOCK_BASE|0x70)
+#define ASY_DATC    (LCD_CONTROL_BLOCK_BASE|0x74)
+#define ASY_DATD    (LCD_CONTROL_BLOCK_BASE|0x78)
+#define ASY_DATE    (LCD_CONTROL_BLOCK_BASE|0x7C)
+#define ASY_DATF    (LCD_CONTROL_BLOCK_BASE|0x80)
+#define ASY_DATG    (LCD_CONTROL_BLOCK_BASE|0x84)
+#define ASY_DATH    (LCD_CONTROL_BLOCK_BASE|0x88)
+#define ASY_CMDSET  (LCD_CONTROL_BLOCK_BASE|0x8C)
+#define MONI        (LCD_CONTROL_BLOCK_BASE|0xB0)
+#define VPOS        (LCD_CONTROL_BLOCK_BASE|0xC0)
+
+#define SSICTL      (SPI_BLOCK_BASE|0x00)
+#define SSITIME     (SPI_BLOCK_BASE|0x04)
+#define SSITX       (SPI_BLOCK_BASE|0x08)
+#define SSIINTS     (SPI_BLOCK_BASE|0x14)
+
+#define TIMER0LOAD    (PWM_BLOCK_BASE|0x00)
+#define TIMER0CTRL    (PWM_BLOCK_BASE|0x08)
+#define PWM0OFF       (PWM_BLOCK_BASE|0x1C)
+#define TIMER1LOAD    (PWM_BLOCK_BASE|0x20)
+#define TIMER1CTRL    (PWM_BLOCK_BASE|0x28)
+#define PWM1OFF       (PWM_BLOCK_BASE|0x3C)
+#define TIMER2LOAD    (PWM_BLOCK_BASE|0x40)
+#define TIMER2CTRL    (PWM_BLOCK_BASE|0x48)
+#define PWM2OFF       (PWM_BLOCK_BASE|0x5C)
+#define PWMCR         (PWM_BLOCK_BASE|0x68)
+
+#define GPIOIS      (GPIO_BLOCK_BASE|0x08)
+#define GPIOIEV     (GPIO_BLOCK_BASE|0x10)
+#define GPIOIC      (GPIO_BLOCK_BASE|0x20)
+
+#define WKREQ       (SYSTEM_BLOCK1_BASE|0x00)
+#define CLKENB      (SYSTEM_BLOCK1_BASE|0x04)
+#define DRAMPWR     (SYSTEM_BLOCK1_BASE|0x08)
+#define INTMASK     (SYSTEM_BLOCK1_BASE|0x0C)
+#define CNT_DIS     (SYSTEM_BLOCK1_BASE|0x10)
+
+typedef enum {
+	TOSHIBA_STATE_OFF,
+	TOSHIBA_STATE_PRIM_SEC_STANDBY,
+	TOSHIBA_STATE_PRIM_SEC_READY,
+	TOSHIBA_STATE_PRIM_NORMAL_MODE,
+	TOSHIBA_STATE_SEC_NORMAL_MODE
+} mddi_toshiba_state_t;
+
+static uint32 mddi_toshiba_curr_vpos;
+static boolean mddi_toshiba_monitor_refresh_value = FALSE;
+static boolean mddi_toshiba_report_refresh_measurements = FALSE;
+
+boolean mddi_toshiba_61Hz_refresh = TRUE;
+
+/* Modifications to timing to increase refresh rate to > 60Hz.
+ *   20MHz dot clock.
+ *   646 total rows.
+ *   506 total columns.
+ *   refresh rate = 61.19Hz
+ */
+static uint32 mddi_toshiba_rows_per_second = 39526;
+static uint32 mddi_toshiba_usecs_per_refresh = 16344;
+static uint32 mddi_toshiba_rows_per_refresh = 646;
+extern boolean mddi_vsync_detect_enabled;
+
+static msm_fb_vsync_handler_type mddi_toshiba_vsync_handler;
+static void *mddi_toshiba_vsync_handler_arg;
+static uint16 mddi_toshiba_vsync_attempts;
+
+static mddi_toshiba_state_t toshiba_state = TOSHIBA_STATE_OFF;
+
+static struct msm_panel_common_pdata *mddi_toshiba_pdata;
+
+static int mddi_toshiba_lcd_on(struct platform_device *pdev);
+static int mddi_toshiba_lcd_off(struct platform_device *pdev);
+
+static void mddi_toshiba_state_transition(mddi_toshiba_state_t a,
+					  mddi_toshiba_state_t b)
+{
+	if (toshiba_state != a) {
+		MDDI_MSG_ERR("toshiba state trans. (%d->%d) found %d\n", a, b,
+			     toshiba_state);
+	}
+	toshiba_state = b;
+}
+
+#define GORDON_REG_IMGCTL1      0x10	/* Image interface control 1   */
+#define GORDON_REG_IMGCTL2      0x11	/* Image interface control 2   */
+#define GORDON_REG_IMGSET1      0x12	/* Image interface settings 1  */
+#define GORDON_REG_IMGSET2      0x13	/* Image interface settings 2  */
+#define GORDON_REG_IVBP1        0x14	/* DM0: Vert back porch        */
+#define GORDON_REG_IHBP1        0x15	/* DM0: Horiz back porch       */
+#define GORDON_REG_IVNUM1       0x16	/* DM0: Num of vert lines      */
+#define GORDON_REG_IHNUM1       0x17	/* DM0: Num of pixels per line */
+#define GORDON_REG_IVBP2        0x18	/* DM1: Vert back porch        */
+#define GORDON_REG_IHBP2        0x19	/* DM1: Horiz back porch       */
+#define GORDON_REG_IVNUM2       0x1A	/* DM1: Num of vert lines      */
+#define GORDON_REG_IHNUM2       0x1B	/* DM1: Num of pixels per line */
+#define GORDON_REG_LCDIFCTL1    0x30	/* LCD interface control 1     */
+#define GORDON_REG_VALTRAN      0x31	/* LCD IF ctl: VALTRAN sync flag */
+#define GORDON_REG_AVCTL        0x33
+#define GORDON_REG_LCDIFCTL2    0x34	/* LCD interface control 2     */
+#define GORDON_REG_LCDIFCTL3    0x35	/* LCD interface control 3     */
+#define GORDON_REG_LCDIFSET1    0x36	/* LCD interface settings 1    */
+#define GORDON_REG_PCCTL        0x3C
+#define GORDON_REG_TPARAM1      0x40
+#define GORDON_REG_TLCDIF1      0x41
+#define GORDON_REG_TSSPB_ST1    0x42
+#define GORDON_REG_TSSPB_ED1    0x43
+#define GORDON_REG_TSCK_ST1     0x44
+#define GORDON_REG_TSCK_WD1     0x45
+#define GORDON_REG_TGSPB_VST1   0x46
+#define GORDON_REG_TGSPB_VED1   0x47
+#define GORDON_REG_TGSPB_CH1    0x48
+#define GORDON_REG_TGCK_ST1     0x49
+#define GORDON_REG_TGCK_ED1     0x4A
+#define GORDON_REG_TPCTL_ST1    0x4B
+#define GORDON_REG_TPCTL_ED1    0x4C
+#define GORDON_REG_TPCHG_ED1    0x4D
+#define GORDON_REG_TCOM_CH1     0x4E
+#define GORDON_REG_THBP1        0x4F
+#define GORDON_REG_TPHCTL1      0x50
+#define GORDON_REG_EVPH1        0x51
+#define GORDON_REG_EVPL1        0x52
+#define GORDON_REG_EVNH1        0x53
+#define GORDON_REG_EVNL1        0x54
+#define GORDON_REG_TBIAS1       0x55
+#define GORDON_REG_TPARAM2      0x56
+#define GORDON_REG_TLCDIF2      0x57
+#define GORDON_REG_TSSPB_ST2    0x58
+#define GORDON_REG_TSSPB_ED2    0x59
+#define GORDON_REG_TSCK_ST2     0x5A
+#define GORDON_REG_TSCK_WD2     0x5B
+#define GORDON_REG_TGSPB_VST2   0x5C
+#define GORDON_REG_TGSPB_VED2   0x5D
+#define GORDON_REG_TGSPB_CH2    0x5E
+#define GORDON_REG_TGCK_ST2     0x5F
+#define GORDON_REG_TGCK_ED2     0x60
+#define GORDON_REG_TPCTL_ST2    0x61
+#define GORDON_REG_TPCTL_ED2    0x62
+#define GORDON_REG_TPCHG_ED2    0x63
+#define GORDON_REG_TCOM_CH2     0x64
+#define GORDON_REG_THBP2        0x65
+#define GORDON_REG_TPHCTL2      0x66
+#define GORDON_REG_EVPH2        0x67
+#define GORDON_REG_EVPL2        0x68
+#define GORDON_REG_EVNH2        0x69
+#define GORDON_REG_EVNL2        0x6A
+#define GORDON_REG_TBIAS2       0x6B
+#define GORDON_REG_POWCTL       0x80
+#define GORDON_REG_POWOSC1      0x81
+#define GORDON_REG_POWOSC2      0x82
+#define GORDON_REG_POWSET       0x83
+#define GORDON_REG_POWTRM1      0x85
+#define GORDON_REG_POWTRM2      0x86
+#define GORDON_REG_POWTRM3      0x87
+#define GORDON_REG_POWTRMSEL    0x88
+#define GORDON_REG_POWHIZ       0x89
+
+void serigo(uint16 reg, uint8 data)
+{
+	uint32 mddi_val = 0;
+	mddi_queue_register_read(SSIINTS, &mddi_val, TRUE, 0);
+	if (mddi_val & (1 << 8))
+		mddi_wait(1);
+	/* No De-assert of CS and send 2 bytes */
+	mddi_val = 0x90000 | ((0x00FF & reg) << 8) | data;
+	mddi_queue_register_write(SSITX, mddi_val, TRUE, 0);
+}
+
+void gordon_init(void)
+{
+       /* Image interface settings ***/
+	serigo(GORDON_REG_IMGCTL2, 0x00);
+	serigo(GORDON_REG_IMGSET1, 0x01);
+
+	/* Exchange the RGB signal for J510(Softbank mobile) */
+	serigo(GORDON_REG_IMGSET2, 0x12);
+	serigo(GORDON_REG_LCDIFSET1, 0x00);
+	mddi_wait(2);
+
+	/* Pre-charge settings */
+	serigo(GORDON_REG_PCCTL, 0x09);
+	serigo(GORDON_REG_LCDIFCTL2, 0x1B);
+	mddi_wait(1);
+}
+
+void gordon_disp_on(void)
+{
+	/*gordon_dispmode setting */
+	/*VGA settings */
+	serigo(GORDON_REG_TPARAM1, 0x30);
+	serigo(GORDON_REG_TLCDIF1, 0x00);
+	serigo(GORDON_REG_TSSPB_ST1, 0x8B);
+	serigo(GORDON_REG_TSSPB_ED1, 0x93);
+	mddi_wait(2);
+	serigo(GORDON_REG_TSCK_ST1, 0x88);
+	serigo(GORDON_REG_TSCK_WD1, 0x00);
+	serigo(GORDON_REG_TGSPB_VST1, 0x01);
+	serigo(GORDON_REG_TGSPB_VED1, 0x02);
+	mddi_wait(2);
+	serigo(GORDON_REG_TGSPB_CH1, 0x5E);
+	serigo(GORDON_REG_TGCK_ST1, 0x80);
+	serigo(GORDON_REG_TGCK_ED1, 0x3C);
+	serigo(GORDON_REG_TPCTL_ST1, 0x50);
+	mddi_wait(2);
+	serigo(GORDON_REG_TPCTL_ED1, 0x74);
+	serigo(GORDON_REG_TPCHG_ED1, 0x78);
+	serigo(GORDON_REG_TCOM_CH1, 0x50);
+	serigo(GORDON_REG_THBP1, 0x84);
+	mddi_wait(2);
+	serigo(GORDON_REG_TPHCTL1, 0x00);
+	serigo(GORDON_REG_EVPH1, 0x70);
+	serigo(GORDON_REG_EVPL1, 0x64);
+	serigo(GORDON_REG_EVNH1, 0x56);
+	mddi_wait(2);
+	serigo(GORDON_REG_EVNL1, 0x48);
+	serigo(GORDON_REG_TBIAS1, 0x88);
+	mddi_wait(2);
+	serigo(GORDON_REG_TPARAM2, 0x28);
+	serigo(GORDON_REG_TLCDIF2, 0x14);
+	serigo(GORDON_REG_TSSPB_ST2, 0x49);
+	serigo(GORDON_REG_TSSPB_ED2, 0x4B);
+	mddi_wait(2);
+	serigo(GORDON_REG_TSCK_ST2, 0x4A);
+	serigo(GORDON_REG_TSCK_WD2, 0x02);
+	serigo(GORDON_REG_TGSPB_VST2, 0x02);
+	serigo(GORDON_REG_TGSPB_VED2, 0x03);
+	mddi_wait(2);
+	serigo(GORDON_REG_TGSPB_CH2, 0x2F);
+	serigo(GORDON_REG_TGCK_ST2, 0x40);
+	serigo(GORDON_REG_TGCK_ED2, 0x1E);
+	serigo(GORDON_REG_TPCTL_ST2, 0x2C);
+	mddi_wait(2);
+	serigo(GORDON_REG_TPCTL_ED2, 0x3A);
+	serigo(GORDON_REG_TPCHG_ED2, 0x3C);
+	serigo(GORDON_REG_TCOM_CH2, 0x28);
+	serigo(GORDON_REG_THBP2, 0x4D);
+	mddi_wait(2);
+	serigo(GORDON_REG_TPHCTL2, 0x1A);
+	mddi_wait(2);
+	serigo(GORDON_REG_IVBP1, 0x02);
+	serigo(GORDON_REG_IHBP1, 0x90);
+	serigo(GORDON_REG_IVNUM1, 0xA0);
+	serigo(GORDON_REG_IHNUM1, 0x78);
+	mddi_wait(2);
+	serigo(GORDON_REG_IVBP2, 0x02);
+	serigo(GORDON_REG_IHBP2, 0x48);
+	serigo(GORDON_REG_IVNUM2, 0x50);
+	serigo(GORDON_REG_IHNUM2, 0x3C);
+	mddi_wait(2);
+	serigo(GORDON_REG_POWCTL, 0x03);
+	mddi_wait(15);
+	serigo(GORDON_REG_POWCTL, 0x07);
+	mddi_wait(15);
+	serigo(GORDON_REG_POWCTL, 0x0F);
+	mddi_wait(15);
+	serigo(GORDON_REG_AVCTL, 0x03);
+	mddi_wait(15);
+	serigo(GORDON_REG_POWCTL, 0x1F);
+	mddi_wait(15);
+	serigo(GORDON_REG_POWCTL, 0x5F);
+	mddi_wait(15);
+	serigo(GORDON_REG_POWCTL, 0x7F);
+	mddi_wait(15);
+	serigo(GORDON_REG_LCDIFCTL1, 0x02);
+	mddi_wait(15);
+	serigo(GORDON_REG_IMGCTL1, 0x00);
+	mddi_wait(15);
+	serigo(GORDON_REG_LCDIFCTL3, 0x00);
+	mddi_wait(15);
+	serigo(GORDON_REG_VALTRAN, 0x01);
+	mddi_wait(15);
+	serigo(GORDON_REG_LCDIFCTL1, 0x03);
+	serigo(GORDON_REG_LCDIFCTL1, 0x03);
+	mddi_wait(1);
+}
+
+void gordon_disp_off(void)
+{
+	serigo(GORDON_REG_LCDIFCTL2, 0x7B);
+	serigo(GORDON_REG_VALTRAN, 0x01);
+	serigo(GORDON_REG_LCDIFCTL1, 0x02);
+	serigo(GORDON_REG_LCDIFCTL3, 0x01);
+	mddi_wait(20);
+	serigo(GORDON_REG_VALTRAN, 0x01);
+	serigo(GORDON_REG_IMGCTL1, 0x01);
+	serigo(GORDON_REG_LCDIFCTL1, 0x00);
+	mddi_wait(20);
+	serigo(GORDON_REG_POWCTL, 0x1F);
+	mddi_wait(40);
+	serigo(GORDON_REG_POWCTL, 0x07);
+	mddi_wait(40);
+	serigo(GORDON_REG_POWCTL, 0x03);
+	mddi_wait(40);
+	serigo(GORDON_REG_POWCTL, 0x00);
+	mddi_wait(40);
+}
+
+void gordon_disp_init(void)
+{
+	gordon_init();
+	mddi_wait(20);
+	gordon_disp_on();
+}
+
+static void toshiba_common_initial_setup(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) {
+		write_client_reg(DPSET0    , 0x4bec0066, TRUE);
+		write_client_reg(DPSET1    , 0x00000113, TRUE);
+		write_client_reg(DPSUS     , 0x00000000, TRUE);
+		write_client_reg(DPRUN     , 0x00000001, TRUE);
+		mddi_wait(5);
+		write_client_reg(SYSCKENA  , 0x00000001, TRUE);
+		write_client_reg(CLKENB    , 0x0000a0e9, TRUE);
+
+		write_client_reg(GPIODATA  , 0x03FF0000, TRUE);
+		write_client_reg(GPIODIR   , 0x0000024D, TRUE);
+		write_client_reg(GPIOSEL   , 0x00000173, TRUE);
+		write_client_reg(GPIOPC    , 0x03C300C0, TRUE);
+		write_client_reg(WKREQ     , 0x00000000, TRUE);
+		write_client_reg(GPIOIS    , 0x00000000, TRUE);
+		write_client_reg(GPIOIEV   , 0x00000001, TRUE);
+		write_client_reg(GPIOIC    , 0x000003FF, TRUE);
+		write_client_reg(GPIODATA  , 0x00040004, TRUE);
+
+		write_client_reg(GPIODATA  , 0x00080008, TRUE);
+		write_client_reg(DRAMPWR   , 0x00000001, TRUE);
+		write_client_reg(CLKENB    , 0x0000a0eb, TRUE);
+		write_client_reg(PWMCR     , 0x00000000, TRUE);
+		mddi_wait(1);
+
+		write_client_reg(SSICTL    , 0x00060399, TRUE);
+		write_client_reg(SSITIME   , 0x00000100, TRUE);
+		write_client_reg(CNT_DIS   , 0x00000002, TRUE);
+		write_client_reg(SSICTL    , 0x0006039b, TRUE);
+
+		write_client_reg(SSITX     , 0x00000000, TRUE);
+		mddi_wait(7);
+		write_client_reg(SSITX     , 0x00000000, TRUE);
+		mddi_wait(7);
+		write_client_reg(SSITX     , 0x00000000, TRUE);
+		mddi_wait(7);
+
+		write_client_reg(SSITX     , 0x000800BA, TRUE);
+		write_client_reg(SSITX     , 0x00000111, TRUE);
+		write_client_reg(SSITX     , 0x00080036, TRUE);
+		write_client_reg(SSITX     , 0x00000100, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x0008003A, TRUE);
+		write_client_reg(SSITX     , 0x00000160, TRUE);
+		write_client_reg(SSITX     , 0x000800B1, TRUE);
+		write_client_reg(SSITX     , 0x0000015D, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800B2, TRUE);
+		write_client_reg(SSITX     , 0x00000133, TRUE);
+		write_client_reg(SSITX     , 0x000800B3, TRUE);
+		write_client_reg(SSITX     , 0x00000122, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800B4, TRUE);
+		write_client_reg(SSITX     , 0x00000102, TRUE);
+		write_client_reg(SSITX     , 0x000800B5, TRUE);
+		write_client_reg(SSITX     , 0x0000011E, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800B6, TRUE);
+		write_client_reg(SSITX     , 0x00000127, TRUE);
+		write_client_reg(SSITX     , 0x000800B7, TRUE);
+		write_client_reg(SSITX     , 0x00000103, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800B9, TRUE);
+		write_client_reg(SSITX     , 0x00000124, TRUE);
+		write_client_reg(SSITX     , 0x000800BD, TRUE);
+		write_client_reg(SSITX     , 0x000001A1, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800BB, TRUE);
+		write_client_reg(SSITX     , 0x00000100, TRUE);
+		write_client_reg(SSITX     , 0x000800BF, TRUE);
+		write_client_reg(SSITX     , 0x00000101, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800BE, TRUE);
+		write_client_reg(SSITX     , 0x00000100, TRUE);
+		write_client_reg(SSITX     , 0x000800C0, TRUE);
+		write_client_reg(SSITX     , 0x00000111, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800C1, TRUE);
+		write_client_reg(SSITX     , 0x00000111, TRUE);
+		write_client_reg(SSITX     , 0x000800C2, TRUE);
+		write_client_reg(SSITX     , 0x00000111, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800C3, TRUE);
+		write_client_reg(SSITX     , 0x00080132, TRUE);
+		write_client_reg(SSITX     , 0x00000132, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800C4, TRUE);
+		write_client_reg(SSITX     , 0x00080132, TRUE);
+		write_client_reg(SSITX     , 0x00000132, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800C5, TRUE);
+		write_client_reg(SSITX     , 0x00080132, TRUE);
+		write_client_reg(SSITX     , 0x00000132, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800C6, TRUE);
+		write_client_reg(SSITX     , 0x00080132, TRUE);
+		write_client_reg(SSITX     , 0x00000132, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800C7, TRUE);
+		write_client_reg(SSITX     , 0x00080164, TRUE);
+		write_client_reg(SSITX     , 0x00000145, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800C8, TRUE);
+		write_client_reg(SSITX     , 0x00000144, TRUE);
+		write_client_reg(SSITX     , 0x000800C9, TRUE);
+		write_client_reg(SSITX     , 0x00000152, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800CA, TRUE);
+		write_client_reg(SSITX     , 0x00000100, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800EC, TRUE);
+		write_client_reg(SSITX     , 0x00080101, TRUE);
+		write_client_reg(SSITX     , 0x000001FC, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800CF, TRUE);
+		write_client_reg(SSITX     , 0x00000101, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800D0, TRUE);
+		write_client_reg(SSITX     , 0x00080110, TRUE);
+		write_client_reg(SSITX     , 0x00000104, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800D1, TRUE);
+		write_client_reg(SSITX     , 0x00000101, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800D2, TRUE);
+		write_client_reg(SSITX     , 0x00080100, TRUE);
+		write_client_reg(SSITX     , 0x00000128, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800D3, TRUE);
+		write_client_reg(SSITX     , 0x00080100, TRUE);
+		write_client_reg(SSITX     , 0x00000128, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800D4, TRUE);
+		write_client_reg(SSITX     , 0x00080126, TRUE);
+		write_client_reg(SSITX     , 0x000001A4, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800D5, TRUE);
+		write_client_reg(SSITX     , 0x00000120, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800EF, TRUE);
+		write_client_reg(SSITX     , 0x00080132, TRUE);
+		write_client_reg(SSITX     , 0x00000100, TRUE);
+		mddi_wait(1);
+
+		write_client_reg(BITMAP0   , 0x032001E0, TRUE);
+		write_client_reg(BITMAP1   , 0x032001E0, TRUE);
+		write_client_reg(BITMAP2   , 0x014000F0, TRUE);
+		write_client_reg(BITMAP3   , 0x014000F0, TRUE);
+		write_client_reg(BITMAP4   , 0x014000F0, TRUE);
+		write_client_reg(CLKENB    , 0x0000A1EB, TRUE);
+		write_client_reg(PORT_ENB  , 0x00000001, TRUE);
+		write_client_reg(PORT      , 0x00000004, TRUE);
+		write_client_reg(PXL       , 0x00000002, TRUE);
+		write_client_reg(MPLFBUF   , 0x00000000, TRUE);
+		write_client_reg(HCYCLE    , 0x000000FD, TRUE);
+		write_client_reg(HSW       , 0x00000003, TRUE);
+		write_client_reg(HDE_START , 0x00000007, TRUE);
+		write_client_reg(HDE_SIZE  , 0x000000EF, TRUE);
+		write_client_reg(VCYCLE    , 0x00000325, TRUE);
+		write_client_reg(VSW       , 0x00000001, TRUE);
+		write_client_reg(VDE_START , 0x00000003, TRUE);
+		write_client_reg(VDE_SIZE  , 0x0000031F, TRUE);
+		write_client_reg(START     , 0x00000001, TRUE);
+		mddi_wait(32);
+		write_client_reg(SSITX     , 0x000800BC, TRUE);
+		write_client_reg(SSITX     , 0x00000180, TRUE);
+		write_client_reg(SSITX     , 0x0008003B, TRUE);
+		write_client_reg(SSITX     , 0x00000100, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800B0, TRUE);
+		write_client_reg(SSITX     , 0x00000116, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x000800B8, TRUE);
+		write_client_reg(SSITX     , 0x000801FF, TRUE);
+		write_client_reg(SSITX     , 0x000001F5, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX     , 0x00000011, TRUE);
+		mddi_wait(5);
+		write_client_reg(SSITX     , 0x00000029, TRUE);
+		return;
+	}
+
+	if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) {
+		write_client_reg(DPSET0, 0x4BEC0066, TRUE);
+		write_client_reg(DPSET1, 0x00000113, TRUE);
+		write_client_reg(DPSUS, 0x00000000, TRUE);
+		write_client_reg(DPRUN, 0x00000001, TRUE);
+		mddi_wait(14);
+		write_client_reg(SYSCKENA, 0x00000001, TRUE);
+		write_client_reg(CLKENB, 0x000000EF, TRUE);
+		write_client_reg(GPIO_BLOCK_BASE, 0x03FF0000, TRUE);
+		write_client_reg(GPIODIR, 0x0000024D, TRUE);
+		write_client_reg(SYSTEM_BLOCK2_BASE, 0x00000173, TRUE);
+		write_client_reg(GPIOPC, 0x03C300C0, TRUE);
+		write_client_reg(SYSTEM_BLOCK1_BASE, 0x00000000, TRUE);
+		write_client_reg(GPIOIS, 0x00000000, TRUE);
+		write_client_reg(GPIOIEV, 0x00000001, TRUE);
+		write_client_reg(GPIOIC, 0x000003FF, TRUE);
+		write_client_reg(GPIO_BLOCK_BASE, 0x00060006, TRUE);
+		write_client_reg(GPIO_BLOCK_BASE, 0x00080008, TRUE);
+		write_client_reg(GPIO_BLOCK_BASE, 0x02000200, TRUE);
+		write_client_reg(DRAMPWR, 0x00000001, TRUE);
+		write_client_reg(TIMER0CTRL, 0x00000060, TRUE);
+		write_client_reg(PWM_BLOCK_BASE, 0x00001388, TRUE);
+		write_client_reg(PWM0OFF, 0x00001387, TRUE);
+		write_client_reg(TIMER1CTRL, 0x00000060, TRUE);
+		write_client_reg(TIMER1LOAD, 0x00001388, TRUE);
+		write_client_reg(PWM1OFF, 0x00001387, TRUE);
+		write_client_reg(TIMER0CTRL, 0x000000E0, TRUE);
+		write_client_reg(TIMER1CTRL, 0x000000E0, TRUE);
+		write_client_reg(PWMCR, 0x00000003, TRUE);
+		mddi_wait(1);
+		write_client_reg(SPI_BLOCK_BASE, 0x00063111, TRUE);
+		write_client_reg(SSITIME, 0x00000100, TRUE);
+		write_client_reg(SPI_BLOCK_BASE, 0x00063113, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x00000000, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x00000000, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x00000000, TRUE);
+		mddi_wait(1);
+		write_client_reg(CLKENB, 0x0000A1EF, TRUE);
+		write_client_reg(START, 0x00000000, TRUE);
+		write_client_reg(WRSTB, 0x0000003F, TRUE);
+		write_client_reg(RDSTB, 0x00000432, TRUE);
+		write_client_reg(PORT_ENB, 0x00000002, TRUE);
+		write_client_reg(VSYNIF, 0x00000000, TRUE);
+		write_client_reg(ASY_DATA, 0x80000000, TRUE);
+		write_client_reg(ASY_DATB, 0x00000001, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+		mddi_wait(10);
+		write_client_reg(ASY_DATA, 0x80000000, TRUE);
+		write_client_reg(ASY_DATB, 0x80000000, TRUE);
+		write_client_reg(ASY_DATC, 0x80000000, TRUE);
+		write_client_reg(ASY_DATD, 0x80000000, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
+		write_client_reg(ASY_DATA, 0x80000007, TRUE);
+		write_client_reg(ASY_DATB, 0x00004005, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+		mddi_wait(20);
+		write_client_reg(ASY_DATA, 0x80000059, TRUE);
+		write_client_reg(ASY_DATB, 0x00000000, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+
+		write_client_reg(VSYNIF, 0x00000001, TRUE);
+		write_client_reg(PORT_ENB, 0x00000001, TRUE);
+	} else {
+		write_client_reg(DPSET0, 0x4BEC0066, TRUE);
+		write_client_reg(DPSET1, 0x00000113, TRUE);
+		write_client_reg(DPSUS, 0x00000000, TRUE);
+		write_client_reg(DPRUN, 0x00000001, TRUE);
+		mddi_wait(14);
+		write_client_reg(SYSCKENA, 0x00000001, TRUE);
+		write_client_reg(CLKENB, 0x000000EF, TRUE);
+		write_client_reg(GPIODATA, 0x03FF0000, TRUE);
+		write_client_reg(GPIODIR, 0x0000024D, TRUE);
+		write_client_reg(GPIOSEL, 0x00000173, TRUE);
+		write_client_reg(GPIOPC, 0x03C300C0, TRUE);
+		write_client_reg(WKREQ, 0x00000000, TRUE);
+		write_client_reg(GPIOIS, 0x00000000, TRUE);
+		write_client_reg(GPIOIEV, 0x00000001, TRUE);
+		write_client_reg(GPIOIC, 0x000003FF, TRUE);
+		write_client_reg(GPIODATA, 0x00060006, TRUE);
+		write_client_reg(GPIODATA, 0x00080008, TRUE);
+		write_client_reg(GPIODATA, 0x02000200, TRUE);
+
+		if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA) {
+			mddi_wait(400);
+			write_client_reg(DRAMPWR, 0x00000001, TRUE);
+
+			write_client_reg(CNT_DIS, 0x00000002, TRUE);
+			write_client_reg(BITMAP0, 0x01E00320, TRUE);
+			write_client_reg(PORT_ENB, 0x00000001, TRUE);
+			write_client_reg(PORT, 0x00000004, TRUE);
+			write_client_reg(PXL, 0x0000003A, TRUE);
+			write_client_reg(MPLFBUF, 0x00000000, TRUE);
+			write_client_reg(HCYCLE, 0x00000253, TRUE);
+			write_client_reg(HSW, 0x00000003, TRUE);
+			write_client_reg(HDE_START, 0x00000017, TRUE);
+			write_client_reg(HDE_SIZE, 0x0000018F, TRUE);
+			write_client_reg(VCYCLE, 0x000001FF, TRUE);
+			write_client_reg(VSW, 0x00000001, TRUE);
+			write_client_reg(VDE_START, 0x00000003, TRUE);
+			write_client_reg(VDE_SIZE, 0x000001DF, TRUE);
+			write_client_reg(START, 0x00000001, TRUE);
+			mddi_wait(1);
+			write_client_reg(TIMER0CTRL, 0x00000060, TRUE);
+			write_client_reg(TIMER0LOAD, 0x00001388, TRUE);
+			write_client_reg(TIMER1CTRL, 0x00000060, TRUE);
+			write_client_reg(TIMER1LOAD, 0x00001388, TRUE);
+			write_client_reg(PWM1OFF, 0x00000087, TRUE);
+		} else {
+			write_client_reg(DRAMPWR, 0x00000001, TRUE);
+			write_client_reg(TIMER0CTRL, 0x00000060, TRUE);
+			write_client_reg(TIMER0LOAD, 0x00001388, TRUE);
+			write_client_reg(TIMER1CTRL, 0x00000060, TRUE);
+			write_client_reg(TIMER1LOAD, 0x00001388, TRUE);
+			write_client_reg(PWM1OFF, 0x00001387, TRUE);
+		}
+
+		write_client_reg(TIMER0CTRL, 0x000000E0, TRUE);
+		write_client_reg(TIMER1CTRL, 0x000000E0, TRUE);
+		write_client_reg(PWMCR, 0x00000003, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSICTL, 0x00000799, TRUE);
+		write_client_reg(SSITIME, 0x00000100, TRUE);
+		write_client_reg(SSICTL, 0x0000079b, TRUE);
+		write_client_reg(SSITX, 0x00000000, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x00000000, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x00000000, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x000800BA, TRUE);
+		write_client_reg(SSITX, 0x00000111, TRUE);
+		write_client_reg(SSITX, 0x00080036, TRUE);
+		write_client_reg(SSITX, 0x00000100, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800BB, TRUE);
+		write_client_reg(SSITX, 0x00000100, TRUE);
+		write_client_reg(SSITX, 0x0008003A, TRUE);
+		write_client_reg(SSITX, 0x00000160, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800BF, TRUE);
+		write_client_reg(SSITX, 0x00000100, TRUE);
+		write_client_reg(SSITX, 0x000800B1, TRUE);
+		write_client_reg(SSITX, 0x0000015D, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800B2, TRUE);
+		write_client_reg(SSITX, 0x00000133, TRUE);
+		write_client_reg(SSITX, 0x000800B3, TRUE);
+		write_client_reg(SSITX, 0x00000122, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800B4, TRUE);
+		write_client_reg(SSITX, 0x00000102, TRUE);
+		write_client_reg(SSITX, 0x000800B5, TRUE);
+		write_client_reg(SSITX, 0x0000011F, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800B6, TRUE);
+		write_client_reg(SSITX, 0x00000128, TRUE);
+		write_client_reg(SSITX, 0x000800B7, TRUE);
+		write_client_reg(SSITX, 0x00000103, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800B9, TRUE);
+		write_client_reg(SSITX, 0x00000120, TRUE);
+		write_client_reg(SSITX, 0x000800BD, TRUE);
+		write_client_reg(SSITX, 0x00000102, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800BE, TRUE);
+		write_client_reg(SSITX, 0x00000100, TRUE);
+		write_client_reg(SSITX, 0x000800C0, TRUE);
+		write_client_reg(SSITX, 0x00000111, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800C1, TRUE);
+		write_client_reg(SSITX, 0x00000111, TRUE);
+		write_client_reg(SSITX, 0x000800C2, TRUE);
+		write_client_reg(SSITX, 0x00000111, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800C3, TRUE);
+		write_client_reg(SSITX, 0x0008010A, TRUE);
+		write_client_reg(SSITX, 0x0000010A, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800C4, TRUE);
+		write_client_reg(SSITX, 0x00080160, TRUE);
+		write_client_reg(SSITX, 0x00000160, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800C5, TRUE);
+		write_client_reg(SSITX, 0x00080160, TRUE);
+		write_client_reg(SSITX, 0x00000160, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800C6, TRUE);
+		write_client_reg(SSITX, 0x00080160, TRUE);
+		write_client_reg(SSITX, 0x00000160, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800C7, TRUE);
+		write_client_reg(SSITX, 0x00080133, TRUE);
+		write_client_reg(SSITX, 0x00000143, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800C8, TRUE);
+		write_client_reg(SSITX, 0x00000144, TRUE);
+		write_client_reg(SSITX, 0x000800C9, TRUE);
+		write_client_reg(SSITX, 0x00000133, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800CA, TRUE);
+		write_client_reg(SSITX, 0x00000100, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800EC, TRUE);
+		write_client_reg(SSITX, 0x00080102, TRUE);
+		write_client_reg(SSITX, 0x00000118, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800CF, TRUE);
+		write_client_reg(SSITX, 0x00000101, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D0, TRUE);
+		write_client_reg(SSITX, 0x00080110, TRUE);
+		write_client_reg(SSITX, 0x00000104, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D1, TRUE);
+		write_client_reg(SSITX, 0x00000101, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D2, TRUE);
+		write_client_reg(SSITX, 0x00080100, TRUE);
+		write_client_reg(SSITX, 0x0000013A, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D3, TRUE);
+		write_client_reg(SSITX, 0x00080100, TRUE);
+		write_client_reg(SSITX, 0x0000013A, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D4, TRUE);
+		write_client_reg(SSITX, 0x00080124, TRUE);
+		write_client_reg(SSITX, 0x0000016E, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x000800D5, TRUE);
+		write_client_reg(SSITX, 0x00000124, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800ED, TRUE);
+		write_client_reg(SSITX, 0x00080101, TRUE);
+		write_client_reg(SSITX, 0x0000010A, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D6, TRUE);
+		write_client_reg(SSITX, 0x00000101, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D7, TRUE);
+		write_client_reg(SSITX, 0x00080110, TRUE);
+		write_client_reg(SSITX, 0x0000010A, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D8, TRUE);
+		write_client_reg(SSITX, 0x00000101, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800D9, TRUE);
+		write_client_reg(SSITX, 0x00080100, TRUE);
+		write_client_reg(SSITX, 0x00000114, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800DE, TRUE);
+		write_client_reg(SSITX, 0x00080100, TRUE);
+		write_client_reg(SSITX, 0x00000114, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800DF, TRUE);
+		write_client_reg(SSITX, 0x00080112, TRUE);
+		write_client_reg(SSITX, 0x0000013F, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800E0, TRUE);
+		write_client_reg(SSITX, 0x0000010B, TRUE);
+		write_client_reg(SSITX, 0x000800E2, TRUE);
+		write_client_reg(SSITX, 0x00000101, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800E3, TRUE);
+		write_client_reg(SSITX, 0x00000136, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800E4, TRUE);
+		write_client_reg(SSITX, 0x00080100, TRUE);
+		write_client_reg(SSITX, 0x00000103, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800E5, TRUE);
+		write_client_reg(SSITX, 0x00080102, TRUE);
+		write_client_reg(SSITX, 0x00000104, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800E6, TRUE);
+		write_client_reg(SSITX, 0x00000103, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800E7, TRUE);
+		write_client_reg(SSITX, 0x00080104, TRUE);
+		write_client_reg(SSITX, 0x0000010A, TRUE);
+		mddi_wait(2);
+		write_client_reg(SSITX, 0x000800E8, TRUE);
+		write_client_reg(SSITX, 0x00000104, TRUE);
+		write_client_reg(CLKENB, 0x000001EF, TRUE);
+		write_client_reg(START, 0x00000000, TRUE);
+		write_client_reg(WRSTB, 0x0000003F, TRUE);
+		write_client_reg(RDSTB, 0x00000432, TRUE);
+		write_client_reg(PORT_ENB, 0x00000002, TRUE);
+		write_client_reg(VSYNIF, 0x00000000, TRUE);
+		write_client_reg(ASY_DATA, 0x80000000, TRUE);
+		write_client_reg(ASY_DATB, 0x00000001, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+		mddi_wait(10);
+		write_client_reg(ASY_DATA, 0x80000000, TRUE);
+		write_client_reg(ASY_DATB, 0x80000000, TRUE);
+		write_client_reg(ASY_DATC, 0x80000000, TRUE);
+		write_client_reg(ASY_DATD, 0x80000000, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
+		write_client_reg(ASY_DATA, 0x80000007, TRUE);
+		write_client_reg(ASY_DATB, 0x00004005, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+		mddi_wait(20);
+		write_client_reg(ASY_DATA, 0x80000059, TRUE);
+		write_client_reg(ASY_DATB, 0x00000000, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+		write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+		write_client_reg(VSYNIF, 0x00000001, TRUE);
+		write_client_reg(PORT_ENB, 0x00000001, TRUE);
+	}
+
+	mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_STANDBY,
+				      TOSHIBA_STATE_PRIM_SEC_READY);
+}
+
+static void toshiba_prim_start(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
+		return;
+
+	if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) {
+		write_client_reg(BITMAP1, 0x01E000F0, TRUE);
+		write_client_reg(BITMAP2, 0x01E000F0, TRUE);
+		write_client_reg(BITMAP3, 0x01E000F0, TRUE);
+		write_client_reg(BITMAP4, 0x00DC00B0, TRUE);
+		write_client_reg(CLKENB, 0x000001EF, TRUE);
+		write_client_reg(PORT_ENB, 0x00000001, TRUE);
+		write_client_reg(PORT, 0x00000016, TRUE);
+		write_client_reg(PXL, 0x00000002, TRUE);
+		write_client_reg(MPLFBUF, 0x00000000, TRUE);
+		write_client_reg(HCYCLE, 0x00000185, TRUE);
+		write_client_reg(HSW, 0x00000018, TRUE);
+		write_client_reg(HDE_START, 0x0000004A, TRUE);
+		write_client_reg(HDE_SIZE, 0x000000EF, TRUE);
+		write_client_reg(VCYCLE, 0x0000028E, TRUE);
+		write_client_reg(VSW, 0x00000004, TRUE);
+		write_client_reg(VDE_START, 0x00000009, TRUE);
+		write_client_reg(VDE_SIZE, 0x0000027F, TRUE);
+		write_client_reg(START, 0x00000001, TRUE);
+		write_client_reg(SYSTEM_BLOCK1_BASE, 0x00000002, TRUE);
+	} else{
+
+		write_client_reg(VSYNIF, 0x00000001, TRUE);
+		write_client_reg(PORT_ENB, 0x00000001, TRUE);
+		write_client_reg(BITMAP1, 0x01E000F0, TRUE);
+		write_client_reg(BITMAP2, 0x01E000F0, TRUE);
+		write_client_reg(BITMAP3, 0x01E000F0, TRUE);
+		write_client_reg(BITMAP4, 0x00DC00B0, TRUE);
+		write_client_reg(CLKENB, 0x000001EF, TRUE);
+		write_client_reg(PORT_ENB, 0x00000001, TRUE);
+		write_client_reg(PORT, 0x00000004, TRUE);
+		write_client_reg(PXL, 0x00000002, TRUE);
+		write_client_reg(MPLFBUF, 0x00000000, TRUE);
+
+		if (mddi_toshiba_61Hz_refresh) {
+			write_client_reg(HCYCLE, 0x000000FC, TRUE);
+			mddi_toshiba_rows_per_second = 39526;
+			mddi_toshiba_rows_per_refresh = 646;
+			mddi_toshiba_usecs_per_refresh = 16344;
+		} else {
+			write_client_reg(HCYCLE, 0x0000010b, TRUE);
+			mddi_toshiba_rows_per_second = 37313;
+			mddi_toshiba_rows_per_refresh = 646;
+			mddi_toshiba_usecs_per_refresh = 17313;
+		}
+
+		write_client_reg(HSW, 0x00000003, TRUE);
+		write_client_reg(HDE_START, 0x00000007, TRUE);
+		write_client_reg(HDE_SIZE, 0x000000EF, TRUE);
+		write_client_reg(VCYCLE, 0x00000285, TRUE);
+		write_client_reg(VSW, 0x00000001, TRUE);
+		write_client_reg(VDE_START, 0x00000003, TRUE);
+		write_client_reg(VDE_SIZE, 0x0000027F, TRUE);
+		write_client_reg(START, 0x00000001, TRUE);
+		mddi_wait(10);
+		write_client_reg(SSITX, 0x000800BC, TRUE);
+		write_client_reg(SSITX, 0x00000180, TRUE);
+		write_client_reg(SSITX, 0x0008003B, TRUE);
+		write_client_reg(SSITX, 0x00000100, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x000800B0, TRUE);
+		write_client_reg(SSITX, 0x00000116, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x000800B8, TRUE);
+		write_client_reg(SSITX, 0x000801FF, TRUE);
+		write_client_reg(SSITX, 0x000001F5, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x00000011, TRUE);
+		write_client_reg(SSITX, 0x00000029, TRUE);
+		write_client_reg(WKREQ, 0x00000000, TRUE);
+		write_client_reg(WAKEUP, 0x00000000, TRUE);
+		write_client_reg(INTMSK, 0x00000001, TRUE);
+	}
+
+	mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_READY,
+				      TOSHIBA_STATE_PRIM_NORMAL_MODE);
+}
+
+static void toshiba_sec_start(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
+		return;
+
+	write_client_reg(VSYNIF, 0x00000000, TRUE);
+	write_client_reg(PORT_ENB, 0x00000002, TRUE);
+	write_client_reg(CLKENB, 0x000011EF, TRUE);
+	write_client_reg(BITMAP0, 0x028001E0, TRUE);
+	write_client_reg(BITMAP1, 0x00000000, TRUE);
+	write_client_reg(BITMAP2, 0x00000000, TRUE);
+	write_client_reg(BITMAP3, 0x00000000, TRUE);
+	write_client_reg(BITMAP4, 0x00DC00B0, TRUE);
+	write_client_reg(PORT, 0x00000000, TRUE);
+	write_client_reg(PXL, 0x00000000, TRUE);
+	write_client_reg(MPLFBUF, 0x00000004, TRUE);
+	write_client_reg(HCYCLE, 0x0000006B, TRUE);
+	write_client_reg(HSW, 0x00000003, TRUE);
+	write_client_reg(HDE_START, 0x00000007, TRUE);
+	write_client_reg(HDE_SIZE, 0x00000057, TRUE);
+	write_client_reg(VCYCLE, 0x000000E6, TRUE);
+	write_client_reg(VSW, 0x00000001, TRUE);
+	write_client_reg(VDE_START, 0x00000003, TRUE);
+	write_client_reg(VDE_SIZE, 0x000000DB, TRUE);
+	write_client_reg(ASY_DATA, 0x80000001, TRUE);
+	write_client_reg(ASY_DATB, 0x0000011B, TRUE);
+	write_client_reg(ASY_DATC, 0x80000002, TRUE);
+	write_client_reg(ASY_DATD, 0x00000700, TRUE);
+	write_client_reg(ASY_DATE, 0x80000003, TRUE);
+	write_client_reg(ASY_DATF, 0x00000230, TRUE);
+	write_client_reg(ASY_DATG, 0x80000008, TRUE);
+	write_client_reg(ASY_DATH, 0x00000402, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	write_client_reg(ASY_DATA, 0x80000009, TRUE);
+	write_client_reg(ASY_DATB, 0x00000000, TRUE);
+	write_client_reg(ASY_DATC, 0x8000000B, TRUE);
+	write_client_reg(ASY_DATD, 0x00000000, TRUE);
+	write_client_reg(ASY_DATE, 0x8000000C, TRUE);
+	write_client_reg(ASY_DATF, 0x00000000, TRUE);
+	write_client_reg(ASY_DATG, 0x8000000D, TRUE);
+	write_client_reg(ASY_DATH, 0x00000409, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	write_client_reg(ASY_DATA, 0x8000000E, TRUE);
+	write_client_reg(ASY_DATB, 0x00000409, TRUE);
+	write_client_reg(ASY_DATC, 0x80000030, TRUE);
+	write_client_reg(ASY_DATD, 0x00000000, TRUE);
+	write_client_reg(ASY_DATE, 0x80000031, TRUE);
+	write_client_reg(ASY_DATF, 0x00000100, TRUE);
+	write_client_reg(ASY_DATG, 0x80000032, TRUE);
+	write_client_reg(ASY_DATH, 0x00000104, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	write_client_reg(ASY_DATA, 0x80000033, TRUE);
+	write_client_reg(ASY_DATB, 0x00000400, TRUE);
+	write_client_reg(ASY_DATC, 0x80000034, TRUE);
+	write_client_reg(ASY_DATD, 0x00000306, TRUE);
+	write_client_reg(ASY_DATE, 0x80000035, TRUE);
+	write_client_reg(ASY_DATF, 0x00000706, TRUE);
+	write_client_reg(ASY_DATG, 0x80000036, TRUE);
+	write_client_reg(ASY_DATH, 0x00000707, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	write_client_reg(ASY_DATA, 0x80000037, TRUE);
+	write_client_reg(ASY_DATB, 0x00000004, TRUE);
+	write_client_reg(ASY_DATC, 0x80000038, TRUE);
+	write_client_reg(ASY_DATD, 0x00000000, TRUE);
+	write_client_reg(ASY_DATE, 0x80000039, TRUE);
+	write_client_reg(ASY_DATF, 0x00000000, TRUE);
+	write_client_reg(ASY_DATG, 0x8000003A, TRUE);
+	write_client_reg(ASY_DATH, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	write_client_reg(ASY_DATA, 0x80000044, TRUE);
+	write_client_reg(ASY_DATB, 0x0000AF00, TRUE);
+	write_client_reg(ASY_DATC, 0x80000045, TRUE);
+	write_client_reg(ASY_DATD, 0x0000DB00, TRUE);
+	write_client_reg(ASY_DATE, 0x08000042, TRUE);
+	write_client_reg(ASY_DATF, 0x0000DB00, TRUE);
+	write_client_reg(ASY_DATG, 0x80000021, TRUE);
+	write_client_reg(ASY_DATH, 0x00000000, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	write_client_reg(PXL, 0x0000000C, TRUE);
+	write_client_reg(VSYNIF, 0x00000001, TRUE);
+	write_client_reg(ASY_DATA, 0x80000022, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000003, TRUE);
+	write_client_reg(START, 0x00000001, TRUE);
+	mddi_wait(60);
+	write_client_reg(PXL, 0x00000000, TRUE);
+	write_client_reg(VSYNIF, 0x00000000, TRUE);
+	write_client_reg(START, 0x00000000, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	write_client_reg(ASY_DATA, 0x80000050, TRUE);
+	write_client_reg(ASY_DATB, 0x00000000, TRUE);
+	write_client_reg(ASY_DATC, 0x80000051, TRUE);
+	write_client_reg(ASY_DATD, 0x00000E00, TRUE);
+	write_client_reg(ASY_DATE, 0x80000052, TRUE);
+	write_client_reg(ASY_DATF, 0x00000D01, TRUE);
+	write_client_reg(ASY_DATG, 0x80000053, TRUE);
+	write_client_reg(ASY_DATH, 0x00000000, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	write_client_reg(ASY_DATA, 0x80000058, TRUE);
+	write_client_reg(ASY_DATB, 0x00000000, TRUE);
+	write_client_reg(ASY_DATC, 0x8000005A, TRUE);
+	write_client_reg(ASY_DATD, 0x00000E01, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
+	write_client_reg(ASY_DATA, 0x80000011, TRUE);
+	write_client_reg(ASY_DATB, 0x00000812, TRUE);
+	write_client_reg(ASY_DATC, 0x80000012, TRUE);
+	write_client_reg(ASY_DATD, 0x00000003, TRUE);
+	write_client_reg(ASY_DATE, 0x80000013, TRUE);
+	write_client_reg(ASY_DATF, 0x00000909, TRUE);
+	write_client_reg(ASY_DATG, 0x80000010, TRUE);
+	write_client_reg(ASY_DATH, 0x00000040, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	mddi_wait(40);
+	write_client_reg(ASY_DATA, 0x80000010, TRUE);
+	write_client_reg(ASY_DATB, 0x00000340, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(60);
+	write_client_reg(ASY_DATA, 0x80000010, TRUE);
+	write_client_reg(ASY_DATB, 0x00003340, TRUE);
+	write_client_reg(ASY_DATC, 0x80000007, TRUE);
+	write_client_reg(ASY_DATD, 0x00004007, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
+	mddi_wait(1);
+	write_client_reg(ASY_DATA, 0x80000007, TRUE);
+	write_client_reg(ASY_DATB, 0x00004017, TRUE);
+	write_client_reg(ASY_DATC, 0x8000005B, TRUE);
+	write_client_reg(ASY_DATD, 0x00000000, TRUE);
+	write_client_reg(ASY_DATE, 0x80000059, TRUE);
+	write_client_reg(ASY_DATF, 0x00000011, TRUE);
+	write_client_reg(ASY_CMDSET, 0x0000000D, TRUE);
+	write_client_reg(ASY_CMDSET, 0x0000000C, TRUE);
+	mddi_wait(20);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	/* LTPS I/F control */
+	write_client_reg(ASY_DATB, 0x00000019, TRUE);
+	/* Direct cmd transfer enable */
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	/* Direct cmd transfer disable */
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(20);
+	/* Index setting of SUB LCDD */
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	/* LTPS I/F control */
+	write_client_reg(ASY_DATB, 0x00000079, TRUE);
+	/* Direct cmd transfer enable */
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	/* Direct cmd transfer disable */
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(20);
+	/* Index setting of SUB LCDD */
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	/* LTPS I/F control */
+	write_client_reg(ASY_DATB, 0x000003FD, TRUE);
+	/* Direct cmd transfer enable */
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	/* Direct cmd transfer disable */
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(20);
+	mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_READY,
+				      TOSHIBA_STATE_SEC_NORMAL_MODE);
+}
+
+static void toshiba_prim_lcd_off(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) {
+		gordon_disp_off();
+	} else{
+
+		/* Main panel power off (Deep standby in) */
+		write_client_reg(SSITX, 0x000800BC, TRUE);
+		write_client_reg(SSITX, 0x00000100, TRUE);
+		write_client_reg(SSITX, 0x00000028, TRUE);
+		mddi_wait(1);
+		write_client_reg(SSITX, 0x000800B8, TRUE);
+		write_client_reg(SSITX, 0x00000180, TRUE);
+		write_client_reg(SSITX, 0x00000102, TRUE);
+		write_client_reg(SSITX, 0x00000010, TRUE);
+	}
+	write_client_reg(PORT, 0x00000003, TRUE);
+	write_client_reg(REGENB, 0x00000001, TRUE);
+	mddi_wait(1);
+	write_client_reg(PXL, 0x00000000, TRUE);
+	write_client_reg(START, 0x00000000, TRUE);
+	write_client_reg(REGENB, 0x00000001, TRUE);
+	mddi_wait(3);
+	if (TM_GET_PID(mfd->panel.id) != LCD_SHARP_2P4_VGA) {
+		write_client_reg(SSITX, 0x000800B0, TRUE);
+		write_client_reg(SSITX, 0x00000100, TRUE);
+	}
+	mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_NORMAL_MODE,
+				      TOSHIBA_STATE_PRIM_SEC_STANDBY);
+}
+
+static void toshiba_sec_lcd_off(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
+		return;
+
+	write_client_reg(VSYNIF, 0x00000000, TRUE);
+	write_client_reg(PORT_ENB, 0x00000002, TRUE);
+	write_client_reg(ASY_DATA, 0x80000007, TRUE);
+	write_client_reg(ASY_DATB, 0x00004016, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x00000019, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x0000000B, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x00000002, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(4);
+	write_client_reg(ASY_DATA, 0x80000010, TRUE);
+	write_client_reg(ASY_DATB, 0x00000300, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(4);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x00000000, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000007, TRUE);
+	write_client_reg(ASY_DATB, 0x00004004, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(PORT, 0x00000000, TRUE);
+	write_client_reg(PXL, 0x00000000, TRUE);
+	write_client_reg(START, 0x00000000, TRUE);
+	write_client_reg(VSYNIF, 0x00000001, TRUE);
+	write_client_reg(PORT_ENB, 0x00000001, TRUE);
+	write_client_reg(REGENB, 0x00000001, TRUE);
+	mddi_toshiba_state_transition(TOSHIBA_STATE_SEC_NORMAL_MODE,
+				      TOSHIBA_STATE_PRIM_SEC_STANDBY);
+}
+
+static void toshiba_sec_cont_update_start(struct msm_fb_data_type *mfd)
+{
+
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
+		return;
+
+	write_client_reg(VSYNIF, 0x00000000, TRUE);
+	write_client_reg(PORT_ENB, 0x00000002, TRUE);
+	write_client_reg(INTMASK, 0x00000001, TRUE);
+	write_client_reg(TTBUSSEL, 0x0000000B, TRUE);
+	write_client_reg(MONI, 0x00000008, TRUE);
+	write_client_reg(CLKENB, 0x000000EF, TRUE);
+	write_client_reg(CLKENB, 0x000010EF, TRUE);
+	write_client_reg(CLKENB, 0x000011EF, TRUE);
+	write_client_reg(BITMAP4, 0x00DC00B0, TRUE);
+	write_client_reg(HCYCLE, 0x0000006B, TRUE);
+	write_client_reg(HSW, 0x00000003, TRUE);
+	write_client_reg(HDE_START, 0x00000002, TRUE);
+	write_client_reg(HDE_SIZE, 0x00000057, TRUE);
+	write_client_reg(VCYCLE, 0x000000E6, TRUE);
+	write_client_reg(VSW, 0x00000001, TRUE);
+	write_client_reg(VDE_START, 0x00000003, TRUE);
+	write_client_reg(VDE_SIZE, 0x000000DB, TRUE);
+	write_client_reg(WRSTB, 0x00000015, TRUE);
+	write_client_reg(MPLFBUF, 0x00000004, TRUE);
+	write_client_reg(ASY_DATA, 0x80000021, TRUE);
+	write_client_reg(ASY_DATB, 0x00000000, TRUE);
+	write_client_reg(ASY_DATC, 0x80000022, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000007, TRUE);
+	write_client_reg(PXL, 0x00000089, TRUE);
+	write_client_reg(VSYNIF, 0x00000001, TRUE);
+	mddi_wait(2);
+}
+
+static void toshiba_sec_cont_update_stop(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
+		return;
+
+	write_client_reg(PXL, 0x00000000, TRUE);
+	write_client_reg(VSYNIF, 0x00000000, TRUE);
+	write_client_reg(START, 0x00000000, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	mddi_wait(3);
+	write_client_reg(SRST, 0x00000002, TRUE);
+	mddi_wait(3);
+	write_client_reg(SRST, 0x00000003, TRUE);
+}
+
+static void toshiba_sec_backlight_on(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
+		return;
+
+	write_client_reg(TIMER0CTRL, 0x00000060, TRUE);
+	write_client_reg(TIMER0LOAD, 0x00001388, TRUE);
+	write_client_reg(PWM0OFF, 0x00000001, TRUE);
+	write_client_reg(TIMER1CTRL, 0x00000060, TRUE);
+	write_client_reg(TIMER1LOAD, 0x00001388, TRUE);
+	write_client_reg(PWM1OFF, 0x00001387, TRUE);
+	write_client_reg(TIMER0CTRL, 0x000000E0, TRUE);
+	write_client_reg(TIMER1CTRL, 0x000000E0, TRUE);
+	write_client_reg(PWMCR, 0x00000003, TRUE);
+}
+
+static void toshiba_sec_sleep_in(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
+		return;
+
+	write_client_reg(VSYNIF, 0x00000000, TRUE);
+	write_client_reg(PORT_ENB, 0x00000002, TRUE);
+	write_client_reg(ASY_DATA, 0x80000007, TRUE);
+	write_client_reg(ASY_DATB, 0x00004016, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x00000019, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x0000000B, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x00000002, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(4);
+	write_client_reg(ASY_DATA, 0x80000010, TRUE);
+	write_client_reg(ASY_DATB, 0x00000300, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(4);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x00000000, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000007, TRUE);
+	write_client_reg(ASY_DATB, 0x00004004, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(PORT, 0x00000000, TRUE);
+	write_client_reg(PXL, 0x00000000, TRUE);
+	write_client_reg(START, 0x00000000, TRUE);
+	write_client_reg(REGENB, 0x00000001, TRUE);
+	/* Sleep in sequence */
+	write_client_reg(ASY_DATA, 0x80000010, TRUE);
+	write_client_reg(ASY_DATB, 0x00000302, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+}
+
+static void toshiba_sec_sleep_out(struct msm_fb_data_type *mfd)
+{
+	if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT)
+		return;
+
+	write_client_reg(VSYNIF, 0x00000000, TRUE);
+	write_client_reg(PORT_ENB, 0x00000002, TRUE);
+	write_client_reg(ASY_DATA, 0x80000010, TRUE);
+	write_client_reg(ASY_DATB, 0x00000300, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	/*  Display ON sequence */
+	write_client_reg(ASY_DATA, 0x80000011, TRUE);
+	write_client_reg(ASY_DATB, 0x00000812, TRUE);
+	write_client_reg(ASY_DATC, 0x80000012, TRUE);
+	write_client_reg(ASY_DATD, 0x00000003, TRUE);
+	write_client_reg(ASY_DATE, 0x80000013, TRUE);
+	write_client_reg(ASY_DATF, 0x00000909, TRUE);
+	write_client_reg(ASY_DATG, 0x80000010, TRUE);
+	write_client_reg(ASY_DATH, 0x00000040, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000001, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000000, TRUE);
+	mddi_wait(4);
+	write_client_reg(ASY_DATA, 0x80000010, TRUE);
+	write_client_reg(ASY_DATB, 0x00000340, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(6);
+	write_client_reg(ASY_DATA, 0x80000010, TRUE);
+	write_client_reg(ASY_DATB, 0x00003340, TRUE);
+	write_client_reg(ASY_DATC, 0x80000007, TRUE);
+	write_client_reg(ASY_DATD, 0x00004007, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000009, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000008, TRUE);
+	mddi_wait(1);
+	write_client_reg(ASY_DATA, 0x80000007, TRUE);
+	write_client_reg(ASY_DATB, 0x00004017, TRUE);
+	write_client_reg(ASY_DATC, 0x8000005B, TRUE);
+	write_client_reg(ASY_DATD, 0x00000000, TRUE);
+	write_client_reg(ASY_DATE, 0x80000059, TRUE);
+	write_client_reg(ASY_DATF, 0x00000011, TRUE);
+	write_client_reg(ASY_CMDSET, 0x0000000D, TRUE);
+	write_client_reg(ASY_CMDSET, 0x0000000C, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x00000019, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x00000079, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+	write_client_reg(ASY_DATA, 0x80000059, TRUE);
+	write_client_reg(ASY_DATB, 0x000003FD, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000005, TRUE);
+	write_client_reg(ASY_CMDSET, 0x00000004, TRUE);
+	mddi_wait(2);
+}
+
+static void mddi_toshiba_lcd_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int32 level;
+	int ret = -EPERM;
+	int max = mfd->panel_info.bl_max;
+	int min = mfd->panel_info.bl_min;
+	int i = 0;
+
+	if (mddi_toshiba_pdata && mddi_toshiba_pdata->pmic_backlight) {
+		while (i++ < 3) {
+			ret = mddi_toshiba_pdata->pmic_backlight(mfd->bl_level);
+			if (!ret)
+				return;
+			msleep(10);
+		}
+		printk(KERN_WARNING "%s: pmic_backlight Failed\n", __func__);
+	}
+
+
+	if (ret && mddi_toshiba_pdata && mddi_toshiba_pdata->backlight_level) {
+		level = mddi_toshiba_pdata->backlight_level(mfd->bl_level,
+								max, min);
+
+		if (level < 0)
+			return;
+
+		if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA)
+			write_client_reg(TIMER0LOAD, 0x00001388, TRUE);
+	} else {
+		if (!max)
+			level = 0;
+		else
+			level = (mfd->bl_level * 4999) / max;
+	}
+
+	write_client_reg(PWM0OFF, level, TRUE);
+}
+
+static void mddi_toshiba_vsync_set_handler(msm_fb_vsync_handler_type handler,	/* ISR to be executed */
+					   void *arg)
+{
+	boolean error = FALSE;
+	unsigned long flags;
+
+	/* Disable interrupts */
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+	/* INTLOCK(); */
+
+	if (mddi_toshiba_vsync_handler != NULL) {
+		error = TRUE;
+	} else {
+		/* Register the handler for this particular GROUP interrupt source */
+		mddi_toshiba_vsync_handler = handler;
+		mddi_toshiba_vsync_handler_arg = arg;
+	}
+
+	/* Restore interrupts */
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+	/* MDDI_INTFREE(); */
+	if (error) {
+		MDDI_MSG_ERR("MDDI: Previous Vsync handler never called\n");
+	} else {
+		/* Enable the vsync wakeup */
+		mddi_queue_register_write(INTMSK, 0x0000, FALSE, 0);
+
+		mddi_toshiba_vsync_attempts = 1;
+		mddi_vsync_detect_enabled = TRUE;
+	}
+}				/* mddi_toshiba_vsync_set_handler */
+
+static void mddi_toshiba_lcd_vsync_detected(boolean detected)
+{
+	/* static timetick_type start_time = 0; */
+	static struct timeval start_time;
+	static boolean first_time = TRUE;
+	/* uint32 mdp_cnt_val = 0; */
+	/* timetick_type elapsed_us; */
+	struct timeval now;
+	uint32 elapsed_us;
+	uint32 num_vsyncs;
+
+	if ((detected) || (mddi_toshiba_vsync_attempts > 5)) {
+		if ((detected) && (mddi_toshiba_monitor_refresh_value)) {
+			/* if (start_time != 0) */
+			if (!first_time) {
+				jiffies_to_timeval(jiffies, &now);
+				elapsed_us =
+				    (now.tv_sec - start_time.tv_sec) * 1000000 +
+				    now.tv_usec - start_time.tv_usec;
+				/*
+				 * LCD is configured for a refresh every usecs,
+				 *  so to determine the number of vsyncs that
+				 *  have occurred since the last measurement
+				 *  add half that to the time difference and
+				 *  divide by the refresh rate.
+				 */
+				num_vsyncs = (elapsed_us +
+					      (mddi_toshiba_usecs_per_refresh >>
+					       1)) /
+				    mddi_toshiba_usecs_per_refresh;
+				/*
+				 * LCD is configured for * hsyncs (rows) per
+				 * refresh cycle. Calculate new rows_per_second
+				 * value based upon these new measurements.
+				 * MDP can update with this new value.
+				 */
+				mddi_toshiba_rows_per_second =
+				    (mddi_toshiba_rows_per_refresh * 1000 *
+				     num_vsyncs) / (elapsed_us / 1000);
+			}
+			/* start_time = timetick_get(); */
+			first_time = FALSE;
+			jiffies_to_timeval(jiffies, &start_time);
+			if (mddi_toshiba_report_refresh_measurements) {
+				(void)mddi_queue_register_read_int(VPOS,
+								   &mddi_toshiba_curr_vpos);
+				/* mdp_cnt_val = MDP_LINE_COUNT; */
+			}
+		}
+		/* if detected = TRUE, client initiated wakeup was detected */
+		if (mddi_toshiba_vsync_handler != NULL) {
+			(*mddi_toshiba_vsync_handler)
+			    (mddi_toshiba_vsync_handler_arg);
+			mddi_toshiba_vsync_handler = NULL;
+		}
+		mddi_vsync_detect_enabled = FALSE;
+		mddi_toshiba_vsync_attempts = 0;
+		/* need to disable the interrupt wakeup */
+		if (!mddi_queue_register_write_int(INTMSK, 0x0001))
+			MDDI_MSG_ERR("Vsync interrupt disable failed!\n");
+		if (!detected) {
+			/* give up after 5 failed attempts but show error */
+			MDDI_MSG_NOTICE("Vsync detection failed!\n");
+		} else if ((mddi_toshiba_monitor_refresh_value) &&
+			   (mddi_toshiba_report_refresh_measurements)) {
+			MDDI_MSG_NOTICE("  Last Line Counter=%d!\n",
+					mddi_toshiba_curr_vpos);
+		/* MDDI_MSG_NOTICE("  MDP Line Counter=%d!\n",mdp_cnt_val); */
+			MDDI_MSG_NOTICE("  Lines Per Second=%d!\n",
+					mddi_toshiba_rows_per_second);
+		}
+		/* clear the interrupt */
+		if (!mddi_queue_register_write_int(INTFLG, 0x0001))
+			MDDI_MSG_ERR("Vsync interrupt clear failed!\n");
+	} else {
+		/* if detected = FALSE, we woke up from hibernation, but did not
+		 * detect client initiated wakeup.
+		 */
+		mddi_toshiba_vsync_attempts++;
+	}
+}
+
+static void mddi_toshiba_prim_init(struct msm_fb_data_type *mfd)
+{
+
+	switch (toshiba_state) {
+	case TOSHIBA_STATE_PRIM_SEC_READY:
+		break;
+	case TOSHIBA_STATE_OFF:
+		toshiba_state = TOSHIBA_STATE_PRIM_SEC_STANDBY;
+		toshiba_common_initial_setup(mfd);
+		break;
+	case TOSHIBA_STATE_PRIM_SEC_STANDBY:
+		toshiba_common_initial_setup(mfd);
+		break;
+	case TOSHIBA_STATE_SEC_NORMAL_MODE:
+		toshiba_sec_cont_update_stop(mfd);
+		toshiba_sec_sleep_in(mfd);
+		toshiba_sec_sleep_out(mfd);
+		toshiba_sec_lcd_off(mfd);
+		toshiba_common_initial_setup(mfd);
+		break;
+	default:
+		MDDI_MSG_ERR("mddi_toshiba_prim_init from state %d\n",
+			     toshiba_state);
+	}
+
+	toshiba_prim_start(mfd);
+	if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA)
+		gordon_disp_init();
+	mddi_host_write_pix_attr_reg(0x00C3);
+}
+
+static void mddi_toshiba_sec_init(struct msm_fb_data_type *mfd)
+{
+
+	switch (toshiba_state) {
+	case TOSHIBA_STATE_PRIM_SEC_READY:
+		break;
+	case TOSHIBA_STATE_PRIM_SEC_STANDBY:
+		toshiba_common_initial_setup(mfd);
+		break;
+	case TOSHIBA_STATE_PRIM_NORMAL_MODE:
+		toshiba_prim_lcd_off(mfd);
+		toshiba_common_initial_setup(mfd);
+		break;
+	default:
+		MDDI_MSG_ERR("mddi_toshiba_sec_init from state %d\n",
+			     toshiba_state);
+	}
+
+	toshiba_sec_start(mfd);
+	toshiba_sec_backlight_on(mfd);
+	toshiba_sec_cont_update_start(mfd);
+	mddi_host_write_pix_attr_reg(0x0400);
+}
+
+static void mddi_toshiba_lcd_powerdown(struct msm_fb_data_type *mfd)
+{
+	switch (toshiba_state) {
+	case TOSHIBA_STATE_PRIM_SEC_READY:
+		mddi_toshiba_prim_init(mfd);
+		mddi_toshiba_lcd_powerdown(mfd);
+		return;
+	case TOSHIBA_STATE_PRIM_SEC_STANDBY:
+		break;
+	case TOSHIBA_STATE_PRIM_NORMAL_MODE:
+		toshiba_prim_lcd_off(mfd);
+		break;
+	case TOSHIBA_STATE_SEC_NORMAL_MODE:
+		toshiba_sec_cont_update_stop(mfd);
+		toshiba_sec_sleep_in(mfd);
+		toshiba_sec_sleep_out(mfd);
+		toshiba_sec_lcd_off(mfd);
+		break;
+	default:
+		MDDI_MSG_ERR("mddi_toshiba_lcd_powerdown from state %d\n",
+			     toshiba_state);
+	}
+}
+
+static int mddi_sharpgordon_firsttime = 1;
+
+static int mddi_toshiba_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mddi_host_client_cnt_reset();
+
+	if (TM_GET_DID(mfd->panel.id) == TOSHIBA_VGA_PRIM)
+		mddi_toshiba_prim_init(mfd);
+	else
+		mddi_toshiba_sec_init(mfd);
+	if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) {
+		if (mddi_sharpgordon_firsttime) {
+			mddi_sharpgordon_firsttime = 0;
+			write_client_reg(REGENB, 0x00000001, TRUE);
+		}
+	}
+	return 0;
+}
+
+static int mddi_toshiba_lcd_off(struct platform_device *pdev)
+{
+	if (mddi_toshiba_vsync_handler != NULL) {
+		(*mddi_toshiba_vsync_handler)
+			    (mddi_toshiba_vsync_handler_arg);
+		mddi_toshiba_vsync_handler = NULL;
+		printk(KERN_INFO "%s: clean up vsyn_handler=%x\n", __func__,
+				(int)mddi_toshiba_vsync_handler);
+	}
+
+	mddi_toshiba_lcd_powerdown(platform_get_drvdata(pdev));
+	return 0;
+}
+
+static int __devinit mddi_toshiba_lcd_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		mddi_toshiba_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mddi_toshiba_lcd_probe,
+	.driver = {
+		.name   = "mddi_toshiba",
+	},
+};
+
+static struct msm_fb_panel_data toshiba_panel_data = {
+	.on 		= mddi_toshiba_lcd_on,
+	.off 		= mddi_toshiba_lcd_off,
+};
+
+static int ch_used[3];
+
+int mddi_toshiba_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	if ((channel != TOSHIBA_VGA_PRIM) &&
+	    mddi_toshiba_pdata && mddi_toshiba_pdata->panel_num)
+		if (mddi_toshiba_pdata->panel_num() < 2)
+			return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	pdev = platform_device_alloc("mddi_toshiba", (panel << 8)|channel);
+	if (!pdev)
+		return -ENOMEM;
+
+	if (channel == TOSHIBA_VGA_PRIM) {
+		toshiba_panel_data.set_backlight =
+				mddi_toshiba_lcd_set_backlight;
+
+		if (pinfo->lcd.vsync_enable) {
+			toshiba_panel_data.set_vsync_notifier =
+				mddi_toshiba_vsync_set_handler;
+			mddi_lcd.vsync_detected =
+				mddi_toshiba_lcd_vsync_detected;
+		}
+	} else {
+		toshiba_panel_data.set_backlight = NULL;
+		toshiba_panel_data.set_vsync_notifier = NULL;
+	}
+
+	toshiba_panel_data.panel_info = *pinfo;
+
+	ret = platform_device_add_data(pdev, &toshiba_panel_data,
+		sizeof(toshiba_panel_data));
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int __init mddi_toshiba_lcd_init(void)
+{
+	return platform_driver_register(&this_driver);
+}
+
+module_init(mddi_toshiba_lcd_init);
diff --git a/drivers/video/msm/mddi_toshiba.h b/drivers/video/msm/mddi_toshiba.h
new file mode 100644
index 0000000..646f5e9
--- /dev/null
+++ b/drivers/video/msm/mddi_toshiba.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MDDI_TOSHIBA_H
+#define MDDI_TOSHIBA_H
+
+#define TOSHIBA_VGA_PRIM 1
+#define TOSHIBA_VGA_SECD 2
+
+#define LCD_TOSHIBA_2P4_VGA 	0
+#define LCD_TOSHIBA_2P4_WVGA 	1
+#define LCD_TOSHIBA_2P4_WVGA_PT	2
+#define LCD_SHARP_2P4_VGA 	3
+
+#define GPIO_BLOCK_BASE        0x150000
+#define SYSTEM_BLOCK2_BASE     0x170000
+
+#define GPIODIR     (GPIO_BLOCK_BASE|0x04)
+#define GPIOSEL     (SYSTEM_BLOCK2_BASE|0x00)
+#define GPIOPC      (GPIO_BLOCK_BASE|0x28)
+#define GPIODATA    (GPIO_BLOCK_BASE|0x00)
+
+#define write_client_reg(__X, __Y, __Z) {\
+  mddi_queue_register_write(__X, __Y, TRUE, 0);\
+}
+
+#endif /* MDDI_TOSHIBA_H */
diff --git a/drivers/video/msm/mddi_toshiba_vga.c b/drivers/video/msm/mddi_toshiba_vga.c
new file mode 100644
index 0000000..73749f9
--- /dev/null
+++ b/drivers/video/msm/mddi_toshiba_vga.c
@@ -0,0 +1,134 @@
+/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+#include "mddi_toshiba.h"
+
+static uint32 read_client_reg(uint32 addr)
+{
+	uint32 val;
+	mddi_queue_register_read(addr, &val, TRUE, 0);
+	return val;
+}
+
+static uint32 toshiba_lcd_gpio_read(void)
+{
+	uint32 val;
+
+	write_client_reg(GPIODIR, 0x0000000C, TRUE);
+	write_client_reg(GPIOSEL, 0x00000000, TRUE);
+	write_client_reg(GPIOSEL, 0x00000000, TRUE);
+	write_client_reg(GPIOPC, 0x03CF00C0, TRUE);
+	val = read_client_reg(GPIODATA) & 0x2C0;
+
+	return val;
+}
+
+static u32 mddi_toshiba_panel_detect(void)
+{
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+	uint32 lcd_gpio;
+	u32 mddi_toshiba_lcd = LCD_TOSHIBA_2P4_VGA;
+
+	/* Toshiba display requires larger drive_lo value */
+	mddi_host_reg_out(DRIVE_LO, 0x0050);
+
+	lcd_gpio = toshiba_lcd_gpio_read();
+	switch (lcd_gpio) {
+	case 0x0080:
+		mddi_toshiba_lcd = LCD_SHARP_2P4_VGA;
+		break;
+
+	case 0x00C0:
+	default:
+		mddi_toshiba_lcd = LCD_TOSHIBA_2P4_VGA;
+		break;
+	}
+
+	return mddi_toshiba_lcd;
+}
+
+static int __init mddi_toshiba_vga_init(void)
+{
+	int ret;
+	struct msm_panel_info pinfo;
+	u32 panel;
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	u32 id;
+
+	ret = msm_fb_detect_client("mddi_toshiba_vga");
+	if (ret == -ENODEV)
+		return 0;
+
+	if (ret) {
+		id = mddi_get_client_id();
+		if ((id >> 16) != 0xD263)
+			return 0;
+	}
+#endif
+
+	panel = mddi_toshiba_panel_detect();
+
+	pinfo.xres = 480;
+	pinfo.yres = 640;
+	pinfo.type = MDDI_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 18;
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.mddi.is_type1 = TRUE;
+	pinfo.lcd.refx100 = 6118;
+	pinfo.lcd.v_back_porch = 6;
+	pinfo.lcd.v_front_porch = 0;
+	pinfo.lcd.v_pulse_width = 0;
+	pinfo.lcd.hw_vsync_mode = FALSE;
+	pinfo.lcd.vsync_notifier_period = (1 * HZ);
+	pinfo.bl_max = 99;
+	pinfo.bl_min = 1;
+	pinfo.clk_rate = 122880000;
+	pinfo.clk_min =  120000000;
+	pinfo.clk_max =  200000000;
+	pinfo.fb_num = 2;
+
+	ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM, panel);
+	if (ret) {
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+		return ret;
+	}
+
+	pinfo.xres = 176;
+	pinfo.yres = 220;
+	MSM_FB_SINGLE_MODE_PANEL(&pinfo);
+	pinfo.type = MDDI_PANEL;
+	pinfo.pdest = DISPLAY_2;
+	pinfo.mddi.vdopkt = 0x400;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 18;
+	pinfo.clk_rate = 122880000;
+	pinfo.clk_min =  120000000;
+	pinfo.clk_max =  200000000;
+	pinfo.fb_num = 2;
+
+	ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_SECD, panel);
+	if (ret)
+		printk(KERN_WARNING
+			"%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mddi_toshiba_vga_init);
diff --git a/drivers/video/msm/mddi_toshiba_wvga.c b/drivers/video/msm/mddi_toshiba_wvga.c
new file mode 100644
index 0000000..c1925e1
--- /dev/null
+++ b/drivers/video/msm/mddi_toshiba_wvga.c
@@ -0,0 +1,61 @@
+/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddi_toshiba.h"
+
+static int __init mddi_toshiba_wvga_init(void)
+{
+	int ret;
+	struct msm_panel_info pinfo;
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	if (msm_fb_detect_client("mddi_toshiba_wvga"))
+		return 0;
+#endif
+
+	pinfo.xres = 800;
+	pinfo.yres = 480;
+	MSM_FB_SINGLE_MODE_PANEL(&pinfo);
+	pinfo.pdest = DISPLAY_2;
+	pinfo.type = MDDI_PANEL;
+	pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 18;
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.mddi.is_type1 = TRUE;
+	pinfo.lcd.refx100 = 6118;
+	pinfo.lcd.v_back_porch = 6;
+	pinfo.lcd.v_front_porch = 0;
+	pinfo.lcd.v_pulse_width = 0;
+	pinfo.lcd.hw_vsync_mode = FALSE;
+	pinfo.lcd.vsync_notifier_period = (1 * HZ);
+	pinfo.bl_max = 4;
+	pinfo.bl_min = 1;
+	pinfo.clk_rate = 192000000;
+	pinfo.clk_min =  190000000;
+	pinfo.clk_max =  200000000;
+	pinfo.fb_num = 2;
+
+	ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM,
+					   LCD_TOSHIBA_2P4_WVGA);
+	if (ret) {
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+		return ret;
+	}
+
+	return ret;
+}
+
+module_init(mddi_toshiba_wvga_init);
diff --git a/drivers/video/msm/mddi_toshiba_wvga_pt.c b/drivers/video/msm/mddi_toshiba_wvga_pt.c
new file mode 100644
index 0000000..8da1485
--- /dev/null
+++ b/drivers/video/msm/mddi_toshiba_wvga_pt.c
@@ -0,0 +1,69 @@
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+#include "mddi_toshiba.h"
+
+static struct msm_panel_info pinfo;
+
+static int __init mddi_toshiba_wvga_pt_init(void)
+{
+	int ret;
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	uint id;
+
+	ret = msm_fb_detect_client("mddi_toshiba_wvga_pt");
+	if (ret == -ENODEV)
+		return 0;
+
+	if (ret) {
+		id = mddi_get_client_id();
+		if (id != 0xd2638722)
+			return 0;
+	}
+#endif
+
+	pinfo.xres = 480;
+	pinfo.yres = 800;
+	MSM_FB_SINGLE_MODE_PANEL(&pinfo);
+	pinfo.type = MDDI_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 18;
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.lcd.refx100 = 6102; /* adjust refx100 to prevent tearing */
+	pinfo.mddi.is_type1 = TRUE;
+	pinfo.lcd.v_back_porch = 8;     /* vsw=10 + vbp = 8 */
+	pinfo.lcd.v_front_porch = 2;
+	pinfo.lcd.v_pulse_width = 10;
+	pinfo.lcd.hw_vsync_mode = FALSE;
+	pinfo.lcd.vsync_notifier_period = (1 * HZ);
+	pinfo.bl_max = 15;
+	pinfo.bl_min = 1;
+	pinfo.clk_rate = 222750000;
+	pinfo.clk_min =  200000000;
+	pinfo.clk_max =  240000000;
+	pinfo.fb_num = 2;
+
+	ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM,
+						LCD_TOSHIBA_2P4_WVGA_PT);
+	if (ret)
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mddi_toshiba_wvga_pt_init);
diff --git a/drivers/video/msm/mddihost.c b/drivers/video/msm/mddihost.c
new file mode 100644
index 0000000..c6acf9f
--- /dev/null
+++ b/drivers/video/msm/mddihost.c
@@ -0,0 +1,626 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+
+#include <linux/clk.h>
+#include <mach/clk.h>
+
+struct semaphore mddi_host_mutex;
+
+struct clk *mddi_io_clk;
+static boolean mddi_host_powered = FALSE;
+static boolean mddi_host_initialized = FALSE;
+extern uint32 *mddi_reg_read_value_ptr;
+
+mddi_lcd_func_type mddi_lcd;
+
+extern mddi_client_capability_type mddi_client_capability_pkt;
+
+#ifdef MDDI_HOST_WINDOW_WORKAROUND
+/* Tables showing number of rows that would cause a packet length
+ * ending in 0x02, for each number of columns. These tables have
+ * been generated for MDDI packets that have 16 and 16 bits-per-pixel.
+ * This is a work-around for MDDI clients that declare a CRC error
+ * on MDDI packets where ((length & 0x00ff) == 0x02).
+ */
+static uint16 error_vals_16bpp[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 10, 0, 0, 0, 14, 0, 0, 0, 2, 0, 0, 4, 6, 12, 0,
+0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0,
+0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 11, 4, 0, 12, 0,
+0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+0, 10, 0, 1, 0, 14, 0, 0, 0, 2, 0, 3, 4, 6, 12, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 10, 0, 0, 0, 14, 0, 0, 0, 2, 0, 0, 4, 6, 12, 0,
+0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0,
+0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 11, 4, 0, 12, 0,
+0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+};
+
+static uint16 error_vals_18bpp[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 14,
+0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 9, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7,
+0, 0, 0, 0, 0, 0, 1, 0, 0, 16, 0, 0, 0, 0, 0, 6,
+14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+7, 0, 0, 0, 0, 0, 0, 4, 0, 16, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+0, 7, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 9, 0
+};
+#endif
+
+#ifdef FEATURE_MDDI_HITACHI
+extern void mddi_hitachi_window_adjust(uint16 x1,
+				       uint16 x2, uint16 y1, uint16 y2);
+#endif
+
+extern void mddi_toshiba_lcd_init(void);
+
+#ifdef FEATURE_MDDI_S6D0142
+extern void mddi_s6d0142_lcd_init(void);
+extern void mddi_s6d0142_window_adjust(uint16 x1,
+				       uint16 x2,
+				       uint16 y1,
+				       uint16 y2,
+				       mddi_llist_done_cb_type done_cb);
+#endif
+
+void mddi_init(void)
+{
+	if (mddi_host_initialized)
+		return;
+
+	mddi_host_initialized = TRUE;
+
+	sema_init(&mddi_host_mutex, 1);
+
+	if (!mddi_host_powered) {
+		down(&mddi_host_mutex);
+		mddi_host_init(MDDI_HOST_PRIM);
+		mddi_host_powered = TRUE;
+		up(&mddi_host_mutex);
+		mdelay(10);
+	}
+}
+
+int mddi_host_register_read(uint32 reg_addr,
+     uint32 *reg_value_ptr, boolean wait, mddi_host_type host) {
+	mddi_linked_list_type *curr_llist_ptr;
+	mddi_register_access_packet_type *regacc_pkt_ptr;
+	uint16 curr_llist_idx;
+	int ret = 0;
+
+	if (in_interrupt())
+		MDDI_MSG_CRIT("Called from ISR context\n");
+
+	if (!mddi_host_powered) {
+		MDDI_MSG_ERR("MDDI powered down!\n");
+		mddi_init();
+	}
+
+	down(&mddi_host_mutex);
+
+	mddi_reg_read_value_ptr = reg_value_ptr;
+	curr_llist_idx = mddi_get_reg_read_llist_item(host, TRUE);
+	if (curr_llist_idx == UNASSIGNED_INDEX) {
+		up(&mddi_host_mutex);
+
+		/* need to change this to some sort of wait */
+		MDDI_MSG_ERR("Attempting to queue up more than 1 reg read\n");
+		return -EINVAL;
+	}
+
+	curr_llist_ptr = &llist_extern[host][curr_llist_idx];
+	curr_llist_ptr->link_controller_flags = 0x11;
+	curr_llist_ptr->packet_header_count = 14;
+	curr_llist_ptr->packet_data_count = 0;
+
+	curr_llist_ptr->next_packet_pointer = NULL;
+	curr_llist_ptr->packet_data_pointer = NULL;
+	curr_llist_ptr->reserved = 0;
+
+	regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
+
+	regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count;
+	regacc_pkt_ptr->packet_type = 146;	/* register access packet */
+	regacc_pkt_ptr->bClient_ID = 0;
+	regacc_pkt_ptr->read_write_info = 0x8001;
+	regacc_pkt_ptr->register_address = reg_addr;
+
+	/* now adjust pointers */
+	mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait,
+				   NULL, host);
+	/* need to check if we can write the pointer or not */
+
+	up(&mddi_host_mutex);
+
+	if (wait) {
+		int wait_ret;
+
+		mddi_linked_list_notify_type *llist_notify_ptr;
+		llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx];
+		wait_ret = wait_for_completion_timeout(
+					&(llist_notify_ptr->done_comp), 5 * HZ);
+
+		if (wait_ret <= 0)
+			ret = -EBUSY;
+
+		if (wait_ret < 0)
+			printk(KERN_ERR "%s: failed to wait for completion!\n",
+				__func__);
+		else if (!wait_ret)
+			printk(KERN_ERR "%s: Timed out waiting!\n", __func__);
+
+		if (!ret && (mddi_reg_read_value_ptr == reg_value_ptr) &&
+			(*reg_value_ptr == -EBUSY)) {
+			printk(KERN_ERR "%s - failed to get data from client",
+				   __func__);
+			mddi_reg_read_value_ptr = NULL;
+			ret = -EBUSY;
+		}
+	}
+
+	MDDI_MSG_DEBUG("Reg Read value=0x%x\n", *reg_value_ptr);
+
+	return ret;
+}				/* mddi_host_register_read */
+
+int mddi_host_register_write(uint32 reg_addr,
+     uint32 reg_val, enum mddi_data_packet_size_type packet_size,
+     boolean wait, mddi_llist_done_cb_type done_cb, mddi_host_type host) {
+	mddi_linked_list_type *curr_llist_ptr;
+	mddi_linked_list_type *curr_llist_dma_ptr;
+	mddi_register_access_packet_type *regacc_pkt_ptr;
+	uint16 curr_llist_idx;
+	int ret = 0;
+
+	if (in_interrupt())
+		MDDI_MSG_CRIT("Called from ISR context\n");
+
+	if (!mddi_host_powered) {
+		MDDI_MSG_ERR("MDDI powered down!\n");
+		mddi_init();
+	}
+
+	down(&mddi_host_mutex);
+
+	curr_llist_idx = mddi_get_next_free_llist_item(host, TRUE);
+	curr_llist_ptr = &llist_extern[host][curr_llist_idx];
+	curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx];
+
+	curr_llist_ptr->link_controller_flags = 1;
+	curr_llist_ptr->packet_header_count = 14;
+	curr_llist_ptr->packet_data_count = 4;
+
+	curr_llist_ptr->next_packet_pointer = NULL;
+	curr_llist_ptr->reserved = 0;
+
+	regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
+
+	regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count +
+					(uint16)packet_size;
+	regacc_pkt_ptr->packet_type = 146;	/* register access packet */
+	regacc_pkt_ptr->bClient_ID = 0;
+	regacc_pkt_ptr->read_write_info = 0x0001;
+	regacc_pkt_ptr->register_address = reg_addr;
+	regacc_pkt_ptr->register_data_list[0] = reg_val;
+
+	MDDI_MSG_DEBUG("Reg Access write reg=0x%x, value=0x%x\n",
+		       regacc_pkt_ptr->register_address,
+		       regacc_pkt_ptr->register_data_list[0]);
+
+	regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt;
+	curr_llist_ptr->packet_data_pointer =
+	    (void *)(&regacc_pkt_ptr->register_data_list[0]);
+
+	/* now adjust pointers */
+	mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait,
+				   done_cb, host);
+
+	up(&mddi_host_mutex);
+
+	if (wait) {
+		int wait_ret;
+
+		mddi_linked_list_notify_type *llist_notify_ptr;
+		llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx];
+		wait_ret = wait_for_completion_timeout(
+					&(llist_notify_ptr->done_comp), 5 * HZ);
+
+		if (wait_ret <= 0)
+			ret = -EBUSY;
+
+		if (wait_ret < 0)
+			printk(KERN_ERR "%s: failed to wait for completion!\n",
+				__func__);
+		else if (!wait_ret)
+			printk(KERN_ERR "%s: Timed out waiting!\n", __func__);
+	}
+
+	return ret;
+}				/* mddi_host_register_write */
+
+boolean mddi_host_register_read_int
+    (uint32 reg_addr, uint32 *reg_value_ptr, mddi_host_type host) {
+	mddi_linked_list_type *curr_llist_ptr;
+	mddi_register_access_packet_type *regacc_pkt_ptr;
+	uint16 curr_llist_idx;
+
+	if (!in_interrupt())
+		MDDI_MSG_CRIT("Called from TASK context\n");
+
+	if (!mddi_host_powered) {
+		MDDI_MSG_ERR("MDDI powered down!\n");
+		return FALSE;
+	}
+
+	if (down_trylock(&mddi_host_mutex) != 0)
+		return FALSE;
+
+	mddi_reg_read_value_ptr = reg_value_ptr;
+	curr_llist_idx = mddi_get_reg_read_llist_item(host, FALSE);
+	if (curr_llist_idx == UNASSIGNED_INDEX) {
+		up(&mddi_host_mutex);
+		return FALSE;
+	}
+
+	curr_llist_ptr = &llist_extern[host][curr_llist_idx];
+	curr_llist_ptr->link_controller_flags = 0x11;
+	curr_llist_ptr->packet_header_count = 14;
+	curr_llist_ptr->packet_data_count = 0;
+
+	curr_llist_ptr->next_packet_pointer = NULL;
+	curr_llist_ptr->packet_data_pointer = NULL;
+	curr_llist_ptr->reserved = 0;
+
+	regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
+
+	regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count;
+	regacc_pkt_ptr->packet_type = 146;	/* register access packet */
+	regacc_pkt_ptr->bClient_ID = 0;
+	regacc_pkt_ptr->read_write_info = 0x8001;
+	regacc_pkt_ptr->register_address = reg_addr;
+
+	/* now adjust pointers */
+	mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, FALSE,
+				   NULL, host);
+	/* need to check if we can write the pointer or not */
+
+	up(&mddi_host_mutex);
+
+	return TRUE;
+
+}				/* mddi_host_register_read */
+
+boolean mddi_host_register_write_int
+    (uint32 reg_addr,
+     uint32 reg_val, mddi_llist_done_cb_type done_cb, mddi_host_type host) {
+	mddi_linked_list_type *curr_llist_ptr;
+	mddi_linked_list_type *curr_llist_dma_ptr;
+	mddi_register_access_packet_type *regacc_pkt_ptr;
+	uint16 curr_llist_idx;
+
+	if (!in_interrupt())
+		MDDI_MSG_CRIT("Called from TASK context\n");
+
+	if (!mddi_host_powered) {
+		MDDI_MSG_ERR("MDDI powered down!\n");
+		return FALSE;
+	}
+
+	if (down_trylock(&mddi_host_mutex) != 0)
+		return FALSE;
+
+	curr_llist_idx = mddi_get_next_free_llist_item(host, FALSE);
+	if (curr_llist_idx == UNASSIGNED_INDEX) {
+		up(&mddi_host_mutex);
+		return FALSE;
+	}
+
+	curr_llist_ptr = &llist_extern[host][curr_llist_idx];
+	curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx];
+
+	curr_llist_ptr->link_controller_flags = 1;
+	curr_llist_ptr->packet_header_count = 14;
+	curr_llist_ptr->packet_data_count = 4;
+
+	curr_llist_ptr->next_packet_pointer = NULL;
+	curr_llist_ptr->reserved = 0;
+
+	regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
+
+	regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count + 4;
+	regacc_pkt_ptr->packet_type = 146;	/* register access packet */
+	regacc_pkt_ptr->bClient_ID = 0;
+	regacc_pkt_ptr->read_write_info = 0x0001;
+	regacc_pkt_ptr->register_address = reg_addr;
+	regacc_pkt_ptr->register_data_list[0] = reg_val;
+
+	regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt;
+	curr_llist_ptr->packet_data_pointer =
+	    (void *)(&(regacc_pkt_ptr->register_data_list[0]));
+
+	/* now adjust pointers */
+	mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, FALSE,
+				   done_cb, host);
+	up(&mddi_host_mutex);
+
+	return TRUE;
+
+}				/* mddi_host_register_write */
+
+void mddi_wait(uint16 time_ms)
+{
+	mdelay(time_ms);
+}
+
+void mddi_client_lcd_vsync_detected(boolean detected)
+{
+	if (mddi_lcd.vsync_detected)
+		(*mddi_lcd.vsync_detected) (detected);
+}
+
+/* extended version of function includes done callback */
+void mddi_window_adjust_ext(struct msm_fb_data_type *mfd,
+			    uint16 x1,
+			    uint16 x2,
+			    uint16 y1,
+			    uint16 y2, mddi_llist_done_cb_type done_cb)
+{
+#ifdef FEATURE_MDDI_HITACHI
+	if (mfd->panel.id == HITACHI)
+		mddi_hitachi_window_adjust(x1, x2, y1, y2);
+#elif defined(FEATURE_MDDI_S6D0142)
+	if (mfd->panel.id == MDDI_LCD_S6D0142)
+		mddi_s6d0142_window_adjust(x1, x2, y1, y2, done_cb);
+#else
+	/* Do nothing then... except avoid lint/compiler warnings */
+	(void)x1;
+	(void)x2;
+	(void)y1;
+	(void)y2;
+	(void)done_cb;
+#endif
+}
+
+void mddi_window_adjust(struct msm_fb_data_type *mfd,
+			uint16 x1, uint16 x2, uint16 y1, uint16 y2)
+{
+	mddi_window_adjust_ext(mfd, x1, x2, y1, y2, NULL);
+}
+
+#ifdef MDDI_HOST_WINDOW_WORKAROUND
+uint16 mddi_assign_pkt_height(uint16 pkt_width,
+	uint16 pkt_height, uint16 bpp)
+{
+	uint16 new_pkt_height;
+	uint16 problem_height = 0;
+
+	if (pkt_width <= 240) {
+		if (bpp == 16)
+			problem_height = error_vals_16bpp[pkt_width-1];
+		else if (bpp == 18)
+			problem_height = error_vals_18bpp[pkt_width-1];
+		else {
+			printk(KERN_ERR"Invalid bpp value");
+			return -EINVAL;
+		}
+	}
+	if (problem_height == pkt_height)
+		new_pkt_height = problem_height - 1;
+	else
+		new_pkt_height = pkt_height;
+
+	return new_pkt_height;
+}
+#endif
+
+#ifdef ENABLE_MDDI_MULTI_READ_WRITE
+int mddi_host_register_multiwrite(uint32 reg_addr,
+	uint32 *value_list_ptr,
+	uint32 value_count, boolean wait, mddi_llist_done_cb_type done_cb,
+	mddi_host_type host)
+{
+	mddi_linked_list_type *curr_llist_ptr;
+	mddi_linked_list_type *curr_llist_dma_ptr;
+	mddi_register_access_packet_type *regacc_pkt_ptr;
+	uint16 curr_llist_idx;
+	int ret = 0;
+
+	if (!value_list_ptr || !value_count ||
+		value_count > MDDI_HOST_MAX_CLIENT_REG_IN_SAME_ADDR) {
+		MDDI_MSG_ERR("\n Invalid value_list or value_count");
+		return -EINVAL;
+	}
+
+	if (in_interrupt())
+		MDDI_MSG_CRIT("Called from ISR context\n");
+
+	if (!mddi_host_powered) {
+		MDDI_MSG_ERR("MDDI powered down!\n");
+		mddi_init();
+	}
+
+	down(&mddi_host_mutex);
+
+	curr_llist_idx = mddi_get_next_free_llist_item(host, TRUE);
+	curr_llist_ptr = &llist_extern[host][curr_llist_idx];
+	curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx];
+
+	curr_llist_ptr->link_controller_flags = 1;
+	curr_llist_ptr->packet_header_count = 14;
+	curr_llist_ptr->packet_data_count =
+		(uint16)(value_count * 4);
+
+	curr_llist_ptr->next_packet_pointer = NULL;
+	curr_llist_ptr->reserved = 0;
+
+	regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
+
+	regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count
+		+ curr_llist_ptr->packet_data_count;
+	regacc_pkt_ptr->packet_type = 146;	/* register access packet */
+	regacc_pkt_ptr->bClient_ID = 0;
+	regacc_pkt_ptr->read_write_info = value_count;
+	regacc_pkt_ptr->register_address = reg_addr;
+	memcpy((void *)&regacc_pkt_ptr->register_data_list[0], value_list_ptr,
+		   curr_llist_ptr->packet_data_count);
+
+	regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt;
+	curr_llist_ptr->packet_data_pointer =
+		(void *)(&regacc_pkt_ptr->register_data_list[0]);
+	MDDI_MSG_DEBUG("MultiReg Access write reg=0x%x, value[0]=0x%x\n",
+		       regacc_pkt_ptr->register_address,
+		       regacc_pkt_ptr->register_data_list[0]);
+
+	/* now adjust pointers */
+	mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait,
+				   done_cb, host);
+
+	up(&mddi_host_mutex);
+
+	if (wait) {
+		int wait_ret;
+
+		mddi_linked_list_notify_type *llist_notify_ptr;
+		llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx];
+		wait_ret = wait_for_completion_timeout(
+					&(llist_notify_ptr->done_comp), 5 * HZ);
+
+		if (wait_ret <= 0)
+			ret = -EBUSY;
+
+		if (wait_ret < 0)
+			printk(KERN_ERR "%s: failed to wait for completion!\n",
+				__func__);
+		else if (!wait_ret)
+			printk(KERN_ERR "%s: Timed out waiting!\n", __func__);
+	}
+
+	return ret;
+}
+
+int mddi_host_register_multiread(uint32 reg_addr,
+	uint32 *value_list_ptr, uint32 value_count,
+	boolean wait, mddi_host_type host) {
+	mddi_linked_list_type *curr_llist_ptr;
+	mddi_register_access_packet_type *regacc_pkt_ptr;
+	uint16 curr_llist_idx;
+	int ret = 0;
+
+	if (!value_list_ptr || !value_count ||
+		value_count >= MDDI_HOST_MAX_CLIENT_REG_IN_SAME_ADDR) {
+		MDDI_MSG_ERR("\n Invalid value_list or value_count");
+		return -EINVAL;
+	}
+
+	if (in_interrupt())
+		MDDI_MSG_CRIT("Called from ISR context\n");
+
+	if (!mddi_host_powered) {
+		MDDI_MSG_ERR("MDDI powered down!\n");
+		mddi_init();
+	}
+
+	down(&mddi_host_mutex);
+
+	mddi_reg_read_value_ptr = value_list_ptr;
+	curr_llist_idx = mddi_get_reg_read_llist_item(host, TRUE);
+	if (curr_llist_idx == UNASSIGNED_INDEX) {
+		up(&mddi_host_mutex);
+
+		/* need to change this to some sort of wait */
+		MDDI_MSG_ERR("Attempting to queue up more than 1 reg read\n");
+		return -EINVAL;
+	}
+
+	curr_llist_ptr = &llist_extern[host][curr_llist_idx];
+	curr_llist_ptr->link_controller_flags = 0x11;
+	curr_llist_ptr->packet_header_count = 14;
+	curr_llist_ptr->packet_data_count = 0;
+
+	curr_llist_ptr->next_packet_pointer = NULL;
+	curr_llist_ptr->packet_data_pointer = NULL;
+	curr_llist_ptr->reserved = 0;
+
+	regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt;
+
+	regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count;
+	regacc_pkt_ptr->packet_type = 146;	/* register access packet */
+	regacc_pkt_ptr->bClient_ID = 0;
+	regacc_pkt_ptr->read_write_info = 0x8000 | value_count;
+	regacc_pkt_ptr->register_address = reg_addr;
+
+	/* now adjust pointers */
+	mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait,
+				   NULL, host);
+	/* need to check if we can write the pointer or not */
+
+	up(&mddi_host_mutex);
+
+	if (wait) {
+		int wait_ret;
+
+		mddi_linked_list_notify_type *llist_notify_ptr;
+		llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx];
+		wait_ret = wait_for_completion_timeout(
+					&(llist_notify_ptr->done_comp), 5 * HZ);
+
+		if (wait_ret <= 0)
+			ret = -EBUSY;
+
+		if (wait_ret < 0)
+			printk(KERN_ERR "%s: failed to wait for completion!\n",
+				__func__);
+		else if (!wait_ret)
+			printk(KERN_ERR "%s: Timed out waiting!\n", __func__);
+
+		if (!ret && (mddi_reg_read_value_ptr == value_list_ptr) &&
+			(*value_list_ptr == -EBUSY)) {
+			printk(KERN_ERR "%s - failed to get data from client",
+				   __func__);
+			mddi_reg_read_value_ptr = NULL;
+			ret = -EBUSY;
+		}
+	}
+
+	MDDI_MSG_DEBUG("MultiReg Read value[0]=0x%x\n", *value_list_ptr);
+
+	return ret;
+}
+#endif
diff --git a/drivers/video/msm/mddihost.h b/drivers/video/msm/mddihost.h
new file mode 100644
index 0000000..52bc67c
--- /dev/null
+++ b/drivers/video/msm/mddihost.h
@@ -0,0 +1,231 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MDDIHOST_H
+#define MDDIHOST_H
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include "linux/proc_fs.h"
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+
+#include "msm_fb_panel.h"
+
+#undef FEATURE_MDDI_MC4
+#undef FEATURE_MDDI_S6D0142
+#undef FEATURE_MDDI_HITACHI
+#define FEATURE_MDDI_SHARP
+#define FEATURE_MDDI_TOSHIBA
+#undef FEATURE_MDDI_E751
+#define FEATURE_MDDI_CORONA
+#define FEATURE_MDDI_PRISM
+
+#define T_MSM7500
+
+typedef enum {
+	format_16bpp,
+	format_18bpp,
+	format_24bpp
+} mddi_video_format;
+
+typedef enum {
+	MDDI_LCD_NONE = 0,
+	MDDI_LCD_MC4,
+	MDDI_LCD_S6D0142,
+	MDDI_LCD_SHARP,
+	MDDI_LCD_E751,
+	MDDI_LCD_CORONA,
+	MDDI_LCD_HITACHI,
+	MDDI_LCD_TOSHIBA,
+	MDDI_LCD_PRISM,
+	MDDI_LCD_TP2,
+	MDDI_NUM_LCD_TYPES,
+	MDDI_LCD_DEFAULT = MDDI_LCD_TOSHIBA
+} mddi_lcd_type;
+
+typedef enum {
+	MDDI_HOST_PRIM = 0,
+	MDDI_HOST_EXT,
+	MDDI_NUM_HOST_CORES
+} mddi_host_type;
+
+typedef enum {
+	MDDI_DRIVER_RESET,	/* host core registers have not been written. */
+	MDDI_DRIVER_DISABLED,	/* registers written, interrupts disabled. */
+	MDDI_DRIVER_ENABLED	/* registers written, interrupts enabled. */
+} mddi_host_driver_state_type;
+
+typedef enum {
+	MDDI_GPIO_INT_0 = 0,
+	MDDI_GPIO_INT_1,
+	MDDI_GPIO_INT_2,
+	MDDI_GPIO_INT_3,
+	MDDI_GPIO_INT_4,
+	MDDI_GPIO_INT_5,
+	MDDI_GPIO_INT_6,
+	MDDI_GPIO_INT_7,
+	MDDI_GPIO_INT_8,
+	MDDI_GPIO_INT_9,
+	MDDI_GPIO_INT_10,
+	MDDI_GPIO_INT_11,
+	MDDI_GPIO_INT_12,
+	MDDI_GPIO_INT_13,
+	MDDI_GPIO_INT_14,
+	MDDI_GPIO_INT_15,
+	MDDI_GPIO_NUM_INTS
+} mddi_gpio_int_type;
+
+enum mddi_data_packet_size_type {
+	MDDI_DATA_PACKET_4_BYTES  = 4,
+	MDDI_DATA_PACKET_8_BYTES  = 8,
+	MDDI_DATA_PACKET_12_BYTES = 12,
+	MDDI_DATA_PACKET_16_BYTES = 16,
+	MDDI_DATA_PACKET_24_BYTES = 24
+};
+
+typedef struct {
+	uint32 addr;
+	uint32 value;
+} mddi_reg_write_type;
+
+boolean mddi_vsync_set_handler(msm_fb_vsync_handler_type handler, void *arg);
+
+typedef void (*mddi_llist_done_cb_type) (void);
+
+typedef void (*mddi_rev_handler_type) (void *);
+
+boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type);
+
+#define MDDI_DEFAULT_PRIM_PIX_ATTR 0xC3
+#define MDDI_DEFAULT_SECD_PIX_ATTR 0xC0
+
+typedef int gpio_int_polarity_type;
+typedef int gpio_int_handler_type;
+
+typedef struct {
+	void (*vsync_detected) (boolean);
+} mddi_lcd_func_type;
+
+extern mddi_lcd_func_type mddi_lcd;
+extern int irq_enabled;
+extern unsigned char mddi_timer_shutdown_flag;
+extern struct mutex mddi_timer_lock;
+
+void mddi_init(void);
+void mddi_powerdown(void);
+
+void mddi_host_start_ext_display(void);
+void mddi_host_stop_ext_display(void);
+
+extern spinlock_t mddi_host_spin_lock;
+#ifdef T_MSM7500
+void mddi_reset(void);
+#ifdef FEATURE_DUAL_PROC_MODEM_DISPLAY
+void mddi_host_switch_proc_control(boolean on);
+#endif
+#endif
+void mddi_host_exit_power_collapse(void);
+
+void mddi_queue_splash_screen
+    (void *buf_ptr,
+     boolean clear_area,
+     int16 src_width,
+     int16 src_starting_row,
+     int16 src_starting_column,
+     int16 num_of_rows,
+     int16 num_of_columns, int16 dst_starting_row, int16 dst_starting_column);
+
+void mddi_queue_image
+    (void *buf_ptr,
+     uint8 stereo_video,
+     boolean clear_area,
+     int16 src_width,
+     int16 src_starting_row,
+     int16 src_starting_column,
+     int16 num_of_rows,
+     int16 num_of_columns, int16 dst_starting_row, int16 dst_starting_column);
+
+int mddi_host_register_read
+    (uint32 reg_addr,
+     uint32 *reg_value_ptr, boolean wait, mddi_host_type host_idx);
+int mddi_host_register_write
+    (uint32 reg_addr, uint32 reg_val,
+     enum mddi_data_packet_size_type packet_size,
+     boolean wait, mddi_llist_done_cb_type done_cb, mddi_host_type host);
+boolean mddi_host_register_write_int
+    (uint32 reg_addr,
+     uint32 reg_val, mddi_llist_done_cb_type done_cb, mddi_host_type host);
+boolean mddi_host_register_read_int
+    (uint32 reg_addr, uint32 *reg_value_ptr, mddi_host_type host_idx);
+void mddi_queue_register_write_static
+    (uint32 reg_addr,
+     uint32 reg_val, boolean wait, mddi_llist_done_cb_type done_cb);
+void mddi_queue_static_window_adjust
+    (const mddi_reg_write_type *reg_write,
+     uint16 num_writes, mddi_llist_done_cb_type done_cb);
+
+#ifdef ENABLE_MDDI_MULTI_READ_WRITE
+int mddi_host_register_multiwrite(uint32 reg_addr,
+	uint32 *value_list_ptr, uint32 value_count,
+    boolean wait, mddi_llist_done_cb_type done_cb,
+	mddi_host_type host);
+int mddi_host_register_multiread(uint32 reg_addr,
+	uint32 *value_list_ptr, uint32 value_count,
+	boolean wait, mddi_host_type host);
+#endif
+
+#define mddi_queue_register_read(reg, val_ptr, wait, sig) \
+	mddi_host_register_read(reg, val_ptr, wait, MDDI_HOST_PRIM)
+#define mddi_queue_register_write(reg, val, wait, sig) \
+	mddi_host_register_write(reg, val, MDDI_DATA_PACKET_4_BYTES,\
+	wait, NULL, MDDI_HOST_PRIM)
+#define mddi_queue_register_write_extn(reg, val, pkt_size, wait, sig) \
+	mddi_host_register_write(reg, val, pkt_size, \
+	wait, NULL, MDDI_HOST_PRIM)
+#define mddi_queue_register_write_int(reg, val) \
+	mddi_host_register_write_int(reg, val, NULL, MDDI_HOST_PRIM)
+#define mddi_queue_register_read_int(reg, val_ptr) \
+	mddi_host_register_read_int(reg, val_ptr, MDDI_HOST_PRIM)
+#define mddi_queue_register_writes(reg_ptr, val, wait, sig) \
+	mddi_host_register_writes(reg_ptr, val, wait, sig, MDDI_HOST_PRIM)
+
+void mddi_wait(uint16 time_ms);
+void mddi_assign_max_pkt_dimensions(uint16 image_cols,
+				    uint16 image_rows,
+				    uint16 bpp,
+				    uint16 *max_cols, uint16 * max_rows);
+#ifdef MDDI_HOST_WINDOW_WORKAROUND
+uint16 mddi_assign_pkt_height(uint16 pkt_width, uint16 pkt_height, uint16 bpp);
+#endif
+void mddi_queue_reverse_encapsulation(boolean wait);
+int mddi_client_power(unsigned int client_id);
+void mddi_disable(int lock);
+void mddi_window_adjust(struct msm_fb_data_type *mfd,
+	uint16 x1, uint16 x2, uint16 y1, uint16 y2);
+void mddi_send_fw_link_skew_cal(mddi_host_type host_idx);
+int pmdh_clk_func(int enable);
+
+#endif /* MDDIHOST_H */
diff --git a/drivers/video/msm/mddihost_e.c b/drivers/video/msm/mddihost_e.c
new file mode 100644
index 0000000..d53aa6f
--- /dev/null
+++ b/drivers/video/msm/mddihost_e.c
@@ -0,0 +1,59 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+
+#include <linux/clk.h>
+#include <mach/clk.h>
+
+extern struct semaphore mddi_host_mutex;
+static boolean mddi_host_ext_powered = FALSE;
+
+void mddi_host_start_ext_display(void)
+{
+	down(&mddi_host_mutex);
+
+	if (!mddi_host_ext_powered) {
+		mddi_host_init(MDDI_HOST_EXT);
+
+		mddi_host_ext_powered = TRUE;
+	}
+
+	up(&mddi_host_mutex);
+}
+
+void mddi_host_stop_ext_display(void)
+{
+	down(&mddi_host_mutex);
+
+	if (mddi_host_ext_powered) {
+		mddi_host_powerdown(MDDI_HOST_EXT);
+
+		mddi_host_ext_powered = FALSE;
+	}
+
+	up(&mddi_host_mutex);
+}
diff --git a/drivers/video/msm/mddihosti.c b/drivers/video/msm/mddihosti.c
new file mode 100644
index 0000000..1a5a3fd
--- /dev/null
+++ b/drivers/video/msm/mddihosti.c
@@ -0,0 +1,2268 @@
+/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+
+#include "msm_fb_panel.h"
+#include "mddihost.h"
+#include "mddihosti.h"
+
+#define FEATURE_MDDI_UNDERRUN_RECOVERY
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+static void mddi_read_rev_packet(byte *data_ptr);
+#endif
+
+struct timer_list mddi_host_timer;
+
+#define MDDI_DEFAULT_TIMER_LENGTH 5000	/* 5 seconds */
+uint32 mddi_rtd_frequency = 60000;	/* send RTD every 60 seconds */
+uint32 mddi_client_status_frequency = 60000;	/* get status pkt every 60 secs */
+
+boolean mddi_vsync_detect_enabled = FALSE;
+mddi_gpio_info_type mddi_gpio;
+
+uint32 mddi_host_core_version;
+boolean mddi_debug_log_statistics = FALSE;
+/* #define FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION */
+/* default to TRUE in case MDP does not vote */
+static boolean mddi_host_mdp_active_flag = TRUE;
+static uint32 mddi_log_stats_counter;
+uint32 mddi_log_stats_frequency = 4000;
+int32 mddi_client_type;
+
+#define MDDI_DEFAULT_REV_PKT_SIZE            0x20
+
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+static boolean mddi_rev_ptr_workaround = TRUE;
+static uint32 mddi_reg_read_retry;
+static uint32 mddi_reg_read_retry_max = 20;
+static boolean mddi_enable_reg_read_retry = TRUE;
+static boolean mddi_enable_reg_read_retry_once = FALSE;
+
+#define MDDI_MAX_REV_PKT_SIZE                0x60
+
+#define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE  0x60
+
+#define MDDI_VIDEO_REV_PKT_SIZE              0x40
+#define MDDI_REV_BUFFER_SIZE  MDDI_MAX_REV_PKT_SIZE
+static byte rev_packet_data[MDDI_MAX_REV_PKT_SIZE];
+#endif /* FEATURE_MDDI_DISABLE_REVERSE */
+/* leave these variables so graphics will compile */
+
+#define MDDI_MAX_REV_DATA_SIZE  128
+/*lint -d__align(x) */
+boolean mddi_debug_clear_rev_data = TRUE;
+
+uint32 *mddi_reg_read_value_ptr;
+
+mddi_client_capability_type mddi_client_capability_pkt;
+static boolean mddi_client_capability_request = FALSE;
+
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+
+#define MAX_MDDI_REV_HANDLERS 2
+#define INVALID_PKT_TYPE 0xFFFF
+
+typedef struct {
+	mddi_rev_handler_type handler;	/* ISR to be executed */
+	uint16 pkt_type;
+} mddi_rev_pkt_handler_type;
+static mddi_rev_pkt_handler_type mddi_rev_pkt_handler[MAX_MDDI_REV_HANDLERS] =
+    { {NULL, INVALID_PKT_TYPE}, {NULL, INVALID_PKT_TYPE} };
+
+static boolean mddi_rev_encap_user_request = FALSE;
+static mddi_linked_list_notify_type mddi_rev_user;
+
+spinlock_t mddi_host_spin_lock;
+extern uint32 mdp_in_processing;
+#endif
+
+typedef enum {
+	MDDI_REV_IDLE
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	    , MDDI_REV_REG_READ_ISSUED,
+	MDDI_REV_REG_READ_SENT,
+	MDDI_REV_ENCAP_ISSUED,
+	MDDI_REV_STATUS_REQ_ISSUED,
+	MDDI_REV_CLIENT_CAP_ISSUED
+#endif
+} mddi_rev_link_state_type;
+
+typedef enum {
+	MDDI_LINK_DISABLED,
+	MDDI_LINK_HIBERNATING,
+	MDDI_LINK_ACTIVATING,
+	MDDI_LINK_ACTIVE
+} mddi_host_link_state_type;
+
+typedef struct {
+	uint32 count;
+	uint32 in_count;
+	uint32 disp_req_count;
+	uint32 state_change_count;
+	uint32 ll_done_count;
+	uint32 rev_avail_count;
+	uint32 error_count;
+	uint32 rev_encap_count;
+	uint32 llist_ptr_write_1;
+	uint32 llist_ptr_write_2;
+} mddi_host_int_type;
+
+typedef struct {
+	uint32 fwd_crc_count;
+	uint32 rev_crc_count;
+	uint32 pri_underflow;
+	uint32 sec_underflow;
+	uint32 rev_overflow;
+	uint32 pri_overwrite;
+	uint32 sec_overwrite;
+	uint32 rev_overwrite;
+	uint32 dma_failure;
+	uint32 rtd_failure;
+	uint32 reg_read_failure;
+#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
+	uint32 pri_underrun_detected;
+#endif
+} mddi_host_stat_type;
+
+typedef struct {
+	uint32 rtd_cnt;
+	uint32 rev_enc_cnt;
+	uint32 vid_cnt;
+	uint32 reg_acc_cnt;
+	uint32 cli_stat_cnt;
+	uint32 cli_cap_cnt;
+	uint32 reg_read_cnt;
+	uint32 link_active_cnt;
+	uint32 link_hibernate_cnt;
+	uint32 vsync_response_cnt;
+	uint32 fwd_crc_cnt;
+	uint32 rev_crc_cnt;
+} mddi_log_params_struct_type;
+
+typedef struct {
+	uint32 rtd_value;
+	uint32 rtd_counter;
+	uint32 client_status_cnt;
+	boolean rev_ptr_written;
+	uint8 *rev_ptr_start;
+	uint8 *rev_ptr_curr;
+	uint32 mddi_rev_ptr_write_val;
+	dma_addr_t rev_data_dma_addr;
+	uint16 rev_pkt_size;
+	mddi_rev_link_state_type rev_state;
+	mddi_host_link_state_type link_state;
+	mddi_host_driver_state_type driver_state;
+	boolean disable_hibernation;
+	uint32 saved_int_reg;
+	uint32 saved_int_en;
+	mddi_linked_list_type *llist_ptr;
+	dma_addr_t llist_dma_addr;
+	mddi_linked_list_type *llist_dma_ptr;
+	uint32 *rev_data_buf;
+	struct completion mddi_llist_avail_comp;
+	boolean mddi_waiting_for_llist_avail;
+	mddi_host_int_type int_type;
+	mddi_host_stat_type stats;
+	mddi_log_params_struct_type log_parms;
+	mddi_llist_info_type llist_info;
+	mddi_linked_list_notify_type llist_notify[MDDI_MAX_NUM_LLIST_ITEMS];
+} mddi_host_cntl_type;
+
+static mddi_host_type mddi_curr_host = MDDI_HOST_PRIM;
+static mddi_host_cntl_type mhctl[MDDI_NUM_HOST_CORES];
+mddi_linked_list_type *llist_extern[MDDI_NUM_HOST_CORES];
+mddi_linked_list_type *llist_dma_extern[MDDI_NUM_HOST_CORES];
+mddi_linked_list_notify_type *llist_extern_notify[MDDI_NUM_HOST_CORES];
+static mddi_log_params_struct_type prev_parms[MDDI_NUM_HOST_CORES];
+
+extern uint32 mdp_total_vdopkts;
+
+static boolean mddi_host_io_clock_on = FALSE;
+static boolean mddi_host_hclk_on = FALSE;
+
+int int_mddi_pri_flag = FALSE;
+int int_mddi_ext_flag = FALSE;
+
+static void mddi_report_errors(uint32 int_reg)
+{
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	if (int_reg & MDDI_INT_PRI_UNDERFLOW) {
+		pmhctl->stats.pri_underflow++;
+		MDDI_MSG_ERR("!!! MDDI Primary Underflow !!!\n");
+	}
+	if (int_reg & MDDI_INT_SEC_UNDERFLOW) {
+		pmhctl->stats.sec_underflow++;
+		MDDI_MSG_ERR("!!! MDDI Secondary Underflow !!!\n");
+	}
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	if (int_reg & MDDI_INT_REV_OVERFLOW) {
+		pmhctl->stats.rev_overflow++;
+		MDDI_MSG_ERR("!!! MDDI Reverse Overflow !!!\n");
+		pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
+		mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val);
+
+	}
+	if (int_reg & MDDI_INT_CRC_ERROR)
+		MDDI_MSG_ERR("!!! MDDI Reverse CRC Error !!!\n");
+#endif
+	if (int_reg & MDDI_INT_PRI_OVERWRITE) {
+		pmhctl->stats.pri_overwrite++;
+		MDDI_MSG_ERR("!!! MDDI Primary Overwrite !!!\n");
+	}
+	if (int_reg & MDDI_INT_SEC_OVERWRITE) {
+		pmhctl->stats.sec_overwrite++;
+		MDDI_MSG_ERR("!!! MDDI Secondary Overwrite !!!\n");
+	}
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	if (int_reg & MDDI_INT_REV_OVERWRITE) {
+		pmhctl->stats.rev_overwrite++;
+		/* This will show up normally and is not a problem */
+		MDDI_MSG_DEBUG("MDDI Reverse Overwrite!\n");
+	}
+	if (int_reg & MDDI_INT_RTD_FAILURE) {
+		mddi_host_reg_outm(INTEN, MDDI_INT_RTD_FAILURE, 0);
+		pmhctl->stats.rtd_failure++;
+		MDDI_MSG_ERR("!!! MDDI RTD Failure !!!\n");
+	}
+#endif
+	if (int_reg & MDDI_INT_DMA_FAILURE) {
+		pmhctl->stats.dma_failure++;
+		MDDI_MSG_ERR("!!! MDDI DMA Abort !!!\n");
+	}
+}
+
+static void mddi_host_enable_io_clock(void)
+{
+	if (!MDDI_HOST_IS_IO_CLOCK_ON)
+		MDDI_HOST_ENABLE_IO_CLOCK;
+}
+
+static void mddi_host_enable_hclk(void)
+{
+
+	if (!MDDI_HOST_IS_HCLK_ON)
+		MDDI_HOST_ENABLE_HCLK;
+}
+
+static void mddi_host_disable_io_clock(void)
+{
+#ifndef FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE
+	if (MDDI_HOST_IS_IO_CLOCK_ON)
+		MDDI_HOST_DISABLE_IO_CLOCK;
+#endif
+}
+
+static void mddi_host_disable_hclk(void)
+{
+#ifndef FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE
+	if (MDDI_HOST_IS_HCLK_ON)
+		MDDI_HOST_DISABLE_HCLK;
+#endif
+}
+
+static void mddi_vote_to_sleep(mddi_host_type host_idx, boolean sleep)
+{
+	uint16 vote_mask;
+
+	if (host_idx == MDDI_HOST_PRIM)
+		vote_mask = 0x01;
+	else
+		vote_mask = 0x02;
+}
+
+static void mddi_report_state_change(uint32 int_reg)
+{
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	if ((pmhctl->saved_int_reg & MDDI_INT_IN_HIBERNATION) &&
+	    (pmhctl->saved_int_reg & MDDI_INT_LINK_ACTIVE)) {
+		/* recover from condition where the io_clock was turned off by the
+		   clock driver during a transition to hibernation. The io_clock
+		   disable is to prevent MDP/MDDI underruns when changing ARM
+		   clock speeds. In the process of halting the ARM, the hclk
+		   divider needs to be set to 1. When it is set to 1, there is
+		   a small time (usecs) when hclk is off or slow, and this can
+		   cause an underrun. To prevent the underrun, clock driver turns
+		   off the MDDI io_clock before making the change. */
+		mddi_host_reg_out(CMD, MDDI_CMD_POWERUP);
+	}
+
+	if (int_reg & MDDI_INT_LINK_ACTIVE) {
+		pmhctl->link_state = MDDI_LINK_ACTIVE;
+		pmhctl->log_parms.link_active_cnt++;
+		pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL);
+		MDDI_MSG_DEBUG("!!! MDDI Active RTD:0x%x!!!\n",
+			       pmhctl->rtd_value);
+		/* now interrupt on hibernation */
+		mddi_host_reg_outm(INTEN,
+				   (MDDI_INT_IN_HIBERNATION |
+				    MDDI_INT_LINK_ACTIVE),
+				   MDDI_INT_IN_HIBERNATION);
+
+#ifdef DEBUG_MDDIHOSTI
+		/* if gpio interrupt is enabled, start polling at fastest
+		 * registered rate
+		 */
+		if (mddi_gpio.polling_enabled) {
+			timer_reg(&mddi_gpio_poll_timer,
+		mddi_gpio_poll_timer_cb, 0, mddi_gpio.polling_interval, 0);
+		}
+#endif
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+		if (mddi_rev_ptr_workaround) {
+			/* HW CR: need to reset reverse register stuff */
+			pmhctl->rev_ptr_written = FALSE;
+			pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
+		}
+#endif
+		/* vote on sleep */
+		mddi_vote_to_sleep(host_idx, FALSE);
+
+		if (host_idx == MDDI_HOST_PRIM) {
+			if (mddi_vsync_detect_enabled) {
+				/*
+				 * Indicate to client specific code that vsync
+				 * was enabled, but we did not detect a client
+				 * intiated wakeup. The client specific
+				 * handler can either reassert vsync detection,
+				 * or treat this as a valid vsync.
+				 */
+				mddi_client_lcd_vsync_detected(FALSE);
+				pmhctl->log_parms.vsync_response_cnt++;
+			}
+		}
+	}
+	if (int_reg & MDDI_INT_IN_HIBERNATION) {
+		pmhctl->link_state = MDDI_LINK_HIBERNATING;
+		pmhctl->log_parms.link_hibernate_cnt++;
+		MDDI_MSG_DEBUG("!!! MDDI Hibernating !!!\n");
+
+		if (mddi_client_type == 2) {
+			mddi_host_reg_out(PAD_CTL, 0x402a850f);
+			mddi_host_reg_out(PAD_CAL, 0x10220020);
+			mddi_host_reg_out(TA1_LEN, 0x0010);
+			mddi_host_reg_out(TA2_LEN, 0x0040);
+		}
+		/* now interrupt on link_active */
+#ifdef FEATURE_MDDI_DISABLE_REVERSE
+		mddi_host_reg_outm(INTEN,
+				   (MDDI_INT_MDDI_IN |
+				    MDDI_INT_IN_HIBERNATION |
+				    MDDI_INT_LINK_ACTIVE),
+				   MDDI_INT_LINK_ACTIVE);
+#else
+		mddi_host_reg_outm(INTEN,
+				   (MDDI_INT_MDDI_IN |
+				    MDDI_INT_IN_HIBERNATION |
+				    MDDI_INT_LINK_ACTIVE),
+				   (MDDI_INT_MDDI_IN | MDDI_INT_LINK_ACTIVE));
+
+		pmhctl->rtd_counter = mddi_rtd_frequency;
+
+		if (pmhctl->rev_state != MDDI_REV_IDLE) {
+			/* a rev_encap will not wake up the link, so we do that here */
+			pmhctl->link_state = MDDI_LINK_ACTIVATING;
+			mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
+		}
+#endif
+
+		if (pmhctl->disable_hibernation) {
+			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
+			mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
+			pmhctl->link_state = MDDI_LINK_ACTIVATING;
+		}
+#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
+		if ((pmhctl->llist_info.transmitting_start_idx !=
+		     UNASSIGNED_INDEX)
+		    &&
+		    ((pmhctl->
+		      saved_int_reg & (MDDI_INT_PRI_LINK_LIST_DONE |
+				       MDDI_INT_PRI_PTR_READ)) ==
+		     MDDI_INT_PRI_PTR_READ)) {
+			mddi_linked_list_type *llist_dma;
+			llist_dma = pmhctl->llist_dma_ptr;
+			/*
+			 * All indications are that we have not received a
+			 * linked list done interrupt, due to an underrun
+			 * condition. Recovery attempt is to send again.
+			 */
+			dma_coherent_pre_ops();
+			/* Write to primary pointer register again */
+			mddi_host_reg_out(PRI_PTR,
+					  &llist_dma[pmhctl->llist_info.
+						     transmitting_start_idx]);
+			pmhctl->stats.pri_underrun_detected++;
+		}
+#endif
+
+		/* vote on sleep */
+		if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
+			mddi_vote_to_sleep(host_idx, TRUE);
+		}
+
+#ifdef DEBUG_MDDIHOSTI
+		/* need to stop polling timer */
+		if (mddi_gpio.polling_enabled) {
+			(void) timer_clr(&mddi_gpio_poll_timer, T_NONE);
+		}
+#endif
+	}
+}
+
+void mddi_host_timer_service(unsigned long data)
+{
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	unsigned long flags;
+#endif
+	mddi_host_type host_idx;
+	mddi_host_cntl_type *pmhctl;
+
+	unsigned long time_ms = MDDI_DEFAULT_TIMER_LENGTH;
+	init_timer(&mddi_host_timer);
+	for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES;
+	     host_idx++) {
+		pmhctl = &(mhctl[host_idx]);
+		mddi_log_stats_counter += (uint32) time_ms;
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+		pmhctl->rtd_counter += (uint32) time_ms;
+		pmhctl->client_status_cnt += (uint32) time_ms;
+
+		if (host_idx == MDDI_HOST_PRIM) {
+			if (pmhctl->client_status_cnt >=
+			    mddi_client_status_frequency) {
+				if ((pmhctl->link_state ==
+				     MDDI_LINK_HIBERNATING)
+				    && (pmhctl->client_status_cnt >
+					mddi_client_status_frequency)) {
+					/*
+					 * special case where we are hibernating
+					 * and mddi_host_isr is not firing, so
+					 * kick the link so that the status can
+					 * be retrieved
+					 */
+
+					/* need to wake up link before issuing
+					 * rev encap command
+					 */
+					MDDI_MSG_INFO("wake up link!\n");
+					spin_lock_irqsave(&mddi_host_spin_lock,
+							  flags);
+					mddi_host_enable_hclk();
+					mddi_host_enable_io_clock();
+					pmhctl->link_state =
+					    MDDI_LINK_ACTIVATING;
+					mddi_host_reg_out(CMD,
+							  MDDI_CMD_LINK_ACTIVE);
+					spin_unlock_irqrestore
+					    (&mddi_host_spin_lock, flags);
+				} else
+				    if ((pmhctl->link_state == MDDI_LINK_ACTIVE)
+					&& pmhctl->disable_hibernation) {
+					/*
+					 * special case where we have disabled
+					 * hibernation and mddi_host_isr
+					 * is not firing, so enable interrupt
+					 * for no pkts pending, which will
+					 * generate an interrupt
+					 */
+					MDDI_MSG_INFO("kick isr!\n");
+					spin_lock_irqsave(&mddi_host_spin_lock,
+							  flags);
+					mddi_host_enable_hclk();
+					mddi_host_reg_outm(INTEN,
+							   MDDI_INT_NO_CMD_PKTS_PEND,
+							   MDDI_INT_NO_CMD_PKTS_PEND);
+					spin_unlock_irqrestore
+					    (&mddi_host_spin_lock, flags);
+				}
+			}
+		}
+#endif /* #ifndef FEATURE_MDDI_DISABLE_REVERSE */
+	}
+
+	/* Check if logging is turned on */
+	for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES;
+	     host_idx++) {
+		mddi_log_params_struct_type *prev_ptr = &(prev_parms[host_idx]);
+		pmhctl = &(mhctl[host_idx]);
+
+		if (mddi_debug_log_statistics) {
+
+			/* get video pkt count from MDP, since MDDI sw cannot know this */
+			pmhctl->log_parms.vid_cnt = mdp_total_vdopkts;
+
+			if (mddi_log_stats_counter >= mddi_log_stats_frequency) {
+				/* mddi_log_stats_counter = 0; */
+				if (mddi_debug_log_statistics) {
+					MDDI_MSG_NOTICE
+					    ("MDDI Statistics since last report:\n");
+					MDDI_MSG_NOTICE("  Packets sent:\n");
+					MDDI_MSG_NOTICE
+					    ("    %d RTD packet(s)\n",
+					     pmhctl->log_parms.rtd_cnt -
+					     prev_ptr->rtd_cnt);
+					if (prev_ptr->rtd_cnt !=
+					    pmhctl->log_parms.rtd_cnt) {
+						unsigned long flags;
+						spin_lock_irqsave
+						    (&mddi_host_spin_lock,
+						     flags);
+						mddi_host_enable_hclk();
+						pmhctl->rtd_value =
+						    mddi_host_reg_in(RTD_VAL);
+						spin_unlock_irqrestore
+						    (&mddi_host_spin_lock,
+						     flags);
+						MDDI_MSG_NOTICE
+						    ("      RTD value=%d\n",
+						     pmhctl->rtd_value);
+					}
+					MDDI_MSG_NOTICE
+					    ("    %d VIDEO packets\n",
+					     pmhctl->log_parms.vid_cnt -
+					     prev_ptr->vid_cnt);
+					MDDI_MSG_NOTICE
+					    ("    %d Register Access packets\n",
+					     pmhctl->log_parms.reg_acc_cnt -
+					     prev_ptr->reg_acc_cnt);
+					MDDI_MSG_NOTICE
+					    ("    %d Reverse Encapsulation packet(s)\n",
+					     pmhctl->log_parms.rev_enc_cnt -
+					     prev_ptr->rev_enc_cnt);
+					if (prev_ptr->rev_enc_cnt !=
+					    pmhctl->log_parms.rev_enc_cnt) {
+						/* report # of reverse CRC errors */
+						MDDI_MSG_NOTICE
+						    ("      %d reverse CRC errors detected\n",
+						     pmhctl->log_parms.
+						     rev_crc_cnt -
+						     prev_ptr->rev_crc_cnt);
+					}
+					MDDI_MSG_NOTICE
+					    ("  Packets received:\n");
+					MDDI_MSG_NOTICE
+					    ("    %d Client Status packets",
+					     pmhctl->log_parms.cli_stat_cnt -
+					     prev_ptr->cli_stat_cnt);
+					if (prev_ptr->cli_stat_cnt !=
+					    pmhctl->log_parms.cli_stat_cnt) {
+						MDDI_MSG_NOTICE
+						    ("      %d forward CRC errors reported\n",
+						     pmhctl->log_parms.
+						     fwd_crc_cnt -
+						     prev_ptr->fwd_crc_cnt);
+					}
+					MDDI_MSG_NOTICE
+					    ("    %d Register Access Read packets\n",
+					     pmhctl->log_parms.reg_read_cnt -
+					     prev_ptr->reg_read_cnt);
+
+					if (pmhctl->link_state ==
+					    MDDI_LINK_ACTIVE) {
+						MDDI_MSG_NOTICE
+						    ("  Current Link Status: Active\n");
+					} else
+					    if ((pmhctl->link_state ==
+						 MDDI_LINK_HIBERNATING)
+						|| (pmhctl->link_state ==
+						    MDDI_LINK_ACTIVATING)) {
+						MDDI_MSG_NOTICE
+						    ("  Current Link Status: Hibernation\n");
+					} else {
+						MDDI_MSG_NOTICE
+						    ("  Current Link Status: Inactive\n");
+					}
+					MDDI_MSG_NOTICE
+					    ("    Active state entered %d times\n",
+					     pmhctl->log_parms.link_active_cnt -
+					     prev_ptr->link_active_cnt);
+					MDDI_MSG_NOTICE
+					    ("    Hibernation state entered %d times\n",
+					     pmhctl->log_parms.
+					     link_hibernate_cnt -
+					     prev_ptr->link_hibernate_cnt);
+				}
+			}
+			prev_parms[host_idx] = pmhctl->log_parms;
+		}
+	}
+	if (mddi_log_stats_counter >= mddi_log_stats_frequency)
+		mddi_log_stats_counter = 0;
+
+	mutex_lock(&mddi_timer_lock);
+	if (!mddi_timer_shutdown_flag) {
+		mddi_host_timer.function = mddi_host_timer_service;
+		mddi_host_timer.data = 0;
+		mddi_host_timer.expires = jiffies + ((time_ms * HZ) / 1000);
+		add_timer(&mddi_host_timer);
+	}
+	mutex_unlock(&mddi_timer_lock);
+
+	return;
+}				/* mddi_host_timer_cb */
+
+static void mddi_process_link_list_done(void)
+{
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	/* normal forward linked list packet(s) were sent */
+	if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) {
+		MDDI_MSG_ERR("**** getting LL done, but no list ****\n");
+	} else {
+		uint16 idx;
+
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+		if (pmhctl->rev_state == MDDI_REV_REG_READ_ISSUED) {
+			/* special case where a register read packet was sent */
+			pmhctl->rev_state = MDDI_REV_REG_READ_SENT;
+			if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) {
+				MDDI_MSG_ERR
+				    ("**** getting LL done, but no list ****\n");
+			}
+		}
+#endif
+		for (idx = pmhctl->llist_info.transmitting_start_idx;;) {
+			uint16 next_idx = pmhctl->llist_notify[idx].next_idx;
+			/* with reg read we don't release the waiting tcb until after
+			 * the reverse encapsulation has completed.
+			 */
+			if (idx != pmhctl->llist_info.reg_read_idx) {
+				/* notify task that may be waiting on this completion */
+				if (pmhctl->llist_notify[idx].waiting) {
+					complete(&
+						 (pmhctl->llist_notify[idx].
+						  done_comp));
+				}
+				if (pmhctl->llist_notify[idx].done_cb != NULL) {
+					(*(pmhctl->llist_notify[idx].done_cb))
+					    ();
+				}
+
+				pmhctl->llist_notify[idx].in_use = FALSE;
+				pmhctl->llist_notify[idx].waiting = FALSE;
+				pmhctl->llist_notify[idx].done_cb = NULL;
+				if (idx < MDDI_NUM_DYNAMIC_LLIST_ITEMS) {
+					/* static LLIST items are configured only once */
+					pmhctl->llist_notify[idx].next_idx =
+					    UNASSIGNED_INDEX;
+				}
+				/*
+				 * currently, all linked list packets are
+				 * register access, so we can increment the
+				 * counter for that packet type here.
+				 */
+				pmhctl->log_parms.reg_acc_cnt++;
+			}
+			if (idx == pmhctl->llist_info.transmitting_end_idx)
+				break;
+			idx = next_idx;
+			if (idx == UNASSIGNED_INDEX)
+				MDDI_MSG_CRIT("MDDI linked list corruption!\n");
+		}
+
+		pmhctl->llist_info.transmitting_start_idx = UNASSIGNED_INDEX;
+		pmhctl->llist_info.transmitting_end_idx = UNASSIGNED_INDEX;
+
+		if (pmhctl->mddi_waiting_for_llist_avail) {
+			if (!
+			    (pmhctl->
+			     llist_notify[pmhctl->llist_info.next_free_idx].
+			     in_use)) {
+				pmhctl->mddi_waiting_for_llist_avail = FALSE;
+				complete(&(pmhctl->mddi_llist_avail_comp));
+			}
+		}
+	}
+
+	/* Turn off MDDI_INT_PRI_LINK_LIST_DONE interrupt */
+	mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, 0);
+
+}
+
+static void mddi_queue_forward_linked_list(void)
+{
+	uint16 first_pkt_index;
+	mddi_linked_list_type *llist_dma;
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+	llist_dma = pmhctl->llist_dma_ptr;
+
+	first_pkt_index = UNASSIGNED_INDEX;
+
+	if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) {
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+		if (pmhctl->llist_info.reg_read_waiting) {
+			if (pmhctl->rev_state == MDDI_REV_IDLE) {
+				/*
+				 * we have a register read to send and
+				 * can send it now
+				 */
+				pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED;
+				mddi_reg_read_retry = 0;
+				first_pkt_index =
+				    pmhctl->llist_info.waiting_start_idx;
+				pmhctl->llist_info.reg_read_waiting = FALSE;
+			}
+		} else
+#endif
+		{
+			/*
+			 * not register read to worry about, go ahead and write
+			 * anything that may be on the waiting list.
+			 */
+			first_pkt_index = pmhctl->llist_info.waiting_start_idx;
+		}
+	}
+
+	if (first_pkt_index != UNASSIGNED_INDEX) {
+		pmhctl->llist_info.transmitting_start_idx =
+		    pmhctl->llist_info.waiting_start_idx;
+		pmhctl->llist_info.transmitting_end_idx =
+		    pmhctl->llist_info.waiting_end_idx;
+		pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX;
+		pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX;
+
+		/* write to the primary pointer register */
+		MDDI_MSG_DEBUG("MDDI writing primary ptr with idx=%d\n",
+			       first_pkt_index);
+
+		pmhctl->int_type.llist_ptr_write_2++;
+
+		dma_coherent_pre_ops();
+		mddi_host_reg_out(PRI_PTR, &llist_dma[first_pkt_index]);
+
+		/* enable interrupt when complete */
+		mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE,
+				   MDDI_INT_PRI_LINK_LIST_DONE);
+
+	}
+
+}
+
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+static void mddi_read_rev_packet(byte *data_ptr)
+{
+	uint16 i, length;
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	uint8 *rev_ptr_overflow =
+	    (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE);
+
+	/* first determine the length and handle invalid lengths */
+	length = *pmhctl->rev_ptr_curr++;
+	if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
+		pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
+	length |= ((*pmhctl->rev_ptr_curr++) << 8);
+	if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
+		pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
+	if (length > (pmhctl->rev_pkt_size - 2)) {
+		MDDI_MSG_ERR("Invalid rev pkt length %d\n", length);
+		/* rev_pkt_size should always be <= rev_ptr_size so limit to packet size */
+		length = pmhctl->rev_pkt_size - 2;
+	}
+
+	/* If the data pointer is NULL, just increment the pmhctl->rev_ptr_curr.
+	 * Loop around if necessary. Don't bother reading the data.
+	 */
+	if (data_ptr == NULL) {
+		pmhctl->rev_ptr_curr += length;
+		if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
+			pmhctl->rev_ptr_curr -= MDDI_REV_BUFFER_SIZE;
+		return;
+	}
+
+	data_ptr[0] = length & 0x0ff;
+	data_ptr[1] = length >> 8;
+	data_ptr += 2;
+	/* copy the data to data_ptr byte-at-a-time */
+	for (i = 0; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow);
+	     i++)
+		*data_ptr++ = *pmhctl->rev_ptr_curr++;
+	if (pmhctl->rev_ptr_curr >= rev_ptr_overflow)
+		pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
+	for (; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow); i++)
+		*data_ptr++ = *pmhctl->rev_ptr_curr++;
+}
+
+static void mddi_process_rev_packets(void)
+{
+	uint32 rev_packet_count;
+	word i;
+	uint32 crc_errors;
+	boolean mddi_reg_read_successful = FALSE;
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	pmhctl->log_parms.rev_enc_cnt++;
+	if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) &&
+	    (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED) &&
+	    (pmhctl->rev_state != MDDI_REV_CLIENT_CAP_ISSUED)) {
+		MDDI_MSG_ERR("Wrong state %d for reverse int\n",
+			     pmhctl->rev_state);
+	}
+	/* Turn off MDDI_INT_REV_AVAIL interrupt */
+	mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL, 0);
+
+	/* Clear rev data avail int */
+	mddi_host_reg_out(INT, MDDI_INT_REV_DATA_AVAIL);
+
+	/* Get Number of packets */
+	rev_packet_count = mddi_host_reg_in(REV_PKT_CNT);
+
+#ifndef T_MSM7500
+	/* Clear out rev packet counter */
+	mddi_host_reg_out(REV_PKT_CNT, 0x0000);
+#endif
+
+#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
+	if ((pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) &&
+	    (rev_packet_count > 0) &&
+	    (mddi_host_core_version == 0x28 ||
+	     mddi_host_core_version == 0x30)) {
+
+		uint32 int_reg;
+		uint32 max_count = 0;
+
+		mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val);
+		int_reg = mddi_host_reg_in(INT);
+		while ((int_reg & 0x100000) == 0) {
+			udelay(3);
+			int_reg = mddi_host_reg_in(INT);
+			if (++max_count > 100)
+				break;
+		}
+	}
+#endif
+
+	/* Get CRC error count */
+	crc_errors = mddi_host_reg_in(REV_CRC_ERR);
+	if (crc_errors != 0) {
+		pmhctl->log_parms.rev_crc_cnt += crc_errors;
+		pmhctl->stats.rev_crc_count += crc_errors;
+		MDDI_MSG_ERR("!!! MDDI %d Reverse CRC Error(s) !!!\n",
+			     crc_errors);
+#ifndef T_MSM7500
+		/* Clear CRC error count */
+		mddi_host_reg_out(REV_CRC_ERR, 0x0000);
+#endif
+		/* also issue an RTD to attempt recovery */
+		pmhctl->rtd_counter = mddi_rtd_frequency;
+	}
+
+	pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL);
+
+	MDDI_MSG_DEBUG("MDDI rev pkt cnt=%d, ptr=0x%x, RTD:0x%x\n",
+		       rev_packet_count,
+		       pmhctl->rev_ptr_curr - pmhctl->rev_ptr_start,
+		       pmhctl->rtd_value);
+
+	if (rev_packet_count >= 1) {
+		mddi_invalidate_cache_lines((uint32 *) pmhctl->rev_ptr_start,
+					    MDDI_REV_BUFFER_SIZE);
+	} else {
+		MDDI_MSG_ERR("Reverse pkt sent, no data rxd\n");
+		if (mddi_reg_read_value_ptr)
+			*mddi_reg_read_value_ptr = -EBUSY;
+	}
+	/* order the reads */
+	dma_coherent_post_ops();
+	for (i = 0; i < rev_packet_count; i++) {
+		mddi_rev_packet_type *rev_pkt_ptr;
+
+		mddi_read_rev_packet(rev_packet_data);
+
+		rev_pkt_ptr = (mddi_rev_packet_type *) rev_packet_data;
+
+		if (rev_pkt_ptr->packet_length > pmhctl->rev_pkt_size) {
+			MDDI_MSG_ERR("!!!invalid packet size: %d\n",
+				     rev_pkt_ptr->packet_length);
+		}
+
+		MDDI_MSG_DEBUG("MDDI rev pkt 0x%x size 0x%x\n",
+			       rev_pkt_ptr->packet_type,
+			       rev_pkt_ptr->packet_length);
+
+		/* Do whatever you want to do with the data based on the packet type */
+		switch (rev_pkt_ptr->packet_type) {
+		case 66:	/* Client Capability */
+			{
+				mddi_client_capability_type
+				    *client_capability_pkt_ptr;
+
+				client_capability_pkt_ptr =
+				    (mddi_client_capability_type *)
+				    rev_packet_data;
+				MDDI_MSG_NOTICE
+				    ("Client Capability: Week=%d, Year=%d\n",
+				     client_capability_pkt_ptr->
+				     Week_of_Manufacture,
+				     client_capability_pkt_ptr->
+				     Year_of_Manufacture);
+				memcpy((void *)&mddi_client_capability_pkt,
+				       (void *)rev_packet_data,
+				       sizeof(mddi_client_capability_type));
+				pmhctl->log_parms.cli_cap_cnt++;
+			}
+			break;
+
+		case 70:	/* Display Status */
+			{
+				mddi_client_status_type *client_status_pkt_ptr;
+
+				client_status_pkt_ptr =
+				    (mddi_client_status_type *) rev_packet_data;
+				if ((client_status_pkt_ptr->crc_error_count !=
+				     0)
+				    || (client_status_pkt_ptr->
+					reverse_link_request != 0)) {
+					MDDI_MSG_ERR
+					    ("Client Status: RevReq=%d, CrcErr=%d\n",
+					     client_status_pkt_ptr->
+					     reverse_link_request,
+					     client_status_pkt_ptr->
+					     crc_error_count);
+				} else {
+					MDDI_MSG_DEBUG
+					    ("Client Status: RevReq=%d, CrcErr=%d\n",
+					     client_status_pkt_ptr->
+					     reverse_link_request,
+					     client_status_pkt_ptr->
+					     crc_error_count);
+				}
+				pmhctl->log_parms.fwd_crc_cnt +=
+				    client_status_pkt_ptr->crc_error_count;
+				pmhctl->stats.fwd_crc_count +=
+				    client_status_pkt_ptr->crc_error_count;
+				pmhctl->log_parms.cli_stat_cnt++;
+			}
+			break;
+
+		case 146:	/* register access packet */
+			{
+				mddi_register_access_packet_type
+				    * regacc_pkt_ptr;
+				uint32 data_count;
+
+				regacc_pkt_ptr =
+				    (mddi_register_access_packet_type *)
+				    rev_packet_data;
+
+				/* Bits[0:13] - read data count */
+				data_count = regacc_pkt_ptr->read_write_info
+					& 0x3FFF;
+				MDDI_MSG_DEBUG("\n MDDI rev read: 0x%x",
+					regacc_pkt_ptr->read_write_info);
+				MDDI_MSG_DEBUG("Reg Acc parse reg=0x%x,"
+					"value=0x%x\n", regacc_pkt_ptr->
+					register_address, regacc_pkt_ptr->
+					register_data_list[0]);
+
+				/* Copy register value to location passed in */
+				if (mddi_reg_read_value_ptr) {
+#if defined(T_MSM6280) && !defined(T_MSM7200)
+					/* only least significant 16 bits are valid with 6280 */
+					*mddi_reg_read_value_ptr =
+					    regacc_pkt_ptr->
+					    register_data_list[0] & 0x0000ffff;
+					mddi_reg_read_successful = TRUE;
+					mddi_reg_read_value_ptr = NULL;
+#else
+				if (data_count && data_count <=
+					MDDI_HOST_MAX_CLIENT_REG_IN_SAME_ADDR) {
+					memcpy(mddi_reg_read_value_ptr,
+						(void *)&regacc_pkt_ptr->
+						register_data_list[0],
+						data_count * 4);
+					mddi_reg_read_successful = TRUE;
+					mddi_reg_read_value_ptr = NULL;
+				}
+#endif
+				}
+
+#ifdef DEBUG_MDDIHOSTI
+				if ((mddi_gpio.polling_enabled) &&
+				    (regacc_pkt_ptr->register_address ==
+				     mddi_gpio.polling_reg)) {
+					/*
+					 * ToDo: need to call Linux GPIO call
+					 * here...
+					 */
+					 mddi_client_lcd_gpio_poll(
+					 regacc_pkt_ptr->register_data_list[0]);
+				}
+#endif
+				pmhctl->log_parms.reg_read_cnt++;
+			}
+			break;
+
+		case INVALID_PKT_TYPE:	/* 0xFFFF */
+			MDDI_MSG_ERR("!!!INVALID_PKT_TYPE rcvd\n");
+			break;
+
+		default:	/* any other packet */
+			{
+				uint16 hdlr;
+
+				for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS;
+				     hdlr++) {
+					if (mddi_rev_pkt_handler[hdlr].
+							handler == NULL)
+						continue;
+					if (mddi_rev_pkt_handler[hdlr].
+					    pkt_type ==
+					    rev_pkt_ptr->packet_type) {
+						(*(mddi_rev_pkt_handler[hdlr].
+						  handler)) (rev_pkt_ptr);
+					/* pmhctl->rev_state = MDDI_REV_IDLE; */
+						break;
+					}
+				}
+				if (hdlr >= MAX_MDDI_REV_HANDLERS)
+					MDDI_MSG_ERR("MDDI unknown rev pkt\n");
+			}
+			break;
+		}
+	}
+	if ((pmhctl->rev_ptr_curr + pmhctl->rev_pkt_size) >=
+	    (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE)) {
+		pmhctl->rev_ptr_written = FALSE;
+	}
+
+	if (pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) {
+		pmhctl->rev_state = MDDI_REV_IDLE;
+		if (mddi_rev_user.waiting) {
+			mddi_rev_user.waiting = FALSE;
+			complete(&(mddi_rev_user.done_comp));
+		} else if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) {
+			MDDI_MSG_ERR
+			    ("Reverse Encap state, but no reg read in progress\n");
+		} else {
+			if ((!mddi_reg_read_successful) &&
+			    (mddi_reg_read_retry < mddi_reg_read_retry_max) &&
+			    (mddi_enable_reg_read_retry)) {
+				/*
+				 * There is a race condition that can happen
+				 * where the reverse encapsulation message is
+				 * sent out by the MDDI host before the register
+				 * read packet is sent. As a work-around for
+				 * that problem we issue the reverse
+				 * encapsulation one more time before giving up.
+				 */
+				if (mddi_enable_reg_read_retry_once)
+					mddi_reg_read_retry =
+					    mddi_reg_read_retry_max;
+				else
+					mddi_reg_read_retry++;
+				pmhctl->rev_state = MDDI_REV_REG_READ_SENT;
+				pmhctl->stats.reg_read_failure++;
+			} else {
+				uint16 reg_read_idx =
+				    pmhctl->llist_info.reg_read_idx;
+
+				mddi_reg_read_retry = 0;
+				if (pmhctl->llist_notify[reg_read_idx].waiting) {
+					complete(&
+						 (pmhctl->
+						  llist_notify[reg_read_idx].
+						  done_comp));
+				}
+				pmhctl->llist_info.reg_read_idx =
+				    UNASSIGNED_INDEX;
+				if (pmhctl->llist_notify[reg_read_idx].
+				    done_cb != NULL) {
+					(*
+					 (pmhctl->llist_notify[reg_read_idx].
+					  done_cb)) ();
+				}
+				pmhctl->llist_notify[reg_read_idx].next_idx =
+				    UNASSIGNED_INDEX;
+				pmhctl->llist_notify[reg_read_idx].in_use =
+				    FALSE;
+				pmhctl->llist_notify[reg_read_idx].waiting =
+				    FALSE;
+				pmhctl->llist_notify[reg_read_idx].done_cb =
+				    NULL;
+				if (!mddi_reg_read_successful)
+					pmhctl->stats.reg_read_failure++;
+			}
+		}
+	} else if (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) {
+#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
+		if (mddi_host_core_version == 0x28 ||
+		    mddi_host_core_version == 0x30) {
+			mddi_host_reg_out(FIFO_ALLOC, 0x00);
+			pmhctl->rev_ptr_written = TRUE;
+			mddi_host_reg_out(REV_PTR,
+				pmhctl->mddi_rev_ptr_write_val);
+			pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
+			mddi_host_reg_out(CMD, 0xC00);
+		}
+#endif
+
+		if (mddi_rev_user.waiting) {
+			mddi_rev_user.waiting = FALSE;
+			complete(&(mddi_rev_user.done_comp));
+		}
+		pmhctl->rev_state = MDDI_REV_IDLE;
+	} else {
+		pmhctl->rev_state = MDDI_REV_IDLE;
+	}
+
+	/* pmhctl->rev_state = MDDI_REV_IDLE; */
+
+	/* Re-enable interrupt */
+	mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL,
+			   MDDI_INT_REV_DATA_AVAIL);
+
+}
+
+static void mddi_issue_reverse_encapsulation(void)
+{
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+	/* Only issue a reverse encapsulation packet if:
+	 * 1) another reverse is not in progress (MDDI_REV_IDLE).
+	 * 2) a register read has been sent (MDDI_REV_REG_READ_SENT).
+	 * 3) forward is not in progress, because of a hw bug in client that
+	 *    causes forward crc errors on packet immediately after rev encap.
+	 */
+	if (((pmhctl->rev_state == MDDI_REV_IDLE) ||
+	     (pmhctl->rev_state == MDDI_REV_REG_READ_SENT)) &&
+	    (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
+	    (!mdp_in_processing)) {
+		uint32 mddi_command = MDDI_CMD_SEND_REV_ENCAP;
+
+		if ((pmhctl->rev_state == MDDI_REV_REG_READ_SENT) ||
+		    (mddi_rev_encap_user_request == TRUE)) {
+			mddi_host_enable_io_clock();
+			if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
+				/* need to wake up link before issuing rev encap command */
+				MDDI_MSG_DEBUG("wake up link!\n");
+				pmhctl->link_state = MDDI_LINK_ACTIVATING;
+				mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
+			} else {
+				if (pmhctl->rtd_counter >= mddi_rtd_frequency) {
+					MDDI_MSG_DEBUG
+					    ("mddi sending RTD command!\n");
+					mddi_host_reg_out(CMD,
+							  MDDI_CMD_SEND_RTD);
+					pmhctl->rtd_counter = 0;
+					pmhctl->log_parms.rtd_cnt++;
+				}
+				if (pmhctl->rev_state != MDDI_REV_REG_READ_SENT) {
+					/* this is generic reverse request by user, so
+					 * reset the waiting flag. */
+					mddi_rev_encap_user_request = FALSE;
+				}
+				/* link is active so send reverse encap to get register read results */
+				pmhctl->rev_state = MDDI_REV_ENCAP_ISSUED;
+				mddi_command = MDDI_CMD_SEND_REV_ENCAP;
+				MDDI_MSG_DEBUG("sending rev encap!\n");
+			}
+		} else
+		    if ((pmhctl->client_status_cnt >=
+			 mddi_client_status_frequency)
+			|| mddi_client_capability_request) {
+			mddi_host_enable_io_clock();
+			if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
+				/* only wake up the link if it client status is overdue */
+				if ((pmhctl->client_status_cnt >=
+				     (mddi_client_status_frequency * 2))
+				    || mddi_client_capability_request) {
+					/* need to wake up link before issuing rev encap command */
+					MDDI_MSG_DEBUG("wake up link!\n");
+					pmhctl->link_state =
+					    MDDI_LINK_ACTIVATING;
+					mddi_host_reg_out(CMD,
+							  MDDI_CMD_LINK_ACTIVE);
+				}
+			} else {
+				if (pmhctl->rtd_counter >= mddi_rtd_frequency) {
+					MDDI_MSG_DEBUG
+					    ("mddi sending RTD command!\n");
+					mddi_host_reg_out(CMD,
+							  MDDI_CMD_SEND_RTD);
+					pmhctl->rtd_counter = 0;
+					pmhctl->log_parms.rtd_cnt++;
+				}
+				/* periodically get client status */
+				MDDI_MSG_DEBUG
+				    ("mddi sending rev enc! (get status)\n");
+				if (mddi_client_capability_request) {
+					pmhctl->rev_state =
+					    MDDI_REV_CLIENT_CAP_ISSUED;
+					mddi_command = MDDI_CMD_GET_CLIENT_CAP;
+					mddi_client_capability_request = FALSE;
+				} else {
+					pmhctl->rev_state =
+					    MDDI_REV_STATUS_REQ_ISSUED;
+					pmhctl->client_status_cnt = 0;
+					mddi_command =
+					    MDDI_CMD_GET_CLIENT_STATUS;
+				}
+			}
+		}
+		if ((pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) ||
+		    (pmhctl->rev_state == MDDI_REV_STATUS_REQ_ISSUED) ||
+		    (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED)) {
+			pmhctl->int_type.rev_encap_count++;
+#if defined(T_MSM6280) && !defined(T_MSM7200)
+			mddi_rev_pointer_written = TRUE;
+			mddi_host_reg_out(REV_PTR, mddi_rev_ptr_write_val);
+			mddi_rev_ptr_curr = mddi_rev_ptr_start;
+			/* force new rev ptr command */
+			mddi_host_reg_out(CMD, 0xC00);
+#else
+			if (!pmhctl->rev_ptr_written) {
+				MDDI_MSG_DEBUG("writing reverse pointer!\n");
+				pmhctl->rev_ptr_written = TRUE;
+#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
+				if ((pmhctl->rev_state ==
+				     MDDI_REV_CLIENT_CAP_ISSUED) &&
+				    (mddi_host_core_version == 0x28 ||
+				     mddi_host_core_version == 0x30)) {
+					pmhctl->rev_ptr_written = FALSE;
+					mddi_host_reg_out(FIFO_ALLOC, 0x02);
+				} else
+					mddi_host_reg_out(REV_PTR,
+						  pmhctl->
+						  mddi_rev_ptr_write_val);
+#else
+				mddi_host_reg_out(REV_PTR,
+						  pmhctl->
+						  mddi_rev_ptr_write_val);
+#endif
+			}
+#endif
+			if (mddi_debug_clear_rev_data) {
+				uint16 i;
+				for (i = 0; i < MDDI_MAX_REV_DATA_SIZE / 4; i++)
+					pmhctl->rev_data_buf[i] = 0xdddddddd;
+				/* clean cache */
+				mddi_flush_cache_lines(pmhctl->rev_data_buf,
+						       MDDI_MAX_REV_DATA_SIZE);
+			}
+
+			/* send reverse encapsulation to get needed data */
+			mddi_host_reg_out(CMD, mddi_command);
+		}
+	}
+
+}
+
+static void mddi_process_client_initiated_wakeup(void)
+{
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	/* Disable MDDI_INT Interrupt, we detect client initiated wakeup one
+	 * time for each entry into hibernation */
+	mddi_host_reg_outm(INTEN, MDDI_INT_MDDI_IN, 0);
+
+	if (host_idx == MDDI_HOST_PRIM) {
+		if (mddi_vsync_detect_enabled) {
+			mddi_host_enable_io_clock();
+#ifndef MDDI_HOST_DISP_LISTEN
+			/* issue command to bring up link */
+			/* need to do this to clear the vsync condition */
+			if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
+				pmhctl->link_state = MDDI_LINK_ACTIVATING;
+				mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
+			}
+#endif
+			/*
+			 * Indicate to client specific code that vsync was
+			 * enabled, and we did not detect a client initiated
+			 * wakeup. The client specific handler can clear the
+			 * condition if necessary to prevent subsequent
+			 * client initiated wakeups.
+			 */
+			mddi_client_lcd_vsync_detected(TRUE);
+			pmhctl->log_parms.vsync_response_cnt++;
+			MDDI_MSG_NOTICE("MDDI_INT_IN condition\n");
+
+		}
+	}
+
+	if (mddi_gpio.polling_enabled) {
+		mddi_host_enable_io_clock();
+		/* check interrupt status now */
+		(void)mddi_queue_register_read_int(mddi_gpio.polling_reg,
+						   &mddi_gpio.polling_val);
+	}
+}
+#endif /* FEATURE_MDDI_DISABLE_REVERSE */
+
+static void mddi_host_isr(void)
+{
+	uint32 int_reg, int_en;
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	uint32 status_reg;
+#endif
+	mddi_host_type host_idx = mddi_curr_host;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	if (!MDDI_HOST_IS_HCLK_ON) {
+		MDDI_HOST_ENABLE_HCLK;
+	}
+	int_reg = mddi_host_reg_in(INT);
+	int_en = mddi_host_reg_in(INTEN);
+	pmhctl->saved_int_reg = int_reg;
+	pmhctl->saved_int_en = int_en;
+	int_reg = int_reg & int_en;
+	pmhctl->int_type.count++;
+
+
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	status_reg = mddi_host_reg_in(STAT);
+
+	if ((int_reg & MDDI_INT_MDDI_IN) ||
+	    ((int_en & MDDI_INT_MDDI_IN) &&
+	     ((int_reg == 0) || (status_reg & MDDI_STAT_CLIENT_WAKEUP_REQ)))) {
+		/*
+		 * The MDDI_IN condition will clear itself, and so it is
+		 * possible that MDDI_IN was the reason for the isr firing,
+		 * even though the interrupt register does not have the
+		 * MDDI_IN bit set. To check if this was the case we need to
+		 * look at the status register bit that signifies a client
+		 * initiated wakeup. If the status register bit is set, as well
+		 * as the MDDI_IN interrupt enabled, then we treat this as a
+		 * client initiated wakeup.
+		 */
+		if (int_reg & MDDI_INT_MDDI_IN)
+			pmhctl->int_type.in_count++;
+		mddi_process_client_initiated_wakeup();
+	}
+#endif
+
+	if (int_reg & MDDI_INT_LINK_STATE_CHANGES) {
+		pmhctl->int_type.state_change_count++;
+		mddi_report_state_change(int_reg);
+	}
+
+	if (int_reg & MDDI_INT_PRI_LINK_LIST_DONE) {
+		pmhctl->int_type.ll_done_count++;
+		mddi_process_link_list_done();
+	}
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	if (int_reg & MDDI_INT_REV_DATA_AVAIL) {
+		pmhctl->int_type.rev_avail_count++;
+		mddi_process_rev_packets();
+	}
+#endif
+
+	if (int_reg & MDDI_INT_ERROR_CONDITIONS) {
+		pmhctl->int_type.error_count++;
+		mddi_report_errors(int_reg);
+
+		mddi_host_reg_out(INT, int_reg & MDDI_INT_ERROR_CONDITIONS);
+	}
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	mddi_issue_reverse_encapsulation();
+
+	if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) &&
+	    (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED))
+#endif
+		/* don't want simultaneous reverse and forward with Eagle */
+		mddi_queue_forward_linked_list();
+
+	if (int_reg & MDDI_INT_NO_CMD_PKTS_PEND) {
+		/* this interrupt is used to kick the isr when hibernation is disabled */
+		mddi_host_reg_outm(INTEN, MDDI_INT_NO_CMD_PKTS_PEND, 0);
+	}
+
+	if ((!mddi_host_mdp_active_flag) &&
+	    (!mddi_vsync_detect_enabled) &&
+	    (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
+	    (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) &&
+	    (pmhctl->rev_state == MDDI_REV_IDLE)) {
+		if (pmhctl->link_state == MDDI_LINK_HIBERNATING) {
+			mddi_host_disable_io_clock();
+			mddi_host_disable_hclk();
+		}
+#ifdef FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION
+		else if ((pmhctl->link_state == MDDI_LINK_ACTIVE) &&
+			 (!pmhctl->disable_hibernation)) {
+			mddi_host_reg_out(CMD, MDDI_CMD_POWERDOWN);
+		}
+#endif
+	}
+}
+
+static void mddi_host_isr_primary(void)
+{
+	mddi_curr_host = MDDI_HOST_PRIM;
+	mddi_host_isr();
+}
+
+irqreturn_t mddi_pmdh_isr_proxy(int irq, void *ptr)
+{
+	mddi_host_isr_primary();
+	return IRQ_HANDLED;
+}
+
+static void mddi_host_isr_external(void)
+{
+	mddi_curr_host = MDDI_HOST_EXT;
+	mddi_host_isr();
+	mddi_curr_host = MDDI_HOST_PRIM;
+}
+
+irqreturn_t mddi_emdh_isr_proxy(int irq, void *ptr)
+{
+	mddi_host_isr_external();
+	return IRQ_HANDLED;
+}
+
+static void mddi_host_initialize_registers(mddi_host_type host_idx)
+{
+	uint32 pad_reg_val;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	if (pmhctl->driver_state == MDDI_DRIVER_ENABLED)
+		return;
+
+	/* turn on HCLK to MDDI host core */
+	mddi_host_enable_hclk();
+
+	/* MDDI Reset command */
+	mddi_host_reg_out(CMD, MDDI_CMD_RESET);
+
+	/* Version register (= 0x01) */
+	mddi_host_reg_out(VERSION, 0x0001);
+
+	/* Bytes per subframe register */
+	mddi_host_reg_out(BPS, MDDI_HOST_BYTES_PER_SUBFRAME);
+
+	/* Subframes per media frames register (= 0x03) */
+	mddi_host_reg_out(SPM, 0x0003);
+
+	/* Turn Around 1 register (= 0x05) */
+	mddi_host_reg_out(TA1_LEN, 0x0005);
+
+	/* Turn Around 2 register (= 0x0C) */
+	mddi_host_reg_out(TA2_LEN, MDDI_HOST_TA2_LEN);
+
+	/* Drive hi register (= 0x96) */
+	mddi_host_reg_out(DRIVE_HI, 0x0096);
+
+	/* Drive lo register (= 0x32) */
+	mddi_host_reg_out(DRIVE_LO, 0x0032);
+
+	/* Display wakeup count register (= 0x3c) */
+	mddi_host_reg_out(DISP_WAKE, 0x003c);
+
+	/* Reverse Rate Divisor register (= 0x2) */
+	mddi_host_reg_out(REV_RATE_DIV, MDDI_HOST_REV_RATE_DIV);
+
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	/* Reverse Pointer Size */
+	mddi_host_reg_out(REV_SIZE, MDDI_REV_BUFFER_SIZE);
+
+	/* Rev Encap Size */
+	mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
+#endif
+
+	/* Periodic Rev Encap */
+	/* don't send periodically */
+	mddi_host_reg_out(CMD, MDDI_CMD_PERIODIC_REV_ENCAP);
+
+	pad_reg_val = mddi_host_reg_in(PAD_CTL);
+	if (pad_reg_val == 0) {
+		/* If we are turning on band gap, need to wait 5us before turning
+		 * on the rest of the PAD */
+		mddi_host_reg_out(PAD_CTL, 0x08000);
+		udelay(5);
+	}
+#ifdef T_MSM7200
+	/* Recommendation from PAD hw team */
+	mddi_host_reg_out(PAD_CTL, 0xa850a);
+#else
+	/* Recommendation from PAD hw team */
+	mddi_host_reg_out(PAD_CTL, 0xa850f);
+#endif
+
+	pad_reg_val = 0x00220020;
+
+#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
+	mddi_host_reg_out(PAD_IO_CTL, 0x00320000);
+	mddi_host_reg_out(PAD_CAL, pad_reg_val);
+#endif
+
+	mddi_host_core_version = mddi_host_reg_inm(CORE_VER, 0xffff);
+
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	if (mddi_host_core_version >= 8)
+		mddi_rev_ptr_workaround = FALSE;
+	pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start;
+#endif
+
+	if ((mddi_host_core_version > 8) && (mddi_host_core_version < 0x19))
+		mddi_host_reg_out(TEST, 0x2);
+
+	/* Need an even number for counts */
+	mddi_host_reg_out(DRIVER_START_CNT, 0x60006);
+
+#ifndef T_MSM7500
+	/* Setup defaults for MDP related register */
+	mddi_host_reg_out(MDP_VID_FMT_DES, 0x5666);
+	mddi_host_reg_out(MDP_VID_PIX_ATTR, 0x00C3);
+	mddi_host_reg_out(MDP_VID_CLIENTID, 0);
+#endif
+
+	/* automatically hibernate after 1 empty subframe */
+	if (pmhctl->disable_hibernation)
+		mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
+	else
+		mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
+
+	/* Bring up link if display (client) requests it */
+#ifdef MDDI_HOST_DISP_LISTEN
+	mddi_host_reg_out(CMD, MDDI_CMD_DISP_LISTEN);
+#else
+	mddi_host_reg_out(CMD, MDDI_CMD_DISP_IGNORE);
+#endif
+
+}
+
+void mddi_host_configure_interrupts(mddi_host_type host_idx, boolean enable)
+{
+	unsigned long flags;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+
+	/* turn on HCLK to MDDI host core if it has been disabled */
+	mddi_host_enable_hclk();
+	/* Clear MDDI Interrupt enable reg */
+	mddi_host_reg_out(INTEN, 0);
+
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+
+	if (enable) {
+		pmhctl->driver_state = MDDI_DRIVER_ENABLED;
+
+		if (host_idx == MDDI_HOST_PRIM) {
+			if (request_irq
+			    (INT_MDDI_PRI, mddi_pmdh_isr_proxy, IRQF_DISABLED,
+			     "PMDH", 0) != 0)
+				printk(KERN_ERR
+				       "a mddi: unable to request_irq\n");
+			else {
+				int_mddi_pri_flag = TRUE;
+				irq_enabled = 1;
+			}
+		} else {
+			if (request_irq
+			    (INT_MDDI_EXT, mddi_emdh_isr_proxy, IRQF_DISABLED,
+			     "EMDH", 0) != 0)
+				printk(KERN_ERR
+				       "b mddi: unable to request_irq\n");
+			else
+				int_mddi_ext_flag = TRUE;
+		}
+
+		/* Set MDDI Interrupt enable reg -- Enable Reverse data avail */
+#ifdef FEATURE_MDDI_DISABLE_REVERSE
+		mddi_host_reg_out(INTEN,
+				  MDDI_INT_ERROR_CONDITIONS |
+				  MDDI_INT_LINK_STATE_CHANGES);
+#else
+		/* Reverse Pointer register */
+		pmhctl->rev_ptr_written = FALSE;
+
+		mddi_host_reg_out(INTEN,
+				  MDDI_INT_REV_DATA_AVAIL |
+				  MDDI_INT_ERROR_CONDITIONS |
+				  MDDI_INT_LINK_STATE_CHANGES);
+		pmhctl->rtd_counter = mddi_rtd_frequency;
+		pmhctl->client_status_cnt = 0;
+#endif
+	} else {
+		if (pmhctl->driver_state == MDDI_DRIVER_ENABLED)
+			pmhctl->driver_state = MDDI_DRIVER_DISABLED;
+	}
+
+}
+
+/*
+ * mddi_host_client_cnt_reset:
+ * reset client_status_cnt to 0 to make sure host does not
+ * send RTD cmd to client right after resume before mddi
+ * client be powered up. this fix "MDDI RTD Failure" problem
+ */
+void mddi_host_client_cnt_reset(void)
+{
+	unsigned long flags;
+	mddi_host_cntl_type *pmhctl;
+
+	pmhctl = &(mhctl[MDDI_HOST_PRIM]);
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+	pmhctl->client_status_cnt = 0;
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+}
+
+static void mddi_host_powerup(mddi_host_type host_idx)
+{
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	if (pmhctl->link_state != MDDI_LINK_DISABLED)
+		return;
+
+	/* enable IO_CLK and hclk to MDDI host core */
+	mddi_host_enable_io_clock();
+
+	mddi_host_initialize_registers(host_idx);
+	mddi_host_configure_interrupts(host_idx, TRUE);
+
+	pmhctl->link_state = MDDI_LINK_ACTIVATING;
+
+	/* Link activate command */
+	mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE);
+
+#ifdef CLKRGM_MDDI_IO_CLOCK_IN_MHZ
+	MDDI_MSG_NOTICE("MDDI Host: Activating Link %d Mbps\n",
+			CLKRGM_MDDI_IO_CLOCK_IN_MHZ * 2);
+#else
+	MDDI_MSG_NOTICE("MDDI Host: Activating Link\n");
+#endif
+
+	/* Initialize the timer */
+	if (host_idx == MDDI_HOST_PRIM)
+		mddi_host_timer_service(0);
+}
+
+void mddi_send_fw_link_skew_cal(mddi_host_type host_idx)
+{
+	mddi_host_reg_out(CMD, MDDI_CMD_FW_LINK_SKEW_CAL);
+	MDDI_MSG_DEBUG("%s: Skew Calibration done!!\n", __func__);
+}
+
+
+void mddi_host_init(mddi_host_type host_idx)
+/* Write out the MDDI configuration registers */
+{
+	static boolean initialized = FALSE;
+	mddi_host_cntl_type *pmhctl;
+
+	if (host_idx >= MDDI_NUM_HOST_CORES) {
+		MDDI_MSG_ERR("Invalid host core index\n");
+		return;
+	}
+
+	if (!initialized) {
+		uint16 idx;
+		mddi_host_type host;
+
+		for (host = MDDI_HOST_PRIM; host < MDDI_NUM_HOST_CORES; host++) {
+			pmhctl = &(mhctl[host]);
+			initialized = TRUE;
+
+			pmhctl->llist_ptr =
+			    dma_alloc_coherent(NULL, MDDI_LLIST_POOL_SIZE,
+					       &(pmhctl->llist_dma_addr),
+					       GFP_KERNEL);
+			pmhctl->llist_dma_ptr =
+			    (mddi_linked_list_type *) (void *)pmhctl->
+			    llist_dma_addr;
+#ifdef FEATURE_MDDI_DISABLE_REVERSE
+			pmhctl->rev_data_buf = NULL;
+			if (pmhctl->llist_ptr == NULL)
+#else
+			mddi_rev_user.waiting = FALSE;
+			init_completion(&(mddi_rev_user.done_comp));
+			pmhctl->rev_data_buf =
+			    dma_alloc_coherent(NULL, MDDI_MAX_REV_DATA_SIZE,
+					       &(pmhctl->rev_data_dma_addr),
+					       GFP_KERNEL);
+			if ((pmhctl->llist_ptr == NULL)
+			    || (pmhctl->rev_data_buf == NULL))
+#endif
+			{
+				MDDI_MSG_CRIT
+				    ("unable to alloc non-cached memory\n");
+			}
+			llist_extern[host] = pmhctl->llist_ptr;
+			llist_dma_extern[host] = pmhctl->llist_dma_ptr;
+			llist_extern_notify[host] = pmhctl->llist_notify;
+
+			for (idx = 0; idx < UNASSIGNED_INDEX; idx++) {
+				init_completion(&
+						(pmhctl->llist_notify[idx].
+						 done_comp));
+			}
+			init_completion(&(pmhctl->mddi_llist_avail_comp));
+			spin_lock_init(&mddi_host_spin_lock);
+			pmhctl->mddi_waiting_for_llist_avail = FALSE;
+			pmhctl->mddi_rev_ptr_write_val =
+			    (uint32) (void *)(pmhctl->rev_data_dma_addr);
+			pmhctl->rev_ptr_start = (void *)pmhctl->rev_data_buf;
+
+			pmhctl->rev_pkt_size = MDDI_DEFAULT_REV_PKT_SIZE;
+			pmhctl->rev_state = MDDI_REV_IDLE;
+#ifdef IMAGE_MODEM_PROC
+			/* assume hibernation state is last state from APPS proc, so that
+			 * we don't reinitialize the host core */
+			pmhctl->link_state = MDDI_LINK_HIBERNATING;
+#else
+			pmhctl->link_state = MDDI_LINK_DISABLED;
+#endif
+			pmhctl->driver_state = MDDI_DRIVER_DISABLED;
+			pmhctl->disable_hibernation = FALSE;
+
+			/* initialize llist variables */
+			pmhctl->llist_info.transmitting_start_idx =
+			    UNASSIGNED_INDEX;
+			pmhctl->llist_info.transmitting_end_idx =
+			    UNASSIGNED_INDEX;
+			pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX;
+			pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX;
+			pmhctl->llist_info.reg_read_idx = UNASSIGNED_INDEX;
+			pmhctl->llist_info.next_free_idx =
+			    MDDI_FIRST_DYNAMIC_LLIST_IDX;
+			pmhctl->llist_info.reg_read_waiting = FALSE;
+
+			mddi_vsync_detect_enabled = FALSE;
+			mddi_gpio.polling_enabled = FALSE;
+
+			pmhctl->int_type.count = 0;
+			pmhctl->int_type.in_count = 0;
+			pmhctl->int_type.disp_req_count = 0;
+			pmhctl->int_type.state_change_count = 0;
+			pmhctl->int_type.ll_done_count = 0;
+			pmhctl->int_type.rev_avail_count = 0;
+			pmhctl->int_type.error_count = 0;
+			pmhctl->int_type.rev_encap_count = 0;
+			pmhctl->int_type.llist_ptr_write_1 = 0;
+			pmhctl->int_type.llist_ptr_write_2 = 0;
+
+			pmhctl->stats.fwd_crc_count = 0;
+			pmhctl->stats.rev_crc_count = 0;
+			pmhctl->stats.pri_underflow = 0;
+			pmhctl->stats.sec_underflow = 0;
+			pmhctl->stats.rev_overflow = 0;
+			pmhctl->stats.pri_overwrite = 0;
+			pmhctl->stats.sec_overwrite = 0;
+			pmhctl->stats.rev_overwrite = 0;
+			pmhctl->stats.dma_failure = 0;
+			pmhctl->stats.rtd_failure = 0;
+			pmhctl->stats.reg_read_failure = 0;
+#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY
+			pmhctl->stats.pri_underrun_detected = 0;
+#endif
+
+			pmhctl->log_parms.rtd_cnt = 0;
+			pmhctl->log_parms.rev_enc_cnt = 0;
+			pmhctl->log_parms.vid_cnt = 0;
+			pmhctl->log_parms.reg_acc_cnt = 0;
+			pmhctl->log_parms.cli_stat_cnt = 0;
+			pmhctl->log_parms.cli_cap_cnt = 0;
+			pmhctl->log_parms.reg_read_cnt = 0;
+			pmhctl->log_parms.link_active_cnt = 0;
+			pmhctl->log_parms.link_hibernate_cnt = 0;
+			pmhctl->log_parms.fwd_crc_cnt = 0;
+			pmhctl->log_parms.rev_crc_cnt = 0;
+			pmhctl->log_parms.vsync_response_cnt = 0;
+
+			prev_parms[host_idx] = pmhctl->log_parms;
+			mddi_client_capability_pkt.packet_length = 0;
+		}
+
+#ifndef T_MSM7500
+		/* tell clock driver we are user of this PLL */
+		MDDI_HOST_ENABLE_IO_CLOCK;
+#endif
+	}
+
+	mddi_host_powerup(host_idx);
+	pmhctl = &(mhctl[host_idx]);
+}
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+static uint32 mddi_client_id;
+
+uint32 mddi_get_client_id(void)
+{
+
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+	static boolean client_detection_try = FALSE;
+	mddi_host_cntl_type *pmhctl;
+	unsigned long flags;
+	uint16 saved_rev_pkt_size;
+	int ret;
+
+	if (!client_detection_try) {
+		/* Toshiba display requires larger drive_lo value */
+		mddi_host_reg_out(DRIVE_LO, 0x0050);
+
+		pmhctl = &(mhctl[MDDI_HOST_PRIM]);
+
+		saved_rev_pkt_size = pmhctl->rev_pkt_size;
+
+		/* Increase Rev Encap Size */
+		pmhctl->rev_pkt_size = MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE;
+		mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
+
+		/* disable hibernation temporarily */
+		if (!pmhctl->disable_hibernation)
+			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
+
+		mddi_rev_user.waiting = TRUE;
+		INIT_COMPLETION(mddi_rev_user.done_comp);
+
+		spin_lock_irqsave(&mddi_host_spin_lock, flags);
+
+		/* turn on clock(s), if they have been disabled */
+		mddi_host_enable_hclk();
+		mddi_host_enable_io_clock();
+
+		mddi_client_capability_request = TRUE;
+
+		if (pmhctl->rev_state == MDDI_REV_IDLE) {
+			/* attempt to send the reverse encapsulation now */
+			mddi_issue_reverse_encapsulation();
+		}
+		spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+
+		wait_for_completion_killable(&(mddi_rev_user.done_comp));
+
+		/* Set Rev Encap Size back to its original value */
+		pmhctl->rev_pkt_size = saved_rev_pkt_size;
+		mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size);
+
+		/* reenable auto-hibernate */
+		if (!pmhctl->disable_hibernation)
+			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
+
+		mddi_host_reg_out(DRIVE_LO, 0x0032);
+		client_detection_try = TRUE;
+
+		mddi_client_id = (mddi_client_capability_pkt.Mfr_Name<<16) |
+				mddi_client_capability_pkt.Product_Code;
+
+		if (!mddi_client_id)
+			mddi_disable(1);
+
+		ret = mddi_client_power(mddi_client_id);
+		if (ret < 0)
+			MDDI_MSG_ERR("mddi_client_power return %d", ret);
+	}
+
+#endif
+
+	return mddi_client_id;
+}
+#endif
+
+void mddi_host_powerdown(mddi_host_type host_idx)
+{
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	if (host_idx >= MDDI_NUM_HOST_CORES) {
+		MDDI_MSG_ERR("Invalid host core index\n");
+		return;
+	}
+
+	if (pmhctl->driver_state == MDDI_DRIVER_RESET) {
+		return;
+	}
+
+	if (host_idx == MDDI_HOST_PRIM) {
+		/* disable timer */
+		del_timer(&mddi_host_timer);
+	}
+
+	mddi_host_configure_interrupts(host_idx, FALSE);
+
+	/* turn on HCLK to MDDI host core if it has been disabled */
+	mddi_host_enable_hclk();
+
+	/* MDDI Reset command */
+	mddi_host_reg_out(CMD, MDDI_CMD_RESET);
+
+	/* Pad Control Register */
+	mddi_host_reg_out(PAD_CTL, 0x0);
+
+	/* disable IO_CLK and hclk to MDDI host core */
+	mddi_host_disable_io_clock();
+	mddi_host_disable_hclk();
+
+	pmhctl->link_state = MDDI_LINK_DISABLED;
+	pmhctl->driver_state = MDDI_DRIVER_RESET;
+
+	MDDI_MSG_NOTICE("MDDI Host: Disabling Link\n");
+
+}
+
+uint16 mddi_get_next_free_llist_item(mddi_host_type host_idx, boolean wait)
+{
+	unsigned long flags;
+	uint16 ret_idx;
+	boolean forced_wait = FALSE;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	ret_idx = pmhctl->llist_info.next_free_idx;
+
+	pmhctl->llist_info.next_free_idx++;
+	if (pmhctl->llist_info.next_free_idx >= MDDI_NUM_DYNAMIC_LLIST_ITEMS)
+		pmhctl->llist_info.next_free_idx = MDDI_FIRST_DYNAMIC_LLIST_IDX;
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+	if (pmhctl->llist_notify[ret_idx].in_use) {
+		if (!wait) {
+			pmhctl->llist_info.next_free_idx = ret_idx;
+			ret_idx = UNASSIGNED_INDEX;
+		} else {
+			forced_wait = TRUE;
+			INIT_COMPLETION(pmhctl->mddi_llist_avail_comp);
+		}
+	}
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+
+	if (forced_wait) {
+		wait_for_completion_killable(&
+						  (pmhctl->
+						   mddi_llist_avail_comp));
+		MDDI_MSG_ERR("task waiting on mddi llist item\n");
+	}
+
+	if (ret_idx != UNASSIGNED_INDEX) {
+		pmhctl->llist_notify[ret_idx].waiting = FALSE;
+		pmhctl->llist_notify[ret_idx].done_cb = NULL;
+		pmhctl->llist_notify[ret_idx].in_use = TRUE;
+		pmhctl->llist_notify[ret_idx].next_idx = UNASSIGNED_INDEX;
+	}
+
+	return ret_idx;
+}
+
+uint16 mddi_get_reg_read_llist_item(mddi_host_type host_idx, boolean wait)
+{
+#ifdef FEATURE_MDDI_DISABLE_REVERSE
+	MDDI_MSG_CRIT("No reverse link available\n");
+	(void)wait;
+	return FALSE;
+#else
+	unsigned long flags;
+	uint16 ret_idx;
+	boolean error = FALSE;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+	if (pmhctl->llist_info.reg_read_idx != UNASSIGNED_INDEX) {
+		/* need to block here or is this an error condition? */
+		error = TRUE;
+		ret_idx = UNASSIGNED_INDEX;
+	}
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+
+	if (!error) {
+		ret_idx = pmhctl->llist_info.reg_read_idx =
+		    mddi_get_next_free_llist_item(host_idx, wait);
+		/* clear the reg_read_waiting flag */
+		pmhctl->llist_info.reg_read_waiting = FALSE;
+	}
+
+	if (error)
+		MDDI_MSG_ERR("***** Reg read still in progress! ****\n");
+	return ret_idx;
+#endif
+
+}
+
+void mddi_queue_forward_packets(uint16 first_llist_idx,
+				uint16 last_llist_idx,
+				boolean wait,
+				mddi_llist_done_cb_type llist_done_cb,
+				mddi_host_type host_idx)
+{
+	unsigned long flags;
+	mddi_linked_list_type *llist;
+	mddi_linked_list_type *llist_dma;
+	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]);
+
+	if ((first_llist_idx >= UNASSIGNED_INDEX) ||
+	    (last_llist_idx >= UNASSIGNED_INDEX)) {
+		MDDI_MSG_ERR("MDDI queueing invalid linked list\n");
+		return;
+	}
+
+	if (pmhctl->link_state == MDDI_LINK_DISABLED)
+		MDDI_MSG_CRIT("MDDI host powered down!\n");
+
+	llist = pmhctl->llist_ptr;
+	llist_dma = pmhctl->llist_dma_ptr;
+
+	/* clean cache so MDDI host can read data */
+	memory_barrier();
+
+	pmhctl->llist_notify[last_llist_idx].waiting = wait;
+	if (wait)
+		INIT_COMPLETION(pmhctl->llist_notify[last_llist_idx].done_comp);
+	pmhctl->llist_notify[last_llist_idx].done_cb = llist_done_cb;
+
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+
+	if ((pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) &&
+	    (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) &&
+	    (pmhctl->rev_state == MDDI_REV_IDLE)) {
+		/* no packets are currently transmitting */
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+		if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
+			/* This is the special case where the packet is a register read. */
+			pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED;
+			mddi_reg_read_retry = 0;
+			/* mddi_rev_reg_read_attempt = 1; */
+		}
+#endif
+		/* assign transmitting index values */
+		pmhctl->llist_info.transmitting_start_idx = first_llist_idx;
+		pmhctl->llist_info.transmitting_end_idx = last_llist_idx;
+
+		/* turn on clock(s), if they have been disabled */
+		mddi_host_enable_hclk();
+		mddi_host_enable_io_clock();
+		pmhctl->int_type.llist_ptr_write_1++;
+		/* Write to primary pointer register */
+		dma_coherent_pre_ops();
+		mddi_host_reg_out(PRI_PTR, &llist_dma[first_llist_idx]);
+
+		/* enable interrupt when complete */
+		mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE,
+				   MDDI_INT_PRI_LINK_LIST_DONE);
+
+	} else if (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) {
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+		if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
+			/*
+			 * we have a register read to send but need to wait
+			 * for current reverse activity to end or there are
+			 * packets currently transmitting
+			 */
+			/* mddi_rev_reg_read_attempt = 0; */
+			pmhctl->llist_info.reg_read_waiting = TRUE;
+		}
+#endif
+
+		/* assign waiting index values */
+		pmhctl->llist_info.waiting_start_idx = first_llist_idx;
+		pmhctl->llist_info.waiting_end_idx = last_llist_idx;
+	} else {
+		uint16 prev_end_idx = pmhctl->llist_info.waiting_end_idx;
+#ifndef FEATURE_MDDI_DISABLE_REVERSE
+		if (first_llist_idx == pmhctl->llist_info.reg_read_idx) {
+			/*
+			 * we have a register read to send but need to wait
+			 * for current reverse activity to end or there are
+			 * packets currently transmitting
+			 */
+			/* mddi_rev_reg_read_attempt = 0; */
+			pmhctl->llist_info.reg_read_waiting = TRUE;
+		}
+#endif
+
+		llist = pmhctl->llist_ptr;
+
+		/* clear end flag in previous last packet */
+		llist[prev_end_idx].link_controller_flags = 0;
+		pmhctl->llist_notify[prev_end_idx].next_idx = first_llist_idx;
+
+		/* set the next_packet_pointer of the previous last packet */
+		llist[prev_end_idx].next_packet_pointer =
+		    (void *)(&llist_dma[first_llist_idx]);
+
+		/* clean cache so MDDI host can read data */
+		memory_barrier();
+
+		/* assign new waiting last index value */
+		pmhctl->llist_info.waiting_end_idx = last_llist_idx;
+	}
+
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+
+}
+
+void mddi_host_write_pix_attr_reg(uint32 value)
+{
+	(void)value;
+}
+
+void mddi_queue_reverse_encapsulation(boolean wait)
+{
+#ifdef FEATURE_MDDI_DISABLE_REVERSE
+	MDDI_MSG_CRIT("No reverse link available\n");
+	(void)wait;
+#else
+	unsigned long flags;
+	boolean error = FALSE;
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+	mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
+
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+
+	/* turn on clock(s), if they have been disabled */
+	mddi_host_enable_hclk();
+	mddi_host_enable_io_clock();
+
+	if (wait) {
+		if (!mddi_rev_user.waiting) {
+			mddi_rev_user.waiting = TRUE;
+			INIT_COMPLETION(mddi_rev_user.done_comp);
+		} else
+			error = TRUE;
+	}
+	mddi_rev_encap_user_request = TRUE;
+
+	if (pmhctl->rev_state == MDDI_REV_IDLE) {
+		/* attempt to send the reverse encapsulation now */
+		mddi_host_type orig_host_idx = mddi_curr_host;
+		mddi_curr_host = host_idx;
+		mddi_issue_reverse_encapsulation();
+		mddi_curr_host = orig_host_idx;
+	}
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+
+	if (error) {
+		MDDI_MSG_ERR("Reverse Encap request already in progress\n");
+	} else if (wait)
+		wait_for_completion_killable(&(mddi_rev_user.done_comp));
+#endif
+}
+
+/* ISR to be executed */
+boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type)
+{
+#ifdef FEATURE_MDDI_DISABLE_REVERSE
+	MDDI_MSG_CRIT("No reverse link available\n");
+	(void)handler;
+	(void)pkt_type;
+	return (FALSE);
+#else
+	unsigned long flags;
+	uint16 hdlr;
+	boolean handler_set = FALSE;
+	boolean overwrite = FALSE;
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+	mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
+
+	/* Disable interrupts */
+	spin_lock_irqsave(&mddi_host_spin_lock, flags);
+
+	for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) {
+		if (mddi_rev_pkt_handler[hdlr].pkt_type == pkt_type) {
+			mddi_rev_pkt_handler[hdlr].handler = handler;
+			if (handler == NULL) {
+				/* clearing handler from table */
+				mddi_rev_pkt_handler[hdlr].pkt_type =
+				    INVALID_PKT_TYPE;
+				handler_set = TRUE;
+				if (pkt_type == 0x10) {	/* video stream packet */
+					/* ensure HCLK on to MDDI host core before register write */
+					mddi_host_enable_hclk();
+					/* No longer getting video, so reset rev encap size to default */
+					pmhctl->rev_pkt_size =
+					    MDDI_DEFAULT_REV_PKT_SIZE;
+					mddi_host_reg_out(REV_ENCAP_SZ,
+							  pmhctl->rev_pkt_size);
+				}
+			} else {
+				/* already a handler for this packet */
+				overwrite = TRUE;
+			}
+			break;
+		}
+	}
+	if ((hdlr >= MAX_MDDI_REV_HANDLERS) && (handler != NULL)) {
+		/* assigning new handler */
+		for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) {
+			if (mddi_rev_pkt_handler[hdlr].pkt_type ==
+			    INVALID_PKT_TYPE) {
+				if ((pkt_type == 0x10) &&	/* video stream packet */
+				    (pmhctl->rev_pkt_size <
+				     MDDI_VIDEO_REV_PKT_SIZE)) {
+					/* ensure HCLK on to MDDI host core before register write */
+					mddi_host_enable_hclk();
+					/* Increase Rev Encap Size */
+					pmhctl->rev_pkt_size =
+					    MDDI_VIDEO_REV_PKT_SIZE;
+					mddi_host_reg_out(REV_ENCAP_SZ,
+							  pmhctl->rev_pkt_size);
+				}
+				mddi_rev_pkt_handler[hdlr].handler = handler;
+				mddi_rev_pkt_handler[hdlr].pkt_type = pkt_type;
+				handler_set = TRUE;
+				break;
+			}
+		}
+	}
+
+	/* Restore interrupts */
+	spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+
+	if (overwrite)
+		MDDI_MSG_ERR("Overwriting previous rev packet handler\n");
+
+	return handler_set;
+
+#endif
+}				/* mddi_set_rev_handler */
+
+void mddi_host_disable_hibernation(boolean disable)
+{
+	mddi_host_type host_idx = MDDI_HOST_PRIM;
+	mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]);
+
+	if (disable) {
+		pmhctl->disable_hibernation = TRUE;
+		/* hibernation will be turned off by isr next time it is entered */
+	} else {
+		if (pmhctl->disable_hibernation) {
+			unsigned long flags;
+			spin_lock_irqsave(&mddi_host_spin_lock, flags);
+			if (!MDDI_HOST_IS_HCLK_ON)
+				MDDI_HOST_ENABLE_HCLK;
+			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
+			spin_unlock_irqrestore(&mddi_host_spin_lock, flags);
+			pmhctl->disable_hibernation = FALSE;
+		}
+	}
+}
+
+void mddi_mhctl_remove(mddi_host_type host_idx)
+{
+	mddi_host_cntl_type *pmhctl;
+
+	pmhctl = &(mhctl[host_idx]);
+
+	dma_free_coherent(NULL, MDDI_LLIST_POOL_SIZE, (void *)pmhctl->llist_ptr,
+			  pmhctl->llist_dma_addr);
+
+	dma_free_coherent(NULL, MDDI_MAX_REV_DATA_SIZE,
+			  (void *)pmhctl->rev_data_buf,
+			  pmhctl->rev_data_dma_addr);
+}
diff --git a/drivers/video/msm/mddihosti.h b/drivers/video/msm/mddihosti.h
new file mode 100644
index 0000000..166d15c
--- /dev/null
+++ b/drivers/video/msm/mddihosti.h
@@ -0,0 +1,552 @@
+/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MDDIHOSTI_H
+#define MDDIHOSTI_H
+
+#include "msm_fb.h"
+#include "mddihost.h"
+#include <linux/clk.h>
+
+/* Register offsets in MDDI, applies to both msm_pmdh_base and
+ * (u32)msm_emdh_base. */
+#define MDDI_CMD   		0x0000
+#define MDDI_VERSION   		0x0004
+#define MDDI_PRI_PTR		0x0008
+#define MDDI_BPS		0x0010
+#define MDDI_SPM		0x0014
+#define MDDI_INT		0x0018
+#define MDDI_INTEN		0x001c
+#define MDDI_REV_PTR		0x0020
+#define MDDI_REV_SIZE		0x0024
+#define MDDI_STAT		0x0028
+#define MDDI_REV_RATE_DIV	0x002c
+#define MDDI_REV_CRC_ERR	0x0030
+#define MDDI_TA1_LEN		0x0034
+#define MDDI_TA2_LEN		0x0038
+#define MDDI_TEST		0x0040
+#define MDDI_REV_PKT_CNT	0x0044
+#define MDDI_DRIVE_HI		0x0048
+#define MDDI_DRIVE_LO		0x004c
+#define MDDI_DISP_WAKE		0x0050
+#define MDDI_REV_ENCAP_SZ	0x0054
+#define MDDI_RTD_VAL		0x0058
+#define MDDI_PAD_CTL		0x0068
+#define MDDI_DRIVER_START_CNT	0x006c
+#define MDDI_CORE_VER		0x008c
+#define MDDI_FIFO_ALLOC         0x0090
+#define MDDI_PAD_IO_CTL         0x00a0
+#define MDDI_PAD_CAL            0x00a4
+
+#ifdef ENABLE_MDDI_MULTI_READ_WRITE
+#define MDDI_HOST_MAX_CLIENT_REG_IN_SAME_ADDR 128
+#else
+#define MDDI_HOST_MAX_CLIENT_REG_IN_SAME_ADDR 1
+#endif
+
+extern int32 mddi_client_type;
+extern u32 mddi_msg_level;
+
+/* No longer need to write to clear these registers */
+#define xxxx_mddi_host_reg_outm(reg, mask, val)  \
+do { \
+	if (host_idx == MDDI_HOST_PRIM) \
+		mddi_host_reg_outm_pmdh(reg, mask, val); \
+	else \
+		mddi_host_reg_outm_emdh(reg, mask, val); \
+} while (0)
+
+#define mddi_host_reg_outm(reg, mask, val) \
+do { \
+	unsigned long __addr; \
+	if (host_idx == MDDI_HOST_PRIM) \
+		__addr = (u32)msm_pmdh_base + MDDI_##reg; \
+	else \
+		__addr = (u32)msm_emdh_base + MDDI_##reg; \
+	writel((readl(__addr) & ~(mask)) | ((val) & (mask)), __addr); \
+} while (0)
+
+#define xxxx_mddi_host_reg_out(reg, val) \
+do { \
+	if (host_idx == MDDI_HOST_PRIM)  \
+		mddi_host_reg_out_pmdh(reg, val); \
+	else \
+		mddi_host_reg_out_emdh(reg, val); \
+	} while (0)
+
+#define mddi_host_reg_out(reg, val) \
+do { \
+	if (host_idx == MDDI_HOST_PRIM) \
+		writel(val, (u32)msm_pmdh_base + MDDI_##reg); \
+	else \
+		writel(val, (u32)msm_emdh_base + MDDI_##reg); \
+} while (0)
+
+#define xxxx_mddi_host_reg_in(reg)  \
+  ((host_idx) ? \
+     mddi_host_reg_in_emdh(reg) : mddi_host_reg_in_pmdh(reg));
+
+#define mddi_host_reg_in(reg) \
+((host_idx) ? \
+	readl((u32)msm_emdh_base + MDDI_##reg) : \
+	readl((u32)msm_pmdh_base + MDDI_##reg)) \
+
+#define xxxx_mddi_host_reg_inm(reg, mask)  \
+  ((host_idx) ? \
+    mddi_host_reg_inm_emdh(reg, mask) : \
+    mddi_host_reg_inm_pmdh(reg, mask);)
+
+#define mddi_host_reg_inm(reg, mask) \
+((host_idx) ? \
+	readl((u32)msm_emdh_base + MDDI_##reg) & (mask) : \
+	readl((u32)msm_pmdh_base + MDDI_##reg) & (mask)) \
+
+/* Using non-cacheable pmem, so do nothing */
+#define mddi_invalidate_cache_lines(addr_start, num_bytes)
+/*
+ * Using non-cacheable pmem, so do nothing with cache
+ * but, ensure write goes out to memory
+ */
+#define mddi_flush_cache_lines(addr_start, num_bytes)  \
+    (void) addr_start; \
+    (void) num_bytes;  \
+    memory_barrier()
+
+/* Since this translates to Remote Procedure Calls to check on clock status
+* just use a local variable to keep track of io_clock */
+#define MDDI_HOST_IS_IO_CLOCK_ON mddi_host_io_clock_on
+#define MDDI_HOST_ENABLE_IO_CLOCK
+#define MDDI_HOST_DISABLE_IO_CLOCK
+#define MDDI_HOST_IS_HCLK_ON mddi_host_hclk_on
+#define MDDI_HOST_ENABLE_HCLK
+#define MDDI_HOST_DISABLE_HCLK
+#define FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE
+#define FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE
+
+#define TRAMP_MDDI_HOST_ISR TRAMP_MDDI_PRI_ISR
+#define TRAMP_MDDI_HOST_EXT_ISR TRAMP_MDDI_EXT_ISR
+#define MDP_LINE_COUNT_BMSK  0x3ff
+#define MDP_SYNC_STATUS  0x000c
+#define MDP_LINE_COUNT      \
+(readl(msm_mdp_base + MDP_SYNC_STATUS) & MDP_LINE_COUNT_BMSK)
+
+/* MDP sends 256 pixel packets, so lower value hibernates more without
+* significantly increasing latency of waiting for next subframe */
+#define MDDI_HOST_BYTES_PER_SUBFRAME  0x3C00
+
+#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40)
+#define MDDI_HOST_TA2_LEN       0x001a
+#define MDDI_HOST_REV_RATE_DIV  0x0004
+#else
+#define MDDI_HOST_TA2_LEN       0x000c
+#define MDDI_HOST_REV_RATE_DIV  0x0002
+#endif
+
+#define MDDI_MSG_EMERG(msg, ...)    \
+	if (mddi_msg_level > 0)  \
+		printk(KERN_EMERG msg, ## __VA_ARGS__);
+#define MDDI_MSG_ALERT(msg, ...)    \
+	if (mddi_msg_level > 1)  \
+		printk(KERN_ALERT msg, ## __VA_ARGS__);
+#define MDDI_MSG_CRIT(msg, ...)    \
+	if (mddi_msg_level > 2)  \
+		printk(KERN_CRIT msg, ## __VA_ARGS__);
+#define MDDI_MSG_ERR(msg, ...)    \
+	if (mddi_msg_level > 3)  \
+		printk(KERN_ERR msg, ## __VA_ARGS__);
+#define MDDI_MSG_WARNING(msg, ...)    \
+	if (mddi_msg_level > 4)  \
+		printk(KERN_WARNING msg, ## __VA_ARGS__);
+#define MDDI_MSG_NOTICE(msg, ...)    \
+	if (mddi_msg_level > 5)  \
+		printk(KERN_NOTICE msg, ## __VA_ARGS__);
+#define MDDI_MSG_INFO(msg, ...)    \
+	if (mddi_msg_level > 6)  \
+		printk(KERN_INFO msg, ## __VA_ARGS__);
+#define MDDI_MSG_DEBUG(msg, ...)    \
+	if (mddi_msg_level > 7)  \
+		printk(KERN_DEBUG msg, ## __VA_ARGS__);
+
+#define GCC_PACKED __attribute__((packed))
+typedef struct GCC_PACKED {
+	uint16 packet_length;
+	/* total # of bytes in the packet not including
+		the packet_length field. */
+
+	uint16 packet_type;
+	/* A Packet Type of 70 identifies the packet as
+		a Client status Packet. */
+
+	uint16 bClient_ID;
+	/* This field is reserved for future use and shall
+		be set to zero. */
+
+} mddi_rev_packet_type;
+
+typedef struct GCC_PACKED {
+	uint16 packet_length;
+	/* total # of bytes in the packet not including
+		the packet_length field. */
+
+	uint16 packet_type;
+	/* A Packet Type of 70 identifies the packet as
+		a Client status Packet. */
+
+	uint16 bClient_ID;
+	/* This field is reserved for future use and shall
+		be set to zero. */
+
+	uint16 reverse_link_request;
+	/* 16 bit unsigned integer with number of bytes client
+		needs in the * reverse encapsulation message
+		to transmit data. */
+
+	uint8 crc_error_count;
+	uint8 capability_change;
+	uint16 graphics_busy_flags;
+
+	uint16 parameter_CRC;
+	/* 16-bit CRC of all the bytes in the packet
+		including Packet Length. */
+
+} mddi_client_status_type;
+
+typedef struct GCC_PACKED {
+	uint16 packet_length;
+	/* total # of bytes in the packet not including
+		the packet_length field. */
+
+	uint16 packet_type;
+	/* A Packet Type of 66 identifies the packet as
+		a Client Capability Packet. */
+
+	uint16 bClient_ID;
+	/* This field is reserved for future use and
+		shall be set to zero. */
+
+	uint16 Protocol_Version;
+	uint16 Minimum_Protocol_Version;
+	uint16 Data_Rate_Capability;
+	uint8 Interface_Type_Capability;
+	uint8 Number_of_Alt_Displays;
+	uint16 PostCal_Data_Rate;
+	uint16 Bitmap_Width;
+	uint16 Bitmap_Height;
+	uint16 Display_Window_Width;
+	uint16 Display_Window_Height;
+	uint32 Color_Map_Size;
+	uint16 Color_Map_RGB_Width;
+	uint16 RGB_Capability;
+	uint8 Monochrome_Capability;
+	uint8 Reserved_1;
+	uint16 Y_Cb_Cr_Capability;
+	uint16 Bayer_Capability;
+	uint16 Alpha_Cursor_Image_Planes;
+	uint32 Client_Feature_Capability_Indicators;
+	uint8 Maximum_Video_Frame_Rate_Capability;
+	uint8 Minimum_Video_Frame_Rate_Capability;
+	uint16 Minimum_Sub_frame_Rate;
+	uint16 Audio_Buffer_Depth;
+	uint16 Audio_Channel_Capability;
+	uint16 Audio_Sample_Rate_Capability;
+	uint8 Audio_Sample_Resolution;
+	uint8 Mic_Audio_Sample_Resolution;
+	uint16 Mic_Sample_Rate_Capability;
+	uint8 Keyboard_Data_Format;
+	uint8 pointing_device_data_format;
+	uint16 content_protection_type;
+	uint16 Mfr_Name;
+	uint16 Product_Code;
+	uint16 Reserved_3;
+	uint32 Serial_Number;
+	uint8 Week_of_Manufacture;
+	uint8 Year_of_Manufacture;
+
+	uint16 parameter_CRC;
+	/* 16-bit CRC of all the bytes in the packet including Packet Length. */
+
+} mddi_client_capability_type;
+
+typedef struct GCC_PACKED {
+	uint16 packet_length;
+	/* total # of bytes in the packet not including the packet_length field. */
+
+	uint16 packet_type;
+	/* A Packet Type of 16 identifies the packet as a Video Stream Packet. */
+
+	uint16 bClient_ID;
+	/* This field is reserved for future use and shall be set to zero. */
+
+	uint16 video_data_format_descriptor;
+	/* format of each pixel in the Pixel Data in the present stream in the
+	 * present packet.
+	 * If bits [15:13] = 000 monochrome
+	 * If bits [15:13] = 001 color pixels (palette).
+	 * If bits [15:13] = 010 color pixels in raw RGB
+	 * If bits [15:13] = 011 data in 4:2:2 Y Cb Cr format
+	 * If bits [15:13] = 100 Bayer pixels
+	 */
+
+	uint16 pixel_data_attributes;
+	/* interpreted as follows:
+	 * Bits [1:0] = 11  pixel data is displayed to both eyes
+	 * Bits [1:0] = 10  pixel data is routed to the left eye only.
+	 * Bits [1:0] = 01  pixel data is routed to the right eye only.
+	 * Bits [1:0] = 00  pixel data is routed to the alternate display.
+	 * Bit 2 is 0  Pixel Data is in the standard progressive format.
+	 * Bit 2 is 1  Pixel Data is in interlace format.
+	 * Bit 3 is 0  Pixel Data is in the standard progressive format.
+	 * Bit 3 is 1  Pixel Data is in alternate pixel format.
+	 * Bit 4 is 0  Pixel Data is to or from the display frame buffer.
+	 * Bit 4 is 1  Pixel Data is to or from the camera.
+	 * Bit 5 is 0  pixel data contains the next consecutive row of pixels.
+	 * Bit 5 is 1  X Left Edge, Y Top Edge, X Right Edge, Y Bottom Edge,
+	 *             X Start, and Y Start parameters are not defined and
+	 *             shall be ignored by the client.
+	 * Bits [7:6] = 01  Pixel data is written to the offline image buffer.
+	 * Bits [7:6] = 00  Pixel data is written to the buffer to refresh display.
+	 * Bits [7:6] = 11  Pixel data is written to all image buffers.
+	 * Bits [7:6] = 10  Invalid. Reserved for future use.
+	 * Bits 8 through 11 alternate display number.
+	 * Bits 12 through 14 are reserved for future use and shall be set to zero.
+	 * Bit 15 is 1 the row of pixels is the last row of pixels in a frame.
+	 */
+
+	uint16 x_left_edge;
+	uint16 y_top_edge;
+	/* X,Y coordinate of the top left edge of the screen window */
+
+	uint16 x_right_edge;
+	uint16 y_bottom_edge;
+	/*  X,Y coordinate of the bottom right edge of the window being updated. */
+
+	uint16 x_start;
+	uint16 y_start;
+	/*  (X Start, Y Start) is the first pixel in the Pixel Data field below. */
+
+	uint16 pixel_count;
+	/*  number of pixels in the Pixel Data field below. */
+
+	uint16 parameter_CRC;
+	/*  16-bit CRC of all bytes from the Packet Length to the Pixel Count. */
+
+	uint16 reserved;
+	/* 16-bit variable to make structure align on 4 byte boundary */
+
+} mddi_video_stream_packet_type;
+
+typedef struct GCC_PACKED {
+	uint16 packet_length;
+	/* total # of bytes in the packet not including the packet_length field. */
+
+	uint16 packet_type;
+	/* A Packet Type of 146 identifies the packet as a Register Access Packet. */
+
+	uint16 bClient_ID;
+	/* This field is reserved for future use and shall be set to zero. */
+
+	uint16 read_write_info;
+	/* Bits 13:0  a 14-bit unsigned integer that specifies the number of
+	 *            32-bit Register Data List items to be transferred in the
+	 *            Register Data List field.
+	 * Bits[15:14] = 00  Write to register(s);
+	 * Bits[15:14] = 10  Read from register(s);
+	 * Bits[15:14] = 11  Response to a Read.
+	 * Bits[15:14] = 01  this value is reserved for future use. */
+
+	uint32 register_address;
+	/* the register address that is to be written to or read from. */
+
+	uint16 parameter_CRC;
+	/* 16-bit CRC of all bytes from the Packet Length to the Register Address. */
+
+	uint32 register_data_list[MDDI_HOST_MAX_CLIENT_REG_IN_SAME_ADDR];
+	/* list of 4-byte register data values for/from client registers */
+	/* For multi-read/write, 512(128 * 4) bytes of data available */
+
+} mddi_register_access_packet_type;
+
+typedef union GCC_PACKED {
+	mddi_video_stream_packet_type video_pkt;
+	mddi_register_access_packet_type register_pkt;
+#ifdef ENABLE_MDDI_MULTI_READ_WRITE
+	/* add 1008 byte pad to ensure 1024 byte llist struct, that can be
+	 * manipulated easily with cache */
+	uint32 alignment_pad[252];	/* 1008 bytes */
+#else
+	/* add 48 byte pad to ensure 64 byte llist struct, that can be
+	 * manipulated easily with cache */
+	uint32 alignment_pad[12];	/* 48 bytes */
+#endif
+} mddi_packet_header_type;
+
+typedef struct GCC_PACKED mddi_host_llist_struct {
+	uint16 link_controller_flags;
+	uint16 packet_header_count;
+	uint16 packet_data_count;
+	void *packet_data_pointer;
+	struct mddi_host_llist_struct *next_packet_pointer;
+	uint16 reserved;
+	mddi_packet_header_type packet_header;
+} mddi_linked_list_type;
+
+typedef struct {
+	struct completion done_comp;
+	mddi_llist_done_cb_type done_cb;
+	uint16 next_idx;
+	boolean waiting;
+	boolean in_use;
+} mddi_linked_list_notify_type;
+
+#ifdef ENABLE_MDDI_MULTI_READ_WRITE
+#define MDDI_LLIST_POOL_SIZE 0x10000
+#else
+#define MDDI_LLIST_POOL_SIZE 0x1000
+#endif
+#define MDDI_MAX_NUM_LLIST_ITEMS (MDDI_LLIST_POOL_SIZE / \
+		 sizeof(mddi_linked_list_type))
+#define UNASSIGNED_INDEX MDDI_MAX_NUM_LLIST_ITEMS
+#define MDDI_FIRST_DYNAMIC_LLIST_IDX 0
+
+/* Static llist items can be used for applications that frequently send
+ * the same set of packets using the linked list interface. */
+/* Here we configure for 6 static linked list items:
+ *  The 1st is used for a the adaptive backlight setting.
+ *  and the remaining 5 are used for sending window adjustments for
+ *  MDDI clients that need windowing info sent separate from video
+ *  packets. */
+#define MDDI_NUM_STATIC_ABL_ITEMS 1
+#define MDDI_NUM_STATIC_WINDOW_ITEMS 5
+#define MDDI_NUM_STATIC_LLIST_ITEMS (MDDI_NUM_STATIC_ABL_ITEMS + \
+				MDDI_NUM_STATIC_WINDOW_ITEMS)
+#define MDDI_NUM_DYNAMIC_LLIST_ITEMS (MDDI_MAX_NUM_LLIST_ITEMS - \
+				MDDI_NUM_STATIC_LLIST_ITEMS)
+
+#define MDDI_FIRST_STATIC_LLIST_IDX  MDDI_NUM_DYNAMIC_LLIST_ITEMS
+#define MDDI_FIRST_STATIC_ABL_IDX  MDDI_FIRST_STATIC_LLIST_IDX
+#define MDDI_FIRST_STATIC_WINDOW_IDX  (MDDI_FIRST_STATIC_LLIST_IDX + \
+				MDDI_NUM_STATIC_ABL_ITEMS)
+
+/* GPIO registers */
+#define VSYNC_WAKEUP_REG          0x80
+#define GPIO_REG                  0x81
+#define GPIO_OUTPUT_REG           0x82
+#define GPIO_INTERRUPT_REG        0x83
+#define GPIO_INTERRUPT_ENABLE_REG 0x84
+#define GPIO_POLARITY_REG         0x85
+
+/* Interrupt Bits */
+#define MDDI_INT_PRI_PTR_READ       0x0001
+#define MDDI_INT_SEC_PTR_READ       0x0002
+#define MDDI_INT_REV_DATA_AVAIL     0x0004
+#define MDDI_INT_DISP_REQ           0x0008
+#define MDDI_INT_PRI_UNDERFLOW      0x0010
+#define MDDI_INT_SEC_UNDERFLOW      0x0020
+#define MDDI_INT_REV_OVERFLOW       0x0040
+#define MDDI_INT_CRC_ERROR          0x0080
+#define MDDI_INT_MDDI_IN            0x0100
+#define MDDI_INT_PRI_OVERWRITE      0x0200
+#define MDDI_INT_SEC_OVERWRITE      0x0400
+#define MDDI_INT_REV_OVERWRITE      0x0800
+#define MDDI_INT_DMA_FAILURE        0x1000
+#define MDDI_INT_LINK_ACTIVE        0x2000
+#define MDDI_INT_IN_HIBERNATION     0x4000
+#define MDDI_INT_PRI_LINK_LIST_DONE 0x8000
+#define MDDI_INT_SEC_LINK_LIST_DONE 0x10000
+#define MDDI_INT_NO_CMD_PKTS_PEND   0x20000
+#define MDDI_INT_RTD_FAILURE        0x40000
+
+#define MDDI_INT_ERROR_CONDITIONS ( \
+	MDDI_INT_PRI_UNDERFLOW | MDDI_INT_SEC_UNDERFLOW | \
+	MDDI_INT_REV_OVERFLOW | MDDI_INT_CRC_ERROR | \
+	MDDI_INT_PRI_OVERWRITE | MDDI_INT_SEC_OVERWRITE | \
+	MDDI_INT_RTD_FAILURE | \
+	MDDI_INT_REV_OVERWRITE | MDDI_INT_DMA_FAILURE)
+
+#define MDDI_INT_LINK_STATE_CHANGES ( \
+	MDDI_INT_LINK_ACTIVE | MDDI_INT_IN_HIBERNATION)
+
+/* Status Bits */
+#define MDDI_STAT_LINK_ACTIVE        0x0001
+#define MDDI_STAT_NEW_REV_PTR        0x0002
+#define MDDI_STAT_NEW_PRI_PTR        0x0004
+#define MDDI_STAT_NEW_SEC_PTR        0x0008
+#define MDDI_STAT_IN_HIBERNATION     0x0010
+#define MDDI_STAT_PRI_LINK_LIST_DONE 0x0020
+#define MDDI_STAT_SEC_LINK_LIST_DONE 0x0040
+#define MDDI_STAT_PENDING_TIMING_PKT 0x0080
+#define MDDI_STAT_PENDING_REV_ENCAP  0x0100
+#define MDDI_STAT_PENDING_POWERDOWN  0x0200
+#define MDDI_STAT_RTD_MEAS_FAIL      0x0800
+#define MDDI_STAT_CLIENT_WAKEUP_REQ  0x1000
+
+/* Command Bits */
+#define MDDI_CMD_POWERDOWN           0x0100
+#define MDDI_CMD_POWERUP             0x0200
+#define MDDI_CMD_HIBERNATE           0x0300
+#define MDDI_CMD_RESET               0x0400
+#define MDDI_CMD_DISP_IGNORE         0x0501
+#define MDDI_CMD_DISP_LISTEN         0x0500
+#define MDDI_CMD_SEND_REV_ENCAP      0x0600
+#define MDDI_CMD_GET_CLIENT_CAP      0x0601
+#define MDDI_CMD_GET_CLIENT_STATUS   0x0602
+#define MDDI_CMD_SEND_RTD            0x0700
+#define MDDI_CMD_LINK_ACTIVE         0x0900
+#define MDDI_CMD_PERIODIC_REV_ENCAP  0x0A00
+#define MDDI_CMD_FW_LINK_SKEW_CAL    0x0D00
+
+extern void mddi_host_init(mddi_host_type host);
+extern void mddi_host_powerdown(mddi_host_type host);
+extern uint16 mddi_get_next_free_llist_item(mddi_host_type host, boolean wait);
+extern uint16 mddi_get_reg_read_llist_item(mddi_host_type host, boolean wait);
+extern void mddi_queue_forward_packets(uint16 first_llist_idx,
+				       uint16 last_llist_idx,
+				       boolean wait,
+				       mddi_llist_done_cb_type llist_done_cb,
+				       mddi_host_type host);
+
+extern void mddi_host_write_pix_attr_reg(uint32 value);
+extern void mddi_client_lcd_gpio_poll(uint32 poll_reg_val);
+extern void mddi_client_lcd_vsync_detected(boolean detected);
+extern void mddi_host_disable_hibernation(boolean disable);
+
+extern mddi_linked_list_type *llist_extern[];
+extern mddi_linked_list_type *llist_dma_extern[];
+extern mddi_linked_list_notify_type *llist_extern_notify[];
+extern struct timer_list mddi_host_timer;
+
+typedef struct {
+	uint16 transmitting_start_idx;
+	uint16 transmitting_end_idx;
+	uint16 waiting_start_idx;
+	uint16 waiting_end_idx;
+	uint16 reg_read_idx;
+	uint16 next_free_idx;
+	boolean reg_read_waiting;
+} mddi_llist_info_type;
+
+extern mddi_llist_info_type mddi_llist;
+
+#define MDDI_GPIO_DEFAULT_POLLING_INTERVAL 200
+typedef struct {
+	uint32 polling_reg;
+	uint32 polling_val;
+	uint32 polling_interval;
+	boolean polling_enabled;
+} mddi_gpio_info_type;
+
+uint32 mddi_get_client_id(void);
+void mddi_mhctl_remove(mddi_host_type host_idx);
+void mddi_host_timer_service(unsigned long data);
+void mddi_host_client_cnt_reset(void);
+#endif /* MDDIHOSTI_H */
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 39178d3..4125ef0 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -2,7 +2,7 @@
  *
  * MSM MDP Interface (used by framebuffer core)
  *
- * Copyright (C) 2007 QUALCOMM Incorporated
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
  * Copyright (C) 2007 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
@@ -15,1422 +15,2799 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/fb.h>
-#include <linux/msm_mdp.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/hrtimer.h>
 #include <linux/clk.h>
-#include <linux/timer.h>
-#include <linux/file.h>
-#include <linux/android_pmem.h>
-#include <linux/major.h>
-
-#include <mach/msm_iomap.h>
-#include <mach/msm_fb.h>
-#include <linux/platform_device.h>
-
-#include "mdp_hw.h"
-#include "mdp_ppp.h"
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <asm/system.h>
 #include <asm/mach-types.h>
-
-#include <mach/debug_display.h>
-
-struct class *mdp_class;
-
-#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000)
-
-static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue);
-static unsigned int mdp_irq_mask;
-static unsigned int mdp_dma_timer_enable = 0;
-struct clk *mdp_clk_to_disable_later = 0;
-#ifdef CONFIG_MDP4_HW_VSYNC
-struct clk *mdp_vsync_clk_to_disable_later = 0;
-#endif
-static unsigned int mdp_dma_user_requested = 0;
-static struct  mdp_blit_req *timeout_req;
-static uint32_t mdp_reg_addr = 0;
-static uint32_t mdp_reg_val = 0;
-
-#ifdef CONFIG_FB_MSM_OVERLAY
-
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <mach/clk.h>
+#include "mdp.h"
+#include "msm_fb.h"
+#ifdef CONFIG_FB_MSM_MDP40
 #include "mdp4.h"
 #endif
-#ifdef CONFIG_MSM_MDP40
-spinlock_t mdp_spin_lock;
-uint32_t mdp_intr_mask = MDP4_ANY_INTR_MASK;
-#endif
+#include "mipi_dsi.h"
 
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-#define MDP_HIST_MAX_BIN 32
-struct mdp_histogram mdp_hist;
-struct completion mdp_hist_comp;
-bool  mdp_is_hist_start = false;
-static DEFINE_MUTEX(mdp_hist_mutex);
-DEFINE_MUTEX(mdp_lut_push_sem);
-static int mdp_lut_push;
-static int mdp_lut_push_i;
-static unsigned int mdp_hist_r[MDP_HIST_MAX_BIN];
-static unsigned int mdp_hist_g[MDP_HIST_MAX_BIN];
-static unsigned int mdp_hist_b[MDP_HIST_MAX_BIN];
-#endif
+uint32 mdp4_extn_disp;
 
-#if defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)
-extern char *get_fb_addr(void);
-#endif //defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)
+static struct clk *mdp_clk;
+static struct clk *mdp_pclk;
+static struct clk *mdp_lut_clk;
+int mdp_rev;
+u32 mdp_max_clk = 200000000;
 
-static void mdp_do_standby_timer(unsigned long data)
-{
-	struct mdp_info *mdp = (struct mdp_info *) data;
-	if (!mdp_irq_mask) {
-		clk_set_rate(mdp->ebi1_clk, 0);
-		mdp->state |= MDP_STATE_STANDBY;
-	} else {
-		mod_timer(&mdp->standby_timer,
-			jiffies + msecs_to_jiffies(200));
-	}
-}
+static struct platform_device *mdp_init_pdev;
+static struct regulator *footswitch, *hdmi_pll_fs;
+static unsigned int mdp_footswitch_on;
 
-static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
-{
-	BUG_ON(!mask);
+struct completion mdp_ppp_comp;
+struct semaphore mdp_ppp_mutex;
+struct semaphore mdp_pipe_ctrl_mutex;
 
-	/* if the mask bits are already set return an error, this interrupt
-	 * is already enabled */
-	if (mdp_irq_mask & mask) {
-		PR_DISP_ERR("mdp irq already on %x %x\n", mdp_irq_mask, mask);
-		return -1;
-	}
-	/* if the mdp irq is not already enabled enable it */
-	if (!mdp_irq_mask) {
-#ifdef CONFIG_MDP4_HW_VSYNC
-		clk_enable(mdp->vsync_clk);
-#endif
-		clk_enable(mdp->clk);
-		enable_irq(mdp->irq);
-		if (mdp->state & MDP_STATE_STANDBY) {
-#ifdef CONFIG_MSM_MDP40
-			#if defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)
-			static int mdp_in_high_speed = 0;
-			if (get_fb_addr() && !mdp_in_high_speed) {
-				/* In car mode and MDP clock was in low speed, speed up EBI and MDP clock to workaround MDP hang problem */
-				clk_set_rate(mdp->ebi1_clk, 192000000);
-				clk_set_rate(mdp->clk, 192000000);
-				mdp_in_high_speed = 1;
-			} else if (!get_fb_addr() && mdp_in_high_speed) {
-				/* Leave car mode and MDP clock was in high speed, restore original EBI and MDP clock */
-				clk_set_rate(mdp->ebi1_clk, 153000000);
-				clk_set_rate(mdp->clk, 122880000);
-				mdp_in_high_speed = 0;
-			} else {
-				if (mdp_in_high_speed) clk_set_rate(mdp->ebi1_clk, 192000000);
-				else clk_set_rate(mdp->ebi1_clk, 153000000);
-			}
-			#else
-			clk_set_rate(mdp->ebi1_clk, 153000000);
-			#endif //defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)
+unsigned long mdp_timer_duration = (HZ/20);   /* 50 msecond */
+
+boolean mdp_ppp_waiting = FALSE;
+uint32 mdp_tv_underflow_cnt;
+uint32 mdp_lcdc_underflow_cnt;
+
+boolean mdp_current_clk_on = FALSE;
+boolean mdp_is_in_isr = FALSE;
+
+struct vsync vsync_cntrl;
+
+/*
+ * legacy mdp_in_processing is only for DMA2-MDDI
+ * this applies to DMA2 block only
+ */
+uint32 mdp_in_processing = FALSE;
+
+#ifdef CONFIG_FB_MSM_MDP40
+uint32 mdp_intr_mask = MDP4_ANY_INTR_MASK;
 #else
-			clk_set_rate(mdp->ebi1_clk, 128000000);
-#endif
-			mdp->state &= ~MDP_STATE_STANDBY;
-		} else {
-			del_timer_sync(&mdp->standby_timer);
-			barrier();
-		}
-	}
-
-	/* clear out any previous irqs for the requested mask*/
-	mdp_writel(mdp, mask, MDP_INTR_CLEAR);
-
-	/* update the irq mask to reflect the fact that the interrupt is
-	 * enabled */
-	mdp_irq_mask |= mask;
-	mdp_writel(mdp, mdp_irq_mask, MDP_INTR_ENABLE);
-	return 0;
-}
-
-static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
-{
-	unsigned long flags = 0;
-	int ret;
-
-	spin_lock_irqsave(&mdp->lock, flags);
-	ret = locked_enable_mdp_irq(mdp, mask);
-	spin_unlock_irqrestore(&mdp->lock, flags);
-	return ret;
-}
-
-static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
-{
-	/* this interrupt is already disabled! */
-	if (!(mdp_irq_mask & mask)) {
-		PR_DISP_ERR("mdp irq already off %x %x\n",
-		       mdp_irq_mask, mask);
-		return -1;
-	}
-	/* update the irq mask to reflect the fact that the interrupt is
-	 * disabled */
-	mdp_irq_mask &= ~(mask);
-	mdp_writel(mdp, mdp_irq_mask, MDP_INTR_ENABLE);
-
-	/* if no one is waiting on the interrupt, disable it */
-	if (!mdp_irq_mask) {
-		disable_irq_nosync(mdp->irq);
-		if (mdp->clk)
-			clk_disable(mdp->clk);
-#ifdef CONFIG_MDP4_HW_VSYNC
-		if (mdp->vsync_clk)
-			clk_disable(mdp->vsync_clk);
-#endif
-		if (!(mdp->state & MDP_STATE_STANDBY))
-			mod_timer(&mdp->standby_timer,
-				jiffies + msecs_to_jiffies(200));
-	}
-	return 0;
-}
-
-int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
-{
-	unsigned long irq_flags = 0;
-	int ret;
-
-	spin_lock_irqsave(&mdp->lock, irq_flags);
-	ret = locked_disable_mdp_irq(mdp, mask);
-	spin_unlock_irqrestore(&mdp->lock, irq_flags);
-	return ret;
-}
-
-static irqreturn_t mdp_isr(int irq, void *data)
-{
-	uint32_t status;
-	unsigned long irq_flags = 0;
-	struct mdp_info *mdp = data;
-	int i;
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-	uint32_t hist_status;
-	uint32_t hist_enable;
+uint32 mdp_intr_mask = MDP_ANY_INTR_MASK;
 #endif
 
-	spin_lock_irqsave(&mdp->lock, irq_flags);
+MDP_BLOCK_TYPE mdp_debug[MDP_MAX_BLOCK];
 
-	status = mdp_readl(mdp, MDP_INTR_STATUS);
-	mdp_writel(mdp, status, MDP_INTR_CLEAR);
+atomic_t mdp_block_power_cnt[MDP_MAX_BLOCK];
 
-#if 0
-	PR_DISP_INFO("%s: status=%08x (irq_mask=%08x)\n", __func__, status,
-		mdp_irq_mask);
+spinlock_t mdp_spin_lock;
+struct workqueue_struct *mdp_dma_wq;	/*mdp dma wq */
+struct workqueue_struct *mdp_vsync_wq;	/*mdp vsync wq */
+
+struct workqueue_struct *mdp_hist_wq;	/*mdp histogram wq */
+
+static struct workqueue_struct *mdp_pipe_ctrl_wq; /* mdp mdp pipe ctrl wq */
+static struct delayed_work mdp_pipe_ctrl_worker;
+
+static boolean mdp_suspended = FALSE;
+ulong mdp4_display_intf;
+static DEFINE_MUTEX(mdp_suspend_mutex);
+
+#ifdef CONFIG_FB_MSM_MDP40
+struct mdp_dma_data dma2_data;
+struct mdp_dma_data dma_s_data;
+struct mdp_dma_data dma_e_data;
+#else
+static struct mdp_dma_data dma2_data;
+static struct mdp_dma_data dma_s_data;
+#ifndef CONFIG_FB_MSM_MDP303
+static struct mdp_dma_data dma_e_data;
+#endif
 #endif
 
-	if (mdp_dma_timer_enable) {
-		del_timer(&mdp->dma_timer);
-		mdp_dma_timer_enable = 0;
-		PR_DISP_ERR("%s: stop dma timer\n", __func__);
-	}
-
-	status &= mdp_irq_mask;
-#ifdef CONFIG_MSM_MDP40
-	if (mdp->hw_version < MDP4_REVISION_V2_1 &&
-		mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) {
-		if (status && mdp->out_if[MSM_MDDI_PMDH_INTERFACE].dma_cb != NULL)
-			status |= (INTR_OVERLAY0_DONE | MDP_DMA_S_DONE);
-	}
-#endif
-	for (i = 0; i < MSM_MDP_NUM_INTERFACES; ++i) {
-		struct mdp_out_interface *out_if = &mdp->out_if[i];
-		if (status & out_if->dma_mask) {
-			if (out_if->dma_cb) {
-				out_if->dma_cb->func(out_if->dma_cb);
-				out_if->dma_cb = NULL;
-			}
-			wake_up(&out_if->dma_waitqueue);
-		}
-		if (status & out_if->irq_mask) {
-			out_if->irq_cb->func(out_if->irq_cb);
-			out_if->irq_cb = NULL;
-		}
-	}
-
-#ifndef CONFIG_MSM_MDP40
-	mdp_ppp_handle_isr(mdp, status);
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+struct mdp_dma_data dma_wb_data;
 #endif
 
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-	if (status & INTR_DMA_P_HISTOGRAM) {
+static struct mdp_dma_data dma3_data;
 
-		hist_status = mdp_readl(mdp, MDP_DMA_P_HIST_INTR_STATUS);
-		mdp_writel(mdp, hist_status, MDP_DMA_P_HIST_INTR_CLEAR);
-		hist_enable = mdp_readl(mdp, MDP_DMA_P_HIST_INTR_ENABLE);
+extern ktime_t mdp_dma2_last_update_time;
 
-		hist_status &= hist_enable;
+extern uint32 mdp_dma2_update_time_in_usec;
+extern int mdp_lcd_rd_cnt_offset_slow;
+extern int mdp_lcd_rd_cnt_offset_fast;
+extern int mdp_usec_diff_threshold;
 
-		if (hist_status & INTR_HIST_DONE) {
-			if (mdp_hist.r)
-				memcpy(mdp_hist.r, mdp->base + 0x95100,
-						mdp_hist.bin_cnt*4);
-			if (mdp_hist.g)
-				memcpy(mdp_hist.g, mdp->base + 0x95200,
-						mdp_hist.bin_cnt*4);
-			if (mdp_hist.b)
-				memcpy(mdp_hist.b, mdp->base + 0x95300,
-						mdp_hist.bin_cnt*4);
-			complete(&mdp_hist_comp);
+extern int first_pixel_start_x;
+extern int first_pixel_start_y;
 
-			if (mdp_is_hist_start == true) {
-				mdp_writel(mdp, mdp_hist.frame_cnt, 0x95004);
-				mdp_writel(mdp, 1, 0x95000);
-			}
-		}
-		status &= ~(INTR_DMA_P_HISTOGRAM);
-	}
-
-	if (status & INTR_PRIMARY_INTF_UDERRUN) {
-		/* When underun occurs mdp clear the histogram registers
-		* that are set before in hw_init so restore them back so
-		*
-		* that histogram works.*/
-		mdp_writel(mdp, 1, 0x95010);
-		mdp_writel(mdp, INTR_HIST_DONE, 0x9501c);
-		status &= ~(INTR_PRIMARY_INTF_UDERRUN);
-
-		if (mdp_is_hist_start == true) {
-			mdp_writel(mdp, mdp_hist.frame_cnt, 0x95004);
-			mdp_writel(mdp, 1, 0x95000);
-		}
-	}
+#ifdef MSM_FB_ENABLE_DBGFS
+struct dentry *mdp_dir;
 #endif
 
-	if (status)
-		locked_disable_mdp_irq(mdp, status);
+#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
+static int mdp_suspend(struct platform_device *pdev, pm_message_t state);
+#else
+#define mdp_suspend NULL
+#endif
 
-	spin_unlock_irqrestore(&mdp->lock, irq_flags);
-	return IRQ_HANDLED;
-}
+struct timeval mdp_dma2_timeval;
+struct timeval mdp_ppp_timeval;
 
-static void mdp_do_dma_timer(unsigned long data)
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct early_suspend early_suspend;
+#endif
+
+static u32 mdp_irq;
+
+static uint32 mdp_prim_panel_type = NO_PANEL;
+#ifndef CONFIG_FB_MSM_MDP22
+
+struct list_head mdp_hist_lut_list;
+DEFINE_MUTEX(mdp_hist_lut_list_mutex);
+
+uint32_t mdp_block2base(uint32_t block)
 {
-	static int run_times = 0;
-	uint32_t status;
-	struct mdp_info *mdp = (struct mdp_info *) data;
-	unsigned long irq_flags = 0;
-	int i;
-
-	spin_lock_irqsave(&mdp->lock, irq_flags);
-	if (mdp_dma_timer_enable) {
-		status = mdp_readl(mdp, MDP_INTR_STATUS);
-		mdp_writel(mdp, mdp_irq_mask, MDP_INTR_CLEAR);
-
-		PR_DISP_WARN("mdp_do_dma_timer(%d): status=0x%x mdp_irq_mask=0x%x\n", run_times++, status, mdp_irq_mask);
-		for (i = 0; i < MSM_MDP_NUM_INTERFACES; ++i) {
-			struct mdp_out_interface *out_if = &mdp->out_if[i];
-			if (mdp_irq_mask & out_if->dma_mask) {
-				if (out_if->dma_cb) {
-					out_if->dma_cb->func(out_if->dma_cb);
-					out_if->dma_cb = NULL;
-				}
-				wake_up(&out_if->dma_waitqueue);
-			}
-			if (mdp_irq_mask & out_if->irq_mask) {
-				out_if->irq_cb->func(out_if->irq_cb);
-				out_if->irq_cb = NULL;
-			}
-		}
-
-		#ifndef	CONFIG_MSM_MDP40
-		if (mdp_irq_mask & DL0_ROI_DONE)
-			mdp_ppp_handle_isr(mdp, DL0_ROI_DONE);
-		#endif
-
-		if (run_times >= 10) {
-			/*  Make sure the HW in correct state... */
-			clk_enable(mdp->clk);
-			enable_irq(mdp->irq);
-
-			#ifdef CONFIG_MSM_MDP40
-			clk_set_rate(mdp->ebi1_clk, 192000000);
-			clk_set_rate(mdp->clk, 192000000);
-			#else
-			clk_set_rate(mdp->ebi1_clk, 128000000);
-			#endif
-			mdp->state &= ~MDP_STATE_STANDBY;
-
-			del_timer_sync(&mdp->standby_timer);
-			barrier();
-
-			/* clear out any previous irqs for the requested mask*/
-			mdp_writel(mdp, status, MDP_INTR_CLEAR);
-
-			/* update the irq mask to reflect the fact that the interrupt is
-			 * enabled */
-			mdp_writel(mdp, mdp_irq_mask, MDP_INTR_ENABLE);
-
-			/* Reset the counter */
-			run_times = 0;
-		}
-	}
-	spin_unlock_irqrestore(&mdp->lock, irq_flags);
-
-}
-
-static uint32_t mdp_check_mask(struct mdp_info *mdp, uint32_t mask)
-{
-	uint32_t ret;
-	unsigned long irq_flags = 0;
-
-	spin_lock_irqsave(&mdp->lock, irq_flags);
-	ret = mdp_irq_mask & mask;
-	spin_unlock_irqrestore(&mdp->lock, irq_flags);
-	return ret;
-}
-
-void mdp_dump_blit(struct mdp_blit_req *req)
-{
-	PR_DISP_INFO("%s: src: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__,
-		req->src.width, req->src.height, req->src.format,
-		req->src.offset, req->src.memory_id);
-	PR_DISP_INFO("%s: dst: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__,
-		req->dst.width, req->dst.height, req->dst.format,
-		req->dst.offset, req->dst.memory_id);
-	PR_DISP_INFO("%s: src_rect: x=%d y=%d w=%d h=%d\n", __func__,
-		req->src_rect.x, req->src_rect.y, req->src_rect.w,
-		req->src_rect.h);
-	PR_DISP_INFO("%s: dst_rect: x=%d y=%d w=%d h=%d\n", __func__,
-		req->dst_rect.x, req->dst_rect.y, req->dst_rect.w,
-		req->dst_rect.h);
-	PR_DISP_INFO("%s: alpha=0x%08x\n", __func__, req->alpha);
-	PR_DISP_INFO("%s: transp_max=0x%08x\n", __func__, req->transp_mask);
-	PR_DISP_INFO("%s: flags=%08x\n", __func__, req->flags);
-}
-
-int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq)
-{
-	int ret = 0;
-	unsigned long irq_flags = 0;
-
-	wait_event_timeout(*wq, !mdp_check_mask(mdp, mask), HZ);
-
-	spin_lock_irqsave(&mdp->lock, irq_flags);
-	if (mdp_irq_mask & mask) {
-		locked_disable_mdp_irq(mdp, mask);
-		PR_DISP_WARN("%s: timeout waiting for mdp to complete 0x%x\n",
-			   __func__, mask);
-	if (timeout_req)
-		mdp_dump_blit(timeout_req);
-
-		ret = -ETIMEDOUT;
-	}
-	spin_unlock_irqrestore(&mdp->lock, irq_flags);
-
-	return ret;
-}
-
-static void mdp_dma_wait(struct mdp_device *mdp_dev, int interface)
-{
-#define MDP_MAX_TIMEOUTS 20
-	static int timeout_count;
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	unsigned int mask = 0;
-	wait_queue_head_t *wq;
-
-	switch (interface) {
-	case MSM_MDDI_PMDH_INTERFACE:
-	case MSM_MDDI_EMDH_INTERFACE:
-	case MSM_LCDC_INTERFACE:
-	case MSM_TV_INTERFACE:
-		mask = mdp->out_if[interface].dma_mask;
-		wq = &mdp->out_if[interface].dma_waitqueue;
+	uint32_t base = 0x0;
+	switch (block) {
+	case MDP_BLOCK_DMA_P:
+		base = 0x90000;
+		break;
+	case MDP_BLOCK_DMA_S:
+		base = 0xA0000;
+		break;
+	case MDP_BLOCK_VG_1:
+		base = 0x20000;
+		break;
+	case MDP_BLOCK_VG_2:
+		base = 0x30000;
+		break;
+	case MDP_BLOCK_RGB_1:
+		base = 0x40000;
+		break;
+	case MDP_BLOCK_RGB_2:
+		base = 0x50000;
+		break;
+	case MDP_BLOCK_OVERLAY_0:
+		base = 0x10000;
+		break;
+	case MDP_BLOCK_OVERLAY_1:
+		base = 0x18000;
+		break;
+	case MDP_BLOCK_OVERLAY_2:
+		base = (mdp_rev >= MDP_REV_44) ? 0x88000 : 0;
 		break;
 	default:
-		PR_DISP_ERR("%s: Unknown interface %d\n", __func__, interface);
-		BUG();
+		break;
+	}
+	return base;
+}
+
+static uint32_t mdp_pp_block2hist_lut(uint32_t block)
+{
+	uint32_t valid = 0;
+	switch (block) {
+	case MDP_BLOCK_DMA_P:
+		valid = (mdp_rev >= MDP_REV_40) ? 1 : 0;
+		break;
+	case MDP_BLOCK_DMA_S:
+		valid = (mdp_rev >= MDP_REV_40) ? 1 : 0;
+		break;
+	case MDP_BLOCK_VG_1:
+		valid = (mdp_rev >= MDP_REV_40) ? 1 : 0;
+		break;
+	case MDP_BLOCK_VG_2:
+		valid = (mdp_rev >= MDP_REV_40) ? 1 : 0;
+		break;
+	default:
+		break;
+	}
+	return valid;
+}
+
+static void mdp_hist_lut_init_mgmt(struct mdp_hist_lut_mgmt *mgmt,
+		uint32_t block)
+{
+	mutex_init(&mgmt->lock);
+	mgmt->block = block;
+
+	mutex_lock(&mdp_hist_lut_list_mutex);
+	list_add(&mgmt->list, &mdp_hist_lut_list);
+	mutex_unlock(&mdp_hist_lut_list_mutex);
+}
+
+static int mdp_hist_lut_init(void)
+{
+	struct mdp_hist_lut_mgmt *temp;
+	struct list_head *pos, *q;
+	INIT_LIST_HEAD(&mdp_hist_lut_list);
+
+	if (mdp_rev >= MDP_REV_30) {
+		temp = kmalloc(sizeof(struct mdp_hist_lut_mgmt), GFP_KERNEL);
+		if (!temp)
+			goto exit;
+		mdp_hist_lut_init_mgmt(temp, MDP_BLOCK_DMA_P);
 	}
 
-	if (mdp_wait(mdp, mask, wq) == -ETIMEDOUT)
-		timeout_count++;
+	if (mdp_rev >= MDP_REV_40) {
+		temp = kmalloc(sizeof(struct mdp_hist_lut_mgmt), GFP_KERNEL);
+		if (!temp)
+			goto exit_list;
+		mdp_hist_lut_init_mgmt(temp, MDP_BLOCK_VG_1);
+
+		temp = kmalloc(sizeof(struct mdp_hist_lut_mgmt), GFP_KERNEL);
+		if (!temp)
+			goto exit_list;
+		mdp_hist_lut_init_mgmt(temp, MDP_BLOCK_VG_2);
+	}
+
+	if (mdp_rev > MDP_REV_42) {
+		temp = kmalloc(sizeof(struct mdp_hist_lut_mgmt), GFP_KERNEL);
+		if (!temp)
+			goto exit_list;
+		mdp_hist_lut_init_mgmt(temp, MDP_BLOCK_DMA_S);
+	}
+	return 0;
+
+exit_list:
+	mutex_lock(&mdp_hist_lut_list_mutex);
+	list_for_each_safe(pos, q, &mdp_hist_lut_list) {
+		temp = list_entry(pos, struct mdp_hist_lut_mgmt, list);
+		list_del(pos);
+		kfree(temp);
+	}
+	mutex_unlock(&mdp_hist_lut_list_mutex);
+exit:
+	pr_err("Failed initializing histogram LUT memory\n");
+	return -ENOMEM;
+}
+
+static int mdp_hist_lut_block2mgmt(uint32_t block,
+		struct mdp_hist_lut_mgmt **mgmt)
+{
+	struct mdp_hist_lut_mgmt *temp, *output;
+	int ret = 0;
+
+	output = NULL;
+
+	mutex_lock(&mdp_hist_lut_list_mutex);
+	list_for_each_entry(temp, &mdp_hist_lut_list, list) {
+		if (temp->block == block)
+			output = temp;
+	}
+	mutex_unlock(&mdp_hist_lut_list_mutex);
+
+	if (output == NULL)
+		ret = -EINVAL;
 	else
-		timeout_count = 0;
+		*mgmt = output;
 
-	if (timeout_count > MDP_MAX_TIMEOUTS) {
-		PR_DISP_ERR("mdp: dma failed %d times, somethings wrong!\n",
-		       MDP_MAX_TIMEOUTS);
-		BUG();
-	}
-}
-/*
-static int mdp_ppp_wait(struct mdp_info *mdp)
-{
-	return mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue);
-}
-*/
-#ifndef CONFIG_MSM_MDP40
-static void mdp_dmas_to_mddi(void *priv, uint32_t addr, uint32_t stride,
-		uint32_t width, uint32_t height, uint32_t x, uint32_t y)
-{
-	struct mdp_info *mdp = priv;
-	uint32_t dma2_cfg;
-	uint32_t video_packet_parameter = 0;
-	uint16_t ld_param = 1;
-
-	dma2_cfg = DMA_PACK_TIGHT |
-		DMA_PACK_ALIGN_LSB |
-		DMA_OUT_SEL_AHB |
-		DMA_IBUF_NONCONTIGUOUS;
-
-	dma2_cfg |= mdp->dma_format;
-
-#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30
-	if (mdp->dma_format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888)
-#else
-	if (mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888)
-#endif
-		dma2_cfg |= DMA_PACK_PATTERN_BGR;
-	else
-		dma2_cfg |= DMA_PACK_PATTERN_RGB;
-
-	dma2_cfg |= DMA_OUT_SEL_MDDI;
-
-	dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
-
-	dma2_cfg |= DMA_DITHER_EN;
-
-	if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) {
-		dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
-		video_packet_parameter = MDDI_VDO_PACKET_DESC_RGB565;
-	} else if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB666) {
-		dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
-		video_packet_parameter = MDDI_VDO_PACKET_DESC_RGB666;
-	}
-
-	/* setup size, address, and stride */
-	mdp_writel(mdp, (height << 16) | (width), MDP_DMA_S_SIZE);
-	mdp_writel(mdp, addr, MDP_DMA_S_IBUF_ADDR);
-	mdp_writel(mdp, stride, MDP_DMA_S_IBUF_Y_STRIDE);
-
-	/* set y & x offset and MDDI transaction parameters */
-	mdp_writel(mdp, (y << 16) | (x), MDP_DMA_S_OUT_XY);
-	mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL);
-	if (mdp->mdp_dev.overrides & MSM_MDP_PANEL_IGNORE_PIXEL_DATA) {
-		mdp_writel(mdp, (video_packet_parameter << 16) | 0xE3,
-			MDP_MDDI_PARAM);
-	} else {
-		mdp_writel(mdp, (video_packet_parameter << 16) | MDDI_VDO_PACKET_PRIM,
-			MDP_MDDI_PARAM);
-	}
-
-	mdp_writel(mdp, dma2_cfg, MDP_DMA_S_CONFIG);
-	mdp_writel(mdp, 0, MDP_DMA_S_START);
+	return ret;
 }
 
-static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride,
-			    uint32_t width, uint32_t height, uint32_t x,
-			    uint32_t y)
+#define MDP_HIST_LUT_SIZE (256)
+static int mdp_hist_lut_write_off(struct mdp_hist_lut_data *data,
+		struct mdp_hist_lut_info *info, uint32_t offset)
 {
-	struct mdp_info *mdp = priv;
-	uint32_t dma2_cfg = 0;
-	uint32_t video_packet_parameter = 0;
-	uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */
+	int i;
+	uint32_t element[MDP_HIST_LUT_SIZE];
+	uint32_t base = mdp_block2base(info->block);
+	uint32_t sel = info->bank_sel;
 
-#if !defined(CONFIG_MSM_MDP30)
-	dma2_cfg = DMA_PACK_TIGHT |
-		DMA_PACK_ALIGN_LSB |
-		DMA_OUT_SEL_AHB |
-		DMA_IBUF_NONCONTIGUOUS;
 
-#endif
-	dma2_cfg |= mdp->dma_format;
-
-#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30
-	if (mdp->dma_format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888)
-#else
-	if (mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888)
-#endif
-		dma2_cfg |= DMA_PACK_PATTERN_BGR;
-	else
-		dma2_cfg |= DMA_PACK_PATTERN_RGB;
-
-	dma2_cfg |= DMA_OUT_SEL_MDDI;
-
-	dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
-
-#if !defined(CONFIG_MSM_MDP30)
-	dma2_cfg |= DMA_DITHER_EN;
-#endif
-
-	if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) {
-		dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
-		video_packet_parameter = MDDI_VDO_PACKET_DESC_RGB565;
-	} else if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB666) {
-		dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
-		video_packet_parameter = MDDI_VDO_PACKET_DESC_RGB666;
+	if (data->len != MDP_HIST_LUT_SIZE) {
+		pr_err("%s: data->len != %d", __func__, MDP_HIST_LUT_SIZE);
+		return -EINVAL;
 	}
 
-
-#if defined(CONFIG_MSM_MDP30) || defined(CONFIG_MSM_MDP302)
-	writel(height << 16 | width, mdp->base + 0x90004);
-	writel(addr, mdp->base + 0x90008);
-	writel(stride, mdp->base + 0x9000c);
-
-	/* set y & x offset and MDDI transaction parameters */
-	writel(y << 16 | x, mdp->base + 0x90010);
-	writel(ld_param, mdp->base + 0x00090);
-	writel((video_packet_parameter << 16) | MDDI_VDO_PACKET_PRIM,
-		mdp->base + 0x00094);
-
-	writel(dma2_cfg, mdp->base + 0x90000);
-
-	/* start DMA2 */
-	writel(0, mdp->base + 0x0044);
-#elif defined(CONFIG_MSM_MDP22)
-	/* setup size, address, and stride */
-	mdp_writel(mdp, (height << 16) | (width),
-		   MDP_CMD_DEBUG_ACCESS_BASE + 0x0184);
-	mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188);
-	mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C);
-
-	/* set y & x offset and MDDI transaction parameters */
-	mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194);
-	mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0);
-	mdp_writel(mdp, (video_packet_parameter << 16) | MDDI_VDO_PACKET_PRIM,
-		   MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4);
-
-	mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180);
-
-	/* start DMA2 */
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044);
-#else
-	/* setup size, address, and stride */
-	mdp_writel(mdp, (height << 16) | (width), MDP_DMA_P_SIZE);
-	mdp_writel(mdp, addr, MDP_DMA_P_IBUF_ADDR);
-	mdp_writel(mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE);
-
-	/* set y & x offset and MDDI transaction parameters */
-	mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY);
-	mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL);
-	mdp_writel(mdp, (video_packet_parameter << 16) | MDDI_VDO_PACKET_PRIM,
-		   MDP_MDDI_PARAM);
-
-	mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG);
-	mdp_writel(mdp, 0, MDP_DMA_P_START);
-#endif
-}
-#endif	/* ifndef CONFIG_MSM_MDP40 */
-
-void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride,
-	     uint32_t width, uint32_t height, uint32_t x, uint32_t y,
-	     struct msmfb_callback *callback, int interface)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	struct mdp_out_interface *out_if;
-	unsigned long flags;
-
-	if (interface < 0 || interface >= MSM_MDP_NUM_INTERFACES ||
-	    !mdp->out_if[interface].registered) {
-		PR_DISP_ERR("%s: Unknown interface: %d\n", __func__, interface);
-		BUG();
+	if (copy_from_user(&element, data->data,
+				MDP_HIST_LUT_SIZE * sizeof(uint32_t))) {
+		pr_err("%s: Error copying histogram data", __func__);
+		return -ENOMEM;
 	}
-	out_if = &mdp->out_if[interface];
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < MDP_HIST_LUT_SIZE; i++)
+		MDP_OUTP(MDP_BASE + base + offset + (0x400*(sel)) + (4*i),
+				element[i]);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
-	spin_lock_irqsave(&mdp->lock, flags);
-	if (locked_enable_mdp_irq(mdp, out_if->dma_mask)) {
-		mdp_dma_user_requested++;
-		if (mdp_dma_user_requested > 2) {
-				PR_DISP_ERR("%s: really busy? start dma timer\n", __func__);
-			/* something wrong in dma, workaround it */
-			mdp_dma_timer_enable = 1;
-			mdp_dma_user_requested = 0;
-		} else {
-			PR_DISP_ERR("%s: busy\n", __func__);
-			goto done;
-		}
-	} else
-		mdp_dma_user_requested = 0;
-
-	out_if->dma_cb = callback;
-	out_if->dma_start(out_if->priv, addr, stride, width, height, x, y);
-
-	if (mdp_dma_timer_enable) {
-		mdp_writel(mdp, mdp_irq_mask & ~out_if->dma_mask, MDP_INTR_ENABLE);
-		PR_DISP_ERR("%s: start dma timer\n", __func__);
-		mod_timer(&mdp->dma_timer,
-			jiffies + msecs_to_jiffies(30));
-	}
-done:
-	spin_unlock_irqrestore(&mdp->lock, flags);
+	return 0;
 }
 
-
-void mdp_configure_dma(struct mdp_device *mdp_dev)
+static int mdp_hist_lut_write(struct mdp_hist_lut_data *data,
+						struct mdp_hist_lut_info *info)
 {
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	uint32_t dma_cfg;
+	int ret = 0;
 
-	if (!mdp->dma_config_dirty)
-		return;
-	dma_cfg = mdp_readl(mdp, MDP_DMA_P_CONFIG);
-	dma_cfg &= ~DMA_IBUF_FORMAT_MASK;
-	dma_cfg &= ~DMA_PACK_PATTERN_MASK;
-	dma_cfg |= (mdp->dma_format | mdp->dma_pack_pattern);
-	mdp_writel(mdp, dma_cfg, MDP_DMA_P_CONFIG);
-	mdp->dma_config_dirty = false;
+	if (data->block != info->block) {
+		ret = -1;
+		pr_err("%s, data/info mdp_block mismatch! %d != %d\n",
+				__func__, data->block, info->block);
+		goto error;
+	}
 
+	switch (data->block) {
+	case MDP_BLOCK_VG_1:
+	case MDP_BLOCK_VG_2:
+		ret = mdp_hist_lut_write_off(data, info, 0x3400);
+		break;
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+		ret = mdp_hist_lut_write_off(data, info, 0x4800);
+		break;
+	default:
+		ret = -EINVAL;
+		goto error;
+	}
+
+error:
+	return ret;
+}
+
+#define MDP_HIST_LUT_VG_EN_MASK (0x20000)
+#define MDP_HIST_LUT_VG_EN_SHIFT (17)
+#define MDP_HIST_LUT_VG_EN_OFFSET (0x0058)
+#define MDP_HIST_LUT_VG_SEL_OFFSET (0x0064)
+static void mdp_hist_lut_commit_vg(struct mdp_hist_lut_info *info)
+{
+	uint32_t out_en, temp_en;
+	uint32_t base = mdp_block2base(info->block);
+	temp_en = (info->is_enabled) ? (1 << MDP_HIST_LUT_VG_EN_SHIFT) : 0x0;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	out_en = inpdw(MDP_BASE + base + MDP_HIST_LUT_VG_EN_OFFSET) &
+						~MDP_HIST_LUT_VG_EN_MASK;
+	MDP_OUTP(MDP_BASE + base + MDP_HIST_LUT_VG_EN_OFFSET, out_en | temp_en);
+
+	if (info->has_sel_update)
+		MDP_OUTP(MDP_BASE + base + MDP_HIST_LUT_VG_SEL_OFFSET,
+								info->bank_sel);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+#define MDP_HIST_LUT_DMA_EN_MASK (0x7)
+#define MDP_HIST_LUT_DMA_SEL_MASK (0x400)
+#define MDP_HIST_LUT_DMA_SEL_SHIFT (10)
+#define MDP_HIST_LUT_DMA_P_OFFSET (0x0070)
+#define MDP_HIST_LUT_DMA_S_OFFSET (0x0028)
+static void mdp_hist_lut_commit_dma(struct mdp_hist_lut_info *info)
+{
+	uint32_t out, temp, mask;
+	uint32_t base = mdp_block2base(info->block);
+	uint32_t offset = (info->block == MDP_BLOCK_DMA_P) ?
+		MDP_HIST_LUT_DMA_P_OFFSET : MDP_HIST_LUT_DMA_S_OFFSET;
+
+	mask = MDP_HIST_LUT_DMA_EN_MASK;
+	temp = (info->is_enabled) ? 0x7 : 0x0;
+
+	if (info->has_sel_update) {
+		mask |= MDP_HIST_LUT_DMA_SEL_MASK;
+		temp |=  ((info->bank_sel & 0x1) << MDP_HIST_LUT_DMA_SEL_SHIFT);
+	}
+
+	out = inpdw(MDP_BASE + base + offset) & ~mask;
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	MDP_OUTP(MDP_BASE + base + offset, out | temp);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+static void mdp_hist_lut_commit_info(struct mdp_hist_lut_info *info)
+{
+	switch (info->block) {
+	case MDP_BLOCK_VG_1:
+	case MDP_BLOCK_VG_2:
+		mdp_hist_lut_commit_vg(info);
+		break;
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+		mdp_hist_lut_commit_dma(info);
+		break;
+	default:
+		goto error;
+	}
+
+error:
 	return;
 }
 
-int mdp_check_output_format(struct mdp_device *mdp_dev, int bpp)
+static void mdp_hist_lut_update_info(struct mdp_hist_lut_info *info, int ops)
 {
-	switch (bpp) {
-	case 16:
-	case 24:
-	case 32:
+	info->bank_sel = (ops & 0x8) >> 3;
+	info->is_enabled = (ops & 0x1) ? TRUE : FALSE;
+	info->has_sel_update = (ops & 0x10) ? TRUE : FALSE;
+}
+
+int mdp_hist_lut_config(struct mdp_hist_lut_data *data)
+{
+	struct mdp_hist_lut_mgmt *mgmt = NULL;
+	struct mdp_hist_lut_info info;
+	int ret = 0;
+
+	if (!mdp_pp_block2hist_lut(data->block)) {
+		ret = -ENOTTY;
+		goto error;
+	}
+
+	ret = mdp_hist_lut_block2mgmt(data->block, &mgmt);
+	if (ret)
+		goto error;
+
+	mutex_lock(&mgmt->lock);
+
+	info.block = mgmt->block;
+
+	mdp_hist_lut_update_info(&info, data->ops);
+
+	switch ((data->ops & 0x6) >> 1) {
+	case 0x1:
+		pr_info("%s: histogram LUT read not supported\n", __func__);
+		break;
+	case 0x2:
+		ret = mdp_hist_lut_write(data, &info);
+		if (ret)
+			goto error_lock;
 		break;
 	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-void mdp_set_panel_size(struct mdp_device *mdp_dev, int width, int height)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	mdp->mdp_dev.width = width;
-	mdp->mdp_dev.height = height;
-}
-
-int mdp_set_output_format(struct mdp_device *mdp_dev, int bpp)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	uint32_t format, pack_pattern = DMA_PACK_PATTERN_RGB;
-
-	switch (bpp) {
-	case 16:
-		format = DMA_IBUF_FORMAT_RGB565;
-		pack_pattern = DMA_PACK_PATTERN_RGB;
 		break;
-#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30
-	case 24:
-	case 32:
-		format = DMA_IBUF_FORMAT_RGB888_OR_ARGB8888;
-		break;
-#else
-	case 24:
-		format = DMA_IBUF_FORMAT_RGB888;
-		pack_pattern = DMA_PACK_PATTERN_BGR;
-		break;
-	case 32:
-		format = DMA_IBUF_FORMAT_XRGB8888;
-		pack_pattern = DMA_PACK_PATTERN_BGR;
-		break;
-#endif
-	default:
-		return -EINVAL;
-	}
-	if (format != mdp->dma_format || pack_pattern != mdp->dma_pack_pattern) {
-		mdp->dma_format = format;
-		mdp->dma_pack_pattern = pack_pattern;
-		mdp->dma_config_dirty = true;
 	}
 
-	return 0;
+	mdp_hist_lut_commit_info(&info);
+
+error_lock:
+	mutex_unlock(&mgmt->lock);
+error:
+	return ret;
 }
 
-int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
-	     struct mdp_blit_req *req)
+DEFINE_MUTEX(mdp_lut_push_sem);
+static int mdp_lut_i;
+static int mdp_lut_hw_update(struct fb_cmap *cmap)
 {
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	timeout_req = req;
-	return mdp_ppp_blit(mdp, fb, req);
-}
+	int i;
+	u16 *c[3];
+	u16 r, g, b;
 
-
-
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-int mdp_lut_update(struct mdp_device *mdp_dev, struct fb_info *fb,
-	     struct fb_cmap *cmap)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	unsigned int i, addr, val;
-	unsigned short *r, *g, *b;
-	int mdp_lut_i = 0;
+	c[0] = cmap->green;
+	c[1] = cmap->blue;
+	c[2] = cmap->red;
 
 	for (i = 0; i < cmap->len; i++) {
-		r = cmap->red++;
-		g = cmap->green++;
-		b = cmap->blue++;
+		if (copy_from_user(&r, cmap->red++, sizeof(r)) ||
+		    copy_from_user(&g, cmap->green++, sizeof(g)) ||
+		    copy_from_user(&b, cmap->blue++, sizeof(b)))
+			return -EFAULT;
 
-		addr = 0x94800 + (0x400 * mdp_lut_i) + cmap->start * 4 + i * 4;
-		val = ((*g & 0xff)|((*b & 0xff) << 8)|((*r & 0xff) << 16));
-		mdp_writel(mdp, val, addr);
+#ifdef CONFIG_FB_MSM_MDP40
+		MDP_OUTP(MDP_BASE + 0x94800 +
+#else
+		MDP_OUTP(MDP_BASE + 0x93800 +
+#endif
+			(0x400*mdp_lut_i) + cmap->start*4 + i*4,
+				((g & 0xff) |
+				 ((b & 0xff) << 8) |
+				 ((r & 0xff) << 16)));
 	}
 
-	/* lcdc case */
-	mdp_writel(mdp, (mdp_lut_i << 10) | 0x17, 0x90070);
+	return 0;
+}
+
+static int mdp_lut_push;
+static int mdp_lut_push_i;
+static int mdp_lut_update_nonlcdc(struct fb_info *info, struct fb_cmap *cmap)
+{
+	int ret;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	ret = mdp_lut_hw_update(cmap);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	if (ret)
+		return ret;
+
+	mutex_lock(&mdp_lut_push_sem);
+	mdp_lut_push = 1;
+	mdp_lut_push_i = mdp_lut_i;
+	mutex_unlock(&mdp_lut_push_sem);
+
 	mdp_lut_i = (mdp_lut_i + 1)%2;
 
 	return 0;
 }
 
-static void mdp_lut_enable(struct mdp_info *mdp)
+static int mdp_lut_update_lcdc(struct fb_info *info, struct fb_cmap *cmap)
 {
+	int ret;
+	uint32_t out;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	ret = mdp_lut_hw_update(cmap);
+
+	if (ret) {
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+		return ret;
+	}
+
+	/*mask off non LUT select bits*/
+	out = inpdw(MDP_BASE + 0x90070) & ~((0x1 << 10) | 0x7);
+	MDP_OUTP(MDP_BASE + 0x90070, (mdp_lut_i << 10) | 0x7 | out);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	mdp_lut_i = (mdp_lut_i + 1)%2;
+
+	return 0;
+}
+
+static void mdp_lut_enable(void)
+{
+	uint32_t out;
 	if (mdp_lut_push) {
 		mutex_lock(&mdp_lut_push_sem);
 		mdp_lut_push = 0;
+		out = inpdw(MDP_BASE + 0x90070) & ~((0x1 << 10) | 0x7);
+		MDP_OUTP(MDP_BASE + 0x90070,
+				(mdp_lut_push_i << 10) | 0x7 | out);
 		mutex_unlock(&mdp_lut_push_sem);
-		mdp_writel(mdp, (mdp_lut_push_i << 10) | 0x17 | 1<<3, 0x90070);
 	}
 }
 
-void mdp_pipe_kickoff(struct mdp_info *mdp, uint32_t term)
+#define MDP_REV42_HIST_MAX_BIN 128
+#define MDP_REV41_HIST_MAX_BIN 32
+
+#define MDP_HIST_DATA32_R_OFF 0x0100
+#define MDP_HIST_DATA32_G_OFF 0x0200
+#define MDP_HIST_DATA32_B_OFF 0x0300
+
+#define MDP_HIST_DATA128_R_OFF 0x0400
+#define MDP_HIST_DATA128_G_OFF 0x0800
+#define MDP_HIST_DATA128_B_OFF 0x0C00
+
+#define MDP_HIST_DATA_LUMA_OFF 0x0200
+
+#define MDP_HIST_EXTRA_DATA0_OFF 0x0028
+#define MDP_HIST_EXTRA_DATA1_OFF 0x002C
+
+struct mdp_hist_mgmt *mdp_hist_mgmt_array[MDP_HIST_MGMT_MAX];
+
+void __mdp_histogram_kickoff(struct mdp_hist_mgmt *mgmt)
+{
+	char *mdp_hist_base = MDP_BASE + mgmt->base;
+	if (mgmt->mdp_is_hist_data == TRUE) {
+		MDP_OUTP(mdp_hist_base + 0x0004, mgmt->frame_cnt);
+		MDP_OUTP(mdp_hist_base, 1);
+	}
+}
+
+void __mdp_histogram_reset(struct mdp_hist_mgmt *mgmt)
+{
+	char *mdp_hist_base = MDP_BASE + mgmt->base;
+	MDP_OUTP(mdp_hist_base + 0x000C, 1);
+}
+
+static void mdp_hist_read_work(struct work_struct *data);
+
+static int mdp_hist_init_mgmt(struct mdp_hist_mgmt *mgmt, uint32_t block)
+{
+	uint32_t bins, extra, index, term = 0;
+	init_completion(&mgmt->mdp_hist_comp);
+	mutex_init(&mgmt->mdp_hist_mutex);
+	mutex_init(&mgmt->mdp_do_hist_mutex);
+	mgmt->block = block;
+	mgmt->base = mdp_block2base(block);
+	mgmt->mdp_is_hist_start = FALSE;
+	mgmt->mdp_is_hist_data = FALSE;
+	mgmt->mdp_is_hist_valid = FALSE;
+	mgmt->mdp_is_hist_init = FALSE;
+	mgmt->frame_cnt = 0;
+	mgmt->bit_mask = 0;
+	mgmt->num_bins = 0;
+	switch (block) {
+	case MDP_BLOCK_DMA_P:
+		term = MDP_HISTOGRAM_TERM_DMA_P;
+		bins = (mdp_rev >= MDP_REV_42) ? MDP_REV42_HIST_MAX_BIN :
+			MDP_REV41_HIST_MAX_BIN;
+		extra = 2;
+		mgmt->base += (mdp_rev >= MDP_REV_40) ? 0x5000 : 0x4000;
+		index = MDP_HIST_MGMT_DMA_P;
+		break;
+	case MDP_BLOCK_DMA_S:
+		term = MDP_HISTOGRAM_TERM_DMA_S;
+		bins = MDP_REV42_HIST_MAX_BIN;
+		extra = 2;
+		mgmt->base += 0x5000;
+		index = MDP_HIST_MGMT_DMA_S;
+		break;
+	case MDP_BLOCK_VG_1:
+		term = MDP_HISTOGRAM_TERM_VG_1;
+		bins = MDP_REV42_HIST_MAX_BIN;
+		extra = 1;
+		mgmt->base += 0x6000;
+		index = MDP_HIST_MGMT_VG_1;
+		break;
+	case MDP_BLOCK_VG_2:
+		term = MDP_HISTOGRAM_TERM_VG_2;
+		bins = MDP_REV42_HIST_MAX_BIN;
+		extra = 1;
+		mgmt->base += 0x6000;
+		index = MDP_HIST_MGMT_VG_2;
+		break;
+	default:
+		term = MDP_HISTOGRAM_TERM_DMA_P;
+		bins = (mdp_rev >= MDP_REV_42) ? MDP_REV42_HIST_MAX_BIN :
+			MDP_REV41_HIST_MAX_BIN;
+		extra = 2;
+		mgmt->base += (mdp_rev >= MDP_REV_40) ? 0x5000 : 0x4000;
+		index = MDP_HIST_MGMT_DMA_P;
+	}
+	mgmt->irq_term = term;
+
+	mgmt->c0 = kmalloc(bins * sizeof(uint32_t), GFP_KERNEL);
+	if (mgmt->c0 == NULL)
+		goto error;
+
+	mgmt->c1 = kmalloc(bins * sizeof(uint32_t), GFP_KERNEL);
+	if (mgmt->c1 == NULL)
+		goto error_1;
+
+	mgmt->c2 = kmalloc(bins * sizeof(uint32_t), GFP_KERNEL);
+	if (mgmt->c2 == NULL)
+		goto error_2;
+
+	mgmt->extra_info = kmalloc(extra * sizeof(uint32_t), GFP_KERNEL);
+	if (mgmt->extra_info == NULL)
+		goto error_extra;
+
+	INIT_WORK(&mgmt->mdp_histogram_worker, mdp_hist_read_work);
+
+	mdp_hist_mgmt_array[index] = mgmt;
+	return 0;
+
+error_extra:
+	kfree(mgmt->c2);
+error_2:
+	kfree(mgmt->c1);
+error_1:
+	kfree(mgmt->c0);
+error:
+	return -ENOMEM;
+}
+
+static void mdp_hist_del_mgmt(struct mdp_hist_mgmt *mgmt)
+{
+	kfree(mgmt->extra_info);
+	kfree(mgmt->c2);
+	kfree(mgmt->c1);
+	kfree(mgmt->c0);
+}
+
+static int mdp_histogram_init(void)
+{
+	struct mdp_hist_mgmt *temp;
+	int i, ret;
+	mdp_hist_wq = alloc_workqueue("mdp_hist_wq", WQ_UNBOUND, 0);
+
+	for (i = 0; i < MDP_HIST_MGMT_MAX; i++)
+		mdp_hist_mgmt_array[i] = NULL;
+
+	if (mdp_rev >= MDP_REV_30) {
+		temp = kmalloc(sizeof(struct mdp_hist_mgmt), GFP_KERNEL);
+		if (!temp)
+			goto exit;
+		ret = mdp_hist_init_mgmt(temp, MDP_BLOCK_DMA_P);
+		if (ret) {
+			kfree(temp);
+			goto exit;
+		}
+	}
+
+	if (mdp_rev >= MDP_REV_40) {
+		temp = kmalloc(sizeof(struct mdp_hist_mgmt), GFP_KERNEL);
+		if (!temp)
+			goto exit_list;
+		ret = mdp_hist_init_mgmt(temp, MDP_BLOCK_VG_1);
+		if (ret)
+			goto exit_list;
+
+		temp = kmalloc(sizeof(struct mdp_hist_mgmt), GFP_KERNEL);
+		if (!temp)
+			goto exit_list;
+		ret = mdp_hist_init_mgmt(temp, MDP_BLOCK_VG_2);
+		if (ret)
+			goto exit_list;
+	}
+
+	if (mdp_rev >= MDP_REV_42) {
+		temp = kmalloc(sizeof(struct mdp_hist_mgmt), GFP_KERNEL);
+		if (!temp)
+			goto exit_list;
+		ret = mdp_hist_init_mgmt(temp, MDP_BLOCK_DMA_S);
+		if (ret)
+			goto exit_list;
+	}
+
+	return 0;
+
+exit_list:
+	for (i = 0; i < MDP_HIST_MGMT_MAX; i++) {
+		temp = mdp_hist_mgmt_array[i];
+		if (!temp)
+			continue;
+		mdp_hist_del_mgmt(temp);
+		kfree(temp);
+		mdp_hist_mgmt_array[i] = NULL;
+	}
+exit:
+	return -ENOMEM;
+}
+
+int mdp_histogram_block2mgmt(uint32_t block, struct mdp_hist_mgmt **mgmt)
+{
+	struct mdp_hist_mgmt *temp, *output;
+	int i, ret = 0;
+
+	output = NULL;
+
+	for (i = 0; i < MDP_HIST_MGMT_MAX; i++) {
+		temp = mdp_hist_mgmt_array[i];
+		if (!temp)
+			continue;
+
+		if (temp->block == block) {
+			output = temp;
+			break;
+		}
+	}
+
+	if (output == NULL)
+		ret = -EINVAL;
+	else
+		*mgmt = output;
+
+	return ret;
+}
+
+static int mdp_histogram_enable(struct mdp_hist_mgmt *mgmt)
+{
+	uint32_t base;
+	if (mgmt->mdp_is_hist_data == TRUE) {
+		pr_err("%s histogram already started\n", __func__);
+		return -EINVAL;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	mdp_enable_irq(mgmt->irq_term);
+	INIT_COMPLETION(mgmt->mdp_hist_comp);
+
+	base = (uint32_t) (MDP_BASE + mgmt->base);
+	MDP_OUTP(base + 0x0018, INTR_HIST_DONE | INTR_HIST_RESET_SEQ_DONE);
+	MDP_OUTP(base + 0x0010, 1);
+	MDP_OUTP(base + 0x001C, INTR_HIST_DONE | INTR_HIST_RESET_SEQ_DONE);
+
+	MDP_OUTP(base + 0x0004, mgmt->frame_cnt);
+	if (mgmt->block != MDP_BLOCK_VG_1 && mgmt->block != MDP_BLOCK_VG_2)
+		MDP_OUTP(base + 0x0008, mgmt->bit_mask);
+	mgmt->mdp_is_hist_data = TRUE;
+	mgmt->mdp_is_hist_valid = TRUE;
+	mgmt->mdp_is_hist_init = FALSE;
+	__mdp_histogram_reset(mgmt);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	return 0;
+}
+
+static int mdp_histogram_disable(struct mdp_hist_mgmt *mgmt)
+{
+	uint32_t base, status;
+	if (mgmt->mdp_is_hist_data == FALSE) {
+		pr_err("%s histogram already stopped\n", __func__);
+		return -EINVAL;
+	}
+
+	mgmt->mdp_is_hist_data = FALSE;
+	mgmt->mdp_is_hist_valid = FALSE;
+	mgmt->mdp_is_hist_init = FALSE;
+
+	base = (uint32_t) (MDP_BASE + mgmt->base);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	if (mdp_rev >= MDP_REV_42)
+		MDP_OUTP(base + 0x0020, 1);
+	status = inpdw(base + 0x001C);
+	status &= ~(INTR_HIST_DONE | INTR_HIST_RESET_SEQ_DONE);
+	MDP_OUTP(base + 0x001C, status);
+
+	MDP_OUTP(base + 0x0018, INTR_HIST_DONE | INTR_HIST_RESET_SEQ_DONE);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	complete(&mgmt->mdp_hist_comp);
+	mdp_disable_irq(mgmt->irq_term);
+	return 0;
+}
+
+/*call when spanning mgmt_array only*/
+int _mdp_histogram_ctrl(boolean en, struct mdp_hist_mgmt *mgmt)
+{
+	int ret = 0;
+
+	mutex_lock(&mgmt->mdp_hist_mutex);
+	if (mgmt->mdp_is_hist_start == TRUE) {
+		if (en)
+			ret = mdp_histogram_enable(mgmt);
+		else
+			ret = mdp_histogram_disable(mgmt);
+	}
+	mutex_unlock(&mgmt->mdp_hist_mutex);
+
+	if (en == false)
+		cancel_work_sync(&mgmt->mdp_histogram_worker);
+
+	return ret;
+}
+
+int mdp_histogram_ctrl(boolean en, uint32_t block)
+{
+	struct mdp_hist_mgmt *mgmt = NULL;
+	int ret = 0;
+
+	ret = mdp_histogram_block2mgmt(block, &mgmt);
+	if (ret)
+		goto error;
+
+	ret = _mdp_histogram_ctrl(en, mgmt);
+error:
+	return ret;
+}
+
+int mdp_histogram_ctrl_all(boolean en)
+{
+	struct mdp_hist_mgmt *temp;
+	int i, ret = 0, ret_temp = 0;
+
+	for (i = 0; i < MDP_HIST_MGMT_MAX; i++) {
+		temp = mdp_hist_mgmt_array[i];
+		if (!temp)
+			continue;
+
+		ret_temp = _mdp_histogram_ctrl(en, temp);
+		if (ret_temp)
+			ret = ret_temp;
+	}
+	return ret;
+}
+
+int mdp_histogram_start(struct mdp_histogram_start_req *req)
+{
+	struct mdp_hist_mgmt *mgmt = NULL;
+	int ret;
+
+	ret = mdp_histogram_block2mgmt(req->block, &mgmt);
+	if (ret) {
+		ret = -ENOTTY;
+		goto error;
+	}
+
+	mutex_lock(&mgmt->mdp_hist_mutex);
+	if (mgmt->mdp_is_hist_start == TRUE) {
+		pr_err("%s histogram already started\n", __func__);
+		ret = -EPERM;
+		goto error_lock;
+	}
+
+	mgmt->block = req->block;
+	mgmt->frame_cnt = req->frame_cnt;
+	mgmt->bit_mask = req->bit_mask;
+	mgmt->num_bins = req->num_bins;
+
+	ret = mdp_histogram_enable(mgmt);
+
+	mgmt->mdp_is_hist_start = TRUE;
+
+error_lock:
+	mutex_unlock(&mgmt->mdp_hist_mutex);
+error:
+	return ret;
+}
+
+int mdp_histogram_stop(struct fb_info *info, uint32_t block)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *) info->par;
+	struct mdp_hist_mgmt *mgmt = NULL;
+	int ret;
+
+	ret = mdp_histogram_block2mgmt(block, &mgmt);
+	if (ret) {
+		ret = -ENOTTY;
+		goto error;
+	}
+
+	mutex_lock(&mgmt->mdp_hist_mutex);
+	if (mgmt->mdp_is_hist_start == FALSE) {
+		pr_err("%s histogram already stopped\n", __func__);
+		ret = -EPERM;
+		goto error_lock;
+	}
+
+	mgmt->mdp_is_hist_start = FALSE;
+
+	if (!mfd->panel_power_on) {
+		mgmt->mdp_is_hist_data = FALSE;
+		complete(&mgmt->mdp_hist_comp);
+		ret = -EINVAL;
+		goto error_lock;
+	}
+
+	ret = mdp_histogram_disable(mgmt);
+
+	mutex_unlock(&mgmt->mdp_hist_mutex);
+	cancel_work_sync(&mgmt->mdp_histogram_worker);
+	return ret;
+
+error_lock:
+	mutex_unlock(&mgmt->mdp_hist_mutex);
+error:
+	return ret;
+}
+
+/*call from within mdp_hist_mutex context*/
+static int _mdp_histogram_read_dma_data(struct mdp_hist_mgmt *mgmt)
+{
+	char *mdp_hist_base;
+	uint32_t r_data_offset, g_data_offset, b_data_offset;
+	int i, ret = 0;
+
+	mdp_hist_base = MDP_BASE + mgmt->base;
+
+	r_data_offset = (32 == mgmt->num_bins) ? MDP_HIST_DATA32_R_OFF :
+		MDP_HIST_DATA128_R_OFF;
+	g_data_offset = (32 == mgmt->num_bins) ? MDP_HIST_DATA32_G_OFF :
+		MDP_HIST_DATA128_G_OFF;
+	b_data_offset = (32 == mgmt->num_bins) ? MDP_HIST_DATA32_B_OFF :
+		MDP_HIST_DATA128_B_OFF;
+
+	if (mgmt->c0 == NULL || mgmt->c1 == NULL || mgmt->c2 == NULL) {
+		ret = -ENOMEM;
+		goto hist_err;
+	}
+
+	if (!mgmt->hist) {
+		pr_err("%s: mgmt->hist not set, mgmt->hist = 0x%08x",
+		__func__, (uint32_t) mgmt->hist);
+		return -EINVAL;
+	}
+
+	if (mgmt->hist->bin_cnt != mgmt->num_bins) {
+		pr_err("%s, bins config = %d, bin requested = %d", __func__,
+					mgmt->num_bins, mgmt->hist->bin_cnt);
+		return -EINVAL;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < mgmt->num_bins; i++) {
+		mgmt->c0[i] = inpdw(mdp_hist_base + r_data_offset + (4*i));
+		mgmt->c1[i] = inpdw(mdp_hist_base + g_data_offset + (4*i));
+		mgmt->c2[i] = inpdw(mdp_hist_base + b_data_offset + (4*i));
+	}
+
+	if (mdp_rev >= MDP_REV_42) {
+		if (mgmt->extra_info) {
+			mgmt->extra_info[0] = inpdw(mdp_hist_base +
+					MDP_HIST_EXTRA_DATA0_OFF);
+			mgmt->extra_info[1] = inpdw(mdp_hist_base +
+					MDP_HIST_EXTRA_DATA0_OFF + 4);
+		} else
+			ret = -ENOMEM;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	if (!ret)
+		return ret;
+
+hist_err:
+	pr_err("%s: invalid hist buffer\n", __func__);
+	return ret;
+}
+
+/*call from within mdp_hist_mutex context*/
+static int _mdp_histogram_read_vg_data(struct mdp_hist_mgmt *mgmt)
+{
+	char *mdp_hist_base;
+	int i, ret = 0;
+
+	mdp_hist_base = MDP_BASE + mgmt->base;
+
+	if (mgmt->c0 == NULL) {
+		ret = -ENOMEM;
+		goto hist_err;
+	}
+
+	if (!mgmt->hist) {
+		pr_err("%s: mgmt->hist not set", __func__);
+		return -EINVAL;
+	}
+
+	if (mgmt->hist->bin_cnt != mgmt->num_bins) {
+		pr_err("%s, bins config = %d, bin requested = %d", __func__,
+					mgmt->num_bins, mgmt->hist->bin_cnt);
+		return -EINVAL;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < mgmt->num_bins; i++)
+		mgmt->c0[i] = inpdw(mdp_hist_base + MDP_HIST_DATA_LUMA_OFF +
+									(4*i));
+
+	if (mdp_rev >= MDP_REV_42) {
+		if (mgmt->extra_info) {
+			mgmt->extra_info[0] = inpdw(mdp_hist_base +
+						MDP_HIST_EXTRA_DATA0_OFF);
+		} else
+			ret = -ENOMEM;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	if (!ret)
+		return ret;
+
+hist_err:
+	pr_err("%s: invalid hist buffer\n", __func__);
+	return ret;
+}
+
+static void mdp_hist_read_work(struct work_struct *data)
+{
+	struct mdp_hist_mgmt *mgmt = container_of(data, struct mdp_hist_mgmt,
+							mdp_histogram_worker);
+	int ret = 0;
+	mutex_lock(&mgmt->mdp_hist_mutex);
+	if (mgmt->mdp_is_hist_data == FALSE) {
+		pr_debug("%s, Histogram disabled before read.\n", __func__);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	switch (mgmt->block) {
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+		ret = _mdp_histogram_read_dma_data(mgmt);
+		break;
+	case MDP_BLOCK_VG_1:
+	case MDP_BLOCK_VG_2:
+		ret = _mdp_histogram_read_vg_data(mgmt);
+		break;
+	default:
+		pr_err("%s, invalid MDP block = %d\n", __func__, mgmt->block);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	/* if read was triggered by an underrun, don't wake up readers*/
+	if (mgmt->mdp_is_hist_valid && mgmt->mdp_is_hist_init) {
+		mgmt->hist = NULL;
+		complete(&mgmt->mdp_hist_comp);
+	}
+
+	if (mgmt->mdp_is_hist_valid == FALSE)
+			mgmt->mdp_is_hist_valid = TRUE;
+	if (mgmt->mdp_is_hist_init == FALSE)
+			mgmt->mdp_is_hist_init = TRUE;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	if (!ret)
+		__mdp_histogram_kickoff(mgmt);
+	else
+		__mdp_histogram_reset(mgmt);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+error:
+	mutex_unlock(&mgmt->mdp_hist_mutex);
+}
+
+/*call from within mdp_hist_mutex*/
+static int _mdp_copy_hist_data(struct mdp_histogram_data *hist,
+						struct mdp_hist_mgmt *mgmt)
+{
+	int ret;
+
+	if (hist->c0) {
+		ret = copy_to_user(hist->c0, mgmt->c0,
+		sizeof(uint32_t) * (hist->bin_cnt));
+		if (ret)
+			goto err;
+	}
+	if (hist->c1) {
+		ret = copy_to_user(hist->c1, mgmt->c1,
+		sizeof(uint32_t) * (hist->bin_cnt));
+		if (ret)
+			goto err;
+	}
+	if (hist->c2) {
+		ret = copy_to_user(hist->c2, mgmt->c2,
+		sizeof(uint32_t) * (hist->bin_cnt));
+		if (ret)
+			goto err;
+	}
+	if (hist->extra_info) {
+		ret = copy_to_user(hist->extra_info, mgmt->extra_info,
+		sizeof(uint32_t) * ((hist->block > MDP_BLOCK_VG_2) ? 2 : 1));
+		if (ret)
+			goto err;
+	}
+err:
+	return ret;
+}
+
+static int mdp_do_histogram(struct fb_info *info,
+					struct mdp_histogram_data *hist)
+{
+	struct mdp_hist_mgmt *mgmt = NULL;
+	int ret = 0;
+
+	ret = mdp_histogram_block2mgmt(hist->block, &mgmt);
+	if (ret) {
+		pr_info("%s - %d", __func__, __LINE__);
+		ret = -EINVAL;
+		return ret;
+	}
+
+	mutex_lock(&mgmt->mdp_do_hist_mutex);
+	if (!mgmt->frame_cnt || (mgmt->num_bins == 0)) {
+		pr_info("%s - frame_cnt = %d, num_bins = %d", __func__,
+		mgmt->frame_cnt, mgmt->num_bins);
+		ret = -EINVAL;
+		goto error;
+}
+	if ((mdp_rev <= MDP_REV_41 && hist->bin_cnt > MDP_REV41_HIST_MAX_BIN)
+		|| (mdp_rev == MDP_REV_42 &&
+				hist->bin_cnt > MDP_REV42_HIST_MAX_BIN)) {
+		pr_info("%s - mdp_rev = %d, num_bins = %d", __func__, mdp_rev,
+								hist->bin_cnt);
+		ret = -EINVAL;
+		goto error;
+}
+	mutex_lock(&mgmt->mdp_hist_mutex);
+	if (!mgmt->mdp_is_hist_data) {
+		pr_info("%s - hist_data = false!", __func__);
+		ret = -EINVAL;
+		goto error_lock;
+	}
+
+	if (!mgmt->mdp_is_hist_start) {
+		pr_err("%s histogram not started\n", __func__);
+		ret = -EPERM;
+		goto error_lock;
+	}
+
+	mgmt->hist = hist;
+	mutex_unlock(&mgmt->mdp_hist_mutex);
+
+	if (wait_for_completion_killable(&mgmt->mdp_hist_comp)) {
+		pr_err("%s(): histogram bin collection killed", __func__);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	mutex_lock(&mgmt->mdp_hist_mutex);
+	if (mgmt->mdp_is_hist_data && mgmt->mdp_is_hist_init)
+		ret =  _mdp_copy_hist_data(hist, mgmt);
+	else
+		ret = -ENODATA;
+error_lock:
+	mutex_unlock(&mgmt->mdp_hist_mutex);
+error:
+	mutex_unlock(&mgmt->mdp_do_hist_mutex);
+	return ret;
+}
+#endif
+
+static void send_vsync_work(struct work_struct *work)
+{
+	char buf[64];
+	char *envp[2];
+
+	snprintf(buf, sizeof(buf), "VSYNC=%llu",
+			ktime_to_ns(vsync_cntrl.vsync_time));
+	envp[0] = buf;
+	envp[1] = NULL;
+	kobject_uevent_env(&(vsync_cntrl.dev->kobj), KOBJ_CHANGE, envp);
+}
+
+void mdp3_vsync_irq_enable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	outp32(MDP_INTR_CLEAR, intr);
+	mdp_intr_mask |= intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_enable_irq(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+void mdp3_vsync_irq_disable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	/* required to synchronize between frame update and vsync
+	 * since both use the same LCDC_FRAME_START interrupt
+	 */
+	if (intr == LCDC_FRAME_START && dma2_data.waiting == FALSE) {
+		mdp_intr_mask &= ~intr;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	}
+	mdp_disable_irq(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+#ifdef CONFIG_FB_MSM_MDP303
+/* vsync_isr_handler: Called from isr context*/
+static void vsync_isr_handler(void)
+{
+	vsync_cntrl.vsync_time = ktime_get();
+	schedule_work(&(vsync_cntrl.vsync_work));
+}
+#endif
+
+/* Returns < 0 on error, 0 on timeout, or > 0 on successful wait */
+int mdp_ppp_pipe_wait(void)
+{
+	int ret = 1;
+
+	/* wait 5 seconds for the operation to complete before declaring
+	the MDP hung */
+
+	if (mdp_ppp_waiting == TRUE) {
+		ret = wait_for_completion_interruptible_timeout(&mdp_ppp_comp,
+								5 * HZ);
+
+		if (!ret)
+			printk(KERN_ERR "%s: Timed out waiting for the MDP.\n",
+					__func__);
+	}
+
+	return ret;
+}
+
+static DEFINE_SPINLOCK(mdp_lock);
+static int mdp_irq_mask;
+static int mdp_irq_enabled;
+
+/*
+ * mdp_enable_irq: can not be called from isr
+ */
+void mdp_enable_irq(uint32 term)
+{
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&mdp_lock, irq_flags);
+	if (mdp_irq_mask & term) {
+		printk(KERN_ERR "%s: MDP IRQ term-0x%x is already set, mask=%x irq=%d\n",
+				__func__, term, mdp_irq_mask, mdp_irq_enabled);
+	} else {
+		mdp_irq_mask |= term;
+		if (mdp_irq_mask && !mdp_irq_enabled) {
+			mdp_irq_enabled = 1;
+			enable_irq(mdp_irq);
+		}
+	}
+	spin_unlock_irqrestore(&mdp_lock, irq_flags);
+}
+
+/*
+ * mdp_disable_irq: can not be called from isr
+ */
+void mdp_disable_irq(uint32 term)
+{
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&mdp_lock, irq_flags);
+	if (!(mdp_irq_mask & term)) {
+		printk(KERN_ERR "%s: MDP IRQ term-0x%x is NOT set, mask=%x irq=%d\n",
+				__func__, term, mdp_irq_mask, mdp_irq_enabled);
+	} else {
+		mdp_irq_mask &= ~term;
+		if (!mdp_irq_mask && mdp_irq_enabled) {
+			mdp_irq_enabled = 0;
+			disable_irq(mdp_irq);
+		}
+	}
+	spin_unlock_irqrestore(&mdp_lock, irq_flags);
+}
+
+void mdp_disable_irq_nosync(uint32 term)
+{
+	spin_lock(&mdp_lock);
+	if (!(mdp_irq_mask & term)) {
+		printk(KERN_ERR "%s: MDP IRQ term-0x%x is NOT set, mask=%x irq=%d\n",
+				__func__, term, mdp_irq_mask, mdp_irq_enabled);
+	} else {
+		mdp_irq_mask &= ~term;
+		if (!mdp_irq_mask && mdp_irq_enabled) {
+			mdp_irq_enabled = 0;
+			disable_irq_nosync(mdp_irq);
+		}
+	}
+	spin_unlock(&mdp_lock);
+}
+
+void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd)
 {
 	/* complete all the writes before starting */
 	wmb();
 
-	if (term == MDP_OVERLAY0_TERM) {
-		mdp_lut_enable(mdp);
-		mdp_writel(mdp, 0, 0x0004);
-	} else if (term == MDP_OVERLAY1_TERM) {
-		mdp_lut_enable(mdp);
-		mdp_writel(mdp, 0, 0x0008);
-	}
-,}
+	/* kick off PPP engine */
+	if (term == MDP_PPP_TERM) {
+		if (mdp_debug[MDP_PPP_BLOCK])
+			jiffies_to_timeval(jiffies, &mdp_ppp_timeval);
 
-int mdp_start_histogram(struct mdp_device *mdp_dev, struct fb_info *info)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-		int ret = 0;
-	int enable = 0;
+		/* let's turn on PPP block */
+		mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
-	mutex_lock(&mdp_hist_mutex);
-	if (mdp_is_hist_start == true) {
-	   PR_DISP_ERR("%s histogram already started\n", __func__);
-	   ret = -EPERM;
-	   goto mdp_hist_start_err;
-	}
+		mdp_enable_irq(term);
+		INIT_COMPLETION(mdp_ppp_comp);
+		mdp_ppp_waiting = TRUE;
+		outpdw(MDP_BASE + 0x30, 0x1000);
+		wait_for_completion_killable(&mdp_ppp_comp);
+		mdp_disable_irq(term);
 
-	mdp_is_hist_start = true;
+		if (mdp_debug[MDP_PPP_BLOCK]) {
+			struct timeval now;
 
-	enable = mdp_readl(mdp, 0x0050);
-	enable |= 0x80;
-	mdp_writel(mdp, enable, 0x0050);
+			jiffies_to_timeval(jiffies, &now);
+			mdp_ppp_timeval.tv_usec =
+			    now.tv_usec - mdp_ppp_timeval.tv_usec;
+			MSM_FB_DEBUG("MDP-PPP: %d\n",
+				    (int)mdp_ppp_timeval.tv_usec);
+		}
+	} else if (term == MDP_DMA2_TERM) {
+		if (mdp_debug[MDP_DMA2_BLOCK]) {
+			MSM_FB_DEBUG("MDP-DMA2: %d\n",
+				    (int)mdp_dma2_timeval.tv_usec);
+			jiffies_to_timeval(jiffies, &mdp_dma2_timeval);
+		}
+		/* DMA update timestamp */
+		mdp_dma2_last_update_time = ktime_get_real();
+		/* let's turn on DMA2 block */
+#ifdef CONFIG_FB_MSM_MDP22
+		outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x0044, 0x0);/* start DMA */
+#else
+		mdp_lut_enable();
 
-	mdp_writel(mdp, 1, 0x95004);
-	mdp_writel(mdp, 1, 0x95000);
+#ifdef CONFIG_FB_MSM_MDP40
+		outpdw(MDP_BASE + 0x000c, 0x0);	/* start DMA */
+#else
+		outpdw(MDP_BASE + 0x0044, 0x0);	/* start DMA */
 
-mdp_hist_start_err:
-	mutex_unlock(&mdp_hist_mutex);
-	return ret;
-}
+#ifdef CONFIG_FB_MSM_MDP303
 
-int mdp_stop_histogram(struct mdp_device *mdp_dev, struct fb_info *info)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	int ret = 0;
-	int enable = 0;
-
-	mutex_lock(&mdp_hist_mutex);
-	if (!mdp_is_hist_start) {
-		PR_DISP_ERR("%s histogram already stopped\n", __func__);
-		ret = -EPERM;
-		goto mdp_hist_stop_err;
-	}
-	mdp_is_hist_start = false;
-
-	/* disable the irq for histogram since we handled it
-	  when the control reaches here */
-
-	enable = mdp_readl(mdp, 0x0050);
-	enable &= ~0x80;
-	mdp_writel(mdp, enable, 0x0050);
-
-mdp_hist_stop_err:
-   mutex_unlock(&mdp_hist_mutex);
-   return ret;
-}
-
-static int mdp_do_histogram(struct mdp_device *mdp_dev, struct mdp_histogram *hist, struct mdp_histogram *out)
-{
-	int ret = 0;
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	if (!hist->frame_cnt || (hist->bin_cnt == 0) || (hist->bin_cnt > MDP_HIST_MAX_BIN))
-	return -EINVAL;
-	mutex_lock(&mdp_hist_mutex);
-	if (!mdp_is_hist_start) {
-		PR_DISP_ERR("%s histogram not started\n", __func__);
-		mutex_unlock(&mdp_hist_mutex);
-		return -EPERM;
-	}
-	enable_mdp_irq(mdp, INTR_DMA_P_HISTOGRAM | INTR_PRIMARY_INTF_UDERRUN);
-	mutex_unlock(&mdp_hist_mutex);
-
-	INIT_COMPLETION(mdp_hist_comp);
-
-	mdp_hist.bin_cnt = hist->bin_cnt;
-	mdp_hist.frame_cnt = hist->frame_cnt;
-	mdp_hist.r = (hist->r) ? mdp_hist_r : 0;
-	mdp_hist.g = (hist->g) ? mdp_hist_g : 0;
-	mdp_hist.b = (hist->b) ? mdp_hist_b : 0;
-
-	wait_for_completion_killable(&mdp_hist_comp);
-
-	out->r = mdp_hist.r;
-	out->g = mdp_hist.g;
-	out->b = mdp_hist.b;
-	disable_mdp_irq(mdp, INTR_DMA_P_HISTOGRAM | INTR_PRIMARY_INTF_UDERRUN);
-	return ret;
-}
-
-int mdp_get_gamma_curvy(struct mdp_device *mdp_dev, struct gamma_curvy *gc)
-{
-	uint32_t *ref_y_gamma;
-	uint32_t *ref_y_shade;
-	uint32_t *ref_bl_lvl;
-	uint32_t *ref_y_lvl;
-	int i = 0;
-
-	if (!mdp_dev->abl_gamma_tbl)
-		return -1;
-
-	ref_y_gamma = mdp_dev->abl_gamma_tbl->ref_y_gamma;
-	ref_y_shade = mdp_dev->abl_gamma_tbl->ref_y_shade;
-	ref_bl_lvl = mdp_dev->abl_gamma_tbl->ref_bl_lvl;
-	ref_y_lvl = mdp_dev->abl_gamma_tbl->ref_y_lvl;
-
-	/* size fo ref_Y_gamma should be the same as size of ref_Y_shade*/
-	if (sizeof(gc->ref_y_gamma) / 4 != sizeof(gc->ref_y_shade) / 4)
-	    return -1;
-
-	/* size fo ref_bl_lvl should be the same as size of ref_Y_lvl*/
-	if (sizeof(gc->ref_bl_lvl) / 4 != sizeof(gc->ref_y_lvl) / 4)
-	    return -1;
-
-	gc->gamma_len = sizeof(gc->ref_y_gamma) / 4;
-	gc->bl_len = sizeof(gc->ref_bl_lvl) / 4;
-
-	for (i = 0; i < gc->gamma_len; i++) {
-		gc->ref_y_gamma[i] = ref_y_gamma[i];
-		gc->ref_y_shade[i] = ref_y_shade[i];
-	}
-
-	for (i = 0; i < gc->bl_len; i++) {
-		gc->ref_bl_lvl[i] = ref_bl_lvl[i];
-		gc->ref_y_lvl[i] = ref_y_lvl[i];
-	}
-	return 0;
-}
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+		mipi_dsi_cmd_mdp_start();
+#endif
 
 #endif
 
-void mdp_set_grp_disp(struct mdp_device *mdp_dev, unsigned disp_id)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-
-	disp_id &= 0xf;
-	mdp_writel(mdp, disp_id, MDP_FULL_BYPASS_WORD43);
+#endif
+#endif
+#ifdef CONFIG_FB_MSM_MDP40
+	} else if (term == MDP_DMA_S_TERM) {
+		mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		outpdw(MDP_BASE + 0x0010, 0x0);	/* start DMA */
+	} else if (term == MDP_DMA_E_TERM) {
+		mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		outpdw(MDP_BASE + 0x0014, 0x0);	/* start DMA */
+	} else if (term == MDP_OVERLAY0_TERM) {
+		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp_lut_enable();
+		outpdw(MDP_BASE + 0x0004, 0);
+	} else if (term == MDP_OVERLAY1_TERM) {
+		mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp_lut_enable();
+		outpdw(MDP_BASE + 0x0008, 0);
+	} else if (term == MDP_OVERLAY2_TERM) {
+		mdp_pipe_ctrl(MDP_OVERLAY2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp_lut_enable();
+		outpdw(MDP_BASE + 0x00D0, 0);
+	}
+#else
+	} else if (term == MDP_DMA_S_TERM) {
+		mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		outpdw(MDP_BASE + 0x0048, 0x0);	/* start DMA */
+	} else if (term == MDP_DMA_E_TERM) {
+		mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		outpdw(MDP_BASE + 0x004C, 0x0);
+	}
+#endif
 }
 
-/* used by output interface drivers like mddi and lcdc */
-int mdp_out_if_register(struct mdp_device *mdp_dev, int interface,
-			void *private_data, uint32_t dma_mask,
-			mdp_dma_start_func_t dma_start)
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+
+static void mdp_pipe_ctrl_workqueue_handler(struct work_struct *work)
 {
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	unsigned long flags = 0;
-	int ret = 0;
-
-	if (interface < 0 || interface >= MSM_MDP_NUM_INTERFACES) {
-		PR_DISP_ERR("%s: invalid interface (%d)\n", __func__, interface);
-		return -EINVAL;
-	}
-
-	spin_lock_irqsave(&mdp->lock, flags);
-
-	if (mdp->out_if[interface].registered) {
-		PR_DISP_ERR("%s: interface (%d) already registered\n", __func__,
-		       interface);
-		ret = -EINVAL;
-		goto done;
-	}
-
-	init_waitqueue_head(&mdp->out_if[interface].dma_waitqueue);
-	mdp->out_if[interface].registered = 1;
-	mdp->out_if[interface].priv = private_data;
-	mdp->out_if[interface].dma_mask = dma_mask;
-	mdp->out_if[interface].dma_start = dma_start;
-	mdp->out_if[interface].dma_cb = NULL;
-
-done:
-	spin_unlock_irqrestore(&mdp->lock, flags);
-	return ret;
+	mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-int mdp_out_if_req_irq(struct mdp_device *mdp_dev, int interface,
-		       uint32_t mask, struct msmfb_callback *cb)
+static int mdp_clk_rate;
+
+#ifdef CONFIG_FB_MSM_NO_MDP_PIPE_CTRL
+
+/*
+ * mdp_clk_disable_unprepare(void) called from thread context
+ */
+static void mdp_clk_disable_unprepare(void)
 {
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	unsigned long flags = 0;
-	int ret = 0;
+	mb();
+	vsync_clk_disable_unprepare();
 
-	if (interface < 0 || interface >= MSM_MDP_NUM_INTERFACES) {
-		PR_DISP_ERR("%s: invalid interface (%d)\n", __func__, interface);
-		BUG();
-	} else if (!mdp->out_if[interface].registered) {
-		PR_DISP_ERR("%s: interface (%d) not registered\n", __func__,
-		       interface);
-		BUG();
-	}
+	if (mdp_clk != NULL)
+		clk_disable_unprepare(mdp_clk);
 
-	spin_lock_irqsave(&mdp->lock, flags);
+	if (mdp_pclk != NULL)
+		clk_disable_unprepare(mdp_pclk);
 
-	if (mask) {
-		ret = locked_enable_mdp_irq(mdp, mask);
-		if (ret) {
-			PR_DISP_ERR("%s: busy\n", __func__);
-			goto done;
-		}
-		mdp->out_if[interface].irq_mask = mask;
-		mdp->out_if[interface].irq_cb = cb;
+	if (mdp_lut_clk != NULL)
+		clk_disable_unprepare(mdp_lut_clk);
+}
+
+/*
+ * mdp_clk_prepare_enable(void) called from thread context
+ */
+static void mdp_clk_prepare_enable(void)
+{
+	if (mdp_clk != NULL)
+		clk_prepare_enable(mdp_clk);
+
+	if (mdp_pclk != NULL)
+		clk_prepare_enable(mdp_pclk);
+
+	if (mdp_lut_clk != NULL)
+		clk_prepare_enable(mdp_lut_clk);
+
+	vsync_clk_prepare_enable();
+}
+
+/*
+ * mdp_clk_ctrl: called from thread context
+ */
+void mdp_clk_ctrl(int on)
+{
+	static int mdp_clk_cnt;
+
+	mutex_lock(&mdp_suspend_mutex);
+	if (on) {
+		if (mdp_clk_cnt == 0)
+			mdp_clk_prepare_enable();
+		mdp_clk_cnt++;
 	} else {
-		locked_disable_mdp_irq(mdp, mask);
-		mdp->out_if[interface].irq_mask = 0;
-		mdp->out_if[interface].irq_cb = NULL;
+		if (mdp_clk_cnt) {
+			mdp_clk_cnt--;
+			if (mdp_clk_cnt == 0)
+				mdp_clk_disable_unprepare();
+		}
+	}
+	mutex_unlock(&mdp_suspend_mutex);
+}
+
+
+
+void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
+		   boolean isr)
+{
+	/* do nothing */
+}
+#else
+void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
+		   boolean isr)
+{
+	boolean mdp_all_blocks_off = TRUE;
+	int i;
+	unsigned long flag;
+	struct msm_fb_panel_data *pdata;
+
+	/*
+	 * It is assumed that if isr = TRUE then start = OFF
+	 * if start = ON when isr = TRUE it could happen that the usercontext
+	 * could turn off the clocks while the interrupt is updating the
+	 * power to ON
+	 */
+	WARN_ON(isr == TRUE && state == MDP_BLOCK_POWER_ON);
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	if (MDP_BLOCK_POWER_ON == state) {
+		atomic_inc(&mdp_block_power_cnt[block]);
+
+		if (MDP_DMA2_BLOCK == block)
+			mdp_in_processing = TRUE;
+	} else {
+		atomic_dec(&mdp_block_power_cnt[block]);
+
+		if (atomic_read(&mdp_block_power_cnt[block]) < 0) {
+			/*
+			* Master has to serve a request to power off MDP always
+			* It also has a timer to power off.  So, in case of
+			* timer expires first and DMA2 finishes later,
+			* master has to power off two times
+			* There shouldn't be multiple power-off request for
+			* other blocks
+			*/
+			if (block != MDP_MASTER_BLOCK) {
+				MSM_FB_INFO("mdp_block_power_cnt[block=%d] \
+				multiple power-off request\n", block);
+			}
+			atomic_set(&mdp_block_power_cnt[block], 0);
+		}
+
+		if (MDP_DMA2_BLOCK == block)
+			mdp_in_processing = FALSE;
+	}
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	/*
+	 * If it's in isr, we send our request to workqueue.
+	 * Otherwise, processing happens in the current context
+	 */
+	if (isr) {
+		if (mdp_current_clk_on) {
+			/* checking all blocks power state */
+			for (i = 0; i < MDP_MAX_BLOCK; i++) {
+				if (atomic_read(&mdp_block_power_cnt[i]) > 0) {
+					mdp_all_blocks_off = FALSE;
+					break;
+				}
+			}
+
+			if (mdp_all_blocks_off) {
+				/* send workqueue to turn off mdp power */
+				queue_delayed_work(mdp_pipe_ctrl_wq,
+						   &mdp_pipe_ctrl_worker,
+						   mdp_timer_duration);
+			}
+		}
+	} else {
+		down(&mdp_pipe_ctrl_mutex);
+		/* checking all blocks power state */
+		for (i = 0; i < MDP_MAX_BLOCK; i++) {
+			if (atomic_read(&mdp_block_power_cnt[i]) > 0) {
+				mdp_all_blocks_off = FALSE;
+				break;
+			}
+		}
+
+		/*
+		 * find out whether a delayable work item is currently
+		 * pending
+		 */
+
+		if (delayed_work_pending(&mdp_pipe_ctrl_worker)) {
+			/*
+			 * try to cancel the current work if it fails to
+			 * stop (which means del_timer can't delete it
+			 * from the list, it's about to expire and run),
+			 * we have to let it run. queue_delayed_work won't
+			 * accept the next job which is same as
+			 * queue_delayed_work(mdp_timer_duration = 0)
+			 */
+			cancel_delayed_work(&mdp_pipe_ctrl_worker);
+		}
+
+		if ((mdp_all_blocks_off) && (mdp_current_clk_on)) {
+			mutex_lock(&mdp_suspend_mutex);
+			if (block == MDP_MASTER_BLOCK || mdp_suspended) {
+				mdp_current_clk_on = FALSE;
+				mb();
+				/* turn off MDP clks */
+				mdp_vsync_clk_disable();
+				for (i = 0; i < pdev_list_cnt; i++) {
+					pdata = (struct msm_fb_panel_data *)
+						pdev_list[i]->dev.platform_data;
+					if (pdata && pdata->clk_func)
+						pdata->clk_func(0);
+				}
+				if (mdp_clk != NULL) {
+					mdp_clk_rate = clk_get_rate(mdp_clk);
+					clk_disable_unprepare(mdp_clk);
+					if (mdp_hw_revision <=
+						MDP4_REVISION_V2_1 &&
+						mdp_clk_rate > 122880000) {
+						clk_set_rate(mdp_clk,
+							 122880000);
+					}
+					MSM_FB_DEBUG("MDP CLK OFF\n");
+				}
+				if (mdp_pclk != NULL) {
+					clk_disable_unprepare(mdp_pclk);
+					MSM_FB_DEBUG("MDP PCLK OFF\n");
+				}
+				if (mdp_lut_clk != NULL)
+					clk_disable_unprepare(mdp_lut_clk);
+			} else {
+				/* send workqueue to turn off mdp power */
+				queue_delayed_work(mdp_pipe_ctrl_wq,
+						   &mdp_pipe_ctrl_worker,
+						   mdp_timer_duration);
+			}
+			mutex_unlock(&mdp_suspend_mutex);
+		} else if ((!mdp_all_blocks_off) && (!mdp_current_clk_on)) {
+			mdp_current_clk_on = TRUE;
+			/* turn on MDP clks */
+			for (i = 0; i < pdev_list_cnt; i++) {
+				pdata = (struct msm_fb_panel_data *)
+					pdev_list[i]->dev.platform_data;
+				if (pdata && pdata->clk_func)
+					pdata->clk_func(1);
+			}
+			if (mdp_clk != NULL) {
+				if (mdp_hw_revision <=
+					MDP4_REVISION_V2_1 &&
+					mdp_clk_rate > 122880000) {
+					clk_set_rate(mdp_clk,
+						 mdp_clk_rate);
+				}
+				clk_prepare_enable(mdp_clk);
+				MSM_FB_DEBUG("MDP CLK ON\n");
+			}
+			if (mdp_pclk != NULL) {
+				clk_prepare_enable(mdp_pclk);
+				MSM_FB_DEBUG("MDP PCLK ON\n");
+			}
+			if (mdp_lut_clk != NULL)
+				clk_prepare_enable(mdp_lut_clk);
+			mdp_vsync_clk_enable();
+		}
+		up(&mdp_pipe_ctrl_mutex);
+	}
+}
+
+void mdp_clk_ctrl(int on)
+{
+	/* do nothing */
+}
+#endif
+
+void mdp_histogram_handle_isr(struct mdp_hist_mgmt *mgmt)
+{
+	uint32 isr, mask;
+	char *base_addr = MDP_BASE + mgmt->base;
+	isr = inpdw(base_addr + MDP_HIST_INTR_STATUS_OFF);
+	mask = inpdw(base_addr + MDP_HIST_INTR_ENABLE_OFF);
+	outpdw(base_addr + MDP_HIST_INTR_CLEAR_OFF, isr);
+	mb();
+	isr &= mask;
+	if (isr & INTR_HIST_RESET_SEQ_DONE)
+		__mdp_histogram_kickoff(mgmt);
+
+	if (isr & INTR_HIST_DONE) {
+		if (waitqueue_active(&mgmt->mdp_hist_comp.wait)) {
+			if (!queue_work(mdp_hist_wq,
+						&mgmt->mdp_histogram_worker)) {
+				pr_err("%s %d- can't queue hist_read\n",
+							 __func__, mgmt->block);
+			}
+		} else {
+			__mdp_histogram_reset(mgmt);
+		}
+	}
+}
+
+#ifndef CONFIG_FB_MSM_MDP40
+irqreturn_t mdp_isr(int irq, void *ptr)
+{
+	uint32 mdp_interrupt = 0;
+	struct mdp_dma_data *dma;
+#ifndef CONFIG_FB_MSM_MDP22
+	struct mdp_hist_mgmt *mgmt = NULL;
+	char *base_addr;
+	int i, ret;
+#endif
+	/* Ensure all the register write are complete */
+	mb();
+
+	mdp_is_in_isr = TRUE;
+	do {
+		mdp_interrupt = inp32(MDP_INTR_STATUS);
+		outp32(MDP_INTR_CLEAR, mdp_interrupt);
+
+		mdp_interrupt &= mdp_intr_mask;
+
+		if (mdp_interrupt & TV_ENC_UNDERRUN) {
+			mdp_interrupt &= ~(TV_ENC_UNDERRUN);
+			mdp_tv_underflow_cnt++;
+		}
+
+		if (!mdp_interrupt)
+			break;
+
+	/*Primary Vsync interrupt*/
+	if (mdp_interrupt & MDP_PRIM_RDPTR)
+		vsync_isr_handler();
+
+		/* DMA3 TV-Out Start */
+		if (mdp_interrupt & TV_OUT_DMA3_START) {
+			/* let's disable TV out interrupt */
+			mdp_intr_mask &= ~TV_OUT_DMA3_START;
+			outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+
+			dma = &dma3_data;
+			if (dma->waiting) {
+				dma->waiting = FALSE;
+				complete(&dma->comp);
+			}
+		}
+#ifndef CONFIG_FB_MSM_MDP22
+	/* Only DMA_P histogram exists for this MDP rev*/
+	if (mdp_interrupt & MDP_HIST_DONE) {
+		ret = mdp_histogram_block2mgmt(MDP_BLOCK_DMA_P, &mgmt);
+		if (!ret)
+			mdp_histogram_handle_isr(mgmt);
+		outp32(MDP_INTR_CLEAR, MDP_HIST_DONE);
 	}
 
-done:
-	spin_unlock_irqrestore(&mdp->lock, flags);
-	return ret;
-}
+	/* LCDC UnderFlow */
+	if (mdp_interrupt & LCDC_UNDERFLOW) {
+		mdp_lcdc_underflow_cnt++;
+		/*when underflow happens HW resets all the histogram
+		  registers that were set before so restore them back
+		  to normal.*/
+		for (i = 0; i < MDP_HIST_MGMT_MAX; i++) {
+			mgmt = mdp_hist_mgmt_array[i];
+			if (!mgmt)
+				continue;
 
-int register_mdp_client(struct class_interface *cint)
-{
-	if (!mdp_class) {
-		PR_DISP_ERR("mdp: no mdp_class when registering mdp client\n");
-		return -ENODEV;
+			base_addr = MDP_BASE + mgmt->base;
+			outpdw(base_addr + 0x010, 1);
+			outpdw(base_addr + 0x01C, INTR_HIST_DONE |
+						INTR_HIST_RESET_SEQ_DONE);
+			mgmt->mdp_is_hist_valid = FALSE;
+			__mdp_histogram_reset(mgmt);
+		}
 	}
-	cint->class = mdp_class;
-	return class_interface_register(cint);
+
+		/* LCDC Frame Start */
+		if (mdp_interrupt & LCDC_FRAME_START) {
+			dma = &dma2_data;
+			if (dma->waiting) {
+				dma->waiting = FALSE;
+				complete(&dma->comp);
+			}
+
+			if (vsync_cntrl.vsync_irq_enabled)
+				vsync_isr_handler();
+
+			if (!vsync_cntrl.vsync_irq_enabled && !(dma->waiting)) {
+				mdp_intr_mask &= ~LCDC_FRAME_START;
+				outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+			}
+		}
+
+		/* DMA2 LCD-Out Complete */
+		if (mdp_interrupt & MDP_DMA_S_DONE) {
+			dma = &dma_s_data;
+			dma->busy = FALSE;
+			mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF,
+				      TRUE);
+			complete(&dma->comp);
+		}
+		/* DMA_E LCD-Out Complete */
+		if (mdp_interrupt & MDP_DMA_E_DONE) {
+			dma = &dma_s_data;
+			dma->busy = FALSE;
+			mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_OFF,
+				TRUE);
+			complete(&dma->comp);
+		}
+
+#endif
+
+		/* DMA2 LCD-Out Complete */
+		if (mdp_interrupt & MDP_DMA_P_DONE) {
+			struct timeval now;
+
+			mdp_dma2_last_update_time = ktime_sub(ktime_get_real(),
+				mdp_dma2_last_update_time);
+			if (mdp_debug[MDP_DMA2_BLOCK]) {
+				jiffies_to_timeval(jiffies, &now);
+				mdp_dma2_timeval.tv_usec =
+				    now.tv_usec - mdp_dma2_timeval.tv_usec;
+			}
+#ifndef CONFIG_FB_MSM_MDP303
+			dma = &dma2_data;
+			dma->busy = FALSE;
+			mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF,
+				      TRUE);
+			complete(&dma->comp);
+#else
+			if (mdp_prim_panel_type == MIPI_CMD_PANEL) {
+				dma = &dma2_data;
+				dma->busy = FALSE;
+				mdp_pipe_ctrl(MDP_DMA2_BLOCK,
+					MDP_BLOCK_POWER_OFF, TRUE);
+				complete(&dma->comp);
+			}
+#endif
+		}
+		/* PPP Complete */
+		if (mdp_interrupt & MDP_PPP_DONE) {
+#ifdef	CONFIG_FB_MSM_MDP31
+			MDP_OUTP(MDP_BASE + 0x00100, 0xFFFF);
+#endif
+			mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+			if (mdp_ppp_waiting) {
+				mdp_ppp_waiting = FALSE;
+				complete(&mdp_ppp_comp);
+			}
+		}
+	} while (1);
+
+	mdp_is_in_isr = FALSE;
+
+	return IRQ_HANDLED;
 }
+#endif
 
-static ssize_t mdp_reg_addr_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
+static void mdp_drv_init(void)
 {
-	int ret;
-
-	ret = sprintf(buf, "0x%x\n", mdp_reg_addr);
-
-	return ret;
-}
-
-static ssize_t mdp_reg_addr_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	unsigned reg_addr;
-
-	sscanf(buf, "%x", &reg_addr);
-
-	if (reg_addr == 0)
-		return -EINVAL;
-
-	mdp_reg_addr = reg_addr;
-
-	return count;
-}
-
-static DEVICE_ATTR(reg_addr, 0644,  mdp_reg_addr_show, mdp_reg_addr_store);
-
-static ssize_t mdp_reg_val_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct mdp_device *mdp_dev = container_of(dev, struct mdp_device, dev);
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	int ret;
-
-	if (mdp_reg_addr == 0)
-		return -EINVAL;
-
-	mdp_reg_val = mdp_readl(mdp, mdp_reg_addr);
-	ret = sprintf(buf, "0x%x\n", mdp_reg_val);
-	return ret;
-}
-
-static ssize_t mdp_reg_val_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct mdp_device *mdp_dev = container_of(dev, struct mdp_device, dev);
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	unsigned reg_val, val;
-	unsigned mask = 0xffffffff;
-
-	if (mdp_reg_addr == 0)
-		return -EINVAL;
-
-	sscanf(buf, "%x %x", &reg_val, &mask);
-	mdp_reg_val = reg_val;
-	val = mdp_readl(mdp, mdp_reg_addr);
-	val &= ~mask;
-	mdp_reg_val &= mask;
-	mdp_reg_val |= val;
-	mdp_writel(mdp, mdp_reg_val, mdp_reg_addr);
-	return count;
-}
-
-static DEVICE_ATTR(reg_val, 0644,  mdp_reg_val_show, mdp_reg_val_store);
-
-
-static int
-mdp_write_reg_mask(struct mdp_info *mdp, uint32_t reg, uint32_t val, uint32_t mask)
-{
-	uint32_t oldval, newval;
-
-	oldval = mdp_readl(mdp, reg);
-
-	oldval &= (~mask);
-	val &= mask;
-	newval = oldval | val;
-
-	mdp_writel(mdp, newval, reg);
-
-	return 0;
-
-}
-
-static int
-mdp_write_regs(struct mdp_info *mdp, const struct mdp_reg *reglist, int size)
-{
-	const struct mdp_reg *reg_seq = reglist;
 	int i;
 
-	for (i = 0; i < size; i++) {
-		if (reg_seq[i].mask == 0x0)
-			mdp_writel(mdp, reg_seq[i].val, reg_seq[i].reg);
-		else
-			mdp_write_reg_mask(mdp, reg_seq[i].reg, reg_seq[i].val, reg_seq[i].mask);
+	for (i = 0; i < MDP_MAX_BLOCK; i++) {
+		mdp_debug[i] = 0;
 	}
 
+	/* initialize spin lock and workqueue */
+	spin_lock_init(&mdp_spin_lock);
+	mdp_dma_wq = create_singlethread_workqueue("mdp_dma_wq");
+	mdp_vsync_wq = create_singlethread_workqueue("mdp_vsync_wq");
+	mdp_hist_wq = create_singlethread_workqueue("mdp_hist_wq");
+	mdp_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq");
+	INIT_DELAYED_WORK(&mdp_pipe_ctrl_worker,
+			  mdp_pipe_ctrl_workqueue_handler);
+
+	/* initialize semaphore */
+	init_completion(&mdp_ppp_comp);
+	sema_init(&mdp_ppp_mutex, 1);
+	sema_init(&mdp_pipe_ctrl_mutex, 1);
+
+	dma2_data.busy = FALSE;
+	dma2_data.dmap_busy = FALSE;
+	dma2_data.waiting = FALSE;
+	init_completion(&dma2_data.comp);
+	init_completion(&dma2_data.dmap_comp);
+	sema_init(&dma2_data.mutex, 1);
+	mutex_init(&dma2_data.ov_mutex);
+
+	dma3_data.busy = FALSE;
+	dma3_data.waiting = FALSE;
+	init_completion(&dma3_data.comp);
+	sema_init(&dma3_data.mutex, 1);
+
+	dma_s_data.busy = FALSE;
+	dma_s_data.waiting = FALSE;
+	init_completion(&dma_s_data.comp);
+	sema_init(&dma_s_data.mutex, 1);
+
+#ifndef CONFIG_FB_MSM_MDP303
+	dma_e_data.busy = FALSE;
+	dma_e_data.waiting = FALSE;
+	init_completion(&dma_e_data.comp);
+	mutex_init(&dma_e_data.ov_mutex);
+#endif
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+	dma_wb_data.busy = FALSE;
+	dma_wb_data.waiting = FALSE;
+	init_completion(&dma_wb_data.comp);
+	mutex_init(&dma_wb_data.ov_mutex);
+#endif
+
+	/* initializing mdp power block counter to 0 */
+	for (i = 0; i < MDP_MAX_BLOCK; i++) {
+		atomic_set(&mdp_block_power_cnt[i], 0);
+	}
+	INIT_WORK(&(vsync_cntrl.vsync_work), send_vsync_work);
+#ifdef MSM_FB_ENABLE_DBGFS
+	{
+		struct dentry *root;
+		char sub_name[] = "mdp";
+
+		root = msm_fb_get_debugfs_root();
+		if (root != NULL) {
+			mdp_dir = debugfs_create_dir(sub_name, root);
+
+			if (mdp_dir) {
+				msm_fb_debugfs_file_create(mdp_dir,
+					"dma2_update_time_in_usec",
+					(u32 *) &mdp_dma2_update_time_in_usec);
+				msm_fb_debugfs_file_create(mdp_dir,
+					"vs_rdcnt_slow",
+					(u32 *) &mdp_lcd_rd_cnt_offset_slow);
+				msm_fb_debugfs_file_create(mdp_dir,
+					"vs_rdcnt_fast",
+					(u32 *) &mdp_lcd_rd_cnt_offset_fast);
+				msm_fb_debugfs_file_create(mdp_dir,
+					"mdp_usec_diff_threshold",
+					(u32 *) &mdp_usec_diff_threshold);
+				msm_fb_debugfs_file_create(mdp_dir,
+					"mdp_current_clk_on",
+					(u32 *) &mdp_current_clk_on);
+#ifdef CONFIG_FB_MSM_LCDC
+				msm_fb_debugfs_file_create(mdp_dir,
+					"lcdc_start_x",
+					(u32 *) &first_pixel_start_x);
+				msm_fb_debugfs_file_create(mdp_dir,
+					"lcdc_start_y",
+					(u32 *) &first_pixel_start_y);
+#endif
+			}
+		}
+	}
+#endif
+}
+
+static int mdp_probe(struct platform_device *pdev);
+static int mdp_remove(struct platform_device *pdev);
+
+static int mdp_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
 	return 0;
 }
 
-#ifdef CONFIG_MSM_MDP40
-static int mdp_hw_version(void)
+static int mdp_runtime_resume(struct device *dev)
 {
-	int mdp_hw_revision;
-	char *cp;
-	uint32_t *hp;
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
 
+static struct dev_pm_ops mdp_dev_pm_ops = {
+	.runtime_suspend = mdp_runtime_suspend,
+	.runtime_resume = mdp_runtime_resume,
+};
+
+
+static struct platform_driver mdp_driver = {
+	.probe = mdp_probe,
+	.remove = mdp_remove,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+	.suspend = mdp_suspend,
+	.resume = NULL,
+#endif
+	.shutdown = NULL,
+	.driver = {
+		/*
+		 * Driver name must match the device name added in
+		 * platform.c.
+		 */
+		.name = "mdp",
+		.pm = &mdp_dev_pm_ops,
+	},
+};
+
+static int mdp_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+
+	mdp_histogram_ctrl_all(FALSE);
+
+	if (mfd->panel.type == MIPI_CMD_PANEL)
+		mdp4_dsi_cmd_off(pdev);
+	else if (mfd->panel.type == MIPI_VIDEO_PANEL)
+		mdp4_dsi_video_off(pdev);
+	else if (mfd->panel.type == HDMI_PANEL ||
+			mfd->panel.type == LCDC_PANEL ||
+			mfd->panel.type == LVDS_PANEL)
+		mdp4_lcdc_off(pdev);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	ret = panel_next_off(pdev);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	if (mdp_rev >= MDP_REV_41 && mfd->panel.type == MIPI_CMD_PANEL)
+		mdp_dsi_cmd_overlay_suspend(mfd);
+	return ret;
+}
+
+static int mdp_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_data_type *mfd;
+	mfd = platform_get_drvdata(pdev);
+
+#ifdef CONFIG_FB_MSM_MDP40
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	mdp_clk_ctrl(1);
+	mdp4_hw_init();
+	outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+	if (mfd->panel.type == MIPI_CMD_PANEL) {
+		mdp_vsync_cfg_regs(mfd, FALSE);
+		mdp4_dsi_cmd_on(pdev);
+	} else if (mfd->panel.type == MIPI_VIDEO_PANEL)
+		mdp4_dsi_video_on(pdev);
+	else if (mfd->panel.type == HDMI_PANEL ||
+			mfd->panel.type == LCDC_PANEL ||
+			mfd->panel.type == LVDS_PANEL)
+		mdp4_lcdc_on(pdev);
+
+	mdp_clk_ctrl(0);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+#endif
+
+	if ((mdp_rev == MDP_REV_303) &&
+			(mfd->panel.type == MIPI_CMD_PANEL))
+		vsync_cntrl.dev = mfd->fbi->dev;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	ret = panel_next_on(pdev);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	mdp_histogram_ctrl_all(TRUE);
+
+	return ret;
+}
+
+static int mdp_resource_initialized;
+static struct msm_panel_common_pdata *mdp_pdata;
+
+uint32 mdp_hw_revision;
+
+/*
+ * mdp_hw_revision:
+ * 0 == V1
+ * 1 == V2
+ * 2 == V2.1
+ *
+ */
+void mdp_hw_version(void)
+{
+	char *cp;
+	uint32 *hp;
+
+	if (mdp_pdata == NULL)
+		return;
 
 	mdp_hw_revision = MDP4_REVISION_NONE;
+	if (mdp_pdata->hw_revision_addr == 0)
+		return;
 
 	/* tlmmgpio2 shadow */
-	cp = (char *)ioremap(0xac001270, 0x16);
+	cp = (char *)ioremap(mdp_pdata->hw_revision_addr, 0x16);
 
 	if (cp == NULL)
-		return -1;
+		return;
 
-	hp = (uint32_t *)cp;	/* HW_REVISION_NUMBER */
+	hp = (uint32 *)cp;	/* HW_REVISION_NUMBER */
 	mdp_hw_revision = *hp;
 	iounmap(cp);
 
 	mdp_hw_revision >>= 28;	/* bit 31:28 */
 	mdp_hw_revision &= 0x0f;
 
-	printk(KERN_INFO "%s: mdp_hw_revision=%x\n",
+	MSM_FB_DEBUG("%s: mdp_hw_revision=%x\n",
 				__func__, mdp_hw_revision);
-	return mdp_hw_revision;
+}
+
+#ifdef CONFIG_MSM_BUS_SCALING
+static uint32_t mdp_bus_scale_handle;
+int mdp_bus_scale_update_request(uint32_t index)
+{
+	if (!mdp_pdata && (!mdp_pdata->mdp_bus_scale_table
+	     || index > (mdp_pdata->mdp_bus_scale_table->num_usecases - 1))) {
+		printk(KERN_ERR "%s invalid table or index\n", __func__);
+		return -EINVAL;
+	}
+	if (mdp_bus_scale_handle < 1) {
+		printk(KERN_ERR "%s invalid bus handle\n", __func__);
+		return -EINVAL;
+	}
+	return msm_bus_scale_client_update_request(mdp_bus_scale_handle,
+							index);
 }
 #endif
-
-#ifdef DEBUG_OVERLAY
-int mdp4_overlay_debugfs_init(void);
-#endif
-
-#ifdef CONFIG_MDP4_HW_VSYNC
-void mdp_config_vsync(struct mdp_info *mdp)
+DEFINE_MUTEX(mdp_clk_lock);
+int mdp_set_core_clk(u32 rate)
 {
-	int total_porch_line;
-	int vsync_cnt_cfg, vsync_cnt_cfg_dem, mdp_vsync_clk_speed_hz;
-	struct clk *mdp_vsync_clk = NULL;
-
-	total_porch_line = mdp->mdp_dev.back_porch +
-				mdp->mdp_dev.front_porch +
-				mdp->mdp_dev.pulse_width;
-
-	mdp->total_lcd_line =
-		total_porch_line + mdp->mdp_dev.yres;
-
-	mdp_vsync_clk = clk_get(NULL, "mdp_vsync_clk");
-	mdp_vsync_clk_speed_hz = clk_get_rate(mdp_vsync_clk);
-
-	vsync_cnt_cfg_dem = 6000 * /*panel_info.lcd.refx100*/ mdp->total_lcd_line / 100;
-	vsync_cnt_cfg =	(mdp_vsync_clk_speed_hz) / vsync_cnt_cfg_dem;
-
-	PR_DISP_INFO("total_lcd_line %x, vsync_cnt_cfg %x\n", mdp->total_lcd_line, vsync_cnt_cfg);
-	mdp_writel(mdp, ((mdp->total_lcd_line-1)<<21)|(3<<19)|(vsync_cnt_cfg), 0x100/*MDP_SYNC_CONFIG_0*/);
-/*	mdp_writel(mdp, (820<<21)|(3<<19)|(499), 0x100 //MDP_SYNC_CONFIG_0);*/
-
-	/* threshold */
-	mdp_writel(mdp, (4<<16) | 1, 0x200/*MDP_SYNC_THRESH_0*/);
-
-	/*
-	 * external vsync source pulse width and
-	 * polarity flip
-	 */
-	mdp_writel(mdp, 1, 0x118);
-
-	/* line counter init value at the next pulse */
-	mdp_writel(mdp, mdp->mdp_dev.yres, 0x128);
-
-
-/*	mdp_writel(mdp, 795, 0x210//MDP_PRIM_START_POS);*/
-/*	mdp_writel(mdp, 1, 0x20c//MDP_TEAR_CHECK_EN);*/
-	PR_DISP_INFO("vsync_clk %d\n", (int)clk_get_rate(mdp->vsync_clk));
-}
-#endif
-
-int mdp_probe(struct platform_device *pdev)
-{
-	struct resource *resource;
 	int ret = -EINVAL;
-	struct mdp_info *mdp;
-	struct msm_mdp_platform_data *pdata = pdev->dev.platform_data;
-
-
-	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!resource) {
-		PR_DISP_ERR("mdp: can not get mdp mem resource!\n");
-		return -ENOMEM;
-	}
-
-	mdp = kzalloc(sizeof(struct mdp_info), GFP_KERNEL);
-	if (!mdp)
-		return -ENOMEM;
-
-	spin_lock_init(&mdp->lock);
-
-	mdp->irq = platform_get_irq(pdev, 0);
-	if (mdp->irq < 0) {
-		PR_DISP_ERR("mdp: can not get mdp irq\n");
-		ret = mdp->irq;
-		goto error_get_irq;
-	}
-
-	mdp->base = ioremap(resource->start,
-			    resource->end - resource->start);
-	if (mdp->base == 0) {
-		PR_DISP_ERR("msmfb: cannot allocate mdp regs!\n");
-		ret = -ENOMEM;
-		goto error_ioremap;
-	}
-
-	mdp->mdp_dev.dma = mdp_dma;
-	mdp->mdp_dev.dma_wait = mdp_dma_wait;
-	mdp->mdp_dev.blit = mdp_blit;
-#ifdef CONFIG_FB_MSM_OVERLAY
-	mdp->mdp_dev.overlay_get = mdp4_overlay_get;
-	mdp->mdp_dev.overlay_set = mdp4_overlay_set;
-	mdp->mdp_dev.overlay_unset = mdp4_overlay_unset;
-	mdp->mdp_dev.overlay_play = mdp4_overlay_play;
-#endif
-	mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp;
-	mdp->mdp_dev.set_output_format = mdp_set_output_format;
-	mdp->mdp_dev.set_panel_size = mdp_set_panel_size;
-	mdp->mdp_dev.check_output_format = mdp_check_output_format;
-	mdp->mdp_dev.configure_dma = mdp_configure_dma;
-
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-	mdp->mdp_dev.lut_update = mdp_lut_update;
-	mdp->mdp_dev.do_histogram = mdp_do_histogram;
-	mdp->mdp_dev.start_histogram = mdp_start_histogram;
-	mdp->mdp_dev.stop_histogram = mdp_stop_histogram;
-	mdp->mdp_dev.get_gamma_curvy = mdp_get_gamma_curvy;
-#endif
-	mdp->enable_irq = enable_mdp_irq;
-	mdp->disable_irq = disable_mdp_irq;
-	mdp->write_regs = mdp_write_regs;
-
-	mdp->mdp_dev.fb0 = NULL;
-	mdp->mdp_dev.fb1 = NULL;
-	if (pdata == NULL || pdata->overrides == 0)
-		mdp->mdp_dev.overrides = 0;
-	else if (pdata->overrides)
-		mdp->mdp_dev.overrides = pdata->overrides;
-
-	if (pdata != NULL)
-		pdata->mdp_dev = &mdp->mdp_dev;
-
-	if (pdata == NULL || pdata->color_format == 0)
-		mdp->mdp_dev.color_format = MSM_MDP_OUT_IF_FMT_RGB565;
-	else if (pdata->color_format)
-		mdp->mdp_dev.color_format = pdata->color_format;
-#ifdef CONFIG_MDP4_HW_VSYNC
-	if (pdata == NULL || pdata->xres == 0) {
-		mdp->mdp_dev.xres = 0;
-		mdp->mdp_dev.yres = 0;
-		mdp->mdp_dev.back_porch = 0;
-		mdp->mdp_dev.front_porch = 0;
-		mdp->mdp_dev.pulse_width = 0;
-	} else if (pdata->xres) {
-		mdp->mdp_dev.xres = pdata->xres;
-		mdp->mdp_dev.yres = pdata->yres;
-		mdp->mdp_dev.back_porch = pdata->back_porch;
-		mdp->mdp_dev.front_porch = pdata->front_porch;
-		mdp->mdp_dev.pulse_width = pdata->pulse_width;
-	}
-#endif
-#ifdef CONFIG_MSM_MDP40
-	mdp->hw_version = mdp_hw_version();
-
-	if (mdp->hw_version < MDP4_REVISION_V2_1 &&
-		mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) {
-		ret = mdp_out_if_register(&mdp->mdp_dev,
-			MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE
-			| MDP_DMA_S_DONE, mdp4_mddi_overlay);
-	} else {
-		ret = mdp_out_if_register(&mdp->mdp_dev,
-			MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE,
-			mdp4_mddi_overlay);
-	}
-#else
-	if (pdata == NULL || pdata->dma_channel == MDP_DMA_P) {
-		ret = mdp_out_if_register(&mdp->mdp_dev,
-				MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_P_DONE,
-				mdp_dma_to_mddi);
-	} else if (pdata->dma_channel == MDP_DMA_S) {
-		ret = mdp_out_if_register(&mdp->mdp_dev,
-				MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_S_DONE,
-				mdp_dmas_to_mddi);
-	}
-#endif
-
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-	if (mdp->mdp_dev.overrides & MSM_MDP_ABL_ENABLE)
-		mdp->mdp_dev.abl_gamma_tbl = pdata->abl_gamma_tbl;
-#endif
+	if (mdp_clk)
+		ret = clk_set_rate(mdp_clk, rate);
 	if (ret)
-		goto error_mddi_pmdh_register;
-
-	mdp->clk = clk_get(&pdev->dev, "mdp_clk");
-	if (IS_ERR(mdp->clk)) {
-		PR_DISP_INFO("mdp: failed to get mdp clk");
-		ret = PTR_ERR(mdp->clk);
-		goto error_get_mdp_clk;
-	}
-
-	mdp->ebi1_clk = clk_get(NULL, "ebi1_clk");
-
-	if (IS_ERR(mdp->ebi1_clk)) {
-			PR_DISP_ERR("mdp: failed to get ebi1 clk\n");
-			ret = PTR_ERR(mdp->ebi1_clk);
-			goto error_get_ebi1_clk;
-	}
-#ifdef CONFIG_MDP4_HW_VSYNC
-	mdp->vsync_clk = clk_get(&pdev->dev, "mdp_vsync_clk");
-	if (IS_ERR(mdp->vsync_clk)) {
-		PR_DISP_INFO("mdp: failed to get mdp vsync clk");
-		ret = PTR_ERR(mdp->vsync_clk);
-		goto error_get_mdp_clk;
-	}
-#endif
-	ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
-	if (ret)
-		goto error_request_irq;
-	disable_irq(mdp->irq);
-
-	clk_enable(mdp->clk);
-	mdp_clk_to_disable_later = mdp->clk;
-#ifdef CONFIG_MDP4_HW_VSYNC
-	clk_enable(mdp->vsync_clk);
-	mdp_vsync_clk_to_disable_later = mdp->vsync_clk;
-#endif
-
-#ifdef CONFIG_MSM_MDP40
-	if (mdp_readl(mdp, 0xc0000))
-		mdp_writel(mdp, 0x8, 0x0038);
+		pr_err("%s unable to set mdp clk rate", __func__);
 	else
-		mdp_writel(mdp, 0xa, 0x0038);
-#endif
-
-#ifdef CONFIG_MSM_MDP40
-	mdp4_hw_init(mdp);
-#else
-	mdp_hw_init(mdp);
-#endif
-
-#ifdef CONFIG_MDP4_HW_VSYNC
-	mdp_config_vsync(mdp);
-#endif
-
-
-#if defined CONFIG_MSM_MDP302
-	/* enable the tearing check in MDP */
-	if (pdata != NULL && pdata->tearing_check)
-		mdp_check_tearing(mdp, pdata);
-#endif
-	/* register mdp device */
-	mdp->mdp_dev.dev.parent = &pdev->dev;
-	mdp->mdp_dev.dev.class = mdp_class;
-	dev_set_name(&mdp->mdp_dev.dev, "mdp%d", pdev->id);
-
-	/* if you can remove the platform device you'd have to implement
-	 * this:
-	mdp_dev.release = mdp_class; */
-
-	ret = device_register(&mdp->mdp_dev.dev);
-	if (ret)
-		goto error_device_register;
-
-	ret = device_create_file(&mdp->mdp_dev.dev, &dev_attr_reg_addr);
-	ret = device_create_file(&mdp->mdp_dev.dev, &dev_attr_reg_val);
-
-	setup_timer(&mdp->standby_timer, mdp_do_standby_timer, (unsigned long)mdp);
-	setup_timer(&mdp->dma_timer, mdp_do_dma_timer, (unsigned long)mdp);
-
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-	init_completion(&mdp_hist_comp);
-#endif
-	PR_DISP_INFO("%s: initialized\n", __func__);
-
-#ifdef DEBUG_OVERLAY
-	mdp4_overlay_debugfs_init();
-#endif
-	return 0;
-
-error_device_register:
-	free_irq(mdp->irq, mdp);
-error_request_irq:
-	clk_put(mdp->ebi1_clk);
-error_get_ebi1_clk:
-	clk_put(mdp->clk);
-error_get_mdp_clk:
-error_mddi_pmdh_register:
-	iounmap(mdp->base);
-error_ioremap:
-error_get_irq:
-	kfree(mdp);
+		pr_debug("%s mdp clk rate to be set %d: actual rate %ld\n",
+			__func__, rate, clk_get_rate(mdp_clk));
 	return ret;
 }
 
-static struct platform_driver msm_mdp_driver = {
-	.probe = mdp_probe,
-	.driver = {.name = "msm_mdp"},
-};
-
-static int __init mdp_lateinit(void)
+int mdp_clk_round_rate(u32 rate)
 {
-	if (mdp_clk_to_disable_later)
-		clk_disable(mdp_clk_to_disable_later);
-#ifdef CONFIG_MDP4_HW_VSYNC
-	if (mdp_vsync_clk_to_disable_later)
-		clk_disable(mdp_vsync_clk_to_disable_later);
+	return clk_round_rate(mdp_clk, rate);
+}
+
+unsigned long mdp_get_core_clk(void)
+{
+	unsigned long clk_rate = 0;
+	if (mdp_clk) {
+		mutex_lock(&mdp_clk_lock);
+		clk_rate = clk_get_rate(mdp_clk);
+		mutex_unlock(&mdp_clk_lock);
+	}
+
+	return clk_rate;
+}
+
+static int mdp_irq_clk_setup(struct platform_device *pdev,
+	char cont_splashScreen)
+{
+	int ret;
+
+#ifdef CONFIG_FB_MSM_MDP40
+	ret = request_irq(mdp_irq, mdp4_isr, IRQF_DISABLED, "MDP", 0);
+#else
+	ret = request_irq(mdp_irq, mdp_isr, IRQF_DISABLED, "MDP", 0);
+#endif
+	if (ret) {
+		printk(KERN_ERR "mdp request_irq() failed!\n");
+		return ret;
+	}
+	disable_irq(mdp_irq);
+
+	hdmi_pll_fs = regulator_get(&pdev->dev, "hdmi_pll_fs");
+	if (IS_ERR(hdmi_pll_fs)) {
+		hdmi_pll_fs = NULL;
+	} else {
+		if (mdp_rev != MDP_REV_44) {
+			ret = regulator_set_voltage(hdmi_pll_fs, 1800000,
+				1800000);
+			if (ret) {
+				pr_err("set_voltage failed for hdmi_pll_fs, ret=%d\n",
+					ret);
+			}
+		}
+	}
+
+	footswitch = regulator_get(NULL, "fs_mdp");
+	if (IS_ERR(footswitch)) {
+		footswitch = NULL;
+	} else {
+		if (hdmi_pll_fs)
+			regulator_enable(hdmi_pll_fs);
+
+		regulator_enable(footswitch);
+		mdp_footswitch_on = 1;
+
+		if (mdp_rev == MDP_REV_42 && !cont_splashScreen) {
+			regulator_disable(footswitch);
+			msleep(20);
+			regulator_enable(footswitch);
+		}
+		if (hdmi_pll_fs)
+			regulator_disable(hdmi_pll_fs);
+	}
+
+	mdp_clk = clk_get(&pdev->dev, "core_clk");
+	if (IS_ERR(mdp_clk)) {
+		ret = PTR_ERR(mdp_clk);
+		printk(KERN_ERR "can't get mdp_clk error:%d!\n", ret);
+		free_irq(mdp_irq, 0);
+		return ret;
+	}
+
+	mdp_pclk = clk_get(&pdev->dev, "iface_clk");
+	if (IS_ERR(mdp_pclk))
+		mdp_pclk = NULL;
+
+	if (mdp_rev == MDP_REV_42) {
+		mdp_lut_clk = clk_get(&pdev->dev, "lut_clk");
+		if (IS_ERR(mdp_lut_clk)) {
+			ret = PTR_ERR(mdp_lut_clk);
+			pr_err("can't get mdp_clk error:%d!\n", ret);
+			clk_put(mdp_clk);
+			free_irq(mdp_irq, 0);
+			return ret;
+		}
+	} else {
+		mdp_lut_clk = NULL;
+	}
+
+#ifdef CONFIG_FB_MSM_MDP40
+
+	if (mdp_pdata)
+		mdp_max_clk = mdp_pdata->mdp_max_clk;
+	else
+		pr_err("%s cannot get mdp max clk!\n", __func__);
+
+	if (!mdp_max_clk)
+		pr_err("%s mdp max clk is zero!\n", __func__);
+
+	if (cont_splashScreen)
+		mdp_clk_rate = clk_get_rate(mdp_clk);
+	else
+		mdp_clk_rate = mdp_max_clk;
+
+	mutex_lock(&mdp_clk_lock);
+	clk_set_rate(mdp_clk, mdp_clk_rate);
+	if (mdp_lut_clk != NULL)
+		clk_set_rate(mdp_lut_clk, mdp_clk_rate);
+	mutex_unlock(&mdp_clk_lock);
+
+	MSM_FB_DEBUG("mdp_clk: mdp_clk=%d\n", (int)clk_get_rate(mdp_clk));
 #endif
 	return 0;
 }
 
-static int __init mdp_init(void)
+static int mdp_probe(struct platform_device *pdev)
 {
-	mdp_class = class_create(THIS_MODULE, "msm_mdp");
-	if (IS_ERR(mdp_class)) {
-		PR_DISP_ERR("Error creating mdp class\n");
-		return PTR_ERR(mdp_class);
+	struct platform_device *msm_fb_dev = NULL;
+	struct msm_fb_data_type *mfd;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc;
+	resource_size_t  size ;
+	unsigned long flag;
+#ifdef CONFIG_FB_MSM_MDP40
+	int intf, if_no;
+#endif
+#if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
+	struct mipi_panel_info *mipi;
+#endif
+	static int contSplash_update_done;
+
+	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
+		mdp_init_pdev = pdev;
+		mdp_pdata = pdev->dev.platform_data;
+
+		size =  resource_size(&pdev->resource[0]);
+		msm_mdp_base = ioremap(pdev->resource[0].start, size);
+
+		MSM_FB_DEBUG("MDP HW Base phy_Address = 0x%x virt = 0x%x\n",
+			(int)pdev->resource[0].start, (int)msm_mdp_base);
+
+		if (unlikely(!msm_mdp_base))
+			return -ENOMEM;
+
+		mdp_irq = platform_get_irq(pdev, 0);
+		if (mdp_irq < 0) {
+			pr_err("mdp: can not get mdp irq\n");
+			return -ENOMEM;
+		}
+
+		mdp_rev = mdp_pdata->mdp_rev;
+
+		rc = mdp_irq_clk_setup(pdev, mdp_pdata->cont_splash_enabled);
+
+		if (rc)
+			return rc;
+
+		mdp_clk_ctrl(1);
+
+		mdp_hw_version();
+
+		/* initializing mdp hw */
+#ifdef CONFIG_FB_MSM_MDP40
+		if (!(mdp_pdata->cont_splash_enabled))
+			mdp4_hw_init();
+#else
+		mdp_hw_init();
+#endif
+
+#ifdef CONFIG_FB_MSM_OVERLAY
+		mdp_hw_cursor_init();
+#endif
+		mdp_clk_ctrl(0);
+
+		mdp_resource_initialized = 1;
+		return 0;
 	}
-	return platform_driver_register(&msm_mdp_driver);
+
+	if (!mdp_resource_initialized)
+		return -EPERM;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	msm_fb_dev = platform_device_alloc("msm_fb", pdev->id);
+	if (!msm_fb_dev)
+		return -ENOMEM;
+
+	/* link to the latest pdev */
+	mfd->pdev = msm_fb_dev;
+	mfd->mdp_rev = mdp_rev;
+
+	if (mdp_pdata) {
+		if (mdp_pdata->cont_splash_enabled) {
+			mfd->cont_splash_done = 0;
+			if (!contSplash_update_done) {
+				mdp_pipe_ctrl(MDP_CMD_BLOCK,
+					MDP_BLOCK_POWER_ON, FALSE);
+				contSplash_update_done = 1;
+			}
+		} else
+			mfd->cont_splash_done = 1;
+	}
+
+	mfd->ov0_wb_buf = MDP_ALLOC(sizeof(struct mdp_buf_type));
+	mfd->ov1_wb_buf = MDP_ALLOC(sizeof(struct mdp_buf_type));
+	memset((void *)mfd->ov0_wb_buf, 0, sizeof(struct mdp_buf_type));
+	memset((void *)mfd->ov1_wb_buf, 0, sizeof(struct mdp_buf_type));
+
+	if (mdp_pdata) {
+		mfd->ov0_wb_buf->size = mdp_pdata->ov0_wb_size;
+		mfd->ov1_wb_buf->size = mdp_pdata->ov1_wb_size;
+		mfd->mem_hid = mdp_pdata->mem_hid;
+	} else {
+		mfd->ov0_wb_buf->size = 0;
+		mfd->ov1_wb_buf->size = 0;
+		mfd->mem_hid = 0;
+	}
+
+	/* initialize Post Processing data*/
+	mdp_hist_lut_init();
+	mdp_histogram_init();
+
+	/* add panel data */
+	if (platform_device_add_data
+	    (msm_fb_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		printk(KERN_ERR "mdp_probe: platform_device_add_data failed!\n");
+		rc = -ENOMEM;
+		goto mdp_probe_err;
+	}
+	/* data chain */
+	pdata = msm_fb_dev->dev.platform_data;
+	pdata->on = mdp_on;
+	pdata->off = mdp_off;
+	pdata->next = pdev;
+
+	mdp_clk_ctrl(1);
+
+	mdp_prim_panel_type = mfd->panel.type;
+	switch (mfd->panel.type) {
+	case EXT_MDDI_PANEL:
+	case MDDI_PANEL:
+	case EBI2_PANEL:
+		INIT_WORK(&mfd->dma_update_worker,
+			  mdp_lcd_update_workqueue_handler);
+		INIT_WORK(&mfd->vsync_resync_worker,
+			  mdp_vsync_resync_workqueue_handler);
+		mfd->hw_refresh = FALSE;
+
+		if (mfd->panel.type == EXT_MDDI_PANEL) {
+			/* 15 fps -> 66 msec */
+			mfd->refresh_timer_duration = (66 * HZ / 1000);
+		} else {
+			/* 24 fps -> 42 msec */
+			mfd->refresh_timer_duration = (42 * HZ / 1000);
+		}
+
+#ifdef CONFIG_FB_MSM_MDP22
+		mfd->dma_fnc = mdp_dma2_update;
+		mfd->dma = &dma2_data;
+#else
+		if (mfd->panel_info.pdest == DISPLAY_1) {
+#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDDI)
+			mfd->dma_fnc = mdp4_mddi_overlay;
+			mfd->cursor_update = mdp4_mddi_overlay_cursor;
+#else
+			mfd->dma_fnc = mdp_dma2_update;
+#endif
+			mfd->dma = &dma2_data;
+			mfd->lut_update = mdp_lut_update_nonlcdc;
+			mfd->do_histogram = mdp_do_histogram;
+		} else {
+			mfd->dma_fnc = mdp_dma_s_update;
+			mfd->dma = &dma_s_data;
+		}
+#endif
+		if (mdp_pdata)
+			mfd->vsync_gpio = mdp_pdata->gpio;
+		else
+			mfd->vsync_gpio = -1;
+
+#ifdef CONFIG_FB_MSM_MDP40
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+			/* dmas dmap switch */
+			mdp_intr_mask |= INTR_DMA_S_DONE;
+		}
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+		if (mfd->panel.type == EBI2_PANEL)
+			intf = EBI2_INTF;
+		else
+			intf = MDDI_INTF;
+
+		if (mfd->panel_info.pdest == DISPLAY_1)
+			if_no = PRIMARY_INTF_SEL;
+		else
+			if_no = SECONDARY_INTF_SEL;
+
+		mdp4_display_intf_sel(if_no, intf);
+#endif
+		mdp_config_vsync(mdp_init_pdev, mfd);
+		break;
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+	case MIPI_VIDEO_PANEL:
+#ifndef CONFIG_FB_MSM_MDP303
+		mipi = &mfd->panel_info.mipi;
+		mdp4_dsi_vsync_init(0);
+		mfd->hw_refresh = TRUE;
+		mfd->dma_fnc = mdp4_dsi_video_overlay;
+		mfd->lut_update = mdp_lut_update_lcdc;
+		mfd->do_histogram = mdp_do_histogram;
+		if (mfd->panel_info.pdest == DISPLAY_1) {
+			if_no = PRIMARY_INTF_SEL;
+			mfd->dma = &dma2_data;
+		} else {
+			if_no = EXTERNAL_INTF_SEL;
+			mfd->dma = &dma_e_data;
+		}
+		mdp4_display_intf_sel(if_no, DSI_VIDEO_INTF);
+#else
+		pdata->on = mdp_dsi_video_on;
+		pdata->off = mdp_dsi_video_off;
+		mfd->hw_refresh = TRUE;
+		mfd->dma_fnc = mdp_dsi_video_update;
+		mfd->do_histogram = mdp_do_histogram;
+		mfd->vsync_ctrl = mdp_dma_video_vsync_ctrl;
+		if (mfd->panel_info.pdest == DISPLAY_1)
+			mfd->dma = &dma2_data;
+		else {
+			printk(KERN_ERR "Invalid Selection of destination panel\n");
+			rc = -ENODEV;
+			goto mdp_probe_err;
+		}
+
+#endif
+		if (mdp_rev >= MDP_REV_40)
+			mfd->cursor_update = mdp_hw_cursor_sync_update;
+		else
+			mfd->cursor_update = mdp_hw_cursor_update;
+		break;
+
+	case MIPI_CMD_PANEL:
+#ifndef CONFIG_FB_MSM_MDP303
+		mfd->dma_fnc = mdp4_dsi_cmd_overlay;
+		mipi = &mfd->panel_info.mipi;
+		mdp4_dsi_rdptr_init(0);
+		if (mfd->panel_info.pdest == DISPLAY_1) {
+			if_no = PRIMARY_INTF_SEL;
+			mfd->dma = &dma2_data;
+		} else {
+			if_no = SECONDARY_INTF_SEL;
+			mfd->dma = &dma_s_data;
+		}
+		mfd->lut_update = mdp_lut_update_nonlcdc;
+		mfd->do_histogram = mdp_do_histogram;
+		mdp4_display_intf_sel(if_no, DSI_CMD_INTF);
+
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+#else
+
+		mfd->dma_fnc = mdp_dma2_update;
+		mfd->do_histogram = mdp_do_histogram;
+		mfd->vsync_ctrl = mdp_dma_vsync_ctrl;
+		if (mfd->panel_info.pdest == DISPLAY_1)
+			mfd->dma = &dma2_data;
+		else {
+			printk(KERN_ERR "Invalid Selection of destination panel\n");
+			rc = -ENODEV;
+			goto mdp_probe_err;
+		}
+		INIT_WORK(&mfd->dma_update_worker,
+			mdp_lcd_update_workqueue_handler);
+#endif
+		mdp_config_vsync(mdp_init_pdev, mfd);
+		break;
+#endif
+
+#ifdef CONFIG_FB_MSM_DTV
+	case DTV_PANEL:
+		mdp4_dtv_vsync_init(0);
+		pdata->on = mdp4_dtv_on;
+		pdata->off = mdp4_dtv_off;
+		mfd->hw_refresh = TRUE;
+		mfd->cursor_update = mdp_hw_cursor_update;
+		mfd->dma_fnc = mdp4_dtv_overlay;
+		mfd->dma = &dma_e_data;
+		mdp4_display_intf_sel(EXTERNAL_INTF_SEL, DTV_INTF);
+		break;
+#endif
+	case HDMI_PANEL:
+	case LCDC_PANEL:
+	case LVDS_PANEL:
+#ifdef CONFIG_FB_MSM_MDP303
+		pdata->on = mdp_lcdc_on;
+		pdata->off = mdp_lcdc_off;
+#endif
+		mfd->hw_refresh = TRUE;
+#if	defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDP40)
+		mfd->cursor_update = mdp_hw_cursor_sync_update;
+#else
+		mfd->cursor_update = mdp_hw_cursor_update;
+#endif
+#ifndef CONFIG_FB_MSM_MDP22
+		mfd->lut_update = mdp_lut_update_lcdc;
+		mfd->do_histogram = mdp_do_histogram;
+#endif
+#ifdef CONFIG_FB_MSM_OVERLAY
+		mfd->dma_fnc = mdp4_lcdc_overlay;
+#else
+		mfd->dma_fnc = mdp_lcdc_update;
+#endif
+
+#ifdef CONFIG_FB_MSM_MDP40
+		mdp4_lcdc_vsync_init(0);
+		if (mfd->panel.type == HDMI_PANEL) {
+			mfd->dma = &dma_e_data;
+			mdp4_display_intf_sel(EXTERNAL_INTF_SEL, LCDC_RGB_INTF);
+		} else {
+			mfd->dma = &dma2_data;
+			mdp4_display_intf_sel(PRIMARY_INTF_SEL, LCDC_RGB_INTF);
+		}
+#else
+		mfd->dma = &dma2_data;
+		mfd->vsync_ctrl = mdp_dma_lcdc_vsync_ctrl;
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mdp_intr_mask &= ~MDP_DMA_P_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+#endif
+		break;
+
+	case TV_PANEL:
+#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_TVOUT)
+		pdata->on = mdp4_atv_on;
+		pdata->off = mdp4_atv_off;
+		mfd->dma_fnc = mdp4_atv_overlay;
+		mfd->dma = &dma_e_data;
+		mdp4_display_intf_sel(EXTERNAL_INTF_SEL, TV_INTF);
+#else
+		pdata->on = mdp_dma3_on;
+		pdata->off = mdp_dma3_off;
+		mfd->hw_refresh = TRUE;
+		mfd->dma_fnc = mdp_dma3_update;
+		mfd->dma = &dma3_data;
+#endif
+		break;
+
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+	case WRITEBACK_PANEL:
+		{
+			unsigned int mdp_version;
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
+						 FALSE);
+			mdp_version = inpdw(MDP_BASE + 0x0);
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF,
+						FALSE);
+			if (mdp_version < 0x04030303) {
+				pr_err("%s: writeback panel not supprted\n",
+					 __func__);
+				platform_device_put(msm_fb_dev);
+				return -ENODEV;
+			}
+			pdata->on = mdp4_overlay_writeback_on;
+			pdata->off = mdp4_overlay_writeback_off;
+			mfd->dma_fnc = mdp4_writeback_overlay;
+			mfd->dma = &dma_wb_data;
+			mdp4_display_intf_sel(EXTERNAL_INTF_SEL, DTV_INTF);
+		}
+		break;
+#endif
+	default:
+		printk(KERN_ERR "mdp_probe: unknown device type!\n");
+		rc = -ENODEV;
+		mdp_clk_ctrl(0);
+		goto mdp_probe_err;
+	}
+#ifdef CONFIG_FB_MSM_MDP40
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	mdp4_display_intf = inpdw(MDP_BASE + 0x0038);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+#endif
+
+	mdp_clk_ctrl(0);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (!mdp_bus_scale_handle && mdp_pdata &&
+		mdp_pdata->mdp_bus_scale_table) {
+		mdp_bus_scale_handle =
+			msm_bus_scale_register_client(
+					mdp_pdata->mdp_bus_scale_table);
+		if (!mdp_bus_scale_handle) {
+			printk(KERN_ERR "%s not able to get bus scale\n",
+				__func__);
+			return -ENOMEM;
+		}
+	}
+
+	/* req bus bandwidth immediately */
+	if (!(mfd->cont_splash_done))
+		mdp_bus_scale_update_request(5);
+
+#endif
+
+	/* set driver data */
+	platform_set_drvdata(msm_fb_dev, mfd);
+
+	rc = platform_device_add(msm_fb_dev);
+	if (rc) {
+		goto mdp_probe_err;
+	}
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	pdev_list[pdev_list_cnt++] = pdev;
+	mdp4_extn_disp = 0;
+	return 0;
+
+      mdp_probe_err:
+	platform_device_put(msm_fb_dev);
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (mdp_pdata && mdp_pdata->mdp_bus_scale_table &&
+		mdp_bus_scale_handle > 0)
+		msm_bus_scale_unregister_client(mdp_bus_scale_handle);
+#endif
+	return rc;
 }
 
-subsys_initcall(mdp_init);
-late_initcall(mdp_lateinit);
+unsigned int mdp_check_suspended(void)
+{
+	unsigned int ret;
+
+	mutex_lock(&mdp_suspend_mutex);
+	ret = mdp_suspended;
+	mutex_unlock(&mdp_suspend_mutex);
+
+	return ret;
+}
+
+void mdp_footswitch_ctrl(boolean on)
+{
+	mutex_lock(&mdp_suspend_mutex);
+	if (!mdp_suspended || mdp4_extn_disp || !footswitch ||
+		mdp_rev <= MDP_REV_41) {
+		mutex_unlock(&mdp_suspend_mutex);
+		return;
+	}
+
+	if (hdmi_pll_fs)
+		regulator_enable(hdmi_pll_fs);
+
+	if (on && !mdp_footswitch_on) {
+		pr_debug("Enable MDP FS\n");
+		regulator_enable(footswitch);
+		mdp_footswitch_on = 1;
+	} else if (!on && mdp_footswitch_on) {
+		pr_debug("Disable MDP FS\n");
+		regulator_disable(footswitch);
+		mdp_footswitch_on = 0;
+	}
+
+	if (hdmi_pll_fs)
+		regulator_disable(hdmi_pll_fs);
+
+	mutex_unlock(&mdp_suspend_mutex);
+}
+
+#ifdef CONFIG_PM
+static void mdp_suspend_sub(void)
+{
+	/* cancel pipe ctrl worker */
+	cancel_delayed_work(&mdp_pipe_ctrl_worker);
+
+	/* for workder can't be cancelled... */
+	flush_workqueue(mdp_pipe_ctrl_wq);
+
+	/* let's wait for PPP completion */
+	while (atomic_read(&mdp_block_power_cnt[MDP_PPP_BLOCK]) > 0)
+		cpu_relax();
+
+	/* try to power down */
+	mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	mutex_lock(&mdp_suspend_mutex);
+	mdp_suspended = TRUE;
+	mutex_unlock(&mdp_suspend_mutex);
+}
+#endif
+
+#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
+static int mdp_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	if (pdev->id == 0) {
+		mdp_suspend_sub();
+		if (mdp_current_clk_on) {
+			printk(KERN_WARNING"MDP suspend failed\n");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mdp_early_suspend(struct early_suspend *h)
+{
+	mdp_suspend_sub();
+#ifdef CONFIG_FB_MSM_DTV
+	mdp4_dtv_set_black_screen();
+#endif
+	mdp4_iommu_detach();
+	mdp_footswitch_ctrl(FALSE);
+}
+
+static void mdp_early_resume(struct early_suspend *h)
+{
+	mdp_footswitch_ctrl(TRUE);
+	mutex_lock(&mdp_suspend_mutex);
+	mdp_suspended = FALSE;
+	mutex_unlock(&mdp_suspend_mutex);
+}
+#endif
+
+static int mdp_remove(struct platform_device *pdev)
+{
+	if (footswitch != NULL)
+		regulator_put(footswitch);
+	iounmap(msm_mdp_base);
+	pm_runtime_disable(&pdev->dev);
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (mdp_pdata && mdp_pdata->mdp_bus_scale_table &&
+		mdp_bus_scale_handle > 0)
+		msm_bus_scale_unregister_client(mdp_bus_scale_handle);
+#endif
+	return 0;
+}
+
+static int mdp_register_driver(void)
+{
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
+	early_suspend.suspend = mdp_early_suspend;
+	early_suspend.resume = mdp_early_resume;
+	register_early_suspend(&early_suspend);
+#endif
+
+	return platform_driver_register(&mdp_driver);
+}
+
+static int __init mdp_driver_init(void)
+{
+	int ret;
+
+	mdp_drv_init();
+
+	ret = mdp_register_driver();
+	if (ret) {
+		printk(KERN_ERR "mdp_register_driver() failed!\n");
+		return ret;
+	}
+
+#if defined(CONFIG_DEBUG_FS)
+	mdp_debugfs_init();
+#endif
+
+	return 0;
+
+}
+
+module_init(mdp_driver_init);
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
new file mode 100644
index 0000000..7f493ff
--- /dev/null
+++ b/drivers/video/msm/mdp.h
@@ -0,0 +1,902 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MDP_H
+#define MDP_H
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/hrtimer.h>
+#include <linux/msm_mdp.h>
+#include <linux/memory_alloc.h>
+#include <mach/hardware.h>
+#include <linux/ion.h>
+
+#ifdef CONFIG_MSM_BUS_SCALING
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#endif
+
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#include "msm_fb_panel.h"
+
+extern uint32 mdp_hw_revision;
+extern ulong mdp4_display_intf;
+extern spinlock_t mdp_spin_lock;
+extern int mdp_rev;
+extern struct mdp_csc_cfg mdp_csc_convert[4];
+
+extern struct workqueue_struct *mdp_hist_wq;
+
+extern uint32 mdp_intr_mask;
+
+#define MDP4_REVISION_V1		0
+#define MDP4_REVISION_V2		1
+#define MDP4_REVISION_V2_1	2
+#define MDP4_REVISION_NONE	0xffffffff
+
+#ifdef BIT
+#undef BIT
+#endif
+
+#define BIT(x)  (1<<(x))
+
+#define MDPOP_NOP               0
+#define MDPOP_LR                BIT(0)	/* left to right flip */
+#define MDPOP_UD                BIT(1)	/* up and down flip */
+#define MDPOP_ROT90             BIT(2)	/* rotate image to 90 degree */
+#define MDPOP_ROT180            (MDPOP_UD|MDPOP_LR)
+#define MDPOP_ROT270            (MDPOP_ROT90|MDPOP_UD|MDPOP_LR)
+#define MDPOP_ASCALE            BIT(7)
+#define MDPOP_ALPHAB            BIT(8)	/* enable alpha blending */
+#define MDPOP_TRANSP            BIT(9)	/* enable transparency */
+#define MDPOP_DITHER            BIT(10)	/* enable dither */
+#define MDPOP_SHARPENING	BIT(11) /* enable sharpening */
+#define MDPOP_BLUR		BIT(12) /* enable blur */
+#define MDPOP_FG_PM_ALPHA       BIT(13)
+#define MDP_ALLOC(x)  kmalloc(x, GFP_KERNEL)
+
+struct mdp_buf_type {
+	struct ion_handle *ihdl;
+	u32 write_addr;
+	u32 read_addr;
+	u32 size;
+};
+
+struct mdp_table_entry {
+	uint32_t reg;
+	uint32_t val;
+};
+
+extern struct mdp_ccs mdp_ccs_yuv2rgb ;
+extern struct mdp_ccs mdp_ccs_rgb2yuv ;
+extern unsigned char hdmi_prim_display;
+
+struct vsync {
+	ktime_t vsync_time;
+	struct device *dev;
+	struct work_struct vsync_work;
+	int vsync_irq_enabled;
+};
+
+extern struct vsync vsync_cntrl;
+
+/*
+ * MDP Image Structure
+ */
+typedef struct mdpImg_ {
+	uint32 imgType;		/* Image type */
+	uint32 *bmy_addr;	/* bitmap or y addr */
+	uint32 *cbcr_addr;	/* cbcr addr */
+	uint32 width;		/* image width */
+	uint32 mdpOp;		/* image opertion (rotation,flip up/down, alpha/tp) */
+	uint32 tpVal;		/* transparency color */
+	uint32 alpha;		/* alpha percentage 0%(0x0) ~ 100%(0x100) */
+	int    sp_value;        /* sharpening strength */
+} MDPIMG;
+
+#define MDP_OUTP(addr, data) outpdw((addr), (data))
+
+#define MDP_BASE msm_mdp_base
+
+typedef enum {
+	MDP_BC_SCALE_POINT2_POINT4,
+	MDP_BC_SCALE_POINT4_POINT6,
+	MDP_BC_SCALE_POINT6_POINT8,
+	MDP_BC_SCALE_POINT8_1,
+	MDP_BC_SCALE_UP,
+	MDP_PR_SCALE_POINT2_POINT4,
+	MDP_PR_SCALE_POINT4_POINT6,
+	MDP_PR_SCALE_POINT6_POINT8,
+	MDP_PR_SCALE_POINT8_1,
+	MDP_PR_SCALE_UP,
+	MDP_SCALE_BLUR,
+	MDP_INIT_SCALE
+} MDP_SCALE_MODE;
+
+typedef enum {
+	MDP_BLOCK_POWER_OFF,
+	MDP_BLOCK_POWER_ON
+} MDP_BLOCK_POWER_STATE;
+
+typedef enum {
+	MDP_CMD_BLOCK,
+	MDP_OVERLAY0_BLOCK,
+	MDP_MASTER_BLOCK,
+	MDP_PPP_BLOCK,
+	MDP_DMA2_BLOCK,
+	MDP_DMA3_BLOCK,
+	MDP_DMA_S_BLOCK,
+	MDP_DMA_E_BLOCK,
+	MDP_OVERLAY1_BLOCK,
+	MDP_OVERLAY2_BLOCK,
+	MDP_MAX_BLOCK
+} MDP_BLOCK_TYPE;
+
+/* Let's keep Q Factor power of 2 for optimization */
+#define MDP_SCALE_Q_FACTOR 512
+
+#ifdef CONFIG_FB_MSM_MDP31
+#define MDP_MAX_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*8)
+#define MDP_MIN_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/8)
+#define MDP_MAX_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*8)
+#define MDP_MIN_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/8)
+#else
+#define MDP_MAX_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*4)
+#define MDP_MIN_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/4)
+#define MDP_MAX_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*4)
+#define MDP_MIN_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/4)
+#endif
+
+/* SHIM Q Factor */
+#define PHI_Q_FACTOR          29
+#define PQF_PLUS_5            (PHI_Q_FACTOR + 5)	/* due to 32 phases */
+#define PQF_PLUS_4            (PHI_Q_FACTOR + 4)
+#define PQF_PLUS_2            (PHI_Q_FACTOR + 2)	/* to get 4.0 */
+#define PQF_MINUS_2           (PHI_Q_FACTOR - 2)	/* to get 0.25 */
+#define PQF_PLUS_5_PLUS_2     (PQF_PLUS_5 + 2)
+#define PQF_PLUS_5_MINUS_2    (PQF_PLUS_5 - 2)
+
+#define MDP_CONVTP(tpVal) (((tpVal&0xF800)<<8)|((tpVal&0x7E0)<<5)|((tpVal&0x1F)<<3))
+
+#define MDPOP_ROTATION (MDPOP_ROT90|MDPOP_LR|MDPOP_UD)
+#define MDP_CHKBIT(val, bit) ((bit) == ((val) & (bit)))
+
+/* overlay interface API defines */
+typedef enum {
+	MORE_IBUF,
+	FINAL_IBUF,
+	COMPLETE_IBUF
+} MDP_IBUF_STATE;
+
+struct mdp_dirty_region {
+	__u32 xoffset;		/* source origin in the x-axis */
+	__u32 yoffset;		/* source origin in the y-axis */
+	__u32 width;		/* number of pixels in the x-axis */
+	__u32 height;		/* number of pixels in the y-axis */
+};
+
+/*
+ * MDP extended data types
+ */
+typedef struct mdp_roi_s {
+	uint32 x;
+	uint32 y;
+	uint32 width;
+	uint32 height;
+	int32 lcd_x;
+	int32 lcd_y;
+	uint32 dst_width;
+	uint32 dst_height;
+} MDP_ROI;
+
+typedef struct mdp_ibuf_s {
+	uint8 *buf;
+	uint32 bpp;
+	uint32 ibuf_type;
+	uint32 ibuf_width;
+	uint32 ibuf_height;
+
+	MDP_ROI roi;
+	MDPIMG mdpImg;
+
+	int32 dma_x;
+	int32 dma_y;
+	uint32 dma_w;
+	uint32 dma_h;
+
+	uint32 vsync_enable;
+} MDPIBUF;
+
+struct mdp_dma_data {
+	boolean busy;
+	boolean dmap_busy;
+	boolean waiting;
+	struct mutex ov_mutex;
+	struct semaphore mutex;
+	struct completion comp;
+	struct completion dmap_comp;
+};
+
+extern struct list_head mdp_hist_lut_list;
+extern struct mutex mdp_hist_lut_list_mutex;
+struct mdp_hist_lut_mgmt {
+	uint32_t block;
+	struct mutex lock;
+	struct list_head list;
+};
+
+struct mdp_hist_lut_info {
+	uint32_t block;
+	boolean is_enabled, has_sel_update;
+	int bank_sel;
+};
+
+struct mdp_hist_mgmt {
+	uint32_t block;
+	uint32_t irq_term;
+	uint32_t base;
+	struct completion mdp_hist_comp;
+	struct mutex mdp_hist_mutex;
+	struct mutex mdp_do_hist_mutex;
+	boolean mdp_is_hist_start, mdp_is_hist_data;
+	boolean mdp_is_hist_valid, mdp_is_hist_init;
+	uint8_t frame_cnt, bit_mask, num_bins;
+	struct work_struct mdp_histogram_worker;
+	struct mdp_histogram_data *hist;
+	uint32_t *c0, *c1, *c2;
+	uint32_t *extra_info;
+};
+
+enum {
+	MDP_HIST_MGMT_DMA_P = 0,
+	MDP_HIST_MGMT_DMA_S,
+	MDP_HIST_MGMT_VG_1,
+	MDP_HIST_MGMT_VG_2,
+	MDP_HIST_MGMT_MAX,
+};
+
+extern struct mdp_hist_mgmt *mdp_hist_mgmt_array[];
+
+#define MDP_CMD_DEBUG_ACCESS_BASE   (MDP_BASE+0x10000)
+
+#define MDP_DMA2_TERM 0x1
+#define MDP_DMA3_TERM 0x2
+#define MDP_PPP_TERM 0x4
+#define MDP_DMA_S_TERM 0x8
+#define MDP_DMA_E_TERM 0x10
+#ifdef CONFIG_FB_MSM_MDP40
+#define MDP_OVERLAY0_TERM 0x20
+#define MDP_OVERLAY1_TERM 0x40
+#define MDP_DMAP_TERM MDP_DMA2_TERM	/* dmap == dma2 */
+#define MDP_PRIM_VSYNC_TERM 0x100
+#define MDP_EXTER_VSYNC_TERM 0x200
+#define MDP_PRIM_RDPTR_TERM 0x400
+#endif
+#define MDP_OVERLAY2_TERM 0x80
+#define MDP_HISTOGRAM_TERM_DMA_P 0x10000
+#define MDP_HISTOGRAM_TERM_DMA_S 0x20000
+#define MDP_HISTOGRAM_TERM_VG_1 0x40000
+#define MDP_HISTOGRAM_TERM_VG_2 0x80000
+#define MDP_VSYNC_TERM 0x1000
+
+#define ACTIVE_START_X_EN BIT(31)
+#define ACTIVE_START_Y_EN BIT(31)
+#define ACTIVE_HIGH 0
+#define ACTIVE_LOW 1
+#define MDP_DMA_S_DONE  BIT(2)
+#define MDP_DMA_E_DONE  BIT(3)
+#define LCDC_FRAME_START    BIT(15)
+#define LCDC_UNDERFLOW      BIT(16)
+
+#ifdef CONFIG_FB_MSM_MDP22
+#define MDP_DMA_P_DONE 	BIT(2)
+#else
+#define MDP_DMA_P_DONE 	BIT(14)
+#endif
+
+#define MDP_PPP_DONE 				BIT(0)
+#define TV_OUT_DMA3_DONE    BIT(6)
+#define TV_ENC_UNDERRUN     BIT(7)
+#define MDP_PRIM_RDPTR      BIT(8)
+#define TV_OUT_DMA3_START   BIT(13)
+#define MDP_HIST_DONE       BIT(20)
+
+/* histogram interrupts */
+#define INTR_HIST_DONE			BIT(1)
+#define INTR_HIST_RESET_SEQ_DONE	BIT(0)
+
+#ifdef CONFIG_FB_MSM_MDP22
+#define MDP_ANY_INTR_MASK (MDP_PPP_DONE| \
+			MDP_DMA_P_DONE| \
+			TV_ENC_UNDERRUN)
+#else
+#define MDP_ANY_INTR_MASK (MDP_PPP_DONE| \
+			MDP_DMA_P_DONE| \
+			MDP_DMA_S_DONE| \
+			MDP_DMA_E_DONE| \
+			LCDC_UNDERFLOW| \
+			MDP_HIST_DONE| \
+			TV_ENC_UNDERRUN)
+#endif
+
+#define MDP_TOP_LUMA       16
+#define MDP_TOP_CHROMA     0
+#define MDP_BOTTOM_LUMA    19
+#define MDP_BOTTOM_CHROMA  3
+#define MDP_LEFT_LUMA      22
+#define MDP_LEFT_CHROMA    6
+#define MDP_RIGHT_LUMA     25
+#define MDP_RIGHT_CHROMA   9
+
+#define CLR_G 0x0
+#define CLR_B 0x1
+#define CLR_R 0x2
+#define CLR_ALPHA 0x3
+
+#define CLR_Y  CLR_G
+#define CLR_CB CLR_B
+#define CLR_CR CLR_R
+
+/* from lsb to msb */
+#define MDP_GET_PACK_PATTERN(a,x,y,z,bit) (((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
+
+/*
+ * 0x0000 0x0004 0x0008 MDP sync config
+ */
+#ifdef CONFIG_FB_MSM_MDP22
+#define MDP_SYNCFG_HGT_LOC 22
+#define MDP_SYNCFG_VSYNC_EXT_EN BIT(21)
+#define MDP_SYNCFG_VSYNC_INT_EN BIT(20)
+#else
+#define MDP_SYNCFG_HGT_LOC 21
+#define MDP_SYNCFG_VSYNC_EXT_EN BIT(20)
+#define MDP_SYNCFG_VSYNC_INT_EN BIT(19)
+#define MDP_HW_VSYNC
+#endif
+
+/*
+ * 0x0018 MDP VSYNC THREASH
+ */
+#define MDP_PRIM_BELOW_LOC 0
+#define MDP_PRIM_ABOVE_LOC 8
+
+/*
+ * MDP_PRIMARY_VSYNC_OUT_CTRL
+ * 0x0080,84,88 internal vsync pulse config
+ */
+#define VSYNC_PULSE_EN BIT(31)
+#define VSYNC_PULSE_INV BIT(30)
+
+/*
+ * 0x008c MDP VSYNC CONTROL
+ */
+#define DISP0_VSYNC_MAP_VSYNC0 0
+#define DISP0_VSYNC_MAP_VSYNC1 BIT(0)
+#define DISP0_VSYNC_MAP_VSYNC2 BIT(0)|BIT(1)
+
+#define DISP1_VSYNC_MAP_VSYNC0 0
+#define DISP1_VSYNC_MAP_VSYNC1 BIT(2)
+#define DISP1_VSYNC_MAP_VSYNC2 BIT(2)|BIT(3)
+
+#define PRIMARY_LCD_SYNC_EN BIT(4)
+#define PRIMARY_LCD_SYNC_DISABLE 0
+
+#define SECONDARY_LCD_SYNC_EN BIT(5)
+#define SECONDARY_LCD_SYNC_DISABLE 0
+
+#define EXTERNAL_LCD_SYNC_EN BIT(6)
+#define EXTERNAL_LCD_SYNC_DISABLE 0
+
+/*
+ * 0x101f0 MDP VSYNC Threshold
+ */
+#define VSYNC_THRESHOLD_ABOVE_LOC 0
+#define VSYNC_THRESHOLD_BELOW_LOC 16
+#define VSYNC_ANTI_TEAR_EN BIT(31)
+
+/*
+ * 0x10004 command config
+ */
+#define MDP_CMD_DBGBUS_EN BIT(0)
+
+/*
+ * 0x10124 or 0x101d4PPP source config
+ */
+#define PPP_SRC_C0G_8BITS (BIT(1)|BIT(0))
+#define PPP_SRC_C1B_8BITS (BIT(3)|BIT(2))
+#define PPP_SRC_C2R_8BITS (BIT(5)|BIT(4))
+#define PPP_SRC_C3A_8BITS (BIT(7)|BIT(6))
+
+#define PPP_SRC_C0G_6BITS BIT(1)
+#define PPP_SRC_C1B_6BITS BIT(3)
+#define PPP_SRC_C2R_6BITS BIT(5)
+
+#define PPP_SRC_C0G_5BITS BIT(0)
+#define PPP_SRC_C1B_5BITS BIT(2)
+#define PPP_SRC_C2R_5BITS BIT(4)
+
+#define PPP_SRC_C3_ALPHA_EN BIT(8)
+
+#define PPP_SRC_BPP_INTERLVD_1BYTES 0
+#define PPP_SRC_BPP_INTERLVD_2BYTES BIT(9)
+#define PPP_SRC_BPP_INTERLVD_3BYTES BIT(10)
+#define PPP_SRC_BPP_INTERLVD_4BYTES (BIT(10)|BIT(9))
+
+#define PPP_SRC_BPP_ROI_ODD_X BIT(11)
+#define PPP_SRC_BPP_ROI_ODD_Y BIT(12)
+#define PPP_SRC_INTERLVD_2COMPONENTS BIT(13)
+#define PPP_SRC_INTERLVD_3COMPONENTS BIT(14)
+#define PPP_SRC_INTERLVD_4COMPONENTS (BIT(14)|BIT(13))
+
+/*
+ * RGB666 unpack format
+ * TIGHT means R6+G6+B6 together
+ * LOOSE means R6+2 +G6+2+ B6+2 (with MSB)
+ * or 2+R6 +2+G6 +2+B6 (with LSB)
+ */
+#define PPP_SRC_UNPACK_TIGHT BIT(17)
+#define PPP_SRC_UNPACK_LOOSE 0
+#define PPP_SRC_UNPACK_ALIGN_LSB 0
+#define PPP_SRC_UNPACK_ALIGN_MSB BIT(18)
+
+#define PPP_SRC_FETCH_PLANES_INTERLVD 0
+#define PPP_SRC_FETCH_PLANES_PSEUDOPLNR BIT(20)
+
+#define PPP_SRC_WMV9_MODE BIT(21)	/* window media version 9 */
+
+/*
+ * 0x10138 PPP operation config
+ */
+#define PPP_OP_SCALE_X_ON BIT(0)
+#define PPP_OP_SCALE_Y_ON BIT(1)
+
+#define PPP_OP_CONVERT_RGB2YCBCR 0
+#define PPP_OP_CONVERT_YCBCR2RGB BIT(2)
+#define PPP_OP_CONVERT_ON BIT(3)
+
+#define PPP_OP_CONVERT_MATRIX_PRIMARY 0
+#define PPP_OP_CONVERT_MATRIX_SECONDARY BIT(4)
+
+#define PPP_OP_LUT_C0_ON BIT(5)
+#define PPP_OP_LUT_C1_ON BIT(6)
+#define PPP_OP_LUT_C2_ON BIT(7)
+
+/* rotate or blend enable */
+#define PPP_OP_ROT_ON BIT(8)
+
+#define PPP_OP_ROT_90 BIT(9)
+#define PPP_OP_FLIP_LR BIT(10)
+#define PPP_OP_FLIP_UD BIT(11)
+
+#define PPP_OP_BLEND_ON BIT(12)
+
+#define PPP_OP_BLEND_SRCPIXEL_ALPHA 0
+#define PPP_OP_BLEND_DSTPIXEL_ALPHA BIT(13)
+#define PPP_OP_BLEND_CONSTANT_ALPHA BIT(14)
+#define PPP_OP_BLEND_SRCPIXEL_TRANSP (BIT(13)|BIT(14))
+
+#define PPP_OP_BLEND_ALPHA_BLEND_NORMAL 0
+#define PPP_OP_BLEND_ALPHA_BLEND_REVERSE BIT(15)
+
+#define PPP_OP_DITHER_EN BIT(16)
+
+#define PPP_OP_COLOR_SPACE_RGB 0
+#define PPP_OP_COLOR_SPACE_YCBCR BIT(17)
+
+#define PPP_OP_SRC_CHROMA_RGB 0
+#define PPP_OP_SRC_CHROMA_H2V1 BIT(18)
+#define PPP_OP_SRC_CHROMA_H1V2 BIT(19)
+#define PPP_OP_SRC_CHROMA_420 (BIT(18)|BIT(19))
+#define PPP_OP_SRC_CHROMA_COSITE 0
+#define PPP_OP_SRC_CHROMA_OFFSITE BIT(20)
+
+#define PPP_OP_DST_CHROMA_RGB 0
+#define PPP_OP_DST_CHROMA_H2V1 BIT(21)
+#define PPP_OP_DST_CHROMA_H1V2 BIT(22)
+#define PPP_OP_DST_CHROMA_420 (BIT(21)|BIT(22))
+#define PPP_OP_DST_CHROMA_COSITE 0
+#define PPP_OP_DST_CHROMA_OFFSITE BIT(23)
+
+#define PPP_BLEND_CALPHA_TRNASP BIT(24)
+
+#define PPP_OP_BG_CHROMA_RGB 0
+#define PPP_OP_BG_CHROMA_H2V1 BIT(25)
+#define PPP_OP_BG_CHROMA_H1V2 BIT(26)
+#define PPP_OP_BG_CHROMA_420 BIT(25)|BIT(26)
+#define PPP_OP_BG_CHROMA_SITE_COSITE 0
+#define PPP_OP_BG_CHROMA_SITE_OFFSITE BIT(27)
+#define PPP_OP_DEINT_EN BIT(28)
+
+#define PPP_BLEND_BG_USE_ALPHA_SEL      (1 << 0)
+#define PPP_BLEND_BG_ALPHA_REVERSE      (1 << 3)
+#define PPP_BLEND_BG_SRCPIXEL_ALPHA     (0 << 1)
+#define PPP_BLEND_BG_DSTPIXEL_ALPHA     (1 << 1)
+#define PPP_BLEND_BG_CONSTANT_ALPHA     (2 << 1)
+#define PPP_BLEND_BG_CONST_ALPHA_VAL(x) ((x) << 24)
+
+#define PPP_OP_DST_RGB 0
+#define PPP_OP_DST_YCBCR BIT(30)
+/*
+ * 0x10150 PPP destination config
+ */
+#define PPP_DST_C0G_8BIT (BIT(0)|BIT(1))
+#define PPP_DST_C1B_8BIT (BIT(3)|BIT(2))
+#define PPP_DST_C2R_8BIT (BIT(5)|BIT(4))
+#define PPP_DST_C3A_8BIT (BIT(7)|BIT(6))
+
+#define PPP_DST_C0G_6BIT BIT(1)
+#define PPP_DST_C1B_6BIT BIT(3)
+#define PPP_DST_C2R_6BIT BIT(5)
+
+#define PPP_DST_C0G_5BIT BIT(0)
+#define PPP_DST_C1B_5BIT BIT(2)
+#define PPP_DST_C2R_5BIT BIT(4)
+
+#define PPP_DST_C3A_8BIT (BIT(7)|BIT(6))
+#define PPP_DST_C3ALPHA_EN BIT(8)
+
+#define PPP_DST_PACKET_CNT_INTERLVD_2ELEM BIT(9)
+#define PPP_DST_PACKET_CNT_INTERLVD_3ELEM BIT(10)
+#define PPP_DST_PACKET_CNT_INTERLVD_4ELEM (BIT(10)|BIT(9))
+#define PPP_DST_PACKET_CNT_INTERLVD_6ELEM (BIT(11)|BIT(9))
+
+#define PPP_DST_PACK_LOOSE 0
+#define PPP_DST_PACK_TIGHT BIT(13)
+#define PPP_DST_PACK_ALIGN_LSB 0
+#define PPP_DST_PACK_ALIGN_MSB BIT(14)
+
+#define PPP_DST_OUT_SEL_AXI 0
+#define PPP_DST_OUT_SEL_MDDI BIT(15)
+
+#define PPP_DST_BPP_2BYTES BIT(16)
+#define PPP_DST_BPP_3BYTES BIT(17)
+#define PPP_DST_BPP_4BYTES (BIT(17)|BIT(16))
+
+#define PPP_DST_PLANE_INTERLVD 0
+#define PPP_DST_PLANE_PLANAR BIT(18)
+#define PPP_DST_PLANE_PSEUDOPLN BIT(19)
+
+#define PPP_DST_TO_TV BIT(20)
+
+#define PPP_DST_MDDI_PRIMARY 0
+#define PPP_DST_MDDI_SECONDARY BIT(21)
+#define PPP_DST_MDDI_EXTERNAL BIT(22)
+
+/*
+ * 0x10180 DMA config
+ */
+#define DMA_DSTC0G_8BITS (BIT(1)|BIT(0))
+#define DMA_DSTC1B_8BITS (BIT(3)|BIT(2))
+#define DMA_DSTC2R_8BITS (BIT(5)|BIT(4))
+
+#define DMA_DSTC0G_6BITS BIT(1)
+#define DMA_DSTC1B_6BITS BIT(3)
+#define DMA_DSTC2R_6BITS BIT(5)
+
+#define DMA_DSTC0G_5BITS BIT(0)
+#define DMA_DSTC1B_5BITS BIT(2)
+#define DMA_DSTC2R_5BITS BIT(4)
+
+#define DMA_PACK_TIGHT                      BIT(6)
+#define DMA_PACK_LOOSE                      0
+#define DMA_PACK_ALIGN_LSB                  0
+/*
+ * use DMA_PACK_ALIGN_MSB if the upper 6 bits from 8 bits output
+ * from LCDC block maps into 6 pins out to the panel
+ */
+#define DMA_PACK_ALIGN_MSB                  BIT(7)
+#define DMA_PACK_PATTERN_RGB \
+       (MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8)
+#define DMA_PACK_PATTERN_BGR \
+       (MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 2)<<8)
+#define DMA_OUT_SEL_AHB                     0
+#define DMA_OUT_SEL_LCDC                    BIT(20)
+#define DMA_IBUF_FORMAT_RGB888              0
+#define DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888  BIT(26)
+
+#ifdef CONFIG_FB_MSM_MDP303
+#define DMA_OUT_SEL_DSI_CMD                  BIT(19)
+#define DMA_OUT_SEL_DSI_VIDEO               (3 << 19)
+#endif
+
+#ifdef CONFIG_FB_MSM_MDP22
+#define DMA_OUT_SEL_MDDI BIT(14)
+#define DMA_AHBM_LCD_SEL_PRIMARY 0
+#define DMA_AHBM_LCD_SEL_SECONDARY BIT(15)
+#define DMA_IBUF_C3ALPHA_EN BIT(16)
+#define DMA_DITHER_EN BIT(17)
+#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
+#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY BIT(18)
+#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL BIT(19)
+#define DMA_IBUF_FORMAT_RGB565 BIT(20)
+#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 0
+#define DMA_IBUF_NONCONTIGUOUS BIT(21)
+#else
+#define DMA_OUT_SEL_MDDI                    BIT(19)
+#define DMA_AHBM_LCD_SEL_PRIMARY            0
+#define DMA_AHBM_LCD_SEL_SECONDARY          0
+#define DMA_IBUF_C3ALPHA_EN                 0
+#define DMA_BUF_FORMAT_RGB565		BIT(25)
+#define DMA_DITHER_EN                       BIT(24)	/* dma_p */
+#define DMA_DEFLKR_EN                       BIT(24)	/* dma_e */
+#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY     0
+#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY   0
+#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL    0
+#define DMA_IBUF_FORMAT_RGB565              BIT(25)
+#define DMA_IBUF_NONCONTIGUOUS 0
+#endif
+
+/*
+ * MDDI Register
+ */
+#define MDDI_VDO_PACKET_DESC_16  0x5565
+#define MDDI_VDO_PACKET_DESC	 0x5666	/* 18 bits */
+#define MDDI_VDO_PACKET_DESC_24  0x5888
+
+#define MDP_HIST_INTR_STATUS_OFF	(0x0014)
+#define MDP_HIST_INTR_CLEAR_OFF		(0x0018)
+#define MDP_HIST_INTR_ENABLE_OFF	(0x001C)
+
+#ifdef CONFIG_FB_MSM_MDP40
+#define MDP_INTR_ENABLE		(msm_mdp_base + 0x0050)
+#define MDP_INTR_STATUS		(msm_mdp_base + 0x0054)
+#define MDP_INTR_CLEAR		(msm_mdp_base + 0x0058)
+#define MDP_EBI2_LCD0		(msm_mdp_base + 0x0060)
+#define MDP_EBI2_LCD1		(msm_mdp_base + 0x0064)
+#define MDP_EBI2_PORTMAP_MODE	(msm_mdp_base + 0x0070)
+
+#define MDP_DMA_P_HIST_INTR_STATUS 	(msm_mdp_base + 0x95014)
+#define MDP_DMA_P_HIST_INTR_CLEAR 	(msm_mdp_base + 0x95018)
+#define MDP_DMA_P_HIST_INTR_ENABLE 	(msm_mdp_base + 0x9501C)
+
+#else
+#define MDP_INTR_ENABLE		(msm_mdp_base + 0x0020)
+#define MDP_INTR_STATUS		(msm_mdp_base + 0x0024)
+#define MDP_INTR_CLEAR		(msm_mdp_base + 0x0028)
+#define MDP_EBI2_LCD0		(msm_mdp_base + 0x003c)
+#define MDP_EBI2_LCD1		(msm_mdp_base + 0x0040)
+#define MDP_EBI2_PORTMAP_MODE	(msm_mdp_base + 0x005c)
+
+#define MDP_DMA_P_HIST_INTR_STATUS	(msm_mdp_base + 0x94014)
+#define MDP_DMA_P_HIST_INTR_CLEAR	(msm_mdp_base + 0x94018)
+#define MDP_DMA_P_HIST_INTR_ENABLE	(msm_mdp_base + 0x9401C)
+#endif
+
+#define MDP_FULL_BYPASS_WORD43  (msm_mdp_base + 0x101ac)
+
+#define MDP_CSC_PFMVn(n)	(msm_mdp_base + 0x40400 + 4 * (n))
+#define MDP_CSC_PRMVn(n)	(msm_mdp_base + 0x40440 + 4 * (n))
+#define MDP_CSC_PRE_BV1n(n)	(msm_mdp_base + 0x40500 + 4 * (n))
+#define MDP_CSC_PRE_BV2n(n)	(msm_mdp_base + 0x40540 + 4 * (n))
+#define MDP_CSC_POST_BV1n(n)	(msm_mdp_base + 0x40580 + 4 * (n))
+#define MDP_CSC_POST_BV2n(n)	(msm_mdp_base + 0x405c0 + 4 * (n))
+
+#ifdef CONFIG_FB_MSM_MDP31
+#define MDP_CSC_PRE_LV1n(n)	(msm_mdp_base + 0x40600 + 4 * (n))
+#define MDP_CSC_PRE_LV2n(n)	(msm_mdp_base + 0x40640 + 4 * (n))
+#define MDP_CSC_POST_LV1n(n)	(msm_mdp_base + 0x40680 + 4 * (n))
+#define MDP_CSC_POST_LV2n(n)	(msm_mdp_base + 0x406c0 + 4 * (n))
+#define MDP_PPP_SCALE_COEFF_LSBn(n)	(msm_mdp_base + 0x50400 + 8 * (n))
+#define MDP_PPP_SCALE_COEFF_MSBn(n)	(msm_mdp_base + 0x50404 + 8 * (n))
+
+#define SCALE_D0_SET  0
+#define SCALE_D1_SET  BIT(0)
+#define SCALE_D2_SET  BIT(1)
+#define SCALE_U1_SET  (BIT(0)|BIT(1))
+
+#else
+#define MDP_CSC_PRE_LV1n(n)	(msm_mdp_base + 0x40580 + 4 * (n))
+#endif
+
+#define MDP_CURSOR_WIDTH 64
+#define MDP_CURSOR_HEIGHT 64
+#define MDP_CURSOR_SIZE (MDP_CURSOR_WIDTH*MDP_CURSOR_WIDTH*4)
+
+#define MDP_DMA_P_LUT_C0_EN   BIT(0)
+#define MDP_DMA_P_LUT_C1_EN   BIT(1)
+#define MDP_DMA_P_LUT_C2_EN   BIT(2)
+#define MDP_DMA_P_LUT_POST    BIT(4)
+
+void mdp_hw_init(void);
+int mdp_ppp_pipe_wait(void);
+void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd);
+void mdp_clk_ctrl(int on);
+void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
+		   boolean isr);
+void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
+			  boolean sync);
+void mdp_dma_pan_update(struct fb_info *info);
+void mdp_refresh_screen(unsigned long data);
+int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req);
+void mdp_lcd_update_workqueue_handler(struct work_struct *work);
+void mdp_vsync_resync_workqueue_handler(struct work_struct *work);
+void mdp_dma2_update(struct msm_fb_data_type *mfd);
+void mdp_vsync_cfg_regs(struct msm_fb_data_type *mfd,
+	boolean first_time);
+void mdp_config_vsync(struct platform_device *pdev,
+	struct msm_fb_data_type *mfd);
+uint32 mdp_get_lcd_line_counter(struct msm_fb_data_type *mfd);
+enum hrtimer_restart mdp_dma2_vsync_hrtimer_handler(struct hrtimer *ht);
+void mdp_set_scale(MDPIBUF *iBuf,
+		   uint32 dst_roi_width,
+		   uint32 dst_roi_height,
+		   boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr);
+void mdp_init_scale_table(void);
+void mdp_adjust_start_addr(uint8 **src0,
+			   uint8 **src1,
+			   int v_slice,
+			   int h_slice,
+			   int x,
+			   int y,
+			   uint32 width,
+			   uint32 height, int bpp, MDPIBUF *iBuf, int layer);
+void mdp_set_blend_attr(MDPIBUF *iBuf,
+			uint32 *alpha,
+			uint32 *tpVal,
+			uint32 perPixelAlpha, uint32 *pppop_reg_ptr);
+
+int mdp_dma3_on(struct platform_device *pdev);
+int mdp_dma3_off(struct platform_device *pdev);
+void mdp_dma3_update(struct msm_fb_data_type *mfd);
+
+int mdp_lcdc_on(struct platform_device *pdev);
+int mdp_lcdc_off(struct platform_device *pdev);
+void mdp_lcdc_update(struct msm_fb_data_type *mfd);
+
+#ifdef CONFIG_FB_MSM_MDP303
+int mdp_dsi_video_on(struct platform_device *pdev);
+int mdp_dsi_video_off(struct platform_device *pdev);
+void mdp_dsi_video_update(struct msm_fb_data_type *mfd);
+void mdp3_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd);
+static inline int mdp4_dsi_cmd_off(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline int mdp4_dsi_video_off(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline int mdp4_lcdc_off(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline int mdp4_dsi_cmd_on(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline int mdp4_dsi_video_on(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline int mdp4_lcdc_on(struct platform_device *pdev)
+{
+	return 0;
+}
+#endif
+
+void set_cont_splashScreen_status(int);
+
+int mdp_hw_cursor_update(struct fb_info *info, struct fb_cursor *cursor);
+#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDP40)
+int mdp_hw_cursor_sync_update(struct fb_info *info, struct fb_cursor *cursor);
+#else
+static inline int mdp_hw_cursor_sync_update(struct fb_info *info,
+		struct fb_cursor *cursor)
+{
+	return 0;
+}
+#endif
+
+void mdp_enable_irq(uint32 term);
+void mdp_disable_irq(uint32 term);
+void mdp_disable_irq_nosync(uint32 term);
+int mdp_get_bytes_per_pixel(uint32_t format,
+				 struct msm_fb_data_type *mfd);
+int mdp_set_core_clk(u32 rate);
+int mdp_clk_round_rate(u32 rate);
+
+unsigned long mdp_get_core_clk(void);
+unsigned long mdp_perf_level2clk_rate(uint32 perf_level);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+int mdp_bus_scale_update_request(uint32_t index);
+#else
+static inline int mdp_bus_scale_update_request(uint32_t index)
+{
+	return 0;
+}
+#endif
+void mdp_dma_vsync_ctrl(int enable);
+void mdp_dma_video_vsync_ctrl(int enable);
+void mdp_dma_lcdc_vsync_ctrl(int enable);
+void mdp3_vsync_irq_enable(int intr, int term);
+void mdp3_vsync_irq_disable(int intr, int term);
+
+#ifdef MDP_HW_VSYNC
+void vsync_clk_prepare_enable(void);
+void vsync_clk_disable_unprepare(void);
+void mdp_hw_vsync_clk_enable(struct msm_fb_data_type *mfd);
+void mdp_hw_vsync_clk_disable(struct msm_fb_data_type *mfd);
+void mdp_vsync_clk_disable(void);
+void mdp_vsync_clk_enable(void);
+#endif
+
+#ifdef CONFIG_DEBUG_FS
+int mdp_debugfs_init(void);
+#endif
+
+void mdp_dma_s_update(struct msm_fb_data_type *mfd);
+int mdp_histogram_start(struct mdp_histogram_start_req *req);
+int mdp_histogram_stop(struct fb_info *info, uint32_t block);
+int mdp_histogram_ctrl(boolean en, uint32_t block);
+int mdp_histogram_ctrl_all(boolean en);
+int mdp_histogram_block2mgmt(uint32_t block, struct mdp_hist_mgmt **mgmt);
+void mdp_histogram_handle_isr(struct mdp_hist_mgmt *mgmt);
+void __mdp_histogram_kickoff(struct mdp_hist_mgmt *mgmt);
+void __mdp_histogram_reset(struct mdp_hist_mgmt *mgmt);
+unsigned int mdp_check_suspended(void);
+void mdp_footswitch_ctrl(boolean on);
+
+#ifdef CONFIG_FB_MSM_MDP303
+static inline void mdp4_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd)
+{
+	/* empty */
+}
+
+static inline void mdp4_dsi_blt_dmap_busy_wait(struct msm_fb_data_type *mfd)
+{
+	/* empty */
+}
+static inline void mdp4_overlay_dsi_state_set(int state)
+{
+	/* empty */
+}
+static inline int mdp4_overlay_dsi_state_get(void)
+{
+	return 0;
+}
+static inline void mdp4_iommu_detach(void)
+{
+	/*empty */
+}
+#endif
+
+void mdp_vid_quant_set(void);
+#ifndef CONFIG_FB_MSM_MDP40
+static inline void mdp_dsi_cmd_overlay_suspend(struct msm_fb_data_type *mfd)
+{
+	/* empty */
+}
+static inline int msmfb_overlay_vsync_ctrl(struct fb_info *info,
+						void __user *argp)
+{
+	return 0;
+}
+#endif
+
+int mdp_ppp_v4l2_overlay_set(struct fb_info *info, struct mdp_overlay *req);
+int mdp_ppp_v4l2_overlay_clear(void);
+int mdp_ppp_v4l2_overlay_play(struct fb_info *info,
+	unsigned long srcp0_addr, unsigned long srcp0_size,
+	unsigned long srcp1_addr, unsigned long srcp1_size);
+
+#endif /* MDP_H */
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 32d9085..3e6933e 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -1,44 +1,36 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of Code Aurora nor
- *       the names of its contributors may be used to endorse or promote
- *       products derived from this software without specific prior written
- *       permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
+
 #ifndef MDP4_H
 #define MDP4_H
 
-/*
-#define DEBUG_OVERLAY
-*/
-
-#define MDP4_NONBLOCKING	/* enable non blocking ioctl */
+extern struct mdp_dma_data dma2_data;
+extern struct mdp_dma_data dma_s_data;
+extern struct mdp_dma_data dma_e_data;
+extern struct mdp_dma_data dma_wb_data;
+extern unsigned int mdp_hist_frame_cnt;
+extern struct completion mdp_hist_comp;
+extern boolean mdp_is_in_isr;
+extern uint32 mdp_intr_mask;
+extern spinlock_t mdp_spin_lock;
+extern struct mdp4_statistic mdp4_stat;
+extern uint32 mdp4_extn_disp;
+extern spinlock_t dsi_clk_lock;
+extern u32 mdp_max_clk;
 
 #define MDP4_OVERLAYPROC0_BASE	0x10000
 #define MDP4_OVERLAYPROC1_BASE	0x18000
-
-#define MDP_OVERLAY0_TERM 0x20
-#define MDP_OVERLAY1_TERM 0x40
+#define MDP4_OVERLAYPROC2_BASE	0x88000
 
 #define MDP4_VIDEO_BASE 0x20000
 #define MDP4_VIDEO_OFF 0x10000
@@ -46,12 +38,25 @@
 #define MDP4_RGB_BASE 0x40000
 #define MDP4_RGB_OFF 0x10000
 
+/* chip select controller */
+#define CS_CONTROLLER_0 0x0707ffff
+#define CS_CONTROLLER_1 0x03073f3f
+
+enum {
+	OVERLAY_PERF_LEVEL1 = 1,
+	OVERLAY_PERF_LEVEL2,
+	OVERLAY_PERF_LEVEL3,
+	OVERLAY_PERF_LEVEL4
+};
+
 enum mdp4_overlay_status {
 	MDP4_OVERLAY_TYPE_UNSET,
 	MDP4_OVERLAY_TYPE_SET,
 	MDP4_OVERLAY_TYPE_MAX
 };
 
+typedef int (*cmd_fxn_t)(struct platform_device *pdev);
+
 enum {		/* display */
 	PRIMARY_INTF_SEL,
 	SECONDARY_INTF_SEL,
@@ -80,6 +85,18 @@
 	EBI2_LCD1
 };
 
+#define MDP4_3D_NONE		0
+#define MDP4_3D_SIDE_BY_SIDE	1
+#define MDP4_3D_TOP_DOWN	2
+
+#define MDP4_PANEL_MDDI		BIT(0)
+#define MDP4_PANEL_LCDC		BIT(1)
+#define MDP4_PANEL_DTV		BIT(2)
+#define MDP4_PANEL_ATV		BIT(3)
+#define MDP4_PANEL_DSI_VIDEO	BIT(4)
+#define MDP4_PANEL_DSI_CMD	BIT(5)
+#define MDP4_PANEL_WRITEBACK		BIT(6)
+
 enum {
 	OVERLAY_MODE_NONE,
 	OVERLAY_MODE_BLT
@@ -109,44 +126,48 @@
 #define INTR_PRIMARY_INTF_UDERRUN	BIT(8)
 #define INTR_EXTERNAL_VSYNC		BIT(9)
 #define INTR_EXTERNAL_INTF_UDERRUN	BIT(10)
+#define INTR_PRIMARY_RDPTR		BIT(11)	/* read pointer */
 #define INTR_DMA_P_HISTOGRAM		BIT(17)
-#define INTR_MDP_HIST_DONE       	BIT(20) /*DMA_P histogram interrupt*/
-
-/* histogram interrupts */
-#define INTR_HIST_DONE			BIT(1)
-#define INTR_HIST_RESET_SEQ_DONE	BIT(0)
-
+#define INTR_DMA_S_HISTOGRAM		BIT(26)
+#define INTR_OVERLAY2_DONE		BIT(30)
 
 #ifdef CONFIG_FB_MSM_OVERLAY
-#define MDP4_ANY_INTR_MASK     (INTR_OVERLAY0_DONE| \
-				INTR_PRIMARY_INTF_UDERRUN | \
-				INTR_DMA_P_HISTOGRAM)
+#define MDP4_ANY_INTR_MASK	(INTR_DMA_P_HISTOGRAM | \
+				INTR_DMA_S_HISTOGRAM | \
+				INTR_VG1_HISTOGRAM | \
+				INTR_VG2_HISTOGRAM )
 #else
 #define MDP4_ANY_INTR_MASK	(INTR_DMA_P_DONE| \
-				INTR_DMA_P_HISTOGRAM)
+				INTR_DMA_P_HISTOGRAM | \
+				INTR_DMA_S_HISTOGRAM | \
+				INTR_VG1_HISTOGRAM | \
+				INTR_VG2_HISTOGRAM)
 #endif
+
 enum {
-	OVERLAY_PIPE_RGB1,
-	OVERLAY_PIPE_RGB2,
 	OVERLAY_PIPE_VG1,	/* video/graphic */
 	OVERLAY_PIPE_VG2,
+	OVERLAY_PIPE_RGB1,
+	OVERLAY_PIPE_RGB2,
+	OVERLAY_PIPE_RGB3,
+	OVERLAY_PIPE_VG3,
+	OVERLAY_PIPE_VG4,
 	OVERLAY_PIPE_MAX
 };
 
-/* 2 VG pipes can be shared by RGB and VIDEO */
-#define MDP4_MAX_PIPE   (OVERLAY_PIPE_MAX + 2)
-
-#define OVERLAY_TYPE_RGB        0x01
-#define OVERLAY_TYPE_VIDEO      0x02
+enum {
+	OVERLAY_TYPE_RGB,
+	OVERLAY_TYPE_VIDEO,
+	OVERLAY_TYPE_BF
+};
 
 enum {
 	MDP4_MIXER0,
 	MDP4_MIXER1,
+	MDP4_MIXER2,
 	MDP4_MIXER_MAX
 };
 
-#define MDP4_MAX_MIXER	2
-
 enum {
 	OVERLAY_PLANE_INTERLEAVED,
 	OVERLAY_PLANE_PLANAR,
@@ -158,11 +179,11 @@
 	MDP4_MIXER_STAGE_BASE,
 	MDP4_MIXER_STAGE0,	/* zorder 0 */
 	MDP4_MIXER_STAGE1,	/* zorder 1 */
-	MDP4_MIXER_STAGE2	/* zorder 2 */
+	MDP4_MIXER_STAGE2,	/* zorder 2 */
+	MDP4_MIXER_STAGE3,	/* zorder 3 */
+	MDP4_MIXER_STAGE_MAX
 };
 
-#define MDP4_MAX_STAGE	4
-
 enum {
 	MDP4_FRAME_FORMAT_LINEAR,
 	MDP4_FRAME_FORMAT_ARGB_TILE,
@@ -211,174 +232,708 @@
 #define MDP4_OP_SCALEX_FIR 		(0 << 2)
 #define MDP4_OP_SCALEX_MN_PHASE 	(1 << 2)
 #define MDP4_OP_SCALEX_PIXEL_RPT 	(2 << 2)
+#define MDP4_OP_SCALE_RGB_ENHANCED	(1 << 4)
+#define MDP4_OP_SCALE_RGB_PIXEL_RPT	(0 << 3)
+#define MDP4_OP_SCALE_RGB_BILINEAR	(1 << 3)
+#define MDP4_OP_SCALE_ALPHA_PIXEL_RPT	(0 << 2)
+#define MDP4_OP_SCALE_ALPHA_BILINEAR	(1 << 2)
 #define MDP4_OP_SCALEY_EN	BIT(1)
 #define MDP4_OP_SCALEX_EN	BIT(0)
 
+#define MDP4_REV40_UP_SCALING_MAX (8)
+#define MDP4_REV41_OR_LATER_UP_SCALING_MAX (20)
+
 #define MDP4_PIPE_PER_MIXER	2
 
 #define MDP4_MAX_PLANE		4
+#define VSYNC_PERIOD		16
 
+struct mdp4_hsic_regs {
+	int32_t params[NUM_HSIC_PARAM];
+	int32_t conv_matrix[3][3];
+	int32_t	pre_limit[6];
+	int32_t post_limit[6];
+	int32_t pre_bias[3];
+	int32_t post_bias[3];
+	int32_t dirty;
+};
+
+struct mdp4_iommu_pipe_info {
+	struct ion_handle *ihdl[MDP4_MAX_PLANE];
+	struct ion_handle *prev_ihdl[MDP4_MAX_PLANE];
+	u8 mark_unmap;
+};
+
+#define IOMMU_FREE_LIST_MAX 32
+
+struct iommu_free_list {
+	int total;
+	int fndx;
+	struct ion_handle *ihdl[IOMMU_FREE_LIST_MAX];
+};
+
+struct blend_cfg {
+	u32 op;
+	u32 bg_alpha;
+	u32 fg_alpha;
+	u32 co3_sel;
+	u32 transp_low0;
+	u32 transp_low1;
+	u32 transp_high0;
+	u32 transp_high1;
+	int solidfill;
+	struct mdp4_overlay_pipe *solidfill_pipe;
+};
 
 struct mdp4_overlay_pipe {
-	uint32_t pipe_used;
-	uint32_t pipe_type;		/* rgb, video/graphic */
-	uint32_t pipe_num;
-	uint32_t pipe_ndx;
-	uint32_t mixer_num;		/* which mixer used */
-	uint32_t mixer_stage;		/* which stage of mixer used */
-	uint32_t src_format;
-	uint32_t src_width;	/* source img width */
-	uint32_t src_height;	/* source img height */
-	uint32_t src_w;		/* roi */
-	uint32_t src_h;		/* roi */
-	uint32_t src_x;		/* roi */
-	uint32_t src_y;		/* roi */
-	uint32_t dst_w;		/* roi */
-	uint32_t dst_h;		/* roi */
-	uint32_t dst_x;		/* roi */
-	uint32_t dst_y;		/* roi */
-	uint32_t op_mode;
-	uint32_t transp;
-	uint32_t blend_op;
-	uint32_t phasex_step;
-	uint32_t phasey_step;
-	uint32_t alpha;
-	uint32_t is_fg;		/* control alpha & color key */
-	uint32_t srcp0_addr;	/* interleave, luma */
-	uint32_t srcp0_ystride;
-	uint32_t srcp1_addr;	/* pseudoplanar, chroma plane */
-	uint32_t srcp1_ystride;
-	uint32_t srcp2_addr;	/* planar color 2*/
-	uint32_t srcp2_ystride;
-	uint32_t srcp3_addr;	/* alpha/color 3 */
-	uint32_t srcp3_ystride;
-	uint32_t fetch_plane;
-	uint32_t frame_format;		/* video */
-	uint32_t chroma_site;		/* video */
-	uint32_t chroma_sample;		/* video */
-	uint32_t solid_fill;
-	uint32_t vc1_reduce;		/* video */
-	uint32_t fatch_planes;		/* video */
-	uint32_t unpack_align_msb;/* 0 to LSB, 1 to MSB */
-	uint32_t unpack_tight;/* 0 for loose, 1 for tight */
-	uint32_t unpack_count;/* 0 = 1 component, 1 = 2 component ... */
-	uint32_t rotated_90; /* has been rotated 90 degree */
-	uint32_t bpp;	/* byte per pixel */
-	uint32_t alpha_enable;/*  source has alpha */
+	uint32 pipe_used;
+	uint32 pipe_type;		/* rgb, video/graphic */
+	uint32 pipe_num;
+	uint32 pipe_ndx;
+	uint32 pipe_share;
+	uint32 mixer_num;		/* which mixer used */
+	uint32 mixer_stage;		/* which stage of mixer used */
+	uint32 src_format;
+	uint32 src_width;	/* source img width */
+	uint32 src_height;	/* source img height */
+	uint32 is_3d;
+	uint32 src_width_3d;	/* source img width */
+	uint32 src_height_3d;	/* source img height */
+	uint32 src_w;		/* roi */
+	uint32 src_h;		/* roi */
+	uint32 src_x;		/* roi */
+	uint32 src_y;		/* roi */
+	uint32 dst_w;		/* roi */
+	uint32 dst_h;		/* roi */
+	uint32 dst_x;		/* roi */
+	uint32 dst_y;		/* roi */
+	uint32 flags;
+	uint32 op_mode;
+	uint32 transp;
+	uint32 blend_op;
+	uint32 phasex_step;
+	uint32 phasey_step;
+	uint32 alpha;
+	uint32 is_fg;		/* control alpha & color key */
+	uint32 srcp0_addr;	/* interleave, luma */
+	uint32 srcp0_ystride;
+	uint32 srcp1_addr;	/* pseudoplanar, chroma plane */
+	uint32 srcp1_ystride;
+	uint32 srcp2_addr;	/* planar color 2*/
+	uint32 srcp2_ystride;
+	uint32 srcp3_addr;	/* alpha/color 3 */
+	uint32 srcp3_ystride;
+	uint32 fetch_plane;
+	uint32 frame_format;		/* video */
+	uint32 chroma_site;		/* video */
+	uint32 chroma_sample;		/* video */
+	uint32 solid_fill;
+	uint32 vc1_reduce;		/* video */
+	uint32 unpack_align_msb;/* 0 to LSB, 1 to MSB */
+	uint32 unpack_tight;/* 0 for loose, 1 for tight */
+	uint32 unpack_count;/* 0 = 1 component, 1 = 2 component ... */
+	uint32 rotated_90; /* has been rotated 90 degree */
+	uint32 bpp;	/* byte per pixel */
+	uint32 alpha_enable;/*  source has alpha */
 	/*
 	 * number of bits for source component,
 	 * 0 = 1 bit, 1 = 2 bits, 2 = 6 bits, 3 = 8 bits
 	 */
-	uint32_t a_bit;	/* component 3, alpha */
-	uint32_t r_bit;	/* component 2, R_Cr */
-	uint32_t b_bit;	/* component 1, B_Cb */
-	uint32_t g_bit;	/* component 0, G_lumz */
+	uint32 a_bit;	/* component 3, alpha */
+	uint32 r_bit;	/* component 2, R_Cr */
+	uint32 b_bit;	/* component 1, B_Cb */
+	uint32 g_bit;	/* component 0, G_lumz */
 	/*
 	 * unpack pattern
 	 * A = C3, R = C2, B = C1, G = C0
 	 */
-	uint32_t element3; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
-	uint32_t element2; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
-	uint32_t element1; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
-	uint32_t element0; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
-	struct completion comp;
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-	ulong blt_addr; /* blt mode addr */
-	uint32_t blt_cnt;
-	uint32_t blt_end;
-#endif
+	uint32 element3; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
+	uint32 element2; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
+	uint32 element1; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
+	uint32 element0; /* 0 = C0, 1 = C1, 2 = C2, 3 = C3 */
+	ulong ov_blt_addr; /* blt mode addr */
+	ulong dma_blt_addr; /* blt mode addr */
+	ulong blt_base;
+	ulong blt_offset;
+	uint32 blt_cnt;
+	uint32 blt_changed;
+	uint32 ov_cnt;
+	uint32 dmap_cnt;
+	uint32 dmae_cnt;
+	uint32 blt_end;
+	uint32 blt_ov_koff;
+	uint32 blt_ov_done;
+	uint32 blt_dmap_koff;
+	uint32 blt_dmap_done;
+	uint32 req_clk;
+	uint32 req_bw;
+	uint32 luma_align_size;
+	struct mdp4_hsic_regs hsic_regs;
 	struct mdp_overlay req_data;
-	struct mdp_info *mdp;
+	struct completion comp;
+	struct completion dmas_comp;
+	struct mdp4_iommu_pipe_info iommu;
 };
 
-struct mdp4_pipe_desc {
-	uint32_t ref_cnt;
-	struct mdp4_overlay_pipe *player;
+struct mdp4_statistic {
+	ulong intr_tot;
+	ulong intr_dma_p;
+	ulong intr_dma_s;
+	ulong intr_dma_e;
+	ulong intr_overlay0;
+	ulong intr_overlay1;
+	ulong intr_overlay2;
+	ulong intr_vsync_p;	/* Primary interface */
+	ulong intr_underrun_p;	/* Primary interface */
+	ulong intr_vsync_e;	/* external interface */
+	ulong intr_underrun_e;	/* external interface */
+	ulong intr_histogram;
+	ulong intr_rdptr;
+	ulong dsi_mdp_start;
+	ulong dsi_clk_on;
+	ulong dsi_clk_off;
+	ulong intr_dsi;
+	ulong intr_dsi_mdp;
+	ulong intr_dsi_cmd;
+	ulong intr_dsi_err;
+	ulong kickoff_ov0;
+	ulong kickoff_ov1;
+	ulong kickoff_dmap;
+	ulong kickoff_dmae;
+	ulong kickoff_dmas;
+	ulong blt_dsi_cmd;	/* blt */
+	ulong blt_dsi_video;	/* blt */
+	ulong blt_lcdc;	/* blt */
+	ulong blt_dtv;	/* blt */
+	ulong blt_mddi;	/* blt */
+	ulong overlay_set[MDP4_MIXER_MAX];
+	ulong overlay_unset[MDP4_MIXER_MAX];
+	ulong overlay_play[MDP4_MIXER_MAX];
+	ulong overlay_commit[MDP4_MIXER_MAX];
+	ulong pipe[OVERLAY_PIPE_MAX];
+	ulong wait4vsync0;
+	ulong wait4vsync1;
+	ulong iommu_map;
+	ulong iommu_unmap;
+	ulong iommu_drop;
+	ulong dsi_clkoff;
+	ulong err_mixer;
+	ulong err_zorder;
+	ulong err_size;
+	ulong err_scale;
+	ulong err_format;
+	ulong err_stage;
+	ulong err_play;
+	ulong err_underflow;
 };
 
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-extern spinlock_t mdp_spin_lock;
-extern uint32_t mdp_intr_mask;
-#endif
+struct vsync_update {
+	int update_cnt;	/* pipes to be updated */
+	struct completion vsync_comp;
+	struct mdp4_overlay_pipe plist[OVERLAY_PIPE_MAX];
+};
 
-
-
+struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx);
+void mdp4_sw_reset(unsigned long bits);
+void mdp4_display_intf_sel(int output, unsigned long intf);
+void mdp4_overlay_cfg(int layer, int blt_mode, int refresh, int direct_out);
+void mdp4_ebi2_lcd_setup(int lcd, unsigned long base, int ystride);
+void mdp4_mddi_setup(int which, unsigned long id);
+unsigned long mdp4_display_status(void);
 void mdp4_enable_clk_irq(void);
 void mdp4_disable_clk_irq(void);
+void mdp4_dma_p_update(struct msm_fb_data_type *mfd);
+void mdp4_dma_s_update(struct msm_fb_data_type *mfd);
+void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state,
+		   boolean isr);
+void mdp4_pipe_kickoff(uint32 pipe, struct msm_fb_data_type *mfd);
 int mdp4_lcdc_on(struct platform_device *pdev);
 int mdp4_lcdc_off(struct platform_device *pdev);
+void mdp4_lcdc_update(struct msm_fb_data_type *mfd);
 void mdp4_intr_clear_set(ulong clear, ulong set);
 void mdp4_dma_p_cfg(void);
-void mdp4_hw_init(struct mdp_info *mdp);
+unsigned is_mdp4_hw_reset(void);
+void mdp4_overlay_cfg_init(void);
+void mdp4_hw_init(void);
 void mdp4_isr_read(int);
-void mdp4_clear_lcdc(struct mdp_info *mdp);
-void mdp4_mixer_blend_init(struct mdp_info *mdp, int mixer_num);
-void mdp4_vg_qseed_init(struct mdp_info *mdp, int vg_num);
-void mdp4_vg_csc_mv_setup(struct mdp_info *mdp, int vp_num);
-void mdp4_vg_csc_pre_bv_setup(struct mdp_info *mdp, int vp_num);
-void mdp4_vg_csc_post_bv_setup(struct mdp_info *mdp, int vp_num);
-void mdp4_vg_csc_pre_lv_setup(struct mdp_info *mdp, int vp_num);
-void mdp4_vg_csc_post_lv_setup(struct mdp_info *mdp, int vp_num);
-void mdp4_mixer1_csc_mv_setup(struct mdp_info *mdp);
-void mdp4_mixer1_csc_pre_bv_setup(struct mdp_info *mdp);
-void mdp4_mixer1_csc_post_bv_setup(struct mdp_info *mdp);
-void mdp4_mixer1_csc_pre_lv_setup(struct mdp_info *mdp);
-void mdp4_mixer1_csc_post_lv_setup(struct mdp_info *mdp);
-void mdp4_overlay_format_to_pipe(uint32_t format, struct mdp4_overlay_pipe *pipe);
-uint32_t mdp4_overlay_format(struct mdp4_overlay_pipe *pipe);
-uint32_t mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe);
-uint32_t mdp4_overlay_op_mode(struct mdp4_overlay_pipe *pipe);
+void mdp4_clear_lcdc(void);
+void mdp4_mixer_blend_init(int mixer_num);
+void mdp4_vg_qseed_init(int vg_num);
+void mdp4_vg_csc_setup(int vp_num);
+void mdp4_mixer_csc_setup(uint32 mixer);
+void mdp4_dmap_csc_setup(void);
+void mdp4_vg_csc_update(struct mdp_csc *p);
+irqreturn_t mdp4_isr(int irq, void *ptr);
+void mdp4_overlay_format_to_pipe(uint32 format, struct mdp4_overlay_pipe *pipe);
+uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe);
+uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe);
+uint32 mdp4_overlay_op_mode(struct mdp4_overlay_pipe *pipe);
+void mdp4_lcdc_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd);
+
+
+#ifdef CONFIG_FB_MSM_DTV
+void mdp4_overlay_dtv_start(void);
+void mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe);
+void mdp4_overlay_dtv_wait_for_ov(struct msm_fb_data_type *mfd,
+	struct mdp4_overlay_pipe *pipe);
+int mdp4_overlay_dtv_set(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe);
+int mdp4_overlay_dtv_unset(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe);
+void mdp4_dmae_done_dtv(void);
+void mdp4_dtv_wait4vsync(int cndx, long long *vtime);
+void mdp4_dtv_vsync_ctrl(int cndx, int enable);
+void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
+#else
+static inline void mdp4_overlay_dtv_start(void)
+{
+	/* empty */
+}
+static inline void  mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+	/* empty */
+}
+static inline void  mdp4_overlay_dtv_wait_for_ov(struct msm_fb_data_type *mfd,
+	struct mdp4_overlay_pipe *pipe)
+{
+	/* empty */
+}
+static inline int mdp4_overlay_dtv_set(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+	return 0;
+}
+static inline int mdp4_overlay_dtv_unset(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+	return 0;
+}
+
+static inline void mdp4_dmae_done_dtv(void)
+{
+    /* empty */
+}
+static inline void mdp4_dtv_wait4vsync(int cndx, long long *vtime)
+{
+    /* empty */
+}
+static inline void mdp4_dtv_vsync_ctrl(int cndx, long long *vtime)
+{
+    /* empty */
+}
+static inline void mdp4_dtv_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+	return;
+}
+static inline void mdp4_dtv_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	return;
+}
+static inline void mdp4_dtv_base_swap(struct mdp4_overlay_pipe *pipe)
+{
+	/* empty */
+}
+#endif /* CONFIG_FB_MSM_DTV */
+
+void mdp4_dtv_set_black_screen(void);
+
+int mdp4_overlay_dtv_set(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe);
+int mdp4_overlay_dtv_unset(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe);
+void mdp4_dtv_overlay(struct msm_fb_data_type *mfd);
+int mdp4_dtv_on(struct platform_device *pdev);
+int mdp4_dtv_off(struct platform_device *pdev);
+void mdp4_atv_overlay(struct msm_fb_data_type *mfd);
+int mdp4_atv_on(struct platform_device *pdev);
+int mdp4_atv_off(struct platform_device *pdev);
+void mdp4_dsi_video_fxn_register(cmd_fxn_t fxn);
+void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd);
+void mdp4_lcdc_vsync_ctrl(int cndx, int enable);
+void mdp4_overlay0_done_dsi_video(int cndx);
+void mdp4_overlay0_done_dsi_cmd(int cndx);
+void mdp4_primary_rdptr(void);
+void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd);
+int mdp4_overlay_commit(struct fb_info *info, int mixer);
+int mdp4_dsi_video_pipe_commit(void);
+int mdp4_dsi_cmd_pipe_commit(void);
+int mdp4_dsi_cmd_update_cnt(int cndx);
+int mdp4_lcdc_pipe_commit(void);
+int mdp4_dtv_pipe_commit(void);
+void mdp4_dsi_rdptr_init(int cndx);
+void mdp4_dsi_vsync_init(int cndx);
+void mdp4_lcdc_vsync_init(int cndx);
+void mdp4_dtv_vsync_init(int cndx);
+void mdp4_overlay_dsi_state_set(int state);
+int mdp4_overlay_dsi_state_get(void);
 void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe);
 void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all);
-void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe);
+void mdp4_mixer_blend_setup(int mixer);
 struct mdp4_overlay_pipe *mdp4_overlay_stage_pipe(int mixer, int stage);
 void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe);
 void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe);
+void mdp4_mixer_pipe_cleanup(int mixer);
 int mdp4_mixer_stage_can_run(struct mdp4_overlay_pipe *pipe);
 void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe);
-void mdp4_mddi_overlay(void *priv, uint32_t addr, uint32_t stride,
-			    uint32_t width, uint32_t height, uint32_t x,
-			    uint32_t y);
-int mdp4_overlay_format2type(uint32_t format);
+void mdp4_mddi_overlay(struct msm_fb_data_type *mfd);
+int mdp4_overlay_format2type(uint32 format);
 int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe);
-int mdp4_overlay_get(struct mdp_device *mdp_dev, struct fb_info *info, struct mdp_overlay *req);
-int mdp4_overlay_set(struct mdp_device *mdp_dev, struct fb_info *info, struct mdp_overlay *req);
-int mdp4_overlay_unset(struct mdp_device *mdp_dev, struct fb_info *info, int ndx);
-int mdp4_overlay_play(struct mdp_device *mdp_dev, struct fb_info *info, struct msmfb_overlay_data *req,
-				struct file **pp_src_file);
-int mdp4_overlay_change_z_order_vg_pipes(struct fb_info *info);
-struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, bool usevg);
+int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req);
+int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req);
+int mdp4_overlay_wait4vsync(struct fb_info *info, long long *vtime);
+int mdp4_overlay_vsync_ctrl(struct fb_info *info, int enable);
+int mdp4_overlay_unset(struct fb_info *info, int ndx);
+int mdp4_overlay_unset_mixer(int mixer);
+int mdp4_overlay_play_wait(struct fb_info *info,
+	struct msmfb_overlay_data *req);
+int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req);
+struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer);
+void mdp4_overlay_dma_commit(int mixer);
+void mdp4_overlay_vsync_commit(struct mdp4_overlay_pipe *pipe);
+void mdp4_mixer_stage_commit(int mixer);
+void mdp4_dsi_cmd_do_update(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_lcdc_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
 void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe);
-void mdp4_overlay_dmap_cfg(struct mdp4_overlay_pipe *pipe, int lcdc);
+void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc);
 void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe);
-void mdp4_overlay_dmae_cfg(struct mdp4_overlay_pipe *pipe, int lcdc);
+void mdp4_overlay_dmae_cfg(struct msm_fb_data_type *mfd, int atv);
 void mdp4_overlay_dmae_xy(struct mdp4_overlay_pipe *pipe);
-void mdp4_overlay_dmas_cfg(struct mdp4_overlay_pipe *pipe, int lcdc);
-void mdp4_overlay_dmas_xy(struct mdp4_overlay_pipe *pipe);
-int mdp4_overlay_active(struct mdp_info *mdp, int mixer);
-void mdp4_overlay0_done_lcdc(void);
-void mdp4_overlay0_done_mddi(void);
-void mdp4_dma_s_done_mddi(void);
-void mdp4_mddi_overlay_restore(void);
-void mdp4_mddi_dma_s_kickoff(struct mdp_info *mdp, struct mdp4_overlay_pipe *pipe);
-void mdp4_mddi_overlay_kickoff(struct mdp_info *mdp,
+int mdp4_overlay_pipe_staged(int mixer);
+void mdp4_lcdc_primary_vsyn(void);
+void mdp4_overlay0_done_lcdc(int cndx);
+void mdp4_overlay0_done_mddi(struct mdp_dma_data *dma);
+void mdp4_dma_p_done_mddi(struct mdp_dma_data *dma);
+void mdp4_dmap_done_dsi_cmd(int cndx);
+void mdp4_dmap_done_dsi_video(int cndx);
+void mdp4_dmap_done_lcdc(int cndx);
+void mdp4_overlay1_done_dtv(void);
+void mdp4_overlay1_done_atv(void);
+void mdp4_primary_vsync_lcdc(void);
+void mdp4_external_vsync_dtv(void);
+void mdp4_lcdc_wait4vsync(int cndx, long long *vtime);
+void mdp4_overlay_lcdc_vsync_push(struct msm_fb_data_type *mfd,
 				struct mdp4_overlay_pipe *pipe);
-void mdp4_rgb_igc_lut_setup(struct mdp_info *mdp, int num);
-void mdp4_vg_igc_lut_setup(struct mdp_info *mdp, int num);
-void mdp4_mixer_gc_lut_setup(struct mdp_info *mdp, int mixer_num);
-void mdp4_fetch_cfg(struct mdp_info *mdp, uint32_t clk, uint32_t pclk);
-uint32_t mdp4_rgb_igc_lut_cvt(uint32_t ndx);
-void mdp_pipe_kickoff(struct mdp_info *mdp, uint32_t term);
+void mdp4_mddi_overlay_dmas_restore(void);
 
-void mdp4_overlay_status_write(enum mdp4_overlay_status type, bool val);
-bool mdp4_overlay_status_read(enum mdp4_overlay_status type);
-
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-void mdp4_dma_p_done_mddi(void);
-int mdp4_overlay_blt(struct mdp_device *mdp_dev, struct fb_info *info,
-		struct msmfb_overlay_blt *req, struct file **pp_src_file);
-void mdp4_mddi_overlay_blt(ulong addr);
-void mdp4_lcdc_overlay_blt(ulong addr);
+#ifndef CONFIG_FB_MSM_MIPI_DSI
+void mdp4_mddi_dma_busy_wait(struct msm_fb_data_type *mfd);
+void mdp4_mddi_overlay_restore(void);
+#else
+static inline void mdp4_mddi_kickoff_video(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+	/* empty */
+}
+static inline void mdp4_mddi_dma_busy_wait(struct msm_fb_data_type *mfd)
+{
+	/* empty */
+}
+static inline void mdp4_mddi_blt_dmap_busy_wait(struct msm_fb_data_type *mfd)
+{
+	/* empty */
+}
+static inline void mdp4_mddi_overlay_restore(void)
+{
+	/* empty */
+}
+static inline void mdp4_mddi_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+	/*empty*/
+}
+static inline void mdp4_mddi_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	/*empty*/
+}
+static inline void mdp4_mddi_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	/* empty */
+}
+static inline void mdp4_mddi_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	/* empty*/
+}
 #endif
 
+void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe);
+void mdp4_rgb_igc_lut_setup(int num);
+void mdp4_vg_igc_lut_setup(int num);
+void mdp4_mixer_gc_lut_setup(int mixer_num);
+void mdp4_fetch_cfg(uint32 clk);
+uint32 mdp4_rgb_igc_lut_cvt(uint32 ndx);
+void mdp4_vg_qseed_init(int);
+int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req);
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+void mdp4_dsi_cmd_blt_start(struct msm_fb_data_type *mfd);
+void mdp4_dsi_cmd_blt_stop(struct msm_fb_data_type *mfd);
+void mdp4_dsi_video_blt_start(struct msm_fb_data_type *mfd);
+void mdp4_dsi_video_blt_stop(struct msm_fb_data_type *mfd);
+void mdp4_dsi_cmd_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req);
+
+void mdp4_dsi_video_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req);
+void mdp4_dsi_video_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
+
+#ifdef CONFIG_FB_MSM_MDP40
+static inline void mdp3_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd)
+{
+	/* empty */
+}
+#endif
+#else     /* CONFIG_FB_MSM_MIPI_DSI */
+int mdp4_mddi_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req);
+void mdp4_mddi_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req);
+int mdp4_mddi_overlay_blt_start(struct msm_fb_data_type *mfd);
+int mdp4_mddi_overlay_blt_stop(struct msm_fb_data_type *mfd);
+void mdp4_mddi_blt_dmap_busy_wait(struct msm_fb_data_type *mfd);
+static inline int mdp4_dsi_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+	return -ENODEV;
+}
+static inline int mdp4_dsi_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	return -ENODEV;
+}
+static inline void mdp4_dsi_video_blt_start(struct msm_fb_data_type *mfd)
+{
+}
+static inline void mdp4_dsi_video_blt_stop(struct msm_fb_data_type *mfd)
+{
+}
+static inline void mdp4_dsi_overlay_blt(
+	struct msm_fb_data_type *mfd, struct msmfb_overlay_blt *req)
+{
+}
+static inline int mdp4_dsi_overlay_blt_offset(
+	struct msm_fb_data_type *mfd, struct msmfb_overlay_blt *req)
+{
+	return -ENODEV;
+}
+static inline void mdp4_dsi_video_overlay_blt(
+	struct msm_fb_data_type *mfd, struct msmfb_overlay_blt *req)
+{
+}
+static inline void mdp4_dsi_cmd_overlay_blt(
+	struct msm_fb_data_type *mfd, struct msmfb_overlay_blt *req)
+{
+}
+static inline void mdp4_dsi_video_base_swap(int cndx,
+			struct mdp4_overlay_pipe *pipe)
+{
+	/* empty */
+}
+static inline void mdp4_dsi_cmd_blt_start(struct msm_fb_data_type *mfd)
+{
+        /* empty */
+}
+static inline void mdp4_dsi_cmd_blt_stop(struct msm_fb_data_type *mfd)
+{
+        /* empty */
+}
+#endif  /* CONFIG_FB_MSM_MIPI_DSI */
+
+void mdp4_lcdc_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req);
+int mdp4_lcdc_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req);
+void mdp4_lcdc_overlay_blt_start(struct msm_fb_data_type *mfd);
+void mdp4_lcdc_overlay_blt_stop(struct msm_fb_data_type *mfd);
+void mdp4_dtv_overlay_blt_start(struct msm_fb_data_type *mfd);
+void mdp4_dtv_overlay_blt_stop(struct msm_fb_data_type *mfd);
+void mdp4_overlay_panel_mode(int mixer_num, uint32 mode);
+void mdp4_overlay_panel_mode_unset(int mixer_num, uint32 mode);
+int mdp4_overlay_mixer_play(int mixer_num);
+uint32 mdp4_overlay_panel_list(void);
+void mdp4_lcdc_overlay_kickoff(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe);
+
+void mdp4_mddi_kickoff_video(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe);
+
+void mdp4_mddi_read_ptr_intr(void);
+
+void mdp4_dsi_cmd_dma_busy_check(void);
+
+
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+void mdp_dsi_cmd_overlay_suspend(struct msm_fb_data_type *mfd);
+int mdp4_dsi_cmd_on(struct platform_device *pdev);
+int mdp4_dsi_cmd_off(struct platform_device *pdev);
+int mdp4_dsi_video_off(struct platform_device *pdev);
+int mdp4_dsi_video_on(struct platform_device *pdev);
+void mdp4_primary_vsync_dsi_video(void);
+void mdp4_dsi_cmd_base_swap(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime);
+void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime);
+void mdp4_dsi_cmd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_dsi_video_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe);
+void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable);
+void mdp4_dsi_video_vsync_ctrl(int cndx, int enable);
+#ifdef CONFIG_FB_MSM_MDP303
+static inline void mdp4_dsi_cmd_del_timer(void)
+{
+	/* empty */
+}
+#else /* CONFIG_FB_MSM_MIPI_DSI */
+void mdp4_dsi_cmd_del_timer(void);
+#endif
+#else  /* CONFIG_FB_MSM_MIPI_DSI */
+
+static inline int mdp4_dsi_cmd_on(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline int mdp4_dsi_cmd_off(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline int mdp4_dsi_video_on(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline int mdp4_dsi_video_off(struct platform_device *pdev)
+{
+	return 0;
+}
+static inline void mdp4_primary_vsync_dsi_video(void)
+{
+}
+static inline void mdp4_dsi_cmd_base_swap(int cndx,
+	struct mdp4_overlay_pipe *pipe)
+{
+}
+static inline void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
+{
+}
+static inline void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime)
+{
+}
+static inline void mdp4_dsi_cmd_pipe_queue(int cndx,
+			struct mdp4_overlay_pipe *pipe)
+{
+}
+static inline void mdp4_dsi_video_pipe_queue(int cndx,
+			struct mdp4_overlay_pipe *pipe)
+{
+}
+static inline void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable)
+{
+}
+static inline void mdp4_dsi_video_vsync_ctrl(int cndx, int enable)
+{
+}
+
+static inline void mdp4_overlay_dsi_video_start(void)
+{
+	/* empty */
+}
+#ifdef CONFIG_FB_MSM_MDP40
+static inline void mdp_dsi_cmd_overlay_suspend(struct msm_fb_data_type *mfd)
+{
+	/* empty */
+}
+#endif
+#endif /* CONFIG_FB_MSM_MIPI_DSI */
+
+void mdp4_dsi_cmd_kickoff_ui(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe);
+void mdp4_dsi_cmd_kickoff_video(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe);
+void mdp4_dsi_cmd_overlay_kickoff(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe);
+void mdp4_overlay_panel_3d(int mixer_num, uint32 panel_3d);
+int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req);
+void mdp4_dsi_cmd_3d_sbys(struct msm_fb_data_type *mfd,
+			 struct msmfb_overlay_3d *r3d);
+void mdp4_dsi_video_3d_sbys(struct msm_fb_data_type *mfd,
+			 struct msmfb_overlay_3d *r3d);
+
+int mdp4_mixer_info(int mixer_num, struct mdp_mixer_info *info);
+
+void mdp_dmap_vsync_set(int enable);
+int mdp_dmap_vsync_get(void);
+void mdp_hw_cursor_done(void);
+void mdp_hw_cursor_init(void);
+int mdp4_mddi_overlay_cursor(struct fb_info *info, struct fb_cursor *cursor);
+int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req);
+void mdp4_overlay_resource_release(void);
+uint32_t mdp4_ss_table_value(int8_t param, int8_t index);
+void mdp4_overlay_status_write(enum mdp4_overlay_status type, bool val);
+bool mdp4_overlay_status_read(enum mdp4_overlay_status type);
+void mdp4_overlay_borderfill_stage_down(struct mdp4_overlay_pipe *pipe);
+
+#ifdef CONFIG_FB_MSM_MDP303
+static inline int mdp4_overlay_borderfill_supported(void)
+{
+	return 0;
+}
+#else
+int mdp4_overlay_borderfill_supported(void);
+#endif
+
+int mdp4_overlay_writeback_on(struct platform_device *pdev);
+int mdp4_overlay_writeback_off(struct platform_device *pdev);
+void mdp4_writeback_overlay(struct msm_fb_data_type *mfd);
+void mdp4_writeback_kickoff_video(struct msm_fb_data_type *mfd,
+		struct mdp4_overlay_pipe *pipe);
+void mdp4_writeback_dma_busy_wait(struct msm_fb_data_type *mfd);
+void mdp4_overlay1_done_writeback(struct mdp_dma_data *dma);
+void mdp4_dma_e_done_dtv(void);
+
+int mdp4_writeback_start(struct fb_info *info);
+int mdp4_writeback_stop(struct fb_info *info);
+int mdp4_writeback_dequeue_buffer(struct fb_info *info,
+		struct msmfb_data *data);
+int mdp4_writeback_queue_buffer(struct fb_info *info,
+		struct msmfb_data *data);
+void mdp4_writeback_dma_stop(struct msm_fb_data_type *mfd);
+int mdp4_writeback_init(struct fb_info *info);
+int mdp4_writeback_terminate(struct fb_info *info);
+
+uint32_t mdp_block2base(uint32_t block);
+int mdp_hist_lut_config(struct mdp_hist_lut_data *data);
+
+void mdp4_hsic_set(struct mdp4_overlay_pipe *pipe, struct dpp_ctrl *ctrl);
+void mdp4_hsic_update(struct mdp4_overlay_pipe *pipe);
+int mdp4_csc_config(struct mdp_csc_cfg_data *config);
+void mdp4_csc_write(struct mdp_csc_cfg *data, uint32_t base);
+int mdp4_csc_enable(struct mdp_csc_cfg_data *config);
+int mdp4_pcc_cfg(struct mdp_pcc_cfg_data *cfg_ptr);
+int mdp4_argc_cfg(struct mdp_pgc_lut_data *pgc_ptr);
+
+u32  mdp4_allocate_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num);
+void mdp4_init_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num);
+void mdp4_free_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num);
+
+int mdp4_igc_lut_config(struct mdp_igc_lut_data *cfg);
+void mdp4_overlay_iommu_pipe_free(int ndx, int all);
+void mdp4_overlay_iommu_free_list(int mixer, struct ion_handle *ihdl);
+void mdp4_overlay_iommu_unmap_freelist(int mixer);
+void mdp4_overlay_iommu_vsync_cnt(void);
+void mdp4_iommu_unmap(struct mdp4_overlay_pipe *pipe);
+void mdp4_iommu_attach(void);
+void mdp4_iommu_detach(void);
+int mdp4_v4l2_overlay_set(struct fb_info *info, struct mdp_overlay *req,
+		struct mdp4_overlay_pipe **ppipe);
+void mdp4_v4l2_overlay_clear(struct mdp4_overlay_pipe *pipe);
+int mdp4_v4l2_overlay_play(struct fb_info *info, struct mdp4_overlay_pipe *pipe,
+	unsigned long srcp0_addr, unsigned long srcp1_addr,
+	unsigned long srcp2_addr);
+
+int mdp4_overlay_mdp_pipe_req(struct mdp4_overlay_pipe *pipe,
+			      struct msm_fb_data_type *mfd);
+int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd,
+			      struct mdp4_overlay_pipe *plist);
+void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, int flag);
 #endif /* MDP_H */
diff --git a/drivers/video/msm/mdp4_dtv.c b/drivers/video/msm/mdp4_dtv.c
new file mode 100644
index 0000000..bd0ce2f
--- /dev/null
+++ b/drivers/video/msm/mdp4_dtv.c
@@ -0,0 +1,327 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <linux/pm_runtime.h>
+#include <mach/clk.h>
+
+#include "msm_fb.h"
+#include "mdp4.h"
+
+static int dtv_probe(struct platform_device *pdev);
+static int dtv_remove(struct platform_device *pdev);
+
+static int dtv_off(struct platform_device *pdev);
+static int dtv_on(struct platform_device *pdev);
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+
+static struct clk *tv_src_clk;
+static struct clk *hdmi_clk;
+static struct clk *mdp_tv_clk;
+
+
+static int mdp4_dtv_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int mdp4_dtv_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+
+static const struct dev_pm_ops mdp4_dtv_dev_pm_ops = {
+	.runtime_suspend = mdp4_dtv_runtime_suspend,
+	.runtime_resume = mdp4_dtv_runtime_resume,
+};
+
+static struct platform_driver dtv_driver = {
+	.probe = dtv_probe,
+	.remove = dtv_remove,
+	.suspend = NULL,
+	.resume = NULL,
+	.shutdown = NULL,
+	.driver = {
+		   .name = "dtv",
+		   .pm = &mdp4_dtv_dev_pm_ops,
+		   },
+};
+
+static struct lcdc_platform_data *dtv_pdata;
+#ifdef CONFIG_MSM_BUS_SCALING
+static uint32_t dtv_bus_scale_handle;
+#else
+static struct clk *ebi1_clk;
+#endif
+
+static int dtv_off(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	ret = panel_next_off(pdev);
+
+	pr_info("%s\n", __func__);
+
+	clk_disable_unprepare(hdmi_clk);
+	if (mdp_tv_clk)
+		clk_disable_unprepare(mdp_tv_clk);
+
+	if (dtv_pdata && dtv_pdata->lcdc_power_save)
+		dtv_pdata->lcdc_power_save(0);
+
+	if (dtv_pdata && dtv_pdata->lcdc_gpio_config)
+		ret = dtv_pdata->lcdc_gpio_config(0);
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (dtv_bus_scale_handle > 0)
+		msm_bus_scale_client_update_request(dtv_bus_scale_handle,
+							0);
+#else
+	if (ebi1_clk)
+		clk_disable_unprepare(ebi1_clk);
+#endif
+	mdp4_extn_disp = 0;
+	return ret;
+}
+
+static int dtv_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_data_type *mfd;
+	unsigned long panel_pixclock_freq , pm_qos_rate;
+
+	mfd = platform_get_drvdata(pdev);
+	panel_pixclock_freq = mfd->fbi->var.pixclock;
+
+	if (panel_pixclock_freq > 58000000)
+		/* pm_qos_rate should be in Khz */
+		pm_qos_rate = panel_pixclock_freq / 1000 ;
+	else
+		pm_qos_rate = 58000;
+	mdp4_extn_disp = 1;
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (dtv_bus_scale_handle > 0)
+		msm_bus_scale_client_update_request(dtv_bus_scale_handle,
+							1);
+#else
+	if (ebi1_clk) {
+		clk_set_rate(ebi1_clk, pm_qos_rate * 1000);
+		clk_prepare_enable(ebi1_clk);
+	}
+#endif
+
+	if (dtv_pdata && dtv_pdata->lcdc_power_save)
+		dtv_pdata->lcdc_power_save(1);
+	if (dtv_pdata && dtv_pdata->lcdc_gpio_config)
+		ret = dtv_pdata->lcdc_gpio_config(1);
+
+	mfd = platform_get_drvdata(pdev);
+
+	ret = clk_set_rate(tv_src_clk, mfd->fbi->var.pixclock);
+	if (ret) {
+		pr_info("%s: clk_set_rate(%d) failed\n", __func__,
+			mfd->fbi->var.pixclock);
+		if (mfd->fbi->var.pixclock == 27030000)
+			mfd->fbi->var.pixclock = 27000000;
+		ret = clk_set_rate(tv_src_clk, mfd->fbi->var.pixclock);
+	}
+	pr_info("%s: tv_src_clk=%dkHz, pm_qos_rate=%ldkHz, [%d]\n", __func__,
+		mfd->fbi->var.pixclock/1000, pm_qos_rate, ret);
+	mfd->panel_info.clk_rate = mfd->fbi->var.pixclock;
+	clk_prepare_enable(hdmi_clk);
+	clk_reset(hdmi_clk, CLK_RESET_ASSERT);
+	udelay(20);
+	clk_reset(hdmi_clk, CLK_RESET_DEASSERT);
+
+	if (mdp_tv_clk)
+		clk_prepare_enable(mdp_tv_clk);
+
+	ret = panel_next_on(pdev);
+	return ret;
+}
+
+static int dtv_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct fb_info *fbi;
+	struct platform_device *mdp_dev = NULL;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc;
+
+	if (pdev->id == 0) {
+		dtv_pdata = pdev->dev.platform_data;
+#ifdef CONFIG_MSM_BUS_SCALING
+		if (!dtv_bus_scale_handle && dtv_pdata &&
+			dtv_pdata->bus_scale_table) {
+			dtv_bus_scale_handle =
+				msm_bus_scale_register_client(
+						dtv_pdata->bus_scale_table);
+			if (!dtv_bus_scale_handle) {
+				pr_err("%s not able to get bus scale\n",
+					__func__);
+			}
+		}
+#else
+		ebi1_clk = clk_get(&pdev->dev, "mem_clk");
+		if (IS_ERR(ebi1_clk)) {
+			ebi1_clk = NULL;
+			pr_warning("%s: Couldn't get ebi1 clock\n", __func__);
+		}
+#endif
+		tv_src_clk = clk_get(&pdev->dev, "src_clk");
+		if (IS_ERR(tv_src_clk)) {
+			pr_err("error: can't get tv_src_clk!\n");
+			return IS_ERR(tv_src_clk);
+		}
+
+		hdmi_clk = clk_get(&pdev->dev, "hdmi_clk");
+		if (IS_ERR(hdmi_clk)) {
+			pr_err("error: can't get hdmi_clk!\n");
+			return IS_ERR(hdmi_clk);
+		}
+
+		mdp_tv_clk = clk_get(&pdev->dev, "mdp_clk");
+		if (IS_ERR(mdp_tv_clk))
+			mdp_tv_clk = NULL;
+
+		return 0;
+	}
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	mdp_dev = platform_device_alloc("mdp", pdev->id);
+	if (!mdp_dev)
+		return -ENOMEM;
+
+	/*
+	 * link to the latest pdev
+	 */
+	mfd->pdev = mdp_dev;
+	mfd->dest = DISPLAY_LCDC;
+
+	/*
+	 * alloc panel device data
+	 */
+	if (platform_device_add_data
+	    (mdp_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		pr_err("dtv_probe: platform_device_add_data failed!\n");
+		platform_device_put(mdp_dev);
+		return -ENOMEM;
+	}
+	/*
+	 * data chain
+	 */
+	pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data;
+	pdata->on = dtv_on;
+	pdata->off = dtv_off;
+	pdata->next = pdev;
+
+	/*
+	 * get/set panel specific fb info
+	 */
+	mfd->panel_info = pdata->panel_info;
+	if (hdmi_prim_display)
+		mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
+	else
+		mfd->fb_imgType = MDP_RGB_565;
+
+	fbi = mfd->fbi;
+	fbi->var.pixclock = mfd->panel_info.clk_rate;
+	fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
+	fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
+	fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
+	fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch;
+	fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width;
+	fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width;
+
+	/*
+	 * set driver data
+	 */
+	platform_set_drvdata(mdp_dev, mfd);
+
+	/*
+	 * register in mdp driver
+	 */
+	rc = platform_device_add(mdp_dev);
+	if (rc)
+		goto dtv_probe_err;
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	pdev_list[pdev_list_cnt++] = pdev;
+	return 0;
+
+dtv_probe_err:
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (dtv_pdata && dtv_pdata->bus_scale_table &&
+		dtv_bus_scale_handle > 0)
+		msm_bus_scale_unregister_client(dtv_bus_scale_handle);
+#endif
+	platform_device_put(mdp_dev);
+	return rc;
+}
+
+static int dtv_remove(struct platform_device *pdev)
+{
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (dtv_pdata && dtv_pdata->bus_scale_table &&
+		dtv_bus_scale_handle > 0)
+		msm_bus_scale_unregister_client(dtv_bus_scale_handle);
+#else
+	if (ebi1_clk)
+		clk_put(ebi1_clk);
+#endif
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static int dtv_register_driver(void)
+{
+	return platform_driver_register(&dtv_driver);
+}
+
+static int __init dtv_driver_init(void)
+{
+	return dtv_register_driver();
+}
+
+module_init(dtv_driver_init);
diff --git a/drivers/video/msm/mdp4_hsic.c b/drivers/video/msm/mdp4_hsic.c
new file mode 100644
index 0000000..5735f45
--- /dev/null
+++ b/drivers/video/msm/mdp4_hsic.c
@@ -0,0 +1,534 @@
+/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/msm_mdp.h>
+#include "mdp.h"
+#include "mdp4.h"
+
+/* Definitions */
+#define MDP4_CSC_MV_OFF		0x4400
+#define MDP4_CSC_PRE_BV_OFF	0x4500
+#define MDP4_CSC_POST_BV_OFF	0x4580
+#define MDP4_CSC_PRE_LV_OFF	0x4600
+#define MDP4_CSC_POST_LV_OFF	0x4680
+#define MDP_VG1_BASE	(MDP_BASE + MDP4_VIDEO_BASE)
+
+#define MDP_VG1_CSC_MVn(n)	(MDP_VG1_BASE + MDP4_CSC_MV_OFF + 4 * (n))
+#define MDP_VG1_CSC_PRE_LVn(n)	(MDP_VG1_BASE + MDP4_CSC_PRE_LV_OFF + 4 * (n))
+#define MDP_VG1_CSC_POST_LVn(n)	(MDP_VG1_BASE + MDP4_CSC_POST_LV_OFF + 4 * (n))
+#define MDP_VG1_CSC_PRE_BVn(n)	(MDP_VG1_BASE + MDP4_CSC_PRE_BV_OFF + 4 * (n))
+#define MDP_VG1_CSC_POST_BVn(n)	(MDP_VG1_BASE + MDP4_CSC_POST_BV_OFF + 4 * (n))
+
+#define Q16	(16)
+#define Q16_ONE	(1 << Q16)
+
+#define Q16_VALUE(x)	((int32_t)((uint32_t)x << Q16))
+#define Q16_PERCENT_VALUE(x, n)	((int32_t)( \
+				div_s64(((int64_t)x * (int64_t)Q16_ONE), n)))
+
+#define Q16_WHOLE(x)	((int32_t)(x >> 16))
+#define Q16_FRAC(x)	((int32_t)(x & 0xFFFF))
+#define Q16_S1Q16_MUL(x, y)	(((x >> 1) * (y >> 1)) >> 14)
+
+#define Q16_MUL(x, y)	((int32_t)((((int64_t)x) * ((int64_t)y)) >> Q16))
+#define Q16_NEGATE(x)	(0 - (x))
+
+/*
+ * HSIC Control min/max values
+ *    These settings are based on the maximum/minimum allowed modifications to
+ *    HSIC controls for layer and display color.  Allowing too much variation in
+ *    the CSC block will result in color clipping resulting in unwanted color
+ *    shifts.
+ */
+#define TRIG_MAX	Q16_VALUE(128)
+#define CON_SAT_MAX	Q16_VALUE(128)
+#define INTENSITY_MAX	(Q16_VALUE(2047) >> 12)
+
+#define HUE_MAX	Q16_VALUE(100)
+#define HUE_MIN	Q16_VALUE(-100)
+#define HUE_DEF	Q16_VALUE(0)
+
+#define SAT_MAX	Q16_VALUE(100)
+#define SAT_MIN	Q16_VALUE(-100)
+#define SAT_DEF	CON_SAT_MAX
+
+#define CON_MAX	Q16_VALUE(100)
+#define CON_MIN	Q16_VALUE(-100)
+#define CON_DEF	CON_SAT_MAX
+
+#define INTEN_MAX	Q16_VALUE(100)
+#define INTEN_MIN	Q16_VALUE(-100)
+#define INTEN_DEF	Q16_VALUE(0)
+
+enum {
+	DIRTY,
+	GENERATED,
+	CLEAN
+};
+
+/* local vars*/
+static int32_t csc_matrix_tab[3][3] = {
+	{0x00012a00, 0x00000000, 0x00019880},
+	{0x00012a00, 0xffff9b80, 0xffff3000},
+	{0x00012a00, 0x00020480, 0x00000000}
+};
+
+static int32_t csc_yuv2rgb_conv_tab[3][3] = {
+	{0x00010000, 0x00000000, 0x000123cb},
+	{0x00010000, 0xffff9af9, 0xffff6b5e},
+	{0x00010000, 0x00020838, 0x00000000}
+};
+
+static int32_t csc_rgb2yuv_conv_tab[3][3] = {
+	{0x00004c8b, 0x00009645, 0x00001d2f},
+	{0xffffda56, 0xffffb60e, 0x00006f9d},
+	{0x00009d70, 0xffff7c2a, 0xffffe666}
+};
+
+static uint32_t csc_pre_bv_tab[3]  = {0xfffff800, 0xffffc000, 0xffffc000};
+static uint32_t csc_post_bv_tab[3] = {0x00000000, 0x00000000, 0x00000000};
+
+static uint32_t csc_pre_lv_tab[6] =  {0x00000000, 0x00007f80, 0x00000000,
+					0x00007f80, 0x00000000, 0x00007f80};
+static uint32_t csc_post_lv_tab[6] = {0x00000000, 0x00007f80, 0x00000000,
+					0x00007f80, 0x00000000, 0x00007f80};
+
+/* Lookup table for Sin/Cos lookup - Q16*/
+static const int32_t  trig_lut[65] = {
+	0x00000000, /* sin((2*M_PI/256) * 0x00);*/
+	0x00000648, /* sin((2*M_PI/256) * 0x01);*/
+	0x00000C90, /* sin((2*M_PI/256) * 0x02);*/
+	0x000012D5,
+	0x00001918,
+	0x00001F56,
+	0x00002590,
+	0x00002BC4,
+	0x000031F1,
+	0x00003817,
+	0x00003E34,
+	0x00004447,
+	0x00004A50,
+	0x0000504D,
+	0x0000563E,
+	0x00005C22,
+	0x000061F8,
+	0x000067BE,
+	0x00006D74,
+	0x0000731A,
+	0x000078AD,
+	0x00007E2F,
+	0x0000839C,
+	0x000088F6,
+	0x00008E3A,
+	0x00009368,
+	0x00009880,
+	0x00009D80,
+	0x0000A268,
+	0x0000A736,
+	0x0000ABEB,
+	0x0000B086,
+	0x0000B505,
+	0x0000B968,
+	0x0000BDAF,
+	0x0000C1D8,
+	0x0000C5E4,
+	0x0000C9D1,
+	0x0000CD9F,
+	0x0000D14D,
+	0x0000D4DB,
+	0x0000D848,
+	0x0000DB94,
+	0x0000DEBE,
+	0x0000E1C6,
+	0x0000E4AA,
+	0x0000E768,
+	0x0000EA0A,
+	0x0000EC83,
+	0x0000EED9,
+	0x0000F109,
+	0x0000F314,
+	0x0000F4FA,
+	0x0000F6BA,
+	0x0000F854,
+	0x0000F9C8,
+	0x0000FB15,
+	0x0000FC3B,
+	0x0000FD3B,
+	0x0000FE13,
+	0x0000FEC4,
+	0x0000FF4E,
+	0x0000FFB1,
+	0x0000FFEC,
+	0x00010000, /* sin((2*M_PI/256) * 0x40);*/
+};
+
+void trig_values_q16(int32_t deg, int32_t *cos, int32_t *sin)
+{
+	int32_t   angle;
+	int32_t   quad, anglei, anglef;
+	int32_t   v0 = 0, v1 = 0;
+	int32_t   t1, t2;
+
+	/*
+	 * Scale the angle so that 256 is one complete revolution and mask it
+	 * to this domain
+	 * NOTE: 0xB60B == 256/360
+	 */
+	angle = Q16_MUL(deg, 0xB60B) & 0x00FFFFFF;
+
+	/* Obtain a quadrant number, integer, and fractional part */
+	quad   =  angle >> 22;
+	anglei = (angle >> 16) & 0x3F;
+	anglef =  angle & 0xFFFF;
+
+	/*
+	 * Using the integer part, obtain the lookup table entry and its
+	 * complement. Using the quadrant, swap and negate these as
+	 * necessary.
+	 * (The values and all derivatives of sine and cosine functions
+	 * can be derived from these values)
+	 */
+	switch (quad) {
+	case 0x0:
+		v0 += trig_lut[anglei];
+		v1 += trig_lut[0x40-anglei];
+		break;
+
+	case 0x1:
+		v0 += trig_lut[0x40-anglei];
+		v1 -= trig_lut[anglei];
+		break;
+
+	case 0x2:
+		v0 -= trig_lut[anglei];
+		v1 -= trig_lut[0x40-anglei];
+		break;
+
+	case 0x3:
+		v0 -= trig_lut[0x40-anglei];
+		v1 += trig_lut[anglei];
+		break;
+	}
+
+	/*
+	 * Multiply the fractional part by 2*PI/256 to move it from lookup
+	 *  table units to radians, giving us the coefficient for first
+	 *  derivatives.
+	 */
+	t1 = Q16_S1Q16_MUL(anglef, 0x0648);
+
+	/*
+	 * Square this and divide by 2 to get the coefficient for second
+	 *   derivatives
+	 */
+	t2 = Q16_S1Q16_MUL(t1, t1) >> 1;
+
+	*sin = v0 + Q16_S1Q16_MUL(v1, t1) - Q16_S1Q16_MUL(v0, t2);
+
+	*cos = v1 - Q16_S1Q16_MUL(v0, t1) - Q16_S1Q16_MUL(v1, t2);
+}
+
+/* Convert input Q16 value to s4.9 */
+int16_t convert_q16_s49(int32_t q16Value)
+{	/* Top half is the whole number, Bottom half is fractional portion*/
+	int16_t whole = Q16_WHOLE(q16Value);
+	int32_t fraction  = Q16_FRAC(q16Value);
+
+	/* Clamp whole to 3 bits */
+	if (whole > 7)
+		whole = 7;
+	else if (whole < -7)
+		whole = -7;
+
+	/* Reduce fraction to 9 bits. */
+	fraction = (fraction<<9)>>Q16;
+
+	return (int16_t) ((int16_t)whole<<9) | ((int16_t)fraction);
+}
+
+/* Convert input Q16 value to uint16 */
+int16_t convert_q16_int16(int32_t val)
+{
+	int32_t rounded;
+
+	if (val >= 0) {
+		/* Add 0.5 */
+		rounded = val + (Q16_ONE>>1);
+	} else {
+		/* Subtract 0.5 */
+		rounded = val - (Q16_ONE>>1);
+	}
+
+	/* Truncate rounded value */
+	return (int16_t)(rounded>>Q16);
+}
+
+/*
+ * norm_q16
+ *              Return a Q16 value represeting a normalized value
+ *
+ * value       -100%                 0%               +100%
+ *                 |-----------------|----------------|
+ *                 ^                 ^                ^
+ *             q16MinValue     q16DefaultValue       q16MaxValue
+ *
+ */
+int32_t norm_q16(int32_t value, int32_t min, int32_t default_val, int32_t max,
+								int32_t range)
+{
+	int32_t diff, perc, mul, result;
+
+	if (0 == value) {
+		result = default_val;
+	} else if (value > 0) {
+		/* value is between 0% and +100% represent 1.0 -> QRange Max */
+		diff = range;
+		perc = Q16_PERCENT_VALUE(value, max);
+		mul = Q16_MUL(perc, diff);
+		result = default_val + mul;
+	} else {
+		/* if (value <= 0) */
+		diff = -range;
+		perc = Q16_PERCENT_VALUE(-value, -min);
+		mul = Q16_MUL(perc, diff);
+		result = default_val + mul;
+	}
+	return result;
+}
+
+void matrix_mul_3x3(int32_t dest[][3], int32_t a[][3], int32_t b[][3])
+{
+	int32_t i, j, k;
+	int32_t tmp[3][3];
+
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++) {
+			tmp[i][j] = 0;
+			for (k = 0; k < 3; k++)
+				tmp[i][j] += Q16_MUL(a[i][k], b[k][j]);
+		}
+	}
+
+	/* in case dest = a or b*/
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++)
+			dest[i][j] = tmp[i][j];
+	}
+}
+
+#define CONVERT(x)	(x)/*convert_q16_s49((x))*/
+void pr_params(struct mdp4_hsic_regs *regs)
+{
+	int i;
+	if (regs) {
+		for (i = 0; i < NUM_HSIC_PARAM; i++) {
+			pr_info("\t: hsic->params[%d] =	0x%08x [raw = 0x%08x]\n",
+			i, CONVERT(regs->params[i]), regs->params[i]);
+		}
+	}
+}
+
+void pr_3x3_matrix(int32_t in[][3])
+{
+	pr_info("\t[0x%08x\t0x%08x\t0x%08x]\n", CONVERT(in[0][0]),
+	CONVERT(in[0][1]), CONVERT(in[0][2]));
+	pr_info("\t[0x%08x\t0x%08x\t0x%08x]\n", CONVERT(in[1][0]),
+	CONVERT(in[1][1]), CONVERT(in[1][2]));
+	pr_info("\t[0x%08x\t0x%08x\t0x%08x]\n", CONVERT(in[2][0]),
+	CONVERT(in[2][1]), CONVERT(in[2][2]));
+}
+
+void _hsic_get(struct mdp4_hsic_regs *regs, int32_t type, int8_t *val)
+{
+	if (type < 0 || type >= NUM_HSIC_PARAM)
+		BUG_ON(-EINVAL);
+	*val = regs->params[type];
+	pr_info("%s: getting params[%d] = %d\n", __func__, type, *val);
+}
+
+void _hsic_set(struct mdp4_hsic_regs *regs, int32_t type, int8_t val)
+{
+	if (type < 0 || type >= NUM_HSIC_PARAM)
+		BUG_ON(-EINVAL);
+
+	if (regs->params[type] != Q16_VALUE(val)) {
+		regs->params[type] = Q16_VALUE(val);
+		regs->dirty = DIRTY;
+	}
+}
+
+void _hsic_generate_csc_matrix(struct mdp4_overlay_pipe *pipe)
+{
+	int i, j;
+	int32_t sin, cos;
+
+	int32_t hue_matrix[3][3];
+	int32_t con_sat_matrix[3][3];
+	struct mdp4_hsic_regs *regs = &(pipe->hsic_regs);
+
+	memset(con_sat_matrix, 0x0, sizeof(con_sat_matrix));
+	memset(hue_matrix, 0x0, sizeof(hue_matrix));
+
+	/*
+	 * HSIC control require matrix multiplication of these two tables
+	 *  [T 0 0][1 0  0]   T = Contrast       C=Cos(Hue)
+	 *  [0 S 0][0 C -N]   S = Saturation     N=Sin(Hue)
+	 *  [0 0 S][0 N  C]
+	 */
+
+	con_sat_matrix[0][0] = norm_q16(regs->params[HSIC_CON], CON_MIN,
+						CON_DEF, CON_MAX, CON_SAT_MAX);
+	con_sat_matrix[1][1] = norm_q16(regs->params[HSIC_SAT], SAT_MIN,
+						SAT_DEF, SAT_MAX, CON_SAT_MAX);
+	con_sat_matrix[2][2] = con_sat_matrix[1][1];
+
+	hue_matrix[0][0] = TRIG_MAX;
+
+	trig_values_q16(norm_q16(regs->params[HSIC_HUE], HUE_MIN, HUE_DEF,
+					 HUE_MAX, TRIG_MAX), &cos, &sin);
+
+	cos = Q16_MUL(cos, TRIG_MAX);
+	sin = Q16_MUL(sin, TRIG_MAX);
+
+	hue_matrix[1][1] = cos;
+	hue_matrix[2][2] = cos;
+	hue_matrix[2][1] = sin;
+	hue_matrix[1][2] = Q16_NEGATE(sin);
+
+	/* Generate YUV CSC matrix */
+	matrix_mul_3x3(regs->conv_matrix, con_sat_matrix, hue_matrix);
+
+	if (!(pipe->op_mode & MDP4_OP_SRC_DATA_YCBCR)) {
+		/* Convert input RGB to YUV then apply CSC matrix */
+		pr_info("Pipe %d, has RGB input\n", pipe->pipe_num);
+		matrix_mul_3x3(regs->conv_matrix, regs->conv_matrix,
+							csc_rgb2yuv_conv_tab);
+	}
+
+	/* Normalize the matrix */
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++)
+			regs->conv_matrix[i][j] = (regs->conv_matrix[i][j]>>14);
+	}
+
+	/* Multiply above result by current csc table */
+	matrix_mul_3x3(regs->conv_matrix, regs->conv_matrix, csc_matrix_tab);
+
+	if (!(pipe->op_mode & MDP4_OP_SRC_DATA_YCBCR)) {
+		/*HACK:only "works"for src side*/
+		/* Convert back to RGB */
+		pr_info("Pipe %d, has RGB output\n", pipe->pipe_num);
+		matrix_mul_3x3(regs->conv_matrix, csc_yuv2rgb_conv_tab,
+							regs->conv_matrix);
+	}
+
+	/* Update clamps pre and post. */
+	/* TODO: different tables for different color formats? */
+	for (i = 0; i < 6; i++) {
+		regs->pre_limit[i] = csc_pre_lv_tab[i];
+		regs->post_limit[i] = csc_post_lv_tab[i];
+	}
+
+	/* update bias values, pre and post */
+	for (i = 0; i < 3; i++) {
+		regs->pre_bias[i] = csc_pre_bv_tab[i];
+		regs->post_bias[i] = csc_post_bv_tab[i] +
+				norm_q16(regs->params[HSIC_INT],
+				INTEN_MIN, INTEN_DEF, INTEN_MAX, INTENSITY_MAX);
+	}
+
+	regs->dirty = GENERATED;
+}
+
+void _hsic_update_mdp(struct mdp4_overlay_pipe *pipe)
+{
+	struct mdp4_hsic_regs *regs = &(pipe->hsic_regs);
+	int i, j, k;
+
+	uint32_t *csc_mv;
+	uint32_t *pre_lv;
+	uint32_t *post_lv;
+	uint32_t *pre_bv;
+	uint32_t *post_bv;
+
+	switch (pipe->pipe_num) {
+	case OVERLAY_PIPE_VG2:
+		csc_mv = (uint32_t *) (MDP_VG1_CSC_MVn(0) +
+					MDP4_VIDEO_OFF);
+		pre_lv = (uint32_t *) (MDP_VG1_CSC_PRE_LVn(0) +
+					MDP4_VIDEO_OFF);
+		post_lv = (uint32_t *) (MDP_VG1_CSC_POST_LVn(0) +
+					MDP4_VIDEO_OFF);
+		pre_bv = (uint32_t *) (MDP_VG1_CSC_PRE_BVn(0) +
+					MDP4_VIDEO_OFF);
+		post_bv = (uint32_t *) (MDP_VG1_CSC_POST_BVn(0) +
+					MDP4_VIDEO_OFF);
+		break;
+	case OVERLAY_PIPE_VG1:
+	default:
+			csc_mv = (uint32_t *) MDP_VG1_CSC_MVn(0);
+			pre_lv = (uint32_t *) MDP_VG1_CSC_PRE_LVn(0);
+			post_lv = (uint32_t *) MDP_VG1_CSC_POST_LVn(0);
+			pre_bv = (uint32_t *) MDP_VG1_CSC_PRE_BVn(0);
+			post_bv = (uint32_t *) MDP_VG1_CSC_POST_BVn(0);
+		break;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++) {
+			k = (3*i) + j;
+			MDP_OUTP(csc_mv + k, convert_q16_s49(
+						regs->conv_matrix[i][j]));
+		}
+	}
+
+	for (i = 0; i < 6; i++) {
+		MDP_OUTP(pre_lv + i, convert_q16_s49(regs->pre_limit[i]));
+		MDP_OUTP(post_lv + i, convert_q16_s49(regs->post_limit[i]));
+	}
+
+	for (i = 0; i < 3; i++) {
+		MDP_OUTP(pre_bv + i, convert_q16_s49(regs->pre_bias[i]));
+		MDP_OUTP(post_bv + i, convert_q16_s49(regs->post_bias[i]));
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	regs->dirty = CLEAN;
+}
+
+void mdp4_hsic_get(struct mdp4_overlay_pipe *pipe, struct dpp_ctrl *ctrl)
+{
+	int i;
+	for (i = 0; i < NUM_HSIC_PARAM; i++)
+		_hsic_get(&(pipe->hsic_regs), i, &(ctrl->hsic_params[i]));
+}
+
+void mdp4_hsic_set(struct mdp4_overlay_pipe *pipe, struct dpp_ctrl *ctrl)
+{
+	int i;
+	for (i = 0; i < NUM_HSIC_PARAM; i++)
+		_hsic_set(&(pipe->hsic_regs), i, ctrl->hsic_params[i]);
+
+	if (pipe->hsic_regs.dirty == DIRTY)
+		_hsic_generate_csc_matrix(pipe);
+}
+
+void mdp4_hsic_update(struct mdp4_overlay_pipe *pipe)
+{
+	if (pipe->hsic_regs.dirty == GENERATED)
+		_hsic_update_mdp(pipe);
+}
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 9f2c77a..b8cde41 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1,57 +1,13 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of Code Aurora Forum nor
- *       the names of its contributors may be used to endorse or promote
- *       products derived from this software without specific prior written
- *       permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * Alternatively, provided that this notice is retained in full, this software
- * may be relicensed by the recipient under the terms of the GNU General Public
- * License version 2 ("GPL") and only version 2, in which case the provisions of
- * the GPL apply INSTEAD OF those given above.  If the recipient relicenses the
- * software under the GPL, then the identification text in the MODULE_LICENSE
- * macro must be changed to reflect "GPLv2" instead of "Dual BSD/GPL".  Once a
- * recipient changes the license terms to the GPL, subsequent recipients shall
- * not relicense under alternate licensing terms, including the BSD or dual
- * BSD/GPL terms.  In addition, the following license statement immediately
- * below and between the words START and END shall also then apply when this
- * software is relicensed under the GPL:
- *
- * START
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License version 2 and only version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * END
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
@@ -65,6 +21,8 @@
 #include <linux/hrtimer.h>
 #include <linux/clk.h>
 #include <mach/hardware.h>
+#include <mach/iommu_domains.h>
+#include <mach/iommu.h>
 #include <linux/io.h>
 #include <linux/debugfs.h>
 #include <linux/fb.h>
@@ -77,25 +35,30 @@
 #include <linux/semaphore.h>
 #include <linux/uaccess.h>
 #include <linux/mutex.h>
-#include <linux/syscalls.h>
-#include <mach/debug_display.h>
-#include <mach/msm_fb.h>
-
-
-#include "mdp_hw.h"
+#include <linux/msm_kgsl.h>
+#include "mdp.h"
+#include "msm_fb.h"
 #include "mdp4.h"
 
-#define OVERLAY_UPDATE_SCREEN		6	/*Refer to user_data field in struct mdp_overlay*/
-#define OVERLAY_UPDATE_SCREEN_EN	1
-#define OVERLAY_UPDATE_SCREEN_DIS	0
-
-static int z_order_change = 0;
+#define VERSION_KEY_MASK	0xFFFFFF00
 
 struct mdp4_overlay_ctrl {
-	struct mdp4_pipe_desc ov_pipe[OVERLAY_PIPE_MAX];/* 4 */
-	struct mdp4_overlay_pipe plist[MDP4_MAX_PIPE];	/* 4 + 2 */
-	struct mdp4_overlay_pipe *stage[MDP4_MAX_MIXER][MDP4_MAX_STAGE];
+	struct mdp4_overlay_pipe plist[OVERLAY_PIPE_MAX];
+	struct mdp4_overlay_pipe *stage[MDP4_MIXER_MAX][MDP4_MIXER_STAGE_MAX];
+	struct mdp4_overlay_pipe *baselayer[MDP4_MIXER_MAX];
+	struct blend_cfg blend[MDP4_MIXER_MAX][MDP4_MIXER_STAGE_MAX];
+	uint32 mixer_cfg[MDP4_MIXER_MAX];
+	uint32 flush[MDP4_MIXER_MAX];
+	struct iommu_free_list iommu_free[MDP4_MIXER_MAX];
+	uint32 cs_controller;
+	uint32 hw_version;
+	uint32 panel_3d;
+	uint32 panel_mode;
+	uint32 mixer0_played;
+	uint32 mixer1_played;
+	uint32 mixer2_played;
 } mdp4_overlay_db = {
+	.cs_controller = CS_CONTROLLER_0,
 	.plist = {
 		{
 			.pipe_type = OVERLAY_TYPE_RGB,
@@ -108,31 +71,236 @@
 			.pipe_ndx = 2,
 		},
 		{
-			.pipe_type = OVERLAY_TYPE_RGB, /* shared */
+			.pipe_type = OVERLAY_TYPE_VIDEO,
 			.pipe_num = OVERLAY_PIPE_VG1,
 			.pipe_ndx = 3,
-			.pipe_used = 1,	/* mark used to NOT shared */
 		},
 		{
-			.pipe_type = OVERLAY_TYPE_RGB, /* shared */
+			.pipe_type = OVERLAY_TYPE_VIDEO,
 			.pipe_num = OVERLAY_PIPE_VG2,
 			.pipe_ndx = 4,
 		},
 		{
-			.pipe_type = OVERLAY_TYPE_VIDEO, /* shared */
-			.pipe_num = OVERLAY_PIPE_VG1,
+			.pipe_type = OVERLAY_TYPE_BF,
+			.pipe_num = OVERLAY_PIPE_RGB3,
 			.pipe_ndx = 5,
+			.mixer_num = MDP4_MIXER0,
 		},
 		{
-			.pipe_type = OVERLAY_TYPE_VIDEO, /* shared */
-			.pipe_num = OVERLAY_PIPE_VG2,
+			.pipe_type = OVERLAY_TYPE_BF,
+			.pipe_num = OVERLAY_PIPE_VG3,
 			.pipe_ndx = 6,
-		}
-	}
+			.mixer_num = MDP4_MIXER1,
+		},
+		{
+			.pipe_type = OVERLAY_TYPE_BF,
+			.pipe_num = OVERLAY_PIPE_VG4,
+			.pipe_ndx = 7,
+			.mixer_num = MDP4_MIXER2,
+		},
+	},
 };
 
+static DEFINE_MUTEX(iommu_mutex);
 static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
 
+struct mdp4_overlay_perf {
+	u32 mdp_clk_rate;
+	u32 use_ov0_blt;
+	u32 use_ov1_blt;
+	u32 mdp_bw;
+};
+
+struct mdp4_overlay_perf perf_request = {
+	.mdp_bw = OVERLAY_PERF_LEVEL4,
+};
+struct mdp4_overlay_perf perf_current = {
+	.mdp_bw = OVERLAY_PERF_LEVEL4,
+};
+
+static struct ion_client *display_iclient;
+
+
+/*
+ * mdp4_overlay_iommu_unmap_freelist()
+ * mdp4_overlay_iommu_2freelist()
+ * mdp4_overlay_iommu_pipe_free()
+ * above three functiosns need to be called from same thread and
+ * in order so that no mutex are needed.
+ */
+void mdp4_overlay_iommu_unmap_freelist(int mixer)
+{
+	int i;
+	struct ion_handle *ihdl;
+	struct iommu_free_list *flist;
+
+	mutex_lock(&iommu_mutex);
+	flist = &ctrl->iommu_free[mixer];
+	if (flist->total == 0) {
+		mutex_unlock(&iommu_mutex);
+		return;
+	}
+	for (i = 0; i < IOMMU_FREE_LIST_MAX; i++) {
+		ihdl = flist->ihdl[i];
+		if (ihdl == NULL)
+			continue;
+		pr_debug("%s: mixer=%d i=%d ihdl=0x%p\n", __func__,
+					mixer, i, ihdl);
+		ion_unmap_iommu(display_iclient, ihdl, DISPLAY_DOMAIN,
+							GEN_POOL);
+		mdp4_stat.iommu_unmap++;
+		pr_debug("%s: map=%d unmap=%d drop=%d\n", __func__,
+			(int)mdp4_stat.iommu_map, (int)mdp4_stat.iommu_unmap,
+				(int)mdp4_stat.iommu_drop);
+		ion_free(display_iclient, ihdl);
+		flist->ihdl[i] = NULL;
+	}
+
+	flist->fndx = 0;
+	flist->total = 0;
+	mutex_unlock(&iommu_mutex);
+}
+
+void mdp4_overlay_iommu_2freelist(int mixer, struct ion_handle *ihdl)
+{
+	struct iommu_free_list *flist;
+
+	flist = &ctrl->iommu_free[mixer];
+	if (flist->fndx >= IOMMU_FREE_LIST_MAX) {
+		pr_err("%s: Error, mixer=%d iommu fndx=%d\n",
+				__func__, mixer, flist->fndx);
+		mdp4_stat.iommu_drop++;
+		return;
+	}
+
+	pr_debug("%s: add mixer=%d fndx=%d ihdl=0x%p\n", __func__,
+				mixer, flist->fndx, ihdl);
+
+	flist->total++;
+	flist->ihdl[flist->fndx++] = ihdl;
+}
+
+void mdp4_overlay_iommu_pipe_free(int ndx, int all)
+{
+	struct mdp4_overlay_pipe *pipe;
+	struct mdp4_iommu_pipe_info *iom;
+	int plane, mixer;
+
+	pipe = mdp4_overlay_ndx2pipe(ndx);
+	if (pipe == NULL)
+		return;
+
+	mutex_lock(&iommu_mutex);
+	mixer = pipe->mixer_num;
+	iom = &pipe->iommu;
+	pr_debug("%s: mixer=%d ndx=%d all=%d\n", __func__,
+				mixer, pipe->pipe_ndx, all);
+	for (plane = 0; plane < MDP4_MAX_PLANE; plane++) {
+		if (iom->prev_ihdl[plane]) {
+			mdp4_overlay_iommu_2freelist(mixer,
+					iom->prev_ihdl[plane]);
+			iom->prev_ihdl[plane] = NULL;
+		}
+		if (all && iom->ihdl[plane]) {
+			mdp4_overlay_iommu_2freelist(mixer, iom->ihdl[plane]);
+			iom->ihdl[plane] = NULL;
+		}
+	}
+	mutex_unlock(&iommu_mutex);
+}
+
+int mdp4_overlay_iommu_map_buf(int mem_id,
+	struct mdp4_overlay_pipe *pipe, unsigned int plane,
+	unsigned long *start, unsigned long *len,
+	struct ion_handle **srcp_ihdl)
+{
+	struct mdp4_iommu_pipe_info *iom;
+
+	if (!display_iclient)
+		return -EINVAL;
+
+	*srcp_ihdl = ion_import_fd(display_iclient, mem_id);
+	if (IS_ERR_OR_NULL(*srcp_ihdl)) {
+		pr_err("ion_import_dma_buf() failed\n");
+		return PTR_ERR(*srcp_ihdl);
+	}
+	pr_debug("%s(): ion_hdl %p, ion_buf %p\n", __func__, *srcp_ihdl,
+		ion_share(display_iclient, *srcp_ihdl));
+	pr_debug("mixer %u, pipe %u, plane %u\n", pipe->mixer_num,
+		pipe->pipe_ndx, plane);
+	if (ion_map_iommu(display_iclient, *srcp_ihdl,
+		DISPLAY_DOMAIN, GEN_POOL, SZ_4K, 0, start,
+		len, 0, ION_IOMMU_UNMAP_DELAYED)) {
+		ion_free(display_iclient, *srcp_ihdl);
+		pr_err("ion_map_iommu() failed\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&iommu_mutex);
+	iom = &pipe->iommu;
+	if (iom->prev_ihdl[plane]) {
+		mdp4_overlay_iommu_2freelist(pipe->mixer_num,
+						iom->prev_ihdl[plane]);
+		mdp4_stat.iommu_drop++;
+		pr_err("%s: dropped, ndx=%d plane=%d\n", __func__,
+						pipe->pipe_ndx, plane);
+	}
+	iom->prev_ihdl[plane] = iom->ihdl[plane];
+	iom->ihdl[plane] = *srcp_ihdl;
+	mdp4_stat.iommu_map++;
+
+	pr_debug("%s: ndx=%d plane=%d prev=0x%p cur=0x%p start=0x%lx len=%lx\n",
+		 __func__, pipe->pipe_ndx, plane, iom->prev_ihdl[plane],
+			iom->ihdl[plane], *start, *len);
+	mutex_unlock(&iommu_mutex);
+	return 0;
+}
+
+static struct mdp4_iommu_pipe_info mdp_iommu[MDP4_MIXER_MAX][OVERLAY_PIPE_MAX];
+
+void mdp4_iommu_unmap(struct mdp4_overlay_pipe *pipe)
+{
+	struct mdp4_iommu_pipe_info *iom_pipe_info;
+	unsigned char i, j;
+
+	if (!display_iclient)
+		return;
+
+	for (j = 0; j < OVERLAY_PIPE_MAX; j++) {
+		iom_pipe_info = &mdp_iommu[pipe->mixer_num][j];
+		for (i = 0; i < MDP4_MAX_PLANE; i++) {
+			if (iom_pipe_info->prev_ihdl[i]) {
+				pr_debug("%s(): mixer %u, pipe %u, plane %u, "
+					"prev_ihdl %p\n", __func__,
+					pipe->mixer_num, j + 1, i,
+					iom_pipe_info->prev_ihdl[i]);
+				ion_unmap_iommu(display_iclient,
+					iom_pipe_info->prev_ihdl[i],
+					DISPLAY_DOMAIN, GEN_POOL);
+				ion_free(display_iclient,
+					iom_pipe_info->prev_ihdl[i]);
+				iom_pipe_info->prev_ihdl[i] = NULL;
+			}
+
+			if (iom_pipe_info->mark_unmap) {
+				if (iom_pipe_info->ihdl[i]) {
+					pr_debug("%s(): MARK, mixer %u, pipe %u, plane %u, "
+						"ihdl %p\n", __func__,
+						pipe->mixer_num, j + 1, i,
+						iom_pipe_info->ihdl[i]);
+					ion_unmap_iommu(display_iclient,
+						iom_pipe_info->ihdl[i],
+						DISPLAY_DOMAIN, GEN_POOL);
+					ion_free(display_iclient,
+						iom_pipe_info->ihdl[i]);
+					iom_pipe_info->ihdl[i] = NULL;
+				}
+			}
+		}
+		iom_pipe_info->mark_unmap = 0;
+	}
+}
+
 /* static array with index 0 for unset status and 1 for set status */
 static bool overlay_status[MDP4_OVERLAY_TYPE_MAX];
 
@@ -146,235 +314,272 @@
 	return overlay_status[type];
 }
 
-void mdp4_overlay_dmae_cfg(struct mdp4_overlay_pipe *pipe, int atv)
+int mdp4_overlay_mixer_play(int mixer_num)
 {
-	uint32_t dmae_cfg_reg;
+	if (mixer_num == MDP4_MIXER2)
+		return ctrl->mixer2_played;
+	else if (mixer_num == MDP4_MIXER1)
+		return ctrl->mixer1_played;
+	else
+		return ctrl->mixer0_played;
+}
+
+void mdp4_overlay_panel_3d(int mixer_num, uint32 panel_3d)
+{
+	ctrl->panel_3d = panel_3d;
+}
+
+void mdp4_overlay_panel_mode(int mixer_num, uint32 mode)
+{
+	ctrl->panel_mode |= mode;
+}
+
+void mdp4_overlay_panel_mode_unset(int mixer_num, uint32 mode)
+{
+	ctrl->panel_mode &= ~mode;
+}
+
+uint32 mdp4_overlay_panel_list(void)
+{
+	return ctrl->panel_mode;
+}
+
+void mdp4_overlay_cfg_init(void)
+{
+	if (ctrl->hw_version == 0) {
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		ctrl->hw_version = inpdw(MDP_BASE + 0x0); /* MDP_HW_VERSION */
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	}
+
+	if (ctrl->hw_version >= 0x0402030b) {
+		/* MDP_LAYERMIXER_IN_CFG_UPDATE_METHOD */
+		outpdw(MDP_BASE + 0x100fc, 0x01);
+	}
+}
+
+int mdp4_overlay_borderfill_supported(void)
+{
+	return (ctrl->hw_version >= 0x0402030b);
+}
+
+void mdp4_overlay_dmae_cfg(struct msm_fb_data_type *mfd, int atv)
+{
+	uint32	dmae_cfg_reg;
 
 	if (atv)
 		dmae_cfg_reg = DMA_DEFLKR_EN;
 	else
 		dmae_cfg_reg = 0;
 
-	if (pipe->mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) {
-		dmae_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
-		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
-	} else if (pipe->mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB666) {
+	if (mfd->fb_imgType == MDP_BGR_565)
+		dmae_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else
+		dmae_cfg_reg |= DMA_PACK_PATTERN_RGB;
+
+
+	if (mfd->panel_info.bpp == 18) {
 		dmae_cfg_reg |= DMA_DSTC0G_6BITS |	/* 666 18BPP */
 		    DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+	} else if (mfd->panel_info.bpp == 16) {
+		dmae_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
+		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
 	} else {
-		dmae_cfg_reg |= DMA_DSTC0G_8BITS |	/* 888 24BPP */
+		dmae_cfg_reg |= DMA_DSTC0G_8BITS |	/* 888 16BPP */
 		    DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
 	}
 
-	dmae_cfg_reg |= DMA_PACK_PATTERN_RGB;
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
 	/* dma2 config register */
-	mdp_writel(pipe->mdp, dmae_cfg_reg, 0xb0000);
-
+	MDP_OUTP(MDP_BASE + 0xb0000, dmae_cfg_reg);
 	if (atv) {
-		mdp_writel(pipe->mdp, 0xeb0010, 0xb0070);
-		mdp_writel(pipe->mdp, 0xf00010, 0xb0074);
-		mdp_writel(pipe->mdp, 0xf00010, 0xb0078);
-		mdp_writel(pipe->mdp, 0x80, 0xb3000);
-		mdp_writel(pipe->mdp, 0x1800040, 0xb3010);
-		mdp_writel(pipe->mdp, 0x1000080, 0xb3014);
-		mdp_writel(pipe->mdp, 0x67686970, 0xb4004);
+		MDP_OUTP(MDP_BASE + 0xb0070, 0xeb0010);
+		MDP_OUTP(MDP_BASE + 0xb0074, 0xf00010);
+		MDP_OUTP(MDP_BASE + 0xb0078, 0xf00010);
+		MDP_OUTP(MDP_BASE + 0xb3000, 0x80);
+		MDP_OUTP(MDP_BASE + 0xb3010, 0x1800040);
+		MDP_OUTP(MDP_BASE + 0xb3014, 0x1000080);
+		MDP_OUTP(MDP_BASE + 0xb4004, 0x67686970);
 	} else {
-		mdp_writel(pipe->mdp, 0xff0000, 0xb0070);
-		mdp_writel(pipe->mdp, 0xff0000, 0xb0074);
-		mdp_writel(pipe->mdp, 0xff0000, 0xb0078);
+#ifdef CONFIG_FB_MSM_HDMI_MHL
+		mdp_vid_quant_set();
+#endif
+		MDP_OUTP(MDP_BASE + 0xb0070, 0xff0000);
+		MDP_OUTP(MDP_BASE + 0xb0074, 0xff0000);
+		MDP_OUTP(MDP_BASE + 0xb0078, 0xff0000);
 	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
+#ifdef CONFIG_FB_MSM_HDMI_3D
+void unfill_black_screen(void) { return; }
+#else
+void unfill_black_screen(void)
+{
+	uint32 temp_src_format;
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	/*
+	* VG2 Constant Color
+	*/
+	temp_src_format = inpdw(MDP_BASE + 0x30050);
+	MDP_OUTP(MDP_BASE + 0x30050, temp_src_format&(~BIT(22)));
+	/*
+	* MDP_OVERLAY_REG_FLUSH
+	*/
+	MDP_OUTP(MDP_BASE + 0x18000, BIT(3));
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	return;
+}
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_3D
+void fill_black_screen(void) { return; }
+#else
+void fill_black_screen(void)
+{
+	/*Black color*/
+	uint32 color = 0x00000000;
+	uint32 temp_src_format;
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	/*
+	* VG2 Constant Color
+	*/
+	MDP_OUTP(MDP_BASE + 0x31008, color);
+	/*
+	* MDP_VG2_SRC_FORMAT
+	*/
+	temp_src_format = inpdw(MDP_BASE + 0x30050);
+	MDP_OUTP(MDP_BASE + 0x30050, temp_src_format | BIT(22));
+	/*
+	* MDP_OVERLAY_REG_FLUSH
+	*/
+	MDP_OUTP(MDP_BASE + 0x18000, BIT(3));
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	return;
+}
+#endif
+
 void mdp4_overlay_dmae_xy(struct mdp4_overlay_pipe *pipe)
 {
-	/* dma_e source */
-	mdp_writel(pipe->mdp, (pipe->src_height << 16 | pipe->src_width)
-			, 0xb0004);
-	mdp_writel(pipe->mdp, pipe->srcp0_addr, 0xb0008);
-	mdp_writel(pipe->mdp, pipe->srcp0_ystride, 0xb000c);
 
-	/* dma_e dest */
-	mdp_writel(pipe->mdp, (pipe->dst_y << 16 | pipe->dst_x), 0xb0010);
-}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
-int mdp4_overlay_parameters_check(struct mdp4_overlay_pipe *pipe)
-{
-	uint32_t fb_width = 0, fb_height = 0;
-
-	if (pipe == NULL || pipe->mdp == NULL)
-		return 0;
-
-	if (pipe->mixer_num == 0) { /* set fb0 */
-		if (pipe->mdp->mdp_dev.fb0 != NULL) {
-			fb_width = pipe->mdp->mdp_dev.fb0->var.xres;
-			fb_height = pipe->mdp->mdp_dev.fb0->var.yres;
-		} else {
-			PR_DISP_ERR("%s(%d) mdp_dev fb0 is NULL\n", __func__, __LINE__);
-			return -EPERM;
-		}
-	} else { /* set fb1 */
-		if (pipe->mdp->mdp_dev.fb1 != NULL) {
-			fb_width = pipe->mdp->mdp_dev.fb1->var.xres;
-			fb_height = pipe->mdp->mdp_dev.fb1->var.yres;
-		} else {
-			PR_DISP_ERR("%s(%d) mdp_dev fb1 is NULL\n", __func__, __LINE__);
-			return -EPERM;
-		}
-	}
-	if (pipe->dst_x < 0 || pipe->dst_x >= fb_width) {
-
-		PR_DISP_WARN("%s(%d) Incorrect parameter dstx=%d", __func__, __LINE__, pipe->dst_x);
-		return -ERANGE;
-	}
-
-	if (pipe->dst_y < 0 || pipe->dst_y >= fb_height) {
-
-		PR_DISP_WARN("%s(%d) Incorrect parameter dsty=%d", __func__, __LINE__, pipe->dst_y);
-		return -ERANGE;
-	}
-
-	if (pipe->dst_w < 0 || pipe->dst_w > fb_width) {
-
-		PR_DISP_WARN("%s(%d) Incorrect parameter dstw=%d", __func__, __LINE__, pipe->dst_w);
-		return -ERANGE;
-	}
-
-	if (pipe->dst_y < 0 || pipe->dst_y > fb_height) {
-
-		PR_DISP_WARN("%s(%d) Incorrect parameter2 dsty=%d", __func__, __LINE__, pipe->dst_y);
-		return -ERANGE;
-	}
-
-	if (pipe->dst_w + pipe->dst_x > fb_width) {
-
-		PR_DISP_WARN("%s(%d) Incorrect parameter dstx=%d dstw=%d found", __func__, __LINE__,
-			pipe->dst_x, pipe->dst_w);
-		return -ERANGE;
-	}
-
-	if (pipe->dst_h + pipe->dst_y > fb_height) {
-
-		PR_DISP_WARN("%s(%d) Incorrect parameter dsty=%d dsth=%d found", __func__, __LINE__,
-			pipe->dst_y, pipe->dst_h);
-		return -ERANGE;
-	}
-
-	if (pipe->dst_w && (pipe->dst_w != pipe->src_w) && (pipe->src_w > pipe->dst_w * 4)) { /* dst_w too little */
-
-		PR_DISP_WARN("%s(%d) Incorrect parameter dst_w=%d(too small)", __func__, __LINE__, pipe->dst_w);
-		return -ERANGE;
-	}
-
-	if (pipe->dst_h && (pipe->dst_h != pipe->src_h) && (pipe->src_h > pipe->dst_h * 4)) { /* dst_h too little */
-
-		PR_DISP_WARN("%s(%d) Incorrect parameter dst_h=%d(too small)", __func__, __LINE__, pipe->dst_h);
-		return -ERANGE;
-	}
-	return 0;
-}
-
-
-void mdp4_overlay_dmap_cfg(struct mdp4_overlay_pipe *pipe, int lcdc)
-{
-	uint32_t	dmap_cfg_reg = 0;
-
-	dmap_cfg_reg |= DMA_DITHER_EN;
-
-
-	if (pipe->mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) {
-		dmap_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
-		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
-	} else if (pipe->mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB666) {
-		dmap_cfg_reg |= DMA_DSTC0G_6BITS |	/* 666 18BPP */
-		    DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+	MDP_OUTP(MDP_BASE + 0xb0004,
+			(pipe->src_height << 16 | pipe->src_width));
+	if (pipe->dma_blt_addr) {
+		uint32 off, bpp;
+#ifdef BLT_RGB565
+		bpp = 2; /* overlay ouput is RGB565 */
+#else
+		bpp = 3; /* overlay ouput is RGB888 */
+#endif
+		off = 0;
+		if (pipe->ov_cnt & 0x01)
+			off = pipe->src_height * pipe->src_width * bpp;
+		MDP_OUTP(MDP_BASE + 0xb0008, pipe->dma_blt_addr + off);
+		/* RGB888, output of overlay blending */
+		MDP_OUTP(MDP_BASE + 0xb000c, pipe->src_width * bpp);
 	} else {
-		dmap_cfg_reg |= DMA_DSTC0G_8BITS |	/* 888 16BPP */
+		/* dma_e source */
+		MDP_OUTP(MDP_BASE + 0xb0008, pipe->srcp0_addr);
+		MDP_OUTP(MDP_BASE + 0xb000c, pipe->srcp0_ystride);
+	}
+	/* dma_e dest */
+	MDP_OUTP(MDP_BASE + 0xb0010, (pipe->dst_y << 16 | pipe->dst_x));
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc)
+{
+	uint32	dma2_cfg_reg;
+	uint32 mask, curr;
+
+	dma2_cfg_reg = DMA_DITHER_EN;
+#ifdef BLT_RGB565
+	/* RGB888 is 0 */
+	dma2_cfg_reg |= DMA_BUF_FORMAT_RGB565; /* blt only */
+#endif
+
+	if (mfd->fb_imgType == MDP_BGR_565)
+		dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else
+		dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
+
+
+	if (mfd->panel_info.bpp == 18) {
+		dma2_cfg_reg |= DMA_DSTC0G_6BITS |	/* 666 18BPP */
+		    DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+	} else if (mfd->panel_info.bpp == 16) {
+		dma2_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
+		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
+	} else {
+		dma2_cfg_reg |= DMA_DSTC0G_8BITS |	/* 888 16BPP */
 		    DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
 	}
 
-	if (lcdc) {
-		if (pipe->mdp->mdp_dev.overrides & MSM_MDP_DMA_PACK_ALIGN_LSB)
-			dmap_cfg_reg |= DMA_PACK_ALIGN_LSB;
-		else
-			dmap_cfg_reg |= DMA_PACK_ALIGN_MSB;
-	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
-	/* dmap config register */
-	mdp_writel(pipe->mdp, dmap_cfg_reg, 0x90000);
-
-}
-
-void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
-{
-
-	/* dma_p source */
-	mdp_writel(pipe->mdp, (pipe->src_height << 16 | pipe->src_width), 0x90004);
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-	if (pipe->blt_addr) {
-		/* overlay ouput is RGB565 */
-		uint32_t off;
-		off = 0;
-		if (pipe->blt_cnt & 0x01)
-			off = pipe->src_height * pipe->src_width * 2;
-		mdp_writel(pipe->mdp, pipe->blt_addr+off , 0x90008);
-		/* RGB888, output of overlay blending */
-		mdp_writel(pipe->mdp, pipe->src_width * 2, 0x9000c);
-	} else {
-		mdp_writel(pipe->mdp, pipe->srcp0_addr, 0x90008);
-		mdp_writel(pipe->mdp, pipe->srcp0_ystride, 0x9000c);
-	}
-#else
-	mdp_writel(pipe->mdp, pipe->srcp0_addr, 0x90008);
-	mdp_writel(pipe->mdp, pipe->srcp0_ystride, 0x9000c);
+#ifndef CONFIG_FB_MSM_LCDC_CHIMEI_WXGA_PANEL
+	if (lcdc)
+		dma2_cfg_reg |= DMA_PACK_ALIGN_MSB;
 #endif
 
-	/* dma_p dest */
-	mdp_writel(pipe->mdp, (pipe->dst_y << 16 | pipe->dst_x), 0x90010);
+	/* dma2 config register */
+	curr = inpdw(MDP_BASE + 0x90000);
+	mask = 0xBFFFFFFF;
+	dma2_cfg_reg = (dma2_cfg_reg & mask) | (curr & ~mask);
+	MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_overlay_dmas_cfg(struct mdp4_overlay_pipe *pipe, int lcdc)
+/*
+ * mdp4_overlay_dmap_xy: called form baselayer only
+ */
+void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
 {
-	uint32_t	dmas_cfg_reg = 0;
+	uint32 off, bpp;
 
-	dmas_cfg_reg |= DMA_DITHER_EN;
-	if (pipe->src_format == MDP_RGBA_8888) {
-		dmas_cfg_reg |= DMA_PACK_PATTERN_BGR;
-		dmas_cfg_reg |= (1 << 26);
+	if (!in_interrupt())
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	if (pipe->dma_blt_addr) {
+#ifdef BLT_RGB565
+		bpp = 2; /* overlay ouput is RGB565 */
+#else
+		bpp = 3; /* overlay ouput is RGB888 */
+#endif
+		off = 0;
+		if (pipe->dmap_cnt & 0x01)
+			off = pipe->src_height * pipe->src_width * bpp;
+		MDP_OUTP(MDP_BASE + 0x90008, pipe->dma_blt_addr + off);
+		/* RGB888, output of overlay blending */
+		MDP_OUTP(MDP_BASE + 0x9000c, pipe->src_width * bpp);
 	} else {
-		dmas_cfg_reg |= DMA_PACK_PATTERN_RGB;
-		dmas_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
+		MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
+		MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
 	}
+	/* dma_p source */
+	MDP_OUTP(MDP_BASE + 0x90004,
+			(pipe->src_height << 16 | pipe->src_width));
 
-	dmas_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
-	    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
+	/* dma_p dest */
+	MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
 
-	if (lcdc)
-		dmas_cfg_reg |= DMA_PACK_ALIGN_MSB;
-
-	/* dmas config register */
-	mdp_writel(pipe->mdp, dmas_cfg_reg, 0xA0000);
-
-}
-
-void mdp4_overlay_dmas_xy(struct mdp4_overlay_pipe *pipe)
-{
-
-	/* dmas source */
-	mdp_writel(pipe->mdp, (pipe->dst_h << 16 | pipe->dst_w), 0xA0004);
-	mdp_writel(pipe->mdp, pipe->srcp0_addr, 0xA0008);
-	mdp_writel(pipe->mdp, pipe->srcp0_ystride, 0xA000c);
-
-	/* dmas dest */
-	mdp_writel(pipe->mdp, (pipe->dst_y << 16 | pipe->dst_x), 0xA0010);
+	if (!in_interrupt())
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
 #define MDP4_VG_PHASE_STEP_DEFAULT	0x20000000
 #define MDP4_VG_PHASE_STEP_SHIFT	29
 
-static int mdp4_leading_0(uint32_t num)
+static int mdp4_leading_0(uint32 num)
 {
-	uint32_t bit = 0x80000000;
+	uint32 bit = 0x80000000;
 	int i;
 
 	for (i = 0; i < 32; i++) {
@@ -386,19 +591,20 @@
 	return i;
 }
 
-static uint32_t mdp4_scale_phase_step(int f_num, uint32_t src, uint32_t dst)
+static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
 {
-	uint32_t val;
+	uint32 val, s;
 	int	n;
 
 	n = mdp4_leading_0(src);
 	if (n > f_num)
 		n = f_num;
-	val = src << n;	/* maximum to reduce lose of resolution */
-	val /= dst;
+	s = src << n;	/* maximum to reduce lose of resolution */
+	val = s / dst;
 	if (n < f_num) {
 		n = f_num - n;
 		val <<= n;
+		val |= ((s % dst) << n) / dst;
 	}
 
 	return val;
@@ -406,20 +612,31 @@
 
 static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe)
 {
-
 	pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
 	pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
 
 	if (pipe->dst_h && pipe->src_h != pipe->dst_h) {
-		if (pipe->dst_h > pipe->src_h * 8)	/* too much */
+		u32 upscale_max;
+		upscale_max = (mdp_rev >= MDP_REV_41) ?
+			MDP4_REV41_OR_LATER_UP_SCALING_MAX :
+			MDP4_REV40_UP_SCALING_MAX;
+		if (pipe->dst_h > pipe->src_h * upscale_max)
 			return;
+
 		pipe->op_mode |= MDP4_OP_SCALEY_EN;
 
-		if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
-			if (pipe->dst_h < (pipe->src_h / 4))
+		if (pipe->pipe_type == OVERLAY_TYPE_VIDEO) {
+			if (pipe->flags & MDP_BACKEND_COMPOSITION &&
+				pipe->alpha_enable && pipe->dst_h > pipe->src_h)
+				pipe->op_mode |= MDP4_OP_SCALEY_PIXEL_RPT;
+			else if (pipe->dst_h <= (pipe->src_h / 4))
 				pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
 			else
 				pipe->op_mode |= MDP4_OP_SCALEY_FIR;
+		} else { /* RGB pipe */
+			pipe->op_mode |= MDP4_OP_SCALE_RGB_ENHANCED |
+				MDP4_OP_SCALE_RGB_BILINEAR |
+				MDP4_OP_SCALE_ALPHA_BILINEAR;
 		}
 
 		pipe->phasey_step = mdp4_scale_phase_step(29,
@@ -427,15 +644,26 @@
 	}
 
 	if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
-		if (pipe->dst_w > pipe->src_w * 8)	/* too much */
+		u32 upscale_max;
+		upscale_max = (mdp_rev >= MDP_REV_41) ?
+			MDP4_REV41_OR_LATER_UP_SCALING_MAX :
+			MDP4_REV40_UP_SCALING_MAX;
+
+		if (pipe->dst_w > pipe->src_w * upscale_max)
 			return;
 		pipe->op_mode |= MDP4_OP_SCALEX_EN;
-
-		if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
-			if (pipe->dst_w < (pipe->src_w / 4))
+		if (pipe->pipe_type == OVERLAY_TYPE_VIDEO) {
+			if (pipe->flags & MDP_BACKEND_COMPOSITION &&
+				pipe->alpha_enable && pipe->dst_w > pipe->src_w)
+				pipe->op_mode |= MDP4_OP_SCALEX_PIXEL_RPT;
+			else if (pipe->dst_w <= (pipe->src_w / 4))
 				pipe->op_mode |= MDP4_OP_SCALEX_MN_PHASE;
 			else
 				pipe->op_mode |= MDP4_OP_SCALEX_FIR;
+		} else { /* RGB pipe */
+			pipe->op_mode |= MDP4_OP_SCALE_RGB_ENHANCED |
+				MDP4_OP_SCALE_RGB_BILINEAR |
+				MDP4_OP_SCALE_ALPHA_BILINEAR;
 		}
 
 		pipe->phasex_step = mdp4_scale_phase_step(29,
@@ -445,161 +673,287 @@
 
 void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
 {
-	uint32_t rgb_base;
-	uint32_t src_size, src_xy, dst_size, dst_xy;
-	uint32_t format, pattern;
-	uint32_t dst_newx = 0, dst_newy = 0;
+	char *rgb_base;
+	uint32 src_size, src_xy, dst_size, dst_xy;
+	uint32 format, pattern;
+	uint32 curr, mask;
+	uint32 offset = 0;
+	int pnum;
 
-	rgb_base = MDP4_RGB_BASE;
-	rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
-
-	mdp4_overlay_parameters_check(pipe);
+	pnum = pipe->pipe_num - OVERLAY_PIPE_RGB1; /* start from 0 */
+	rgb_base = MDP_BASE + MDP4_RGB_BASE;
+	rgb_base += (MDP4_RGB_OFF * pnum);
 
 	src_size = ((pipe->src_h << 16) | pipe->src_w);
 	src_xy = ((pipe->src_y << 16) | pipe->src_x);
 	dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
+	dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
+
+	if ((pipe->src_x + pipe->src_w) > 0x7FF) {
+		offset += pipe->src_x * pipe->bpp;
+		src_xy &= 0xFFFF0000;
+	}
+
+	if ((pipe->src_y + pipe->src_h) > 0x7FF) {
+		offset += pipe->src_y * pipe->src_width * pipe->bpp;
+		src_xy &= 0x0000FFFF;
+	}
 
 	format = mdp4_overlay_format(pipe);
 	pattern = mdp4_overlay_unpack_pattern(pipe);
 
 #ifdef MDP4_IGC_LUT_ENABLE
-	pipe->op_mode = MDP4_OP_IGC_LUT_EN;
-#else
-	pipe->op_mode = 0;
+	pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
 #endif
 
-	/* workaroud for the panel with wrong direction */
-	if (pipe->mdp->mdp_dev.overrides & MSM_MDP_PANEL_FLIP_UD) {
-		pipe->op_mode ^= MDP4_OP_FLIP_UD;
-
-		if (pipe->mixer_num == 0)
-			dst_newy = pipe->mdp->mdp_dev.fb0->var.yres - pipe->dst_y - pipe->dst_h;
-		else
-			dst_newy = pipe->mdp->mdp_dev.fb1->var.yres - pipe->dst_y - pipe->dst_h;
-		dst_xy = dst_newy << 16;
-	} else
-		dst_xy = pipe->dst_y << 16;
-
-	if (pipe->mdp->mdp_dev.overrides & MSM_MDP_PANEL_FLIP_LR) {
-		pipe->op_mode ^= MDP4_OP_FLIP_LR;
-		if (pipe->mixer_num == 0)
-			dst_newx = pipe->mdp->mdp_dev.fb0->var.xres - pipe->dst_x - pipe->dst_w;
-		else
-			dst_newx = pipe->mdp->mdp_dev.fb1->var.xres - pipe->dst_x - pipe->dst_w;
-		dst_xy |= dst_newx;
-	} else
-		dst_xy |= pipe->dst_x;
-
 	mdp4_scale_setup(pipe);
 
-	mdp_writel(pipe->mdp, src_size, rgb_base + 0x0000);	/* MDP_RGB_SRC_SIZE */
-	mdp_writel(pipe->mdp, src_xy, rgb_base + 0x0004);	/* MDP_RGB_SRC_XY */
-	mdp_writel(pipe->mdp, src_xy, rgb_base + 0x0008);	/* MDP_RGB_DST_SIZE */
-	mdp_writel(pipe->mdp, dst_xy, rgb_base + 0x000c);	/* MDP_RGB_DST_XY */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
-	mdp_writel(pipe->mdp, pipe->srcp0_addr, rgb_base + 0x0010);
-	mdp_writel(pipe->mdp, pipe->srcp0_ystride, rgb_base + 0x0040);
+	/* Ensure proper covert matrix loaded when color space swaps */
+	curr = inpdw(rgb_base + 0x0058);
+	/* Don't touch bits you don't want to configure*/
+	mask = 0xFFFEFFFF;
+	pipe->op_mode = (pipe->op_mode & mask) | (curr & ~mask);
 
-	mdp_writel(pipe->mdp, format, rgb_base + 0x0050);/* MDP_RGB_SRC_FORMAT */
-	mdp_writel(pipe->mdp, pattern, rgb_base + 0x0054);/* MDP_RGB_SRC_UNPACK_PATTERN */
-	mdp_writel(pipe->mdp, pipe->op_mode, rgb_base + 0x0058);/* MDP_RGB_OP_MODE */
-	mdp_writel(pipe->mdp, pipe->phasex_step, rgb_base + 0x005c);
-	mdp_writel(pipe->mdp, pipe->phasey_step, rgb_base + 0x0060);
+	outpdw(rgb_base + 0x0000, src_size);	/* MDP_RGB_SRC_SIZE */
+	outpdw(rgb_base + 0x0004, src_xy);	/* MDP_RGB_SRC_XY */
+	outpdw(rgb_base + 0x0008, dst_size);	/* MDP_RGB_DST_SIZE */
+	outpdw(rgb_base + 0x000c, dst_xy);	/* MDP_RGB_DST_XY */
+
+	outpdw(rgb_base + 0x0010, pipe->srcp0_addr + offset);
+	outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
+
+	outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
+	outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */
+	if (format & MDP4_FORMAT_SOLID_FILL) {
+		u32 op_mode = pipe->op_mode;
+		op_mode &= ~(MDP4_OP_FLIP_LR + MDP4_OP_SCALEX_EN);
+		op_mode &= ~(MDP4_OP_FLIP_UD + MDP4_OP_SCALEY_EN);
+		outpdw(rgb_base + 0x0058, op_mode);/* MDP_RGB_OP_MODE */
+	} else
+		outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
+	outpdw(rgb_base + 0x005c, pipe->phasex_step);
+	outpdw(rgb_base + 0x0060, pipe->phasey_step);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	mdp4_stat.pipe[pipe->pipe_num]++;
 }
 
-int mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
+
+static void mdp4_overlay_vg_get_src_offset(struct mdp4_overlay_pipe *pipe,
+	char *vg_base, uint32 *luma_off, uint32 *chroma_off)
 {
-	uint32_t vg_base;
-	uint32_t frame_size, src_size, src_xy, dst_size, dst_xy;
-	uint32_t format, pattern;
-	uint32_t dst_newx = 0, dst_newy = 0;
-	int pnum, ret = 0;
+	uint32 src_xy;
+	*luma_off = 0;
+	*chroma_off = 0;
+
+	if (pipe->src_x && (pipe->frame_format ==
+		MDP4_FRAME_FORMAT_LINEAR)) {
+		src_xy = (pipe->src_y << 16) | pipe->src_x;
+		src_xy &= 0xffff0000;
+		outpdw(vg_base + 0x0004, src_xy);	/* MDP_RGB_SRC_XY */
+
+		switch (pipe->src_format) {
+		case MDP_Y_CR_CB_H2V2:
+		case MDP_Y_CR_CB_GH2V2:
+		case MDP_Y_CB_CR_H2V2:
+				*luma_off = pipe->src_x;
+				*chroma_off = pipe->src_x/2;
+			break;
+
+		case MDP_Y_CBCR_H2V2_TILE:
+		case MDP_Y_CRCB_H2V2_TILE:
+		case MDP_Y_CBCR_H2V2:
+		case MDP_Y_CRCB_H2V2:
+		case MDP_Y_CRCB_H1V1:
+		case MDP_Y_CBCR_H1V1:
+		case MDP_Y_CRCB_H2V1:
+		case MDP_Y_CBCR_H2V1:
+			*luma_off = pipe->src_x;
+			*chroma_off = pipe->src_x;
+			break;
+
+		case MDP_YCRYCB_H2V1:
+			if (pipe->src_x & 0x1)
+				pipe->src_x += 1;
+			*luma_off += pipe->src_x * 2;
+			break;
+
+		case MDP_ARGB_8888:
+		case MDP_RGBA_8888:
+		case MDP_BGRA_8888:
+		case MDP_RGBX_8888:
+		case MDP_RGB_565:
+		case MDP_BGR_565:
+		case MDP_XRGB_8888:
+		case MDP_RGB_888:
+		case MDP_YCBCR_H1V1:
+		case MDP_YCRCB_H1V1:
+			*luma_off = pipe->src_x * pipe->bpp;
+			break;
+
+		default:
+			pr_err("%s: fmt %u not supported for adjustment\n",
+				__func__, pipe->src_format);
+			break;
+		}
+	}
+}
+
+void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
+{
+	char *vg_base;
+	uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
+	uint32 format, pattern, luma_offset, chroma_offset;
+	uint32 mask, curr, addr;
+	int pnum, ptype;
 
 	pnum = pipe->pipe_num - OVERLAY_PIPE_VG1; /* start from 0 */
-	vg_base = MDP4_VIDEO_BASE;
+	vg_base = MDP_BASE + MDP4_VIDEO_BASE;
 	vg_base += (MDP4_VIDEO_OFF * pnum);
 
-	ret = mdp4_overlay_parameters_check(pipe);
-	if (ret)
-		return ret;
-
 	frame_size = ((pipe->src_height << 16) | pipe->src_width);
 	src_size = ((pipe->src_h << 16) | pipe->src_w);
 	src_xy = ((pipe->src_y << 16) | pipe->src_x);
 	dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
+	dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
 
+	ptype = mdp4_overlay_format2type(pipe->src_format);
 	format = mdp4_overlay_format(pipe);
 	pattern = mdp4_overlay_unpack_pattern(pipe);
 
+	/* not RGB use VG pipe, pure VG pipe */
+	pipe->op_mode |= MDP4_OP_CSC_EN;
+	if (ptype != OVERLAY_TYPE_RGB)
+		pipe->op_mode |= MDP4_OP_SRC_DATA_YCBCR;
+
 #ifdef MDP4_IGC_LUT_ENABLE
-	pipe->op_mode = MDP4_OP_IGC_LUT_EN;
-#else
-	pipe->op_mode = 0;
+	pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
 #endif
 
-	/* not RGB use VG pipe */
-	if (pipe->pipe_type != OVERLAY_TYPE_RGB)
-		pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR);
-
-
 	mdp4_scale_setup(pipe);
 
-	/* workaroud for the panel with wrong direction */
-	if (pipe->mdp->mdp_dev.overrides & MSM_MDP_PANEL_FLIP_UD) {
-		pipe->op_mode ^= MDP4_OP_FLIP_UD;
-		if (pipe->mixer_num == 0)
-			dst_newy = pipe->mdp->mdp_dev.fb0->var.yres - pipe->dst_y - pipe->dst_h;
-		else
-			dst_newy = pipe->mdp->mdp_dev.fb0->var.yres - pipe->dst_y - pipe->dst_h;
-		dst_xy = dst_newy << 16;
-	} else
-		dst_xy = pipe->dst_y << 16;
+	luma_offset = 0;
+	chroma_offset = 0;
 
-	if (pipe->mdp->mdp_dev.overrides & MSM_MDP_PANEL_FLIP_LR) {
-		pipe->op_mode ^= MDP4_OP_FLIP_LR;
+	if (ptype == OVERLAY_TYPE_RGB) {
+		if ((pipe->src_y + pipe->src_h) > 0x7FF) {
+			luma_offset = pipe->src_y * pipe->src_width * pipe->bpp;
+			src_xy &= 0x0000FFFF;
+		}
 
-		if (pipe->mixer_num == 0)
-			dst_newx = pipe->mdp->mdp_dev.fb0->var.xres - pipe->dst_x - pipe->dst_w;
-		else
-			dst_newx = pipe->mdp->mdp_dev.fb1->var.yres - pipe->dst_x - pipe->dst_w;
-		dst_xy |= dst_newx;
-	} else
-		dst_xy |= pipe->dst_x;
-
-	if (pipe->dst_x < 0 || pipe->dst_y < 0) {
-		PR_DISP_ERR("%s(%d) Incorrect overlay input pipex=%d pipey=%d newx=%d newy=%d width=%d height=%d\n",
-			__func__, __LINE__, pipe->dst_x, pipe->dst_y, dst_newx, dst_newy,
-			pipe->mdp->mdp_dev.width, pipe->mdp->mdp_dev.height);
+		if ((pipe->src_x + pipe->src_w) > 0x7FF) {
+			luma_offset += pipe->src_x * pipe->bpp;
+			src_xy &= 0xFFFF0000;
+		}
 	}
 
-	mdp_writel(pipe->mdp, src_size, vg_base + 0x0000);	/* MDP_RGB_SRC_SIZE */
-	mdp_writel(pipe->mdp, src_xy, vg_base + 0x0004);	/* MDP_RGB_SRC_XY */
-	mdp_writel(pipe->mdp, dst_size, vg_base + 0x0008);	/* MDP_RGB_DST_SIZE */
-	mdp_writel(pipe->mdp, dst_xy, vg_base + 0x000c);	/* MDP_RGB_DST_XY */
-	mdp_writel(pipe->mdp, frame_size, vg_base + 0x0048);	/* TILE frame size */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	outpdw(vg_base + 0x0000, src_size);	/* MDP_RGB_SRC_SIZE */
+	outpdw(vg_base + 0x0004, src_xy);	/* MDP_RGB_SRC_XY */
+	outpdw(vg_base + 0x0008, dst_size);	/* MDP_RGB_DST_SIZE */
+	outpdw(vg_base + 0x000c, dst_xy);	/* MDP_RGB_DST_XY */
+
+	if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR)
+		outpdw(vg_base + 0x0048, frame_size);	/* TILE frame size */
+
+	/*
+	 * Adjust src X offset to avoid MDP from overfetching pixels
+	 * present before the offset. This is required for video
+	 * frames coming with unused green pixels along the left margin
+	 */
+	/* not RGB use VG pipe, pure VG pipe */
+	if (ptype != OVERLAY_TYPE_RGB) {
+		mdp4_overlay_vg_get_src_offset(pipe, vg_base, &luma_offset,
+			&chroma_offset);
+	}
+
+	/* Ensure proper covert matrix loaded when color space swaps */
+	curr = inpdw(vg_base + 0x0058);
+	mask = 0x600;
+
+	if ((curr & mask) != (pipe->op_mode & mask)) {
+		addr = ((uint32_t)vg_base) + 0x4000;
+		if (ptype != OVERLAY_TYPE_RGB)
+			mdp4_csc_write(&(mdp_csc_convert[1]), addr);
+		else
+			mdp4_csc_write(&(mdp_csc_convert[0]), addr);
+
+		mask = 0xFFFCFFFF;
+	} else {
+		/* Don't touch bits you don't want to configure*/
+		mask = 0xFFFCF1FF;
+	}
+	pipe->op_mode = (pipe->op_mode & mask) | (curr & ~mask);
 
 	/* luma component plane */
-	mdp_writel(pipe->mdp, pipe->srcp0_addr, vg_base + 0x0010);
+	outpdw(vg_base + 0x0010, pipe->srcp0_addr + luma_offset);
 
-	/* chroma component plane */
-	mdp_writel(pipe->mdp, pipe->srcp1_addr, vg_base + 0x0014);
+	/* chroma component plane or  planar color 1 */
+	outpdw(vg_base + 0x0014, pipe->srcp1_addr + chroma_offset);
+
+	/* planar color 2 */
+	outpdw(vg_base + 0x0018, pipe->srcp2_addr + chroma_offset);
+
+	outpdw(vg_base + 0x0040,
+			pipe->srcp1_ystride << 16 | pipe->srcp0_ystride);
+
+	outpdw(vg_base + 0x0044,
+			pipe->srcp3_ystride << 16 | pipe->srcp2_ystride);
+
+	outpdw(vg_base + 0x0050, format);	/* MDP_RGB_SRC_FORMAT */
+	outpdw(vg_base + 0x0054, pattern);	/* MDP_RGB_SRC_UNPACK_PATTERN */
+	if (format & MDP4_FORMAT_SOLID_FILL) {
+		u32 op_mode = pipe->op_mode;
+		op_mode &= ~(MDP4_OP_FLIP_LR + MDP4_OP_SCALEX_EN);
+		op_mode &= ~(MDP4_OP_FLIP_UD + MDP4_OP_SCALEY_EN);
+		outpdw(vg_base + 0x0058, op_mode);/* MDP_RGB_OP_MODE */
+	} else
+		outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
+	outpdw(vg_base + 0x005c, pipe->phasex_step);
+	outpdw(vg_base + 0x0060, pipe->phasey_step);
+
+	if (pipe->op_mode & MDP4_OP_DITHER_EN) {
+		outpdw(vg_base + 0x0068,
+			pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit);
+	}
+
+	if (pipe->flags & MDP_SHARPENING) {
+		outpdw(vg_base + 0x8200,
+			mdp4_ss_table_value(pipe->req_data.dpp.sharp_strength,
+									0));
+		outpdw(vg_base + 0x8204,
+			mdp4_ss_table_value(pipe->req_data.dpp.sharp_strength,
+									1));
+	}
+
+	if (mdp_rev > MDP_REV_41) {
+		/* mdp chip select controller */
+		mask = 0;
+		if (pipe->pipe_num == OVERLAY_PIPE_VG1)
+			mask = 0x020; /* bit 5 */
+		else if (pipe->pipe_num == OVERLAY_PIPE_VG2)
+			mask = 0x02000; /* bit 13 */
+		if (mask) {
+			if (pipe->op_mode & MDP4_OP_SCALEY_MN_PHASE)
+				ctrl->cs_controller &= ~mask;
+			else
+				ctrl->cs_controller |= mask;
+			/* NOT double buffered */
+			outpdw(MDP_BASE + 0x00c0, ctrl->cs_controller);
+		}
+	}
 
 
-	mdp_writel(pipe->mdp, pipe->srcp1_ystride << 16 | pipe->srcp0_ystride, vg_base + 0x0040);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
-	mdp_writel(pipe->mdp, format, vg_base + 0x0050);	/* MDP_RGB_SRC_FORMAT */
-	mdp_writel(pipe->mdp, pattern, vg_base + 0x0054);	/* MDP_RGB_SRC_UNPACK_PATTERN */
-	mdp_writel(pipe->mdp, pipe->op_mode, vg_base + 0x0058); /* MDP_RGB_OP_MODE */
-	mdp_writel(pipe->mdp, pipe->phasex_step, vg_base + 0x005c);
-	mdp_writel(pipe->mdp, pipe->phasey_step, vg_base + 0x0060);
-
-	if (pipe->op_mode & MDP4_OP_DITHER_EN)
-		mdp_writel(pipe->mdp, pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit, vg_base + 0x0068);
-
-	return 0;
+	mdp4_stat.pipe[pipe->pipe_num]++;
 }
 
-int mdp4_overlay_format2type(uint32_t format)
+int mdp4_overlay_format2type(uint32 format)
 {
 	switch (format) {
 	case MDP_RGB_565:
@@ -618,12 +972,21 @@
 	case MDP_Y_CBCR_H2V2:
 	case MDP_Y_CBCR_H2V2_TILE:
 	case MDP_Y_CRCB_H2V2_TILE:
+	case MDP_Y_CR_CB_H2V2:
+	case MDP_Y_CR_CB_GH2V2:
+	case MDP_Y_CB_CR_H2V2:
 	case MDP_Y_CRCB_H1V1:
 	case MDP_Y_CBCR_H1V1:
+	case MDP_YCRCB_H1V1:
+	case MDP_YCBCR_H1V1:
 		return OVERLAY_TYPE_VIDEO;
+	case MDP_RGB_BORDERFILL:
+		return OVERLAY_TYPE_BF;
 	default:
+		mdp4_stat.err_format++;
 		return -ERANGE;
 	}
+
 }
 
 #define C3_ALPHA	3	/* alpha */
@@ -858,8 +1221,47 @@
 		}
 		pipe->bpp = 2;	/* 2 bpp */
 		break;
+	case MDP_Y_CR_CB_H2V2:
+	case MDP_Y_CR_CB_GH2V2:
+	case MDP_Y_CB_CR_H2V2:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_PLANAR;
+		pipe->a_bit = 0;
+		pipe->r_bit = 3;	/* R, 8 bits */
+		pipe->b_bit = 3;	/* B, 8 bits */
+		pipe->g_bit = 3;	/* G, 8 bits */
+		pipe->alpha_enable = 0;
+		pipe->chroma_sample = MDP4_CHROMA_420;
+		pipe->bpp = 2;	/* 2 bpp */
+		break;
+	case MDP_YCBCR_H1V1:
+	case MDP_YCRCB_H1V1:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 0;
+		pipe->r_bit = 3;    /* R, 8 bits */
+		pipe->b_bit = 3;    /* B, 8 bits */
+		pipe->g_bit = 3;    /* G, 8 bits */
+		pipe->alpha_enable = 0;
+		pipe->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 2;
+		pipe->element0 = C0_G_Y;    /* G */
+		if (pipe->src_format == MDP_YCRCB_H1V1) {
+			pipe->element1 = C2_R_Cr; /* R */
+			pipe->element2 = C1_B_Cb; /* B */
+		} else {
+			pipe->element1 = C1_B_Cb;   /* B */
+			pipe->element2 = C2_R_Cr;   /* R */
+		}
+		pipe->bpp = 3;  /* 3 bpp */
+	case MDP_RGB_BORDERFILL:
+		pipe->alpha_enable = 0;
+		pipe->alpha = 0;
+		break;
 	default:
 		/* not likely */
+		mdp4_stat.err_format++;
 		return -ERANGE;
 	}
 
@@ -869,9 +1271,9 @@
 /*
  * color_key_convert: output with 12 bits color key
  */
-static uint32_t color_key_convert(int start, int num, uint32_t color)
+static uint32 color_key_convert(int start, int num, uint32 color)
 {
-	uint32_t data;
+	uint32 data;
 
 	data = (color >> start) & ((1 << num) - 1);
 
@@ -887,8 +1289,8 @@
 	return data;
 }
 
-void transp_color_key(int format, uint32_t transp,
-			uint32_t *c0, uint32_t *c1, uint32_t *c2)
+void transp_color_key(int format, uint32 transp,
+			uint32 *c0, uint32 *c1, uint32 *c2)
 {
 	int b_start, g_start, r_start;
 	int b_num, g_num, r_num;
@@ -930,8 +1332,10 @@
 		g_num = 6;
 		b_num = 5;
 		break;
+	case MDP_Y_CB_CR_H2V2:
 	case MDP_Y_CBCR_H2V2:
 	case MDP_Y_CBCR_H2V1:
+	case MDP_YCBCR_H1V1:
 		b_start = 8;
 		g_start = 16;
 		r_start = 0;
@@ -939,10 +1343,13 @@
 		g_num = 8;
 		b_num = 8;
 		break;
+	case MDP_Y_CR_CB_H2V2:
+	case MDP_Y_CR_CB_GH2V2:
 	case MDP_Y_CRCB_H2V2:
 	case MDP_Y_CRCB_H2V1:
 	case MDP_Y_CRCB_H1V1:
 	case MDP_Y_CBCR_H1V1:
+	case MDP_YCRCB_H1V1:
 		b_start = 0;
 		g_start = 16;
 		r_start = 8;
@@ -965,9 +1372,9 @@
 	*c2 = color_key_convert(r_start, r_num, transp);
 }
 
-uint32_t mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
+uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
 {
-	uint32_t	format;
+	uint32	format;
 
 	format = 0;
 
@@ -983,6 +1390,8 @@
 	if (pipe->alpha_enable)
 		format |= MDP4_FORMAT_ALPHA_ENABLE;
 
+	if (pipe->flags & MDP_SOURCE_ROTATED_90)
+		format |= MDP4_FORMAT_90_ROTATED;
 	format |= (pipe->unpack_count << 13);
 	format |= ((pipe->bpp - 1) << 9);
 	format |= (pipe->a_bit << 6);
@@ -992,7 +1401,8 @@
 
 	format |= (pipe->frame_format << 29);
 
-	if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
+	if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR ||
+			pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
 		/* video/graphic */
 		format |= (pipe->fetch_plane << 19);
 		format |= (pipe->chroma_site << 28);
@@ -1002,87 +1412,134 @@
 	return format;
 }
 
-uint32_t mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
+uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
 {
 	return (pipe->element3 << 24) | (pipe->element2 << 16) |
 			(pipe->element1 << 8) | pipe->element0;
 }
+
 /*
  * mdp4_overlayproc_cfg: only be called from base layer
  */
 void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe)
 {
-	uint32_t data;
-	uint32_t overlay_base;
+	uint32 data, intf;
+	char *overlay_base;
 
-	if (pipe->mixer_num == MDP4_MIXER1)
-		overlay_base = MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
-	else
-		overlay_base = MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+	intf = 0;
+	if (pipe->mixer_num == MDP4_MIXER2)
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC2_BASE;
+	else if (pipe->mixer_num == MDP4_MIXER1) {
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
+		intf = inpdw(MDP_BASE + 0x0038); /* MDP_DISP_INTF_SEL */
+		intf >>= 4;
+		intf &= 0x03;
+	} else
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
 
-	/* MDP_OVERLAYPROC_CFG */
-	mdp_writel(pipe->mdp, 0x01, overlay_base + 0x0004); /* directout */
-	data = pipe->src_height;
-	data <<= 16;
-	data |= pipe->src_width;
-	mdp_writel(pipe->mdp, data, overlay_base + 0x0008); /* ROI, height + width */
+	if (!in_interrupt())
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
 	/*
-	 * BLT only siupport at primary display
+	 * BLT support both primary and external external
 	 */
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-	if (pipe->mixer_num == MDP4_MIXER0 && pipe->blt_addr) {
-		int off;
-		int mddi = 0;
-		mddi = mdp_readl(pipe->mdp, 0x0038);
-		mddi &= 0x02;
-
-		if (!mddi) {
-		   mdp_writel(pipe->mdp, pipe->blt_addr, overlay_base + 0x000c);
-		   mdp_writel(pipe->mdp, pipe->src_width * 2, overlay_base + 0x0010);
-		   /* overlay ouput is RGB565 */
-		   off = pipe->src_height * pipe->src_width * 2;
-		   mdp_writel(pipe->mdp, pipe->blt_addr + off, overlay_base + 0x001c);
-		   /* LCDC - FRAME BUFFER + vsync rate */
-		   mdp_writel(pipe->mdp, 0x02, overlay_base + 0x0004);
-		} else { /* MDDI */
+	if (pipe->ov_blt_addr) {
+		int off, bpp;
+#ifdef BLT_RGB565
+		bpp = 2;  /* overlay ouput is RGB565 */
+#else
+		bpp = 3;  /* overlay ouput is RGB888 */
+#endif
+		data = pipe->src_height;
+		data <<= 16;
+		data |= pipe->src_width;
+		outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
+		if (pipe->mixer_num == MDP4_MIXER0 ||
+		    pipe->mixer_num == MDP4_MIXER1) {
 			off = 0;
-			if (pipe->blt_cnt & 0x01)
-				off = pipe->src_height * pipe->src_width * 2;
+			if (pipe->ov_cnt & 0x01)
+				off = pipe->src_height * pipe->src_width * bpp;
 
-			mdp_writel(pipe->mdp, pipe->blt_addr+off, overlay_base + 0x000c);
-			/* overlay ouput is RGB565 */
-			mdp_writel(pipe->mdp, pipe->src_width * 2, overlay_base + 0x0010);
-			mdp_writel(pipe->mdp, pipe->blt_addr + off, overlay_base + 0x001c);
+			outpdw(overlay_base + 0x000c, pipe->ov_blt_addr + off);
+			/* overlay ouput is RGB888 */
+			outpdw(overlay_base + 0x0010, pipe->src_width * bpp);
+			outpdw(overlay_base + 0x001c, pipe->ov_blt_addr + off);
 			/* MDDI - BLT + on demand */
-			mdp_writel(pipe->mdp, 0x02, overlay_base + 0x0004);
+			outpdw(overlay_base + 0x0004, 0x08);
+#ifdef BLT_RGB565
+			outpdw(overlay_base + 0x0014, 0x1); /* RGB565 */
+#else
+			outpdw(overlay_base + 0x0014, 0x0); /* RGB888 */
+#endif
+		} else if (pipe->mixer_num == MDP4_MIXER2) {
+			if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
+				off = 0;
+				bpp = 1;
+				if (pipe->ov_cnt & 0x01)
+					off = pipe->src_height *
+							pipe->src_width * bpp;
+
+				outpdw(overlay_base + 0x000c,
+						pipe->ov_blt_addr + off);
+				/* overlay ouput is RGB888 */
+				outpdw(overlay_base + 0x0010,
+					((pipe->src_width << 16) |
+					 pipe->src_width));
+				outpdw(overlay_base + 0x001c,
+						pipe->ov_blt_addr + off);
+				off = pipe->src_height * pipe->src_width;
+				/* align chroma to 2k address */
+				off = (off + 2047) & ~2047;
+				/* UV plane adress */
+				outpdw(overlay_base + 0x0020,
+						pipe->ov_blt_addr + off);
+				/* MDDI - BLT + on demand */
+				outpdw(overlay_base + 0x0004, 0x08);
+				/* pseudo planar + writeback */
+				outpdw(overlay_base + 0x0014, 0x012);
+				/* rgb->yuv */
+				outpdw(overlay_base + 0x0200, 0x05);
+			}
 		}
 	} else {
-		mdp_writel(pipe->mdp, data, overlay_base + 0x0008);
-		mdp_writel(pipe->mdp, pipe->srcp0_addr, overlay_base + 0x000c);
-		mdp_writel(pipe->mdp, pipe->srcp0_ystride, overlay_base + 0x0010);
-		mdp_writel(pipe->mdp, 0x01, overlay_base + 0x0004);
+		data = pipe->src_height;
+		data <<= 16;
+		data |= pipe->src_width;
+		outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
+		outpdw(overlay_base + 0x000c, pipe->srcp0_addr);
+		outpdw(overlay_base + 0x0010, pipe->srcp0_ystride);
+		outpdw(overlay_base + 0x0004, 0x01); /* directout */
 	}
-#else
-	mdp_writel(pipe->mdp, data, overlay_base + 0x0008);/* ROI, height + width */
-	mdp_writel(pipe->mdp, pipe->srcp0_addr, overlay_base + 0x000c);
-	mdp_writel(pipe->mdp, pipe->srcp0_ystride, overlay_base + 0x0010);
-#endif
 
+	if (pipe->mixer_num == MDP4_MIXER1) {
+		if (intf == TV_INTF) {
+			outpdw(overlay_base + 0x0014, 0x02); /* yuv422 */
+			/* overlay1 CSC config */
+			outpdw(overlay_base + 0x0200, 0x05); /* rgb->yuv */
+		}
+	}
 
 #ifdef MDP4_IGC_LUT_ENABLE
-	mdp_writel(pipe->mdp, 0x4, overlay_base + 0x0014); /* GC_LUT_EN, 888 */
+	outpdw(overlay_base + 0x0014, 0x4);	/* GC_LUT_EN, 888 */
 #endif
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-	mdp_writel(pipe->mdp, 0x1, overlay_base + 0x0014);
-#endif
+
+	if (!in_interrupt())
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-int mdp4_overlay_active(struct mdp_info *mdp, int mixer)
+int mdp4_overlay_pipe_staged(int mixer)
 {
-	uint32_t data, mask, i;
+	uint32 data, mask, i, off;
 	int p1, p2;
 
-	data = mdp_readl(mdp, 0x10100);
+	if (mixer == MDP4_MIXER2)
+		off = 0x100F0;
+	else
+		off = 0x10100;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	data = inpdw(MDP_BASE + off);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 	p1 = 0;
 	p2 = 0;
 	for (i = 0; i < 8; i++) {
@@ -1102,178 +1559,498 @@
 		return p1;
 }
 
-void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
+int mdp4_mixer_info(int mixer_num, struct mdp_mixer_info *info)
 {
-	uint32_t data, mask, snum, stage, mixer, pnum;
 
-	stage = pipe->mixer_stage;
-	mixer = pipe->mixer_num;
-	pnum = pipe->pipe_num;
+	int ndx, cnt;
+	struct mdp4_overlay_pipe *pipe;
 
-	/* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1  */
-	data = mdp_readl(pipe->mdp, 0x10100);
+	if (mixer_num > MDP4_MIXER_MAX)
+		return -ENODEV;
 
-	if (mixer == MDP4_MIXER1)
-		stage += 8;
+	cnt = 0;
+	ndx = MDP4_MIXER_STAGE_BASE;
+	for ( ; ndx < MDP4_MIXER_STAGE_MAX; ndx++) {
+		pipe = ctrl->stage[mixer_num][ndx];
+		if (pipe == NULL)
+			continue;
+		info->z_order = pipe->mixer_stage - MDP4_MIXER_STAGE0;
+		/* z_order == -1, means base layer */
+		info->ptype = pipe->pipe_type;
+		info->pnum = pipe->pipe_num;
+		info->pndx = pipe->pipe_ndx;
+		info->mixer_num = pipe->mixer_num;
+		info++;
+		cnt++;
+	}
+	return cnt;
+}
 
-	if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {/* VG1 and VG2 */
-		pnum -= OVERLAY_PIPE_VG1; /* start from 0 */
-		snum = 0;
-		snum += (4 * pnum);
-	} else {
-		snum = 8;
-		snum += (4 * pnum);	/* RGB1 and RGB2 */
+void mdp4_mixer_stage_commit(int mixer)
+{
+	struct mdp4_overlay_pipe *pipe;
+	int i, num;
+	u32 data, stage;
+	int off;
+	unsigned long flags;
+
+	data = 0;
+	for (i = MDP4_MIXER_STAGE_BASE; i < MDP4_MIXER_STAGE_MAX; i++) {
+		pipe = ctrl->stage[mixer][i];
+		if (pipe == NULL)
+			continue;
+		pr_debug("%s: mixer=%d ndx=%d stage=%d\n", __func__,
+					mixer, pipe->pipe_ndx, i);
+		stage = pipe->mixer_stage;
+		if (mixer >= MDP4_MIXER1)
+			stage += 8;
+		stage <<= (4 * pipe->pipe_num);
+		data |= stage;
 	}
 
-	mask = 0x0f;
-	mask <<= snum;
-	stage <<= snum;
-	data &= ~mask;	/* clear old bits */
+	mdp4_mixer_blend_setup(mixer);
 
-	data |= stage;
+	off = 0;
+	if (data != ctrl->mixer_cfg[mixer]) {
+		ctrl->mixer_cfg[mixer] = data;
+		if (mixer >= MDP4_MIXER2) {
+			/* MDP_LAYERMIXER2_IN_CFG */
+			off = 0x100f0;
+		} else {
+			/* mixer 0 or 1 */
+			num = mixer + 1;
+			num &= 0x01;
+			data |= ctrl->mixer_cfg[num];
+			off = 0x10100;
+		}
+		pr_debug("%s: mixer=%d data=%x flush=%x pid=%d\n", __func__,
+				mixer, data, ctrl->flush[mixer], current->pid);
+	}
 
-	mdp_writel(pipe->mdp, data, 0x10100); /* MDP_LAYERMIXER_IN_CFG */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	local_irq_save(flags);
+	if (off)
+		outpdw(MDP_BASE + off, data);
 
-	data = mdp_readl(pipe->mdp, 0x10100);
+	if (ctrl->flush[mixer]) {
+		outpdw(MDP_BASE + 0x18000, ctrl->flush[mixer]);
+		ctrl->flush[mixer] = 0;
+	}
+	local_irq_restore(flags);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
 
-	ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe;	/* keep it */
+
+void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
+{
+	struct mdp4_overlay_pipe *pp;
+	int i, mixer;
+
+	mixer = pipe->mixer_num;
+
+	for (i = MDP4_MIXER_STAGE_BASE; i < MDP4_MIXER_STAGE_MAX; i++) {
+		pp = ctrl->stage[mixer][i];
+		if (pp && pp->pipe_ndx == pipe->pipe_ndx) {
+			ctrl->stage[mixer][i] = NULL;
+			break;
+		}
+	}
+
+	ctrl->stage[mixer][pipe->mixer_stage] = pipe;	/* keep it */
 }
 
 void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe)
 {
-	uint32_t data, mask, snum, stage, mixer, pnum;
+	struct mdp4_overlay_pipe *pp;
+	int i, mixer;
 
-	stage = pipe->mixer_stage;
 	mixer = pipe->mixer_num;
-	pnum = pipe->pipe_num;
 
-	if (pipe != ctrl->stage[mixer][stage])	/* not runing */
-		return;
-
-	/* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1  */
-	data = mdp_readl(pipe->mdp, 0x10100);
-
-	if (mixer == MDP4_MIXER1)
-		stage += 8;
-
-	if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {/* VG1 and VG2 */
-		pnum -= OVERLAY_PIPE_VG1; /* start from 0 */
-		snum = 0;
-		snum += (4 * pnum);
-	} else {
-		snum = 8;
-		snum += (4 * pnum);	/* RGB1 and RGB2 */
+	for (i = MDP4_MIXER_STAGE_BASE; i < MDP4_MIXER_STAGE_MAX; i++) {
+		pp = ctrl->stage[mixer][i];
+		if (pp && pp->pipe_ndx == pipe->pipe_ndx)
+			ctrl->stage[mixer][i] = NULL;  /* clear it */
 	}
 
-	mask = 0x0f;
-	mask <<= snum;
-	data &= ~mask;	/* clear old bits */
+	mdp4_mixer_stage_commit(mixer);
+}
+/*
+ * mixer0: rgb3: border color at register 0x15004, 0x15008
+ * mixer1:  vg3: border color at register 0x1D004, 0x1D008
+ * mixer2:  xxx: border color at register 0x8D004, 0x8D008
+ */
+void mdp4_overlay_borderfill_stage_up(struct mdp4_overlay_pipe *pipe)
+{
+	struct mdp4_overlay_pipe *bspipe;
+	int ptype, pnum, pndx, mixer;
+	int format, alpha_enable, alpha;
 
-	mdp_writel(pipe->mdp, data, 0x10100); /* MDP_LAYERMIXER_IN_CFG */
+	if (pipe->pipe_type != OVERLAY_TYPE_BF)
+		return;
 
-	data = mdp_readl(pipe->mdp, 0x10100);
+	mixer = pipe->mixer_num;
 
-	ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL;	/* clear it */
+	if (ctrl->baselayer[mixer])
+		return;
+
+	bspipe = ctrl->stage[mixer][MDP4_MIXER_STAGE_BASE];
+
+	/*
+	 * bspipe is clone here
+	 * get real pipe
+	 */
+	bspipe = mdp4_overlay_ndx2pipe(bspipe->pipe_ndx);
+
+	/* save original base layer */
+	ctrl->baselayer[mixer] = bspipe;
+
+	pipe->alpha = 0;	/* make sure bf pipe has alpha 0 */
+	ptype = pipe->pipe_type;
+	pnum = pipe->pipe_num;
+	pndx = pipe->pipe_ndx;
+	format = pipe->src_format;
+	alpha_enable = pipe->alpha_enable;
+	alpha = pipe->alpha;
+	*pipe = *bspipe;	/* keep base layer configuration */
+	pipe->pipe_type = ptype;
+	pipe->pipe_num = pnum;
+	pipe->pipe_ndx = pndx;
+	pipe->src_format = format;
+	pipe->alpha_enable = alpha_enable;
+	pipe->alpha = alpha;
+
+	/* free original base layer pipe to be sued as normal pipe */
+	bspipe->pipe_used = 0;
+
+	if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
+		mdp4_dsi_video_base_swap(0, pipe);
+	else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+		mdp4_dsi_cmd_base_swap(0, pipe);
+	else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+		mdp4_lcdc_base_swap(0, pipe);
+#ifdef CONFIG_FB_MSM_DTV
+	else if (ctrl->panel_mode & MDP4_PANEL_DTV)
+		mdp4_dtv_base_swap(0, pipe);
+#endif
+
+	mdp4_overlay_reg_flush(bspipe, 1);
+	/* borderfill pipe as base layer */
+	mdp4_mixer_stage_up(pipe);
 }
 
-void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
+void mdp4_overlay_borderfill_stage_down(struct mdp4_overlay_pipe *pipe)
 {
-	struct mdp4_overlay_pipe *bg_pipe;
-	uint32_t overlay_base;
-	uint32_t c0, c1, c2, blend_op;
-	int off;
+	struct mdp4_overlay_pipe *bspipe;
+	int ptype, pnum, pndx, mixer;
+	int format, alpha_enable, alpha;
 
-	if (pipe->mixer_num) 	/* mixer number, /dev/fb0, /dev/fb1 */
-		overlay_base = MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
-	else
-		overlay_base = MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+	if (pipe->pipe_type != OVERLAY_TYPE_BF)
+		return;
 
-	/* stage 0 to stage 2 */
-	off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
+	mixer = pipe->mixer_num;
 
-	bg_pipe = mdp4_overlay_stage_pipe(pipe->mixer_num,
-					MDP4_MIXER_STAGE_BASE);
-	if (bg_pipe == NULL) {
-		PR_DISP_INFO("%s: Error: no bg_pipe\n", __func__);
+	/* retrieve original base layer */
+	bspipe = ctrl->baselayer[mixer];
+	if (bspipe == NULL) {
+		pr_err("%s: no base layer at mixer=%d\n",
+				__func__, mixer);
 		return;
 	}
 
+	ptype = bspipe->pipe_type;
+	pnum = bspipe->pipe_num;
+	pndx = bspipe->pipe_ndx;
+	format = bspipe->src_format;
+	alpha_enable = bspipe->alpha_enable;
+	alpha = bspipe->alpha;
+	*bspipe = *pipe;	/* restore base layer configuration */
+	bspipe->pipe_type = ptype;
+	bspipe->pipe_num = pnum;
+	bspipe->pipe_ndx = pndx;
+	bspipe->src_format = format;
+	bspipe->alpha_enable = alpha_enable;
+	bspipe->alpha = alpha;
 
-	blend_op = 0;
-	if (pipe->is_fg) {
-		blend_op |= (MDP4_BLEND_FG_ALPHA_FG_CONST |
-				MDP4_BLEND_BG_ALPHA_BG_CONST);
-		mdp_writel(pipe->mdp, pipe->alpha, overlay_base + off + 0x108);
-		mdp_writel(pipe->mdp, 0xff - pipe->alpha, overlay_base + off + 0x10c);
+	bspipe->pipe_used++;	/* mark base layer pipe used */
+
+	ctrl->baselayer[mixer] = NULL;
+
+	/* free borderfill pipe */
+	pipe->pipe_used = 0;
+
+	if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
+		mdp4_dsi_video_base_swap(0, bspipe);
+	else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+		mdp4_dsi_cmd_base_swap(0, bspipe);
+	else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+		mdp4_lcdc_base_swap(0, bspipe);
+#ifdef CONFIG_FB_MSM_DTV
+	else if (ctrl->panel_mode & MDP4_PANEL_DTV)
+		mdp4_dtv_base_swap(0, bspipe);
+#endif
+
+	/* free borderfill pipe */
+	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_down(pipe);
+	mdp4_overlay_pipe_free(pipe);
+
+	/* stage up base layer */
+	mdp4_overlay_reg_flush(bspipe, 1);
+	/* restore original base layer */
+	mdp4_mixer_stage_up(bspipe);
+}
+
+
+static struct mdp4_overlay_pipe *mdp4_background_layer(int mixer,
+			struct mdp4_overlay_pipe *sp)
+{
+	struct mdp4_overlay_pipe *pp;
+	struct mdp4_overlay_pipe *kp;
+	int i;
+
+	kp = ctrl->stage[mixer][MDP4_MIXER_STAGE_BASE];
+	for (i = MDP4_MIXER_STAGE_BASE; i < MDP4_MIXER_STAGE_MAX; i++) {
+		pp = ctrl->stage[mixer][i];
+		if (pp == NULL)
+			continue;
+		if (pp == sp)
+			break;
+
+		if ((pp->dst_x <= sp->dst_x) &&
+			((pp->dst_x + pp->dst_w) >= (sp->dst_x + sp->dst_w))) {
+			if ((pp->dst_y <= sp->dst_y) &&
+				((pp->dst_y + pp->dst_h) >=
+					(sp->dst_y + sp->dst_h))) {
+				kp = pp;
+			}
+		}
+	}
+	return kp;
+}
+
+static void mdp4_overlay_bg_solidfill(struct blend_cfg *blend)
+{
+	struct mdp4_overlay_pipe *pipe;
+	char *base;
+	u32 op_mode, format;
+	int pnum, ptype;
+
+	pipe = blend->solidfill_pipe;
+	if (pipe == NULL)
+		return;
+
+	if (pipe->pipe_type == OVERLAY_TYPE_BF)
+		return;
+
+	ptype = mdp4_overlay_format2type(pipe->src_format);
+	if (ptype == OVERLAY_TYPE_RGB) {
+		pnum = pipe->pipe_num - OVERLAY_PIPE_RGB1;
+		base = MDP_BASE + MDP4_RGB_BASE;
+		base += MDP4_RGB_OFF * pnum;
 	} else {
-		if (bg_pipe->alpha_enable && pipe->alpha_enable) {
-			/* both pipe have alpha */
-			blend_op |= (MDP4_BLEND_FG_ALPHA_BG_PIXEL |
-				MDP4_BLEND_FG_INV_ALPHA |
-				MDP4_BLEND_BG_ALPHA_BG_PIXEL);
-	} else if (bg_pipe->alpha_enable && pipe->alpha_enable == 0) {
-		blend_op = (MDP4_BLEND_BG_ALPHA_BG_PIXEL |
-				MDP4_BLEND_FG_ALPHA_BG_PIXEL |
-				MDP4_BLEND_FG_INV_ALPHA);
-		}
+		pnum = pipe->pipe_num - OVERLAY_PIPE_VG1;
+		base = MDP_BASE + MDP4_VIDEO_BASE;
+		base += MDP4_VIDEO_OFF * pnum;
 	}
 
-	if (pipe->transp != MDP_TRANSP_NOP) {
-		if (pipe->is_fg) {
-			transp_color_key(pipe->src_format, pipe->transp,
-						&c0, &c1, &c2);
-#if 0
-			/* FIXME: We don't enable this function until framework can support color keying. */
-			blend_op |= MDP4_BLEND_FG_TRANSP_EN; /* Fg blocked */
-#endif
-			/* lower limit */
-			mdp_writel(pipe->mdp, (c1 << 16 | c0), overlay_base + off + 0x110); /* low */
-			mdp_writel(pipe->mdp, c2, overlay_base + off + 0x114);/* low */
-			/* upper limit */
-			mdp_writel(pipe->mdp, (c1 << 16 | c0), overlay_base + off + 0x118);/* high */
-			mdp_writel(pipe->mdp, c2, overlay_base + off + 0x11c);/* high */
-		} else {
-			transp_color_key(bg_pipe->src_format, pipe->transp,
-						&c0, &c1, &c2);
-#if 0
-			blend_op |= MDP4_BLEND_BG_TRANSP_EN; /* bg blocked */
-#endif
-			/* lower limit */
-			mdp_writel(pipe->mdp, (c1 << 16 | c0), overlay_base + off + 0x180);/* low */
-			mdp_writel(pipe->mdp, c2, overlay_base + off + 0x184);/* low */
-			/* upper limit */
-			mdp_writel(pipe->mdp, (c1 << 16 | c0), overlay_base + off + 0x188);/* high */
-			mdp_writel(pipe->mdp, c2, overlay_base + off + 0x18c);/* high */
-		}
+	format = inpdw(base + 0x50);
+	if (blend->solidfill) {
+		format |= MDP4_FORMAT_SOLID_FILL;
+		/*
+		 * If solid fill is enabled, flip and scale
+		 * have to be disabled. otherwise, h/w
+		 * underruns.
+		 */
+		op_mode = inpdw(base + 0x0058);
+		op_mode &= ~(MDP4_OP_FLIP_LR + MDP4_OP_SCALEX_EN);
+		op_mode &= ~(MDP4_OP_FLIP_UD + MDP4_OP_SCALEY_EN);
+		outpdw(base + 0x0058, op_mode);
+		outpdw(base + 0x1008, 0);	/* black */
+		/*
+		 * Set src size and dst size same to avoid underruns
+		 */
+		outpdw(base + 0x0000, inpdw(base + 0x0008));
+	} else {
+		u32 src_size = ((pipe->src_h << 16) | pipe->src_w);
+		outpdw(base + 0x0000, src_size);
+		format &= ~MDP4_FORMAT_SOLID_FILL;
+		blend->solidfill_pipe = NULL;
 	}
 
-	mdp_writel(pipe->mdp, blend_op, overlay_base + off + 0x104);
+	outpdw(base + 0x50, format);
+
+	mdp4_overlay_reg_flush(pipe, 0);
+}
+
+/*
+ * D(i+1) = Ks * S + Kd * D(i)
+ */
+void mdp4_mixer_blend_setup(int mixer)
+{
+	struct mdp4_overlay_pipe *d_pipe;
+	struct mdp4_overlay_pipe *s_pipe;
+	struct blend_cfg *blend;
+	int i, off, ptype;
+	int d_alpha, s_alpha;
+	unsigned char *overlay_base;
+	uint32 c0, c1, c2;
+
+
+	d_pipe = ctrl->stage[mixer][MDP4_MIXER_STAGE_BASE];
+	if (d_pipe == NULL) {
+		pr_err("%s: Error: no bg_pipe at mixer=%d\n", __func__, mixer);
+		return;
+	}
+
+	blend = &ctrl->blend[mixer][MDP4_MIXER_STAGE0];
+	for (i = MDP4_MIXER_STAGE0; i < MDP4_MIXER_STAGE_MAX; i++) {
+		blend->solidfill = 0;
+		blend->op = (MDP4_BLEND_FG_ALPHA_FG_CONST |
+				    MDP4_BLEND_BG_ALPHA_BG_CONST);
+		s_pipe = ctrl->stage[mixer][i];
+		if (s_pipe == NULL) {
+			blend++;
+			d_pipe = NULL;
+			d_alpha = 0;
+			continue;
+		}
+		d_pipe = mdp4_background_layer(mixer, s_pipe);
+		d_alpha = d_pipe->alpha_enable;
+		s_alpha = s_pipe->alpha_enable;
+		pr_debug("%s: stage=%d: bg: ndx=%d da=%d dalpha=%x "
+			"fg: ndx=%d sa=%d salpha=%x is_fg=%d\n",
+		 __func__, i-2, d_pipe->pipe_ndx, d_alpha, d_pipe->alpha,
+		s_pipe->pipe_ndx, s_alpha, s_pipe->alpha, s_pipe->is_fg);
+
+		/* base on fg's alpha */
+		blend->bg_alpha = 0x0ff - s_pipe->alpha;
+		blend->fg_alpha = s_pipe->alpha;
+		blend->co3_sel = 1; /* use fg alpha */
+
+		if (s_pipe->is_fg) {
+			if (s_pipe->alpha == 0xff) {
+				blend->solidfill = 1;
+				blend->solidfill_pipe = d_pipe;
+			}
+		} else if (s_alpha) {
+			blend->op = (MDP4_BLEND_BG_ALPHA_FG_PIXEL |
+				    MDP4_BLEND_BG_INV_ALPHA);
+		} else if (d_alpha) {
+			ptype = mdp4_overlay_format2type(s_pipe->src_format);
+			if (ptype == OVERLAY_TYPE_VIDEO) {
+				blend->op = (MDP4_BLEND_BG_ALPHA_BG_PIXEL |
+				    MDP4_BLEND_FG_ALPHA_BG_PIXEL |
+				    MDP4_BLEND_FG_INV_ALPHA);
+				blend->co3_sel = 0; /* use bg alpha */
+			} else {
+				/* s_pipe is rgb without alpha */
+				blend->op = (MDP4_BLEND_FG_ALPHA_FG_CONST |
+					    MDP4_BLEND_BG_ALPHA_BG_CONST);
+				blend->bg_alpha = 0;
+			}
+		}
+
+		if (s_pipe->transp != MDP_TRANSP_NOP) {
+			if (s_pipe->is_fg) {
+				transp_color_key(s_pipe->src_format,
+						s_pipe->transp, &c0, &c1, &c2);
+				/* Fg blocked */
+				blend->op |= MDP4_BLEND_FG_TRANSP_EN;
+				/* lower limit */
+				blend->transp_low0 = (c1 << 16 | c0);
+				blend->transp_low1 = c2;
+				/* upper limit */
+				blend->transp_high0 = (c1 << 16 | c0);
+				blend->transp_high1 = c2;
+			} else {
+				transp_color_key(d_pipe->src_format,
+						s_pipe->transp, &c0, &c1, &c2);
+				/* Fg blocked */
+				blend->op |= MDP4_BLEND_BG_TRANSP_EN;
+				blend--; /* one stage back */
+				/* lower limit */
+				blend->transp_low0 = (c1 << 16 | c0);
+				blend->transp_low1 = c2;
+				/* upper limit */
+				blend->transp_high0 = (c1 << 16 | c0);
+				blend->transp_high1 = c2;
+				blend++; /* back to original stage */
+			}
+		}
+		blend++;
+	}
+
+	/* mixer numer, /dev/fb0, /dev/fb1, /dev/fb2 */
+	if (mixer == MDP4_MIXER2)
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC2_BASE;/* 0x88000 */
+	else if (mixer == MDP4_MIXER1)
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
+	else
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	blend = &ctrl->blend[mixer][MDP4_MIXER_STAGE_BASE];
+	/* lower limit */
+	outpdw(overlay_base + 0x180, blend->transp_low0);
+	outpdw(overlay_base + 0x184,  blend->transp_low1);
+	/* upper limit */
+	outpdw(overlay_base + 0x188, blend->transp_high0);
+	outpdw(overlay_base + 0x18c,  blend->transp_high1);
+	blend++; /* stage0 */
+	for (i = MDP4_MIXER_STAGE0; i < MDP4_MIXER_STAGE_MAX; i++) {
+		off = 20 * i;
+		off = 0x20 * (i - MDP4_MIXER_STAGE0);
+		if (i == MDP4_MIXER_STAGE3)
+			off -= 4;
+
+		if (blend->solidfill_pipe)
+			mdp4_overlay_bg_solidfill(blend);
+
+		outpdw(overlay_base + off + 0x108, blend->fg_alpha);
+		outpdw(overlay_base + off + 0x10c, blend->bg_alpha);
+		outpdw(overlay_base + off + 0x104, blend->op);
+		outpdw(overlay_base + (off << 5) + 0x1004, blend->co3_sel);
+		outpdw(overlay_base + off + 0x110, blend->transp_low0);/* low */
+		outpdw(overlay_base + off + 0x114, blend->transp_low1);/* low */
+			/* upper limit */
+		outpdw(overlay_base + off + 0x118, blend->transp_high0);
+		outpdw(overlay_base + off + 0x11c, blend->transp_high1);
+		blend++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
 void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
 {
-	uint32_t bits = 0;
+	int mixer;
+	uint32 *reg;
 
-	if (pipe->mixer_num == MDP4_MIXER1)
-		bits |= 0x02;
-	else
-		bits |= 0x01;
+	mixer = pipe->mixer_num;
+	reg = &ctrl->flush[mixer];
+	*reg |= (1 << (2 + pipe->pipe_num));
 
 	if (all) {
-		if (pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
-			if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
-				bits |= 0x20;
-			else
-				bits |= 0x10;
-		} else {
-			if (pipe->pipe_num == OVERLAY_PIPE_VG2)
-				bits |= 0x08;
-			else
-				bits |= 0x04;
-		}
+		if (mixer == MDP4_MIXER0)
+			*reg |= 0x01;
+		else
+			*reg |= 0x02;
 	}
+}
 
-	mdp_writel(pipe->mdp, bits, 0x18000);	/* MDP_OVERLAY_REG_FLUSH */
+void mdp4_overlay_flush_piggyback(int m0, int m1)
+{
+	u32 data;
+
+	data = ctrl->flush[m0] | ctrl->flush[m1];
+	ctrl->flush[m0] = data;
+}
+
+void mdp4_overlay_reg_flush_reset(struct mdp4_overlay_pipe *pipe)
+{
+	int mixer;
+
+	mixer = pipe->mixer_num;
+	ctrl->flush[mixer] = 0;
 }
 
 struct mdp4_overlay_pipe *mdp4_overlay_stage_pipe(int mixer, int stage)
@@ -1285,7 +2062,7 @@
 {
 	struct mdp4_overlay_pipe *pipe;
 
-	if (ndx <= 0 || ndx > MDP4_MAX_PIPE)
+	if (ndx <= 0 || ndx > OVERLAY_PIPE_MAX)
 		return NULL;
 
 	pipe = &ctrl->plist[ndx - 1];	/* ndx start from 1 */
@@ -1296,25 +2073,33 @@
 	return pipe;
 }
 
-struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, bool usevg)
+struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer)
 {
-	int i = 0;
+	int i;
 	struct mdp4_overlay_pipe *pipe;
 
-	if (usevg)
-		i = 2;
-	pipe = &ctrl->plist[i];
-	for (; i < MDP4_MAX_PIPE; i++) {
-		if (pipe->pipe_type == ptype && pipe->pipe_used == 0) {
-			init_completion(&pipe->comp);
-			PR_DISP_INFO("mdp4_overlay_pipe_alloc: pipe=%x ndx=%d\n",
-				(int)pipe, pipe->pipe_ndx);
-			return pipe;
-		}
-		pipe++;
+	if (ptype == OVERLAY_TYPE_BF) {
+		if (!mdp4_overlay_borderfill_supported())
+			return NULL;
 	}
 
-	PR_DISP_INFO("mdp4_overlay_pipe_alloc: ptype=%d FAILED\n", ptype);
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++) {
+		pipe = &ctrl->plist[i];
+		if ((pipe->pipe_used == 0) && ((pipe->pipe_type == ptype) ||
+		    (ptype == OVERLAY_TYPE_RGB &&
+		     pipe->pipe_type == OVERLAY_TYPE_VIDEO))) {
+			if (ptype == OVERLAY_TYPE_BF &&
+			    mixer != pipe->mixer_num)
+				continue;
+			init_completion(&pipe->comp);
+			init_completion(&pipe->dmas_comp);
+			pr_debug("%s: pipe=%x ndx=%d num=%d\n", __func__,
+				(int)pipe, pipe->pipe_ndx, pipe->pipe_num);
+			return pipe;
+		}
+	}
+
+	pr_err("%s: ptype=%d FAILED\n", __func__, ptype);
 
 	return NULL;
 }
@@ -1322,138 +2107,220 @@
 
 void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
 {
-	uint32_t ptype, num, ndx;
-	struct mdp4_pipe_desc  *pd;
+	uint32 ptype, num, ndx, mixer;
+	struct mdp4_iommu_pipe_info iom;
 
-	PR_DISP_INFO("mdp4_overlay_pipe_free: pipe=%x ndx=%d\n",
-					(int)pipe, pipe->pipe_ndx);
-	pd = &ctrl->ov_pipe[pipe->pipe_num];
-	if (pd->ref_cnt)
-		pd->ref_cnt--;
-
-	pd->player = NULL;
+	pr_debug("%s: pipe=%x ndx=%d\n", __func__, (int)pipe, pipe->pipe_ndx);
 
 	ptype = pipe->pipe_type;
 	num = pipe->pipe_num;
 	ndx = pipe->pipe_ndx;
+	mixer = pipe->mixer_num;
 
+	mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+
+	iom = pipe->iommu;
 
 	memset(pipe, 0, sizeof(*pipe));
-
 	pipe->pipe_type = ptype;
 	pipe->pipe_num = num;
 	pipe->pipe_ndx = ndx;
-}
+	pipe->mixer_num = mixer;
+	pipe->iommu = iom;
 
-int mdp4_overlay_req_check(uint32_t id, uint32_t z_order, uint32_t mixer)
-{
-	struct mdp4_overlay_pipe *pipe;
-	/* HTC to support multiple overlays, correct stage array mapping
-	 *
-	 * base layer == 1, reserved for frame buffer
-	 * zorder 0 == stage 0 == 2
-	 * zorder 1 == stage 1 == 3
-	 * zorder 2 == stage 2 == 4
-	 */
-	/* FIXME: original design has problem, therefore, prevent query out of range stage array here */
-	if (z_order + MDP4_MIXER_STAGE0 >= MDP4_MAX_STAGE) {
-		PR_DISP_ERR("%s(%d) zorder=%d out of stage arry range\n", __func__, __LINE__, z_order);
-		return -EPERM;
-	}
-
-	pipe = ctrl->stage[mixer][z_order+MDP4_MIXER_STAGE0];
-
-	if (pipe == NULL)
-		return 0;
-
-	if (pipe->pipe_ndx == id)	/* same req, recycle */
-		return 0;
-
-	if (id == MSMFB_NEW_REQUEST) {  /* new request */
-		if (pipe->pipe_num >= OVERLAY_PIPE_VG1) /* share pipe */
-			return 0;
-	}
-
-	return -EPERM;
 }
 
 static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
-			struct mdp4_overlay_pipe **ppipe)
+			struct mdp4_overlay_pipe **ppipe,
+			struct msm_fb_data_type *mfd)
 {
 	struct mdp4_overlay_pipe *pipe;
-	struct mdp4_pipe_desc  *pd;
 	int ret, ptype;
 
-	if (mixer >= MDP4_MAX_MIXER) {
-		PR_DISP_ERR("mpd_overlay_req2pipe: mixer out of range!\n");
+	u32 upscale_max;
+	upscale_max = (mdp_rev >= MDP_REV_41) ?
+		MDP4_REV41_OR_LATER_UP_SCALING_MAX :
+		MDP4_REV40_UP_SCALING_MAX;
+
+	if (mfd == NULL) {
+		pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
+		return -ENODEV;
+	}
+
+	if (mixer >= MDP4_MIXER_MAX) {
+		pr_err("%s: mixer out of range!\n", __func__);
+		mdp4_stat.err_mixer++;
 		return -ERANGE;
 	}
 
-	if (req->z_order < 0 || req->z_order > 2) {
-		PR_DISP_ERR("mpd_overlay_req2pipe: z_order=%d out of range!\n",
+	if (req->z_order < 0 || req->z_order > 3) {
+		pr_err("%s: z_order=%d out of range!\n", __func__,
 				req->z_order);
+		mdp4_stat.err_zorder++;
 		return -ERANGE;
 	}
 
-	if (req->src_rect.h == 0 || req->src_rect.w == 0) {
-		PR_DISP_ERR("mpd_overlay_req2pipe: src img of zero size!\n");
+	if (req->src_rect.h > 0xFFF) {
+		pr_err("%s: src_h is out of range: 0X%x!\n",
+		       __func__, req->src_rect.h);
+		mdp4_stat.err_size++;
 		return -EINVAL;
 	}
 
+	if (req->src_rect.w > 0xFFF) {
+		pr_err("%s: src_w is out of range: 0X%x!\n",
+		       __func__, req->src_rect.w);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
 
-	if (req->dst_rect.h > (req->src_rect.h * 8)) {	/* too much */
-		PR_DISP_ERR("mpd_overlay_req2pipe: too much (h)!\n");
+	if (req->src_rect.x > 0xFFF) {
+		pr_err("%s: src_x is out of range: 0X%x!\n",
+		       __func__, req->src_rect.x);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
+
+	if (req->src_rect.y > 0xFFF) {
+		pr_err("%s: src_y is out of range: 0X%x!\n",
+		       __func__, req->src_rect.y);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
+
+	if (req->dst_rect.h > 0xFFF) {
+		pr_err("%s: dst_h is out of range: 0X%x!\n",
+		       __func__, req->dst_rect.h);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
+
+	if (req->dst_rect.w > 0xFFF) {
+		pr_err("%s: dst_w is out of range: 0X%x!\n",
+		       __func__, req->dst_rect.w);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
+
+	if (req->dst_rect.x > 0xFFF) {
+		pr_err("%s: dst_x is out of range: 0X%x!\n",
+		       __func__, req->dst_rect.x);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
+
+	if (req->dst_rect.y > 0xFFF) {
+		pr_err("%s: dst_y is out of range: 0X%x!\n",
+		       __func__, req->dst_rect.y);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
+
+	if (req->src_rect.h == 0 || req->src_rect.w == 0) {
+		pr_err("%s: src img of zero size!\n", __func__);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
+
+	if (req->dst_rect.h > (req->src_rect.h * upscale_max)) {
+		mdp4_stat.err_scale++;
+		pr_err("%s: scale up, too much (h)!\n", __func__);
 		return -ERANGE;
 	}
 
 	if (req->src_rect.h > (req->dst_rect.h * 8)) {	/* too little */
-		PR_DISP_ERR("mpd_overlay_req2pipe: too little (h)!\n");
+		mdp4_stat.err_scale++;
+		pr_err("%s: scale down, too little (h)!\n", __func__);
 		return -ERANGE;
 	}
 
-	if (req->dst_rect.w > (req->src_rect.w * 8)) {	/* too much */
-		PR_DISP_ERR("mpd_overlay_req2pipe: too much (w)!\n");
+	if (req->dst_rect.w > (req->src_rect.w * upscale_max)) {
+		mdp4_stat.err_scale++;
+		pr_err("%s: scale up, too much (w)!\n", __func__);
 		return -ERANGE;
 	}
 
 	if (req->src_rect.w > (req->dst_rect.w * 8)) {	/* too little */
-		PR_DISP_ERR("mpd_overlay_req2pipe: too little (w)!\n");
+		mdp4_stat.err_scale++;
+		pr_err("%s: scale down, too little (w)!\n", __func__);
 		return -ERANGE;
 	}
 
-	/* Current mdp only support the maximum 1/4 downscaling */
-	if (req->src_rect.w > req->dst_rect.w * 4 || req->src_rect.h > req->dst_rect.h * 4) {
-		PR_DISP_ERR("mdp_overlay_req2pipe: Don't support this kind of downscalig srcw=%d srch=%d dstw=%d dsth=%d\n",
-		req->src_rect.w, req->src_rect.h, req->dst_rect.w, req->dst_rect.h);
-		return -EINVAL;
+	if (mdp_hw_revision == MDP4_REVISION_V1) {
+		/*  non integer down saceling ratio  smaller than 1/4
+		 *  is not supportted
+		 */
+		if (req->src_rect.h > (req->dst_rect.h * 4)) {
+			if (req->src_rect.h % req->dst_rect.h) {
+				mdp4_stat.err_scale++;
+				pr_err("%s: need integer (h)!\n", __func__);
+				return -ERANGE;
+			}
+		}
+
+		if (req->src_rect.w > (req->dst_rect.w * 4)) {
+			if (req->src_rect.w % req->dst_rect.w) {
+				mdp4_stat.err_scale++;
+				pr_err("%s: need integer (w)!\n", __func__);
+				return -ERANGE;
+			}
+		}
+	}
+
+	if (((req->src_rect.x + req->src_rect.w) > req->src.width) ||
+		((req->src_rect.y + req->src_rect.h) > req->src.height)) {
+		mdp4_stat.err_size++;
+		pr_err("%s invalid src rectangle\n", __func__);
+		return -ERANGE;
+	}
+
+	if (ctrl->panel_3d != MDP4_3D_SIDE_BY_SIDE) {
+		int xres;
+		int yres;
+
+		xres = mfd->panel_info.xres;
+		yres = mfd->panel_info.yres;
+
+		if (((req->dst_rect.x + req->dst_rect.w) > xres) ||
+			((req->dst_rect.y + req->dst_rect.h) > yres)) {
+			mdp4_stat.err_size++;
+			pr_err("%s invalid dst rectangle\n", __func__);
+			return -ERANGE;
+		}
 	}
 
 	ptype = mdp4_overlay_format2type(req->src.format);
-	if (ptype < 0)
+	if (ptype < 0) {
+		pr_err("%s: mdp4_overlay_format2type!\n", __func__);
 		return ptype;
+	}
 
-	if (req->id == MSMFB_NEW_REQUEST) /* new request */
-		pipe = mdp4_overlay_pipe_alloc(ptype, true);
+	if (req->flags & MDP_OV_PIPE_SHARE)
+		ptype = OVERLAY_TYPE_VIDEO; /* VG pipe supports both RGB+YUV */
+
+	if (req->id == MSMFB_NEW_REQUEST)  /* new request */
+		pipe = mdp4_overlay_pipe_alloc(ptype, mixer);
 	else
 		pipe = mdp4_overlay_ndx2pipe(req->id);
 
-	if (pipe == NULL)
+	if (pipe == NULL) {
+		pr_err("%s: pipe == NULL!\n", __func__);
 		return -ENOMEM;
+	}
 
-	/* no down scale at rgb pipe */
-	if (pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
-		if ((req->src_rect.h > req->dst_rect.h) ||
-			(req->src_rect.w > req->dst_rect.w)) {
-				PR_DISP_ERR("mpd_overlay_req2pipe: h>h || w>w!\n");
-				return -ERANGE;
-		}
+	if (!display_iclient && !IS_ERR_OR_NULL(mfd->iclient)) {
+		display_iclient = mfd->iclient;
+		pr_debug("%s(): display_iclient %p\n", __func__,
+			display_iclient);
 	}
 
 	pipe->src_format = req->src.format;
 	ret = mdp4_overlay_format2pipe(pipe);
 
-	if (ret < 0)
+	if (ret < 0) {
+		pr_err("%s: mdp4_overlay_format2pipe!\n", __func__);
 		return ret;
+	}
 
 	/*
 	 * base layer == 1, reserved for frame buffer
@@ -1462,18 +2329,16 @@
 	 * zorder 2 == stage 2 == 4
 	 */
 	if (req->id == MSMFB_NEW_REQUEST) {  /* new request */
-		pd = &ctrl->ov_pipe[pipe->pipe_num];
-		pd->ref_cnt++;
 		pipe->pipe_used++;
 		pipe->mixer_num = mixer;
-		PR_DISP_INFO("mpd4_overlay_req2pipe: zorder=%d pipe_num=%d\n",
-				req->z_order, pipe->pipe_num);
+		pr_debug("%s: zorder=%d pipe ndx=%d num=%d\n", __func__,
+			req->z_order, pipe->pipe_ndx, pipe->pipe_num);
+
 	}
 
 	pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
-
-	pipe->src_width = req->src.width & 0x07ff;	/* source img width */
-	pipe->src_height = req->src.height & 0x07ff;	/* source img height */
+	pipe->src_width = req->src.width & 0x1fff;	/* source img width */
+	pipe->src_height = req->src.height & 0x1fff;	/* source img height */
 	pipe->src_h = req->src_rect.h & 0x07ff;
 	pipe->src_w = req->src_rect.w & 0x07ff;
 	pipe->src_y = req->src_rect.y & 0x07ff;
@@ -1483,9 +2348,6 @@
 	pipe->dst_y = req->dst_rect.y & 0x07ff;
 	pipe->dst_x = req->dst_rect.x & 0x07ff;
 
-	if (mdp4_overlay_parameters_check(pipe))
-		return -ERANGE;
-
 	pipe->op_mode = 0;
 
 	if (req->flags & MDP_FLIP_LR)
@@ -1500,137 +2362,563 @@
 	if (req->flags & MDP_DEINTERLACE)
 		pipe->op_mode |= MDP4_OP_DEINT_EN;
 
+	if (req->flags & MDP_DEINTERLACE_ODD)
+		pipe->op_mode |= MDP4_OP_DEINT_ODD_REF;
+
 	pipe->is_fg = req->is_fg;/* control alpha and color key */
 
 	pipe->alpha = req->alpha & 0x0ff;
 
 	pipe->transp = req->transp_mask;
 
+	pipe->flags = req->flags;
+
 	*ppipe = pipe;
 
 	return 0;
 }
 
-
-static int get_img(struct msmfb_data *img, struct fb_info *info,
-	unsigned long *start, unsigned long *len, struct file **pp_file)
+static int mdp4_calc_pipe_mdp_clk(struct msm_fb_data_type *mfd,
+				  struct mdp4_overlay_pipe *pipe)
 {
-	int put_needed, ret = 0, fb_num;
-	struct file *file;
-#ifdef CONFIG_ANDROID_PMEM
-	unsigned long vstart;
-#endif
+	u32 pclk;
+	u32 xscale, yscale;
+	u32 hsync = 0;
+	u32 shift = 16;
+	u64 rst;
+	int ret = -EINVAL;
 
-#ifdef CONFIG_ANDROID_PMEM
-	if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
+	if (!pipe) {
+		pr_err("%s: pipe is null!\n", __func__);
+		pipe->req_bw = OVERLAY_PERF_LEVEL4;
+		return ret;
+	}
+	if (!mfd) {
+		pr_err("%s: mfd is null!\n", __func__);
+		pipe->req_bw = OVERLAY_PERF_LEVEL4;
+		return ret;
+	}
+
+	/*
+	 * Serveral special cases require the max mdp clk but cannot
+	 * be explained by mdp clk equation.
+	 */
+	if (pipe->flags & MDP_DEINTERLACE) {
+		pr_info("%s deinterlace requires max mdp clk.\n",
+			__func__);
+		pipe->req_clk = mdp_max_clk;
 		return 0;
-#endif
-	file = fget_light(img->memory_id, &put_needed);
-	if (file == NULL)
-		return -1;
+	}
 
-	if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
-		fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
-		if (get_fb_phys_info(start, len, fb_num))
-			ret = -1;
-		else
-			*pp_file = file;
-	} else
-		ret = -1;
-	if (ret)
-		fput_light(file, put_needed);
+	pr_debug("%s: pipe sets: panel res(x,y)=(%d,%d)\n",
+		 __func__,  mfd->panel_info.xres, mfd->panel_info.yres);
+	pr_debug("%s: src(w,h)(%d,%d),src(x,y)(%d,%d)\n",
+		 __func__,  pipe->src_w, pipe->src_h, pipe->src_x, pipe->src_y);
+	pr_debug("%s: dst(w,h)(%d,%d),dst(x,y)(%d,%d)\n",
+		 __func__, pipe->dst_w, pipe->dst_h, pipe->dst_x, pipe->dst_y);
+
+	pclk = (mfd->panel_info.type == MIPI_VIDEO_PANEL ||
+		mfd->panel_info.type == MIPI_CMD_PANEL) ?
+		mfd->panel_info.mipi.dsi_pclk_rate :
+		mfd->panel_info.clk_rate;
+	if (!pclk) {
+		pipe->req_clk = mdp_max_clk;
+		pr_err("%s panel pixel clk is zero!\n", __func__);
+		return ret;
+	}
+	pr_debug("%s: mdp panel pixel clk is %d.\n",
+		 __func__, pclk);
+
+	if (!pipe->dst_h) {
+		pr_err("%s: pipe dst_h is zero!\n", __func__);
+		pipe->req_clk = mdp_max_clk;
+		return ret;
+	}
+
+	if (!pipe->src_h) {
+		pr_err("%s: pipe src_h is zero!\n", __func__);
+		pipe->req_clk = mdp_max_clk;
+		return ret;
+	}
+
+	if (!pipe->dst_w) {
+		pr_err("%s: pipe dst_w is zero!\n", __func__);
+		pipe->req_clk = mdp_max_clk;
+		return ret;
+	}
+
+	if (!pipe->dst_h) {
+		pr_err("%s: pipe dst_h is zero!\n", __func__);
+		pipe->req_clk = mdp_max_clk;
+		return ret;
+	}
+
+	/*
+	 * For the scaling cases, make more margin by removing porch
+	 * values and adding extra 20%.
+	 */
+	if ((pipe->src_h != pipe->dst_h) ||
+	    (pipe->src_w != pipe->dst_w)) {
+		hsync = mfd->panel_info.xres;
+		hsync *= 100;
+		hsync /= 120;
+		pr_debug("%s: panel hsync is %d. with scaling\n",
+			__func__, hsync);
+
+	} else {
+		hsync = mfd->panel_info.lcdc.h_back_porch +
+			mfd->panel_info.lcdc.h_front_porch +
+			mfd->panel_info.lcdc.h_pulse_width +
+			mfd->panel_info.xres;
+		pr_debug("%s: panel hsync is %d.\n",
+			__func__, hsync);
+	}
+
+	if (!hsync) {
+		pipe->req_clk = mdp_max_clk;
+		pr_err("%s: panel hsync is zero!\n", __func__);
+		return 0;
+	}
+
+	xscale = mfd->panel_info.xres;
+	xscale += pipe->src_w;
+
+	if (xscale < pipe->dst_w) {
+		pipe->req_clk = mdp_max_clk;
+		pr_err("%s: xres+src_w cannot be less than dst_w!\n",
+		       __func__);
+		return ret;
+	}
+
+	xscale -= pipe->dst_w;
+	xscale <<= shift;
+	xscale /= hsync;
+	pr_debug("%s: the right %d shifted xscale is %d.\n",
+		 __func__, shift, xscale);
+
+	if (pipe->src_h > pipe->dst_h) {
+		yscale = pipe->src_h;
+		yscale <<= shift;
+		yscale /= pipe->dst_h;
+	} else {		/* upscale */
+		yscale = pipe->dst_h;
+		yscale <<= shift;
+		yscale /= pipe->src_h;
+	}
+
+	yscale *= pipe->src_w;
+	yscale /= hsync;
+
+	pr_debug("%s: the right %d shifted yscale is %d.\n",
+		 __func__, shift, yscale);
+
+	rst = pclk;
+	if (yscale > xscale)
+		rst *= yscale;
+	else
+		rst *= xscale;
+
+	rst >>= shift;
+
+	/*
+	 * If the calculated mdp clk is less than panel pixel clk,
+	 * most likely due to upscaling, mdp clk rate will be set to
+	 * greater than pclk. Now the driver uses 1.15 as the
+	 * factor. Ideally this factor is passed from board file.
+	 */
+	if (rst < pclk) {
+		rst = ((pclk >> shift) * 23 / 20) << shift;
+		pr_debug("%s calculated mdp clk is less than pclk.\n",
+			__func__);
+	}
+
+	pipe->req_clk = (u32) rst;
+
+	pr_debug("%s: required mdp clk %d mixer %d pipe ndx %d\n",
+		 __func__, pipe->req_clk, pipe->mixer_num, pipe->pipe_ndx);
+
+	return 0;
+}
+
+#define OVERLAY_VGA_SIZE	0x04B000
+#define OVERLAY_720P_TILE_SIZE  0x0E6000
+#define OVERLAY_WSVGA_SIZE 0x98000 /* 1024x608, align 600 to 32bit */
+
+#define OVERLAY_BUS_SCALE_TABLE_BASE	6
+
+
+static int mdp4_calc_pipe_mdp_bw(struct msm_fb_data_type *mfd,
+			  struct mdp4_overlay_pipe *pipe)
+{
+	u32 res;
+	int ret = -EINVAL;
+
+	if (!pipe) {
+		pr_err("%s: pipe is null!\n", __func__);
+		return ret;
+	}
+	if (!mfd) {
+		pr_err("%s: mfd is null!\n", __func__);
+		return ret;
+	}
+
+	if (pipe->flags & MDP_DEINTERLACE) {
+		pr_info("%s deinterlace requires max mdp bw.\n",
+			__func__);
+		pipe->req_bw = OVERLAY_PERF_LEVEL1;
+		return 0;
+	}
+
+	if (pipe->pipe_type == OVERLAY_TYPE_BF) {
+		pipe->req_bw = OVERLAY_PERF_LEVEL4;
+		return 0;
+	}
+
+	res = pipe->src_w * pipe->src_h;
+
+	if (res <= OVERLAY_WSVGA_SIZE)
+		pipe->req_bw = OVERLAY_PERF_LEVEL4;
+	else if (res <= OVERLAY_VGA_SIZE)
+		pipe->req_bw = OVERLAY_PERF_LEVEL3;
+	else if (res <= OVERLAY_720P_TILE_SIZE)
+		pipe->req_bw = OVERLAY_PERF_LEVEL2;
+	else
+		pipe->req_bw = OVERLAY_PERF_LEVEL1;
+
+	return 0;
+}
+
+int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd,
+			      struct mdp4_overlay_pipe *plist)
+{
+	u32 worst_mdp_clk = 0;
+	u32 worst_mdp_bw = OVERLAY_PERF_LEVEL4;
+	int i;
+	struct mdp4_overlay_perf *perf_req = &perf_request;
+	struct mdp4_overlay_pipe *pipe = plist;
+	u32 cnt = 0;
+	int ret = -EINVAL;
+
+	if (!mfd) {
+		pr_err("%s: mfd is null!\n", __func__);
+		return ret;
+	}
+
+	if (!plist) {
+		pr_err("%s: plist is null!\n", __func__);
+		return ret;
+	}
+
+	perf_req->use_ov0_blt = 0;
+	perf_req->use_ov1_blt = 0;
+
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+
+		if (!pipe)
+			return ret;
+
+		if (!pipe->pipe_used)
+			continue;
+		cnt++;
+		if (worst_mdp_clk < pipe->req_clk)
+			worst_mdp_clk = pipe->req_clk;
+		if (pipe->req_clk > mdp_max_clk) {
+			if (pipe->mixer_num == MDP4_MIXER0)
+				perf_req->use_ov0_blt = 1;
+			if (pipe->mixer_num == MDP4_MIXER1)
+				perf_req->use_ov1_blt = 1;
+		}
+
+		if (!pipe->req_bw) {
+			pr_err("%s mdp pipe bw request should not be zero!\n",
+			       __func__);
+			pr_debug("%s %d pid %d num %d idx %d mix %d bw %d\n",
+				 __func__, __LINE__, current->pid,
+				 pipe->pipe_num, pipe->pipe_ndx,
+				 pipe->mixer_num, pipe->req_bw);
+			pipe->req_bw = OVERLAY_PERF_LEVEL4;
+		}
+
+		if (pipe->req_bw < worst_mdp_bw)
+			worst_mdp_bw = pipe->req_bw;
+
+		if (mfd->mdp_rev == MDP_REV_41) {
+			/*
+			 * writeback (blt) mode to provide work around
+			 * for dsi cmd mode interface hardware bug.
+			 */
+			if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+				if (pipe->dst_x != 0)
+					perf_req->use_ov0_blt = 1;
+			}
+			if ((mfd->panel_info.xres > 1280) &&
+			    (mfd->panel_info.type != DTV_PANEL)) {
+				perf_req->use_ov0_blt = 1;
+			}
+		}
+	}
+
+	perf_req->mdp_clk_rate = worst_mdp_clk;
+	if (perf_req->mdp_clk_rate > mdp_max_clk)
+		perf_req->mdp_clk_rate = mdp_max_clk;
+
+	perf_req->mdp_clk_rate = mdp_clk_round_rate(perf_req->mdp_clk_rate);
+
+	perf_req->mdp_bw = worst_mdp_bw;
+
+	if (cnt >= 3)
+		perf_req->mdp_bw = OVERLAY_PERF_LEVEL1;
+
+	pr_debug("%s %d pid %d cnt %d clk %d ov0_blt %d, ov1_blt %d bw %d\n",
+		 __func__, __LINE__, current->pid, cnt,
+		 perf_req->mdp_clk_rate,
+		 perf_req->use_ov0_blt,
+		 perf_req->use_ov1_blt,
+		 perf_req->mdp_bw);
+
+	return 0;
+}
+
+int mdp4_overlay_mdp_pipe_req(struct mdp4_overlay_pipe *pipe,
+				  struct msm_fb_data_type *mfd)
+{
+	int ret = 0;
+
+	if (mdp4_calc_pipe_mdp_clk(mfd, pipe)) {
+		pr_err("%s unable to calc mdp pipe clk rate ret=%d\n",
+		       __func__, ret);
+		ret = -EINVAL;
+	}
+	if (mdp4_calc_pipe_mdp_bw(mfd, pipe)) {
+		pr_err("%s unable to calc mdp pipe bandwidth ret=%d\n",
+		       __func__, ret);
+		ret = -EINVAL;
+	}
 	return ret;
 }
 
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-int mdp4_overlay_blt(struct mdp_device *mdp_dev, struct fb_info *info, struct msmfb_overlay_blt *req,
-		struct file **pp_src_file)
+void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd,
+				  int flag)
 {
-	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	int lcdc = 0;
-	ulong addr;
-	addr = get_pmem_id_addr(0);
-	lcdc = mdp_readl(mdp, 0xc0000);
-	if (mfd == NULL)
-		return -ENODEV;
-	if (req->enable) {
-		if (lcdc)
-			mdp4_lcdc_overlay_blt(addr); /* enable */
-		else
-			mdp4_mddi_overlay_blt(addr); /* enable */
-	} else {
-		if (lcdc)
-			mdp4_lcdc_overlay_blt(0); /* disable */
-		else
-			mdp4_mddi_overlay_blt(0); /* disable */
+	struct mdp4_overlay_perf *perf_req = &perf_request;
+	struct mdp4_overlay_perf *perf_cur = &perf_current;
 
-		PR_DISP_INFO("mdp4_overlay_blt: END\n");
+	pr_debug("%s %d: req mdp clk %d, cur mdp clk %d flag %d\n",
+		 __func__, __LINE__,
+		 perf_req->mdp_clk_rate,
+		 perf_cur->mdp_clk_rate,
+		 flag);
+
+	if (!mdp4_extn_disp)
+		perf_cur->use_ov1_blt = 0;
+
+	if (flag) {
+		if (perf_req->mdp_clk_rate > perf_cur->mdp_clk_rate) {
+			mdp_set_core_clk(perf_req->mdp_clk_rate);
+			pr_info("%s mdp clk is changed [%d] from %d to %d\n",
+				__func__,
+				flag,
+				perf_cur->mdp_clk_rate,
+				perf_req->mdp_clk_rate);
+			perf_cur->mdp_clk_rate =
+				perf_req->mdp_clk_rate;
+		}
+		if (perf_req->mdp_bw < perf_cur->mdp_bw) {
+			mdp_bus_scale_update_request
+				(OVERLAY_BUS_SCALE_TABLE_BASE -
+				 perf_req->mdp_bw);
+			pr_info("%s mdp bw is changed [%d] from %d to %d\n",
+				__func__,
+				flag,
+				perf_cur->mdp_bw,
+				perf_req->mdp_bw);
+			perf_cur->mdp_bw = perf_req->mdp_bw;
+		}
+		if (mfd->panel_info.pdest == DISPLAY_1 &&
+		    perf_req->use_ov0_blt && !perf_cur->use_ov0_blt) {
+			if (mfd->panel_info.type == LCDC_PANEL ||
+			    mfd->panel_info.type == LVDS_PANEL)
+				mdp4_lcdc_overlay_blt_start(mfd);
+			else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
+				mdp4_dsi_video_blt_start(mfd);
+			else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+				mdp4_dsi_cmd_blt_start(mfd);
+			pr_info("%s mixer0 start blt [%d] from %d to %d.\n",
+				__func__,
+				flag,
+				perf_cur->use_ov0_blt,
+				perf_req->use_ov0_blt);
+			perf_cur->use_ov0_blt = perf_req->use_ov0_blt;
+		}
+		if (mfd->panel_info.pdest == DISPLAY_2 &&
+		    perf_req->use_ov1_blt && !perf_cur->use_ov1_blt) {
+			mdp4_dtv_overlay_blt_start(mfd);
+			pr_info("%s mixer1 start blt [%d] from %d to %d.\n",
+				__func__,
+				flag,
+				perf_cur->use_ov1_blt,
+				perf_req->use_ov1_blt);
+			perf_cur->use_ov1_blt = perf_req->use_ov1_blt;
+		}
+	} else {
+		if (perf_req->mdp_clk_rate < perf_cur->mdp_clk_rate) {
+			pr_info("%s mdp clk is changed [%d] from %d to %d\n",
+				__func__,
+				flag,
+				perf_cur->mdp_clk_rate,
+				perf_req->mdp_clk_rate);
+			mdp_set_core_clk(perf_req->mdp_clk_rate);
+			perf_cur->mdp_clk_rate =
+				perf_req->mdp_clk_rate;
+		}
+		if (perf_req->mdp_bw > perf_cur->mdp_bw) {
+			pr_info("%s mdp bw is changed [%d] from %d to %d\n",
+				__func__,
+				flag,
+				perf_cur->mdp_bw,
+				perf_req->mdp_bw);
+			mdp_bus_scale_update_request
+				(OVERLAY_BUS_SCALE_TABLE_BASE -
+				 perf_req->mdp_bw);
+			perf_cur->mdp_bw = perf_req->mdp_bw;
+		}
+		if (mfd->panel_info.pdest == DISPLAY_1 &&
+		    !perf_req->use_ov0_blt && perf_cur->use_ov0_blt) {
+			if (mfd->panel_info.type == LCDC_PANEL ||
+			    mfd->panel_info.type == LVDS_PANEL)
+				mdp4_lcdc_overlay_blt_stop(mfd);
+			else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
+				mdp4_dsi_video_blt_stop(mfd);
+			else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+				mdp4_dsi_cmd_blt_stop(mfd);
+			pr_info("%s mixer0 stop blt [%d] from %d to %d.\n",
+				__func__,
+				flag,
+				perf_cur->use_ov0_blt,
+				perf_req->use_ov0_blt);
+			perf_cur->use_ov0_blt = perf_req->use_ov0_blt;
+		}
+		if (mfd->panel_info.pdest == DISPLAY_2 &&
+		    !perf_req->use_ov1_blt && perf_cur->use_ov1_blt) {
+			mdp4_dtv_overlay_blt_stop(mfd);
+			pr_info("%s mixer1 stop blt [%d] from %d to %d.\n",
+				__func__,
+				flag,
+				perf_cur->use_ov1_blt,
+				perf_req->use_ov1_blt);
+			perf_cur->use_ov1_blt = perf_req->use_ov1_blt;
+		}
+	}
+	return;
+}
+
+static int get_img(struct msmfb_data *img, struct fb_info *info,
+	struct mdp4_overlay_pipe *pipe, unsigned int plane,
+	unsigned long *start, unsigned long *len, struct file **srcp_file,
+	int *p_need, struct ion_handle **srcp_ihdl)
+{
+	struct file *file;
+	int put_needed, ret = 0, fb_num;
+#ifdef CONFIG_ANDROID_PMEM
+	unsigned long vstart;
+#endif
+	*p_need = 0;
+
+	if (img->flags & MDP_BLIT_SRC_GEM) {
+		*srcp_file = NULL;
+		return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
+					 start, len);
 	}
 
-	return 0;
+	if (img->flags & MDP_MEMORY_ID_TYPE_FB) {
+		file = fget_light(img->memory_id, &put_needed);
+		if (file == NULL)
+			return -EINVAL;
+
+		if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
+			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
+			if (get_fb_phys_info(start, len, fb_num,
+				DISPLAY_SUBSYSTEM_ID)) {
+				ret = -1;
+			} else {
+				pr_warn("%s: mdp4_overlay play with FB memory\n",
+							 __func__);
+				*srcp_file = file;
+				*p_need = put_needed;
+			}
+		} else
+			ret = -1;
+		if (ret)
+			fput_light(file, put_needed);
+		return ret;
+	}
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	return mdp4_overlay_iommu_map_buf(img->memory_id, pipe, plane,
+		start, len, srcp_ihdl);
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+	if (!get_pmem_file(img->memory_id, start, &vstart,
+					    len, srcp_file))
+		return 0;
+	else
+		return -EINVAL;
+#endif
+}
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	int ret = -EPERM;
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
+		return -EINTR;
+
+	if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+		mdp4_dsi_cmd_3d_sbys(mfd, req);
+		ret = 0;
+	} else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
+		mdp4_dsi_video_3d_sbys(mfd, req);
+		ret = 0;
+	}
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	return ret;
+}
+#else
+int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
+{
+	/* do nothing */
+	return -EPERM;
 }
 #endif
 
-int mdp4_overlay_change_z_order_vg_pipes(struct fb_info *info)
+int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req)
 {
-	struct mdp4_overlay_pipe *pipeS1, *pipeS2;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
 
-	pipeS1 = &ctrl->plist[4];	/* ndx start from 1 */
-	pipeS2 = &ctrl->plist[5];	/* ndx start from 1 */
-
-	if (ctrl->stage[pipeS1->mixer_num][pipeS1->mixer_stage] == NULL ||
-		ctrl->stage[pipeS2->mixer_num][pipeS2->mixer_stage] == NULL) {
-		PR_DISP_ERR("mdp4_overlay_change_z_order_vg_pipes: less than two VG pipes are active \n");
-		z_order_change = 0;
+	if (mfd == NULL)
 		return -ENODEV;
-	} else {
-		z_order_change = 1;
-	}
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
+		return -EINTR;
+
+	if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+		mdp4_dsi_cmd_overlay_blt(mfd, req);
+	else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
+		mdp4_dsi_video_overlay_blt(mfd, req);
+	else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+		mdp4_lcdc_overlay_blt(mfd, req);
+	else if (ctrl->panel_mode & MDP4_PANEL_MDDI)
+		mdp4_mddi_overlay_blt(mfd, req);
+
+	mutex_unlock(&mfd->dma->ov_mutex);
+
 	return 0;
 }
 
-static int mdp4_overlay_change_z_order_vg_pipes_actual(struct mdp4_overlay_pipe *pipe)
-{
-	int data;
-	int pipe1 = 0, pipe2 = 0;
-	int temp;
-	struct mdp4_overlay_pipe *pipeS1, *pipeS2;
-
-	pipeS1 = &ctrl->plist[4];	/* ndx start from 1 */
-	pipeS2 = &ctrl->plist[5];	/* ndx start from 1 */
-
-	z_order_change = 0;
-	if (ctrl->stage[pipeS1->mixer_num][pipeS1->mixer_stage] == NULL ||
-		ctrl->stage[pipeS2->mixer_num][pipeS2->mixer_stage] == NULL) {
-		PR_DISP_ERR("mdp4_overlay_change_z_order_vg_pipes: less than two VG pipes are active \n");
-		mdp4_mixer_stage_up(pipe);
-		return -ENODEV;
-	}
-
-	temp = pipeS1->mixer_stage;
-	pipeS1->mixer_stage = pipeS2->mixer_stage;
-	pipeS2->mixer_stage = temp;
-
-	pipeS1->req_data.z_order = pipeS1->mixer_stage - MDP4_MIXER_STAGE0;
-	pipeS2->req_data.z_order = pipeS2->mixer_stage - MDP4_MIXER_STAGE0;
-
-	PR_DISP_INFO("mdp4_overlay_change_z_order_vg_pipes\n");
-	data = mdp_readl(pipeS1->mdp, 0x10100);
-	PR_DISP_INFO("mdp4_overlay_change_z_order_vg_pipes data = 0x%x\n", data);
-	pipe1 = (data & 0xf) << 4;
-	PR_DISP_INFO("mdp4_overlay_change_z_order_vg_pipes pipe1 = 0x%x\n", pipe1);
-	pipe2 = (data & 0xf0) >> 4;
-	PR_DISP_INFO("mdp4_overlay_change_z_order_vg_pipes pipe2 = 0x%x\n", pipe2);
-	data &= 0xffffff00;
-	data |= pipe1;
-	data |= pipe2;
-	PR_DISP_INFO("mdp4_overlay_change_z_order_vg_pipes data = 0x%x\n", data);
-	mdp_writel(pipeS1->mdp, data, 0x10100);
-	return 0;
- }
-
-int mdp4_overlay_get(struct mdp_device *mdp_dev, struct fb_info *info, struct mdp_overlay *req)
+int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
 {
 	struct mdp4_overlay_pipe *pipe;
 
@@ -1640,174 +2928,223 @@
 
 	*req = pipe->req_data;
 
+	if (mdp4_overlay_borderfill_supported())
+		req->flags |= MDP_BORDERFILL_SUPPORTED;
+
 	return 0;
 }
 
-
-static int mdp4_pull_mode(struct mdp4_overlay_pipe *pipe)
+int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
 {
-	uint32_t lcdc;
-	if (pipe->mixer_num == MDP4_MIXER1) { /* DTV */
-		lcdc = mdp_readl(pipe->mdp, 0xd0000);
-		lcdc &= 0x01;
-	} else {           /* LCDC */
-		lcdc = mdp_readl(pipe->mdp, 0x0038);
-		lcdc &= 0x08;
-	}
-	return lcdc;
-}
-
-#ifdef CONFIG_MACH_VISION
-/* Temporary workaround before QCT release formal fix. */
-int mdp4_overlay_alter_req(struct mdp_overlay *req)
-{
-	if (req->src.format == MDP_Y_CRCB_H2V2 &&
-			req->src.width == 1280 && req->src.height == 720 &&
-			req->dst_rect.w == 480) {
-		pr_info("%s: alter req due to down-scaling issue of 720p.",
-				__func__);
-		req->src_rect.x = 60;
-		req->src_rect.y = 90;
-		req->src_rect.w = 960;
-		req->src_rect.h = 540;
-	}
-	return 0;
-}
-#endif
-
-void mdp4_dump_ov(struct mdp_overlay *ov);
-
-int mdp4_overlay_set(struct mdp_device *mdp_dev, struct fb_info *info, struct mdp_overlay *req)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
 	int ret, mixer;
 	struct mdp4_overlay_pipe *pipe;
-	int lcdc, mddi = 0;
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	unsigned long irq_flags = 0;
-#endif
-	if (req->src.format == MDP_FB_FORMAT)
-		req->src.format = MDP_RGB_565; /* mfd->fb_imgType; */
 
-#ifdef DEBUG_OVERLAY
-	mdp4_dump_ov(req);
-#endif
-
-#ifdef CONFIG_MACH_VISION
-	mdp4_overlay_alter_req(req);
-#endif
-
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	if (mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
-		panel_icm->force_leave();
-		spin_lock_irqsave(&panel_icm->lock, irq_flags);
-		panel_icm->panel_update = 1;
-		spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
-		wake_up(&panel_update_wait_queue);
-		mutex_lock(&panel_icm->icm_lock);
-		panel_icm->icm_doable = false;
-		mutex_unlock(&panel_icm->icm_lock);
+	if (mfd == NULL) {
+		pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
+		return -ENODEV;
 	}
-#endif
 
-	mixer = info->node; /* minor number of char device */
+	if (info->node != 0 || mfd->cont_splash_done)	/* primary */
+		if (!mfd->panel_power_on)		/* suspended */
+			return -EPERM;
 
-	ret = mdp4_overlay_req2pipe(req, mixer, &pipe);
-	if (ret < 0)
+	if (req->src.format == MDP_FB_FORMAT)
+		req->src.format = mfd->fb_imgType;
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex)) {
+		pr_err("%s: mutex_lock_interruptible, -EINTR\n", __func__);
+		return -EINTR;
+	}
+
+	mixer = mfd->panel_info.pdest;	/* DISPLAY_1 or DISPLAY_2 */
+
+	ret = mdp4_overlay_req2pipe(req, mixer, &pipe, mfd);
+
+	if (ret < 0) {
+		mutex_unlock(&mfd->dma->ov_mutex);
+		pr_err("%s: mdp4_overlay_req2pipe, ret=%d\n", __func__, ret);
 		return ret;
-
-	pipe->mdp = mdp;
+	}
 
 	/* return id back to user */
 	req->id = pipe->pipe_ndx;	/* pipe_ndx start from 1 */
 	pipe->req_data = *req;		/* keep original req */
 
-	if (req->user_data[OVERLAY_UPDATE_SCREEN] == OVERLAY_UPDATE_SCREEN_EN
-		&& pipe->srcp0_addr) {
-		clk_enable(mdp->clk);
-		if (pipe->pipe_num >= OVERLAY_PIPE_VG1)
-			mdp4_overlay_vg_setup(pipe);	/* video/graphic pipe */
-		else
-			mdp4_overlay_rgb_setup(pipe);	/* rgb pipe */
-
-		pipe->req_data.user_data[OVERLAY_UPDATE_SCREEN] = OVERLAY_UPDATE_SCREEN_DIS;
-
-		mdp4_mixer_blend_setup(pipe);
-		mdp4_mixer_stage_up(pipe);
-
-		lcdc = mdp_readl(mdp, 0xc0000);
-		if (lcdc) /* LCDC mode */
-			mdp4_overlay_reg_flush(pipe, 1);
-		clk_disable(mdp->clk);
+	if (!IS_ERR_OR_NULL(mfd->iclient)) {
+		pr_debug("pipe->flags 0x%x\n", pipe->flags);
+		if (pipe->flags & MDP_SECURE_OVERLAY_SESSION) {
+			mfd->mem_hid &= ~BIT(ION_IOMMU_HEAP_ID);
+			mfd->mem_hid |= ION_SECURE;
+		} else {
+			mfd->mem_hid |= BIT(ION_IOMMU_HEAP_ID);
+			mfd->mem_hid &= ~ION_SECURE;
+		}
 	}
 
-	mddi = mdp_readl(pipe->mdp, 0x0038);
-	mddi &= 0x02;
-	if (mddi) {
-		if (mdp->hw_version == MDP4_REVISION_V2_1 &&
+	if (pipe->flags & MDP_SHARPENING) {
+		bool test = ((pipe->req_data.dpp.sharp_strength > 0) &&
+			((req->src_rect.w > req->dst_rect.w) &&
+			 (req->src_rect.h > req->dst_rect.h)));
+		if (test) {
+			pr_debug("%s: No sharpening while downscaling.\n",
+								__func__);
+			pipe->flags &= ~MDP_SHARPENING;
+		}
+	}
+
+	/* precompute HSIC matrices */
+	if (req->flags & MDP_DPP_HSIC)
+		mdp4_hsic_set(pipe, &(req->dpp));
+
+	mdp4_stat.overlay_set[pipe->mixer_num]++;
+
+	if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
+		if (mdp_hw_revision == MDP4_REVISION_V2_1 &&
 			pipe->mixer_num == MDP4_MIXER0)
 			mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_SET, true);
-			/* clean the UNSET flag to false */
-			mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_UNSET, false);
 	}
+
+	mdp4_overlay_mdp_pipe_req(pipe, mfd);
+
+	mutex_unlock(&mfd->dma->ov_mutex);
+
 	return 0;
 }
 
-int mdp4_overlay_unset(struct mdp_device *mdp_dev, struct fb_info *info, int ndx)
+int mdp4_overlay_unset_mixer(int mixer)
 {
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
 	struct mdp4_overlay_pipe *pipe;
-	int pull;
+	int i, cnt = 0;
+
+	/* free pipe besides base layer pipe */
+	for (i = MDP4_MIXER_STAGE3; i > MDP4_MIXER_STAGE_BASE; i--) {
+		pipe = ctrl->stage[mixer][i];
+		if (pipe == NULL)
+			continue;
+		pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
+		mdp4_overlay_reg_flush(pipe, 1);
+		mdp4_mixer_stage_down(pipe);
+		mdp4_overlay_pipe_free(pipe);
+		cnt++;
+	}
+
+	return cnt;
+}
+
+int mdp4_overlay_unset(struct fb_info *info, int ndx)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct mdp4_overlay_pipe *pipe;
+	struct dpp_ctrl dpp;
+	int i;
+
+	if (mfd == NULL)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
+		return -EINTR;
 
 	pipe = mdp4_overlay_ndx2pipe(ndx);
 
-	if (pipe == NULL)
+	if (pipe == NULL) {
+		mutex_unlock(&mfd->dma->ov_mutex);
 		return -ENODEV;
+	}
 
-	pipe->mdp = mdp;
-	clk_enable(mdp->clk);
+	if (pipe->pipe_type == OVERLAY_TYPE_BF) {
+		mdp4_overlay_borderfill_stage_down(pipe);
+		mutex_unlock(&mfd->dma->ov_mutex);
+		return 0;
+	}
 
-	pull = mdp4_pull_mode(pipe);
-
+	if (pipe->mixer_num == MDP4_MIXER2)
+		ctrl->mixer2_played = 0;
+	else if (pipe->mixer_num == MDP4_MIXER1)
+		ctrl->mixer1_played = 0;
+	else {
+		/* mixer 0 */
+		ctrl->mixer0_played = 0;
+		if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
+			if (mfd->panel_power_on)
+				mdp4_mddi_blt_dmap_busy_wait(mfd);
+		}
+	}
+	mdp4_overlay_reg_flush(pipe, 1);
 	mdp4_mixer_stage_down(pipe);
 
-	if (pull) /* LCDC or DTV mode */
-		mdp4_overlay_reg_flush(pipe, 0);
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-	else
-		mdp4_overlay0_done_mddi();
-#endif
+	if (pipe->mixer_num == MDP4_MIXER0) {
+		if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
+			if (mfd->panel_power_on)
+				mdp4_mddi_overlay_restore();
+		}
+	} else {	/* mixer1, DTV, ATV */
+		if (ctrl->panel_mode & MDP4_PANEL_DTV)
+			mdp4_overlay_dtv_unset(mfd, pipe);
+	}
+
+	/* Reset any HSIC settings to default */
+	if (pipe->flags & MDP_DPP_HSIC) {
+		for (i = 0; i < NUM_HSIC_PARAM; i++)
+			dpp.hsic_params[i] = 0;
+
+		mdp4_hsic_set(pipe, &dpp);
+		mdp4_hsic_update(pipe);
+	}
+
+	mdp4_stat.overlay_unset[pipe->mixer_num]++;
 
 	mdp4_overlay_pipe_free(pipe);
-
-	if (!(ctrl->ov_pipe[OVERLAY_PIPE_VG1].ref_cnt +
-		ctrl->ov_pipe[OVERLAY_PIPE_VG2].ref_cnt)) {
-		if ((pipe->mixer_num == MDP4_MIXER0) &&
-			(mdp->hw_version == MDP4_REVISION_V2_1))
-			mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_UNSET, true);
-			/* clean the SET flag to false */
-			mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_SET, false);
-	}
-
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	if (mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
-		mutex_lock(&panel_icm->icm_lock);
-		if (panel_icm->icm_suspend == false)
-			panel_icm->icm_doable = true;
-		mutex_unlock(&panel_icm->icm_lock);
-	}
-#endif
-
-	clk_disable(mdp->clk);
+	mutex_unlock(&mfd->dma->ov_mutex);
 
 	return 0;
 }
 
+int mdp4_overlay_wait4vsync(struct fb_info *info, long long *vtime)
+{
+	if (!hdmi_prim_display && info->node == 0) {
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
+			mdp4_dsi_video_wait4vsync(0, vtime);
+		else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+			mdp4_dsi_cmd_wait4vsync(0, vtime);
+		else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+			mdp4_lcdc_wait4vsync(0, vtime);
+	} else if (hdmi_prim_display || info->node == 1) {
+		mdp4_dtv_wait4vsync(0, vtime);
+	}
+
+	return 0;
+}
+
+int mdp4_overlay_vsync_ctrl(struct fb_info *info, int enable)
+{
+	int cmd;
+
+	if (enable)
+		cmd = 1;
+	else
+		cmd = 0;
+
+	if (!hdmi_prim_display && info->node == 0) {
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
+			mdp4_dsi_video_vsync_ctrl(0, cmd);
+		else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+			mdp4_dsi_cmd_vsync_ctrl(0, cmd);
+		else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+			mdp4_lcdc_vsync_ctrl(0, cmd);
+	} else if (hdmi_prim_display || info->node == 1) {
+		mdp4_dtv_vsync_ctrl(0, cmd);
+	}
+
+	return 0;
+}
+
+
 struct tile_desc {
-	uint32_t width;  /* tile's width */
-	uint32_t height; /* tile's height */
-	uint32_t row_tile_w; /* tiles per row's width */
-	uint32_t row_tile_h; /* tiles per row's height */
+	uint32 width;  /* tile's width */
+	uint32 height; /* tile's height */
+	uint32 row_tile_w; /* tiles per row's width */
+	uint32 row_tile_h; /* tiles per row's height */
 };
 
 void tile_samsung(struct tile_desc *tp)
@@ -1825,10 +3162,10 @@
 	tp->row_tile_h = 1;	/* 1 tiles per row's height */
 }
 
-uint32_t tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
+uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
 {
-	uint32_t tile_w, tile_h;
-	uint32_t row_num_w, row_num_h;
+	uint32 tile_w, tile_h;
+	uint32 row_num_w, row_num_h;
 
 
 	tile_w = tp->width * tp->row_tile_w;
@@ -1839,136 +3176,117 @@
 	return ((row_num_w * row_num_h * tile_w * tile_h) + 8191) & ~8191;
 }
 
-#ifdef DEBUG_OVERLAY
-
-static char     snapshot_filename[2048];
-static bool	is_demanding_snapshot = false;
-static		DEFINE_MUTEX(snapshot_lock);
-
-/*
-TODO: file header to brife the image content
-*/
-int mdp4_overlay_snapshot(struct msmfb_overlay_data *req, uint32_t phy_addr,
-	int w, int h, int bpp, char *filename)
+int mdp4_overlay_play_wait(struct fb_info *info, struct msmfb_overlay_data *req)
 {
-	int retval, size;
-	uint8_t *vir_addr;
-	struct file *dstf;
-	mm_segment_t orgfs;
-
-	/* Save FS register and set FS register to kernel space, needed
-	 * for read and write to accept buffer in kernel space.
-	 */
-	orgfs = get_fs();
-	set_fs(KERNEL_DS);
-
-	dstf = filp_open(filename, O_WRONLY | O_TRUNC | O_CREAT , 0644);
-	if (IS_ERR(dstf)) {
-		pr_err("%s: Error %ld opening %s\n", __func__,
-				-PTR_ERR(dstf), filename);
-		is_demanding_snapshot = false;
-		return -EIO;
-	}
-
-	if (!(dstf->f_op && dstf->f_op->write)) {
-		pr_err("file doesn't have a write method\n");
-		return -EFAULT;
-	}
-
-	size = w * h * bpp;
-	vir_addr = (uint8_t *)ioremap(phy_addr, size);
-	pr_info("%s: w=%d, h=%d, size=%d, vir=%08x\n", __func__,
-		w, h, size, (uint32_t)vir_addr);
-	retval = dstf->f_op->write(dstf, vir_addr, size, &dstf->f_pos);
-	iounmap(vir_addr);
-
-	retval = filp_close(dstf, NULL);
-	if (retval)
-		pr_err("%s: Error %d closing %s\n", __func__,
-			-retval, filename);
-
-	set_fs(orgfs);
-	is_demanding_snapshot = false;
-
 	return 0;
 }
-#endif
 
-int mdp4_overlay_play(struct mdp_device *mdp_dev, struct fb_info *info, struct msmfb_overlay_data *req,
-		struct file **pp_src_file)
+/*
+ * mdp4_overlay_dma_commit: called from dma_done isr
+ * No mutex/sleep allowed
+ */
+void mdp4_overlay_dma_commit(int mixer)
 {
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	struct msmfb_info *msmfb = (struct msmfb_info *)info->par;
-	struct msm_panel_data *panel = msmfb->panel;
+	/*
+	* non double buffer register update here
+	* perf level, new clock rate should be done here
+	*/
+}
+
+/*
+ * mdp4_overlay_vsync_commit: called from tasklet context
+ * No mutex/sleep allowed
+ */
+void mdp4_overlay_vsync_commit(struct mdp4_overlay_pipe *pipe)
+{
+	if (pipe->pipe_type == OVERLAY_TYPE_VIDEO)
+		mdp4_overlay_vg_setup(pipe);	/* video/graphic pipe */
+	else
+		mdp4_overlay_rgb_setup(pipe);	/* rgb pipe */
+
+	pr_debug("%s: pipe=%x ndx=%d num=%d used=%d\n", __func__,
+		(int) pipe, pipe->pipe_ndx, pipe->pipe_num, pipe->pipe_used);
+	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
+}
+
+int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
 	struct msmfb_data *img;
 	struct mdp4_overlay_pipe *pipe;
-	struct mdp4_pipe_desc *pd;
 	ulong start, addr;
 	ulong len = 0;
-	struct file *p_src_file = 0;
-	int pull;
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	unsigned long irq_flags = 0;
-#endif
+	struct file *srcp0_file = NULL;
+	struct file *srcp1_file = NULL, *srcp2_file = NULL;
+	struct ion_handle *srcp0_ihdl = NULL;
+	struct ion_handle *srcp1_ihdl = NULL, *srcp2_ihdl = NULL;
+	int ps0_need, p_need;
+	uint32_t overlay_version = 0;
+	int ret = 0;
 
-	pipe = mdp4_overlay_ndx2pipe(req->id);
-	if (pipe == NULL)
+	if (mfd == NULL)
 		return -ENODEV;
 
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	if (mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
-		panel_icm->force_leave();
-		spin_lock_irqsave(&panel_icm->lock, irq_flags);
-		panel_icm->panel_update = 1;
-		spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
-		wake_up(&panel_update_wait_queue);
-	}
-#endif
+	if (!mfd->panel_power_on) /* suspended */
+		return -EPERM;
 
-	pd = &ctrl->ov_pipe[pipe->pipe_num];
-	if (pd->player && pipe != pd->player) {
-		if (pipe->pipe_type == OVERLAY_TYPE_RGB)
-			return 0; /* ignore it, kicked out already */
+	pipe = mdp4_overlay_ndx2pipe(req->id);
+	if (pipe == NULL) {
+		mdp4_stat.err_play++;
+		return -ENODEV;
 	}
 
-	pd->player = pipe;      /* keep */
+	if (pipe->pipe_type == OVERLAY_TYPE_BF) {
+		mdp4_overlay_borderfill_stage_up(pipe);
+		mdp4_mixer_stage_commit(pipe->mixer_num);
+		return 0;
+	}
+
+	mutex_lock(&mfd->dma->ov_mutex);
 
 	img = &req->data;
-	get_img(img, info, &start, &len, &p_src_file);
+	get_img(img, info, pipe, 0, &start, &len, &srcp0_file,
+		&ps0_need, &srcp0_ihdl);
 	if (len == 0) {
-		PR_DISP_ERR("mdp_overlay_play: could not retrieve"
-				       " image from memory\n");
-		return -1;
+		pr_err("%s: pmem Error\n", __func__);
+		ret = -1;
+		goto end;
 	}
-	*pp_src_file = p_src_file;
 
 	addr = start + img->offset;
 	pipe->srcp0_addr = addr;
 	pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
-	pipe->mdp = mdp;
 
-#ifdef DEBUG_OVERLAY
-	mutex_lock(&snapshot_lock);
-	if (is_demanding_snapshot) {
-		mdp4_overlay_snapshot(req, addr, pipe->src_width,
-			pipe->src_height, pipe->bpp, snapshot_filename);
-	}
-	mutex_unlock(&snapshot_lock);
-#endif
 
-	clk_set_rate(mdp->ebi1_clk, 153000000);
-	clk_enable(mdp->clk);
+	pr_debug("%s: mixer=%d ndx=%x addr=%x flags=%x pid=%d\n", __func__,
+		pipe->mixer_num, pipe->pipe_ndx, (int)addr, pipe->flags,
+							current->pid);
+
+	if ((req->version_key & VERSION_KEY_MASK) == 0xF9E8D700)
+		overlay_version = (req->version_key & ~VERSION_KEY_MASK);
 
 	if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
-		if (pipe->frame_format == MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
+		if (overlay_version > 0) {
+			img = &req->plane1_data;
+			get_img(img, info, pipe, 1, &start, &len, &srcp1_file,
+				&p_need, &srcp1_ihdl);
+			if (len == 0) {
+				pr_err("%s: Error to get plane1\n", __func__);
+				ret = -EINVAL;
+				goto end;
+			}
+			pipe->srcp1_addr = start + img->offset;
+		} else if (pipe->frame_format ==
+				MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
 			struct tile_desc tile;
 
 			tile_samsung(&tile);
 			pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile);
-		} else
-			pipe->srcp1_addr = addr +
-					pipe->src_width * pipe->src_height;
-
+		} else {
+			pipe->srcp1_addr = addr + (pipe->src_width *
+						pipe->src_height);
+		}
 		pipe->srcp0_ystride = pipe->src_width;
 		if ((pipe->src_format == MDP_Y_CRCB_H1V1) ||
 			(pipe->src_format == MDP_Y_CBCR_H1V1)) {
@@ -1978,193 +3296,341 @@
 				pipe->srcp1_ystride = pipe->src_width << 1;
 		} else
 			pipe->srcp1_ystride = pipe->src_width;
-	}
 
-	if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
-		int ret = 0;
-		ret = mdp4_overlay_vg_setup(pipe);/* video/graphic pipe */
-		if (ret) {
-			clk_disable(mdp->clk);
-			mod_timer(&mdp->standby_timer,
-				jiffies + msecs_to_jiffies(1000));
-			return ret;
+	} else if (pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
+		if (overlay_version > 0) {
+			img = &req->plane1_data;
+			get_img(img, info, pipe, 1, &start, &len, &srcp1_file,
+				&p_need, &srcp1_ihdl);
+			if (len == 0) {
+				pr_err("%s: Error to get plane1\n", __func__);
+				ret = -EINVAL;
+				goto end;
+			}
+			pipe->srcp1_addr = start + img->offset;
+
+			img = &req->plane2_data;
+			get_img(img, info, pipe, 2, &start, &len, &srcp2_file,
+				&p_need, &srcp2_ihdl);
+			if (len == 0) {
+				pr_err("%s: Error to get plane2\n", __func__);
+				ret = -EINVAL;
+				goto end;
+			}
+			pipe->srcp2_addr = start + img->offset;
+		} else {
+			if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
+				addr += (ALIGN(pipe->src_width, 16) *
+					pipe->src_height);
+				pipe->srcp1_addr = addr;
+				addr += ((ALIGN((pipe->src_width / 2), 16)) *
+					(pipe->src_height / 2));
+				pipe->srcp2_addr = addr;
+			} else {
+				addr += (pipe->src_width * pipe->src_height);
+				pipe->srcp1_addr = addr;
+				addr += ((pipe->src_width / 2) *
+					(pipe->src_height / 2));
+				pipe->srcp2_addr = addr;
+			}
 		}
-	} else
-		mdp4_overlay_rgb_setup(pipe);	/* rgb pipe */
+		/* mdp planar format expects Cb in srcp1 and Cr in p2 */
+		if ((pipe->src_format == MDP_Y_CR_CB_H2V2) ||
+			(pipe->src_format == MDP_Y_CR_CB_GH2V2))
+			swap(pipe->srcp1_addr, pipe->srcp2_addr);
 
-	mdp4_mixer_blend_setup(pipe);
-	if (z_order_change == 1)
-		mdp4_overlay_change_z_order_vg_pipes_actual(pipe);
-	else
-		mdp4_mixer_stage_up(pipe);
-
-	pull = mdp4_pull_mode(pipe);
-
-
-	if (pull) {	/* LCDC or DTV mode */
-		mdp4_overlay_reg_flush(pipe, 1);
-		if (pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) { /* done */
-			clk_disable(mdp->clk);
-			mod_timer(&mdp->standby_timer,
-				jiffies + msecs_to_jiffies(1000));
-			return 0;
+		if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
+			pipe->srcp0_ystride = ALIGN(pipe->src_width, 16);
+			pipe->srcp1_ystride = ALIGN(pipe->src_width / 2, 16);
+			pipe->srcp2_ystride = ALIGN(pipe->src_width / 2, 16);
+		} else {
+			pipe->srcp0_ystride = pipe->src_width;
+			pipe->srcp1_ystride = pipe->src_width / 2;
+			pipe->srcp2_ystride = pipe->src_width / 2;
 		}
-	} else
-		mdp_dev->dma_wait(mdp_dev, panel->interface_type);
-
-	clk_disable(mdp->clk);
-	mod_timer(&mdp->standby_timer,
-		jiffies + msecs_to_jiffies(1000));
-
-	return 0;
-}
-
-/*---------------------------------------------------------------------------*/
-#ifdef DEBUG_OVERLAY
-static char     debug_buf[2048];
-int ov_dump_req(struct mdp_overlay *ov, char *buff)
-{
-	int len = 0;
-	char *bp = buff;
-	struct mdp_rect *r;
-	uint32_t *p = ov->user_data;
-
-	len = snprintf(buff, sizeof(debug_buf),
-		"[OV]src: width=%d, height=%d, format=%d\n",
-		ov->src.width, ov->src.height, ov->src.format);
-	r = &ov->src_rect;
-	bp += len;
-	len = snprintf(bp, sizeof(debug_buf),
-		"[OV]src_rect: x=%d, y=%d, w=%d, h=%d\n",
-		r->x, r->y, r->w, r->h);
-	r = &ov->dst_rect;
-	bp += len;
-	len = snprintf(bp, sizeof(debug_buf),
-		"[OV]dst_rect: x=%d, y=%d, w=%d, h=%d\n",
-		r->x, r->y, r->w, r->h);
-	bp += len;
-	len = snprintf(bp, sizeof(debug_buf),
-		"[OV]z_order=%d, is_fg=%d, alpha=0x%08x\n",
-		ov->z_order, ov->is_fg, ov->alpha);
-	bp += len;
-	len = snprintf(bp, sizeof(debug_buf),
-		"[OV]transp_mask=0x%08x, flags=0x%08x, id=%d\n",
-		ov->transp_mask, ov->flags, ov->id);
-	bp += len;
-	len = snprintf(bp, sizeof(debug_buf),
-		"[OV]user_data={%08x, %08x, %08x, %08x,\n"
-		"[OV]\t%08x, %08x, %08x, %08x}\n",
-		p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
-
-	return (bp - buff + len);
-}
-
-static int ov_requests_open(struct inode *inode, struct file *file)
-{
-	/* non-seekable */
-	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
-	return 0;
-}
-
-static int ov_requests_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static ssize_t ov_requests_read(struct file *file, char __user *buff,
-		size_t count, loff_t *ppos)
-{
-	int i, len = 0;
-
-	pr_info("%s\n", __func__);
-	if (*ppos)
-		return 0;       /* the end */
-
-	for (i = 0 ; i < MDP4_MAX_PIPE; i++) {
-		len += snprintf(debug_buf+len, sizeof(debug_buf),
-			"Pipe-%d\n", i);
-		len += ov_dump_req(&(ctrl->plist[i].req_data), debug_buf+len);
 	}
 
-	if (copy_to_user(buff, debug_buf, len))
-		return -EFAULT;
+	mdp4_overlay_mdp_perf_req(mfd, ctrl->plist);
 
-	*ppos += len;   /* increase offset */
+	if (pipe->mixer_num == MDP4_MIXER2 || ctrl->panel_mode & MDP4_PANEL_MDDI)
+		goto mddi;
 
-	return len;
-}
-
-static const struct file_operations ov_requests_fops = {
-	.open		= ov_requests_open,
-	.release	= ov_requests_release,
-	.read		= ov_requests_read,
-};
-
-static int ov_snapshot_open(struct inode *inode, struct file *file)
-{
-	/* non-seekable */
-	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
-	return 0;
-}
-
-static int ov_snapshot_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static ssize_t ov_snapshot_write(struct file *file, const char __user *buff, size_t count, loff_t *ppos)
-{
-	if (count >= sizeof(snapshot_filename))
-		return -EFAULT;
-	if (copy_from_user(snapshot_filename, buff, count))
-		return -EFAULT;
-	snapshot_filename[count] = 0;   /* end of string */
-	pr_info("%s: snapshot to: %s\n", __func__, snapshot_filename);
-
-	mutex_lock(&snapshot_lock);
-	is_demanding_snapshot = true;
-	mutex_unlock(&snapshot_lock);
-
-	return 0;
-}
-
-static const struct file_operations ov_snapshot_fops = {
-	.open		= ov_snapshot_open,
-	.release	= ov_snapshot_release,
-	.write		= ov_snapshot_write,
-};
-
-void mdp4_dump_ov(struct mdp_overlay *ov)
-{
-	ov_dump_req(ov, debug_buf);
-	pr_info("%s\n", debug_buf);
-}
-
-int mdp4_overlay_debugfs_init(void)
-{
-	struct dentry *dent = debugfs_create_dir("overlay", NULL);
-
-	if (IS_ERR(dent)) {
-		printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
-				__FILE__, __LINE__, PTR_ERR(dent));
-		return -1;
-	}
-
-	if (debugfs_create_file("requests", 0444, dent, 0, &ov_requests_fops)
-			== NULL) {
-		printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
-				__FILE__, __LINE__);
-		return -1;
-	}
-
-	if (debugfs_create_file("snapshot", 0222, dent, 0, &ov_snapshot_fops)
-			== NULL) {
-		printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
-				__FILE__, __LINE__);
-		return -1;
-	}
-
-
-	return 0;
-}
+	if (pipe->mixer_num == MDP4_MIXER0) {
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+			/* cndx = 0 */
+			mdp4_dsi_cmd_pipe_queue(0, pipe);
+		}
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
+			/* cndx = 0 */
+			mdp4_dsi_video_pipe_queue(0, pipe);
+		} else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
+			/* cndx = 0 */
+			mdp4_lcdc_pipe_queue(0, pipe);
+		}
+	} else if (pipe->mixer_num == MDP4_MIXER1) {
+#ifdef CONFIG_FB_MSM_DTV
+		if (ctrl->panel_mode & MDP4_PANEL_DTV)
+			mdp4_dtv_pipe_queue(0, pipe);/* cndx = 0 */
 #endif
+	}
+
+	mutex_unlock(&mfd->dma->ov_mutex);
+	return ret;
+
+mddi:
+	if (pipe->pipe_type == OVERLAY_TYPE_VIDEO) {
+		mdp4_overlay_vg_setup(pipe);    /* video/graphic pipe */
+	} else {
+		mdp4_overlay_rgb_setup(pipe);	/* rgb pipe */
+	}
+
+	mdp4_mixer_stage_up(pipe);
+
+	if (pipe->mixer_num == MDP4_MIXER2) {
+		ctrl->mixer2_played++;
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+		if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
+			mdp4_writeback_dma_busy_wait(mfd);
+			mdp4_writeback_kickoff_video(mfd, pipe);
+		}
+#endif
+	} else if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
+		if (pipe->flags & MDP_OV_PLAY_NOWAIT) {
+			mdp4_stat.overlay_play[pipe->mixer_num]++;
+			mutex_unlock(&mfd->dma->ov_mutex);
+			goto end;
+		}
+		mdp4_mixer_stage_commit(pipe->mixer_num);
+		mdp4_mddi_dma_busy_wait(mfd);
+		mdp4_mddi_kickoff_video(mfd, pipe);
+	}
+
+	if (!(pipe->flags & MDP_OV_PLAY_NOWAIT))
+		mdp4_iommu_unmap(pipe);
+	mdp4_stat.overlay_play[pipe->mixer_num]++;
+
+end:
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+#ifdef CONFIG_ANDROID_PMEM
+	if (srcp0_file)
+		put_pmem_file(srcp0_file);
+	if (srcp1_file)
+		put_pmem_file(srcp1_file);
+	if (srcp2_file)
+		put_pmem_file(srcp2_file);
+#endif
+	/* only source may use frame buffer */
+	if (img->flags & MDP_MEMORY_ID_TYPE_FB)
+		fput_light(srcp0_file, ps0_need);
+	return ret;
+}
+
+static struct {
+	char *name;
+	int  domain;
+} msm_iommu_ctx_names[] = {
+	/* Display */
+	{
+		.name = "mdp_port0_cb0",
+		.domain = DISPLAY_DOMAIN,
+	},
+	/* Display */
+	{
+		.name = "mdp_port0_cb1",
+		.domain = DISPLAY_DOMAIN,
+	},
+	/* Display */
+	{
+		.name = "mdp_port1_cb0",
+		.domain = DISPLAY_DOMAIN,
+	},
+	/* Display */
+	{
+		.name = "mdp_port1_cb1",
+		.domain = DISPLAY_DOMAIN,
+	},
+};
+
+static int iommu_enabled;
+
+void mdp4_iommu_attach(void)
+{
+	struct iommu_domain *domain;
+	int i;
+
+	if (!iommu_enabled) {
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_names); i++) {
+			int domain_idx;
+			struct device *ctx = msm_iommu_get_ctx(
+				msm_iommu_ctx_names[i].name);
+
+			if (!ctx)
+				continue;
+
+			domain_idx = msm_iommu_ctx_names[i].domain;
+
+			domain = msm_get_iommu_domain(domain_idx);
+			if (!domain)
+				continue;
+
+			if (iommu_attach_device(domain,	ctx)) {
+				WARN(1, "%s: could not attach domain %d to context %s."
+					" iommu programming will not occur.\n",
+					__func__, domain_idx,
+					msm_iommu_ctx_names[i].name);
+				continue;
+			}
+		}
+		pr_debug("Attached MDP IOMMU device\n");
+		iommu_enabled = 1;
+	}
+}
+
+void mdp4_iommu_detach(void)
+{
+	struct iommu_domain *domain;
+	int i;
+
+	if (!mdp_check_suspended() || mdp4_extn_disp)
+		return;
+
+	if (iommu_enabled) {
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_names); i++) {
+			int domain_idx;
+			struct device *ctx = msm_iommu_get_ctx(
+				msm_iommu_ctx_names[i].name);
+
+			if (!ctx)
+				continue;
+
+			domain_idx = msm_iommu_ctx_names[i].domain;
+
+			domain = msm_get_iommu_domain(domain_idx);
+			if (!domain)
+				continue;
+
+			iommu_detach_device(domain,	ctx);
+		}
+		pr_debug("Detached MDP IOMMU device\n");
+		iommu_enabled = 0;
+	}
+}
+
+int mdp4_v4l2_overlay_set(struct fb_info *info, struct mdp_overlay *req,
+	struct mdp4_overlay_pipe **ppipe)
+{
+	struct mdp4_overlay_pipe *pipe;
+	int err;
+	struct msm_fb_data_type *mfb = info->par;
+
+	req->z_order = 0;
+	req->id = MSMFB_NEW_REQUEST;
+	req->is_fg = false;
+	req->alpha = 0xff;
+	err = mdp4_overlay_req2pipe(req, MDP4_MIXER0, &pipe, mfb);
+	if (err < 0) {
+		pr_err("%s:Could not allocate MDP overlay pipe\n", __func__);
+		return err;
+	}
+
+	mdp4_mixer_blend_setup(pipe->mixer_num);
+	*ppipe = pipe;
+
+	return 0;
+}
+
+void mdp4_v4l2_overlay_clear(struct mdp4_overlay_pipe *pipe)
+{
+	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_down(pipe);
+	mdp4_overlay_pipe_free(pipe);
+}
+
+int mdp4_v4l2_overlay_play(struct fb_info *info, struct mdp4_overlay_pipe *pipe,
+	unsigned long srcp0_addr, unsigned long srcp1_addr,
+	unsigned long srcp2_addr)
+{
+	struct msm_fb_data_type *mfd = info->par;
+	int err;
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
+		return -EINTR;
+
+	switch (pipe->src_format) {
+	case MDP_Y_CR_CB_H2V2:
+		/* YUV420 */
+		pipe->srcp0_addr = srcp0_addr;
+		pipe->srcp0_ystride = pipe->src_width;
+		/*
+		 * For YUV420, the luma plane is 1 byte per pixel times
+		 * num of pixels in the image Also, the planes are
+		 * switched in MDP, srcp2 is actually first chroma plane
+		 */
+		pipe->srcp2_addr = srcp1_addr ? srcp1_addr :
+		pipe->srcp0_addr + (pipe->src_width * pipe->src_height);
+		pipe->srcp2_ystride = pipe->src_width/2;
+		/*
+		 * The chroma planes are half the size of the luma
+		 * planes
+		 */
+		pipe->srcp1_addr = srcp2_addr ? srcp2_addr :
+		pipe->srcp2_addr +
+			(pipe->src_width * pipe->src_height / 4);
+		pipe->srcp1_ystride = pipe->src_width/2;
+		break;
+	case MDP_Y_CRCB_H2V2:
+		/* NV12 */
+		pipe->srcp0_addr = srcp0_addr;
+		pipe->srcp0_ystride = pipe->src_width;
+		pipe->srcp1_addr = srcp1_addr ? srcp1_addr :
+		pipe->srcp0_addr +
+			(pipe->src_width * pipe->src_height);
+		pipe->srcp1_ystride = pipe->src_width;
+		break;
+	default:
+		pr_err("%s: format (%u) is not supported\n", __func__,
+				pipe->src_format);
+		err = -EINVAL;
+		goto done;
+	}
+
+	pr_debug("%s: pipe ndx=%d stage=%d format=%x\n", __func__,
+		pipe->pipe_ndx, pipe->mixer_stage, pipe->src_format);
+
+	if (pipe->pipe_type == OVERLAY_TYPE_VIDEO)
+		mdp4_overlay_vg_setup(pipe);
+	else
+		mdp4_overlay_rgb_setup(pipe);
+
+	if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+		mdp4_overlay_reg_flush(pipe, 1);
+
+	mdp4_mixer_stage_up(pipe);
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+#ifdef V4L2_VSYNC
+	/*
+	 * TODO: incorporate v4l2 into vsycn driven mechanism
+	 */
+	if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
+		mdp4_overlay_lcdc_vsync_push(mfd, pipe);
+	} else {
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+			mdp4_dsi_cmd_dma_busy_wait(mfd);
+			mdp4_dsi_cmd_kickoff_video(mfd, pipe);
+		}
+#else
+		if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
+			mdp4_mddi_dma_busy_wait(mfd);
+			mdp4_mddi_kickoff_video(mfd, pipe);
+		}
+#endif
+	}
+#endif
+
+done:
+	mutex_unlock(&mfd->dma->ov_mutex);
+	return err;
+}
+
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
new file mode 100644
index 0000000..c133831
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -0,0 +1,208 @@
+/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/fb.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+
+
+static struct mdp4_overlay_pipe *atv_pipe;
+
+int mdp4_atv_on(struct platform_device *pdev)
+{
+	uint8 *buf;
+	unsigned int buf_offset;
+	int bpp, ptype;
+	struct fb_info *fbi;
+	struct fb_var_screeninfo *var;
+	struct msm_fb_data_type *mfd;
+	struct mdp4_overlay_pipe *pipe;
+	int ret;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	fbi = mfd->fbi;
+	var = &fbi->var;
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+	buf_offset = calc_fb_offset(mfd, fbi, bpp);
+
+	if (atv_pipe == NULL) {
+		ptype = mdp4_overlay_format2type(mfd->fb_imgType);
+		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1);
+		if (pipe == NULL)
+			return -EBUSY;
+		pipe->pipe_used++;
+		pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
+		pipe->mixer_num  = MDP4_MIXER1;
+		pipe->src_format = mfd->fb_imgType;
+		mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_ATV);
+		mdp4_overlay_format2pipe(pipe);
+
+		atv_pipe = pipe; /* keep it */
+	} else {
+		pipe = atv_pipe;
+	}
+
+	printk(KERN_INFO "mdp4_atv_overlay: pipe=%x ndx=%d\n",
+					(int)pipe, pipe->pipe_ndx);
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/* Turn the next panel on, get correct resolution
+		before configuring overlay pipe */
+	ret = panel_next_on(pdev);
+
+	pr_info("%s: fbi->var.yres: %d | fbi->var.xres: %d",
+			__func__, fbi->var.yres, fbi->var.xres);
+
+	/* MDP4 Config */
+	pipe->src_height = fbi->var.yres;
+	pipe->src_width = fbi->var.xres;
+	pipe->src_h = fbi->var.yres;
+	pipe->src_w = fbi->var.xres;
+	pipe->src_y = 0;
+	pipe->src_x = 0;
+	if (mfd->map_buffer) {
+		pipe->srcp0_addr = (unsigned int)mfd->map_buffer->iova[0] + \
+			buf_offset;
+		pr_debug("start 0x%lx srcp0_addr 0x%x\n", mfd->
+			map_buffer->iova[0], pipe->srcp0_addr);
+	} else {
+		pipe->srcp0_addr = (uint32)(buf + buf_offset);
+	}
+
+	pipe->srcp0_ystride = fbi->fix.line_length;
+
+	mdp4_overlay_dmae_xy(pipe);	/* dma_e */
+	mdp4_overlay_dmae_cfg(mfd, 1);
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+	if (ret == 0)
+		mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return ret;
+}
+
+int mdp4_atv_off(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	ret = panel_next_off(pdev);
+
+	/* delay to make sure the last frame finishes */
+	msleep(100);
+
+	/* dis-engage rgb2 from mixer1 */
+	if (atv_pipe) {
+		mdp4_mixer_stage_down(atv_pipe);
+		mdp4_iommu_unmap(atv_pipe);
+	}
+
+	return ret;
+}
+
+/*
+ * mdp4_overlay1_done_atv: called from isr
+ */
+void mdp4_overlay1_done_atv()
+{
+	complete(&atv_pipe->comp);
+}
+
+void mdp4_atv_overlay(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	unsigned int buf_offset;
+	int bpp;
+	unsigned long flag;
+	struct mdp4_overlay_pipe *pipe;
+
+	if (!mfd->panel_power_on)
+		return;
+
+	/* no need to power on cmd block since it's lcdc mode */
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+	buf_offset = calc_fb_offset(mfd, fbi, bpp);
+
+	mutex_lock(&mfd->dma->ov_mutex);
+
+	pipe = atv_pipe;
+	if (mfd->map_buffer) {
+		pipe->srcp0_addr = (unsigned int)mfd->map_buffer->iova[0] + \
+			buf_offset;
+		pr_debug("start 0x%lx srcp0_addr 0x%x\n", mfd->
+			map_buffer->iova[0], pipe->srcp0_addr);
+	} else {
+		pipe->srcp0_addr = (uint32)(buf + buf_offset);
+	}
+	mdp4_overlay_mdp_perf_req(pipe, mfd);
+	mdp4_overlay_mdp_perf_upd(mfd, 1);
+	mdp4_overlay_rgb_setup(pipe);
+	mdp4_overlay_reg_flush(pipe, 0);
+	mdp4_mixer_stage_up(pipe);
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+	printk(KERN_INFO "mdp4_atv_overlay: pipe=%x ndx=%d\n",
+					(int)pipe, pipe->pipe_ndx);
+
+	/* enable irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_OVERLAY1_TERM);
+	INIT_COMPLETION(atv_pipe->comp);
+	mfd->dma->waiting = TRUE;
+	outp32(MDP_INTR_CLEAR, INTR_OVERLAY1_DONE);
+	mdp_intr_mask |= INTR_OVERLAY1_DONE;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	wait_for_completion_killable(&atv_pipe->comp);
+	mdp_disable_irq(MDP_OVERLAY1_TERM);
+	mdp4_overlay_mdp_perf_upd(mfd, 0);
+	mdp4_stat.kickoff_atv++;
+	mutex_unlock(&mfd->dma->ov_mutex);
+}
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
new file mode 100644
index 0000000..334f600
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -0,0 +1,1058 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/fb.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mdp4.h"
+
+static int dsi_state;
+
+#define TOUT_PERIOD	HZ	/* 1 second */
+#define MS_100		(HZ/10)	/* 100 ms */
+
+static int vsync_start_y_adjust = 4;
+
+#define MAX_CONTROLLER	1
+#define VSYNC_EXPIRE_TICK 4
+
+static struct vsycn_ctrl {
+	struct device *dev;
+	int inited;
+	int update_ndx;
+	int expire_tick;
+	int blt_wait;
+	u32 ov_koff;
+	u32 ov_done;
+	u32 dmap_koff;
+	u32 dmap_done;
+	uint32 rdptr_intr_tot;
+	uint32 rdptr_sirq_tot;
+	atomic_t suspend;
+	int wait_vsync_cnt;
+	int blt_change;
+	int blt_free;
+	int blt_end;
+	int fake_vsync;
+	struct mutex update_lock;
+	struct completion ov_comp;
+	struct completion dmap_comp;
+	struct completion vsync_comp;
+	spinlock_t spin_lock;
+	struct msm_fb_data_type *mfd;
+	struct mdp4_overlay_pipe *base_pipe;
+	struct vsync_update vlist[2];
+	int vsync_enabled;
+	int clk_enabled;
+	int clk_control;
+	ktime_t vsync_time;
+	struct work_struct vsync_work;
+	struct work_struct clk_work;
+} vsync_ctrl_db[MAX_CONTROLLER];
+
+static void vsync_irq_enable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	/* no need to clrear other interrupts for comamnd mode */
+	mdp_intr_mask |= intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_enable_irq(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+static void vsync_irq_disable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	/* no need to clrear other interrupts for comamnd mode */
+	mdp_intr_mask &= ~intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_disable_irq_nosync(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+static void mdp4_dsi_cmd_blt_ov_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+	char *overlay_base;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = 0;
+	if (pipe->ov_cnt & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr = pipe->ov_blt_addr + off;
+	/* overlay 0 */
+	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+	outpdw(overlay_base + 0x000c, addr);
+	outpdw(overlay_base + 0x001c, addr);
+}
+
+static void mdp4_dsi_cmd_blt_dmap_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = 0;
+	if (pipe->dmap_cnt & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr = pipe->dma_blt_addr + off;
+
+	/* dmap */
+	MDP_OUTP(MDP_BASE + 0x90008, addr);
+}
+
+static void mdp4_dsi_cmd_wait4dmap(int cndx);
+static void mdp4_dsi_cmd_wait4ov(int cndx);
+
+static void mdp4_dsi_cmd_do_blt(struct msm_fb_data_type *mfd, int enable)
+{
+	unsigned long flags;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	int need_wait;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
+
+	if (mfd->ov0_wb_buf->write_addr == 0) {
+		pr_info("%s: no blt_base assigned\n", __func__);
+		return;
+	}
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (enable && pipe->ov_blt_addr == 0) {
+		vctrl->blt_change++;
+		if (vctrl->dmap_koff != vctrl->dmap_done) {
+			INIT_COMPLETION(vctrl->dmap_comp);
+			need_wait = 1;
+		}
+	} else if (enable == 0 && pipe->ov_blt_addr) {
+		vctrl->blt_change++;
+		if (vctrl->ov_koff != vctrl->dmap_done) {
+			INIT_COMPLETION(vctrl->dmap_comp);
+			need_wait = 1;
+		}
+	}
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	if (need_wait)
+		mdp4_dsi_cmd_wait4dmap(0);
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (enable && pipe->ov_blt_addr == 0) {
+		pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
+		pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr;
+		pipe->ov_cnt = 0;
+		pipe->dmap_cnt = 0;
+		vctrl->ov_koff = vctrl->dmap_koff;
+		vctrl->ov_done = vctrl->dmap_done;
+		vctrl->blt_free = 0;
+		vctrl->blt_wait = 0;
+		vctrl->blt_end = 0;
+		mdp4_stat.blt_dsi_video++;
+	} else if (enable == 0 && pipe->ov_blt_addr) {
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr =  0;
+		vctrl->blt_end = 1;
+		vctrl->blt_free = 4;	/* 4 commits to free wb buf */
+	}
+
+	pr_info("%s: changed=%d enable=%d ov_blt_addr=%x\n", __func__,
+		vctrl->blt_change, enable, (int)pipe->ov_blt_addr);
+
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+}
+
+/*
+ * mdp4_dsi_cmd_do_update:
+ * called from thread context
+ */
+void mdp4_dsi_cmd_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+	struct vsycn_ctrl *vctrl;
+	struct vsync_update *vp;
+	struct mdp4_overlay_pipe *pp;
+	int undx;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	mutex_lock(&vctrl->update_lock);
+	undx =  vctrl->update_ndx;
+	vp = &vctrl->vlist[undx];
+
+	pp = &vp->plist[pipe->pipe_ndx - 1];	/* ndx start form 1 */
+
+	pr_debug("%s: vndx=%d pipe_ndx=%d expire=%x pid=%d\n", __func__,
+		undx, pipe->pipe_ndx, vctrl->expire_tick, current->pid);
+
+	*pp = *pipe;	/* clone it */
+	vp->update_cnt++;
+
+	mutex_unlock(&vctrl->update_lock);
+	mdp4_stat.overlay_play[pipe->mixer_num]++;
+}
+
+static void mdp4_dsi_cmd_blt_ov_update(struct mdp4_overlay_pipe *pipe);
+
+int mdp4_dsi_cmd_pipe_commit(void)
+{
+	int  i, undx;
+	int mixer = 0;
+	struct vsycn_ctrl *vctrl;
+	struct vsync_update *vp;
+	struct mdp4_overlay_pipe *pipe;
+	struct mdp4_overlay_pipe *real_pipe;
+	unsigned long flags;
+	int need_dmap_wait = 0;
+	int need_ov_wait = 0;
+	int cnt = 0;
+
+	vctrl = &vsync_ctrl_db[0];
+
+	mutex_lock(&vctrl->update_lock);
+	undx =  vctrl->update_ndx;
+	vp = &vctrl->vlist[undx];
+	pipe = vctrl->base_pipe;
+	mixer = pipe->mixer_num;
+
+	if (vp->update_cnt == 0) {
+		mutex_unlock(&vctrl->update_lock);
+		return cnt;
+	}
+
+	vctrl->update_ndx++;
+	vctrl->update_ndx &= 0x01;
+	vp->update_cnt = 0;     /* reset */
+	if (vctrl->blt_free) {
+		vctrl->blt_free--;
+		if (vctrl->blt_free == 0)
+			mdp4_free_writeback_buf(vctrl->mfd, mixer);
+	}
+	mutex_unlock(&vctrl->update_lock);
+
+	/* free previous committed iommu back to pool */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (pipe->ov_blt_addr) {
+		/* Blt */
+		if (vctrl->blt_wait)
+			need_dmap_wait = 1;
+		else if (vctrl->ov_koff != vctrl->ov_done) {
+			INIT_COMPLETION(vctrl->ov_comp);
+			need_ov_wait = 1;
+		}
+	} else {
+		/* direct out */
+		if (vctrl->dmap_koff != vctrl->dmap_done) {
+			INIT_COMPLETION(vctrl->dmap_comp);
+			pr_debug("%s: wait, ok=%d od=%d dk=%d dd=%d cpu=%d\n",
+			 __func__, vctrl->ov_koff, vctrl->ov_done,
+			vctrl->dmap_koff, vctrl->dmap_done, smp_processor_id());
+			need_dmap_wait = 1;
+		}
+	}
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	if (need_dmap_wait) {
+		pr_debug("%s: wait4dmap\n", __func__);
+		mdp4_dsi_cmd_wait4dmap(0);
+	}
+
+	if (need_ov_wait) {
+		pr_debug("%s: wait4ov\n", __func__);
+		mdp4_dsi_cmd_wait4ov(0);
+	}
+
+	if (pipe->ov_blt_addr) {
+		if (vctrl->blt_end) {
+			vctrl->blt_end = 0;
+			pipe->ov_blt_addr = 0;
+			pipe->dma_blt_addr =  0;
+		}
+	}
+
+	if (vctrl->blt_change) {
+		mdp4_overlayproc_cfg(pipe);
+		mdp4_overlay_dmap_xy(pipe);
+		vctrl->blt_change = 0;
+	}
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			cnt++;
+			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
+			if (real_pipe && real_pipe->pipe_used) {
+				/* pipe not unset */
+				mdp4_overlay_vsync_commit(pipe);
+			}
+			/* free previous iommu to freelist
+			* which will be freed at next
+			* pipe_commit
+			*/
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+
+	/* tx dcs command if had any */
+	mipi_dsi_cmdlist_commit(1);
+
+	mdp4_mixer_stage_commit(mixer);
+
+	pipe = vctrl->base_pipe;
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (pipe->ov_blt_addr) {
+		mdp4_dsi_cmd_blt_ov_update(pipe);
+		pipe->ov_cnt++;
+		vctrl->ov_koff++;
+		vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
+	} else {
+		vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+		vctrl->dmap_koff++;
+	}
+	pr_debug("%s: kickoff\n", __func__);
+	/* kickoff overlay engine */
+	mdp4_stat.kickoff_ov0++;
+	outpdw(MDP_BASE + 0x0004, 0);
+	mb();
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	mdp4_stat.overlay_commit[pipe->mixer_num]++;
+
+	return cnt;
+}
+
+void mdp4_dsi_cmd_vsync_ctrl(int cndx, int enable)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (enable && vctrl->fake_vsync) {
+		vctrl->fake_vsync = 0;
+		schedule_work(&vctrl->vsync_work);
+	}
+
+	if (vctrl->vsync_enabled == enable)
+		return;
+
+	vctrl->vsync_enabled = enable;
+
+#ifdef CLOCK_CONTROL
+	mutex_lock(&vctrl->update_lock);
+	if (enable) {
+		vsync_irq_enable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
+	} else {
+		vsync_irq_disable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
+	}
+	mutex_unlock(&vctrl->update_lock);
+#endif
+}
+
+void mdp4_dsi_cmd_wait4vsync(int cndx, long long *vtime)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	unsigned long flags;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	if (atomic_read(&vctrl->suspend) > 0) {
+		*vtime = -1;
+		return;
+	}
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (vctrl->wait_vsync_cnt == 0)
+		INIT_COMPLETION(vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt++;
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	wait_for_completion(&vctrl->vsync_comp);
+	mdp4_stat.wait4vsync0++;
+
+	*vtime = ktime_to_ns(vctrl->vsync_time);
+}
+
+static void mdp4_dsi_cmd_wait4dmap(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	wait_for_completion(&vctrl->dmap_comp);
+}
+
+static void mdp4_dsi_cmd_wait4ov(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	wait_for_completion(&vctrl->ov_comp);
+}
+
+/*
+ * primary_rdptr_isr:
+ * called from interrupt context
+ */
+
+static void primary_rdptr_isr(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pr_debug("%s: ISR, cpu=%d\n", __func__, smp_processor_id());
+	vctrl->rdptr_intr_tot++;
+	vctrl->vsync_time = ktime_get();
+	schedule_work(&vctrl->vsync_work);
+
+	spin_lock(&vctrl->spin_lock);
+	if (vctrl->wait_vsync_cnt) {
+		complete(&vctrl->vsync_comp);
+		vctrl->wait_vsync_cnt = 0;
+	}
+	spin_unlock(&vctrl->spin_lock);
+}
+
+void mdp4_dmap_done_dsi_cmd(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	int diff;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	 /* blt enabled */
+	spin_lock(&vctrl->spin_lock);
+	vsync_irq_disable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+	vctrl->dmap_done++;
+	diff = vctrl->ov_done - vctrl->dmap_done;
+	pr_debug("%s: ov_koff=%d ov_done=%d dmap_koff=%d dmap_done=%d cpu=%d\n",
+		__func__, vctrl->ov_koff, vctrl->ov_done, vctrl->dmap_koff,
+		vctrl->dmap_done, smp_processor_id());
+	complete_all(&vctrl->dmap_comp);
+	if (diff <= 0) {
+		if (vctrl->blt_wait)
+			vctrl->blt_wait = 0;
+		spin_unlock(&vctrl->spin_lock);
+		return;
+	}
+
+	/* kick dmap */
+	mdp4_dsi_cmd_blt_dmap_update(pipe);
+	pipe->dmap_cnt++;
+	mdp4_stat.kickoff_dmap++;
+	vctrl->dmap_koff++;
+	vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+	outpdw(MDP_BASE + 0x000c, 0); /* kickoff dmap engine */
+	mb();
+	spin_unlock(&vctrl->spin_lock);
+}
+
+/*
+ * mdp4_overlay0_done_dsi_cmd: called from isr
+ */
+void mdp4_overlay0_done_dsi_cmd(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	int diff;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	spin_lock(&vctrl->spin_lock);
+	vsync_irq_disable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
+	vctrl->ov_done++;
+	complete_all(&vctrl->ov_comp);
+	diff = vctrl->ov_done - vctrl->dmap_done;
+
+	pr_debug("%s: ov_koff=%d ov_done=%d dmap_koff=%d dmap_done=%d cpu=%d\n",
+		__func__, vctrl->ov_koff, vctrl->ov_done, vctrl->dmap_koff,
+		vctrl->dmap_done, smp_processor_id());
+
+	if (pipe->ov_blt_addr == 0) {
+		/* blt disabled */
+		spin_unlock(&vctrl->spin_lock);
+		return;
+	}
+
+	if (diff > 1) {
+		/*
+		 * two overlay_done and none dmap_done yet
+		 * let dmap_done kickoff dmap
+		 * and put pipe_commit to wait
+		 */
+		vctrl->blt_wait = 1;
+		pr_debug("%s: blt_wait set\n", __func__);
+		spin_unlock(&vctrl->spin_lock);
+		return;
+	}
+	mdp4_dsi_cmd_blt_dmap_update(pipe);
+	pipe->dmap_cnt++;
+	mdp4_stat.kickoff_dmap++;
+	vctrl->dmap_koff++;
+	vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+	outpdw(MDP_BASE + 0x000c, 0); /* kickoff dmap engine */
+	mb();
+	spin_unlock(&vctrl->spin_lock);
+}
+
+static void clk_ctrl_work(struct work_struct *work)
+{
+	struct vsycn_ctrl *vctrl =
+		container_of(work, typeof(*vctrl), clk_work);
+
+	mutex_lock(&vctrl->update_lock);
+	if (vctrl->clk_control) {
+		if (vctrl->clk_enabled) {
+			mdp_clk_ctrl(0);
+			vctrl->clk_enabled = 0;
+			vctrl->fake_vsync = 1;
+		}
+	}
+
+	mutex_unlock(&vctrl->update_lock);
+}
+
+static void send_vsync_work(struct work_struct *work)
+{
+	struct vsycn_ctrl *vctrl =
+		container_of(work, typeof(*vctrl), vsync_work);
+	char buf[64];
+	char *envp[2];
+
+	snprintf(buf, sizeof(buf), "VSYNC=%llu",
+			ktime_to_ns(vctrl->vsync_time));
+	envp[0] = buf;
+	envp[1] = NULL;
+	kobject_uevent_env(&vctrl->dev->kobj, KOBJ_CHANGE, envp);
+}
+
+
+void mdp4_dsi_rdptr_init(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->inited)
+		return;
+
+	vctrl->inited = 1;
+	vctrl->update_ndx = 0;
+	mutex_init(&vctrl->update_lock);
+	init_completion(&vctrl->ov_comp);
+	init_completion(&vctrl->dmap_comp);
+	init_completion(&vctrl->vsync_comp);
+	spin_lock_init(&vctrl->spin_lock);
+	INIT_WORK(&vctrl->vsync_work, send_vsync_work);
+	INIT_WORK(&vctrl->clk_work, clk_ctrl_work);
+}
+
+void mdp4_primary_rdptr(void)
+{
+	primary_rdptr_isr(0);
+}
+
+void mdp4_overlay_dsi_state_set(int state)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	dsi_state = state;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+int mdp4_overlay_dsi_state_get(void)
+{
+	return dsi_state;
+}
+
+static __u32 msm_fb_line_length(__u32 fb_index, __u32 xres, int bpp)
+{
+	/*
+	 * The adreno GPU hardware requires that the pitch be aligned to
+	 * 32 pixels for color buffers, so for the cases where the GPU
+	 * is writing directly to fb0, the framebuffer pitch
+	 * also needs to be 32 pixel aligned
+	 */
+
+	if (fb_index == 0)
+		return ALIGN(xres, 32) * bpp;
+	else
+		return xres * bpp;
+}
+
+void mdp4_mipi_vsync_enable(struct msm_fb_data_type *mfd,
+		struct mdp4_overlay_pipe *pipe, int which)
+{
+	uint32 start_y, data, tear_en;
+
+	tear_en = (1 << which);
+
+	if ((mfd->use_mdp_vsync) && (mfd->ibuf.vsync_enable) &&
+		(mfd->panel_info.lcd.vsync_enable)) {
+
+		if (vsync_start_y_adjust <= pipe->dst_y)
+			start_y = pipe->dst_y - vsync_start_y_adjust;
+		else
+			start_y = (mfd->total_lcd_lines - 1) -
+				(vsync_start_y_adjust - pipe->dst_y);
+		if (which == 0)
+			MDP_OUTP(MDP_BASE + 0x210, start_y);	/* primary */
+		else
+			MDP_OUTP(MDP_BASE + 0x214, start_y);	/* secondary */
+
+		data = inpdw(MDP_BASE + 0x20c);
+		data |= tear_en;
+		MDP_OUTP(MDP_BASE + 0x20c, data);
+	} else {
+		data = inpdw(MDP_BASE + 0x20c);
+		data &= ~tear_en;
+		MDP_OUTP(MDP_BASE + 0x20c, data);
+	}
+}
+
+void mdp4_dsi_cmd_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	vctrl->base_pipe = pipe;
+}
+
+static void mdp4_overlay_setup_pipe_addr(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+	MDPIBUF *iBuf = &mfd->ibuf;
+	struct fb_info *fbi;
+	int bpp;
+	uint8 *src;
+
+	/* whole screen for base layer */
+	src = (uint8 *) iBuf->buf;
+	fbi = mfd->fbi;
+
+	if (pipe->is_3d) {
+		bpp = fbi->var.bits_per_pixel / 8;
+		pipe->src_height = pipe->src_height_3d;
+		pipe->src_width = pipe->src_width_3d;
+		pipe->src_h = pipe->src_height_3d;
+		pipe->src_w = pipe->src_width_3d;
+		pipe->dst_h = pipe->src_height_3d;
+		pipe->dst_w = pipe->src_width_3d;
+		pipe->srcp0_ystride = msm_fb_line_length(0,
+						pipe->src_width, bpp);
+	} else {
+		 /* 2D */
+		pipe->src_height = fbi->var.yres;
+		pipe->src_width = fbi->var.xres;
+		pipe->src_h = fbi->var.yres;
+		pipe->src_w = fbi->var.xres;
+		pipe->dst_h = fbi->var.yres;
+		pipe->dst_w = fbi->var.xres;
+		pipe->srcp0_ystride = fbi->fix.line_length;
+	}
+	pipe->src_y = 0;
+	pipe->src_x = 0;
+	pipe->dst_y = 0;
+	pipe->dst_x = 0;
+	pipe->srcp0_addr = (uint32)src;
+}
+
+void mdp4_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd)
+{
+	int ptype;
+	struct mdp4_overlay_pipe *pipe;
+	int ret;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+
+
+	if (mfd->key != MFD_KEY)
+		return;
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	/* MDP cmd block enable */
+	mdp_clk_ctrl(1);
+
+	ptype = mdp4_overlay_format2type(mfd->fb_imgType);
+	if (ptype < 0)
+		printk(KERN_INFO "%s: format2type failed\n", __func__);
+	pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
+	if (pipe == NULL) {
+		printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
+		return;
+	}
+	pipe->pipe_used++;
+	pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
+	pipe->mixer_num  = MDP4_MIXER0;
+	pipe->src_format = mfd->fb_imgType;
+	mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_CMD);
+	ret = mdp4_overlay_format2pipe(pipe);
+	if (ret < 0)
+		printk(KERN_INFO "%s: format2type failed\n", __func__);
+
+	vctrl->base_pipe = pipe; /* keep it */
+	mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
+	pipe->ov_blt_addr = 0;
+	pipe->dma_blt_addr = 0;
+
+	MDP_OUTP(MDP_BASE + 0x021c, 10); /* read pointer */
+
+	/*
+	 * configure dsi stream id
+	 * dma_p = 0, dma_s = 1
+	 */
+	MDP_OUTP(MDP_BASE + 0x000a0, 0x10);
+	/* disable dsi trigger */
+	MDP_OUTP(MDP_BASE + 0x000a4, 0x00);
+
+
+	mdp4_overlay_setup_pipe_addr(mfd, pipe);
+
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_overlay_reg_flush(pipe, 1);
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_dmap_xy(pipe);
+
+	mdp4_overlay_dmap_cfg(mfd, 0);
+
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+	/* MDP cmd block disable */
+	mdp_clk_ctrl(0);
+
+	wmb();
+}
+
+/* 3D side by side */
+void mdp4_dsi_cmd_3d_sbys(struct msm_fb_data_type *mfd,
+				struct msmfb_overlay_3d *r3d)
+{
+	struct fb_info *fbi;
+	int bpp;
+	uint8 *src = NULL;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	if (pipe == NULL)
+		return;
+
+	if (pipe->pipe_used == 0 ||
+			pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) {
+		pr_err("%s: NOT baselayer\n", __func__);
+		return;
+	}
+
+	pipe->is_3d = r3d->is_3d;
+	pipe->src_height_3d = r3d->height;
+	pipe->src_width_3d = r3d->width;
+
+	if (pipe->is_3d)
+		mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_SIDE_BY_SIDE);
+	else
+		mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_NONE);
+
+	fbi = mfd->fbi;
+	if (pipe->is_3d) {
+		bpp = fbi->var.bits_per_pixel / 8;
+		pipe->src_height = pipe->src_height_3d;
+		pipe->src_width = pipe->src_width_3d;
+		pipe->src_h = pipe->src_height_3d;
+		pipe->src_w = pipe->src_width_3d;
+		pipe->dst_h = pipe->src_height_3d;
+		pipe->dst_w = pipe->src_width_3d;
+		pipe->srcp0_ystride = msm_fb_line_length(0,
+					pipe->src_width, bpp);
+	} else {
+		 /* 2D */
+		pipe->src_height = fbi->var.yres;
+		pipe->src_width = fbi->var.xres;
+		pipe->src_h = fbi->var.yres;
+		pipe->src_w = fbi->var.xres;
+		pipe->dst_h = fbi->var.yres;
+		pipe->dst_w = fbi->var.xres;
+		pipe->srcp0_ystride = fbi->fix.line_length;
+	}
+	pipe->src_y = 0;
+	pipe->src_x = 0;
+	pipe->dst_y = 0;
+	pipe->dst_x = 0;
+	pipe->srcp0_addr = (uint32)src;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_overlay_reg_flush(pipe, 1);
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_dmap_xy(pipe);
+
+	mdp4_overlay_dmap_cfg(mfd, 0);
+
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_dsi_cmd_blt_start(struct msm_fb_data_type *mfd)
+{
+	mdp4_dsi_cmd_do_blt(mfd, 1);
+}
+
+void mdp4_dsi_cmd_blt_stop(struct msm_fb_data_type *mfd)
+{
+	mdp4_dsi_cmd_do_blt(mfd, 0);
+}
+
+void mdp4_dsi_cmd_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	mdp4_dsi_cmd_do_blt(mfd, req->enable);
+}
+
+int mdp4_dsi_cmd_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	int cndx = 0;
+	struct msm_fb_data_type *mfd;
+	struct vsycn_ctrl *vctrl;
+
+	pr_info("%s+:\n", __func__);
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	vctrl = &vsync_ctrl_db[cndx];
+	vctrl->mfd = mfd;
+	vctrl->dev = mfd->fbi->dev;
+
+	mdp_clk_ctrl(1);
+	vsync_irq_enable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
+
+	if (vctrl->base_pipe == NULL)
+		mdp4_overlay_update_dsi_cmd(mfd);
+
+	mdp4_iommu_attach();
+
+	atomic_set(&vctrl->suspend, 0);
+	pr_info("%s-:\n", __func__);
+
+
+	return ret;
+}
+
+int mdp4_dsi_cmd_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	int cndx = 0;
+	struct msm_fb_data_type *mfd;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	pr_info("%s+:\n", __func__);
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+	if (pipe == NULL) {
+		pr_err("%s: NO base pipe\n", __func__);
+		return ret;
+	}
+
+	atomic_set(&vctrl->suspend, 1);
+
+	/* sanity check, free pipes besides base layer */
+	mdp4_overlay_unset_mixer(pipe->mixer_num);
+	mdp4_mixer_stage_down(pipe);
+	mdp4_overlay_pipe_free(pipe);
+	vctrl->base_pipe = NULL;
+
+	vctrl->fake_vsync = 1;
+
+	vsync_irq_disable(INTR_PRIMARY_RDPTR, MDP_PRIM_RDPTR_TERM);
+
+	pr_info("%s-:\n", __func__);
+
+	/*
+	 * footswitch off
+	 * this will casue all mdp register
+	 * to be reset to default
+	 * after footswitch on later
+	 */
+
+	return ret;
+}
+
+void mdp_dsi_cmd_overlay_suspend(struct msm_fb_data_type *mfd)
+{
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+	/* dis-engage rgb0 from mixer0 */
+	if (pipe) {
+		if (mfd->ref_cnt == 0) {
+			/* adb stop */
+			if (pipe->pipe_type == OVERLAY_TYPE_BF)
+				mdp4_overlay_borderfill_stage_down(pipe);
+
+			/* pipe == rgb1 */
+			mdp4_overlay_unset_mixer(pipe->mixer_num);
+			vctrl->base_pipe = NULL;
+		} else {
+			mdp4_mixer_stage_down(pipe);
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 1);
+		}
+	}
+}
+
+void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd)
+{
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	long long xx;
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (!mfd->panel_power_on)
+		return;
+
+	vctrl->clk_control = 0;
+	pipe = vctrl->base_pipe;
+	if (pipe == NULL) {
+		pr_err("%s: NO base pipe\n", __func__);
+		return;
+	}
+
+	if (pipe->mixer_stage == MDP4_MIXER_STAGE_BASE) {
+		mdp4_mipi_vsync_enable(mfd, pipe, 0);
+		mdp4_overlay_setup_pipe_addr(mfd, pipe);
+		mdp4_dsi_cmd_pipe_queue(0, pipe);
+	}
+
+	mdp4_overlay_mdp_perf_upd(mfd, 1);
+
+	mutex_lock(&mfd->dma->ov_mutex);
+	mdp4_dsi_cmd_pipe_commit();
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	mdp4_dsi_cmd_wait4vsync(0, &xx);
+	vctrl->expire_tick = VSYNC_EXPIRE_TICK;
+	vctrl->clk_control = 1;
+
+	mdp4_overlay_mdp_perf_upd(mfd, 0);
+}
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
new file mode 100644
index 0000000..7afa8d7
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -0,0 +1,1041 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+#include <linux/ktime.h>
+#include <linux/wakelock.h>
+#include <linux/time.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+#include "mipi_dsi.h"
+
+#include <mach/iommu_domains.h>
+
+#define DSI_VIDEO_BASE	0xE0000
+
+static int first_pixel_start_x;
+static int first_pixel_start_y;
+static int dsi_video_enabled;
+
+#define MAX_CONTROLLER	1
+
+static struct vsycn_ctrl {
+	struct device *dev;
+	int inited;
+	int update_ndx;
+	int ov_koff;
+	int ov_done;
+	atomic_t suspend;
+	int wait_vsync_cnt;
+	int blt_change;
+	int blt_free;
+	int fake_vsync;
+	struct mutex update_lock;
+	struct completion ov_comp;
+	struct completion dmap_comp;
+	struct completion vsync_comp;
+	spinlock_t spin_lock;
+	struct msm_fb_data_type *mfd;
+	struct mdp4_overlay_pipe *base_pipe;
+	struct vsync_update vlist[2];
+	int vsync_irq_enabled;
+	ktime_t vsync_time;
+	struct work_struct vsync_work;
+} vsync_ctrl_db[MAX_CONTROLLER];
+
+static void vsync_irq_enable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	outp32(MDP_INTR_CLEAR, intr);
+	mdp_intr_mask |= intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_enable_irq(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	pr_debug("%s: IRQ-en done, term=%x\n", __func__, term);
+}
+
+static void vsync_irq_disable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	outp32(MDP_INTR_CLEAR, intr);
+	mdp_intr_mask &= ~intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_disable_irq_nosync(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	pr_debug("%s: IRQ-dis done, term=%x\n", __func__, term);
+}
+
+static void mdp4_overlay_dsi_video_start(void)
+{
+	if (!dsi_video_enabled) {
+		/* enable DSI block */
+		mdp4_iommu_attach();
+		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1);
+		dsi_video_enabled = 1;
+	}
+}
+
+/*
+ * mdp4_dsi_video_pipe_queue:
+ * called from thread context
+ */
+void mdp4_dsi_video_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+	struct vsycn_ctrl *vctrl;
+	struct vsync_update *vp;
+	struct mdp4_overlay_pipe *pp;
+	int undx;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	mutex_lock(&vctrl->update_lock);
+	undx =  vctrl->update_ndx;
+	vp = &vctrl->vlist[undx];
+
+	pp = &vp->plist[pipe->pipe_ndx - 1];	/* ndx start form 1 */
+
+	pr_debug("%s: vndx=%d pipe=%x ndx=%d num=%d pid=%d\n",
+		 __func__, undx, (int)pipe, pipe->pipe_ndx, pipe->pipe_num,
+		current->pid);
+
+	*pp = *pipe;	/* clone it */
+	vp->update_cnt++;
+	mutex_unlock(&vctrl->update_lock);
+	mdp4_stat.overlay_play[pipe->mixer_num]++;
+}
+
+static void mdp4_dsi_video_blt_ov_update(struct mdp4_overlay_pipe *pipe);
+static void mdp4_dsi_video_wait4dmap(int cndx);
+static void mdp4_dsi_video_wait4ov(int cndx);
+
+int mdp4_dsi_video_pipe_commit(void)
+{
+
+	int  i, undx;
+	int mixer = 0;
+	struct vsycn_ctrl *vctrl;
+	struct vsync_update *vp;
+	struct mdp4_overlay_pipe *pipe;
+	struct mdp4_overlay_pipe *real_pipe;
+	unsigned long flags;
+	int cnt = 0;
+
+	vctrl = &vsync_ctrl_db[0];
+
+	mutex_lock(&vctrl->update_lock);
+	undx =  vctrl->update_ndx;
+	vp = &vctrl->vlist[undx];
+	pipe = vctrl->base_pipe;
+	mixer = pipe->mixer_num;
+
+	if (vp->update_cnt == 0) {
+		mutex_unlock(&vctrl->update_lock);
+		return cnt;
+	}
+
+	vctrl->update_ndx++;
+	vctrl->update_ndx &= 0x01;
+	vp->update_cnt = 0;     /* reset */
+	if (vctrl->blt_free) {
+		vctrl->blt_free--;
+		if (vctrl->blt_free == 0)
+			mdp4_free_writeback_buf(vctrl->mfd, mixer);
+	}
+	mutex_unlock(&vctrl->update_lock);
+
+	/* free previous committed iommu back to pool */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (vctrl->ov_koff != vctrl->ov_done) {
+		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+		pr_err("%s: Error, frame dropped %d %d\n", __func__,
+				vctrl->ov_koff, vctrl->ov_done);
+		return 0;
+	}
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	mdp4_overlay_mdp_perf_upd(vctrl->mfd, 1);
+
+	if (vctrl->blt_change) {
+		pipe = vctrl->base_pipe;
+		spin_lock_irqsave(&vctrl->spin_lock, flags);
+		INIT_COMPLETION(vctrl->dmap_comp);
+		INIT_COMPLETION(vctrl->ov_comp);
+		vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+		mdp4_dsi_video_wait4dmap(0);
+		if (pipe->ov_blt_addr)
+			mdp4_dsi_video_wait4ov(0);
+	}
+
+	pipe = vp->plist;
+
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			cnt++;
+			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
+			if (real_pipe && real_pipe->pipe_used) {
+				/* pipe not unset */
+				mdp4_overlay_vsync_commit(pipe);
+			}
+			/* free previous iommu to freelist
+			* which will be freed at next
+			* pipe_commit
+			*/
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+
+	mdp4_mixer_stage_commit(mixer);
+
+	/* start timing generator & mmu if they are not started yet */
+	mdp4_overlay_dsi_video_start();
+
+	pipe = vctrl->base_pipe;
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (pipe->ov_blt_addr) {
+		mdp4_dsi_video_blt_ov_update(pipe);
+		pipe->ov_cnt++;
+		INIT_COMPLETION(vctrl->ov_comp);
+		vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
+		mb();
+		vctrl->ov_koff++;
+		/* kickoff overlay engine */
+		mdp4_stat.kickoff_ov0++;
+		outpdw(MDP_BASE + 0x0004, 0);
+	} else {
+		/* schedule second phase update  at dmap */
+		INIT_COMPLETION(vctrl->dmap_comp);
+		vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+	}
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	mdp4_stat.overlay_commit[pipe->mixer_num]++;
+
+	return cnt;
+}
+
+void mdp4_dsi_video_vsync_ctrl(int cndx, int enable)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (vctrl->fake_vsync) {
+		vctrl->fake_vsync = 0;
+		schedule_work(&vctrl->vsync_work);
+	}
+
+	if (vctrl->vsync_irq_enabled == enable)
+		return;
+
+	pr_debug("%s: vsync enable=%d\n", __func__, enable);
+
+	vctrl->vsync_irq_enabled = enable;
+
+	if (enable)
+		vsync_irq_enable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+	else
+		vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+}
+
+void mdp4_dsi_video_wait4vsync(int cndx, long long *vtime)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	unsigned long flags;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	if (atomic_read(&vctrl->suspend) > 0) {
+		*vtime = -1;
+		return;
+	}
+
+	/* start timing generator & mmu if they are not started yet */
+	mdp4_overlay_dsi_video_start();
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (vctrl->wait_vsync_cnt == 0)
+		INIT_COMPLETION(vctrl->vsync_comp);
+
+	vctrl->wait_vsync_cnt++;
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	wait_for_completion(&vctrl->vsync_comp);
+	mdp4_stat.wait4vsync0++;
+
+	*vtime = ktime_to_ns(vctrl->vsync_time);
+}
+
+static void mdp4_dsi_video_wait4dmap(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	wait_for_completion(&vctrl->dmap_comp);
+}
+
+
+static void mdp4_dsi_video_wait4dmap_done(int cndx)
+{
+	unsigned long flags;
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+	vctrl = &vsync_ctrl_db[cndx];
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	INIT_COMPLETION(vctrl->dmap_comp);
+	vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+	mdp4_dsi_video_wait4dmap(cndx);
+	vsync_irq_disable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+}
+
+
+static void mdp4_dsi_video_wait4ov(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	wait_for_completion(&vctrl->ov_comp);
+}
+
+static void send_vsync_work(struct work_struct *work)
+{
+	struct vsycn_ctrl *vctrl =
+			container_of(work, typeof(*vctrl), vsync_work);
+	char buf[64];
+	char *envp[2];
+
+	snprintf(buf, sizeof(buf), "VSYNC=%llu",
+			ktime_to_ns(vctrl->vsync_time));
+	envp[0] = buf;
+	envp[1] = NULL;
+	kobject_uevent_env(&vctrl->dev->kobj, KOBJ_CHANGE, envp);
+}
+
+void mdp4_dsi_vsync_init(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	pr_info("%s: ndx=%d\n", __func__, cndx);
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->inited)
+		return;
+
+	vctrl->inited = 1;
+	vctrl->update_ndx = 0;
+	mutex_init(&vctrl->update_lock);
+	init_completion(&vctrl->vsync_comp);
+	init_completion(&vctrl->dmap_comp);
+	init_completion(&vctrl->ov_comp);
+	atomic_set(&vctrl->suspend, 0);
+	spin_lock_init(&vctrl->spin_lock);
+	INIT_WORK(&vctrl->vsync_work, send_vsync_work);
+}
+
+void mdp4_dsi_video_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	vctrl->base_pipe = pipe;
+}
+
+int mdp4_dsi_video_on(struct platform_device *pdev)
+{
+	int dsi_width;
+	int dsi_height;
+	int dsi_bpp;
+	int dsi_border_clr;
+	int dsi_underflow_clr;
+	int dsi_hsync_skew;
+
+	int hsync_period;
+	int hsync_ctrl;
+	int vsync_period;
+	int display_hctl;
+	int display_v_start;
+	int display_v_end;
+	int active_hctl;
+	int active_h_start;
+	int active_h_end;
+	int active_v_start;
+	int active_v_end;
+	int ctrl_polarity;
+	int h_back_porch;
+	int h_front_porch;
+	int v_back_porch;
+	int v_front_porch;
+	int hsync_pulse_width;
+	int vsync_pulse_width;
+	int hsync_polarity;
+	int vsync_polarity;
+	int data_en_polarity;
+	int hsync_start_x;
+	int hsync_end_x;
+	uint8 *buf;
+	unsigned int buf_offset;
+	int bpp, ptype;
+	struct fb_info *fbi;
+	struct fb_var_screeninfo *var;
+	struct msm_fb_data_type *mfd;
+	struct mdp4_overlay_pipe *pipe;
+	int ret = 0;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	vctrl->mfd = mfd;
+	vctrl->dev = mfd->fbi->dev;
+	vctrl->fake_vsync = 1;
+
+	/* mdp clock on */
+	mdp_clk_ctrl(1);
+
+	fbi = mfd->fbi;
+	var = &fbi->var;
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+	buf_offset = calc_fb_offset(mfd, fbi, bpp);
+
+	if (vctrl->base_pipe == NULL) {
+		ptype = mdp4_overlay_format2type(mfd->fb_imgType);
+		if (ptype < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
+		if (pipe == NULL) {
+			printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
+			return -EBUSY;
+		}
+		pipe->pipe_used++;
+		pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
+		pipe->mixer_num  = MDP4_MIXER0;
+		pipe->src_format = mfd->fb_imgType;
+		mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_VIDEO);
+		ret = mdp4_overlay_format2pipe(pipe);
+		if (ret < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
+		vctrl->base_pipe = pipe; /* keep it */
+		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
+
+	} else {
+		pipe = vctrl->base_pipe;
+	}
+
+	if (!(mfd->cont_splash_done)) {
+		mfd->cont_splash_done = 1;
+		mdp4_dsi_video_wait4dmap_done(0);
+		MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
+		mipi_dsi_controller_cfg(0);
+	}
+
+	pipe->src_height = fbi->var.yres;
+	pipe->src_width = fbi->var.xres;
+	pipe->src_h = fbi->var.yres;
+	pipe->src_w = fbi->var.xres;
+	pipe->src_y = 0;
+	pipe->src_x = 0;
+	pipe->dst_h = fbi->var.yres;
+	pipe->dst_w = fbi->var.xres;
+	pipe->srcp0_ystride = fbi->fix.line_length;
+	pipe->bpp = bpp;
+
+	if (mfd->map_buffer) {
+		pipe->srcp0_addr = (unsigned int)mfd->map_buffer->iova[0] + \
+			buf_offset;
+			pr_debug("start 0x%lx srcp0_addr 0x%x\n", mfd->
+				map_buffer->iova[0], pipe->srcp0_addr);
+	} else {
+		pipe->srcp0_addr = (uint32)(buf + buf_offset);
+	}
+
+	pipe->dst_h = fbi->var.yres;
+	pipe->dst_w = fbi->var.xres;
+
+	mdp4_overlay_mdp_pipe_req(pipe, mfd);
+
+	atomic_set(&vctrl->suspend, 0);
+
+	mdp4_overlay_dmap_xy(pipe);	/* dma_p */
+	mdp4_overlay_dmap_cfg(mfd, 1);
+	mdp4_overlay_rgb_setup(pipe);
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+	/*
+	 * DSI timing setting
+	 */
+	h_back_porch = var->left_margin;
+	h_front_porch = var->right_margin;
+	v_back_porch = var->upper_margin;
+	v_front_porch = var->lower_margin;
+	hsync_pulse_width = var->hsync_len;
+	vsync_pulse_width = var->vsync_len;
+	dsi_border_clr = mfd->panel_info.lcdc.border_clr;
+	dsi_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
+	dsi_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
+	dsi_width = mfd->panel_info.xres +
+		mfd->panel_info.lcdc.xres_pad;
+	dsi_height = mfd->panel_info.yres +
+		mfd->panel_info.lcdc.yres_pad;
+	dsi_bpp = mfd->panel_info.bpp;
+
+	hsync_period = hsync_pulse_width + h_back_porch + dsi_width
+				+ h_front_porch;
+	hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
+	hsync_start_x = h_back_porch + hsync_pulse_width;
+	hsync_end_x = hsync_period - h_front_porch - 1;
+	display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+	vsync_period =
+	    (vsync_pulse_width + v_back_porch + dsi_height + v_front_porch);
+	display_v_start = ((vsync_pulse_width + v_back_porch) * hsync_period)
+				+ dsi_hsync_skew;
+	display_v_end =
+	  ((vsync_period - v_front_porch) * hsync_period) + dsi_hsync_skew - 1;
+
+	if (dsi_width != var->xres) {
+		active_h_start = hsync_start_x + first_pixel_start_x;
+		active_h_end = active_h_start + var->xres - 1;
+		active_hctl =
+		    ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
+	} else {
+		active_hctl = 0;
+	}
+
+	if (dsi_height != var->yres) {
+		active_v_start =
+		    display_v_start + first_pixel_start_y * hsync_period;
+		active_v_end = active_v_start + (var->yres) * hsync_period - 1;
+		active_v_start |= ACTIVE_START_Y_EN;
+	} else {
+		active_v_start = 0;
+		active_v_end = 0;
+	}
+
+	dsi_underflow_clr |= 0x80000000;	/* enable recovery */
+	hsync_polarity = 0;
+	vsync_polarity = 0;
+	data_en_polarity = 0;
+
+	ctrl_polarity =
+	    (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x4, hsync_ctrl);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x8, vsync_period * hsync_period);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0xc,
+				vsync_pulse_width * hsync_period);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x10, display_hctl);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x14, display_v_start);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x18, display_v_end);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x1c, active_hctl);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x20, active_v_start);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x24, active_v_end);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x28, dsi_border_clr);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x2c, dsi_underflow_clr);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	mdp_histogram_ctrl_all(TRUE);
+	return ret;
+}
+
+int mdp4_dsi_video_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	int cndx = 0;
+	struct msm_fb_data_type *mfd;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	atomic_set(&vctrl->suspend, 1);
+
+	while (vctrl->wait_vsync_cnt)
+		msleep(20);	/* >= 17 ms */
+
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
+
+	dsi_video_enabled = 0;
+
+	mdp_histogram_ctrl_all(FALSE);
+
+
+	if (pipe) {
+		/* sanity check, free pipes besides base layer */
+		mdp4_overlay_unset_mixer(pipe->mixer_num);
+		if (mfd->ref_cnt == 0) {
+			/* adb stop */
+			if (pipe->pipe_type == OVERLAY_TYPE_BF)
+				mdp4_overlay_borderfill_stage_down(pipe);
+			vctrl->base_pipe = NULL;
+		} else {
+			/* system suspending */
+			mdp4_mixer_stage_down(vctrl->base_pipe);
+			mdp4_overlay_iommu_pipe_free(
+				vctrl->base_pipe->pipe_ndx, 1);
+		}
+	}
+
+	vctrl->fake_vsync = 1;
+
+	/* mdp clock off */
+	mdp_clk_ctrl(0);
+	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return ret;
+}
+
+static __u32 msm_fb_line_length(__u32 fb_index, __u32 xres, int bpp)
+{
+	/*
+	 * The adreno GPU hardware requires that the pitch be aligned to
+	 * 32 pixels for color buffers, so for the cases where the GPU
+	 * is writing directly to fb0, the framebuffer pitch
+	 * also needs to be 32 pixel aligned
+	 */
+
+	if (fb_index == 0)
+		return ALIGN(xres, 32) * bpp;
+	else
+		return xres * bpp;
+}
+
+/* 3D side by side */
+void mdp4_dsi_video_3d_sbys(struct msm_fb_data_type *mfd,
+				struct msmfb_overlay_3d *r3d)
+{
+	struct fb_info *fbi;
+	unsigned int buf_offset;
+	int bpp;
+	uint8 *buf = NULL;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	if (vctrl->base_pipe == NULL)
+		return;
+
+	pipe = vctrl->base_pipe;
+	pipe->is_3d = r3d->is_3d;
+	pipe->src_height_3d = r3d->height;
+	pipe->src_width_3d = r3d->width;
+
+	if (pipe->is_3d)
+		mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_SIDE_BY_SIDE);
+	else
+		mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_NONE);
+
+	fbi = mfd->fbi;
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+	buf_offset = calc_fb_offset(mfd, fbi, bpp);
+
+	if (pipe->is_3d) {
+		pipe->src_height = pipe->src_height_3d;
+		pipe->src_width = pipe->src_width_3d;
+		pipe->src_h = pipe->src_height_3d;
+		pipe->src_w = pipe->src_width_3d;
+		pipe->dst_h = pipe->src_height_3d;
+		pipe->dst_w = pipe->src_width_3d;
+		pipe->srcp0_ystride = msm_fb_line_length(0,
+					pipe->src_width, bpp);
+	} else {
+		 /* 2D */
+		pipe->src_height = fbi->var.yres;
+		pipe->src_width = fbi->var.xres;
+		pipe->src_h = fbi->var.yres;
+		pipe->src_w = fbi->var.xres;
+		pipe->dst_h = fbi->var.yres;
+		pipe->dst_w = fbi->var.xres;
+		pipe->srcp0_ystride = fbi->fix.line_length;
+	}
+
+	pipe->src_y = 0;
+	pipe->src_x = 0;
+	pipe->dst_y = 0;
+	pipe->dst_x = 0;
+
+	if (mfd->map_buffer) {
+		pipe->srcp0_addr = (unsigned int)mfd->map_buffer->iova[0] + \
+			buf_offset;
+		pr_debug("start 0x%lx srcp0_addr 0x%x\n", mfd->
+			map_buffer->iova[0], pipe->srcp0_addr);
+	} else {
+		pipe->srcp0_addr = (uint32)(buf + buf_offset);
+	}
+
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_dmap_xy(pipe);
+
+	mdp4_overlay_dmap_cfg(mfd, 1);
+
+	mdp4_overlay_reg_flush(pipe, 1);
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+
+	mb();
+}
+
+static void mdp4_dsi_video_blt_ov_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+	char *overlay_base;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = 0;
+	if (pipe->ov_cnt & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr = pipe->ov_blt_addr + off;
+
+	/* overlay 0 */
+	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+	outpdw(overlay_base + 0x000c, addr);
+	outpdw(overlay_base + 0x001c, addr);
+}
+
+static void mdp4_dsi_video_blt_dmap_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = 0;
+	if (pipe->dmap_cnt & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr = pipe->dma_blt_addr + off;
+
+	/* dmap */
+	MDP_OUTP(MDP_BASE + 0x90008, addr);
+}
+
+/*
+ * mdp4_primary_vsync_dsi_video: called from isr
+ */
+void mdp4_primary_vsync_dsi_video(void)
+{
+	int cndx;
+	struct vsycn_ctrl *vctrl;
+
+
+	cndx = 0;
+	vctrl = &vsync_ctrl_db[cndx];
+	pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
+	vctrl->vsync_time = ktime_get();
+	schedule_work(&vctrl->vsync_work);
+
+	spin_lock(&vctrl->spin_lock);
+	if (vctrl->wait_vsync_cnt) {
+		complete_all(&vctrl->vsync_comp);
+		vctrl->wait_vsync_cnt = 0;
+	}
+	spin_unlock(&vctrl->spin_lock);
+}
+
+ /*
+ * mdp4_dmap_done_dsi_video: called from isr
+ */
+void mdp4_dmap_done_dsi_video(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	spin_lock(&vctrl->spin_lock);
+	vsync_irq_disable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+	if (vctrl->blt_change) {
+		mdp4_overlayproc_cfg(pipe);
+		mdp4_overlay_dmap_xy(pipe);
+		if (pipe->ov_blt_addr) {
+			mdp4_dsi_video_blt_ov_update(pipe);
+			pipe->ov_cnt++;
+			/* Prefill one frame */
+			vsync_irq_enable(INTR_OVERLAY0_DONE,
+						MDP_OVERLAY0_TERM);
+			/* kickoff overlay0 engine */
+			mdp4_stat.kickoff_ov0++;
+			vctrl->ov_koff++;	/* make up for prefill */
+			outpdw(MDP_BASE + 0x0004, 0);
+		}
+		vctrl->blt_change = 0;
+	}
+
+	complete_all(&vctrl->dmap_comp);
+	mdp4_overlay_dma_commit(cndx);
+	spin_unlock(&vctrl->spin_lock);
+}
+
+/*
+ * mdp4_overlay0_done_dsi: called from isr
+ */
+void mdp4_overlay0_done_dsi_video(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	spin_lock(&vctrl->spin_lock);
+	vsync_irq_disable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
+	vctrl->ov_done++;
+	complete_all(&vctrl->ov_comp);
+	if (pipe->ov_blt_addr == 0) {
+		spin_unlock(&vctrl->spin_lock);
+		return;
+	}
+
+	mdp4_dsi_video_blt_dmap_update(pipe);
+	pipe->dmap_cnt++;
+	spin_unlock(&vctrl->spin_lock);
+}
+
+/*
+ * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile
+ * has enough space h * w * 3 * 2
+ */
+static void mdp4_dsi_video_do_blt(struct msm_fb_data_type *mfd, int enable)
+{
+	unsigned long flag;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
+
+	if (mfd->ov0_wb_buf->write_addr == 0) {
+		pr_info("%s: no blt_base assigned\n", __func__);
+		return;
+	}
+
+	spin_lock_irqsave(&vctrl->spin_lock, flag);
+	if (enable && pipe->ov_blt_addr == 0) {
+		pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
+		pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr;
+		pipe->ov_cnt = 0;
+		pipe->dmap_cnt = 0;
+		vctrl->ov_koff = 0;
+		vctrl->ov_done = 0;
+		vctrl->blt_free = 0;
+		mdp4_stat.blt_dsi_video++;
+		vctrl->blt_change++;
+	} else if (enable == 0 && pipe->ov_blt_addr) {
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr =  0;
+		vctrl->blt_free = 4;	/* 4 commits to free wb buf */
+		vctrl->blt_change++;
+	}
+
+	pr_info("%s: changed=%d enable=%d ov_blt_addr=%x\n", __func__,
+		vctrl->blt_change, enable, (int)pipe->ov_blt_addr);
+
+	if (!vctrl->blt_change) {
+		spin_unlock_irqrestore(&vctrl->spin_lock, flag);
+		return;
+	}
+
+	spin_unlock_irqrestore(&vctrl->spin_lock, flag);
+}
+
+void mdp4_dsi_video_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	mdp4_dsi_video_do_blt(mfd, req->enable);
+}
+
+void mdp4_dsi_video_blt_start(struct msm_fb_data_type *mfd)
+{
+	mdp4_dsi_video_do_blt(mfd, 1);
+}
+
+void mdp4_dsi_video_blt_stop(struct msm_fb_data_type *mfd)
+{
+	mdp4_dsi_video_do_blt(mfd, 0);
+}
+
+void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	unsigned int buf_offset;
+	int bpp;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	if (!pipe || !mfd->panel_power_on)
+		return;
+
+	pr_debug("%s: cpu=%d pid=%d\n", __func__,
+			smp_processor_id(), current->pid);
+	if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
+		bpp = fbi->var.bits_per_pixel / 8;
+		buf = (uint8 *) fbi->fix.smem_start;
+		buf_offset = calc_fb_offset(mfd, fbi, bpp);
+
+		if (mfd->map_buffer->iova[0]) {
+			pipe->srcp0_addr = mfd->map_buffer->iova[0]
+				+ buf_offset;
+		} else
+			pipe->srcp0_addr = (uint32)(buf + buf_offset);
+
+		mdp4_dsi_video_pipe_queue(0, pipe);
+	}
+
+	mdp4_overlay_mdp_perf_upd(mfd, 1);
+
+	mutex_lock(&mfd->dma->ov_mutex);
+	mdp4_dsi_video_pipe_commit();
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	if (pipe->ov_blt_addr)
+		mdp4_dsi_video_wait4ov(0);
+	else
+		mdp4_dsi_video_wait4dmap(0);
+
+	mdp4_overlay_mdp_perf_upd(mfd, 0);
+}
+
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
new file mode 100644
index 0000000..0bd4ced
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -0,0 +1,1011 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/fb.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+
+#define DTV_BASE	0xD0000
+
+static int dtv_enabled;
+
+/*#define DEBUG*/
+#ifdef DEBUG
+static void __mdp_outp(uint32 port, uint32 value)
+{
+	uint32 in_val;
+
+	outpdw(port, value);
+	in_val = inpdw(port);
+	printk(KERN_INFO "MDP-DTV[%04x] => %08x [%08x]\n",
+		port-(uint32)(MDP_BASE + DTV_BASE), value, in_val);
+}
+
+#undef MDP_OUTP
+#define MDP_OUTP(port, value)	__mdp_outp((uint32)(port), (value))
+#endif
+
+static int first_pixel_start_x;
+static int first_pixel_start_y;
+
+void mdp4_dtv_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+#ifdef BYPASS4
+	if (hdmi_prim_display)
+		dtv_pipe = pipe;
+#endif
+}
+
+#define MAX_CONTROLLER	1
+
+static struct vsycn_ctrl {
+	struct device *dev;
+	int inited;
+	int update_ndx;
+	int dmae_intr_cnt;
+	atomic_t suspend;
+	int wait_vsync_cnt;
+	int blt_change;
+	int fake_vsync;
+	struct mutex update_lock;
+	struct completion ov_comp;
+	struct completion dmae_comp;
+	struct completion vsync_comp;
+	spinlock_t spin_lock;
+	struct mdp4_overlay_pipe *base_pipe;
+	struct vsync_update vlist[2];
+	int vsync_irq_enabled;
+	ktime_t vsync_time;
+	struct work_struct vsync_work;
+} vsync_ctrl_db[MAX_CONTROLLER];
+
+static void vsync_irq_enable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	outp32(MDP_INTR_CLEAR, intr);
+	mdp_intr_mask |= intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_enable_irq(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	pr_debug("%s: IRQ-en done, term=%x\n", __func__, term);
+}
+
+static void vsync_irq_disable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	outp32(MDP_INTR_CLEAR, intr);
+	mdp_intr_mask &= ~intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_disable_irq_nosync(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	pr_debug("%s: IRQ-dis done, term=%x\n", __func__, term);
+}
+
+void mdp4_overlay_dtv_start(void)
+{
+	if (!dtv_enabled) {
+		/* enable DTV block */
+		mdp4_iommu_attach();
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		MDP_OUTP(MDP_BASE + DTV_BASE, 1);
+		mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+		dtv_enabled = 1;
+	}
+}
+
+/*
+ * mdp4_dtv_vsync_do_update:
+ * called from thread context
+ */
+void mdp4_dtv_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+	struct vsycn_ctrl *vctrl;
+	struct vsync_update *vp;
+	struct mdp4_overlay_pipe *pp;
+	int undx;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	mutex_lock(&vctrl->update_lock);
+	undx =  vctrl->update_ndx;
+	vp = &vctrl->vlist[undx];
+
+	pp = &vp->plist[pipe->pipe_ndx - 1];	/* ndx start form 1 */
+
+	pr_debug("%s: vndx=%d pipe_ndx=%d flags=%x pid=%d\n",
+		 __func__, undx, pipe->pipe_ndx, pipe->flags, current->pid);
+
+	*pp = *pipe;	/* clone it */
+	vp->update_cnt++;
+	mutex_unlock(&vctrl->update_lock);
+	mdp4_stat.overlay_play[pipe->mixer_num]++;
+}
+
+static void mdp4_dtv_blt_ov_update(struct mdp4_overlay_pipe *pipe);
+static void mdp4_dtv_wait4dmae(int cndx);
+
+int mdp4_dtv_pipe_commit(void)
+{
+
+	int  i, undx;
+	int mixer = 0;
+	struct vsycn_ctrl *vctrl;
+	struct vsync_update *vp;
+	struct mdp4_overlay_pipe *pipe;
+	struct mdp4_overlay_pipe *real_pipe;
+	unsigned long flags;
+	int cnt = 0;
+
+	vctrl = &vsync_ctrl_db[0];
+	mutex_lock(&vctrl->update_lock);
+	undx =  vctrl->update_ndx;
+	vp = &vctrl->vlist[undx];
+	pipe = vctrl->base_pipe;
+	mixer = pipe->mixer_num;
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
+	if (vp->update_cnt == 0) {
+		mutex_unlock(&vctrl->update_lock);
+		return 0;
+	}
+
+	vctrl->update_ndx++;
+	vctrl->update_ndx &= 0x01;
+	vp->update_cnt = 0;	/* reset */
+	mutex_unlock(&vctrl->update_lock);
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			cnt++;
+			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
+			if (real_pipe && real_pipe->pipe_used) {
+				/* pipe not unset */
+				mdp4_overlay_vsync_commit(pipe);
+			}
+			/* free previous iommu to freelist
+			* which will be freed at next
+			* pipe_commit
+			*/
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+	mdp4_mixer_stage_commit(mixer);
+
+	 /* start timing generator & mmu if they are not started yet */
+	mdp4_overlay_dtv_start();
+
+	pipe = vctrl->base_pipe;
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (pipe->ov_blt_addr) {
+		mdp4_dtv_blt_ov_update(pipe);
+		pipe->blt_ov_done++;
+		vsync_irq_enable(INTR_OVERLAY1_DONE, MDP_OVERLAY1_TERM);
+		mb();
+		pipe->blt_ov_koff++;
+		/* kickoff overlay1 engine */
+		mdp4_stat.kickoff_ov1++;
+		outpdw(MDP_BASE + 0x0008, 0);
+	} else {
+		/* schedule second phase update  at dmap */
+		INIT_COMPLETION(vctrl->dmae_comp);
+		vsync_irq_enable(INTR_DMA_E_DONE, MDP_DMA_E_TERM);
+	}
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+	mdp4_stat.overlay_commit[pipe->mixer_num]++;
+
+	return cnt;
+}
+
+void mdp4_dtv_vsync_ctrl(int cndx, int enable)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (vctrl->fake_vsync) {
+		vctrl->fake_vsync = 0;
+		schedule_work(&vctrl->vsync_work);
+	}
+
+	if (vctrl->vsync_irq_enabled == enable)
+		return;
+
+	pr_debug("%s: vsync enable=%d\n", __func__, enable);
+
+	vctrl->vsync_irq_enabled = enable;
+
+	if (enable)
+		vsync_irq_enable(INTR_EXTERNAL_VSYNC, MDP_EXTER_VSYNC_TERM);
+	else
+		vsync_irq_disable(INTR_EXTERNAL_VSYNC, MDP_EXTER_VSYNC_TERM);
+}
+
+void mdp4_dtv_wait4vsync(int cndx, long long *vtime)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	unsigned long flags;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+
+	if (vctrl->wait_vsync_cnt == 0)
+		INIT_COMPLETION(vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt++;
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	wait_for_completion(&vctrl->vsync_comp);
+	mdp4_stat.wait4vsync1++;
+
+	*vtime = ktime_to_ns(vctrl->vsync_time);
+}
+
+static void mdp4_dtv_wait4dmae(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	wait_for_completion(&vctrl->dmae_comp);
+}
+
+static void send_vsync_work(struct work_struct *work)
+{
+	struct vsycn_ctrl *vctrl =
+		container_of(work, typeof(*vctrl), vsync_work);
+	char buf[64];
+	char *envp[2];
+
+	snprintf(buf, sizeof(buf), "VSYNC=%llu",
+			ktime_to_ns(vctrl->vsync_time));
+	envp[0] = buf;
+	envp[1] = NULL;
+	kobject_uevent_env(&vctrl->dev->kobj, KOBJ_CHANGE, envp);
+}
+
+void mdp4_dtv_vsync_init(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	pr_info("%s: ndx=%d\n", __func__, cndx);
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->inited)
+		return;
+
+	vctrl->inited = 1;
+	vctrl->update_ndx = 0;
+	mutex_init(&vctrl->update_lock);
+	init_completion(&vctrl->vsync_comp);
+	init_completion(&vctrl->ov_comp);
+	init_completion(&vctrl->dmae_comp);
+	atomic_set(&vctrl->suspend, 0);
+	spin_lock_init(&vctrl->spin_lock);
+	INIT_WORK(&vctrl->vsync_work, send_vsync_work);
+}
+
+static int mdp4_dtv_start(struct msm_fb_data_type *mfd)
+{
+	int dtv_width;
+	int dtv_height;
+	int dtv_bpp;
+	int dtv_border_clr;
+	int dtv_underflow_clr;
+	int dtv_hsync_skew;
+
+	int hsync_period;
+	int hsync_ctrl;
+	int vsync_period;
+	int display_hctl;
+	int display_v_start;
+	int display_v_end;
+	int active_hctl;
+	int active_h_start;
+	int active_h_end;
+	int active_v_start;
+	int active_v_end;
+	int ctrl_polarity;
+	int h_back_porch;
+	int h_front_porch;
+	int v_back_porch;
+	int v_front_porch;
+	int hsync_pulse_width;
+	int vsync_pulse_width;
+	int hsync_polarity;
+	int vsync_polarity;
+	int data_en_polarity;
+	int hsync_start_x;
+	int hsync_end_x;
+	struct fb_info *fbi;
+	struct fb_var_screeninfo *var;
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	fbi = mfd->fbi;
+	var = &fbi->var;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	if (hdmi_prim_display) {
+		if (is_mdp4_hw_reset()) {
+			mdp4_hw_init();
+			outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+		}
+	}
+	mdp4_overlay_dmae_cfg(mfd, 0);
+
+	/*
+	 * DTV timing setting
+	 */
+	h_back_porch = var->left_margin;
+	h_front_porch = var->right_margin;
+	v_back_porch = var->upper_margin;
+	v_front_porch = var->lower_margin;
+	hsync_pulse_width = var->hsync_len;
+	vsync_pulse_width = var->vsync_len;
+	dtv_border_clr = mfd->panel_info.lcdc.border_clr;
+	dtv_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
+	dtv_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
+
+	pr_info("%s: <ID=%d %dx%d (%d,%d,%d), (%d,%d,%d) %dMHz>\n", __func__,
+		var->reserved[3], var->xres, var->yres,
+		var->right_margin, var->hsync_len, var->left_margin,
+		var->lower_margin, var->vsync_len, var->upper_margin,
+		var->pixclock/1000/1000);
+
+	dtv_width = var->xres;
+	dtv_height = var->yres;
+	dtv_bpp = mfd->panel_info.bpp;
+
+	hsync_period =
+	    hsync_pulse_width + h_back_porch + dtv_width + h_front_porch;
+	hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
+	hsync_start_x = hsync_pulse_width + h_back_porch;
+	hsync_end_x = hsync_period - h_front_porch - 1;
+	display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+	vsync_period =
+	    (vsync_pulse_width + v_back_porch + dtv_height +
+	     v_front_porch) * hsync_period;
+	display_v_start =
+	    (vsync_pulse_width + v_back_porch) * hsync_period + dtv_hsync_skew;
+	display_v_end =
+	    vsync_period - (v_front_porch * hsync_period) + dtv_hsync_skew - 1;
+
+	if (dtv_width != var->xres) {
+		active_h_start = hsync_start_x + first_pixel_start_x;
+		active_h_end = active_h_start + var->xres - 1;
+		active_hctl =
+		    ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
+	} else {
+		active_hctl = 0;
+	}
+
+	if (dtv_height != var->yres) {
+		active_v_start =
+		    display_v_start + first_pixel_start_y * hsync_period;
+		active_v_end = active_v_start + (var->yres) * hsync_period - 1;
+		active_v_start |= ACTIVE_START_Y_EN;
+	} else {
+		active_v_start = 0;
+		active_v_end = 0;
+	}
+
+	dtv_underflow_clr |= 0x80000000;	/* enable recovery */
+	hsync_polarity = fbi->var.yres >= 720 ? 0 : 1;
+	vsync_polarity = fbi->var.yres >= 720 ? 0 : 1;
+	data_en_polarity = 0;
+
+	ctrl_polarity =
+	    (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);
+
+
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x4, hsync_ctrl);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x8, vsync_period);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0xc, vsync_pulse_width * hsync_period);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x18, display_hctl);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x1c, display_v_start);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x20, display_v_end);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x40, dtv_border_clr);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x44, dtv_underflow_clr);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x48, dtv_hsync_skew);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x50, ctrl_polarity);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x2c, active_hctl);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x30, active_v_start);
+	MDP_OUTP(MDP_BASE + DTV_BASE + 0x38, active_v_end);
+
+	/* Test pattern 8 x 8 pixel */
+	/* MDP_OUTP(MDP_BASE + DTV_BASE + 0x4C, 0x80000808); */
+
+	/* enable DTV block */
+	MDP_OUTP(MDP_BASE + DTV_BASE, 1);
+
+	return 0;
+}
+
+static int mdp4_dtv_stop(struct msm_fb_data_type *mfd)
+{
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->base_pipe == NULL)
+		return -EINVAL;
+
+	MDP_OUTP(MDP_BASE + DTV_BASE, 0);
+
+	return 0;
+}
+
+int mdp4_dtv_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	int ret = 0;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	vctrl->dev = mfd->fbi->dev;
+	vctrl->fake_vsync = 1;
+
+	mdp_footswitch_ctrl(TRUE);
+	/* Mdp clock enable */
+	mdp_clk_ctrl(1);
+
+	mdp4_overlay_panel_mode(MDP4_MIXER1, MDP4_PANEL_DTV);
+
+	/* Allocate dtv_pipe at dtv_on*/
+	if (vctrl->base_pipe == NULL) {
+		if (mdp4_overlay_dtv_set(mfd, NULL)) {
+			pr_warn("%s: dtv_pipe is NULL, dtv_set failed\n",
+				__func__);
+			return -EINVAL;
+		}
+	}
+
+	ret = panel_next_on(pdev);
+	if (ret != 0)
+		pr_warn("%s: panel_next_on failed", __func__);
+
+	atomic_set(&vctrl->suspend, 0);
+
+	pr_info("%s:\n", __func__);
+
+	return ret;
+}
+
+int mdp4_dtv_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	int ret = 0;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	atomic_set(&vctrl->suspend, 1);
+
+	while (vctrl->wait_vsync_cnt)
+		msleep(20);	/* >= 17 ms */
+
+	pipe = vctrl->base_pipe;
+	if (pipe != NULL) {
+		mdp4_dtv_stop(mfd);
+		/* sanity check, free pipes besides base layer */
+		mdp4_overlay_unset_mixer(pipe->mixer_num);
+		if (hdmi_prim_display && mfd->ref_cnt == 0) {
+			/* adb stop */
+			if (pipe->pipe_type == OVERLAY_TYPE_BF)
+				mdp4_overlay_borderfill_stage_down(pipe);
+
+			/* pipe == rgb2 */
+			vctrl->base_pipe = NULL;
+		} else {
+			mdp4_mixer_stage_down(pipe);
+			mdp4_overlay_pipe_free(pipe);
+			vctrl->base_pipe = NULL;
+		}
+	}
+
+	mdp4_overlay_panel_mode_unset(MDP4_MIXER1, MDP4_PANEL_DTV);
+
+	ret = panel_next_off(pdev);
+	mdp_footswitch_ctrl(FALSE);
+	vctrl->fake_vsync = 1;
+
+	/* Mdp clock disable */
+	mdp_clk_ctrl(0);
+
+	pr_info("%s:\n", __func__);
+	return ret;
+}
+
+static void mdp4_dtv_blt_ov_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+	char *overlay_base;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = 0;
+	if (pipe->blt_ov_done & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr = pipe->ov_blt_addr + off;
+
+	/* overlay 1 */
+	overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x10000 */
+	outpdw(overlay_base + 0x000c, addr);
+	outpdw(overlay_base + 0x001c, addr);
+}
+
+static void mdp4_dtv_blt_dmae_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = 0;
+	if (pipe->blt_dmap_done & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr = pipe->dma_blt_addr + off;
+
+	/* dmae */
+	MDP_OUTP(MDP_BASE + 0xb0008, addr);
+}
+
+void mdp4_overlay_dtv_set_perf(struct msm_fb_data_type *mfd)
+{
+
+}
+
+static void mdp4_overlay_dtv_alloc_pipe(struct msm_fb_data_type *mfd,
+		int32 ptype, struct vsycn_ctrl *vctrl)
+{
+	int ret = 0;
+	struct fb_info *fbi = mfd->fbi;
+	struct mdp4_overlay_pipe *pipe;
+
+	if (vctrl->base_pipe != NULL)
+		return;
+
+	pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1);
+	if (pipe == NULL) {
+		pr_err("%s: pipe_alloc failed\n", __func__);
+		return;
+	}
+	pipe->pipe_used++;
+	pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
+	pipe->mixer_num = MDP4_MIXER1;
+
+	if (ptype == OVERLAY_TYPE_BF) {
+		/* LSP_BORDER_COLOR */
+		MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5004,
+			((0x0 & 0xFFF) << 16) |	/* 12-bit B */
+			(0x0 & 0xFFF));		/* 12-bit G */
+		/* MSP_BORDER_COLOR */
+		MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5008,
+			(0x0 & 0xFFF));		/* 12-bit R */
+		pipe->src_format = MDP_ARGB_8888;
+	} else {
+		switch (mfd->ibuf.bpp) {
+		case 2:
+			pipe->src_format = MDP_RGB_565;
+			break;
+		case 3:
+			pipe->src_format = MDP_RGB_888;
+			break;
+		case 4:
+		default:
+			if (hdmi_prim_display)
+				pipe->src_format = MSMFB_DEFAULT_TYPE;
+			else
+				pipe->src_format = MDP_ARGB_8888;
+			break;
+		}
+	}
+
+	pipe->src_height = fbi->var.yres;
+	pipe->src_width = fbi->var.xres;
+	pipe->src_h = fbi->var.yres;
+	pipe->src_w = fbi->var.xres;
+	pipe->dst_h = fbi->var.yres;
+	pipe->dst_w = fbi->var.xres;
+	pipe->src_y = 0;
+	pipe->src_x = 0;
+	pipe->dst_h = fbi->var.yres;
+	pipe->dst_w = fbi->var.xres;
+	pipe->srcp0_ystride = fbi->fix.line_length;
+
+	mdp4_overlay_mdp_pipe_req(pipe, mfd);
+
+	ret = mdp4_overlay_format2pipe(pipe);
+	if (ret < 0)
+		pr_warn("%s: format2type failed\n", __func__);
+
+	mdp4_overlay_dmae_xy(pipe);	/* dma_e */
+	mdp4_overlayproc_cfg(pipe);
+
+	if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
+		pipe->srcp0_addr = (uint32) mfd->ibuf.buf;
+		mdp4_overlay_rgb_setup(pipe);
+	}
+
+	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+	vctrl->base_pipe = pipe; /* keep it */
+}
+
+int mdp4_overlay_dtv_set(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->base_pipe != NULL)
+		return 0;
+
+	if (pipe != NULL && pipe->mixer_stage == MDP4_MIXER_STAGE_BASE &&
+			pipe->pipe_type == OVERLAY_TYPE_RGB)
+		vctrl->base_pipe = pipe; /* keep it */
+	else if (!hdmi_prim_display && mdp4_overlay_borderfill_supported())
+		mdp4_overlay_dtv_alloc_pipe(mfd, OVERLAY_TYPE_BF, vctrl);
+	else
+		mdp4_overlay_dtv_alloc_pipe(mfd, OVERLAY_TYPE_RGB, vctrl);
+
+
+	if (vctrl->base_pipe == NULL)
+		return -ENODEV;
+
+	mdp4_init_writeback_buf(mfd, MDP4_MIXER1);
+	vctrl->base_pipe->ov_blt_addr = 0;
+	vctrl->base_pipe->dma_blt_addr = 0;
+
+	return mdp4_dtv_start(mfd);
+}
+
+int mdp4_overlay_dtv_unset(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+	int result = 0;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->base_pipe != NULL)
+		return 0;
+
+	if (pipe->mixer_stage == MDP4_MIXER_STAGE_BASE &&
+			pipe->pipe_type == OVERLAY_TYPE_RGB) {
+		result = mdp4_dtv_stop(mfd);
+		vctrl->base_pipe = NULL;
+	}
+	return result;
+}
+
+/* TODO: dtv writeback need to be added later */
+
+void mdp4_external_vsync_dtv(void)
+{
+	int cndx;
+	struct vsycn_ctrl *vctrl;
+
+	cndx = 0;
+	vctrl = &vsync_ctrl_db[cndx];
+	pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
+	vctrl->vsync_time = ktime_get();
+	schedule_work(&vctrl->vsync_work);
+
+	spin_lock(&vctrl->spin_lock);
+	if (vctrl->wait_vsync_cnt) {
+		complete_all(&vctrl->vsync_comp);
+		vctrl->wait_vsync_cnt = 0;
+	}
+	spin_unlock(&vctrl->spin_lock);
+}
+
+/*
+ * mdp4_dmae_done_dtv: called from isr
+ */
+void mdp4_dmae_done_dtv(void)
+{
+	int cndx;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	cndx = 0;
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+	pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
+
+	spin_lock(&vctrl->spin_lock);
+	if (vctrl->blt_change) {
+		if (pipe->ov_blt_addr) {
+			mdp4_overlayproc_cfg(pipe);
+			mdp4_overlay_dmae_xy(pipe);
+			mdp4_dtv_blt_ov_update(pipe);
+			pipe->blt_ov_done++;
+
+			/* Prefill one frame */
+			vsync_irq_enable(INTR_OVERLAY1_DONE, MDP_OVERLAY1_TERM);
+			/* kickoff overlay1 engine */
+			mdp4_stat.kickoff_ov1++;
+			outpdw(MDP_BASE + 0x0008, 0);
+		}
+		vctrl->blt_change = 0;
+	}
+
+	complete_all(&vctrl->dmae_comp);
+	mdp4_overlay_dma_commit(MDP4_MIXER1);
+	vsync_irq_disable(INTR_DMA_E_DONE, MDP_DMA_E_TERM);
+	spin_unlock(&vctrl->spin_lock);
+}
+
+/*
+ * mdp4_overlay1_done_dtv: called from isr
+ */
+void mdp4_overlay1_done_dtv(void)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	int cndx = 0;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	spin_lock(&vctrl->spin_lock);
+	if (pipe->ov_blt_addr == 0) {
+		spin_unlock(&vctrl->spin_lock);
+		return;
+	}
+
+	mdp4_dtv_blt_dmae_update(pipe);
+	pipe->blt_dmap_done++;
+	vsync_irq_disable(INTR_OVERLAY1_DONE, MDP_OVERLAY1_TERM);
+	spin_unlock(&vctrl->spin_lock);
+}
+
+void mdp4_dtv_set_black_screen(void)
+{
+	char *rgb_base;
+	/*Black color*/
+	uint32 color = 0x00000000;
+	uint32 temp_src_format;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->base_pipe == NULL || !hdmi_prim_display) {
+		pr_err("dtv_pipe is not configured yet\n");
+		return;
+	}
+	rgb_base = MDP_BASE + MDP4_RGB_BASE;
+	rgb_base += (MDP4_RGB_OFF * vctrl->base_pipe->pipe_num);
+
+	/*
+	* RGB Constant Color
+	*/
+	MDP_OUTP(rgb_base + 0x1008, color);
+	/*
+	* MDP_RGB_SRC_FORMAT
+	*/
+	temp_src_format = inpdw(rgb_base + 0x0050);
+	MDP_OUTP(rgb_base + 0x0050, temp_src_format | BIT(22));
+	mdp4_overlay_reg_flush(vctrl->base_pipe, 1);
+	mdp4_mixer_stage_up(vctrl->base_pipe);
+	mdp4_mixer_stage_commit(vctrl->base_pipe->mixer_num);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+static void mdp4_dtv_do_blt(struct msm_fb_data_type *mfd, int enable)
+{
+	unsigned long flag;
+	int data;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER1);
+
+	if (!mfd->ov1_wb_buf->write_addr) {
+		pr_info("%s: ctrl=%d blt_base NOT assigned\n", __func__, cndx);
+		return;
+	}
+
+	spin_lock_irqsave(&vctrl->spin_lock, flag);
+	if (enable && pipe->ov_blt_addr == 0) {
+		pipe->ov_blt_addr = mfd->ov1_wb_buf->write_addr;
+		pipe->dma_blt_addr = mfd->ov1_wb_buf->read_addr;
+		pipe->blt_cnt = 0;
+		pipe->ov_cnt = 0;
+		pipe->blt_dmap_done = 0;
+		pipe->blt_ov_koff = 0;
+		pipe->blt_ov_done = 0;
+		mdp4_stat.blt_dtv++;
+		vctrl->blt_change++;
+	} else if (enable == 0 && pipe->ov_blt_addr) {
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
+		vctrl->blt_change++;
+	}
+
+	pr_info("%s: enable=%d change=%d blt_addr=%x\n", __func__,
+		enable, vctrl->blt_change, (int)pipe->ov_blt_addr);
+
+	if (!vctrl->blt_change) {
+		spin_unlock_irqrestore(&vctrl->spin_lock, flag);
+		return;
+	}
+
+	atomic_set(&vctrl->suspend, 1);
+	spin_unlock_irqrestore(&vctrl->spin_lock, flag);
+
+	data = inpdw(MDP_BASE + DTV_BASE);
+	data &= 0x01;
+	if (data)       /* timing generator enabled */
+		mdp4_dtv_wait4dmae(0);
+
+	if (pipe->ov_blt_addr == 0) {
+		MDP_OUTP(MDP_BASE + DTV_BASE, 0);       /* stop dtv */
+		msleep(20);
+		mdp4_overlayproc_cfg(pipe);
+		mdp4_overlay_dmae_xy(pipe);
+		MDP_OUTP(MDP_BASE + DTV_BASE, 1);       /* start dtv */
+	}
+
+	atomic_set(&vctrl->suspend, 0);
+}
+
+void mdp4_dtv_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+	mdp4_dtv_do_blt(mfd, 1);
+}
+
+void mdp4_dtv_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	mdp4_dtv_do_blt(mfd, 0);
+}
+
+void mdp4_dtv_overlay(struct msm_fb_data_type *mfd)
+{
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	if (!mfd->panel_power_on)
+		return;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->base_pipe == NULL)
+		mdp4_overlay_dtv_set(mfd, NULL);
+
+	pipe = vctrl->base_pipe;
+
+	if (pipe == NULL) {
+		pr_warn("%s: dtv_pipe == NULL\n", __func__);
+		return;
+	}
+
+	if (hdmi_prim_display && (pipe->pipe_used == 0 ||
+			pipe->mixer_stage != MDP4_MIXER_STAGE_BASE)) {
+		pr_err("%s: NOT baselayer\n", __func__);
+		mutex_unlock(&mfd->dma->ov_mutex);
+		return;
+	}
+
+	if (pipe->pipe_type == OVERLAY_TYPE_RGB)  {
+		pipe->srcp0_addr = (uint32)mfd->ibuf.buf;
+		mdp4_dtv_pipe_queue(0, pipe);
+	}
+
+	mutex_lock(&mfd->dma->ov_mutex);
+	mdp4_dtv_pipe_commit();
+	mutex_unlock(&mfd->dma->ov_mutex);
+}
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
new file mode 100644
index 0000000..dd5b67e
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -0,0 +1,911 @@
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+
+#include <linux/fb.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+
+#ifdef CONFIG_FB_MSM_MDP40
+#define LCDC_BASE	0xC0000
+#else
+#define LCDC_BASE	0xE0000
+#endif
+
+int first_pixel_start_x;
+int first_pixel_start_y;
+
+static int lcdc_enabled;
+
+#define MAX_CONTROLLER	1
+
+static struct vsycn_ctrl {
+	struct device *dev;
+	int inited;
+	int update_ndx;
+	int ov_koff;
+	int ov_done;
+	atomic_t suspend;
+	int wait_vsync_cnt;
+	int blt_change;
+	int blt_free;
+	int fake_vsync;
+	struct mutex update_lock;
+	struct completion ov_comp;
+	struct completion dmap_comp;
+	struct completion vsync_comp;
+	spinlock_t spin_lock;
+	struct msm_fb_data_type *mfd;
+	struct mdp4_overlay_pipe *base_pipe;
+	struct vsync_update vlist[2];
+	int vsync_irq_enabled;
+	ktime_t vsync_time;
+	struct work_struct vsync_work;
+} vsync_ctrl_db[MAX_CONTROLLER];
+
+
+/*******************************************************
+to do:
+1) move vsync_irq_enable/vsync_irq_disable to mdp.c to be shared
+*******************************************************/
+static void vsync_irq_enable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	outp32(MDP_INTR_CLEAR, intr);
+	mdp_intr_mask |= intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_enable_irq(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	pr_debug("%s: IRQ-en done, term=%x\n", __func__, term);
+}
+
+static void vsync_irq_disable(int intr, int term)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	outp32(MDP_INTR_CLEAR, intr);
+	mdp_intr_mask &= ~intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	mdp_disable_irq_nosync(term);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	pr_debug("%s: IRQ-dis done, term=%x\n", __func__, term);
+}
+
+static void mdp4_overlay_lcdc_start(void)
+{
+	if (!lcdc_enabled) {
+		/* enable DSI block */
+		mdp4_iommu_attach();
+		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		MDP_OUTP(MDP_BASE + LCDC_BASE, 1);
+		lcdc_enabled = 1;
+	}
+}
+
+/*
+ * mdp4_lcdc_pipe_queue:
+ * called from thread context
+ */
+void mdp4_lcdc_pipe_queue(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+	struct vsycn_ctrl *vctrl;
+	struct vsync_update *vp;
+	struct mdp4_overlay_pipe *pp;
+	int undx;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	mutex_lock(&vctrl->update_lock);
+	undx =  vctrl->update_ndx;
+	vp = &vctrl->vlist[undx];
+
+	pp = &vp->plist[pipe->pipe_ndx - 1];	/* ndx start form 1 */
+
+	pr_debug("%s: vndx=%d pipe_ndx=%d pid=%d\n", __func__,
+			undx, pipe->pipe_ndx, current->pid);
+
+	*pp = *pipe;	/* clone it */
+	vp->update_cnt++;
+	mutex_unlock(&vctrl->update_lock);
+	mdp4_stat.overlay_play[pipe->mixer_num]++;
+}
+
+static void mdp4_lcdc_blt_ov_update(struct mdp4_overlay_pipe *pipe);
+static void mdp4_lcdc_wait4dmap(int cndx);
+static void mdp4_lcdc_wait4ov(int cndx);
+
+int mdp4_lcdc_pipe_commit(void)
+{
+
+	int  i, undx;
+	int mixer = 0;
+	struct vsycn_ctrl *vctrl;
+	struct vsync_update *vp;
+	struct mdp4_overlay_pipe *pipe;
+	struct mdp4_overlay_pipe *real_pipe;
+	unsigned long flags;
+	int cnt = 0;
+
+	vctrl = &vsync_ctrl_db[0];
+
+	mutex_lock(&vctrl->update_lock);
+	undx =  vctrl->update_ndx;
+	vp = &vctrl->vlist[undx];
+	pipe = vctrl->base_pipe;
+	mixer = pipe->mixer_num;
+
+	if (vp->update_cnt == 0) {
+		mutex_unlock(&vctrl->update_lock);
+		return 0;
+	}
+
+	vctrl->update_ndx++;
+	vctrl->update_ndx &= 0x01;
+	vp->update_cnt = 0;     /* reset */
+	if (vctrl->blt_free) {
+		vctrl->blt_free--;
+		if (vctrl->blt_free == 0)
+			mdp4_free_writeback_buf(vctrl->mfd, mixer);
+	}
+	mutex_unlock(&vctrl->update_lock);
+
+	/* free previous committed iommu back to pool */
+	mdp4_overlay_iommu_unmap_freelist(mixer);
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (vctrl->ov_koff != vctrl->ov_done) {
+		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+		pr_err("%s: Error, frame dropped %d %d\n", __func__,
+			vctrl->ov_koff, vctrl->ov_done);
+		return 0;
+	}
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	mdp4_overlay_mdp_perf_upd(vctrl->mfd, 1);
+
+	if (vctrl->blt_change) {
+		pipe = vctrl->base_pipe;
+		spin_lock_irqsave(&vctrl->spin_lock, flags);
+		INIT_COMPLETION(vctrl->dmap_comp);
+		INIT_COMPLETION(vctrl->ov_comp);
+		vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+		mdp4_lcdc_wait4dmap(0);
+		if (pipe->ov_blt_addr)
+			mdp4_lcdc_wait4ov(0);
+	}
+
+	pipe = vp->plist;
+	for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+		if (pipe->pipe_used) {
+			cnt++;
+			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
+			if (real_pipe && real_pipe->pipe_used) {
+				/* pipe not unset */
+				mdp4_overlay_vsync_commit(pipe);
+			}
+			/* free previous iommu to freelist
+			 * which will be freed at next
+			 * pipe_commit
+			 */
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
+			pipe->pipe_used = 0; /* clear */
+		}
+	}
+
+	mdp4_mixer_stage_commit(mixer);
+
+	/* start timing generator & mmu if they are not started yet */
+	mdp4_overlay_lcdc_start();
+
+	pipe = vctrl->base_pipe;
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+	if (pipe->ov_blt_addr) {
+		mdp4_lcdc_blt_ov_update(pipe);
+		pipe->ov_cnt++;
+		INIT_COMPLETION(vctrl->ov_comp);
+		vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
+		mb();
+		vctrl->ov_koff++;
+		/* kickoff overlay engine */
+		mdp4_stat.kickoff_ov0++;
+		outpdw(MDP_BASE + 0x0004, 0);
+	} else {
+		/* schedule second phase update  at dmap */
+		INIT_COMPLETION(vctrl->dmap_comp);
+		vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+	}
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	mdp4_stat.overlay_commit[pipe->mixer_num]++;
+
+	return cnt;
+}
+
+void mdp4_lcdc_vsync_ctrl(int cndx, int enable)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (vctrl->fake_vsync) {
+		vctrl->fake_vsync = 0;
+		schedule_work(&vctrl->vsync_work);
+	}
+
+	if (vctrl->vsync_irq_enabled == enable)
+		return;
+
+	pr_debug("%s: vsync enable=%d\n", __func__, enable);
+
+	vctrl->vsync_irq_enabled = enable;
+
+	if (enable)
+		vsync_irq_enable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+	else
+		vsync_irq_disable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
+}
+
+void mdp4_lcdc_wait4vsync(int cndx, long long *vtime)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+	unsigned long flags;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	if (atomic_read(&vctrl->suspend) > 0) {
+		*vtime = -1;
+		return;
+	}
+
+	/* start timing generator & mmu if they are not started yet */
+	mdp4_overlay_lcdc_start();
+
+	spin_lock_irqsave(&vctrl->spin_lock, flags);
+
+	if (vctrl->wait_vsync_cnt == 0)
+		INIT_COMPLETION(vctrl->vsync_comp);
+	vctrl->wait_vsync_cnt++;
+	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+
+	wait_for_completion(&vctrl->vsync_comp);
+	mdp4_stat.wait4vsync0++;
+
+	*vtime = vctrl->vsync_time.tv64;
+}
+
+static void mdp4_lcdc_wait4dmap(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	wait_for_completion(&vctrl->dmap_comp);
+}
+
+static void mdp4_lcdc_wait4ov(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+
+	if (atomic_read(&vctrl->suspend) > 0)
+		return;
+
+	wait_for_completion(&vctrl->ov_comp);
+}
+
+static void send_vsync_work(struct work_struct *work)
+{
+	struct vsycn_ctrl *vctrl =
+		container_of(work, typeof(*vctrl), vsync_work);
+	char buf[64];
+	char *envp[2];
+
+	snprintf(buf, sizeof(buf), "VSYNC=%llu",
+				ktime_to_ns(vctrl->vsync_time));
+	envp[0] = buf;
+	envp[1] = NULL;
+	kobject_uevent_env(&vctrl->dev->kobj, KOBJ_CHANGE, envp);
+}
+
+void mdp4_lcdc_vsync_init(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	pr_info("%s: ndx=%d\n", __func__, cndx);
+
+	vctrl = &vsync_ctrl_db[cndx];
+	if (vctrl->inited)
+		return;
+
+	vctrl->inited = 1;
+	vctrl->update_ndx = 0;
+	mutex_init(&vctrl->update_lock);
+	init_completion(&vctrl->vsync_comp);
+	init_completion(&vctrl->dmap_comp);
+	init_completion(&vctrl->ov_comp);
+	atomic_set(&vctrl->suspend, 0);
+	spin_lock_init(&vctrl->spin_lock);
+	INIT_WORK(&vctrl->vsync_work, send_vsync_work);
+}
+
+void mdp4_lcdc_base_swap(int cndx, struct mdp4_overlay_pipe *pipe)
+{
+	struct vsycn_ctrl *vctrl;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+
+	vctrl = &vsync_ctrl_db[cndx];
+	vctrl->base_pipe = pipe;
+}
+
+int mdp4_lcdc_on(struct platform_device *pdev)
+{
+	int lcdc_width;
+	int lcdc_height;
+	int lcdc_bpp;
+	int lcdc_border_clr;
+	int lcdc_underflow_clr;
+	int lcdc_hsync_skew;
+
+	int hsync_period;
+	int hsync_ctrl;
+	int vsync_period;
+	int display_hctl;
+	int display_v_start;
+	int display_v_end;
+	int active_hctl;
+	int active_h_start;
+	int active_h_end;
+	int active_v_start;
+	int active_v_end;
+	int ctrl_polarity;
+	int h_back_porch;
+	int h_front_porch;
+	int v_back_porch;
+	int v_front_porch;
+	int hsync_pulse_width;
+	int vsync_pulse_width;
+	int hsync_polarity;
+	int vsync_polarity;
+	int data_en_polarity;
+	int hsync_start_x;
+	int hsync_end_x;
+	uint8 *buf;
+	unsigned int buf_offset;
+	int bpp, ptype;
+	struct fb_info *fbi;
+	struct fb_var_screeninfo *var;
+	struct msm_fb_data_type *mfd;
+	struct mdp4_overlay_pipe *pipe;
+	int ret = 0;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	vctrl->mfd = mfd;
+	vctrl->dev = mfd->fbi->dev;
+	vctrl->fake_vsync = 1;
+
+	/* mdp clock on */
+	mdp_clk_ctrl(1);
+
+	fbi = mfd->fbi;
+	var = &fbi->var;
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+	buf_offset = calc_fb_offset(mfd, fbi, bpp);
+
+	if (vctrl->base_pipe == NULL) {
+		ptype = mdp4_overlay_format2type(mfd->fb_imgType);
+		if (ptype < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
+		if (pipe == NULL)
+			printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
+		pipe->pipe_used++;
+		pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
+		pipe->mixer_num  = MDP4_MIXER0;
+		pipe->src_format = mfd->fb_imgType;
+		mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_LCDC);
+		ret = mdp4_overlay_format2pipe(pipe);
+		if (ret < 0)
+			printk(KERN_INFO "%s: format2pipe failed\n", __func__);
+
+		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
+
+		vctrl->base_pipe = pipe; /* keep it */
+	} else {
+		pipe = vctrl->base_pipe;
+	}
+
+	pipe->src_height = fbi->var.yres;
+	pipe->src_width = fbi->var.xres;
+	pipe->src_h = fbi->var.yres;
+	pipe->src_w = fbi->var.xres;
+	pipe->src_y = 0;
+	pipe->src_x = 0;
+	pipe->dst_h = fbi->var.yres;
+	pipe->dst_w = fbi->var.xres;
+	if (mfd->map_buffer) {
+		pipe->srcp0_addr = (unsigned int)mfd->map_buffer->iova[0] + \
+			buf_offset;
+		pr_debug("start 0x%lx srcp0_addr 0x%x\n", mfd->
+			map_buffer->iova[0], pipe->srcp0_addr);
+	} else {
+		pipe->srcp0_addr = (uint32)(buf + buf_offset);
+	}
+
+	pipe->srcp0_ystride = fbi->fix.line_length;
+	pipe->bpp = bpp;
+
+	mdp4_overlay_mdp_pipe_req(pipe, mfd);
+
+	atomic_set(&vctrl->suspend, 0);
+
+	mdp4_overlay_dmap_xy(pipe);
+	mdp4_overlay_dmap_cfg(mfd, 1);
+	mdp4_overlay_rgb_setup(pipe);
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_reg_flush(pipe, 1);
+	mdp4_mixer_stage_up(pipe);
+
+
+	/*
+	 * LCDC timing setting
+	 */
+	h_back_porch = var->left_margin;
+	h_front_porch = var->right_margin;
+	v_back_porch = var->upper_margin;
+	v_front_porch = var->lower_margin;
+	hsync_pulse_width = var->hsync_len;
+	vsync_pulse_width = var->vsync_len;
+	lcdc_border_clr = mfd->panel_info.lcdc.border_clr;
+	lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
+	lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
+
+	lcdc_width = var->xres + mfd->panel_info.lcdc.xres_pad;
+	lcdc_height = var->yres + mfd->panel_info.lcdc.yres_pad;
+	lcdc_bpp = mfd->panel_info.bpp;
+
+	hsync_period =
+	    hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch;
+	hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
+	hsync_start_x = hsync_pulse_width + h_back_porch;
+	hsync_end_x = hsync_period - h_front_porch - 1;
+	display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+	vsync_period =
+	    (vsync_pulse_width + v_back_porch + lcdc_height +
+	     v_front_porch) * hsync_period;
+	display_v_start =
+	    (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew;
+	display_v_end =
+	    vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1;
+
+	if (lcdc_width != var->xres) {
+		active_h_start = hsync_start_x + first_pixel_start_x;
+		active_h_end = active_h_start + var->xres - 1;
+		active_hctl =
+		    ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
+	} else {
+		active_hctl = 0;
+	}
+
+	if (lcdc_height != var->yres) {
+		active_v_start =
+		    display_v_start + first_pixel_start_y * hsync_period;
+		active_v_end = active_v_start + (var->yres) * hsync_period - 1;
+		active_v_start |= ACTIVE_START_Y_EN;
+	} else {
+		active_v_start = 0;
+		active_v_end = 0;
+	}
+
+
+#ifdef CONFIG_FB_MSM_MDP40
+	hsync_polarity = 1;
+	vsync_polarity = 1;
+	lcdc_underflow_clr |= 0x80000000;	/* enable recovery */
+#else
+	hsync_polarity = 0;
+	vsync_polarity = 0;
+#endif
+	data_en_polarity = 0;
+
+	ctrl_polarity =
+	    (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x4, hsync_ctrl);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x8, vsync_period);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0xc, vsync_pulse_width * hsync_period);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x10, display_hctl);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x14, display_v_start);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x18, display_v_end);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x28, lcdc_border_clr);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x2c, lcdc_underflow_clr);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x30, lcdc_hsync_skew);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x38, ctrl_polarity);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x1c, active_hctl);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start);
+	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	mdp_histogram_ctrl_all(TRUE);
+	return ret;
+}
+
+int mdp4_lcdc_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	int cndx = 0;
+	struct msm_fb_data_type *mfd;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	atomic_set(&vctrl->suspend, 1);
+
+	while (vctrl->wait_vsync_cnt)
+		msleep(20);	/* >= 17 ms */
+
+	MDP_OUTP(MDP_BASE + LCDC_BASE, 0);
+
+	lcdc_enabled = 0;
+
+	mdp_histogram_ctrl_all(FALSE);
+
+
+	if (pipe) {
+		/* sanity check, free pipes besides base layer */
+		mdp4_overlay_unset_mixer(pipe->mixer_num);
+		if (mfd->ref_cnt == 0) {
+			/* adb stop */
+			if (pipe->pipe_type == OVERLAY_TYPE_BF)
+				mdp4_overlay_borderfill_stage_down(pipe);
+			vctrl->base_pipe = NULL;
+		} else {
+			/* system suspending */
+			mdp4_mixer_stage_down(vctrl->base_pipe);
+			mdp4_overlay_iommu_pipe_free(
+				vctrl->base_pipe->pipe_ndx, 1);
+		}
+	}
+
+	vctrl->fake_vsync = 1;
+
+	/* MDP clock disable */
+	mdp_clk_ctrl(0);
+	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return ret;
+}
+
+static void mdp4_lcdc_blt_ov_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+	char *overlay_base;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = 0;
+	if (pipe->ov_cnt & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr = pipe->ov_blt_addr + off;
+
+	/* overlay 0 */
+	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+	outpdw(overlay_base + 0x000c, addr);
+	outpdw(overlay_base + 0x001c, addr);
+}
+
+static void mdp4_lcdc_blt_dmap_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
+#else
+	bpp = 3; /* overlay ouput is RGB888 */
+#endif
+	off = 0;
+	if (pipe->dmap_cnt & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr = pipe->dma_blt_addr + off;
+
+	/* dmap */
+	MDP_OUTP(MDP_BASE + 0x90008, addr);
+}
+
+/*
+ * mdp4_primary_vsync_lcdc: called from isr
+ */
+void mdp4_primary_vsync_lcdc(void)
+{
+	int cndx;
+	struct vsycn_ctrl *vctrl;
+
+	cndx = 0;
+	vctrl = &vsync_ctrl_db[cndx];
+	pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
+	vctrl->vsync_time = ktime_get();
+	schedule_work(&vctrl->vsync_work);
+
+	spin_lock(&vctrl->spin_lock);
+	if (vctrl->wait_vsync_cnt) {
+		complete_all(&vctrl->vsync_comp);
+		vctrl->wait_vsync_cnt = 0;
+	}
+
+	spin_unlock(&vctrl->spin_lock);
+}
+
+/*
+ * mdp4_dma_p_done_lcdc: called from isr
+ */
+void mdp4_dmap_done_lcdc(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	if (cndx >= MAX_CONTROLLER) {
+		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
+		return;
+	}
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	spin_lock(&vctrl->spin_lock);
+	vsync_irq_disable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
+	if (vctrl->blt_change) {
+		mdp4_overlayproc_cfg(pipe);
+		mdp4_overlay_dmap_xy(pipe);
+		if (pipe->ov_blt_addr) {
+			mdp4_lcdc_blt_ov_update(pipe);
+			pipe->ov_cnt++;
+			/* Prefill one frame */
+			vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
+			/* kickoff overlay0 engine */
+			mdp4_stat.kickoff_ov0++;
+			vctrl->ov_koff++;       /* make up for prefill */
+			outpdw(MDP_BASE + 0x0004, 0);
+		}
+		vctrl->blt_change = 0;
+	}
+
+	complete_all(&vctrl->dmap_comp);
+	mdp4_overlay_dma_commit(cndx);
+	spin_unlock(&vctrl->spin_lock);
+}
+
+/*
+ * mdp4_overlay0_done_lcdc: called from isr
+ */
+void mdp4_overlay0_done_lcdc(int cndx)
+{
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	spin_lock(&vctrl->spin_lock);
+	vsync_irq_disable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
+	vctrl->ov_done++;
+	complete_all(&vctrl->ov_comp);
+	if (pipe->ov_blt_addr == 0) {
+		spin_unlock(&vctrl->spin_lock);
+		return;
+	}
+
+	mdp4_lcdc_blt_dmap_update(pipe);
+	pipe->dmap_cnt++;
+	spin_unlock(&vctrl->spin_lock);
+}
+
+static void mdp4_lcdc_do_blt(struct msm_fb_data_type *mfd, int enable)
+{
+	unsigned long flag;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
+
+	if (mfd->ov0_wb_buf->write_addr == 0) {
+		pr_info("%s: no blt_base assigned\n", __func__);
+		return;
+	}
+
+	spin_lock_irqsave(&vctrl->spin_lock, flag);
+	if (enable && pipe->ov_blt_addr == 0) {
+		pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
+		pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr;
+		pipe->ov_cnt = 0;
+		pipe->dmap_cnt = 0;
+		vctrl->ov_koff = 0;
+		vctrl->ov_done = 0;
+		vctrl->blt_free = 0;
+		mdp4_stat.blt_lcdc++;
+		vctrl->blt_change++;
+	} else if (enable == 0 && pipe->ov_blt_addr) {
+		pipe->ov_blt_addr = 0;
+		pipe->dma_blt_addr = 0;
+		vctrl->blt_free = 4;    /* 4 commits to free wb buf */
+		vctrl->blt_change++;
+	}
+
+	pr_info("%s: enable=%d change=%d blt_addr=%x\n", __func__,
+		vctrl->blt_change, enable, (int)pipe->ov_blt_addr);
+
+	if (!vctrl->blt_change) {
+		spin_unlock_irqrestore(&vctrl->spin_lock, flag);
+		return;
+	}
+
+	spin_unlock_irqrestore(&vctrl->spin_lock, flag);
+}
+
+void mdp4_lcdc_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	mdp4_lcdc_do_blt(mfd, req->enable);
+}
+
+void mdp4_lcdc_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+	mdp4_lcdc_do_blt(mfd, 1);
+}
+
+void mdp4_lcdc_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	mdp4_lcdc_do_blt(mfd, 0);
+}
+
+void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	unsigned int buf_offset;
+	int bpp;
+	int cndx = 0;
+	struct vsycn_ctrl *vctrl;
+	struct mdp4_overlay_pipe *pipe;
+
+
+	vctrl = &vsync_ctrl_db[cndx];
+	pipe = vctrl->base_pipe;
+
+	if (!pipe || !mfd->panel_power_on)
+		return;
+
+	pr_debug("%s: cpu=%d pid=%d\n", __func__,
+			smp_processor_id(), current->pid);
+	if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
+		bpp = fbi->var.bits_per_pixel / 8;
+		buf = (uint8 *) fbi->fix.smem_start;
+		buf_offset = calc_fb_offset(mfd, fbi, bpp);
+
+		if (mfd->map_buffer->iova[0]) {
+			pipe->srcp0_addr = mfd->map_buffer->iova[0]
+				+ buf_offset;
+		} else
+			pipe->srcp0_addr = (uint32)(buf + buf_offset);
+
+		mdp4_lcdc_pipe_queue(0, pipe);
+	}
+
+	mdp4_overlay_mdp_perf_upd(mfd, 1);
+
+	mdp4_lcdc_pipe_commit();
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	if (pipe->ov_blt_addr)
+		mdp4_lcdc_wait4ov(0);
+	else
+		mdp4_lcdc_wait4dmap(0);
+
+	mdp4_overlay_mdp_perf_upd(mfd, 0);
+}
diff --git a/drivers/video/msm/mdp4_overlay_mddi.c b/drivers/video/msm/mdp4_overlay_mddi.c
index 1f62f79..c4e144e 100644
--- a/drivers/video/msm/mdp4_overlay_mddi.c
+++ b/drivers/video/msm/mdp4_overlay_mddi.c
@@ -1,57 +1,13 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of Code Aurora Forum nor
- *       the names of its contributors may be used to endorse or promote
- *       products derived from this software without specific prior written
- *       permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * Alternatively, provided that this notice is retained in full, this software
- * may be relicensed by the recipient under the terms of the GNU General Public
- * License version 2 ("GPL") and only version 2, in which case the provisions of
- * the GPL apply INSTEAD OF those given above.  If the recipient relicenses the
- * software under the GPL, then the identification text in the MODULE_LICENSE
- * macro must be changed to reflect "GPLv2" instead of "Dual BSD/GPL".  Once a
- * recipient changes the license terms to the GPL, subsequent recipients shall
- * not relicense under alternate licensing terms, including the BSD or dual
- * BSD/GPL terms.  In addition, the following license statement immediately
- * below and between the words START and END shall also then apply when this
- * software is relicensed under the GPL:
- *
- * START
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License version 2 and only version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * END
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
@@ -73,170 +29,117 @@
 
 #include <linux/fb.h>
 
-#include <linux/msm_mdp.h>
-#include <mach/msm_fb.h>
-#include <mach/debug_display.h>
-
-#include "mdp_hw.h"
+#include "mdp.h"
+#include "msm_fb.h"
 #include "mdp4.h"
 
-static struct mdp4_overlay_pipe *mddi_pipe = NULL;
-static struct mdp_info *mddi_mdp;
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-static struct completion mddi_comp;
-static ulong blt_addr;
-#endif
+static struct mdp4_overlay_pipe *mddi_pipe;
+static struct msm_fb_data_type *mddi_mfd;
+static int busy_wait_cnt;
+
+static int vsync_start_y_adjust = 4;
+
+static int dmap_vsync_enable;
+
+void mdp_dmap_vsync_set(int enable)
+{
+	dmap_vsync_enable = enable;
+}
+
+int mdp_dmap_vsync_get(void)
+{
+	return dmap_vsync_enable;
+}
+
+void mdp4_mddi_vsync_enable(struct msm_fb_data_type *mfd,
+		struct mdp4_overlay_pipe *pipe, int which)
+{
+	uint32 start_y, data, tear_en;
+
+	tear_en = (1 << which);
+
+	if ((mfd->use_mdp_vsync) && (mfd->ibuf.vsync_enable) &&
+		(mfd->panel_info.lcd.vsync_enable)) {
+
+		if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+			/* need dmas dmap switch */
+			if (which == 0 && dmap_vsync_enable == 0 &&
+				mfd->panel_info.lcd.rev < 2) /* dma_p */
+				return;
+		}
+
+		if (vsync_start_y_adjust <= pipe->dst_y)
+			start_y = pipe->dst_y - vsync_start_y_adjust;
+		else
+			start_y = (mfd->total_lcd_lines - 1) -
+				(vsync_start_y_adjust - pipe->dst_y);
+		if (which == 0)
+			MDP_OUTP(MDP_BASE + 0x210, start_y);	/* primary */
+		else
+			MDP_OUTP(MDP_BASE + 0x214, start_y);	/* secondary */
+
+		data = inpdw(MDP_BASE + 0x20c);
+		data |= tear_en;
+		MDP_OUTP(MDP_BASE + 0x20c, data);
+	} else {
+		data = inpdw(MDP_BASE + 0x20c);
+		data &= ~tear_en;
+		MDP_OUTP(MDP_BASE + 0x20c, data);
+	}
+}
+
 #define WHOLESCREEN
 
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-void mdp4_mddi_overlay_blt(ulong addr)
+void mdp4_overlay_update_lcd(struct msm_fb_data_type *mfd)
 {
-	unsigned long flag;
-
-	spin_lock_irqsave(&mdp_spin_lock, flag);
-	if (addr) {
-		mdp_intr_mask |= INTR_DMA_P_DONE;
-		if (mddi_pipe != NULL) {
-			mdp_writel(mddi_pipe->mdp, mdp_intr_mask, MDP_INTR_ENABLE);
-			mddi_pipe->blt_cnt = 0;
-			mddi_pipe->blt_end = 0;
-			mddi_pipe->blt_addr = addr;
-		}
-		blt_addr = addr;
-	} else {
-		mddi_pipe->blt_end = 1; /* mark as end */
-		mdp4_dma_p_done_mddi();
-	}
-	spin_unlock_irqrestore(&mdp_spin_lock, flag);
-}
-void mdp4_blt_xy_update(struct mdp4_overlay_pipe *pipe)
-{
-	uint32_t off, addr;
-
-	if (pipe->blt_addr == 0)
-		return;
-
-	/* overlay ouput is RG565 */
-	off = 0;
-	if (pipe->blt_cnt & 0x01)
-		off = pipe->src_height * pipe->src_width * 2;
-
-	addr = pipe->blt_addr + off;
-
-	/* dmap */
-	mdp_writel(pipe->mdp, addr, 0x90008);
-	/* overlay 0 */
-	mdp_writel(pipe->mdp, addr, MDP4_OVERLAYPROC0_BASE + 0x000c);
-	mdp_writel(pipe->mdp, addr, MDP4_OVERLAYPROC0_BASE + 0x001c);
-}
-
-/*
- * mdp4_dmap_done_mddi: called from isr
- */
-void mdp4_dma_p_done_mddi(void)
-{
-	if (mddi_pipe->blt_end) {
-		mddi_pipe->blt_addr = 0;
-		mdp_intr_mask &= ~INTR_DMA_P_DONE;
-		mdp_writel(mddi_pipe->mdp, mdp_intr_mask, MDP_INTR_ENABLE);
-		mdp4_overlayproc_cfg(mddi_pipe);
-		mdp4_overlay_dmap_xy(mddi_pipe);
-		return;
-	}
-}
-/*
- * mdp4_overlay0_done_mddi: called from isr
- */
-void mdp4_overlay0_done_mddi(void)
-{
-	if (mddi_pipe->blt_addr) {
-		if (mddi_pipe->blt_cnt == 0) {
-			mdp4_overlayproc_cfg(mddi_pipe);
-			mdp4_overlay_dmap_xy(mddi_pipe);
-			mddi_pipe->blt_cnt++;
-			/* BLT start from next frame */
-		} else {
-			mdp4_blt_xy_update(mddi_pipe);
-			mddi_pipe->blt_cnt++;
-
-			/* start DMAP */
-			mdp_writel(mddi_pipe->mdp, 0x0, 0x000c);
-		}
-	}
-
-}
-#endif
-
-#ifdef CONFIG_MDP4_HW_VSYNC
-void mdp4_mddi_vsync_enable(struct mdp_info *mdp,
-		struct mdp4_overlay_pipe *pipe)
-{
-	uint32_t start_y, data;
-	int vsync_start_y_adjust = 4;
-
-	if (vsync_start_y_adjust <= pipe->dst_y)
-		start_y = pipe->dst_y - vsync_start_y_adjust;
-	else
-		start_y = (mdp->total_lcd_line - 1) -
-			(vsync_start_y_adjust - pipe->dst_y);
-
-	mdp_writel(mdp, start_y, 0x210);	/* primary */
-
-	data = mdp_readl(mdp, 0x20c);
-	data |= 1;
-	mdp_writel(mdp, data, 0x20c);
-}
-#endif
-
-void mdp4_overlay_update_lcd(struct mdp_info *mdp, uint32_t addr, uint32_t stride,
-			    uint32_t width, uint32_t height, uint32_t x,
-			    uint32_t y)
-{
+	MDPIBUF *iBuf = &mfd->ibuf;
+	uint8 *src;
 	int ptype;
-	uint32_t mddi_ld_param;
-	uint16_t mddi_vdo_packet_reg;
-	struct mdp4_overlay_pipe *pipe = NULL;
-	int data;
+	uint32 mddi_ld_param;
+	uint16 mddi_vdo_packet_reg;
+	struct mdp4_overlay_pipe *pipe;
+	int ret;
 
-	mddi_mdp = mdp;		/* keep it */
+	if (mfd->key != MFD_KEY)
+		return;
 
+	mddi_mfd = mfd;		/* keep it */
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
 	if (mddi_pipe == NULL) {
-
-		ptype = mdp4_overlay_format2type(MDP_RGB_565);
-		pipe = mdp4_overlay_pipe_alloc(ptype, false);
-
-		pipe->pipe_type = ptype;
-		pipe->pipe_used = 1;
-		pipe->mdp = mdp;
+		ptype = mdp4_overlay_format2type(mfd->fb_imgType);
+		if (ptype < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
+		if (pipe == NULL)
+			printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
+		pipe->pipe_used++;
 		pipe->mixer_num  = MDP4_MIXER0;
-		pipe->src_format = MDP_RGB_565;
-		mdp4_overlay_format2pipe(pipe);
+		pipe->src_format = mfd->fb_imgType;
+		mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_MDDI);
+		ret = mdp4_overlay_format2pipe(pipe);
+		if (ret < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
 
 		mddi_pipe = pipe; /* keep it */
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-		init_completion(&mddi_comp);
-		mddi_pipe->blt_cnt = 0;
-		mddi_pipe->blt_end = 0;
-		mddi_pipe->blt_addr = blt_addr;
-#endif
-
 		mddi_ld_param = 0;
+		mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
 
-		mddi_vdo_packet_reg = MDDI_VDO_PACKET_PRIM;
-		if (mdp->hw_version >= MDP4_REVISION_V2_1) {
-			data = mdp_readl(mdp, MDP_AXI_RDMASTER_CONFIG);
-			data &= ~0x0300;        /* bit 8, 9, MASTER4 */
-			if (width == 540) /* qHD, 540x960 */
+		if (mdp_hw_revision == MDP4_REVISION_V2_1) {
+			uint32	data;
+
+			data = inpdw(MDP_BASE + 0x0028);
+			data &= ~0x0300;	/* bit 8, 9, MASTER4 */
+			if (mfd->fbi->var.xres == 540) /* qHD, 540x960 */
 				data |= 0x0200;
 			else
 				data |= 0x0100;
 
-			mdp_writel(mdp, data, MDP_AXI_RDMASTER_CONFIG);
+			MDP_OUTP(MDP_BASE + 0x00028, data);
 		}
 
-/*     FIXME: currently we use only one display
-
 		if (mfd->panel_info.type == MDDI_PANEL) {
 			if (mfd->panel_info.pdest == DISPLAY_1)
 				mddi_ld_param = 0;
@@ -245,65 +148,91 @@
 		} else {
 			mddi_ld_param = 2;
 		}
-*/
-		mdp_writel(mdp, mddi_ld_param, 0x00090);
-		if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB888)
-			mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB888 << 16) | mddi_vdo_packet_reg, 0x00094);
+
+		MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param);
+
+		if (mfd->panel_info.bpp == 24)
+			MDP_OUTP(MDP_BASE + 0x00094,
+			 (MDDI_VDO_PACKET_DESC_24 << 16) | mddi_vdo_packet_reg);
+		else if (mfd->panel_info.bpp == 16)
+			MDP_OUTP(MDP_BASE + 0x00094,
+			 (MDDI_VDO_PACKET_DESC_16 << 16) | mddi_vdo_packet_reg);
 		else
-			mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | mddi_vdo_packet_reg, 0x00094);
-		mdp_writel(mdp, 0x01, 0x00098);
+			MDP_OUTP(MDP_BASE + 0x00094,
+			 (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
+
+		MDP_OUTP(MDP_BASE + 0x00098, 0x01);
+		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);
+		pipe->ov_blt_addr = 0;
 	} else {
 		pipe = mddi_pipe;
-		if (mdp->hw_version >= MDP4_REVISION_V2_1 &&
-			mdp4_overlay_status_read(MDP4_OVERLAY_TYPE_UNSET)) {
-			data = mdp_readl(mdp, MDP_AXI_RDMASTER_CONFIG);
-			data &= ~0x0300;        /* bit 8, 9, MASTER4 */
-			if (width == 540) /* qHD, 540x960 */
-				data |= 0x0200;
-			else
-				data |= 0x0100;
-			mdp_writel(mdp, data, MDP_AXI_RDMASTER_CONFIG);
-			mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_UNSET, false);
-		}
-		if (mdp->hw_version >= MDP4_REVISION_V2_1 &&
-			mdp4_overlay_status_read(MDP4_OVERLAY_TYPE_SET)) {
-			data = mdp_readl(mdp, MDP_AXI_RDMASTER_CONFIG);
-			if (data & 0x0300) {
-				data &= ~0x0300;		/* bit 8, 9, MASTER4 */
-				mdp_writel(mdp, data, MDP_AXI_RDMASTER_CONFIG);
-			}
-			mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_SET, false);
-		}
 	}
 
-	pipe->src_height = height;
-	pipe->src_width = width;
-	pipe->src_h = height;
-	pipe->src_w = width;
-	pipe->src_y = 0;
-	pipe->src_x = 0;
-	pipe->dst_h = height;
-	pipe->dst_w = width;
-	pipe->dst_y = 0;
-	pipe->dst_x = 0;
-	pipe->srcp0_addr = (uint32_t)addr;
-	pipe->srcp0_ystride = (stride + 31) & ~31;
+	/* 0 for dma_p, client_id = 0 */
+	MDP_OUTP(MDP_BASE + 0x00090, 0);
+
+
+	src = (uint8 *) iBuf->buf;
+
+#ifdef WHOLESCREEN
+
+	{
+		struct fb_info *fbi;
+
+		fbi = mfd->fbi;
+		pipe->src_height = fbi->var.yres;
+		pipe->src_width = fbi->var.xres;
+		pipe->src_h = fbi->var.yres;
+		pipe->src_w = fbi->var.xres;
+		pipe->src_y = 0;
+		pipe->src_x = 0;
+		pipe->dst_h = fbi->var.yres;
+		pipe->dst_w = fbi->var.xres;
+		pipe->dst_y = 0;
+		pipe->dst_x = 0;
+		pipe->srcp0_addr = (uint32)src;
+		pipe->srcp0_ystride = fbi->fix.line_length;
+	}
+
+#else
+	if (mdp4_overlay_active(MDP4_MIXER0)) {
+		struct fb_info *fbi;
+
+		fbi = mfd->fbi;
+		pipe->src_height = fbi->var.yres;
+		pipe->src_width = fbi->var.xres;
+		pipe->src_h = fbi->var.yres;
+		pipe->src_w = fbi->var.xres;
+		pipe->src_y = 0;
+		pipe->src_x = 0;
+		pipe->dst_h = fbi->var.yres;
+		pipe->dst_w = fbi->var.xres;
+		pipe->dst_y = 0;
+		pipe->dst_x = 0;
+		pipe->srcp0_addr = (uint32) src;
+		pipe->srcp0_ystride = fbi->fix.line_length;
+	} else {
+		/* starting input address */
+		src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width)
+					* iBuf->bpp;
+
+		pipe->src_height = iBuf->dma_h;
+		pipe->src_width = iBuf->dma_w;
+		pipe->src_h = iBuf->dma_h;
+		pipe->src_w = iBuf->dma_w;
+		pipe->src_y = 0;
+		pipe->src_x = 0;
+		pipe->dst_h = iBuf->dma_h;
+		pipe->dst_w = iBuf->dma_w;
+		pipe->dst_y = iBuf->dma_y;
+		pipe->dst_x = iBuf->dma_x;
+		pipe->srcp0_addr = (uint32) src;
+		pipe->srcp0_ystride = iBuf->ibuf_width * iBuf->bpp;
+	}
+#endif
 
 	pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
 
-	/* 16/32 bits framebuffer */
-	if (mddi_mdp->dma_config_dirty) {
-		if (mddi_mdp->dma_format == DMA_IBUF_FORMAT_RGB565) {
-			pipe->src_format = MDP_RGB_565;
-			pipe->srcp0_ystride = pipe->src_width * 2;
-		} else if (mddi_mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888) {
-			pipe->src_format = MDP_RGBA_8888;
-			pipe->srcp0_ystride = pipe->src_width * 4;
-		}
-		mdp4_overlay_format2pipe(pipe);
-		mddi_mdp->dma_config_dirty = false;
-	}
-
 	mdp4_overlay_rgb_setup(pipe);
 
 	mdp4_mixer_stage_up(pipe);
@@ -312,91 +241,507 @@
 
 	mdp4_overlay_dmap_xy(pipe);
 
-	mdp4_overlay_dmap_cfg(pipe, 0);
-#ifdef CONFIG_MDP4_HW_VSYNC
-	mdp4_mddi_vsync_enable(mdp, pipe);
-#endif
+	mdp4_overlay_dmap_cfg(mfd, 0);
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+	mdp4_mddi_vsync_enable(mfd, pipe, 0);
 
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_mddi_overlay_kickoff(struct mdp_info *mdp,
-				struct mdp4_overlay_pipe *pipe)
+int mdp4_mddi_overlay_blt_start(struct msm_fb_data_type *mfd)
 {
+	unsigned long flag;
 
-#ifdef MDP4_NONBLOCKING
-	mdp_writel(mdp, 0, 0x0004);
-#endif
-}
-void mdp4_dma_s_update_lcd(struct mdp_info *mdp)
-{
-	uint32_t mddi_ld_param = 1;
-	uint16_t mddi_vdo_packet_reg = MDDI_VDO_PACKET_PRIM;
-	struct mdp4_overlay_pipe *pipe = NULL;
+	pr_debug("%s: blt_end=%d ov_blt_addr=%x pid=%d\n",
+	__func__, mddi_pipe->blt_end, (int)mddi_pipe->ov_blt_addr, current->pid);
 
-	mddi_mdp = mdp;		/* keep it */
+	mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
 
-	pipe = mddi_pipe;
-
-	/*config PIXELSIZE*/
-	mdp4_overlay_dmas_xy(pipe);
-
-	/*config for dma_s_cfg_reg*/
-	mdp4_overlay_dmas_cfg(pipe, 0);
-
-	mdp_writel(mdp, mddi_ld_param, 0x00090);
-	mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | mddi_vdo_packet_reg, 0x00094);
-	mdp_writel(mdp, 1, 0x00098);
-}
-
-
-void mdp4_mddi_dma_s_kickoff(struct mdp_info *mdp,
-				struct mdp4_overlay_pipe *pipe)
-{
-	mdp_writel(mdp, 0, 0x00010);
-}
-
-void mdp4_mddi_overlay(void *priv, uint32_t addr, uint32_t stride,
-			    uint32_t width, uint32_t height, uint32_t x,
-			    uint32_t y)
-{
-	struct mdp_info *mdp = priv;
-
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-	if (mdp->hw_version < MDP4_REVISION_V2_1 &&
-		mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) {
-		mdp4_overlay_update_lcd(mdp, addr, stride, width, height, x, y);
-
-		if (mdp4_overlay_active(mdp, MDP4_MIXER0) > 1) {
-			mdp4_overlay0_done_mddi();
-			mdp4_mddi_overlay_kickoff(mdp, mddi_pipe);
-		} else {
-			if (mddi_pipe->blt_addr) {
-				mdp4_overlay0_done_mddi();
-				mdp4_mddi_overlay_kickoff(mdp, mddi_pipe);
-			} else {
-				mdp4_dma_s_update_lcd(mdp);
-				mdp4_mddi_dma_s_kickoff(mdp, mddi_pipe);
-			}
-		}
-	} else {
-		mdp4_overlay_update_lcd(mdp, addr, stride, width, height, x, y);
-		mdp4_overlay0_done_mddi();
-		mdp4_mddi_overlay_kickoff(mdp, mddi_pipe);
+	if (mfd->ov0_wb_buf->write_addr == 0) {
+		pr_info("%s: no blt_base assigned\n", __func__);
+		return -EBUSY;
 	}
+
+	if (mddi_pipe->ov_blt_addr == 0) {
+		mdp4_mddi_dma_busy_wait(mfd);
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mddi_pipe->blt_end = 0;
+		mddi_pipe->blt_cnt = 0;
+		mddi_pipe->ov_cnt = 0;
+		mddi_pipe->dmap_cnt = 0;
+		mddi_pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
+		mdp4_stat.blt_mddi++;
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	return 0;
+}
+
+	return -EBUSY;
+}
+
+int mdp4_mddi_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	pr_debug("%s: blt_end=%d ov_blt_addr=%x\n",
+		 __func__, mddi_pipe->blt_end, (int)mddi_pipe->ov_blt_addr);
+
+	if ((mddi_pipe->blt_end == 0) && mddi_pipe->ov_blt_addr) {
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mddi_pipe->blt_end = 1;	/* mark as end */
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		return 0;
+	}
+
+	return -EBUSY;
+}
+
+int mdp4_mddi_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	req->offset = 0;
+	req->width = mddi_pipe->src_width;
+	req->height = mddi_pipe->src_height;
+	req->bpp = mddi_pipe->bpp;
+
+	return sizeof(*req);
+}
+
+void mdp4_mddi_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	if (req->enable)
+		mdp4_mddi_overlay_blt_start(mfd);
+	else if (req->enable == 0)
+		mdp4_mddi_overlay_blt_stop(mfd);
+
+}
+
+void mdp4_blt_xy_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr, addr2;
+	int bpp;
+	char *overlay_base;
+
+	if (pipe->ov_blt_addr == 0)
+		return;
+
+
+#ifdef BLT_RGB565
+	bpp = 2; /* overlay ouput is RGB565 */
 #else
-	if (mdp->hw_version < MDP4_REVISION_V2_1 &&
-		mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) {
-		mdp4_overlay_update_lcd(mdp, addr, stride, width, height, x, y);
-		if (mdp4_overlay_active(mdp, MDP4_MIXER0) > 1)
-			mdp4_mddi_overlay_kickoff(mdp, mddi_pipe);
-		else {
-			mdp4_dma_s_update_lcd(mdp);
-			mdp4_mddi_dma_s_kickoff(mdp, mddi_pipe);
-		}
-	} else {
-		mdp4_overlay_update_lcd(mdp, addr, stride, width, height, x, y);
-		mdp4_mddi_overlay_kickoff(mdp, mddi_pipe);
-	}
+	bpp = 3; /* overlay ouput is RGB888 */
 #endif
+	off = 0;
+	if (pipe->dmap_cnt & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+
+	addr = pipe->ov_blt_addr + off;
+
+	/* dmap */
+	MDP_OUTP(MDP_BASE + 0x90008, addr);
+
+	off = 0;
+	if (pipe->ov_cnt & 0x01)
+		off = pipe->src_height * pipe->src_width * bpp;
+	addr2 = pipe->ov_blt_addr + off;
+	/* overlay 0 */
+	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+	outpdw(overlay_base + 0x000c, addr2);
+	outpdw(overlay_base + 0x001c, addr2);
 }
 
+void mdp4_primary_rdptr(void)
+{
+}
+
+/*
+ * mdp4_dmap_done_mddi: called from isr
+ */
+void mdp4_dma_p_done_mddi(struct mdp_dma_data *dma)
+{
+	int diff;
+
+	mddi_pipe->dmap_cnt++;
+	diff = mddi_pipe->ov_cnt - mddi_pipe->dmap_cnt;
+	pr_debug("%s: ov_cnt=%d dmap_cnt=%d\n",
+			__func__, mddi_pipe->ov_cnt, mddi_pipe->dmap_cnt);
+
+	if (diff <= 0) {
+		spin_lock(&mdp_spin_lock);
+		dma->dmap_busy = FALSE;
+		complete(&dma->dmap_comp);
+		spin_unlock(&mdp_spin_lock);
+
+		if (mddi_pipe->blt_end) {
+			mddi_pipe->blt_end = 0;
+			mddi_pipe->ov_blt_addr = 0;
+			pr_debug("%s: END, ov_cnt=%d dmap_cnt=%d\n", __func__,
+				mddi_pipe->ov_cnt, mddi_pipe->dmap_cnt);
+			mdp_intr_mask &= ~INTR_DMA_P_DONE;
+			outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		}
+
+		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+		mdp_disable_irq_nosync(MDP_DMA2_TERM);  /* disable intr */
+		return;
+	}
+
+	spin_lock(&mdp_spin_lock);
+	dma->busy = FALSE;
+	spin_unlock(&mdp_spin_lock);
+	complete(&dma->comp);
+	if (busy_wait_cnt)
+		busy_wait_cnt--;
+
+	pr_debug("%s: kickoff dmap\n", __func__);
+
+	mdp4_blt_xy_update(mddi_pipe);
+	/* kick off dmap */
+	outpdw(MDP_BASE + 0x000c, 0x0);
+	mdp4_stat.kickoff_dmap++;
+	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+}
+
+/*
+ * mdp4_overlay0_done_mddi: called from isr
+ */
+void mdp4_overlay0_done_mddi(struct mdp_dma_data *dma)
+{
+	int diff;
+
+	if (mddi_pipe->ov_blt_addr == 0) {
+		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+		spin_lock(&mdp_spin_lock);
+		dma->busy = FALSE;
+		spin_unlock(&mdp_spin_lock);
+		complete(&dma->comp);
+
+		if (busy_wait_cnt)
+			busy_wait_cnt--;
+		mdp_disable_irq_nosync(MDP_OVERLAY0_TERM);
+
+		return;
+	}
+
+	/* blt enabled */
+	if (mddi_pipe->blt_end == 0)
+		mddi_pipe->ov_cnt++;
+
+	pr_debug("%s: ov_cnt=%d dmap_cnt=%d\n",
+			__func__, mddi_pipe->ov_cnt, mddi_pipe->dmap_cnt);
+
+	if (mddi_pipe->blt_cnt == 0) {
+		/* first kickoff since blt enabled */
+		mdp_intr_mask |= INTR_DMA_P_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	}
+
+	mddi_pipe->blt_cnt++;
+
+	diff = mddi_pipe->ov_cnt - mddi_pipe->dmap_cnt;
+	if (diff >= 2) {
+		mdp_disable_irq_nosync(MDP_OVERLAY0_TERM);
+		return;
+	}
+
+	spin_lock(&mdp_spin_lock);
+	dma->busy = FALSE;
+	dma->dmap_busy = TRUE;
+	spin_unlock(&mdp_spin_lock);
+	complete(&dma->comp);
+
+	if (busy_wait_cnt)
+		busy_wait_cnt--;
+
+	pr_debug("%s: kickoff dmap\n", __func__);
+
+	mdp4_blt_xy_update(mddi_pipe);
+	mdp_enable_irq(MDP_DMA2_TERM);	/* enable intr */
+	/* kick off dmap */
+	outpdw(MDP_BASE + 0x000c, 0x0);
+	mdp4_stat.kickoff_dmap++;
+	mdp_disable_irq_nosync(MDP_OVERLAY0_TERM);
+}
+
+void mdp4_mddi_overlay_restore(void)
+{
+	if (mddi_mfd == NULL)
+		return;
+
+	pr_debug("%s: resotre, pid=%d\n", __func__, current->pid);
+
+	if (mddi_mfd->panel_power_on == 0)
+		return;
+	if (mddi_mfd && mddi_pipe) {
+		mdp4_mddi_dma_busy_wait(mddi_mfd);
+		mdp4_overlay_update_lcd(mddi_mfd);
+
+		if (mddi_pipe->ov_blt_addr)
+			mdp4_mddi_blt_dmap_busy_wait(mddi_mfd);
+		mdp4_mddi_overlay_kickoff(mddi_mfd, mddi_pipe);
+		mddi_mfd->dma_update_flag = 1;
+	}
+	if (mdp_hw_revision < MDP4_REVISION_V2_1) /* need dmas dmap switch */
+		mdp4_mddi_overlay_dmas_restore();
+}
+
+void mdp4_mddi_blt_dmap_busy_wait(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+	int need_wait = 0;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	if (mfd->dma->dmap_busy == TRUE) {
+		INIT_COMPLETION(mfd->dma->dmap_comp);
+		need_wait++;
+	}
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	if (need_wait) {
+		/* wait until DMA finishes the current job */
+		wait_for_completion(&mfd->dma->dmap_comp);
+	}
+}
+
+/*
+ * mdp4_mddi_cmd_dma_busy_wait: check mddi link activity
+ * mddi link is a shared resource and it can only be used
+ * while it is in idle state.
+ * ov_mutex need to be acquired before call this function.
+ */
+void mdp4_mddi_dma_busy_wait(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+	int need_wait = 0;
+
+	pr_debug("%s: START, pid=%d\n", __func__, current->pid);
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	if (mfd->dma->busy == TRUE) {
+		if (busy_wait_cnt == 0)
+			INIT_COMPLETION(mfd->dma->comp);
+		busy_wait_cnt++;
+		need_wait++;
+	}
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+
+	if (need_wait) {
+		/* wait until DMA finishes the current job */
+		pr_debug("%s: PENDING, pid=%d\n", __func__, current->pid);
+		wait_for_completion(&mfd->dma->comp);
+	}
+	pr_debug("%s: DONE, pid=%d\n", __func__, current->pid);
+}
+
+void mdp4_mddi_kickoff_video(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+	/*
+	 * a video kickoff may happen before UI kickoff after
+	 * blt enabled. mdp4_overlay_update_lcd() need
+	 * to be called before kickoff.
+	 * vice versa for blt disabled.
+	 */
+	if (mddi_pipe->ov_blt_addr && mddi_pipe->blt_cnt == 0)
+		mdp4_overlay_update_lcd(mfd); /* first time */
+	else if (mddi_pipe->ov_blt_addr == 0  && mddi_pipe->blt_cnt) {
+		mdp4_overlay_update_lcd(mfd); /* last time */
+		mddi_pipe->blt_cnt = 0;
+	}
+
+	pr_debug("%s: ov_blt_addr=%d blt_cnt=%d\n",
+		__func__, (int)mddi_pipe->ov_blt_addr, mddi_pipe->blt_cnt);
+
+	if (mddi_pipe->ov_blt_addr)
+		mdp4_mddi_blt_dmap_busy_wait(mddi_mfd);
+	mdp4_mddi_overlay_kickoff(mfd, pipe);
+}
+
+void mdp4_mddi_kickoff_ui(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+	pr_debug("%s: pid=%d\n", __func__, current->pid);
+	mdp4_mddi_overlay_kickoff(mfd, pipe);
+}
+
+
+void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+	unsigned long flag;
+
+	if (mdp_hw_revision == MDP4_REVISION_V2_1) {
+		if (mdp4_overlay_status_read(MDP4_OVERLAY_TYPE_UNSET)) {
+			uint32  data;
+			data = inpdw(MDP_BASE + 0x0028);
+			data &= ~0x0300;        /* bit 8, 9, MASTER4 */
+			if (mfd->fbi->var.xres == 540) /* qHD, 540x960 */
+				data |= 0x0200;
+			else
+				data |= 0x0100;
+			MDP_OUTP(MDP_BASE + 0x00028, data);
+			mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_UNSET,
+				false);
+		}
+		if (mdp4_overlay_status_read(MDP4_OVERLAY_TYPE_SET)) {
+			uint32  data;
+			data = inpdw(MDP_BASE + 0x0028);
+			data &= ~0x0300;        /* bit 8, 9, MASTER4 */
+			MDP_OUTP(MDP_BASE + 0x00028, data);
+			mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_SET, false);
+		}
+	}
+	mdp_enable_irq(MDP_OVERLAY0_TERM);
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mfd->dma->busy = TRUE;
+	if (mddi_pipe->ov_blt_addr)
+		mfd->dma->dmap_busy = TRUE;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	/* start OVERLAY pipe */
+	mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
+	mdp4_stat.kickoff_ov0++;
+}
+
+void mdp4_dma_s_update_lcd(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+	MDPIBUF *iBuf = &mfd->ibuf;
+	uint32 outBpp = iBuf->bpp;
+	uint16 mddi_vdo_packet_reg;
+	uint32 dma_s_cfg_reg;
+
+	dma_s_cfg_reg = 0;
+
+	if (mfd->fb_imgType == MDP_RGBA_8888)
+		dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR; /* on purpose */
+	else if (mfd->fb_imgType == MDP_BGR_565)
+		dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else
+		dma_s_cfg_reg |= DMA_PACK_PATTERN_RGB;
+
+	if (outBpp == 4)
+		dma_s_cfg_reg |= (1 << 26); /* xRGB8888 */
+	else if (outBpp == 2)
+		dma_s_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
+
+	dma_s_cfg_reg |= DMA_DITHER_EN;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	/* PIXELSIZE */
+	MDP_OUTP(MDP_BASE + 0xa0004, (pipe->dst_h << 16 | pipe->dst_w));
+	MDP_OUTP(MDP_BASE + 0xa0008, pipe->srcp0_addr);	/* ibuf address */
+	MDP_OUTP(MDP_BASE + 0xa000c, pipe->srcp0_ystride);/* ystride */
+
+	if (mfd->panel_info.bpp == 24) {
+		dma_s_cfg_reg |= DMA_DSTC0G_8BITS |	/* 666 18BPP */
+		    DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
+	} else if (mfd->panel_info.bpp == 18) {
+		dma_s_cfg_reg |= DMA_DSTC0G_6BITS |	/* 666 18BPP */
+		    DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+	} else {
+		dma_s_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
+		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
+	}
+
+	MDP_OUTP(MDP_BASE + 0xa0010, (pipe->dst_y << 16) | pipe->dst_x);
+
+	/* 1 for dma_s, client_id = 0 */
+	MDP_OUTP(MDP_BASE + 0x00090, 1);
+
+	mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
+
+	if (mfd->panel_info.bpp == 24)
+		MDP_OUTP(MDP_BASE + 0x00094,
+			(MDDI_VDO_PACKET_DESC_24 << 16) | mddi_vdo_packet_reg);
+	else if (mfd->panel_info.bpp == 16)
+		MDP_OUTP(MDP_BASE + 0x00094,
+			 (MDDI_VDO_PACKET_DESC_16 << 16) | mddi_vdo_packet_reg);
+	else
+		MDP_OUTP(MDP_BASE + 0x00094,
+			 (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
+
+	MDP_OUTP(MDP_BASE + 0x00098, 0x01);
+
+	MDP_OUTP(MDP_BASE + 0xa0000, dma_s_cfg_reg);
+
+	mdp4_mddi_vsync_enable(mfd, pipe, 1);
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_mddi_dma_s_kickoff(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+	mdp_enable_irq(MDP_DMA_S_TERM);
+
+	if (mddi_pipe->ov_blt_addr == 0)
+		mfd->dma->busy = TRUE;
+
+	mfd->ibuf_flushed = TRUE;
+	/* start dma_s pipe */
+	mdp_pipe_kickoff(MDP_DMA_S_TERM, mfd);
+	mdp4_stat.kickoff_dmas++;
+
+	/* wait until DMA finishes the current job */
+	wait_for_completion(&mfd->dma->comp);
+	mdp_disable_irq(MDP_DMA_S_TERM);
+}
+
+void mdp4_mddi_overlay_dmas_restore(void)
+{
+	/* mutex held by caller */
+	if (mddi_mfd && mddi_pipe) {
+		mdp4_mddi_dma_busy_wait(mddi_mfd);
+		mdp4_dma_s_update_lcd(mddi_mfd, mddi_pipe);
+		mdp4_mddi_dma_s_kickoff(mddi_mfd, mddi_pipe);
+		mddi_mfd->dma_update_flag = 1;
+	}
+}
+
+void mdp4_mddi_overlay(struct msm_fb_data_type *mfd)
+{
+	mutex_lock(&mfd->dma->ov_mutex);
+
+	if (mfd && mfd->panel_power_on) {
+		mdp4_mddi_dma_busy_wait(mfd);
+
+		if (mddi_pipe && mddi_pipe->ov_blt_addr)
+			mdp4_mddi_blt_dmap_busy_wait(mfd);
+		mdp4_overlay_mdp_perf_upd(mfd, 0);
+		mdp4_overlay_update_lcd(mfd);
+
+		mdp4_overlay_mdp_perf_upd(mfd, 1);
+		if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+			/* dmas dmap switch */
+			if (mdp4_overlay_mixer_play(mddi_pipe->mixer_num)
+						== 0) {
+				mdp4_dma_s_update_lcd(mfd, mddi_pipe);
+				mdp4_mddi_dma_s_kickoff(mfd, mddi_pipe);
+			} else
+				mdp4_mddi_kickoff_ui(mfd, mddi_pipe);
+		} else	/* no dams dmap switch  */
+			mdp4_mddi_kickoff_ui(mfd, mddi_pipe);
+
+	/* signal if pan function is waiting for the update completion */
+		if (mfd->pan_waiting) {
+			mfd->pan_waiting = FALSE;
+			complete(&mfd->pan_comp);
+		}
+	}
+	mutex_unlock(&mfd->dma->ov_mutex);
+}
+
+int mdp4_mddi_overlay_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	struct msm_fb_data_type *mfd = info->par;
+	mutex_lock(&mfd->dma->ov_mutex);
+	if (mfd && mfd->panel_power_on) {
+		mdp4_mddi_dma_busy_wait(mfd);
+		mdp_hw_cursor_update(info, cursor);
+	}
+	mutex_unlock(&mfd->dma->ov_mutex);
+	return 0;
+}
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
new file mode 100644
index 0000000..2e76134
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -0,0 +1,620 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <mach/iommu_domains.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+
+#include <linux/fb.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+enum {
+	WB_OPEN,
+	WB_START,
+	WB_STOPING,
+	WB_STOP
+};
+enum {
+	REGISTERED,
+	IN_FREE_QUEUE,
+	IN_BUSY_QUEUE,
+	WITH_CLIENT
+};
+
+static struct mdp4_overlay_pipe *writeback_pipe;
+static struct msm_fb_data_type *writeback_mfd;
+static int busy_wait_cnt;
+
+int mdp4_overlay_writeback_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct fb_info *fbi;
+	uint8 *buf;
+	struct mdp4_overlay_pipe *pipe;
+	int bpp;
+	int ret;
+	uint32 data;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	writeback_mfd = mfd;		  /* keep it */
+
+	fbi = mfd->fbi;
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+	buf += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	if (writeback_pipe == NULL) {
+		pipe = mdp4_overlay_pipe_alloc(OVERLAY_TYPE_BF, MDP4_MIXER2);
+		if (pipe == NULL)
+			pr_info("%s: pipe_alloc failed\n", __func__);
+		pipe->pipe_used++;
+		pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
+		pipe->mixer_num  = MDP4_MIXER2;
+		pipe->src_format = MDP_ARGB_8888;
+		mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_WRITEBACK);
+		ret = mdp4_overlay_format2pipe(pipe);
+		if (ret < 0)
+			pr_info("%s: format2type failed\n", __func__);
+
+		writeback_pipe = pipe; /* keep it */
+
+	} else {
+		pipe = writeback_pipe;
+	}
+	ret = panel_next_on(pdev);
+
+	/* MDP_LAYERMIXER_WB_MUX_SEL to use mixer1 axi for mixer2 writeback */
+	if (hdmi_prim_display)
+		data = 0x01;
+	else
+		data = 0x02;
+	outpdw(MDP_BASE + 0x100F4, data);
+
+	MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5004,
+		((0x0 & 0xFFF) << 16) | /* 12-bit B */
+			(0x0 & 0xFFF));         /* 12-bit G */
+	/* MSP_BORDER_COLOR */
+	MDP_OUTP(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x5008,
+		(0x0 & 0xFFF));         /* 12-bit R */
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	return ret;
+}
+
+int mdp4_overlay_writeback_off(struct platform_device *pdev)
+{
+	int ret;
+	struct msm_fb_data_type *mfd =
+			(struct msm_fb_data_type *)platform_get_drvdata(pdev);
+	if (mfd && writeback_pipe) {
+		mdp4_writeback_dma_busy_wait(mfd);
+		mdp4_overlay_pipe_free(writeback_pipe);
+		mdp4_overlay_panel_mode_unset(writeback_pipe->mixer_num,
+						MDP4_PANEL_WRITEBACK);
+		writeback_pipe = NULL;
+	}
+	ret = panel_next_off(pdev);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	/* MDP_LAYERMIXER_WB_MUX_SEL to restore to default cfg*/
+	outpdw(MDP_BASE + 0x100F4, 0x0);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	return ret;
+}
+int mdp4_overlay_writeback_update(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi;
+	uint8 *buf;
+	unsigned int buf_offset;
+	struct mdp4_overlay_pipe *pipe;
+	int bpp;
+
+	if (mfd->key != MFD_KEY)
+		return -ENODEV;
+
+	if (!writeback_pipe)
+		return -EINVAL;
+
+	fbi = mfd->fbi;
+
+	pipe = writeback_pipe;
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+	buf_offset = fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	pipe->src_height = fbi->var.yres;
+	pipe->src_width = fbi->var.xres;
+	pipe->src_h = fbi->var.yres;
+	pipe->src_w = fbi->var.xres;
+	pipe->dst_h = fbi->var.yres;
+	pipe->dst_w = fbi->var.xres;
+	pipe->srcp0_ystride = fbi->fix.line_length;
+	pipe->src_y = 0;
+	pipe->src_x = 0;
+	pipe->dst_y = 0;
+	pipe->dst_x = 0;
+
+	mdp4_overlay_mdp_pipe_req(pipe, mfd);
+	if (mfd->map_buffer) {
+		pipe->srcp0_addr = (unsigned int)mfd->map_buffer->iova[0] + \
+			buf_offset;
+		pr_debug("start 0x%lx srcp0_addr 0x%x\n", mfd->
+			map_buffer->iova[0], pipe->srcp0_addr);
+	} else {
+		pipe->srcp0_addr = (uint32)(buf + buf_offset);
+	}
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	wmb();
+	return 0;
+}
+void mdp4_writeback_dma_busy_wait(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+	int need_wait = 0;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	if (mfd->dma->busy == TRUE) {
+		if (busy_wait_cnt == 0)
+			INIT_COMPLETION(mfd->dma->comp);
+		busy_wait_cnt = 1;
+		need_wait++;
+	}
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	if (need_wait) {
+		/* wait until DMA finishes the current job */
+		pr_debug("%s: pending pid=%d\n",
+				__func__, current->pid);
+		wait_for_completion(&mfd->dma->comp);
+	}
+}
+
+void mdp4_overlay1_done_writeback(struct mdp_dma_data *dma)
+{
+	spin_lock(&mdp_spin_lock);
+	dma->busy = FALSE;
+	if (busy_wait_cnt)
+		busy_wait_cnt = 0;
+	mdp_disable_irq_nosync(MDP_OVERLAY2_TERM);
+	spin_unlock(&mdp_spin_lock);
+	complete_all(&dma->comp);
+	pr_debug("%s ovdone interrupt\n", __func__);
+
+}
+void mdp4_writeback_overlay_kickoff(struct msm_fb_data_type *mfd,
+				    struct mdp4_overlay_pipe *pipe)
+{
+	unsigned long flag;
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_OVERLAY2_TERM);
+
+	mfd->dma->busy = TRUE;
+	outp32(MDP_INTR_CLEAR, INTR_OVERLAY2_DONE);
+	mdp_intr_mask |= INTR_OVERLAY2_DONE;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+
+	wmb();	/* make sure all registers updated */
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	/* start OVERLAY pipe */
+	mdp_pipe_kickoff(MDP_OVERLAY2_TERM, mfd);
+	wmb();
+	pr_debug("%s: before ov done interrupt\n", __func__);
+}
+void mdp4_writeback_dma_stop(struct msm_fb_data_type *mfd)
+{
+	/* mutex holded by caller */
+	if (mfd && writeback_pipe) {
+		mdp4_writeback_dma_busy_wait(mfd);
+		mdp4_overlay_writeback_update(mfd);
+
+		mdp4_writeback_overlay_kickoff(mfd, writeback_pipe);
+	}
+}
+
+void mdp4_writeback_kickoff_video(struct msm_fb_data_type *mfd,
+		struct mdp4_overlay_pipe *pipe)
+{
+	struct msmfb_writeback_data_list *node = NULL;
+	mutex_lock(&mfd->unregister_mutex);
+	mutex_lock(&mfd->writeback_mutex);
+	if (!list_empty(&mfd->writeback_free_queue)
+		&& mfd->writeback_state != WB_STOPING
+		&& mfd->writeback_state != WB_STOP) {
+		node = list_first_entry(&mfd->writeback_free_queue,
+				struct msmfb_writeback_data_list, active_entry);
+	}
+	if (node) {
+		list_del(&(node->active_entry));
+		node->state = IN_BUSY_QUEUE;
+		mfd->writeback_active_cnt++;
+	}
+	mutex_unlock(&mfd->writeback_mutex);
+
+	writeback_pipe->ov_blt_addr = (ulong) (node ? node->addr : NULL);
+
+	if (!writeback_pipe->ov_blt_addr) {
+		pr_err("%s: no writeback buffer 0x%x, %p\n", __func__,
+				(unsigned int)writeback_pipe->ov_blt_addr, node);
+		mutex_unlock(&mfd->unregister_mutex);
+		return;
+	}
+
+	if (writeback_pipe->blt_cnt == 0)
+		mdp4_overlay_writeback_update(mfd);
+
+	pr_debug("%s: pid=%d\n", __func__, current->pid);
+
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+
+	mdp4_writeback_overlay_kickoff(mfd, pipe);
+
+	mutex_lock(&mfd->writeback_mutex);
+	list_add_tail(&node->active_entry, &mfd->writeback_busy_queue);
+	mutex_unlock(&mfd->writeback_mutex);
+	mfd->writeback_active_cnt--;
+	mutex_unlock(&mfd->unregister_mutex);
+	wake_up(&mfd->wait_q);
+}
+
+void mdp4_writeback_kickoff_ui(struct msm_fb_data_type *mfd,
+		struct mdp4_overlay_pipe *pipe)
+{
+	mdp4_mixer_stage_commit(pipe->mixer_num);
+
+	pr_debug("%s: pid=%d\n", __func__, current->pid);
+	mdp4_writeback_overlay_kickoff(mfd, pipe);
+}
+
+void mdp4_writeback_overlay(struct msm_fb_data_type *mfd)
+{
+	int ret = 0;
+	struct msmfb_writeback_data_list *node = NULL;
+
+	mutex_lock(&mfd->unregister_mutex);
+	mutex_lock(&mfd->writeback_mutex);
+	if (!list_empty(&mfd->writeback_free_queue)
+		&& mfd->writeback_state != WB_STOPING
+		&& mfd->writeback_state != WB_STOP) {
+		node = list_first_entry(&mfd->writeback_free_queue,
+				struct msmfb_writeback_data_list, active_entry);
+	}
+	if (node) {
+		list_del(&(node->active_entry));
+		node->state = IN_BUSY_QUEUE;
+		mfd->writeback_active_cnt++;
+	}
+	mutex_unlock(&mfd->writeback_mutex);
+
+	writeback_pipe->ov_blt_addr = (ulong) (node ? node->addr : NULL);
+
+	mutex_lock(&mfd->dma->ov_mutex);
+	pr_debug("%s in writeback\n", __func__);
+	if (writeback_pipe && !writeback_pipe->ov_blt_addr) {
+		pr_err("%s: no writeback buffer 0x%x\n", __func__,
+				(unsigned int)writeback_pipe->ov_blt_addr);
+		ret = mdp4_overlay_writeback_update(mfd);
+		if (ret)
+			pr_err("%s: update failed writeback pipe NULL\n",
+					__func__);
+		goto fail_no_blt_addr;
+	}
+
+	if (mfd && mfd->panel_power_on) {
+		pr_debug("%s in before busy wait\n", __func__);
+		mdp4_writeback_dma_busy_wait(mfd);
+
+		pr_debug("%s in before update\n", __func__);
+		ret = mdp4_overlay_writeback_update(mfd);
+		if (ret) {
+			pr_err("%s: update failed writeback pipe NULL\n",
+					__func__);
+			goto fail_no_blt_addr;
+		}
+
+		pr_debug("%s: in writeback pan display 0x%x\n", __func__,
+				(unsigned int)writeback_pipe->ov_blt_addr);
+		mdp4_writeback_kickoff_ui(mfd, writeback_pipe);
+		mdp4_iommu_unmap(writeback_pipe);
+
+		/* signal if pan function is waiting for the
+		 * update completion */
+		if (mfd->pan_waiting) {
+			mfd->pan_waiting = FALSE;
+			complete(&mfd->pan_comp);
+		}
+	}
+
+	mutex_lock(&mfd->writeback_mutex);
+	list_add_tail(&node->active_entry, &mfd->writeback_busy_queue);
+	mfd->writeback_active_cnt--;
+	mutex_unlock(&mfd->writeback_mutex);
+	wake_up(&mfd->wait_q);
+fail_no_blt_addr:
+	/*NOTE: This api was removed
+	  mdp4_overlay_resource_release();*/
+	mutex_unlock(&mfd->dma->ov_mutex);
+	mutex_unlock(&mfd->unregister_mutex);
+}
+static int mdp4_overlay_writeback_register_buffer(
+	struct msm_fb_data_type *mfd, struct msmfb_writeback_data_list *node)
+{
+	if (!node) {
+		pr_err("Cannot register a NULL node\n");
+		return -EINVAL;
+	}
+	node->state = REGISTERED;
+	list_add_tail(&node->registered_entry, &mfd->writeback_register_queue);
+	return 0;
+}
+static struct msmfb_writeback_data_list *get_if_registered(
+			struct msm_fb_data_type *mfd, struct msmfb_data *data)
+{
+	struct msmfb_writeback_data_list *temp;
+	bool found = false;
+	if (!list_empty(&mfd->writeback_register_queue)) {
+		list_for_each_entry(temp,
+				&mfd->writeback_register_queue,
+				registered_entry) {
+			if (temp && temp->buf_info.iova == data->iova) {
+				found = true;
+				break;
+			}
+		}
+	}
+	if (!found) {
+		temp = kzalloc(sizeof(struct msmfb_writeback_data_list),
+				GFP_KERNEL);
+		if (temp == NULL) {
+			pr_err("%s: out of memory\n", __func__);
+			goto register_alloc_fail;
+		}
+		temp->ihdl = NULL;
+		if (data->iova)
+			temp->addr = (void *)(data->iova + data->offset);
+		else if (mfd->iclient) {
+			struct ion_handle *srcp_ihdl;
+			ulong len;
+			srcp_ihdl = ion_import_fd(mfd->iclient,
+						  data->memory_id);
+			if (IS_ERR_OR_NULL(srcp_ihdl)) {
+				pr_err("%s: ion import fd failed\n", __func__);
+				goto register_ion_fail;
+			}
+
+			if (ion_map_iommu(mfd->iclient,
+					  srcp_ihdl,
+					  DISPLAY_DOMAIN,
+					  GEN_POOL,
+					  SZ_4K,
+					  0,
+					  (ulong *)&temp->addr,
+					  (ulong *)&len,
+					  0,
+					  ION_IOMMU_UNMAP_DELAYED)) {
+				ion_free(mfd->iclient, srcp_ihdl);
+				pr_err("%s: unable to get ion mapping addr\n",
+				       __func__);
+				goto register_ion_fail;
+			}
+			temp->addr += data->offset;
+			temp->ihdl = srcp_ihdl;
+		}
+		else {
+			pr_err("%s: only support ion memory\n", __func__);
+			goto register_ion_fail;
+		}
+
+		memcpy(&temp->buf_info, data, sizeof(struct msmfb_data));
+		if (mdp4_overlay_writeback_register_buffer(mfd, temp)) {
+			pr_err("%s: error registering node\n", __func__);
+			goto register_ion_fail;
+		}
+	}
+	return temp;
+ register_ion_fail:
+	kfree(temp);
+ register_alloc_fail:
+	return NULL;
+}
+int mdp4_writeback_start(
+		struct fb_info *info)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	mutex_lock(&mfd->writeback_mutex);
+	mfd->writeback_state = WB_START;
+	mutex_unlock(&mfd->writeback_mutex);
+	wake_up(&mfd->wait_q);
+	return 0;
+}
+
+int mdp4_writeback_queue_buffer(struct fb_info *info, struct msmfb_data *data)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct msmfb_writeback_data_list *node = NULL;
+	int rv = 0;
+
+	mutex_lock(&mfd->writeback_mutex);
+	node = get_if_registered(mfd, data);
+	if (!node || node->state == IN_BUSY_QUEUE ||
+		node->state == IN_FREE_QUEUE) {
+		pr_err("memory not registered or Buffer already with us\n");
+		rv = -EINVAL;
+		goto exit;
+	}
+
+	list_add_tail(&node->active_entry, &mfd->writeback_free_queue);
+	node->state = IN_FREE_QUEUE;
+
+exit:
+	mutex_unlock(&mfd->writeback_mutex);
+	return rv;
+}
+static int is_buffer_ready(struct msm_fb_data_type *mfd)
+{
+	int rc;
+	mutex_lock(&mfd->writeback_mutex);
+	rc = !list_empty(&mfd->writeback_busy_queue) ||
+			(mfd->writeback_state == WB_STOPING);
+	mutex_unlock(&mfd->writeback_mutex);
+	return rc;
+}
+int mdp4_writeback_dequeue_buffer(struct fb_info *info, struct msmfb_data *data)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct msmfb_writeback_data_list *node = NULL;
+	int rc = 0;
+
+	rc = wait_event_interruptible(mfd->wait_q, is_buffer_ready(mfd));
+	if (rc) {
+		pr_err("failed to get dequeued buffer\n");
+		return -ENOBUFS;
+	}
+	mutex_lock(&mfd->writeback_mutex);
+	if (mfd->writeback_state == WB_STOPING) {
+		mfd->writeback_state = WB_STOP;
+		mutex_unlock(&mfd->writeback_mutex);
+		return -ENOBUFS;
+	} else	if (!list_empty(&mfd->writeback_busy_queue)) {
+		node = list_first_entry(&mfd->writeback_busy_queue,
+				struct msmfb_writeback_data_list, active_entry);
+	}
+	if (node) {
+		list_del(&node->active_entry);
+		node->state = WITH_CLIENT;
+		memcpy(data, &node->buf_info, sizeof(struct msmfb_data));
+		if (!data->iova)
+			if (mfd->iclient && node->ihdl) {
+				ion_unmap_iommu(mfd->iclient,
+						node->ihdl,
+						DISPLAY_DOMAIN,
+						GEN_POOL);
+				ion_free(mfd->iclient,
+					 node->ihdl);
+			}
+	} else {
+		pr_err("node is NULL. Somebody else dequeued?\n");
+		rc = -ENOBUFS;
+	}
+	mutex_unlock(&mfd->writeback_mutex);
+	return rc;
+}
+
+static bool is_writeback_inactive(struct msm_fb_data_type *mfd)
+{
+	bool active;
+	mutex_lock(&mfd->writeback_mutex);
+	active = !mfd->writeback_active_cnt;
+	mutex_unlock(&mfd->writeback_mutex);
+	return active;
+}
+int mdp4_writeback_stop(struct fb_info *info)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	mutex_lock(&mfd->writeback_mutex);
+	mfd->writeback_state = WB_STOPING;
+	mutex_unlock(&mfd->writeback_mutex);
+	/* Wait for all pending writebacks to finish */
+	wait_event_interruptible(mfd->wait_q, is_writeback_inactive(mfd));
+
+	/* Wake up dequeue thread in case of no UI update*/
+	wake_up(&mfd->wait_q);
+
+	return 0;
+}
+int mdp4_writeback_init(struct fb_info *info)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	mutex_init(&mfd->writeback_mutex);
+	mutex_init(&mfd->unregister_mutex);
+	INIT_LIST_HEAD(&mfd->writeback_free_queue);
+	INIT_LIST_HEAD(&mfd->writeback_busy_queue);
+	INIT_LIST_HEAD(&mfd->writeback_register_queue);
+	mfd->writeback_state = WB_OPEN;
+	init_waitqueue_head(&mfd->wait_q);
+	return 0;
+}
+int mdp4_writeback_terminate(struct fb_info *info)
+{
+	struct list_head *ptr, *next;
+	struct msmfb_writeback_data_list *temp;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	int rc = 0;
+
+	mutex_lock(&mfd->unregister_mutex);
+	mutex_lock(&mfd->writeback_mutex);
+
+	if (mfd->writeback_state != WB_STOPING &&
+		mfd->writeback_state != WB_STOP) {
+		pr_err("%s called without stopping\n", __func__);
+		rc = -EPERM;
+		goto terminate_err;
+
+	}
+
+	if (!list_empty(&mfd->writeback_register_queue)) {
+		list_for_each_safe(ptr, next,
+				&mfd->writeback_register_queue) {
+			temp = list_entry(ptr,
+					struct msmfb_writeback_data_list,
+					registered_entry);
+			list_del(&temp->registered_entry);
+			kfree(temp);
+		}
+	}
+	INIT_LIST_HEAD(&mfd->writeback_register_queue);
+	INIT_LIST_HEAD(&mfd->writeback_busy_queue);
+	INIT_LIST_HEAD(&mfd->writeback_free_queue);
+
+
+terminate_err:
+	mutex_unlock(&mfd->writeback_mutex);
+	mutex_unlock(&mfd->unregister_mutex);
+	return rc;
+}
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 00e8acf..2ad7d36 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -1,58 +1,13 @@
-
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of Code Aurora Forum nor
- *       the names of its contributors may be used to endorse or promote
- *       products derived from this software without specific prior written
- *       permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * Alternatively, provided that this notice is retained in full, this software
- * may be relicensed by the recipient under the terms of the GNU General Public
- * License version 2 ("GPL") and only version 2, in which case the provisions of
- * the GPL apply INSTEAD OF those given above.  If the recipient relicenses the
- * software under the GPL, then the identification text in the MODULE_LICENSE
- * macro must be changed to reflect "GPLv2" instead of "Dual BSD/GPL".  Once a
- * recipient changes the license terms to the GPL, subsequent recipients shall
- * not relicense under alternate licensing terms, including the BSD or dual
- * BSD/GPL terms.  In addition, the following license statement immediately
- * below and between the words START and END shall also then apply when this
- * software is relicensed under the GPL:
- *
- * START
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License version 2 and only version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * END
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
@@ -65,32 +20,52 @@
 #include <linux/spinlock.h>
 #include <linux/hrtimer.h>
 #include <linux/clk.h>
-#include <mach/hardware.h>
 #include <linux/io.h>
 #include <linux/debugfs.h>
-#include <linux/msm_mdp.h>
-
-#include <asm/system.h>
-#include <asm/mach-types.h>
 #include <linux/semaphore.h>
 #include <linux/uaccess.h>
-#include <mach/debug_display.h>
-
-#include "mdp_hw.h"
+#include <linux/msm_mdp.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/iommu_domains.h>
+#include "mdp.h"
+#include "msm_fb.h"
 #include "mdp4.h"
 
+struct mdp4_statistic mdp4_stat;
 
-void mdp4_sw_reset(struct mdp_info *mdp, ulong bits)
+unsigned is_mdp4_hw_reset(void)
 {
-	bits &= 0x1f;	/* 5 bits */
-	mdp_writel(mdp, bits, 0x001c);	/* MDP_SW_RESET */
+	unsigned hw_reset = 0;
 
-	while (mdp_readl(mdp, 0x001c) & bits) /* self clear when complete */
-		;
-	PR_DISP_WARN("mdp4_sw_reset: 0x%x\n", (int)bits);
+	/* Only revisions > v2.1 may be reset or powered off/on at runtime */
+	if (mdp_hw_revision > MDP4_REVISION_V2_1) {
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		hw_reset = !inpdw(MDP_BASE + 0x003c);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	}
+
+	return hw_reset;
 }
 
-void mdp4_overlay_cfg(struct mdp_info *mdp, int overlayer, int blt_mode, int refresh, int direct_out)
+void mdp4_sw_reset(ulong bits)
+{
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	bits &= 0x1f;	/* 5 bits */
+	outpdw(MDP_BASE + 0x001c, bits);	/* MDP_SW_RESET */
+
+	while (inpdw(MDP_BASE + 0x001c) & bits) /* self clear when complete */
+		;
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	MSM_FB_DEBUG("mdp4_sw_reset: 0x%x\n", (int)bits);
+}
+
+void mdp4_overlay_cfg(int overlayer, int blt_mode, int refresh, int direct_out)
 {
 	ulong bits = 0;
 
@@ -100,33 +75,41 @@
 	bits |= (refresh << 1);
 	direct_out &= 0x01;
 	bits |= direct_out;
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
 
 	if (overlayer == MDP4_MIXER0)
-	  mdp_writel(mdp, bits, 0x10004); /* MDP_OVERLAY0_CFG */
-	else
-	  mdp_writel(mdp, bits, 0x18004); /* MDP_OVERLAY1_CFG */
+		outpdw(MDP_BASE + 0x10004, bits); /* MDP_OVERLAY0_CFG */
+	else if (overlayer == MDP4_MIXER1)
+		outpdw(MDP_BASE + 0x18004, bits); /* MDP_OVERLAY1_CFG */
 
-	PR_DISP_WARN("mdp4_overlay_cfg: 0x%x\n", (int)mdp_readl(mdp, 0x10004));
+	MSM_FB_DEBUG("mdp4_overlay_cfg: 0x%x\n",
+		(int)inpdw(MDP_BASE + 0x10004));
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_display_intf_sel(struct mdp_info *mdp, int output, ulong intf)
+void mdp4_display_intf_sel(int output, ulong intf)
 {
 	ulong bits, mask, data;
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
-	bits = mdp_readl(mdp, 0x0038);	/* MDP_DISP_INTF_SEL */
+	bits = inpdw(MDP_BASE + 0x0038);	/* MDP_DISP_INTF_SEL */
 
 	if (intf == DSI_VIDEO_INTF) {
 		data = 0x40;	/* bit 6 */
 		intf = MDDI_LCDC_INTF;
 		if (output == SECONDARY_INTF_SEL) {
-			PR_DISP_INFO("%s: Illegal INTF selected, output=%d \
+			MSM_FB_INFO("%s: Illegal INTF selected, output=%d \
 				intf=%d\n", __func__, output, (int)intf);
 		}
 	} else if (intf == DSI_CMD_INTF) {
 		data = 0x80;	/* bit 7 */
 		intf = MDDI_INTF;
 		if (output == EXTERNAL_INTF_SEL) {
-			PR_DISP_INFO("%s: Illegal INTF selected, output=%d \
+			MSM_FB_INFO("%s: Illegal INTF selected, output=%d \
 				intf=%d\n", __func__, output, (int)intf);
 		}
 	} else
@@ -155,30 +138,45 @@
 	bits &= ~mask;
 	bits |= intf;
 
-	mdp_writel(mdp, bits, 0x0038); /* MDP_DISP_INTF_SEL */
+	outpdw(MDP_BASE + 0x0038, bits);	/* MDP_DISP_INTF_SEL */
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
-  PR_DISP_WARN("mdp4_display_intf_sel: 0x%x\n", (int)mdp_readl(mdp, 0x0038));
+  MSM_FB_DEBUG("mdp4_display_intf_sel: 0x%x\n", (int)inpdw(MDP_BASE + 0x0038));
 }
 
-unsigned long mdp4_display_status(struct mdp_info *mdp)
+unsigned long mdp4_display_status(void)
 {
-	return mdp_readl(mdp, 0x0018) & 0x3ff;	/* MDP_DISPLAY_STATUS */
+	ulong status;
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	status = inpdw(MDP_BASE + 0x0018) & 0x3ff;	/* MDP_DISPLAY_STATUS */
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	return status;
 }
 
-void mdp4_ebi2_lcd_setup(struct mdp_info *mdp, int lcd, ulong base, int ystride)
+void mdp4_ebi2_lcd_setup(int lcd, ulong base, int ystride)
 {
 	/* always use memory map */
 	ystride &= 0x01fff;	/* 13 bits */
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
 	if (lcd == EBI2_LCD0) {
-		mdp_writel(mdp, base, 0x0060);/* MDP_EBI2_LCD0 */
-		mdp_writel(mdp, ystride, 0x0068);/* MDP_EBI2_LCD0_YSTRIDE */
+		outpdw(MDP_BASE + 0x0060, base);/* MDP_EBI2_LCD0 */
+		outpdw(MDP_BASE + 0x0068, ystride);/* MDP_EBI2_LCD0_YSTRIDE */
 	} else {
-		mdp_writel(mdp, base, 0x0064);/* MDP_EBI2_LCD1 */
-		mdp_writel(mdp, ystride, 0x006c);/* MDP_EBI2_LCD1_YSTRIDE */
+		outpdw(MDP_BASE + 0x0064, base);/* MDP_EBI2_LCD1 */
+		outpdw(MDP_BASE + 0x006c, ystride);/* MDP_EBI2_LCD1_YSTRIDE */
 	}
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_mddi_setup(struct mdp_info *mdp, int mddi, unsigned long id)
+void mdp4_mddi_setup(int mddi, unsigned long id)
 {
 	ulong 	bits;
 
@@ -192,413 +190,392 @@
 	id <<= 16;
 
 	bits |= id;
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
-  mdp_writel(mdp, bits, 0x0090);  /* MDP_MDDI_PARAM_WR_SEL */
-
+	outpdw(MDP_BASE + 0x0090, bits); /* MDP_MDDI_PARAM_WR_SEL */
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-
-
-void mdp4_fetch_cfg(struct mdp_info *mdp, uint32_t clk, uint32_t pclk)
+int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req)
 {
 
-	uint32_t dmap_data, vg_data;
-	uint32_t base;
+	/* not implemented yet */
+	return -1;
+}
+
+void mdp4_fetch_cfg(uint32 core_clk)
+{
+	uint32 dmap_data, vg_data;
+	char *base;
 	int i;
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
-	if (clk <= pclk)
-		PR_DISP_INFO("mdp4_fetch_cfg: ERROR!! mdp_clk=%d \
-				<= mdp_pclk=%d\n", (int)clk, (int)pclk);
-
-	if (clk >= 90000000) { /* 90 Mhz */
+	if (mdp_rev >= MDP_REV_41 || core_clk >= 90000000) { /* 90 Mhz */
 		dmap_data = 0x47; /* 16 bytes-burst x 8 req */
-		vg_data = 0xc7; /* 16 bytes-burs x 8 req */
+		vg_data = 0x47; /* 16 bytes-burs x 8 req */
 	} else {
 		dmap_data = 0x27; /* 8 bytes-burst x 8 req */
-		vg_data = 0xc3; /* 16 bytes-burst x 4 req */
+		vg_data = 0x43; /* 16 bytes-burst x 4 req */
 	}
 
-	PR_DISP_INFO("mdp4_fetch_cfg: dmap=%x vg=%x\n",
+	MSM_FB_DEBUG("mdp4_fetch_cfg: dmap=%x vg=%x\n",
 			dmap_data, vg_data);
 
 	/* dma_p fetch config */
-	mdp_writel(mdp, dmap_data, 0x91004);
+	outpdw(MDP_BASE + 0x91004, dmap_data);
 	/* dma_e fetch config */
-	mdp_writel(mdp, dmap_data, 0xB1004);
+	outpdw(MDP_BASE + 0xB1004, dmap_data);
 
 	/*
 	 * set up two vg pipes and two rgb pipes
 	 */
-	base = MDP4_VIDEO_BASE;
+	base = MDP_BASE + MDP4_VIDEO_BASE;
 	for (i = 0; i < 4; i++) {
-		mdp_writel(mdp, vg_data, base + 0x1004);
+		outpdw(base + 0x1004, vg_data);
 		base += MDP4_VIDEO_OFF;
 	}
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_hw_init(struct mdp_info *mdp)
+void mdp4_hw_init(void)
 {
 	ulong bits;
+	uint32 clk_rate;
 
-	PR_DISP_WARN("%s\n", __func__);
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	mdp_bus_scale_update_request(5);
+
 #ifdef MDP4_ERROR
 	/*
 	 * Issue software reset on DMA_P will casue DMA_P dma engine stall
 	 * on LCDC mode. However DMA_P does not stall at MDDI mode.
 	 * This need further investigation.
 	 */
-	mdp4_sw_reset(mdp, 0x17);
+	mdp4_sw_reset(0x17);
 #endif
 
-	mdp4_clear_lcdc(mdp);
+	if (mdp_rev > MDP_REV_41) {
+		/* mdp chip select controller */
+		outpdw(MDP_BASE + 0x00c0, CS_CONTROLLER_0);
+		outpdw(MDP_BASE + 0x00c4, CS_CONTROLLER_1);
+	}
 
-	mdp4_mixer_blend_init(mdp, 0);
-	mdp4_mixer_blend_init(mdp, 1);
-	mdp4_vg_qseed_init(mdp, 0);
-	mdp4_vg_qseed_init(mdp, 1);
+	mdp4_clear_lcdc();
 
-	/* yuv2rgb */
-	mdp4_vg_qseed_init(mdp, 0);
-	mdp4_vg_qseed_init(mdp, 1);
-	mdp4_vg_csc_mv_setup(mdp, 0);
-	mdp4_vg_csc_mv_setup(mdp, 1);
-	mdp4_vg_csc_pre_bv_setup(mdp, 0);
-	mdp4_vg_csc_pre_bv_setup(mdp, 1);
-	mdp4_vg_csc_post_bv_setup(mdp, 0);
-	mdp4_vg_csc_post_bv_setup(mdp, 1);
-	mdp4_vg_csc_pre_lv_setup(mdp, 0);
-	mdp4_vg_csc_pre_lv_setup(mdp, 1);
-	mdp4_vg_csc_post_lv_setup(mdp, 0);
-	mdp4_vg_csc_post_lv_setup(mdp, 1);
+	mdp4_mixer_blend_init(0);
+	mdp4_mixer_blend_init(1);
+	mdp4_vg_qseed_init(0);
+	mdp4_vg_qseed_init(1);
 
-	/* rgb2yuv */
-	mdp4_mixer1_csc_mv_setup(mdp);
-	mdp4_mixer1_csc_pre_bv_setup(mdp);
-	mdp4_mixer1_csc_post_bv_setup(mdp);
-	mdp4_mixer1_csc_pre_lv_setup(mdp);
-	mdp4_mixer1_csc_post_lv_setup(mdp);
+	mdp4_vg_csc_setup(0);
+	mdp4_vg_csc_setup(1);
+	mdp4_mixer_csc_setup(1);
+	mdp4_mixer_csc_setup(2);
+	mdp4_dmap_csc_setup();
 
-	mdp4_mixer_gc_lut_setup(mdp, 0);
-	mdp4_mixer_gc_lut_setup(mdp, 1);
+	if (mdp_rev <= MDP_REV_41) {
+		mdp4_mixer_gc_lut_setup(0);
+		mdp4_mixer_gc_lut_setup(1);
+	}
 
-	mdp4_vg_igc_lut_setup(mdp, 0);
-	mdp4_vg_igc_lut_setup(mdp, 1);
+	mdp4_vg_igc_lut_setup(0);
+	mdp4_vg_igc_lut_setup(1);
 
-	 mdp4_rgb_igc_lut_setup(mdp, 0);
-	 mdp4_rgb_igc_lut_setup(mdp, 1);
+	mdp4_rgb_igc_lut_setup(0);
+	mdp4_rgb_igc_lut_setup(1);
 
-
-	mdp_writel(mdp, 0x3, MDP_EBI2_PORTMAP_MODE);
+	outp32(MDP_EBI2_PORTMAP_MODE, 0x3);
 
 	/* system interrupts */
-	bits =  MDP4_ANY_INTR_MASK;
-	mdp_writel(mdp, bits, 0x0050);/* enable specififed interrupts */
 
-	/* histogram */
-	mdp_writel(mdp, 1, 0x95010);	/* auto clear HIST */
+	bits =  mdp_intr_mask;
+	outpdw(MDP_BASE + 0x0050, bits);/* enable specififed interrupts */
 
-	/* enable histogram interrupts */
-	mdp_writel(mdp, INTR_HIST_DONE, 0x9501c);
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-	mdp_writel(mdp, MDP_HIST_DONE, MDP_INTR_ENABLE);
-#endif
 	/* For the max read pending cmd config below, if the MDP clock     */
 	/* is less than the AXI clock, then we must use 3 pending          */
 	/* pending requests.  Otherwise, we should use 8 pending requests. */
 	/* In the future we should do this detection automatically.	   */
 
 	/* max read pending cmd config */
-	mdp_writel(mdp, 0x02222, 0x004c);	/* 3 pending requests */
+	outpdw(MDP_BASE + 0x004c, 0x02222);	/* 3 pending requests */
 
 #ifndef CONFIG_FB_MSM_OVERLAY
 	/* both REFRESH_MODE and DIRECT_OUT are ignored at BLT mode */
-	mdp4_overlay_cfg(mdp, MDP4_MIXER0, OVERLAY_MODE_BLT, 0, 0);
-	mdp4_overlay_cfg(mdp, MDP4_MIXER1, OVERLAY_MODE_BLT, 0, 0);
+	mdp4_overlay_cfg(MDP4_MIXER0, OVERLAY_MODE_BLT, 0, 0);
+	mdp4_overlay_cfg(MDP4_MIXER1, OVERLAY_MODE_BLT, 0, 0);
 #endif
 
+	clk_rate = mdp_get_core_clk();
+	mdp4_fetch_cfg(clk_rate);
+
+	mdp4_overlay_cfg_init();
+
+	/* Mark hardware as initialized. Only revisions > v2.1 have a register
+	 * for tracking core reset status. */
+	if (mdp_hw_revision > MDP4_REVISION_V2_1)
+		outpdw(MDP_BASE + 0x003c, 1);
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
 
-void mdp4_clear_lcdc(struct mdp_info *mdp)
+void mdp4_clear_lcdc(void)
 {
-	uint32_t bits;
+	uint32 bits;
 
-	bits = mdp_readl(mdp, 0xc0000);
-	if (bits & 0x01) /* enabled already */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	bits = inpdw(MDP_BASE + 0xc0000);
+	if (bits & 0x01) { /* enabled already */
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 		return;
+	}
 
-	mdp_writel(mdp, 0, 0xc0004);	/* vsync ctrl out */
-	mdp_writel(mdp, 0, 0xc0008);	/* vsync period */
-	mdp_writel(mdp, 0, 0xc000c);	/* vsync pusle width */
-	mdp_writel(mdp, 0, 0xc0010);	/* lcdc display HCTL */
-	mdp_writel(mdp, 0, 0xc0014);	/* lcdc display v start */
-	mdp_writel(mdp, 0, 0xc0018);	/* lcdc display v end */
-	mdp_writel(mdp, 0, 0xc001c);	/* lcdc active hctl */
-	mdp_writel(mdp, 0, 0xc0020);	/* lcdc active v start */
-	mdp_writel(mdp, 0, 0xc0024);	/* lcdc active v end */
-	mdp_writel(mdp, 0, 0xc0028);	/* lcdc board color */
-	mdp_writel(mdp, 0, 0xc002c);	/* lcdc underflow ctrl */
-	mdp_writel(mdp, 0, 0xc0030);	/* lcdc hsync skew */
-	mdp_writel(mdp, 0, 0xc0034);	/* lcdc test ctl */
-	mdp_writel(mdp, 0, 0xc0038);	/* lcdc ctl polarity */
+	outpdw(MDP_BASE + 0xc0004, 0);	/* vsync ctrl out */
+	outpdw(MDP_BASE + 0xc0008, 0);	/* vsync period */
+	outpdw(MDP_BASE + 0xc000c, 0);	/* vsync pusle width */
+	outpdw(MDP_BASE + 0xc0010, 0);	/* lcdc display HCTL */
+	outpdw(MDP_BASE + 0xc0014, 0);	/* lcdc display v start */
+	outpdw(MDP_BASE + 0xc0018, 0);	/* lcdc display v end */
+	outpdw(MDP_BASE + 0xc001c, 0);	/* lcdc active hctl */
+	outpdw(MDP_BASE + 0xc0020, 0);	/* lcdc active v start */
+	outpdw(MDP_BASE + 0xc0024, 0);	/* lcdc active v end */
+	outpdw(MDP_BASE + 0xc0028, 0);	/* lcdc board color */
+	outpdw(MDP_BASE + 0xc002c, 0);	/* lcdc underflow ctrl */
+	outpdw(MDP_BASE + 0xc0030, 0);	/* lcdc hsync skew */
+	outpdw(MDP_BASE + 0xc0034, 0);	/* lcdc test ctl */
+	outpdw(MDP_BASE + 0xc0038, 0);	/* lcdc ctl polarity */
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
+irqreturn_t mdp4_isr(int irq, void *ptr)
+{
+	uint32 isr, mask, panel;
+	struct mdp_dma_data *dma;
+	struct mdp_hist_mgmt *mgmt = NULL;
+	char *base_addr;
+	int i, ret;
 
+	mdp_is_in_isr = TRUE;
+
+	/* complete all the reads before reading the interrupt
+	* status register - eliminate effects of speculative
+	* reads by the cpu
+	*/
+	rmb();
+	isr = inpdw(MDP_INTR_STATUS);
+	if (isr == 0)
+		goto out;
+
+	mdp4_stat.intr_tot++;
+	mask = inpdw(MDP_INTR_ENABLE);
+	outpdw(MDP_INTR_CLEAR, isr);
+
+	if (isr & INTR_PRIMARY_INTF_UDERRUN) {
+		pr_debug("%s: UNDERRUN -- primary\n", __func__);
+		mdp4_stat.intr_underrun_p++;
+		/* When underun occurs mdp clear the histogram registers
+		that are set before in hw_init so restore them back so
+		that histogram works.*/
+		for (i = 0; i < MDP_HIST_MGMT_MAX; i++) {
+			mgmt = mdp_hist_mgmt_array[i];
+			if (!mgmt)
+				continue;
+			base_addr = MDP_BASE + mgmt->base;
+			MDP_OUTP(base_addr + 0x010, 1);
+			outpdw(base_addr + 0x01c, INTR_HIST_DONE |
+						INTR_HIST_RESET_SEQ_DONE);
+			mgmt->mdp_is_hist_valid = FALSE;
+			__mdp_histogram_reset(mgmt);
+		}
+	}
+
+	if (isr & INTR_EXTERNAL_INTF_UDERRUN) {
+		pr_debug("%s: UNDERRUN -- external\n", __func__);
+		mdp4_stat.intr_underrun_e++;
+	}
+
+	isr &= mask;
+
+	if (isr == 0)
+		goto out;
+
+	panel = mdp4_overlay_panel_list();
+
+	if (isr & INTR_DMA_P_DONE) {
+		mdp4_stat.intr_dma_p++;
+		dma = &dma2_data;
+		if (panel & MDP4_PANEL_LCDC)
+			mdp4_dmap_done_lcdc(0);
+#ifdef CONFIG_FB_MSM_OVERLAY
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+		else if (panel & MDP4_PANEL_DSI_VIDEO)
+			mdp4_dmap_done_dsi_video(0);
+		else if (panel & MDP4_PANEL_DSI_CMD)
+			mdp4_dmap_done_dsi_cmd(0);
+#else
+		else { /* MDDI */
+			mdp4_dma_p_done_mddi(dma);
+			mdp_pipe_ctrl(MDP_DMA2_BLOCK,
+				MDP_BLOCK_POWER_OFF, TRUE);
+			complete(&dma->comp);
+		}
+#endif
+#else
+		else {
+			spin_lock(&mdp_spin_lock);
+			dma->busy = FALSE;
+			spin_unlock(&mdp_spin_lock);
+			complete(&dma->comp);
+		}
+#endif
+	}
+	if (isr & INTR_DMA_S_DONE) {
+		mdp4_stat.intr_dma_s++;
+#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDDI)
+		dma = &dma2_data;
+#else
+		dma = &dma_s_data;
+#endif
+
+		dma->busy = FALSE;
+		mdp_pipe_ctrl(MDP_DMA_S_BLOCK,
+				MDP_BLOCK_POWER_OFF, TRUE);
+		complete(&dma->comp);
+	}
+	if (isr & INTR_DMA_E_DONE) {
+		mdp4_stat.intr_dma_e++;
+		if (panel & MDP4_PANEL_DTV)
+			mdp4_dmae_done_dtv();
+	}
+#ifdef CONFIG_FB_MSM_OVERLAY
+	if (isr & INTR_OVERLAY0_DONE) {
+		mdp4_stat.intr_overlay0++;
+		dma = &dma2_data;
+		if (panel & (MDP4_PANEL_LCDC | MDP4_PANEL_DSI_VIDEO)) {
+			/* disable LCDC interrupt */
+			if (panel & MDP4_PANEL_LCDC)
+				mdp4_overlay0_done_lcdc(0);
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+			else if (panel & MDP4_PANEL_DSI_VIDEO)
+				mdp4_overlay0_done_dsi_video(0);
+#endif
+		} else {        /* MDDI, DSI_CMD  */
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+			if (panel & MDP4_PANEL_DSI_CMD)
+				mdp4_overlay0_done_dsi_cmd(0);
+#else
+			if (panel & MDP4_PANEL_MDDI)
+				mdp4_overlay0_done_mddi(dma);
+#endif
+		}
+		mdp_hw_cursor_done();
+	}
+	if (isr & INTR_OVERLAY1_DONE) {
+		mdp4_stat.intr_overlay1++;
+		/* disable DTV interrupt */
+		dma = &dma_e_data;
+		spin_lock(&mdp_spin_lock);
+		mdp_intr_mask &= ~INTR_OVERLAY1_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		dma->waiting = FALSE;
+		spin_unlock(&mdp_spin_lock);
+#if defined(CONFIG_FB_MSM_DTV)
+		if (panel & MDP4_PANEL_DTV)
+			mdp4_overlay1_done_dtv();
+#endif
+#if defined(CONFIG_FB_MSM_TVOUT)
+		if (panel & MDP4_PANEL_ATV)
+			mdp4_overlay1_done_atv();
+#endif
+	}
+#if defined(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL)
+	if (isr & INTR_OVERLAY2_DONE) {
+		mdp4_stat.intr_overlay2++;
+		/* disable DTV interrupt */
+		dma = &dma_wb_data;
+		spin_lock(&mdp_spin_lock);
+		mdp_intr_mask &= ~INTR_OVERLAY2_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		dma->waiting = FALSE;
+		spin_unlock(&mdp_spin_lock);
+		if (panel & MDP4_PANEL_WRITEBACK)
+			mdp4_overlay1_done_writeback(dma);
+	}
+#endif
+#endif	/* OVERLAY */
+
+	if (isr & INTR_PRIMARY_VSYNC) {
+		mdp4_stat.intr_vsync_p++;
+		if (panel & MDP4_PANEL_LCDC)
+			mdp4_primary_vsync_lcdc();
+		else if (panel & MDP4_PANEL_DSI_VIDEO)
+			mdp4_primary_vsync_dsi_video();
+	}
+#ifdef CONFIG_FB_MSM_DTV
+	if (isr & INTR_EXTERNAL_VSYNC) {
+		mdp4_stat.intr_vsync_e++;
+		if (panel & MDP4_PANEL_DTV)
+			mdp4_external_vsync_dtv();
+	}
+#endif
+	if (isr & INTR_DMA_P_HISTOGRAM) {
+		mdp4_stat.intr_histogram++;
+		ret = mdp_histogram_block2mgmt(MDP_BLOCK_DMA_P, &mgmt);
+		if (!ret)
+			mdp_histogram_handle_isr(mgmt);
+	}
+	if (isr & INTR_DMA_S_HISTOGRAM) {
+		mdp4_stat.intr_histogram++;
+		ret = mdp_histogram_block2mgmt(MDP_BLOCK_DMA_S, &mgmt);
+		if (!ret)
+			mdp_histogram_handle_isr(mgmt);
+	}
+	if (isr & INTR_VG1_HISTOGRAM) {
+		mdp4_stat.intr_histogram++;
+		ret = mdp_histogram_block2mgmt(MDP_BLOCK_VG_1, &mgmt);
+		if (!ret)
+			mdp_histogram_handle_isr(mgmt);
+	}
+	if (isr & INTR_VG2_HISTOGRAM) {
+		mdp4_stat.intr_histogram++;
+		ret = mdp_histogram_block2mgmt(MDP_BLOCK_VG_2, &mgmt);
+		if (!ret)
+			mdp_histogram_handle_isr(mgmt);
+	}
+	if (isr & INTR_PRIMARY_RDPTR) {
+		mdp4_stat.intr_rdptr++;
+		mdp4_primary_rdptr();
+	}
+
+out:
+	mdp_is_in_isr = FALSE;
+
+	return IRQ_HANDLED;
+}
 
 
 /*
  * QSEED tables
  */
 
-static uint32_t vg_qseed_table0[] = {
+static uint32 vg_qseed_table0[] = {
 	0x5556aaff, 0x00000000, 0x00000000, 0x00000000
 };
 
-static uint32_t vg_qseed_table1[] = {
-	0x76543210, 0xfedcba98
+static uint32 vg_qseed_table1[] = {
+	0x00000000, 0x20000000,
 };
 
-static uint32_t vg_qseed_table2[] = {
-	0x02000000, 0x00000000, 0x02060ff2, 0x00000008,
-	0x02090fe4, 0x00000013, 0x020a0fd9, 0x0ffc0021,
-	0x02080fce, 0x0ffa0030, 0x02030fc5, 0x0ff60042,
-	0x01fd0fbe, 0x0ff10054, 0x01f50fb6, 0x0fed0068,
-	0x01e90fb1, 0x0fe60080, 0x01dc0fae, 0x0fe10095,
-	0x01ca0fae, 0x0fda00ae, 0x01b70fad, 0x0fd600c6,
-	0x01a40fad, 0x0fcf00e0, 0x018f0faf, 0x0fc800fa,
-	0x01780fb1, 0x0fc30114, 0x015f0fb5, 0x0fbf012d,
-	0x01490fb7, 0x0fb70149, 0x012d0fbf, 0x0fb5015f,
-	0x01140fc3, 0x0fb10178, 0x00fa0fc8, 0x0faf018f,
-	0x00e00fcf, 0x0fad01a4, 0x00c60fd6, 0x0fad01b7,
-	0x00ae0fda, 0x0fae01ca, 0x00950fe1, 0x0fae01dc,
-	0x00800fe6, 0x0fb101e9, 0x00680fed, 0x0fb601f5,
-	0x00540ff1, 0x0fbe01fd, 0x00420ff6, 0x0fc50203,
-	0x00300ffa, 0x0fce0208, 0x00210ffc, 0x0fd9020a,
-	0x00130000, 0x0fe40209, 0x00080000, 0x0ff20206,
-	0x02000000, 0x00000000, 0x02040ff2, 0x0000000a,
-	0x02040fe4, 0x00000018, 0x02010fda, 0x0ffc0029,
-	0x01fc0fcf, 0x0ffa003b, 0x01f30fc7, 0x0ff60050,
-	0x01e90fc0, 0x0ff20065, 0x01dc0fba, 0x0fee007c,
-	0x01cc0fb6, 0x0fe80096, 0x01ba0fb4, 0x0fe400ae,
-	0x01a70fb4, 0x0fdd00c8, 0x018f0fb5, 0x0fda00e2,
-	0x017a0fb5, 0x0fd400fd, 0x01630fb8, 0x0fce0117,
-	0x014c0fba, 0x0fca0130, 0x01320fbf, 0x0fc70148,
-	0x011b0fc1, 0x0fc10163, 0x01010fc8, 0x0fc00177,
-	0x00e90fcd, 0x0fbd018d, 0x00d10fd1, 0x0fbc01a2,
-	0x00ba0fd7, 0x0fbb01b4, 0x00a30fdd, 0x0fbc01c4,
-	0x008e0fe1, 0x0fbd01d4, 0x00790fe7, 0x0fbe01e2,
-	0x00670feb, 0x0fc001ee, 0x00540ff1, 0x0fc501f6,
-	0x00430ff4, 0x0fcb01fe, 0x00340ff8, 0x0fd10203,
-	0x00260ffb, 0x0fd80207, 0x001a0ffd, 0x0fe10208,
-	0x000f0000, 0x0fea0207, 0x00060000, 0x0ff50205,
-	0x02000000, 0x00000000, 0x02020ff2, 0x0000000c,
-	0x02000fe4, 0x0000001c, 0x01fa0fda, 0x0ffc0030,
-	0x01f10fd0, 0x0ffa0045, 0x01e50fc8, 0x0ff6005d,
-	0x01d60fc3, 0x0ff30074, 0x01c60fbd, 0x0fef008e,
-	0x01b30fba, 0x0fe900aa, 0x019e0fb9, 0x0fe500c4,
-	0x01870fba, 0x0fe000df, 0x016f0fbb, 0x0fdd00f9,
-	0x01580fbc, 0x0fd80114, 0x01400fbf, 0x0fd3012e,
-	0x01280fc2, 0x0fd00146, 0x010f0fc6, 0x0fce015d,
-	0x00f90fc9, 0x0fc90175, 0x00e00fcf, 0x0fc90188,
-	0x00ca0fd4, 0x0fc6019c, 0x00b40fd8, 0x0fc601ae,
-	0x009f0fdd, 0x0fc501bf, 0x008b0fe3, 0x0fc601cc,
-	0x00780fe6, 0x0fc701db, 0x00660feb, 0x0fc801e7,
-	0x00560fef, 0x0fcb01f0, 0x00460ff3, 0x0fcf01f8,
-	0x00380ff6, 0x0fd401fe, 0x002c0ff9, 0x0fd90202,
-	0x00200ffc, 0x0fdf0205, 0x00160ffe, 0x0fe60206,
-	0x000c0000, 0x0fed0207, 0x00050000, 0x0ff70204,
-	0x02000000, 0x00000000, 0x01fe0ff3, 0x0000000f,
-	0x01f60fe5, 0x00000025, 0x01ea0fdb, 0x0ffd003e,
-	0x01db0fd2, 0x0ffb0058, 0x01c80fcc, 0x0ff70075,
-	0x01b50fc7, 0x0ff40090, 0x01a00fc3, 0x0ff000ad,
-	0x01880fc1, 0x0feb00cc, 0x01700fc1, 0x0fe800e7,
-	0x01550fc3, 0x0fe40104, 0x013b0fc5, 0x0fe2011e,
-	0x01240fc6, 0x0fde0138, 0x010c0fca, 0x0fda0150,
-	0x00f40fcd, 0x0fd90166, 0x00dd0fd1, 0x0fd7017b,
-	0x00c80fd4, 0x0fd40190, 0x00b20fd9, 0x0fd401a1,
-	0x009f0fdd, 0x0fd301b1, 0x008c0fe1, 0x0fd301c0,
-	0x007b0fe5, 0x0fd301cd, 0x006a0fea, 0x0fd401d8,
-	0x005c0fec, 0x0fd501e3, 0x004d0ff0, 0x0fd601ed,
-	0x00410ff3, 0x0fd801f4, 0x00340ff7, 0x0fdb01fa,
-	0x002a0ff9, 0x0fdf01fe, 0x00200ffb, 0x0fe30202,
-	0x00180ffd, 0x0fe70204, 0x00100ffe, 0x0fed0205,
-	0x00090000, 0x0ff20205, 0x00040000, 0x0ff90203,
-	0x02000000, 0x00000000, 0x02050ff5, 0x00000006,
-	0x02070fea, 0x0000000f, 0x02080fe1, 0x0ffd001a,
-	0x02070fd8, 0x0ffb0026, 0x02030fd1, 0x0ff80034,
-	0x01fe0fcb, 0x0ff40043, 0x01f60fc5, 0x0ff10054,
-	0x01ee0fc0, 0x0feb0067, 0x01e20fbe, 0x0fe70079,
-	0x01d40fbd, 0x0fe1008e, 0x01c40fbc, 0x0fdd00a3,
-	0x01b40fbb, 0x0fd700ba, 0x01a20fbc, 0x0fd100d1,
-	0x018d0fbd, 0x0fcd00e9, 0x01770fc0, 0x0fc80101,
-	0x01630fc1, 0x0fc1011b, 0x01480fc7, 0x0fbf0132,
-	0x01300fca, 0x0fba014c, 0x01170fce, 0x0fb80163,
-	0x00fd0fd4, 0x0fb5017a, 0x00e20fda, 0x0fb5018f,
-	0x00c80fdd, 0x0fb401a7, 0x00ae0fe4, 0x0fb401ba,
-	0x00960fe8, 0x0fb601cc, 0x007c0fee, 0x0fba01dc,
-	0x00650ff2, 0x0fc001e9, 0x00500ff6, 0x0fc701f3,
-	0x003b0ffa, 0x0fcf01fc, 0x00290ffc, 0x0fda0201,
-	0x00180000, 0x0fe40204, 0x000a0000, 0x0ff20204,
-	0x02000000, 0x00000000, 0x02030ff5, 0x00000008,
-	0x02030fea, 0x00000013, 0x02020fe1, 0x0ffd0020,
-	0x01fc0fd9, 0x0ffc002f, 0x01f60fd2, 0x0ff80040,
-	0x01ed0fcd, 0x0ff50051, 0x01e30fc7, 0x0ff10065,
-	0x01d70fc3, 0x0fec007a, 0x01c60fc2, 0x0fe9008f,
-	0x01b60fc1, 0x0fe300a6, 0x01a20fc1, 0x0fe000bd,
-	0x018f0fc1, 0x0fdb00d5, 0x017b0fc2, 0x0fd500ee,
-	0x01640fc4, 0x0fd20106, 0x014d0fc8, 0x0fce011d,
-	0x01370fc9, 0x0fc90137, 0x011d0fce, 0x0fc8014d,
-	0x01060fd2, 0x0fc40164, 0x00ee0fd5, 0x0fc2017b,
-	0x00d50fdb, 0x0fc1018f, 0x00bd0fe0, 0x0fc101a2,
-	0x00a60fe3, 0x0fc101b6, 0x008f0fe9, 0x0fc201c6,
-	0x007a0fec, 0x0fc301d7, 0x00650ff1, 0x0fc701e3,
-	0x00510ff5, 0x0fcd01ed, 0x00400ff8, 0x0fd201f6,
-	0x002f0ffc, 0x0fd901fc, 0x00200ffd, 0x0fe10202,
-	0x00130000, 0x0fea0203, 0x00080000, 0x0ff50203,
-	0x02000000, 0x00000000, 0x02020ff5, 0x00000009,
-	0x01ff0fea, 0x00000017, 0x01fb0fe2, 0x0ffd0026,
-	0x01f30fda, 0x0ffc0037, 0x01ea0fd3, 0x0ff8004b,
-	0x01df0fce, 0x0ff5005e, 0x01d10fc9, 0x0ff20074,
-	0x01c10fc6, 0x0fed008c, 0x01ae0fc5, 0x0fea00a3,
-	0x019b0fc5, 0x0fe500bb, 0x01850fc6, 0x0fe200d3,
-	0x01700fc6, 0x0fde00ec, 0x015a0fc8, 0x0fd90105,
-	0x01430fca, 0x0fd6011d, 0x012b0fcd, 0x0fd30135,
-	0x01150fcf, 0x0fcf014d, 0x00fc0fd4, 0x0fce0162,
-	0x00e50fd8, 0x0fcc0177, 0x00cf0fdb, 0x0fca018c,
-	0x00b80fe0, 0x0fc9019f, 0x00a20fe5, 0x0fca01af,
-	0x008e0fe8, 0x0fcb01bf, 0x00790fec, 0x0fcb01d0,
-	0x00670fef, 0x0fcd01dd, 0x00550ff4, 0x0fd001e7,
-	0x00440ff7, 0x0fd501f0, 0x00350ffa, 0x0fda01f7,
-	0x00270ffc, 0x0fdf01fe, 0x001b0ffe, 0x0fe70200,
-	0x00100000, 0x0fee0202, 0x00060000, 0x0ff70203,
-	0x02000000, 0x00000000, 0x01ff0ff5, 0x0000000c,
-	0x01f80fea, 0x0000001e, 0x01ef0fe2, 0x0ffd0032,
-	0x01e20fdb, 0x0ffc0047, 0x01d30fd5, 0x0ff9005f,
-	0x01c20fd1, 0x0ff60077, 0x01b00fcd, 0x0ff30090,
-	0x019b0fcb, 0x0fef00ab, 0x01850fcb, 0x0fec00c4,
-	0x016e0fcc, 0x0fe800de, 0x01550fcd, 0x0fe600f8,
-	0x013f0fce, 0x0fe20111, 0x01280fd0, 0x0fdf0129,
-	0x01110fd2, 0x0fdd0140, 0x00f90fd6, 0x0fdb0156,
-	0x00e40fd8, 0x0fd8016c, 0x00cd0fdd, 0x0fd8017e,
-	0x00b80fe0, 0x0fd60192, 0x00a40fe3, 0x0fd601a3,
-	0x00910fe7, 0x0fd501b3, 0x007f0feb, 0x0fd601c0,
-	0x006e0fed, 0x0fd701ce, 0x005d0ff1, 0x0fd701db,
-	0x004f0ff3, 0x0fd901e5, 0x00400ff7, 0x0fdc01ed,
-	0x00330ff9, 0x0fe001f4, 0x00280ffb, 0x0fe301fa,
-	0x001d0ffd, 0x0fe801fe, 0x00140ffe, 0x0fed0201,
-	0x000c0000, 0x0ff20202, 0x00050000, 0x0ff90202,
-	0x02000000, 0x00000000, 0x02040ff7, 0x00000005,
-	0x02070fed, 0x0000000c, 0x02060fe6, 0x0ffe0016,
-	0x02050fdf, 0x0ffc0020, 0x02020fd9, 0x0ff9002c,
-	0x01fe0fd4, 0x0ff60038, 0x01f80fcf, 0x0ff30046,
-	0x01f00fcb, 0x0fef0056, 0x01e70fc8, 0x0feb0066,
-	0x01db0fc7, 0x0fe60078, 0x01cc0fc6, 0x0fe3008b,
-	0x01bf0fc5, 0x0fdd009f, 0x01ae0fc6, 0x0fd800b4,
-	0x019c0fc6, 0x0fd400ca, 0x01880fc9, 0x0fcf00e0,
-	0x01750fc9, 0x0fc900f9, 0x015d0fce, 0x0fc6010f,
-	0x01460fd0, 0x0fc20128, 0x012e0fd3, 0x0fbf0140,
-	0x01140fd8, 0x0fbc0158, 0x00f90fdd, 0x0fbb016f,
-	0x00df0fe0, 0x0fba0187, 0x00c40fe5, 0x0fb9019e,
-	0x00aa0fe9, 0x0fba01b3, 0x008e0fef, 0x0fbd01c6,
-	0x00740ff3, 0x0fc301d6, 0x005d0ff6, 0x0fc801e5,
-	0x00450ffa, 0x0fd001f1, 0x00300ffc, 0x0fda01fa,
-	0x001c0000, 0x0fe40200, 0x000c0000, 0x0ff20202,
-	0x02000000, 0x00000000, 0x02030ff7, 0x00000006,
-	0x02020fee, 0x00000010, 0x02000fe7, 0x0ffe001b,
-	0x01fe0fdf, 0x0ffc0027, 0x01f70fda, 0x0ffa0035,
-	0x01f00fd5, 0x0ff70044, 0x01e70fd0, 0x0ff40055,
-	0x01dd0fcd, 0x0fef0067, 0x01d00fcb, 0x0fec0079,
-	0x01bf0fcb, 0x0fe8008e, 0x01af0fca, 0x0fe500a2,
-	0x019f0fc9, 0x0fe000b8, 0x018c0fca, 0x0fdb00cf,
-	0x01770fcc, 0x0fd800e5, 0x01620fce, 0x0fd400fc,
-	0x014d0fcf, 0x0fcf0115, 0x01350fd3, 0x0fcd012b,
-	0x011d0fd6, 0x0fca0143, 0x01050fd9, 0x0fc8015a,
-	0x00ec0fde, 0x0fc60170, 0x00d30fe2, 0x0fc60185,
-	0x00bb0fe5, 0x0fc5019b, 0x00a30fea, 0x0fc501ae,
-	0x008c0fed, 0x0fc601c1, 0x00740ff2, 0x0fc901d1,
-	0x005e0ff5, 0x0fce01df, 0x004b0ff8, 0x0fd301ea,
-	0x00370ffc, 0x0fda01f3, 0x00260ffd, 0x0fe201fb,
-	0x00170000, 0x0fea01ff, 0x00090000, 0x0ff50202,
-	0x02000000, 0x00000000, 0x02010ff7, 0x00000008,
-	0x01ff0fee, 0x00000013, 0x01fb0fe7, 0x0ffe0020,
-	0x01f60fe0, 0x0ffc002e, 0x01ed0fda, 0x0ffa003f,
-	0x01e40fd6, 0x0ff7004f, 0x01d80fd2, 0x0ff40062,
-	0x01ca0fcf, 0x0ff00077, 0x01bb0fcd, 0x0fed008b,
-	0x01a90fcd, 0x0fe900a1, 0x01960fcd, 0x0fe600b7,
-	0x01830fcd, 0x0fe200ce, 0x016d0fcf, 0x0fde00e6,
-	0x01580fd0, 0x0fdb00fd, 0x01410fd3, 0x0fd80114,
-	0x012c0fd4, 0x0fd4012c, 0x01140fd8, 0x0fd30141,
-	0x00fd0fdb, 0x0fd00158, 0x00e60fde, 0x0fcf016d,
-	0x00ce0fe2, 0x0fcd0183, 0x00b70fe6, 0x0fcd0196,
-	0x00a10fe9, 0x0fcd01a9, 0x008b0fed, 0x0fcd01bb,
-	0x00770ff0, 0x0fcf01ca, 0x00620ff4, 0x0fd201d8,
-	0x004f0ff7, 0x0fd601e4, 0x003f0ffa, 0x0fda01ed,
-	0x002e0ffc, 0x0fe001f6, 0x00200ffe, 0x0fe701fb,
-	0x00130000, 0x0fee01ff, 0x00080000, 0x0ff70201,
-	0x02000000, 0x00000000, 0x01ff0ff7, 0x0000000a,
-	0x01f90fee, 0x00000019, 0x01f10fe7, 0x0ffe002a,
-	0x01e60fe1, 0x0ffd003c, 0x01d90fdc, 0x0ffa0051,
-	0x01cc0fd8, 0x0ff70065, 0x01bb0fd5, 0x0ff5007b,
-	0x01a80fd3, 0x0ff10094, 0x01950fd2, 0x0fef00aa,
-	0x01800fd2, 0x0feb00c3, 0x016a0fd3, 0x0fe900da,
-	0x01540fd3, 0x0fe600f3, 0x013f0fd5, 0x0fe2010a,
-	0x01280fd7, 0x0fe00121, 0x01100fda, 0x0fde0138,
-	0x00fb0fdb, 0x0fdb014f, 0x00e40fdf, 0x0fdb0162,
-	0x00ce0fe2, 0x0fd90177, 0x00b90fe4, 0x0fd8018b,
-	0x00a50fe8, 0x0fd8019b, 0x00910fec, 0x0fd801ab,
-	0x007e0fee, 0x0fd801bc, 0x006c0ff2, 0x0fd901c9,
-	0x005c0ff4, 0x0fda01d6, 0x004b0ff7, 0x0fdd01e1,
-	0x003c0ff9, 0x0fe001eb, 0x002f0ffb, 0x0fe401f2,
-	0x00230ffd, 0x0fe801f8, 0x00180ffe, 0x0fed01fd,
-	0x000e0000, 0x0ff20200, 0x00060000, 0x0ff90201,
-	0x02000000, 0x00000000, 0x02030ff9, 0x00000004,
-	0x02050ff2, 0x00000009, 0x02050fed, 0x0ffe0010,
-	0x02040fe7, 0x0ffd0018, 0x02020fe3, 0x0ffb0020,
-	0x01fe0fdf, 0x0ff9002a, 0x01fa0fdb, 0x0ff70034,
-	0x01f40fd8, 0x0ff30041, 0x01ed0fd6, 0x0ff0004d,
-	0x01e30fd5, 0x0fec005c, 0x01d80fd4, 0x0fea006a,
-	0x01cd0fd3, 0x0fe5007b, 0x01c00fd3, 0x0fe1008c,
-	0x01b10fd3, 0x0fdd009f, 0x01a10fd4, 0x0fd900b2,
-	0x01900fd4, 0x0fd400c8, 0x017b0fd7, 0x0fd100dd,
-	0x01660fd9, 0x0fcd00f4, 0x01500fda, 0x0fca010c,
-	0x01380fde, 0x0fc60124, 0x011e0fe2, 0x0fc5013b,
-	0x01040fe4, 0x0fc30155, 0x00e70fe8, 0x0fc10170,
-	0x00cc0feb, 0x0fc10188, 0x00ad0ff0, 0x0fc301a0,
-	0x00900ff4, 0x0fc701b5, 0x00750ff7, 0x0fcc01c8,
-	0x00580ffb, 0x0fd201db, 0x003e0ffd, 0x0fdb01ea,
-	0x00250000, 0x0fe501f6, 0x000f0000, 0x0ff301fe,
-	0x02000000, 0x00000000, 0x02020ff9, 0x00000005,
-	0x02020ff2, 0x0000000c, 0x02010fed, 0x0ffe0014,
-	0x01fe0fe8, 0x0ffd001d, 0x01fa0fe3, 0x0ffb0028,
-	0x01f40fe0, 0x0ff90033, 0x01ed0fdc, 0x0ff70040,
-	0x01e50fd9, 0x0ff3004f, 0x01db0fd7, 0x0ff1005d,
-	0x01ce0fd7, 0x0fed006e, 0x01c00fd6, 0x0feb007f,
-	0x01b30fd5, 0x0fe70091, 0x01a30fd6, 0x0fe300a4,
-	0x01920fd6, 0x0fe000b8, 0x017e0fd8, 0x0fdd00cd,
-	0x016c0fd8, 0x0fd800e4, 0x01560fdb, 0x0fd600f9,
-	0x01400fdd, 0x0fd20111, 0x01290fdf, 0x0fd00128,
-	0x01110fe2, 0x0fce013f, 0x00f80fe6, 0x0fcd0155,
-	0x00de0fe8, 0x0fcc016e, 0x00c40fec, 0x0fcb0185,
-	0x00ab0fef, 0x0fcb019b, 0x00900ff3, 0x0fcd01b0,
-	0x00770ff6, 0x0fd101c2, 0x005f0ff9, 0x0fd501d3,
-	0x00470ffc, 0x0fdb01e2, 0x00320ffd, 0x0fe201ef,
-	0x001e0000, 0x0fea01f8, 0x000c0000, 0x0ff501ff,
-	0x02000000, 0x00000000, 0x02010ff9, 0x00000006,
-	0x02000ff2, 0x0000000e, 0x01fd0fed, 0x0ffe0018,
-	0x01f80fe8, 0x0ffd0023, 0x01f20fe4, 0x0ffb002f,
-	0x01eb0fe0, 0x0ff9003c, 0x01e10fdd, 0x0ff7004b,
-	0x01d60fda, 0x0ff4005c, 0x01c90fd9, 0x0ff2006c,
-	0x01bc0fd8, 0x0fee007e, 0x01ab0fd8, 0x0fec0091,
-	0x019b0fd8, 0x0fe800a5, 0x018b0fd8, 0x0fe400b9,
-	0x01770fd9, 0x0fe200ce, 0x01620fdb, 0x0fdf00e4,
-	0x014f0fdb, 0x0fdb00fb, 0x01380fde, 0x0fda0110,
-	0x01210fe0, 0x0fd70128, 0x010a0fe2, 0x0fd5013f,
-	0x00f30fe6, 0x0fd30154, 0x00da0fe9, 0x0fd3016a,
-	0x00c30feb, 0x0fd20180, 0x00aa0fef, 0x0fd20195,
-	0x00940ff1, 0x0fd301a8, 0x007b0ff5, 0x0fd501bb,
-	0x00650ff7, 0x0fd801cc, 0x00510ffa, 0x0fdc01d9,
-	0x003c0ffd, 0x0fe101e6, 0x002a0ffe, 0x0fe701f1,
-	0x00190000, 0x0fee01f9, 0x000a0000, 0x0ff701ff,
+static uint32 vg_qseed_table2[] = {
 	0x02000000, 0x00000000, 0x01ff0ff9, 0x00000008,
 	0x01fb0ff2, 0x00000013, 0x01f50fed, 0x0ffe0020,
 	0x01ed0fe8, 0x0ffd002e, 0x01e30fe4, 0x0ffb003e,
@@ -615,246 +592,262 @@
 	0x004e0ff9, 0x0fe101d8, 0x003e0ffb, 0x0fe401e3,
 	0x002e0ffd, 0x0fe801ed, 0x00200ffe, 0x0fed01f5,
 	0x00130000, 0x0ff201fb, 0x00080000, 0x0ff901ff,
-	0x02000000, 0x00000000, 0x02060ff2, 0x00000008,
-	0x02090fe4, 0x00000013, 0x020a0fd9, 0x0ffc0021,
-	0x02080fce, 0x0ffa0030, 0x02030fc5, 0x0ff60042,
-	0x01fd0fbe, 0x0ff10054, 0x01f50fb6, 0x0fed0068,
-	0x01e90fb1, 0x0fe60080, 0x01dc0fae, 0x0fe10095,
-	0x01ca0fae, 0x0fda00ae, 0x01b70fad, 0x0fd600c6,
-	0x01a40fad, 0x0fcf00e0, 0x018f0faf, 0x0fc800fa,
-	0x01780fb1, 0x0fc30114, 0x015f0fb5, 0x0fbf012d,
-	0x01490fb7, 0x0fb70149, 0x012d0fbf, 0x0fb5015f,
-	0x01140fc3, 0x0fb10178, 0x00fa0fc8, 0x0faf018f,
-	0x00e00fcf, 0x0fad01a4, 0x00c60fd6, 0x0fad01b7,
-	0x00ae0fda, 0x0fae01ca, 0x00950fe1, 0x0fae01dc,
-	0x00800fe6, 0x0fb101e9, 0x00680fed, 0x0fb601f5,
-	0x00540ff1, 0x0fbe01fd, 0x00420ff6, 0x0fc50203,
-	0x00300ffa, 0x0fce0208, 0x00210ffc, 0x0fd9020a,
-	0x00130000, 0x0fe40209, 0x00080000, 0x0ff20206,
-	0x02000000, 0x00000000, 0x02040ff2, 0x0000000a,
-	0x02040fe4, 0x00000018, 0x02010fda, 0x0ffc0029,
-	0x01fc0fcf, 0x0ffa003b, 0x01f30fc7, 0x0ff60050,
-	0x01e90fc0, 0x0ff20065, 0x01dc0fba, 0x0fee007c,
-	0x01cc0fb6, 0x0fe80096, 0x01ba0fb4, 0x0fe400ae,
-	0x01a70fb4, 0x0fdd00c8, 0x018f0fb5, 0x0fda00e2,
-	0x017a0fb5, 0x0fd400fd, 0x01630fb8, 0x0fce0117,
-	0x014c0fba, 0x0fca0130, 0x01320fbf, 0x0fc70148,
-	0x011b0fc1, 0x0fc10163, 0x01010fc8, 0x0fc00177,
-	0x00e90fcd, 0x0fbd018d, 0x00d10fd1, 0x0fbc01a2,
-	0x00ba0fd7, 0x0fbb01b4, 0x00a30fdd, 0x0fbc01c4,
-	0x008e0fe1, 0x0fbd01d4, 0x00790fe7, 0x0fbe01e2,
-	0x00670feb, 0x0fc001ee, 0x00540ff1, 0x0fc501f6,
-	0x00430ff4, 0x0fcb01fe, 0x00340ff8, 0x0fd10203,
-	0x00260ffb, 0x0fd80207, 0x001a0ffd, 0x0fe10208,
-	0x000f0000, 0x0fea0207, 0x00060000, 0x0ff50205,
-	0x02000000, 0x00000000, 0x02020ff2, 0x0000000c,
-	0x02000fe4, 0x0000001c, 0x01fa0fda, 0x0ffc0030,
-	0x01f10fd0, 0x0ffa0045, 0x01e50fc8, 0x0ff6005d,
-	0x01d60fc3, 0x0ff30074, 0x01c60fbd, 0x0fef008e,
-	0x01b30fba, 0x0fe900aa, 0x019e0fb9, 0x0fe500c4,
-	0x01870fba, 0x0fe000df, 0x016f0fbb, 0x0fdd00f9,
-	0x01580fbc, 0x0fd80114, 0x01400fbf, 0x0fd3012e,
-	0x01280fc2, 0x0fd00146, 0x010f0fc6, 0x0fce015d,
-	0x00f90fc9, 0x0fc90175, 0x00e00fcf, 0x0fc90188,
-	0x00ca0fd4, 0x0fc6019c, 0x00b40fd8, 0x0fc601ae,
-	0x009f0fdd, 0x0fc501bf, 0x008b0fe3, 0x0fc601cc,
-	0x00780fe6, 0x0fc701db, 0x00660feb, 0x0fc801e7,
-	0x00560fef, 0x0fcb01f0, 0x00460ff3, 0x0fcf01f8,
-	0x00380ff6, 0x0fd401fe, 0x002c0ff9, 0x0fd90202,
-	0x00200ffc, 0x0fdf0205, 0x00160ffe, 0x0fe60206,
-	0x000c0000, 0x0fed0207, 0x00050000, 0x0ff70204,
-	0x02000000, 0x00000000, 0x01fe0ff3, 0x0000000f,
-	0x01f60fe5, 0x00000025, 0x01ea0fdb, 0x0ffd003e,
-	0x01db0fd2, 0x0ffb0058, 0x01c80fcc, 0x0ff70075,
-	0x01b50fc7, 0x0ff40090, 0x01a00fc3, 0x0ff000ad,
-	0x01880fc1, 0x0feb00cc, 0x01700fc1, 0x0fe800e7,
-	0x01550fc3, 0x0fe40104, 0x013b0fc5, 0x0fe2011e,
-	0x01240fc6, 0x0fde0138, 0x010c0fca, 0x0fda0150,
-	0x00f40fcd, 0x0fd90166, 0x00dd0fd1, 0x0fd7017b,
-	0x00c80fd4, 0x0fd40190, 0x00b20fd9, 0x0fd401a1,
-	0x009f0fdd, 0x0fd301b1, 0x008c0fe1, 0x0fd301c0,
-	0x007b0fe5, 0x0fd301cd, 0x006a0fea, 0x0fd401d8,
-	0x005c0fec, 0x0fd501e3, 0x004d0ff0, 0x0fd601ed,
-	0x00410ff3, 0x0fd801f4, 0x00340ff7, 0x0fdb01fa,
-	0x002a0ff9, 0x0fdf01fe, 0x00200ffb, 0x0fe30202,
-	0x00180ffd, 0x0fe70204, 0x00100ffe, 0x0fed0205,
-	0x00090000, 0x0ff20205, 0x00040000, 0x0ff90203,
-	0x02000000, 0x00000000, 0x02050ff5, 0x00000006,
-	0x02070fea, 0x0000000f, 0x02080fe1, 0x0ffd001a,
-	0x02070fd8, 0x0ffb0026, 0x02030fd1, 0x0ff80034,
-	0x01fe0fcb, 0x0ff40043, 0x01f60fc5, 0x0ff10054,
-	0x01ee0fc0, 0x0feb0067, 0x01e20fbe, 0x0fe70079,
-	0x01d40fbd, 0x0fe1008e, 0x01c40fbc, 0x0fdd00a3,
-	0x01b40fbb, 0x0fd700ba, 0x01a20fbc, 0x0fd100d1,
-	0x018d0fbd, 0x0fcd00e9, 0x01770fc0, 0x0fc80101,
-	0x01630fc1, 0x0fc1011b, 0x01480fc7, 0x0fbf0132,
-	0x01300fca, 0x0fba014c, 0x01170fce, 0x0fb80163,
-	0x00fd0fd4, 0x0fb5017a, 0x00e20fda, 0x0fb5018f,
-	0x00c80fdd, 0x0fb401a7, 0x00ae0fe4, 0x0fb401ba,
-	0x00960fe8, 0x0fb601cc, 0x007c0fee, 0x0fba01dc,
-	0x00650ff2, 0x0fc001e9, 0x00500ff6, 0x0fc701f3,
-	0x003b0ffa, 0x0fcf01fc, 0x00290ffc, 0x0fda0201,
-	0x00180000, 0x0fe40204, 0x000a0000, 0x0ff20204,
-	0x02000000, 0x00000000, 0x02030ff5, 0x00000008,
-	0x02030fea, 0x00000013, 0x02020fe1, 0x0ffd0020,
-	0x01fc0fd9, 0x0ffc002f, 0x01f60fd2, 0x0ff80040,
-	0x01ed0fcd, 0x0ff50051, 0x01e30fc7, 0x0ff10065,
-	0x01d70fc3, 0x0fec007a, 0x01c60fc2, 0x0fe9008f,
-	0x01b60fc1, 0x0fe300a6, 0x01a20fc1, 0x0fe000bd,
-	0x018f0fc1, 0x0fdb00d5, 0x017b0fc2, 0x0fd500ee,
-	0x01640fc4, 0x0fd20106, 0x014d0fc8, 0x0fce011d,
-	0x01370fc9, 0x0fc90137, 0x011d0fce, 0x0fc8014d,
-	0x01060fd2, 0x0fc40164, 0x00ee0fd5, 0x0fc2017b,
-	0x00d50fdb, 0x0fc1018f, 0x00bd0fe0, 0x0fc101a2,
-	0x00a60fe3, 0x0fc101b6, 0x008f0fe9, 0x0fc201c6,
-	0x007a0fec, 0x0fc301d7, 0x00650ff1, 0x0fc701e3,
-	0x00510ff5, 0x0fcd01ed, 0x00400ff8, 0x0fd201f6,
-	0x002f0ffc, 0x0fd901fc, 0x00200ffd, 0x0fe10202,
-	0x00130000, 0x0fea0203, 0x00080000, 0x0ff50203,
-	0x02000000, 0x00000000, 0x02020ff5, 0x00000009,
-	0x01ff0fea, 0x00000017, 0x01fb0fe2, 0x0ffd0026,
-	0x01f30fda, 0x0ffc0037, 0x01ea0fd3, 0x0ff8004b,
-	0x01df0fce, 0x0ff5005e, 0x01d10fc9, 0x0ff20074,
-	0x01c10fc6, 0x0fed008c, 0x01ae0fc5, 0x0fea00a3,
-	0x019b0fc5, 0x0fe500bb, 0x01850fc6, 0x0fe200d3,
-	0x01700fc6, 0x0fde00ec, 0x015a0fc8, 0x0fd90105,
-	0x01430fca, 0x0fd6011d, 0x012b0fcd, 0x0fd30135,
-	0x01150fcf, 0x0fcf014d, 0x00fc0fd4, 0x0fce0162,
-	0x00e50fd8, 0x0fcc0177, 0x00cf0fdb, 0x0fca018c,
-	0x00b80fe0, 0x0fc9019f, 0x00a20fe5, 0x0fca01af,
-	0x008e0fe8, 0x0fcb01bf, 0x00790fec, 0x0fcb01d0,
-	0x00670fef, 0x0fcd01dd, 0x00550ff4, 0x0fd001e7,
-	0x00440ff7, 0x0fd501f0, 0x00350ffa, 0x0fda01f7,
-	0x00270ffc, 0x0fdf01fe, 0x001b0ffe, 0x0fe70200,
-	0x00100000, 0x0fee0202, 0x00060000, 0x0ff70203,
-	0x02000000, 0x00000000, 0x01ff0ff5, 0x0000000c,
-	0x01f80fea, 0x0000001e, 0x01ef0fe2, 0x0ffd0032,
-	0x01e20fdb, 0x0ffc0047, 0x01d30fd5, 0x0ff9005f,
-	0x01c20fd1, 0x0ff60077, 0x01b00fcd, 0x0ff30090,
-	0x019b0fcb, 0x0fef00ab, 0x01850fcb, 0x0fec00c4,
-	0x016e0fcc, 0x0fe800de, 0x01550fcd, 0x0fe600f8,
-	0x013f0fce, 0x0fe20111, 0x01280fd0, 0x0fdf0129,
-	0x01110fd2, 0x0fdd0140, 0x00f90fd6, 0x0fdb0156,
-	0x00e40fd8, 0x0fd8016c, 0x00cd0fdd, 0x0fd8017e,
-	0x00b80fe0, 0x0fd60192, 0x00a40fe3, 0x0fd601a3,
-	0x00910fe7, 0x0fd501b3, 0x007f0feb, 0x0fd601c0,
-	0x006e0fed, 0x0fd701ce, 0x005d0ff1, 0x0fd701db,
-	0x004f0ff3, 0x0fd901e5, 0x00400ff7, 0x0fdc01ed,
-	0x00330ff9, 0x0fe001f4, 0x00280ffb, 0x0fe301fa,
-	0x001d0ffd, 0x0fe801fe, 0x00140ffe, 0x0fed0201,
-	0x000c0000, 0x0ff20202, 0x00050000, 0x0ff90202,
-	0x02000000, 0x00000000, 0x02040ff7, 0x00000005,
-	0x02070fed, 0x0000000c, 0x02060fe6, 0x0ffe0016,
-	0x02050fdf, 0x0ffc0020, 0x02020fd9, 0x0ff9002c,
-	0x01fe0fd4, 0x0ff60038, 0x01f80fcf, 0x0ff30046,
-	0x01f00fcb, 0x0fef0056, 0x01e70fc8, 0x0feb0066,
-	0x01db0fc7, 0x0fe60078, 0x01cc0fc6, 0x0fe3008b,
-	0x01bf0fc5, 0x0fdd009f, 0x01ae0fc6, 0x0fd800b4,
-	0x019c0fc6, 0x0fd400ca, 0x01880fc9, 0x0fcf00e0,
-	0x01750fc9, 0x0fc900f9, 0x015d0fce, 0x0fc6010f,
-	0x01460fd0, 0x0fc20128, 0x012e0fd3, 0x0fbf0140,
-	0x01140fd8, 0x0fbc0158, 0x00f90fdd, 0x0fbb016f,
-	0x00df0fe0, 0x0fba0187, 0x00c40fe5, 0x0fb9019e,
-	0x00aa0fe9, 0x0fba01b3, 0x008e0fef, 0x0fbd01c6,
-	0x00740ff3, 0x0fc301d6, 0x005d0ff6, 0x0fc801e5,
-	0x00450ffa, 0x0fd001f1, 0x00300ffc, 0x0fda01fa,
-	0x001c0000, 0x0fe40200, 0x000c0000, 0x0ff20202,
-	0x02000000, 0x00000000, 0x02030ff7, 0x00000006,
-	0x02020fee, 0x00000010, 0x02000fe7, 0x0ffe001b,
-	0x01fe0fdf, 0x0ffc0027, 0x01f70fda, 0x0ffa0035,
-	0x01f00fd5, 0x0ff70044, 0x01e70fd0, 0x0ff40055,
-	0x01dd0fcd, 0x0fef0067, 0x01d00fcb, 0x0fec0079,
-	0x01bf0fcb, 0x0fe8008e, 0x01af0fca, 0x0fe500a2,
-	0x019f0fc9, 0x0fe000b8, 0x018c0fca, 0x0fdb00cf,
-	0x01770fcc, 0x0fd800e5, 0x01620fce, 0x0fd400fc,
-	0x014d0fcf, 0x0fcf0115, 0x01350fd3, 0x0fcd012b,
-	0x011d0fd6, 0x0fca0143, 0x01050fd9, 0x0fc8015a,
-	0x00ec0fde, 0x0fc60170, 0x00d30fe2, 0x0fc60185,
-	0x00bb0fe5, 0x0fc5019b, 0x00a30fea, 0x0fc501ae,
-	0x008c0fed, 0x0fc601c1, 0x00740ff2, 0x0fc901d1,
-	0x005e0ff5, 0x0fce01df, 0x004b0ff8, 0x0fd301ea,
-	0x00370ffc, 0x0fda01f3, 0x00260ffd, 0x0fe201fb,
-	0x00170000, 0x0fea01ff, 0x00090000, 0x0ff50202,
-	0x02000000, 0x00000000, 0x02010ff7, 0x00000008,
-	0x01ff0fee, 0x00000013, 0x01fb0fe7, 0x0ffe0020,
-	0x01f60fe0, 0x0ffc002e, 0x01ed0fda, 0x0ffa003f,
-	0x01e40fd6, 0x0ff7004f, 0x01d80fd2, 0x0ff40062,
-	0x01ca0fcf, 0x0ff00077, 0x01bb0fcd, 0x0fed008b,
-	0x01a90fcd, 0x0fe900a1, 0x01960fcd, 0x0fe600b7,
-	0x01830fcd, 0x0fe200ce, 0x016d0fcf, 0x0fde00e6,
-	0x01580fd0, 0x0fdb00fd, 0x01410fd3, 0x0fd80114,
-	0x012c0fd4, 0x0fd4012c, 0x01140fd8, 0x0fd30141,
-	0x00fd0fdb, 0x0fd00158, 0x00e60fde, 0x0fcf016d,
-	0x00ce0fe2, 0x0fcd0183, 0x00b70fe6, 0x0fcd0196,
-	0x00a10fe9, 0x0fcd01a9, 0x008b0fed, 0x0fcd01bb,
-	0x00770ff0, 0x0fcf01ca, 0x00620ff4, 0x0fd201d8,
-	0x004f0ff7, 0x0fd601e4, 0x003f0ffa, 0x0fda01ed,
-	0x002e0ffc, 0x0fe001f6, 0x00200ffe, 0x0fe701fb,
-	0x00130000, 0x0fee01ff, 0x00080000, 0x0ff70201,
-	0x02000000, 0x00000000, 0x01ff0ff7, 0x0000000a,
-	0x01f90fee, 0x00000019, 0x01f10fe7, 0x0ffe002a,
-	0x01e60fe1, 0x0ffd003c, 0x01d90fdc, 0x0ffa0051,
-	0x01cc0fd8, 0x0ff70065, 0x01bb0fd5, 0x0ff5007b,
-	0x01a80fd3, 0x0ff10094, 0x01950fd2, 0x0fef00aa,
-	0x01800fd2, 0x0feb00c3, 0x016a0fd3, 0x0fe900da,
-	0x01540fd3, 0x0fe600f3, 0x013f0fd5, 0x0fe2010a,
-	0x01280fd7, 0x0fe00121, 0x01100fda, 0x0fde0138,
-	0x00fb0fdb, 0x0fdb014f, 0x00e40fdf, 0x0fdb0162,
-	0x00ce0fe2, 0x0fd90177, 0x00b90fe4, 0x0fd8018b,
-	0x00a50fe8, 0x0fd8019b, 0x00910fec, 0x0fd801ab,
-	0x007e0fee, 0x0fd801bc, 0x006c0ff2, 0x0fd901c9,
-	0x005c0ff4, 0x0fda01d6, 0x004b0ff7, 0x0fdd01e1,
-	0x003c0ff9, 0x0fe001eb, 0x002f0ffb, 0x0fe401f2,
-	0x00230ffd, 0x0fe801f8, 0x00180ffe, 0x0fed01fd,
-	0x000e0000, 0x0ff20200, 0x00060000, 0x0ff90201,
-	0x02000000, 0x00000000, 0x02030ff9, 0x00000004,
-	0x02050ff2, 0x00000009, 0x02050fed, 0x0ffe0010,
-	0x02040fe7, 0x0ffd0018, 0x02020fe3, 0x0ffb0020,
-	0x01fe0fdf, 0x0ff9002a, 0x01fa0fdb, 0x0ff70034,
-	0x01f40fd8, 0x0ff30041, 0x01ed0fd6, 0x0ff0004d,
-	0x01e30fd5, 0x0fec005c, 0x01d80fd4, 0x0fea006a,
-	0x01cd0fd3, 0x0fe5007b, 0x01c00fd3, 0x0fe1008c,
-	0x01b10fd3, 0x0fdd009f, 0x01a10fd4, 0x0fd900b2,
-	0x01900fd4, 0x0fd400c8, 0x017b0fd7, 0x0fd100dd,
-	0x01660fd9, 0x0fcd00f4, 0x01500fda, 0x0fca010c,
-	0x01380fde, 0x0fc60124, 0x011e0fe2, 0x0fc5013b,
-	0x01040fe4, 0x0fc30155, 0x00e70fe8, 0x0fc10170,
-	0x00cc0feb, 0x0fc10188, 0x00ad0ff0, 0x0fc301a0,
-	0x00900ff4, 0x0fc701b5, 0x00750ff7, 0x0fcc01c8,
-	0x00580ffb, 0x0fd201db, 0x003e0ffd, 0x0fdb01ea,
-	0x00250000, 0x0fe501f6, 0x000f0000, 0x0ff301fe,
-	0x02000000, 0x00000000, 0x02020ff9, 0x00000005,
-	0x02020ff2, 0x0000000c, 0x02010fed, 0x0ffe0014,
-	0x01fe0fe8, 0x0ffd001d, 0x01fa0fe3, 0x0ffb0028,
-	0x01f40fe0, 0x0ff90033, 0x01ed0fdc, 0x0ff70040,
-	0x01e50fd9, 0x0ff3004f, 0x01db0fd7, 0x0ff1005d,
-	0x01ce0fd7, 0x0fed006e, 0x01c00fd6, 0x0feb007f,
-	0x01b30fd5, 0x0fe70091, 0x01a30fd6, 0x0fe300a4,
-	0x01920fd6, 0x0fe000b8, 0x017e0fd8, 0x0fdd00cd,
-	0x016c0fd8, 0x0fd800e4, 0x01560fdb, 0x0fd600f9,
-	0x01400fdd, 0x0fd20111, 0x01290fdf, 0x0fd00128,
-	0x01110fe2, 0x0fce013f, 0x00f80fe6, 0x0fcd0155,
-	0x00de0fe8, 0x0fcc016e, 0x00c40fec, 0x0fcb0185,
-	0x00ab0fef, 0x0fcb019b, 0x00900ff3, 0x0fcd01b0,
-	0x00770ff6, 0x0fd101c2, 0x005f0ff9, 0x0fd501d3,
-	0x00470ffc, 0x0fdb01e2, 0x00320ffd, 0x0fe201ef,
-	0x001e0000, 0x0fea01f8, 0x000c0000, 0x0ff501ff,
-	0x02000000, 0x00000000, 0x02010ff9, 0x00000006,
-	0x02000ff2, 0x0000000e, 0x01fd0fed, 0x0ffe0018,
-	0x01f80fe8, 0x0ffd0023, 0x01f20fe4, 0x0ffb002f,
-	0x01eb0fe0, 0x0ff9003c, 0x01e10fdd, 0x0ff7004b,
-	0x01d60fda, 0x0ff4005c, 0x01c90fd9, 0x0ff2006c,
-	0x01bc0fd8, 0x0fee007e, 0x01ab0fd8, 0x0fec0091,
-	0x019b0fd8, 0x0fe800a5, 0x018b0fd8, 0x0fe400b9,
-	0x01770fd9, 0x0fe200ce, 0x01620fdb, 0x0fdf00e4,
-	0x014f0fdb, 0x0fdb00fb, 0x01380fde, 0x0fda0110,
-	0x01210fe0, 0x0fd70128, 0x010a0fe2, 0x0fd5013f,
-	0x00f30fe6, 0x0fd30154, 0x00da0fe9, 0x0fd3016a,
-	0x00c30feb, 0x0fd20180, 0x00aa0fef, 0x0fd20195,
-	0x00940ff1, 0x0fd301a8, 0x007b0ff5, 0x0fd501bb,
-	0x00650ff7, 0x0fd801cc, 0x00510ffa, 0x0fdc01d9,
-	0x003c0ffd, 0x0fe101e6, 0x002a0ffe, 0x0fe701f1,
-	0x00190000, 0x0fee01f9, 0x000a0000, 0x0ff701ff,
+
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+
+	0x02000000, 0x00000000, 0x01fc0ff9, 0x0ffe000d,
+	0x01f60ff3, 0x0ffb001c, 0x01ef0fed, 0x0ff9002b,
+	0x01e60fe8, 0x0ff6003c, 0x01dc0fe4, 0x0ff3004d,
+	0x01d00fe0, 0x0ff1005f, 0x01c30fde, 0x0fee0071,
+	0x01b50fdb, 0x0feb0085, 0x01a70fd9, 0x0fe80098,
+	0x01960fd8, 0x0fe600ac, 0x01850fd7, 0x0fe300c1,
+	0x01730fd7, 0x0fe100d5, 0x01610fd7, 0x0fdf00e9,
+	0x014e0fd8, 0x0fdd00fd, 0x013b0fd8, 0x0fdb0112,
+	0x01250fda, 0x0fda0127, 0x01120fdb, 0x0fd8013b,
+	0x00fd0fdd, 0x0fd8014e, 0x00e90fdf, 0x0fd70161,
+	0x00d50fe1, 0x0fd70173, 0x00c10fe3, 0x0fd70185,
+	0x00ac0fe6, 0x0fd80196, 0x00980fe8, 0x0fd901a7,
+	0x00850feb, 0x0fdb01b5, 0x00710fee, 0x0fde01c3,
+	0x005f0ff1, 0x0fe001d0, 0x004d0ff3, 0x0fe401dc,
+	0x003c0ff6, 0x0fe801e6, 0x002b0ff9, 0x0fed01ef,
+	0x001c0ffb, 0x0ff301f6, 0x000d0ffe, 0x0ff901fc,
+
+	0x020f0034, 0x0f7a0043, 0x01e80023, 0x0fa8004d,
+	0x01d30016, 0x0fbe0059, 0x01c6000a, 0x0fc90067,
+	0x01bd0000, 0x0fce0075, 0x01b50ff7, 0x0fcf0085,
+	0x01ae0fee, 0x0fcf0095, 0x01a70fe6, 0x0fcd00a6,
+	0x019d0fe0, 0x0fcb00b8, 0x01940fd9, 0x0fc900ca,
+	0x01890fd4, 0x0fc700dc, 0x017d0fcf, 0x0fc600ee,
+	0x01700fcc, 0x0fc40100, 0x01620fc9, 0x0fc40111,
+	0x01540fc6, 0x0fc30123, 0x01430fc5, 0x0fc40134,
+	0x01340fc4, 0x0fc50143, 0x01230fc3, 0x0fc60154,
+	0x01110fc4, 0x0fc90162, 0x01000fc4, 0x0fcc0170,
+	0x00ee0fc6, 0x0fcf017d, 0x00dc0fc7, 0x0fd40189,
+	0x00ca0fc9, 0x0fd90194, 0x00b80fcb, 0x0fe0019d,
+	0x00a60fcd, 0x0fe601a7, 0x00950fcf, 0x0fee01ae,
+	0x00850fcf, 0x0ff701b5, 0x00750fce, 0x000001bd,
+	0x00670fc9, 0x000a01c6, 0x00590fbe, 0x001601d3,
+	0x004d0fa8, 0x002301e8, 0x00430f7a, 0x0034020f,
+
+	0x015c005e, 0x0fde0068, 0x015c0054, 0x0fdd0073,
+	0x015b004b, 0x0fdc007e, 0x015a0042, 0x0fdb0089,
+	0x01590039, 0x0fda0094, 0x01560030, 0x0fda00a0,
+	0x01530028, 0x0fda00ab, 0x014f0020, 0x0fda00b7,
+	0x014a0019, 0x0fdb00c2, 0x01450011, 0x0fdc00ce,
+	0x013e000b, 0x0fde00d9, 0x01390004, 0x0fdf00e4,
+	0x01310ffe, 0x0fe200ef, 0x01290ff9, 0x0fe400fa,
+	0x01200ff4, 0x0fe80104, 0x01180fef, 0x0feb010e,
+	0x010e0feb, 0x0fef0118, 0x01040fe8, 0x0ff40120,
+	0x00fa0fe4, 0x0ff90129, 0x00ef0fe2, 0x0ffe0131,
+	0x00e40fdf, 0x00040139, 0x00d90fde, 0x000b013e,
+	0x00ce0fdc, 0x00110145, 0x00c20fdb, 0x0019014a,
+	0x00b70fda, 0x0020014f, 0x00ab0fda, 0x00280153,
+	0x00a00fda, 0x00300156, 0x00940fda, 0x00390159,
+	0x00890fdb, 0x0042015a, 0x007e0fdc, 0x004b015b,
+	0x00730fdd, 0x0054015c, 0x00680fde, 0x005e015c,
+
+	0x01300068, 0x0ff80070, 0x01300060, 0x0ff80078,
+	0x012f0059, 0x0ff80080, 0x012d0052, 0x0ff80089,
+	0x012b004b, 0x0ff90091, 0x01290044, 0x0ff9009a,
+	0x0126003d, 0x0ffa00a3, 0x01220037, 0x0ffb00ac,
+	0x011f0031, 0x0ffc00b4, 0x011a002b, 0x0ffe00bd,
+	0x01150026, 0x000000c5, 0x010f0021, 0x000200ce,
+	0x010a001c, 0x000400d6, 0x01030018, 0x000600df,
+	0x00fd0014, 0x000900e6, 0x00f60010, 0x000c00ee,
+	0x00ee000c, 0x001000f6, 0x00e60009, 0x001400fd,
+	0x00df0006, 0x00180103, 0x00d60004, 0x001c010a,
+	0x00ce0002, 0x0021010f, 0x00c50000, 0x00260115,
+	0x00bd0ffe, 0x002b011a, 0x00b40ffc, 0x0031011f,
+	0x00ac0ffb, 0x00370122, 0x00a30ffa, 0x003d0126,
+	0x009a0ff9, 0x00440129, 0x00910ff9, 0x004b012b,
+	0x00890ff8, 0x0052012d, 0x00800ff8, 0x0059012f,
+	0x00780ff8, 0x00600130, 0x00700ff8, 0x00680130,
+
+	0x01050079, 0x0003007f, 0x01040073, 0x00030086,
+	0x0103006d, 0x0004008c, 0x01030066, 0x00050092,
+	0x01010060, 0x00060099, 0x0100005a, 0x0007009f,
+	0x00fe0054, 0x000900a5, 0x00fa004f, 0x000b00ac,
+	0x00f80049, 0x000d00b2, 0x00f50044, 0x000f00b8,
+	0x00f2003f, 0x001200bd, 0x00ef0039, 0x001500c3,
+	0x00ea0035, 0x001800c9, 0x00e60030, 0x001c00ce,
+	0x00e3002b, 0x001f00d3, 0x00dd0027, 0x002300d9,
+	0x00d90023, 0x002700dd, 0x00d3001f, 0x002b00e3,
+	0x00ce001c, 0x003000e6, 0x00c90018, 0x003500ea,
+	0x00c30015, 0x003900ef, 0x00bd0012, 0x003f00f2,
+	0x00b8000f, 0x004400f5, 0x00b2000d, 0x004900f8,
+	0x00ac000b, 0x004f00fa, 0x00a50009, 0x005400fe,
+	0x009f0007, 0x005a0100, 0x00990006, 0x00600101,
+	0x00920005, 0x00660103, 0x008c0004, 0x006d0103,
+	0x00860003, 0x00730104, 0x007f0003, 0x00790105,
+
+	0x00cf0088, 0x001d008c, 0x00ce0084, 0x0020008e,
+	0x00cd0080, 0x00210092, 0x00cd007b, 0x00240094,
+	0x00ca0077, 0x00270098, 0x00c90073, 0x0029009b,
+	0x00c8006f, 0x002c009d, 0x00c6006b, 0x002f00a0,
+	0x00c50067, 0x003200a2, 0x00c30062, 0x003600a5,
+	0x00c0005f, 0x003900a8, 0x00c0005b, 0x003b00aa,
+	0x00be0057, 0x003e00ad, 0x00ba0054, 0x004200b0,
+	0x00b90050, 0x004500b2, 0x00b7004c, 0x004900b4,
+	0x00b40049, 0x004c00b7, 0x00b20045, 0x005000b9,
+	0x00b00042, 0x005400ba, 0x00ad003e, 0x005700be,
+	0x00aa003b, 0x005b00c0, 0x00a80039, 0x005f00c0,
+	0x00a50036, 0x006200c3, 0x00a20032, 0x006700c5,
+	0x00a0002f, 0x006b00c6, 0x009d002c, 0x006f00c8,
+	0x009b0029, 0x007300c9, 0x00980027, 0x007700ca,
+	0x00940024, 0x007b00cd, 0x00920021, 0x008000cd,
+	0x008e0020, 0x008400ce, 0x008c001d, 0x008800cf,
+
+	0x008e0083, 0x006b0084, 0x008d0083, 0x006c0084,
+	0x008d0082, 0x006d0084, 0x008d0081, 0x006d0085,
+	0x008d0080, 0x006e0085, 0x008c007f, 0x006f0086,
+	0x008b007f, 0x00700086, 0x008b007e, 0x00710086,
+	0x008b007d, 0x00720086, 0x008a007d, 0x00730086,
+	0x008a007c, 0x00730087, 0x008a007b, 0x00740087,
+	0x0089007b, 0x00750087, 0x008a0079, 0x00750088,
+	0x008a0078, 0x00760088, 0x008a0077, 0x00770088,
+	0x00880077, 0x0077008a, 0x00880076, 0x0078008a,
+	0x00880075, 0x0079008a, 0x00870075, 0x007b0089,
+	0x00870074, 0x007b008a, 0x00870073, 0x007c008a,
+	0x00860073, 0x007d008a, 0x00860072, 0x007d008b,
+	0x00860071, 0x007e008b, 0x00860070, 0x007f008b,
+	0x0086006f, 0x007f008c, 0x0085006e, 0x0080008d,
+	0x0085006d, 0x0081008d, 0x0084006d, 0x0082008d,
+	0x0084006c, 0x0083008d, 0x0084006b, 0x0083008e,
+
+	0x023c0fe2, 0x00000fe2, 0x023a0fdb, 0x00000feb,
+	0x02360fd3, 0x0fff0ff8, 0x022e0fcf, 0x0ffc0007,
+	0x02250fca, 0x0ffa0017, 0x021a0fc6, 0x0ff70029,
+	0x020c0fc4, 0x0ff4003c, 0x01fd0fc1, 0x0ff10051,
+	0x01eb0fc0, 0x0fed0068, 0x01d80fc0, 0x0fe9007f,
+	0x01c30fc1, 0x0fe50097, 0x01ac0fc2, 0x0fe200b0,
+	0x01960fc3, 0x0fdd00ca, 0x017e0fc5, 0x0fd900e4,
+	0x01650fc8, 0x0fd500fe, 0x014b0fcb, 0x0fd20118,
+	0x01330fcd, 0x0fcd0133, 0x01180fd2, 0x0fcb014b,
+	0x00fe0fd5, 0x0fc80165, 0x00e40fd9, 0x0fc5017e,
+	0x00ca0fdd, 0x0fc30196, 0x00b00fe2, 0x0fc201ac,
+	0x00970fe5, 0x0fc101c3, 0x007f0fe9, 0x0fc001d8,
+	0x00680fed, 0x0fc001eb, 0x00510ff1, 0x0fc101fd,
+	0x003c0ff4, 0x0fc4020c, 0x00290ff7, 0x0fc6021a,
+	0x00170ffa, 0x0fca0225, 0x00070ffc, 0x0fcf022e,
+	0x0ff80fff, 0x0fd30236, 0x0feb0000, 0x0fdb023a,
+
+	0x02780fc4, 0x00000fc4, 0x02770fbc, 0x0fff0fce,
+	0x02710fb5, 0x0ffe0fdc, 0x02690fb0, 0x0ffa0fed,
+	0x025f0fab, 0x0ff70fff, 0x02500fa8, 0x0ff30015,
+	0x02410fa6, 0x0fef002a, 0x022f0fa4, 0x0feb0042,
+	0x021a0fa4, 0x0fe5005d, 0x02040fa5, 0x0fe10076,
+	0x01eb0fa7, 0x0fdb0093, 0x01d20fa9, 0x0fd600af,
+	0x01b80fab, 0x0fd000cd, 0x019d0faf, 0x0fca00ea,
+	0x01810fb2, 0x0fc50108, 0x01620fb7, 0x0fc10126,
+	0x01440fbb, 0x0fbb0146, 0x01260fc1, 0x0fb70162,
+	0x01080fc5, 0x0fb20181, 0x00ea0fca, 0x0faf019d,
+	0x00cd0fd0, 0x0fab01b8, 0x00af0fd6, 0x0fa901d2,
+	0x00930fdb, 0x0fa701eb, 0x00760fe1, 0x0fa50204,
+	0x005d0fe5, 0x0fa4021a, 0x00420feb, 0x0fa4022f,
+	0x002a0fef, 0x0fa60241, 0x00150ff3, 0x0fa80250,
+	0x0fff0ff7, 0x0fab025f, 0x0fed0ffa, 0x0fb00269,
+	0x0fdc0ffe, 0x0fb50271, 0x0fce0fff, 0x0fbc0277,
+
+	0x02a00fb0, 0x00000fb0, 0x029e0fa8, 0x0fff0fbb,
+	0x02980fa1, 0x0ffd0fca, 0x028f0f9c, 0x0ff90fdc,
+	0x02840f97, 0x0ff50ff0, 0x02740f94, 0x0ff10007,
+	0x02640f92, 0x0fec001e, 0x02500f91, 0x0fe70038,
+	0x023a0f91, 0x0fe00055, 0x02220f92, 0x0fdb0071,
+	0x02080f95, 0x0fd4008f, 0x01ec0f98, 0x0fce00ae,
+	0x01cf0f9b, 0x0fc700cf, 0x01b10f9f, 0x0fc100ef,
+	0x01920fa4, 0x0fbb010f, 0x01710faa, 0x0fb50130,
+	0x01520fae, 0x0fae0152, 0x01300fb5, 0x0faa0171,
+	0x010f0fbb, 0x0fa40192, 0x00ef0fc1, 0x0f9f01b1,
+	0x00cf0fc7, 0x0f9b01cf, 0x00ae0fce, 0x0f9801ec,
+	0x008f0fd4, 0x0f950208, 0x00710fdb, 0x0f920222,
+	0x00550fe0, 0x0f91023a, 0x00380fe7, 0x0f910250,
+	0x001e0fec, 0x0f920264, 0x00070ff1, 0x0f940274,
+	0x0ff00ff5, 0x0f970284, 0x0fdc0ff9, 0x0f9c028f,
+	0x0fca0ffd, 0x0fa10298, 0x0fbb0fff, 0x0fa8029e,
+
+	0x02c80f9c, 0x00000f9c, 0x02c70f94, 0x0ffe0fa7,
+	0x02c10f8c, 0x0ffc0fb7, 0x02b70f87, 0x0ff70fcb,
+	0x02aa0f83, 0x0ff30fe0, 0x02990f80, 0x0fee0ff9,
+	0x02870f7f, 0x0fe80012, 0x02720f7e, 0x0fe2002e,
+	0x025a0f7e, 0x0fdb004d, 0x02400f80, 0x0fd5006b,
+	0x02230f84, 0x0fcd008c, 0x02050f87, 0x0fc700ad,
+	0x01e60f8b, 0x0fbf00d0, 0x01c60f90, 0x0fb700f3,
+	0x01a30f96, 0x0fb00117, 0x01800f9c, 0x0faa013a,
+	0x015d0fa2, 0x0fa2015f, 0x013a0faa, 0x0f9c0180,
+	0x01170fb0, 0x0f9601a3, 0x00f30fb7, 0x0f9001c6,
+	0x00d00fbf, 0x0f8b01e6, 0x00ad0fc7, 0x0f870205,
+	0x008c0fcd, 0x0f840223, 0x006b0fd5, 0x0f800240,
+	0x004d0fdb, 0x0f7e025a, 0x002e0fe2, 0x0f7e0272,
+	0x00120fe8, 0x0f7f0287, 0x0ff90fee, 0x0f800299,
+	0x0fe00ff3, 0x0f8302aa, 0x0fcb0ff7, 0x0f8702b7,
+	0x0fb70ffc, 0x0f8c02c1, 0x0fa70ffe, 0x0f9402c7,
+
+	0x02f00f88, 0x00000f88, 0x02ee0f80, 0x0ffe0f94,
+	0x02e70f78, 0x0ffc0fa5, 0x02dd0f73, 0x0ff60fba,
+	0x02ce0f6f, 0x0ff20fd1, 0x02be0f6c, 0x0feb0feb,
+	0x02aa0f6b, 0x0fe50006, 0x02940f6a, 0x0fde0024,
+	0x02790f6c, 0x0fd60045, 0x025e0f6e, 0x0fcf0065,
+	0x023f0f72, 0x0fc60089, 0x021d0f77, 0x0fbf00ad,
+	0x01fd0f7b, 0x0fb600d2, 0x01da0f81, 0x0fad00f8,
+	0x01b50f87, 0x0fa6011e, 0x018f0f8f, 0x0f9e0144,
+	0x016b0f95, 0x0f95016b, 0x01440f9e, 0x0f8f018f,
+	0x011e0fa6, 0x0f8701b5, 0x00f80fad, 0x0f8101da,
+	0x00d20fb6, 0x0f7b01fd, 0x00ad0fbf, 0x0f77021d,
+	0x00890fc6, 0x0f72023f, 0x00650fcf, 0x0f6e025e,
+	0x00450fd6, 0x0f6c0279, 0x00240fde, 0x0f6a0294,
+	0x00060fe5, 0x0f6b02aa, 0x0feb0feb, 0x0f6c02be,
+	0x0fd10ff2, 0x0f6f02ce, 0x0fba0ff6, 0x0f7302dd,
+	0x0fa50ffc, 0x0f7802e7, 0x0f940ffe, 0x0f8002ee,
+
+	0x03180f74, 0x00000f74, 0x03160f6b, 0x0ffe0f81,
+	0x030e0f64, 0x0ffb0f93, 0x03030f5f, 0x0ff50fa9,
+	0x02f40f5b, 0x0ff00fc1, 0x02e20f58, 0x0fe90fdd,
+	0x02cd0f57, 0x0fe20ffa, 0x02b60f57, 0x0fda0019,
+	0x02990f59, 0x0fd1003d, 0x027b0f5c, 0x0fc90060,
+	0x02590f61, 0x0fc00086, 0x02370f66, 0x0fb700ac,
+	0x02130f6b, 0x0fae00d4, 0x01ee0f72, 0x0fa400fc,
+	0x01c70f79, 0x0f9b0125, 0x019f0f81, 0x0f93014d,
+	0x01760f89, 0x0f890178, 0x014d0f93, 0x0f81019f,
+	0x01250f9b, 0x0f7901c7, 0x00fc0fa4, 0x0f7201ee,
+	0x00d40fae, 0x0f6b0213, 0x00ac0fb7, 0x0f660237,
+	0x00860fc0, 0x0f610259, 0x00600fc9, 0x0f5c027b,
+	0x003d0fd1, 0x0f590299, 0x00190fda, 0x0f5702b6,
+	0x0ffa0fe2, 0x0f5702cd, 0x0fdd0fe9, 0x0f5802e2,
+	0x0fc10ff0, 0x0f5b02f4, 0x0fa90ff5, 0x0f5f0303,
+	0x0f930ffb, 0x0f64030e, 0x0f810ffe, 0x0f6b0316,
+
+	0x03400f60, 0x00000f60, 0x033e0f57, 0x0ffe0f6d,
+	0x03370f4f, 0x0ffa0f80, 0x032a0f4b, 0x0ff30f98,
+	0x031a0f46, 0x0fee0fb2, 0x03070f44, 0x0fe60fcf,
+	0x02f10f44, 0x0fde0fed, 0x02d70f44, 0x0fd6000f,
+	0x02b80f46, 0x0fcc0036, 0x02990f4a, 0x0fc3005a,
+	0x02750f4f, 0x0fb90083, 0x02500f55, 0x0fb000ab,
+	0x022a0f5b, 0x0fa500d6, 0x02020f63, 0x0f9a0101,
+	0x01d80f6b, 0x0f91012c, 0x01ae0f74, 0x0f870157,
+	0x01840f7c, 0x0f7c0184, 0x01570f87, 0x0f7401ae,
+	0x012c0f91, 0x0f6b01d8, 0x01010f9a, 0x0f630202,
+	0x00d60fa5, 0x0f5b022a, 0x00ab0fb0, 0x0f550250,
+	0x00830fb9, 0x0f4f0275, 0x005a0fc3, 0x0f4a0299,
+	0x00360fcc, 0x0f4602b8, 0x000f0fd6, 0x0f4402d7,
+	0x0fed0fde, 0x0f4402f1, 0x0fcf0fe6, 0x0f440307,
+	0x0fb20fee, 0x0f46031a, 0x0f980ff3, 0x0f4b032a,
+	0x0f800ffa, 0x0f4f0337, 0x0f6d0ffe, 0x0f57033e,
+
 	0x02000000, 0x00000000, 0x01ff0ff9, 0x00000008,
 	0x01fb0ff2, 0x00000013, 0x01f50fed, 0x0ffe0020,
 	0x01ed0fe8, 0x0ffd002e, 0x01e30fe4, 0x0ffb003e,
@@ -870,7 +863,262 @@
 	0x00740ff4, 0x0fdc01bc, 0x00600ff7, 0x0fde01cb,
 	0x004e0ff9, 0x0fe101d8, 0x003e0ffb, 0x0fe401e3,
 	0x002e0ffd, 0x0fe801ed, 0x00200ffe, 0x0fed01f5,
-	0x00130000, 0x0ff201fb, 0x00080000, 0x0ff901ff
+	0x00130000, 0x0ff201fb, 0x00080000, 0x0ff901ff,
+
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+	0x02000000, 0x00000000, 0x02000000, 0x00000000,
+
+	0x02000000, 0x00000000, 0x01fc0ff9, 0x0ffe000d,
+	0x01f60ff3, 0x0ffb001c, 0x01ef0fed, 0x0ff9002b,
+	0x01e60fe8, 0x0ff6003c, 0x01dc0fe4, 0x0ff3004d,
+	0x01d00fe0, 0x0ff1005f, 0x01c30fde, 0x0fee0071,
+	0x01b50fdb, 0x0feb0085, 0x01a70fd9, 0x0fe80098,
+	0x01960fd8, 0x0fe600ac, 0x01850fd7, 0x0fe300c1,
+	0x01730fd7, 0x0fe100d5, 0x01610fd7, 0x0fdf00e9,
+	0x014e0fd8, 0x0fdd00fd, 0x013b0fd8, 0x0fdb0112,
+	0x01250fda, 0x0fda0127, 0x01120fdb, 0x0fd8013b,
+	0x00fd0fdd, 0x0fd8014e, 0x00e90fdf, 0x0fd70161,
+	0x00d50fe1, 0x0fd70173, 0x00c10fe3, 0x0fd70185,
+	0x00ac0fe6, 0x0fd80196, 0x00980fe8, 0x0fd901a7,
+	0x00850feb, 0x0fdb01b5, 0x00710fee, 0x0fde01c3,
+	0x005f0ff1, 0x0fe001d0, 0x004d0ff3, 0x0fe401dc,
+	0x003c0ff6, 0x0fe801e6, 0x002b0ff9, 0x0fed01ef,
+	0x001c0ffb, 0x0ff301f6, 0x000d0ffe, 0x0ff901fc,
+
+	0x020f0034, 0x0f7a0043, 0x01e80023, 0x0fa8004d,
+	0x01d30016, 0x0fbe0059, 0x01c6000a, 0x0fc90067,
+	0x01bd0000, 0x0fce0075, 0x01b50ff7, 0x0fcf0085,
+	0x01ae0fee, 0x0fcf0095, 0x01a70fe6, 0x0fcd00a6,
+	0x019d0fe0, 0x0fcb00b8, 0x01940fd9, 0x0fc900ca,
+	0x01890fd4, 0x0fc700dc, 0x017d0fcf, 0x0fc600ee,
+	0x01700fcc, 0x0fc40100, 0x01620fc9, 0x0fc40111,
+	0x01540fc6, 0x0fc30123, 0x01430fc5, 0x0fc40134,
+	0x01340fc4, 0x0fc50143, 0x01230fc3, 0x0fc60154,
+	0x01110fc4, 0x0fc90162, 0x01000fc4, 0x0fcc0170,
+	0x00ee0fc6, 0x0fcf017d, 0x00dc0fc7, 0x0fd40189,
+	0x00ca0fc9, 0x0fd90194, 0x00b80fcb, 0x0fe0019d,
+	0x00a60fcd, 0x0fe601a7, 0x00950fcf, 0x0fee01ae,
+	0x00850fcf, 0x0ff701b5, 0x00750fce, 0x000001bd,
+	0x00670fc9, 0x000a01c6, 0x00590fbe, 0x001601d3,
+	0x004d0fa8, 0x002301e8, 0x00430f7a, 0x0034020f,
+
+	0x015c005e, 0x0fde0068, 0x015c0054, 0x0fdd0073,
+	0x015b004b, 0x0fdc007e, 0x015a0042, 0x0fdb0089,
+	0x01590039, 0x0fda0094, 0x01560030, 0x0fda00a0,
+	0x01530028, 0x0fda00ab, 0x014f0020, 0x0fda00b7,
+	0x014a0019, 0x0fdb00c2, 0x01450011, 0x0fdc00ce,
+	0x013e000b, 0x0fde00d9, 0x01390004, 0x0fdf00e4,
+	0x01310ffe, 0x0fe200ef, 0x01290ff9, 0x0fe400fa,
+	0x01200ff4, 0x0fe80104, 0x01180fef, 0x0feb010e,
+	0x010e0feb, 0x0fef0118, 0x01040fe8, 0x0ff40120,
+	0x00fa0fe4, 0x0ff90129, 0x00ef0fe2, 0x0ffe0131,
+	0x00e40fdf, 0x00040139, 0x00d90fde, 0x000b013e,
+	0x00ce0fdc, 0x00110145, 0x00c20fdb, 0x0019014a,
+	0x00b70fda, 0x0020014f, 0x00ab0fda, 0x00280153,
+	0x00a00fda, 0x00300156, 0x00940fda, 0x00390159,
+	0x00890fdb, 0x0042015a, 0x007e0fdc, 0x004b015b,
+	0x00730fdd, 0x0054015c, 0x00680fde, 0x005e015c,
+
+	0x01300068, 0x0ff80070, 0x01300060, 0x0ff80078,
+	0x012f0059, 0x0ff80080, 0x012d0052, 0x0ff80089,
+	0x012b004b, 0x0ff90091, 0x01290044, 0x0ff9009a,
+	0x0126003d, 0x0ffa00a3, 0x01220037, 0x0ffb00ac,
+	0x011f0031, 0x0ffc00b4, 0x011a002b, 0x0ffe00bd,
+	0x01150026, 0x000000c5, 0x010f0021, 0x000200ce,
+	0x010a001c, 0x000400d6, 0x01030018, 0x000600df,
+	0x00fd0014, 0x000900e6, 0x00f60010, 0x000c00ee,
+	0x00ee000c, 0x001000f6, 0x00e60009, 0x001400fd,
+	0x00df0006, 0x00180103, 0x00d60004, 0x001c010a,
+	0x00ce0002, 0x0021010f, 0x00c50000, 0x00260115,
+	0x00bd0ffe, 0x002b011a, 0x00b40ffc, 0x0031011f,
+	0x00ac0ffb, 0x00370122, 0x00a30ffa, 0x003d0126,
+	0x009a0ff9, 0x00440129, 0x00910ff9, 0x004b012b,
+	0x00890ff8, 0x0052012d, 0x00800ff8, 0x0059012f,
+	0x00780ff8, 0x00600130, 0x00700ff8, 0x00680130,
+
+	0x01050079, 0x0003007f, 0x01040073, 0x00030086,
+	0x0103006d, 0x0004008c, 0x01030066, 0x00050092,
+	0x01010060, 0x00060099, 0x0100005a, 0x0007009f,
+	0x00fe0054, 0x000900a5, 0x00fa004f, 0x000b00ac,
+	0x00f80049, 0x000d00b2, 0x00f50044, 0x000f00b8,
+	0x00f2003f, 0x001200bd, 0x00ef0039, 0x001500c3,
+	0x00ea0035, 0x001800c9, 0x00e60030, 0x001c00ce,
+	0x00e3002b, 0x001f00d3, 0x00dd0027, 0x002300d9,
+	0x00d90023, 0x002700dd, 0x00d3001f, 0x002b00e3,
+	0x00ce001c, 0x003000e6, 0x00c90018, 0x003500ea,
+	0x00c30015, 0x003900ef, 0x00bd0012, 0x003f00f2,
+	0x00b8000f, 0x004400f5, 0x00b2000d, 0x004900f8,
+	0x00ac000b, 0x004f00fa, 0x00a50009, 0x005400fe,
+	0x009f0007, 0x005a0100, 0x00990006, 0x00600101,
+	0x00920005, 0x00660103, 0x008c0004, 0x006d0103,
+	0x00860003, 0x00730104, 0x007f0003, 0x00790105,
+
+	0x00cf0088, 0x001d008c, 0x00ce0084, 0x0020008e,
+	0x00cd0080, 0x00210092, 0x00cd007b, 0x00240094,
+	0x00ca0077, 0x00270098, 0x00c90073, 0x0029009b,
+	0x00c8006f, 0x002c009d, 0x00c6006b, 0x002f00a0,
+	0x00c50067, 0x003200a2, 0x00c30062, 0x003600a5,
+	0x00c0005f, 0x003900a8, 0x00c0005b, 0x003b00aa,
+	0x00be0057, 0x003e00ad, 0x00ba0054, 0x004200b0,
+	0x00b90050, 0x004500b2, 0x00b7004c, 0x004900b4,
+	0x00b40049, 0x004c00b7, 0x00b20045, 0x005000b9,
+	0x00b00042, 0x005400ba, 0x00ad003e, 0x005700be,
+	0x00aa003b, 0x005b00c0, 0x00a80039, 0x005f00c0,
+	0x00a50036, 0x006200c3, 0x00a20032, 0x006700c5,
+	0x00a0002f, 0x006b00c6, 0x009d002c, 0x006f00c8,
+	0x009b0029, 0x007300c9, 0x00980027, 0x007700ca,
+	0x00940024, 0x007b00cd, 0x00920021, 0x008000cd,
+	0x008e0020, 0x008400ce, 0x008c001d, 0x008800cf,
+
+	0x008e0083, 0x006b0084, 0x008d0083, 0x006c0084,
+	0x008d0082, 0x006d0084, 0x008d0081, 0x006d0085,
+	0x008d0080, 0x006e0085, 0x008c007f, 0x006f0086,
+	0x008b007f, 0x00700086, 0x008b007e, 0x00710086,
+	0x008b007d, 0x00720086, 0x008a007d, 0x00730086,
+	0x008a007c, 0x00730087, 0x008a007b, 0x00740087,
+	0x0089007b, 0x00750087, 0x008a0079, 0x00750088,
+	0x008a0078, 0x00760088, 0x008a0077, 0x00770088,
+	0x00880077, 0x0077008a, 0x00880076, 0x0078008a,
+	0x00880075, 0x0079008a, 0x00870075, 0x007b0089,
+	0x00870074, 0x007b008a, 0x00870073, 0x007c008a,
+	0x00860073, 0x007d008a, 0x00860072, 0x007d008b,
+	0x00860071, 0x007e008b, 0x00860070, 0x007f008b,
+	0x0086006f, 0x007f008c, 0x0085006e, 0x0080008d,
+	0x0085006d, 0x0081008d, 0x0084006d, 0x0082008d,
+	0x0084006c, 0x0083008d, 0x0084006b, 0x0083008e,
+
+	0x023c0fe2, 0x00000fe2, 0x023a0fdb, 0x00000feb,
+	0x02360fd3, 0x0fff0ff8, 0x022e0fcf, 0x0ffc0007,
+	0x02250fca, 0x0ffa0017, 0x021a0fc6, 0x0ff70029,
+	0x020c0fc4, 0x0ff4003c, 0x01fd0fc1, 0x0ff10051,
+	0x01eb0fc0, 0x0fed0068, 0x01d80fc0, 0x0fe9007f,
+	0x01c30fc1, 0x0fe50097, 0x01ac0fc2, 0x0fe200b0,
+	0x01960fc3, 0x0fdd00ca, 0x017e0fc5, 0x0fd900e4,
+	0x01650fc8, 0x0fd500fe, 0x014b0fcb, 0x0fd20118,
+	0x01330fcd, 0x0fcd0133, 0x01180fd2, 0x0fcb014b,
+	0x00fe0fd5, 0x0fc80165, 0x00e40fd9, 0x0fc5017e,
+	0x00ca0fdd, 0x0fc30196, 0x00b00fe2, 0x0fc201ac,
+	0x00970fe5, 0x0fc101c3, 0x007f0fe9, 0x0fc001d8,
+	0x00680fed, 0x0fc001eb, 0x00510ff1, 0x0fc101fd,
+	0x003c0ff4, 0x0fc4020c, 0x00290ff7, 0x0fc6021a,
+	0x00170ffa, 0x0fca0225, 0x00070ffc, 0x0fcf022e,
+	0x0ff80fff, 0x0fd30236, 0x0feb0000, 0x0fdb023a,
+
+	0x02780fc4, 0x00000fc4, 0x02770fbc, 0x0fff0fce,
+	0x02710fb5, 0x0ffe0fdc, 0x02690fb0, 0x0ffa0fed,
+	0x025f0fab, 0x0ff70fff, 0x02500fa8, 0x0ff30015,
+	0x02410fa6, 0x0fef002a, 0x022f0fa4, 0x0feb0042,
+	0x021a0fa4, 0x0fe5005d, 0x02040fa5, 0x0fe10076,
+	0x01eb0fa7, 0x0fdb0093, 0x01d20fa9, 0x0fd600af,
+	0x01b80fab, 0x0fd000cd, 0x019d0faf, 0x0fca00ea,
+	0x01810fb2, 0x0fc50108, 0x01620fb7, 0x0fc10126,
+	0x01440fbb, 0x0fbb0146, 0x01260fc1, 0x0fb70162,
+	0x01080fc5, 0x0fb20181, 0x00ea0fca, 0x0faf019d,
+	0x00cd0fd0, 0x0fab01b8, 0x00af0fd6, 0x0fa901d2,
+	0x00930fdb, 0x0fa701eb, 0x00760fe1, 0x0fa50204,
+	0x005d0fe5, 0x0fa4021a, 0x00420feb, 0x0fa4022f,
+	0x002a0fef, 0x0fa60241, 0x00150ff3, 0x0fa80250,
+	0x0fff0ff7, 0x0fab025f, 0x0fed0ffa, 0x0fb00269,
+	0x0fdc0ffe, 0x0fb50271, 0x0fce0fff, 0x0fbc0277,
+
+	0x02a00fb0, 0x00000fb0, 0x029e0fa8, 0x0fff0fbb,
+	0x02980fa1, 0x0ffd0fca, 0x028f0f9c, 0x0ff90fdc,
+	0x02840f97, 0x0ff50ff0, 0x02740f94, 0x0ff10007,
+	0x02640f92, 0x0fec001e, 0x02500f91, 0x0fe70038,
+	0x023a0f91, 0x0fe00055, 0x02220f92, 0x0fdb0071,
+	0x02080f95, 0x0fd4008f, 0x01ec0f98, 0x0fce00ae,
+	0x01cf0f9b, 0x0fc700cf, 0x01b10f9f, 0x0fc100ef,
+	0x01920fa4, 0x0fbb010f, 0x01710faa, 0x0fb50130,
+	0x01520fae, 0x0fae0152, 0x01300fb5, 0x0faa0171,
+	0x010f0fbb, 0x0fa40192, 0x00ef0fc1, 0x0f9f01b1,
+	0x00cf0fc7, 0x0f9b01cf, 0x00ae0fce, 0x0f9801ec,
+	0x008f0fd4, 0x0f950208, 0x00710fdb, 0x0f920222,
+	0x00550fe0, 0x0f91023a, 0x00380fe7, 0x0f910250,
+	0x001e0fec, 0x0f920264, 0x00070ff1, 0x0f940274,
+	0x0ff00ff5, 0x0f970284, 0x0fdc0ff9, 0x0f9c028f,
+	0x0fca0ffd, 0x0fa10298, 0x0fbb0fff, 0x0fa8029e,
+
+	0x02c80f9c, 0x00000f9c, 0x02c70f94, 0x0ffe0fa7,
+	0x02c10f8c, 0x0ffc0fb7, 0x02b70f87, 0x0ff70fcb,
+	0x02aa0f83, 0x0ff30fe0, 0x02990f80, 0x0fee0ff9,
+	0x02870f7f, 0x0fe80012, 0x02720f7e, 0x0fe2002e,
+	0x025a0f7e, 0x0fdb004d, 0x02400f80, 0x0fd5006b,
+	0x02230f84, 0x0fcd008c, 0x02050f87, 0x0fc700ad,
+	0x01e60f8b, 0x0fbf00d0, 0x01c60f90, 0x0fb700f3,
+	0x01a30f96, 0x0fb00117, 0x01800f9c, 0x0faa013a,
+	0x015d0fa2, 0x0fa2015f, 0x013a0faa, 0x0f9c0180,
+	0x01170fb0, 0x0f9601a3, 0x00f30fb7, 0x0f9001c6,
+	0x00d00fbf, 0x0f8b01e6, 0x00ad0fc7, 0x0f870205,
+	0x008c0fcd, 0x0f840223, 0x006b0fd5, 0x0f800240,
+	0x004d0fdb, 0x0f7e025a, 0x002e0fe2, 0x0f7e0272,
+	0x00120fe8, 0x0f7f0287, 0x0ff90fee, 0x0f800299,
+	0x0fe00ff3, 0x0f8302aa, 0x0fcb0ff7, 0x0f8702b7,
+	0x0fb70ffc, 0x0f8c02c1, 0x0fa70ffe, 0x0f9402c7,
+
+	0x02f00f88, 0x00000f88, 0x02ee0f80, 0x0ffe0f94,
+	0x02e70f78, 0x0ffc0fa5, 0x02dd0f73, 0x0ff60fba,
+	0x02ce0f6f, 0x0ff20fd1, 0x02be0f6c, 0x0feb0feb,
+	0x02aa0f6b, 0x0fe50006, 0x02940f6a, 0x0fde0024,
+	0x02790f6c, 0x0fd60045, 0x025e0f6e, 0x0fcf0065,
+	0x023f0f72, 0x0fc60089, 0x021d0f77, 0x0fbf00ad,
+	0x01fd0f7b, 0x0fb600d2, 0x01da0f81, 0x0fad00f8,
+	0x01b50f87, 0x0fa6011e, 0x018f0f8f, 0x0f9e0144,
+	0x016b0f95, 0x0f95016b, 0x01440f9e, 0x0f8f018f,
+	0x011e0fa6, 0x0f8701b5, 0x00f80fad, 0x0f8101da,
+	0x00d20fb6, 0x0f7b01fd, 0x00ad0fbf, 0x0f77021d,
+	0x00890fc6, 0x0f72023f, 0x00650fcf, 0x0f6e025e,
+	0x00450fd6, 0x0f6c0279, 0x00240fde, 0x0f6a0294,
+	0x00060fe5, 0x0f6b02aa, 0x0feb0feb, 0x0f6c02be,
+	0x0fd10ff2, 0x0f6f02ce, 0x0fba0ff6, 0x0f7302dd,
+	0x0fa50ffc, 0x0f7802e7, 0x0f940ffe, 0x0f8002ee,
+
+	0x03180f74, 0x00000f74, 0x03160f6b, 0x0ffe0f81,
+	0x030e0f64, 0x0ffb0f93, 0x03030f5f, 0x0ff50fa9,
+	0x02f40f5b, 0x0ff00fc1, 0x02e20f58, 0x0fe90fdd,
+	0x02cd0f57, 0x0fe20ffa, 0x02b60f57, 0x0fda0019,
+	0x02990f59, 0x0fd1003d, 0x027b0f5c, 0x0fc90060,
+	0x02590f61, 0x0fc00086, 0x02370f66, 0x0fb700ac,
+	0x02130f6b, 0x0fae00d4, 0x01ee0f72, 0x0fa400fc,
+	0x01c70f79, 0x0f9b0125, 0x019f0f81, 0x0f93014d,
+	0x01760f89, 0x0f890178, 0x014d0f93, 0x0f81019f,
+	0x01250f9b, 0x0f7901c7, 0x00fc0fa4, 0x0f7201ee,
+	0x00d40fae, 0x0f6b0213, 0x00ac0fb7, 0x0f660237,
+	0x00860fc0, 0x0f610259, 0x00600fc9, 0x0f5c027b,
+	0x003d0fd1, 0x0f590299, 0x00190fda, 0x0f5702b6,
+	0x0ffa0fe2, 0x0f5702cd, 0x0fdd0fe9, 0x0f5802e2,
+	0x0fc10ff0, 0x0f5b02f4, 0x0fa90ff5, 0x0f5f0303,
+	0x0f930ffb, 0x0f64030e, 0x0f810ffe, 0x0f6b0316,
+
+	0x03400f60, 0x00000f60, 0x033e0f57, 0x0ffe0f6d,
+	0x03370f4f, 0x0ffa0f80, 0x032a0f4b, 0x0ff30f98,
+	0x031a0f46, 0x0fee0fb2, 0x03070f44, 0x0fe60fcf,
+	0x02f10f44, 0x0fde0fed, 0x02d70f44, 0x0fd6000f,
+	0x02b80f46, 0x0fcc0036, 0x02990f4a, 0x0fc3005a,
+	0x02750f4f, 0x0fb90083, 0x02500f55, 0x0fb000ab,
+	0x022a0f5b, 0x0fa500d6, 0x02020f63, 0x0f9a0101,
+	0x01d80f6b, 0x0f91012c, 0x01ae0f74, 0x0f870157,
+	0x01840f7c, 0x0f7c0184, 0x01570f87, 0x0f7401ae,
+	0x012c0f91, 0x0f6b01d8, 0x01010f9a, 0x0f630202,
+	0x00d60fa5, 0x0f5b022a, 0x00ab0fb0, 0x0f550250,
+	0x00830fb9, 0x0f4f0275, 0x005a0fc3, 0x0f4a0299,
+	0x00360fcc, 0x0f4602b8, 0x000f0fd6, 0x0f4402d7,
+	0x0fed0fde, 0x0f4402f1, 0x0fcf0fe6, 0x0f440307,
+	0x0fb20fee, 0x0f46031a, 0x0f980ff3, 0x0f4b032a,
+	0x0f800ffa, 0x0f4f0337, 0x0f6d0ffe, 0x0f57033e
 };
 
 
@@ -878,71 +1126,202 @@
 #define MDP4_QSEED_TABLE1_OFF 0x8200
 #define MDP4_QSEED_TABLE2_OFF 0x9000
 
-void mdp4_vg_qseed_init(struct mdp_info *mdp, int vp_num)
+void mdp4_vg_qseed_init(int vp_num)
 {
-	uint32_t off;
+	uint32 *off;
 	int i, voff;
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
 	voff = MDP4_VIDEO_OFF * vp_num;
-	off = MDP4_VIDEO_BASE + voff + MDP4_QSEED_TABLE0_OFF;
-	for (i = 0; i < (sizeof(vg_qseed_table0) / sizeof(uint32_t)); i++) {
-		mdp_writel(mdp, vg_qseed_table0[i], off);
-		off += 4;
+	off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
+						MDP4_QSEED_TABLE0_OFF);
+	for (i = 0; i < (sizeof(vg_qseed_table0) / sizeof(uint32)); i++) {
+		outpdw(off, vg_qseed_table0[i]);
+		off++;
+		/* This code is added to workaround the 1K Boundary AXI
+		Interleave operations from Scorpion that can potentially
+		corrupt the QSEED table. The idea is to complete the prevous
+		to the buffer before making the next write when address is
+		1KB aligned to ensure the write has been committed prior to
+		next instruction write that can go out from  the secondary AXI
+		port.This happens also because of the expected write sequence
+		from QSEED table, where LSP has to be written first then the
+		MSP to trigger both to write out to SRAM, if this has not been
+		the expectation, then corruption wouldn't have happened.*/
+
+		if (!((uint32)off & 0x3FF))
+			wmb();
 	}
 
-	off = MDP4_VIDEO_BASE + voff +	MDP4_QSEED_TABLE1_OFF;
-	for (i = 0; i < (sizeof(vg_qseed_table1) / sizeof(uint32_t)); i++) {
-		mdp_writel(mdp, vg_qseed_table1[i], off);
-		off += 4;
+	off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
+						MDP4_QSEED_TABLE1_OFF);
+	for (i = 0; i < (sizeof(vg_qseed_table1) / sizeof(uint32)); i++) {
+		outpdw(off, vg_qseed_table1[i]);
+		off++;
+		if (!((uint32)off & 0x3FF))
+			wmb();
 	}
 
-	off = MDP4_VIDEO_BASE + voff + MDP4_QSEED_TABLE2_OFF;
-	for (i = 0; i < (sizeof(vg_qseed_table2) / sizeof(uint32_t)); i++) {
-		mdp_writel(mdp, vg_qseed_table2[i], off);
-		off += 4;
+	off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
+						MDP4_QSEED_TABLE2_OFF);
+	for (i = 0; i < (sizeof(vg_qseed_table2) / sizeof(uint32)); i++) {
+		outpdw(off, vg_qseed_table2[i]);
+		off++;
+		if (!((uint32)off & 0x3FF))
+			wmb();
 	}
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
 }
 
-void mdp4_mixer_blend_init(struct mdp_info *mdp, int mixer_num)
+void mdp4_mixer_blend_init(mixer_num)
 {
-	unsigned long overlay_base;
+	unsigned char *overlay_base;
 	int off;
 
 	if (mixer_num) 	/* mixer number, /dev/fb0, /dev/fb1 */
-		overlay_base = MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
 	else
-		overlay_base = MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
 	/* stage 0 to stage 2 */
 	off = 0;
-	mdp_writel(mdp, 0x010, overlay_base + off + 0x104);
-	mdp_writel(mdp, 0xff, overlay_base + off + 0x108);/* FG */
-	mdp_writel(mdp, 0x00, overlay_base + off + 0x10c);/* BG */
+	outpdw(overlay_base + off + 0x104, 0x010);
+	outpdw(overlay_base + off + 0x108, 0xff);/* FG */
+	outpdw(overlay_base + off + 0x10c, 0x00);/* BG */
 
 	off += 0x20;
-	mdp_writel(mdp, 0x010, overlay_base + off + 0x104);
-	mdp_writel(mdp, 0xff, overlay_base + off + 0x108);/* FG */
-	mdp_writel(mdp, 0x00, overlay_base + off + 0x10c);/* BG */
+	outpdw(overlay_base + off + 0x104, 0x010);
+	outpdw(overlay_base + off + 0x108, 0xff);/* FG */
+	outpdw(overlay_base + off + 0x10c, 0x00);/* BG */
 
 	off += 0x20;
-	mdp_writel(mdp, 0x010, overlay_base + off + 0x104);
-	mdp_writel(mdp, 0xff, overlay_base + off + 0x108);/* FG */
-	mdp_writel(mdp, 0x00, overlay_base + off + 0x10c);/* BG */
+	outpdw(overlay_base + off + 0x104, 0x010);
+	outpdw(overlay_base + off + 0x108, 0xff);/* FG */
+	outpdw(overlay_base + off + 0x10c, 0x00);/* BG */
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-
-static uint32_t csc_matrix_tab[9] = {
-	0x0254, 0x0000, 0x0331,
-	0x0254, 0xff37, 0xfe60,
-	0x0254, 0x0409, 0x0000
+struct mdp_csc_cfg mdp_csc_convert[4] = {
+	{ /*RGB2RGB*/
+		0,
+		{
+			0x0200, 0x0000, 0x0000,
+			0x0000, 0x0200, 0x0000,
+			0x0000, 0x0000, 0x0200,
+		},
+		{ 0x0, 0x0, 0x0, },
+		{ 0x0, 0x0, 0x0, },
+		{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, },
+		{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, },
+	},
+	{ /*YUV2RGB*/
+		0,
+		{
+			0x0254, 0x0000, 0x0331,
+			0x0254, 0xff37, 0xfe60,
+			0x0254, 0x0409, 0x0000,
+		},
+		{ 0xfff0, 0xff80, 0xff80, },
+		{ 0x0, 0x0, 0x0, },
+		{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, },
+		{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, },
+	},
+	{ /*RGB2YUV*/
+		0,
+		{
+			0x0083, 0x0102, 0x0032,
+			0x1fb5, 0x1f6c, 0x00e1,
+			0x00e1, 0x1f45, 0x1fdc
+		},
+		{ 0x0, 0x0, 0x0, },
+		{ 0x0010, 0x0080, 0x0080, },
+		{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, },
+		{ 0x0010, 0x00eb, 0x0010, 0x00f0, 0x0010, 0x00f0, },
+	},
+	{ /*YUV2YUV ???*/
+		0,
+		{
+			0x0200, 0x0000, 0x0000,
+			0x0000, 0x0200, 0x0000,
+			0x0000, 0x0000, 0x0200,
+		},
+		{ 0x0, 0x0, 0x0, },
+		{ 0x0, 0x0, 0x0, },
+		{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, },
+		{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, },
+	},
 };
 
-static uint32_t csc_pre_bv_tab[3] = {0xfff0, 0xff80, 0xff80 };
-static uint32_t csc_post_bv_tab[3] = {0, 0, 0 };
+struct mdp_csc_cfg csc_matrix[3] = {
+	{
+		(MDP_CSC_FLAG_YUV_OUT),
+		{
+			0x0254, 0x0000, 0x0331,
+			0x0254, 0xff37, 0xfe60,
+			0x0254, 0x0409, 0x0000,
+		},
+		{
+			0xfff0, 0xff80, 0xff80,
+		},
+		{
+			0, 0, 0,
+		},
+		{
+			0, 0xff, 0, 0xff, 0, 0xff,
+		},
+		{
+			0, 0xff, 0, 0xff, 0, 0xff,
+		},
+	},
+	{
+		(MDP_CSC_FLAG_YUV_OUT),
+		{
+			0x0254, 0x0000, 0x0331,
+			0x0254, 0xff37, 0xfe60,
+			0x0254, 0x0409, 0x0000,
+		},
+		{
+			0xfff0, 0xff80, 0xff80,
+		},
+		{
+			0, 0, 0,
+		},
+		{
+			0, 0xff, 0, 0xff, 0, 0xff,
+		},
+		{
+			0, 0xff, 0, 0xff, 0, 0xff,
+		},
+	},
+	{
+		(0),
+		{
+			0x0200, 0x0000, 0x0000,
+			0x0000, 0x0200, 0x0000,
+			0x0000, 0x0000, 0x0200,
+		},
+		{
+			0x0, 0x0, 0x0,
+		},
+		{
+			0, 0, 0,
+		},
+		{
+			0, 0xff, 0, 0xff, 0, 0xff,
+		},
+		{
+			0, 0xff, 0, 0xff, 0, 0xff,
+		},
+	},
+};
 
-static  uint32_t csc_pre_lv_tab[6] =  {0, 0xff, 0, 0xff, 0, 0xff };
-static  uint32_t csc_post_lv_tab[6] = {0, 0xff, 0, 0xff, 0, 0xff };
+
 
 #define MDP4_CSC_MV_OFF 	0x4400
 #define MDP4_CSC_PRE_BV_OFF 	0x4500
@@ -950,158 +1329,352 @@
 #define MDP4_CSC_PRE_LV_OFF 	0x4600
 #define MDP4_CSC_POST_LV_OFF 	0x4680
 
-void mdp4_vg_csc_mv_setup(struct mdp_info *mdp, int vp_num)
+void mdp4_vg_csc_mv_setup(int vp_num)
 {
-	uint32_t off;
+	uint32 *off;
 	int i, voff;
 
 	voff = MDP4_VIDEO_OFF * vp_num;
-	off = MDP4_VIDEO_BASE + voff + MDP4_CSC_MV_OFF;
+	off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
+					MDP4_CSC_MV_OFF);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 9; i++) {
-    mdp_writel(mdp, csc_matrix_tab[i], off);
-		off += 4;
+		outpdw(off, csc_matrix[vp_num].csc_mv[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_vg_csc_pre_bv_setup(struct mdp_info *mdp, int vp_num)
+void mdp4_vg_csc_pre_bv_setup(int vp_num)
 {
-	uint32_t off;
+	uint32 *off;
 	int i, voff;
 
 	voff = MDP4_VIDEO_OFF * vp_num;
-	off = MDP4_VIDEO_BASE + voff + MDP4_CSC_PRE_BV_OFF;
+	off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
+					MDP4_CSC_PRE_BV_OFF);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 3; i++) {
-    mdp_writel(mdp, csc_pre_bv_tab[i], off);
-		off += 4;
+		outpdw(off, csc_matrix[vp_num].csc_pre_bv[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_vg_csc_post_bv_setup(struct mdp_info *mdp, int vp_num)
+void mdp4_vg_csc_post_bv_setup(int vp_num)
 {
-	uint32_t off;
+	uint32 *off;
 	int i, voff;
 
 	voff = MDP4_VIDEO_OFF * vp_num;
-	off = MDP4_VIDEO_BASE + voff + MDP4_CSC_POST_BV_OFF;
+	off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
+					MDP4_CSC_POST_BV_OFF);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 3; i++) {
-    mdp_writel(mdp, csc_post_bv_tab[i], off);
-		off += 4;
+		outpdw(off, csc_matrix[vp_num].csc_post_bv[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_vg_csc_pre_lv_setup(struct mdp_info *mdp, int vp_num)
+void mdp4_vg_csc_pre_lv_setup(int vp_num)
 {
-	uint32_t off;
+	uint32 *off;
 	int i, voff;
 
 	voff = MDP4_VIDEO_OFF * vp_num;
-	off = MDP4_VIDEO_BASE + voff + MDP4_CSC_PRE_LV_OFF;
+	off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
+					MDP4_CSC_PRE_LV_OFF);
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 6; i++) {
-		mdp_writel(mdp, csc_pre_lv_tab[i], off);
-		off += 4;
+		outpdw(off, csc_matrix[vp_num].csc_pre_lv[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_vg_csc_post_lv_setup(struct mdp_info *mdp, int vp_num)
+void mdp4_vg_csc_post_lv_setup(int vp_num)
 {
-	uint32_t off;
+	uint32 *off;
 	int i, voff;
 
 	voff = MDP4_VIDEO_OFF * vp_num;
-	off = MDP4_VIDEO_BASE + voff + MDP4_CSC_POST_LV_OFF;
+	off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff +
+					MDP4_CSC_POST_LV_OFF);
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 6; i++) {
-		mdp_writel(mdp, csc_post_lv_tab[i], off);
-		off += 4;
+		outpdw(off, csc_matrix[vp_num].csc_post_lv[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-static uint32_t csc_rgb2yuv_matrix_tab[9] = {
+void mdp4_vg_csc_convert_setup(int vp_num)
+{
+	struct mdp_csc_cfg_data cfg;
+
+	switch (vp_num) {
+	case 0:
+		cfg.block = MDP_BLOCK_VG_1;
+		break;
+	case 1:
+		cfg.block = MDP_BLOCK_VG_2;
+		break;
+	default:
+		pr_err("%s - invalid vp_num = %d", __func__, vp_num);
+		return;
+	}
+	cfg.csc_data = csc_matrix[vp_num];
+	mdp4_csc_enable(&cfg);
+}
+
+void mdp4_vg_csc_setup(int vp_num)
+{
+		/* yuv2rgb */
+		mdp4_vg_csc_mv_setup(vp_num);
+		mdp4_vg_csc_pre_bv_setup(vp_num);
+		mdp4_vg_csc_post_bv_setup(vp_num);
+		mdp4_vg_csc_pre_lv_setup(vp_num);
+		mdp4_vg_csc_post_lv_setup(vp_num);
+		mdp4_vg_csc_convert_setup(vp_num);
+}
+void mdp4_vg_csc_update(struct mdp_csc *p)
+{
+	struct mdp4_overlay_pipe *pipe;
+	int vp_num;
+
+	pipe = mdp4_overlay_ndx2pipe(p->id);
+	if (pipe == NULL) {
+		pr_err("%s: p->id = %d Error\n", __func__, p->id);
+		return;
+	}
+
+	vp_num = pipe->pipe_num - OVERLAY_PIPE_VG1;
+
+	if (vp_num == 0 || vp_num == 1) {
+		memcpy(csc_matrix[vp_num].csc_mv, p->csc_mv, sizeof(p->csc_mv));
+		memcpy(csc_matrix[vp_num].csc_pre_bv, p->csc_pre_bv,
+			sizeof(p->csc_pre_bv));
+		memcpy(csc_matrix[vp_num].csc_post_bv, p->csc_post_bv,
+			sizeof(p->csc_post_bv));
+		memcpy(csc_matrix[vp_num].csc_pre_lv, p->csc_pre_lv,
+			sizeof(p->csc_pre_lv));
+		memcpy(csc_matrix[vp_num].csc_post_lv, p->csc_post_lv,
+			sizeof(p->csc_post_lv));
+		mdp4_vg_csc_setup(vp_num);
+	}
+}
+static uint32 csc_rgb2yuv_matrix_tab[9] = {
 	0x0083, 0x0102, 0x0032,
-	0xffb5, 0xff6c, 0x00e1,
-	0x00e1, 0xff45, 0xffdc
+	0x1fb5, 0x1f6c, 0x00e1,
+	0x00e1, 0x1f45, 0x1fdc
 };
 
-static uint32_t csc_rgb2yuv_pre_bv_tab[3] = {0, 0, 0};
+static uint32 csc_rgb2yuv_pre_bv_tab[3] = {0, 0, 0};
 
-static uint32_t csc_rgb2yuv_post_bv_tab[3] = {0x0010, 0x0080, 0x0080};
+static uint32 csc_rgb2yuv_post_bv_tab[3] = {0x0010, 0x0080, 0x0080};
 
-static  uint32_t csc_rgb2yuv_pre_lv_tab[6] = {
+static  uint32 csc_rgb2yuv_pre_lv_tab[6] = {
 	0x00, 0xff, 0x00,
 	0xff, 0x00, 0xff
 };
 
-static  uint32_t csc_rgb2yuv_post_lv_tab[6] = {
+static  uint32 csc_rgb2yuv_post_lv_tab[6] = {
 	0x0010, 0x00eb, 0x0010,
 	0x00f0, 0x0010, 0x00f0
 };
 
-void mdp4_mixer1_csc_mv_setup(struct mdp_info *mdp)
+void mdp4_mixer_csc_mv_setup(uint32 mixer)
 {
-	uint32_t off;
+	uint32 *off;
 	int i;
 
-	off = MDP4_OVERLAYPROC1_BASE + 0x2400;
+	if (mixer == MDP4_MIXER1)
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2400);
+	else
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC2_BASE + 0x2400);
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 9; i++) {
-		mdp_writel(mdp, csc_rgb2yuv_matrix_tab[i], off);
-		off += 4;
+		outpdw(off, csc_rgb2yuv_matrix_tab[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_mixer1_csc_pre_bv_setup(struct mdp_info *mdp)
+void mdp4_mixer_csc_pre_bv_setup(uint32 mixer)
 {
-	uint32_t off;
+	uint32 *off;
 	int i;
 
-	off = MDP4_OVERLAYPROC1_BASE + 0x2500;
+	if (mixer == MDP4_MIXER1)
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2500);
+	else
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC2_BASE + 0x2500);
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 3; i++) {
-		mdp_writel(mdp, csc_rgb2yuv_pre_bv_tab[i], off);
-		off += 4;
+		outpdw(off, csc_rgb2yuv_pre_bv_tab[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_mixer1_csc_post_bv_setup(struct mdp_info *mdp)
+void mdp4_mixer_csc_post_bv_setup(uint32 mixer)
 {
-	uint32_t off;
+	uint32 *off;
 	int i;
 
-	off = MDP4_OVERLAYPROC1_BASE + 0x2580;
+	if (mixer == MDP4_MIXER1)
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2580);
+	else
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC2_BASE + 0x2580);
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 3; i++) {
-		mdp_writel(mdp, csc_rgb2yuv_post_bv_tab[i], off);
-		off += 4;
+		outpdw(off, csc_rgb2yuv_post_bv_tab[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_mixer1_csc_pre_lv_setup(struct mdp_info *mdp)
+void mdp4_mixer_csc_pre_lv_setup(uint32 mixer)
 {
-	uint32_t off;
+	uint32 *off;
 	int i;
 
-	off = MDP4_OVERLAYPROC1_BASE + 0x2600;
+	if (mixer == MDP4_MIXER1)
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2600);
+	else
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC2_BASE + 0x2600);
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 6; i++) {
-		mdp_writel(mdp, csc_rgb2yuv_pre_lv_tab[i], off);
-		off += 4;
+		outpdw(off, csc_rgb2yuv_pre_lv_tab[i]);
+		off++;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-void mdp4_mixer1_csc_post_lv_setup(struct mdp_info *mdp)
+void mdp4_mixer_csc_post_lv_setup(uint32 mixer)
 {
-	uint32_t off;
+	uint32 *off;
 	int i;
 
-	off = MDP4_OVERLAYPROC1_BASE + 0x2680;
+	if (mixer == MDP4_MIXER1)
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2680);
+	else
+		off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC2_BASE + 0x2680);
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	for (i = 0; i < 6; i++) {
-		mdp_writel(mdp, csc_rgb2yuv_post_lv_tab[i], off);
-		off += 4;
+		outpdw(off, csc_rgb2yuv_post_lv_tab[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_mixer_csc_setup(uint32 mixer)
+{
+	if (mixer >= MDP4_MIXER1) {
+		/* rgb2yuv */
+		mdp4_mixer_csc_mv_setup(mixer);
+		mdp4_mixer_csc_pre_bv_setup(mixer);
+		mdp4_mixer_csc_post_bv_setup(mixer);
+		mdp4_mixer_csc_pre_lv_setup(mixer);
+		mdp4_mixer_csc_post_lv_setup(mixer);
 	}
 }
 
+#define DMA_P_BASE 0x90000
+void mdp4_dmap_csc_mv_setup(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + DMA_P_BASE + 0x3400);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 9; i++) {
+		outpdw(off, csc_matrix[2].csc_mv[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_dmap_csc_pre_bv_setup(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + DMA_P_BASE + 0x3500);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 3; i++) {
+		outpdw(off, csc_matrix[2].csc_pre_bv[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_dmap_csc_post_bv_setup(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + DMA_P_BASE + 0x3580);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 3; i++) {
+		outpdw(off, csc_matrix[2].csc_post_bv[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_dmap_csc_pre_lv_setup(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + DMA_P_BASE + 0x3600);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 6; i++) {
+		outpdw(off, csc_matrix[2].csc_pre_lv[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_dmap_csc_post_lv_setup(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + DMA_P_BASE + 0x3680);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 6; i++) {
+		outpdw(off, csc_matrix[2].csc_post_lv[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_dmap_csc_setup(void)
+{
+	mdp4_dmap_csc_mv_setup();
+	mdp4_dmap_csc_pre_bv_setup();
+	mdp4_dmap_csc_post_bv_setup();
+	mdp4_dmap_csc_pre_lv_setup();
+	mdp4_dmap_csc_post_lv_setup();
+}
 
 char gc_lut[] = {
 	0x0, 0x1, 0x2, 0x2, 0x3, 0x4, 0x5, 0x6,
@@ -1618,30 +2191,32 @@
 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 };
 
-void mdp4_mixer_gc_lut_setup(struct mdp_info *mdp, int mixer_num)
+void mdp4_mixer_gc_lut_setup(int mixer_num)
 {
-	unsigned long base;
-	uint32_t data;
+	unsigned char *base;
+	uint32 data;
 	char val;
 	int i, off;
 
 	if (mixer_num) 	/* mixer number, /dev/fb0, /dev/fb1 */
-		base = MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
+		base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
 	else
-		base = MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+		base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
 
 	base += 0x4000;	/* GC_LUT offset */
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	off = 0;
 	for (i = 0; i < 4096; i++) {
 		val = gc_lut[i];
 		data = (val << 16 | val << 8 | val); /* R, B, and G are same */
-		mdp_writel(mdp, data, base + off);
+		outpdw(base + off, data);
 		off += 4;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-uint32_t igc_video_lut[] = {	 /* non linear */
+uint32 igc_video_lut[] = {	 /* non linear */
 	0x0, 0x1, 0x2, 0x4, 0x5, 0x6, 0x7, 0x9,
 	0xA, 0xB, 0xC, 0xE, 0xF, 0x10, 0x12, 0x14,
 	0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F, 0x21, 0x23,
@@ -1676,26 +2251,28 @@
 	0xF04, 0xF27, 0xF4B, 0xF6E, 0xF92, 0xFB6, 0xFDB, 0xFFF,
 };
 
-void mdp4_vg_igc_lut_setup(struct mdp_info *mdp, int vp_num)
+void mdp4_vg_igc_lut_setup(int vp_num)
 {
-	unsigned long base;
+	unsigned char *base;
 	int i, voff, off;
-	uint32_t data, val;
+	uint32 data, val;
 
 	voff = MDP4_VIDEO_OFF * vp_num;
-	base = MDP4_VIDEO_BASE + voff + 0x5000;
+	base = MDP_BASE + MDP4_VIDEO_BASE + voff + 0x5000;
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	off = 0;
 	for (i = 0; i < 256; i++) {
 		val = igc_video_lut[i];
 		data = (val << 16 | val);	/* color 0 and 1 */
-		mdp_writel(mdp, data, base + off);
-    mdp_writel(mdp, val, base + off + 0x800);	/* color 2 */
+		outpdw(base + off, data);
+		outpdw(base + off + 0x800, val);	/* color 2 */
 		off += 4;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-uint32_t igc_rgb_lut[] = {   /* linear */
+uint32 igc_rgb_lut[] = {   /* linear */
 	0x0, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
 	0x80, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
 	0x101, 0x111, 0x121, 0x131, 0x141, 0x151, 0x161, 0x171,
@@ -1730,26 +2307,875 @@
 	0xF8F, 0xF9F, 0xFAF, 0xFBF, 0xFCF, 0xFDF, 0xFEF, 0xFFF,
 };
 
-void mdp4_rgb_igc_lut_setup(struct mdp_info *mdp, int num)
+void mdp4_rgb_igc_lut_setup(int num)
 {
-	unsigned long base;
+	unsigned char *base;
 	int i, voff, off;
-	uint32_t data, val;
+	uint32 data, val;
 
 	voff = MDP4_RGB_OFF * num;
-	base = MDP4_RGB_BASE + voff + 0x5000;
+	base = MDP_BASE + MDP4_RGB_BASE + voff + 0x5000;
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	off = 0;
 	for (i = 0; i < 256; i++) {
 		val = igc_rgb_lut[i];
 		data = (val << 16 | val);	/* color 0 and 1 */
-		mdp_writel(mdp, data, base + off);
-    mdp_writel(mdp, val, base + off + 0x800);	/* color 2 */
+		outpdw(base + off, data);
+		outpdw(base + off + 0x800, val);	/* color 2 */
 		off += 4;
 	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+uint32 mdp4_rgb_igc_lut_cvt(uint32 ndx)
+{
+	return igc_rgb_lut[ndx & 0x0ff];
+}
+
+uint32_t mdp4_ss_table_value(int8_t value, int8_t index)
+{
+	uint32_t out = 0x0;
+	int8_t level = -1;
+	uint32_t mask = 0xffffffff;
+
+	if (value < 0) {
+		if (value == -128)
+			value = 127;
+		else
+			value = -value;
+		out = 0x11111111;
+	} else {
+		out = 0x88888888;
+		mask = 0x0fffffff;
+	}
+
+	if (value == 0)
+		level = 0;
+	else {
+		while (value > 0 && level < 7) {
+			level++;
+			value -= 16;
+		}
+	}
+
+	if (level == 0) {
+		if (index == 0)
+			out = 0x0;
+		else
+			out = 0x20000000;
+	} else {
+		out += (0x11111111 * level);
+		if (index == 1)
+			out &= mask;
+	}
+
+	return out;
+}
+
+static uint32_t mdp4_csc_block2base(uint32_t block)
+{
+	uint32_t base = 0x0;
+	switch (block) {
+	case MDP_BLOCK_OVERLAY_1:
+		base = 0x1A000;
+		break;
+	case MDP_BLOCK_OVERLAY_2:
+		base = (mdp_rev >= MDP_REV_44) ? 0x8A000 : 0x0;
+		break;
+	case MDP_BLOCK_VG_1:
+		base = 0x24000;
+		break;
+	case MDP_BLOCK_VG_2:
+		base = 0x34000;
+		break;
+	case MDP_BLOCK_DMA_P:
+		base = 0x93000;
+		break;
+	case MDP_BLOCK_DMA_S:
+		base = (mdp_rev >= MDP_REV_42) ? 0xA3000 : 0x0;
+	default:
+		break;
+	}
+	return base;
+}
+
+int mdp4_csc_enable(struct mdp_csc_cfg_data *config)
+{
+	uint32_t output, base, temp, mask;
+
+	switch (config->block) {
+	case MDP_BLOCK_DMA_P:
+		base = 0x90070;
+		output = (config->csc_data.flags << 3) & (0x08);
+		temp = (config->csc_data.flags << 10) & (0x1800);
+		output |= temp;
+		mask = 0x08 | 0x1800;
+		break;
+	case MDP_BLOCK_DMA_S:
+		base = 0xA0028;
+		output = (config->csc_data.flags << 3) & (0x08);
+		temp = (config->csc_data.flags << 10) & (0x1800);
+		output |= temp;
+		mask = 0x08 | 0x1800;
+		break;
+	case MDP_BLOCK_VG_1:
+		base = 0x20058;
+		output = (config->csc_data.flags << 11) & (0x800);
+		temp = (config->csc_data.flags << 8) & (0x600);
+		output |= temp;
+		mask = 0x800 | 0x600;
+		break;
+	case MDP_BLOCK_VG_2:
+		base = 0x30058;
+		output = (config->csc_data.flags << 11) & (0x800);
+		temp = (config->csc_data.flags << 8) & (0x600);
+		output |= temp;
+		mask = 0x800 | 0x600;
+		break;
+	case MDP_BLOCK_OVERLAY_1:
+		base = 0x18200;
+		output = config->csc_data.flags;
+		mask = 0x07;
+		break;
+	case MDP_BLOCK_OVERLAY_2:
+		base = 0x88200;
+		output = config->csc_data.flags;
+		mask = 0x07;
+		break;
+	default:
+		pr_err("%s - CSC block does not exist on MDP_BLOCK = %d\n",
+						__func__, config->block);
+		return -EINVAL;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	temp = inpdw(MDP_BASE + base) & ~mask;
+	output |= temp;
+	outpdw(MDP_BASE + base, output);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	return 0;
+}
+
+#define CSC_MV_OFF	0x400
+#define CSC_BV_OFF	0x500
+#define CSC_LV_OFF	0x600
+#define CSC_POST_OFF	0x80
+
+void mdp4_csc_write(struct mdp_csc_cfg *data, uint32_t base)
+{
+	int i;
+	uint32_t *off;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	off = (uint32_t *) ((uint32_t) base + CSC_MV_OFF);
+	for (i = 0; i < 9; i++) {
+		outpdw(off, data->csc_mv[i]);
+		off++;
+	}
+
+	off = (uint32_t *) ((uint32_t) base + CSC_BV_OFF);
+	for (i = 0; i < 3; i++) {
+		outpdw(off, data->csc_pre_bv[i]);
+		outpdw((uint32_t *)((uint32_t)off + CSC_POST_OFF),
+					data->csc_post_bv[i]);
+		off++;
+	}
+
+	off = (uint32_t *) ((uint32_t) base + CSC_LV_OFF);
+	for (i = 0; i < 6; i++) {
+		outpdw(off, data->csc_pre_lv[i]);
+		outpdw((uint32_t *)((uint32_t)off + CSC_POST_OFF),
+					data->csc_post_lv[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+int mdp4_csc_config(struct mdp_csc_cfg_data *config)
+{
+	int ret = 0;
+	uint32_t base;
+
+	base = mdp4_csc_block2base(config->block);
+	if (!base) {
+		pr_warn("%s: Block type %d isn't supported by CSC.\n",
+				__func__, config->block);
+		return -EINVAL;
+	}
+
+	mdp4_csc_write(&config->csc_data, (uint32_t) (MDP_BASE + base));
+
+	ret = mdp4_csc_enable(config);
+
+	return ret;
+}
+
+void mdp4_init_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num)
+{
+	struct mdp_buf_type *buf;
+
+	if (mix_num == MDP4_MIXER0)
+		buf = mfd->ov0_wb_buf;
+	else
+		buf = mfd->ov1_wb_buf;
+
+	buf->ihdl = NULL;
+	buf->write_addr = 0;
+	buf->read_addr = 0;
+}
+
+u32 mdp4_allocate_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num)
+{
+	struct mdp_buf_type *buf;
+	ion_phys_addr_t	addr;
+	size_t buffer_size;
+	unsigned long len;
+
+	if (mix_num == MDP4_MIXER0)
+		buf = mfd->ov0_wb_buf;
+	else
+		buf = mfd->ov1_wb_buf;
+
+	if (buf->write_addr || !IS_ERR_OR_NULL(buf->ihdl))
+		return 0;
+
+	if (!buf->size) {
+		pr_err("%s:%d In valid size\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	buffer_size = roundup(mfd->panel_info.xres * \
+		mfd->panel_info.yres * 3 * 2, SZ_4K);
+
+	if (!IS_ERR_OR_NULL(mfd->iclient)) {
+		pr_info("%s:%d ion based allocation mfd->mem_hid 0x%x\n",
+			__func__, __LINE__, mfd->mem_hid);
+		buf->ihdl = ion_alloc(mfd->iclient, buffer_size, SZ_4K,
+			mfd->mem_hid);
+		if (!IS_ERR_OR_NULL(buf->ihdl)) {
+			if (ion_map_iommu(mfd->iclient, buf->ihdl,
+				DISPLAY_DOMAIN, GEN_POOL, SZ_4K, 0, &addr,
+				&len, 0, 0)) {
+				pr_err("ion_map_iommu() failed\n");
+				return -ENOMEM;
+			}
+		} else {
+			pr_err("%s:%d: ion_alloc failed\n", __func__,
+				__LINE__);
+			return -ENOMEM;
+		}
+	} else {
+		addr = allocate_contiguous_memory_nomap(buffer_size,
+			mfd->mem_hid, 4);
+	}
+	if (addr) {
+		pr_info("allocating %d bytes at %x for mdp writeback\n",
+			buffer_size, (u32) addr);
+		buf->write_addr = addr;
+		buf->read_addr = buf->write_addr;
+		return 0;
+	} else {
+		pr_err("%s cannot allocate memory for mdp writeback!\n",
+			 __func__);
+		return -ENOMEM;
+	}
 }
 
-uint32_t mdp4_rgb_igc_lut_cvt(uint32_t ndx)
+void mdp4_free_writeback_buf(struct msm_fb_data_type *mfd, u32 mix_num)
 {
-	return igc_rgb_lut[ndx & 0x0ff];
+	struct mdp_buf_type *buf;
+
+	if (mix_num == MDP4_MIXER0)
+		buf = mfd->ov0_wb_buf;
+	else
+		buf = mfd->ov1_wb_buf;
+
+	if (!IS_ERR_OR_NULL(mfd->iclient)) {
+		if (!IS_ERR_OR_NULL(buf->ihdl)) {
+			ion_unmap_iommu(mfd->iclient, buf->ihdl,
+				DISPLAY_DOMAIN, GEN_POOL);
+			ion_free(mfd->iclient, buf->ihdl);
+			buf->ihdl = NULL;
+			pr_info("%s:%d free ION writeback imem",
+					__func__, __LINE__);
+		}
+	} else {
+		if (buf->write_addr) {
+			free_contiguous_memory_by_paddr(buf->write_addr);
+			pr_info("%s:%d free writeback pmem\n", __func__,
+				__LINE__);
+		}
+	}
+	buf->write_addr = 0;
+	buf->read_addr = 0;
+}
+
+static int mdp4_update_pcc_regs(uint32_t offset,
+				struct mdp_pcc_cfg_data *cfg_ptr)
+{
+	int ret = -1;
+
+	if (offset && cfg_ptr) {
+
+		outpdw(offset, cfg_ptr->r.c);
+		outpdw(offset + 0x30, cfg_ptr->g.c);
+		outpdw(offset + 0x60, cfg_ptr->b.c);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.r);
+		outpdw(offset + 0x30, cfg_ptr->g.r);
+		outpdw(offset + 0x60, cfg_ptr->b.r);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.g);
+		outpdw(offset + 0x30, cfg_ptr->g.g);
+		outpdw(offset + 0x60, cfg_ptr->b.g);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.b);
+		outpdw(offset + 0x30, cfg_ptr->g.b);
+		outpdw(offset + 0x60, cfg_ptr->b.b);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.rr);
+		outpdw(offset + 0x30, cfg_ptr->g.rr);
+		outpdw(offset + 0x60, cfg_ptr->b.rr);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.gg);
+		outpdw(offset + 0x30, cfg_ptr->g.gg);
+		outpdw(offset + 0x60, cfg_ptr->b.gg);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.bb);
+		outpdw(offset + 0x30, cfg_ptr->g.bb);
+		outpdw(offset + 0x60, cfg_ptr->b.bb);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.rg);
+		outpdw(offset + 0x30, cfg_ptr->g.rg);
+		outpdw(offset + 0x60, cfg_ptr->b.rg);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.gb);
+		outpdw(offset + 0x30, cfg_ptr->g.gb);
+		outpdw(offset + 0x60, cfg_ptr->b.gb);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.rb);
+		outpdw(offset + 0x30, cfg_ptr->g.rb);
+		outpdw(offset + 0x60, cfg_ptr->b.rb);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.rgb_0);
+		outpdw(offset + 0x30, cfg_ptr->g.rgb_0);
+		outpdw(offset + 0x60, cfg_ptr->b.rgb_0);
+		offset += 4;
+
+		outpdw(offset, cfg_ptr->r.rgb_1);
+		outpdw(offset + 0x30, cfg_ptr->g.rgb_1);
+		outpdw(offset + 0x60, cfg_ptr->b.rgb_1);
+
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int mdp4_read_pcc_regs(uint32_t offset,
+				struct mdp_pcc_cfg_data *cfg_ptr)
+{
+	int ret = -1;
+
+	if (offset && cfg_ptr) {
+		cfg_ptr->r.c = inpdw(offset);
+		cfg_ptr->g.c = inpdw(offset + 0x30);
+		cfg_ptr->b.c = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.r = inpdw(offset);
+		cfg_ptr->g.r = inpdw(offset + 0x30);
+		cfg_ptr->b.r = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.g = inpdw(offset);
+		cfg_ptr->g.g = inpdw(offset + 0x30);
+		cfg_ptr->b.g = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.b = inpdw(offset);
+		cfg_ptr->g.b = inpdw(offset + 0x30);
+		cfg_ptr->b.b = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.rr = inpdw(offset);
+		cfg_ptr->g.rr = inpdw(offset + 0x30);
+		cfg_ptr->b.rr = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.gg = inpdw(offset);
+		cfg_ptr->g.gg = inpdw(offset + 0x30);
+		cfg_ptr->b.gg = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.bb = inpdw(offset);
+		cfg_ptr->g.bb = inpdw(offset + 0x30);
+		cfg_ptr->b.bb = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.rg = inpdw(offset);
+		cfg_ptr->g.rg = inpdw(offset + 0x30);
+		cfg_ptr->b.rg = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.gb = inpdw(offset);
+		cfg_ptr->g.gb = inpdw(offset + 0x30);
+		cfg_ptr->b.gb = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.rb = inpdw(offset);
+		cfg_ptr->g.rb = inpdw(offset + 0x30);
+		cfg_ptr->b.rb = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.rgb_0 = inpdw(offset);
+		cfg_ptr->g.rgb_0 = inpdw(offset + 0x30);
+		cfg_ptr->b.rgb_0 = inpdw(offset + 0x60);
+		offset += 4;
+
+		cfg_ptr->r.rgb_1 = inpdw(offset);
+		cfg_ptr->g.rgb_1 = inpdw(offset + 0x30);
+		cfg_ptr->b.rgb_1 = inpdw(offset + 0x60);
+
+		ret = 0;
+	}
+
+	return ret;
+}
+
+
+#define MDP_PCC_OFFSET 0xA000
+#define MDP_DMA_GC_OFFSET 0x8800
+#define MDP_LM_GC_OFFSET 0x4800
+
+#define MDP_DMA_P_OP_MODE_OFFSET 0x70
+#define MDP_DMA_S_OP_MODE_OFFSET 0x28
+#define MDP_LM_OP_MODE_OFFSET 0x14
+
+#define DMA_PCC_R2_OFFSET 0x100
+
+#define MDP_GC_COLOR_OFFSET	0x100
+#define MDP_GC_PARMS_OFFSET	0x80
+
+#define MDP_AR_GC_MAX_STAGES	16
+
+static uint32_t mdp_pp_block2pcc(uint32_t block)
+{
+	uint32_t valid = 0;
+
+	switch (block) {
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+		valid = (mdp_rev >= MDP_REV_42) ? 1 : 0;
+		break;
+
+	default:
+		break;
+	}
+
+	return valid;
+}
+
+int mdp4_pcc_cfg(struct mdp_pcc_cfg_data *cfg_ptr)
+{
+	int ret = -1;
+	uint32_t pcc_offset = 0, mdp_cfg_offset = 0;
+	uint32_t mdp_dma_op_mode = 0;
+	uint32_t blockbase;
+
+	if (!mdp_pp_block2pcc(cfg_ptr->block))
+		return ret;
+
+	blockbase = mdp_block2base(cfg_ptr->block);
+	if (!blockbase)
+		return ret;
+
+	blockbase += (uint32_t) MDP_BASE;
+
+	switch (cfg_ptr->block) {
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+		pcc_offset = blockbase + MDP_PCC_OFFSET;
+		mdp_cfg_offset = blockbase;
+		mdp_dma_op_mode = blockbase +
+			(MDP_BLOCK_DMA_P == cfg_ptr->block ?
+			 MDP_DMA_P_OP_MODE_OFFSET
+			 : MDP_DMA_S_OP_MODE_OFFSET);
+		break;
+
+	default:
+		break;
+	}
+
+	if (0x8 & cfg_ptr->ops)
+		pcc_offset += DMA_PCC_R2_OFFSET;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	switch ((0x6 & cfg_ptr->ops)>>1) {
+	case 0x1:
+		ret = mdp4_read_pcc_regs(pcc_offset, cfg_ptr);
+		break;
+
+	case 0x2:
+		ret = mdp4_update_pcc_regs(pcc_offset, cfg_ptr);
+		break;
+
+	default:
+		break;
+	}
+
+	if (0x8 & cfg_ptr->ops)
+		outpdw(mdp_dma_op_mode,
+			(inpdw(mdp_dma_op_mode)|((0x8&cfg_ptr->ops)<<10)));
+
+	outpdw(mdp_cfg_offset,
+			(inpdw(mdp_cfg_offset)|((cfg_ptr->ops&0x1)<<29)));
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return ret;
+}
+
+static uint32_t mdp_pp_block2argc(uint32_t block)
+{
+	uint32_t valid = 0;
+
+	switch (block) {
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+	case MDP_BLOCK_OVERLAY_0:
+	case MDP_BLOCK_OVERLAY_1:
+		valid = (mdp_rev >= MDP_REV_42) ? 1 : 0;
+		break;
+
+	case MDP_BLOCK_OVERLAY_2:
+		valid = (mdp_rev >= MDP_REV_44) ? 1 : 0;
+		break;
+
+	default:
+		break;
+	}
+
+	return valid;
+}
+
+static int update_ar_gc_lut(uint32_t *offset, struct mdp_pgc_lut_data *lut_data)
+{
+	int count = 0;
+
+	uint32_t *c0_offset = offset;
+	uint32_t *c0_params_offset = (uint32_t *)((uint32_t)c0_offset
+							+ MDP_GC_PARMS_OFFSET);
+
+	uint32_t *c1_offset = (uint32_t *)((uint32_t)offset
+							+ MDP_GC_COLOR_OFFSET);
+
+	uint32_t *c1_params_offset = (uint32_t *)((uint32_t)c1_offset
+							+ MDP_GC_PARMS_OFFSET);
+
+	uint32_t *c2_offset = (uint32_t *)((uint32_t)offset
+						+ 2*MDP_GC_COLOR_OFFSET);
+
+	uint32_t *c2_params_offset = (uint32_t *)((uint32_t)c2_offset
+						+MDP_GC_PARMS_OFFSET);
+
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (count = 0; count < MDP_AR_GC_MAX_STAGES; count++) {
+		if (count < lut_data->num_r_stages) {
+			outpdw(c0_offset+count,
+				((0xfff & lut_data->r_data[count].x_start)
+					| 0x10000));
+
+			outpdw(c0_params_offset+count,
+				((0x7fff & lut_data->r_data[count].slope)
+					| ((0xffff
+					& lut_data->r_data[count].offset)
+						<< 16)));
+		} else
+			outpdw(c0_offset+count, 0);
+
+		if (count < lut_data->num_b_stages) {
+			outpdw(c1_offset+count,
+				((0xfff & lut_data->b_data[count].x_start)
+					| 0x10000));
+
+			outpdw(c1_params_offset+count,
+				((0x7fff & lut_data->b_data[count].slope)
+					| ((0xffff
+					& lut_data->b_data[count].offset)
+						<< 16)));
+		} else
+			outpdw(c1_offset+count, 0);
+
+		if (count < lut_data->num_g_stages) {
+			outpdw(c2_offset+count,
+				((0xfff & lut_data->g_data[count].x_start)
+					| 0x10000));
+
+			outpdw(c2_params_offset+count,
+				((0x7fff & lut_data->g_data[count].slope)
+				| ((0xffff
+				& lut_data->g_data[count].offset)
+					<< 16)));
+		} else
+			outpdw(c2_offset+count, 0);
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return 0;
+}
+
+static int mdp4_argc_process_write_req(uint32_t *offset,
+		struct mdp_pgc_lut_data *pgc_ptr)
+{
+	int ret = -1;
+	struct mdp_ar_gc_lut_data r[MDP_AR_GC_MAX_STAGES];
+	struct mdp_ar_gc_lut_data g[MDP_AR_GC_MAX_STAGES];
+	struct mdp_ar_gc_lut_data b[MDP_AR_GC_MAX_STAGES];
+
+	ret = copy_from_user(&r[0], pgc_ptr->r_data,
+		pgc_ptr->num_r_stages * sizeof(struct mdp_ar_gc_lut_data));
+
+	if (!ret) {
+		ret = copy_from_user(&g[0],
+				pgc_ptr->g_data,
+				pgc_ptr->num_g_stages
+				* sizeof(struct mdp_ar_gc_lut_data));
+		if (!ret)
+			ret = copy_from_user(&b[0],
+					pgc_ptr->b_data,
+					pgc_ptr->num_b_stages
+					* sizeof(struct mdp_ar_gc_lut_data));
+	}
+
+	if (ret)
+		return ret;
+
+	pgc_ptr->r_data = &r[0];
+	pgc_ptr->g_data = &g[0];
+	pgc_ptr->b_data = &b[0];
+
+	ret = update_ar_gc_lut(offset, pgc_ptr);
+	return ret;
+}
+
+int mdp4_argc_cfg(struct mdp_pgc_lut_data *pgc_ptr)
+{
+	int ret = -1;
+	uint32_t *offset = 0, *pgc_enable_offset = 0, lshift_bits = 0;
+	uint32_t blockbase;
+
+	if (!mdp_pp_block2argc(pgc_ptr->block))
+		return ret;
+
+	blockbase = mdp_block2base(pgc_ptr->block);
+	if (!blockbase)
+		return ret;
+
+	blockbase += (uint32_t) MDP_BASE;
+	ret = 0;
+
+	switch (pgc_ptr->block) {
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+		offset = (uint32_t *)(blockbase + MDP_DMA_GC_OFFSET);
+		pgc_enable_offset = (uint32_t *) blockbase;
+		lshift_bits = 28;
+		break;
+
+	case MDP_BLOCK_OVERLAY_0:
+	case MDP_BLOCK_OVERLAY_1:
+	case MDP_BLOCK_OVERLAY_2:
+		offset = (uint32_t *)(blockbase + MDP_LM_GC_OFFSET);
+		pgc_enable_offset = (uint32_t *)(blockbase
+				+ MDP_LM_OP_MODE_OFFSET);
+		lshift_bits = 2;
+		break;
+
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (!ret) {
+
+		switch ((0x6 & pgc_ptr->flags)>>1) {
+		case 0x1:
+			ret = -ENOTTY;
+			break;
+
+		case 0x2:
+			ret = mdp4_argc_process_write_req(offset, pgc_ptr);
+			break;
+
+		default:
+			break;
+		}
+
+		if (!ret) {
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+			outpdw(pgc_enable_offset, (inpdw(pgc_enable_offset) |
+				((0x1 & pgc_ptr->flags) << lshift_bits)));
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF,
+									FALSE);
+		}
+	}
+
+	return ret;
+}
+
+static uint32_t mdp4_pp_block2igc(uint32_t block)
+{
+	uint32_t valid = 0;
+	switch (block) {
+	case MDP_BLOCK_VG_1:
+		valid = 0x1;
+		break;
+	case MDP_BLOCK_VG_2:
+		valid = 0x1;
+		break;
+	case MDP_BLOCK_RGB_1:
+		valid = 0x1;
+		break;
+	case MDP_BLOCK_RGB_2:
+		valid = 0x1;
+		break;
+	case MDP_BLOCK_DMA_P:
+		valid = (mdp_rev >= MDP_REV_40) ? 1 : 0;
+		break;
+	case MDP_BLOCK_DMA_S:
+		valid = (mdp_rev >= MDP_REV_40) ? 1 : 0;
+		break;
+	default:
+		break;
+	}
+	return valid;
+}
+
+static int mdp4_igc_lut_write(struct mdp_igc_lut_data *cfg, uint32_t en_off,
+		uint32_t lut_off)
+{
+	int i;
+	uint32_t base, *off_low, *off_high;
+	uint32_t low[cfg->len];
+	uint32_t high[cfg->len];
+
+	base = mdp_block2base(cfg->block);
+
+	if (cfg->len != 256)
+		return -EINVAL;
+
+	off_low = (uint32_t *)(MDP_BASE + base + lut_off);
+	off_high = (uint32_t *)(MDP_BASE + base + lut_off + 0x800);
+	if (copy_from_user(&low, cfg->c0_c1_data, cfg->len * sizeof(uint32_t)))
+		return -EFAULT;
+	if (copy_from_user(&high, cfg->c2_data, cfg->len * sizeof(uint32_t)))
+		return -EFAULT;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < cfg->len; i++) {
+		MDP_OUTP(off_low++, low[i]);
+		/*low address write should occur before high address write*/
+		wmb();
+		MDP_OUTP(off_high++, high[i]);
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	return 0;
+}
+
+static int mdp4_igc_lut_ctrl(struct mdp_igc_lut_data *cfg)
+{
+	uint32_t mask, out;
+	uint32_t base = mdp_block2base(cfg->block);
+	int8_t shift = 0;
+
+	switch (cfg->block) {
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+		base = base;
+		shift = 30;
+		break;
+	case MDP_BLOCK_VG_1:
+	case MDP_BLOCK_VG_2:
+	case MDP_BLOCK_RGB_1:
+	case MDP_BLOCK_RGB_2:
+		base += 0x58;
+		shift = 16;
+		break;
+	default:
+		return -EINVAL;
+
+	}
+	out = 1<<shift;
+	mask = ~out;
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	out = inpdw(MDP_BASE + base) & mask;
+	MDP_OUTP(MDP_BASE + base, out | ((cfg->ops & 0x1)<<shift));
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return 0;
+}
+
+static int mdp4_igc_lut_write_cfg(struct mdp_igc_lut_data *cfg)
+{
+	int ret = 0;
+
+	switch (cfg->block) {
+	case MDP_BLOCK_DMA_P:
+	case MDP_BLOCK_DMA_S:
+		ret = mdp4_igc_lut_write(cfg, 0x00, 0x9000);
+		break;
+	case MDP_BLOCK_VG_1:
+	case MDP_BLOCK_VG_2:
+	case MDP_BLOCK_RGB_1:
+	case MDP_BLOCK_RGB_2:
+		ret = mdp4_igc_lut_write(cfg, 0x58, 0x5000);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+int mdp4_igc_lut_config(struct mdp_igc_lut_data *cfg)
+{
+	int ret = 0;
+
+	if (!mdp4_pp_block2igc(cfg->block)) {
+		ret = -ENOTTY;
+		goto error;
+	}
+
+	switch ((cfg->ops & 0x6) >> 1) {
+	case 0x1:
+		pr_info("%s: IGC LUT read not supported\n", __func__);
+		break;
+	case 0x2:
+		ret = mdp4_igc_lut_write_cfg(cfg);
+		if (ret)
+			goto error;
+		break;
+	default:
+		break;
+	}
+
+	ret = mdp4_igc_lut_ctrl(cfg);
+
+error:
+	return ret;
 }
diff --git a/drivers/video/msm/mdp4_wfd_writeback.c b/drivers/video/msm/mdp4_wfd_writeback.c
new file mode 100644
index 0000000..a8fdcc0
--- /dev/null
+++ b/drivers/video/msm/mdp4_wfd_writeback.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/version.h>
+
+#include "mdp4_wfd_writeback_util.h"
+#include "msm_fb.h"
+
+static int writeback_on(struct platform_device *pdev)
+{
+	return 0;
+}
+static int writeback_off(struct platform_device *pdev)
+{
+	return 0;
+}
+static int writeback_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct platform_device *mdp_dev = NULL;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc = 0;
+
+	WRITEBACK_MSG_ERR("Inside writeback_probe\n");
+	mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mdp_dev = platform_device_alloc("mdp", pdev->id);
+	if (!mdp_dev)
+		return -ENOMEM;
+	/*
+	 * link to the latest pdev
+	 */
+	mfd->pdev = mdp_dev;
+	mfd->dest = DISPLAY_LCD;
+
+	if (platform_device_add_data
+			(mdp_dev, pdev->dev.platform_data,
+			 sizeof(struct msm_fb_panel_data))) {
+		pr_err("writeback_probe: "
+			"platform_device_add_data failed!\n");
+		platform_device_put(mdp_dev);
+		return -ENOMEM;
+	}
+	pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data;
+	pdata->on = writeback_on;
+	pdata->off = writeback_off;
+	pdata->next = pdev;
+
+	/*
+	 * get/set panel specific fb info
+	 */
+	mfd->panel_info = pdata->panel_info;
+
+	mfd->fb_imgType = MDP_RGB_565;
+
+	platform_set_drvdata(mdp_dev, mfd);
+
+	rc = platform_device_add(mdp_dev);
+	if (rc) {
+		WRITEBACK_MSG_ERR("failed to add device");
+		platform_device_put(mdp_dev);
+		return rc;
+	}
+	return rc;
+}
+
+static struct platform_driver writeback_driver = {
+	.probe = writeback_probe,
+	.driver = {
+		.name = "writeback",
+	},
+};
+
+static int __init writeback_driver_init(void)
+{
+	int rc = 0;
+	WRITEBACK_MSG_ERR("Inside writeback_driver_init\n");
+	rc = platform_driver_register(&writeback_driver);
+	return rc;
+}
+
+module_init(writeback_driver_init);
diff --git a/drivers/video/msm/mdp4_wfd_writeback_panel.c b/drivers/video/msm/mdp4_wfd_writeback_panel.c
new file mode 100644
index 0000000..40ffb65
--- /dev/null
+++ b/drivers/video/msm/mdp4_wfd_writeback_panel.c
@@ -0,0 +1,83 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/version.h>
+
+#include "mdp4_wfd_writeback_util.h"
+#include "msm_fb.h"
+
+static int __devinit writeback_panel_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	if (pdev->id == 0)
+		return 0;
+
+	if (!msm_fb_add_device(pdev)) {
+		WRITEBACK_MSG_ERR("Failed to add fd device\n");
+		rc = -ENOMEM;
+	}
+	return rc;
+}
+static struct msm_fb_panel_data writeback_msm_panel_data = {
+	.panel_info = {
+		.type = WRITEBACK_PANEL,
+		.xres = 1280,
+		.yres = 720,
+		.pdest = DISPLAY_3,
+		.wait_cycle = 0,
+		.bpp = 24,
+		.fb_num = 1,
+		.clk_rate = 74250000,
+	},
+};
+
+static struct platform_device writeback_panel_device = {
+	.name = "writeback_panel",
+	.id = 1,
+	.dev.platform_data = &writeback_msm_panel_data,
+};
+static struct platform_driver writeback_panel_driver = {
+	.probe = writeback_panel_probe,
+	.driver = {
+		.name = "writeback_panel"
+	}
+};
+
+static int __init writeback_panel_init(void)
+{
+	int rc = 0;
+	rc = platform_driver_register(&writeback_panel_driver);
+	if (rc) {
+		WRITEBACK_MSG_ERR("Failed to register platform driver\n");
+		goto fail_driver_registration;
+	}
+	rc = platform_device_register(&writeback_panel_device);
+	if (rc) {
+		WRITEBACK_MSG_ERR("Failed to register "
+				"writeback_panel_device\n");
+		goto fail_device_registration;
+	}
+	return rc;
+fail_device_registration:
+	platform_driver_unregister(&writeback_panel_driver);
+fail_driver_registration:
+	return rc;
+}
+
+module_init(writeback_panel_init);
diff --git a/drivers/video/msm/mdp4_wfd_writeback_util.h b/drivers/video/msm/mdp4_wfd_writeback_util.h
new file mode 100644
index 0000000..2d62713
--- /dev/null
+++ b/drivers/video/msm/mdp4_wfd_writeback_util.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _WRITEBACK_UTIL_H_
+#define _WRITEBACK_UTIL_H_
+
+#define DEBUG
+
+#ifdef DEBUG
+	#define WRITEBACK_MSG_INFO(fmt...) pr_info(fmt)
+	#define WRITEBACK_MSG_WARN(fmt...) pr_warning(fmt)
+#else
+	#define WRITEBACK_MSG_INFO(fmt...)
+	#define WRITEBACK_MSG_WARN(fmt...)
+#endif
+	#define WRITEBACK_MSG_ERR(fmt...) pr_err(fmt)
+	#define WRITEBACK_MSG_CRIT(fmt...) pr_crit(fmt)
+#endif
diff --git a/drivers/video/msm/mdp_csc_table.h b/drivers/video/msm/mdp_csc_table.h
new file mode 100644
index 0000000..a0f72c0
--- /dev/null
+++ b/drivers/video/msm/mdp_csc_table.h
@@ -0,0 +1,641 @@
+/* drivers/video/msm/mdp_csc_table.h
+ *
+ * Copyright (C) 2007 QUALCOMM Incorporated
+ * Copyright (C) 2007 Google Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+static struct {
+	uint32_t reg;
+	uint32_t val;
+} csc_matrix_config_table[] = {
+	/* RGB -> YUV primary forward matrix (set1). */
+	{ MDP_CSC_PFMVn(0), 0x83 },
+	{ MDP_CSC_PFMVn(1), 0x102 },
+	{ MDP_CSC_PFMVn(2), 0x32 },
+	{ MDP_CSC_PFMVn(3), 0xffffffb5 },
+	{ MDP_CSC_PFMVn(4), 0xffffff6c },
+	{ MDP_CSC_PFMVn(5), 0xe1 },
+	{ MDP_CSC_PFMVn(6), 0xe1 },
+	{ MDP_CSC_PFMVn(7), 0xffffff45 },
+	{ MDP_CSC_PFMVn(8), 0xffffffdc },
+
+	/* YUV -> RGB primary reverse matrix (set2) */
+	{ MDP_CSC_PRMVn(0), 0x254 },
+	{ MDP_CSC_PRMVn(1), 0x0 },
+	{ MDP_CSC_PRMVn(2), 0x331 },
+	{ MDP_CSC_PRMVn(3), 0x254 },
+	{ MDP_CSC_PRMVn(4), 0xffffff38 },
+	{ MDP_CSC_PRMVn(5), 0xfffffe61 },
+	{ MDP_CSC_PRMVn(6), 0x254 },
+	{ MDP_CSC_PRMVn(7), 0x409 },
+	{ MDP_CSC_PRMVn(8), 0x0 },
+
+#ifndef CONFIG_MSM_MDP31
+	/* For MDP 2.2/3.0 */
+
+	/* primary limit vector */
+	{ MDP_CSC_PLVn(0), 0x10 },
+	{ MDP_CSC_PLVn(1), 0xeb },
+	{ MDP_CSC_PLVn(2), 0x10 },
+	{ MDP_CSC_PLVn(3), 0xf0 },
+
+	/* primary bias vector */
+	{ MDP_CSC_PBVn(0), 0x10 },
+	{ MDP_CSC_PBVn(1), 0x80 },
+	{ MDP_CSC_PBVn(2), 0x80 },
+
+#else /* CONFIG_MSM_MDP31 */
+
+	/* limit vectors configuration */
+	/* rgb -> yuv (set1) pre-limit vector */
+	{ MDP_PPP_CSC_PRE_LV1n(0), 0x10 },
+	{ MDP_PPP_CSC_PRE_LV1n(1), 0xeb },
+	{ MDP_PPP_CSC_PRE_LV1n(2), 0x10 },
+	{ MDP_PPP_CSC_PRE_LV1n(3), 0xf0 },
+	{ MDP_PPP_CSC_PRE_LV1n(4), 0x10 },
+	{ MDP_PPP_CSC_PRE_LV1n(5), 0xf0 },
+
+	/* rgb -> yuv (set1) post-limit vector */
+	{ MDP_PPP_CSC_POST_LV1n(0), 0x0 },
+	{ MDP_PPP_CSC_POST_LV1n(1), 0xff },
+	{ MDP_PPP_CSC_POST_LV1n(2), 0x0 },
+	{ MDP_PPP_CSC_POST_LV1n(3), 0xff },
+	{ MDP_PPP_CSC_POST_LV1n(4), 0x0 },
+	{ MDP_PPP_CSC_POST_LV1n(5), 0xff },
+
+	/* yuv -> rgb (set2) pre-limit vector */
+	{ MDP_PPP_CSC_PRE_LV2n(0), 0x0 },
+	{ MDP_PPP_CSC_PRE_LV2n(1), 0xff },
+	{ MDP_PPP_CSC_PRE_LV2n(2), 0x0 },
+	{ MDP_PPP_CSC_PRE_LV2n(3), 0xff },
+	{ MDP_PPP_CSC_PRE_LV2n(4), 0x0 },
+	{ MDP_PPP_CSC_PRE_LV2n(5), 0xff },
+
+	/* yuv -> rgb (set2) post-limit vector */
+	{ MDP_PPP_CSC_POST_LV2n(0), 0x10 },
+	{ MDP_PPP_CSC_POST_LV2n(1), 0xeb },
+	{ MDP_PPP_CSC_POST_LV2n(2), 0x10 },
+	{ MDP_PPP_CSC_POST_LV2n(3), 0xf0 },
+	{ MDP_PPP_CSC_POST_LV2n(4), 0x10 },
+	{ MDP_PPP_CSC_POST_LV2n(5), 0xf0 },
+
+	/* bias vectors configuration */
+
+	/* XXX: why is set2 used for rgb->yuv, but set1 */
+	/* used for yuv -> rgb??!? Seems to be the reverse of the
+	 * other vectors. */
+
+	/* RGB -> YUV pre-bias vector... */
+	{ MDP_PPP_CSC_PRE_BV2n(0), 0 },
+	{ MDP_PPP_CSC_PRE_BV2n(1), 0 },
+	{ MDP_PPP_CSC_PRE_BV2n(2), 0 },
+
+	/* RGB -> YUV post-bias vector */
+	{ MDP_PPP_CSC_POST_BV2n(0), 0x10 },
+	{ MDP_PPP_CSC_POST_BV2n(1), 0x80 },
+	{ MDP_PPP_CSC_POST_BV2n(2), 0x80 },
+
+	/* YUV -> RGB pre-bias vector... */
+	{ MDP_PPP_CSC_PRE_BV1n(0), 0x1f0 },
+	{ MDP_PPP_CSC_PRE_BV1n(1), 0x180 },
+	{ MDP_PPP_CSC_PRE_BV1n(2), 0x180 },
+
+	/* YUV -> RGB post-bias vector */
+	{ MDP_PPP_CSC_POST_BV1n(0), 0 },
+	{ MDP_PPP_CSC_POST_BV1n(1), 0 },
+	{ MDP_PPP_CSC_POST_BV1n(2), 0 },
+
+	/* luma filter coefficients */
+	{ MDP_PPP_DEINT_COEFFn(0), 0x3e0 },
+	{ MDP_PPP_DEINT_COEFFn(1), 0x360 },
+	{ MDP_PPP_DEINT_COEFFn(2), 0x120 },
+	{ MDP_PPP_DEINT_COEFFn(3), 0x140 },
+#endif
+};
+
+static struct {
+	uint32_t reg;
+	uint32_t val;
+} csc_color_lut[] = {
+	{ 0x40800, 0x0 },
+	{ 0x40804, 0x151515 },
+	{ 0x40808, 0x1d1d1d },
+	{ 0x4080c, 0x232323 },
+	{ 0x40810, 0x272727 },
+	{ 0x40814, 0x2b2b2b },
+	{ 0x40818, 0x2f2f2f },
+	{ 0x4081c, 0x333333 },
+	{ 0x40820, 0x363636 },
+	{ 0x40824, 0x393939 },
+	{ 0x40828, 0x3b3b3b },
+	{ 0x4082c, 0x3e3e3e },
+	{ 0x40830, 0x404040 },
+	{ 0x40834, 0x434343 },
+	{ 0x40838, 0x454545 },
+	{ 0x4083c, 0x474747 },
+	{ 0x40840, 0x494949 },
+	{ 0x40844, 0x4b4b4b },
+	{ 0x40848, 0x4d4d4d },
+	{ 0x4084c, 0x4f4f4f },
+	{ 0x40850, 0x515151 },
+	{ 0x40854, 0x535353 },
+	{ 0x40858, 0x555555 },
+	{ 0x4085c, 0x565656 },
+	{ 0x40860, 0x585858 },
+	{ 0x40864, 0x5a5a5a },
+	{ 0x40868, 0x5b5b5b },
+	{ 0x4086c, 0x5d5d5d },
+	{ 0x40870, 0x5e5e5e },
+	{ 0x40874, 0x606060 },
+	{ 0x40878, 0x616161 },
+	{ 0x4087c, 0x636363 },
+	{ 0x40880, 0x646464 },
+	{ 0x40884, 0x666666 },
+	{ 0x40888, 0x676767 },
+	{ 0x4088c, 0x686868 },
+	{ 0x40890, 0x6a6a6a },
+	{ 0x40894, 0x6b6b6b },
+	{ 0x40898, 0x6c6c6c },
+	{ 0x4089c, 0x6e6e6e },
+	{ 0x408a0, 0x6f6f6f },
+	{ 0x408a4, 0x707070 },
+	{ 0x408a8, 0x717171 },
+	{ 0x408ac, 0x727272 },
+	{ 0x408b0, 0x747474 },
+	{ 0x408b4, 0x757575 },
+	{ 0x408b8, 0x767676 },
+	{ 0x408bc, 0x777777 },
+	{ 0x408c0, 0x787878 },
+	{ 0x408c4, 0x797979 },
+	{ 0x408c8, 0x7a7a7a },
+	{ 0x408cc, 0x7c7c7c },
+	{ 0x408d0, 0x7d7d7d },
+	{ 0x408d4, 0x7e7e7e },
+	{ 0x408d8, 0x7f7f7f },
+	{ 0x408dc, 0x808080 },
+	{ 0x408e0, 0x818181 },
+	{ 0x408e4, 0x828282 },
+	{ 0x408e8, 0x838383 },
+	{ 0x408ec, 0x848484 },
+	{ 0x408f0, 0x858585 },
+	{ 0x408f4, 0x868686 },
+	{ 0x408f8, 0x878787 },
+	{ 0x408fc, 0x888888 },
+	{ 0x40900, 0x898989 },
+	{ 0x40904, 0x8a8a8a },
+	{ 0x40908, 0x8b8b8b },
+	{ 0x4090c, 0x8c8c8c },
+	{ 0x40910, 0x8d8d8d },
+	{ 0x40914, 0x8e8e8e },
+	{ 0x40918, 0x8f8f8f },
+	{ 0x4091c, 0x8f8f8f },
+	{ 0x40920, 0x909090 },
+	{ 0x40924, 0x919191 },
+	{ 0x40928, 0x929292 },
+	{ 0x4092c, 0x939393 },
+	{ 0x40930, 0x949494 },
+	{ 0x40934, 0x959595 },
+	{ 0x40938, 0x969696 },
+	{ 0x4093c, 0x969696 },
+	{ 0x40940, 0x979797 },
+	{ 0x40944, 0x989898 },
+	{ 0x40948, 0x999999 },
+	{ 0x4094c, 0x9a9a9a },
+	{ 0x40950, 0x9b9b9b },
+	{ 0x40954, 0x9c9c9c },
+	{ 0x40958, 0x9c9c9c },
+	{ 0x4095c, 0x9d9d9d },
+	{ 0x40960, 0x9e9e9e },
+	{ 0x40964, 0x9f9f9f },
+	{ 0x40968, 0xa0a0a0 },
+	{ 0x4096c, 0xa0a0a0 },
+	{ 0x40970, 0xa1a1a1 },
+	{ 0x40974, 0xa2a2a2 },
+	{ 0x40978, 0xa3a3a3 },
+	{ 0x4097c, 0xa4a4a4 },
+	{ 0x40980, 0xa4a4a4 },
+	{ 0x40984, 0xa5a5a5 },
+	{ 0x40988, 0xa6a6a6 },
+	{ 0x4098c, 0xa7a7a7 },
+	{ 0x40990, 0xa7a7a7 },
+	{ 0x40994, 0xa8a8a8 },
+	{ 0x40998, 0xa9a9a9 },
+	{ 0x4099c, 0xaaaaaa },
+	{ 0x409a0, 0xaaaaaa },
+	{ 0x409a4, 0xababab },
+	{ 0x409a8, 0xacacac },
+	{ 0x409ac, 0xadadad },
+	{ 0x409b0, 0xadadad },
+	{ 0x409b4, 0xaeaeae },
+	{ 0x409b8, 0xafafaf },
+	{ 0x409bc, 0xafafaf },
+	{ 0x409c0, 0xb0b0b0 },
+	{ 0x409c4, 0xb1b1b1 },
+	{ 0x409c8, 0xb2b2b2 },
+	{ 0x409cc, 0xb2b2b2 },
+	{ 0x409d0, 0xb3b3b3 },
+	{ 0x409d4, 0xb4b4b4 },
+	{ 0x409d8, 0xb4b4b4 },
+	{ 0x409dc, 0xb5b5b5 },
+	{ 0x409e0, 0xb6b6b6 },
+	{ 0x409e4, 0xb6b6b6 },
+	{ 0x409e8, 0xb7b7b7 },
+	{ 0x409ec, 0xb8b8b8 },
+	{ 0x409f0, 0xb8b8b8 },
+	{ 0x409f4, 0xb9b9b9 },
+	{ 0x409f8, 0xbababa },
+	{ 0x409fc, 0xbababa },
+	{ 0x40a00, 0xbbbbbb },
+	{ 0x40a04, 0xbcbcbc },
+	{ 0x40a08, 0xbcbcbc },
+	{ 0x40a0c, 0xbdbdbd },
+	{ 0x40a10, 0xbebebe },
+	{ 0x40a14, 0xbebebe },
+	{ 0x40a18, 0xbfbfbf },
+	{ 0x40a1c, 0xc0c0c0 },
+	{ 0x40a20, 0xc0c0c0 },
+	{ 0x40a24, 0xc1c1c1 },
+	{ 0x40a28, 0xc1c1c1 },
+	{ 0x40a2c, 0xc2c2c2 },
+	{ 0x40a30, 0xc3c3c3 },
+	{ 0x40a34, 0xc3c3c3 },
+	{ 0x40a38, 0xc4c4c4 },
+	{ 0x40a3c, 0xc5c5c5 },
+	{ 0x40a40, 0xc5c5c5 },
+	{ 0x40a44, 0xc6c6c6 },
+	{ 0x40a48, 0xc6c6c6 },
+	{ 0x40a4c, 0xc7c7c7 },
+	{ 0x40a50, 0xc8c8c8 },
+	{ 0x40a54, 0xc8c8c8 },
+	{ 0x40a58, 0xc9c9c9 },
+	{ 0x40a5c, 0xc9c9c9 },
+	{ 0x40a60, 0xcacaca },
+	{ 0x40a64, 0xcbcbcb },
+	{ 0x40a68, 0xcbcbcb },
+	{ 0x40a6c, 0xcccccc },
+	{ 0x40a70, 0xcccccc },
+	{ 0x40a74, 0xcdcdcd },
+	{ 0x40a78, 0xcecece },
+	{ 0x40a7c, 0xcecece },
+	{ 0x40a80, 0xcfcfcf },
+	{ 0x40a84, 0xcfcfcf },
+	{ 0x40a88, 0xd0d0d0 },
+	{ 0x40a8c, 0xd0d0d0 },
+	{ 0x40a90, 0xd1d1d1 },
+	{ 0x40a94, 0xd2d2d2 },
+	{ 0x40a98, 0xd2d2d2 },
+	{ 0x40a9c, 0xd3d3d3 },
+	{ 0x40aa0, 0xd3d3d3 },
+	{ 0x40aa4, 0xd4d4d4 },
+	{ 0x40aa8, 0xd4d4d4 },
+	{ 0x40aac, 0xd5d5d5 },
+	{ 0x40ab0, 0xd6d6d6 },
+	{ 0x40ab4, 0xd6d6d6 },
+	{ 0x40ab8, 0xd7d7d7 },
+	{ 0x40abc, 0xd7d7d7 },
+	{ 0x40ac0, 0xd8d8d8 },
+	{ 0x40ac4, 0xd8d8d8 },
+	{ 0x40ac8, 0xd9d9d9 },
+	{ 0x40acc, 0xd9d9d9 },
+	{ 0x40ad0, 0xdadada },
+	{ 0x40ad4, 0xdbdbdb },
+	{ 0x40ad8, 0xdbdbdb },
+	{ 0x40adc, 0xdcdcdc },
+	{ 0x40ae0, 0xdcdcdc },
+	{ 0x40ae4, 0xdddddd },
+	{ 0x40ae8, 0xdddddd },
+	{ 0x40aec, 0xdedede },
+	{ 0x40af0, 0xdedede },
+	{ 0x40af4, 0xdfdfdf },
+	{ 0x40af8, 0xdfdfdf },
+	{ 0x40afc, 0xe0e0e0 },
+	{ 0x40b00, 0xe0e0e0 },
+	{ 0x40b04, 0xe1e1e1 },
+	{ 0x40b08, 0xe1e1e1 },
+	{ 0x40b0c, 0xe2e2e2 },
+	{ 0x40b10, 0xe3e3e3 },
+	{ 0x40b14, 0xe3e3e3 },
+	{ 0x40b18, 0xe4e4e4 },
+	{ 0x40b1c, 0xe4e4e4 },
+	{ 0x40b20, 0xe5e5e5 },
+	{ 0x40b24, 0xe5e5e5 },
+	{ 0x40b28, 0xe6e6e6 },
+	{ 0x40b2c, 0xe6e6e6 },
+	{ 0x40b30, 0xe7e7e7 },
+	{ 0x40b34, 0xe7e7e7 },
+	{ 0x40b38, 0xe8e8e8 },
+	{ 0x40b3c, 0xe8e8e8 },
+	{ 0x40b40, 0xe9e9e9 },
+	{ 0x40b44, 0xe9e9e9 },
+	{ 0x40b48, 0xeaeaea },
+	{ 0x40b4c, 0xeaeaea },
+	{ 0x40b50, 0xebebeb },
+	{ 0x40b54, 0xebebeb },
+	{ 0x40b58, 0xececec },
+	{ 0x40b5c, 0xececec },
+	{ 0x40b60, 0xededed },
+	{ 0x40b64, 0xededed },
+	{ 0x40b68, 0xeeeeee },
+	{ 0x40b6c, 0xeeeeee },
+	{ 0x40b70, 0xefefef },
+	{ 0x40b74, 0xefefef },
+	{ 0x40b78, 0xf0f0f0 },
+	{ 0x40b7c, 0xf0f0f0 },
+	{ 0x40b80, 0xf1f1f1 },
+	{ 0x40b84, 0xf1f1f1 },
+	{ 0x40b88, 0xf2f2f2 },
+	{ 0x40b8c, 0xf2f2f2 },
+	{ 0x40b90, 0xf2f2f2 },
+	{ 0x40b94, 0xf3f3f3 },
+	{ 0x40b98, 0xf3f3f3 },
+	{ 0x40b9c, 0xf4f4f4 },
+	{ 0x40ba0, 0xf4f4f4 },
+	{ 0x40ba4, 0xf5f5f5 },
+	{ 0x40ba8, 0xf5f5f5 },
+	{ 0x40bac, 0xf6f6f6 },
+	{ 0x40bb0, 0xf6f6f6 },
+	{ 0x40bb4, 0xf7f7f7 },
+	{ 0x40bb8, 0xf7f7f7 },
+	{ 0x40bbc, 0xf8f8f8 },
+	{ 0x40bc0, 0xf8f8f8 },
+	{ 0x40bc4, 0xf9f9f9 },
+	{ 0x40bc8, 0xf9f9f9 },
+	{ 0x40bcc, 0xfafafa },
+	{ 0x40bd0, 0xfafafa },
+	{ 0x40bd4, 0xfafafa },
+	{ 0x40bd8, 0xfbfbfb },
+	{ 0x40bdc, 0xfbfbfb },
+	{ 0x40be0, 0xfcfcfc },
+	{ 0x40be4, 0xfcfcfc },
+	{ 0x40be8, 0xfdfdfd },
+	{ 0x40bec, 0xfdfdfd },
+	{ 0x40bf0, 0xfefefe },
+	{ 0x40bf4, 0xfefefe },
+	{ 0x40bf8, 0xffffff },
+	{ 0x40bfc, 0xffffff },
+	{ 0x40c00, 0x0 },
+	{ 0x40c04, 0x0 },
+	{ 0x40c08, 0x0 },
+	{ 0x40c0c, 0x0 },
+	{ 0x40c10, 0x0 },
+	{ 0x40c14, 0x0 },
+	{ 0x40c18, 0x0 },
+	{ 0x40c1c, 0x0 },
+	{ 0x40c20, 0x0 },
+	{ 0x40c24, 0x0 },
+	{ 0x40c28, 0x0 },
+	{ 0x40c2c, 0x0 },
+	{ 0x40c30, 0x0 },
+	{ 0x40c34, 0x0 },
+	{ 0x40c38, 0x0 },
+	{ 0x40c3c, 0x0 },
+	{ 0x40c40, 0x10101 },
+	{ 0x40c44, 0x10101 },
+	{ 0x40c48, 0x10101 },
+	{ 0x40c4c, 0x10101 },
+	{ 0x40c50, 0x10101 },
+	{ 0x40c54, 0x10101 },
+	{ 0x40c58, 0x10101 },
+	{ 0x40c5c, 0x10101 },
+	{ 0x40c60, 0x10101 },
+	{ 0x40c64, 0x10101 },
+	{ 0x40c68, 0x20202 },
+	{ 0x40c6c, 0x20202 },
+	{ 0x40c70, 0x20202 },
+	{ 0x40c74, 0x20202 },
+	{ 0x40c78, 0x20202 },
+	{ 0x40c7c, 0x20202 },
+	{ 0x40c80, 0x30303 },
+	{ 0x40c84, 0x30303 },
+	{ 0x40c88, 0x30303 },
+	{ 0x40c8c, 0x30303 },
+	{ 0x40c90, 0x30303 },
+	{ 0x40c94, 0x40404 },
+	{ 0x40c98, 0x40404 },
+	{ 0x40c9c, 0x40404 },
+	{ 0x40ca0, 0x40404 },
+	{ 0x40ca4, 0x40404 },
+	{ 0x40ca8, 0x50505 },
+	{ 0x40cac, 0x50505 },
+	{ 0x40cb0, 0x50505 },
+	{ 0x40cb4, 0x50505 },
+	{ 0x40cb8, 0x60606 },
+	{ 0x40cbc, 0x60606 },
+	{ 0x40cc0, 0x60606 },
+	{ 0x40cc4, 0x70707 },
+	{ 0x40cc8, 0x70707 },
+	{ 0x40ccc, 0x70707 },
+	{ 0x40cd0, 0x70707 },
+	{ 0x40cd4, 0x80808 },
+	{ 0x40cd8, 0x80808 },
+	{ 0x40cdc, 0x80808 },
+	{ 0x40ce0, 0x90909 },
+	{ 0x40ce4, 0x90909 },
+	{ 0x40ce8, 0xa0a0a },
+	{ 0x40cec, 0xa0a0a },
+	{ 0x40cf0, 0xa0a0a },
+	{ 0x40cf4, 0xb0b0b },
+	{ 0x40cf8, 0xb0b0b },
+	{ 0x40cfc, 0xb0b0b },
+	{ 0x40d00, 0xc0c0c },
+	{ 0x40d04, 0xc0c0c },
+	{ 0x40d08, 0xd0d0d },
+	{ 0x40d0c, 0xd0d0d },
+	{ 0x40d10, 0xe0e0e },
+	{ 0x40d14, 0xe0e0e },
+	{ 0x40d18, 0xe0e0e },
+	{ 0x40d1c, 0xf0f0f },
+	{ 0x40d20, 0xf0f0f },
+	{ 0x40d24, 0x101010 },
+	{ 0x40d28, 0x101010 },
+	{ 0x40d2c, 0x111111 },
+	{ 0x40d30, 0x111111 },
+	{ 0x40d34, 0x121212 },
+	{ 0x40d38, 0x121212 },
+	{ 0x40d3c, 0x131313 },
+	{ 0x40d40, 0x131313 },
+	{ 0x40d44, 0x141414 },
+	{ 0x40d48, 0x151515 },
+	{ 0x40d4c, 0x151515 },
+	{ 0x40d50, 0x161616 },
+	{ 0x40d54, 0x161616 },
+	{ 0x40d58, 0x171717 },
+	{ 0x40d5c, 0x171717 },
+	{ 0x40d60, 0x181818 },
+	{ 0x40d64, 0x191919 },
+	{ 0x40d68, 0x191919 },
+	{ 0x40d6c, 0x1a1a1a },
+	{ 0x40d70, 0x1b1b1b },
+	{ 0x40d74, 0x1b1b1b },
+	{ 0x40d78, 0x1c1c1c },
+	{ 0x40d7c, 0x1c1c1c },
+	{ 0x40d80, 0x1d1d1d },
+	{ 0x40d84, 0x1e1e1e },
+	{ 0x40d88, 0x1f1f1f },
+	{ 0x40d8c, 0x1f1f1f },
+	{ 0x40d90, 0x202020 },
+	{ 0x40d94, 0x212121 },
+	{ 0x40d98, 0x212121 },
+	{ 0x40d9c, 0x222222 },
+	{ 0x40da0, 0x232323 },
+	{ 0x40da4, 0x242424 },
+	{ 0x40da8, 0x242424 },
+	{ 0x40dac, 0x252525 },
+	{ 0x40db0, 0x262626 },
+	{ 0x40db4, 0x272727 },
+	{ 0x40db8, 0x272727 },
+	{ 0x40dbc, 0x282828 },
+	{ 0x40dc0, 0x292929 },
+	{ 0x40dc4, 0x2a2a2a },
+	{ 0x40dc8, 0x2b2b2b },
+	{ 0x40dcc, 0x2c2c2c },
+	{ 0x40dd0, 0x2c2c2c },
+	{ 0x40dd4, 0x2d2d2d },
+	{ 0x40dd8, 0x2e2e2e },
+	{ 0x40ddc, 0x2f2f2f },
+	{ 0x40de0, 0x303030 },
+	{ 0x40de4, 0x313131 },
+	{ 0x40de8, 0x323232 },
+	{ 0x40dec, 0x333333 },
+	{ 0x40df0, 0x333333 },
+	{ 0x40df4, 0x343434 },
+	{ 0x40df8, 0x353535 },
+	{ 0x40dfc, 0x363636 },
+	{ 0x40e00, 0x373737 },
+	{ 0x40e04, 0x383838 },
+	{ 0x40e08, 0x393939 },
+	{ 0x40e0c, 0x3a3a3a },
+	{ 0x40e10, 0x3b3b3b },
+	{ 0x40e14, 0x3c3c3c },
+	{ 0x40e18, 0x3d3d3d },
+	{ 0x40e1c, 0x3e3e3e },
+	{ 0x40e20, 0x3f3f3f },
+	{ 0x40e24, 0x404040 },
+	{ 0x40e28, 0x414141 },
+	{ 0x40e2c, 0x424242 },
+	{ 0x40e30, 0x434343 },
+	{ 0x40e34, 0x444444 },
+	{ 0x40e38, 0x464646 },
+	{ 0x40e3c, 0x474747 },
+	{ 0x40e40, 0x484848 },
+	{ 0x40e44, 0x494949 },
+	{ 0x40e48, 0x4a4a4a },
+	{ 0x40e4c, 0x4b4b4b },
+	{ 0x40e50, 0x4c4c4c },
+	{ 0x40e54, 0x4d4d4d },
+	{ 0x40e58, 0x4f4f4f },
+	{ 0x40e5c, 0x505050 },
+	{ 0x40e60, 0x515151 },
+	{ 0x40e64, 0x525252 },
+	{ 0x40e68, 0x535353 },
+	{ 0x40e6c, 0x545454 },
+	{ 0x40e70, 0x565656 },
+	{ 0x40e74, 0x575757 },
+	{ 0x40e78, 0x585858 },
+	{ 0x40e7c, 0x595959 },
+	{ 0x40e80, 0x5b5b5b },
+	{ 0x40e84, 0x5c5c5c },
+	{ 0x40e88, 0x5d5d5d },
+	{ 0x40e8c, 0x5e5e5e },
+	{ 0x40e90, 0x606060 },
+	{ 0x40e94, 0x616161 },
+	{ 0x40e98, 0x626262 },
+	{ 0x40e9c, 0x646464 },
+	{ 0x40ea0, 0x656565 },
+	{ 0x40ea4, 0x666666 },
+	{ 0x40ea8, 0x686868 },
+	{ 0x40eac, 0x696969 },
+	{ 0x40eb0, 0x6a6a6a },
+	{ 0x40eb4, 0x6c6c6c },
+	{ 0x40eb8, 0x6d6d6d },
+	{ 0x40ebc, 0x6f6f6f },
+	{ 0x40ec0, 0x707070 },
+	{ 0x40ec4, 0x717171 },
+	{ 0x40ec8, 0x737373 },
+	{ 0x40ecc, 0x747474 },
+	{ 0x40ed0, 0x767676 },
+	{ 0x40ed4, 0x777777 },
+	{ 0x40ed8, 0x797979 },
+	{ 0x40edc, 0x7a7a7a },
+	{ 0x40ee0, 0x7c7c7c },
+	{ 0x40ee4, 0x7d7d7d },
+	{ 0x40ee8, 0x7f7f7f },
+	{ 0x40eec, 0x808080 },
+	{ 0x40ef0, 0x828282 },
+	{ 0x40ef4, 0x838383 },
+	{ 0x40ef8, 0x858585 },
+	{ 0x40efc, 0x868686 },
+	{ 0x40f00, 0x888888 },
+	{ 0x40f04, 0x898989 },
+	{ 0x40f08, 0x8b8b8b },
+	{ 0x40f0c, 0x8d8d8d },
+	{ 0x40f10, 0x8e8e8e },
+	{ 0x40f14, 0x909090 },
+	{ 0x40f18, 0x919191 },
+	{ 0x40f1c, 0x939393 },
+	{ 0x40f20, 0x959595 },
+	{ 0x40f24, 0x969696 },
+	{ 0x40f28, 0x989898 },
+	{ 0x40f2c, 0x9a9a9a },
+	{ 0x40f30, 0x9b9b9b },
+	{ 0x40f34, 0x9d9d9d },
+	{ 0x40f38, 0x9f9f9f },
+	{ 0x40f3c, 0xa1a1a1 },
+	{ 0x40f40, 0xa2a2a2 },
+	{ 0x40f44, 0xa4a4a4 },
+	{ 0x40f48, 0xa6a6a6 },
+	{ 0x40f4c, 0xa7a7a7 },
+	{ 0x40f50, 0xa9a9a9 },
+	{ 0x40f54, 0xababab },
+	{ 0x40f58, 0xadadad },
+	{ 0x40f5c, 0xafafaf },
+	{ 0x40f60, 0xb0b0b0 },
+	{ 0x40f64, 0xb2b2b2 },
+	{ 0x40f68, 0xb4b4b4 },
+	{ 0x40f6c, 0xb6b6b6 },
+	{ 0x40f70, 0xb8b8b8 },
+	{ 0x40f74, 0xbababa },
+	{ 0x40f78, 0xbbbbbb },
+	{ 0x40f7c, 0xbdbdbd },
+	{ 0x40f80, 0xbfbfbf },
+	{ 0x40f84, 0xc1c1c1 },
+	{ 0x40f88, 0xc3c3c3 },
+	{ 0x40f8c, 0xc5c5c5 },
+	{ 0x40f90, 0xc7c7c7 },
+	{ 0x40f94, 0xc9c9c9 },
+	{ 0x40f98, 0xcbcbcb },
+	{ 0x40f9c, 0xcdcdcd },
+	{ 0x40fa0, 0xcfcfcf },
+	{ 0x40fa4, 0xd1d1d1 },
+	{ 0x40fa8, 0xd3d3d3 },
+	{ 0x40fac, 0xd5d5d5 },
+	{ 0x40fb0, 0xd7d7d7 },
+	{ 0x40fb4, 0xd9d9d9 },
+	{ 0x40fb8, 0xdbdbdb },
+	{ 0x40fbc, 0xdddddd },
+	{ 0x40fc0, 0xdfdfdf },
+	{ 0x40fc4, 0xe1e1e1 },
+	{ 0x40fc8, 0xe3e3e3 },
+	{ 0x40fcc, 0xe5e5e5 },
+	{ 0x40fd0, 0xe7e7e7 },
+	{ 0x40fd4, 0xe9e9e9 },
+	{ 0x40fd8, 0xebebeb },
+	{ 0x40fdc, 0xeeeeee },
+	{ 0x40fe0, 0xf0f0f0 },
+	{ 0x40fe4, 0xf2f2f2 },
+	{ 0x40fe8, 0xf4f4f4 },
+	{ 0x40fec, 0xf6f6f6 },
+	{ 0x40ff0, 0xf8f8f8 },
+	{ 0x40ff4, 0xfbfbfb },
+	{ 0x40ff8, 0xfdfdfd },
+	{ 0x40ffc, 0xffffff },
+};
diff --git a/drivers/video/msm/mdp_cursor.c b/drivers/video/msm/mdp_cursor.c
new file mode 100644
index 0000000..f8c08e3
--- /dev/null
+++ b/drivers/video/msm/mdp_cursor.c
@@ -0,0 +1,264 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+
+#include <linux/fb.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+
+static int cursor_enabled;
+
+#include "mdp4.h"
+
+#if	defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDP40)
+static struct workqueue_struct *mdp_cursor_ctrl_wq;
+static struct work_struct mdp_cursor_ctrl_worker;
+
+/* cursor configuration */
+static void *cursor_buf_phys;
+static __u32 width, height, bg_color;
+static int calpha_en, transp_en, alpha;
+static int sync_disabled = -1;
+
+void mdp_cursor_ctrl_workqueue_handler(struct work_struct *work)
+{
+	unsigned long flag;
+
+	/* disable vsync */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_disable_irq(MDP_OVERLAY0_TERM);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+void mdp_hw_cursor_init(void)
+{
+	mdp_cursor_ctrl_wq =
+			create_singlethread_workqueue("mdp_cursor_ctrl_wq");
+	INIT_WORK(&mdp_cursor_ctrl_worker, mdp_cursor_ctrl_workqueue_handler);
+}
+
+void mdp_hw_cursor_done(void)
+{
+	/* Cursor configuration:
+	 *
+	 * This is done in DMA_P_DONE ISR because the following registers are
+	 * not double buffered in hardware:
+	 *
+	 * MDP_DMA_P_CURSOR_SIZE, address = 0x90044
+	 * MDP_DMA_P_CURSOR_BLEND_CONFIG, address = 0x90060
+	 * MDP_DMA_P_CURSOR_BLEND_PARAM, address = 0x90064
+	 * MDP_DMA_P_CURSOR_BLEND_TRANS_LOW, address = 0x90068
+	 * MDP_DMA_P_CURSOR_BLEND_TRANS_HIG, address = 0x9006C
+	 *
+	 * Moving this code out of the ISR will cause the MDP to underrun!
+	 */
+	spin_lock(&mdp_spin_lock);
+	if (sync_disabled) {
+		spin_unlock(&mdp_spin_lock);
+		return;
+	}
+
+	MDP_OUTP(MDP_BASE + 0x90044, (height << 16) | width);
+	MDP_OUTP(MDP_BASE + 0x90048, cursor_buf_phys);
+
+	MDP_OUTP(MDP_BASE + 0x90060,
+		 (transp_en << 3) | (calpha_en << 1) |
+		 (inp32(MDP_BASE + 0x90060) & 0x1));
+
+	MDP_OUTP(MDP_BASE + 0x90064, (alpha << 24));
+	MDP_OUTP(MDP_BASE + 0x90068, (0xffffff & bg_color));
+	MDP_OUTP(MDP_BASE + 0x9006C, (0xffffff & bg_color));
+
+	/* enable/disable the cursor as per the last request */
+	if (cursor_enabled && !(inp32(MDP_BASE + 0x90060) & (0x1)))
+		MDP_OUTP(MDP_BASE + 0x90060, inp32(MDP_BASE + 0x90060) | 0x1);
+	else if (!cursor_enabled && (inp32(MDP_BASE + 0x90060) & (0x1)))
+		MDP_OUTP(MDP_BASE + 0x90060,
+					inp32(MDP_BASE + 0x90060) & (~0x1));
+
+	/* enqueue the task to disable MDP interrupts */
+	queue_work(mdp_cursor_ctrl_wq, &mdp_cursor_ctrl_worker);
+
+	/* update done */
+	sync_disabled = 1;
+	spin_unlock(&mdp_spin_lock);
+}
+
+static void mdp_hw_cursor_enable_vsync(void)
+{
+	/* if the cursor registers were updated (once or more) since the
+	 * last vsync, enable the vsync interrupt (if not already enabled)
+	 * for the next update
+	 */
+	if (sync_disabled) {
+
+		/* cancel pending task to disable MDP interrupts */
+		if (work_pending(&mdp_cursor_ctrl_worker))
+			cancel_work_sync(&mdp_cursor_ctrl_worker);
+		else
+			/* enable irq */
+			mdp_enable_irq(MDP_OVERLAY0_TERM);
+
+		sync_disabled = 0;
+
+		/* enable vsync intr */
+		outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	}
+}
+
+int mdp_hw_cursor_sync_update(struct fb_info *info, struct fb_cursor *cursor)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct fb_image *img = &cursor->image;
+	unsigned long flag;
+	int sync_needed = 0, ret = 0;
+
+	if ((img->width > MDP_CURSOR_WIDTH) ||
+	    (img->height > MDP_CURSOR_HEIGHT) ||
+	    (img->depth != 32))
+		return -EINVAL;
+
+	if (cursor->set & FB_CUR_SETPOS)
+		MDP_OUTP(MDP_BASE + 0x9004c, (img->dy << 16) | img->dx);
+
+	if (cursor->set & FB_CUR_SETIMAGE) {
+		ret = copy_from_user(mfd->cursor_buf, img->data,
+					img->width*img->height*4);
+		if (ret)
+			return ret;
+
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		if (img->bg_color == 0xffffffff)
+			transp_en = 0;
+		else
+			transp_en = 1;
+
+		alpha = (img->fg_color & 0xff000000) >> 24;
+
+		if (alpha)
+			calpha_en = 0x2; /* xrgb */
+		else
+			calpha_en = 0x1; /* argb */
+
+		/* cursor parameters */
+		height = img->height;
+		width = img->width;
+		bg_color = img->bg_color;
+		cursor_buf_phys = mfd->cursor_buf_phys;
+
+		sync_needed = 1;
+	} else
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+
+	if ((cursor->enable) && (!cursor_enabled)) {
+		cursor_enabled = 1;
+		sync_needed = 1;
+	} else if ((!cursor->enable) && (cursor_enabled)) {
+		cursor_enabled = 0;
+		sync_needed = 1;
+	}
+
+	/* if sync cursor update is needed, enable vsync */
+	if (sync_needed)
+		mdp_hw_cursor_enable_vsync();
+
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	return 0;
+}
+#endif /* CONFIG_FB_MSM_OVERLAY && CONFIG_FB_MSM_MDP40 */
+
+int mdp_hw_cursor_update(struct fb_info *info, struct fb_cursor *cursor)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct fb_image *img = &cursor->image;
+	int calpha_en, transp_en;
+	int alpha;
+	int ret = 0;
+
+	if ((img->width > MDP_CURSOR_WIDTH) ||
+	    (img->height > MDP_CURSOR_HEIGHT) ||
+	    (img->depth != 32))
+		return -EINVAL;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	if (cursor->set & FB_CUR_SETPOS)
+		MDP_OUTP(MDP_BASE + 0x9004c, (img->dy << 16) | img->dx);
+
+	if (cursor->set & FB_CUR_SETIMAGE) {
+		ret = copy_from_user(mfd->cursor_buf, img->data,
+					img->width*img->height*4);
+		if (ret)
+			return ret;
+
+		if (img->bg_color == 0xffffffff)
+			transp_en = 0;
+		else
+			transp_en = 1;
+
+		alpha = (img->fg_color & 0xff000000) >> 24;
+
+		if (alpha)
+			calpha_en = 0x2; /* xrgb */
+		else
+			calpha_en = 0x1; /* argb */
+
+		MDP_OUTP(MDP_BASE + 0x90044, (img->height << 16) | img->width);
+		MDP_OUTP(MDP_BASE + 0x90048, mfd->cursor_buf_phys);
+		/* order the writes the cursor_buf before updating the
+		 * hardware */
+		dma_coherent_pre_ops();
+		MDP_OUTP(MDP_BASE + 0x90060,
+			 (transp_en << 3) | (calpha_en << 1) |
+			 (inp32(MDP_BASE + 0x90060) & 0x1));
+#ifdef CONFIG_FB_MSM_MDP40
+		MDP_OUTP(MDP_BASE + 0x90064, (alpha << 24));
+		MDP_OUTP(MDP_BASE + 0x90068, (0xffffff & img->bg_color));
+		MDP_OUTP(MDP_BASE + 0x9006C, (0xffffff & img->bg_color));
+#else
+		MDP_OUTP(MDP_BASE + 0x90064,
+			 (alpha << 24) | (0xffffff & img->bg_color));
+		MDP_OUTP(MDP_BASE + 0x90068, 0);
+#endif
+	}
+
+	if ((cursor->enable) && (!cursor_enabled)) {
+		cursor_enabled = 1;
+		MDP_OUTP(MDP_BASE + 0x90060, inp32(MDP_BASE + 0x90060) | 0x1);
+	} else if ((!cursor->enable) && (cursor_enabled)) {
+		cursor_enabled = 0;
+		MDP_OUTP(MDP_BASE + 0x90060,
+			 inp32(MDP_BASE + 0x90060) & (~0x1));
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return 0;
+}
diff --git a/drivers/video/msm/mdp_debugfs.c b/drivers/video/msm/mdp_debugfs.c
new file mode 100644
index 0000000..0fad0a7
--- /dev/null
+++ b/drivers/video/msm/mdp_debugfs.c
@@ -0,0 +1,1423 @@
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/hrtimer.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#ifdef CONFIG_FB_MSM_MDP40
+#include "mdp4.h"
+#endif
+#include "mddihosti.h"
+#include "tvenc.h"
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+#include "hdmi_msm.h"
+#endif
+
+#define MDP_DEBUG_BUF	2048
+
+static uint32	mdp_offset;
+static uint32	mdp_count;
+
+static char	debug_buf[MDP_DEBUG_BUF];
+
+/*
+ * MDP4
+ *
+ */
+
+static int mdp_offset_open(struct inode *inode, struct file *file)
+{
+	/* non-seekable */
+	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+	return 0;
+}
+
+static int mdp_offset_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static ssize_t mdp_offset_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 off, cnt;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	sscanf(debug_buf, "%x %d", &off, &cnt);
+
+	if (cnt <= 0)
+		cnt = 1;
+
+	mdp_offset = off;
+	mdp_count = cnt;
+
+	printk(KERN_INFO "%s: offset=%x cnt=%d\n", __func__,
+				mdp_offset, mdp_count);
+
+	return count;
+}
+
+static ssize_t mdp_offset_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int len = 0;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	len = snprintf(debug_buf, sizeof(debug_buf), "0x%08x %d\n",
+					mdp_offset, mdp_count);
+	if (len < 0)
+		return 0;
+
+	if (copy_to_user(buff, debug_buf, len))
+		return -EFAULT;
+
+	*ppos += len;	/* increase offset */
+
+	return len;
+}
+
+static const struct file_operations mdp_off_fops = {
+	.open = mdp_offset_open,
+	.release = mdp_offset_release,
+	.read = mdp_offset_read,
+	.write = mdp_offset_write,
+};
+
+static int mdp_reg_open(struct inode *inode, struct file *file)
+{
+	/* non-seekable */
+	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+	return 0;
+}
+
+static int mdp_reg_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static ssize_t mdp_reg_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 off, data;
+	int cnt;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	cnt = sscanf(debug_buf, "%x %x", &off, &data);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	outpdw(MDP_BASE + off, data);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	printk(KERN_INFO "%s: addr=%x data=%x\n", __func__, off, data);
+
+	return count;
+}
+
+static ssize_t mdp_reg_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int len = 0;
+	uint32 data;
+	int i, j, off, dlen, num;
+	char *bp, *cp;
+	int tot = 0;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	j = 0;
+	num = 0;
+	bp = debug_buf;
+	cp = MDP_BASE + mdp_offset;
+	dlen = sizeof(debug_buf);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	while (j++ < 8) {
+		len = snprintf(bp, dlen, "0x%08x: ", (int)cp);
+		tot += len;
+		bp += len;
+		dlen -= len;
+		off = 0;
+		i = 0;
+		while (i++ < 4) {
+			data = inpdw(cp + off);
+			len = snprintf(bp, dlen, "%08x ", data);
+			tot += len;
+			bp += len;
+			dlen -= len;
+			off += 4;
+			num++;
+			if (num >= mdp_count)
+				break;
+		}
+		*bp++ = '\n';
+		--dlen;
+		tot++;
+		cp += off;
+		if (num >= mdp_count)
+			break;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	*bp = 0;
+	tot++;
+
+	if (copy_to_user(buff, debug_buf, tot))
+		return -EFAULT;
+
+	*ppos += tot;	/* increase offset */
+
+	return tot;
+}
+
+
+static const struct file_operations mdp_reg_fops = {
+	.open = mdp_reg_open,
+	.release = mdp_reg_release,
+	.read = mdp_reg_read,
+	.write = mdp_reg_write,
+};
+
+#ifdef CONFIG_FB_MSM_MDP40
+static int mdp_stat_open(struct inode *inode, struct file *file)
+{
+	/* non-seekable */
+	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+	return 0;
+}
+
+static int mdp_stat_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static ssize_t mdp_stat_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	unsigned long flag;
+
+	if (count > sizeof(debug_buf))
+		return -EFAULT;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	memset((char *)&mdp4_stat, 0 , sizeof(mdp4_stat));	/* reset */
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	return count;
+}
+
+static ssize_t mdp_stat_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int len = 0;
+	int tot = 0;
+	int dlen;
+	char *bp;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	bp = debug_buf;
+	dlen = sizeof(debug_buf);
+
+	len = snprintf(bp, dlen, "\nmdp:\n");
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "int_total: %08lu\t",
+					mdp4_stat.intr_tot);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "int_overlay0: %08lu\t",
+					mdp4_stat.intr_overlay0);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "int_overlay1: %08lu\n",
+					mdp4_stat.intr_overlay1);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "int_overlay1: %08lu\n",
+					mdp4_stat.intr_overlay2);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "int_dmap: %08lu\t",
+					mdp4_stat.intr_dma_p);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "int_dmas: %08lu\t",
+					mdp4_stat.intr_dma_s);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "int_dmae:  %08lu\n",
+					mdp4_stat.intr_dma_e);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "primary:   vsync: %08lu\t",
+					mdp4_stat.intr_vsync_p);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "underrun: %08lu\n",
+					mdp4_stat.intr_underrun_p);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "external:  vsync: %08lu\t",
+					mdp4_stat.intr_vsync_e);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "underrun: %08lu\n",
+					mdp4_stat.intr_underrun_e);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "histogram: %08lu\t",
+					mdp4_stat.intr_histogram);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "read_ptr: %08lu\n\n",
+					mdp4_stat.intr_rdptr);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "dsi:\n");
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "int_total: %08lu\tmdp_start: %08lu\n",
+			mdp4_stat.intr_dsi, mdp4_stat.dsi_mdp_start);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "int_cmd: %08lu\t",
+					mdp4_stat.intr_dsi_cmd);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "int_mdp: %08lu\t",
+					mdp4_stat.intr_dsi_mdp);
+
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "int_err: %08lu\n",
+					mdp4_stat.intr_dsi_err);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "clk_on : %08lu\t",
+					mdp4_stat.dsi_clk_on);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "clk_off: %08lu\n\n",
+					mdp4_stat.dsi_clk_off);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "kickoff:\n");
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "overlay0: %08lu\t",
+					mdp4_stat.kickoff_ov0);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "dmap: %08lu\t",
+					mdp4_stat.kickoff_dmap);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "dmas: %08lu\n",
+					mdp4_stat.kickoff_dmas);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "overlay1: %08lu\t",
+					mdp4_stat.kickoff_ov1);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "dmae: %08lu\n\n",
+					mdp4_stat.kickoff_dmae);
+
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "overlay0_play:\n");
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "set:   %08lu\t",
+					mdp4_stat.overlay_set[0]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "unset: %08lu\t",
+					mdp4_stat.overlay_unset[0]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "play:  %08lu\t",
+					mdp4_stat.overlay_play[0]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "commit:  %08lu\n",
+					mdp4_stat.overlay_commit[0]);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "overlay1_play:\n");
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "set:   %08lu\t",
+					mdp4_stat.overlay_set[1]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "unset: %08lu\t",
+					mdp4_stat.overlay_unset[1]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "play:  %08lu\t",
+					mdp4_stat.overlay_play[1]);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "commit:  %08lu\n\n",
+					mdp4_stat.overlay_commit[1]);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "frame_push:\n");
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "vg1 :   %08lu\t", mdp4_stat.pipe[0]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "vg2 :   %08lu\t", mdp4_stat.pipe[1]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "vg3 :   %08lu\n", mdp4_stat.pipe[5]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "rgb1:   %08lu\t", mdp4_stat.pipe[2]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "rgb2:   %08lu\t", mdp4_stat.pipe[3]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "rgb3:   %08lu\n\n", mdp4_stat.pipe[4]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "wait4vsync: ");
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "mixer0 : %08lu\t", mdp4_stat.wait4vsync0);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "mixer1: %08lu\n\n", mdp4_stat.wait4vsync1);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "iommu: ");
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "map : %08lu\t", mdp4_stat.iommu_map);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "unmap: %08lu\t", mdp4_stat.iommu_unmap);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "drop: %08lu\n\n", mdp4_stat.iommu_drop);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_mixer : %08lu\t", mdp4_stat.err_mixer);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_size  : %08lu\n", mdp4_stat.err_size);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_scale : %08lu\t", mdp4_stat.err_scale);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_format: %08lu\n", mdp4_stat.err_format);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_play  : %08lu\t", mdp4_stat.err_play);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_stage : %08lu\n", mdp4_stat.err_stage);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_underflow: %08lu\n\n",
+		       mdp4_stat.err_underflow);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "writeback:\n");
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "dsi_cmd: %08lu\t",
+					mdp4_stat.blt_dsi_cmd);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "dsi_video: %08lu\n",
+					mdp4_stat.blt_dsi_video);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "lcdc: %08lu\t",
+					mdp4_stat.blt_lcdc);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "dtv: %08lu\t",
+					mdp4_stat.blt_dtv);
+	bp += len;
+	dlen -= len;
+
+	len = snprintf(bp, dlen, "mddi: %08lu\n\n",
+					mdp4_stat.blt_mddi);
+	bp += len;
+	dlen -= len;
+
+	tot = (uint32)bp - (uint32)debug_buf;
+	*bp = 0;
+	tot++;
+
+	if (tot < 0)
+		return 0;
+	if (copy_to_user(buff, debug_buf, tot))
+		return -EFAULT;
+
+	*ppos += tot;	/* increase offset */
+
+	return tot;
+}
+
+static const struct file_operations mdp_stat_fops = {
+	.open = mdp_stat_open,
+	.release = mdp_stat_release,
+	.read = mdp_stat_read,
+	.write = mdp_stat_write,
+};
+#endif
+
+/*
+ * MDDI
+ *
+ */
+
+struct mddi_reg {
+	char *name;
+	int off;
+};
+
+static struct mddi_reg mddi_regs_list[] = {
+	{"MDDI_CMD", MDDI_CMD},	 	/* 0x0000 */
+	{"MDDI_VERSION", MDDI_VERSION},  /* 0x0004 */
+	{"MDDI_PRI_PTR", MDDI_PRI_PTR},  /* 0x0008 */
+	{"MDDI_BPS",  MDDI_BPS}, 	/* 0x0010 */
+	{"MDDI_SPM", MDDI_SPM}, 	/* 0x0014 */
+	{"MDDI_INT", MDDI_INT}, 	/* 0x0018 */
+	{"MDDI_INTEN", MDDI_INTEN},	/* 0x001c */
+	{"MDDI_REV_PTR", MDDI_REV_PTR},	/* 0x0020 */
+	{"MDDI_	REV_SIZE", MDDI_REV_SIZE},/* 0x0024 */
+	{"MDDI_STAT", MDDI_STAT},	/* 0x0028 */
+	{"MDDI_REV_RATE_DIV", MDDI_REV_RATE_DIV}, /* 0x002c */
+	{"MDDI_REV_CRC_ERR", MDDI_REV_CRC_ERR}, /* 0x0030 */
+	{"MDDI_TA1_LEN", MDDI_TA1_LEN}, /* 0x0034 */
+	{"MDDI_TA2_LEN", MDDI_TA2_LEN}, /* 0x0038 */
+	{"MDDI_TEST", MDDI_TEST}, 	/* 0x0040 */
+	{"MDDI_REV_PKT_CNT", MDDI_REV_PKT_CNT}, /* 0x0044 */
+	{"MDDI_DRIVE_HI", MDDI_DRIVE_HI},/* 0x0048 */
+	{"MDDI_DRIVE_LO", MDDI_DRIVE_LO},	/* 0x004c */
+	{"MDDI_DISP_WAKE", MDDI_DISP_WAKE},/* 0x0050 */
+	{"MDDI_REV_ENCAP_SZ", MDDI_REV_ENCAP_SZ}, /* 0x0054 */
+	{"MDDI_RTD_VAL", MDDI_RTD_VAL}, /* 0x0058 */
+	{"MDDI_PAD_CTL", MDDI_PAD_CTL},	 /* 0x0068 */
+	{"MDDI_DRIVER_START_CNT", MDDI_DRIVER_START_CNT}, /* 0x006c */
+	{"MDDI_CORE_VER", MDDI_CORE_VER}, /* 0x008c */
+	{"MDDI_FIFO_ALLOC", MDDI_FIFO_ALLOC}, /* 0x0090 */
+	{"MDDI_PAD_IO_CTL", MDDI_PAD_IO_CTL}, /* 0x00a0 */
+	{"MDDI_PAD_CAL", MDDI_PAD_CAL},  /* 0x00a4 */
+	{0, 0}
+};
+
+static int mddi_reg_open(struct inode *inode, struct file *file)
+{
+	/* non-seekable */
+	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+	return 0;
+}
+
+static int mddi_reg_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static void mddi_reg_write(int ndx, uint32 off, uint32 data)
+{
+	char *base;
+
+	if (ndx)
+		base = (char *)msm_emdh_base;
+	else
+		base = (char *)msm_pmdh_base;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	writel(data, base + off);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	printk(KERN_INFO "%s: addr=%x data=%x\n",
+			__func__, (int)(base+off), (int)data);
+}
+
+static int mddi_reg_read(int ndx)
+{
+	struct mddi_reg *reg;
+	unsigned char *base;
+	int data;
+	char *bp;
+	int len = 0;
+	int tot = 0;
+	int dlen;
+
+	if (ndx)
+		base = msm_emdh_base;
+	else
+		base = msm_pmdh_base;
+
+	reg = mddi_regs_list;
+	bp = debug_buf;
+	dlen = sizeof(debug_buf);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	while (reg->name) {
+		data = readl((u32)base + reg->off);
+		len = snprintf(bp, dlen, "%s:0x%08x\t\t= 0x%08x\n",
+					reg->name, reg->off, data);
+		tot += len;
+		bp += len;
+		dlen -= len;
+		reg++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	*bp = 0;
+	tot++;
+
+	return tot;
+}
+
+static ssize_t pmdh_reg_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 off, data;
+	int cnt;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	cnt = sscanf(debug_buf, "%x %x", &off, &data);
+
+	mddi_reg_write(0, off, data);
+
+	return count;
+}
+
+static ssize_t pmdh_reg_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int tot = 0;
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	tot = mddi_reg_read(0);	/* pmdh */
+
+	if (tot < 0)
+		return 0;
+	if (copy_to_user(buff, debug_buf, tot))
+		return -EFAULT;
+
+	*ppos += tot;	/* increase offset */
+
+	return tot;
+}
+
+
+static const struct file_operations pmdh_fops = {
+	.open = mddi_reg_open,
+	.release = mddi_reg_release,
+	.read = pmdh_reg_read,
+	.write = pmdh_reg_write,
+};
+
+
+
+#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDDI)
+static int vsync_reg_open(struct inode *inode, struct file *file)
+{
+	/* non-seekable */
+	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+	return 0;
+}
+
+static int vsync_reg_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static ssize_t vsync_reg_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 enable;
+	int cnt;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	cnt = sscanf(debug_buf, "%x", &enable);
+
+	mdp_dmap_vsync_set(enable);
+
+	return count;
+}
+
+static ssize_t vsync_reg_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	char *bp;
+	int len = 0;
+	int tot = 0;
+	int dlen;
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	bp = debug_buf;
+	dlen = sizeof(debug_buf);
+	len = snprintf(bp, dlen, "%x\n", mdp_dmap_vsync_get());
+	tot += len;
+	bp += len;
+	*bp = 0;
+	tot++;
+
+	if (copy_to_user(buff, debug_buf, tot))
+		return -EFAULT;
+
+	*ppos += tot;	/* increase offset */
+
+	return tot;
+}
+
+
+static const struct file_operations vsync_fops = {
+	.open = vsync_reg_open,
+	.release = vsync_reg_release,
+	.read = vsync_reg_read,
+	.write = vsync_reg_write,
+};
+#endif
+
+static ssize_t emdh_reg_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 off, data;
+	int cnt;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	cnt = sscanf(debug_buf, "%x %x", &off, &data);
+
+	mddi_reg_write(1, off, data);
+
+	return count;
+}
+
+static ssize_t emdh_reg_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int tot = 0;
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	tot = mddi_reg_read(1);	/* emdh */
+
+	if (tot < 0)
+		return 0;
+	if (copy_to_user(buff, debug_buf, tot))
+		return -EFAULT;
+
+	*ppos += tot;	/* increase offset */
+
+	return tot;
+}
+
+static const struct file_operations emdh_fops = {
+	.open = mddi_reg_open,
+	.release = mddi_reg_release,
+	.read = emdh_reg_read,
+	.write = emdh_reg_write,
+};
+
+
+uint32 dbg_offset;
+uint32 dbg_count;
+char *dbg_base;
+
+
+static int dbg_open(struct inode *inode, struct file *file)
+{
+	/* non-seekable */
+	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+	return 0;
+}
+
+static int dbg_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static ssize_t dbg_base_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	return count;
+}
+
+static ssize_t dbg_base_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int len = 0;
+	int tot = 0;
+	int dlen;
+	char *bp;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+
+	bp = debug_buf;
+	dlen = sizeof(debug_buf);
+
+	len = snprintf(bp, dlen, "mdp_base  :    %08x\n",
+				(int)msm_mdp_base);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "mddi_base :    %08x\n",
+				(int)msm_pmdh_base);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "emdh_base :    %08x\n",
+				(int)msm_emdh_base);
+	bp += len;
+	dlen -= len;
+#ifdef CONFIG_FB_MSM_TVOUT
+	len = snprintf(bp, dlen, "tvenv_base:    %08x\n",
+				(int)tvenc_base);
+	bp += len;
+	dlen -= len;
+#endif
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+	len = snprintf(bp, dlen, "mipi_dsi_base: %08x\n",
+				(int)mipi_dsi_base);
+	bp += len;
+	dlen -= len;
+#endif
+
+	tot = (uint32)bp - (uint32)debug_buf;
+	*bp = 0;
+	tot++;
+
+	if (tot < 0)
+		return 0;
+	if (copy_to_user(buff, debug_buf, tot))
+		return -EFAULT;
+
+	*ppos += tot;	/* increase offset */
+
+	return tot;
+}
+
+static const struct file_operations dbg_base_fops = {
+	.open = dbg_open,
+	.release = dbg_release,
+	.read = dbg_base_read,
+	.write = dbg_base_write,
+};
+
+static ssize_t dbg_offset_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 off, cnt, num, base;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	cnt = sscanf(debug_buf, "%x %d %x", &off, &num, &base);
+
+	if (cnt < 0)
+		cnt = 0;
+
+	if (cnt >= 1)
+		dbg_offset = off;
+	if (cnt >= 2)
+		dbg_count = num;
+	if (cnt >= 3)
+		dbg_base = (char *)base;
+
+	printk(KERN_INFO "%s: offset=%x cnt=%d base=%x\n", __func__,
+				dbg_offset, dbg_count, (int)dbg_base);
+
+	return count;
+}
+
+static ssize_t dbg_offset_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int len = 0;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	len = snprintf(debug_buf, sizeof(debug_buf), "0x%08x %d 0x%08x\n",
+				dbg_offset, dbg_count, (int)dbg_base);
+	if (len < 0)
+		return 0;
+
+	if (copy_to_user(buff, debug_buf, len))
+		return -EFAULT;
+
+	*ppos += len;	/* increase offset */
+
+	return len;
+}
+
+static const struct file_operations dbg_off_fops = {
+	.open = dbg_open,
+	.release = dbg_release,
+	.read = dbg_offset_read,
+	.write = dbg_offset_write,
+};
+
+
+static ssize_t dbg_reg_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 off, data;
+	int cnt;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	cnt = sscanf(debug_buf, "%x %x", &off, &data);
+
+	writel(data, dbg_base + off);
+
+	printk(KERN_INFO "%s: addr=%x data=%x\n",
+			__func__, (int)(dbg_base+off), (int)data);
+
+	return count;
+}
+
+static ssize_t dbg_reg_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int len = 0;
+	uint32 data;
+	int i, j, off, dlen, num;
+	char *bp, *cp;
+	int tot = 0;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	if (dbg_base == 0)
+		return 0;	/* nothing to read */
+
+	j = 0;
+	num = 0;
+	bp = debug_buf;
+	cp = (char *)(dbg_base + dbg_offset);
+	dlen = sizeof(debug_buf);
+	while (j++ < 16) {
+		len = snprintf(bp, dlen, "0x%08x: ", (int)cp);
+		tot += len;
+		bp += len;
+		dlen -= len;
+		off = 0;
+		i = 0;
+		while (i++ < 4) {
+			data = readl(cp + off);
+			len = snprintf(bp, dlen, "%08x ", data);
+			tot += len;
+			bp += len;
+			dlen -= len;
+			off += 4;
+			num++;
+			if (num >= dbg_count)
+				break;
+		}
+		data = readl((u32)cp + off);
+		*bp++ = '\n';
+		--dlen;
+		tot++;
+		cp += off;
+		if (num >= dbg_count)
+			break;
+	}
+	*bp = 0;
+	tot++;
+
+	if (copy_to_user(buff, debug_buf, tot))
+		return -EFAULT;
+
+	*ppos += tot;	/* increase offset */
+
+	return tot;
+}
+
+
+static const struct file_operations dbg_reg_fops = {
+	.open = dbg_open,
+	.release = dbg_release,
+	.read = dbg_reg_read,
+	.write = dbg_reg_write,
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static uint32 hdmi_offset;
+static uint32 hdmi_count;
+
+static int hdmi_open(struct inode *inode, struct file *file)
+{
+	/* non-seekable */
+	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+	return 0;
+}
+
+static int hdmi_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static ssize_t hdmi_offset_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 off, cnt, num;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	cnt = sscanf(debug_buf, "%x %d", &off, &num);
+
+	if (cnt < 0)
+		cnt = 0;
+
+	if (cnt >= 1)
+		hdmi_offset = off;
+	if (cnt >= 2)
+		hdmi_count = num;
+
+	printk(KERN_INFO "%s: offset=%x cnt=%d\n", __func__,
+				hdmi_offset, hdmi_count);
+
+	return count;
+}
+
+static ssize_t hdmi_offset_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int len = 0;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	len = snprintf(debug_buf, sizeof(debug_buf), "0x%08x %d\n",
+				hdmi_offset, hdmi_count);
+	if (len < 0)
+		return 0;
+
+	if (copy_to_user(buff, debug_buf, len))
+		return -EFAULT;
+
+	*ppos += len;	/* increase offset */
+
+	return len;
+}
+
+static const struct file_operations hdmi_off_fops = {
+	.open = hdmi_open,
+	.release = hdmi_release,
+	.read = hdmi_offset_read,
+	.write = hdmi_offset_write,
+};
+
+
+static ssize_t hdmi_reg_write(
+	struct file *file,
+	const char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	uint32 off, data, base;
+	int cnt;
+
+	if (count >= sizeof(debug_buf))
+		return -EFAULT;
+
+	if (copy_from_user(debug_buf, buff, count))
+		return -EFAULT;
+
+	base = hdmi_msm_get_io_base();
+	if (base == 0)
+		return -EFAULT;
+
+	debug_buf[count] = 0;	/* end of string */
+
+	cnt = sscanf(debug_buf, "%x %x", &off, &data);
+
+	writel(data, base + off);
+
+	printk(KERN_INFO "%s: addr=%x data=%x\n",
+			__func__, (int)(base+off), (int)data);
+
+	return count;
+}
+
+static ssize_t hdmi_reg_read(
+	struct file *file,
+	char __user *buff,
+	size_t count,
+	loff_t *ppos)
+{
+	int len = 0;
+	uint32 data;
+	int i, j, off, dlen, num;
+	char *bp, *cp;
+	int tot = 0;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	if (hdmi_msm_get_io_base() == 0)
+		return 0;	/* nothing to read */
+
+	j = 0;
+	num = 0;
+	bp = debug_buf;
+	cp = (char *)(hdmi_msm_get_io_base() + hdmi_offset);
+	dlen = sizeof(debug_buf);
+	while (j++ < 16) {
+		len = snprintf(bp, dlen, "0x%08x: ", (int)cp);
+		tot += len;
+		bp += len;
+		dlen -= len;
+		off = 0;
+		i = 0;
+		while (i++ < 4) {
+			data = readl(cp + off);
+			len = snprintf(bp, dlen, "%08x ", data);
+			tot += len;
+			bp += len;
+			dlen -= len;
+			off += 4;
+			num++;
+			if (num >= hdmi_count)
+				break;
+		}
+		data = readl((u32)cp + off);
+		*bp++ = '\n';
+		--dlen;
+		tot++;
+		cp += off;
+		if (num >= hdmi_count)
+			break;
+	}
+	*bp = 0;
+	tot++;
+
+	if (copy_to_user(buff, debug_buf, tot))
+		return -EFAULT;
+
+	*ppos += tot;	/* increase offset */
+
+	return tot;
+}
+
+
+static const struct file_operations hdmi_reg_fops = {
+	.open = hdmi_open,
+	.release = hdmi_release,
+	.read = hdmi_reg_read,
+	.write = hdmi_reg_write,
+};
+#endif
+
+/*
+ * debugfs
+ *
+ */
+
+int mdp_debugfs_init(void)
+{
+	struct dentry *dent = debugfs_create_dir("mdp", NULL);
+
+	if (IS_ERR(dent)) {
+		printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
+			__FILE__, __LINE__, PTR_ERR(dent));
+		return -1;
+	}
+
+	if (debugfs_create_file("off", 0644, dent, 0, &mdp_off_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+	if (debugfs_create_file("reg", 0644, dent, 0, &mdp_reg_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+#ifdef CONFIG_FB_MSM_MDP40
+	if (debugfs_create_file("stat", 0644, dent, 0, &mdp_stat_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+#endif
+
+	dent = debugfs_create_dir("mddi", NULL);
+
+	if (IS_ERR(dent)) {
+		printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
+			__FILE__, __LINE__, PTR_ERR(dent));
+		return -1;
+	}
+
+	if (debugfs_create_file("reg", 0644, dent, 0, &pmdh_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDDI)
+	if (debugfs_create_file("vsync", 0644, dent, 0, &vsync_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+#endif
+
+	dent = debugfs_create_dir("emdh", NULL);
+
+	if (IS_ERR(dent)) {
+		printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
+			__FILE__, __LINE__, PTR_ERR(dent));
+		return -1;
+	}
+
+	if (debugfs_create_file("reg", 0644, dent, 0, &emdh_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+	dent = debugfs_create_dir("mdp-dbg", NULL);
+
+	if (IS_ERR(dent)) {
+		printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
+			__FILE__, __LINE__, PTR_ERR(dent));
+		return -1;
+	}
+
+	if (debugfs_create_file("base", 0644, dent, 0, &dbg_base_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+	if (debugfs_create_file("off", 0644, dent, 0, &dbg_off_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+	if (debugfs_create_file("reg", 0644, dent, 0, &dbg_reg_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
+			__FILE__, __LINE__);
+		return -1;
+	}
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+	dent = debugfs_create_dir("hdmi", NULL);
+
+	if (IS_ERR(dent)) {
+		printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
+			__FILE__, __LINE__, PTR_ERR(dent));
+		return PTR_ERR(dent);
+	}
+
+	if (debugfs_create_file("off", 0644, dent, 0, &hdmi_off_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: 'off' fail\n",
+			__FILE__, __LINE__);
+		return -ENOENT;
+	}
+
+	if (debugfs_create_file("reg", 0644, dent, 0, &hdmi_reg_fops)
+			== NULL) {
+		printk(KERN_ERR "%s(%d): debugfs_create_file: 'reg' fail\n",
+			__FILE__, __LINE__);
+		return -ENOENT;
+	}
+#endif
+
+	return 0;
+}
diff --git a/drivers/video/msm/mdp_dma.c b/drivers/video/msm/mdp_dma.c
new file mode 100644
index 0000000..da9761e
--- /dev/null
+++ b/drivers/video/msm/mdp_dma.c
@@ -0,0 +1,627 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+
+#include <linux/fb.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mddihost.h"
+
+static uint32 mdp_last_dma2_update_width;
+static uint32 mdp_last_dma2_update_height;
+static uint32 mdp_curr_dma2_update_width;
+static uint32 mdp_curr_dma2_update_height;
+
+ktime_t mdp_dma2_last_update_time = { 0 };
+
+int mdp_lcd_rd_cnt_offset_slow = 20;
+int mdp_lcd_rd_cnt_offset_fast = 20;
+int mdp_vsync_usec_wait_line_too_short = 5;
+uint32 mdp_dma2_update_time_in_usec;
+uint32 mdp_total_vdopkts;
+
+extern u32 msm_fb_debug_enabled;
+extern struct workqueue_struct *mdp_dma_wq;
+
+int vsync_start_y_adjust = 4;
+
+static void mdp_dma2_update_lcd(struct msm_fb_data_type *mfd)
+{
+	MDPIBUF *iBuf = &mfd->ibuf;
+	int mddi_dest = FALSE;
+	int cmd_mode = FALSE;
+	uint32 outBpp = iBuf->bpp;
+	uint32 dma2_cfg_reg;
+	uint8 *src;
+	uint32 mddi_ld_param;
+	uint16 mddi_vdo_packet_reg;
+#ifndef CONFIG_FB_MSM_MDP303
+	struct msm_fb_panel_data *pdata =
+	    (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+#endif
+	uint32 ystride = mfd->fbi->fix.line_length;
+	uint32 mddi_pkt_desc;
+
+	dma2_cfg_reg = DMA_PACK_ALIGN_LSB |
+		    DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS;
+
+#ifdef CONFIG_FB_MSM_MDP22
+	dma2_cfg_reg |= DMA_PACK_TIGHT;
+#endif
+
+#ifdef CONFIG_FB_MSM_MDP30
+	/*
+	 * Software workaround:  On 7x25/7x27, the MDP will not
+	 * respond if dma_w is 1 pixel.  Set the update width to
+	 * 2 pixels and adjust the x offset if needed.
+	 */
+	if (iBuf->dma_w == 1) {
+		iBuf->dma_w = 2;
+		if (iBuf->dma_x == (iBuf->ibuf_width - 2))
+			iBuf->dma_x--;
+	}
+#endif
+
+	if (mfd->fb_imgType == MDP_BGR_565)
+		dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else if (mfd->fb_imgType == MDP_RGBA_8888)
+		dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else
+		dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
+
+	if (outBpp == 4) {
+		dma2_cfg_reg |= DMA_IBUF_C3ALPHA_EN;
+		dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888;
+	}
+
+	if (outBpp == 2)
+		dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
+
+	mddi_ld_param = 0;
+	mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
+
+	if ((mfd->panel_info.type == MDDI_PANEL) ||
+	    (mfd->panel_info.type == EXT_MDDI_PANEL)) {
+		dma2_cfg_reg |= DMA_OUT_SEL_MDDI;
+		mddi_dest = TRUE;
+
+		if (mfd->panel_info.type == MDDI_PANEL) {
+			mdp_total_vdopkts++;
+			if (mfd->panel_info.pdest == DISPLAY_1) {
+				dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
+				mddi_ld_param = 0;
+#ifdef MDDI_HOST_WINDOW_WORKAROUND
+				mddi_window_adjust(mfd, iBuf->dma_x,
+						   iBuf->dma_w - 1, iBuf->dma_y,
+						   iBuf->dma_h - 1);
+#endif
+			} else {
+				dma2_cfg_reg |=
+				    DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY;
+				mddi_ld_param = 1;
+#ifdef MDDI_HOST_WINDOW_WORKAROUND
+				mddi_window_adjust(mfd, iBuf->dma_x,
+						   iBuf->dma_w - 1, iBuf->dma_y,
+						   iBuf->dma_h - 1);
+#endif
+			}
+		} else {
+			dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL;
+			mddi_ld_param = 2;
+		}
+#ifdef CONFIG_FB_MSM_MDP303
+	} else if (mfd->panel_info.type == MIPI_CMD_PANEL) {
+		cmd_mode = TRUE;
+		dma2_cfg_reg |= DMA_OUT_SEL_DSI_CMD;
+#endif
+	} else {
+		if (mfd->panel_info.pdest == DISPLAY_1) {
+			dma2_cfg_reg |= DMA_AHBM_LCD_SEL_PRIMARY;
+			outp32(MDP_EBI2_LCD0, mfd->data_port_phys);
+		} else {
+			dma2_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY;
+			outp32(MDP_EBI2_LCD1, mfd->data_port_phys);
+		}
+	}
+
+	src = (uint8 *) iBuf->buf;
+	/* starting input address */
+	src += iBuf->dma_x * outBpp + iBuf->dma_y * ystride;
+
+	mdp_curr_dma2_update_width = iBuf->dma_w;
+	mdp_curr_dma2_update_height = iBuf->dma_h;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+#ifdef CONFIG_FB_MSM_MDP22
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0184,
+			(iBuf->dma_h << 16 | iBuf->dma_w));
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0188, src);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x018C, ystride);
+#else
+	if (cmd_mode)
+		MDP_OUTP(MDP_BASE + 0x90004,
+			(mfd->panel_info.yres << 16 | mfd->panel_info.xres));
+	else
+		MDP_OUTP(MDP_BASE + 0x90004, (iBuf->dma_h << 16 | iBuf->dma_w));
+
+	MDP_OUTP(MDP_BASE + 0x90008, src);
+	MDP_OUTP(MDP_BASE + 0x9000c, ystride);
+#endif
+
+	if (mfd->panel_info.bpp == 18) {
+		mddi_pkt_desc = MDDI_VDO_PACKET_DESC;
+		dma2_cfg_reg |= DMA_DSTC0G_6BITS |	/* 666 18BPP */
+		    DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+	} else if (mfd->panel_info.bpp == 24) {
+		mddi_pkt_desc = MDDI_VDO_PACKET_DESC_24;
+		dma2_cfg_reg |= DMA_DSTC0G_8BITS |      /* 888 24BPP */
+			DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
+	} else {
+		mddi_pkt_desc = MDDI_VDO_PACKET_DESC_16;
+		dma2_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
+		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
+	}
+
+#ifndef CONFIG_FB_MSM_MDP303
+
+	if (mddi_dest) {
+#ifdef CONFIG_FB_MSM_MDP22
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0194,
+			 (iBuf->dma_y << 16) | iBuf->dma_x);
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0, mddi_ld_param);
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4,
+			 (mddi_pkt_desc << 16) | mddi_vdo_packet_reg);
+#else
+		MDP_OUTP(MDP_BASE + 0x90010, (iBuf->dma_y << 16) | iBuf->dma_x);
+		MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param);
+		MDP_OUTP(MDP_BASE + 0x00094,
+			 (mddi_pkt_desc << 16) | mddi_vdo_packet_reg);
+#endif
+	} else {
+		/* setting EBI2 LCDC write window */
+		pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
+				iBuf->dma_h);
+	}
+#else
+	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
+		/* dma_p = 0, dma_s = 1 */
+		 MDP_OUTP(MDP_BASE + 0xF1000, 0x10);
+		 /* enable dsi trigger on dma_p */
+		 MDP_OUTP(MDP_BASE + 0xF1004, 0x01);
+	}
+#endif
+
+	/* dma2 config register */
+#ifdef MDP_HW_VSYNC
+	MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
+
+	if ((mfd->use_mdp_vsync) &&
+	    (mfd->ibuf.vsync_enable) && (mfd->panel_info.lcd.vsync_enable)) {
+		uint32 start_y;
+
+		if (vsync_start_y_adjust <= iBuf->dma_y)
+			start_y = iBuf->dma_y - vsync_start_y_adjust;
+		else
+			start_y =
+			    (mfd->total_lcd_lines - 1) - (vsync_start_y_adjust -
+							  iBuf->dma_y);
+
+		/*
+		 * MDP VSYNC clock must be On by now so, we don't have to
+		 * re-enable it
+		 */
+		MDP_OUTP(MDP_BASE + 0x210, start_y);
+		MDP_OUTP(MDP_BASE + 0x20c, 1);	/* enable prim vsync */
+	} else {
+		MDP_OUTP(MDP_BASE + 0x20c, 0);	/* disable prim vsync */
+	}
+#else
+#ifdef CONFIG_FB_MSM_MDP22
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0180, dma2_cfg_reg);
+#else
+	MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
+#endif
+#endif /* MDP_HW_VSYNC */
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+static ktime_t vt = { 0 };
+int mdp_usec_diff_threshold = 100;
+int mdp_expected_usec_wait;
+
+enum hrtimer_restart mdp_dma2_vsync_hrtimer_handler(struct hrtimer *ht)
+{
+	struct msm_fb_data_type *mfd = NULL;
+
+	mfd = container_of(ht, struct msm_fb_data_type, dma_hrtimer);
+
+	mdp_pipe_kickoff(MDP_DMA2_TERM, mfd);
+
+	if (msm_fb_debug_enabled) {
+		ktime_t t;
+		int usec_diff;
+		int actual_wait;
+
+		t = ktime_get_real();
+
+		actual_wait = ktime_to_us(ktime_sub(t, vt));
+		usec_diff = actual_wait - mdp_expected_usec_wait;
+
+		if ((mdp_usec_diff_threshold < usec_diff) || (usec_diff < 0))
+			MSM_FB_DEBUG
+			    ("HRT Diff = %d usec Exp=%d usec  Act=%d usec\n",
+			     usec_diff, mdp_expected_usec_wait, actual_wait);
+	}
+
+	return HRTIMER_NORESTART;
+}
+
+
+#ifdef CONFIG_FB_MSM_MDP303
+static int busy_wait_cnt;
+
+void	mdp3_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+	int need_wait = 0;
+
+#ifdef DSI_CLK_CTRL
+	mod_timer(&dsi_clock_timer, jiffies + HZ); /* one second */
+#endif
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+#ifdef DSI_CLK_CTRL
+
+	spin_lock_bh(&dsi_clk_lock);
+	if (mipi_dsi_clk_on == 0)
+		mipi_dsi_turn_on_clks();
+	spin_unlock_bh(&dsi_clk_lock);
+#endif
+
+	if (mfd->dma->busy == TRUE) {
+		if (busy_wait_cnt == 0)
+			INIT_COMPLETION(mfd->dma->comp);
+		busy_wait_cnt++;
+		need_wait++;
+	}
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	if (need_wait) {
+		/* wait until DMA finishes the current job */
+		wait_for_completion(&mfd->dma->comp);
+	}
+}
+#endif
+
+static void mdp_dma_schedule(struct msm_fb_data_type *mfd, uint32 term)
+{
+	/*
+	 * dma2 configure VSYNC block
+	 * vsync supported on Primary LCD only for now
+	 */
+	int32 mdp_lcd_rd_cnt;
+	uint32 usec_wait_time;
+	uint32 start_y;
+
+	/*
+	 * ToDo: if we can move HRT timer callback to workqueue, we can
+	 * move DMA2 power on under mdp_pipe_kickoff().
+	 * This will save a power for hrt time wait.
+	 * However if the latency for context switch (hrt irq -> workqueue)
+	 * is too big, we will miss the vsync timing.
+	 */
+	if (term == MDP_DMA2_TERM)
+		mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	mdp_dma2_update_time_in_usec = ktime_to_us(mdp_dma2_last_update_time);
+
+	if ((!mfd->ibuf.vsync_enable) || (!mfd->panel_info.lcd.vsync_enable)
+	    || (mfd->use_mdp_vsync)) {
+		mdp_pipe_kickoff(term, mfd);
+		return;
+	}
+	/* SW vsync logic starts here */
+
+	/* get current rd counter */
+	mdp_lcd_rd_cnt = mdp_get_lcd_line_counter(mfd);
+	if (mdp_dma2_update_time_in_usec != 0) {
+		uint32 num, den;
+
+		/*
+		 * roi width boundary calculation to know the size of pixel
+		 * width that MDP can send faster or slower than LCD read
+		 * pointer
+		 */
+
+		num = mdp_last_dma2_update_width * mdp_last_dma2_update_height;
+		den =
+		    (((mfd->panel_info.lcd.refx100 * mfd->total_lcd_lines) /
+		      1000) * (mdp_dma2_update_time_in_usec / 100)) / 1000;
+
+		if (den == 0)
+			mfd->vsync_width_boundary[mdp_last_dma2_update_width] =
+			    mfd->panel_info.xres + 1;
+		else
+			mfd->vsync_width_boundary[mdp_last_dma2_update_width] =
+			    (int)(num / den);
+	}
+
+	if (mfd->vsync_width_boundary[mdp_last_dma2_update_width] >
+	    mdp_curr_dma2_update_width) {
+		/* MDP wrp is faster than LCD rdp */
+		mdp_lcd_rd_cnt += mdp_lcd_rd_cnt_offset_fast;
+	} else {
+		/* MDP wrp is slower than LCD rdp */
+		mdp_lcd_rd_cnt -= mdp_lcd_rd_cnt_offset_slow;
+	}
+
+	if (mdp_lcd_rd_cnt < 0)
+		mdp_lcd_rd_cnt = mfd->total_lcd_lines + mdp_lcd_rd_cnt;
+	else if (mdp_lcd_rd_cnt > mfd->total_lcd_lines)
+		mdp_lcd_rd_cnt = mdp_lcd_rd_cnt - mfd->total_lcd_lines - 1;
+
+	/* get wrt pointer position */
+	start_y = mfd->ibuf.dma_y;
+
+	/* measure line difference between start_y and rd counter */
+	if (start_y > mdp_lcd_rd_cnt) {
+		/*
+		 * *100 for lcd_ref_hzx100 was already multiplied by 100
+		 * *1000000 is for usec conversion
+		 */
+
+		if ((start_y - mdp_lcd_rd_cnt) <=
+		    mdp_vsync_usec_wait_line_too_short)
+			usec_wait_time = 0;
+		else
+			usec_wait_time =
+			    ((start_y -
+			      mdp_lcd_rd_cnt) * 1000000) /
+			    ((mfd->total_lcd_lines *
+			      mfd->panel_info.lcd.refx100) / 100);
+	} else {
+		if ((start_y + (mfd->total_lcd_lines - mdp_lcd_rd_cnt)) <=
+		    mdp_vsync_usec_wait_line_too_short)
+			usec_wait_time = 0;
+		else
+			usec_wait_time =
+			    ((start_y +
+			      (mfd->total_lcd_lines -
+			       mdp_lcd_rd_cnt)) * 1000000) /
+			    ((mfd->total_lcd_lines *
+			      mfd->panel_info.lcd.refx100) / 100);
+	}
+
+	mdp_last_dma2_update_width = mdp_curr_dma2_update_width;
+	mdp_last_dma2_update_height = mdp_curr_dma2_update_height;
+
+	if (usec_wait_time == 0) {
+		mdp_pipe_kickoff(term, mfd);
+	} else {
+		ktime_t wait_time;
+
+		wait_time = ns_to_ktime(usec_wait_time * 1000);
+
+		if (msm_fb_debug_enabled) {
+			vt = ktime_get_real();
+			mdp_expected_usec_wait = usec_wait_time;
+		}
+		hrtimer_start(&mfd->dma_hrtimer, wait_time, HRTIMER_MODE_REL);
+	}
+}
+
+#ifdef MDDI_HOST_WINDOW_WORKAROUND
+static void mdp_dma2_update_sub(struct msm_fb_data_type *mfd);
+void mdp_dma2_update(struct msm_fb_data_type *mfd)
+{
+	MDPIBUF *iBuf;
+	uint32 upper_height;
+
+	if (mfd->panel.type == EXT_MDDI_PANEL) {
+		mdp_dma2_update_sub(mfd);
+		return;
+	}
+
+	iBuf = &mfd->ibuf;
+
+	upper_height =
+	    (uint32) mddi_assign_pkt_height((uint16) iBuf->dma_w,
+					    (uint16) iBuf->dma_h, 18);
+
+	if (upper_height >= iBuf->dma_h) {
+		mdp_dma2_update_sub(mfd);
+	} else {
+		uint32 lower_height;
+
+		/* sending the upper region first */
+		lower_height = iBuf->dma_h - upper_height;
+		iBuf->dma_h = upper_height;
+		mdp_dma2_update_sub(mfd);
+
+		/* sending the lower region second */
+		iBuf->dma_h = lower_height;
+		iBuf->dma_y += lower_height;
+		iBuf->vsync_enable = FALSE;
+		mdp_dma2_update_sub(mfd);
+	}
+}
+
+static void mdp_dma2_update_sub(struct msm_fb_data_type *mfd)
+#else
+void mdp_dma2_update(struct msm_fb_data_type *mfd)
+#endif
+{
+	down(&mfd->dma->mutex);
+	if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
+		down(&mfd->sem);
+		mfd->ibuf_flushed = TRUE;
+		mdp_dma2_update_lcd(mfd);
+
+		mdp_enable_irq(MDP_DMA2_TERM);
+		mfd->dma->busy = TRUE;
+		INIT_COMPLETION(mfd->dma->comp);
+
+		/* schedule DMA to start */
+		mdp_dma_schedule(mfd, MDP_DMA2_TERM);
+		up(&mfd->sem);
+
+		/* wait until DMA finishes the current job */
+		wait_for_completion_killable(&mfd->dma->comp);
+		mdp_disable_irq(MDP_DMA2_TERM);
+
+	/* signal if pan function is waiting for the update completion */
+		if (mfd->pan_waiting) {
+			mfd->pan_waiting = FALSE;
+			complete(&mfd->pan_comp);
+		}
+	}
+	up(&mfd->dma->mutex);
+}
+
+void mdp_dma_vsync_ctrl(int enable)
+{
+	if (vsync_cntrl.vsync_irq_enabled == enable)
+		return;
+
+	vsync_cntrl.vsync_irq_enabled = enable;
+
+	if (enable) {
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		MDP_OUTP(MDP_BASE + 0x021c, 0x10); /* read pointer */
+		mdp3_vsync_irq_enable(MDP_PRIM_RDPTR, MDP_VSYNC_TERM);
+	} else {
+		mdp3_vsync_irq_disable(MDP_PRIM_RDPTR, MDP_VSYNC_TERM);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	}
+}
+
+void mdp_lcd_update_workqueue_handler(struct work_struct *work)
+{
+	struct msm_fb_data_type *mfd = NULL;
+
+	mfd = container_of(work, struct msm_fb_data_type, dma_update_worker);
+	if (mfd)
+		mfd->dma_fnc(mfd);
+}
+
+void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
+			  boolean sync)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct fb_info *fbi = mfd->fbi;
+	MDPIBUF *iBuf;
+	int bpp = info->var.bits_per_pixel / 8;
+
+	down(&mfd->sem);
+
+	iBuf = &mfd->ibuf;
+	if (mfd->map_buffer)
+		iBuf->buf = (uint8 *)mfd->map_buffer->iova[0];
+	else
+		iBuf->buf = (uint8 *) info->fix.smem_start;
+
+	iBuf->buf += calc_fb_offset(mfd, fbi, bpp);
+
+	iBuf->ibuf_width = info->var.xres_virtual;
+	iBuf->bpp = bpp;
+
+	iBuf->vsync_enable = sync;
+
+	if (dirty) {
+		/*
+		 * ToDo: dirty region check inside var.xoffset+xres
+		 * <-> var.yoffset+yres
+		 */
+		iBuf->dma_x = dirty->xoffset % info->var.xres;
+		iBuf->dma_y = dirty->yoffset % info->var.yres;
+		iBuf->dma_w = dirty->width;
+		iBuf->dma_h = dirty->height;
+	} else {
+		iBuf->dma_x = 0;
+		iBuf->dma_y = 0;
+		iBuf->dma_w = info->var.xres;
+		iBuf->dma_h = info->var.yres;
+	}
+	mfd->ibuf_flushed = FALSE;
+	up(&mfd->sem);
+}
+
+void mdp_dma_pan_update(struct fb_info *info)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	MDPIBUF *iBuf;
+
+	iBuf = &mfd->ibuf;
+
+	if (mfd->sw_currently_refreshing) {
+		/* we need to wait for the pending update */
+		mfd->pan_waiting = TRUE;
+		if (!mfd->ibuf_flushed) {
+			wait_for_completion_killable(&mfd->pan_comp);
+		}
+		/* waiting for this update to complete */
+		mfd->pan_waiting = TRUE;
+		wait_for_completion_killable(&mfd->pan_comp);
+	} else
+		mfd->dma_fnc(mfd);
+}
+
+void mdp_refresh_screen(unsigned long data)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
+
+	if ((mfd->sw_currently_refreshing) && (mfd->sw_refreshing_enable)) {
+		init_timer(&mfd->refresh_timer);
+		mfd->refresh_timer.function = mdp_refresh_screen;
+		mfd->refresh_timer.data = data;
+
+		if (mfd->dma->busy)
+			/* come back in 1 msec */
+			mfd->refresh_timer.expires = jiffies + (HZ / 1000);
+		else
+			mfd->refresh_timer.expires =
+			    jiffies + mfd->refresh_timer_duration;
+
+		add_timer(&mfd->refresh_timer);
+
+		if (!mfd->dma->busy) {
+			if (!queue_work(mdp_dma_wq, &mfd->dma_update_worker)) {
+				MSM_FB_DEBUG("mdp_dma: can't queue_work! -> \
+			MDP/MDDI/LCD clock speed needs to be increased\n");
+			}
+		}
+	} else {
+		if (!mfd->hw_refresh)
+			complete(&mfd->refresher_comp);
+	}
+}
diff --git a/drivers/video/msm/mdp_dma_dsi_video.c b/drivers/video/msm/mdp_dma_dsi_video.c
new file mode 100644
index 0000000..8a41c78
--- /dev/null
+++ b/drivers/video/msm/mdp_dma_dsi_video.c
@@ -0,0 +1,292 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/fb.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+
+#define DSI_VIDEO_BASE	0xF0000
+#define DMA_P_BASE      0x90000
+
+static int first_pixel_start_x;
+static int first_pixel_start_y;
+
+int mdp_dsi_video_on(struct platform_device *pdev)
+{
+	int dsi_width;
+	int dsi_height;
+	int dsi_bpp;
+	int dsi_border_clr;
+	int dsi_underflow_clr;
+	int dsi_hsync_skew;
+
+	int hsync_period;
+	int hsync_ctrl;
+	int vsync_period;
+	int display_hctl;
+	int display_v_start;
+	int display_v_end;
+	int active_hctl;
+	int active_h_start;
+	int active_h_end;
+	int active_v_start;
+	int active_v_end;
+	int ctrl_polarity;
+	int h_back_porch;
+	int h_front_porch;
+	int v_back_porch;
+	int v_front_porch;
+	int hsync_pulse_width;
+	int vsync_pulse_width;
+	int hsync_polarity;
+	int vsync_polarity;
+	int data_en_polarity;
+	int hsync_start_x;
+	int hsync_end_x;
+	uint8 *buf;
+	uint32 dma2_cfg_reg;
+
+	int bpp;
+	struct fb_info *fbi;
+	struct fb_var_screeninfo *var;
+	struct msm_fb_data_type *mfd;
+	int ret;
+	uint32 mask, curr;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	fbi = mfd->fbi;
+	var = &fbi->var;
+
+	vsync_cntrl.dev = mfd->fbi->dev;
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+
+	buf += calc_fb_offset(mfd, fbi, bpp);
+
+	dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_DSI_VIDEO;
+
+	if (mfd->fb_imgType == MDP_BGR_565)
+		dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else if (mfd->fb_imgType == MDP_RGBA_8888)
+		dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else
+		dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
+
+	if (bpp == 2)
+		dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
+	else if (bpp == 3)
+		dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888;
+	else
+		dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888;
+
+	switch (mfd->panel_info.bpp) {
+	case 24:
+		dma2_cfg_reg |= DMA_DSTC0G_8BITS |
+			DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
+		break;
+	case 18:
+		dma2_cfg_reg |= DMA_DSTC0G_6BITS |
+			DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+		break;
+	case 16:
+		dma2_cfg_reg |= DMA_DSTC0G_6BITS |
+			DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
+		break;
+	default:
+		printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n",
+			mfd->panel_info.bpp);
+		return -ENODEV;
+	}
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/* starting address */
+	MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x8, (uint32) buf);
+
+	/* active window width and height */
+	MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x4, ((fbi->var.yres) << 16) |
+		(fbi->var.xres));
+
+	/* buffer ystride */
+	MDP_OUTP(MDP_BASE + DMA_P_BASE + 0xc, fbi->fix.line_length);
+
+	/* x/y coordinate = always 0 for lcdc */
+	MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x10, 0);
+
+	/* dma config */
+	curr = inpdw(MDP_BASE + 0x90000);
+	mask = 0xBFFFFFFF;
+	dma2_cfg_reg = (dma2_cfg_reg & mask) | (curr & ~mask);
+	MDP_OUTP(MDP_BASE + DMA_P_BASE, dma2_cfg_reg);
+
+	/*
+	 * DSI timing setting
+	 */
+	h_back_porch = var->left_margin;
+	h_front_porch = var->right_margin;
+	v_back_porch = var->upper_margin;
+	v_front_porch = var->lower_margin;
+	hsync_pulse_width = var->hsync_len;
+	vsync_pulse_width = var->vsync_len;
+	dsi_border_clr = mfd->panel_info.lcdc.border_clr;
+	dsi_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
+	dsi_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
+	dsi_width = mfd->panel_info.xres;
+	dsi_height = mfd->panel_info.yres;
+	dsi_bpp = mfd->panel_info.bpp;
+	hsync_period = h_back_porch + dsi_width + h_front_porch + 1;
+	hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
+	hsync_start_x = h_back_porch;
+	hsync_end_x = dsi_width + h_back_porch - 1;
+	display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+	vsync_period =
+		(v_back_porch + dsi_height + v_front_porch + 1) * hsync_period;
+	display_v_start = v_back_porch * hsync_period + dsi_hsync_skew;
+	display_v_end = (dsi_height + v_back_porch) * hsync_period;
+
+	active_h_start = hsync_start_x + first_pixel_start_x;
+	active_h_end = active_h_start + var->xres - 1;
+	active_hctl = ACTIVE_START_X_EN |
+			(active_h_end << 16) | active_h_start;
+
+	active_v_start = display_v_start +
+			first_pixel_start_y * hsync_period;
+	active_v_end = active_v_start +	(var->yres) * hsync_period - 1;
+	active_v_start |= ACTIVE_START_Y_EN;
+
+	dsi_underflow_clr |= 0x80000000;	/* enable recovery */
+	hsync_polarity = 0;
+	vsync_polarity = 0;
+	data_en_polarity = 0;
+
+	ctrl_polarity =	(data_en_polarity << 2) |
+		(vsync_polarity << 1) | (hsync_polarity);
+
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x4, hsync_ctrl);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x8, vsync_period);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0xc, vsync_pulse_width);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x10, display_hctl);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x14, display_v_start);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x18, display_v_end);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x1c, active_hctl);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x20, active_v_start);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x24, active_v_end);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x28, dsi_border_clr);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x2c, dsi_underflow_clr);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity);
+
+	ret = panel_next_on(pdev);
+	if (ret == 0) {
+		/* enable DSI block */
+		MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1);
+		/*Turning on DMA_P block*/
+		mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	}
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return ret;
+}
+
+int mdp_dsi_video_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	/*Turning off DMA_P block*/
+	mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	ret = panel_next_off(pdev);
+	/* delay to make sure the last frame finishes */
+	msleep(20);
+
+	return ret;
+}
+
+void mdp_dma_video_vsync_ctrl(int enable)
+{
+	if (vsync_cntrl.vsync_irq_enabled == enable)
+		return;
+
+	vsync_cntrl.vsync_irq_enabled = enable;
+
+	if (enable) {
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp3_vsync_irq_enable(LCDC_FRAME_START, MDP_VSYNC_TERM);
+	} else {
+		mdp3_vsync_irq_disable(LCDC_FRAME_START, MDP_VSYNC_TERM);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	}
+}
+
+void mdp_dsi_video_update(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	int bpp;
+	unsigned long flag;
+	int irq_block = MDP_DMA2_TERM;
+
+	if (!mfd->panel_power_on)
+		return;
+
+	down(&mfd->dma->mutex);
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+
+	buf += calc_fb_offset(mfd, fbi, bpp);
+
+	/* no need to power on cmd block since it's dsi mode */
+	/* starting address */
+	MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x8, (uint32) buf);
+	/* enable  irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(irq_block);
+	INIT_COMPLETION(mfd->dma->comp);
+	mfd->dma->waiting = TRUE;
+
+	outp32(MDP_INTR_CLEAR, LCDC_FRAME_START);
+	mdp_intr_mask |= LCDC_FRAME_START;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	wait_for_completion_killable(&mfd->dma->comp);
+	mdp_disable_irq(irq_block);
+	up(&mfd->dma->mutex);
+}
diff --git a/drivers/video/msm/mdp_dma_lcdc.c b/drivers/video/msm/mdp_dma_lcdc.c
new file mode 100644
index 0000000..d576c46
--- /dev/null
+++ b/drivers/video/msm/mdp_dma_lcdc.c
@@ -0,0 +1,390 @@
+/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+
+#include <linux/fb.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+
+#ifdef CONFIG_FB_MSM_MDP40
+#define LCDC_BASE	0xC0000
+#define DTV_BASE	0xD0000
+#define DMA_E_BASE      0xB0000
+#else
+#define LCDC_BASE	0xE0000
+#endif
+
+#define DMA_P_BASE      0x90000
+
+extern spinlock_t mdp_spin_lock;
+#ifndef CONFIG_FB_MSM_MDP40
+extern uint32 mdp_intr_mask;
+#endif
+
+int first_pixel_start_x;
+int first_pixel_start_y;
+
+int mdp_lcdc_on(struct platform_device *pdev)
+{
+	int lcdc_width;
+	int lcdc_height;
+	int lcdc_bpp;
+	int lcdc_border_clr;
+	int lcdc_underflow_clr;
+	int lcdc_hsync_skew;
+
+	int hsync_period;
+	int hsync_ctrl;
+	int vsync_period;
+	int display_hctl;
+	int display_v_start;
+	int display_v_end;
+	int active_hctl;
+	int active_h_start;
+	int active_h_end;
+	int active_v_start;
+	int active_v_end;
+	int ctrl_polarity;
+	int h_back_porch;
+	int h_front_porch;
+	int v_back_porch;
+	int v_front_porch;
+	int hsync_pulse_width;
+	int vsync_pulse_width;
+	int hsync_polarity;
+	int vsync_polarity;
+	int data_en_polarity;
+	int hsync_start_x;
+	int hsync_end_x;
+	uint8 *buf;
+	int bpp;
+	uint32 dma2_cfg_reg;
+	struct fb_info *fbi;
+	struct fb_var_screeninfo *var;
+	struct msm_fb_data_type *mfd;
+	uint32 dma_base;
+	uint32 timer_base = LCDC_BASE;
+	uint32 block = MDP_DMA2_BLOCK;
+	int ret;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	fbi = mfd->fbi;
+	var = &fbi->var;
+	vsync_cntrl.dev = mfd->fbi->dev;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+
+	buf += calc_fb_offset(mfd, fbi, bpp);
+
+	dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_LCDC;
+
+	if (mfd->fb_imgType == MDP_BGR_565)
+		dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else if (mfd->fb_imgType == MDP_RGBA_8888)
+		dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else
+		dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
+
+	if (bpp == 2)
+		dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
+	else if (bpp == 3)
+		dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888;
+	else
+		dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888;
+
+	switch (mfd->panel_info.bpp) {
+	case 24:
+		dma2_cfg_reg |= DMA_DSTC0G_8BITS |
+		    DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
+		break;
+
+	case 18:
+		dma2_cfg_reg |= DMA_DSTC0G_6BITS |
+		    DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+		break;
+
+	case 16:
+		dma2_cfg_reg |= DMA_DSTC0G_6BITS |
+		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
+		break;
+
+	default:
+		printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n",
+		       mfd->panel_info.bpp);
+		return -ENODEV;
+	}
+
+	/* DMA register config */
+
+	dma_base = DMA_P_BASE;
+
+#ifdef CONFIG_FB_MSM_MDP40
+	if (mfd->panel.type == HDMI_PANEL)
+		dma_base = DMA_E_BASE;
+#endif
+
+	/* starting address */
+	MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf);
+	/* active window width and height */
+	MDP_OUTP(MDP_BASE + dma_base + 0x4, ((fbi->var.yres) << 16) |
+						(fbi->var.xres));
+	/* buffer ystride */
+	MDP_OUTP(MDP_BASE + dma_base + 0xc, fbi->fix.line_length);
+	/* x/y coordinate = always 0 for lcdc */
+	MDP_OUTP(MDP_BASE + dma_base + 0x10, 0);
+	/* dma config */
+	MDP_OUTP(MDP_BASE + dma_base, dma2_cfg_reg);
+
+	/*
+	 * LCDC timing setting
+	 */
+	h_back_porch = var->left_margin;
+	h_front_porch = var->right_margin;
+	v_back_porch = var->upper_margin;
+	v_front_porch = var->lower_margin;
+	hsync_pulse_width = var->hsync_len;
+	vsync_pulse_width = var->vsync_len;
+	lcdc_border_clr = mfd->panel_info.lcdc.border_clr;
+	lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
+	lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
+
+	lcdc_width = mfd->panel_info.xres;
+	lcdc_height = mfd->panel_info.yres;
+	lcdc_bpp = mfd->panel_info.bpp;
+
+	hsync_period =
+	    hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch;
+	hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
+	hsync_start_x = hsync_pulse_width + h_back_porch;
+	hsync_end_x = hsync_period - h_front_porch - 1;
+	display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+	vsync_period =
+	    (vsync_pulse_width + v_back_porch + lcdc_height +
+	     v_front_porch) * hsync_period;
+	display_v_start =
+	    (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew;
+	display_v_end =
+	    vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1;
+
+	if (lcdc_width != var->xres) {
+		active_h_start = hsync_start_x + first_pixel_start_x;
+		active_h_end = active_h_start + var->xres - 1;
+		active_hctl =
+		    ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
+	} else {
+		active_hctl = 0;
+	}
+
+	if (lcdc_height != var->yres) {
+		active_v_start =
+		    display_v_start + first_pixel_start_y * hsync_period;
+		active_v_end = active_v_start + (var->yres) * hsync_period - 1;
+		active_v_start |= ACTIVE_START_Y_EN;
+	} else {
+		active_v_start = 0;
+		active_v_end = 0;
+	}
+
+
+#ifdef CONFIG_FB_MSM_MDP40
+	if (mfd->panel.type == HDMI_PANEL) {
+		block = MDP_DMA_E_BLOCK;
+		timer_base = DTV_BASE;
+		hsync_polarity = 0;
+		vsync_polarity = 0;
+	} else {
+		hsync_polarity = 1;
+		vsync_polarity = 1;
+	}
+
+	lcdc_underflow_clr |= 0x80000000;	/* enable recovery */
+#else
+	hsync_polarity = 0;
+	vsync_polarity = 0;
+#endif
+	data_en_polarity = 0;
+
+	ctrl_polarity =
+	    (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);
+
+	MDP_OUTP(MDP_BASE + timer_base + 0x4, hsync_ctrl);
+	MDP_OUTP(MDP_BASE + timer_base + 0x8, vsync_period);
+	MDP_OUTP(MDP_BASE + timer_base + 0xc, vsync_pulse_width * hsync_period);
+	if (timer_base == LCDC_BASE) {
+		MDP_OUTP(MDP_BASE + timer_base + 0x10, display_hctl);
+		MDP_OUTP(MDP_BASE + timer_base + 0x14, display_v_start);
+		MDP_OUTP(MDP_BASE + timer_base + 0x18, display_v_end);
+		MDP_OUTP(MDP_BASE + timer_base + 0x28, lcdc_border_clr);
+		MDP_OUTP(MDP_BASE + timer_base + 0x2c, lcdc_underflow_clr);
+		MDP_OUTP(MDP_BASE + timer_base + 0x30, lcdc_hsync_skew);
+		MDP_OUTP(MDP_BASE + timer_base + 0x38, ctrl_polarity);
+		MDP_OUTP(MDP_BASE + timer_base + 0x1c, active_hctl);
+		MDP_OUTP(MDP_BASE + timer_base + 0x20, active_v_start);
+		MDP_OUTP(MDP_BASE + timer_base + 0x24, active_v_end);
+	} else {
+		MDP_OUTP(MDP_BASE + timer_base + 0x18, display_hctl);
+		MDP_OUTP(MDP_BASE + timer_base + 0x1c, display_v_start);
+		MDP_OUTP(MDP_BASE + timer_base + 0x20, display_v_end);
+		MDP_OUTP(MDP_BASE + timer_base + 0x40, lcdc_border_clr);
+		MDP_OUTP(MDP_BASE + timer_base + 0x44, lcdc_underflow_clr);
+		MDP_OUTP(MDP_BASE + timer_base + 0x48, lcdc_hsync_skew);
+		MDP_OUTP(MDP_BASE + timer_base + 0x50, ctrl_polarity);
+		MDP_OUTP(MDP_BASE + timer_base + 0x2c, active_hctl);
+		MDP_OUTP(MDP_BASE + timer_base + 0x30, active_v_start);
+		MDP_OUTP(MDP_BASE + timer_base + 0x38, active_v_end);
+	}
+
+	ret = panel_next_on(pdev);
+	if (ret == 0) {
+		/* enable LCDC block */
+		MDP_OUTP(MDP_BASE + timer_base, 1);
+		mdp_pipe_ctrl(block, MDP_BLOCK_POWER_ON, FALSE);
+	}
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return ret;
+}
+
+int mdp_lcdc_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_data_type *mfd;
+	uint32 timer_base = LCDC_BASE;
+	uint32 block = MDP_DMA2_BLOCK;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+#ifdef CONFIG_FB_MSM_MDP40
+	if (mfd->panel.type == HDMI_PANEL) {
+		block = MDP_DMA_E_BLOCK;
+		timer_base = DTV_BASE;
+	}
+#endif
+
+	down(&mfd->dma->mutex);
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	MDP_OUTP(MDP_BASE + timer_base, 0);
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	mdp_pipe_ctrl(block, MDP_BLOCK_POWER_OFF, FALSE);
+
+	ret = panel_next_off(pdev);
+	up(&mfd->dma->mutex);
+
+	/* delay to make sure the last frame finishes */
+	msleep(16);
+
+	return ret;
+}
+
+void mdp_dma_lcdc_vsync_ctrl(int enable)
+{
+	if (vsync_cntrl.vsync_irq_enabled == enable)
+		return;
+
+	vsync_cntrl.vsync_irq_enabled = enable;
+
+	if (enable) {
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp3_vsync_irq_enable(LCDC_FRAME_START, MDP_VSYNC_TERM);
+	} else {
+		mdp3_vsync_irq_disable(LCDC_FRAME_START, MDP_VSYNC_TERM);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	}
+}
+
+void mdp_lcdc_update(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	int bpp;
+	unsigned long flag;
+	uint32 dma_base;
+	int irq_block = MDP_DMA2_TERM;
+#ifdef CONFIG_FB_MSM_MDP40
+	int intr = INTR_DMA_P_DONE;
+#endif
+
+	if (!mfd->panel_power_on)
+		return;
+
+	down(&mfd->dma->mutex);
+	/* no need to power on cmd block since it's lcdc mode */
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+
+	buf += calc_fb_offset(mfd, fbi, bpp);
+
+	dma_base = DMA_P_BASE;
+
+#ifdef CONFIG_FB_MSM_MDP40
+	if (mfd->panel.type == HDMI_PANEL) {
+		intr = INTR_DMA_E_DONE;
+		irq_block = MDP_DMA_E_TERM;
+		dma_base = DMA_E_BASE;
+	}
+#endif
+
+	/* starting address */
+	MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf);
+
+	/* enable LCDC irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(irq_block);
+	INIT_COMPLETION(mfd->dma->comp);
+	mfd->dma->waiting = TRUE;
+#ifdef CONFIG_FB_MSM_MDP40
+	outp32(MDP_INTR_CLEAR, intr);
+	mdp_intr_mask |= intr;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+#else
+	outp32(MDP_INTR_CLEAR, LCDC_FRAME_START);
+	mdp_intr_mask |= LCDC_FRAME_START;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+#endif
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	wait_for_completion_killable(&mfd->dma->comp);
+	mdp_disable_irq(irq_block);
+	up(&mfd->dma->mutex);
+}
diff --git a/drivers/video/msm/mdp_dma_s.c b/drivers/video/msm/mdp_dma_s.c
new file mode 100644
index 0000000..22d79be
--- /dev/null
+++ b/drivers/video/msm/mdp_dma_s.c
@@ -0,0 +1,166 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+
+#include <linux/fb.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+
+static void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd)
+{
+	MDPIBUF *iBuf = &mfd->ibuf;
+	int mddi_dest = FALSE;
+	uint32 outBpp = iBuf->bpp;
+	uint32 dma_s_cfg_reg;
+	uint8 *src;
+	struct msm_fb_panel_data *pdata =
+	    (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
+	dma_s_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB |
+	    DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS;
+
+	if (mfd->fb_imgType == MDP_BGR_565)
+		dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR;
+	else
+		dma_s_cfg_reg |= DMA_PACK_PATTERN_RGB;
+
+	if (outBpp == 4)
+		dma_s_cfg_reg |= DMA_IBUF_C3ALPHA_EN;
+
+	if (outBpp == 2)
+		dma_s_cfg_reg |= DMA_IBUF_FORMAT_RGB565;
+
+	if (mfd->panel_info.pdest != DISPLAY_2) {
+		printk(KERN_ERR "error: non-secondary type through dma_s!\n");
+		return;
+	}
+
+	if (mfd->panel_info.type == MDDI_PANEL ||
+		mfd->panel_info.type == EXT_MDDI_PANEL) {
+		dma_s_cfg_reg |= DMA_OUT_SEL_MDDI;
+		mddi_dest = TRUE;
+	} else {
+		dma_s_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY;
+		outp32(MDP_EBI2_LCD1, mfd->data_port_phys);
+	}
+
+	src = (uint8 *) iBuf->buf;
+	/* starting input address */
+	src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * outBpp;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	/* PIXELSIZE */
+	if (mfd->panel_info.type == MDDI_PANEL) {
+		MDP_OUTP(MDP_BASE + 0xa0004,
+			(iBuf->dma_h << 16 | iBuf->dma_w));
+		MDP_OUTP(MDP_BASE + 0xa0008, src);	/* ibuf address */
+		MDP_OUTP(MDP_BASE + 0xa000c,
+			iBuf->ibuf_width * outBpp);/* ystride */
+	} else {
+		MDP_OUTP(MDP_BASE + 0xb0004,
+			(iBuf->dma_h << 16 | iBuf->dma_w));
+		MDP_OUTP(MDP_BASE + 0xb0008, src);	/* ibuf address */
+		MDP_OUTP(MDP_BASE + 0xb000c,
+			iBuf->ibuf_width * outBpp);/* ystride */
+	}
+
+	if (mfd->panel_info.bpp == 18) {
+		dma_s_cfg_reg |= DMA_DSTC0G_6BITS |	/* 666 18BPP */
+		    DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+	} else {
+		dma_s_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
+		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
+	}
+
+	if (mddi_dest) {
+		if (mfd->panel_info.type == MDDI_PANEL) {
+			MDP_OUTP(MDP_BASE + 0xa0010,
+				(iBuf->dma_y << 16) | iBuf->dma_x);
+			MDP_OUTP(MDP_BASE + 0x00090, 1);
+		} else {
+			MDP_OUTP(MDP_BASE + 0xb0010,
+				(iBuf->dma_y << 16) | iBuf->dma_x);
+			MDP_OUTP(MDP_BASE + 0x00090, 2);
+		}
+		MDP_OUTP(MDP_BASE + 0x00094,
+				(MDDI_VDO_PACKET_DESC << 16) |
+				mfd->panel_info.mddi.vdopkt);
+	} else {
+		/* setting LCDC write window */
+		pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w,
+				iBuf->dma_h);
+	}
+
+	if (mfd->panel_info.type == MDDI_PANEL)
+		MDP_OUTP(MDP_BASE + 0xa0000, dma_s_cfg_reg);
+	else
+		MDP_OUTP(MDP_BASE + 0xb0000, dma_s_cfg_reg);
+
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	if (mfd->panel_info.type == MDDI_PANEL)
+		mdp_pipe_kickoff(MDP_DMA_S_TERM, mfd);
+	else
+		mdp_pipe_kickoff(MDP_DMA_E_TERM, mfd);
+
+}
+
+void mdp_dma_s_update(struct msm_fb_data_type *mfd)
+{
+	down(&mfd->dma->mutex);
+	if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
+		down(&mfd->sem);
+		mdp_enable_irq(MDP_DMA_S_TERM);
+		if (mfd->panel_info.type == MDDI_PANEL)
+			mdp_enable_irq(MDP_DMA_S_TERM);
+		else
+			mdp_enable_irq(MDP_DMA_E_TERM);
+		mfd->dma->busy = TRUE;
+		INIT_COMPLETION(mfd->dma->comp);
+		mfd->ibuf_flushed = TRUE;
+		mdp_dma_s_update_lcd(mfd);
+		up(&mfd->sem);
+
+		/* wait until DMA finishes the current job */
+		wait_for_completion_killable(&mfd->dma->comp);
+		if (mfd->panel_info.type == MDDI_PANEL)
+			mdp_disable_irq(MDP_DMA_S_TERM);
+		else
+			mdp_disable_irq(MDP_DMA_E_TERM);
+
+	/* signal if pan function is waiting for the update completion */
+		if (mfd->pan_waiting) {
+			mfd->pan_waiting = FALSE;
+			complete(&mfd->pan_comp);
+		}
+	}
+	up(&mfd->dma->mutex);
+}
diff --git a/drivers/video/msm/mdp_dma_tv.c b/drivers/video/msm/mdp_dma_tv.c
new file mode 100644
index 0000000..b578ba2
--- /dev/null
+++ b/drivers/video/msm/mdp_dma_tv.c
@@ -0,0 +1,140 @@
+/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+
+#include <linux/fb.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+
+extern spinlock_t mdp_spin_lock;
+extern uint32 mdp_intr_mask;
+
+int mdp_dma3_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct fb_info *fbi;
+	uint8 *buf;
+	int bpp;
+	int ret = 0;
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	fbi = mfd->fbi;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+
+	buf += calc_fb_offset(mfd, fbi, bpp);
+
+	/* starting address[31..8] of Video frame buffer is CS0 */
+	MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3);
+
+	mdp_pipe_ctrl(MDP_DMA3_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	MDP_OUTP(MDP_BASE + 0xC0004, 0x4c60674); /* flicker filter enabled */
+	MDP_OUTP(MDP_BASE + 0xC0010, 0x20);	/* sobel treshold */
+
+	MDP_OUTP(MDP_BASE + 0xC0018, 0xeb0010);	/* Y  Max, Y  min */
+	MDP_OUTP(MDP_BASE + 0xC001C, 0xf00010);	/* Cb Max, Cb min */
+	MDP_OUTP(MDP_BASE + 0xC0020, 0xf00010);	/* Cb Max, Cb min */
+
+	MDP_OUTP(MDP_BASE + 0xC000C, 0x67686970); /* add a few chars for CC */
+	MDP_OUTP(MDP_BASE + 0xC0000, 0x1);	/* MDP tv out enable */
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	ret = panel_next_on(pdev);
+
+	return ret;
+}
+
+int mdp_dma3_off(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	ret = panel_next_off(pdev);
+	if (ret)
+		return ret;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	MDP_OUTP(MDP_BASE + 0xC0000, 0x0);
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	mdp_pipe_ctrl(MDP_DMA3_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	/* delay to make sure the last frame finishes */
+	msleep(16);
+
+	return ret;
+}
+
+void mdp_dma3_update(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	int bpp;
+	unsigned long flag;
+
+	if (!mfd->panel_power_on)
+		return;
+
+	/* no need to power on cmd block since dma3 is running */
+	bpp = fbi->var.bits_per_pixel / 8;
+	buf = (uint8 *) fbi->fix.smem_start;
+
+	buf += calc_fb_offset(mfd, fbi, bpp);
+
+	MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3);
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_DMA3_TERM);
+	INIT_COMPLETION(mfd->dma->comp);
+	mfd->dma->waiting = TRUE;
+
+	outp32(MDP_INTR_CLEAR, TV_OUT_DMA3_START);
+	mdp_intr_mask |= TV_OUT_DMA3_START;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	wait_for_completion_killable(&mfd->dma->comp);
+	mdp_disable_irq(MDP_DMA3_TERM);
+}
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h
index 66d37d7..f35a757 100644
--- a/drivers/video/msm/mdp_hw.h
+++ b/drivers/video/msm/mdp_hw.h
@@ -47,106 +47,11 @@
 	char * __iomem base;
 	int irq;
 	struct clk *clk;
-	struct clk *pclk;
 	struct clk *ebi1_clk;
-#ifdef CONFIG_MDP4_HW_VSYNC
-	struct clk *vsync_clk;
-#endif
 	struct mdp_out_interface out_if[MSM_MDP_NUM_INTERFACES];
-	int dma_format;
-	int dma_pack_pattern;
+	int format;
+	int pack_pattern;
 	bool dma_config_dirty;
-	struct mdp_blit_req *req;
-	uint32_t state;
-	struct timer_list standby_timer;
-	struct timer_list dma_timer;
-#ifdef CONFIG_MSM_MDP40
-	int hw_version;
-#endif
-#ifdef CONFIG_MDP4_HW_VSYNC
-	int total_lcd_line;
-#endif
-	int (*enable_irq)(struct mdp_info *mdp, uint32_t mask);
-	int (*disable_irq)(struct mdp_info *mdp, uint32_t mask);
-	int (*write_regs)(struct mdp_info *mdp, const struct mdp_reg *reglist, int size);
-};
-
-struct mdp_lcdc_info {
-	struct mdp_info			*mdp;
-	struct clk			*mdp_clk;
-	struct clk			*mdp_pclk;
-	struct clk			*pclk;
-	struct clk			*pad_pclk;
-	struct msm_panel_data		fb_panel_data;
-	struct platform_device		fb_pdev;
-	struct msm_lcdc_platform_data	*pdata;
-	uint32_t fb_start;
-
-	struct msmfb_callback		frame_start_cb;
-	wait_queue_head_t		vsync_waitq;
-	int				got_vsync;
-	unsigned			color_format;
-	struct {
-		uint32_t	clk_rate;
-		uint32_t	hsync_ctl;
-		uint32_t	vsync_period;
-		uint32_t	vsync_pulse_width;
-		uint32_t	display_hctl;
-		uint32_t	display_vstart;
-		uint32_t	display_vend;
-		uint32_t	hsync_skew;
-		uint32_t	polarity;
-	} parms;
-};
-
-struct mdp_dtv_info {
-	struct mdp_info			*mdp;
-	struct clk			*mdp_clk;
-	struct clk			*tv_enc_clk;
-	struct clk			*tv_dac_clk;
-	struct clk			*tv_src_clk;
-	struct clk			*hdmi_clk;
-	struct clk			*mdp_tv_clk;
-	struct msm_panel_data		fb_panel_data;
-	struct platform_device		fb_pdev;
-	struct msm_lcdc_platform_data	*pdata;
-	char				*fb_base;
-	uint32_t fb_start;
-	uint32_t fb_size;
-	bool 				active;
-
-	struct msmfb_callback		frame_start_cb;
-	wait_queue_head_t		vsync_waitq;
-	int				got_vsync;
-	unsigned			color_format;
-	struct {
-		uint32_t	clk_rate;
-		uint32_t	hsync_ctl;
-		uint32_t	vsync_period;
-		uint32_t	vsync_pulse_width;
-		uint32_t	display_hctl;
-		uint32_t	display_vstart;
-		uint32_t	display_vend;
-		uint32_t	hsync_skew;
-		uint32_t	polarity;
-	} parms;
-
-	void (*dtv_relay)(struct mdp_dtv_info *dtv, int on_off);
-	void (*dtv_reconfig_timing)(struct mdp_dtv_info *dtv,
-		struct msm_lcdc_timing *timing, struct msm_fb_data *fb_data);
-};
-
-
-struct panel_icm_info {
-	bool	icm_mode;
-	bool	icm_doable;
-	bool	clock_enabled;
-	int	panel_update;
-	bool	icm_suspend;
-	struct mutex icm_lock;
-	struct mdp_lcdc_info *lcdc;
-	spinlock_t lock;
-	void (*force_leave)(void);
 };
 
 extern int mdp_out_if_register(struct mdp_device *mdp_dev, int interface,
@@ -158,74 +63,33 @@
 
 struct mdp_blit_req;
 struct mdp_device;
+int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
+		 struct file *src_file, unsigned long src_start,
+		 unsigned long src_len, struct file *dst_file,
+		 unsigned long dst_start, unsigned long dst_len);
 
-struct msm_mdp_platform_data;
 void mdp_ppp_dump_debug(const struct mdp_info *mdp);
-int mdp_hw_init(struct mdp_info *mdp);
-void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata);
-void mdp_dump_blit(struct mdp_blit_req *req);
-int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq);
 
 #define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset)
 #define mdp_readl(mdp, offset) readl(mdp->base + offset)
-#define panel_to_lcdc(p) container_of((p), struct mdp_lcdc_info, fb_panel_data)
-#define panel_to_dtv(p) container_of((p), struct mdp_dtv_info, fb_panel_data)
 
-/* define mdp state for multi purpose */
-#define MDP_STATE_STANDBY		(1 << 0)
-
-#define MDP4_REVISION_V1			0
-#define MDP4_REVISION_V2			1
-#define MDP4_REVISION_V2_1			2
-#define MDP4_REVISION_NONE		0xffffffff
-#define MDP_AXI_RDMASTER_CONFIG		(0x00028)
-
-#ifdef CONFIG_MSM_MDP302
-#define MDP_SYNC_CONFIG_0                (0x00300)
-#define MDP_SYNC_CONFIG_1                (0x00304)
-#define MDP_SYNC_CONFIG_2                (0x00308)
-#else
 #define MDP_SYNC_CONFIG_0                (0x00000)
 #define MDP_SYNC_CONFIG_1                (0x00004)
 #define MDP_SYNC_CONFIG_2                (0x00008)
-#endif
-
 #define MDP_SYNC_STATUS_0                (0x0000c)
 #define MDP_SYNC_STATUS_1                (0x00010)
 #define MDP_SYNC_STATUS_2                (0x00014)
-
-#ifdef CONFIG_MSM_MDP302
-#define MDP_SYNC_THRESH_0                (0x00200)
-#define MDP_SYNC_THRESH_1                (0x00204)
-#else
 #define MDP_SYNC_THRESH_0                (0x00018)
 #define MDP_SYNC_THRESH_1                (0x0001c)
-#endif
-#ifdef CONFIG_MSM_MDP40
-#define MDP_INTR_ENABLE                  (0x0050)
-#define MDP_INTR_STATUS                  (0x0054)
-#define MDP_INTR_CLEAR                   (0x0058)
-#define MDP_EBI2_LCD0                    (0x0060)
-#define MDP_EBI2_LCD1                    (0x0064)
-#define MDP_EBI2_PORTMAP_MODE            (0x0070)
-
-#define MDP_DMA_P_HIST_INTR_STATUS 	(0x95014)
-#define MDP_DMA_P_HIST_INTR_CLEAR 	(0x95018)
-#define MDP_DMA_P_HIST_INTR_ENABLE 	(0x9501C)
-#else
 #define MDP_INTR_ENABLE                  (0x00020)
 #define MDP_INTR_STATUS                  (0x00024)
 #define MDP_INTR_CLEAR                   (0x00028)
-#define MDP_EBI2_LCD0                    (0x0003c)
-#define MDP_EBI2_LCD1                    (0x00040)
-#define MDP_EBI2_PORTMAP_MODE            (0x0005c)
-#endif
 #define MDP_DISPLAY0_START               (0x00030)
 #define MDP_DISPLAY1_START               (0x00034)
 #define MDP_DISPLAY_STATUS               (0x00038)
-/* CONFIG_MSM_MDP302 */
-#define MDP_TEAR_CHECK_EN                (0x0020c)
-#define MDP_PRIM_START_POS               (0x00210)
+#define MDP_EBI2_LCD0                    (0x0003c)
+#define MDP_EBI2_LCD1                    (0x00040)
+#define MDP_EBI2_PORTMAP_MODE            (0x0005c)
 
 #ifndef CONFIG_MSM_MDP31
 #define MDP_DISPLAY0_ADDR                (0x00054)
@@ -248,14 +112,6 @@
 #define MDP_VSYNC_CTRL                   (0x0008c)
 #define MDP_MDDI_PARAM_WR_SEL            (0x00090)
 #define MDP_MDDI_PARAM                   (0x00094)
-#define MDP_MDDI_DATA_XFR                (0x00098)
-
-
-#if defined(CONFIG_MSM_MDP40)
-#define MDP_LAYERMIXER_IN_CFG            (0x10100)
-#define MDP_OVERLAYPROC0_CFG             (0x10004)
-#define MDP_OVERLAYPROC1_CFG             (0x18004)
-#endif
 #define MDP_CGC_EN                       (0x00100)
 #define MDP_CMD_STATUS                   (0x10008)
 #define MDP_PROFILE_EN                   (0x10010)
@@ -371,11 +227,7 @@
 #define MDP_TEST_CAPTURED_DCLK           (0xd0210)
 #define MDP_TEST_MISR_CAPT_VAL_DCLK      (0xd0214)
 
-#ifdef CONFIG_MSM_MDP40
-#define MDP_DMA_P_START                  (0x000c)
-#else
 #define MDP_DMA_P_START                  (0x00044)
-#endif
 #define MDP_DMA_P_CONFIG                 (0x90000)
 #define MDP_DMA_P_SIZE                   (0x90004)
 #define MDP_DMA_P_IBUF_ADDR              (0x90008)
@@ -383,45 +235,6 @@
 #define MDP_DMA_P_OUT_XY                 (0x90010)
 #define MDP_DMA_P_COLOR_CORRECT_CONFIG   (0x90070)
 
-#define MDP_DMA_S_START                  (0x00048)
-#define MDP_DMA_S_CONFIG                 (0xa0000)
-#define MDP_DMA_S_SIZE                   (0xa0004)
-#define MDP_DMA_S_IBUF_ADDR              (0xa0008)
-#define MDP_DMA_S_IBUF_Y_STRIDE          (0xa000c)
-#define MDP_DMA_S_OUT_XY                 (0xa0010)
-
-#ifdef CONFIG_MSM_MDP40
-#define MDP_LCDC_EN                      (0xc0000)
-#define MDP_LCDC_HSYNC_CTL               (0xc0004)
-#define MDP_LCDC_VSYNC_PERIOD            (0xc0008)
-#define MDP_LCDC_VSYNC_PULSE_WIDTH       (0xc000c)
-#define MDP_LCDC_DISPLAY_HCTL            (0xc0010)
-#define MDP_LCDC_DISPLAY_V_START         (0xc0014)
-#define MDP_LCDC_DISPLAY_V_END           (0xc0018)
-#define MDP_LCDC_ACTIVE_HCTL             (0xc001c)
-#define MDP_LCDC_ACTIVE_V_START          (0xc0020)
-#define MDP_LCDC_ACTIVE_V_END            (0xc0024)
-#define MDP_LCDC_BORDER_CLR              (0xc0028)
-#define MDP_LCDC_UNDERFLOW_CTL           (0xc002c)
-#define MDP_LCDC_HSYNC_SKEW              (0xc0030)
-#define MDP_LCDC_TEST_CTL                (0xc0034)
-#define MDP_LCDC_CTL_POLARITY            (0xc0038)
-
-#define MDP_DTV_EN                       (0xd0000)
-#define MDP_DTV_HSYNC_CTL                (0xd0004)
-#define MDP_DTV_VSYNC_PERIOD             (0xd0008)
-#define MDP_DTV_VSYNC_PULSE_WIDTH        (0xd000c)
-#define MDP_DTV_DISPLAY_HCTL             (0xd0018)
-#define MDP_DTV_DISPLAY_V_START          (0xd001c)
-#define MDP_DTV_DISPLAY_V_END            (0xd0020)
-#define MDP_DTV_ACTIVE_HCTL              (0xd002c)
-#define MDP_DTV_ACTIVE_V_START           (0xd0030)
-#define MDP_DTV_ACTIVE_V_END             (0xd0038)
-#define MDP_DTV_BORDER_CLR               (0xd0040)
-#define MDP_DTV_UNDERFLOW_CTL            (0xd0044)
-#define MDP_DTV_HSYNC_SKEW               (0xd0048)
-#define MDP_DTV_CTL_POLARITY             (0xd0050)
-#else
 #define MDP_LCDC_EN                      (0xe0000)
 #define MDP_LCDC_HSYNC_CTL               (0xe0004)
 #define MDP_LCDC_VSYNC_PERIOD            (0xe0008)
@@ -437,7 +250,6 @@
 #define MDP_LCDC_HSYNC_SKEW              (0xe0030)
 #define MDP_LCDC_TEST_CTL                (0xe0034)
 #define MDP_LCDC_CTL_POLARITY            (0xe0038)
-#endif
 
 #define MDP_PPP_SCALE_STATUS             (0x50000)
 #define MDP_PPP_BLEND_STATUS             (0x70000)
@@ -449,31 +261,15 @@
 #define DL0_ROI_DONE			(1<<0)
 #define TV_OUT_DMA3_DONE		(1<<6)
 #define TV_ENC_UNDERRUN			(1<<7)
-#define TV_OUT_FRAME_START		(1<<13)
-#define MDP_HIST_DONE       	(1<<20)
 
 #ifdef CONFIG_MSM_MDP22
 #define MDP_DMA_P_DONE			(1 << 2)
-#define MDP_DMA_S_DONE			(1 << 3)
 #else /* CONFIG_MSM_MDP31 */
-
-#ifdef CONFIG_MSM_MDP40
-#define MDP_DMA_P_DONE			(1 << 4)
-#else
 #define MDP_DMA_P_DONE			(1 << 14)
-#endif
-
-#define MDP_DMA_S_DONE			(1 << 2)
 #define MDP_LCDC_UNDERFLOW		(1 << 16)
-
-#ifdef CONFIG_MSM_MDP40
-#define MDP_LCDC_FRAME_START		(1 << 7)
-#else
 #define MDP_LCDC_FRAME_START		(1 << 15)
 #endif
 
-#endif
-
 #define MDP_TOP_LUMA       16
 #define MDP_TOP_CHROMA     0
 #define MDP_BOTTOM_LUMA    19
@@ -497,15 +293,9 @@
 	(((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
 
 /* MDP_SYNC_CONFIG_0/1/2 */
-#if defined(CONFIG_MSM_MDP30)
-#define MDP_SYNCFG_HGT_LOC 21
-#define MDP_SYNCFG_VSYNC_EXT_EN (1<<20)
-#define MDP_SYNCFG_VSYNC_INT_EN (1<<19)
-#else
 #define MDP_SYNCFG_HGT_LOC 22
 #define MDP_SYNCFG_VSYNC_EXT_EN (1<<21)
 #define MDP_SYNCFG_VSYNC_INT_EN (1<<20)
-#endif
 
 /* MDP_SYNC_THRESH_0 */
 #define MDP_PRIM_BELOW_LOC 0
@@ -518,11 +308,11 @@
 /* MDP_VSYNC_CTRL */
 #define DISP0_VSYNC_MAP_VSYNC0 0
 #define DISP0_VSYNC_MAP_VSYNC1 (1<<0)
-#define DISP0_VSYNC_MAP_VSYNC2 (1<<0)|(1<<1)
+#define DISP0_VSYNC_MAP_VSYNC2 ((1<<0)|(1<<1))
 
 #define DISP1_VSYNC_MAP_VSYNC0 0
 #define DISP1_VSYNC_MAP_VSYNC1 (1<<2)
-#define DISP1_VSYNC_MAP_VSYNC2 (1<<2)|(1<<3)
+#define DISP1_VSYNC_MAP_VSYNC2 ((1<<2)|(1<<3))
 
 #define PRIMARY_LCD_SYNC_EN (1<<4)
 #define PRIMARY_LCD_SYNC_DISABLE 0
@@ -953,32 +743,13 @@
 #define DMA_IBUF_FORMAT_MASK (1 << 20)
 #define DMA_IBUF_NONCONTIGUOUS (1<<21)
 
-#elif defined(CONFIG_MSM_MDP30)
-
-#define DMA_OUT_SEL_AHB  0
-#define DMA_OUT_SEL_MDDI (1<<19)
-#define DMA_AHBM_LCD_SEL_PRIMARY 0
-#define DMA_AHBM_LCD_SEL_SECONDARY (0)
-#define DMA_IBUF_C3ALPHA_EN (0)
-#define DMA_DITHER_EN (1<<24)
-
-#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
-#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY (0)
-#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL (0)
-
-#define DMA_IBUF_FORMAT_MASK (1 << 20)
-#define DMA_IBUF_FORMAT_RGB565 (1<<25)
-#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 (1<<26)
-#define DMA_IBUF_NONCONTIGUOUS (0)
-
-#else /* CONFIG_MSM_MDP31 | CONFIG_MSM_MDP302 */
+#else /* CONFIG_MSM_MDP31 */
 
 #define DMA_OUT_SEL_AHB				(0 << 19)
 #define DMA_OUT_SEL_MDDI			(1 << 19)
 #define DMA_OUT_SEL_LCDC			(2 << 19)
 #define DMA_OUT_SEL_LCDC_MDDI			(3 << 19)
 #define DMA_DITHER_EN				(1 << 24)
-#define DMA_DEFLKR_EN				(1 << 24)	/* dma_e */
 #define DMA_IBUF_FORMAT_RGB888			(0 << 25)
 #define DMA_IBUF_FORMAT_RGB565			(1 << 25)
 #define DMA_IBUF_FORMAT_XRGB8888		(2 << 25)
@@ -991,9 +762,7 @@
 #endif
 
 /* MDDI REGISTER ? */
-#define MDDI_VDO_PACKET_DESC_RGB565  0x5565
-#define MDDI_VDO_PACKET_DESC_RGB666  0x5666
-#define MDDI_VDO_PACKET_DESC_RGB888  0x5888
+#define MDDI_VDO_PACKET_DESC  0x5666
 #define MDDI_VDO_PACKET_PRIM  0xC3
 #define MDDI_VDO_PACKET_SECD  0xC0
 
diff --git a/drivers/video/msm/mdp_hw40.c b/drivers/video/msm/mdp_hw40.c
new file mode 100644
index 0000000..a642c9b
--- /dev/null
+++ b/drivers/video/msm/mdp_hw40.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Dima Zavin <dima@android.com>
+ *
+ * Based on code from Code Aurora Forum.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include "mdp_hw.h"
+
+static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride,
+			    uint32_t width, uint32_t height, uint32_t x,
+			    uint32_t y)
+{
+	struct mdp_info *mdp = priv;
+	uint32_t dma2_cfg;
+	uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */
+
+	dma2_cfg = DMA_PACK_TIGHT |
+		DMA_PACK_ALIGN_LSB;
+
+	dma2_cfg |= mdp->dma_format;
+	dma2_cfg |= mdp->dma_pack_pattern;
+	dma2_cfg |= DMA_DITHER_EN;
+
+	/* 666 18BPP */
+	dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+
+	/* setup size, address, and stride */
+	mdp_writel(mdp, (height << 16) | (width), MDP_DMA_P_SIZE);
+	mdp_writel(mdp, addr, MDP_DMA_P_IBUF_ADDR);
+	mdp_writel(mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE);
+
+	/* set y & x offset and MDDI transaction parameters */
+	mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY);
+	mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL);
+	mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM,
+		   MDP_MDDI_PARAM);
+
+	mdp_writel(mdp, 0x1, MDP_MDDI_DATA_XFR);
+	mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG);
+	mdp_writel(mdp, 0, MDP_DMA_P_START);
+}
+
+int mdp_hw_init(struct mdp_info *mdp)
+{
+	int ret;
+
+	ret = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp,
+				  MDP_DMA_P_DONE, mdp_dma_to_mddi);
+	if (ret)
+		return ret;
+
+	mdp_writel(mdp, 0, MDP_INTR_ENABLE);
+	mdp_writel(mdp, 0, MDP_DMA_P_HIST_INTR_ENABLE);
+
+	/* XXX: why set this? QCT says it should be > mdp_pclk,
+	 * but they never set the clkrate of pclk */
+	clk_set_rate(mdp->clk, 122880000); /* 122.88 Mhz */
+	pr_info("%s: mdp_clk=%lu\n", __func__, clk_get_rate(mdp->clk));
+
+	/* TODO: Configure the VG/RGB pipes fetch data */
+
+	/* this should work for any mdp_clk freq. 
+	 * TODO: use different value for mdp_clk freqs >= 90Mhz */
+	mdp_writel(mdp, 0x27, MDP_DMA_P_FETCH_CFG); /* 8 bytes-burst x 8 req */
+
+	mdp_writel(mdp, 0x3, MDP_EBI2_PORTMAP_MODE);
+
+	/* 3 pending requests */
+	mdp_writel(mdp, 0x02222, MDP_MAX_RD_PENDING_CMD_CONFIG);
+
+	/* no overlay processing, sw controls everything */
+	mdp_writel(mdp, 0, MDP_LAYERMIXER_IN_CFG);
+	mdp_writel(mdp, 1 << 3, MDP_OVERLAYPROC0_CFG);
+	mdp_writel(mdp, 1 << 3, MDP_OVERLAYPROC1_CFG);
+
+	/* XXX: HACK! hardcode to do mddi on primary */
+	mdp_writel(mdp, 0x2, MDP_DISP_INTF_SEL);
+	return 0;
+}
+
diff --git a/drivers/video/msm/mdp_hw_init.c b/drivers/video/msm/mdp_hw_init.c
new file mode 100644
index 0000000..ff3ad41
--- /dev/null
+++ b/drivers/video/msm/mdp_hw_init.c
@@ -0,0 +1,714 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "mdp.h"
+
+/* mdp primary csc limit vector */
+uint32 mdp_plv[] = { 0x10, 0xeb, 0x10, 0xf0 };
+
+/* Color Coefficient matrix for YUV -> RGB */
+struct mdp_ccs mdp_ccs_yuv2rgb = {
+	MDP_CCS_YUV2RGB,
+	{
+		0x254,
+		0x000,
+		0x331,
+		0x254,
+		0xff38,
+		0xfe61,
+		0x254,
+		0x409,
+		0x000,
+	},
+	{
+#ifdef CONFIG_FB_MSM_MDP31
+		0x1f0,
+		0x180,
+		0x180
+#else
+		0x10,
+		0x80,
+		0x80
+#endif
+	}
+};
+
+/* Color Coefficient matrix for RGB -> YUV */
+struct mdp_ccs mdp_ccs_rgb2yuv = {
+	MDP_CCS_RGB2YUV,
+	{
+		0x83,
+		0x102,
+		0x32,
+		0xffb5,
+		0xff6c,
+		0xe1,
+		0xe1,
+		0xff45,
+		0xffdc,
+	},
+#ifdef CONFIG_FB_MSM_MDP31
+	{
+		0x10,
+		0x80,
+		0x80
+	}
+#endif
+};
+
+static void mdp_load_lut_param(void)
+{
+	outpdw(MDP_BASE + 0x40800, 0x0);
+	outpdw(MDP_BASE + 0x40804, 0x151515);
+	outpdw(MDP_BASE + 0x40808, 0x1d1d1d);
+	outpdw(MDP_BASE + 0x4080c, 0x232323);
+	outpdw(MDP_BASE + 0x40810, 0x272727);
+	outpdw(MDP_BASE + 0x40814, 0x2b2b2b);
+	outpdw(MDP_BASE + 0x40818, 0x2f2f2f);
+	outpdw(MDP_BASE + 0x4081c, 0x333333);
+	outpdw(MDP_BASE + 0x40820, 0x363636);
+	outpdw(MDP_BASE + 0x40824, 0x393939);
+	outpdw(MDP_BASE + 0x40828, 0x3b3b3b);
+	outpdw(MDP_BASE + 0x4082c, 0x3e3e3e);
+	outpdw(MDP_BASE + 0x40830, 0x404040);
+	outpdw(MDP_BASE + 0x40834, 0x434343);
+	outpdw(MDP_BASE + 0x40838, 0x454545);
+	outpdw(MDP_BASE + 0x4083c, 0x474747);
+	outpdw(MDP_BASE + 0x40840, 0x494949);
+	outpdw(MDP_BASE + 0x40844, 0x4b4b4b);
+	outpdw(MDP_BASE + 0x40848, 0x4d4d4d);
+	outpdw(MDP_BASE + 0x4084c, 0x4f4f4f);
+	outpdw(MDP_BASE + 0x40850, 0x515151);
+	outpdw(MDP_BASE + 0x40854, 0x535353);
+	outpdw(MDP_BASE + 0x40858, 0x555555);
+	outpdw(MDP_BASE + 0x4085c, 0x565656);
+	outpdw(MDP_BASE + 0x40860, 0x585858);
+	outpdw(MDP_BASE + 0x40864, 0x5a5a5a);
+	outpdw(MDP_BASE + 0x40868, 0x5b5b5b);
+	outpdw(MDP_BASE + 0x4086c, 0x5d5d5d);
+	outpdw(MDP_BASE + 0x40870, 0x5e5e5e);
+	outpdw(MDP_BASE + 0x40874, 0x606060);
+	outpdw(MDP_BASE + 0x40878, 0x616161);
+	outpdw(MDP_BASE + 0x4087c, 0x636363);
+	outpdw(MDP_BASE + 0x40880, 0x646464);
+	outpdw(MDP_BASE + 0x40884, 0x666666);
+	outpdw(MDP_BASE + 0x40888, 0x676767);
+	outpdw(MDP_BASE + 0x4088c, 0x686868);
+	outpdw(MDP_BASE + 0x40890, 0x6a6a6a);
+	outpdw(MDP_BASE + 0x40894, 0x6b6b6b);
+	outpdw(MDP_BASE + 0x40898, 0x6c6c6c);
+	outpdw(MDP_BASE + 0x4089c, 0x6e6e6e);
+	outpdw(MDP_BASE + 0x408a0, 0x6f6f6f);
+	outpdw(MDP_BASE + 0x408a4, 0x707070);
+	outpdw(MDP_BASE + 0x408a8, 0x717171);
+	outpdw(MDP_BASE + 0x408ac, 0x727272);
+	outpdw(MDP_BASE + 0x408b0, 0x747474);
+	outpdw(MDP_BASE + 0x408b4, 0x757575);
+	outpdw(MDP_BASE + 0x408b8, 0x767676);
+	outpdw(MDP_BASE + 0x408bc, 0x777777);
+	outpdw(MDP_BASE + 0x408c0, 0x787878);
+	outpdw(MDP_BASE + 0x408c4, 0x797979);
+	outpdw(MDP_BASE + 0x408c8, 0x7a7a7a);
+	outpdw(MDP_BASE + 0x408cc, 0x7c7c7c);
+	outpdw(MDP_BASE + 0x408d0, 0x7d7d7d);
+	outpdw(MDP_BASE + 0x408d4, 0x7e7e7e);
+	outpdw(MDP_BASE + 0x408d8, 0x7f7f7f);
+	outpdw(MDP_BASE + 0x408dc, 0x808080);
+	outpdw(MDP_BASE + 0x408e0, 0x818181);
+	outpdw(MDP_BASE + 0x408e4, 0x828282);
+	outpdw(MDP_BASE + 0x408e8, 0x838383);
+	outpdw(MDP_BASE + 0x408ec, 0x848484);
+	outpdw(MDP_BASE + 0x408f0, 0x858585);
+	outpdw(MDP_BASE + 0x408f4, 0x868686);
+	outpdw(MDP_BASE + 0x408f8, 0x878787);
+	outpdw(MDP_BASE + 0x408fc, 0x888888);
+	outpdw(MDP_BASE + 0x40900, 0x898989);
+	outpdw(MDP_BASE + 0x40904, 0x8a8a8a);
+	outpdw(MDP_BASE + 0x40908, 0x8b8b8b);
+	outpdw(MDP_BASE + 0x4090c, 0x8c8c8c);
+	outpdw(MDP_BASE + 0x40910, 0x8d8d8d);
+	outpdw(MDP_BASE + 0x40914, 0x8e8e8e);
+	outpdw(MDP_BASE + 0x40918, 0x8f8f8f);
+	outpdw(MDP_BASE + 0x4091c, 0x8f8f8f);
+	outpdw(MDP_BASE + 0x40920, 0x909090);
+	outpdw(MDP_BASE + 0x40924, 0x919191);
+	outpdw(MDP_BASE + 0x40928, 0x929292);
+	outpdw(MDP_BASE + 0x4092c, 0x939393);
+	outpdw(MDP_BASE + 0x40930, 0x949494);
+	outpdw(MDP_BASE + 0x40934, 0x959595);
+	outpdw(MDP_BASE + 0x40938, 0x969696);
+	outpdw(MDP_BASE + 0x4093c, 0x969696);
+	outpdw(MDP_BASE + 0x40940, 0x979797);
+	outpdw(MDP_BASE + 0x40944, 0x989898);
+	outpdw(MDP_BASE + 0x40948, 0x999999);
+	outpdw(MDP_BASE + 0x4094c, 0x9a9a9a);
+	outpdw(MDP_BASE + 0x40950, 0x9b9b9b);
+	outpdw(MDP_BASE + 0x40954, 0x9c9c9c);
+	outpdw(MDP_BASE + 0x40958, 0x9c9c9c);
+	outpdw(MDP_BASE + 0x4095c, 0x9d9d9d);
+	outpdw(MDP_BASE + 0x40960, 0x9e9e9e);
+	outpdw(MDP_BASE + 0x40964, 0x9f9f9f);
+	outpdw(MDP_BASE + 0x40968, 0xa0a0a0);
+	outpdw(MDP_BASE + 0x4096c, 0xa0a0a0);
+	outpdw(MDP_BASE + 0x40970, 0xa1a1a1);
+	outpdw(MDP_BASE + 0x40974, 0xa2a2a2);
+	outpdw(MDP_BASE + 0x40978, 0xa3a3a3);
+	outpdw(MDP_BASE + 0x4097c, 0xa4a4a4);
+	outpdw(MDP_BASE + 0x40980, 0xa4a4a4);
+	outpdw(MDP_BASE + 0x40984, 0xa5a5a5);
+	outpdw(MDP_BASE + 0x40988, 0xa6a6a6);
+	outpdw(MDP_BASE + 0x4098c, 0xa7a7a7);
+	outpdw(MDP_BASE + 0x40990, 0xa7a7a7);
+	outpdw(MDP_BASE + 0x40994, 0xa8a8a8);
+	outpdw(MDP_BASE + 0x40998, 0xa9a9a9);
+	outpdw(MDP_BASE + 0x4099c, 0xaaaaaa);
+	outpdw(MDP_BASE + 0x409a0, 0xaaaaaa);
+	outpdw(MDP_BASE + 0x409a4, 0xababab);
+	outpdw(MDP_BASE + 0x409a8, 0xacacac);
+	outpdw(MDP_BASE + 0x409ac, 0xadadad);
+	outpdw(MDP_BASE + 0x409b0, 0xadadad);
+	outpdw(MDP_BASE + 0x409b4, 0xaeaeae);
+	outpdw(MDP_BASE + 0x409b8, 0xafafaf);
+	outpdw(MDP_BASE + 0x409bc, 0xafafaf);
+	outpdw(MDP_BASE + 0x409c0, 0xb0b0b0);
+	outpdw(MDP_BASE + 0x409c4, 0xb1b1b1);
+	outpdw(MDP_BASE + 0x409c8, 0xb2b2b2);
+	outpdw(MDP_BASE + 0x409cc, 0xb2b2b2);
+	outpdw(MDP_BASE + 0x409d0, 0xb3b3b3);
+	outpdw(MDP_BASE + 0x409d4, 0xb4b4b4);
+	outpdw(MDP_BASE + 0x409d8, 0xb4b4b4);
+	outpdw(MDP_BASE + 0x409dc, 0xb5b5b5);
+	outpdw(MDP_BASE + 0x409e0, 0xb6b6b6);
+	outpdw(MDP_BASE + 0x409e4, 0xb6b6b6);
+	outpdw(MDP_BASE + 0x409e8, 0xb7b7b7);
+	outpdw(MDP_BASE + 0x409ec, 0xb8b8b8);
+	outpdw(MDP_BASE + 0x409f0, 0xb8b8b8);
+	outpdw(MDP_BASE + 0x409f4, 0xb9b9b9);
+	outpdw(MDP_BASE + 0x409f8, 0xbababa);
+	outpdw(MDP_BASE + 0x409fc, 0xbababa);
+	outpdw(MDP_BASE + 0x40a00, 0xbbbbbb);
+	outpdw(MDP_BASE + 0x40a04, 0xbcbcbc);
+	outpdw(MDP_BASE + 0x40a08, 0xbcbcbc);
+	outpdw(MDP_BASE + 0x40a0c, 0xbdbdbd);
+	outpdw(MDP_BASE + 0x40a10, 0xbebebe);
+	outpdw(MDP_BASE + 0x40a14, 0xbebebe);
+	outpdw(MDP_BASE + 0x40a18, 0xbfbfbf);
+	outpdw(MDP_BASE + 0x40a1c, 0xc0c0c0);
+	outpdw(MDP_BASE + 0x40a20, 0xc0c0c0);
+	outpdw(MDP_BASE + 0x40a24, 0xc1c1c1);
+	outpdw(MDP_BASE + 0x40a28, 0xc1c1c1);
+	outpdw(MDP_BASE + 0x40a2c, 0xc2c2c2);
+	outpdw(MDP_BASE + 0x40a30, 0xc3c3c3);
+	outpdw(MDP_BASE + 0x40a34, 0xc3c3c3);
+	outpdw(MDP_BASE + 0x40a38, 0xc4c4c4);
+	outpdw(MDP_BASE + 0x40a3c, 0xc5c5c5);
+	outpdw(MDP_BASE + 0x40a40, 0xc5c5c5);
+	outpdw(MDP_BASE + 0x40a44, 0xc6c6c6);
+	outpdw(MDP_BASE + 0x40a48, 0xc6c6c6);
+	outpdw(MDP_BASE + 0x40a4c, 0xc7c7c7);
+	outpdw(MDP_BASE + 0x40a50, 0xc8c8c8);
+	outpdw(MDP_BASE + 0x40a54, 0xc8c8c8);
+	outpdw(MDP_BASE + 0x40a58, 0xc9c9c9);
+	outpdw(MDP_BASE + 0x40a5c, 0xc9c9c9);
+	outpdw(MDP_BASE + 0x40a60, 0xcacaca);
+	outpdw(MDP_BASE + 0x40a64, 0xcbcbcb);
+	outpdw(MDP_BASE + 0x40a68, 0xcbcbcb);
+	outpdw(MDP_BASE + 0x40a6c, 0xcccccc);
+	outpdw(MDP_BASE + 0x40a70, 0xcccccc);
+	outpdw(MDP_BASE + 0x40a74, 0xcdcdcd);
+	outpdw(MDP_BASE + 0x40a78, 0xcecece);
+	outpdw(MDP_BASE + 0x40a7c, 0xcecece);
+	outpdw(MDP_BASE + 0x40a80, 0xcfcfcf);
+	outpdw(MDP_BASE + 0x40a84, 0xcfcfcf);
+	outpdw(MDP_BASE + 0x40a88, 0xd0d0d0);
+	outpdw(MDP_BASE + 0x40a8c, 0xd0d0d0);
+	outpdw(MDP_BASE + 0x40a90, 0xd1d1d1);
+	outpdw(MDP_BASE + 0x40a94, 0xd2d2d2);
+	outpdw(MDP_BASE + 0x40a98, 0xd2d2d2);
+	outpdw(MDP_BASE + 0x40a9c, 0xd3d3d3);
+	outpdw(MDP_BASE + 0x40aa0, 0xd3d3d3);
+	outpdw(MDP_BASE + 0x40aa4, 0xd4d4d4);
+	outpdw(MDP_BASE + 0x40aa8, 0xd4d4d4);
+	outpdw(MDP_BASE + 0x40aac, 0xd5d5d5);
+	outpdw(MDP_BASE + 0x40ab0, 0xd6d6d6);
+	outpdw(MDP_BASE + 0x40ab4, 0xd6d6d6);
+	outpdw(MDP_BASE + 0x40ab8, 0xd7d7d7);
+	outpdw(MDP_BASE + 0x40abc, 0xd7d7d7);
+	outpdw(MDP_BASE + 0x40ac0, 0xd8d8d8);
+	outpdw(MDP_BASE + 0x40ac4, 0xd8d8d8);
+	outpdw(MDP_BASE + 0x40ac8, 0xd9d9d9);
+	outpdw(MDP_BASE + 0x40acc, 0xd9d9d9);
+	outpdw(MDP_BASE + 0x40ad0, 0xdadada);
+	outpdw(MDP_BASE + 0x40ad4, 0xdbdbdb);
+	outpdw(MDP_BASE + 0x40ad8, 0xdbdbdb);
+	outpdw(MDP_BASE + 0x40adc, 0xdcdcdc);
+	outpdw(MDP_BASE + 0x40ae0, 0xdcdcdc);
+	outpdw(MDP_BASE + 0x40ae4, 0xdddddd);
+	outpdw(MDP_BASE + 0x40ae8, 0xdddddd);
+	outpdw(MDP_BASE + 0x40aec, 0xdedede);
+	outpdw(MDP_BASE + 0x40af0, 0xdedede);
+	outpdw(MDP_BASE + 0x40af4, 0xdfdfdf);
+	outpdw(MDP_BASE + 0x40af8, 0xdfdfdf);
+	outpdw(MDP_BASE + 0x40afc, 0xe0e0e0);
+	outpdw(MDP_BASE + 0x40b00, 0xe0e0e0);
+	outpdw(MDP_BASE + 0x40b04, 0xe1e1e1);
+	outpdw(MDP_BASE + 0x40b08, 0xe1e1e1);
+	outpdw(MDP_BASE + 0x40b0c, 0xe2e2e2);
+	outpdw(MDP_BASE + 0x40b10, 0xe3e3e3);
+	outpdw(MDP_BASE + 0x40b14, 0xe3e3e3);
+	outpdw(MDP_BASE + 0x40b18, 0xe4e4e4);
+	outpdw(MDP_BASE + 0x40b1c, 0xe4e4e4);
+	outpdw(MDP_BASE + 0x40b20, 0xe5e5e5);
+	outpdw(MDP_BASE + 0x40b24, 0xe5e5e5);
+	outpdw(MDP_BASE + 0x40b28, 0xe6e6e6);
+	outpdw(MDP_BASE + 0x40b2c, 0xe6e6e6);
+	outpdw(MDP_BASE + 0x40b30, 0xe7e7e7);
+	outpdw(MDP_BASE + 0x40b34, 0xe7e7e7);
+	outpdw(MDP_BASE + 0x40b38, 0xe8e8e8);
+	outpdw(MDP_BASE + 0x40b3c, 0xe8e8e8);
+	outpdw(MDP_BASE + 0x40b40, 0xe9e9e9);
+	outpdw(MDP_BASE + 0x40b44, 0xe9e9e9);
+	outpdw(MDP_BASE + 0x40b48, 0xeaeaea);
+	outpdw(MDP_BASE + 0x40b4c, 0xeaeaea);
+	outpdw(MDP_BASE + 0x40b50, 0xebebeb);
+	outpdw(MDP_BASE + 0x40b54, 0xebebeb);
+	outpdw(MDP_BASE + 0x40b58, 0xececec);
+	outpdw(MDP_BASE + 0x40b5c, 0xececec);
+	outpdw(MDP_BASE + 0x40b60, 0xededed);
+	outpdw(MDP_BASE + 0x40b64, 0xededed);
+	outpdw(MDP_BASE + 0x40b68, 0xeeeeee);
+	outpdw(MDP_BASE + 0x40b6c, 0xeeeeee);
+	outpdw(MDP_BASE + 0x40b70, 0xefefef);
+	outpdw(MDP_BASE + 0x40b74, 0xefefef);
+	outpdw(MDP_BASE + 0x40b78, 0xf0f0f0);
+	outpdw(MDP_BASE + 0x40b7c, 0xf0f0f0);
+	outpdw(MDP_BASE + 0x40b80, 0xf1f1f1);
+	outpdw(MDP_BASE + 0x40b84, 0xf1f1f1);
+	outpdw(MDP_BASE + 0x40b88, 0xf2f2f2);
+	outpdw(MDP_BASE + 0x40b8c, 0xf2f2f2);
+	outpdw(MDP_BASE + 0x40b90, 0xf2f2f2);
+	outpdw(MDP_BASE + 0x40b94, 0xf3f3f3);
+	outpdw(MDP_BASE + 0x40b98, 0xf3f3f3);
+	outpdw(MDP_BASE + 0x40b9c, 0xf4f4f4);
+	outpdw(MDP_BASE + 0x40ba0, 0xf4f4f4);
+	outpdw(MDP_BASE + 0x40ba4, 0xf5f5f5);
+	outpdw(MDP_BASE + 0x40ba8, 0xf5f5f5);
+	outpdw(MDP_BASE + 0x40bac, 0xf6f6f6);
+	outpdw(MDP_BASE + 0x40bb0, 0xf6f6f6);
+	outpdw(MDP_BASE + 0x40bb4, 0xf7f7f7);
+	outpdw(MDP_BASE + 0x40bb8, 0xf7f7f7);
+	outpdw(MDP_BASE + 0x40bbc, 0xf8f8f8);
+	outpdw(MDP_BASE + 0x40bc0, 0xf8f8f8);
+	outpdw(MDP_BASE + 0x40bc4, 0xf9f9f9);
+	outpdw(MDP_BASE + 0x40bc8, 0xf9f9f9);
+	outpdw(MDP_BASE + 0x40bcc, 0xfafafa);
+	outpdw(MDP_BASE + 0x40bd0, 0xfafafa);
+	outpdw(MDP_BASE + 0x40bd4, 0xfafafa);
+	outpdw(MDP_BASE + 0x40bd8, 0xfbfbfb);
+	outpdw(MDP_BASE + 0x40bdc, 0xfbfbfb);
+	outpdw(MDP_BASE + 0x40be0, 0xfcfcfc);
+	outpdw(MDP_BASE + 0x40be4, 0xfcfcfc);
+	outpdw(MDP_BASE + 0x40be8, 0xfdfdfd);
+	outpdw(MDP_BASE + 0x40bec, 0xfdfdfd);
+	outpdw(MDP_BASE + 0x40bf0, 0xfefefe);
+	outpdw(MDP_BASE + 0x40bf4, 0xfefefe);
+	outpdw(MDP_BASE + 0x40bf8, 0xffffff);
+	outpdw(MDP_BASE + 0x40bfc, 0xffffff);
+	outpdw(MDP_BASE + 0x40c00, 0x0);
+	outpdw(MDP_BASE + 0x40c04, 0x0);
+	outpdw(MDP_BASE + 0x40c08, 0x0);
+	outpdw(MDP_BASE + 0x40c0c, 0x0);
+	outpdw(MDP_BASE + 0x40c10, 0x0);
+	outpdw(MDP_BASE + 0x40c14, 0x0);
+	outpdw(MDP_BASE + 0x40c18, 0x0);
+	outpdw(MDP_BASE + 0x40c1c, 0x0);
+	outpdw(MDP_BASE + 0x40c20, 0x0);
+	outpdw(MDP_BASE + 0x40c24, 0x0);
+	outpdw(MDP_BASE + 0x40c28, 0x0);
+	outpdw(MDP_BASE + 0x40c2c, 0x0);
+	outpdw(MDP_BASE + 0x40c30, 0x0);
+	outpdw(MDP_BASE + 0x40c34, 0x0);
+	outpdw(MDP_BASE + 0x40c38, 0x0);
+	outpdw(MDP_BASE + 0x40c3c, 0x0);
+	outpdw(MDP_BASE + 0x40c40, 0x10101);
+	outpdw(MDP_BASE + 0x40c44, 0x10101);
+	outpdw(MDP_BASE + 0x40c48, 0x10101);
+	outpdw(MDP_BASE + 0x40c4c, 0x10101);
+	outpdw(MDP_BASE + 0x40c50, 0x10101);
+	outpdw(MDP_BASE + 0x40c54, 0x10101);
+	outpdw(MDP_BASE + 0x40c58, 0x10101);
+	outpdw(MDP_BASE + 0x40c5c, 0x10101);
+	outpdw(MDP_BASE + 0x40c60, 0x10101);
+	outpdw(MDP_BASE + 0x40c64, 0x10101);
+	outpdw(MDP_BASE + 0x40c68, 0x20202);
+	outpdw(MDP_BASE + 0x40c6c, 0x20202);
+	outpdw(MDP_BASE + 0x40c70, 0x20202);
+	outpdw(MDP_BASE + 0x40c74, 0x20202);
+	outpdw(MDP_BASE + 0x40c78, 0x20202);
+	outpdw(MDP_BASE + 0x40c7c, 0x20202);
+	outpdw(MDP_BASE + 0x40c80, 0x30303);
+	outpdw(MDP_BASE + 0x40c84, 0x30303);
+	outpdw(MDP_BASE + 0x40c88, 0x30303);
+	outpdw(MDP_BASE + 0x40c8c, 0x30303);
+	outpdw(MDP_BASE + 0x40c90, 0x30303);
+	outpdw(MDP_BASE + 0x40c94, 0x40404);
+	outpdw(MDP_BASE + 0x40c98, 0x40404);
+	outpdw(MDP_BASE + 0x40c9c, 0x40404);
+	outpdw(MDP_BASE + 0x40ca0, 0x40404);
+	outpdw(MDP_BASE + 0x40ca4, 0x40404);
+	outpdw(MDP_BASE + 0x40ca8, 0x50505);
+	outpdw(MDP_BASE + 0x40cac, 0x50505);
+	outpdw(MDP_BASE + 0x40cb0, 0x50505);
+	outpdw(MDP_BASE + 0x40cb4, 0x50505);
+	outpdw(MDP_BASE + 0x40cb8, 0x60606);
+	outpdw(MDP_BASE + 0x40cbc, 0x60606);
+	outpdw(MDP_BASE + 0x40cc0, 0x60606);
+	outpdw(MDP_BASE + 0x40cc4, 0x70707);
+	outpdw(MDP_BASE + 0x40cc8, 0x70707);
+	outpdw(MDP_BASE + 0x40ccc, 0x70707);
+	outpdw(MDP_BASE + 0x40cd0, 0x70707);
+	outpdw(MDP_BASE + 0x40cd4, 0x80808);
+	outpdw(MDP_BASE + 0x40cd8, 0x80808);
+	outpdw(MDP_BASE + 0x40cdc, 0x80808);
+	outpdw(MDP_BASE + 0x40ce0, 0x90909);
+	outpdw(MDP_BASE + 0x40ce4, 0x90909);
+	outpdw(MDP_BASE + 0x40ce8, 0xa0a0a);
+	outpdw(MDP_BASE + 0x40cec, 0xa0a0a);
+	outpdw(MDP_BASE + 0x40cf0, 0xa0a0a);
+	outpdw(MDP_BASE + 0x40cf4, 0xb0b0b);
+	outpdw(MDP_BASE + 0x40cf8, 0xb0b0b);
+	outpdw(MDP_BASE + 0x40cfc, 0xb0b0b);
+	outpdw(MDP_BASE + 0x40d00, 0xc0c0c);
+	outpdw(MDP_BASE + 0x40d04, 0xc0c0c);
+	outpdw(MDP_BASE + 0x40d08, 0xd0d0d);
+	outpdw(MDP_BASE + 0x40d0c, 0xd0d0d);
+	outpdw(MDP_BASE + 0x40d10, 0xe0e0e);
+	outpdw(MDP_BASE + 0x40d14, 0xe0e0e);
+	outpdw(MDP_BASE + 0x40d18, 0xe0e0e);
+	outpdw(MDP_BASE + 0x40d1c, 0xf0f0f);
+	outpdw(MDP_BASE + 0x40d20, 0xf0f0f);
+	outpdw(MDP_BASE + 0x40d24, 0x101010);
+	outpdw(MDP_BASE + 0x40d28, 0x101010);
+	outpdw(MDP_BASE + 0x40d2c, 0x111111);
+	outpdw(MDP_BASE + 0x40d30, 0x111111);
+	outpdw(MDP_BASE + 0x40d34, 0x121212);
+	outpdw(MDP_BASE + 0x40d38, 0x121212);
+	outpdw(MDP_BASE + 0x40d3c, 0x131313);
+	outpdw(MDP_BASE + 0x40d40, 0x131313);
+	outpdw(MDP_BASE + 0x40d44, 0x141414);
+	outpdw(MDP_BASE + 0x40d48, 0x151515);
+	outpdw(MDP_BASE + 0x40d4c, 0x151515);
+	outpdw(MDP_BASE + 0x40d50, 0x161616);
+	outpdw(MDP_BASE + 0x40d54, 0x161616);
+	outpdw(MDP_BASE + 0x40d58, 0x171717);
+	outpdw(MDP_BASE + 0x40d5c, 0x171717);
+	outpdw(MDP_BASE + 0x40d60, 0x181818);
+	outpdw(MDP_BASE + 0x40d64, 0x191919);
+	outpdw(MDP_BASE + 0x40d68, 0x191919);
+	outpdw(MDP_BASE + 0x40d6c, 0x1a1a1a);
+	outpdw(MDP_BASE + 0x40d70, 0x1b1b1b);
+	outpdw(MDP_BASE + 0x40d74, 0x1b1b1b);
+	outpdw(MDP_BASE + 0x40d78, 0x1c1c1c);
+	outpdw(MDP_BASE + 0x40d7c, 0x1c1c1c);
+	outpdw(MDP_BASE + 0x40d80, 0x1d1d1d);
+	outpdw(MDP_BASE + 0x40d84, 0x1e1e1e);
+	outpdw(MDP_BASE + 0x40d88, 0x1f1f1f);
+	outpdw(MDP_BASE + 0x40d8c, 0x1f1f1f);
+	outpdw(MDP_BASE + 0x40d90, 0x202020);
+	outpdw(MDP_BASE + 0x40d94, 0x212121);
+	outpdw(MDP_BASE + 0x40d98, 0x212121);
+	outpdw(MDP_BASE + 0x40d9c, 0x222222);
+	outpdw(MDP_BASE + 0x40da0, 0x232323);
+	outpdw(MDP_BASE + 0x40da4, 0x242424);
+	outpdw(MDP_BASE + 0x40da8, 0x242424);
+	outpdw(MDP_BASE + 0x40dac, 0x252525);
+	outpdw(MDP_BASE + 0x40db0, 0x262626);
+	outpdw(MDP_BASE + 0x40db4, 0x272727);
+	outpdw(MDP_BASE + 0x40db8, 0x272727);
+	outpdw(MDP_BASE + 0x40dbc, 0x282828);
+	outpdw(MDP_BASE + 0x40dc0, 0x292929);
+	outpdw(MDP_BASE + 0x40dc4, 0x2a2a2a);
+	outpdw(MDP_BASE + 0x40dc8, 0x2b2b2b);
+	outpdw(MDP_BASE + 0x40dcc, 0x2c2c2c);
+	outpdw(MDP_BASE + 0x40dd0, 0x2c2c2c);
+	outpdw(MDP_BASE + 0x40dd4, 0x2d2d2d);
+	outpdw(MDP_BASE + 0x40dd8, 0x2e2e2e);
+	outpdw(MDP_BASE + 0x40ddc, 0x2f2f2f);
+	outpdw(MDP_BASE + 0x40de0, 0x303030);
+	outpdw(MDP_BASE + 0x40de4, 0x313131);
+	outpdw(MDP_BASE + 0x40de8, 0x323232);
+	outpdw(MDP_BASE + 0x40dec, 0x333333);
+	outpdw(MDP_BASE + 0x40df0, 0x333333);
+	outpdw(MDP_BASE + 0x40df4, 0x343434);
+	outpdw(MDP_BASE + 0x40df8, 0x353535);
+	outpdw(MDP_BASE + 0x40dfc, 0x363636);
+	outpdw(MDP_BASE + 0x40e00, 0x373737);
+	outpdw(MDP_BASE + 0x40e04, 0x383838);
+	outpdw(MDP_BASE + 0x40e08, 0x393939);
+	outpdw(MDP_BASE + 0x40e0c, 0x3a3a3a);
+	outpdw(MDP_BASE + 0x40e10, 0x3b3b3b);
+	outpdw(MDP_BASE + 0x40e14, 0x3c3c3c);
+	outpdw(MDP_BASE + 0x40e18, 0x3d3d3d);
+	outpdw(MDP_BASE + 0x40e1c, 0x3e3e3e);
+	outpdw(MDP_BASE + 0x40e20, 0x3f3f3f);
+	outpdw(MDP_BASE + 0x40e24, 0x404040);
+	outpdw(MDP_BASE + 0x40e28, 0x414141);
+	outpdw(MDP_BASE + 0x40e2c, 0x424242);
+	outpdw(MDP_BASE + 0x40e30, 0x434343);
+	outpdw(MDP_BASE + 0x40e34, 0x444444);
+	outpdw(MDP_BASE + 0x40e38, 0x464646);
+	outpdw(MDP_BASE + 0x40e3c, 0x474747);
+	outpdw(MDP_BASE + 0x40e40, 0x484848);
+	outpdw(MDP_BASE + 0x40e44, 0x494949);
+	outpdw(MDP_BASE + 0x40e48, 0x4a4a4a);
+	outpdw(MDP_BASE + 0x40e4c, 0x4b4b4b);
+	outpdw(MDP_BASE + 0x40e50, 0x4c4c4c);
+	outpdw(MDP_BASE + 0x40e54, 0x4d4d4d);
+	outpdw(MDP_BASE + 0x40e58, 0x4f4f4f);
+	outpdw(MDP_BASE + 0x40e5c, 0x505050);
+	outpdw(MDP_BASE + 0x40e60, 0x515151);
+	outpdw(MDP_BASE + 0x40e64, 0x525252);
+	outpdw(MDP_BASE + 0x40e68, 0x535353);
+	outpdw(MDP_BASE + 0x40e6c, 0x545454);
+	outpdw(MDP_BASE + 0x40e70, 0x565656);
+	outpdw(MDP_BASE + 0x40e74, 0x575757);
+	outpdw(MDP_BASE + 0x40e78, 0x585858);
+	outpdw(MDP_BASE + 0x40e7c, 0x595959);
+	outpdw(MDP_BASE + 0x40e80, 0x5b5b5b);
+	outpdw(MDP_BASE + 0x40e84, 0x5c5c5c);
+	outpdw(MDP_BASE + 0x40e88, 0x5d5d5d);
+	outpdw(MDP_BASE + 0x40e8c, 0x5e5e5e);
+	outpdw(MDP_BASE + 0x40e90, 0x606060);
+	outpdw(MDP_BASE + 0x40e94, 0x616161);
+	outpdw(MDP_BASE + 0x40e98, 0x626262);
+	outpdw(MDP_BASE + 0x40e9c, 0x646464);
+	outpdw(MDP_BASE + 0x40ea0, 0x656565);
+	outpdw(MDP_BASE + 0x40ea4, 0x666666);
+	outpdw(MDP_BASE + 0x40ea8, 0x686868);
+	outpdw(MDP_BASE + 0x40eac, 0x696969);
+	outpdw(MDP_BASE + 0x40eb0, 0x6a6a6a);
+	outpdw(MDP_BASE + 0x40eb4, 0x6c6c6c);
+	outpdw(MDP_BASE + 0x40eb8, 0x6d6d6d);
+	outpdw(MDP_BASE + 0x40ebc, 0x6f6f6f);
+	outpdw(MDP_BASE + 0x40ec0, 0x707070);
+	outpdw(MDP_BASE + 0x40ec4, 0x717171);
+	outpdw(MDP_BASE + 0x40ec8, 0x737373);
+	outpdw(MDP_BASE + 0x40ecc, 0x747474);
+	outpdw(MDP_BASE + 0x40ed0, 0x767676);
+	outpdw(MDP_BASE + 0x40ed4, 0x777777);
+	outpdw(MDP_BASE + 0x40ed8, 0x797979);
+	outpdw(MDP_BASE + 0x40edc, 0x7a7a7a);
+	outpdw(MDP_BASE + 0x40ee0, 0x7c7c7c);
+	outpdw(MDP_BASE + 0x40ee4, 0x7d7d7d);
+	outpdw(MDP_BASE + 0x40ee8, 0x7f7f7f);
+	outpdw(MDP_BASE + 0x40eec, 0x808080);
+	outpdw(MDP_BASE + 0x40ef0, 0x828282);
+	outpdw(MDP_BASE + 0x40ef4, 0x838383);
+	outpdw(MDP_BASE + 0x40ef8, 0x858585);
+	outpdw(MDP_BASE + 0x40efc, 0x868686);
+	outpdw(MDP_BASE + 0x40f00, 0x888888);
+	outpdw(MDP_BASE + 0x40f04, 0x898989);
+	outpdw(MDP_BASE + 0x40f08, 0x8b8b8b);
+	outpdw(MDP_BASE + 0x40f0c, 0x8d8d8d);
+	outpdw(MDP_BASE + 0x40f10, 0x8e8e8e);
+	outpdw(MDP_BASE + 0x40f14, 0x909090);
+	outpdw(MDP_BASE + 0x40f18, 0x919191);
+	outpdw(MDP_BASE + 0x40f1c, 0x939393);
+	outpdw(MDP_BASE + 0x40f20, 0x959595);
+	outpdw(MDP_BASE + 0x40f24, 0x969696);
+	outpdw(MDP_BASE + 0x40f28, 0x989898);
+	outpdw(MDP_BASE + 0x40f2c, 0x9a9a9a);
+	outpdw(MDP_BASE + 0x40f30, 0x9b9b9b);
+	outpdw(MDP_BASE + 0x40f34, 0x9d9d9d);
+	outpdw(MDP_BASE + 0x40f38, 0x9f9f9f);
+	outpdw(MDP_BASE + 0x40f3c, 0xa1a1a1);
+	outpdw(MDP_BASE + 0x40f40, 0xa2a2a2);
+	outpdw(MDP_BASE + 0x40f44, 0xa4a4a4);
+	outpdw(MDP_BASE + 0x40f48, 0xa6a6a6);
+	outpdw(MDP_BASE + 0x40f4c, 0xa7a7a7);
+	outpdw(MDP_BASE + 0x40f50, 0xa9a9a9);
+	outpdw(MDP_BASE + 0x40f54, 0xababab);
+	outpdw(MDP_BASE + 0x40f58, 0xadadad);
+	outpdw(MDP_BASE + 0x40f5c, 0xafafaf);
+	outpdw(MDP_BASE + 0x40f60, 0xb0b0b0);
+	outpdw(MDP_BASE + 0x40f64, 0xb2b2b2);
+	outpdw(MDP_BASE + 0x40f68, 0xb4b4b4);
+	outpdw(MDP_BASE + 0x40f6c, 0xb6b6b6);
+	outpdw(MDP_BASE + 0x40f70, 0xb8b8b8);
+	outpdw(MDP_BASE + 0x40f74, 0xbababa);
+	outpdw(MDP_BASE + 0x40f78, 0xbbbbbb);
+	outpdw(MDP_BASE + 0x40f7c, 0xbdbdbd);
+	outpdw(MDP_BASE + 0x40f80, 0xbfbfbf);
+	outpdw(MDP_BASE + 0x40f84, 0xc1c1c1);
+	outpdw(MDP_BASE + 0x40f88, 0xc3c3c3);
+	outpdw(MDP_BASE + 0x40f8c, 0xc5c5c5);
+	outpdw(MDP_BASE + 0x40f90, 0xc7c7c7);
+	outpdw(MDP_BASE + 0x40f94, 0xc9c9c9);
+	outpdw(MDP_BASE + 0x40f98, 0xcbcbcb);
+	outpdw(MDP_BASE + 0x40f9c, 0xcdcdcd);
+	outpdw(MDP_BASE + 0x40fa0, 0xcfcfcf);
+	outpdw(MDP_BASE + 0x40fa4, 0xd1d1d1);
+	outpdw(MDP_BASE + 0x40fa8, 0xd3d3d3);
+	outpdw(MDP_BASE + 0x40fac, 0xd5d5d5);
+	outpdw(MDP_BASE + 0x40fb0, 0xd7d7d7);
+	outpdw(MDP_BASE + 0x40fb4, 0xd9d9d9);
+	outpdw(MDP_BASE + 0x40fb8, 0xdbdbdb);
+	outpdw(MDP_BASE + 0x40fbc, 0xdddddd);
+	outpdw(MDP_BASE + 0x40fc0, 0xdfdfdf);
+	outpdw(MDP_BASE + 0x40fc4, 0xe1e1e1);
+	outpdw(MDP_BASE + 0x40fc8, 0xe3e3e3);
+	outpdw(MDP_BASE + 0x40fcc, 0xe5e5e5);
+	outpdw(MDP_BASE + 0x40fd0, 0xe7e7e7);
+	outpdw(MDP_BASE + 0x40fd4, 0xe9e9e9);
+	outpdw(MDP_BASE + 0x40fd8, 0xebebeb);
+	outpdw(MDP_BASE + 0x40fdc, 0xeeeeee);
+	outpdw(MDP_BASE + 0x40fe0, 0xf0f0f0);
+	outpdw(MDP_BASE + 0x40fe4, 0xf2f2f2);
+	outpdw(MDP_BASE + 0x40fe8, 0xf4f4f4);
+	outpdw(MDP_BASE + 0x40fec, 0xf6f6f6);
+	outpdw(MDP_BASE + 0x40ff0, 0xf8f8f8);
+	outpdw(MDP_BASE + 0x40ff4, 0xfbfbfb);
+	outpdw(MDP_BASE + 0x40ff8, 0xfdfdfd);
+	outpdw(MDP_BASE + 0x40ffc, 0xffffff);
+}
+
+#define   IRQ_EN_1__MDP_IRQ___M    0x00000800
+
+void mdp_hw_init(void)
+{
+	int i;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/* debug interface write access */
+	outpdw(MDP_BASE + 0x60, 1);
+
+	outp32(MDP_INTR_ENABLE, MDP_ANY_INTR_MASK);
+	outp32(MDP_EBI2_PORTMAP_MODE, 0x3);
+	outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8, 0x0);
+	outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc, 0x0);
+	outpdw(MDP_BASE + 0x60, 0x1);
+	mdp_load_lut_param();
+
+	/*
+	 * clear up unused fg/main registers
+	 */
+	/* comp.plane 2&3 ystride */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0120, 0x0);
+	/* unpacked pattern */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x012c, 0x0);
+	/* unpacked pattern */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0130, 0x0);
+	/* unpacked pattern */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0134, 0x0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0158, 0x0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x15c, 0x0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0160, 0x0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0170, 0x0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0174, 0x0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x017c, 0x0);
+
+	/* comp.plane 2 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0114, 0x0);
+	/* comp.plane 3 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0118, 0x0);
+
+	/* clear up unused bg registers */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8, 0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0, 0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc, 0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0, 0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4, 0);
+
+#ifndef CONFIG_FB_MSM_MDP22
+	MDP_OUTP(MDP_BASE + 0xE0000, 0);
+	MDP_OUTP(MDP_BASE + 0x100, 0xffffffff);
+	MDP_OUTP(MDP_BASE + 0x90070, 0);
+#endif
+
+	/*
+	 * limit vector
+	 * pre gets applied before color matrix conversion
+	 * post is after ccs
+	 */
+	writel(mdp_plv[0], MDP_CSC_PRE_LV1n(0));
+	writel(mdp_plv[1], MDP_CSC_PRE_LV1n(1));
+	writel(mdp_plv[2], MDP_CSC_PRE_LV1n(2));
+	writel(mdp_plv[3], MDP_CSC_PRE_LV1n(3));
+
+#ifdef CONFIG_FB_MSM_MDP31
+	writel(mdp_plv[2], MDP_CSC_PRE_LV1n(4));
+	writel(mdp_plv[3], MDP_CSC_PRE_LV1n(5));
+
+	writel(0, MDP_CSC_POST_LV1n(0));
+	writel(0xff, MDP_CSC_POST_LV1n(1));
+	writel(0, MDP_CSC_POST_LV1n(2));
+	writel(0xff, MDP_CSC_POST_LV1n(3));
+	writel(0, MDP_CSC_POST_LV1n(4));
+	writel(0xff, MDP_CSC_POST_LV1n(5));
+
+	writel(0, MDP_CSC_PRE_LV2n(0));
+	writel(0xff, MDP_CSC_PRE_LV2n(1));
+	writel(0, MDP_CSC_PRE_LV2n(2));
+	writel(0xff, MDP_CSC_PRE_LV2n(3));
+	writel(0, MDP_CSC_PRE_LV2n(4));
+	writel(0xff, MDP_CSC_PRE_LV2n(5));
+
+	writel(mdp_plv[0], MDP_CSC_POST_LV2n(0));
+	writel(mdp_plv[1], MDP_CSC_POST_LV2n(1));
+	writel(mdp_plv[2], MDP_CSC_POST_LV2n(2));
+	writel(mdp_plv[3], MDP_CSC_POST_LV2n(3));
+	writel(mdp_plv[2], MDP_CSC_POST_LV2n(4));
+	writel(mdp_plv[3], MDP_CSC_POST_LV2n(5));
+#endif
+
+	/* primary forward matrix */
+	for (i = 0; i < MDP_CCS_SIZE; i++)
+		writel(mdp_ccs_rgb2yuv.ccs[i], MDP_CSC_PFMVn(i));
+
+#ifdef CONFIG_FB_MSM_MDP31
+	for (i = 0; i < MDP_BV_SIZE; i++)
+		writel(mdp_ccs_rgb2yuv.bv[i], MDP_CSC_POST_BV2n(i));
+
+	writel(0, MDP_CSC_PRE_BV2n(0));
+	writel(0, MDP_CSC_PRE_BV2n(1));
+	writel(0, MDP_CSC_PRE_BV2n(2));
+#endif
+	/* primary reverse matrix */
+	for (i = 0; i < MDP_CCS_SIZE; i++)
+		writel(mdp_ccs_yuv2rgb.ccs[i], MDP_CSC_PRMVn(i));
+
+	for (i = 0; i < MDP_BV_SIZE; i++)
+		writel(mdp_ccs_yuv2rgb.bv[i], MDP_CSC_PRE_BV1n(i));
+
+#ifdef CONFIG_FB_MSM_MDP31
+	writel(0, MDP_CSC_POST_BV1n(0));
+	writel(0, MDP_CSC_POST_BV1n(1));
+	writel(0, MDP_CSC_POST_BV1n(2));
+
+	outpdw(MDP_BASE + 0x30010, 0x03e0);
+	outpdw(MDP_BASE + 0x30014, 0x0360);
+	outpdw(MDP_BASE + 0x30018, 0x0120);
+	outpdw(MDP_BASE + 0x3001c, 0x0140);
+#endif
+	mdp_init_scale_table();
+
+#ifndef CONFIG_FB_MSM_MDP31
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0104,
+		 ((16 << 6) << 16) | (16) << 6);
+#endif
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
diff --git a/drivers/video/msm/mdp_lcdc.c b/drivers/video/msm/mdp_lcdc.c
index 4c3deb6..62b0975 100644
--- a/drivers/video/msm/mdp_lcdc.c
+++ b/drivers/video/msm/mdp_lcdc.c
@@ -1,7 +1,7 @@
 /* drivers/video/msm/mdp_lcdc.c
  *
  * Copyright (c) 2009 Google Inc.
- * Copyright (c) 2009 QUALCOMM Incorporated
+ * Copyright (c) 2009 Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -23,202 +23,52 @@
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
-#include <linux/msm_mdp.h>
+
 #include <mach/msm_fb.h>
-#include <mach/debug_display.h>
 
 #include "mdp_hw.h"
-#ifdef CONFIG_MSM_MDP40
-#include "mdp4.h"
-#endif
-#ifdef CONFIG_PANEL_SELF_REFRESH
-#include <linux/kthread.h>
-#endif
 
-#if 0
-#define D(fmt, args...) printk(KERN_INFO "Dispaly: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
+struct mdp_lcdc_info {
+	struct mdp_info			*mdp;
+	struct clk			*mdp_clk;
+	struct clk			*pclk;
+	struct clk			*pad_pclk;
+	struct msm_panel_data		fb_panel_data;
+	struct platform_device		fb_pdev;
+	struct msm_lcdc_platform_data	*pdata;
+	uint32_t fb_start;
 
-#if defined(CONFIG_ARCH_MSM7227)
-#define LCDC_MUX_CTL (MSM_TGPIO1_BASE + 0x278)
-#endif
+	struct msmfb_callback		frame_start_cb;
+	wait_queue_head_t		vsync_waitq;
+	int				got_vsync;
 
+	struct {
+		uint32_t	clk_rate;
+		uint32_t	hsync_ctl;
+		uint32_t	vsync_period;
+		uint32_t	vsync_pulse_width;
+		uint32_t	display_hctl;
+		uint32_t	display_vstart;
+		uint32_t	display_vend;
+		uint32_t	hsync_skew;
+		uint32_t	polarity;
+	} parms;
+};
 
 static struct mdp_device *mdp_dev;
 
-#ifdef CONFIG_MSM_MDP40
-static struct mdp4_overlay_pipe *lcdc_pipe;
-#endif
-
-#ifdef CONFIG_PANEL_SELF_REFRESH
-#if 0
-#define ICM_DBG(s...) printk("[icm]" s)
-#else
-#define ICM_DBG(s...) do {} while (0)
-#endif
-
-/* set the timeout to 200 milliseconds */
-#define PANEL_ENTER_IDLE_TIMEOUT HZ/5
-/* Afetr setting ICM=1, we need to keep sending the RGB signal more than 2-frame */
-#define PANEL_IDLE_STABLE_TIMEOUT 48
-
-static struct task_struct *th_display;
-struct panel_icm_info *panel_icm;
-DECLARE_WAIT_QUEUE_HEAD(panel_update_wait_queue);
-#endif
-
-#ifdef CONFIG_PANEL_SELF_REFRESH
-static int icm_check_panel_update(void)
-{
-	int ret;
-	unsigned long irq_flags = 0;
-
-	spin_lock_irqsave(&panel_icm->lock, irq_flags);
-	ret = panel_icm->panel_update;
-	spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
-	return ret;
-}
-
-static int icm_thread(void *data)
-{
-	struct mdp_lcdc_info *lcdc;
-	struct msm_lcdc_panel_ops *panel_ops;
-	int rc;
-	unsigned long irq_flags = 0;
-
-	lcdc = data;
-	panel_ops = lcdc->pdata->panel_ops;
-	while (1) {
-		rc = wait_event_timeout(panel_update_wait_queue, icm_check_panel_update() == 1, PANEL_ENTER_IDLE_TIMEOUT);
-		ICM_DBG("ICM Thread:wake up rc=%d \n", rc);
-		mutex_lock(&panel_icm->icm_lock);
-		if (rc == 0 && icm_check_panel_update() != 1) {/* wait_timeout */
-			ICM_DBG("EnterICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
-			if (panel_icm->icm_mode == false && panel_icm->icm_doable == true) {
-
-				if (panel_ops->refresh_enable)
-					panel_ops->refresh_enable(panel_ops);
-
-				panel_icm->icm_mode = true;
-				msleep(PANEL_IDLE_STABLE_TIMEOUT);
-
-				mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
-				clk_disable(lcdc->pad_pclk);
-				clk_disable(lcdc->pclk);
-				clk_disable(lcdc->mdp_clk);
-				panel_icm->clock_enabled = false;
-				PR_DISP_DEBUG("EnterICM: enter ICM MODE done!!!\n");
-			}
-		} else {/* get update event, no timeout */
-			ICM_DBG("Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
-			if (panel_icm->icm_mode == true && panel_icm->icm_doable == true) {
-				clk_enable(lcdc->mdp_clk);
-				clk_enable(lcdc->pclk);
-				clk_enable(lcdc->pad_pclk);
-				mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
-				panel_icm->clock_enabled = true;
-
-				if (panel_ops->refresh_disable)
-					panel_ops->refresh_disable(panel_ops);
-
-				panel_icm->icm_mode = false;
-				PR_DISP_DEBUG("LeaveICM: leave ICM MODE done !!!\n");
-			}
-			spin_lock_irqsave(&panel_icm->lock, irq_flags);
-			panel_icm->panel_update = 0;
-			spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
-		}
-		mutex_unlock(&panel_icm->icm_lock);
-	} /* end while */
-	return 0;
-}
-
-static void icm_force_leave(void)
-{
-	struct msm_lcdc_panel_ops *panel_ops;
-	unsigned long irq_flags = 0;
-
-	panel_ops = panel_icm->lcdc->pdata->panel_ops;
-
-	mutex_lock(&panel_icm->icm_lock);
-	ICM_DBG("Force Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
-	if (panel_icm->icm_mode == true) {
-		clk_enable(panel_icm->lcdc->mdp_clk);
-		clk_enable(panel_icm->lcdc->pclk);
-		clk_enable(panel_icm->lcdc->pad_pclk);
-		mdp_writel(panel_icm->lcdc->mdp, 1, MDP_LCDC_EN);
-		panel_icm->clock_enabled = true;
-		if (panel_ops->refresh_disable)
-			panel_ops->refresh_disable(panel_ops);
-		panel_icm->icm_mode = false;
-		panel_icm->icm_doable = true;
-		PR_DISP_INFO("ForceLeaveICM: leave ICM MODE done !!!\n");
-	}
-	spin_lock_irqsave(&panel_icm->lock, irq_flags);
-	panel_icm->panel_update = 0;
-	spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
-	mutex_unlock(&panel_icm->icm_lock);
-}
-
-static int icm_init(struct mdp_lcdc_info *lcdc)
-{
-	int ret = 0;
-
-	/* init panel_icm_info */
-	panel_icm = kzalloc(sizeof(struct panel_icm_info), GFP_KERNEL);
-	if (!panel_icm)
-		return -ENOMEM;
-	panel_icm->icm_doable = 1;
-	panel_icm->clock_enabled = true;
-	panel_icm->lcdc = lcdc;
-	panel_icm->force_leave = icm_force_leave;
-	panel_icm->icm_suspend = false;
-	mutex_init(&panel_icm->icm_lock);
-	th_display = kthread_run(icm_thread, lcdc, "panel-enterIdle");
-	if (IS_ERR(th_display)) {
-		ret = PTR_ERR(th_display);
-		PR_DISP_ERR("%s: panel_icm_thread  create fail:%d!!!\n", __func__, ret);
-		goto	error_create_thread;
-	}
-	return ret;
-error_create_thread:
-	kfree(panel_icm);
-	return ret;
-}
-#endif
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-void mdp4_lcdc_overlay_blt(ulong addr)
-{
-       unsigned long flag;
-
-       spin_lock_irqsave(&mdp_spin_lock, flag);
-       lcdc_pipe->blt_addr = addr;
-       lcdc_pipe->blt_cnt = 0;
-       spin_unlock_irqrestore(&mdp_spin_lock, flag);
-       mdp_writel(lcdc_pipe->mdp, 0x0, 0xc0000);
-       mdelay(100);
-       mdp4_overlayproc_cfg(lcdc_pipe);
-       mdp4_overlay_dmap_xy(lcdc_pipe);
-       mdelay(100);
-       mdp_writel(lcdc_pipe->mdp, 0x1, 0xc0000);
-}
-#endif
+#define panel_to_lcdc(p) container_of((p), struct mdp_lcdc_info, fb_panel_data)
 
 static int lcdc_unblank(struct msm_panel_data *fb_panel)
 {
 	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
 	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
 
-	PR_DISP_INFO("%s: ()\n", __func__);
-
-	if (panel_ops->unblank)
-		panel_ops->unblank(panel_ops);
+	pr_info("%s: ()\n", __func__);
+	panel_ops->unblank(panel_ops);
 
 	return 0;
 }
@@ -228,23 +78,8 @@
 	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
 	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
 
-	PR_DISP_INFO("%s: ()\n", __func__);
-
-	if (panel_ops->blank)
-		panel_ops->blank(panel_ops);
-
-	return 0;
-}
-
-static int lcdc_shutdown(struct msm_panel_data *fb_panel)
-{
-	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
-	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
-
-	PR_DISP_INFO("%s: ()\n", __func__);
-
-	if (panel_ops->shutdown)
-		panel_ops->shutdown(panel_ops);
+	pr_info("%s: ()\n", __func__);
+	panel_ops->blank(panel_ops);
 
 	return 0;
 }
@@ -252,46 +87,13 @@
 static int lcdc_suspend(struct msm_panel_data *fb_panel)
 {
 	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
-	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
 
-	PR_DISP_INFO("%s: suspending\n", __func__);
+	pr_info("%s: suspending\n", __func__);
 
-#if defined(CONFIG_ARCH_MSM7227)
-	writel(0x0, LCDC_MUX_CTL);
-	D("suspend_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL));
-#endif
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
-		mutex_lock(&panel_icm->icm_lock);
-		panel_icm->icm_doable = false;
-		panel_icm->icm_suspend = true;
-		PR_DISP_INFO("[ICM %s]: icm mode=%d, clock_enabled=%d\n", __func__, panel_icm->icm_mode, panel_icm->clock_enabled);
-		if (panel_icm->icm_mode == true && panel_icm->clock_enabled == false) {
-			if (panel_ops->refresh_disable)
-				panel_ops->refresh_disable(panel_ops);
-			panel_icm->icm_mode = false;
-		} else {
-			mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
-			clk_disable(lcdc->pad_pclk);
-			clk_disable(lcdc->pclk);
-			clk_disable(lcdc->mdp_clk);
-		}
-		panel_icm->clock_enabled = false;
-		mutex_unlock(&panel_icm->icm_lock);
-	} else {
-		mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
-		clk_disable(lcdc->pad_pclk);
-		clk_disable(lcdc->pclk);
-		clk_disable(lcdc->mdp_clk);
-	}
-#else
 	mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
-	clk_disable(lcdc->pad_pclk);
-	clk_disable(lcdc->pclk);
-	clk_disable(lcdc->mdp_clk);
-#endif
-	if (panel_ops->uninit)
-		panel_ops->uninit(panel_ops);
+	clk_disable_unprepare(lcdc->pad_pclk);
+	clk_disable_unprepare(lcdc->pclk);
+	clk_disable_unprepare(lcdc->mdp_clk);
 
 	return 0;
 }
@@ -299,33 +101,13 @@
 static int lcdc_resume(struct msm_panel_data *fb_panel)
 {
 	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
-	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
 
-	PR_DISP_INFO("%s: resuming\n", __func__);
+	pr_info("%s: resuming\n", __func__);
 
-	if (panel_ops->init) {
-		if (panel_ops->init(panel_ops) < 0)
-			PR_DISP_ERR("LCD init fail!\n");
-	}
-
-	clk_enable(lcdc->mdp_clk);
-	clk_enable(lcdc->pclk);
-	clk_enable(lcdc->pad_pclk);
-#if defined(CONFIG_ARCH_MSM7227)
-	writel(0x1, LCDC_MUX_CTL);
-	D("resume_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL));
-#endif
-
+	clk_prepare_enable(lcdc->mdp_clk);
+	clk_prepare_enable(lcdc->pclk);
+	clk_prepare_enable(lcdc->pad_pclk);
 	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
-		mutex_lock(&panel_icm->icm_lock);
-		panel_icm->icm_doable = true;
-		panel_icm->clock_enabled = true;
-		panel_icm->icm_suspend = false;
-		mutex_unlock(&panel_icm->icm_lock);
-	}
-#endif
 
 	return 0;
 }
@@ -335,16 +117,13 @@
 	struct msm_panel_data *fb_panel = &lcdc->fb_panel_data;
 	uint32_t dma_cfg;
 
-	clk_enable(lcdc->mdp_clk);
-	clk_enable(lcdc->pclk);
-	clk_enable(lcdc->pad_pclk);
+	clk_prepare_enable(lcdc->mdp_clk);
+	clk_prepare_enable(lcdc->pclk);
+	clk_prepare_enable(lcdc->pad_pclk);
 
-#ifdef CONFIG_MSM_MDP40
-	mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
-	mdelay(10);
-#endif
 	clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate);
 	clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate);
+
 	/* write the lcdc params */
 	mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL);
 	mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD);
@@ -362,29 +141,26 @@
 	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START);
 	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END);
 	mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY);
+
 	/* config the dma_p block that drives the lcdc data */
 	mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR);
 	mdp_writel(lcdc->mdp, (((fb_panel->fb_data->yres & 0x7ff) << 16) |
 			       (fb_panel->fb_data->xres & 0x7ff)),
 		   MDP_DMA_P_SIZE);
+
 	mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY);
 
 	dma_cfg = mdp_readl(lcdc->mdp, MDP_DMA_P_CONFIG);
-	if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_DMA_PACK_ALIGN_LSB)
-		dma_cfg &= ~DMA_PACK_ALIGN_MSB;
-	else
-		dma_cfg |= DMA_PACK_ALIGN_MSB;
-
-	dma_cfg |= (DMA_PACK_PATTERN_RGB |
+	dma_cfg |= (DMA_PACK_ALIGN_LSB |
+		   DMA_PACK_PATTERN_RGB |
 		   DMA_DITHER_EN);
 	dma_cfg |= DMA_OUT_SEL_LCDC;
 	dma_cfg &= ~DMA_DST_BITS_MASK;
-	if (lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB565)
-		dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
-	else if (lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB666)
+
+	if (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB666)
 		dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
-	else if (lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB888)
-		dma_cfg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
+	else
+		dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
 
 	mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG);
 
@@ -401,7 +177,7 @@
 
 	ret = wait_event_timeout(lcdc->vsync_waitq, lcdc->got_vsync, HZ / 2);
 	if (!ret && !lcdc->got_vsync)
-		PR_DISP_ERR("%s: timeout waiting for VSYNC\n", __func__);
+		pr_err("%s: timeout waiting for VSYNC\n", __func__);
 	lcdc->got_vsync = 0;
 }
 
@@ -437,58 +213,23 @@
 	wake_up(&lcdc->vsync_waitq);
 }
 
-#ifdef CONFIG_MSM_MDP40
-static void lcdc_overlay_start(void *priv, uint32_t addr, uint32_t stride,
-			   uint32_t width, uint32_t height, uint32_t x,
-			   uint32_t y)
-{
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-
-	struct mdp4_overlay_pipe *pipe;
-	pipe = lcdc_pipe;
-	pipe->srcp0_addr = addr;
-
-	if (mdp->dma_config_dirty) {
-		if (mdp->dma_format == DMA_IBUF_FORMAT_RGB565) {
-			pipe->src_format = MDP_RGB_565;
-			pipe->srcp0_ystride = pipe->src_width * 2;
-		} else if (mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888) {
-			pipe->src_format = MDP_RGBA_8888;
-			pipe->srcp0_ystride = pipe->src_width * 4;
-		}
-		mdp4_overlay_format2pipe(pipe);
-		mdp_writel(pipe->mdp, 0, MDP_LCDC_EN);
-		mdelay(30);
-		mdp4_overlay_dmap_xy(pipe);
-		mdp4_overlay_dmap_cfg(pipe, 1);
-		mdp4_overlayproc_cfg(pipe);
-		mdp4_overlay_rgb_setup(pipe);
-		mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */
-		mdp_writel(pipe->mdp, 1, MDP_LCDC_EN);
-		mdp->dma_config_dirty = false;
-	} else {
-		mdp4_overlay_rgb_setup(pipe);
-		mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */
-	}
-
-}
-#else
 static void lcdc_dma_start(void *priv, uint32_t addr, uint32_t stride,
 			   uint32_t width, uint32_t height, uint32_t x,
 			   uint32_t y)
 {
 	struct mdp_lcdc_info *lcdc = priv;
+
 	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	if (mdp->dma_config_dirty) {
+	if (mdp->dma_config_dirty)
+	{
 		mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
-		mdelay(30);
+		mdelay(20);
 		mdp_dev->configure_dma(mdp_dev);
 		mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
 	}
 	mdp_writel(lcdc->mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE);
 	mdp_writel(lcdc->mdp, addr, MDP_DMA_P_IBUF_ADDR);
 }
-#endif
 
 static void precompute_timing_parms(struct mdp_lcdc_info *lcdc)
 {
@@ -501,21 +242,21 @@
 	unsigned int display_vstart;
 	unsigned int display_vend;
 
-	hsync_period = (timing->hsync_pulse_width + timing->hsync_back_porch +
+	hsync_period = (timing->hsync_back_porch +
 			fb_data->xres + timing->hsync_front_porch);
-	hsync_start_x = (timing->hsync_pulse_width + timing->hsync_back_porch);
+	hsync_start_x = timing->hsync_back_porch;
 	hsync_end_x = hsync_start_x + fb_data->xres - 1;
 
-	vsync_period = (timing->vsync_pulse_width + timing->vsync_back_porch +
+	vsync_period = (timing->vsync_back_porch +
 			fb_data->yres + timing->vsync_front_porch);
 	vsync_period *= hsync_period;
 
-	display_vstart = timing->vsync_pulse_width + timing->vsync_back_porch;
+	display_vstart = timing->vsync_back_porch;
 	display_vstart *= hsync_period;
 	display_vstart += timing->hsync_skew;
 
-	display_vend = (timing->vsync_pulse_width + timing->vsync_back_porch +
-			 fb_data->yres) * hsync_period;
+	display_vend = (timing->vsync_back_porch + fb_data->yres) *
+		hsync_period;
 	display_vend += timing->hsync_skew - 1;
 
 	/* register values we pre-compute at init time from the timing
@@ -542,13 +283,9 @@
 	struct msm_lcdc_platform_data *pdata = pdev->dev.platform_data;
 	struct mdp_lcdc_info *lcdc;
 	int ret = 0;
-#ifdef CONFIG_MSM_MDP40
-	struct mdp4_overlay_pipe *pipe;
-	int ptype;
-#endif
 
 	if (!pdata) {
-		PR_DISP_ERR("%s: no LCDC platform data found\n", __func__);
+		pr_err("%s: no LCDC platform data found\n", __func__);
 		return -EINVAL;
 	}
 
@@ -559,21 +296,21 @@
 	/* We don't actually own the clocks, the mdp does. */
 	lcdc->mdp_clk = clk_get(mdp_dev->dev.parent, "mdp_clk");
 	if (IS_ERR(lcdc->mdp_clk)) {
-		PR_DISP_ERR("%s: failed to get mdp_clk\n", __func__);
+		pr_err("%s: failed to get mdp_clk\n", __func__);
 		ret = PTR_ERR(lcdc->mdp_clk);
 		goto err_get_mdp_clk;
 	}
 
 	lcdc->pclk = clk_get(mdp_dev->dev.parent, "lcdc_pclk_clk");
 	if (IS_ERR(lcdc->pclk)) {
-		PR_DISP_ERR("%s: failed to get lcdc_pclk\n", __func__);
+		pr_err("%s: failed to get lcdc_pclk\n", __func__);
 		ret = PTR_ERR(lcdc->pclk);
 		goto err_get_pclk;
 	}
 
 	lcdc->pad_pclk = clk_get(mdp_dev->dev.parent, "lcdc_pad_pclk_clk");
 	if (IS_ERR(lcdc->pad_pclk)) {
-		PR_DISP_ERR("%s: failed to get lcdc_pad_pclk\n", __func__);
+		pr_err("%s: failed to get lcdc_pad_pclk\n", __func__);
 		ret = PTR_ERR(lcdc->pad_pclk);
 		goto err_get_pad_pclk;
 	}
@@ -583,53 +320,14 @@
 	lcdc->frame_start_cb.func = lcdc_frame_start;
 
 	platform_set_drvdata(pdev, lcdc);
-#ifdef CONFIG_MSM_MDP40
-	mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, INTR_OVERLAY0_DONE,
-			    lcdc_overlay_start);
-#else
+
 	mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, MDP_DMA_P_DONE,
 			    lcdc_dma_start);
-#endif
-	lcdc->mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
+
 	precompute_timing_parms(lcdc);
 
 	lcdc->fb_start = pdata->fb_resource->start;
-	if (lcdc->mdp->mdp_dev.color_format)
-		lcdc->color_format = lcdc->mdp->mdp_dev.color_format;
-	else
-		lcdc->color_format = MSM_MDP_OUT_IF_FMT_RGB565;
-
-#ifdef CONFIG_MSM_MDP40
-	if (lcdc_pipe == NULL) {
-		ptype = mdp4_overlay_format2type(MDP_RGB_565);
-		pipe = mdp4_overlay_pipe_alloc(ptype, false);
-		if (!pipe)
-			goto err_mdp4_overlay_pipe_alloc;
-		pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
-		pipe->pipe_used = 1;
-		pipe->mixer_num  = MDP4_MIXER0;
-		pipe->src_format = MDP_RGB_565;
-		mdp4_overlay_format2pipe(pipe);
-		pipe->mdp = lcdc->mdp;
-
-		lcdc_pipe = pipe; /* keep it */
-	} else {
-		pipe = lcdc_pipe;
-	}
-
-	pipe->src_height = pdata->fb_data->yres;
-	pipe->src_width = pdata->fb_data->xres;
-	pipe->src_h = pdata->fb_data->yres;
-	pipe->src_w = pdata->fb_data->xres;
-	pipe->src_y = 0;
-	pipe->src_x = 0;
-	pipe->srcp0_addr = (uint32_t) lcdc->fb_start;
-
-	pipe->srcp0_ystride = pdata->fb_data->xres * 2;
-
-	mdp4_overlay_rgb_setup(pipe);
-	mdp4_mixer_stage_up(pipe);
-#endif
+	lcdc->mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
 
 	lcdc->fb_panel_data.suspend = lcdc_suspend;
 	lcdc->fb_panel_data.resume = lcdc_resume;
@@ -640,43 +338,34 @@
 	lcdc->fb_panel_data.unblank = lcdc_unblank;
 	lcdc->fb_panel_data.fb_data = pdata->fb_data;
 	lcdc->fb_panel_data.interface_type = MSM_LCDC_INTERFACE;
-	lcdc->fb_panel_data.shutdown = lcdc_shutdown;
+
 	ret = lcdc_hw_init(lcdc);
 	if (ret) {
-		PR_DISP_ERR("%s: Cannot initialize the mdp_lcdc\n", __func__);
+		pr_err("%s: Cannot initialize the mdp_lcdc\n", __func__);
 		goto err_hw_init;
 	}
+
 	lcdc->fb_pdev.name = "msm_panel";
 	lcdc->fb_pdev.id = pdata->fb_id;
 	lcdc->fb_pdev.resource = pdata->fb_resource;
 	lcdc->fb_pdev.num_resources = 1;
 	lcdc->fb_pdev.dev.platform_data = &lcdc->fb_panel_data;
 
+	if (pdata->panel_ops->init)
+		pdata->panel_ops->init(pdata->panel_ops);
 
 	ret = platform_device_register(&lcdc->fb_pdev);
 	if (ret) {
-		PR_DISP_ERR("%s: Cannot register msm_panel pdev\n", __func__);
+		pr_err("%s: Cannot register msm_panel pdev\n", __func__);
 		goto err_plat_dev_reg;
 	}
 
-	PR_DISP_INFO("%s: initialized\n", __func__);
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
-		ret = icm_init(lcdc);
-		if (ret) {
-			PR_DISP_ERR("%s: Cannot init dispaly selfrefresh \n", __func__);
-			goto err_plat_dev_reg;
-		}
-	}
-#endif
+	pr_info("%s: initialized\n", __func__);
 
 	return 0;
 
 err_plat_dev_reg:
 err_hw_init:
-#ifdef CONFIG_MSM_MDP40
-err_mdp4_overlay_pipe_alloc:
-#endif
 	platform_set_drvdata(pdev, NULL);
 	clk_put(lcdc->pad_pclk);
 err_get_pad_pclk:
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
new file mode 100644
index 0000000..b84fe44
--- /dev/null
+++ b/drivers/video/msm/mdp_ppp.c
@@ -0,0 +1,1724 @@
+/* drivers/video/msm/src/drv/mdp/mdp_ppp.c
+ *
+ * Copyright (C) 2007 Google Incorporated
+ * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+#include <linux/file.h>
+#include <linux/android_pmem.h>
+#include <linux/major.h>
+
+#include "linux/proc_fs.h"
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/msm_kgsl.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+
+#define MDP_IS_IMGTYPE_BAD(x) (((x) >= MDP_IMGTYPE_LIMIT) && \
+				(((x) < MDP_IMGTYPE2_START) || \
+				 ((x) >= MDP_IMGTYPE_LIMIT2)))
+
+static uint32_t bytes_per_pixel[] = {
+	[MDP_RGB_565] = 2,
+	[MDP_RGB_888] = 3,
+	[MDP_XRGB_8888] = 4,
+	[MDP_ARGB_8888] = 4,
+	[MDP_RGBA_8888] = 4,
+	[MDP_BGRA_8888] = 4,
+	[MDP_RGBX_8888] = 4,
+	[MDP_Y_CBCR_H2V1] = 1,
+	[MDP_Y_CBCR_H2V2] = 1,
+	[MDP_Y_CBCR_H2V2_ADRENO] = 1,
+	[MDP_Y_CRCB_H2V1] = 1,
+	[MDP_Y_CRCB_H2V2] = 1,
+	[MDP_YCRYCB_H2V1] = 2,
+	[MDP_BGR_565] = 2
+};
+
+extern uint32 mdp_plv[];
+extern struct semaphore mdp_ppp_mutex;
+static struct ion_client *ppp_display_iclient;
+
+int mdp_get_bytes_per_pixel(uint32_t format,
+				 struct msm_fb_data_type *mfd)
+{
+	int bpp = -EINVAL;
+	if (format == MDP_FB_FORMAT)
+		format = mfd->fb_imgType;
+	if (format < ARRAY_SIZE(bytes_per_pixel))
+		bpp = bytes_per_pixel[format];
+
+	if (bpp <= 0)
+		printk(KERN_ERR "%s incorrect format %d\n", __func__, format);
+	return bpp;
+}
+
+static uint32 mdp_conv_matx_rgb2yuv(uint32 input_pixel,
+				    uint16 *matrix_and_bias_vector,
+				    uint32 *clamp_vector,
+				    uint32 *look_up_table)
+{
+	uint8 input_C2, input_C0, input_C1;
+	uint32 output;
+	int32 comp_C2, comp_C1, comp_C0, temp;
+	int32 temp1, temp2, temp3;
+	int32 matrix[9];
+	int32 bias_vector[3];
+	int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
+	int32 i;
+	uint32 _is_lookup_table_enabled;
+
+	input_C2 = (input_pixel >> 16) & 0xFF;
+	input_C1 = (input_pixel >> 8) & 0xFF;
+	input_C0 = (input_pixel >> 0) & 0xFF;
+
+	comp_C0 = input_C0;
+	comp_C1 = input_C1;
+	comp_C2 = input_C2;
+
+	for (i = 0; i < 9; i++)
+		matrix[i] =
+		    ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20;
+
+	bias_vector[0] = (int32) (matrix_and_bias_vector[9] & 0xFF);
+	bias_vector[1] = (int32) (matrix_and_bias_vector[10] & 0xFF);
+	bias_vector[2] = (int32) (matrix_and_bias_vector[11] & 0xFF);
+
+	Y_low_limit = (int32) clamp_vector[0];
+	Y_high_limit = (int32) clamp_vector[1];
+	C_low_limit = (int32) clamp_vector[2];
+	C_high_limit = (int32) clamp_vector[3];
+
+	if (look_up_table == 0)	/* check for NULL point */
+		_is_lookup_table_enabled = 0;
+	else
+		_is_lookup_table_enabled = 1;
+
+	if (_is_lookup_table_enabled == 1) {
+		comp_C2 = (look_up_table[comp_C2] >> 16) & 0xFF;
+		comp_C1 = (look_up_table[comp_C1] >> 8) & 0xFF;
+		comp_C0 = (look_up_table[comp_C0] >> 0) & 0xFF;
+	}
+	/*
+	 * Color Conversion
+	 * reorder input colors
+	 */
+	temp = comp_C2;
+	comp_C2 = comp_C1;
+	comp_C1 = comp_C0;
+	comp_C0 = temp;
+
+	/* matrix multiplication */
+	temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2];
+	temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5];
+	temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8];
+
+	comp_C0 = temp1 + 0x100;
+	comp_C1 = temp2 + 0x100;
+	comp_C2 = temp3 + 0x100;
+
+	/* take interger part */
+	comp_C0 >>= 9;
+	comp_C1 >>= 9;
+	comp_C2 >>= 9;
+
+	/* post bias (+) */
+	comp_C0 += bias_vector[0];
+	comp_C1 += bias_vector[1];
+	comp_C2 += bias_vector[2];
+
+	/* limit pixel to 8-bit */
+	if (comp_C0 < 0)
+		comp_C0 = 0;
+
+	if (comp_C0 > 255)
+		comp_C0 = 255;
+
+	if (comp_C1 < 0)
+		comp_C1 = 0;
+
+	if (comp_C1 > 255)
+		comp_C1 = 255;
+
+	if (comp_C2 < 0)
+		comp_C2 = 0;
+
+	if (comp_C2 > 255)
+		comp_C2 = 255;
+
+	/* clamp */
+	if (comp_C0 < Y_low_limit)
+		comp_C0 = Y_low_limit;
+
+	if (comp_C0 > Y_high_limit)
+		comp_C0 = Y_high_limit;
+
+	if (comp_C1 < C_low_limit)
+		comp_C1 = C_low_limit;
+
+	if (comp_C1 > C_high_limit)
+		comp_C1 = C_high_limit;
+
+	if (comp_C2 < C_low_limit)
+		comp_C2 = C_low_limit;
+
+	if (comp_C2 > C_high_limit)
+		comp_C2 = C_high_limit;
+
+	output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0;
+	return output;
+}
+
+uint32 mdp_conv_matx_yuv2rgb(uint32 input_pixel,
+			     uint16 *matrix_and_bias_vector,
+			     uint32 *clamp_vector, uint32 *look_up_table)
+{
+	uint8 input_C2, input_C0, input_C1;
+	uint32 output;
+	int32 comp_C2, comp_C1, comp_C0, temp;
+	int32 temp1, temp2, temp3;
+	int32 matrix[9];
+	int32 bias_vector[3];
+	int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
+	int32 i;
+	uint32 _is_lookup_table_enabled;
+
+	input_C2 = (input_pixel >> 16) & 0xFF;
+	input_C1 = (input_pixel >> 8) & 0xFF;
+	input_C0 = (input_pixel >> 0) & 0xFF;
+
+	comp_C0 = input_C0;
+	comp_C1 = input_C1;
+	comp_C2 = input_C2;
+
+	for (i = 0; i < 9; i++)
+		matrix[i] =
+		    ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20;
+
+	bias_vector[0] = (int32) (matrix_and_bias_vector[9] & 0xFF);
+	bias_vector[1] = (int32) (matrix_and_bias_vector[10] & 0xFF);
+	bias_vector[2] = (int32) (matrix_and_bias_vector[11] & 0xFF);
+
+	Y_low_limit = (int32) clamp_vector[0];
+	Y_high_limit = (int32) clamp_vector[1];
+	C_low_limit = (int32) clamp_vector[2];
+	C_high_limit = (int32) clamp_vector[3];
+
+	if (look_up_table == 0)	/* check for NULL point */
+		_is_lookup_table_enabled = 0;
+	else
+		_is_lookup_table_enabled = 1;
+
+	/* clamp */
+	if (comp_C0 < Y_low_limit)
+		comp_C0 = Y_low_limit;
+
+	if (comp_C0 > Y_high_limit)
+		comp_C0 = Y_high_limit;
+
+	if (comp_C1 < C_low_limit)
+		comp_C1 = C_low_limit;
+
+	if (comp_C1 > C_high_limit)
+		comp_C1 = C_high_limit;
+
+	if (comp_C2 < C_low_limit)
+		comp_C2 = C_low_limit;
+
+	if (comp_C2 > C_high_limit)
+		comp_C2 = C_high_limit;
+
+	/*
+	 * Color Conversion
+	 * pre bias (-)
+	 */
+	comp_C0 -= bias_vector[0];
+	comp_C1 -= bias_vector[1];
+	comp_C2 -= bias_vector[2];
+
+	/* matrix multiplication */
+	temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2];
+	temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5];
+	temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8];
+
+	comp_C0 = temp1 + 0x100;
+	comp_C1 = temp2 + 0x100;
+	comp_C2 = temp3 + 0x100;
+
+	/* take interger part */
+	comp_C0 >>= 9;
+	comp_C1 >>= 9;
+	comp_C2 >>= 9;
+
+	/* reorder output colors */
+	temp = comp_C0;
+	comp_C0 = comp_C1;
+	comp_C1 = comp_C2;
+	comp_C2 = temp;
+
+	/* limit pixel to 8-bit */
+	if (comp_C0 < 0)
+		comp_C0 = 0;
+
+	if (comp_C0 > 255)
+		comp_C0 = 255;
+
+	if (comp_C1 < 0)
+		comp_C1 = 0;
+
+	if (comp_C1 > 255)
+		comp_C1 = 255;
+
+	if (comp_C2 < 0)
+		comp_C2 = 0;
+
+	if (comp_C2 > 255)
+		comp_C2 = 255;
+
+	/* Look-up table */
+	if (_is_lookup_table_enabled == 1) {
+		comp_C2 = (look_up_table[comp_C2] >> 16) & 0xFF;
+		comp_C1 = (look_up_table[comp_C1] >> 8) & 0xFF;
+		comp_C0 = (look_up_table[comp_C0] >> 0) & 0xFF;
+	}
+
+	output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0;
+	return output;
+}
+
+static uint32 mdp_calc_tpval(MDPIMG *mdpImg)
+{
+	uint32 tpVal;
+	uint8 plane_tp;
+
+	tpVal = 0;
+	if ((mdpImg->imgType == MDP_RGB_565)
+	    || (mdpImg->imgType == MDP_BGR_565)) {
+		/*
+		 * transparent color conversion into 24 bpp
+		 *
+		 * C2R_8BIT
+		 * left shift the entire bit and or it with the upper most bits
+		 */
+		plane_tp = (uint8) ((mdpImg->tpVal & 0xF800) >> 11);
+		tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 16;
+
+		/* C1B_8BIT */
+		plane_tp = (uint8) (mdpImg->tpVal & 0x1F);
+		tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 8;
+
+		/* C0G_8BIT */
+		plane_tp = (uint8) ((mdpImg->tpVal & 0x7E0) >> 5);
+		tpVal |= ((plane_tp << 2) | ((plane_tp & 0x30) >> 4));
+	} else {
+		/* 24bit RGB to RBG conversion */
+
+		tpVal = (mdpImg->tpVal & 0xFF00) >> 8;
+		tpVal |= (mdpImg->tpVal & 0xFF) << 8;
+		tpVal |= (mdpImg->tpVal & 0xFF0000);
+	}
+
+	return tpVal;
+}
+
+static uint8 *mdp_get_chroma_addr(MDPIBUF *iBuf)
+{
+	uint8 *dest1;
+
+	dest1 = NULL;
+	switch (iBuf->ibuf_type) {
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CRCB_H2V2:
+	case MDP_Y_CBCR_H2V1:
+	case MDP_Y_CRCB_H2V1:
+		dest1 = (uint8 *) iBuf->buf;
+		dest1 += iBuf->ibuf_width * iBuf->ibuf_height * iBuf->bpp;
+		break;
+
+	default:
+		break;
+	}
+
+	return dest1;
+}
+
+static void mdp_ppp_setbg(MDPIBUF *iBuf)
+{
+	uint8 *bg0_addr;
+	uint8 *bg1_addr;
+	uint32 bg0_ystride, bg1_ystride;
+	uint32 ppp_src_cfg_reg, unpack_pattern;
+	int v_slice, h_slice;
+
+	v_slice = h_slice = 1;
+	bg0_addr = (uint8 *) iBuf->buf;
+	bg1_addr = mdp_get_chroma_addr(iBuf);
+
+	bg0_ystride = iBuf->ibuf_width * iBuf->bpp;
+	bg1_ystride = iBuf->ibuf_width * iBuf->bpp;
+
+	switch (iBuf->ibuf_type) {
+	case MDP_BGR_565:
+	case MDP_RGB_565:
+		/* 888 = 3bytes
+		 * RGB = 3Components
+		 * RGB interleaved
+		 */
+		ppp_src_cfg_reg = PPP_SRC_C2R_5BITS | PPP_SRC_C0G_6BITS |
+			PPP_SRC_C1B_5BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
+			PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
+			PPP_SRC_UNPACK_ALIGN_LSB |
+			PPP_SRC_FETCH_PLANES_INTERLVD;
+
+		if (iBuf->ibuf_type == MDP_RGB_565)
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
+		else
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
+		break;
+
+	case MDP_RGB_888:
+		/*
+		 * 888 = 3bytes
+		 * RGB = 3Components
+		 * RGB interleaved
+		 */
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
+		PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_3BYTES |
+		PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
+		PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_INTERLVD;
+
+		unpack_pattern =
+		    MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
+		break;
+
+	case MDP_BGRA_8888:
+	case MDP_RGBA_8888:
+	case MDP_ARGB_8888:
+	case MDP_XRGB_8888:
+	case MDP_RGBX_8888:
+		/*
+		 * 8888 = 4bytes
+		 * ARGB = 4Components
+		 * ARGB interleaved
+		 */
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
+		PPP_SRC_C1B_8BITS | PPP_SRC_C3A_8BITS | PPP_SRC_C3_ALPHA_EN |
+		PPP_SRC_BPP_INTERLVD_4BYTES | PPP_SRC_INTERLVD_4COMPONENTS |
+		PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB |
+		PPP_SRC_FETCH_PLANES_INTERLVD;
+
+		if (iBuf->ibuf_type == MDP_BGRA_8888)
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+		else if (iBuf->ibuf_type == MDP_RGBA_8888 ||
+				 iBuf->ibuf_type == MDP_RGBX_8888)
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
+						 8);
+		else if (iBuf->ibuf_type == MDP_XRGB_8888)
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+		else
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+		break;
+
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CRCB_H2V2:
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
+		    PPP_SRC_C0G_8BITS |
+		    PPP_SRC_C1B_8BITS |
+		    PPP_SRC_C3A_8BITS |
+		    PPP_SRC_BPP_INTERLVD_2BYTES |
+		    PPP_SRC_INTERLVD_2COMPONENTS |
+		    PPP_SRC_UNPACK_TIGHT |
+		    PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
+
+		if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
+		else
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
+		v_slice = h_slice = 2;
+		break;
+
+	case MDP_YCRYCB_H2V1:
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
+		    PPP_SRC_C0G_8BITS |
+		    PPP_SRC_C1B_8BITS |
+		    PPP_SRC_C3A_8BITS |
+		    PPP_SRC_BPP_INTERLVD_2BYTES |
+		    PPP_SRC_INTERLVD_4COMPONENTS |
+		    PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB;
+
+		unpack_pattern =
+		    MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
+		h_slice = 2;
+		break;
+
+	case MDP_Y_CBCR_H2V1:
+	case MDP_Y_CRCB_H2V1:
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
+		    PPP_SRC_C0G_8BITS |
+		    PPP_SRC_C1B_8BITS |
+		    PPP_SRC_C3A_8BITS |
+		    PPP_SRC_BPP_INTERLVD_2BYTES |
+		    PPP_SRC_INTERLVD_2COMPONENTS |
+		    PPP_SRC_UNPACK_TIGHT |
+		    PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
+
+		if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
+		else
+			unpack_pattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
+		h_slice = 2;
+		break;
+
+	default:
+		return;
+	}
+
+	/* starting input address adjustment */
+	mdp_adjust_start_addr(&bg0_addr, &bg1_addr, v_slice, h_slice,
+			      iBuf->roi.lcd_x, iBuf->roi.lcd_y,
+			      iBuf->ibuf_width, iBuf->ibuf_height, iBuf->bpp,
+			      iBuf, 1);
+
+	/*
+	 * 0x01c0: background plane 0 addr
+	 * 0x01c4: background plane 1 addr
+	 * 0x01c8: background plane 2 addr
+	 * 0x01cc: bg y stride for plane 0 and 1
+	 * 0x01d0: bg y stride for plane 2
+	 * 0x01d4: bg src PPP config
+	 * 0x01d8: unpack pattern
+	 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c0, bg0_addr);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c4, bg1_addr);
+
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01cc,
+		 (bg1_ystride << 16) | bg0_ystride);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d4, ppp_src_cfg_reg);
+
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d8, unpack_pattern);
+}
+
+#define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \
+				(img == MDP_Y_CBCR_H2V2) | \
+				(img == MDP_Y_CBCR_H2V2_ADRENO) | \
+				(img == MDP_Y_CRCB_H2V1) | \
+				(img == MDP_Y_CBCR_H2V1))
+
+#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
+
+#define Y_TO_CRCB_RATIO(format) \
+	((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CBCR_H2V2_ADRENO || \
+	  format == MDP_Y_CRCB_H2V2) ?  2 : (format == MDP_Y_CBCR_H2V1 || \
+	  format == MDP_Y_CRCB_H2V1) ?  1 : 1)
+
+#ifdef CONFIG_ANDROID_PMEM
+static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp,
+			uint32_t *len0, uint32_t *len1)
+{
+	*len0 = IMG_LEN(rect->h, img->width, rect->w, bpp);
+	if (IS_PSEUDOPLNR(img->format))
+		*len1 = *len0/Y_TO_CRCB_RATIO(img->format);
+	else
+		*len1 = 0;
+}
+
+static void flush_imgs(struct mdp_blit_req *req, int src_bpp, int dst_bpp,
+			struct file *p_src_file, struct file *p_dst_file)
+{
+	uint32_t src0_len, src1_len;
+
+	if (!(req->flags & MDP_BLIT_NON_CACHED)) {
+		/* flush src images to memory before dma to mdp */
+		get_len(&req->src, &req->src_rect, src_bpp,
+		&src0_len, &src1_len);
+
+		flush_pmem_file(p_src_file,
+		req->src.offset, src0_len);
+
+		if (IS_PSEUDOPLNR(req->src.format))
+			flush_pmem_file(p_src_file,
+				req->src.offset + src0_len, src1_len);
+	}
+
+}
+#else
+static void flush_imgs(struct mdp_blit_req *req, int src_bpp, int dst_bpp,
+			struct file *p_src_file, struct file *p_dst_file) { }
+#endif
+
+static void mdp_start_ppp(struct msm_fb_data_type *mfd, MDPIBUF *iBuf,
+struct mdp_blit_req *req, struct file *p_src_file, struct file *p_dst_file)
+{
+	uint8 *src0, *src1;
+	uint8 *dest0, *dest1;
+	uint16 inpBpp;
+	uint32 dest0_ystride;
+	uint32 src_width;
+	uint32 src_height;
+	uint32 src0_ystride;
+	uint32 src0_y1stride;
+	uint32 dst_roi_width;
+	uint32 dst_roi_height;
+	uint32 ppp_src_cfg_reg, ppp_operation_reg, ppp_dst_cfg_reg;
+	uint32 alpha, tpVal;
+	uint32 packPattern;
+	uint32 dst_packPattern;
+	boolean inputRGB, outputRGB, pseudoplanr_output;
+	int sv_slice, sh_slice;
+	int dv_slice, dh_slice;
+	boolean perPixelAlpha = FALSE;
+	boolean ppp_lookUp_enable = FALSE;
+
+	sv_slice = sh_slice = dv_slice = dh_slice = 1;
+	alpha = tpVal = 0;
+	src_width = iBuf->mdpImg.width;
+	src_height = iBuf->roi.y + iBuf->roi.height;
+	src1 = NULL;
+	dest1 = NULL;
+
+	inputRGB = outputRGB = TRUE;
+	pseudoplanr_output = FALSE;
+	ppp_operation_reg = 0;
+	ppp_dst_cfg_reg = 0;
+	ppp_src_cfg_reg = 0;
+
+	/* Wait for the pipe to clear */
+	do { } while (mdp_ppp_pipe_wait() <= 0);
+
+	/*
+	 * destination config
+	 */
+	switch (iBuf->ibuf_type) {
+	case MDP_RGB_888:
+		dst_packPattern =
+		    MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
+		ppp_dst_cfg_reg =
+		    PPP_DST_C0G_8BIT | PPP_DST_C1B_8BIT | PPP_DST_C2R_8BIT |
+		    PPP_DST_PACKET_CNT_INTERLVD_3ELEM | PPP_DST_PACK_TIGHT |
+		    PPP_DST_PACK_ALIGN_LSB | PPP_DST_OUT_SEL_AXI |
+		    PPP_DST_BPP_3BYTES | PPP_DST_PLANE_INTERLVD;
+		break;
+
+	case MDP_BGRA_8888:
+	case MDP_XRGB_8888:
+	case MDP_ARGB_8888:
+	case MDP_RGBA_8888:
+	case MDP_RGBX_8888:
+		if (iBuf->ibuf_type == MDP_BGRA_8888)
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+		else if (iBuf->ibuf_type == MDP_RGBA_8888 ||
+				 iBuf->ibuf_type == MDP_RGBX_8888)
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
+						 8);
+		else if (iBuf->ibuf_type == MDP_XRGB_8888)
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+		else
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+
+		ppp_dst_cfg_reg = PPP_DST_C0G_8BIT |
+		    PPP_DST_C1B_8BIT |
+		    PPP_DST_C2R_8BIT |
+		    PPP_DST_C3A_8BIT |
+		    PPP_DST_C3ALPHA_EN |
+		    PPP_DST_PACKET_CNT_INTERLVD_4ELEM |
+		    PPP_DST_PACK_TIGHT |
+		    PPP_DST_PACK_ALIGN_LSB |
+		    PPP_DST_OUT_SEL_AXI |
+		    PPP_DST_BPP_4BYTES | PPP_DST_PLANE_INTERLVD;
+		break;
+
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CRCB_H2V2:
+		if (iBuf->ibuf_type == MDP_Y_CBCR_H2V2)
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
+		else
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
+
+		ppp_dst_cfg_reg = PPP_DST_C2R_8BIT |
+		    PPP_DST_C0G_8BIT |
+		    PPP_DST_C1B_8BIT |
+		    PPP_DST_C3A_8BIT |
+		    PPP_DST_PACKET_CNT_INTERLVD_2ELEM |
+		    PPP_DST_PACK_TIGHT |
+		    PPP_DST_PACK_ALIGN_LSB |
+		    PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES;
+
+		ppp_operation_reg |= PPP_OP_DST_CHROMA_420;
+		outputRGB = FALSE;
+		pseudoplanr_output = TRUE;
+		/*
+		 * vertically (y direction) and horizontally (x direction)
+		 * sample reduction by 2
+		 */
+
+		/*
+		 * H2V2(YUV420) Cosite
+		 *
+		 * Y    Y    Y    Y
+		 * CbCr      CbCr
+		 * Y    Y    Y    Y
+		 * Y    Y    Y    Y
+		 * CbCr      CbCr
+		 * Y    Y    Y    Y
+		 */
+		dv_slice = dh_slice = 2;
+
+		/* (x,y) and (width,height) must be even numbern */
+		iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
+		iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
+		iBuf->roi.x = (iBuf->roi.x / 2) * 2;
+		iBuf->roi.width = (iBuf->roi.width / 2) * 2;
+
+		iBuf->roi.lcd_y = (iBuf->roi.lcd_y / 2) * 2;
+		iBuf->roi.dst_height = (iBuf->roi.dst_height / 2) * 2;
+		iBuf->roi.y = (iBuf->roi.y / 2) * 2;
+		iBuf->roi.height = (iBuf->roi.height / 2) * 2;
+		break;
+
+	case MDP_YCRYCB_H2V1:
+		dst_packPattern =
+		    MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
+		ppp_dst_cfg_reg =
+		    PPP_DST_C2R_8BIT | PPP_DST_C0G_8BIT | PPP_DST_C1B_8BIT |
+		    PPP_DST_C3A_8BIT | PPP_DST_PACKET_CNT_INTERLVD_4ELEM |
+		    PPP_DST_PACK_TIGHT | PPP_DST_PACK_ALIGN_LSB |
+		    PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES |
+		    PPP_DST_PLANE_INTERLVD;
+
+		ppp_operation_reg |= PPP_OP_DST_CHROMA_H2V1;
+		outputRGB = FALSE;
+		/*
+		 * horizontally (x direction) sample reduction by 2
+		 *
+		 * H2V1(YUV422) Cosite
+		 *
+		 * YCbCr    Y    YCbCr    Y
+		 * YCbCr    Y    YCbCr    Y
+		 * YCbCr    Y    YCbCr    Y
+		 * YCbCr    Y    YCbCr    Y
+		 */
+		dh_slice = 2;
+
+		/*
+		 * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the
+		 * preloaded gamma setting of 2.2 when the content is
+		 * non-linear ppp_lookUp_enable = TRUE;
+		 */
+
+		/* x and width must be even number */
+		iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
+		iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
+		iBuf->roi.x = (iBuf->roi.x / 2) * 2;
+		iBuf->roi.width = (iBuf->roi.width / 2) * 2;
+		break;
+
+	case MDP_Y_CBCR_H2V1:
+	case MDP_Y_CRCB_H2V1:
+		if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
+		else
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
+
+		ppp_dst_cfg_reg = PPP_DST_C2R_8BIT |
+		    PPP_DST_C0G_8BIT |
+		    PPP_DST_C1B_8BIT |
+		    PPP_DST_C3A_8BIT |
+		    PPP_DST_PACKET_CNT_INTERLVD_2ELEM |
+		    PPP_DST_PACK_TIGHT |
+		    PPP_DST_PACK_ALIGN_LSB |
+		    PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES;
+
+		ppp_operation_reg |= PPP_OP_DST_CHROMA_H2V1;
+		outputRGB = FALSE;
+		pseudoplanr_output = TRUE;
+		/* horizontally (x direction) sample reduction by 2 */
+		dh_slice = 2;
+
+		/* x and width must be even number */
+		iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
+		iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
+		iBuf->roi.x = (iBuf->roi.x / 2) * 2;
+		iBuf->roi.width = (iBuf->roi.width / 2) * 2;
+		break;
+
+	case MDP_BGR_565:
+	case MDP_RGB_565:
+	default:
+		if (iBuf->ibuf_type == MDP_RGB_565)
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
+		else
+			dst_packPattern =
+			    MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
+
+		ppp_dst_cfg_reg = PPP_DST_C0G_6BIT |
+		    PPP_DST_C1B_5BIT |
+		    PPP_DST_C2R_5BIT |
+		    PPP_DST_PACKET_CNT_INTERLVD_3ELEM |
+		    PPP_DST_PACK_TIGHT |
+		    PPP_DST_PACK_ALIGN_LSB |
+		    PPP_DST_OUT_SEL_AXI |
+		    PPP_DST_BPP_2BYTES | PPP_DST_PLANE_INTERLVD;
+		break;
+	}
+
+	/* source config */
+	switch (iBuf->mdpImg.imgType) {
+	case MDP_RGB_888:
+		inpBpp = 3;
+		/*
+		 * 565 = 2bytes
+		 * RGB = 3Components
+		 * RGB interleaved
+		 */
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
+			PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_3BYTES |
+			PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
+			PPP_SRC_UNPACK_ALIGN_LSB |
+			PPP_SRC_FETCH_PLANES_INTERLVD;
+
+		packPattern = MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
+
+		ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
+		    PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
+		break;
+
+	case MDP_BGRA_8888:
+	case MDP_RGBA_8888:
+	case MDP_ARGB_8888:
+		perPixelAlpha = TRUE;
+	case MDP_XRGB_8888:
+	case MDP_RGBX_8888:
+		inpBpp = 4;
+		/*
+		 * 8888 = 4bytes
+		 * ARGB = 4Components
+		 * ARGB interleaved
+		 */
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
+			PPP_SRC_C1B_8BITS | PPP_SRC_C3A_8BITS |
+			PPP_SRC_C3_ALPHA_EN | PPP_SRC_BPP_INTERLVD_4BYTES |
+			PPP_SRC_INTERLVD_4COMPONENTS | PPP_SRC_UNPACK_TIGHT |
+			PPP_SRC_UNPACK_ALIGN_LSB |
+			PPP_SRC_FETCH_PLANES_INTERLVD;
+
+		if (iBuf->mdpImg.imgType == MDP_BGRA_8888)
+			packPattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+		else if (iBuf->mdpImg.imgType == MDP_RGBA_8888 ||
+				 iBuf->mdpImg.imgType == MDP_RGBX_8888)
+			packPattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
+						 8);
+		else if (iBuf->ibuf_type == MDP_XRGB_8888)
+			packPattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+		else
+			packPattern =
+			    MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
+						 8);
+
+		ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
+		    PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
+		break;
+
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CBCR_H2V2_ADRENO:
+	case MDP_Y_CRCB_H2V2:
+		inpBpp = 1;
+		src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
+
+		/*
+		 * CbCr = 2bytes
+		 * CbCr = 2Components
+		 * Y+CbCr
+		 */
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS |
+			PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
+			PPP_SRC_INTERLVD_2COMPONENTS | PPP_SRC_UNPACK_TIGHT |
+			PPP_SRC_UNPACK_ALIGN_LSB |
+			PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
+
+		if (iBuf->mdpImg.imgType == MDP_Y_CRCB_H2V2)
+			packPattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
+		else
+			packPattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
+
+		ppp_operation_reg |= PPP_OP_COLOR_SPACE_YCBCR |
+		    PPP_OP_SRC_CHROMA_420 |
+		    PPP_OP_SRC_CHROMA_COSITE |
+		    PPP_OP_DST_CHROMA_RGB | PPP_OP_DST_CHROMA_COSITE;
+
+		inputRGB = FALSE;
+		sh_slice = sv_slice = 2;
+		break;
+
+	case MDP_YCRYCB_H2V1:
+		inpBpp = 2;
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
+		    PPP_SRC_C0G_8BITS |
+		    PPP_SRC_C1B_8BITS |
+		    PPP_SRC_C3A_8BITS |
+		    PPP_SRC_BPP_INTERLVD_2BYTES |
+		    PPP_SRC_INTERLVD_4COMPONENTS |
+		    PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB;
+
+		packPattern =
+		    MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
+
+		ppp_operation_reg |= PPP_OP_SRC_CHROMA_H2V1 |
+		    PPP_OP_SRC_CHROMA_COSITE | PPP_OP_DST_CHROMA_COSITE;
+
+		/*
+		 * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the
+		 * preloaded inverse gamma setting of 2.2 since they're
+		 * symetric when the content is non-linear
+		 * ppp_lookUp_enable = TRUE;
+		 */
+
+		/* x and width must be even number */
+		iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2;
+		iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2;
+		iBuf->roi.x = (iBuf->roi.x / 2) * 2;
+		iBuf->roi.width = (iBuf->roi.width / 2) * 2;
+
+		inputRGB = FALSE;
+		sh_slice = 2;
+		break;
+
+	case MDP_Y_CBCR_H2V1:
+	case MDP_Y_CRCB_H2V1:
+		inpBpp = 1;
+		src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
+
+		ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
+		    PPP_SRC_C0G_8BITS |
+		    PPP_SRC_C1B_8BITS |
+		    PPP_SRC_C3A_8BITS |
+		    PPP_SRC_BPP_INTERLVD_2BYTES |
+		    PPP_SRC_INTERLVD_2COMPONENTS |
+		    PPP_SRC_UNPACK_TIGHT |
+		    PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR;
+
+		if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V1)
+			packPattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
+		else
+			packPattern =
+			    MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
+
+		ppp_operation_reg |= PPP_OP_SRC_CHROMA_H2V1 |
+		    PPP_OP_SRC_CHROMA_COSITE | PPP_OP_DST_CHROMA_COSITE;
+		inputRGB = FALSE;
+		sh_slice = 2;
+		break;
+
+	case MDP_BGR_565:
+	case MDP_RGB_565:
+	default:
+		inpBpp = 2;
+		/*
+		 * 565 = 2bytes
+		 * RGB = 3Components
+		 * RGB interleaved
+		 */
+		ppp_src_cfg_reg = PPP_SRC_C2R_5BITS | PPP_SRC_C0G_6BITS |
+			PPP_SRC_C1B_5BITS | PPP_SRC_BPP_INTERLVD_2BYTES |
+			PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT |
+			PPP_SRC_UNPACK_ALIGN_LSB |
+			PPP_SRC_FETCH_PLANES_INTERLVD;
+
+		if (iBuf->mdpImg.imgType == MDP_RGB_565)
+			packPattern =
+			    MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
+		else
+			packPattern =
+			    MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
+
+		ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB |
+		    PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB;
+		break;
+
+	}
+
+	if (pseudoplanr_output)
+		ppp_dst_cfg_reg |= PPP_DST_PLANE_PSEUDOPLN;
+
+	/* YCbCr to RGB color conversion flag */
+	if ((!inputRGB) && (outputRGB)) {
+		ppp_operation_reg |= PPP_OP_CONVERT_YCBCR2RGB |
+		    PPP_OP_CONVERT_ON;
+
+		/*
+		 * primary/secondary is sort of misleading term...but
+		 * in mdp2.2/3.0 we only use primary matrix (forward/rev)
+		 * in mdp3.1 we use set1(prim) and set2(secd)
+		 */
+#ifdef CONFIG_FB_MSM_MDP31
+		ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_SECONDARY |
+					PPP_OP_DST_RGB;
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0);
+#endif
+
+		if (ppp_lookUp_enable) {
+			ppp_operation_reg |= PPP_OP_LUT_C0_ON |
+			    PPP_OP_LUT_C1_ON | PPP_OP_LUT_C2_ON;
+		}
+	}
+	/* RGB to YCbCr color conversion flag */
+	if ((inputRGB) && (!outputRGB)) {
+		ppp_operation_reg |= PPP_OP_CONVERT_RGB2YCBCR |
+		    PPP_OP_CONVERT_ON;
+
+#ifdef CONFIG_FB_MSM_MDP31
+		ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_PRIMARY |
+					PPP_OP_DST_YCBCR;
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0x1e);
+#endif
+
+		if (ppp_lookUp_enable) {
+			ppp_operation_reg |= PPP_OP_LUT_C0_ON |
+			    PPP_OP_LUT_C1_ON | PPP_OP_LUT_C2_ON;
+		}
+	}
+	/* YCbCr to YCbCr color conversion flag */
+	if ((!inputRGB) && (!outputRGB)) {
+		if ((ppp_lookUp_enable) &&
+		    (iBuf->mdpImg.imgType != iBuf->ibuf_type)) {
+			ppp_operation_reg |= PPP_OP_LUT_C0_ON;
+		}
+	}
+
+	ppp_src_cfg_reg |= (iBuf->roi.x % 2) ? PPP_SRC_BPP_ROI_ODD_X : 0;
+	ppp_src_cfg_reg |= (iBuf->roi.y % 2) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
+
+	if (req->flags & MDP_DEINTERLACE)
+		ppp_operation_reg |= PPP_OP_DEINT_EN;
+
+	/* Dither at DMA side only since iBuf format is RGB888 */
+	if (iBuf->mdpImg.mdpOp & MDPOP_DITHER)
+		ppp_operation_reg |= PPP_OP_DITHER_EN;
+
+	if (iBuf->mdpImg.mdpOp & MDPOP_ROTATION) {
+		ppp_operation_reg |= PPP_OP_ROT_ON;
+
+		if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
+			ppp_operation_reg |= PPP_OP_ROT_90;
+		}
+		if (iBuf->mdpImg.mdpOp & MDPOP_LR) {
+			ppp_operation_reg |= PPP_OP_FLIP_LR;
+		}
+		if (iBuf->mdpImg.mdpOp & MDPOP_UD) {
+			ppp_operation_reg |= PPP_OP_FLIP_UD;
+		}
+	}
+
+	if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
+		src0_ystride = ALIGN(src_width, 32) * inpBpp;
+	else
+		src0_ystride = src_width * inpBpp;
+
+	if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
+		src0_y1stride = 2 * ALIGN(src_width/2, 32);
+	else
+		src0_y1stride = src0_ystride;
+
+	dest0_ystride = iBuf->ibuf_width * iBuf->bpp;
+
+	/* no need to care about rotation since it's the real-XY. */
+	dst_roi_width = iBuf->roi.dst_width;
+	dst_roi_height = iBuf->roi.dst_height;
+
+	src0 = (uint8 *) iBuf->mdpImg.bmy_addr;
+	dest0 = (uint8 *) iBuf->buf;
+
+	/* Jumping from Y-Plane to Chroma Plane */
+	dest1 = mdp_get_chroma_addr(iBuf);
+
+	/* first pixel addr calculation */
+	mdp_adjust_start_addr(&src0, &src1, sv_slice, sh_slice, iBuf->roi.x,
+			      iBuf->roi.y, src_width, src_height, inpBpp, iBuf,
+			      0);
+	mdp_adjust_start_addr(&dest0, &dest1, dv_slice, dh_slice,
+			      iBuf->roi.lcd_x, iBuf->roi.lcd_y,
+			      iBuf->ibuf_width, iBuf->ibuf_height, iBuf->bpp,
+			      iBuf, 2);
+
+	/* set scale operation */
+	mdp_set_scale(iBuf, dst_roi_width, dst_roi_height,
+		      inputRGB, outputRGB, &ppp_operation_reg);
+
+	/*
+	 * setting background source for blending
+	 */
+	mdp_set_blend_attr(iBuf, &alpha, &tpVal, perPixelAlpha,
+			   &ppp_operation_reg);
+
+	if (ppp_operation_reg & PPP_OP_BLEND_ON) {
+		mdp_ppp_setbg(iBuf);
+
+		if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
+			ppp_operation_reg |= PPP_OP_BG_CHROMA_H2V1;
+
+			if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) {
+				tpVal = mdp_conv_matx_rgb2yuv(tpVal,
+						      (uint16 *) &
+						      mdp_ccs_rgb2yuv,
+						      &mdp_plv[0], NULL);
+			}
+		}
+	}
+
+	/*
+	 * 0x0004: enable dbg bus
+	 * 0x0100: "don't care" Edge Condit until scaling is on
+	 * 0x0104: xrc tile x&y size u7.6 format = 7bit.6bit
+	 * 0x0108: src pixel size
+	 * 0x010c: component plane 0 starting address
+	 * 0x011c: component plane 0 ystride
+	 * 0x0124: PPP source config register
+	 * 0x0128: unpacked pattern from lsb to msb (eg. RGB->BGR)
+	 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0108, (iBuf->roi.height << 16 |
+						      iBuf->roi.width));
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x010c, src0); /* comp.plane 0 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0110, src1); /* comp.plane 1 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x011c,
+		 (src0_y1stride << 16 | src0_ystride));
+
+	/* setup for rgb 565 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0124, ppp_src_cfg_reg);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0128, packPattern);
+	/*
+	 * 0x0138: PPP destination operation register
+	 * 0x014c: constant_alpha|transparent_color
+	 * 0x0150: PPP destination config register
+	 * 0x0154: PPP packing pattern
+	 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0138, ppp_operation_reg);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x014c, alpha << 24 | (tpVal &
+								0xffffff));
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0150, ppp_dst_cfg_reg);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0154, dst_packPattern);
+
+	/*
+	 * 0x0164: ROI height and width
+	 * 0x0168: Component Plane 0 starting addr
+	 * 0x016c: Component Plane 1 starting addr
+	 * 0x0178: Component Plane 1/0 y stride
+	 */
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0164,
+		 (dst_roi_height << 16 | dst_roi_width));
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0168, dest0);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x016c, dest1);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0178,
+		 (dest0_ystride << 16 | dest0_ystride));
+
+	flush_imgs(req, inpBpp, iBuf->bpp, p_src_file, p_dst_file);
+#ifdef	CONFIG_FB_MSM_MDP31
+	MDP_OUTP(MDP_BASE + 0x00100, 0xFF00);
+#endif
+	mdp_pipe_kickoff(MDP_PPP_TERM, mfd);
+}
+
+static int mdp_ppp_verify_req(struct mdp_blit_req *req)
+{
+	u32 src_width, src_height, dst_width, dst_height;
+
+	if (req == NULL) {
+		printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
+			__LINE__);
+		return -1;
+	}
+
+	if (MDP_IS_IMGTYPE_BAD(req->src.format) ||
+	    MDP_IS_IMGTYPE_BAD(req->dst.format)) {
+		printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
+			__LINE__);
+		return -1;
+	}
+
+	if ((req->src.width == 0) || (req->src.height == 0) ||
+	    (req->src_rect.w == 0) || (req->src_rect.h == 0) ||
+	    (req->dst.width == 0) || (req->dst.height == 0) ||
+	    (req->dst_rect.w == 0) || (req->dst_rect.h == 0)) {
+		printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
+			__LINE__);
+
+		return -1;
+	}
+
+	if (((req->src_rect.x + req->src_rect.w) > req->src.width) ||
+	    ((req->src_rect.y + req->src_rect.h) > req->src.height)) {
+		printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
+			__LINE__);
+		return -1;
+	}
+
+	if (((req->dst_rect.x + req->dst_rect.w) > req->dst.width) ||
+	    ((req->dst_rect.y + req->dst_rect.h) > req->dst.height)) {
+		printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
+			__LINE__);
+		return -1;
+	}
+
+	/*
+	 * scaling range check
+	 */
+	src_width = req->src_rect.w;
+	src_height = req->src_rect.h;
+
+	if (req->flags & MDP_ROT_90) {
+		dst_width = req->dst_rect.h;
+		dst_height = req->dst_rect.w;
+	} else {
+		dst_width = req->dst_rect.w;
+		dst_height = req->dst_rect.h;
+	}
+
+	switch (req->dst.format) {
+	case MDP_Y_CRCB_H2V2:
+	case MDP_Y_CBCR_H2V2:
+		src_width = (src_width / 2) * 2;
+		src_height = (src_height / 2) * 2;
+		dst_width = (src_width / 2) * 2;
+		dst_height = (src_height / 2) * 2;
+		break;
+
+	case MDP_Y_CRCB_H2V1:
+	case MDP_Y_CBCR_H2V1:
+	case MDP_YCRYCB_H2V1:
+		src_width = (src_width / 2) * 2;
+		dst_width = (src_width / 2) * 2;
+		break;
+
+	default:
+		break;
+	}
+
+	if (((MDP_SCALE_Q_FACTOR * dst_width) / src_width >
+	     MDP_MAX_X_SCALE_FACTOR)
+	    || ((MDP_SCALE_Q_FACTOR * dst_width) / src_width <
+		MDP_MIN_X_SCALE_FACTOR)) {
+		printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
+			__LINE__);
+		return -1;
+	}
+
+	if (((MDP_SCALE_Q_FACTOR * dst_height) / src_height >
+	     MDP_MAX_Y_SCALE_FACTOR)
+	    || ((MDP_SCALE_Q_FACTOR * dst_height) / src_height <
+		MDP_MIN_Y_SCALE_FACTOR)) {
+		printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
+			__LINE__);
+		return -1;
+	}
+	return 0;
+}
+
+int get_gem_img(struct mdp_img *img, unsigned long *start, unsigned long *len)
+{
+	/* Set len to zero to appropriately error out if
+	   kgsl_gem_obj_addr fails */
+
+	*len = 0;
+	return kgsl_gem_obj_addr(img->memory_id, (int) img->priv, start, len);
+}
+
+int get_img(struct mdp_img *img, struct mdp_blit_req *req,
+		struct fb_info *info, unsigned long *start, unsigned long *len,
+		struct file **srcp_file, struct ion_handle **srcp_ihdl)
+{
+	int put_needed, fb_num, ret = 0;
+	struct file *file;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+	unsigned long vstart;
+#endif
+
+	if (req->flags & MDP_MEMORY_ID_TYPE_FB) {
+		file = fget_light(img->memory_id, &put_needed);
+		if (file == NULL)
+			return -EINVAL;
+
+		if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
+			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
+			if (get_fb_phys_info(start, len, fb_num,
+				DISPLAY_SUBSYSTEM_ID)) {
+				pr_err("get_fb_phys_info() failed\n");
+				fput_light(file, put_needed);
+			} else {
+				*srcp_file = file;
+			}
+
+			return ret;
+		} else {
+			fput_light(file, put_needed);
+		}
+	}
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		*srcp_ihdl = ion_import_fd(mfd->iclient, img->memory_id);
+		if (IS_ERR_OR_NULL(*srcp_ihdl))
+			return PTR_ERR(*srcp_ihdl);
+
+		if (!ion_phys(mfd->iclient, *srcp_ihdl, start, (size_t *) len))
+			return ret;
+		 else
+			return -EINVAL;
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+	if (!get_pmem_file(img->memory_id, start, &vstart, len, srcp_file))
+		return ret;
+	else
+		return -EINVAL;
+#endif
+}
+
+void put_img(struct file *p_src_file, struct ion_handle *p_ihdl)
+{
+#ifdef CONFIG_ANDROID_PMEM
+	if (p_src_file)
+		put_pmem_file(p_src_file);
+#endif
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	if (!IS_ERR_OR_NULL(p_ihdl))
+		ion_free(ppp_display_iclient, p_ihdl);
+#endif
+}
+
+
+static int mdp_ppp_blit_addr(struct fb_info *info, struct mdp_blit_req *req,
+	unsigned long srcp0_start, unsigned long srcp0_len,
+	unsigned long srcp1_start, unsigned long srcp1_len,
+	unsigned long dst_start, unsigned long dst_len,
+	struct file *p_src_file, struct file *p_dst_file,
+	struct ion_handle **src_ihdl, struct ion_handle **dst_ihdl)
+{
+	MDPIBUF iBuf;
+	u32 dst_width, dst_height;
+	struct msm_fb_data_type *mfd = info->par;
+
+	if (req->dst.format == MDP_FB_FORMAT)
+		req->dst.format =  mfd->fb_imgType;
+	if (req->src.format == MDP_FB_FORMAT)
+		req->src.format = mfd->fb_imgType;
+
+	if (mdp_ppp_verify_req(req)) {
+		pr_err("mdp_ppp: invalid image!\n");
+		put_img(p_src_file, *src_ihdl);
+		put_img(p_dst_file, *dst_ihdl);
+		return -1;
+	}
+
+	iBuf.ibuf_width = req->dst.width;
+	iBuf.ibuf_height = req->dst.height;
+	iBuf.bpp = bytes_per_pixel[req->dst.format];
+
+	iBuf.ibuf_type = req->dst.format;
+	iBuf.buf = (uint8 *) dst_start;
+	iBuf.buf += req->dst.offset;
+
+	iBuf.roi.lcd_x = req->dst_rect.x;
+	iBuf.roi.lcd_y = req->dst_rect.y;
+	iBuf.roi.dst_width = req->dst_rect.w;
+	iBuf.roi.dst_height = req->dst_rect.h;
+
+	iBuf.roi.x = req->src_rect.x;
+	iBuf.roi.width = req->src_rect.w;
+	iBuf.roi.y = req->src_rect.y;
+	iBuf.roi.height = req->src_rect.h;
+
+	iBuf.mdpImg.width = req->src.width;
+	iBuf.mdpImg.imgType = req->src.format;
+
+
+	iBuf.mdpImg.bmy_addr = (uint32 *) (srcp0_start + req->src.offset);
+	if (iBuf.mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
+		iBuf.mdpImg.cbcr_addr =
+			(uint32 *) ((uint32) iBuf.mdpImg.bmy_addr +
+				ALIGN((ALIGN(req->src.width, 32) *
+				ALIGN(req->src.height, 32)), 4096));
+	else
+		iBuf.mdpImg.cbcr_addr = srcp1_start ? (uint32 *)srcp1_start :
+			(uint32 *) ((uint32) iBuf.mdpImg.bmy_addr +
+			req->src.width * req->src.height);
+
+	iBuf.mdpImg.mdpOp = MDPOP_NOP;
+
+	/* blending check */
+	if (req->transp_mask != MDP_TRANSP_NOP) {
+		iBuf.mdpImg.mdpOp |= MDPOP_TRANSP;
+		iBuf.mdpImg.tpVal = req->transp_mask;
+		iBuf.mdpImg.tpVal = mdp_calc_tpval(&iBuf.mdpImg);
+	} else {
+		iBuf.mdpImg.tpVal = 0;
+	}
+
+	req->alpha &= 0xff;
+	if (req->alpha < MDP_ALPHA_NOP) {
+		iBuf.mdpImg.mdpOp |= MDPOP_ALPHAB;
+		iBuf.mdpImg.alpha = req->alpha;
+	} else {
+		iBuf.mdpImg.alpha = 0xff;
+	}
+
+	/* rotation check */
+	if (req->flags & MDP_FLIP_LR)
+		iBuf.mdpImg.mdpOp |= MDPOP_LR;
+	if (req->flags & MDP_FLIP_UD)
+		iBuf.mdpImg.mdpOp |= MDPOP_UD;
+	if (req->flags & MDP_ROT_90)
+		iBuf.mdpImg.mdpOp |= MDPOP_ROT90;
+	if (req->flags & MDP_DITHER)
+		iBuf.mdpImg.mdpOp |= MDPOP_DITHER;
+
+	if (req->flags & MDP_BLEND_FG_PREMULT) {
+#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP303)
+		iBuf.mdpImg.mdpOp |= MDPOP_FG_PM_ALPHA;
+#else
+		put_img(p_src_file, *src_ihdl);
+		put_img(p_dst_file, *dst_ihdl);
+		return -EINVAL;
+#endif
+	}
+
+	if (req->flags & MDP_DEINTERLACE) {
+#ifdef CONFIG_FB_MSM_MDP31
+		if ((req->src.format != MDP_Y_CBCR_H2V2) &&
+			(req->src.format != MDP_Y_CRCB_H2V2)) {
+#endif
+			put_img(p_src_file, *src_ihdl);
+			put_img(p_dst_file, *dst_ihdl);
+			return -EINVAL;
+#ifdef CONFIG_FB_MSM_MDP31
+		}
+#endif
+	}
+
+	/* scale check */
+	if (req->flags & MDP_ROT_90) {
+		dst_width = req->dst_rect.h;
+		dst_height = req->dst_rect.w;
+	} else {
+		dst_width = req->dst_rect.w;
+		dst_height = req->dst_rect.h;
+	}
+
+	if ((iBuf.roi.width != dst_width) || (iBuf.roi.height != dst_height))
+		iBuf.mdpImg.mdpOp |= MDPOP_ASCALE;
+
+	if (req->flags & MDP_BLUR) {
+#ifdef CONFIG_FB_MSM_MDP31
+		if (req->flags & MDP_SHARPENING)
+			printk(KERN_WARNING
+				"mdp: MDP_SHARPENING is set with MDP_BLUR!\n");
+		req->flags |= MDP_SHARPENING;
+		req->sharpening_strength = -127;
+#else
+		iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_BLUR;
+
+#endif
+	}
+
+	if (req->flags & MDP_SHARPENING) {
+#ifdef CONFIG_FB_MSM_MDP31
+		if ((req->sharpening_strength > 127) ||
+			(req->sharpening_strength < -127)) {
+			printk(KERN_ERR
+				"%s: sharpening strength out of range\n",
+				__func__);
+			put_img(p_src_file, *src_ihdl);
+			put_img(p_dst_file, *dst_ihdl);
+			return -EINVAL;
+		}
+
+		iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_SHARPENING;
+		iBuf.mdpImg.sp_value = req->sharpening_strength & 0xff;
+#else
+		put_img(p_src_file, *src_ihdl);
+		put_img(p_dst_file, *dst_ihdl);
+		return -EINVAL;
+#endif
+	}
+
+	down(&mdp_ppp_mutex);
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+#ifndef CONFIG_FB_MSM_MDP22
+	mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
+#else
+	/* bg tile fetching HW workaround */
+	if (((iBuf.mdpImg.mdpOp & (MDPOP_TRANSP | MDPOP_ALPHAB)) ||
+	     (req->src.format == MDP_ARGB_8888) ||
+	     (req->src.format == MDP_BGRA_8888) ||
+	     (req->src.format == MDP_RGBA_8888)) &&
+	    (iBuf.mdpImg.mdpOp & MDPOP_ROT90) && (req->dst_rect.w <= 16)) {
+		int dst_h, src_w, i;
+		uint32 mdpOp = iBuf.mdpImg.mdpOp;
+
+		src_w = req->src_rect.w;
+		dst_h = iBuf.roi.dst_height;
+
+		for (i = 0; i < (req->dst_rect.h / 16); i++) {
+			/* this tile size */
+			iBuf.roi.dst_height = 16;
+			iBuf.roi.width =
+			    (16 * req->src_rect.w) / req->dst_rect.h;
+
+			/* if it's out of scale range... */
+			if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
+			     iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR)
+				iBuf.roi.width =
+				    (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
+				    MDP_MAX_X_SCALE_FACTOR;
+			else if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
+				  iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR)
+				iBuf.roi.width =
+				    (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
+				    MDP_MIN_X_SCALE_FACTOR;
+
+			mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
+
+			/* next tile location */
+			iBuf.roi.lcd_y += 16;
+			iBuf.roi.x += iBuf.roi.width;
+
+			/* this is for a remainder update */
+			dst_h -= 16;
+			src_w -= iBuf.roi.width;
+			/* restore mdpOp since MDPOP_ASCALE have been cleared */
+			iBuf.mdpImg.mdpOp = mdpOp;
+		}
+
+		if ((dst_h < 0) || (src_w < 0))
+			printk
+			    ("msm_fb: mdp_blt_ex() unexpected result! line:%d\n",
+			     __LINE__);
+
+		/* remainder update */
+		if ((dst_h > 0) && (src_w > 0)) {
+			u32 tmp_v;
+
+			iBuf.roi.dst_height = dst_h;
+			iBuf.roi.width = src_w;
+
+			if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
+			     iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR) {
+				tmp_v =
+				    (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
+				    MDP_MAX_X_SCALE_FACTOR +
+				    (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) %
+				    MDP_MAX_X_SCALE_FACTOR ? 1 : 0;
+
+				/* move x location as roi width gets bigger */
+				iBuf.roi.x -= tmp_v - iBuf.roi.width;
+				iBuf.roi.width = tmp_v;
+			} else
+			    if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
+				 iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR) {
+				tmp_v =
+				    (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
+				    MDP_MIN_X_SCALE_FACTOR +
+				    (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) %
+				    MDP_MIN_X_SCALE_FACTOR ? 1 : 0;
+
+				/*
+				 * we don't move x location for continuity of
+				 * source image
+				 */
+				iBuf.roi.width = tmp_v;
+			}
+
+			mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
+		}
+	} else {
+		mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
+	}
+#endif
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	up(&mdp_ppp_mutex);
+
+	put_img(p_src_file, *src_ihdl);
+	put_img(p_dst_file, *dst_ihdl);
+	return 0;
+}
+
+int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req)
+{
+	unsigned long src_start, dst_start;
+	unsigned long src_len = 0;
+	unsigned long dst_len = 0;
+	struct file *p_src_file = 0 , *p_dst_file = 0;
+	struct ion_handle *src_ihdl = NULL;
+	struct ion_handle *dst_ihdl = NULL;
+	struct msm_fb_data_type *mfd = info->par;
+	ppp_display_iclient = mfd->iclient;
+
+	if (req->flags & MDP_BLIT_SRC_GEM)
+		get_gem_img(&req->src, &src_start, &src_len);
+	else
+		get_img(&req->src, req, info, &src_start, &src_len, &p_src_file,
+			&src_ihdl);
+	if (src_len == 0) {
+		pr_err("mdp_ppp: could not retrieve source image from "
+		       "memory\n");
+		return -EINVAL;
+	}
+	if (req->flags & MDP_BLIT_DST_GEM)
+		get_gem_img(&req->dst, &dst_start, &dst_len);
+	else
+		get_img(&req->dst, req, info, &dst_start, &dst_len, &p_dst_file,
+			&dst_ihdl);
+
+	if (dst_len == 0) {
+		put_img(p_src_file, src_ihdl);
+		pr_err("mdp_ppp: could not retrieve destination image from "
+		       "memory\n");
+		return -EINVAL;
+	}
+
+	return mdp_ppp_blit_addr(info, req, src_start, src_len, 0, 0, dst_start,
+		dst_len, p_src_file, p_dst_file, &src_ihdl, &dst_ihdl);
+}
+
+static struct mdp_blit_req overlay_req;
+static bool mdp_overlay_req_set;
+
+int mdp_ppp_v4l2_overlay_set(struct fb_info *info, struct mdp_overlay *req)
+{
+	memset(&overlay_req, 0, sizeof(struct mdp_blit_req));
+
+	overlay_req.src.width  = req->src.width;
+	overlay_req.src.height = req->src.height;
+	overlay_req.src.format = req->src.format;
+
+
+	overlay_req.dst.width  = req->dst_rect.w;
+	overlay_req.dst.height = req->dst_rect.h;
+	overlay_req.dst.format = MDP_FB_FORMAT;
+	overlay_req.transp_mask = req->transp_mask;
+	overlay_req.flags = req->flags;
+	overlay_req.alpha = req->alpha;
+
+	overlay_req.src_rect.x = req->src_rect.x;
+	overlay_req.src_rect.y = req->src_rect.y;
+	overlay_req.src_rect.w = req->src_rect.w;
+	overlay_req.src_rect.h = req->src_rect.h;
+	overlay_req.dst_rect.x = req->dst_rect.x;
+	overlay_req.dst_rect.y = req->dst_rect.y;
+	overlay_req.dst_rect.w = req->dst_rect.w;
+	overlay_req.dst_rect.h = req->dst_rect.h;
+	mdp_overlay_req_set = true;
+
+	pr_debug("%s: Overlay parameters:", __func__);
+	pr_debug("Src_Image (%u %u)\n", overlay_req.src.width,
+	overlay_req.src.height);
+
+	if (overlay_req.src.format == MDP_Y_CRCB_H2V2)
+		pr_debug("Overlay format MDP_Y_CRCB_H2V2\n");
+	else if (overlay_req.src.format == MDP_RGB_565)
+		pr_debug("Overlay format MDP_RGB_565\n");
+	else
+		pr_debug("Overlay format(%u) unknown\n",
+		overlay_req.src.format);
+
+	pr_debug("Dst_Image (%u %u)\n", overlay_req.dst.width,
+		overlay_req.dst.height);
+	pr_debug("Src rect: (%u,%u,%u,%u), Dst rect: (%u,%u,%u,%u)\n",
+		overlay_req.src_rect.x, overlay_req.src_rect.y,
+		overlay_req.src_rect.w, overlay_req.src_rect.h,
+		overlay_req.dst_rect.x, overlay_req.dst_rect.y,
+		overlay_req.dst_rect.w, overlay_req.dst_rect.h);
+	return 0;
+}
+
+int mdp_ppp_v4l2_overlay_clear(void)
+{
+	memset(&overlay_req, 0, sizeof(struct mdp_overlay));
+	mdp_overlay_req_set = false;
+	return 0;
+}
+
+int mdp_ppp_v4l2_overlay_play(struct fb_info *info,
+	unsigned long srcp0_addr, unsigned long srcp0_size,
+	unsigned long srcp1_addr, unsigned long srcp1_size)
+{
+	int ret;
+
+	if (!mdp_overlay_req_set) {
+		pr_err("mdp_ppp:v4l2:No overlay set, ignore play req\n");
+		return -EINVAL;
+	}
+
+	overlay_req.dst.width = info->var.xres;
+	overlay_req.dst.height = info->var.yres;
+
+	ret = mdp_ppp_blit_addr(info, &overlay_req,
+		srcp0_addr, srcp0_size, srcp1_addr, srcp1_size,
+		info->fix.smem_start, info->fix.smem_len, NULL, NULL,
+		NULL, NULL);
+
+	if (ret)
+		pr_err("%s:Blitting overlay failed(%d)\n", __func__, ret);
+
+	return ret;
+}
diff --git a/drivers/video/msm/mdp_ppp.h b/drivers/video/msm/mdp_ppp.h
index 7a8ea37..e045643 100644
--- a/drivers/video/msm/mdp_ppp.h
+++ b/drivers/video/msm/mdp_ppp.h
@@ -16,7 +16,6 @@
 #define _VIDEO_MSM_MDP_PPP_H_
 
 #include <linux/types.h>
-#define  PPP_DUMP_BLITS 0
 
 struct ppp_regs {
 	uint32_t src0;
@@ -63,59 +62,21 @@
 struct mdp_info;
 struct mdp_rect;
 struct mdp_blit_req;
-struct fb_info;
 
-#ifdef CONFIG_FB_MSM_MDP_PPP
-int mdp_get_bytes_per_pixel(int format);
-int mdp_ppp_blit(struct mdp_info *mdp, struct fb_info *fb,
-		 struct mdp_blit_req *req);
-void mdp_ppp_handle_isr(struct mdp_info *mdp, uint32_t mask);
-int mdp_ppp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req,
-			  struct file *src_file, unsigned long src_start,
-			  unsigned long src_len, struct file *dst_file,
-			  unsigned long dst_start, unsigned long dst_len);
+void mdp_ppp_init_scale(const struct mdp_info *mdp);
+int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
+		      struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
+		      uint32_t src_format, uint32_t dst_format);
+int mdp_ppp_load_blur(const struct mdp_info *mdp);
 
-/* these must be provided by h/w specific ppp files */
-void mdp_ppp_init_scale(struct mdp_info *mdp);
-int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs,
-		 struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
-		 uint32_t src_format, uint32_t dst_format);
-int mdp_ppp_load_blur(struct mdp_info *mdp);
+#ifndef CONFIG_MSM_MDP31
 int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs);
-int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req);
-int mdp_ppp_do_blit(struct mdp_info *mdp, struct mdp_blit_req *req,
-		    struct file *src_file, unsigned long src_start,
-		    unsigned long src_len, struct file *dst_file,
-		    unsigned long dst_start, unsigned long dst_len);
-int mdp_fb_mirror(struct mdp_device *mdp_dev,
-		struct fb_info *src_fb, struct fb_info *dst_fb,
-		struct mdp_blit_req *req);
 #else
-
-static inline int mdp_get_bytes_per_pixel(int format) { return -1; }
-static inline int mdp_ppp_blit(struct mdp_info *mdp, struct fb_info *fb,
-			       struct mdp_blit_req *req) { return -EINVAL; }
-static inline void mdp_ppp_handle_isr(struct mdp_info *mdp, uint32_t mask) {}
-static inline int mdp_ppp_blit_and_wait(struct mdp_info *mdp,
-		struct mdp_blit_req *req, struct file *src_file,
-		unsigned long src_start, unsigned long src_len,
-		struct file *dst_file, unsigned long dst_start,
-		unsigned long dst_len) { return 0; }
-
-static inline void mdp_ppp_init_scale(struct mdp_info *mdp) {}
-static inline int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs,
-		 struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
-		 uint32_t src_format, uint32_t dst_format) { return 0; }
-static inline int mdp_ppp_load_blur(struct mdp_info *mdp) { return 0; }
-static inline int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs) { return 0; }
-static inline int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req) { return -EINVAL; }
-static inline int mdp_ppp_do_blit(struct mdp_info *mdp,
-		struct mdp_blit_req *req,
-		struct file *src_file, unsigned long src_start,
-		unsigned long src_len, struct file *dst_file,
-		unsigned long dst_start, unsigned long dst_len) { return 0; }
-
-
-#endif /* CONFIG_FB_MSM_MDP_PPP */
+static inline int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req,
+				 struct ppp_regs *regs)
+{
+	return 0;
+}
+#endif
 
 #endif /* _VIDEO_MSM_MDP_PPP_H_ */
diff --git a/drivers/video/msm/mdp_ppp22.c b/drivers/video/msm/mdp_ppp22.c
new file mode 100644
index 0000000..9016f0a
--- /dev/null
+++ b/drivers/video/msm/mdp_ppp22.c
@@ -0,0 +1,1091 @@
+/* drivers/video/msm/mdp_ppp22.c
+ *
+ * Copyright (C) 2007 Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2007 Google Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/msm_mdp.h>
+
+#include "mdp_hw.h"
+#include "mdp_ppp.h"
+
+struct mdp_table_entry {
+	uint32_t reg;
+	uint32_t val;
+};
+
+enum {
+	MDP_DOWNSCALE_PT2TOPT4,
+	MDP_DOWNSCALE_PT4TOPT6,
+	MDP_DOWNSCALE_PT6TOPT8,
+	MDP_DOWNSCALE_PT8TO1,
+	MDP_DOWNSCALE_MAX,
+
+	/* not technically in the downscale table list */
+	MDP_DOWNSCALE_BLUR,
+};
+
+static int downscale_x_table;
+static int downscale_y_table;
+
+static struct mdp_table_entry mdp_upscale_table[] = {
+	{ 0x5fffc, 0x0 },
+	{ 0x50200, 0x7fc00000 },
+	{ 0x5fffc, 0xff80000d },
+	{ 0x50204, 0x7ec003f9 },
+	{ 0x5fffc, 0xfec0001c },
+	{ 0x50208, 0x7d4003f3 },
+	{ 0x5fffc, 0xfe40002b },
+	{ 0x5020c, 0x7b8003ed },
+	{ 0x5fffc, 0xfd80003c },
+	{ 0x50210, 0x794003e8 },
+	{ 0x5fffc, 0xfcc0004d },
+	{ 0x50214, 0x76c003e4 },
+	{ 0x5fffc, 0xfc40005f },
+	{ 0x50218, 0x73c003e0 },
+	{ 0x5fffc, 0xfb800071 },
+	{ 0x5021c, 0x708003de },
+	{ 0x5fffc, 0xfac00085 },
+	{ 0x50220, 0x6d0003db },
+	{ 0x5fffc, 0xfa000098 },
+	{ 0x50224, 0x698003d9 },
+	{ 0x5fffc, 0xf98000ac },
+	{ 0x50228, 0x654003d8 },
+	{ 0x5fffc, 0xf8c000c1 },
+	{ 0x5022c, 0x610003d7 },
+	{ 0x5fffc, 0xf84000d5 },
+	{ 0x50230, 0x5c8003d7 },
+	{ 0x5fffc, 0xf7c000e9 },
+	{ 0x50234, 0x580003d7 },
+	{ 0x5fffc, 0xf74000fd },
+	{ 0x50238, 0x534003d8 },
+	{ 0x5fffc, 0xf6c00112 },
+	{ 0x5023c, 0x4e8003d8 },
+	{ 0x5fffc, 0xf6800126 },
+	{ 0x50240, 0x494003da },
+	{ 0x5fffc, 0xf600013a },
+	{ 0x50244, 0x448003db },
+	{ 0x5fffc, 0xf600014d },
+	{ 0x50248, 0x3f4003dd },
+	{ 0x5fffc, 0xf5c00160 },
+	{ 0x5024c, 0x3a4003df },
+	{ 0x5fffc, 0xf5c00172 },
+	{ 0x50250, 0x354003e1 },
+	{ 0x5fffc, 0xf5c00184 },
+	{ 0x50254, 0x304003e3 },
+	{ 0x5fffc, 0xf6000195 },
+	{ 0x50258, 0x2b0003e6 },
+	{ 0x5fffc, 0xf64001a6 },
+	{ 0x5025c, 0x260003e8 },
+	{ 0x5fffc, 0xf6c001b4 },
+	{ 0x50260, 0x214003eb },
+	{ 0x5fffc, 0xf78001c2 },
+	{ 0x50264, 0x1c4003ee },
+	{ 0x5fffc, 0xf80001cf },
+	{ 0x50268, 0x17c003f1 },
+	{ 0x5fffc, 0xf90001db },
+	{ 0x5026c, 0x134003f3 },
+	{ 0x5fffc, 0xfa0001e5 },
+	{ 0x50270, 0xf0003f6 },
+	{ 0x5fffc, 0xfb4001ee },
+	{ 0x50274, 0xac003f9 },
+	{ 0x5fffc, 0xfcc001f5 },
+	{ 0x50278, 0x70003fb },
+	{ 0x5fffc, 0xfe4001fb },
+	{ 0x5027c, 0x34003fe },
+};
+
+static struct mdp_table_entry mdp_downscale_x_table_PT2TOPT4[] = {
+	{ 0x5fffc, 0x740008c },
+	{ 0x50280, 0x33800088 },
+	{ 0x5fffc, 0x800008e },
+	{ 0x50284, 0x33400084 },
+	{ 0x5fffc, 0x8400092 },
+	{ 0x50288, 0x33000080 },
+	{ 0x5fffc, 0x9000094 },
+	{ 0x5028c, 0x3300007b },
+	{ 0x5fffc, 0x9c00098 },
+	{ 0x50290, 0x32400077 },
+	{ 0x5fffc, 0xa40009b },
+	{ 0x50294, 0x32000073 },
+	{ 0x5fffc, 0xb00009d },
+	{ 0x50298,  0x31c0006f },
+	{ 0x5fffc,  0xbc000a0 },
+	{ 0x5029c,  0x3140006b },
+	{ 0x5fffc,  0xc8000a2 },
+	{ 0x502a0,  0x31000067 },
+	{ 0x5fffc,  0xd8000a5 },
+	{ 0x502a4,  0x30800062 },
+	{ 0x5fffc,  0xe4000a8 },
+	{ 0x502a8,  0x2fc0005f },
+	{ 0x5fffc,  0xec000aa },
+	{ 0x502ac,  0x2fc0005b },
+	{ 0x5fffc,  0xf8000ad },
+	{ 0x502b0,  0x2f400057 },
+	{ 0x5fffc,  0x108000b0 },
+	{ 0x502b4,  0x2e400054 },
+	{ 0x5fffc,  0x114000b2 },
+	{ 0x502b8,  0x2e000050 },
+	{ 0x5fffc,  0x124000b4 },
+	{ 0x502bc,  0x2d80004c },
+	{ 0x5fffc,  0x130000b6 },
+	{ 0x502c0,  0x2d000049 },
+	{ 0x5fffc,  0x140000b8 },
+	{ 0x502c4,  0x2c800045 },
+	{ 0x5fffc,  0x150000b9 },
+	{ 0x502c8,  0x2c000042 },
+	{ 0x5fffc,  0x15c000bd },
+	{ 0x502cc,  0x2b40003e },
+	{ 0x5fffc,  0x16c000bf },
+	{ 0x502d0,  0x2a80003b },
+	{ 0x5fffc,  0x17c000bf },
+	{ 0x502d4,  0x2a000039 },
+	{ 0x5fffc,  0x188000c2 },
+	{ 0x502d8,  0x29400036 },
+	{ 0x5fffc,  0x19c000c4 },
+	{ 0x502dc,  0x28800032 },
+	{ 0x5fffc,  0x1ac000c5 },
+	{ 0x502e0,  0x2800002f },
+	{ 0x5fffc,  0x1bc000c7 },
+	{ 0x502e4,  0x2740002c },
+	{ 0x5fffc,  0x1cc000c8 },
+	{ 0x502e8,  0x26c00029 },
+	{ 0x5fffc,  0x1dc000c9 },
+	{ 0x502ec,  0x26000027 },
+	{ 0x5fffc,  0x1ec000cc },
+	{ 0x502f0,  0x25000024 },
+	{ 0x5fffc,  0x200000cc },
+	{ 0x502f4,  0x24800021 },
+	{ 0x5fffc,  0x210000cd },
+	{ 0x502f8,  0x23800020 },
+	{ 0x5fffc,  0x220000ce },
+	{ 0x502fc,  0x2300001d },
+};
+
+static struct mdp_table_entry mdp_downscale_x_table_PT4TOPT6[] = {
+	{ 0x5fffc,  0x740008c },
+	{ 0x50280,  0x33800088 },
+	{ 0x5fffc,  0x800008e },
+	{ 0x50284,  0x33400084 },
+	{ 0x5fffc,  0x8400092 },
+	{ 0x50288,  0x33000080 },
+	{ 0x5fffc,  0x9000094 },
+	{ 0x5028c,  0x3300007b },
+	{ 0x5fffc,  0x9c00098 },
+	{ 0x50290,  0x32400077 },
+	{ 0x5fffc,  0xa40009b },
+	{ 0x50294,  0x32000073 },
+	{ 0x5fffc,  0xb00009d },
+	{ 0x50298,  0x31c0006f },
+	{ 0x5fffc,  0xbc000a0 },
+	{ 0x5029c,  0x3140006b },
+	{ 0x5fffc,  0xc8000a2 },
+	{ 0x502a0,  0x31000067 },
+	{ 0x5fffc,  0xd8000a5 },
+	{ 0x502a4,  0x30800062 },
+	{ 0x5fffc,  0xe4000a8 },
+	{ 0x502a8,  0x2fc0005f },
+	{ 0x5fffc,  0xec000aa },
+	{ 0x502ac,  0x2fc0005b },
+	{ 0x5fffc,  0xf8000ad },
+	{ 0x502b0,  0x2f400057 },
+	{ 0x5fffc,  0x108000b0 },
+	{ 0x502b4,  0x2e400054 },
+	{ 0x5fffc,  0x114000b2 },
+	{ 0x502b8,  0x2e000050 },
+	{ 0x5fffc,  0x124000b4 },
+	{ 0x502bc,  0x2d80004c },
+	{ 0x5fffc,  0x130000b6 },
+	{ 0x502c0,  0x2d000049 },
+	{ 0x5fffc,  0x140000b8 },
+	{ 0x502c4,  0x2c800045 },
+	{ 0x5fffc,  0x150000b9 },
+	{ 0x502c8,  0x2c000042 },
+	{ 0x5fffc,  0x15c000bd },
+	{ 0x502cc,  0x2b40003e },
+	{ 0x5fffc,  0x16c000bf },
+	{ 0x502d0,  0x2a80003b },
+	{ 0x5fffc,  0x17c000bf },
+	{ 0x502d4,  0x2a000039 },
+	{ 0x5fffc,  0x188000c2 },
+	{ 0x502d8,  0x29400036 },
+	{ 0x5fffc,  0x19c000c4 },
+	{ 0x502dc,  0x28800032 },
+	{ 0x5fffc,  0x1ac000c5 },
+	{ 0x502e0,  0x2800002f },
+	{ 0x5fffc,  0x1bc000c7 },
+	{ 0x502e4,  0x2740002c },
+	{ 0x5fffc,  0x1cc000c8 },
+	{ 0x502e8,  0x26c00029 },
+	{ 0x5fffc,  0x1dc000c9 },
+	{ 0x502ec,  0x26000027 },
+	{ 0x5fffc,  0x1ec000cc },
+	{ 0x502f0,  0x25000024 },
+	{ 0x5fffc,  0x200000cc },
+	{ 0x502f4,  0x24800021 },
+	{ 0x5fffc,  0x210000cd },
+	{ 0x502f8,  0x23800020 },
+	{ 0x5fffc,  0x220000ce },
+	{ 0x502fc,  0x2300001d },
+};
+
+static struct mdp_table_entry mdp_downscale_x_table_PT6TOPT8[] = {
+	{ 0x5fffc,  0xfe000070 },
+	{ 0x50280,  0x4bc00068 },
+	{ 0x5fffc,  0xfe000078 },
+	{ 0x50284,  0x4bc00060 },
+	{ 0x5fffc,  0xfe000080 },
+	{ 0x50288,  0x4b800059 },
+	{ 0x5fffc,  0xfe000089 },
+	{ 0x5028c,  0x4b000052 },
+	{ 0x5fffc,  0xfe400091 },
+	{ 0x50290,  0x4a80004b },
+	{ 0x5fffc,  0xfe40009a },
+	{ 0x50294,  0x4a000044 },
+	{ 0x5fffc,  0xfe8000a3 },
+	{ 0x50298,  0x4940003d },
+	{ 0x5fffc,  0xfec000ac },
+	{ 0x5029c,  0x48400037 },
+	{ 0x5fffc,  0xff0000b4 },
+	{ 0x502a0,  0x47800031 },
+	{ 0x5fffc,  0xff8000bd },
+	{ 0x502a4,  0x4640002b },
+	{ 0x5fffc,  0xc5 },
+	{ 0x502a8,  0x45000026 },
+	{ 0x5fffc,  0x8000ce },
+	{ 0x502ac,  0x43800021 },
+	{ 0x5fffc,  0x10000d6 },
+	{ 0x502b0,  0x4240001c },
+	{ 0x5fffc,  0x18000df },
+	{ 0x502b4,  0x40800018 },
+	{ 0x5fffc,  0x24000e6 },
+	{ 0x502b8,  0x3f000014 },
+	{ 0x5fffc,  0x30000ee },
+	{ 0x502bc,  0x3d400010 },
+	{ 0x5fffc,  0x40000f5 },
+	{ 0x502c0,  0x3b80000c },
+	{ 0x5fffc,  0x50000fc },
+	{ 0x502c4,  0x39800009 },
+	{ 0x5fffc,  0x6000102 },
+	{ 0x502c8,  0x37c00006 },
+	{ 0x5fffc,  0x7000109 },
+	{ 0x502cc,  0x35800004 },
+	{ 0x5fffc,  0x840010e },
+	{ 0x502d0,  0x33800002 },
+	{ 0x5fffc,  0x9800114 },
+	{ 0x502d4,  0x31400000 },
+	{ 0x5fffc,  0xac00119 },
+	{ 0x502d8,  0x2f4003fe },
+	{ 0x5fffc,  0xc40011e },
+	{ 0x502dc,  0x2d0003fc },
+	{ 0x5fffc,  0xdc00121 },
+	{ 0x502e0,  0x2b0003fb },
+	{ 0x5fffc,  0xf400125 },
+	{ 0x502e4,  0x28c003fa },
+	{ 0x5fffc,  0x11000128 },
+	{ 0x502e8,  0x268003f9 },
+	{ 0x5fffc,  0x12c0012a },
+	{ 0x502ec,  0x244003f9 },
+	{ 0x5fffc,  0x1480012c },
+	{ 0x502f0,  0x224003f8 },
+	{ 0x5fffc,  0x1640012e },
+	{ 0x502f4,  0x200003f8 },
+	{ 0x5fffc,  0x1800012f },
+	{ 0x502f8,  0x1e0003f8 },
+	{ 0x5fffc,  0x1a00012f },
+	{ 0x502fc,  0x1c0003f8 },
+};
+
+static struct mdp_table_entry mdp_downscale_x_table_PT8TO1[] = {
+	{ 0x5fffc,  0x0 },
+	{ 0x50280,  0x7fc00000 },
+	{ 0x5fffc,  0xff80000d },
+	{ 0x50284,  0x7ec003f9 },
+	{ 0x5fffc,  0xfec0001c },
+	{ 0x50288,  0x7d4003f3 },
+	{ 0x5fffc,  0xfe40002b },
+	{ 0x5028c,  0x7b8003ed },
+	{ 0x5fffc,  0xfd80003c },
+	{ 0x50290,  0x794003e8 },
+	{ 0x5fffc,  0xfcc0004d },
+	{ 0x50294,  0x76c003e4 },
+	{ 0x5fffc,  0xfc40005f },
+	{ 0x50298,  0x73c003e0 },
+	{ 0x5fffc,  0xfb800071 },
+	{ 0x5029c,  0x708003de },
+	{ 0x5fffc,  0xfac00085 },
+	{ 0x502a0,  0x6d0003db },
+	{ 0x5fffc,  0xfa000098 },
+	{ 0x502a4,  0x698003d9 },
+	{ 0x5fffc,  0xf98000ac },
+	{ 0x502a8,  0x654003d8 },
+	{ 0x5fffc,  0xf8c000c1 },
+	{ 0x502ac,  0x610003d7 },
+	{ 0x5fffc,  0xf84000d5 },
+	{ 0x502b0,  0x5c8003d7 },
+	{ 0x5fffc,  0xf7c000e9 },
+	{ 0x502b4,  0x580003d7 },
+	{ 0x5fffc,  0xf74000fd },
+	{ 0x502b8,  0x534003d8 },
+	{ 0x5fffc,  0xf6c00112 },
+	{ 0x502bc,  0x4e8003d8 },
+	{ 0x5fffc,  0xf6800126 },
+	{ 0x502c0,  0x494003da },
+	{ 0x5fffc,  0xf600013a },
+	{ 0x502c4,  0x448003db },
+	{ 0x5fffc,  0xf600014d },
+	{ 0x502c8,  0x3f4003dd },
+	{ 0x5fffc,  0xf5c00160 },
+	{ 0x502cc,  0x3a4003df },
+	{ 0x5fffc,  0xf5c00172 },
+	{ 0x502d0,  0x354003e1 },
+	{ 0x5fffc,  0xf5c00184 },
+	{ 0x502d4,  0x304003e3 },
+	{ 0x5fffc,  0xf6000195 },
+	{ 0x502d8,  0x2b0003e6 },
+	{ 0x5fffc,  0xf64001a6 },
+	{ 0x502dc,  0x260003e8 },
+	{ 0x5fffc,  0xf6c001b4 },
+	{ 0x502e0,  0x214003eb },
+	{ 0x5fffc,  0xf78001c2 },
+	{ 0x502e4,  0x1c4003ee },
+	{ 0x5fffc,  0xf80001cf },
+	{ 0x502e8,  0x17c003f1 },
+	{ 0x5fffc,  0xf90001db },
+	{ 0x502ec,  0x134003f3 },
+	{ 0x5fffc,  0xfa0001e5 },
+	{ 0x502f0,  0xf0003f6 },
+	{ 0x5fffc,  0xfb4001ee },
+	{ 0x502f4,  0xac003f9 },
+	{ 0x5fffc,  0xfcc001f5 },
+	{ 0x502f8,  0x70003fb },
+	{ 0x5fffc,  0xfe4001fb },
+	{ 0x502fc,  0x34003fe },
+};
+
+struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX] = {
+	[MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_x_table_PT2TOPT4,
+	[MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_x_table_PT4TOPT6,
+	[MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_x_table_PT6TOPT8,
+	[MDP_DOWNSCALE_PT8TO1]  = mdp_downscale_x_table_PT8TO1,
+};
+
+static struct mdp_table_entry mdp_downscale_y_table_PT2TOPT4[] = {
+	{ 0x5fffc,  0x740008c },
+	{ 0x50300,  0x33800088 },
+	{ 0x5fffc,  0x800008e },
+	{ 0x50304,  0x33400084 },
+	{ 0x5fffc,  0x8400092 },
+	{ 0x50308,  0x33000080 },
+	{ 0x5fffc,  0x9000094 },
+	{ 0x5030c,  0x3300007b },
+	{ 0x5fffc,  0x9c00098 },
+	{ 0x50310,  0x32400077 },
+	{ 0x5fffc,  0xa40009b },
+	{ 0x50314,  0x32000073 },
+	{ 0x5fffc,  0xb00009d },
+	{ 0x50318,  0x31c0006f },
+	{ 0x5fffc,  0xbc000a0 },
+	{ 0x5031c,  0x3140006b },
+	{ 0x5fffc,  0xc8000a2 },
+	{ 0x50320,  0x31000067 },
+	{ 0x5fffc,  0xd8000a5 },
+	{ 0x50324,  0x30800062 },
+	{ 0x5fffc,  0xe4000a8 },
+	{ 0x50328,  0x2fc0005f },
+	{ 0x5fffc,  0xec000aa },
+	{ 0x5032c,  0x2fc0005b },
+	{ 0x5fffc,  0xf8000ad },
+	{ 0x50330,  0x2f400057 },
+	{ 0x5fffc,  0x108000b0 },
+	{ 0x50334,  0x2e400054 },
+	{ 0x5fffc,  0x114000b2 },
+	{ 0x50338,  0x2e000050 },
+	{ 0x5fffc,  0x124000b4 },
+	{ 0x5033c,  0x2d80004c },
+	{ 0x5fffc,  0x130000b6 },
+	{ 0x50340,  0x2d000049 },
+	{ 0x5fffc,  0x140000b8 },
+	{ 0x50344,  0x2c800045 },
+	{ 0x5fffc,  0x150000b9 },
+	{ 0x50348,  0x2c000042 },
+	{ 0x5fffc,  0x15c000bd },
+	{ 0x5034c,  0x2b40003e },
+	{ 0x5fffc,  0x16c000bf },
+	{ 0x50350,  0x2a80003b },
+	{ 0x5fffc,  0x17c000bf },
+	{ 0x50354,  0x2a000039 },
+	{ 0x5fffc,  0x188000c2 },
+	{ 0x50358,  0x29400036 },
+	{ 0x5fffc,  0x19c000c4 },
+	{ 0x5035c,  0x28800032 },
+	{ 0x5fffc,  0x1ac000c5 },
+	{ 0x50360,  0x2800002f },
+	{ 0x5fffc,  0x1bc000c7 },
+	{ 0x50364,  0x2740002c },
+	{ 0x5fffc,  0x1cc000c8 },
+	{ 0x50368,  0x26c00029 },
+	{ 0x5fffc,  0x1dc000c9 },
+	{ 0x5036c,  0x26000027 },
+	{ 0x5fffc,  0x1ec000cc },
+	{ 0x50370,  0x25000024 },
+	{ 0x5fffc,  0x200000cc },
+	{ 0x50374,  0x24800021 },
+	{ 0x5fffc,  0x210000cd },
+	{ 0x50378,  0x23800020 },
+	{ 0x5fffc,  0x220000ce },
+	{ 0x5037c,  0x2300001d },
+};
+
+static struct mdp_table_entry mdp_downscale_y_table_PT4TOPT6[] = {
+	{ 0x5fffc,  0x740008c },
+	{ 0x50300,  0x33800088 },
+	{ 0x5fffc,  0x800008e },
+	{ 0x50304,  0x33400084 },
+	{ 0x5fffc,  0x8400092 },
+	{ 0x50308,  0x33000080 },
+	{ 0x5fffc,  0x9000094 },
+	{ 0x5030c,  0x3300007b },
+	{ 0x5fffc,  0x9c00098 },
+	{ 0x50310,  0x32400077 },
+	{ 0x5fffc,  0xa40009b },
+	{ 0x50314,  0x32000073 },
+	{ 0x5fffc,  0xb00009d },
+	{ 0x50318,  0x31c0006f },
+	{ 0x5fffc,  0xbc000a0 },
+	{ 0x5031c,  0x3140006b },
+	{ 0x5fffc,  0xc8000a2 },
+	{ 0x50320,  0x31000067 },
+	{ 0x5fffc,  0xd8000a5 },
+	{ 0x50324,  0x30800062 },
+	{ 0x5fffc,  0xe4000a8 },
+	{ 0x50328,  0x2fc0005f },
+	{ 0x5fffc,  0xec000aa },
+	{ 0x5032c,  0x2fc0005b },
+	{ 0x5fffc,  0xf8000ad },
+	{ 0x50330,  0x2f400057 },
+	{ 0x5fffc,  0x108000b0 },
+	{ 0x50334,  0x2e400054 },
+	{ 0x5fffc,  0x114000b2 },
+	{ 0x50338,  0x2e000050 },
+	{ 0x5fffc,  0x124000b4 },
+	{ 0x5033c,  0x2d80004c },
+	{ 0x5fffc,  0x130000b6 },
+	{ 0x50340,  0x2d000049 },
+	{ 0x5fffc,  0x140000b8 },
+	{ 0x50344,  0x2c800045 },
+	{ 0x5fffc,  0x150000b9 },
+	{ 0x50348,  0x2c000042 },
+	{ 0x5fffc,  0x15c000bd },
+	{ 0x5034c,  0x2b40003e },
+	{ 0x5fffc,  0x16c000bf },
+	{ 0x50350,  0x2a80003b },
+	{ 0x5fffc,  0x17c000bf },
+	{ 0x50354,  0x2a000039 },
+	{ 0x5fffc,  0x188000c2 },
+	{ 0x50358,  0x29400036 },
+	{ 0x5fffc,  0x19c000c4 },
+	{ 0x5035c,  0x28800032 },
+	{ 0x5fffc,  0x1ac000c5 },
+	{ 0x50360,  0x2800002f },
+	{ 0x5fffc,  0x1bc000c7 },
+	{ 0x50364,  0x2740002c },
+	{ 0x5fffc,  0x1cc000c8 },
+	{ 0x50368,  0x26c00029 },
+	{ 0x5fffc,  0x1dc000c9 },
+	{ 0x5036c,  0x26000027 },
+	{ 0x5fffc,  0x1ec000cc },
+	{ 0x50370,  0x25000024 },
+	{ 0x5fffc,  0x200000cc },
+	{ 0x50374,  0x24800021 },
+	{ 0x5fffc,  0x210000cd },
+	{ 0x50378,  0x23800020 },
+	{ 0x5fffc,  0x220000ce },
+	{ 0x5037c,  0x2300001d },
+};
+
+static struct mdp_table_entry mdp_downscale_y_table_PT6TOPT8[] = {
+	{ 0x5fffc,  0xfe000070 },
+	{ 0x50300,  0x4bc00068 },
+	{ 0x5fffc,  0xfe000078 },
+	{ 0x50304,  0x4bc00060 },
+	{ 0x5fffc,  0xfe000080 },
+	{ 0x50308,  0x4b800059 },
+	{ 0x5fffc,  0xfe000089 },
+	{ 0x5030c,  0x4b000052 },
+	{ 0x5fffc,  0xfe400091 },
+	{ 0x50310,  0x4a80004b },
+	{ 0x5fffc,  0xfe40009a },
+	{ 0x50314,  0x4a000044 },
+	{ 0x5fffc,  0xfe8000a3 },
+	{ 0x50318,  0x4940003d },
+	{ 0x5fffc,  0xfec000ac },
+	{ 0x5031c,  0x48400037 },
+	{ 0x5fffc,  0xff0000b4 },
+	{ 0x50320,  0x47800031 },
+	{ 0x5fffc,  0xff8000bd },
+	{ 0x50324,  0x4640002b },
+	{ 0x5fffc,  0xc5 },
+	{ 0x50328,  0x45000026 },
+	{ 0x5fffc,  0x8000ce },
+	{ 0x5032c,  0x43800021 },
+	{ 0x5fffc,  0x10000d6 },
+	{ 0x50330,  0x4240001c },
+	{ 0x5fffc,  0x18000df },
+	{ 0x50334,  0x40800018 },
+	{ 0x5fffc,  0x24000e6 },
+	{ 0x50338,  0x3f000014 },
+	{ 0x5fffc,  0x30000ee },
+	{ 0x5033c,  0x3d400010 },
+	{ 0x5fffc,  0x40000f5 },
+	{ 0x50340,  0x3b80000c },
+	{ 0x5fffc,  0x50000fc },
+	{ 0x50344,  0x39800009 },
+	{ 0x5fffc,  0x6000102 },
+	{ 0x50348,  0x37c00006 },
+	{ 0x5fffc,  0x7000109 },
+	{ 0x5034c,  0x35800004 },
+	{ 0x5fffc,  0x840010e },
+	{ 0x50350,  0x33800002 },
+	{ 0x5fffc,  0x9800114 },
+	{ 0x50354,  0x31400000 },
+	{ 0x5fffc,  0xac00119 },
+	{ 0x50358,  0x2f4003fe },
+	{ 0x5fffc,  0xc40011e },
+	{ 0x5035c,  0x2d0003fc },
+	{ 0x5fffc,  0xdc00121 },
+	{ 0x50360,  0x2b0003fb },
+	{ 0x5fffc,  0xf400125 },
+	{ 0x50364,  0x28c003fa },
+	{ 0x5fffc,  0x11000128 },
+	{ 0x50368,  0x268003f9 },
+	{ 0x5fffc,  0x12c0012a },
+	{ 0x5036c,  0x244003f9 },
+	{ 0x5fffc,  0x1480012c },
+	{ 0x50370,  0x224003f8 },
+	{ 0x5fffc,  0x1640012e },
+	{ 0x50374,  0x200003f8 },
+	{ 0x5fffc,  0x1800012f },
+	{ 0x50378,  0x1e0003f8 },
+	{ 0x5fffc,  0x1a00012f },
+	{ 0x5037c,  0x1c0003f8 },
+};
+
+static struct mdp_table_entry mdp_downscale_y_table_PT8TO1[] = {
+	{ 0x5fffc,  0x0 },
+	{ 0x50300,  0x7fc00000 },
+	{ 0x5fffc,  0xff80000d },
+	{ 0x50304,  0x7ec003f9 },
+	{ 0x5fffc,  0xfec0001c },
+	{ 0x50308,  0x7d4003f3 },
+	{ 0x5fffc,  0xfe40002b },
+	{ 0x5030c,  0x7b8003ed },
+	{ 0x5fffc,  0xfd80003c },
+	{ 0x50310,  0x794003e8 },
+	{ 0x5fffc,  0xfcc0004d },
+	{ 0x50314,  0x76c003e4 },
+	{ 0x5fffc,  0xfc40005f },
+	{ 0x50318,  0x73c003e0 },
+	{ 0x5fffc,  0xfb800071 },
+	{ 0x5031c,  0x708003de },
+	{ 0x5fffc,  0xfac00085 },
+	{ 0x50320,  0x6d0003db },
+	{ 0x5fffc,  0xfa000098 },
+	{ 0x50324,  0x698003d9 },
+	{ 0x5fffc,  0xf98000ac },
+	{ 0x50328,  0x654003d8 },
+	{ 0x5fffc,  0xf8c000c1 },
+	{ 0x5032c,  0x610003d7 },
+	{ 0x5fffc,  0xf84000d5 },
+	{ 0x50330,  0x5c8003d7 },
+	{ 0x5fffc,  0xf7c000e9 },
+	{ 0x50334,  0x580003d7 },
+	{ 0x5fffc,  0xf74000fd },
+	{ 0x50338,  0x534003d8 },
+	{ 0x5fffc,  0xf6c00112 },
+	{ 0x5033c,  0x4e8003d8 },
+	{ 0x5fffc,  0xf6800126 },
+	{ 0x50340,  0x494003da },
+	{ 0x5fffc,  0xf600013a },
+	{ 0x50344,  0x448003db },
+	{ 0x5fffc,  0xf600014d },
+	{ 0x50348,  0x3f4003dd },
+	{ 0x5fffc,  0xf5c00160 },
+	{ 0x5034c,  0x3a4003df },
+	{ 0x5fffc,  0xf5c00172 },
+	{ 0x50350,  0x354003e1 },
+	{ 0x5fffc,  0xf5c00184 },
+	{ 0x50354,  0x304003e3 },
+	{ 0x5fffc,  0xf6000195 },
+	{ 0x50358,  0x2b0003e6 },
+	{ 0x5fffc,  0xf64001a6 },
+	{ 0x5035c,  0x260003e8 },
+	{ 0x5fffc,  0xf6c001b4 },
+	{ 0x50360,  0x214003eb },
+	{ 0x5fffc,  0xf78001c2 },
+	{ 0x50364,  0x1c4003ee },
+	{ 0x5fffc,  0xf80001cf },
+	{ 0x50368,  0x17c003f1 },
+	{ 0x5fffc,  0xf90001db },
+	{ 0x5036c,  0x134003f3 },
+	{ 0x5fffc,  0xfa0001e5 },
+	{ 0x50370,  0xf0003f6 },
+	{ 0x5fffc,  0xfb4001ee },
+	{ 0x50374,  0xac003f9 },
+	{ 0x5fffc,  0xfcc001f5 },
+	{ 0x50378,  0x70003fb },
+	{ 0x5fffc,  0xfe4001fb },
+	{ 0x5037c,  0x34003fe },
+};
+
+struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX] = {
+	[MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_y_table_PT2TOPT4,
+	[MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_y_table_PT4TOPT6,
+	[MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_y_table_PT6TOPT8,
+	[MDP_DOWNSCALE_PT8TO1]  = mdp_downscale_y_table_PT8TO1,
+};
+
+struct mdp_table_entry mdp_gaussian_blur_table[] = {
+	/* max variance */
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50280, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50284, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50288, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5028c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50290, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50294, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50298, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5029c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502ac, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502bc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502cc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502dc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502ec, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502fc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50300, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50304, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50308, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5030c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50310, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50314, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50318, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5031c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50320, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50324, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50328, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5032c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50330, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50334, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50338, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5033c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50340, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50344, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50348, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5034c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50350, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50354, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50358, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5035c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50360, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50364, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50368, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5036c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50370, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50374, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50378, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5037c, 0x20000080 },
+};
+
+static void load_table(const struct mdp_info *mdp,
+		       struct mdp_table_entry *table, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		mdp_writel(mdp, table[i].val, table[i].reg);
+}
+
+enum {
+	IMG_LEFT,
+	IMG_RIGHT,
+	IMG_TOP,
+	IMG_BOTTOM,
+};
+
+static void get_edge_info(uint32_t src, uint32_t src_coord, uint32_t dst,
+			  uint32_t *interp1, uint32_t *interp2,
+			  uint32_t *repeat1, uint32_t *repeat2) {
+	if (src > 3 * dst) {
+		*interp1 = 0;
+		*interp2 = src - 1;
+		*repeat1 = 0;
+		*repeat2 = 0;
+	} else if (src == 3 * dst) {
+		*interp1 = 0;
+		*interp2 = src;
+		*repeat1 = 0;
+		*repeat2 = 1;
+	} else if (src > dst && src < 3 * dst) {
+		*interp1 = -1;
+		*interp2 = src;
+		*repeat1 = 1;
+		*repeat2 = 1;
+	} else if (src == dst) {
+		*interp1 = -1;
+		*interp2 = src + 1;
+		*repeat1 = 1;
+		*repeat2 = 2;
+	} else {
+		*interp1 = -2;
+		*interp2 = src + 1;
+		*repeat1 = 2;
+		*repeat2 = 2;
+	}
+	*interp1 += src_coord;
+	*interp2 += src_coord;
+}
+
+int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs)
+{
+	int32_t luma_interp[4];
+	int32_t luma_repeat[4];
+	int32_t chroma_interp[4];
+	int32_t chroma_bound[4];
+	int32_t chroma_repeat[4];
+	uint32_t dst_w, dst_h;
+
+	memset(&luma_interp, 0, sizeof(int32_t) * 4);
+	memset(&luma_repeat, 0, sizeof(int32_t) * 4);
+	memset(&chroma_interp, 0, sizeof(int32_t) * 4);
+	memset(&chroma_bound, 0, sizeof(int32_t) * 4);
+	memset(&chroma_repeat, 0, sizeof(int32_t) * 4);
+	regs->edge = 0;
+
+	if (req->flags & MDP_ROT_90) {
+		dst_w = req->dst_rect.h;
+		dst_h = req->dst_rect.w;
+	} else {
+		dst_w = req->dst_rect.w;
+		dst_h = req->dst_rect.h;
+	}
+
+	if (regs->op & (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON)) {
+		get_edge_info(req->src_rect.h, req->src_rect.y, dst_h,
+			      &luma_interp[IMG_TOP], &luma_interp[IMG_BOTTOM],
+			      &luma_repeat[IMG_TOP], &luma_repeat[IMG_BOTTOM]);
+		get_edge_info(req->src_rect.w, req->src_rect.x, dst_w,
+			      &luma_interp[IMG_LEFT], &luma_interp[IMG_RIGHT],
+			      &luma_repeat[IMG_LEFT], &luma_repeat[IMG_RIGHT]);
+	} else {
+		luma_interp[IMG_LEFT] = req->src_rect.x;
+		luma_interp[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
+		luma_interp[IMG_TOP] = req->src_rect.y;
+		luma_interp[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
+		luma_repeat[IMG_LEFT] = 0;
+		luma_repeat[IMG_TOP] = 0;
+		luma_repeat[IMG_RIGHT] = 0;
+		luma_repeat[IMG_BOTTOM] = 0;
+	}
+
+	chroma_interp[IMG_LEFT] = luma_interp[IMG_LEFT];
+	chroma_interp[IMG_RIGHT] = luma_interp[IMG_RIGHT];
+	chroma_interp[IMG_TOP] = luma_interp[IMG_TOP];
+	chroma_interp[IMG_BOTTOM] = luma_interp[IMG_BOTTOM];
+
+	chroma_bound[IMG_LEFT] = req->src_rect.x;
+	chroma_bound[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
+	chroma_bound[IMG_TOP] = req->src_rect.y;
+	chroma_bound[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
+
+	if (IS_YCRCB(req->src.format)) {
+		chroma_interp[IMG_LEFT] = chroma_interp[IMG_LEFT] >> 1;
+		chroma_interp[IMG_RIGHT] = (chroma_interp[IMG_RIGHT] + 1) >> 1;
+
+		chroma_bound[IMG_LEFT] = chroma_bound[IMG_LEFT] >> 1;
+		chroma_bound[IMG_RIGHT] = chroma_bound[IMG_RIGHT] >> 1;
+	}
+
+	if (req->src.format == MDP_Y_CBCR_H2V2 ||
+	    req->src.format == MDP_Y_CRCB_H2V2) {
+		chroma_interp[IMG_TOP] = (chroma_interp[IMG_TOP] - 1) >> 1;
+		chroma_interp[IMG_BOTTOM] = (chroma_interp[IMG_BOTTOM] + 1)
+					    >> 1;
+		chroma_bound[IMG_TOP] = (chroma_bound[IMG_TOP] + 1) >> 1;
+		chroma_bound[IMG_BOTTOM] = chroma_bound[IMG_BOTTOM] >> 1;
+	}
+
+	chroma_repeat[IMG_LEFT] = chroma_bound[IMG_LEFT] -
+				  chroma_interp[IMG_LEFT];
+	chroma_repeat[IMG_RIGHT] = chroma_interp[IMG_RIGHT] -
+				  chroma_bound[IMG_RIGHT];
+	chroma_repeat[IMG_TOP] = chroma_bound[IMG_TOP] -
+				  chroma_interp[IMG_TOP];
+	chroma_repeat[IMG_BOTTOM] = chroma_interp[IMG_BOTTOM] -
+				  chroma_bound[IMG_BOTTOM];
+
+	if (chroma_repeat[IMG_LEFT] < 0 || chroma_repeat[IMG_LEFT] > 3 ||
+	    chroma_repeat[IMG_RIGHT] < 0 || chroma_repeat[IMG_RIGHT] > 3 ||
+	    chroma_repeat[IMG_TOP] < 0 || chroma_repeat[IMG_TOP] > 3 ||
+	    chroma_repeat[IMG_BOTTOM] < 0 || chroma_repeat[IMG_BOTTOM] > 3 ||
+	    luma_repeat[IMG_LEFT] < 0 || luma_repeat[IMG_LEFT] > 3 ||
+	    luma_repeat[IMG_RIGHT] < 0 || luma_repeat[IMG_RIGHT] > 3 ||
+	    luma_repeat[IMG_TOP] < 0 || luma_repeat[IMG_TOP] > 3 ||
+	    luma_repeat[IMG_BOTTOM] < 0 || luma_repeat[IMG_BOTTOM] > 3)
+		return -1;
+
+	regs->edge |= (chroma_repeat[IMG_LEFT] & 3) << MDP_LEFT_CHROMA;
+	regs->edge |= (chroma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_CHROMA;
+	regs->edge |= (chroma_repeat[IMG_TOP] & 3) << MDP_TOP_CHROMA;
+	regs->edge |= (chroma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_CHROMA;
+	regs->edge |= (luma_repeat[IMG_LEFT] & 3) << MDP_LEFT_LUMA;
+	regs->edge |= (luma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_LUMA;
+	regs->edge |= (luma_repeat[IMG_TOP] & 3) << MDP_TOP_LUMA;
+	regs->edge |= (luma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_LUMA;
+	return 0;
+}
+
+#define ONE_HALF	(1LL << 32)
+#define ONE		(1LL << 33)
+#define TWO		(2LL << 33)
+#define THREE		(3LL << 33)
+#define FRAC_MASK (ONE - 1)
+#define INT_MASK (~FRAC_MASK)
+
+static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t origin,
+			uint32_t *phase_init, uint32_t *phase_step)
+{
+	/* to improve precicsion calculations are done in U31.33 and converted
+	 * to U3.29 at the end */
+	int64_t k1, k2, k3, k4, tmp;
+	uint64_t n, d, os, os_p, od, od_p, oreq;
+	unsigned rpa = 0;
+	int64_t ip64, delta;
+
+	if (dim_out % 3 == 0)
+		rpa = !(dim_in % (dim_out / 3));
+
+	n = ((uint64_t)dim_out) << 34;
+	d = dim_in;
+	if (!d)
+		return -1;
+	do_div(n, d);
+	k3 = (n + 1) >> 1;
+	if ((k3 >> 4) < (1LL << 27) || (k3 >> 4) > (1LL << 31))
+		return -1;
+
+	n = ((uint64_t)dim_in) << 34;
+	d = (uint64_t)dim_out;
+	if (!d)
+		return -1;
+	do_div(n, d);
+	k1 = (n + 1) >> 1;
+	k2 = (k1 - ONE) >> 1;
+
+	*phase_init = (int)(k2 >> 4);
+	k4 = (k3 - ONE) >> 1;
+
+	if (rpa) {
+		os = ((uint64_t)origin << 33) - ONE_HALF;
+		tmp = (dim_out * os) + ONE_HALF;
+		if (!dim_in)
+			return -1;
+		do_div(tmp, dim_in);
+		od = tmp - ONE_HALF;
+	} else {
+		os = ((uint64_t)origin << 1) - 1;
+		od = (((k3 * os) >> 1) + k4);
+	}
+
+	od_p = od & INT_MASK;
+	if (od_p != od)
+		od_p += ONE;
+
+	if (rpa) {
+		tmp = (dim_in * od_p) + ONE_HALF;
+		if (!dim_in)
+			return -1;
+		do_div(tmp, dim_in);
+		os_p = tmp - ONE_HALF;
+	} else {
+		os_p = ((k1 * (od_p >> 33)) + k2);
+	}
+
+	oreq = (os_p & INT_MASK) - ONE;
+
+	ip64 = os_p - oreq;
+	delta = ((int64_t)(origin) << 33) - oreq;
+	ip64 -= delta;
+	/* limit to valid range before the left shift */
+	delta = (ip64 & (1LL << 63)) ? 4 : -4;
+	delta <<= 33;
+	while (abs((int)(ip64 >> 33)) > 4)
+		ip64 += delta;
+	*phase_init = (int)(ip64 >> 4);
+	*phase_step = (uint32_t)(k1 >> 4);
+	return 0;
+}
+
+int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
+		      struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
+		      uint32_t src_format, uint32_t dst_format)
+{
+	int downscale;
+	uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y;
+	uint32_t scale_factor_x, scale_factor_y;
+
+	if (scale_params(src_rect->w, dst_rect->w, 1, &phase_init_x,
+			 &phase_step_x) ||
+	    scale_params(src_rect->h, dst_rect->h, 1, &phase_init_y,
+			 &phase_step_y))
+		return -1;
+
+	regs->phasex_init = phase_init_x;
+	regs->phasey_init = phase_init_y;
+	regs->phasex_step = phase_step_x;
+	regs->phasey_step = phase_step_y;
+
+	scale_factor_x = (dst_rect->w * 10) / src_rect->w;
+	scale_factor_y = (dst_rect->h * 10) / src_rect->h;
+
+	if (scale_factor_x > 8)
+		downscale = MDP_DOWNSCALE_PT8TO1;
+	else if (scale_factor_x > 6)
+		downscale = MDP_DOWNSCALE_PT6TOPT8;
+	else if (scale_factor_x > 4)
+		downscale = MDP_DOWNSCALE_PT4TOPT6;
+	else
+		downscale = MDP_DOWNSCALE_PT2TOPT4;
+
+	if (downscale != downscale_x_table) {
+		load_table(mdp, mdp_downscale_x_table[downscale], 64);
+		downscale_x_table = downscale;
+	}
+
+	if (scale_factor_y > 8)
+		downscale = MDP_DOWNSCALE_PT8TO1;
+	else if (scale_factor_y > 6)
+		downscale = MDP_DOWNSCALE_PT6TOPT8;
+	else if (scale_factor_y > 4)
+		downscale = MDP_DOWNSCALE_PT4TOPT6;
+	else
+		downscale = MDP_DOWNSCALE_PT2TOPT4;
+
+	if (downscale != downscale_y_table) {
+		load_table(mdp, mdp_downscale_y_table[downscale], 64);
+		downscale_y_table = downscale;
+	}
+
+	return 0;
+}
+
+
+int mdp_ppp_load_blur(const struct mdp_info *mdp)
+{
+	if (!(downscale_x_table == MDP_DOWNSCALE_BLUR &&
+              downscale_y_table == MDP_DOWNSCALE_BLUR)) {
+		load_table(mdp, mdp_gaussian_blur_table, 128);
+		downscale_x_table = MDP_DOWNSCALE_BLUR;
+		downscale_y_table = MDP_DOWNSCALE_BLUR;
+	}
+
+	return 0;
+}
+
+void mdp_ppp_init_scale(const struct mdp_info *mdp)
+{
+	downscale_x_table = MDP_DOWNSCALE_MAX;
+	downscale_y_table = MDP_DOWNSCALE_MAX;
+
+	load_table(mdp, mdp_upscale_table, ARRAY_SIZE(mdp_upscale_table));
+}
diff --git a/drivers/video/msm/mdp_ppp31.c b/drivers/video/msm/mdp_ppp31.c
new file mode 100644
index 0000000..91764fe
--- /dev/null
+++ b/drivers/video/msm/mdp_ppp31.c
@@ -0,0 +1,332 @@
+/* drivers/video/msm/mdp_ppp31.c
+ *
+ * Copyright (C) 2009 Code Aurora Forum. All rights reserved.
+ * Copyright (C) 2009 Google Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/msm_mdp.h>
+
+#include "mdp_hw.h"
+#include "mdp_ppp.h"
+
+#define NUM_COEFFS			32
+
+struct mdp_scale_coeffs {
+	uint16_t	c[4][NUM_COEFFS];
+};
+
+struct mdp_scale_tbl_info {
+	uint16_t			offset;
+	uint32_t			set:2;
+	int				use_pr;
+	struct mdp_scale_coeffs		coeffs;
+};
+
+enum {
+	MDP_SCALE_PT2TOPT4,
+	MDP_SCALE_PT4TOPT6,
+	MDP_SCALE_PT6TOPT8,
+	MDP_SCALE_PT8TO8,
+	MDP_SCALE_MAX,
+};
+
+static struct mdp_scale_coeffs mdp_scale_pr_coeffs = {
+	.c = {
+		[0] = {
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+		},
+		[1] = {
+			511, 511, 511, 511, 511, 511, 511, 511,
+			511, 511, 511, 511, 511, 511, 511, 511,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+		},
+		[2] = {
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			511, 511, 511, 511, 511, 511, 511, 511,
+			511, 511, 511, 511, 511, 511, 511, 511,
+		},
+		[3] = {
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+		},
+	},
+};
+
+static struct mdp_scale_tbl_info mdp_scale_tbl[MDP_SCALE_MAX] = {
+	[ MDP_SCALE_PT2TOPT4 ]	= {
+		.offset		= 0,
+		.set		= MDP_PPP_SCALE_COEFF_D0_SET,
+		.use_pr		= -1,
+		.coeffs.c	= {
+			[0] = {
+				131, 131, 130, 129, 128, 127, 127, 126,
+				125, 125, 124, 123, 123, 121, 120, 119,
+				119, 118, 117, 117, 116, 115, 115, 114,
+				113, 112, 111, 110, 109, 109, 108, 107,
+			},
+			[1] = {
+				141, 140, 140, 140, 140, 139, 138, 138,
+				138, 137, 137, 137, 136, 137, 137, 137,
+				136, 136, 136, 135, 135, 135, 134, 134,
+				134, 134, 134, 133, 133, 132, 132, 132,
+			},
+			[2] = {
+				132, 132, 132, 133, 133, 134, 134, 134,
+				134, 134, 135, 135, 135, 136, 136, 136,
+				137, 137, 137, 136, 137, 137, 137, 138,
+				138, 138, 139, 140, 140, 140, 140, 141,
+			},
+			[3] = {
+				107, 108, 109, 109, 110, 111, 112, 113,
+				114, 115, 115, 116, 117, 117, 118, 119,
+				119, 120, 121, 123, 123, 124, 125, 125,
+				126, 127, 127, 128, 129, 130, 131, 131,
+			}
+		},
+	},
+	[ MDP_SCALE_PT4TOPT6 ] = {
+		.offset		= 32,
+		.set		= MDP_PPP_SCALE_COEFF_D1_SET,
+		.use_pr		= -1,
+		.coeffs.c	= {
+			[0] = {
+				136, 132, 128, 123, 119, 115, 111, 107,
+				103, 98, 95, 91, 87, 84, 80, 76,
+				73, 69, 66, 62, 59, 57, 54, 50,
+				47, 44, 41, 39, 36, 33, 32, 29,
+			},
+			[1] = {
+				206, 205, 204, 204, 201, 200, 199, 197,
+				196, 194, 191, 191, 189, 185, 184, 182,
+				180, 178, 176, 173, 170, 168, 165, 162,
+				160, 157, 155, 152, 148, 146, 142, 140,
+			},
+			[2] = {
+				140, 142, 146, 148, 152, 155, 157, 160,
+				162, 165, 168, 170, 173, 176, 178, 180,
+				182, 184, 185, 189, 191, 191, 194, 196,
+				197, 199, 200, 201, 204, 204, 205, 206,
+			},
+			[3] = {
+				29, 32, 33, 36, 39, 41, 44, 47,
+				50, 54, 57, 59, 62, 66, 69, 73,
+				76, 80, 84, 87, 91, 95, 98, 103,
+				107, 111, 115, 119, 123, 128, 132, 136,
+			},
+		},
+	},
+	[ MDP_SCALE_PT6TOPT8 ] = {
+		.offset		= 64,
+		.set		= MDP_PPP_SCALE_COEFF_D2_SET,
+		.use_pr		= -1,
+		.coeffs.c	= {
+			[0] = {
+				104, 96, 89, 82, 75, 68, 61, 55,
+				49, 43, 38, 33, 28, 24, 20, 16,
+				12, 9, 6, 4, 2, 0, -2, -4,
+				-5, -6, -7, -7, -8, -8, -8, -8,
+			},
+			[1] = {
+				303, 303, 302, 300, 298, 296, 293, 289,
+				286, 281, 276, 270, 265, 258, 252, 245,
+				238, 230, 223, 214, 206, 197, 189, 180,
+				172, 163, 154, 145, 137, 128, 120, 112,
+			},
+			[2] = {
+				112, 120, 128, 137, 145, 154, 163, 172,
+				180, 189, 197, 206, 214, 223, 230, 238,
+				245, 252, 258, 265, 270, 276, 281, 286,
+				289, 293, 296, 298, 300, 302, 303, 303,
+			},
+			[3] = {
+				-8, -8, -8, -8, -7, -7, -6, -5,
+				-4, -2, 0, 2, 4, 6, 9, 12,
+				16, 20, 24, 28, 33, 38, 43, 49,
+				55, 61, 68, 75, 82, 89, 96, 104,
+			},
+		},
+	},
+	[ MDP_SCALE_PT8TO8 ] = {
+		.offset		= 96,
+		.set		= MDP_PPP_SCALE_COEFF_U1_SET,
+		.use_pr		= -1,
+		.coeffs.c	= {
+			[0] = {
+				0, -7, -13, -19, -24, -28, -32, -34,
+				-37, -39, -40, -41, -41, -41, -40, -40,
+				-38, -37, -35, -33, -31, -29, -26, -24,
+				-21, -18, -15, -13, -10, -7, -5, -2,
+			},
+			[1] = {
+				511, 507, 501, 494, 485, 475, 463, 450,
+				436, 422, 405, 388, 370, 352, 333, 314,
+				293, 274, 253, 233, 213, 193, 172, 152,
+				133, 113, 95, 77, 60, 43, 28, 13,
+			},
+			[2] = {
+				0, 13, 28, 43, 60, 77, 95, 113,
+				133, 152, 172, 193, 213, 233, 253, 274,
+				294, 314, 333, 352, 370, 388, 405, 422,
+				436, 450, 463, 475, 485, 494, 501, 507,
+			},
+			[3] = {
+				0, -2, -5, -7, -10, -13, -15, -18,
+				-21, -24, -26, -29, -31, -33, -35, -37,
+				-38, -40, -40, -41, -41, -41, -40, -39,
+				-37, -34, -32, -28, -24, -19, -13, -7,
+			},
+		},
+	},
+};
+
+static void load_table(const struct mdp_info *mdp, int scale, int use_pr)
+{
+	int i;
+	uint32_t val;
+	struct mdp_scale_coeffs *coeffs;
+	struct mdp_scale_tbl_info *tbl = &mdp_scale_tbl[scale];
+
+	if (use_pr == tbl->use_pr)
+		return;
+
+	tbl->use_pr = use_pr;
+	if (!use_pr)
+		coeffs = &tbl->coeffs;
+	else
+		coeffs = &mdp_scale_pr_coeffs;
+
+	for (i = 0; i < NUM_COEFFS; ++i) {
+		val = ((coeffs->c[1][i] & 0x3ff) << 16) |
+			(coeffs->c[0][i] & 0x3ff);
+		mdp_writel(mdp, val, MDP_PPP_SCALE_COEFF_LSBn(tbl->offset + i));
+
+		val = ((coeffs->c[3][i] & 0x3ff) << 16) |
+			(coeffs->c[2][i] & 0x3ff);
+		mdp_writel(mdp, val, MDP_PPP_SCALE_COEFF_MSBn(tbl->offset + i));
+	}
+}
+
+#define SCALER_PHASE_BITS		29
+static void scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t scaler,
+			 uint32_t *phase_init, uint32_t *phase_step)
+{
+	uint64_t src = dim_in;
+	uint64_t dst = dim_out;
+	uint64_t numer;
+	uint64_t denom;
+
+	*phase_init = 0;
+
+	if (dst == 1) {
+		/* if destination is 1 pixel wide, the value of phase_step
+		 * is unimportant. */
+		*phase_step = (uint32_t) (src << SCALER_PHASE_BITS);
+		if (scaler == MDP_PPP_SCALER_FIR)
+			*phase_init =
+				(uint32_t) ((src - 1) << SCALER_PHASE_BITS);
+		return;
+	}
+
+	if (scaler == MDP_PPP_SCALER_FIR) {
+		numer = (src - 1) << SCALER_PHASE_BITS;
+		denom = dst - 1;
+		/* we want to round up the result*/
+		numer += denom - 1;
+	} else {
+		numer = src << SCALER_PHASE_BITS;
+		denom = dst;
+	}
+
+	do_div(numer, denom);
+	*phase_step = (uint32_t) numer;
+}
+
+static int scale_idx(int factor)
+{
+	int idx;
+
+	if (factor > 80)
+		idx = MDP_SCALE_PT8TO8;
+	else if (factor > 60)
+		idx = MDP_SCALE_PT6TOPT8;
+	else if (factor > 40)
+		idx = MDP_SCALE_PT4TOPT6;
+	else
+		idx = MDP_SCALE_PT2TOPT4;
+
+	return idx;
+}
+
+int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
+		      struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
+		      uint32_t src_format, uint32_t dst_format)
+{
+	uint32_t x_fac;
+	uint32_t y_fac;
+	uint32_t scaler_x = MDP_PPP_SCALER_FIR;
+	uint32_t scaler_y = MDP_PPP_SCALER_FIR;
+	// Don't use pixel repeat mode, it looks bad
+	int use_pr = 0;
+	int x_idx;
+	int y_idx;
+
+	if (unlikely(src_rect->w > 2048 || src_rect->h > 2048))
+		return -ENOTSUPP;
+
+	x_fac = (dst_rect->w * 100) / src_rect->w;
+	y_fac = (dst_rect->h * 100) / src_rect->h;
+
+	/* if down-scaling by a factor smaller than 1/4, use M/N */
+	scaler_x = x_fac <= 25 ? MDP_PPP_SCALER_MN : MDP_PPP_SCALER_FIR;
+	scaler_y = y_fac <= 25 ? MDP_PPP_SCALER_MN : MDP_PPP_SCALER_FIR;
+	scale_params(src_rect->w, dst_rect->w, scaler_x, &regs->phasex_init,
+		     &regs->phasex_step);
+	scale_params(src_rect->h, dst_rect->h, scaler_y, &regs->phasey_init,
+		     &regs->phasey_step);
+
+	x_idx = scale_idx(x_fac);
+	y_idx = scale_idx(y_fac);
+	load_table(mdp, x_idx, use_pr);
+	load_table(mdp, y_idx, use_pr);
+
+	regs->scale_cfg = 0;
+	// Enable SVI when source or destination is YUV
+	if (!IS_RGB(src_format) && !IS_RGB(dst_format))
+		regs->scale_cfg |= (1 << 6);
+	regs->scale_cfg |= (mdp_scale_tbl[x_idx].set << 2) |
+		(mdp_scale_tbl[x_idx].set << 4);
+	regs->scale_cfg |= (scaler_x << 0) | (scaler_y << 1);
+
+	return 0;
+}
+
+int mdp_ppp_load_blur(const struct mdp_info *mdp)
+{
+	return -ENOTSUPP;
+}
+
+void mdp_ppp_init_scale(const struct mdp_info *mdp)
+{
+	int scale;
+	for (scale = 0; scale < MDP_SCALE_MAX; ++scale)
+		load_table(mdp, scale, 0);
+}
diff --git a/drivers/video/msm/mdp_ppp_v20.c b/drivers/video/msm/mdp_ppp_v20.c
new file mode 100644
index 0000000..fe237ee
--- /dev/null
+++ b/drivers/video/msm/mdp_ppp_v20.c
@@ -0,0 +1,2531 @@
+/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include "linux/proc_fs.h"
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <asm/div64.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+
+static MDP_SCALE_MODE mdp_curr_up_scale_xy;
+static MDP_SCALE_MODE mdp_curr_down_scale_x;
+static MDP_SCALE_MODE mdp_curr_down_scale_y;
+
+static long long mdp_do_div(long long num, long long den)
+{
+	do_div(num, den);
+	return num;
+}
+
+struct mdp_table_entry mdp_gaussian_blur_table[] = {
+	/* max variance */
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50280, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50284, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50288, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5028c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50290, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50294, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50298, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5029c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502ac, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502bc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502cc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502dc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502ec, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502fc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50300, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50304, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50308, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5030c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50310, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50314, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50318, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5031c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50320, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50324, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50328, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5032c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50330, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50334, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50338, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5033c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50340, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50344, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50348, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5034c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50350, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50354, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50358, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5035c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50360, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50364, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50368, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5036c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50370, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50374, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50378, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5037c, 0x20000080 },
+};
+
+static void load_scale_table(
+	struct mdp_table_entry *table, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		MDP_OUTP(MDP_BASE + table[i].reg, table[i].val);
+}
+
+static void mdp_load_pr_upscale_table(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50200, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50204, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50208, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5020c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50210, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50214, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50218, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5021c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50220, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50224, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50228, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5022c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50230, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50234, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50238, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5023c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50240, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50244, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50248, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5024c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50250, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50254, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50258, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5025c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50260, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50264, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50268, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5026c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50270, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50274, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50278, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5027c, 0x0);
+}
+
+static void mdp_load_pr_downscale_table_x_point2TOpoint4(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502cc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502dc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502ec, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502fc, 0x0);
+}
+
+static void mdp_load_pr_downscale_table_y_point2TOpoint4(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50340, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50344, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50348, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5034c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50350, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50354, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50358, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5035c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50360, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50364, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50368, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5036c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50370, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50374, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50378, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5037c, 0x0);
+}
+
+static void mdp_load_pr_downscale_table_x_point4TOpoint6(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502cc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502dc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502ec, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502fc, 0x0);
+}
+
+static void mdp_load_pr_downscale_table_y_point4TOpoint6(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50340, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50344, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50348, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5034c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50350, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50354, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50358, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5035c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50360, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50364, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50368, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5036c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50370, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50374, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50378, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5037c, 0x0);
+}
+
+static void mdp_load_pr_downscale_table_x_point6TOpoint8(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502cc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502dc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502ec, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502fc, 0x0);
+}
+
+static void mdp_load_pr_downscale_table_y_point6TOpoint8(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50340, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50344, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50348, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5034c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50350, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50354, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50358, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5035c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50360, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50364, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50368, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5036c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50370, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50374, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50378, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5037c, 0x0);
+}
+
+static void mdp_load_pr_downscale_table_x_point8TO1(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502c8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502cc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502d8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502dc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502e8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502ec, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f0, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f4, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502f8, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x502fc, 0x0);
+}
+
+static void mdp_load_pr_downscale_table_y_point8TO1(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50340, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50344, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50348, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5034c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50350, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50354, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50358, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5035c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50360, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50364, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50368, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5036c, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50370, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50374, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x50378, 0x0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff);
+	MDP_OUTP(MDP_BASE + 0x5037c, 0x0);
+}
+
+static void mdp_load_bc_upscale_table(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50200, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d);
+	MDP_OUTP(MDP_BASE + 0x50204, 0x7ec003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c);
+	MDP_OUTP(MDP_BASE + 0x50208, 0x7d4003f3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b);
+	MDP_OUTP(MDP_BASE + 0x5020c, 0x7b8003ed);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c);
+	MDP_OUTP(MDP_BASE + 0x50210, 0x794003e8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d);
+	MDP_OUTP(MDP_BASE + 0x50214, 0x76c003e4);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f);
+	MDP_OUTP(MDP_BASE + 0x50218, 0x73c003e0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071);
+	MDP_OUTP(MDP_BASE + 0x5021c, 0x708003de);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085);
+	MDP_OUTP(MDP_BASE + 0x50220, 0x6d0003db);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098);
+	MDP_OUTP(MDP_BASE + 0x50224, 0x698003d9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac);
+	MDP_OUTP(MDP_BASE + 0x50228, 0x654003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1);
+	MDP_OUTP(MDP_BASE + 0x5022c, 0x610003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5);
+	MDP_OUTP(MDP_BASE + 0x50230, 0x5c8003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9);
+	MDP_OUTP(MDP_BASE + 0x50234, 0x580003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd);
+	MDP_OUTP(MDP_BASE + 0x50238, 0x534003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112);
+	MDP_OUTP(MDP_BASE + 0x5023c, 0x4e8003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126);
+	MDP_OUTP(MDP_BASE + 0x50240, 0x494003da);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a);
+	MDP_OUTP(MDP_BASE + 0x50244, 0x448003db);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d);
+	MDP_OUTP(MDP_BASE + 0x50248, 0x3f4003dd);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160);
+	MDP_OUTP(MDP_BASE + 0x5024c, 0x3a4003df);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172);
+	MDP_OUTP(MDP_BASE + 0x50250, 0x354003e1);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184);
+	MDP_OUTP(MDP_BASE + 0x50254, 0x304003e3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195);
+	MDP_OUTP(MDP_BASE + 0x50258, 0x2b0003e6);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6);
+	MDP_OUTP(MDP_BASE + 0x5025c, 0x260003e8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4);
+	MDP_OUTP(MDP_BASE + 0x50260, 0x214003eb);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2);
+	MDP_OUTP(MDP_BASE + 0x50264, 0x1c4003ee);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf);
+	MDP_OUTP(MDP_BASE + 0x50268, 0x17c003f1);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db);
+	MDP_OUTP(MDP_BASE + 0x5026c, 0x134003f3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5);
+	MDP_OUTP(MDP_BASE + 0x50270, 0xf0003f6);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee);
+	MDP_OUTP(MDP_BASE + 0x50274, 0xac003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5);
+	MDP_OUTP(MDP_BASE + 0x50278, 0x70003fb);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb);
+	MDP_OUTP(MDP_BASE + 0x5027c, 0x34003fe);
+}
+
+static void mdp_load_bc_downscale_table_x_point2TOpoint4(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac00084);
+	MDP_OUTP(MDP_BASE + 0x50280, 0x23400083);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b000084);
+	MDP_OUTP(MDP_BASE + 0x50284, 0x23000083);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400084);
+	MDP_OUTP(MDP_BASE + 0x50288, 0x23000082);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400085);
+	MDP_OUTP(MDP_BASE + 0x5028c, 0x23000081);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b800085);
+	MDP_OUTP(MDP_BASE + 0x50290, 0x23000080);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc00086);
+	MDP_OUTP(MDP_BASE + 0x50294, 0x22c0007f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c000086);
+	MDP_OUTP(MDP_BASE + 0x50298, 0x2280007f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c400086);
+	MDP_OUTP(MDP_BASE + 0x5029c, 0x2280007e);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c800086);
+	MDP_OUTP(MDP_BASE + 0x502a0, 0x2280007d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00086);
+	MDP_OUTP(MDP_BASE + 0x502a4, 0x2240007d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00087);
+	MDP_OUTP(MDP_BASE + 0x502a8, 0x2240007c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d000087);
+	MDP_OUTP(MDP_BASE + 0x502ac, 0x2240007b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400087);
+	MDP_OUTP(MDP_BASE + 0x502b0, 0x2200007b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400088);
+	MDP_OUTP(MDP_BASE + 0x502b4, 0x22400079);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d800088);
+	MDP_OUTP(MDP_BASE + 0x502b8, 0x22400078);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00088);
+	MDP_OUTP(MDP_BASE + 0x502bc, 0x22400077);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00089);
+	MDP_OUTP(MDP_BASE + 0x502c0, 0x22000077);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e000089);
+	MDP_OUTP(MDP_BASE + 0x502c4, 0x22000076);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e400089);
+	MDP_OUTP(MDP_BASE + 0x502c8, 0x22000075);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00088);
+	MDP_OUTP(MDP_BASE + 0x502cc, 0x21c00075);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00089);
+	MDP_OUTP(MDP_BASE + 0x502d0, 0x21c00074);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f000089);
+	MDP_OUTP(MDP_BASE + 0x502d4, 0x21c00073);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f400089);
+	MDP_OUTP(MDP_BASE + 0x502d8, 0x21800073);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f40008a);
+	MDP_OUTP(MDP_BASE + 0x502dc, 0x21800072);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f80008a);
+	MDP_OUTP(MDP_BASE + 0x502e0, 0x21800071);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008a);
+	MDP_OUTP(MDP_BASE + 0x502e4, 0x21800070);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008b);
+	MDP_OUTP(MDP_BASE + 0x502e8, 0x2180006f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x2000008c);
+	MDP_OUTP(MDP_BASE + 0x502ec, 0x2140006e);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x2040008c);
+	MDP_OUTP(MDP_BASE + 0x502f0, 0x2140006d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x2080008c);
+	MDP_OUTP(MDP_BASE + 0x502f4, 0x2100006d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008c);
+	MDP_OUTP(MDP_BASE + 0x502f8, 0x2100006c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008d);
+	MDP_OUTP(MDP_BASE + 0x502fc, 0x2100006b);
+}
+
+static void mdp_load_bc_downscale_table_y_point2TOpoint4(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac00084);
+	MDP_OUTP(MDP_BASE + 0x50300, 0x23400083);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b000084);
+	MDP_OUTP(MDP_BASE + 0x50304, 0x23000083);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400084);
+	MDP_OUTP(MDP_BASE + 0x50308, 0x23000082);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400085);
+	MDP_OUTP(MDP_BASE + 0x5030c, 0x23000081);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b800085);
+	MDP_OUTP(MDP_BASE + 0x50310, 0x23000080);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc00086);
+	MDP_OUTP(MDP_BASE + 0x50314, 0x22c0007f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c000086);
+	MDP_OUTP(MDP_BASE + 0x50318, 0x2280007f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c400086);
+	MDP_OUTP(MDP_BASE + 0x5031c, 0x2280007e);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c800086);
+	MDP_OUTP(MDP_BASE + 0x50320, 0x2280007d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00086);
+	MDP_OUTP(MDP_BASE + 0x50324, 0x2240007d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00087);
+	MDP_OUTP(MDP_BASE + 0x50328, 0x2240007c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d000087);
+	MDP_OUTP(MDP_BASE + 0x5032c, 0x2240007b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400087);
+	MDP_OUTP(MDP_BASE + 0x50330, 0x2200007b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400088);
+	MDP_OUTP(MDP_BASE + 0x50334, 0x22400079);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d800088);
+	MDP_OUTP(MDP_BASE + 0x50338, 0x22400078);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00088);
+	MDP_OUTP(MDP_BASE + 0x5033c, 0x22400077);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00089);
+	MDP_OUTP(MDP_BASE + 0x50340, 0x22000077);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e000089);
+	MDP_OUTP(MDP_BASE + 0x50344, 0x22000076);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e400089);
+	MDP_OUTP(MDP_BASE + 0x50348, 0x22000075);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00088);
+	MDP_OUTP(MDP_BASE + 0x5034c, 0x21c00075);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00089);
+	MDP_OUTP(MDP_BASE + 0x50350, 0x21c00074);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f000089);
+	MDP_OUTP(MDP_BASE + 0x50354, 0x21c00073);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f400089);
+	MDP_OUTP(MDP_BASE + 0x50358, 0x21800073);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f40008a);
+	MDP_OUTP(MDP_BASE + 0x5035c, 0x21800072);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f80008a);
+	MDP_OUTP(MDP_BASE + 0x50360, 0x21800071);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008a);
+	MDP_OUTP(MDP_BASE + 0x50364, 0x21800070);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008b);
+	MDP_OUTP(MDP_BASE + 0x50368, 0x2180006f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x2000008c);
+	MDP_OUTP(MDP_BASE + 0x5036c, 0x2140006e);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x2040008c);
+	MDP_OUTP(MDP_BASE + 0x50370, 0x2140006d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x2080008c);
+	MDP_OUTP(MDP_BASE + 0x50374, 0x2100006d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008c);
+	MDP_OUTP(MDP_BASE + 0x50378, 0x2100006c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008d);
+	MDP_OUTP(MDP_BASE + 0x5037c, 0x2100006b);
+}
+
+static void mdp_load_bc_downscale_table_x_point4TOpoint6(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x740008c);
+	MDP_OUTP(MDP_BASE + 0x50280, 0x33800088);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x800008e);
+	MDP_OUTP(MDP_BASE + 0x50284, 0x33400084);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x8400092);
+	MDP_OUTP(MDP_BASE + 0x50288, 0x33000080);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x9000094);
+	MDP_OUTP(MDP_BASE + 0x5028c, 0x3300007b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x9c00098);
+	MDP_OUTP(MDP_BASE + 0x50290, 0x32400077);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xa40009b);
+	MDP_OUTP(MDP_BASE + 0x50294, 0x32000073);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xb00009d);
+	MDP_OUTP(MDP_BASE + 0x50298, 0x31c0006f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xbc000a0);
+	MDP_OUTP(MDP_BASE + 0x5029c, 0x3140006b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xc8000a2);
+	MDP_OUTP(MDP_BASE + 0x502a0, 0x31000067);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xd8000a5);
+	MDP_OUTP(MDP_BASE + 0x502a4, 0x30800062);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xe4000a8);
+	MDP_OUTP(MDP_BASE + 0x502a8, 0x2fc0005f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xec000aa);
+	MDP_OUTP(MDP_BASE + 0x502ac, 0x2fc0005b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8000ad);
+	MDP_OUTP(MDP_BASE + 0x502b0, 0x2f400057);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x108000b0);
+	MDP_OUTP(MDP_BASE + 0x502b4, 0x2e400054);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x114000b2);
+	MDP_OUTP(MDP_BASE + 0x502b8, 0x2e000050);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x124000b4);
+	MDP_OUTP(MDP_BASE + 0x502bc, 0x2d80004c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x130000b6);
+	MDP_OUTP(MDP_BASE + 0x502c0, 0x2d000049);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x140000b8);
+	MDP_OUTP(MDP_BASE + 0x502c4, 0x2c800045);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x150000b9);
+	MDP_OUTP(MDP_BASE + 0x502c8, 0x2c000042);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x15c000bd);
+	MDP_OUTP(MDP_BASE + 0x502cc, 0x2b40003e);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x16c000bf);
+	MDP_OUTP(MDP_BASE + 0x502d0, 0x2a80003b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x17c000bf);
+	MDP_OUTP(MDP_BASE + 0x502d4, 0x2a000039);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x188000c2);
+	MDP_OUTP(MDP_BASE + 0x502d8, 0x29400036);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x19c000c4);
+	MDP_OUTP(MDP_BASE + 0x502dc, 0x28800032);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac000c5);
+	MDP_OUTP(MDP_BASE + 0x502e0, 0x2800002f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc000c7);
+	MDP_OUTP(MDP_BASE + 0x502e4, 0x2740002c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc000c8);
+	MDP_OUTP(MDP_BASE + 0x502e8, 0x26c00029);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc000c9);
+	MDP_OUTP(MDP_BASE + 0x502ec, 0x26000027);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec000cc);
+	MDP_OUTP(MDP_BASE + 0x502f0, 0x25000024);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x200000cc);
+	MDP_OUTP(MDP_BASE + 0x502f4, 0x24800021);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x210000cd);
+	MDP_OUTP(MDP_BASE + 0x502f8, 0x23800020);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x220000ce);
+	MDP_OUTP(MDP_BASE + 0x502fc, 0x2300001d);
+}
+
+static void mdp_load_bc_downscale_table_y_point4TOpoint6(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x740008c);
+	MDP_OUTP(MDP_BASE + 0x50300, 0x33800088);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x800008e);
+	MDP_OUTP(MDP_BASE + 0x50304, 0x33400084);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x8400092);
+	MDP_OUTP(MDP_BASE + 0x50308, 0x33000080);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x9000094);
+	MDP_OUTP(MDP_BASE + 0x5030c, 0x3300007b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x9c00098);
+	MDP_OUTP(MDP_BASE + 0x50310, 0x32400077);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xa40009b);
+	MDP_OUTP(MDP_BASE + 0x50314, 0x32000073);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xb00009d);
+	MDP_OUTP(MDP_BASE + 0x50318, 0x31c0006f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xbc000a0);
+	MDP_OUTP(MDP_BASE + 0x5031c, 0x3140006b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xc8000a2);
+	MDP_OUTP(MDP_BASE + 0x50320, 0x31000067);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xd8000a5);
+	MDP_OUTP(MDP_BASE + 0x50324, 0x30800062);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xe4000a8);
+	MDP_OUTP(MDP_BASE + 0x50328, 0x2fc0005f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xec000aa);
+	MDP_OUTP(MDP_BASE + 0x5032c, 0x2fc0005b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8000ad);
+	MDP_OUTP(MDP_BASE + 0x50330, 0x2f400057);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x108000b0);
+	MDP_OUTP(MDP_BASE + 0x50334, 0x2e400054);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x114000b2);
+	MDP_OUTP(MDP_BASE + 0x50338, 0x2e000050);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x124000b4);
+	MDP_OUTP(MDP_BASE + 0x5033c, 0x2d80004c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x130000b6);
+	MDP_OUTP(MDP_BASE + 0x50340, 0x2d000049);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x140000b8);
+	MDP_OUTP(MDP_BASE + 0x50344, 0x2c800045);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x150000b9);
+	MDP_OUTP(MDP_BASE + 0x50348, 0x2c000042);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x15c000bd);
+	MDP_OUTP(MDP_BASE + 0x5034c, 0x2b40003e);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x16c000bf);
+	MDP_OUTP(MDP_BASE + 0x50350, 0x2a80003b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x17c000bf);
+	MDP_OUTP(MDP_BASE + 0x50354, 0x2a000039);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x188000c2);
+	MDP_OUTP(MDP_BASE + 0x50358, 0x29400036);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x19c000c4);
+	MDP_OUTP(MDP_BASE + 0x5035c, 0x28800032);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac000c5);
+	MDP_OUTP(MDP_BASE + 0x50360, 0x2800002f);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc000c7);
+	MDP_OUTP(MDP_BASE + 0x50364, 0x2740002c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc000c8);
+	MDP_OUTP(MDP_BASE + 0x50368, 0x26c00029);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc000c9);
+	MDP_OUTP(MDP_BASE + 0x5036c, 0x26000027);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec000cc);
+	MDP_OUTP(MDP_BASE + 0x50370, 0x25000024);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x200000cc);
+	MDP_OUTP(MDP_BASE + 0x50374, 0x24800021);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x210000cd);
+	MDP_OUTP(MDP_BASE + 0x50378, 0x23800020);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x220000ce);
+	MDP_OUTP(MDP_BASE + 0x5037c, 0x2300001d);
+}
+
+static void mdp_load_bc_downscale_table_x_point6TOpoint8(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000070);
+	MDP_OUTP(MDP_BASE + 0x50280, 0x4bc00068);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000078);
+	MDP_OUTP(MDP_BASE + 0x50284, 0x4bc00060);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000080);
+	MDP_OUTP(MDP_BASE + 0x50288, 0x4b800059);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000089);
+	MDP_OUTP(MDP_BASE + 0x5028c, 0x4b000052);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe400091);
+	MDP_OUTP(MDP_BASE + 0x50290, 0x4a80004b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40009a);
+	MDP_OUTP(MDP_BASE + 0x50294, 0x4a000044);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe8000a3);
+	MDP_OUTP(MDP_BASE + 0x50298, 0x4940003d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec000ac);
+	MDP_OUTP(MDP_BASE + 0x5029c, 0x48400037);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xff0000b4);
+	MDP_OUTP(MDP_BASE + 0x502a0, 0x47800031);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xff8000bd);
+	MDP_OUTP(MDP_BASE + 0x502a4, 0x4640002b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xc5);
+	MDP_OUTP(MDP_BASE + 0x502a8, 0x45000026);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x8000ce);
+	MDP_OUTP(MDP_BASE + 0x502ac, 0x43800021);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x10000d6);
+	MDP_OUTP(MDP_BASE + 0x502b0, 0x4240001c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x18000df);
+	MDP_OUTP(MDP_BASE + 0x502b4, 0x40800018);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x24000e6);
+	MDP_OUTP(MDP_BASE + 0x502b8, 0x3f000014);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x30000ee);
+	MDP_OUTP(MDP_BASE + 0x502bc, 0x3d400010);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x40000f5);
+	MDP_OUTP(MDP_BASE + 0x502c0, 0x3b80000c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x50000fc);
+	MDP_OUTP(MDP_BASE + 0x502c4, 0x39800009);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x6000102);
+	MDP_OUTP(MDP_BASE + 0x502c8, 0x37c00006);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x7000109);
+	MDP_OUTP(MDP_BASE + 0x502cc, 0x35800004);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x840010e);
+	MDP_OUTP(MDP_BASE + 0x502d0, 0x33800002);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x9800114);
+	MDP_OUTP(MDP_BASE + 0x502d4, 0x31400000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xac00119);
+	MDP_OUTP(MDP_BASE + 0x502d8, 0x2f4003fe);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xc40011e);
+	MDP_OUTP(MDP_BASE + 0x502dc, 0x2d0003fc);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xdc00121);
+	MDP_OUTP(MDP_BASE + 0x502e0, 0x2b0003fb);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf400125);
+	MDP_OUTP(MDP_BASE + 0x502e4, 0x28c003fa);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x11000128);
+	MDP_OUTP(MDP_BASE + 0x502e8, 0x268003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x12c0012a);
+	MDP_OUTP(MDP_BASE + 0x502ec, 0x244003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1480012c);
+	MDP_OUTP(MDP_BASE + 0x502f0, 0x224003f8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1640012e);
+	MDP_OUTP(MDP_BASE + 0x502f4, 0x200003f8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1800012f);
+	MDP_OUTP(MDP_BASE + 0x502f8, 0x1e0003f8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1a00012f);
+	MDP_OUTP(MDP_BASE + 0x502fc, 0x1c0003f8);
+}
+
+static void mdp_load_bc_downscale_table_y_point6TOpoint8(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000070);
+	MDP_OUTP(MDP_BASE + 0x50300, 0x4bc00068);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000078);
+	MDP_OUTP(MDP_BASE + 0x50304, 0x4bc00060);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000080);
+	MDP_OUTP(MDP_BASE + 0x50308, 0x4b800059);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000089);
+	MDP_OUTP(MDP_BASE + 0x5030c, 0x4b000052);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe400091);
+	MDP_OUTP(MDP_BASE + 0x50310, 0x4a80004b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40009a);
+	MDP_OUTP(MDP_BASE + 0x50314, 0x4a000044);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe8000a3);
+	MDP_OUTP(MDP_BASE + 0x50318, 0x4940003d);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec000ac);
+	MDP_OUTP(MDP_BASE + 0x5031c, 0x48400037);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xff0000b4);
+	MDP_OUTP(MDP_BASE + 0x50320, 0x47800031);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xff8000bd);
+	MDP_OUTP(MDP_BASE + 0x50324, 0x4640002b);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xc5);
+	MDP_OUTP(MDP_BASE + 0x50328, 0x45000026);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x8000ce);
+	MDP_OUTP(MDP_BASE + 0x5032c, 0x43800021);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x10000d6);
+	MDP_OUTP(MDP_BASE + 0x50330, 0x4240001c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x18000df);
+	MDP_OUTP(MDP_BASE + 0x50334, 0x40800018);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x24000e6);
+	MDP_OUTP(MDP_BASE + 0x50338, 0x3f000014);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x30000ee);
+	MDP_OUTP(MDP_BASE + 0x5033c, 0x3d400010);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x40000f5);
+	MDP_OUTP(MDP_BASE + 0x50340, 0x3b80000c);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x50000fc);
+	MDP_OUTP(MDP_BASE + 0x50344, 0x39800009);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x6000102);
+	MDP_OUTP(MDP_BASE + 0x50348, 0x37c00006);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x7000109);
+	MDP_OUTP(MDP_BASE + 0x5034c, 0x35800004);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x840010e);
+	MDP_OUTP(MDP_BASE + 0x50350, 0x33800002);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x9800114);
+	MDP_OUTP(MDP_BASE + 0x50354, 0x31400000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xac00119);
+	MDP_OUTP(MDP_BASE + 0x50358, 0x2f4003fe);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xc40011e);
+	MDP_OUTP(MDP_BASE + 0x5035c, 0x2d0003fc);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xdc00121);
+	MDP_OUTP(MDP_BASE + 0x50360, 0x2b0003fb);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf400125);
+	MDP_OUTP(MDP_BASE + 0x50364, 0x28c003fa);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x11000128);
+	MDP_OUTP(MDP_BASE + 0x50368, 0x268003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x12c0012a);
+	MDP_OUTP(MDP_BASE + 0x5036c, 0x244003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1480012c);
+	MDP_OUTP(MDP_BASE + 0x50370, 0x224003f8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1640012e);
+	MDP_OUTP(MDP_BASE + 0x50374, 0x200003f8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1800012f);
+	MDP_OUTP(MDP_BASE + 0x50378, 0x1e0003f8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x1a00012f);
+	MDP_OUTP(MDP_BASE + 0x5037c, 0x1c0003f8);
+}
+
+static void mdp_load_bc_downscale_table_x_point8TO1(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d);
+	MDP_OUTP(MDP_BASE + 0x50284, 0x7ec003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c);
+	MDP_OUTP(MDP_BASE + 0x50288, 0x7d4003f3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b);
+	MDP_OUTP(MDP_BASE + 0x5028c, 0x7b8003ed);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c);
+	MDP_OUTP(MDP_BASE + 0x50290, 0x794003e8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d);
+	MDP_OUTP(MDP_BASE + 0x50294, 0x76c003e4);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f);
+	MDP_OUTP(MDP_BASE + 0x50298, 0x73c003e0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071);
+	MDP_OUTP(MDP_BASE + 0x5029c, 0x708003de);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085);
+	MDP_OUTP(MDP_BASE + 0x502a0, 0x6d0003db);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098);
+	MDP_OUTP(MDP_BASE + 0x502a4, 0x698003d9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac);
+	MDP_OUTP(MDP_BASE + 0x502a8, 0x654003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1);
+	MDP_OUTP(MDP_BASE + 0x502ac, 0x610003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5);
+	MDP_OUTP(MDP_BASE + 0x502b0, 0x5c8003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9);
+	MDP_OUTP(MDP_BASE + 0x502b4, 0x580003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd);
+	MDP_OUTP(MDP_BASE + 0x502b8, 0x534003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112);
+	MDP_OUTP(MDP_BASE + 0x502bc, 0x4e8003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126);
+	MDP_OUTP(MDP_BASE + 0x502c0, 0x494003da);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a);
+	MDP_OUTP(MDP_BASE + 0x502c4, 0x448003db);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d);
+	MDP_OUTP(MDP_BASE + 0x502c8, 0x3f4003dd);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160);
+	MDP_OUTP(MDP_BASE + 0x502cc, 0x3a4003df);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172);
+	MDP_OUTP(MDP_BASE + 0x502d0, 0x354003e1);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184);
+	MDP_OUTP(MDP_BASE + 0x502d4, 0x304003e3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195);
+	MDP_OUTP(MDP_BASE + 0x502d8, 0x2b0003e6);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6);
+	MDP_OUTP(MDP_BASE + 0x502dc, 0x260003e8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4);
+	MDP_OUTP(MDP_BASE + 0x502e0, 0x214003eb);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2);
+	MDP_OUTP(MDP_BASE + 0x502e4, 0x1c4003ee);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf);
+	MDP_OUTP(MDP_BASE + 0x502e8, 0x17c003f1);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db);
+	MDP_OUTP(MDP_BASE + 0x502ec, 0x134003f3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5);
+	MDP_OUTP(MDP_BASE + 0x502f0, 0xf0003f6);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee);
+	MDP_OUTP(MDP_BASE + 0x502f4, 0xac003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5);
+	MDP_OUTP(MDP_BASE + 0x502f8, 0x70003fb);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb);
+	MDP_OUTP(MDP_BASE + 0x502fc, 0x34003fe);
+}
+
+static void mdp_load_bc_downscale_table_y_point8TO1(void)
+{
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0x0);
+	MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d);
+	MDP_OUTP(MDP_BASE + 0x50304, 0x7ec003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c);
+	MDP_OUTP(MDP_BASE + 0x50308, 0x7d4003f3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b);
+	MDP_OUTP(MDP_BASE + 0x5030c, 0x7b8003ed);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c);
+	MDP_OUTP(MDP_BASE + 0x50310, 0x794003e8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d);
+	MDP_OUTP(MDP_BASE + 0x50314, 0x76c003e4);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f);
+	MDP_OUTP(MDP_BASE + 0x50318, 0x73c003e0);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071);
+	MDP_OUTP(MDP_BASE + 0x5031c, 0x708003de);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085);
+	MDP_OUTP(MDP_BASE + 0x50320, 0x6d0003db);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098);
+	MDP_OUTP(MDP_BASE + 0x50324, 0x698003d9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac);
+	MDP_OUTP(MDP_BASE + 0x50328, 0x654003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1);
+	MDP_OUTP(MDP_BASE + 0x5032c, 0x610003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5);
+	MDP_OUTP(MDP_BASE + 0x50330, 0x5c8003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9);
+	MDP_OUTP(MDP_BASE + 0x50334, 0x580003d7);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd);
+	MDP_OUTP(MDP_BASE + 0x50338, 0x534003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112);
+	MDP_OUTP(MDP_BASE + 0x5033c, 0x4e8003d8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126);
+	MDP_OUTP(MDP_BASE + 0x50340, 0x494003da);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a);
+	MDP_OUTP(MDP_BASE + 0x50344, 0x448003db);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d);
+	MDP_OUTP(MDP_BASE + 0x50348, 0x3f4003dd);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160);
+	MDP_OUTP(MDP_BASE + 0x5034c, 0x3a4003df);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172);
+	MDP_OUTP(MDP_BASE + 0x50350, 0x354003e1);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184);
+	MDP_OUTP(MDP_BASE + 0x50354, 0x304003e3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195);
+	MDP_OUTP(MDP_BASE + 0x50358, 0x2b0003e6);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6);
+	MDP_OUTP(MDP_BASE + 0x5035c, 0x260003e8);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4);
+	MDP_OUTP(MDP_BASE + 0x50360, 0x214003eb);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2);
+	MDP_OUTP(MDP_BASE + 0x50364, 0x1c4003ee);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf);
+	MDP_OUTP(MDP_BASE + 0x50368, 0x17c003f1);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db);
+	MDP_OUTP(MDP_BASE + 0x5036c, 0x134003f3);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5);
+	MDP_OUTP(MDP_BASE + 0x50370, 0xf0003f6);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee);
+	MDP_OUTP(MDP_BASE + 0x50374, 0xac003f9);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5);
+	MDP_OUTP(MDP_BASE + 0x50378, 0x70003fb);
+	MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb);
+	MDP_OUTP(MDP_BASE + 0x5037c, 0x34003fe);
+}
+
+static int mdp_get_edge_cond(MDPIBUF *iBuf, uint32 *dup, uint32 *dup2)
+{
+	uint32 reg;
+	uint32 dst_roi_width;	/* Dimensions of DST ROI. */
+	uint32 dst_roi_height;	/* Used to calculate scaling ratios. */
+
+	/*
+	 * positions of the luma pixel(relative to the image ) required for
+	 * scaling the ROI
+	 */
+	int32 luma_interp_point_left = 0; /* left-most luma pixel needed */
+	int32 luma_interp_point_right = 0; /* right-most luma pixel needed */
+	int32 luma_interp_point_top = 0; /* top-most luma pixel needed */
+	int32 luma_interp_point_bottom = 0; /* bottom-most luma pixel needed */
+
+	/*
+	 * positions of the chroma pixel(relative to the image ) required for
+	 * interpolating a chroma value at all required luma positions
+	 */
+	/* left-most chroma pixel needed */
+	int32 chroma_interp_point_left = 0;
+	/* right-most chroma pixel needed */
+	int32 chroma_interp_point_right = 0;
+	/* top-most chroma pixel needed */
+	int32 chroma_interp_point_top = 0;
+	/* bottom-most chroma pixel needed */
+	int32 chroma_interp_point_bottom = 0;
+
+	/*
+	 * a rectangular region within the chroma plane of the "image".
+	 * Chroma pixels falling inside of this rectangle belongs to the ROI
+	 */
+	int32 chroma_bound_left = 0;
+	int32 chroma_bound_right = 0;
+	int32 chroma_bound_top = 0;
+	int32 chroma_bound_bottom = 0;
+
+	/*
+	 * number of chroma pixels to replicate on the left, right,
+	 * top and bottom edge of the ROI.
+	 */
+	int32 chroma_repeat_left = 0;
+	int32 chroma_repeat_right = 0;
+	int32 chroma_repeat_top = 0;
+	int32 chroma_repeat_bottom = 0;
+
+	/*
+	 * number of luma pixels to replicate on the left, right,
+	 * top and bottom edge of the ROI.
+	 */
+	int32 luma_repeat_left = 0;
+	int32 luma_repeat_right = 0;
+	int32 luma_repeat_top = 0;
+	int32 luma_repeat_bottom = 0;
+
+	boolean chroma_edge_enable;
+
+	uint32 _is_scale_enabled = 0;
+	uint32 _is_yuv_offsite_vertical = 0;
+
+	/* fg edge duplicate */
+	reg = 0x0;
+
+	if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {	/* if scaling enabled */
+
+		_is_scale_enabled = 1;
+
+		/*
+		 * if rotation mode involves a 90 deg rotation, flip
+		 * dst_roi_width with dst_roi_height.
+		 * Scaling ratios is based on source ROI dimensions, and
+		 * dst ROI dimensions before rotation.
+		 */
+		if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
+			dst_roi_width = iBuf->roi.dst_height;
+			dst_roi_height = iBuf->roi.dst_width;
+		} else {
+			dst_roi_width = iBuf->roi.dst_width;
+			dst_roi_height = iBuf->roi.dst_height;
+		}
+
+		/*
+		 * Find out the luma pixels needed for scaling in the
+		 * x direction (LEFT and RIGHT).  Locations of pixels are
+		 * relative to the ROI. Upper-left corner of ROI corresponds
+		 * to coordinates (0,0). Also set the number of luma pixel
+		 * to repeat.
+		 */
+		if (iBuf->roi.width > 3 * dst_roi_width) {
+			/* scale factor < 1/3 */
+			luma_interp_point_left = 0;
+			luma_interp_point_right = (iBuf->roi.width - 1);
+			luma_repeat_left = 0;
+			luma_repeat_right = 0;
+		} else if (iBuf->roi.width == 3 * dst_roi_width) {
+			/* scale factor == 1/3 */
+			luma_interp_point_left = 0;
+			luma_interp_point_right = (iBuf->roi.width - 1) + 1;
+			luma_repeat_left = 0;
+			luma_repeat_right = 1;
+		} else if ((iBuf->roi.width > dst_roi_width) &&
+			   (iBuf->roi.width < 3 * dst_roi_width)) {
+			/* 1/3 < scale factor < 1 */
+			luma_interp_point_left = -1;
+			luma_interp_point_right = (iBuf->roi.width - 1) + 1;
+			luma_repeat_left = 1;
+			luma_repeat_right = 1;
+		}
+
+		else if (iBuf->roi.width == dst_roi_width) {
+			/* scale factor == 1 */
+			luma_interp_point_left = -1;
+			luma_interp_point_right = (iBuf->roi.width - 1) + 2;
+			luma_repeat_left = 1;
+			luma_repeat_right = 2;
+		} else {	/* (iBuf->roi.width < dst_roi_width) */
+			  /* scale factor > 1 */
+			luma_interp_point_left = -2;
+			luma_interp_point_right = (iBuf->roi.width - 1) + 2;
+			luma_repeat_left = 2;
+			luma_repeat_right = 2;
+		}
+
+		/*
+		 * Find out the number of pixels needed for scaling in the
+		 * y direction (TOP and BOTTOM).  Locations of pixels are
+		 * relative to the ROI. Upper-left corner of ROI corresponds
+		 * to coordinates (0,0). Also set the number of luma pixel
+		 * to repeat.
+		 */
+		if (iBuf->roi.height > 3 * dst_roi_height) {
+			/* scale factor < 1/3 */
+			luma_interp_point_top = 0;
+			luma_interp_point_bottom = (iBuf->roi.height - 1);
+			luma_repeat_top = 0;
+			luma_repeat_bottom = 0;
+		} else if (iBuf->roi.height == 3 * dst_roi_height) {
+			/* scale factor == 1/3 */
+			luma_interp_point_top = 0;
+			luma_interp_point_bottom = (iBuf->roi.height - 1) + 1;
+			luma_repeat_top = 0;
+			luma_repeat_bottom = 1;
+		} else if ((iBuf->roi.height > dst_roi_height) &&
+			   (iBuf->roi.height < 3 * dst_roi_height)) {
+			/* 1/3 < scale factor < 1 */
+			luma_interp_point_top = -1;
+			luma_interp_point_bottom = (iBuf->roi.height - 1) + 1;
+			luma_repeat_top = 1;
+			luma_repeat_bottom = 1;
+		} else if (iBuf->roi.height == dst_roi_height) {
+			/* scale factor == 1 */
+			luma_interp_point_top = -1;
+			luma_interp_point_bottom = (iBuf->roi.height - 1) + 2;
+			luma_repeat_top = 1;
+			luma_repeat_bottom = 2;
+		} else {	/* (iBuf->roi.height < dst_roi_height) */
+			 /* scale factor > 1 */
+			luma_interp_point_top = -2;
+			luma_interp_point_bottom = (iBuf->roi.height - 1) + 2;
+			luma_repeat_top = 2;
+			luma_repeat_bottom = 2;
+		}
+	}			/* if (iBuf->scale.scale_flag) */
+	else {			/* scaling disabled */
+		/*
+		 * Since no scaling needed, Tile Fetch does not require any
+		 * more luma pixel than what the ROI contains.
+		 */
+		luma_interp_point_left = (int32) 0;
+		luma_interp_point_right = (int32) (iBuf->roi.width - 1);
+		luma_interp_point_top = (int32) 0;
+		luma_interp_point_bottom = (int32) (iBuf->roi.height - 1);
+
+		luma_repeat_left = 0;
+		luma_repeat_right = 0;
+		luma_repeat_top = 0;
+		luma_repeat_bottom = 0;
+	}
+
+	/* After adding the ROI offsets, we have locations of
+	 * luma_interp_points relative to the image.
+	 */
+	luma_interp_point_left += (int32) (iBuf->roi.x);
+	luma_interp_point_right += (int32) (iBuf->roi.x);
+	luma_interp_point_top += (int32) (iBuf->roi.y);
+	luma_interp_point_bottom += (int32) (iBuf->roi.y);
+
+	/*
+	 * After adding the ROI offsets, we have locations of
+	 * chroma_interp_points relative to the image.
+	 */
+	chroma_interp_point_left = luma_interp_point_left;
+	chroma_interp_point_right = luma_interp_point_right;
+	chroma_interp_point_top = luma_interp_point_top;
+	chroma_interp_point_bottom = luma_interp_point_bottom;
+
+	chroma_edge_enable = TRUE;
+	/* find out which chroma pixels are needed for chroma upsampling. */
+	switch (iBuf->mdpImg.imgType) {
+		/*
+		 * cosite in horizontal axis
+		 * fully sampled in vertical axis
+		 */
+	case MDP_Y_CBCR_H2V1:
+	case MDP_Y_CRCB_H2V1:
+	case MDP_YCRYCB_H2V1:
+		/* floor( luma_interp_point_left / 2 ); */
+		chroma_interp_point_left = luma_interp_point_left >> 1;
+		/* floor( ( luma_interp_point_right + 1 ) / 2 ); */
+		chroma_interp_point_right = (luma_interp_point_right + 1) >> 1;
+
+		chroma_interp_point_top = luma_interp_point_top;
+		chroma_interp_point_bottom = luma_interp_point_bottom;
+		break;
+
+		/*
+		 * cosite in horizontal axis
+		 * offsite in vertical axis
+		 */
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CBCR_H2V2_ADRENO:
+	case MDP_Y_CRCB_H2V2:
+		/* floor( luma_interp_point_left / 2) */
+		chroma_interp_point_left = luma_interp_point_left >> 1;
+
+		/* floor( ( luma_interp_point_right + 1 )/ 2 ) */
+		chroma_interp_point_right = (luma_interp_point_right + 1) >> 1;
+
+		/* floor( (luma_interp_point_top - 1 ) / 2 ) */
+		chroma_interp_point_top = (luma_interp_point_top - 1) >> 1;
+
+		/* floor( ( luma_interp_point_bottom + 1 ) / 2 ) */
+		chroma_interp_point_bottom =
+		    (luma_interp_point_bottom + 1) >> 1;
+
+		_is_yuv_offsite_vertical = 1;
+		break;
+
+	default:
+		chroma_edge_enable = FALSE;
+		chroma_interp_point_left = luma_interp_point_left;
+		chroma_interp_point_right = luma_interp_point_right;
+		chroma_interp_point_top = luma_interp_point_top;
+		chroma_interp_point_bottom = luma_interp_point_bottom;
+
+		break;
+	}
+
+	/* only if the image type is in YUV domain, we calculate chroma edge */
+	if (chroma_edge_enable) {
+		/* Defines which chroma pixels belongs to the roi */
+		switch (iBuf->mdpImg.imgType) {
+			/*
+			 * Cosite in horizontal direction, and fully sampled
+			 * in vertical direction.
+			 */
+		case MDP_Y_CBCR_H2V1:
+		case MDP_Y_CRCB_H2V1:
+		case MDP_YCRYCB_H2V1:
+			/*
+			 * width of chroma ROI is 1/2 of size of luma ROI
+			 * height of chroma ROI same as size of luma ROI
+			 */
+			chroma_bound_left = iBuf->roi.x / 2;
+
+			/* there are half as many chroma pixel as luma pixels */
+			chroma_bound_right =
+			    (iBuf->roi.width + iBuf->roi.x - 1) / 2;
+			chroma_bound_top = iBuf->roi.y;
+			chroma_bound_bottom =
+			    (iBuf->roi.height + iBuf->roi.y - 1);
+			break;
+
+		case MDP_Y_CBCR_H2V2:
+		case MDP_Y_CBCR_H2V2_ADRENO:
+		case MDP_Y_CRCB_H2V2:
+			/*
+			 * cosite in horizontal dir, and offsite in vertical dir
+			 * width of chroma ROI is 1/2 of size of luma ROI
+			 * height of chroma ROI is 1/2 of size of luma ROI
+			 */
+
+			chroma_bound_left = iBuf->roi.x / 2;
+			chroma_bound_right =
+			    (iBuf->roi.width + iBuf->roi.x - 1) / 2;
+			chroma_bound_top = iBuf->roi.y / 2;
+			chroma_bound_bottom =
+			    (iBuf->roi.height + iBuf->roi.y - 1) / 2;
+			break;
+
+		default:
+			/*
+			 * If no valid chroma sub-sampling format specified,
+			 * assume 4:4:4 ( i.e. fully sampled).  Set ROI
+			 * boundaries for chroma same as ROI boundaries for
+			 * luma.
+			 */
+			chroma_bound_left = iBuf->roi.x;
+			chroma_bound_right = iBuf->roi.width + iBuf->roi.x - 1;
+			chroma_bound_top = iBuf->roi.y;
+			chroma_bound_bottom =
+			    (iBuf->roi.height + iBuf->roi.y - 1);
+			break;
+		}
+
+		/*
+		 * Knowing which chroma pixels are needed, and which chroma
+		 * pixels belong to the ROI (i.e. available for fetching ),
+		 * calculate how many chroma pixels Tile Fetch needs to
+		 * duplicate.  If any required chroma pixels falls outside
+		 * of the ROI, Tile Fetch must obtain them by replicating
+		 * pixels.
+		 */
+		if (chroma_bound_left > chroma_interp_point_left)
+			chroma_repeat_left =
+			    chroma_bound_left - chroma_interp_point_left;
+		else
+			chroma_repeat_left = 0;
+
+		if (chroma_interp_point_right > chroma_bound_right)
+			chroma_repeat_right =
+			    chroma_interp_point_right - chroma_bound_right;
+		else
+			chroma_repeat_right = 0;
+
+		if (chroma_bound_top > chroma_interp_point_top)
+			chroma_repeat_top =
+			    chroma_bound_top - chroma_interp_point_top;
+		else
+			chroma_repeat_top = 0;
+
+		if (chroma_interp_point_bottom > chroma_bound_bottom)
+			chroma_repeat_bottom =
+			    chroma_interp_point_bottom - chroma_bound_bottom;
+		else
+			chroma_repeat_bottom = 0;
+
+		if (_is_scale_enabled && (iBuf->roi.height == 1)
+		    && _is_yuv_offsite_vertical) {
+			chroma_repeat_bottom = 3;
+			chroma_repeat_top = 0;
+		}
+	}
+	/* make sure chroma repeats are non-negative */
+	if ((chroma_repeat_left < 0) || (chroma_repeat_right < 0) ||
+	    (chroma_repeat_top < 0) || (chroma_repeat_bottom < 0))
+		return -1;
+
+	/* make sure chroma repeats are no larger than 3 pixels */
+	if ((chroma_repeat_left > 3) || (chroma_repeat_right > 3) ||
+	    (chroma_repeat_top > 3) || (chroma_repeat_bottom > 3))
+		return -1;
+
+	/* make sure luma repeats are non-negative */
+	if ((luma_repeat_left < 0) || (luma_repeat_right < 0) ||
+	    (luma_repeat_top < 0) || (luma_repeat_bottom < 0))
+		return -1;
+
+	/* make sure luma repeats are no larger than 3 pixels */
+	if ((luma_repeat_left > 3) || (luma_repeat_right > 3) ||
+	    (luma_repeat_top > 3) || (luma_repeat_bottom > 3))
+		return -1;
+
+	/* write chroma_repeat_left to register */
+	reg |= (chroma_repeat_left & 3) << MDP_LEFT_CHROMA;
+
+	/* write chroma_repeat_right to register */
+	reg |= (chroma_repeat_right & 3) << MDP_RIGHT_CHROMA;
+
+	/* write chroma_repeat_top to register */
+	reg |= (chroma_repeat_top & 3) << MDP_TOP_CHROMA;
+
+	/* write chroma_repeat_bottom to register */
+	reg |= (chroma_repeat_bottom & 3) << MDP_BOTTOM_CHROMA;
+
+	/* write luma_repeat_left to register */
+	reg |= (luma_repeat_left & 3) << MDP_LEFT_LUMA;
+
+	/* write luma_repeat_right to register */
+	reg |= (luma_repeat_right & 3) << MDP_RIGHT_LUMA;
+
+	/* write luma_repeat_top to register */
+	reg |= (luma_repeat_top & 3) << MDP_TOP_LUMA;
+
+	/* write luma_repeat_bottom to register */
+	reg |= (luma_repeat_bottom & 3) << MDP_BOTTOM_LUMA;
+
+	/* done with reg */
+	*dup = reg;
+
+	/* bg edge duplicate */
+	reg = 0x0;
+
+	switch (iBuf->ibuf_type) {
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CRCB_H2V2:
+		/*
+		 * Edge condition for MDP_Y_CRCB/CBCR_H2V2 cosite only.
+		 * For 420 cosite, 1 chroma replicated on all sides except
+		 * left, so reg 101b8 should be 0x0209. For 420 offsite,
+		 * 1 chroma replicated all sides.
+		 */
+		if (iBuf->roi.lcd_y == 0) {
+			reg |= BIT(MDP_TOP_CHROMA);
+		}
+
+		if ((iBuf->roi.lcd_y + iBuf->roi.dst_height) ==
+		    iBuf->ibuf_height) {
+			reg |= BIT(MDP_BOTTOM_CHROMA);
+		}
+
+		if (((iBuf->roi.lcd_x + iBuf->roi.dst_width) ==
+		     iBuf->ibuf_width) && ((iBuf->roi.dst_width % 2) == 0)) {
+			reg |= BIT(MDP_RIGHT_CHROMA);
+		}
+
+		break;
+
+	case MDP_Y_CBCR_H2V1:
+	case MDP_Y_CRCB_H2V1:
+	case MDP_YCRYCB_H2V1:
+		if (((iBuf->roi.lcd_x + iBuf->roi.dst_width) ==
+		     iBuf->ibuf_width) && ((iBuf->roi.dst_width % 2) == 0)) {
+			reg |= BIT(MDP_RIGHT_CHROMA);
+		}
+		break;
+	default:
+		break;
+	}
+
+	*dup2 = reg;
+
+	return 0;
+}
+
+#define ADJUST_IP		/* for 1/3 scale factor fix */
+
+static int mdp_calc_scale_params(
+/* ROI origin coordinate for the dimension */
+					uint32 org,
+/* src ROI dimension */
+					uint32 dim_in,
+/* scaled ROI dimension*/
+					uint32 dim_out,
+/* is this ROI width dimension? */
+					boolean is_W,
+/* initial phase location address */
+					int32 *phase_init_ptr,
+/* phase increment location address */
+					uint32 *phase_step_ptr,
+/* ROI start over-fetch location address */
+					uint32 *num_repl_beg_ptr,
+/* ROI end over-fetch location address */
+					uint32 *num_repl_end_ptr)
+{
+	boolean rpa_on = FALSE;
+	int init_phase = 0;
+	uint32 beg_of = 0;
+	uint32 end_of = 0;
+	uint64 numer = 0;
+	uint64 denom = 0;
+	/*uint64 inverter = 1; */
+	int64 point5 = 1;
+	int64 one = 1;
+	int64 k1, k2, k3, k4;	/* linear equation coefficients */
+	uint64 int_mask;
+	uint64 fract_mask;
+	uint64 Os;
+	int64 Osprime;
+	int64 Od;
+	int64 Odprime;
+	int64 Oreq;
+	uint64 Es;
+	uint64 Ed;
+	uint64 Ereq;
+#ifdef ADJUST_IP
+	int64 IP64;
+	int64 delta;
+#endif
+	uint32 mult;
+
+	/*
+	 * The phase accumulator should really be rational for all cases in a
+	 * general purpose polyphase scaler for a tiled architecture with
+	 * non-zero * origin capability because there is no way to represent
+	 * certain scale factors in fixed point regardless of precision.
+	 * The error incurred in attempting to use fixed point is most
+	 * eggregious for SF where 1/SF is an integral multiple of 1/3.
+	 *
+	 * However, since the MDP2 has already been committed to HW, we
+	 * only use the rational phase accumulator (RPA) when 1/SF is an
+	 * integral multiple of 1/3.  This will help minimize regressions in
+	 * matching the HW to the C-Sim.
+	 */
+	/*
+	 * Set the RPA flag for this dimension.
+	 *
+	 * In order for 1/SF (dim_in/dim_out) to be an integral multiple of
+	 * 1/3, dim_out must be an integral multiple of 3.
+	 */
+	if (!(dim_out % 3)) {
+		mult = dim_out / 3;
+		rpa_on = (!(dim_in % mult));
+	}
+
+	numer = dim_out;
+	denom = dim_in;
+
+	/*
+	 * convert to U30.34 before division
+	 *
+	 * The K vectors carry 4 extra bits of precision
+	 * and are rounded.
+	 *
+	 * We initially go 5 bits over then round by adding
+	 * 1 and right shifting by 1
+	 * so final result is U31.33
+	 */
+	numer <<= PQF_PLUS_5;
+
+	/* now calculate the scale factor (aka k3) */
+	k3 = ((mdp_do_div(numer, denom) + 1) >> 1);
+
+	/* check scale factor for legal range [0.25 - 4.0] */
+	if (((k3 >> 4) < (1LL << PQF_MINUS_2)) ||
+	    ((k3 >> 4) > (1LL << PQF_PLUS_2))) {
+		return -1;
+	}
+
+	/* calculate inverse scale factor (aka k1) for phase init */
+	numer = dim_in;
+	denom = dim_out;
+	numer <<= PQF_PLUS_5;
+	k1 = ((mdp_do_div(numer, denom) + 1) >> 1);
+
+	/*
+	 * calculate initial phase and ROI overfetch
+	 */
+	/* convert point5 & one to S39.24 (will always be positive) */
+	point5 <<= (PQF_PLUS_4 - 1);
+	one <<= PQF_PLUS_4;
+	k2 = ((k1 - one) >> 1);
+	init_phase = (int)(k2 >> 4);
+	k4 = ((k3 - one) >> 1);
+	if (k3 == one) {
+		/* the simple case; SF = 1.0 */
+		beg_of = 1;
+		end_of = 2;
+	} else {
+		/* calculate the masks */
+		fract_mask = one - 1;
+		int_mask = ~fract_mask;
+
+		if (!rpa_on) {
+			/*
+			 * FIXED POINT IMPLEMENTATION
+			 */
+			if (!org) {
+				/* A fairly simple case; ROI origin = 0 */
+				if (k1 < one) {
+					/* upscaling */
+					beg_of = end_of = 2;
+				}
+				/* 0.33 <= SF < 1.0 */
+				else if (k1 < (3LL << PQF_PLUS_4))
+					beg_of = end_of = 1;
+				/* 0.33 == SF */
+				else if (k1 == (3LL << PQF_PLUS_4)) {
+					beg_of = 0;
+					end_of = 1;
+				}
+				/* 0.25 <= SF < 0.33 */
+				else
+					beg_of = end_of = 0;
+			} else {
+				/*
+				 * The complicated case; ROI origin != 0
+				 * init_phase needs to be adjusted
+				 * OF is also position dependent
+				 */
+
+				/* map (org - .5) into destination space */
+				Os = ((uint64) org << 1) - 1;
+				Od = ((k3 * Os) >> 1) + k4;
+
+				/* take the ceiling */
+				Odprime = (Od & int_mask);
+				if (Odprime != Od)
+					Odprime += one;
+
+				/* now map that back to source space */
+				Osprime = (k1 * (Odprime >> PQF_PLUS_4)) + k2;
+
+				/* then floor & decrement to calculate the required
+				   starting coordinate */
+				Oreq = (Osprime & int_mask) - one;
+
+				/* calculate end coord in destination space then map to
+				   source space */
+				Ed = Odprime +
+				    ((uint64) dim_out << PQF_PLUS_4) - one;
+				Es = (k1 * (Ed >> PQF_PLUS_4)) + k2;
+
+				/* now floor & increment by 2 to calculate the required
+				   ending coordinate */
+				Ereq = (Es & int_mask) + (one << 1);
+
+				/* calculate initial phase */
+#ifdef ADJUST_IP
+
+				IP64 = Osprime - Oreq;
+				delta = ((int64) (org) << PQF_PLUS_4) - Oreq;
+				IP64 -= delta;
+
+				/* limit to valid range before the left shift */
+				delta = (IP64 & (1LL << 63)) ? 4 : -4;
+				delta <<= PQF_PLUS_4;
+				while (abs((int)(IP64 >> PQF_PLUS_4)) > 4)
+					IP64 += delta;
+
+				/* right shift to account for extra bits of precision */
+				init_phase = (int)(IP64 >> 4);
+
+#else /* ADJUST_IP */
+
+				/* just calculate the real initial phase */
+				init_phase = (int)((Osprime - Oreq) >> 4);
+
+#endif /* ADJUST_IP */
+
+				/* calculate the overfetch */
+				beg_of = org - (uint32) (Oreq >> PQF_PLUS_4);
+				end_of =
+				    (uint32) (Ereq >> PQF_PLUS_4) - (org +
+								     dim_in -
+								     1);
+			}
+		} else {
+			/*
+			 * RPA IMPLEMENTATION
+			 *
+			 * init_phase needs to be calculated in all RPA_on cases
+			 * because it's a numerator, not a fixed point value.
+			 */
+
+			/* map (org - .5) into destination space */
+			Os = ((uint64) org << PQF_PLUS_4) - point5;
+			Od = mdp_do_div((dim_out * (Os + point5)),
+					dim_in) - point5;
+
+			/* take the ceiling */
+			Odprime = (Od & int_mask);
+			if (Odprime != Od)
+				Odprime += one;
+
+			/* now map that back to source space */
+			Osprime =
+			    mdp_do_div((dim_in * (Odprime + point5)),
+				       dim_out) - point5;
+
+			/* then floor & decrement to calculate the required
+			   starting coordinate */
+			Oreq = (Osprime & int_mask) - one;
+
+			/* calculate end coord in destination space then map to
+			   source space */
+			Ed = Odprime + ((uint64) dim_out << PQF_PLUS_4) - one;
+			Es = mdp_do_div((dim_in * (Ed + point5)),
+					dim_out) - point5;
+
+			/* now floor & increment by 2 to calculate the required
+			   ending coordinate */
+			Ereq = (Es & int_mask) + (one << 1);
+
+			/* calculate initial phase */
+
+#ifdef ADJUST_IP
+
+			IP64 = Osprime - Oreq;
+			delta = ((int64) (org) << PQF_PLUS_4) - Oreq;
+			IP64 -= delta;
+
+			/* limit to valid range before the left shift */
+			delta = (IP64 & (1LL << 63)) ? 4 : -4;
+			delta <<= PQF_PLUS_4;
+			while (abs((int)(IP64 >> PQF_PLUS_4)) > 4)
+				IP64 += delta;
+
+			/* right shift to account for extra bits of precision */
+			init_phase = (int)(IP64 >> 4);
+
+#else /* ADJUST_IP */
+
+			/* just calculate the real initial phase */
+			init_phase = (int)((Osprime - Oreq) >> 4);
+
+#endif /* ADJUST_IP */
+
+			/* calculate the overfetch */
+			beg_of = org - (uint32) (Oreq >> PQF_PLUS_4);
+			end_of =
+			    (uint32) (Ereq >> PQF_PLUS_4) - (org + dim_in - 1);
+		}
+	}
+
+	/* return the scale parameters */
+	*phase_init_ptr = init_phase;
+	*phase_step_ptr = (uint32) (k1 >> 4);
+	*num_repl_beg_ptr = beg_of;
+	*num_repl_end_ptr = end_of;
+
+	return 0;
+}
+
+static uint8 *mdp_adjust_rot_addr(MDPIBUF *iBuf, uint8 *addr, uint32 uv)
+{
+	uint32 dest_ystride = iBuf->ibuf_width * iBuf->bpp;
+	uint32 h_slice = 1;
+
+	if (uv && ((iBuf->ibuf_type == MDP_Y_CBCR_H2V2) ||
+		(iBuf->ibuf_type == MDP_Y_CRCB_H2V2)))
+		h_slice = 2;
+
+	if (MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_ROT90) ^
+	    MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_LR)) {
+		addr =
+		    addr + (iBuf->roi.dst_width -
+			    MIN(16, iBuf->roi.dst_width)) * iBuf->bpp;
+	}
+	if (MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_UD)) {
+		addr =
+		    addr + ((iBuf->roi.dst_height -
+			MIN(16, iBuf->roi.dst_height))/h_slice) * dest_ystride;
+	}
+
+	return addr;
+}
+
+void mdp_set_scale(MDPIBUF *iBuf,
+		   uint32 dst_roi_width,
+		   uint32 dst_roi_height,
+		   boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr)
+{
+	uint32 dst_roi_width_scale;
+	uint32 dst_roi_height_scale;
+	boolean use_pr;
+	uint32 phasex_step = 0;
+	uint32 phasey_step = 0;
+	int32 phasex_init = 0;
+	int32 phasey_init = 0;
+	uint32 lines_dup = 0;
+	uint32 lines_dup_bg = 0;
+	uint32 dummy;
+	uint32 mdp_blur = 0;
+
+	if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {
+		if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
+			dst_roi_width_scale = dst_roi_height;
+			dst_roi_height_scale = dst_roi_width;
+		} else {
+			dst_roi_width_scale = dst_roi_width;
+			dst_roi_height_scale = dst_roi_height;
+		}
+
+		mdp_blur = iBuf->mdpImg.mdpOp & MDPOP_BLUR;
+
+		if ((dst_roi_width_scale != iBuf->roi.width) ||
+		    (dst_roi_height_scale != iBuf->roi.height) ||
+			mdp_blur) {
+			*pppop_reg_ptr |=
+			    (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
+
+			/* let's use SHIM logic to calculate the
+			   partial ROI scaling */
+			mdp_calc_scale_params(iBuf->roi.x, iBuf->roi.width,
+					      dst_roi_width_scale, 1,
+					      &phasex_init, &phasex_step,
+					      &dummy, &dummy);
+			mdp_calc_scale_params(iBuf->roi.y, iBuf->roi.height,
+					      dst_roi_height_scale, 0,
+					      &phasey_init, &phasey_step,
+					      &dummy, &dummy);
+			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
+				 phasex_init);
+			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
+				 phasey_init);
+			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144,
+				 phasex_step);
+			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148,
+				 phasey_step);
+
+			/* disable the pixel repeat option for scaling */
+			use_pr = false;
+
+			if ((dst_roi_width_scale > iBuf->roi.width) ||
+			    (dst_roi_height_scale > iBuf->roi.height)) {
+				if ((use_pr)
+				    && (mdp_curr_up_scale_xy !=
+					MDP_PR_SCALE_UP)) {
+					mdp_load_pr_upscale_table();
+					mdp_curr_up_scale_xy = MDP_PR_SCALE_UP;
+				} else if ((!use_pr)
+					   && (mdp_curr_up_scale_xy !=
+					       MDP_BC_SCALE_UP)) {
+					mdp_load_bc_upscale_table();
+					mdp_curr_up_scale_xy = MDP_BC_SCALE_UP;
+				}
+			}
+
+			if (mdp_blur) {
+				load_scale_table(mdp_gaussian_blur_table,
+					ARRAY_SIZE(mdp_gaussian_blur_table));
+				mdp_curr_down_scale_x = MDP_SCALE_BLUR;
+				mdp_curr_down_scale_y = MDP_SCALE_BLUR;
+			}
+
+			/* 0.2 < x <= 1 scaling factor */
+			if ((dst_roi_width_scale <= iBuf->roi.width) &&
+				!mdp_blur) {
+				if (((dst_roi_width_scale * 10) /
+				     iBuf->roi.width) > 8) {
+					if ((use_pr)
+					    && (mdp_curr_down_scale_x !=
+						MDP_PR_SCALE_POINT8_1)) {
+						mdp_load_pr_downscale_table_x_point8TO1
+						    ();
+						mdp_curr_down_scale_x =
+						    MDP_PR_SCALE_POINT8_1;
+					} else if ((!use_pr)
+						   && (mdp_curr_down_scale_x !=
+						       MDP_BC_SCALE_POINT8_1)) {
+						mdp_load_bc_downscale_table_x_point8TO1
+						    ();
+						mdp_curr_down_scale_x =
+						    MDP_BC_SCALE_POINT8_1;
+					}
+				} else
+				    if (((dst_roi_width_scale * 10) /
+					 iBuf->roi.width) > 6) {
+					if ((use_pr)
+					    && (mdp_curr_down_scale_x !=
+						MDP_PR_SCALE_POINT6_POINT8)) {
+						mdp_load_pr_downscale_table_x_point6TOpoint8
+						    ();
+						mdp_curr_down_scale_x =
+						    MDP_PR_SCALE_POINT6_POINT8;
+					} else if ((!use_pr)
+						   && (mdp_curr_down_scale_x !=
+						       MDP_BC_SCALE_POINT6_POINT8))
+					{
+						mdp_load_bc_downscale_table_x_point6TOpoint8
+						    ();
+						mdp_curr_down_scale_x =
+						    MDP_BC_SCALE_POINT6_POINT8;
+					}
+				} else
+				    if (((dst_roi_width_scale * 10) /
+					 iBuf->roi.width) > 4) {
+					if ((use_pr)
+					    && (mdp_curr_down_scale_x !=
+						MDP_PR_SCALE_POINT4_POINT6)) {
+						mdp_load_pr_downscale_table_x_point4TOpoint6
+						    ();
+						mdp_curr_down_scale_x =
+						    MDP_PR_SCALE_POINT4_POINT6;
+					} else if ((!use_pr)
+						   && (mdp_curr_down_scale_x !=
+						       MDP_BC_SCALE_POINT4_POINT6))
+					{
+						mdp_load_bc_downscale_table_x_point4TOpoint6
+						    ();
+						mdp_curr_down_scale_x =
+						    MDP_BC_SCALE_POINT4_POINT6;
+					}
+				} else {
+					if ((use_pr)
+					    && (mdp_curr_down_scale_x !=
+						MDP_PR_SCALE_POINT2_POINT4)) {
+						mdp_load_pr_downscale_table_x_point2TOpoint4
+						    ();
+						mdp_curr_down_scale_x =
+						    MDP_PR_SCALE_POINT2_POINT4;
+					} else if ((!use_pr)
+						   && (mdp_curr_down_scale_x !=
+						       MDP_BC_SCALE_POINT2_POINT4))
+					{
+						mdp_load_bc_downscale_table_x_point2TOpoint4
+						    ();
+						mdp_curr_down_scale_x =
+						    MDP_BC_SCALE_POINT2_POINT4;
+					}
+				}
+			}
+			/* 0.2 < y <= 1 scaling factor */
+			if ((dst_roi_height_scale <= iBuf->roi.height) &&
+				!mdp_blur) {
+				if (((dst_roi_height_scale * 10) /
+				     iBuf->roi.height) > 8) {
+					if ((use_pr)
+					    && (mdp_curr_down_scale_y !=
+						MDP_PR_SCALE_POINT8_1)) {
+						mdp_load_pr_downscale_table_y_point8TO1
+						    ();
+						mdp_curr_down_scale_y =
+						    MDP_PR_SCALE_POINT8_1;
+					} else if ((!use_pr)
+						   && (mdp_curr_down_scale_y !=
+						       MDP_BC_SCALE_POINT8_1)) {
+						mdp_load_bc_downscale_table_y_point8TO1
+						    ();
+						mdp_curr_down_scale_y =
+						    MDP_BC_SCALE_POINT8_1;
+					}
+				} else
+				    if (((dst_roi_height_scale * 10) /
+					 iBuf->roi.height) > 6) {
+					if ((use_pr)
+					    && (mdp_curr_down_scale_y !=
+						MDP_PR_SCALE_POINT6_POINT8)) {
+						mdp_load_pr_downscale_table_y_point6TOpoint8
+						    ();
+						mdp_curr_down_scale_y =
+						    MDP_PR_SCALE_POINT6_POINT8;
+					} else if ((!use_pr)
+						   && (mdp_curr_down_scale_y !=
+						       MDP_BC_SCALE_POINT6_POINT8))
+					{
+						mdp_load_bc_downscale_table_y_point6TOpoint8
+						    ();
+						mdp_curr_down_scale_y =
+						    MDP_BC_SCALE_POINT6_POINT8;
+					}
+				} else
+				    if (((dst_roi_height_scale * 10) /
+					 iBuf->roi.height) > 4) {
+					if ((use_pr)
+					    && (mdp_curr_down_scale_y !=
+						MDP_PR_SCALE_POINT4_POINT6)) {
+						mdp_load_pr_downscale_table_y_point4TOpoint6
+						    ();
+						mdp_curr_down_scale_y =
+						    MDP_PR_SCALE_POINT4_POINT6;
+					} else if ((!use_pr)
+						   && (mdp_curr_down_scale_y !=
+						       MDP_BC_SCALE_POINT4_POINT6))
+					{
+						mdp_load_bc_downscale_table_y_point4TOpoint6
+						    ();
+						mdp_curr_down_scale_y =
+						    MDP_BC_SCALE_POINT4_POINT6;
+					}
+				} else {
+					if ((use_pr)
+					    && (mdp_curr_down_scale_y !=
+						MDP_PR_SCALE_POINT2_POINT4)) {
+						mdp_load_pr_downscale_table_y_point2TOpoint4
+						    ();
+						mdp_curr_down_scale_y =
+						    MDP_PR_SCALE_POINT2_POINT4;
+					} else if ((!use_pr)
+						   && (mdp_curr_down_scale_y !=
+						       MDP_BC_SCALE_POINT2_POINT4))
+					{
+						mdp_load_bc_downscale_table_y_point2TOpoint4
+						    ();
+						mdp_curr_down_scale_y =
+						    MDP_BC_SCALE_POINT2_POINT4;
+					}
+				}
+			}
+		} else {
+			iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE);
+		}
+	}
+	/* setting edge condition here after scaling check */
+	if (mdp_get_edge_cond(iBuf, &lines_dup, &lines_dup_bg))
+		printk(KERN_ERR "msm_fb: mdp_get_edge_cond() error!\n");
+
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01b8, lines_dup);
+	MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01bc, lines_dup_bg);
+}
+
+void mdp_init_scale_table(void)
+{
+	mdp_curr_up_scale_xy = MDP_INIT_SCALE;
+	mdp_curr_down_scale_x = MDP_INIT_SCALE;
+	mdp_curr_down_scale_y = MDP_INIT_SCALE;
+}
+
+void mdp_adjust_start_addr(uint8 **src0,
+			   uint8 **src1,
+			   int v_slice,
+			   int h_slice,
+			   int x,
+			   int y,
+			   uint32 width,
+			   uint32 height, int bpp, MDPIBUF *iBuf, int layer)
+{
+	*src0 += (x + y * width) * bpp;
+
+	/* if it's dest/bg buffer, we need to adjust it for rotation */
+	if (layer != 0)
+		*src0 = mdp_adjust_rot_addr(iBuf, *src0, 0);
+
+	if (*src1) {
+		/*
+		 * MDP_Y_CBCR_H2V2/MDP_Y_CRCB_H2V2 cosite for now
+		 * we need to shift x direction same as y dir for offsite
+		 */
+		*src1 +=
+		    ((x / h_slice) * h_slice +
+		     ((y == 0) ? 0 : ((y + 1) / v_slice - 1) * width)) * bpp;
+
+		/* if it's dest/bg buffer, we need to adjust it for rotation */
+		if (layer != 0)
+			*src1 = mdp_adjust_rot_addr(iBuf, *src1, 1);
+	}
+}
+
+void mdp_set_blend_attr(MDPIBUF *iBuf,
+			uint32 *alpha,
+			uint32 *tpVal,
+			uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
+{
+	if (mdp_rev == MDP_REV_303) {
+		int bg_alpha;
+
+		*alpha = iBuf->mdpImg.alpha;
+		*tpVal = iBuf->mdpImg.tpVal;
+
+		if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
+			if (perPixelAlpha) {
+				*pppop_reg_ptr |= PPP_OP_ROT_ON |
+						  PPP_OP_BLEND_ON |
+						  PPP_OP_BLEND_CONSTANT_ALPHA;
+			} else {
+				if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+					&& (iBuf->mdpImg.alpha == 0xff)) {
+					iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
+				}
+
+				if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+				   || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
+
+					*pppop_reg_ptr |= PPP_OP_ROT_ON |
+						PPP_OP_BLEND_ON |
+						PPP_OP_BLEND_CONSTANT_ALPHA |
+						PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
+				}
+			}
+
+			bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
+				PPP_BLEND_BG_ALPHA_REVERSE;
+
+			if (perPixelAlpha) {
+				bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
+			} else {
+				bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
+				bg_alpha |= iBuf->mdpImg.alpha << 24;
+			}
+			outpdw(MDP_BASE + 0x70010, bg_alpha);
+
+			if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
+				*pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
+		} else if (perPixelAlpha) {
+				*pppop_reg_ptr |= PPP_OP_ROT_ON |
+						  PPP_OP_BLEND_ON |
+						  PPP_OP_BLEND_SRCPIXEL_ALPHA;
+			} else {
+				if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+					&& (iBuf->mdpImg.alpha == 0xff)) {
+						iBuf->mdpImg.mdpOp &=
+							~(MDPOP_ALPHAB);
+				}
+
+				if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+				   || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
+					*pppop_reg_ptr |= PPP_OP_ROT_ON |
+						PPP_OP_BLEND_ON |
+						PPP_OP_BLEND_CONSTANT_ALPHA |
+						PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
+				}
+
+				if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
+					*pppop_reg_ptr |=
+						PPP_BLEND_CALPHA_TRNASP;
+			}
+	} else {
+		if (perPixelAlpha) {
+			*pppop_reg_ptr |= PPP_OP_ROT_ON |
+			    PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
+		} else {
+			if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+			    && (iBuf->mdpImg.alpha == 0xff)) {
+				iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
+			}
+
+			if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+			    && (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
+				*pppop_reg_ptr |=
+				    PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
+				    PPP_OP_BLEND_CONSTANT_ALPHA |
+				    PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
+				    PPP_BLEND_CALPHA_TRNASP;
+
+				*alpha = iBuf->mdpImg.alpha;
+				*tpVal = iBuf->mdpImg.tpVal;
+			} else {
+				if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) {
+					*pppop_reg_ptr |= PPP_OP_ROT_ON |
+					    PPP_OP_BLEND_ON |
+					    PPP_OP_BLEND_SRCPIXEL_TRANSP;
+					*tpVal = iBuf->mdpImg.tpVal;
+				} else if (iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) {
+					*pppop_reg_ptr |= PPP_OP_ROT_ON |
+					    PPP_OP_BLEND_ON |
+					    PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
+					    PPP_OP_BLEND_CONSTANT_ALPHA;
+					*alpha = iBuf->mdpImg.alpha;
+				}
+			}
+		}
+	}
+}
diff --git a/drivers/video/msm/mdp_ppp_v31.c b/drivers/video/msm/mdp_ppp_v31.c
new file mode 100644
index 0000000..ee6af53
--- /dev/null
+++ b/drivers/video/msm/mdp_ppp_v31.c
@@ -0,0 +1,844 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include "linux/proc_fs.h"
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <asm/div64.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+
+#define MDP_SCALE_COEFF_NUM      32
+#define MDP_SCALE_0P2_TO_0P4_INDEX 0
+#define MDP_SCALE_0P4_TO_0P6_INDEX 32
+#define MDP_SCALE_0P6_TO_0P8_INDEX 64
+#define MDP_SCALE_0P8_TO_8P0_INDEX 96
+#define MDP_SCALE_COEFF_MASK 0x3ff
+
+#define MDP_SCALE_PR  0
+#define MDP_SCALE_FIR 1
+
+static uint32 mdp_scale_0p8_to_8p0_mode;
+static uint32 mdp_scale_0p6_to_0p8_mode;
+static uint32 mdp_scale_0p4_to_0p6_mode;
+static uint32 mdp_scale_0p2_to_0p4_mode;
+
+/* -------- All scaling range, "pixel repeat" -------- */
+static int16 mdp_scale_pixel_repeat_C0[MDP_SCALE_COEFF_NUM] = {
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int16 mdp_scale_pixel_repeat_C1[MDP_SCALE_COEFF_NUM] = {
+	511, 511, 511, 511, 511, 511, 511, 511,
+	511, 511, 511, 511, 511, 511, 511, 511,
+	511, 511, 511, 511, 511, 511, 511, 511,
+	511, 511, 511, 511, 511, 511, 511, 511
+};
+
+static int16 mdp_scale_pixel_repeat_C2[MDP_SCALE_COEFF_NUM] = {
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static int16 mdp_scale_pixel_repeat_C3[MDP_SCALE_COEFF_NUM] = {
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* --------------------------- FIR ------------------------------------- */
+/* -------- Downscale, ranging from 0.8x to 8.0x of original size -------- */
+
+static int16 mdp_scale_0p8_to_8p0_C0[MDP_SCALE_COEFF_NUM] = {
+	0, -7, -13, -19, -24, -28, -32, -34, -37, -39,
+	-40, -41, -41, -41, -40, -40, -38, -37, -35, -33,
+	-31, -29, -26, -24, -21, -18, -15, -13, -10, -7,
+	-5, -2
+};
+
+static int16 mdp_scale_0p8_to_8p0_C1[MDP_SCALE_COEFF_NUM] = {
+	511, 507, 501, 494, 485, 475, 463, 450, 436, 422,
+	405, 388, 370, 352, 333, 314, 293, 274, 253, 233,
+	213, 193, 172, 152, 133, 113, 95, 77, 60, 43,
+	28, 13
+};
+
+static int16 mdp_scale_0p8_to_8p0_C2[MDP_SCALE_COEFF_NUM] = {
+	0, 13, 28, 43, 60, 77, 95, 113, 133, 152,
+	172, 193, 213, 233, 253, 274, 294, 314, 333, 352,
+	370, 388, 405, 422, 436, 450, 463, 475, 485, 494,
+	501, 507,
+};
+
+static int16 mdp_scale_0p8_to_8p0_C3[MDP_SCALE_COEFF_NUM] = {
+	0, -2, -5, -7, -10, -13, -15, -18, -21, -24,
+	-26, -29, -31, -33, -35, -37, -38, -40, -40, -41,
+	-41, -41, -40, -39, -37, -34, -32, -28, -24, -19,
+	-13, -7
+};
+
+/* -------- Downscale, ranging from 0.6x to 0.8x of original size -------- */
+
+static int16 mdp_scale_0p6_to_0p8_C0[MDP_SCALE_COEFF_NUM] = {
+	104, 96, 89, 82, 75, 68, 61, 55, 49, 43,
+	38, 33, 28, 24, 20, 16, 12, 9, 6, 4,
+	2, 0, -2, -4, -5, -6, -7, -7, -8, -8,
+	-8, -8
+};
+
+static int16 mdp_scale_0p6_to_0p8_C1[MDP_SCALE_COEFF_NUM] = {
+	303, 303, 302, 300, 298, 296, 293, 289, 286, 281,
+	276, 270, 265, 258, 252, 245, 238, 230, 223, 214,
+	206, 197, 189, 180, 172, 163, 154, 145, 137, 128,
+	120, 112
+};
+
+static int16 mdp_scale_0p6_to_0p8_C2[MDP_SCALE_COEFF_NUM] = {
+	112, 120, 128, 137, 145, 154, 163, 172, 180, 189,
+	197, 206, 214, 223, 230, 238, 245, 252, 258, 265,
+	270, 276, 281, 286, 289, 293, 296, 298, 300, 302,
+	303, 303
+};
+
+static int16 mdp_scale_0p6_to_0p8_C3[MDP_SCALE_COEFF_NUM] = {
+	-8, -8, -8, -8, -7, -7, -6, -5, -4, -2,
+	0, 2, 4, 6, 9, 12, 16, 20, 24, 28,
+	33, 38, 43, 49, 55, 61, 68, 75, 82, 89,
+	96, 104
+};
+
+/* -------- Downscale, ranging from 0.4x to 0.6x of original size -------- */
+
+static int16 mdp_scale_0p4_to_0p6_C0[MDP_SCALE_COEFF_NUM] = {
+	136, 132, 128, 123, 119, 115, 111, 107, 103, 98,
+	95, 91, 87, 84, 80, 76, 73, 69, 66, 62,
+	59, 57, 54, 50, 47, 44, 41, 39, 36, 33,
+	32, 29
+};
+
+static int16 mdp_scale_0p4_to_0p6_C1[MDP_SCALE_COEFF_NUM] = {
+	206, 205, 204, 204, 201, 200, 199, 197, 196, 194,
+	191, 191, 189, 185, 184, 182, 180, 178, 176, 173,
+	170, 168, 165, 162, 160, 157, 155, 152, 148, 146,
+	142, 140
+};
+
+static int16 mdp_scale_0p4_to_0p6_C2[MDP_SCALE_COEFF_NUM] = {
+	140, 142, 146, 148, 152, 155, 157, 160, 162, 165,
+	168, 170, 173, 176, 178, 180, 182, 184, 185, 189,
+	191, 191, 194, 196, 197, 199, 200, 201, 204, 204,
+	205, 206
+};
+
+static int16 mdp_scale_0p4_to_0p6_C3[MDP_SCALE_COEFF_NUM] = {
+	29, 32, 33, 36, 39, 41, 44, 47, 50, 54,
+	57, 59, 62, 66, 69, 73, 76, 80, 84, 87,
+	91, 95, 98, 103, 107, 111, 115, 119, 123, 128,
+	132, 136
+};
+
+/* -------- Downscale, ranging from 0.2x to 0.4x of original size -------- */
+
+static int16 mdp_scale_0p2_to_0p4_C0[MDP_SCALE_COEFF_NUM] = {
+	131, 131, 130, 129, 128, 127, 127, 126, 125, 125,
+	124, 123, 123, 121, 120, 119, 119, 118, 117, 117,
+	116, 115, 115, 114, 113, 112, 111, 110, 109, 109,
+	108, 107
+};
+
+static int16 mdp_scale_0p2_to_0p4_C1[MDP_SCALE_COEFF_NUM] = {
+	141, 140, 140, 140, 140, 139, 138, 138, 138, 137,
+	137, 137, 136, 137, 137, 137, 136, 136, 136, 135,
+	135, 135, 134, 134, 134, 134, 134, 133, 133, 132,
+	132, 132
+};
+
+static int16 mdp_scale_0p2_to_0p4_C2[MDP_SCALE_COEFF_NUM] = {
+	132, 132, 132, 133, 133, 134, 134, 134, 134, 134,
+	135, 135, 135, 136, 136, 136, 137, 137, 137, 136,
+	137, 137, 137, 138, 138, 138, 139, 140, 140, 140,
+	140, 141
+};
+
+static int16 mdp_scale_0p2_to_0p4_C3[MDP_SCALE_COEFF_NUM] = {
+	107, 108, 109, 109, 110, 111, 112, 113, 114, 115,
+	115, 116, 117, 117, 118, 119, 119, 120, 121, 123,
+	123, 124, 125, 125, 126, 127, 127, 128, 129, 130,
+	131, 131
+};
+
+static void mdp_update_scale_table(int index, int16 *c0, int16 *c1,
+				   int16 *c2, int16 *c3)
+{
+	int i, val;
+
+	for (i = 0; i < MDP_SCALE_COEFF_NUM; i++) {
+		val =
+		    ((MDP_SCALE_COEFF_MASK & c1[i]) << 16) |
+		    (MDP_SCALE_COEFF_MASK & c0[i]);
+		writel(val, MDP_PPP_SCALE_COEFF_LSBn(index));
+		val =
+		    ((MDP_SCALE_COEFF_MASK & c3[i]) << 16) |
+		    (MDP_SCALE_COEFF_MASK & c2[i]);
+		writel(val, MDP_PPP_SCALE_COEFF_MSBn(index));
+		index++;
+	}
+}
+
+void mdp_init_scale_table(void)
+{
+	mdp_scale_0p2_to_0p4_mode = MDP_SCALE_FIR;
+	mdp_update_scale_table(MDP_SCALE_0P2_TO_0P4_INDEX,
+			       mdp_scale_0p2_to_0p4_C0,
+			       mdp_scale_0p2_to_0p4_C1,
+			       mdp_scale_0p2_to_0p4_C2,
+			       mdp_scale_0p2_to_0p4_C3);
+
+	mdp_scale_0p4_to_0p6_mode = MDP_SCALE_FIR;
+	mdp_update_scale_table(MDP_SCALE_0P4_TO_0P6_INDEX,
+			       mdp_scale_0p4_to_0p6_C0,
+			       mdp_scale_0p4_to_0p6_C1,
+			       mdp_scale_0p4_to_0p6_C2,
+			       mdp_scale_0p4_to_0p6_C3);
+
+	mdp_scale_0p6_to_0p8_mode = MDP_SCALE_FIR;
+	mdp_update_scale_table(MDP_SCALE_0P6_TO_0P8_INDEX,
+			       mdp_scale_0p6_to_0p8_C0,
+			       mdp_scale_0p6_to_0p8_C1,
+			       mdp_scale_0p6_to_0p8_C2,
+			       mdp_scale_0p6_to_0p8_C3);
+
+	mdp_scale_0p8_to_8p0_mode = MDP_SCALE_FIR;
+	mdp_update_scale_table(MDP_SCALE_0P8_TO_8P0_INDEX,
+			       mdp_scale_0p8_to_8p0_C0,
+			       mdp_scale_0p8_to_8p0_C1,
+			       mdp_scale_0p8_to_8p0_C2,
+			       mdp_scale_0p8_to_8p0_C3);
+}
+
+static long long mdp_do_div(long long num, long long den)
+{
+	do_div(num, den);
+	return num;
+}
+
+#define SCALER_PHASE_BITS 29
+#define HAL_MDP_PHASE_STEP_2P50    0x50000000
+#define HAL_MDP_PHASE_STEP_1P66    0x35555555
+#define HAL_MDP_PHASE_STEP_1P25    0x28000000
+
+struct phase_val {
+	int phase_init_x;
+	int phase_init_y;
+	int phase_step_x;
+	int phase_step_y;
+};
+
+static void mdp_calc_scaleInitPhase_3p1(uint32 in_w,
+					uint32 in_h,
+					uint32 out_w,
+					uint32 out_h,
+					boolean is_rotate,
+					boolean is_pp_x,
+					boolean is_pp_y, struct phase_val *pval)
+{
+	uint64 dst_ROI_width;
+	uint64 dst_ROI_height;
+	uint64 src_ROI_width;
+	uint64 src_ROI_height;
+
+	/*
+	 * phase_step_x, phase_step_y, phase_init_x and phase_init_y
+	 * are represented in fixed-point, unsigned 3.29 format
+	 */
+	uint32 phase_step_x = 0;
+	uint32 phase_step_y = 0;
+	uint32 phase_init_x = 0;
+	uint32 phase_init_y = 0;
+	uint32 yscale_filter_sel, xscale_filter_sel;
+	uint32 scale_unit_sel_x, scale_unit_sel_y;
+
+	uint64 numerator, denominator;
+	uint64 temp_dim;
+
+	src_ROI_width = in_w;
+	src_ROI_height = in_h;
+	dst_ROI_width = out_w;
+	dst_ROI_height = out_h;
+
+	/* if there is a 90 degree rotation */
+	if (is_rotate) {
+		/* decide whether to use FIR or M/N for scaling */
+
+		/* if down-scaling by a factor smaller than 1/4 */
+		if ((dst_ROI_height == 1 && src_ROI_width < 4) ||
+			(src_ROI_width < 4 * dst_ROI_height - 3))
+			scale_unit_sel_x = 0;/* use FIR scalar */
+		else
+			scale_unit_sel_x = 1;/* use M/N scalar */
+
+		/* if down-scaling by a factor smaller than 1/4 */
+		if ((dst_ROI_width == 1 && src_ROI_height < 4) ||
+			(src_ROI_height < 4 * dst_ROI_width - 3))
+			scale_unit_sel_y = 0;/* use FIR scalar */
+		else
+			scale_unit_sel_y = 1;/* use M/N scalar */
+	} else {
+		/* decide whether to use FIR or M/N for scaling */
+		if ((dst_ROI_width == 1 && src_ROI_width < 4) ||
+			(src_ROI_width < 4 * dst_ROI_width - 3))
+			scale_unit_sel_x = 0;/* use FIR scalar */
+		else
+			scale_unit_sel_x = 1;/* use M/N scalar */
+
+		if ((dst_ROI_height == 1 && src_ROI_height < 4) ||
+			(src_ROI_height < 4 * dst_ROI_height - 3))
+			scale_unit_sel_y = 0;/* use FIR scalar */
+		else
+			scale_unit_sel_y = 1;/* use M/N scalar */
+	}
+
+	/* if there is a 90 degree rotation */
+	if (is_rotate) {
+		/* swap the width and height of dst ROI */
+		temp_dim = dst_ROI_width;
+		dst_ROI_width = dst_ROI_height;
+		dst_ROI_height = temp_dim;
+	}
+
+	/* calculate phase step for the x direction */
+
+	/* if destination is only 1 pixel wide, the value of phase_step_x
+	   is unimportant. Assigning phase_step_x to src ROI width
+	   as an arbitrary value. */
+	if (dst_ROI_width == 1)
+		phase_step_x = (uint32) ((src_ROI_width) << SCALER_PHASE_BITS);
+
+	/* if using FIR scalar */
+	else if (scale_unit_sel_x == 0) {
+
+		/* Calculate the quotient ( src_ROI_width - 1 ) / ( dst_ROI_width - 1)
+		   with u3.29 precision. Quotient is rounded up to the larger
+		   29th decimal point. */
+		numerator = (src_ROI_width - 1) << SCALER_PHASE_BITS;
+		denominator = (dst_ROI_width - 1);	/* never equals to 0 because of the "( dst_ROI_width == 1 ) case" */
+		phase_step_x = (uint32) mdp_do_div((numerator + denominator - 1), denominator);	/* divide and round up to the larger 29th decimal point. */
+
+	}
+
+	/* if M/N scalar */
+	else if (scale_unit_sel_x == 1) {
+		/* Calculate the quotient ( src_ROI_width ) / ( dst_ROI_width)
+		   with u3.29 precision. Quotient is rounded down to the
+		   smaller 29th decimal point. */
+		numerator = (src_ROI_width) << SCALER_PHASE_BITS;
+		denominator = (dst_ROI_width);
+		phase_step_x = (uint32) mdp_do_div(numerator, denominator);
+	}
+	/* calculate phase step for the y direction */
+
+	/* if destination is only 1 pixel wide, the value of
+	   phase_step_x is unimportant. Assigning phase_step_x
+	   to src ROI width as an arbitrary value. */
+	if (dst_ROI_height == 1)
+		phase_step_y = (uint32) ((src_ROI_height) << SCALER_PHASE_BITS);
+
+	/* if FIR scalar */
+	else if (scale_unit_sel_y == 0) {
+		/* Calculate the quotient ( src_ROI_height - 1 ) / ( dst_ROI_height - 1)
+		   with u3.29 precision. Quotient is rounded up to the larger
+		   29th decimal point. */
+		numerator = (src_ROI_height - 1) << SCALER_PHASE_BITS;
+		denominator = (dst_ROI_height - 1);	/* never equals to 0 because of the "( dst_ROI_height == 1 )" case */
+		phase_step_y = (uint32) mdp_do_div((numerator + denominator - 1), denominator);	/* Quotient is rounded up to the larger 29th decimal point. */
+
+	}
+
+	/* if M/N scalar */
+	else if (scale_unit_sel_y == 1) {
+		/* Calculate the quotient ( src_ROI_height ) / ( dst_ROI_height)
+		   with u3.29 precision. Quotient is rounded down to the smaller
+		   29th decimal point. */
+		numerator = (src_ROI_height) << SCALER_PHASE_BITS;
+		denominator = (dst_ROI_height);
+		phase_step_y = (uint32) mdp_do_div(numerator, denominator);
+	}
+
+	/* decide which set of FIR coefficients to use */
+	if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
+		xscale_filter_sel = 0;
+	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
+		xscale_filter_sel = 1;
+	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
+		xscale_filter_sel = 2;
+	else
+		xscale_filter_sel = 3;
+
+	if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
+		yscale_filter_sel = 0;
+	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
+		yscale_filter_sel = 1;
+	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
+		yscale_filter_sel = 2;
+	else
+		yscale_filter_sel = 3;
+
+	/* calculate phase init for the x direction */
+
+	/* if using FIR scalar */
+	if (scale_unit_sel_x == 0) {
+		if (dst_ROI_width == 1)
+			phase_init_x =
+			    (uint32) ((src_ROI_width - 1) << SCALER_PHASE_BITS);
+		else
+			phase_init_x = 0;
+
+	}
+	/* M over N scalar  */
+	else if (scale_unit_sel_x == 1)
+		phase_init_x = 0;
+
+	/* calculate phase init for the y direction
+	   if using FIR scalar */
+	if (scale_unit_sel_y == 0) {
+		if (dst_ROI_height == 1)
+			phase_init_y =
+			    (uint32) ((src_ROI_height -
+				       1) << SCALER_PHASE_BITS);
+		else
+			phase_init_y = 0;
+
+	}
+	/* M over N scalar   */
+	else if (scale_unit_sel_y == 1)
+		phase_init_y = 0;
+
+	/* write registers */
+	pval->phase_step_x = (uint32) phase_step_x;
+	pval->phase_step_y = (uint32) phase_step_y;
+	pval->phase_init_x = (uint32) phase_init_x;
+	pval->phase_init_y = (uint32) phase_init_y;
+
+	return;
+}
+
+void mdp_set_scale(MDPIBUF *iBuf,
+		   uint32 dst_roi_width,
+		   uint32 dst_roi_height,
+		   boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr)
+{
+	uint32 dst_roi_width_scale;
+	uint32 dst_roi_height_scale;
+	struct phase_val pval;
+	boolean use_pr;
+	uint32 ppp_scale_config = 0;
+
+	if (!inputRGB)
+		ppp_scale_config |= BIT(6);
+
+	if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {
+		if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
+			dst_roi_width_scale = dst_roi_height;
+			dst_roi_height_scale = dst_roi_width;
+		} else {
+			dst_roi_width_scale = dst_roi_width;
+			dst_roi_height_scale = dst_roi_height;
+		}
+
+		if ((dst_roi_width_scale != iBuf->roi.width) ||
+		    (dst_roi_height_scale != iBuf->roi.height) ||
+			(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
+			*pppop_reg_ptr |=
+			    (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
+
+			mdp_calc_scaleInitPhase_3p1(iBuf->roi.width,
+						    iBuf->roi.height,
+						    dst_roi_width,
+						    dst_roi_height,
+						    iBuf->mdpImg.
+						    mdpOp & MDPOP_ROT90, 1, 1,
+						    &pval);
+
+			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
+				 pval.phase_init_x);
+			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
+				 pval.phase_init_y);
+			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144,
+				 pval.phase_step_x);
+			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148,
+				 pval.phase_step_y);
+
+			/* disable the pixel repeat option for scaling */
+			use_pr = false;
+
+			/* x-direction */
+			if ((dst_roi_width_scale == iBuf->roi.width) &&
+				!(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
+				*pppop_reg_ptr &= ~PPP_OP_SCALE_X_ON;
+			} else
+			    if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
+				8) {
+				if ((use_pr)
+				    && (mdp_scale_0p8_to_8p0_mode !=
+					MDP_SCALE_PR)) {
+					mdp_scale_0p8_to_8p0_mode =
+					    MDP_SCALE_PR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P8_TO_8P0_INDEX,
+					     mdp_scale_pixel_repeat_C0,
+					     mdp_scale_pixel_repeat_C1,
+					     mdp_scale_pixel_repeat_C2,
+					     mdp_scale_pixel_repeat_C3);
+				} else if ((!use_pr)
+					   && (mdp_scale_0p8_to_8p0_mode !=
+					       MDP_SCALE_FIR)) {
+					mdp_scale_0p8_to_8p0_mode =
+					    MDP_SCALE_FIR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P8_TO_8P0_INDEX,
+					     mdp_scale_0p8_to_8p0_C0,
+					     mdp_scale_0p8_to_8p0_C1,
+					     mdp_scale_0p8_to_8p0_C2,
+					     mdp_scale_0p8_to_8p0_C3);
+				}
+				ppp_scale_config |= (SCALE_U1_SET << 2);
+			} else
+			    if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
+				6) {
+				if ((use_pr)
+				    && (mdp_scale_0p6_to_0p8_mode !=
+					MDP_SCALE_PR)) {
+					mdp_scale_0p6_to_0p8_mode =
+					    MDP_SCALE_PR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P6_TO_0P8_INDEX,
+					     mdp_scale_pixel_repeat_C0,
+					     mdp_scale_pixel_repeat_C1,
+					     mdp_scale_pixel_repeat_C2,
+					     mdp_scale_pixel_repeat_C3);
+				} else if ((!use_pr)
+					   && (mdp_scale_0p6_to_0p8_mode !=
+					       MDP_SCALE_FIR)) {
+					mdp_scale_0p6_to_0p8_mode =
+					    MDP_SCALE_FIR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P6_TO_0P8_INDEX,
+					     mdp_scale_0p6_to_0p8_C0,
+					     mdp_scale_0p6_to_0p8_C1,
+					     mdp_scale_0p6_to_0p8_C2,
+					     mdp_scale_0p6_to_0p8_C3);
+				}
+				ppp_scale_config |= (SCALE_D2_SET << 2);
+			} else
+			    if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
+				4) {
+				if ((use_pr)
+				    && (mdp_scale_0p4_to_0p6_mode !=
+					MDP_SCALE_PR)) {
+					mdp_scale_0p4_to_0p6_mode =
+					    MDP_SCALE_PR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P4_TO_0P6_INDEX,
+					     mdp_scale_pixel_repeat_C0,
+					     mdp_scale_pixel_repeat_C1,
+					     mdp_scale_pixel_repeat_C2,
+					     mdp_scale_pixel_repeat_C3);
+				} else if ((!use_pr)
+					   && (mdp_scale_0p4_to_0p6_mode !=
+					       MDP_SCALE_FIR)) {
+					mdp_scale_0p4_to_0p6_mode =
+					    MDP_SCALE_FIR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P4_TO_0P6_INDEX,
+					     mdp_scale_0p4_to_0p6_C0,
+					     mdp_scale_0p4_to_0p6_C1,
+					     mdp_scale_0p4_to_0p6_C2,
+					     mdp_scale_0p4_to_0p6_C3);
+				}
+				ppp_scale_config |= (SCALE_D1_SET << 2);
+			} else
+			if ((dst_roi_width_scale == 1 && iBuf->roi.width < 4) ||
+			(iBuf->roi.width < 4 * dst_roi_width_scale - 3)) {
+				if ((use_pr)
+				    && (mdp_scale_0p2_to_0p4_mode !=
+					MDP_SCALE_PR)) {
+					mdp_scale_0p2_to_0p4_mode =
+					    MDP_SCALE_PR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P2_TO_0P4_INDEX,
+					     mdp_scale_pixel_repeat_C0,
+					     mdp_scale_pixel_repeat_C1,
+					     mdp_scale_pixel_repeat_C2,
+					     mdp_scale_pixel_repeat_C3);
+				} else if ((!use_pr)
+					   && (mdp_scale_0p2_to_0p4_mode !=
+					       MDP_SCALE_FIR)) {
+					mdp_scale_0p2_to_0p4_mode =
+					    MDP_SCALE_FIR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P2_TO_0P4_INDEX,
+					     mdp_scale_0p2_to_0p4_C0,
+					     mdp_scale_0p2_to_0p4_C1,
+					     mdp_scale_0p2_to_0p4_C2,
+					     mdp_scale_0p2_to_0p4_C3);
+				}
+				ppp_scale_config |= (SCALE_D0_SET << 2);
+			} else
+				ppp_scale_config |= BIT(0);
+
+			/* y-direction */
+			if ((dst_roi_height_scale == iBuf->roi.height) &&
+				!(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
+				*pppop_reg_ptr &= ~PPP_OP_SCALE_Y_ON;
+			} else if (((dst_roi_height_scale * 10) /
+					iBuf->roi.height) > 8) {
+				if ((use_pr)
+				    && (mdp_scale_0p8_to_8p0_mode !=
+					MDP_SCALE_PR)) {
+					mdp_scale_0p8_to_8p0_mode =
+					    MDP_SCALE_PR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P8_TO_8P0_INDEX,
+					     mdp_scale_pixel_repeat_C0,
+					     mdp_scale_pixel_repeat_C1,
+					     mdp_scale_pixel_repeat_C2,
+					     mdp_scale_pixel_repeat_C3);
+				} else if ((!use_pr)
+					   && (mdp_scale_0p8_to_8p0_mode !=
+					       MDP_SCALE_FIR)) {
+					mdp_scale_0p8_to_8p0_mode =
+					    MDP_SCALE_FIR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P8_TO_8P0_INDEX,
+					     mdp_scale_0p8_to_8p0_C0,
+					     mdp_scale_0p8_to_8p0_C1,
+					     mdp_scale_0p8_to_8p0_C2,
+					     mdp_scale_0p8_to_8p0_C3);
+				}
+				ppp_scale_config |= (SCALE_U1_SET << 4);
+			} else
+			    if (((dst_roi_height_scale * 10) /
+				 iBuf->roi.height) > 6) {
+				if ((use_pr)
+				    && (mdp_scale_0p6_to_0p8_mode !=
+					MDP_SCALE_PR)) {
+					mdp_scale_0p6_to_0p8_mode =
+					    MDP_SCALE_PR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P6_TO_0P8_INDEX,
+					     mdp_scale_pixel_repeat_C0,
+					     mdp_scale_pixel_repeat_C1,
+					     mdp_scale_pixel_repeat_C2,
+					     mdp_scale_pixel_repeat_C3);
+				} else if ((!use_pr)
+					   && (mdp_scale_0p6_to_0p8_mode !=
+					       MDP_SCALE_FIR)) {
+					mdp_scale_0p6_to_0p8_mode =
+					    MDP_SCALE_FIR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P6_TO_0P8_INDEX,
+					     mdp_scale_0p6_to_0p8_C0,
+					     mdp_scale_0p6_to_0p8_C1,
+					     mdp_scale_0p6_to_0p8_C2,
+					     mdp_scale_0p6_to_0p8_C3);
+				}
+				ppp_scale_config |= (SCALE_D2_SET << 4);
+			} else
+			    if (((dst_roi_height_scale * 10) /
+				 iBuf->roi.height) > 4) {
+				if ((use_pr)
+				    && (mdp_scale_0p4_to_0p6_mode !=
+					MDP_SCALE_PR)) {
+					mdp_scale_0p4_to_0p6_mode =
+					    MDP_SCALE_PR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P4_TO_0P6_INDEX,
+					     mdp_scale_pixel_repeat_C0,
+					     mdp_scale_pixel_repeat_C1,
+					     mdp_scale_pixel_repeat_C2,
+					     mdp_scale_pixel_repeat_C3);
+				} else if ((!use_pr)
+					   && (mdp_scale_0p4_to_0p6_mode !=
+					       MDP_SCALE_FIR)) {
+					mdp_scale_0p4_to_0p6_mode =
+					    MDP_SCALE_FIR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P4_TO_0P6_INDEX,
+					     mdp_scale_0p4_to_0p6_C0,
+					     mdp_scale_0p4_to_0p6_C1,
+					     mdp_scale_0p4_to_0p6_C2,
+					     mdp_scale_0p4_to_0p6_C3);
+				}
+				ppp_scale_config |= (SCALE_D1_SET << 4);
+			} else if ((dst_roi_height_scale == 1 &&
+			iBuf->roi.height < 4) ||
+			(iBuf->roi.height < 4 * dst_roi_height_scale - 3)) {
+				if ((use_pr)
+				    && (mdp_scale_0p2_to_0p4_mode !=
+					MDP_SCALE_PR)) {
+					mdp_scale_0p2_to_0p4_mode =
+					    MDP_SCALE_PR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P2_TO_0P4_INDEX,
+					     mdp_scale_pixel_repeat_C0,
+					     mdp_scale_pixel_repeat_C1,
+					     mdp_scale_pixel_repeat_C2,
+					     mdp_scale_pixel_repeat_C3);
+				} else if ((!use_pr)
+					   && (mdp_scale_0p2_to_0p4_mode !=
+					       MDP_SCALE_FIR)) {
+					mdp_scale_0p2_to_0p4_mode =
+					    MDP_SCALE_FIR;
+					mdp_update_scale_table
+					    (MDP_SCALE_0P2_TO_0P4_INDEX,
+					     mdp_scale_0p2_to_0p4_C0,
+					     mdp_scale_0p2_to_0p4_C1,
+					     mdp_scale_0p2_to_0p4_C2,
+					     mdp_scale_0p2_to_0p4_C3);
+				}
+				ppp_scale_config |= (SCALE_D0_SET << 4);
+			} else
+				ppp_scale_config |= BIT(1);
+
+			if (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING) {
+				ppp_scale_config |= BIT(7);
+				MDP_OUTP(MDP_BASE + 0x50020,
+						iBuf->mdpImg.sp_value);
+			}
+
+			MDP_OUTP(MDP_BASE + 0x10230, ppp_scale_config);
+		} else {
+			iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE);
+		}
+	}
+}
+
+void mdp_adjust_start_addr(uint8 **src0,
+			   uint8 **src1,
+			   int v_slice,
+			   int h_slice,
+			   int x,
+			   int y,
+			   uint32 width,
+			   uint32 height, int bpp, MDPIBUF *iBuf, int layer)
+{
+	switch (layer) {
+	case 0:
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0200, (y << 16) | (x));
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0208,
+			 (height << 16) | (width));
+		break;
+
+	case 1:
+		/* MDP 3.1 HW bug workaround */
+		if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
+			*src0 += (x + y * width) * bpp;
+			x = y = 0;
+			width = iBuf->roi.dst_width;
+			height = iBuf->roi.dst_height;
+		}
+
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0204, (y << 16) | (x));
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x020c,
+			 (height << 16) | (width));
+		break;
+
+	case 2:
+		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x019c, (y << 16) | (x));
+		break;
+	}
+}
+
+void mdp_set_blend_attr(MDPIBUF *iBuf,
+			uint32 *alpha,
+			uint32 *tpVal,
+			uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
+{
+	int bg_alpha;
+
+	*alpha = iBuf->mdpImg.alpha;
+	*tpVal = iBuf->mdpImg.tpVal;
+
+	if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
+		if (perPixelAlpha) {
+			*pppop_reg_ptr |= PPP_OP_ROT_ON |
+			PPP_OP_BLEND_ON | PPP_OP_BLEND_CONSTANT_ALPHA;
+			}
+		else {
+			if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+				&& (iBuf->mdpImg.alpha == 0xff)) {
+					iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
+				}
+
+			if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+				|| (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
+				*pppop_reg_ptr |=
+				PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
+				PPP_OP_BLEND_CONSTANT_ALPHA |
+				PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
+			}
+		}
+
+		bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
+				PPP_BLEND_BG_ALPHA_REVERSE;
+
+		if (perPixelAlpha)
+			bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
+		else {
+			bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
+			bg_alpha |= iBuf->mdpImg.alpha << 24;
+			}
+		outpdw(MDP_BASE + 0x70010, bg_alpha);
+
+		if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
+			*pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
+	} else if (perPixelAlpha) {
+		*pppop_reg_ptr |= PPP_OP_ROT_ON |
+		    PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
+	} else {
+		if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+		    && (iBuf->mdpImg.alpha == 0xff)) {
+			iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
+		}
+
+		if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
+		    || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
+			*pppop_reg_ptr |=
+			    PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
+			    PPP_OP_BLEND_CONSTANT_ALPHA |
+			    PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
+		}
+
+		if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
+			*pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
+	}
+}
diff --git a/drivers/video/msm/mdp_scale_tables.c b/drivers/video/msm/mdp_scale_tables.c
new file mode 100644
index 0000000..604783b
--- /dev/null
+++ b/drivers/video/msm/mdp_scale_tables.c
@@ -0,0 +1,766 @@
+/* drivers/video/msm_fb/mdp_scale_tables.c
+ *
+ * Copyright (C) 2007 QUALCOMM Incorporated
+ * Copyright (C) 2007 Google Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "mdp_scale_tables.h"
+#include "mdp_hw.h"
+
+struct mdp_table_entry mdp_upscale_table[] = {
+	{ 0x5fffc, 0x0 },
+	{ 0x50200, 0x7fc00000 },
+	{ 0x5fffc, 0xff80000d },
+	{ 0x50204, 0x7ec003f9 },
+	{ 0x5fffc, 0xfec0001c },
+	{ 0x50208, 0x7d4003f3 },
+	{ 0x5fffc, 0xfe40002b },
+	{ 0x5020c, 0x7b8003ed },
+	{ 0x5fffc, 0xfd80003c },
+	{ 0x50210, 0x794003e8 },
+	{ 0x5fffc, 0xfcc0004d },
+	{ 0x50214, 0x76c003e4 },
+	{ 0x5fffc, 0xfc40005f },
+	{ 0x50218, 0x73c003e0 },
+	{ 0x5fffc, 0xfb800071 },
+	{ 0x5021c, 0x708003de },
+	{ 0x5fffc, 0xfac00085 },
+	{ 0x50220, 0x6d0003db },
+	{ 0x5fffc, 0xfa000098 },
+	{ 0x50224, 0x698003d9 },
+	{ 0x5fffc, 0xf98000ac },
+	{ 0x50228, 0x654003d8 },
+	{ 0x5fffc, 0xf8c000c1 },
+	{ 0x5022c, 0x610003d7 },
+	{ 0x5fffc, 0xf84000d5 },
+	{ 0x50230, 0x5c8003d7 },
+	{ 0x5fffc, 0xf7c000e9 },
+	{ 0x50234, 0x580003d7 },
+	{ 0x5fffc, 0xf74000fd },
+	{ 0x50238, 0x534003d8 },
+	{ 0x5fffc, 0xf6c00112 },
+	{ 0x5023c, 0x4e8003d8 },
+	{ 0x5fffc, 0xf6800126 },
+	{ 0x50240, 0x494003da },
+	{ 0x5fffc, 0xf600013a },
+	{ 0x50244, 0x448003db },
+	{ 0x5fffc, 0xf600014d },
+	{ 0x50248, 0x3f4003dd },
+	{ 0x5fffc, 0xf5c00160 },
+	{ 0x5024c, 0x3a4003df },
+	{ 0x5fffc, 0xf5c00172 },
+	{ 0x50250, 0x354003e1 },
+	{ 0x5fffc, 0xf5c00184 },
+	{ 0x50254, 0x304003e3 },
+	{ 0x5fffc, 0xf6000195 },
+	{ 0x50258, 0x2b0003e6 },
+	{ 0x5fffc, 0xf64001a6 },
+	{ 0x5025c, 0x260003e8 },
+	{ 0x5fffc, 0xf6c001b4 },
+	{ 0x50260, 0x214003eb },
+	{ 0x5fffc, 0xf78001c2 },
+	{ 0x50264, 0x1c4003ee },
+	{ 0x5fffc, 0xf80001cf },
+	{ 0x50268, 0x17c003f1 },
+	{ 0x5fffc, 0xf90001db },
+	{ 0x5026c, 0x134003f3 },
+	{ 0x5fffc, 0xfa0001e5 },
+	{ 0x50270, 0xf0003f6 },
+	{ 0x5fffc, 0xfb4001ee },
+	{ 0x50274, 0xac003f9 },
+	{ 0x5fffc, 0xfcc001f5 },
+	{ 0x50278, 0x70003fb },
+	{ 0x5fffc, 0xfe4001fb },
+	{ 0x5027c, 0x34003fe },
+};
+
+static struct mdp_table_entry mdp_downscale_x_table_PT2TOPT4[] = {
+	{ 0x5fffc, 0x740008c },
+	{ 0x50280, 0x33800088 },
+	{ 0x5fffc, 0x800008e },
+	{ 0x50284, 0x33400084 },
+	{ 0x5fffc, 0x8400092 },
+	{ 0x50288, 0x33000080 },
+	{ 0x5fffc, 0x9000094 },
+	{ 0x5028c, 0x3300007b },
+	{ 0x5fffc, 0x9c00098 },
+	{ 0x50290, 0x32400077 },
+	{ 0x5fffc, 0xa40009b },
+	{ 0x50294, 0x32000073 },
+	{ 0x5fffc, 0xb00009d },
+	{ 0x50298,  0x31c0006f },
+	{ 0x5fffc,  0xbc000a0 },
+	{ 0x5029c,  0x3140006b },
+	{ 0x5fffc,  0xc8000a2 },
+	{ 0x502a0,  0x31000067 },
+	{ 0x5fffc,  0xd8000a5 },
+	{ 0x502a4,  0x30800062 },
+	{ 0x5fffc,  0xe4000a8 },
+	{ 0x502a8,  0x2fc0005f },
+	{ 0x5fffc,  0xec000aa },
+	{ 0x502ac,  0x2fc0005b },
+	{ 0x5fffc,  0xf8000ad },
+	{ 0x502b0,  0x2f400057 },
+	{ 0x5fffc,  0x108000b0 },
+	{ 0x502b4,  0x2e400054 },
+	{ 0x5fffc,  0x114000b2 },
+	{ 0x502b8,  0x2e000050 },
+	{ 0x5fffc,  0x124000b4 },
+	{ 0x502bc,  0x2d80004c },
+	{ 0x5fffc,  0x130000b6 },
+	{ 0x502c0,  0x2d000049 },
+	{ 0x5fffc,  0x140000b8 },
+	{ 0x502c4,  0x2c800045 },
+	{ 0x5fffc,  0x150000b9 },
+	{ 0x502c8,  0x2c000042 },
+	{ 0x5fffc,  0x15c000bd },
+	{ 0x502cc,  0x2b40003e },
+	{ 0x5fffc,  0x16c000bf },
+	{ 0x502d0,  0x2a80003b },
+	{ 0x5fffc,  0x17c000bf },
+	{ 0x502d4,  0x2a000039 },
+	{ 0x5fffc,  0x188000c2 },
+	{ 0x502d8,  0x29400036 },
+	{ 0x5fffc,  0x19c000c4 },
+	{ 0x502dc,  0x28800032 },
+	{ 0x5fffc,  0x1ac000c5 },
+	{ 0x502e0,  0x2800002f },
+	{ 0x5fffc,  0x1bc000c7 },
+	{ 0x502e4,  0x2740002c },
+	{ 0x5fffc,  0x1cc000c8 },
+	{ 0x502e8,  0x26c00029 },
+	{ 0x5fffc,  0x1dc000c9 },
+	{ 0x502ec,  0x26000027 },
+	{ 0x5fffc,  0x1ec000cc },
+	{ 0x502f0,  0x25000024 },
+	{ 0x5fffc,  0x200000cc },
+	{ 0x502f4,  0x24800021 },
+	{ 0x5fffc,  0x210000cd },
+	{ 0x502f8,  0x23800020 },
+	{ 0x5fffc,  0x220000ce },
+	{ 0x502fc,  0x2300001d },
+};
+
+static struct mdp_table_entry mdp_downscale_x_table_PT4TOPT6[] = {
+	{ 0x5fffc,  0x740008c },
+	{ 0x50280,  0x33800088 },
+	{ 0x5fffc,  0x800008e },
+	{ 0x50284,  0x33400084 },
+	{ 0x5fffc,  0x8400092 },
+	{ 0x50288,  0x33000080 },
+	{ 0x5fffc,  0x9000094 },
+	{ 0x5028c,  0x3300007b },
+	{ 0x5fffc,  0x9c00098 },
+	{ 0x50290,  0x32400077 },
+	{ 0x5fffc,  0xa40009b },
+	{ 0x50294,  0x32000073 },
+	{ 0x5fffc,  0xb00009d },
+	{ 0x50298,  0x31c0006f },
+	{ 0x5fffc,  0xbc000a0 },
+	{ 0x5029c,  0x3140006b },
+	{ 0x5fffc,  0xc8000a2 },
+	{ 0x502a0,  0x31000067 },
+	{ 0x5fffc,  0xd8000a5 },
+	{ 0x502a4,  0x30800062 },
+	{ 0x5fffc,  0xe4000a8 },
+	{ 0x502a8,  0x2fc0005f },
+	{ 0x5fffc,  0xec000aa },
+	{ 0x502ac,  0x2fc0005b },
+	{ 0x5fffc,  0xf8000ad },
+	{ 0x502b0,  0x2f400057 },
+	{ 0x5fffc,  0x108000b0 },
+	{ 0x502b4,  0x2e400054 },
+	{ 0x5fffc,  0x114000b2 },
+	{ 0x502b8,  0x2e000050 },
+	{ 0x5fffc,  0x124000b4 },
+	{ 0x502bc,  0x2d80004c },
+	{ 0x5fffc,  0x130000b6 },
+	{ 0x502c0,  0x2d000049 },
+	{ 0x5fffc,  0x140000b8 },
+	{ 0x502c4,  0x2c800045 },
+	{ 0x5fffc,  0x150000b9 },
+	{ 0x502c8,  0x2c000042 },
+	{ 0x5fffc,  0x15c000bd },
+	{ 0x502cc,  0x2b40003e },
+	{ 0x5fffc,  0x16c000bf },
+	{ 0x502d0,  0x2a80003b },
+	{ 0x5fffc,  0x17c000bf },
+	{ 0x502d4,  0x2a000039 },
+	{ 0x5fffc,  0x188000c2 },
+	{ 0x502d8,  0x29400036 },
+	{ 0x5fffc,  0x19c000c4 },
+	{ 0x502dc,  0x28800032 },
+	{ 0x5fffc,  0x1ac000c5 },
+	{ 0x502e0,  0x2800002f },
+	{ 0x5fffc,  0x1bc000c7 },
+	{ 0x502e4,  0x2740002c },
+	{ 0x5fffc,  0x1cc000c8 },
+	{ 0x502e8,  0x26c00029 },
+	{ 0x5fffc,  0x1dc000c9 },
+	{ 0x502ec,  0x26000027 },
+	{ 0x5fffc,  0x1ec000cc },
+	{ 0x502f0,  0x25000024 },
+	{ 0x5fffc,  0x200000cc },
+	{ 0x502f4,  0x24800021 },
+	{ 0x5fffc,  0x210000cd },
+	{ 0x502f8,  0x23800020 },
+	{ 0x5fffc,  0x220000ce },
+	{ 0x502fc,  0x2300001d },
+};
+
+static struct mdp_table_entry mdp_downscale_x_table_PT6TOPT8[] = {
+	{ 0x5fffc,  0xfe000070 },
+	{ 0x50280,  0x4bc00068 },
+	{ 0x5fffc,  0xfe000078 },
+	{ 0x50284,  0x4bc00060 },
+	{ 0x5fffc,  0xfe000080 },
+	{ 0x50288,  0x4b800059 },
+	{ 0x5fffc,  0xfe000089 },
+	{ 0x5028c,  0x4b000052 },
+	{ 0x5fffc,  0xfe400091 },
+	{ 0x50290,  0x4a80004b },
+	{ 0x5fffc,  0xfe40009a },
+	{ 0x50294,  0x4a000044 },
+	{ 0x5fffc,  0xfe8000a3 },
+	{ 0x50298,  0x4940003d },
+	{ 0x5fffc,  0xfec000ac },
+	{ 0x5029c,  0x48400037 },
+	{ 0x5fffc,  0xff0000b4 },
+	{ 0x502a0,  0x47800031 },
+	{ 0x5fffc,  0xff8000bd },
+	{ 0x502a4,  0x4640002b },
+	{ 0x5fffc,  0xc5 },
+	{ 0x502a8,  0x45000026 },
+	{ 0x5fffc,  0x8000ce },
+	{ 0x502ac,  0x43800021 },
+	{ 0x5fffc,  0x10000d6 },
+	{ 0x502b0,  0x4240001c },
+	{ 0x5fffc,  0x18000df },
+	{ 0x502b4,  0x40800018 },
+	{ 0x5fffc,  0x24000e6 },
+	{ 0x502b8,  0x3f000014 },
+	{ 0x5fffc,  0x30000ee },
+	{ 0x502bc,  0x3d400010 },
+	{ 0x5fffc,  0x40000f5 },
+	{ 0x502c0,  0x3b80000c },
+	{ 0x5fffc,  0x50000fc },
+	{ 0x502c4,  0x39800009 },
+	{ 0x5fffc,  0x6000102 },
+	{ 0x502c8,  0x37c00006 },
+	{ 0x5fffc,  0x7000109 },
+	{ 0x502cc,  0x35800004 },
+	{ 0x5fffc,  0x840010e },
+	{ 0x502d0,  0x33800002 },
+	{ 0x5fffc,  0x9800114 },
+	{ 0x502d4,  0x31400000 },
+	{ 0x5fffc,  0xac00119 },
+	{ 0x502d8,  0x2f4003fe },
+	{ 0x5fffc,  0xc40011e },
+	{ 0x502dc,  0x2d0003fc },
+	{ 0x5fffc,  0xdc00121 },
+	{ 0x502e0,  0x2b0003fb },
+	{ 0x5fffc,  0xf400125 },
+	{ 0x502e4,  0x28c003fa },
+	{ 0x5fffc,  0x11000128 },
+	{ 0x502e8,  0x268003f9 },
+	{ 0x5fffc,  0x12c0012a },
+	{ 0x502ec,  0x244003f9 },
+	{ 0x5fffc,  0x1480012c },
+	{ 0x502f0,  0x224003f8 },
+	{ 0x5fffc,  0x1640012e },
+	{ 0x502f4,  0x200003f8 },
+	{ 0x5fffc,  0x1800012f },
+	{ 0x502f8,  0x1e0003f8 },
+	{ 0x5fffc,  0x1a00012f },
+	{ 0x502fc,  0x1c0003f8 },
+};
+
+static struct mdp_table_entry mdp_downscale_x_table_PT8TO1[] = {
+	{ 0x5fffc,  0x0 },
+	{ 0x50280,  0x7fc00000 },
+	{ 0x5fffc,  0xff80000d },
+	{ 0x50284,  0x7ec003f9 },
+	{ 0x5fffc,  0xfec0001c },
+	{ 0x50288,  0x7d4003f3 },
+	{ 0x5fffc,  0xfe40002b },
+	{ 0x5028c,  0x7b8003ed },
+	{ 0x5fffc,  0xfd80003c },
+	{ 0x50290,  0x794003e8 },
+	{ 0x5fffc,  0xfcc0004d },
+	{ 0x50294,  0x76c003e4 },
+	{ 0x5fffc,  0xfc40005f },
+	{ 0x50298,  0x73c003e0 },
+	{ 0x5fffc,  0xfb800071 },
+	{ 0x5029c,  0x708003de },
+	{ 0x5fffc,  0xfac00085 },
+	{ 0x502a0,  0x6d0003db },
+	{ 0x5fffc,  0xfa000098 },
+	{ 0x502a4,  0x698003d9 },
+	{ 0x5fffc,  0xf98000ac },
+	{ 0x502a8,  0x654003d8 },
+	{ 0x5fffc,  0xf8c000c1 },
+	{ 0x502ac,  0x610003d7 },
+	{ 0x5fffc,  0xf84000d5 },
+	{ 0x502b0,  0x5c8003d7 },
+	{ 0x5fffc,  0xf7c000e9 },
+	{ 0x502b4,  0x580003d7 },
+	{ 0x5fffc,  0xf74000fd },
+	{ 0x502b8,  0x534003d8 },
+	{ 0x5fffc,  0xf6c00112 },
+	{ 0x502bc,  0x4e8003d8 },
+	{ 0x5fffc,  0xf6800126 },
+	{ 0x502c0,  0x494003da },
+	{ 0x5fffc,  0xf600013a },
+	{ 0x502c4,  0x448003db },
+	{ 0x5fffc,  0xf600014d },
+	{ 0x502c8,  0x3f4003dd },
+	{ 0x5fffc,  0xf5c00160 },
+	{ 0x502cc,  0x3a4003df },
+	{ 0x5fffc,  0xf5c00172 },
+	{ 0x502d0,  0x354003e1 },
+	{ 0x5fffc,  0xf5c00184 },
+	{ 0x502d4,  0x304003e3 },
+	{ 0x5fffc,  0xf6000195 },
+	{ 0x502d8,  0x2b0003e6 },
+	{ 0x5fffc,  0xf64001a6 },
+	{ 0x502dc,  0x260003e8 },
+	{ 0x5fffc,  0xf6c001b4 },
+	{ 0x502e0,  0x214003eb },
+	{ 0x5fffc,  0xf78001c2 },
+	{ 0x502e4,  0x1c4003ee },
+	{ 0x5fffc,  0xf80001cf },
+	{ 0x502e8,  0x17c003f1 },
+	{ 0x5fffc,  0xf90001db },
+	{ 0x502ec,  0x134003f3 },
+	{ 0x5fffc,  0xfa0001e5 },
+	{ 0x502f0,  0xf0003f6 },
+	{ 0x5fffc,  0xfb4001ee },
+	{ 0x502f4,  0xac003f9 },
+	{ 0x5fffc,  0xfcc001f5 },
+	{ 0x502f8,  0x70003fb },
+	{ 0x5fffc,  0xfe4001fb },
+	{ 0x502fc,  0x34003fe },
+};
+
+struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX] = {
+	[MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_x_table_PT2TOPT4,
+	[MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_x_table_PT4TOPT6,
+	[MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_x_table_PT6TOPT8,
+	[MDP_DOWNSCALE_PT8TO1]  = mdp_downscale_x_table_PT8TO1,
+};
+
+static struct mdp_table_entry mdp_downscale_y_table_PT2TOPT4[] = {
+	{ 0x5fffc,  0x740008c },
+	{ 0x50300,  0x33800088 },
+	{ 0x5fffc,  0x800008e },
+	{ 0x50304,  0x33400084 },
+	{ 0x5fffc,  0x8400092 },
+	{ 0x50308,  0x33000080 },
+	{ 0x5fffc,  0x9000094 },
+	{ 0x5030c,  0x3300007b },
+	{ 0x5fffc,  0x9c00098 },
+	{ 0x50310,  0x32400077 },
+	{ 0x5fffc,  0xa40009b },
+	{ 0x50314,  0x32000073 },
+	{ 0x5fffc,  0xb00009d },
+	{ 0x50318,  0x31c0006f },
+	{ 0x5fffc,  0xbc000a0 },
+	{ 0x5031c,  0x3140006b },
+	{ 0x5fffc,  0xc8000a2 },
+	{ 0x50320,  0x31000067 },
+	{ 0x5fffc,  0xd8000a5 },
+	{ 0x50324,  0x30800062 },
+	{ 0x5fffc,  0xe4000a8 },
+	{ 0x50328,  0x2fc0005f },
+	{ 0x5fffc,  0xec000aa },
+	{ 0x5032c,  0x2fc0005b },
+	{ 0x5fffc,  0xf8000ad },
+	{ 0x50330,  0x2f400057 },
+	{ 0x5fffc,  0x108000b0 },
+	{ 0x50334,  0x2e400054 },
+	{ 0x5fffc,  0x114000b2 },
+	{ 0x50338,  0x2e000050 },
+	{ 0x5fffc,  0x124000b4 },
+	{ 0x5033c,  0x2d80004c },
+	{ 0x5fffc,  0x130000b6 },
+	{ 0x50340,  0x2d000049 },
+	{ 0x5fffc,  0x140000b8 },
+	{ 0x50344,  0x2c800045 },
+	{ 0x5fffc,  0x150000b9 },
+	{ 0x50348,  0x2c000042 },
+	{ 0x5fffc,  0x15c000bd },
+	{ 0x5034c,  0x2b40003e },
+	{ 0x5fffc,  0x16c000bf },
+	{ 0x50350,  0x2a80003b },
+	{ 0x5fffc,  0x17c000bf },
+	{ 0x50354,  0x2a000039 },
+	{ 0x5fffc,  0x188000c2 },
+	{ 0x50358,  0x29400036 },
+	{ 0x5fffc,  0x19c000c4 },
+	{ 0x5035c,  0x28800032 },
+	{ 0x5fffc,  0x1ac000c5 },
+	{ 0x50360,  0x2800002f },
+	{ 0x5fffc,  0x1bc000c7 },
+	{ 0x50364,  0x2740002c },
+	{ 0x5fffc,  0x1cc000c8 },
+	{ 0x50368,  0x26c00029 },
+	{ 0x5fffc,  0x1dc000c9 },
+	{ 0x5036c,  0x26000027 },
+	{ 0x5fffc,  0x1ec000cc },
+	{ 0x50370,  0x25000024 },
+	{ 0x5fffc,  0x200000cc },
+	{ 0x50374,  0x24800021 },
+	{ 0x5fffc,  0x210000cd },
+	{ 0x50378,  0x23800020 },
+	{ 0x5fffc,  0x220000ce },
+	{ 0x5037c,  0x2300001d },
+};
+
+static struct mdp_table_entry mdp_downscale_y_table_PT4TOPT6[] = {
+	{ 0x5fffc,  0x740008c },
+	{ 0x50300,  0x33800088 },
+	{ 0x5fffc,  0x800008e },
+	{ 0x50304,  0x33400084 },
+	{ 0x5fffc,  0x8400092 },
+	{ 0x50308,  0x33000080 },
+	{ 0x5fffc,  0x9000094 },
+	{ 0x5030c,  0x3300007b },
+	{ 0x5fffc,  0x9c00098 },
+	{ 0x50310,  0x32400077 },
+	{ 0x5fffc,  0xa40009b },
+	{ 0x50314,  0x32000073 },
+	{ 0x5fffc,  0xb00009d },
+	{ 0x50318,  0x31c0006f },
+	{ 0x5fffc,  0xbc000a0 },
+	{ 0x5031c,  0x3140006b },
+	{ 0x5fffc,  0xc8000a2 },
+	{ 0x50320,  0x31000067 },
+	{ 0x5fffc,  0xd8000a5 },
+	{ 0x50324,  0x30800062 },
+	{ 0x5fffc,  0xe4000a8 },
+	{ 0x50328,  0x2fc0005f },
+	{ 0x5fffc,  0xec000aa },
+	{ 0x5032c,  0x2fc0005b },
+	{ 0x5fffc,  0xf8000ad },
+	{ 0x50330,  0x2f400057 },
+	{ 0x5fffc,  0x108000b0 },
+	{ 0x50334,  0x2e400054 },
+	{ 0x5fffc,  0x114000b2 },
+	{ 0x50338,  0x2e000050 },
+	{ 0x5fffc,  0x124000b4 },
+	{ 0x5033c,  0x2d80004c },
+	{ 0x5fffc,  0x130000b6 },
+	{ 0x50340,  0x2d000049 },
+	{ 0x5fffc,  0x140000b8 },
+	{ 0x50344,  0x2c800045 },
+	{ 0x5fffc,  0x150000b9 },
+	{ 0x50348,  0x2c000042 },
+	{ 0x5fffc,  0x15c000bd },
+	{ 0x5034c,  0x2b40003e },
+	{ 0x5fffc,  0x16c000bf },
+	{ 0x50350,  0x2a80003b },
+	{ 0x5fffc,  0x17c000bf },
+	{ 0x50354,  0x2a000039 },
+	{ 0x5fffc,  0x188000c2 },
+	{ 0x50358,  0x29400036 },
+	{ 0x5fffc,  0x19c000c4 },
+	{ 0x5035c,  0x28800032 },
+	{ 0x5fffc,  0x1ac000c5 },
+	{ 0x50360,  0x2800002f },
+	{ 0x5fffc,  0x1bc000c7 },
+	{ 0x50364,  0x2740002c },
+	{ 0x5fffc,  0x1cc000c8 },
+	{ 0x50368,  0x26c00029 },
+	{ 0x5fffc,  0x1dc000c9 },
+	{ 0x5036c,  0x26000027 },
+	{ 0x5fffc,  0x1ec000cc },
+	{ 0x50370,  0x25000024 },
+	{ 0x5fffc,  0x200000cc },
+	{ 0x50374,  0x24800021 },
+	{ 0x5fffc,  0x210000cd },
+	{ 0x50378,  0x23800020 },
+	{ 0x5fffc,  0x220000ce },
+	{ 0x5037c,  0x2300001d },
+};
+
+static struct mdp_table_entry mdp_downscale_y_table_PT6TOPT8[] = {
+	{ 0x5fffc,  0xfe000070 },
+	{ 0x50300,  0x4bc00068 },
+	{ 0x5fffc,  0xfe000078 },
+	{ 0x50304,  0x4bc00060 },
+	{ 0x5fffc,  0xfe000080 },
+	{ 0x50308,  0x4b800059 },
+	{ 0x5fffc,  0xfe000089 },
+	{ 0x5030c,  0x4b000052 },
+	{ 0x5fffc,  0xfe400091 },
+	{ 0x50310,  0x4a80004b },
+	{ 0x5fffc,  0xfe40009a },
+	{ 0x50314,  0x4a000044 },
+	{ 0x5fffc,  0xfe8000a3 },
+	{ 0x50318,  0x4940003d },
+	{ 0x5fffc,  0xfec000ac },
+	{ 0x5031c,  0x48400037 },
+	{ 0x5fffc,  0xff0000b4 },
+	{ 0x50320,  0x47800031 },
+	{ 0x5fffc,  0xff8000bd },
+	{ 0x50324,  0x4640002b },
+	{ 0x5fffc,  0xc5 },
+	{ 0x50328,  0x45000026 },
+	{ 0x5fffc,  0x8000ce },
+	{ 0x5032c,  0x43800021 },
+	{ 0x5fffc,  0x10000d6 },
+	{ 0x50330,  0x4240001c },
+	{ 0x5fffc,  0x18000df },
+	{ 0x50334,  0x40800018 },
+	{ 0x5fffc,  0x24000e6 },
+	{ 0x50338,  0x3f000014 },
+	{ 0x5fffc,  0x30000ee },
+	{ 0x5033c,  0x3d400010 },
+	{ 0x5fffc,  0x40000f5 },
+	{ 0x50340,  0x3b80000c },
+	{ 0x5fffc,  0x50000fc },
+	{ 0x50344,  0x39800009 },
+	{ 0x5fffc,  0x6000102 },
+	{ 0x50348,  0x37c00006 },
+	{ 0x5fffc,  0x7000109 },
+	{ 0x5034c,  0x35800004 },
+	{ 0x5fffc,  0x840010e },
+	{ 0x50350,  0x33800002 },
+	{ 0x5fffc,  0x9800114 },
+	{ 0x50354,  0x31400000 },
+	{ 0x5fffc,  0xac00119 },
+	{ 0x50358,  0x2f4003fe },
+	{ 0x5fffc,  0xc40011e },
+	{ 0x5035c,  0x2d0003fc },
+	{ 0x5fffc,  0xdc00121 },
+	{ 0x50360,  0x2b0003fb },
+	{ 0x5fffc,  0xf400125 },
+	{ 0x50364,  0x28c003fa },
+	{ 0x5fffc,  0x11000128 },
+	{ 0x50368,  0x268003f9 },
+	{ 0x5fffc,  0x12c0012a },
+	{ 0x5036c,  0x244003f9 },
+	{ 0x5fffc,  0x1480012c },
+	{ 0x50370,  0x224003f8 },
+	{ 0x5fffc,  0x1640012e },
+	{ 0x50374,  0x200003f8 },
+	{ 0x5fffc,  0x1800012f },
+	{ 0x50378,  0x1e0003f8 },
+	{ 0x5fffc,  0x1a00012f },
+	{ 0x5037c,  0x1c0003f8 },
+};
+
+static struct mdp_table_entry mdp_downscale_y_table_PT8TO1[] = {
+	{ 0x5fffc,  0x0 },
+	{ 0x50300,  0x7fc00000 },
+	{ 0x5fffc,  0xff80000d },
+	{ 0x50304,  0x7ec003f9 },
+	{ 0x5fffc,  0xfec0001c },
+	{ 0x50308,  0x7d4003f3 },
+	{ 0x5fffc,  0xfe40002b },
+	{ 0x5030c,  0x7b8003ed },
+	{ 0x5fffc,  0xfd80003c },
+	{ 0x50310,  0x794003e8 },
+	{ 0x5fffc,  0xfcc0004d },
+	{ 0x50314,  0x76c003e4 },
+	{ 0x5fffc,  0xfc40005f },
+	{ 0x50318,  0x73c003e0 },
+	{ 0x5fffc,  0xfb800071 },
+	{ 0x5031c,  0x708003de },
+	{ 0x5fffc,  0xfac00085 },
+	{ 0x50320,  0x6d0003db },
+	{ 0x5fffc,  0xfa000098 },
+	{ 0x50324,  0x698003d9 },
+	{ 0x5fffc,  0xf98000ac },
+	{ 0x50328,  0x654003d8 },
+	{ 0x5fffc,  0xf8c000c1 },
+	{ 0x5032c,  0x610003d7 },
+	{ 0x5fffc,  0xf84000d5 },
+	{ 0x50330,  0x5c8003d7 },
+	{ 0x5fffc,  0xf7c000e9 },
+	{ 0x50334,  0x580003d7 },
+	{ 0x5fffc,  0xf74000fd },
+	{ 0x50338,  0x534003d8 },
+	{ 0x5fffc,  0xf6c00112 },
+	{ 0x5033c,  0x4e8003d8 },
+	{ 0x5fffc,  0xf6800126 },
+	{ 0x50340,  0x494003da },
+	{ 0x5fffc,  0xf600013a },
+	{ 0x50344,  0x448003db },
+	{ 0x5fffc,  0xf600014d },
+	{ 0x50348,  0x3f4003dd },
+	{ 0x5fffc,  0xf5c00160 },
+	{ 0x5034c,  0x3a4003df },
+	{ 0x5fffc,  0xf5c00172 },
+	{ 0x50350,  0x354003e1 },
+	{ 0x5fffc,  0xf5c00184 },
+	{ 0x50354,  0x304003e3 },
+	{ 0x5fffc,  0xf6000195 },
+	{ 0x50358,  0x2b0003e6 },
+	{ 0x5fffc,  0xf64001a6 },
+	{ 0x5035c,  0x260003e8 },
+	{ 0x5fffc,  0xf6c001b4 },
+	{ 0x50360,  0x214003eb },
+	{ 0x5fffc,  0xf78001c2 },
+	{ 0x50364,  0x1c4003ee },
+	{ 0x5fffc,  0xf80001cf },
+	{ 0x50368,  0x17c003f1 },
+	{ 0x5fffc,  0xf90001db },
+	{ 0x5036c,  0x134003f3 },
+	{ 0x5fffc,  0xfa0001e5 },
+	{ 0x50370,  0xf0003f6 },
+	{ 0x5fffc,  0xfb4001ee },
+	{ 0x50374,  0xac003f9 },
+	{ 0x5fffc,  0xfcc001f5 },
+	{ 0x50378,  0x70003fb },
+	{ 0x5fffc,  0xfe4001fb },
+	{ 0x5037c,  0x34003fe },
+};
+
+struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX] = {
+	[MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_y_table_PT2TOPT4,
+	[MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_y_table_PT4TOPT6,
+	[MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_y_table_PT6TOPT8,
+	[MDP_DOWNSCALE_PT8TO1]  = mdp_downscale_y_table_PT8TO1,
+};
+
+struct mdp_table_entry mdp_gaussian_blur_table[] = {
+	/* max variance */
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50280, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50284, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50288, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5028c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50290, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50294, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50298, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5029c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502a8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502ac, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502b8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502bc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502c8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502cc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502d8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502dc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502e8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502ec, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f0, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f4, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502f8, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x502fc, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50300, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50304, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50308, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5030c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50310, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50314, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50318, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5031c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50320, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50324, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50328, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5032c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50330, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50334, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50338, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5033c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50340, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50344, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50348, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5034c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50350, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50354, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50358, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5035c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50360, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50364, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50368, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5036c, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50370, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50374, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x50378, 0x20000080 },
+	{ 0x5fffc, 0x20000080 },
+	{ 0x5037c, 0x20000080 },
+};
diff --git a/drivers/video/msm/mdp_scale_tables.h b/drivers/video/msm/mdp_scale_tables.h
new file mode 100644
index 0000000..34077b1
--- /dev/null
+++ b/drivers/video/msm/mdp_scale_tables.h
@@ -0,0 +1,38 @@
+/* drivers/video/msm_fb/mdp_scale_tables.h
+ *
+ * Copyright (C) 2007 QUALCOMM Incorporated
+ * Copyright (C) 2007 Google Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _MDP_SCALE_TABLES_H_
+#define _MDP_SCALE_TABLES_H_
+
+#include <linux/types.h>
+struct mdp_table_entry {
+	uint32_t reg;
+	uint32_t val;
+};
+
+extern struct mdp_table_entry mdp_upscale_table[64];
+
+enum {
+	MDP_DOWNSCALE_PT2TOPT4,
+	MDP_DOWNSCALE_PT4TOPT6,
+	MDP_DOWNSCALE_PT6TOPT8,
+	MDP_DOWNSCALE_PT8TO1,
+	MDP_DOWNSCALE_MAX,
+};
+
+extern struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX];
+extern struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX];
+extern struct mdp_table_entry mdp_gaussian_blur_table[];
+
+#endif
diff --git a/drivers/video/msm/mdp_vsync.c b/drivers/video/msm/mdp_vsync.c
new file mode 100644
index 0000000..cc350d3
--- /dev/null
+++ b/drivers/video/msm/mdp_vsync.c
@@ -0,0 +1,504 @@
+/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/hrtimer.h>
+#include <linux/vmalloc.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <mach/gpio.h>
+
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mddihost.h"
+
+#ifdef CONFIG_FB_MSM_MDP40
+#include "mdp4.h"
+
+#define MDP_SYNC_CFG_0		0x100
+#define MDP_SYNC_STATUS_0	0x10c
+#define MDP_SYNC_CFG_1		0x104
+#define MDP_SYNC_STATUS_1	0x110
+#define MDP_PRIM_VSYNC_OUT_CTRL	0x118
+#define MDP_SEC_VSYNC_OUT_CTRL	0x11C
+#define MDP_VSYNC_SEL		0x124
+#define MDP_PRIM_VSYNC_INIT_VAL	0x128
+#define MDP_SEC_VSYNC_INIT_VAL	0x12C
+#else
+#define MDP_SYNC_CFG_0		0x300
+#define MDP_SYNC_STATUS_0	0x30c
+#define MDP_PRIM_VSYNC_OUT_CTRL	0x318
+#define MDP_PRIM_VSYNC_INIT_VAL	0x328
+#endif
+
+extern mddi_lcd_type mddi_lcd_idx;
+extern spinlock_t mdp_spin_lock;
+extern struct workqueue_struct *mdp_vsync_wq;
+extern int lcdc_mode;
+extern int vsync_mode;
+
+#ifdef MDP_HW_VSYNC
+int vsync_above_th = 4;
+int vsync_start_th = 1;
+int vsync_load_cnt;
+int vsync_clk_status;
+DEFINE_MUTEX(vsync_clk_lock);
+static DEFINE_SPINLOCK(vsync_timer_lock);
+
+static struct clk *mdp_vsync_clk;
+static struct msm_fb_data_type *vsync_mfd;
+static unsigned char timer_shutdown_flag;
+static uint32 vsync_cnt_cfg;
+
+
+void vsync_clk_prepare_enable(void)
+{
+	if (mdp_vsync_clk)
+		clk_prepare_enable(mdp_vsync_clk);
+}
+
+void vsync_clk_disable_unprepare(void)
+{
+	if (mdp_vsync_clk)
+		clk_disable_unprepare(mdp_vsync_clk);
+}
+
+void mdp_hw_vsync_clk_enable(struct msm_fb_data_type *mfd)
+{
+	if (vsync_clk_status == 1)
+		return;
+	mutex_lock(&vsync_clk_lock);
+	if (mfd->use_mdp_vsync) {
+		clk_prepare_enable(mdp_vsync_clk);
+		vsync_clk_status = 1;
+	}
+	mutex_unlock(&vsync_clk_lock);
+}
+
+void mdp_hw_vsync_clk_disable(struct msm_fb_data_type *mfd)
+{
+	if (vsync_clk_status == 0)
+		return;
+	mutex_lock(&vsync_clk_lock);
+	if (mfd->use_mdp_vsync) {
+		clk_disable_unprepare(mdp_vsync_clk);
+		vsync_clk_status = 0;
+	}
+	mutex_unlock(&vsync_clk_lock);
+}
+
+static void mdp_set_vsync(unsigned long data);
+void mdp_vsync_clk_enable(void)
+{
+	if (vsync_mfd) {
+		mdp_hw_vsync_clk_enable(vsync_mfd);
+		if (!vsync_mfd->vsync_resync_timer.function)
+			mdp_set_vsync((unsigned long) vsync_mfd);
+	}
+}
+
+void mdp_vsync_clk_disable(void)
+{
+	if (vsync_mfd) {
+		if (vsync_mfd->vsync_resync_timer.function) {
+			spin_lock(&vsync_timer_lock);
+			timer_shutdown_flag = 1;
+			spin_unlock(&vsync_timer_lock);
+			del_timer_sync(&vsync_mfd->vsync_resync_timer);
+			spin_lock(&vsync_timer_lock);
+			timer_shutdown_flag = 0;
+			spin_unlock(&vsync_timer_lock);
+			vsync_mfd->vsync_resync_timer.function = NULL;
+		}
+
+		mdp_hw_vsync_clk_disable(vsync_mfd);
+	}
+}
+#endif
+
+static void mdp_set_vsync(unsigned long data)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
+	struct msm_fb_panel_data *pdata = NULL;
+
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
+	vsync_mfd = mfd;
+	init_timer(&mfd->vsync_resync_timer);
+
+	if ((pdata) && (pdata->set_vsync_notifier == NULL))
+		return;
+
+	if ((mfd->panel_info.lcd.vsync_enable) && (mfd->panel_power_on)
+	    && (!mfd->vsync_handler_pending)) {
+		mfd->vsync_handler_pending = TRUE;
+		if (!queue_work(mdp_vsync_wq, &mfd->vsync_resync_worker)) {
+			MSM_FB_INFO
+			    ("mdp_set_vsync: can't queue_work! -> needs to increase vsync_resync_timer_duration\n");
+		}
+	} else {
+		MSM_FB_DEBUG
+		    ("mdp_set_vsync failed!  EN:%d  PWR:%d  PENDING:%d\n",
+		     mfd->panel_info.lcd.vsync_enable, mfd->panel_power_on,
+		     mfd->vsync_handler_pending);
+	}
+
+	spin_lock(&vsync_timer_lock);
+	if (!timer_shutdown_flag) {
+		mfd->vsync_resync_timer.function = mdp_set_vsync;
+		mfd->vsync_resync_timer.data = data;
+		mfd->vsync_resync_timer.expires =
+			jiffies + mfd->panel_info.lcd.vsync_notifier_period;
+		add_timer(&mfd->vsync_resync_timer);
+	}
+	spin_unlock(&vsync_timer_lock);
+}
+
+static void mdp_vsync_handler(void *data)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
+
+	if (vsync_clk_status == 0) {
+		pr_debug("Warning: vsync clk is disabled\n");
+		mfd->vsync_handler_pending = FALSE;
+		return;
+	}
+
+	if (mfd->use_mdp_vsync) {
+#ifdef MDP_HW_VSYNC
+		if (mfd->panel_power_on) {
+			MDP_OUTP(MDP_BASE + MDP_SYNC_STATUS_0, vsync_load_cnt);
+
+#ifdef CONFIG_FB_MSM_MDP40
+			if (mdp_hw_revision < MDP4_REVISION_V2_1)
+				MDP_OUTP(MDP_BASE + MDP_SYNC_STATUS_1,
+						vsync_load_cnt);
+#endif
+		}
+
+#endif
+	} else {
+		mfd->last_vsync_timetick = ktime_get_real();
+	}
+
+	mfd->vsync_handler_pending = FALSE;
+}
+
+irqreturn_t mdp_hw_vsync_handler_proxy(int irq, void *data)
+{
+	/*
+	 * ToDo: tried enabling/disabling GPIO MDP HW VSYNC interrupt
+	 * but getting inaccurate timing in mdp_vsync_handler()
+	 * disable_irq(MDP_HW_VSYNC_IRQ);
+	 */
+	mdp_vsync_handler(data);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef MDP_HW_VSYNC
+static void mdp_set_sync_cfg_0(struct msm_fb_data_type *mfd, int vsync_cnt)
+{
+	unsigned long cfg;
+
+	cfg = mfd->total_lcd_lines - 1;
+	cfg <<= MDP_SYNCFG_HGT_LOC;
+	if (mfd->panel_info.lcd.hw_vsync_mode)
+		cfg |= MDP_SYNCFG_VSYNC_EXT_EN;
+	cfg |= (MDP_SYNCFG_VSYNC_INT_EN | vsync_cnt);
+
+	MDP_OUTP(MDP_BASE + MDP_SYNC_CFG_0, cfg);
+}
+
+#ifdef CONFIG_FB_MSM_MDP40
+static void mdp_set_sync_cfg_1(struct msm_fb_data_type *mfd, int vsync_cnt)
+{
+	unsigned long cfg;
+
+	cfg = mfd->total_lcd_lines - 1;
+	cfg <<= MDP_SYNCFG_HGT_LOC;
+	if (mfd->panel_info.lcd.hw_vsync_mode)
+		cfg |= MDP_SYNCFG_VSYNC_EXT_EN;
+	cfg |= (MDP_SYNCFG_VSYNC_INT_EN | vsync_cnt);
+
+	MDP_OUTP(MDP_BASE + MDP_SYNC_CFG_1, cfg);
+}
+#endif
+
+void mdp_vsync_cfg_regs(struct msm_fb_data_type *mfd,
+	boolean first_time)
+{
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
+			  FALSE);
+	if (first_time)
+		mdp_hw_vsync_clk_enable(mfd);
+
+	mdp_set_sync_cfg_0(mfd, vsync_cnt_cfg);
+
+#ifdef CONFIG_FB_MSM_MDP40
+	if (mdp_hw_revision < MDP4_REVISION_V2_1)
+		mdp_set_sync_cfg_1(mfd, vsync_cnt_cfg);
+#endif
+
+	/*
+	 * load the last line + 1 to be in the
+	 * safety zone
+	 */
+	vsync_load_cnt = mfd->panel_info.yres;
+
+	/* line counter init value at the next pulse */
+	MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_INIT_VAL,
+		vsync_load_cnt);
+#ifdef CONFIG_FB_MSM_MDP40
+	if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+		MDP_OUTP(MDP_BASE +	MDP_SEC_VSYNC_INIT_VAL,
+			vsync_load_cnt);
+	}
+#endif
+
+	/*
+	 * external vsync source pulse width and
+	 * polarity flip
+	 */
+	MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_OUT_CTRL, BIT(0));
+#ifdef CONFIG_FB_MSM_MDP40
+	if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+		MDP_OUTP(MDP_BASE +	MDP_SEC_VSYNC_OUT_CTRL, BIT(0));
+		MDP_OUTP(MDP_BASE +	MDP_VSYNC_SEL, 0x20);
+	}
+#endif
+
+	/* threshold */
+	MDP_OUTP(MDP_BASE + 0x200, (vsync_above_th << 16) |
+		 (vsync_start_th));
+
+	if (first_time)
+		mdp_hw_vsync_clk_disable(mfd);
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+#endif
+
+void mdp_config_vsync(struct platform_device *pdev,
+	struct msm_fb_data_type *mfd)
+{
+	/* vsync on primary lcd only for now */
+	if ((mfd->dest != DISPLAY_LCD) || (mfd->panel_info.pdest != DISPLAY_1)
+	    || (!vsync_mode)) {
+		goto err_handle;
+	}
+
+	vsync_clk_status = 0;
+	if (mfd->panel_info.lcd.vsync_enable) {
+		mfd->total_porch_lines = mfd->panel_info.lcd.v_back_porch +
+		    mfd->panel_info.lcd.v_front_porch +
+		    mfd->panel_info.lcd.v_pulse_width;
+		mfd->total_lcd_lines =
+		    mfd->panel_info.yres + mfd->total_porch_lines;
+		mfd->lcd_ref_usec_time =
+		    100000000 / mfd->panel_info.lcd.refx100;
+		mfd->vsync_handler_pending = FALSE;
+
+		mfd->last_vsync_timetick.tv64 = 0;
+
+#ifdef MDP_HW_VSYNC
+		if (mdp_vsync_clk == NULL)
+			mdp_vsync_clk = clk_get(&pdev->dev, "vsync_clk");
+
+		if (IS_ERR(mdp_vsync_clk)) {
+			printk(KERN_ERR "error: can't get mdp_vsync_clk!\n");
+			mfd->use_mdp_vsync = 0;
+		} else
+			mfd->use_mdp_vsync = 1;
+
+		if (mfd->use_mdp_vsync) {
+			uint32 vsync_cnt_cfg_dem;
+			uint32 mdp_vsync_clk_speed_hz;
+
+			mdp_vsync_clk_speed_hz = clk_get_rate(mdp_vsync_clk);
+
+			if (mdp_vsync_clk_speed_hz == 0) {
+				mfd->use_mdp_vsync = 0;
+			} else {
+				/*
+				 * Do this calculation in 2 steps for
+				 * rounding uint32 properly.
+				 */
+				vsync_cnt_cfg_dem =
+				    (mfd->panel_info.lcd.refx100 *
+				     mfd->total_lcd_lines) / 100;
+				vsync_cnt_cfg =
+				    (mdp_vsync_clk_speed_hz) /
+				    vsync_cnt_cfg_dem;
+				mdp_vsync_cfg_regs(mfd, TRUE);
+			}
+		}
+#else
+		mfd->use_mdp_vsync = 0;
+		hrtimer_init(&mfd->dma_hrtimer, CLOCK_MONOTONIC,
+			     HRTIMER_MODE_REL);
+		mfd->dma_hrtimer.function = mdp_dma2_vsync_hrtimer_handler;
+		mfd->vsync_width_boundary = vmalloc(mfd->panel_info.xres * 4);
+#endif
+
+#ifdef CONFIG_FB_MSM_MDDI
+		mfd->channel_irq = 0;
+		if (mfd->panel_info.lcd.hw_vsync_mode) {
+			u32 vsync_gpio = mfd->vsync_gpio;
+			u32 ret;
+
+			if (vsync_gpio == -1) {
+				MSM_FB_INFO("vsync_gpio not defined!\n");
+				goto err_handle;
+			}
+
+			ret = gpio_tlmm_config(GPIO_CFG
+					(vsync_gpio,
+					(mfd->use_mdp_vsync) ? 1 : 0,
+					GPIO_CFG_INPUT,
+					GPIO_CFG_PULL_DOWN,
+					GPIO_CFG_2MA),
+					GPIO_CFG_ENABLE);
+			if (ret)
+				goto err_handle;
+
+			/*
+			 * if use_mdp_vsync, then no interrupt need since
+			 * mdp_vsync is feed directly to mdp to reset the
+			 * write pointer counter. therefore no irq_handler
+			 * need to reset write pointer counter.
+			 */
+			if (!mfd->use_mdp_vsync) {
+				mfd->channel_irq = MSM_GPIO_TO_INT(vsync_gpio);
+				if (request_irq
+				    (mfd->channel_irq,
+				     &mdp_hw_vsync_handler_proxy,
+				     IRQF_TRIGGER_FALLING, "VSYNC_GPIO",
+				     (void *)mfd)) {
+					MSM_FB_INFO
+					("irq=%d failed! vsync_gpio=%d\n",
+						mfd->channel_irq,
+						vsync_gpio);
+					goto err_handle;
+				}
+			}
+		}
+#endif
+		mdp_hw_vsync_clk_enable(mfd);
+		mdp_set_vsync((unsigned long)mfd);
+	}
+
+	return;
+
+err_handle:
+	if (mfd->vsync_width_boundary)
+		vfree(mfd->vsync_width_boundary);
+	mfd->panel_info.lcd.vsync_enable = FALSE;
+	printk(KERN_ERR "%s: failed!\n", __func__);
+}
+
+void mdp_vsync_resync_workqueue_handler(struct work_struct *work)
+{
+	struct msm_fb_data_type *mfd = NULL;
+	int vsync_fnc_enabled = FALSE;
+	struct msm_fb_panel_data *pdata = NULL;
+
+	mfd = container_of(work, struct msm_fb_data_type, vsync_resync_worker);
+
+	if (mfd) {
+		if (mfd->panel_power_on) {
+			pdata =
+			    (struct msm_fb_panel_data *)mfd->pdev->dev.
+			    platform_data;
+
+			if (pdata->set_vsync_notifier != NULL) {
+				if (pdata->clk_func && !pdata->clk_func(2)) {
+					mfd->vsync_handler_pending = FALSE;
+					return;
+				}
+
+				pdata->set_vsync_notifier(
+						mdp_vsync_handler,
+						(void *)mfd);
+				vsync_fnc_enabled = TRUE;
+			}
+		}
+	}
+
+	if ((mfd) && (!vsync_fnc_enabled))
+		mfd->vsync_handler_pending = FALSE;
+}
+
+boolean mdp_hw_vsync_set_handler(msm_fb_vsync_handler_type handler, void *data)
+{
+	/*
+	 * ToDo: tried enabling/disabling GPIO MDP HW VSYNC interrupt
+	 * but getting inaccurate timing in mdp_vsync_handler()
+	 * enable_irq(MDP_HW_VSYNC_IRQ);
+	 */
+
+	return TRUE;
+}
+
+uint32 mdp_get_lcd_line_counter(struct msm_fb_data_type *mfd)
+{
+	uint32 elapsed_usec_time;
+	uint32 lcd_line;
+	ktime_t last_vsync_timetick_local;
+	ktime_t curr_time;
+	unsigned long flag;
+
+	if ((!mfd->panel_info.lcd.vsync_enable) || (!vsync_mode))
+		return 0;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	last_vsync_timetick_local = mfd->last_vsync_timetick;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	curr_time = ktime_get_real();
+	elapsed_usec_time = ktime_to_us(ktime_sub(curr_time,
+						last_vsync_timetick_local));
+
+	elapsed_usec_time = elapsed_usec_time % mfd->lcd_ref_usec_time;
+
+	/* lcd line calculation referencing to line counter = 0 */
+	lcd_line =
+	    (elapsed_usec_time * mfd->total_lcd_lines) / mfd->lcd_ref_usec_time;
+
+	/* lcd line adjusment referencing to the actual line counter at vsync */
+	lcd_line =
+	    (mfd->total_lcd_lines - mfd->panel_info.lcd.v_back_porch +
+	     lcd_line) % (mfd->total_lcd_lines + 1);
+
+	if (lcd_line > mfd->total_lcd_lines) {
+		MSM_FB_INFO
+		    ("mdp_get_lcd_line_counter: mdp_lcd_rd_cnt >= mfd->total_lcd_lines error!\n");
+	}
+
+	return lcd_line;
+}
diff --git a/drivers/video/msm/mhl_api.h b/drivers/video/msm/mhl_api.h
new file mode 100644
index 0000000..627f802
--- /dev/null
+++ b/drivers/video/msm/mhl_api.h
@@ -0,0 +1,26 @@
+
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __MHL_API_H__
+#define __MHL_API_H__
+
+#ifdef CONFIG_FB_MSM_HDMI_MHL
+bool mhl_is_connected(void);
+#else
+static bool mhl_is_connected(void)
+{
+	return false;
+}
+#endif
+
+#endif /* __MHL_API_H__ */
diff --git a/drivers/video/msm/mipi_chimei_wuxga.c b/drivers/video/msm/mipi_chimei_wuxga.c
new file mode 100644
index 0000000..feb26a1
--- /dev/null
+++ b/drivers/video/msm/mipi_chimei_wuxga.c
@@ -0,0 +1,197 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Chimei WUXGA LVDS Panel driver.
+ * The panel model is N101JSF-L21.
+ *
+ * The panel interface includes:
+ * 1. LVDS input for video (clock & data).
+ * 2. few configuration	pins to control 3D module: Enable, Mode (2D/3D).
+ * 3. Backlight LED control (PWM 200 HZ).
+ *
+ * This panel is controled via the Toshiba DSI-to-LVDS bridge.
+ *
+ */
+
+/* #define DEBUG 1 */
+
+#include "msm_fb.h"
+#include "msm_fb_panel.h"
+#include "mipi_dsi.h"
+#include "mipi_tc358764_dsi2lvds.h"
+
+#define MHZ (1000*1000)
+
+/**
+ * Panel info parameters.
+ * The panel info is passed to the mipi framebuffer driver.
+ */
+static struct msm_panel_info chimei_wuxga_pinfo;
+
+/**
+ * The mipi_dsi_phy_ctrl is calculated according to the
+ * "dsi_timing_program.xlsm" excel sheet.
+ * Output is based on: 1200x1920, RGB565, 4 lanes , 58 frames
+ * per second.
+ */
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* DSIPHY_REGULATOR_CTRL */
+	.regulator = {0x03, 0x0a, 0x04, 0x00, 0x20}, /* common 8960 */
+	/* DSIPHY_CTRL */
+	.ctrl = {0x5f, 0x00, 0x00, 0x10}, /* common 8960 */
+	/* DSIPHY_STRENGTH_CTRL */
+	.strength = {0xff, 0x00, 0x06, 0x00}, /* common 8960 */
+	/* DSIPHY_TIMING_CTRL */
+	.timing = { 0xC9, 0x92, 0x29, /* panel specific */
+	0, /* DSIPHY_TIMING_CTRL_3 = 0 */
+	0x2D, 0x9B, 0x2B, 0x94, 0x2D, 0x03, 0x04},  /* panel specific */
+
+	/* DSIPHY_PLL_CTRL */
+	.pll = { 0x00, /* common 8960 */
+	/* VCO */
+	0x30, (0x01 | 0x30) , (0x19 | 0xC0), /* panel specific */
+	0x00, 0x50, 0x48, 0x63,
+	0x77, 0x88, 0x99, /* Auto update by dsi-mipi driver */
+	0x00, 0x14, 0x03, 0x00, 0x02, /* common 8960 */
+	0x00, 0x20, 0x00, 0x01 }, /* common 8960 */
+};
+
+/**
+ * Module init.
+ *
+ * Register the panel-info.
+ *
+ * Some parameters are from the panel datasheet
+ * and other are *calculated* by the "dsi_timing_program.xlsm"
+ * excel file
+ *
+ * @return int
+ */
+static int __init mipi_chimei_wuxga_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo = &chimei_wuxga_pinfo;
+
+	if (msm_fb_detect_client("mipi_video_chimei_wuxga"))
+		return 0;
+
+	pr_info("mipi-dsi chimei wuxga (1200x1920) driver ver 1.0.\n");
+
+	/* Portrait */
+	pinfo->xres = 1200;
+	pinfo->yres = 1920;
+	pinfo->type =  MIPI_VIDEO_PANEL;
+	pinfo->pdest = DISPLAY_1; /* Primary Display */
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24; /* RGB565 requires 24 bits-per-pixel :-O */
+	pinfo->fb_num = 2; /* using two frame buffers */
+
+	/*
+	 * The CMI panel requires 80 MHZ LVDS-CLK.
+	 * The D2L bridge drives the LVDS-CLK from the DSI-CLK.
+	 * The DSI-CLK = bitclk/2, 640 MHZ/2= 320 MHZ.
+	 * LVDS-CLK = DSI-CLK/4 , 320 MHZ/4= 80 MHZ.
+	 */
+
+	pinfo->clk_rate = 635 * MHZ ; /* bitclk Calculated */
+
+	/*
+	 * this panel is operated by DE,
+	 * vsycn and hsync are ignored
+	 */
+
+	pinfo->lcdc.h_front_porch = 160-48-32;	/* thfp */
+	pinfo->lcdc.h_back_porch = 48;	/* thb */
+	pinfo->lcdc.h_pulse_width = 32;	/* thpw */
+
+	pinfo->lcdc.v_front_porch = 26-3-6;	/* tvfp */
+	pinfo->lcdc.v_back_porch = 3;	/* tvb */
+	pinfo->lcdc.v_pulse_width = 6;	/* tvpw */
+
+	pinfo->lcdc.border_clr = 0;		/* black */
+	pinfo->lcdc.underflow_clr = 0xff;	/* blue */
+
+	pinfo->lcdc.hsync_skew = 0;
+
+	/* Backlight levels - controled via PMIC pwm gpio */
+	pinfo->bl_max = 15;
+	pinfo->bl_min = 1;
+
+	/* mipi - general */
+	pinfo->mipi.vc = 0; /* virtual channel */
+	pinfo->mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo->mipi.tx_eot_append = true;
+	pinfo->mipi.t_clk_post = 34;		/* Calculated */
+	pinfo->mipi.t_clk_pre = 69;		/* Calculated */
+
+	pinfo->mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+	/* Four lanes are recomended for 1920x1200 at 60 frames per second */
+	pinfo->mipi.frame_rate = 60;
+	pinfo->mipi.data_lane0 = true;
+	pinfo->mipi.data_lane1 = true;
+	pinfo->mipi.data_lane2 = true;
+	pinfo->mipi.data_lane3 = true;
+	pinfo->mipi.esc_byte_ratio = 6;
+
+	pinfo->mipi.mode = DSI_VIDEO_MODE;
+	/*
+	 * Note: The CMI panel input is RGB888,
+	 * thus the DSI-to-LVDS bridge output is RGB888.
+	 * This parameter selects the DSI-Core output to the bridge.
+	 */
+	pinfo->mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB565;
+
+	/* mipi - video mode */
+	pinfo->mipi.traffic_mode = DSI_NON_BURST_SYNCH_EVENT;
+	pinfo->mipi.pulse_mode_hsa_he = false; /* sync mode */
+
+	pinfo->mipi.hfp_power_stop = false;
+	pinfo->mipi.hbp_power_stop = false;
+	pinfo->mipi.hsa_power_stop = false;
+	pinfo->mipi.eof_bllp_power_stop = false;
+	pinfo->mipi.bllp_power_stop = false;
+
+	/* mipi - command mode */
+	pinfo->mipi.te_sel = 1; /* TE from vsycn gpio */
+	pinfo->mipi.interleave_max = 1;
+	/* The bridge supports only Generic Read/Write commands */
+	pinfo->mipi.insert_dcs_cmd = false;
+	pinfo->mipi.wr_mem_continue = 0;
+	pinfo->mipi.wr_mem_start = 0;
+	pinfo->mipi.stream = false; /* dma_p */
+	pinfo->mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo->mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	/*
+	 * toshiba d2l chip does not need max_pkt_size dcs cmd
+	 * client reply len is directly configure through
+	 * RDPKTLN register (0x0404)
+	 */
+	pinfo->mipi.no_max_pkt_size = 1;
+	pinfo->mipi.force_clk_lane_hs = 1;
+
+	pinfo->is_3d_panel = FB_TYPE_3D_PANEL;
+
+	ret = mipi_tc358764_dsi2lvds_register(pinfo, MIPI_DSI_PRIM, 1);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_chimei_wuxga_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Chimei WUXGA LVDS Panel driver");
+MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
diff --git a/drivers/video/msm/mipi_chimei_wxga_pt.c b/drivers/video/msm/mipi_chimei_wxga_pt.c
new file mode 100644
index 0000000..70a8787
--- /dev/null
+++ b/drivers/video/msm/mipi_chimei_wxga_pt.c
@@ -0,0 +1,192 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Chimei WXGA LVDS Panel driver.
+ * The panel model is N101BCG-L21.
+ *
+ * The panel interface includes:
+ * 1. LVDS input for video (clock & data).
+ * 2. few configuration	pins: Up/Down scan, Left/Right scan etc.
+ * 3. Backlight LED control.
+ * 4. I2C interface for EEPROM access.
+ *
+ * The Panel is *internally* controlled by Novatek NT51009 controller.
+ * However, the "3-wire" SPI interface is not exposed on the panel interface.
+ *
+ * This panel is controled via the Toshiba DSI-to-LVDS bridge.
+ *
+ */
+
+/* #define DEBUG 1 */
+
+#include "msm_fb.h"
+#include "msm_fb_panel.h"
+#include "mipi_dsi.h"
+#include "mipi_tc358764_dsi2lvds.h"
+
+#define MHZ (1000*1000)
+
+/**
+ * Panel info parameters.
+ * The panel info is passed to the mipi framebuffer driver.
+ */
+static struct msm_panel_info chimei_wxga_pinfo;
+
+/**
+ * The mipi_dsi_phy_ctrl is calculated according to the
+ * "DSI_panel_bring_up_guide_ver3.docm" using the excel sheet.
+ * Output is based on: 1366x768, RGB888, 4 lanes , 60 frames per second.
+ */
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* DSIPHY_REGULATOR_CTRL */
+	.regulator = {0x03, 0x0a, 0x04, 0x00, 0x20}, /* common 8960 */
+	/* DSIPHY_CTRL */
+	.ctrl = {0x5f, 0x00, 0x00, 0x10}, /* common 8960 */
+	/* DSIPHY_STRENGTH_CTRL */
+	.strength = {0xff, 0x00, 0x06, 0x00}, /* common 8960 */
+	/* DSIPHY_TIMING_CTRL */
+	.timing = { 0xB6, 0x8D, 0x1E, /* panel specific */
+	0, /* DSIPHY_TIMING_CTRL_3 = 0 */
+	0x21, 0x95, 0x21, 0x8F, 0x21, 0x03, 0x04},  /* panel specific */
+
+	/* DSIPHY_PLL_CTRL */
+	.pll = { 0x00, /* common 8960 */
+	/* VCO */
+	0xC6, 0x01, 0x19, /* panel specific */
+	0x00, 0x50, 0x48, 0x63,
+	0x77, 0x88, 0x99, /* Auto update by dsi-mipi driver */
+	0x00, 0x14, 0x03, 0x00, 0x02, /* common 8960 */
+	0x00, 0x20, 0x00, 0x01 }, /* common 8960 */
+};
+
+/**
+ * Module init.
+ *
+ * Register the panel-info.
+ *
+ * Some parameters are from the panel datasheet
+ * and other are *calculated* according to the
+ * "DSI_panel_bring_up_guide_ver3.docm".
+ *
+ * @return int
+ */
+static int __init mipi_chimei_wxga_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo = &chimei_wxga_pinfo;
+
+	if (msm_fb_detect_client("mipi_video_chimei_wxga"))
+		return 0;
+
+	pr_debug("mipi-dsi chimei wxga (1366x768) driver ver 1.0.\n");
+	/* Landscape */
+	pinfo->xres = 1366;
+	pinfo->yres = 768;
+	pinfo->type =  MIPI_VIDEO_PANEL;
+	pinfo->pdest = DISPLAY_1; /* Primary Display */
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 24; /* RGB888 = 24 bits-per-pixel */
+	pinfo->fb_num = 2; /* using two frame buffers */
+
+	/* bitclk */
+	pinfo->clk_rate = 473400000; /* 473.4 MHZ Calculated */
+
+	/*
+	 * this panel is operated by DE,
+	 * vsycn and hsync are ignored
+	 */
+
+	pinfo->lcdc.h_front_porch = 96+2;/* thfp */
+	pinfo->lcdc.h_back_porch = 88;	/* thb */
+	pinfo->lcdc.h_pulse_width = 40;	/* thpw */
+
+	pinfo->lcdc.v_front_porch = 15;	/* tvfp */
+	pinfo->lcdc.v_back_porch = 23;	/* tvb */
+	pinfo->lcdc.v_pulse_width = 20;	/* tvpw */
+
+	pinfo->lcdc.border_clr = 0;		/* black */
+	pinfo->lcdc.underflow_clr = 0xff;	/* blue */
+
+	pinfo->lcdc.hsync_skew = 0;
+
+	/* Backlight levels - controled via PMIC pwm gpio */
+	pinfo->bl_max = 15;
+	pinfo->bl_min = 1;
+
+	/* mipi - general */
+	pinfo->mipi.vc = 0; /* virtual channel */
+	pinfo->mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo->mipi.tx_eot_append = true;
+	pinfo->mipi.t_clk_post = 34;		/* Calculated */
+	pinfo->mipi.t_clk_pre = 64;		/* Calculated */
+	pinfo->mipi.esc_byte_ratio = 4;
+
+	pinfo->mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+	/* Four lanes are recomended for 1366x768 at 60 frames per second */
+	pinfo->mipi.frame_rate = 60; /* 60 frames per second */
+	pinfo->mipi.data_lane0 = true;
+	pinfo->mipi.data_lane1 = true;
+	pinfo->mipi.data_lane2 = true;
+	pinfo->mipi.data_lane3 = true;
+
+	pinfo->mipi.mode = DSI_VIDEO_MODE;
+	/*
+	 * Note: The CMI panel input is RGB888,
+	 * thus the DSI-to-LVDS bridge output is RGB888.
+	 * This parameter selects the DSI-Core output to the bridge.
+	 */
+	pinfo->mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+
+	/* mipi - video mode */
+	pinfo->mipi.traffic_mode = DSI_NON_BURST_SYNCH_EVENT;
+	pinfo->mipi.pulse_mode_hsa_he = false; /* sync mode */
+
+	pinfo->mipi.hfp_power_stop = false;
+	pinfo->mipi.hbp_power_stop = false;
+	pinfo->mipi.hsa_power_stop = false;
+	pinfo->mipi.eof_bllp_power_stop = false;
+	pinfo->mipi.bllp_power_stop = false;
+
+	/* mipi - command mode */
+	pinfo->mipi.te_sel = 1; /* TE from vsycn gpio */
+	pinfo->mipi.interleave_max = 1;
+	/* The bridge supports only Generic Read/Write commands */
+	pinfo->mipi.insert_dcs_cmd = false;
+	pinfo->mipi.wr_mem_continue = 0;
+	pinfo->mipi.wr_mem_start = 0;
+	pinfo->mipi.stream = false; /* dma_p */
+	pinfo->mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo->mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	/*
+	 * toshiba d2l chip does not need max_pkt_szie dcs cmd
+	 * client reply len is directly configure through
+	 * RDPKTLN register (0x0404)
+	 */
+	pinfo->mipi.no_max_pkt_size = 1;
+	pinfo->mipi.force_clk_lane_hs = 1;
+
+	ret = mipi_tc358764_dsi2lvds_register(pinfo, MIPI_DSI_PRIM,
+					      MIPI_DSI_PANEL_WXGA);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_chimei_wxga_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Chimei WXGA LVDS Panel driver");
+MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
new file mode 100644
index 0000000..b4fb930
--- /dev/null
+++ b/drivers/video/msm/mipi_dsi.c
@@ -0,0 +1,614 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/clk.h>
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mdp.h"
+#include "mdp4.h"
+
+u32 dsi_irq;
+u32 esc_byte_ratio;
+
+static boolean tlmm_settings = FALSE;
+
+static int mipi_dsi_probe(struct platform_device *pdev);
+static int mipi_dsi_remove(struct platform_device *pdev);
+
+static int mipi_dsi_off(struct platform_device *pdev);
+static int mipi_dsi_on(struct platform_device *pdev);
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+static struct mipi_dsi_platform_data *mipi_dsi_pdata;
+
+static int vsync_gpio = -1;
+
+static struct platform_driver mipi_dsi_driver = {
+	.probe = mipi_dsi_probe,
+	.remove = mipi_dsi_remove,
+	.shutdown = NULL,
+	.driver = {
+		   .name = "mipi_dsi",
+		   },
+};
+
+struct device dsi_dev;
+
+static int mipi_dsi_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_data_type *mfd;
+	struct msm_panel_info *pinfo;
+
+	mfd = platform_get_drvdata(pdev);
+	pinfo = &mfd->panel_info;
+
+	if (mdp_rev >= MDP_REV_41)
+		mutex_lock(&mfd->dma->ov_mutex);
+	else
+		down(&mfd->dma->mutex);
+
+	mdp4_overlay_dsi_state_set(ST_DSI_SUSPEND);
+
+	/*
+	 * Desctiption: change to DSI_CMD_MODE since it needed to
+	 * tx DCS dsiplay off comamnd to panel
+	 */
+	mipi_dsi_op_mode_config(DSI_CMD_MODE);
+
+	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
+		if (pinfo->lcd.vsync_enable) {
+			if (pinfo->lcd.hw_vsync_mode && vsync_gpio >= 0) {
+				if (MDP_REV_303 != mdp_rev)
+					gpio_free(vsync_gpio);
+			}
+			mipi_dsi_set_tear_off(mfd);
+		}
+	}
+
+	ret = panel_next_off(pdev);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(0);
+#endif
+
+	spin_lock_bh(&dsi_clk_lock);
+	mipi_dsi_clk_disable();
+
+	/* disbale dsi engine */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0000, 0);
+
+	mipi_dsi_phy_ctrl(0);
+
+	mipi_dsi_ahb_ctrl(0);
+	spin_unlock_bh(&dsi_clk_lock);
+
+	mipi_dsi_unprepare_clocks();
+	if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save)
+		mipi_dsi_pdata->dsi_power_save(0);
+
+	if (mdp_rev >= MDP_REV_41)
+		mutex_unlock(&mfd->dma->ov_mutex);
+	else
+		up(&mfd->dma->mutex);
+
+	pr_debug("%s-:\n", __func__);
+
+	return ret;
+}
+
+static int mipi_dsi_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	u32 clk_rate;
+	struct msm_fb_data_type *mfd;
+	struct fb_info *fbi;
+	struct fb_var_screeninfo *var;
+	struct msm_panel_info *pinfo;
+	struct mipi_panel_info *mipi;
+	u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height;
+	u32 ystride, bpp, data;
+	u32 dummy_xres, dummy_yres;
+	int target_type = 0;
+
+	mfd = platform_get_drvdata(pdev);
+	fbi = mfd->fbi;
+	var = &fbi->var;
+	pinfo = &mfd->panel_info;
+	esc_byte_ratio = pinfo->mipi.esc_byte_ratio;
+
+	if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save)
+		mipi_dsi_pdata->dsi_power_save(1);
+
+	cont_splash_clk_ctrl(0);
+	mipi_dsi_prepare_clocks();
+
+	mipi_dsi_ahb_ctrl(1);
+
+	clk_rate = mfd->fbi->var.pixclock;
+	clk_rate = min(clk_rate, mfd->panel_info.clk_max);
+
+	mipi_dsi_phy_ctrl(1);
+
+	if (mdp_rev == MDP_REV_42 && mipi_dsi_pdata)
+		target_type = mipi_dsi_pdata->target_type;
+
+	mipi_dsi_phy_init(0, &(mfd->panel_info), target_type);
+
+	mipi_dsi_clk_enable();
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x114, 1);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x114, 0);
+
+	hbp = var->left_margin;
+	hfp = var->right_margin;
+	vbp = var->upper_margin;
+	vfp = var->lower_margin;
+	hspw = var->hsync_len;
+	vspw = var->vsync_len;
+	width = mfd->panel_info.xres;
+	height = mfd->panel_info.yres;
+
+	mipi  = &mfd->panel_info.mipi;
+	if (mfd->panel_info.type == MIPI_VIDEO_PANEL) {
+		dummy_xres = mfd->panel_info.lcdc.xres_pad;
+		dummy_yres = mfd->panel_info.lcdc.yres_pad;
+
+		if (mdp_rev >= MDP_REV_41) {
+			MIPI_OUTP(MIPI_DSI_BASE + 0x20,
+				((hspw + hbp + width + dummy_xres) << 16 |
+				(hspw + hbp)));
+			MIPI_OUTP(MIPI_DSI_BASE + 0x24,
+				((vspw + vbp + height + dummy_yres) << 16 |
+				(vspw + vbp)));
+			MIPI_OUTP(MIPI_DSI_BASE + 0x28,
+				(vspw + vbp + height + dummy_yres +
+					vfp - 1) << 16 | (hspw + hbp +
+					width + dummy_xres + hfp - 1));
+		} else {
+			/* DSI_LAN_SWAP_CTRL */
+			MIPI_OUTP(MIPI_DSI_BASE + 0x00ac, mipi->dlane_swap);
+
+			MIPI_OUTP(MIPI_DSI_BASE + 0x20,
+				((hbp + width + dummy_xres) << 16 | (hbp)));
+			MIPI_OUTP(MIPI_DSI_BASE + 0x24,
+				((vbp + height + dummy_yres) << 16 | (vbp)));
+			MIPI_OUTP(MIPI_DSI_BASE + 0x28,
+				(vbp + height + dummy_yres + vfp) << 16 |
+					(hbp + width + dummy_xres + hfp));
+		}
+
+		MIPI_OUTP(MIPI_DSI_BASE + 0x2c, (hspw << 16));
+		MIPI_OUTP(MIPI_DSI_BASE + 0x30, 0);
+		MIPI_OUTP(MIPI_DSI_BASE + 0x34, (vspw << 16));
+
+	} else {		/* command mode */
+		if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888)
+			bpp = 3;
+		else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB666)
+			bpp = 3;
+		else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565)
+			bpp = 2;
+		else
+			bpp = 3;	/* Default format set to RGB888 */
+
+		ystride = width * bpp + 1;
+
+		/* DSI_COMMAND_MODE_MDP_STREAM_CTRL */
+		data = (ystride << 16) | (mipi->vc << 8) | DTYPE_DCS_LWRITE;
+		MIPI_OUTP(MIPI_DSI_BASE + 0x5c, data);
+		MIPI_OUTP(MIPI_DSI_BASE + 0x54, data);
+
+		/* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */
+		data = height << 16 | width;
+		MIPI_OUTP(MIPI_DSI_BASE + 0x60, data);
+		MIPI_OUTP(MIPI_DSI_BASE + 0x58, data);
+	}
+
+	mipi_dsi_host_init(mipi);
+
+	if (mipi->force_clk_lane_hs) {
+		u32 tmp;
+
+		tmp = MIPI_INP(MIPI_DSI_BASE + 0xA8);
+		tmp |= (1<<28);
+		MIPI_OUTP(MIPI_DSI_BASE + 0xA8, tmp);
+		wmb();
+	}
+
+	if (mdp_rev >= MDP_REV_41)
+		mutex_lock(&mfd->dma->ov_mutex);
+	else
+		down(&mfd->dma->mutex);
+
+	ret = panel_next_on(pdev);
+
+	mipi_dsi_op_mode_config(mipi->mode);
+
+	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
+		if (pinfo->lcd.vsync_enable) {
+			if (pinfo->lcd.hw_vsync_mode && vsync_gpio >= 0) {
+				if (mdp_rev >= MDP_REV_41) {
+					if (gpio_request(vsync_gpio,
+						"MDP_VSYNC") == 0)
+						gpio_direction_input(
+							vsync_gpio);
+					else
+						pr_err("%s: unable to \
+							request gpio=%d\n",
+							__func__, vsync_gpio);
+				} else if (mdp_rev == MDP_REV_303) {
+					if (!tlmm_settings && gpio_request(
+						vsync_gpio, "MDP_VSYNC") == 0) {
+						ret = gpio_tlmm_config(
+							GPIO_CFG(
+							vsync_gpio, 1,
+							GPIO_CFG_INPUT,
+							GPIO_CFG_PULL_DOWN,
+							GPIO_CFG_2MA),
+							GPIO_CFG_ENABLE);
+
+						if (ret) {
+							pr_err(
+							"%s: unable to config \
+							tlmm = %d\n",
+							__func__, vsync_gpio);
+						}
+						tlmm_settings = TRUE;
+
+						gpio_direction_input(
+							vsync_gpio);
+					} else {
+						if (!tlmm_settings) {
+							pr_err(
+							"%s: unable to request \
+							gpio=%d\n",
+							__func__, vsync_gpio);
+						}
+					}
+				}
+			}
+			mipi_dsi_set_tear_on(mfd);
+		}
+	}
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(2);
+#endif
+
+	mdp4_overlay_dsi_state_set(ST_DSI_RESUME);
+
+	if (mdp_rev >= MDP_REV_41)
+		mutex_unlock(&mfd->dma->ov_mutex);
+	else
+		up(&mfd->dma->mutex);
+
+	pr_debug("%s-:\n", __func__);
+
+	return ret;
+}
+
+
+static int mipi_dsi_resource_initialized;
+
+static int mipi_dsi_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct fb_info *fbi;
+	struct msm_panel_info *pinfo;
+	struct mipi_panel_info *mipi;
+	struct platform_device *mdp_dev = NULL;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc;
+	uint8 lanes = 0, bpp;
+	uint32 h_period, v_period, dsi_pclk_rate;
+
+	resource_size_t size ;
+
+	if ((pdev->id == 1) && (pdev->num_resources >= 0)) {
+		mipi_dsi_pdata = pdev->dev.platform_data;
+
+		size =  resource_size(&pdev->resource[0]);
+		mipi_dsi_base =  ioremap(pdev->resource[0].start, size);
+
+		MSM_FB_INFO("mipi_dsi base phy_addr = 0x%x virt = 0x%x\n",
+				pdev->resource[0].start, (int) mipi_dsi_base);
+
+		if (!mipi_dsi_base)
+			return -ENOMEM;
+
+		if (mdp_rev >= MDP_REV_41) {
+			mmss_sfpb_base =  ioremap(MMSS_SFPB_BASE_PHY, 0x100);
+			MSM_FB_INFO("mmss_sfpb  base phy_addr = 0x%x,"
+				"virt = 0x%x\n", MMSS_SFPB_BASE_PHY,
+				(int) mmss_sfpb_base);
+
+			if (!mmss_sfpb_base)
+				return -ENOMEM;
+		}
+
+		dsi_irq = platform_get_irq(pdev, 0);
+		if (dsi_irq < 0) {
+			pr_err("mipi_dsi: can not get mdp irq\n");
+			return -ENOMEM;
+		}
+
+		rc = request_irq(dsi_irq, mipi_dsi_isr, IRQF_DISABLED,
+						"MIPI_DSI", 0);
+		if (rc) {
+			pr_err("mipi_dsi_host request_irq() failed!\n");
+			return rc;
+		}
+
+		disable_irq(dsi_irq);
+
+		if (mdp_rev == MDP_REV_42 && mipi_dsi_pdata &&
+			mipi_dsi_pdata->target_type == 1) {
+			/* Target type is 1 for device with (De)serializer
+			 * 0x4f00000 is the base for TV Encoder.
+			 * Unused Offset 0x1000 is used for
+			 * (de)serializer on emulation platform
+			 */
+			periph_base = ioremap(MMSS_SERDES_BASE_PHY, 0x100);
+
+			if (periph_base) {
+				pr_debug("periph_base %p\n", periph_base);
+				writel(0x4, periph_base + 0x28);
+				writel(0xc, periph_base + 0x28);
+			} else {
+				pr_err("periph_base is NULL\n");
+				free_irq(dsi_irq, 0);
+				return -ENOMEM;
+			}
+		}
+
+		if (mipi_dsi_pdata) {
+			vsync_gpio = mipi_dsi_pdata->vsync_gpio;
+			pr_debug("%s: vsync_gpio=%d\n", __func__, vsync_gpio);
+
+			if (mdp_rev == MDP_REV_303 &&
+				mipi_dsi_pdata->dsi_client_reset) {
+				if (mipi_dsi_pdata->dsi_client_reset())
+					pr_err("%s: DSI Client Reset failed!\n",
+						__func__);
+				else
+					pr_debug("%s: DSI Client Reset success\n",
+						__func__);
+			}
+		}
+
+		if (mipi_dsi_clk_init(pdev))
+			return -EPERM;
+
+		if (mipi_dsi_pdata->splash_is_enabled &&
+			!mipi_dsi_pdata->splash_is_enabled()) {
+			mipi_dsi_ahb_ctrl(1);
+			MIPI_OUTP(MIPI_DSI_BASE + 0x118, 0);
+			MIPI_OUTP(MIPI_DSI_BASE + 0x0, 0);
+			MIPI_OUTP(MIPI_DSI_BASE + 0x200, 0);
+			mipi_dsi_ahb_ctrl(0);
+		}
+		mipi_dsi_resource_initialized = 1;
+
+		return 0;
+	}
+
+	if (!mipi_dsi_resource_initialized)
+		return -EPERM;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	if (!mfd->cont_splash_done)
+		cont_splash_clk_ctrl(1);
+
+	mdp_dev = platform_device_alloc("mdp", pdev->id);
+	if (!mdp_dev)
+		return -ENOMEM;
+
+	/*
+	 * link to the latest pdev
+	 */
+	mfd->pdev = mdp_dev;
+
+	/*
+	 * alloc panel device data
+	 */
+	if (platform_device_add_data
+	    (mdp_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		pr_err("mipi_dsi_probe: platform_device_add_data failed!\n");
+		platform_device_put(mdp_dev);
+		return -ENOMEM;
+	}
+	/*
+	 * data chain
+	 */
+	pdata = mdp_dev->dev.platform_data;
+	pdata->on = mipi_dsi_on;
+	pdata->off = mipi_dsi_off;
+	pdata->next = pdev;
+
+	/*
+	 * get/set panel specific fb info
+	 */
+	mfd->panel_info = pdata->panel_info;
+	pinfo = &mfd->panel_info;
+
+	if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
+		mfd->dest = DISPLAY_LCDC;
+	else
+		mfd->dest = DISPLAY_LCD;
+
+	if (mdp_rev == MDP_REV_303 &&
+		mipi_dsi_pdata->get_lane_config) {
+		if (mipi_dsi_pdata->get_lane_config() != 2) {
+			pr_info("Changing to DSI Single Mode Configuration\n");
+#ifdef CONFIG_FB_MSM_MDP303
+			update_lane_config(pinfo);
+#endif
+		}
+	}
+
+	if (mfd->index == 0)
+		mfd->fb_imgType = MSMFB_DEFAULT_TYPE;
+	else
+		mfd->fb_imgType = MDP_RGB_565;
+
+	fbi = mfd->fbi;
+	fbi->var.pixclock = mfd->panel_info.clk_rate;
+	fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
+	fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
+	fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
+	fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch;
+	fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width;
+	fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width;
+
+	h_period = ((mfd->panel_info.lcdc.h_pulse_width)
+			+ (mfd->panel_info.lcdc.h_back_porch)
+			+ (mfd->panel_info.xres)
+			+ (mfd->panel_info.lcdc.h_front_porch));
+
+	v_period = ((mfd->panel_info.lcdc.v_pulse_width)
+			+ (mfd->panel_info.lcdc.v_back_porch)
+			+ (mfd->panel_info.yres)
+			+ (mfd->panel_info.lcdc.v_front_porch));
+
+	mipi  = &mfd->panel_info.mipi;
+
+	if (mipi->data_lane3)
+		lanes += 1;
+	if (mipi->data_lane2)
+		lanes += 1;
+	if (mipi->data_lane1)
+		lanes += 1;
+	if (mipi->data_lane0)
+		lanes += 1;
+
+	if ((mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888)
+	    || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB888)
+	    || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB666_LOOSE))
+		bpp = 3;
+	else if ((mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565)
+		 || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB565))
+		bpp = 2;
+	else
+		bpp = 3;		/* Default format set to RGB888 */
+
+	if (mfd->panel_info.type == MIPI_VIDEO_PANEL &&
+		!mfd->panel_info.clk_rate) {
+		h_period += mfd->panel_info.lcdc.xres_pad;
+		v_period += mfd->panel_info.lcdc.yres_pad;
+
+		if (lanes > 0) {
+			mfd->panel_info.clk_rate =
+			((h_period * v_period * (mipi->frame_rate) * bpp * 8)
+			   / lanes);
+		} else {
+			pr_err("%s: forcing mipi_dsi lanes to 1\n", __func__);
+			mfd->panel_info.clk_rate =
+				(h_period * v_period
+					 * (mipi->frame_rate) * bpp * 8);
+		}
+	}
+	pll_divider_config.clk_rate = mfd->panel_info.clk_rate;
+
+	rc = mipi_dsi_clk_div_config(bpp, lanes, &dsi_pclk_rate);
+	if (rc)
+		goto mipi_dsi_probe_err;
+
+	if ((dsi_pclk_rate < 3300000) || (dsi_pclk_rate > 103300000))
+		dsi_pclk_rate = 35000000;
+	mipi->dsi_pclk_rate = dsi_pclk_rate;
+
+	/*
+	 * set driver data
+	 */
+	platform_set_drvdata(mdp_dev, mfd);
+
+	/*
+	 * register in mdp driver
+	 */
+	rc = platform_device_add(mdp_dev);
+	if (rc)
+		goto mipi_dsi_probe_err;
+
+	pdev_list[pdev_list_cnt++] = pdev;
+
+return 0;
+
+mipi_dsi_probe_err:
+	platform_device_put(mdp_dev);
+	return rc;
+}
+
+static int mipi_dsi_remove(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+	iounmap(mipi_dsi_base);
+	return 0;
+}
+
+static int mipi_dsi_register_driver(void)
+{
+	return platform_driver_register(&mipi_dsi_driver);
+}
+
+static int __init mipi_dsi_driver_init(void)
+{
+	int ret;
+
+	mipi_dsi_init();
+
+	ret = mipi_dsi_register_driver();
+
+	device_initialize(&dsi_dev);
+
+	if (ret) {
+		pr_err("mipi_dsi_register_driver() failed!\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+module_init(mipi_dsi_driver_init);
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
new file mode 100644
index 0000000..2f691cf
--- /dev/null
+++ b/drivers/video/msm/mipi_dsi.h
@@ -0,0 +1,352 @@
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MIPI_DSI_H
+#define MIPI_DSI_H
+
+#include <mach/scm-io.h>
+#include <linux/list.h>
+
+#ifdef BIT
+#undef BIT
+#endif
+
+#define BIT(x)  (1<<(x))
+
+#define MMSS_CC_BASE_PHY 0x04000000	/* mmss clcok control */
+#define MMSS_SFPB_BASE_PHY 0x05700000	/* mmss SFPB CFG */
+#define MMSS_SERDES_BASE_PHY 0x04f01000 /* mmss (De)Serializer CFG */
+
+#define MIPI_DSI_BASE mipi_dsi_base
+
+#define MIPI_OUTP(addr, data) writel((data), (addr))
+#define MIPI_INP(addr) readl(addr)
+
+#ifdef CONFIG_MSM_SECURE_IO
+#define MIPI_OUTP_SECURE(addr, data) secure_writel((data), (addr))
+#define MIPI_INP_SECURE(addr) secure_readl(addr)
+#else
+#define MIPI_OUTP_SECURE(addr, data) writel((data), (addr))
+#define MIPI_INP_SECURE(addr) readl(addr)
+#endif
+
+#define MIPI_DSI_PRIM 1
+#define MIPI_DSI_SECD 2
+
+#define MIPI_DSI_PANEL_VGA	0
+#define MIPI_DSI_PANEL_WVGA	1
+#define MIPI_DSI_PANEL_WVGA_PT	2
+#define MIPI_DSI_PANEL_FWVGA_PT	3
+#define MIPI_DSI_PANEL_WSVGA_PT	4
+#define MIPI_DSI_PANEL_QHD_PT 5
+#define MIPI_DSI_PANEL_WXGA	6
+#define MIPI_DSI_PANEL_WUXGA	7
+#define MIPI_DSI_PANEL_720P_PT	8
+#define DSI_PANEL_MAX	8
+
+enum {		/* mipi dsi panel */
+	DSI_VIDEO_MODE,
+	DSI_CMD_MODE,
+};
+
+enum {
+	ST_DSI_CLK_OFF,
+	ST_DSI_SUSPEND,
+	ST_DSI_RESUME,
+	ST_DSI_PLAYING,
+	ST_DSI_NUM
+};
+
+enum {
+	EV_DSI_UPDATE,
+	EV_DSI_DONE,
+	EV_DSI_TOUT,
+	EV_DSI_NUM
+};
+
+enum {
+	LANDSCAPE = 1,
+	PORTRAIT = 2,
+};
+
+enum dsi_trigger_type {
+	DSI_CMD_MODE_DMA,
+	DSI_CMD_MODE_MDP,
+};
+
+#define DSI_NON_BURST_SYNCH_PULSE	0
+#define DSI_NON_BURST_SYNCH_EVENT	1
+#define DSI_BURST_MODE			2
+
+
+#define DSI_RGB_SWAP_RGB	0
+#define DSI_RGB_SWAP_RBG	1
+#define DSI_RGB_SWAP_BGR	2
+#define DSI_RGB_SWAP_BRG	3
+#define DSI_RGB_SWAP_GRB	4
+#define DSI_RGB_SWAP_GBR	5
+
+#define DSI_VIDEO_DST_FORMAT_RGB565		0
+#define DSI_VIDEO_DST_FORMAT_RGB666		1
+#define DSI_VIDEO_DST_FORMAT_RGB666_LOOSE	2
+#define DSI_VIDEO_DST_FORMAT_RGB888		3
+
+#define DSI_CMD_DST_FORMAT_RGB111	0
+#define DSI_CMD_DST_FORMAT_RGB332	3
+#define DSI_CMD_DST_FORMAT_RGB444	4
+#define DSI_CMD_DST_FORMAT_RGB565	6
+#define DSI_CMD_DST_FORMAT_RGB666	7
+#define DSI_CMD_DST_FORMAT_RGB888	8
+
+#define DSI_INTR_ERROR_MASK		BIT(25)
+#define DSI_INTR_ERROR			BIT(24)
+#define DSI_INTR_VIDEO_DONE_MASK	BIT(17)
+#define DSI_INTR_VIDEO_DONE		BIT(16)
+#define DSI_INTR_CMD_MDP_DONE_MASK	BIT(9)
+#define DSI_INTR_CMD_MDP_DONE		BIT(8)
+#define DSI_INTR_CMD_DMA_DONE_MASK	BIT(1)
+#define DSI_INTR_CMD_DMA_DONE		BIT(0)
+
+#define DSI_MDP_TERM	BIT(8)
+#define DSI_CMD_TERM	BIT(0)
+
+#define DSI_CMD_TRIGGER_NONE		0x0	/* mdp trigger */
+#define DSI_CMD_TRIGGER_TE		0x02
+#define DSI_CMD_TRIGGER_SW		0x04
+#define DSI_CMD_TRIGGER_SW_SEOF		0x05	/* cmd dma only */
+#define DSI_CMD_TRIGGER_SW_TE		0x06
+
+extern struct device dsi_dev;
+extern int mipi_dsi_clk_on;
+extern u32 dsi_irq;
+extern u32 esc_byte_ratio;
+
+extern void  __iomem *periph_base;
+extern char *mmss_cc_base;	/* mutimedia sub system clock control */
+extern char *mmss_sfpb_base;	/* mutimedia sub system sfpb */
+
+struct dsiphy_pll_divider_config {
+	u32 clk_rate;
+	u32 fb_divider;
+	u32 ref_divider_ratio;
+	u32 bit_clk_divider;	/* oCLK1 */
+	u32 byte_clk_divider;	/* oCLK2 */
+	u32 dsi_clk_divider;	/* oCLK3 */
+};
+
+extern struct dsiphy_pll_divider_config pll_divider_config;
+
+struct dsi_clk_mnd_table {
+	uint8 lanes;
+	uint8 bpp;
+	uint8 dsiclk_div;
+	uint8 dsiclk_m;
+	uint8 dsiclk_n;
+	uint8 dsiclk_d;
+	uint8 pclk_m;
+	uint8 pclk_n;
+	uint8 pclk_d;
+};
+
+static const struct dsi_clk_mnd_table mnd_table[] = {
+	{ 1, 2, 8, 1, 1, 0, 1,  2, 1},
+	{ 1, 3, 8, 1, 1, 0, 1,  3, 2},
+	{ 2, 2, 4, 1, 1, 0, 1,  2, 1},
+	{ 2, 3, 4, 1, 1, 0, 1,  3, 2},
+	{ 3, 2, 1, 3, 8, 4, 3, 16, 8},
+	{ 3, 3, 1, 3, 8, 4, 1,  8, 4},
+	{ 4, 2, 2, 1, 1, 0, 1,  2, 1},
+	{ 4, 3, 2, 1, 1, 0, 1,  3, 2},
+};
+
+struct dsi_clk_desc {
+	uint32 src;
+	uint32 m;
+	uint32 n;
+	uint32 d;
+	uint32 mnd_mode;
+	uint32 pre_div_func;
+};
+
+#define DSI_HOST_HDR_SIZE	4
+#define DSI_HDR_LAST		BIT(31)
+#define DSI_HDR_LONG_PKT	BIT(30)
+#define DSI_HDR_BTA		BIT(29)
+#define DSI_HDR_VC(vc)		(((vc) & 0x03) << 22)
+#define DSI_HDR_DTYPE(dtype)	(((dtype) & 0x03f) << 16)
+#define DSI_HDR_DATA2(data)	(((data) & 0x0ff) << 8)
+#define DSI_HDR_DATA1(data)	((data) & 0x0ff)
+#define DSI_HDR_WC(wc)		((wc) & 0x0ffff)
+
+#define DSI_BUF_SIZE	64
+#define MIPI_DSI_MRPS	0x04	/* Maximum Return Packet Size */
+
+#define MIPI_DSI_LEN 8 /* 4 x 4 - 6 - 2, bytes dcs header+crc-align  */
+
+struct dsi_buf {
+	uint32 *hdr;	/* dsi host header */
+	char *start;	/* buffer start addr */
+	char *end;	/* buffer end addr */
+	int size;	/* size of buffer */
+	char *data;	/* buffer */
+	int len;	/* data length */
+	dma_addr_t dmap; /* mapped dma addr */
+};
+
+/* dcs read/write */
+#define DTYPE_DCS_WRITE		0x05	/* short write, 0 parameter */
+#define DTYPE_DCS_WRITE1	0x15	/* short write, 1 parameter */
+#define DTYPE_DCS_READ		0x06	/* read */
+#define DTYPE_DCS_LWRITE	0x39	/* long write */
+
+/* generic read/write */
+#define DTYPE_GEN_WRITE		0x03	/* short write, 0 parameter */
+#define DTYPE_GEN_WRITE1	0x13	/* short write, 1 parameter */
+#define DTYPE_GEN_WRITE2	0x23	/* short write, 2 parameter */
+#define DTYPE_GEN_LWRITE	0x29	/* long write */
+#define DTYPE_GEN_READ		0x04	/* long read, 0 parameter */
+#define DTYPE_GEN_READ1		0x14	/* long read, 1 parameter */
+#define DTYPE_GEN_READ2		0x24	/* long read, 2 parameter */
+
+#define DTYPE_TEAR_ON		0x35	/* set tear on */
+#define DTYPE_MAX_PKTSIZE	0x37	/* set max packet size */
+#define DTYPE_NULL_PKT		0x09	/* null packet, no data */
+#define DTYPE_BLANK_PKT		0x19	/* blankiing packet, no data */
+
+#define DTYPE_CM_ON		0x02	/* color mode off */
+#define DTYPE_CM_OFF		0x12	/* color mode on */
+#define DTYPE_PERIPHERAL_OFF	0x22
+#define DTYPE_PERIPHERAL_ON	0x32
+
+/*
+ * dcs response
+ */
+#define DTYPE_ACK_ERR_RESP      0x02
+#define DTYPE_EOT_RESP          0x08    /* end of tx */
+#define DTYPE_GEN_READ1_RESP    0x11    /* 1 parameter, short */
+#define DTYPE_GEN_READ2_RESP    0x12    /* 2 parameter, short */
+#define DTYPE_GEN_LREAD_RESP    0x1a
+#define DTYPE_DCS_LREAD_RESP    0x1c
+#define DTYPE_DCS_READ1_RESP    0x21    /* 1 parameter, short */
+#define DTYPE_DCS_READ2_RESP    0x22    /* 2 parameter, short */
+
+struct dsi_cmd_desc {
+	int dtype;
+	int last;
+	int vc;
+	int ack;	/* ask ACK from peripheral */
+	int wait;
+	int dlen;
+	char *payload;
+};
+
+typedef void (*kickoff_act)(void *);
+
+struct dsi_kickoff_action {
+	struct list_head act_entry;
+	kickoff_act	action;
+	void *data;
+};
+
+
+#define CMD_REQ_MAX	4
+
+typedef void (*fxn)(u32 data);
+
+#define CMD_REQ_RX	0x0001
+#define CMD_REQ_COMMIT 0x0002
+#define CMD_REQ_NO_MAX_PKT_SIZE 0x0008
+
+struct dcs_cmd_req {
+	struct dsi_cmd_desc *cmds;
+	int cmds_cnt;
+	u32 flags;
+	int rlen;	/* rx length */
+	fxn cb;
+};
+
+struct dcs_cmd_list {
+	int put;
+	int get;
+	int tot;
+	struct dcs_cmd_req list[CMD_REQ_MAX];
+};
+
+
+char *mipi_dsi_buf_reserve_hdr(struct dsi_buf *dp, int hlen);
+char *mipi_dsi_buf_init(struct dsi_buf *dp);
+void mipi_dsi_init(void);
+void mipi_dsi_lane_cfg(void);
+void mipi_dsi_bist_ctrl(void);
+int mipi_dsi_buf_alloc(struct dsi_buf *, int size);
+int mipi_dsi_cmd_dma_add(struct dsi_buf *dp, struct dsi_cmd_desc *cm);
+int mipi_dsi_cmds_tx(struct dsi_buf *dp, struct dsi_cmd_desc *cmds, int cnt);
+
+int mipi_dsi_cmd_dma_tx(struct dsi_buf *dp);
+int mipi_dsi_cmd_reg_tx(uint32 data);
+int mipi_dsi_cmds_rx(struct msm_fb_data_type *mfd,
+			struct dsi_buf *tp, struct dsi_buf *rp,
+			struct dsi_cmd_desc *cmds, int len);
+int mipi_dsi_cmd_dma_rx(struct dsi_buf *tp, int rlen);
+void mipi_dsi_host_init(struct mipi_panel_info *pinfo);
+void mipi_dsi_op_mode_config(int mode);
+void mipi_dsi_cmd_mode_ctrl(int enable);
+void mdp4_dsi_cmd_trigger(void);
+void mipi_dsi_cmd_mdp_start(void);
+int mipi_dsi_ctrl_lock(int mdp);
+int mipi_dsi_ctrl_lock_query(void);
+void mipi_dsi_cmd_bta_sw_trigger(void);
+void mipi_dsi_ack_err_status(void);
+void mipi_dsi_set_tear_on(struct msm_fb_data_type *mfd);
+void mipi_dsi_set_tear_off(struct msm_fb_data_type *mfd);
+void mipi_dsi_set_backlight(struct msm_fb_data_type *mfd, int level);
+void mipi_dsi_cmd_backlight_tx(struct dsi_buf *dp);
+void mipi_dsi_clk_enable(void);
+void mipi_dsi_clk_disable(void);
+void mipi_dsi_pre_kickoff_action(void);
+void mipi_dsi_post_kickoff_action(void);
+void mipi_dsi_pre_kickoff_add(struct dsi_kickoff_action *act);
+void mipi_dsi_post_kickoff_add(struct dsi_kickoff_action *act);
+void mipi_dsi_pre_kickoff_del(struct dsi_kickoff_action *act);
+void mipi_dsi_post_kickoff_del(struct dsi_kickoff_action *act);
+void mipi_dsi_controller_cfg(int enable);
+void mipi_dsi_sw_reset(void);
+void mipi_dsi_mdp_busy_wait(struct msm_fb_data_type *mfd);
+
+irqreturn_t mipi_dsi_isr(int irq, void *ptr);
+
+void mipi_set_tx_power_mode(int mode);
+void mipi_dsi_phy_ctrl(int on);
+void mipi_dsi_phy_init(int panel_ndx, struct msm_panel_info const *panel_info,
+	int target_type);
+int mipi_dsi_clk_div_config(uint8 bpp, uint8 lanes,
+			    uint32 *expected_dsi_pclk);
+int mipi_dsi_clk_init(struct platform_device *pdev);
+void mipi_dsi_clk_deinit(struct device *dev);
+void mipi_dsi_prepare_clocks(void);
+void mipi_dsi_unprepare_clocks(void);
+void mipi_dsi_ahb_ctrl(u32 enable);
+void cont_splash_clk_ctrl(int enable);
+void mipi_dsi_turn_on_clks(void);
+void mipi_dsi_turn_off_clks(void);
+void mipi_dsi_clk_cfg(int on);
+
+int mipi_dsi_cmdlist_put(struct dcs_cmd_req *cmdreq);
+struct dcs_cmd_req *mipi_dsi_cmdlist_get(void);
+void mipi_dsi_cmdlist_commit(int from_mdp);
+
+#ifdef CONFIG_FB_MSM_MDP303
+void update_lane_config(struct msm_panel_info *pinfo);
+#endif
+
+#endif /* MIPI_DSI_H */
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
new file mode 100644
index 0000000..e495112
--- /dev/null
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -0,0 +1,1770 @@
+
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/clk.h>
+#include <mach/dma.h>
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mdp.h"
+#include "mdp4.h"
+
+static struct completion dsi_dma_comp;
+static struct completion dsi_mdp_comp;
+static struct dsi_buf dsi_tx_buf;
+static struct dsi_buf dsi_rx_buf;
+static spinlock_t dsi_irq_lock;
+static spinlock_t dsi_mdp_lock;
+spinlock_t dsi_clk_lock;
+static int dsi_ctrl_lock;
+static int dsi_mdp_busy;
+static struct mutex cmd_mutex;
+
+static struct list_head pre_kickoff_list;
+static struct list_head post_kickoff_list;
+
+enum {
+	STAT_DSI_START,
+	STAT_DSI_ERROR,
+	STAT_DSI_CMD,
+	STAT_DSI_MDP
+};
+
+struct dcs_cmd_list	cmdlist;
+
+#ifdef CONFIG_FB_MSM_MDP40
+void mipi_dsi_mdp_stat_inc(int which)
+{
+	switch (which) {
+	case STAT_DSI_START:
+		mdp4_stat.dsi_mdp_start++;
+		break;
+	case STAT_DSI_ERROR:
+		mdp4_stat.intr_dsi_err++;
+		break;
+	case STAT_DSI_CMD:
+		mdp4_stat.intr_dsi_cmd++;
+		break;
+	case STAT_DSI_MDP:
+		mdp4_stat.intr_dsi_mdp++;
+		break;
+	default:
+		break;
+	}
+}
+#else
+void mipi_dsi_mdp_stat_inc(int which)
+{
+}
+#endif
+
+void mipi_dsi_init(void)
+{
+	init_completion(&dsi_dma_comp);
+	init_completion(&dsi_mdp_comp);
+	mipi_dsi_buf_alloc(&dsi_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&dsi_rx_buf, DSI_BUF_SIZE);
+	spin_lock_init(&dsi_irq_lock);
+	spin_lock_init(&dsi_mdp_lock);
+	spin_lock_init(&dsi_clk_lock);
+	mutex_init(&cmd_mutex);
+
+	INIT_LIST_HEAD(&pre_kickoff_list);
+	INIT_LIST_HEAD(&post_kickoff_list);
+}
+
+
+static u32 dsi_irq_mask;
+
+void mipi_dsi_enable_irq(u32 term)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dsi_irq_lock, flags);
+	if (dsi_irq_mask & term) {
+		spin_unlock_irqrestore(&dsi_irq_lock, flags);
+		return;
+	}
+	if (dsi_irq_mask == 0) {
+		enable_irq(dsi_irq);
+		pr_debug("%s: IRQ Enable, mask=%x term=%x\n",
+				__func__, (int)dsi_irq_mask, (int)term);
+	}
+	dsi_irq_mask |= term;
+	spin_unlock_irqrestore(&dsi_irq_lock, flags);
+}
+
+void mipi_dsi_disable_irq(u32 term)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dsi_irq_lock, flags);
+	if (!(dsi_irq_mask & term)) {
+		spin_unlock_irqrestore(&dsi_irq_lock, flags);
+		return;
+	}
+	dsi_irq_mask &= ~term;
+	if (dsi_irq_mask == 0) {
+		disable_irq(dsi_irq);
+		pr_debug("%s: IRQ Disable, mask=%x term=%x\n",
+				__func__, (int)dsi_irq_mask, (int)term);
+	}
+	spin_unlock_irqrestore(&dsi_irq_lock, flags);
+}
+
+/*
+ * mipi_dsi_disale_irq_nosync() should be called
+ * from interrupt context
+ */
+void mipi_dsi_disable_irq_nosync(u32 term)
+{
+	spin_lock(&dsi_irq_lock);
+	if (!(dsi_irq_mask & term)) {
+		spin_unlock(&dsi_irq_lock);
+		return;
+	}
+	dsi_irq_mask &= ~term;
+	if (dsi_irq_mask == 0) {
+		disable_irq_nosync(dsi_irq);
+		pr_debug("%s: IRQ Disable, mask=%x term=%x\n",
+				__func__, (int)dsi_irq_mask, (int)term);
+	}
+	spin_unlock(&dsi_irq_lock);
+}
+
+void mipi_dsi_clk_cfg(int on)
+{
+	unsigned long flags;
+	static int dsi_clk_cnt;
+
+	spin_lock_irqsave(&mdp_spin_lock, flags);
+	if (on) {
+		if (dsi_clk_cnt == 0) {
+			mipi_dsi_ahb_ctrl(1);
+			mipi_dsi_clk_enable();
+		}
+		dsi_clk_cnt++;
+	} else {
+		if (dsi_clk_cnt) {
+			dsi_clk_cnt--;
+			if (dsi_clk_cnt == 0) {
+				mipi_dsi_clk_disable();
+				mipi_dsi_ahb_ctrl(0);
+			}
+		}
+	}
+	spin_unlock_irqrestore(&mdp_spin_lock, flags);
+}
+
+void mipi_dsi_turn_on_clks(void)
+{
+	mipi_dsi_ahb_ctrl(1);
+	mipi_dsi_clk_enable();
+}
+
+void mipi_dsi_turn_off_clks(void)
+{
+	mipi_dsi_clk_disable();
+	mipi_dsi_ahb_ctrl(0);
+}
+
+static void mipi_dsi_action(struct list_head *act_list)
+{
+	struct list_head *lp;
+	struct dsi_kickoff_action *act;
+
+	list_for_each(lp, act_list) {
+		act = list_entry(lp, struct dsi_kickoff_action, act_entry);
+		if (act && act->action)
+			act->action(act->data);
+	}
+}
+
+void mipi_dsi_pre_kickoff_action(void)
+{
+	mipi_dsi_action(&pre_kickoff_list);
+}
+
+void mipi_dsi_post_kickoff_action(void)
+{
+	mipi_dsi_action(&post_kickoff_list);
+}
+
+/*
+ * mipi_dsi_pre_kickoff_add:
+ * ov_mutex need to be acquired before call this function.
+ */
+void mipi_dsi_pre_kickoff_add(struct dsi_kickoff_action *act)
+{
+	if (act)
+		list_add_tail(&act->act_entry, &pre_kickoff_list);
+}
+
+/*
+ * mipi_dsi_pre_kickoff_add:
+ * ov_mutex need to be acquired before call this function.
+ */
+void mipi_dsi_post_kickoff_add(struct dsi_kickoff_action *act)
+{
+	if (act)
+		list_add_tail(&act->act_entry, &post_kickoff_list);
+}
+
+/*
+ * mipi_dsi_pre_kickoff_add:
+ * ov_mutex need to be acquired before call this function.
+ */
+void mipi_dsi_pre_kickoff_del(struct dsi_kickoff_action *act)
+{
+	if (!list_empty(&pre_kickoff_list) && act)
+		list_del(&act->act_entry);
+}
+
+/*
+ * mipi_dsi_pre_kickoff_add:
+ * ov_mutex need to be acquired before call this function.
+ */
+void mipi_dsi_post_kickoff_del(struct dsi_kickoff_action *act)
+{
+	if (!list_empty(&post_kickoff_list) && act)
+		list_del(&act->act_entry);
+}
+
+/*
+ * mipi dsi buf mechanism
+ */
+char *mipi_dsi_buf_reserve(struct dsi_buf *dp, int len)
+{
+	dp->data += len;
+	return dp->data;
+}
+
+char *mipi_dsi_buf_unreserve(struct dsi_buf *dp, int len)
+{
+	dp->data -= len;
+	return dp->data;
+}
+
+char *mipi_dsi_buf_push(struct dsi_buf *dp, int len)
+{
+	dp->data -= len;
+	dp->len += len;
+	return dp->data;
+}
+
+char *mipi_dsi_buf_reserve_hdr(struct dsi_buf *dp, int hlen)
+{
+	dp->hdr = (uint32 *)dp->data;
+	return mipi_dsi_buf_reserve(dp, hlen);
+}
+
+char *mipi_dsi_buf_init(struct dsi_buf *dp)
+{
+	int off;
+
+	dp->data = dp->start;
+	off = (int)dp->data;
+	/* 8 byte align */
+	off &= 0x07;
+	if (off)
+		off = 8 - off;
+	dp->data += off;
+	dp->len = 0;
+	return dp->data;
+}
+
+int mipi_dsi_buf_alloc(struct dsi_buf *dp, int size)
+{
+
+	dp->start = kmalloc(size, GFP_KERNEL);
+	if (dp->start == NULL) {
+		pr_err("%s:%u\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	dp->end = dp->start + size;
+	dp->size = size;
+
+	if ((int)dp->start & 0x07)
+		pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
+
+	dp->data = dp->start;
+	dp->len = 0;
+	return size;
+}
+
+/*
+ * mipi dsi gerneric long write
+ */
+static int mipi_dsi_generic_lwrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	char *bp;
+	uint32 *hp;
+	int i, len;
+
+	bp = mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+
+	/* fill up payload */
+	if (cm->payload) {
+		len = cm->dlen;
+		len += 3;
+		len &= ~0x03;	/* multipled by 4 */
+		for (i = 0; i < cm->dlen; i++)
+			*bp++ = cm->payload[i];
+
+		/* append 0xff to the end */
+		for (; i < len; i++)
+			*bp++ = 0xff;
+
+		dp->len += len;
+	}
+
+	/* fill up header */
+	hp = dp->hdr;
+	*hp = 0;
+	*hp = DSI_HDR_WC(cm->dlen);
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_LONG_PKT;
+	*hp |= DSI_HDR_DTYPE(DTYPE_GEN_LWRITE);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;
+}
+
+/*
+ * mipi dsi gerneric short write with 0, 1 2 parameters
+ */
+static int mipi_dsi_generic_swrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+	int len;
+
+	if (cm->dlen && cm->payload == 0) {
+		pr_err("%s: NO payload error\n", __func__);
+		return 0;
+	}
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+
+	len = (cm->dlen > 2) ? 2 : cm->dlen;
+
+	if (len == 1) {
+		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE1);
+		*hp |= DSI_HDR_DATA1(cm->payload[0]);
+		*hp |= DSI_HDR_DATA2(0);
+	} else if (len == 2) {
+		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE2);
+		*hp |= DSI_HDR_DATA1(cm->payload[0]);
+		*hp |= DSI_HDR_DATA2(cm->payload[1]);
+	} else {
+		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE);
+		*hp |= DSI_HDR_DATA1(0);
+		*hp |= DSI_HDR_DATA2(0);
+	}
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+/*
+ * mipi dsi gerneric read with 0, 1 2 parameters
+ */
+static int mipi_dsi_generic_read(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+	int len;
+
+	if (cm->dlen && cm->payload == 0) {
+		pr_err("%s: NO payload error\n", __func__);
+		return 0;
+	}
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_BTA;
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	len = (cm->dlen > 2) ? 2 : cm->dlen;
+
+	if (len == 1) {
+		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ1);
+		*hp |= DSI_HDR_DATA1(cm->payload[0]);
+		*hp |= DSI_HDR_DATA2(0);
+	} else if (len == 2) {
+		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ2);
+		*hp |= DSI_HDR_DATA1(cm->payload[0]);
+		*hp |= DSI_HDR_DATA2(cm->payload[1]);
+	} else {
+		*hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ);
+		*hp |= DSI_HDR_DATA1(0);
+		*hp |= DSI_HDR_DATA2(0);
+	}
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+	return dp->len;	/* 4 bytes */
+}
+
+/*
+ * mipi dsi dcs long write
+ */
+static int mipi_dsi_dcs_lwrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	char *bp;
+	uint32 *hp;
+	int i, len;
+
+	bp = mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+
+	/*
+	 * fill up payload
+	 * dcs command byte (first byte) followed by payload
+	 */
+	if (cm->payload) {
+		len = cm->dlen;
+		len += 3;
+		len &= ~0x03;	/* multipled by 4 */
+		for (i = 0; i < cm->dlen; i++)
+			*bp++ = cm->payload[i];
+
+		/* append 0xff to the end */
+		for (; i < len; i++)
+			*bp++ = 0xff;
+
+		dp->len += len;
+	}
+
+	/* fill up header */
+	hp = dp->hdr;
+	*hp = 0;
+	*hp = DSI_HDR_WC(cm->dlen);
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_LONG_PKT;
+	*hp |= DSI_HDR_DTYPE(DTYPE_DCS_LWRITE);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;
+}
+
+/*
+ * mipi dsi dcs short write with 0 parameters
+ */
+static int mipi_dsi_dcs_swrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+	int len;
+
+	if (cm->payload == 0) {
+		pr_err("%s: NO payload error\n", __func__);
+		return -EINVAL;
+	}
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	if (cm->ack)		/* ask ACK trigger msg from peripeheral */
+		*hp |= DSI_HDR_BTA;
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	len = (cm->dlen > 1) ? 1 : cm->dlen;
+
+	*hp |= DSI_HDR_DTYPE(DTYPE_DCS_WRITE);
+	*hp |= DSI_HDR_DATA1(cm->payload[0]);	/* dcs command byte */
+	*hp |= DSI_HDR_DATA2(0);
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+	return dp->len;
+}
+
+/*
+ * mipi dsi dcs short write with 1 parameters
+ */
+static int mipi_dsi_dcs_swrite1(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	if (cm->dlen < 2 || cm->payload == 0) {
+		pr_err("%s: NO payload error\n", __func__);
+		return -EINVAL;
+	}
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	if (cm->ack)		/* ask ACK trigger msg from peripeheral */
+		*hp |= DSI_HDR_BTA;
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	*hp |= DSI_HDR_DTYPE(DTYPE_DCS_WRITE1);
+	*hp |= DSI_HDR_DATA1(cm->payload[0]);	/* dcs comamnd byte */
+	*hp |= DSI_HDR_DATA2(cm->payload[1]);	/* parameter */
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;
+}
+/*
+ * mipi dsi dcs read with 0 parameters
+ */
+
+static int mipi_dsi_dcs_read(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	if (cm->payload == 0) {
+		pr_err("%s: NO payload error\n", __func__);
+		return -EINVAL;
+	}
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_BTA;
+	*hp |= DSI_HDR_DTYPE(DTYPE_DCS_READ);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	*hp |= DSI_HDR_DATA1(cm->payload[0]);	/* dcs command byte */
+	*hp |= DSI_HDR_DATA2(0);
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+static int mipi_dsi_cm_on(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_DTYPE(DTYPE_CM_ON);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+static int mipi_dsi_cm_off(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_DTYPE(DTYPE_CM_OFF);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+static int mipi_dsi_peripheral_on(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_DTYPE(DTYPE_PERIPHERAL_ON);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+static int mipi_dsi_peripheral_off(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_DTYPE(DTYPE_PERIPHERAL_OFF);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+static int mipi_dsi_set_max_pktsize(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	if (cm->payload == 0) {
+		pr_err("%s: NO payload error\n", __func__);
+		return 0;
+	}
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_DTYPE(DTYPE_MAX_PKTSIZE);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	*hp |= DSI_HDR_DATA1(cm->payload[0]);
+	*hp |= DSI_HDR_DATA2(cm->payload[1]);
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+static int mipi_dsi_null_pkt(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp = DSI_HDR_WC(cm->dlen);
+	*hp |= DSI_HDR_LONG_PKT;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_DTYPE(DTYPE_NULL_PKT);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+static int mipi_dsi_blank_pkt(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	uint32 *hp;
+
+	mipi_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
+	hp = dp->hdr;
+	*hp = 0;
+	*hp = DSI_HDR_WC(cm->dlen);
+	*hp |= DSI_HDR_LONG_PKT;
+	*hp |= DSI_HDR_VC(cm->vc);
+	*hp |= DSI_HDR_DTYPE(DTYPE_BLANK_PKT);
+	if (cm->last)
+		*hp |= DSI_HDR_LAST;
+
+	mipi_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
+
+	return dp->len;	/* 4 bytes */
+}
+
+/*
+ * prepare cmd buffer to be txed
+ */
+int mipi_dsi_cmd_dma_add(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
+{
+	int len = 0;
+
+	switch (cm->dtype) {
+	case DTYPE_GEN_WRITE:
+	case DTYPE_GEN_WRITE1:
+	case DTYPE_GEN_WRITE2:
+		len = mipi_dsi_generic_swrite(dp, cm);
+		break;
+	case DTYPE_GEN_LWRITE:
+		len = mipi_dsi_generic_lwrite(dp, cm);
+		break;
+	case DTYPE_GEN_READ:
+	case DTYPE_GEN_READ1:
+	case DTYPE_GEN_READ2:
+		len = mipi_dsi_generic_read(dp, cm);
+		break;
+	case DTYPE_DCS_LWRITE:
+		len = mipi_dsi_dcs_lwrite(dp, cm);
+		break;
+	case DTYPE_DCS_WRITE:
+		len = mipi_dsi_dcs_swrite(dp, cm);
+		break;
+	case DTYPE_DCS_WRITE1:
+		len = mipi_dsi_dcs_swrite1(dp, cm);
+		break;
+	case DTYPE_DCS_READ:
+		len = mipi_dsi_dcs_read(dp, cm);
+		break;
+	case DTYPE_MAX_PKTSIZE:
+		len = mipi_dsi_set_max_pktsize(dp, cm);
+		break;
+	case DTYPE_NULL_PKT:
+		len = mipi_dsi_null_pkt(dp, cm);
+		break;
+	case DTYPE_BLANK_PKT:
+		len = mipi_dsi_blank_pkt(dp, cm);
+		break;
+	case DTYPE_CM_ON:
+		len = mipi_dsi_cm_on(dp, cm);
+		break;
+	case DTYPE_CM_OFF:
+		len = mipi_dsi_cm_off(dp, cm);
+		break;
+	case DTYPE_PERIPHERAL_ON:
+		len = mipi_dsi_peripheral_on(dp, cm);
+		break;
+	case DTYPE_PERIPHERAL_OFF:
+		len = mipi_dsi_peripheral_off(dp, cm);
+		break;
+	default:
+		pr_debug("%s: dtype=%x NOT supported\n",
+					__func__, cm->dtype);
+		break;
+
+	}
+
+	return len;
+}
+
+/*
+ * mipi_dsi_short_read1_resp: 1 parameter
+ */
+static int mipi_dsi_short_read1_resp(struct dsi_buf *rp)
+{
+	/* strip out dcs type */
+	rp->data++;
+	rp->len = 1;
+	return rp->len;
+}
+
+/*
+ * mipi_dsi_short_read2_resp: 2 parameter
+ */
+static int mipi_dsi_short_read2_resp(struct dsi_buf *rp)
+{
+	/* strip out dcs type */
+	rp->data++;
+	rp->len = 2;
+	return rp->len;
+}
+
+static int mipi_dsi_long_read_resp(struct dsi_buf *rp)
+{
+	short len;
+
+	len = rp->data[2];
+	len <<= 8;
+	len |= rp->data[1];
+	/* strip out dcs header */
+	rp->data += 4;
+	rp->len -= 4;
+	/* strip out 2 bytes of checksum */
+	rp->len -= 2;
+	return len;
+}
+
+void mipi_dsi_host_init(struct mipi_panel_info *pinfo)
+{
+	uint32 dsi_ctrl, intr_ctrl;
+	uint32 data;
+
+	if (mdp_rev > MDP_REV_41 || mdp_rev == MDP_REV_303)
+		pinfo->rgb_swap = DSI_RGB_SWAP_RGB;
+	else
+		pinfo->rgb_swap = DSI_RGB_SWAP_BGR;
+
+	if (pinfo->mode == DSI_VIDEO_MODE) {
+		data = 0;
+		if (pinfo->pulse_mode_hsa_he)
+			data |= BIT(28);
+		if (pinfo->hfp_power_stop)
+			data |= BIT(24);
+		if (pinfo->hbp_power_stop)
+			data |= BIT(20);
+		if (pinfo->hsa_power_stop)
+			data |= BIT(16);
+		if (pinfo->eof_bllp_power_stop)
+			data |= BIT(15);
+		if (pinfo->bllp_power_stop)
+			data |= BIT(12);
+		data |= ((pinfo->traffic_mode & 0x03) << 8);
+		data |= ((pinfo->dst_format & 0x03) << 4); /* 2 bits */
+		data |= (pinfo->vc & 0x03);
+		MIPI_OUTP(MIPI_DSI_BASE + 0x000c, data);
+
+		data = 0;
+		data |= ((pinfo->rgb_swap & 0x07) << 12);
+		if (pinfo->b_sel)
+			data |= BIT(8);
+		if (pinfo->g_sel)
+			data |= BIT(4);
+		if (pinfo->r_sel)
+			data |= BIT(0);
+		MIPI_OUTP(MIPI_DSI_BASE + 0x001c, data);
+	} else if (pinfo->mode == DSI_CMD_MODE) {
+		data = 0;
+		data |= ((pinfo->interleave_max & 0x0f) << 20);
+		data |= ((pinfo->rgb_swap & 0x07) << 16);
+		if (pinfo->b_sel)
+			data |= BIT(12);
+		if (pinfo->g_sel)
+			data |= BIT(8);
+		if (pinfo->r_sel)
+			data |= BIT(4);
+		data |= (pinfo->dst_format & 0x0f);	/* 4 bits */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x003c, data);
+
+		/* DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL */
+		data = pinfo->wr_mem_continue & 0x0ff;
+		data <<= 8;
+		data |= (pinfo->wr_mem_start & 0x0ff);
+		if (pinfo->insert_dcs_cmd)
+			data |= BIT(16);
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0040, data);
+	} else
+		pr_err("%s: Unknown DSI mode=%d\n", __func__, pinfo->mode);
+
+	dsi_ctrl = BIT(8) | BIT(2);	/* clock enable & cmd mode */
+	intr_ctrl = 0;
+	intr_ctrl = (DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_CMD_MDP_DONE_MASK);
+
+	if (pinfo->crc_check)
+		dsi_ctrl |= BIT(24);
+	if (pinfo->ecc_check)
+		dsi_ctrl |= BIT(20);
+	if (pinfo->data_lane3)
+		dsi_ctrl |= BIT(7);
+	if (pinfo->data_lane2)
+		dsi_ctrl |= BIT(6);
+	if (pinfo->data_lane1)
+		dsi_ctrl |= BIT(5);
+	if (pinfo->data_lane0)
+		dsi_ctrl |= BIT(4);
+
+	/* from frame buffer, low power mode */
+	/* DSI_COMMAND_MODE_DMA_CTRL */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);
+
+	data = 0;
+	if (pinfo->te_sel)
+		data |= BIT(31);
+	data |= pinfo->mdp_trigger << 4;/* cmd mdp trigger */
+	data |= pinfo->dma_trigger;	/* cmd dma trigger */
+	data |= (pinfo->stream & 0x01) << 8;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0080, data); /* DSI_TRIG_CTRL */
+
+	/* DSI_LAN_SWAP_CTRL */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x00ac, pinfo->dlane_swap);
+
+	/* clock out ctrl */
+	data = pinfo->t_clk_post & 0x3f;	/* 6 bits */
+	data <<= 8;
+	data |= pinfo->t_clk_pre & 0x3f;	/*  6 bits */
+	MIPI_OUTP(MIPI_DSI_BASE + 0xc0, data);	/* DSI_CLKOUT_TIMING_CTRL */
+
+	data = 0;
+	if (pinfo->rx_eot_ignore)
+		data |= BIT(4);
+	if (pinfo->tx_eot_append)
+		data |= BIT(0);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x00c8, data); /* DSI_EOT_PACKET_CTRL */
+
+
+	/* allow only ack-err-status  to generate interrupt */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0108, 0x13ff3fe0); /* DSI_ERR_INT_MASK0 */
+
+	intr_ctrl |= DSI_INTR_ERROR_MASK;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x010c, intr_ctrl); /* DSI_INTL_CTRL */
+
+	/* turn esc, byte, dsi, pclk, sclk, hclk on */
+	if (mdp_rev >= MDP_REV_41)
+		MIPI_OUTP(MIPI_DSI_BASE + 0x118, 0x23f); /* DSI_CLK_CTRL */
+	else
+		MIPI_OUTP(MIPI_DSI_BASE + 0x118, 0x33f); /* DSI_CLK_CTRL */
+
+	dsi_ctrl |= BIT(0);	/* enable dsi */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl);
+
+	wmb();
+}
+
+void mipi_set_tx_power_mode(int mode)
+{
+	uint32 data = MIPI_INP(MIPI_DSI_BASE + 0x38);
+
+	if (mode == 0)
+		data &= ~BIT(26);
+	else
+		data |= BIT(26);
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x38, data);
+}
+
+void mipi_dsi_sw_reset(void)
+{
+	MIPI_OUTP(MIPI_DSI_BASE + 0x114, 0x01);
+	wmb();
+	MIPI_OUTP(MIPI_DSI_BASE + 0x114, 0x00);
+	wmb();
+}
+
+void mipi_dsi_controller_cfg(int enable)
+{
+
+	uint32 dsi_ctrl;
+	uint32 status;
+	int cnt;
+
+	cnt = 16;
+	while (cnt--) {
+		status = MIPI_INP(MIPI_DSI_BASE + 0x0004);
+		status &= 0x02;		/* CMD_MODE_DMA_BUSY */
+		if (status == 0)
+			break;
+		usleep(1000);
+	}
+	if (cnt == 0)
+		pr_info("%s: DSI status=%x failed\n", __func__, status);
+
+	cnt = 16;
+	while (cnt--) {
+		status = MIPI_INP(MIPI_DSI_BASE + 0x0008);
+		status &= 0x11111000;	/* x_HS_FIFO_EMPTY */
+		if (status == 0x11111000)	/* all empty */
+			break;
+		usleep(1000);
+	}
+
+	if (cnt == 0)
+		pr_info("%s: FIFO status=%x failed\n", __func__, status);
+
+	dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000);
+	if (enable)
+		dsi_ctrl |= 0x01;
+	else
+		dsi_ctrl &= ~0x01;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl);
+	wmb();
+}
+
+void mipi_dsi_op_mode_config(int mode)
+{
+
+	uint32 dsi_ctrl, intr_ctrl;
+
+	dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000);
+	dsi_ctrl &= ~0x07;
+	if (mode == DSI_VIDEO_MODE) {
+		dsi_ctrl |= 0x03;
+		intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK;
+	} else {		/* command mode */
+		dsi_ctrl |= 0x05;
+		intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK |
+				DSI_INTR_CMD_MDP_DONE_MASK;
+	}
+
+	pr_debug("%s: dsi_ctrl=%x intr=%x\n", __func__, dsi_ctrl, intr_ctrl);
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x010c, intr_ctrl); /* DSI_INTL_CTRL */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl);
+	wmb();
+}
+
+void mipi_dsi_mdp_busy_wait(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+	int need_wait = 0;
+
+	pr_debug("%s: start pid=%d\n",
+			__func__, current->pid);
+	spin_lock_irqsave(&dsi_mdp_lock, flag);
+	if (dsi_mdp_busy == TRUE) {
+		INIT_COMPLETION(dsi_mdp_comp);
+		need_wait++;
+	}
+	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
+	if (need_wait) {
+		/* wait until DMA finishes the current job */
+		pr_debug("%s: pending pid=%d\n",
+				__func__, current->pid);
+		wait_for_completion(&dsi_mdp_comp);
+	}
+	pr_debug("%s: done pid=%d\n",
+			__func__, current->pid);
+}
+
+void mipi_dsi_cmd_mdp_start(void)
+{
+	unsigned long flag;
+
+	mipi_dsi_mdp_stat_inc(STAT_DSI_START);
+
+	spin_lock_irqsave(&dsi_mdp_lock, flag);
+	 mipi_dsi_enable_irq(DSI_MDP_TERM);
+	 dsi_mdp_busy = TRUE;
+	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+}
+
+void mipi_dsi_cmd_bta_sw_trigger(void)
+{
+	uint32 data;
+	int cnt = 0;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x094, 0x01);	/* trigger */
+	wmb();
+
+	while (cnt < 10000) {
+		data = MIPI_INP(MIPI_DSI_BASE + 0x0004);/* DSI_STATUS */
+		if ((data & 0x0010) == 0)
+			break;
+		cnt++;
+	}
+
+	mipi_dsi_ack_err_status();
+
+	pr_debug("%s: BTA done, cnt=%d\n", __func__, cnt);
+}
+
+static char set_tear_on[2] = {0x35, 0x00};
+static struct dsi_cmd_desc dsi_tear_on_cmd = {
+	DTYPE_DCS_WRITE1, 1, 0, 0, 0, sizeof(set_tear_on), set_tear_on};
+
+static char set_tear_off[2] = {0x34, 0x00};
+static struct dsi_cmd_desc dsi_tear_off_cmd = {
+	DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(set_tear_off), set_tear_off};
+
+void mipi_dsi_set_tear_on(struct msm_fb_data_type *mfd)
+{
+	mipi_dsi_buf_init(&dsi_tx_buf);
+	mipi_dsi_cmds_tx(&dsi_tx_buf, &dsi_tear_on_cmd, 1);
+}
+
+void mipi_dsi_set_tear_off(struct msm_fb_data_type *mfd)
+{
+	mipi_dsi_buf_init(&dsi_tx_buf);
+	mipi_dsi_cmds_tx(&dsi_tx_buf, &dsi_tear_off_cmd, 1);
+}
+
+int mipi_dsi_cmd_reg_tx(uint32 data)
+{
+#ifdef DSI_HOST_DEBUG
+	int i;
+	char *bp;
+
+	bp = (char *)&data;
+	pr_debug("%s: ", __func__);
+	for (i = 0; i < 4; i++)
+		pr_debug("%x ", *bp++);
+
+	pr_debug("\n");
+#endif
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0080, 0x04);/* sw trigger */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0, 0x135);
+
+	wmb();
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x038, data);
+	wmb();
+	MIPI_OUTP(MIPI_DSI_BASE + 0x08c, 0x01);	/* trigger */
+	wmb();
+
+	udelay(300);
+
+	return 4;
+}
+
+/*
+ * mipi_dsi_cmds_tx:
+ * thread context only
+ */
+int mipi_dsi_cmds_tx(struct dsi_buf *tp, struct dsi_cmd_desc *cmds, int cnt)
+{
+	struct dsi_cmd_desc *cm;
+	uint32 dsi_ctrl, ctrl;
+	int i, video_mode;
+	unsigned long flag;
+
+	/* turn on cmd mode
+	* for video mode, do not send cmds more than
+	* one pixel line, since it only transmit it
+	* during BLLP.
+	*/
+	dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000);
+	video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
+	if (video_mode) {
+		ctrl = dsi_ctrl | 0x04; /* CMD_MODE_EN */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0000, ctrl);
+	}
+
+	spin_lock_irqsave(&dsi_mdp_lock, flag);
+	dsi_mdp_busy = TRUE;
+	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
+	cm = cmds;
+	mipi_dsi_buf_init(tp);
+	for (i = 0; i < cnt; i++) {
+		mipi_dsi_enable_irq(DSI_CMD_TERM);
+		mipi_dsi_buf_init(tp);
+		mipi_dsi_cmd_dma_add(tp, cm);
+		mipi_dsi_cmd_dma_tx(tp);
+		if (cm->wait)
+			msleep(cm->wait);
+		cm++;
+	}
+
+	if (video_mode)
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl); /* restore */
+
+	spin_lock_irqsave(&dsi_mdp_lock, flag);
+	dsi_mdp_busy = FALSE;
+	complete(&dsi_mdp_comp);
+	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
+	return cnt;
+}
+
+/* MIPI_DSI_MRPS, Maximum Return Packet Size */
+static char max_pktsize[2] = {0x00, 0x00}; /* LSB tx first, 10 bytes */
+
+static struct dsi_cmd_desc pkt_size_cmd[] = {
+	{DTYPE_MAX_PKTSIZE, 1, 0, 0, 0,
+		sizeof(max_pktsize), max_pktsize}
+};
+
+/*
+ * DSI panel reply with  MAX_RETURN_PACKET_SIZE bytes of data
+ * plus DCS header, ECC and CRC for DCS long read response
+ * mipi_dsi_controller only have 4x32 bits register ( 16 bytes) to
+ * hold data per transaction.
+ * MIPI_DSI_LEN equal to 8
+ * len should be either 4 or 8
+ * any return data more than MIPI_DSI_LEN need to be break down
+ * to multiple transactions.
+ *
+ * ov_mutex need to be acquired before call this function.
+ */
+int mipi_dsi_cmds_rx(struct msm_fb_data_type *mfd,
+			struct dsi_buf *tp, struct dsi_buf *rp,
+			struct dsi_cmd_desc *cmds, int rlen)
+{
+	int cnt, len, diff, pkt_size;
+	char cmd;
+	unsigned long flag;
+
+	if (mfd->panel_info.mipi.no_max_pkt_size) {
+		/* Only support rlen = 4*n */
+		rlen += 3;
+		rlen &= ~0x03;
+	}
+
+	len = rlen;
+	diff = 0;
+
+	if (len <= 2)
+		cnt = 4;	/* short read */
+	else {
+		if (len > MIPI_DSI_LEN)
+			len = MIPI_DSI_LEN;	/* 8 bytes at most */
+
+		len = (len + 3) & ~0x03; /* len 4 bytes align */
+		diff = len - rlen;
+		/*
+		 * add extra 2 bytes to len to have overall
+		 * packet size is multipe by 4. This also make
+		 * sure 4 bytes dcs headerlocates within a
+		 * 32 bits register after shift in.
+		 * after all, len should be either 6 or 10.
+		 */
+		len += 2;
+		cnt = len + 6; /* 4 bytes header + 2 bytes crc */
+	}
+
+	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
+		/* make sure mdp dma is not txing pixel data */
+#ifdef CONFIG_FB_MSM_MDP303
+			mdp3_dsi_cmd_dma_busy_wait(mfd);
+#endif
+	}
+
+	spin_lock_irqsave(&dsi_mdp_lock, flag);
+	dsi_mdp_busy = TRUE;
+	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
+	if (!mfd->panel_info.mipi.no_max_pkt_size) {
+		/* packet size need to be set at every read */
+		pkt_size = len;
+		max_pktsize[0] = pkt_size;
+		mipi_dsi_enable_irq(DSI_CMD_TERM);
+		mipi_dsi_buf_init(tp);
+		mipi_dsi_cmd_dma_add(tp, pkt_size_cmd);
+		mipi_dsi_cmd_dma_tx(tp);
+	}
+
+	mipi_dsi_enable_irq(DSI_CMD_TERM);
+	mipi_dsi_buf_init(tp);
+	mipi_dsi_cmd_dma_add(tp, cmds);
+
+	/* transmit read comamnd to client */
+	mipi_dsi_cmd_dma_tx(tp);
+
+	mipi_dsi_disable_irq(DSI_CMD_TERM);
+	/*
+	 * once cmd_dma_done interrupt received,
+	 * return data from client is ready and stored
+	 * at RDBK_DATA register already
+	 */
+	mipi_dsi_buf_init(rp);
+	if (mfd->panel_info.mipi.no_max_pkt_size) {
+		/*
+		 * expect rlen = n * 4
+		 * short alignement for start addr
+		 */
+		rp->data += 2;
+	}
+
+	mipi_dsi_cmd_dma_rx(rp, cnt);
+
+	spin_lock_irqsave(&dsi_mdp_lock, flag);
+	dsi_mdp_busy = FALSE;
+	complete(&dsi_mdp_comp);
+	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
+	if (mfd->panel_info.mipi.no_max_pkt_size) {
+		/*
+		 * remove extra 2 bytes from previous
+		 * rx transaction at shift register
+		 * which was inserted during copy
+		 * shift registers to rx buffer
+		 * rx payload start from long alignment addr
+		 */
+		rp->data += 2;
+	}
+
+	cmd = rp->data[0];
+	switch (cmd) {
+	case DTYPE_ACK_ERR_RESP:
+		pr_debug("%s: rx ACK_ERR_PACLAGE\n", __func__);
+		break;
+	case DTYPE_GEN_READ1_RESP:
+	case DTYPE_DCS_READ1_RESP:
+		mipi_dsi_short_read1_resp(rp);
+		break;
+	case DTYPE_GEN_READ2_RESP:
+	case DTYPE_DCS_READ2_RESP:
+		mipi_dsi_short_read2_resp(rp);
+		break;
+	case DTYPE_GEN_LREAD_RESP:
+	case DTYPE_DCS_LREAD_RESP:
+		mipi_dsi_long_read_resp(rp);
+		rp->len -= 2; /* extra 2 bytes added */
+		rp->len -= diff; /* align bytes */
+		break;
+	default:
+		break;
+	}
+
+	return rp->len;
+}
+
+int mipi_dsi_cmds_rx_new(struct dsi_buf *tp, struct dsi_buf *rp,
+			struct dcs_cmd_req *req, int rlen)
+{
+	struct dsi_cmd_desc *cmds;
+	int cnt, len, diff, pkt_size;
+	char cmd;
+	unsigned long flag;
+
+	if (req->flags & CMD_REQ_NO_MAX_PKT_SIZE) {
+		/* Only support rlen = 4*n */
+		rlen += 3;
+		rlen &= ~0x03;
+	}
+
+	cmds = req->cmds;
+
+	len = rlen;
+	diff = 0;
+
+	if (len <= 2)
+		cnt = 4;	/* short read */
+	else {
+		if (len > MIPI_DSI_LEN)
+			len = MIPI_DSI_LEN;	/* 8 bytes at most */
+
+		len = (len + 3) & ~0x03; /* len 4 bytes align */
+		diff = len - rlen;
+		/*
+		 * add extra 2 bytes to len to have overall
+		 * packet size is multipe by 4. This also make
+		 * sure 4 bytes dcs headerlocates within a
+		 * 32 bits register after shift in.
+		 * after all, len should be either 6 or 10.
+		 */
+		len += 2;
+		cnt = len + 6; /* 4 bytes header + 2 bytes crc */
+	}
+
+	spin_lock_irqsave(&dsi_mdp_lock, flag);
+	dsi_mdp_busy = TRUE;
+	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
+	if (!(req->flags & CMD_REQ_NO_MAX_PKT_SIZE)) {
+
+
+		/* packet size need to be set at every read */
+		pkt_size = len;
+		max_pktsize[0] = pkt_size;
+		mipi_dsi_enable_irq(DSI_CMD_TERM);
+		mipi_dsi_buf_init(tp);
+		mipi_dsi_cmd_dma_add(tp, pkt_size_cmd);
+		mipi_dsi_cmd_dma_tx(tp);
+	}
+
+	mipi_dsi_enable_irq(DSI_CMD_TERM);
+	mipi_dsi_buf_init(tp);
+	mipi_dsi_cmd_dma_add(tp, cmds);
+
+	/* transmit read comamnd to client */
+	mipi_dsi_cmd_dma_tx(tp);
+
+	mipi_dsi_disable_irq(DSI_CMD_TERM);
+	/*
+	 * once cmd_dma_done interrupt received,
+	 * return data from client is ready and stored
+	 * at RDBK_DATA register already
+	 */
+	mipi_dsi_buf_init(rp);
+	if (req->flags & CMD_REQ_NO_MAX_PKT_SIZE) {
+		/*
+		 * expect rlen = n * 4
+		 * short alignement for start addr
+		 */
+		rp->data += 2;
+	}
+
+	mipi_dsi_cmd_dma_rx(rp, cnt);
+
+	spin_lock_irqsave(&dsi_mdp_lock, flag);
+	dsi_mdp_busy = FALSE;
+	complete(&dsi_mdp_comp);
+	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
+
+	if (req->flags & CMD_REQ_NO_MAX_PKT_SIZE) {
+		/*
+		 * remove extra 2 bytes from previous
+		 * rx transaction at shift register
+		 * which was inserted during copy
+		 * shift registers to rx buffer
+		 * rx payload start from long alignment addr
+		 */
+		rp->data += 2;
+	}
+
+	cmd = rp->data[0];
+	switch (cmd) {
+	case DTYPE_ACK_ERR_RESP:
+		pr_debug("%s: rx ACK_ERR_PACLAGE\n", __func__);
+		break;
+	case DTYPE_GEN_READ1_RESP:
+	case DTYPE_DCS_READ1_RESP:
+		mipi_dsi_short_read1_resp(rp);
+		break;
+	case DTYPE_GEN_READ2_RESP:
+	case DTYPE_DCS_READ2_RESP:
+		mipi_dsi_short_read2_resp(rp);
+		break;
+	case DTYPE_GEN_LREAD_RESP:
+	case DTYPE_DCS_LREAD_RESP:
+		mipi_dsi_long_read_resp(rp);
+		rp->len -= 2; /* extra 2 bytes added */
+		rp->len -= diff; /* align bytes */
+		break;
+	default:
+		break;
+	}
+
+	return rp->len;
+}
+
+int mipi_dsi_cmd_dma_tx(struct dsi_buf *tp)
+{
+
+	unsigned long flags;
+
+#ifdef DSI_HOST_DEBUG
+	int i;
+	char *bp;
+
+	bp = tp->data;
+
+	pr_debug("%s: ", __func__);
+	for (i = 0; i < tp->len; i++)
+		pr_debug("%x ", *bp++);
+
+	pr_debug("\n");
+#endif
+
+	if (tp->len == 0) {
+		pr_err("%s: Error, len=0\n", __func__);
+		return 0;
+	}
+
+	spin_lock_irqsave(&dsi_mdp_lock, flags);
+	tp->len += 3;
+	tp->len &= ~0x03;	/* multipled by 4 */
+
+	tp->dmap = dma_map_single(&dsi_dev, tp->data, tp->len, DMA_TO_DEVICE);
+	if (dma_mapping_error(&dsi_dev, tp->dmap))
+		pr_err("%s: dmap mapp failed\n", __func__);
+
+	INIT_COMPLETION(dsi_dma_comp);
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x044, tp->dmap);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x048, tp->len);
+	wmb();
+	MIPI_OUTP(MIPI_DSI_BASE + 0x08c, 0x01);	/* trigger */
+	wmb();
+	spin_unlock_irqrestore(&dsi_mdp_lock, flags);
+
+	wait_for_completion(&dsi_dma_comp);
+
+	dma_unmap_single(&dsi_dev, tp->dmap, tp->len, DMA_TO_DEVICE);
+	tp->dmap = 0;
+	return tp->len;
+}
+
+int mipi_dsi_cmd_dma_rx(struct dsi_buf *rp, int rlen)
+{
+	uint32 *lp, data;
+	int i, off, cnt;
+
+	lp = (uint32 *)rp->data;
+	cnt = rlen;
+	cnt += 3;
+	cnt >>= 2;
+
+	if (cnt > 4)
+		cnt = 4; /* 4 x 32 bits registers only */
+
+	off = 0x068;	/* DSI_RDBK_DATA0 */
+	off += ((cnt - 1) * 4);
+
+
+	for (i = 0; i < cnt; i++) {
+		data = (uint32)MIPI_INP(MIPI_DSI_BASE + off);
+		*lp++ = ntohl(data);	/* to network byte order */
+		off -= 4;
+		rp->len += sizeof(*lp);
+	}
+
+	return rlen;
+}
+
+void mipi_dsi_cmd_mdp_busy(void)
+{
+	u32 status;
+	unsigned long flags;
+	int need_wait;
+
+	spin_lock_irqsave(&dsi_mdp_lock, flags);
+	status = MIPI_INP(MIPI_DSI_BASE + 0x0004);/* DSI_STATUS */
+	if (status & 0x04) {	/* MDP BUSY */
+		INIT_COMPLETION(dsi_mdp_comp);
+		need_wait = 1;
+printk("%s: status=%x need_wait\n",__func__, (int)status);
+		mipi_dsi_enable_irq(DSI_MDP_TERM);
+	}
+	spin_unlock_irqrestore(&dsi_mdp_lock, flags);
+
+	if (need_wait)
+		wait_for_completion(&dsi_mdp_comp);
+}
+
+/*
+ * mipi_dsi_cmd_get: cmd_mutex acquired by caller
+ */
+struct dcs_cmd_req *mipi_dsi_cmdlist_get(void)
+{
+	struct dcs_cmd_req *req = NULL;
+
+	if (cmdlist.get != cmdlist.put) {
+		req = &cmdlist.list[cmdlist.get];
+		cmdlist.get++;
+		cmdlist.get %= CMD_REQ_MAX;
+		cmdlist.tot--;
+		pr_debug("%s: tot=%d put=%d get=%d\n", __func__,
+		cmdlist.tot, cmdlist.put, cmdlist.get);
+	}
+	return req;
+}
+void mipi_dsi_cmdlist_tx(struct dcs_cmd_req *req)
+{
+	struct dsi_buf *tp;
+	int ret;
+
+	mipi_dsi_buf_init(&dsi_tx_buf);
+	tp = &dsi_tx_buf;
+	ret = mipi_dsi_cmds_tx(tp, req->cmds, req->cmds_cnt);
+
+	if (req->cb)
+		req->cb(ret);
+
+}
+
+void mipi_dsi_cmdlist_rx(struct dcs_cmd_req *req)
+{
+	int len;
+	u32 *dp;
+	struct dsi_buf *tp;
+	struct dsi_buf *rp;
+
+	mipi_dsi_buf_init(&dsi_tx_buf);
+	mipi_dsi_buf_init(&dsi_rx_buf);
+
+	tp = &dsi_tx_buf;
+	rp = &dsi_rx_buf;
+
+	len = mipi_dsi_cmds_rx_new(tp, rp, req, req->rlen);
+	dp = (u32 *)rp->data;
+
+	if (req->cb)
+		req->cb(*dp);
+}
+
+void mipi_dsi_cmdlist_commit(int from_mdp)
+{
+	struct dcs_cmd_req *req;
+
+	mutex_lock(&cmd_mutex);
+	req = mipi_dsi_cmdlist_get();
+	if (req == NULL) {
+		mutex_unlock(&cmd_mutex);
+		return;
+	}
+
+	pr_debug("%s:  from_mdp=%d pid=%d\n",__func__, from_mdp, current->pid);
+
+	if (!from_mdp) { /* from put */
+		/* make sure dsi_cmd_mdp is idle */
+		mipi_dsi_cmd_mdp_busy();
+	}
+
+	if (req->flags && CMD_REQ_RX)
+		mipi_dsi_cmdlist_rx(req);
+	else
+		mipi_dsi_cmdlist_tx(req);
+
+	mutex_unlock(&cmd_mutex);
+}
+
+int mipi_dsi_cmdlist_put(struct dcs_cmd_req *cmdreq)
+{
+	struct dcs_cmd_req *req;
+	int ret = 0;
+
+	mutex_lock(&cmd_mutex);
+	req = &cmdlist.list[cmdlist.put];
+	*req = *cmdreq;
+	cmdlist.put++;
+	cmdlist.put %= CMD_REQ_MAX;
+	cmdlist.tot++;
+	if (cmdlist.put == cmdlist.get) {
+		/* drop the oldest one */
+		pr_debug("%s: DROP, tot=%d put=%d get=%d\n", __func__,
+			cmdlist.tot, cmdlist.put, cmdlist.get);
+		cmdlist.get++;
+		cmdlist.get %= CMD_REQ_MAX;
+		cmdlist.tot--;
+	}
+	mutex_unlock(&cmd_mutex);
+
+	ret++;
+	pr_debug("%s: tot=%d put=%d get=%d\n", __func__,
+		cmdlist.tot, cmdlist.put, cmdlist.get);
+
+	if (req->flags & CMD_REQ_COMMIT)
+		mipi_dsi_cmdlist_commit(0);
+
+	return ret;
+}
+
+void mipi_dsi_irq_set(uint32 mask, uint32 irq)
+{
+	uint32 data;
+
+	data = MIPI_INP(MIPI_DSI_BASE + 0x010c);/* DSI_INTR_CTRL */
+	data &= ~mask;
+	data |= irq;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x010c, data);
+}
+
+
+void mipi_dsi_ack_err_status(void)
+{
+	uint32 status;
+
+	status = MIPI_INP(MIPI_DSI_BASE + 0x0064);/* DSI_ACK_ERR_STATUS */
+
+	if (status) {
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0064, status);
+		pr_debug("%s: status=%x\n", __func__, status);
+	}
+}
+
+void mipi_dsi_timeout_status(void)
+{
+	uint32 status;
+
+	status = MIPI_INP(MIPI_DSI_BASE + 0x00bc);/* DSI_TIMEOUT_STATUS */
+	if (status & 0x0111) {
+		MIPI_OUTP(MIPI_DSI_BASE + 0x00bc, status);
+		pr_debug("%s: status=%x\n", __func__, status);
+	}
+}
+
+void mipi_dsi_dln0_phy_err(void)
+{
+	uint32 status;
+
+	status = MIPI_INP(MIPI_DSI_BASE + 0x00b0);/* DSI_DLN0_PHY_ERR */
+
+	if (status & 0x011111) {
+		MIPI_OUTP(MIPI_DSI_BASE + 0x00b0, status);
+		pr_debug("%s: status=%x\n", __func__, status);
+	}
+}
+
+void mipi_dsi_fifo_status(void)
+{
+	uint32 status;
+
+	status = MIPI_INP(MIPI_DSI_BASE + 0x0008);/* DSI_FIFO_STATUS */
+
+	if (status & 0x44444489) {
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0008, status);
+		pr_debug("%s: status=%x\n", __func__, status);
+	}
+}
+
+void mipi_dsi_status(void)
+{
+	uint32 status;
+
+	status = MIPI_INP(MIPI_DSI_BASE + 0x0004);/* DSI_STATUS */
+
+	if (status & 0x80000000) {
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0004, status);
+		pr_debug("%s: status=%x\n", __func__, status);
+	}
+}
+
+void mipi_dsi_error(void)
+{
+	/* DSI_ERR_INT_MASK0 */
+	mipi_dsi_ack_err_status();	/* mask0, 0x01f */
+	mipi_dsi_timeout_status();	/* mask0, 0x0e0 */
+	mipi_dsi_fifo_status();		/* mask0, 0x133d00 */
+	mipi_dsi_status();		/* mask0, 0xc0100 */
+	mipi_dsi_dln0_phy_err();	/* mask0, 0x3e00000 */
+}
+
+
+irqreturn_t mipi_dsi_isr(int irq, void *ptr)
+{
+	uint32 isr;
+
+	isr = MIPI_INP(MIPI_DSI_BASE + 0x010c);/* DSI_INTR_CTRL */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x010c, isr);
+
+	pr_debug("%s: isr=%x\n", __func__, (int)isr);
+
+#ifdef CONFIG_FB_MSM_MDP40
+	mdp4_stat.intr_dsi++;
+#endif
+	if (isr & DSI_INTR_ERROR) {
+		mipi_dsi_mdp_stat_inc(STAT_DSI_ERROR);
+		mipi_dsi_error();
+	}
+
+	if (isr & DSI_INTR_VIDEO_DONE) {
+		/*
+		* do something  here
+		*/
+	}
+
+	if (isr & DSI_INTR_CMD_DMA_DONE) {
+		mipi_dsi_mdp_stat_inc(STAT_DSI_CMD);
+		spin_lock(&dsi_mdp_lock);
+		complete(&dsi_dma_comp);
+		dsi_ctrl_lock = FALSE;
+		mipi_dsi_disable_irq_nosync(DSI_CMD_TERM);
+		spin_unlock(&dsi_mdp_lock);
+	}
+
+	if (isr & DSI_INTR_CMD_MDP_DONE) {
+		mipi_dsi_mdp_stat_inc(STAT_DSI_MDP);
+		spin_lock(&dsi_mdp_lock);
+		dsi_ctrl_lock = FALSE;
+		mipi_dsi_disable_irq_nosync(DSI_MDP_TERM);
+		dsi_mdp_busy = FALSE;
+		complete(&dsi_mdp_comp);
+		spin_unlock(&dsi_mdp_lock);
+	}
+
+
+	return IRQ_HANDLED;
+}
diff --git a/drivers/video/msm/mipi_novatek.c b/drivers/video/msm/mipi_novatek.c
new file mode 100644
index 0000000..2dde711
--- /dev/null
+++ b/drivers/video/msm/mipi_novatek.c
@@ -0,0 +1,635 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifdef CONFIG_SPI_QUP
+#include <linux/spi/spi.h>
+#endif
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_novatek.h"
+#include "mdp4.h"
+
+
+static struct mipi_dsi_panel_platform_data *mipi_novatek_pdata;
+
+static struct dsi_buf novatek_tx_buf;
+static struct dsi_buf novatek_rx_buf;
+static int mipi_novatek_lcd_init(void);
+
+#define MIPI_DSI_NOVATEK_SPI_DEVICE_NAME	"dsi_novatek_3d_panel_spi"
+#define HPCI_FPGA_READ_CMD	0x84
+#define HPCI_FPGA_WRITE_CMD	0x04
+
+#ifdef CONFIG_SPI_QUP
+static struct spi_device *panel_3d_spi_client;
+
+static void novatek_fpga_write(uint8 addr, uint16 value)
+{
+	char tx_buf[32];
+	int  rc;
+	struct spi_message  m;
+	struct spi_transfer t;
+	u8 data[4] = {0x0, 0x0, 0x0, 0x0};
+
+	if (!panel_3d_spi_client) {
+		pr_err("%s panel_3d_spi_client is NULL\n", __func__);
+		return;
+	}
+	data[0] = HPCI_FPGA_WRITE_CMD;
+	data[1] = addr;
+	data[2] = ((value >> 8) & 0xFF);
+	data[3] = (value & 0xFF);
+
+	memset(&t, 0, sizeof t);
+	memset(tx_buf, 0, sizeof tx_buf);
+	t.tx_buf = data;
+	t.len = 4;
+	spi_setup(panel_3d_spi_client);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	rc = spi_sync(panel_3d_spi_client, &m);
+	if (rc)
+		pr_err("%s: SPI transfer failed\n", __func__);
+
+	return;
+}
+
+static void novatek_fpga_read(uint8 addr)
+{
+	char tx_buf[32];
+	int  rc;
+	struct spi_message  m;
+	struct spi_transfer t;
+	struct spi_transfer rx;
+	char rx_value[2];
+	u8 data[4] = {0x0, 0x0};
+
+	if (!panel_3d_spi_client) {
+		pr_err("%s panel_3d_spi_client is NULL\n", __func__);
+		return;
+	}
+
+	data[0] = HPCI_FPGA_READ_CMD;
+	data[1] = addr;
+
+	memset(&t, 0, sizeof t);
+	memset(tx_buf, 0, sizeof tx_buf);
+	memset(&rx, 0, sizeof rx);
+	memset(rx_value, 0, sizeof rx_value);
+	t.tx_buf = data;
+	t.len = 2;
+	rx.rx_buf = rx_value;
+	rx.len = 2;
+	spi_setup(panel_3d_spi_client);
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+	spi_message_add_tail(&rx, &m);
+
+	rc = spi_sync(panel_3d_spi_client, &m);
+	if (rc)
+		pr_err("%s: SPI transfer failed\n", __func__);
+	else
+		pr_info("%s: rx_value = 0x%x, 0x%x\n", __func__,
+						rx_value[0], rx_value[1]);
+
+	return;
+}
+
+static int __devinit panel_3d_spi_probe(struct spi_device *spi)
+{
+	panel_3d_spi_client = spi;
+	return 0;
+}
+static int __devexit panel_3d_spi_remove(struct spi_device *spi)
+{
+	panel_3d_spi_client = NULL;
+	return 0;
+}
+static struct spi_driver panel_3d_spi_driver = {
+	.probe         = panel_3d_spi_probe,
+	.remove        = __devexit_p(panel_3d_spi_remove),
+	.driver		   = {
+		.name = "dsi_novatek_3d_panel_spi",
+		.owner  = THIS_MODULE,
+	}
+};
+
+#else
+
+static void novatek_fpga_write(uint8 addr, uint16 value)
+{
+	return;
+}
+
+static void novatek_fpga_read(uint8 addr)
+{
+	return;
+}
+
+#endif
+
+
+/* novatek blue panel */
+
+#ifdef NOVETAK_COMMANDS_UNUSED
+static char display_config_cmd_mode1[] = {
+	/* TYPE_DCS_LWRITE */
+	0x2A, 0x00, 0x00, 0x01,
+	0x3F, 0xFF, 0xFF, 0xFF
+};
+
+static char display_config_cmd_mode2[] = {
+	/* DTYPE_DCS_LWRITE */
+	0x2B, 0x00, 0x00, 0x01,
+	0xDF, 0xFF, 0xFF, 0xFF
+};
+
+static char display_config_cmd_mode3_666[] = {
+	/* DTYPE_DCS_WRITE1 */
+	0x3A, 0x66, 0x15, 0x80 /* 666 Packed (18-bits) */
+};
+
+static char display_config_cmd_mode3_565[] = {
+	/* DTYPE_DCS_WRITE1 */
+	0x3A, 0x55, 0x15, 0x80 /* 565 mode */
+};
+
+static char display_config_321[] = {
+	/* DTYPE_DCS_WRITE1 */
+	0x66, 0x2e, 0x15, 0x00 /* Reg 0x66 : 2E */
+};
+
+static char display_config_323[] = {
+	/* DTYPE_DCS_WRITE */
+	0x13, 0x00, 0x05, 0x00 /* Reg 0x13 < Set for Normal Mode> */
+};
+
+static char display_config_2lan[] = {
+	/* DTYPE_DCS_WRITE */
+	0x61, 0x01, 0x02, 0xff /* Reg 0x61 : 01,02 < Set for 2 Data Lane > */
+};
+
+static char display_config_exit_sleep[] = {
+	/* DTYPE_DCS_WRITE */
+	0x11, 0x00, 0x05, 0x80 /* Reg 0x11 < exit sleep mode> */
+};
+
+static char display_config_TE_ON[] = {
+	/* DTYPE_DCS_WRITE1 */
+	0x35, 0x00, 0x15, 0x80
+};
+
+static char display_config_39H[] = {
+	/* DTYPE_DCS_WRITE */
+	0x39, 0x00, 0x05, 0x80
+};
+
+static char display_config_set_tear_scanline[] = {
+	/* DTYPE_DCS_LWRITE */
+	0x44, 0x00, 0x00, 0xff
+};
+
+static char display_config_set_twolane[] = {
+	/* DTYPE_DCS_WRITE1 */
+	0xae, 0x03, 0x15, 0x80
+};
+
+static char display_config_set_threelane[] = {
+	/* DTYPE_DCS_WRITE1 */
+	0xae, 0x05, 0x15, 0x80
+};
+
+#else
+
+static char sw_reset[2] = {0x01, 0x00}; /* DTYPE_DCS_WRITE */
+static char enter_sleep[2] = {0x10, 0x00}; /* DTYPE_DCS_WRITE */
+static char exit_sleep[2] = {0x11, 0x00}; /* DTYPE_DCS_WRITE */
+static char display_off[2] = {0x28, 0x00}; /* DTYPE_DCS_WRITE */
+static char display_on[2] = {0x29, 0x00}; /* DTYPE_DCS_WRITE */
+
+
+
+static char rgb_888[2] = {0x3A, 0x77}; /* DTYPE_DCS_WRITE1 */
+
+#if defined(NOVATEK_TWO_LANE)
+static char set_num_of_lanes[2] = {0xae, 0x03}; /* DTYPE_DCS_WRITE1 */
+#else  /* 1 lane */
+static char set_num_of_lanes[2] = {0xae, 0x01}; /* DTYPE_DCS_WRITE1 */
+#endif
+/* commands by Novatke */
+static char novatek_f4[2] = {0xf4, 0x55}; /* DTYPE_DCS_WRITE1 */
+static char novatek_8c[16] = { /* DTYPE_DCS_LWRITE */
+	0x8C, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x08, 0x08, 0x00, 0x30, 0xC0, 0xB7, 0x37};
+static char novatek_ff[2] = {0xff, 0x55 }; /* DTYPE_DCS_WRITE1 */
+
+static char set_width[5] = { /* DTYPE_DCS_LWRITE */
+	0x2A, 0x00, 0x00, 0x02, 0x1B}; /* 540 - 1 */
+static char set_height[5] = { /* DTYPE_DCS_LWRITE */
+	0x2B, 0x00, 0x00, 0x03, 0xBF}; /* 960 - 1 */
+#endif
+
+static char led_pwm2[2] = {0x53, 0x24}; /* DTYPE_DCS_WRITE1 */
+static char led_pwm3[2] = {0x55, 0x00}; /* DTYPE_DCS_WRITE1 */
+
+static struct dsi_cmd_desc novatek_video_on_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 50,
+		sizeof(sw_reset), sw_reset},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(display_on), display_on},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 10,
+		sizeof(set_num_of_lanes), set_num_of_lanes},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 10,
+		sizeof(rgb_888), rgb_888},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 10,
+		sizeof(led_pwm2), led_pwm2},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 10,
+		sizeof(led_pwm3), led_pwm3},
+};
+
+static struct dsi_cmd_desc novatek_cmd_on_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 50,
+		sizeof(sw_reset), sw_reset},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(display_on), display_on},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 50,
+		sizeof(novatek_f4), novatek_f4},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, 50,
+		sizeof(novatek_8c), novatek_8c},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 50,
+		sizeof(novatek_ff), novatek_ff},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 10,
+		sizeof(set_num_of_lanes), set_num_of_lanes},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, 50,
+		sizeof(set_width), set_width},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, 50,
+		sizeof(set_height), set_height},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 10,
+		sizeof(rgb_888), rgb_888},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 1,
+		sizeof(led_pwm2), led_pwm2},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 1,
+		sizeof(led_pwm3), led_pwm3},
+};
+
+static struct dsi_cmd_desc novatek_display_off_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(display_off), display_off},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 120,
+		sizeof(enter_sleep), enter_sleep}
+};
+
+static char manufacture_id[2] = {0x04, 0x00}; /* DTYPE_DCS_READ */
+
+static struct dsi_cmd_desc novatek_manufacture_id_cmd = {
+	DTYPE_DCS_READ, 1, 0, 1, 5, sizeof(manufacture_id), manufacture_id};
+
+static uint32 mipi_novatek_manufacture_id(struct msm_fb_data_type *mfd)
+{
+	struct dsi_buf *rp, *tp;
+	struct dsi_cmd_desc *cmd;
+	uint32 *lp;
+
+	tp = &novatek_tx_buf;
+	rp = &novatek_rx_buf;
+	cmd = &novatek_manufacture_id_cmd;
+	mipi_dsi_cmds_rx(mfd, tp, rp, cmd, 3);
+	lp = (uint32 *)rp->data;
+	pr_info("%s: manufacture_id=%x\n", __func__, *lp);
+	return *lp;
+}
+
+static int fpga_addr;
+static int fpga_access_mode;
+static bool support_3d;
+
+static void mipi_novatek_3d_init(int addr, int mode)
+{
+	fpga_addr = addr;
+	fpga_access_mode = mode;
+}
+
+static void mipi_dsi_enable_3d_barrier(int mode)
+{
+	void __iomem *fpga_ptr;
+	uint32_t ptr_value = 0;
+
+	if (!fpga_addr && support_3d) {
+		pr_err("%s: fpga_addr not set. Failed to enable 3D barrier\n",
+					__func__);
+		return;
+	}
+
+	if (fpga_access_mode == FPGA_SPI_INTF) {
+		if (mode == LANDSCAPE)
+			novatek_fpga_write(fpga_addr, 1);
+		else if (mode == PORTRAIT)
+			novatek_fpga_write(fpga_addr, 3);
+		else
+			novatek_fpga_write(fpga_addr, 0);
+
+		mb();
+		novatek_fpga_read(fpga_addr);
+	} else if (fpga_access_mode == FPGA_EBI2_INTF) {
+		fpga_ptr = ioremap_nocache(fpga_addr, sizeof(uint32_t));
+		if (!fpga_ptr) {
+			pr_err("%s: FPGA ioremap failed."
+				"Failed to enable 3D barrier\n",
+						__func__);
+			return;
+		}
+
+		ptr_value = readl_relaxed(fpga_ptr);
+		if (mode == LANDSCAPE)
+			writel_relaxed(((0xFFFF0000 & ptr_value) | 1),
+								fpga_ptr);
+		else if (mode == PORTRAIT)
+			writel_relaxed(((0xFFFF0000 & ptr_value) | 3),
+								fpga_ptr);
+		else
+			writel_relaxed((0xFFFF0000 & ptr_value),
+								fpga_ptr);
+
+		mb();
+		iounmap(fpga_ptr);
+	} else
+		pr_err("%s: 3D barrier not configured correctly\n",
+					__func__);
+}
+
+static int mipi_novatek_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+	struct msm_panel_info *pinfo;
+
+	mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	pinfo = &mfd->panel_info;
+	if (pinfo->is_3d_panel)
+		support_3d = TRUE;
+
+	mipi  = &mfd->panel_info.mipi;
+
+	if (mipi->mode == DSI_VIDEO_MODE) {
+		mipi_dsi_cmds_tx(&novatek_tx_buf, novatek_video_on_cmds,
+				ARRAY_SIZE(novatek_video_on_cmds));
+	} else {
+		mipi_dsi_cmds_tx(&novatek_tx_buf, novatek_cmd_on_cmds,
+				ARRAY_SIZE(novatek_cmd_on_cmds));
+
+		/* clean up ack_err_status */
+		mipi_dsi_cmd_bta_sw_trigger();
+		mipi_novatek_manufacture_id(mfd);
+	}
+
+	return 0;
+}
+
+static int mipi_novatek_lcd_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi_dsi_cmds_tx(&novatek_tx_buf, novatek_display_off_cmds,
+			ARRAY_SIZE(novatek_display_off_cmds));
+
+	return 0;
+}
+
+static char led_pwm1[2] = {0x51, 0x0};	/* DTYPE_DCS_WRITE1 */
+static struct dsi_cmd_desc backlight_cmd = {
+	DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(led_pwm1), led_pwm1};
+
+struct dcs_cmd_req cmdreq;
+
+static void mipi_novatek_set_backlight(struct msm_fb_data_type *mfd)
+{
+	led_pwm1[1] = (unsigned char)mfd->bl_level;
+
+	cmdreq.cmds = &backlight_cmd;
+	cmdreq.cmds_cnt = 1;
+	cmdreq.flags = 0;
+	cmdreq.rlen = 0;
+	cmdreq.cb = NULL;
+
+	mipi_dsi_cmdlist_put(&cmdreq);
+}
+
+static int mipi_dsi_3d_barrier_sysfs_register(struct device *dev);
+static int barrier_mode;
+
+static int __devinit mipi_novatek_lcd_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+	struct platform_device *current_pdev;
+	static struct mipi_dsi_phy_ctrl *phy_settings;
+	static char dlane_swap;
+
+	if (pdev->id == 0) {
+		mipi_novatek_pdata = pdev->dev.platform_data;
+
+		if (mipi_novatek_pdata
+			&& mipi_novatek_pdata->phy_ctrl_settings) {
+			phy_settings = (mipi_novatek_pdata->phy_ctrl_settings);
+		}
+
+		if (mipi_novatek_pdata
+			&& mipi_novatek_pdata->dlane_swap) {
+			dlane_swap = (mipi_novatek_pdata->dlane_swap);
+		}
+
+		if (mipi_novatek_pdata
+			 && mipi_novatek_pdata->fpga_3d_config_addr)
+			mipi_novatek_3d_init(mipi_novatek_pdata
+	->fpga_3d_config_addr, mipi_novatek_pdata->fpga_ctrl_mode);
+
+		/* create sysfs to control 3D barrier for the Sharp panel */
+		if (mipi_dsi_3d_barrier_sysfs_register(&pdev->dev)) {
+			pr_err("%s: Failed to register 3d Barrier sysfs\n",
+						__func__);
+			return -ENODEV;
+		}
+		barrier_mode = 0;
+
+		return 0;
+	}
+
+	current_pdev = msm_fb_add_device(pdev);
+
+	if (current_pdev) {
+		mfd = platform_get_drvdata(current_pdev);
+		if (!mfd)
+			return -ENODEV;
+		if (mfd->key != MFD_KEY)
+			return -EINVAL;
+
+		mipi  = &mfd->panel_info.mipi;
+
+		if (phy_settings != NULL)
+			mipi->dsi_phy_db = phy_settings;
+
+		if (dlane_swap)
+			mipi->dlane_swap = dlane_swap;
+	}
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mipi_novatek_lcd_probe,
+	.driver = {
+		.name   = "mipi_novatek",
+	},
+};
+
+static struct msm_fb_panel_data novatek_panel_data = {
+	.on		= mipi_novatek_lcd_on,
+	.off		= mipi_novatek_lcd_off,
+	.set_backlight = mipi_novatek_set_backlight,
+};
+
+static ssize_t mipi_dsi_3d_barrier_read(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	return snprintf((char *)buf, sizeof(buf), "%u\n", barrier_mode);
+}
+
+static ssize_t mipi_dsi_3d_barrier_write(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf,
+				size_t count)
+{
+	int ret = -1;
+	u32 data = 0;
+
+	if (sscanf((char *)buf, "%u", &data) != 1) {
+		dev_err(dev, "%s\n", __func__);
+		ret = -EINVAL;
+	} else {
+		barrier_mode = data;
+		if (data == 1)
+			mipi_dsi_enable_3d_barrier(LANDSCAPE);
+		else if (data == 2)
+			mipi_dsi_enable_3d_barrier(PORTRAIT);
+		else
+			mipi_dsi_enable_3d_barrier(0);
+	}
+
+	return count;
+}
+
+static struct device_attribute mipi_dsi_3d_barrier_attributes[] = {
+	__ATTR(enable_3d_barrier, 0664, mipi_dsi_3d_barrier_read,
+					 mipi_dsi_3d_barrier_write),
+};
+
+static int mipi_dsi_3d_barrier_sysfs_register(struct device *dev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mipi_dsi_3d_barrier_attributes); i++)
+		if (device_create_file(dev, mipi_dsi_3d_barrier_attributes + i))
+			goto error;
+
+	return 0;
+
+error:
+	for (; i >= 0 ; i--)
+		device_remove_file(dev, mipi_dsi_3d_barrier_attributes + i);
+	pr_err("%s: Unable to create interface\n", __func__);
+
+	return -ENODEV;
+}
+
+static int ch_used[3];
+
+int mipi_novatek_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	ret = mipi_novatek_lcd_init();
+	if (ret) {
+		pr_err("mipi_novatek_lcd_init() failed with ret %u\n", ret);
+		return ret;
+	}
+
+	pdev = platform_device_alloc("mipi_novatek", (panel << 8)|channel);
+	if (!pdev)
+		return -ENOMEM;
+
+	novatek_panel_data.panel_info = *pinfo;
+
+	ret = platform_device_add_data(pdev, &novatek_panel_data,
+		sizeof(novatek_panel_data));
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int mipi_novatek_lcd_init(void)
+{
+#ifdef CONFIG_SPI_QUP
+	int ret;
+	ret = spi_register_driver(&panel_3d_spi_driver);
+
+	if (ret) {
+		pr_err("%s: spi register failed: rc=%d\n", __func__, ret);
+		platform_driver_unregister(&this_driver);
+	} else
+		pr_info("%s: SUCCESS (SPI)\n", __func__);
+#endif
+
+	mipi_dsi_buf_alloc(&novatek_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&novatek_rx_buf, DSI_BUF_SIZE);
+
+	return platform_driver_register(&this_driver);
+}
diff --git a/drivers/video/msm/mipi_novatek.h b/drivers/video/msm/mipi_novatek.h
new file mode 100644
index 0000000..f84de9a
--- /dev/null
+++ b/drivers/video/msm/mipi_novatek.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MIPI_NOVATEK_BLUE_H
+#define MIPI_NOVATEK_BLUE_H
+
+#define NOVATEK_TWO_LANE
+
+int mipi_novatek_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#endif  /* MIPI_NOVATEK_BLUE_H */
diff --git a/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
new file mode 100644
index 0000000..f139f4c
--- /dev/null
+++ b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
@@ -0,0 +1,100 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_novatek.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_cmd_mode_phy_db = {
+/* DSI_BIT_CLK at 500MHz, 2 lane, RGB888 */
+		{0x03, 0x01, 0x01, 0x00},	/* regulator */
+		/* timing   */
+		{0xB4, 0x8D, 0x1D, 0x00, 0x20, 0x94, 0x20,
+		0x8F, 0x20, 0x03, 0x04},
+		{0x7f, 0x00, 0x00, 0x00},	/* phy ctrl */
+		{0xee, 0x02, 0x86, 0x00},	/* strength */
+		/* pll control */
+		{0x40, 0xf9, 0xb0, 0xda, 0x00, 0x50, 0x48, 0x63,
+#if defined(NOVATEK_TWO_LANE)
+		0x30, 0x07, 0x03,
+#else           /* default set to 1 lane */
+		0x30, 0x07, 0x07,
+#endif
+		0x05, 0x14, 0x03, 0x0, 0x0, 0x54, 0x06, 0x10, 0x04, 0x0},
+};
+
+static int __init mipi_cmd_novatek_blue_qhd_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_cmd_novatek_qhd"))
+		return 0;
+
+	pinfo.xres = 540;
+	pinfo.yres = 960;
+	pinfo.type = MIPI_CMD_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 50;
+	pinfo.lcdc.h_front_porch = 50;
+	pinfo.lcdc.h_pulse_width = 20;
+	pinfo.lcdc.v_back_porch = 11;
+	pinfo.lcdc.v_front_porch = 10;
+	pinfo.lcdc.v_pulse_width = 5;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 255;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+	pinfo.clk_rate = 454000000;
+	pinfo.is_3d_panel = FB_TYPE_3D_PANEL;
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.lcd.hw_vsync_mode = TRUE;
+	pinfo.lcd.refx100 = 6000; /* adjust refx100 to prevent tearing */
+	pinfo.lcd.v_back_porch = 11;
+	pinfo.lcd.v_front_porch = 10;
+	pinfo.lcd.v_pulse_width = 5;
+
+	pinfo.mipi.mode = DSI_CMD_MODE;
+	pinfo.mipi.dst_format = DSI_CMD_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.esc_byte_ratio = 4;
+#if defined(NOVATEK_TWO_LANE)
+	pinfo.mipi.data_lane1 = TRUE;
+#endif
+	pinfo.mipi.t_clk_post = 0x22;
+	pinfo.mipi.t_clk_pre = 0x3f;
+	pinfo.mipi.stream = 0;	/* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.te_sel = 1; /* TE from vsycn gpio */
+	pinfo.mipi.interleave_max = 1;
+	pinfo.mipi.insert_dcs_cmd = TRUE;
+	pinfo.mipi.wr_mem_continue = 0x3c;
+	pinfo.mipi.wr_mem_start = 0x2c;
+	pinfo.mipi.dsi_phy_db = &dsi_cmd_mode_phy_db;
+
+	ret = mipi_novatek_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_QHD_PT);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_cmd_novatek_blue_qhd_pt_init);
diff --git a/drivers/video/msm/mipi_novatek_video_qhd_pt.c b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
new file mode 100644
index 0000000..7a9d556
--- /dev/null
+++ b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
@@ -0,0 +1,97 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_novatek.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+/* DSI_BIT_CLK at 500MHz, 2 lane, RGB888 */
+		{0x03, 0x01, 0x01, 0x00},	/* regulator */
+		/* timing   */
+		{0x82, 0x31, 0x13, 0x0, 0x42, 0x4D, 0x18,
+		0x35, 0x21, 0x03, 0x04},
+		{0x7f, 0x00, 0x00, 0x00},	/* phy ctrl */
+		{0xee, 0x02, 0x86, 0x00},	/* strength */
+		/* pll control */
+		{0x40, 0xf9, 0xb0, 0xda, 0x00, 0x50, 0x48, 0x63,
+#if defined(NOVATEK_TWO_LANE)
+		0x30, 0x07, 0x03,
+#else           /* default set to 1 lane */
+		0x30, 0x07, 0x07,
+#endif
+		0x05, 0x14, 0x03, 0x0, 0x0, 0x54, 0x06, 0x10, 0x04, 0x0},
+};
+
+static int __init mipi_video_novatek_qhd_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_novatek_qhd"))
+		return 0;
+
+	pinfo.xres = 540;
+	pinfo.yres = 960;
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 80;
+	pinfo.lcdc.h_front_porch = 24;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 16;
+	pinfo.lcdc.v_front_porch = 8;
+	pinfo.lcdc.v_pulse_width = 1;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 15;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	pinfo.mipi.pulse_mode_hsa_he = TRUE;
+	pinfo.mipi.hfp_power_stop = FALSE;
+	pinfo.mipi.hbp_power_stop = FALSE;
+	pinfo.mipi.hsa_power_stop = FALSE;
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	pinfo.mipi.bllp_power_stop = TRUE;
+	pinfo.mipi.traffic_mode = DSI_NON_BURST_SYNCH_PULSE;
+	pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_BGR;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.esc_byte_ratio = 4;
+#if defined(NOVATEK_TWO_LANE)
+	pinfo.mipi.data_lane1 = TRUE;
+#endif
+	pinfo.mipi.tx_eot_append = TRUE;
+	pinfo.mipi.t_clk_post = 0x04;
+	pinfo.mipi.t_clk_pre = 0x1c;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60;
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+	ret = mipi_novatek_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_QHD_PT);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_novatek_qhd_pt_init);
diff --git a/drivers/video/msm/mipi_orise.c b/drivers/video/msm/mipi_orise.c
new file mode 100644
index 0000000..d1d6956
--- /dev/null
+++ b/drivers/video/msm/mipi_orise.c
@@ -0,0 +1,194 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_orise.h"
+#include "mdp4.h"
+
+
+static struct mipi_dsi_panel_platform_data *mipi_orise_pdata;
+
+static struct dsi_buf orise_tx_buf;
+static struct dsi_buf orise_rx_buf;
+
+static char enter_sleep[2] = {0x10, 0x00}; /* DTYPE_DCS_WRITE */
+static char exit_sleep[2] = {0x11, 0x00}; /* DTYPE_DCS_WRITE */
+static char display_off[2] = {0x28, 0x00}; /* DTYPE_DCS_WRITE */
+static char display_on[2] = {0x29, 0x00}; /* DTYPE_DCS_WRITE */
+
+static struct dsi_cmd_desc orise_video_on_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(display_on), display_on},
+};
+
+static struct dsi_cmd_desc orise_cmd_on_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(display_on), display_on},
+};
+
+static struct dsi_cmd_desc orise_display_off_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,
+		sizeof(display_off), display_off},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 120,
+		sizeof(enter_sleep), enter_sleep}
+};
+
+static int mipi_orise_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+	struct msm_panel_info *pinfo;
+
+	mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	pinfo = &mfd->panel_info;
+	mipi  = &mfd->panel_info.mipi;
+
+	if (mipi->mode == DSI_VIDEO_MODE) {
+		mipi_dsi_cmds_tx(&orise_tx_buf, orise_video_on_cmds,
+			ARRAY_SIZE(orise_video_on_cmds));
+	} else {
+		mipi_dsi_cmds_tx(&orise_tx_buf, orise_cmd_on_cmds,
+			ARRAY_SIZE(orise_cmd_on_cmds));
+
+		mipi_dsi_cmd_bta_sw_trigger(); /* clean up ack_err_status */
+	}
+
+	return 0;
+}
+
+static int mipi_orise_lcd_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi_dsi_cmds_tx(&orise_tx_buf, orise_display_off_cmds,
+			ARRAY_SIZE(orise_display_off_cmds));
+
+	return 0;
+}
+
+
+
+static int __devinit mipi_orise_lcd_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+	struct platform_device *current_pdev;
+	static struct mipi_dsi_phy_ctrl *phy_settings;
+
+	if (pdev->id == 0) {
+		mipi_orise_pdata = pdev->dev.platform_data;
+
+		if (mipi_orise_pdata
+			&& mipi_orise_pdata->phy_ctrl_settings) {
+			phy_settings = (mipi_orise_pdata->phy_ctrl_settings);
+		}
+
+		return 0;
+	}
+
+	current_pdev = msm_fb_add_device(pdev);
+
+	if (current_pdev) {
+		mfd = platform_get_drvdata(current_pdev);
+		if (!mfd)
+			return -ENODEV;
+		if (mfd->key != MFD_KEY)
+			return -EINVAL;
+
+		mipi  = &mfd->panel_info.mipi;
+
+		if (phy_settings != NULL)
+			mipi->dsi_phy_db = phy_settings;
+	}
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mipi_orise_lcd_probe,
+	.driver = {
+		.name   = "mipi_orise",
+	},
+};
+
+static struct msm_fb_panel_data orise_panel_data = {
+	.on		= mipi_orise_lcd_on,
+	.off		= mipi_orise_lcd_off,
+};
+
+static int ch_used[3];
+
+int mipi_orise_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	pdev = platform_device_alloc("mipi_orise", (panel << 8)|channel);
+	if (!pdev)
+		return -ENOMEM;
+
+	orise_panel_data.panel_info = *pinfo;
+
+	ret = platform_device_add_data(pdev, &orise_panel_data,
+		sizeof(orise_panel_data));
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int __init mipi_orise_lcd_init(void)
+{
+	mipi_dsi_buf_alloc(&orise_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&orise_rx_buf, DSI_BUF_SIZE);
+
+	return platform_driver_register(&this_driver);
+}
+
+module_init(mipi_orise_lcd_init);
diff --git a/drivers/video/msm/mipi_orise.h b/drivers/video/msm/mipi_orise.h
new file mode 100644
index 0000000..1659479
--- /dev/null
+++ b/drivers/video/msm/mipi_orise.h
@@ -0,0 +1,21 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+
+#ifndef MIPI_ORISE_H
+#define MIPI_ORISE_H
+
+int mipi_orise_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#endif  /* MIPI_ORISE_H */
diff --git a/drivers/video/msm/mipi_orise_cmd_720p_pt.c b/drivers/video/msm/mipi_orise_cmd_720p_pt.c
new file mode 100644
index 0000000..c2a158d
--- /dev/null
+++ b/drivers/video/msm/mipi_orise_cmd_720p_pt.c
@@ -0,0 +1,96 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_orise.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_cmd_mode_phy_db = {
+/* DSI_BIT_CLK at 507MHz, 4 lane, RGB888 */
+	{0x03, 0x0a, 0x04, 0x00, 0x20},
+	/* timing */
+	{0x8c, 0x34, 0x15, 0x00, 0x46, 0x50, 0x1a, 0x38,
+	0x24, 0x03, 0x04, 0xa0},
+    /* phy ctrl */
+	{0x5f, 0x00, 0x00, 0x10},
+    /* strength */
+	{0xff, 0x00, 0x06, 0x00},
+	/* pll control */
+		{0x0, 0xf9, 0x30, 0xda, 0x00, 0x40, 0x03, 0x62,
+	0x40, 0x07, 0x03,
+	0x00, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01 },
+};
+
+static int __init mipi_cmd_orise_720p_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_cmd_orise_720p"))
+		return 0;
+
+	pinfo.xres = 720;
+	pinfo.yres = 1280;
+	pinfo.type = MIPI_CMD_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 160;
+	pinfo.lcdc.h_front_porch = 160;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 32;
+	pinfo.lcdc.v_front_porch = 32;
+	pinfo.lcdc.v_pulse_width = 1;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 200;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+	pinfo.clk_rate = 507000000;
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.lcd.hw_vsync_mode = TRUE;
+	pinfo.lcd.refx100 = 6000; /* adjust refx100 to prevent tearing */
+	pinfo.lcd.v_back_porch = 32;
+	pinfo.lcd.v_front_porch = 32;
+	pinfo.lcd.v_pulse_width = 1;
+
+	pinfo.mipi.mode = DSI_CMD_MODE;
+	pinfo.mipi.dst_format = DSI_CMD_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.data_lane2 = TRUE;
+	pinfo.mipi.data_lane3 = TRUE;
+	pinfo.mipi.t_clk_post = 0x04;
+	pinfo.mipi.t_clk_pre = 0x1e;
+	pinfo.mipi.stream = 0;	/* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.te_sel = 1; /* TE from vsycn gpio */
+	pinfo.mipi.interleave_max = 1;
+	pinfo.mipi.insert_dcs_cmd = TRUE;
+	pinfo.mipi.wr_mem_continue = 0x3c;
+	pinfo.mipi.wr_mem_start = 0x2c;
+	pinfo.mipi.dsi_phy_db = &dsi_cmd_mode_phy_db;
+
+	ret = mipi_orise_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_720P_PT);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_cmd_orise_720p_pt_init);
diff --git a/drivers/video/msm/mipi_orise_video_720p_pt.c b/drivers/video/msm/mipi_orise_video_720p_pt.c
new file mode 100644
index 0000000..da8b5e5
--- /dev/null
+++ b/drivers/video/msm/mipi_orise_video_720p_pt.c
@@ -0,0 +1,98 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_orise.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+    /* regulator */
+	{0x03, 0x0a, 0x04, 0x00, 0x20},
+	/* timing */
+	{0x83, 0x31, 0x13, 0x00, 0x42, 0x4d, 0x18, 0x35,
+	0x21, 0x03, 0x04, 0xa0},
+    /* phy ctrl */
+	{0x5f, 0x00, 0x00, 0x10},
+    /* strength */
+	{0xff, 0x00, 0x06, 0x00},
+	/* pll control */
+	{0x0, 0x0e, 0x30, 0xc0, 0x00, 0x40, 0x03, 0x62,
+	0x40, 0x07, 0x07,
+	0x00, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01 },
+};
+
+static int __init mipi_video_orise_720p_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_orise_720p"))
+		return 0;
+
+	pinfo.xres = 720;
+	pinfo.yres = 1280;
+	pinfo.lcdc.xres_pad = 0;
+	pinfo.lcdc.yres_pad = 0;
+
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 160;
+	pinfo.lcdc.h_front_porch = 160;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 32;
+	pinfo.lcdc.v_front_porch = 32;
+	pinfo.lcdc.v_pulse_width = 1;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 200;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	pinfo.mipi.pulse_mode_hsa_he = TRUE;
+	pinfo.mipi.hfp_power_stop = TRUE;
+	pinfo.mipi.hbp_power_stop = TRUE;
+	pinfo.mipi.hsa_power_stop = FALSE;
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	pinfo.mipi.bllp_power_stop = TRUE;
+	pinfo.mipi.traffic_mode = DSI_NON_BURST_SYNCH_EVENT;
+	pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.data_lane2 = TRUE;
+	pinfo.mipi.data_lane3 = TRUE;
+	pinfo.mipi.t_clk_post = 0x04;
+	pinfo.mipi.t_clk_pre = 0x1c;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = 0;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 55;
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+	pinfo.mipi.tx_eot_append = TRUE;
+	pinfo.mipi.esc_byte_ratio = 4;
+
+	ret = mipi_orise_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_720P_PT);
+	if (ret)
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_orise_720p_pt_init);
diff --git a/drivers/video/msm/mipi_renesas.c b/drivers/video/msm/mipi_renesas.c
new file mode 100644
index 0000000..2e1a805
--- /dev/null
+++ b/drivers/video/msm/mipi_renesas.c
@@ -0,0 +1,1262 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_renesas.h"
+#include <mach/socinfo.h>
+
+#define RENESAS_CMD_DELAY 0 /* 50 */
+#define RENESAS_SLEEP_OFF_DELAY 50
+static struct msm_panel_common_pdata *mipi_renesas_pdata;
+
+static struct dsi_buf renesas_tx_buf;
+static struct dsi_buf renesas_rx_buf;
+
+static int mipi_renesas_lcd_init(void);
+
+static char config_sleep_out[2] = {0x11, 0x00};
+static char config_CMD_MODE[2] = {0x40, 0x01};
+static char config_WRTXHT[7] = {0x92, 0x16, 0x08, 0x08, 0x00, 0x01, 0xe0};
+static char config_WRTXVT[7] = {0x8b, 0x02, 0x02, 0x02, 0x00, 0x03, 0x60};
+static char config_PLL2NR[2] = {0xa0, 0x24};
+static char config_PLL2NF1[2] = {0xa2, 0xd0};
+static char config_PLL2NF2[2] = {0xa4, 0x00};
+static char config_PLL2BWADJ1[2] = {0xa6, 0xd0};
+static char config_PLL2BWADJ2[2] = {0xa8, 0x00};
+static char config_PLL2CTL[2] = {0xaa, 0x00};
+static char config_DBICBR[2] = {0x48, 0x03};
+static char config_DBICTYPE[2] = {0x49, 0x00};
+static char config_DBICSET1[2] = {0x4a, 0x1c};
+static char config_DBICADD[2] = {0x4b, 0x00};
+static char config_DBICCTL[2] = {0x4e, 0x01};
+/* static char config_COLMOD_565[2] = {0x3a, 0x05}; */
+/* static char config_COLMOD_666PACK[2] = {0x3a, 0x06}; */
+static char config_COLMOD_888[2] = {0x3a, 0x07};
+static char config_MADCTL[2] = {0x36, 0x00};
+static char config_DBIOC[2] = {0x82, 0x40};
+static char config_CASET[7] = {0x2a, 0x00, 0x00, 0x00, 0x00, 0x01, 0xdf };
+static char config_PASET[7] = {0x2b, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5f };
+static char config_TXON[2] = {0x81, 0x00};
+static char config_BLSET_TM[2] = {0xff, 0x6c};
+static char config_DSIRXCTL[2] = {0x41, 0x01};
+static char config_TEON[2] = {0x35, 0x00};
+static char config_TEOFF[1] = {0x34};
+
+static char config_AGCPSCTL_TM[2] = {0x56, 0x08};
+
+static char config_DBICADD70[2] = {0x4b, 0x70};
+static char config_DBICSET_15[2] = {0x4a, 0x15};
+static char config_DBICADD72[2] = {0x4b, 0x72};
+
+static char config_Power_Ctrl_2a_cmd[3] = {0x4c, 0x40, 0x10};
+static char config_Auto_Sequencer_Setting_a_cmd[3] = {0x4c, 0x00, 0x00};
+static char Driver_Output_Ctrl_indx[3] = {0x4c, 0x00, 0x01};
+static char Driver_Output_Ctrl_cmd[3] = {0x4c, 0x03, 0x10};
+static char config_LCD_drive_AC_Ctrl_indx[3] = {0x4c, 0x00, 0x02};
+static char config_LCD_drive_AC_Ctrl_cmd[3] = {0x4c, 0x01, 0x00};
+static char config_Entry_Mode_indx[3] = {0x4c, 0x00, 0x03};
+static char config_Entry_Mode_cmd[3] = {0x4c, 0x00, 0x00};
+static char config_Display_Ctrl_1_indx[3] = {0x4c, 0x00, 0x07};
+static char config_Display_Ctrl_1_cmd[3] = {0x4c, 0x00, 0x00};
+static char config_Display_Ctrl_2_indx[3] = {0x4c, 0x00, 0x08};
+static char config_Display_Ctrl_2_cmd[3] = {0x4c, 0x00, 0x04};
+static char config_Display_Ctrl_3_indx[3] = {0x4c, 0x00, 0x09};
+static char config_Display_Ctrl_3_cmd[3] = {0x4c, 0x00, 0x0c};
+static char config_Display_IF_Ctrl_1_indx[3] = {0x4c, 0x00, 0x0c};
+static char config_Display_IF_Ctrl_1_cmd[3] = {0x4c, 0x40, 0x10};
+static char config_Display_IF_Ctrl_2_indx[3] = {0x4c, 0x00, 0x0e};
+static char config_Display_IF_Ctrl_2_cmd[3] = {0x4c, 0x00, 0x00};
+
+static char config_Panel_IF_Ctrl_1_indx[3] = {0x4c, 0x00, 0x20};
+static char config_Panel_IF_Ctrl_1_cmd[3] = {0x4c, 0x01, 0x3f};
+static char config_Panel_IF_Ctrl_3_indx[3] = {0x4c, 0x00, 0x22};
+static char config_Panel_IF_Ctrl_3_cmd[3] = {0x4c, 0x76, 0x00};
+static char config_Panel_IF_Ctrl_4_indx[3] = {0x4c, 0x00, 0x23};
+static char config_Panel_IF_Ctrl_4_cmd[3] = {0x4c, 0x1c, 0x0a};
+static char config_Panel_IF_Ctrl_5_indx[3] = {0x4c, 0x00, 0x24};
+static char config_Panel_IF_Ctrl_5_cmd[3] = {0x4c, 0x1c, 0x2c};
+static char config_Panel_IF_Ctrl_6_indx[3] = {0x4c, 0x00, 0x25};
+static char config_Panel_IF_Ctrl_6_cmd[3] = {0x4c, 0x1c, 0x4e};
+static char config_Panel_IF_Ctrl_8_indx[3] = {0x4c, 0x00, 0x27};
+static char config_Panel_IF_Ctrl_8_cmd[3] = {0x4c, 0x00, 0x00};
+static char config_Panel_IF_Ctrl_9_indx[3] = {0x4c, 0x00, 0x28};
+static char config_Panel_IF_Ctrl_9_cmd[3] = {0x4c, 0x76, 0x0c};
+
+
+static char config_gam_adjust_00_indx[3] = {0x4c, 0x03, 0x00};
+static char config_gam_adjust_00_cmd[3] = {0x4c, 0x00, 0x00};
+static char config_gam_adjust_01_indx[3] = {0x4c, 0x03, 0x01};
+static char config_gam_adjust_01_cmd[3] = {0x4c, 0x05, 0x02};
+static char config_gam_adjust_02_indx[3] = {0x4c, 0x03, 0x02};
+static char config_gam_adjust_02_cmd[3] = {0x4c, 0x07, 0x05};
+static char config_gam_adjust_03_indx[3] = {0x4c, 0x03, 0x03};
+static char config_gam_adjust_03_cmd[3] = {0x4c, 0x00, 0x00};
+static char config_gam_adjust_04_indx[3] = {0x4c, 0x03, 0x04};
+static char config_gam_adjust_04_cmd[3] = {0x4c, 0x02, 0x00};
+static char config_gam_adjust_05_indx[3] = {0x4c, 0x03, 0x05};
+static char config_gam_adjust_05_cmd[3] = {0x4c, 0x07, 0x07};
+static char config_gam_adjust_06_indx[3] = {0x4c, 0x03, 0x06};
+static char config_gam_adjust_06_cmd[3] = {0x4c, 0x10, 0x10};
+static char config_gam_adjust_07_indx[3] = {0x4c, 0x03, 0x07};
+static char config_gam_adjust_07_cmd[3] = {0x4c, 0x02, 0x02};
+static char config_gam_adjust_08_indx[3] = {0x4c, 0x03, 0x08};
+static char config_gam_adjust_08_cmd[3] = {0x4c, 0x07, 0x04};
+static char config_gam_adjust_09_indx[3] = {0x4c, 0x03, 0x09};
+static char config_gam_adjust_09_cmd[3] = {0x4c, 0x07, 0x07};
+static char config_gam_adjust_0A_indx[3] = {0x4c, 0x03, 0x0a};
+static char config_gam_adjust_0A_cmd[3] = {0x4c, 0x00, 0x00};
+static char config_gam_adjust_0B_indx[3] = {0x4c, 0x03, 0x0b};
+static char config_gam_adjust_0B_cmd[3] = {0x4c, 0x00, 0x00};
+static char config_gam_adjust_0C_indx[3] = {0x4c, 0x03, 0x0c};
+static char config_gam_adjust_0C_cmd[3] = {0x4c, 0x07, 0x07};
+static char config_gam_adjust_0D_indx[3] = {0x4c, 0x03, 0x0d};
+static char config_gam_adjust_0D_cmd[3] = {0x4c, 0x10, 0x10};
+static char config_gam_adjust_10_indx[3] = {0x4c, 0x03, 0x10};
+static char config_gam_adjust_10_cmd[3] = {0x4c, 0x01, 0x04};
+static char config_gam_adjust_11_indx[3] = {0x4c, 0x03, 0x11};
+static char config_gam_adjust_11_cmd[3] = {0x4c, 0x05, 0x03};
+static char config_gam_adjust_12_indx[3] = {0x4c, 0x03, 0x12};
+static char config_gam_adjust_12_cmd[3] = {0x4c, 0x03, 0x04};
+static char config_gam_adjust_15_indx[3] = {0x4c, 0x03, 0x15};
+static char config_gam_adjust_15_cmd[3] = {0x4c, 0x03, 0x04};
+static char config_gam_adjust_16_indx[3] = {0x4c, 0x03, 0x16};
+static char config_gam_adjust_16_cmd[3] = {0x4c, 0x03, 0x1c};
+static char config_gam_adjust_17_indx[3] = {0x4c, 0x03, 0x17};
+static char config_gam_adjust_17_cmd[3] = {0x4c, 0x02, 0x04};
+static char config_gam_adjust_18_indx[3] = {0x4c, 0x03, 0x18};
+static char config_gam_adjust_18_cmd[3] = {0x4c, 0x04, 0x02};
+static char config_gam_adjust_19_indx[3] = {0x4c, 0x03, 0x19};
+static char config_gam_adjust_19_cmd[3] = {0x4c, 0x03, 0x05};
+static char config_gam_adjust_1C_indx[3] = {0x4c, 0x03, 0x1c};
+static char config_gam_adjust_1C_cmd[3] = {0x4c, 0x07, 0x07};
+static char config_gam_adjust_1D_indx[3] = {0x4c, 0x03, 0x1D};
+static char config_gam_adjust_1D_cmd[3] = {0x4c, 0x02, 0x1f};
+static char config_gam_adjust_20_indx[3] = {0x4c, 0x03, 0x20};
+static char config_gam_adjust_20_cmd[3] = {0x4c, 0x05, 0x07};
+static char config_gam_adjust_21_indx[3] = {0x4c, 0x03, 0x21};
+static char config_gam_adjust_21_cmd[3] = {0x4c, 0x06, 0x04};
+static char config_gam_adjust_22_indx[3] = {0x4c, 0x03, 0x22};
+static char config_gam_adjust_22_cmd[3] = {0x4c, 0x04, 0x05};
+static char config_gam_adjust_27_indx[3] = {0x4c, 0x03, 0x27};
+static char config_gam_adjust_27_cmd[3] = {0x4c, 0x02, 0x03};
+static char config_gam_adjust_28_indx[3] = {0x4c, 0x03, 0x28};
+static char config_gam_adjust_28_cmd[3] = {0x4c, 0x03, 0x00};
+static char config_gam_adjust_29_indx[3] = {0x4c, 0x03, 0x29};
+static char config_gam_adjust_29_cmd[3] = {0x4c, 0x00, 0x02};
+
+static char config_Power_Ctrl_1_indx[3] = {0x4c, 0x01, 0x00};
+static char config_Power_Ctrl_1b_cmd[3] = {0x4c, 0x36, 0x3c};
+static char config_Power_Ctrl_2_indx[3] = {0x4c, 0x01, 0x01};
+static char config_Power_Ctrl_2b_cmd[3] = {0x4c, 0x40, 0x03};
+static char config_Power_Ctrl_3_indx[3] = {0x4c, 0x01, 0x02};
+static char config_Power_Ctrl_3a_cmd[3] = {0x4c, 0x00, 0x01};
+static char config_Power_Ctrl_4_indx[3] = {0x4c, 0x01, 0x03};
+static char config_Power_Ctrl_4a_cmd[3] = {0x4c, 0x3c, 0x58};
+static char config_Power_Ctrl_6_indx[3] = {0x4c, 0x01, 0x0c};
+static char config_Power_Ctrl_6a_cmd[3] = {0x4c, 0x01, 0x35};
+
+static char config_Auto_Sequencer_Setting_b_cmd[3] = {0x4c, 0x00, 0x02};
+
+static char config_Panel_IF_Ctrl_10_indx[3] = {0x4c, 0x00, 0x29};
+static char config_Panel_IF_Ctrl_10a_cmd[3] = {0x4c, 0x03, 0xbf};
+static char config_Auto_Sequencer_Setting_indx[3] = {0x4c, 0x01, 0x06};
+static char config_Auto_Sequencer_Setting_c_cmd[3] = {0x4c, 0x00, 0x03};
+static char config_Power_Ctrl_2c_cmd[3] = {0x4c, 0x40, 0x10};
+
+static char config_VIDEO[2] = {0x40, 0x00};
+
+static char config_Panel_IF_Ctrl_10_indx_off[3] = {0x4C, 0x00, 0x29};
+
+static char config_Panel_IF_Ctrl_10b_cmd_off[3] = {0x4C, 0x00, 0x02};
+
+static char config_Power_Ctrl_1a_cmd[3] = {0x4C, 0x30, 0x00};
+
+static struct dsi_cmd_desc renesas_sleep_off_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, RENESAS_SLEEP_OFF_DELAY,
+		sizeof(config_sleep_out), config_sleep_out }
+};
+
+static struct dsi_cmd_desc renesas_display_off_cmds[] = {
+	/* Choosing Command Mode */
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_CMD_MODE), config_CMD_MODE },
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_indx),
+			config_Auto_Sequencer_Setting_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_b_cmd),
+			config_Auto_Sequencer_Setting_b_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY * 2,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	/* After waiting >= 5 frames, turn OFF RGB signals
+	This is done by on DSI/MDP (depends on Vid/Cmd Mode.  */
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_indx),
+			config_Auto_Sequencer_Setting_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_a_cmd),
+			config_Auto_Sequencer_Setting_a_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_10_indx_off),
+			config_Panel_IF_Ctrl_10_indx_off},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_10b_cmd_off),
+				config_Panel_IF_Ctrl_10b_cmd_off},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_1_indx),
+				config_Power_Ctrl_1_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_1a_cmd),
+				config_Power_Ctrl_1a_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_TEOFF), config_TEOFF},
+};
+
+static struct dsi_cmd_desc renesas_display_on_cmds[] = {
+	/* Choosing Command Mode */
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_CMD_MODE), config_CMD_MODE },
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_WRTXHT), config_WRTXHT },
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_WRTXVT), config_WRTXVT },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_PLL2NR), config_PLL2NR },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_PLL2NF1), config_PLL2NF1 },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_PLL2NF2), config_PLL2NF2 },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_PLL2BWADJ1), config_PLL2BWADJ1},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_PLL2BWADJ2), config_PLL2BWADJ2},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_PLL2CTL), config_PLL2CTL},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICBR), config_DBICBR},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICTYPE), config_DBICTYPE},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET1), config_DBICSET1},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD), config_DBICADD},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICCTL), config_DBICCTL},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_COLMOD_888), config_COLMOD_888},
+	/* Choose config_COLMOD_565 or config_COLMOD_666PACK for other modes */
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_MADCTL), config_MADCTL},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBIOC), config_DBIOC},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_CASET), config_CASET},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_PASET), config_PASET},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DSIRXCTL), config_DSIRXCTL},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_TEON), config_TEON},
+	{DTYPE_DCS_WRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_TXON), config_TXON},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_BLSET_TM), config_BLSET_TM},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_AGCPSCTL_TM), config_AGCPSCTL_TM},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_1_indx), config_Power_Ctrl_1_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_1a_cmd), config_Power_Ctrl_1a_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_2_indx), config_Power_Ctrl_2_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_2a_cmd), config_Power_Ctrl_2a_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_indx),
+			config_Auto_Sequencer_Setting_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_a_cmd),
+			config_Auto_Sequencer_Setting_a_cmd },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(Driver_Output_Ctrl_indx), Driver_Output_Ctrl_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(Driver_Output_Ctrl_cmd),
+			Driver_Output_Ctrl_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_LCD_drive_AC_Ctrl_indx),
+			config_LCD_drive_AC_Ctrl_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_LCD_drive_AC_Ctrl_cmd),
+			config_LCD_drive_AC_Ctrl_cmd },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Entry_Mode_indx),
+			config_Entry_Mode_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Entry_Mode_cmd),
+			config_Entry_Mode_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_Ctrl_1_indx),
+			config_Display_Ctrl_1_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_Ctrl_1_cmd),
+			config_Display_Ctrl_1_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_Ctrl_2_indx),
+			config_Display_Ctrl_2_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_Ctrl_2_cmd),
+			config_Display_Ctrl_2_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_Ctrl_3_indx),
+			config_Display_Ctrl_3_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_Ctrl_3_cmd),
+			config_Display_Ctrl_3_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_IF_Ctrl_1_indx),
+			config_Display_IF_Ctrl_1_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_IF_Ctrl_1_cmd),
+			config_Display_IF_Ctrl_1_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_IF_Ctrl_2_indx),
+			config_Display_IF_Ctrl_2_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Display_IF_Ctrl_2_cmd),
+			config_Display_IF_Ctrl_2_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_1_indx),
+			config_Panel_IF_Ctrl_1_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_1_cmd),
+			config_Panel_IF_Ctrl_1_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_3_indx),
+			config_Panel_IF_Ctrl_3_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_3_cmd),
+			config_Panel_IF_Ctrl_3_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_4_indx),
+			config_Panel_IF_Ctrl_4_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_4_cmd),
+			config_Panel_IF_Ctrl_4_cmd },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_5_indx),
+			config_Panel_IF_Ctrl_5_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_5_cmd),
+			config_Panel_IF_Ctrl_5_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_6_indx),
+			config_Panel_IF_Ctrl_6_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_6_cmd),
+			config_Panel_IF_Ctrl_6_cmd },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_8_indx),
+			config_Panel_IF_Ctrl_8_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_8_cmd),
+			config_Panel_IF_Ctrl_8_cmd },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_9_indx),
+			config_Panel_IF_Ctrl_9_indx },
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_9_cmd),
+			config_Panel_IF_Ctrl_9_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_00_indx),
+			config_gam_adjust_00_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_00_cmd),
+			config_gam_adjust_00_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_01_indx),
+			config_gam_adjust_01_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_01_cmd),
+			config_gam_adjust_01_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_02_indx),
+			config_gam_adjust_02_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_02_cmd),
+			config_gam_adjust_02_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_03_indx),
+			config_gam_adjust_03_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_03_cmd),
+			config_gam_adjust_03_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_04_indx), config_gam_adjust_04_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_04_cmd), config_gam_adjust_04_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_05_indx), config_gam_adjust_05_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_05_cmd), config_gam_adjust_05_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_06_indx), config_gam_adjust_06_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_06_cmd), config_gam_adjust_06_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_07_indx), config_gam_adjust_07_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_07_cmd), config_gam_adjust_07_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_08_indx), config_gam_adjust_08_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_08_cmd), config_gam_adjust_08_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_09_indx), config_gam_adjust_09_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_09_cmd), config_gam_adjust_09_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_0A_indx), config_gam_adjust_0A_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_0A_cmd), config_gam_adjust_0A_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_0B_indx), config_gam_adjust_0B_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_0B_cmd), config_gam_adjust_0B_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_0C_indx), config_gam_adjust_0C_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_0C_cmd), config_gam_adjust_0C_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_0D_indx), config_gam_adjust_0D_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_0D_cmd), config_gam_adjust_0D_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_10_indx), config_gam_adjust_10_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_10_cmd), config_gam_adjust_10_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_11_indx), config_gam_adjust_11_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_11_cmd), config_gam_adjust_11_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_12_indx), config_gam_adjust_12_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_12_cmd), config_gam_adjust_12_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_15_indx), config_gam_adjust_15_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_15_cmd), config_gam_adjust_15_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_16_indx), config_gam_adjust_16_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_16_cmd), config_gam_adjust_16_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_17_indx), config_gam_adjust_17_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_17_cmd), config_gam_adjust_17_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_18_indx), config_gam_adjust_18_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_18_cmd), config_gam_adjust_18_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_19_indx), config_gam_adjust_19_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_19_cmd), config_gam_adjust_19_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_1C_indx), config_gam_adjust_1C_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_1C_cmd), config_gam_adjust_1C_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_1D_indx), config_gam_adjust_1D_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_1D_cmd), config_gam_adjust_1D_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_20_indx), config_gam_adjust_20_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_20_cmd), config_gam_adjust_20_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_21_indx), config_gam_adjust_21_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_21_cmd), config_gam_adjust_21_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_22_indx), config_gam_adjust_22_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_22_cmd), config_gam_adjust_22_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_27_indx), config_gam_adjust_27_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_27_cmd), config_gam_adjust_27_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_28_indx), config_gam_adjust_28_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_28_cmd), config_gam_adjust_28_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_29_indx), config_gam_adjust_29_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_gam_adjust_29_cmd), config_gam_adjust_29_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_1_indx), config_Power_Ctrl_1_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_1b_cmd), config_Power_Ctrl_1b_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_2_indx), config_Power_Ctrl_2_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_2b_cmd), config_Power_Ctrl_2b_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_3_indx), config_Power_Ctrl_3_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_3a_cmd), config_Power_Ctrl_3a_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_4_indx), config_Power_Ctrl_4_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_4a_cmd), config_Power_Ctrl_4a_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_6_indx), config_Power_Ctrl_6_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_6a_cmd), config_Power_Ctrl_6a_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_indx),
+			config_Auto_Sequencer_Setting_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_b_cmd),
+			config_Auto_Sequencer_Setting_b_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_10_indx),
+			config_Panel_IF_Ctrl_10_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Panel_IF_Ctrl_10a_cmd),
+			config_Panel_IF_Ctrl_10a_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_indx),
+			config_Auto_Sequencer_Setting_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Auto_Sequencer_Setting_c_cmd),
+			config_Auto_Sequencer_Setting_c_cmd},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD70), config_DBICADD70},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_2_indx),
+			config_Power_Ctrl_2_indx},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_DBICADD72), config_DBICADD72},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_Power_Ctrl_2c_cmd),
+			config_Power_Ctrl_2c_cmd},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 0/* RENESAS_CMD_DELAY */,
+		sizeof(config_DBICSET_15), config_DBICSET_15},
+
+};
+
+static char config_WRTXHT2[7] = {0x92, 0x15, 0x05, 0x0F, 0x00, 0x01, 0xe0};
+static char config_WRTXVT2[7] = {0x8b, 0x14, 0x01, 0x14, 0x00, 0x03, 0x60};
+
+static struct dsi_cmd_desc renesas_hvga_on_cmds[] = {
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_WRTXHT2), config_WRTXHT2},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_WRTXVT2), config_WRTXVT2},
+};
+
+static struct dsi_cmd_desc renesas_video_on_cmds[] = {
+{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_VIDEO), config_VIDEO}
+};
+
+static struct dsi_cmd_desc renesas_cmd_on_cmds[] = {
+{DTYPE_DCS_WRITE1, 1, 0, 0, RENESAS_CMD_DELAY,
+		sizeof(config_CMD_MODE), config_CMD_MODE},
+};
+
+static int mipi_renesas_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+
+	mfd = platform_get_drvdata(pdev);
+	mipi  = &mfd->panel_info.mipi;
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_sleep_off_cmds,
+			ARRAY_SIZE(renesas_sleep_off_cmds));
+
+	mipi_set_tx_power_mode(1);
+	mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_display_on_cmds,
+			ARRAY_SIZE(renesas_display_on_cmds));
+
+	if (cpu_is_msm7x25a() || cpu_is_msm7x25aa()) {
+		mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_hvga_on_cmds,
+			ARRAY_SIZE(renesas_hvga_on_cmds));
+	}
+
+	if (mipi->mode == DSI_VIDEO_MODE)
+		mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_video_on_cmds,
+			ARRAY_SIZE(renesas_video_on_cmds));
+	else
+		mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_cmd_on_cmds,
+			ARRAY_SIZE(renesas_cmd_on_cmds));
+	mipi_set_tx_power_mode(0);
+
+	return 0;
+}
+
+static int mipi_renesas_lcd_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_display_off_cmds,
+			ARRAY_SIZE(renesas_display_off_cmds));
+
+	return 0;
+}
+
+static int __devinit mipi_renesas_lcd_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		mipi_renesas_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static void mipi_renesas_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int ret = -EPERM;
+	int bl_level;
+
+	bl_level = mfd->bl_level;
+
+	if (mipi_renesas_pdata && mipi_renesas_pdata->pmic_backlight)
+		ret = mipi_renesas_pdata->pmic_backlight(bl_level);
+	else
+		pr_err("%s(): Backlight level set failed", __func__);
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mipi_renesas_lcd_probe,
+	.driver = {
+		.name   = "mipi_renesas",
+	},
+};
+
+static struct msm_fb_panel_data renesas_panel_data = {
+	.on		= mipi_renesas_lcd_on,
+	.off	= mipi_renesas_lcd_off,
+	.set_backlight = mipi_renesas_set_backlight,
+};
+
+static int ch_used[3];
+
+int mipi_renesas_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	ret = mipi_renesas_lcd_init();
+	if (ret) {
+		pr_err("mipi_renesas_lcd_init() failed with ret %u\n", ret);
+		return ret;
+	}
+
+	pdev = platform_device_alloc("mipi_renesas", (panel << 8)|channel);
+	if (!pdev)
+		return -ENOMEM;
+
+	renesas_panel_data.panel_info = *pinfo;
+
+	ret = platform_device_add_data(pdev, &renesas_panel_data,
+		sizeof(renesas_panel_data));
+	if (ret) {
+		pr_err("%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		pr_err("%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int mipi_renesas_lcd_init(void)
+{
+	mipi_dsi_buf_alloc(&renesas_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&renesas_rx_buf, DSI_BUF_SIZE);
+
+	return platform_driver_register(&this_driver);
+}
diff --git a/drivers/video/msm/mipi_renesas.h b/drivers/video/msm/mipi_renesas.h
new file mode 100644
index 0000000..59ccfd0
--- /dev/null
+++ b/drivers/video/msm/mipi_renesas.h
@@ -0,0 +1,21 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MIPI_RENESAS_H
+#define MIPI_RENESAS_H
+
+#define RENESAS_FWVGA_TWO_LANE
+
+int mipi_renesas_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#endif  /* MIPI_RENESAS_H */
diff --git a/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
new file mode 100644
index 0000000..7f5ac70
--- /dev/null
+++ b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
@@ -0,0 +1,157 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_renesas.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_cmd_mode_phy_db = {
+#ifdef CONFIG_FB_MSM_MDP303
+	/* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */
+	/* regulator */
+	{0x03, 0x01, 0x01, 0x00},
+	/* timing   */
+	{0xb9, 0x8e, 0x1f, 0x00, 0x98, 0x9c, 0x22, 0x90,
+	0x18, 0x03, 0x04},
+	/* phy ctrl */
+	{0x7f, 0x00, 0x00, 0x00},
+	/* strength */
+	{0xbb, 0x02, 0x06, 0x00},
+	/* pll control */
+	{0x01, 0xec, 0x31, 0xd2, 0x00, 0x40, 0x37, 0x62,
+	0x01, 0x0f, 0x07,
+	0x05, 0x14, 0x03, 0x0, 0x0, 0x0, 0x20, 0x0, 0x02, 0x0},
+#else
+	/* DSI_BIT_CLK at 400MHz, 1 lane, RGB888 */
+	{0x03, 0x01, 0x01, 0x00},	/* regulator */
+	/* timing   */
+	{0x22, 0x0c, 0x7, 0x00, 0x10, 0x20, 0x10,
+	0xd, 0x8, 0x2, 0x3},
+	/* phy ctrl */
+	{0x7f, 0x00, 0x00, 0x00},
+	/* strength */
+	{0xee, 0x00, 0x6, 0x00},
+	/* pll control */
+	{0x40, 0x2f, 0xb1, 0xda, 0x00, 0x50, 0x48, 0x63,
+#if defined(RENESAS_FWVGA_TWO_LANE)
+	0x33, 0x1f, 0x07,
+#else	/* default set to 1 lane */
+	0x30, 0x07, 0x07,
+#endif
+	0x05, 0x14, 0x03, 0x0, 0x0, 0x54, 0x06, 0x10, 0x04, 0x0},
+#endif
+};
+
+static int __init mipi_cmd_renesas_fwvga_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_cmd_renesas_fwvga"))
+		return 0;
+
+	pinfo.xres = 480;
+	pinfo.yres = 864;
+	pinfo.type = MIPI_CMD_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+#ifdef CONFIG_FB_MSM_MDP303
+	pinfo.lcdc.h_back_porch = 100;
+	pinfo.lcdc.h_front_porch = 100;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 20;
+	pinfo.lcdc.v_front_porch = 20;
+	pinfo.lcdc.v_pulse_width = 1;
+#else
+	pinfo.lcdc.h_front_porch = 50;
+#if defined(RENESAS_FWVGA_TWO_LANE)
+	pinfo.lcdc.h_back_porch = 400;
+	pinfo.lcdc.h_pulse_width = 5;
+	pinfo.lcdc.v_back_porch = 75;
+	pinfo.lcdc.v_front_porch = 5;
+	pinfo.lcdc.v_pulse_width = 1;
+#else
+	pinfo.lcdc.h_back_porch = 50;
+	pinfo.lcdc.h_pulse_width = 20;
+	pinfo.lcdc.v_back_porch = 10;
+	pinfo.lcdc.v_front_porch = 10;
+	pinfo.lcdc.v_pulse_width = 5;
+#endif
+
+#endif /* CONFIG_FB_MSM_MDP303 */
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 100;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+#ifdef CONFIG_FB_MSM_MDP303
+	pinfo.clk_rate = 499000000;
+#else
+	pinfo.clk_rate = 152000000;
+#endif
+	pinfo.lcd.refx100 = 6000; /* adjust refx100 to prevent tearing */
+
+	pinfo.mipi.mode = DSI_CMD_MODE;
+	pinfo.mipi.dst_format = DSI_CMD_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo.mipi.data_lane0 = TRUE;
+#ifdef CONFIG_FB_MSM_MDP303
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.lcd.hw_vsync_mode = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.t_clk_post = 0x20;
+	pinfo.mipi.t_clk_pre = 0x2F;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.te_sel = 1; /* TE from vsync gpio */
+	pinfo.mipi.interleave_max = 1;
+	pinfo.mipi.insert_dcs_cmd = TRUE;
+	pinfo.mipi.wr_mem_continue = 0x3c;
+	pinfo.mipi.wr_mem_start = 0x2c;
+	pinfo.mipi.dsi_phy_db = &dsi_cmd_mode_phy_db;
+	pinfo.mipi.tx_eot_append = 0x01;
+	pinfo.mipi.rx_eot_ignore = 0;
+	pinfo.mipi.dlane_swap = 0x01;
+#else
+#if defined(RENESAS_FWVGA_TWO_LANE)
+	pinfo.mipi.data_lane1 = TRUE;
+#else
+	pinfo.mipi.data_lane1 = FALSE;
+#endif
+	pinfo.mipi.t_clk_post = 0x18;
+	pinfo.mipi.t_clk_pre = 0x14;
+	pinfo.mipi.stream = 0;	/* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.te_sel = 1; /* TE from vsycn gpio */
+	pinfo.mipi.interleave_max = 1;
+	pinfo.mipi.insert_dcs_cmd = TRUE;
+	pinfo.mipi.wr_mem_continue = 0x3c;
+	pinfo.mipi.wr_mem_start = 0x2c;
+	pinfo.mipi.dsi_phy_db = &dsi_cmd_mode_phy_db;
+#endif /* CONFIG_FB_MSM_MDP303 */
+
+	ret = mipi_renesas_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_FWVGA_PT);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_cmd_renesas_fwvga_pt_init);
diff --git a/drivers/video/msm/mipi_renesas_video_fwvga_pt.c b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
new file mode 100644
index 0000000..e826773
--- /dev/null
+++ b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
@@ -0,0 +1,163 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_renesas.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+#ifdef CONFIG_FB_MSM_MDP303
+	/* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */
+	/* regulator */
+	{0x03, 0x01, 0x01, 0x00},
+	/* timing   */
+	{0xb9, 0x8e, 0x1f, 0x00, 0x98, 0x9c, 0x22, 0x90,
+	0x18, 0x03, 0x04},
+	/* phy ctrl */
+	{0x7f, 0x00, 0x00, 0x00},
+	/* strength */
+	{0xbb, 0x02, 0x06, 0x00},
+	/* pll control */
+	{0x00, 0xec, 0x31, 0xd2, 0x00, 0x40, 0x37, 0x62,
+	0x01, 0x0f, 0x07,
+	0x05, 0x14, 0x03, 0x0, 0x0, 0x0, 0x20, 0x0, 0x02, 0x0},
+#else
+	/* DSI_BIT_CLK at 400MHz, 1 lane, RGB888 */
+	/* regulator */
+	{0x03, 0x01, 0x01, 0x00},
+	/* timing   */
+	{0xaa, 0x3b, 0x1b, 0x00, 0x52, 0x58, 0x20, 0x3f,
+	0x2e, 0x03, 0x04},
+	/* phy ctrl */
+	{0x7f, 0x00, 0x00, 0x00},
+	/* strength */
+	{0xee, 0x00, 0x86, 0x00},
+	/* pll control */
+	{0x40, 0xc7, 0xb0, 0xda, 0x00, 0x50, 0x48, 0x63,
+#if defined(RENESAS_FWVGA_TWO_LANE)
+	0x30, 0x07, 0x03,
+#else
+	/* default set to 1 lane */
+	0x30, 0x07, 0x07,
+#endif
+	0x05, 0x14, 0x03, 0x0, 0x0, 0x54, 0x06, 0x10, 0x04, 0x0},
+#endif
+};
+
+static int __init mipi_video_renesas_fwvga_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_renesas_fwvga"))
+		return 0;
+
+	pinfo.xres = 480;
+	pinfo.yres = 864;
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+#ifdef CONFIG_FB_MSM_MDP303
+	pinfo.lcdc.h_back_porch = 100;
+	pinfo.lcdc.h_front_porch = 100;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 20;
+	pinfo.lcdc.v_front_porch = 20;
+	pinfo.lcdc.v_pulse_width = 1;
+	pinfo.clk_rate = 499000000;
+#else
+
+#if defined(RENESAS_FWVGA_TWO_LANE)
+	pinfo.lcdc.h_back_porch = 400;
+#else
+	pinfo.lcdc.h_back_porch = 50;
+#endif
+	pinfo.lcdc.h_front_porch = 50;
+
+#if defined(RENESAS_FWVGA_TWO_LANE)
+	pinfo.lcdc.h_pulse_width = 5;
+#else
+	pinfo.lcdc.h_pulse_width = 20;
+#endif
+
+#if defined(RENESAS_FWVGA_TWO_LANE)
+	pinfo.lcdc.v_back_porch = 75;
+	pinfo.lcdc.v_front_porch = 5;
+	pinfo.lcdc.v_pulse_width = 1;
+#else
+	pinfo.lcdc.v_back_porch = 10;
+	pinfo.lcdc.v_front_porch = 10;
+	pinfo.lcdc.v_pulse_width = 5;
+#endif
+
+#endif
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 100;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	pinfo.mipi.pulse_mode_hsa_he = TRUE;
+	pinfo.mipi.hfp_power_stop = TRUE;
+	pinfo.mipi.hbp_power_stop = TRUE;
+	pinfo.mipi.hsa_power_stop = TRUE;
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	pinfo.mipi.bllp_power_stop = TRUE;
+#ifdef CONFIG_FB_MSM_MDP303
+	pinfo.mipi.traffic_mode = DSI_BURST_MODE;
+	pinfo.mipi.dst_format =  DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.t_clk_post = 0x20;
+	pinfo.mipi.t_clk_pre = 0x2F;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60;
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+	pinfo.mipi.dlane_swap = 0x01;
+	pinfo.mipi.tx_eot_append = 0x01;
+#else
+	pinfo.mipi.traffic_mode = DSI_NON_BURST_SYNCH_PULSE;
+	pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_BGR;
+	pinfo.mipi.data_lane0 = TRUE;
+#if defined(RENESAS_FWVGA_TWO_LANE)
+	pinfo.mipi.data_lane1 = TRUE;
+#else
+	pinfo.mipi.data_lane1 = FALSE;
+#endif
+	pinfo.mipi.t_clk_post = 0x03;
+	pinfo.mipi.t_clk_pre = 0x24;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60;
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+#endif
+
+	ret = mipi_renesas_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_FWVGA_PT);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_renesas_fwvga_pt_init);
diff --git a/drivers/video/msm/mipi_simulator.c b/drivers/video/msm/mipi_simulator.c
new file mode 100644
index 0000000..c751472
--- /dev/null
+++ b/drivers/video/msm/mipi_simulator.c
@@ -0,0 +1,167 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_simulator.h"
+
+static struct dsi_buf simulator_tx_buf;
+static struct dsi_buf simulator_rx_buf;
+static struct msm_panel_common_pdata *mipi_simulator_pdata;
+
+static int mipi_simulator_lcd_init(void);
+
+static char display_on[2]  = {0x00, 0x00};
+static char display_off[2] = {0x00, 0x00};
+
+static struct dsi_cmd_desc display_on_cmds[] = {
+		{DTYPE_PERIPHERAL_ON, 1, 0, 0, 0, sizeof(display_on),
+				display_on}
+};
+static struct dsi_cmd_desc display_off_cmds[] = {
+		{DTYPE_PERIPHERAL_OFF, 1, 0, 0, 0, sizeof(display_off),
+				display_off}
+};
+
+static int mipi_simulator_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+
+	mfd = platform_get_drvdata(pdev);
+	mipi  = &mfd->panel_info.mipi;
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	pr_debug("%s:%d, debug info (mode) : %d", __func__, __LINE__,
+		 mipi->mode);
+
+	if (mipi->mode == DSI_VIDEO_MODE) {
+		mipi_dsi_cmds_tx(&simulator_tx_buf, display_on_cmds,
+			ARRAY_SIZE(display_on_cmds));
+	} else {
+		pr_err("%s:%d, CMD MODE NOT SUPPORTED", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mipi_simulator_lcd_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+
+	mfd = platform_get_drvdata(pdev);
+	mipi  = &mfd->panel_info.mipi;
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	pr_debug("%s:%d, debug info", __func__, __LINE__);
+
+	if (mipi->mode == DSI_VIDEO_MODE) {
+		mipi_dsi_cmds_tx(&simulator_tx_buf, display_off_cmds,
+			ARRAY_SIZE(display_off_cmds));
+	} else {
+		pr_debug("%s:%d, DONT REACH HERE", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int __devinit mipi_simulator_lcd_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		mipi_simulator_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+	pr_debug("%s:%d, debug info", __func__, __LINE__);
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mipi_simulator_lcd_probe,
+	.driver = {
+		.name   = "mipi_simulator",
+	},
+};
+
+static struct msm_fb_panel_data simulator_panel_data = {
+	.on		= mipi_simulator_lcd_on,
+	.off		= mipi_simulator_lcd_off,
+};
+
+static int ch_used[3];
+
+int mipi_simulator_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	pr_debug("%s:%d, debug info", __func__, __LINE__);
+	ret = mipi_simulator_lcd_init();
+	if (ret) {
+		pr_err("mipi_simulator_lcd_init() failed with ret %u\n", ret);
+		return ret;
+	}
+
+	pdev = platform_device_alloc("mipi_simulator", (panel << 8)|channel);
+	if (!pdev)
+		return -ENOMEM;
+
+	simulator_panel_data.panel_info = *pinfo;
+
+	ret = platform_device_add_data(pdev, &simulator_panel_data,
+		sizeof(simulator_panel_data));
+	if (ret) {
+		pr_err(KERN_ERR
+		  "%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		pr_err(KERN_ERR
+		  "%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int mipi_simulator_lcd_init(void)
+{
+	mipi_dsi_buf_alloc(&simulator_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&simulator_rx_buf, DSI_BUF_SIZE);
+
+	return platform_driver_register(&this_driver);
+}
diff --git a/drivers/video/msm/mipi_simulator.h b/drivers/video/msm/mipi_simulator.h
new file mode 100644
index 0000000..274ce8f
--- /dev/null
+++ b/drivers/video/msm/mipi_simulator.h
@@ -0,0 +1,19 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MIPI_SIMULATOR_H
+#define MIPI_SIMULATOR_H
+
+int mipi_simulator_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#endif  /* MIPI_SIMULATOR_H */
diff --git a/drivers/video/msm/mipi_simulator_video.c b/drivers/video/msm/mipi_simulator_video.c
new file mode 100644
index 0000000..845df75
--- /dev/null
+++ b/drivers/video/msm/mipi_simulator_video.c
@@ -0,0 +1,86 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_simulator.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	{0x03, 0x01, 0x01, 0x00},
+	{0xaa, 0x3b, 0x1b, 0x00, 0x52, 0x58, 0x20, 0x3f,
+		0x2e, 0x03, 0x04},
+	{0x7f, 0x00, 0x00, 0x00},
+	{0xee, 0x00, 0x86, 0x00},
+	{0x40, 0xc7, 0xb0, 0xda, 0x00, 0x50, 0x48, 0x63,
+		0x30, 0x07, 0x03,
+		0x05, 0x14, 0x03, 0x0, 0x0, 0x54, 0x06, 0x10, 0x04, 0x0},
+};
+
+static int __init mipi_video_simulator_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_simulator_vga"))
+		return 0;
+	pinfo.xres = 640;
+	pinfo.yres = 480;
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+
+	pinfo.lcdc.h_back_porch  = 6;
+	pinfo.lcdc.h_front_porch = 6;
+	pinfo.lcdc.h_pulse_width = 2;
+	pinfo.lcdc.v_back_porch  = 6;
+	pinfo.lcdc.v_front_porch = 6;
+	pinfo.lcdc.v_pulse_width = 2;
+
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 15;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	pinfo.mipi.pulse_mode_hsa_he = TRUE;
+	pinfo.mipi.hfp_power_stop = TRUE;
+	pinfo.mipi.hbp_power_stop = TRUE;
+	pinfo.mipi.hsa_power_stop = TRUE;
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	pinfo.mipi.bllp_power_stop = TRUE;
+	pinfo.mipi.traffic_mode = DSI_NON_BURST_SYNCH_PULSE;
+	pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.t_clk_post = 0x03;
+	pinfo.mipi.t_clk_pre = 0x24;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60;
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+	ret = mipi_simulator_device_register(&pinfo, MIPI_DSI_PRIM,
+		MIPI_DSI_PANEL_VGA);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+		return ret;
+}
+
+module_init(mipi_video_simulator_init);
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.c b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
new file mode 100644
index 0000000..aa0e29c
--- /dev/null
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
@@ -0,0 +1,1006 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Toshiba MIPI-DSI-to-LVDS Bridge driver.
+ * Device Model TC358764XBG/65XBG.
+ * Reference document: TC358764XBG_65XBG_V119.pdf
+ *
+ * The Host sends a DSI Generic Long Write packet (Data ID = 0x29) over the
+ * DSI link for each write access transaction to the chip configuration
+ * registers.
+ * Payload of this packet is 16-bit register address and 32-bit data.
+ * Multiple data values are allowed for sequential addresses.
+ *
+ * The Host sends a DSI Generic Read packet (Data ID = 0x24) over the DSI
+ * link for each read request transaction to the chip configuration
+ * registers. Payload of this packet is further defined as follows:
+ * 16-bit address followed by a 32-bit value (Generic Long Read Response
+ * packet).
+ *
+ * The bridge supports 5 GPIO lines controlled via the GPC register.
+ *
+ * The bridge support I2C Master/Slave.
+ * The I2C slave can be used for read/write to the bridge register instead of
+ * using the DSI interface.
+ * I2C slave address is 0x0F (read/write 0x1F/0x1E).
+ * The I2C Master can be used for communication with the panel if
+ * it has an I2C slave.
+ *
+ * NOTE: The I2C interface is not used in this driver.
+ * Only the DSI interface is used for read/write the bridge registers.
+ *
+ * Pixel data can be transmitted in non-burst or burst fashion.
+ * Non-burst refers to pixel data packet transmission time on DSI link
+ * being roughly the same (to account for packet overhead time)
+ * as active video line time on LVDS output (i.e. DE = 1).
+ * And burst refers to pixel data packet transmission time on DSI link
+ * being less than the active video line time on LVDS output.
+ * Video mode transmission is further differentiated by the types of
+ * timing events being transmitted.
+ * Video pulse mode refers to the case where both sync start and sync end
+ * events (for frame and line) are transmitted.
+ * Video event mode refers to the case where only sync start events
+ * are transmitted.
+ * This is configured via register bit VPCTRL.EVTMODE.
+ *
+ */
+
+/* #define DEBUG 1 */
+
+/**
+ * Use the I2C master to control the panel.
+ */
+/* #define TC358764_USE_I2C_MASTER */
+
+#define DRV_NAME "mipi_tc358764"
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#include <linux/gpio.h>
+#include "msm_fb.h"
+#include "mdp4.h"
+#include "mipi_dsi.h"
+#include "mipi_tc358764_dsi2lvds.h"
+
+/* Registers definition */
+
+/* DSI D-PHY Layer Registers */
+#define D0W_DPHYCONTTX	0x0004	/* Data Lane 0 DPHY Tx Control */
+#define CLW_DPHYCONTRX	0x0020	/* Clock Lane DPHY Rx Control */
+#define D0W_DPHYCONTRX	0x0024	/* Data Lane 0 DPHY Rx Control */
+#define D1W_DPHYCONTRX	0x0028	/* Data Lane 1 DPHY Rx Control */
+#define D2W_DPHYCONTRX	0x002C	/* Data Lane 2 DPHY Rx Control */
+#define D3W_DPHYCONTRX	0x0030	/* Data Lane 3 DPHY Rx Control */
+#define COM_DPHYCONTRX	0x0038	/* DPHY Rx Common Control */
+#define CLW_CNTRL	0x0040	/* Clock Lane Control */
+#define D0W_CNTRL	0x0044	/* Data Lane 0 Control */
+#define D1W_CNTRL	0x0048	/* Data Lane 1 Control */
+#define D2W_CNTRL	0x004C	/* Data Lane 2 Control */
+#define D3W_CNTRL	0x0050	/* Data Lane 3 Control */
+#define DFTMODE_CNTRL	0x0054	/* DFT Mode Control */
+
+/* DSI PPI Layer Registers */
+#define PPI_STARTPPI	0x0104	/* START control bit of PPI-TX function. */
+#define PPI_BUSYPPI	0x0108
+#define PPI_LINEINITCNT	0x0110	/* Line Initialization Wait Counter  */
+#define PPI_LPTXTIMECNT	0x0114
+#define PPI_LANEENABLE	0x0134	/* Enables each lane at the PPI layer. */
+#define PPI_TX_RX_TA	0x013C	/* DSI Bus Turn Around timing parameters */
+
+/* Analog timer function enable */
+#define PPI_CLS_ATMR	0x0140	/* Delay for Clock Lane in LPRX  */
+#define PPI_D0S_ATMR	0x0144	/* Delay for Data Lane 0 in LPRX */
+#define PPI_D1S_ATMR	0x0148	/* Delay for Data Lane 1 in LPRX */
+#define PPI_D2S_ATMR	0x014C	/* Delay for Data Lane 2 in LPRX */
+#define PPI_D3S_ATMR	0x0150	/* Delay for Data Lane 3 in LPRX */
+#define PPI_D0S_CLRSIPOCOUNT	0x0164
+
+#define PPI_D1S_CLRSIPOCOUNT	0x0168	/* For lane 1 */
+#define PPI_D2S_CLRSIPOCOUNT	0x016C	/* For lane 2 */
+#define PPI_D3S_CLRSIPOCOUNT	0x0170	/* For lane 3 */
+
+#define CLS_PRE		0x0180	/* Digital Counter inside of PHY IO */
+#define D0S_PRE		0x0184	/* Digital Counter inside of PHY IO */
+#define D1S_PRE		0x0188	/* Digital Counter inside of PHY IO */
+#define D2S_PRE		0x018C	/* Digital Counter inside of PHY IO */
+#define D3S_PRE		0x0190	/* Digital Counter inside of PHY IO */
+#define CLS_PREP	0x01A0	/* Digital Counter inside of PHY IO */
+#define D0S_PREP	0x01A4	/* Digital Counter inside of PHY IO */
+#define D1S_PREP	0x01A8	/* Digital Counter inside of PHY IO */
+#define D2S_PREP	0x01AC	/* Digital Counter inside of PHY IO */
+#define D3S_PREP	0x01B0	/* Digital Counter inside of PHY IO */
+#define CLS_ZERO	0x01C0	/* Digital Counter inside of PHY IO */
+#define D0S_ZERO	0x01C4	/* Digital Counter inside of PHY IO */
+#define D1S_ZERO	0x01C8	/* Digital Counter inside of PHY IO */
+#define D2S_ZERO	0x01CC	/* Digital Counter inside of PHY IO */
+#define D3S_ZERO	0x01D0	/* Digital Counter inside of PHY IO */
+
+#define PPI_CLRFLG	0x01E0	/* PRE Counters has reached set values */
+#define PPI_CLRSIPO	0x01E4	/* Clear SIPO values, Slave mode use only. */
+#define HSTIMEOUT	0x01F0	/* HS Rx Time Out Counter */
+#define HSTIMEOUTENABLE	0x01F4	/* Enable HS Rx Time Out Counter */
+#define DSI_STARTDSI	0x0204	/* START control bit of DSI-TX function */
+#define DSI_BUSYDSI	0x0208
+#define DSI_LANEENABLE	0x0210	/* Enables each lane at the Protocol layer. */
+#define DSI_LANESTATUS0	0x0214	/* Displays lane is in HS RX mode. */
+#define DSI_LANESTATUS1	0x0218	/* Displays lane is in ULPS or STOP state */
+
+#define DSI_INTSTATUS	0x0220	/* Interrupt Status */
+#define DSI_INTMASK	0x0224	/* Interrupt Mask */
+#define DSI_INTCLR	0x0228	/* Interrupt Clear */
+#define DSI_LPTXTO	0x0230	/* Low Power Tx Time Out Counter */
+
+#define DSIERRCNT	0x0300	/* DSI Error Count */
+#define APLCTRL		0x0400	/* Application Layer Control */
+#define RDPKTLN		0x0404	/* Command Read Packet Length */
+#define VPCTRL		0x0450	/* Video Path Control */
+#define HTIM1		0x0454	/* Horizontal Timing Control 1 */
+#define HTIM2		0x0458	/* Horizontal Timing Control 2 */
+#define VTIM1		0x045C	/* Vertical Timing Control 1 */
+#define VTIM2		0x0460	/* Vertical Timing Control 2 */
+#define VFUEN		0x0464	/* Video Frame Timing Update Enable */
+
+/* Mux Input Select for LVDS LINK Input */
+#define LVMX0003	0x0480	/* Bit 0 to 3 */
+#define LVMX0407	0x0484	/* Bit 4 to 7 */
+#define LVMX0811	0x0488	/* Bit 8 to 11 */
+#define LVMX1215	0x048C	/* Bit 12 to 15 */
+#define LVMX1619	0x0490	/* Bit 16 to 19 */
+#define LVMX2023	0x0494	/* Bit 20 to 23 */
+#define LVMX2427	0x0498	/* Bit 24 to 27 */
+
+#define LVCFG		0x049C	/* LVDS Configuration  */
+#define LVPHY0		0x04A0	/* LVDS PHY 0 */
+#define LVPHY1		0x04A4	/* LVDS PHY 1 */
+#define SYSSTAT		0x0500	/* System Status  */
+#define SYSRST		0x0504	/* System Reset  */
+
+/* GPIO Registers */
+#define GPIOC		0x0520	/* GPIO Control  */
+#define GPIOO		0x0524	/* GPIO Output  */
+#define GPIOI		0x0528	/* GPIO Input  */
+
+/* I2C Registers */
+#define I2CTIMCTRL	0x0540	/* I2C IF Timing and Enable Control */
+#define I2CMADDR	0x0544	/* I2C Master Addressing */
+#define WDATAQ		0x0548	/* Write Data Queue */
+#define RDATAQ		0x054C	/* Read Data Queue */
+
+/* Chip ID and Revision ID Register */
+#define IDREG		0x0580
+
+#define TC358764XBG_ID	0x00006500
+
+/* Debug Registers */
+#define DEBUG00		0x05A0	/* Debug */
+#define DEBUG01		0x05A4	/* LVDS Data */
+
+/* PWM */
+static u32 d2l_pwm_freq_hz = (66*1000);
+
+/* 1366x768 uses pwm at 66 KHZ */
+/* 1200x1920 uses pwm at 25 KHZ */
+#define PWM_FREQ_HZ	(d2l_pwm_freq_hz)
+#define PWM_LEVEL 15
+#define PWM_PERIOD_USEC (USEC_PER_SEC / PWM_FREQ_HZ)
+#define PWM_DUTY_LEVEL (PWM_PERIOD_USEC / PWM_LEVEL)
+
+#define CMD_DELAY 100
+#define DSI_MAX_LANES 4
+#define KHZ 1000
+#define MHZ (1000*1000)
+
+/**
+ * Command payload for DTYPE_GEN_LWRITE (0x29) / DTYPE_GEN_READ2 (0x24).
+ */
+struct wr_cmd_payload {
+	u16 addr;
+	u32 data;
+} __packed;
+
+/*
+ * Driver state.
+ */
+static struct msm_panel_common_pdata *d2l_common_pdata;
+struct msm_fb_data_type *d2l_mfd;
+static struct dsi_buf d2l_tx_buf;
+static struct dsi_buf d2l_rx_buf;
+static int led_pwm;
+static struct pwm_device *bl_pwm;
+static struct pwm_device *tn_pwm;
+static int bl_level;
+static u32 d2l_gpio_out_mask;
+static u32 d2l_gpio_out_val;
+static u32 d2l_3d_gpio_enable;
+static u32 d2l_3d_gpio_mode;
+static int d2l_enable_3d;
+static struct i2c_client *d2l_i2c_client;
+static struct i2c_driver d2l_i2c_slave_driver;
+
+static int mipi_d2l_init(void);
+static int mipi_d2l_enable_3d(struct msm_fb_data_type *mfd,
+			      bool enable, bool mode);
+static u32 d2l_i2c_read_reg(struct i2c_client *client, u16 reg);
+static u32 d2l_i2c_write_reg(struct i2c_client *client, u16 reg, u32 val);
+
+/**
+ * Read a bridge register
+ *
+ * @param mfd
+ *
+ * @return register data value
+ */
+static u32 mipi_d2l_read_reg(struct msm_fb_data_type *mfd, u16 reg)
+{
+	u32 data;
+	int len = 4;
+	struct dsi_cmd_desc cmd_read_reg = {
+		DTYPE_GEN_READ2, 1, 0, 1, 0, /* cmd 0x24 */
+			sizeof(reg), (char *) &reg};
+
+	mipi_dsi_buf_init(&d2l_tx_buf);
+	mipi_dsi_buf_init(&d2l_rx_buf);
+
+	/* mutex had been acquired at mipi_dsi_on */
+	len = mipi_dsi_cmds_rx(mfd, &d2l_tx_buf, &d2l_rx_buf,
+			       &cmd_read_reg, len);
+
+	data = *(u32 *)d2l_rx_buf.data;
+
+	if (len != 4)
+		pr_err("%s: invalid rlen=%d, expecting 4.\n", __func__, len);
+
+	pr_debug("%s: reg=0x%x.data=0x%08x.\n", __func__, reg, data);
+
+	return data;
+}
+
+/**
+ * Write a bridge register
+ *
+ * @param mfd
+ *
+ * @return int
+ */
+static int mipi_d2l_write_reg(struct msm_fb_data_type *mfd, u16 reg, u32 data)
+{
+	struct wr_cmd_payload payload;
+	struct dsi_cmd_desc cmd_write_reg = {
+		DTYPE_GEN_LWRITE, 1, 0, 0, 0,
+			sizeof(payload), (char *)&payload};
+
+	payload.addr = reg;
+	payload.data = data;
+
+	/* mutex had been acquried at dsi_on */
+	mipi_dsi_cmds_tx(&d2l_tx_buf, &cmd_write_reg, 1);
+
+	pr_debug("%s: reg=0x%x. data=0x%x.\n", __func__, reg, data);
+
+	return 0;
+}
+
+static void mipi_d2l_read_status(struct msm_fb_data_type *mfd)
+{
+	mipi_d2l_read_reg(mfd, DSI_LANESTATUS0);	/* 0x214 */
+	mipi_d2l_read_reg(mfd, DSI_LANESTATUS1);	/* 0x218 */
+	mipi_d2l_read_reg(mfd, DSI_INTSTATUS);		/* 0x220 */
+	mipi_d2l_read_reg(mfd, SYSSTAT);		/* 0x500 */
+}
+
+static void mipi_d2l_read_status_via_i2c(struct i2c_client *client)
+{
+	u32 tmp = 0;
+
+	tmp = d2l_i2c_read_reg(client, DSIERRCNT);
+	d2l_i2c_write_reg(client, DSIERRCNT, 0xFFFF0000);
+
+	d2l_i2c_read_reg(client, DSI_LANESTATUS0);	/* 0x214 */
+	d2l_i2c_read_reg(client, DSI_LANESTATUS1);	/* 0x218 */
+	d2l_i2c_read_reg(client, DSI_INTSTATUS);	/* 0x220 */
+	d2l_i2c_read_reg(client, SYSSTAT);		/* 0x500 */
+
+	d2l_i2c_write_reg(client, DSIERRCNT, tmp);
+}
+/**
+ * Init the D2L bridge via the DSI interface for Video.
+ *
+ * VPCTRL.EVTMODE (0x20) configuration bit is needed to determine whether
+ * video timing information is delivered in pulse mode or event mode.
+ * In pulse mode, both Sync Start and End packets are required.
+ * In event mode, only Sync Start packets are required.
+ *
+ * @param mfd
+ *
+ * @return int
+ */
+static int mipi_d2l_dsi_init_sequence(struct msm_fb_data_type *mfd)
+{
+	struct mipi_panel_info *mipi = &mfd->panel_info.mipi;
+	u32 lanes_enable;
+	u32 vpctrl;
+	u32 htime1;
+	u32 vtime1;
+	u32 htime2;
+	u32 vtime2;
+	u32 ppi_tx_rx_ta; /* BTA Bus-Turn-Around */
+	u32 lvcfg;
+	u32 hbpr;	/* Horizontal Back Porch */
+	u32 hpw;	/* Horizontal Pulse Width */
+	u32 vbpr;	/* Vertical Back Porch */
+	u32 vpw;	/* Vertical Pulse Width */
+
+	u32 hfpr;	/* Horizontal Front Porch */
+	u32 hsize;	/* Horizontal Active size */
+	u32 vfpr;	/* Vertical Front Porch */
+	u32 vsize;	/* Vertical Active size */
+	bool vesa_rgb888 = false;
+
+	lanes_enable = 0x01; /* clock-lane enable */
+	lanes_enable |= (mipi->data_lane0 << 1);
+	lanes_enable |= (mipi->data_lane1 << 2);
+	lanes_enable |= (mipi->data_lane2 << 3);
+	lanes_enable |= (mipi->data_lane3 << 4);
+
+	if (mipi->traffic_mode == DSI_NON_BURST_SYNCH_EVENT)
+		vpctrl = 0x01000120;
+	else if (mipi->traffic_mode == DSI_NON_BURST_SYNCH_PULSE)
+		vpctrl = 0x01000100;
+	else {
+		pr_err("%s.unsupported traffic_mode %d.\n",
+		       __func__, mipi->traffic_mode);
+		return -EINVAL;
+	}
+
+	if (mfd->panel_info.clk_rate > 800*1000*1000) {
+		pr_err("%s.unsupported clk_rate %d.\n",
+		       __func__, mfd->panel_info.clk_rate);
+		return -EINVAL;
+	}
+
+	pr_debug("%s.xres=%d.yres=%d.fps=%d.dst_format=%d.\n",
+		__func__,
+		 mfd->panel_info.xres,
+		 mfd->panel_info.yres,
+		 mfd->panel_info.mipi.frame_rate,
+		 mfd->panel_info.mipi.dst_format);
+
+	hbpr = mfd->panel_info.lcdc.h_back_porch;
+	hpw	= mfd->panel_info.lcdc.h_pulse_width;
+	vbpr = mfd->panel_info.lcdc.v_back_porch;
+	vpw	= mfd->panel_info.lcdc.v_pulse_width;
+
+	htime1 = (hbpr << 16) + hpw;
+	vtime1 = (vbpr << 16) + vpw;
+
+	hfpr = mfd->panel_info.lcdc.h_front_porch;
+	hsize = mfd->panel_info.xres;
+	vfpr = mfd->panel_info.lcdc.v_front_porch;
+	vsize = mfd->panel_info.yres;
+
+	htime2 = (hfpr << 16) + hsize;
+	vtime2 = (vfpr << 16) + vsize;
+
+	lvcfg = 0x0003; /* PCLK=DCLK/3, Dual Link, LVEN */
+	vpctrl = 0x01000120; /* Output RGB888 , Event-Mode , */
+	ppi_tx_rx_ta = 0x00040004;
+
+	if (mfd->panel_info.xres == 1366) {
+		ppi_tx_rx_ta = 0x00040004;
+		lvcfg = 0x01; /* LVEN */
+		vesa_rgb888 = true;
+	}
+
+	if (mfd->panel_info.xres == 1200) {
+		lvcfg = 0x0103; /* PCLK=DCLK/4, Dual Link, LVEN */
+		vesa_rgb888 = true;
+	}
+
+	pr_debug("%s.htime1=0x%x.\n", __func__, htime1);
+	pr_debug("%s.vtime1=0x%x.\n", __func__, vtime1);
+	pr_debug("%s.vpctrl=0x%x.\n", __func__, vpctrl);
+	pr_debug("%s.lvcfg=0x%x.\n", __func__, lvcfg);
+
+	mipi_d2l_write_reg(mfd, SYSRST, 0xFF);
+	msleep(30);
+
+	if (vesa_rgb888) {
+		/* VESA format instead of JEIDA format for RGB888 */
+		mipi_d2l_write_reg(mfd, LVMX0003, 0x03020100);
+		mipi_d2l_write_reg(mfd, LVMX0407, 0x08050704);
+		mipi_d2l_write_reg(mfd, LVMX0811, 0x0F0E0A09);
+		mipi_d2l_write_reg(mfd, LVMX1215, 0x100D0C0B);
+		mipi_d2l_write_reg(mfd, LVMX1619, 0x12111716);
+		mipi_d2l_write_reg(mfd, LVMX2023, 0x1B151413);
+		mipi_d2l_write_reg(mfd, LVMX2427, 0x061A1918);
+	}
+
+	mipi_d2l_write_reg(mfd, PPI_TX_RX_TA, ppi_tx_rx_ta); /* BTA */
+	mipi_d2l_write_reg(mfd, PPI_LPTXTIMECNT, 0x00000004);
+	mipi_d2l_write_reg(mfd, PPI_D0S_CLRSIPOCOUNT, 0x00000003);
+	mipi_d2l_write_reg(mfd, PPI_D1S_CLRSIPOCOUNT, 0x00000003);
+	mipi_d2l_write_reg(mfd, PPI_D2S_CLRSIPOCOUNT, 0x00000003);
+	mipi_d2l_write_reg(mfd, PPI_D3S_CLRSIPOCOUNT, 0x00000003);
+	mipi_d2l_write_reg(mfd, PPI_LANEENABLE, lanes_enable);
+	mipi_d2l_write_reg(mfd, DSI_LANEENABLE, lanes_enable);
+	mipi_d2l_write_reg(mfd, PPI_STARTPPI, 0x00000001);
+	mipi_d2l_write_reg(mfd, DSI_STARTDSI, 0x00000001);
+
+	mipi_d2l_write_reg(mfd, VPCTRL, vpctrl); /* RGB888 + Event mode */
+	mipi_d2l_write_reg(mfd, HTIM1, htime1);
+	mipi_d2l_write_reg(mfd, VTIM1, vtime1);
+	mipi_d2l_write_reg(mfd, HTIM2, htime2);
+	mipi_d2l_write_reg(mfd, VTIM2, vtime2);
+	mipi_d2l_write_reg(mfd, VFUEN, 0x00000001);
+	mipi_d2l_write_reg(mfd, LVCFG, lvcfg); /* Enables LVDS tx */
+
+	return 0;
+}
+
+/**
+ * Set Backlight level.
+ *
+ * @param pwm
+ * @param level
+ *
+ * @return int
+ */
+static int mipi_d2l_set_backlight_level(struct pwm_device *pwm, int level)
+{
+	int ret = 0;
+
+	pr_debug("%s: level=%d.\n", __func__, level);
+
+	if ((pwm == NULL) || (level > PWM_LEVEL) || (level < 0)) {
+		pr_err("%s.pwm=NULL.\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = pwm_config(pwm, PWM_DUTY_LEVEL * level, PWM_PERIOD_USEC);
+	if (ret) {
+		pr_err("%s: pwm_config() failed err=%d.\n", __func__, ret);
+		return ret;
+	}
+
+	ret = pwm_enable(pwm);
+	if (ret) {
+		pr_err("%s: pwm_enable() failed err=%d\n",
+		       __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * Set TN CLK.
+ *
+ * @param pwm
+ * @param level
+ *
+ * @return int
+ */
+static int mipi_d2l_set_tn_clk(struct pwm_device *pwm, u32 usec)
+{
+	int ret = 0;
+
+	pr_debug("%s: usec=%d.\n", __func__, usec);
+
+	ret = pwm_config(pwm, usec/2 , usec);
+	if (ret) {
+		pr_err("%s: pwm_config() failed err=%d.\n", __func__, ret);
+		return ret;
+	}
+
+	ret = pwm_enable(pwm);
+	if (ret) {
+		pr_err("%s: pwm_enable() failed err=%d\n",
+		       __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * LCD ON.
+ *
+ * Set LCD On via MIPI interface or I2C-Slave interface.
+ * Set Backlight on.
+ *
+ * @param pdev
+ *
+ * @return int
+ */
+static int mipi_d2l_lcd_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	u32 chip_id;
+	struct msm_fb_data_type *mfd;
+
+	pr_info("%s.\n", __func__);
+
+	/* wait for valid clock before sending data over DSI or I2C. */
+	msleep(30);
+
+	mfd = platform_get_drvdata(pdev);
+	d2l_mfd = mfd;
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	chip_id = mipi_d2l_read_reg(mfd, IDREG);
+
+
+	if (chip_id != TC358764XBG_ID) {
+		pr_err("%s: invalid chip_id=0x%x", __func__, chip_id);
+		return -ENODEV;
+	}
+
+	ret = mipi_d2l_dsi_init_sequence(mfd);
+	if (ret)
+		return ret;
+
+	mipi_d2l_write_reg(mfd, GPIOC, d2l_gpio_out_mask);
+	/* Set gpio#4=U/D=0, gpio#3=L/R=1 , gpio#2,1=CABC=0, gpio#0=NA. */
+	mipi_d2l_write_reg(mfd, GPIOO, d2l_gpio_out_val);
+
+	if (mfd->panel_info.xres == 1366)
+		d2l_pwm_freq_hz = (66*1000);
+	else
+		d2l_pwm_freq_hz = (25*1000);
+
+	if (bl_level == 0)
+		bl_level = PWM_LEVEL * 2 / 3 ; /* Default ON value */
+
+	/* Set backlight via PWM */
+	if (bl_pwm) {
+		ret = mipi_d2l_set_backlight_level(bl_pwm, bl_level);
+		if (ret)
+			pr_err("%s.mipi_d2l_set_backlight_level.ret=%d",
+			       __func__, ret);
+	}
+
+	mipi_d2l_read_status(mfd);
+
+	mipi_d2l_enable_3d(mfd, false, false);
+
+	/* Add I2C driver only after DSI-CLK is running */
+	if (d2l_i2c_client == NULL)
+		i2c_add_driver(&d2l_i2c_slave_driver);
+
+	pr_info("%s.ret=%d.\n", __func__, ret);
+
+	return ret;
+}
+
+/**
+ * LCD OFF.
+ *
+ * @param pdev
+ *
+ * @return int
+ */
+static int mipi_d2l_lcd_off(struct platform_device *pdev)
+{
+	int ret;
+	struct msm_fb_data_type *mfd;
+
+	pr_info("%s.\n", __func__);
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	ret = mipi_d2l_set_backlight_level(bl_pwm, 1);
+
+	pr_info("%s.ret=%d.\n", __func__, ret);
+
+	return ret;
+}
+
+static void mipi_d2l_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int level = mfd->bl_level;
+
+	pr_debug("%s.lvl=%d.\n", __func__, level);
+
+	mipi_d2l_set_backlight_level(bl_pwm, level);
+
+	bl_level = level;
+}
+
+static struct msm_fb_panel_data d2l_panel_data = {
+	.on = mipi_d2l_lcd_on,
+	.off = mipi_d2l_lcd_off,
+	.set_backlight = mipi_d2l_set_backlight,
+};
+
+static u32 d2l_i2c_read_reg(struct i2c_client *client, u16 reg)
+{
+	int rc;
+	u32 val = 0;
+	u8 buf[6];
+
+	if (client == NULL) {
+		pr_err("%s.invalid i2c client.\n", __func__);
+		return -EINVAL;
+	}
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xFF;
+
+	rc = i2c_master_send(client, buf, sizeof(reg));
+	rc = i2c_master_recv(client, buf, 4);
+
+	if (rc >= 0) {
+		val = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
+		pr_debug("%s.reg=0x%x.val=0x%x.\n", __func__, reg, val);
+	} else
+		pr_err("%s.fail.reg=0x%x.\n", __func__, reg);
+
+	return val;
+}
+
+static u32 d2l_i2c_write_reg(struct i2c_client *client, u16 reg, u32 val)
+{
+	int rc;
+	u8 buf[6];
+
+	if (client == NULL) {
+		pr_err("%s.invalid i2c client.\n", __func__);
+		return -EINVAL;
+	}
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xFF;
+
+	buf[2] = (val >> 0) & 0xFF;
+	buf[3] = (val >> 8) & 0xFF;
+	buf[4] = (val >> 16) & 0xFF;
+	buf[5] = (val >> 24) & 0xFF;
+
+	rc = i2c_master_send(client, buf, sizeof(buf));
+
+	if (rc >= 0)
+		pr_debug("%s.reg=0x%x.val=0x%x.\n", __func__, reg, val);
+	else
+		pr_err("%s.fail.reg=0x%x.\n", __func__, reg);
+
+	return val;
+}
+
+static int __devinit d2l_i2c_slave_probe(struct i2c_client *client,
+					 const struct i2c_device_id *id)
+{
+	static const u32 i2c_funcs = I2C_FUNC_I2C;
+
+	d2l_i2c_client = client;
+
+	if (!i2c_check_functionality(client->adapter, i2c_funcs)) {
+		pr_err("%s.i2c_check_functionality failed.\n", __func__);
+		return -ENOSYS;
+	} else {
+		pr_debug("%s.i2c_check_functionality OK.\n", __func__);
+	}
+
+	d2l_i2c_read_reg(client, IDREG);
+
+	mipi_d2l_read_status_via_i2c(d2l_i2c_client);
+
+	return 0;
+}
+
+static __devexit int d2l_i2c_slave_remove(struct i2c_client *client)
+{
+	d2l_i2c_client = NULL;
+
+	return 0;
+}
+
+static const struct i2c_device_id d2l_i2c_id[] = {
+	{"tc358764-i2c", 0},
+	{}
+};
+
+static struct i2c_driver d2l_i2c_slave_driver = {
+	.driver = {
+		.name = "tc358764-i2c",
+		.owner = THIS_MODULE
+	},
+	.probe    = d2l_i2c_slave_probe,
+	.remove   = __devexit_p(d2l_i2c_slave_remove),
+	.id_table = d2l_i2c_id,
+};
+
+static int mipi_d2l_enable_3d(struct msm_fb_data_type *mfd,
+			      bool enable, bool mode)
+{
+	u32 tn_usec = 1000000 / 66; /* 66 HZ */
+
+	pr_debug("%s.enable=%d.mode=%d.\n", __func__, enable, mode);
+
+	gpio_direction_output(d2l_3d_gpio_enable, enable);
+	gpio_direction_output(d2l_3d_gpio_mode, mode);
+
+	mipi_d2l_set_tn_clk(tn_pwm, tn_usec);
+
+	return 0;
+}
+
+static ssize_t mipi_d2l_enable_3d_read(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	return snprintf((char *)buf, sizeof(buf), "%u\n", d2l_enable_3d);
+}
+
+static ssize_t mipi_d2l_enable_3d_write(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf,
+				size_t count)
+{
+	int ret = -1;
+	u32 data = 0;
+
+	if (sscanf((char *)buf, "%u", &data) != 1) {
+		dev_err(dev, "%s. Invalid input.\n", __func__);
+		ret = -EINVAL;
+	} else {
+		d2l_enable_3d = data;
+		if (data == 1) /* LANDSCAPE */
+			mipi_d2l_enable_3d(d2l_mfd, true, true);
+		else if (data == 2) /* PORTRAIT */
+			mipi_d2l_enable_3d(d2l_mfd, true, false);
+		else if (data == 0)
+			mipi_d2l_enable_3d(d2l_mfd, false, false);
+		else if (data == 9)
+			mipi_d2l_read_status_via_i2c(d2l_i2c_client);
+		else
+			pr_err("%s.Invalid value=%d.\n", __func__, data);
+	}
+
+	return count;
+}
+
+static struct device_attribute mipi_d2l_3d_barrier_attributes[] = {
+	__ATTR(enable_3d_barrier, 0666,
+	       mipi_d2l_enable_3d_read,
+	       mipi_d2l_enable_3d_write),
+};
+
+static int mipi_dsi_3d_barrier_sysfs_register(struct device *dev)
+{
+	int ret;
+
+	pr_debug("%s.d2l_3d_gpio_enable=%d.\n", __func__, d2l_3d_gpio_enable);
+	pr_debug("%s.d2l_3d_gpio_mode=%d.\n", __func__, d2l_3d_gpio_mode);
+
+	ret  = device_create_file(dev, mipi_d2l_3d_barrier_attributes);
+	if (ret) {
+		pr_err("%s.failed to create 3D sysfs.\n", __func__);
+		goto err_device_create_file;
+	}
+
+	ret = gpio_request(d2l_3d_gpio_enable, "d2l_3d_gpio_enable");
+	if (ret) {
+		pr_err("%s.failed to get d2l_3d_gpio_enable=%d.\n",
+		       __func__, d2l_3d_gpio_enable);
+		goto err_d2l_3d_gpio_enable;
+	}
+
+	ret = gpio_request(d2l_3d_gpio_mode, "d2l_3d_gpio_mode");
+	if (ret) {
+		pr_err("%s.failed to get d2l_3d_gpio_mode=%d.\n",
+		       __func__, d2l_3d_gpio_mode);
+		goto err_d2l_3d_gpio_mode;
+	}
+
+	return 0;
+
+err_d2l_3d_gpio_mode:
+	gpio_free(d2l_3d_gpio_enable);
+err_d2l_3d_gpio_enable:
+	device_remove_file(dev, mipi_d2l_3d_barrier_attributes);
+err_device_create_file:
+
+	return ret;
+}
+
+/**
+ * Probe for device.
+ *
+ * Both the "target" and "panel" device use the same probe function.
+ * "Target" device has id=0, "Panel" devic has non-zero id.
+ * Target device should register first, passing msm_panel_common_pdata.
+ * Panel device passing msm_panel_info.
+ *
+ * @param pdev
+ *
+ * @return int
+ */
+static int __devinit mipi_d2l_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_panel_info *pinfo = NULL;
+
+	pr_debug("%s.id=%d.\n", __func__, pdev->id);
+
+	if (pdev->id == 0) {
+		d2l_common_pdata = pdev->dev.platform_data;
+
+		if (d2l_common_pdata == NULL) {
+			pr_err("%s: no PWM gpio specified.\n", __func__);
+			return 0;
+		}
+
+		led_pwm = d2l_common_pdata->gpio_num[0];
+		d2l_gpio_out_mask = d2l_common_pdata->gpio_num[1] >> 8;
+		d2l_gpio_out_val = d2l_common_pdata->gpio_num[1] & 0xFF;
+		d2l_3d_gpio_enable = d2l_common_pdata->gpio_num[2];
+		d2l_3d_gpio_mode = d2l_common_pdata->gpio_num[3];
+
+		mipi_dsi_buf_alloc(&d2l_tx_buf, DSI_BUF_SIZE);
+		mipi_dsi_buf_alloc(&d2l_rx_buf, DSI_BUF_SIZE);
+
+		return 0;
+	}
+
+	if (d2l_common_pdata == NULL) {
+		pr_err("%s: d2l_common_pdata is NULL.\n", __func__);
+		return -ENODEV;
+	}
+
+	bl_pwm = NULL;
+	if (led_pwm >= 0) {
+		bl_pwm = pwm_request(led_pwm, "lcd-backlight");
+		if (bl_pwm == NULL || IS_ERR(bl_pwm)) {
+			pr_err("%s pwm_request() failed.id=%d.bl_pwm=%d.\n",
+			       __func__, led_pwm, (int) bl_pwm);
+			bl_pwm = NULL;
+			return -EIO;
+		} else {
+			pr_debug("%s.pwm_request() ok.pwm-id=%d.\n",
+			       __func__, led_pwm);
+
+		}
+	} else {
+		pr_err("%s. led_pwm is invalid.\n", __func__);
+	}
+
+	tn_pwm = pwm_request(1, "3D_TN_clk");
+	if (tn_pwm == NULL || IS_ERR(tn_pwm)) {
+		pr_err("%s pwm_request() failed.id=%d.tn_pwm=%d.\n",
+		       __func__, 1, (int) tn_pwm);
+		tn_pwm = NULL;
+		return -EIO;
+	} else {
+		pr_debug("%s.pwm_request() ok.pwm-id=%d.\n", __func__, 1);
+
+	}
+
+	pinfo = pdev->dev.platform_data;
+
+	if (pinfo == NULL) {
+		pr_err("%s: pinfo is NULL.\n", __func__);
+		return -ENODEV;
+	}
+
+	d2l_panel_data.panel_info = *pinfo;
+
+	pdev->dev.platform_data = &d2l_panel_data;
+
+	msm_fb_add_device(pdev);
+
+	if (pinfo->is_3d_panel)
+		mipi_dsi_3d_barrier_sysfs_register(&(pdev->dev));
+
+	return ret;
+}
+
+/**
+ * Device removal notification handler.
+ *
+ * @param pdev
+ *
+ * @return int
+ */
+static int __devexit mipi_d2l_remove(struct platform_device *pdev)
+{
+	/* Note: There are no APIs to remove fb device and free DSI buf. */
+	pr_debug("%s.\n", __func__);
+
+	if (bl_pwm) {
+		pwm_free(bl_pwm);
+		bl_pwm = NULL;
+	}
+
+	return 0;
+}
+
+/**
+ * Register the panel device.
+ *
+ * @param pinfo
+ * @param channel_id
+ * @param panel_id
+ *
+ * @return int
+ */
+int mipi_tc358764_dsi2lvds_register(struct msm_panel_info *pinfo,
+					   u32 channel_id, u32 panel_id)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+	/* Use DSI-to-LVDS bridge */
+	const char driver_name[] = "mipi_tc358764";
+
+	pr_debug("%s.\n", __func__);
+	ret = mipi_d2l_init();
+	if (ret) {
+		pr_err("mipi_d2l_init() failed with ret %u\n", ret);
+		return ret;
+	}
+
+	/* Note: the device id should be non-zero */
+	pdev = platform_device_alloc(driver_name, (panel_id << 8)|channel_id);
+	if (pdev == NULL)
+		return -ENOMEM;
+
+	pdev->dev.platform_data = pinfo;
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		pr_err("%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static struct platform_driver d2l_driver = {
+	.probe  = mipi_d2l_probe,
+	.remove = __devexit_p(mipi_d2l_remove),
+	.driver = {
+		.name   = DRV_NAME,
+	},
+};
+
+/**
+ * Module Init
+ *
+ * @return int
+ */
+static int mipi_d2l_init(void)
+{
+	pr_debug("%s.\n", __func__);
+
+	d2l_i2c_client = NULL;
+
+	return platform_driver_register(&d2l_driver);
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Toshiba MIPI-DSI-to-LVDS bridge driver");
+MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.h b/drivers/video/msm/mipi_tc358764_dsi2lvds.h
new file mode 100644
index 0000000..072d1f4
--- /dev/null
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.h
@@ -0,0 +1,19 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MIPI_TC358764_DSI2LVDS_H
+#define MIPI_TC358764_DSI2LVDS_H
+
+int mipi_tc358764_dsi2lvds_register(struct msm_panel_info *pinfo,
+	u32 channel_id, u32 panel_id);
+#endif  /* MIPI_TC358764_DSI2LVDS_H */
diff --git a/drivers/video/msm/mipi_toshiba.c b/drivers/video/msm/mipi_toshiba.c
new file mode 100644
index 0000000..520c67b
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba.c
@@ -0,0 +1,355 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_toshiba.h"
+
+static struct pwm_device *bl_lpm;
+static struct mipi_dsi_panel_platform_data *mipi_toshiba_pdata;
+
+#define TM_GET_PID(id) (((id) & 0xff00)>>8)
+
+static struct dsi_buf toshiba_tx_buf;
+static struct dsi_buf toshiba_rx_buf;
+static int mipi_toshiba_lcd_init(void);
+
+#ifdef TOSHIBA_CMDS_UNUSED
+static char one_lane[3] = {0xEF, 0x60, 0x62};
+static char dmode_wqvga[2] = {0xB3, 0x01};
+static char intern_wr_clk1_wqvga[3] = {0xef, 0x2f, 0x22};
+static char intern_wr_clk2_wqvga[3] = {0xef, 0x6e, 0x33};
+static char hor_addr_2A_wqvga[5] = {0x2A, 0x00, 0x00, 0x00, 0xef};
+static char hor_addr_2B_wqvga[5] = {0x2B, 0x00, 0x00, 0x01, 0xaa};
+static char if_sel_cmd[2] = {0x53, 0x00};
+#endif
+
+static char exit_sleep[2] = {0x11, 0x00};
+static char display_on[2] = {0x29, 0x00};
+static char display_off[2] = {0x28, 0x00};
+static char enter_sleep[2] = {0x10, 0x00};
+
+static char mcap_off[2] = {0xb2, 0x00};
+static char ena_test_reg[3] = {0xEF, 0x01, 0x01};
+static char two_lane[3] = {0xEF, 0x60, 0x63};
+static char non_burst_sync_pulse[3] = {0xef, 0x61, 0x09};
+static char dmode_wvga[2] = {0xB3, 0x00};
+static char intern_wr_clk1_wvga[3] = {0xef, 0x2f, 0xcc};
+static char intern_wr_clk2_wvga[3] = {0xef, 0x6e, 0xdd};
+static char hor_addr_2A_wvga[5] = {0x2A, 0x00, 0x00, 0x01, 0xdf};
+static char hor_addr_2B_wvga[5] = {0x2B, 0x00, 0x00, 0x03, 0x55};
+static char if_sel_video[2] = {0x53, 0x01};
+
+static struct dsi_cmd_desc toshiba_wvga_display_on_cmds[] = {
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(mcap_off), mcap_off},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(ena_test_reg), ena_test_reg},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(two_lane), two_lane},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(non_burst_sync_pulse),
+					non_burst_sync_pulse},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(dmode_wvga), dmode_wvga},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(intern_wr_clk1_wvga),
+					intern_wr_clk1_wvga},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(intern_wr_clk2_wvga),
+					intern_wr_clk2_wvga},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, 0, sizeof(hor_addr_2A_wvga),
+					hor_addr_2A_wvga},
+	{DTYPE_DCS_LWRITE, 1, 0, 0, 0, sizeof(hor_addr_2B_wvga),
+					hor_addr_2B_wvga},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(if_sel_video), if_sel_video},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(display_on), display_on}
+};
+
+static char mcap_start[2] = {0xb0, 0x04};
+static char num_out_pixelform[3] = {0xb3, 0x00, 0x87};
+static char dsi_ctrl[3] = {0xb6, 0x30, 0x83};
+static char panel_driving[7] = {0xc0, 0x01, 0x00, 0x85, 0x00, 0x00, 0x00};
+static char dispV_timing[5] = {0xc1, 0x00, 0x10, 0x00, 0x01};
+static char dispCtrl[3] = {0xc3, 0x00, 0x19};
+static char test_mode_c4[2] = {0xc4, 0x03};
+static char dispH_timing[15] = {
+	/* TYPE_DCS_LWRITE */
+	0xc5, 0x00, 0x01, 0x05,
+	0x04, 0x5e, 0x00, 0x00,
+	0x00, 0x00, 0x0b, 0x17,
+	0x05, 0x00, 0x00
+};
+static char test_mode_c6[2] = {0xc6, 0x00};
+static char gamma_setA[13] = {
+	0xc8, 0x0a, 0x15, 0x18,
+	0x1b, 0x1c, 0x0d, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00
+};
+static char gamma_setB[13] = {
+	0xc9, 0x0d, 0x1d, 0x1f,
+	0x1f, 0x1f, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00
+};
+static char gamma_setC[13] = {
+	0xca, 0x1e, 0x1f, 0x1e,
+	0x1d, 0x1d, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00
+};
+static char powerSet_ChrgPmp[5] = {0xd0, 0x02, 0x00, 0xa3, 0xb8};
+static char testMode_d1[6] = {0xd1, 0x10, 0x14, 0x53, 0x64, 0x00};
+static char powerSet_SrcAmp[3] = {0xd2, 0xb3, 0x00};
+static char powerInt_PS[3] = {0xd3, 0x33, 0x03};
+static char vreg[2] = {0xd5, 0x00};
+static char test_mode_d6[2] = {0xd6, 0x01};
+static char timingCtrl_d7[9] = {
+	0xd7, 0x09, 0x00, 0x84,
+	0x81, 0x61, 0xbc, 0xb5,
+	0x05
+};
+static char timingCtrl_d8[7] = {
+	0xd8, 0x04, 0x25, 0x90,
+	0x4c, 0x92, 0x00
+};
+static char timingCtrl_d9[4] = {0xd9, 0x5b, 0x7f, 0x05};
+static char white_balance[6] = {0xcb, 0x00, 0x00, 0x00, 0x1c, 0x00};
+static char vcs_settings[2] = {0xdd, 0x53};
+static char vcom_dc_settings[2] = {0xde, 0x43};
+static char testMode_e3[5] = {0xe3, 0x00, 0x00, 0x00, 0x00};
+static char testMode_e4[6] = {0xe4, 0x00, 0x00, 0x22, 0xaa, 0x00};
+static char testMode_e5[2] = {0xe5, 0x00};
+static char testMode_fa[4] = {0xfa, 0x00, 0x00, 0x00};
+static char testMode_fd[5] = {0xfd, 0x00, 0x00, 0x00, 0x00};
+static char testMode_fe[5] = {0xfe, 0x00, 0x00, 0x00, 0x00};
+static char mcap_end[2] = {0xb0, 0x03};
+static char set_add_mode[2] = {0x36, 0x0};
+static char set_pixel_format[2] = {0x3a, 0x70};
+
+
+static struct dsi_cmd_desc toshiba_wsvga_display_on_cmds[] = {
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 10, sizeof(mcap_start), mcap_start},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 10, sizeof(num_out_pixelform),
+		num_out_pixelform},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 10, sizeof(dsi_ctrl), dsi_ctrl},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(panel_driving), panel_driving},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(dispV_timing), dispV_timing},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(dispCtrl), dispCtrl},
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 0, sizeof(test_mode_c4), test_mode_c4},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(dispH_timing), dispH_timing},
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 0, sizeof(test_mode_c6), test_mode_c6},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(gamma_setA), gamma_setA},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(gamma_setB), gamma_setB},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(gamma_setC), gamma_setC},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(powerSet_ChrgPmp),
+		powerSet_ChrgPmp},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(testMode_d1), testMode_d1},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(powerSet_SrcAmp),
+		powerSet_SrcAmp},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(powerInt_PS), powerInt_PS},
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 0, sizeof(vreg), vreg},
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 0, sizeof(test_mode_d6), test_mode_d6},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(timingCtrl_d7), timingCtrl_d7},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(timingCtrl_d8), timingCtrl_d8},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(timingCtrl_d9), timingCtrl_d9},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(white_balance), white_balance},
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 0, sizeof(vcs_settings), vcs_settings},
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 0, sizeof(vcom_dc_settings),
+		vcom_dc_settings},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(testMode_e3), testMode_e3},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(testMode_e4), testMode_e4},
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 0, sizeof(testMode_e5), testMode_e5},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(testMode_fa), testMode_fa},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(testMode_fd), testMode_fd},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 0, sizeof(testMode_fe), testMode_fe},
+	{DTYPE_GEN_WRITE2, 1, 0, 0, 0, sizeof(mcap_end), mcap_end},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 0, sizeof(set_add_mode), set_add_mode},
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 0, sizeof(set_pixel_format),
+		set_pixel_format},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 120, sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(display_on), display_on}
+};
+
+static struct dsi_cmd_desc toshiba_display_off_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 50, sizeof(display_off), display_off},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 120, sizeof(enter_sleep), enter_sleep}
+};
+
+static int mipi_toshiba_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WVGA_PT)
+		mipi_dsi_cmds_tx(&toshiba_tx_buf,
+			toshiba_wvga_display_on_cmds,
+			ARRAY_SIZE(toshiba_wvga_display_on_cmds));
+	else if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WSVGA_PT ||
+		TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WUXGA)
+		mipi_dsi_cmds_tx(&toshiba_tx_buf,
+			toshiba_wsvga_display_on_cmds,
+			ARRAY_SIZE(toshiba_wsvga_display_on_cmds));
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int mipi_toshiba_lcd_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi_dsi_cmds_tx(&toshiba_tx_buf, toshiba_display_off_cmds,
+			ARRAY_SIZE(toshiba_display_off_cmds));
+
+	return 0;
+}
+
+void mipi_bklight_pwm_cfg(void)
+{
+	if (mipi_toshiba_pdata && mipi_toshiba_pdata->dsi_pwm_cfg)
+		mipi_toshiba_pdata->dsi_pwm_cfg();
+}
+
+static void mipi_toshiba_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int ret;
+	static int bklight_pwm_cfg;
+
+	if (bklight_pwm_cfg == 0) {
+		mipi_bklight_pwm_cfg();
+		bklight_pwm_cfg++;
+	}
+
+	if (bl_lpm) {
+		ret = pwm_config(bl_lpm, MIPI_TOSHIBA_PWM_DUTY_LEVEL *
+			mfd->bl_level, MIPI_TOSHIBA_PWM_PERIOD_USEC);
+		if (ret) {
+			pr_err("pwm_config on lpm failed %d\n", ret);
+			return;
+		}
+		if (mfd->bl_level) {
+			ret = pwm_enable(bl_lpm);
+			if (ret)
+				pr_err("pwm enable/disable on lpm failed"
+					"for bl %d\n",	mfd->bl_level);
+		} else {
+			pwm_disable(bl_lpm);
+		}
+	}
+}
+
+static int __devinit mipi_toshiba_lcd_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		mipi_toshiba_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	if (mipi_toshiba_pdata == NULL) {
+		pr_err("%s.invalid platform data.\n", __func__);
+		return -ENODEV;
+	}
+
+	if (mipi_toshiba_pdata != NULL)
+		bl_lpm = pwm_request(mipi_toshiba_pdata->gpio[0],
+			"backlight");
+
+	if (bl_lpm == NULL || IS_ERR(bl_lpm)) {
+		pr_err("%s pwm_request() failed\n", __func__);
+		bl_lpm = NULL;
+	}
+	pr_debug("bl_lpm = %p lpm = %d\n", bl_lpm,
+		mipi_toshiba_pdata->gpio[0]);
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mipi_toshiba_lcd_probe,
+	.driver = {
+		.name   = "mipi_toshiba",
+	},
+};
+
+static struct msm_fb_panel_data toshiba_panel_data = {
+	.on		= mipi_toshiba_lcd_on,
+	.off		= mipi_toshiba_lcd_off,
+	.set_backlight  = mipi_toshiba_set_backlight,
+};
+
+static int ch_used[3];
+
+int mipi_toshiba_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	ret = mipi_toshiba_lcd_init();
+	if (ret) {
+		pr_err("mipi_toshiba_lcd_init() failed with ret %u\n", ret);
+		return ret;
+	}
+
+	pdev = platform_device_alloc("mipi_toshiba", (panel << 8)|channel);
+	if (!pdev)
+		return -ENOMEM;
+
+	toshiba_panel_data.panel_info = *pinfo;
+
+	ret = platform_device_add_data(pdev, &toshiba_panel_data,
+		sizeof(toshiba_panel_data));
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		printk(KERN_ERR
+		  "%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int mipi_toshiba_lcd_init(void)
+{
+	mipi_dsi_buf_alloc(&toshiba_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&toshiba_rx_buf, DSI_BUF_SIZE);
+
+	return platform_driver_register(&this_driver);
+}
diff --git a/drivers/video/msm/mipi_toshiba.h b/drivers/video/msm/mipi_toshiba.h
new file mode 100644
index 0000000..632bbd3
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba.h
@@ -0,0 +1,30 @@
+
+/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MIPI_TOSHIBA_H
+#define MIPI_TOSHIBA_H
+
+#include <linux/pwm.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+
+int mipi_toshiba_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#define MIPI_TOSHIBA_PWM_FREQ_HZ 300
+#define MIPI_TOSHIBA_PWM_PERIOD_USEC (USEC_PER_SEC / MIPI_TOSHIBA_PWM_FREQ_HZ)
+#define MIPI_TOSHIBA_PWM_LEVEL 100
+#define MIPI_TOSHIBA_PWM_DUTY_LEVEL \
+	(MIPI_TOSHIBA_PWM_PERIOD_USEC / MIPI_TOSHIBA_PWM_LEVEL)
+
+#endif  /* MIPI_TOSHIBA_H */
diff --git a/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
new file mode 100644
index 0000000..eb2946b
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
@@ -0,0 +1,104 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_toshiba.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* 600*1024, RGB888, 3 Lane 55 fps video mode */
+    /* regulator */
+	{0x09, 0x08, 0x05, 0x00, 0x20},
+	/* timing */
+	{0x73, 0x2e, 0x11, 0x00, 0x3c, 0x46, 0x14, 0x31,
+	0x1c, 0x03, 0x04, 0xa0},
+    /* phy ctrl */
+	{0x5f, 0x00, 0x00, 0x10},
+    /* strength */
+	{0xff, 0x00, 0x06, 0x00},
+	/* pll control */
+	{0x0, 0x49, 0x30, 0xc4, 0x00, 0x20, 0x07, 0x62,
+	0x41, 0x0f, 0x01,
+	0x00, 0x14, 0x03, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01 },
+};
+
+static int __init mipi_video_toshiba_wsvga_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_toshiba_wsvga"))
+		return 0;
+
+	pinfo.xres = 600;
+	pinfo.yres = 1024;
+	/*
+	 *
+	 * Panel's Horizontal input timing requirement is to
+	 * include dummy(pad) data of 200 clk in addition to
+	 * width and porch/sync width values
+	 */
+	pinfo.lcdc.xres_pad = 200;
+	pinfo.lcdc.yres_pad = 0;
+
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 16;
+	pinfo.lcdc.h_front_porch = 23;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 3;
+	pinfo.lcdc.v_front_porch = 45;
+	pinfo.lcdc.v_pulse_width = 2;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = MIPI_TOSHIBA_PWM_LEVEL;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	pinfo.mipi.pulse_mode_hsa_he = FALSE;
+	pinfo.mipi.hfp_power_stop = FALSE;
+	pinfo.mipi.hbp_power_stop = FALSE;
+	pinfo.mipi.hsa_power_stop = FALSE;
+	pinfo.mipi.eof_bllp_power_stop = FALSE;
+	pinfo.mipi.bllp_power_stop = FALSE;
+	pinfo.mipi.traffic_mode = DSI_NON_BURST_SYNCH_EVENT;
+	pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.data_lane2 = TRUE;
+	pinfo.mipi.t_clk_post = 0x04;
+	pinfo.mipi.t_clk_pre = 0x1a;
+	pinfo.mipi.esc_byte_ratio = 4;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = 0;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 55;
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+	pinfo.mipi.tx_eot_append = TRUE;
+
+	ret = mipi_toshiba_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_WSVGA_PT);
+	if (ret)
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_toshiba_wsvga_pt_init);
diff --git a/drivers/video/msm/mipi_toshiba_video_wuxga.c b/drivers/video/msm/mipi_toshiba_video_wuxga.c
new file mode 100644
index 0000000..8eddce4
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba_video_wuxga.c
@@ -0,0 +1,98 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_toshiba.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* 1920*1200, RGB888, 4 Lane 60 fps video mode */
+	/* regulator */
+	{0x03, 0x0a, 0x04, 0x00, 0x20},
+	/* timing */
+	{0x66, 0x26, 0x1F, 0x00, 0x55, 0x9C, 0x16, 0x90,
+	0x23, 0x03, 0x04, 0xa0},
+	/* phy ctrl */
+	{0x5f, 0x00, 0x00, 0x10},
+	/* strength */
+	{0xff, 0x00, 0x06, 0x00},
+	/* pll control */
+	{0x0, 0xD7, 0x1, 0x19, 0x00, 0x50, 0x48, 0x63,
+	0x41, 0x0f, 0x01,
+	0x00, 0x14, 0x03, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01 },
+};
+
+static int __init mipi_video_toshiba_wuxga_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_toshiba_wuxga"))
+		return 0;
+
+	pinfo.xres = 1920;
+	pinfo.yres = 1200;
+
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 50;
+	pinfo.lcdc.h_front_porch = 50;
+	pinfo.lcdc.h_pulse_width = 170;
+	pinfo.lcdc.v_back_porch = 7;
+	pinfo.lcdc.v_front_porch = 8;
+	pinfo.lcdc.v_pulse_width = 30;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = MIPI_TOSHIBA_PWM_LEVEL;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+	pinfo.clk_rate = 981560000;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	pinfo.mipi.pulse_mode_hsa_he = TRUE;
+	pinfo.mipi.hfp_power_stop = FALSE;
+	pinfo.mipi.hbp_power_stop = FALSE;
+	pinfo.mipi.hsa_power_stop = FALSE;
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	pinfo.mipi.bllp_power_stop = TRUE;
+	pinfo.mipi.traffic_mode = DSI_NON_BURST_SYNCH_PULSE;
+	pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_BGR;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.data_lane2 = TRUE;
+	pinfo.mipi.data_lane3 = TRUE;
+	pinfo.mipi.tx_eot_append = TRUE;
+	pinfo.mipi.t_clk_post = 0x04;
+	pinfo.mipi.t_clk_pre = 0x1c;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60;
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+	pinfo.mipi.esc_byte_ratio = 9;
+
+	ret = mipi_toshiba_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_WUXGA);
+	if (ret)
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_toshiba_wuxga_init);
diff --git a/drivers/video/msm/mipi_toshiba_video_wvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
new file mode 100644
index 0000000..d6cabfc
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
@@ -0,0 +1,106 @@
+/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_toshiba.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* 480*854, RGB888, 2 Lane 60 fps video mode */
+		{0x03, 0x01, 0x01, 0x00},	/* regulator */
+		/* timing   */
+		{0x6a, 0x22, 0x0f, 0x00, 0x30, 0x38, 0x13, 0x26,
+		0x1b, 0x03, 0x04},
+		{0x7f, 0x00, 0x00, 0x00},	/* phy ctrl */
+		{0xee, 0x03, 0x86, 0x03},	/* strength */
+		/* pll control */
+
+#define DSI_BIT_CLK_380MHZ
+
+#if defined(DSI_BIT_CLK_366MHZ)
+		{0x41, 0xdb, 0xb2, 0xf5, 0x00, 0x50, 0x48, 0x63,
+		0x31, 0x0f, 0x07,
+		0x05, 0x14, 0x03, 0x03, 0x03, 0x54, 0x06, 0x10, 0x04, 0x03 },
+#elif defined(DSI_BIT_CLK_380MHZ)
+		{0x41, 0xf7, 0xb2, 0xf5, 0x00, 0x50, 0x48, 0x63,
+		0x31, 0x0f, 0x07,
+		0x05, 0x14, 0x03, 0x03, 0x03, 0x54, 0x06, 0x10, 0x04, 0x03 },
+#elif defined(DSI_BIT_CLK_400MHZ)
+		{0x41, 0x8f, 0xb1, 0xda, 0x00, 0x50, 0x48, 0x63,
+		0x31, 0x0f, 0x07,
+		0x05, 0x14, 0x03, 0x03, 0x03, 0x54, 0x06, 0x10, 0x04, 0x03 },
+#else		/* 200 mhz */
+		{0x41, 0x8f, 0xb1, 0xda, 0x00, 0x50, 0x48, 0x63,
+		0x33, 0x1f, 0x0f,
+		0x05, 0x14, 0x03, 0x03, 0x03, 0x54, 0x06, 0x10, 0x04, 0x03 },
+#endif
+};
+
+static int __init mipi_video_toshiba_wvga_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_toshiba_wvga"))
+		return 0;
+
+	pinfo.xres = 480;
+	pinfo.yres = 864; /* 856 for V1 surf */
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 64;
+	pinfo.lcdc.h_front_porch = 64;
+	pinfo.lcdc.h_pulse_width = 16;
+	pinfo.lcdc.v_back_porch = 8;
+	pinfo.lcdc.v_front_porch = 4;
+	pinfo.lcdc.v_pulse_width = 1;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 15;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	pinfo.mipi.pulse_mode_hsa_he = TRUE;
+	pinfo.mipi.hfp_power_stop = FALSE;
+	pinfo.mipi.hbp_power_stop = FALSE;
+	pinfo.mipi.hsa_power_stop = FALSE;
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	pinfo.mipi.bllp_power_stop = TRUE;
+	pinfo.mipi.traffic_mode = DSI_NON_BURST_SYNCH_PULSE;
+	pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_BGR;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.t_clk_post = 0x04;
+	pinfo.mipi.t_clk_pre = 0x17;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60;
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+	ret = mipi_toshiba_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_WVGA_PT);
+	if (ret)
+		printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_toshiba_wvga_pt_init);
diff --git a/drivers/video/msm/mipi_truly.c b/drivers/video/msm/mipi_truly.c
new file mode 100644
index 0000000..fd2a3ea
--- /dev/null
+++ b/drivers/video/msm/mipi_truly.c
@@ -0,0 +1,259 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_truly.h"
+
+static struct msm_panel_common_pdata *mipi_truly_pdata;
+static struct dsi_buf truly_tx_buf;
+static struct dsi_buf truly_rx_buf;
+
+#define TRULY_CMD_DELAY		0
+#define TRULY_SLEEP_OFF_DELAY	150
+#define TRULY_DISPLAY_ON_DELAY	150
+#define GPIO_TRULY_LCD_RESET	129
+
+static int prev_bl = 17;
+
+static char extend_cmd_enable[4] = {0xB9, 0xFF, 0x83, 0x69};
+static char display_setting[16] = {
+	0xB2, 0x00, 0x23, 0x62,
+	0x62, 0x70, 0x00, 0xFF,
+	0x00, 0x00, 0x00, 0x00,
+	0x03, 0x03, 0x00, 0x01,
+};
+static char wave_cycle_setting[6] = {0xB4, 0x00, 0x1D, 0x5F, 0x0E, 0x06};
+static char gip_setting[27] = {
+	0xD5, 0x00, 0x04, 0x03,
+	0x00, 0x01, 0x05, 0x1C,
+	0x70, 0x01, 0x03, 0x00,
+	0x00, 0x40, 0x06, 0x51,
+	0x07, 0x00, 0x00, 0x41,
+	0x06, 0x50, 0x07, 0x07,
+	0x0F, 0x04, 0x00,
+};
+static char power_setting[20] = {
+	0xB1, 0x01, 0x00, 0x34,
+	0x06, 0x00, 0x0F, 0x0F,
+	0x2A, 0x32, 0x3F, 0x3F,
+	0x07, 0x3A, 0x01, 0xE6,
+	0xE6, 0xE6, 0xE6, 0xE6,
+};
+static char vcom_setting[3] = {0xB6, 0x56, 0x56};
+static char pannel_setting[2] = {0xCC, 0x02};
+static char gamma_setting[35] = {
+	0xE0, 0x00, 0x1D, 0x22,
+	0x38, 0x3D, 0x3F, 0x2E,
+	0x4A, 0x06, 0x0D, 0x0F,
+	0x13, 0x15, 0x13, 0x16,
+	0x10, 0x19, 0x00, 0x1D,
+	0x22, 0x38, 0x3D, 0x3F,
+	0x2E, 0x4A, 0x06, 0x0D,
+	0x0F, 0x13, 0x15, 0x13,
+	0x16, 0x10, 0x19,
+};
+static char mipi_setting[14] = {
+	0xBA, 0x00, 0xA0, 0xC6,
+	0x00, 0x0A, 0x00, 0x10,
+	0x30, 0x6F, 0x02, 0x11,
+	0x18, 0x40,
+};
+static char exit_sleep[2] = {0x11, 0x00};
+static char display_on[2] = {0x29, 0x00};
+static char display_off[2] = {0x28, 0x00};
+static char enter_sleep[2] = {0x10, 0x00};
+
+static struct dsi_cmd_desc truly_display_off_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10, sizeof(display_off), display_off},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 120, sizeof(enter_sleep), enter_sleep}
+};
+
+static struct dsi_cmd_desc truly_display_on_cmds[] = {
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(extend_cmd_enable), extend_cmd_enable},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(display_setting), display_setting},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(wave_cycle_setting), wave_cycle_setting},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(gip_setting), gip_setting},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(power_setting), power_setting},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(vcom_setting), vcom_setting},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(pannel_setting), pannel_setting},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(gamma_setting), gamma_setting},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
+			sizeof(mipi_setting), mipi_setting},
+	{DTYPE_DCS_WRITE, 1, 0, 0, TRULY_SLEEP_OFF_DELAY,
+			sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, TRULY_DISPLAY_ON_DELAY,
+			sizeof(display_on), display_on},
+};
+
+static int mipi_truly_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	msleep(20);
+	mipi_dsi_cmds_tx(&truly_tx_buf, truly_display_on_cmds,
+			ARRAY_SIZE(truly_display_on_cmds));
+
+	return 0;
+}
+
+static int mipi_truly_lcd_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi_dsi_cmds_tx(&truly_tx_buf, truly_display_off_cmds,
+			ARRAY_SIZE(truly_display_off_cmds));
+
+	return 0;
+}
+
+#define BL_LEVEL	17
+static void mipi_truly_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int step = 0, i = 0;
+	int bl_level = mfd->bl_level;
+
+	/* real backlight level, 1 - max, 16 - min, 17 - off */
+	bl_level = BL_LEVEL - bl_level;
+
+	if (bl_level > prev_bl) {
+		step = bl_level - prev_bl;
+		if (bl_level == BL_LEVEL)
+			step--;
+	} else if (bl_level < prev_bl) {
+		step = bl_level + 16 - prev_bl;
+	} else {
+		pr_debug("%s: no change\n", __func__);
+		return;
+	}
+
+	if (bl_level == BL_LEVEL) {
+		/* turn off backlight */
+		mipi_truly_pdata->pmic_backlight(0);
+	} else {
+		if (prev_bl == BL_LEVEL) {
+			/* turn on backlight */
+			mipi_truly_pdata->pmic_backlight(1);
+			udelay(30);
+		}
+		/* adjust backlight level */
+		for (i = 0; i < step; i++) {
+			mipi_truly_pdata->pmic_backlight(0);
+			udelay(1);
+			mipi_truly_pdata->pmic_backlight(1);
+			udelay(1);
+		}
+	}
+	msleep(20);
+	prev_bl = bl_level;
+
+	return;
+}
+
+static int __devinit mipi_truly_lcd_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		mipi_truly_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mipi_truly_lcd_probe,
+	.driver = {
+		.name   = "mipi_truly",
+	},
+};
+
+static struct msm_fb_panel_data truly_panel_data = {
+	.on		= mipi_truly_lcd_on,
+	.off		= mipi_truly_lcd_off,
+	.set_backlight	= mipi_truly_set_backlight,
+};
+
+static int ch_used[3];
+
+int mipi_truly_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	pdev = platform_device_alloc("mipi_truly", (panel << 8)|channel);
+
+	if (!pdev)
+		return -ENOMEM;
+
+	truly_panel_data.panel_info = *pinfo;
+
+	ret = platform_device_add_data(pdev, &truly_panel_data,
+				sizeof(truly_panel_data));
+	if (ret) {
+		pr_err("%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+
+	if (ret) {
+		pr_err("%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int __init mipi_truly_lcd_init(void)
+{
+	mipi_dsi_buf_alloc(&truly_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&truly_rx_buf, DSI_BUF_SIZE);
+
+	return platform_driver_register(&this_driver);
+}
+
+module_init(mipi_truly_lcd_init);
diff --git a/drivers/video/msm/mipi_truly.h b/drivers/video/msm/mipi_truly.h
new file mode 100644
index 0000000..900e6f6
--- /dev/null
+++ b/drivers/video/msm/mipi_truly.h
@@ -0,0 +1,21 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MIPI_TRULY_H
+#define MIPI_TRULY_H
+
+/* #define MIPI_TRULY_FAKE_PANEL */	/* FAKE PANEL for test */
+
+int mipi_truly_device_register(struct msm_panel_info *pinfo,
+		u32 channel, u32 panel);
+
+#endif  /* MIPI_TRULY_H */
diff --git a/drivers/video/msm/mipi_truly_video_wvga_pt.c b/drivers/video/msm/mipi_truly_video_wvga_pt.c
new file mode 100644
index 0000000..931c564
--- /dev/null
+++ b/drivers/video/msm/mipi_truly_video_wvga_pt.c
@@ -0,0 +1,110 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_truly.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */
+	/* regulator */
+	{0x03, 0x01, 0x01, 0x00},
+	/* timing   */
+	{0xb9, 0x8e, 0x1f, 0x00, 0x98, 0x9c, 0x22, 0x90,
+	0x18, 0x03, 0x04},
+	/* phy ctrl */
+	{0x7f, 0x00, 0x00, 0x00},
+	/* strength */
+	{0xbb, 0x02, 0x06, 0x00},
+	/* pll control */
+	{0x00, 0xec, 0x31, 0xd2, 0x00, 0x40, 0x37, 0x62,
+	0x01, 0x0f, 0x07,
+	0x05, 0x14, 0x03, 0x0, 0x0, 0x0, 0x20, 0x0, 0x02, 0x0},
+};
+
+static int __init mipi_video_truly_wvga_pt_init(void)
+{
+	int ret;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("mipi_video_truly_wvga"))
+		return 0;
+#endif
+
+	pinfo.xres = 480;
+	pinfo.yres = 800;
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 100;
+	pinfo.lcdc.h_front_porch = 100;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 20;
+	pinfo.lcdc.v_front_porch = 20;
+	pinfo.lcdc.v_pulse_width = 1;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	/* number of dot_clk cycles HSYNC active edge
+	   is delayed from VSYNC active edge */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.clk_rate = 499000000;
+	pinfo.bl_max = 15;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	pinfo.mipi.pulse_mode_hsa_he = TRUE; /* send HSA and HE following
+						VS/VE packet */
+	pinfo.mipi.hfp_power_stop = TRUE; /* LP-11 during the HFP period */
+	pinfo.mipi.hbp_power_stop = TRUE; /* LP-11 during the HBP period */
+	pinfo.mipi.hsa_power_stop = TRUE; /* LP-11 during the HSA period */
+	/* LP-11 or let Command Mode Engine send packets in
+	HS or LP mode for the BLLP of the last line of a frame */
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	/* LP-11 or let Command Mode Engine send packets in
+	HS or LP mode for packets sent during BLLP period */
+	pinfo.mipi.bllp_power_stop = TRUE;
+
+	pinfo.mipi.traffic_mode = DSI_BURST_MODE;
+	pinfo.mipi.dst_format =  DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB; /* RGB */
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+
+	pinfo.mipi.t_clk_post = 0x20;
+	pinfo.mipi.t_clk_pre = 0x2f;
+
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60; /* FIXME */
+
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+	pinfo.mipi.dlane_swap = 0x01;
+	pinfo.mipi.tx_eot_append = 0x01; /* append EOT at the end
+					    of data burst */
+
+	ret = mipi_truly_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_WVGA_PT);
+
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_truly_wvga_pt_init);
diff --git a/drivers/video/msm/msm_dss_io_7x27a.c b/drivers/video/msm/msm_dss_io_7x27a.c
new file mode 100644
index 0000000..17ee976
--- /dev/null
+++ b/drivers/video/msm/msm_dss_io_7x27a.c
@@ -0,0 +1,470 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/clk.h>
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+
+/* multimedia sub system sfpb */
+char *mmss_sfpb_base;
+void  __iomem *periph_base;
+
+static struct dsi_clk_desc dsicore_clk;
+static struct dsi_clk_desc dsi_pclk;
+
+static struct clk *dsi_byte_div_clk;
+static struct clk *dsi_esc_clk;
+static struct clk *dsi_pixel_clk;
+static struct clk *dsi_clk;
+static struct clk *dsi_ref_clk;
+static struct clk *mdp_dsi_pclk;
+static struct clk *ahb_m_clk;
+static struct clk *ahb_s_clk;
+static struct clk *ebi1_dsi_clk;
+int mipi_dsi_clk_on;
+
+int mipi_dsi_clk_init(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	dsi_esc_clk = clk_get(dev, "esc_clk");
+	if (IS_ERR_OR_NULL(dsi_esc_clk)) {
+		printk(KERN_ERR "can't find dsi_esc_clk\n");
+		dsi_esc_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_byte_div_clk = clk_get(dev, "byte_clk");
+	if (IS_ERR_OR_NULL(dsi_byte_div_clk)) {
+		pr_err("can't find dsi_byte_div_clk\n");
+		dsi_byte_div_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_pixel_clk = clk_get(dev, "pixel_clk");
+	if (IS_ERR_OR_NULL(dsi_pixel_clk)) {
+		pr_err("can't find dsi_pixel_clk\n");
+		dsi_pixel_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_clk = clk_get(dev, "core_clk");
+	if (IS_ERR_OR_NULL(dsi_clk)) {
+		pr_err("can't find dsi_clk\n");
+		dsi_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_ref_clk = clk_get(dev, "ref_clk");
+	if (IS_ERR_OR_NULL(dsi_ref_clk)) {
+		pr_err("can't find dsi_ref_clk\n");
+		dsi_ref_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	mdp_dsi_pclk = clk_get(dev, "mdp_clk");
+	if (IS_ERR_OR_NULL(mdp_dsi_pclk)) {
+		pr_err("can't find mdp_dsi_pclk\n");
+		mdp_dsi_pclk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	ahb_m_clk = clk_get(dev, "master_iface_clk");
+	if (IS_ERR_OR_NULL(ahb_m_clk)) {
+		pr_err("can't find ahb_m_clk\n");
+		ahb_m_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	ahb_s_clk = clk_get(dev, "slave_iface_clk");
+	if (IS_ERR_OR_NULL(ahb_s_clk)) {
+		pr_err("can't find ahb_s_clk\n");
+		ahb_s_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	ebi1_dsi_clk = clk_get(dev, "mem_clk");
+	if (IS_ERR_OR_NULL(ebi1_dsi_clk)) {
+		pr_err("can't find ebi1_dsi_clk\n");
+		ebi1_dsi_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	return 0;
+
+mipi_dsi_clk_err:
+	mipi_dsi_clk_deinit(NULL);
+	return -EPERM;
+}
+
+void mipi_dsi_clk_deinit(struct device *dev)
+{
+	if (mdp_dsi_pclk)
+		clk_put(mdp_dsi_pclk);
+	if (ahb_m_clk)
+		clk_put(ahb_m_clk);
+	if (ahb_s_clk)
+		clk_put(ahb_s_clk);
+	if (dsi_ref_clk)
+		clk_put(dsi_ref_clk);
+	if (dsi_byte_div_clk)
+		clk_put(dsi_byte_div_clk);
+	if (dsi_esc_clk)
+		clk_put(dsi_esc_clk);
+	if (ebi1_dsi_clk)
+		clk_put(ebi1_dsi_clk);
+}
+
+static void mipi_dsi_clk_ctrl(struct dsi_clk_desc *clk, int clk_en)
+{
+	uint32 data;
+	if (clk_en) {
+		data = (clk->pre_div_func) << 24 |
+			(clk->m) << 16 | (clk->n) << 8 |
+			((clk->d) * 2);
+		clk_set_rate(dsi_clk, data);
+		clk_enable(dsi_clk);
+	} else
+		clk_disable(dsi_clk);
+}
+
+static void mipi_dsi_pclk_ctrl(struct dsi_clk_desc *clk, int clk_en)
+{
+	uint32 data;
+
+	if (clk_en) {
+		data = (clk->pre_div_func) << 24 | (clk->m) << 16
+			| (clk->n) << 8 | ((clk->d) * 2);
+		if ((clk_set_rate(dsi_pixel_clk, data)) < 0)
+			pr_err("%s: pixel clk set rate failed\n", __func__);
+		if (clk_enable(dsi_pixel_clk))
+			pr_err("%s clk enable failed\n", __func__);
+	} else {
+		clk_disable(dsi_pixel_clk);
+	}
+}
+
+static void mipi_dsi_calibration(void)
+{
+	MIPI_OUTP(MIPI_DSI_BASE + 0xf8, 0x00a105a1); /* cal_hw_ctrl */
+}
+
+#define PREF_DIV_RATIO 19
+struct dsiphy_pll_divider_config pll_divider_config;
+
+int mipi_dsi_clk_div_config(uint8 bpp, uint8 lanes,
+			    uint32 *expected_dsi_pclk)
+{
+	u32 fb_divider, rate, vco;
+	u32 div_ratio = 0;
+	struct dsi_clk_mnd_table const *mnd_entry = mnd_table;
+	if (pll_divider_config.clk_rate == 0)
+		pll_divider_config.clk_rate = 454000000;
+
+	rate = pll_divider_config.clk_rate / 1000000; /* In Mhz */
+
+	if (rate < 125) {
+		vco = rate * 8;
+		div_ratio = 8;
+	} else if (rate < 250) {
+		vco = rate * 4;
+		div_ratio = 4;
+	} else if (rate < 500) {
+		vco = rate * 2;
+		div_ratio = 2;
+	} else {
+		vco = rate * 1;
+		div_ratio = 1;
+	}
+
+	/* find the mnd settings from mnd_table entry */
+	for (; mnd_entry != mnd_table + ARRAY_SIZE(mnd_table); ++mnd_entry) {
+		if (((mnd_entry->lanes) == lanes) &&
+			((mnd_entry->bpp) == bpp))
+			break;
+	}
+
+	if (mnd_entry == mnd_table + ARRAY_SIZE(mnd_table)) {
+		pr_err("%s: requested Lanes, %u & BPP, %u, not supported\n",
+			__func__, lanes, bpp);
+		return -EINVAL;
+	}
+	fb_divider = ((vco * PREF_DIV_RATIO) / 27);
+	pll_divider_config.fb_divider = fb_divider;
+	pll_divider_config.ref_divider_ratio = PREF_DIV_RATIO;
+	pll_divider_config.bit_clk_divider = div_ratio;
+	pll_divider_config.byte_clk_divider =
+			pll_divider_config.bit_clk_divider * 8;
+	pll_divider_config.dsi_clk_divider =
+			(mnd_entry->dsiclk_div) * div_ratio;
+
+	if ((mnd_entry->dsiclk_d == 0)
+		|| (mnd_entry->dsiclk_m == 1)) {
+		dsicore_clk.mnd_mode = 0;
+		dsicore_clk.src = 0x3;
+		dsicore_clk.pre_div_func = (mnd_entry->dsiclk_n - 1);
+	} else {
+		dsicore_clk.mnd_mode = 2;
+		dsicore_clk.src = 0x3;
+		dsicore_clk.m = mnd_entry->dsiclk_m;
+		dsicore_clk.n = mnd_entry->dsiclk_n;
+		dsicore_clk.d = mnd_entry->dsiclk_d;
+	}
+
+	if ((mnd_entry->pclk_d == 0)
+		|| (mnd_entry->pclk_m == 1)) {
+		dsi_pclk.mnd_mode = 0;
+		dsi_pclk.src = 0x3;
+		dsi_pclk.pre_div_func = (mnd_entry->pclk_n - 1);
+		*expected_dsi_pclk = ((vco * 1000000) /
+					((pll_divider_config.dsi_clk_divider)
+					* (mnd_entry->pclk_n)));
+	} else {
+		dsi_pclk.mnd_mode = 2;
+		dsi_pclk.src = 0x3;
+		dsi_pclk.m = mnd_entry->pclk_m;
+		dsi_pclk.n = mnd_entry->pclk_n;
+		dsi_pclk.d = mnd_entry->pclk_d;
+		*expected_dsi_pclk = ((vco * 1000000 * dsi_pclk.m) /
+					((pll_divider_config.dsi_clk_divider)
+					* (mnd_entry->pclk_n)));
+	}
+	dsicore_clk.m = 1;
+	dsicore_clk.n = 1;
+	dsicore_clk.d = 2;
+	dsicore_clk.pre_div_func = 0;
+
+	dsi_pclk.m = 1;
+	dsi_pclk.n = 3;
+	dsi_pclk.d = 2;
+	dsi_pclk.pre_div_func = 0;
+	return 0;
+}
+
+void mipi_dsi_phy_init(int panel_ndx, struct msm_panel_info const *panel_info,
+	int target_type)
+{
+	struct mipi_dsi_phy_ctrl *pd;
+	int i, off;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0001);/* start phy sw reset */
+	wmb();
+	usleep(1000);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0000);/* end phy w reset */
+	wmb();
+	usleep(1000);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2cc, 0x0003);/* regulator_ctrl_0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2d0, 0x0001);/* regulator_ctrl_1 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2d4, 0x0001);/* regulator_ctrl_2 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2d8, 0x0000);/* regulator_ctrl_3 */
+#ifdef DSI_POWER
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2dc, 0x0100);/* regulator_ctrl_4 */
+#endif
+
+	pd = (panel_info->mipi).dsi_phy_db;
+
+	off = 0x02cc;	/* regulator ctrl 0 */
+	for (i = 0; i < 4; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->regulator[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x0260;	/* phy timig ctrl 0 */
+	for (i = 0; i < 11; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->timing[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x0290;	/* ctrl 0 */
+	for (i = 0; i < 4; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->ctrl[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x02a0;	/* strength 0 */
+	for (i = 0; i < 4; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->strength[i]);
+		wmb();
+		off += 4;
+	}
+
+	mipi_dsi_calibration();
+
+	off = 0x0204;	/* pll ctrl 1, skip 0 */
+	for (i = 1; i < 21; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->pll[i]);
+		wmb();
+		off += 4;
+	}
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x100, 0x67);
+
+	/* pll ctrl 0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pd->pll[0]);
+	wmb();
+}
+
+void cont_splash_clk_ctrl(int enable)
+{
+}
+
+void mipi_dsi_prepare_clocks(void)
+{
+	clk_prepare(dsi_ref_clk);
+	clk_prepare(ahb_m_clk);
+	clk_prepare(ahb_s_clk);
+	clk_prepare(ebi1_dsi_clk);
+	clk_prepare(mdp_dsi_pclk);
+	clk_prepare(dsi_byte_div_clk);
+	clk_prepare(dsi_esc_clk);
+	clk_prepare(dsi_clk);
+	clk_prepare(dsi_pixel_clk);
+}
+
+void mipi_dsi_unprepare_clocks(void)
+{
+	clk_unprepare(dsi_esc_clk);
+	clk_unprepare(dsi_byte_div_clk);
+	clk_unprepare(mdp_dsi_pclk);
+	clk_unprepare(ebi1_dsi_clk);
+	clk_unprepare(ahb_m_clk);
+	clk_unprepare(ahb_s_clk);
+	clk_unprepare(dsi_ref_clk);
+	clk_unprepare(dsi_clk);
+	clk_unprepare(dsi_pixel_clk);
+}
+
+void mipi_dsi_ahb_ctrl(u32 enable)
+{
+	static int ahb_ctrl_done;
+	if (enable) {
+		if (ahb_ctrl_done) {
+			pr_info("%s: ahb clks already ON\n", __func__);
+			return;
+		}
+		clk_enable(dsi_ref_clk);
+		clk_enable(ahb_m_clk);
+		clk_enable(ahb_s_clk);
+		ahb_ctrl_done = 1;
+	} else {
+		if (ahb_ctrl_done == 0) {
+			pr_info("%s: ahb clks already OFF\n", __func__);
+			return;
+		}
+		clk_disable(ahb_m_clk);
+		clk_disable(ahb_s_clk);
+		clk_disable(dsi_ref_clk);
+		ahb_ctrl_done = 0;
+	}
+}
+
+void mipi_dsi_clk_enable(void)
+{
+	unsigned data = 0;
+	uint32 pll_ctrl;
+
+	if (mipi_dsi_clk_on) {
+		pr_info("%s: mipi_dsi_clks already ON\n", __func__);
+		return;
+	}
+	if (clk_set_rate(ebi1_dsi_clk, 65000000)) /* 65 MHz */
+		pr_err("%s: ebi1_dsi_clk set rate failed\n", __func__);
+	clk_enable(ebi1_dsi_clk);
+
+	pll_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0200);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pll_ctrl | 0x01);
+	mb();
+
+	clk_set_rate(dsi_byte_div_clk, data);
+	clk_set_rate(dsi_esc_clk, data);
+	clk_enable(mdp_dsi_pclk);
+	clk_enable(dsi_byte_div_clk);
+	clk_enable(dsi_esc_clk);
+	mipi_dsi_pclk_ctrl(&dsi_pclk, 1);
+	mipi_dsi_clk_ctrl(&dsicore_clk, 1);
+	mipi_dsi_clk_on = 1;
+}
+
+void mipi_dsi_clk_disable(void)
+{
+	if (mipi_dsi_clk_on == 0) {
+		pr_info("%s: mipi_dsi_clks already OFF\n", __func__);
+		return;
+	}
+	mipi_dsi_pclk_ctrl(&dsi_pclk, 0);
+	mipi_dsi_clk_ctrl(&dsicore_clk, 0);
+	clk_disable(dsi_esc_clk);
+	clk_disable(dsi_byte_div_clk);
+	clk_disable(mdp_dsi_pclk);
+	/* DSIPHY_PLL_CTRL_0, disable dsi pll */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x40);
+	if (clk_set_rate(ebi1_dsi_clk, 0))
+		pr_err("%s: ebi1_dsi_clk set rate failed\n", __func__);
+	clk_disable(ebi1_dsi_clk);
+	mipi_dsi_clk_on = 0;
+}
+
+void mipi_dsi_phy_ctrl(int on)
+{
+	if (on) {
+		/* DSIPHY_PLL_CTRL_5 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0214, 0x050);
+
+		/* DSIPHY_TPA_CTRL_1 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0258, 0x00f);
+
+		/* DSIPHY_TPA_CTRL_2 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x025c, 0x000);
+	} else {
+		/* DSIPHY_PLL_CTRL_5 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0214, 0x05f);
+
+		/* DSIPHY_TPA_CTRL_1 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0258, 0x08f);
+
+		/* DSIPHY_TPA_CTRL_2 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x025c, 0x001);
+
+		/* DSIPHY_REGULATOR_CTRL_0 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x02cc, 0x02);
+
+		/* DSIPHY_CTRL_0 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0290, 0x00);
+
+		/* DSIPHY_CTRL_1 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0294, 0x7f);
+
+		/* disable dsi clk */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0118, 0);
+	}
+}
+
+#ifdef CONFIG_FB_MSM_MDP303
+void update_lane_config(struct msm_panel_info *pinfo)
+{
+	struct mipi_dsi_phy_ctrl *pd;
+
+	pd = (pinfo->mipi).dsi_phy_db;
+	pinfo->mipi.data_lane1 = FALSE;
+	pd->pll[10] |= 0x08;
+
+	pinfo->yres = 320;
+	pinfo->lcdc.h_back_porch = 15;
+	pinfo->lcdc.h_front_porch = 21;
+	pinfo->lcdc.h_pulse_width = 5;
+	pinfo->lcdc.v_back_porch = 50;
+	pinfo->lcdc.v_front_porch = 101;
+	pinfo->lcdc.v_pulse_width = 50;
+}
+#endif
diff --git a/drivers/video/msm/msm_dss_io_8960.c b/drivers/video/msm/msm_dss_io_8960.c
new file mode 100644
index 0000000..828be9c
--- /dev/null
+++ b/drivers/video/msm/msm_dss_io_8960.c
@@ -0,0 +1,824 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/clk.h>
+#include "msm_fb.h"
+#include "mdp.h"
+#include "mdp4.h"
+#include "mipi_dsi.h"
+#include "hdmi_msm.h"
+#include <mach/msm_iomap.h>
+
+/* HDMI PHY macros */
+#define HDMI_PHY_REG_0                   (0x00000400)
+#define HDMI_PHY_REG_1                   (0x00000404)
+#define HDMI_PHY_REG_2                   (0x00000408)
+#define HDMI_PHY_REG_3                   (0x0000040c)
+#define HDMI_PHY_REG_4                   (0x00000410)
+#define HDMI_PHY_REG_5                   (0x00000414)
+#define HDMI_PHY_REG_6                   (0x00000418)
+#define HDMI_PHY_REG_7                   (0x0000041c)
+#define HDMI_PHY_REG_8                   (0x00000420)
+#define HDMI_PHY_REG_9                   (0x00000424)
+#define HDMI_PHY_REG_10                  (0x00000428)
+#define HDMI_PHY_REG_11                  (0x0000042c)
+#define HDMI_PHY_REG_12                  (0x00000430)
+#define HDMI_PHY_REG_BIST_CFG            (0x00000434)
+#define HDMI_PHY_DEBUG_BUS_SEL           (0x00000438)
+#define HDMI_PHY_REG_MISC0               (0x0000043c)
+#define HDMI_PHY_REG_13                  (0x00000440)
+#define HDMI_PHY_REG_14                  (0x00000444)
+#define HDMI_PHY_REG_15                  (0x00000448)
+#define HDMI_PHY_CTRL			         (0x000002D4)
+
+/* HDMI PHY/PLL bit field macros */
+#define HDMI_PHY_PLL_STATUS0             (0x00000598)
+#define SW_RESET BIT(2)
+#define SW_RESET_PLL BIT(0)
+#define PWRDN_B BIT(7)
+
+/* multimedia sub system clock control */
+char *mmss_cc_base = MSM_MMSS_CLK_CTL_BASE;
+/* multimedia sub system sfpb */
+char *mmss_sfpb_base;
+void  __iomem *periph_base;
+
+static struct dsi_clk_desc dsicore_clk;
+static struct dsi_clk_desc dsi_pclk;
+
+static struct clk *dsi_byte_div_clk;
+static struct clk *dsi_esc_clk;
+static struct clk *dsi_m_pclk;
+static struct clk *dsi_s_pclk;
+
+static struct clk *amp_pclk;
+int mipi_dsi_clk_on;
+
+int mipi_dsi_clk_init(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct device *dev = &pdev->dev;
+
+	mfd = platform_get_drvdata(pdev);
+
+	amp_pclk = clk_get(dev, "arb_clk");
+	if (IS_ERR_OR_NULL(amp_pclk)) {
+		pr_err("can't find amp_pclk\n");
+		amp_pclk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_m_pclk = clk_get(dev, "master_iface_clk");
+	if (IS_ERR_OR_NULL(dsi_m_pclk)) {
+		pr_err("can't find dsi_m_pclk\n");
+		dsi_m_pclk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_s_pclk = clk_get(dev, "slave_iface_clk");
+	if (IS_ERR_OR_NULL(dsi_s_pclk)) {
+		pr_err("can't find dsi_s_pclk\n");
+		dsi_s_pclk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_byte_div_clk = clk_get(dev, "byte_clk");
+	if (IS_ERR(dsi_byte_div_clk)) {
+		pr_err("can't find dsi_byte_div_clk\n");
+		dsi_byte_div_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_esc_clk = clk_get(dev, "esc_clk");
+	if (IS_ERR(dsi_esc_clk)) {
+		printk(KERN_ERR "can't find dsi_esc_clk\n");
+		dsi_esc_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	return 0;
+
+mipi_dsi_clk_err:
+	mipi_dsi_clk_deinit(dev);
+	return -EPERM;
+}
+
+void mipi_dsi_clk_deinit(struct device *dev)
+{
+	if (amp_pclk)
+		clk_put(amp_pclk);
+	if (amp_pclk)
+		clk_put(dsi_m_pclk);
+	if (dsi_s_pclk)
+		clk_put(dsi_s_pclk);
+	if (dsi_byte_div_clk)
+		clk_put(dsi_byte_div_clk);
+	if (dsi_esc_clk)
+		clk_put(dsi_esc_clk);
+}
+
+static void mipi_dsi_clk_ctrl(struct dsi_clk_desc *clk, int clk_en)
+{
+	char	*cc, *ns, *md;
+	int	pmxo_sel = 0;
+	char	mnd_en = 1, root_en = 1;
+	uint32	data, val;
+
+	cc = mmss_cc_base + 0x004c;
+	md = mmss_cc_base + 0x0050;
+	ns = mmss_cc_base + 0x0054;
+
+	if (clk_en) {
+		if (clk->mnd_mode == 0) {
+			data  = clk->pre_div_func << 14;
+			data |= clk->src;
+			MIPI_OUTP_SECURE(ns, data);
+			MIPI_OUTP_SECURE(cc, ((pmxo_sel << 8)
+						| (clk->mnd_mode << 6)
+						| (root_en << 2) | clk_en));
+		} else {
+			val = clk->d * 2;
+			data = (~val) & 0x0ff;
+			data |= clk->m << 8;
+			MIPI_OUTP_SECURE(md, data);
+
+			val = clk->n - clk->m;
+			data = (~val) & 0x0ff;
+			data <<= 24;
+			data |= clk->src;
+			MIPI_OUTP_SECURE(ns, data);
+
+			MIPI_OUTP_SECURE(cc, ((pmxo_sel << 8)
+					      | (clk->mnd_mode << 6)
+					      | (mnd_en << 5)
+					      | (root_en << 2) | clk_en));
+		}
+	} else
+		MIPI_OUTP_SECURE(cc, 0);
+
+	wmb();
+}
+
+static void mipi_dsi_sfpb_cfg(void)
+{
+	char *sfpb;
+	int data;
+
+	sfpb = mmss_sfpb_base + 0x058;
+
+	data = MIPI_INP(sfpb);
+	data |= 0x01800;
+	MIPI_OUTP(sfpb, data);
+	wmb();
+}
+
+static void mipi_dsi_pclk_ctrl(struct dsi_clk_desc *clk, int clk_en)
+{
+	char	*cc, *ns, *md;
+	char	mnd_en = 1, root_en = 1;
+	uint32	data, val;
+
+	cc = mmss_cc_base + 0x0130;
+	md = mmss_cc_base + 0x0134;
+	ns = mmss_cc_base + 0x0138;
+
+	if (clk_en) {
+		if (clk->mnd_mode == 0) {
+			data  = clk->pre_div_func << 12;
+			data |= clk->src;
+			MIPI_OUTP_SECURE(ns, data);
+			MIPI_OUTP_SECURE(cc, ((clk->mnd_mode << 6)
+					      | (root_en << 2) | clk_en));
+		} else {
+			val = clk->d * 2;
+			data = (~val) & 0x0ff;
+			data |= clk->m << 8;
+			MIPI_OUTP_SECURE(md, data);
+
+			val = clk->n - clk->m;
+			data = (~val) & 0x0ff;
+			data <<= 24;
+			data |= clk->src;
+			MIPI_OUTP_SECURE(ns, data);
+
+			MIPI_OUTP_SECURE(cc, ((clk->mnd_mode << 6)
+					      | (mnd_en << 5)
+					      | (root_en << 2) | clk_en));
+		}
+	} else
+		MIPI_OUTP_SECURE(cc, 0);
+
+	wmb();
+}
+
+static void mipi_dsi_ahb_en(void)
+{
+	char	*ahb;
+
+	ahb = mmss_cc_base + 0x08;
+
+	pr_debug("%s: ahb=%x %x\n",
+		__func__, (int) ahb, MIPI_INP_SECURE(ahb));
+}
+
+void mipi_dsi_lane_cfg(void)
+{
+	int i, ln_offset;
+
+	ln_offset = 0x300;
+	for (i = 0; i < 4; i++) {
+		/* DSI1_DSIPHY_LN_CFG0 */
+		MIPI_OUTP(MIPI_DSI_BASE + ln_offset, 0x80);
+		/* DSI1_DSIPHY_LN_CFG1 */
+		MIPI_OUTP(MIPI_DSI_BASE + ln_offset + 0x04, 0x45);
+		/* DSI1_DSIPHY_LN_CFG2 */
+		MIPI_OUTP(MIPI_DSI_BASE + ln_offset + 0x08, 0x0);
+		/* DSI1_DSIPHY_LN_TEST_DATAPATH */
+		MIPI_OUTP(MIPI_DSI_BASE + ln_offset + 0x0c, 0x0);
+		/* DSI1_DSIPHY_LN_TEST_STR0 */
+		MIPI_OUTP(MIPI_DSI_BASE + ln_offset + 0x14, 0x1);
+		/* DSI1_DSIPHY_LN_TEST_STR1 */
+		MIPI_OUTP(MIPI_DSI_BASE + ln_offset + 0x18, 0x66);
+		ln_offset += 0x40;
+	}
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0400, 0x40); /* DSI1_DSIPHY_LNCK_CFG0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0404, 0x67); /* DSI1_DSIPHY_LNCK_CFG1 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0408, 0x0); /* DSI1_DSIPHY_LNCK_CFG2 */
+	/* DSI1_DSIPHY_LNCK_TEST_DATAPATH */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x040c, 0x0);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0414, 0x1); /* DSI1_DSIPHY_LNCK_TEST_STR0 */
+	/* DSI1_DSIPHY_LNCK_TEST_STR1 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0418, 0x88);
+}
+
+void mipi_dsi_bist_ctrl(void)
+{
+	MIPI_OUTP(MIPI_DSI_BASE + 0x049c, 0x0f); /* DSI1_DSIPHY_BIST_CTRL4 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0490, 0x03); /* DSI1_DSIPHY_BIST_CTRL1 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x048c, 0x03); /* DSI1_DSIPHY_BIST_CTRL0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x049c, 0x0); /* DSI1_DSIPHY_BIST_CTRL4 */
+}
+
+static void mipi_dsi_calibration(void)
+{
+	int i = 0;
+	uint32 term_cnt = 5000;
+	int cal_busy = MIPI_INP(MIPI_DSI_BASE + 0x550);
+
+	/* DSI1_DSIPHY_REGULATOR_CAL_PWR_CFG */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0518, 0x03);
+
+	/* DSI1_DSIPHY_CAL_SW_CFG2 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0534, 0x0);
+	/* DSI1_DSIPHY_CAL_HW_CFG1 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x053c, 0x5a);
+	/* DSI1_DSIPHY_CAL_HW_CFG3 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0544, 0x10);
+	/* DSI1_DSIPHY_CAL_HW_CFG4 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0548, 0x01);
+	/* DSI1_DSIPHY_CAL_HW_CFG0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0538, 0x01);
+
+	/* DSI1_DSIPHY_CAL_HW_TRIGGER */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0528, 0x01);
+	usleep_range(5000, 5000);
+	/* DSI1_DSIPHY_CAL_HW_TRIGGER */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0528, 0x00);
+
+	cal_busy = MIPI_INP(MIPI_DSI_BASE + 0x550);
+	while (cal_busy & 0x10) {
+		i++;
+		if (i > term_cnt) {
+			pr_err("DSI1 PHY REGULATOR NOT READY,"
+				"exceeded polling TIMEOUT!\n");
+			break;
+		}
+		cal_busy = MIPI_INP(MIPI_DSI_BASE + 0x550);
+	}
+}
+
+void mipi_dsi_phy_rdy_poll(void)
+{
+	uint32 phy_pll_busy;
+	uint32 i = 0;
+	uint32 term_cnt = 0xFFFFFF;
+
+	phy_pll_busy = MIPI_INP(MIPI_DSI_BASE + 0x280);
+	while (!(phy_pll_busy & 0x1)) {
+		i++;
+		if (i > term_cnt) {
+			pr_err("DSI1 PHY NOT READY, exceeded polling TIMEOUT!\n");
+			break;
+		}
+		phy_pll_busy = MIPI_INP(MIPI_DSI_BASE + 0x280);
+	}
+}
+
+#define PREF_DIV_RATIO 27
+struct dsiphy_pll_divider_config pll_divider_config;
+
+int mipi_dsi_phy_pll_config(u32 clk_rate)
+{
+	struct dsiphy_pll_divider_config *dividers;
+	u32 fb_divider, tmp;
+	dividers = &pll_divider_config;
+
+	/* DSIPHY_PLL_CTRL_x:    1     2     3     8     9     10 */
+	/* masks               0xff  0x07  0x3f  0x0f  0xff  0xff */
+
+	/* DSIPHY_PLL_CTRL_1 */
+	fb_divider = ((dividers->fb_divider) / 2) - 1;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x204, fb_divider & 0xff);
+
+	/* DSIPHY_PLL_CTRL_2 */
+	tmp = MIPI_INP(MIPI_DSI_BASE + 0x208);
+	tmp &= ~0x07;
+	tmp |= (fb_divider >> 8) & 0x07;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x208, tmp);
+
+	/* DSIPHY_PLL_CTRL_3 */
+	tmp = MIPI_INP(MIPI_DSI_BASE + 0x20c);
+	tmp &= ~0x3f;
+	tmp |= (dividers->ref_divider_ratio - 1) & 0x3f;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x20c, tmp);
+
+	/* DSIPHY_PLL_CTRL_8 */
+	tmp = MIPI_INP(MIPI_DSI_BASE + 0x220);
+	tmp &= ~0x0f;
+	tmp |= (dividers->bit_clk_divider - 1) & 0x0f;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x220, tmp);
+
+	/* DSIPHY_PLL_CTRL_9 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x224, (dividers->byte_clk_divider - 1));
+
+	/* DSIPHY_PLL_CTRL_10 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x228, (dividers->dsi_clk_divider - 1));
+
+	return 0;
+}
+
+int mipi_dsi_clk_div_config(uint8 bpp, uint8 lanes,
+			    uint32 *expected_dsi_pclk)
+{
+	u32 fb_divider, rate, vco;
+	u32 div_ratio = 0;
+	struct dsi_clk_mnd_table const *mnd_entry = mnd_table;
+	if (pll_divider_config.clk_rate == 0)
+		pll_divider_config.clk_rate = 454000000;
+
+	rate = pll_divider_config.clk_rate / 1000000; /* In Mhz */
+
+	if (rate < 125) {
+		vco = rate * 8;
+		div_ratio = 8;
+	} else if (rate < 250) {
+		vco = rate * 4;
+		div_ratio = 4;
+	} else if (rate < 600) {
+		vco = rate * 2;
+		div_ratio = 2;
+	} else {
+		vco = rate * 1;
+		div_ratio = 1;
+	}
+
+	/* find the mnd settings from mnd_table entry */
+	for (; mnd_entry != mnd_table + ARRAY_SIZE(mnd_table); ++mnd_entry) {
+		if (((mnd_entry->lanes) == lanes) &&
+			((mnd_entry->bpp) == bpp))
+			break;
+	}
+
+	if (mnd_entry == mnd_table + ARRAY_SIZE(mnd_table)) {
+		pr_err("%s: requested Lanes, %u & BPP, %u, not supported\n",
+			__func__, lanes, bpp);
+		return -EINVAL;
+	}
+	fb_divider = ((vco * PREF_DIV_RATIO) / 27);
+	pll_divider_config.fb_divider = fb_divider;
+	pll_divider_config.ref_divider_ratio = PREF_DIV_RATIO;
+	pll_divider_config.bit_clk_divider = div_ratio;
+	pll_divider_config.byte_clk_divider =
+			pll_divider_config.bit_clk_divider * 8;
+	pll_divider_config.dsi_clk_divider =
+			(mnd_entry->dsiclk_div) * div_ratio;
+
+	if (mnd_entry->dsiclk_d == 0) {
+		dsicore_clk.mnd_mode = 0;
+		dsicore_clk.src = 0x3;
+		dsicore_clk.pre_div_func = (mnd_entry->dsiclk_n - 1);
+	} else {
+		dsicore_clk.mnd_mode = 2;
+		dsicore_clk.src = 0x3;
+		dsicore_clk.m = mnd_entry->dsiclk_m;
+		dsicore_clk.n = mnd_entry->dsiclk_n;
+		dsicore_clk.d = mnd_entry->dsiclk_d;
+	}
+
+	if ((mnd_entry->pclk_d == 0)
+		|| (mnd_entry->pclk_m == 1)) {
+		dsi_pclk.mnd_mode = 0;
+		dsi_pclk.src = 0x3;
+		dsi_pclk.pre_div_func = (mnd_entry->pclk_n - 1);
+		*expected_dsi_pclk = ((vco * 1000000) /
+					((pll_divider_config.dsi_clk_divider)
+					* (mnd_entry->pclk_n)));
+	} else {
+		dsi_pclk.mnd_mode = 2;
+		dsi_pclk.src = 0x3;
+		dsi_pclk.m = mnd_entry->pclk_m;
+		dsi_pclk.n = mnd_entry->pclk_n;
+		dsi_pclk.d = mnd_entry->pclk_d;
+		*expected_dsi_pclk = ((vco * 1000000 * dsi_pclk.m) /
+					((pll_divider_config.dsi_clk_divider)
+					* (mnd_entry->pclk_n)));
+	}
+	return 0;
+}
+
+static void mipi_dsi_configure_serdes(void)
+{
+	void __iomem *cc;
+
+	/* PHY registers programemd thru S2P interface */
+	if (periph_base) {
+		MIPI_OUTP(periph_base + 0x2c, 0x000000b6);
+		MIPI_OUTP(periph_base + 0x2c, 0x000001b5);
+		MIPI_OUTP(periph_base + 0x2c, 0x000001b4);
+		MIPI_OUTP(periph_base + 0x2c, 0x000003b3);
+		MIPI_OUTP(periph_base + 0x2c, 0x000003a2);
+		MIPI_OUTP(periph_base + 0x2c, 0x000002a1);
+		MIPI_OUTP(periph_base + 0x2c, 0x000008a0);
+		MIPI_OUTP(periph_base + 0x2c, 0x00000d9f);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000109e);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000209d);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000109c);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000079a);
+		MIPI_OUTP(periph_base + 0x2c, 0x00000c99);
+		MIPI_OUTP(periph_base + 0x2c, 0x00002298);
+		MIPI_OUTP(periph_base + 0x2c, 0x000000a7);
+		MIPI_OUTP(periph_base + 0x2c, 0x000000a6);
+		MIPI_OUTP(periph_base + 0x2c, 0x000000a5);
+		MIPI_OUTP(periph_base + 0x2c, 0x00007fa4);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000eea8);
+		MIPI_OUTP(periph_base + 0x2c, 0x000006aa);
+		MIPI_OUTP(periph_base + 0x2c, 0x00002095);
+		MIPI_OUTP(periph_base + 0x2c, 0x00000493);
+		MIPI_OUTP(periph_base + 0x2c, 0x00001092);
+		MIPI_OUTP(periph_base + 0x2c, 0x00000691);
+		MIPI_OUTP(periph_base + 0x2c, 0x00005490);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000038d);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000148c);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000058b);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000078a);
+		MIPI_OUTP(periph_base + 0x2c, 0x00001f89);
+		MIPI_OUTP(periph_base + 0x2c, 0x00003388);
+		MIPI_OUTP(periph_base + 0x2c, 0x00006387);
+		MIPI_OUTP(periph_base + 0x2c, 0x00004886);
+		MIPI_OUTP(periph_base + 0x2c, 0x00005085);
+		MIPI_OUTP(periph_base + 0x2c, 0x00000084);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000da83);
+		MIPI_OUTP(periph_base + 0x2c, 0x0000b182);
+		MIPI_OUTP(periph_base + 0x2c, 0x00002f81);
+		MIPI_OUTP(periph_base + 0x2c, 0x00004080);
+		MIPI_OUTP(periph_base + 0x2c, 0x00004180);
+		MIPI_OUTP(periph_base + 0x2c, 0x000006aa);
+	}
+
+	cc = MIPI_DSI_BASE + 0x0130;
+	MIPI_OUTP(cc, 0x806c11c8);
+	MIPI_OUTP(cc, 0x804c11c8);
+	MIPI_OUTP(cc, 0x806d0080);
+	MIPI_OUTP(cc, 0x804d0080);
+	MIPI_OUTP(cc, 0x00000000);
+	MIPI_OUTP(cc, 0x807b1597);
+	MIPI_OUTP(cc, 0x805b1597);
+	MIPI_OUTP(cc, 0x807c0080);
+	MIPI_OUTP(cc, 0x805c0080);
+	MIPI_OUTP(cc, 0x00000000);
+	MIPI_OUTP(cc, 0x807911c8);
+	MIPI_OUTP(cc, 0x805911c8);
+	MIPI_OUTP(cc, 0x807a0080);
+	MIPI_OUTP(cc, 0x805a0080);
+	MIPI_OUTP(cc, 0x00000000);
+	MIPI_OUTP(cc, 0x80721555);
+	MIPI_OUTP(cc, 0x80521555);
+	MIPI_OUTP(cc, 0x80730000);
+	MIPI_OUTP(cc, 0x80530000);
+	MIPI_OUTP(cc, 0x00000000);
+}
+
+void mipi_dsi_phy_init(int panel_ndx, struct msm_panel_info const *panel_info,
+	int target_type)
+{
+	struct mipi_dsi_phy_ctrl *pd;
+	int i, off;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0001);/* start phy sw reset */
+	wmb();
+	usleep(1);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0000);/* end phy w reset */
+	wmb();
+	usleep(1);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x500, 0x0003);/* regulator_ctrl_0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x504, 0x0001);/* regulator_ctrl_1 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x508, 0x0001);/* regulator_ctrl_2 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x50c, 0x0000);/* regulator_ctrl_3 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x510, 0x0100);/* regulator_ctrl_4 */
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x4b0, 0x04);/* DSIPHY_LDO_CNTRL */
+
+	pd = (panel_info->mipi).dsi_phy_db;
+
+	off = 0x0480;	/* strength 0 - 2 */
+	for (i = 0; i < 3; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->strength[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x0470;	/* ctrl 0 - 3 */
+	for (i = 0; i < 4; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->ctrl[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x0500;	/* regulator ctrl 0 - 4 */
+	for (i = 0; i < 5; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->regulator[i]);
+		wmb();
+		off += 4;
+	}
+	mipi_dsi_calibration();
+	mipi_dsi_lane_cfg(); /* lane cfgs */
+	mipi_dsi_bist_ctrl(); /* bist ctrl */
+
+	off = 0x0204;	/* pll ctrl 1 - 19, skip 0 */
+	for (i = 1; i < 20; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->pll[i]);
+		wmb();
+		off += 4;
+	}
+
+	if (panel_info)
+		mipi_dsi_phy_pll_config(panel_info->clk_rate);
+
+	/* pll ctrl 0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x200, pd->pll[0]);
+	wmb();
+
+	off = 0x0440;	/* phy timing ctrl 0 - 11 */
+	for (i = 0; i < 12; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->timing[i]);
+		wmb();
+		off += 4;
+	}
+
+	if (target_type == 1)
+		mipi_dsi_configure_serdes();
+}
+
+void cont_splash_clk_ctrl(int enable)
+{
+	static int cont_splash_clks_enabled;
+	if (enable && !cont_splash_clks_enabled) {
+			clk_prepare_enable(dsi_byte_div_clk);
+			clk_prepare_enable(dsi_esc_clk);
+			cont_splash_clks_enabled = 1;
+	} else if (!enable && cont_splash_clks_enabled) {
+			clk_disable_unprepare(dsi_byte_div_clk);
+			clk_disable_unprepare(dsi_esc_clk);
+			cont_splash_clks_enabled = 0;
+	}
+}
+
+void mipi_dsi_prepare_clocks(void)
+{
+	clk_prepare(amp_pclk);
+	clk_prepare(dsi_m_pclk);
+	clk_prepare(dsi_s_pclk);
+	clk_prepare(dsi_byte_div_clk);
+	clk_prepare(dsi_esc_clk);
+}
+
+void mipi_dsi_unprepare_clocks(void)
+{
+	clk_unprepare(dsi_esc_clk);
+	clk_unprepare(dsi_byte_div_clk);
+	clk_unprepare(dsi_m_pclk);
+	clk_unprepare(dsi_s_pclk);
+	clk_unprepare(amp_pclk);
+}
+
+void mipi_dsi_ahb_ctrl(u32 enable)
+{
+	static int ahb_ctrl_done;
+	if (enable) {
+		if (ahb_ctrl_done) {
+			pr_info("%s: ahb clks already ON\n", __func__);
+			return;
+		}
+		clk_enable(amp_pclk); /* clock for AHB-master to AXI */
+		clk_enable(dsi_m_pclk);
+		clk_enable(dsi_s_pclk);
+		mipi_dsi_ahb_en();
+		mipi_dsi_sfpb_cfg();
+		ahb_ctrl_done = 1;
+	} else {
+		if (ahb_ctrl_done == 0) {
+			pr_info("%s: ahb clks already OFF\n", __func__);
+			return;
+		}
+		clk_disable(dsi_m_pclk);
+		clk_disable(dsi_s_pclk);
+		clk_disable(amp_pclk); /* clock for AHB-master to AXI */
+		ahb_ctrl_done = 0;
+	}
+}
+
+void mipi_dsi_clk_enable(void)
+{
+	u32 pll_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0200);
+	if (mipi_dsi_clk_on) {
+		pr_info("%s: mipi_dsi_clks already ON\n", __func__);
+		return;
+	}
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pll_ctrl | 0x01);
+	mipi_dsi_phy_rdy_poll();
+
+	if (clk_set_rate(dsi_byte_div_clk, 1) < 0)	/* divided by 1 */
+		pr_err("%s: dsi_byte_div_clk - "
+			"clk_set_rate failed\n", __func__);
+	if (clk_set_rate(dsi_esc_clk, esc_byte_ratio) < 0) /* divided by esc */
+		pr_err("%s: dsi_esc_clk - "			 /* clk ratio */
+			"clk_set_rate failed\n", __func__);
+	mipi_dsi_pclk_ctrl(&dsi_pclk, 1);
+	mipi_dsi_clk_ctrl(&dsicore_clk, 1);
+	clk_enable(dsi_byte_div_clk);
+	clk_enable(dsi_esc_clk);
+	mipi_dsi_clk_on = 1;
+	mdp4_stat.dsi_clk_on++;
+}
+
+void mipi_dsi_clk_disable(void)
+{
+	if (mipi_dsi_clk_on == 0) {
+		pr_info("%s: mipi_dsi_clks already OFF\n", __func__);
+		return;
+	}
+	clk_disable(dsi_esc_clk);
+	clk_disable(dsi_byte_div_clk);
+	mipi_dsi_pclk_ctrl(&dsi_pclk, 0);
+	mipi_dsi_clk_ctrl(&dsicore_clk, 0);
+	/* DSIPHY_PLL_CTRL_0, disable dsi pll */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x0);
+	mipi_dsi_clk_on = 0;
+	mdp4_stat.dsi_clk_off++;
+}
+
+void mipi_dsi_phy_ctrl(int on)
+{
+	if (on) {
+		/* DSIPHY_PLL_CTRL_5 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0214, 0x050);
+	} else {
+		/* DSIPHY_PLL_CTRL_5 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0214, 0x05f);
+
+		/* DSIPHY_REGULATOR_CTRL_0 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0500, 0x02);
+
+		/* DSIPHY_CTRL_0 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0470, 0x00);
+
+		/* DSIPHY_CTRL_1 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0474, 0x7f);
+
+		/* disable dsi clk */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0118, 0);
+	}
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+void hdmi_phy_reset(void)
+{
+	unsigned int phy_reset_polarity = 0x0;
+	unsigned int pll_reset_polarity = 0x0;
+
+	unsigned int val = HDMI_INP_ND(HDMI_PHY_CTRL);
+
+	phy_reset_polarity = val >> 3 & 0x1;
+	pll_reset_polarity = val >> 1 & 0x1;
+
+	if (phy_reset_polarity == 0)
+		HDMI_OUTP(HDMI_PHY_CTRL, val | SW_RESET);
+	else
+		HDMI_OUTP(HDMI_PHY_CTRL, val & (~SW_RESET));
+
+	if (pll_reset_polarity == 0)
+		HDMI_OUTP(HDMI_PHY_CTRL, val | SW_RESET_PLL);
+	else
+		HDMI_OUTP(HDMI_PHY_CTRL, val & (~SW_RESET_PLL));
+
+	msleep(100);
+
+	if (phy_reset_polarity == 0)
+		HDMI_OUTP(HDMI_PHY_CTRL, val & (~SW_RESET));
+	else
+		HDMI_OUTP(HDMI_PHY_CTRL, val | SW_RESET);
+
+	if (pll_reset_polarity == 0)
+		HDMI_OUTP(HDMI_PHY_CTRL, val & (~SW_RESET_PLL));
+	else
+		HDMI_OUTP(HDMI_PHY_CTRL, val | SW_RESET_PLL);
+}
+
+void hdmi_msm_reset_core(void)
+{
+	hdmi_msm_clk(0);
+	udelay(5);
+	hdmi_msm_clk(1);
+}
+
+void hdmi_msm_init_phy(int video_format)
+{
+	uint32 offset;
+	pr_err("Video format is : %u\n", video_format);
+
+	HDMI_OUTP(HDMI_PHY_REG_0, 0x1B);
+	HDMI_OUTP(HDMI_PHY_REG_1, 0xf2);
+
+	offset = HDMI_PHY_REG_4;
+	while (offset <= HDMI_PHY_REG_11) {
+		HDMI_OUTP(offset, 0x0);
+		offset += 0x4;
+	}
+
+	HDMI_OUTP(HDMI_PHY_REG_3, 0x20);
+}
+
+void hdmi_msm_powerdown_phy(void)
+{
+	/* Power down PHY */
+	HDMI_OUTP_ND(HDMI_PHY_REG_2, 0x7F); /*0b01111111*/
+}
+
+void hdmi_frame_ctrl_cfg(const struct hdmi_disp_mode_timing_type *timing)
+{
+	/*  0x02C8 HDMI_FRAME_CTRL
+	 *  31 INTERLACED_EN   Interlaced or progressive enable bit
+	 *    0: Frame in progressive
+	 *    1: Frame is interlaced
+	 *  29 HSYNC_HDMI_POL  HSYNC polarity fed to HDMI core
+	 *     0: Active Hi Hsync, detect the rising edge of hsync
+	 *     1: Active lo Hsync, Detect the falling edge of Hsync
+	 *  28 VSYNC_HDMI_POL  VSYNC polarity fed to HDMI core
+	 *     0: Active Hi Vsync, detect the rising edge of vsync
+	 *     1: Active Lo Vsync, Detect the falling edge of Vsync
+	 *  12 RGB_MUX_SEL     ALPHA mdp4 input is RGB, mdp4 input is BGR
+	 */
+	HDMI_OUTP(0x02C8,
+		  ((timing->interlaced << 31) & 0x80000000)
+		| ((timing->active_low_h << 29) & 0x20000000)
+		| ((timing->active_low_v << 28) & 0x10000000));
+}
+
+void hdmi_msm_phy_status_poll(void)
+{
+	unsigned int lock_det, phy_ready;
+	lock_det = 0x1 & HDMI_INP_ND(HDMI_PHY_PLL_STATUS0);
+	if (lock_det) {
+		pr_debug("HDMI Phy PLL Lock Detect Bit is set\n");
+	} else {
+		pr_debug("HDMI Phy Lock Detect Bit is not set,"
+			 "waiting for lock detection\n");
+		do {
+			lock_det = 0x1 & \
+				HDMI_INP_ND(HDMI_PHY_PLL_STATUS0);
+		} while (!lock_det);
+	}
+
+	phy_ready = 0x1 & HDMI_INP_ND(HDMI_PHY_REG_15);
+	if (phy_ready) {
+		pr_debug("HDMI Phy Status bit is set and ready\n");
+	} else {
+		pr_debug("HDMI Phy Status bit is not set,"
+			"waiting for ready status\n");
+		do {
+			phy_ready = 0x1 & HDMI_INP_ND(HDMI_PHY_REG_15);
+		} while (!phy_ready);
+	}
+}
+
+#endif
diff --git a/drivers/video/msm/msm_dss_io_8x60.c b/drivers/video/msm/msm_dss_io_8x60.c
new file mode 100644
index 0000000..c79c4c7
--- /dev/null
+++ b/drivers/video/msm/msm_dss_io_8x60.c
@@ -0,0 +1,685 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/clk.h>
+#include <mach/clk.h>
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "hdmi_msm.h"
+#include <mach/msm_iomap.h>
+
+/* multimedia sub system clock control */
+char *mmss_cc_base = MSM_MMSS_CLK_CTL_BASE;
+/* multimedia sub system sfpb */
+char *mmss_sfpb_base;
+void  __iomem *periph_base;
+
+static struct dsi_clk_desc dsicore_clk;
+static struct dsi_clk_desc dsi_pclk;
+
+static struct clk *dsi_byte_div_clk;
+static struct clk *dsi_esc_clk;
+static struct clk *dsi_m_pclk;
+static struct clk *dsi_s_pclk;
+
+static struct clk *amp_pclk;
+int mipi_dsi_clk_on;
+
+int mipi_dsi_clk_init(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	amp_pclk = clk_get(dev, "arb_clk");
+	if (IS_ERR_OR_NULL(amp_pclk)) {
+		pr_err("can't find amp_pclk\n");
+		amp_pclk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_m_pclk = clk_get(dev, "master_iface_clk");
+	if (IS_ERR_OR_NULL(dsi_m_pclk)) {
+		pr_err("can't find dsi_m_pclk\n");
+		dsi_m_pclk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_s_pclk = clk_get(dev, "slave_iface_clk");
+	if (IS_ERR_OR_NULL(dsi_s_pclk)) {
+		pr_err("can't find dsi_s_pclk\n");
+		dsi_s_pclk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_byte_div_clk = clk_get(dev, "byte_clk");
+	if (IS_ERR_OR_NULL(dsi_byte_div_clk)) {
+		pr_err("can't find dsi_byte_div_clk\n");
+		dsi_byte_div_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_esc_clk = clk_get(dev, "esc_clk");
+	if (IS_ERR_OR_NULL(dsi_esc_clk)) {
+		printk(KERN_ERR "can't find dsi_esc_clk\n");
+		dsi_esc_clk = NULL;
+		goto mipi_dsi_clk_err;
+	}
+
+	return 0;
+
+mipi_dsi_clk_err:
+	mipi_dsi_clk_deinit(NULL);
+	return -EPERM;
+}
+
+void mipi_dsi_clk_deinit(struct device *dev)
+{
+	if (amp_pclk)
+		clk_put(amp_pclk);
+	if (dsi_m_pclk)
+		clk_put(dsi_m_pclk);
+	if (dsi_s_pclk)
+		clk_put(dsi_s_pclk);
+	if (dsi_byte_div_clk)
+		clk_put(dsi_byte_div_clk);
+	if (dsi_esc_clk)
+		clk_put(dsi_esc_clk);
+}
+
+static void mipi_dsi_clk_ctrl(struct dsi_clk_desc *clk, int clk_en)
+{
+	char	*cc, *ns, *md;
+	int	pmxo_sel = 0;
+	char	mnd_en = 1, root_en = 1;
+	uint32	data, val;
+
+	cc = mmss_cc_base + 0x004c;
+	md = mmss_cc_base + 0x0050;
+	ns = mmss_cc_base + 0x0054;
+
+	if (clk_en) {
+		if (clk->mnd_mode == 0) {
+			data  = clk->pre_div_func << 14;
+			data |= clk->src;
+			MIPI_OUTP_SECURE(ns, data);
+			MIPI_OUTP_SECURE(cc, ((pmxo_sel << 8)
+						| (clk->mnd_mode << 6)
+						| (root_en << 2) | clk_en));
+		} else {
+			val = clk->d * 2;
+			data = (~val) & 0x0ff;
+			data |= clk->m << 8;
+			MIPI_OUTP_SECURE(md, data);
+
+			val = clk->n - clk->m;
+			data = (~val) & 0x0ff;
+			data <<= 24;
+			data |= clk->src;
+			MIPI_OUTP_SECURE(ns, data);
+
+			MIPI_OUTP_SECURE(cc, ((pmxo_sel << 8)
+					      | (clk->mnd_mode << 6)
+					      | (mnd_en << 5)
+					      | (root_en << 2) | clk_en));
+		}
+
+	} else
+		MIPI_OUTP_SECURE(cc, 0);
+
+	wmb();
+}
+
+static void mipi_dsi_sfpb_cfg(void)
+{
+	char *sfpb;
+	int data;
+
+	sfpb = mmss_sfpb_base + 0x058;
+
+	data = MIPI_INP(sfpb);
+	data |= 0x01800;
+	MIPI_OUTP(sfpb, data);
+	wmb();
+}
+
+static void mipi_dsi_pclk_ctrl(struct dsi_clk_desc *clk, int clk_en)
+{
+	char	*cc, *ns, *md;
+	char	mnd_en = 1, root_en = 1;
+	uint32	data, val;
+
+	cc = mmss_cc_base + 0x0130;
+	md = mmss_cc_base + 0x0134;
+	ns = mmss_cc_base + 0x0138;
+
+	if (clk_en) {
+		if (clk->mnd_mode == 0) {
+			data  = clk->pre_div_func << 12;
+			data |= clk->src;
+			MIPI_OUTP_SECURE(ns, data);
+			MIPI_OUTP_SECURE(cc, ((clk->mnd_mode << 6)
+					      | (root_en << 2) | clk_en));
+		} else {
+			val = clk->d * 2;
+			data = (~val) & 0x0ff;
+			data |= clk->m << 8;
+			MIPI_OUTP_SECURE(md, data);
+
+			val = clk->n - clk->m;
+			data = (~val) & 0x0ff;
+			data <<= 24;
+			data |= clk->src;
+			MIPI_OUTP_SECURE(ns, data);
+
+			MIPI_OUTP_SECURE(cc, ((clk->mnd_mode << 6)
+					      | (mnd_en << 5)
+					      | (root_en << 2) | clk_en));
+		}
+
+	} else
+		MIPI_OUTP_SECURE(cc, 0);
+
+	wmb();
+}
+
+static void mipi_dsi_ahb_en(void)
+{
+	char	*ahb;
+
+	ahb = mmss_cc_base + 0x08;
+
+	pr_debug("%s: ahb=%x %x\n",
+		__func__, (int) ahb, MIPI_INP_SECURE(ahb));
+}
+
+static void mipi_dsi_calibration(void)
+{
+	uint32 data;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0xf4, 0x0000ff11); /* cal_ctrl */
+	MIPI_OUTP(MIPI_DSI_BASE + 0xf0, 0x01); /* cal_hw_trigger */
+
+	while (1) {
+		data = MIPI_INP(MIPI_DSI_BASE + 0xfc); /* cal_status */
+		if ((data & 0x10000000) == 0)
+			break;
+
+		udelay(10);
+	}
+}
+
+#define PREF_DIV_RATIO 27
+struct dsiphy_pll_divider_config pll_divider_config;
+
+
+int mipi_dsi_phy_pll_config(u32 clk_rate)
+{
+	struct dsiphy_pll_divider_config *dividers;
+	u32 fb_divider, tmp;
+	dividers = &pll_divider_config;
+
+	/* DSIPHY_PLL_CTRL_x:    1     2     3     8     9     10 */
+	/* masks               0xff  0x07  0x3f  0x0f  0xff  0xff */
+
+	/* DSIPHY_PLL_CTRL_1 */
+	fb_divider = ((dividers->fb_divider) / 2) - 1;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x204, fb_divider & 0xff);
+
+	/* DSIPHY_PLL_CTRL_2 */
+	tmp = MIPI_INP(MIPI_DSI_BASE + 0x208);
+	tmp &= ~0x07;
+	tmp |= (fb_divider >> 8) & 0x07;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x208, tmp);
+
+	/* DSIPHY_PLL_CTRL_3 */
+	tmp = MIPI_INP(MIPI_DSI_BASE + 0x20c);
+	tmp &= ~0x3f;
+	tmp |= (dividers->ref_divider_ratio - 1) & 0x3f;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x20c, tmp);
+
+	/* DSIPHY_PLL_CTRL_8 */
+	tmp = MIPI_INP(MIPI_DSI_BASE + 0x220);
+	tmp &= ~0x0f;
+	tmp |= (dividers->bit_clk_divider - 1) & 0x0f;
+	MIPI_OUTP(MIPI_DSI_BASE + 0x220, tmp);
+
+	/* DSIPHY_PLL_CTRL_9 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x224, (dividers->byte_clk_divider - 1));
+
+	/* DSIPHY_PLL_CTRL_10 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x228, (dividers->dsi_clk_divider - 1));
+
+	return 0;
+}
+
+int mipi_dsi_clk_div_config(uint8 bpp, uint8 lanes,
+			    uint32 *expected_dsi_pclk)
+{
+	u32 fb_divider, rate, vco;
+	u32 div_ratio = 0;
+	struct dsi_clk_mnd_table const *mnd_entry = mnd_table;
+	if (pll_divider_config.clk_rate == 0)
+		pll_divider_config.clk_rate = 454000000;
+
+	rate = pll_divider_config.clk_rate / 1000000; /* In Mhz */
+
+	if (rate < 125) {
+		vco = rate * 8;
+		div_ratio = 8;
+	} else if (rate < 250) {
+		vco = rate * 4;
+		div_ratio = 4;
+	} else if (rate < 500) {
+		vco = rate * 2;
+		div_ratio = 2;
+	} else {
+		vco = rate * 1;
+		div_ratio = 1;
+	}
+
+	/* find the mnd settings from mnd_table entry */
+	for (; mnd_entry != mnd_table + ARRAY_SIZE(mnd_table); ++mnd_entry) {
+		if (((mnd_entry->lanes) == lanes) &&
+			((mnd_entry->bpp) == bpp))
+			break;
+	}
+
+	if (mnd_entry == mnd_table + ARRAY_SIZE(mnd_table)) {
+		pr_err("%s: requested Lanes, %u & BPP, %u, not supported\n",
+			__func__, lanes, bpp);
+		return -EINVAL;
+	}
+	fb_divider = ((vco * PREF_DIV_RATIO) / 27);
+	pll_divider_config.fb_divider = fb_divider;
+	pll_divider_config.ref_divider_ratio = PREF_DIV_RATIO;
+	pll_divider_config.bit_clk_divider = div_ratio;
+	pll_divider_config.byte_clk_divider =
+			pll_divider_config.bit_clk_divider * 8;
+	pll_divider_config.dsi_clk_divider =
+			(mnd_entry->dsiclk_div) * div_ratio;
+
+	if ((mnd_entry->dsiclk_d == 0)
+		|| (mnd_entry->dsiclk_m == 1)) {
+		dsicore_clk.mnd_mode = 0;
+		dsicore_clk.src = 0x3;
+		dsicore_clk.pre_div_func = (mnd_entry->dsiclk_n - 1);
+	} else {
+		dsicore_clk.mnd_mode = 2;
+		dsicore_clk.src = 0x3;
+		dsicore_clk.m = mnd_entry->dsiclk_m;
+		dsicore_clk.n = mnd_entry->dsiclk_n;
+		dsicore_clk.d = mnd_entry->dsiclk_d;
+	}
+
+	if ((mnd_entry->pclk_d == 0)
+		|| (mnd_entry->pclk_m == 1)) {
+		dsi_pclk.mnd_mode = 0;
+		dsi_pclk.src = 0x3;
+		dsi_pclk.pre_div_func = (mnd_entry->pclk_n - 1);
+		*expected_dsi_pclk = ((vco * 1000000) /
+					((pll_divider_config.dsi_clk_divider)
+					* (mnd_entry->pclk_n)));
+	} else {
+		dsi_pclk.mnd_mode = 2;
+		dsi_pclk.src = 0x3;
+		dsi_pclk.m = mnd_entry->pclk_m;
+		dsi_pclk.n = mnd_entry->pclk_n;
+		dsi_pclk.d = mnd_entry->pclk_d;
+		*expected_dsi_pclk = ((vco * 1000000 * dsi_pclk.m) /
+					((pll_divider_config.dsi_clk_divider)
+					* (mnd_entry->pclk_n)));
+	}
+	return 0;
+}
+
+void mipi_dsi_phy_init(int panel_ndx, struct msm_panel_info const *panel_info,
+	int target_type)
+{
+	struct mipi_dsi_phy_ctrl *pd;
+	int i, off;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0001);/* start phy sw reset */
+	wmb();
+	usleep(1);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0000);/* end phy w reset */
+	wmb();
+	usleep(1);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2cc, 0x0003);/* regulator_ctrl_0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2d0, 0x0001);/* regulator_ctrl_1 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2d4, 0x0001);/* regulator_ctrl_2 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2d8, 0x0000);/* regulator_ctrl_3 */
+#ifdef DSI_POWER
+	MIPI_OUTP(MIPI_DSI_BASE + 0x2dc, 0x0100);/* regulator_ctrl_4 */
+#endif
+
+	pd = (panel_info->mipi).dsi_phy_db;
+
+	off = 0x02cc;	/* regulator ctrl 0 */
+	for (i = 0; i < 4; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->regulator[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x0260;	/* phy timig ctrl 0 */
+	for (i = 0; i < 11; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->timing[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x0290;	/* ctrl 0 */
+	for (i = 0; i < 4; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->ctrl[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x02a0;	/* strength 0 */
+	for (i = 0; i < 4; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->strength[i]);
+		wmb();
+		off += 4;
+	}
+
+	mipi_dsi_calibration();
+
+	off = 0x0204;	/* pll ctrl 1, skip 0 */
+	for (i = 1; i < 21; i++) {
+		MIPI_OUTP(MIPI_DSI_BASE + off, pd->pll[i]);
+		wmb();
+		off += 4;
+	}
+
+	if (panel_info)
+		mipi_dsi_phy_pll_config(panel_info->clk_rate);
+
+	/* pll ctrl 0 */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x200, pd->pll[0]);
+	wmb();
+}
+
+void cont_splash_clk_ctrl(int enable)
+{
+}
+
+void mipi_dsi_prepare_clocks(void)
+{
+	clk_prepare(amp_pclk);
+	clk_prepare(dsi_m_pclk);
+	clk_prepare(dsi_s_pclk);
+	clk_prepare(dsi_byte_div_clk);
+	clk_prepare(dsi_esc_clk);
+}
+
+void mipi_dsi_unprepare_clocks(void)
+{
+	clk_unprepare(dsi_esc_clk);
+	clk_unprepare(dsi_byte_div_clk);
+	clk_unprepare(dsi_m_pclk);
+	clk_unprepare(dsi_s_pclk);
+	clk_unprepare(amp_pclk);
+}
+
+void mipi_dsi_ahb_ctrl(u32 enable)
+{
+	static int ahb_ctrl_done;
+	if (enable) {
+		if (ahb_ctrl_done) {
+			pr_info("%s: ahb clks already ON\n", __func__);
+			return;
+		}
+		clk_enable(amp_pclk); /* clock for AHB-master to AXI */
+		clk_enable(dsi_m_pclk);
+		clk_enable(dsi_s_pclk);
+		mipi_dsi_ahb_en();
+		mipi_dsi_sfpb_cfg();
+		ahb_ctrl_done = 1;
+	} else {
+		if (ahb_ctrl_done == 0) {
+			pr_info("%s: ahb clks already OFF\n", __func__);
+			return;
+		}
+		clk_disable(dsi_m_pclk);
+		clk_disable(dsi_s_pclk);
+		clk_disable(amp_pclk); /* clock for AHB-master to AXI */
+		ahb_ctrl_done = 0;
+	}
+}
+
+void mipi_dsi_clk_enable(void)
+{
+	u32 pll_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0200);
+	if (mipi_dsi_clk_on) {
+		pr_info("%s: mipi_dsi_clks already ON\n", __func__);
+		return;
+	}
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pll_ctrl | 0x01);
+	mb();
+
+	if (clk_set_rate(dsi_byte_div_clk, 1) < 0)	/* divided by 1 */
+		pr_err("%s: clk_set_rate failed\n",	__func__);
+	mipi_dsi_pclk_ctrl(&dsi_pclk, 1);
+	mipi_dsi_clk_ctrl(&dsicore_clk, 1);
+	clk_enable(dsi_byte_div_clk);
+	clk_enable(dsi_esc_clk);
+	mipi_dsi_clk_on = 1;
+}
+
+void mipi_dsi_clk_disable(void)
+{
+	if (mipi_dsi_clk_on == 0) {
+		pr_info("%s: mipi_dsi_clks already OFF\n", __func__);
+		return;
+	}
+	clk_disable(dsi_esc_clk);
+	clk_disable(dsi_byte_div_clk);
+
+	mipi_dsi_pclk_ctrl(&dsi_pclk, 0);
+	mipi_dsi_clk_ctrl(&dsicore_clk, 0);
+	/* DSIPHY_PLL_CTRL_0, disable dsi pll */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x40);
+	mipi_dsi_clk_on = 0;
+}
+
+void mipi_dsi_phy_ctrl(int on)
+{
+	if (on) {
+		/* DSIPHY_PLL_CTRL_5 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0214, 0x050);
+
+		/* DSIPHY_TPA_CTRL_1 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0258, 0x00f);
+
+		/* DSIPHY_TPA_CTRL_2 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x025c, 0x000);
+	} else {
+		/* DSIPHY_PLL_CTRL_5 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0214, 0x05f);
+
+		/* DSIPHY_TPA_CTRL_1 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0258, 0x08f);
+
+		/* DSIPHY_TPA_CTRL_2 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x025c, 0x001);
+
+		/* DSIPHY_REGULATOR_CTRL_0 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x02cc, 0x02);
+
+		/* DSIPHY_CTRL_0 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0290, 0x00);
+
+		/* DSIPHY_CTRL_1 */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0294, 0x7f);
+
+		/* disable dsi clk */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0118, 0);
+	}
+}
+
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+#define SW_RESET BIT(2)
+void hdmi_phy_reset(void)
+{
+	unsigned int phy_reset_polarity = 0x0;
+	unsigned int val = HDMI_INP_ND(0x2D4);
+
+	phy_reset_polarity = val >> 3 & 0x1;
+
+	if (phy_reset_polarity == 0)
+		HDMI_OUTP(0x2D4, val | SW_RESET);
+	else
+		HDMI_OUTP(0x2D4, val & (~SW_RESET));
+
+	msleep(100);
+
+	if (phy_reset_polarity == 0)
+		HDMI_OUTP(0x2D4, val & (~SW_RESET));
+	else
+		HDMI_OUTP(0x2D4, val | SW_RESET);
+}
+
+void hdmi_msm_reset_core(void)
+{
+	hdmi_msm_clk(0);
+	udelay(5);
+	hdmi_msm_clk(1);
+
+	clk_reset(hdmi_msm_state->hdmi_app_clk, CLK_RESET_ASSERT);
+	udelay(20);
+	clk_reset(hdmi_msm_state->hdmi_app_clk, CLK_RESET_DEASSERT);
+}
+
+void hdmi_msm_init_phy(int video_format)
+{
+	uint32 offset;
+	/* De-serializer delay D/C for non-lbk mode
+	 * PHY REG0 = (DESER_SEL(0) | DESER_DEL_CTRL(3)
+	 * | AMUX_OUT_SEL(0))
+	 */
+	HDMI_OUTP_ND(0x0300, 0x0C); /*0b00001100*/
+
+	if (video_format == HDMI_VFRMT_720x480p60_16_9) {
+		/* PHY REG1 = DTEST_MUX_SEL(5) | PLL_GAIN_SEL(0)
+		 * | OUTVOL_SWING_CTRL(3)
+		 */
+		HDMI_OUTP_ND(0x0304, 0x53); /*0b01010011*/
+	} else {
+		/* If the freq. is less than 120MHz, use low gain 0
+		 * for board with termination
+		 * PHY REG1 = DTEST_MUX_SEL(5) | PLL_GAIN_SEL(0)
+		 * | OUTVOL_SWING_CTRL(4)
+		 */
+		HDMI_OUTP_ND(0x0304, 0x54); /*0b01010100*/
+	}
+
+	/* No matter what, start from the power down mode
+	 * PHY REG2 = PD_PWRGEN | PD_PLL | PD_DRIVE_4 | PD_DRIVE_3
+	 * | PD_DRIVE_2 | PD_DRIVE_1 | PD_DESER
+	 */
+	HDMI_OUTP_ND(0x0308, 0x7F); /*0b01111111*/
+
+	/* Turn PowerGen on
+	 * PHY REG2 = PD_PLL | PD_DRIVE_4 | PD_DRIVE_3
+	 * | PD_DRIVE_2 | PD_DRIVE_1 | PD_DESER
+	 */
+	HDMI_OUTP_ND(0x0308, 0x3F); /*0b00111111*/
+
+	/* Turn PLL power on
+	 * PHY REG2 = PD_DRIVE_4 | PD_DRIVE_3
+	 * | PD_DRIVE_2 | PD_DRIVE_1 | PD_DESER
+	 */
+	HDMI_OUTP_ND(0x0308, 0x1F); /*0b00011111*/
+
+	/* Write to HIGH after PLL power down de-assert
+	 * PHY REG3 = PLL_ENABLE
+	 */
+	HDMI_OUTP_ND(0x030C, 0x01);
+	/* ASIC power on; PHY REG9 = 0 */
+	HDMI_OUTP_ND(0x0324, 0x00);
+	/* Enable PLL lock detect, PLL lock det will go high after lock
+	 * Enable the re-time logic
+	 * PHY REG12 = PLL_LOCK_DETECT_EN | RETIMING_ENABLE
+	 */
+	HDMI_OUTP_ND(0x0330, 0x03); /*0b00000011*/
+
+	/* Drivers are on
+	 * PHY REG2 = PD_DESER
+	 */
+	HDMI_OUTP_ND(0x0308, 0x01); /*0b00000001*/
+	/* If the RX detector is needed
+	 * PHY REG2 = RCV_SENSE_EN | PD_DESER
+	 */
+	HDMI_OUTP_ND(0x0308, 0x81); /*0b10000001*/
+
+	offset = 0x0310;
+	while (offset <= 0x032C) {
+		HDMI_OUTP(offset, 0x0);
+		offset += 0x4;
+	}
+
+	/* If we want to use lock enable based on counting
+	 * PHY REG12 = FORCE_LOCK | PLL_LOCK_DETECT_EN | RETIMING_ENABLE
+	 */
+	HDMI_OUTP_ND(0x0330, 0x13); /*0b00010011*/
+}
+
+void hdmi_msm_powerdown_phy(void)
+{
+	/* Assert RESET PHY from controller */
+	HDMI_OUTP_ND(0x02D4, 0x4);
+	udelay(10);
+	/* De-assert RESET PHY from controller */
+	HDMI_OUTP_ND(0x02D4, 0x0);
+	/* Turn off Driver */
+	HDMI_OUTP_ND(0x0308, 0x1F);
+	udelay(10);
+	/* Disable PLL */
+	HDMI_OUTP_ND(0x030C, 0x00);
+	/* Power down PHY */
+	HDMI_OUTP_ND(0x0308, 0x7F); /*0b01111111*/
+}
+
+void hdmi_frame_ctrl_cfg(const struct hdmi_disp_mode_timing_type *timing)
+{
+	/*  0x02C8 HDMI_FRAME_CTRL
+	 *  31 INTERLACED_EN   Interlaced or progressive enable bit
+	 *    0: Frame in progressive
+	 *    1: Frame is interlaced
+	 *  29 HSYNC_HDMI_POL  HSYNC polarity fed to HDMI core
+	 *     0: Active Hi Hsync, detect the rising edge of hsync
+	 *     1: Active lo Hsync, Detect the falling edge of Hsync
+	 *  28 VSYNC_HDMI_POL  VSYNC polarity fed to HDMI core
+	 *     0: Active Hi Vsync, detect the rising edge of vsync
+	 *     1: Active Lo Vsync, Detect the falling edge of Vsync
+	 *  12 RGB_MUX_SEL     ALPHA mdp4 input is RGB, mdp4 input is BGR
+	 */
+	HDMI_OUTP(0x02C8,
+		  ((timing->interlaced << 31) & 0x80000000)
+		| ((timing->active_low_h << 29) & 0x20000000)
+		| ((timing->active_low_v << 28) & 0x10000000)
+		| (1 << 12));
+}
+
+void hdmi_msm_phy_status_poll(void)
+{
+	unsigned int phy_ready;
+	phy_ready = 0x1 & HDMI_INP_ND(0x33c);
+	if (phy_ready) {
+		pr_debug("HDMI Phy Status bit is set and ready\n");
+	} else {
+		pr_debug("HDMI Phy Status bit is not set,"
+			"waiting for ready status\n");
+		do {
+			phy_ready = 0x1 & HDMI_INP_ND(0x33c);
+		} while (!phy_ready);
+	}
+}
+#endif
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 1056dc0..773b9bf 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -3,6 +3,7 @@
  * Core MSM framebuffer driver.
  *
  * Copyright (C) 2007 Google Incorporated
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -14,466 +15,235 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/platform_device.h>
 #include <linux/module.h>
-#include <linux/fb.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
-
-#include <linux/freezer.h>
-#include <linux/wait.h>
-#include <linux/wakelock.h>
-#include <linux/earlysuspend.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
 #include <linux/msm_mdp.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <mach/msm_fb.h>
-#include <mach/board.h>
-#include <linux/workqueue.h>
-#include <linux/clk.h>
-#include <linux/debugfs.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <mach/board.h>
+#include <linux/uaccess.h>
+
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <linux/debugfs.h>
+#include <linux/console.h>
 #include <linux/android_pmem.h>
-#include <mach/debug_display.h>
-#include "mdp_hw.h"
-#ifdef CONFIG_MSM_MDP40
+#include <linux/leds.h>
+#include <linux/pm_runtime.h>
+
+#define MSM_FB_C
+#include "msm_fb.h"
+#include "mddihosti.h"
+#include "tvenc.h"
+#include "mdp.h"
 #include "mdp4.h"
+
+#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
+#define MSM_FB_NUM	3
 #endif
 
-static void msmfb_resume_handler(struct early_suspend *h);
-static void msmfb_resume(struct msmfb_info *msmfb);
+static unsigned char *fbram;
+static unsigned char *fbram_phys;
+static int fbram_size;
+static boolean bf_supported;
 
-#define MSMFB_DEBUG 1
-#ifdef CONFIG_FB_MSM_LOGO
-#define INIT_IMAGE_FILE "/logo.rle"
-#endif
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
 
-#define PRINT_FPS 0
-#define PRINT_BLIT_TIME 0
+int vsync_mode = 1;
 
-#define SLEEPING 0x4
-#define UPDATING 0x3
-#define FULL_UPDATE_DONE 0x2
-#define WAKING 0x1
-#define AWAKE 0x0
+#define MAX_BLIT_REQ 256
 
-#define NONE 0
-#define SUSPEND_RESUME 0x1
-#define FPS 0x2
-#define BLIT_TIME 0x4
-#define SHOW_UPDATES 0x8
+#define MAX_FBI_LIST 32
+static struct fb_info *fbi_list[MAX_FBI_LIST];
+static int fbi_list_index;
 
-#define DLOG(mask, fmt, args...) \
-do { \
-	if ((msmfb_debug_mask | SUSPEND_RESUME) & mask) \
-		PR_DISP_INFO("msmfb: "fmt, ##args); \
-} while (0)
-#define BITS_PER_PIXEL(info) (info->fb->var.bits_per_pixel)
-#define BYTES_PER_PIXEL(info) (info->fb->var.bits_per_pixel >> 3)
-static int msmfb_debug_mask;
-module_param_named(msmfb_debug_mask, msmfb_debug_mask, int,
-		   S_IRUGO | S_IWUSR | S_IWGRP);
+static struct msm_fb_data_type *mfd_list[MAX_FBI_LIST];
+static int mfd_list_index;
 
-#if defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)
-#define NUM_ALLOC 3
-static void *virt_addr[NUM_ALLOC] = { NULL };
-static void *phys_addr[NUM_ALLOC] = { NULL };
-static struct msmfb_usb_projector_info usb_pjt_info = {0, 0};
-char *get_fb_addr(void)
+static u32 msm_fb_pseudo_palette[16] = {
+	0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
+};
+
+static struct ion_client *iclient;
+
+u32 msm_fb_debug_enabled;
+/* Setting msm_fb_msg_level to 8 prints out ALL messages */
+u32 msm_fb_msg_level = 7;
+
+/* Setting mddi_msg_level to 8 prints out ALL messages */
+u32 mddi_msg_level = 5;
+
+extern int32 mdp_block_power_cnt[MDP_MAX_BLOCK];
+extern unsigned long mdp_timer_duration;
+
+static int msm_fb_register(struct msm_fb_data_type *mfd);
+static int msm_fb_open(struct fb_info *info, int user);
+static int msm_fb_release(struct fb_info *info, int user);
+static int msm_fb_pan_display(struct fb_var_screeninfo *var,
+			      struct fb_info *info);
+static int msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd);
+int msm_fb_resume_sw_refresher(struct msm_fb_data_type *mfd);
+static int msm_fb_check_var(struct fb_var_screeninfo *var,
+			    struct fb_info *info);
+static int msm_fb_set_par(struct fb_info *info);
+static int msm_fb_blank_sub(int blank_mode, struct fb_info *info,
+			    boolean op_enable);
+static int msm_fb_suspend_sub(struct msm_fb_data_type *mfd);
+static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd,
+			unsigned long arg);
+static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma);
+static int mdp_bl_scale_config(struct msm_fb_data_type *mfd,
+						struct mdp_bl_scale_data *data);
+static void msm_fb_scale_bl(__u32 *bl_lvl);
+
+#ifdef MSM_FB_ENABLE_DBGFS
+
+#define MSM_FB_MAX_DBGFS 1024
+#define MAX_BACKLIGHT_BRIGHTNESS 255
+
+int msm_fb_debugfs_file_index;
+struct dentry *msm_fb_debugfs_root;
+struct dentry *msm_fb_debugfs_file[MSM_FB_MAX_DBGFS];
+static int bl_scale, bl_min_lvl;
+
+DEFINE_MUTEX(msm_fb_notify_update_sem);
+void msmfb_no_update_notify_timer_cb(unsigned long data)
 {
-	int i;
-
-	if (!usb_pjt_info.latest_offset)
-		return 0;
-
-	usb_pjt_info.usb_offset = usb_pjt_info.latest_offset;
-
-	for (i=0; i<NUM_ALLOC; i++)
-		if (phys_addr[i] == (void *)usb_pjt_info.usb_offset)
-			return virt_addr[i];
-
-	printk(KERN_ERR "%s: <FATAL> Impossible to be here.\n", __func__);
-	return 0;
-}
-#endif
-
-struct mdp_device *mdp;
-#ifdef CONFIG_FB_MSM_OVERLAY
-static atomic_t mdpclk_on = ATOMIC_INIT(1);
-#endif
-
-DECLARE_MUTEX(ov_semaphore);
-static DEFINE_MUTEX(overlay_ioctl_mutex);
-
-#if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR))
-static DEFINE_SPINLOCK(fb_data_lock);
-static struct msm_fb_info msm_fb_data;
-int msmfb_get_var(struct msm_fb_info *tmp)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&fb_data_lock, flags);
-	memcpy(tmp, &msm_fb_data, sizeof(msm_fb_data));
-	spin_unlock_irqrestore(&fb_data_lock, flags);
-	return 0;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
+	if (!mfd)
+		pr_err("%s mfd NULL\n", __func__);
+	complete(&mfd->msmfb_no_update_notify);
 }
 
-/* projector need this, and very much */
-int msmfb_get_fb_area(void)
+struct dentry *msm_fb_get_debugfs_root(void)
 {
-	int area;
-	unsigned long flags;
-	spin_lock_irqsave(&fb_data_lock, flags);
-	area = msm_fb_data.msmfb_area;
-	spin_unlock_irqrestore(&fb_data_lock, flags);
-	return area;
-}
-#endif
+	if (msm_fb_debugfs_root == NULL)
+		msm_fb_debugfs_root = debugfs_create_dir("msm_fb", NULL);
 
-static int msmfb_open(struct fb_info *info, int user)
-{
-	return 0;
+	return msm_fb_debugfs_root;
 }
 
-static int msmfb_release(struct fb_info *info, int user)
+void msm_fb_debugfs_file_create(struct dentry *root, const char *name,
+				u32 *var)
 {
-	return 0;
-}
-
-int overlay_semaphore_lock(void)
-{
-	static struct task_struct last_owner_task = {0};
-	static int fail_counter = 0;
-	int err = down_timeout(&ov_semaphore, msecs_to_jiffies(1000));
-
-	if (!err) {
-		/* Got the ownership for this semaphore, record who own it...
-		 * Then reset the fail ccounter...
-		 */
-		last_owner_task.pid = current->pid;
-		last_owner_task.tgid = current->tgid;
-		strncpy(last_owner_task.comm, current->comm, (TASK_COMM_LEN-1));
-		fail_counter = 0;
-	} else {
-		/* Fail to get the ownership for this semaphore... */
-		if ((fail_counter%10) == 0) {
-			PR_DISP_WARN("Semaphore own by [%s](%d, %d), [%s](%d, %d) "
-				"want to own it(err=%d)...\n",
-				last_owner_task.comm, last_owner_task.pid,
-				last_owner_task.tgid, current->comm,
-				current->pid, current->tgid, err);
-			dump_stack();
-		}
-		fail_counter++;
-	}
-
-	return err;
-}
-
-void overlay_semaphore_unlock(void)
-{
-	up(&ov_semaphore);
-}
-
-/* Called from dma interrupt handler, must not sleep */
-static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
-{
-	unsigned long irq_flags = 0;
-	struct msmfb_info *msmfb  = container_of(callback, struct msmfb_info,
-					       dma_callback);
-#if PRINT_FPS
-	int64_t dt;
-	ktime_t now;
-	static int64_t frame_count;
-	static ktime_t last_sec;
-#endif
-
-	overlay_semaphore_unlock();
-	spin_lock_irqsave(&msmfb->update_lock, irq_flags);
-	msmfb->frame_done = msmfb->frame_requested;
-	if (msmfb->sleeping == UPDATING &&
-	    msmfb->frame_done == msmfb->update_frame) {
-		DLOG(SUSPEND_RESUME, "full update completed\n");
-		queue_work(msmfb->resume_workqueue, &msmfb->resume_work);
-	}
-#if PRINT_FPS
-	now = ktime_get();
-	dt = ktime_to_ns(ktime_sub(now, last_sec));
-	frame_count++;
-	if (dt > NSEC_PER_SEC) {
-		int64_t fps = frame_count * NSEC_PER_SEC * 100;
-		frame_count = 0;
-		last_sec = ktime_get();
-		do_div(fps, dt);
-		DLOG(FPS, "fps * 100: %llu\n", fps);
-	}
-#endif
-	spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-	wake_up(&msmfb->frame_wq);
-}
-
-static int msmfb_start_dma(struct msmfb_info *msmfb)
-{
-	uint32_t x, y, w, h;
-	unsigned addr;
-	unsigned long irq_flags = 0;
-	uint32_t yoffset;
-	s64 time_since_request;
-	struct msm_panel_data *panel = msmfb->panel;
-
-	spin_lock_irqsave(&msmfb->update_lock, irq_flags);
-	time_since_request = ktime_to_ns(ktime_sub(ktime_get(),
-			     msmfb->vsync_request_time));
-	if (time_since_request > 20 * NSEC_PER_MSEC) {
-		uint32_t us;
-		us = do_div(time_since_request, NSEC_PER_MSEC) / NSEC_PER_USEC;
-		PR_DISP_WARN("msmfb_start_dma %lld.%03u ms after vsync "
-			"request\n", time_since_request, us);
-	}
-	if (msmfb->frame_done == msmfb->frame_requested) {
-		spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-		overlay_semaphore_unlock();
-		return -1;
-	}
-	if (msmfb->sleeping == SLEEPING) {
-		DLOG(SUSPEND_RESUME, "tried to start dma while asleep\n");
-		spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-		overlay_semaphore_unlock();
-		return -1;
-	}
-	x = msmfb->update_info.left;
-	y = msmfb->update_info.top;
-	w = msmfb->update_info.eright - x;
-	h = msmfb->update_info.ebottom - y;
-	yoffset = msmfb->yoffset;
-	msmfb->update_info.left = msmfb->xres + 1;
-	msmfb->update_info.top = msmfb->yres + 1;
-	msmfb->update_info.eright = 0;
-	msmfb->update_info.ebottom = 0;
-	if (unlikely(w > msmfb->xres || h > msmfb->yres ||
-		     w == 0 || h == 0)) {
-		PR_DISP_INFO("invalid update: %d %d %d "
-				"%d\n", x, y, w, h);
-		msmfb->frame_done = msmfb->frame_requested;
-		goto error;
-	}
-	spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-
-	addr = ((ALIGN(msmfb->xres, 32) * (yoffset + y) + x) * BYTES_PER_PIXEL(msmfb));
-	mdp->dma(mdp, addr + msmfb->fb->fix.smem_start,
-		 msmfb->xres * BYTES_PER_PIXEL(msmfb), w, h, x, y,
-		 &msmfb->dma_callback,
-		 panel->interface_type);
-	return 0;
-error:
-	spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-	/* some clients need to clear their vsync interrupt */
-	if (panel->clear_vsync)
-		panel->clear_vsync(panel);
-	overlay_semaphore_unlock();
-	wake_up(&msmfb->frame_wq);
-	return 0;
-}
-
-/* Called from esync interrupt handler, must not sleep */
-static void msmfb_handle_vsync_interrupt(struct msmfb_callback *callback)
-{
-	struct msmfb_info *msmfb = container_of(callback, struct msmfb_info,
-					       vsync_callback);
-	wake_unlock(&msmfb->idle_lock);
-	msmfb_start_dma(msmfb);
-}
-
-static enum hrtimer_restart msmfb_fake_vsync(struct hrtimer *timer)
-{
-	struct msmfb_info *msmfb  = container_of(timer, struct msmfb_info,
-					       fake_vsync);
-	msmfb_start_dma(msmfb);
-	return HRTIMER_NORESTART;
-}
-
-static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top,
-			     uint32_t eright, uint32_t ebottom,
-			     uint32_t yoffset, int pan_display)
-{
-	struct msmfb_info *msmfb = info->par;
-	struct msm_panel_data *panel = msmfb->panel;
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	struct mdp_lcdc_info *lcdc = panel_to_lcdc(panel);
-#endif
-	unsigned long irq_flags = 0;
-	int sleeping;
-	int retry = 1;
-#if PRINT_FPS
-	ktime_t t1, t2;
-	static uint64_t pans;
-	static uint64_t dt;
-	t1 = ktime_get();
-#endif
-	DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n",
-		left, top, eright, ebottom, yoffset, pan_display);
-
-	if (msmfb->sleeping != AWAKE)
-		DLOG(SUSPEND_RESUME, "pan_update in state(%d)\n", msmfb->sleeping);
-
-#ifdef CONFIG_PANEL_SELF_REFRESH
-	if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
-		spin_lock_irqsave(&panel_icm->lock, irq_flags);
-		panel_icm->panel_update = 1;
-		spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
-		wake_up(&panel_update_wait_queue);
-	}
-#endif
-
-restart:
-	spin_lock_irqsave(&msmfb->update_lock, irq_flags);
-
-	/* if we are sleeping, on a pan_display wait 10ms (to throttle back
-	 * drawing otherwise return */
-	if (msmfb->sleeping == SLEEPING) {
-		DLOG(SUSPEND_RESUME, "drawing while asleep\n");
-		spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-		if (pan_display)
-			wait_event_interruptible_timeout(msmfb->frame_wq,
-				msmfb->sleeping != SLEEPING, HZ/10);
+	if (msm_fb_debugfs_file_index >= MSM_FB_MAX_DBGFS)
 		return;
-	}
 
-	sleeping = msmfb->sleeping;
-	/* on a full update, if the last frame has not completed, wait for it */
-	if (pan_display && (msmfb->frame_requested != msmfb->frame_done ||
-			    sleeping == UPDATING)) {
-		int ret;
-		spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-		/* Shorten delay time when apply vsync recover mechanism*/
-		if (panel->recover_vsync) {
-			ret = wait_event_interruptible_timeout(msmfb->frame_wq,
-				msmfb->frame_done == msmfb->frame_requested &&
-				msmfb->sleeping != UPDATING, HZ/3);
+	msm_fb_debugfs_file[msm_fb_debugfs_file_index++] =
+	    debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
+}
+#endif
+
+int msm_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	if (!mfd->cursor_update)
+		return -ENODEV;
+
+	return mfd->cursor_update(info, cursor);
+}
+
+static int msm_fb_resource_initialized;
+
+#ifndef CONFIG_FB_BACKLIGHT
+static int lcd_backlight_registered;
+
+static void msm_fb_set_bl_brightness(struct led_classdev *led_cdev,
+					enum led_brightness value)
+{
+	struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent);
+	int bl_lvl;
+
+	if (value > MAX_BACKLIGHT_BRIGHTNESS)
+		value = MAX_BACKLIGHT_BRIGHTNESS;
+
+	/* This maps android backlight level 0 to 255 into
+	   driver backlight level 0 to bl_max with rounding */
+	bl_lvl = (2 * value * mfd->panel_info.bl_max + MAX_BACKLIGHT_BRIGHTNESS)
+		/(2 * MAX_BACKLIGHT_BRIGHTNESS);
+
+	if (!bl_lvl && value)
+		bl_lvl = 1;
+
+	msm_fb_set_backlight(mfd, bl_lvl);
+}
+
+static struct led_classdev backlight_led = {
+	.name		= "lcd-backlight",
+	.brightness	= MAX_BACKLIGHT_BRIGHTNESS,
+	.brightness_set	= msm_fb_set_bl_brightness,
+};
+#endif
+
+static struct msm_fb_platform_data *msm_fb_pdata;
+unsigned char hdmi_prim_display;
+
+int msm_fb_detect_client(const char *name)
+{
+	int ret = 0;
+	u32 len;
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	u32 id;
+#endif
+	if (!msm_fb_pdata)
+		return -EPERM;
+
+	len = strnlen(name, PANEL_NAME_MAX_LEN);
+	if (strnlen(msm_fb_pdata->prim_panel_name, PANEL_NAME_MAX_LEN)) {
+		pr_err("\n name = %s, prim_display = %s",
+			name, msm_fb_pdata->prim_panel_name);
+		if (!strncmp((char *)msm_fb_pdata->prim_panel_name,
+			name, len)) {
+			if (!strncmp((char *)msm_fb_pdata->prim_panel_name,
+				"hdmi_msm", len))
+				hdmi_prim_display = 1;
+			return 0;
 		} else {
-			ret = wait_event_interruptible_timeout(msmfb->frame_wq,
-				msmfb->frame_done == msmfb->frame_requested &&
-				msmfb->sleeping != UPDATING, 5 * HZ);
-		}
-
-		if (ret <= 0 && (msmfb->frame_requested != msmfb->frame_done ||
-				 msmfb->sleeping == UPDATING)) {
-			if (retry && panel->request_vsync &&
-			    (sleeping == AWAKE)) {
-				wake_lock_timeout(&msmfb->idle_lock, HZ/4);
-				panel->request_vsync(panel,
-					&msmfb->vsync_callback);
-				retry = 0;
-				/* FIXME */
-				if (panel->recover_vsync)
-					panel->recover_vsync(panel);
-				PR_DISP_WARN("msmfb_pan_display timeout "
-					"rerequest vsync\n");
-			} else {
-				PR_DISP_WARN("msmfb_pan_display timeout "
-					"waiting for frame start, %d %d\n",
-					msmfb->frame_requested,
-					msmfb->frame_done);
-				return;
-			}
-		}
-		goto restart;
-	}
-
-#if PRINT_FPS
-	t2 = ktime_get();
-	if (pan_display) {
-		uint64_t temp = ktime_to_ns(ktime_sub(t2, t1));
-		do_div(temp, 1000);
-		dt += temp;
-		pans++;
-		if (pans > 1000) {
-			do_div(dt, pans);
-			DLOG(FPS, "ave_wait_time: %lld\n", dt);
-			dt = 0;
-			pans = 0;
+			ret = -EPERM;
 		}
 	}
+
+	if (strnlen(msm_fb_pdata->ext_panel_name, PANEL_NAME_MAX_LEN)) {
+		pr_err("\n name = %s, ext_display = %s",
+			name, msm_fb_pdata->ext_panel_name);
+		if (!strncmp((char *)msm_fb_pdata->ext_panel_name, name, len))
+			return 0;
+		else
+			ret = -EPERM;
+	}
+
+	if (ret)
+		return ret;
+
+	ret = -EPERM;
+	if (msm_fb_pdata && msm_fb_pdata->detect_client) {
+		ret = msm_fb_pdata->detect_client(name);
+
+		/* if it's non mddi panel, we need to pre-scan
+		   mddi client to see if we can disable mddi host */
+
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+		if (!ret && msm_fb_pdata->mddi_prescan)
+			id = mddi_get_client_id();
 #endif
-
-	msmfb->frame_requested++;
-	/* if necessary, update the y offset, if this is the
-	 * first full update on resume, set the sleeping state */
-	if (pan_display) {
-		msmfb->yoffset = yoffset;
-		if (left == 0 && top == 0 && eright == info->var.xres &&
-		    ebottom == info->var.yres) {
-			if (sleeping == WAKING) {
-				msmfb->update_frame = msmfb->frame_requested;
-				DLOG(SUSPEND_RESUME, "full update starting\n");
-				msmfb->sleeping = UPDATING;
-			}
-		}
 	}
 
-	/* set the update request */
-	if (left < msmfb->update_info.left)
-		msmfb->update_info.left = left;
-	if (top < msmfb->update_info.top)
-		msmfb->update_info.top = top;
-	if (eright > msmfb->update_info.eright)
-		msmfb->update_info.eright = eright;
-	if (ebottom > msmfb->update_info.ebottom)
-		msmfb->update_info.ebottom = ebottom;
-	DLOG(SHOW_UPDATES, "update queued %d %d %d %d %d\n",
-		msmfb->update_info.left, msmfb->update_info.top,
-		msmfb->update_info.eright, msmfb->update_info.ebottom,
-		msmfb->yoffset);
-	spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-
-	/* if the panel is all the way on wait for vsync, otherwise sleep
-	 * for 16 ms (long enough for the dma to panel) and then begin dma */
-	overlay_semaphore_lock();
-	msmfb->vsync_request_time = ktime_get();
-
-#ifdef CONFIG_MDP4_HW_VSYNC
-	msmfb_start_dma(msmfb);
-#else
-	if (panel->request_vsync && (sleeping == AWAKE)) {
-		wake_lock_timeout(&msmfb->idle_lock, HZ/4);
-		panel->request_vsync(panel, &msmfb->vsync_callback);
-	} else {
-		if (!hrtimer_active(&msmfb->fake_vsync)) {
-			hrtimer_start(&msmfb->fake_vsync,
-				      ktime_set(0, NSEC_PER_SEC/60),
-				      HRTIMER_MODE_REL);
-		}
-	}
-#endif
-}
-
-static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top,
-			 uint32_t eright, uint32_t ebottom)
-{
-	msmfb_pan_update(info, left, top, eright, ebottom, 0, 0);
-}
-
-static void power_on_panel(struct work_struct *work)
-{
-	struct msmfb_info *msmfb =
-		container_of(work, struct msmfb_info, resume_work);
-	struct msm_panel_data *panel = msmfb->panel;
-	unsigned long irq_flags = 0;
-	mutex_lock(&msmfb->panel_init_lock);
-	DLOG(SUSPEND_RESUME, "turning on panel\n");
-	if (msmfb->sleeping == UPDATING) {
-		wake_lock_timeout(&msmfb->idle_lock, HZ);
-		if (panel->unblank && panel->unblank(panel)) {
-			PR_DISP_INFO("msmfb: panel unblank failed,"
-			       "not starting drawing\n");
-			goto error;
-		}
-		wake_unlock(&msmfb->idle_lock);
-		spin_lock_irqsave(&msmfb->update_lock, irq_flags);
-		msmfb->sleeping = AWAKE;
-		wake_up(&msmfb->frame_wq);
-		spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-	}
-error:
-	mutex_unlock(&msmfb->panel_init_lock);
+	return ret;
 }
 
 static BLOCKING_NOTIFIER_HEAD(display_chain_head);
@@ -482,267 +252,2523 @@
 	return blocking_notifier_chain_register(&display_chain_head, nb);
 }
 
-static int display_notifier_callback(struct notifier_block *nfb,
-		unsigned long action, void *ignored)
+static ssize_t msm_fb_msm_fb_type(struct device *dev,
+				  struct device_attribute *attr, char *buf)
 {
-	switch (action) {
-	case NOTIFY_MSM_FB:
-		PR_DISP_DEBUG("NOTIFY_MSM_FB\n");
+	ssize_t ret = 0;
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+	struct msm_fb_panel_data *pdata =
+		(struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
+	switch (pdata->panel_info.type) {
+	case NO_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "no panel\n");
 		break;
-	case NOTIFY_POWER:
-		/* nothing to do */
+	case MDDI_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "mddi panel\n");
+		break;
+	case EBI2_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "ebi2 panel\n");
+		break;
+	case LCDC_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "lcdc panel\n");
+		break;
+	case EXT_MDDI_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "ext mddi panel\n");
+		break;
+	case TV_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "tv panel\n");
+		break;
+	case HDMI_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "hdmi panel\n");
+		break;
+	case DTV_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "dtv panel\n");
+		break;
+	case MIPI_VIDEO_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "mipi dsi video panel\n");
+		break;
+	case MIPI_CMD_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "mipi dsi cmd panel\n");
+		break;
+	case WRITEBACK_PANEL:
+		ret = snprintf(buf, PAGE_SIZE, "writeback panel\n");
 		break;
 	default:
-		PR_DISP_ERR("%s: unknown action in 0x%lx\n",
-				__func__, action);
-		return NOTIFY_BAD;
+		ret = snprintf(buf, PAGE_SIZE, "unknown panel\n");
+		break;
 	}
-	return NOTIFY_OK;
+
+	return ret;
 }
 
-/* -------------------------------------------------------------------------- */
-#ifdef CONFIG_HAS_EARLYSUSPEND
-/* turn off the panel */
-static void msmfb_earlier_suspend(struct early_suspend *h)
+static DEVICE_ATTR(msm_fb_type, S_IRUGO, msm_fb_msm_fb_type, NULL);
+static struct attribute *msm_fb_attrs[] = {
+	&dev_attr_msm_fb_type.attr,
+	NULL,
+};
+static struct attribute_group msm_fb_attr_group = {
+	.attrs = msm_fb_attrs,
+};
+
+static int msm_fb_create_sysfs(struct platform_device *pdev)
 {
-	struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
-						earlier_suspend);
-	struct msm_panel_data *panel = msmfb->panel;
-	unsigned long irq_flags = 0;
-	mutex_lock(&msmfb->panel_init_lock);
-	msmfb->sleeping = SLEEPING;
-	wake_up(&msmfb->frame_wq);
-	spin_lock_irqsave(&msmfb->update_lock, irq_flags);
-	spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-	wait_event_timeout(msmfb->frame_wq,
-			   msmfb->frame_requested == msmfb->frame_done, HZ/10);
-#ifndef CONFIG_MSM_MDP40
-	mdp->dma(mdp, virt_to_phys(msmfb->black), 0,
-		 msmfb->fb->var.xres, msmfb->fb->var.yres, 0, 0,
-		 NULL, panel->interface_type);
-	mdp->dma_wait(mdp, panel->interface_type);
-#endif
-	/* turn off the panel */
-	panel->blank(panel);
+	int rc;
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+
+	rc = sysfs_create_group(&mfd->fbi->dev->kobj, &msm_fb_attr_group);
+	if (rc)
+		MSM_FB_ERR("%s: sysfs group creation failed, rc=%d\n", __func__,
+			rc);
+	return rc;
+}
+static void msm_fb_remove_sysfs(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+	sysfs_remove_group(&mfd->fbi->dev->kobj, &msm_fb_attr_group);
 }
 
-static void msmfb_suspend(struct early_suspend *h)
+static int msm_fb_probe(struct platform_device *pdev)
 {
-	struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
-						early_suspend);
-	struct msm_panel_data *panel = msmfb->panel;
-	/* suspend the panel */
-	PR_DISP_INFO("%s", __func__);
-#ifdef CONFIG_FB_MSM_OVERLAY
-	atomic_set(&mdpclk_on, 0);
-#endif
-	panel->suspend(panel);
-	msmfb->fb_resumed = 0;
-	mutex_unlock(&msmfb->panel_init_lock);
-}
+	struct msm_fb_data_type *mfd;
+	int rc;
+	int err = 0;
 
-static void msmfb_resume_handler(struct early_suspend *h)
-{
-	struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
-					early_suspend);
-#ifdef CONFIG_HTC_ONMODE_CHARGING
-	if (msmfb->fb_resumed == 1) {
-		DLOG(SUSPEND_RESUME, "fb is resumed by onchg. skip resume\n");
-		return;
+	MSM_FB_DEBUG("msm_fb_probe\n");
+
+	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
+		msm_fb_pdata = pdev->dev.platform_data;
+		fbram_size =
+			pdev->resource[0].end - pdev->resource[0].start + 1;
+		fbram_phys = (char *)pdev->resource[0].start;
+		fbram = __va(fbram_phys);
+
+		if (!fbram) {
+			printk(KERN_ERR "fbram ioremap failed!\n");
+			return -ENOMEM;
+		}
+		MSM_FB_DEBUG("msm_fb_probe:  phy_Addr = 0x%x virt = 0x%x\n",
+			     (int)fbram_phys, (int)fbram);
+
+		iclient = msm_ion_client_create(-1, pdev->name);
+		if (IS_ERR_OR_NULL(iclient)) {
+			pr_err("msm_ion_client_create() return"
+				" error, val %p\n", iclient);
+			iclient = NULL;
+		}
+
+		msm_fb_resource_initialized = 1;
+		return 0;
 	}
-#endif
-	msmfb_resume(msmfb);
-}
 
-#ifdef CONFIG_HTC_ONMODE_CHARGING
-static void msmfb_onchg_earlier_suspend(struct early_suspend *h)
-{
-	struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
-						onchg_earlier_suspend);
-	struct msm_panel_data *panel = msmfb->panel;
-	unsigned long irq_flags = 0;
+	if (!msm_fb_resource_initialized)
+		return -EPERM;
 
-	mutex_lock(&msmfb->panel_init_lock);
-	msmfb->sleeping = SLEEPING;
-	wake_up(&msmfb->frame_wq);
-	spin_lock_irqsave(&msmfb->update_lock, irq_flags);
-	spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-	wait_event_timeout(msmfb->frame_wq,
-			   msmfb->frame_requested == msmfb->frame_done, HZ/10);
-#ifndef CONFIG_MSM_MDP40
-	mdp->dma(mdp, virt_to_phys(msmfb->black), 0,
-		 msmfb->fb->var.xres, msmfb->fb->var.yres, 0, 0,
-		 NULL, panel->interface_type);
-	mdp->dma_wait(mdp, panel->interface_type);
-#endif
-	/* turn off the panel */
-	panel->blank(panel);
-}
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
 
-static void msmfb_onchg_suspend(struct early_suspend *h)
-{
-	struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
-						onchg_suspend);
-	struct msm_panel_data *panel = msmfb->panel;
-	/* suspend the panel */
-#ifdef CONFIG_FB_MSM_OVERLAY
-	atomic_set(&mdpclk_on, 0);
-#endif
-	panel->suspend(panel);
-	msmfb->fb_resumed = 0;
-	mutex_unlock(&msmfb->panel_init_lock);
-}
+	if (!mfd)
+		return -ENODEV;
 
-static void msmfb_onchg_resume_handler(struct early_suspend *h)
-{
-	struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
-					onchg_suspend);
-	msmfb_resume(msmfb);
-}
-#endif
-
-static void msmfb_resume(struct msmfb_info *msmfb)
-{
-	struct msm_panel_data *panel = msmfb->panel;
-	unsigned long irq_flags = 0;
-	if (panel->resume(panel)) {
-		PR_DISP_INFO("msmfb: panel resume failed, not resuming "
-		       "fb\n");
-		return;
-	}
-	spin_lock_irqsave(&msmfb->update_lock, irq_flags);
-	msmfb->frame_requested = msmfb->frame_done = msmfb->update_frame = 0;
-	msmfb->sleeping = WAKING;
-	DLOG(SUSPEND_RESUME, "ready, waiting for full update\n");
-	spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-	msmfb->fb_resumed = 1;
-
-#ifdef CONFIG_FB_MSM_OVERLAY
-	atomic_set(&mdpclk_on, 1);
-#endif
-}
-#endif
-
-static int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	u32 size;
-
-	if ((var->xres != info->var.xres) ||
-	    (var->yres != info->var.yres) ||
-	    (var->xoffset != info->var.xoffset) ||
-	    (mdp->check_output_format(mdp, var->bits_per_pixel)) ||
-	    (var->grayscale != info->var.grayscale))
-		 return -EINVAL;
-
-	size = var->xres_virtual * var->yres_virtual *
-		(var->bits_per_pixel >> 3);
-	if (size > info->fix.smem_len)
+	if (mfd->key != MFD_KEY)
 		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	vsync_cntrl.dev = mfd->fbi->dev;
+	mfd->panel_info.frame_count = 0;
+	mfd->bl_level = 0;
+	bl_scale = 1024;
+	bl_min_lvl = 255;
+#ifdef CONFIG_FB_MSM_OVERLAY
+	mfd->overlay_play_enable = 1;
+#endif
+
+	bf_supported = mdp4_overlay_borderfill_supported();
+
+	rc = msm_fb_register(mfd);
+	if (rc)
+		return rc;
+	err = pm_runtime_set_active(mfd->fbi->dev);
+	if (err < 0)
+		printk(KERN_ERR "pm_runtime: fail to set active.\n");
+	pm_runtime_enable(mfd->fbi->dev);
+#ifdef CONFIG_FB_BACKLIGHT
+	msm_fb_config_backlight(mfd);
+#else
+	/* android supports only one lcd-backlight/lcd for now */
+	if (!lcd_backlight_registered) {
+		if (led_classdev_register(&pdev->dev, &backlight_led))
+			printk(KERN_ERR "led_classdev_register failed\n");
+		else
+			lcd_backlight_registered = 1;
+	}
+#endif
+
+	pdev_list[pdev_list_cnt++] = pdev;
+	msm_fb_create_sysfs(pdev);
 	return 0;
 }
 
-static int msmfb_set_par(struct fb_info *info)
+static int msm_fb_remove(struct platform_device *pdev)
 {
-	struct fb_var_screeninfo *var = &info->var;
-	struct fb_fix_screeninfo *fix = &info->fix;
+	struct msm_fb_data_type *mfd;
 
-	/* we only support RGB ordering for now */
-	if (var->bits_per_pixel == 32 || var->bits_per_pixel == 24) {
-		var->red.offset = 0;
-		var->red.length = 8;
-		var->green.offset = 8;
-		var->green.length = 8;
-		var->blue.offset = 16;
-		var->blue.length = 8;
-	} else if (var->bits_per_pixel == 16) {
-		var->red.offset = 11;
-		var->red.length = 5;
-		var->green.offset = 5;
-		var->green.length = 6;
+	MSM_FB_DEBUG("msm_fb_remove\n");
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	msm_fb_remove_sysfs(pdev);
+
+	pm_runtime_disable(mfd->fbi->dev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (msm_fb_suspend_sub(mfd))
+		printk(KERN_ERR "msm_fb_remove: can't stop the device %d\n", mfd->index);
+
+	if (mfd->channel_irq != 0)
+		free_irq(mfd->channel_irq, (void *)mfd);
+
+	if (mfd->vsync_width_boundary)
+		vfree(mfd->vsync_width_boundary);
+
+	if (mfd->vsync_resync_timer.function)
+		del_timer(&mfd->vsync_resync_timer);
+
+	if (mfd->refresh_timer.function)
+		del_timer(&mfd->refresh_timer);
+
+	if (mfd->dma_hrtimer.function)
+		hrtimer_cancel(&mfd->dma_hrtimer);
+
+	if (mfd->msmfb_no_update_notify_timer.function)
+		del_timer(&mfd->msmfb_no_update_notify_timer);
+	complete(&mfd->msmfb_no_update_notify);
+	complete(&mfd->msmfb_update_notify);
+
+	/* remove /dev/fb* */
+	unregister_framebuffer(mfd->fbi);
+
+#ifdef CONFIG_FB_BACKLIGHT
+	/* remove /sys/class/backlight */
+	backlight_device_unregister(mfd->fbi->bl_dev);
+#else
+	if (lcd_backlight_registered) {
+		lcd_backlight_registered = 0;
+		led_classdev_unregister(&backlight_led);
+	}
+#endif
+
+#ifdef MSM_FB_ENABLE_DBGFS
+	if (mfd->sub_dir)
+		debugfs_remove(mfd->sub_dir);
+#endif
+
+	return 0;
+}
+
+#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
+static int msm_fb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct msm_fb_data_type *mfd;
+	int ret = 0;
+
+	MSM_FB_DEBUG("msm_fb_suspend\n");
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if ((!mfd) || (mfd->key != MFD_KEY))
+		return 0;
+
+	console_lock();
+	fb_set_suspend(mfd->fbi, FBINFO_STATE_SUSPENDED);
+
+	ret = msm_fb_suspend_sub(mfd);
+	if (ret != 0) {
+		printk(KERN_ERR "msm_fb: failed to suspend! %d\n", ret);
+		fb_set_suspend(mfd->fbi, FBINFO_STATE_RUNNING);
+	} else {
+		pdev->dev.power.power_state = state;
+	}
+
+	console_unlock();
+	return ret;
+}
+#else
+#define msm_fb_suspend NULL
+#endif
+
+static int msm_fb_suspend_sub(struct msm_fb_data_type *mfd)
+{
+	int ret = 0;
+
+	if ((!mfd) || (mfd->key != MFD_KEY))
+		return 0;
+
+	if (mfd->msmfb_no_update_notify_timer.function)
+		del_timer(&mfd->msmfb_no_update_notify_timer);
+	complete(&mfd->msmfb_no_update_notify);
+
+	/*
+	 * suspend this channel
+	 */
+	mfd->suspend.sw_refreshing_enable = mfd->sw_refreshing_enable;
+	mfd->suspend.op_enable = mfd->op_enable;
+	mfd->suspend.panel_power_on = mfd->panel_power_on;
+
+	if (mfd->op_enable) {
+		ret =
+		     msm_fb_blank_sub(FB_BLANK_POWERDOWN, mfd->fbi,
+				      mfd->suspend.op_enable);
+		if (ret) {
+			MSM_FB_INFO
+			    ("msm_fb_suspend: can't turn off display!\n");
+			return ret;
+		}
+		mfd->op_enable = FALSE;
+	}
+	/*
+	 * try to power down
+	 */
+	mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	/*
+	 * detach display channel irq if there's any
+	 * or wait until vsync-resync completes
+	 */
+	if ((mfd->dest == DISPLAY_LCD)) {
+		if (mfd->panel_info.lcd.vsync_enable) {
+			if (mfd->panel_info.lcd.hw_vsync_mode) {
+				if (mfd->channel_irq != 0)
+					disable_irq(mfd->channel_irq);
+			} else {
+				volatile boolean vh_pending;
+				do {
+					vh_pending = mfd->vsync_handler_pending;
+				} while (vh_pending);
+			}
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int msm_fb_resume_sub(struct msm_fb_data_type *mfd)
+{
+	int ret = 0;
+	struct msm_fb_panel_data *pdata = NULL;
+
+	if ((!mfd) || (mfd->key != MFD_KEY))
+		return 0;
+
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
+	/* attach display channel irq if there's any */
+	if (mfd->channel_irq != 0)
+		enable_irq(mfd->channel_irq);
+
+	/* resume state var recover */
+	mfd->sw_refreshing_enable = mfd->suspend.sw_refreshing_enable;
+	mfd->op_enable = mfd->suspend.op_enable;
+
+	if (mfd->suspend.panel_power_on) {
+		ret =
+		     msm_fb_blank_sub(FB_BLANK_UNBLANK, mfd->fbi,
+				      mfd->op_enable);
+		if (ret)
+			MSM_FB_INFO("msm_fb_resume: can't turn on display!\n");
+	}
+
+	return ret;
+}
+#endif
+
+#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
+static int msm_fb_resume(struct platform_device *pdev)
+{
+	/* This resume function is called when interrupt is enabled.
+	 */
+	int ret = 0;
+	struct msm_fb_data_type *mfd;
+
+	MSM_FB_DEBUG("msm_fb_resume\n");
+
+	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+
+	if ((!mfd) || (mfd->key != MFD_KEY))
+		return 0;
+
+	console_lock();
+	ret = msm_fb_resume_sub(mfd);
+	pdev->dev.power.power_state = PMSG_ON;
+	fb_set_suspend(mfd->fbi, FBINFO_STATE_RUNNING);
+	console_unlock();
+
+	return ret;
+}
+#else
+#define msm_fb_resume NULL
+#endif
+
+static int msm_fb_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int msm_fb_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+
+static int msm_fb_runtime_idle(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: idling...\n");
+	return 0;
+}
+
+#if (defined(CONFIG_SUSPEND) && defined(CONFIG_FB_MSM_HDMI_MSM_PANEL))
+static int msm_fb_ext_suspend(struct device *dev)
+{
+	struct msm_fb_data_type *mfd = dev_get_drvdata(dev);
+	struct msm_fb_panel_data *pdata = NULL;
+	int ret = 0;
+
+	if ((!mfd) || (mfd->key != MFD_KEY))
+		return 0;
+
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+	if (mfd->panel_info.type == HDMI_PANEL ||
+		mfd->panel_info.type == DTV_PANEL) {
+		ret = msm_fb_suspend_sub(mfd);
+
+		/* Turn off the HPD circuitry */
+		if (pdata->power_ctrl) {
+			MSM_FB_INFO("%s: Turning off HPD circuitry\n",
+					__func__);
+			pdata->power_ctrl(FALSE);
+		}
+	}
+
+	return ret;
+}
+
+static int msm_fb_ext_resume(struct device *dev)
+{
+	struct msm_fb_data_type *mfd = dev_get_drvdata(dev);
+	struct msm_fb_panel_data *pdata = NULL;
+	int ret = 0;
+
+	if ((!mfd) || (mfd->key != MFD_KEY))
+		return 0;
+
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+	if (mfd->panel_info.type == HDMI_PANEL ||
+		mfd->panel_info.type == DTV_PANEL) {
+		/* Turn on the HPD circuitry */
+		if (pdata->power_ctrl) {
+			pdata->power_ctrl(TRUE);
+			MSM_FB_INFO("%s: Turning on HPD circuitry\n",
+					__func__);
+		}
+
+		ret = msm_fb_resume_sub(mfd);
+	}
+
+	return ret;
+}
+#endif
+
+static struct dev_pm_ops msm_fb_dev_pm_ops = {
+	.runtime_suspend = msm_fb_runtime_suspend,
+	.runtime_resume = msm_fb_runtime_resume,
+	.runtime_idle = msm_fb_runtime_idle,
+#if (defined(CONFIG_SUSPEND) && defined(CONFIG_FB_MSM_HDMI_MSM_PANEL))
+	.suspend = msm_fb_ext_suspend,
+	.resume = msm_fb_ext_resume,
+#endif
+};
+
+static struct platform_driver msm_fb_driver = {
+	.probe = msm_fb_probe,
+	.remove = msm_fb_remove,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+	.suspend = msm_fb_suspend,
+	.resume = msm_fb_resume,
+#endif
+	.shutdown = NULL,
+	.driver = {
+		   /* Driver name must match the device name added in platform.c. */
+		   .name = "msm_fb",
+		   .pm = &msm_fb_dev_pm_ops,
+		   },
+};
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_FB_MSM_MDP303)
+static void memset32_io(u32 __iomem *_ptr, u32 val, size_t count)
+{
+	count >>= 2;
+	while (count--)
+		writel(val, _ptr++);
+}
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void msmfb_early_suspend(struct early_suspend *h)
+{
+	struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
+						    early_suspend);
+#if defined(CONFIG_FB_MSM_MDP303)
+	/*
+	* For MDP with overlay, set framebuffer with black pixels
+	* to show black screen on HDMI.
+	*/
+	struct fb_info *fbi = mfd->fbi;
+	switch (mfd->fbi->var.bits_per_pixel) {
+	case 32:
+		memset32_io((void *)fbi->screen_base, 0xFF000000,
+							fbi->fix.smem_len);
+		break;
+	default:
+		memset32_io((void *)fbi->screen_base, 0x00, fbi->fix.smem_len);
+		break;
+	}
+#endif
+	msm_fb_suspend_sub(mfd);
+}
+
+static void msmfb_early_resume(struct early_suspend *h)
+{
+	struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
+						    early_suspend);
+	msm_fb_resume_sub(mfd);
+}
+#endif
+
+static int unset_bl_level, bl_updated;
+static int bl_level_old;
+static int mdp_bl_scale_config(struct msm_fb_data_type *mfd,
+						struct mdp_bl_scale_data *data)
+{
+	int ret = 0;
+	int curr_bl = mfd->bl_level;
+	bl_scale = data->scale;
+	bl_min_lvl = data->min_lvl;
+	pr_debug("%s: update scale = %d, min_lvl = %d\n", __func__, bl_scale,
+								bl_min_lvl);
+
+	/* update current backlight to use new scaling*/
+	msm_fb_set_backlight(mfd, curr_bl);
+
+	return ret;
+}
+
+static void msm_fb_scale_bl(__u32 *bl_lvl)
+{
+	__u32 temp = *bl_lvl;
+	if (temp >= bl_min_lvl) {
+		/* bl_scale is the numerator of scaling fraction (x/1024)*/
+		temp = ((*bl_lvl) * bl_scale) / 1024;
+
+		/*if less than minimum level, use min level*/
+		if (temp < bl_min_lvl)
+			temp = bl_min_lvl;
+	}
+
+	(*bl_lvl) = temp;
+}
+
+void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl)
+{
+	struct msm_fb_panel_data *pdata;
+	__u32 temp = bkl_lvl;
+	if (!mfd->panel_power_on || !bl_updated) {
+		unset_bl_level = bkl_lvl;
+		return;
+	} else {
+		unset_bl_level = 0;
+	}
+
+	msm_fb_scale_bl(&temp);
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
+	if ((pdata) && (pdata->set_backlight)) {
+		down(&mfd->sem);
+		if (bl_level_old == temp) {
+			up(&mfd->sem);
+			return;
+		}
+		mfd->bl_level = temp;
+		pdata->set_backlight(mfd);
+		mfd->bl_level = bkl_lvl;
+		bl_level_old = temp;
+		up(&mfd->sem);
+	}
+}
+
+static int msm_fb_blank_sub(int blank_mode, struct fb_info *info,
+			    boolean op_enable)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct msm_fb_panel_data *pdata = NULL;
+	int ret = 0;
+
+	if (!op_enable)
+		return -EPERM;
+
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+	if ((!pdata) || (!pdata->on) || (!pdata->off)) {
+		printk(KERN_ERR "msm_fb_blank_sub: no panel operation detected!\n");
+		return -ENODEV;
+	}
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+		if (!mfd->panel_power_on) {
+			msleep(16);
+			ret = pdata->on(mfd->pdev);
+			if (ret == 0) {
+				mfd->panel_power_on = TRUE;
+
+/* ToDo: possible conflict with android which doesn't expect sw refresher */
+/*
+	  if (!mfd->hw_refresh)
+	  {
+	    if ((ret = msm_fb_resume_sw_refresher(mfd)) != 0)
+	    {
+	      MSM_FB_INFO("msm_fb_blank_sub: msm_fb_resume_sw_refresher failed = %d!\n",ret);
+	    }
+	  }
+*/
+			}
+		}
+		break;
+
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+	case FB_BLANK_POWERDOWN:
+	default:
+		if (mfd->panel_power_on) {
+			int curr_pwr_state;
+
+			mfd->op_enable = FALSE;
+			curr_pwr_state = mfd->panel_power_on;
+			mfd->panel_power_on = FALSE;
+			bl_updated = 0;
+
+			msleep(16);
+			ret = pdata->off(mfd->pdev);
+			if (ret)
+				mfd->panel_power_on = curr_pwr_state;
+
+			mfd->op_enable = TRUE;
+		}
+		break;
+	}
+
+	return ret;
+}
+
+int calc_fb_offset(struct msm_fb_data_type *mfd, struct fb_info *fbi, int bpp)
+{
+	struct msm_panel_info *panel_info = &mfd->panel_info;
+	int remainder, yres, offset;
+
+	if (panel_info->mode2_yres != 0) {
+		yres = panel_info->mode2_yres;
+		remainder = (fbi->fix.line_length*yres) & (PAGE_SIZE - 1);
+	} else {
+		yres = panel_info->yres;
+		remainder = (fbi->fix.line_length*yres) & (PAGE_SIZE - 1);
+	}
+
+	if (!remainder)
+		remainder = PAGE_SIZE;
+
+	if (fbi->var.yoffset < yres) {
+		offset = (fbi->var.xoffset * bpp);
+				/* iBuf->buf +=	fbi->var.xoffset * bpp + 0 *
+				yres * fbi->fix.line_length; */
+	} else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+		offset = (fbi->var.xoffset * bpp + yres *
+		fbi->fix.line_length + PAGE_SIZE - remainder);
+	} else {
+		offset = (fbi->var.xoffset * bpp + 2 * yres *
+		fbi->fix.line_length + 2 * (PAGE_SIZE - remainder));
+	}
+	return offset;
+}
+
+static void msm_fb_fillrect(struct fb_info *info,
+			    const struct fb_fillrect *rect)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	cfb_fillrect(info, rect);
+	if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
+		!mfd->sw_currently_refreshing) {
+		struct fb_var_screeninfo var;
+
+		var = info->var;
+		var.reserved[0] = 0x54445055;
+		var.reserved[1] = (rect->dy << 16) | (rect->dx);
+		var.reserved[2] = ((rect->dy + rect->height) << 16) |
+		    (rect->dx + rect->width);
+
+		msm_fb_pan_display(&var, info);
+	}
+}
+
+static void msm_fb_copyarea(struct fb_info *info,
+			    const struct fb_copyarea *area)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	cfb_copyarea(info, area);
+	if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
+		!mfd->sw_currently_refreshing) {
+		struct fb_var_screeninfo var;
+
+		var = info->var;
+		var.reserved[0] = 0x54445055;
+		var.reserved[1] = (area->dy << 16) | (area->dx);
+		var.reserved[2] = ((area->dy + area->height) << 16) |
+		    (area->dx + area->width);
+
+		msm_fb_pan_display(&var, info);
+	}
+}
+
+static void msm_fb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	cfb_imageblit(info, image);
+	if (!mfd->hw_refresh && (info->var.yoffset == 0) &&
+		!mfd->sw_currently_refreshing) {
+		struct fb_var_screeninfo var;
+
+		var = info->var;
+		var.reserved[0] = 0x54445055;
+		var.reserved[1] = (image->dy << 16) | (image->dx);
+		var.reserved[2] = ((image->dy + image->height) << 16) |
+		    (image->dx + image->width);
+
+		msm_fb_pan_display(&var, info);
+	}
+}
+
+static int msm_fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	return msm_fb_blank_sub(blank_mode, info, mfd->op_enable);
+}
+
+static int msm_fb_set_lut(struct fb_cmap *cmap, struct fb_info *info)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	if (!mfd->lut_update)
+		return -ENODEV;
+
+	mfd->lut_update(info, cmap);
+	return 0;
+}
+
+/*
+ * Custom Framebuffer mmap() function for MSM driver.
+ * Differs from standard mmap() function by allowing for customized
+ * page-protection.
+ */
+static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma)
+{
+	/* Get frame buffer memory range. */
+	unsigned long start = info->fix.smem_start;
+	u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
+	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	if (off >= len) {
+		/* memory mapped io */
+		off -= len;
+		if (info->var.accel_flags) {
+			mutex_unlock(&info->lock);
+			return -EINVAL;
+		}
+		start = info->fix.mmio_start;
+		len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
+	}
+
+	/* Set VM flags. */
+	start &= PAGE_MASK;
+	if ((vma->vm_end - vma->vm_start + off) > len)
+		return -EINVAL;
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO | VM_RESERVED;
+
+	/* Set VM page protection */
+	if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	else if (mfd->mdp_fb_page_protection ==
+			MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE)
+		vma->vm_page_prot = pgprot_writethroughcache(vma->vm_page_prot);
+	else if (mfd->mdp_fb_page_protection ==
+			MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE)
+		vma->vm_page_prot = pgprot_writebackcache(vma->vm_page_prot);
+	else if (mfd->mdp_fb_page_protection ==
+			MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE)
+		vma->vm_page_prot = pgprot_writebackwacache(vma->vm_page_prot);
+	else
+		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	/* Remap the frame buffer I/O range */
+	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+				vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static struct fb_ops msm_fb_ops = {
+	.owner = THIS_MODULE,
+	.fb_open = msm_fb_open,
+	.fb_release = msm_fb_release,
+	.fb_read = NULL,
+	.fb_write = NULL,
+	.fb_cursor = NULL,
+	.fb_check_var = msm_fb_check_var,	/* vinfo check */
+	.fb_set_par = msm_fb_set_par,	/* set the video mode according to info->var */
+	.fb_setcolreg = NULL,	/* set color register */
+	.fb_blank = msm_fb_blank,	/* blank display */
+	.fb_pan_display = msm_fb_pan_display,	/* pan display */
+	.fb_fillrect = msm_fb_fillrect,	/* Draws a rectangle */
+	.fb_copyarea = msm_fb_copyarea,	/* Copy data from area to another */
+	.fb_imageblit = msm_fb_imageblit,	/* Draws a image to the display */
+	.fb_rotate = NULL,
+	.fb_sync = NULL,	/* wait for blit idle, optional */
+	.fb_ioctl = msm_fb_ioctl,	/* perform fb specific ioctl (optional) */
+	.fb_mmap = msm_fb_mmap,
+};
+
+static __u32 msm_fb_line_length(__u32 fb_index, __u32 xres, int bpp)
+{
+	/* The adreno GPU hardware requires that the pitch be aligned to
+	   32 pixels for color buffers, so for the cases where the GPU
+	   is writing directly to fb0, the framebuffer pitch
+	   also needs to be 32 pixel aligned */
+
+	if (fb_index == 0)
+		return ALIGN(xres, 32) * bpp;
+	else
+		return xres * bpp;
+}
+
+static int msm_fb_register(struct msm_fb_data_type *mfd)
+{
+	int ret = -ENODEV;
+	int bpp;
+	struct msm_panel_info *panel_info = &mfd->panel_info;
+	struct fb_info *fbi = mfd->fbi;
+	struct fb_fix_screeninfo *fix;
+	struct fb_var_screeninfo *var;
+	int *id;
+	int fbram_offset;
+	int remainder, remainder_mode2;
+	static int subsys_id[2] = {MSM_SUBSYSTEM_DISPLAY,
+		MSM_SUBSYSTEM_ROTATOR};
+	unsigned int flags = MSM_SUBSYSTEM_MAP_IOVA;
+
+	/*
+	 * fb info initialization
+	 */
+	fix = &fbi->fix;
+	var = &fbi->var;
+
+	fix->type_aux = 0;	/* if type == FB_TYPE_INTERLEAVED_PLANES */
+	fix->visual = FB_VISUAL_TRUECOLOR;	/* True Color */
+	fix->ywrapstep = 0;	/* No support */
+	fix->mmio_start = 0;	/* No MMIO Address */
+	fix->mmio_len = 0;	/* No MMIO Address */
+	fix->accel = FB_ACCEL_NONE;/* FB_ACCEL_MSM needes to be added in fb.h */
+
+	var->xoffset = 0,	/* Offset from virtual to visible */
+	var->yoffset = 0,	/* resolution */
+	var->grayscale = 0,	/* No graylevels */
+	var->nonstd = 0,	/* standard pixel format */
+	var->activate = FB_ACTIVATE_VBL,	/* activate it at vsync */
+	var->height = -1,	/* height of picture in mm */
+	var->width = -1,	/* width of picture in mm */
+	var->accel_flags = 0,	/* acceleration flags */
+	var->sync = 0,	/* see FB_SYNC_* */
+	var->rotate = 0,	/* angle we rotate counter clockwise */
+	mfd->op_enable = FALSE;
+
+	switch (mfd->fb_imgType) {
+	case MDP_RGB_565:
+		fix->type = FB_TYPE_PACKED_PIXELS;
+		fix->xpanstep = 1;
+		fix->ypanstep = 1;
+		var->vmode = FB_VMODE_NONINTERLACED;
 		var->blue.offset = 0;
+		var->green.offset = 5;
+		var->red.offset = 11;
 		var->blue.length = 5;
-	} else
-		return -1;
-	mdp->set_output_format(mdp, var->bits_per_pixel);
-	fix->line_length = ALIGN(var->xres, 32) * var->bits_per_pixel / 8;
+		var->green.length = 6;
+		var->red.length = 5;
+		var->blue.msb_right = 0;
+		var->green.msb_right = 0;
+		var->red.msb_right = 0;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		bpp = 2;
+		break;
+
+	case MDP_RGB_888:
+		fix->type = FB_TYPE_PACKED_PIXELS;
+		fix->xpanstep = 1;
+		fix->ypanstep = 1;
+		var->vmode = FB_VMODE_NONINTERLACED;
+		var->blue.offset = 0;
+		var->green.offset = 8;
+		var->red.offset = 16;
+		var->blue.length = 8;
+		var->green.length = 8;
+		var->red.length = 8;
+		var->blue.msb_right = 0;
+		var->green.msb_right = 0;
+		var->red.msb_right = 0;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		bpp = 3;
+		break;
+
+	case MDP_ARGB_8888:
+		fix->type = FB_TYPE_PACKED_PIXELS;
+		fix->xpanstep = 1;
+		fix->ypanstep = 1;
+		var->vmode = FB_VMODE_NONINTERLACED;
+		var->blue.offset = 0;
+		var->green.offset = 8;
+		var->red.offset = 16;
+		var->blue.length = 8;
+		var->green.length = 8;
+		var->red.length = 8;
+		var->blue.msb_right = 0;
+		var->green.msb_right = 0;
+		var->red.msb_right = 0;
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		bpp = 4;
+		break;
+
+	case MDP_RGBA_8888:
+		fix->type = FB_TYPE_PACKED_PIXELS;
+		fix->xpanstep = 1;
+		fix->ypanstep = 1;
+		var->vmode = FB_VMODE_NONINTERLACED;
+		var->blue.offset = 8;
+		var->green.offset = 16;
+		var->red.offset = 24;
+		var->blue.length = 8;
+		var->green.length = 8;
+		var->red.length = 8;
+		var->blue.msb_right = 0;
+		var->green.msb_right = 0;
+		var->red.msb_right = 0;
+		var->transp.offset = 0;
+		var->transp.length = 8;
+		bpp = 4;
+		break;
+
+	case MDP_YCRYCB_H2V1:
+		/* ToDo: need to check TV-Out YUV422i framebuffer format */
+		/*       we might need to create new type define */
+		fix->type = FB_TYPE_INTERLEAVED_PLANES;
+		fix->xpanstep = 2;
+		fix->ypanstep = 1;
+		var->vmode = FB_VMODE_NONINTERLACED;
+
+		/* how about R/G/B offset? */
+		var->blue.offset = 0;
+		var->green.offset = 5;
+		var->red.offset = 11;
+		var->blue.length = 5;
+		var->green.length = 6;
+		var->red.length = 5;
+		var->blue.msb_right = 0;
+		var->green.msb_right = 0;
+		var->red.msb_right = 0;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		bpp = 2;
+		break;
+
+	default:
+		MSM_FB_ERR("msm_fb_init: fb %d unkown image type!\n",
+			   mfd->index);
+		return ret;
+	}
+
+	fix->type = panel_info->is_3d_panel;
+
+	fix->line_length = msm_fb_line_length(mfd->index, panel_info->xres,
+					      bpp);
+
+	/* Make sure all buffers can be addressed on a page boundary by an x
+	 * and y offset */
+
+	remainder = (fix->line_length * panel_info->yres) & (PAGE_SIZE - 1);
+					/* PAGE_SIZE is a power of 2 */
+	if (!remainder)
+		remainder = PAGE_SIZE;
+	remainder_mode2 = (fix->line_length *
+				panel_info->mode2_yres) & (PAGE_SIZE - 1);
+	if (!remainder_mode2)
+		remainder_mode2 = PAGE_SIZE;
+
+	/*
+	 * calculate smem_len based on max size of two supplied modes.
+	 * Only fb0 has mem. fb1 and fb2 don't have mem.
+	 */
+
+	if (!bf_supported || mfd->index == 0)
+		fix->smem_len = MAX((msm_fb_line_length(mfd->index,
+							panel_info->xres,
+							bpp) *
+				     panel_info->yres + PAGE_SIZE -
+				     remainder) * mfd->fb_page,
+				    (msm_fb_line_length(mfd->index,
+							panel_info->mode2_xres,
+							bpp) *
+				     panel_info->mode2_yres + PAGE_SIZE -
+				     remainder_mode2) * mfd->fb_page);
+	else if (mfd->index == 1 || mfd->index == 2) {
+		pr_debug("%s:%d no memory is allocated for fb%d!\n",
+			__func__, __LINE__, mfd->index);
+		fix->smem_len = 0;
+	}
+
+	mfd->var_xres = panel_info->xres;
+	mfd->var_yres = panel_info->yres;
+	mfd->var_frame_rate = panel_info->frame_rate;
+
+	var->pixclock = mfd->panel_info.clk_rate;
+	mfd->var_pixclock = var->pixclock;
+
+	var->xres = panel_info->xres;
+	var->yres = panel_info->yres;
+	var->xres_virtual = panel_info->xres;
+	var->yres_virtual = panel_info->yres * mfd->fb_page;
+	var->bits_per_pixel = bpp * 8;	/* FrameBuffer color depth */
+	if (mfd->dest == DISPLAY_LCD) {
+		if (panel_info->type == MDDI_PANEL && panel_info->mddi.is_type1)
+			var->reserved[4] = panel_info->lcd.refx100 / (100 * 2);
+		else
+			var->reserved[4] = panel_info->lcd.refx100 / 100;
+	} else {
+		if (panel_info->type == MIPI_VIDEO_PANEL) {
+			var->reserved[4] = panel_info->mipi.frame_rate;
+		} else {
+			var->reserved[4] = panel_info->clk_rate /
+				((panel_info->lcdc.h_back_porch +
+				  panel_info->lcdc.h_front_porch +
+				  panel_info->lcdc.h_pulse_width +
+				  panel_info->xres) *
+				 (panel_info->lcdc.v_back_porch +
+				  panel_info->lcdc.v_front_porch +
+				  panel_info->lcdc.v_pulse_width +
+				  panel_info->yres));
+		}
+	}
+	pr_debug("reserved[4] %u\n", var->reserved[4]);
+
+		/*
+		 * id field for fb app
+		 */
+	id = (int *)&mfd->panel;
+
+	switch (mdp_rev) {
+	case MDP_REV_20:
+		snprintf(fix->id, sizeof(fix->id), "msmfb20_%x", (__u32) *id);
+		break;
+	case MDP_REV_22:
+		snprintf(fix->id, sizeof(fix->id), "msmfb22_%x", (__u32) *id);
+		break;
+	case MDP_REV_30:
+		snprintf(fix->id, sizeof(fix->id), "msmfb30_%x", (__u32) *id);
+		break;
+	case MDP_REV_303:
+		snprintf(fix->id, sizeof(fix->id), "msmfb303_%x", (__u32) *id);
+		break;
+	case MDP_REV_31:
+		snprintf(fix->id, sizeof(fix->id), "msmfb31_%x", (__u32) *id);
+		break;
+	case MDP_REV_40:
+		snprintf(fix->id, sizeof(fix->id), "msmfb40_%x", (__u32) *id);
+		break;
+	case MDP_REV_41:
+		snprintf(fix->id, sizeof(fix->id), "msmfb41_%x", (__u32) *id);
+		break;
+	case MDP_REV_42:
+		snprintf(fix->id, sizeof(fix->id), "msmfb42_%x", (__u32) *id);
+		break;
+	case MDP_REV_43:
+		snprintf(fix->id, sizeof(fix->id), "msmfb43_%x", (__u32) *id);
+		break;
+	case MDP_REV_44:
+		snprintf(fix->id, sizeof(fix->id), "msmfb44_%x", (__u32) *id);
+		break;
+	default:
+		snprintf(fix->id, sizeof(fix->id), "msmfb0_%x", (__u32) *id);
+		break;
+	}
+
+	fbi->fbops = &msm_fb_ops;
+	fbi->flags = FBINFO_FLAG_DEFAULT;
+	fbi->pseudo_palette = msm_fb_pseudo_palette;
+
+	mfd->ref_cnt = 0;
+	mfd->sw_currently_refreshing = FALSE;
+	mfd->sw_refreshing_enable = TRUE;
+	mfd->panel_power_on = FALSE;
+
+	mfd->pan_waiting = FALSE;
+	init_completion(&mfd->pan_comp);
+	init_completion(&mfd->refresher_comp);
+	sema_init(&mfd->sem, 1);
+
+	init_timer(&mfd->msmfb_no_update_notify_timer);
+	mfd->msmfb_no_update_notify_timer.function =
+			msmfb_no_update_notify_timer_cb;
+	mfd->msmfb_no_update_notify_timer.data = (unsigned long)mfd;
+	init_completion(&mfd->msmfb_update_notify);
+	init_completion(&mfd->msmfb_no_update_notify);
+
+	fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
+	fbram += fbram_offset;
+	fbram_phys += fbram_offset;
+	fbram_size -= fbram_offset;
+
+	if (!bf_supported || mfd->index == 0)
+		if (fbram_size < fix->smem_len) {
+			pr_err("error: no more framebuffer memory!\n");
+			return -ENOMEM;
+		}
+
+	fbi->screen_base = fbram;
+	fbi->fix.smem_start = (unsigned long)fbram_phys;
+
+	mfd->map_buffer = msm_subsystem_map_buffer(
+		fbi->fix.smem_start, fbi->fix.smem_len,
+		flags, subsys_id, 2);
+	if (mfd->map_buffer) {
+		pr_debug("%s(): buf 0x%lx, mfd->map_buffer->iova[0] 0x%lx\n"
+			"mfd->map_buffer->iova[1] 0x%lx", __func__,
+			fbi->fix.smem_start, mfd->map_buffer->iova[0],
+			mfd->map_buffer->iova[1]);
+	}
+	if (!bf_supported || mfd->index == 0)
+		memset(fbi->screen_base, 0x0, fix->smem_len);
+
+	mfd->op_enable = TRUE;
+	mfd->panel_power_on = FALSE;
+
+	/* cursor memory allocation */
+	if (mfd->cursor_update) {
+		mfd->cursor_buf = dma_alloc_coherent(NULL,
+					MDP_CURSOR_SIZE,
+					(dma_addr_t *) &mfd->cursor_buf_phys,
+					GFP_KERNEL);
+		if (!mfd->cursor_buf)
+			mfd->cursor_update = 0;
+	}
+
+	if (mfd->lut_update) {
+		ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
+		if (ret)
+			printk(KERN_ERR "%s: fb_alloc_cmap() failed!\n",
+					__func__);
+	}
+
+	if (register_framebuffer(fbi) < 0) {
+		if (mfd->lut_update)
+			fb_dealloc_cmap(&fbi->cmap);
+
+		if (mfd->cursor_buf)
+			dma_free_coherent(NULL,
+				MDP_CURSOR_SIZE,
+				mfd->cursor_buf,
+				(dma_addr_t) mfd->cursor_buf_phys);
+
+		mfd->op_enable = FALSE;
+		return -EPERM;
+	}
+
+	fbram += fix->smem_len;
+	fbram_phys += fix->smem_len;
+	fbram_size -= fix->smem_len;
+
+	MSM_FB_INFO
+	    ("FrameBuffer[%d] %dx%d size=%d bytes is registered successfully!\n",
+	     mfd->index, fbi->var.xres, fbi->var.yres, fbi->fix.smem_len);
+
+#ifdef CONFIG_FB_MSM_LOGO
+	/* Flip buffer */
+	if (!load_565rle_image(INIT_IMAGE_FILE, bf_supported))
+		;
+#endif
+	ret = 0;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	if (mfd->panel_info.type != DTV_PANEL) {
+		mfd->early_suspend.suspend = msmfb_early_suspend;
+		mfd->early_suspend.resume = msmfb_early_resume;
+		mfd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2;
+		register_early_suspend(&mfd->early_suspend);
+	}
+#endif
+
+#ifdef MSM_FB_ENABLE_DBGFS
+	{
+		struct dentry *root;
+		struct dentry *sub_dir;
+		char sub_name[2];
+
+		root = msm_fb_get_debugfs_root();
+		if (root != NULL) {
+			sub_name[0] = (char)(mfd->index + 0x30);
+			sub_name[1] = '\0';
+			sub_dir = debugfs_create_dir(sub_name, root);
+		} else {
+			sub_dir = NULL;
+		}
+
+		mfd->sub_dir = sub_dir;
+
+		if (sub_dir) {
+			msm_fb_debugfs_file_create(sub_dir, "op_enable",
+						   (u32 *) &mfd->op_enable);
+			msm_fb_debugfs_file_create(sub_dir, "panel_power_on",
+						   (u32 *) &mfd->
+						   panel_power_on);
+			msm_fb_debugfs_file_create(sub_dir, "ref_cnt",
+						   (u32 *) &mfd->ref_cnt);
+			msm_fb_debugfs_file_create(sub_dir, "fb_imgType",
+						   (u32 *) &mfd->fb_imgType);
+			msm_fb_debugfs_file_create(sub_dir,
+						   "sw_currently_refreshing",
+						   (u32 *) &mfd->
+						   sw_currently_refreshing);
+			msm_fb_debugfs_file_create(sub_dir,
+						   "sw_refreshing_enable",
+						   (u32 *) &mfd->
+						   sw_refreshing_enable);
+
+			msm_fb_debugfs_file_create(sub_dir, "xres",
+						   (u32 *) &mfd->panel_info.
+						   xres);
+			msm_fb_debugfs_file_create(sub_dir, "yres",
+						   (u32 *) &mfd->panel_info.
+						   yres);
+			msm_fb_debugfs_file_create(sub_dir, "bpp",
+						   (u32 *) &mfd->panel_info.
+						   bpp);
+			msm_fb_debugfs_file_create(sub_dir, "type",
+						   (u32 *) &mfd->panel_info.
+						   type);
+			msm_fb_debugfs_file_create(sub_dir, "wait_cycle",
+						   (u32 *) &mfd->panel_info.
+						   wait_cycle);
+			msm_fb_debugfs_file_create(sub_dir, "pdest",
+						   (u32 *) &mfd->panel_info.
+						   pdest);
+			msm_fb_debugfs_file_create(sub_dir, "backbuff",
+						   (u32 *) &mfd->panel_info.
+						   fb_num);
+			msm_fb_debugfs_file_create(sub_dir, "clk_rate",
+						   (u32 *) &mfd->panel_info.
+						   clk_rate);
+			msm_fb_debugfs_file_create(sub_dir, "frame_count",
+						   (u32 *) &mfd->panel_info.
+						   frame_count);
+
+
+			switch (mfd->dest) {
+			case DISPLAY_LCD:
+				msm_fb_debugfs_file_create(sub_dir,
+				"vsync_enable",
+				(u32 *)&mfd->panel_info.lcd.vsync_enable);
+				msm_fb_debugfs_file_create(sub_dir,
+				"refx100",
+				(u32 *) &mfd->panel_info.lcd. refx100);
+				msm_fb_debugfs_file_create(sub_dir,
+				"v_back_porch",
+				(u32 *) &mfd->panel_info.lcd.v_back_porch);
+				msm_fb_debugfs_file_create(sub_dir,
+				"v_front_porch",
+				(u32 *) &mfd->panel_info.lcd.v_front_porch);
+				msm_fb_debugfs_file_create(sub_dir,
+				"v_pulse_width",
+				(u32 *) &mfd->panel_info.lcd.v_pulse_width);
+				msm_fb_debugfs_file_create(sub_dir,
+				"hw_vsync_mode",
+				(u32 *) &mfd->panel_info.lcd.hw_vsync_mode);
+				msm_fb_debugfs_file_create(sub_dir,
+				"vsync_notifier_period", (u32 *)
+				&mfd->panel_info.lcd.vsync_notifier_period);
+				break;
+
+			case DISPLAY_LCDC:
+				msm_fb_debugfs_file_create(sub_dir,
+				"h_back_porch",
+				(u32 *) &mfd->panel_info.lcdc.h_back_porch);
+				msm_fb_debugfs_file_create(sub_dir,
+				"h_front_porch",
+				(u32 *) &mfd->panel_info.lcdc.h_front_porch);
+				msm_fb_debugfs_file_create(sub_dir,
+				"h_pulse_width",
+				(u32 *) &mfd->panel_info.lcdc.h_pulse_width);
+				msm_fb_debugfs_file_create(sub_dir,
+				"v_back_porch",
+				(u32 *) &mfd->panel_info.lcdc.v_back_porch);
+				msm_fb_debugfs_file_create(sub_dir,
+				"v_front_porch",
+				(u32 *) &mfd->panel_info.lcdc.v_front_porch);
+				msm_fb_debugfs_file_create(sub_dir,
+				"v_pulse_width",
+				(u32 *) &mfd->panel_info.lcdc.v_pulse_width);
+				msm_fb_debugfs_file_create(sub_dir,
+				"border_clr",
+				(u32 *) &mfd->panel_info.lcdc.border_clr);
+				msm_fb_debugfs_file_create(sub_dir,
+				"underflow_clr",
+				(u32 *) &mfd->panel_info.lcdc.underflow_clr);
+				msm_fb_debugfs_file_create(sub_dir,
+				"hsync_skew",
+				(u32 *) &mfd->panel_info.lcdc.hsync_skew);
+				break;
+
+			default:
+				break;
+			}
+		}
+	}
+#endif /* MSM_FB_ENABLE_DBGFS */
+
+	return ret;
+}
+
+static int msm_fb_open(struct fb_info *info, int user)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	int result;
+
+	result = pm_runtime_get_sync(info->dev);
+
+	if (result < 0) {
+		printk(KERN_ERR "pm_runtime: fail to wake up\n");
+	}
+
+	if (info->node == 0 && !(mfd->cont_splash_done)) {	/* primary */
+			mfd->ref_cnt++;
+			return 0;
+	}
+
+	if (!mfd->ref_cnt) {
+		if (!bf_supported ||
+			(info->node != 1 && info->node != 2))
+			mdp_set_dma_pan_info(info, NULL, TRUE);
+		else
+			pr_debug("%s:%d no mdp_set_dma_pan_info %d\n",
+				__func__, __LINE__, info->node);
+
+		if (msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable)) {
+			printk(KERN_ERR "msm_fb_open: can't turn on display!\n");
+			return -1;
+		}
+	}
+
+	mfd->ref_cnt++;
 	return 0;
 }
 
-int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+static int msm_fb_release(struct fb_info *info, int user)
 {
-	struct msmfb_info *msmfb = info->par;
-	struct msm_panel_data *panel = msmfb->panel;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	int ret = 0;
+
+	if (!mfd->ref_cnt) {
+		MSM_FB_INFO("msm_fb_release: try to close unopened fb %d!\n",
+			    mfd->index);
+		return -EINVAL;
+	}
+
+	mfd->ref_cnt--;
+
+	if (!mfd->ref_cnt) {
+		if ((ret =
+		     msm_fb_blank_sub(FB_BLANK_POWERDOWN, info,
+				      mfd->op_enable)) != 0) {
+			printk(KERN_ERR "msm_fb_release: can't turn off display!\n");
+			return ret;
+		}
+	}
+
+	pm_runtime_put(info->dev);
+	return ret;
+}
+
+DECLARE_MUTEX(msm_fb_pan_sem);
+
+static int msm_fb_pan_display(struct fb_var_screeninfo *var,
+			      struct fb_info *info)
+{
+	struct mdp_dirty_region dirty;
+	struct mdp_dirty_region *dirtyPtr = NULL;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct msm_fb_panel_data *pdata;
+
+	/*
+	 * If framebuffer is 2, io pen display is not allowed.
+	 */
+	if (bf_supported && info->node == 2) {
+		pr_err("%s: no pan display for fb%d!",
+		       __func__, info->node);
+		return -EPERM;
+	}
+
+	if (info->node != 0 || mfd->cont_splash_done)	/* primary */
+		if ((!mfd->op_enable) || (!mfd->panel_power_on))
+			return -EPERM;
+
+	if (var->xoffset > (info->var.xres_virtual - info->var.xres))
+		return -EINVAL;
+
+	if (var->yoffset > (info->var.yres_virtual - info->var.yres))
+		return -EINVAL;
+
+	if (info->fix.xpanstep)
+		info->var.xoffset =
+		    (var->xoffset / info->fix.xpanstep) * info->fix.xpanstep;
+
+	if (info->fix.ypanstep)
+		info->var.yoffset =
+		    (var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;
 
 	/* "UPDT" */
-	if ((panel->caps & MSMFB_CAP_PARTIAL_UPDATES) &&
-	    (var->reserved[0] == 0x54445055)) {
-#if 0
-		PR_DISP_INFO("pan frame %d-%d, rect %d %d %d %d\n",
-		       msmfb->frame_requested, msmfb->frame_done,
-		       var->reserved[1] & 0xffff,
-		       var->reserved[1] >> 16, var->reserved[2] & 0xffff,
-		       var->reserved[2] >> 16);
-#endif
-		msmfb_pan_update(info, var->reserved[1] & 0xffff,
-				 var->reserved[1] >> 16,
-				 var->reserved[2] & 0xffff,
-				 var->reserved[2] >> 16, var->yoffset, 1);
-	} else {
-		msmfb_pan_update(info, 0, 0, info->var.xres, info->var.yres,
-				 var->yoffset, 1);
+	if (var->reserved[0] == 0x54445055) {
+
+		dirty.xoffset = var->reserved[1] & 0xffff;
+		dirty.yoffset = (var->reserved[1] >> 16) & 0xffff;
+
+		if ((var->reserved[2] & 0xffff) <= dirty.xoffset)
+			return -EINVAL;
+		if (((var->reserved[2] >> 16) & 0xffff) <= dirty.yoffset)
+			return -EINVAL;
+
+		dirty.width = (var->reserved[2] & 0xffff) - dirty.xoffset;
+		dirty.height =
+		    ((var->reserved[2] >> 16) & 0xffff) - dirty.yoffset;
+		info->var.yoffset = var->yoffset;
+
+		if (dirty.xoffset < 0)
+			return -EINVAL;
+
+		if (dirty.yoffset < 0)
+			return -EINVAL;
+
+		if ((dirty.xoffset + dirty.width) > info->var.xres)
+			return -EINVAL;
+
+		if ((dirty.yoffset + dirty.height) > info->var.yres)
+			return -EINVAL;
+
+		if ((dirty.width <= 0) || (dirty.height <= 0))
+			return -EINVAL;
+
+		dirtyPtr = &dirty;
 	}
+	complete(&mfd->msmfb_update_notify);
+	mutex_lock(&msm_fb_notify_update_sem);
+	if (mfd->msmfb_no_update_notify_timer.function)
+		del_timer(&mfd->msmfb_no_update_notify_timer);
+
+	mfd->msmfb_no_update_notify_timer.expires =
+				jiffies + ((1000 * HZ) / 1000);
+	add_timer(&mfd->msmfb_no_update_notify_timer);
+	mutex_unlock(&msm_fb_notify_update_sem);
+
+	down(&msm_fb_pan_sem);
+
+	if (info->node == 0 && !(mfd->cont_splash_done)) { /* primary */
+		mdp_set_dma_pan_info(info, NULL, TRUE);
+		if (msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable)) {
+			pr_err("%s: can't turn on display!\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	mdp_set_dma_pan_info(info, dirtyPtr,
+			     (var->activate == FB_ACTIVATE_VBL));
+	mdp_dma_pan_update(info);
+	up(&msm_fb_pan_sem);
+
+	if (unset_bl_level && !bl_updated) {
+		pdata = (struct msm_fb_panel_data *)mfd->pdev->
+			dev.platform_data;
+		if ((pdata) && (pdata->set_backlight)) {
+			down(&mfd->sem);
+			mfd->bl_level = unset_bl_level;
+			pdata->set_backlight(mfd);
+			bl_level_old = unset_bl_level;
+			up(&mfd->sem);
+			bl_updated = 1;
+		}
+	}
+
+	++mfd->panel_info.frame_count;
 	return 0;
 }
 
-static void msmfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
+static int msm_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	cfb_fillrect(p, rect);
-	msmfb_update(p, rect->dx, rect->dy, rect->dx + rect->width,
-		     rect->dy + rect->height);
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	if (var->rotate != FB_ROTATE_UR)
+		return -EINVAL;
+	if (var->grayscale != info->var.grayscale)
+		return -EINVAL;
+
+	switch (var->bits_per_pixel) {
+	case 16:
+		if ((var->green.offset != 5) ||
+			!((var->blue.offset == 11)
+				|| (var->blue.offset == 0)) ||
+			!((var->red.offset == 11)
+				|| (var->red.offset == 0)) ||
+			(var->blue.length != 5) ||
+			(var->green.length != 6) ||
+			(var->red.length != 5) ||
+			(var->blue.msb_right != 0) ||
+			(var->green.msb_right != 0) ||
+			(var->red.msb_right != 0) ||
+			(var->transp.offset != 0) ||
+			(var->transp.length != 0))
+				return -EINVAL;
+		break;
+
+	case 24:
+		if ((var->blue.offset != 0) ||
+			(var->green.offset != 8) ||
+			(var->red.offset != 16) ||
+			(var->blue.length != 8) ||
+			(var->green.length != 8) ||
+			(var->red.length != 8) ||
+			(var->blue.msb_right != 0) ||
+			(var->green.msb_right != 0) ||
+			(var->red.msb_right != 0) ||
+			!(((var->transp.offset == 0) &&
+				(var->transp.length == 0)) ||
+			  ((var->transp.offset == 24) &&
+				(var->transp.length == 8))))
+				return -EINVAL;
+		break;
+
+	case 32:
+		/* Figure out if the user meant RGBA or ARGB
+		   and verify the position of the RGB components */
+
+		if (var->transp.offset == 24) {
+			if ((var->blue.offset != 0) ||
+			    (var->green.offset != 8) ||
+			    (var->red.offset != 16))
+				return -EINVAL;
+		} else if (var->transp.offset == 0) {
+			if ((var->blue.offset != 8) ||
+			    (var->green.offset != 16) ||
+			    (var->red.offset != 24))
+				return -EINVAL;
+		} else
+			return -EINVAL;
+
+		/* Check the common values for both RGBA and ARGB */
+
+		if ((var->blue.length != 8) ||
+		    (var->green.length != 8) ||
+		    (var->red.length != 8) ||
+		    (var->transp.length != 8) ||
+		    (var->blue.msb_right != 0) ||
+		    (var->green.msb_right != 0) ||
+		    (var->red.msb_right != 0))
+			return -EINVAL;
+
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if ((var->xres_virtual <= 0) || (var->yres_virtual <= 0))
+		return -EINVAL;
+
+	if (!bf_supported ||
+		(info->node != 1 && info->node != 2))
+		if (info->fix.smem_len <
+		    (var->xres_virtual*
+		     var->yres_virtual*
+		     (var->bits_per_pixel/8)))
+			return -EINVAL;
+
+	if ((var->xres == 0) || (var->yres == 0))
+		return -EINVAL;
+
+	if ((var->xres > MAX(mfd->panel_info.xres,
+			     mfd->panel_info.mode2_xres)) ||
+		(var->yres > MAX(mfd->panel_info.yres,
+				 mfd->panel_info.mode2_yres)))
+		return -EINVAL;
+
+	if (var->xoffset > (var->xres_virtual - var->xres))
+		return -EINVAL;
+
+	if (var->yoffset > (var->yres_virtual - var->yres))
+		return -EINVAL;
+
+	return 0;
 }
 
-static void msmfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
+int msm_fb_check_frame_rate(struct msm_fb_data_type *mfd
+						, struct fb_info *info)
 {
-	cfb_copyarea(p, area);
-	msmfb_update(p, area->dx, area->dy, area->dx + area->width,
-		     area->dy + area->height);
+	int panel_height, panel_width, var_frame_rate, fps_mod;
+	struct fb_var_screeninfo *var = &info->var;
+	fps_mod = 0;
+	if ((mfd->panel_info.type == DTV_PANEL) ||
+		(mfd->panel_info.type == HDMI_PANEL)) {
+		panel_height = var->yres + var->upper_margin +
+			var->vsync_len + var->lower_margin;
+		panel_width = var->xres + var->right_margin +
+			var->hsync_len + var->left_margin;
+		var_frame_rate = ((var->pixclock)/(panel_height * panel_width));
+		if (mfd->var_frame_rate != var_frame_rate) {
+			fps_mod = 1;
+			mfd->var_frame_rate = var_frame_rate;
+		}
+	}
+	return fps_mod;
 }
 
-static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image)
+static int msm_fb_set_par(struct fb_info *info)
 {
-	cfb_imageblit(p, image);
-	msmfb_update(p, image->dx, image->dy, image->dx + image->width,
-		     image->dy + image->height);
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct fb_var_screeninfo *var = &info->var;
+	int old_imgType;
+	int blank = 0;
+
+	old_imgType = mfd->fb_imgType;
+	switch (var->bits_per_pixel) {
+	case 16:
+		if (var->red.offset == 0)
+			mfd->fb_imgType = MDP_BGR_565;
+		else
+			mfd->fb_imgType = MDP_RGB_565;
+		break;
+
+	case 24:
+		if ((var->transp.offset == 0) && (var->transp.length == 0))
+			mfd->fb_imgType = MDP_RGB_888;
+		else if ((var->transp.offset == 24) &&
+				(var->transp.length == 8)) {
+			mfd->fb_imgType = MDP_ARGB_8888;
+			info->var.bits_per_pixel = 32;
+		}
+		break;
+
+	case 32:
+		if (var->transp.offset == 24)
+			mfd->fb_imgType = MDP_ARGB_8888;
+		else
+			mfd->fb_imgType = MDP_RGBA_8888;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if ((mfd->var_pixclock != var->pixclock) ||
+		(mfd->hw_refresh && ((mfd->fb_imgType != old_imgType) ||
+				(mfd->var_pixclock != var->pixclock) ||
+				(mfd->var_xres != var->xres) ||
+				(mfd->var_yres != var->yres) ||
+				(msm_fb_check_frame_rate(mfd, info))))) {
+		mfd->var_xres = var->xres;
+		mfd->var_yres = var->yres;
+		mfd->var_pixclock = var->pixclock;
+		blank = 1;
+	}
+	mfd->fbi->fix.line_length = msm_fb_line_length(mfd->index, var->xres,
+						       var->bits_per_pixel/8);
+
+	if (blank) {
+		msm_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable);
+		msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable);
+	}
+
+	return 0;
 }
 
-
-static int msmfb_blit(struct fb_info *info,
-		      void __user *p)
+static int msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd)
 {
-	struct mdp_blit_req req;
-	struct mdp_blit_req_list req_list;
-	int i;
-	int ret, sem_owned;
+	if (mfd->hw_refresh)
+		return -EPERM;
 
-	if (copy_from_user(&req_list, p, sizeof(req_list)))
-		return -EFAULT;
+	if (mfd->sw_currently_refreshing) {
+		down(&mfd->sem);
+		mfd->sw_currently_refreshing = FALSE;
+		up(&mfd->sem);
 
-	for (i = 0; i < req_list.count; i++) {
-		struct mdp_blit_req_list *list =
-			(struct mdp_blit_req_list *)p;
-		if (copy_from_user(&req, &list->req[i], sizeof(req)))
-			return -EFAULT;
-		sem_owned = overlay_semaphore_lock();
-		ret = mdp->blit(mdp, info, &req);
+		/* wait until the refresher finishes the last job */
+		wait_for_completion_killable(&mfd->refresher_comp);
+	}
 
-		if (sem_owned == 0)
-			overlay_semaphore_unlock();
+	return 0;
+}
+
+int msm_fb_resume_sw_refresher(struct msm_fb_data_type *mfd)
+{
+	boolean do_refresh;
+
+	if (mfd->hw_refresh)
+		return -EPERM;
+
+	down(&mfd->sem);
+	if ((!mfd->sw_currently_refreshing) && (mfd->sw_refreshing_enable)) {
+		do_refresh = TRUE;
+		mfd->sw_currently_refreshing = TRUE;
+	} else {
+		do_refresh = FALSE;
+	}
+	up(&mfd->sem);
+
+	if (do_refresh)
+		mdp_refresh_screen((unsigned long)mfd);
+
+	return 0;
+}
+
+#if defined CONFIG_FB_MSM_MDP31
+static int mdp_blit_split_height(struct fb_info *info,
+				struct mdp_blit_req *req)
+{
+	int ret;
+	struct mdp_blit_req splitreq;
+	int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1;
+	int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1;
+
+	splitreq = *req;
+	/* break dest roi at height*/
+	d_x_0 = d_x_1 = req->dst_rect.x;
+	d_w_0 = d_w_1 = req->dst_rect.w;
+	d_y_0 = req->dst_rect.y;
+	if (req->dst_rect.h % 32 == 3)
+		d_h_1 = (req->dst_rect.h - 3) / 2 - 1;
+	else if (req->dst_rect.h % 32 == 2)
+		d_h_1 = (req->dst_rect.h - 2) / 2 - 6;
+	else
+		d_h_1 = (req->dst_rect.h - 1) / 2 - 1;
+	d_h_0 = req->dst_rect.h - d_h_1;
+	d_y_1 = d_y_0 + d_h_0;
+	if (req->dst_rect.h == 3) {
+		d_h_1 = 2;
+		d_h_0 = 2;
+		d_y_1 = d_y_0 + 1;
+	}
+
+	/* blit first region */
+	if (((splitreq.flags & 0x07) == 0x04) ||
+		((splitreq.flags & 0x07) == 0x0)) {
+
+		if (splitreq.flags & MDP_ROT_90) {
+			s_y_0 = s_y_1 = req->src_rect.y;
+			s_h_0 = s_h_1 = req->src_rect.h;
+			s_x_0 = req->src_rect.x;
+			s_w_1 = (req->src_rect.w * d_h_1) / req->dst_rect.h;
+			s_w_0 = req->src_rect.w - s_w_1;
+			s_x_1 = s_x_0 + s_w_0;
+			if (d_h_1 >= 8 * s_w_1) {
+				s_w_1++;
+				s_x_1--;
+			}
+		} else {
+			s_x_0 = s_x_1 = req->src_rect.x;
+			s_w_0 = s_w_1 = req->src_rect.w;
+			s_y_0 = req->src_rect.y;
+			s_h_1 = (req->src_rect.h * d_h_1) / req->dst_rect.h;
+			s_h_0 = req->src_rect.h - s_h_1;
+			s_y_1 = s_y_0 + s_h_0;
+			if (d_h_1 >= 8 * s_h_1) {
+				s_h_1++;
+				s_y_1--;
+			}
+		}
+
+		splitreq.src_rect.h = s_h_0;
+		splitreq.src_rect.y = s_y_0;
+		splitreq.dst_rect.h = d_h_0;
+		splitreq.dst_rect.y = d_y_0;
+		splitreq.src_rect.x = s_x_0;
+		splitreq.src_rect.w = s_w_0;
+		splitreq.dst_rect.x = d_x_0;
+		splitreq.dst_rect.w = d_w_0;
+	} else {
+
+		if (splitreq.flags & MDP_ROT_90) {
+			s_y_0 = s_y_1 = req->src_rect.y;
+			s_h_0 = s_h_1 = req->src_rect.h;
+			s_x_0 = req->src_rect.x;
+			s_w_1 = (req->src_rect.w * d_h_0) / req->dst_rect.h;
+			s_w_0 = req->src_rect.w - s_w_1;
+			s_x_1 = s_x_0 + s_w_0;
+			if (d_h_0 >= 8 * s_w_1) {
+				s_w_1++;
+				s_x_1--;
+			}
+		} else {
+			s_x_0 = s_x_1 = req->src_rect.x;
+			s_w_0 = s_w_1 = req->src_rect.w;
+			s_y_0 = req->src_rect.y;
+			s_h_1 = (req->src_rect.h * d_h_0) / req->dst_rect.h;
+			s_h_0 = req->src_rect.h - s_h_1;
+			s_y_1 = s_y_0 + s_h_0;
+			if (d_h_0 >= 8 * s_h_1) {
+				s_h_1++;
+				s_y_1--;
+			}
+		}
+		splitreq.src_rect.h = s_h_0;
+		splitreq.src_rect.y = s_y_0;
+		splitreq.dst_rect.h = d_h_1;
+		splitreq.dst_rect.y = d_y_1;
+		splitreq.src_rect.x = s_x_0;
+		splitreq.src_rect.w = s_w_0;
+		splitreq.dst_rect.x = d_x_1;
+		splitreq.dst_rect.w = d_w_1;
+	}
+	ret = mdp_ppp_blit(info, &splitreq);
+	if (ret)
+		return ret;
+
+	/* blit second region */
+	if (((splitreq.flags & 0x07) == 0x04) ||
+		((splitreq.flags & 0x07) == 0x0)) {
+		splitreq.src_rect.h = s_h_1;
+		splitreq.src_rect.y = s_y_1;
+		splitreq.dst_rect.h = d_h_1;
+		splitreq.dst_rect.y = d_y_1;
+		splitreq.src_rect.x = s_x_1;
+		splitreq.src_rect.w = s_w_1;
+		splitreq.dst_rect.x = d_x_1;
+		splitreq.dst_rect.w = d_w_1;
+	} else {
+		splitreq.src_rect.h = s_h_1;
+		splitreq.src_rect.y = s_y_1;
+		splitreq.dst_rect.h = d_h_0;
+		splitreq.dst_rect.y = d_y_0;
+		splitreq.src_rect.x = s_x_1;
+		splitreq.src_rect.w = s_w_1;
+		splitreq.dst_rect.x = d_x_0;
+		splitreq.dst_rect.w = d_w_0;
+	}
+	ret = mdp_ppp_blit(info, &splitreq);
+	return ret;
+}
+#endif
+
+int mdp_blit(struct fb_info *info, struct mdp_blit_req *req)
+{
+	int ret;
+#if defined CONFIG_FB_MSM_MDP31 || defined CONFIG_FB_MSM_MDP30
+	unsigned int remainder = 0, is_bpp_4 = 0;
+	struct mdp_blit_req splitreq;
+	int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1;
+	int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1;
+
+	if (req->flags & MDP_ROT_90) {
+		if (((req->dst_rect.h == 1) && ((req->src_rect.w != 1) ||
+			(req->dst_rect.w != req->src_rect.h))) ||
+			((req->dst_rect.w == 1) && ((req->src_rect.h != 1) ||
+			(req->dst_rect.h != req->src_rect.w)))) {
+			printk(KERN_ERR "mpd_ppp: error scaling when size is 1!\n");
+			return -EINVAL;
+		}
+	} else {
+		if (((req->dst_rect.w == 1) && ((req->src_rect.w != 1) ||
+			(req->dst_rect.h != req->src_rect.h))) ||
+			((req->dst_rect.h == 1) && ((req->src_rect.h != 1) ||
+			(req->dst_rect.w != req->src_rect.w)))) {
+			printk(KERN_ERR "mpd_ppp: error scaling when size is 1!\n");
+			return -EINVAL;
+		}
+	}
+#endif
+	if (unlikely(req->src_rect.h == 0 || req->src_rect.w == 0)) {
+		printk(KERN_ERR "mpd_ppp: src img of zero size!\n");
+		return -EINVAL;
+	}
+	if (unlikely(req->dst_rect.h == 0 || req->dst_rect.w == 0))
+		return 0;
+
+#if defined CONFIG_FB_MSM_MDP31
+	/* MDP width split workaround */
+	remainder = (req->dst_rect.w)%32;
+	ret = mdp_get_bytes_per_pixel(req->dst.format,
+					(struct msm_fb_data_type *)info->par);
+	if (ret <= 0) {
+		printk(KERN_ERR "mdp_ppp: incorrect bpp!\n");
+		return -EINVAL;
+	}
+	is_bpp_4 = (ret == 4) ? 1 : 0;
+
+	if ((is_bpp_4 && (remainder == 6 || remainder == 14 ||
+	remainder == 22 || remainder == 30)) || remainder == 3 ||
+	(remainder == 1 && req->dst_rect.w != 1) ||
+	(remainder == 2 && req->dst_rect.w != 2)) {
+		/* make new request as provide by user */
+		splitreq = *req;
+
+		/* break dest roi at width*/
+		d_y_0 = d_y_1 = req->dst_rect.y;
+		d_h_0 = d_h_1 = req->dst_rect.h;
+		d_x_0 = req->dst_rect.x;
+
+		if (remainder == 14)
+			d_w_1 = (req->dst_rect.w - 14) / 2 + 4;
+		else if (remainder == 22)
+			d_w_1 = (req->dst_rect.w - 22) / 2 + 10;
+		else if (remainder == 30)
+			d_w_1 = (req->dst_rect.w - 30) / 2 + 10;
+		else if (remainder == 6)
+			d_w_1 = req->dst_rect.w / 2 - 1;
+		else if (remainder == 3)
+			d_w_1 = (req->dst_rect.w - 3) / 2 - 1;
+		else if (remainder == 2)
+			d_w_1 = (req->dst_rect.w - 2) / 2 - 6;
+		else
+			d_w_1 = (req->dst_rect.w - 1) / 2 - 1;
+		d_w_0 = req->dst_rect.w - d_w_1;
+		d_x_1 = d_x_0 + d_w_0;
+		if (req->dst_rect.w == 3) {
+			d_w_1 = 2;
+			d_w_0 = 2;
+			d_x_1 = d_x_0 + 1;
+		}
+
+		/* blit first region */
+		if (((splitreq.flags & 0x07) == 0x07) ||
+			((splitreq.flags & 0x07) == 0x0)) {
+
+			if (splitreq.flags & MDP_ROT_90) {
+				s_x_0 = s_x_1 = req->src_rect.x;
+				s_w_0 = s_w_1 = req->src_rect.w;
+				s_y_0 = req->src_rect.y;
+				s_h_1 = (req->src_rect.h * d_w_1) /
+					req->dst_rect.w;
+				s_h_0 = req->src_rect.h - s_h_1;
+				s_y_1 = s_y_0 + s_h_0;
+				if (d_w_1 >= 8 * s_h_1) {
+					s_h_1++;
+					s_y_1--;
+				}
+			} else {
+				s_y_0 = s_y_1 = req->src_rect.y;
+				s_h_0 = s_h_1 = req->src_rect.h;
+				s_x_0 = req->src_rect.x;
+				s_w_1 = (req->src_rect.w * d_w_1) /
+					req->dst_rect.w;
+				s_w_0 = req->src_rect.w - s_w_1;
+				s_x_1 = s_x_0 + s_w_0;
+				if (d_w_1 >= 8 * s_w_1) {
+					s_w_1++;
+					s_x_1--;
+				}
+			}
+
+			splitreq.src_rect.h = s_h_0;
+			splitreq.src_rect.y = s_y_0;
+			splitreq.dst_rect.h = d_h_0;
+			splitreq.dst_rect.y = d_y_0;
+			splitreq.src_rect.x = s_x_0;
+			splitreq.src_rect.w = s_w_0;
+			splitreq.dst_rect.x = d_x_0;
+			splitreq.dst_rect.w = d_w_0;
+		} else {
+			if (splitreq.flags & MDP_ROT_90) {
+				s_x_0 = s_x_1 = req->src_rect.x;
+				s_w_0 = s_w_1 = req->src_rect.w;
+				s_y_0 = req->src_rect.y;
+				s_h_1 = (req->src_rect.h * d_w_0) /
+					req->dst_rect.w;
+				s_h_0 = req->src_rect.h - s_h_1;
+				s_y_1 = s_y_0 + s_h_0;
+				if (d_w_0 >= 8 * s_h_1) {
+					s_h_1++;
+					s_y_1--;
+				}
+			} else {
+				s_y_0 = s_y_1 = req->src_rect.y;
+				s_h_0 = s_h_1 = req->src_rect.h;
+				s_x_0 = req->src_rect.x;
+				s_w_1 = (req->src_rect.w * d_w_0) /
+					req->dst_rect.w;
+				s_w_0 = req->src_rect.w - s_w_1;
+				s_x_1 = s_x_0 + s_w_0;
+				if (d_w_0 >= 8 * s_w_1) {
+					s_w_1++;
+					s_x_1--;
+				}
+			}
+			splitreq.src_rect.h = s_h_0;
+			splitreq.src_rect.y = s_y_0;
+			splitreq.dst_rect.h = d_h_1;
+			splitreq.dst_rect.y = d_y_1;
+			splitreq.src_rect.x = s_x_0;
+			splitreq.src_rect.w = s_w_0;
+			splitreq.dst_rect.x = d_x_1;
+			splitreq.dst_rect.w = d_w_1;
+		}
+
+		if ((splitreq.dst_rect.h % 32 == 3) ||
+			((req->dst_rect.h % 32) == 1 && req->dst_rect.h != 1) ||
+			((req->dst_rect.h % 32) == 2 && req->dst_rect.h != 2))
+			ret = mdp_blit_split_height(info, &splitreq);
+		else
+			ret = mdp_ppp_blit(info, &splitreq);
+		if (ret)
+			return ret;
+		/* blit second region */
+		if (((splitreq.flags & 0x07) == 0x07) ||
+			((splitreq.flags & 0x07) == 0x0)) {
+			splitreq.src_rect.h = s_h_1;
+			splitreq.src_rect.y = s_y_1;
+			splitreq.dst_rect.h = d_h_1;
+			splitreq.dst_rect.y = d_y_1;
+			splitreq.src_rect.x = s_x_1;
+			splitreq.src_rect.w = s_w_1;
+			splitreq.dst_rect.x = d_x_1;
+			splitreq.dst_rect.w = d_w_1;
+		} else {
+			splitreq.src_rect.h = s_h_1;
+			splitreq.src_rect.y = s_y_1;
+			splitreq.dst_rect.h = d_h_0;
+			splitreq.dst_rect.y = d_y_0;
+			splitreq.src_rect.x = s_x_1;
+			splitreq.src_rect.w = s_w_1;
+			splitreq.dst_rect.x = d_x_0;
+			splitreq.dst_rect.w = d_w_0;
+		}
+		if (((splitreq.dst_rect.h % 32) == 3) ||
+			((req->dst_rect.h % 32) == 1 && req->dst_rect.h != 1) ||
+			((req->dst_rect.h % 32) == 2 && req->dst_rect.h != 2))
+			ret = mdp_blit_split_height(info, &splitreq);
+		else
+			ret = mdp_ppp_blit(info, &splitreq);
+		if (ret)
+			return ret;
+	} else if ((req->dst_rect.h % 32) == 3 ||
+		((req->dst_rect.h % 32) == 1 && req->dst_rect.h != 1) ||
+		((req->dst_rect.h % 32) == 2 && req->dst_rect.h != 2))
+		ret = mdp_blit_split_height(info, req);
+	else
+		ret = mdp_ppp_blit(info, req);
+	return ret;
+#elif defined CONFIG_FB_MSM_MDP30
+	/* MDP width split workaround */
+	remainder = (req->dst_rect.w)%16;
+	ret = mdp_get_bytes_per_pixel(req->dst.format,
+					(struct msm_fb_data_type *)info->par);
+	if (ret <= 0) {
+		printk(KERN_ERR "mdp_ppp: incorrect bpp!\n");
+		return -EINVAL;
+	}
+	is_bpp_4 = (ret == 4) ? 1 : 0;
+
+	if ((is_bpp_4 && (remainder == 6 || remainder == 14))) {
+
+		/* make new request as provide by user */
+		splitreq = *req;
+
+		/* break dest roi at width*/
+		d_y_0 = d_y_1 = req->dst_rect.y;
+		d_h_0 = d_h_1 = req->dst_rect.h;
+		d_x_0 = req->dst_rect.x;
+
+		if (remainder == 14 || remainder == 6)
+			d_w_1 = req->dst_rect.w / 2;
+		else
+			d_w_1 = (req->dst_rect.w - 1) / 2 - 1;
+
+		d_w_0 = req->dst_rect.w - d_w_1;
+		d_x_1 = d_x_0 + d_w_0;
+
+		/* blit first region */
+		if (((splitreq.flags & 0x07) == 0x07) ||
+			((splitreq.flags & 0x07) == 0x0)) {
+
+			if (splitreq.flags & MDP_ROT_90) {
+				s_x_0 = s_x_1 = req->src_rect.x;
+				s_w_0 = s_w_1 = req->src_rect.w;
+				s_y_0 = req->src_rect.y;
+				s_h_1 = (req->src_rect.h * d_w_1) /
+					req->dst_rect.w;
+				s_h_0 = req->src_rect.h - s_h_1;
+				s_y_1 = s_y_0 + s_h_0;
+				if (d_w_1 >= 8 * s_h_1) {
+					s_h_1++;
+					s_y_1--;
+				}
+			} else {
+				s_y_0 = s_y_1 = req->src_rect.y;
+				s_h_0 = s_h_1 = req->src_rect.h;
+				s_x_0 = req->src_rect.x;
+				s_w_1 = (req->src_rect.w * d_w_1) /
+					req->dst_rect.w;
+				s_w_0 = req->src_rect.w - s_w_1;
+				s_x_1 = s_x_0 + s_w_0;
+				if (d_w_1 >= 8 * s_w_1) {
+					s_w_1++;
+					s_x_1--;
+				}
+			}
+
+			splitreq.src_rect.h = s_h_0;
+			splitreq.src_rect.y = s_y_0;
+			splitreq.dst_rect.h = d_h_0;
+			splitreq.dst_rect.y = d_y_0;
+			splitreq.src_rect.x = s_x_0;
+			splitreq.src_rect.w = s_w_0;
+			splitreq.dst_rect.x = d_x_0;
+			splitreq.dst_rect.w = d_w_0;
+		} else {
+			if (splitreq.flags & MDP_ROT_90) {
+				s_x_0 = s_x_1 = req->src_rect.x;
+				s_w_0 = s_w_1 = req->src_rect.w;
+				s_y_0 = req->src_rect.y;
+				s_h_1 = (req->src_rect.h * d_w_0) /
+					req->dst_rect.w;
+				s_h_0 = req->src_rect.h - s_h_1;
+				s_y_1 = s_y_0 + s_h_0;
+				if (d_w_0 >= 8 * s_h_1) {
+					s_h_1++;
+					s_y_1--;
+				}
+			} else {
+				s_y_0 = s_y_1 = req->src_rect.y;
+				s_h_0 = s_h_1 = req->src_rect.h;
+				s_x_0 = req->src_rect.x;
+				s_w_1 = (req->src_rect.w * d_w_0) /
+					req->dst_rect.w;
+				s_w_0 = req->src_rect.w - s_w_1;
+				s_x_1 = s_x_0 + s_w_0;
+				if (d_w_0 >= 8 * s_w_1) {
+					s_w_1++;
+					s_x_1--;
+				}
+			}
+			splitreq.src_rect.h = s_h_0;
+			splitreq.src_rect.y = s_y_0;
+			splitreq.dst_rect.h = d_h_1;
+			splitreq.dst_rect.y = d_y_1;
+			splitreq.src_rect.x = s_x_0;
+			splitreq.src_rect.w = s_w_0;
+			splitreq.dst_rect.x = d_x_1;
+			splitreq.dst_rect.w = d_w_1;
+		}
+
+		/* No need to split in height */
+		ret = mdp_ppp_blit(info, &splitreq);
 
 		if (ret)
 			return ret;
+
+		/* blit second region */
+		if (((splitreq.flags & 0x07) == 0x07) ||
+			((splitreq.flags & 0x07) == 0x0)) {
+			splitreq.src_rect.h = s_h_1;
+			splitreq.src_rect.y = s_y_1;
+			splitreq.dst_rect.h = d_h_1;
+			splitreq.dst_rect.y = d_y_1;
+			splitreq.src_rect.x = s_x_1;
+			splitreq.src_rect.w = s_w_1;
+			splitreq.dst_rect.x = d_x_1;
+			splitreq.dst_rect.w = d_w_1;
+		} else {
+			splitreq.src_rect.h = s_h_1;
+			splitreq.src_rect.y = s_y_1;
+			splitreq.dst_rect.h = d_h_0;
+			splitreq.dst_rect.y = d_y_0;
+			splitreq.src_rect.x = s_x_1;
+			splitreq.src_rect.w = s_w_1;
+			splitreq.dst_rect.x = d_x_0;
+			splitreq.dst_rect.w = d_w_0;
+		}
+
+		/* No need to split in height ... just width */
+		ret = mdp_ppp_blit(info, &splitreq);
+
+		if (ret)
+			return ret;
+
+	} else
+		ret = mdp_ppp_blit(info, req);
+	return ret;
+#else
+	ret = mdp_ppp_blit(info, req);
+	return ret;
+#endif
+}
+
+typedef void (*msm_dma_barrier_function_pointer) (void *, size_t);
+
+static inline void msm_fb_dma_barrier_for_rect(struct fb_info *info,
+			struct mdp_img *img, struct mdp_rect *rect,
+			msm_dma_barrier_function_pointer dma_barrier_fp
+			)
+{
+	/*
+	 * Compute the start and end addresses of the rectangles.
+	 * NOTE: As currently implemented, the data between
+	 *       the end of one row and the start of the next is
+	 *       included in the address range rather than
+	 *       doing multiple calls for each row.
+	 */
+	unsigned long start;
+	size_t size;
+	char * const pmem_start = info->screen_base;
+	int bytes_per_pixel = mdp_get_bytes_per_pixel(img->format,
+					(struct msm_fb_data_type *)info->par);
+	if (bytes_per_pixel <= 0) {
+		printk(KERN_ERR "%s incorrect bpp!\n", __func__);
+		return;
+	}
+	start = (unsigned long)pmem_start + img->offset +
+		(img->width * rect->y + rect->x) * bytes_per_pixel;
+	size  = (rect->h * img->width + rect->w) * bytes_per_pixel;
+	(*dma_barrier_fp) ((void *) start, size);
+
+}
+
+static inline void msm_dma_nc_pre(void)
+{
+	dmb();
+}
+static inline void msm_dma_wt_pre(void)
+{
+	dmb();
+}
+static inline void msm_dma_todevice_wb_pre(void *start, size_t size)
+{
+	dma_cache_pre_ops(start, size, DMA_TO_DEVICE);
+}
+
+static inline void msm_dma_fromdevice_wb_pre(void *start, size_t size)
+{
+	dma_cache_pre_ops(start, size, DMA_FROM_DEVICE);
+}
+
+static inline void msm_dma_nc_post(void)
+{
+	dmb();
+}
+
+static inline void msm_dma_fromdevice_wt_post(void *start, size_t size)
+{
+	dma_cache_post_ops(start, size, DMA_FROM_DEVICE);
+}
+
+static inline void msm_dma_todevice_wb_post(void *start, size_t size)
+{
+	dma_cache_post_ops(start, size, DMA_TO_DEVICE);
+}
+
+static inline void msm_dma_fromdevice_wb_post(void *start, size_t size)
+{
+	dma_cache_post_ops(start, size, DMA_FROM_DEVICE);
+}
+
+/*
+ * Do the write barriers required to guarantee data is committed to RAM
+ * (from CPU cache or internal buffers) before a DMA operation starts.
+ * NOTE: As currently implemented, the data between
+ *       the end of one row and the start of the next is
+ *       included in the address range rather than
+ *       doing multiple calls for each row.
+*/
+static void msm_fb_ensure_memory_coherency_before_dma(struct fb_info *info,
+		struct mdp_blit_req *req_list,
+		int req_list_count)
+{
+#ifdef CONFIG_ARCH_QSD8X50
+	int i;
+
+	/*
+	 * Normally, do the requested barriers for each address
+	 * range that corresponds to a rectangle.
+	 *
+	 * But if at least one write barrier is requested for data
+	 * going to or from the device but no address range is
+	 * needed for that barrier, then do the barrier, but do it
+	 * only once, no matter how many requests there are.
+	 */
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	switch (mfd->mdp_fb_page_protection)	{
+	default:
+	case MDP_FB_PAGE_PROTECTION_NONCACHED:
+	case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
+		/*
+		 * The following barrier is only done at most once,
+		 * since further calls would be redundant.
+		 */
+		for (i = 0; i < req_list_count; i++) {
+			if (!(req_list[i].flags
+				& MDP_NO_DMA_BARRIER_START)) {
+				msm_dma_nc_pre();
+				break;
+			}
+		}
+		break;
+
+	case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
+		/*
+		 * The following barrier is only done at most once,
+		 * since further calls would be redundant.
+		 */
+		for (i = 0; i < req_list_count; i++) {
+			if (!(req_list[i].flags
+				& MDP_NO_DMA_BARRIER_START)) {
+				msm_dma_wt_pre();
+				break;
+			}
+		}
+		break;
+
+	case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
+	case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
+		for (i = 0; i < req_list_count; i++) {
+			if (!(req_list[i].flags &
+					MDP_NO_DMA_BARRIER_START)) {
+
+				msm_fb_dma_barrier_for_rect(info,
+						&(req_list[i].src),
+						&(req_list[i].src_rect),
+						msm_dma_todevice_wb_pre
+						);
+
+				msm_fb_dma_barrier_for_rect(info,
+						&(req_list[i].dst),
+						&(req_list[i].dst_rect),
+						msm_dma_todevice_wb_pre
+						);
+			}
+		}
+		break;
+	}
+#else
+	dmb();
+#endif
+}
+
+
+/*
+ * Do the write barriers required to guarantee data will be re-read from RAM by
+ * the CPU after a DMA operation ends.
+ * NOTE: As currently implemented, the data between
+ *       the end of one row and the start of the next is
+ *       included in the address range rather than
+ *       doing multiple calls for each row.
+*/
+static void msm_fb_ensure_memory_coherency_after_dma(struct fb_info *info,
+		struct mdp_blit_req *req_list,
+		int req_list_count)
+{
+#ifdef CONFIG_ARCH_QSD8X50
+	int i;
+
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	switch (mfd->mdp_fb_page_protection)	{
+	default:
+	case MDP_FB_PAGE_PROTECTION_NONCACHED:
+	case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
+		/*
+		 * The following barrier is only done at most once,
+		 * since further calls would be redundant.
+		 */
+		for (i = 0; i < req_list_count; i++) {
+			if (!(req_list[i].flags
+				& MDP_NO_DMA_BARRIER_END)) {
+				msm_dma_nc_post();
+				break;
+			}
+		}
+		break;
+
+	case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
+		for (i = 0; i < req_list_count; i++) {
+			if (!(req_list[i].flags &
+					MDP_NO_DMA_BARRIER_END)) {
+
+				msm_fb_dma_barrier_for_rect(info,
+						&(req_list[i].dst),
+						&(req_list[i].dst_rect),
+						msm_dma_fromdevice_wt_post
+						);
+			}
+		}
+		break;
+	case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
+	case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
+		for (i = 0; i < req_list_count; i++) {
+			if (!(req_list[i].flags &
+					MDP_NO_DMA_BARRIER_END)) {
+
+				msm_fb_dma_barrier_for_rect(info,
+						&(req_list[i].dst),
+						&(req_list[i].dst_rect),
+						msm_dma_fromdevice_wb_post
+						);
+			}
+		}
+		break;
+	}
+#else
+	dmb();
+#endif
+}
+
+/*
+ * NOTE: The userspace issues blit operations in a sequence, the sequence
+ * start with a operation marked START and ends in an operation marked
+ * END. It is guranteed by the userspace that all the blit operations
+ * between START and END are only within the regions of areas designated
+ * by the START and END operations and that the userspace doesnt modify
+ * those areas. Hence it would be enough to perform barrier/cache operations
+ * only on the START and END operations.
+ */
+static int msmfb_blit(struct fb_info *info, void __user *p)
+{
+	/*
+	 * CAUTION: The names of the struct types intentionally *DON'T* match
+	 * the names of the variables declared -- they appear to be swapped.
+	 * Read the code carefully and you should see that the variable names
+	 * make sense.
+	 */
+	const int MAX_LIST_WINDOW = 16;
+	struct mdp_blit_req req_list[MAX_LIST_WINDOW];
+	struct mdp_blit_req_list req_list_header;
+
+	int count, i, req_list_count;
+	if (bf_supported &&
+		(info->node == 1 || info->node == 2)) {
+		pr_err("%s: no pan display for fb%d.",
+		       __func__, info->node);
+		return -EPERM;
+	}
+	/* Get the count size for the total BLIT request. */
+	if (copy_from_user(&req_list_header, p, sizeof(req_list_header)))
+		return -EFAULT;
+	p += sizeof(req_list_header);
+	count = req_list_header.count;
+	if (count < 0 || count >= MAX_BLIT_REQ)
+		return -EINVAL;
+	while (count > 0) {
+		/*
+		 * Access the requests through a narrow window to decrease copy
+		 * overhead and make larger requests accessible to the
+		 * coherency management code.
+		 * NOTE: The window size is intended to be larger than the
+		 *       typical request size, but not require more than 2
+		 *       kbytes of stack storage.
+		 */
+		req_list_count = count;
+		if (req_list_count > MAX_LIST_WINDOW)
+			req_list_count = MAX_LIST_WINDOW;
+		if (copy_from_user(&req_list, p,
+				sizeof(struct mdp_blit_req)*req_list_count))
+			return -EFAULT;
+
+		/*
+		 * Ensure that any data CPU may have previously written to
+		 * internal state (but not yet committed to memory) is
+		 * guaranteed to be committed to memory now.
+		 */
+		msm_fb_ensure_memory_coherency_before_dma(info,
+				req_list, req_list_count);
+
+		/*
+		 * Do the blit DMA, if required -- returning early only if
+		 * there is a failure.
+		 */
+		for (i = 0; i < req_list_count; i++) {
+			if (!(req_list[i].flags & MDP_NO_BLIT)) {
+				/* Do the actual blit. */
+				int ret = mdp_blit(info, &(req_list[i]));
+
+				/*
+				 * Note that early returns don't guarantee
+				 * memory coherency.
+				 */
+				if (ret)
+					return ret;
+			}
+		}
+
+		/*
+		 * Ensure that CPU cache and other internal CPU state is
+		 * updated to reflect any change in memory modified by MDP blit
+		 * DMA.
+		 */
+		msm_fb_ensure_memory_coherency_after_dma(info,
+				req_list,
+				req_list_count);
+
+		/* Go to next window of requests. */
+		count -= req_list_count;
+		p += sizeof(struct mdp_blit_req)*req_list_count;
 	}
 	return 0;
 }
+
+static int msmfb_vsync_ctrl(struct fb_info *info, void __user *argp)
+{
+	int enable, ret;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	ret = copy_from_user(&enable, argp, sizeof(enable));
+	if (ret) {
+		pr_err("%s:msmfb_overlay_vsync ioctl failed", __func__);
+		return ret;
+	}
+
+	if (mfd->vsync_ctrl)
+		mfd->vsync_ctrl(enable);
+	else {
+		pr_err("%s: Vsync IOCTL not supported", __func__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 #ifdef CONFIG_FB_MSM_OVERLAY
 static int msmfb_overlay_get(struct fb_info *info, void __user *p)
 {
@@ -752,15 +2778,14 @@
 	if (copy_from_user(&req, p, sizeof(req)))
 		return -EFAULT;
 
-	ret = mdp->overlay_get(mdp, info, &req);
-
+	ret = mdp4_overlay_get(info, &req);
 	if (ret) {
-		PR_DISP_ERR("%s: ioctl failed \n",
+		printk(KERN_ERR "%s: ioctl failed \n",
 			__func__);
 		return ret;
 	}
 	if (copy_to_user(p, &req, sizeof(req))) {
-		PR_DISP_ERR("%s: copy2user failed \n",
+		printk(KERN_ERR "%s: copy2user failed \n",
 			__func__);
 		return -EFAULT;
 	}
@@ -771,31 +2796,20 @@
 static int msmfb_overlay_set(struct fb_info *info, void __user *p)
 {
 	struct mdp_overlay req;
-	int ret, sem_owned;
+	int ret;
 
 	if (copy_from_user(&req, p, sizeof(req)))
 		return -EFAULT;
 
-	PR_DISP_INFO("%s(%d) dst rect info w=%d h=%d x=%d y=%d rotator=%d\n", __func__, __LINE__, req.dst_rect.w, req.dst_rect.h, req.dst_rect.x, req.dst_rect.y, req.user_data[0]);
-
-	sem_owned = overlay_semaphore_lock();
-	/* Used the following mutex to make sure that overlay play/set will not do at the same time */
-	/* It assume overlay play can complete in fixed time */
-	mutex_lock(&overlay_ioctl_mutex);
-	ret = mdp->overlay_set(mdp, info, &req);
-	mutex_unlock(&overlay_ioctl_mutex);
-
-	if (sem_owned == 0)
-		overlay_semaphore_unlock();
-
+	ret = mdp4_overlay_set(info, &req);
 	if (ret) {
-		PR_DISP_ERR("%s:ioctl failed \n",
-			__func__);
+		printk(KERN_ERR "%s: ioctl failed, rc=%d\n",
+			__func__, ret);
 		return ret;
 	}
 
 	if (copy_to_user(p, &req, sizeof(req))) {
-		PR_DISP_ERR("%s: copy2user failed \n",
+		printk(KERN_ERR "%s: copy2user failed \n",
 			__func__);
 		return -EFAULT;
 	}
@@ -805,21 +2819,50 @@
 
 static int msmfb_overlay_unset(struct fb_info *info, unsigned long *argp)
 {
-	int	ret, ndx;
+	int ret, ndx;
 
 	ret = copy_from_user(&ndx, argp, sizeof(ndx));
 	if (ret) {
-		PR_DISP_ERR("%s:msmfb_overlay_unset ioctl failed \n",
+		printk(KERN_ERR "%s:msmfb_overlay_unset ioctl failed \n",
 			__func__);
 		return ret;
 	}
 
-	/* Used the following mutex to make sure that overlay play/set/unset will not do at the same time */
-	/* Otherwise we met the mdp4_overlay_play()->mdp4_overlay_vg_setup() which try to access the pipe free
-	in mdp4_overlay_unset()->mdp4_overlay_*/
-	mutex_lock(&overlay_ioctl_mutex);
-	ret = mdp->overlay_unset(mdp, info, ndx);
-	mutex_unlock(&overlay_ioctl_mutex);
+	return mdp4_overlay_unset(info, ndx);
+}
+
+static int msmfb_overlay_vsync_ctrl(struct fb_info *info, void __user *argp)
+{
+	int ret;
+	int enable;
+
+	ret = copy_from_user(&enable, argp, sizeof(enable));
+	if (ret) {
+		pr_err("%s:msmfb_overlay_vsync ioctl failed", __func__);
+		return ret;
+	}
+
+	ret = mdp4_overlay_vsync_ctrl(info, enable);
+
+	return ret;
+}
+
+static int msmfb_overlay_play_wait(struct fb_info *info, unsigned long *argp)
+{
+	int ret;
+	struct msmfb_overlay_data req;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	if (mfd->overlay_play_enable == 0)      /* nothing to do */
+		return 0;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		pr_err("%s:msmfb_overlay_wait ioctl failed", __func__);
+		return ret;
+	}
+
+	ret = mdp4_overlay_play_wait(info, &req);
 
 	return ret;
 }
@@ -828,692 +2871,960 @@
 {
 	int	ret;
 	struct msmfb_overlay_data req;
-	struct file *p_src_file = 0;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct msm_fb_panel_data *pdata;
+
+	if (mfd->overlay_play_enable == 0)	/* nothing to do */
+		return 0;
 
 	ret = copy_from_user(&req, argp, sizeof(req));
 	if (ret) {
-		PR_DISP_ERR("%s:msmfb_overlay_play ioctl failed \n",
+		printk(KERN_ERR "%s:msmfb_overlay_play ioctl failed \n",
 			__func__);
 		return ret;
 	}
 
-	/* Used the following mutex to make sure that overlay play/set will not do at the same time */
-	mutex_lock(&overlay_ioctl_mutex);
-	ret = mdp->overlay_play(mdp, info, &req, &p_src_file);
-	mutex_unlock(&overlay_ioctl_mutex);
+	complete(&mfd->msmfb_update_notify);
+	mutex_lock(&msm_fb_notify_update_sem);
+	if (mfd->msmfb_no_update_notify_timer.function)
+		del_timer(&mfd->msmfb_no_update_notify_timer);
 
-	if (p_src_file)
-		put_pmem_file(p_src_file);
+	mfd->msmfb_no_update_notify_timer.expires =
+				jiffies + ((1000 * HZ) / 1000);
+	add_timer(&mfd->msmfb_no_update_notify_timer);
+	mutex_unlock(&msm_fb_notify_update_sem);
+
+	if (info->node == 0 && !(mfd->cont_splash_done)) { /* primary */
+		mdp_set_dma_pan_info(info, NULL, TRUE);
+		if (msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable)) {
+			pr_err("%s: can't turn on display!\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	ret = mdp4_overlay_play(info, &req);
+
+	if (unset_bl_level && !bl_updated) {
+		pdata = (struct msm_fb_panel_data *)mfd->pdev->
+			dev.platform_data;
+		if ((pdata) && (pdata->set_backlight)) {
+			down(&mfd->sem);
+			mfd->bl_level = unset_bl_level;
+			pdata->set_backlight(mfd);
+			bl_level_old = unset_bl_level;
+			up(&mfd->sem);
+			bl_updated = 1;
+		}
+	}
 
 	return ret;
 }
 
-#ifdef CONFIG_FB_MSM_WRITE_BACK
+static int msmfb_overlay_play_enable(struct fb_info *info, unsigned long *argp)
+{
+	int	ret, enable;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	ret = copy_from_user(&enable, argp, sizeof(enable));
+	if (ret) {
+		printk(KERN_ERR "%s:msmfb_overlay_play_enable ioctl failed \n",
+			__func__);
+		return ret;
+	}
+
+	mfd->overlay_play_enable = enable;
+
+	return 0;
+}
+
 static int msmfb_overlay_blt(struct fb_info *info, unsigned long *argp)
 {
 	int     ret;
 	struct msmfb_overlay_blt req;
-	struct file *p_src_file = 0;
+
 	ret = copy_from_user(&req, argp, sizeof(req));
 	if (ret) {
-		PR_DISP_ERR("%s:msmfb_overlay_blt ioctl failed\n",
-			__func__);
+		pr_err("%s: failed\n", __func__);
 		return ret;
 	}
 
-	ret = mdp4_overlay_blt(mdp, info, &req, &p_src_file);
-
-	if (p_src_file)
-		put_pmem_file(p_src_file);
+	ret = mdp4_overlay_blt(info, &req);
 
 	return ret;
 }
+
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+static int msmfb_overlay_ioctl_writeback_init(struct fb_info *info)
+{
+	return mdp4_writeback_init(info);
+}
+static int msmfb_overlay_ioctl_writeback_start(
+		struct fb_info *info)
+{
+	int ret = 0;
+	ret = mdp4_writeback_start(info);
+	if (ret)
+		goto error;
+error:
+	if (ret)
+		pr_err("%s:msmfb_writeback_start "
+				" ioctl failed\n", __func__);
+	return ret;
+}
+
+static int msmfb_overlay_ioctl_writeback_stop(
+		struct fb_info *info)
+{
+	int ret = 0;
+	ret = mdp4_writeback_stop(info);
+	if (ret)
+		goto error;
+
+error:
+	if (ret)
+		pr_err("%s:msmfb_writeback_stop ioctl failed\n",
+				__func__);
+	return ret;
+}
+
+static int msmfb_overlay_ioctl_writeback_queue_buffer(
+		struct fb_info *info, unsigned long *argp)
+{
+	int ret = 0;
+	struct msmfb_data data;
+
+	ret = copy_from_user(&data, argp, sizeof(data));
+	if (ret)
+		goto error;
+
+	ret = mdp4_writeback_queue_buffer(info, &data);
+	if (ret)
+		goto error;
+
+error:
+	if (ret)
+		pr_err("%s:msmfb_writeback_queue_buffer ioctl failed\n",
+				__func__);
+	return ret;
+}
+
+static int msmfb_overlay_ioctl_writeback_dequeue_buffer(
+		struct fb_info *info, unsigned long *argp)
+{
+	int ret = 0;
+	struct msmfb_data data;
+
+	ret = copy_from_user(&data, argp, sizeof(data));
+	if (ret)
+		goto error;
+
+	ret = mdp4_writeback_dequeue_buffer(info, &data);
+	if (ret)
+		goto error;
+
+	ret = copy_to_user(argp, &data, sizeof(data));
+	if (ret)
+		goto error;
+
+error:
+	if (ret)
+		pr_err("%s:msmfb_writeback_dequeue_buffer ioctl failed\n",
+				__func__);
+	return ret;
+}
+static int msmfb_overlay_ioctl_writeback_terminate(struct fb_info *info)
+{
+	return mdp4_writeback_terminate(info);
+}
+
+#else
+static int msmfb_overlay_ioctl_writeback_init(struct fb_info *info)
+{
+	return -ENOTSUPP;
+}
+static int msmfb_overlay_ioctl_writeback_start(
+		struct fb_info *info)
+{
+	return -ENOTSUPP;
+}
+
+static int msmfb_overlay_ioctl_writeback_stop(
+		struct fb_info *info)
+{
+	return -ENOTSUPP;
+}
+
+static int msmfb_overlay_ioctl_writeback_queue_buffer(
+		struct fb_info *info, unsigned long *argp)
+{
+	return -ENOTSUPP;
+}
+
+static int msmfb_overlay_ioctl_writeback_dequeue_buffer(
+		struct fb_info *info, unsigned long *argp)
+{
+	return -ENOTSUPP;
+}
+static int msmfb_overlay_ioctl_writeback_terminate(struct fb_info *info)
+{
+	return -ENOTSUPP;
+}
 #endif
 
-static int msmfb_overlay_change_z_order_vg_pipes(struct fb_info *info, unsigned long *argp)
+static int msmfb_overlay_3d_sbys(struct fb_info *info, unsigned long *argp)
 {
 	int	ret;
+	struct msmfb_overlay_3d req;
 
-	ret = mdp4_overlay_change_z_order_vg_pipes(info);
-
+	ret = copy_from_user(&req, argp, sizeof(req));
 	if (ret) {
-		PR_DISP_ERR("%s:msmfb_overlay_change_z_order_vg_pipes ioctl failed \n",
+		pr_err("%s:msmfb_overlay_3d_ctrl ioctl failed\n",
 			__func__);
 		return ret;
 	}
 
+	ret = mdp4_overlay_3d_sbys(info, &req);
 
 	return ret;
 }
+
+static int msmfb_mixer_info(struct fb_info *info, unsigned long *argp)
+{
+	int     ret, cnt;
+	struct msmfb_mixer_info_req req;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		pr_err("%s: failed\n", __func__);
+		return ret;
+	}
+
+	cnt = mdp4_mixer_info(req.mixer_num, req.info);
+	req.cnt = cnt;
+	ret = copy_to_user(argp, &req, sizeof(req));
+	if (ret)
+		pr_err("%s:msmfb_overlay_blt_off ioctl failed\n",
+		__func__);
+
+	return cnt;
+}
+
 #endif
 
 DECLARE_MUTEX(msm_fb_ioctl_ppp_sem);
-#if defined(CONFIG_FB_MSM_MDP_ABL)
 DEFINE_MUTEX(msm_fb_ioctl_lut_sem);
-DEFINE_MUTEX(msm_fb_ioctl_hist_sem);
 
-static int msmfb_lut_update(struct fb_info *info, void __user *p)
+/* Set color conversion matrix from user space */
+
+#ifndef CONFIG_FB_MSM_MDP40
+static void msmfb_set_color_conv(struct mdp_ccs *p)
 {
-	struct fb_cmap cmap;
-	int ret;
-
-	if (copy_from_user(&cmap, p, sizeof(cmap)))
-		return -EFAULT;
-
-	mutex_lock(&msm_fb_ioctl_lut_sem);
-
-	ret = mdp->lut_update(mdp, info, &cmap);
-
-	mutex_unlock(&msm_fb_ioctl_lut_sem);
-
-	if (ret) {
-		PR_DISP_ERR("%s: ioctl failed \n",
-			__func__);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int msmfb_do_histogram(struct fb_info *info, void __user *p)
-{
-	struct mdp_histogram hist;
-	struct mdp_histogram out;
-	int ret;
-
-	if (copy_from_user(&hist, p, sizeof(hist)))
-		return -EFAULT;
-
-	mutex_lock(&msm_fb_ioctl_hist_sem);
-	ret = mdp->do_histogram(mdp, &hist, &out);
-	mutex_unlock(&msm_fb_ioctl_hist_sem);
-
-	if (ret) {
-		PR_DISP_ERR("%s: ioctl failed \n",
-			__func__);
-		return ret;
-	}
-
-	if (hist.r) {
-		ret = copy_to_user(hist.r, out.r, hist.bin_cnt * 4);
-		if (ret)
-			goto hist_err;
-	}
-	if (hist.g) {
-		ret = copy_to_user(hist.g, out.g, hist.bin_cnt * 4);
-		if (ret)
-			goto hist_err;
-	}
-	if (hist.b) {
-		ret = copy_to_user(hist.b, out.b, hist.bin_cnt * 4);
-		if (ret)
-			goto hist_err;
-	}
-	return 0;
-
-hist_err:
-	PR_DISP_ERR("%s: invalid hist buffer\n", __func__);
-	return ret;
-
-}
-
-static int msmfb_get_gamma_curvy(struct fb_info *info, void __user *p)
-{
-	struct gamma_curvy gc;
-	int ret;
-
-	if (!mdp->get_gamma_curvy) {
-		PR_DISP_INFO("error to get get_gamma_curvy functoin\n");
-		return -EFAULT;
-	}
-
-	if (copy_from_user(&gc, p, sizeof(struct gamma_curvy)))
-		return -EFAULT;
-
-	ret = mdp->get_gamma_curvy(mdp, &gc);
-
-	if (ret) {
-		PR_DISP_ERR("%s: ioctl failed \n",
-			__func__);
-		return ret;
-	}
-	ret = copy_to_user(p, &gc, sizeof(struct gamma_curvy));
-
-	return ret;
-}
-#endif
-
-DEFINE_MUTEX(mdp_ppp_lock);
-
-static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg)
-{
-	void __user *argp = (void __user *)arg;
-	int ret = 0;
-#if PRINT_BLIT_TIME
-	ktime_t t1, t2;
-#endif
-
-#if defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)
 	int i;
-	struct msmfb_usb_projector_info tmp_info;
-	static int pmem_mapped = 0;
+
+	if (p->direction == MDP_CCS_RGB2YUV) {
+		/* MDP cmd block enable */
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+		/* RGB->YUV primary forward matrix */
+		for (i = 0; i < MDP_CCS_SIZE; i++)
+			writel(p->ccs[i], MDP_CSC_PFMVn(i));
+
+		#ifdef CONFIG_FB_MSM_MDP31
+		for (i = 0; i < MDP_BV_SIZE; i++)
+			writel(p->bv[i], MDP_CSC_POST_BV2n(i));
+		#endif
+
+		/* MDP cmd block disable */
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	} else {
+		/* MDP cmd block enable */
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+		/* YUV->RGB primary reverse matrix */
+		for (i = 0; i < MDP_CCS_SIZE; i++)
+			writel(p->ccs[i], MDP_CSC_PRMVn(i));
+		for (i = 0; i < MDP_BV_SIZE; i++)
+			writel(p->bv[i], MDP_CSC_PRE_BV1n(i));
+
+		/* MDP cmd block disable */
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	}
+}
+#else
+static void msmfb_set_color_conv(struct mdp_csc *p)
+{
+	mdp4_vg_csc_update(p);
+}
 #endif
 
+static int msmfb_notify_update(struct fb_info *info, unsigned long *argp)
+{
+	int ret, notify;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	ret = copy_from_user(&notify, argp, sizeof(int));
+	if (ret) {
+		pr_err("%s:ioctl failed\n", __func__);
+		return ret;
+	}
+
+	if (notify > NOTIFY_UPDATE_STOP)
+		return -EINVAL;
+
+	if (notify == NOTIFY_UPDATE_START) {
+		INIT_COMPLETION(mfd->msmfb_update_notify);
+		wait_for_completion_interruptible(&mfd->msmfb_update_notify);
+	} else {
+		INIT_COMPLETION(mfd->msmfb_no_update_notify);
+		wait_for_completion_interruptible(&mfd->msmfb_no_update_notify);
+	}
+	return 0;
+}
+
+static int msmfb_handle_pp_ioctl(struct msm_fb_data_type *mfd,
+						struct msmfb_mdp_pp *pp_ptr)
+{
+	int ret = -1;
+
+	if (!pp_ptr)
+		return ret;
+
+	switch (pp_ptr->op) {
+#ifdef CONFIG_FB_MSM_MDP40
+	case mdp_op_csc_cfg:
+		ret = mdp4_csc_config(&(pp_ptr->data.csc_cfg_data));
+		break;
+
+	case mdp_op_pcc_cfg:
+		ret = mdp4_pcc_cfg(&(pp_ptr->data.pcc_cfg_data));
+		break;
+
+	case mdp_op_lut_cfg:
+		switch (pp_ptr->data.lut_cfg_data.lut_type) {
+		case mdp_lut_igc:
+			ret = mdp4_igc_lut_config(
+					(struct mdp_igc_lut_data *)
+					&pp_ptr->data.lut_cfg_data.data);
+			break;
+
+		case mdp_lut_pgc:
+			ret = mdp4_argc_cfg(
+				&pp_ptr->data.lut_cfg_data.data.pgc_lut_data);
+			break;
+
+		case mdp_lut_hist:
+			ret = mdp_hist_lut_config(
+					(struct mdp_hist_lut_data *)
+					&pp_ptr->data.lut_cfg_data.data);
+			break;
+
+		default:
+			break;
+		}
+		break;
+#endif
+	case mdp_bl_scale_cfg:
+		ret = mdp_bl_scale_config(mfd, (struct mdp_bl_scale_data *)
+				&pp_ptr->data.bl_scale_data);
+		break;
+
+	default:
+		pr_warn("Unsupported request to MDP_PP IOCTL.\n");
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd,
+			unsigned long arg)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	void __user *argp = (void __user *)arg;
+	struct fb_cursor cursor;
+	struct fb_cmap cmap;
+	struct mdp_histogram_data hist;
+	struct mdp_histogram_start_req hist_req;
+	uint32_t block;
+#ifndef CONFIG_FB_MSM_MDP40
+	struct mdp_ccs ccs_matrix;
+#else
+	struct mdp_csc csc_matrix;
+#endif
+	struct mdp_page_protection fb_page_protection;
+	struct msmfb_mdp_pp mdp_pp;
+	int ret = 0;
+
 	switch (cmd) {
-	case MSMFB_GRP_DISP:
-		mdp->set_grp_disp(mdp, arg);
-		break;
-#ifdef CONFIG_FB_MSM_WRITE_BACK
-	case MSMFB_OVERLAY_BLT:
-		down(&msm_fb_ioctl_ppp_sem);
-		ret = msmfb_overlay_blt(p, argp);
-		up(&msm_fb_ioctl_ppp_sem);
-		break;
-#endif
-	case MSMFB_BLIT:
-#if PRINT_BLIT_TIME
-		t1 = ktime_get();
-#endif
-		down(&msm_fb_ioctl_ppp_sem);
-		ret = msmfb_blit(p, argp);
-		up(&msm_fb_ioctl_ppp_sem);
-		if (ret)
-			return ret;
-#if PRINT_BLIT_TIME
-		t2 = ktime_get();
-		DLOG(BLIT_TIME, "total %lld\n",
-		       ktime_to_ns(t2) - ktime_to_ns(t1));
-#endif
-		break;
 #ifdef CONFIG_FB_MSM_OVERLAY
 	case MSMFB_OVERLAY_GET:
-		if (!atomic_read(&mdpclk_on)) {
-			PR_DISP_WARN("MSMFB_OVERLAY_GET during suspend\n");
-			ret = -EINVAL;
-		} else {
-			down(&msm_fb_ioctl_ppp_sem);
-			ret = msmfb_overlay_get(p, argp);
-			up(&msm_fb_ioctl_ppp_sem);
-		}
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_get(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
 		break;
 	case MSMFB_OVERLAY_SET:
-		if (!atomic_read(&mdpclk_on)) {
-			PR_DISP_WARN("MSMFB_OVERLAY_SET during suspend\n");
-			ret = -EINVAL;
-		} else
-			ret = msmfb_overlay_set(p, argp);
-		PR_DISP_INFO("MSMFB_OVERLAY_SET ret=%d\n", ret);
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_set(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
 		break;
 	case MSMFB_OVERLAY_UNSET:
-		ret = msmfb_overlay_unset(p, argp);
-		PR_DISP_INFO("MSMFB_OVERLAY_UNSET ret=%d\n", ret);
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_unset(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
 		break;
 	case MSMFB_OVERLAY_PLAY:
-		if (!atomic_read(&mdpclk_on)) {
-			PR_DISP_ERR("MSMFB_OVERLAY_PLAY during suspend\n");
-			ret = -EINVAL;
-		} else
-			ret = msmfb_overlay_play(p, argp);
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_play(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
 		break;
-	case MSMFB_OVERLAY_CHANGE_ZORDER_VG_PIPES:
-		if (!atomic_read(&mdpclk_on)) {
-			PR_DISP_ERR("MSMFB_OVERLAY_CHANGE_ZORDER_VG_PIPES during suspend\n");
-			ret = -EINVAL;
-		} else {
-			down(&msm_fb_ioctl_ppp_sem);
-			ret = msmfb_overlay_change_z_order_vg_pipes(p, argp);
-			up(&msm_fb_ioctl_ppp_sem);
-		}
+	case MSMFB_OVERLAY_PLAY_ENABLE:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_play_enable(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_OVERLAY_PLAY_WAIT:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_play_wait(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_OVERLAY_BLT:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_blt(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_OVERLAY_3D:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_3d_sbys(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_MIXER_INFO:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_mixer_info(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_WRITEBACK_INIT:
+		ret = msmfb_overlay_ioctl_writeback_init(info);
+		break;
+	case MSMFB_WRITEBACK_START:
+		ret = msmfb_overlay_ioctl_writeback_start(
+				info);
+		break;
+	case MSMFB_WRITEBACK_STOP:
+		ret = msmfb_overlay_ioctl_writeback_stop(
+				info);
+		break;
+	case MSMFB_WRITEBACK_QUEUE_BUFFER:
+		ret = msmfb_overlay_ioctl_writeback_queue_buffer(
+				info, argp);
+		break;
+	case MSMFB_WRITEBACK_DEQUEUE_BUFFER:
+		ret = msmfb_overlay_ioctl_writeback_dequeue_buffer(
+				info, argp);
+		break;
+	case MSMFB_WRITEBACK_TERMINATE:
+		ret = msmfb_overlay_ioctl_writeback_terminate(info);
 		break;
 #endif
-#if defined(CONFIG_FB_MSM_MDP_ABL)
+	case MSMFB_VSYNC_CTRL:
+	case MSMFB_OVERLAY_VSYNC_CTRL:
+		down(&msm_fb_ioctl_ppp_sem);
+		if (mdp_rev >= MDP_REV_40)
+			ret = msmfb_overlay_vsync_ctrl(info, argp);
+		else
+			ret = msmfb_vsync_ctrl(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_BLIT:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_blit(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+
+		break;
+
+	/* Ioctl for setting ccs matrix from user space */
+	case MSMFB_SET_CCS_MATRIX:
+#ifndef CONFIG_FB_MSM_MDP40
+		ret = copy_from_user(&ccs_matrix, argp, sizeof(ccs_matrix));
+		if (ret) {
+			printk(KERN_ERR
+				"%s:MSMFB_SET_CCS_MATRIX ioctl failed \n",
+				__func__);
+			return ret;
+		}
+
+		down(&msm_fb_ioctl_ppp_sem);
+		if (ccs_matrix.direction == MDP_CCS_RGB2YUV)
+			mdp_ccs_rgb2yuv = ccs_matrix;
+		else
+			mdp_ccs_yuv2rgb = ccs_matrix;
+
+		msmfb_set_color_conv(&ccs_matrix) ;
+		up(&msm_fb_ioctl_ppp_sem);
+#else
+		ret = copy_from_user(&csc_matrix, argp, sizeof(csc_matrix));
+		if (ret) {
+			pr_err("%s:MSMFB_SET_CSC_MATRIX ioctl failed\n",
+				__func__);
+			return ret;
+		}
+		down(&msm_fb_ioctl_ppp_sem);
+		msmfb_set_color_conv(&csc_matrix);
+		up(&msm_fb_ioctl_ppp_sem);
+
+#endif
+
+		break;
+
+	/* Ioctl for getting ccs matrix to user space */
+	case MSMFB_GET_CCS_MATRIX:
+#ifndef CONFIG_FB_MSM_MDP40
+		ret = copy_from_user(&ccs_matrix, argp, sizeof(ccs_matrix)) ;
+		if (ret) {
+			printk(KERN_ERR
+				"%s:MSMFB_GET_CCS_MATRIX ioctl failed \n",
+				 __func__);
+			return ret;
+		}
+
+		down(&msm_fb_ioctl_ppp_sem);
+		if (ccs_matrix.direction == MDP_CCS_RGB2YUV)
+			ccs_matrix = mdp_ccs_rgb2yuv;
+		 else
+			ccs_matrix =  mdp_ccs_yuv2rgb;
+
+		ret = copy_to_user(argp, &ccs_matrix, sizeof(ccs_matrix));
+
+		if (ret)	{
+			printk(KERN_ERR
+				"%s:MSMFB_GET_CCS_MATRIX ioctl failed \n",
+				 __func__);
+			return ret ;
+		}
+		up(&msm_fb_ioctl_ppp_sem);
+#else
+		ret = -EINVAL;
+#endif
+
+		break;
+
+	case MSMFB_GRP_DISP:
+#ifdef CONFIG_FB_MSM_MDP22
+		{
+			unsigned long grp_id;
+
+			ret = copy_from_user(&grp_id, argp, sizeof(grp_id));
+			if (ret)
+				return ret;
+
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+			writel(grp_id, MDP_FULL_BYPASS_WORD43);
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF,
+				      FALSE);
+			break;
+		}
+#else
+		return -EFAULT;
+#endif
+	case MSMFB_SUSPEND_SW_REFRESHER:
+		if (!mfd->panel_power_on)
+			return -EPERM;
+
+		mfd->sw_refreshing_enable = FALSE;
+		ret = msm_fb_stop_sw_refresher(mfd);
+		break;
+
+	case MSMFB_RESUME_SW_REFRESHER:
+		if (!mfd->panel_power_on)
+			return -EPERM;
+
+		mfd->sw_refreshing_enable = TRUE;
+		ret = msm_fb_resume_sw_refresher(mfd);
+		break;
+
+	case MSMFB_CURSOR:
+		ret = copy_from_user(&cursor, argp, sizeof(cursor));
+		if (ret)
+			return ret;
+
+		ret = msm_fb_cursor(info, &cursor);
+		break;
+
 	case MSMFB_SET_LUT:
-		ret = msmfb_lut_update(p, argp);
+		ret = copy_from_user(&cmap, argp, sizeof(cmap));
+		if (ret)
+			return ret;
+
+		mutex_lock(&msm_fb_ioctl_lut_sem);
+		ret = msm_fb_set_lut(&cmap, info);
+		mutex_unlock(&msm_fb_ioctl_lut_sem);
 		break;
 
 	case MSMFB_HISTOGRAM:
-		ret = msmfb_do_histogram(p, argp);
+		if (!mfd->panel_power_on)
+			return -EPERM;
+
+		if (!mfd->do_histogram)
+			return -ENODEV;
+
+		ret = copy_from_user(&hist, argp, sizeof(hist));
+		if (ret)
+			return ret;
+
+		ret = mfd->do_histogram(info, &hist);
 		break;
 
 	case MSMFB_HISTOGRAM_START:
-		ret = mdp->start_histogram(mdp, p);
-			break;
+		if (!mfd->panel_power_on)
+			return -EPERM;
+
+		if (!mfd->do_histogram)
+			return -ENODEV;
+
+		ret = copy_from_user(&hist_req, argp, sizeof(hist_req));
+		if (ret)
+			return ret;
+
+		ret = mdp_histogram_start(&hist_req);
+		break;
 
 	case MSMFB_HISTOGRAM_STOP:
-	ret = mdp->stop_histogram(mdp, p);
-	break;
+		if (!mfd->do_histogram)
+			return -ENODEV;
 
-	case MSMFB_GET_GAMMA_CURVY:
-		ret = msmfb_get_gamma_curvy(p, argp);
-		break;
-#endif
-#if defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)
-	case MSMFB_GET_USB_PROJECTOR_INFO:
-		ret = copy_to_user(argp, &usb_pjt_info, sizeof(usb_pjt_info));
+		ret = copy_from_user(&block, argp, sizeof(int));
 		if (ret)
 			return ret;
+
+		ret = mdp_histogram_stop(info, block);
 		break;
-	case MSMFB_SET_USB_PROJECTOR_INFO:
-		ret = copy_from_user(&tmp_info, argp, sizeof(tmp_info));
-		usb_pjt_info.latest_offset = tmp_info.latest_offset;
-		if (!usb_pjt_info.latest_offset) {
-			/* pmem in user space has been freed */
-			for (i=0; i<NUM_ALLOC; i++) {
-				pmem_mapped = 0;
-				phys_addr[i] = 0;
-				virt_addr[i] = 0;
-			}
-		} else {
-			if (pmem_mapped < NUM_ALLOC) {
-				for (i=0; i<NUM_ALLOC; i++) {
-					if (phys_addr[i] == (void *)usb_pjt_info.latest_offset)
-						break;
-					if (!phys_addr[i]) {
-						unsigned long pmem_vbase;
-						unsigned long pmem_base;
-						unsigned long pmem_size;
-						struct file *map_file;
-						phys_addr[i] = (void *)usb_pjt_info.latest_offset;
-						/* call get_pmem_file only to get information */
-						get_pmem_file((unsigned int)phys_addr[i], &pmem_base, &pmem_vbase, &pmem_size, &map_file);
-						printk(KERN_ERR "%s: phys %p, virt %p\n",
-							__func__, (void *)pmem_base, (void *)pmem_vbase);
-						virt_addr[i] = (void*)pmem_vbase;
-						pmem_mapped++;
-						put_pmem_file(map_file);
-						break;
-					}
-				}
-			}
+
+
+	case MSMFB_GET_PAGE_PROTECTION:
+		fb_page_protection.page_protection
+			= mfd->mdp_fb_page_protection;
+		ret = copy_to_user(argp, &fb_page_protection,
+				sizeof(fb_page_protection));
+		if (ret)
+				return ret;
+		break;
+
+	case MSMFB_NOTIFY_UPDATE:
+		ret = msmfb_notify_update(info, argp);
+		break;
+
+	case MSMFB_SET_PAGE_PROTECTION:
+#if defined CONFIG_ARCH_QSD8X50 || defined CONFIG_ARCH_MSM8X60
+		ret = copy_from_user(&fb_page_protection, argp,
+				sizeof(fb_page_protection));
+		if (ret)
+				return ret;
+
+		/* Validate the proposed page protection settings. */
+		switch (fb_page_protection.page_protection)	{
+		case MDP_FB_PAGE_PROTECTION_NONCACHED:
+		case MDP_FB_PAGE_PROTECTION_WRITECOMBINE:
+		case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE:
+		/* Write-back cache (read allocate)  */
+		case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE:
+		/* Write-back cache (write allocate) */
+		case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE:
+			mfd->mdp_fb_page_protection =
+				fb_page_protection.page_protection;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
 		}
+#else
+		/*
+		 * Don't allow caching until 7k DMA cache operations are
+		 * available.
+		 */
+		ret = -EINVAL;
+#endif
+		break;
+
+	case MSMFB_MDP_PP:
+		ret = copy_from_user(&mdp_pp, argp, sizeof(mdp_pp));
 		if (ret)
 			return ret;
+
+		ret = msmfb_handle_pp_ioctl(mfd, &mdp_pp);
 		break;
-#endif
+
 	default:
-		PR_DISP_INFO("msmfb unknown ioctl: %d\n", cmd);
-		return -EINVAL;
+		MSM_FB_INFO("MDP: unknown ioctl (cmd=%x) received!\n", cmd);
+		ret = -EINVAL;
+		break;
 	}
+
 	return ret;
 }
 
-static struct fb_ops msmfb_ops = {
-	.owner = THIS_MODULE,
-	.fb_open = msmfb_open,
-	.fb_release = msmfb_release,
-	.fb_check_var = msmfb_check_var,
-	.fb_set_par = msmfb_set_par,
-	.fb_pan_display = msmfb_pan_display,
-	.fb_fillrect = msmfb_fillrect,
-	.fb_copyarea = msmfb_copyarea,
-	.fb_imageblit = msmfb_imageblit,
-	.fb_ioctl = msmfb_ioctl,
-};
-
-static unsigned PP[16];
-
-
-#if MSMFB_DEBUG
-static ssize_t debug_open(struct inode *inode, struct file *file)
+static int msm_fb_register_driver(void)
 {
-	file->private_data = inode->i_private;
-	return 0;
+	return platform_driver_register(&msm_fb_driver);
 }
 
-
-static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
-			  loff_t *ppos)
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+struct fb_info *msm_fb_get_writeback_fb(void)
 {
-	const int debug_bufmax = 4096;
-	static char buffer[4096];
-	int n = 0;
-	struct msmfb_info *msmfb = (struct msmfb_info *)file->private_data;
-	unsigned long irq_flags = 0;
+	int c = 0;
+	for (c = 0; c < fbi_list_index; ++c) {
+		struct msm_fb_data_type *mfd;
+		mfd = (struct msm_fb_data_type *)fbi_list[c]->par;
+		if (mfd->panel.type == WRITEBACK_PANEL)
+			return fbi_list[c];
+	}
 
-	spin_lock_irqsave(&msmfb->update_lock, irq_flags);
-	n = scnprintf(buffer, debug_bufmax, "yoffset %d\n", msmfb->yoffset);
-	n += scnprintf(buffer + n, debug_bufmax, "frame_requested %d\n",
-		       msmfb->frame_requested);
-	n += scnprintf(buffer + n, debug_bufmax, "frame_done %d\n",
-		       msmfb->frame_done);
-	n += scnprintf(buffer + n, debug_bufmax, "sleeping %d\n",
-		       msmfb->sleeping);
-	n += scnprintf(buffer + n, debug_bufmax, "update_frame %d\n",
-		       msmfb->update_frame);
-	spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-	n++;
-	buffer[n] = 0;
-	return simple_read_from_buffer(buf, count, ppos, buffer, n);
+	return NULL;
 }
+EXPORT_SYMBOL(msm_fb_get_writeback_fb);
 
-static struct file_operations debug_fops = {
-	.read = debug_read,
-	.open = debug_open,
-};
-#endif
-
-#define BITS_PER_PIXEL_DEF 32
-
-static void setup_fb_info(struct msmfb_info *msmfb)
+int msm_fb_writeback_start(struct fb_info *info)
 {
-	struct fb_info *fb_info = msmfb->fb;
-	int r;
-
-	/* finish setting up the fb_info struct */
-	strncpy(fb_info->fix.id, "msmfb", 16);
-	fb_info->fix.ypanstep = 1;
-
-	fb_info->fbops = &msmfb_ops;
-	fb_info->flags = FBINFO_DEFAULT;
-
-	fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
-	fb_info->fix.visual = FB_VISUAL_TRUECOLOR;
-	fb_info->fix.line_length = ALIGN(msmfb->xres, 32) * BITS_PER_PIXEL_DEF/8;
-
-	fb_info->var.xres = msmfb->xres;
-	fb_info->var.yres = msmfb->yres;
-	fb_info->var.width = msmfb->panel->fb_data->width;
-	fb_info->var.height = msmfb->panel->fb_data->height;
-	fb_info->var.xres_virtual = ALIGN(msmfb->xres, 32);
-	fb_info->var.yres_virtual = msmfb->yres * 2;
-	fb_info->var.bits_per_pixel = BITS_PER_PIXEL_DEF;
-	fb_info->var.accel_flags = 0;
-
-	fb_info->var.yoffset = 0;
-
-	if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) {
-		/* set the param in the fixed screen, so userspace can't
-		 * change it. This will be used to check for the
-		 * capability. */
-
-		/* FIX ME: every panel support partial update?
-		fb_info->fix.reserved[0] = 0x5444;
-		fb_info->fix.reserved[1] = 0x5055;
-		*/
-
-		/* This preloads the value so that if userspace doesn't
-		 * change it, it will be a full update */
-		fb_info->var.reserved[0] = 0x54445055;
-		fb_info->var.reserved[1] = 0;
-		fb_info->var.reserved[2] = (uint16_t)msmfb->xres |
-					   ((uint32_t)msmfb->yres << 16);
-	}
-
-	fb_info->var.red.offset = 11;
-	fb_info->var.red.length = 5;
-	fb_info->var.red.msb_right = 0;
-	fb_info->var.green.offset = 5;
-	fb_info->var.green.length = 6;
-	fb_info->var.green.msb_right = 0;
-	fb_info->var.blue.offset = 0;
-	fb_info->var.blue.length = 5;
-	fb_info->var.blue.msb_right = 0;
-
-	mdp->set_output_format(mdp, fb_info->var.bits_per_pixel);
-	mdp->set_panel_size(mdp, msmfb->xres, msmfb->yres);
-
-	r = fb_alloc_cmap(&fb_info->cmap, 16, 0);
-	fb_info->pseudo_palette = PP;
-
-	PP[0] = 0;
-	for (r = 1; r < 16; r++)
-		PP[r] = 0xffffffff;
-
-	/* Jay add, 7/1/09' */
-#if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR))
-	msm_fb_data.xres = ALIGN(msmfb->xres, 32);
-	msm_fb_data.yres = msmfb->yres;
-	PR_DISP_INFO("setup_fb_info msmfb->xres %d, msmfb->yres %d\n",
-				msmfb->xres, msmfb->yres);
-#endif
+	return mdp4_writeback_start(info);
 }
+EXPORT_SYMBOL(msm_fb_writeback_start);
 
-static int setup_fbmem(struct msmfb_info *msmfb, struct platform_device *pdev)
+int msm_fb_writeback_queue_buffer(struct fb_info *info,
+		struct msmfb_data *data)
 {
-	struct fb_info *fb = msmfb->fb;
-	unsigned long size = msmfb->xres * msmfb->yres *
-		BYTES_PER_PIXEL(msmfb) * 2;
-	unsigned char *fbram;
-	unsigned char *fbram_phys;
-	int fbram_size;
-	int fbram_offset;
-
-	fbram_size = pdev->resource[0].end - pdev->resource[0].start + 1;
-	fbram_phys = (char *)pdev->resource[0].start;
-	fbram = __va(fbram_phys);
-
-	if (!fbram) {
-		printk(KERN_ERR "fbram ioremap failed!\n");
-		return -ENOMEM;
-	}
-
-	fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
-	fbram += fbram_offset;
-	fbram_phys += fbram_offset;
-	fbram_size -= fbram_offset;
-
-	if (fbram_size < size) {
-		printk(KERN_ERR "error: no more framebuffer memory!\n");
-		return -ENOMEM;
-	}
-
-	fb->fix.smem_len = fbram_size;
-	fb->screen_base = fbram;
-	fb->fix.smem_start = (unsigned long)fbram_phys;
-
-	return 0;
+	return mdp4_writeback_queue_buffer(info, data);
 }
+EXPORT_SYMBOL(msm_fb_writeback_queue_buffer);
 
-static int msmfb_probe(struct platform_device *pdev)
+int msm_fb_writeback_dequeue_buffer(struct fb_info *info,
+		struct msmfb_data *data)
 {
-	struct fb_info *fb;
-	struct msmfb_info *msmfb;
-	struct msm_panel_data *panel = pdev->dev.platform_data;
-	int ret;
+	return mdp4_writeback_dequeue_buffer(info, data);
+}
+EXPORT_SYMBOL(msm_fb_writeback_dequeue_buffer);
 
-	if (!panel) {
-		PR_DISP_ERR("msmfb_probe: no platform data\n");
-		return -EINVAL;
-	}
-	if (!panel->fb_data) {
-		PR_DISP_ERR("msmfb_probe: no fb_data\n");
-		return -EINVAL;
-	}
-
-	fb = framebuffer_alloc(sizeof(struct msmfb_info), &pdev->dev);
-	if (!fb)
-		return -ENOMEM;
-	msmfb = fb->par;
-	msmfb->fb = fb;
-	msmfb->panel = panel;
-	msmfb->xres = panel->fb_data->xres;
-	msmfb->yres = panel->fb_data->yres;
-	msmfb->overrides = panel->fb_data->overrides;
-	ret = setup_fbmem(msmfb, pdev);
-	if (ret)
-		goto error_setup_fbmem;
-
-	setup_fb_info(msmfb);
-
-	spin_lock_init(&msmfb->update_lock);
-	mutex_init(&msmfb->panel_init_lock);
-	init_waitqueue_head(&msmfb->frame_wq);
-	msmfb->resume_workqueue = alloc_workqueue("panel_on", WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
-	if (msmfb->resume_workqueue == NULL) {
-		PR_DISP_ERR("failed to create panel_on workqueue\n");
-		ret = -ENOMEM;
-		goto error_create_workqueue;
-	}
-	INIT_WORK(&msmfb->resume_work, power_on_panel);
-	msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres,
-			       GFP_KERNEL);
-
-	wake_lock_init(&msmfb->idle_lock, WAKE_LOCK_IDLE, "msmfb_idle_lock");
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	if (!(msmfb->overrides & MSM_FB_PM_DISABLE)) {
-		msmfb->early_suspend.suspend = msmfb_suspend;
-		msmfb->early_suspend.resume = msmfb_resume_handler;
-		msmfb->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
-		register_early_suspend(&msmfb->early_suspend);
-
-		msmfb->earlier_suspend.suspend = msmfb_earlier_suspend;
-		msmfb->earlier_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
-		register_early_suspend(&msmfb->earlier_suspend);
-	}
-#ifdef CONFIG_HTC_ONMODE_CHARGING
-	if (!(msmfb->overrides & MSM_FB_PM_DISABLE)) {
-		msmfb->onchg_suspend.suspend = msmfb_onchg_suspend;
-		msmfb->onchg_suspend.resume = msmfb_onchg_resume_handler;
-		msmfb->onchg_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
-		register_onchg_suspend(&msmfb->onchg_suspend);
-
-		msmfb->onchg_earlier_suspend.suspend = msmfb_onchg_earlier_suspend;
-		msmfb->onchg_earlier_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
-		register_onchg_suspend(&msmfb->onchg_earlier_suspend);
-	}
-#endif
+int msm_fb_writeback_stop(struct fb_info *info)
+{
+	return mdp4_writeback_stop(info);
+}
+EXPORT_SYMBOL(msm_fb_writeback_stop);
+int msm_fb_writeback_init(struct fb_info *info)
+{
+	return mdp4_writeback_init(info);
+}
+EXPORT_SYMBOL(msm_fb_writeback_init);
+int msm_fb_writeback_terminate(struct fb_info *info)
+{
+	return mdp4_writeback_terminate(info);
+}
+EXPORT_SYMBOL(msm_fb_writeback_terminate);
 #endif
 
-#if MSMFB_DEBUG
-	debugfs_create_file("msm_fb", S_IFREG | S_IRUGO, NULL,
-			    (void *)fb->par, &debug_fops);
-#endif
+struct platform_device *msm_fb_add_device(struct platform_device *pdev)
+{
+	struct msm_fb_panel_data *pdata;
+	struct platform_device *this_dev = NULL;
+	struct fb_info *fbi;
+	struct msm_fb_data_type *mfd = NULL;
+	u32 type, id, fb_num;
 
-	PR_DISP_INFO("msmfb_probe() installing %d x %d panel\n",
-	       msmfb->xres, msmfb->yres);
+	if (!pdev)
+		return NULL;
+	id = pdev->id;
 
-	msmfb->dma_callback.func = msmfb_handle_dma_interrupt;
-	msmfb->vsync_callback.func = msmfb_handle_vsync_interrupt;
-	hrtimer_init(&msmfb->fake_vsync, CLOCK_MONOTONIC,
-		     HRTIMER_MODE_REL);
+	pdata = pdev->dev.platform_data;
+	if (!pdata)
+		return NULL;
+	type = pdata->panel_info.type;
 
-	msmfb->fake_vsync.function = msmfb_fake_vsync;
-
-	ret = register_framebuffer(fb);
-
-	if (fb->node == 0)
-		mdp->fb0 = msmfb->fb;
+#if defined MSM_FB_NUM
+	/*
+	 * over written fb_num which defined
+	 * at panel_info
+	 *
+	 */
+	if (type == HDMI_PANEL || type == DTV_PANEL ||
+		type == TV_PANEL || type == WRITEBACK_PANEL) {
+		if (hdmi_prim_display)
+			pdata->panel_info.fb_num = 2;
+		else
+			pdata->panel_info.fb_num = 1;
+	}
 	else
-		mdp->fb1 = msmfb->fb;
+		pdata->panel_info.fb_num = MSM_FB_NUM;
 
-	if (ret)
-		goto error_register_framebuffer;
+	MSM_FB_INFO("setting pdata->panel_info.fb_num to %d. type: %d\n",
+			pdata->panel_info.fb_num, type);
+#endif
+	fb_num = pdata->panel_info.fb_num;
 
-	msmfb->sleeping = WAKING;
+	if (fb_num <= 0)
+		return NULL;
 
-/* FIXME: Check if deprecated */
-#ifdef CONFIG_FB_MSM_LOGO
-	if (!load_565rle_image(INIT_IMAGE_FILE)) {
-		/* Flip buffer */
-		msmfb->update_info.left = 0;
-		msmfb->update_info.top = 0;
-		msmfb->update_info.eright = info->var.xres;
-		msmfb->update_info.ebottom = info->var.yres;
-		msmfb_pan_update(info, 0, 0, fb->var.xres,
-				 fb->var.yres, 0, 1);
+	if (fbi_list_index >= MAX_FBI_LIST) {
+		printk(KERN_ERR "msm_fb: no more framebuffer info list!\n");
+		return NULL;
 	}
-#endif
-	/* Jay, 29/12/08' */
-	display_notifier(display_notifier_callback, NOTIFY_MSM_FB);
+	/*
+	 * alloc panel device data
+	 */
+	this_dev = msm_fb_device_alloc(pdata, type, id);
 
-#if defined(CONFIG_FB_MSM_MDP_ABL)
-	init_completion(&mdp_hist_comp);
-#endif
+	if (!this_dev) {
+		printk(KERN_ERR
+		"%s: msm_fb_device_alloc failed!\n", __func__);
+		return NULL;
+	}
+
+	/*
+	 * alloc framebuffer info + par data
+	 */
+	fbi = framebuffer_alloc(sizeof(struct msm_fb_data_type), NULL);
+	if (fbi == NULL) {
+		platform_device_put(this_dev);
+		printk(KERN_ERR "msm_fb: can't alloca framebuffer info data!\n");
+		return NULL;
+	}
+
+	mfd = (struct msm_fb_data_type *)fbi->par;
+	mfd->key = MFD_KEY;
+	mfd->fbi = fbi;
+	mfd->panel.type = type;
+	mfd->panel.id = id;
+	mfd->fb_page = fb_num;
+	mfd->index = fbi_list_index;
+	mfd->mdp_fb_page_protection = MDP_FB_PAGE_PROTECTION_WRITECOMBINE;
+	mfd->iclient = iclient;
+	/* link to the latest pdev */
+	mfd->pdev = this_dev;
+
+	mfd_list[mfd_list_index++] = mfd;
+	fbi_list[fbi_list_index++] = fbi;
+
+	/*
+	 * set driver data
+	 */
+	platform_set_drvdata(this_dev, mfd);
+
+	if (platform_device_add(this_dev)) {
+		printk(KERN_ERR "msm_fb: platform_device_add failed!\n");
+		platform_device_put(this_dev);
+		framebuffer_release(fbi);
+		fbi_list_index--;
+		return NULL;
+	}
+	return this_dev;
+}
+EXPORT_SYMBOL(msm_fb_add_device);
+
+int get_fb_phys_info(unsigned long *start, unsigned long *len, int fb_num,
+	int subsys_id)
+{
+	struct fb_info *info;
+	struct msm_fb_data_type *mfd;
+
+	if (fb_num > MAX_FBI_LIST ||
+		(subsys_id != DISPLAY_SUBSYSTEM_ID &&
+		 subsys_id != ROTATOR_SUBSYSTEM_ID)) {
+		pr_err("%s(): Invalid parameters\n", __func__);
+		return -1;
+	}
+
+	info = fbi_list[fb_num];
+	if (!info) {
+		pr_err("%s(): info is NULL\n", __func__);
+		return -1;
+	}
+
+	mfd = (struct msm_fb_data_type *)info->par;
+	if (mfd->map_buffer)
+		*start = mfd->map_buffer->iova[subsys_id];
+	else
+		*start = info->fix.smem_start;
+	*len = info->fix.smem_len;
+
 	return 0;
-
-error_register_framebuffer:
-	wake_lock_destroy(&msmfb->idle_lock);
-	destroy_workqueue(msmfb->resume_workqueue);
-error_create_workqueue:
-	iounmap(fb->screen_base);
-error_setup_fbmem:
-	framebuffer_release(msmfb->fb);
-	return ret;
 }
+EXPORT_SYMBOL(get_fb_phys_info);
 
-static void msmfb_shutdown(struct platform_device *pdev)
+int __init msm_fb_init(void)
 {
-	struct msm_panel_data *panel = pdev->dev.platform_data;
-	struct fb_info *fb;
-	struct msmfb_info *msmfb;
+	int rc = -ENODEV;
 
-	PR_DISP_INFO("%s\n", __func__);
-	fb = registered_fb[0];
-	if (!fb) {
-		PR_DISP_ERR("fb0 unavailable.\n");
-		return;
+	if (msm_fb_register_driver())
+		return rc;
+
+#ifdef MSM_FB_ENABLE_DBGFS
+	{
+		struct dentry *root;
+
+		if ((root = msm_fb_get_debugfs_root()) != NULL) {
+			msm_fb_debugfs_file_create(root,
+						   "msm_fb_msg_printing_level",
+						   (u32 *) &msm_fb_msg_level);
+			msm_fb_debugfs_file_create(root,
+						   "mddi_msg_printing_level",
+						   (u32 *) &mddi_msg_level);
+			msm_fb_debugfs_file_create(root, "msm_fb_debug_enabled",
+						   (u32 *) &msm_fb_debug_enabled);
+		}
 	}
-	msmfb = fb->par;
-
-	/* HTC, Change state to SLEEPING to skip pan_update during shutdown */
-	msmfb->sleeping = SLEEPING;
-
-	if (panel->blank)
-		panel->blank(panel);
-
-	if (panel->shutdown)
-		panel->shutdown(panel);
-}
-
-static struct platform_driver msm_panel_driver = {
-	/* need to write remove */
-	.probe = msmfb_probe,
-	.shutdown = msmfb_shutdown,
-	.driver = {.name = "msm_panel"},
-};
-
-int get_fb_phys_info(unsigned long *start, unsigned long *len, int fb_num)
-{
-	struct fb_info *fi;
-	PR_DISP_DEBUG("%s fb_num %d\n", __func__, fb_num);
-
-	if (fb_num >= FB_MAX)
-		return -1;
-
-	fi = registered_fb[fb_num];
-
-	if (!fi)
-		return -1;
-
-	*start = fi->fix.smem_start;
-	*len = fi->fix.smem_len;
-
-	if (!*start)
-		return -1;
+#endif
 
 	return 0;
 }
 
-
-static int msmfb_add_mdp_device(struct device *dev,
-				struct class_interface *class_intf)
+/* Called by v4l2 driver to enable/disable overlay pipe */
+int msm_fb_v4l2_enable(struct mdp_overlay *req, bool enable, void **par)
 {
-	/* might need locking if mulitple mdp devices */
-	if (mdp)
-		return 0;
-	mdp = container_of(dev, struct mdp_device, dev);
-	return platform_driver_register(&msm_panel_driver);
-}
+	int err = 0;
+#ifdef CONFIG_FB_MSM_MDP40
+	struct mdp4_overlay_pipe *pipe;
+	if (enable) {
 
-static void msmfb_remove_mdp_device(struct device *dev,
-				struct class_interface *class_intf)
+		err = mdp4_v4l2_overlay_set(fbi_list[0], req, &pipe);
+
+		*(struct mdp4_overlay_pipe **)par = pipe;
+
+	} else {
+		pipe = *(struct mdp4_overlay_pipe **)par;
+		mdp4_v4l2_overlay_clear(pipe);
+	}
+#else
+#ifdef CONFIG_FB_MSM_MDP30
+	if (enable)
+		err = mdp_ppp_v4l2_overlay_set(fbi_list[0], req);
+	else
+		err = mdp_ppp_v4l2_overlay_clear();
+#else
+	err = -EINVAL;
+#endif
+#endif
+
+	return err;
+}
+EXPORT_SYMBOL(msm_fb_v4l2_enable);
+
+/* Called by v4l2 driver to provide a frame for display */
+int msm_fb_v4l2_update(void *par,
+	unsigned long srcp0_addr, unsigned long srcp0_size,
+	unsigned long srcp1_addr, unsigned long srcp1_size,
+	unsigned long srcp2_addr, unsigned long srcp2_size)
 {
-	/* might need locking if mulitple mdp devices */
-	if (dev != &mdp->dev)
-		return;
-	platform_driver_unregister(&msm_panel_driver);
-	mdp = NULL;
+#ifdef CONFIG_FB_MSM_MDP40
+	struct mdp4_overlay_pipe *pipe = (struct mdp4_overlay_pipe *)par;
+	return mdp4_v4l2_overlay_play(fbi_list[0], pipe,
+		srcp0_addr, srcp1_addr,
+		srcp2_addr);
+#else
+#ifdef CONFIG_FB_MSM_MDP30
+	return mdp_ppp_v4l2_overlay_play(fbi_list[0],
+		srcp0_addr, srcp0_size,
+		srcp1_addr, srcp1_size);
+#else
+	return -EINVAL;
+#endif
+#endif
 }
+EXPORT_SYMBOL(msm_fb_v4l2_update);
 
-static struct class_interface msm_fb_interface = {
-	.add_dev = &msmfb_add_mdp_device,
-	.remove_dev = &msmfb_remove_mdp_device,
-};
-
-static int __init msmfb_init(void)
-{
-	return register_mdp_client(&msm_fb_interface);
-}
-
-module_init(msmfb_init);
+module_init(msm_fb_init);
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
new file mode 100644
index 0000000..fcb6d46
--- /dev/null
+++ b/drivers/video/msm/msm_fb.h
@@ -0,0 +1,222 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MSM_FB_H
+#define MSM_FB_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include "linux/proc_fs.h"
+
+#include <mach/hardware.h>
+#include <mach/msm_subsystem_map.h>
+#include <linux/io.h>
+#include <mach/board.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/memory.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/hrtimer.h>
+
+#include <linux/fb.h>
+#include <linux/list.h>
+#include <linux/types.h>
+
+#include <linux/msm_mdp.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "msm_fb_panel.h"
+#include "mdp.h"
+
+#define MSM_FB_DEFAULT_PAGE_SIZE 2
+#define MFD_KEY  0x11161126
+#define MSM_FB_MAX_DEV_LIST 32
+
+struct disp_info_type_suspend {
+	boolean op_enable;
+	boolean sw_refreshing_enable;
+	boolean panel_power_on;
+};
+
+struct msmfb_writeback_data_list {
+	struct list_head registered_entry;
+	struct list_head active_entry;
+	void *addr;
+	struct ion_handle *ihdl;
+	struct file *pmem_file;
+	struct msmfb_data buf_info;
+	struct msmfb_img img;
+	int state;
+};
+
+
+struct msm_fb_data_type {
+	__u32 key;
+	__u32 index;
+	__u32 ref_cnt;
+	__u32 fb_page;
+
+	panel_id_type panel;
+	struct msm_panel_info panel_info;
+
+	DISP_TARGET dest;
+	struct fb_info *fbi;
+
+	struct device *dev;
+	boolean op_enable;
+	uint32 fb_imgType;
+	boolean sw_currently_refreshing;
+	boolean sw_refreshing_enable;
+	boolean hw_refresh;
+#ifdef CONFIG_FB_MSM_OVERLAY
+	int overlay_play_enable;
+#endif
+
+	MDPIBUF ibuf;
+	boolean ibuf_flushed;
+	struct timer_list refresh_timer;
+	struct completion refresher_comp;
+
+	boolean pan_waiting;
+	struct completion pan_comp;
+
+	/* vsync */
+	boolean use_mdp_vsync;
+	__u32 vsync_gpio;
+	__u32 total_lcd_lines;
+	__u32 total_porch_lines;
+	__u32 lcd_ref_usec_time;
+	__u32 refresh_timer_duration;
+
+	struct hrtimer dma_hrtimer;
+
+	boolean panel_power_on;
+	struct work_struct dma_update_worker;
+	struct semaphore sem;
+
+	struct timer_list vsync_resync_timer;
+	boolean vsync_handler_pending;
+	struct work_struct vsync_resync_worker;
+
+	ktime_t last_vsync_timetick;
+
+	__u32 *vsync_width_boundary;
+
+	unsigned int pmem_id;
+	struct disp_info_type_suspend suspend;
+
+	__u32 channel_irq;
+
+	struct mdp_dma_data *dma;
+	void (*dma_fnc) (struct msm_fb_data_type *mfd);
+	int (*cursor_update) (struct fb_info *info,
+			      struct fb_cursor *cursor);
+	int (*lut_update) (struct fb_info *info,
+			      struct fb_cmap *cmap);
+	int (*do_histogram) (struct fb_info *info,
+			      struct mdp_histogram_data *hist);
+	void (*vsync_ctrl) (int enable);
+	void *cursor_buf;
+	void *cursor_buf_phys;
+
+	void *cmd_port;
+	void *data_port;
+	void *data_port_phys;
+
+	__u32 bl_level;
+
+	struct platform_device *pdev;
+
+	__u32 var_xres;
+	__u32 var_yres;
+	__u32 var_pixclock;
+	__u32 var_frame_rate;
+
+#ifdef MSM_FB_ENABLE_DBGFS
+	struct dentry *sub_dir;
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	struct early_suspend early_suspend;
+#ifdef CONFIG_FB_MSM_MDDI
+	struct early_suspend mddi_early_suspend;
+	struct early_suspend mddi_ext_early_suspend;
+#endif
+#endif
+	u32 mdp_fb_page_protection;
+
+	struct clk *ebi1_clk;
+	boolean dma_update_flag;
+	struct timer_list msmfb_no_update_notify_timer;
+	struct completion msmfb_update_notify;
+	struct completion msmfb_no_update_notify;
+	struct mutex writeback_mutex;
+	struct mutex unregister_mutex;
+	struct list_head writeback_busy_queue;
+	struct list_head writeback_free_queue;
+	struct list_head writeback_register_queue;
+	wait_queue_head_t wait_q;
+	struct ion_client *iclient;
+	struct msm_mapped_buffer *map_buffer;
+	struct mdp_buf_type *ov0_wb_buf;
+	struct mdp_buf_type *ov1_wb_buf;
+	u32 ov_start;
+	u32 mem_hid;
+	u32 mdp_rev;
+	u32 writeback_state;
+	bool writeback_active_cnt;
+	int cont_splash_done;
+};
+
+struct dentry *msm_fb_get_debugfs_root(void);
+void msm_fb_debugfs_file_create(struct dentry *root, const char *name,
+				u32 *var);
+void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl);
+
+struct platform_device *msm_fb_add_device(struct platform_device *pdev);
+struct fb_info *msm_fb_get_writeback_fb(void);
+int msm_fb_writeback_init(struct fb_info *info);
+int msm_fb_writeback_start(struct fb_info *info);
+int msm_fb_writeback_queue_buffer(struct fb_info *info,
+		struct msmfb_data *data);
+int msm_fb_writeback_dequeue_buffer(struct fb_info *info,
+		struct msmfb_data *data);
+int msm_fb_writeback_stop(struct fb_info *info);
+int msm_fb_writeback_terminate(struct fb_info *info);
+int msm_fb_detect_client(const char *name);
+int calc_fb_offset(struct msm_fb_data_type *mfd, struct fb_info *fbi, int bpp);
+
+#ifdef CONFIG_FB_BACKLIGHT
+void msm_fb_config_backlight(struct msm_fb_data_type *mfd);
+#endif
+
+void fill_black_screen(void);
+void unfill_black_screen(void);
+int msm_fb_check_frame_rate(struct msm_fb_data_type *mfd,
+				struct fb_info *info);
+
+#ifdef CONFIG_FB_MSM_LOGO
+#define INIT_IMAGE_FILE "/initlogo.rle"
+int load_565rle_image(char *filename, bool bf_supported);
+#endif
+
+#endif /* MSM_FB_H */
diff --git a/drivers/video/msm/msm_fb_bl.c b/drivers/video/msm/msm_fb_bl.c
new file mode 100644
index 0000000..9afbbf1
--- /dev/null
+++ b/drivers/video/msm/msm_fb_bl.c
@@ -0,0 +1,75 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/backlight.h>
+
+#include "msm_fb.h"
+
+static int msm_fb_bl_get_brightness(struct backlight_device *pbd)
+{
+	return pbd->props.brightness;
+}
+
+static int msm_fb_bl_update_status(struct backlight_device *pbd)
+{
+	struct msm_fb_data_type *mfd = bl_get_data(pbd);
+	__u32 bl_lvl;
+
+	bl_lvl = pbd->props.brightness;
+	bl_lvl = mfd->fbi->bl_curve[bl_lvl];
+	msm_fb_set_backlight(mfd, bl_lvl);
+	return 0;
+}
+
+static struct backlight_ops msm_fb_bl_ops = {
+	.get_brightness = msm_fb_bl_get_brightness,
+	.update_status = msm_fb_bl_update_status,
+};
+
+void msm_fb_config_backlight(struct msm_fb_data_type *mfd)
+{
+	struct msm_fb_panel_data *pdata;
+	struct backlight_device *pbd;
+	struct fb_info *fbi;
+	char name[16];
+	struct backlight_properties props;
+
+	fbi = mfd->fbi;
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
+	if ((pdata) && (pdata->set_backlight)) {
+		snprintf(name, sizeof(name), "msmfb_bl%d", mfd->index);
+		props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+		props.brightness = FB_BACKLIGHT_LEVELS - 1;
+		pbd =
+		    backlight_device_register(name, fbi->dev, mfd,
+					      &msm_fb_bl_ops, &props);
+		if (!IS_ERR(pbd)) {
+			fbi->bl_dev = pbd;
+			fb_bl_default_curve(fbi,
+					    0,
+					    mfd->panel_info.bl_min,
+					    mfd->panel_info.bl_max);
+		} else {
+			fbi->bl_dev = NULL;
+			printk(KERN_ERR "msm_fb: backlight_device_register failed!\n");
+		}
+	}
+}
diff --git a/drivers/video/msm/msm_fb_def.h b/drivers/video/msm/msm_fb_def.h
new file mode 100644
index 0000000..1c1f392
--- /dev/null
+++ b/drivers/video/msm/msm_fb_def.h
@@ -0,0 +1,204 @@
+/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MSM_FB_DEF_H
+#define MSM_FB_DEF_H
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/uaccess.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <linux/debugfs.h>
+#include <linux/console.h>
+#include <linux/android_pmem.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include "linux/proc_fs.h"
+#include <linux/io.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+
+
+typedef s64 int64;
+typedef s32 int32;
+typedef s16 int16;
+typedef s8 int8;
+
+typedef u64 uint64;
+typedef u32 uint32;
+typedef u16 uint16;
+typedef u8 uint8;
+
+typedef s32 int4;
+typedef s16 int2;
+typedef s8 int1;
+
+typedef u32 uint4;
+typedef u16 uint2;
+typedef u8 uint1;
+
+typedef u32 dword;
+typedef u16 word;
+typedef u8 byte;
+
+typedef unsigned int boolean;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define MSM_FB_ENABLE_DBGFS
+#define FEATURE_MDDI
+
+#if defined(CONFIG_FB_MSM_DEFAULT_DEPTH_RGB565)
+#define MSMFB_DEFAULT_TYPE MDP_RGB_565
+#elif defined(CONFIG_FB_MSM_DEFAULT_DEPTH_ARGB8888)
+#define MSMFB_DEFAULT_TYPE MDP_ARGB_8888
+#elif defined(CONFIG_FB_MSM_DEFAULT_DEPTH_RGBA8888)
+#define MSMFB_DEFAULT_TYPE MDP_RGBA_8888
+#else
+#define MSMFB_DEFAULT_TYPE MDP_RGB_565
+#endif
+
+#define outp32(addr, val) writel(val, addr)
+#define outp16(addr, val) writew(val, addr)
+#define outp8(addr, val) writeb(val, addr)
+#define outp(addr, val) outp32(addr, val)
+
+#ifndef MAX
+#define  MAX( x, y ) (((x) > (y)) ? (x) : (y))
+#endif
+
+#ifndef MIN
+#define  MIN( x, y ) (((x) < (y)) ? (x) : (y))
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+#define inp32(addr) readl(addr)
+#define inp16(addr) readw(addr)
+#define inp8(addr) readb(addr)
+#define inp(addr) inp32(addr)
+
+#define inpw(port)             readw(port)
+#define outpw(port, val)       writew(val, port)
+#define inpdw(port)            readl(port)
+#define outpdw(port, val)      writel(val, port)
+
+
+#define clk_busy_wait(x) msleep_interruptible((x)/1000)
+
+#define memory_barrier()
+
+#define assert(expr) \
+	if(!(expr)) { \
+		printk(KERN_ERR "msm_fb: assertion failed! %s,%s,%s,line=%d\n",\
+			#expr, __FILE__, __func__, __LINE__); \
+	}
+
+#define ASSERT(x)   assert(x)
+
+#define DISP_EBI2_LOCAL_DEFINE
+#ifdef DISP_EBI2_LOCAL_DEFINE
+#define LCD_PRIM_BASE_PHYS 0x98000000
+#define LCD_SECD_BASE_PHYS 0x9c000000
+#define EBI2_PRIM_LCD_RS_PIN 0x20000
+#define EBI2_SECD_LCD_RS_PIN 0x20000
+
+#define EBI2_PRIM_LCD_CLR 0xC0
+#define EBI2_PRIM_LCD_SEL 0x40
+
+#define EBI2_SECD_LCD_CLR 0x300
+#define EBI2_SECD_LCD_SEL 0x100
+#endif
+
+extern u32 msm_fb_msg_level;
+
+/*
+ * Message printing priorities:
+ * LEVEL 0 KERN_EMERG (highest priority)
+ * LEVEL 1 KERN_ALERT
+ * LEVEL 2 KERN_CRIT
+ * LEVEL 3 KERN_ERR
+ * LEVEL 4 KERN_WARNING
+ * LEVEL 5 KERN_NOTICE
+ * LEVEL 6 KERN_INFO
+ * LEVEL 7 KERN_DEBUG (Lowest priority)
+ */
+#define MSM_FB_EMERG(msg, ...)    \
+	if (msm_fb_msg_level > 0)  \
+		printk(KERN_EMERG msg, ## __VA_ARGS__);
+#define MSM_FB_ALERT(msg, ...)    \
+	if (msm_fb_msg_level > 1)  \
+		printk(KERN_ALERT msg, ## __VA_ARGS__);
+#define MSM_FB_CRIT(msg, ...)    \
+	if (msm_fb_msg_level > 2)  \
+		printk(KERN_CRIT msg, ## __VA_ARGS__);
+#define MSM_FB_ERR(msg, ...)    \
+	if (msm_fb_msg_level > 3)  \
+		printk(KERN_ERR msg, ## __VA_ARGS__);
+#define MSM_FB_WARNING(msg, ...)    \
+	if (msm_fb_msg_level > 4)  \
+		printk(KERN_WARNING msg, ## __VA_ARGS__);
+#define MSM_FB_NOTICE(msg, ...)    \
+	if (msm_fb_msg_level > 5)  \
+		printk(KERN_NOTICE msg, ## __VA_ARGS__);
+#define MSM_FB_INFO(msg, ...)    \
+	if (msm_fb_msg_level > 6)  \
+		printk(KERN_INFO msg, ## __VA_ARGS__);
+#define MSM_FB_DEBUG(msg, ...)    \
+	if (msm_fb_msg_level > 7)  \
+		printk(KERN_DEBUG msg, ## __VA_ARGS__);
+
+#ifdef MSM_FB_C
+unsigned char *msm_mdp_base;
+unsigned char *msm_pmdh_base;
+unsigned char *msm_emdh_base;
+unsigned char *mipi_dsi_base;
+#else
+extern unsigned char *msm_mdp_base;
+extern unsigned char *msm_pmdh_base;
+extern unsigned char *msm_emdh_base;
+extern unsigned char *mipi_dsi_base;
+#endif
+
+#undef ENABLE_MDDI_MULTI_READ_WRITE
+#undef ENABLE_FWD_LINK_SKEW_CALIBRATION
+
+#endif /* MSM_FB_DEF_H */
diff --git a/drivers/video/msm/msm_fb_panel.c b/drivers/video/msm/msm_fb_panel.c
new file mode 100644
index 0000000..d8eaea2
--- /dev/null
+++ b/drivers/video/msm/msm_fb_panel.c
@@ -0,0 +1,144 @@
+/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/uaccess.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <linux/debugfs.h>
+
+#include "msm_fb_panel.h"
+
+int panel_next_on(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_panel_data *pdata;
+	struct msm_fb_panel_data *next_pdata;
+	struct platform_device *next_pdev;
+
+	pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
+
+	if (pdata) {
+		next_pdev = pdata->next;
+		if (next_pdev) {
+			next_pdata =
+			    (struct msm_fb_panel_data *)next_pdev->dev.
+			    platform_data;
+			if ((next_pdata) && (next_pdata->on))
+				ret = next_pdata->on(next_pdev);
+		}
+	}
+
+	return ret;
+}
+
+int panel_next_off(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_fb_panel_data *pdata;
+	struct msm_fb_panel_data *next_pdata;
+	struct platform_device *next_pdev;
+
+	pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data;
+
+	if (pdata) {
+		next_pdev = pdata->next;
+		if (next_pdev) {
+			next_pdata =
+			    (struct msm_fb_panel_data *)next_pdev->dev.
+			    platform_data;
+			if ((next_pdata) && (next_pdata->on))
+				ret = next_pdata->off(next_pdev);
+		}
+	}
+
+	return ret;
+}
+
+struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata,
+						u32 type, u32 id)
+{
+	struct platform_device *this_dev = NULL;
+	char dev_name[16];
+
+	switch (type) {
+	case EBI2_PANEL:
+		snprintf(dev_name, sizeof(dev_name), "ebi2_lcd");
+		break;
+
+	case MDDI_PANEL:
+		snprintf(dev_name, sizeof(dev_name), "mddi");
+		break;
+
+	case EXT_MDDI_PANEL:
+		snprintf(dev_name, sizeof(dev_name), "mddi_ext");
+		break;
+
+	case TV_PANEL:
+		snprintf(dev_name, sizeof(dev_name), "tvenc");
+		break;
+
+	case HDMI_PANEL:
+	case LCDC_PANEL:
+		snprintf(dev_name, sizeof(dev_name), "lcdc");
+		break;
+
+	case DTV_PANEL:
+		snprintf(dev_name, sizeof(dev_name), "dtv");
+		break;
+
+	case MIPI_VIDEO_PANEL:
+	case MIPI_CMD_PANEL:
+		snprintf(dev_name, sizeof(dev_name), "mipi_dsi");
+		break;
+	case WRITEBACK_PANEL:
+		snprintf(dev_name, sizeof(dev_name), "writeback");
+		break;
+
+	default:
+		return NULL;
+	}
+
+	if (pdata != NULL)
+		pdata->next = NULL;
+	else
+		return NULL;
+
+	this_dev =
+	    platform_device_alloc(dev_name, ((u32) type << 16) | (u32) id);
+
+	if (this_dev) {
+		if (platform_device_add_data
+		    (this_dev, pdata, sizeof(struct msm_fb_panel_data))) {
+			printk
+			    ("msm_fb_device_alloc: platform_device_add_data failed!\n");
+			platform_device_put(this_dev);
+			return NULL;
+		}
+	}
+
+	return this_dev;
+}
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
new file mode 100644
index 0000000..51a3f38
--- /dev/null
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -0,0 +1,201 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef MSM_FB_PANEL_H
+#define MSM_FB_PANEL_H
+
+#include "msm_fb_def.h"
+
+struct msm_fb_data_type;
+
+typedef void (*msm_fb_vsync_handler_type) (void *arg);
+
+/* panel id type */
+typedef struct panel_id_s {
+	uint16 id;
+	uint16 type;
+} panel_id_type;
+
+/* panel type list */
+#define NO_PANEL		0xffff	/* No Panel */
+#define MDDI_PANEL		1	/* MDDI */
+#define EBI2_PANEL		2	/* EBI2 */
+#define LCDC_PANEL		3	/* internal LCDC type */
+#define EXT_MDDI_PANEL		4	/* Ext.MDDI */
+#define TV_PANEL		5	/* TV */
+#define HDMI_PANEL		6	/* HDMI TV */
+#define DTV_PANEL		7	/* DTV */
+#define MIPI_VIDEO_PANEL	8	/* MIPI */
+#define MIPI_CMD_PANEL		9	/* MIPI */
+#define WRITEBACK_PANEL		10	/* Wifi display */
+#define LVDS_PANEL		11	/* LVDS */
+
+/* panel class */
+typedef enum {
+	DISPLAY_LCD = 0,	/* lcd = ebi2/mddi */
+	DISPLAY_LCDC,		/* lcdc */
+	DISPLAY_TV,		/* TV Out */
+	DISPLAY_EXT_MDDI,	/* External MDDI */
+} DISP_TARGET;
+
+/* panel device locaiton */
+typedef enum {
+	DISPLAY_1 = 0,		/* attached as first device */
+	DISPLAY_2,		/* attached on second device */
+	DISPLAY_3,              /* attached on third writeback device */
+	MAX_PHYS_TARGET_NUM,
+} DISP_TARGET_PHYS;
+
+/* panel info type */
+struct lcd_panel_info {
+	__u32 vsync_enable;
+	__u32 refx100;
+	__u32 v_back_porch;
+	__u32 v_front_porch;
+	__u32 v_pulse_width;
+	__u32 hw_vsync_mode;
+	__u32 vsync_notifier_period;
+	__u32 rev;
+};
+
+struct lcdc_panel_info {
+	__u32 h_back_porch;
+	__u32 h_front_porch;
+	__u32 h_pulse_width;
+	__u32 v_back_porch;
+	__u32 v_front_porch;
+	__u32 v_pulse_width;
+	__u32 border_clr;
+	__u32 underflow_clr;
+	__u32 hsync_skew;
+	/* Pad width */
+	uint32 xres_pad;
+	/* Pad height */
+	uint32 yres_pad;
+};
+
+struct mddi_panel_info {
+	__u32 vdopkt;
+	boolean is_type1;
+};
+
+struct mipi_panel_info {
+	char mode;		/* video/cmd */
+	char interleave_mode;
+	char crc_check;
+	char ecc_check;
+	char dst_format;	/* shared by video and command */
+	char data_lane0;
+	char data_lane1;
+	char data_lane2;
+	char data_lane3;
+	char dlane_swap;	/* data lane swap */
+	char rgb_swap;
+	char b_sel;
+	char g_sel;
+	char r_sel;
+	char rx_eot_ignore;
+	char tx_eot_append;
+	char t_clk_post; /* 0xc0, DSI_CLKOUT_TIMING_CTRL */
+	char t_clk_pre;  /* 0xc0, DSI_CLKOUT_TIMING_CTRL */
+	char vc;	/* virtual channel */
+	struct mipi_dsi_phy_ctrl *dsi_phy_db;
+	/* video mode */
+	char pulse_mode_hsa_he;
+	char hfp_power_stop;
+	char hbp_power_stop;
+	char hsa_power_stop;
+	char eof_bllp_power_stop;
+	char bllp_power_stop;
+	char traffic_mode;
+	char frame_rate;
+	/* command mode */
+	char interleave_max;
+	char insert_dcs_cmd;
+	char wr_mem_continue;
+	char wr_mem_start;
+	char te_sel;
+	char stream;	/* 0 or 1 */
+	char mdp_trigger;
+	char dma_trigger;
+	uint32 dsi_pclk_rate;
+	/* byte to esc clk ratio */
+	uint32 esc_byte_ratio;
+	/* The packet-size should not bet changed */
+	char no_max_pkt_size;
+	/* Clock required during LP commands */
+	char force_clk_lane_hs;
+};
+
+struct msm_panel_info {
+	__u32 xres;
+	__u32 yres;
+	__u32 bpp;
+	__u32 mode2_xres;
+	__u32 mode2_yres;
+	__u32 mode2_bpp;
+	__u32 type;
+	__u32 wait_cycle;
+	DISP_TARGET_PHYS pdest;
+	__u32 bl_max;
+	__u32 bl_min;
+	__u32 fb_num;
+	__u32 clk_rate;
+	__u32 clk_min;
+	__u32 clk_max;
+	__u32 frame_count;
+	__u32 is_3d_panel;
+	__u32 frame_rate;
+
+
+	struct mddi_panel_info mddi;
+	struct lcd_panel_info lcd;
+	struct lcdc_panel_info lcdc;
+	struct mipi_panel_info mipi;
+};
+
+#define MSM_FB_SINGLE_MODE_PANEL(pinfo)		\
+	do {					\
+		(pinfo)->mode2_xres = 0;	\
+		(pinfo)->mode2_yres = 0;	\
+		(pinfo)->mode2_bpp = 0;		\
+	} while (0)
+
+struct msm_fb_panel_data {
+	struct msm_panel_info panel_info;
+	void (*set_rect) (int x, int y, int xres, int yres);
+	void (*set_vsync_notifier) (msm_fb_vsync_handler_type, void *arg);
+	void (*set_backlight) (struct msm_fb_data_type *);
+
+	/* function entry chain */
+	int (*on) (struct platform_device *pdev);
+	int (*off) (struct platform_device *pdev);
+	int (*power_ctrl) (boolean enable);
+	struct platform_device *next;
+	int (*clk_func) (int enable);
+};
+
+/*===========================================================================
+  FUNCTIONS PROTOTYPES
+============================================================================*/
+struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata,
+						u32 type, u32 id);
+int panel_next_on(struct platform_device *pdev);
+int panel_next_off(struct platform_device *pdev);
+
+int lcdc_device_register(struct msm_panel_info *pinfo);
+
+int mddi_toshiba_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#endif /* MSM_FB_PANEL_H */
diff --git a/drivers/video/msm/tvenc.c b/drivers/video/msm/tvenc.c
new file mode 100644
index 0000000..30dc854
--- /dev/null
+++ b/drivers/video/msm/tvenc.c
@@ -0,0 +1,522 @@
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#define TVENC_C
+#include "tvenc.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+/* AXI rate in KHz */
+#define MSM_SYSTEM_BUS_RATE	128000000
+
+static int tvenc_probe(struct platform_device *pdev);
+static int tvenc_remove(struct platform_device *pdev);
+
+static int tvenc_off(struct platform_device *pdev);
+static int tvenc_on(struct platform_device *pdev);
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+
+static struct clk *tvenc_clk;
+static struct clk *tvdac_clk;
+static struct clk *tvenc_pclk;
+static struct clk *mdp_tv_clk;
+#ifdef CONFIG_FB_MSM_MDP40
+static struct clk *tv_src_clk;
+#endif
+
+#ifdef CONFIG_MSM_BUS_SCALING
+static uint32_t tvenc_bus_scale_handle;
+#endif
+
+static int tvenc_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int tvenc_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+
+static struct dev_pm_ops tvenc_dev_pm_ops = {
+	.runtime_suspend = tvenc_runtime_suspend,
+	.runtime_resume = tvenc_runtime_resume,
+};
+
+static struct platform_driver tvenc_driver = {
+	.probe = tvenc_probe,
+	.remove = tvenc_remove,
+	.suspend = NULL,
+	.resume = NULL,
+	.shutdown = NULL,
+	.driver = {
+		   .name = "tvenc",
+		   .pm = &tvenc_dev_pm_ops
+		   },
+};
+
+int tvenc_set_encoder_clock(boolean clock_on)
+{
+	int ret = 0;
+	if (clock_on) {
+#ifdef CONFIG_FB_MSM_MDP40
+		/* Consolidated clock used by both HDMI & TV encoder.
+		Clock exists only in MDP4 and not in older versions */
+		ret = clk_set_rate(tv_src_clk, 27000000);
+		if (ret) {
+			pr_err("%s: tvsrc_clk set rate failed! %d\n",
+				__func__, ret);
+			goto tvsrc_err;
+		}
+#endif
+		ret = clk_prepare_enable(tvenc_clk);
+		if (ret) {
+			pr_err("%s: tvenc_clk enable failed! %d\n",
+				__func__, ret);
+			goto tvsrc_err;
+		}
+
+		if (!IS_ERR(tvenc_pclk)) {
+			ret = clk_prepare_enable(tvenc_pclk);
+			if (ret) {
+				pr_err("%s: tvenc_pclk enable failed! %d\n",
+					__func__, ret);
+				goto tvencp_err;
+			}
+		}
+		return ret;
+	} else {
+		if (!IS_ERR(tvenc_pclk))
+			clk_disable_unprepare(tvenc_pclk);
+		clk_disable_unprepare(tvenc_clk);
+		return ret;
+	}
+tvencp_err:
+	clk_disable_unprepare(tvenc_clk);
+tvsrc_err:
+	return ret;
+}
+
+int tvenc_set_clock(boolean clock_on)
+{
+	int ret = 0;
+	if (clock_on) {
+		if (tvenc_pdata->poll) {
+			ret = tvenc_set_encoder_clock(CLOCK_ON);
+			if (ret) {
+				pr_err("%s: TVenc clock(s) enable failed! %d\n",
+					__func__, ret);
+				goto tvenc_err;
+			}
+		}
+		ret = clk_prepare_enable(tvdac_clk);
+		if (ret) {
+			pr_err("%s: tvdac_clk enable failed! %d\n",
+				__func__, ret);
+			goto tvdac_err;
+		}
+		if (!IS_ERR(mdp_tv_clk)) {
+			ret = clk_prepare_enable(mdp_tv_clk);
+			if (ret) {
+				pr_err("%s: mdp_tv_clk enable failed! %d\n",
+					__func__, ret);
+				goto mdptv_err;
+			}
+		}
+		return ret;
+	} else {
+		if (!IS_ERR(mdp_tv_clk))
+			clk_disable_unprepare(mdp_tv_clk);
+		clk_disable_unprepare(tvdac_clk);
+		if (tvenc_pdata->poll)
+			tvenc_set_encoder_clock(CLOCK_OFF);
+		return ret;
+	}
+
+mdptv_err:
+	clk_disable_unprepare(tvdac_clk);
+tvdac_err:
+	tvenc_set_encoder_clock(CLOCK_OFF);
+tvenc_err:
+	return ret;
+}
+
+static int tvenc_off(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+	ret = panel_next_off(pdev);
+	if (ret)
+		pr_err("%s: tvout_off failed! %d\n",
+		__func__, ret);
+
+	tvenc_set_clock(CLOCK_OFF);
+
+	if (tvenc_pdata && tvenc_pdata->pm_vid_en)
+		ret = tvenc_pdata->pm_vid_en(0);
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (tvenc_bus_scale_handle > 0)
+		msm_bus_scale_client_update_request(tvenc_bus_scale_handle,
+							0);
+#else
+	if (mfd->ebi1_clk)
+		clk_disable_unprepare(mfd->ebi1_clk);
+#endif
+
+	if (ret)
+		pr_err("%s: pm_vid_en(off) failed! %d\n",
+		__func__, ret);
+	mdp4_extn_disp = 0;
+	return ret;
+}
+
+static int tvenc_on(struct platform_device *pdev)
+{
+	int ret = 0;
+
+#ifndef CONFIG_MSM_BUS_SCALING
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+#endif
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (tvenc_bus_scale_handle > 0)
+		msm_bus_scale_client_update_request(tvenc_bus_scale_handle,
+							1);
+#else
+	if (mfd->ebi1_clk)
+		clk_prepare_enable(mfd->ebi1_clk);
+#endif
+	mdp4_extn_disp = 1;
+	if (tvenc_pdata && tvenc_pdata->pm_vid_en)
+		ret = tvenc_pdata->pm_vid_en(1);
+	if (ret) {
+		pr_err("%s: pm_vid_en(on) failed! %d\n",
+		__func__, ret);
+		return ret;
+	}
+
+	ret = tvenc_set_clock(CLOCK_ON);
+	if (ret) {
+		pr_err("%s: tvenc_set_clock(CLOCK_ON) failed! %d\n",
+		__func__, ret);
+		tvenc_pdata->pm_vid_en(0);
+		goto error;
+	}
+
+	ret = panel_next_on(pdev);
+	if (ret) {
+		pr_err("%s: tvout_on failed! %d\n",
+		__func__, ret);
+		tvenc_set_clock(CLOCK_OFF);
+		tvenc_pdata->pm_vid_en(0);
+	}
+
+error:
+	return ret;
+
+}
+
+void tvenc_gen_test_pattern(struct msm_fb_data_type *mfd)
+{
+	uint32 reg = 0, i;
+
+	reg = readl(MSM_TV_ENC_CTL);
+	reg |= TVENC_CTL_TEST_PATT_EN;
+
+	for (i = 0; i < 3; i++) {
+		TV_OUT(TV_ENC_CTL, 0);	/* disable TV encoder */
+
+		switch (i) {
+			/*
+			 * TV Encoder - Color Bar Test Pattern
+			 */
+		case 0:
+			reg |= TVENC_CTL_TPG_CLRBAR;
+			break;
+			/*
+			 * TV Encoder - Red Frame Test Pattern
+			 */
+		case 1:
+			reg |= TVENC_CTL_TPG_REDCLR;
+			break;
+			/*
+			 * TV Encoder - Modulated Ramp Test Pattern
+			 */
+		default:
+			reg |= TVENC_CTL_TPG_MODRAMP;
+			break;
+		}
+
+		TV_OUT(TV_ENC_CTL, reg);
+		mdelay(5000);
+
+		switch (i) {
+			/*
+			 * TV Encoder - Color Bar Test Pattern
+			 */
+		case 0:
+			reg &= ~TVENC_CTL_TPG_CLRBAR;
+			break;
+			/*
+			 * TV Encoder - Red Frame Test Pattern
+			 */
+		case 1:
+			reg &= ~TVENC_CTL_TPG_REDCLR;
+			break;
+			/*
+			 * TV Encoder - Modulated Ramp Test Pattern
+			 */
+		default:
+			reg &= ~TVENC_CTL_TPG_MODRAMP;
+			break;
+		}
+	}
+}
+
+static int tvenc_resource_initialized;
+
+static int tvenc_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct platform_device *mdp_dev = NULL;
+	struct msm_fb_panel_data *pdata = NULL;
+	int rc, ret;
+	struct clk *ebi1_clk = NULL;
+
+	if (pdev->id == 0) {
+		tvenc_base = ioremap(pdev->resource[0].start,
+					pdev->resource[0].end -
+					pdev->resource[0].start + 1);
+		if (!tvenc_base) {
+			pr_err("tvenc_base ioremap failed!\n");
+			return -ENOMEM;
+		}
+
+		tvenc_clk = clk_get(&pdev->dev, "enc_clk");
+		tvdac_clk = clk_get(&pdev->dev, "dac_clk");
+		tvenc_pclk = clk_get(&pdev->dev, "iface_clk");
+		mdp_tv_clk = clk_get(&pdev->dev, "mdp_clk");
+
+#ifndef CONFIG_MSM_BUS_SCALING
+		ebi1_clk = clk_get(&pdev->dev, "mem_clk");
+		if (IS_ERR(ebi1_clk)) {
+			rc = PTR_ERR(ebi1_clk);
+			goto tvenc_probe_err;
+		}
+		clk_set_rate(ebi1_clk, MSM_SYSTEM_BUS_RATE);
+#endif
+
+#ifdef CONFIG_FB_MSM_MDP40
+		tv_src_clk = clk_get(&pdev->dev, "src_clk");
+		if (IS_ERR(tv_src_clk))
+			tv_src_clk = tvenc_clk; /* Fallback to slave */
+#endif
+
+		if (IS_ERR(tvenc_clk)) {
+			pr_err("%s: error: can't get tvenc_clk!\n", __func__);
+			return PTR_ERR(tvenc_clk);
+		}
+
+		if (IS_ERR(tvdac_clk)) {
+			pr_err("%s: error: can't get tvdac_clk!\n", __func__);
+			return PTR_ERR(tvdac_clk);
+		}
+
+		if (IS_ERR(tvenc_pclk)) {
+			ret = PTR_ERR(tvenc_pclk);
+			if (-ENOENT == ret)
+				pr_info("%s: tvenc_pclk does not exist!\n",
+								__func__);
+			else {
+				pr_err("%s: error: can't get tvenc_pclk!\n",
+								__func__);
+				return ret;
+			}
+		}
+
+		if (IS_ERR(mdp_tv_clk)) {
+			ret = PTR_ERR(mdp_tv_clk);
+			if (-ENOENT == ret)
+				pr_info("%s: mdp_tv_clk does not exist!\n",
+								__func__);
+			else {
+				pr_err("%s: error: can't get mdp_tv_clk!\n",
+								__func__);
+				return ret;
+			}
+		}
+
+		tvenc_pdata = pdev->dev.platform_data;
+		tvenc_resource_initialized = 1;
+		return 0;
+	}
+
+	if (!tvenc_resource_initialized)
+		return -EPERM;
+
+	mfd = platform_get_drvdata(pdev);
+	mfd->ebi1_clk = ebi1_clk;
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
+		return -ENOMEM;
+
+	if (tvenc_base == NULL)
+		return -ENOMEM;
+
+	mdp_dev = platform_device_alloc("mdp", pdev->id);
+	if (!mdp_dev)
+		return -ENOMEM;
+
+	/*
+	 * link to the latest pdev
+	 */
+	mfd->pdev = mdp_dev;
+	mfd->dest = DISPLAY_TV;
+
+	/*
+	 * alloc panel device data
+	 */
+	if (platform_device_add_data
+	    (mdp_dev, pdev->dev.platform_data,
+	     sizeof(struct msm_fb_panel_data))) {
+		pr_err("tvenc_probe: platform_device_add_data failed!\n");
+		platform_device_put(mdp_dev);
+		return -ENOMEM;
+	}
+	/*
+	 * data chain
+	 */
+	pdata = mdp_dev->dev.platform_data;
+	pdata->on = tvenc_on;
+	pdata->off = tvenc_off;
+	pdata->next = pdev;
+
+	/*
+	 * get/set panel specific fb info
+	 */
+	mfd->panel_info = pdata->panel_info;
+#ifdef CONFIG_FB_MSM_MDP40
+	mfd->fb_imgType = MDP_RGB_565;  /* base layer */
+#else
+	mfd->fb_imgType = MDP_YCRYCB_H2V1;
+#endif
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (!tvenc_bus_scale_handle && tvenc_pdata &&
+		tvenc_pdata->bus_scale_table) {
+		tvenc_bus_scale_handle =
+			msm_bus_scale_register_client(
+				tvenc_pdata->bus_scale_table);
+		if (!tvenc_bus_scale_handle) {
+			printk(KERN_ERR "%s not able to get bus scale\n",
+				__func__);
+		}
+	}
+#endif
+
+	/*
+	 * set driver data
+	 */
+	platform_set_drvdata(mdp_dev, mfd);
+
+	/*
+	 * register in mdp driver
+	 */
+	rc = platform_device_add(mdp_dev);
+	if (rc)
+		goto tvenc_probe_err;
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+
+
+	pdev_list[pdev_list_cnt++] = pdev;
+
+	return 0;
+
+tvenc_probe_err:
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (tvenc_pdata && tvenc_pdata->bus_scale_table &&
+		tvenc_bus_scale_handle > 0) {
+		msm_bus_scale_unregister_client(tvenc_bus_scale_handle);
+		tvenc_bus_scale_handle = 0;
+	}
+#endif
+	platform_device_put(mdp_dev);
+	return rc;
+}
+
+static int tvenc_remove(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	mfd = platform_get_drvdata(pdev);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (tvenc_pdata && tvenc_pdata->bus_scale_table &&
+		tvenc_bus_scale_handle > 0) {
+		msm_bus_scale_unregister_client(tvenc_bus_scale_handle);
+		tvenc_bus_scale_handle = 0;
+	}
+#else
+	clk_put(mfd->ebi1_clk);
+#endif
+
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static int tvenc_register_driver(void)
+{
+	return platform_driver_register(&tvenc_driver);
+}
+
+static int __init tvenc_driver_init(void)
+{
+	return tvenc_register_driver();
+}
+
+module_init(tvenc_driver_init);
diff --git a/drivers/video/msm/tvenc.h b/drivers/video/msm/tvenc.h
new file mode 100644
index 0000000..c64c160
--- /dev/null
+++ b/drivers/video/msm/tvenc.h
@@ -0,0 +1,129 @@
+/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef TVENC_H
+#define TVENC_H
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#include "msm_fb_panel.h"
+
+#define NTSC_M		0 /* North America, Korea */
+#define NTSC_J		1 /* Japan */
+#define PAL_BDGHIN	2 /* Non-argentina PAL-N */
+#define PAL_M		3 /* PAL-M */
+#define PAL_N		4 /* Argentina PAL-N */
+
+#define CLOCK_OFF	0
+#define CLOCK_ON	1
+
+/* 3.57954545 Mhz */
+#define TVENC_CTL_TV_MODE_NTSC_M_PAL60  0
+/* 3.57961149 Mhz */
+#define TVENC_CTL_TV_MODE_PAL_M			BIT(0)
+/*non-Argintina = 4.3361875 Mhz */
+#define TVENC_CTL_TV_MODE_PAL_BDGHIN		BIT(1)
+/*Argentina = 3.582055625 Mhz */
+#define TVENC_CTL_TV_MODE_PAL_N			(BIT(1)|BIT(0))
+
+#define TVENC_CTL_ENC_EN			BIT(2)
+#define TVENC_CTL_CC_EN				BIT(3)
+#define TVENC_CTL_CGMS_EN			BIT(4)
+#define TVENC_CTL_MACRO_EN			BIT(5)
+#define TVENC_CTL_Y_FILTER_W_NOTCH		BIT(6)
+#define TVENC_CTL_Y_FILTER_WO_NOTCH		0
+#define TVENC_CTL_Y_FILTER_EN			BIT(7)
+#define TVENC_CTL_CR_FILTER_EN			BIT(8)
+#define TVENC_CTL_CB_FILTER_EN			BIT(9)
+#define TVENC_CTL_SINX_FILTER_EN		BIT(10)
+#define TVENC_CTL_TEST_PATT_EN			BIT(11)
+#define TVENC_CTL_OUTPUT_INV			BIT(12)
+#define TVENC_CTL_PAL60_MODE			BIT(13)
+#define TVENC_CTL_NTSCJ_MODE			BIT(14)
+#define TVENC_CTL_S_VIDEO_EN			BIT(19)
+
+
+#define TVENC_CTL_TPG_CLRBAR			0
+#define TVENC_CTL_TPG_MODRAMP			BIT(15)
+#define TVENC_CTL_TPG_REDCLR			BIT(16)
+#define TVENC_CTL_TPG_NTSC_CBAR			(BIT(16)|BIT(15))
+#define TVENC_CTL_TPG_BLACK			BIT(17)
+#define TVENC_CTL_TPG_WHITE100			(BIT(17)|BIT(15))
+#define TVENC_CTL_TPG_YELLOW75			(BIT(17)|BIT(16))
+#define TVENC_CTL_TPG_CYAN75			(BIT(17)|BIT(16)|BIT(15))
+#define TVENC_CTL_TPG_GREEN75			BIT(18)
+#define TVENC_CTL_TPG_MAGENTA75			(BIT(18)|BIT(15))
+#define TVENC_CTL_TPG_RED75			(BIT(18)|BIT(16))
+#define TVENC_CTL_TPG_BLUE75			(BIT(18)|BIT(16)|BIT(15))
+#define TVENC_CTL_TPG_WHITE75			(BIT(18)|BIT(17))
+#define TVENC_CTL_TPG_WHITE_TRSTN		(BIT(18)|BIT(17)|BIT(15))
+
+#define TVENC_LOAD_DETECT_EN			BIT(8)
+
+#ifdef TVENC_C
+void *tvenc_base;
+struct tvenc_platform_data *tvenc_pdata;
+#else
+extern void *tvenc_base;
+extern struct tvenc_platform_data *tvenc_pdata;
+#endif
+
+#define TV_OUT(reg, v)		writel(v, tvenc_base + MSM_##reg)
+#define TV_IN(reg)		readl(tvenc_base + MSM_##reg)
+
+#define MSM_TV_ENC_CTL				0x00
+#define MSM_TV_LEVEL				0x04
+#define MSM_TV_GAIN				0x08
+#define MSM_TV_OFFSET				0x0c
+#define MSM_TV_CGMS				0x10
+#define MSM_TV_SYNC_1				0x14
+#define MSM_TV_SYNC_2				0x18
+#define MSM_TV_SYNC_3				0x1c
+#define MSM_TV_SYNC_4				0x20
+#define MSM_TV_SYNC_5				0x24
+#define MSM_TV_SYNC_6				0x28
+#define MSM_TV_SYNC_7				0x2c
+#define MSM_TV_BURST_V1				0x30
+#define MSM_TV_BURST_V2				0x34
+#define MSM_TV_BURST_V3				0x38
+#define MSM_TV_BURST_V4				0x3c
+#define MSM_TV_BURST_H				0x40
+#define MSM_TV_SOL_REQ_ODD			0x44
+#define MSM_TV_SOL_REQ_EVEN			0x48
+#define MSM_TV_DAC_CTL				0x4c
+#define MSM_TV_TEST_MUX				0x50
+#define MSM_TV_TEST_MODE			0x54
+#define MSM_TV_TEST_MISR_RESET			0x58
+#define MSM_TV_TEST_EXPORT_MISR			0x5c
+#define MSM_TV_TEST_MISR_CURR_VAL		0x60
+#define MSM_TV_TEST_SOF_CFG			0x64
+#define MSM_TV_DAC_INTF				0x100
+
+#define MSM_TV_INTR_ENABLE			0x200
+#define MSM_TV_INTR_STATUS			0x204
+#define MSM_TV_INTR_CLEAR			0x208
+
+int tvenc_set_encoder_clock(boolean clock_on);
+int tvenc_set_clock(boolean clock_on);
+#endif /* TVENC_H */
diff --git a/drivers/video/msm/tvout_msm.c b/drivers/video/msm/tvout_msm.c
new file mode 100644
index 0000000..9ee55cc
--- /dev/null
+++ b/drivers/video/msm/tvout_msm.c
@@ -0,0 +1,652 @@
+/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#include "msm_fb.h"
+#include "tvenc.h"
+#include "external_common.h"
+
+#define TVOUT_HPD_DUTY_CYCLE 3000
+
+#define TV_DIMENSION_MAX_WIDTH		720
+#define TV_DIMENSION_MAX_HEIGHT		576
+
+struct tvout_msm_state_type {
+	struct external_common_state_type common;
+	struct platform_device *pdev;
+	struct timer_list hpd_state_timer;
+	struct timer_list hpd_work_timer;
+	struct work_struct hpd_work;
+	uint32 hpd_int_status;
+	uint32 prev_hpd_int_status;
+	uint32 five_retry;
+	int irq;
+	uint16 y_res;
+	boolean hpd_initialized;
+	boolean disp_powered_up;
+#ifdef CONFIG_SUSPEND
+	boolean pm_suspended;
+#endif
+
+};
+
+static struct tvout_msm_state_type *tvout_msm_state;
+static DEFINE_MUTEX(tvout_msm_state_mutex);
+
+static int tvout_off(struct platform_device *pdev);
+static int tvout_on(struct platform_device *pdev);
+static void tvout_check_status(void);
+
+static void tvout_msm_turn_on(boolean power_on)
+{
+	uint32 reg_val = 0;
+	reg_val = TV_IN(TV_ENC_CTL);
+	if (power_on) {
+		DEV_DBG("%s: TV Encoder turned on\n", __func__);
+		reg_val |= TVENC_CTL_ENC_EN;
+	} else {
+		DEV_DBG("%s: TV Encoder turned off\n", __func__);
+		reg_val = 0;
+	}
+	/* Enable TV Encoder*/
+	TV_OUT(TV_ENC_CTL, reg_val);
+}
+
+static void tvout_check_status()
+{
+	tvout_msm_state->hpd_int_status &= 0x05;
+	/* hpd_int_status could either be 0x05 or 0x04 for a cable
+		plug-out event when cable detect is driven by polling. */
+	if ((((tvout_msm_state->hpd_int_status == 0x05) ||
+		(tvout_msm_state->hpd_int_status == 0x04)) &&
+		(tvout_msm_state->prev_hpd_int_status == BIT(2))) ||
+		((tvout_msm_state->hpd_int_status == 0x01) &&
+		(tvout_msm_state->prev_hpd_int_status == BIT(0)))) {
+		DEV_DBG("%s: cable event sent already!", __func__);
+		return;
+	}
+
+	if (tvout_msm_state->hpd_int_status & BIT(2)) {
+		DEV_DBG("%s: cable plug-out\n", __func__);
+		mutex_lock(&external_common_state_hpd_mutex);
+		external_common_state->hpd_state = FALSE;
+		mutex_unlock(&external_common_state_hpd_mutex);
+		kobject_uevent(external_common_state->uevent_kobj,
+				KOBJ_OFFLINE);
+		tvout_msm_state->prev_hpd_int_status = BIT(2);
+	} else if (tvout_msm_state->hpd_int_status & BIT(0)) {
+		DEV_DBG("%s: cable plug-in\n", __func__);
+		mutex_lock(&external_common_state_hpd_mutex);
+		external_common_state->hpd_state = TRUE;
+		mutex_unlock(&external_common_state_hpd_mutex);
+		kobject_uevent(external_common_state->uevent_kobj,
+				KOBJ_ONLINE);
+		tvout_msm_state->prev_hpd_int_status = BIT(0);
+	}
+}
+
+/* ISR for TV out cable detect */
+static irqreturn_t tvout_msm_isr(int irq, void *dev_id)
+{
+	tvout_msm_state->hpd_int_status = TV_IN(TV_INTR_STATUS);
+	TV_OUT(TV_INTR_CLEAR, tvout_msm_state->hpd_int_status);
+	DEV_DBG("%s: ISR: 0x%02x\n", __func__,
+		tvout_msm_state->hpd_int_status & 0x05);
+
+	if (tvenc_pdata->poll)
+		if (!tvout_msm_state || !tvout_msm_state->disp_powered_up) {
+			DEV_DBG("%s: ISR ignored, display not yet powered on\n",
+				__func__);
+			return IRQ_HANDLED;
+		}
+	if (tvout_msm_state->hpd_int_status & BIT(0) ||
+		tvout_msm_state->hpd_int_status & BIT(2)) {
+		/* Use .75sec to debounce the interrupt */
+		mod_timer(&tvout_msm_state->hpd_state_timer, jiffies
+			+ msecs_to_jiffies(750));
+	}
+
+	return IRQ_HANDLED;
+}
+
+/* Interrupt debounce timer */
+static void tvout_msm_hpd_state_timer(unsigned long data)
+{
+#ifdef CONFIG_SUSPEND
+	mutex_lock(&tvout_msm_state_mutex);
+	if (tvout_msm_state->pm_suspended) {
+		mutex_unlock(&tvout_msm_state_mutex);
+		DEV_WARN("%s: ignored, pm_suspended\n", __func__);
+		return;
+	}
+	mutex_unlock(&tvout_msm_state_mutex);
+#endif
+
+	if (tvenc_pdata->poll)
+		if (!tvout_msm_state || !tvout_msm_state->disp_powered_up) {
+			DEV_DBG("%s: ignored, display powered off\n", __func__);
+			return;
+		}
+
+	/* TV_INTR_STATUS[0x204]
+		When a TV_ENC interrupt occurs, then reading this register will
+		indicate what caused the interrupt since that each bit indicates
+		the source of the interrupt that had happened. If multiple
+		interrupt sources had happened, then multiple bits of this
+		register will be set
+		Bit 0 : Load present on Video1
+		Bit 1 : Load present on Video2
+		Bit 2 : Load removed on Video1
+		Bit 3 : Load removed on Video2
+	*/
+
+	/* Locking interrupt status is not required because
+	last status read after debouncing is used */
+	if ((tvout_msm_state->hpd_int_status & 0x05) == 0x05) {
+		/* SW-workaround :If the status read after debouncing is
+		0x05(indicating both load present & load removed- which can't
+		happen in reality), force an update. If status remains 0x05
+		after retry, it's a cable unplug event */
+		if (++tvout_msm_state->five_retry < 2) {
+			uint32 reg;
+			DEV_DBG("tvout: Timer: 0x05\n");
+			TV_OUT(TV_INTR_CLEAR, 0xf);
+			reg = TV_IN(TV_DAC_INTF);
+			TV_OUT(TV_DAC_INTF, reg & ~TVENC_LOAD_DETECT_EN);
+			TV_OUT(TV_INTR_CLEAR, 0xf);
+			reg = TV_IN(TV_DAC_INTF);
+			TV_OUT(TV_DAC_INTF, reg | TVENC_LOAD_DETECT_EN);
+			return;
+		}
+	}
+	tvout_msm_state->five_retry = 0;
+	tvout_check_status();
+}
+
+static void tvout_msm_hpd_work(struct work_struct *work)
+{
+	uint32 reg;
+
+#ifdef CONFIG_SUSPEND
+	mutex_lock(&tvout_msm_state_mutex);
+	if (tvout_msm_state->pm_suspended) {
+		mutex_unlock(&tvout_msm_state_mutex);
+		DEV_WARN("%s: ignored, pm_suspended\n", __func__);
+		return;
+	}
+	mutex_unlock(&tvout_msm_state_mutex);
+#endif
+
+	/* Enable power lines & clocks */
+	tvenc_pdata->pm_vid_en(1);
+	tvenc_set_clock(CLOCK_ON);
+
+	/* Enable encoder to get a stable interrupt */
+	reg = TV_IN(TV_ENC_CTL);
+	TV_OUT(TV_ENC_CTL, reg | TVENC_CTL_ENC_EN);
+
+	/* SW- workaround to update status register */
+	reg = TV_IN(TV_DAC_INTF);
+	TV_OUT(TV_DAC_INTF, reg & ~TVENC_LOAD_DETECT_EN);
+	TV_OUT(TV_INTR_CLEAR, 0xf);
+	reg = TV_IN(TV_DAC_INTF);
+	TV_OUT(TV_DAC_INTF, reg | TVENC_LOAD_DETECT_EN);
+
+	tvout_msm_state->hpd_int_status = TV_IN(TV_INTR_STATUS);
+
+	/* Disable TV encoder */
+	reg = TV_IN(TV_ENC_CTL);
+	TV_OUT(TV_ENC_CTL, reg & ~TVENC_CTL_ENC_EN);
+
+	/*Disable power lines & clocks */
+	tvenc_set_clock(CLOCK_OFF);
+	tvenc_pdata->pm_vid_en(0);
+
+	DEV_DBG("%s: ISR: 0x%02x\n", __func__,
+		tvout_msm_state->hpd_int_status & 0x05);
+
+	mod_timer(&tvout_msm_state->hpd_work_timer, jiffies
+		+ msecs_to_jiffies(TVOUT_HPD_DUTY_CYCLE));
+
+	tvout_check_status();
+}
+
+static void tvout_msm_hpd_work_timer(unsigned long data)
+{
+	schedule_work(&tvout_msm_state->hpd_work);
+}
+
+static int tvout_on(struct platform_device *pdev)
+{
+	uint32 reg = 0;
+	struct fb_var_screeninfo *var;
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+#ifdef CONFIG_SUSPEND
+	mutex_lock(&tvout_msm_state_mutex);
+	if (tvout_msm_state->pm_suspended) {
+		mutex_unlock(&tvout_msm_state_mutex);
+		DEV_WARN("%s: ignored, pm_suspended\n", __func__);
+		return -ENODEV;
+	}
+	mutex_unlock(&tvout_msm_state_mutex);
+#endif
+
+	var = &mfd->fbi->var;
+	if (var->reserved[3] >= NTSC_M && var->reserved[3] <= PAL_N)
+		external_common_state->video_resolution = var->reserved[3];
+
+	tvout_msm_state->pdev = pdev;
+	if (del_timer(&tvout_msm_state->hpd_work_timer))
+		DEV_DBG("%s: work timer stopped\n", __func__);
+
+	TV_OUT(TV_ENC_CTL, 0);	/* disable TV encoder */
+
+	switch (external_common_state->video_resolution) {
+	case NTSC_M:
+	case NTSC_J:
+		TV_OUT(TV_CGMS, 0x0);
+		/*  NTSC Timing */
+		TV_OUT(TV_SYNC_1, 0x0020009e);
+		TV_OUT(TV_SYNC_2, 0x011306B4);
+		TV_OUT(TV_SYNC_3, 0x0006000C);
+		TV_OUT(TV_SYNC_4, 0x0028020D);
+		TV_OUT(TV_SYNC_5, 0x005E02FB);
+		TV_OUT(TV_SYNC_6, 0x0006000C);
+		TV_OUT(TV_SYNC_7, 0x00000012);
+		TV_OUT(TV_BURST_V1, 0x0013020D);
+		TV_OUT(TV_BURST_V2, 0x0014020C);
+		TV_OUT(TV_BURST_V3, 0x0013020D);
+		TV_OUT(TV_BURST_V4, 0x0014020C);
+		TV_OUT(TV_BURST_H, 0x00AE00F2);
+		TV_OUT(TV_SOL_REQ_ODD, 0x00280208);
+		TV_OUT(TV_SOL_REQ_EVEN, 0x00290209);
+
+		reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60;
+
+		if (external_common_state->video_resolution == NTSC_M) {
+			/* Cr gain 11, Cb gain C6, y_gain 97 */
+			TV_OUT(TV_GAIN, 0x0081B697);
+		} else {
+			/* Cr gain 11, Cb gain C6, y_gain 97 */
+			TV_OUT(TV_GAIN, 0x008bc4a3);
+			reg |= TVENC_CTL_NTSCJ_MODE;
+		}
+
+		var->yres = 480;
+		break;
+	case PAL_BDGHIN:
+	case PAL_N:
+		/*  PAL Timing */
+		TV_OUT(TV_SYNC_1, 0x00180097);
+		TV_OUT(TV_SYNC_3, 0x0005000a);
+		TV_OUT(TV_SYNC_4, 0x00320271);
+		TV_OUT(TV_SYNC_5, 0x005602f9);
+		TV_OUT(TV_SYNC_6, 0x0005000a);
+		TV_OUT(TV_SYNC_7, 0x0000000f);
+		TV_OUT(TV_BURST_V1, 0x0012026e);
+		TV_OUT(TV_BURST_V2, 0x0011026d);
+		TV_OUT(TV_BURST_V3, 0x00100270);
+		TV_OUT(TV_BURST_V4, 0x0013026f);
+		TV_OUT(TV_SOL_REQ_ODD, 0x0030026e);
+		TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f);
+
+		if (external_common_state->video_resolution == PAL_BDGHIN) {
+			/* Cr gain 11, Cb gain C6, y_gain 97 */
+			TV_OUT(TV_GAIN, 0x0088c1a0);
+			TV_OUT(TV_CGMS, 0x00012345);
+			TV_OUT(TV_SYNC_2, 0x011f06c0);
+			TV_OUT(TV_BURST_H, 0x00af00ea);
+			reg |= TVENC_CTL_TV_MODE_PAL_BDGHIN;
+		} else {
+			/* Cr gain 11, Cb gain C6, y_gain 97 */
+			TV_OUT(TV_GAIN, 0x0081b697);
+			TV_OUT(TV_CGMS, 0x000af317);
+			TV_OUT(TV_SYNC_2, 0x12006c0);
+			TV_OUT(TV_BURST_H, 0x00af00fa);
+			reg |= TVENC_CTL_TV_MODE_PAL_N;
+		}
+		var->yres = 576;
+		break;
+	case PAL_M:
+		/* Cr gain 11, Cb gain C6, y_gain 97 */
+		TV_OUT(TV_GAIN, 0x0081b697);
+		TV_OUT(TV_CGMS, 0x000af317);
+		TV_OUT(TV_TEST_MUX, 0x000001c3);
+		TV_OUT(TV_TEST_MODE, 0x00000002);
+		/*  PAL Timing */
+		TV_OUT(TV_SYNC_1, 0x0020009e);
+		TV_OUT(TV_SYNC_2, 0x011306b4);
+		TV_OUT(TV_SYNC_3, 0x0006000c);
+		TV_OUT(TV_SYNC_4, 0x0028020D);
+		TV_OUT(TV_SYNC_5, 0x005e02fb);
+		TV_OUT(TV_SYNC_6, 0x0006000c);
+		TV_OUT(TV_SYNC_7, 0x00000012);
+		TV_OUT(TV_BURST_V1, 0x0012020b);
+		TV_OUT(TV_BURST_V2, 0x0016020c);
+		TV_OUT(TV_BURST_V3, 0x00150209);
+		TV_OUT(TV_BURST_V4, 0x0013020c);
+		TV_OUT(TV_BURST_H, 0x00bf010b);
+		TV_OUT(TV_SOL_REQ_ODD, 0x00280208);
+		TV_OUT(TV_SOL_REQ_EVEN, 0x00290209);
+
+		reg |= TVENC_CTL_TV_MODE_PAL_M;
+		var->yres = 480;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	reg |= TVENC_CTL_Y_FILTER_EN | TVENC_CTL_CR_FILTER_EN |
+		TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN;
+
+	/* DC offset to 0. */
+	TV_OUT(TV_LEVEL, 0x00000000);
+	TV_OUT(TV_OFFSET, 0x008080f0);
+
+#ifdef CONFIG_FB_MSM_TVOUT_SVIDEO
+	reg |= TVENC_CTL_S_VIDEO_EN;
+#endif
+#if defined(CONFIG_FB_MSM_MDP31)
+	TV_OUT(TV_DAC_INTF, 0x29);
+#endif
+	TV_OUT(TV_ENC_CTL, reg);
+
+	if (!tvout_msm_state->hpd_initialized) {
+		tvout_msm_state->hpd_initialized = TRUE;
+		/* Load detect enable */
+		reg = TV_IN(TV_DAC_INTF);
+		reg |= TVENC_LOAD_DETECT_EN;
+		TV_OUT(TV_DAC_INTF, reg);
+	}
+
+	tvout_msm_state->disp_powered_up = TRUE;
+	tvout_msm_turn_on(TRUE);
+
+	if (tvenc_pdata->poll) {
+		/* Enable Load present & removal interrupts for Video1 */
+		TV_OUT(TV_INTR_ENABLE, 0x5);
+
+		/* Enable interrupts when display is on */
+		enable_irq(tvout_msm_state->irq);
+	}
+	return 0;
+}
+
+static int tvout_off(struct platform_device *pdev)
+{
+	/* Disable TV encoder irqs when display is off */
+	if (tvenc_pdata->poll)
+		disable_irq(tvout_msm_state->irq);
+	tvout_msm_turn_on(FALSE);
+	tvout_msm_state->hpd_initialized = FALSE;
+	tvout_msm_state->disp_powered_up = FALSE;
+	if (tvenc_pdata->poll) {
+		mod_timer(&tvout_msm_state->hpd_work_timer, jiffies
+			+ msecs_to_jiffies(TVOUT_HPD_DUTY_CYCLE));
+	}
+	return 0;
+}
+
+static int __devinit tvout_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	uint32 reg;
+	struct platform_device *fb_dev;
+
+#ifdef CONFIG_FB_MSM_TVOUT_NTSC_M
+	external_common_state->video_resolution = NTSC_M;
+#elif defined CONFIG_FB_MSM_TVOUT_NTSC_J
+	external_common_state->video_resolution = NTSC_J;
+#elif defined CONFIG_FB_MSM_TVOUT_PAL_M
+	external_common_state->video_resolution = PAL_M;
+#elif defined CONFIG_FB_MSM_TVOUT_PAL_N
+	external_common_state->video_resolution = PAL_N;
+#elif defined CONFIG_FB_MSM_TVOUT_PAL_BDGHIN
+	external_common_state->video_resolution = PAL_BDGHIN;
+#endif
+	external_common_state->dev = &pdev->dev;
+	if (pdev->id == 0) {
+		struct resource *res;
+
+		#define GET_RES(name, mode) do {			\
+			res = platform_get_resource_byname(pdev, mode, name); \
+			if (!res) {					\
+				DEV_DBG("'" name "' resource not found\n"); \
+				rc = -ENODEV;				\
+				goto error;				\
+			}						\
+		} while (0)
+
+		#define GET_IRQ(var, name) do {				\
+			GET_RES(name, IORESOURCE_IRQ);			\
+			var = res->start;				\
+		} while (0)
+
+		GET_IRQ(tvout_msm_state->irq, "tvout_device_irq");
+		#undef GET_IRQ
+		#undef GET_RES
+		return 0;
+	}
+
+	DEV_DBG("%s: tvout_msm_state->irq : %d",
+			__func__, tvout_msm_state->irq);
+
+	rc = request_irq(tvout_msm_state->irq, &tvout_msm_isr,
+		IRQF_TRIGGER_HIGH, "tvout_msm_isr", NULL);
+
+	if (rc) {
+		DEV_DBG("Init FAILED: IRQ request, rc=%d\n", rc);
+		goto error;
+	}
+	disable_irq(tvout_msm_state->irq);
+
+	init_timer(&tvout_msm_state->hpd_state_timer);
+	tvout_msm_state->hpd_state_timer.function =
+		tvout_msm_hpd_state_timer;
+	tvout_msm_state->hpd_state_timer.data = (uint32)NULL;
+	tvout_msm_state->hpd_state_timer.expires = jiffies
+						+ msecs_to_jiffies(1000);
+
+	if (tvenc_pdata->poll) {
+		init_timer(&tvout_msm_state->hpd_work_timer);
+		tvout_msm_state->hpd_work_timer.function =
+			tvout_msm_hpd_work_timer;
+		tvout_msm_state->hpd_work_timer.data = (uint32)NULL;
+		tvout_msm_state->hpd_work_timer.expires = jiffies
+						+ msecs_to_jiffies(1000);
+	}
+	fb_dev = msm_fb_add_device(pdev);
+	if (fb_dev) {
+		rc = external_common_state_create(fb_dev);
+		if (rc) {
+			DEV_ERR("Init FAILED: tvout_msm_state_create, rc=%d\n",
+				rc);
+			goto error;
+		}
+		if (tvenc_pdata->poll) {
+			/* Start polling timer to detect load */
+			mod_timer(&tvout_msm_state->hpd_work_timer, jiffies
+				+ msecs_to_jiffies(TVOUT_HPD_DUTY_CYCLE));
+		} else {
+			/* Enable interrupt to detect load */
+			tvenc_set_encoder_clock(CLOCK_ON);
+			reg = TV_IN(TV_DAC_INTF);
+			reg |= TVENC_LOAD_DETECT_EN;
+			TV_OUT(TV_DAC_INTF, reg);
+			TV_OUT(TV_INTR_ENABLE, 0x5);
+			enable_irq(tvout_msm_state->irq);
+		}
+	} else
+		DEV_ERR("Init FAILED: failed to add fb device\n");
+error:
+	return 0;
+}
+
+static int __devexit tvout_remove(struct platform_device *pdev)
+{
+	external_common_state_remove();
+	kfree(tvout_msm_state);
+	tvout_msm_state = NULL;
+	return 0;
+}
+
+#ifdef CONFIG_SUSPEND
+static int tvout_device_pm_suspend(struct device *dev)
+{
+	mutex_lock(&tvout_msm_state_mutex);
+	if (tvout_msm_state->pm_suspended) {
+		mutex_unlock(&tvout_msm_state_mutex);
+		return 0;
+	}
+	if (tvenc_pdata->poll) {
+		if (del_timer(&tvout_msm_state->hpd_work_timer))
+			DEV_DBG("%s: suspending cable detect timer\n",
+				__func__);
+	} else {
+		disable_irq(tvout_msm_state->irq);
+		tvenc_set_encoder_clock(CLOCK_OFF);
+	}
+	tvout_msm_state->pm_suspended = TRUE;
+	mutex_unlock(&tvout_msm_state_mutex);
+	return 0;
+}
+
+static int tvout_device_pm_resume(struct device *dev)
+{
+	mutex_lock(&tvout_msm_state_mutex);
+	if (!tvout_msm_state->pm_suspended) {
+		mutex_unlock(&tvout_msm_state_mutex);
+		return 0;
+	}
+
+	if (tvenc_pdata->poll) {
+		tvout_msm_state->pm_suspended = FALSE;
+		mod_timer(&tvout_msm_state->hpd_work_timer, jiffies
+				+ msecs_to_jiffies(TVOUT_HPD_DUTY_CYCLE));
+		mutex_unlock(&tvout_msm_state_mutex);
+		DEV_DBG("%s: resuming cable detect timer\n", __func__);
+	} else {
+		tvenc_set_encoder_clock(CLOCK_ON);
+		tvout_msm_state->pm_suspended = FALSE;
+		mutex_unlock(&tvout_msm_state_mutex);
+		enable_irq(tvout_msm_state->irq);
+		DEV_DBG("%s: enable cable detect interrupt\n", __func__);
+	}
+	return 0;
+}
+#else
+#define tvout_device_pm_suspend	NULL
+#define tvout_device_pm_resume		NULL
+#endif
+
+
+static const struct dev_pm_ops tvout_device_pm_ops = {
+	.suspend = tvout_device_pm_suspend,
+	.resume = tvout_device_pm_resume,
+};
+
+static struct platform_driver this_driver = {
+	.probe  = tvout_probe,
+	.remove = tvout_remove,
+	.driver = {
+		.name	= "tvout_device",
+		.pm	= &tvout_device_pm_ops,
+	},
+};
+
+static struct msm_fb_panel_data tvout_panel_data = {
+	.panel_info.xres = TV_DIMENSION_MAX_WIDTH,
+	.panel_info.yres = TV_DIMENSION_MAX_HEIGHT,
+	.panel_info.type = TV_PANEL,
+	.panel_info.pdest = DISPLAY_2,
+	.panel_info.wait_cycle = 0,
+#ifdef CONFIG_FB_MSM_MDP40
+	.panel_info.bpp = 24,
+#else
+	.panel_info.bpp = 16,
+#endif
+	.panel_info.fb_num = 2,
+	.on = tvout_on,
+	.off = tvout_off,
+};
+
+static struct platform_device this_device = {
+	.name   = "tvout_device",
+	.id = 1,
+	.dev	= {
+		.platform_data = &tvout_panel_data,
+	}
+};
+
+static int __init tvout_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("tvout_msm"))
+		return 0;
+
+	tvout_msm_state = kzalloc(sizeof(*tvout_msm_state), GFP_KERNEL);
+	if (!tvout_msm_state) {
+		DEV_ERR("tvout_msm_init FAILED: out of memory\n");
+		ret = -ENOMEM;
+		goto init_exit;
+	}
+
+	external_common_state = &tvout_msm_state->common;
+	ret = platform_driver_register(&this_driver);
+	if (ret) {
+		DEV_ERR("tvout_device_init FAILED: platform_driver_register\
+			rc=%d\n", ret);
+		goto init_exit;
+	}
+
+	ret = platform_device_register(&this_device);
+	if (ret) {
+		DEV_ERR("tvout_device_init FAILED: platform_driver_register\
+			rc=%d\n", ret);
+		platform_driver_unregister(&this_driver);
+		goto init_exit;
+	}
+
+	INIT_WORK(&tvout_msm_state->hpd_work, tvout_msm_hpd_work);
+	return 0;
+
+init_exit:
+	kfree(tvout_msm_state);
+	tvout_msm_state = NULL;
+	return ret;
+}
+
+static void __exit tvout_exit(void)
+{
+	platform_device_unregister(&this_device);
+	platform_driver_unregister(&this_driver);
+}
+
+module_init(tvout_init);
+module_exit(tvout_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
+MODULE_DESCRIPTION("TV out driver");
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
new file mode 100644
index 0000000..bd37cc0
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
@@ -0,0 +1,721 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <mach/msm_memtypes.h>
+#include "vcd_ddl.h"
+#include "vcd_ddl_metadata.h"
+#include "vcd_res_tracker_api.h"
+
+static unsigned int first_time;
+
+u32 ddl_device_init(struct ddl_init_config *ddl_init_config,
+	void *client_data)
+{
+	struct ddl_context *ddl_context;
+	u32 status = VCD_S_SUCCESS;
+	void *ptr = NULL;
+	DDL_MSG_HIGH("ddl_device_init");
+
+	if ((!ddl_init_config) || (!ddl_init_config->ddl_callback) ||
+		(!ddl_init_config->core_virtual_base_addr)) {
+		DDL_MSG_ERROR("ddl_dev_init:Bad_argument");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	ddl_context = ddl_get_context();
+	if (DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dev_init:Multiple_init");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!DDL_IS_IDLE(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dev_init:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	memset(ddl_context, 0, sizeof(struct ddl_context));
+	DDL_BUSY(ddl_context);
+	if (res_trk_get_enable_ion()) {
+		DDL_MSG_LOW("ddl_dev_init:ION framework enabled");
+		ddl_context->video_ion_client  =
+			res_trk_get_ion_client();
+		if (!ddl_context->video_ion_client) {
+			DDL_MSG_ERROR("ION client create failed");
+			return VCD_ERR_ILLEGAL_OP;
+		}
+	}
+	ddl_context->ddl_callback = ddl_init_config->ddl_callback;
+	if (ddl_init_config->interrupt_clr)
+		ddl_context->interrupt_clr =
+			ddl_init_config->interrupt_clr;
+	ddl_context->core_virtual_base_addr =
+		ddl_init_config->core_virtual_base_addr;
+	ddl_context->client_data = client_data;
+	ddl_context->ddl_hw_response.arg1 = DDL_INVALID_INTR_STATUS;
+
+	ddl_context->frame_channel_depth = VCD_FRAME_COMMAND_DEPTH;
+
+	DDL_MSG_LOW("%s() : virtual address of core(%x)\n", __func__,
+		(u32) ddl_init_config->core_virtual_base_addr);
+	vidc_1080p_set_device_base_addr(
+		ddl_context->core_virtual_base_addr);
+	ddl_context->cmd_state =	DDL_CMD_INVALID;
+	ddl_client_transact(DDL_INIT_CLIENTS, NULL);
+	ddl_context->fw_memory_size =
+		DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE;
+	if (res_trk_get_firmware_addr(&ddl_context->dram_base_a)) {
+		DDL_MSG_ERROR("firmware allocation failed");
+		ptr = NULL;
+	} else {
+		ptr = (void *)ddl_context->dram_base_a.virtual_base_addr;
+	}
+	if (!ptr) {
+		DDL_MSG_ERROR("Memory Aocation Failed for FW Base");
+		status = VCD_ERR_ALLOC_FAIL;
+	} else {
+		DDL_MSG_LOW("%s() : physical address of base(%x)\n",
+			 __func__, (u32) ddl_context->dram_base_a.\
+			align_physical_addr);
+		ddl_context->dram_base_b.align_physical_addr =
+			ddl_context->dram_base_a.align_physical_addr;
+		ddl_context->dram_base_b.align_virtual_addr  =
+			ddl_context->dram_base_a.align_virtual_addr;
+	}
+	if (!status) {
+		ddl_context->metadata_shared_input.mem_type = DDL_FW_MEM;
+		ptr = ddl_pmem_alloc(&ddl_context->metadata_shared_input,
+			DDL_METADATA_TOTAL_INPUTBUFSIZE,
+			DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		if (!ptr) {
+			DDL_MSG_ERROR("ddl_device_init: metadata alloc fail");
+			status = VCD_ERR_ALLOC_FAIL;
+		}
+	}
+	if (!status && !ddl_fw_init(&ddl_context->dram_base_a)) {
+		DDL_MSG_ERROR("ddl_dev_init:fw_init_failed");
+		status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (!status) {
+		ddl_context->cmd_state = DDL_CMD_DMA_INIT;
+		ddl_vidc_core_init(ddl_context);
+	} else {
+		ddl_release_context_buffers(ddl_context);
+		DDL_IDLE(ddl_context);
+	}
+	return status;
+}
+
+u32 ddl_device_release(void *client_data)
+{
+	struct ddl_context *ddl_context;
+
+	DDL_MSG_HIGH("ddl_device_release");
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_IDLE(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dev_rel:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dev_rel:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl_client_transact(DDL_ACTIVE_CLIENT, NULL)) {
+		DDL_MSG_ERROR("ddl_dev_rel:Client_present_err");
+		return VCD_ERR_CLIENT_PRESENT;
+	}
+	DDL_BUSY(ddl_context);
+	ddl_context->device_state = DDL_DEVICE_NOTINIT;
+	ddl_context->client_data = client_data;
+	ddl_context->cmd_state = DDL_CMD_INVALID;
+	ddl_vidc_core_term(ddl_context);
+	DDL_MSG_LOW("FW_ENDDONE");
+	ddl_context->core_virtual_base_addr = NULL;
+	ddl_release_context_buffers(ddl_context);
+	ddl_context->video_ion_client = NULL;
+	DDL_IDLE(ddl_context);
+	return VCD_S_SUCCESS;
+}
+
+u32 ddl_open(u32 **ddl_handle, u32 decoding)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_client_context *ddl;
+	void *ptr;
+	u32 status;
+
+	DDL_MSG_HIGH("ddl_open");
+	if (!ddl_handle) {
+		DDL_MSG_ERROR("ddl_open:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_open:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	status = ddl_client_transact(DDL_GET_CLIENT, &ddl);
+	if (status) {
+		DDL_MSG_ERROR("ddl_open:Client_trasac_failed");
+		return status;
+	}
+	if (res_trk_check_for_sec_session())
+		ddl->shared_mem[0].mem_type = DDL_CMD_MEM;
+	else
+		ddl->shared_mem[0].mem_type = DDL_FW_MEM;
+	ptr = ddl_pmem_alloc(&ddl->shared_mem[0],
+			DDL_FW_AUX_HOST_CMD_SPACE_SIZE, 0);
+	if (!ptr)
+		status = VCD_ERR_ALLOC_FAIL;
+	if (!status && ddl_context->frame_channel_depth
+		== VCD_DUAL_FRAME_COMMAND_CHANNEL) {
+		if (res_trk_check_for_sec_session())
+			ddl->shared_mem[1].mem_type = DDL_CMD_MEM;
+		else
+			ddl->shared_mem[1].mem_type = DDL_FW_MEM;
+		ptr = ddl_pmem_alloc(&ddl->shared_mem[1],
+				DDL_FW_AUX_HOST_CMD_SPACE_SIZE, 0);
+		if (!ptr) {
+			ddl_pmem_free(&ddl->shared_mem[0]);
+			status = VCD_ERR_ALLOC_FAIL;
+		}
+	}
+	if (!status) {
+		memset(ddl->shared_mem[0].align_virtual_addr, 0,
+			DDL_FW_AUX_HOST_CMD_SPACE_SIZE);
+		if (ddl_context->frame_channel_depth ==
+			VCD_DUAL_FRAME_COMMAND_CHANNEL) {
+			memset(ddl->shared_mem[1].align_virtual_addr, 0,
+				DDL_FW_AUX_HOST_CMD_SPACE_SIZE);
+		}
+		DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_OPEN",
+		ddl_get_state_string(ddl->client_state));
+		ddl->client_state = DDL_CLIENT_OPEN;
+		ddl->codec_data.hdr.decoding = decoding;
+		ddl->decoding = decoding;
+		ddl_set_default_meta_data_hdr(ddl);
+		ddl_set_initial_default_values(ddl);
+		*ddl_handle	= (u32 *) ddl;
+	} else {
+		ddl_pmem_free(&ddl->shared_mem[0]);
+		if (ddl_context->frame_channel_depth
+			== VCD_DUAL_FRAME_COMMAND_CHANNEL)
+			ddl_pmem_free(&ddl->shared_mem[1]);
+		ddl_client_transact(DDL_FREE_CLIENT, &ddl);
+	}
+	return status;
+}
+
+u32 ddl_close(u32 **ddl_handle)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_client_context **pp_ddl =
+		(struct ddl_client_context **)ddl_handle;
+
+	DDL_MSG_HIGH("ddl_close");
+	if (!pp_ddl || !*pp_ddl) {
+		DDL_MSG_ERROR("ddl_close:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_close:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!DDLCLIENT_STATE_IS(*pp_ddl, DDL_CLIENT_OPEN)) {
+		DDL_MSG_ERROR("ddl_close:Not_in_open_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	ddl_pmem_free(&(*pp_ddl)->shared_mem[0]);
+	if (ddl_context->frame_channel_depth ==
+		VCD_DUAL_FRAME_COMMAND_CHANNEL)
+		ddl_pmem_free(&(*pp_ddl)->shared_mem[1]);
+	DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_INVALID",
+	ddl_get_state_string((*pp_ddl)->client_state));
+	(*pp_ddl)->client_state = DDL_CLIENT_INVALID;
+	ddl_codec_type_transact(*pp_ddl, true, (enum vcd_codec)0);
+	ddl_client_transact(DDL_FREE_CLIENT, pp_ddl);
+	return VCD_S_SUCCESS;
+}
+
+u32 ddl_encode_start(u32 *ddl_handle, void *client_data)
+{
+	struct ddl_client_context *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	struct ddl_context *ddl_context;
+	struct ddl_encoder_data *encoder;
+	void *ptr;
+	u32 status = VCD_S_SUCCESS;
+	DDL_MSG_HIGH("ddl_encode_start");
+	if (first_time < 2) {
+		ddl_reset_core_time_variables(ENC_OP_TIME);
+		first_time++;
+	 }
+	ddl_set_core_start_time(__func__, ENC_OP_TIME);
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_start:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_start:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || ddl->decoding) {
+		DDL_MSG_ERROR("ddl_enc_start:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+		DDL_MSG_ERROR("ddl_enc_start:Not_opened");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl_encoder_ready_to_start(ddl)) {
+		DDL_MSG_ERROR("ddl_enc_start:Err_param_settings");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	encoder = &ddl->codec_data.encoder;
+	status = ddl_allocate_enc_hw_buffers(ddl);
+	if (status)
+		return status;
+#ifdef DDL_BUF_LOG
+	ddl_list_buffers(ddl);
+#endif
+	encoder->seq_header.mem_type = DDL_MM_MEM;
+	ptr = ddl_pmem_alloc(&encoder->seq_header,
+		DDL_ENC_SEQHEADER_SIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES);
+	if (!ptr) {
+		ddl_free_enc_hw_buffers(ddl);
+		DDL_MSG_ERROR("ddl_enc_start:Seq_hdr_alloc_failed");
+		return VCD_ERR_ALLOC_FAIL;
+	}
+	msm_ion_do_cache_op(ddl_context->video_ion_client,
+				encoder->seq_header.alloc_handle,
+				encoder->seq_header.virtual_base_addr,
+				encoder->seq_header.buffer_size,
+				ION_IOC_CLEAN_INV_CACHES);
+	if (encoder->slice_delivery_info.enable) {
+		DDL_MSG_LOW("%s: slice mode allocate memory for struct\n",
+					__func__);
+		ptr = ddl_pmem_alloc(&encoder->batch_frame.slice_batch_in,
+				DDL_ENC_SLICE_BATCH_INPSTRUCT_SIZE,
+				DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		if (ptr) {
+			ptr = ddl_pmem_alloc(
+				&encoder->batch_frame.slice_batch_out,
+				DDL_ENC_SLICE_BATCH_OUTSTRUCT_SIZE,
+				DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		}
+		if (!ptr) {
+			ddl_pmem_free(&encoder->batch_frame.slice_batch_in);
+			ddl_pmem_free(&encoder->batch_frame.slice_batch_out);
+			ddl_free_enc_hw_buffers(ddl);
+			ddl_pmem_free(&encoder->seq_header);
+			DDL_MSG_ERROR("ddlEncStart:SeqHdrAllocFailed");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+	}
+	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+		return VCD_ERR_BUSY;
+	ddl_vidc_channel_set(ddl);
+	return status;
+}
+
+u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header,
+	void *client_data)
+{
+	struct ddl_client_context  *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	struct ddl_context *ddl_context;
+	struct ddl_decoder_data *decoder;
+	u32 status = VCD_S_SUCCESS;
+
+	DDL_MSG_HIGH("ddl_decode_start");
+	ddl_reset_core_time_variables(DEC_OP_TIME);
+	ddl_reset_core_time_variables(DEC_IP_TIME);
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dec_start:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dec_start:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || !ddl->decoding) {
+		DDL_MSG_ERROR("ddl_dec_start:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+		DDL_MSG_ERROR("ddl_dec_start:Not_in_opened_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if ((header) && ((!header->sequence_header_len) ||
+		(!header->sequence_header))) {
+		DDL_MSG_ERROR("ddl_dec_start:Bad_param_seq_header");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if (!ddl_decoder_ready_to_start(ddl, header)) {
+		DDL_MSG_ERROR("ddl_dec_start:Err_param_settings");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	decoder = &ddl->codec_data.decoder;
+	status = ddl_allocate_dec_hw_buffers(ddl);
+	if (status)
+		return status;
+#ifdef DDL_BUF_LOG
+	ddl_list_buffers(ddl);
+#endif
+	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+		return VCD_ERR_BUSY;
+	if (header) {
+		decoder->header_in_start = true;
+		decoder->decode_config = *header;
+	} else {
+		decoder->header_in_start = false;
+		decoder->decode_config.sequence_header_len = 0;
+	}
+	ddl_vidc_channel_set(ddl);
+	return status;
+}
+
+u32 ddl_decode_frame(u32 *ddl_handle,
+	struct ddl_frame_data_tag *input_bits, void *client_data)
+{
+	u32 vcd_status = VCD_S_SUCCESS;
+	struct ddl_client_context *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	struct ddl_context *ddl_context;
+	struct ddl_decoder_data *decoder;
+	DDL_MSG_HIGH("ddl_decode_frame");
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dec_frame:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dec_frame:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || !ddl->decoding) {
+		DDL_MSG_ERROR("ddl_dec_frame:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	if (!input_bits || ((!input_bits->vcd_frm.physical ||
+		!input_bits->vcd_frm.data_len) &&
+		(!(VCD_FRAME_FLAG_EOS &	input_bits->vcd_frm.flags)))) {
+		DDL_MSG_ERROR("ddl_dec_frame:Bad_input_param");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) &&
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) &&
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) {
+		DDL_MSG_ERROR("Dec_frame:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	decoder = &(ddl->codec_data.decoder);
+	if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC)	&&
+		!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) {
+		DDL_MSG_ERROR("ddl_dec_frame:Dpbs_requied");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+		return VCD_ERR_BUSY;
+
+	ddl->input_frame = *input_bits;
+	if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME))
+		ddl_vidc_decode_frame_run(ddl);
+	else {
+		if (!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) {
+			DDL_MSG_ERROR("ddl_dec_frame:Dpbs_requied");
+			vcd_status = VCD_ERR_ILLEGAL_OP;
+		} else if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) {
+			vcd_status = ddl_vidc_decode_set_buffers(ddl);
+		if (vcd_status)
+			ddl_release_command_channel(ddl_context,
+				ddl->command_channel);
+		} else if (DDLCLIENT_STATE_IS(ddl,
+			DDL_CLIENT_WAIT_FOR_INITCODEC)) {
+			if (decoder->codec.codec == VCD_CODEC_DIVX_3) {
+				if ((!decoder->client_frame_size.width) ||
+				(!decoder->client_frame_size.height))
+					return VCD_ERR_ILLEGAL_OP;
+		}
+		ddl->codec_data.decoder.decode_config.sequence_header =
+			ddl->input_frame.vcd_frm.physical;
+		ddl->codec_data.decoder.decode_config.sequence_header_len =
+			ddl->input_frame.vcd_frm.data_len;
+		ddl_vidc_decode_init_codec(ddl);
+		} else {
+			DDL_MSG_ERROR("Dec_frame:Wrong_state");
+			vcd_status = VCD_ERR_ILLEGAL_OP;
+		}
+		if (vcd_status)
+			DDL_IDLE(ddl_context);
+		}
+	return vcd_status;
+}
+
+u32 ddl_encode_frame(u32 *ddl_handle,
+	struct ddl_frame_data_tag *input_frame,
+	struct ddl_frame_data_tag *output_bit, void *client_data)
+{
+	struct ddl_client_context *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	struct ddl_context *ddl_context;
+	struct ddl_encoder_data *encoder =
+		&ddl->codec_data.encoder;
+	u32 vcd_status = VCD_S_SUCCESS;
+
+	struct vcd_transc *transc;
+	transc = (struct vcd_transc *)(ddl->client_data);
+	DDL_MSG_LOW("%s: transc = 0x%x, in_use = %u",
+				 __func__, (u32)ddl->client_data, transc->in_use);
+
+	if (encoder->slice_delivery_info.enable) {
+		return ddl_encode_frame_batch(ddl_handle,
+					input_frame,
+					output_bit,
+					1,
+					encoder->slice_delivery_info.num_slices,
+					client_data);
+	}
+
+	ddl_set_core_start_time(__func__, ENC_OP_TIME);
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || ddl->decoding) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_handle");
+	return VCD_ERR_BAD_HANDLE;
+	}
+	if (!input_frame || !input_frame->vcd_frm.physical	||
+		!input_frame->vcd_frm.data_len) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_input_params");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if ((((u32) input_frame->vcd_frm.physical +
+		input_frame->vcd_frm.offset) &
+		(DDL_STREAMBUF_ALIGN_GUARD_BYTES))) {
+		DDL_MSG_ERROR("ddl_enc_frame:Un_aligned_yuv_start_address");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if (!output_bit || !output_bit->vcd_frm.physical ||
+		!output_bit->vcd_frm.alloc_len) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_output_params");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if ((ddl->codec_data.encoder.output_buf_req.sz +
+		output_bit->vcd_frm.offset) >
+		output_bit->vcd_frm.alloc_len)
+		DDL_MSG_ERROR("ddl_enc_frame:offset_large,"
+			"Exceeds_min_buf_size");
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+		return VCD_ERR_BUSY;
+
+	ddl->input_frame = *input_frame;
+	ddl->output_frame = *output_bit;
+	if (ddl->codec_data.encoder.i_period.b_frames > 0) {
+		if (!ddl->b_count) {
+			ddl->first_output_frame = *output_bit;
+			ddl->b_count++;
+		} else if (ddl->codec_data.encoder.i_period.b_frames >=
+			ddl->b_count) {
+			ddl->extra_output_frame[ddl->b_count-1] =
+				*output_bit;
+			ddl->output_frame = ddl->first_output_frame;
+			ddl->b_count++;
+		}
+	}
+	ddl_insert_input_frame_to_pool(ddl, input_frame);
+	if (!vcd_status)
+		ddl_vidc_encode_frame_run(ddl);
+	else
+		DDL_MSG_ERROR("insert to frame pool failed %u", vcd_status);
+	return vcd_status;
+}
+
+u32 ddl_encode_frame_batch(u32 *ddl_handle,
+	struct ddl_frame_data_tag *input_frame,
+	struct ddl_frame_data_tag *output_bit,
+	u32 num_in_frames, u32 num_out_frames,
+	void *client_data)
+{
+	struct ddl_client_context *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	struct ddl_context *ddl_context;
+	u32 vcd_status = VCD_S_SUCCESS;
+	struct ddl_encoder_data *encoder;
+
+	DDL_MSG_LOW("ddl_encode_frame_batch");
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || ddl->decoding) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_handle");
+	return VCD_ERR_BAD_HANDLE;
+	}
+	if (!input_frame || !input_frame->vcd_frm.physical	||
+		!input_frame->vcd_frm.data_len) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_input_params");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if ((((u32) input_frame->vcd_frm.physical +
+		input_frame->vcd_frm.offset) &
+		(DDL_STREAMBUF_ALIGN_GUARD_BYTES))) {
+		DDL_MSG_ERROR("ddl_enc_frame:Un_aligned_yuv_start_address");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if (!output_bit || !output_bit->vcd_frm.physical ||
+		!output_bit->vcd_frm.alloc_len) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_output_params");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if ((ddl->codec_data.encoder.output_buf_req.sz +
+		output_bit->vcd_frm.offset) >
+		output_bit->vcd_frm.alloc_len)
+		DDL_MSG_ERROR("ddl_enc_frame:offset_large,"
+			"Exceeds_min_buf_size");
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+		return VCD_ERR_BUSY;
+	encoder = &ddl->codec_data.encoder;
+	if (encoder->slice_delivery_info.enable) {
+		DDL_MEMCPY((void *)&(encoder->batch_frame.output_frame[0]),
+			(void *)output_bit,
+			sizeof(struct ddl_frame_data_tag) * num_out_frames);
+		encoder->batch_frame.num_output_frames = num_out_frames;
+		ddl->input_frame = *input_frame;
+		vcd_status = ddl_insert_input_frame_to_pool(ddl, input_frame);
+		if (!vcd_status)
+			ddl_vidc_encode_slice_batch_run(ddl);
+		else
+			DDL_MSG_ERROR("insert to frame pool failed %u",
+					vcd_status);
+	}
+	return vcd_status;
+}
+
+u32 ddl_decode_end(u32 *ddl_handle, void *client_data)
+{
+	struct ddl_client_context *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	struct ddl_context *ddl_context;
+
+	DDL_MSG_HIGH("ddl_decode_end");
+	ddl_reset_core_time_variables(DEC_OP_TIME);
+	ddl_reset_core_time_variables(DEC_IP_TIME);
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dec_end:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		DDL_MSG_ERROR("ddl_dec_end:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || !ddl->decoding) {
+		DDL_MSG_ERROR("ddl_dec_end:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) &&
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) &&
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) &&
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FAVIDC_ERROR)) {
+		DDL_MSG_ERROR("ddl_dec_end:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+		return VCD_ERR_BUSY;
+	ddl_vidc_channel_end(ddl);
+	return VCD_S_SUCCESS;
+}
+
+u32 ddl_encode_end(u32 *ddl_handle, void *client_data)
+{
+	struct ddl_client_context  *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	struct ddl_context *ddl_context;
+
+	DDL_MSG_HIGH("ddl_encode_end");
+	ddl_reset_core_time_variables(ENC_OP_TIME);
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_end:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_end:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || ddl->decoding) {
+		DDL_MSG_ERROR("ddl_enc_end:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) &&
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) &&
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FAVIDC_ERROR)) {
+		DDL_MSG_ERROR("ddl_enc_end:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+		return VCD_ERR_BUSY;
+	ddl_vidc_channel_end(ddl);
+	return VCD_S_SUCCESS;
+}
+
+u32 ddl_reset_hw(u32 mode)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_client_context *ddl;
+	u32 i;
+
+	DDL_MSG_HIGH("ddl_reset_hw");
+	DDL_MSG_LOW("ddl_reset_hw:called");
+	ddl_context = ddl_get_context();
+	ddl_context->cmd_state = DDL_CMD_INVALID;
+	DDL_BUSY(ddl_context);
+	if (ddl_context->core_virtual_base_addr) {
+		vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE);
+		msleep(DDL_SW_RESET_SLEEP);
+		vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE);
+		msleep(DDL_SW_RESET_SLEEP);
+		ddl_context->core_virtual_base_addr = NULL;
+	}
+	ddl_context->device_state = DDL_DEVICE_NOTINIT;
+	for (i = 0; i < VCD_MAX_NO_CLIENT; i++) {
+		ddl = ddl_context->ddl_clients[i];
+		ddl_context->ddl_clients[i] = NULL;
+		if (ddl) {
+			ddl_release_client_internal_buffers(ddl);
+			ddl_client_transact(DDL_FREE_CLIENT, &ddl);
+		}
+	}
+	ddl_release_context_buffers(ddl_context);
+	memset(ddl_context, 0, sizeof(struct ddl_context));
+	return true;
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
new file mode 100644
index 0000000..c1c2875
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -0,0 +1,484 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VCD_DDL_H_
+#define _VCD_DDL_H_
+
+#include <mach/msm_subsystem_map.h>
+#include "vcd_ddl_api.h"
+#include "vcd_ddl_core.h"
+#include "vcd_ddl_utils.h"
+#include "vidc.h"
+#include "vidc_hwio.h"
+#include "vidc_pix_cache.h"
+#include "vidc.h"
+
+#define DDL_IDLE_STATE  0
+#define DDL_BUSY_STATE  1
+#define DDL_ERROR_STATE 2
+#define DDL_RUN_STATE   3
+
+#define DDL_IS_BUSY(ddl_context) \
+		((ddl_context)->ddl_busy == DDL_BUSY_STATE)
+#define DDL_IS_IDLE(ddl_context) \
+		((ddl_context)->ddl_busy == DDL_IDLE_STATE)
+#define DDL_BUSY(ddl_context) \
+		((ddl_context)->ddl_busy = DDL_BUSY_STATE)
+#define DDL_IDLE(ddl_context) \
+		((ddl_context)->ddl_busy = DDL_IDLE_STATE)
+#define DDL_ERROR(ddl_context) \
+		((ddl_context)->ddl_busy = DDL_ERROR_STATE)
+#define DDL_RUN(ddl_context) \
+	((ddl_context)->ddl_busy = DDL_RUN_STATE)
+
+#define DDL_DEVICE_NOTINIT  0
+#define DDL_DEVICE_INITED   1
+#define DDL_DEVICE_HWFATAL  2
+
+#define DDL_IS_INITIALIZED(ddl_context) \
+	(ddl_context->device_state == DDL_DEVICE_INITED)
+#define DDLCOMMAND_STATE_IS(ddl_context, command_state) \
+	(command_state == (ddl_context)->cmd_state)
+#define DDLCLIENT_STATE_IS(ddl, state) \
+	(state == (ddl)->client_state)
+
+#define DDL_DPB_OP_INIT       1
+#define DDL_DPB_OP_MARK_FREE  2
+#define DDL_DPB_OP_MARK_BUSY  3
+#define DDL_DPB_OP_SET_MASK   4
+#define DDL_DPB_OP_RETRIEVE   5
+
+#define DDL_INIT_CLIENTS     0
+#define DDL_GET_CLIENT       1
+#define DDL_FREE_CLIENT      2
+#define DDL_ACTIVE_CLIENT    3
+
+#define DDL_INVALID_CHANNEL_ID  ((u32)~0)
+#define DDL_INVALID_CODEC_TYPE  ((u32)~0)
+#define DDL_INVALID_INTR_STATUS ((u32)~0)
+
+#define DDL_ENC_REQ_IFRAME        0x01
+#define DDL_ENC_CHANGE_IPERIOD    0x02
+#define DDL_ENC_CHANGE_BITRATE    0x04
+#define DDL_ENC_CHANGE_FRAMERATE  0x08
+#define DDL_ENC_CHANGE_CIR        0x10
+
+#define DDL_DEC_REQ_OUTPUT_FLUSH  0x1
+
+#define DDL_MIN_NUM_OF_B_FRAME  0
+#define DDL_MAX_NUM_OF_B_FRAME  1
+#define DDL_DEFAULT_NUM_OF_B_FRAME  DDL_MIN_NUM_OF_B_FRAME
+
+#define DDL_MIN_NUM_REF_FOR_P_FRAME             1
+#define DDL_MAX_NUM_REF_FOR_P_FRAME             2
+
+#define DDL_MAX_NUM_IN_INPUTFRAME_POOL          (DDL_MAX_NUM_OF_B_FRAME + 1)
+
+enum ddl_mem_area {
+	DDL_FW_MEM	= 0x0,
+	DDL_MM_MEM	= 0x1,
+	DDL_CMD_MEM	= 0x2
+};
+
+struct ddl_buf_addr{
+	u8  *virtual_base_addr;
+	u8  *physical_base_addr;
+	u8  *align_physical_addr;
+	u8  *align_virtual_addr;
+	phys_addr_t alloced_phys_addr;
+	struct msm_mapped_buffer *mapped_buffer;
+	struct ion_handle *alloc_handle;
+	u32 buffer_size;
+	enum ddl_mem_area mem_type;
+	void *pil_cookie;
+};
+enum ddl_cmd_state{
+	DDL_CMD_INVALID         = 0x0,
+	DDL_CMD_DMA_INIT        = 0x1,
+	DDL_CMD_CPU_RESET       = 0x2,
+	DDL_CMD_CHANNEL_SET     = 0x3,
+	DDL_CMD_INIT_CODEC      = 0x4,
+	DDL_CMD_HEADER_PARSE    = 0x5,
+	DDL_CMD_DECODE_SET_DPB  = 0x6,
+	DDL_CMD_DECODE_FRAME    = 0x7,
+	DDL_CMD_ENCODE_FRAME    = 0x8,
+	DDL_CMD_EOS             = 0x9,
+	DDL_CMD_CHANNEL_END     = 0xA,
+	DDL_CMD_ENCODE_CONTINUE = 0xB,
+	DDL_CMD_32BIT           = 0x7FFFFFFF
+};
+enum ddl_client_state{
+	DDL_CLIENT_INVALID                 = 0x0,
+	DDL_CLIENT_OPEN                    = 0x1,
+	DDL_CLIENT_WAIT_FOR_CHDONE         = 0x2,
+	DDL_CLIENT_WAIT_FOR_INITCODEC      = 0x3,
+	DDL_CLIENT_WAIT_FOR_INITCODECDONE  = 0x4,
+	DDL_CLIENT_WAIT_FOR_DPB            = 0x5,
+	DDL_CLIENT_WAIT_FOR_DPBDONE        = 0x6,
+	DDL_CLIENT_WAIT_FOR_FRAME          = 0x7,
+	DDL_CLIENT_WAIT_FOR_FRAME_DONE     = 0x8,
+	DDL_CLIENT_WAIT_FOR_EOS_DONE       = 0x9,
+	DDL_CLIENT_WAIT_FOR_CHEND          = 0xA,
+	DDL_CLIENT_FATAL_ERROR             = 0xB,
+	DDL_CLIENT_FAVIDC_ERROR            = 0xC,
+	DDL_CLIENT_WAIT_FOR_CONTINUE       = 0xD,
+	DDL_CLIENT_32BIT                   = 0x7FFFFFFF
+};
+struct ddl_hw_interface{
+	u32 cmd;
+	u32 arg1;
+	u32 arg2;
+	u32 arg3;
+	u32 arg4;
+};
+struct ddl_mask{
+	u32  client_mask;
+	u32  hw_mask;
+};
+struct ddl_yuv_buffer_size{
+	u32  size_yuv;
+	u32  size_y;
+	u32  size_c;
+};
+struct ddl_dec_buffer_size{
+	u32  sz_dpb0;
+	u32  sz_dpb1;
+	u32  sz_mv;
+	u32  sz_vert_nb_mv;
+	u32  sz_nb_ip;
+	u32  sz_luma;
+	u32  sz_chroma;
+	u32  sz_nb_dcac;
+	u32  sz_upnb_mv;
+	u32  sz_sub_anchor_mv;
+	u32  sz_overlap_xform;
+	u32  sz_bit_plane3;
+	u32  sz_bit_plane2;
+	u32  sz_bit_plane1;
+	u32  sz_stx_parser;
+	u32  sz_desc;
+	u32  sz_cpb;
+	u32  sz_context;
+};
+struct ddl_dec_buffers{
+	struct ddl_buf_addr desc;
+	struct ddl_buf_addr nb_dcac;
+	struct ddl_buf_addr upnb_mv;
+	struct ddl_buf_addr sub_anchor_mv;
+	struct ddl_buf_addr overlay_xform;
+	struct ddl_buf_addr bit_plane3;
+	struct ddl_buf_addr bit_plane2;
+	struct ddl_buf_addr bit_plane1;
+	struct ddl_buf_addr stx_parser;
+	struct ddl_buf_addr h264_mv[DDL_MAX_BUFFER_COUNT];
+	struct ddl_buf_addr h264_vert_nb_mv;
+	struct ddl_buf_addr h264_nb_ip;
+	struct ddl_buf_addr context;
+};
+struct ddl_enc_buffer_size{
+	u32  sz_cur_y;
+	u32  sz_cur_c;
+	u32  sz_dpb_y;
+	u32  sz_dpb_c;
+	u32  sz_strm;
+	u32  sz_mv;
+	u32  sz_col_zero;
+	u32  sz_md;
+	u32  sz_pred;
+	u32  sz_nbor_info;
+	u32  sz_acdc_coef;
+	u32  sz_mb_info;
+	u32  sz_context;
+};
+struct ddl_enc_buffers{
+	struct ddl_buf_addr dpb_y[4];
+	struct ddl_buf_addr dpb_c[4];
+	struct ddl_buf_addr mv;
+	struct ddl_buf_addr col_zero;
+	struct ddl_buf_addr md;
+	struct ddl_buf_addr pred;
+	struct ddl_buf_addr nbor_info;
+	struct ddl_buf_addr acdc_coef;
+	struct ddl_buf_addr mb_info;
+	struct ddl_buf_addr context;
+	u32  dpb_count;
+	u32  sz_dpb_y;
+	u32  sz_dpb_c;
+};
+struct ddl_codec_data_hdr{
+	u32  decoding;
+};
+struct ddl_batch_frame_data {
+	struct ddl_buf_addr slice_batch_in;
+	struct ddl_buf_addr slice_batch_out;
+	struct ddl_frame_data_tag input_frame;
+	struct ddl_frame_data_tag output_frame
+			[DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH];
+	u32 num_output_frames;
+	u32 out_frm_next_frmindex;
+};
+struct ddl_encoder_data{
+	struct ddl_codec_data_hdr   hdr;
+	struct vcd_property_codec   codec;
+	struct vcd_property_frame_size  frame_size;
+	struct vcd_property_frame_rate  frame_rate;
+	struct vcd_property_target_bitrate  target_bit_rate;
+	struct vcd_property_profile  profile;
+	struct vcd_property_level  level;
+	struct vcd_property_rate_control  rc;
+	struct vcd_property_multi_slice  multi_slice;
+	struct ddl_buf_addr  meta_data_input;
+	struct vcd_property_short_header  short_header;
+	struct vcd_property_vop_timing  vop_timing;
+	struct vcd_property_db_config  db_control;
+	struct vcd_property_entropy_control  entropy_control;
+	struct vcd_property_i_period  i_period;
+	struct vcd_property_session_qp  session_qp;
+	struct vcd_property_qp_range  qp_range;
+	struct vcd_property_rc_level  rc_level;
+	struct vcd_property_frame_level_rc_params  frame_level_rc;
+	struct vcd_property_adaptive_rc_params  adaptive_rc;
+	struct vcd_property_intra_refresh_mb_number  intra_refresh;
+	struct vcd_property_buffer_format  buf_format;
+	struct vcd_property_buffer_format  recon_buf_format;
+	struct vcd_property_sps_pps_for_idr_enable sps_pps;
+	struct ddl_buf_addr  seq_header;
+	struct vcd_buffer_requirement  input_buf_req;
+	struct vcd_buffer_requirement  output_buf_req;
+	struct vcd_buffer_requirement  client_input_buf_req;
+	struct vcd_buffer_requirement  client_output_buf_req;
+	struct ddl_enc_buffers  hw_bufs;
+	struct ddl_yuv_buffer_size  input_buf_size;
+	struct vidc_1080p_enc_frame_info enc_frame_info;
+	u32  meta_data_enable_flag;
+	u32  suffix;
+	u32  meta_data_offset;
+	u32  hdr_ext_control;
+	u32  r_cframe_skip;
+	u32  vb_vbuffer_size;
+	u32  dynamic_prop_change;
+	u32  dynmic_prop_change_req;
+	u32  seq_header_length;
+	u32  intra_frame_insertion;
+	u32  mb_info_enable;
+	u32  ext_enc_control_val;
+	u32  num_references_for_p_frame;
+	u32  closed_gop;
+	struct vcd_property_slice_delivery_info slice_delivery_info;
+	struct ddl_batch_frame_data batch_frame;
+};
+struct ddl_decoder_data {
+	struct ddl_codec_data_hdr  hdr;
+	struct vcd_property_codec  codec;
+	struct vcd_property_buffer_format  buf_format;
+	struct vcd_property_frame_size  frame_size;
+	struct vcd_property_frame_size  client_frame_size;
+	struct vcd_property_profile  profile;
+	struct vcd_property_level  level;
+	struct ddl_buf_addr  meta_data_input;
+	struct vcd_property_post_filter  post_filter;
+	struct vcd_sequence_hdr  decode_config;
+	struct ddl_property_dec_pic_buffers  dp_buf;
+	struct ddl_mask  dpb_mask;
+	struct vcd_buffer_requirement  actual_input_buf_req;
+	struct vcd_buffer_requirement  min_input_buf_req;
+	struct vcd_buffer_requirement  client_input_buf_req;
+	struct vcd_buffer_requirement  actual_output_buf_req;
+	struct vcd_buffer_requirement  min_output_buf_req;
+	struct vcd_buffer_requirement  client_output_buf_req;
+	struct ddl_dec_buffers  hw_bufs;
+	struct ddl_yuv_buffer_size  dpb_buf_size;
+	struct vidc_1080p_dec_disp_info dec_disp_info;
+	u32  progressive_only;
+	u32  output_order;
+	u32  meta_data_enable_flag;
+	u32  suffix;
+	u32  meta_data_offset;
+	u32  header_in_start;
+	u32  min_dpb_num;
+	u32  y_cb_cr_size;
+	u32  dynamic_prop_change;
+	u32  dynmic_prop_change_req;
+	u32  flush_pending;
+	u32  meta_data_exists;
+	u32  idr_only_decoding;
+	u32  field_needed_for_prev_ip;
+	u32  prev_ip_frm_tag;
+	u32  cont_mode;
+	u32  reconfig_detected;
+	u32  dmx_disable;
+};
+union ddl_codec_data{
+	struct ddl_codec_data_hdr  hdr;
+	struct ddl_decoder_data   decoder;
+	struct ddl_encoder_data   encoder;
+};
+struct ddl_context{
+	u8 *core_virtual_base_addr;
+	void *client_data;
+	u32 device_state;
+	u32 ddl_busy;
+	u32 cmd_err_status;
+	u32 disp_pic_err_status;
+	u32 pix_cache_enable;
+	u32 fw_version;
+	u32 fw_memory_size;
+	u32 cmd_seq_num;
+	u32 response_cmd_ch_id;
+	enum ddl_cmd_state cmd_state;
+	struct ddl_client_context *current_ddl[2];
+	struct ddl_buf_addr metadata_shared_input;
+	struct ddl_client_context *ddl_clients[VCD_MAX_NO_CLIENT];
+	struct ddl_buf_addr dram_base_a;
+	struct ddl_buf_addr dram_base_b;
+	struct ddl_hw_interface ddl_hw_response;
+	struct ion_client *video_ion_client;
+	void (*ddl_callback) (u32 event, u32 status, void *payload,
+		size_t sz, u32 *ddl_handle, void *const client_data);
+	void (*interrupt_clr) (void);
+	void (*vidc_decode_seq_start[2])
+		(struct vidc_1080p_dec_seq_start_param *param);
+	void (*vidc_set_dec_resolution[2])
+		(u32 width, u32 height);
+	void(*vidc_decode_init_buffers[2])
+		(struct vidc_1080p_dec_init_buffers_param *param);
+	void(*vidc_decode_frame_start[2])
+		(struct vidc_1080p_dec_frame_start_param *param);
+	void(*vidc_encode_seq_start[2])
+		(struct vidc_1080p_enc_seq_start_param *param);
+	void(*vidc_encode_frame_start[2])
+		(struct vidc_1080p_enc_frame_start_param *param);
+	void(*vidc_encode_slice_batch_start[2])
+		(struct vidc_1080p_enc_frame_start_param *param);
+	u32 frame_channel_depth;
+};
+struct ddl_client_context{
+	struct ddl_context  *ddl_context;
+	enum ddl_client_state  client_state;
+	struct ddl_frame_data_tag  first_output_frame;
+	struct ddl_frame_data_tag
+		extra_output_frame[DDL_MAX_NUM_OF_B_FRAME];
+	struct ddl_frame_data_tag  input_frame;
+	struct ddl_frame_data_tag  output_frame;
+	struct ddl_frame_data_tag
+		input_frame_pool[DDL_MAX_NUM_IN_INPUTFRAME_POOL];
+	union ddl_codec_data  codec_data;
+	enum ddl_cmd_state  cmd_state;
+	struct ddl_buf_addr  shared_mem[2];
+	void *client_data;
+	u32  decoding;
+	u32  channel_id;
+	u32  command_channel;
+	u32  b_count;
+	s32  extra_output_buf_count;
+	u32  instance_id;
+};
+
+struct ddl_context *ddl_get_context(void);
+void ddl_vidc_core_init(struct ddl_context *);
+void ddl_vidc_core_term(struct ddl_context *);
+void ddl_vidc_channel_set(struct ddl_client_context *);
+void ddl_vidc_channel_end(struct ddl_client_context *);
+void ddl_vidc_encode_init_codec(struct ddl_client_context *);
+void ddl_vidc_decode_init_codec(struct ddl_client_context *);
+void ddl_vidc_encode_frame_continue(struct ddl_client_context *);
+void ddl_vidc_encode_frame_run(struct ddl_client_context *);
+void ddl_vidc_encode_slice_batch_run(struct ddl_client_context *);
+void ddl_vidc_decode_frame_run(struct ddl_client_context *);
+void ddl_vidc_decode_eos_run(struct ddl_client_context *ddl);
+void ddl_vidc_encode_eos_run(struct ddl_client_context *ddl);
+void ddl_release_context_buffers(struct ddl_context *);
+void ddl_release_client_internal_buffers(struct ddl_client_context *ddl);
+u32  ddl_vidc_decode_set_buffers(struct ddl_client_context *);
+u32  ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder,
+	struct ddl_frame_data_tag *in_out_frame, u32 operation);
+u32  ddl_decoder_dpb_init(struct ddl_client_context *ddl);
+u32  ddl_client_transact(u32 , struct ddl_client_context **);
+u32  ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder,
+	u32 estimate);
+void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data
+	*encoder);
+void ddl_set_default_dec_property(struct ddl_client_context *);
+u32  ddl_encoder_ready_to_start(struct ddl_client_context *);
+u32  ddl_decoder_ready_to_start(struct ddl_client_context *,
+	struct vcd_sequence_hdr *);
+u32  ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size,
+	struct vcd_property_buffer_format *buf_format, u32 interlace,
+	u32 decoding, u32 *pn_c_offset);
+void ddl_calculate_stride(struct vcd_property_frame_size *frame_size,
+	u32 interlace);
+u32  ddl_codec_type_transact(struct ddl_client_context *ddl,
+	u32 remove, enum vcd_codec requested_codec);
+void ddl_vidc_encode_dynamic_property(struct ddl_client_context *ddl,
+	u32 enable);
+void ddl_vidc_decode_dynamic_property(struct ddl_client_context *ddl,
+	u32 enable);
+void ddl_set_initial_default_values(struct ddl_client_context *ddl);
+
+u32  ddl_take_command_channel(struct ddl_context *ddl_context,
+	struct ddl_client_context *ddl, void *client_data);
+void ddl_release_command_channel(struct ddl_context  *ddl_context,
+	u32 command_channel);
+struct ddl_client_context *ddl_get_current_ddl_client_for_channel_id(
+	struct ddl_context *ddl_context, u32 channel_id);
+struct ddl_client_context *ddl_get_current_ddl_client_for_command(
+	struct ddl_context *ddl_context,
+	enum ddl_cmd_state cmd_state);
+
+u32  ddl_get_yuv_buf_size(u32 width, u32 height, u32 format);
+void ddl_free_dec_hw_buffers(struct ddl_client_context *ddl);
+void ddl_free_enc_hw_buffers(struct ddl_client_context *ddl);
+void ddl_calc_dec_hw_buffers_size(enum vcd_codec codec, u32 width,
+	u32 height, u32 h264_dpb,
+	struct ddl_dec_buffer_size *buf_size);
+u32  ddl_allocate_dec_hw_buffers(struct ddl_client_context *ddl);
+u32  ddl_calc_enc_hw_buffers_size(enum vcd_codec codec, u32 width,
+	u32 height, enum vcd_yuv_buffer_format  input_format,
+	struct ddl_client_context *ddl,
+	struct ddl_enc_buffer_size *buf_size);
+u32  ddl_allocate_enc_hw_buffers(struct ddl_client_context *ddl);
+
+u32  ddl_handle_core_errors(struct ddl_context *ddl_context);
+void ddl_client_fatal_cb(struct ddl_client_context *ddl);
+void ddl_hw_fatal_cb(struct ddl_client_context *ddl);
+
+void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment);
+void ddl_pmem_free(struct ddl_buf_addr *addr);
+
+u32 ddl_get_input_frame_from_pool(struct ddl_client_context *ddl,
+	u8 *input_buffer_address);
+u32 ddl_get_stream_buf_from_batch_pool(struct ddl_client_context *ddl,
+	struct ddl_frame_data_tag *stream_buffer);
+u32 ddl_insert_input_frame_to_pool(struct ddl_client_context *ddl,
+	struct ddl_frame_data_tag *ddl_input_frame);
+void ddl_decoder_chroma_dpb_change(struct ddl_client_context *ddl);
+u32  ddl_check_reconfig(struct ddl_client_context *ddl);
+void ddl_handle_reconfig(u32 res_change, struct ddl_client_context *ddl);
+void ddl_fill_dec_desc_buffer(struct ddl_client_context *ddl);
+void ddl_set_vidc_timeout(struct ddl_client_context *ddl);
+
+
+#ifdef DDL_BUF_LOG
+void ddl_list_buffers(struct ddl_client_context *ddl);
+#endif
+#ifdef DDL_MSG_LOG
+s8 *ddl_get_state_string(enum ddl_client_state client_state);
+#endif
+extern unsigned char *vidc_video_codec_fw;
+extern u32 vidc_video_codec_fw_size;
+
+u32 ddl_fw_init(struct ddl_buf_addr *dram_base);
+void ddl_get_fw_info(const unsigned char **fw_array_addr,
+	unsigned int *fw_size);
+void ddl_fw_release(struct ddl_buf_addr *);
+#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
new file mode 100644
index 0000000..5c1ee21
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
@@ -0,0 +1,120 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VCD_DDL_API_H_
+#define _VCD_DDL_API_H_
+
+#include <media/msm/vcd_api.h>
+#include "vidc.h"
+
+#define VCD_EVT_RESP_DDL_BASE             0x3000
+#define VCD_EVT_RESP_DEVICE_INIT          (VCD_EVT_RESP_DDL_BASE + 0x1)
+#define VCD_EVT_RESP_OUTPUT_REQ           (VCD_EVT_RESP_DDL_BASE + 0x2)
+#define VCD_EVT_RESP_EOS_DONE             (VCD_EVT_RESP_DDL_BASE + 0x3)
+#define VCD_EVT_RESP_TRANSACTION_PENDING  (VCD_EVT_RESP_DDL_BASE + 0x4)
+
+#define VCD_S_DDL_ERR_BASE       0x90000000
+#define VCD_ERR_MAX_NO_CODEC     (VCD_S_DDL_ERR_BASE + 0x1)
+#define VCD_ERR_CLIENT_PRESENT   (VCD_S_DDL_ERR_BASE + 0x2)
+#define VCD_ERR_CLIENT_FATAL     (VCD_S_DDL_ERR_BASE + 0x3)
+#define VCD_ERR_NO_SEQ_HDR       (VCD_S_DDL_ERR_BASE + 0x4)
+
+#define VCD_I_CUSTOM_BASE        (VCD_I_RESERVED_BASE)
+#define VCD_I_RC_LEVEL_CONFIG    (VCD_I_CUSTOM_BASE + 0x1)
+#define VCD_I_FRAME_LEVEL_RC     (VCD_I_CUSTOM_BASE + 0x2)
+#define VCD_I_ADAPTIVE_RC        (VCD_I_CUSTOM_BASE + 0x3)
+#define VCD_I_CUSTOM_DDL_BASE    (VCD_I_RESERVED_BASE + 0x100)
+#define DDL_I_INPUT_BUF_REQ      (VCD_I_CUSTOM_DDL_BASE + 0x1)
+#define DDL_I_OUTPUT_BUF_REQ     (VCD_I_CUSTOM_DDL_BASE + 0x2)
+#define DDL_I_DPB                (VCD_I_CUSTOM_DDL_BASE + 0x3)
+#define DDL_I_DPB_RELEASE        (VCD_I_CUSTOM_DDL_BASE + 0x4)
+#define DDL_I_DPB_RETRIEVE       (VCD_I_CUSTOM_DDL_BASE + 0x5)
+#define DDL_I_REQ_OUTPUT_FLUSH   (VCD_I_CUSTOM_DDL_BASE + 0x6)
+#define DDL_I_SEQHDR_ALIGN_BYTES (VCD_I_CUSTOM_DDL_BASE + 0x7)
+#define DDL_I_CAPABILITY         (VCD_I_CUSTOM_DDL_BASE + 0x8)
+#define DDL_I_FRAME_PROC_UNITS   (VCD_I_CUSTOM_DDL_BASE + 0x9)
+#define DDL_I_SEQHDR_PRESENT     (VCD_I_CUSTOM_DDL_BASE + 0xA)
+
+#define DDL_FRAME_VGA_SIZE     (640*480)
+#define DDL_FRAME_720P_WIDTH   1280
+#define DDL_FRAME_720P_HEIGHT  720
+
+struct vcd_property_rc_level{
+	u32 frame_level_rc;
+	u32 mb_level_rc;
+};
+struct vcd_property_frame_level_rc_params{
+	u32 reaction_coeff;
+};
+struct vcd_property_adaptive_rc_params{
+	u32 disable_dark_region_as_flag;
+	u32 disable_smooth_region_as_flag;
+	u32 disable_static_region_as_flag;
+	u32 disable_activity_region_flag;
+};
+struct vcd_property_slice_delivery_info {
+	u32  enable;
+	u32  num_slices;
+	u32  num_slices_enc;
+};
+struct ddl_property_dec_pic_buffers{
+	struct ddl_frame_data_tag *dec_pic_buffers;
+	u32 no_of_dec_pic_buf;
+};
+struct ddl_property_capability{
+	u32 max_num_client;
+	u32 general_command_depth;
+	u32 exclusive;
+	u32 frame_command_depth;
+	u32 ddl_time_out_in_ms;
+};
+struct ddl_init_config{
+	int memtype;
+	u8 *core_virtual_base_addr;
+	void (*interrupt_clr) (void);
+	void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz,
+		u32 *ddl_handle, void *const client_data);
+};
+struct ddl_frame_data_tag{
+	struct vcd_frame_data vcd_frm;
+	u32 frm_trans_end;
+	u32 frm_delta;
+};
+u32 ddl_device_init(struct ddl_init_config *ddl_init_config,
+	void *client_data);
+u32 ddl_device_release(void *client_data);
+u32 ddl_open(u32 **ddl_handle, u32 decoding);
+u32 ddl_close(u32 **ddl_handle);
+u32 ddl_encode_start(u32 *ddl_handle, void *client_data);
+u32 ddl_encode_frame(u32 *ddl_handle,
+	struct ddl_frame_data_tag *input_frame,
+	struct ddl_frame_data_tag *output_bit, void *client_data);
+u32 ddl_encode_frame_batch(u32 *ddl_handle,
+	struct ddl_frame_data_tag *input_frame,
+	struct ddl_frame_data_tag *output_bit,
+	u32 num_in_frames, u32 num_out_frames,
+	void *client_data);
+u32 ddl_encode_end(u32 *ddl_handle, void *client_data);
+u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header,
+	void *client_data);
+u32 ddl_decode_frame(u32 *ddl_handle,
+	struct ddl_frame_data_tag *input_bits, void *client_data);
+u32 ddl_decode_end(u32 *ddl_handle, void *client_data);
+u32 ddl_set_property(u32 *ddl_handle,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+u32 ddl_get_property(u32 *ddl_handle,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+u32 ddl_process_core_response(void);
+u32 ddl_reset_hw(u32 mode);
+void ddl_read_and_clear_interrupt(void);
+#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
new file mode 100644
index 0000000..ddddaa9
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
@@ -0,0 +1,149 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VCD_DDL_CORE_H_
+#define _VCD_DDL_CORE_H_
+
+#define DDL_LINEAR_BUF_ALIGN_MASK         0xFFFFF800U
+#define DDL_LINEAR_BUF_ALIGN_GUARD_BYTES  0x7FF
+#define DDL_LINEAR_BUFFER_ALIGN_BYTES     2048
+#define DDL_TILE_BUF_ALIGN_MASK           0xFFFFE000U
+#define DDL_TILE_BUF_ALIGN_GUARD_BYTES    0x1FFF
+#define DDL_TILE_BUFFER_ALIGN_BYTES       8192
+
+#define DDL_YUV_BUF_TYPE_LINEAR 0
+#define DDL_YUV_BUF_TYPE_TILE   1
+
+#define DDL_NO_OF_MB(nWidth, nHeight) \
+	((((nWidth) + 15) >> 4) * (((nHeight) + 15) >> 4))
+
+#define DDL_MAX_FRAME_WIDTH   1920
+#define DDL_MAX_FRAME_HEIGHT  1088
+
+#define MAX_DPB_SIZE_L4PT0_MBS    DDL_KILO_BYTE(32)
+#define MAX_FRAME_SIZE_L4PT0_MBS  DDL_KILO_BYTE(8)
+
+#define DDL_MAX_MB_PER_FRAME (DDL_NO_OF_MB(DDL_MAX_FRAME_WIDTH,\
+	DDL_MAX_FRAME_HEIGHT))
+
+#define DDL_DB_LINE_BUF_SIZE\
+	(((((DDL_MAX_FRAME_WIDTH * 4) - 1) / 256) + 1) * 8 * 1024)
+
+#define DDL_MAX_FRAME_RATE               120
+#define DDL_INITIAL_FRAME_RATE            30
+
+#define DDL_MAX_BIT_RATE    (20*1024*1024)
+#define DDL_MAX_MB_PER_SEC  (DDL_MAX_MB_PER_FRAME * DDL_INITIAL_FRAME_RATE)
+
+#define DDL_SW_RESET_SLEEP               1
+#define VCD_MAX_NO_CLIENT                4
+#define VCD_SINGLE_FRAME_COMMAND_CHANNEL 1
+#define VCD_DUAL_FRAME_COMMAND_CHANNEL   2
+#define VCD_FRAME_COMMAND_DEPTH          VCD_SINGLE_FRAME_COMMAND_CHANNEL
+#define VCD_GENEVIDC_COMMAND_DEPTH        1
+#define VCD_COMMAND_EXCLUSIVE            true
+#define DDL_HW_TIMEOUT_IN_MS             1000
+#define DDL_STREAMBUF_ALIGN_GUARD_BYTES  0x7FF
+
+#define DDL_VIDC_1080P_48MHZ			(48000000)
+#define DDL_VIDC_1080P_133MHZ			(133330000)
+#define DDL_VIDC_1080P_200MHZ			(200000000)
+#define DDL_VIDC_1080P_48MHZ_TIMEOUT_VALUE	(0xCB8)
+#define DDL_VIDC_1080P_133MHZ_TIMEOUT_VALUE	(0x2355)
+#define DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE	(0x3500)
+
+#define DDL_CONTEXT_MEMORY (1024 * 15 * (VCD_MAX_NO_CLIENT + 1))
+
+#define DDL_ENC_MIN_DPB_BUFFERS           2
+#define DDL_ENC_MAX_DPB_BUFFERS           4
+
+#define DDL_FW_AUX_HOST_CMD_SPACE_SIZE         (DDL_KILO_BYTE(4))
+#define DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE  (DDL_KILO_BYTE(800))
+#define DDL_FW_H264DEC_CONTEXT_SPACE_SIZE      (DDL_KILO_BYTE(800))
+#define DDL_FW_H264ENC_CONTEXT_SPACE_SIZE      (DDL_KILO_BYTE(20))
+#define DDL_FW_OTHER_CONTEXT_SPACE_SIZE        (DDL_KILO_BYTE(20))
+
+#define VCD_DEC_CPB_SIZE         (DDL_KILO_BYTE(512))
+#define DDL_DBG_CORE_DUMP_SIZE   (DDL_KILO_BYTE(10))
+#define DDL_VIDC_1080P_BASE_OFFSET_SHIFT        11
+
+#define DDL_BUFEND_PAD                    256
+#define DDL_ENC_SEQHEADER_SIZE            (512+DDL_BUFEND_PAD)
+#define DDL_ENC_SLICE_BATCH_FACTOR         5
+#define DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH   8
+#define DDL_ENC_SLICE_BATCH_INPSTRUCT_SIZE (128 + \
+				32 * DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH)
+#define DDL_ENC_SLICE_BATCH_OUTSTRUCT_SIZE (64 + \
+				64 * DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH)
+#define DDL_MAX_BUFFER_COUNT              32
+#define DDL_MIN_BUFFER_COUNT              1
+
+#define DDL_MPEG_REFBUF_COUNT             2
+#define DDL_MPEG_COMV_BUF_NO              2
+#define DDL_H263_COMV_BUF_NO              0
+#define DDL_COMV_BUFLINE_NO               128
+#define DDL_VC1_COMV_BUFLINE_NO           32
+
+#define DDL_MAX_H264_QP            51
+#define DDL_MAX_MPEG4_QP           31
+
+#define DDL_CONCEALMENT_Y_COLOR                 16
+#define DDL_CONCEALMENT_C_COLOR                 128
+
+#define DDL_ALLOW_DEC_FRAMESIZE(width, height) \
+	((DDL_NO_OF_MB(width, height) <= \
+	MAX_FRAME_SIZE_L4PT0_MBS) && \
+	(width <= DDL_MAX_FRAME_WIDTH) && \
+	(height <= DDL_MAX_FRAME_WIDTH) && \
+	((width >= 32 && height >= 16) || \
+	(width >= 16 && height >= 32)))
+
+#define DDL_ALLOW_ENC_FRAMESIZE(width, height) \
+	((DDL_NO_OF_MB(width, height) <= \
+	MAX_FRAME_SIZE_L4PT0_MBS) && \
+	(width <= DDL_MAX_FRAME_WIDTH) && \
+	(height <= DDL_MAX_FRAME_WIDTH) && \
+	((width >= 32 && height >= 32)))
+
+#define DDL_LINEAR_ALIGN_WIDTH      16
+#define DDL_LINEAR_ALIGN_HEIGHT     16
+#define DDL_LINEAR_MULTIPLY_FACTOR  2048
+#define DDL_TILE_ALIGN_WIDTH        128
+#define DDL_TILE_ALIGN_HEIGHT       32
+#define DDL_TILE_MULTIPLY_FACTOR    8192
+#define DDL_TILE_ALIGN(val, grid) \
+	(((val) + (grid) - 1) / (grid) * (grid))
+
+#define VCD_DDL_720P_YUV_BUF_SIZE     ((1280*720*3) >> 1)
+#define VCD_DDL_WVGA_BUF_SIZE         (800*480)
+
+#define VCD_DDL_TEST_MAX_WIDTH        (DDL_MAX_FRAME_WIDTH)
+#define VCD_DDL_TEST_MAX_HEIGHT       (DDL_MAX_FRAME_HEIGHT)
+
+#define VCD_DDL_TEST_MAX_NUM_H264_DPB  8
+
+#define VCD_DDL_TEST_NUM_ENC_INPUT_BUFS   6
+#define VCD_DDL_TEST_NUM_ENC_OUTPUT_BUFS  4
+
+#define VCD_DDL_TEST_DEFAULT_WIDTH       176
+#define VCD_DDL_TEST_DEFAULT_HEIGHT      144
+
+#define DDL_PIXEL_CACHE_NOT_IDLE          0x4000
+#define DDL_PIXEL_CACHE_STATUS_READ_RETRY 10
+#define DDL_PIXEL_CACHE_STATUS_READ_SLEEP 200
+
+#define DDL_RESL_CHANGE_NO_CHANGE               0
+#define DDL_RESL_CHANGE_INCREASED               1
+#define DDL_RESL_CHANGE_DECREASED               2
+
+#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
new file mode 100644
index 0000000..a2327d5
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -0,0 +1,771 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vcd_ddl.h"
+#include "vcd_ddl_shared_mem.h"
+#include "vidc.h"
+
+static u32 ddl_handle_hw_fatal_errors(struct ddl_client_context *ddl);
+static u32 ddl_handle_client_fatal_errors(
+	struct ddl_client_context *ddl);
+static void ddl_input_failed_cb(struct ddl_client_context *ddl,
+	u32 vcd_event, u32 vcd_status);
+static u32 ddl_handle_core_recoverable_errors(
+	struct ddl_client_context *ddl);
+static u32 ddl_handle_core_warnings(u32 error_code);
+static void ddl_release_prev_field(
+	struct ddl_client_context *ddl);
+static u32 ddl_handle_dec_seq_hdr_fail_error(struct ddl_client_context *ddl);
+static void print_core_errors(u32 error_code);
+static void print_core_recoverable_errors(u32 error_code);
+
+void ddl_hw_fatal_cb(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	u32 error_code = ddl_context->cmd_err_status;
+
+	DDL_MSG_FATAL("VIDC_HW_FATAL");
+	ddl->cmd_state = DDL_CMD_INVALID;
+	ddl_context->device_state = DDL_DEVICE_HWFATAL;
+
+	ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL, VCD_ERR_HW_FATAL,
+		&error_code, sizeof(error_code),
+		(u32 *)ddl, ddl->client_data);
+
+	ddl_release_command_channel(ddl_context, ddl->command_channel);
+}
+
+static u32 ddl_handle_hw_fatal_errors(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	u32 status = false, error_code = ddl_context->cmd_err_status;
+
+	switch (error_code) {
+	case VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER:
+	case VIDC_1080P_ERROR_INVALID_COMMAND_ID:
+	case VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE:
+	case VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE:
+	case VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START:
+	case VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED:
+	case VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS:
+	case VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS:
+	case VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED:
+	case VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START:
+	case VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START:
+	case VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START:
+	case VIDC_1080P_ERROR_RESOLUTION_CHANGED:
+	case VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME:
+	case VIDC_1080P_ERROR_INVALID_COMMAND:
+	case VIDC_1080P_ERROR_INVALID_CODEC_TYPE:
+	case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED:
+	case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE:
+	case VIDC_1080P_ERROR_DIVIDE_BY_ZERO:
+	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
+	case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE:
+	case VIDC_1080P_ERROR_VSP_NOT_READY:
+	case VIDC_1080P_ERROR_BUFFER_FULL_STATE:
+		ddl_hw_fatal_cb(ddl);
+		status = true;
+	break;
+	default:
+	break;
+	}
+	return status;
+}
+
+void ddl_client_fatal_cb(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+
+	if (ddl->cmd_state == DDL_CMD_DECODE_FRAME)
+		ddl_vidc_decode_dynamic_property(ddl, false);
+	else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME)
+		ddl_vidc_encode_dynamic_property(ddl, false);
+	ddl->cmd_state = DDL_CMD_INVALID;
+	DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_FAVIDC_ERROR",
+		ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_FAVIDC_ERROR;
+	ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL,
+		VCD_ERR_CLIENT_FATAL, NULL, 0, (u32 *)ddl,
+		ddl->client_data);
+	ddl_release_command_channel(ddl_context, ddl->command_channel);
+}
+
+static u32 ddl_handle_client_fatal_errors(
+	struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	u32 status = false;
+
+	switch (ddl_context->cmd_err_status) {
+	case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE:
+	case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED:
+	case VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_INVALID_QP_VALUE:
+	case VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT:
+	case VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL:
+	case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT:
+	case VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE:
+	case VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER:
+	case VIDC_1080P_ERROR_NULL_DPB_POINTER:
+	case VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR:
+	case VIDC_1080P_ERROR_NULL_MV_POINTER:
+		status = true;
+		DDL_MSG_ERROR("VIDC_CLIENT_FATAL!!");
+	break;
+	default:
+	break;
+	}
+	if (!status)
+		DDL_MSG_ERROR("VIDC_UNKNOWN_OP_FAILED %d",
+				ddl_context->cmd_err_status);
+	ddl_client_fatal_cb(ddl);
+	return true;
+}
+
+static void ddl_input_failed_cb(struct ddl_client_context *ddl,
+	u32 vcd_event, u32 vcd_status)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	u32 payload_size = sizeof(struct ddl_frame_data_tag);
+
+	ddl->cmd_state = DDL_CMD_INVALID;
+	if (ddl->decoding)
+		ddl_vidc_decode_dynamic_property(ddl, false);
+	else
+		ddl_vidc_encode_dynamic_property(ddl, false);
+	if (ddl->client_state == DDL_CLIENT_WAIT_FOR_INITCODECDONE) {
+		payload_size = 0;
+		DDL_MSG_LOW("ddl_state_transition: %s ~~> "
+			"DDL_CLIENT_WAIT_FOR_INITCODEC",
+			ddl_get_state_string(ddl->client_state));
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC;
+	} else {
+		DDL_MSG_LOW("ddl_state_transition: %s ~~> "
+			"DDL_CLIENT_WAIT_FOR_FRAME",
+			ddl_get_state_string(ddl->client_state));
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME;
+	}
+	if (vcd_status == VCD_ERR_IFRAME_EXPECTED)
+		vcd_status = VCD_S_SUCCESS;
+	ddl_context->ddl_callback(vcd_event, vcd_status, &ddl->input_frame,
+		payload_size, (u32 *)ddl, ddl->client_data);
+}
+
+static u32 ddl_handle_core_recoverable_errors(
+	struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	u32 vcd_status = VCD_S_SUCCESS;
+	u32 vcd_event = VCD_EVT_RESP_INPUT_DONE;
+	u32 eos = false, status = false;
+
+	if (ddl->decoding) {
+		if (ddl_handle_dec_seq_hdr_fail_error(ddl))
+			return true;
+	}
+
+	if ((ddl->cmd_state != DDL_CMD_DECODE_FRAME) &&
+		(ddl->cmd_state != DDL_CMD_ENCODE_FRAME))
+		return false;
+
+	if (ddl->decoding &&
+		(ddl->codec_data.decoder.field_needed_for_prev_ip == 1)) {
+		ddl->codec_data.decoder.field_needed_for_prev_ip = 0;
+		ddl_release_prev_field(ddl);
+		if (ddl_context->cmd_err_status ==
+		 VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED) {
+			ddl_vidc_decode_frame_run(ddl);
+			return true;
+		}
+	}
+
+	switch (ddl_context->cmd_err_status) {
+	case VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED:
+		vcd_status = VCD_ERR_IFRAME_EXPECTED;
+		break;
+	case VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST:
+		{
+			u32 pending_display = 0, release_mask;
+
+			release_mask =
+				ddl->codec_data.decoder.\
+				dpb_mask.hw_mask;
+			while (release_mask > 0) {
+				if (release_mask & 0x1)
+					pending_display++;
+				release_mask >>= 1;
+			}
+			if (pending_display >= ddl->codec_data.\
+				decoder.min_dpb_num) {
+				DDL_MSG_ERROR("VIDC_FW_ISSUE_REQ_BUF");
+				ddl_client_fatal_cb(ddl);
+				status = true;
+			} else {
+				vcd_event = VCD_EVT_RESP_OUTPUT_REQ;
+				DDL_MSG_LOW("VIDC_OUTPUT_BUF_REQ!!");
+			}
+			break;
+		}
+	case VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST:
+	case VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID:
+	case VIDC_1080P_ERROR_MB_COEFF_NOT_DONE:
+	case VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE:
+	case VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT:
+	case VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR:
+	case VIDC_1080P_ERROR_RESOLUTION_MISMATCH:
+	case VIDC_1080P_ERROR_NV_QUANT_ERR:
+	case VIDC_1080P_ERROR_SYNC_MARKER_ERR:
+	case VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_MEM_CORRUPTION:
+	case VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME:
+	case VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR:
+	case VIDC_1080P_ERROR_MV_RANGE_ERR:
+	case VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR:
+	case VIDC_1080P_ERROR_SLICE_ADDR_INVALID:
+	case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED:
+	case VIDC_1080P_ERROR_NALU_HEADER_ERROR:
+	case VIDC_1080P_ERROR_SPS_PARSE_ERROR:
+	case VIDC_1080P_ERROR_PPS_PARSE_ERROR:
+	case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
+	case VIDC_1080P_ERROR_SLICE_PARSE_ERROR:
+	case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED:
+		vcd_status = VCD_ERR_BITSTREAM_ERR;
+		DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR");
+		break;
+	case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE:
+	case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED:
+		if (ddl->decoding) {
+			vcd_status = VCD_ERR_BITSTREAM_ERR;
+			DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR");
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (((vcd_status) || (vcd_event != VCD_EVT_RESP_INPUT_DONE)) &&
+		!status) {
+				ddl->input_frame.frm_trans_end = true;
+		eos = ((vcd_event == VCD_EVT_RESP_INPUT_DONE) &&
+			(ddl->input_frame.vcd_frm.flags & VCD_FRAME_FLAG_EOS));
+		if (((ddl->decoding) && (eos)) || !ddl->decoding)
+			ddl->input_frame.frm_trans_end = false;
+		ddl_input_failed_cb(ddl, vcd_event, vcd_status);
+		if (!ddl->decoding) {
+			ddl->output_frame.frm_trans_end = !eos;
+			ddl->output_frame.vcd_frm.data_len = 0;
+			ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+				VCD_ERR_FAIL, &ddl->output_frame,
+				sizeof(struct ddl_frame_data_tag), (u32 *)ddl,
+				ddl->client_data);
+			if (eos) {
+				DDL_MSG_LOW("VIDC_ENC_EOS_DONE");
+				ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE,
+					VCD_S_SUCCESS, NULL, 0, (u32 *)ddl,
+					ddl->client_data);
+			}
+		}
+		if ((ddl->decoding) && (eos))
+			ddl_vidc_decode_eos_run(ddl);
+		else
+			ddl_release_command_channel(ddl_context,
+				ddl->command_channel);
+			status = true;
+	}
+	return status;
+}
+
+static u32 ddl_handle_core_warnings(u32 err_status)
+{
+	u32 status = false;
+
+	switch (err_status) {
+	case VIDC_1080P_WARN_COMMAND_FLUSHED:
+	case VIDC_1080P_WARN_FRAME_RATE_UNKNOWN:
+	case VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN:
+	case VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN:
+	case VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN:
+	case VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN:
+	case VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR:
+	case VIDC_1080P_WARN_BROKEN_LINK:
+	case VIDC_1080P_WARN_FRAME_CONCEALED:
+	case VIDC_1080P_WARN_PROFILE_UNKNOWN:
+	case VIDC_1080P_WARN_LEVEL_UNKNOWN:
+	case VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED:
+	case VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED:
+	case VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER:
+	case VIDC_1080P_WARN_DEBLOCKING_NOT_DONE:
+	case VIDC_1080P_WARN_INCOMPLETE_FRAME:
+	case VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER:
+	case VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_QP:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_SEI:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_VUI:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE:
+	case VIDC_1080P_WARN_RESOLUTION_WARNING:
+	case VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE:
+	case VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP:
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB:
+		status = true;
+		DDL_MSG_ERROR("VIDC_WARNING_IGNORED");
+	break;
+	default:
+	break;
+	}
+	return status;
+}
+
+u32 ddl_handle_core_errors(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+	u32 channel_inst_id, status = false;
+	u32 disp_status;
+
+	if (!ddl_context->cmd_err_status &&
+		!ddl_context->disp_pic_err_status) {
+		DDL_MSG_ERROR("VIDC_NO_ERROR");
+		return false;
+	}
+		vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+		vidc_1080p_clear_returned_channel_inst_id();
+		ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	if (!ddl) {
+		DDL_MSG_ERROR("VIDC_SPURIOUS_INTERRUPT_ERROR");
+		return true;
+	}
+	if (ddl_context->cmd_err_status) {
+		print_core_errors(ddl_context->cmd_err_status);
+		print_core_recoverable_errors(ddl_context->cmd_err_status);
+	}
+	if (ddl_context->disp_pic_err_status)
+		print_core_errors(ddl_context->disp_pic_err_status);
+	status = ddl_handle_core_warnings(ddl_context->cmd_err_status);
+	disp_status = ddl_handle_core_warnings(
+		ddl_context->disp_pic_err_status);
+	if (!status && !disp_status) {
+		DDL_MSG_ERROR("ddl_warning:Unknown");
+		status = ddl_handle_hw_fatal_errors(ddl);
+		if (!status)
+			status = ddl_handle_core_recoverable_errors(ddl);
+		if (!status)
+			status = ddl_handle_client_fatal_errors(ddl);
+	}
+	return status;
+}
+
+static void ddl_release_prev_field(struct ddl_client_context *ddl)
+{
+	ddl->output_frame.vcd_frm.ip_frm_tag =
+		ddl->codec_data.decoder.prev_ip_frm_tag;
+		ddl->output_frame.vcd_frm.physical = NULL;
+		ddl->output_frame.vcd_frm.virtual = NULL;
+		ddl->output_frame.frm_trans_end = false;
+		ddl->ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+			VCD_ERR_INTRLCD_FIELD_DROP, &(ddl->output_frame),
+			sizeof(struct ddl_frame_data_tag),
+			(u32 *) ddl, ddl->client_data);
+}
+
+static u32 ddl_handle_dec_seq_hdr_fail_error(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	u32 status = false;
+
+	if ((ddl->cmd_state != DDL_CMD_HEADER_PARSE) ||
+		(ddl->client_state != DDL_CLIENT_WAIT_FOR_INITCODECDONE)) {
+		DDL_MSG_ERROR("STATE-CRITICAL-HDDONE");
+		return false;
+	}
+
+	switch (ddl_context->cmd_err_status) {
+	case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE:
+	case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED:
+	case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
+	case VIDC_1080P_ERROR_SPS_PARSE_ERROR:
+	case VIDC_1080P_ERROR_PPS_PARSE_ERROR:
+	{
+		struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+		if (ddl_context->cmd_err_status ==
+			VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE
+			&& decoder->codec.codec == VCD_CODEC_H264) {
+			DDL_MSG_ERROR("Unsupported Feature for H264");
+			ddl_client_fatal_cb(ddl);
+			return true;
+		}
+		if ((ddl_context->cmd_err_status ==
+			VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED)
+			&& (decoder->codec.codec == VCD_CODEC_H263
+			|| decoder->codec.codec == VCD_CODEC_H264
+			|| decoder->codec.codec == VCD_CODEC_MPEG4
+			|| decoder->codec.codec == VCD_CODEC_VC1
+			|| decoder->codec.codec == VCD_CODEC_VC1_RCV)) {
+			DDL_MSG_ERROR("Unsupported resolution");
+			ddl_client_fatal_cb(ddl);
+			return true;
+		}
+
+		DDL_MSG_ERROR("SEQHDR-FAILED");
+		if (decoder->header_in_start) {
+			decoder->header_in_start = false;
+			ddl_context->ddl_callback(VCD_EVT_RESP_START,
+				VCD_ERR_SEQHDR_PARSE_FAIL, NULL, 0,
+				(u32 *) ddl, ddl->client_data);
+		} else {
+			ddl->input_frame.frm_trans_end = true;
+			if ((ddl->input_frame.vcd_frm.flags &
+				VCD_FRAME_FLAG_EOS)) {
+				ddl->input_frame.frm_trans_end = false;
+			}
+			ddl_vidc_decode_dynamic_property(ddl, false);
+			ddl_context->ddl_callback(
+				VCD_EVT_RESP_INPUT_DONE,
+				VCD_ERR_SEQHDR_PARSE_FAIL, &ddl->input_frame,
+				sizeof(struct ddl_frame_data_tag), (u32 *)ddl,
+				ddl->client_data);
+			if ((ddl->input_frame.vcd_frm.flags &
+				VCD_FRAME_FLAG_EOS)) {
+				DDL_MSG_HIGH("EOS_DONE-fromDDL");
+				ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE,
+				VCD_S_SUCCESS, NULL, 0, (u32 *) ddl,
+				ddl->client_data);
+			}
+		}
+		DDL_MSG_LOW("ddl_state_transition: %s ~~> "
+			"DDL_CLIENT_WAIT_FOR_INITCODEC",
+			ddl_get_state_string(ddl->client_state));
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC;
+		ddl_release_command_channel(ddl_context, ddl->command_channel);
+		status = true;
+		break;
+	}
+	default:
+		break;
+	}
+	return status;
+}
+
+void print_core_errors(u32 error_code)
+{
+	s8 *string = NULL;
+
+	switch (error_code) {
+	case VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER:
+		string = "VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER";
+	break;
+	case VIDC_1080P_ERROR_INVALID_COMMAND_ID:
+		string = "VIDC_1080P_ERROR_INVALID_COMMAND_ID";
+	break;
+	case VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE:
+		string = "VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE";
+	break;
+	case VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE:
+		string =
+		"VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE";
+	break;
+	case VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START:
+		string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START";
+	break;
+	case VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED:
+		string = "VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED";
+	break;
+	case VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS:
+		string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS";
+	break;
+	case VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS:
+		string = "VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS";
+	break;
+	case VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED:
+		string = "VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED";
+	break;
+	case VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START:
+		string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START";
+	break;
+	case VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START:
+		string = "VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START";
+	break;
+	case VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START:
+		string = "VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START";
+	break;
+	case VIDC_1080P_ERROR_RESOLUTION_CHANGED:
+		string = "VIDC_1080P_ERROR_RESOLUTION_CHANGED";
+	break;
+	case VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME:
+		string = "VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME";
+	break;
+	case VIDC_1080P_ERROR_INVALID_COMMAND:
+		string = "VIDC_1080P_ERROR_INVALID_COMMAND";
+	break;
+	case VIDC_1080P_ERROR_INVALID_CODEC_TYPE:
+		string = "VIDC_1080P_ERROR_INVALID_CODEC_TYPE";
+	break;
+	case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED:
+		string = "VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED";
+	break;
+	case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE:
+		string = "VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE";
+	break;
+	case VIDC_1080P_ERROR_DIVIDE_BY_ZERO:
+		string = "VIDC_1080P_ERROR_DIVIDE_BY_ZERO";
+	break;
+	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
+		string = "VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY";
+	break;
+	case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE:
+		string = "VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE";
+	break;
+	case VIDC_1080P_ERROR_VSP_NOT_READY:
+		string = "VIDC_1080P_ERROR_VSP_NOT_READY";
+	break;
+	case VIDC_1080P_ERROR_BUFFER_FULL_STATE:
+		string = "VIDC_1080P_ERROR_BUFFER_FULL_STATE";
+	break;
+	case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE:
+		string = "VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE";
+	break;
+	case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
+		string = "VIDC_1080P_ERROR_HEADER_NOT_FOUND";
+	break;
+	case VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED:
+		string = "VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED";
+	break;
+	case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED:
+		string = "VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED";
+	break;
+	case VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED:
+		string = "VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED";
+	break;
+	case VIDC_1080P_ERROR_INVALID_QP_VALUE:
+		string = "VIDC_1080P_ERROR_INVALID_QP_VALUE";
+	break;
+	case VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT:
+		string = "VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT";
+	break;
+	case VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL:
+		string = "VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL";
+	break;
+	case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED:
+		string = "VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED";
+	break;
+	case VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT:
+		string = "VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT";
+	break;
+	case VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE:
+		string = "VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE";
+	break;
+	case VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER:
+		string = "VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER";
+	break;
+	case VIDC_1080P_ERROR_NULL_DPB_POINTER:
+		string = "VIDC_1080P_ERROR_NULL_DPB_POINTER";
+	break;
+	case VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR:
+		string = "VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR";
+	break;
+	case VIDC_1080P_ERROR_NULL_MV_POINTER:
+		string = "VIDC_1080P_ERROR_NULL_MV_POINTER";
+	break;
+	case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED:
+		string = "VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED";
+	break;
+	case VIDC_1080P_WARN_COMMAND_FLUSHED:
+		string = "VIDC_1080P_WARN_COMMAND_FLUSHED";
+	break;
+	case VIDC_1080P_WARN_FRAME_RATE_UNKNOWN:
+		string = "VIDC_1080P_WARN_FRAME_RATE_UNKNOWN";
+	break;
+	case VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN:
+		string = "VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN";
+	break;
+	case VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN:
+		string = "VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN";
+	break;
+	case VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN:
+		string = "VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN";
+	break;
+	case VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN:
+		string = "VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN";
+	break;
+	case VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR:
+		string = "VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR";
+	break;
+	case VIDC_1080P_WARN_BROKEN_LINK:
+		string = "VIDC_1080P_WARN_BROKEN_LINK";
+	break;
+	case VIDC_1080P_WARN_FRAME_CONCEALED:
+		string = "VIDC_1080P_WARN_FRAME_CONCEALED";
+	break;
+	case VIDC_1080P_WARN_PROFILE_UNKNOWN:
+		string = "VIDC_1080P_WARN_PROFILE_UNKNOWN";
+	break;
+	case VIDC_1080P_WARN_LEVEL_UNKNOWN:
+		string = "VIDC_1080P_WARN_LEVEL_UNKNOWN";
+	break;
+	case VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED:
+		string = "VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED";
+	break;
+	case VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED:
+		string = "VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED";
+	break;
+	case VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER:
+		string = "VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER";
+	break;
+	case VIDC_1080P_WARN_DEBLOCKING_NOT_DONE:
+		string = "VIDC_1080P_WARN_DEBLOCKING_NOT_DONE";
+	break;
+	case VIDC_1080P_WARN_INCOMPLETE_FRAME:
+		string = "VIDC_1080P_WARN_INCOMPLETE_FRAME";
+	break;
+	case VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER:
+		string = "VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER";
+	break;
+	case VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT:
+		string =
+		"VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_QP:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_QP";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_SEI:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_SEI";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_VUI:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_VUI";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE";
+	break;
+	case VIDC_1080P_WARN_RESOLUTION_WARNING:
+		string = "VIDC_1080P_WARN_RESOLUTION_WARNING";
+	break;
+	case VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE:
+		string = "VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE";
+	break;
+	case VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP:
+		string = "VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP";
+	break;
+	case VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB:
+		string = "VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB";
+	break;
+	}
+	if (string)
+		DDL_MSG_ERROR("Error code = 0x%x : %s", error_code, string);
+}
+
+void print_core_recoverable_errors(u32 error_code)
+{
+	s8 *string = NULL;
+
+	switch (error_code) {
+	case VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED:
+		string = "VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED";
+	break;
+	case VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST:
+		string = "VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST";
+	break;
+	case VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST:
+		string = "VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST";
+	break;
+	case VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID:
+		string = "VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID";
+	break;
+	case VIDC_1080P_ERROR_MB_COEFF_NOT_DONE:
+		string = "VIDC_1080P_ERROR_MB_COEFF_NOT_DONE";
+	break;
+	case VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE:
+		string = "VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE";
+	break;
+	case VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT:
+		string = "VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT";
+	break;
+	case VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR:
+		string = "VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR";
+	break;
+	case VIDC_1080P_ERROR_RESOLUTION_MISMATCH:
+		string = "VIDC_1080P_ERROR_RESOLUTION_MISMATCH";
+	break;
+	case VIDC_1080P_ERROR_NV_QUANT_ERR:
+		string = "VIDC_1080P_ERROR_NV_QUANT_ERR";
+	break;
+	case VIDC_1080P_ERROR_SYNC_MARKER_ERR:
+		string = "VIDC_1080P_ERROR_SYNC_MARKER_ERR";
+	break;
+	case VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED:
+		string = "VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED";
+	break;
+	case VIDC_1080P_ERROR_MEM_CORRUPTION:
+		string = "VIDC_1080P_ERROR_MEM_CORRUPTION";
+	break;
+	case VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME:
+		string = "VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME";
+	break;
+	case VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR:
+		string = "VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR";
+	break;
+	case VIDC_1080P_ERROR_MV_RANGE_ERR:
+		string = "VIDC_1080P_ERROR_MV_RANGE_ERR";
+	break;
+	case VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR:
+		string = "VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR";
+	break;
+	case VIDC_1080P_ERROR_SLICE_ADDR_INVALID:
+		string = "VIDC_1080P_ERROR_SLICE_ADDR_INVALID";
+	break;
+	case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED:
+		string = "VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED";
+	break;
+	case VIDC_1080P_ERROR_NALU_HEADER_ERROR:
+		string = "VIDC_1080P_ERROR_NALU_HEADER_ERROR";
+	break;
+	case VIDC_1080P_ERROR_SPS_PARSE_ERROR:
+		string = "VIDC_1080P_ERROR_SPS_PARSE_ERROR";
+	break;
+	case VIDC_1080P_ERROR_PPS_PARSE_ERROR:
+		string = "VIDC_1080P_ERROR_PPS_PARSE_ERROR";
+	break;
+	case VIDC_1080P_ERROR_SLICE_PARSE_ERROR:
+		string = "VIDC_1080P_ERROR_SLICE_PARSE_ERROR";
+	break;
+	}
+	if (string)
+		DDL_MSG_ERROR("Recoverable Error code = 0x%x : %s",
+					  error_code, string);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
new file mode 100644
index 0000000..0acc2f6
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -0,0 +1,1065 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/ion.h>
+#include <mach/msm_memtypes.h>
+#include "vcd_ddl.h"
+#include "vcd_ddl_shared_mem.h"
+#include "vcd_res_tracker_api.h"
+
+
+struct ddl_context *ddl_get_context(void)
+{
+	static struct ddl_context ddl_context;
+	return &ddl_context;
+}
+
+#ifdef DDL_MSG_LOG
+s8 *ddl_get_state_string(enum ddl_client_state client_state)
+{
+	s8 *ptr;
+
+	switch (client_state) {
+	case DDL_CLIENT_INVALID:
+		ptr = "INVALID        ";
+	break;
+	case DDL_CLIENT_OPEN:
+		ptr = "OPEN   ";
+	break;
+	case DDL_CLIENT_WAIT_FOR_CHDONE:
+		ptr = "WAIT_FOR_CHDONE       ";
+	break;
+	case DDL_CLIENT_WAIT_FOR_INITCODEC:
+		ptr = "WAIT_FOR_INITCODEC    ";
+	break;
+	case DDL_CLIENT_WAIT_FOR_INITCODECDONE:
+		ptr = "WAIT_FOR_INITCODECDONE";
+	break;
+	case DDL_CLIENT_WAIT_FOR_DPB:
+		ptr = "WAIT_FOR_DPB   ";
+	break;
+	case DDL_CLIENT_WAIT_FOR_DPBDONE:
+		ptr = "WAIT_FOR_DPBDONE";
+	break;
+	case DDL_CLIENT_WAIT_FOR_FRAME:
+		ptr = "WAIT_FOR_FRAME ";
+	break;
+	case DDL_CLIENT_WAIT_FOR_FRAME_DONE:
+		ptr = "WAIT_FOR_FRAME_DONE   ";
+	break;
+	case DDL_CLIENT_WAIT_FOR_EOS_DONE:
+		ptr = "WAIT_FOR_EOS_DONE     ";
+	break;
+	case DDL_CLIENT_WAIT_FOR_CHEND:
+		ptr = "WAIT_FOR_CHEND ";
+	break;
+	case DDL_CLIENT_FATAL_ERROR:
+		ptr = "FATAL_ERROR";
+	break;
+	default:
+		ptr = "UNKNOWN        ";
+	break;
+	}
+	return ptr;
+}
+#endif
+
+u32 ddl_client_transact(u32 operation,
+	struct ddl_client_context **pddl_client)
+{
+	struct ddl_context *ddl_context;
+	u32 ret_status = VCD_ERR_FAIL;
+	s32 counter;
+
+	ddl_context = ddl_get_context();
+	switch (operation) {
+	case DDL_FREE_CLIENT:
+		ret_status = VCD_ERR_MAX_CLIENT;
+		for (counter = 0; (counter < VCD_MAX_NO_CLIENT) &&
+			(ret_status == VCD_ERR_MAX_CLIENT); ++counter) {
+			if (*pddl_client == ddl_context->ddl_clients
+				[counter]) {
+					kfree(*pddl_client);
+					*pddl_client = NULL;
+					ddl_context->ddl_clients[counter]
+						= NULL;
+				ret_status = VCD_S_SUCCESS;
+			}
+		}
+	break;
+	case DDL_GET_CLIENT:
+		ret_status = VCD_ERR_MAX_CLIENT;
+		for (counter = (VCD_MAX_NO_CLIENT - 1); (counter >= 0) &&
+			(ret_status == VCD_ERR_MAX_CLIENT); --counter) {
+			if (!ddl_context->ddl_clients[counter]) {
+				*pddl_client =
+					(struct ddl_client_context *)
+					kmalloc(sizeof(struct
+					ddl_client_context), GFP_KERNEL);
+				if (!*pddl_client)
+					ret_status = VCD_ERR_ALLOC_FAIL;
+				else {
+					memset(*pddl_client, 0,
+						sizeof(struct
+						ddl_client_context));
+					ddl_context->ddl_clients
+						[counter] = *pddl_client;
+					(*pddl_client)->ddl_context =
+						ddl_context;
+					ret_status = VCD_S_SUCCESS;
+				}
+			}
+		}
+	break;
+	case DDL_INIT_CLIENTS:
+		for (counter = 0; counter < VCD_MAX_NO_CLIENT; ++counter)
+			ddl_context->ddl_clients[counter] = NULL;
+		ret_status = VCD_S_SUCCESS;
+	break;
+	case DDL_ACTIVE_CLIENT:
+		for (counter = 0; counter < VCD_MAX_NO_CLIENT;
+			++counter) {
+			if (ddl_context->ddl_clients[counter]) {
+				ret_status = VCD_S_SUCCESS;
+				break;
+			}
+		}
+	break;
+	default:
+		ret_status = VCD_ERR_ILLEGAL_PARM;
+	break;
+	}
+	return ret_status;
+}
+
+u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder,
+	struct ddl_frame_data_tag  *in_out_frame, u32 operation)
+{
+	struct ddl_frame_data_tag *found_frame = NULL;
+	struct ddl_mask *dpb_mask = &decoder->dpb_mask;
+	u32 vcd_status = VCD_S_SUCCESS, loopc;
+
+	switch (operation) {
+	case DDL_DPB_OP_MARK_BUSY:
+	case DDL_DPB_OP_MARK_FREE:
+		for (loopc = 0; !found_frame && loopc <
+			decoder->dp_buf.no_of_dec_pic_buf; ++loopc) {
+			if (in_out_frame->vcd_frm.physical ==
+				decoder->dp_buf.dec_pic_buffers[loopc].
+				vcd_frm.physical) {
+				found_frame = &(decoder->dp_buf.
+					dec_pic_buffers[loopc]);
+			break;
+			}
+		}
+		if (found_frame) {
+			if (operation == DDL_DPB_OP_MARK_BUSY) {
+				dpb_mask->hw_mask &=
+					(~(u32)(0x1 << loopc));
+				*in_out_frame = *found_frame;
+			} else if (operation == DDL_DPB_OP_MARK_FREE) {
+				dpb_mask->client_mask |= (0x1 << loopc);
+				*found_frame = *in_out_frame;
+			}
+		} else {
+			in_out_frame->vcd_frm.physical = NULL;
+			in_out_frame->vcd_frm.virtual = NULL;
+			vcd_status = VCD_ERR_BAD_POINTER;
+			DDL_MSG_ERROR("BUF_NOT_FOUND");
+		}
+	break;
+	case DDL_DPB_OP_SET_MASK:
+		dpb_mask->hw_mask |= dpb_mask->client_mask;
+		dpb_mask->client_mask = 0;
+	break;
+	case DDL_DPB_OP_INIT:
+	{
+		u32 dpb_size;
+		dpb_size = (!decoder->meta_data_offset) ?
+		decoder->dp_buf.dec_pic_buffers[0].vcd_frm.alloc_len :
+			decoder->meta_data_offset;
+	}
+	break;
+	case DDL_DPB_OP_RETRIEVE:
+	{
+		u32 position;
+		if (dpb_mask->client_mask) {
+			position = 0x1;
+			for (loopc = 0; loopc <
+				decoder->dp_buf.no_of_dec_pic_buf &&
+				!found_frame; ++loopc) {
+				if (dpb_mask->client_mask & position) {
+					found_frame = &decoder->dp_buf.
+						dec_pic_buffers[loopc];
+					dpb_mask->client_mask &=
+						~(position);
+				}
+				position <<= 1;
+			}
+		} else if (dpb_mask->hw_mask) {
+			position = 0x1;
+			for (loopc = 0; loopc <
+				decoder->dp_buf.no_of_dec_pic_buf &&
+				!found_frame; ++loopc) {
+				if (dpb_mask->hw_mask & position) {
+					found_frame = &decoder->dp_buf.
+						dec_pic_buffers[loopc];
+					dpb_mask->hw_mask &= ~(position);
+				}
+				position <<= 1;
+			}
+		}
+		if (found_frame)
+			*in_out_frame = *found_frame;
+		else {
+			in_out_frame->vcd_frm.physical = NULL;
+			in_out_frame->vcd_frm.virtual = NULL;
+		}
+	}
+	break;
+	default:
+	break;
+	}
+	return vcd_status;
+}
+
+u32 ddl_decoder_dpb_init(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs;
+	struct ddl_frame_data_tag *frame;
+	u32 luma[DDL_MAX_BUFFER_COUNT], chroma[DDL_MAX_BUFFER_COUNT];
+	u32 mv[DDL_MAX_BUFFER_COUNT], luma_size, i, dpb;
+	frame = &decoder->dp_buf.dec_pic_buffers[0];
+	luma_size = ddl_get_yuv_buf_size(decoder->frame_size.width,
+			decoder->frame_size.height, DDL_YUV_BUF_TYPE_TILE);
+	dpb = decoder->dp_buf.no_of_dec_pic_buf;
+	DDL_MSG_LOW("%s Decoder num DPB buffers = %u Luma Size = %u"
+				 __func__, dpb, luma_size);
+	if (dpb > DDL_MAX_BUFFER_COUNT)
+		dpb = DDL_MAX_BUFFER_COUNT;
+	for (i = 0; i < dpb; i++) {
+		if (!res_trk_check_for_sec_session() &&
+			frame[i].vcd_frm.virtual) {
+			if (luma_size <= frame[i].vcd_frm.alloc_len) {
+				memset(frame[i].vcd_frm.virtual,
+					 0x10101010, luma_size);
+				memset(frame[i].vcd_frm.virtual + luma_size,
+					 0x80808080,
+					frame[i].vcd_frm.alloc_len - luma_size);
+				if (frame[i].vcd_frm.ion_flag == CACHED) {
+					msm_ion_do_cache_op(
+					ddl_context->video_ion_client,
+					frame[i].vcd_frm.buff_ion_handle,
+					(unsigned long *)frame[i].
+					vcd_frm.virtual,
+					(unsigned long)frame[i].
+					vcd_frm.alloc_len,
+					ION_IOC_CLEAN_INV_CACHES);
+				}
+			} else {
+				DDL_MSG_ERROR("luma size error");
+				return VCD_ERR_FAIL;
+			}
+		}
+
+		luma[i] = DDL_OFFSET(ddl_context->dram_base_a.
+			align_physical_addr, frame[i].vcd_frm.physical);
+		chroma[i] = luma[i] + luma_size;
+		DDL_MSG_LOW("%s Decoder Luma address = %x Chroma address = %x"
+					__func__, luma[i], chroma[i]);
+	}
+	switch (decoder->codec.codec) {
+	case VCD_CODEC_MPEG1:
+	case VCD_CODEC_MPEG2:
+		vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma);
+	break;
+	case VCD_CODEC_DIVX_3:
+	case VCD_CODEC_DIVX_4:
+	case VCD_CODEC_DIVX_5:
+	case VCD_CODEC_DIVX_6:
+	case VCD_CODEC_XVID:
+	case VCD_CODEC_MPEG4:
+		vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma);
+		vidc_1080p_set_mpeg4_divx_decode_work_buffers(
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			dec_buffers->nb_dcac),
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			dec_buffers->upnb_mv),
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			dec_buffers->sub_anchor_mv),
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			dec_buffers->overlay_xform),
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			dec_buffers->stx_parser));
+	break;
+	case VCD_CODEC_H263:
+		vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma);
+		vidc_1080p_set_h263_decode_work_buffers(
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->nb_dcac),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->upnb_mv),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->sub_anchor_mv),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->overlay_xform));
+	break;
+	case VCD_CODEC_VC1:
+	case VCD_CODEC_VC1_RCV:
+		vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma);
+		vidc_1080p_set_vc1_decode_work_buffers(
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->nb_dcac),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->upnb_mv),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->sub_anchor_mv),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->overlay_xform),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->bit_plane1),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->bit_plane2),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->bit_plane3));
+	break;
+	case VCD_CODEC_H264:
+		for (i = 0; i < dpb; i++)
+			mv[i] = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+					dec_buffers->h264_mv[i]);
+		vidc_1080p_set_h264_decode_buffers(dpb,
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->h264_vert_nb_mv),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				dec_buffers->h264_nb_ip),
+			luma, chroma, mv);
+	break;
+	default:
+	break;
+	}
+	return VCD_S_SUCCESS;
+}
+
+void ddl_release_context_buffers(struct ddl_context *ddl_context)
+{
+	ddl_pmem_free(&ddl_context->metadata_shared_input);
+	ddl_fw_release(&ddl_context->dram_base_a);
+}
+
+void ddl_release_client_internal_buffers(struct ddl_client_context *ddl)
+{
+	if (ddl->decoding) {
+		struct ddl_decoder_data *decoder =
+			&(ddl->codec_data.decoder);
+		kfree(decoder->dp_buf.dec_pic_buffers);
+		decoder->dp_buf.dec_pic_buffers = NULL;
+		ddl_vidc_decode_dynamic_property(ddl, false);
+		decoder->decode_config.sequence_header_len = 0;
+		decoder->decode_config.sequence_header = NULL;
+		decoder->dpb_mask.client_mask = 0;
+		decoder->dpb_mask.hw_mask = 0;
+		decoder->dp_buf.no_of_dec_pic_buf = 0;
+		decoder->dynamic_prop_change = 0;
+		ddl_free_dec_hw_buffers(ddl);
+	} else {
+		struct ddl_encoder_data *encoder =
+			&(ddl->codec_data.encoder);
+		ddl_pmem_free(&encoder->seq_header);
+		ddl_pmem_free(&encoder->batch_frame.slice_batch_in);
+		ddl_pmem_free(&encoder->batch_frame.slice_batch_out);
+		ddl_vidc_encode_dynamic_property(ddl, false);
+		encoder->dynamic_prop_change = 0;
+		ddl_free_enc_hw_buffers(ddl);
+	}
+}
+
+u32 ddl_codec_type_transact(struct ddl_client_context *ddl,
+	u32 remove, enum vcd_codec requested_codec)
+{
+	if (requested_codec > VCD_CODEC_VC1_RCV ||
+		requested_codec < VCD_CODEC_H264)
+		return false;
+	if (!ddl->decoding && requested_codec != VCD_CODEC_MPEG4 &&
+		requested_codec != VCD_CODEC_H264 &&
+		requested_codec != VCD_CODEC_H263)
+		return false;
+
+	return true;
+}
+
+u32 ddl_take_command_channel(struct ddl_context *ddl_context,
+	struct ddl_client_context *ddl, void *client_data)
+{
+	u32  status = true;
+
+	if (!ddl_context->current_ddl[0]) {
+		ddl_context->current_ddl[0] = ddl;
+		ddl->client_data = client_data;
+		ddl->command_channel = 0;
+	} else if (!ddl_context->current_ddl[1]) {
+		ddl_context->current_ddl[1] = ddl;
+		ddl->client_data = client_data;
+		ddl->command_channel = 1;
+	} else
+		status = false;
+	if (status) {
+		if (ddl_context->current_ddl[0] &&
+			ddl_context->current_ddl[1])
+			DDL_BUSY(ddl_context);
+		else
+			DDL_RUN(ddl_context);
+	}
+	return status;
+}
+
+void ddl_release_command_channel(struct ddl_context *ddl_context,
+	u32 command_channel)
+{
+	ddl_context->current_ddl[command_channel]->client_data = NULL;
+	ddl_context->current_ddl[command_channel] = NULL;
+	if (!ddl_context->current_ddl[0] &&
+		!ddl_context->current_ddl[1])
+		DDL_IDLE(ddl_context);
+	else
+		DDL_RUN(ddl_context);
+}
+
+struct ddl_client_context *ddl_get_current_ddl_client_for_channel_id(
+	struct ddl_context *ddl_context, u32 channel_id)
+{
+	struct ddl_client_context *ddl;
+
+	if (ddl_context->current_ddl[0] && channel_id ==
+		ddl_context->current_ddl[0]->command_channel)
+		ddl = ddl_context->current_ddl[0];
+	else if (ddl_context->current_ddl[1] && channel_id ==
+		ddl_context->current_ddl[1]->command_channel)
+		ddl = ddl_context->current_ddl[1];
+	else {
+		DDL_MSG_LOW("STATE-CRITICAL-FRMRUN");
+		DDL_MSG_ERROR("Unexpected channel ID = %d", channel_id);
+		ddl = NULL;
+	}
+	return ddl;
+}
+
+struct ddl_client_context *ddl_get_current_ddl_client_for_command(
+	struct ddl_context *ddl_context,
+	enum ddl_cmd_state cmd_state)
+{
+	struct ddl_client_context *ddl;
+
+	if (ddl_context->current_ddl[0] &&
+		cmd_state == ddl_context->current_ddl[0]->cmd_state)
+		ddl = ddl_context->current_ddl[0];
+	else if (ddl_context->current_ddl[1] &&
+		cmd_state == ddl_context->current_ddl[1]->cmd_state)
+		ddl = ddl_context->current_ddl[1];
+	else {
+		DDL_MSG_LOW("STATE-CRITICAL-FRMRUN");
+		DDL_MSG_ERROR("Error: Unexpected cmd_state = %d",
+			cmd_state);
+		ddl = NULL;
+	}
+	return ddl;
+}
+
+u32 ddl_get_yuv_buf_size(u32 width, u32 height, u32 format)
+{
+	u32 mem_size, width_round_up, height_round_up, align;
+
+	width_round_up  = width;
+	height_round_up = height;
+	if (format == DDL_YUV_BUF_TYPE_TILE) {
+		width_round_up  = DDL_ALIGN(width, DDL_TILE_ALIGN_WIDTH);
+		height_round_up = DDL_ALIGN(height, DDL_TILE_ALIGN_HEIGHT);
+		align = DDL_TILE_MULTIPLY_FACTOR;
+	}
+	if (format == DDL_YUV_BUF_TYPE_LINEAR) {
+		width_round_up = DDL_ALIGN(width, DDL_LINEAR_ALIGN_WIDTH);
+		align = DDL_LINEAR_MULTIPLY_FACTOR;
+	}
+	mem_size = (width_round_up * height_round_up);
+	mem_size = DDL_ALIGN(mem_size, align);
+	return mem_size;
+}
+void ddl_free_dec_hw_buffers(struct ddl_client_context *ddl)
+{
+	struct ddl_dec_buffers *dec_bufs =
+		&ddl->codec_data.decoder.hw_bufs;
+	ddl_pmem_free(&dec_bufs->h264_nb_ip);
+	ddl_pmem_free(&dec_bufs->h264_vert_nb_mv);
+	ddl_pmem_free(&dec_bufs->nb_dcac);
+	ddl_pmem_free(&dec_bufs->upnb_mv);
+	ddl_pmem_free(&dec_bufs->sub_anchor_mv);
+	ddl_pmem_free(&dec_bufs->overlay_xform);
+	ddl_pmem_free(&dec_bufs->bit_plane3);
+	ddl_pmem_free(&dec_bufs->bit_plane2);
+	ddl_pmem_free(&dec_bufs->bit_plane1);
+	ddl_pmem_free(&dec_bufs->stx_parser);
+	ddl_pmem_free(&dec_bufs->desc);
+	ddl_pmem_free(&dec_bufs->context);
+	memset(dec_bufs, 0, sizeof(struct ddl_dec_buffers));
+}
+
+void ddl_free_enc_hw_buffers(struct ddl_client_context *ddl)
+{
+	struct ddl_enc_buffers *enc_bufs =
+		&ddl->codec_data.encoder.hw_bufs;
+	u32 i;
+
+	for (i = 0; i < enc_bufs->dpb_count; i++) {
+		ddl_pmem_free(&enc_bufs->dpb_y[i]);
+		ddl_pmem_free(&enc_bufs->dpb_c[i]);
+	}
+	ddl_pmem_free(&enc_bufs->mv);
+	ddl_pmem_free(&enc_bufs->col_zero);
+	ddl_pmem_free(&enc_bufs->md);
+	ddl_pmem_free(&enc_bufs->pred);
+	ddl_pmem_free(&enc_bufs->nbor_info);
+	ddl_pmem_free(&enc_bufs->acdc_coef);
+	ddl_pmem_free(&enc_bufs->context);
+	memset(enc_bufs, 0, sizeof(struct ddl_enc_buffers));
+}
+
+u32 ddl_get_input_frame_from_pool(struct ddl_client_context *ddl,
+	u8 *input_buffer_address)
+{
+	u32 vcd_status = VCD_S_SUCCESS, i, found = false;
+
+	for (i = 0; i < DDL_MAX_NUM_IN_INPUTFRAME_POOL && !found; i++) {
+		if (input_buffer_address ==
+			ddl->input_frame_pool[i].vcd_frm.physical) {
+			found = true;
+			ddl->input_frame = ddl->input_frame_pool[i];
+			memset(&ddl->input_frame_pool[i], 0,
+				sizeof(struct ddl_frame_data_tag));
+		}
+	}
+	if (!found)
+		vcd_status = VCD_ERR_FAIL;
+
+	return vcd_status;
+}
+
+u32 ddl_insert_input_frame_to_pool(struct ddl_client_context *ddl,
+	struct ddl_frame_data_tag *ddl_input_frame)
+{
+	u32 vcd_status = VCD_S_SUCCESS, i, found = false;
+
+	for (i = 0; i < DDL_MAX_NUM_IN_INPUTFRAME_POOL && !found; i++) {
+		if (!ddl->input_frame_pool[i].vcd_frm.physical) {
+			found = true;
+			ddl->input_frame_pool[i] = *ddl_input_frame;
+		}
+	}
+	if (!found)
+		vcd_status = VCD_ERR_FAIL;
+
+	return vcd_status;
+}
+
+void ddl_calc_dec_hw_buffers_size(enum vcd_codec codec, u32 width,
+	u32 height, u32 dpb, struct ddl_dec_buffer_size *buf_size)
+{
+	u32 sz_dpb0 = 0, sz_dpb1 = 0, sz_mv = 0;
+	u32 sz_luma = 0, sz_chroma = 0, sz_nb_dcac = 0, sz_upnb_mv = 0;
+	u32 sz_sub_anchor_mv = 0, sz_overlap_xform = 0, sz_bit_plane3 = 0;
+	u32 sz_bit_plane2 = 0, sz_bit_plane1 = 0, sz_stx_parser = 0;
+	u32 sz_desc, sz_cpb, sz_context, sz_vert_nb_mv = 0, sz_nb_ip = 0;
+
+	if (codec == VCD_CODEC_H264) {
+		sz_mv = ddl_get_yuv_buf_size(width,
+			height>>2, DDL_YUV_BUF_TYPE_TILE);
+		sz_nb_ip = DDL_KILO_BYTE(32);
+		sz_vert_nb_mv = DDL_KILO_BYTE(16);
+	} else {
+		if ((codec == VCD_CODEC_MPEG4) ||
+			(codec == VCD_CODEC_DIVX_3) ||
+			(codec == VCD_CODEC_DIVX_4) ||
+			(codec == VCD_CODEC_DIVX_5) ||
+			(codec == VCD_CODEC_DIVX_6) ||
+			(codec == VCD_CODEC_XVID) ||
+			(codec == VCD_CODEC_H263)) {
+			sz_nb_dcac = DDL_KILO_BYTE(16);
+			sz_upnb_mv = DDL_KILO_BYTE(68);
+			sz_sub_anchor_mv = DDL_KILO_BYTE(136);
+			sz_overlap_xform = DDL_KILO_BYTE(32);
+			if (codec != VCD_CODEC_H263)
+				sz_stx_parser = DDL_KILO_BYTE(68);
+		} else if ((codec == VCD_CODEC_VC1) ||
+			(codec == VCD_CODEC_VC1_RCV)) {
+			sz_nb_dcac = DDL_KILO_BYTE(16);
+			sz_upnb_mv = DDL_KILO_BYTE(68);
+			sz_sub_anchor_mv = DDL_KILO_BYTE(136);
+			sz_overlap_xform = DDL_KILO_BYTE(32);
+			sz_bit_plane3 = DDL_KILO_BYTE(2);
+			sz_bit_plane2 = DDL_KILO_BYTE(2);
+			sz_bit_plane1 = DDL_KILO_BYTE(2);
+		}
+	}
+	sz_desc = DDL_KILO_BYTE(128);
+	sz_cpb = VCD_DEC_CPB_SIZE;
+	if (codec == VCD_CODEC_H264)
+		sz_context = DDL_FW_H264DEC_CONTEXT_SPACE_SIZE;
+	else
+		sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE;
+	if (buf_size) {
+		buf_size->sz_dpb0           = sz_dpb0;
+		buf_size->sz_dpb1           = sz_dpb1;
+		buf_size->sz_mv             = sz_mv;
+		buf_size->sz_vert_nb_mv     = sz_vert_nb_mv;
+		buf_size->sz_nb_ip          = sz_nb_ip;
+		buf_size->sz_luma           = sz_luma;
+		buf_size->sz_chroma         = sz_chroma;
+		buf_size->sz_nb_dcac        = sz_nb_dcac;
+		buf_size->sz_upnb_mv        = sz_upnb_mv;
+		buf_size->sz_sub_anchor_mv  = sz_sub_anchor_mv;
+		buf_size->sz_overlap_xform  = sz_overlap_xform;
+		buf_size->sz_bit_plane3     = sz_bit_plane3;
+		buf_size->sz_bit_plane2     = sz_bit_plane2;
+		buf_size->sz_bit_plane1     = sz_bit_plane1;
+		buf_size->sz_stx_parser     = sz_stx_parser;
+		buf_size->sz_desc           = sz_desc;
+		buf_size->sz_cpb            = sz_cpb;
+		buf_size->sz_context        = sz_context;
+	}
+}
+
+u32 ddl_allocate_dec_hw_buffers(struct ddl_client_context *ddl)
+{
+	struct ddl_dec_buffers *dec_bufs;
+	struct ddl_dec_buffer_size buf_size;
+	u32 status = VCD_S_SUCCESS, dpb = 0;
+	u32 width = 0, height = 0;
+	u8 *ptr;
+	struct ddl_context *ddl_context = ddl->ddl_context;
+
+	dec_bufs = &ddl->codec_data.decoder.hw_bufs;
+	ddl_calc_dec_hw_buffers_size(ddl->codec_data.decoder.
+		codec.codec, width, height, dpb, &buf_size);
+	if (buf_size.sz_context > 0) {
+		dec_bufs->context.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->context, buf_size.sz_context,
+			DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+		msm_ion_do_cache_op(ddl_context->video_ion_client,
+					dec_bufs->context.alloc_handle,
+					dec_bufs->context.virtual_base_addr,
+					dec_bufs->context.buffer_size,
+					ION_IOC_CLEAN_INV_CACHES);
+	}
+	if (buf_size.sz_nb_ip > 0) {
+		dec_bufs->h264_nb_ip.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->h264_nb_ip, buf_size.sz_nb_ip,
+			DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_vert_nb_mv > 0) {
+		dec_bufs->h264_vert_nb_mv.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->h264_vert_nb_mv,
+			buf_size.sz_vert_nb_mv, DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_nb_dcac > 0) {
+		dec_bufs->nb_dcac.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->nb_dcac, buf_size.sz_nb_dcac,
+			DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_upnb_mv > 0) {
+		dec_bufs->upnb_mv.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->upnb_mv, buf_size.sz_upnb_mv,
+			DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_sub_anchor_mv > 0) {
+		dec_bufs->sub_anchor_mv.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->sub_anchor_mv,
+			buf_size.sz_sub_anchor_mv, DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_overlap_xform > 0) {
+		dec_bufs->overlay_xform.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->overlay_xform,
+			buf_size.sz_overlap_xform, DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_bit_plane3 > 0) {
+		dec_bufs->bit_plane3.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->bit_plane3,
+			buf_size.sz_bit_plane3, DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_bit_plane2 > 0) {
+		dec_bufs->bit_plane2.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->bit_plane2,
+			buf_size.sz_bit_plane2, DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_bit_plane1 > 0) {
+		dec_bufs->bit_plane1.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->bit_plane1,
+			buf_size.sz_bit_plane1, DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_stx_parser > 0) {
+		dec_bufs->stx_parser.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->stx_parser,
+			buf_size.sz_stx_parser, DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_desc > 0) {
+		dec_bufs->desc.mem_type = DDL_MM_MEM;
+		ptr = ddl_pmem_alloc(&dec_bufs->desc, buf_size.sz_desc,
+			DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+		else {
+			if (!res_trk_check_for_sec_session()) {
+				memset(dec_bufs->desc.align_virtual_addr,
+					0, buf_size.sz_desc);
+				msm_ion_do_cache_op(
+					ddl_context->video_ion_client,
+					dec_bufs->desc.alloc_handle,
+					dec_bufs->desc.virtual_base_addr,
+					dec_bufs->desc.buffer_size,
+					ION_IOC_CLEAN_INV_CACHES);
+			}
+		}
+	}
+	if (status)
+		ddl_free_dec_hw_buffers(ddl);
+	return status;
+}
+
+u32 ddl_calc_enc_hw_buffers_size(enum vcd_codec codec, u32 width,
+	u32 height, enum vcd_yuv_buffer_format input_format,
+	struct ddl_client_context *ddl,
+	struct ddl_enc_buffer_size *buf_size)
+{
+	u32 status = VCD_S_SUCCESS, mb_x, mb_y;
+	u32 sz_cur_y, sz_cur_c, sz_dpb_y, sz_dpb_c, sz_strm = 0, sz_mv;
+	u32 sz_md = 0, sz_pred = 0, sz_nbor_info = 0 , sz_acdc_coef = 0;
+	u32 sz_mb_info = 0, sz_context, sz_col_zero = 0;
+
+	mb_x = (width + 15) / 16;
+	mb_y = (height + 15) / 16;
+	sz_dpb_y = ddl_get_yuv_buf_size(width,
+		height, DDL_YUV_BUF_TYPE_TILE);
+	sz_dpb_c = ddl_get_yuv_buf_size(width, height>>1,
+		DDL_YUV_BUF_TYPE_TILE);
+	if (input_format ==
+		VCD_BUFFER_FORMAT_NV12_16M2KA) {
+		sz_cur_y = ddl_get_yuv_buf_size(width, height,
+			DDL_YUV_BUF_TYPE_LINEAR);
+		sz_cur_c = ddl_get_yuv_buf_size(width, height>>1,
+			DDL_YUV_BUF_TYPE_LINEAR);
+	} else if (VCD_BUFFER_FORMAT_TILE_4x2 == input_format) {
+		sz_cur_y = sz_dpb_y;
+		sz_cur_c = sz_dpb_c;
+	} else
+		status = VCD_ERR_NOT_SUPPORTED;
+	sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE;
+	if (!status) {
+		sz_strm = DDL_ALIGN(ddl_get_yuv_buf_size(width, height,
+			DDL_YUV_BUF_TYPE_LINEAR) + ddl_get_yuv_buf_size(width,
+			height/2, DDL_YUV_BUF_TYPE_LINEAR), DDL_KILO_BYTE(4));
+		sz_mv = DDL_ALIGN(2 * mb_x * mb_y * 8, DDL_KILO_BYTE(2));
+		if ((codec == VCD_CODEC_MPEG4) ||
+			(codec == VCD_CODEC_H264)) {
+			sz_col_zero = DDL_ALIGN(((mb_x * mb_y + 7) / 8) *
+					8, DDL_KILO_BYTE(2));
+		}
+		if ((codec == VCD_CODEC_MPEG4) ||
+			(codec == VCD_CODEC_H263)) {
+			sz_acdc_coef = DDL_ALIGN((width / 2) * 8,
+						DDL_KILO_BYTE(2));
+		} else if (codec == VCD_CODEC_H264) {
+			sz_md = DDL_ALIGN(mb_x * 48, DDL_KILO_BYTE(2));
+			sz_pred = DDL_ALIGN(2 * 8 * 1024, DDL_KILO_BYTE(2));
+			sz_context = DDL_FW_H264ENC_CONTEXT_SPACE_SIZE;
+			if (ddl) {
+				if (ddl->codec_data.encoder.
+					entropy_control.entropy_sel ==
+					VCD_ENTROPY_SEL_CAVLC)
+					sz_nbor_info = DDL_ALIGN(8 * 8 * mb_x,
+						DDL_KILO_BYTE(2));
+				else if (ddl->codec_data.encoder.
+					entropy_control.entropy_sel ==
+					VCD_ENTROPY_SEL_CABAC)
+					sz_nbor_info = DDL_ALIGN(8 * 24 *
+						mb_x, DDL_KILO_BYTE(2));
+				if ((ddl->codec_data.encoder.
+					mb_info_enable) &&
+					(codec == VCD_CODEC_H264)) {
+					sz_mb_info = DDL_ALIGN(mb_x * mb_y *
+						6 * 8, DDL_KILO_BYTE(2));
+				}
+			}
+		} else {
+			sz_nbor_info = DDL_ALIGN(8 * 24 * mb_x,
+						DDL_KILO_BYTE(2));
+			sz_mb_info = DDL_ALIGN(mb_x * mb_y * 6 * 8,
+					DDL_KILO_BYTE(2));
+		}
+		if (buf_size) {
+			buf_size->sz_cur_y      = sz_cur_y;
+			buf_size->sz_cur_c      = sz_cur_c;
+			buf_size->sz_dpb_y      = sz_dpb_y;
+			buf_size->sz_dpb_c      = sz_dpb_c;
+			buf_size->sz_strm       = sz_strm;
+			buf_size->sz_mv         = sz_mv;
+			buf_size->sz_col_zero   = sz_col_zero;
+			buf_size->sz_md         = sz_md;
+			buf_size->sz_pred       = sz_pred;
+			buf_size->sz_nbor_info  = sz_nbor_info;
+			buf_size->sz_acdc_coef  = sz_acdc_coef;
+			buf_size->sz_mb_info    = sz_mb_info;
+			buf_size->sz_context    = sz_context;
+		}
+	}
+	return status;
+}
+
+u32 ddl_allocate_enc_hw_buffers(struct ddl_client_context *ddl)
+{
+	struct ddl_enc_buffers *enc_bufs;
+	struct ddl_enc_buffer_size buf_size;
+	void *ptr;
+	u32 status = VCD_S_SUCCESS;
+	struct ddl_context *ddl_context = ddl->ddl_context;
+
+	enc_bufs = &ddl->codec_data.encoder.hw_bufs;
+	enc_bufs->dpb_count = DDL_ENC_MIN_DPB_BUFFERS;
+
+	if ((ddl->codec_data.encoder.i_period.b_frames >
+		DDL_MIN_NUM_OF_B_FRAME) ||
+		(ddl->codec_data.encoder.num_references_for_p_frame
+		> DDL_MIN_NUM_REF_FOR_P_FRAME))
+		enc_bufs->dpb_count = DDL_ENC_MAX_DPB_BUFFERS;
+		DDL_MSG_HIGH("Encoder num DPB buffers allocated = %d",
+			enc_bufs->dpb_count);
+
+	status = ddl_calc_enc_hw_buffers_size(
+		ddl->codec_data.encoder.codec.codec,
+		ddl->codec_data.encoder.frame_size.width,
+		ddl->codec_data.encoder.frame_size.height,
+		ddl->codec_data.encoder.buf_format.buffer_format,
+		ddl, &buf_size);
+	buf_size.sz_strm = ddl->codec_data.encoder.
+		client_output_buf_req.sz;
+	if (!status) {
+		enc_bufs->sz_dpb_y = buf_size.sz_dpb_y;
+		enc_bufs->sz_dpb_c = buf_size.sz_dpb_c;
+		if (buf_size.sz_mv > 0) {
+			enc_bufs->mv.mem_type = DDL_MM_MEM;
+			ptr = ddl_pmem_alloc(&enc_bufs->mv, buf_size.sz_mv,
+				DDL_KILO_BYTE(2));
+			if (!ptr)
+				status = VCD_ERR_ALLOC_FAIL;
+		}
+		if (buf_size.sz_col_zero > 0) {
+			enc_bufs->col_zero.mem_type = DDL_MM_MEM;
+			ptr = ddl_pmem_alloc(&enc_bufs->col_zero,
+				buf_size.sz_col_zero, DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+		}
+		if (buf_size.sz_md > 0) {
+			enc_bufs->md.mem_type = DDL_MM_MEM;
+			ptr = ddl_pmem_alloc(&enc_bufs->md, buf_size.sz_md,
+				DDL_KILO_BYTE(2));
+			if (!ptr)
+				status = VCD_ERR_ALLOC_FAIL;
+		}
+		if (buf_size.sz_pred > 0) {
+			enc_bufs->pred.mem_type = DDL_MM_MEM;
+			ptr = ddl_pmem_alloc(&enc_bufs->pred,
+				buf_size.sz_pred, DDL_KILO_BYTE(2));
+			if (!ptr)
+				status = VCD_ERR_ALLOC_FAIL;
+		}
+		if (buf_size.sz_nbor_info > 0) {
+			enc_bufs->nbor_info.mem_type = DDL_MM_MEM;
+			ptr = ddl_pmem_alloc(&enc_bufs->nbor_info,
+				buf_size.sz_nbor_info, DDL_KILO_BYTE(2));
+			if (!ptr)
+				status = VCD_ERR_ALLOC_FAIL;
+		}
+		if (buf_size.sz_acdc_coef > 0) {
+			enc_bufs->acdc_coef.mem_type = DDL_MM_MEM;
+			ptr = ddl_pmem_alloc(&enc_bufs->acdc_coef,
+				buf_size.sz_acdc_coef, DDL_KILO_BYTE(2));
+			if (!ptr)
+				status = VCD_ERR_ALLOC_FAIL;
+		}
+		if (buf_size.sz_mb_info > 0) {
+			enc_bufs->mb_info.mem_type = DDL_MM_MEM;
+			ptr = ddl_pmem_alloc(&enc_bufs->mb_info,
+				buf_size.sz_mb_info, DDL_KILO_BYTE(2));
+			if (!ptr)
+				status = VCD_ERR_ALLOC_FAIL;
+		}
+		if (buf_size.sz_context > 0) {
+			enc_bufs->context.mem_type = DDL_MM_MEM;
+			ptr = ddl_pmem_alloc(&enc_bufs->context,
+				buf_size.sz_context, DDL_KILO_BYTE(2));
+			if (!ptr)
+				status = VCD_ERR_ALLOC_FAIL;
+			msm_ion_do_cache_op(ddl_context->video_ion_client,
+					enc_bufs->context.alloc_handle,
+					enc_bufs->context.virtual_base_addr,
+					enc_bufs->context.buffer_size,
+					ION_IOC_CLEAN_INV_CACHES);
+		}
+		if (status)
+			ddl_free_enc_hw_buffers(ddl);
+	}
+	return status;
+}
+
+void ddl_decoder_chroma_dpb_change(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	struct ddl_frame_data_tag *frame =
+			&(decoder->dp_buf.dec_pic_buffers[0]);
+	u32 luma[DDL_MAX_BUFFER_COUNT];
+	u32 chroma[DDL_MAX_BUFFER_COUNT];
+	u32 luma_size, i, dpb;
+	luma_size = decoder->dpb_buf_size.size_y;
+	dpb = decoder->dp_buf.no_of_dec_pic_buf;
+	DDL_MSG_HIGH("%s Decoder num DPB buffers = %u Luma Size = %u"
+			 __func__, dpb, luma_size);
+	if (dpb > DDL_MAX_BUFFER_COUNT)
+		dpb = DDL_MAX_BUFFER_COUNT;
+	for (i = 0; i < dpb; i++) {
+		luma[i] = DDL_OFFSET(
+			ddl_context->dram_base_a.align_physical_addr,
+			frame[i].vcd_frm.physical);
+		chroma[i] = luma[i] + luma_size;
+		DDL_MSG_LOW("%s Decoder Luma address = %x"
+			"Chroma address = %x", __func__, luma[i], chroma[i]);
+	}
+	vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma);
+}
+
+u32 ddl_check_reconfig(struct ddl_client_context *ddl)
+{
+	u32 need_reconfig = true;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	if (decoder->cont_mode) {
+		if ((decoder->actual_output_buf_req.sz <=
+			 decoder->client_output_buf_req.sz) &&
+			(decoder->actual_output_buf_req.actual_count <=
+			 decoder->client_output_buf_req.actual_count)) {
+			need_reconfig = false;
+			if (decoder->min_dpb_num >
+				decoder->min_output_buf_req.min_count) {
+				decoder->min_output_buf_req =
+					decoder->actual_output_buf_req;
+			}
+			DDL_MSG_LOW("%s Decoder width = %u height = %u "
+				"Client width = %u height = %u\n",
+				__func__, decoder->frame_size.width,
+				 decoder->frame_size.height,
+				 decoder->client_frame_size.width,
+				 decoder->client_frame_size.height);
+		}
+	} else {
+		if ((decoder->frame_size.width ==
+			decoder->client_frame_size.width) &&
+			(decoder->frame_size.height ==
+			decoder->client_frame_size.height) &&
+			(decoder->actual_output_buf_req.sz <=
+			decoder->client_output_buf_req.sz) &&
+			(decoder->actual_output_buf_req.min_count ==
+			decoder->client_output_buf_req.min_count) &&
+			(decoder->actual_output_buf_req.actual_count ==
+			decoder->client_output_buf_req.actual_count) &&
+			(decoder->frame_size.scan_lines ==
+			decoder->client_frame_size.scan_lines) &&
+			(decoder->frame_size.stride ==
+			decoder->client_frame_size.stride))
+				need_reconfig = false;
+	}
+	return need_reconfig;
+}
+
+void ddl_handle_reconfig(u32 res_change, struct ddl_client_context *ddl)
+{
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	if ((decoder->cont_mode) &&
+		(res_change == DDL_RESL_CHANGE_DECREASED)) {
+		DDL_MSG_LOW("%s Resolution decreased, continue decoding\n",
+				 __func__);
+		vidc_sm_get_min_yc_dpb_sizes(
+					&ddl->shared_mem[ddl->command_channel],
+					&decoder->dpb_buf_size.size_y,
+					&decoder->dpb_buf_size.size_c);
+		DDL_MSG_LOW(" %s Resolution decreased, size_y = %u"
+				" size_c = %u\n",
+				__func__,
+				decoder->dpb_buf_size.size_y,
+				decoder->dpb_buf_size.size_c);
+		ddl_decoder_chroma_dpb_change(ddl);
+		vidc_sm_set_chroma_addr_change(
+				&ddl->shared_mem[ddl->command_channel],
+				true);
+		ddl_vidc_decode_frame_run(ddl);
+	} else {
+		DDL_MSG_LOW("%s Resolution change, start realloc\n",
+				 __func__);
+		decoder->reconfig_detected = true;
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+		ddl->cmd_state = DDL_CMD_EOS;
+		vidc_1080p_frame_start_realloc(ddl->instance_id);
+	}
+}
+
+void ddl_fill_dec_desc_buffer(struct ddl_client_context *ddl)
+{
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	struct vcd_frame_data *ip_bitstream = &(ddl->input_frame.vcd_frm);
+	struct ddl_buf_addr *dec_desc_buf = &(decoder->hw_bufs.desc);
+
+	if (ip_bitstream->desc_buf &&
+		ip_bitstream->desc_size < DDL_KILO_BYTE(128))
+		memcpy(dec_desc_buf->align_virtual_addr,
+			   ip_bitstream->desc_buf,
+			   ip_bitstream->desc_size);
+}
+
+void ddl_set_vidc_timeout(struct ddl_client_context *ddl)
+{
+	u32 vidc_time_out = 0;
+	if (ddl->codec_data.decoder.idr_only_decoding)
+		vidc_time_out = 2 * DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE;
+	DDL_MSG_HIGH("%s Video core time out value = 0x%x",
+		 __func__, vidc_time_out);
+	vidc_sm_set_video_core_timeout_value(
+		&ddl->shared_mem[ddl->command_channel], vidc_time_out);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
new file mode 100644
index 0000000..f9c728a
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -0,0 +1,1983 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+
+#include "vcd_ddl.h"
+#include "vcd_ddl_shared_mem.h"
+#include "vcd_ddl_metadata.h"
+#include "vcd_res_tracker_api.h"
+#include <linux/delay.h>
+
+static void ddl_decoder_input_done_callback(
+	struct ddl_client_context *ddl, u32 frame_transact_end);
+static u32 ddl_decoder_output_done_callback(
+	struct ddl_client_context *ddl, u32 frame_transact_end);
+static u32 ddl_get_decoded_frame(struct vcd_frame_data  *frame,
+	enum vidc_1080p_decode_frame frame_type);
+static u32 ddl_get_encoded_frame(struct vcd_frame_data *frame,
+	enum vcd_codec codec,
+	enum vidc_1080p_encode_frame frame_type);
+static void ddl_get_dec_profile_level(struct ddl_decoder_data *decoder,
+	u32 profile, u32 level);
+static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl,
+	u32 eos_present);
+static void ddl_handle_slice_done_slice_batch(struct ddl_client_context *ddl);
+static void ddl_handle_enc_frame_done_slice_mode(
+		struct ddl_client_context *ddl, u32 eos_present);
+static void ddl_handle_enc_skipframe_slice_mode(
+		struct ddl_client_context *ddl, u32 eos_present);
+
+static void ddl_fw_status_done_callback(struct ddl_context *ddl_context)
+{
+	DDL_MSG_MED("ddl_fw_status_done_callback");
+	if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) {
+		DDL_MSG_ERROR("UNKWN_DMADONE");
+	} else {
+		DDL_MSG_LOW("FW_STATUS_DONE");
+		vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_SYS_INIT,
+			ddl_context->fw_memory_size, 0, 0, 0);
+	}
+}
+
+static void ddl_sys_init_done_callback(struct ddl_context *ddl_context,
+	u32 fw_size)
+{
+	u32 vcd_status = VCD_S_SUCCESS;
+	u8 *fw_ver;
+
+	DDL_MSG_MED("ddl_sys_init_done_callback");
+	if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) {
+		DDL_MSG_ERROR("UNKNOWN_SYS_INIT_DONE");
+	} else {
+		ddl_context->cmd_state = DDL_CMD_INVALID;
+		DDL_MSG_LOW("SYS_INIT_DONE");
+		vidc_1080p_get_fw_version(&ddl_context->fw_version);
+		fw_ver = (u8 *)&ddl_context->fw_version;
+		DDL_MSG_ERROR("fw_version %x:%x:20%x",
+			fw_ver[1]&0xFF, fw_ver[0]&0xFF, fw_ver[2]&0xFF);
+		if (ddl_context->fw_memory_size >= fw_size) {
+			ddl_context->device_state = DDL_DEVICE_INITED;
+			vcd_status = VCD_S_SUCCESS;
+		} else
+			vcd_status = VCD_ERR_FAIL;
+		ddl_context->ddl_callback(VCD_EVT_RESP_DEVICE_INIT,
+			vcd_status, NULL, 0, NULL,
+			ddl_context->client_data);
+		DDL_IDLE(ddl_context);
+	}
+}
+
+static void ddl_decoder_eos_done_callback(
+	struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+
+	if (!ddl->decoding) {
+		DDL_MSG_ERROR("STATE-CRITICAL-EOSDONE");
+		ddl_client_fatal_cb(ddl);
+	} else {
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME;
+		DDL_MSG_LOW("EOS_DONE");
+		ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE,
+			VCD_S_SUCCESS, NULL, 0, (u32 *)ddl,
+			ddl->client_data);
+		ddl_release_command_channel(ddl_context,
+			ddl->command_channel);
+	}
+}
+
+static u32 ddl_channel_set_callback(struct ddl_context *ddl_context,
+	u32 instance_id)
+{
+	struct ddl_client_context *ddl;
+	u32 ret = false;
+
+	DDL_MSG_MED("ddl_channel_open_callback");
+	ddl = ddl_get_current_ddl_client_for_command(ddl_context,
+			DDL_CMD_CHANNEL_SET);
+	if (ddl) {
+		ddl->cmd_state = DDL_CMD_INVALID;
+		if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHDONE)) {
+			DDL_MSG_ERROR("STATE-CRITICAL-CHSET");
+			ddl_release_command_channel(ddl_context,
+			ddl->command_channel);
+		} else {
+			DDL_MSG_LOW("CH_SET_DONE");
+			DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+				"DDL_CLIENT_WAIT_FOR_INITCODEC",
+				ddl_get_state_string(ddl->client_state));
+			ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC;
+			ddl->instance_id = instance_id;
+			if (ddl->decoding) {
+				if (vidc_msg_timing)
+					ddl_calc_core_proc_time(__func__,
+						DEC_OP_TIME);
+				if (ddl->codec_data.decoder.header_in_start)
+					ddl_vidc_decode_init_codec(ddl);
+				else {
+					ddl_context->ddl_callback(
+						VCD_EVT_RESP_START,
+						VCD_S_SUCCESS, NULL, 0,
+						(u32 *)ddl,
+						ddl->client_data);
+					ddl_release_command_channel(
+						ddl_context,
+						ddl->command_channel);
+					ret = true;
+				}
+			} else
+				ddl_vidc_encode_init_codec(ddl);
+		}
+	}
+	return ret;
+}
+
+static u32 ddl_encoder_seq_done_callback(struct ddl_context *ddl_context,
+	struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder;
+
+	DDL_MSG_HIGH("ddl_encoder_seq_done_callback");
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) {
+		DDL_MSG_ERROR("STATE-CRITICAL-INITCODEC");
+		ddl_client_fatal_cb(ddl);
+		return true;
+	}
+	if (vidc_msg_timing)
+		ddl_calc_core_proc_time(__func__, ENC_OP_TIME);
+	ddl->cmd_state = DDL_CMD_INVALID;
+	DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_FRAME",
+	ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME;
+	DDL_MSG_LOW("INIT_CODEC_DONE");
+	encoder = &ddl->codec_data.encoder;
+	vidc_1080p_get_encoder_sequence_header_size(
+		&encoder->seq_header_length);
+	if ((encoder->codec.codec == VCD_CODEC_H264) &&
+		(encoder->profile.profile == VCD_PROFILE_H264_BASELINE))
+		if ((encoder->seq_header.align_virtual_addr) &&
+			(encoder->seq_header_length > 6))
+			encoder->seq_header.align_virtual_addr[6] = 0xC0;
+	ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS,
+		NULL, 0, (u32 *) ddl, ddl->client_data);
+	ddl_release_command_channel(ddl_context,
+		ddl->command_channel);
+	return true;
+}
+
+static void parse_hdr_size_data(struct ddl_client_context *ddl,
+	struct vidc_1080p_seq_hdr_info *seq_hdr_info)
+{
+	u32 progressive;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) {
+		decoder->frame_size.width = seq_hdr_info->img_size_x;
+		decoder->frame_size.height = seq_hdr_info->img_size_y;
+		progressive = seq_hdr_info->disp_progressive;
+	} else {
+		vidc_sm_get_dec_order_resl(
+			&ddl->shared_mem[ddl->command_channel],
+			&decoder->frame_size.width,
+			&decoder->frame_size.height);
+		progressive = seq_hdr_info->dec_progressive;
+	}
+	decoder->min_dpb_num = seq_hdr_info->min_num_dpb;
+	vidc_sm_get_min_yc_dpb_sizes(
+		&ddl->shared_mem[ddl->command_channel],
+		&seq_hdr_info->min_luma_dpb_size,
+		&seq_hdr_info->min_chroma_dpb_size);
+	decoder->y_cb_cr_size = seq_hdr_info->min_luma_dpb_size +
+		seq_hdr_info->min_chroma_dpb_size;
+	decoder->dpb_buf_size.size_yuv = decoder->y_cb_cr_size;
+	decoder->dpb_buf_size.size_y =
+		seq_hdr_info->min_luma_dpb_size;
+	decoder->dpb_buf_size.size_c =
+		seq_hdr_info->min_chroma_dpb_size;
+	decoder->progressive_only = progressive ? false : true;
+}
+
+static void parse_hdr_crop_data(struct ddl_client_context *ddl,
+	struct vidc_1080p_seq_hdr_info *seq_hdr_info)
+{
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	u32 crop_exists = (decoder->output_order == VCD_DEC_ORDER_DISPLAY) ?
+		seq_hdr_info->disp_crop_exists : seq_hdr_info->dec_crop_exists;
+	if (crop_exists) {
+		if (decoder->output_order ==
+			VCD_DEC_ORDER_DISPLAY)
+			vidc_sm_get_crop_info(
+				&ddl->shared_mem[ddl->command_channel],
+				&seq_hdr_info->crop_left_offset,
+				&seq_hdr_info->crop_right_offset,
+				&seq_hdr_info->crop_top_offset,
+				&seq_hdr_info->crop_bottom_offset);
+		else
+			vidc_sm_get_dec_order_crop_info(
+				&ddl->shared_mem[ddl->command_channel],
+				&seq_hdr_info->crop_left_offset,
+				&seq_hdr_info->crop_right_offset,
+				&seq_hdr_info->crop_top_offset,
+				&seq_hdr_info->crop_bottom_offset);
+		decoder->frame_size.width -=
+			seq_hdr_info->crop_right_offset +
+			seq_hdr_info->crop_left_offset;
+		decoder->frame_size.height -=
+			seq_hdr_info->crop_top_offset +
+			seq_hdr_info->crop_bottom_offset;
+	}
+}
+
+static u32 ddl_decoder_seq_done_callback(struct ddl_context *ddl_context,
+	struct ddl_client_context *ddl)
+{
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	struct vidc_1080p_seq_hdr_info seq_hdr_info;
+	u32 process_further = true;
+	struct ddl_profile_info_type disp_profile_info;
+
+	DDL_MSG_MED("ddl_decoder_seq_done_callback");
+	if (!ddl->decoding ||
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) {
+		DDL_MSG_ERROR("STATE-CRITICAL-HDDONE");
+		ddl_client_fatal_cb(ddl);
+	} else {
+		if (vidc_msg_timing)
+			ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
+		ddl->cmd_state = DDL_CMD_INVALID;
+		DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+			"DDL_CLIENT_WAIT_FOR_DPB",
+			ddl_get_state_string(ddl->client_state));
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_DPB;
+		DDL_MSG_LOW("HEADER_DONE");
+		vidc_1080p_get_decode_seq_start_result(&seq_hdr_info);
+		parse_hdr_size_data(ddl, &seq_hdr_info);
+		if (res_trk_get_disable_fullhd() &&
+			(seq_hdr_info.img_size_x * seq_hdr_info.img_size_y >
+				1280 * 720)) {
+			DDL_MSG_ERROR("FATAL:Resolution greater than 720P HD");
+			ddl_client_fatal_cb(ddl);
+			return process_further;
+		}
+		if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) {
+			DDL_MSG_ERROR("FATAL:ZeroImageSize");
+			ddl_client_fatal_cb(ddl);
+			return process_further;
+		}
+		vidc_sm_get_profile_info(&ddl->shared_mem
+			[ddl->command_channel], &disp_profile_info);
+		disp_profile_info.pic_profile = seq_hdr_info.profile;
+		disp_profile_info.pic_level = seq_hdr_info.level;
+		ddl_get_dec_profile_level(decoder, seq_hdr_info.profile,
+			seq_hdr_info.level);
+		switch (decoder->codec.codec) {
+		case VCD_CODEC_H264:
+			if (decoder->profile.profile == VCD_PROFILE_H264_HIGH ||
+				decoder->profile.profile ==
+				VCD_PROFILE_UNKNOWN) {
+				if ((disp_profile_info.chroma_format_idc >
+					VIDC_1080P_IDCFORMAT_420) ||
+					(disp_profile_info.bit_depth_luma_minus8
+					 || disp_profile_info.
+					bit_depth_chroma_minus8)) {
+					DDL_MSG_ERROR("Unsupported H.264 "
+						"feature: IDC format : %d, Bitdepth: %d",
+						disp_profile_info.
+						chroma_format_idc,
+						(disp_profile_info.
+						 bit_depth_luma_minus8
+						 ||	disp_profile_info.
+					bit_depth_chroma_minus8));
+					ddl_client_fatal_cb(ddl);
+					return process_further;
+				}
+			}
+			break;
+		case VCD_CODEC_MPEG4:
+		case VCD_CODEC_DIVX_4:
+		case VCD_CODEC_DIVX_5:
+		case VCD_CODEC_DIVX_6:
+		case VCD_CODEC_XVID:
+			if (seq_hdr_info.data_partition)
+				if ((seq_hdr_info.img_size_x *
+				seq_hdr_info.img_size_y) > (720 * 576)) {
+					DDL_MSG_ERROR("Unsupported DP clip");
+					ddl_client_fatal_cb(ddl);
+					return process_further;
+				}
+			break;
+		default:
+			break;
+		}
+		ddl_calculate_stride(&decoder->frame_size,
+			!decoder->progressive_only);
+		decoder->frame_size.scan_lines =
+		DDL_ALIGN(decoder->frame_size.height, DDL_TILE_ALIGN_HEIGHT);
+		decoder->frame_size.stride =
+		DDL_ALIGN(decoder->frame_size.width, DDL_TILE_ALIGN_WIDTH);
+		parse_hdr_crop_data(ddl, &seq_hdr_info);
+		if (decoder->codec.codec == VCD_CODEC_H264 &&
+			seq_hdr_info.level > VIDC_1080P_H264_LEVEL4) {
+			DDL_MSG_ERROR("WARNING: H264MaxLevelExceeded : %d",
+				seq_hdr_info.level);
+		}
+		ddl_set_default_decoder_buffer_req(decoder, false);
+		if (decoder->header_in_start) {
+			if (!(decoder->cont_mode) ||
+				(decoder->min_dpb_num >
+				 decoder->client_output_buf_req.min_count) ||
+				(decoder->actual_output_buf_req.sz >
+				 decoder->client_output_buf_req.sz)) {
+				decoder->client_frame_size =
+					 decoder->frame_size;
+				decoder->client_output_buf_req =
+					decoder->actual_output_buf_req;
+				decoder->client_input_buf_req =
+					decoder->actual_input_buf_req;
+			}
+			ddl_context->ddl_callback(VCD_EVT_RESP_START,
+				VCD_S_SUCCESS, NULL, 0, (u32 *) ddl,
+				ddl->client_data);
+			ddl_release_command_channel(ddl_context,
+				ddl->command_channel);
+		} else {
+			u32 seq_hdr_only_frame = false;
+			u32 need_reconfig = false;
+			struct vcd_frame_data *input_vcd_frm =
+				&ddl->input_frame.vcd_frm;
+			need_reconfig = ddl_check_reconfig(ddl);
+			DDL_MSG_HIGH("%s : need_reconfig = %u\n", __func__,
+				 need_reconfig);
+			if (input_vcd_frm->flags &
+				  VCD_FRAME_FLAG_EOS) {
+				need_reconfig = false;
+			}
+			if (((input_vcd_frm->flags &
+				VCD_FRAME_FLAG_CODECCONFIG) &&
+				(!(input_vcd_frm->flags &
+				VCD_FRAME_FLAG_SYNCFRAME))) ||
+				input_vcd_frm->data_len <=
+				seq_hdr_info.dec_frm_size) {
+				seq_hdr_only_frame = true;
+				input_vcd_frm->offset +=
+					seq_hdr_info.dec_frm_size;
+				input_vcd_frm->data_len = 0;
+				input_vcd_frm->flags |=
+					VCD_FRAME_FLAG_CODECCONFIG;
+				ddl->input_frame.frm_trans_end =
+					!need_reconfig;
+				ddl_context->ddl_callback(
+					VCD_EVT_RESP_INPUT_DONE,
+					VCD_S_SUCCESS, &ddl->input_frame,
+					sizeof(struct ddl_frame_data_tag),
+					(u32 *) ddl, ddl->client_data);
+			} else {
+				if (decoder->codec.codec ==
+					VCD_CODEC_VC1_RCV) {
+					vidc_sm_set_start_byte_number(
+						&ddl->shared_mem
+						[ddl->command_channel],
+						seq_hdr_info.dec_frm_size);
+				}
+			}
+			if (need_reconfig) {
+				struct ddl_frame_data_tag *payload =
+					&ddl->input_frame;
+				u32 payload_size =
+					sizeof(struct ddl_frame_data_tag);
+				decoder->client_frame_size =
+					decoder->frame_size;
+				decoder->client_output_buf_req =
+					decoder->actual_output_buf_req;
+				decoder->client_input_buf_req =
+					decoder->actual_input_buf_req;
+				if (seq_hdr_only_frame) {
+					payload = NULL;
+					payload_size = 0;
+				}
+				DDL_MSG_HIGH("%s : sending port reconfig\n",
+					 __func__);
+				ddl_context->ddl_callback(
+					VCD_EVT_IND_OUTPUT_RECONFIG,
+					VCD_S_SUCCESS, payload,
+					payload_size, (u32 *) ddl,
+					ddl->client_data);
+			}
+			if (!need_reconfig && !seq_hdr_only_frame) {
+				if (!ddl_vidc_decode_set_buffers(ddl))
+					process_further = false;
+				else {
+					DDL_MSG_ERROR("ddl_vidc_decode_set_"
+						"buffers failed");
+					ddl_client_fatal_cb(ddl);
+				}
+			} else
+				ddl_release_command_channel(ddl_context,
+					ddl->command_channel);
+		}
+	}
+	return process_further;
+}
+
+static u32 ddl_sequence_done_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+	u32 channel_inst_id, ret;
+
+	vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+	vidc_1080p_clear_returned_channel_inst_id();
+	ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	if (!ddl) {
+		DDL_MSG_ERROR("UNKWN_SEQ_DONE");
+		ret = true;
+	} else {
+		if (ddl->decoding)
+			ret = ddl_decoder_seq_done_callback(ddl_context,
+					ddl);
+		else
+			ret = ddl_encoder_seq_done_callback(ddl_context,
+					ddl);
+	}
+	return ret;
+}
+
+static u32 ddl_dpb_buffers_set_done_callback(
+	struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+	u32 channel_inst_id, ret_status = true;
+
+	DDL_MSG_MED("ddl_dpb_buffers_set_done_callback");
+	vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+	vidc_1080p_clear_returned_channel_inst_id();
+	ddl = ddl_get_current_ddl_client_for_command(ddl_context,
+			DDL_CMD_DECODE_SET_DPB);
+	if (ddl) {
+		ddl->cmd_state = DDL_CMD_INVALID;
+		if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE)) {
+			DDL_MSG_ERROR("STATE-CRITICAL-DPBDONE");
+			ddl_client_fatal_cb(ddl);
+		} else {
+			DDL_MSG_LOW("INTR_DPBDONE");
+			DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+				"DDL_CLIENT_WAIT_FOR_FRAME",
+				ddl_get_state_string(ddl->client_state));
+			if (vidc_msg_timing) {
+				ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
+				ddl_reset_core_time_variables(DEC_OP_TIME);
+			}
+			ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME;
+			ddl_vidc_decode_frame_run(ddl);
+			ret_status = false;
+		}
+	}
+	return ret_status;
+}
+
+static void ddl_encoder_frame_run_callback(
+	struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data *encoder =
+		&(ddl->codec_data.encoder);
+	struct vcd_frame_data *output_frame =
+		&(ddl->output_frame.vcd_frm);
+	u32 eos_present = false;
+
+	DDL_MSG_MED("ddl_encoder_frame_run_callback\n");
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) &&
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
+		DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN");
+		ddl_client_fatal_cb(ddl);
+	} else {
+		if (vidc_msg_timing)
+			ddl_calc_core_proc_time(__func__, ENC_OP_TIME);
+		DDL_MSG_LOW("ENC_FRM_RUN_DONE");
+		ddl->cmd_state = DDL_CMD_INVALID;
+		vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info);
+
+		if (encoder->meta_data_enable_flag)
+			vidc_sm_get_metadata_status(&ddl->shared_mem
+				[ddl->command_channel],
+				&encoder->enc_frame_info.meta_data_exists);
+
+		if (VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags) {
+				DDL_MSG_LOW("%s EOS detected\n", __func__);
+				eos_present = true;
+		}
+
+		if (encoder->enc_frame_info.enc_frame_size ||
+			(encoder->enc_frame_info.enc_frame ==
+			VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
+			if (encoder->slice_delivery_info.enable) {
+				if (encoder->enc_frame_info.enc_frame ==
+					VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED)
+					ddl_handle_enc_skipframe_slice_mode(
+							ddl, eos_present);
+				else
+					ddl_handle_enc_frame_done_slice_mode(
+							ddl, eos_present);
+			} else {
+				ddl_handle_enc_frame_done(ddl, eos_present);
+			}
+			if (DDLCLIENT_STATE_IS(ddl,
+				DDL_CLIENT_WAIT_FOR_EOS_DONE) &&
+				encoder->i_period.b_frames) {
+				if ((ddl->extra_output_buf_count < 0) ||
+					(ddl->extra_output_buf_count >
+					encoder->i_period.b_frames)) {
+					DDL_MSG_ERROR("Invalid B frame output"
+								  "buffer index");
+				} else {
+					struct vidc_1080p_enc_frame_start_param
+						enc_param;
+					ddl->output_frame = ddl->\
+					extra_output_frame[ddl->\
+					extra_output_buf_count];
+					ddl->\
+					extra_output_buf_count--;
+					output_frame =
+					&ddl->output_frame.\
+					vcd_frm;
+					memset(&enc_param, 0,
+						sizeof(enc_param));
+					enc_param.cmd_seq_num =
+						++ddl_context->cmd_seq_num;
+					enc_param.inst_id = ddl->instance_id;
+					enc_param.shared_mem_addr_offset =
+					   DDL_ADDR_OFFSET(ddl_context->\
+						dram_base_a, ddl->shared_mem
+						[ddl->command_channel]);
+					enc_param.stream_buffer_addr_offset =
+						DDL_OFFSET(ddl_context->\
+						dram_base_a.\
+						align_physical_addr,
+						output_frame->physical);
+					enc_param.stream_buffer_size =
+					encoder->client_output_buf_req.sz;
+					enc_param.encode =
+					VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA;
+					ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
+					ddl_context->vidc_encode_frame_start
+						[ddl->command_channel]
+						(&enc_param);
+					}
+				} else if (eos_present &&
+					encoder->slice_delivery_info.enable) {
+					ddl_vidc_encode_eos_run(ddl);
+				} else {
+				DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+					"DDL_CLIENT_WAIT_FOR_FRAME",
+					ddl_get_state_string(
+					ddl->client_state));
+				ddl->client_state =
+					DDL_CLIENT_WAIT_FOR_FRAME;
+				ddl_release_command_channel(ddl_context,
+				ddl->command_channel);
+			}
+		} else {
+			ddl_context->ddl_callback(
+				VCD_EVT_RESP_TRANSACTION_PENDING,
+				VCD_S_SUCCESS, NULL, 0, (u32 *)ddl,
+				ddl->client_data);
+			DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+				"DDL_CLIENT_WAIT_FOR_FRAME",
+			ddl_get_state_string(ddl->client_state));
+			ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME;
+			ddl_release_command_channel(ddl_context,
+			ddl->command_channel);
+		}
+	}
+}
+
+static void get_dec_status(struct ddl_client_context *ddl,
+	 struct vidc_1080p_dec_disp_info *dec_disp_info,
+	 u32 output_order, u32 *status, u32 *rsl_chg)
+{
+	if (output_order == VCD_DEC_ORDER_DISPLAY) {
+		vidc_1080p_get_display_frame_result(dec_disp_info);
+		*status = dec_disp_info->display_status;
+		*rsl_chg = dec_disp_info->disp_resl_change;
+	} else {
+		vidc_1080p_get_decode_frame_result(dec_disp_info);
+		vidc_sm_get_dec_order_resl(
+			&ddl->shared_mem[ddl->command_channel],
+			&dec_disp_info->img_size_x,
+			&dec_disp_info->img_size_y);
+		*status = dec_disp_info->decode_status;
+		*rsl_chg = dec_disp_info->dec_resl_change;
+	}
+}
+
+static u32 ddl_decoder_frame_run_callback(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	u32 callback_end = false, ret_status = false;
+	u32 eos_present = false, rsl_chg;
+	u32 more_field_needed, extended_rsl_chg;
+	enum vidc_1080p_display_status disp_status;
+	DDL_MSG_MED("ddl_decoder_frame_run_callback");
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) {
+		DDL_MSG_ERROR("STATE-CRITICAL-DECFRMRUN");
+		ddl_client_fatal_cb(ddl);
+		ret_status = true;
+	} else {
+		DDL_MSG_LOW("DEC_FRM_RUN_DONE");
+		ddl->cmd_state = DDL_CMD_INVALID;
+		get_dec_status(ddl, &ddl->codec_data.decoder.dec_disp_info,
+			ddl->codec_data.decoder.output_order,
+			&disp_status, &rsl_chg);
+
+		vidc_sm_get_extended_decode_status(
+			&ddl->shared_mem[ddl->command_channel],
+			&more_field_needed,
+			&extended_rsl_chg);
+		decoder->field_needed_for_prev_ip =
+			more_field_needed;
+		decoder->prev_ip_frm_tag =
+			ddl->input_frame.vcd_frm.ip_frm_tag;
+
+		ddl_vidc_decode_dynamic_property(ddl, false);
+		if (rsl_chg != DDL_RESL_CHANGE_NO_CHANGE) {
+			ddl_handle_reconfig(rsl_chg, ddl);
+			ret_status = false;
+		} else {
+			if ((VCD_FRAME_FLAG_EOS &
+				ddl->input_frame.vcd_frm.flags)) {
+				callback_end = false;
+				eos_present = true;
+			}
+			if (disp_status ==
+				VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY ||
+				disp_status ==
+				VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY) {
+				if (!eos_present)
+					callback_end =
+					(disp_status ==
+					VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY);
+				ddl_decoder_input_done_callback(ddl,
+					callback_end);
+			}
+			if (disp_status ==
+				VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY ||
+				disp_status ==
+				VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) {
+				if (!eos_present)
+					callback_end = (disp_status ==
+				VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY);
+				if (ddl_decoder_output_done_callback(
+					ddl, callback_end))
+					ret_status = true;
+			}
+			if (!ret_status) {
+				if (disp_status ==
+					VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY
+					|| disp_status ==
+					VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY ||
+					disp_status ==
+					VIDC_1080P_DISPLAY_STATUS_NOOP) {
+					ddl_vidc_decode_frame_run(ddl);
+				} else if (eos_present)
+					ddl_vidc_decode_eos_run(ddl);
+				else {
+					ddl->client_state =
+						DDL_CLIENT_WAIT_FOR_FRAME;
+					ddl_release_command_channel(ddl_context,
+						ddl->command_channel);
+					ret_status = true;
+				}
+			}
+		}
+	}
+	return ret_status;
+}
+
+static u32 ddl_eos_frame_done_callback(
+	struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	struct ddl_mask *dpb_mask = &decoder->dpb_mask;
+	u32 ret_status = true, rsl_chg, more_field_needed;
+	enum vidc_1080p_display_status disp_status;
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
+		DDL_MSG_ERROR("STATE-CRITICAL-EOSFRMRUN");
+		ddl_client_fatal_cb(ddl);
+	} else {
+		DDL_MSG_LOW("EOS_FRM_RUN_DONE");
+		ddl->cmd_state = DDL_CMD_INVALID;
+		get_dec_status(ddl, &ddl->codec_data.decoder.dec_disp_info,
+			ddl->codec_data.decoder.output_order,
+			&disp_status, &rsl_chg);
+		vidc_sm_get_extended_decode_status(
+			&ddl->shared_mem[ddl->command_channel],
+			&more_field_needed, &rsl_chg);
+
+		decoder->field_needed_for_prev_ip =
+			more_field_needed;
+		decoder->prev_ip_frm_tag =
+			ddl->input_frame.vcd_frm.ip_frm_tag;
+		ddl_vidc_decode_dynamic_property(ddl, false);
+		if (disp_status ==
+			VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY) {
+			if (rsl_chg) {
+				decoder->header_in_start = false;
+				decoder->decode_config.sequence_header =
+					ddl->input_frame.vcd_frm.physical;
+				decoder->decode_config.sequence_header_len =
+					ddl->input_frame.vcd_frm.data_len;
+				decoder->reconfig_detected = false;
+				ddl_vidc_decode_init_codec(ddl);
+				ret_status = false;
+			} else
+				ddl_decoder_eos_done_callback(ddl);
+		} else {
+			struct vidc_1080p_dec_frame_start_param dec_param;
+			ret_status = false;
+			if (disp_status ==
+				VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) {
+				if (ddl_decoder_output_done_callback(
+					ddl, false))
+					ret_status = true;
+			} else if (disp_status !=
+				VIDC_1080P_DISPLAY_STATUS_NOOP)
+				DDL_MSG_ERROR("EOS-STATE-CRITICAL-"
+					"WRONG-DISP-STATUS");
+			if (!ret_status) {
+				ddl_decoder_dpb_transact(decoder, NULL,
+					DDL_DPB_OP_SET_MASK);
+				ddl->cmd_state = DDL_CMD_EOS;
+
+				memset(&dec_param, 0, sizeof(dec_param));
+
+				dec_param.cmd_seq_num =
+					++ddl_context->cmd_seq_num;
+				dec_param.inst_id = ddl->instance_id;
+				dec_param.shared_mem_addr_offset =
+					DDL_ADDR_OFFSET(
+					ddl_context->dram_base_a,
+					ddl->shared_mem[ddl->command_channel]);
+				dec_param.release_dpb_bit_mask =
+					dpb_mask->hw_mask;
+				dec_param.decode =
+					(decoder->reconfig_detected) ?\
+					VIDC_1080P_DEC_TYPE_FRAME_DATA :\
+					VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA;
+
+				ddl_context->vidc_decode_frame_start[ddl->\
+					command_channel](&dec_param);
+			}
+		}
+	}
+	return ret_status;
+}
+
+static u32 ddl_frame_run_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+	u32 channel_inst_id;
+	u32 return_status = true;
+
+	vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+	vidc_1080p_clear_returned_channel_inst_id();
+	ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	if (ddl) {
+		if (ddl_context->pix_cache_enable) {
+			struct vidc_1080P_pix_cache_statistics
+			pixel_cache_stats;
+			vidc_pix_cache_get_statistics(&pixel_cache_stats);
+
+			DDL_MSG_HIGH(" pixel cache hits = %d,"
+				"miss = %d", pixel_cache_stats.access_hit,
+				pixel_cache_stats.access_miss);
+			DDL_MSG_HIGH(" pixel cache core reqs = %d,"
+				"axi reqs = %d", pixel_cache_stats.core_req,
+				pixel_cache_stats.axi_req);
+			DDL_MSG_HIGH(" pixel cache core bus stats = %d,"
+			"axi bus stats = %d", pixel_cache_stats.core_bus,
+				pixel_cache_stats.axi_bus);
+		}
+
+		if (ddl->cmd_state == DDL_CMD_DECODE_FRAME)
+			return_status = ddl_decoder_frame_run_callback(ddl);
+		else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME)
+			ddl_encoder_frame_run_callback(ddl);
+		else if (ddl->cmd_state == DDL_CMD_EOS)
+			return_status = ddl_eos_frame_done_callback(ddl);
+		else {
+			DDL_MSG_ERROR("UNKWN_FRAME_DONE");
+			return_status = false;
+		}
+	} else
+		return_status = false;
+
+	return return_status;
+}
+
+static void ddl_channel_end_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+
+	DDL_MSG_MED("ddl_channel_end_callback");
+	ddl = ddl_get_current_ddl_client_for_command(ddl_context,
+			DDL_CMD_CHANNEL_END);
+	if (ddl) {
+		ddl->cmd_state = DDL_CMD_INVALID;
+		if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHEND)) {
+			DDL_MSG_LOW("STATE-CRITICAL-CHEND");
+		} else {
+			DDL_MSG_LOW("CH_END_DONE");
+			ddl_release_client_internal_buffers(ddl);
+			ddl_context->ddl_callback(VCD_EVT_RESP_STOP,
+				VCD_S_SUCCESS, NULL, 0, (u32 *)ddl,
+				ddl->client_data);
+			DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+				"DDL_CLIENT_OPEN",
+				ddl_get_state_string(ddl->client_state));
+			ddl->client_state = DDL_CLIENT_OPEN;
+		}
+		ddl_release_command_channel(ddl_context,
+			ddl->command_channel);
+	}
+}
+
+static void ddl_edfu_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+	u32 channel_inst_id;
+
+	DDL_MSG_MED("ddl_edfu_callback");
+	vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+	vidc_1080p_clear_returned_channel_inst_id();
+	ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	if (ddl) {
+		if (ddl->cmd_state != DDL_CMD_ENCODE_FRAME)
+			DDL_MSG_LOW("UNKWN_EDFU");
+	}
+}
+
+static void ddl_encoder_eos_done(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+	u32 channel_inst_id;
+
+	vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+	vidc_1080p_clear_returned_channel_inst_id();
+	ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	DDL_MSG_LOW("ddl_encoder_eos_done\n");
+	if (ddl == NULL) {
+		DDL_MSG_ERROR("NO_DDL_CONTEXT");
+	} else {
+		if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
+			DDL_MSG_ERROR("STATE-CRITICAL-EOSFRMDONE");
+			ddl_client_fatal_cb(ddl);
+		} else {
+			struct ddl_encoder_data *encoder =
+				&(ddl->codec_data.encoder);
+			vidc_1080p_get_encode_frame_info(
+				&encoder->enc_frame_info);
+			if (!encoder->slice_delivery_info.enable) {
+				ddl_handle_enc_frame_done(ddl, true);
+				ddl->cmd_state = DDL_CMD_INVALID;
+			}
+			DDL_MSG_LOW("encoder_eos_done");
+			DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+				"DDL_CLIENT_WAIT_FOR_FRAME",
+				ddl_get_state_string(ddl->client_state));
+			ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME;
+			DDL_MSG_LOW("eos_done");
+			ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE,
+					VCD_S_SUCCESS, NULL, 0,
+					(u32 *)ddl, ddl->client_data);
+			ddl_release_command_channel(ddl_context,
+				ddl->command_channel);
+		}
+	}
+}
+
+static u32 ddl_slice_done_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+	u32 channel_inst_id;
+	u32 return_status = true;
+	DDL_MSG_LOW("ddl_sliceDoneCallback");
+	vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+	vidc_1080p_clear_returned_channel_inst_id();
+	ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	if (ddl == NULL) {
+		DDL_MSG_ERROR("NO_DDL_CONTEXT");
+		return_status = false;
+	} else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME) {
+			ddl->cmd_state = DDL_CMD_INVALID;
+			if (DDLCLIENT_STATE_IS(ddl,
+				DDL_CLIENT_WAIT_FOR_FRAME_DONE)) {
+				ddl_handle_slice_done_slice_batch(ddl);
+			} else {
+				DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN : %s\n",
+					 __func__);
+				ddl_client_fatal_cb(ddl);
+			}
+	} else {
+		DDL_MSG_ERROR("UNKNOWN_SLICEDONE : %s\n", __func__);
+	}
+	return return_status;
+}
+
+static u32 ddl_process_intr_status(struct ddl_context *ddl_context,
+	u32 intr_status)
+{
+	u32 return_status = true;
+	switch (intr_status) {
+	case VIDC_1080P_RISC2HOST_CMD_OPEN_CH_RET:
+		return_status = ddl_channel_set_callback(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_CLOSE_CH_RET:
+		ddl_channel_end_callback(ddl_context);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_SEQ_DONE_RET:
+		return_status = ddl_sequence_done_callback(ddl_context);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET:
+		return_status = ddl_frame_run_callback(ddl_context);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET:
+		 ddl_slice_done_callback(ddl_context);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_SYS_INIT_RET:
+		ddl_sys_init_done_callback(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_FW_STATUS_RET:
+		ddl_fw_status_done_callback(ddl_context);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_EDFU_INT_RET:
+		ddl_edfu_callback(ddl_context);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_ENC_COMPLETE_RET:
+		ddl_encoder_eos_done(ddl_context);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_ERROR_RET:
+		DDL_MSG_ERROR("CMD_ERROR_INTR");
+		return_status = ddl_handle_core_errors(ddl_context);
+	break;
+	case VIDC_1080P_RISC2HOST_CMD_INIT_BUFFERS_RET:
+		return_status =
+			ddl_dpb_buffers_set_done_callback(ddl_context);
+	break;
+	default:
+		DDL_MSG_LOW("UNKWN_INTR");
+	break;
+	}
+	return return_status;
+}
+
+void ddl_read_and_clear_interrupt(void)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_hw_interface  *ddl_hw_response;
+	struct ddl_client_context *ddl;
+	struct ddl_encoder_data *encoder;
+
+	ddl_context = ddl_get_context();
+	if (!ddl_context->core_virtual_base_addr) {
+		DDL_MSG_LOW("SPURIOUS_INTERRUPT");
+	} else {
+		ddl_hw_response = &ddl_context->ddl_hw_response;
+		vidc_1080p_get_risc2host_cmd(&ddl_hw_response->cmd,
+			&ddl_hw_response->arg1, &ddl_hw_response->arg2,
+			&ddl_hw_response->arg3,
+			&ddl_hw_response->arg4);
+		DDL_MSG_LOW("%s vidc_1080p_get_risc2host_cmd cmd = %u"
+			"arg1 = %u arg2 = %u arg3 = %u"
+			"arg4 = %u\n",
+			__func__, ddl_hw_response->cmd,
+			ddl_hw_response->arg1, ddl_hw_response->arg2,
+			ddl_hw_response->arg3,
+			ddl_hw_response->arg4);
+		ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+		if (ddl) {
+			encoder = &(ddl->codec_data.encoder);
+			if (encoder && encoder->slice_delivery_info.enable
+			&&
+			((ddl_hw_response->cmd ==
+				VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET)
+			|| (ddl_hw_response->cmd ==
+				VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET))) {
+				vidc_sm_set_encoder_slice_batch_int_ctrl(
+				&ddl->shared_mem[ddl->command_channel],
+				1);
+			}
+		}
+		vidc_1080p_clear_risc2host_cmd();
+		vidc_1080p_clear_interrupt();
+		vidc_1080p_get_risc2host_cmd_status(ddl_hw_response->arg2,
+			&ddl_context->cmd_err_status,
+			&ddl_context->disp_pic_err_status);
+		DDL_MSG_LOW("%s cmd_err_status = %d\n", __func__,
+				ddl_context->cmd_err_status);
+		ddl_context->response_cmd_ch_id = ddl_hw_response->arg1;
+	}
+}
+
+u32 ddl_process_core_response(void)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_hw_interface *ddl_hw_response;
+	u32 status = false;
+
+	ddl_context = ddl_get_context();
+	if (!ddl_context->core_virtual_base_addr) {
+		DDL_MSG_LOW("SPURIOUS_INTERRUPT");
+		return status;
+	}
+	ddl_hw_response = &ddl_context->ddl_hw_response;
+	status = ddl_process_intr_status(ddl_context, ddl_hw_response->cmd);
+	if (ddl_context->interrupt_clr)
+		(*ddl_context->interrupt_clr)();
+	return status;
+}
+
+static void ddl_decoder_input_done_callback(
+	struct ddl_client_context *ddl, u32 frame_transact_end)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vidc_1080p_dec_disp_info *dec_disp_info =
+		&decoder->dec_disp_info;
+	struct vcd_frame_data *input_vcd_frm = &(ddl->input_frame.vcd_frm);
+	u32 is_interlaced;
+	vidc_1080p_get_decoded_frame_size(
+		&dec_disp_info->input_bytes_consumed);
+	vidc_sm_set_start_byte_number(&ddl->shared_mem
+		[ddl->command_channel], 0);
+	vidc_1080p_get_decode_frame(&dec_disp_info->input_frame);
+	ddl_get_decoded_frame(input_vcd_frm,
+		dec_disp_info->input_frame);
+	vidc_1080p_get_decode_frame_result(dec_disp_info);
+	is_interlaced = (dec_disp_info->decode_coding ==
+		VIDC_1080P_DISPLAY_CODING_INTERLACED);
+	if (decoder->output_order == VCD_DEC_ORDER_DECODE) {
+		dec_disp_info->tag_bottom = is_interlaced ?
+			dec_disp_info->tag_top :
+			VCD_FRAMETAG_INVALID;
+		dec_disp_info->tag_top = input_vcd_frm->ip_frm_tag;
+	}
+	input_vcd_frm->interlaced = is_interlaced;
+	input_vcd_frm->offset += dec_disp_info->input_bytes_consumed;
+	input_vcd_frm->data_len -= dec_disp_info->input_bytes_consumed;
+	ddl->input_frame.frm_trans_end = frame_transact_end;
+	if (vidc_msg_timing)
+		ddl_calc_core_proc_time(__func__, DEC_IP_TIME);
+	ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS,
+		&ddl->input_frame, sizeof(struct ddl_frame_data_tag),
+		(u32 *)ddl, ddl->client_data);
+}
+
+static void get_dec_op_done_data(struct vidc_1080p_dec_disp_info *dec_disp_info,
+	u32 output_order, u8 **physical, u32 *is_interlaced)
+{
+	enum vidc_1080p_display_coding disp_coding;
+	if (output_order == VCD_DEC_ORDER_DECODE) {
+		*physical = (u8 *)(dec_disp_info->decode_y_addr << 11);
+		disp_coding = dec_disp_info->decode_coding;
+	} else {
+		*physical = (u8 *)(dec_disp_info->display_y_addr << 11);
+		disp_coding = dec_disp_info->display_coding;
+	}
+	*is_interlaced = (disp_coding ==
+			VIDC_1080P_DISPLAY_CODING_INTERLACED);
+}
+
+static void get_dec_op_done_crop(u32 output_order,
+	struct vidc_1080p_dec_disp_info *dec_disp_info,
+	struct vcd_frame_rect *crop_data,
+	struct vcd_property_frame_size *op_frame_sz,
+	struct vcd_property_frame_size *frame_sz,
+	struct ddl_buf_addr *shared_mem)
+{
+	u32 crop_exists =
+		(output_order == VCD_DEC_ORDER_DECODE) ?
+		dec_disp_info->dec_crop_exists :
+		dec_disp_info->disp_crop_exists;
+	crop_data->left = 0;
+	crop_data->top = 0;
+	crop_data->right = dec_disp_info->img_size_x;
+	crop_data->bottom = dec_disp_info->img_size_y;
+	op_frame_sz->width = dec_disp_info->img_size_x;
+	op_frame_sz->height = dec_disp_info->img_size_y;
+	ddl_calculate_stride(op_frame_sz, false);
+	op_frame_sz->stride = DDL_ALIGN(op_frame_sz->width,
+				DDL_TILE_ALIGN_WIDTH);
+	op_frame_sz->scan_lines = DDL_ALIGN(op_frame_sz->height,
+					DDL_TILE_ALIGN_HEIGHT);
+	DDL_MSG_LOW("%s img_size_x = %u img_size_y = %u\n",
+				__func__, dec_disp_info->img_size_x,
+				dec_disp_info->img_size_y);
+	if (crop_exists) {
+		if (output_order == VCD_DEC_ORDER_DECODE)
+			vidc_sm_get_dec_order_crop_info(shared_mem,
+				&dec_disp_info->crop_left_offset,
+				&dec_disp_info->crop_right_offset,
+				&dec_disp_info->crop_top_offset,
+				&dec_disp_info->crop_bottom_offset);
+		else
+			vidc_sm_get_crop_info(shared_mem,
+				&dec_disp_info->crop_left_offset,
+				&dec_disp_info->crop_right_offset,
+				&dec_disp_info->crop_top_offset,
+				&dec_disp_info->crop_bottom_offset);
+		crop_data->left = dec_disp_info->crop_left_offset;
+		crop_data->top = dec_disp_info->crop_top_offset;
+		crop_data->right -= dec_disp_info->crop_right_offset;
+		crop_data->bottom -= dec_disp_info->crop_bottom_offset;
+		op_frame_sz->width = crop_data->right - crop_data->left;
+		op_frame_sz->height = crop_data->bottom - crop_data->top;
+	}
+}
+
+static u32 ddl_decoder_output_done_callback(
+	struct ddl_client_context *ddl, u32 frame_transact_end)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vidc_1080p_dec_disp_info *dec_disp_info =
+		&(decoder->dec_disp_info);
+	struct ddl_frame_data_tag *output_frame = &(ddl->output_frame);
+	struct vcd_frame_data *output_vcd_frm = &(output_frame->vcd_frm);
+	u32 vcd_status, free_luma_dpb = 0, disp_pict = 0, is_interlaced;
+	get_dec_op_done_data(dec_disp_info, decoder->output_order,
+		&output_vcd_frm->physical, &is_interlaced);
+	decoder->progressive_only = !(is_interlaced);
+	output_vcd_frm->frame = VCD_FRAME_YUV;
+	if (decoder->codec.codec == VCD_CODEC_MPEG4 ||
+		decoder->codec.codec == VCD_CODEC_VC1 ||
+		decoder->codec.codec == VCD_CODEC_VC1_RCV ||
+		(decoder->codec.codec >= VCD_CODEC_DIVX_3 &&
+		decoder->codec.codec <= VCD_CODEC_XVID)) {
+		vidc_sm_get_displayed_picture_frame(&ddl->shared_mem
+		[ddl->command_channel], &disp_pict);
+		if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) {
+			if (!disp_pict) {
+				output_vcd_frm->frame = VCD_FRAME_NOTCODED;
+				vidc_sm_get_available_luma_dpb_address(
+					&ddl->shared_mem[ddl->command_channel],
+					&free_luma_dpb);
+			}
+		} else {
+			if (dec_disp_info->input_frame ==
+				VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED) {
+				output_vcd_frm->frame = VCD_FRAME_NOTCODED;
+			vidc_sm_get_available_luma_dpb_dec_order_address(
+					&ddl->shared_mem[ddl->command_channel],
+					&free_luma_dpb);
+			}
+		}
+		if (free_luma_dpb)
+			output_vcd_frm->physical =
+				(u8 *)(free_luma_dpb << 11);
+	}
+	vcd_status = ddl_decoder_dpb_transact(decoder, output_frame,
+			DDL_DPB_OP_MARK_BUSY);
+	if (vcd_status) {
+		DDL_MSG_ERROR("CORRUPTED_OUTPUT_BUFFER_ADDRESS");
+		ddl_hw_fatal_cb(ddl);
+	} else {
+		vidc_sm_get_metadata_status(&ddl->shared_mem
+			[ddl->command_channel],
+			&decoder->meta_data_exists);
+		if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) {
+			vidc_sm_get_frame_tags(&ddl->shared_mem
+				[ddl->command_channel],
+				&dec_disp_info->tag_top,
+				&dec_disp_info->tag_bottom);
+			if (dec_disp_info->display_correct ==
+				VIDC_1080P_DECODE_NOT_CORRECT ||
+				dec_disp_info->display_correct ==
+				VIDC_1080P_DECODE_APPROX_CORRECT)
+				output_vcd_frm->flags |=
+					VCD_FRAME_FLAG_DATACORRUPT;
+		} else {
+			if (dec_disp_info->decode_correct ==
+				VIDC_1080P_DECODE_NOT_CORRECT ||
+				dec_disp_info->decode_correct ==
+				VIDC_1080P_DECODE_APPROX_CORRECT)
+				output_vcd_frm->flags |=
+					VCD_FRAME_FLAG_DATACORRUPT;
+		}
+		output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top;
+		vidc_sm_get_picture_times(&ddl->shared_mem
+			[ddl->command_channel],
+			&dec_disp_info->pic_time_top,
+			&dec_disp_info->pic_time_bottom);
+		get_dec_op_done_crop(decoder->output_order, dec_disp_info,
+			&output_vcd_frm->dec_op_prop.disp_frm,
+			&output_vcd_frm->dec_op_prop.frm_size,
+			&decoder->frame_size,
+			&ddl->shared_mem[ddl_context->response_cmd_ch_id]);
+		if ((decoder->cont_mode) &&
+			((output_vcd_frm->dec_op_prop.frm_size.width !=
+			decoder->frame_size.width) ||
+			(output_vcd_frm->dec_op_prop.frm_size.height !=
+			decoder->frame_size.height) ||
+			(decoder->frame_size.width !=
+			decoder->client_frame_size.width) ||
+			(decoder->frame_size.height !=
+			decoder->client_frame_size.height))) {
+			DDL_MSG_LOW("%s o/p width = %u o/p height = %u"
+				"decoder width = %u decoder height = %u ",
+				__func__,
+				output_vcd_frm->dec_op_prop.frm_size.width,
+				output_vcd_frm->dec_op_prop.frm_size.height,
+				decoder->frame_size.width,
+				decoder->frame_size.height);
+			DDL_MSG_HIGH("%s Sending INFO_OP_RECONFIG event\n",
+				 __func__);
+			ddl_context->ddl_callback(
+				VCD_EVT_IND_INFO_OUTPUT_RECONFIG,
+				VCD_S_SUCCESS, NULL, 0,
+				(u32 *)ddl,
+				ddl->client_data);
+			decoder->frame_size =
+				 output_vcd_frm->dec_op_prop.frm_size;
+			decoder->client_frame_size = decoder->frame_size;
+			decoder->y_cb_cr_size =
+				ddl_get_yuv_buffer_size(&decoder->frame_size,
+					&decoder->buf_format,
+					(!decoder->progressive_only),
+					decoder->codec.codec, NULL);
+			decoder->actual_output_buf_req.sz =
+				decoder->y_cb_cr_size + decoder->suffix;
+			decoder->min_output_buf_req =
+				decoder->actual_output_buf_req;
+			DDL_MSG_LOW("%s y_cb_cr_size = %u "
+				"actual_output_buf_req.sz = %u"
+				"min_output_buf_req.sz = %u\n",
+				decoder->y_cb_cr_size,
+				decoder->actual_output_buf_req.sz,
+				decoder->min_output_buf_req.sz);
+			vidc_sm_set_chroma_addr_change(
+			&ddl->shared_mem[ddl->command_channel],
+			false);
+		}
+		output_vcd_frm->interlaced = is_interlaced;
+		output_vcd_frm->intrlcd_ip_frm_tag =
+			(!is_interlaced || !dec_disp_info->tag_bottom) ?
+			VCD_FRAMETAG_INVALID : dec_disp_info->tag_bottom;
+		output_vcd_frm->offset = 0;
+		output_vcd_frm->data_len = decoder->y_cb_cr_size;
+		if (free_luma_dpb) {
+			output_vcd_frm->data_len = 0;
+			output_vcd_frm->flags |= VCD_FRAME_FLAG_DECODEONLY;
+		}
+		output_vcd_frm->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
+		output_frame->frm_trans_end = frame_transact_end;
+		if (vidc_msg_timing)
+			ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
+		ddl_process_decoder_metadata(ddl);
+		vidc_sm_get_aspect_ratio_info(
+			&ddl->shared_mem[ddl->command_channel],
+			&output_vcd_frm->aspect_ratio_info);
+		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+			vcd_status, output_frame,
+			sizeof(struct ddl_frame_data_tag),
+			(u32 *)ddl, ddl->client_data);
+	}
+	return vcd_status;
+}
+
+static u32 ddl_get_decoded_frame(struct vcd_frame_data  *frame,
+	enum vidc_1080p_decode_frame frame_type)
+{
+	u32 status = true;
+
+	switch (frame_type) {
+	case VIDC_1080P_DECODE_FRAMETYPE_I:
+		frame->flags |= VCD_FRAME_FLAG_SYNCFRAME;
+		frame->frame = VCD_FRAME_I;
+	break;
+	case VIDC_1080P_DECODE_FRAMETYPE_P:
+		frame->frame = VCD_FRAME_P;
+	break;
+	case VIDC_1080P_DECODE_FRAMETYPE_B:
+		frame->frame = VCD_FRAME_B;
+	break;
+	case VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED:
+		frame->frame = VCD_FRAME_NOTCODED;
+		frame->data_len = 0;
+		DDL_MSG_HIGH("DDL_INFO:Decoder:NotCodedFrame>");
+	break;
+	case VIDC_1080P_DECODE_FRAMETYPE_OTHERS:
+		frame->frame = VCD_FRAME_YUV;
+	break;
+	case VIDC_1080P_DECODE_FRAMETYPE_32BIT:
+	default:
+		DDL_MSG_ERROR("UNKNOWN-FRAMETYPE");
+		status = false;
+	break;
+	}
+	return status;
+}
+
+static u32 ddl_get_encoded_frame(struct vcd_frame_data *frame,
+	enum vcd_codec codec,
+	enum vidc_1080p_encode_frame frame_type)
+{
+	u32 status = true;
+
+	if (codec == VCD_CODEC_H264) {
+		switch (frame_type) {
+		case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED:
+			frame->frame = VCD_FRAME_P;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_I:
+			frame->flags |= VCD_FRAME_FLAG_SYNCFRAME;
+			frame->frame = VCD_FRAME_I;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_P:
+			frame->frame = VCD_FRAME_P;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_B:
+			frame->frame = VCD_FRAME_B;
+			frame->flags |= VCD_FRAME_FLAG_BFRAME;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED:
+			frame->frame = VCD_FRAME_NOTCODED;
+			frame->data_len = 0;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS:
+			DDL_MSG_LOW("FRAMETYPE-OTHERS");
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_32BIT:
+		default:
+			DDL_MSG_LOW("UNKNOWN-FRAMETYPE");
+			status = false;
+		break;
+		}
+	} else if (codec == VCD_CODEC_MPEG4) {
+		switch (frame_type) {
+		case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED:
+			frame->frame = VCD_FRAME_P;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_I:
+			frame->flags |= VCD_FRAME_FLAG_SYNCFRAME;
+			frame->frame = VCD_FRAME_I;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_P:
+			frame->frame = VCD_FRAME_P;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_B:
+			frame->frame = VCD_FRAME_B;
+			frame->flags |= VCD_FRAME_FLAG_BFRAME;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED:
+			frame->frame = VCD_FRAME_NOTCODED;
+			frame->data_len = 0;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS:
+			DDL_MSG_LOW("FRAMETYPE-OTHERS");
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_32BIT:
+		default:
+			DDL_MSG_LOW("UNKNOWN-FRAMETYPE");
+			status = false;
+		break;
+		}
+	} else if (codec == VCD_CODEC_H263) {
+		switch (frame_type) {
+		case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED:
+			frame->frame = VCD_FRAME_P;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_I:
+			frame->flags |= VCD_FRAME_FLAG_SYNCFRAME;
+			frame->frame = VCD_FRAME_I;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_P:
+			frame->frame = VCD_FRAME_P;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED:
+			frame->frame = VCD_FRAME_NOTCODED;
+			frame->data_len = 0;
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS:
+			DDL_MSG_LOW("FRAMETYPE-OTHERS");
+		break;
+		case VIDC_1080P_ENCODE_FRAMETYPE_32BIT:
+		default:
+			DDL_MSG_LOW("UNKNOWN-FRAMETYPE");
+			status = false;
+		break;
+		}
+	} else
+		status = false;
+	DDL_MSG_HIGH("Enc Frame Type %u", (u32)frame->frame);
+	return status;
+}
+
+static void ddl_get_mpeg4_dec_level(enum vcd_codec_level *level,
+	u32 level_codec, enum vcd_codec_profile mpeg4_profile)
+{
+	switch (level_codec) {
+	case VIDC_1080P_MPEG4_LEVEL0:
+		*level = VCD_LEVEL_MPEG4_0;
+	break;
+	case VIDC_1080P_MPEG4_LEVEL0b:
+		*level = VCD_LEVEL_MPEG4_0b;
+	break;
+	case VIDC_1080P_MPEG4_LEVEL1:
+		*level = VCD_LEVEL_MPEG4_1;
+	break;
+	case VIDC_1080P_MPEG4_LEVEL2:
+		*level = VCD_LEVEL_MPEG4_2;
+	break;
+	case VIDC_1080P_MPEG4_LEVEL3:
+		*level = VCD_LEVEL_MPEG4_3;
+	break;
+	case VIDC_1080P_MPEG4_LEVEL3b:
+		if (mpeg4_profile == VCD_PROFILE_MPEG4_SP)
+			*level = VCD_LEVEL_MPEG4_7;
+		else
+			*level = VCD_LEVEL_MPEG4_3b;
+	break;
+	case VIDC_1080P_MPEG4_LEVEL4a:
+		*level = VCD_LEVEL_MPEG4_4a;
+	break;
+	case VIDC_1080P_MPEG4_LEVEL5:
+		*level = VCD_LEVEL_MPEG4_5;
+	break;
+	case VIDC_1080P_MPEG4_LEVEL6:
+		*level = VCD_LEVEL_MPEG4_6;
+	break;
+	default:
+		*level = VCD_LEVEL_UNKNOWN;
+	break;
+	}
+}
+
+static void ddl_get_h264_dec_level(enum vcd_codec_level *level,
+	u32 level_codec)
+{
+	switch (level_codec) {
+	case VIDC_1080P_H264_LEVEL1:
+		*level = VCD_LEVEL_H264_1;
+	break;
+	case VIDC_1080P_H264_LEVEL1b:
+		*level = VCD_LEVEL_H264_1b;
+	break;
+	case VIDC_1080P_H264_LEVEL1p1:
+		*level = VCD_LEVEL_H264_1p1;
+	break;
+	case VIDC_1080P_H264_LEVEL1p2:
+		*level = VCD_LEVEL_H264_1p2;
+	break;
+	case VIDC_1080P_H264_LEVEL1p3:
+		*level = VCD_LEVEL_H264_1p3;
+	break;
+	case VIDC_1080P_H264_LEVEL2:
+		*level = VCD_LEVEL_H264_2;
+	break;
+	case VIDC_1080P_H264_LEVEL2p1:
+		*level = VCD_LEVEL_H264_2p1;
+	break;
+	case VIDC_1080P_H264_LEVEL2p2:
+		*level = VCD_LEVEL_H264_2p2;
+	break;
+	case VIDC_1080P_H264_LEVEL3:
+		*level = VCD_LEVEL_H264_3;
+	break;
+	case VIDC_1080P_H264_LEVEL3p1:
+		*level = VCD_LEVEL_H264_3p1;
+	break;
+	case VIDC_1080P_H264_LEVEL3p2:
+		*level = VCD_LEVEL_H264_3p2;
+	break;
+	case VIDC_1080P_H264_LEVEL4:
+		*level = VCD_LEVEL_H264_4;
+	break;
+	default:
+		*level = VCD_LEVEL_UNKNOWN;
+	break;
+	}
+}
+
+static void ddl_get_h263_dec_level(enum vcd_codec_level *level,
+	u32 level_codec)
+{
+	switch (level_codec) {
+	case VIDC_1080P_H263_LEVEL10:
+		*level = VCD_LEVEL_H263_10;
+	break;
+	case VIDC_1080P_H263_LEVEL20:
+		*level = VCD_LEVEL_H263_20;
+	break;
+	case VIDC_1080P_H263_LEVEL30:
+		*level = VCD_LEVEL_H263_30;
+	break;
+	case VIDC_1080P_H263_LEVEL40:
+		*level = VCD_LEVEL_H263_40;
+	break;
+	case VIDC_1080P_H263_LEVEL45:
+		*level = VCD_LEVEL_H263_45;
+	break;
+	case VIDC_1080P_H263_LEVEL50:
+		*level = VCD_LEVEL_H263_50;
+	break;
+	case VIDC_1080P_H263_LEVEL60:
+		*level = VCD_LEVEL_H263_60;
+	break;
+	case VIDC_1080P_H263_LEVEL70:
+		*level = VCD_LEVEL_H263_70;
+	break;
+	default:
+		*level = VCD_LEVEL_UNKNOWN;
+	break;
+	}
+}
+
+static void ddl_get_vc1_dec_level(enum vcd_codec_level *level,
+	u32 level_codec, enum vcd_codec_profile vc1_profile)
+{
+	if (vc1_profile == VCD_PROFILE_VC1_ADVANCE) {
+		switch (level_codec) {
+		case VIDC_SM_LEVEL_VC1_ADV_0:
+			*level = VCD_LEVEL_VC1_A_0;
+		break;
+		case VIDC_SM_LEVEL_VC1_ADV_1:
+			*level = VCD_LEVEL_VC1_A_1;
+		break;
+		case VIDC_SM_LEVEL_VC1_ADV_2:
+			*level = VCD_LEVEL_VC1_A_2;
+		break;
+		case VIDC_SM_LEVEL_VC1_ADV_3:
+			*level = VCD_LEVEL_VC1_A_3;
+		break;
+		case VIDC_SM_LEVEL_VC1_ADV_4:
+			*level = VCD_LEVEL_VC1_A_4;
+		break;
+		default:
+			*level = VCD_LEVEL_UNKNOWN;
+		break;
+		}
+	} else if (vc1_profile == VCD_PROFILE_VC1_MAIN) {
+		switch (level_codec) {
+		case VIDC_SM_LEVEL_VC1_LOW:
+			*level = VCD_LEVEL_VC1_M_LOW;
+		break;
+		case VIDC_SM_LEVEL_VC1_MEDIUM:
+			*level = VCD_LEVEL_VC1_M_MEDIUM;
+		break;
+		case VIDC_SM_LEVEL_VC1_HIGH:
+			*level = VCD_LEVEL_VC1_M_HIGH;
+		break;
+		default:
+			*level = VCD_LEVEL_UNKNOWN;
+		break;
+		}
+	} else if (vc1_profile == VCD_PROFILE_VC1_SIMPLE) {
+		switch (level_codec) {
+		case VIDC_SM_LEVEL_VC1_LOW:
+			*level = VCD_LEVEL_VC1_S_LOW;
+		break;
+		case VIDC_SM_LEVEL_VC1_MEDIUM:
+			*level = VCD_LEVEL_VC1_S_MEDIUM;
+		break;
+		default:
+			*level = VCD_LEVEL_UNKNOWN;
+		break;
+		}
+	}
+}
+
+static void ddl_get_mpeg2_dec_level(enum vcd_codec_level *level,
+	u32 level_codec)
+{
+	switch (level_codec) {
+	case VIDC_SM_LEVEL_MPEG2_LOW:
+		*level = VCD_LEVEL_MPEG2_LOW;
+	break;
+	case VIDC_SM_LEVEL_MPEG2_MAIN:
+		*level = VCD_LEVEL_MPEG2_MAIN;
+	break;
+	case VIDC_SM_LEVEL_MPEG2_HIGH_1440:
+		*level = VCD_LEVEL_MPEG2_HIGH_14;
+	break;
+	case VIDC_SM_LEVEL_MPEG2_HIGH:
+		*level = VCD_LEVEL_MPEG2_HIGH;
+	break;
+	default:
+		*level = VCD_LEVEL_UNKNOWN;
+	break;
+	}
+}
+
+static void ddl_get_dec_profile_level(struct ddl_decoder_data *decoder,
+	u32 profile_codec, u32 level_codec)
+{
+	enum vcd_codec_profile profile = VCD_PROFILE_UNKNOWN;
+	enum vcd_codec_level level = VCD_LEVEL_UNKNOWN;
+
+	switch (decoder->codec.codec) {
+	case VCD_CODEC_MPEG4:
+	case VCD_CODEC_XVID:
+		if (profile_codec == VIDC_SM_PROFILE_MPEG4_SIMPLE)
+			profile = VCD_PROFILE_MPEG4_SP;
+		else if (profile_codec == VIDC_SM_PROFILE_MPEG4_ADV_SIMPLE)
+			profile = VCD_PROFILE_MPEG4_ASP;
+		else
+			profile = VCD_PROFILE_UNKNOWN;
+		ddl_get_mpeg4_dec_level(&level, level_codec, profile);
+	break;
+	case VCD_CODEC_H264:
+		if (profile_codec == VIDC_SM_PROFILE_H264_BASELINE)
+			profile = VCD_PROFILE_H264_BASELINE;
+		else if (profile_codec == VIDC_SM_PROFILE_H264_MAIN)
+			profile = VCD_PROFILE_H264_MAIN;
+		else if (profile_codec == VIDC_SM_PROFILE_H264_HIGH)
+			profile = VCD_PROFILE_H264_HIGH;
+		else
+			profile = VCD_PROFILE_UNKNOWN;
+		ddl_get_h264_dec_level(&level, level_codec);
+	break;
+	case VCD_CODEC_H263:
+		if (profile_codec == VIDC_SM_PROFILE_H263_BASELINE)
+			profile = VCD_PROFILE_H263_BASELINE;
+		else
+			profile = VCD_PROFILE_UNKNOWN;
+		ddl_get_h263_dec_level(&level, level_codec);
+	break;
+	case VCD_CODEC_MPEG2:
+		if (profile_codec == VIDC_SM_PROFILE_MPEG2_MAIN)
+			profile = VCD_PROFILE_MPEG2_MAIN;
+		else if (profile_codec == VIDC_SM_PROFILE_MPEG2_SIMPLE)
+			profile = VCD_PROFILE_MPEG2_SIMPLE;
+		else
+			profile = VCD_PROFILE_UNKNOWN;
+		ddl_get_mpeg2_dec_level(&level, level_codec);
+	break;
+	case VCD_CODEC_VC1:
+	case VCD_CODEC_VC1_RCV:
+		if (profile_codec == VIDC_SM_PROFILE_VC1_SIMPLE)
+			profile = VCD_PROFILE_VC1_SIMPLE;
+		else if (profile_codec == VIDC_SM_PROFILE_VC1_MAIN)
+			profile = VCD_PROFILE_VC1_MAIN;
+		else if (profile_codec == VIDC_SM_PROFILE_VC1_ADVANCED)
+			profile = VCD_PROFILE_VC1_ADVANCE;
+		else
+			profile = VCD_PROFILE_UNKNOWN;
+		ddl_get_vc1_dec_level(&level, level_codec, profile);
+	break;
+	default:
+		if (!profile_codec)
+			profile = VCD_PROFILE_UNKNOWN;
+		if (!level)
+			level = VCD_LEVEL_UNKNOWN;
+	break;
+	}
+	decoder->profile.profile = profile;
+	decoder->level.level = level;
+}
+
+static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl,
+					u32 eos_present)
+{
+	struct ddl_context       *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct vcd_frame_data    *output_frame = &(ddl->output_frame.vcd_frm);
+	u32 bottom_frame_tag;
+	u8 *input_buffer_address = NULL;
+
+	vidc_sm_get_frame_tags(&ddl->shared_mem[ddl->command_channel],
+		&output_frame->ip_frm_tag, &bottom_frame_tag);
+	output_frame->data_len = encoder->enc_frame_info.enc_frame_size;
+	output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
+	(void)ddl_get_encoded_frame(output_frame,
+		encoder->codec.codec, encoder->enc_frame_info.enc_frame
+								);
+	ddl_process_encoder_metadata(ddl);
+	ddl_vidc_encode_dynamic_property(ddl, false);
+	ddl->input_frame.frm_trans_end = false;
+	input_buffer_address = ddl_context->dram_base_a.align_physical_addr +
+			encoder->enc_frame_info.enc_luma_address;
+	ddl_get_input_frame_from_pool(ddl, input_buffer_address);
+	ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
+					VCD_S_SUCCESS, &(ddl->input_frame),
+					sizeof(struct ddl_frame_data_tag),
+					(u32 *) ddl, ddl->client_data);
+	ddl->output_frame.frm_trans_end = eos_present ?
+		false : true;
+	ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+				VCD_S_SUCCESS, &(ddl->output_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl, ddl->client_data);
+}
+
+static void ddl_handle_slice_done_slice_batch(struct ddl_client_context *ddl)
+{
+	struct ddl_context       *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct vcd_frame_data    *output_frame = NULL;
+	u32 bottom_frame_tag;
+	struct vidc_1080p_enc_slice_batch_out_param *slice_output = NULL;
+	u32 num_slices_comp = 0;
+	u32 index = 0;
+	u32 start_bfr_idx = 0;
+	u32 actual_idx = 0;
+
+	DDL_MSG_LOW("%s\n", __func__);
+	vidc_sm_get_num_slices_comp(
+			&ddl->shared_mem[ddl->command_channel],
+			&num_slices_comp);
+	slice_output = (struct vidc_1080p_enc_slice_batch_out_param *)
+		(encoder->batch_frame.slice_batch_out.align_virtual_addr);
+	DDL_MSG_LOW(" after get no of slices = %d\n", num_slices_comp);
+	if (slice_output == NULL)
+		DDL_MSG_ERROR(" slice_output is NULL\n");
+	encoder->slice_delivery_info.num_slices_enc += num_slices_comp;
+	if (vidc_msg_timing) {
+		ddl_calc_core_proc_time_cnt(__func__, ENC_SLICE_OP_TIME,
+					num_slices_comp);
+		ddl_set_core_start_time(__func__, ENC_SLICE_OP_TIME);
+	}
+	DDL_MSG_LOW("%s : Slices Completed %d Total slices %d OutBfrInfo:"
+			"Cmd %d Size %d\n",
+			__func__,
+			num_slices_comp,
+			encoder->slice_delivery_info.num_slices_enc,
+			slice_output->cmd_type,
+			slice_output->output_size);
+	start_bfr_idx = encoder->batch_frame.out_frm_next_frmindex;
+	for (index = 0; index < num_slices_comp; index++) {
+		actual_idx =
+		slice_output->slice_info[start_bfr_idx+index].stream_buffer_idx;
+		DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d\n",
+			actual_idx,
+			slice_output->slice_info[start_bfr_idx+index].
+			stream_buffer_size);
+		output_frame = &(
+			encoder->batch_frame.output_frame[actual_idx].vcd_frm);
+		DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
+			"frmbfr(physical) 0x%x\n",
+			&output_frame,
+			output_frame.virtual_base_addr,
+			output_frame.physical_base_addr);
+		vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info);
+		vidc_sm_get_frame_tags(&ddl->shared_mem
+			[ddl->command_channel],
+			&output_frame->ip_frm_tag, &bottom_frame_tag);
+		ddl_get_encoded_frame(output_frame,
+				encoder->codec.codec,
+				encoder->enc_frame_info.enc_frame);
+		output_frame->data_len =
+			slice_output->slice_info[actual_idx].stream_buffer_size;
+		ddl->output_frame =
+			encoder->batch_frame.output_frame[actual_idx];
+		ddl->output_frame.frm_trans_end = false;
+		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+				VCD_S_SUCCESS, &(ddl->output_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl, ddl->client_data);
+		ddl->input_frame.frm_trans_end = false;
+		DDL_MSG_LOW("%s Set i/p o/p transactions to false\n", __func__);
+	}
+	encoder->batch_frame.out_frm_next_frmindex = start_bfr_idx + index;
+	ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
+	vidc_sm_set_encoder_slice_batch_int_ctrl(
+			&ddl->shared_mem[ddl->command_channel],
+			0);
+}
+
+static void ddl_handle_enc_frame_done_slice_mode(
+		struct ddl_client_context *ddl, u32 eos_present)
+{
+	struct ddl_context       *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct vcd_frame_data    *output_frame = NULL;
+	u32 bottom_frame_tag;
+	u8 *input_buffer_address = NULL;
+	struct vidc_1080p_enc_slice_batch_out_param *slice_output = NULL;
+	u32 num_slices_comp = 0;
+	u32 index = 0;
+	u32 start_bfr_idx = 0;
+	u32 actual_idx = 0;
+	struct vcd_transc *transc;
+
+	DDL_MSG_LOW("%s\n", __func__);
+	vidc_sm_get_num_slices_comp(
+				&ddl->shared_mem[ddl->command_channel],
+				&num_slices_comp);
+	slice_output = (struct vidc_1080p_enc_slice_batch_out_param *)
+		encoder->batch_frame.slice_batch_out.align_virtual_addr;
+	encoder->slice_delivery_info.num_slices_enc += num_slices_comp;
+	if (vidc_msg_timing) {
+		ddl_calc_core_proc_time_cnt(__func__, ENC_OP_TIME,
+					num_slices_comp);
+	}
+	DDL_MSG_LOW("%s Slices Completed %d Total slices done = %d"
+		" OutBfrInfo: Cmd %d Size %d",
+		__func__,
+		num_slices_comp,
+		encoder->slice_delivery_info.num_slices_enc,
+		slice_output->cmd_type,
+		slice_output->output_size);
+	start_bfr_idx = encoder->batch_frame.out_frm_next_frmindex;
+	if ((encoder->slice_delivery_info.num_slices_enc %
+		encoder->batch_frame.num_output_frames) != 0) {
+		DDL_MSG_ERROR("ERROR : %d %d\n",
+		encoder->slice_delivery_info.num_slices_enc,
+		encoder->batch_frame.num_output_frames);
+	}
+	for (index = 0; index < num_slices_comp; index++) {
+		actual_idx =
+			slice_output->slice_info[start_bfr_idx+index]. \
+			stream_buffer_idx;
+		DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d",
+			actual_idx,
+			slice_output->slice_info[start_bfr_idx+index]. \
+			stream_buffer_size, 0);
+		output_frame =
+		&(encoder->batch_frame.output_frame[actual_idx].vcd_frm);
+		DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
+				"frmbfr(physical) 0x%x",
+				&output_frame,
+				output_frame.virtual_base_addr,
+				output_frame.physical_base_addr);
+		vidc_1080p_get_encode_frame_info(
+			&encoder->enc_frame_info);
+		vidc_sm_get_frame_tags(&ddl->shared_mem
+			[ddl->command_channel],
+			&output_frame->ip_frm_tag, &bottom_frame_tag);
+		ddl_get_encoded_frame(output_frame,
+				encoder->codec.codec,
+				encoder->enc_frame_info.enc_frame);
+		output_frame->data_len =
+			slice_output->slice_info[actual_idx].stream_buffer_size;
+		ddl->output_frame =
+			encoder->batch_frame.output_frame[actual_idx];
+		DDL_MSG_LOW(" %s actual_idx = %d"
+		"encoder->batch_frame.num_output_frames = %d\n", __func__,
+		actual_idx, encoder->batch_frame.num_output_frames);
+		if (encoder->batch_frame.num_output_frames == (actual_idx+1)) {
+			output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
+			ddl_vidc_encode_dynamic_property(ddl, false);
+			ddl->input_frame.frm_trans_end = true;
+			DDL_MSG_LOW("%s End of frame detected\n", __func__);
+			input_buffer_address =
+				ddl_context->dram_base_a.align_physical_addr +
+				encoder->enc_frame_info.enc_luma_address;
+			ddl_get_input_frame_from_pool(ddl,
+				input_buffer_address);
+			transc = (struct vcd_transc *)(ddl->client_data);
+			if (eos_present)
+				ddl->output_frame.frm_trans_end = false;
+			else
+				ddl->output_frame.frm_trans_end = true;
+		}
+		DDL_MSG_LOW("%s Before output done cb\n", __func__);
+		transc = (struct vcd_transc *)(ddl->client_data);
+		ddl->output_frame.vcd_frm = *output_frame;
+		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+				VCD_S_SUCCESS, &(ddl->output_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl, ddl->client_data);
+	}
+	if (encoder->batch_frame.num_output_frames == (actual_idx+1)) {
+		DDL_MSG_LOW("%s sending input done\n", __func__);
+		ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
+				VCD_S_SUCCESS, &(ddl->input_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl, ddl->client_data);
+	}
+}
+
+static void ddl_handle_enc_skipframe_slice_mode(
+		struct ddl_client_context *ddl, u32 eos_present)
+{
+	struct ddl_context       *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct vcd_frame_data    *output_frame = NULL;
+	u32 bottom_frame_tag;
+	u8 *input_buffer_address = NULL;
+	u32 index = 0;
+	DDL_MSG_HIGH("ddl_handle_enc_skipframe_slice_mode: frame skipped");
+	vidc_sm_set_encoder_slice_batch_int_ctrl(
+			&ddl->shared_mem[ddl->command_channel],
+			1);
+	for (index = 0;
+		index < encoder->batch_frame.num_output_frames;
+		index++) {
+		output_frame =
+			&(encoder->batch_frame.output_frame[index].vcd_frm);
+		DDL_MSG_MED("output buffer: vcd_frm = 0x%x "
+				"frmbfr(virtual) = 0x%x frmbfr(physical) = 0x%x",
+				(u32)output_frame, (u32)output_frame->virtual,
+				(u32)output_frame->physical);
+		vidc_sm_get_frame_tags(
+				&ddl->shared_mem[ddl->command_channel],
+				&output_frame->ip_frm_tag,
+				&bottom_frame_tag);
+		ddl_get_encoded_frame(
+				output_frame,
+				encoder->codec.codec,
+				encoder->enc_frame_info.enc_frame);
+		output_frame->data_len = 0;
+		ddl->output_frame.frm_trans_end = false;
+		if (encoder->batch_frame.num_output_frames ==
+			(index + 1)) {
+			DDL_MSG_MED("last output bfr for skip frame, set EOF");
+			output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
+			ddl_vidc_encode_dynamic_property(ddl, false);
+			if (eos_present)
+				ddl->output_frame.frm_trans_end = false;
+			else
+				ddl->output_frame.frm_trans_end = true;
+		}
+		ddl->output_frame.vcd_frm = *output_frame;
+		ddl_context->ddl_callback(
+				VCD_EVT_RESP_OUTPUT_DONE,
+				VCD_S_SUCCESS,
+				&(ddl->output_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *)ddl,
+				ddl->client_data);
+
+		if (encoder->batch_frame.num_output_frames ==
+			(index + 1)) {
+			ddl->input_frame.frm_trans_end = false;
+			input_buffer_address =
+				ddl_context->dram_base_a.physical_base_addr +
+				(encoder->enc_frame_info.enc_luma_address);
+			ddl_get_input_frame_from_pool(ddl,
+					input_buffer_address);
+			DDL_MSG_MED("InpBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
+					" frmbfr(physical) 0x%x",
+					(u32)&(ddl->input_frame.vcd_frm),
+					(u32)ddl->input_frame.vcd_frm.virtual,
+					(u32)ddl->input_frame.vcd_frm.physical);
+			ddl_context->ddl_callback(
+					VCD_EVT_RESP_INPUT_DONE,
+					VCD_S_SUCCESS,
+					&(ddl->input_frame),
+					sizeof(struct ddl_frame_data_tag),
+					(u32 *)ddl,
+					ddl->client_data);
+		}
+	}
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
new file mode 100644
index 0000000..267e924
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
@@ -0,0 +1,508 @@
+/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vcd_ddl.h"
+#include "vcd_ddl_shared_mem.h"
+#include "vcd_ddl_metadata.h"
+
+static u32 *ddl_metadata_hdr_entry(struct ddl_client_context *ddl,
+	u32 meta_data)
+{
+	u32 skip_words = 0;
+	u32 *buffer;
+
+	if (ddl->decoding) {
+		buffer = (u32 *) ddl->codec_data.decoder.meta_data_input.
+			align_virtual_addr;
+		skip_words = 32 + 1;
+		buffer += skip_words;
+		switch (meta_data) {
+		default:
+		case VCD_METADATA_DATANONE:
+			skip_words = 0;
+		break;
+		case VCD_METADATA_QPARRAY:
+			skip_words = 3;
+		break;
+		case VCD_METADATA_CONCEALMB:
+			skip_words = 6;
+		break;
+		case VCD_METADATA_VC1:
+			skip_words = 9;
+		break;
+		case VCD_METADATA_SEI:
+			skip_words = 12;
+		break;
+		case VCD_METADATA_VUI:
+			skip_words = 15;
+		break;
+		case VCD_METADATA_PASSTHROUGH:
+			skip_words = 18;
+		break;
+		case VCD_METADATA_QCOMFILLER:
+			skip_words = 21;
+		break;
+		}
+	} else {
+		buffer = (u32 *) ddl->codec_data.encoder.meta_data_input.
+				align_virtual_addr;
+		skip_words = 2;
+		buffer += skip_words;
+		switch (meta_data) {
+		default:
+		case VCD_METADATA_DATANONE:
+			skip_words = 0;
+		break;
+		case VCD_METADATA_ENC_SLICE:
+			skip_words = 3;
+		break;
+		case VCD_METADATA_QCOMFILLER:
+			skip_words = 6;
+		break;
+		}
+	}
+	buffer += skip_words;
+	return buffer;
+}
+
+void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl)
+{
+	struct ddl_buf_addr *main_buffer =
+		&ddl->ddl_context->metadata_shared_input;
+	struct ddl_buf_addr *client_buffer;
+	u32 *hdr_entry;
+
+	if (ddl->decoding)
+		client_buffer = &(ddl->codec_data.decoder.meta_data_input);
+	else
+		client_buffer = &(ddl->codec_data.encoder.meta_data_input);
+	DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer,
+		ddl->instance_id);
+	hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER);
+	hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+	hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+	hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QCOMFILLER;
+	hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_DATANONE);
+	hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+	hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+	hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_DATANONE;
+	if (ddl->decoding) {
+		hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QPARRAY);
+		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QPARRAY;
+		hdr_entry = ddl_metadata_hdr_entry(ddl,	VCD_METADATA_CONCEALMB);
+		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_CONCEALMB;
+		hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_SEI);
+		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_SEI;
+		hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VUI);
+		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VUI;
+		hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VC1);
+		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VC1;
+		hdr_entry = ddl_metadata_hdr_entry(ddl,
+			VCD_METADATA_PASSTHROUGH);
+		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] =
+			VCD_METADATA_PASSTHROUGH;
+	} else {
+		hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_ENC_SLICE);
+		hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101;
+		hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1;
+		hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_ENC_SLICE;
+	}
+}
+
+static u32 ddl_supported_metadata_flag(struct ddl_client_context *ddl)
+{
+	u32 flag = 0;
+
+	if (ddl->decoding) {
+		enum vcd_codec codec =
+			ddl->codec_data.decoder.codec.codec;
+
+		flag |= (VCD_METADATA_CONCEALMB | VCD_METADATA_PASSTHROUGH |
+				VCD_METADATA_QPARRAY);
+		if (codec == VCD_CODEC_H264)
+			flag |= (VCD_METADATA_SEI | VCD_METADATA_VUI);
+		else if (codec == VCD_CODEC_VC1 ||
+			codec == VCD_CODEC_VC1_RCV)
+			flag |= VCD_METADATA_VC1;
+	} else
+		flag |= VCD_METADATA_ENC_SLICE;
+	return flag;
+}
+
+void ddl_set_default_metadata_flag(struct ddl_client_context *ddl)
+{
+	if (ddl->decoding)
+		ddl->codec_data.decoder.meta_data_enable_flag = 0;
+	else
+		ddl->codec_data.encoder.meta_data_enable_flag = 0;
+}
+
+void ddl_set_default_decoder_metadata_buffer_size(struct ddl_decoder_data
+	*decoder, struct vcd_property_frame_size *frame_size,
+	struct vcd_buffer_requirement *output_buf_req)
+{
+	u32 flag = decoder->meta_data_enable_flag;
+	u32 suffix = 0, size = 0;
+
+	if (!flag) {
+		decoder->suffix = 0;
+		return;
+	}
+	if (flag & VCD_METADATA_QPARRAY) {
+		u32 num_of_mb = DDL_NO_OF_MB(frame_size->width,
+			frame_size->height);
+
+		size = DDL_METADATA_HDR_SIZE;
+		size += num_of_mb;
+		DDL_METADATA_ALIGNSIZE(size);
+		suffix += size;
+	}
+	if (flag & VCD_METADATA_CONCEALMB) {
+		u32 num_of_mb = DDL_NO_OF_MB(frame_size->width,
+			frame_size->height);
+		size = DDL_METADATA_HDR_SIZE + (num_of_mb >> 3);
+		DDL_METADATA_ALIGNSIZE(size);
+		suffix += size;
+	}
+	if (flag & VCD_METADATA_VC1) {
+		size = DDL_METADATA_HDR_SIZE;
+		size += DDL_METADATA_VC1_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(size);
+		suffix += size;
+	}
+	if (flag & VCD_METADATA_SEI) {
+		size = DDL_METADATA_HDR_SIZE;
+		size += DDL_METADATA_SEI_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(size);
+		suffix += (size * DDL_METADATA_SEI_MAX);
+	}
+	if (flag & VCD_METADATA_VUI) {
+		size = DDL_METADATA_HDR_SIZE;
+		size += DDL_METADATA_VUI_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(size);
+		suffix += (size);
+	}
+	if (flag & VCD_METADATA_PASSTHROUGH) {
+		size = DDL_METADATA_HDR_SIZE;
+		size += DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(size);
+		suffix += (size);
+	}
+	size = DDL_METADATA_EXTRADATANONE_SIZE;
+	DDL_METADATA_ALIGNSIZE(size);
+	suffix += (size);
+	suffix += DDL_METADATA_EXTRAPAD_SIZE;
+	DDL_METADATA_ALIGNSIZE(suffix);
+	decoder->suffix = suffix;
+	output_buf_req->sz += suffix;
+	DDL_MSG_LOW("metadata output buf size : %d", suffix);
+}
+
+void ddl_set_default_encoder_metadata_buffer_size(struct ddl_encoder_data
+	*encoder)
+{
+	u32 flag = encoder->meta_data_enable_flag;
+	u32 suffix = 0, size = 0;
+
+	if (!flag) {
+		encoder->suffix = 0;
+		return;
+	}
+	if (flag & VCD_METADATA_ENC_SLICE) {
+		u32 num_of_mb = DDL_NO_OF_MB(encoder->frame_size.width,
+			encoder->frame_size.height);
+		size = DDL_METADATA_HDR_SIZE;
+		size += 4;
+		size += (num_of_mb << 3);
+		DDL_METADATA_ALIGNSIZE(size);
+		suffix += size;
+	}
+	size = DDL_METADATA_EXTRADATANONE_SIZE;
+	DDL_METADATA_ALIGNSIZE(size);
+	suffix += (size);
+	suffix += DDL_METADATA_EXTRAPAD_SIZE;
+	DDL_METADATA_ALIGNSIZE(suffix);
+	encoder->suffix = suffix;
+	encoder->output_buf_req.sz += suffix;
+	encoder->output_buf_req.sz =
+		DDL_ALIGN(encoder->output_buf_req.sz, DDL_KILO_BYTE(4));
+}
+
+u32 ddl_set_metadata_params(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	u32  vcd_status = VCD_ERR_ILLEGAL_PARM;
+	if (property_hdr->prop_id == VCD_I_METADATA_ENABLE) {
+		struct vcd_property_meta_data_enable *meta_data_enable =
+			(struct vcd_property_meta_data_enable *) property_value;
+		u32 *meta_data_enable_flag;
+		enum vcd_codec codec;
+
+		if (ddl->decoding) {
+			meta_data_enable_flag =
+			&(ddl->codec_data.decoder.meta_data_enable_flag);
+			codec = ddl->codec_data.decoder.codec.codec;
+		} else {
+			meta_data_enable_flag =
+				&ddl->codec_data.encoder.meta_data_enable_flag;
+			codec = ddl->codec_data.encoder.codec.codec;
+		}
+		if (sizeof(struct vcd_property_meta_data_enable) ==
+			property_hdr->sz &&
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && codec) {
+			u32 flag = ddl_supported_metadata_flag(ddl);
+			flag &= (meta_data_enable->meta_data_enable_flag);
+			if (flag)
+				flag |= DDL_METADATA_MANDATORY;
+			if (*meta_data_enable_flag != flag) {
+				*meta_data_enable_flag = flag;
+				if (ddl->decoding)
+					ddl_set_default_decoder_buffer_req(
+						&ddl->codec_data.decoder, true);
+				else
+					ddl_set_default_encoder_buffer_req(
+						&ddl->codec_data.encoder);
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	} else if (property_hdr->prop_id == VCD_I_METADATA_HEADER) {
+		struct vcd_property_metadata_hdr *hdr =
+			(struct vcd_property_metadata_hdr *) property_value;
+
+		if (sizeof(struct vcd_property_metadata_hdr) ==
+			property_hdr->sz) {
+			u32 flag = ddl_supported_metadata_flag(ddl);
+
+			flag |= DDL_METADATA_MANDATORY;
+			flag &= hdr->meta_data_id;
+			if (!(flag & (flag - 1))) {
+				u32 *hdr_entry = ddl_metadata_hdr_entry(ddl,
+					flag);
+				hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] =
+					hdr->version;
+				hdr_entry[DDL_METADATA_HDR_PORT_INDEX] =
+					hdr->port_index;
+				hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] =
+					hdr->type;
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+	}
+	return vcd_status;
+}
+
+u32 ddl_get_metadata_params(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+	if (property_hdr->prop_id == VCD_I_METADATA_ENABLE &&
+		sizeof(struct vcd_property_meta_data_enable) ==
+		property_hdr->sz) {
+		struct vcd_property_meta_data_enable *meta_data_enable =
+			(struct vcd_property_meta_data_enable *) property_value;
+
+		meta_data_enable->meta_data_enable_flag =
+			((ddl->decoding) ?
+			(ddl->codec_data.decoder.meta_data_enable_flag) :
+			(ddl->codec_data.encoder.meta_data_enable_flag));
+		vcd_status = VCD_S_SUCCESS;
+	} else if (property_hdr->prop_id == VCD_I_METADATA_HEADER &&
+		sizeof(struct vcd_property_metadata_hdr) ==
+		property_hdr->sz) {
+		struct vcd_property_metadata_hdr *hdr =
+			(struct vcd_property_metadata_hdr *) property_value;
+		u32 flag = ddl_supported_metadata_flag(ddl);
+
+		flag |= DDL_METADATA_MANDATORY;
+		flag &= hdr->meta_data_id;
+		if (!(flag & (flag - 1))) {
+			u32 *hdr_entry = ddl_metadata_hdr_entry(ddl, flag);
+			hdr->version =
+				hdr_entry[DDL_METADATA_HDR_VERSION_INDEX];
+			hdr->port_index =
+				hdr_entry[DDL_METADATA_HDR_PORT_INDEX];
+			hdr->type = hdr_entry[DDL_METADATA_HDR_TYPE_INDEX];
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	return vcd_status;
+}
+
+void ddl_vidc_metadata_enable(struct ddl_client_context *ddl)
+{
+	u32 flag, extradata_enable = false;
+	u32 qp_enable = false, concealed_mb_enable = false;
+	u32 vc1_param_enable = false, sei_nal_enable = false;
+	u32 vui_enable = false, enc_slice_size_enable = false;
+
+	if (ddl->decoding)
+		flag = ddl->codec_data.decoder.meta_data_enable_flag;
+	else
+		flag = ddl->codec_data.encoder.meta_data_enable_flag;
+	if (flag) {
+		if (flag & VCD_METADATA_QPARRAY)
+			qp_enable = true;
+		if (flag & VCD_METADATA_CONCEALMB)
+			concealed_mb_enable = true;
+		if (flag & VCD_METADATA_VC1)
+			vc1_param_enable = true;
+		if (flag & VCD_METADATA_SEI)
+			sei_nal_enable = true;
+		if (flag & VCD_METADATA_VUI)
+			vui_enable = true;
+		if (flag & VCD_METADATA_ENC_SLICE)
+			enc_slice_size_enable = true;
+		if (flag & VCD_METADATA_PASSTHROUGH)
+			extradata_enable = true;
+	}
+
+	DDL_MSG_LOW("metadata enable flag : %d", sei_nal_enable);
+	vidc_sm_set_metadata_enable(&ddl->shared_mem
+		[ddl->command_channel], extradata_enable, qp_enable,
+		concealed_mb_enable, vc1_param_enable, sei_nal_enable,
+		vui_enable, enc_slice_size_enable);
+}
+
+u32 ddl_vidc_encode_set_metadata_output_buf(struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &ddl->codec_data.encoder;
+	struct vcd_frame_data *stream = &ddl->output_frame.vcd_frm;
+	struct ddl_context *ddl_context;
+	u32 ext_buffer_end, hw_metadata_start;
+	u32 *buffer;
+
+	ddl_context = ddl_get_context();
+	ext_buffer_end = (u32) stream->physical + stream->alloc_len;
+	if (!encoder->meta_data_enable_flag) {
+		ext_buffer_end &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+		return ext_buffer_end;
+	}
+	hw_metadata_start = (ext_buffer_end - encoder->suffix) &
+		~(DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+	ext_buffer_end = (hw_metadata_start - 1) &
+		~(DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+	buffer = (u32 *) encoder->meta_data_input.align_virtual_addr;
+	*buffer++ = encoder->suffix;
+	*buffer  = DDL_OFFSET(ddl_context->dram_base_a.align_physical_addr,
+		hw_metadata_start);
+	encoder->meta_data_offset = hw_metadata_start - (u32) stream->physical;
+	return ext_buffer_end;
+}
+
+void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder)
+{
+	struct ddl_context *ddl_context;
+	u32 loopc, yuv_size;
+	u32 *buffer;
+
+	if (!decoder->meta_data_enable_flag) {
+		decoder->meta_data_offset = 0;
+		return;
+	}
+	ddl_context = ddl_get_context();
+	yuv_size = ddl_get_yuv_buffer_size(&decoder->client_frame_size,
+		&decoder->buf_format, !decoder->progressive_only,
+		decoder->hdr.decoding, NULL);
+	decoder->meta_data_offset = DDL_ALIGN_SIZE(yuv_size,
+		DDL_LINEAR_BUF_ALIGN_GUARD_BYTES, DDL_LINEAR_BUF_ALIGN_MASK);
+	buffer = (u32 *) decoder->meta_data_input.align_virtual_addr;
+	*buffer++ = decoder->suffix;
+	DDL_MSG_LOW("Metadata offset & size : %d/%d",
+		decoder->meta_data_offset, decoder->suffix);
+	for (loopc = 0; loopc < decoder->dp_buf.no_of_dec_pic_buf;
+		++loopc) {
+		*buffer++ = (u32)(decoder->meta_data_offset + (u8 *)
+			DDL_OFFSET(ddl_context->dram_base_a.
+			align_physical_addr, decoder->dp_buf.
+			dec_pic_buffers[loopc].vcd_frm.physical));
+	}
+}
+
+void ddl_process_encoder_metadata(struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	struct vcd_frame_data *out_frame =
+		&(ddl->output_frame.vcd_frm);
+	u32 *qfiller_hdr, *qfiller, start_addr;
+	u32 qfiller_size;
+	if (!encoder->meta_data_enable_flag) {
+		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
+		return;
+	}
+	if (!encoder->enc_frame_info.meta_data_exists) {
+		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
+		return;
+	}
+	out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
+	DDL_MSG_LOW("processing metadata for encoder");
+	start_addr = (u32) ((u8 *)out_frame->virtual + out_frame->offset);
+	qfiller = (u32 *)((out_frame->data_len +
+				start_addr + 3) & ~3);
+	qfiller_size = (u32)((encoder->meta_data_offset +
+		(u8 *) out_frame->virtual) - (u8 *) qfiller);
+	qfiller_hdr = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER);
+	*qfiller++ = qfiller_size;
+	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX];
+	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX];
+	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX];
+	*qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE);
+}
+
+void ddl_process_decoder_metadata(struct ddl_client_context *ddl)
+{
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vcd_frame_data *output_frame =
+		&(ddl->output_frame.vcd_frm);
+	u32 *qfiller_hdr, *qfiller;
+	u32 qfiller_size;
+
+	if (!decoder->meta_data_enable_flag) {
+		output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
+		return;
+	}
+	if (!decoder->meta_data_exists) {
+		output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
+		return;
+	}
+	DDL_MSG_LOW("processing metadata for decoder");
+	DDL_MSG_LOW("data_len/metadata_offset : %d/%d",
+		output_frame->data_len, decoder->meta_data_offset);
+	output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
+	if (output_frame->data_len != decoder->meta_data_offset) {
+		qfiller = (u32 *)((u32)((output_frame->data_len +
+			output_frame->offset  +
+				(u8 *) output_frame->virtual) + 3) & ~3);
+		qfiller_size = (u32)((decoder->meta_data_offset +
+				(u8 *) output_frame->virtual) -
+				(u8 *) qfiller);
+		qfiller_hdr = ddl_metadata_hdr_entry(ddl,
+				VCD_METADATA_QCOMFILLER);
+		*qfiller++ = qfiller_size;
+		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX];
+		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX];
+		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX];
+		*qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE);
+	}
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h
new file mode 100644
index 0000000..c63b6a9
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h
@@ -0,0 +1,66 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VCD_DDL_METADATA_H_
+#define _VCD_DDL_METADATA_H_
+
+#define DDL_MAX_DEC_METADATATYPE          8
+#define DDL_MAX_ENC_METADATATYPE          3
+#define DDL_METADATA_EXTRAPAD_SIZE      256
+#define DDL_METADATA_HDR_SIZE            20
+#define DDL_METADATA_EXTRADATANONE_SIZE  24
+#define DDL_METADATA_ALIGNSIZE(x) ((x) = (((x) + 0x7) & ~0x7))
+#define DDL_METADATA_MANDATORY \
+	(VCD_METADATA_DATANONE | VCD_METADATA_QCOMFILLER)
+#define DDL_METADATA_VC1_PAYLOAD_SIZE         (38*4)
+#define DDL_METADATA_SEI_PAYLOAD_SIZE          100
+#define DDL_METADATA_SEI_MAX                     5
+#define DDL_METADATA_VUI_PAYLOAD_SIZE          256
+#define DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE   68
+#define DDL_METADATA_CLIENT_INPUTBUFSIZE       256
+#define DDL_METADATA_TOTAL_INPUTBUFSIZE \
+	(DDL_METADATA_CLIENT_INPUTBUFSIZE * VCD_MAX_NO_CLIENT)
+
+#define DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer,\
+	channel_id) { \
+	(client_buffer)->align_physical_addr = (u8 *) \
+	((u8 *)(main_buffer)->align_physical_addr + \
+	(DDL_METADATA_CLIENT_INPUTBUFSIZE * channel_id)); \
+	(client_buffer)->align_virtual_addr = (u8 *) \
+	((u8 *)(main_buffer)->align_virtual_addr + \
+	(DDL_METADATA_CLIENT_INPUTBUFSIZE * channel_id)); \
+	(client_buffer)->virtual_base_addr = 0;	\
+	}
+
+#define DDL_METADATA_HDR_VERSION_INDEX 0
+#define DDL_METADATA_HDR_PORT_INDEX    1
+#define DDL_METADATA_HDR_TYPE_INDEX    2
+
+void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl);
+u32 ddl_get_metadata_params(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+u32 ddl_set_metadata_params(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+void ddl_set_default_metadata_flag(struct ddl_client_context *ddl);
+void ddl_set_default_decoder_metadata_buffer_size(struct ddl_decoder_data
+	*decoder, struct vcd_property_frame_size *frame_size,
+	struct vcd_buffer_requirement *output_buf_req);
+void ddl_set_default_encoder_metadata_buffer_size(
+	struct ddl_encoder_data *encoder);
+void ddl_vidc_metadata_enable(struct ddl_client_context *ddl);
+u32 ddl_vidc_encode_set_metadata_output_buf(struct ddl_client_context *ddl);
+void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder);
+void ddl_process_encoder_metadata(struct ddl_client_context *ddl);
+void ddl_process_decoder_metadata(struct ddl_client_context *ddl);
+
+#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
new file mode 100644
index 0000000..db3624a
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -0,0 +1,2099 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vcd_ddl.h"
+#include "vcd_ddl_metadata.h"
+#include "vcd_res_tracker_api.h"
+
+static u32 ddl_set_dec_property(struct ddl_client_context *pddl,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+static u32 ddl_set_enc_property(struct ddl_client_context *pddl,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+static u32 ddl_get_dec_property(struct ddl_client_context *pddl,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+static u32 ddl_get_enc_property(struct ddl_client_context *pddl,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+static u32 ddl_set_enc_dynamic_property(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value);
+static void ddl_set_default_enc_property(struct ddl_client_context *ddl);
+static void ddl_set_default_enc_profile(
+	struct ddl_encoder_data *encoder);
+static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder);
+static void ddl_set_default_enc_vop_timing(
+	struct ddl_encoder_data *encoder);
+static void ddl_set_default_enc_intra_period(
+	struct ddl_encoder_data *encoder);
+static void ddl_set_default_enc_rc_params(
+	struct ddl_encoder_data *encoder);
+static u32 ddl_valid_buffer_requirement(
+	struct vcd_buffer_requirement *original_buf_req,
+	struct vcd_buffer_requirement *req_buf_req);
+static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder);
+static u32 ddl_set_dec_buffers(struct ddl_decoder_data *decoder,
+	struct ddl_property_dec_pic_buffers *dpb);
+
+u32 ddl_set_property(u32 *ddl_handle,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_client_context *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	u32 vcd_status;
+
+	DDL_MSG_HIGH("ddl_set_property");
+	if (!property_hdr || !property_value) {
+		DDL_MSG_ERROR("ddl_set_prop:Bad_argument");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_set_prop:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl) {
+		DDL_MSG_ERROR("ddl_set_prop:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	if (ddl->decoding)
+		vcd_status = ddl_set_dec_property(ddl, property_hdr,
+				property_value);
+	else
+		vcd_status = ddl_set_enc_property(ddl, property_hdr,
+				property_value);
+	if (vcd_status)
+		DDL_MSG_ERROR("ddl_set_prop:FAILED");
+	return vcd_status;
+}
+
+u32 ddl_get_property(u32 *ddl_handle,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_client_context *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+
+	DDL_MSG_HIGH("ddl_get_property");
+	if (!property_hdr || !property_value)
+		return VCD_ERR_ILLEGAL_PARM;
+	if (property_hdr->prop_id == DDL_I_CAPABILITY) {
+		if (sizeof(struct ddl_property_capability) ==
+			property_hdr->sz) {
+			struct ddl_property_capability *ddl_capability =
+				(struct ddl_property_capability *)
+				property_value;
+
+			ddl_capability->max_num_client = VCD_MAX_NO_CLIENT;
+			ddl_capability->exclusive = VCD_COMMAND_EXCLUSIVE;
+			ddl_capability->frame_command_depth =
+				VCD_FRAME_COMMAND_DEPTH;
+			ddl_capability->general_command_depth =
+				VCD_GENEVIDC_COMMAND_DEPTH;
+			ddl_capability->ddl_time_out_in_ms =
+				DDL_HW_TIMEOUT_IN_MS;
+			vcd_status = VCD_S_SUCCESS;
+		}
+		return vcd_status;
+	}
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context))
+		return VCD_ERR_ILLEGAL_OP;
+	if (!ddl)
+		return VCD_ERR_BAD_HANDLE;
+	if (ddl->decoding)
+		vcd_status = ddl_get_dec_property(ddl, property_hdr,
+				property_value);
+	else
+		vcd_status = ddl_get_enc_property(ddl, property_hdr,
+				property_value);
+	if (vcd_status)
+		DDL_MSG_ERROR("ddl_get_prop:FAILED");
+	else
+		DDL_MSG_MED("ddl_get_prop:SUCCESS");
+	return vcd_status;
+}
+
+u32 ddl_decoder_ready_to_start(struct ddl_client_context *ddl,
+	struct vcd_sequence_hdr  *header)
+{
+	struct ddl_decoder_data *decoder =
+		&(ddl->codec_data.decoder);
+
+	if (!decoder->codec.codec) {
+		DDL_MSG_ERROR("ddl_dec_start_check:Codec_not_set");
+		return false;
+	}
+	if ((!header) && (!decoder->client_frame_size.height ||
+		!decoder->client_frame_size.width)) {
+		DDL_MSG_ERROR("ddl_dec_start_check:"
+			"Client_height_width_default");
+		return false;
+	}
+	return true;
+}
+
+u32 ddl_encoder_ready_to_start(struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+
+	if (!encoder->codec.codec || !encoder->frame_size.height ||
+		!encoder->frame_size.width ||
+		!encoder->frame_rate.fps_denominator ||
+		!encoder->frame_rate.fps_numerator ||
+		!encoder->target_bit_rate.target_bitrate)
+		return false;
+	if (encoder->frame_rate.fps_numerator >
+		(encoder->frame_rate.fps_denominator *
+		encoder->vop_timing.vop_time_resolution)) {
+		DDL_MSG_ERROR("ResVsFrameRateFailed!");
+		return false;
+	}
+	if (encoder->profile.profile == VCD_PROFILE_H264_BASELINE &&
+		encoder->entropy_control.entropy_sel == VCD_ENTROPY_SEL_CABAC) {
+		DDL_MSG_ERROR("H264BaseLineCABAC!!");
+		return false;
+	}
+	return true;
+}
+
+static u32 ddl_set_dec_property(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	u32  vcd_status = VCD_ERR_ILLEGAL_PARM ;
+
+	switch (property_hdr->prop_id) {
+	case DDL_I_DPB_RELEASE:
+		if ((sizeof(struct ddl_frame_data_tag) ==
+			property_hdr->sz) &&
+			(decoder->dp_buf.no_of_dec_pic_buf))
+			vcd_status = ddl_decoder_dpb_transact(decoder,
+				(struct ddl_frame_data_tag *)
+				property_value, DDL_DPB_OP_MARK_FREE);
+	break;
+	case DDL_I_DPB:
+	{
+		struct ddl_property_dec_pic_buffers *dpb =
+		(struct ddl_property_dec_pic_buffers *) property_value;
+
+		if ((sizeof(struct ddl_property_dec_pic_buffers) ==
+			property_hdr->sz) &&
+			(DDLCLIENT_STATE_IS(ddl,
+			DDL_CLIENT_WAIT_FOR_INITCODEC) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) &&
+			(dpb->no_of_dec_pic_buf ==
+			decoder->client_output_buf_req.actual_count))
+			vcd_status = ddl_set_dec_buffers(decoder, dpb);
+	}
+	break;
+	case DDL_I_REQ_OUTPUT_FLUSH:
+		if (sizeof(u32) == property_hdr->sz) {
+			decoder->dynamic_prop_change |=
+				DDL_DEC_REQ_OUTPUT_FLUSH;
+			decoder->dpb_mask.client_mask = 0;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_INPUT_BUF_REQ:
+	{
+		struct vcd_buffer_requirement *buffer_req =
+			(struct vcd_buffer_requirement *)property_value;
+
+		if (sizeof(struct vcd_buffer_requirement) ==
+			property_hdr->sz &&
+			(DDLCLIENT_STATE_IS(ddl,
+			DDL_CLIENT_WAIT_FOR_INITCODEC) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) &&
+			(ddl_valid_buffer_requirement(
+			&decoder->min_input_buf_req, buffer_req))) {
+			decoder->client_input_buf_req = *buffer_req;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case DDL_I_OUTPUT_BUF_REQ:
+	{
+		struct vcd_buffer_requirement *buffer_req =
+			(struct vcd_buffer_requirement *)property_value;
+
+		if (sizeof(struct vcd_buffer_requirement) ==
+			property_hdr->sz &&
+			(DDLCLIENT_STATE_IS(ddl,
+			DDL_CLIENT_WAIT_FOR_INITCODEC) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) &&
+			(ddl_valid_buffer_requirement(
+			&decoder->min_output_buf_req, buffer_req))) {
+				decoder->client_output_buf_req =
+					*buffer_req;
+				vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_CODEC:
+	{
+		struct vcd_property_codec *codec =
+			(struct vcd_property_codec *)property_value;
+		if (sizeof(struct vcd_property_codec) ==
+			property_hdr->sz &&
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) &&
+			ddl_codec_type_transact(ddl, false,
+			codec->codec)) {
+			if (decoder->codec.codec != codec->codec) {
+				decoder->codec = *codec;
+				ddl_set_default_dec_property(ddl);
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_POST_FILTER:
+		if (sizeof(struct vcd_property_post_filter) ==
+			property_hdr->sz &&
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && (
+			decoder->codec.codec == VCD_CODEC_MPEG4 ||
+			decoder->codec.codec == VCD_CODEC_MPEG2)) {
+			decoder->post_filter =
+				*(struct vcd_property_post_filter *)
+				property_value;
+			vcd_status = VCD_S_SUCCESS;
+	}
+	break;
+	case VCD_I_FRAME_SIZE:
+	{
+		struct vcd_property_frame_size *frame_size =
+		(struct vcd_property_frame_size *) property_value;
+		if ((sizeof(struct vcd_property_frame_size) ==
+			property_hdr->sz) &&
+			(DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) &&
+			(DDL_ALLOW_DEC_FRAMESIZE(frame_size->width,
+			frame_size->height))) {
+			if (decoder->client_frame_size.height !=
+				frame_size->height ||
+				decoder->client_frame_size.width !=
+				frame_size->width) {
+				decoder->client_frame_size = *frame_size;
+				ddl_set_default_decoder_buffer_req(decoder,
+					true);
+			}
+			DDL_MSG_LOW("set  VCD_I_FRAME_SIZE width = %d"
+				" height = %d\n",
+				frame_size->width, frame_size->height);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_BUFFER_FORMAT:
+	{
+		struct vcd_property_buffer_format *tile =
+			(struct vcd_property_buffer_format *)
+			property_value;
+		if (sizeof(struct vcd_property_buffer_format) ==
+			property_hdr->sz &&
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) &&
+			tile->buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) {
+			if (tile->buffer_format !=
+				decoder->buf_format.buffer_format) {
+				decoder->buf_format = *tile;
+				ddl_set_default_decoder_buffer_req(
+					decoder, true);
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_H264_MV_BUFFER:
+	{
+		int index, buffer_size;
+		u8 *phys_addr;
+		u8 *virt_addr;
+		struct vcd_property_h264_mv_buffer *mv_buff =
+			(struct vcd_property_h264_mv_buffer *)
+		property_value;
+		DDL_MSG_LOW("Entered VCD_I_H264_MV_BUFFER Virt: %p, Phys %p,"
+					"fd: %d size: %d count: %d\n",
+					mv_buff->kernel_virtual_addr,
+					mv_buff->physical_addr,
+					mv_buff->pmem_fd,
+					mv_buff->size, mv_buff->count);
+		if ((property_hdr->sz == sizeof(struct
+			vcd_property_h264_mv_buffer)) &&
+			(DDLCLIENT_STATE_IS(ddl,
+			DDL_CLIENT_WAIT_FOR_INITCODEC) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) ||
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) {
+			phys_addr = mv_buff->dev_addr;
+			virt_addr = mv_buff->kernel_virtual_addr;
+			buffer_size = mv_buff->size/mv_buff->count;
+
+			for (index = 0; index < mv_buff->count; index++) {
+				ddl->codec_data.decoder.hw_bufs.
+					h264_mv[index].align_physical_addr
+					= phys_addr;
+				ddl->codec_data.decoder.hw_bufs.
+					h264_mv[index].align_virtual_addr
+					= virt_addr;
+				ddl->codec_data.decoder.hw_bufs.
+					h264_mv[index].buffer_size
+					= buffer_size;
+				ddl->codec_data.decoder.hw_bufs.
+					h264_mv[index].physical_base_addr
+					= phys_addr;
+				ddl->codec_data.decoder.hw_bufs.
+					h264_mv[index].virtual_base_addr
+					= virt_addr;
+				DDL_MSG_LOW("Assigned %d buffer for "
+							"virt: %p, phys %p for "
+							"h264_mv_buffers "
+							"of size: %d\n",
+							index, virt_addr,
+							phys_addr, buffer_size);
+				phys_addr += buffer_size;
+				virt_addr += buffer_size;
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_FREE_H264_MV_BUFFER:
+		{
+			memset(&decoder->hw_bufs.h264_mv, 0, sizeof(struct
+					ddl_buf_addr) * DDL_MAX_BUFFER_COUNT);
+			vcd_status = VCD_S_SUCCESS;
+		}
+		break;
+	case VCD_I_OUTPUT_ORDER:
+		{
+			if (sizeof(u32) == property_hdr->sz &&
+				DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+					decoder->output_order =
+						*(u32 *)property_value;
+					vcd_status = VCD_S_SUCCESS;
+			}
+		}
+		break;
+	case VCD_I_DEC_PICTYPE:
+		{
+			if ((sizeof(u32) == property_hdr->sz) &&
+				DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+				decoder->idr_only_decoding =
+					*(u32 *)property_value;
+				ddl_set_default_decoder_buffer_req(
+						decoder, true);
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+		break;
+	case VCD_I_METADATA_ENABLE:
+	case VCD_I_METADATA_HEADER:
+		DDL_MSG_MED("Meta Data Interface is Requested");
+		vcd_status = ddl_set_metadata_params(ddl, property_hdr,
+			property_value);
+		vcd_status = VCD_S_SUCCESS;
+		break;
+	case VCD_I_FRAME_RATE:
+		vcd_status = VCD_S_SUCCESS;
+		break;
+	case VCD_I_CONT_ON_RECONFIG:
+	{
+		DDL_MSG_LOW("Set property VCD_I_CONT_ON_RECONFIG\n");
+		if (sizeof(u32) == property_hdr->sz &&
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+				decoder->cont_mode = *(u32 *)property_value;
+				vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_DISABLE_DMX:
+	{
+		int disable_dmx_allowed = 0;
+		DDL_MSG_LOW("Set property VCD_I_DISABLE_DMX\n");
+		if (res_trk_get_disable_dmx() &&
+			((decoder->codec.codec == VCD_CODEC_H264) ||
+			 (decoder->codec.codec == VCD_CODEC_VC1) ||
+			 (decoder->codec.codec == VCD_CODEC_VC1_RCV)))
+			disable_dmx_allowed = 1;
+
+		if (sizeof(u32) == property_hdr->sz &&
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) &&
+			disable_dmx_allowed) {
+				decoder->dmx_disable = *(u32 *)property_value;
+				vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_REQ_PERF_LEVEL:
+		vcd_status = VCD_S_SUCCESS;
+		break;
+	default:
+		vcd_status = VCD_ERR_ILLEGAL_OP;
+		break;
+	}
+	return vcd_status;
+}
+
+static u32 ddl_check_valid_enc_level(struct vcd_property_codec *codec,
+	struct vcd_property_profile *profile,
+	struct vcd_property_level *level)
+{
+	u32 status = false;
+
+	if (codec && profile && level) {
+		switch (codec->codec) {
+		case VCD_CODEC_MPEG4:
+			status = (profile->profile ==
+				VCD_PROFILE_MPEG4_SP) &&
+				(level->level >= VCD_LEVEL_MPEG4_0) &&
+				(level->level <= VCD_LEVEL_MPEG4_6) &&
+				(VCD_LEVEL_MPEG4_3b != level->level);
+			status = status ||
+				((profile->profile ==
+				VCD_PROFILE_MPEG4_ASP) &&
+				(level->level >= VCD_LEVEL_MPEG4_0) &&
+				(level->level <= VCD_LEVEL_MPEG4_5));
+		break;
+		case VCD_CODEC_H264:
+		status = (level->level >= VCD_LEVEL_H264_1) &&
+				(level->level <= VCD_LEVEL_H264_4);
+		break;
+		case VCD_CODEC_H263:
+		status = (level->level >= VCD_LEVEL_H263_10) &&
+			(level->level <= VCD_LEVEL_H263_70);
+		break;
+		default:
+		break;
+		}
+	}
+	return status;
+}
+
+static u32 ddl_set_enc_property(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr,
+	void *property_value)
+{
+	struct ddl_encoder_data *encoder =
+		&(ddl->codec_data.encoder);
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+
+	if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) ||
+		DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) ||
+		DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+		vcd_status = ddl_set_enc_dynamic_property(ddl,
+				property_hdr, property_value);
+	}
+	if (vcd_status) {
+		if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) ||
+			vcd_status != VCD_ERR_ILLEGAL_OP) {
+			DDL_MSG_ERROR("ddl_set_enc_property:"
+				"Fails_as_not_in_open_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	} else
+		return vcd_status;
+
+	switch (property_hdr->prop_id) {
+	case VCD_I_FRAME_SIZE:
+	{
+		struct vcd_property_frame_size *frame_size =
+		(struct vcd_property_frame_size *) property_value;
+		if ((sizeof(struct vcd_property_frame_size) ==
+			property_hdr->sz) &&
+			(DDL_ALLOW_ENC_FRAMESIZE(frame_size->width,
+			frame_size->height))) {
+			if (encoder->frame_size.height != frame_size->height ||
+				encoder->frame_size.width !=
+				frame_size->width) {
+				ddl_calculate_stride(frame_size, false);
+				encoder->frame_size = *frame_size;
+				ddl_set_default_encoder_buffer_req(encoder);
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_CODEC:
+	{
+		struct vcd_property_codec *codec =
+		(struct vcd_property_codec *) property_value;
+		if ((sizeof(struct vcd_property_codec) ==
+		property_hdr->sz) &&
+		(ddl_codec_type_transact(ddl, false, codec->codec))) {
+			if (codec->codec != encoder->codec.codec) {
+				encoder->codec = *codec;
+				ddl_set_default_enc_property(ddl);
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_REQ_IFRAME:
+		vcd_status = VCD_S_SUCCESS;
+		break;
+	case VCD_I_INTRA_PERIOD:
+	{
+		struct vcd_property_i_period *i_period =
+			(struct vcd_property_i_period *)property_value;
+		if (sizeof(struct vcd_property_i_period) ==
+			property_hdr->sz &&
+			i_period->b_frames <= DDL_MAX_NUM_OF_B_FRAME) {
+			encoder->i_period = *i_period;
+			encoder->client_input_buf_req.min_count =
+				i_period->b_frames + 1;
+			encoder->client_input_buf_req.actual_count =
+				DDL_MAX(encoder->client_input_buf_req.\
+				actual_count, encoder->\
+				client_input_buf_req.min_count);
+			encoder->client_output_buf_req.min_count =
+				i_period->b_frames + 2;
+			encoder->client_output_buf_req.actual_count =
+				DDL_MAX(encoder->client_output_buf_req.\
+				actual_count, encoder->\
+				client_output_buf_req.min_count);
+			ddl->extra_output_buf_count =
+				i_period->b_frames - 1;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_PROFILE:
+	{
+		struct vcd_property_profile *profile =
+			(struct vcd_property_profile *)property_value;
+
+		if ((sizeof(struct vcd_property_profile) ==
+			property_hdr->sz) && ((
+			(encoder->codec.codec == VCD_CODEC_MPEG4) && (
+			profile->profile == VCD_PROFILE_MPEG4_SP ||
+			profile->profile == VCD_PROFILE_MPEG4_ASP)) ||
+			((encoder->codec.codec == VCD_CODEC_H264) &&
+			(profile->profile >= VCD_PROFILE_H264_BASELINE) &&
+			(profile->profile <= VCD_PROFILE_H264_HIGH)) ||
+			((encoder->codec.codec == VCD_CODEC_H263) &&
+			(profile->profile == VCD_PROFILE_H263_BASELINE)))) {
+			encoder->profile = *profile;
+			vcd_status = VCD_S_SUCCESS;
+			if (profile->profile == VCD_PROFILE_H264_BASELINE)
+				encoder->entropy_control.entropy_sel =
+					VCD_ENTROPY_SEL_CAVLC;
+			else
+				encoder->entropy_control.entropy_sel =
+					VCD_ENTROPY_SEL_CABAC;
+		}
+	}
+	break;
+	case VCD_I_LEVEL:
+	{
+		struct vcd_property_level *level =
+			(struct vcd_property_level *) property_value;
+
+		if ((sizeof(struct vcd_property_level) ==
+			property_hdr->sz) && (ddl_check_valid_enc_level
+			(&encoder->codec,
+			&encoder->profile, level))) {
+			encoder->level = *level;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_MULTI_SLICE:
+	{
+		struct vcd_property_multi_slice *multi_slice =
+			(struct vcd_property_multi_slice *)
+				property_value;
+		DDL_MSG_HIGH("VCD_I_MULTI_SLICE eMSliceSel %d  nMSliceSize %d"
+				"Tot#of MB %d encoder->frame_size.width = %d"
+				"encoder->frame_size.height = %d",
+				(int)multi_slice->m_slice_sel,
+				multi_slice->m_slice_size,
+				DDL_NO_OF_MB(encoder->frame_size.width,
+					encoder->frame_size.height),
+				encoder->frame_size.width,
+				encoder->frame_size.height);
+		switch (multi_slice->m_slice_sel) {
+		case VCD_MSLICE_OFF:
+			vcd_status = VCD_S_SUCCESS;
+		break;
+		case VCD_MSLICE_BY_GOB:
+			if (encoder->codec.codec == VCD_CODEC_H263)
+				vcd_status = VCD_S_SUCCESS;
+		break;
+		case VCD_MSLICE_BY_MB_COUNT:
+		{
+			if ((multi_slice->m_slice_size >= 1) &&
+				(multi_slice->m_slice_size <=
+				DDL_NO_OF_MB(encoder->frame_size.width,
+					encoder->frame_size.height))) {
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+		break;
+		case VCD_MSLICE_BY_BYTE_COUNT:
+			if (multi_slice->m_slice_size > 0)
+				vcd_status = VCD_S_SUCCESS;
+		break;
+		default:
+		break;
+		}
+		if (sizeof(struct vcd_property_multi_slice) ==
+			property_hdr->sz && !vcd_status) {
+			encoder->multi_slice = *multi_slice;
+			if (multi_slice->m_slice_sel == VCD_MSLICE_OFF)
+				encoder->multi_slice.m_slice_size = 0;
+		}
+	}
+	break;
+	case VCD_I_RATE_CONTROL:
+	{
+		struct vcd_property_rate_control *rate_control =
+			(struct vcd_property_rate_control *)
+			property_value;
+		if (sizeof(struct vcd_property_rate_control) ==
+			property_hdr->sz &&
+			rate_control->rate_control >=
+			VCD_RATE_CONTROL_OFF &&
+			rate_control->rate_control <=
+			VCD_RATE_CONTROL_CBR_CFR) {
+			encoder->rc = *rate_control;
+			ddl_set_default_enc_rc_params(encoder);
+			vcd_status = VCD_S_SUCCESS;
+		}
+
+	}
+	break;
+	case VCD_I_SHORT_HEADER:
+		if (sizeof(struct vcd_property_short_header) ==
+			property_hdr->sz &&
+			encoder->codec.codec ==
+			VCD_CODEC_MPEG4) {
+			encoder->short_header =
+			*(struct vcd_property_short_header *)
+				property_value;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_VOP_TIMING:
+	{
+		struct vcd_property_vop_timing *vop_time =
+			(struct vcd_property_vop_timing *)
+				property_value;
+
+		if ((sizeof(struct vcd_property_vop_timing) ==
+			property_hdr->sz) &&
+			(encoder->frame_rate.fps_numerator <=
+			vop_time->vop_time_resolution) &&
+			(encoder->codec.codec == VCD_CODEC_MPEG4)) {
+			encoder->vop_timing = *vop_time;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_HEADER_EXTENSION:
+		if (sizeof(u32) == property_hdr->sz &&
+			encoder->codec.codec == VCD_CODEC_MPEG4) {
+			encoder->hdr_ext_control = *(u32 *)property_value;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_ENTROPY_CTRL:
+	{
+		struct vcd_property_entropy_control *entropy_control =
+			(struct vcd_property_entropy_control *)
+			property_value;
+		if (sizeof(struct vcd_property_entropy_control) ==
+			property_hdr->sz &&
+			encoder->codec.codec == VCD_CODEC_H264 &&
+			entropy_control->entropy_sel >=
+			VCD_ENTROPY_SEL_CAVLC &&
+			entropy_control->entropy_sel <=
+			VCD_ENTROPY_SEL_CABAC) {
+			if ((entropy_control->entropy_sel ==
+			     VCD_ENTROPY_SEL_CABAC) &&
+			     (encoder->entropy_control.cabac_model ==
+			     VCD_CABAC_MODEL_NUMBER_1 ||
+			     encoder->entropy_control.cabac_model ==
+			     VCD_CABAC_MODEL_NUMBER_2)) {
+				vcd_status = VCD_ERR_ILLEGAL_PARM;
+			} else {
+				encoder->entropy_control = *entropy_control;
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+	}
+	break;
+	case VCD_I_DEBLOCKING:
+	{
+		struct vcd_property_db_config *db_config =
+			(struct vcd_property_db_config *) property_value;
+		if (sizeof(struct vcd_property_db_config) ==
+			property_hdr->sz  &&
+			encoder->codec.codec == VCD_CODEC_H264 &&
+			db_config->db_config >=
+			VCD_DB_ALL_BLOCKING_BOUNDARY &&
+			db_config->db_config <=
+			VCD_DB_SKIP_SLICE_BOUNDARY) {
+			encoder->db_control = *db_config;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_QP_RANGE:
+	{
+		struct vcd_property_qp_range *qp =
+			(struct vcd_property_qp_range *)property_value;
+
+		if ((sizeof(struct vcd_property_qp_range) ==
+			property_hdr->sz) && (qp->min_qp <=
+			qp->max_qp) && ((encoder->codec.codec ==
+			VCD_CODEC_H264 && qp->max_qp <= DDL_MAX_H264_QP) ||
+			(qp->max_qp <= DDL_MAX_MPEG4_QP))) {
+			encoder->qp_range = *qp;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_SESSION_QP:
+	{
+		struct vcd_property_session_qp *qp =
+			(struct vcd_property_session_qp *)property_value;
+		if ((sizeof(struct vcd_property_session_qp) ==
+			property_hdr->sz) &&
+			(qp->i_frame_qp >= encoder->qp_range.min_qp) &&
+			(qp->i_frame_qp <= encoder->qp_range.max_qp) &&
+			(qp->p_frame_qp >= encoder->qp_range.min_qp) &&
+			(qp->p_frame_qp <= encoder->qp_range.max_qp)) {
+			encoder->session_qp = *qp;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_RC_LEVEL_CONFIG:
+	{
+		struct vcd_property_rc_level *rc_level =
+			(struct vcd_property_rc_level *) property_value;
+		if (sizeof(struct vcd_property_rc_level) ==
+			property_hdr->sz &&
+			(encoder->rc.rate_control >=
+			VCD_RATE_CONTROL_VBR_VFR ||
+			encoder->rc.rate_control <=
+			VCD_RATE_CONTROL_CBR_VFR) &&
+			(!rc_level->mb_level_rc ||
+			encoder->codec.codec == VCD_CODEC_H264)) {
+			encoder->rc_level = *rc_level;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_FRAME_LEVEL_RC:
+	{
+		struct vcd_property_frame_level_rc_params
+			*frame_level_rc =
+			(struct vcd_property_frame_level_rc_params *)
+			property_value;
+		if ((sizeof(struct vcd_property_frame_level_rc_params) ==
+			property_hdr->sz) &&
+			(frame_level_rc->reaction_coeff) &&
+			(encoder->rc_level.frame_level_rc)) {
+			encoder->frame_level_rc = *frame_level_rc;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_ADAPTIVE_RC:
+		if ((sizeof(struct vcd_property_adaptive_rc_params) ==
+			property_hdr->sz) &&
+			(encoder->codec.codec == VCD_CODEC_H264) &&
+			(encoder->rc_level.mb_level_rc)) {
+			encoder->adaptive_rc =
+				*(struct vcd_property_adaptive_rc_params *)
+				property_value;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_BUFFER_FORMAT:
+	{
+		struct vcd_property_buffer_format *buffer_format =
+			(struct vcd_property_buffer_format *)
+			property_value;
+
+		if (sizeof(struct vcd_property_buffer_format) ==
+			property_hdr->sz &&
+			((buffer_format->buffer_format ==
+			VCD_BUFFER_FORMAT_NV12_16M2KA) ||
+			(VCD_BUFFER_FORMAT_TILE_4x2 ==
+			buffer_format->buffer_format))) {
+			if (buffer_format->buffer_format !=
+				encoder->buf_format.buffer_format) {
+				encoder->buf_format = *buffer_format;
+				ddl_set_default_encoder_buffer_req(encoder);
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case DDL_I_INPUT_BUF_REQ:
+	{
+		struct vcd_buffer_requirement *buffer_req =
+			(struct vcd_buffer_requirement *)property_value;
+		if (sizeof(struct vcd_buffer_requirement) ==
+			property_hdr->sz && (ddl_valid_buffer_requirement(
+			&encoder->input_buf_req, buffer_req))) {
+			encoder->client_input_buf_req = *buffer_req;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case DDL_I_OUTPUT_BUF_REQ:
+	{
+		struct vcd_buffer_requirement *buffer_req =
+			(struct vcd_buffer_requirement *)property_value;
+		if (sizeof(struct vcd_buffer_requirement) ==
+			property_hdr->sz && (ddl_valid_buffer_requirement(
+			&encoder->output_buf_req, buffer_req))) {
+			encoder->client_output_buf_req = *buffer_req;
+			encoder->client_output_buf_req.sz =
+				DDL_ALIGN(buffer_req->sz,
+				DDL_KILO_BYTE(4));
+			DDL_MSG_LOW("%s encoder->client_output_buf_req.sz"
+				"  = %d\n", __func__,
+				encoder->client_output_buf_req.sz);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_RECON_BUFFERS:
+	{
+		int index, index_hw_bufs = -1;
+		struct vcd_property_enc_recon_buffer *recon_buffers =
+			(struct vcd_property_enc_recon_buffer *)property_value;
+		for (index = 0; index < 4; index++) {
+			if (!encoder->hw_bufs.dpb_y[index].
+				align_physical_addr) {
+					index_hw_bufs = index;
+				break;
+			} else
+				continue;
+		}
+		if (index_hw_bufs == -1) {
+			DDL_MSG_HIGH("ERROR: value of index_hw_bufs");
+			vcd_status = VCD_ERR_ILLEGAL_PARM;
+		} else {
+			if (property_hdr->sz == sizeof(struct
+				vcd_property_enc_recon_buffer)) {
+				encoder->hw_bufs.dpb_y[index_hw_bufs].
+				align_physical_addr =
+					recon_buffers->dev_addr;
+				encoder->hw_bufs.dpb_y[index_hw_bufs].
+				align_virtual_addr =
+					recon_buffers->kernel_virtual_addr;
+				encoder->hw_bufs.dpb_y[index_hw_bufs].
+				buffer_size = recon_buffers->buffer_size;
+				encoder->hw_bufs.dpb_c[index_hw_bufs].
+				align_physical_addr =
+				recon_buffers->dev_addr +
+					ddl_get_yuv_buf_size(
+						encoder->frame_size.width,
+						encoder->frame_size.height,
+						DDL_YUV_BUF_TYPE_TILE);
+				encoder->hw_bufs.dpb_c[index_hw_bufs].
+					align_virtual_addr =
+					recon_buffers->kernel_virtual_addr +
+					recon_buffers->ysize;
+				DDL_MSG_LOW("Y::KVirt: %p,KPhys: %p"
+							"UV::KVirt: %p,KPhys: %p\n",
+				encoder->hw_bufs.dpb_y[index_hw_bufs].
+				align_virtual_addr,
+				encoder->hw_bufs.dpb_y[index_hw_bufs].
+				align_physical_addr,
+				encoder->hw_bufs.dpb_c[index_hw_bufs].
+				align_virtual_addr,
+				encoder->hw_bufs.dpb_c[index_hw_bufs].
+				align_physical_addr);
+				vcd_status = VCD_S_SUCCESS;
+				}
+		}
+	}
+	break;
+	case VCD_I_FREE_RECON_BUFFERS:
+	{
+		memset(&encoder->hw_bufs.dpb_y, 0,
+			sizeof(struct ddl_buf_addr) * 4);
+		memset(&encoder->hw_bufs.dpb_c, 0,
+			sizeof(struct ddl_buf_addr) * 4);
+		vcd_status = VCD_S_SUCCESS;
+		break;
+	}
+	case VCD_I_METADATA_ENABLE:
+	case VCD_I_METADATA_HEADER:
+		DDL_MSG_LOW("Meta Data Interface is Requested");
+		if (!res_trk_check_for_sec_session()) {
+			if (!encoder->slice_delivery_info.enable) {
+				vcd_status = ddl_set_metadata_params(ddl,
+						property_hdr, property_value);
+			} else {
+				DDL_MSG_ERROR("Ignoring meta data settting in "
+					"slice mode: %s\n", __func__);
+				vcd_status = VCD_S_SUCCESS;
+			}
+		} else {
+			DDL_MSG_ERROR("Meta Data Interface is not "
+				"supported in secure session");
+			vcd_status = VCD_ERR_ILLEGAL_OP;
+		}
+	break;
+	case VCD_I_META_BUFFER_MODE:
+		vcd_status = VCD_S_SUCCESS;
+		break;
+	case VCD_I_ENABLE_SPS_PPS_FOR_IDR:
+	{
+		struct vcd_property_sps_pps_for_idr_enable *sps_pps =
+		(struct vcd_property_sps_pps_for_idr_enable *) property_value;
+
+		if ((sizeof(struct vcd_property_sps_pps_for_idr_enable)) ==
+		property_hdr->sz) {
+			DDL_MSG_LOW("SPS PPS generation for IDR Encode "
+				"is Requested");
+			encoder->sps_pps.sps_pps_for_idr_enable_flag =
+			sps_pps->sps_pps_for_idr_enable_flag;
+			vcd_status = VCD_S_SUCCESS;
+		}
+		break;
+	}
+	case VCD_I_SLICE_DELIVERY_MODE:
+	{
+		size_t output_buf_size;
+		u32 num_mb, num_slices;
+		struct vcd_property_hdr slice_property_hdr;
+		struct vcd_property_meta_data_enable slice_meta_data;
+		DDL_MSG_HIGH("Set property VCD_I_SLICE_DELIVERY_MODE\n");
+		if (sizeof(u32) == property_hdr->sz &&
+			encoder->codec.codec == VCD_CODEC_H264 &&
+			encoder->multi_slice.m_slice_sel
+				 == VCD_MSLICE_BY_MB_COUNT &&
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+			encoder->slice_delivery_info.enable
+				= *(u32 *)property_value;
+			DDL_MSG_HIGH("set encoder->slice_delivery_mode = %u\n",
+				encoder->slice_delivery_info.enable);
+			output_buf_size =
+				encoder->client_output_buf_req.sz;
+			num_mb = DDL_NO_OF_MB(encoder->frame_size.width,
+					encoder->frame_size.height);
+			num_slices = num_mb/
+				encoder->multi_slice.m_slice_size;
+			num_slices = ((num_mb - num_slices *
+				encoder->multi_slice.m_slice_size) > 0)
+				? (num_slices + 1) : num_slices;
+			encoder->slice_delivery_info.num_slices =
+				num_slices;
+			if (num_slices <= DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH) {
+				DDL_MSG_HIGH("%s: currently slice info "
+					"metadata is not supported when slice "
+					"delivery mode is enabled. hence "
+					"disabling slice info metadata.\n",
+					__func__);
+				slice_property_hdr.prop_id =
+					VCD_I_METADATA_ENABLE;
+				slice_property_hdr.sz =
+					sizeof(struct \
+					vcd_property_meta_data_enable);
+				ddl_get_metadata_params(ddl,
+						&slice_property_hdr,
+						&slice_meta_data);
+				slice_meta_data.meta_data_enable_flag
+					&= ~VCD_METADATA_ENC_SLICE;
+				ddl_set_metadata_params(ddl,
+						&slice_property_hdr,
+						&slice_meta_data);
+				encoder->client_output_buf_req.min_count =
+				((DDL_ENC_SLICE_BATCH_FACTOR * num_slices + 2)
+				> DDL_MAX_BUFFER_COUNT)
+				? DDL_MAX_BUFFER_COUNT :
+				(DDL_ENC_SLICE_BATCH_FACTOR * num_slices + 2);
+				output_buf_size =
+				encoder->client_output_buf_req.sz/num_slices;
+				encoder->client_output_buf_req.sz =
+				DDL_ALIGN(output_buf_size, DDL_KILO_BYTE(4));
+				encoder->output_buf_req =
+				encoder->client_output_buf_req;
+				DDL_MSG_HIGH("%s num_mb = %u num_slices = %u "
+				"output_buf_count = %u "
+				"output_buf_size = %u aligned size = %u\n",
+				__func__, num_mb, num_slices,
+				encoder->client_output_buf_req.min_count,
+				output_buf_size,
+				encoder->client_output_buf_req.sz);
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+		break;
+	}
+	case VCD_REQ_PERF_LEVEL:
+		vcd_status = VCD_S_SUCCESS;
+		break;
+	default:
+		DDL_MSG_ERROR("INVALID ID %d\n", (int)property_hdr->prop_id);
+		vcd_status = VCD_ERR_ILLEGAL_OP;
+	break;
+	}
+	return vcd_status;
+}
+
+static u32 ddl_get_dec_property(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	struct vcd_property_frame_size *fz_size;
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+	DDL_MSG_HIGH("property_hdr->prop_id:%x\n", property_hdr->prop_id);
+	switch (property_hdr->prop_id) {
+	case VCD_I_FRAME_SIZE:
+		if (sizeof(struct vcd_property_frame_size) ==
+			property_hdr->sz) {
+			ddl_calculate_stride(&decoder->client_frame_size,
+				!decoder->progressive_only);
+			fz_size =
+			&decoder->client_frame_size;
+			fz_size->stride =
+			DDL_TILE_ALIGN(fz_size->width,
+				DDL_TILE_ALIGN_WIDTH);
+			fz_size->scan_lines =
+			DDL_TILE_ALIGN(fz_size->height,
+				DDL_TILE_ALIGN_HEIGHT);
+			*(struct vcd_property_frame_size *)
+				property_value =
+					decoder->client_frame_size;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_PROFILE:
+		if (sizeof(struct vcd_property_profile) ==
+			property_hdr->sz) {
+			*(struct vcd_property_profile *)property_value =
+				decoder->profile;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_LEVEL:
+		if (sizeof(struct vcd_property_level) ==
+			property_hdr->sz) {
+			*(struct vcd_property_level *)property_value =
+				decoder->level;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_PROGRESSIVE_ONLY:
+		if (sizeof(u32) == property_hdr->sz) {
+			*(u32 *)property_value =
+				decoder->progressive_only;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_INPUT_BUF_REQ:
+		if (sizeof(struct vcd_buffer_requirement) ==
+			property_hdr->sz) {
+			*(struct vcd_buffer_requirement *)
+				property_value =
+					decoder->client_input_buf_req;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_OUTPUT_BUF_REQ:
+		if (sizeof(struct vcd_buffer_requirement) ==
+			property_hdr->sz) {
+				*(struct vcd_buffer_requirement *)
+			property_value = decoder->client_output_buf_req;
+				vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_CODEC:
+	if (sizeof(struct vcd_property_codec) ==
+		property_hdr->sz) {
+			*(struct vcd_property_codec *) property_value =
+				decoder->codec;
+			vcd_status = VCD_S_SUCCESS;
+	}
+	break;
+	case VCD_I_BUFFER_FORMAT:
+		if (sizeof(struct vcd_property_buffer_format) ==
+			property_hdr->sz) {
+			*(struct vcd_property_buffer_format *)
+				property_value = decoder->buf_format;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_POST_FILTER:
+		if (sizeof(struct vcd_property_post_filter) ==
+			property_hdr->sz) {
+			*(struct vcd_property_post_filter *)
+				property_value =
+					decoder->post_filter;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_SEQHDR_ALIGN_BYTES:
+		if (sizeof(u32) == property_hdr->sz) {
+			*(u32 *)property_value =
+				DDL_LINEAR_BUFFER_ALIGN_BYTES;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_FRAME_PROC_UNITS:
+		if (sizeof(u32) == property_hdr->sz) {
+			if (!decoder->progressive_only &&
+				(decoder->client_frame_size.width *
+				 decoder->client_frame_size.height) <=
+				DDL_FRAME_VGA_SIZE) {
+				*(u32 *) property_value = DDL_NO_OF_MB(
+					DDL_FRAME_720P_WIDTH,
+					DDL_FRAME_720P_HEIGHT);
+			} else {
+				*(u32 *) property_value = DDL_NO_OF_MB(
+					decoder->client_frame_size.width,
+					decoder->client_frame_size.height);
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_DPB_RETRIEVE:
+		if (sizeof(struct ddl_frame_data_tag) ==
+			property_hdr->sz) {
+			vcd_status = ddl_decoder_dpb_transact(decoder,
+				(struct ddl_frame_data_tag *)
+				property_value, DDL_DPB_OP_RETRIEVE);
+		}
+	break;
+	case VCD_I_GET_H264_MV_SIZE:
+		if (property_hdr->sz == sizeof(struct
+			vcd_property_buffer_size)) {
+			struct vcd_property_buffer_size *mv_size =
+			(struct vcd_property_buffer_size *) property_value;
+			mv_size->size = ddl_get_yuv_buf_size(mv_size->width,
+				mv_size->height, DDL_YUV_BUF_TYPE_TILE);
+			mv_size->alignment = DDL_TILE_BUFFER_ALIGN_BYTES;
+			DDL_MSG_LOW("w: %d, h: %d, S: %d, "
+						"A: %d", mv_size->width,
+						mv_size->height, mv_size->size,
+						mv_size->alignment);
+			vcd_status = VCD_S_SUCCESS;
+		}
+		break;
+	case VCD_I_OUTPUT_ORDER:
+		{
+			if (sizeof(u32) == property_hdr->sz) {
+				*(u32 *)property_value = decoder->output_order;
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+		break;
+	case VCD_I_METADATA_ENABLE:
+	case VCD_I_METADATA_HEADER:
+		DDL_MSG_ERROR("Meta Data Interface is Requested");
+		vcd_status = ddl_get_metadata_params(ddl, property_hdr,
+			property_value);
+		vcd_status = VCD_S_SUCCESS;
+	break;
+	case VCD_I_CONT_ON_RECONFIG:
+		if (sizeof(u32) == property_hdr->sz) {
+			*(u32 *)property_value = decoder->cont_mode;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_DISABLE_DMX_SUPPORT:
+		if (sizeof(u32) == property_hdr->sz) {
+			*(u32 *)property_value = res_trk_get_disable_dmx();
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_DISABLE_DMX:
+		if (sizeof(u32) == property_hdr->sz) {
+			*(u32 *)property_value = decoder->dmx_disable;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	default:
+		vcd_status = VCD_ERR_ILLEGAL_OP;
+	break;
+	}
+	return vcd_status;
+}
+
+static u32 ddl_get_enc_property(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	struct ddl_encoder_data *encoder = &ddl->codec_data.encoder;
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+
+	switch (property_hdr->prop_id) {
+	case VCD_I_CODEC:
+		if (sizeof(struct vcd_property_codec) ==
+			property_hdr->sz) {
+			*(struct vcd_property_codec *) property_value =
+				encoder->codec;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_FRAME_SIZE:
+		if (sizeof(struct vcd_property_frame_size) ==
+			property_hdr->sz) {
+			*(struct vcd_property_frame_size *)
+				property_value = encoder->frame_size;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_FRAME_RATE:
+		if (sizeof(struct vcd_property_frame_rate) ==
+			property_hdr->sz) {
+			*(struct vcd_property_frame_rate *)
+				property_value = encoder->frame_rate;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_TARGET_BITRATE:
+		if (sizeof(struct vcd_property_target_bitrate) ==
+			property_hdr->sz) {
+			*(struct vcd_property_target_bitrate *)
+				property_value = encoder->target_bit_rate;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_RATE_CONTROL:
+		if (sizeof(struct vcd_property_rate_control) ==
+			property_hdr->sz) {
+			*(struct vcd_property_rate_control *)
+				property_value = encoder->rc;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_PROFILE:
+		if (sizeof(struct vcd_property_profile) ==
+			property_hdr->sz) {
+			*(struct vcd_property_profile *) property_value =
+				encoder->profile;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_LEVEL:
+		if (sizeof(struct vcd_property_level) ==
+			property_hdr->sz) {
+			*(struct vcd_property_level *) property_value =
+				encoder->level;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_MULTI_SLICE:
+		if (sizeof(struct vcd_property_multi_slice) ==
+			property_hdr->sz) {
+			*(struct vcd_property_multi_slice *)
+				property_value = encoder->multi_slice;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_SEQ_HEADER:
+	{
+		struct vcd_sequence_hdr *seq_hdr =
+			(struct vcd_sequence_hdr *) property_value;
+
+		if (!encoder->seq_header_length) {
+			seq_hdr->sequence_header_len =
+				encoder->seq_header_length;
+			vcd_status = VCD_ERR_NO_SEQ_HDR;
+		} else if (sizeof(struct vcd_sequence_hdr) ==
+			property_hdr->sz &&
+			encoder->seq_header_length <=
+			seq_hdr->sequence_header_len) {
+			memcpy(seq_hdr->sequence_header,
+				encoder->seq_header.align_virtual_addr,
+				encoder->seq_header_length);
+			seq_hdr->sequence_header_len =
+				encoder->seq_header_length;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case DDL_I_SEQHDR_PRESENT:
+		if (sizeof(u32) == property_hdr->sz) {
+			if ((encoder->codec.codec ==
+				VCD_CODEC_MPEG4 &&
+				!encoder->short_header.short_header) ||
+				encoder->codec.codec == VCD_CODEC_H264)
+				*(u32 *) property_value = 0x1;
+			else
+				*(u32 *) property_value = 0x0;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_VOP_TIMING:
+		if (sizeof(struct vcd_property_vop_timing) ==
+			property_hdr->sz) {
+			*(struct vcd_property_vop_timing *)
+				property_value = encoder->vop_timing;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_SHORT_HEADER:
+		if (sizeof(struct vcd_property_short_header) ==
+			property_hdr->sz) {
+			if (encoder->codec.codec == VCD_CODEC_MPEG4) {
+				*(struct vcd_property_short_header *)
+					property_value =
+						encoder->short_header;
+				vcd_status = VCD_S_SUCCESS;
+			} else
+				vcd_status = VCD_ERR_ILLEGAL_OP;
+		}
+	break;
+	case VCD_I_ENTROPY_CTRL:
+		if (sizeof(struct vcd_property_entropy_control) ==
+			property_hdr->sz) {
+			if (encoder->codec.codec == VCD_CODEC_H264) {
+				*(struct vcd_property_entropy_control *)
+					property_value =
+						encoder->entropy_control;
+				vcd_status = VCD_S_SUCCESS;
+			} else
+				vcd_status = VCD_ERR_ILLEGAL_OP;
+		}
+	break;
+	case VCD_I_DEBLOCKING:
+		if (sizeof(struct vcd_property_db_config) ==
+			property_hdr->sz) {
+			if (encoder->codec.codec == VCD_CODEC_H264) {
+				*(struct vcd_property_db_config *)
+					property_value =
+						encoder->db_control;
+				vcd_status = VCD_S_SUCCESS;
+			} else
+				vcd_status = VCD_ERR_ILLEGAL_OP;
+		}
+	break;
+	case VCD_I_INTRA_PERIOD:
+		if (sizeof(struct vcd_property_i_period) ==
+			property_hdr->sz) {
+			*(struct vcd_property_i_period *)
+				property_value = encoder->i_period;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_QP_RANGE:
+		if (sizeof(struct vcd_property_qp_range) ==
+			property_hdr->sz) {
+			*(struct vcd_property_qp_range *)
+				property_value = encoder->qp_range;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_SESSION_QP:
+		if (sizeof(struct vcd_property_session_qp) ==
+			property_hdr->sz) {
+			*(struct vcd_property_session_qp *)
+				property_value = encoder->session_qp;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_RC_LEVEL_CONFIG:
+		if (sizeof(struct vcd_property_rc_level) ==
+			property_hdr->sz) {
+			*(struct vcd_property_rc_level *)
+				property_value = encoder->rc_level;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_FRAME_LEVEL_RC:
+		if (sizeof(struct vcd_property_frame_level_rc_params) ==
+			property_hdr->sz) {
+			*(struct vcd_property_frame_level_rc_params *)
+			property_value = encoder->frame_level_rc;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_ADAPTIVE_RC:
+		if (sizeof(struct vcd_property_adaptive_rc_params) ==
+			property_hdr->sz) {
+			*(struct vcd_property_adaptive_rc_params *)
+				property_value = encoder->adaptive_rc;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_INTRA_REFRESH:
+		if (sizeof(struct vcd_property_intra_refresh_mb_number) ==
+			property_hdr->sz) {
+			*(struct vcd_property_intra_refresh_mb_number *)
+				property_value = encoder->intra_refresh;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_INPUT_BUF_REQ:
+		if (sizeof(struct vcd_buffer_requirement) ==
+			property_hdr->sz) {
+				*(struct vcd_buffer_requirement *)
+			property_value = encoder->client_input_buf_req;
+				vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_OUTPUT_BUF_REQ:
+		if (sizeof(struct vcd_buffer_requirement) ==
+			property_hdr->sz) {
+				*(struct vcd_buffer_requirement *)
+			property_value = encoder->client_output_buf_req;
+			DDL_MSG_LOW("%s encoder->client_output_buf_req = %d\n",
+				 __func__,
+				encoder->client_output_buf_req.sz);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_BUFFER_FORMAT:
+		if (sizeof(struct vcd_property_buffer_format) ==
+			property_hdr->sz) {
+			*(struct vcd_property_buffer_format *)
+			property_value = encoder->buf_format;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case DDL_I_FRAME_PROC_UNITS:
+		if (sizeof(u32) == property_hdr->sz &&
+			encoder->frame_size.width &&
+			encoder->frame_size.height) {
+			*(u32 *)property_value = DDL_NO_OF_MB(
+				encoder->frame_size.width,
+				encoder->frame_size.height);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_HEADER_EXTENSION:
+		if (sizeof(u32) == property_hdr->sz &&
+			encoder->codec.codec == VCD_CODEC_MPEG4) {
+			*(u32 *) property_value =
+				encoder->hdr_ext_control;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_GET_RECON_BUFFER_SIZE:
+	{
+		u32 ysize, uvsize;
+		if (property_hdr->sz == sizeof(struct
+			vcd_property_buffer_size)) {
+			struct vcd_property_buffer_size *recon_buff_size =
+			(struct vcd_property_buffer_size *) property_value;
+
+			ysize = ddl_get_yuv_buf_size(recon_buff_size->width,
+				recon_buff_size->height, DDL_YUV_BUF_TYPE_TILE);
+			uvsize = ddl_get_yuv_buf_size(recon_buff_size->width,
+				recon_buff_size->height/2,
+				DDL_YUV_BUF_TYPE_TILE);
+			recon_buff_size->size = ysize + uvsize;
+			recon_buff_size->alignment =
+				DDL_TILE_BUFFER_ALIGN_BYTES;
+			DDL_MSG_LOW("w: %d, h: %d, S: %d, A: %d",
+			recon_buff_size->width, recon_buff_size->height,
+			recon_buff_size->size, recon_buff_size->alignment);
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_METADATA_ENABLE:
+	case VCD_I_METADATA_HEADER:
+		DDL_MSG_ERROR("Meta Data Interface is Requested");
+		vcd_status = ddl_get_metadata_params(ddl, property_hdr,
+			property_value);
+		vcd_status = VCD_S_SUCCESS;
+	break;
+	case VCD_I_ENABLE_SPS_PPS_FOR_IDR:
+		if (sizeof(struct vcd_property_sps_pps_for_idr_enable) ==
+			property_hdr->sz) {
+			*(struct vcd_property_sps_pps_for_idr_enable *)
+				property_value = encoder->sps_pps;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_SLICE_DELIVERY_MODE:
+		if (sizeof(struct vcd_property_slice_delivery_info) ==
+			property_hdr->sz) {
+			*(struct vcd_property_slice_delivery_info *)
+				property_value = encoder->slice_delivery_info;
+			vcd_status = VCD_S_SUCCESS;
+		}
+		break;
+	default:
+		vcd_status = VCD_ERR_ILLEGAL_OP;
+		break;
+	}
+	return vcd_status;
+}
+
+static u32 ddl_set_enc_dynamic_property(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	struct ddl_encoder_data *encoder = &ddl->codec_data.encoder;
+	u32  vcd_status = VCD_ERR_ILLEGAL_PARM;
+	u32  dynamic_prop_change = 0x0;
+
+	switch (property_hdr->prop_id) {
+	case VCD_I_REQ_IFRAME:
+		if (sizeof(struct vcd_property_req_i_frame) ==
+			property_hdr->sz) {
+			dynamic_prop_change |= DDL_ENC_REQ_IFRAME;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
+	case VCD_I_TARGET_BITRATE:
+	{
+		struct vcd_property_target_bitrate *bitrate =
+			(struct vcd_property_target_bitrate *)property_value;
+
+		if (sizeof(struct vcd_property_target_bitrate) ==
+			property_hdr->sz && bitrate->target_bitrate &&
+			bitrate->target_bitrate <= DDL_MAX_BIT_RATE) {
+			encoder->target_bit_rate = *bitrate;
+			dynamic_prop_change = DDL_ENC_CHANGE_BITRATE;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_INTRA_PERIOD:
+	{
+		struct vcd_property_i_period *i_period =
+			(struct vcd_property_i_period *)property_value;
+
+		if (sizeof(struct vcd_property_i_period) ==
+			property_hdr->sz) {
+			encoder->i_period = *i_period;
+			dynamic_prop_change = DDL_ENC_CHANGE_IPERIOD;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_FRAME_RATE:
+	{
+		struct vcd_property_frame_rate *frame_rate =
+			(struct vcd_property_frame_rate *)
+			property_value;
+		if (sizeof(struct vcd_property_frame_rate) ==
+			property_hdr->sz &&
+			frame_rate->fps_denominator &&
+			frame_rate->fps_numerator &&
+			frame_rate->fps_denominator <=
+			frame_rate->fps_numerator) {
+			encoder->frame_rate = *frame_rate;
+			dynamic_prop_change = DDL_ENC_CHANGE_FRAMERATE;
+			if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) &&
+				(encoder->codec.codec != VCD_CODEC_MPEG4 ||
+				encoder->short_header.short_header)) {
+				ddl_set_default_enc_vop_timing(encoder);
+			}
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	case VCD_I_INTRA_REFRESH:
+	{
+		struct vcd_property_intra_refresh_mb_number
+			*intra_refresh_mb_num =
+			(struct vcd_property_intra_refresh_mb_number *)
+			property_value;
+		u32 frame_mb_num = DDL_NO_OF_MB(encoder->frame_size.width,
+			encoder->frame_size.height);
+
+		if ((sizeof(struct vcd_property_intra_refresh_mb_number) ==
+			property_hdr->sz) &&
+			(intra_refresh_mb_num->cir_mb_number <= frame_mb_num)) {
+			encoder->intra_refresh = *intra_refresh_mb_num;
+			dynamic_prop_change = DDL_ENC_CHANGE_CIR;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	default:
+		vcd_status = VCD_ERR_ILLEGAL_OP;
+		break;
+	}
+
+	if (!vcd_status && (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)
+		|| DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)))
+		encoder->dynamic_prop_change |= dynamic_prop_change;
+
+	return vcd_status;
+}
+
+void ddl_set_default_dec_property(struct ddl_client_context *ddl)
+{
+	struct ddl_decoder_data *decoder =
+		&(ddl->codec_data.decoder);
+
+	if (decoder->codec.codec >= VCD_CODEC_MPEG2 &&
+		decoder->codec.codec <=  VCD_CODEC_XVID)
+		decoder->post_filter.post_filter = false;
+	else
+		decoder->post_filter.post_filter = false;
+	decoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_TILE_4x2;
+	decoder->client_frame_size.height = VCD_DDL_TEST_DEFAULT_HEIGHT;
+	decoder->client_frame_size.width  = VCD_DDL_TEST_DEFAULT_WIDTH;
+	decoder->client_frame_size.stride = VCD_DDL_TEST_DEFAULT_WIDTH;
+	decoder->client_frame_size.scan_lines = VCD_DDL_TEST_DEFAULT_HEIGHT;
+	decoder->progressive_only = 1;
+	decoder->idr_only_decoding = false;
+	decoder->output_order = VCD_DEC_ORDER_DISPLAY;
+	decoder->field_needed_for_prev_ip = 0;
+	decoder->cont_mode = 0;
+	decoder->reconfig_detected = false;
+	decoder->dmx_disable = false;
+	ddl_set_default_metadata_flag(ddl);
+	ddl_set_default_decoder_buffer_req(decoder, true);
+}
+
+static void ddl_set_default_enc_property(struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+
+	ddl_set_default_enc_profile(encoder);
+	ddl_set_default_enc_level(encoder);
+	encoder->rc.rate_control = VCD_RATE_CONTROL_VBR_VFR;
+	ddl_set_default_enc_rc_params(encoder);
+	ddl_set_default_enc_intra_period(encoder);
+	encoder->intra_refresh.cir_mb_number = 0;
+	ddl_set_default_enc_vop_timing(encoder);
+	encoder->multi_slice.m_slice_sel = VCD_MSLICE_OFF;
+	encoder->multi_slice.m_slice_size = 0;
+	ddl->b_count = 0;
+	encoder->short_header.short_header    = false;
+	encoder->entropy_control.entropy_sel  = VCD_ENTROPY_SEL_CAVLC;
+	encoder->entropy_control.cabac_model  = VCD_CABAC_MODEL_NUMBER_0;
+	encoder->db_control.db_config         =
+		VCD_DB_ALL_BLOCKING_BOUNDARY;
+	encoder->db_control.slice_alpha_offset = 0;
+	encoder->db_control.slice_beta_offset = 0;
+	encoder->recon_buf_format.buffer_format =
+		VCD_BUFFER_FORMAT_TILE_1x1;
+	encoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12_16M2KA;
+	encoder->hdr_ext_control = 0;
+	encoder->mb_info_enable  = false;
+	encoder->num_references_for_p_frame = DDL_MIN_NUM_REF_FOR_P_FRAME;
+	if (encoder->codec.codec == VCD_CODEC_MPEG4)
+		encoder->closed_gop = true;
+	ddl_set_default_metadata_flag(ddl);
+	ddl_set_default_encoder_buffer_req(encoder);
+	encoder->slice_delivery_info.enable = 0;
+	encoder->slice_delivery_info.num_slices = 0;
+	encoder->slice_delivery_info.num_slices_enc = 0;
+}
+
+static void ddl_set_default_enc_profile(struct ddl_encoder_data *encoder)
+{
+	enum vcd_codec codec = encoder->codec.codec;
+
+	if (codec == VCD_CODEC_MPEG4)
+		encoder->profile.profile = VCD_PROFILE_MPEG4_SP;
+	else if (codec == VCD_CODEC_H264)
+		encoder->profile.profile = VCD_PROFILE_H264_BASELINE;
+	else
+		encoder->profile.profile = VCD_PROFILE_H263_BASELINE;
+}
+
+static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder)
+{
+	enum vcd_codec codec = encoder->codec.codec;
+
+	if (codec == VCD_CODEC_MPEG4)
+		encoder->level.level = VCD_LEVEL_MPEG4_1;
+	else if (codec == VCD_CODEC_H264)
+		encoder->level.level = VCD_LEVEL_H264_1;
+	else
+		encoder->level.level = VCD_LEVEL_H263_10;
+}
+
+static void ddl_set_default_enc_vop_timing(
+	struct ddl_encoder_data *encoder)
+{
+	if (encoder->codec.codec == VCD_CODEC_MPEG4) {
+		encoder->vop_timing.vop_time_resolution =
+			(encoder->frame_rate.fps_numerator << 1) /
+			encoder->frame_rate.fps_denominator;
+	} else
+		encoder->vop_timing.vop_time_resolution =
+			DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE);
+}
+
+static void ddl_set_default_enc_intra_period(
+	struct ddl_encoder_data *encoder)
+{
+	switch (encoder->rc.rate_control) {
+	default:
+	case VCD_RATE_CONTROL_VBR_VFR:
+	case VCD_RATE_CONTROL_VBR_CFR:
+	case VCD_RATE_CONTROL_CBR_VFR:
+	case VCD_RATE_CONTROL_OFF:
+		encoder->i_period.p_frames =
+			((encoder->frame_rate.fps_numerator << 1) /
+			encoder->frame_rate.fps_denominator) - 1;
+	break;
+	case VCD_RATE_CONTROL_CBR_CFR:
+		encoder->i_period.p_frames =
+			((encoder->frame_rate.fps_numerator >> 1) /
+			encoder->frame_rate.fps_denominator) - 1;
+	break;
+	}
+	encoder->i_period.b_frames = DDL_DEFAULT_NUM_OF_B_FRAME;
+}
+
+static void ddl_set_default_enc_rc_params(
+	struct ddl_encoder_data *encoder)
+{
+	enum vcd_codec codec = encoder->codec.codec;
+	encoder->rc_level.frame_level_rc = true;
+	encoder->qp_range.min_qp = 0x1;
+	if (codec == VCD_CODEC_H264) {
+		encoder->qp_range.min_qp = 0x1;
+		encoder->qp_range.max_qp = 0x33;
+		encoder->session_qp.i_frame_qp = 0x14;
+		encoder->session_qp.p_frame_qp = 0x14;
+		encoder->session_qp.b_frame_qp = 0x14;
+		encoder->rc_level.mb_level_rc  = true;
+		encoder->adaptive_rc.disable_activity_region_flag = true;
+		encoder->adaptive_rc.disable_dark_region_as_flag = true;
+		encoder->adaptive_rc.disable_smooth_region_as_flag = true;
+		encoder->adaptive_rc.disable_static_region_as_flag = true;
+	} else {
+		encoder->qp_range.max_qp       = 0x1f;
+		encoder->qp_range.min_qp       = 0x1;
+		encoder->session_qp.i_frame_qp = 0xd;
+		encoder->session_qp.p_frame_qp = 0xd;
+		encoder->session_qp.b_frame_qp = 0xd;
+		encoder->rc_level.frame_level_rc = true;
+		encoder->rc_level.mb_level_rc  = false;
+	}
+	switch (encoder->rc.rate_control) {
+	case VCD_RATE_CONTROL_VBR_CFR:
+		encoder->r_cframe_skip = 0;
+		encoder->frame_level_rc.reaction_coeff = 0x1f4;
+	break;
+	case VCD_RATE_CONTROL_CBR_VFR:
+		encoder->r_cframe_skip = 1;
+		if (codec != VCD_CODEC_H264) {
+			encoder->session_qp.i_frame_qp = 0xf;
+			encoder->session_qp.p_frame_qp = 0xf;
+			encoder->session_qp.b_frame_qp = 0xf;
+		}
+		encoder->frame_level_rc.reaction_coeff = 0x14;
+	break;
+	case VCD_RATE_CONTROL_CBR_CFR:
+		encoder->r_cframe_skip = 0;
+		encoder->frame_level_rc.reaction_coeff = 0x6;
+	break;
+	case VCD_RATE_CONTROL_OFF:
+		encoder->r_cframe_skip = 0;
+		encoder->rc_level.frame_level_rc = false;
+		encoder->rc_level.mb_level_rc = false;
+	break;
+	case VCD_RATE_CONTROL_VBR_VFR:
+	default:
+		encoder->r_cframe_skip = 1;
+		encoder->frame_level_rc.reaction_coeff = 0x1f4;
+	break;
+	}
+}
+
+void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data *encoder)
+{
+	u32 y_cb_cr_size, y_size;
+	memset(&encoder->hw_bufs.dpb_y, 0, sizeof(struct ddl_buf_addr) * 4);
+	memset(&encoder->hw_bufs.dpb_c, 0, sizeof(struct ddl_buf_addr) * 4);
+
+	y_cb_cr_size = ddl_get_yuv_buffer_size(&encoder->frame_size,
+				&encoder->buf_format, false,
+				encoder->hdr.decoding, &y_size);
+	encoder->input_buf_size.size_yuv = y_cb_cr_size;
+	encoder->input_buf_size.size_y   = y_size;
+	encoder->input_buf_size.size_c   = y_cb_cr_size - y_size;
+	memset(&encoder->input_buf_req , 0 ,
+		sizeof(struct vcd_buffer_requirement));
+	encoder->input_buf_req.min_count    = 3;
+	encoder->input_buf_req.actual_count =
+		encoder->input_buf_req.min_count;
+	encoder->input_buf_req.max_count    = DDL_MAX_BUFFER_COUNT;
+	encoder->input_buf_req.sz = y_cb_cr_size;
+	if (encoder->buf_format.buffer_format ==
+		VCD_BUFFER_FORMAT_NV12_16M2KA)
+		encoder->input_buf_req.align =
+			DDL_LINEAR_BUFFER_ALIGN_BYTES;
+	else if (VCD_BUFFER_FORMAT_TILE_4x2 ==
+		encoder->buf_format.buffer_format)
+		encoder->input_buf_req.align = DDL_TILE_BUFFER_ALIGN_BYTES;
+	encoder->client_input_buf_req = encoder->input_buf_req;
+	memset(&encoder->output_buf_req , 0 ,
+		sizeof(struct vcd_buffer_requirement));
+	encoder->output_buf_req.min_count = encoder->i_period.b_frames + 2;
+	encoder->output_buf_req.actual_count =
+		encoder->output_buf_req.min_count + 3;
+	encoder->output_buf_req.max_count    = DDL_MAX_BUFFER_COUNT;
+	encoder->output_buf_req.align	= DDL_LINEAR_BUFFER_ALIGN_BYTES;
+	if (y_cb_cr_size >= VCD_DDL_720P_YUV_BUF_SIZE)
+		y_cb_cr_size = y_cb_cr_size>>1;
+	encoder->output_buf_req.sz =
+		DDL_ALIGN(y_cb_cr_size, DDL_KILO_BYTE(4));
+	ddl_set_default_encoder_metadata_buffer_size(encoder);
+	encoder->client_output_buf_req = encoder->output_buf_req;
+	DDL_MSG_LOW("%s encoder->client_output_buf_req.sz = %d\n",
+		__func__, encoder->client_output_buf_req.sz);
+}
+
+u32 ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder,
+	u32 estimate)
+{
+	struct vcd_property_frame_size *frame_size;
+	struct vcd_buffer_requirement *input_buf_req;
+	struct vcd_buffer_requirement *output_buf_req;
+	u32  min_dpb, y_cb_cr_size;
+
+	if (!decoder->codec.codec)
+		return false;
+	if (estimate) {
+		if (!decoder->cont_mode)
+			min_dpb = ddl_decoder_min_num_dpb(decoder);
+		else
+			min_dpb = 5;
+		frame_size = &decoder->client_frame_size;
+		output_buf_req = &decoder->client_output_buf_req;
+		input_buf_req = &decoder->client_input_buf_req;
+		y_cb_cr_size = ddl_get_yuv_buffer_size(frame_size,
+					&decoder->buf_format,
+					(!decoder->progressive_only),
+					decoder->hdr.decoding, NULL);
+	} else {
+		frame_size = &decoder->frame_size;
+		output_buf_req = &decoder->actual_output_buf_req;
+		input_buf_req = &decoder->actual_input_buf_req;
+		min_dpb = decoder->min_dpb_num;
+		y_cb_cr_size = decoder->y_cb_cr_size;
+	}
+	memset(output_buf_req, 0,
+		sizeof(struct vcd_buffer_requirement));
+	if (!decoder->idr_only_decoding && !decoder->cont_mode)
+		output_buf_req->actual_count = min_dpb + 4;
+	else
+		output_buf_req->actual_count = min_dpb;
+	output_buf_req->min_count = min_dpb;
+	output_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
+	output_buf_req->sz = y_cb_cr_size;
+	DDL_MSG_LOW("output_buf_req->sz : %d", output_buf_req->sz);
+	if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12)
+		output_buf_req->align = DDL_TILE_BUFFER_ALIGN_BYTES;
+	else
+		output_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
+	ddl_set_default_decoder_metadata_buffer_size(decoder, frame_size,
+		output_buf_req);
+
+	decoder->min_output_buf_req = *output_buf_req;
+	memset(input_buf_req, 0,
+		sizeof(struct vcd_buffer_requirement));
+	input_buf_req->min_count = 1;
+	input_buf_req->actual_count = input_buf_req->min_count + 1;
+	input_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
+	input_buf_req->sz = (1024 * 1024 * 2);
+	input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
+	decoder->min_input_buf_req = *input_buf_req;
+	return true;
+}
+
+u32 ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size,
+	struct vcd_property_buffer_format *buf_format,
+	u32 interlace, u32 decoding, u32 *pn_c_offset)
+{
+	struct vcd_property_frame_size frame_sz = *frame_size;
+	u32 total_memory_size = 0, c_offset = 0;
+	ddl_calculate_stride(&frame_sz, interlace);
+	if (buf_format->buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) {
+		u32 component_mem_size, width_round_up;
+		u32 height_round_up, height_chroma = (frame_sz.scan_lines >> 1);
+
+		width_round_up =
+			DDL_ALIGN(frame_sz.stride, DDL_TILE_ALIGN_WIDTH);
+		height_round_up =
+			DDL_ALIGN(frame_sz.scan_lines,
+						   DDL_TILE_ALIGN_HEIGHT);
+		component_mem_size = width_round_up * height_round_up;
+		component_mem_size = DDL_ALIGN(component_mem_size,
+			DDL_TILE_MULTIPLY_FACTOR);
+		c_offset = component_mem_size;
+		total_memory_size = ((component_mem_size +
+					DDL_TILE_BUF_ALIGN_GUARD_BYTES) &
+					DDL_TILE_BUF_ALIGN_MASK);
+		height_round_up = DDL_ALIGN(height_chroma,
+					DDL_TILE_ALIGN_HEIGHT);
+		component_mem_size = width_round_up * height_round_up;
+		component_mem_size = DDL_ALIGN(component_mem_size,
+					DDL_TILE_MULTIPLY_FACTOR);
+		total_memory_size += component_mem_size;
+	} else {
+		if (decoding)
+			total_memory_size = frame_sz.scan_lines *
+						frame_sz.stride;
+		else
+			total_memory_size = frame_sz.height * frame_sz.stride;
+		c_offset = DDL_ALIGN(total_memory_size,
+			DDL_LINEAR_MULTIPLY_FACTOR);
+		total_memory_size = c_offset + DDL_ALIGN(
+			total_memory_size >> 1, DDL_LINEAR_MULTIPLY_FACTOR);
+	}
+	if (pn_c_offset)
+		*pn_c_offset = c_offset;
+	return total_memory_size;
+}
+
+
+void ddl_calculate_stride(struct vcd_property_frame_size *frame_size,
+	u32 interlace)
+{
+	frame_size->stride = DDL_ALIGN(frame_size->width,
+					DDL_LINEAR_ALIGN_WIDTH);
+	if (interlace)
+		frame_size->scan_lines = DDL_ALIGN(frame_size->height,
+						DDL_TILE_ALIGN_HEIGHT);
+	else
+		frame_size->scan_lines = DDL_ALIGN(frame_size->height,
+						DDL_LINEAR_ALIGN_HEIGHT);
+}
+
+
+static u32 ddl_valid_buffer_requirement(struct vcd_buffer_requirement
+	*original_buf_req, struct vcd_buffer_requirement *req_buf_req)
+{
+	u32 status = false;
+
+	if (original_buf_req->max_count >= req_buf_req->actual_count &&
+		original_buf_req->min_count <=
+		req_buf_req->actual_count &&
+		!((original_buf_req->align - (u32)0x1) &
+		req_buf_req->align) &&
+		/*original_buf_req->align <= req_buf_req->align,*/
+		original_buf_req->sz <= req_buf_req->sz)
+		status = true;
+	else {
+		DDL_MSG_ERROR("ddl_valid_buf_req:Failed");
+		DDL_MSG_ERROR("codec_buf_req: min_cnt=%d, mx_cnt=%d, "
+			"align=%d, sz=%d\n", original_buf_req->min_count,
+			original_buf_req->max_count, original_buf_req->align,
+			original_buf_req->sz);
+		DDL_MSG_ERROR("client_buffs: actual_count=%d, align=%d, "
+			"sz=%d\n", req_buf_req->actual_count,
+			req_buf_req->align,	req_buf_req->sz);
+	}
+	return status;
+}
+
+static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder)
+{
+	u32 min_dpb = 0;
+
+	if (decoder->idr_only_decoding) {
+		min_dpb = DDL_MIN_BUFFER_COUNT;
+		if (decoder->post_filter.post_filter)
+			min_dpb *= 2;
+		return min_dpb;
+	}
+
+	switch (decoder->codec.codec) {
+	case VCD_CODEC_H264:
+	{
+		u32 yuv_size_in_mb = DDL_MIN(DDL_NO_OF_MB(
+			decoder->client_frame_size.stride,
+			decoder->client_frame_size.scan_lines),
+			MAX_FRAME_SIZE_L4PT0_MBS);
+		min_dpb = DDL_MIN((MAX_DPB_SIZE_L4PT0_MBS /
+				yuv_size_in_mb), 16);
+		min_dpb += 2;
+	}
+	break;
+	case VCD_CODEC_H263:
+		min_dpb = 3;
+	break;
+	default:
+	case VCD_CODEC_MPEG1:
+	case VCD_CODEC_MPEG2:
+	case VCD_CODEC_MPEG4:
+	case VCD_CODEC_DIVX_3:
+	case VCD_CODEC_DIVX_4:
+	case VCD_CODEC_DIVX_5:
+	case VCD_CODEC_DIVX_6:
+	case VCD_CODEC_XVID:
+	case VCD_CODEC_VC1:
+	case VCD_CODEC_VC1_RCV:
+		min_dpb = 4;
+		if (decoder->post_filter.post_filter)
+			min_dpb *= 2;
+	break;
+	}
+	return min_dpb;
+}
+
+static u32 ddl_set_dec_buffers(struct ddl_decoder_data *decoder,
+	struct ddl_property_dec_pic_buffers *dpb)
+{
+	u32 vcd_status  = VCD_S_SUCCESS, loopc;
+
+
+	for (loopc = 0; !vcd_status &&
+		loopc < dpb->no_of_dec_pic_buf; ++loopc) {
+		if ((!DDL_ADDR_IS_ALIGNED(dpb->dec_pic_buffers[loopc].
+			vcd_frm.physical,
+			decoder->client_output_buf_req.align)) ||
+			(dpb->dec_pic_buffers[loopc].vcd_frm.alloc_len <
+			decoder->client_output_buf_req.sz))
+			vcd_status = VCD_ERR_ILLEGAL_PARM;
+	}
+	if (vcd_status) {
+		DDL_MSG_ERROR("ddl_set_prop:"
+			"Dpb_align_fail_or_alloc_size_small");
+		return vcd_status;
+	}
+	if (decoder->dp_buf.no_of_dec_pic_buf) {
+		kfree(decoder->dp_buf.dec_pic_buffers);
+		decoder->dp_buf.no_of_dec_pic_buf = 0;
+	}
+	decoder->dp_buf.dec_pic_buffers =
+		kmalloc(dpb->no_of_dec_pic_buf *
+			sizeof(struct ddl_frame_data_tag), GFP_KERNEL);
+	if (!decoder->dp_buf.dec_pic_buffers) {
+		DDL_MSG_ERROR("ddl_dec_set_prop:Dpb_container_alloc_failed");
+		return VCD_ERR_ALLOC_FAIL;
+	}
+	decoder->dp_buf.no_of_dec_pic_buf = dpb->no_of_dec_pic_buf;
+	for (loopc = 0; loopc < dpb->no_of_dec_pic_buf; ++loopc)
+		decoder->dp_buf.dec_pic_buffers[loopc] =
+			dpb->dec_pic_buffers[loopc];
+	decoder->dpb_mask.client_mask = 0;
+	decoder->dpb_mask.hw_mask = 0;
+	decoder->dynamic_prop_change = 0;
+	return VCD_S_SUCCESS;
+}
+
+void ddl_set_initial_default_values(struct ddl_client_context *ddl)
+{
+
+	if (ddl->decoding) {
+		ddl->codec_data.decoder.codec.codec = VCD_CODEC_MPEG4;
+		ddl_set_default_dec_property(ddl);
+	} else {
+		struct ddl_encoder_data *encoder =
+			&(ddl->codec_data.encoder);
+		encoder->codec.codec = VCD_CODEC_MPEG4;
+		encoder->target_bit_rate.target_bitrate = 64000;
+		encoder->frame_size.width = VCD_DDL_TEST_DEFAULT_WIDTH;
+		encoder->frame_size.height = VCD_DDL_TEST_DEFAULT_HEIGHT;
+		encoder->frame_size.scan_lines =
+			VCD_DDL_TEST_DEFAULT_HEIGHT;
+		encoder->frame_size.stride = VCD_DDL_TEST_DEFAULT_WIDTH;
+		encoder->frame_rate.fps_numerator = DDL_INITIAL_FRAME_RATE;
+		encoder->frame_rate.fps_denominator = 1;
+		ddl_set_default_enc_property(ddl);
+		encoder->sps_pps.sps_pps_for_idr_enable_flag = false;
+	}
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
new file mode 100644
index 0000000..7437f94
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -0,0 +1,876 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vcd_ddl_shared_mem.h"
+
+#define VIDC_SM_EXTENDED_DECODE_STATUS_ADDR    0x0000
+#define VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_BMSK 0x1
+#define VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_SHFT 0x0
+#define VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_BMSK 0x4
+#define VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_SHFT 0x2
+
+#define VIDC_SM_SET_FRAME_TAG_ADDR             0x0004
+#define VIDC_SM_GET_FRAME_TAG_TOP_ADDR         0x0008
+#define VIDC_SM_GET_FRAME_TAG_BOTTOM_ADDR      0x000c
+#define VIDC_SM_PIC_TIME_TOP_ADDR              0x0010
+#define VIDC_SM_PIC_TIME_BOTTOM_ADDR           0x0014
+#define VIDC_SM_START_BYTE_NUM_ADDR            0x0018
+
+#define VIDC_SM_CROP_INFO1_ADDR                0x0020
+#define VIDC_SM_CROP_INFO1_RIGHT_OFFSET_BMSK   0xffff0000
+#define VIDC_SM_CROP_INFO1_RIGHT_OFFSET_SHFT   16
+#define VIDC_SM_CROP_INFO1_LEFT_OFFSET_BMSK    0x0000ffff
+#define VIDC_SM_CROP_INFO1_LEFT_OFFSET_SHFT    0
+
+#define VIDC_SM_CROP_INFO2_ADDR                0x0024
+#define VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_BMSK  0xffff0000
+#define VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_SHFT  16
+#define VIDC_SM_CROP_INFO2_TOP_OFFSET_BMSK     0x0000ffff
+#define VIDC_SM_CROP_INFO2_TOP_OFFSET_SHFT     0
+
+#define VIDC_SM_DISP_PIC_PROFILE_ADDR                       0x007c
+#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_BMASK       0x0000ff00
+#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_SHFT        8
+#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_BMASK     0x0000001f
+#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_SHFT      0
+
+#define VIDC_SM_DISP_PIC_FRAME_TYPE_ADDR                    0x00c0
+#define VIDC_SM_DISP_PIC_FRAME_TYPE_BMSK                    0x00000003
+#define VIDC_SM_DISP_PIC_FRAME_TYPE_SHFT                    0
+
+#define VIDC_SM_FREE_LUMA_DPB_ADDR                          0x00c4
+#define VIDC_SM_FREE_LUMA_DPB_BMSK                          0xffffffff
+#define VIDC_SM_FREE_LUMA_DPB_SHFT                          0
+
+#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_ADDR                0x00fc
+#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_BMSK                0xffffffff
+#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_SHFT                0
+
+#define VIDC_SM_DEC_ORDER_WIDTH_ADDR                        0x00e8
+#define VIDC_SM_DEC_ORDER_WIDTH_BMSK                        0xffffffff
+#define VIDC_SM_DEC_ORDER_WIDTH_SHFT                        0
+
+#define VIDC_SM_DEC_ORDER_HEIGHT_ADDR                       0x00ec
+#define VIDC_SM_DEC_ORDER_HEIGHT_BMSK                       0xffffffff
+#define VIDC_SM_DEC_ORDER_HEIGHT_SHFT                       0
+
+#define VIDC_SM_DEC_CROP_INFO1_ADDR                         0x00f4
+#define VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_BMSK            0xffff0000
+#define VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_SHFT            16
+#define VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_BMSK             0x0000ffff
+#define VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_SHFT             0
+
+#define VIDC_SM_DEC_CROP_INFO2_ADDR                         0x00f8
+#define VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_BMSK           0xffff0000
+#define VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_SHFT           16
+#define VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_BMSK              0x0000ffff
+#define VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_SHFT              0
+
+#define VIDC_SM_IDR_DECODING_ONLY_ADDR                      0x0108
+#define VIDC_SM_IDR_DECODING_ONLY_BMSK                      0x00000001
+#define VIDC_SM_IDR_DECODING_ONLY_SHIFT                     0
+
+#define VIDC_SM_ENC_EXT_CTRL_ADDR                    0x0028
+#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_BMSK    0xffff0000
+#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT    16
+#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK  0x80
+#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT  7
+#define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK    0X100
+#define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_SHFT    8
+#define VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_BMSK       0x8
+#define VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_SHFT       3
+#define VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_BMSK  0x6
+#define VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_SHFT  1
+#define VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK         0x1
+#define VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT         0
+
+#define VIDC_SM_ENC_PARAM_CHANGE_ADDR                0x002c
+#define VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_BMSK    0x4
+#define VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_SHFT    2
+#define VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_BMSK  0x2
+#define VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_SHFT  1
+#define VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_BMSK       0x1
+#define VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_SHFT       0
+
+#define VIDC_SM_ENC_VOP_TIMING_ADDR                  0x0030
+#define VIDC_SM_ENC_VOP_TIMING_ENABLE_BMSK           0x80000000
+#define VIDC_SM_ENC_VOP_TIMING_ENABLE_SHFT           31
+#define VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_BMSK  0x7fff0000
+#define VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_SHFT  16
+#define VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_BMSK      0x0000ffff
+#define VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_SHFT      0
+
+#define VIDC_SM_ENC_HEC_PERIOD_ADDR                  0x0034
+
+#define VIDC_SM_H264_REF_L0_ADDR                    0x005c
+#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_BMSK     0x80000000
+#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_SHFT     31
+#define VIDC_SM_H264_REF_L0_CHRO_REF_1_BMSK         0x7f000000
+#define VIDC_SM_H264_REF_L0_CHRO_REF_1_SHFT         24
+#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_BMSK     0x00800000
+#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_SHFT     23
+#define VIDC_SM_H264_REF_L0_CHRO_REF_0_BMSK         0x007f0000
+#define VIDC_SM_H264_REF_L0_CHRO_REF_0_SHFT         16
+#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_BMSK     0x00008000
+#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_SHFT     15
+#define VIDC_SM_H264_REF_L0_LUMA_REF_1_BMSK         0x00007f00
+#define VIDC_SM_H264_REF_L0_LUMA_REF_1_SHFT         8
+#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_BMSK     0x00000080
+#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_SHFT     7
+#define VIDC_SM_H264_REF_L0_LUMA_REF_0_BMSK         0x0000007f
+#define VIDC_SM_H264_REF_L0_LUMA_REF_0_SHFT         0
+
+#define VIDC_SM_H264_REF_L1_ADDR                  0x0060
+#define VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_BMSK   0x00800000
+#define VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_SHFT   23
+#define VIDC_SM_H264_REF_L1_CHRO_REF_0_BMSK       0x007f0000
+#define VIDC_SM_H264_REF_L1_CHRO_REF_0_SHFT       16
+#define VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_BMSK   0x00000080
+#define VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_SHFT   7
+#define VIDC_SM_H264_REF_L1_LUMA_REF_0_BMSK       0x0000007f
+#define VIDC_SM_H264_REF_L1_LUMA_REF_0_SHFT       0
+
+#define VIDC_SM_P_B_FRAME_QP_ADDR               0x0070
+#define VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_BMASK   0x00000fc0
+#define VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_SHFT    6
+#define VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_BMASK   0x0000003f
+#define VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_SHFT    0
+
+#define VIDC_SM_NEW_RC_BIT_RATE_ADDR           0x0090
+#define VIDC_SM_NEW_RC_BIT_RATE_VALUE_BMASK    0xffffffff
+#define VIDC_SM_NEW_RC_BIT_RATE_VALUE_SHFT     0
+#define VIDC_SM_NEW_RC_FRAME_RATE_ADDR         0x0094
+#define VIDC_SM_NEW_RC_FRAME_RATE_VALUE_BMASK  0xffffffff
+#define VIDC_SM_NEW_RC_FRAME_RATE_VALUE_SHFT   0
+#define VIDC_SM_NEW_I_PERIOD_ADDR              0x0098
+#define VIDC_SM_NEW_I_PERIOD_VALUE_BMASK       0xffffffff
+#define VIDC_SM_NEW_I_PERIOD_VALUE_SHFT        0
+
+#define VIDC_SM_BATCH_INPUT_ADDR                                  0x00a4
+#define VIDC_SM_BATCH_INPUT_ADDR_VALUE_BMSK                       0xffffffff
+#define VIDC_SM_BATCH_INPUT_ADDRL_VALUE_SHFT                      0
+#define VIDC_SM_BATCH_OUTPUT_ADDR                                 0x00a8
+#define VIDC_SM_BATCH_OUTPUT_ADDR_VALUE_BMSK                      0xffffffff
+#define VIDC_SM_BATCH_OUTPUT_ADDR_VALUE_SHFT                      0
+#define VIDC_SM_BATCH_OUTPUT_SIZE_ADDR                            0x00ac
+#define VIDC_SM_BATCH_OUTPUT_SIZE_VALUE_BMSK                      0xffffffff
+#define VIDC_SM_BATCH_OUTPUT_SIZE_VALUE_SHFT                      0
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_ADDR                     0x01c8
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_VALUE_BMSK               0x1
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_VALUE_SHFT               0
+#define VIDC_SM_ENC_NUM_OF_SLICE_ADDR                             0x01cc
+#define VIDC_SM_ENC_NUM_OF_SLICE_VALUE_BMSK                       0xffffffff
+#define VIDC_SM_ENC_NUM_OF_SLICE_VALUE_SHFT                       0
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR                        0x01d0
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_BMSK                  0xffffffff
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_SHFT                  0
+
+
+#define VIDC_SM_ALLOCATED_LUMA_DPB_SIZE_ADDR               0x0064
+#define VIDC_SM_ALLOCATED_CHROMA_DPB_SIZE_ADDR             0x0068
+#define VIDC_SM_ALLOCATED_MV_SIZE_ADDR                     0x006c
+#define VIDC_SM_FLUSH_CMD_TYPE_ADDR                        0x0080
+#define VIDC_SM_FLUSH_CMD_INBUF1_ADDR                      0x0084
+#define VIDC_SM_FLUSH_CMD_INBUF2_ADDR                      0x0088
+#define VIDC_SM_FLUSH_CMD_OUTBUF_ADDR                      0x008c
+#define VIDC_SM_MIN_LUMA_DPB_SIZE_ADDR                     0x00b0
+#define VIDC_SM_MIN_CHROMA_DPB_SIZE_ADDR                   0x00bc
+
+
+#define VIDC_SM_METADATA_ENABLE_ADDR                 0x0038
+#define VIDC_SM_METADATA_ENABLE_EXTRADATA_BMSK       0x40
+#define VIDC_SM_METADATA_ENABLE_EXTRADATA_SHFT       6
+#define VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_BMSK  0x20
+#define VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_SHFT  5
+#define VIDC_SM_METADATA_ENABLE_VUI_BMSK             0x10
+#define VIDC_SM_METADATA_ENABLE_VUI_SHFT             4
+#define VIDC_SM_METADATA_ENABLE_SEI_VIDC_BMSK         0x8
+#define VIDC_SM_METADATA_ENABLE_SEI_VIDC_SHFT         3
+#define VIDC_SM_METADATA_ENABLE_VC1_PARAM_BMSK       0x4
+#define VIDC_SM_METADATA_ENABLE_VC1_PARAM_SHFT       2
+#define VIDC_SM_METADATA_ENABLE_CONCEALED_MB_BMSK    0x2
+#define VIDC_SM_METADATA_ENABLE_CONCEALED_MB_SHFT    1
+#define VIDC_SM_METADATA_ENABLE_QP_BMSK              0x1
+#define VIDC_SM_METADATA_ENABLE_QP_SHFT              0
+
+#define VIDC_SM_ASPECT_RATIO_INFO_ADDR               0x00c8
+#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_BMSK         0xf
+#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_SHFT         0x0
+#define VIDC_SM_EXTENDED_PAR_ADDR                    0x00cc
+#define VIDC_SM_EXTENDED_PAR_WIDTH_BMSK              0xffff0000
+#define VIDC_SM_EXTENDED_PAR_WIDTH_SHFT              0xf
+#define VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK             0x0000ffff
+#define VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT             0x0
+
+#define VIDC_SM_METADATA_STATUS_ADDR         0x003c
+#define VIDC_SM_METADATA_STATUS_STATUS_BMSK  0x1
+#define VIDC_SM_METADATA_STATUS_STATUS_SHFT  0
+
+#define VIDC_SM_METADATA_DISPLAY_INDEX_ADDR   0x0040
+#define VIDC_SM_EXT_METADATA_START_ADDR_ADDR  0x0044
+
+#define VIDC_SM_PUT_EXTRADATA_ADDR      0x0048
+#define VIDC_SM_PUT_EXTRADATA_PUT_BMSK  0x1
+#define VIDC_SM_PUT_EXTRADATA_PUT_SHFT  0
+
+#define VIDC_SM_EXTRADATA_ADDR_ADDR     0x004c
+
+#define VIDC_SM_CHROMA_ADDR_CHANGE_ADDR   0x0148
+#define VIDC_SM_CHROMA_ADDR_CHANGE_BMASK  0x00000001
+#define VIDC_SM_CHROMA_ADDR_CHANGE_SHFT   0
+
+#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_ADDR   0x0154
+
+#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_BMSK  0x0c
+#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_SHFT 2
+#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_BMSK 0X02
+#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_SHFT 1
+#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_BMSK  0x01
+#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_SHFT   0
+
+#define VIDC_SM_SEI_ENABLE_ADDR                     0x0180
+#define VIDC_SM_SEI_ENABLE_RECOVERY_POINT_SEI_BMSK  0x00000001
+#define VIDC_SM_SEI_ENABLE_RECOVERY_POINT_SEI_SHFT  0
+
+#define VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR    0X01ac
+
+#define VIDC_SM_TIMEOUT_VALUE_ADDR        0x0158
+#define VIDC_SM_TIMEOUT_VALUE_BMSK        0xffffffff
+#define VIDC_SM_TIMEOUT_VALUE_SHFT        0
+
+#define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK	0x40
+#define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT	6
+
+#define DDL_MEM_WRITE_32(base, offset, val) ddl_mem_write_32(\
+	(u32 *) ((u8 *) (base)->align_virtual_addr + (offset)), (val))
+#define DDL_MEM_READ_32(base, offset) ddl_mem_read_32(\
+	(u32 *) ((u8 *) (base)->align_virtual_addr + (offset)))
+
+#define DDL_SHARED_MEM_11BIT_RIGHT_SHIFT  11
+
+static void ddl_mem_write_32(u32 *addr, u32 data)
+{
+	*addr = data;
+}
+
+static u32 ddl_mem_read_32(u32 *addr)
+{
+	return *addr;
+}
+
+void vidc_sm_get_extended_decode_status(struct ddl_buf_addr *shared_mem,
+	u32 *more_field_needed,
+	u32 *resl_change)
+{
+	u32 decode_status = DDL_MEM_READ_32(shared_mem,
+					VIDC_SM_EXTENDED_DECODE_STATUS_ADDR);
+	if (more_field_needed)
+		*more_field_needed =
+				VIDC_GETFIELD(decode_status,
+				VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_BMSK,
+				VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_SHFT);
+	if (resl_change)
+		*resl_change =
+				VIDC_GETFIELD(decode_status,
+				VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_BMSK,
+				VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_SHFT);
+}
+
+void vidc_sm_set_frame_tag(struct ddl_buf_addr *shared_mem,
+	u32 frame_tag)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_SET_FRAME_TAG_ADDR, frame_tag);
+}
+
+void vidc_sm_get_frame_tags(struct ddl_buf_addr *shared_mem,
+	u32  *pn_frame_tag_top, u32 *pn_frame_tag_bottom)
+{
+	*pn_frame_tag_top = DDL_MEM_READ_32(shared_mem,
+				VIDC_SM_GET_FRAME_TAG_TOP_ADDR);
+	*pn_frame_tag_bottom = DDL_MEM_READ_32(shared_mem,
+					VIDC_SM_GET_FRAME_TAG_BOTTOM_ADDR);
+}
+
+void vidc_sm_get_picture_times(struct ddl_buf_addr *shared_mem,
+	u32 *pn_time_top, u32 *pn_time_bottom)
+{
+	*pn_time_top = DDL_MEM_READ_32(shared_mem, VIDC_SM_PIC_TIME_TOP_ADDR);
+	*pn_time_bottom = DDL_MEM_READ_32(shared_mem,
+						VIDC_SM_PIC_TIME_BOTTOM_ADDR);
+}
+
+void vidc_sm_set_start_byte_number(struct ddl_buf_addr *shared_mem,
+	u32 byte_num)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_START_BYTE_NUM_ADDR, byte_num);
+}
+
+void vidc_sm_get_crop_info(struct ddl_buf_addr *shared_mem,
+	u32 *pn_left, u32 *pn_right, u32 *pn_top, u32 *pn_bottom)
+{
+	u32 info1, info2;
+
+	info1 = DDL_MEM_READ_32(shared_mem, VIDC_SM_CROP_INFO1_ADDR);
+
+	*pn_left = VIDC_GETFIELD(info1, VIDC_SM_CROP_INFO1_LEFT_OFFSET_BMSK,
+					VIDC_SM_CROP_INFO1_LEFT_OFFSET_SHFT);
+	*pn_right = VIDC_GETFIELD(info1, VIDC_SM_CROP_INFO1_RIGHT_OFFSET_BMSK,
+					VIDC_SM_CROP_INFO1_RIGHT_OFFSET_SHFT);
+	info2 = DDL_MEM_READ_32(shared_mem, VIDC_SM_CROP_INFO2_ADDR);
+	*pn_top = VIDC_GETFIELD(info2, VIDC_SM_CROP_INFO2_TOP_OFFSET_BMSK,
+					VIDC_SM_CROP_INFO2_TOP_OFFSET_SHFT);
+	*pn_bottom = VIDC_GETFIELD(info2,
+					VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_BMSK,
+					VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_SHFT);
+}
+
+void vidc_sm_get_displayed_picture_frame(struct ddl_buf_addr
+	*shared_mem, u32  *n_disp_picture_frame)
+{
+	u32 disp_pict_frame;
+
+	disp_pict_frame = DDL_MEM_READ_32(shared_mem,
+					VIDC_SM_DISP_PIC_FRAME_TYPE_ADDR);
+	*n_disp_picture_frame = VIDC_GETFIELD(disp_pict_frame,
+			VIDC_SM_DISP_PIC_FRAME_TYPE_BMSK,
+			VIDC_SM_DISP_PIC_FRAME_TYPE_SHFT);
+}
+void vidc_sm_get_available_luma_dpb_address(struct ddl_buf_addr
+	*shared_mem, u32 *pn_free_luma_dpb_address)
+{
+	*pn_free_luma_dpb_address = DDL_MEM_READ_32(shared_mem,
+		VIDC_SM_FREE_LUMA_DPB_ADDR);
+}
+
+void vidc_sm_get_available_luma_dpb_dec_order_address(
+	struct ddl_buf_addr	*shared_mem,
+	u32 *pn_free_luma_dpb_address)
+{
+	*pn_free_luma_dpb_address = DDL_MEM_READ_32(shared_mem,
+		VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_ADDR);
+}
+
+void vidc_sm_get_dec_order_resl(
+	struct ddl_buf_addr *shared_mem, u32 *width, u32 *height)
+{
+	*width = DDL_MEM_READ_32(shared_mem,
+			VIDC_SM_DEC_ORDER_WIDTH_ADDR);
+	*height = DDL_MEM_READ_32(shared_mem,
+			VIDC_SM_DEC_ORDER_HEIGHT_ADDR);
+}
+
+void vidc_sm_get_dec_order_crop_info(
+	struct ddl_buf_addr *shared_mem, u32 *left,
+	u32 *right, u32 *top, u32 *bottom)
+{
+	u32 crop_data;
+	crop_data = DDL_MEM_READ_32(shared_mem,
+		VIDC_SM_DEC_CROP_INFO1_ADDR);
+	*left = VIDC_GETFIELD(crop_data,
+		VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_BMSK,
+		VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_SHFT);
+	*right = VIDC_GETFIELD(crop_data,
+		VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_BMSK,
+		VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_SHFT);
+	crop_data = DDL_MEM_READ_32(shared_mem,
+		VIDC_SM_DEC_CROP_INFO2_ADDR);
+	*top = VIDC_GETFIELD(crop_data,
+		VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_BMSK,
+		VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_SHFT);
+	*bottom = VIDC_GETFIELD(crop_data,
+		VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_BMSK,
+		VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_SHFT);
+}
+
+void vidc_sm_set_extended_encoder_control(struct ddl_buf_addr
+	*shared_mem, u32 hec_enable,
+	enum VIDC_SM_frame_skip frame_skip_mode,
+	u32 seq_hdr_in_band, u32 vbv_buffer_size, u32 cpcfc_enable,
+	u32 sps_pps_control, u32 closed_gop_enable)
+{
+	u32 enc_ctrl;
+
+	enc_ctrl = VIDC_SETFIELD((hec_enable) ? 1 : 0,
+			VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK) |
+			VIDC_SETFIELD((u32) frame_skip_mode,
+			VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_BMSK) |
+			VIDC_SETFIELD((seq_hdr_in_band) ? 1 : 0 ,
+			VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_SHFT ,
+			VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_BMSK) |
+			VIDC_SETFIELD(vbv_buffer_size,
+			VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_BMSK) |
+			VIDC_SETFIELD((cpcfc_enable) ? 1 : 0,
+			VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK) |
+			VIDC_SETFIELD((sps_pps_control) ? 1 : 0,
+			VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK) |
+			VIDC_SETFIELD(closed_gop_enable,
+			VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK);
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_EXT_CTRL_ADDR, enc_ctrl);
+}
+
+void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem,
+	u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg)
+{
+	u32 enc_param_chg;
+
+	enc_param_chg = VIDC_SETFIELD((bit_rate_chg) ? 1 : 0,
+				VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_SHFT,
+				VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_BMSK) |
+				VIDC_SETFIELD((frame_rate_chg) ? 1 : 0,
+				VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_SHFT,
+				VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_BMSK) |
+				VIDC_SETFIELD((i_period_chg) ? 1 : 0,
+				VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_SHFT,
+				VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_BMSK);
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_PARAM_CHANGE_ADDR,
+		enc_param_chg);
+}
+
+void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem,
+	u32 vop_time_enable, u32 time_resolution, u32 frame_delta)
+{
+	u32 vop_time;
+
+	vop_time = VIDC_SETFIELD((vop_time_enable) ? 1 : 0,
+			VIDC_SM_ENC_VOP_TIMING_ENABLE_SHFT ,
+			VIDC_SM_ENC_VOP_TIMING_ENABLE_BMSK) |
+			VIDC_SETFIELD(time_resolution ,
+			VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_SHFT,
+			VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_BMSK) |
+			VIDC_SETFIELD(frame_delta,
+			VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_SHFT,
+			VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_BMSK);
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_VOP_TIMING_ADDR, vop_time);
+}
+
+void vidc_sm_set_encoder_hec_period(struct ddl_buf_addr *shared_mem,
+	u32 hec_period)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_HEC_PERIOD_ADDR,
+		hec_period);
+}
+
+void vidc_sm_get_h264_encoder_reference_list0(struct ddl_buf_addr
+	*shared_mem, enum VIDC_SM_ref_picture *pe_luma_picture0,
+	u32 *pn_luma_picture_index0, enum VIDC_SM_ref_picture
+		*pe_luma_picture1, u32 *pn_luma_picture_index1,
+	enum VIDC_SM_ref_picture *pe_chroma_picture0,
+	u32 *pn_chroma_picture_index0,
+	enum VIDC_SM_ref_picture *pe_chroma_picture1,
+	u32 *pn_chroma_picture_index1)
+{
+	u32 ref_list;
+
+	ref_list = DDL_MEM_READ_32(shared_mem, VIDC_SM_H264_REF_L0_ADDR);
+
+	*pe_luma_picture0 = (enum VIDC_SM_ref_picture)
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_BMSK,
+				VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_SHFT);
+	*pn_luma_picture_index0 =
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L0_LUMA_REF_0_BMSK,
+				VIDC_SM_H264_REF_L0_LUMA_REF_0_SHFT);
+	*pe_luma_picture1 = (enum VIDC_SM_ref_picture)
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_BMSK,
+				VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_SHFT);
+	*pn_luma_picture_index1 = VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L0_LUMA_REF_1_BMSK,
+				VIDC_SM_H264_REF_L0_LUMA_REF_1_SHFT);
+	*pe_chroma_picture0 = (enum VIDC_SM_ref_picture)
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_BMSK,
+				VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_SHFT);
+	*pn_chroma_picture_index0 = VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L0_CHRO_REF_0_BMSK,
+				VIDC_SM_H264_REF_L0_CHRO_REF_0_SHFT);
+	*pe_chroma_picture1 = (enum VIDC_SM_ref_picture)
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_BMSK,
+				VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_SHFT);
+	*pn_chroma_picture_index1 =
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L0_CHRO_REF_1_BMSK,
+				VIDC_SM_H264_REF_L0_CHRO_REF_1_SHFT);
+}
+
+void vidc_sm_get_h264_encoder_reference_list1(struct ddl_buf_addr
+	*shared_mem, enum VIDC_SM_ref_picture *pe_luma_picture,
+	u32 *pn_luma_picture_index,
+	enum VIDC_SM_ref_picture *pe_chroma_picture,
+	u32 *pn_chroma_picture_index)
+{
+	u32 ref_list;
+
+	ref_list = DDL_MEM_READ_32(shared_mem, VIDC_SM_H264_REF_L1_ADDR);
+
+	*pe_luma_picture = (enum VIDC_SM_ref_picture)
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_BMSK,
+				VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_SHFT);
+	*pn_luma_picture_index =
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L1_LUMA_REF_0_BMSK,
+				VIDC_SM_H264_REF_L1_LUMA_REF_0_SHFT);
+	*pe_chroma_picture = (enum VIDC_SM_ref_picture)
+				VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_BMSK,
+				VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_SHFT);
+	*pn_chroma_picture_index = VIDC_GETFIELD(ref_list,
+				VIDC_SM_H264_REF_L1_CHRO_REF_0_BMSK,
+				VIDC_SM_H264_REF_L1_CHRO_REF_0_SHFT);
+}
+
+void vidc_sm_set_allocated_dpb_size(struct ddl_buf_addr *shared_mem,
+		u32 y_size, u32 c_size)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_LUMA_DPB_SIZE_ADDR,
+		y_size);
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_CHROMA_DPB_SIZE_ADDR,
+		c_size);
+}
+
+void vidc_sm_set_allocated_h264_mv_size(struct ddl_buf_addr *shared_mem,
+	u32 mv_size)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_MV_SIZE_ADDR,
+		mv_size);
+}
+
+void vidc_sm_get_min_yc_dpb_sizes(struct ddl_buf_addr *shared_mem,
+	u32 *pn_min_luma_dpb_size, u32 *pn_min_chroma_dpb_size)
+{
+	*pn_min_luma_dpb_size = DDL_MEM_READ_32(shared_mem,
+		VIDC_SM_MIN_LUMA_DPB_SIZE_ADDR);
+	*pn_min_chroma_dpb_size = DDL_MEM_READ_32(shared_mem,
+		VIDC_SM_MIN_CHROMA_DPB_SIZE_ADDR);
+}
+
+void vidc_sm_set_concealment_color(struct ddl_buf_addr *shared_mem,
+	u32 conceal_ycolor, u32 conceal_ccolor)
+{
+	u32 conceal_color;
+
+	conceal_color = (((conceal_ycolor << 8) & 0xff00) |
+		(conceal_ccolor & 0xff));
+	DDL_MEM_WRITE_32(shared_mem, 0x00f0, conceal_color);
+}
+
+void vidc_sm_set_metadata_enable(struct ddl_buf_addr *shared_mem,
+	u32 extradata_enable, u32 qp_enable, u32 concealed_mb_enable,
+	u32 vc1Param_enable, u32 sei_nal_enable, u32 vui_enable,
+	u32 enc_slice_size_enable)
+{
+	u32 metadata_enable;
+
+	metadata_enable = VIDC_SETFIELD((extradata_enable) ? 1 : 0,
+				VIDC_SM_METADATA_ENABLE_EXTRADATA_SHFT,
+				VIDC_SM_METADATA_ENABLE_EXTRADATA_BMSK) |
+				VIDC_SETFIELD((enc_slice_size_enable) ? 1 : 0,
+				VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_SHFT,
+				VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_BMSK) |
+				VIDC_SETFIELD((vui_enable) ? 1 : 0,
+				VIDC_SM_METADATA_ENABLE_VUI_SHFT,
+				VIDC_SM_METADATA_ENABLE_VUI_BMSK) |
+				VIDC_SETFIELD((sei_nal_enable) ? 1 : 0,
+				VIDC_SM_METADATA_ENABLE_SEI_VIDC_SHFT,
+				VIDC_SM_METADATA_ENABLE_SEI_VIDC_BMSK) |
+				VIDC_SETFIELD((vc1Param_enable) ? 1 : 0,
+				VIDC_SM_METADATA_ENABLE_VC1_PARAM_SHFT,
+				VIDC_SM_METADATA_ENABLE_VC1_PARAM_BMSK) |
+				VIDC_SETFIELD((concealed_mb_enable) ? 1 : 0,
+				VIDC_SM_METADATA_ENABLE_CONCEALED_MB_SHFT,
+				VIDC_SM_METADATA_ENABLE_CONCEALED_MB_BMSK) |
+				VIDC_SETFIELD((qp_enable) ? 1 : 0,
+				VIDC_SM_METADATA_ENABLE_QP_SHFT,
+				VIDC_SM_METADATA_ENABLE_QP_BMSK);
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_METADATA_ENABLE_ADDR,
+		metadata_enable);
+}
+
+void vidc_sm_get_metadata_status(struct ddl_buf_addr
+		*shared_mem, u32 *pb_metadata_present)
+{
+	u32 status;
+
+	status = DDL_MEM_READ_32(shared_mem, VIDC_SM_METADATA_STATUS_ADDR);
+	*pb_metadata_present = (u32) VIDC_GETFIELD(status,
+				VIDC_SM_METADATA_STATUS_STATUS_BMSK,
+				VIDC_SM_METADATA_STATUS_STATUS_SHFT);
+}
+
+void vidc_sm_get_metadata_display_index(struct ddl_buf_addr *shared_mem,
+	u32 *pn_dixplay_index)
+{
+	*pn_dixplay_index = DDL_MEM_READ_32(shared_mem,
+					VIDC_SM_METADATA_DISPLAY_INDEX_ADDR);
+}
+
+void vidc_sm_set_metadata_start_address(struct ddl_buf_addr *shared_mem,
+	u32 address)
+{
+	u32 address_shift = address;
+
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_EXT_METADATA_START_ADDR_ADDR,
+		address_shift);
+}
+
+void vidc_sm_set_extradata_presence(struct ddl_buf_addr *shared_mem,
+	u32 extradata_present)
+{
+	u32 put_extradata;
+
+	put_extradata = VIDC_SETFIELD((extradata_present) ? 1 : 0,
+				VIDC_SM_PUT_EXTRADATA_PUT_SHFT,
+				VIDC_SM_PUT_EXTRADATA_PUT_BMSK);
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_PUT_EXTRADATA_ADDR,
+			put_extradata);
+}
+
+void vidc_sm_set_extradata_addr(struct ddl_buf_addr *shared_mem,
+	u32 extradata_addr)
+{
+	u32 address_shift = extradata_addr;
+
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_EXTRADATA_ADDR_ADDR,
+		address_shift);
+}
+
+void vidc_sm_set_pand_b_frame_qp(struct ddl_buf_addr *shared_mem,
+	u32 b_frame_qp, u32 p_frame_qp)
+{
+	u32 nP_B_frame_qp;
+
+	nP_B_frame_qp = VIDC_SETFIELD(b_frame_qp,
+				VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_SHFT,
+				VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_BMASK);
+	nP_B_frame_qp |= VIDC_SETFIELD(p_frame_qp,
+				VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_SHFT,
+				VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_BMASK);
+	DDL_MEM_WRITE_32(shared_mem , VIDC_SM_P_B_FRAME_QP_ADDR,
+		nP_B_frame_qp);
+}
+
+
+void vidc_sm_get_profile_info(struct ddl_buf_addr *shared_mem,
+	struct ddl_profile_info_type *ddl_profile_info)
+{
+	u32 disp_pic_profile;
+
+	disp_pic_profile = DDL_MEM_READ_32(shared_mem,
+		VIDC_SM_DISP_PIC_PROFILE_ADDR);
+	ddl_profile_info->bit_depth_chroma_minus8 =
+		(disp_pic_profile  & 0x00380000) >> 19;
+	ddl_profile_info->bit_depth_luma_minus8 =
+		(disp_pic_profile & 0x00070000) >> 16;
+	ddl_profile_info->pic_profile = VIDC_GETFIELD(
+		disp_pic_profile,
+		VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_BMASK,
+		VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_SHFT);
+	ddl_profile_info->pic_level = VIDC_GETFIELD(
+		disp_pic_profile,
+		VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_BMASK,
+		VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_SHFT);
+	ddl_profile_info->chroma_format_idc =
+		(disp_pic_profile & 0x60) >> 5;
+}
+
+void vidc_sm_set_encoder_new_bit_rate(struct ddl_buf_addr *shared_mem,
+	u32 new_bit_rate)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_RC_BIT_RATE_ADDR,
+		new_bit_rate);
+}
+
+void vidc_sm_set_encoder_new_frame_rate(struct ddl_buf_addr *shared_mem,
+	u32 new_frame_rate)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_RC_FRAME_RATE_ADDR,
+		new_frame_rate);
+}
+
+void vidc_sm_set_encoder_new_i_period(struct ddl_buf_addr *shared_mem,
+	u32 new_i_period)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_I_PERIOD_ADDR,
+		new_i_period);
+}
+void vidc_sm_set_encoder_init_rc_value(struct ddl_buf_addr *shared_mem,
+	u32 new_rc_value)
+{
+	DDL_MEM_WRITE_32(shared_mem, 0x011C, new_rc_value);
+
+}
+void vidc_sm_set_idr_decode_only(struct ddl_buf_addr *shared_mem,
+	u32 enable)
+{
+	u32 idr_decode_only = VIDC_SETFIELD((enable) ? 1 : 0,
+			VIDC_SM_IDR_DECODING_ONLY_SHIFT,
+			VIDC_SM_IDR_DECODING_ONLY_BMSK
+			);
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_IDR_DECODING_ONLY_ADDR,
+			idr_decode_only);
+}
+
+void vidc_sm_set_chroma_addr_change(struct ddl_buf_addr *shared_mem,
+	u32 addr_change)
+{
+	u32 chroma_addr_change = VIDC_SETFIELD((addr_change) ? 1 : 0,
+					VIDC_SM_CHROMA_ADDR_CHANGE_SHFT,
+					VIDC_SM_CHROMA_ADDR_CHANGE_BMASK);
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_CHROMA_ADDR_CHANGE_ADDR,
+					 chroma_addr_change);
+
+}
+
+void vidc_sm_set_mpeg4_profile_override(struct ddl_buf_addr *shared_mem,
+	enum vidc_sm_mpeg4_profileinfo profile_info)
+{
+	u32 profile_enforce = 0;
+	if (shared_mem != NULL) {
+		profile_enforce = 1;
+		switch (profile_info) {
+		case VIDC_SM_PROFILE_INFO_ASP:
+			profile_enforce |= 4;
+			break;
+		case VIDC_SM_PROFILE_INFO_SP:
+			profile_enforce |= 2;
+			break;
+		case VIDC_SM_PROFILE_INFO_DISABLE:
+		default:
+			profile_enforce = 0;
+			break;
+		}
+		DDL_MEM_WRITE_32(shared_mem, 0x15c, profile_enforce);
+	}
+}
+void vidc_sm_set_decoder_sei_enable(struct ddl_buf_addr *shared_mem,
+	u32 sei_enable)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_SEI_ENABLE_ADDR, sei_enable);
+}
+
+void vidc_sm_get_decoder_sei_enable(struct ddl_buf_addr *shared_mem,
+	u32 *sei_enable)
+{
+	*sei_enable = DDL_MEM_READ_32(shared_mem, VIDC_SM_SEI_ENABLE_ADDR);
+}
+
+void vidc_sm_set_error_concealment_config(struct ddl_buf_addr *shared_mem,
+	u32 inter_slice, u32 intra_slice, u32 conceal_config_enable)
+{
+	u32 error_conceal_config = 0;
+
+	error_conceal_config = VIDC_SETFIELD(inter_slice,
+			VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_SHFT,
+			VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_BMSK);
+
+	error_conceal_config |= VIDC_SETFIELD(intra_slice,
+			VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_SHFT,
+			VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_BMSK);
+
+	error_conceal_config |= VIDC_SETFIELD(conceal_config_enable,
+			VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_SHFT,
+			VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_BMSK);
+
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ERROR_CONCEALMENT_CONFIG_ADDR,
+			error_conceal_config);
+}
+
+void vidc_sm_set_decoder_stuff_bytes_consumption(
+	struct ddl_buf_addr *shared_mem,
+	enum vidc_sm_num_stuff_bytes_consume_info consume_info)
+{
+	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR,
+	consume_info);
+}
+
+void vidc_sm_set_video_core_timeout_value(struct ddl_buf_addr *shared_mem,
+        u32 timeout)
+{
+    DDL_MEM_WRITE_32(shared_mem, VIDC_SM_TIMEOUT_VALUE_ADDR,
+        timeout);
+}
+
+void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem,
+	struct vcd_aspect_ratio *aspect_ratio_info)
+{
+	u32 extended_par_info = 0;
+	aspect_ratio_info->aspect_ratio = DDL_MEM_READ_32(shared_mem,
+				VIDC_SM_ASPECT_RATIO_INFO_ADDR);
+
+	if (aspect_ratio_info->aspect_ratio == 0x0f) {
+		extended_par_info = DDL_MEM_READ_32(shared_mem,
+			VIDC_SM_EXTENDED_PAR_ADDR);
+		aspect_ratio_info->extended_par_width =
+			VIDC_GETFIELD(extended_par_info,
+			VIDC_SM_EXTENDED_PAR_WIDTH_BMSK,
+			VIDC_SM_EXTENDED_PAR_WIDTH_SHFT);
+		aspect_ratio_info->extended_par_height =
+			VIDC_GETFIELD(extended_par_info,
+			VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK,
+			VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT);
+	}
+}
+
+void vidc_sm_set_encoder_slice_batch_int_ctrl(struct ddl_buf_addr *shared_mem,
+        u32 slice_batch_int_enable)
+{
+    u32 slice_batch_int_ctrl = VIDC_SETFIELD((slice_batch_int_enable) ?
+            1 : 0,
+            VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT,
+            VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK);
+    DDL_MEM_WRITE_32(shared_mem,
+            VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_ADDR,
+            slice_batch_int_ctrl);
+}
+
+void vidc_sm_get_num_slices_comp(struct ddl_buf_addr *shared_mem,
+        u32 *num_slices_comp)
+{
+    *num_slices_comp = DDL_MEM_READ_32(shared_mem,
+            VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR);
+}
+
+void vidc_sm_set_encoder_batch_config(struct ddl_buf_addr *shared_mem,
+        u32 num_slices,
+        u32 input_addr, u32 output_addr,
+        u32 output_buffer_size)
+{
+    DDL_MEM_WRITE_32(shared_mem,
+            VIDC_SM_ENC_NUM_OF_SLICE_ADDR,
+            num_slices);
+    DDL_MEM_WRITE_32(shared_mem,
+            VIDC_SM_BATCH_INPUT_ADDR,
+            input_addr);
+    DDL_MEM_WRITE_32(shared_mem,
+            VIDC_SM_BATCH_OUTPUT_ADDR,
+            output_addr);
+    DDL_MEM_WRITE_32(shared_mem,
+            VIDC_SM_BATCH_OUTPUT_SIZE_ADDR,
+            output_buffer_size);
+}
+
+void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem,
+        u32 *output_buffer_size)
+{
+    *output_buffer_size = DDL_MEM_READ_32(shared_mem,
+            VIDC_SM_BATCH_OUTPUT_SIZE_ADDR);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
new file mode 100644
index 0000000..3bb170e
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -0,0 +1,197 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VCD_DDL_SHARED_MEM_H_
+#define _VCD_DDL_SHARED_MEM_H_
+
+#include "vcd_ddl.h"
+
+#define VIDC_SM_PROFILE_MPEG4_SIMPLE      (0)
+#define VIDC_SM_PROFILE_MPEG4_ADV_SIMPLE  (1)
+
+#define VIDC_SM_PROFILE_H264_BASELINE     (0)
+#define VIDC_SM_PROFILE_H264_MAIN         (1)
+#define VIDC_SM_PROFILE_H264_HIGH         (2)
+
+#define VIDC_SM_PROFILE_H263_BASELINE     (0)
+
+#define VIDC_SM_PROFILE_VC1_SIMPLE        (0)
+#define VIDC_SM_PROFILE_VC1_MAIN          (1)
+#define VIDC_SM_PROFILE_VC1_ADVANCED      (2)
+
+#define VIDC_SM_PROFILE_MPEG2_MAIN        (4)
+#define VIDC_SM_PROFILE_MPEG2_SIMPLE      (5)
+
+#define VIDC_SM_LEVEL_MPEG2_LOW        (10)
+#define VIDC_SM_LEVEL_MPEG2_MAIN        (8)
+#define VIDC_SM_LEVEL_MPEG2_HIGH_1440   (6)
+#define VIDC_SM_LEVEL_MPEG2_HIGH        (4)
+
+#define VIDC_SM_LEVEL_VC1_LOW     (0)
+#define VIDC_SM_LEVEL_VC1_MEDIUM  (2)
+#define VIDC_SM_LEVEL_VC1_HIGH    (4)
+
+#define VIDC_SM_LEVEL_VC1_ADV_0  (0)
+#define VIDC_SM_LEVEL_VC1_ADV_1  (1)
+#define VIDC_SM_LEVEL_VC1_ADV_2  (2)
+#define VIDC_SM_LEVEL_VC1_ADV_3  (3)
+#define VIDC_SM_LEVEL_VC1_ADV_4  (4)
+
+#define VIDC_SM_RECOVERY_POINT_SEI  (1)
+enum VIDC_SM_frame_skip {
+	VIDC_SM_FRAME_SKIP_DISABLE      = 0,
+	VIDC_SM_FRAME_SKIP_ENABLE_LEVEL = 1,
+	VIDC_SM_FRAME_SKIP_ENABLE_VBV   = 2
+};
+enum VIDC_SM_ref_picture {
+	VIDC_SM_REF_PICT_FRAME_OR_TOP_FIELD   = 0,
+	VIDC_SM_REF_PICT_BOTTOM_FIELD         = 1
+};
+
+struct ddl_profile_info_type {
+	u32 bit_depth_chroma_minus8;
+	u32 bit_depth_luma_minus8;
+	u32 pic_level;
+	u32 chroma_format_idc;
+	u32 pic_profile;
+};
+
+enum vidc_sm_mpeg4_profileinfo {
+	VIDC_SM_PROFILE_INFO_DISABLE  = 0,
+	VIDC_SM_PROFILE_INFO_SP       = 1,
+	VIDC_SM_PROFILE_INFO_ASP      = 2,
+	VIDC_SM_PROFILE_INFO_MAX      = 0x7fffffff
+};
+
+enum vidc_sm_num_stuff_bytes_consume_info {
+	VIDC_SM_NUM_STUFF_BYTES_CONSUME_ALL  = 0x0,
+	VIDC_SM_NUM_STUFF_BYTES_CONSUME_NONE = 0xffffffff
+};
+
+void vidc_sm_get_extended_decode_status(struct ddl_buf_addr *shared_mem,
+	u32 *more_field_needed,
+	u32 *resl_change);
+void vidc_sm_set_frame_tag(struct ddl_buf_addr *shared_mem,
+	u32 frame_tag);
+void vidc_sm_get_frame_tags(struct ddl_buf_addr *shared_mem,
+	u32 *pn_frame_tag_top, u32 *pn_frame_tag_bottom);
+void vidc_sm_get_picture_times(struct ddl_buf_addr *shared_mem,
+	u32 *pn_time_top, u32 *pn_time_bottom);
+void vidc_sm_set_start_byte_number(struct ddl_buf_addr *shared_mem,
+	u32 byte_num);
+void vidc_sm_get_crop_info(struct ddl_buf_addr *shared_mem, u32 *pn_left,
+	u32 *pn_right, u32 *pn_top, u32 *pn_bottom);
+void vidc_sm_get_displayed_picture_frame(struct ddl_buf_addr
+	*shared_mem, u32 *n_disp_picture_frame);
+void vidc_sm_get_available_luma_dpb_address(
+	struct ddl_buf_addr *shared_mem, u32 *pn_free_luma_dpb_address);
+void vidc_sm_get_available_luma_dpb_dec_order_address(
+	struct ddl_buf_addr *shared_mem, u32 *pn_free_luma_dpb_address);
+void vidc_sm_get_dec_order_resl(
+	struct ddl_buf_addr *shared_mem, u32 *width, u32 *height);
+void vidc_sm_get_dec_order_crop_info(
+	struct ddl_buf_addr *shared_mem, u32 *left,
+	u32 *right, u32 *top, u32 *bottom);
+void vidc_sm_set_extended_encoder_control(
+	struct ddl_buf_addr *shared_mem, u32 hec_enable,
+	enum VIDC_SM_frame_skip  frame_skip_mode, u32 seq_hdr_in_band,
+	u32 vbv_buffer_size, u32 cpcfc_enable, u32 sps_pps_control,
+	u32 closed_gop_enable);
+void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem,
+	u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg);
+void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem,
+	u32 vop_time_enable, u32 time_resolution, u32 frame_delta);
+void vidc_sm_set_encoder_hec_period(struct ddl_buf_addr *shared_mem,
+	u32 hec_period);
+void vidc_sm_get_h264_encoder_reference_list0(
+	struct ddl_buf_addr *shared_mem,
+	enum VIDC_SM_ref_picture *pe_luma_picture0,
+	u32 *pn_luma_picture_index0,
+	enum VIDC_SM_ref_picture *pe_luma_picture1,
+	u32 *pn_luma_picture_index1,
+	enum VIDC_SM_ref_picture *pe_chroma_picture0,
+	u32 *pn_chroma_picture_index0,
+	enum VIDC_SM_ref_picture *pe_chroma_picture1,
+	u32 *pn_chroma_picture_index1);
+
+void vidc_sm_get_h264_encoder_reference_list1(
+	struct ddl_buf_addr *shared_mem,
+	enum VIDC_SM_ref_picture *pe_luma_picture,
+	u32 *pn_luma_picture_index,
+	enum VIDC_SM_ref_picture *pe_chroma_picture,
+	u32 *pn_chroma_picture_index);
+void vidc_sm_set_allocated_dpb_size(struct ddl_buf_addr *shared_mem,
+	u32 y_size, u32 c_size);
+void vidc_sm_set_allocated_h264_mv_size(struct ddl_buf_addr *shared_mem,
+	u32 mv_size);
+void vidc_sm_get_min_yc_dpb_sizes(struct ddl_buf_addr *shared_mem,
+	u32 *pn_min_luma_dpb_size, u32 *pn_min_chroma_dpb_size);
+void vidc_sm_set_metadata_enable(struct ddl_buf_addr *shared_mem,
+	u32 extradata_enable, u32 qp_enable, u32 concealed_mb_enable,
+	u32 vc1Param_enable, u32 sei_nal_enable, u32 vui_enable,
+	u32 enc_slice_size_enable);
+void vidc_sm_get_metadata_status(struct ddl_buf_addr *shared_mem,
+	u32 *pb_metadata_present);
+void vidc_sm_get_metadata_display_index(struct ddl_buf_addr *shared_mem,
+	u32 *pn_dixplay_index);
+void vidc_sm_set_metadata_start_address(struct ddl_buf_addr *shared_mem,
+	u32 address);
+void vidc_sm_set_extradata_presence(struct ddl_buf_addr *shared_mem,
+	u32 extradata_present);
+void vidc_sm_set_extradata_addr(struct ddl_buf_addr *shared_mem,
+	u32 extradata_addr);
+void vidc_sm_set_pand_b_frame_qp(struct ddl_buf_addr *shared_mem,
+	u32 b_frame_qp, u32 p_frame_qp);
+void vidc_sm_get_profile_info(struct ddl_buf_addr *shared_mem,
+	struct ddl_profile_info_type *ddl_profile_info);
+void vidc_sm_set_encoder_new_bit_rate(struct ddl_buf_addr *shared_mem,
+	u32 new_bit_rate);
+void vidc_sm_set_encoder_new_frame_rate(struct ddl_buf_addr *shared_mem,
+	u32 new_frame_rate);
+void vidc_sm_set_encoder_new_i_period(struct ddl_buf_addr *shared_mem,
+	u32 new_i_period);
+void vidc_sm_set_encoder_init_rc_value(struct ddl_buf_addr *shared_mem,
+	u32 new_rc_value);
+void vidc_sm_set_idr_decode_only(struct ddl_buf_addr *shared_mem,
+	u32 enable);
+void vidc_sm_set_concealment_color(struct ddl_buf_addr *shared_mem,
+	u32 conceal_ycolor, u32 conceal_ccolor);
+void vidc_sm_set_chroma_addr_change(struct ddl_buf_addr *shared_mem,
+	u32 addr_change);
+void vidc_sm_set_mpeg4_profile_override(struct ddl_buf_addr *shared_mem,
+	enum vidc_sm_mpeg4_profileinfo profile_info);
+void vidc_sm_set_decoder_sei_enable(struct ddl_buf_addr *shared_mem,
+	u32 sei_enable);
+void vidc_sm_get_decoder_sei_enable(struct ddl_buf_addr *shared_mem,
+	u32 *sei_enable);
+void vidc_sm_set_error_concealment_config(struct ddl_buf_addr *shared_mem,
+	u32 inter_slice, u32 intra_slice, u32 conceal_config_enable);
+void vidc_sm_set_decoder_stuff_bytes_consumption(
+	struct ddl_buf_addr *shared_mem,
+	enum vidc_sm_num_stuff_bytes_consume_info consume_info);
+void vidc_sm_set_video_core_timeout_value(struct ddl_buf_addr *shared_mem,
+    u32 timeout);
+void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem,
+	struct vcd_aspect_ratio *aspect_ratio_info);
+void vidc_sm_set_encoder_slice_batch_int_ctrl(struct ddl_buf_addr *shared_mem,
+    u32 slice_batch_int_enable);
+void vidc_sm_get_num_slices_comp(struct ddl_buf_addr *shared_mem,
+    u32 *num_slices_comp);
+void vidc_sm_set_encoder_batch_config(struct ddl_buf_addr *shared_mem,
+        u32 num_slices,
+        u32 input_addr, u32 output_addr,
+        u32 output_buffer_size);
+void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem,
+        u32 *output_buffer_size);
+
+#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
new file mode 100644
index 0000000..6781e29
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -0,0 +1,487 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/memory_alloc.h>
+#include <mach/msm_subsystem_map.h>
+#include <mach/peripheral-loader.h>
+#include <linux/delay.h>
+#include "vcd_ddl_utils.h"
+#include "vcd_ddl.h"
+#include "vcd_res_tracker_api.h"
+
+struct time_data {
+	unsigned int ddl_t1;
+	unsigned int ddl_ttotal;
+	unsigned int ddl_count;
+};
+static struct time_data proc_time[MAX_TIME_DATA];
+#define DDL_MSG_TIME(x...) printk(KERN_DEBUG x)
+static unsigned int vidc_mmu_subsystem[] =	{
+		MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
+
+#ifdef DDL_BUF_LOG
+static void ddl_print_buffer(struct ddl_context *ddl_context,
+	struct ddl_buf_addr *buf, u32 idx, u8 *str);
+static void ddl_print_port(struct ddl_context *ddl_context,
+	struct ddl_buf_addr *buf);
+static void ddl_print_buffer_port(struct ddl_context *ddl_context,
+	struct ddl_buf_addr *buf, u32 idx, u8 *str);
+#endif
+void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+	u32 alloc_size, offset = 0 ;
+	u32 index = 0;
+	struct ddl_context *ddl_context;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	unsigned long iova = 0;
+	unsigned long buffer_size = 0;
+	unsigned long *kernel_vaddr = NULL;
+	unsigned long ionflag = 0;
+	unsigned long flags = 0;
+	int ret = 0;
+	ion_phys_addr_t phyaddr = 0;
+	size_t len = 0;
+	int rc = 0;
+	DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
+	if (!addr) {
+		DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__);
+		goto bail_out;
+	}
+	ddl_context = ddl_get_context();
+	res_trk_set_mem_type(addr->mem_type);
+	alloc_size = (sz + alignment);
+	if (res_trk_get_enable_ion()) {
+		if (!ddl_context->video_ion_client)
+			ddl_context->video_ion_client =
+				res_trk_get_ion_client();
+		if (!ddl_context->video_ion_client) {
+			DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n",
+						 __func__);
+			goto bail_out;
+		}
+		alloc_size = (alloc_size+4095) & ~4095;
+		addr->alloc_handle = ion_alloc(
+		ddl_context->video_ion_client, alloc_size, SZ_4K,
+			res_trk_get_mem_type());
+		if (IS_ERR_OR_NULL(addr->alloc_handle)) {
+			DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
+						 __func__);
+			goto bail_out;
+		}
+		if (res_trk_check_for_sec_session() ||
+			addr->mem_type == DDL_FW_MEM)
+			ionflag = UNCACHED;
+		else
+			ionflag = CACHED;
+		kernel_vaddr = (unsigned long *) ion_map_kernel(
+					ddl_context->video_ion_client,
+					addr->alloc_handle, ionflag);
+		if (IS_ERR_OR_NULL(kernel_vaddr)) {
+				DDL_MSG_ERROR("%s() :DDL ION map failed\n",
+							 __func__);
+				goto free_ion_alloc;
+		}
+		addr->virtual_base_addr = (u8 *) kernel_vaddr;
+		if (res_trk_check_for_sec_session()) {
+			rc = ion_phys(ddl_context->video_ion_client,
+				addr->alloc_handle, &phyaddr,
+					&len);
+			if (rc || !phyaddr) {
+				DDL_MSG_ERROR(
+				"%s():DDL ION client physical failed\n",
+				__func__);
+				goto unmap_ion_alloc;
+			}
+			addr->alloced_phys_addr = phyaddr;
+		} else {
+			ret = ion_map_iommu(ddl_context->video_ion_client,
+					addr->alloc_handle,
+					VIDEO_DOMAIN,
+					VIDEO_MAIN_POOL,
+					SZ_4K,
+					0,
+					&iova,
+					&buffer_size,
+					UNCACHED, 0);
+			if (ret) {
+				DDL_MSG_ERROR(
+				"%s():DDL ION ion map iommu failed\n",
+				 __func__);
+				goto unmap_ion_alloc;
+			}
+			addr->alloced_phys_addr = (phys_addr_t) iova;
+		}
+		if (!addr->alloced_phys_addr) {
+			DDL_MSG_ERROR("%s():DDL ION client physical failed\n",
+						 __func__);
+			goto unmap_ion_alloc;
+		}
+		addr->mapped_buffer = NULL;
+		addr->physical_base_addr = (u8 *) addr->alloced_phys_addr;
+		addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
+			addr->physical_base_addr, alignment);
+		offset = (u32)(addr->align_physical_addr -
+				addr->physical_base_addr);
+		addr->align_virtual_addr = addr->virtual_base_addr + offset;
+		addr->buffer_size = alloc_size;
+	} else {
+		addr->alloced_phys_addr = (phys_addr_t)
+		allocate_contiguous_memory_nomap(alloc_size,
+			res_trk_get_mem_type(), SZ_4K);
+		if (!addr->alloced_phys_addr) {
+			DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n",
+					 __func__, alloc_size);
+			goto bail_out;
+		}
+		flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
+		if (alignment == DDL_KILO_BYTE(128))
+				index = 1;
+		else if (alignment > SZ_4K)
+			flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;
+
+		addr->mapped_buffer =
+		msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr,
+			alloc_size, flags, &vidc_mmu_subsystem[index],
+			sizeof(vidc_mmu_subsystem[index])/sizeof(unsigned int));
+		if (IS_ERR(addr->mapped_buffer)) {
+			pr_err(" %s() buffer map failed", __func__);
+			goto free_acm_alloc;
+		}
+		mapped_buffer = addr->mapped_buffer;
+		if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
+			pr_err("%s() map buffers failed\n", __func__);
+			goto free_map_buffers;
+		}
+		addr->physical_base_addr = (u8 *)mapped_buffer->iova[0];
+		addr->virtual_base_addr = mapped_buffer->vaddr;
+		addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
+			addr->physical_base_addr, alignment);
+		offset = (u32)(addr->align_physical_addr -
+				addr->physical_base_addr);
+		addr->align_virtual_addr = addr->virtual_base_addr + offset;
+		addr->buffer_size = sz;
+	}
+	return addr->virtual_base_addr;
+free_map_buffers:
+	msm_subsystem_unmap_buffer(addr->mapped_buffer);
+	addr->mapped_buffer = NULL;
+free_acm_alloc:
+		free_contiguous_memory_by_paddr(
+			(unsigned long)addr->alloced_phys_addr);
+		addr->alloced_phys_addr = (phys_addr_t)NULL;
+		return NULL;
+unmap_ion_alloc:
+	ion_unmap_kernel(ddl_context->video_ion_client,
+		addr->alloc_handle);
+	addr->virtual_base_addr = NULL;
+	addr->alloced_phys_addr = (phys_addr_t)NULL;
+free_ion_alloc:
+	ion_free(ddl_context->video_ion_client,
+		addr->alloc_handle);
+	addr->alloc_handle = NULL;
+bail_out:
+	return NULL;
+}
+
+void ddl_pmem_free(struct ddl_buf_addr *addr)
+{
+	struct ddl_context *ddl_context;
+	ddl_context = ddl_get_context();
+	if (!addr) {
+		pr_err("%s() invalid args\n", __func__);
+		return;
+	}
+	if (ddl_context->video_ion_client) {
+		if (!IS_ERR_OR_NULL(addr->alloc_handle)) {
+			ion_unmap_kernel(ddl_context->video_ion_client,
+					addr->alloc_handle);
+			if (!res_trk_check_for_sec_session()) {
+				ion_unmap_iommu(ddl_context->video_ion_client,
+					addr->alloc_handle,
+					VIDEO_DOMAIN,
+					VIDEO_MAIN_POOL);
+			}
+			ion_free(ddl_context->video_ion_client,
+				addr->alloc_handle);
+			}
+	} else {
+		if (addr->mapped_buffer)
+			msm_subsystem_unmap_buffer(addr->mapped_buffer);
+		if (addr->alloced_phys_addr)
+			free_contiguous_memory_by_paddr(
+				(unsigned long)addr->alloced_phys_addr);
+	}
+	memset(addr, 0, sizeof(struct ddl_buf_addr));
+}
+
+#ifdef DDL_BUF_LOG
+
+static void ddl_print_buffer(struct ddl_context *ddl_context,
+	struct ddl_buf_addr *buf, u32 idx, u8 *str)
+{
+	struct ddl_buf_addr *base_ram;
+	s32  offset;
+	size_t sz, KB = 0;
+
+	base_ram = &ddl_context->dram_base_a;
+	offset = (s32) DDL_ADDR_OFFSET(*base_ram, *buf);
+	sz = buf->buffer_size;
+	if (sz > 0) {
+		if (!(sz % 1024)) {
+			sz /= 1024;
+			KB++;
+			if (!(sz % 1024)) {
+				sz /= 1024;
+				KB++;
+			}
+		}
+	}
+	DDL_MSG_LOW("\n%12s [%2d]:  0x%08x [0x%04x],  0x%08x(%d%s),  %s",
+		str, idx, (u32) buf->align_physical_addr,
+		(offset > 0) ? offset : 0, buf->buffer_size, sz,
+		((2 == KB) ? "MB" : (1 == KB) ? "KB" : ""),
+		(((u32) buf->virtual_base_addr) ? "Alloc" : ""));
+}
+
+static void ddl_print_port(struct ddl_context *ddl_context,
+	struct ddl_buf_addr *buf)
+{
+	struct ddl_buf_addr *a = &ddl_context->dram_base_a;
+	struct ddl_buf_addr *b = &ddl_context->dram_base_b;
+
+	if (!buf->align_physical_addr || !buf->buffer_size)
+		return;
+	if (buf->align_physical_addr >= a->align_physical_addr &&
+		buf->align_physical_addr + buf->buffer_size <=
+		a->align_physical_addr + a->buffer_size)
+		DDL_MSG_LOW(" -A [0x%x]-", DDL_ADDR_OFFSET(*a, *buf));
+	else if (buf->align_physical_addr >= b->align_physical_addr &&
+		buf->align_physical_addr + buf->buffer_size <=
+		b->align_physical_addr + b->buffer_size)
+		DDL_MSG_LOW(" -B [0x%x]-", DDL_ADDR_OFFSET(*b, *buf));
+	else
+		DDL_MSG_LOW(" -?-");
+}
+
+static void ddl_print_buffer_port(struct ddl_context *ddl_context,
+	struct ddl_buf_addr *buf, u32 idx, u8 *str)
+{
+	DDL_MSG_LOW("\n");
+	ddl_print_buffer(ddl_context, buf, idx, str);
+	ddl_print_port(ddl_context, buf);
+}
+
+void ddl_list_buffers(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context;
+	u32 i;
+
+	ddl_context = ddl->ddl_context;
+	DDL_MSG_LOW("\n\n");
+	DDL_MSG_LOW("\n      Buffer     :     Start    [offs],      Size    \
+	(Size),     Alloc/Port");
+	DDL_MSG_LOW("\n-------------------------------------------------------\
+	-------------------------");
+	ddl_print_buffer(ddl_context, &ddl_context->dram_base_a, 0,
+		"dram_base_a");
+	ddl_print_buffer(ddl_context, &ddl_context->dram_base_b, 0,
+		"dram_base_b");
+	if (ddl->codec_data.hdr.decoding) {
+		struct ddl_dec_buffers  *dec_bufs =
+			&ddl->codec_data.decoder.hw_bufs;
+		for (i = 0; i < 32; i++)
+			ddl_print_buffer_port(ddl_context,
+				&dec_bufs->h264Mv[i], i, "h264Mv");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->h264Vert_nb_mv, 0, "h264Vert_nb_mv");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->h264Nb_ip, 0, "h264Nb_ip");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->nb_dcac, 0, "nb_dcac");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->upnb_mv, 0, "upnb_mv");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->sub_anchor_mv, 0, "sub_anchor_mv");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->overlay_xform, 0, "overlay_xform");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->bit_plane3, 0, "bit_plane3");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->bit_plane2, 0, "bit_plane2");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->bit_plane1, 0, "bit_plane1");
+		ddl_print_buffer_port(ddl_context,
+			dec_bufs->stx_parser, 0, "stx_parser");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->desc, 0, "desc");
+		ddl_print_buffer_port(ddl_context,
+			&dec_bufs->context, 0, "context");
+	} else {
+		struct ddl_enc_buffers  *enc_bufs =
+			&ddl->codec_data.encoder.hw_bufs;
+
+		for (i = 0; i < 4; i++)
+			ddl_print_buffer_port(ddl_context,
+				&enc_bufs->dpb_y[i], i, "dpb_y");
+		for (i = 0; i < 4; i++)
+			ddl_print_buffer_port(ddl_context,
+				&enc_bufs->dpb_c[i], i, "dpb_c");
+		ddl_print_buffer_port(ddl_context, &enc_bufs->mv, 0, "mv");
+		ddl_print_buffer_port(ddl_context,
+			&enc_bufs->col_zero, 0, "col_zero");
+		ddl_print_buffer_port(ddl_context, &enc_bufs->md, 0, "md");
+		ddl_print_buffer_port(ddl_context,
+			&enc_bufs->pred, 0, "pred");
+		ddl_print_buffer_port(ddl_context,
+			&enc_bufs->nbor_info, 0, "nbor_info");
+		ddl_print_buffer_port(ddl_context,
+			&enc_bufs->acdc_coef, 0, "acdc_coef");
+		ddl_print_buffer_port(ddl_context,
+			&enc_bufs->context, 0, "context");
+	}
+}
+#endif
+
+u32 ddl_fw_init(struct ddl_buf_addr *dram_base)
+{
+	u8 *dest_addr;
+	dest_addr = DDL_GET_ALIGNED_VITUAL(*dram_base);
+	DDL_MSG_LOW("FW Addr / FW Size : %x/%d", (u32)vidc_video_codec_fw,
+		vidc_video_codec_fw_size);
+	if (res_trk_check_for_sec_session() && res_trk_is_cp_enabled()) {
+		if (res_trk_enable_footswitch()) {
+			pr_err("Failed to enable footswitch");
+			return false;
+		}
+		if(res_trk_enable_iommu_clocks()) {
+			res_trk_disable_footswitch();
+			pr_err("Failed to enable iommu clocks\n");
+			return false;
+		}
+		dram_base->pil_cookie = pil_get("vidc");
+		if(res_trk_disable_iommu_clocks())
+			pr_err("Failed to disable iommu clocks\n");
+		if (IS_ERR_OR_NULL(dram_base->pil_cookie)) {
+			pr_err("pil_get failed\n");
+			return false;
+		}
+	} else {
+		if (vidc_video_codec_fw_size > dram_base->buffer_size ||
+				!vidc_video_codec_fw)
+			return false;
+		memcpy(dest_addr, vidc_video_codec_fw,
+				vidc_video_codec_fw_size);
+	}
+	return true;
+}
+
+void ddl_fw_release(struct ddl_buf_addr *dram_base)
+{
+	void *cookie = dram_base->pil_cookie;
+   if (res_trk_is_cp_enabled() &&
+         res_trk_check_for_sec_session()) {
+      res_trk_close_secure_session();
+      if (IS_ERR_OR_NULL(cookie)){
+         pr_err("Invalid params");
+         return;
+      }
+      if (res_trk_enable_footswitch()) {
+         pr_err("Failed to enable footswitch");
+         return;
+      }
+      if(res_trk_enable_iommu_clocks()) {
+         res_trk_disable_footswitch();
+         pr_err("Failed to enable iommu clocks\n");
+         return;
+      }
+      pil_put(cookie);
+      if(res_trk_disable_iommu_clocks())
+         pr_err("Failed to disable iommu clocks\n");
+      if(res_trk_disable_footswitch())
+         pr_err("Failed to disable footswitch\n");
+   } else {
+         if (res_trk_check_for_sec_session())
+            res_trk_close_secure_session();
+		res_trk_release_fw_addr();
+   }
+}
+
+void ddl_set_core_start_time(const char *func_name, u32 index)
+{
+	u32 act_time;
+	struct timeval ddl_tv;
+	struct time_data *time_data = &proc_time[index];
+	do_gettimeofday(&ddl_tv);
+	act_time = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000);
+	if (!time_data->ddl_t1) {
+		time_data->ddl_t1 = act_time;
+		DDL_MSG_LOW("\n%s(): Start Time (%u)", func_name, act_time);
+	} else {
+		DDL_MSG_TIME("\n%s(): Timer already started! St(%u) Act(%u)",
+			func_name, time_data->ddl_t1, act_time);
+	}
+}
+
+void ddl_calc_core_proc_time(const char *func_name, u32 index)
+{
+	struct time_data *time_data = &proc_time[index];
+	if (time_data->ddl_t1) {
+		int ddl_t2;
+		struct timeval ddl_tv;
+		do_gettimeofday(&ddl_tv);
+		ddl_t2 = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000);
+		time_data->ddl_ttotal += (ddl_t2 - time_data->ddl_t1);
+		time_data->ddl_count++;
+		DDL_MSG_TIME("\n%s(): cnt(%u) End Time (%u) Diff(%u) Avg(%u)",
+			func_name, time_data->ddl_count, ddl_t2,
+			ddl_t2 - time_data->ddl_t1,
+			time_data->ddl_ttotal/time_data->ddl_count);
+		time_data->ddl_t1 = 0;
+	}
+}
+
+void ddl_calc_core_proc_time_cnt(const char *func_name, u32 index, u32 count)
+{
+	struct time_data *time_data = &proc_time[index];
+	if (time_data->ddl_t1) {
+		int ddl_t2;
+		struct timeval ddl_tv;
+		do_gettimeofday(&ddl_tv);
+		ddl_t2 = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000);
+		time_data->ddl_ttotal += (ddl_t2 - time_data->ddl_t1);
+		time_data->ddl_count += count;
+		DDL_MSG_TIME("\n%s(): cnt(%u) End Time (%u) Diff(%u) Avg(%u)",
+			func_name, time_data->ddl_count, ddl_t2,
+			ddl_t2 - time_data->ddl_t1,
+			time_data->ddl_ttotal/time_data->ddl_count);
+		time_data->ddl_t1 = 0;
+	}
+}
+
+void ddl_update_core_start_time(const char *func_name, u32 index)
+{
+	u32 act_time;
+	struct timeval ddl_tv;
+	struct time_data *time_data = &proc_time[index];
+	do_gettimeofday(&ddl_tv);
+	act_time = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000);
+	time_data->ddl_t1 = act_time;
+	DDL_MSG_LOW("\n%s(): Start time updated Act(%u)",
+				func_name, act_time);
+}
+
+void ddl_reset_core_time_variables(u32 index)
+{
+	proc_time[index].ddl_t1 = 0;
+	proc_time[index].ddl_ttotal = 0;
+	proc_time[index].ddl_count = 0;
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
new file mode 100644
index 0000000..13bef35
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
@@ -0,0 +1,77 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VCD_DDL_UTILS_H_
+#define _VCD_DDL_UTILS_H_
+
+#include <linux/delay.h>
+#include <media/msm/vidc_type.h>
+
+extern u32 vidc_msg_pmem;
+extern u32 vidc_msg_timing;
+
+enum timing_data {
+	DEC_OP_TIME,
+	DEC_IP_TIME,
+	ENC_OP_TIME,
+	ENC_SLICE_OP_TIME,
+	MAX_TIME_DATA
+};
+
+#define DBG_PMEM(x...) \
+do { \
+	if (vidc_msg_pmem) \
+		printk(KERN_DEBUG x); \
+} while (0)
+
+#ifdef DDL_MSG_LOG
+#define DDL_MSG_LOW(x...)    printk(KERN_INFO x)
+#define DDL_MSG_MED(x...)    printk(KERN_INFO x)
+#define DDL_MSG_HIGH(x...)   printk(KERN_INFO x)
+#else
+#define DDL_MSG_LOW(x...)
+#define DDL_MSG_MED(x...)
+#define DDL_MSG_HIGH(x...)
+#endif
+
+#define DDL_MSG_ERROR(x...)  printk(KERN_INFO x)
+#define DDL_MSG_FATAL(x...)  printk(KERN_INFO x)
+
+#define DDL_ALIGN_SIZE(sz, guard_bytes, align_mask) \
+	(((u32)(sz) + guard_bytes) & align_mask)
+#define DDL_ADDR_IS_ALIGNED(addr, align_bytes) \
+	(!((u32)(addr) & ((align_bytes) - 1)))
+#define  DDL_ALIGN(val, grid) ((!(grid)) ? (val) : \
+		((((val) + (grid) - 1) / (grid)) * (grid)))
+#define  DDL_ALIGN_FLOOR(val, grid) ((!(grid)) ? (val) : \
+		(((val) / (grid)) * (grid)))
+#define DDL_OFFSET(base, addr) ((!(addr)) ? 0 : (u32)((u8 *) \
+		(addr) - (u8 *) (base)))
+#define DDL_ADDR_OFFSET(base, addr) DDL_OFFSET((base).align_physical_addr, \
+		(addr).align_physical_addr)
+#define DDL_GET_ALIGNED_VITUAL(x)   ((x).align_virtual_addr)
+#define DDL_KILO_BYTE(x)   ((x)*1024)
+#define DDL_MEGA_BYTE(x)   ((x)*1024*1024)
+#define DDL_FRAMERATE_SCALE(x)            ((x) * 1000)
+
+#define DDL_MIN(x, y)  ((x < y) ? x : y)
+#define DDL_MAX(x, y)  ((x > y) ? x : y)
+#define DDL_MEMCPY(dest, src, len)  memcpy((dest), (src), (len))
+#define DDL_MEMSET(src, value, len) memset((src), (value), (len))
+
+void ddl_set_core_start_time(const char *func_name, u32 index);
+void ddl_calc_core_proc_time(const char *func_name, u32 index);
+void ddl_reset_core_time_variables(u32 index);
+void ddl_calc_core_proc_time_cnt(const char *func_name, u32 index, u32 count);
+void ddl_update_core_start_time(const char *func_name, u32 index);
+#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
new file mode 100644
index 0000000..c4ab478
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -0,0 +1,1164 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vcd_ddl.h"
+#include "vcd_ddl_metadata.h"
+#include "vcd_ddl_shared_mem.h"
+#include "vcd_core.h"
+
+#if defined(PIX_CACHE_DISABLE)
+#define DDL_PIX_CACHE_ENABLE  false
+#else
+#define DDL_PIX_CACHE_ENABLE  true
+#endif
+static unsigned int run_cnt;
+
+void ddl_vidc_core_init(struct ddl_context *ddl_context)
+{
+	struct vidc_1080P_pix_cache_config pixel_cache_config;
+
+	vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE);
+	msleep(DDL_SW_RESET_SLEEP);
+	vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE);
+	vidc_1080p_init_memory_controller(
+		(u32) ddl_context->dram_base_a.align_physical_addr,
+		(u32) ddl_context->dram_base_b.align_physical_addr);
+	vidc_1080p_clear_returned_channel_inst_id();
+	ddl_context->vidc_decode_seq_start[0] =
+		vidc_1080p_decode_seq_start_ch0;
+	ddl_context->vidc_decode_seq_start[1] =
+		vidc_1080p_decode_seq_start_ch1;
+	ddl_context->vidc_decode_init_buffers[0] =
+		vidc_1080p_decode_init_buffers_ch0;
+	ddl_context->vidc_decode_init_buffers[1] =
+		vidc_1080p_decode_init_buffers_ch1;
+	ddl_context->vidc_decode_frame_start[0] =
+		vidc_1080p_decode_frame_start_ch0;
+	ddl_context->vidc_decode_frame_start[1] =
+		vidc_1080p_decode_frame_start_ch1;
+	ddl_context->vidc_set_dec_resolution[0] =
+		vidc_1080p_set_dec_resolution_ch0;
+	ddl_context->vidc_set_dec_resolution[1] =
+		vidc_1080p_set_dec_resolution_ch1;
+	ddl_context->vidc_encode_seq_start[0] =
+		vidc_1080p_encode_seq_start_ch0;
+	ddl_context->vidc_encode_seq_start[1] =
+		vidc_1080p_encode_seq_start_ch1;
+	ddl_context->vidc_encode_frame_start[0] =
+		vidc_1080p_encode_frame_start_ch0;
+	ddl_context->vidc_encode_frame_start[1] =
+		vidc_1080p_encode_frame_start_ch1;
+	ddl_context->vidc_encode_slice_batch_start[0] =
+		vidc_1080p_encode_slice_batch_start_ch0;
+	ddl_context->vidc_encode_slice_batch_start[1] =
+		vidc_1080p_encode_slice_batch_start_ch1;
+	vidc_1080p_release_sw_reset();
+	ddl_context->pix_cache_enable = DDL_PIX_CACHE_ENABLE;
+	if (ddl_context->pix_cache_enable) {
+		vidc_pix_cache_sw_reset();
+		pixel_cache_config.cache_enable = true;
+		pixel_cache_config.prefetch_en = true;
+		pixel_cache_config.port_select = VIDC_1080P_PIX_CACHE_PORT_B;
+		pixel_cache_config.statistics_off = true;
+		pixel_cache_config.page_size =
+			VIDC_1080P_PIX_CACHE_PAGE_SIZE_1K;
+		vidc_pix_cache_init_config(&pixel_cache_config);
+	}
+}
+
+void ddl_vidc_core_term(struct ddl_context *ddl_context)
+{
+	if (ddl_context->pix_cache_enable) {
+		u32 pix_cache_idle = false;
+		u32 counter = 0;
+
+		vidc_pix_cache_set_halt(true);
+
+		do {
+			msleep(DDL_SW_RESET_SLEEP);
+			vidc_pix_cache_get_status_idle(&pix_cache_idle);
+			counter++;
+		} while (!pix_cache_idle &&
+			counter < DDL_PIXEL_CACHE_STATUS_READ_RETRY);
+
+		if (!pix_cache_idle) {
+			ddl_context->cmd_err_status =
+				DDL_PIXEL_CACHE_NOT_IDLE;
+			ddl_handle_core_errors(ddl_context);
+		}
+	}
+}
+
+void ddl_vidc_channel_set(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	enum vcd_codec *vcd_codec;
+	enum vidc_1080p_codec codec = VIDC_1080P_H264_DECODE;
+	const enum vidc_1080p_decode_p_cache_enable
+		dec_pix_cache = VIDC_1080P_DECODE_PCACHE_DISABLE;
+	const enum vidc_1080p_encode_p_cache_enable
+		enc_pix_cache = VIDC_1080P_ENCODE_PCACHE_ENABLE;
+	u32 pix_cache_ctrl, ctxt_mem_offset, ctxt_mem_size;
+
+	if (ddl->decoding) {
+		if (vidc_msg_timing)
+			ddl_set_core_start_time(__func__, DEC_OP_TIME);
+		vcd_codec = &(ddl->codec_data.decoder.codec.codec);
+		pix_cache_ctrl = (u32)dec_pix_cache;
+		ctxt_mem_offset = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+		ddl->codec_data.decoder.hw_bufs.context) >> 11;
+		ctxt_mem_size =
+			ddl->codec_data.decoder.hw_bufs.context.buffer_size;
+	} else {
+		vcd_codec = &(ddl->codec_data.encoder.codec.codec);
+		pix_cache_ctrl = (u32)enc_pix_cache;
+		ctxt_mem_offset = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			ddl->codec_data.encoder.hw_bufs.context) >> 11;
+		ctxt_mem_size =
+			ddl->codec_data.encoder.hw_bufs.context.buffer_size;
+	}
+	switch (*vcd_codec) {
+	default:
+	case VCD_CODEC_MPEG4:
+		if (ddl->decoding)
+			codec = VIDC_1080P_MPEG4_DECODE;
+		else
+			codec = VIDC_1080P_MPEG4_ENCODE;
+	break;
+	case VCD_CODEC_H264:
+		if (ddl->decoding)
+			codec = VIDC_1080P_H264_DECODE;
+		else
+			codec = VIDC_1080P_H264_ENCODE;
+	break;
+	case VCD_CODEC_DIVX_3:
+		if (ddl->decoding)
+			codec = VIDC_1080P_DIVX311_DECODE;
+	break;
+	case VCD_CODEC_DIVX_4:
+		if (ddl->decoding)
+			codec = VIDC_1080P_DIVX412_DECODE;
+	break;
+	case VCD_CODEC_DIVX_5:
+		if (ddl->decoding)
+			codec = VIDC_1080P_DIVX502_DECODE;
+	break;
+	case VCD_CODEC_DIVX_6:
+		if (ddl->decoding)
+			codec = VIDC_1080P_DIVX503_DECODE;
+	break;
+	case VCD_CODEC_XVID:
+		if (ddl->decoding)
+			codec = VIDC_1080P_MPEG4_DECODE;
+	break;
+	case VCD_CODEC_H263:
+		if (ddl->decoding)
+			codec = VIDC_1080P_H263_DECODE;
+		else
+			codec = VIDC_1080P_H263_ENCODE;
+	break;
+	case VCD_CODEC_MPEG1:
+	case VCD_CODEC_MPEG2:
+		if (ddl->decoding)
+			codec = VIDC_1080P_MPEG2_DECODE;
+	break;
+	case VCD_CODEC_VC1:
+		if (ddl->decoding)
+			codec = VIDC_1080P_VC1_DECODE;
+	break;
+	case VCD_CODEC_VC1_RCV:
+		if (ddl->decoding)
+			codec = VIDC_1080P_VC1_RCV_DECODE;
+	break;
+	}
+	ddl->cmd_state = DDL_CMD_CHANNEL_SET;
+	DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_CHDONE",
+	ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_CHDONE;
+	vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_OPEN_CH,
+		(u32)codec, pix_cache_ctrl, ctxt_mem_offset,
+		ctxt_mem_size);
+}
+
+void ddl_vidc_decode_init_codec(struct ddl_client_context *ddl)
+{
+	struct ddl_context  *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vidc_1080p_dec_seq_start_param seq_start_param;
+	u32 seq_size;
+
+	if (vidc_msg_timing)
+		ddl_set_core_start_time(__func__, DEC_OP_TIME);
+	vidc_1080p_set_decode_mpeg4_pp_filter(decoder->post_filter.post_filter);
+	vidc_sm_set_concealment_color(&ddl->shared_mem[ddl->command_channel],
+		DDL_CONCEALMENT_Y_COLOR, DDL_CONCEALMENT_C_COLOR);
+	ddl_vidc_metadata_enable(ddl);
+	vidc_sm_set_metadata_start_address(&ddl->shared_mem
+		[ddl->command_channel],
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+		ddl->codec_data.decoder.meta_data_input));
+
+	vidc_sm_set_idr_decode_only(&ddl->shared_mem[ddl->command_channel],
+			decoder->idr_only_decoding);
+
+	if ((decoder->codec.codec == VCD_CODEC_DIVX_3) ||
+	   (decoder->codec.codec == VCD_CODEC_VC1_RCV ||
+		decoder->codec.codec == VCD_CODEC_VC1))
+		ddl_context->vidc_set_dec_resolution
+		[ddl->command_channel](decoder->client_frame_size.width,
+		decoder->client_frame_size.height);
+	else
+	ddl_context->vidc_set_dec_resolution
+	[ddl->command_channel](0x0, 0x0);
+	DDL_MSG_LOW("HEADER-PARSE-START");
+	DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+	"DDL_CLIENT_WAIT_FOR_INITCODECDONE",
+	ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODECDONE;
+	ddl->cmd_state = DDL_CMD_HEADER_PARSE;
+	seq_start_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	seq_start_param.inst_id = ddl->instance_id;
+	seq_start_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+	ddl_context->dram_base_a, ddl->shared_mem
+		[ddl->command_channel]);
+	seq_start_param.stream_buffer_addr_offset =
+	DDL_OFFSET(ddl_context->dram_base_a.align_physical_addr,
+	decoder->decode_config.sequence_header);
+	seq_start_param.stream_buffersize =
+		decoder->client_input_buf_req.sz;
+	seq_size = decoder->decode_config.sequence_header_len +
+		DDL_LINEAR_BUFFER_ALIGN_BYTES + VCD_SEQ_HDR_PADDING_BYTES;
+	if (seq_start_param.stream_buffersize < seq_size)
+		seq_start_param.stream_buffersize = seq_size;
+	seq_start_param.stream_frame_size =
+		decoder->decode_config.sequence_header_len;
+	seq_start_param.descriptor_buffer_addr_offset =
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+		decoder->hw_bufs.desc),
+	seq_start_param.descriptor_buffer_size =
+		decoder->hw_bufs.desc.buffer_size;
+	if ((decoder->codec.codec == VCD_CODEC_MPEG4) ||
+		(decoder->codec.codec == VCD_CODEC_DIVX_4) ||
+		(decoder->codec.codec == VCD_CODEC_DIVX_5) ||
+		(decoder->codec.codec == VCD_CODEC_DIVX_6) ||
+		(decoder->codec.codec == VCD_CODEC_XVID))
+		vidc_sm_set_mpeg4_profile_override(
+			&ddl->shared_mem[ddl->command_channel],
+			VIDC_SM_PROFILE_INFO_ASP);
+	if (VCD_CODEC_H264 == decoder->codec.codec)
+		vidc_sm_set_decoder_sei_enable(
+			&ddl->shared_mem[ddl->command_channel],
+			VIDC_SM_RECOVERY_POINT_SEI);
+	ddl_context->vidc_decode_seq_start[ddl->command_channel](
+		&seq_start_param);
+
+	vidc_sm_set_decoder_stuff_bytes_consumption(
+		&ddl->shared_mem[ddl->command_channel],
+		VIDC_SM_NUM_STUFF_BYTES_CONSUME_NONE);
+}
+
+void ddl_vidc_decode_dynamic_property(struct ddl_client_context *ddl,
+	u32 enable)
+{
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vcd_frame_data *bit_stream =
+		&(ddl->input_frame.vcd_frm);
+	struct ddl_context *ddl_context = ddl->ddl_context;
+
+	if (!enable) {
+		if (decoder->dynmic_prop_change_req)
+			decoder->dynmic_prop_change_req = false;
+		return;
+	}
+	if ((decoder->dynamic_prop_change & DDL_DEC_REQ_OUTPUT_FLUSH)) {
+		decoder->dynmic_prop_change_req = true;
+		decoder->dynamic_prop_change &= ~(DDL_DEC_REQ_OUTPUT_FLUSH);
+		decoder->dpb_mask.hw_mask = 0;
+		decoder->flush_pending = true;
+	}
+	if (((decoder->meta_data_enable_flag & VCD_METADATA_PASSTHROUGH)) &&
+		((VCD_FRAME_FLAG_EXTRADATA & bit_stream->flags))) {
+		u32 extradata_presence = true;
+		u8* tmp = ((u8 *) bit_stream->physical +
+				bit_stream->offset +
+				bit_stream->data_len + 3);
+		u32 extra_data_start = (u32) ((u32)tmp & ~3);
+
+		extra_data_start = extra_data_start -
+			(u32)ddl_context->dram_base_a.align_physical_addr;
+		decoder->dynmic_prop_change_req = true;
+		vidc_sm_set_extradata_addr(&ddl->shared_mem
+			[ddl->command_channel], extra_data_start);
+		vidc_sm_set_extradata_presence(&ddl->shared_mem
+			[ddl->command_channel], extradata_presence);
+	}
+}
+
+void ddl_vidc_encode_dynamic_property(struct ddl_client_context *ddl,
+	u32 enable)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	u32 frame_rate_change = false, bit_rate_change = false;
+	u32 i_period_change = false, reset_req = false;
+
+	if (!enable) {
+		if (encoder->dynmic_prop_change_req) {
+			reset_req = true;
+			encoder->dynmic_prop_change_req = false;
+		}
+	} else {
+		if ((encoder->dynamic_prop_change & DDL_ENC_REQ_IFRAME)) {
+			encoder->intra_frame_insertion = true;
+			encoder->dynamic_prop_change &=
+				~(DDL_ENC_REQ_IFRAME);
+		}
+		if ((encoder->dynamic_prop_change &
+			DDL_ENC_CHANGE_BITRATE)) {
+			bit_rate_change = true;
+			vidc_sm_set_encoder_new_bit_rate(
+				&ddl->shared_mem[ddl->command_channel],
+				encoder->target_bit_rate.target_bitrate);
+			encoder->dynamic_prop_change &=
+				~(DDL_ENC_CHANGE_BITRATE);
+		}
+		if ((encoder->dynamic_prop_change
+			& DDL_ENC_CHANGE_IPERIOD)) {
+			i_period_change = true;
+			vidc_sm_set_encoder_new_i_period(
+				&ddl->shared_mem[ddl->command_channel],
+				encoder->i_period.p_frames);
+			encoder->dynamic_prop_change &=
+				~(DDL_ENC_CHANGE_IPERIOD);
+		}
+		if ((encoder->dynamic_prop_change
+			& DDL_ENC_CHANGE_FRAMERATE)) {
+			frame_rate_change = true;
+			vidc_sm_set_encoder_new_frame_rate(
+				&ddl->shared_mem[ddl->command_channel],
+				(u32)(DDL_FRAMERATE_SCALE(encoder->\
+				frame_rate.fps_numerator) /
+				encoder->frame_rate.fps_denominator));
+			encoder->dynamic_prop_change &=
+				~(DDL_ENC_CHANGE_FRAMERATE);
+		}
+	}
+	if ((enable) || (reset_req)) {
+		vidc_sm_set_encoder_param_change(
+			&ddl->shared_mem[ddl->command_channel],
+			bit_rate_change, frame_rate_change,
+			i_period_change);
+	}
+}
+
+static void ddl_vidc_encode_set_profile_level(
+	struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	u32  encode_profile, level = 0;
+
+	switch (encoder->profile.profile) {
+	default:
+	case VCD_PROFILE_MPEG4_SP:
+		encode_profile = VIDC_1080P_PROFILE_MPEG4_SIMPLE;
+	break;
+	case VCD_PROFILE_MPEG4_ASP:
+		encode_profile = VIDC_1080P_PROFILE_MPEG4_ADV_SIMPLE;
+	break;
+	case VCD_PROFILE_H264_BASELINE:
+		encode_profile = VIDC_1080P_PROFILE_H264_BASELINE;
+	break;
+	case VCD_PROFILE_H264_MAIN:
+		encode_profile = VIDC_1080P_PROFILE_H264_MAIN;
+	break;
+	case VCD_PROFILE_H264_HIGH:
+		encode_profile = VIDC_1080P_PROFILE_H264_HIGH;
+	break;
+	}
+	switch (encoder->level.level) {
+	default:
+	case VCD_LEVEL_MPEG4_0:
+		level = VIDC_1080P_MPEG4_LEVEL0;
+	break;
+	case VCD_LEVEL_MPEG4_0b:
+		level = VIDC_1080P_MPEG4_LEVEL0b;
+	break;
+	case VCD_LEVEL_MPEG4_1:
+		level = VIDC_1080P_MPEG4_LEVEL1;
+	break;
+	case VCD_LEVEL_MPEG4_2:
+		level = VIDC_1080P_MPEG4_LEVEL2;
+	break;
+	case VCD_LEVEL_MPEG4_3:
+		level = VIDC_1080P_MPEG4_LEVEL3;
+	break;
+	case VCD_LEVEL_MPEG4_3b:
+		level = VIDC_1080P_MPEG4_LEVEL3b;
+	break;
+	case VCD_LEVEL_MPEG4_4:
+		level = VIDC_1080P_MPEG4_LEVEL4;
+	break;
+	case VCD_LEVEL_MPEG4_4a:
+		level = VIDC_1080P_MPEG4_LEVEL4a;
+	break;
+	case VCD_LEVEL_MPEG4_5:
+		level = VIDC_1080P_MPEG4_LEVEL5;
+	break;
+	case VCD_LEVEL_MPEG4_6:
+		level = VIDC_1080P_MPEG4_LEVEL6;
+	break;
+	case VCD_LEVEL_MPEG4_7:
+		level = VIDC_1080P_MPEG4_LEVEL7;
+	break;
+	case VCD_LEVEL_H264_1:
+		level = VIDC_1080P_H264_LEVEL1;
+	break;
+	case VCD_LEVEL_H264_1b:
+		level = VIDC_1080P_H264_LEVEL1b;
+	break;
+	case VCD_LEVEL_H264_1p1:
+		level = VIDC_1080P_H264_LEVEL1p1;
+	break;
+	case VCD_LEVEL_H264_1p2:
+		level = VIDC_1080P_H264_LEVEL1p2;
+	break;
+	case VCD_LEVEL_H264_1p3:
+		level = VIDC_1080P_H264_LEVEL1p3;
+	break;
+	case VCD_LEVEL_H264_2:
+		level = VIDC_1080P_H264_LEVEL2;
+	break;
+	case VCD_LEVEL_H264_2p1:
+		level = VIDC_1080P_H264_LEVEL2p1;
+	break;
+	case VCD_LEVEL_H264_2p2:
+		level = VIDC_1080P_H264_LEVEL2p2;
+	break;
+	case VCD_LEVEL_H264_3:
+		level = VIDC_1080P_H264_LEVEL3;
+	break;
+	case VCD_LEVEL_H264_3p1:
+		level = VIDC_1080P_H264_LEVEL3p1;
+	break;
+	case VCD_LEVEL_H264_3p2:
+		level = VIDC_1080P_H264_LEVEL3p2;
+	break;
+	case VCD_LEVEL_H264_4:
+		level = VIDC_1080P_H264_LEVEL4;
+	break;
+	case VCD_LEVEL_H263_10:
+		level = VIDC_1080P_H263_LEVEL10;
+	break;
+	case VCD_LEVEL_H263_20:
+		level = VIDC_1080P_H263_LEVEL20;
+	break;
+	case VCD_LEVEL_H263_30:
+		level = VIDC_1080P_H263_LEVEL30;
+	break;
+	case VCD_LEVEL_H263_40:
+		level = VIDC_1080P_H263_LEVEL40;
+	break;
+	case VCD_LEVEL_H263_45:
+		level = VIDC_1080P_H263_LEVEL45;
+	break;
+	case VCD_LEVEL_H263_50:
+		level = VIDC_1080P_H263_LEVEL50;
+	break;
+	case VCD_LEVEL_H263_60:
+		level = VIDC_1080P_H263_LEVEL60;
+	break;
+	case VCD_LEVEL_H263_70:
+		level = VIDC_1080P_H263_LEVEL70;
+	break;
+	}
+	vidc_1080p_set_encode_profile_level(encode_profile, level);
+}
+
+static void ddl_vidc_encode_set_multi_slice_info(
+	struct ddl_encoder_data *encoder)
+{
+	enum vidc_1080p_MSlice_selection m_slice_sel;
+	u32 i_multi_slice_size = 0, i_multi_slice_byte = 0;
+
+	if (!encoder) {
+		DDL_MSG_ERROR("Invalid Parameter");
+		return;
+	}
+
+	switch (encoder->multi_slice.m_slice_sel) {
+	default:
+	case VCD_MSLICE_OFF:
+		m_slice_sel = VIDC_1080P_MSLICE_DISABLE;
+	break;
+	case VCD_MSLICE_BY_GOB:
+	case VCD_MSLICE_BY_MB_COUNT:
+		m_slice_sel = VIDC_1080P_MSLICE_BY_MB_COUNT;
+		i_multi_slice_size = encoder->multi_slice.m_slice_size;
+	break;
+	case VCD_MSLICE_BY_BYTE_COUNT:
+		m_slice_sel = VIDC_1080P_MSLICE_BY_BYTE_COUNT;
+		i_multi_slice_byte = encoder->multi_slice.m_slice_size;
+	break;
+	}
+	vidc_1080p_set_encode_multi_slice_control(m_slice_sel,
+		i_multi_slice_size, i_multi_slice_byte);
+}
+
+static void ddl_vidc_encode_set_batch_slice_info(
+	struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	DDL_MSG_LOW("%s\n", __func__);
+	encoder->batch_frame.slice_batch_out.buffer_size =
+					encoder->output_buf_req.sz;
+	DDL_MSG_LOW("encoder->batch_frame.slice_batch_out.buffer_size = %d\n",
+			encoder->batch_frame.slice_batch_out.buffer_size);
+	vidc_sm_set_encoder_batch_config(
+			&ddl->shared_mem[ddl->command_channel],
+			1,
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			encoder->batch_frame.slice_batch_in),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			encoder->batch_frame.slice_batch_out),
+			encoder->batch_frame.slice_batch_out.buffer_size);
+	vidc_sm_set_encoder_slice_batch_int_ctrl(
+			&ddl->shared_mem[ddl->command_channel],
+			0);
+}
+
+void ddl_vidc_encode_init_codec(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	struct ddl_enc_buffers *enc_buffers = &encoder->hw_bufs;
+	struct vidc_1080p_enc_seq_start_param seq_start_param;
+	enum vidc_1080p_memory_access_method mem_access_method;
+	enum vidc_1080p_DBConfig db_config;
+	enum VIDC_SM_frame_skip r_cframe_skip =
+		VIDC_SM_FRAME_SKIP_DISABLE;
+	u32 index, luma[4], chroma[4], hdr_ext_control = false;
+	const u32 recon_bufs = 4;
+	u32 h263_cpfc_enable = false;
+	u32 scaled_frame_rate;
+
+	ddl_vidc_encode_set_profile_level(ddl);
+	vidc_1080p_set_encode_frame_size(encoder->frame_size.width,
+		encoder->frame_size.height);
+	vidc_1080p_encode_set_qp_params(encoder->qp_range.max_qp,
+		encoder->qp_range.min_qp);
+	vidc_1080p_encode_set_rc_config(encoder->rc_level.frame_level_rc,
+		encoder->rc_level.mb_level_rc,
+		encoder->session_qp.i_frame_qp);
+	if (encoder->hdr_ext_control > 0)
+		hdr_ext_control = true;
+	if (encoder->r_cframe_skip > 0)
+		r_cframe_skip = VIDC_SM_FRAME_SKIP_ENABLE_LEVEL;
+	scaled_frame_rate = DDL_FRAMERATE_SCALE(encoder->\
+			frame_rate.fps_numerator) /
+			encoder->frame_rate.fps_denominator;
+	if ((encoder->codec.codec == VCD_CODEC_H263) &&
+		(DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE)
+		 != scaled_frame_rate))
+		h263_cpfc_enable = true;
+	vidc_sm_set_extended_encoder_control(&ddl->shared_mem
+		[ddl->command_channel], hdr_ext_control,
+		r_cframe_skip, false, 0,
+		h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag,
+		encoder->closed_gop);
+	vidc_sm_set_encoder_init_rc_value(&ddl->shared_mem
+		[ddl->command_channel],
+		encoder->target_bit_rate.target_bitrate);
+	vidc_sm_set_encoder_hec_period(&ddl->shared_mem
+		[ddl->command_channel], encoder->hdr_ext_control);
+		vidc_sm_set_encoder_vop_time(&ddl->shared_mem
+			[ddl->command_channel], true,
+			encoder->vop_timing.vop_time_resolution, 0);
+	if (encoder->rc_level.frame_level_rc)
+		vidc_1080p_encode_set_frame_level_rc_params(
+			scaled_frame_rate,
+			encoder->target_bit_rate.target_bitrate,
+			encoder->frame_level_rc.reaction_coeff);
+	if (encoder->rc_level.mb_level_rc)
+		vidc_1080p_encode_set_mb_level_rc_params(
+			encoder->adaptive_rc.disable_dark_region_as_flag,
+			encoder->adaptive_rc.disable_smooth_region_as_flag,
+			encoder->adaptive_rc.disable_static_region_as_flag,
+			encoder->adaptive_rc.disable_activity_region_flag);
+	if ((!encoder->rc_level.frame_level_rc) &&
+		(!encoder->rc_level.mb_level_rc))
+		vidc_sm_set_pand_b_frame_qp(
+			&ddl->shared_mem[ddl->command_channel],
+			encoder->session_qp.b_frame_qp,
+			encoder->session_qp.p_frame_qp);
+	if (encoder->codec.codec == VCD_CODEC_MPEG4) {
+		vidc_1080p_set_mpeg4_encode_quarter_pel_control(false);
+		vidc_1080p_set_encode_field_picture_structure(false);
+	}
+	if (encoder->codec.codec == VCD_CODEC_H264) {
+		enum vidc_1080p_entropy_sel entropy_sel;
+		switch (encoder->entropy_control.entropy_sel) {
+		default:
+		case VCD_ENTROPY_SEL_CAVLC:
+			entropy_sel = VIDC_1080P_ENTROPY_SEL_CAVLC;
+		break;
+		case VCD_ENTROPY_SEL_CABAC:
+			entropy_sel = VIDC_1080P_ENTROPY_SEL_CABAC;
+		break;
+	}
+	vidc_1080p_set_h264_encode_entropy(entropy_sel);
+	switch (encoder->db_control.db_config) {
+	default:
+	case VCD_DB_ALL_BLOCKING_BOUNDARY:
+		db_config = VIDC_1080P_DB_ALL_BLOCKING_BOUNDARY;
+	break;
+	case VCD_DB_DISABLE:
+		db_config = VIDC_1080P_DB_DISABLE;
+	break;
+	case VCD_DB_SKIP_SLICE_BOUNDARY:
+		db_config = VIDC_1080P_DB_SKIP_SLICE_BOUNDARY;
+	break;
+	}
+	vidc_1080p_set_h264_encode_loop_filter(db_config,
+		encoder->db_control.slice_alpha_offset,
+		encoder->db_control.slice_beta_offset);
+	vidc_1080p_set_h264_encoder_p_frame_ref_count(encoder->\
+		num_references_for_p_frame);
+	if (encoder->profile.profile == VCD_PROFILE_H264_HIGH)
+		vidc_1080p_set_h264_encode_8x8transform_control(true);
+	}
+	vidc_1080p_set_encode_picture(encoder->i_period.p_frames,
+		encoder->i_period.b_frames);
+	vidc_1080p_set_encode_circular_intra_refresh(
+		encoder->intra_refresh.cir_mb_number);
+	ddl_vidc_encode_set_multi_slice_info(encoder);
+	ddl_vidc_metadata_enable(ddl);
+	if (encoder->meta_data_enable_flag)
+		vidc_sm_set_metadata_start_address(&ddl->shared_mem
+			[ddl->command_channel], DDL_ADDR_OFFSET(
+			ddl_context->dram_base_a,
+			ddl->codec_data.encoder.meta_data_input));
+	luma[0] = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			enc_buffers->dpb_y[0]);
+	luma[1] = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			enc_buffers->dpb_y[1]);
+	if (encoder->hw_bufs.dpb_count == DDL_ENC_MAX_DPB_BUFFERS) {
+		luma[2] = DDL_ADDR_OFFSET(ddl_context->dram_base_b,
+			enc_buffers->dpb_y[2]);
+		luma[3] = DDL_ADDR_OFFSET(ddl_context->dram_base_b,
+			enc_buffers->dpb_y[3]);
+	}
+	for (index = 0; index < recon_bufs; index++)
+		chroma[index] = DDL_ADDR_OFFSET(ddl_context->dram_base_b,
+					enc_buffers->dpb_c[index]);
+	vidc_1080p_set_encode_recon_buffers(recon_bufs, luma, chroma);
+	switch (encoder->codec.codec) {
+	case VCD_CODEC_MPEG4:
+		vidc_1080p_set_mpeg4_encode_work_buffers(
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->col_zero),
+				DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->acdc_coef),
+				DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->mv));
+	break;
+	case VCD_CODEC_H263:
+		vidc_1080p_set_h263_encode_work_buffers(
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->mv),
+				DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->acdc_coef));
+	break;
+	case VCD_CODEC_H264:
+		vidc_1080p_set_h264_encode_work_buffers(
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->mv),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->col_zero),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->md),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_b,
+				enc_buffers->pred),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->nbor_info),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+				enc_buffers->mb_info));
+	break;
+	default:
+	break;
+	}
+	if (encoder->buf_format.buffer_format ==
+		VCD_BUFFER_FORMAT_NV12_16M2KA)
+		mem_access_method = VIDC_1080P_TILE_LINEAR;
+	else
+		mem_access_method = VIDC_1080P_TILE_64x32;
+	vidc_1080p_set_encode_input_frame_format(mem_access_method);
+	vidc_1080p_set_encode_padding_control(0, 0, 0, 0);
+	DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+		"DDL_CLIENT_WAIT_FOR_INITCODECDONE",
+		ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODECDONE;
+	ddl->cmd_state = DDL_CMD_INIT_CODEC;
+	vidc_1080p_set_encode_field_picture_structure(false);
+	seq_start_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	seq_start_param.inst_id = ddl->instance_id;
+	seq_start_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+		ddl_context->dram_base_a, ddl->shared_mem
+		[ddl->command_channel]);
+	seq_start_param.stream_buffer_addr_offset = DDL_ADDR_OFFSET(
+		ddl_context->dram_base_a, encoder->seq_header);
+	seq_start_param.stream_buffer_size =
+		encoder->seq_header.buffer_size;
+	encoder->seq_header_length = 0;
+	ddl_context->vidc_encode_seq_start[ddl->command_channel](
+		&seq_start_param);
+}
+
+void ddl_vidc_channel_end(struct ddl_client_context *ddl)
+{
+	DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_CHEND",
+	ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_CHEND;
+	ddl->cmd_state = DDL_CMD_CHANNEL_END;
+	vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_CLOSE_CH,
+		ddl->instance_id, 0, 0, 0);
+}
+
+void ddl_vidc_encode_frame_run(struct ddl_client_context *ddl)
+{
+	struct vidc_1080p_enc_frame_start_param enc_param;
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct ddl_enc_buffers *enc_buffers = &(encoder->hw_bufs);
+	struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm);
+	struct vcd_frame_data *input_vcd_frm =
+		&(ddl->input_frame.vcd_frm);
+	u32 dpb_addr_y[4], dpb_addr_c[4];
+	u32 index, y_addr, c_addr;
+
+	DDL_MSG_LOW("%s\n", __func__);
+	ddl_vidc_encode_set_metadata_output_buf(ddl);
+
+	encoder->enc_frame_info.meta_data_exists = false;
+
+	y_addr = DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr,
+			input_vcd_frm->physical);
+	c_addr = (y_addr + encoder->input_buf_size.size_y);
+	if (input_vcd_frm->flags & VCD_FRAME_FLAG_EOS) {
+		enc_param.encode = VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA;
+		DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+			"DDL_CLIENT_WAIT_FOR_EOS_DONE",
+			ddl_get_state_string(ddl->client_state));
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+	} else {
+		enc_param.encode = VIDC_1080P_ENC_TYPE_FRAME_DATA;
+		DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+			"DDL_CLIENT_WAIT_FOR_FRAME_DONE",
+			ddl_get_state_string(ddl->client_state));
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE;
+	}
+	ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
+	if (encoder->dynamic_prop_change) {
+		encoder->dynmic_prop_change_req = true;
+		ddl_vidc_encode_dynamic_property(ddl, true);
+	}
+
+	vidc_1080p_set_encode_circular_intra_refresh(
+		encoder->intra_refresh.cir_mb_number);
+	ddl_vidc_encode_set_multi_slice_info(encoder);
+	enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	enc_param.inst_id = ddl->instance_id;
+	enc_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+			ddl_context->dram_base_a,
+			ddl->shared_mem[ddl->command_channel]);
+	enc_param.current_y_addr_offset = y_addr;
+	enc_param.current_c_addr_offset = c_addr;
+	enc_param.stream_buffer_addr_offset = DDL_OFFSET(
+	ddl_context->dram_base_a.align_physical_addr, stream->physical);
+	enc_param.stream_buffer_size =
+		encoder->client_output_buf_req.sz;
+
+	enc_param.intra_frame = encoder->intra_frame_insertion;
+	if (encoder->intra_frame_insertion)
+		encoder->intra_frame_insertion = false;
+	enc_param.input_flush = false;
+	enc_param.slice_enable = false;
+		vidc_sm_set_encoder_vop_time(
+			&ddl->shared_mem[ddl->command_channel], true,
+			encoder->vop_timing.vop_time_resolution,
+			ddl->input_frame.frm_delta);
+	vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+	ddl->input_frame.vcd_frm.ip_frm_tag);
+	if (ddl_context->pix_cache_enable) {
+		for (index = 0; index < enc_buffers->dpb_count;
+			index++) {
+			dpb_addr_y[index] =
+				(u32) VIDC_1080P_DEC_DPB_RESET_VALUE;
+			dpb_addr_c[index] = (u32) enc_buffers->dpb_c
+				[index].align_physical_addr;
+		}
+
+		dpb_addr_y[index] = (u32) input_vcd_frm->physical;
+		dpb_addr_c[index] = (u32) input_vcd_frm->physical +
+			encoder->input_buf_size.size_y;
+
+		vidc_pix_cache_init_luma_chroma_base_addr(
+			enc_buffers->dpb_count + 1, dpb_addr_y, dpb_addr_c);
+		vidc_pix_cache_set_frame_size(encoder->frame_size.width,
+			encoder->frame_size.height);
+		vidc_pix_cache_set_frame_range(enc_buffers->sz_dpb_y,
+			enc_buffers->sz_dpb_c);
+		vidc_pix_cache_clear_cache_tags();
+	}
+	ddl_context->vidc_encode_frame_start[ddl->command_channel] (
+		&enc_param);
+}
+
+void ddl_vidc_encode_frame_continue(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct vcd_frame_data *input_vcd_frm = &(ddl->input_frame.vcd_frm);
+	u32 address_offset;
+	address_offset = (u32)(ddl->output_frame.vcd_frm.physical -
+			ddl_context->dram_base_a.align_physical_addr) >>
+			DDL_VIDC_1080P_BASE_OFFSET_SHIFT;
+	DDL_MSG_LOW("%s\n", __func__);
+	if (VCD_FRAME_FLAG_EOS & input_vcd_frm->flags)
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+	else
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE;
+	ddl->cmd_state = DDL_CMD_ENCODE_CONTINUE;
+	vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_CONTINUE_ENC,
+		address_offset,
+		0, 0, 0);
+}
+
+void ddl_vidc_encode_slice_batch_run(struct ddl_client_context *ddl)
+{
+	struct vidc_1080p_enc_frame_start_param enc_param;
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct ddl_enc_buffers *enc_buffers = &(encoder->hw_bufs);
+	struct vcd_frame_data *input_vcd_frm =
+		&(ddl->input_frame.vcd_frm);
+	u32 dpb_addr_y[4], dpb_addr_c[4];
+	u32 index, y_addr, c_addr;
+	u32 bitstream_size;
+	struct vidc_1080p_enc_slice_batch_in_param *slice_batch_in =
+		(struct vidc_1080p_enc_slice_batch_in_param *)
+		encoder->batch_frame.slice_batch_in.align_virtual_addr;
+	DDL_MSG_LOW("%s\n", __func__);
+	DDL_MEMSET(slice_batch_in, 0,
+		sizeof(struct vidc_1080p_enc_slice_batch_in_param));
+	DDL_MEMSET(encoder->batch_frame.slice_batch_in.align_virtual_addr, 0,
+		sizeof(struct vidc_1080p_enc_slice_batch_in_param));
+	encoder->batch_frame.out_frm_next_frmindex = 0;
+	bitstream_size = encoder->batch_frame.output_frame[0].vcd_frm.alloc_len;
+	encoder->output_buf_req.sz = bitstream_size;
+	y_addr = DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr,
+			input_vcd_frm->physical);
+	c_addr = (y_addr + encoder->input_buf_size.size_y);
+	enc_param.encode = VIDC_1080P_ENC_TYPE_SLICE_BATCH_START;
+	DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+		"DDL_CLIENT_WAIT_FOR_FRAME_DONE",
+		ddl_get_state_string(ddl->client_state));
+	slice_batch_in->cmd_type = VIDC_1080P_ENC_TYPE_SLICE_BATCH_START;
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE;
+	ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
+	vidc_1080p_set_encode_circular_intra_refresh(
+		encoder->intra_refresh.cir_mb_number);
+	ddl_vidc_encode_set_multi_slice_info(encoder);
+	enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	enc_param.inst_id = ddl->instance_id;
+	enc_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+			ddl_context->dram_base_a,
+			ddl->shared_mem[ddl->command_channel]);
+	enc_param.current_y_addr_offset = y_addr;
+	enc_param.current_c_addr_offset = c_addr;
+	enc_param.stream_buffer_size = bitstream_size;
+	slice_batch_in->num_stream_buffer =
+		encoder->batch_frame.num_output_frames;
+	slice_batch_in->stream_buffer_size = bitstream_size;
+	DDL_MSG_LOW("%s slice_batch_in->num_stream_buffer = %u size = %u\n",
+			 __func__, slice_batch_in->num_stream_buffer,
+			slice_batch_in->stream_buffer_size);
+	for (index = 0; index < encoder->batch_frame.num_output_frames;
+		index++) {
+		slice_batch_in->stream_buffer_addr_offset[index] =
+		((DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr,
+		encoder->batch_frame.output_frame[index].vcd_frm.physical)) >>
+			DDL_VIDC_1080P_BASE_OFFSET_SHIFT);
+	}
+	slice_batch_in->input_size = VIDC_1080P_SLICE_BATCH_IN_SIZE(index);
+	enc_param.intra_frame = encoder->intra_frame_insertion;
+	if (encoder->intra_frame_insertion)
+		encoder->intra_frame_insertion = false;
+	enc_param.input_flush = false;
+	enc_param.slice_enable =
+		encoder->slice_delivery_info.enable;
+	vidc_sm_set_encoder_vop_time(
+			&ddl->shared_mem[ddl->command_channel], true,
+			encoder->vop_timing.vop_time_resolution,
+			ddl->input_frame.frm_delta);
+	vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+			ddl->input_frame.vcd_frm.ip_frm_tag);
+	DDL_MSG_LOW("%sdpb_count = %d\n", __func__, enc_buffers->dpb_count);
+	if (ddl_context->pix_cache_enable) {
+		for (index = 0; index < enc_buffers->dpb_count;
+			index++) {
+			dpb_addr_y[index] =
+				(u32) VIDC_1080P_DEC_DPB_RESET_VALUE;
+			dpb_addr_c[index] = (u32) enc_buffers->dpb_c
+				[index].align_physical_addr;
+		}
+
+		dpb_addr_y[index] = (u32) input_vcd_frm->physical;
+		dpb_addr_c[index] = (u32) input_vcd_frm->physical +
+				encoder->input_buf_size.size_y;
+
+		vidc_pix_cache_init_luma_chroma_base_addr(
+			enc_buffers->dpb_count + 1, dpb_addr_y, dpb_addr_c);
+		vidc_pix_cache_set_frame_size(encoder->frame_size.width,
+			encoder->frame_size.height);
+		vidc_pix_cache_set_frame_range(enc_buffers->sz_dpb_y,
+			enc_buffers->sz_dpb_c);
+		vidc_pix_cache_clear_cache_tags();
+	}
+	if ((!encoder->rc_level.frame_level_rc) &&
+		(!encoder->rc_level.mb_level_rc)) {
+		encoder->session_qp.p_frame_qp++;
+		if (encoder->session_qp.p_frame_qp > encoder->qp_range.max_qp)
+			encoder->session_qp.p_frame_qp =
+						encoder->qp_range.min_qp;
+		vidc_sm_set_pand_b_frame_qp(
+			&ddl->shared_mem[ddl->command_channel],
+				encoder->session_qp.b_frame_qp,
+				encoder->session_qp.p_frame_qp);
+	}
+
+	if (vidc_msg_timing) {
+		if (run_cnt < 2) {
+			ddl_reset_core_time_variables(ENC_OP_TIME);
+			ddl_reset_core_time_variables(ENC_SLICE_OP_TIME);
+			run_cnt++;
+		 }
+		ddl_update_core_start_time(__func__, ENC_SLICE_OP_TIME);
+		ddl_set_core_start_time(__func__, ENC_OP_TIME);
+	}
+	ddl_vidc_encode_set_batch_slice_info(ddl);
+	ddl_context->vidc_encode_slice_batch_start[ddl->command_channel] (
+			&enc_param);
+}
+
+u32 ddl_vidc_decode_set_buffers(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	u32 vcd_status = VCD_S_SUCCESS;
+	struct vidc_1080p_dec_init_buffers_param init_buf_param;
+	u32 size_y = 0;
+	u32 size_c = 0;
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) {
+		DDL_MSG_ERROR("STATE-CRITICAL");
+		return VCD_ERR_FAIL;
+	}
+	ddl_set_vidc_timeout(ddl);
+	ddl_vidc_decode_set_metadata_output(decoder);
+	if (decoder->dp_buf.no_of_dec_pic_buf <
+		decoder->client_output_buf_req.actual_count)
+		return VCD_ERR_BAD_STATE;
+	if (decoder->codec.codec == VCD_CODEC_H264) {
+		vidc_sm_set_allocated_h264_mv_size(
+			&ddl->shared_mem[ddl->command_channel],
+			decoder->hw_bufs.h264_mv[0].buffer_size);
+	}
+	if (vcd_status)
+		return vcd_status;
+#ifdef DDL_BUF_LOG
+	ddl_list_buffers(ddl);
+#endif
+	if (vidc_msg_timing)
+		ddl_set_core_start_time(__func__, DEC_OP_TIME);
+	ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_INIT);
+	if (ddl_decoder_dpb_init(ddl) == VCD_ERR_FAIL)
+		return VCD_ERR_FAIL;
+	DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_DPBDONE",
+	ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_DPBDONE;
+	ddl->cmd_state = DDL_CMD_DECODE_SET_DPB;
+	if (decoder->cont_mode) {
+		size_y = ddl_get_yuv_buf_size(decoder->client_frame_size.width,
+				decoder->client_frame_size.height,
+				DDL_YUV_BUF_TYPE_TILE);
+		size_c = ddl_get_yuv_buf_size(decoder->client_frame_size.width,
+				(decoder->client_frame_size.height >> 1),
+				DDL_YUV_BUF_TYPE_TILE);
+		vidc_sm_set_allocated_dpb_size(
+			&ddl->shared_mem[ddl->command_channel],
+			size_y,
+			size_c);
+	} else {
+		vidc_sm_set_allocated_dpb_size(
+			&ddl->shared_mem[ddl->command_channel],
+			decoder->dpb_buf_size.size_y,
+			decoder->dpb_buf_size.size_c);
+	}
+	init_buf_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	init_buf_param.inst_id = ddl->instance_id;
+	init_buf_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+				ddl_context->dram_base_a, ddl->shared_mem
+				[ddl->command_channel]);
+	init_buf_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf;
+	init_buf_param.dmx_disable = decoder->dmx_disable;
+	ddl_context->vidc_decode_init_buffers[ddl->command_channel] (
+		&init_buf_param);
+	return VCD_S_SUCCESS;
+}
+
+void ddl_vidc_decode_frame_run(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vcd_frame_data *bit_stream =
+		&(ddl->input_frame.vcd_frm);
+	struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs;
+	struct ddl_mask *dpb_mask = &ddl->codec_data.decoder.dpb_mask;
+	struct vidc_1080p_dec_frame_start_param dec_param;
+	u32 dpb_addr_y[32], index;
+	if (vidc_msg_timing) {
+		ddl_set_core_start_time(__func__, DEC_OP_TIME);
+		ddl_set_core_start_time(__func__, DEC_IP_TIME);
+	}
+	if ((!bit_stream->data_len) || (!bit_stream->physical)) {
+		ddl_vidc_decode_eos_run(ddl);
+		return;
+	}
+	DDL_MSG_LOW("ddl_state_transition: %s ~~"
+		"DDL_CLIENT_WAIT_FOR_FRAME_DONE",
+		ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE;
+	ddl_vidc_decode_dynamic_property(ddl, true);
+	ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK);
+	ddl->cmd_state = DDL_CMD_DECODE_FRAME;
+	dec_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	dec_param.inst_id = ddl->instance_id;
+	dec_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+				ddl_context->dram_base_a, ddl->shared_mem
+				[ddl->command_channel]);
+	dec_param.stream_buffer_addr_offset = DDL_OFFSET(
+			ddl_context->dram_base_a.align_physical_addr,
+			bit_stream->physical);
+	dec_param.stream_frame_size = bit_stream->data_len;
+	dec_param.stream_buffersize = decoder->client_input_buf_req.sz;
+	dec_param.descriptor_buffer_addr_offset = DDL_ADDR_OFFSET(
+	ddl_context->dram_base_a, dec_buffers->desc);
+	dec_param.descriptor_buffer_size = dec_buffers->desc.buffer_size;
+	dec_param.release_dpb_bit_mask = dpb_mask->hw_mask;
+	dec_param.decode = VIDC_1080P_DEC_TYPE_FRAME_DATA;
+	dec_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf;
+	dec_param.dmx_disable = decoder->dmx_disable;
+	if (decoder->dmx_disable)
+		ddl_fill_dec_desc_buffer(ddl);
+	if (decoder->flush_pending) {
+		dec_param.dpb_flush = true;
+		decoder->flush_pending = false;
+	} else
+		dec_param.dpb_flush = false;
+	vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+		bit_stream->ip_frm_tag);
+	if (ddl_context->pix_cache_enable) {
+		for (index = 0; index <
+			decoder->dp_buf.no_of_dec_pic_buf; index++) {
+			dpb_addr_y[index] = (u32)
+			decoder->dp_buf.dec_pic_buffers
+				[index].vcd_frm.physical;
+		}
+		vidc_pix_cache_init_luma_chroma_base_addr(
+			decoder->dp_buf.no_of_dec_pic_buf,
+			dpb_addr_y, NULL);
+		vidc_pix_cache_set_frame_range(decoder->dpb_buf_size.size_y,
+			decoder->dpb_buf_size.size_c);
+		vidc_pix_cache_clear_cache_tags();
+	}
+	ddl_context->vidc_decode_frame_start[ddl->command_channel] (
+		&dec_param);
+}
+
+void ddl_vidc_decode_eos_run(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vcd_frame_data *bit_stream =
+		&(ddl->input_frame.vcd_frm);
+	struct ddl_dec_buffers *dec_buffers = &(decoder->hw_bufs);
+	struct ddl_mask *dpb_mask =
+		&(ddl->codec_data.decoder.dpb_mask);
+	struct vidc_1080p_dec_frame_start_param dec_param;
+
+	DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_EOS_DONE",
+	ddl_get_state_string(ddl->client_state));
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+	if (decoder->output_order == VCD_DEC_ORDER_DECODE)
+		decoder->dynamic_prop_change |= DDL_DEC_REQ_OUTPUT_FLUSH;
+	ddl_vidc_decode_dynamic_property(ddl, true);
+	ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK);
+	decoder->dynmic_prop_change_req = true;
+	ddl->cmd_state = DDL_CMD_EOS;
+	memset(&dec_param, 0, sizeof(dec_param));
+	dec_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	dec_param.inst_id = ddl->instance_id;
+	dec_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+			ddl_context->dram_base_a,
+			ddl->shared_mem[ddl->command_channel]);
+	dec_param.descriptor_buffer_addr_offset = DDL_ADDR_OFFSET(
+	ddl_context->dram_base_a, dec_buffers->desc);
+	dec_param.descriptor_buffer_size = dec_buffers->desc.buffer_size;
+	dec_param.release_dpb_bit_mask = dpb_mask->hw_mask;
+	dec_param.decode = VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA;
+	dec_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf;
+	if (decoder->flush_pending) {
+		dec_param.dpb_flush = true;
+		decoder->flush_pending = false;
+	} else
+		dec_param.dpb_flush = false;
+	vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+	bit_stream->ip_frm_tag);
+	ddl_context->vidc_decode_frame_start[ddl->command_channel] (
+		&dec_param);
+}
+
+void ddl_vidc_encode_eos_run(struct ddl_client_context *ddl)
+{
+	struct vidc_1080p_enc_frame_start_param enc_param;
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	DDL_MSG_LOW("%s\n", __func__);
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+	ddl_vidc_encode_dynamic_property(ddl, true);
+	ddl->client_state = DDL_CMD_EOS;
+	DDL_MEMSET(&enc_param, 0, sizeof(enc_param));
+	enc_param.encode = VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA;
+	enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	enc_param.inst_id = ddl->instance_id;
+	enc_param.shared_mem_addr_offset =
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+		ddl->shared_mem[ddl->command_channel]);
+	enc_param.current_y_addr_offset = 0;
+	enc_param.current_c_addr_offset = 0;
+	enc_param.stream_buffer_size = 0;
+	enc_param.intra_frame = encoder->intra_frame_insertion;
+	vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+				ddl->input_frame.vcd_frm.ip_frm_tag);
+	ddl_context->vidc_encode_frame_start[ddl->command_channel](
+						&enc_param);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.c b/drivers/video/msm/vidc/1080p/ddl/vidc.c
new file mode 100644
index 0000000..d399847
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c
@@ -0,0 +1,1108 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vidc.h"
+#include "vidc_hwio.h"
+
+
+#define VIDC_1080P_INIT_CH_INST_ID      0x0000ffff
+#define VIDC_1080P_RESET_VI             0x3f7
+#define VIDC_1080P_RESET_VI_RISC        0x3f6
+#define VIDC_1080P_RESET_VI_VIDC_RISC    0x3f2
+#define VIDC_1080P_RESET_ALL            0
+#define VIDC_1080P_RESET_RISC           0x3fe
+#define VIDC_1080P_RESET_NONE           0x3ff
+#define VIDC_1080P_INTERRUPT_CLEAR      0
+#define VIDC_1080P_MAX_H264DECODER_DPB  32
+#define VIDC_1080P_MAX_DEC_RECON_BUF    32
+
+#define VIDC_1080P_SI_RG7_DISPLAY_STATUS_MASK    0x00000007
+#define VIDC_1080P_SI_RG7_DISPLAY_STATUS_SHIFT   0
+#define VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK    0x00000008
+#define VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT   3
+#define VIDC_1080P_SI_RG7_DISPLAY_RES_MASK       0x00000030
+#define VIDC_1080P_SI_RG7_DISPLAY_RES_SHIFT      4
+
+#define VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK      0x00000040
+#define VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT     6
+
+#define VIDC_1080P_SI_RG7_DISPLAY_CORRECT_MASK    0x00000180
+#define VIDC_1080P_SI_RG7_DISPLAY_CORRECT_SHIFT   7
+#define VIDC_1080P_SI_RG8_DECODE_FRAMETYPE_MASK  0x00000007
+
+#define VIDC_1080P_SI_RG10_NUM_DPB_BMSK      0x00003fff
+#define VIDC_1080P_SI_RG10_NUM_DPB_SHFT      0
+#define VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK    0x00004000
+#define VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT    14
+#define VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK  0x00008000
+#define VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT  15
+
+#define VIDC_1080P_SI_RG11_DECODE_STATUS_MASK    0x00000007
+#define VIDC_1080P_SI_RG11_DECODE_STATUS_SHIFT   0
+#define VIDC_1080P_SI_RG11_DECODE_CODING_MASK    0x00000008
+#define VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT   3
+#define VIDC_1080P_SI_RG11_DECODE_RES_MASK       0x000000C0
+#define VIDC_1080P_SI_RG11_DECODE_RES_SHIFT      6
+#define VIDC_1080P_SI_RG11_DECODE_CROPP_MASK     0x00000100
+#define VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT    8
+
+#define VIDC_1080P_SI_RG11_DECODE_CORRECT_MASK    0x00000600
+#define VIDC_1080P_SI_RG11_DECODE_CORRECT_SHIFT   9
+#define VIDC_1080P_BASE_OFFSET_SHIFT         11
+
+
+#define VIDC_1080P_H264DEC_LUMA_ADDR      HWIO_REG_759068_ADDR
+#define VIDC_1080P_H264DEC_CHROMA_ADDR    HWIO_REG_515200_ADDR
+#define VIDC_1080P_H264DEC_MV_PLANE_ADDR  HWIO_REG_466192_ADDR
+
+#define VIDC_1080P_DEC_LUMA_ADDR        HWIO_REG_759068_ADDR
+#define VIDC_1080P_DEC_CHROMA_ADDR      HWIO_REG_515200_ADDR
+
+#define VIDC_1080P_DEC_TYPE_SEQ_HEADER         0x00010000
+#define VIDC_1080P_DEC_TYPE_FRAME_DATA         0x00020000
+#define VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA    0x00030000
+#define VIDC_1080P_DEC_TYPE_INIT_BUFFERS       0x00040000
+
+#define VIDC_1080P_ENC_TYPE_SEQ_HEADER       0x00010000
+#define VIDC_1080P_ENC_TYPE_FRAME_DATA       0x00020000
+#define VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA  0x00030000
+
+#define VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK   0x00004000
+#define VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT   14
+#define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK      0x80000000
+#define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT      31
+#define VIDC_1080P_MAX_INTRA_PERIOD 0xffff
+
+u8 *VIDC_BASE_PTR;
+
+void vidc_1080p_do_sw_reset(enum vidc_1080p_reset init_flag)
+{
+	if (init_flag == VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE) {
+		u32 sw_reset_value = 0;
+
+		VIDC_HWIO_IN(REG_557899, &sw_reset_value);
+		sw_reset_value &= (~HWIO_REG_557899_RSTN_VI_BMSK);
+		VIDC_HWIO_OUT(REG_557899, sw_reset_value);
+		sw_reset_value &= (~HWIO_REG_557899_RSTN_RISC_BMSK);
+		VIDC_HWIO_OUT(REG_557899, sw_reset_value);
+		sw_reset_value &= (~(HWIO_REG_557899_RSTN_VIDCCORE_BMSK |
+					HWIO_REG_557899_RSTN_DMX_BMSK));
+
+		VIDC_HWIO_OUT(REG_557899, sw_reset_value);
+	} else if (init_flag == VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE) {
+		VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_ALL);
+		VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_RISC);
+	}
+}
+
+void vidc_1080p_release_sw_reset(void)
+{
+	u32 nAxiCtl;
+	u32 nAxiStatus;
+	u32 nRdWrBurst;
+	u32 nOut_Order;
+
+	nOut_Order = VIDC_SETFIELD(1, HWIO_REG_5519_AXI_AOOORD_SHFT,
+					HWIO_REG_5519_AXI_AOOORD_BMSK);
+	VIDC_HWIO_OUT(REG_5519, nOut_Order);
+
+	nOut_Order = VIDC_SETFIELD(1, HWIO_REG_606364_AXI_AOOOWR_SHFT,
+					HWIO_REG_606364_AXI_AOOOWR_BMSK);
+	VIDC_HWIO_OUT(REG_606364, nOut_Order);
+
+	nAxiCtl = VIDC_SETFIELD(1, HWIO_REG_471159_AXI_HALT_REQ_SHFT,
+				HWIO_REG_471159_AXI_HALT_REQ_BMSK);
+
+	VIDC_HWIO_OUT(REG_471159, nAxiCtl);
+
+	do {
+		VIDC_HWIO_IN(REG_437878, &nAxiStatus);
+		nAxiStatus = VIDC_GETFIELD(nAxiStatus,
+					 HWIO_REG_437878_AXI_HALT_ACK_BMSK,
+					 HWIO_REG_437878_AXI_HALT_ACK_SHFT);
+	} while (0x3 != nAxiStatus);
+
+	nAxiCtl  =  VIDC_SETFIELD(1,
+				HWIO_REG_471159_AXI_RESET_SHFT,
+				HWIO_REG_471159_AXI_RESET_BMSK);
+
+	VIDC_HWIO_OUT(REG_471159, nAxiCtl);
+	VIDC_HWIO_OUT(REG_471159, 0);
+
+	nRdWrBurst = VIDC_SETFIELD(8,
+				HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_SHFT,
+				HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_BMSK) |
+	VIDC_SETFIELD(8, HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_SHFT,
+				HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_BMSK);
+
+	VIDC_HWIO_OUT(REG_922106, nRdWrBurst);
+
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_611794, VIDC_1080P_HOST2RISC_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_NONE);
+}
+
+void vidc_1080p_clear_interrupt(void)
+{
+	VIDC_HWIO_OUT(REG_575377, VIDC_1080P_INTERRUPT_CLEAR);
+}
+
+void vidc_1080p_set_host2risc_cmd(enum vidc_1080p_host2risc_cmd
+	host2risc_command, u32 host2risc_arg1, u32 host2risc_arg2,
+	u32 host2risc_arg3, u32 host2risc_arg4)
+{
+	VIDC_HWIO_OUT(REG_611794, VIDC_1080P_HOST2RISC_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_356340, host2risc_arg1);
+	VIDC_HWIO_OUT(REG_899023, host2risc_arg2);
+	VIDC_HWIO_OUT(REG_987762, host2risc_arg3);
+	VIDC_HWIO_OUT(REG_544000, host2risc_arg4);
+	VIDC_HWIO_OUT(REG_611794, host2risc_command);
+}
+
+void vidc_1080p_get_risc2host_cmd(u32 *pn_risc2host_command,
+	u32 *pn_risc2host_arg1, u32 *pn_risc2host_arg2,
+	u32 *pn_risc2host_arg3, u32 *pn_risc2host_arg4)
+{
+	VIDC_HWIO_IN(REG_695082, pn_risc2host_command);
+	VIDC_HWIO_IN(REG_156596, pn_risc2host_arg1);
+	VIDC_HWIO_IN(REG_222292, pn_risc2host_arg2);
+	VIDC_HWIO_IN(REG_790962, pn_risc2host_arg3);
+	VIDC_HWIO_IN(REG_679882, pn_risc2host_arg4);
+}
+
+void vidc_1080p_get_risc2host_cmd_status(u32 err_status,
+	u32 *dec_err_status, u32 *disp_err_status)
+{
+	*dec_err_status = VIDC_GETFIELD(err_status,
+		VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_BMSK,
+		VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_SHFT);
+	*disp_err_status = VIDC_GETFIELD(err_status,
+		VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_BMSK,
+		VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_SHFT);
+
+}
+
+void vidc_1080p_clear_risc2host_cmd(void)
+{
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+}
+
+void vidc_1080p_get_fw_version(u32 *pn_fw_version)
+{
+	VIDC_HWIO_IN(REG_653206, pn_fw_version);
+}
+
+void vidc_1080p_get_fw_status(u32 *pn_fw_status)
+{
+	VIDC_HWIO_IN(REG_350619, pn_fw_status);
+}
+
+void vidc_1080p_init_memory_controller(u32 dram_base_addr_a,
+	u32 dram_base_addr_b)
+{
+	VIDC_HWIO_OUT(REG_64440, dram_base_addr_a);
+	VIDC_HWIO_OUT(REG_675915, dram_base_addr_b);
+}
+
+void vidc_1080p_get_memory_controller_status(u32 *pb_mc_abusy,
+	u32 *pb_mc_bbusy)
+{
+	u32 mc_status = 0;
+
+	VIDC_HWIO_IN(REG_399911, &mc_status);
+	*pb_mc_abusy = (u32) ((mc_status &
+			HWIO_REG_399911_MC_BUSY_A_BMSK) >>
+			HWIO_REG_399911_MC_BUSY_A_SHFT);
+	*pb_mc_bbusy = (u32) ((mc_status &
+			HWIO_REG_399911_MC_BUSY_B_BMSK) >>
+			HWIO_REG_399911_MC_BUSY_B_SHFT);
+}
+
+void vidc_1080p_set_h264_decode_buffers(u32 dpb, u32 dec_vert_nb_mv_offset,
+	u32 dec_nb_ip_offset, u32 *pn_dpb_luma_offset,
+	u32 *pn_dpb_chroma_offset, u32 *pn_mv_buffer_offset)
+{
+	u32 count = 0, num_dpb_used = dpb;
+	u8 *vidc_dpb_luma_reg = (u8 *) VIDC_1080P_H264DEC_LUMA_ADDR;
+	u8 *vidc_dpb_chroma_reg = (u8 *) VIDC_1080P_H264DEC_CHROMA_ADDR;
+	u8 *vidc_mv_buffer_reg = (u8 *) VIDC_1080P_H264DEC_MV_PLANE_ADDR;
+
+	VIDC_HWIO_OUT(REG_931311, (dec_vert_nb_mv_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_16277, (dec_nb_ip_offset >>
+	VIDC_1080P_BASE_OFFSET_SHIFT));
+	if (num_dpb_used > VIDC_1080P_MAX_H264DECODER_DPB)
+		num_dpb_used = VIDC_1080P_MAX_H264DECODER_DPB;
+	for (count = 0; count < num_dpb_used; count++) {
+		VIDC_OUT_DWORD(vidc_dpb_luma_reg,
+			(pn_dpb_luma_offset[count] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		VIDC_OUT_DWORD(vidc_dpb_chroma_reg,
+			(pn_dpb_chroma_offset[count] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		VIDC_OUT_DWORD(vidc_mv_buffer_reg,
+			(pn_mv_buffer_offset[count] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		vidc_dpb_luma_reg += 4;
+		vidc_dpb_chroma_reg += 4;
+		vidc_mv_buffer_reg += 4;
+	}
+}
+
+void vidc_1080p_set_decode_recon_buffers(u32 recon_buffer,
+	u32 *pn_dec_luma, u32 *pn_dec_chroma)
+{
+	u32 count = 0, recon_buf_to_program = recon_buffer;
+	u8 *dec_recon_luma_reg = (u8 *) VIDC_1080P_DEC_LUMA_ADDR;
+	u8 *dec_recon_chroma_reg = (u8 *) VIDC_1080P_DEC_CHROMA_ADDR;
+
+	if (recon_buf_to_program > VIDC_1080P_MAX_DEC_RECON_BUF)
+		recon_buf_to_program = VIDC_1080P_MAX_DEC_RECON_BUF;
+	for (count = 0; count < recon_buf_to_program; count++) {
+		VIDC_OUT_DWORD(dec_recon_luma_reg, (pn_dec_luma[count] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		VIDC_OUT_DWORD(dec_recon_chroma_reg,
+			(pn_dec_chroma[count] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		dec_recon_luma_reg += 4;
+		dec_recon_chroma_reg += 4;
+	}
+}
+
+void vidc_1080p_set_mpeg4_divx_decode_work_buffers(u32 nb_dcac_buffer_offset,
+	u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset,
+	u32 overlay_transform_buffer_offset, u32 stx_parser_buffer_offset)
+{
+	VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_802794,
+		(overlay_transform_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_252167, (stx_parser_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+}
+
+void vidc_1080p_set_h263_decode_work_buffers(u32 nb_dcac_buffer_offset,
+	u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset,
+	u32 overlay_transform_buffer_offset)
+{
+	VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_802794,
+		(overlay_transform_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+}
+
+void vidc_1080p_set_vc1_decode_work_buffers(u32 nb_dcac_buffer_offset,
+	u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset,
+	u32 overlay_transform_buffer_offset, u32 bitplain1Buffer_offset,
+	u32 bitplain2Buffer_offset, u32 bitplain3Buffer_offset)
+{
+	VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_802794,
+		(overlay_transform_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_724376, (bitplain3Buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_551674, (bitplain2Buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_115991, (bitplain1Buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+}
+
+void vidc_1080p_set_encode_recon_buffers(u32 recon_buffer,
+	u32 *pn_enc_luma, u32 *pn_enc_chroma)
+{
+	if (recon_buffer > 0) {
+		VIDC_HWIO_OUT(REG_294579, (pn_enc_luma[0] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		VIDC_HWIO_OUT(REG_759068, (pn_enc_chroma[0] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+	}
+	if (recon_buffer > 1) {
+		VIDC_HWIO_OUT(REG_616802, (pn_enc_luma[1] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		VIDC_HWIO_OUT(REG_833502, (pn_enc_chroma[1] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+	}
+	if (recon_buffer > 2) {
+		VIDC_HWIO_OUT(REG_61427, (pn_enc_luma[2] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		VIDC_HWIO_OUT(REG_68356, (pn_enc_chroma[2] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+	}
+	if (recon_buffer > 3) {
+		VIDC_HWIO_OUT(REG_23318, (pn_enc_luma[3] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+		VIDC_HWIO_OUT(REG_127855, (pn_enc_chroma[3] >>
+			VIDC_1080P_BASE_OFFSET_SHIFT));
+	}
+}
+
+void vidc_1080p_set_h264_encode_work_buffers(u32 up_row_mv_buffer_offset,
+	u32 direct_colzero_flag_buffer_offset,
+	u32 upper_intra_md_buffer_offset,
+	u32 upper_intra_pred_buffer_offset, u32 nbor_infor_buffer_offset,
+	u32 mb_info_offset)
+{
+	VIDC_HWIO_OUT(REG_515200, (up_row_mv_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_69832,
+		(direct_colzero_flag_buffer_offset>>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_256132,
+		(upper_intra_md_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_475648,
+		(upper_intra_pred_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_29510, (nbor_infor_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_175929, (mb_info_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+}
+
+void vidc_1080p_set_h263_encode_work_buffers(u32 up_row_mv_buffer_offset,
+	u32 up_row_inv_quanti_coeff_buffer_offset)
+{
+	VIDC_HWIO_OUT(REG_515200, (up_row_mv_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_29510, (
+		up_row_inv_quanti_coeff_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+}
+
+void vidc_1080p_set_mpeg4_encode_work_buffers(u32 skip_flag_buffer_offset,
+	u32 up_row_inv_quanti_coeff_buffer_offset, u32 upper_mv_offset)
+{
+	VIDC_HWIO_OUT(REG_69832, (skip_flag_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_29510, (
+		up_row_inv_quanti_coeff_buffer_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+	VIDC_HWIO_OUT(REG_515200, (upper_mv_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT));
+}
+
+void vidc_1080p_set_encode_frame_size(u32 hori_size, u32 vert_size)
+{
+	VIDC_HWIO_OUT(REG_934655, hori_size);
+	VIDC_HWIO_OUT(REG_179070, vert_size);
+}
+
+void vidc_1080p_set_encode_profile_level(u32 encode_profile, u32 enc_level)
+{
+	u32 profile_level = 0;
+
+	profile_level = VIDC_SETFIELD(enc_level,
+				HWIO_REG_63643_LEVEL_SHFT,
+				HWIO_REG_63643_LEVEL_BMSK) |
+				VIDC_SETFIELD(encode_profile,
+				HWIO_REG_63643_PROFILE_SHFT,
+				HWIO_REG_63643_PROFILE_BMSK);
+	VIDC_HWIO_OUT(REG_63643, profile_level);
+}
+
+void vidc_1080p_set_encode_field_picture_structure(u32 enc_field_picture)
+{
+	VIDC_HWIO_OUT(REG_786024, enc_field_picture);
+}
+
+void vidc_1080p_set_decode_mpeg4_pp_filter(u32 lf_enables)
+{
+	VIDC_HWIO_OUT(REG_152500, lf_enables);
+}
+
+void vidc_1080p_set_decode_qp_save_control(u32 enable_q_pout)
+{
+	VIDC_HWIO_OUT(REG_143629, enable_q_pout);
+}
+
+void vidc_1080p_get_returned_channel_inst_id(u32 *pn_rtn_chid)
+{
+	VIDC_HWIO_IN(REG_607589, pn_rtn_chid);
+}
+
+void vidc_1080p_clear_returned_channel_inst_id(void)
+{
+	VIDC_HWIO_OUT(REG_607589, VIDC_1080P_INIT_CH_INST_ID);
+}
+
+void vidc_1080p_get_decode_seq_start_result(
+	struct vidc_1080p_seq_hdr_info *seq_hdr_info)
+{
+	u32 dec_disp_result;
+	u32 frame = 0;
+	VIDC_HWIO_IN(REG_845544, &seq_hdr_info->img_size_y);
+	VIDC_HWIO_IN(REG_859906, &seq_hdr_info->img_size_x);
+	VIDC_HWIO_IN(REG_490078, &seq_hdr_info->min_num_dpb);
+	VIDC_HWIO_IN(REG_489688, &seq_hdr_info->dec_frm_size);
+	VIDC_HWIO_IN(REG_853667, &dec_disp_result);
+	seq_hdr_info->disp_progressive = VIDC_GETFIELD(dec_disp_result,
+					VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK,
+					VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT);
+	seq_hdr_info->disp_crop_exists  = VIDC_GETFIELD(dec_disp_result,
+		VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK,
+		VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT);
+	VIDC_HWIO_IN(REG_692991, &dec_disp_result);
+	seq_hdr_info->dec_progressive = VIDC_GETFIELD(dec_disp_result,
+					VIDC_1080P_SI_RG11_DECODE_CODING_MASK,
+					VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT);
+	seq_hdr_info->dec_crop_exists  = VIDC_GETFIELD(dec_disp_result,
+		VIDC_1080P_SI_RG11_DECODE_CROPP_MASK,
+		VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT);
+	VIDC_HWIO_IN(REG_760102, &frame);
+	seq_hdr_info->data_partition = ((frame & 0x8) >> 3);
+}
+
+void vidc_1080p_get_decoded_frame_size(u32 *pn_decoded_size)
+{
+	VIDC_HWIO_IN(REG_489688, pn_decoded_size);
+}
+
+void vidc_1080p_get_display_frame_result(
+	struct vidc_1080p_dec_disp_info *dec_disp_info)
+{
+	u32 display_result;
+	VIDC_HWIO_IN(REG_640904, &dec_disp_info->display_y_addr);
+	VIDC_HWIO_IN(REG_60114, &dec_disp_info->display_c_addr);
+	VIDC_HWIO_IN(REG_853667, &display_result);
+	VIDC_HWIO_IN(REG_845544, &dec_disp_info->img_size_y);
+	VIDC_HWIO_IN(REG_859906, &dec_disp_info->img_size_x);
+	dec_disp_info->display_status =
+		(enum vidc_1080p_display_status)
+		VIDC_GETFIELD(display_result,
+		VIDC_1080P_SI_RG7_DISPLAY_STATUS_MASK,
+		VIDC_1080P_SI_RG7_DISPLAY_STATUS_SHIFT);
+	dec_disp_info->display_coding =
+		(enum vidc_1080p_display_coding)
+	VIDC_GETFIELD(display_result, VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK,
+		VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT);
+	dec_disp_info->disp_resl_change = VIDC_GETFIELD(display_result,
+		VIDC_1080P_SI_RG7_DISPLAY_RES_MASK,
+		VIDC_1080P_SI_RG7_DISPLAY_RES_SHIFT);
+	dec_disp_info->disp_crop_exists = VIDC_GETFIELD(display_result,
+		VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK,
+		VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT);
+	dec_disp_info->display_correct = VIDC_GETFIELD(display_result,
+		VIDC_1080P_SI_RG7_DISPLAY_CORRECT_MASK,
+		VIDC_1080P_SI_RG7_DISPLAY_CORRECT_SHIFT);
+}
+
+void vidc_1080p_get_decode_frame(
+	enum vidc_1080p_decode_frame *pe_frame)
+{
+	u32 frame = 0;
+
+	VIDC_HWIO_IN(REG_760102, &frame);
+	*pe_frame = (enum vidc_1080p_decode_frame)
+		(frame & VIDC_1080P_SI_RG8_DECODE_FRAMETYPE_MASK);
+}
+
+void vidc_1080p_get_decode_frame_result(
+	struct vidc_1080p_dec_disp_info *dec_disp_info)
+{
+	u32 decode_result;
+
+	VIDC_HWIO_IN(REG_378318, &dec_disp_info->decode_y_addr);
+	VIDC_HWIO_IN(REG_203487, &dec_disp_info->decode_c_addr);
+	VIDC_HWIO_IN(REG_692991, &decode_result);
+	dec_disp_info->decode_status = (enum vidc_1080p_display_status)
+				VIDC_GETFIELD(decode_result,
+				VIDC_1080P_SI_RG11_DECODE_STATUS_MASK,
+				VIDC_1080P_SI_RG11_DECODE_STATUS_SHIFT);
+	dec_disp_info->decode_coding = (enum vidc_1080p_display_coding)
+				VIDC_GETFIELD(decode_result,
+				VIDC_1080P_SI_RG11_DECODE_CODING_MASK,
+				VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT);
+	dec_disp_info->dec_resl_change = VIDC_GETFIELD(decode_result,
+		VIDC_1080P_SI_RG11_DECODE_RES_MASK,
+		VIDC_1080P_SI_RG11_DECODE_RES_SHIFT);
+	dec_disp_info->dec_crop_exists = VIDC_GETFIELD(decode_result,
+		VIDC_1080P_SI_RG11_DECODE_CROPP_MASK,
+		VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT);
+	dec_disp_info->decode_correct = VIDC_GETFIELD(decode_result,
+		VIDC_1080P_SI_RG11_DECODE_CORRECT_MASK,
+		VIDC_1080P_SI_RG11_DECODE_CORRECT_SHIFT);
+}
+
+void vidc_1080p_decode_seq_start_ch0(
+	struct vidc_1080p_dec_seq_start_param *param)
+{
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_117192,
+		param->stream_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_145068, param->stream_frame_size);
+	VIDC_HWIO_OUT(REG_921356,
+		param->descriptor_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_190381,  param->stream_buffersize);
+	VIDC_HWIO_OUT(REG_85655,  param->descriptor_buffer_size);
+	VIDC_HWIO_OUT(REG_889944,  param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_404623, 0);
+	VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_DEC_TYPE_SEQ_HEADER |
+		param->inst_id);
+}
+
+void vidc_1080p_decode_seq_start_ch1(
+	struct vidc_1080p_dec_seq_start_param *param)
+{
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_980194,
+		param->stream_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_936704, param->stream_frame_size);
+	VIDC_HWIO_OUT(REG_821977,
+		param->descriptor_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_887095, param->stream_buffersize);
+	VIDC_HWIO_OUT(REG_576987, param->descriptor_buffer_size);
+	VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_404623, 0);
+	VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_DEC_TYPE_SEQ_HEADER |
+		param->inst_id);
+}
+
+void vidc_1080p_decode_frame_start_ch0(
+	struct vidc_1080p_dec_frame_start_param *param)
+{
+	u32 dpb_config;
+
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	if ((param->decode == VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA) &&
+		((!param->stream_buffer_addr_offset) ||
+		(!param->stream_frame_size))) {
+		VIDC_HWIO_OUT(REG_117192, 0);
+		VIDC_HWIO_OUT(REG_145068, 0);
+		VIDC_HWIO_OUT(REG_190381, 0);
+	} else {
+		VIDC_HWIO_OUT(REG_117192,
+			param->stream_buffer_addr_offset >>
+			VIDC_1080P_BASE_OFFSET_SHIFT);
+		VIDC_HWIO_OUT(REG_145068,
+			param->stream_frame_size);
+		VIDC_HWIO_OUT(REG_190381,
+			param->stream_buffersize);
+	}
+	dpb_config = VIDC_SETFIELD(param->dmx_disable,
+					VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT,
+					VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) |
+				VIDC_SETFIELD(param->dpb_flush,
+					VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT,
+					VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK) |
+				VIDC_SETFIELD(param->dpb_count,
+					VIDC_1080P_SI_RG10_NUM_DPB_SHFT,
+					VIDC_1080P_SI_RG10_NUM_DPB_BMSK);
+	VIDC_HWIO_OUT(REG_921356,
+		param->descriptor_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_85655, param->descriptor_buffer_size);
+	VIDC_HWIO_OUT(REG_86830, param->release_dpb_bit_mask);
+	VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_404623, dpb_config);
+	VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_666957, (u32)param->decode |
+		param->inst_id);
+}
+
+
+void vidc_1080p_decode_frame_start_ch1(
+	struct vidc_1080p_dec_frame_start_param *param)
+{
+	u32 dpb_config;
+
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+	if ((param->decode == VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA) &&
+		((!param->stream_buffer_addr_offset) ||
+		(!param->stream_frame_size))) {
+		VIDC_HWIO_OUT(REG_980194, 0);
+		VIDC_HWIO_OUT(REG_936704, 0);
+		VIDC_HWIO_OUT(REG_887095, 0);
+	} else {
+		VIDC_HWIO_OUT(REG_980194,
+			param->stream_buffer_addr_offset >>
+			VIDC_1080P_BASE_OFFSET_SHIFT);
+		VIDC_HWIO_OUT(REG_936704,
+			param->stream_frame_size);
+		VIDC_HWIO_OUT(REG_887095,
+			param->stream_buffersize);
+	}
+	dpb_config = VIDC_SETFIELD(param->dmx_disable,
+					VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT,
+					VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) |
+				VIDC_SETFIELD(param->dpb_flush,
+					VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT,
+					VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK) |
+				VIDC_SETFIELD(param->dpb_count,
+					VIDC_1080P_SI_RG10_NUM_DPB_SHFT,
+					VIDC_1080P_SI_RG10_NUM_DPB_BMSK);
+	VIDC_HWIO_OUT(REG_821977,
+		param->descriptor_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_576987, param->descriptor_buffer_size);
+	VIDC_HWIO_OUT(REG_70448, param->release_dpb_bit_mask);
+	VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_220637, dpb_config);
+	VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_313350, (u32)param->decode |
+		param->inst_id);
+}
+
+void vidc_1080p_decode_init_buffers_ch0(
+	struct vidc_1080p_dec_init_buffers_param *param)
+{
+	u32 dpb_config;
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	dpb_config = VIDC_SETFIELD(param->dmx_disable,
+					VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT,
+					VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) |
+				VIDC_SETFIELD(param->dpb_count,
+					VIDC_1080P_SI_RG10_NUM_DPB_SHFT,
+					VIDC_1080P_SI_RG10_NUM_DPB_BMSK);
+	VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_404623, dpb_config);
+	VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_DEC_TYPE_INIT_BUFFERS |
+		param->inst_id);
+}
+
+void vidc_1080p_decode_init_buffers_ch1(
+	struct vidc_1080p_dec_init_buffers_param *param)
+{
+	u32 dpb_config;
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+	dpb_config = VIDC_SETFIELD(param->dmx_disable,
+					VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT,
+					VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) |
+				VIDC_SETFIELD(param->dpb_count,
+					VIDC_1080P_SI_RG10_NUM_DPB_SHFT,
+					VIDC_1080P_SI_RG10_NUM_DPB_BMSK);
+	VIDC_HWIO_OUT(REG_652528,  param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_220637, dpb_config);
+	VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_DEC_TYPE_INIT_BUFFERS |
+		param->inst_id);
+}
+
+void vidc_1080p_set_dec_resolution_ch0(u32 width, u32 height)
+{
+	VIDC_HWIO_OUT(REG_612810, height);
+	VIDC_HWIO_OUT(REG_175608, width);
+}
+
+void vidc_1080p_set_dec_resolution_ch1(u32 width, u32 height)
+{
+	VIDC_HWIO_OUT(REG_655721, height);
+	VIDC_HWIO_OUT(REG_548308, width);
+}
+
+void vidc_1080p_get_encode_frame_info(
+	struct vidc_1080p_enc_frame_info *frame_info)
+{
+	VIDC_HWIO_IN(REG_845544, &(frame_info->enc_frame_size));
+	VIDC_HWIO_IN(REG_859906,
+		&(frame_info->enc_picture_count));
+	VIDC_HWIO_IN(REG_490078,
+		&(frame_info->enc_write_pointer));
+	VIDC_HWIO_IN(REG_640904,
+		(u32 *)(&(frame_info->enc_frame)));
+	VIDC_HWIO_IN(REG_60114,
+		&(frame_info->enc_luma_address));
+	frame_info->enc_luma_address = frame_info->enc_luma_address <<
+		VIDC_1080P_BASE_OFFSET_SHIFT;
+	VIDC_HWIO_IN(REG_489688,
+		&(frame_info->enc_chroma_address));
+	frame_info->enc_chroma_address = frame_info->\
+		enc_chroma_address << VIDC_1080P_BASE_OFFSET_SHIFT;
+}
+
+void vidc_1080p_encode_seq_start_ch0(
+	struct vidc_1080p_enc_seq_start_param *param)
+{
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_117192,
+		param->stream_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_921356, param->stream_buffer_size);
+	VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_ENC_TYPE_SEQ_HEADER |
+		param->inst_id);
+}
+
+void vidc_1080p_encode_seq_start_ch1(
+	struct vidc_1080p_enc_seq_start_param *param)
+{
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_980194,
+		param->stream_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_821977, param->stream_buffer_size);
+	VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_ENC_TYPE_SEQ_HEADER |
+		param->inst_id);
+}
+
+void vidc_1080p_encode_frame_start_ch0(
+	struct vidc_1080p_enc_frame_start_param *param)
+{
+	u32 input_flush;
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_117192,
+		param->stream_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_921356, param->stream_buffer_size);
+	VIDC_HWIO_OUT(REG_612810, param->current_y_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_175608, param->current_c_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_190381, param->intra_frame);
+	VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
+	input_flush = VIDC_SETFIELD(param->input_flush,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+	input_flush |= VIDC_SETFIELD(param->slice_enable,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+	VIDC_HWIO_OUT(REG_404623, input_flush);
+	VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+
+	VIDC_HWIO_OUT(REG_666957, (u32)param->encode |
+		param->inst_id);
+}
+
+void vidc_1080p_encode_frame_start_ch1(
+	struct vidc_1080p_enc_frame_start_param *param)
+{
+	u32 input_flush;
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_980194,
+		param->stream_buffer_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_821977, param->stream_buffer_size);
+	VIDC_HWIO_OUT(REG_655721, param->current_y_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_548308,  param->current_c_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_887095, param->intra_frame);
+	VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
+	input_flush = VIDC_SETFIELD(param->input_flush,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+	input_flush |= VIDC_SETFIELD(param->slice_enable,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+
+	VIDC_HWIO_OUT(REG_404623, input_flush);
+	VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_313350, (u32)param->encode |
+		param->inst_id);
+}
+
+void vidc_1080p_encode_slice_batch_start_ch0(
+	struct vidc_1080p_enc_frame_start_param *param)
+{
+	u32 input_flush;
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_612810, param->current_y_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_175608, param->current_c_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_190381, param->intra_frame);
+	VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
+	input_flush = VIDC_SETFIELD(param->input_flush,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+	input_flush |= VIDC_SETFIELD(param->slice_enable,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+	VIDC_HWIO_OUT(REG_404623, input_flush);
+	VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+
+	VIDC_HWIO_OUT(REG_666957, (u32)param->encode |
+		param->inst_id);
+
+}
+
+void vidc_1080p_encode_slice_batch_start_ch1(
+	struct vidc_1080p_enc_frame_start_param *param)
+{
+	u32 input_flush;
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_655721, param->current_y_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_548308,  param->current_c_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_887095, param->intra_frame);
+	VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
+	input_flush = VIDC_SETFIELD(param->input_flush,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+	input_flush |= VIDC_SETFIELD(param->slice_enable,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+
+	VIDC_HWIO_OUT(REG_404623, input_flush);
+	VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_313350, (u32)param->encode |
+		param->inst_id);
+
+}
+
+void vidc_1080p_set_encode_picture(u32 number_p, u32 number_b)
+{
+	u32 picture, ifrm_ctrl;
+	if (number_p >= VIDC_1080P_MAX_INTRA_PERIOD)
+		ifrm_ctrl = 0;
+	else
+		ifrm_ctrl = number_p + 1;
+	picture = VIDC_SETFIELD(1 ,
+				HWIO_REG_783891_ENC_PIC_TYPE_USE_SHFT,
+				HWIO_REG_783891_ENC_PIC_TYPE_USE_BMSK) |
+				VIDC_SETFIELD(ifrm_ctrl,
+					HWIO_REG_783891_I_FRM_CTRL_SHFT,
+					HWIO_REG_783891_I_FRM_CTRL_BMSK)
+				| VIDC_SETFIELD(number_b ,
+				HWIO_REG_783891_B_FRM_CTRL_SHFT ,
+				HWIO_REG_783891_B_FRM_CTRL_BMSK);
+	VIDC_HWIO_OUT(REG_783891, picture);
+}
+
+void vidc_1080p_set_encode_multi_slice_control(
+	enum vidc_1080p_MSlice_selection multiple_slice_selection,
+	u32 mslice_mb, u32 mslice_byte)
+{
+	VIDC_HWIO_OUT(REG_226332, multiple_slice_selection);
+	VIDC_HWIO_OUT(REG_696136, mslice_mb);
+	VIDC_HWIO_OUT(REG_515564, mslice_byte);
+}
+
+void vidc_1080p_set_encode_circular_intra_refresh(u32 cir_num)
+{
+	VIDC_HWIO_OUT(REG_886210, cir_num);
+}
+
+void vidc_1080p_set_encode_input_frame_format(
+	enum vidc_1080p_memory_access_method memory_format)
+{
+	VIDC_HWIO_OUT(REG_645603, memory_format);
+}
+
+void vidc_1080p_set_encode_padding_control(u32 pad_ctrl_on,
+	u32 cr_pad_val, u32 cb_pad_val, u32 luma_pad_val)
+{
+	u32 padding = VIDC_SETFIELD(pad_ctrl_on ,
+				HWIO_REG_811733_PAD_CTRL_ON_SHFT,
+				HWIO_REG_811733_PAD_CTRL_ON_BMSK) |
+			VIDC_SETFIELD(cr_pad_val ,
+				HWIO_REG_811733_CR_PAD_VIDC_SHFT ,
+				HWIO_REG_811733_CR_PAD_VIDC_BMSK) |
+			VIDC_SETFIELD(cb_pad_val ,
+				HWIO_REG_811733_CB_PAD_VIDC_SHFT ,
+				HWIO_REG_811733_CB_PAD_VIDC_BMSK) |
+			VIDC_SETFIELD(luma_pad_val ,
+				HWIO_REG_811733_LUMA_PAD_VIDC_SHFT ,
+				HWIO_REG_811733_LUMA_PAD_VIDC_BMSK) ;
+	VIDC_HWIO_OUT(REG_811733, padding);
+}
+
+void vidc_1080p_encode_set_rc_config(u32 enable_frame_level_rc,
+	u32 enable_mb_level_rc_flag, u32 frame_qp)
+{
+	u32 rc_config = VIDC_SETFIELD(enable_frame_level_rc ,
+					HWIO_REG_559908_FR_RC_EN_SHFT ,
+					HWIO_REG_559908_FR_RC_EN_BMSK) |
+			VIDC_SETFIELD(enable_mb_level_rc_flag ,
+					HWIO_REG_559908_MB_RC_EN_SHFT,
+					HWIO_REG_559908_MB_RC_EN_BMSK) |
+			VIDC_SETFIELD(frame_qp ,
+					HWIO_REG_559908_FRAME_QP_SHFT ,
+					HWIO_REG_559908_FRAME_QP_BMSK);
+	VIDC_HWIO_OUT(REG_559908, rc_config);
+}
+
+void vidc_1080p_encode_set_frame_level_rc_params(u32 rc_frame_rate,
+	u32 target_bitrate, u32 reaction_coeff)
+{
+	VIDC_HWIO_OUT(REG_977937, rc_frame_rate);
+	VIDC_HWIO_OUT(REG_166135, target_bitrate);
+	VIDC_HWIO_OUT(REG_550322, reaction_coeff);
+}
+
+void vidc_1080p_encode_set_qp_params(u32 max_qp, u32 min_qp)
+{
+	u32 qbound = VIDC_SETFIELD(max_qp , HWIO_REG_109072_MAX_QP_SHFT,
+					HWIO_REG_109072_MAX_QP_BMSK) |
+					VIDC_SETFIELD(min_qp,
+					HWIO_REG_109072_MIN_QP_SHFT ,
+					HWIO_REG_109072_MIN_QP_BMSK);
+	VIDC_HWIO_OUT(REG_109072, qbound);
+}
+
+void vidc_1080p_encode_set_mb_level_rc_params(u32 disable_dark_region_as_flag,
+	u32 disable_smooth_region_as_flag , u32 disable_static_region_as_flag,
+	u32 disable_activity_region_flag)
+{
+	u32 rc_active_feature = VIDC_SETFIELD(
+					disable_dark_region_as_flag,
+					HWIO_REG_949086_DARK_DISABLE_SHFT,
+					HWIO_REG_949086_DARK_DISABLE_BMSK) |
+					VIDC_SETFIELD(
+					disable_smooth_region_as_flag,
+					HWIO_REG_949086_SMOOTH_DISABLE_SHFT,
+					HWIO_REG_949086_SMOOTH_DISABLE_BMSK) |
+					VIDC_SETFIELD(
+					disable_static_region_as_flag,
+					HWIO_REG_949086_STATIC_DISABLE_SHFT,
+					HWIO_REG_949086_STATIC_DISABLE_BMSK) |
+					VIDC_SETFIELD(
+					disable_activity_region_flag,
+					HWIO_REG_949086_ACT_DISABLE_SHFT,
+					HWIO_REG_949086_ACT_DISABLE_BMSK);
+	VIDC_HWIO_OUT(REG_949086, rc_active_feature);
+}
+
+void vidc_1080p_set_h264_encode_entropy(
+	enum vidc_1080p_entropy_sel entropy_sel)
+{
+	VIDC_HWIO_OUT(REG_447796, entropy_sel);
+}
+
+void vidc_1080p_set_h264_encode_loop_filter(
+	enum vidc_1080p_DBConfig db_config, u32 slice_alpha_offset,
+	u32 slice_beta_offset)
+{
+	VIDC_HWIO_OUT(REG_152500, db_config);
+	VIDC_HWIO_OUT(REG_266285, slice_alpha_offset);
+	VIDC_HWIO_OUT(REG_964731, slice_beta_offset);
+}
+
+void vidc_1080p_set_h264_encoder_p_frame_ref_count(u32 max_reference)
+{
+	u32 ref_frames;
+	ref_frames = VIDC_SETFIELD(max_reference,
+		HWIO_REG_744348_P_SHFT,
+		HWIO_REG_744348_P_BMSK);
+	VIDC_HWIO_OUT(REG_744348, ref_frames);
+}
+
+void vidc_1080p_set_h264_encode_8x8transform_control(u32 enable_8x8transform)
+{
+	VIDC_HWIO_OUT(REG_672163, enable_8x8transform);
+}
+
+void vidc_1080p_set_mpeg4_encode_quarter_pel_control(
+	u32 enable_mpeg4_quarter_pel)
+{
+	VIDC_HWIO_OUT(REG_330132, enable_mpeg4_quarter_pel);
+}
+
+void vidc_1080p_set_device_base_addr(u8 *mapped_va)
+{
+	VIDC_BASE_PTR = mapped_va;
+}
+
+void vidc_1080p_get_intra_bias(u32 *bias)
+{
+	u32 intra_bias;
+
+	VIDC_HWIO_IN(REG_676866, &intra_bias);
+	*bias = VIDC_GETFIELD(intra_bias,
+					HWIO_REG_676866_RMSK,
+					HWIO_REG_676866_SHFT);
+}
+
+void vidc_1080p_set_intra_bias(u32 bias)
+{
+	u32 intra_bias;
+
+	intra_bias = VIDC_SETFIELD(bias,
+					HWIO_REG_676866_SHFT,
+					HWIO_REG_676866_RMSK);
+	VIDC_HWIO_OUT(REG_676866, intra_bias);
+}
+
+void vidc_1080p_get_bi_directional_bias(u32 *bi_directional_bias)
+{
+	u32 nbi_direct_bias;
+
+	VIDC_HWIO_IN(REG_54267, &nbi_direct_bias);
+	*bi_directional_bias = VIDC_GETFIELD(nbi_direct_bias,
+					HWIO_REG_54267_RMSK,
+					HWIO_REG_54267_SHFT);
+}
+
+void vidc_1080p_set_bi_directional_bias(u32 bi_directional_bias)
+{
+	u32 nbi_direct_bias;
+
+	nbi_direct_bias = VIDC_SETFIELD(bi_directional_bias,
+					HWIO_REG_54267_SHFT,
+					HWIO_REG_54267_RMSK);
+	VIDC_HWIO_OUT(REG_54267, nbi_direct_bias);
+}
+
+void vidc_1080p_get_encoder_sequence_header_size(u32 *seq_header_size)
+{
+	VIDC_HWIO_IN(REG_845544, seq_header_size);
+}
+
+void vidc_1080p_get_intermedia_stage_debug_counter(
+	u32 *intermediate_stage_counter)
+{
+	VIDC_HWIO_IN(REG_805993, intermediate_stage_counter);
+}
+
+void vidc_1080p_get_exception_status(u32 *exception_status)
+{
+	VIDC_HWIO_IN(REG_493355, exception_status);
+}
+
+void vidc_1080p_frame_start_realloc(u32 instance_id)
+{
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_666957,
+		VIDC_1080P_DEC_TYPE_FRAME_START_REALLOC | instance_id);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.h b/drivers/video/msm/vidc/1080p/ddl/vidc.h
new file mode 100644
index 0000000..7460ef3
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h
@@ -0,0 +1,586 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VIDC_H_
+#define _VIDC_H_
+
+#include "vidc_hwio_reg.h"
+
+#define VIDC_1080P_RISC2HOST_CMD_EMPTY               0
+#define VIDC_1080P_RISC2HOST_CMD_OPEN_CH_RET         1
+#define VIDC_1080P_RISC2HOST_CMD_CLOSE_CH_RET        2
+#define VIDC_1080P_RISC2HOST_CMD_SEQ_DONE_RET        4
+#define VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET      5
+#define VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET      6
+#define VIDC_1080P_RISC2HOST_CMD_ENC_COMPLETE_RET    7
+#define VIDC_1080P_RISC2HOST_CMD_SYS_INIT_RET        8
+#define VIDC_1080P_RISC2HOST_CMD_FW_STATUS_RET       9
+#define VIDC_1080P_RISC2HOST_CMD_FLUSH_COMMAND_RET  12
+#define VIDC_1080P_RISC2HOST_CMD_ABORT_RET          13
+#define VIDC_1080P_RISC2HOST_CMD_BATCH_ENC_RET      14
+#define VIDC_1080P_RISC2HOST_CMD_INIT_BUFFERS_RET   15
+#define VIDC_1080P_RISC2HOST_CMD_EDFU_INT_RET       16
+#define VIDC_1080P_RISC2HOST_CMD_ERROR_RET          32
+
+#define VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_BMSK  0xffff0000
+#define VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_SHFT  16
+#define VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_BMSK   0x0000ffff
+#define VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_SHFT   0
+
+#define VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER                  1
+#define VIDC_1080P_ERROR_INVALID_COMMAND_ID                      2
+#define VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE                  3
+#define VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE   4
+#define VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START                 5
+#define VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED                6
+#define VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS              7
+#define VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS            8
+#define VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED              9
+#define VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START              10
+#define VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START            11
+#define VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START         12
+#define VIDC_1080P_ERROR_RESOLUTION_CHANGED                     13
+#define VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME             14
+#define VIDC_1080P_ERROR_INVALID_COMMAND                        15
+#define VIDC_1080P_ERROR_INVALID_CODEC_TYPE                     16
+
+#define VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED                  20
+#define VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE              25
+#define VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE         27
+#define VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED               28
+
+#define VIDC_1080P_ERROR_HEADER_NOT_FOUND                 52
+#define VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED            53
+#define VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED         62
+#define VIDC_1080P_ERROR_INVALID_QP_VALUE                 63
+#define VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT  64
+#define VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL  65
+#define VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED            66
+#define VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT    71
+#define VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE             74
+#define VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER      77
+#define VIDC_1080P_ERROR_NULL_DPB_POINTER                 78
+#define VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR             79
+#define VIDC_1080P_ERROR_NULL_MV_POINTER                  80
+#define VIDC_1080P_ERROR_DIVIDE_BY_ZERO                   81
+#define VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST           82
+#define VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY          83
+#define VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE              84
+#define VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID   85
+#define VIDC_1080P_ERROR_MB_COEFF_NOT_DONE        86
+#define VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE     87
+#define VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT       88
+#define VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR  89
+#define VIDC_1080P_ERROR_VSP_NOT_READY            90
+#define VIDC_1080P_ERROR_BUFFER_FULL_STATE        91
+
+#define VIDC_1080P_ERROR_RESOLUTION_MISMATCH      112
+#define VIDC_1080P_ERROR_NV_QUANT_ERR             113
+#define VIDC_1080P_ERROR_SYNC_MARKER_ERR          114
+#define VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED    115
+#define VIDC_1080P_ERROR_MEM_CORRUPTION           116
+#define VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME  117
+#define VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR  118
+#define VIDC_1080P_ERROR_MV_RANGE_ERR             119
+#define VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR    120
+#define VIDC_1080P_ERROR_SLICE_ADDR_INVALID       121
+#define VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED         122
+#define VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED                123
+#define VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST           125
+#define VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER             126
+#define VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT     127
+#define VIDC_1080P_ERROR_NALU_HEADER_ERROR       128
+#define VIDC_1080P_ERROR_SPS_PARSE_ERROR         129
+#define VIDC_1080P_ERROR_PPS_PARSE_ERROR         130
+#define VIDC_1080P_ERROR_SLICE_PARSE_ERROR       131
+#define VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED  171
+
+#define VIDC_1080P_WARN_COMMAND_FLUSHED                  145
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB 150
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_QP             151
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB     152
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM      153
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_SEI            154
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_VUI            155
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA          156
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE      157
+#define VIDC_1080P_WARN_FRAME_RATE_UNKNOWN               158
+#define VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN             159
+#define VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN          160
+#define VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN            161
+#define VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN             162
+#define VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR               163
+#define VIDC_1080P_WARN_BROKEN_LINK                      164
+#define VIDC_1080P_WARN_FRAME_CONCEALED                  165
+#define VIDC_1080P_WARN_PROFILE_UNKNOWN                  166
+#define VIDC_1080P_WARN_LEVEL_UNKNOWN                    167
+#define VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED           168
+#define VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED  169
+#define VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER      170
+#define VIDC_1080P_WARN_DEBLOCKING_NOT_DONE              178
+#define VIDC_1080P_WARN_INCOMPLETE_FRAME                 179
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO        180
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE     181
+#define VIDC_1080P_WARN_RESOLUTION_WARNING               182
+
+#define VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE           183
+#define VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP         190
+#define VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB     191
+
+#define VIDC_1080P_H264_ENC_TYPE_P       0
+#define VIDC_1080P_H264_ENC_TYPE_B       1
+#define VIDC_1080P_H264_ENC_TYPE_IDR     2
+#define VIDC_1080P_MP4_H263_ENC_TYPE_I   0
+#define VIDC_1080P_MP4_H263_ENC_TYPE_P   1
+#define VIDC_1080P_MP4_H263_ENC_TYPE_B   2
+
+#define VIDC_1080P_MPEG4_LEVEL0    0
+#define VIDC_1080P_MPEG4_LEVEL0b   9
+#define VIDC_1080P_MPEG4_LEVEL1    1
+#define VIDC_1080P_MPEG4_LEVEL2    2
+#define VIDC_1080P_MPEG4_LEVEL3    3
+#define VIDC_1080P_MPEG4_LEVEL3b   7
+#define VIDC_1080P_MPEG4_LEVEL4    4
+#define VIDC_1080P_MPEG4_LEVEL4a   4
+#define VIDC_1080P_MPEG4_LEVEL5    5
+#define VIDC_1080P_MPEG4_LEVEL6    6
+#define VIDC_1080P_MPEG4_LEVEL7    7
+
+#define VIDC_1080P_H264_LEVEL1     10
+#define VIDC_1080P_H264_LEVEL1b    9
+#define VIDC_1080P_H264_LEVEL1p1   11
+#define VIDC_1080P_H264_LEVEL1p2   12
+#define VIDC_1080P_H264_LEVEL1p3   13
+#define VIDC_1080P_H264_LEVEL2     20
+#define VIDC_1080P_H264_LEVEL2p1   21
+#define VIDC_1080P_H264_LEVEL2p2   22
+#define VIDC_1080P_H264_LEVEL3     30
+#define VIDC_1080P_H264_LEVEL3p1   31
+#define VIDC_1080P_H264_LEVEL3p2   32
+#define VIDC_1080P_H264_LEVEL4     40
+#define VIDC_1080P_H264_LEVEL5p1   51
+#define VIDC_1080P_H264_LEVEL_MAX  VIDC_1080P_H264_LEVEL5p1
+
+#define VIDC_1080P_H263_LEVEL10    10
+#define VIDC_1080P_H263_LEVEL20    20
+#define VIDC_1080P_H263_LEVEL30    30
+#define VIDC_1080P_H263_LEVEL40    40
+#define VIDC_1080P_H263_LEVEL45    45
+#define VIDC_1080P_H263_LEVEL50    50
+#define VIDC_1080P_H263_LEVEL60    60
+#define VIDC_1080P_H263_LEVEL70    70
+
+#define VIDC_1080P_BUS_ERROR_HANDLER                   0x01
+#define VIDC_1080P_ILLEVIDC_INSTRUCTION_HANDLER         0x02
+#define VIDC_1080P_TICK_HANDLER                        0x04
+#define VIDC_1080P_TRAP_HANDLER                        0x10
+#define VIDC_1080P_ALIGN_HANDLER                       0x20
+#define VIDC_1080P_RANGE_HANDLER                       0x40
+#define VIDC_1080P_DTLB_MISS_EXCEPTION_HANDLER         0x80
+#define VIDC_1080P_ITLB_MISS_EXCEPTION_HANDLER        0x100
+#define VIDC_1080P_DATA_PAGE_FAULT_EXCEPTION_HANDLER  0x200
+#define VIDC_1080P_INST_PAGE_FAULT_EXCEPTION_HANDLER  0x400
+#define VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR           8
+#define VIDC_1080P_SLICE_BATCH_IN_SIZE(idx)           (4 * sizeof(u32) + \
+							idx * sizeof(u32))
+enum vidc_1080p_reset{
+	VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE   = 0x0,
+	VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE  = 0x1,
+};
+enum vidc_1080p_memory_access_method{
+	VIDC_1080P_TILE_LINEAR = 0,
+	VIDC_1080P_TILE_16x16  = 2,
+	VIDC_1080P_TILE_64x32  = 3,
+	VIDC_1080P_TILE_32BIT  = 0x7FFFFFFF
+};
+enum vidc_1080p_host2risc_cmd{
+	VIDC_1080P_HOST2RISC_CMD_EMPTY          = 0,
+	VIDC_1080P_HOST2RISC_CMD_OPEN_CH        = 1,
+	VIDC_1080P_HOST2RISC_CMD_CLOSE_CH       = 2,
+	VIDC_1080P_HOST2RISC_CMD_SYS_INIT       = 3,
+	VIDC_1080P_HOST2RISC_CMD_FLUSH_COMMMAND = 4,
+	VIDC_1080P_HOST2RISC_CMD_CONTINUE_ENC   = 7,
+	VIDC_1080P_HOST2RISC_CMD_ABORT_ENC      = 8,
+	VIDC_1080P_HOST2RISC_CMD_32BIT          = 0x7FFFFFFF
+};
+enum vidc_1080p_decode_p_cache_enable{
+	VIDC_1080P_DECODE_PCACHE_ENABLE_P   = 0,
+	VIDC_1080P_DECODE_PCACHE_ENABLE_B   = 1,
+	VIDC_1080P_DECODE_PCACHE_ENABLE_PB  = 2,
+	VIDC_1080P_DECODE_PCACHE_DISABLE    = 3,
+	VIDC_1080P_DECODE_PCACHE_32BIT      = 0x7FFFFFFF
+};
+enum vidc_1080p_encode_p_cache_enable{
+	VIDC_1080P_ENCODE_PCACHE_ENABLE  = 0,
+	VIDC_1080P_ENCODE_PCACHE_DISABLE = 3,
+	VIDC_1080P_ENCODE_PCACHE_32BIT   = 0x7FFFFFFF
+};
+enum vidc_1080p_codec{
+	VIDC_1080P_H264_DECODE     = 0,
+	VIDC_1080P_VC1_DECODE      = 1,
+	VIDC_1080P_MPEG4_DECODE    = 2,
+	VIDC_1080P_MPEG2_DECODE    = 3,
+	VIDC_1080P_H263_DECODE     = 4,
+	VIDC_1080P_VC1_RCV_DECODE  = 5,
+	VIDC_1080P_DIVX311_DECODE  = 6,
+	VIDC_1080P_DIVX412_DECODE  = 7,
+	VIDC_1080P_DIVX502_DECODE  = 8,
+	VIDC_1080P_DIVX503_DECODE  = 9,
+	VIDC_1080P_H264_ENCODE    = 16,
+	VIDC_1080P_MPEG4_ENCODE   = 17,
+	VIDC_1080P_H263_ENCODE    = 18,
+	VIDC_1080P_CODEC_32BIT    = 0x7FFFFFFF
+};
+enum vidc_1080p_entropy_sel{
+	VIDC_1080P_ENTROPY_SEL_CAVLC = 0,
+	VIDC_1080P_ENTROPY_SEL_CABAC = 1,
+	VIDC_1080P_ENTROPY_32BIT     = 0x7FFFFFFF
+};
+enum vidc_1080p_DBConfig{
+	VIDC_1080P_DB_ALL_BLOCKING_BOUNDARY  = 0,
+	VIDC_1080P_DB_DISABLE                = 1,
+	VIDC_1080P_DB_SKIP_SLICE_BOUNDARY    = 2,
+	VIDC_1080P_DB_32BIT                  = 0x7FFFFFFF
+};
+enum vidc_1080p_MSlice_selection{
+	VIDC_1080P_MSLICE_DISABLE        = 0,
+	VIDC_1080P_MSLICE_BY_MB_COUNT    = 1,
+	VIDC_1080P_MSLICE_BY_BYTE_COUNT  = 3,
+	VIDC_1080P_MSLICE_32BIT          = 0x7FFFFFFF
+};
+enum vidc_1080p_display_status{
+	VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY        = 0,
+	VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY = 1,
+	VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY       = 2,
+	VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY          = 3,
+	VIDC_1080P_DISPLAY_STATUS_NOOP               = 4,
+	VIDC_1080P_DISPLAY_STATUS_32BIT              = 0x7FFFFFFF
+};
+enum vidc_1080p_display_coding{
+	VIDC_1080P_DISPLAY_CODING_PROGRESSIVE_SCAN = 0,
+	VIDC_1080P_DISPLAY_CODING_INTERLACED       = 1,
+	VIDC_1080P_DISPLAY_CODING_32BIT            = 0x7FFFFFFF
+};
+enum vidc_1080p_decode_frame{
+	VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED  = 0,
+	VIDC_1080P_DECODE_FRAMETYPE_I          = 1,
+	VIDC_1080P_DECODE_FRAMETYPE_P          = 2,
+	VIDC_1080P_DECODE_FRAMETYPE_B          = 3,
+	VIDC_1080P_DECODE_FRAMETYPE_OTHERS     = 4,
+	VIDC_1080P_DECODE_FRAMETYPE_32BIT      = 0x7FFFFFFF
+};
+enum vidc_1080P_decode_frame_correct_type {
+	VIDC_1080P_DECODE_NOT_CORRECT = 0,
+	VIDC_1080P_DECODE_CORRECT = 1,
+	VIDC_1080P_DECODE_APPROX_CORRECT = 2,
+	VIDC_1080P_DECODE_CORRECTTYPE_32BIT = 0x7FFFFFFF
+};
+enum vidc_1080p_encode_frame{
+	VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED  = 0,
+	VIDC_1080P_ENCODE_FRAMETYPE_I          = 1,
+	VIDC_1080P_ENCODE_FRAMETYPE_P          = 2,
+	VIDC_1080P_ENCODE_FRAMETYPE_B          = 3,
+	VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED    = 4,
+	VIDC_1080P_ENCODE_FRAMETYPE_OTHERS     = 5,
+	VIDC_1080P_ENCODE_FRAMETYPE_32BIT      = 0x7FFFFFFF
+
+};
+
+enum vidc_1080p_decode_idc_format {
+	VIDC_1080P_IDCFORMAT_MONOCHROME = 0,
+	VIDC_1080P_IDCFORMAT_420 = 1,
+	VIDC_1080P_IDCFORMAT_422 = 2,
+	VIDC_1080P_IDCFORMAT_444 = 3,
+	VIDC_1080P_IDCFORMAT_OTHERS = 4,
+	VIDC_1080P_IDCFORMAT_32BIT = 0x7FFFFFFF
+};
+
+#define VIDC_1080P_PROFILE_MPEG4_SIMPLE      0x00000000
+#define VIDC_1080P_PROFILE_MPEG4_ADV_SIMPLE  0x00000001
+
+#define VIDC_1080P_PROFILE_H264_MAIN         0x00000000
+#define VIDC_1080P_PROFILE_H264_HIGH         0x00000001
+#define VIDC_1080P_PROFILE_H264_BASELINE     0x00000002
+
+
+enum vidc_1080p_decode{
+	VIDC_1080P_DEC_TYPE_SEQ_HEADER       = 0x00010000,
+	VIDC_1080P_DEC_TYPE_FRAME_DATA       = 0x00020000,
+	VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA  = 0x00030000,
+	VIDC_1080P_DEC_TYPE_INIT_BUFFERS     = 0x00040000,
+	VIDC_1080P_DEC_TYPE_FRAME_START_REALLOC = 0x00050000,
+	VIDC_1080P_DEC_TYPE_32BIT            = 0x7FFFFFFF
+};
+enum vidc_1080p_encode{
+	VIDC_1080P_ENC_TYPE_SEQ_HEADER        = 0x00010000,
+	VIDC_1080P_ENC_TYPE_FRAME_DATA        = 0x00020000,
+	VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA   = 0x00030000,
+	VIDC_1080P_ENC_TYPE_SLICE_BATCH_START = 0x00070000,
+	VIDC_1080P_ENC_TYPE_32BIT             = 0x7FFFFFFF
+};
+struct vidc_1080p_dec_seq_start_param{
+	u32 cmd_seq_num;
+	u32 inst_id;
+	u32 shared_mem_addr_offset;
+	u32 stream_buffer_addr_offset;
+	u32 stream_buffersize;
+	u32 stream_frame_size;
+	u32 descriptor_buffer_addr_offset;
+	u32 descriptor_buffer_size;
+};
+struct vidc_1080p_dec_frame_start_param{
+	u32 cmd_seq_num;
+	u32 inst_id;
+	u32 shared_mem_addr_offset;
+	u32 stream_buffer_addr_offset;
+	u32 stream_buffersize;
+	u32 stream_frame_size;
+	u32 descriptor_buffer_addr_offset;
+	u32 descriptor_buffer_size;
+	u32 release_dpb_bit_mask;
+	u32 dpb_count;
+	u32 dpb_flush;
+	u32 dmx_disable;
+	enum vidc_1080p_decode decode;
+};
+struct vidc_1080p_dec_init_buffers_param{
+	u32 cmd_seq_num;
+	u32 inst_id;
+	u32 shared_mem_addr_offset;
+	u32 dpb_count;
+	u32 dmx_disable;
+};
+struct vidc_1080p_seq_hdr_info{
+	u32 img_size_x;
+	u32 img_size_y;
+	u32 dec_frm_size;
+	u32 min_num_dpb;
+	u32 min_luma_dpb_size;
+	u32 min_chroma_dpb_size;
+	u32 profile;
+	u32 level;
+	u32 disp_progressive;
+	u32 disp_crop_exists;
+	u32 dec_progressive;
+	u32 dec_crop_exists;
+	u32 crop_right_offset;
+	u32 crop_left_offset;
+	u32 crop_bottom_offset;
+	u32 crop_top_offset;
+	u32 data_partition;
+};
+struct vidc_1080p_enc_seq_start_param{
+	u32 cmd_seq_num;
+	u32 inst_id;
+	u32 shared_mem_addr_offset;
+	u32 stream_buffer_addr_offset;
+	u32 stream_buffer_size;
+};
+struct vidc_1080p_enc_frame_start_param{
+	u32 cmd_seq_num;
+	u32 inst_id;
+	u32 shared_mem_addr_offset;
+	u32 current_y_addr_offset;
+	u32 current_c_addr_offset;
+	u32 stream_buffer_addr_offset;
+	u32 stream_buffer_size;
+	u32 intra_frame;
+	u32 input_flush;
+	u32 slice_enable;
+	enum vidc_1080p_encode encode;
+};
+struct vidc_1080p_enc_frame_info{
+	u32 enc_frame_size;
+	u32 enc_picture_count;
+	u32 enc_write_pointer;
+	u32 enc_luma_address;
+	u32 enc_chroma_address;
+	enum vidc_1080p_encode_frame enc_frame;
+	u32 meta_data_exists;
+};
+struct vidc_1080p_enc_slice_batch_in_param {
+	u32 cmd_type;
+	u32 input_size;
+	u32 num_stream_buffer;
+	u32 stream_buffer_size;
+	u32 stream_buffer_addr_offset[VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR];
+};
+struct vidc_1080p_enc_slice_info {
+	u32 stream_buffer_idx;
+	u32 stream_buffer_size;
+};
+struct vidc_1080p_enc_slice_batch_out_param {
+	u32 cmd_type;
+	u32 output_size;
+	struct vidc_1080p_enc_slice_info slice_info
+		[VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR];
+};
+struct vidc_1080p_dec_disp_info{
+	u32 disp_resl_change;
+	u32 dec_resl_change;
+	u32 reconfig_flush_done;
+	u32 img_size_x;
+	u32 img_size_y;
+	u32 display_y_addr;
+	u32 display_c_addr;
+	u32 decode_y_addr;
+	u32 decode_c_addr;
+	u32 tag_top;
+	u32 pic_time_top;
+	u32 tag_bottom;
+	u32 pic_time_bottom;
+	u32 metadata_exists;
+	u32 disp_crop_exists;
+	u32 dec_crop_exists;
+	u32 crop_right_offset;
+	u32 crop_left_offset;
+	u32 crop_bottom_offset;
+	u32 crop_top_offset;
+	u32 input_bytes_consumed;
+	u32 input_is_interlace;
+	u32 input_frame_num;
+	enum vidc_1080p_display_status display_status;
+	enum vidc_1080p_display_status decode_status;
+	enum vidc_1080p_display_coding display_coding;
+	enum vidc_1080p_display_coding decode_coding;
+	enum vidc_1080P_decode_frame_correct_type display_correct;
+	enum vidc_1080P_decode_frame_correct_type decode_correct;
+	enum vidc_1080p_decode_frame input_frame;
+};
+void vidc_1080p_do_sw_reset(enum vidc_1080p_reset init_flag);
+void vidc_1080p_release_sw_reset(void);
+void vidc_1080p_clear_interrupt(void);
+void vidc_1080p_set_host2risc_cmd(
+	enum vidc_1080p_host2risc_cmd host2risc_command,
+	u32 host2risc_arg1, u32 host2risc_arg2,
+	u32 host2risc_arg3, u32 host2risc_arg4);
+void vidc_1080p_get_risc2host_cmd(u32 *pn_risc2host_command,
+	u32 *pn_risc2host_arg1, u32 *pn_risc2host_arg2,
+	u32 *pn_risc2host_arg3, u32 *pn_risc2host_arg4);
+void vidc_1080p_get_risc2host_cmd_status(u32 err_status,
+	u32 *dec_err_status, u32 *disp_err_status);
+void vidc_1080p_clear_risc2host_cmd(void);
+void vidc_1080p_get_fw_version(u32 *pn_fw_version);
+void vidc_1080p_get_fw_status(u32 *pn_fw_status);
+void vidc_1080p_init_memory_controller(u32 dram_base_addr_a,
+	u32 dram_base_addr_b);
+void vidc_1080p_get_memory_controller_status(u32 *pb_mc_abusy,
+	u32 *pb_mc_bbusy);
+void vidc_1080p_set_h264_decode_buffers(u32 dpb, u32 dec_vert_nb_mv_offset,
+	u32 dec_nb_ip_offset, u32 *pn_dpb_luma_offset,
+	u32 *pn_dpb_chroma_offset, u32 *pn_mv_buffer_offset);
+void vidc_1080p_set_decode_recon_buffers(u32 recon_buffer, u32 *pn_dec_luma,
+	u32 *pn_dec_chroma);
+void vidc_1080p_set_mpeg4_divx_decode_work_buffers(u32 nb_dcac_buffer_offset,
+	u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset,
+	u32 overlay_transform_buffer_offset, u32 stx_parser_buffer_offset);
+void vidc_1080p_set_h263_decode_work_buffers(u32 nb_dcac_buffer_offset,
+	u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset,
+	u32 overlay_transform_buffer_offset);
+void vidc_1080p_set_vc1_decode_work_buffers(u32 nb_dcac_buffer_offset,
+	u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset,
+	u32 overlay_transform_buffer_offset, u32 bitplain1Buffer_offset,
+	u32 bitplain2Buffer_offset, u32 bitplain3Buffer_offset);
+void vidc_1080p_set_encode_recon_buffers(u32 recon_buffer, u32 *pn_enc_luma,
+	u32 *pn_enc_chroma);
+void vidc_1080p_set_h264_encode_work_buffers(u32 up_row_mv_buffer_offset,
+	u32 direct_colzero_flag_buffer_offset,
+	u32 upper_intra_md_buffer_offset,
+	u32 upper_intra_pred_buffer_offset, u32 nbor_infor_buffer_offset,
+	u32 mb_info_offset);
+void vidc_1080p_set_h263_encode_work_buffers(u32 up_row_mv_buffer_offset,
+	u32 up_row_inv_quanti_coeff_buffer_offset);
+void vidc_1080p_set_mpeg4_encode_work_buffers(u32 skip_flag_buffer_offset,
+	u32 up_row_inv_quanti_coeff_buffer_offset, u32 upper_mv_offset);
+void vidc_1080p_set_encode_frame_size(u32 hori_size, u32 vert_size);
+void vidc_1080p_set_encode_profile_level(u32 encode_profile, u32 enc_level);
+void vidc_1080p_set_encode_field_picture_structure(u32 enc_field_picture);
+void vidc_1080p_set_decode_mpeg4_pp_filter(u32 lf_enables);
+void vidc_1080p_set_decode_qp_save_control(u32 enable_q_pout);
+void vidc_1080p_get_returned_channel_inst_id(u32 *pn_rtn_chid);
+void vidc_1080p_clear_returned_channel_inst_id(void);
+void vidc_1080p_get_decode_seq_start_result(
+	struct vidc_1080p_seq_hdr_info *seq_hdr_info);
+void vidc_1080p_get_decoded_frame_size(u32 *pn_decoded_size);
+void vidc_1080p_get_display_frame_result(
+	struct vidc_1080p_dec_disp_info *dec_disp_info);
+void vidc_1080p_get_decode_frame(
+	enum vidc_1080p_decode_frame *pe_frame);
+void vidc_1080p_get_decode_frame_result(
+	struct vidc_1080p_dec_disp_info *dec_disp_info);
+void vidc_1080p_decode_seq_start_ch0(
+	struct vidc_1080p_dec_seq_start_param *param);
+void vidc_1080p_decode_seq_start_ch1(
+	struct vidc_1080p_dec_seq_start_param *param);
+void vidc_1080p_decode_init_buffers_ch0
+	(struct vidc_1080p_dec_init_buffers_param *param);
+void vidc_1080p_decode_init_buffers_ch1(
+	struct vidc_1080p_dec_init_buffers_param *param);
+void vidc_1080p_decode_frame_start_ch0(
+	struct vidc_1080p_dec_frame_start_param *param);
+void vidc_1080p_decode_frame_start_ch1(
+	struct vidc_1080p_dec_frame_start_param *param);
+void vidc_1080p_set_dec_resolution_ch0(u32 width, u32 height);
+void vidc_1080p_set_dec_resolution_ch1(u32 width, u32 height);
+void vidc_1080p_get_encode_frame_info(
+	struct vidc_1080p_enc_frame_info *frame_info);
+void vidc_1080p_encode_seq_start_ch0(
+	struct vidc_1080p_enc_seq_start_param *param);
+void vidc_1080p_encode_seq_start_ch1(
+	struct vidc_1080p_enc_seq_start_param *param);
+void vidc_1080p_encode_frame_start_ch0(
+	struct vidc_1080p_enc_frame_start_param *param);
+void vidc_1080p_encode_frame_start_ch1(
+	struct vidc_1080p_enc_frame_start_param *param);
+void vidc_1080p_encode_slice_batch_start_ch0(
+	struct vidc_1080p_enc_frame_start_param *param);
+void vidc_1080p_encode_slice_batch_start_ch1(
+	struct vidc_1080p_enc_frame_start_param *param);
+void vidc_1080p_set_encode_picture(u32 ifrm_ctrl, u32 number_b);
+void vidc_1080p_set_encode_multi_slice_control(
+	enum vidc_1080p_MSlice_selection multiple_slice_selection,
+	u32 mslice_mb, u32 mslice_byte);
+void vidc_1080p_set_encode_circular_intra_refresh(u32 cir_num);
+void vidc_1080p_set_encode_input_frame_format(
+	enum vidc_1080p_memory_access_method memory_format);
+void vidc_1080p_set_encode_padding_control(u32 pad_ctrl_on,
+	u32 cr_pad_val, u32 cb_pad_val, u32 luma_pad_val);
+void vidc_1080p_encode_set_rc_config(u32 enable_frame_level_rc,
+	u32 enable_mb_level_rc_flag, u32 frame_qp);
+void vidc_1080p_encode_set_frame_level_rc_params(u32 rc_frame_rate,
+	u32 target_bitrate, u32 reaction_coeff);
+void vidc_1080p_encode_set_qp_params(u32 max_qp, u32 min_qp);
+void vidc_1080p_encode_set_mb_level_rc_params(u32 disable_dark_region_as_flag,
+	u32 disable_smooth_region_as_flag , u32 disable_static_region_as_flag,
+	u32 disable_activity_region_flag);
+void vidc_1080p_get_qp(u32 *pn_frame_qp);
+void vidc_1080p_set_h264_encode_entropy(
+	enum vidc_1080p_entropy_sel entropy_sel);
+void vidc_1080p_set_h264_encode_loop_filter(
+	enum vidc_1080p_DBConfig db_config, u32 slice_alpha_offset,
+	u32 slice_beta_offset);
+void vidc_1080p_set_h264_encoder_p_frame_ref_count(u32 max_reference);
+void vidc_1080p_set_h264_encode_8x8transform_control(u32 enable_8x8transform);
+void vidc_1080p_set_mpeg4_encode_quarter_pel_control(
+	u32 enable_mpeg4_quarter_pel);
+void vidc_1080p_set_device_base_addr(u8 *mapped_va);
+void vidc_1080p_get_intra_bias(u32 *intra_bias);
+void vidc_1080p_set_intra_bias(u32 intra_bias);
+void vidc_1080p_get_bi_directional_bias(u32 *bi_directional_bias);
+void vidc_1080p_set_bi_directional_bias(u32 bi_directional_bias);
+void vidc_1080p_get_encoder_sequence_header_size(u32 *seq_header_size);
+void vidc_1080p_get_intermedia_stage_debug_counter(
+	u32 *intermediate_stage_counter);
+void vidc_1080p_get_exception_status(u32 *exception_status);
+void vidc_1080p_frame_start_realloc(u32 instance_id);
+#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
new file mode 100644
index 0000000..a5a8e57
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
@@ -0,0 +1,115 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VIDC_HWIO_H_
+#define _VIDC_HWIO_H_
+
+#include "vidc_hwio_reg.h"
+
+#ifdef VIDC_REGISTER_LOG
+#define VIDC_REG_OUT(x...)  printk(KERN_DEBUG x)
+#define VIDC_REG_IN(x...)   printk(KERN_DEBUG x)
+#else
+#define VIDC_REG_OUT(x...)
+#define VIDC_REG_IN(x...)
+#endif
+
+#define __inpdw(port) __raw_readl(port)
+#define __outpdw(port, val) __raw_writel(val, port)
+
+#define in_dword(addr) (__inpdw(addr))
+#define in_dword_masked(addr, mask) (__inpdw(addr) & (mask))
+#define out_dword(addr, val) __outpdw(addr, val)
+
+#define out_dword_masked(io, mask, val, shadow) \
+do { \
+	shadow = (shadow & (u32)(~(mask))) | ((u32)((val) & (mask))); \
+	out_dword(io, shadow); \
+} while (0)
+#define out_dword_masked_ns(io, mask, val, current_reg_content) \
+	out_dword(io, ((current_reg_content & (u32)(~(mask))) | \
+	((u32)((val) & (mask)))))
+
+#define HWIO_IN(hwiosym)  HWIO_##hwiosym##_IN
+#define HWIO_INI(hwiosym, index)  HWIO_##hwiosym##_INI(index)
+#define HWIO_INM(hwiosym, mask)   HWIO_##hwiosym##_INM(mask)
+#define HWIO_INF(hwiosym, field)  (HWIO_INM(hwiosym, \
+	HWIO_FMSK(hwiosym, field)) >> HWIO_SHFT(hwiosym, field))
+
+#define HWIO_OUT(hwiosym, val)  HWIO_##hwiosym##_OUT(val)
+#define HWIO_OUTI(hwiosym, index, val)  HWIO_##hwiosym##_OUTI(index, val)
+#define HWIO_OUTM(hwiosym, mask, val)  HWIO_##hwiosym##_OUTM(mask, val)
+#define HWIO_OUTF(hwiosym, field, val)  HWIO_OUTM(hwiosym, \
+	HWIO_FMSK(hwiosym, field), (u32)(val) << HWIO_SHFT(hwiosym, field))
+
+#define HWIO_SHFT(hwio_regsym, hwio_fldsym) \
+	HWIO_##hwiosym##_##hwiofldsym##_SHFT
+#define HWIO_FMSK(hwio_regsym, hwio_fldsym) \
+	HWIO_##hwiosym##_##hwiofldsym##_BMSK
+
+#define VIDC_SETFIELD(val, shift, mask) \
+	(((val) << (shift)) & (mask))
+#define VIDC_GETFIELD(val, mask, shift) \
+	(((val) & (mask)) >> (shift))
+
+#define VIDC_HWIO_OUT(hwiosym, val) \
+do { \
+	VIDC_REG_OUT("\n(0x%x:"#hwiosym"=0x%x)", \
+	HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, val); \
+	mb(); \
+	HWIO_OUT(hwiosym, val); \
+} while (0)
+#define VIDC_HWIO_OUTI(hwiosym, index, val) \
+do { \
+	VIDC_REG_OUT("\n(0x%x:"#hwiosym"(%d)=0x%x)", \
+	HWIO_##hwiosym##_ADDR(index) - VIDC_BASE_PTR, index, val); \
+	mb(); \
+	HWIO_OUTI(hwiosym, index, val); \
+} while (0)
+#define VIDC_HWIO_OUTF(hwiosym, field, val) \
+do { \
+	VIDC_REG_OUT("\n(0x%x:"#hwiosym":0x%x:=0x%x)" , \
+	HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, \
+	HWIO_##hwiosym##_##field##_BMSK, val) \
+	mb(); \
+	HWIO_OUTF(hwiosym, field, val); \
+} while (0)
+#define VIDC_OUT_DWORD(addr, val) \
+do { \
+	VIDC_REG_OUT("\n(0x%x:"#addr"=0x%x)", \
+	addr - VIDC_BASE_PTR, val); \
+	mb(); \
+	out_dword(addr, val); \
+} while (0)
+#define VIDC_HWIO_IN(hwiosym, pval) \
+do { \
+	mb(); \
+	*pval = (u32) HWIO_IN(hwiosym); \
+	VIDC_REG_IN("\n(0x%x:"#hwiosym"=0x%x)", \
+	HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, *pval);\
+} while (0)
+#define VIDC_HWIO_INI(hwiosym, index, pval) \
+do { \
+	mb(); \
+	*pval = (u32) HWIO_INI(hwiosym, index); \
+	VIDC_REG_IN("(0x%x:"#hwiosym"(%d)==0x%x)", \
+	HWIO_##hwiosym##_ADDR(index) - VIDC_BASE_PTR, index, *pval); \
+} while (0)
+#define VIDC_HWIO_INF(hwiosym, mask, pval) \
+do { \
+	mb(); \
+	*pval = HWIO_INF(hwiosym, mask); \
+	VIDC_REG_IN("\n(0x%x:"#hwiosym"=0x%x)", \
+	HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, *pval); \
+} while (0)
+#endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h
new file mode 100644
index 0000000..819cd6c
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h
@@ -0,0 +1,4544 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VIDC_HWIO_REG_H_
+#define _VIDC_HWIO_REG_H_
+
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <asm/system.h>
+#include "vidc.h"
+
+extern u8 *VIDC_BASE_PTR;
+
+#define VIDC_BASE  VIDC_BASE_PTR
+
+#define VIDC_BLACKBIRD_REG_BASE  (VIDC_BASE + 0x00000000)
+#define VIDC_BLACKBIRD_REG_BASE_PHYS  0x04400000
+
+#define HWIO_REG_557899_ADDR  (VIDC_BLACKBIRD_REG_BASE + 00000000)
+#define HWIO_REG_557899_PHYS  (VIDC_BLACKBIRD_REG_BASE_PHYS + 00000000)
+#define HWIO_REG_557899_RMSK  0x3ff
+#define HWIO_REG_557899_SHFT  0
+#define HWIO_REG_557899_IN  in_dword_masked(HWIO_REG_557899_ADDR,\
+	HWIO_REG_557899_RMSK)
+#define HWIO_REG_557899_INM(m)  in_dword_masked(HWIO_REG_557899_ADDR, m)
+#define HWIO_REG_557899_OUT(v)  out_dword(HWIO_REG_557899_ADDR, v)
+#define HWIO_REG_557899_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_557899_ADDR, m, v, HWIO_REG_557899_IN);
+#define HWIO_REG_557899_RSTN_RG_MPEG2_BMSK     0x200
+#define HWIO_REG_557899_RSTN_RG_MPEG2_SHFT     0x9
+#define HWIO_REG_557899_RSTN_RG_MPEG4_BMSK     0x100
+#define HWIO_REG_557899_RSTN_RG_MPEG4_SHFT     0x8
+#define HWIO_REG_557899_RSTN_RG_VC1_BMSK       0x80
+#define HWIO_REG_557899_RSTN_RG_VC1_SHFT       0x7
+#define HWIO_REG_557899_RSTN_RG_H264_BMSK      0x40
+#define HWIO_REG_557899_RSTN_RG_H264_SHFT      0x6
+#define HWIO_REG_557899_RSTN_RG_COMMON_BMSK    0x20
+#define HWIO_REG_557899_RSTN_RG_COMMON_SHFT    0x5
+#define HWIO_REG_557899_RSTN_DMX_BMSK          0x10
+#define HWIO_REG_557899_RSTN_DMX_SHFT          0x4
+#define HWIO_REG_557899_RSTN_VI_BMSK           0x8
+#define HWIO_REG_557899_RSTN_VI_SHFT           0x3
+#define HWIO_REG_557899_RSTN_VIDCCORE_BMSK     0x4
+#define HWIO_REG_557899_RSTN_VIDCCORE_SHFT     0x2
+#define HWIO_REG_557899_RSTN_MC_BMSK           0x2
+#define HWIO_REG_557899_RSTN_MC_SHFT           0x1
+#define HWIO_REG_557899_RSTN_RISC_BMSK         0x1
+#define HWIO_REG_557899_RSTN_RISC_SHFT         0
+
+#define HWIO_REG_575377_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000008)
+#define HWIO_REG_575377_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000008)
+#define HWIO_REG_575377_RMSK 0x1
+#define HWIO_REG_575377_SHFT 0
+#define HWIO_REG_575377_IN  in_dword_masked(\
+	HWIO_REG_575377_ADDR, HWIO_REG_575377_RMSK)
+#define HWIO_REG_575377_INM(m) \
+	in_dword_masked(HWIO_REG_575377_ADDR, m)
+#define HWIO_REG_575377_OUT(v) \
+	out_dword(HWIO_REG_575377_ADDR, v)
+#define HWIO_REG_575377_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_575377_ADDR, m, v, HWIO_REG_575377_IN);
+#define HWIO_REG_575377_INTERRUPT_BMSK  0x1
+#define HWIO_REG_575377_INTERRUPT_SHFT  0
+
+#define HWIO_REG_611794_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000030)
+#define HWIO_REG_611794_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000030)
+#define HWIO_REG_611794_RMSK  0xffffffff
+#define HWIO_REG_611794_SHFT  0
+#define HWIO_REG_611794_IN  in_dword_masked(\
+	HWIO_REG_611794_ADDR, HWIO_REG_611794_RMSK)
+#define HWIO_REG_611794_INM(m) \
+	in_dword_masked(HWIO_REG_611794_ADDR, m)
+#define HWIO_REG_611794_OUT(v) \
+	out_dword(HWIO_REG_611794_ADDR, v)
+#define HWIO_REG_611794_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_611794_ADDR, m, v,\
+	HWIO_REG_611794_IN);
+#define HWIO_REG_611794_HOST2RISC_COMMAND_BMSK 0xffffffff
+#define HWIO_REG_611794_HOST2RISC_COMMAND_SHFT 0
+
+#define HWIO_REG_356340_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000034)
+#define HWIO_REG_356340_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000034)
+#define HWIO_REG_356340_RMSK  0xffffffff
+#define HWIO_REG_356340_SHFT  0
+#define HWIO_REG_356340_IN  in_dword_masked(\
+	HWIO_REG_356340_ADDR, HWIO_REG_356340_RMSK)
+#define HWIO_REG_356340_INM(m) \
+	in_dword_masked(HWIO_REG_356340_ADDR, m)
+#define HWIO_REG_356340_OUT(v) \
+	out_dword(HWIO_REG_356340_ADDR, v)
+#define HWIO_REG_356340_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_356340_ADDR, m, v, HWIO_REG_356340_IN);
+#define HWIO_REG_356340_HOST2RISC_ARG1_BMSK  0xffffffff
+#define HWIO_REG_356340_HOST2RISC_ARG1_SHFT  0
+
+#define HWIO_REG_899023_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000038)
+#define HWIO_REG_899023_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000038)
+#define HWIO_REG_899023_RMSK 0xffffffff
+#define HWIO_REG_899023_SHFT 0
+#define HWIO_REG_899023_IN  in_dword_masked(\
+	HWIO_REG_899023_ADDR, HWIO_REG_899023_RMSK)
+#define HWIO_REG_899023_INM(m) \
+	in_dword_masked(HWIO_REG_899023_ADDR, m)
+#define HWIO_REG_899023_OUT(v) \
+	out_dword(HWIO_REG_899023_ADDR, v)
+#define HWIO_REG_899023_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_899023_ADDR, m, v, HWIO_REG_899023_IN);
+#define HWIO_REG_899023_HOST2RISC_ARG2_BMSK  0xffffffff
+#define HWIO_REG_899023_HOST2RISC_ARG2_SHFT  0
+
+#define HWIO_REG_987762_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000003c)
+#define HWIO_REG_987762_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000003c)
+#define HWIO_REG_987762_RMSK  0xffffffff
+#define HWIO_REG_987762_SHFT  0
+#define HWIO_REG_987762_IN  in_dword_masked(\
+	HWIO_REG_987762_ADDR, HWIO_REG_987762_RMSK)
+#define HWIO_REG_987762_INM(m) \
+	in_dword_masked(HWIO_REG_987762_ADDR, m)
+#define HWIO_REG_987762_OUT(v) \
+	out_dword(HWIO_REG_987762_ADDR, v)
+#define HWIO_REG_987762_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_987762_ADDR, m, v, HWIO_REG_987762_IN);
+#define HWIO_REG_987762_HOST2RISC_ARG3_BMSK  0xffffffff
+#define HWIO_REG_987762_HOST2RISC_ARG3_SHFT  0
+
+#define HWIO_REG_544000_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000040)
+#define HWIO_REG_544000_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000040)
+#define HWIO_REG_544000_RMSK  0xffffffff
+#define HWIO_REG_544000_SHFT  0
+#define HWIO_REG_544000_IN  in_dword_masked(\
+	HWIO_REG_544000_ADDR, HWIO_REG_544000_RMSK)
+#define HWIO_REG_544000_INM(m)  \
+	in_dword_masked(HWIO_REG_544000_ADDR, m)
+#define HWIO_REG_544000_OUT(v)  \
+	out_dword(HWIO_REG_544000_ADDR, v)
+#define HWIO_REG_544000_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_544000_ADDR, m, v, HWIO_REG_544000_IN);
+#define HWIO_REG_544000_HOST2RISC_ARG4_BMSK  0xffffffff
+#define HWIO_REG_544000_HOST2RISC_ARG4_SHFT  0
+
+#define HWIO_REG_695082_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000044)
+#define HWIO_REG_695082_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000044)
+#define HWIO_REG_695082_RMSK  0xffffffff
+#define HWIO_REG_695082_SHFT  0
+#define HWIO_REG_695082_IN  in_dword_masked(\
+	HWIO_REG_695082_ADDR, HWIO_REG_695082_RMSK)
+#define HWIO_REG_695082_INM(m) \
+	in_dword_masked(HWIO_REG_695082_ADDR, m)
+#define HWIO_REG_695082_OUT(v) \
+	out_dword(HWIO_REG_695082_ADDR, v)
+#define HWIO_REG_695082_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_695082_ADDR, m, v, HWIO_REG_695082_IN);
+#define HWIO_REG_695082_RISC2HOST_COMMAND_BMSK  0xffffffff
+#define HWIO_REG_695082_RISC2HOST_COMMAND_SHFT  0
+
+#define HWIO_REG_156596_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000048)
+#define HWIO_REG_156596_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000048)
+#define HWIO_REG_156596_RMSK  0xffffffff
+#define HWIO_REG_156596_SHFT  0
+#define HWIO_REG_156596_IN  in_dword_masked(\
+	HWIO_REG_156596_ADDR, HWIO_REG_156596_RMSK)
+#define HWIO_REG_156596_INM(m) \
+	in_dword_masked(HWIO_REG_156596_ADDR, m)
+#define HWIO_REG_156596_OUT(v) \
+	out_dword(HWIO_REG_156596_ADDR, v)
+#define HWIO_REG_156596_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_156596_ADDR, m, v, HWIO_REG_156596_IN);
+#define HWIO_REG_156596_REG_156596_BMSK  0xffffffff
+#define HWIO_REG_156596_REG_156596_SHFT  0
+
+#define HWIO_REG_222292_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000004c)
+#define HWIO_REG_222292_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000004c)
+#define HWIO_REG_222292_RMSK  0xffffffff
+#define HWIO_REG_222292_SHFT  0
+#define HWIO_REG_222292_IN  in_dword_masked(\
+	HWIO_REG_222292_ADDR, HWIO_REG_222292_RMSK)
+#define HWIO_REG_222292_INM(m) \
+	in_dword_masked(HWIO_REG_222292_ADDR, m)
+#define HWIO_REG_222292_OUT(v) \
+	out_dword(HWIO_REG_222292_ADDR, v)
+#define HWIO_REG_222292_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_222292_ADDR, m, v, HWIO_REG_222292_IN);
+#define HWIO_REG_222292_REG_222292_BMSK  0xffffffff
+#define HWIO_REG_222292_REG_222292_SHFT  0
+
+#define HWIO_REG_790962_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000050)
+#define HWIO_REG_790962_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000050)
+#define HWIO_REG_790962_RMSK  0xffffffff
+#define HWIO_REG_790962_SHFT  0
+#define HWIO_REG_790962_IN  in_dword_masked(\
+	HWIO_REG_790962_ADDR, HWIO_REG_790962_RMSK)
+#define HWIO_REG_790962_INM(m) \
+	in_dword_masked(HWIO_REG_790962_ADDR, m)
+#define HWIO_REG_790962_OUT(v) \
+	out_dword(HWIO_REG_790962_ADDR, v)
+#define HWIO_REG_790962_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_790962_ADDR, m, v, HWIO_REG_790962_IN);
+#define HWIO_REG_790962_REG_790962_BMSK  0xffffffff
+#define HWIO_REG_790962_REG_790962_SHFT  0
+
+#define HWIO_REG_679882_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000054)
+#define HWIO_REG_679882_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000054)
+#define HWIO_REG_679882_RMSK  0xffffffff
+#define HWIO_REG_679882_SHFT  0
+#define HWIO_REG_679882_IN  in_dword_masked(\
+	HWIO_REG_679882_ADDR, HWIO_REG_679882_RMSK)
+#define HWIO_REG_679882_INM(m) \
+	in_dword_masked(HWIO_REG_679882_ADDR, m)
+#define HWIO_REG_679882_OUT(v) \
+	out_dword(HWIO_REG_679882_ADDR, v)
+#define HWIO_REG_679882_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_679882_ADDR, m, v, HWIO_REG_679882_IN);
+#define HWIO_REG_679882_REG_679882_BMSK  0xffffffff
+#define HWIO_REG_679882_REG_679882_SHFT  0
+
+#define HWIO_REG_653206_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000058)
+#define HWIO_REG_653206_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000058)
+#define HWIO_REG_653206_RMSK  0xffffff
+#define HWIO_REG_653206_SHFT  0
+#define HWIO_REG_653206_IN  in_dword_masked(\
+	HWIO_REG_653206_ADDR, HWIO_REG_653206_RMSK)
+#define HWIO_REG_653206_INM(m) \
+	in_dword_masked(HWIO_REG_653206_ADDR, m)
+#define HWIO_REG_653206_YEAR_BMSK   0xff0000
+#define HWIO_REG_653206_YEAR_SHFT   0x10
+#define HWIO_REG_653206_MONTH_BMSK  0xff00
+#define HWIO_REG_653206_MONTH_SHFT  0x8
+#define HWIO_REG_653206_DAY_BMSK    0xff
+#define HWIO_REG_653206_DAY_SHFT    0
+
+#define HWIO_REG_805993_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000064)
+#define HWIO_REG_805993_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000064)
+#define HWIO_REG_805993_RMSK  0xffffffff
+#define HWIO_REG_805993_SHFT  0
+#define HWIO_REG_805993_IN  in_dword_masked(\
+	HWIO_REG_805993_ADDR, HWIO_REG_805993_RMSK)
+#define HWIO_REG_805993_INM(m) \
+	in_dword_masked(HWIO_REG_805993_ADDR, m)
+#define HWIO_REG_805993_INTERMEDIATE_STAGE_COUNTER_BMSK  0xffffffff
+#define HWIO_REG_805993_INTERMEDIATE_STAGE_COUNTER_SHFT  0
+
+#define HWIO_REG_493355_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000068)
+#define HWIO_REG_493355_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000068)
+#define HWIO_REG_493355_RMSK  0xffffffff
+#define HWIO_REG_493355_SHFT  0
+#define HWIO_REG_493355_IN  in_dword_masked(\
+	HWIO_REG_493355_ADDR, HWIO_REG_493355_RMSK)
+#define HWIO_REG_493355_INM(m) \
+	in_dword_masked(HWIO_REG_493355_ADDR, m)
+#define HWIO_REG_493355_EXCEPTION_STATUS_BMSK  0xffffffff
+#define HWIO_REG_493355_EXCEPTION_STATUS_SHFT  0
+
+#define HWIO_REG_350619_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000080)
+#define HWIO_REG_350619_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000080)
+#define HWIO_REG_350619_RMSK  0x1
+#define HWIO_REG_350619_SHFT  0
+#define HWIO_REG_350619_IN  in_dword_masked(\
+	HWIO_REG_350619_ADDR, HWIO_REG_350619_RMSK)
+#define HWIO_REG_350619_INM(m) \
+	in_dword_masked(HWIO_REG_350619_ADDR, m)
+#define HWIO_REG_350619_FIRMWARE_STATUS_BMSK  0x1
+#define HWIO_REG_350619_FIRMWARE_STATUS_SHFT  0
+
+#define HWIO_REG_64440_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000508)
+#define HWIO_REG_64440_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000508)
+#define HWIO_REG_64440_RMSK  0xfffe0000
+#define HWIO_REG_64440_SHFT  0
+#define HWIO_REG_64440_IN  in_dword_masked(\
+	HWIO_REG_64440_ADDR, HWIO_REG_64440_RMSK)
+#define HWIO_REG_64440_INM(m) \
+	in_dword_masked(HWIO_REG_64440_ADDR, m)
+#define HWIO_REG_64440_OUT(v) \
+	out_dword(HWIO_REG_64440_ADDR, v)
+#define HWIO_REG_64440_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_64440_ADDR, m, v,\
+	HWIO_REG_64440_IN);
+#define HWIO_REG_64440_MC_DRAMBASE_ADDR_BMSK  0xfffe0000
+#define HWIO_REG_64440_MC_DRAMBASE_ADDR_SHFT  0x11
+
+#define HWIO_REG_675915_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000050c)
+#define HWIO_REG_675915_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000050c)
+#define HWIO_REG_675915_RMSK  0xfffe0000
+#define HWIO_REG_675915_SHFT  0
+#define HWIO_REG_675915_IN  in_dword_masked(\
+	HWIO_REG_675915_ADDR, HWIO_REG_675915_RMSK)
+#define HWIO_REG_675915_INM(m) \
+	in_dword_masked(HWIO_REG_675915_ADDR, m)
+#define HWIO_REG_675915_OUT(v) \
+	out_dword(HWIO_REG_675915_ADDR, v)
+#define HWIO_REG_675915_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_675915_ADDR, m, v,\
+	HWIO_REG_675915_IN);
+#define HWIO_REG_675915_MC_DRAMBASE_ADDR_BMSK  0xfffe0000
+#define HWIO_REG_675915_MC_DRAMBASE_ADDR_SHFT  0x11
+
+#define HWIO_REG_399911_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000510)
+#define HWIO_REG_399911_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000510)
+#define HWIO_REG_399911_RMSK  0x3
+#define HWIO_REG_399911_SHFT  0
+#define HWIO_REG_399911_IN  in_dword_masked(\
+	HWIO_REG_399911_ADDR, HWIO_REG_399911_RMSK)
+#define HWIO_REG_399911_INM(m)  in_dword_masked(HWIO_REG_399911_ADDR, m)
+#define HWIO_REG_399911_MC_BUSY_B_BMSK  0x2
+#define HWIO_REG_399911_MC_BUSY_B_SHFT  0x1
+#define HWIO_REG_399911_MC_BUSY_A_BMSK  0x1
+#define HWIO_REG_399911_MC_BUSY_A_SHFT  0
+
+#define HWIO_REG_515200_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000600)
+#define HWIO_REG_515200_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000600)
+#define HWIO_REG_515200_RMSK  0x1ffff
+#define HWIO_REG_515200_SHFT  0
+#define HWIO_REG_515200_IN  in_dword_masked(\
+	HWIO_REG_515200_ADDR, HWIO_REG_515200_RMSK)
+#define HWIO_REG_515200_INM(m) \
+	in_dword_masked(HWIO_REG_515200_ADDR, m)
+#define HWIO_REG_515200_OUT(v) \
+	out_dword(HWIO_REG_515200_ADDR, v)
+#define HWIO_REG_515200_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_515200_ADDR, m, v,\
+	HWIO_REG_515200_IN);
+#define HWIO_REG_515200_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_515200_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_29510_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000604)
+#define HWIO_REG_29510_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000604)
+#define HWIO_REG_29510_RMSK  0x1ffff
+#define HWIO_REG_29510_SHFT  0
+#define HWIO_REG_29510_IN  in_dword_masked(\
+	HWIO_REG_29510_ADDR, HWIO_REG_29510_RMSK)
+#define HWIO_REG_29510_INM(m) \
+	in_dword_masked(HWIO_REG_29510_ADDR, m)
+#define HWIO_REG_29510_OUT(v) \
+	out_dword(HWIO_REG_29510_ADDR, v)
+#define HWIO_REG_29510_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_29510_ADDR, m, v,\
+	HWIO_REG_29510_IN);
+#define HWIO_REG_29510_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_29510_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_256132_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000608)
+#define HWIO_REG_256132_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000608)
+#define HWIO_REG_256132_RMSK  0x1ffff
+#define HWIO_REG_256132_SHFT  0
+#define HWIO_REG_256132_IN  in_dword_masked(\
+	HWIO_REG_256132_ADDR, HWIO_REG_256132_RMSK)
+#define HWIO_REG_256132_INM(m) \
+	in_dword_masked(HWIO_REG_256132_ADDR, m)
+#define HWIO_REG_256132_OUT(v) \
+	out_dword(HWIO_REG_256132_ADDR, v)
+#define HWIO_REG_256132_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_256132_ADDR, m, v,\
+	HWIO_REG_256132_IN);
+#define HWIO_REG_256132_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_256132_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_885152_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000060c)
+#define HWIO_REG_885152_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000060c)
+#define HWIO_REG_885152_RMSK  0x1ffff
+#define HWIO_REG_885152_SHFT  0
+#define HWIO_REG_885152_IN  in_dword_masked(\
+	HWIO_REG_885152_ADDR, HWIO_REG_885152_RMSK)
+#define HWIO_REG_885152_INM(m) \
+	in_dword_masked(HWIO_REG_885152_ADDR, m)
+#define HWIO_REG_885152_OUT(v) \
+	out_dword(HWIO_REG_885152_ADDR, v)
+#define HWIO_REG_885152_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_885152_ADDR, m, v,\
+	HWIO_REG_885152_IN);
+#define HWIO_REG_885152_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_885152_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_69832_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000610)
+#define HWIO_REG_69832_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000610)
+#define HWIO_REG_69832_RMSK 0x1ffff
+#define HWIO_REG_69832_SHFT 0
+#define HWIO_REG_69832_IN  in_dword_masked(\
+	HWIO_REG_69832_ADDR, HWIO_REG_69832_RMSK)
+#define HWIO_REG_69832_INM(m) \
+	in_dword_masked(HWIO_REG_69832_ADDR, m)
+#define HWIO_REG_69832_OUT(v) \
+	out_dword(HWIO_REG_69832_ADDR, v)
+#define HWIO_REG_69832_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_69832_ADDR, m, v,\
+	HWIO_REG_69832_IN);
+#define HWIO_REG_69832_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_69832_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_686205_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000614)
+#define HWIO_REG_686205_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000614)
+#define HWIO_REG_686205_RMSK  0x1ffff
+#define HWIO_REG_686205_SHFT  0
+#define HWIO_REG_686205_IN  in_dword_masked(\
+	HWIO_REG_686205_ADDR, HWIO_REG_686205_RMSK)
+#define HWIO_REG_686205_INM(m) \
+	in_dword_masked(HWIO_REG_686205_ADDR, m)
+#define HWIO_REG_686205_OUT(v) \
+	out_dword(HWIO_REG_686205_ADDR, v)
+#define HWIO_REG_686205_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_686205_ADDR, m, v,\
+	HWIO_REG_686205_IN);
+#define HWIO_REG_686205_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_686205_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_728036_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000618)
+#define HWIO_REG_728036_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000618)
+#define HWIO_REG_728036_RMSK 0x1ffff
+#define HWIO_REG_728036_SHFT 0
+#define HWIO_REG_728036_IN  in_dword_masked(\
+	HWIO_REG_728036_ADDR, HWIO_REG_728036_RMSK)
+#define HWIO_REG_728036_INM(m) \
+	in_dword_masked(HWIO_REG_728036_ADDR, m)
+#define HWIO_REG_728036_OUT(v) \
+	out_dword(HWIO_REG_728036_ADDR, v)
+#define HWIO_REG_728036_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_728036_ADDR, m, v,\
+	HWIO_REG_728036_IN);
+#define HWIO_REG_728036_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_728036_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_294579_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000061c)
+#define HWIO_REG_294579_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000061c)
+#define HWIO_REG_294579_RMSK  0x1ffff
+#define HWIO_REG_294579_SHFT  0
+#define HWIO_REG_294579_IN  in_dword_masked(\
+	HWIO_REG_294579_ADDR, HWIO_REG_294579_RMSK)
+#define HWIO_REG_294579_INM(m) \
+	in_dword_masked(HWIO_REG_294579_ADDR, m)
+#define HWIO_REG_294579_OUT(v) \
+	out_dword(HWIO_REG_294579_ADDR, v)
+#define HWIO_REG_294579_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_294579_ADDR, m, v,\
+	HWIO_REG_294579_IN);
+#define HWIO_REG_294579_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_294579_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_61427_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000620)
+#define HWIO_REG_61427_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000620)
+#define HWIO_REG_61427_RMSK  0x1ffff
+#define HWIO_REG_61427_SHFT  0
+#define HWIO_REG_61427_IN  in_dword_masked(\
+	HWIO_REG_61427_ADDR, HWIO_REG_61427_RMSK)
+#define HWIO_REG_61427_INM(m) \
+	in_dword_masked(HWIO_REG_61427_ADDR, m)
+#define HWIO_REG_61427_OUT(v) \
+	out_dword(HWIO_REG_61427_ADDR, v)
+#define HWIO_REG_61427_OUTM(m , v)  out_dword_masked_ns(\
+	HWIO_REG_61427_ADDR, m, v,\
+	HWIO_REG_61427_IN);
+#define HWIO_REG_61427_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_61427_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_578196_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000624)
+#define HWIO_REG_578196_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000624)
+#define HWIO_REG_578196_RMSK  0x1ffff
+#define HWIO_REG_578196_SHFT  0
+#define HWIO_REG_578196_IN  in_dword_masked(\
+	HWIO_REG_578196_ADDR, HWIO_REG_578196_RMSK)
+#define HWIO_REG_578196_INM(m) \
+	in_dword_masked(HWIO_REG_578196_ADDR, m)
+#define HWIO_REG_578196_OUT(v) \
+	out_dword(HWIO_REG_578196_ADDR, v)
+#define HWIO_REG_578196_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_578196_ADDR, m, v,\
+	HWIO_REG_578196_IN);
+#define HWIO_REG_578196_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_578196_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_408588_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000628)
+#define HWIO_REG_408588_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000628)
+#define HWIO_REG_408588_RMSK  0x1ffff
+#define HWIO_REG_408588_SHFT  0
+#define HWIO_REG_408588_IN  in_dword_masked(\
+	HWIO_REG_408588_ADDR, HWIO_REG_408588_RMSK)
+#define HWIO_REG_408588_INM(m) \
+	in_dword_masked(HWIO_REG_408588_ADDR, m)
+#define HWIO_REG_408588_OUT(v) \
+	out_dword(HWIO_REG_408588_ADDR, v)
+#define HWIO_REG_408588_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_408588_ADDR, m, v,\
+	HWIO_REG_408588_IN);
+#define HWIO_REG_408588_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_408588_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_55617_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000062c)
+#define HWIO_REG_55617_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000062c)
+#define HWIO_REG_55617_RMSK  0x1ffff
+#define HWIO_REG_55617_SHFT  0
+#define HWIO_REG_55617_IN  in_dword_masked(\
+	HWIO_REG_55617_ADDR, HWIO_REG_55617_RMSK)
+#define HWIO_REG_55617_INM(m) \
+	in_dword_masked(HWIO_REG_55617_ADDR, m)
+#define HWIO_REG_55617_OUT(v) \
+	out_dword(HWIO_REG_55617_ADDR, v)
+#define HWIO_REG_55617_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_55617_ADDR, m, v,\
+	HWIO_REG_55617_IN);
+#define HWIO_REG_55617_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_55617_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_555239_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000630)
+#define HWIO_REG_555239_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000630)
+#define HWIO_REG_555239_RMSK  0x1ffff
+#define HWIO_REG_555239_SHFT  0
+#define HWIO_REG_555239_IN  in_dword_masked(\
+	HWIO_REG_555239_ADDR, HWIO_REG_555239_RMSK)
+#define HWIO_REG_555239_INM(m) \
+	in_dword_masked(HWIO_REG_555239_ADDR, m)
+#define HWIO_REG_555239_OUT(v) \
+	out_dword(HWIO_REG_555239_ADDR, v)
+#define HWIO_REG_555239_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_555239_ADDR, m, v,\
+	HWIO_REG_555239_IN);
+#define HWIO_REG_555239_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_555239_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_515333_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000634)
+#define HWIO_REG_515333_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000634)
+#define HWIO_REG_515333_RMSK  0x1ffff
+#define HWIO_REG_515333_SHFT  0
+#define HWIO_REG_515333_IN  in_dword_masked(\
+	HWIO_REG_515333_ADDR, HWIO_REG_515333_RMSK)
+#define HWIO_REG_515333_INM(m) \
+	in_dword_masked(HWIO_REG_515333_ADDR, m)
+#define HWIO_REG_515333_OUT(v) \
+	out_dword(HWIO_REG_515333_ADDR, v)
+#define HWIO_REG_515333_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_515333_ADDR, m, v,\
+	HWIO_REG_515333_IN);
+#define HWIO_REG_515333_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_515333_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_951675_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE  + 0x00000638)
+#define HWIO_REG_951675_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000638)
+#define HWIO_REG_951675_RMSK  0x1ffff
+#define HWIO_REG_951675_SHFT  0
+#define HWIO_REG_951675_IN  in_dword_masked(\
+	HWIO_REG_951675_ADDR, HWIO_REG_951675_RMSK)
+#define HWIO_REG_951675_INM(m) \
+	in_dword_masked(HWIO_REG_951675_ADDR, m)
+#define HWIO_REG_951675_OUT(v) \
+	out_dword(HWIO_REG_951675_ADDR, v)
+#define HWIO_REG_951675_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_951675_ADDR, m, v,\
+	HWIO_REG_951675_IN);
+#define HWIO_REG_951675_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_951675_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_500775_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE  + 0x0000063c)
+#define HWIO_REG_500775_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000063c)
+#define HWIO_REG_500775_RMSK  0x1ffff
+#define HWIO_REG_500775_SHFT  0
+#define HWIO_REG_500775_IN  in_dword_masked(\
+	HWIO_REG_500775_ADDR, HWIO_REG_500775_RMSK)
+#define HWIO_REG_500775_INM(m) \
+	in_dword_masked(HWIO_REG_500775_ADDR, m)
+#define HWIO_REG_500775_OUT(v) \
+	out_dword(HWIO_REG_500775_ADDR, v)
+#define HWIO_REG_500775_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_500775_ADDR, m, v,\
+	HWIO_REG_500775_IN);
+#define HWIO_REG_500775_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_500775_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_649786_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000640)
+#define HWIO_REG_649786_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000640)
+#define HWIO_REG_649786_RMSK  0x1ffff
+#define HWIO_REG_649786_SHFT  0
+#define HWIO_REG_649786_IN  in_dword_masked(\
+	HWIO_REG_649786_ADDR, HWIO_REG_649786_RMSK)
+#define HWIO_REG_649786_INM(m) \
+	in_dword_masked(HWIO_REG_649786_ADDR, m)
+#define HWIO_REG_649786_OUT(v) \
+	out_dword(HWIO_REG_649786_ADDR, v)
+#define HWIO_REG_649786_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_649786_ADDR, m, v,\
+	HWIO_REG_649786_IN);
+#define HWIO_REG_649786_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_649786_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_233366_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000644)
+#define HWIO_REG_233366_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000644)
+#define HWIO_REG_233366_RMSK  0x1ffff
+#define HWIO_REG_233366_SHFT  0
+#define HWIO_REG_233366_IN  in_dword_masked(\
+	HWIO_REG_233366_ADDR, HWIO_REG_233366_RMSK)
+#define HWIO_REG_233366_INM(m) \
+	in_dword_masked(HWIO_REG_233366_ADDR, m)
+#define HWIO_REG_233366_OUT(v) \
+	out_dword(HWIO_REG_233366_ADDR, v)
+#define HWIO_REG_233366_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_233366_ADDR, m, v,\
+	HWIO_REG_233366_IN);
+#define HWIO_REG_233366_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_233366_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_366750_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000648)
+#define HWIO_REG_366750_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000648)
+#define HWIO_REG_366750_RMSK  0x1ffff
+#define HWIO_REG_366750_SHFT  0
+#define HWIO_REG_366750_IN  in_dword_masked(\
+	HWIO_REG_366750_ADDR, HWIO_REG_366750_RMSK)
+#define HWIO_REG_366750_INM(m) \
+	in_dword_masked(HWIO_REG_366750_ADDR, m)
+#define HWIO_REG_366750_OUT(v) \
+	out_dword(HWIO_REG_366750_ADDR, v)
+#define HWIO_REG_366750_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_366750_ADDR, m, v,\
+	HWIO_REG_366750_IN);
+#define HWIO_REG_366750_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_366750_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_616292_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000064c)
+#define HWIO_REG_616292_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000064c)
+#define HWIO_REG_616292_RMSK  0x1ffff
+#define HWIO_REG_616292_SHFT  0
+#define HWIO_REG_616292_IN  in_dword_masked(\
+	HWIO_REG_616292_ADDR, HWIO_REG_616292_RMSK)
+#define HWIO_REG_616292_INM(m) \
+	in_dword_masked(HWIO_REG_616292_ADDR, m)
+#define HWIO_REG_616292_OUT(v) \
+	out_dword(HWIO_REG_616292_ADDR, v)
+#define HWIO_REG_616292_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_616292_ADDR, m, v,\
+	HWIO_REG_616292_IN);
+#define HWIO_REG_616292_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_616292_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_666754_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000650)
+#define HWIO_REG_666754_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000650)
+#define HWIO_REG_666754_RMSK  0x1ffff
+#define HWIO_REG_666754_SHFT  0
+#define HWIO_REG_666754_IN  in_dword_masked(\
+	HWIO_REG_666754_ADDR, HWIO_REG_666754_RMSK)
+#define HWIO_REG_666754_INM(m) \
+	in_dword_masked(HWIO_REG_666754_ADDR, m)
+#define HWIO_REG_666754_OUT(v) \
+	out_dword(HWIO_REG_666754_ADDR, v)
+#define HWIO_REG_666754_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_666754_ADDR, m, v,\
+	HWIO_REG_666754_IN);
+#define HWIO_REG_666754_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_666754_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_650155_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000654)
+#define HWIO_REG_650155_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000654)
+#define HWIO_REG_650155_RMSK  0x1ffff
+#define HWIO_REG_650155_SHFT  0
+#define HWIO_REG_650155_IN  in_dword_masked(\
+	HWIO_REG_650155_ADDR, HWIO_REG_650155_RMSK)
+#define HWIO_REG_650155_INM(m) \
+	in_dword_masked(HWIO_REG_650155_ADDR, m)
+#define HWIO_REG_650155_OUT(v) \
+	out_dword(HWIO_REG_650155_ADDR, v)
+#define HWIO_REG_650155_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_650155_ADDR, m, v,\
+	HWIO_REG_650155_IN);
+#define HWIO_REG_650155_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_650155_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_248198_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000658)
+#define HWIO_REG_248198_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000658)
+#define HWIO_REG_248198_RMSK  0x1ffff
+#define HWIO_REG_248198_SHFT  0
+#define HWIO_REG_248198_IN  in_dword_masked(\
+	HWIO_REG_248198_ADDR, HWIO_REG_248198_RMSK)
+#define HWIO_REG_248198_INM(m) \
+	in_dword_masked(HWIO_REG_248198_ADDR, m)
+#define HWIO_REG_248198_OUT(v) \
+	out_dword(HWIO_REG_248198_ADDR, v)
+#define HWIO_REG_248198_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_248198_ADDR, m, v,\
+	HWIO_REG_248198_IN);
+#define HWIO_REG_248198_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_248198_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_389428_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000065c)
+#define HWIO_REG_389428_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000065c)
+#define HWIO_REG_389428_RMSK  0x1ffff
+#define HWIO_REG_389428_SHFT  0
+#define HWIO_REG_389428_IN  in_dword_masked(\
+	HWIO_REG_389428_ADDR, HWIO_REG_389428_RMSK)
+#define HWIO_REG_389428_INM(m) \
+	in_dword_masked(HWIO_REG_389428_ADDR, m)
+#define HWIO_REG_389428_OUT(v) \
+	out_dword(HWIO_REG_389428_ADDR, v)
+#define HWIO_REG_389428_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_389428_ADDR, m, v,\
+	HWIO_REG_389428_IN);
+#define HWIO_REG_389428_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_389428_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_504308_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000660)
+#define HWIO_REG_504308_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000660)
+#define HWIO_REG_504308_RMSK  0x1ffff
+#define HWIO_REG_504308_SHFT  0
+#define HWIO_REG_504308_IN  in_dword_masked(\
+	HWIO_REG_504308_ADDR, HWIO_REG_504308_RMSK)
+#define HWIO_REG_504308_INM(m) \
+	in_dword_masked(HWIO_REG_504308_ADDR, m)
+#define HWIO_REG_504308_OUT(v) \
+	out_dword(HWIO_REG_504308_ADDR, v)
+#define HWIO_REG_504308_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_504308_ADDR, m, v,\
+	HWIO_REG_504308_IN);
+#define HWIO_REG_504308_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_504308_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_280814_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000664)
+#define HWIO_REG_280814_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000664)
+#define HWIO_REG_280814_RMSK  0x1ffff
+#define HWIO_REG_280814_SHFT  0
+#define HWIO_REG_280814_IN  in_dword_masked(\
+	HWIO_REG_280814_ADDR, HWIO_REG_280814_RMSK)
+#define HWIO_REG_280814_INM(m) \
+	in_dword_masked(HWIO_REG_280814_ADDR, m)
+#define HWIO_REG_280814_OUT(v) \
+	out_dword(HWIO_REG_280814_ADDR, v)
+#define HWIO_REG_280814_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_280814_ADDR, m, v,\
+	HWIO_REG_280814_IN);
+#define HWIO_REG_280814_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_280814_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_785484_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000668)
+#define HWIO_REG_785484_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000668)
+#define HWIO_REG_785484_RMSK  0x1ffff
+#define HWIO_REG_785484_SHFT  0
+#define HWIO_REG_785484_IN  in_dword_masked(\
+	HWIO_REG_785484_ADDR, HWIO_REG_785484_RMSK)
+#define HWIO_REG_785484_INM(m) \
+	in_dword_masked(HWIO_REG_785484_ADDR, m)
+#define HWIO_REG_785484_OUT(v) \
+		out_dword(HWIO_REG_785484_ADDR, v)
+#define HWIO_REG_785484_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_785484_ADDR, m, v,\
+	HWIO_REG_785484_IN);
+#define HWIO_REG_785484_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_785484_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_218455_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000066c)
+#define HWIO_REG_218455_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000066c)
+#define HWIO_REG_218455_RMSK  0x1ffff
+#define HWIO_REG_218455_SHFT  0
+#define HWIO_REG_218455_IN  in_dword_masked(\
+	HWIO_REG_218455_ADDR, HWIO_REG_218455_RMSK)
+#define HWIO_REG_218455_INM(m) \
+	in_dword_masked(HWIO_REG_218455_ADDR, m)
+#define HWIO_REG_218455_OUT(v) \
+	out_dword(HWIO_REG_218455_ADDR, v)
+#define HWIO_REG_218455_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_218455_ADDR, m, v,\
+	HWIO_REG_218455_IN);
+#define HWIO_REG_218455_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_218455_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_886591_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000670)
+#define HWIO_REG_886591_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000670)
+#define HWIO_REG_886591_RMSK  0x1ffff
+#define HWIO_REG_886591_SHFT  0
+#define HWIO_REG_886591_IN  in_dword_masked(\
+	HWIO_REG_886591_ADDR, HWIO_REG_886591_RMSK)
+#define HWIO_REG_886591_INM(m) \
+	in_dword_masked(HWIO_REG_886591_ADDR, m)
+#define HWIO_REG_886591_OUT(v) \
+	out_dword(HWIO_REG_886591_ADDR, v)
+#define HWIO_REG_886591_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_886591_ADDR, m, v,\
+	HWIO_REG_886591_IN);
+#define HWIO_REG_886591_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_886591_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_912449_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000674)
+#define HWIO_REG_912449_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000674)
+#define HWIO_REG_912449_RMSK  0x1ffff
+#define HWIO_REG_912449_SHFT  0
+#define HWIO_REG_912449_IN  in_dword_masked(\
+	HWIO_REG_912449_ADDR, HWIO_REG_912449_RMSK)
+#define HWIO_REG_912449_INM(m) \
+	in_dword_masked(HWIO_REG_912449_ADDR, m)
+#define HWIO_REG_912449_OUT(v) \
+	out_dword(HWIO_REG_912449_ADDR, v)
+#define HWIO_REG_912449_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_912449_ADDR, m, v,\
+	HWIO_REG_912449_IN);
+#define HWIO_REG_912449_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_912449_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_1065_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000678)
+#define HWIO_REG_1065_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000678)
+#define HWIO_REG_1065_RMSK  0x1ffff
+#define HWIO_REG_1065_SHFT  0
+#define HWIO_REG_1065_IN  in_dword_masked(\
+	HWIO_REG_1065_ADDR, HWIO_REG_1065_RMSK)
+#define HWIO_REG_1065_INM(m) \
+	in_dword_masked(HWIO_REG_1065_ADDR, m)
+#define HWIO_REG_1065_OUT(v) \
+	out_dword(HWIO_REG_1065_ADDR, v)
+#define HWIO_REG_1065_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_1065_ADDR, m, v,\
+	HWIO_REG_1065_IN);
+#define HWIO_REG_1065_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_1065_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_61838_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000067c)
+#define HWIO_REG_61838_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000067c)
+#define HWIO_REG_61838_RMSK  0x1ffff
+#define HWIO_REG_61838_SHFT  0
+#define HWIO_REG_61838_IN  in_dword_masked(\
+	HWIO_REG_61838_ADDR, HWIO_REG_61838_RMSK)
+#define HWIO_REG_61838_INM(m) \
+	in_dword_masked(HWIO_REG_61838_ADDR, m)
+#define HWIO_REG_61838_OUT(v) \
+	out_dword(HWIO_REG_61838_ADDR, v)
+#define HWIO_REG_61838_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_61838_ADDR, m, v,\
+	HWIO_REG_61838_IN);
+#define HWIO_REG_61838_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_61838_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_169838_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000680)
+#define HWIO_REG_169838_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000680)
+#define HWIO_REG_169838_RMSK  0x1ffff
+#define HWIO_REG_169838_SHFT  0
+#define HWIO_REG_169838_IN  in_dword_masked(\
+	HWIO_REG_169838_ADDR, HWIO_REG_169838_RMSK)
+#define HWIO_REG_169838_INM(m) \
+	in_dword_masked(HWIO_REG_169838_ADDR, m)
+#define HWIO_REG_169838_OUT(v) \
+	out_dword(HWIO_REG_169838_ADDR, v)
+#define HWIO_REG_169838_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_169838_ADDR, m, v,\
+	HWIO_REG_169838_IN);
+#define HWIO_REG_169838_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_169838_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_986147_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000684)
+#define HWIO_REG_986147_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000684)
+#define HWIO_REG_986147_RMSK  0x1ffff
+#define HWIO_REG_986147_SHFT  0
+#define HWIO_REG_986147_IN  in_dword_masked(\
+	HWIO_REG_986147_ADDR, HWIO_REG_986147_RMSK)
+#define HWIO_REG_986147_INM(m) \
+	in_dword_masked(HWIO_REG_986147_ADDR, m)
+#define HWIO_REG_986147_OUT(v)  \
+	out_dword(HWIO_REG_986147_ADDR, v)
+#define HWIO_REG_986147_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_986147_ADDR, m, v,\
+	HWIO_REG_986147_IN);
+#define HWIO_REG_986147_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_986147_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_678637_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000688)
+#define HWIO_REG_678637_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000688)
+#define HWIO_REG_678637_RMSK  0x1ffff
+#define HWIO_REG_678637_SHFT  0
+#define HWIO_REG_678637_IN  in_dword_masked(\
+	HWIO_REG_678637_ADDR, HWIO_REG_678637_RMSK)
+#define HWIO_REG_678637_INM(m) \
+	in_dword_masked(HWIO_REG_678637_ADDR, m)
+#define HWIO_REG_678637_OUT(v) \
+	out_dword(HWIO_REG_678637_ADDR, v)
+#define HWIO_REG_678637_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_678637_ADDR, m, v,\
+	HWIO_REG_678637_IN);
+#define HWIO_REG_678637_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_678637_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_931311_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000068c)
+#define HWIO_REG_931311_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000068c)
+#define HWIO_REG_931311_RMSK  0x1ffff
+#define HWIO_REG_931311_SHFT  0
+#define HWIO_REG_931311_IN  in_dword_masked(\
+	HWIO_REG_931311_ADDR, HWIO_REG_931311_RMSK)
+#define HWIO_REG_931311_INM(m) \
+	in_dword_masked(HWIO_REG_931311_ADDR, m)
+#define HWIO_REG_931311_OUT(v) \
+	out_dword(HWIO_REG_931311_ADDR, v)
+#define HWIO_REG_931311_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_931311_ADDR, m, v,\
+	HWIO_REG_931311_IN);
+#define HWIO_REG_931311_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_931311_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_16277_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000690)
+#define HWIO_REG_16277_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000690)
+#define HWIO_REG_16277_RMSK  0x1ffff
+#define HWIO_REG_16277_SHFT  0
+#define HWIO_REG_16277_IN  in_dword_masked(\
+	HWIO_REG_16277_ADDR, HWIO_REG_16277_RMSK)
+#define HWIO_REG_16277_INM(m) \
+	in_dword_masked(HWIO_REG_16277_ADDR, m)
+#define HWIO_REG_16277_OUT(v) \
+	out_dword(HWIO_REG_16277_ADDR, v)
+#define HWIO_REG_16277_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_16277_ADDR, m, v,\
+	HWIO_REG_16277_IN);
+#define HWIO_REG_16277_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_16277_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_654169_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE  + 0x00000694)
+#define HWIO_REG_654169_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000694)
+#define HWIO_REG_654169_RMSK  0x1ffff
+#define HWIO_REG_654169_SHFT  0
+#define HWIO_REG_654169_IN  in_dword_masked(\
+	HWIO_REG_654169_ADDR, HWIO_REG_654169_RMSK)
+#define HWIO_REG_654169_INM(m) \
+	in_dword_masked(HWIO_REG_654169_ADDR, m)
+#define HWIO_REG_654169_OUT(v) \
+	out_dword(HWIO_REG_654169_ADDR, v)
+#define HWIO_REG_654169_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_654169_ADDR, m, v,\
+	HWIO_REG_654169_IN);
+#define HWIO_REG_654169_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_654169_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_802794_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000698)
+#define HWIO_REG_802794_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000698)
+#define HWIO_REG_802794_RMSK  0x1ffff
+#define HWIO_REG_802794_SHFT  0
+#define HWIO_REG_802794_IN  in_dword_masked(\
+	HWIO_REG_802794_ADDR, HWIO_REG_802794_RMSK)
+#define HWIO_REG_802794_INM(m) \
+	in_dword_masked(HWIO_REG_802794_ADDR, m)
+#define HWIO_REG_802794_OUT(v) \
+	out_dword(HWIO_REG_802794_ADDR, v)
+#define HWIO_REG_802794_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_802794_ADDR, m, v,\
+	HWIO_REG_802794_IN);
+#define HWIO_REG_802794_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_802794_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_724376_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000069c)
+#define HWIO_REG_724376_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000069c)
+#define HWIO_REG_724376_RMSK  0x1ffff
+#define HWIO_REG_724376_SHFT  0
+#define HWIO_REG_724376_IN  in_dword_masked(\
+	HWIO_REG_724376_ADDR, HWIO_REG_724376_RMSK)
+#define HWIO_REG_724376_INM(m) \
+	in_dword_masked(HWIO_REG_724376_ADDR, m)
+#define HWIO_REG_724376_OUT(v) \
+	out_dword(HWIO_REG_724376_ADDR, v)
+#define HWIO_REG_724376_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_724376_ADDR, m, v,\
+	HWIO_REG_724376_IN);
+#define HWIO_REG_724376_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_724376_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_551674_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006a0)
+#define HWIO_REG_551674_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a0)
+#define HWIO_REG_551674_RMSK  0x1ffff
+#define HWIO_REG_551674_SHFT  0
+#define HWIO_REG_551674_IN  in_dword_masked(\
+	HWIO_REG_551674_ADDR, HWIO_REG_551674_RMSK)
+#define HWIO_REG_551674_INM(m) \
+	in_dword_masked(HWIO_REG_551674_ADDR, m)
+#define HWIO_REG_551674_OUT(v) \
+	out_dword(HWIO_REG_551674_ADDR, v)
+#define HWIO_REG_551674_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_551674_ADDR, m, v,\
+	HWIO_REG_551674_IN);
+#define HWIO_REG_551674_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_551674_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_115991_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006a4)
+#define HWIO_REG_115991_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a4)
+#define HWIO_REG_115991_RMSK  0x1ffff
+#define HWIO_REG_115991_SHFT  0
+#define HWIO_REG_115991_IN  in_dword_masked(\
+	HWIO_REG_115991_ADDR, HWIO_REG_115991_RMSK)
+#define HWIO_REG_115991_INM(m) \
+	in_dword_masked(HWIO_REG_115991_ADDR, m)
+#define HWIO_REG_115991_OUT(v) \
+	out_dword(HWIO_REG_115991_ADDR, v)
+#define HWIO_REG_115991_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_115991_ADDR, m, v,\
+	HWIO_REG_115991_IN);
+#define HWIO_REG_115991_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_115991_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_252167_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006a8)
+#define HWIO_REG_252167_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a8)
+#define HWIO_REG_252167_RMSK  0x1ffff
+#define HWIO_REG_252167_SHFT  0
+#define HWIO_REG_252167_IN  in_dword_masked(\
+	HWIO_REG_252167_ADDR, HWIO_REG_252167_RMSK)
+#define HWIO_REG_252167_INM(m) \
+	in_dword_masked(HWIO_REG_252167_ADDR, m)
+#define HWIO_REG_252167_OUT(v) \
+	out_dword(HWIO_REG_252167_ADDR, v)
+#define HWIO_REG_252167_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_252167_ADDR, m, v,\
+	HWIO_REG_252167_IN);
+#define HWIO_REG_252167_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_252167_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_695516_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006ac)
+#define HWIO_REG_695516_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006ac)
+#define HWIO_REG_695516_RMSK  0x1ffff
+#define HWIO_REG_695516_SHFT  0
+#define HWIO_REG_695516_IN  in_dword_masked(\
+	HWIO_REG_695516_ADDR, HWIO_REG_695516_RMSK)
+#define HWIO_REG_695516_INM(m) \
+	in_dword_masked(HWIO_REG_695516_ADDR, m)
+#define HWIO_REG_695516_OUT(v) \
+	out_dword(HWIO_REG_695516_ADDR, v)
+#define HWIO_REG_695516_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_695516_ADDR, m, v,\
+	HWIO_REG_695516_IN);
+#define HWIO_REG_695516_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_695516_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_152193_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006b0)
+#define HWIO_REG_152193_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b0)
+#define HWIO_REG_152193_RMSK  0x1ffff
+#define HWIO_REG_152193_SHFT  0
+#define HWIO_REG_152193_IN  in_dword_masked(\
+	HWIO_REG_152193_ADDR, HWIO_REG_152193_RMSK)
+#define HWIO_REG_152193_INM(m) \
+	in_dword_masked(HWIO_REG_152193_ADDR, m)
+#define HWIO_REG_152193_OUT(v) \
+	out_dword(HWIO_REG_152193_ADDR, v)
+#define HWIO_REG_152193_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_152193_ADDR, m, v,\
+	HWIO_REG_152193_IN);
+#define HWIO_REG_152193_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_152193_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_358705_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006b4)
+#define HWIO_REG_358705_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b4)
+#define HWIO_REG_358705_RMSK  0x1ffff
+#define HWIO_REG_358705_SHFT  0
+#define HWIO_REG_358705_IN  in_dword_masked(\
+	HWIO_REG_358705_ADDR, HWIO_REG_358705_RMSK)
+#define HWIO_REG_358705_INM(m) \
+	in_dword_masked(HWIO_REG_358705_ADDR, m)
+#define HWIO_REG_358705_OUT(v) \
+	out_dword(HWIO_REG_358705_ADDR, v)
+#define HWIO_REG_358705_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_358705_ADDR, m, v,\
+	HWIO_REG_358705_IN);
+#define HWIO_REG_358705_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_358705_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_457068_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006b8)
+#define HWIO_REG_457068_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b8)
+#define HWIO_REG_457068_RMSK  0x1ffff
+#define HWIO_REG_457068_SHFT  0
+#define HWIO_REG_457068_IN  in_dword_masked(\
+	HWIO_REG_457068_ADDR, HWIO_REG_457068_RMSK)
+#define HWIO_REG_457068_INM(m) \
+	in_dword_masked(HWIO_REG_457068_ADDR, m)
+#define HWIO_REG_457068_OUT(v) \
+	out_dword(HWIO_REG_457068_ADDR, v)
+#define HWIO_REG_457068_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_457068_ADDR, m, v,\
+	HWIO_REG_457068_IN);
+#define HWIO_REG_457068_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_457068_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_485412_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006bc)
+#define HWIO_REG_485412_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006bc)
+#define HWIO_REG_485412_RMSK  0x1ffff
+#define HWIO_REG_485412_SHFT  0
+#define HWIO_REG_485412_IN  in_dword_masked(\
+	HWIO_REG_485412_ADDR, HWIO_REG_485412_RMSK)
+#define HWIO_REG_485412_INM(m) \
+	in_dword_masked(HWIO_REG_485412_ADDR, m)
+#define HWIO_REG_485412_OUT(v) \
+	out_dword(HWIO_REG_485412_ADDR, v)
+#define HWIO_REG_485412_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_485412_ADDR, m, v,\
+	HWIO_REG_485412_IN);
+#define HWIO_REG_485412_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_485412_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_223131_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006c0)
+#define HWIO_REG_223131_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c0)
+#define HWIO_REG_223131_RMSK  0x1ffff
+#define HWIO_REG_223131_SHFT  0
+#define HWIO_REG_223131_IN  in_dword_masked(\
+	HWIO_REG_223131_ADDR, HWIO_REG_223131_RMSK)
+#define HWIO_REG_223131_INM(m) \
+		in_dword_masked(HWIO_REG_223131_ADDR, m)
+#define HWIO_REG_223131_OUT(v) \
+		out_dword(HWIO_REG_223131_ADDR, v)
+#define HWIO_REG_223131_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_223131_ADDR, m, v,\
+	HWIO_REG_223131_IN);
+#define HWIO_REG_223131_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_223131_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_683737_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006c4)
+#define HWIO_REG_683737_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c4)
+#define HWIO_REG_683737_RMSK  0x1ffff
+#define HWIO_REG_683737_SHFT  0
+#define HWIO_REG_683737_IN  in_dword_masked(\
+	HWIO_REG_683737_ADDR, HWIO_REG_683737_RMSK)
+#define HWIO_REG_683737_INM(m) \
+	in_dword_masked(HWIO_REG_683737_ADDR, m)
+#define HWIO_REG_683737_OUT(v) \
+	out_dword(HWIO_REG_683737_ADDR, v)
+#define HWIO_REG_683737_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_683737_ADDR, m, v,\
+	HWIO_REG_683737_IN);
+#define HWIO_REG_683737_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_683737_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_750474_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006c8)
+#define HWIO_REG_750474_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c8)
+#define HWIO_REG_750474_RMSK  0x1ffff
+#define HWIO_REG_750474_SHFT  0
+#define HWIO_REG_750474_IN  in_dword_masked(\
+	HWIO_REG_750474_ADDR, HWIO_REG_750474_RMSK)
+#define HWIO_REG_750474_INM(m) \
+	in_dword_masked(HWIO_REG_750474_ADDR, m)
+#define HWIO_REG_750474_OUT(v) \
+	out_dword(HWIO_REG_750474_ADDR, v)
+#define HWIO_REG_750474_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_750474_ADDR, m, v,\
+	HWIO_REG_750474_IN);
+#define HWIO_REG_750474_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_750474_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_170086_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006cc)
+#define HWIO_REG_170086_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006cc)
+#define HWIO_REG_170086_RMSK  0x1ffff
+#define HWIO_REG_170086_SHFT  0
+#define HWIO_REG_170086_IN  in_dword_masked(\
+	HWIO_REG_170086_ADDR, HWIO_REG_170086_RMSK)
+#define HWIO_REG_170086_INM(m) \
+	in_dword_masked(HWIO_REG_170086_ADDR, m)
+#define HWIO_REG_170086_OUT(v) \
+	out_dword(HWIO_REG_170086_ADDR, v)
+#define HWIO_REG_170086_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_170086_ADDR, m, v,\
+	HWIO_REG_170086_IN);
+#define HWIO_REG_170086_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_170086_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_838595_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006d0)
+#define HWIO_REG_838595_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d0)
+#define HWIO_REG_838595_RMSK  0x1ffff
+#define HWIO_REG_838595_SHFT  0
+#define HWIO_REG_838595_IN  in_dword_masked(\
+	HWIO_REG_838595_ADDR, HWIO_REG_838595_RMSK)
+#define HWIO_REG_838595_INM(m)  \
+	in_dword_masked(HWIO_REG_838595_ADDR, m)
+#define HWIO_REG_838595_OUT(v)  \
+	out_dword(HWIO_REG_838595_ADDR, v)
+#define HWIO_REG_838595_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_838595_ADDR, m, v,\
+	HWIO_REG_838595_IN);
+#define HWIO_REG_838595_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_838595_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_569788_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006d4)
+#define HWIO_REG_569788_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d4)
+#define HWIO_REG_569788_RMSK  0x1ffff
+#define HWIO_REG_569788_SHFT  0
+#define HWIO_REG_569788_IN  in_dword_masked(\
+	HWIO_REG_569788_ADDR, HWIO_REG_569788_RMSK)
+#define HWIO_REG_569788_INM(m) \
+	in_dword_masked(HWIO_REG_569788_ADDR, m)
+#define HWIO_REG_569788_OUT(v) \
+	out_dword(HWIO_REG_569788_ADDR, v)
+#define HWIO_REG_569788_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_569788_ADDR, m, v,\
+	HWIO_REG_569788_IN);
+#define HWIO_REG_569788_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_569788_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_974527_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006d8)
+#define HWIO_REG_974527_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d8)
+#define HWIO_REG_974527_RMSK  0x1ffff
+#define HWIO_REG_974527_SHFT  0
+#define HWIO_REG_974527_IN  in_dword_masked(\
+	HWIO_REG_974527_ADDR, HWIO_REG_974527_RMSK)
+#define HWIO_REG_974527_INM(m) \
+	in_dword_masked(HWIO_REG_974527_ADDR, m)
+#define HWIO_REG_974527_OUT(v) \
+	out_dword(HWIO_REG_974527_ADDR, v)
+#define HWIO_REG_974527_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_974527_ADDR, m, v,\
+	HWIO_REG_974527_IN);
+#define HWIO_REG_974527_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_974527_BASE_ADDR_SHFT   0
+
+#define HWIO_REG_316806_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006dc)
+#define HWIO_REG_316806_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006dc)
+#define HWIO_REG_316806_RMSK  0x1ffff
+#define HWIO_REG_316806_SHFT  0
+#define HWIO_REG_316806_IN  in_dword_masked(\
+	HWIO_REG_316806_ADDR, HWIO_REG_316806_RMSK)
+#define HWIO_REG_316806_INM(m) \
+	in_dword_masked(HWIO_REG_316806_ADDR, m)
+#define HWIO_REG_316806_OUT(v) \
+	out_dword(HWIO_REG_316806_ADDR, v)
+#define HWIO_REG_316806_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_316806_ADDR, m, v,\
+	HWIO_REG_316806_IN);
+#define HWIO_REG_316806_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_316806_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_900472_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006e0)
+#define HWIO_REG_900472_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e0)
+#define HWIO_REG_900472_RMSK  0x1ffff
+#define HWIO_REG_900472_SHFT  0
+#define HWIO_REG_900472_IN  in_dword_masked(\
+	HWIO_REG_900472_ADDR, HWIO_REG_900472_RMSK)
+#define HWIO_REG_900472_INM(m) \
+	in_dword_masked(HWIO_REG_900472_ADDR, m)
+#define HWIO_REG_900472_OUT(v) \
+	out_dword(HWIO_REG_900472_ADDR, v)
+#define HWIO_REG_900472_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_900472_ADDR, m, v,\
+	HWIO_REG_900472_IN);
+#define HWIO_REG_900472_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_900472_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_256156_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006e4)
+#define HWIO_REG_256156_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e4)
+#define HWIO_REG_256156_RMSK  0x1ffff
+#define HWIO_REG_256156_SHFT  0
+#define HWIO_REG_256156_IN  in_dword_masked(\
+	HWIO_REG_256156_ADDR, HWIO_REG_256156_RMSK)
+#define HWIO_REG_256156_INM(m) \
+	in_dword_masked(HWIO_REG_256156_ADDR, m)
+#define HWIO_REG_256156_OUT(v) \
+	out_dword(HWIO_REG_256156_ADDR, v)
+#define HWIO_REG_256156_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_256156_ADDR, m, v,\
+	HWIO_REG_256156_IN);
+#define HWIO_REG_256156_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_256156_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_335729_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006e8)
+#define HWIO_REG_335729_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e8)
+#define HWIO_REG_335729_RMSK  0x1ffff
+#define HWIO_REG_335729_SHFT  0
+#define HWIO_REG_335729_IN  in_dword_masked(\
+	HWIO_REG_335729_ADDR, HWIO_REG_335729_RMSK)
+#define HWIO_REG_335729_INM(m) \
+	in_dword_masked(HWIO_REG_335729_ADDR, m)
+#define HWIO_REG_335729_OUT(v) \
+	out_dword(HWIO_REG_335729_ADDR, v)
+#define HWIO_REG_335729_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_335729_ADDR, m, v,\
+	HWIO_REG_335729_IN);
+#define HWIO_REG_335729_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_335729_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_303383_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006ec)
+#define HWIO_REG_303383_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006ec)
+#define HWIO_REG_303383_RMSK  0x1ffff
+#define HWIO_REG_303383_SHFT  0
+#define HWIO_REG_303383_IN  in_dword_masked(\
+	HWIO_REG_303383_ADDR, HWIO_REG_303383_RMSK)
+#define HWIO_REG_303383_INM(m) \
+	in_dword_masked(HWIO_REG_303383_ADDR, m)
+#define HWIO_REG_303383_OUT(v) \
+	out_dword(HWIO_REG_303383_ADDR, v)
+#define HWIO_REG_303383_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_303383_ADDR, m, v,\
+	HWIO_REG_303383_IN);
+#define HWIO_REG_303383_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_303383_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_180871_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006f0)
+#define HWIO_REG_180871_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f0)
+#define HWIO_REG_180871_RMSK  0x1ffff
+#define HWIO_REG_180871_SHFT  0
+#define HWIO_REG_180871_IN  in_dword_masked(\
+	HWIO_REG_180871_ADDR, HWIO_REG_180871_RMSK)
+#define HWIO_REG_180871_INM(m) \
+	in_dword_masked(HWIO_REG_180871_ADDR, m)
+#define HWIO_REG_180871_OUT(v) \
+	out_dword(HWIO_REG_180871_ADDR, v)
+#define HWIO_REG_180871_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_180871_ADDR, m, v,\
+	HWIO_REG_180871_IN);
+#define HWIO_REG_180871_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_180871_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_514148_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006f4)
+#define HWIO_REG_514148_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f4)
+#define HWIO_REG_514148_RMSK  0x1ffff
+#define HWIO_REG_514148_SHFT  0
+#define HWIO_REG_514148_IN  in_dword_masked(\
+	HWIO_REG_514148_ADDR, HWIO_REG_514148_RMSK)
+#define HWIO_REG_514148_INM(m) \
+	in_dword_masked(HWIO_REG_514148_ADDR, m)
+#define HWIO_REG_514148_OUT(v) \
+	out_dword(HWIO_REG_514148_ADDR, v)
+#define HWIO_REG_514148_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_514148_ADDR, m, v,\
+	HWIO_REG_514148_IN);
+#define HWIO_REG_514148_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_514148_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_578636_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006f8)
+#define HWIO_REG_578636_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f8)
+#define HWIO_REG_578636_RMSK  0x1ffff
+#define HWIO_REG_578636_SHFT  0
+#define HWIO_REG_578636_IN  in_dword_masked(\
+	HWIO_REG_578636_ADDR, HWIO_REG_578636_RMSK)
+#define HWIO_REG_578636_INM(m) \
+	in_dword_masked(HWIO_REG_578636_ADDR, m)
+#define HWIO_REG_578636_OUT(v) \
+	out_dword(HWIO_REG_578636_ADDR, v)
+#define HWIO_REG_578636_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_578636_ADDR, m, v,\
+	HWIO_REG_578636_IN);
+#define HWIO_REG_578636_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_578636_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_888116_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000006fc)
+#define HWIO_REG_888116_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006fc)
+#define HWIO_REG_888116_RMSK  0x1ffff
+#define HWIO_REG_888116_SHFT  0
+#define HWIO_REG_888116_IN  in_dword_masked(\
+	HWIO_REG_888116_ADDR, HWIO_REG_888116_RMSK)
+#define HWIO_REG_888116_INM(m) \
+	in_dword_masked(HWIO_REG_888116_ADDR, m)
+#define HWIO_REG_888116_OUT(v) \
+	out_dword(HWIO_REG_888116_ADDR, v)
+#define HWIO_REG_888116_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_888116_ADDR, m, v,\
+	HWIO_REG_888116_IN);
+#define HWIO_REG_888116_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_888116_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_759068_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000700)
+#define HWIO_REG_759068_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000700)
+#define HWIO_REG_759068_RMSK  0x1ffff
+#define HWIO_REG_759068_SHFT  0
+#define HWIO_REG_759068_IN  in_dword_masked(\
+	HWIO_REG_759068_ADDR, HWIO_REG_759068_RMSK)
+#define HWIO_REG_759068_INM(m) \
+	in_dword_masked(HWIO_REG_759068_ADDR, m)
+#define HWIO_REG_759068_OUT(v) \
+	out_dword(HWIO_REG_759068_ADDR, v)
+#define HWIO_REG_759068_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_759068_ADDR, m, v,\
+	HWIO_REG_759068_IN);
+#define HWIO_REG_759068_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_759068_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_68356_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000704)
+#define HWIO_REG_68356_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000704)
+#define HWIO_REG_68356_RMSK  0x1ffff
+#define HWIO_REG_68356_SHFT  0
+#define HWIO_REG_68356_IN   in_dword_masked(\
+	HWIO_REG_68356_ADDR, HWIO_REG_68356_RMSK)
+#define HWIO_REG_68356_INM(m) \
+	in_dword_masked(HWIO_REG_68356_ADDR, m)
+#define HWIO_REG_68356_OUT(v) \
+	out_dword(HWIO_REG_68356_ADDR, v)
+#define HWIO_REG_68356_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_68356_ADDR, m, v,\
+	HWIO_REG_68356_IN);
+#define HWIO_REG_68356_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_68356_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_833502_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000708)
+#define HWIO_REG_833502_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000708)
+#define HWIO_REG_833502_RMSK  0x1ffff
+#define HWIO_REG_833502_SHFT  0
+#define HWIO_REG_833502_IN  in_dword_masked(\
+	HWIO_REG_833502_ADDR, HWIO_REG_833502_RMSK)
+#define HWIO_REG_833502_INM(m) \
+	in_dword_masked(HWIO_REG_833502_ADDR, m)
+#define HWIO_REG_833502_OUT(v) \
+	out_dword(HWIO_REG_833502_ADDR, v)
+#define HWIO_REG_833502_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_833502_ADDR, m, v,\
+	HWIO_REG_833502_IN);
+#define HWIO_REG_833502_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_833502_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_127855_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000070c)
+#define HWIO_REG_127855_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000070c)
+#define HWIO_REG_127855_RMSK  0x1ffff
+#define HWIO_REG_127855_SHFT  0
+#define HWIO_REG_127855_IN  in_dword_masked(\
+	HWIO_REG_127855_ADDR, HWIO_REG_127855_RMSK)
+#define HWIO_REG_127855_INM(m) \
+	in_dword_masked(HWIO_REG_127855_ADDR, m)
+#define HWIO_REG_127855_OUT(v) \
+	out_dword(HWIO_REG_127855_ADDR, v)
+#define HWIO_REG_127855_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_127855_ADDR, m, v,\
+	HWIO_REG_127855_IN);
+#define HWIO_REG_127855_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_127855_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_616802_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000710)
+#define HWIO_REG_616802_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000710)
+#define HWIO_REG_616802_RMSK  0x1ffff
+#define HWIO_REG_616802_SHFT  0
+#define HWIO_REG_616802_IN  in_dword_masked(\
+	HWIO_REG_616802_ADDR, HWIO_REG_616802_RMSK)
+#define HWIO_REG_616802_INM(m) \
+	in_dword_masked(HWIO_REG_616802_ADDR, m)
+#define HWIO_REG_616802_OUT(v) \
+	out_dword(HWIO_REG_616802_ADDR, v)
+#define HWIO_REG_616802_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_616802_ADDR, m, v,\
+	HWIO_REG_616802_IN);
+#define HWIO_REG_616802_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_616802_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_23318_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000714)
+#define HWIO_REG_23318_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000714)
+#define HWIO_REG_23318_RMSK  0x1ffff
+#define HWIO_REG_23318_SHFT  0
+#define HWIO_REG_23318_IN  in_dword_masked(\
+	HWIO_REG_23318_ADDR, HWIO_REG_23318_RMSK)
+#define HWIO_REG_23318_INM(m) \
+	in_dword_masked(HWIO_REG_23318_ADDR, m)
+#define HWIO_REG_23318_OUT(v) \
+	out_dword(HWIO_REG_23318_ADDR, v)
+#define HWIO_REG_23318_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_23318_ADDR, m, v,\
+	HWIO_REG_23318_IN);
+#define HWIO_REG_23318_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_23318_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_317106_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000718)
+#define HWIO_REG_317106_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000718)
+#define HWIO_REG_317106_RMSK  0x1ffff
+#define HWIO_REG_317106_SHFT  0
+#define HWIO_REG_317106_IN  in_dword_masked(\
+	HWIO_REG_317106_ADDR, HWIO_REG_317106_RMSK)
+#define HWIO_REG_317106_INM(m) \
+	in_dword_masked(HWIO_REG_317106_ADDR, m)
+#define HWIO_REG_317106_OUT(v) \
+	out_dword(HWIO_REG_317106_ADDR, v)
+#define HWIO_REG_317106_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_317106_ADDR, m, v,\
+	HWIO_REG_317106_IN);
+#define HWIO_REG_317106_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_317106_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_603772_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000071c)
+#define HWIO_REG_603772_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000071c)
+#define HWIO_REG_603772_RMSK  0x1ffff
+#define HWIO_REG_603772_SHFT  0
+#define HWIO_REG_603772_IN  in_dword_masked(\
+	HWIO_REG_603772_ADDR, HWIO_REG_603772_RMSK)
+#define HWIO_REG_603772_INM(m) \
+	in_dword_masked(HWIO_REG_603772_ADDR, m)
+#define HWIO_REG_603772_OUT(v) \
+	out_dword(HWIO_REG_603772_ADDR, v)
+#define HWIO_REG_603772_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_603772_ADDR, m, v,\
+	HWIO_REG_603772_IN);
+#define HWIO_REG_603772_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_603772_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_175929_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000720)
+#define HWIO_REG_175929_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000720)
+#define HWIO_REG_175929_RMSK  0x1ffff
+#define HWIO_REG_175929_SHFT  0
+#define HWIO_REG_175929_IN  in_dword_masked(\
+	HWIO_REG_175929_ADDR, HWIO_REG_175929_RMSK)
+#define HWIO_REG_175929_INM(m) \
+	in_dword_masked(HWIO_REG_175929_ADDR, m)
+#define HWIO_REG_175929_OUT(v) \
+	out_dword(HWIO_REG_175929_ADDR, v)
+#define HWIO_REG_175929_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_175929_ADDR, m, v,\
+	HWIO_REG_175929_IN);
+#define HWIO_REG_175929_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_175929_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_11928_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000724)
+#define HWIO_REG_11928_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000724)
+#define HWIO_REG_11928_RMSK  0x1ffff
+#define HWIO_REG_11928_SHFT  0
+#define HWIO_REG_11928_IN  in_dword_masked(\
+	HWIO_REG_11928_ADDR, HWIO_REG_11928_RMSK)
+#define HWIO_REG_11928_INM(m) \
+	in_dword_masked(HWIO_REG_11928_ADDR, m)
+#define HWIO_REG_11928_OUT(v) \
+	out_dword(HWIO_REG_11928_ADDR, v)
+#define HWIO_REG_11928_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_11928_ADDR, m, v,\
+	HWIO_REG_11928_IN);
+#define HWIO_REG_11928_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_11928_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_772678_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000728)
+#define HWIO_REG_772678_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000728)
+#define HWIO_REG_772678_RMSK  0x1ffff
+#define HWIO_REG_772678_SHFT  0
+#define HWIO_REG_772678_IN  in_dword_masked(\
+	HWIO_REG_772678_ADDR, HWIO_REG_772678_RMSK)
+#define HWIO_REG_772678_INM(m) \
+	in_dword_masked(HWIO_REG_772678_ADDR, m)
+#define HWIO_REG_772678_OUT(v) \
+	out_dword(HWIO_REG_772678_ADDR, v)
+#define HWIO_REG_772678_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_772678_ADDR, m, v,\
+	HWIO_REG_772678_IN);
+#define HWIO_REG_772678_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_772678_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_603389_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000072c)
+#define HWIO_REG_603389_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000072c)
+#define HWIO_REG_603389_RMSK  0x1ffff
+#define HWIO_REG_603389_SHFT  0
+#define HWIO_REG_603389_IN  in_dword_masked(\
+	HWIO_REG_603389_ADDR, HWIO_REG_603389_RMSK)
+#define HWIO_REG_603389_INM(m) \
+	in_dword_masked(HWIO_REG_603389_ADDR, m)
+#define HWIO_REG_603389_OUT(v) \
+	out_dword(HWIO_REG_603389_ADDR, v)
+#define HWIO_REG_603389_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_603389_ADDR, m, v,\
+	HWIO_REG_603389_IN);
+#define HWIO_REG_603389_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_603389_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_989918_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000730)
+#define HWIO_REG_989918_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000730)
+#define HWIO_REG_989918_RMSK  0x1ffff
+#define HWIO_REG_989918_SHFT  0
+#define HWIO_REG_989918_IN  in_dword_masked(\
+	HWIO_REG_989918_ADDR, HWIO_REG_989918_RMSK)
+#define HWIO_REG_989918_INM(m) \
+	in_dword_masked(HWIO_REG_989918_ADDR, m)
+#define HWIO_REG_989918_OUT(v) \
+	out_dword(HWIO_REG_989918_ADDR, v)
+#define HWIO_REG_989918_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_989918_ADDR, m, v,\
+	HWIO_REG_989918_IN);
+#define HWIO_REG_989918_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_989918_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_5460_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000734)
+#define HWIO_REG_5460_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000734)
+#define HWIO_REG_5460_RMSK  0x1ffff
+#define HWIO_REG_5460_SHFT  0
+#define HWIO_REG_5460_IN  in_dword_masked(\
+	HWIO_REG_5460_ADDR, HWIO_REG_5460_RMSK)
+#define HWIO_REG_5460_INM(m) \
+	in_dword_masked(HWIO_REG_5460_ADDR, m)
+#define HWIO_REG_5460_OUT(v) \
+	out_dword(HWIO_REG_5460_ADDR, v)
+#define HWIO_REG_5460_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_5460_ADDR, m, v,\
+	HWIO_REG_5460_IN);
+#define HWIO_REG_5460_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_5460_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_734724_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000738)
+#define HWIO_REG_734724_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000738)
+#define HWIO_REG_734724_RMSK  0x1ffff
+#define HWIO_REG_734724_SHFT  0
+#define HWIO_REG_734724_IN  in_dword_masked(\
+	HWIO_REG_734724_ADDR, HWIO_REG_734724_RMSK)
+#define HWIO_REG_734724_INM(m) \
+	in_dword_masked(HWIO_REG_734724_ADDR, m)
+#define HWIO_REG_734724_OUT(v) \
+	out_dword(HWIO_REG_734724_ADDR, v)
+#define HWIO_REG_734724_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_734724_ADDR, m, v,\
+	HWIO_REG_734724_IN);
+#define HWIO_REG_734724_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_734724_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_451742_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000073c)
+#define HWIO_REG_451742_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000073c)
+#define HWIO_REG_451742_RMSK  0x1ffff
+#define HWIO_REG_451742_SHFT  0
+#define HWIO_REG_451742_IN  in_dword_masked(\
+	HWIO_REG_451742_ADDR, HWIO_REG_451742_RMSK)
+#define HWIO_REG_451742_INM(m) \
+	in_dword_masked(HWIO_REG_451742_ADDR, m)
+#define HWIO_REG_451742_OUT(v) \
+	out_dword(HWIO_REG_451742_ADDR, v)
+#define HWIO_REG_451742_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_451742_ADDR, m, v,\
+	HWIO_REG_451742_IN);
+#define HWIO_REG_451742_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_451742_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_475648_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000740)
+#define HWIO_REG_475648_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000740)
+#define HWIO_REG_475648_RMSK  0x1ffff
+#define HWIO_REG_475648_SHFT  0
+#define HWIO_REG_475648_IN  in_dword_masked(\
+	HWIO_REG_475648_ADDR, HWIO_REG_475648_RMSK)
+#define HWIO_REG_475648_INM(m) \
+	in_dword_masked(HWIO_REG_475648_ADDR, m)
+#define HWIO_REG_475648_OUT(v) \
+	out_dword(HWIO_REG_475648_ADDR, v)
+#define HWIO_REG_475648_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_475648_ADDR, m, v,\
+	HWIO_REG_475648_IN);
+#define HWIO_REG_475648_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_475648_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_284758_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000744)
+#define HWIO_REG_284758_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000744)
+#define HWIO_REG_284758_RMSK  0x1ffff
+#define HWIO_REG_284758_SHFT  0
+#define HWIO_REG_284758_IN  in_dword_masked(\
+	HWIO_REG_284758_ADDR, HWIO_REG_284758_RMSK)
+#define HWIO_REG_284758_INM(m) \
+	in_dword_masked(HWIO_REG_284758_ADDR, m)
+#define HWIO_REG_284758_OUT(v) \
+	out_dword(HWIO_REG_284758_ADDR, v)
+#define HWIO_REG_284758_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_284758_ADDR, m, v,\
+	HWIO_REG_284758_IN);
+#define HWIO_REG_284758_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_284758_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_523659_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000748)
+#define HWIO_REG_523659_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000748)
+#define HWIO_REG_523659_RMSK  0x1ffff
+#define HWIO_REG_523659_SHFT  0
+#define HWIO_REG_523659_IN  in_dword_masked(\
+	HWIO_REG_523659_ADDR, HWIO_REG_523659_RMSK)
+#define HWIO_REG_523659_INM(m) \
+	in_dword_masked(HWIO_REG_523659_ADDR, m)
+#define HWIO_REG_523659_OUT(v) \
+	out_dword(HWIO_REG_523659_ADDR, v)
+#define HWIO_REG_523659_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_523659_ADDR, m, v,\
+	HWIO_REG_523659_IN);
+#define HWIO_REG_523659_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_523659_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_815580_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000074c)
+#define HWIO_REG_815580_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000074c)
+#define HWIO_REG_815580_RMSK  0x1ffff
+#define HWIO_REG_815580_SHFT  0
+#define HWIO_REG_815580_IN  in_dword_masked(\
+	HWIO_REG_815580_ADDR, HWIO_REG_815580_RMSK)
+#define HWIO_REG_815580_INM(m) \
+	in_dword_masked(HWIO_REG_815580_ADDR, m)
+#define HWIO_REG_815580_OUT(v) \
+	out_dword(HWIO_REG_815580_ADDR, v)
+#define HWIO_REG_815580_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_815580_ADDR, m, v,\
+	HWIO_REG_815580_IN);
+#define HWIO_REG_815580_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_815580_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_546551_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000750)
+#define HWIO_REG_546551_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000750)
+#define HWIO_REG_546551_RMSK  0x1ffff
+#define HWIO_REG_546551_SHFT  0
+#define HWIO_REG_546551_IN  in_dword_masked(\
+	HWIO_REG_546551_ADDR, HWIO_REG_546551_RMSK)
+#define HWIO_REG_546551_INM(m) \
+	in_dword_masked(HWIO_REG_546551_ADDR, m)
+#define HWIO_REG_546551_OUT(v) \
+	out_dword(HWIO_REG_546551_ADDR, v)
+#define HWIO_REG_546551_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_546551_ADDR, m, v,\
+	HWIO_REG_546551_IN);
+#define HWIO_REG_546551_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_546551_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_769851_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000754)
+#define HWIO_REG_769851_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000754)
+#define HWIO_REG_769851_RMSK  0x1ffff
+#define HWIO_REG_769851_SHFT  0
+#define HWIO_REG_769851_IN  in_dword_masked(\
+	HWIO_REG_769851_ADDR, HWIO_REG_769851_RMSK)
+#define HWIO_REG_769851_INM(m) \
+	in_dword_masked(HWIO_REG_769851_ADDR, m)
+#define HWIO_REG_769851_OUT(v) \
+	out_dword(HWIO_REG_769851_ADDR, v)
+#define HWIO_REG_769851_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_769851_ADDR, m, v,\
+	HWIO_REG_769851_IN);
+#define HWIO_REG_769851_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_769851_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_205028_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000758)
+#define HWIO_REG_205028_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000758)
+#define HWIO_REG_205028_RMSK  0x1ffff
+#define HWIO_REG_205028_SHFT  0
+#define HWIO_REG_205028_IN  in_dword_masked(\
+	HWIO_REG_205028_ADDR, HWIO_REG_205028_RMSK)
+#define HWIO_REG_205028_INM(m) \
+	in_dword_masked(HWIO_REG_205028_ADDR, m)
+#define HWIO_REG_205028_OUT(v) \
+	out_dword(HWIO_REG_205028_ADDR, v)
+#define HWIO_REG_205028_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_205028_ADDR, m, v,\
+	HWIO_REG_205028_IN);
+#define HWIO_REG_205028_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_205028_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_206835_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000075c)
+#define HWIO_REG_206835_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000075c)
+#define HWIO_REG_206835_RMSK  0x1ffff
+#define HWIO_REG_206835_SHFT  0
+#define HWIO_REG_206835_IN  in_dword_masked(\
+	HWIO_REG_206835_ADDR, HWIO_REG_206835_RMSK)
+#define HWIO_REG_206835_INM(m) \
+	in_dword_masked(HWIO_REG_206835_ADDR, m)
+#define HWIO_REG_206835_OUT(v) \
+	out_dword(HWIO_REG_206835_ADDR, v)
+#define HWIO_REG_206835_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_206835_ADDR, m, v,\
+	HWIO_REG_206835_IN);
+#define HWIO_REG_206835_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_206835_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_582575_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000760)
+#define HWIO_REG_582575_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000760)
+#define HWIO_REG_582575_RMSK  0x1ffff
+#define HWIO_REG_582575_SHFT  0
+#define HWIO_REG_582575_IN  in_dword_masked(\
+	HWIO_REG_582575_ADDR, HWIO_REG_582575_RMSK)
+#define HWIO_REG_582575_INM(m) \
+	in_dword_masked(HWIO_REG_582575_ADDR, m)
+#define HWIO_REG_582575_OUT(v) \
+	out_dword(HWIO_REG_582575_ADDR, v)
+#define HWIO_REG_582575_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_582575_ADDR, m, v,\
+	HWIO_REG_582575_IN);
+#define HWIO_REG_582575_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_582575_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_120885_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000764)
+#define HWIO_REG_120885_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000764)
+#define HWIO_REG_120885_RMSK  0x1ffff
+#define HWIO_REG_120885_SHFT  0
+#define HWIO_REG_120885_IN  in_dword_masked(\
+	HWIO_REG_120885_ADDR, HWIO_REG_120885_RMSK)
+#define HWIO_REG_120885_INM(m) \
+	in_dword_masked(HWIO_REG_120885_ADDR, m)
+#define HWIO_REG_120885_OUT(v) \
+	out_dword(HWIO_REG_120885_ADDR, v)
+#define HWIO_REG_120885_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_120885_ADDR, m, v,\
+	HWIO_REG_120885_IN);
+#define HWIO_REG_120885_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_120885_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_496067_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000768)
+#define HWIO_REG_496067_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000768)
+#define HWIO_REG_496067_RMSK  0x1ffff
+#define HWIO_REG_496067_SHFT  0
+#define HWIO_REG_496067_IN  in_dword_masked(\
+	HWIO_REG_496067_ADDR, HWIO_REG_496067_RMSK)
+#define HWIO_REG_496067_INM(m) \
+	in_dword_masked(HWIO_REG_496067_ADDR, m)
+#define HWIO_REG_496067_OUT(v) \
+	out_dword(HWIO_REG_496067_ADDR, v)
+#define HWIO_REG_496067_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_496067_ADDR, m, v,\
+	HWIO_REG_496067_IN);
+#define HWIO_REG_496067_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_496067_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_472919_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000076c)
+#define HWIO_REG_472919_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000076c)
+#define HWIO_REG_472919_RMSK  0x1ffff
+#define HWIO_REG_472919_SHFT  0
+#define HWIO_REG_472919_IN  in_dword_masked(\
+	HWIO_REG_472919_ADDR, HWIO_REG_472919_RMSK)
+#define HWIO_REG_472919_INM(m) \
+	in_dword_masked(HWIO_REG_472919_ADDR, m)
+#define HWIO_REG_472919_OUT(v) \
+	out_dword(HWIO_REG_472919_ADDR, v)
+#define HWIO_REG_472919_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_472919_ADDR, m, v,\
+	HWIO_REG_472919_IN);
+#define HWIO_REG_472919_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_472919_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_486985_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000770)
+#define HWIO_REG_486985_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000770)
+#define HWIO_REG_486985_RMSK  0x1ffff
+#define HWIO_REG_486985_SHFT  0
+#define HWIO_REG_486985_IN  in_dword_masked(\
+	HWIO_REG_486985_ADDR, HWIO_REG_486985_RMSK)
+#define HWIO_REG_486985_INM(m) \
+	in_dword_masked(HWIO_REG_486985_ADDR, m)
+#define HWIO_REG_486985_OUT(v) \
+	out_dword(HWIO_REG_486985_ADDR, v)
+#define HWIO_REG_486985_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_486985_ADDR, m, v,\
+	HWIO_REG_486985_IN);
+#define HWIO_REG_486985_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_486985_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_964692_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000774)
+#define HWIO_REG_964692_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000774)
+#define HWIO_REG_964692_RMSK  0x1ffff
+#define HWIO_REG_964692_SHFT  0
+#define HWIO_REG_964692_IN  in_dword_masked(\
+	HWIO_REG_964692_ADDR, HWIO_REG_964692_RMSK)
+#define HWIO_REG_964692_INM(m) \
+	in_dword_masked(HWIO_REG_964692_ADDR, m)
+#define HWIO_REG_964692_OUT(v) \
+	out_dword(HWIO_REG_964692_ADDR, v)
+#define HWIO_REG_964692_OUTM(m, v)   out_dword_masked_ns(\
+	HWIO_REG_964692_ADDR, m, v,\
+	HWIO_REG_964692_IN);
+#define HWIO_REG_964692_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_964692_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_941116_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000778)
+#define HWIO_REG_941116_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000778)
+#define HWIO_REG_941116_RMSK  0x1ffff
+#define HWIO_REG_941116_SHFT  0
+#define HWIO_REG_941116_IN  in_dword_masked(\
+	HWIO_REG_941116_ADDR, HWIO_REG_941116_RMSK)
+#define HWIO_REG_941116_INM(m) \
+	in_dword_masked(HWIO_REG_941116_ADDR, m)
+#define HWIO_REG_941116_OUT(v) \
+	out_dword(HWIO_REG_941116_ADDR, v)
+#define HWIO_REG_941116_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_941116_ADDR, m, v,\
+	HWIO_REG_941116_IN);
+#define HWIO_REG_941116_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_941116_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_122567_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000077c)
+#define HWIO_REG_122567_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000077c)
+#define HWIO_REG_122567_RMSK  0x1ffff
+#define HWIO_REG_122567_SHFT  0
+#define HWIO_REG_122567_IN  in_dword_masked(\
+	HWIO_REG_122567_ADDR, HWIO_REG_122567_RMSK)
+#define HWIO_REG_122567_INM(m) \
+	in_dword_masked(HWIO_REG_122567_ADDR, m)
+#define HWIO_REG_122567_OUT(v) \
+	out_dword(HWIO_REG_122567_ADDR, v)
+#define HWIO_REG_122567_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_122567_ADDR, m, v,\
+	HWIO_REG_122567_IN);
+#define HWIO_REG_122567_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_122567_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_466192_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000780)
+#define HWIO_REG_466192_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000780)
+#define HWIO_REG_466192_RMSK  0x1ffff
+#define HWIO_REG_466192_SHFT  0
+#define HWIO_REG_466192_IN  in_dword_masked(\
+	HWIO_REG_466192_ADDR, HWIO_REG_466192_RMSK)
+#define HWIO_REG_466192_INM(m) \
+	in_dword_masked(HWIO_REG_466192_ADDR, m)
+#define HWIO_REG_466192_OUT(v) \
+	out_dword(HWIO_REG_466192_ADDR, v)
+#define HWIO_REG_466192_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_466192_ADDR, m, v,\
+	HWIO_REG_466192_IN);
+#define HWIO_REG_466192_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_466192_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_554890_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000784)
+#define HWIO_REG_554890_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000784)
+#define HWIO_REG_554890_RMSK  0x1ffff
+#define HWIO_REG_554890_SHFT  0
+#define HWIO_REG_554890_IN  in_dword_masked(\
+	HWIO_REG_554890_ADDR, HWIO_REG_554890_RMSK)
+#define HWIO_REG_554890_INM(m) \
+	in_dword_masked(HWIO_REG_554890_ADDR, m)
+#define HWIO_REG_554890_OUT(v)                          \
+	out_dword(HWIO_REG_554890_ADDR, v)
+#define HWIO_REG_554890_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_554890_ADDR, m, v,\
+	HWIO_REG_554890_IN);
+#define HWIO_REG_554890_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_554890_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_295616_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000788)
+#define HWIO_REG_295616_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000788)
+#define HWIO_REG_295616_RMSK  0x1ffff
+#define HWIO_REG_295616_SHFT  0
+#define HWIO_REG_295616_IN  in_dword_masked(\
+	HWIO_REG_295616_ADDR, HWIO_REG_295616_RMSK)
+#define HWIO_REG_295616_INM(m) \
+	in_dword_masked(HWIO_REG_295616_ADDR, m)
+#define HWIO_REG_295616_OUT(v) \
+	out_dword(HWIO_REG_295616_ADDR, v)
+#define HWIO_REG_295616_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_295616_ADDR, m, v,\
+	HWIO_REG_295616_IN);
+#define HWIO_REG_295616_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_295616_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_440836_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000078c)
+#define HWIO_REG_440836_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000078c)
+#define HWIO_REG_440836_RMSK  0x1ffff
+#define HWIO_REG_440836_SHFT  0
+#define HWIO_REG_440836_IN  in_dword_masked(\
+	HWIO_REG_440836_ADDR, HWIO_REG_440836_RMSK)
+#define HWIO_REG_440836_INM(m) \
+	in_dword_masked(HWIO_REG_440836_ADDR, m)
+#define HWIO_REG_440836_OUT(v) \
+	out_dword(HWIO_REG_440836_ADDR, v)
+#define HWIO_REG_440836_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_440836_ADDR, m, v,\
+	HWIO_REG_440836_IN);
+#define HWIO_REG_440836_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_440836_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_741154_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000790)
+#define HWIO_REG_741154_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000790)
+#define HWIO_REG_741154_RMSK  0x1ffff
+#define HWIO_REG_741154_SHFT  0
+#define HWIO_REG_741154_IN  in_dword_masked(\
+	HWIO_REG_741154_ADDR,\
+	HWIO_REG_741154_RMSK)
+#define HWIO_REG_741154_INM(m) \
+	in_dword_masked(HWIO_REG_741154_ADDR, m)
+#define HWIO_REG_741154_OUT(v) \
+	out_dword(HWIO_REG_741154_ADDR, v)
+#define HWIO_REG_741154_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_741154_ADDR, m, v,\
+	HWIO_REG_741154_IN);
+#define HWIO_REG_741154_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_741154_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_753139_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000794)
+#define HWIO_REG_753139_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000794)
+#define HWIO_REG_753139_RMSK  0x1ffff
+#define HWIO_REG_753139_SHFT  0
+#define HWIO_REG_753139_IN  in_dword_masked(\
+	HWIO_REG_753139_ADDR,\
+	HWIO_REG_753139_RMSK)
+#define HWIO_REG_753139_INM(m) \
+	in_dword_masked(HWIO_REG_753139_ADDR, m)
+#define HWIO_REG_753139_OUT(v) \
+	out_dword(HWIO_REG_753139_ADDR, v)
+#define HWIO_REG_753139_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_753139_ADDR, m, v,\
+	HWIO_REG_753139_IN);
+#define HWIO_REG_753139_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_753139_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_409994_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x00000798)
+#define HWIO_REG_409994_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000798)
+#define HWIO_REG_409994_RMSK  0x1ffff
+#define HWIO_REG_409994_SHFT  0
+#define HWIO_REG_409994_IN  in_dword_masked(\
+	HWIO_REG_409994_ADDR,\
+	HWIO_REG_409994_RMSK)
+#define HWIO_REG_409994_INM(m) \
+	in_dword_masked(HWIO_REG_409994_ADDR, m)
+#define HWIO_REG_409994_OUT(v) \
+	out_dword(HWIO_REG_409994_ADDR, v)
+#define HWIO_REG_409994_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_409994_ADDR, m, v,\
+	HWIO_REG_409994_IN);
+#define HWIO_REG_409994_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_409994_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_492611_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000079c)
+#define HWIO_REG_492611_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000079c)
+#define HWIO_REG_492611_RMSK  0x1ffff
+#define HWIO_REG_492611_SHFT  0
+#define HWIO_REG_492611_IN  in_dword_masked(\
+	HWIO_REG_492611_ADDR,\
+	HWIO_REG_492611_RMSK)
+#define HWIO_REG_492611_INM(m) \
+	in_dword_masked(HWIO_REG_492611_ADDR, m)
+#define HWIO_REG_492611_OUT(v) \
+	out_dword(HWIO_REG_492611_ADDR, v)
+#define HWIO_REG_492611_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_492611_ADDR, m, v,\
+	HWIO_REG_492611_IN);
+#define HWIO_REG_492611_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_492611_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_91427_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007a0)
+#define HWIO_REG_91427_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a0)
+#define HWIO_REG_91427_RMSK  0x1ffff
+#define HWIO_REG_91427_SHFT  0
+#define HWIO_REG_91427_IN  in_dword_masked(\
+	HWIO_REG_91427_ADDR,\
+	HWIO_REG_91427_RMSK)
+#define HWIO_REG_91427_INM(m) \
+	in_dword_masked(HWIO_REG_91427_ADDR, m)
+#define HWIO_REG_91427_OUT(v) \
+	out_dword(HWIO_REG_91427_ADDR, v)
+#define HWIO_REG_91427_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_91427_ADDR, m, v,\
+	HWIO_REG_91427_IN);
+#define HWIO_REG_91427_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_91427_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_617696_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007a4)
+#define HWIO_REG_617696_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a4)
+#define HWIO_REG_617696_RMSK  0x1ffff
+#define HWIO_REG_617696_SHFT  0
+#define HWIO_REG_617696_IN  in_dword_masked(\
+	HWIO_REG_617696_ADDR,\
+	HWIO_REG_617696_RMSK)
+#define HWIO_REG_617696_INM(m) \
+	in_dword_masked(HWIO_REG_617696_ADDR, m)
+#define HWIO_REG_617696_OUT(v) \
+	out_dword(HWIO_REG_617696_ADDR, v)
+#define HWIO_REG_617696_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_617696_ADDR, m, v,\
+	HWIO_REG_617696_IN);
+#define HWIO_REG_617696_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_617696_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_459602_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007a8)
+#define HWIO_REG_459602_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a8)
+#define HWIO_REG_459602_RMSK  0x1ffff
+#define HWIO_REG_459602_SHFT  0
+#define HWIO_REG_459602_IN  in_dword_masked(\
+	HWIO_REG_459602_ADDR,\
+	HWIO_REG_459602_RMSK)
+#define HWIO_REG_459602_INM(m) \
+	in_dword_masked(HWIO_REG_459602_ADDR, m)
+#define HWIO_REG_459602_OUT(v) \
+	out_dword(HWIO_REG_459602_ADDR, v)
+#define HWIO_REG_459602_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_459602_ADDR, m, v,\
+	HWIO_REG_459602_IN);
+#define HWIO_REG_459602_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_459602_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_758_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007ac)
+#define HWIO_REG_758_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007ac)
+#define HWIO_REG_758_RMSK  0x1ffff
+#define HWIO_REG_758_SHFT  0
+#define HWIO_REG_758_IN  in_dword_masked(\
+	HWIO_REG_758_ADDR,\
+	HWIO_REG_758_RMSK)
+#define HWIO_REG_758_INM(m) \
+	in_dword_masked(HWIO_REG_758_ADDR, m)
+#define HWIO_REG_758_OUT(v) \
+	out_dword(HWIO_REG_758_ADDR, v)
+#define HWIO_REG_758_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_758_ADDR, m, v,\
+	HWIO_REG_758_IN);
+#define HWIO_REG_758_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_758_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_710606_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007b0)
+#define HWIO_REG_710606_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b0)
+#define HWIO_REG_710606_RMSK  0x1ffff
+#define HWIO_REG_710606_SHFT  0
+#define HWIO_REG_710606_IN  in_dword_masked(\
+	HWIO_REG_710606_ADDR,\
+	HWIO_REG_710606_RMSK)
+#define HWIO_REG_710606_INM(m) \
+	in_dword_masked(HWIO_REG_710606_ADDR, m)
+#define HWIO_REG_710606_OUT(v) \
+	out_dword(HWIO_REG_710606_ADDR, v)
+#define HWIO_REG_710606_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_710606_ADDR, m, v,\
+	HWIO_REG_710606_IN);
+#define HWIO_REG_710606_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_710606_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_122975_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007b4)
+#define HWIO_REG_122975_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b4)
+#define HWIO_REG_122975_RMSK  0x1ffff
+#define HWIO_REG_122975_SHFT  0
+#define HWIO_REG_122975_IN  in_dword_masked(\
+	HWIO_REG_122975_ADDR,\
+	HWIO_REG_122975_RMSK)
+#define HWIO_REG_122975_INM(m)\
+	in_dword_masked(HWIO_REG_122975_ADDR, m)
+#define HWIO_REG_122975_OUT(v)\
+	out_dword(HWIO_REG_122975_ADDR, v)
+#define HWIO_REG_122975_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_122975_ADDR, m, v,\
+	HWIO_REG_122975_IN);
+#define HWIO_REG_122975_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_122975_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_860205_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007b8)
+#define HWIO_REG_860205_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b8)
+#define HWIO_REG_860205_RMSK  0x1ffff
+#define HWIO_REG_860205_SHFT  0
+#define HWIO_REG_860205_IN  in_dword_masked(\
+	HWIO_REG_860205_ADDR,\
+	HWIO_REG_860205_RMSK)
+#define HWIO_REG_860205_INM(m) \
+	in_dword_masked(HWIO_REG_860205_ADDR, m)
+#define HWIO_REG_860205_OUT(v) \
+	out_dword(HWIO_REG_860205_ADDR, v)
+#define HWIO_REG_860205_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_860205_ADDR, m, v,\
+	HWIO_REG_860205_IN);
+#define HWIO_REG_860205_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_860205_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_366154_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007bc)
+#define HWIO_REG_366154_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007bc)
+#define HWIO_REG_366154_RMSK  0x1ffff
+#define HWIO_REG_366154_SHFT  0
+#define HWIO_REG_366154_IN  in_dword_masked(\
+	HWIO_REG_366154_ADDR,\
+	HWIO_REG_366154_RMSK)
+#define HWIO_REG_366154_INM(m) \
+	in_dword_masked(HWIO_REG_366154_ADDR, m)
+#define HWIO_REG_366154_OUT(v) \
+	out_dword(HWIO_REG_366154_ADDR, v)
+#define HWIO_REG_366154_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_366154_ADDR, m, v,\
+	HWIO_REG_366154_IN);
+#define HWIO_REG_366154_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_366154_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_632247_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007c0)
+#define HWIO_REG_632247_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c0)
+#define HWIO_REG_632247_RMSK  0x1ffff
+#define HWIO_REG_632247_SHFT  0
+#define HWIO_REG_632247_IN  in_dword_masked(\
+	HWIO_REG_632247_ADDR,\
+	HWIO_REG_632247_RMSK)
+#define HWIO_REG_632247_INM(m) \
+	in_dword_masked(HWIO_REG_632247_ADDR, m)
+#define HWIO_REG_632247_OUT(v) \
+	out_dword(HWIO_REG_632247_ADDR, v)
+#define HWIO_REG_632247_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_632247_ADDR, m, v,\
+	HWIO_REG_632247_IN);
+#define HWIO_REG_632247_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_632247_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_709312_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007c4)
+#define HWIO_REG_709312_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c4)
+#define HWIO_REG_709312_RMSK  0x1ffff
+#define HWIO_REG_709312_SHFT  0
+#define HWIO_REG_709312_IN  in_dword_masked(\
+	HWIO_REG_709312_ADDR,\
+	HWIO_REG_709312_RMSK)
+#define HWIO_REG_709312_INM(m) \
+	in_dword_masked(HWIO_REG_709312_ADDR, m)
+#define HWIO_REG_709312_OUT(v) \
+	out_dword(HWIO_REG_709312_ADDR, v)
+#define HWIO_REG_709312_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_709312_ADDR, m, v,\
+	HWIO_REG_709312_IN);
+#define HWIO_REG_709312_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_709312_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_891367_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007c8)
+#define HWIO_REG_891367_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c8)
+#define HWIO_REG_891367_RMSK  0x1ffff
+#define HWIO_REG_891367_SHFT  0
+#define HWIO_REG_891367_IN  in_dword_masked(\
+	HWIO_REG_891367_ADDR,\
+	HWIO_REG_891367_RMSK)
+#define HWIO_REG_891367_INM(m) \
+	in_dword_masked(HWIO_REG_891367_ADDR, m)
+#define HWIO_REG_891367_OUT(v) \
+	out_dword(HWIO_REG_891367_ADDR, v)
+#define HWIO_REG_891367_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_891367_ADDR, m, v,\
+	HWIO_REG_891367_IN);
+#define HWIO_REG_891367_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_891367_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_628746_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007cc)
+#define HWIO_REG_628746_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007cc)
+#define HWIO_REG_628746_RMSK  0x1ffff
+#define HWIO_REG_628746_SHFT  0
+#define HWIO_REG_628746_IN  in_dword_masked(\
+	HWIO_REG_628746_ADDR,\
+	HWIO_REG_628746_RMSK)
+#define HWIO_REG_628746_INM(m) \
+	in_dword_masked(HWIO_REG_628746_ADDR, m)
+#define HWIO_REG_628746_OUT(v) \
+	out_dword(HWIO_REG_628746_ADDR, v)
+#define HWIO_REG_628746_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_628746_ADDR, m, v,\
+	HWIO_REG_628746_IN);
+#define HWIO_REG_628746_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_628746_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_821010_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007d0)
+#define HWIO_REG_821010_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d0)
+#define HWIO_REG_821010_RMSK  0x1ffff
+#define HWIO_REG_821010_SHFT  0
+#define HWIO_REG_821010_IN  in_dword_masked(\
+	HWIO_REG_821010_ADDR,\
+	HWIO_REG_821010_RMSK)
+#define HWIO_REG_821010_INM(m) \
+	in_dword_masked(HWIO_REG_821010_ADDR, m)
+#define HWIO_REG_821010_OUT(v) \
+	out_dword(HWIO_REG_821010_ADDR, v)
+#define HWIO_REG_821010_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_821010_ADDR, m, v,\
+	HWIO_REG_821010_IN);
+#define HWIO_REG_821010_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_821010_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_902098_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007d4)
+#define HWIO_REG_902098_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d4)
+#define HWIO_REG_902098_RMSK  0x1ffff
+#define HWIO_REG_902098_SHFT  0
+#define HWIO_REG_902098_IN   in_dword_masked(\
+	HWIO_REG_902098_ADDR,\
+	HWIO_REG_902098_RMSK)
+#define HWIO_REG_902098_INM(m) \
+	in_dword_masked(HWIO_REG_902098_ADDR, m)
+#define HWIO_REG_902098_OUT(v) \
+	out_dword(HWIO_REG_902098_ADDR, v)
+#define HWIO_REG_902098_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_902098_ADDR, m, v,\
+	HWIO_REG_902098_IN);
+#define HWIO_REG_902098_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_902098_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_939091_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007d8)
+#define HWIO_REG_939091_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d8)
+#define HWIO_REG_939091_RMSK  0x1ffff
+#define HWIO_REG_939091_SHFT  0
+#define HWIO_REG_939091_IN  in_dword_masked(\
+	HWIO_REG_939091_ADDR,\
+	HWIO_REG_939091_RMSK)
+#define HWIO_REG_939091_INM(m) \
+	in_dword_masked(HWIO_REG_939091_ADDR, m)
+#define HWIO_REG_939091_OUT(v) \
+	out_dword(HWIO_REG_939091_ADDR, v)
+#define HWIO_REG_939091_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_939091_ADDR, m, v,\
+	HWIO_REG_939091_IN);
+#define HWIO_REG_939091_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_939091_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_261074_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007dc)
+#define HWIO_REG_261074_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007dc)
+#define HWIO_REG_261074_RMSK  0x1ffff
+#define HWIO_REG_261074_SHFT  0
+#define HWIO_REG_261074_IN  in_dword_masked(\
+	HWIO_REG_261074_ADDR,\
+	HWIO_REG_261074_RMSK)
+#define HWIO_REG_261074_INM(m) \
+	in_dword_masked(HWIO_REG_261074_ADDR, m)
+#define HWIO_REG_261074_OUT(v) \
+	out_dword(HWIO_REG_261074_ADDR, v)
+#define HWIO_REG_261074_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_261074_ADDR, m, v,\
+	HWIO_REG_261074_IN);
+#define HWIO_REG_261074_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_261074_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_157718_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007e0)
+#define HWIO_REG_157718_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007e0)
+#define HWIO_REG_157718_RMSK  0x1ffff
+#define HWIO_REG_157718_SHFT  0
+#define HWIO_REG_157718_IN  in_dword_masked(\
+	HWIO_REG_157718_ADDR,\
+	HWIO_REG_157718_RMSK)
+#define HWIO_REG_157718_INM(m) \
+	in_dword_masked(HWIO_REG_157718_ADDR, m)
+#define HWIO_REG_157718_OUT(v) \
+	out_dword(HWIO_REG_157718_ADDR, v)
+#define HWIO_REG_157718_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_157718_ADDR, m, v,\
+	HWIO_REG_157718_IN);
+#define HWIO_REG_5552391_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_5552391_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_148889_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007e8)
+#define HWIO_REG_148889_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007e8)
+#define HWIO_REG_148889_RMSK  0x1ffff
+#define HWIO_REG_148889_SHFT  0
+#define HWIO_REG_148889_IN  in_dword_masked(\
+	HWIO_REG_148889_ADDR,\
+	HWIO_REG_148889_RMSK)
+#define HWIO_REG_148889_INM(m) \
+	in_dword_masked(HWIO_REG_148889_ADDR, m)
+#define HWIO_REG_148889_OUT(v) \
+	out_dword(HWIO_REG_148889_ADDR, v)
+#define HWIO_REG_148889_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_148889_ADDR, m, v,\
+	HWIO_REG_148889_IN);
+#define HWIO_REG_148889_BASE_ADDR_BMSK 0x1ffff
+#define HWIO_REG_148889_BASE_ADDR_SHFT 0
+
+#define HWIO_REG_396380_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007ec)
+#define HWIO_REG_396380_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007ec)
+#define HWIO_REG_396380_RMSK  0x1ffff
+#define HWIO_REG_396380_SHFT  0
+#define HWIO_REG_396380_IN  in_dword_masked(\
+	HWIO_REG_396380_ADDR,\
+	HWIO_REG_396380_RMSK)
+#define HWIO_REG_396380_INM(m) \
+	in_dword_masked(HWIO_REG_396380_ADDR, m)
+#define HWIO_REG_396380_OUT(v) \
+	out_dword(HWIO_REG_396380_ADDR, v)
+#define HWIO_REG_396380_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_396380_ADDR, m, v,\
+	HWIO_REG_396380_IN);
+#define HWIO_REG_396380_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_396380_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_351005_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007f0)
+#define HWIO_REG_351005_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f0)
+#define HWIO_REG_351005_RMSK  0x1ffff
+#define HWIO_REG_351005_SHFT  0
+#define HWIO_REG_351005_IN  in_dword_masked(\
+	HWIO_REG_351005_ADDR,\
+	HWIO_REG_351005_RMSK)
+#define HWIO_REG_351005_INM(m) \
+	in_dword_masked(HWIO_REG_351005_ADDR, m)
+#define HWIO_REG_351005_OUT(v) \
+	out_dword(HWIO_REG_351005_ADDR, v)
+#define HWIO_REG_351005_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_351005_ADDR, m, v,\
+	HWIO_REG_351005_IN);
+#define HWIO_REG_351005_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_351005_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_863263_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007f4)
+#define HWIO_REG_863263_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f4)
+#define HWIO_REG_863263_RMSK  0x1ffff
+#define HWIO_REG_863263_SHFT  0
+#define HWIO_REG_863263_IN  in_dword_masked(\
+	HWIO_REG_863263_ADDR,\
+	HWIO_REG_863263_RMSK)
+#define HWIO_REG_863263_INM(m) \
+	in_dword_masked(HWIO_REG_863263_ADDR, m)
+#define HWIO_REG_863263_OUT(v) \
+	out_dword(HWIO_REG_863263_ADDR, v)
+#define HWIO_REG_863263_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_863263_ADDR, m, v,\
+	HWIO_REG_863263_IN);
+#define HWIO_REG_863263_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_863263_BASE_ADDR_SHFT   0
+
+#define HWIO_REG_135009_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007f8)
+#define HWIO_REG_135009_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f8)
+#define HWIO_REG_135009_RMSK  0x1ffff
+#define HWIO_REG_135009_SHFT  0
+#define HWIO_REG_135009_IN  in_dword_masked(\
+	HWIO_REG_135009_ADDR,\
+	HWIO_REG_135009_RMSK)
+#define HWIO_REG_135009_INM(m) \
+	in_dword_masked(HWIO_REG_135009_ADDR, m)
+#define HWIO_REG_135009_OUT(v) \
+	out_dword(HWIO_REG_135009_ADDR, v)
+#define HWIO_REG_135009_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_135009_ADDR, m, v,\
+	HWIO_REG_135009_IN);
+#define HWIO_REG_135009_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_135009_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_923883_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x000007fc)
+#define HWIO_REG_923883_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007fc)
+#define HWIO_REG_923883_RMSK  0x1ffff
+#define HWIO_REG_923883_SHFT  0
+#define HWIO_REG_923883_IN  in_dword_masked(\
+	HWIO_REG_923883_ADDR,\
+	HWIO_REG_923883_RMSK)
+#define HWIO_REG_923883_INM(m) \
+	in_dword_masked(HWIO_REG_923883_ADDR, m)
+#define HWIO_REG_923883_OUT(v) \
+	out_dword(HWIO_REG_923883_ADDR, v)
+#define HWIO_REG_923883_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_923883_ADDR, m, v,\
+	HWIO_REG_923883_IN);
+#define HWIO_REG_923883_BASE_ADDR_BMSK  0x1ffff
+#define HWIO_REG_923883_BASE_ADDR_SHFT  0
+
+#define HWIO_REG_934655_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000818)
+#define HWIO_REG_934655_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000818)
+#define HWIO_REG_934655_RMSK  0x1fff
+#define HWIO_REG_934655_SHFT  0
+#define HWIO_REG_934655_IN \
+	in_dword_masked(HWIO_REG_934655_ADDR, HWIO_REG_934655_RMSK)
+#define HWIO_REG_934655_INM(m) \
+	in_dword_masked(HWIO_REG_934655_ADDR, m)
+#define HWIO_REG_934655_OUT(v) \
+	out_dword(HWIO_REG_934655_ADDR, v)
+#define HWIO_REG_934655_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_934655_ADDR, m, v, HWIO_REG_934655_IN);
+#define HWIO_REG_934655_FRAME_WIDTH_BMSK  0x1fff
+#define HWIO_REG_934655_FRAME_WIDTH_SHFT  0
+
+#define HWIO_REG_179070_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000081c)
+#define HWIO_REG_179070_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000081c)
+#define HWIO_REG_179070_RMSK  0x1fff
+#define HWIO_REG_179070_SHFT  0
+#define HWIO_REG_179070_IN  in_dword_masked(\
+	HWIO_REG_179070_ADDR, HWIO_REG_179070_RMSK)
+#define HWIO_REG_179070_INM(m) \
+	in_dword_masked(HWIO_REG_179070_ADDR, m)
+#define HWIO_REG_179070_OUT(v) \
+	out_dword(HWIO_REG_179070_ADDR, v)
+#define HWIO_REG_179070_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_179070_ADDR, m, v, HWIO_REG_179070_IN);
+#define HWIO_REG_179070_FRAME_HEIGHT_BMSK  0x1fff
+#define HWIO_REG_179070_FRAME_HEIGHT_SHFT  0
+
+#define HWIO_REG_63643_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000830)
+#define HWIO_REG_63643_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000830)
+#define HWIO_REG_63643_RMSK  0xff3f
+#define HWIO_REG_63643_SHFT  0
+#define HWIO_REG_63643_IN  in_dword_masked(\
+	HWIO_REG_63643_ADDR, HWIO_REG_63643_RMSK)
+#define HWIO_REG_63643_INM(m) \
+	in_dword_masked(HWIO_REG_63643_ADDR, m)
+#define HWIO_REG_63643_OUT(v) \
+	out_dword(HWIO_REG_63643_ADDR, v)
+#define HWIO_REG_63643_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_63643_ADDR, m, v, HWIO_REG_63643_IN);
+#define HWIO_REG_63643_LEVEL_BMSK    0xff00
+#define HWIO_REG_63643_LEVEL_SHFT    0x8
+#define HWIO_REG_63643_PROFILE_BMSK  0x3f
+#define HWIO_REG_63643_PROFILE_SHFT  0
+
+#define HWIO_REG_786024_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000083c)
+#define HWIO_REG_786024_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000083c)
+#define HWIO_REG_786024_RMSK  0x1
+#define HWIO_REG_786024_SHFT  0
+#define HWIO_REG_786024_IN  in_dword_masked(\
+	HWIO_REG_786024_ADDR, HWIO_REG_786024_RMSK)
+#define HWIO_REG_786024_INM(m) \
+	in_dword_masked(HWIO_REG_786024_ADDR, m)
+#define HWIO_REG_786024_OUT(v) \
+	out_dword(HWIO_REG_786024_ADDR, v)
+#define HWIO_REG_786024_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_786024_ADDR, m, v, HWIO_REG_786024_IN);
+#define HWIO_REG_786024_FIELD_BMSK  0x1
+#define HWIO_REG_786024_FIELD_SHFT  0
+
+#define HWIO_REG_152500_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000848)
+#define HWIO_REG_152500_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000848)
+#define HWIO_REG_152500_RMSK  0x3
+#define HWIO_REG_152500_SHFT  0
+#define HWIO_REG_152500_IN  in_dword_masked(\
+	HWIO_REG_152500_ADDR, HWIO_REG_152500_RMSK)
+#define HWIO_REG_152500_INM(m) \
+	in_dword_masked(HWIO_REG_152500_ADDR, m)
+#define HWIO_REG_152500_OUT(v) \
+	out_dword(HWIO_REG_152500_ADDR, v)
+#define HWIO_REG_152500_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_152500_ADDR, m, v, HWIO_REG_152500_IN);
+#define HWIO_REG_152500_LF_CONTROL_BMSK  0x3
+#define HWIO_REG_152500_LF_CONTROL_SHFT  0
+
+#define HWIO_REG_266285_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000084c)
+#define HWIO_REG_266285_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000084c)
+#define HWIO_REG_266285_RMSK  0x1f
+#define HWIO_REG_266285_SHFT  0
+#define HWIO_REG_266285_IN  in_dword_masked(\
+	HWIO_REG_266285_ADDR, HWIO_REG_266285_RMSK)
+#define HWIO_REG_266285_INM(m) \
+	in_dword_masked(HWIO_REG_266285_ADDR, m)
+#define HWIO_REG_266285_OUT(v) \
+	out_dword(HWIO_REG_266285_ADDR, v)
+#define HWIO_REG_266285_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_266285_ADDR, m, v, HWIO_REG_266285_IN);
+#define HWIO_REG_266285_LF_ALPHAS_OFF_BMSK  0x1f
+#define HWIO_REG_266285_LF_ALPHAS_OFF_SHFT  0
+
+#define HWIO_REG_964731_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000850)
+#define HWIO_REG_964731_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000850)
+#define HWIO_REG_964731_RMSK  0x1f
+#define HWIO_REG_964731_SHFT  0
+#define HWIO_REG_964731_IN  in_dword_masked(\
+	HWIO_REG_964731_ADDR, HWIO_REG_964731_RMSK)
+#define HWIO_REG_964731_INM(m) \
+	in_dword_masked(HWIO_REG_964731_ADDR, m)
+#define HWIO_REG_964731_OUT(v) \
+	out_dword(HWIO_REG_964731_ADDR, v)
+#define HWIO_REG_964731_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_964731_ADDR, m, v, HWIO_REG_964731_IN);
+#define HWIO_REG_964731_LF_BETA_OFF_BMSK  0x1f
+#define HWIO_REG_964731_LF_BETA_OFF_SHFT  0
+
+#define HWIO_REG_919924_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000c30)
+#define HWIO_REG_919924_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000c30)
+#define HWIO_REG_919924_RMSK  0xffffffff
+#define HWIO_REG_919924_SHFT  0
+#define HWIO_REG_919924_IN  in_dword_masked(\
+	HWIO_REG_919924_ADDR, HWIO_REG_919924_RMSK)
+#define HWIO_REG_919924_INM(m) \
+	in_dword_masked(HWIO_REG_919924_ADDR, m)
+#define HWIO_REG_919924_OUT(v) \
+	out_dword(HWIO_REG_919924_ADDR, v)
+#define HWIO_REG_919924_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_919924_ADDR, m, v, HWIO_REG_919924_IN);
+#define HWIO_REG_919924_VIDC_QP_OFFSET_BMSK  0xffffffff
+#define HWIO_REG_919924_VIDC_QP_OFFSET_SHFT  0
+
+#define HWIO_REG_143629_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000c34)
+#define HWIO_REG_143629_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000c34)
+#define HWIO_REG_143629_RMSK  0x1
+#define HWIO_REG_143629_SHFT  0
+#define HWIO_REG_143629_IN  in_dword_masked(\
+	HWIO_REG_143629_ADDR, HWIO_REG_143629_RMSK)
+#define HWIO_REG_143629_INM(m) \
+	in_dword_masked(HWIO_REG_143629_ADDR, m)
+#define HWIO_REG_143629_OUT(v) \
+	out_dword(HWIO_REG_143629_ADDR, v)
+#define HWIO_REG_143629_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_143629_ADDR, m, v, HWIO_REG_143629_IN);
+#define HWIO_REG_143629_REG_143629_BMSK  0x1
+#define HWIO_REG_143629_REG_143629_SHFT  0
+
+#define HWIO_REG_607589_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002000)
+#define HWIO_REG_607589_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002000)
+#define HWIO_REG_607589_RMSK  0xffffffff
+#define HWIO_REG_607589_SHFT  0
+#define HWIO_REG_607589_IN  in_dword_masked(\
+	HWIO_REG_607589_ADDR, HWIO_REG_607589_RMSK)
+#define HWIO_REG_607589_INM(m) \
+	in_dword_masked(HWIO_REG_607589_ADDR, m)
+#define HWIO_REG_607589_OUT(v) \
+	out_dword(HWIO_REG_607589_ADDR, v)
+#define HWIO_REG_607589_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_607589_ADDR, m, v, HWIO_REG_607589_IN);
+#define HWIO_REG_607589_RTN_CHID_BMSK  0xffffffff
+#define HWIO_REG_607589_RTN_CHID_SHFT  0
+
+#define HWIO_REG_845544_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002004)
+#define HWIO_REG_845544_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002004)
+#define HWIO_REG_845544_RMSK  0xffffffff
+#define HWIO_REG_845544_SHFT  0
+#define HWIO_REG_845544_IN  in_dword_masked(\
+	HWIO_REG_845544_ADDR, HWIO_REG_845544_RMSK)
+#define HWIO_REG_845544_INM(m) \
+	in_dword_masked(HWIO_REG_845544_ADDR, m)
+#define HWIO_REG_845544_OUT(v) \
+	out_dword(HWIO_REG_845544_ADDR, v)
+#define HWIO_REG_845544_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_845544_ADDR, m, v, HWIO_REG_845544_IN);
+#define HWIO_REG_845544_REG_845544_BMSK  0xffffffff
+#define HWIO_REG_845544_REG_845544_SHFT  0
+
+#define HWIO_REG_859906_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002008)
+#define HWIO_REG_859906_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002008)
+#define HWIO_REG_859906_RMSK  0xffffffff
+#define HWIO_REG_859906_SHFT  0
+#define HWIO_REG_859906_IN  in_dword_masked(\
+	HWIO_REG_859906_ADDR, HWIO_REG_859906_RMSK)
+#define HWIO_REG_859906_INM(m) \
+	in_dword_masked(HWIO_REG_859906_ADDR, m)
+#define HWIO_REG_859906_OUT(v) \
+	out_dword(HWIO_REG_859906_ADDR, v)
+#define HWIO_REG_859906_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_859906_ADDR, m, v, HWIO_REG_859906_IN);
+#define HWIO_REG_859906_REG_859906_BMSK  0xffffffff
+#define HWIO_REG_859906_REG_859906_SHFT  0
+
+#define HWIO_REG_490078_ADDR  (VIDC_BLACKBIRD_REG_BASE + 0x0000200c)
+#define HWIO_REG_490078_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000200c)
+#define HWIO_REG_490078_RMSK  0xffffffff
+#define HWIO_REG_490078_SHFT  0
+#define HWIO_REG_490078_IN  in_dword_masked(\
+	HWIO_REG_490078_ADDR, HWIO_REG_490078_RMSK)
+#define HWIO_REG_490078_INM(m) \
+	in_dword_masked(HWIO_REG_490078_ADDR, m)
+#define HWIO_REG_490078_OUT(v) \
+	out_dword(HWIO_REG_490078_ADDR, v)
+#define HWIO_REG_490078_OUTM(m, v) \
+	out_dword_masked_ns(HWIO_REG_490078_ADDR, m, v,\
+	HWIO_REG_490078_IN);
+#define HWIO_REG_490078_REG_490078_BMSK  0xffffffff
+#define HWIO_REG_490078_REG_490078_SHFT  0
+
+#define HWIO_REG_640904_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002010)
+#define HWIO_REG_640904_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002010)
+#define HWIO_REG_640904_RMSK  0xffffffff
+#define HWIO_REG_640904_SHFT  0
+#define HWIO_REG_640904_IN  in_dword_masked(\
+	HWIO_REG_640904_ADDR, HWIO_REG_640904_RMSK)
+#define HWIO_REG_640904_INM(m) \
+	in_dword_masked(HWIO_REG_640904_ADDR, m)
+#define HWIO_REG_640904_OUT(v) \
+	out_dword(HWIO_REG_640904_ADDR, v)
+#define HWIO_REG_640904_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_640904_ADDR, m, v, HWIO_REG_640904_IN);
+#define HWIO_REG_640904_REG_640904_BMSK  0xffffffff
+#define HWIO_REG_640904_REG_640904_SHFT  0
+
+#define HWIO_REG_60114_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002014)
+#define HWIO_REG_60114_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002014)
+#define HWIO_REG_60114_RMSK  0xffffffff
+#define HWIO_REG_60114_SHFT  0
+#define HWIO_REG_60114_IN  in_dword_masked(\
+	HWIO_REG_60114_ADDR, HWIO_REG_60114_RMSK)
+#define HWIO_REG_60114_INM(m) \
+	in_dword_masked(HWIO_REG_60114_ADDR, m)
+#define HWIO_REG_60114_OUT(v) \
+	out_dword(HWIO_REG_60114_ADDR, v)
+#define HWIO_REG_60114_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_60114_ADDR, m, v, HWIO_REG_60114_IN);
+#define HWIO_REG_60114_REG_60114_BMSK  0xffffffff
+#define HWIO_REG_60114_REG_60114_SHFT  0
+
+#define HWIO_REG_489688_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002018)
+#define HWIO_REG_489688_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002018)
+#define HWIO_REG_489688_RMSK  0xffffffff
+#define HWIO_REG_489688_SHFT  0
+#define HWIO_REG_489688_IN  in_dword_masked(\
+	HWIO_REG_489688_ADDR, HWIO_REG_489688_RMSK)
+#define HWIO_REG_489688_INM(m) \
+	in_dword_masked(HWIO_REG_489688_ADDR, m)
+#define HWIO_REG_489688_OUT(v) \
+	out_dword(HWIO_REG_489688_ADDR, v)
+#define HWIO_REG_489688_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_489688_ADDR, m, v, HWIO_REG_489688_IN);
+#define HWIO_REG_489688_REG_489688_BMSK  0xffffffff
+#define HWIO_REG_489688_REG_489688_SHFT  0
+
+#define HWIO_REG_853667_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000201c)
+#define HWIO_REG_853667_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000201c)
+#define HWIO_REG_853667_RMSK  0xffffffff
+#define HWIO_REG_853667_SHFT  0
+#define HWIO_REG_853667_IN  in_dword_masked(\
+	HWIO_REG_853667_ADDR, HWIO_REG_853667_RMSK)
+#define HWIO_REG_853667_INM(m) \
+	in_dword_masked(HWIO_REG_853667_ADDR, m)
+#define HWIO_REG_853667_OUT(v) \
+	out_dword(HWIO_REG_853667_ADDR, v)
+#define HWIO_REG_853667_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_853667_ADDR, m, v, HWIO_REG_853667_IN);
+#define HWIO_REG_853667_REG_853667_BMSK  0xffffffff
+#define HWIO_REG_853667_REG_853667_SHFT  0
+
+#define HWIO_REG_760102_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002020)
+#define HWIO_REG_760102_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002020)
+#define HWIO_REG_760102_RMSK  0xffffffff
+#define HWIO_REG_760102_SHFT  0
+#define HWIO_REG_760102_IN  in_dword_masked(\
+	HWIO_REG_760102_ADDR, HWIO_REG_760102_RMSK)
+#define HWIO_REG_760102_INM(m) \
+	in_dword_masked(HWIO_REG_760102_ADDR, m)
+#define HWIO_REG_760102_OUT(v) \
+	out_dword(HWIO_REG_760102_ADDR, v)
+#define HWIO_REG_760102_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_760102_ADDR, m, v, HWIO_REG_760102_IN);
+#define HWIO_REG_760102_REG_760102_BMSK  0xffffffff
+#define HWIO_REG_760102_REG_760102_SHFT  0
+
+#define HWIO_REG_378318_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002024)
+#define HWIO_REG_378318_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002024)
+#define HWIO_REG_378318_RMSK  0xffffffff
+#define HWIO_REG_378318_SHFT  0
+#define HWIO_REG_378318_IN  in_dword_masked(\
+	HWIO_REG_378318_ADDR, HWIO_REG_378318_RMSK)
+#define HWIO_REG_378318_INM(m) \
+	in_dword_masked(HWIO_REG_378318_ADDR, m)
+#define HWIO_REG_378318_OUT(v) \
+	out_dword(HWIO_REG_378318_ADDR, v)
+#define HWIO_REG_378318_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_378318_ADDR, m, v, HWIO_REG_378318_IN);
+#define HWIO_REG_378318_REG_378318_BMSK  0xffffffff
+#define HWIO_REG_378318_REG_378318_SHFT  0
+
+#define HWIO_REG_203487_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002028)
+#define HWIO_REG_203487_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002028)
+#define HWIO_REG_203487_RMSK  0xffffffff
+#define HWIO_REG_203487_SHFT  0
+#define HWIO_REG_203487_IN  in_dword_masked(\
+	HWIO_REG_203487_ADDR, HWIO_REG_203487_RMSK)
+#define HWIO_REG_203487_INM(m) \
+	in_dword_masked(HWIO_REG_203487_ADDR, m)
+#define HWIO_REG_203487_OUT(v) \
+	out_dword(HWIO_REG_203487_ADDR, v)
+#define HWIO_REG_203487_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_203487_ADDR, m, v, HWIO_REG_203487_IN);
+#define HWIO_REG_203487_REG_203487_BMSK  0xffffffff
+#define HWIO_REG_203487_REG_203487_SHFT  0
+
+#define HWIO_REG_692991_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000202c)
+#define HWIO_REG_692991_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000202c)
+#define HWIO_REG_692991_RMSK  0xffffffff
+#define HWIO_REG_692991_SHFT  0
+#define HWIO_REG_692991_IN  in_dword_masked(\
+	HWIO_REG_692991_ADDR, HWIO_REG_692991_RMSK)
+#define HWIO_REG_692991_INM(m) \
+	in_dword_masked(HWIO_REG_692991_ADDR, m)
+#define HWIO_REG_692991_OUT(v) \
+	out_dword(HWIO_REG_692991_ADDR, v)
+#define HWIO_REG_692991_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_692991_ADDR, m, v, HWIO_REG_692991_IN);
+#define HWIO_REG_692991_REG_692991_BMSK  0xffffffff
+#define HWIO_REG_692991_REG_692991_SHFT  0
+
+#define HWIO_REG_161740_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002030)
+#define HWIO_REG_161740_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002030)
+#define HWIO_REG_161740_RMSK  0xffffffff
+#define HWIO_REG_161740_SHFT  0
+#define HWIO_REG_161740_IN  in_dword_masked(\
+	HWIO_REG_161740_ADDR, HWIO_REG_161740_RMSK)
+#define HWIO_REG_161740_INM(m) \
+	in_dword_masked(HWIO_REG_161740_ADDR, m)
+#define HWIO_REG_161740_OUT(v) \
+	out_dword(HWIO_REG_161740_ADDR, v)
+#define HWIO_REG_161740_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_161740_ADDR, m, v, HWIO_REG_161740_IN);
+#define HWIO_REG_161740_REG_161740_BMSK  0xffffffff
+#define HWIO_REG_161740_REG_161740_SHFT  0
+
+#define HWIO_REG_930239_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002034)
+#define HWIO_REG_930239_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002034)
+#define HWIO_REG_930239_RMSK  0xffffffff
+#define HWIO_REG_930239_SHFT  0
+#define HWIO_REG_930239_IN  in_dword_masked(\
+	HWIO_REG_930239_ADDR, HWIO_REG_930239_RMSK)
+#define HWIO_REG_930239_INM(m) \
+	in_dword_masked(HWIO_REG_930239_ADDR, m)
+#define HWIO_REG_930239_OUT(v) \
+	out_dword(HWIO_REG_930239_ADDR, v)
+#define HWIO_REG_930239_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_930239_ADDR, m, v, HWIO_REG_930239_IN);
+#define HWIO_REG_930239_REG_930239_BMSK  0xffffffff
+#define HWIO_REG_930239_REG_930239_SHFT  0
+
+#define HWIO_REG_567827_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002038)
+#define HWIO_REG_567827_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002038)
+#define HWIO_REG_567827_RMSK  0xffffffff
+#define HWIO_REG_567827_SHFT  0
+#define HWIO_REG_567827_IN  in_dword_masked(\
+	HWIO_REG_567827_ADDR, HWIO_REG_567827_RMSK)
+#define HWIO_REG_567827_INM(m) \
+	in_dword_masked(HWIO_REG_567827_ADDR, m)
+#define HWIO_REG_567827_OUT(v) \
+	out_dword(HWIO_REG_567827_ADDR, v)
+#define HWIO_REG_567827_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_567827_ADDR, m, v, HWIO_REG_567827_IN);
+#define HWIO_REG_567827_REG_567827_BMSK 0xffffffff
+#define HWIO_REG_567827_REG_567827_SHFT 0
+
+#define HWIO_REG_542997_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000203c)
+#define HWIO_REG_542997_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000203c)
+#define HWIO_REG_542997_RMSK  0xffffffff
+#define HWIO_REG_542997_SHFT  0
+#define HWIO_REG_542997_IN  in_dword_masked(\
+	HWIO_REG_542997_ADDR, HWIO_REG_542997_RMSK)
+#define HWIO_REG_542997_INM(m) \
+	in_dword_masked(HWIO_REG_542997_ADDR, m)
+#define HWIO_REG_542997_OUT(v) \
+	out_dword(HWIO_REG_542997_ADDR, v)
+#define HWIO_REG_542997_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_542997_ADDR, m, v, HWIO_REG_542997_IN);
+#define HWIO_REG_542997_REG_542997_BMSK  0xffffffff
+#define HWIO_REG_542997_REG_542997_SHFT  0
+
+#define HWIO_REG_666957_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002040)
+#define HWIO_REG_666957_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002040)
+#define HWIO_REG_666957_RMSK  0x7ffff
+#define HWIO_REG_666957_SHFT  0
+#define HWIO_REG_666957_IN  in_dword_masked(\
+	HWIO_REG_666957_ADDR, HWIO_REG_666957_RMSK)
+#define HWIO_REG_666957_INM(m) \
+	in_dword_masked(HWIO_REG_666957_ADDR, m)
+#define HWIO_REG_666957_OUT(v) \
+	out_dword(HWIO_REG_666957_ADDR, v)
+#define HWIO_REG_666957_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_666957_ADDR, m, v, HWIO_REG_666957_IN);
+#define HWIO_REG_666957_CH_DEC_TYPE_BMSK  0x70000
+#define HWIO_REG_666957_CH_DEC_TYPE_SHFT  0x10
+#define HWIO_REG_666957_CH_INST_ID_BMSK   0xffff
+#define HWIO_REG_666957_CH_INST_ID_SHFT   0
+
+#define HWIO_REG_117192_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002044)
+#define HWIO_REG_117192_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002044)
+#define HWIO_REG_117192_RMSK  0xffffffff
+#define HWIO_REG_117192_SHFT  0
+#define HWIO_REG_117192_IN  in_dword_masked(\
+	HWIO_REG_117192_ADDR, HWIO_REG_117192_RMSK)
+#define HWIO_REG_117192_INM(m) \
+	in_dword_masked(HWIO_REG_117192_ADDR, m)
+#define HWIO_REG_117192_OUT(v) \
+	out_dword(HWIO_REG_117192_ADDR, v)
+#define HWIO_REG_117192_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_117192_ADDR, m, v, HWIO_REG_117192_IN);
+#define HWIO_REG_117192_REG_117192_BMSK  0xffffffff
+#define HWIO_REG_117192_REG_117192_SHFT  0
+
+#define HWIO_REG_145068_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002048)
+#define HWIO_REG_145068_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002048)
+#define HWIO_REG_145068_RMSK  0xffffffff
+#define HWIO_REG_145068_SHFT  0
+#define HWIO_REG_145068_IN  in_dword_masked(\
+	HWIO_REG_145068_ADDR, HWIO_REG_145068_RMSK)
+#define HWIO_REG_145068_INM(m) \
+	in_dword_masked(HWIO_REG_145068_ADDR, m)
+#define HWIO_REG_145068_OUT(v) \
+	out_dword(HWIO_REG_145068_ADDR, v)
+#define HWIO_REG_145068_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_145068_ADDR, m, v, HWIO_REG_145068_IN);
+#define HWIO_REG_145068_REG_145068_BMSK  0xffffffff
+#define HWIO_REG_145068_REG_145068_SHFT  0
+
+#define HWIO_REG_921356_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000204c)
+#define HWIO_REG_921356_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000204c)
+#define HWIO_REG_921356_RMSK  0xffffffff
+#define HWIO_REG_921356_SHFT  0
+#define HWIO_REG_921356_IN  in_dword_masked(\
+	HWIO_REG_921356_ADDR, HWIO_REG_921356_RMSK)
+#define HWIO_REG_921356_INM(m) \
+	in_dword_masked(HWIO_REG_921356_ADDR, m)
+#define HWIO_REG_921356_OUT(v) \
+	out_dword(HWIO_REG_921356_ADDR, v)
+#define HWIO_REG_921356_OUTM(m, v) out_dword_masked_ns(\
+	HWIO_REG_921356_ADDR, m, v, HWIO_REG_921356_IN);
+#define HWIO_REG_921356_REG_921356_BMSK  0xffffffff
+#define HWIO_REG_921356_REG_921356_SHFT  0
+
+#define HWIO_REG_612810_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002050)
+#define HWIO_REG_612810_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002050)
+#define HWIO_REG_612810_RMSK  0xffffffff
+#define HWIO_REG_612810_SHFT  0
+#define HWIO_REG_612810_IN  in_dword_masked(\
+	HWIO_REG_612810_ADDR, HWIO_REG_612810_RMSK)
+#define HWIO_REG_612810_INM(m) \
+	in_dword_masked(HWIO_REG_612810_ADDR, m)
+#define HWIO_REG_612810_OUT(v) \
+	out_dword(HWIO_REG_612810_ADDR, v)
+#define HWIO_REG_612810_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_612810_ADDR, m, v, HWIO_REG_612810_IN);
+#define HWIO_REG_612810_REG_612810_BMSK  0xffffffff
+#define HWIO_REG_612810_REG_612810_SHFT  0
+
+#define HWIO_REG_175608_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002054)
+#define HWIO_REG_175608_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002054)
+#define HWIO_REG_175608_RMSK  0xffffffff
+#define HWIO_REG_175608_SHFT  0
+#define HWIO_REG_175608_IN  in_dword_masked(\
+	HWIO_REG_175608_ADDR, HWIO_REG_175608_RMSK)
+#define HWIO_REG_175608_INM(m) \
+	in_dword_masked(HWIO_REG_175608_ADDR, m)
+#define HWIO_REG_175608_OUT(v) \
+	out_dword(HWIO_REG_175608_ADDR, v)
+#define HWIO_REG_175608_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_175608_ADDR, m, v, HWIO_REG_175608_IN);
+#define HWIO_REG_175608_REG_175608_BMSK  0xffffffff
+#define HWIO_REG_175608_REG_175608_SHFT  0
+
+#define HWIO_REG_190381_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002058)
+#define HWIO_REG_190381_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002058)
+#define HWIO_REG_190381_RMSK  0xffffffff
+#define HWIO_REG_190381_SHFT  0
+#define HWIO_REG_190381_IN  in_dword_masked(\
+	HWIO_REG_190381_ADDR, HWIO_REG_190381_RMSK)
+#define HWIO_REG_190381_INM(m) \
+	in_dword_masked(HWIO_REG_190381_ADDR, m)
+#define HWIO_REG_190381_OUT(v) \
+	out_dword(HWIO_REG_190381_ADDR, v)
+#define HWIO_REG_190381_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_190381_ADDR, m, v, HWIO_REG_190381_IN);
+#define HWIO_REG_190381_REG_190381_BMSK  0xffffffff
+#define HWIO_REG_190381_REG_190381_SHFT  0
+
+#define HWIO_REG_85655_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000205c)
+#define HWIO_REG_85655_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000205c)
+#define HWIO_REG_85655_RMSK  0xffffffff
+#define HWIO_REG_85655_SHFT  0
+#define HWIO_REG_85655_IN  in_dword_masked(\
+	HWIO_REG_85655_ADDR, HWIO_REG_85655_RMSK)
+#define HWIO_REG_85655_INM(m) \
+	in_dword_masked(HWIO_REG_85655_ADDR, m)
+#define HWIO_REG_85655_OUT(v) \
+	out_dword(HWIO_REG_85655_ADDR, v)
+#define HWIO_REG_85655_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_85655_ADDR, m, v, HWIO_REG_85655_IN);
+#define HWIO_REG_85655_REG_85655_BMSK  0xffffffff
+#define HWIO_REG_85655_REG_85655_SHFT  0
+
+#define HWIO_REG_86830_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002060)
+#define HWIO_REG_86830_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002060)
+#define HWIO_REG_86830_RMSK  0xffffffff
+#define HWIO_REG_86830_SHFT  0
+#define HWIO_REG_86830_IN  in_dword_masked(\
+	HWIO_REG_86830_ADDR, HWIO_REG_86830_RMSK)
+#define HWIO_REG_86830_INM(m) \
+	in_dword_masked(HWIO_REG_86830_ADDR, m)
+#define HWIO_REG_86830_OUT(v) \
+	out_dword(HWIO_REG_86830_ADDR, v)
+#define HWIO_REG_86830_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_86830_ADDR, m, v, HWIO_REG_86830_IN);
+#define HWIO_REG_86830_REG_86830_BMSK  0xffffffff
+#define HWIO_REG_86830_REG_86830_SHFT  0
+
+#define HWIO_REG_889944_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002064)
+#define HWIO_REG_889944_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002064)
+#define HWIO_REG_889944_RMSK  0xffffffff
+#define HWIO_REG_889944_SHFT  0
+#define HWIO_REG_889944_IN  in_dword_masked(\
+	HWIO_REG_889944_ADDR, HWIO_REG_889944_RMSK)
+#define HWIO_REG_889944_INM(m) \
+	in_dword_masked(HWIO_REG_889944_ADDR, m)
+#define HWIO_REG_889944_OUT(v) \
+	out_dword(HWIO_REG_889944_ADDR, v)
+#define HWIO_REG_889944_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_889944_ADDR, m, v, HWIO_REG_889944_IN);
+#define HWIO_REG_889944_HOST_WR_ADDR_BMSK  0xffffffff
+#define HWIO_REG_889944_HOST_WR_ADSR_SHFT  0
+
+#define HWIO_REG_404623_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002068)
+#define HWIO_REG_404623_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002068)
+#define HWIO_REG_404623_RMSK  0xffffffff
+#define HWIO_REG_404623_SHFT  0
+#define HWIO_REG_404623_IN  in_dword_masked(\
+	HWIO_REG_404623_ADDR, HWIO_REG_404623_RMSK)
+#define HWIO_REG_404623_INM(m) \
+	in_dword_masked(HWIO_REG_404623_ADDR, m)
+#define HWIO_REG_404623_OUT(v) \
+	out_dword(HWIO_REG_404623_ADDR, v)
+#define HWIO_REG_404623_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_404623_ADDR, m, v, HWIO_REG_404623_IN);
+#define HWIO_REG_404623_REG_404623_BMSK  0xffffffff
+#define HWIO_REG_404623_REG_404623_SHFT  0
+
+#define HWIO_REG_397087_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000206c)
+#define HWIO_REG_397087_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000206c)
+#define HWIO_REG_397087_RMSK  0xffffffff
+#define HWIO_REG_397087_SHFT  0
+#define HWIO_REG_397087_IN  in_dword_masked(\
+	HWIO_REG_397087_ADDR, HWIO_REG_397087_RMSK)
+#define HWIO_REG_397087_INM(m) \
+	in_dword_masked(HWIO_REG_397087_ADDR, m)
+#define HWIO_REG_397087_OUT(v) \
+	out_dword(HWIO_REG_397087_ADDR, v)
+#define HWIO_REG_397087_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_397087_ADDR, m, v, HWIO_REG_397087_IN);
+#define HWIO_REG_397087_CMD_SEQ_NUM_BMSK  0xffffffff
+#define HWIO_REG_397087_CMD_SEQ_NUM_SHFT  0
+
+#define HWIO_REG_212613_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002070)
+#define HWIO_REG_212613_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002070)
+#define HWIO_REG_212613_RMSK  0xffffffff
+#define HWIO_REG_212613_SHFT  0
+#define HWIO_REG_212613_IN  in_dword_masked(\
+	HWIO_REG_212613_ADDR, HWIO_REG_212613_RMSK)
+#define HWIO_REG_212613_INM(m) \
+	in_dword_masked(HWIO_REG_212613_ADDR, m)
+#define HWIO_REG_212613_OUT(v) \
+	out_dword(HWIO_REG_212613_ADDR, v)
+#define HWIO_REG_212613_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_212613_ADDR, m, v, HWIO_REG_212613_IN);
+#define HWIO_REG_212613_REG_212613_BMSK  0xffffffff
+#define HWIO_REG_212613_REG_212613_SHFT  0
+
+#define HWIO_REG_840123_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002074)
+#define HWIO_REG_840123_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002074)
+#define HWIO_REG_840123_RMSK  0xffffffff
+#define HWIO_REG_840123_SHFT  0
+#define HWIO_REG_840123_IN  in_dword_masked(\
+	HWIO_REG_840123_ADDR, HWIO_REG_840123_RMSK)
+#define HWIO_REG_840123_INM(m) \
+	in_dword_masked(HWIO_REG_840123_ADDR, m)
+#define HWIO_REG_840123_OUT(v) \
+	out_dword(HWIO_REG_840123_ADDR, v)
+#define HWIO_REG_840123_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_840123_ADDR, m, v, HWIO_REG_840123_IN);
+#define HWIO_REG_840123_REG_840123_BMSK  0xffffffff
+#define HWIO_REG_840123_REG_840123_SHFT  0
+
+#define HWIO_REG_520335_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002078)
+#define HWIO_REG_520335_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002078)
+#define HWIO_REG_520335_RMSK  0xffffffff
+#define HWIO_REG_520335_SHFT  0
+#define HWIO_REG_520335_IN  in_dword_masked(\
+	HWIO_REG_520335_ADDR, HWIO_REG_520335_RMSK)
+#define HWIO_REG_520335_INM(m) \
+	in_dword_masked(HWIO_REG_520335_ADDR, m)
+#define HWIO_REG_520335_OUT(v) \
+	out_dword(HWIO_REG_520335_ADDR, v)
+#define HWIO_REG_520335_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_520335_ADDR, m, v, HWIO_REG_520335_IN);
+#define HWIO_REG_520335_REG_196943_BMSK  0xffffffff
+#define HWIO_REG_520335_REG_196943_SHFT  0
+
+#define HWIO_REG_196943_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000207c)
+#define HWIO_REG_196943_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000207c)
+#define HWIO_REG_196943_RMSK  0xffffffff
+#define HWIO_REG_196943_SHFT  0
+#define HWIO_REG_196943_IN  in_dword_masked(\
+	HWIO_REG_196943_ADDR, HWIO_REG_196943_RMSK)
+#define HWIO_REG_196943_INM(m) \
+	in_dword_masked(HWIO_REG_196943_ADDR, m)
+#define HWIO_REG_196943_OUT(v) \
+	out_dword(HWIO_REG_196943_ADDR, v)
+#define HWIO_REG_196943_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_196943_ADDR, m, v, HWIO_REG_196943_IN);
+#define HWIO_REG_196943_REG_196943_BMSK  0xffffffff
+#define HWIO_REG_196943_REG_196943_SHFT   0
+
+#define HWIO_REG_313350_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002080)
+#define HWIO_REG_313350_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002080)
+#define HWIO_REG_313350_RMSK  0x7ffff
+#define HWIO_REG_313350_SHFT  0
+#define HWIO_REG_313350_IN  in_dword_masked(\
+	HWIO_REG_313350_ADDR, HWIO_REG_313350_RMSK)
+#define HWIO_REG_313350_INM(m) \
+	in_dword_masked(HWIO_REG_313350_ADDR, m)
+#define HWIO_REG_313350_OUT(v) \
+	out_dword(HWIO_REG_313350_ADDR, v)
+#define HWIO_REG_313350_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_313350_ADDR, m, v, HWIO_REG_313350_IN);
+#define HWIO_REG_313350_CH_DEC_TYPE_BMSK  0x70000
+#define HWIO_REG_313350_CH_DEC_TYPE_SHFT  0x10
+#define HWIO_REG_313350_CH_INST_ID_BMSK   0xffff
+#define HWIO_REG_313350_CH_INST_ID_SHFT   0
+
+#define HWIO_REG_980194_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002084)
+#define HWIO_REG_980194_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002084)
+#define HWIO_REG_980194_RMSK  0xffffffff
+#define HWIO_REG_980194_SHFT  0
+#define HWIO_REG_980194_IN  in_dword_masked(\
+	HWIO_REG_980194_ADDR, HWIO_REG_980194_RMSK)
+#define HWIO_REG_980194_INM(m) \
+	in_dword_masked(HWIO_REG_980194_ADDR, m)
+#define HWIO_REG_980194_OUT(v) \
+	out_dword(HWIO_REG_980194_ADDR, v)
+#define HWIO_REG_980194_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_980194_ADDR, m, v, HWIO_REG_980194_IN);
+#define HWIO_REG_980194_REG_980194_BMSK  0xffffffff
+#define HWIO_REG_980194_REG_980194_SHFT  0
+
+#define HWIO_REG_936704_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002088)
+#define HWIO_REG_936704_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002088)
+#define HWIO_REG_936704_RMSK  0xffffffff
+#define HWIO_REG_936704_SHFT  0
+#define HWIO_REG_936704_IN  in_dword_masked(\
+	HWIO_REG_936704_ADDR, HWIO_REG_936704_RMSK)
+#define HWIO_REG_936704_INM(m) \
+	in_dword_masked(HWIO_REG_936704_ADDR, m)
+#define HWIO_REG_936704_OUT(v) \
+	out_dword(HWIO_REG_936704_ADDR, v)
+#define HWIO_REG_936704_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_936704_ADDR, m, v, HWIO_REG_936704_IN);
+#define HWIO_REG_936704_REG_936704_BMSK  0xffffffff
+#define HWIO_REG_936704_REG_936704_SHFT  0
+
+#define HWIO_REG_821977_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000208c)
+#define HWIO_REG_821977_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000208c)
+#define HWIO_REG_821977_RMSK  0xffffffff
+#define HWIO_REG_821977_SHFT  0
+#define HWIO_REG_821977_IN  in_dword_masked(\
+	HWIO_REG_821977_ADDR, HWIO_REG_821977_RMSK)
+#define HWIO_REG_821977_INM(m) \
+	in_dword_masked(HWIO_REG_821977_ADDR, m)
+#define HWIO_REG_821977_OUT(v) \
+	out_dword(HWIO_REG_821977_ADDR, v)
+#define HWIO_REG_821977_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_821977_ADDR, m, v, HWIO_REG_821977_IN);
+#define HWIO_REG_821977_REG_821977_BMSK  0xffffffff
+#define HWIO_REG_821977_REG_821977_SHFT  0
+
+#define HWIO_REG_655721_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002090)
+#define HWIO_REG_655721_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002090)
+#define HWIO_REG_655721_RMSK  0xffffffff
+#define HWIO_REG_655721_SHFT  0
+#define HWIO_REG_655721_IN  in_dword_masked(\
+	HWIO_REG_655721_ADDR, HWIO_REG_655721_RMSK)
+#define HWIO_REG_655721_INM(m) \
+	in_dword_masked(HWIO_REG_655721_ADDR, m)
+#define HWIO_REG_655721_OUT(v) \
+	out_dword(HWIO_REG_655721_ADDR, v)
+#define HWIO_REG_655721_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_655721_ADDR, m, v, HWIO_REG_655721_IN);
+#define HWIO_REG_655721_REG_655721_BMSK  0xffffffff
+#define HWIO_REG_655721_REG_655721_SHFT  0
+
+#define HWIO_REG_548308_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002094)
+#define HWIO_REG_548308_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002094)
+#define HWIO_REG_548308_RMSK  0xffffffff
+#define HWIO_REG_548308_SHFT  0
+#define HWIO_REG_548308_IN  in_dword_masked(\
+	HWIO_REG_548308_ADDR, HWIO_REG_548308_RMSK)
+#define HWIO_REG_548308_INM(m) \
+	in_dword_masked(HWIO_REG_548308_ADDR, m)
+#define HWIO_REG_548308_OUT(v) \
+	out_dword(HWIO_REG_548308_ADDR, v)
+#define HWIO_REG_548308_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_548308_ADDR, m, v, HWIO_REG_548308_IN);
+#define HWIO_REG_548308_REG_548308_BMSK  0xffffffff
+#define HWIO_REG_548308_REG_548308_SHFT  0
+
+#define HWIO_REG_887095_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002098)
+#define HWIO_REG_887095_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002098)
+#define HWIO_REG_887095_RMSK  0xffffffff
+#define HWIO_REG_887095_SHFT  0
+#define HWIO_REG_887095_IN  in_dword_masked(\
+	HWIO_REG_887095_ADDR, HWIO_REG_887095_RMSK)
+#define HWIO_REG_887095_INM(m) \
+	in_dword_masked(HWIO_REG_887095_ADDR, m)
+#define HWIO_REG_887095_OUT(v) \
+	out_dword(HWIO_REG_887095_ADDR, v)
+#define HWIO_REG_887095_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_887095_ADDR, m, v, HWIO_REG_887095_IN);
+#define HWIO_REG_887095_REG_887095_BMSK  0xffffffff
+#define HWIO_REG_887095_REG_887095_SHFT  0
+
+#define HWIO_REG_576987_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000209c)
+#define HWIO_REG_576987_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000209c)
+#define HWIO_REG_576987_RMSK  0xffffffff
+#define HWIO_REG_576987_SHFT 0
+#define HWIO_REG_576987_IN  in_dword_masked(\
+	HWIO_REG_576987_ADDR, HWIO_REG_576987_RMSK)
+#define HWIO_REG_576987_INM(m) \
+	in_dword_masked(HWIO_REG_576987_ADDR, m)
+#define HWIO_REG_576987_OUT(v) \
+	out_dword(HWIO_REG_576987_ADDR, v)
+#define HWIO_REG_576987_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_576987_ADDR, m, v, HWIO_REG_576987_IN);
+#define HWIO_REG_576987_REG_576987_BMSK  0xffffffff
+#define HWIO_REG_576987_REG_576987_SHFT  0
+
+#define HWIO_REG_70448_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a0)
+#define HWIO_REG_70448_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a0)
+#define HWIO_REG_70448_RMSK  0xffffffff
+#define HWIO_REG_70448_SHFT  0
+#define HWIO_REG_70448_IN  in_dword_masked(\
+	HWIO_REG_70448_ADDR, HWIO_REG_70448_RMSK)
+#define HWIO_REG_70448_INM(m) \
+	in_dword_masked(HWIO_REG_70448_ADDR, m)
+#define HWIO_REG_70448_OUT(v) \
+	out_dword(HWIO_REG_70448_ADDR, v)
+#define HWIO_REG_70448_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_70448_ADDR, m, v, HWIO_REG_70448_IN);
+#define HWIO_REG_70448_REG_70448_BMSK  0xffffffff
+#define HWIO_REG_70448_REG_70448_SHFT  0
+
+#define HWIO_REG_652528_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a4)
+#define HWIO_REG_652528_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a4)
+#define HWIO_REG_652528_RMSK  0xffffffff
+#define HWIO_REG_652528_SHFT  0
+#define HWIO_REG_652528_IN  in_dword_masked(\
+	HWIO_REG_652528_ADDR, HWIO_REG_652528_RMSK)
+#define HWIO_REG_652528_INM(m) \
+	in_dword_masked(HWIO_REG_652528_ADDR, m)
+#define HWIO_REG_652528_OUT(v) \
+	out_dword(HWIO_REG_652528_ADDR, v)
+#define HWIO_REG_652528_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_652528_ADDR, m, v , HWIO_REG_652528_IN);
+#define HWIO_REG_652528_REG_652528_BMSK  0xffffffff
+#define HWIO_REG_652528_REG_652528_SHFT  0
+
+#define HWIO_REG_220637_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a8)
+#define HWIO_REG_220637_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a8)
+#define HWIO_REG_220637_RMSK  0xffffffff
+#define HWIO_REG_220637_SHFT  0
+#define HWIO_REG_220637_IN  in_dword_masked(\
+	HWIO_REG_220637_ADDR, HWIO_REG_220637_RMSK)
+#define HWIO_REG_220637_INM(m) \
+	in_dword_masked(HWIO_REG_220637_ADDR, m)
+#define HWIO_REG_220637_OUT(v) \
+	out_dword(HWIO_REG_220637_ADDR, v)
+#define HWIO_REG_220637_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_220637_ADDR, m, v, HWIO_REG_220637_IN);
+#define HWIO_REG_220637_REG_220637_BMSK  0xffffffff
+#define HWIO_REG_220637_REG_220637_SHFT  0
+
+#define HWIO_REG_254093_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020ac)
+#define HWIO_REG_254093_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020ac)
+#define HWIO_REG_254093_RMSK  0xffffffff
+#define HWIO_REG_254093_SHFT  0
+#define HWIO_REG_254093_IN  in_dword_masked(\
+	HWIO_REG_254093_ADDR, HWIO_REG_254093_RMSK)
+#define HWIO_REG_254093_INM(m) \
+	in_dword_masked(HWIO_REG_254093_ADDR, m)
+#define HWIO_REG_254093_OUT(v) \
+	out_dword(HWIO_REG_254093_ADDR, v)
+#define HWIO_REG_254093_OUTM(m, v)  out_dword_masked_ns\
+	(HWIO_REG_254093_ADDR, m, v, HWIO_REG_254093_IN);
+#define HWIO_REG_254093_REG_254093_BMSK  0xffffffff
+#define HWIO_REG_254093_REG_254093_SHFT  0
+
+#define HWIO_REG_160474_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b0)
+#define HWIO_REG_160474_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b0)
+#define HWIO_REG_160474_RMSK  0xffffffff
+#define HWIO_REG_160474_SHFT  0
+#define HWIO_REG_160474_IN  in_dword_masked(\
+	HWIO_REG_160474_ADDR, HWIO_REG_160474_RMSK)
+#define HWIO_REG_160474_INM(m) \
+	in_dword_masked(HWIO_REG_160474_ADDR, m)
+#define HWIO_REG_160474_OUT(v) \
+	out_dword(HWIO_REG_160474_ADDR, v)
+#define HWIO_REG_160474_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_160474_ADDR, m, v, HWIO_REG_160474_IN);
+#define HWIO_REG_160474_REG_160474_BMSK  0xffffffff
+#define HWIO_REG_160474_REG_160474_SHFT  0
+
+#define HWIO_REG_39027_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b4)
+#define HWIO_REG_39027_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b4)
+#define HWIO_REG_39027_RMSK  0xffffffff
+#define HWIO_REG_39027_SHFT  0
+#define HWIO_REG_39027_IN  in_dword_masked(\
+	HWIO_REG_39027_ADDR, HWIO_REG_39027_RMSK)
+#define HWIO_REG_39027_INM(m) \
+	in_dword_masked(HWIO_REG_39027_ADDR, m)
+#define HWIO_REG_39027_OUT(v) \
+	out_dword(HWIO_REG_39027_ADDR, v)
+#define HWIO_REG_39027_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_39027_ADDR, m, v, HWIO_REG_39027_IN);
+#define HWIO_REG_39027_REG_39027_BMSK  0xffffffff
+#define HWIO_REG_39027_REG_39027_SHFT  0
+
+#define HWIO_REG_74049_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b8)
+#define HWIO_REG_74049_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b8)
+#define HWIO_REG_74049_RMSK  0xffffffff
+#define HWIO_REG_74049_SHFT  0
+#define HWIO_REG_74049_IN  in_dword_masked(\
+	HWIO_REG_74049_ADDR, HWIO_REG_74049_RMSK)
+#define HWIO_REG_74049_INM(m) \
+	in_dword_masked(HWIO_REG_74049_ADDR, m)
+#define HWIO_REG_74049_OUT(v) \
+	out_dword(HWIO_REG_74049_ADDR, v)
+#define HWIO_REG_74049_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_74049_ADDR, m, v, HWIO_REG_74049_IN);
+#define HWIO_REG_74049_REG_74049_BMSK  0xffffffff
+#define HWIO_REG_74049_REG_74049_SHFT  0
+
+#define HWIO_REG_697870_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020bc)
+#define HWIO_REG_697870_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020bc)
+#define HWIO_REG_697870_RMSK  0xffffffff
+#define HWIO_REG_697870_SHFT  0
+#define HWIO_REG_697870_IN  in_dword_masked(\
+	HWIO_REG_697870_ADDR, HWIO_REG_697870_RMSK)
+#define HWIO_REG_697870_INM(m) \
+	in_dword_masked(HWIO_REG_697870_ADDR, m)
+#define HWIO_REG_697870_OUT(v) \
+	out_dword(HWIO_REG_697870_ADDR, v)
+#define HWIO_REG_697870_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_697870_ADDR, m, v, HWIO_REG_697870_IN);
+#define HWIO_REG_697870_REG_697870_BMSK  0xffffffff
+#define HWIO_REG_697870_REG_697870_SHFT  0
+
+#define HWIO_REG_783891_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c504)
+#define HWIO_REG_783891_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c504)
+#define HWIO_REG_783891_RMSK  0x7ffff
+#define HWIO_REG_783891_SHFT  0
+#define HWIO_REG_783891_IN  in_dword_masked(\
+	HWIO_REG_783891_ADDR, HWIO_REG_783891_RMSK)
+#define HWIO_REG_783891_INM(m) \
+	in_dword_masked(HWIO_REG_783891_ADDR, m)
+#define HWIO_REG_783891_OUT(v) \
+	out_dword(HWIO_REG_783891_ADDR, v)
+#define HWIO_REG_783891_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_783891_ADDR, m, v, HWIO_REG_783891_IN);
+#define HWIO_REG_783891_ENC_PIC_TYPE_USE_BMSK  0x40000
+#define HWIO_REG_783891_ENC_PIC_TYPE_USE_SHFT  0x12
+#define HWIO_REG_783891_B_FRM_CTRL_BMSK        0x30000
+#define HWIO_REG_783891_B_FRM_CTRL_SHFT        0x10
+#define HWIO_REG_783891_I_FRM_CTRL_BMSK        0xffff
+#define HWIO_REG_783891_I_FRM_CTRL_SHFT        0
+
+#define HWIO_REG_226332_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c50c)
+#define HWIO_REG_226332_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c50c)
+#define HWIO_REG_226332_RMSK  0x7
+#define HWIO_REG_226332_SHFT  0
+#define HWIO_REG_226332_IN  in_dword_masked(\
+	HWIO_REG_226332_ADDR, HWIO_REG_226332_RMSK)
+#define HWIO_REG_226332_INM(m)  in_dword_masked(HWIO_REG_226332_ADDR, m)
+#define HWIO_REG_226332_OUT(v)  out_dword(HWIO_REG_226332_ADDR, v)
+#define HWIO_REG_226332_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_226332_ADDR, m, v, HWIO_REG_226332_IN);
+#define HWIO_REG_226332_MSLICE_MODE_BMSK  0x6
+#define HWIO_REG_226332_MSLICE_MODE_SHFT  0x1
+#define HWIO_REG_226332_MSLICE_ENA_BMSK   0x1
+#define HWIO_REG_226332_MSLICE_ENA_SHFT   0
+
+#define HWIO_REG_696136_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c510)
+#define HWIO_REG_696136_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c510)
+#define HWIO_REG_696136_RMSK  0xffff
+#define HWIO_REG_696136_SHFT  0
+#define HWIO_REG_696136_IN  in_dword_masked(\
+	HWIO_REG_696136_ADDR, HWIO_REG_696136_RMSK)
+#define HWIO_REG_696136_INM(m)  in_dword_masked(HWIO_REG_696136_ADDR, m)
+#define HWIO_REG_696136_OUT(v)  out_dword(HWIO_REG_696136_ADDR, v)
+#define HWIO_REG_696136_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_696136_ADDR, m, v, HWIO_REG_696136_IN);
+#define HWIO_REG_696136_MSLICE_MB_BMSK  0xffff
+#define HWIO_REG_696136_MSLICE_MB_SHFT  0
+
+#define HWIO_REG_515564_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c514)
+#define HWIO_REG_515564_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c514)
+#define HWIO_REG_515564_RMSK  0xffffffff
+#define HWIO_REG_515564_SHFT  0
+#define HWIO_REG_515564_IN  in_dword_masked(\
+	HWIO_REG_515564_ADDR, HWIO_REG_515564_RMSK)
+#define HWIO_REG_515564_INM(m) \
+	in_dword_masked(HWIO_REG_515564_ADDR, m)
+#define HWIO_REG_515564_OUT(v)  out_dword(HWIO_REG_515564_ADDR, v)
+#define HWIO_REG_515564_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_515564_ADDR, m, v, HWIO_REG_515564_IN);
+#define HWIO_REG_515564_MSLICE_BIT_BMSK  0xffffffff
+#define HWIO_REG_515564_MSLICE_BIT_SHFT  0
+
+#define HWIO_REG_886210_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c518)
+#define HWIO_REG_886210_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c518)
+#define HWIO_REG_886210_RMSK  0xffff
+#define HWIO_REG_886210_SHFT  0
+#define HWIO_REG_886210_IN  in_dword_masked(\
+	HWIO_REG_886210_ADDR, HWIO_REG_886210_RMSK)
+#define HWIO_REG_886210_INM(m)  in_dword_masked(HWIO_REG_886210_ADDR, m)
+#define HWIO_REG_886210_OUT(v)  out_dword(HWIO_REG_886210_ADDR, v)
+#define HWIO_REG_886210_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_886210_ADDR, m, v, HWIO_REG_886210_IN);
+#define HWIO_REG_886210_CIR_NUM_BMSK  0xffff
+#define HWIO_REG_886210_CIR_NUM_SHFT  0
+
+#define HWIO_REG_645603_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c51c)
+#define HWIO_REG_645603_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c51c)
+#define HWIO_REG_645603_RMSK  0x3
+#define HWIO_REG_645603_SHFT  0
+#define HWIO_REG_645603_IN  in_dword_masked(\
+	HWIO_REG_645603_ADDR, HWIO_REG_645603_RMSK)
+#define HWIO_REG_645603_INM(m) \
+	in_dword_masked(HWIO_REG_645603_ADDR, m)
+#define HWIO_REG_645603_OUT(v)  out_dword(HWIO_REG_645603_ADDR, v)
+#define HWIO_REG_645603_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_645603_ADDR, m, v, HWIO_REG_645603_IN);
+#define HWIO_REG_645603_REG_645603_BMSK  0x3
+#define HWIO_REG_645603_REG_645603_SHFT  0
+
+#define HWIO_REG_811733_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c520)
+#define HWIO_REG_811733_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c520)
+#define HWIO_REG_811733_RMSK  0x80ffffff
+#define HWIO_REG_811733_SHFT  0
+#define HWIO_REG_811733_IN  in_dword_masked(\
+	HWIO_REG_811733_ADDR, HWIO_REG_811733_RMSK)
+#define HWIO_REG_811733_INM(m) \
+	in_dword_masked(HWIO_REG_811733_ADDR, m)
+#define HWIO_REG_811733_OUT(v)  out_dword(HWIO_REG_811733_ADDR, v)
+#define HWIO_REG_811733_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_811733_ADDR, m, v, HWIO_REG_811733_IN);
+#define HWIO_REG_811733_PAD_CTRL_ON_BMSK    0x80000000
+#define HWIO_REG_811733_PAD_CTRL_ON_SHFT    0x1f
+#define HWIO_REG_811733_CR_PAD_VIDC_BMSK    0xff0000
+#define HWIO_REG_811733_CR_PAD_VIDC_SHFT    0x10
+#define HWIO_REG_811733_CB_PAD_VIDC_BMSK    0xff00
+#define HWIO_REG_811733_CB_PAD_VIDC_SHFT    0x8
+#define HWIO_REG_811733_LUMA_PAD_VIDC_BMSK  0xff
+#define HWIO_REG_811733_LUMA_PAD_VIDC_SHFT  0
+
+#define HWIO_REG_676866_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c588)
+#define HWIO_REG_676866_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c588)
+#define HWIO_REG_676866_RMSK  0xffff
+#define HWIO_REG_676866_SHFT  0
+#define HWIO_REG_676866_IN  in_dword_masked(\
+	HWIO_REG_676866_ADDR, HWIO_REG_676866_RMSK)
+#define HWIO_REG_676866_INM(m) \
+	in_dword_masked(HWIO_REG_676866_ADDR, m)
+#define HWIO_REG_676866_OUT(v) \
+	out_dword(HWIO_REG_676866_ADDR, v)
+#define HWIO_REG_676866_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_676866_ADDR, m, v, HWIO_REG_676866_IN);
+#define HWIO_REG_676866_REG_676866_BMSK  0xffff
+#define HWIO_REG_676866_REG_676866_SHFT  0
+
+#define HWIO_REG_54267_ADDR \
+	(VIDC_BLACKBIRD_REG_BASE + 0x0000c58c)
+#define HWIO_REG_54267_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c58c)
+#define HWIO_REG_54267_RMSK  0xffff
+#define HWIO_REG_54267_SHFT  0
+#define HWIO_REG_54267_IN  in_dword_masked(\
+	HWIO_REG_54267_ADDR,\
+	HWIO_REG_54267_RMSK)
+#define HWIO_REG_54267_INM(m) \
+	in_dword_masked(HWIO_REG_54267_ADDR, m)
+#define HWIO_REG_54267_OUT(v) \
+	out_dword(HWIO_REG_54267_ADDR, v)
+#define HWIO_REG_54267_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_54267_ADDR, m, v,\
+	HWIO_REG_54267_IN);
+#define HWIO_REG_54267_REG_54267_BMSK  0xffff
+#define HWIO_REG_54267_REG_54267_SHFT  0
+
+#define HWIO_REG_559908_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5a0)
+#define HWIO_REG_559908_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5a0)
+#define HWIO_REG_559908_RMSK  0x33f
+#define HWIO_REG_559908_SHFT  0
+#define HWIO_REG_559908_IN  in_dword_masked(\
+	HWIO_REG_559908_ADDR, HWIO_REG_559908_RMSK)
+#define HWIO_REG_559908_INM(m)  in_dword_masked(HWIO_REG_559908_ADDR, m)
+#define HWIO_REG_559908_OUT(v)  out_dword(HWIO_REG_559908_ADDR, v)
+#define HWIO_REG_559908_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_559908_ADDR, m, v, HWIO_REG_559908_IN);
+#define HWIO_REG_559908_FR_RC_EN_BMSK  0x200
+#define HWIO_REG_559908_FR_RC_EN_SHFT  0x9
+#define HWIO_REG_559908_MB_RC_EN_BMSK  0x100
+#define HWIO_REG_559908_MB_RC_EN_SHFT  0x8
+#define HWIO_REG_559908_FRAME_QP_BMSK  0x3f
+#define HWIO_REG_559908_FRAME_QP_SHFT  0
+
+#define HWIO_REG_977937_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d0d0)
+#define HWIO_REG_977937_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d0d0)
+#define HWIO_REG_977937_RMSK  0xff
+#define HWIO_REG_977937_SHFT  0
+#define HWIO_REG_977937_IN  in_dword_masked(\
+	HWIO_REG_977937_ADDR, HWIO_REG_977937_RMSK)
+#define HWIO_REG_977937_INM(m)  in_dword_masked(HWIO_REG_977937_ADDR, m)
+#define HWIO_REG_977937_OUT(v)  out_dword(HWIO_REG_977937_ADDR, v)
+#define HWIO_REG_977937_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_977937_ADDR, m, v, HWIO_REG_977937_IN);
+#define HWIO_REG_977937_FRAME_RATE_BMSK  0xff
+#define HWIO_REG_977937_FRAME_RATE_SHFT  0
+
+#define HWIO_REG_166135_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5a8)
+#define HWIO_REG_166135_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5a8)
+#define HWIO_REG_166135_RMSK  0xffffffff
+#define HWIO_REG_166135_SHFT  0
+#define HWIO_REG_166135_IN  in_dword_masked(\
+	HWIO_REG_166135_ADDR, HWIO_REG_166135_RMSK)
+#define HWIO_REG_166135_INM(m)  in_dword_masked(HWIO_REG_166135_ADDR, m)
+#define HWIO_REG_166135_OUT(v)  out_dword(HWIO_REG_166135_ADDR, v)
+#define HWIO_REG_166135_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_166135_ADDR, m, v, HWIO_REG_166135_IN);
+#define HWIO_REG_166135_BIT_RATE_BMSK  0xffffffff
+#define HWIO_REG_166135_BIT_RATE_SHFT  0
+
+#define HWIO_REG_109072_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5ac)
+#define HWIO_REG_109072_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5ac)
+#define HWIO_REG_109072_RMSK  0x3fff
+#define HWIO_REG_109072_SHFT  0
+#define HWIO_REG_109072_IN  in_dword_masked(\
+	HWIO_REG_109072_ADDR, HWIO_REG_109072_RMSK)
+#define HWIO_REG_109072_INM(m)  in_dword_masked(HWIO_REG_109072_ADDR, m)
+#define HWIO_REG_109072_OUT(v)  out_dword(HWIO_REG_109072_ADDR, v)
+#define HWIO_REG_109072_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_109072_ADDR, m, v, HWIO_REG_109072_IN);
+#define HWIO_REG_109072_MAX_QP_BMSK  0x3f00
+#define HWIO_REG_109072_MAX_QP_SHFT  0x8
+#define HWIO_REG_109072_MIN_QP_BMSK  0x3f
+#define HWIO_REG_109072_MIN_QP_SHFT  0
+
+#define HWIO_REG_550322_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5b0)
+#define HWIO_REG_550322_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5b0)
+#define HWIO_REG_550322_RMSK  0xffff
+#define HWIO_REG_550322_SHFT  0
+#define HWIO_REG_550322_IN  in_dword_masked(\
+	HWIO_REG_550322_ADDR, HWIO_REG_550322_RMSK)
+#define HWIO_REG_550322_INM(m)  in_dword_masked(HWIO_REG_550322_ADDR, m)
+#define HWIO_REG_550322_OUT(v)  out_dword(HWIO_REG_550322_ADDR, v)
+#define HWIO_REG_550322_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_550322_ADDR, m, v, HWIO_REG_550322_IN);
+#define HWIO_REG_550322_REACT_PARA_BMSK  0xffff
+#define HWIO_REG_550322_REACT_PARA_SHFT  0
+
+#define HWIO_REG_949086_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5b4)
+#define HWIO_REG_949086_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5b4)
+#define HWIO_REG_949086_RMSK  0xf
+#define HWIO_REG_949086_SHFT  0
+#define HWIO_REG_949086_IN  in_dword_masked(\
+	HWIO_REG_949086_ADDR, HWIO_REG_949086_RMSK)
+#define HWIO_REG_949086_INM(m)  in_dword_masked(HWIO_REG_949086_ADDR, m)
+#define HWIO_REG_949086_OUT(v)  out_dword(HWIO_REG_949086_ADDR, v)
+#define HWIO_REG_949086_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_949086_ADDR, m, v, HWIO_REG_949086_IN);
+#define HWIO_REG_949086_DARK_DISABLE_BMSK    0x8
+#define HWIO_REG_949086_DARK_DISABLE_SHFT    0x3
+#define HWIO_REG_949086_SMOOTH_DISABLE_BMSK  0x4
+#define HWIO_REG_949086_SMOOTH_DISABLE_SHFT  0x2
+#define HWIO_REG_949086_STATIC_DISABLE_BMSK  0x2
+#define HWIO_REG_949086_STATIC_DISABLE_SHFT  0x1
+#define HWIO_REG_949086_ACT_DISABLE_BMSK     0x1
+#define HWIO_REG_949086_ACT_DISABLE_SHFT     0
+
+#define HWIO_REG_447796_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d004)
+#define HWIO_REG_447796_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d004)
+#define HWIO_REG_447796_RMSK  0x1
+#define HWIO_REG_447796_SHFT  0
+#define HWIO_REG_447796_IN  in_dword_masked(\
+	HWIO_REG_447796_ADDR, HWIO_REG_447796_RMSK)
+#define HWIO_REG_447796_INM(m) \
+	in_dword_masked(HWIO_REG_447796_ADDR, m)
+#define HWIO_REG_447796_OUT(v) \
+	out_dword(HWIO_REG_447796_ADDR, v)
+#define HWIO_REG_447796_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_447796_ADDR, m, v, HWIO_REG_447796_IN);
+#define HWIO_REG_447796_REG_447796_BMSK  0x1
+#define HWIO_REG_447796_REG_447796_SHFT  0
+
+#define HWIO_REG_744348_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d010)
+#define HWIO_REG_744348_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d010)
+#define HWIO_REG_744348_RMSK  0x7f
+#define HWIO_REG_744348_SHFT  0
+#define HWIO_REG_744348_IN  in_dword_masked(\
+	HWIO_REG_744348_ADDR, HWIO_REG_744348_RMSK)
+#define HWIO_REG_744348_INM(m) \
+	in_dword_masked(HWIO_REG_744348_ADDR, m)
+#define HWIO_REG_744348_OUT(v)  \
+	out_dword(HWIO_REG_744348_ADDR, v)
+#define HWIO_REG_744348_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_744348_ADDR, m, v, HWIO_REG_744348_IN);
+#define HWIO_REG_744348_P_BMSK  0x60
+#define HWIO_REG_744348_P_SHFT  0x5
+#define HWIO_REG_744348_BMSK  0x1f
+#define HWIO_REG_744348_SHFT  0
+
+#define HWIO_REG_672163_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d034)
+#define HWIO_REG_672163_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d034)
+#define HWIO_REG_672163_RMSK  0x1
+#define HWIO_REG_672163_SHFT  0
+#define HWIO_REG_672163_IN  in_dword_masked(\
+	HWIO_REG_672163_ADDR, HWIO_REG_672163_RMSK)
+#define HWIO_REG_672163_INM(m) \
+	in_dword_masked(HWIO_REG_672163_ADDR, m)
+#define HWIO_REG_672163_OUT(v) \
+	out_dword(HWIO_REG_672163_ADDR, v)
+#define HWIO_REG_672163_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_672163_ADDR, m, v,\
+	HWIO_REG_672163_IN);
+#define HWIO_REG_672163_ENC_TRANS_8X8_FLAG_BMSK  0x1
+#define HWIO_REG_672163_ENC_TRANS_8X8_FLAG_SHFT  0
+
+#define HWIO_REG_780908_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d140)
+#define HWIO_REG_780908_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d140)
+#define HWIO_REG_780908_RMSK  0x1
+#define HWIO_REG_780908_SHFT  0
+#define HWIO_REG_780908_IN  in_dword_masked(\
+	HWIO_REG_780908_ADDR, HWIO_REG_780908_RMSK)
+#define HWIO_REG_780908_INM(m)  in_dword_masked(\
+	HWIO_REG_780908_ADDR, m)
+#define HWIO_REG_780908_OUT(v)  out_dword(\
+	HWIO_REG_780908_ADDR, v)
+#define HWIO_REG_780908_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_780908_ADDR, m, v,\
+	HWIO_REG_780908_IN)
+#define HWIO_REG_780908_REG_780908_BMSK  0x1
+#define HWIO_REG_780908_REG_780908_SHFT  0
+
+#define HWIO_REG_330132_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000e008)
+#define HWIO_REG_330132_PHYS \
+	(VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000e008)
+#define HWIO_REG_330132_RMSK  0x1
+#define HWIO_REG_330132_SHFT  0
+#define HWIO_REG_330132_IN  in_dword_masked(\
+	HWIO_REG_330132_ADDR, HWIO_REG_330132_RMSK)
+#define HWIO_REG_330132_INM(m) \
+	in_dword_masked(HWIO_REG_330132_ADDR, m)
+#define HWIO_REG_330132_OUT(v) \
+	out_dword(HWIO_REG_330132_ADDR, v)
+#define HWIO_REG_330132_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_330132_ADDR, m, v, HWIO_REG_330132_IN);
+#define HWIO_REG_330132_MPEG4_QUART_PXL_BMSK  0x1
+#define HWIO_REG_330132_MPEG4_QUART_PXL_SHFT  0
+
+
+#define VIDC_MGEN2MAXI_REG_BASE (VIDC_BASE + 0x00080000)
+#define VIDC_MGEN2MAXI_REG_BASE_PHYS 0x04480000
+
+#define HWIO_REG_916352_ADDR (VIDC_MGEN2MAXI_REG_BASE + 00000000)
+#define HWIO_REG_916352_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 00000000)
+#define HWIO_REG_916352_RMSK  0xff
+#define HWIO_REG_916352_SHFT  0
+#define HWIO_REG_916352_IN  in_dword_masked(\
+	HWIO_REG_916352_ADDR, HWIO_REG_916352_RMSK)
+#define HWIO_REG_916352_INM(m) \
+	in_dword_masked(HWIO_REG_916352_ADDR, m)
+#define HWIO_REG_916352_VERSION_BMSK  0xff
+#define HWIO_REG_916352_VERSION_SHFT  0
+
+#define HWIO_REG_5519_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000004)
+#define HWIO_REG_5519_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000004)
+#define HWIO_REG_5519_RMSK  0x1
+#define HWIO_REG_5519_SHFT  0
+#define HWIO_REG_5519_IN  in_dword_masked(\
+	HWIO_REG_5519_ADDR, HWIO_REG_5519_RMSK)
+#define HWIO_REG_5519_INM(m) \
+	in_dword_masked(HWIO_REG_5519_ADDR, m)
+#define HWIO_REG_5519_OUT(v) \
+	out_dword(HWIO_REG_5519_ADDR, v)
+#define HWIO_REG_5519_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_5519_ADDR, m, v, HWIO_REG_5519_IN);
+#define HWIO_REG_5519_AXI_AOOORD_BMSK  0x1
+#define HWIO_REG_5519_AXI_AOOORD_SHFT  0
+
+#define HWIO_REG_606364_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000008)
+#define HWIO_REG_606364_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000008)
+#define HWIO_REG_606364_RMSK  0x1
+#define HWIO_REG_606364_SHFT  0
+#define HWIO_REG_606364_IN  in_dword_masked(\
+	HWIO_REG_606364_ADDR, HWIO_REG_606364_RMSK)
+#define HWIO_REG_606364_INM(m) \
+	in_dword_masked(HWIO_REG_606364_ADDR, m)
+#define HWIO_REG_606364_OUT(v) \
+	out_dword(HWIO_REG_606364_ADDR, v)
+#define HWIO_REG_606364_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_606364_ADDR, m, v, HWIO_REG_606364_IN);
+#define HWIO_REG_606364_AXI_AOOOWR_BMSK  0x1
+#define HWIO_REG_606364_AXI_AOOOWR_SHFT  0
+
+#define HWIO_REG_821472_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x0000000c)
+#define HWIO_REG_821472_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000000c)
+#define HWIO_REG_821472_RMSK  0xf
+#define HWIO_REG_821472_SHFT  0
+#define HWIO_REG_821472_IN  in_dword_masked(\
+	HWIO_REG_821472_ADDR, HWIO_REG_821472_RMSK)
+#define HWIO_REG_821472_INM(m) \
+	in_dword_masked(HWIO_REG_821472_ADDR, m)
+#define HWIO_REG_821472_OUT(v) \
+	out_dword(HWIO_REG_821472_ADDR, v)
+#define HWIO_REG_821472_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_821472_ADDR, m, v, HWIO_REG_821472_IN);
+#define HWIO_REG_821472_AXI_TYPE_BMSK  0xf
+#define HWIO_REG_821472_AXI_TYPE_SHFT  0
+
+#define HWIO_REG_988424_ADDR \
+	(VIDC_MGEN2MAXI_REG_BASE  + 0x00000010)
+#define HWIO_REG_988424_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000010)
+#define HWIO_REG_988424_RMSK  0x3
+#define HWIO_REG_988424_SHFT  0
+#define HWIO_REG_988424_IN  in_dword_masked(\
+	HWIO_REG_988424_ADDR,\
+	HWIO_REG_988424_RMSK)
+#define HWIO_REG_988424_INM(m) \
+	in_dword_masked(HWIO_REG_988424_ADDR, m)
+#define HWIO_REG_988424_OUT(v) \
+	out_dword(HWIO_REG_988424_ADDR, v)
+#define HWIO_REG_988424_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_988424_ADDR, m, v,\
+	HWIO_REG_988424_IN);
+#define HWIO_REG_988424_AXI_AREQPRIORITY_BMSK  0x3
+#define HWIO_REG_988424_AXI_AREQPRIORITY_SHFT  0
+
+#define HWIO_REG_471159_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000014)
+#define HWIO_REG_471159_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000014)
+#define HWIO_REG_471159_RMSK  0x801f1111
+#define HWIO_REG_471159_SHFT  0
+#define HWIO_REG_471159_IN  in_dword_masked(\
+	HWIO_REG_471159_ADDR, HWIO_REG_471159_RMSK)
+#define HWIO_REG_471159_INM(m) \
+	in_dword_masked(HWIO_REG_471159_ADDR, m)
+#define HWIO_REG_471159_OUT(v) \
+	out_dword(HWIO_REG_471159_ADDR, v)
+#define HWIO_REG_471159_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_471159_ADDR, m, v, HWIO_REG_471159_IN);
+#define HWIO_REG_471159_AXI_INTR_CLR_BMSK           0x80000000
+#define HWIO_REG_471159_AXI_INTR_CLR_SHFT           0x1f
+#define HWIO_REG_471159_AXI_WDTIMEOUT_LOG2_BMSK     0x1e0000
+#define HWIO_REG_471159_AXI_WDTIMEOUT_LOG2_SHFT     0x11
+#define HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_BMSK  0x10000
+#define HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_SHFT  0x10
+#define HWIO_REG_471159_AXI_HALT_ON_WR_ERR_BMSK     0x1000
+#define HWIO_REG_471159_AXI_HALT_ON_WR_ERR_SHFT     0xc
+#define HWIO_REG_471159_AXI_HALT_ON_RD_ERR_BMSK     0x100
+#define HWIO_REG_471159_AXI_HALT_ON_RD_ERR_SHFT     0x8
+#define HWIO_REG_471159_AXI_RESET_BMSK              0x10
+#define HWIO_REG_471159_AXI_RESET_SHFT              0x4
+#define HWIO_REG_471159_AXI_HALT_REQ_BMSK           0x1
+#define HWIO_REG_471159_AXI_HALT_REQ_SHFT            0
+
+#define HWIO_REG_437878_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000018)
+#define HWIO_REG_437878_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000018)
+#define HWIO_REG_437878_RMSK  0x3333
+#define HWIO_REG_437878_SHFT  0
+#define HWIO_REG_437878_IN  in_dword_masked(\
+	HWIO_REG_437878_ADDR, HWIO_REG_437878_RMSK)
+#define HWIO_REG_437878_INM(m) \
+	in_dword_masked(HWIO_REG_437878_ADDR, m)
+#define HWIO_REG_437878_AXI_WDTIMEOUT_INTR_BMSK  0x3000
+#define HWIO_REG_437878_AXI_WDTIMEOUT_INTR_SHFT  0xc
+#define HWIO_REG_437878_AXI_ERR_INTR_BMSK        0x300
+#define HWIO_REG_437878_AXI_ERR_INTR_SHFT        0x8
+#define HWIO_REG_437878_AXI_IDLE_BMSK            0x30
+#define HWIO_REG_437878_AXI_IDLE_SHFT            0x4
+#define HWIO_REG_437878_AXI_HALT_ACK_BMSK        0x3
+#define HWIO_REG_437878_AXI_HALT_ACK_SHFT        0
+
+#define HWIO_REG_736158_ADDR \
+	(VIDC_MGEN2MAXI_REG_BASE + 0x0000001c)
+#define HWIO_REG_736158_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000001c)
+#define HWIO_REG_736158_RMSK  0x10fff
+#define HWIO_REG_736158_SHFT  0
+#define HWIO_REG_736158_IN  in_dword_masked(\
+	HWIO_REG_736158_ADDR,\
+	HWIO_REG_736158_RMSK)
+#define HWIO_REG_736158_INM(m) \
+	in_dword_masked(HWIO_REG_736158_ADDR, m)
+#define HWIO_REG_736158_AXI_WDTIMEOUT_BMSK  0x10000
+#define HWIO_REG_736158_AXI_WDTIMEOUT_SHFT  0x10
+#define HWIO_REG_736158_AXI_ERR_BMSK        0x800
+#define HWIO_REG_736158_AXI_ERR_SHFT        0xb
+#define HWIO_REG_736158_AXI_ERR_TYPE_BMSK   0x400
+#define HWIO_REG_736158_AXI_ERR_TYPE_SHFT   0xa
+#define HWIO_REG_736158_AXI_RESP_BMSK       0x300
+#define HWIO_REG_736158_AXI_RESP_SHFT       0x8
+#define HWIO_REG_736158_AXI_MID_BMSK        0xf0
+#define HWIO_REG_736158_AXI_MID_SHFT        0x4
+#define HWIO_REG_736158_AXI_TID_BMSK        0xf
+#define HWIO_REG_736158_AXI_TID_SHFT        0
+
+#define HWIO_REG_598415_ADDR \
+	(VIDC_MGEN2MAXI_REG_BASE + 0x00000020)
+#define HWIO_REG_598415_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000020)
+#define HWIO_REG_598415_RMSK  0x10fff
+#define HWIO_REG_598415_SHFT  0
+#define HWIO_REG_598415_IN  in_dword_masked(\
+	HWIO_REG_598415_ADDR,\
+	HWIO_REG_598415_RMSK)
+#define HWIO_REG_598415_INM(m) \
+	in_dword_masked(HWIO_REG_598415_ADDR, m)
+#define HWIO_REG_598415_AXI_WDTIMEOUT_BMSK  0x10000
+#define HWIO_REG_598415_AXI_WDTIMEOUT_SHFT  0x10
+#define HWIO_REG_598415_AXI_ERR_BMSK        0x800
+#define HWIO_REG_598415_AXI_ERR_SHFT        0xb
+#define HWIO_REG_598415_AXI_ERR_TYPE_BMSK   0x400
+#define HWIO_REG_598415_AXI_ERR_TYPE_SHFT   0xa
+#define HWIO_REG_598415_AXI_RESP_BMSK       0x300
+#define HWIO_REG_598415_AXI_RESP_SHFT       0x8
+#define HWIO_REG_598415_AXI_MID_BMSK        0xf0
+#define HWIO_REG_598415_AXI_MID_SHFT        0x4
+#define HWIO_REG_598415_AXI_TID_BMSK        0xf
+#define HWIO_REG_598415_AXI_TID_SHFT        0
+
+#define HWIO_REG_439061_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000024)
+#define HWIO_REG_439061_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000024)
+#define HWIO_REG_439061_RMSK  0x11111ff
+#define HWIO_REG_439061_SHFT  0
+#define HWIO_REG_439061_IN  in_dword_masked(\
+	HWIO_REG_439061_ADDR, HWIO_REG_439061_RMSK)
+#define HWIO_REG_439061_INM(m) \
+	in_dword_masked(HWIO_REG_439061_ADDR, m)
+#define HWIO_REG_439061_OUT(v) \
+	out_dword(HWIO_REG_439061_ADDR, v)
+#define HWIO_REG_439061_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_439061_ADDR, m, v, HWIO_REG_439061_IN);
+#define HWIO_REG_439061_AXI_RD_LAT_REP_EN_BMSK  0x1000000
+#define HWIO_REG_439061_AXI_RD_LAT_REP_EN_SHFT  0x18
+#define HWIO_REG_439061_AXI_LSFR_EN_BMSK        0x100000
+#define HWIO_REG_439061_AXI_LSFR_EN_SHFT        0x14
+#define HWIO_REG_439061_AXI_MISR_RES_BMSK       0x10000
+#define HWIO_REG_439061_AXI_MISR_RES_SHFT       0x10
+#define HWIO_REG_439061_AXI_MISR_EN_BMSK        0x1000
+#define HWIO_REG_439061_AXI_MISR_EN_SHFT        0xc
+#define HWIO_REG_439061_AXI_MISR_WD_BMSK        0x100
+#define HWIO_REG_439061_AXI_MISR_WD_SHFT        0x8
+#define HWIO_REG_439061_AXI_CTR_EN_BMSK         0x80
+#define HWIO_REG_439061_AXI_CTR_EN_SHFT         0x7
+#define HWIO_REG_439061_AXI_CTR_RES_BMSK        0x40
+#define HWIO_REG_439061_AXI_CTR_RES_SHFT        0x6
+#define HWIO_REG_439061_AXI_TEST_ARB_SEL_BMSK   0x30
+#define HWIO_REG_439061_AXI_TEST_ARB_SEL_SHFT   0x4
+#define HWIO_REG_439061_AXI_TEST_OUT_SEL_BMSK   0xf
+#define HWIO_REG_439061_AXI_TEST_OUT_SEL_SHFT   0
+
+#define HWIO_REG_573121_ADDR \
+	(VIDC_MGEN2MAXI_REG_BASE + 0x00000028)
+#define HWIO_REG_573121_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000028)
+#define HWIO_REG_573121_RMSK  0xffffffff
+#define HWIO_REG_573121_SHFT  0
+#define HWIO_REG_573121_IN  in_dword_masked(\
+	HWIO_REG_573121_ADDR,\
+	HWIO_REG_573121_RMSK)
+#define HWIO_REG_573121_INM(m) \
+	in_dword_masked(HWIO_REG_573121_ADDR, m)
+#define HWIO_REG_573121_AXI_TEST_OUT_BMSK  0xffffffff
+#define HWIO_REG_573121_AXI_TEST_OUT_SHFT  0
+
+#define HWIO_REG_806413_ADDR \
+	(VIDC_MGEN2MAXI_REG_BASE + 0x0000002c)
+#define HWIO_REG_806413_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000002c)
+#define HWIO_REG_806413_RMSK  0xffffffff
+#define HWIO_REG_806413_SHFT  0
+#define HWIO_REG_806413_IN  in_dword_masked(\
+	HWIO_REG_806413_ADDR,\
+	HWIO_REG_806413_RMSK)
+#define HWIO_REG_806413_INM(m) \
+	in_dword_masked(HWIO_REG_806413_ADDR, m)
+#define HWIO_REG_806413_AXI_TEST_OUT_BMSK 0xffffffff
+#define HWIO_REG_806413_AXI_TEST_OUT_SHFT 0
+
+#define HWIO_REG_804110_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000030)
+#define HWIO_REG_804110_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000030)
+#define HWIO_REG_804110_RMSK  0xc00fffff
+#define HWIO_REG_804110_SHFT  0
+#define HWIO_REG_804110_IN  in_dword_masked(\
+	HWIO_REG_804110_ADDR, HWIO_REG_804110_RMSK)
+#define HWIO_REG_804110_INM(m) \
+	in_dword_masked(HWIO_REG_804110_ADDR, m)
+#define HWIO_REG_804110_OUT(v)  out_dword(HWIO_REG_804110_ADDR, v)
+#define HWIO_REG_804110_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_804110_ADDR, m, v, HWIO_REG_804110_IN);
+#define HWIO_REG_804110_ENABLE_BMSK                 0x80000000
+#define HWIO_REG_804110_ENABLE_SHFT                 0x1f
+#define HWIO_REG_804110_CONST_VIDC_BMSK             0x40000000
+#define HWIO_REG_804110_CONST_VIDC_SHFT             0x1e
+#define HWIO_REG_804110_VIDCV_1080P_VERSION_BMSK    0xff000
+#define HWIO_REG_804110_VIDCV_1080P_VERSION_SHFT    0xc
+#define HWIO_REG_804110_MGEN2MAXI_DATA_SEL_BMSK     0xf00
+#define HWIO_REG_804110_MGEN2MAXI_DATA_SEL_SHFT     0x8
+#define HWIO_REG_804110_MGEN2MAXI_XIN_SEL_BMSK      0x80
+#define HWIO_REG_804110_MGEN2MAXI_XIN_SEL_SHFT      0x7
+#define HWIO_REG_804110_MGEN2MAXI_ARB_SEL_BMSK      0x40
+#define HWIO_REG_804110_MGEN2MAXI_ARB_SEL_SHFT      0x6
+#define HWIO_REG_804110_MGEN2MAXI_TESTBUS_SEL_BMSK  0x30
+#define HWIO_REG_804110_MGEN2MAXI_TESTBUS_SEL_SHFT  0x4
+#define HWIO_REG_804110_AHB2AHB_TESTBUS_SEL_BMSK    0x8
+#define HWIO_REG_804110_AHB2AHB_TESTBUS_SEL_SHFT    0x3
+#define HWIO_REG_804110_MGEN2MAXI_AXI_SEL_BMSK      0x4
+#define HWIO_REG_804110_MGEN2MAXI_AXI_SEL_SHFT      0x2
+#define HWIO_REG_804110_SELECT_BMSK                 0x3
+#define HWIO_REG_804110_SELECT_SHFT                 0
+
+#define HWIO_REG_616440_ADDR \
+	(VIDC_MGEN2MAXI_REG_BASE + 0x00000034)
+#define HWIO_REG_616440_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000034)
+#define HWIO_REG_616440_RMSK  0xffff
+#define HWIO_REG_616440_SHFT  0
+#define HWIO_REG_616440_IN  in_dword_masked(\
+	HWIO_REG_616440_ADDR,\
+	HWIO_REG_616440_RMSK)
+#define HWIO_REG_616440_INM(m) \
+	in_dword_masked(HWIO_REG_616440_ADDR, m)
+#define HWIO_REG_616440_OUT(v) \
+	out_dword(HWIO_REG_616440_ADDR, v)
+#define HWIO_REG_616440_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_616440_ADDR, m, v,\
+	HWIO_REG_616440_IN);
+#define HWIO_REG_616440_XBAR_IN_RD_LIM_BMSK  0xff00
+#define HWIO_REG_616440_XBAR_IN_RD_LIM_SHFT  0x8
+#define HWIO_REG_616440_XBAR_IN_WR_LIM_BMSK  0xff
+#define HWIO_REG_616440_XBAR_IN_WR_LIM_SHFT  0
+
+#define HWIO_REG_527219_ADDR \
+	(VIDC_MGEN2MAXI_REG_BASE + 0x00000038)
+#define HWIO_REG_527219_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000038)
+#define HWIO_REG_527219_RMSK  0xffff
+#define HWIO_REG_527219_SHFT  0
+#define HWIO_REG_527219_IN  in_dword_masked(\
+	HWIO_REG_527219_ADDR,\
+	HWIO_REG_527219_RMSK)
+#define HWIO_REG_527219_INM(m) \
+	in_dword_masked(HWIO_REG_527219_ADDR, m)
+#define HWIO_REG_527219_OUT(v) \
+	out_dword(HWIO_REG_527219_ADDR, v)
+#define HWIO_REG_527219_OUTM(m, v) \out_dword_masked_ns(\
+	HWIO_REG_527219_ADDR, m, v,\
+	HWIO_REG_527219_IN);
+#define HWIO_REG_527219_XBAR_OUT_RD_LIM_BMSK  0xff00
+#define HWIO_REG_527219_XBAR_OUT_RD_LIM_SHFT  0x8
+#define HWIO_REG_527219_XBAR_OUT_WR_LIM_BMSK  0xff
+#define HWIO_REG_527219_XBAR_OUT_WR_LIM_SHFT  0
+
+#define HWIO_REG_922106_ADDR \
+	(VIDC_MGEN2MAXI_REG_BASE + 0x0000003c)
+#define HWIO_REG_922106_PHYS \
+	(VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000003c)
+#define HWIO_REG_922106_RMSK  0xffff
+#define HWIO_REG_922106_SHFT  0
+#define HWIO_REG_922106_IN  in_dword_masked(\
+	HWIO_REG_922106_ADDR,\
+	HWIO_REG_922106_RMSK)
+#define HWIO_REG_922106_INM(m) \
+	in_dword_masked(HWIO_REG_922106_ADDR, m)
+#define HWIO_REG_922106_OUT(v) \
+	out_dword(HWIO_REG_922106_ADDR, v)
+#define HWIO_REG_922106_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_922106_ADDR, m, v,\
+	HWIO_REG_922106_IN);
+#define HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_BMSK  0xff00
+#define HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_SHFT  0x8
+#define HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_BMSK  0xff
+#define HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_SHFT  0
+
+#define VIDC_ENHANCE_REG_BASE (VIDC_BASE + 0x000c0000)
+#define VIDC_ENHANCE_REG_BASE_PHYS  0x044c0000
+
+#define HWIO_REG_261029_ADDR (VIDC_ENHANCE_REG_BASE + 00000000)
+#define HWIO_REG_261029_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 00000000)
+#define HWIO_REG_261029_RMSK  0x10f
+#define HWIO_REG_261029_SHFT  0
+#define HWIO_REG_261029_IN  in_dword_masked(\
+	HWIO_REG_261029_ADDR, HWIO_REG_261029_RMSK)
+#define HWIO_REG_261029_INM(m) \
+	in_dword_masked(HWIO_REG_261029_ADDR, m)
+#define HWIO_REG_261029_OUT(v) \
+	out_dword(HWIO_REG_261029_ADDR, v)
+#define HWIO_REG_261029_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_261029_ADDR, m, v, HWIO_REG_261029_IN);
+#define HWIO_REG_261029_AUTO_INC_EN_BMSK  0x100
+#define HWIO_REG_261029_AUTO_INC_EN_SHFT  0x8
+#define HWIO_REG_261029_DMI_RAM_SEL_BMSK  0xf
+#define HWIO_REG_261029_DMI_RAM_SEL_SHFT  0
+
+#define HWIO_REG_576200_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000004)
+#define HWIO_REG_576200_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000004)
+#define HWIO_REG_576200_RMSK  0x7ff
+#define HWIO_REG_576200_SHFT  0
+#define HWIO_REG_576200_IN  in_dword_masked(\
+	HWIO_REG_576200_ADDR, HWIO_REG_576200_RMSK)
+#define HWIO_REG_576200_INM(m) \
+	in_dword_masked(HWIO_REG_576200_ADDR, m)
+#define HWIO_REG_576200_OUT(v) \
+	out_dword(HWIO_REG_576200_ADDR, v)
+#define HWIO_REG_576200_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_576200_ADDR, m, v, HWIO_REG_576200_IN);
+#define HWIO_REG_576200_DMI_ADDR_BMSK  0x7ff
+#define HWIO_REG_576200_DMI_ADDR_SHFT  0
+
+#define HWIO_REG_917583_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000008)
+#define HWIO_REG_917583_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000008)
+#define HWIO_REG_917583_RMSK  0xffffffff
+#define HWIO_REG_917583_SHFT   0
+#define HWIO_REG_917583_IN  in_dword_masked(\
+	HWIO_REG_917583_ADDR, HWIO_REG_917583_RMSK)
+#define HWIO_REG_917583_INM(m) \
+	in_dword_masked(HWIO_REG_917583_ADDR, m)
+#define HWIO_REG_917583_OUT(v) \
+	out_dword(HWIO_REG_917583_ADDR, v)
+#define HWIO_REG_917583_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_917583_ADDR, m, v, HWIO_REG_917583_IN);
+#define HWIO_REG_917583_DMI_DATA_HI_BMSK  0xffffffff
+#define HWIO_REG_917583_DMI_DATA_HI_SHFT  0
+
+#define HWIO_REG_556274_ADDR (VIDC_ENHANCE_REG_BASE + 0x0000000c)
+#define HWIO_REG_556274_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x0000000c)
+#define HWIO_REG_556274_RMSK  0xffffffff
+#define HWIO_REG_556274_SHFT  0
+#define HWIO_REG_556274_IN  in_dword_masked(\
+	HWIO_REG_556274_ADDR, HWIO_REG_556274_RMSK)
+#define HWIO_REG_556274_INM(m) \
+	in_dword_masked(HWIO_REG_556274_ADDR, m)
+#define HWIO_REG_556274_OUT(v) \
+	out_dword(HWIO_REG_556274_ADDR, v)
+#define HWIO_REG_556274_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_556274_ADDR, m, v, HWIO_REG_556274_IN);
+#define HWIO_REG_556274_DMI_DATA_LO_BMSK  0xffffffff
+#define HWIO_REG_556274_DMI_DATA_LO_SHFT  0
+
+#define HWIO_REG_39703_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000010)
+#define HWIO_REG_39703_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x00000010)
+#define HWIO_REG_39703_RMSK  0x1f
+#define HWIO_REG_39703_SHFT  0
+#define HWIO_REG_39703_IN  in_dword_masked(\
+	HWIO_REG_39703_ADDR, HWIO_REG_39703_RMSK)
+#define HWIO_REG_39703_INM(m) \
+	in_dword_masked(HWIO_REG_39703_ADDR, m)
+#define HWIO_REG_39703_OUT(v) \
+	out_dword(HWIO_REG_39703_ADDR, v)
+#define HWIO_REG_39703_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_39703_ADDR, m, v, HWIO_REG_39703_IN);
+#define HWIO_REG_39703_PIX_CACHE_TB_SEL_BMSK  0x1f
+#define HWIO_REG_39703_PIX_CACHE_TB_SEL_SHFT  0
+
+#define HWIO_REG_169013_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000014)
+#define HWIO_REG_169013_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000014)
+#define HWIO_REG_169013_RMSK  0x3
+#define HWIO_REG_169013_SHFT  0
+#define HWIO_REG_169013_IN  in_dword_masked(\
+	HWIO_REG_169013_ADDR, HWIO_REG_169013_RMSK)
+#define HWIO_REG_169013_INM(m) \
+	in_dword_masked(HWIO_REG_169013_ADDR, m)
+#define HWIO_REG_169013_OUT(v) \
+	out_dword(HWIO_REG_169013_ADDR, v)
+#define HWIO_REG_169013_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_169013_ADDR, m, v, HWIO_REG_169013_IN);
+#define HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK  0x2
+#define HWIO_REG_169013_PIX_CACHE_SW_RESET_SHFT  0x1
+#define HWIO_REG_169013_CRIF_RESET_BMSK          0x1
+#define HWIO_REG_169013_CRIF_RESET_SHFT          0
+
+#define HWIO_REG_22756_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000018)
+#define HWIO_REG_22756_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x00000018)
+#define HWIO_REG_22756_RMSK  0x133f
+#define HWIO_REG_22756_SHFT  0
+#define HWIO_REG_22756_IN  in_dword_masked(\
+	HWIO_REG_22756_ADDR, HWIO_REG_22756_RMSK)
+#define HWIO_REG_22756_INM(m) \
+	in_dword_masked(HWIO_REG_22756_ADDR, m)
+#define HWIO_REG_22756_OUT(v) \
+	out_dword(HWIO_REG_22756_ADDR, v)
+#define HWIO_REG_22756_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_22756_ADDR, m, v, HWIO_REG_22756_IN);
+#define HWIO_REG_22756_CACHE_HALT_BMSK         0x1000
+#define HWIO_REG_22756_CACHE_HALT_SHFT         0xc
+#define HWIO_REG_22756_PAGE_SIZE_BMSK          0x300
+#define HWIO_REG_22756_PAGE_SIZE_SHFT          0x8
+#define HWIO_REG_22756_STATISTICS_OFF_BMSK     0x20
+#define HWIO_REG_22756_STATISTICS_OFF_SHFT     0x5
+#define HWIO_REG_22756_CACHE_PORT_SELECT_BMSK  0x10
+#define HWIO_REG_22756_CACHE_PORT_SELECT_SHFT  0x4
+#define HWIO_REG_22756_PREFETCH_EN_BMSK        0x8
+#define HWIO_REG_22756_PREFETCH_EN_SHFT        0x3
+#define HWIO_REG_22756_SS_TILE_FORMAT_BMSK     0x4
+#define HWIO_REG_22756_SS_TILE_FORMAT_SHFT     0x2
+#define HWIO_REG_22756_CACHE_EN_BMSK           0x2
+#define HWIO_REG_22756_CACHE_EN_SHFT           0x1
+#define HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK    0x1
+#define HWIO_REG_22756_CACHE_TAG_CLEAR_SHFT    0
+
+#define HWIO_REG_951731_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x0000001c)
+#define HWIO_REG_951731_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x0000001c)
+#define HWIO_REG_951731_RMSK  0x7ff07ff
+#define HWIO_REG_951731_SHFT  0
+#define HWIO_REG_951731_IN  in_dword_masked(\
+	HWIO_REG_951731_ADDR,\
+	HWIO_REG_951731_RMSK)
+#define HWIO_REG_951731_INM(m) \
+	in_dword_masked(HWIO_REG_951731_ADDR, m)
+#define HWIO_REG_951731_OUT(v) \
+	out_dword(HWIO_REG_951731_ADDR, v)
+#define HWIO_REG_951731_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_951731_ADDR, m, v,\
+	HWIO_REG_951731_IN);
+#define HWIO_REG_951731_FRAME_HEIGHT_BMSK  0x7ff0000
+#define HWIO_REG_951731_FRAME_HEIGHT_SHFT  0x10
+#define HWIO_REG_951731_FRAME_WIDTH_BMSK   0x7ff
+#define HWIO_REG_951731_FRAME_WIDTH_SHFT   0
+
+#define HWIO_REG_905239_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x00000020)
+#define HWIO_REG_905239_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x00000020)
+#define HWIO_REG_905239_RMSK  0x3ffff
+#define HWIO_REG_905239_SHFT  0
+#define HWIO_REG_905239_IN  in_dword_masked(\
+	HWIO_REG_905239_ADDR,\
+	HWIO_REG_905239_RMSK)
+#define HWIO_REG_905239_INM(m) \
+	in_dword_masked(HWIO_REG_905239_ADDR, m)
+#define HWIO_REG_905239_OUT(v) \
+	out_dword(HWIO_REG_905239_ADDR, v)
+#define HWIO_REG_905239_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_905239_ADDR, m, v,\
+	HWIO_REG_905239_IN);
+#define HWIO_REG_905239_LINEAR_LUMA_BMSK  0x3ffff
+#define HWIO_REG_905239_LINEAR_LUMA_SHFT  0
+#define HWIO_REG_905239_TILE_LUMA_BMSK    0xff00
+#define HWIO_REG_905239_TILE_LUMA_SHFT    0x8
+#define HWIO_REG_905239_TILE_CHROMA_BMSK  0xff
+#define HWIO_REG_905239_TILE_CHROMA_SHFT  0
+
+#define HWIO_REG_804925_ADDR(n) \
+	(VIDC_ENHANCE_REG_BASE + 0x00000024 + 4 * (n))
+#define HWIO_REG_804925_PHYS(n) \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x00000024 + 4 * (n))
+#define HWIO_REG_804925_RMSK  0xfffffff8
+#define HWIO_REG_804925_SHFT  0
+#define HWIO_REG_804925_MAXn  0x12
+#define HWIO_REG_804925_INI(n) \
+	in_dword(HWIO_REG_804925_ADDR(n))
+#define HWIO_REG_804925_INMI(n, mask) \
+	in_dword_masked(HWIO_REG_804925_ADDR(n), mask)
+#define HWIO_REG_804925_OUTI(n, val) \
+	out_dword(HWIO_REG_804925_ADDR(n), val)
+#define HWIO_REG_804925_OUTMI(n, mask, val) \
+	out_dword_masked_ns(HWIO_REG_804925_ADDR(n),\
+	mask, val, HWIO_REG_804925_INI(n));
+#define HWIO_REG_804925_ADDR_BMSK  0xfffffff8
+#define HWIO_REG_804925_ADDR_SHFT  0x3
+
+#define HWIO_REG_41909_ADDR(n) \
+	(VIDC_ENHANCE_REG_BASE + 0x00000070 + 4 * (n))
+#define HWIO_REG_41909_PHYS(n) \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x00000070 + 4 * (n))
+#define HWIO_REG_41909_RMSK  0xfffffff8
+#define HWIO_REG_41909_SHFT  0
+#define HWIO_REG_41909_MAXn  0x12
+#define HWIO_REG_41909_INI(n) \
+	in_dword(HWIO_REG_41909_ADDR(n))
+#define HWIO_REG_41909_INMI(n, mask) \
+	in_dword_masked(HWIO_REG_41909_ADDR(n), mask)
+#define HWIO_REG_41909_OUTI(n, val) \
+	out_dword(HWIO_REG_41909_ADDR(n), val)
+#define HWIO_REG_41909_OUTMI(n, mask, val) \
+	out_dword_masked_ns(HWIO_REG_41909_ADDR(n),\
+	mask, val, HWIO_REG_41909_INI(n));
+#define HWIO_REG_41909_ADDR_BMSK  0xfffffff8
+#define HWIO_REG_41909_ADDR_SHFT  0x3
+
+#define HWIO_REG_919904_ADDR (VIDC_ENHANCE_REG_BASE + 0x000000bc)
+#define HWIO_REG_919904_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000bc)
+#define HWIO_REG_919904_RMSK  0x1
+#define HWIO_REG_919904_SHFT  0
+#define HWIO_REG_919904_IN  in_dword_masked(\
+	HWIO_REG_919904_ADDR,\
+	HWIO_REG_919904_RMSK)
+#define HWIO_REG_919904_INM(m) \
+	in_dword_masked(HWIO_REG_919904_ADDR, m)
+#define HWIO_REG_919904_IDLE_BMSK  0x1
+#define HWIO_REG_919904_IDLE_SHFT  0
+
+#define HWIO_REG_278310_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x000000c0)
+#define HWIO_REG_278310_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c0)
+#define HWIO_REG_278310_RMSK  0xffffffff
+#define HWIO_REG_278310_SHFT  0
+#define HWIO_REG_278310_IN  in_dword_masked(\
+	HWIO_REG_278310_ADDR,\
+	HWIO_REG_278310_RMSK)
+#define HWIO_REG_278310_INM(m) \
+	in_dword_masked(HWIO_REG_278310_ADDR, m)
+#define HWIO_REG_278310_MISS_COUNT_BMSK  0xffffffff
+#define HWIO_REG_278310_MISS_COUNT_SHFT  0
+
+#define HWIO_REG_421222_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x000000c4)
+#define HWIO_REG_421222_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c4)
+#define HWIO_REG_421222_RMSK  0xffffffff
+#define HWIO_REG_421222_SHFT  0
+#define HWIO_REG_421222_IN  in_dword_masked(\
+	HWIO_REG_421222_ADDR,\
+	HWIO_REG_421222_RMSK)
+#define HWIO_REG_421222_INM(m) \
+	in_dword_masked(HWIO_REG_421222_ADDR, m)
+#define HWIO_REG_421222_HIT_COUNT_BMSK  0xffffffff
+#define HWIO_REG_421222_HIT_COUNT_SHFT  0
+
+#define HWIO_REG_609607_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x000000c8)
+#define HWIO_REG_609607_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c8)
+#define HWIO_REG_609607_RMSK  0xffffffff
+#define HWIO_REG_609607_SHFT  0
+#define HWIO_REG_609607_IN  in_dword_masked(\
+	HWIO_REG_609607_ADDR,\
+	HWIO_REG_609607_RMSK)
+#define HWIO_REG_609607_INM(m) \
+	in_dword_masked(HWIO_REG_609607_ADDR, m)
+#define HWIO_REG_609607_AXI_REQUEST_COUNT_BMSK  0xffffffff
+#define HWIO_REG_609607_AXI_REQUEST_COUNT_SHFT  0
+
+#define HWIO_REG_395232_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x000000cc)
+#define HWIO_REG_395232_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000cc)
+#define HWIO_REG_395232_RMSK  0xffffffff
+#define HWIO_REG_395232_SHFT  0
+#define HWIO_REG_395232_IN  in_dword_masked(\
+	HWIO_REG_395232_ADDR,\
+	HWIO_REG_395232_RMSK)
+#define HWIO_REG_395232_INM(m) \
+	in_dword_masked(HWIO_REG_395232_ADDR, m)
+#define HWIO_REG_395232_CORE_REQUEST_COUNT_BMSK \
+	0xffffffff
+#define HWIO_REG_395232_CORE_REQUEST_COUNT_SHFT  0
+
+#define HWIO_REG_450146_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x000000d0)
+#define HWIO_REG_450146_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d0)
+#define HWIO_REG_450146_RMSK  0xffffffff
+#define HWIO_REG_450146_SHFT  0
+#define HWIO_REG_450146_IN  in_dword_masked(\
+	HWIO_REG_450146_ADDR,\
+	HWIO_REG_450146_RMSK)
+#define HWIO_REG_450146_INM(m) \
+	in_dword_masked(HWIO_REG_450146_ADDR, m)
+#define HWIO_REG_450146_AXI_BEAT_COUNT_BMSK  0xffffffff
+#define HWIO_REG_450146_AXI_BEAT_COUNT_SHFT  0
+
+#define HWIO_REG_610651_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x000000d4)
+#define HWIO_REG_610651_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d4)
+#define HWIO_REG_610651_RMSK  0xffffffff
+#define HWIO_REG_610651_SHFT  0
+#define HWIO_REG_610651_IN  in_dword_masked(\
+	HWIO_REG_610651_ADDR,\
+	HWIO_REG_610651_RMSK)
+#define HWIO_REG_610651_INM(m) \
+	in_dword_masked(HWIO_REG_610651_ADDR, m)
+#define HWIO_REG_610651_CORE_BEAT_COUNT_BMSK  0xffffffff
+#define HWIO_REG_610651_CORE_BEAT_COUNT_SHFT  0
+
+#define HWIO_REG_883784_ADDR \
+	(VIDC_ENHANCE_REG_BASE + 0x000000d8)
+#define HWIO_REG_883784_PHYS \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d8)
+#define HWIO_REG_883784_RMSK  0xffffffff
+#define HWIO_REG_883784_SHFT  0
+#define HWIO_REG_883784_IN  in_dword_masked(\
+	HWIO_REG_883784_ADDR,\
+	HWIO_REG_883784_RMSK)
+#define HWIO_REG_883784_INM(m) \
+	in_dword_masked(HWIO_REG_883784_ADDR, m)
+#define HWIO_REG_883784_OUT(v) \
+	out_dword(HWIO_REG_883784_ADDR, v)
+#define HWIO_REG_883784_OUTM(m, v)  out_dword_masked_ns(\
+	HWIO_REG_883784_ADDR, m, v,\
+	HWIO_REG_883784_IN);
+#define HWIO_REG_883784_COUNTER_BMSK    0xffffff00
+#define HWIO_REG_883784_COUNTER_SHFT    0x8
+#define HWIO_REG_883784_ID_BMSK         0xf0
+#define HWIO_REG_883784_ID_SHFT         0x4
+#define HWIO_REG_883784_IGNORE_ID_BMSK  0x8
+#define HWIO_REG_883784_IGNORE_ID_SHFT  0x3
+#define HWIO_REG_883784_INPUT_SEL_BMSK  0x6
+#define HWIO_REG_883784_INPUT_SEL_SHFT  0x1
+#define HWIO_REG_883784_MISR_EN_BMSK    0x1
+#define HWIO_REG_883784_MISR_EN_SHFT    0
+
+#define HWIO_REG_651391_ADDR(n) \
+	(VIDC_ENHANCE_REG_BASE + 0x000000dc + 4 * (n))
+#define HWIO_REG_651391_PHYS(n) \
+	(VIDC_ENHANCE_REG_BASE_PHYS + 0x000000dc + 4 * (n))
+#define HWIO_REG_651391_RMSK  0xffffffff
+#define HWIO_REG_651391_SHFT  0
+#define HWIO_REG_651391_MAXn  0x1
+#define HWIO_REG_651391_INI(n) \
+	in_dword(HWIO_REG_651391_ADDR(n))
+#define HWIO_REG_651391_INMI(n, mask) \
+	in_dword_masked(HWIO_REG_651391_ADDR(n), mask)
+#define HWIO_REG_651391_OUTI(n, val) \
+	out_dword(HWIO_REG_651391_ADDR(n), val)
+#define HWIO_REG_651391_SIGNATURE_BMSK  0xffffffff
+#define HWIO_REG_651391_SIGNATURE_SHFT  0
+
+#endif
+
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c
new file mode 100644
index 0000000..6870525
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c
@@ -0,0 +1,349 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vidc_hwio_reg.h"
+#include "vidc_hwio.h"
+#include "vidc_pix_cache.h"
+
+
+#define VIDC_1080P_MAX_DEC_DPB 19
+#define VIDC_TILE_MULTIPLY_FACTOR 8192
+
+void vidc_pix_cache_sw_reset(void)
+{
+	u32 sw_reset_value = 0;
+
+	VIDC_HWIO_IN(REG_169013, &sw_reset_value);
+	sw_reset_value |= HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK;
+	VIDC_HWIO_OUT(REG_169013, sw_reset_value);
+	VIDC_HWIO_IN(REG_169013, &sw_reset_value);
+	sw_reset_value &= (~HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK);
+	VIDC_HWIO_OUT(REG_169013, sw_reset_value);
+}
+
+void vidc_pix_cache_init_luma_chroma_base_addr(u32 dpb,
+	u32 *pn_dpb_luma_offset, u32 *pn_dpb_chroma_offset)
+{
+	u32 count, num_dpb_used = dpb;
+	u32 dpb_reset_value = VIDC_1080P_DEC_DPB_RESET_VALUE;
+
+	if (num_dpb_used > VIDC_1080P_MAX_DEC_DPB)
+		num_dpb_used = VIDC_1080P_MAX_DEC_DPB;
+	for (count = 0; count < VIDC_1080P_MAX_DEC_DPB; count++) {
+		if (count < num_dpb_used) {
+			if (pn_dpb_luma_offset) {
+				VIDC_HWIO_OUTI(
+					REG_804925,
+					count, pn_dpb_luma_offset[count]);
+			} else {
+				VIDC_HWIO_OUTI(
+					REG_804925,
+					count, dpb_reset_value);
+			}
+			if (pn_dpb_chroma_offset) {
+				VIDC_HWIO_OUTI(
+					REG_41909,
+					count, pn_dpb_chroma_offset[count]);
+			} else {
+				VIDC_HWIO_OUTI(
+					REG_41909,
+					count, dpb_reset_value);
+			}
+		} else {
+			VIDC_HWIO_OUTI(REG_804925,
+				count, dpb_reset_value);
+			VIDC_HWIO_OUTI(REG_41909,
+				count, dpb_reset_value);
+		}
+	}
+}
+
+void vidc_pix_cache_set_frame_range(u32 luma_size, u32 chroma_size)
+{
+	u32 frame_range;
+
+	frame_range =
+		(((luma_size / VIDC_TILE_MULTIPLY_FACTOR) & 0xFF) << 8)|
+		((chroma_size / VIDC_TILE_MULTIPLY_FACTOR) & 0xFF);
+	VIDC_HWIO_OUT(REG_905239, frame_range);
+}
+void vidc_pix_cache_set_frame_size(u32 frame_width, u32 frame_height)
+{
+   u32 frame_size;
+   frame_size =  (((u32) (frame_height << HWIO_REG_951731_FRAME_HEIGHT_SHFT) &
+		HWIO_REG_951731_FRAME_HEIGHT_BMSK) |
+		((u32) (frame_width << HWIO_REG_951731_FRAME_WIDTH_SHFT) &
+		 HWIO_REG_951731_FRAME_WIDTH_BMSK));
+   VIDC_HWIO_OUT(REG_951731, frame_size);
+}
+
+void vidc_pix_cache_init_config(
+	struct vidc_1080P_pix_cache_config *config)
+{
+	u32 cfg_reg = 0;
+
+	if (config->cache_enable)
+		cfg_reg |= HWIO_REG_22756_CACHE_EN_BMSK;
+	else
+		cfg_reg &= (~HWIO_REG_22756_CACHE_EN_BMSK);
+	if (config->port_select == VIDC_1080P_PIX_CACHE_PORT_A)
+		cfg_reg &=
+			(~HWIO_REG_22756_CACHE_PORT_SELECT_BMSK);
+	else
+		cfg_reg |= HWIO_REG_22756_CACHE_PORT_SELECT_BMSK;
+	if (!config->statistics_off)
+		cfg_reg |= HWIO_REG_22756_STATISTICS_OFF_BMSK;
+	else
+		cfg_reg &= (~HWIO_REG_22756_STATISTICS_OFF_BMSK);
+	if (config->prefetch_en)
+		cfg_reg |= HWIO_REG_22756_PREFETCH_EN_BMSK;
+	else
+		cfg_reg &= (~HWIO_REG_22756_PREFETCH_EN_BMSK);
+	cfg_reg &= (~HWIO_REG_22756_PAGE_SIZE_BMSK);
+	cfg_reg |= VIDC_SETFIELD(config->page_size,
+			HWIO_REG_22756_PAGE_SIZE_SHFT,
+			HWIO_REG_22756_PAGE_SIZE_BMSK);
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+}
+
+void vidc_pix_cache_set_prefetch_page_limit(u32 page_size_limit)
+{
+	u32 cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_22756, &cfg_reg);
+	cfg_reg &= (~HWIO_REG_22756_PAGE_SIZE_BMSK);
+	cfg_reg |= VIDC_SETFIELD(page_size_limit,
+			HWIO_REG_22756_PAGE_SIZE_SHFT,
+			HWIO_REG_22756_PAGE_SIZE_BMSK);
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+}
+
+void vidc_pix_cache_enable_prefetch(u32 prefetch_enable)
+{
+	u32 cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_22756, &cfg_reg);
+	if (prefetch_enable)
+		cfg_reg |= HWIO_REG_22756_PREFETCH_EN_BMSK;
+	else
+		cfg_reg &= (~HWIO_REG_22756_PREFETCH_EN_BMSK);
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+}
+
+void vidc_pix_cache_disable_statistics(u32 statistics_off)
+{
+	u32 cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_22756, &cfg_reg);
+	if (!statistics_off)
+		cfg_reg |= HWIO_REG_22756_STATISTICS_OFF_BMSK;
+	else
+		cfg_reg &= (~HWIO_REG_22756_STATISTICS_OFF_BMSK);
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+}
+
+void vidc_pix_cache_set_port(
+	enum vidc_1080P_pix_cache_port_sel port_select)
+{
+	u32 cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_22756, &cfg_reg);
+	if (port_select == VIDC_1080P_PIX_CACHE_PORT_A)
+		cfg_reg &=
+			(~HWIO_REG_22756_CACHE_PORT_SELECT_BMSK);
+	else
+		cfg_reg |= HWIO_REG_22756_CACHE_PORT_SELECT_BMSK;
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+}
+
+void vidc_pix_cache_enable_cache(u32 cache_enable)
+{
+	u32 cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_22756, &cfg_reg);
+	if (cache_enable)
+		cfg_reg |= HWIO_REG_22756_CACHE_EN_BMSK;
+	else
+		cfg_reg &= (~HWIO_REG_22756_CACHE_EN_BMSK);
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+}
+
+void vidc_pix_cache_clear_cache_tags(void)
+{
+	u32 cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_22756, &cfg_reg);
+	cfg_reg |= HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK;
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+	VIDC_HWIO_IN(REG_22756, &cfg_reg);
+	cfg_reg &= (~HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK);
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+}
+
+void vidc_pix_cache_set_halt(u32 halt_enable)
+{
+	u32 cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_22756, &cfg_reg);
+	if (halt_enable)
+		cfg_reg |= HWIO_REG_22756_CACHE_HALT_BMSK;
+	else
+		cfg_reg &= (~HWIO_REG_22756_CACHE_HALT_BMSK);
+	VIDC_HWIO_OUT(REG_22756, cfg_reg);
+}
+
+void vidc_pix_cache_get_status_idle(u32 *idle_status)
+{
+	VIDC_HWIO_IN(REG_919904, idle_status);
+}
+
+void vidc_pix_cache_set_ram(u32 ram_select)
+{
+	u32 dmi_cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg);
+	dmi_cfg_reg &= (~HWIO_REG_261029_DMI_RAM_SEL_BMSK);
+	dmi_cfg_reg |= VIDC_SETFIELD(ram_select,
+			HWIO_REG_261029_AUTO_INC_EN_SHFT,
+			HWIO_REG_261029_DMI_RAM_SEL_BMSK);
+	VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg);
+}
+
+void vidc_pix_cache_set_auto_inc_ram_addr(u32 auto_inc_enable)
+{
+	u32 dmi_cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg);
+	if (auto_inc_enable)
+		dmi_cfg_reg |= HWIO_REG_261029_AUTO_INC_EN_BMSK;
+	else
+		dmi_cfg_reg &= (~HWIO_REG_261029_AUTO_INC_EN_BMSK);
+	VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg);
+}
+
+
+void vidc_pix_cache_read_ram_data(u32 src_ram_address,
+	u32 ram_size, u32 *dest_address)
+{
+	u32 count, dmi_cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg);
+	VIDC_HWIO_OUT(REG_576200, src_ram_address);
+	vidc_pix_cache_set_auto_inc_ram_addr(1);
+	for (count = 0; count < ram_size; count++) {
+		VIDC_HWIO_IN(REG_556274, dest_address);
+		dest_address++;
+		VIDC_HWIO_IN(REG_917583, dest_address);
+		dest_address++;
+	}
+	VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg);
+}
+
+void vidc_pix_cache_write_ram_data(u32 *src_address,
+	u32 ram_size, u32 dest_ram_address)
+{
+	u32 count, dmi_cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg);
+	VIDC_HWIO_OUT(REG_576200, dest_ram_address);
+	vidc_pix_cache_set_auto_inc_ram_addr(1);
+	for (count = 0; count < ram_size; count++) {
+		VIDC_HWIO_OUT(REG_917583, *src_address);
+		src_address++;
+		VIDC_HWIO_OUT(REG_556274, *src_address);
+		src_address++;
+	}
+	VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg);
+}
+
+void vidc_pix_cache_get_statistics(
+	struct vidc_1080P_pix_cache_statistics *statistics)
+{
+	VIDC_HWIO_IN(REG_278310,
+		&statistics->access_miss);
+	VIDC_HWIO_IN(REG_421222,
+		&statistics->access_hit);
+	VIDC_HWIO_IN(REG_609607,
+		&statistics->axi_req);
+	VIDC_HWIO_IN(REG_395232,
+		&statistics->core_req);
+	VIDC_HWIO_IN(REG_450146,
+		&statistics->axi_bus);
+	VIDC_HWIO_IN(REG_610651,
+		&statistics->core_bus);
+}
+
+void vidc_pix_cache_enable_misr(u32 misr_enable)
+{
+   u32 misr_cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_883784, &misr_cfg_reg);
+	if (misr_enable)
+		misr_cfg_reg |= HWIO_REG_883784_MISR_EN_BMSK;
+	else
+		misr_cfg_reg &=
+			(~HWIO_REG_883784_MISR_EN_BMSK);
+	VIDC_HWIO_OUT(REG_261029, misr_cfg_reg);
+}
+
+void vidc_pix_cache_set_misr_interface(u32 input_select)
+{
+	u32 misr_cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_883784, &misr_cfg_reg);
+	misr_cfg_reg &= (~HWIO_REG_883784_INPUT_SEL_BMSK);
+	misr_cfg_reg |= VIDC_SETFIELD(input_select,
+			HWIO_REG_883784_INPUT_SEL_SHFT,
+			HWIO_REG_883784_INPUT_SEL_BMSK);
+	VIDC_HWIO_OUT(REG_261029, misr_cfg_reg);
+}
+
+void vidc_pix_cache_set_misr_id_filtering(
+	struct vidc_1080P_pix_cache_misr_id_filtering *filter_id)
+{
+	u32 misr_cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_883784, &misr_cfg_reg);
+	if (filter_id->ignore_id)
+		misr_cfg_reg |=
+			HWIO_REG_883784_IGNORE_ID_BMSK;
+	else
+		misr_cfg_reg &=
+			(~HWIO_REG_883784_IGNORE_ID_BMSK);
+	misr_cfg_reg &= (~HWIO_REG_883784_ID_BMSK);
+	misr_cfg_reg |= VIDC_SETFIELD(filter_id->id,
+			HWIO_REG_883784_ID_SHFT,
+			HWIO_REG_883784_ID_BMSK);
+	VIDC_HWIO_OUT(REG_261029, misr_cfg_reg);
+}
+
+void vidc_pix_cache_set_misr_filter_trans(u32 no_of_trans)
+{
+	u32 misr_cfg_reg = 0;
+
+	VIDC_HWIO_IN(REG_883784, &misr_cfg_reg);
+	misr_cfg_reg &= (~HWIO_REG_883784_COUNTER_BMSK);
+	misr_cfg_reg |= VIDC_SETFIELD(no_of_trans,
+			HWIO_REG_883784_COUNTER_SHFT,
+			HWIO_REG_883784_COUNTER_BMSK);
+	VIDC_HWIO_OUT(REG_261029, misr_cfg_reg);
+}
+
+void vidc_pix_cache_get_misr_signatures(
+	struct vidc_1080P_pix_cache_misr_signature *signatures)
+{
+	VIDC_HWIO_INI(REG_651391, 0,
+		&signatures->signature0);
+	VIDC_HWIO_INI(REG_651391, 1,
+		&signatures->signature1);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h
new file mode 100644
index 0000000..e8a93a1
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h
@@ -0,0 +1,87 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VIDEO_CORE_PIXCACHE_
+#define _VIDEO_CORE_PIXCACHE_
+
+
+#include "vidc.h"
+
+#define VIDC_1080P_DEC_DPB_RESET_VALUE 0xFFFFFFF8
+
+enum vidc_1080P_pix_cache_port_sel{
+	VIDC_1080P_PIX_CACHE_PORT_A = 0,
+	VIDC_1080P_PIX_CACHE_PORT_B = 1,
+	VIDC_1080P_PIX_CACHE_PORT_32BIT = 0x7FFFFFFF
+};
+enum vidc_1080P_pix_cache_page_size{
+	VIDC_1080P_PIX_CACHE_PAGE_SIZE_1K = 0,
+	VIDC_1080P_PIX_CACHE_PAGE_SIZE_2K = 1,
+	VIDC_1080P_PIX_CACHE_PAGE_SIZE_4K = 2
+};
+struct vidc_1080P_pix_cache_config{
+	u32 cache_enable;
+	u32 prefetch_en;
+	enum vidc_1080P_pix_cache_port_sel port_select;
+	u32 statistics_off;
+	enum vidc_1080P_pix_cache_page_size page_size;
+};
+struct vidc_1080P_pix_cache_statistics{
+	u32 access_miss;
+	u32 access_hit;
+	u32 axi_req;
+	u32 core_req;
+	u32 axi_bus;
+	u32 core_bus;
+};
+struct vidc_1080P_pix_cache_misr_id_filtering{
+	u32 ignore_id;
+	u32 id;
+};
+struct vidc_1080P_pix_cache_misr_signature{
+	u32 signature0;
+	u32 signature1;
+};
+
+void vidc_pix_cache_sw_reset(void);
+void vidc_pix_cache_init_luma_chroma_base_addr(u32 dpb,
+	u32 *pn_dpb_luma_offset, u32 *pn_dpb_chroma_offset);
+void vidc_pix_cache_set_frame_range(u32 luma_size, u32 chroma_size);
+void vidc_pix_cache_set_frame_size(u32 frame_width, u32 frame_height);
+void vidc_pix_cache_init_config(
+	struct vidc_1080P_pix_cache_config *config);
+void vidc_pix_cache_set_prefetch_page_limit(u32 page_size_limit);
+void vidc_pix_cache_enable_prefetch(u32 prefetch_enable);
+void vidc_pix_cache_disable_statistics(u32 statistics_off);
+void vidc_pix_cache_set_port(
+	enum vidc_1080P_pix_cache_port_sel port_select);
+void vidc_pix_cache_enable_cache(u32 cache_enable);
+void vidc_pix_cache_clear_cache_tags(void);
+void vidc_pix_cache_set_halt(u32 halt_enable);
+void vidc_pix_cache_get_status_idle(u32 *idle_status);
+void vidc_pix_cache_set_ram(u32 ram_select);
+void vidc_pix_cache_set_auto_inc_ram_addr(u32 auto_inc_enable);
+void vidc_pix_cache_read_ram_data(u32 src_ram_address, u32 ram_size,
+	u32 *dest_address);
+void vidc_pix_cache_write_ram_data(u32 *src_address, u32 ram_size,
+	u32 dest_ram_address);
+void vidc_pix_cache_get_statistics(
+	struct vidc_1080P_pix_cache_statistics *statistics);
+void vidc_pix_cache_enable_misr(u32 misr_enable);
+void vidc_pix_cache_set_misr_interface(u32 input_select);
+void vidc_pix_cache_set_misr_id_filtering(
+	struct vidc_1080P_pix_cache_misr_id_filtering *filter_id);
+void vidc_pix_cache_set_misr_filter_trans(u32 no_of_trans);
+void vidc_pix_cache_get_misr_signatures(
+	struct vidc_1080P_pix_cache_misr_signature *signatures);
+#endif
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
new file mode 100755
index 0000000..7af0de3
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -0,0 +1,991 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/firmware.h>
+#include <linux/pm_qos_params.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+#include <mach/clk.h>
+#include <mach/msm_memtypes.h>
+#include <linux/interrupt.h>
+#include <linux/memory_alloc.h>
+#include <asm/sizes.h>
+#include <media/msm/vidc_init.h>
+#include "vidc.h"
+#include "vcd_res_tracker.h"
+
+#define PIL_FW_BASE_ADDR 0xafe00000
+#define PIL_FW_SIZE 0x200000
+
+static unsigned int vidc_clk_table[4] = {
+	48000000, 133330000, 200000000, 228570000,
+};
+static unsigned int restrk_mmu_subsystem[] =	{
+		MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
+static struct res_trk_context resource_context;
+
+#define VIDC_FW	"vidc_1080p.fw"
+#define VIDC_FW_SIZE SZ_1M
+
+struct res_trk_vidc_mmu_clk {
+	char *mmu_clk_name;
+	struct clk *mmu_clk;
+};
+
+static struct res_trk_vidc_mmu_clk vidc_mmu_clks[] = {
+	{"mdp_iommu_clk"}, {"rot_iommu_clk"},
+	{"vcodec_iommu0_clk"}, {"vcodec_iommu1_clk"},
+	{"smmu_iface_clk"}
+};
+
+unsigned char *vidc_video_codec_fw;
+u32 vidc_video_codec_fw_size;
+static u32 res_trk_get_clk(void);
+static void res_trk_put_clk(void);
+
+static void *res_trk_pmem_map
+	(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+	u32 offset = 0, flags = 0;
+	u32 index = 0;
+	struct ddl_context *ddl_context;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	int ret = 0;
+	unsigned long iova = 0;
+	unsigned long buffer_size  = 0;
+	unsigned long *kernel_vaddr = NULL;
+
+	ddl_context = ddl_get_context();
+	if (res_trk_get_enable_ion() && addr->alloc_handle) {
+		kernel_vaddr = (unsigned long *) ion_map_kernel(
+					ddl_context->video_ion_client,
+					addr->alloc_handle, UNCACHED);
+		if (IS_ERR_OR_NULL(kernel_vaddr)) {
+			DDL_MSG_ERROR("%s():DDL ION client map failed\n",
+						 __func__);
+			goto ion_bail_out;
+		}
+		addr->virtual_base_addr = (u8 *) kernel_vaddr;
+		ret = ion_map_iommu(ddl_context->video_ion_client,
+				addr->alloc_handle,
+				VIDEO_DOMAIN,
+				VIDEO_FIRMWARE_POOL,
+				SZ_4K,
+				0,
+				&iova,
+				&buffer_size,
+				UNCACHED, 0);
+		if (ret) {
+			DDL_MSG_ERROR("%s():DDL ION client iommu map failed\n",
+						 __func__);
+			goto ion_unmap_bail_out;
+		}
+		addr->mapped_buffer = NULL;
+		addr->physical_base_addr = (u8 *)iova;
+		addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
+		addr->physical_base_addr, alignment);
+		offset = (u32)(addr->align_physical_addr -
+				addr->physical_base_addr);
+		addr->align_virtual_addr = addr->virtual_base_addr + offset;
+		addr->buffer_size = buffer_size;
+	} else {
+		if (!res_trk_check_for_sec_session()) {
+			if (!addr->alloced_phys_addr) {
+				pr_err(" %s() alloced addres NULL", __func__);
+				goto bail_out;
+			}
+			flags = MSM_SUBSYSTEM_MAP_IOVA|MSM_SUBSYSTEM_MAP_KADDR;
+			if (alignment == DDL_KILO_BYTE(128))
+					index = 1;
+			else if (alignment > SZ_4K)
+				flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;
+
+			addr->mapped_buffer =
+			msm_subsystem_map_buffer(
+			(unsigned long)addr->alloced_phys_addr,
+			sz, flags, &restrk_mmu_subsystem[index],
+			sizeof(restrk_mmu_subsystem[index])
+			/sizeof(unsigned int));
+			if (IS_ERR(addr->mapped_buffer)) {
+				pr_err(" %s() buffer map failed", __func__);
+				goto bail_out;
+			}
+			mapped_buffer = addr->mapped_buffer;
+			if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
+				pr_err("%s() map buffers failed\n", __func__);
+				goto bail_out;
+			}
+			addr->physical_base_addr = (u8 *)mapped_buffer->iova[0];
+			addr->virtual_base_addr = mapped_buffer->vaddr;
+		} else {
+			addr->physical_base_addr = (u8 *)
+					 addr->alloced_phys_addr;
+			addr->virtual_base_addr = (u8 *)
+					addr->alloced_phys_addr;
+		}
+		addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
+		addr->physical_base_addr, alignment);
+		offset = (u32)(addr->align_physical_addr -
+				addr->physical_base_addr);
+		addr->align_virtual_addr = addr->virtual_base_addr + offset;
+		addr->buffer_size = sz;
+	}
+	return addr->virtual_base_addr;
+bail_out:
+	if (addr->mapped_buffer)
+		msm_subsystem_unmap_buffer(addr->mapped_buffer);
+	return NULL;
+ion_unmap_bail_out:
+	if (!IS_ERR_OR_NULL(addr->alloc_handle)) {
+		ion_unmap_kernel(resource_context.
+			res_ion_client,	addr->alloc_handle);
+	}
+ion_bail_out:
+	return NULL;
+}
+
+static void res_trk_pmem_free(struct ddl_buf_addr *addr)
+{
+	/* TODO Pmem*/
+	struct ddl_context *ddl_context;
+	ddl_context = ddl_get_context();
+	if (ddl_context->video_ion_client) {
+		if (addr && addr->alloc_handle) {
+			ion_free(ddl_context->video_ion_client, addr->alloc_handle);
+			addr->alloc_handle = NULL;
+		}
+	}
+}
+static int res_trk_pmem_alloc
+	(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+	u32 alloc_size;
+	struct ddl_context *ddl_context;
+	int rc = 0;
+	DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
+	if (!addr) {
+		DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__);
+		rc = -EINVAL;
+		goto bail_out;
+	}
+	ddl_context = ddl_get_context();
+	res_trk_set_mem_type(addr->mem_type);
+	alloc_size = (sz + alignment);
+	if (res_trk_get_enable_ion()) {
+		if (!res_trk_is_cp_enabled() || !res_trk_check_for_sec_session()) {
+			if (!ddl_context->video_ion_client)
+				ddl_context->video_ion_client =
+					res_trk_get_ion_client();
+			if (!ddl_context->video_ion_client) {
+				DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n",
+							 __func__);
+				rc = -ENOMEM;
+				goto bail_out;
+			}
+			alloc_size = (alloc_size+4095) & ~4095;
+			addr->alloc_handle = ion_alloc(
+			ddl_context->video_ion_client, alloc_size, SZ_4K,
+				res_trk_get_mem_type());
+			if (IS_ERR_OR_NULL(addr->alloc_handle)) {
+				DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
+							 __func__);
+				rc = -ENOMEM;
+				goto bail_out;
+			}
+		} else {
+			addr->alloc_handle = NULL;
+			addr->alloced_phys_addr = PIL_FW_BASE_ADDR;
+			addr->buffer_size = sz;
+		}
+	} else {
+		addr->alloced_phys_addr = (phys_addr_t)
+			allocate_contiguous_memory_nomap(alloc_size,
+					res_trk_get_mem_type(), SZ_4K);
+		if (!addr->alloced_phys_addr) {
+			DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n",
+					__func__, alloc_size);
+			rc = -ENOMEM;
+			goto bail_out;
+		}
+		addr->buffer_size = sz;
+		return rc;
+	}
+bail_out:
+	return rc;
+}
+
+static void res_trk_pmem_unmap(struct ddl_buf_addr *addr)
+{
+	if (!addr) {
+		pr_err("%s() invalid args\n", __func__);
+		return;
+	}
+	if (!IS_ERR_OR_NULL(addr->alloc_handle)) {
+		if (addr->physical_base_addr) {
+			ion_unmap_kernel(resource_context.res_ion_client,
+					addr->alloc_handle);
+			if (!res_trk_check_for_sec_session()) {
+				ion_unmap_iommu(resource_context.res_ion_client,
+				addr->alloc_handle,
+				VIDEO_DOMAIN,
+				VIDEO_FIRMWARE_POOL);
+			}
+			addr->virtual_base_addr = NULL;
+			addr->physical_base_addr = NULL;
+		}
+	} else if (addr->mapped_buffer)
+		msm_subsystem_unmap_buffer(addr->mapped_buffer);
+	addr->mapped_buffer = NULL;
+}
+
+static u32 res_trk_get_clk()
+{
+	if (resource_context.vcodec_clk ||
+		resource_context.vcodec_pclk) {
+		VCDRES_MSG_ERROR("%s() Clock reference exists\n",
+						__func__);
+		goto bail_out;
+	}
+	resource_context.vcodec_clk = clk_get(resource_context.device,
+		"core_clk");
+	if (IS_ERR(resource_context.vcodec_clk)) {
+		VCDRES_MSG_ERROR("%s(): core_clk get failed\n",
+						__func__);
+		goto bail_out;
+	}
+	 resource_context.vcodec_pclk = clk_get(resource_context.device,
+		"iface_clk");
+	if (IS_ERR(resource_context.vcodec_pclk)) {
+		VCDRES_MSG_ERROR("%s(): iface_clk get failed\n",
+						__func__);
+		goto release_vcodec_clk;
+	}
+	if (clk_set_rate(resource_context.vcodec_clk,
+		vidc_clk_table[0])) {
+		VCDRES_MSG_ERROR("%s(): set rate failed in power up\n",
+						__func__);
+		goto release_vcodec_pclk;
+	}
+	return true;
+release_vcodec_pclk:
+	clk_put(resource_context.vcodec_pclk);
+	resource_context.vcodec_pclk = NULL;
+release_vcodec_clk:
+	clk_put(resource_context.vcodec_clk);
+	resource_context.vcodec_clk = NULL;
+bail_out:
+	return false;
+}
+
+static void res_trk_put_clk()
+{
+	if (resource_context.vcodec_clk)
+		clk_put(resource_context.vcodec_clk);
+	if (resource_context.vcodec_pclk)
+		clk_put(resource_context.vcodec_pclk);
+	resource_context.vcodec_clk = NULL;
+	resource_context.vcodec_pclk = NULL;
+}
+
+static u32 res_trk_shutdown_vidc(void)
+{
+	mutex_lock(&resource_context.lock);
+	if (resource_context.clock_enabled) {
+		mutex_unlock(&resource_context.lock);
+		VCDRES_MSG_LOW("\n Calling CLK disable in Power Down\n");
+		res_trk_disable_clocks();
+		mutex_lock(&resource_context.lock);
+	}
+	res_trk_put_clk();
+	if (resource_context.footswitch) {
+		if (regulator_disable(resource_context.footswitch))
+			VCDRES_MSG_ERROR("Regulator disable failed\n");
+		regulator_put(resource_context.footswitch);
+		resource_context.footswitch = NULL;
+	}
+	if (pm_runtime_put(resource_context.device) < 0)
+		VCDRES_MSG_ERROR("Error : pm_runtime_put failed");
+	mutex_unlock(&resource_context.lock);
+	return true;
+}
+
+u32 res_trk_enable_clocks(void)
+{
+	VCDRES_MSG_LOW("\n in res_trk_enable_clocks()");
+	mutex_lock(&resource_context.lock);
+	if (!resource_context.clock_enabled) {
+		VCDRES_MSG_LOW("Enabling IRQ in %s()\n", __func__);
+		enable_irq(resource_context.irq_num);
+		VCDRES_MSG_LOW("%s(): Enabling the clocks\n", __func__);
+		if (resource_context.vcodec_clk &&
+			resource_context.vcodec_pclk) {
+			if (clk_enable(resource_context.vcodec_pclk)) {
+				VCDRES_MSG_ERROR("vidc pclk Enable fail\n");
+				goto bail_out;
+			}
+			if (clk_enable(resource_context.vcodec_clk)) {
+				VCDRES_MSG_ERROR("vidc core clk Enable fail\n");
+				goto vidc_disable_pclk;
+			}
+
+			VCDRES_MSG_LOW("%s(): Clocks enabled!\n", __func__);
+		} else {
+		   VCDRES_MSG_ERROR("%s(): Clocks enable failed!\n",
+			__func__);
+		   goto bail_out;
+		}
+	}
+	resource_context.clock_enabled = 1;
+	mutex_unlock(&resource_context.lock);
+	return true;
+vidc_disable_pclk:
+	clk_disable(resource_context.vcodec_pclk);
+bail_out:
+	mutex_unlock(&resource_context.lock);
+	return false;
+}
+
+static u32 res_trk_sel_clk_rate(unsigned long hclk_rate)
+{
+	u32 status = true;
+	mutex_lock(&resource_context.lock);
+	if (clk_set_rate(resource_context.vcodec_clk,
+		hclk_rate)) {
+		VCDRES_MSG_ERROR("vidc hclk set rate failed\n");
+		status = false;
+	} else
+		resource_context.vcodec_clk_rate = hclk_rate;
+	mutex_unlock(&resource_context.lock);
+	return status;
+}
+
+u32 res_trk_get_clk_rate(unsigned long *phclk_rate)
+{
+	u32 status = true;
+	mutex_lock(&resource_context.lock);
+	if (phclk_rate) {
+		*phclk_rate = clk_get_rate(resource_context.vcodec_clk);
+		if (!(*phclk_rate)) {
+			VCDRES_MSG_ERROR("vidc hclk get rate failed\n");
+			status = false;
+		}
+	} else
+		status = false;
+	mutex_unlock(&resource_context.lock);
+	return status;
+}
+
+u32 res_trk_disable_clocks(void)
+{
+	u32 status = false;
+	VCDRES_MSG_LOW("in res_trk_disable_clocks()\n");
+	mutex_lock(&resource_context.lock);
+	if (resource_context.clock_enabled) {
+		VCDRES_MSG_LOW("Disabling IRQ in %s()\n", __func__);
+		disable_irq_nosync(resource_context.irq_num);
+		VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__);
+		resource_context.clock_enabled = 0;
+		if (resource_context.vcodec_clk)
+			clk_disable(resource_context.vcodec_clk);
+		if (resource_context.vcodec_pclk)
+			clk_disable(resource_context.vcodec_pclk);
+		status = true;
+	}
+	mutex_unlock(&resource_context.lock);
+	return status;
+}
+
+static u32 res_trk_vidc_pwr_up(void)
+{
+	mutex_lock(&resource_context.lock);
+
+	if (pm_runtime_get(resource_context.device) < 0) {
+		VCDRES_MSG_ERROR("Error : pm_runtime_get failed\n");
+		goto bail_out;
+	}
+	resource_context.footswitch = regulator_get(NULL, "fs_ved");
+	if (IS_ERR(resource_context.footswitch)) {
+		VCDRES_MSG_ERROR("foot switch get failed\n");
+		resource_context.footswitch = NULL;
+	} else
+		regulator_enable(resource_context.footswitch);
+	if (!res_trk_get_clk())
+		goto rel_vidc_pm_runtime;
+	mutex_unlock(&resource_context.lock);
+	return true;
+
+rel_vidc_pm_runtime:
+	if (pm_runtime_put(resource_context.device) < 0)
+		VCDRES_MSG_ERROR("Error : pm_runtime_put failed");
+bail_out:
+	mutex_unlock(&resource_context.lock);
+	return false;
+}
+
+static struct ion_client *res_trk_create_ion_client(void){
+	struct ion_client *video_client;
+	video_client = msm_ion_client_create(-1, "video_client");
+	return video_client;
+}
+
+int res_trk_enable_footswitch(void)
+{
+	int rc = 0;
+	mutex_lock(&resource_context.lock);
+	resource_context.footswitch = regulator_get(NULL, "fs_ved");
+	if (IS_ERR(resource_context.footswitch)) {
+		VCDRES_MSG_ERROR("foot switch get failed\n");
+		resource_context.footswitch = NULL;
+		rc = -EINVAL;
+	} else
+		rc = regulator_enable(resource_context.footswitch);
+	mutex_unlock(&resource_context.lock);
+	return rc;
+}
+
+int res_trk_disable_footswitch(void)
+{
+	mutex_lock(&resource_context.lock);
+	if (resource_context.footswitch) {
+		if (regulator_disable(resource_context.footswitch))
+			VCDRES_MSG_ERROR("Regulator disable failed\n");
+		regulator_put(resource_context.footswitch);
+		resource_context.footswitch = NULL;
+	}
+	mutex_unlock(&resource_context.lock);
+	return 0;
+}
+
+u32 res_trk_power_up(void)
+{
+	VCDRES_MSG_LOW("clk_regime_rail_enable");
+	VCDRES_MSG_LOW("clk_regime_sel_rail_control");
+#ifdef CONFIG_MSM_BUS_SCALING
+	resource_context.pcl = 0;
+	if (resource_context.vidc_bus_client_pdata) {
+		resource_context.pcl = msm_bus_scale_register_client(
+			resource_context.vidc_bus_client_pdata);
+		VCDRES_MSG_LOW("%s(), resource_context.pcl = %x", __func__,
+			 resource_context.pcl);
+	}
+	if (resource_context.pcl == 0) {
+		dev_err(resource_context.device,
+			"register bus client returned NULL\n");
+		return false;
+	}
+#endif
+	return res_trk_vidc_pwr_up();
+}
+
+u32 res_trk_power_down(void)
+{
+	VCDRES_MSG_LOW("clk_regime_rail_disable");
+	res_trk_pmem_unmap(&resource_context.firmware_addr);
+	res_trk_pmem_free(&resource_context.firmware_addr);
+#ifdef CONFIG_MSM_BUS_SCALING
+	msm_bus_scale_client_update_request(resource_context.pcl, 0);
+	msm_bus_scale_unregister_client(resource_context.pcl);
+#endif
+	VCDRES_MSG_MED("res_trk_power_down():: Calling "
+		"res_trk_shutdown_vidc()\n");
+	return res_trk_shutdown_vidc();
+}
+
+u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl)
+{
+	if (!pn_max_perf_lvl) {
+		VCDRES_MSG_ERROR("%s(): pn_max_perf_lvl is NULL\n",
+			__func__);
+		return false;
+	}
+	*pn_max_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL;
+	return true;
+}
+
+#ifdef CONFIG_MSM_BUS_SCALING
+int res_trk_update_bus_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_level)
+{
+	struct vcd_clnt_ctxt *cctxt_itr = NULL;
+	u32 enc_perf_level = 0, dec_perf_level = 0;
+	u32 bus_clk_index, client_type = 0;
+	int rc = 0;
+
+	cctxt_itr = dev_ctxt->cctxt_list_head;
+	while (cctxt_itr) {
+		if (cctxt_itr->decoding)
+			dec_perf_level += cctxt_itr->reqd_perf_lvl;
+		else
+			enc_perf_level += cctxt_itr->reqd_perf_lvl;
+		cctxt_itr = cctxt_itr->next;
+	}
+
+	if (!enc_perf_level)
+		client_type = 1;
+	if (perf_level <= RESTRK_1080P_VGA_PERF_LEVEL)
+		bus_clk_index = 0;
+	else if (perf_level <= RESTRK_1080P_720P_PERF_LEVEL)
+		bus_clk_index = 1;
+	else if (perf_level <= RESTRK_1080P_MAX_PERF_LEVEL)
+		bus_clk_index = 2;
+	else
+		bus_clk_index = 3;
+
+	if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0)
+		bus_clk_index = 2;
+	else if (resource_context.vidc_platform_data->disable_turbo
+						&& bus_clk_index == 3) {
+		VCDRES_MSG_ERROR("Warning: Turbo mode not supported "
+				" falling back to 1080p bus\n");
+		bus_clk_index = 2;
+	}
+
+	bus_clk_index = (bus_clk_index << 1) + (client_type + 1);
+	VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index);
+	VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl);
+	VCDRES_MSG_LOW("%s(), bus_perf_level = %x", __func__, perf_level);
+	rc = msm_bus_scale_client_update_request(resource_context.pcl,
+		bus_clk_index);
+	return rc;
+}
+#endif
+
+u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl,
+	struct vcd_dev_ctxt *dev_ctxt)
+{
+	u32 vidc_freq = 0;
+	if (!pn_set_perf_lvl || !dev_ctxt) {
+		VCDRES_MSG_ERROR("%s(): NULL pointer! dev_ctxt(%p)\n",
+			__func__, dev_ctxt);
+		return false;
+	}
+	VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl);
+
+	if (resource_context.vidc_platform_data->disable_turbo
+			&& req_perf_lvl > RESTRK_1080P_MAX_PERF_LEVEL) {
+		VCDRES_MSG_ERROR("%s(): Turbo not supported! dev_ctxt(%p)\n",
+			__func__, dev_ctxt);
+	}
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (!res_trk_update_bus_perf_level(dev_ctxt, req_perf_lvl) < 0) {
+		VCDRES_MSG_ERROR("%s(): update buf perf level failed\n",
+			__func__);
+		return false;
+	}
+
+#endif
+	if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0)
+		req_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL;
+
+	if (req_perf_lvl <= RESTRK_1080P_VGA_PERF_LEVEL) {
+		vidc_freq = vidc_clk_table[0];
+		*pn_set_perf_lvl = RESTRK_1080P_VGA_PERF_LEVEL;
+	} else if (req_perf_lvl <= RESTRK_1080P_720P_PERF_LEVEL) {
+		vidc_freq = vidc_clk_table[1];
+		*pn_set_perf_lvl = RESTRK_1080P_720P_PERF_LEVEL;
+	} else if (req_perf_lvl <= RESTRK_1080P_MAX_PERF_LEVEL) {
+		vidc_freq = vidc_clk_table[2];
+		*pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL;
+	} else {
+		vidc_freq = vidc_clk_table[3];
+		*pn_set_perf_lvl = RESTRK_1080P_TURBO_PERF_LEVEL;
+	}
+
+	if (resource_context.vidc_platform_data->disable_turbo &&
+		*pn_set_perf_lvl == RESTRK_1080P_TURBO_PERF_LEVEL) {
+		VCDRES_MSG_ERROR("Warning: Turbo mode not supported "
+				" falling back to 1080p clocks\n");
+		vidc_freq = vidc_clk_table[2];
+		*pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL;
+	}
+
+	resource_context.perf_level = *pn_set_perf_lvl;
+	VCDRES_MSG_MED("VIDC: vidc_freq = %u, req_perf_lvl = %u\n",
+		vidc_freq, req_perf_lvl);
+#ifdef USE_RES_TRACKER
+    if (req_perf_lvl != RESTRK_1080P_MIN_PERF_LEVEL) {
+		VCDRES_MSG_MED("%s(): Setting vidc freq to %u\n",
+			__func__, vidc_freq);
+		if (!res_trk_sel_clk_rate(vidc_freq)) {
+			VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n",
+				__func__);
+			*pn_set_perf_lvl = 0;
+			return false;
+		}
+	}
+#endif
+	VCDRES_MSG_MED("%s() set perl level : %d", __func__, *pn_set_perf_lvl);
+	return true;
+}
+
+u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl)
+{
+	unsigned long freq;
+
+	if (!pn_perf_lvl) {
+		VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n",
+			__func__);
+		return false;
+	}
+	VCDRES_MSG_LOW("clk_regime_msm_get_clk_freq_hz");
+	if (!res_trk_get_clk_rate(&freq)) {
+		VCDRES_MSG_ERROR("%s(): res_trk_get_clk_rate FAILED\n",
+			__func__);
+		*pn_perf_lvl = 0;
+		return false;
+	}
+	*pn_perf_lvl = resource_context.perf_level;
+	VCDRES_MSG_MED("%s(): freq = %lu, *pn_perf_lvl = %u", __func__,
+		freq, *pn_perf_lvl);
+	return true;
+}
+
+u32 res_trk_download_firmware(void)
+{
+	const struct firmware *fw_video = NULL;
+	int rc = 0;
+	u32 status = true;
+
+	VCDRES_MSG_HIGH("%s(): Request firmware download\n",
+		__func__);
+	mutex_lock(&resource_context.lock);
+	rc = request_firmware(&fw_video, VIDC_FW,
+		resource_context.device);
+	if (rc) {
+		VCDRES_MSG_ERROR("request_firmware for %s error %d\n",
+				VIDC_FW, rc);
+		status = false;
+		goto bail_out;
+	}
+	vidc_video_codec_fw = (unsigned char *)fw_video->data;
+	vidc_video_codec_fw_size = (u32) fw_video->size;
+bail_out:
+	mutex_unlock(&resource_context.lock);
+	return status;
+}
+
+void res_trk_init(struct device *device, u32 irq)
+{
+	if (resource_context.device || resource_context.irq_num ||
+		!device) {
+		VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n",
+			__func__);
+	} else {
+		memset(&resource_context, 0, sizeof(resource_context));
+		mutex_init(&resource_context.lock);
+		mutex_init(&resource_context.secure_lock);
+		resource_context.device = device;
+		resource_context.irq_num = irq;
+		resource_context.vidc_platform_data =
+			(struct msm_vidc_platform_data *) device->platform_data;
+		if (resource_context.vidc_platform_data) {
+			resource_context.memtype =
+			resource_context.vidc_platform_data->memtype;
+			resource_context.fw_mem_type =
+			resource_context.vidc_platform_data->memtype;
+			resource_context.cmd_mem_type =
+			resource_context.vidc_platform_data->memtype;
+			if (resource_context.vidc_platform_data->enable_ion) {
+				resource_context.res_ion_client =
+					res_trk_create_ion_client();
+				if (!(resource_context.res_ion_client)) {
+					VCDRES_MSG_ERROR("%s()ION createfail\n",
+							__func__);
+					return;
+				}
+				resource_context.fw_mem_type =
+				ION_MM_FIRMWARE_HEAP_ID;
+				resource_context.cmd_mem_type =
+				ION_CP_MFC_HEAP_ID;
+			}
+			resource_context.disable_dmx =
+			resource_context.vidc_platform_data->disable_dmx;
+			resource_context.disable_fullhd =
+			resource_context.vidc_platform_data->disable_fullhd;
+#ifdef CONFIG_MSM_BUS_SCALING
+			resource_context.vidc_bus_client_pdata =
+			resource_context.vidc_platform_data->
+				vidc_bus_client_pdata;
+#endif
+		} else {
+			resource_context.memtype = -1;
+			resource_context.disable_dmx = 0;
+		}
+		resource_context.core_type = VCD_CORE_1080P;
+		resource_context.firmware_addr.mem_type = DDL_FW_MEM;
+	}
+}
+
+u32 res_trk_get_core_type(void){
+	return resource_context.core_type;
+}
+
+u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr)
+{
+	int rc = 0;
+	size_t size= 0;
+	if (!firm_addr || resource_context.firmware_addr.mapped_buffer) {
+		pr_err("%s() invalid params", __func__);
+		return -EINVAL;
+	}
+	if (res_trk_is_cp_enabled() && res_trk_check_for_sec_session())
+		size = PIL_FW_SIZE;
+	else
+		size = VIDC_FW_SIZE;
+
+	if (res_trk_pmem_alloc(&resource_context.firmware_addr,
+				size, DDL_KILO_BYTE(128))) {
+		pr_err("%s() Firmware buffer allocation failed",
+				__func__);
+		memset(&resource_context.firmware_addr, 0,
+				sizeof(resource_context.firmware_addr));
+		rc = -ENOMEM;
+		goto fail_alloc;
+	}
+	if (!res_trk_pmem_map(&resource_context.firmware_addr,
+		resource_context.firmware_addr.buffer_size,
+		DDL_KILO_BYTE(128))) {
+		pr_err("%s() Firmware buffer mapping failed",
+			   __func__);
+		rc = -ENOMEM;
+		goto fail_map;
+	}
+	memcpy(firm_addr, &resource_context.firmware_addr,
+			sizeof(struct ddl_buf_addr));
+	return 0;
+fail_map:
+	res_trk_pmem_free(&resource_context.firmware_addr);
+fail_alloc:
+	return rc;
+}
+
+void res_trk_release_fw_addr(void)
+{
+	res_trk_pmem_unmap(&resource_context.firmware_addr);
+	res_trk_pmem_free(&resource_context.firmware_addr);
+}
+
+int res_trk_check_for_sec_session(void)
+{
+	int rc;
+	mutex_lock(&resource_context.secure_lock);
+	rc = resource_context.secure_session;
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
+
+int res_trk_get_mem_type(void)
+{
+	int mem_type = -1;
+	switch (resource_context.res_mem_type) {
+	case DDL_FW_MEM:
+		mem_type = ION_HEAP(resource_context.fw_mem_type);
+		return mem_type;
+	case DDL_MM_MEM:
+		mem_type = resource_context.memtype;
+		break;
+	case DDL_CMD_MEM:
+		if (res_trk_check_for_sec_session())
+			mem_type = resource_context.cmd_mem_type;
+		else
+			mem_type = resource_context.memtype;
+		break;
+	default:
+		return mem_type;
+	}
+	if (resource_context.vidc_platform_data->enable_ion) {
+		if (res_trk_check_for_sec_session()) {
+         mem_type = ION_HEAP(mem_type);
+         if(resource_context.res_mem_type != DDL_FW_MEM)
+            mem_type |= ION_SECURE;
+         else if (res_trk_is_cp_enabled())
+            mem_type |= ION_SECURE;
+      }
+		else
+			mem_type = (ION_HEAP(mem_type) |
+					ION_HEAP(ION_IOMMU_HEAP_ID));
+	}
+	return mem_type;
+}
+
+u32 res_trk_is_cp_enabled(void)
+{
+	if (resource_context.vidc_platform_data->cp_enabled)
+		return 1;
+	else
+		return 0;
+}
+
+u32 res_trk_get_enable_ion(void)
+{
+	if (resource_context.vidc_platform_data->enable_ion)
+		return 1;
+	else
+		return 0;
+}
+
+struct ion_client *res_trk_get_ion_client(void)
+{
+	return resource_context.res_ion_client;
+}
+
+u32 res_trk_get_disable_dmx(void){
+	return resource_context.disable_dmx;
+}
+
+void res_trk_set_mem_type(enum ddl_mem_area mem_type)
+{
+	resource_context.res_mem_type = mem_type;
+	return;
+}
+
+u32 res_trk_get_disable_fullhd(void)
+{
+	return resource_context.disable_fullhd;
+}
+
+int res_trk_enable_iommu_clocks(void)
+{
+	int ret = 0, i;
+	if (resource_context.mmu_clks_on) {
+		pr_err(" %s: Clocks are already on", __func__);
+		return -EINVAL;
+	}
+	resource_context.mmu_clks_on = 1;
+	for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
+		vidc_mmu_clks[i].mmu_clk = clk_get(resource_context.device,
+			vidc_mmu_clks[i].mmu_clk_name);
+		if (IS_ERR(vidc_mmu_clks[i].mmu_clk)) {
+			pr_err(" %s: Get failed for clk %s", __func__,
+				   vidc_mmu_clks[i].mmu_clk_name);
+			ret = PTR_ERR(vidc_mmu_clks[i].mmu_clk);
+		}
+		if (!ret) {
+			ret = clk_enable(vidc_mmu_clks[i].mmu_clk);
+			if (ret) {
+				clk_put(vidc_mmu_clks[i].mmu_clk);
+				vidc_mmu_clks[i].mmu_clk = NULL;
+			}
+		}
+		if (ret) {
+			for (i--; i >= 0; i--) {
+				clk_disable(vidc_mmu_clks[i].mmu_clk);
+				clk_put(vidc_mmu_clks[i].mmu_clk);
+				vidc_mmu_clks[i].mmu_clk = NULL;
+			}
+			resource_context.mmu_clks_on = 0;
+			pr_err("%s() clocks enable failed", __func__);
+			break;
+		}
+	}
+	return ret;
+}
+
+int res_trk_disable_iommu_clocks(void)
+{
+	int i;
+	if (!resource_context.mmu_clks_on) {
+		pr_err(" %s: clks are already off", __func__);
+		return -EINVAL;
+	}
+	resource_context.mmu_clks_on = 0;
+	for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
+		clk_disable(vidc_mmu_clks[i].mmu_clk);
+		clk_put(vidc_mmu_clks[i].mmu_clk);
+		vidc_mmu_clks[i].mmu_clk = NULL;
+	}
+	return 0;
+}
+
+void res_trk_secure_unset(void)
+{
+	mutex_lock(&resource_context.secure_lock);
+	resource_context.secure_session--;
+	mutex_unlock(&resource_context.secure_lock);
+}
+
+void res_trk_secure_set(void)
+{
+	mutex_lock(&resource_context.secure_lock);
+	resource_context.secure_session++;
+	mutex_unlock(&resource_context.secure_lock);
+}
+
+int res_trk_open_secure_session()
+{
+	int rc;
+
+	if (res_trk_check_for_sec_session() == 1) {
+		mutex_lock(&resource_context.secure_lock);
+		pr_err("Securing...\n");
+		rc = res_trk_enable_iommu_clocks();
+		if (rc) {
+			pr_err("IOMMU clock enabled failed while open");
+			goto error_open;
+		}
+		msm_ion_secure_heap(ION_HEAP(resource_context.memtype));
+		msm_ion_secure_heap(ION_HEAP(resource_context.cmd_mem_type));
+		res_trk_disable_iommu_clocks();
+		mutex_unlock(&resource_context.secure_lock);
+	}
+	return 0;
+error_open:
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
+
+int res_trk_close_secure_session()
+{
+	int rc;
+	if (res_trk_check_for_sec_session() == 1) {
+		pr_err("Unsecuring....\n");
+		mutex_lock(&resource_context.secure_lock);
+		rc = res_trk_enable_iommu_clocks();
+		if (rc) {
+			pr_err("IOMMU clock enabled failed while close");
+			goto error_close;
+		}
+		msm_ion_unsecure_heap(ION_HEAP(resource_context.cmd_mem_type));
+		msm_ion_unsecure_heap(ION_HEAP(resource_context.memtype));
+		res_trk_disable_iommu_clocks();
+		mutex_unlock(&resource_context.secure_lock);
+	}
+	return 0;
+error_close:
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
+
+u32 get_res_trk_perf_level(enum vcd_perf_level perf_level)
+{
+	u32 res_trk_perf_level;
+	switch (perf_level) {
+	case VCD_PERF_LEVEL0:
+		res_trk_perf_level = RESTRK_1080P_VGA_PERF_LEVEL;
+		break;
+	case VCD_PERF_LEVEL1:
+		res_trk_perf_level = RESTRK_1080P_720P_PERF_LEVEL;
+		break;
+	case VCD_PERF_LEVEL2:
+		res_trk_perf_level = RESTRK_1080P_MAX_PERF_LEVEL;
+		break;
+	case VCD_PERF_LEVEL_TURBO:
+		res_trk_perf_level = RESTRK_1080P_TURBO_PERF_LEVEL;
+		break;
+	default:
+		VCD_MSG_ERROR("Invalid perf level: %d\n", perf_level);
+		res_trk_perf_level = -EINVAL;
+	}
+	return res_trk_perf_level;
+}
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
new file mode 100644
index 0000000..d5e656b
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _VIDEO_720P_RESOURCE_TRACKER_H_
+#define _VIDEO_720P_RESOURCE_TRACKER_H_
+
+#include <linux/regulator/consumer.h>
+#include <linux/ion.h>
+#include "vcd_res_tracker_api.h"
+#ifdef CONFIG_MSM_BUS_SCALING
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#endif
+#include <mach/board.h>
+
+#define RESTRK_1080P_VGA_PERF_LEVEL    VCD_MIN_PERF_LEVEL
+#define RESTRK_1080P_720P_PERF_LEVEL   108000
+#define RESTRK_1080P_1080P_PERF_LEVEL  244800
+
+#define RESTRK_1080P_MIN_PERF_LEVEL RESTRK_1080P_VGA_PERF_LEVEL
+#define RESTRK_1080P_MAX_PERF_LEVEL RESTRK_1080P_1080P_PERF_LEVEL
+#define RESTRK_1080P_TURBO_PERF_LEVEL (RESTRK_1080P_MAX_PERF_LEVEL + 1)
+
+struct res_trk_context {
+	struct device *device;
+	u32 irq_num;
+	struct mutex lock;
+	struct clk *vcodec_clk;
+	struct clk *vcodec_pclk;
+	unsigned long vcodec_clk_rate;
+	unsigned int clock_enabled;
+	unsigned int perf_level;
+	struct regulator *footswitch;
+	struct msm_vidc_platform_data *vidc_platform_data;
+	int memtype;
+	int fw_mem_type;
+	int cmd_mem_type;
+#ifdef CONFIG_MSM_BUS_SCALING
+	struct msm_bus_scale_pdata *vidc_bus_client_pdata;
+	uint32_t     pcl;
+#endif
+	u32 core_type;
+	struct ddl_buf_addr firmware_addr;
+	struct ion_client *res_ion_client;
+	u32 disable_dmx;
+	u32 disable_fullhd;
+	enum ddl_mem_area res_mem_type;
+	u32 mmu_clks_on;
+	u32 secure_session;
+	struct mutex secure_lock;
+};
+
+#if DEBUG
+
+#define VCDRES_MSG_LOW(xx_fmt...)	printk(KERN_INFO "\n\t* " xx_fmt)
+#define VCDRES_MSG_MED(xx_fmt...)	printk(KERN_INFO "\n  * " xx_fmt)
+
+#else
+
+#define VCDRES_MSG_LOW(xx_fmt...)
+#define VCDRES_MSG_MED(xx_fmt...)
+
+#endif
+
+#define VCDRES_MSG_HIGH(xx_fmt...)	printk(KERN_WARNING "\n" xx_fmt)
+#define VCDRES_MSG_ERROR(xx_fmt...)	printk(KERN_ERR "\n err: " xx_fmt)
+#define VCDRES_MSG_FATAL(xx_fmt...)	printk(KERN_ERR "\n<FATAL> " xx_fmt)
+
+#endif
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
new file mode 100644
index 0000000..3fbbb38
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
@@ -0,0 +1,51 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _VIDEO_720P_RESOURCE_TRACKER_API_H_
+#define _VIDEO_720P_RESOURCE_TRACKER_API_H_
+
+#include "vcd_core.h"
+#include "vcd_ddl.h"
+#include "vcd_ddl_utils.h"
+
+void res_trk_init(struct device *device, u32 irq);
+u32 res_trk_power_up(void);
+u32 res_trk_power_down(void);
+u32 res_trk_enable_clocks(void);
+u32 res_trk_disable_clocks(void);
+u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl);
+u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl,
+	struct vcd_dev_ctxt *dev_ctxt);
+u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl);
+u32 res_trk_download_firmware(void);
+u32 res_trk_get_core_type(void);
+u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr);
+int res_trk_get_mem_type(void);
+u32 res_trk_get_enable_ion(void);
+u32 res_trk_is_cp_enabled(void);
+u32 res_trk_get_disable_fullhd(void);
+struct ion_client *res_trk_get_ion_client(void);
+u32 res_trk_get_disable_dmx(void);
+void res_trk_set_mem_type(enum ddl_mem_area mem_type);
+int res_trk_enable_iommu_clocks(void);
+int res_trk_disable_iommu_clocks(void);
+int res_trk_check_for_sec_session(void);
+int res_trk_open_secure_session(void);
+int res_trk_close_secure_session(void);
+void res_trk_secure_set(void);
+void res_trk_secure_unset(void);
+u32 get_res_trk_perf_level(enum vcd_perf_level);
+int res_trk_enable_footswitch(void);
+int res_trk_disable_footswitch(void);
+void res_trk_release_fw_addr(void);
+u32 res_trk_get_clk_rate(unsigned long *phclk_rate);
+#endif
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
index b53a354..a144e06 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,16 +9,12 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd_ddl_utils.h"
 #include "vcd_ddl_metadata.h"
+#include "vcd_res_tracker_api.h"
 
 u32 ddl_device_init(struct ddl_init_config *ddl_init_config,
 		    void *client_data)
@@ -46,9 +42,22 @@
 	}
 
 	DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context));
-
 	DDL_BUSY(ddl_context);
 
+	if (res_trk_get_enable_ion()) {
+		VIDC_LOGERR_STRING("ddl_dev_init: ION framework enabled");
+		ddl_context->video_ion_client  =
+			res_trk_get_ion_client();
+		if (!ddl_context->video_ion_client) {
+			VIDC_LOGERR_STRING("ION client create failed");
+			return VCD_ERR_ILLEGAL_OP;
+		}
+	}
+	ddl_context->memtype = res_trk_get_mem_type();
+	if (ddl_context->memtype == -1) {
+		VIDC_LOGERR_STRING("ddl_dev_init:Invalid Memtype");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
 	ddl_context->ddl_callback = ddl_init_config->ddl_callback;
 	ddl_context->interrupt_clr = ddl_init_config->interrupt_clr;
 	ddl_context->core_virtual_base_addr =
@@ -161,7 +170,7 @@
 
 	VIDC_LOG_STRING("FW_ENDDONE");
 	ddl_release_context_buffers(ddl_context);
-
+	ddl_context->video_ion_client = NULL;
 	DDL_IDLE(ddl_context);
 
 	return VCD_S_SUCCESS;
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
index 34b522a..e6d3527 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
@@ -1,33 +1,18 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012 Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DDL_H_
 #define _VCD_DDL_H_
+#include <mach/msm_subsystem_map.h>
 #include "vcd_ddl_api.h"
 #include "vcd_ddl_utils.h"
 #include "vcd_ddl_firmware.h"
@@ -82,12 +67,19 @@
 
 #define DDL_DEC_REQ_OUTPUT_FLUSH                0x1
 
+enum ddl_mem_area {
+	DDL_MM_MEM	= 0x0
+};
+
 struct ddl_buf_addr {
 	u32 *physical_base_addr;
 	u32 *virtual_base_addr;
 	u32 *align_physical_addr;
 	u32 *align_virtual_addr;
+	struct msm_mapped_buffer *mapped_buffer;
+	struct ion_handle *alloc_handle;
 	u32 buffer_size;
+	enum ddl_mem_area mem_type;
 };
 
 enum ddl_cmd_state {
@@ -209,6 +201,7 @@
 	struct vcd_buffer_requirement actual_output_buf_req;
 	struct vcd_buffer_requirement min_output_buf_req;
 	struct vcd_buffer_requirement client_output_buf_req;
+	u32 idr_only_decoding;
 };
 
 union ddl_codec_data {
@@ -218,6 +211,7 @@
 };
 
 struct ddl_context {
+	int memtype;
 	u8 *core_virtual_base_addr;
 	void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz,
 			      u32 *ddl_handle, void *const client_data);
@@ -232,6 +226,7 @@
 	struct ddl_buf_addr dbg_core_dump;
 	u32 enable_dbg_core_dump;
 	struct ddl_client_context *ddl_clients[VCD_MAX_NO_CLIENT];
+	struct ion_client *video_ion_client;
 	u32 device_state;
 	u32 ddl_busy;
 	u32  intr_status;
@@ -294,4 +289,6 @@
 void ddl_client_fatal_cb(struct ddl_context *ddl_context);
 void ddl_hw_fatal_cb(struct ddl_context *ddl_context);
 u32 ddl_hal_engine_reset(struct ddl_context *ddl_context);
+void ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment);
+void ddl_pmem_free(struct ddl_buf_addr *addr);
 #endif
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
index 444bb6f..53cc93e 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
@@ -1,29 +1,13 @@
 /* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DDL_API_H_
@@ -31,6 +15,7 @@
 #include "vcd_ddl_internal_property.h"
 
 struct ddl_init_config {
+	int memtype;
 	u8 *core_virtual_base_addr;
 	void (*interrupt_clr) (void);
 	void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz,
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
index b4e4c39..9fdb668 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
@@ -1,29 +1,13 @@
 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DDL_CORE_H_
@@ -43,6 +27,8 @@
 #define DDL_MAX_DP_FRAME_WIDTH  352
 #define DDL_MAX_DP_FRAME_HEIGHT 288
 
+#define DDL_MAX_BIT_RATE (14*1000*1000)
+
 #define DDL_SW_RESET_SLEEP 10
 
 #define VCD_MAX_NO_CLIENT  4
@@ -70,7 +56,7 @@
 #define DDL_MPEG_REFBUF_COUNT  2
 
 #define DDL_MPEG_COMV_BUF_NO 2
-#define DDL_H263_COMV_BUF_NO 0
+#define DDL_H263_COMV_BUF_NO 2
 #define DDL_COMV_BUFLINE_NO  128
 #define DDL_VC1_COMV_BUFLINE_NO  32
 #define DDL_MINIMUM_BYTE_PER_SLICE  1920
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
index 9ce7233..ac5bce9 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd_ddl_utils.h"
 #include "vcd_ddl.h"
 
@@ -365,6 +360,11 @@
 	case ACTIVE_SPS_NOT_PRESENT:
 	case ACTIVE_PPS_NOT_PRESENT:
 		{
+			if (ddl->codec_data.decoder.idr_only_decoding) {
+				DBG("Consider warnings as errors in idr mode");
+				ddl_client_fatal_cb(ddl_context);
+				return true;
+			}
 			vcd_status = VCD_ERR_BITSTREAM_ERR;
 			break;
 		}
@@ -555,11 +555,23 @@
 		DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) {
 		switch (ddl_context->cmd_err_status) {
 		case UNSUPPORTED_FEATURE_IN_PROFILE:
-		case RESOLUTION_NOT_SUPPORTED:
 		case HEADER_NOT_FOUND:
 		case INVALID_SPS_ID:
 		case INVALID_PPS_ID:
+		case RESOLUTION_NOT_SUPPORTED:
+		case PROFILE_UNKOWN:
 			ERR("SEQ-HDR-FAILED!!!");
+			if ((ddl_context->cmd_err_status ==
+				 RESOLUTION_NOT_SUPPORTED) &&
+				(decoder->codec.codec == VCD_CODEC_H264 ||
+				decoder->codec.codec == VCD_CODEC_H263 ||
+				decoder->codec.codec == VCD_CODEC_MPEG4 ||
+				decoder->codec.codec == VCD_CODEC_VC1_RCV ||
+				decoder->codec.codec == VCD_CODEC_VC1)) {
+				ddl_client_fatal_cb(ddl_context);
+				status = true;
+				break;
+			}
 			if (decoder->header_in_start) {
 				decoder->header_in_start = false;
 				ddl_context->ddl_callback(VCD_EVT_RESP_START,
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
index 1a9552e..965c3aa 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd_ddl_firmware.h"
 #include "vcd_ddl_utils.h"
 
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
index 533e945..a136de8 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
@@ -1,34 +1,18 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DDL_FIRMWARE_H_
 #define _VCD_DDL_FIRMWARE_H_
-#include "vcd_property.h"
+#include <media/msm/vcd_property.h>
 
 #define VCD_FW_BIG_ENDIAN     0x0
 #define VCD_FW_LITTLE_ENDIAN  0x1
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
index 0ae12d3..6a69955 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 
 #include "vcd_ddl_utils.h"
 #include "vcd_ddl_metadata.h"
@@ -812,8 +807,13 @@
 		}
 	case VCD_CODEC_H264:
 		{
-			comv_buf_no =
-			    decoder->client_output_buf_req.actual_count;
+			if (decoder->idr_only_decoding)
+				comv_buf_no = decoder->min_dpb_num;
+			else
+				comv_buf_no =
+					decoder->
+					client_output_buf_req.
+					actual_count;
 			break;
 		}
 	}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
index 2debffa..15adf21 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd_ddl_utils.h"
 
 DDL_INLINE struct ddl_context *ddl_get_context(void)
@@ -129,6 +124,7 @@
 	u32 loopc;
 	struct ddl_frame_data_tag *found_frame = NULL;
 	struct ddl_mask *dpb_mask = &decoder->dpb_mask;
+	u32 temp_mask;
 
 	switch (operation) {
 	case DDL_DPB_OP_MARK_BUSY:
@@ -150,13 +146,17 @@
 
 			if (found_frame) {
 				if (operation == DDL_DPB_OP_MARK_BUSY) {
-					dpb_mask->hw_mask &=
-					    (~(0x1 << loopc));
+					temp_mask = (~(0x1 << loopc));
+					if (decoder->idr_only_decoding)
+						temp_mask = ~(0xffffffff);
+					dpb_mask->hw_mask &= temp_mask;
 					*in_out_frame = *found_frame;
 				} else if (operation ==
 					DDL_DPB_OP_MARK_FREE) {
-					dpb_mask->client_mask |=
-					    (0x1 << loopc);
+					temp_mask = (0x1 << loopc);
+					if (decoder->idr_only_decoding)
+						temp_mask = 0xffffffff;
+					dpb_mask->client_mask |= temp_mask;
 					*found_frame = *in_out_frame;
 				}
 			} else {
@@ -177,29 +177,35 @@
 		}
 	case DDL_DPB_OP_INIT:
 		{
-			u32 dpb_size;
+			u32 dpb_size, index, num_dpb;
 			dpb_size = (!decoder->meta_data_offset) ?
 			    decoder->dp_buf.dec_pic_buffers[0].vcd_frm.
 			    alloc_len : decoder->meta_data_offset;
-			vidc_720p_decode_set_dpb_details(decoder->dp_buf.
-						  no_of_dec_pic_buf,
+			if (decoder->idr_only_decoding)
+				num_dpb = decoder->min_dpb_num;
+			else
+				num_dpb = decoder->dp_buf.no_of_dec_pic_buf;
+			vidc_720p_decode_set_dpb_details(
+						  num_dpb,
 						  dpb_size,
 						  decoder->ref_buffer.
 						  align_physical_addr);
-			for (loopc = 0;
-			     loopc < decoder->dp_buf.no_of_dec_pic_buf;
-			     ++loopc) {
+			for (loopc = 0; loopc < num_dpb; ++loopc) {
+				if (decoder->idr_only_decoding)
+					index = 0;
+				else
+					index = loopc;
 				vidc_720p_decode_set_dpb_buffers(loopc,
 							  (u32 *)
 							  decoder->
 							  dp_buf.
 							  dec_pic_buffers
-							  [loopc].
+							  [index].
 							  vcd_frm.
 							  physical);
-				VIDC_LOG1("DEC_DPB_BUFn_SIZE",
+				VIDC_LOG1("DEC_DPB_BUFn_SIZE=%d",
 					   decoder->dp_buf.
-					   dec_pic_buffers[loopc].vcd_frm.
+					   dec_pic_buffers[index].vcd_frm.
 					   alloc_len);
 			}
 			break;
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
index 81879cb..7e201cf 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
@@ -1,34 +1,18 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DDL_INTERNAL_PROPERTY_H_
 #define _VCD_DDL_INTERNAL_PROPERTY_H_
-#include "vcd_api.h"
+#include <media/msm/vcd_api.h>
 
 #define VCD_EVT_RESP_DDL_BASE          0x3000
 #define VCD_EVT_RESP_DEVICE_INIT       (VCD_EVT_RESP_DDL_BASE + 0x1)
@@ -73,6 +57,12 @@
 	u32 activity_region_flag;
 };
 
+struct vcd_property_slice_delivery_info {
+	u32  enable;
+	u32  num_slices;
+	u32  num_slices_enc;
+};
+
 struct ddl_frame_data_tag;
 
 struct ddl_property_dec_pic_buffers {
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
index 2584417..fe71dc1 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vidc.h"
 #include "vcd_ddl_utils.h"
 #include "vcd_ddl_metadata.h"
@@ -235,6 +230,14 @@
 	ddl_calculate_stride(&decoder->frame_size,
 			!decoder->progressive_only,
 			decoder->codec.codec);
+	if (decoder->buf_format.buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) {
+		decoder->frame_size.stride =
+		DDL_TILE_ALIGN(decoder->frame_size.width,
+					DDL_TILE_ALIGN_WIDTH);
+		decoder->frame_size.scan_lines =
+			DDL_TILE_ALIGN(decoder->frame_size.height,
+						 DDL_TILE_ALIGN_HEIGHT);
+	}
 	if (seq_hdr_info.crop_exists)	{
 		decoder->frame_size.width -=
 		(seq_hdr_info.crop_right_offset
@@ -287,13 +290,14 @@
 			decoder->client_output_buf_req.actual_count
 			&& decoder->progressive_only)
 			need_reconfig = false;
-		if ((input_vcd_frm->data_len == seq_hdr_info.dec_frm_size ||
+		if ((input_vcd_frm->data_len <= seq_hdr_info.dec_frm_size ||
 			 (input_vcd_frm->flags & VCD_FRAME_FLAG_CODECCONFIG)) &&
 			(!need_reconfig ||
 			 !(input_vcd_frm->flags & VCD_FRAME_FLAG_EOS))) {
 			input_vcd_frm->flags |=
 				VCD_FRAME_FLAG_CODECCONFIG;
 			seq_hdr_only_frame = true;
+			input_vcd_frm->data_len = 0;
 			ddl->input_frame.frm_trans_end = !need_reconfig;
 			ddl_context->ddl_callback(
 				VCD_EVT_RESP_INPUT_DONE,
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
index bbf97df..2a74da8 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd_ddl_utils.h"
 #include "vcd_ddl_metadata.h"
 
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
index 9d9f3fc..ed43861 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
@@ -1,29 +1,13 @@
 /* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DDL_METADATA_H_
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
index 4bc97c0..3aebdaf 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd_ddl_utils.h"
 #include "vcd_ddl_metadata.h"
 
@@ -239,6 +234,10 @@
 						&decoder->min_input_buf_req,
 						buffer_req))) {
 				decoder->client_input_buf_req = *buffer_req;
+				decoder->client_input_buf_req.min_count =
+					decoder->min_input_buf_req.min_count;
+				decoder->client_input_buf_req.max_count =
+					decoder->min_input_buf_req.max_count;
 				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
@@ -255,6 +254,10 @@
 						buffer_req))) {
 				decoder->client_output_buf_req =
 				    *buffer_req;
+				decoder->client_output_buf_req.min_count =
+					decoder->min_output_buf_req.min_count;
+				decoder->client_output_buf_req.max_count =
+					decoder->min_output_buf_req.max_count;
 				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
@@ -362,6 +365,18 @@
 			}
 			break;
 		}
+	case VCD_I_DEC_PICTYPE:
+		{
+			if ((sizeof(u32) == property_hdr->sz) &&
+				DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+				decoder->idr_only_decoding =
+					*(u32 *)property_value;
+				ddl_set_default_decoder_buffer_req(
+						decoder, true);
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+		break;
 	case VCD_I_FRAME_RATE:
 		{
 			vcd_status = VCD_S_SUCCESS;
@@ -790,6 +805,10 @@
 				&encoder->input_buf_req, buffer_req))
 				) {
 				encoder->client_input_buf_req = *buffer_req;
+				encoder->client_input_buf_req.min_count =
+					encoder->input_buf_req.min_count;
+				encoder->client_input_buf_req.max_count =
+					encoder->input_buf_req.max_count;
 				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
@@ -806,6 +825,10 @@
 				) {
 				encoder->client_output_buf_req =
 					*buffer_req;
+				encoder->client_output_buf_req.min_count =
+					encoder->output_buf_req.min_count;
+				encoder->client_output_buf_req.max_count =
+					encoder->output_buf_req.max_count;
 				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
@@ -840,12 +863,24 @@
 	switch (property_hdr->prop_id) {
 	case VCD_I_FRAME_SIZE:
 		{
+			struct vcd_property_frame_size *fz_size;
 			if (sizeof(struct vcd_property_frame_size) ==
 			    property_hdr->sz) {
 					ddl_calculate_stride(
 					&decoder->client_frame_size,
 					!decoder->progressive_only,
 					decoder->codec.codec);
+					if (decoder->buf_format.buffer_format
+						== VCD_BUFFER_FORMAT_TILE_4x2) {
+						fz_size =
+						&decoder->client_frame_size;
+						fz_size->stride =
+						DDL_TILE_ALIGN(fz_size->width,
+							DDL_TILE_ALIGN_WIDTH);
+						fz_size->scan_lines =
+						DDL_TILE_ALIGN(fz_size->height,
+							DDL_TILE_ALIGN_HEIGHT);
+					}
 					*(struct vcd_property_frame_size *)
 						property_value =
 						decoder->client_frame_size;
@@ -886,15 +921,10 @@
 		{
 			if (sizeof(struct vcd_buffer_requirement) ==
 			    property_hdr->sz) {
-				if (decoder->
-						client_input_buf_req.sz) {
-					*(struct vcd_buffer_requirement *)
-					    property_value =
-					    decoder->client_input_buf_req;
-					vcd_status = VCD_S_SUCCESS;
-				} else {
-					vcd_status = VCD_ERR_ILLEGAL_OP;
-				}
+				*(struct vcd_buffer_requirement *)
+				    property_value =
+						decoder->client_input_buf_req;
+				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
 		}
@@ -902,14 +932,10 @@
 		{
 			if (sizeof(struct vcd_buffer_requirement) ==
 			    property_hdr->sz) {
-				if (decoder->client_output_buf_req.sz) {
-					*(struct vcd_buffer_requirement *)
-					    property_value =
-					    decoder->client_output_buf_req;
-					vcd_status = VCD_S_SUCCESS;
-				} else {
-					vcd_status = VCD_ERR_ILLEGAL_OP;
-				}
+				*(struct vcd_buffer_requirement *)
+				    property_value =
+						decoder->client_output_buf_req;
+				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
 		}
@@ -917,14 +943,9 @@
 		{
 			if (sizeof(struct vcd_property_codec) ==
 			    property_hdr->sz) {
-				if (decoder->codec.codec) {
-					*(struct vcd_property_codec *)
-					    property_value =
-					    decoder->codec;
-					vcd_status = VCD_S_SUCCESS;
-				} else {
-					vcd_status = VCD_ERR_ILLEGAL_OP;
-				}
+				*(struct vcd_property_codec *)
+				    property_value = decoder->codec;
+				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
 		}
@@ -959,9 +980,7 @@
 		}
 	case DDL_I_FRAME_PROC_UNITS:
 		{
-			if (sizeof(u32) == property_hdr->sz &&
-			    decoder->client_frame_size.width &&
-			    decoder->client_frame_size.height) {
+			if (sizeof(u32) == property_hdr->sz) {
 				struct vcd_property_frame_size frame_sz =
 					decoder->client_frame_size;
 				ddl_calculate_stride(&frame_sz,
@@ -1279,14 +1298,10 @@
 		{
 			if (sizeof(struct vcd_buffer_requirement) ==
 			    property_hdr->sz) {
-				if (encoder->output_buf_req.sz) {
-					*(struct vcd_buffer_requirement *)
-					    property_value =
-					    encoder->client_input_buf_req;
-					vcd_status = VCD_S_SUCCESS;
-				} else {
-					vcd_status = VCD_ERR_ILLEGAL_OP;
-				}
+				*(struct vcd_buffer_requirement *)
+				    property_value =
+						encoder->client_input_buf_req;
+				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
 		}
@@ -1294,14 +1309,10 @@
 		{
 			if (sizeof(struct vcd_buffer_requirement) ==
 			    property_hdr->sz) {
-				if (encoder->output_buf_req.sz) {
-					*(struct vcd_buffer_requirement *)
-					    property_value =
-					    encoder->client_output_buf_req;
-					vcd_status = VCD_S_SUCCESS;
-				} else {
-					vcd_status = VCD_ERR_ILLEGAL_OP;
-				}
+				*(struct vcd_buffer_requirement *)
+				    property_value =
+						encoder->client_output_buf_req;
+				vcd_status = VCD_S_SUCCESS;
 			}
 			break;
 		}
@@ -1317,9 +1328,7 @@
 		}
 	case DDL_I_FRAME_PROC_UNITS:
 		{
-			if (sizeof(u32) == property_hdr->sz &&
-			    encoder->frame_size.width &&
-			    encoder->frame_size.height) {
+			if (sizeof(u32) == property_hdr->sz) {
 				*(u32 *) property_value =
 				    ((encoder->frame_size.width >> 4) *
 				     (encoder->frame_size.height >> 4)
@@ -1377,7 +1386,8 @@
 				(struct vcd_property_target_bitrate *)
 				property_value;
 			if (sizeof(struct vcd_property_target_bitrate) ==
-			 property_hdr->sz) {
+			 property_hdr->sz && bitrate->target_bitrate > 0
+			 && bitrate->target_bitrate <= DDL_MAX_BIT_RATE) {
 				encoder->target_bit_rate = *bitrate;
 				dynamic_prop_change = DDL_ENC_CHANGE_BITRATE;
 				vcd_status = VCD_S_SUCCESS;
@@ -1458,8 +1468,8 @@
 {
 	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
 
-	if (decoder->codec.codec == VCD_CODEC_MPEG4 ||
-	    decoder->codec.codec == VCD_CODEC_MPEG2)
+	if (decoder->codec.codec >= VCD_CODEC_MPEG2 &&
+		decoder->codec.codec <=  VCD_CODEC_XVID)
 		decoder->post_filter.post_filter = true;
 	else
 		decoder->post_filter.post_filter = false;
@@ -1469,6 +1479,7 @@
 	decoder->client_frame_size.stride = 176;
 	decoder->client_frame_size.scan_lines = 144;
 	decoder->progressive_only = 1;
+	decoder->idr_only_decoding = 0;
 	decoder->profile.profile = VCD_PROFILE_UNKNOWN;
 	decoder->level.level = VCD_LEVEL_UNKNOWN;
 	decoder->output_order = VCD_DEC_ORDER_DISPLAY;
@@ -1538,9 +1549,12 @@
 static void ddl_set_default_enc_vop_timing
     (struct ddl_encoder_data *encoder)
 {
-	encoder->vop_timing.vop_time_resolution =
-	    (2 * encoder->frame_rate.fps_numerator) /
-	    encoder->frame_rate.fps_denominator;
+	if (encoder->codec.codec == VCD_CODEC_MPEG4)
+		encoder->vop_timing.vop_time_resolution =
+		    (2 * encoder->frame_rate.fps_numerator) /
+		    encoder->frame_rate.fps_denominator;
+	else
+		encoder->vop_timing.vop_time_resolution = 0x7530;
 }
 
 static void ddl_set_default_enc_intra_period(
@@ -1693,18 +1707,24 @@
 		min_dpb = decoder->min_dpb_num;
 	}
 
+	if (decoder->idr_only_decoding)
+		min_dpb = 1;
+
 	memset(output_buf_req, 0, sizeof(struct vcd_buffer_requirement));
 
 	output_buf_req->min_count = min_dpb;
 
 	num_mb = DDL_NO_OF_MB(frame_size->width, frame_size->height);
-	if (num_mb >= DDL_WVGA_MBS) {
-		output_buf_req->actual_count = min_dpb + 2;
-		if (output_buf_req->actual_count < 10)
-			output_buf_req->actual_count = 10;
-	} else
-		output_buf_req->actual_count = min_dpb + 5;
-
+	if (decoder->idr_only_decoding) {
+		output_buf_req->actual_count = output_buf_req->min_count;
+	} else {
+		if (num_mb >= DDL_WVGA_MBS) {
+			output_buf_req->actual_count = min_dpb + 2;
+			if (output_buf_req->actual_count < 10)
+				output_buf_req->actual_count = 10;
+		} else
+			output_buf_req->actual_count = min_dpb + 5;
+	}
 	output_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
 	output_buf_req->sz = y_cb_cr_size;
 	if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12)
@@ -1722,7 +1742,7 @@
 	input_buf_req->min_count = 1;
 	input_buf_req->actual_count = input_buf_req->min_count + 3;
 	input_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
-	input_buf_req->sz = (1280*720*3) >> 2;
+	input_buf_req->sz = (1280*720*3*3) >> 3;
 	input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
 
 	decoder->min_input_buf_req = *input_buf_req;
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
index f984292..580d428 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,15 +9,11 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
-
-#include "vidc_type.h"
+#include <linux/memory_alloc.h>
+#include <media/msm/vidc_type.h>
 #include "vcd_ddl_utils.h"
+#include "vcd_res_tracker_api.h"
 
 #if DEBUG
 #define DBG(x...) printk(KERN_DEBUG x)
@@ -91,91 +87,183 @@
 void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align)
 {
 	u32 guard_bytes, align_mask;
-	s32 physical_addr;
+	u32 physical_addr;
 	u32 align_offset;
+	u32 alloc_size, flags = 0;
+	struct ddl_context *ddl_context;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	unsigned long *kernel_vaddr = NULL;
+	ion_phys_addr_t phyaddr = 0;
+	size_t len = 0;
+	int ret = -EINVAL;
 
-	DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
-
+	if (!buff_addr) {
+		ERR("\n%s() Invalid Parameters\n", __func__);
+		return;
+	}
 	if (align == DDL_LINEAR_BUFFER_ALIGN_BYTES) {
-
 		guard_bytes = 31;
 		align_mask = 0xFFFFFFE0U;
-
 	} else {
-
 		guard_bytes = DDL_TILE_BUF_ALIGN_GUARD_BYTES;
 		align_mask = DDL_TILE_BUF_ALIGN_MASK;
 	}
-
-	physical_addr = pmem_kalloc((sz + guard_bytes),
-				      PMEM_MEMTYPE_EBI1 | PMEM_ALIGNMENT_4K);
-	buff_addr->physical_base_addr = (u32 *)physical_addr;
-
-	if (IS_ERR((void *)physical_addr)) {
-		pr_err("%s(): could not allocte in kernel pmem buffers\n",
-		       __func__);
-		goto bailout;
+	ddl_context = ddl_get_context();
+	alloc_size = sz + guard_bytes;
+	if (res_trk_get_enable_ion()) {
+		if (!ddl_context->video_ion_client)
+			ddl_context->video_ion_client =
+				res_trk_get_ion_client();
+		if (!ddl_context->video_ion_client) {
+			ERR("\n%s(): DDL ION Client Invalid handle\n",
+				__func__);
+			goto bailout;
+		}
+		buff_addr->mem_type = res_trk_get_mem_type();
+		buff_addr->alloc_handle = ion_alloc(
+					ddl_context->video_ion_client,
+					alloc_size,
+					SZ_4K,
+					buff_addr->mem_type);
+		if (!buff_addr->alloc_handle) {
+			ERR("\n%s(): DDL ION alloc failed\n",
+					__func__);
+			goto bailout;
+		}
+		ret = ion_phys(ddl_context->video_ion_client,
+					buff_addr->alloc_handle,
+					&phyaddr,
+					&len);
+		if (ret || !phyaddr) {
+			ERR("\n%s(): DDL ION client physical failed\n",
+					__func__);
+			goto free_ion_buffer;
+		}
+		buff_addr->physical_base_addr = (u32 *)phyaddr;
+		kernel_vaddr = (unsigned long *) ion_map_kernel(
+					ddl_context->video_ion_client,
+					buff_addr->alloc_handle,
+					UNCACHED);
+		if (IS_ERR_OR_NULL(kernel_vaddr)) {
+			ERR("\n%s(): DDL ION map failed\n", __func__);
+			goto unmap_ion_buffer;
+		}
+		buff_addr->virtual_base_addr = (u32 *)kernel_vaddr;
+		DBG("ddl_ion_alloc: handle(0x%x), mem_type(0x%x), "\
+			"phys(0x%x), virt(0x%x), size(%u), align(%u), "\
+			"alloced_len(%u)", (u32)buff_addr->alloc_handle,
+			(u32)buff_addr->mem_type,
+			(u32)buff_addr->physical_base_addr,
+			(u32)buff_addr->virtual_base_addr,
+			alloc_size, align, len);
+	} else {
+		physical_addr = (u32)
+			allocate_contiguous_memory_nomap(alloc_size,
+						ddl_context->memtype, SZ_4K);
+		if (!physical_addr) {
+			ERR("\n%s(): DDL pmem allocate failed\n",
+			       __func__);
+			goto bailout;
+		}
+		buff_addr->physical_base_addr = (u32 *) physical_addr;
+		flags = MSM_SUBSYSTEM_MAP_KADDR;
+		buff_addr->mapped_buffer =
+		msm_subsystem_map_buffer((unsigned long)physical_addr,
+		alloc_size, flags, NULL, 0);
+		if (IS_ERR(buff_addr->mapped_buffer)) {
+			ERR("\n%s() buffer map failed\n", __func__);
+			goto free_pmem_buffer;
+		}
+		mapped_buffer = buff_addr->mapped_buffer;
+		if (!mapped_buffer->vaddr) {
+			ERR("\n%s() mapped virtual address is NULL\n",
+				__func__);
+			goto unmap_pmem_buffer;
+		}
+		buff_addr->virtual_base_addr = mapped_buffer->vaddr;
+		DBG("ddl_pmem_alloc: mem_type(0x%x), phys(0x%x),"\
+			" virt(0x%x), sz(%u), align(%u)",
+			(u32)buff_addr->mem_type,
+			(u32)buff_addr->physical_base_addr,
+			(u32)buff_addr->virtual_base_addr,
+			alloc_size, SZ_4K);
 	}
 
-	buff_addr->virtual_base_addr =
-	    (u32 *) ioremap((unsigned long)physical_addr,
-			    sz + guard_bytes);
-	if (!buff_addr->virtual_base_addr) {
-
-		pr_err("%s: could not ioremap in kernel pmem buffers\n",
-		       __func__);
-		pmem_kfree(physical_addr);
-		goto bailout;
-	}
 	memset(buff_addr->virtual_base_addr, 0 , sz + guard_bytes);
 	buff_addr->buffer_size = sz;
-
-	buff_addr->align_physical_addr =
-	    (u32 *) ((physical_addr + guard_bytes) & align_mask);
-
-	align_offset =
-	    (u32) (buff_addr->align_physical_addr) - physical_addr;
-
+	buff_addr->align_physical_addr = (u32 *)
+		(((u32)buff_addr->physical_base_addr + guard_bytes) &
+		align_mask);
+	align_offset = (u32) (buff_addr->align_physical_addr) -
+		(u32)buff_addr->physical_base_addr;
 	buff_addr->align_virtual_addr =
 	    (u32 *) ((u32) (buff_addr->virtual_base_addr)
 		     + align_offset);
-
-	DBG_PMEM("\n%s() OUT: phy_addr(%p) ker_addr(%p) size(%u)", __func__,
-		buff_addr->physical_base_addr, buff_addr->virtual_base_addr,
-		buff_addr->buffer_size);
-
+	DBG("%s(): phys(0x%x) align_phys(0x%x), virt(0x%x),"\
+		" align_virt(0x%x)", __func__,
+		(u32)buff_addr->physical_base_addr,
+		(u32)buff_addr->align_physical_addr,
+		(u32)buff_addr->virtual_base_addr,
+		(u32)buff_addr->align_virtual_addr);
 	return;
+
+unmap_pmem_buffer:
+	if (buff_addr->mapped_buffer)
+		msm_subsystem_unmap_buffer(buff_addr->mapped_buffer);
+free_pmem_buffer:
+	if (buff_addr->physical_base_addr)
+		free_contiguous_memory_by_paddr((unsigned long)
+			buff_addr->physical_base_addr);
+	memset(buff_addr, 0, sizeof(struct ddl_buf_addr));
+	return;
+
+unmap_ion_buffer:
+	if (ddl_context->video_ion_client) {
+		if (buff_addr->alloc_handle)
+			ion_unmap_kernel(ddl_context->video_ion_client,
+				buff_addr->alloc_handle);
+	}
+free_ion_buffer:
+	if (ddl_context->video_ion_client) {
+		if (buff_addr->alloc_handle)
+			ion_free(ddl_context->video_ion_client,
+				buff_addr->alloc_handle);
+	}
 bailout:
-	buff_addr->physical_base_addr = NULL;
-	buff_addr->virtual_base_addr = NULL;
-	buff_addr->buffer_size = 0;
+	memset(buff_addr, 0, sizeof(struct ddl_buf_addr));
 }
 
 void ddl_pmem_free(struct ddl_buf_addr *buff_addr)
 {
+	struct ddl_context *ddl_context;
+	ddl_context = ddl_get_context();
 	if (!buff_addr) {
 		ERR("\n %s() invalid arguments %p", __func__, buff_addr);
 		return;
 	}
-	DBG_PMEM("\n%s() IN: phy_addr(%p) ker_addr(%p) size(%u)", __func__,
-		buff_addr->physical_base_addr, buff_addr->virtual_base_addr,
+	DBG("ddl_pmem_free: phys(0x%x) align_phys(0x%x), "\
+		"virt(0x%x), align_virt(0x%x), size(%u)",
+		(u32)buff_addr->physical_base_addr,
+		(u32)buff_addr->align_physical_addr,
+		(u32)buff_addr->virtual_base_addr,
+		(u32)buff_addr->align_virtual_addr,
 		buff_addr->buffer_size);
-
-	if (buff_addr->virtual_base_addr)
-		iounmap((void *)buff_addr->virtual_base_addr);
-
-	if ((buff_addr->physical_base_addr) &&
-		pmem_kfree((s32) buff_addr->physical_base_addr)) {
-		ERR("\n %s(): Error in Freeing ddl_pmem_free "
-		"Physical Address %p", __func__,
-		buff_addr->physical_base_addr);
+	if (ddl_context->video_ion_client) {
+		if (buff_addr->alloc_handle) {
+			ion_unmap_kernel(ddl_context->video_ion_client,
+				buff_addr->alloc_handle);
+			ion_free(ddl_context->video_ion_client,
+				buff_addr->alloc_handle);
+		}
+	} else {
+		if (buff_addr->mapped_buffer)
+			msm_subsystem_unmap_buffer(
+				buff_addr->mapped_buffer);
+		if (buff_addr->physical_base_addr)
+			free_contiguous_memory_by_paddr((unsigned long)
+				buff_addr->physical_base_addr);
 	}
-	DBG_PMEM("\n%s() OUT: phy_addr(%p) ker_addr(%p) size(%u)", __func__,
-		buff_addr->physical_base_addr, buff_addr->virtual_base_addr,
-		buff_addr->buffer_size);
-	buff_addr->buffer_size = 0;
-	buff_addr->physical_base_addr = NULL;
-	buff_addr->virtual_base_addr = NULL;
+	memset(buff_addr, 0, sizeof(struct ddl_buf_addr));
 }
 #endif
 
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
index 81e8b21..539f753 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
@@ -1,29 +1,13 @@
 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DDL_UTILS_H_
@@ -56,10 +40,6 @@
 		printk(KERN_DEBUG x); \
 } while (0)
 
-void ddl_pmem_alloc(struct ddl_buf_addr *, u32, u32);
-
-void ddl_pmem_free(struct ddl_buf_addr *);
-
 void ddl_set_core_start_time(const char *func_name, u32 index);
 
 void ddl_calc_core_proc_time(const char *func_name, u32 index);
diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.c b/drivers/video/msm/vidc/720p/ddl/vidc.c
index eacfbca..de6cbbb 100644
--- a/drivers/video/msm/vidc/720p/ddl/vidc.c
+++ b/drivers/video/msm/vidc/720p/ddl/vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,16 +9,11 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
 #include <linux/unistd.h>
+#include <media/msm/vidc_type.h>
 #include "vidc.h"
-#include "vidc_type.h"
 
 #if DEBUG
 #define DBG(x...) printk(KERN_DEBUG x)
@@ -228,6 +223,9 @@
 	/*Sets the DMA endianness */
 	VIDC_IO_OUT(REG_736316, dma_endian);
 
+	/*Restore ARM endianness */
+	VIDC_IO_OUT(REG_215724, 0);
+
 	/* retun engine reset success */
 	return true ;
 }
diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.h b/drivers/video/msm/vidc/720p/ddl/vidc.h
index 03232b9..509482b 100644
--- a/drivers/video/msm/vidc/720p/ddl/vidc.h
+++ b/drivers/video/msm/vidc/720p/ddl/vidc.h
@@ -1,29 +1,13 @@
 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef VIDC_H
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
index 6387325..a636196 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,25 +9,19 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 #include <linux/firmware.h>
-#include <linux/pm_qos_params.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
-#include <mach/internal_power_rail.h>
+#include <linux/regulator/consumer.h>
 #include <mach/clk.h>
-#include <mach/msm_reqs.h>
 #include <linux/interrupt.h>
-#include "vidc_type.h"
+#include <media/msm/vidc_init.h>
+#include <media/msm/vidc_type.h>
 #include "vcd_res_tracker.h"
-#include "vidc_init.h"
 
 #define MSM_AXI_QOS_NAME "msm_vidc_reg"
+#define AXI_CLK_SCALING
 
 #define QVGA_PERF_LEVEL (300 * 30)
 #define VGA_PERF_LEVEL (1200 * 30)
@@ -37,23 +31,12 @@
 	61440000, 122880000, 170667000
 };
 
-#ifndef CONFIG_MSM_NPA_SYSTEM_BUS
 static unsigned int axi_clk_freq_table_enc[2] = {
 	122880, 192000
 };
 static unsigned int axi_clk_freq_table_dec[2] = {
 	122880, 192000
 };
-#else
-static unsigned int axi_clk_freq_table_enc[2] = {
-	MSM_AXI_FLOW_VIDEO_RECORDING_720P,
-	MSM_AXI_FLOW_VIDEO_RECORDING_720P
-};
-static unsigned int axi_clk_freq_table_dec[2] = {
-	MSM_AXI_FLOW_VIDEO_PLAYBACK_720P,
-	MSM_AXI_FLOW_VIDEO_PLAYBACK_720P
-};
-#endif
 
 static struct res_trk_context resource_context;
 
@@ -86,23 +69,48 @@
 unsigned char *vidc_vc1_dec_fw;
 u32 vidc_vc1_dec_fw_size;
 
-static u32 res_trk_disable_pwr_rail(void)
+static u32 res_trk_disable_videocore(void)
 {
 	int rc = -1;
 	mutex_lock(&resource_context.lock);
 
-	if (resource_context.clock_enabled) {
-		mutex_unlock(&resource_context.lock);
-		VCDRES_MSG_LOW("\n Calling CLK disable in Power Down\n");
-		res_trk_disable_clocks();
-		mutex_lock(&resource_context.lock);
-	}
-
 	if (!resource_context.rail_enabled) {
 		mutex_unlock(&resource_context.lock);
 		return false;
 	}
 
+	if (!resource_context.clock_enabled &&
+		resource_context.pclk &&
+		resource_context.hclk &&
+		resource_context.hclk_div2) {
+
+		VCDRES_MSG_LOW("\nEnabling clk before disabling pwr rail\n");
+		if (clk_set_rate(resource_context.hclk,
+			mfc_clk_freq_table[0])) {
+			VCDRES_MSG_ERROR("\n pwr_rail_disable:"
+				 " set clk rate failed\n");
+			goto bail_out;
+		}
+
+		if (clk_enable(resource_context.pclk)) {
+			VCDRES_MSG_ERROR("vidc pclk Enable failed\n");
+			goto bail_out;
+		}
+
+		if (clk_enable(resource_context.hclk)) {
+			VCDRES_MSG_ERROR("vidc hclk Enable failed\n");
+			goto disable_pclk;
+		}
+
+		if (clk_enable(resource_context.hclk_div2)) {
+			VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n");
+			goto disable_hclk;
+		}
+	} else {
+		VCDRES_MSG_ERROR("\ndisabling pwr rail: Enabling clk failed\n");
+		goto bail_out;
+	}
+
 	resource_context.rail_enabled = 0;
 	rc = clk_reset(resource_context.pclk, CLK_RESET_ASSERT);
 	if (rc) {
@@ -112,19 +120,48 @@
 	}
 	msleep(20);
 
-	rc = internal_pwr_rail_ctl(PWR_RAIL_MFC_CLK, 0);
-	if (rc) {
-		VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc);
-		mutex_unlock(&resource_context.lock);
-		return false;
-	}
+	clk_disable(resource_context.pclk);
+	clk_disable(resource_context.hclk);
+	clk_disable(resource_context.hclk_div2);
 
 	clk_put(resource_context.hclk_div2);
 	clk_put(resource_context.hclk);
 	clk_put(resource_context.pclk);
+
+	rc = regulator_disable(resource_context.regulator);
+	if (rc) {
+		VCDRES_MSG_ERROR("\n regulator disable failed %d\n", rc);
+		mutex_unlock(&resource_context.lock);
+		return false;
+	}
+
+	resource_context.hclk_div2 = NULL;
+	resource_context.hclk = NULL;
+	resource_context.pclk = NULL;
+
 	mutex_unlock(&resource_context.lock);
 
 	return true;
+
+disable_hclk:
+	clk_disable(resource_context.hclk);
+disable_pclk:
+	clk_disable(resource_context.pclk);
+bail_out:
+	if (resource_context.pclk) {
+		clk_put(resource_context.pclk);
+		resource_context.pclk = NULL;
+	}
+	if (resource_context.hclk) {
+		clk_put(resource_context.hclk);
+		resource_context.hclk = NULL;
+	}
+	if (resource_context.hclk_div2) {
+		clk_put(resource_context.hclk_div2);
+		resource_context.hclk_div2 = NULL;
+	}
+	mutex_unlock(&resource_context.lock);
+	return false;
 }
 
 u32 res_trk_enable_clocks(void)
@@ -224,80 +261,107 @@
 	return true;
 }
 
-static u32 res_trk_enable_pwr_rail(void)
+static u32 res_trk_enable_videocore(void)
 {
 	mutex_lock(&resource_context.lock);
 	if (!resource_context.rail_enabled) {
 		int rc = -1;
-		rc = internal_pwr_rail_mode(PWR_RAIL_MFC_CLK,
-			PWR_RAIL_CTL_MANUAL);
+
+		rc = regulator_enable(resource_context.regulator);
 		if (rc) {
-			VCDRES_MSG_ERROR("%s(): internal_pwr_rail_mode \
-					failed %d\n", __func__, rc);
-			mutex_unlock(&resource_context.lock);
-			return false;
+			VCDRES_MSG_ERROR("%s(): regulator_enable failed %d\n",
+							 __func__, rc);
+			goto bail_out;
 		}
-		VCDRES_MSG_LOW("%s(): internal_pwr_rail_mode Success %d\n",
-			__func__, rc);
+		VCDRES_MSG_LOW("%s(): regulator enable Success %d\n",
+							__func__, rc);
 
 		resource_context.pclk = clk_get(resource_context.device,
-			"mfc_pclk");
+			"iface_clk");
 
 		if (IS_ERR(resource_context.pclk)) {
-			VCDRES_MSG_ERROR("%s(): mfc_pclk get failed\n"
+			VCDRES_MSG_ERROR("%s(): iface_clk get failed\n"
 							 , __func__);
-
-			mutex_unlock(&resource_context.lock);
-			return false;
+			goto disable_regulator;
 		}
 
 		resource_context.hclk = clk_get(resource_context.device,
-			"mfc_clk");
+			"core_clk");
 
 		if (IS_ERR(resource_context.hclk)) {
-			VCDRES_MSG_ERROR("%s(): mfc_clk get failed\n"
+			VCDRES_MSG_ERROR("%s(): core_clk get failed\n"
 							 , __func__);
 
-			clk_put(resource_context.pclk);
-			mutex_unlock(&resource_context.lock);
-			return false;
+			goto release_pclk;
 		}
 
 		resource_context.hclk_div2 =
-			clk_get(resource_context.device, "mfc_div2_clk");
+			clk_get(resource_context.device, "core_div2_clk");
 
-		if (IS_ERR(resource_context.pclk)) {
-			VCDRES_MSG_ERROR("%s(): mfc_div2_clk get failed\n"
+		if (IS_ERR(resource_context.hclk_div2)) {
+			VCDRES_MSG_ERROR("%s(): core_div2_clk get failed\n"
 							 , __func__);
-
-			clk_put(resource_context.pclk);
-			clk_put(resource_context.hclk);
-			mutex_unlock(&resource_context.lock);
-			return false;
+			goto release_hclk_pclk;
 		}
 
-		rc = internal_pwr_rail_ctl(PWR_RAIL_MFC_CLK, 1);
-		if (rc) {
-			VCDRES_MSG_ERROR("\n internal_pwr_rail_ctl failed %d\n"
-							 , rc);
-			mutex_unlock(&resource_context.lock);
-			return false;
+		if (clk_set_rate(resource_context.hclk,
+			mfc_clk_freq_table[0])) {
+			VCDRES_MSG_ERROR("\n pwr_rail_enable:"
+				 " set clk rate failed\n");
+			goto release_all_clks;
 		}
-		VCDRES_MSG_LOW("%s(): internal_pwr_rail_ctl Success %d\n"
-					   , __func__, rc);
-		msleep(20);
+
+		if (clk_enable(resource_context.pclk)) {
+			VCDRES_MSG_ERROR("vidc pclk Enable failed\n");
+			goto release_all_clks;
+		}
+
+		if (clk_enable(resource_context.hclk)) {
+			VCDRES_MSG_ERROR("vidc hclk Enable failed\n");
+			goto disable_pclk;
+		}
+
+		if (clk_enable(resource_context.hclk_div2)) {
+			VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n");
+			goto disable_hclk_pclk;
+		}
 
 		rc = clk_reset(resource_context.pclk, CLK_RESET_DEASSERT);
 		if (rc) {
 			VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc);
-			mutex_unlock(&resource_context.lock);
-			return false;
+			goto disable_and_release_all_clks;
 		}
 		msleep(20);
+
+		clk_disable(resource_context.pclk);
+		clk_disable(resource_context.hclk);
+		clk_disable(resource_context.hclk_div2);
+
 	}
 	resource_context.rail_enabled = 1;
 	mutex_unlock(&resource_context.lock);
 	return true;
+
+disable_and_release_all_clks:
+	clk_disable(resource_context.hclk_div2);
+disable_hclk_pclk:
+	clk_disable(resource_context.hclk);
+disable_pclk:
+	clk_disable(resource_context.pclk);
+release_all_clks:
+	clk_put(resource_context.hclk_div2);
+	resource_context.hclk_div2 = NULL;
+release_hclk_pclk:
+	clk_put(resource_context.hclk);
+	resource_context.hclk = NULL;
+release_pclk:
+	clk_put(resource_context.pclk);
+	resource_context.pclk = NULL;
+disable_regulator:
+	regulator_disable(resource_context.regulator);
+bail_out:
+	mutex_unlock(&resource_context.lock);
+	return false;
 }
 
 static u32 res_trk_convert_freq_to_perf_lvl(u64 freq)
@@ -333,9 +397,7 @@
 	return (u32)freq;
 }
 
-#ifdef AXI_CLK_SCALING
-static struct pm_qos_request_list *qos_req_list;
-#endif
+static struct clk *ebi1_clk;
 
 u32 res_trk_power_up(void)
 {
@@ -345,18 +407,18 @@
 {
 	VCDRES_MSG_MED("\n res_trk_power_up():: "
 		"Calling AXI add requirement\n");
-	qos_req_list = pm_qos_add_request(PM_QOS_SYSTEM_BUS_FREQ,
-		PM_QOS_DEFAULT_VALUE);
-	if (IS_ERR_OR_NULL(qos_req_list)) {
+	ebi1_clk = clk_get(resource_context.device, "mem_clk");
+	if (IS_ERR(ebi1_clk)) {
 		VCDRES_MSG_ERROR("Request AXI bus QOS fails.");
 		return false;
 	}
+	clk_enable(ebi1_clk);
 }
 #endif
 
 	VCDRES_MSG_MED("\n res_trk_power_up():: Calling "
 		"vidc_enable_pwr_rail()\n");
-	return res_trk_enable_pwr_rail();
+	return res_trk_enable_videocore();
 }
 
 u32 res_trk_power_down(void)
@@ -365,11 +427,12 @@
 #ifdef AXI_CLK_SCALING
 	VCDRES_MSG_MED("\n res_trk_power_down()::"
 		"Calling AXI remove requirement\n");
-	pm_qos_remove_request(qos_req_list);
+	clk_disable(ebi1_clk);
+	clk_put(ebi1_clk);
 #endif
 	VCDRES_MSG_MED("\n res_trk_power_down():: Calling "
-		"res_trk_disable_pwr_rail()\n");
-	return res_trk_disable_pwr_rail();
+		"res_trk_disable_videocore()\n");
+	return res_trk_disable_videocore();
 }
 
 u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl)
@@ -458,8 +521,7 @@
     if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) {
 		VCDRES_MSG_MED("\n %s(): Setting AXI freq to %u",
 			__func__, axi_freq);
-		pm_qos_update_request(qos_req_list,
-			axi_freq);	
+		clk_set_rate(ebi1_clk, axi_freq * 1000);
 	}
 #endif
 
@@ -615,8 +677,16 @@
 	return false;
 }
 
+static struct ion_client *res_trk_create_ion_client(void){
+	struct ion_client *video_client;
+	VCDRES_MSG_LOW("%s", __func__);
+	video_client = msm_ion_client_create(-1, "video_client");
+	return video_client;
+}
+
 void res_trk_init(struct device *device, u32 irq)
 {
+	VCDRES_MSG_LOW("%s", __func__);
 	if (resource_context.device || resource_context.irq_num ||
 		!device) {
 		VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n",
@@ -628,8 +698,100 @@
 	resource_context.device = device;
 	resource_context.irq_num = irq;
 	resource_context.core_type = VCD_CORE_720P;
+	resource_context.regulator = regulator_get(NULL, "fs_mfc");
+	resource_context.vidc_platform_data =
+		(struct msm_vidc_platform_data *) device->platform_data;
+	if (resource_context.vidc_platform_data) {
+		resource_context.memtype =
+			resource_context.vidc_platform_data->memtype;
+		VCDRES_MSG_LOW("%s(): resource_context.memtype = 0x%x",
+			__func__, (u32)resource_context.memtype);
+		if (resource_context.vidc_platform_data->enable_ion) {
+			resource_context.res_ion_client =
+				res_trk_create_ion_client();
+			if (!(resource_context.res_ion_client)) {
+				VCDRES_MSG_ERROR("%s()ION createfail\n",
+						__func__);
+				return;
+			}
+			VCDRES_MSG_LOW("%s(): ion_client = 0x%x", __func__,
+				(u32)resource_context.res_ion_client);
+		} else {
+			VCDRES_MSG_ERROR("%s(): ION not disabled\n",
+					__func__);
+		}
+	} else {
+		resource_context.memtype = -1;
+		VCDRES_MSG_ERROR("%s(): vidc_platform_data is NULL",
+			__func__);
+	}
 }
 
 u32 res_trk_get_core_type(void){
 	return resource_context.core_type;
 }
+
+u32 res_trk_get_enable_ion(void)
+{
+	if (resource_context.vidc_platform_data->enable_ion)
+		return 1;
+	else
+		return 0;
+}
+
+struct ion_client *res_trk_get_ion_client(void)
+{
+	return resource_context.res_ion_client;
+}
+
+u32 res_trk_get_mem_type(void)
+{
+	u32 mem_type = ION_HEAP(resource_context.memtype);
+	return mem_type;
+}
+
+void res_trk_set_mem_type(enum ddl_mem_area mem_type)
+{
+	return;
+}
+
+u32 res_trk_get_disable_fullhd(void)
+{
+	return 0;
+}
+
+int res_trk_check_for_sec_session()
+{
+	return 0;
+}
+
+void res_trk_secure_unset(void)
+{
+	return;
+}
+
+void res_trk_secure_set(void)
+{
+	return;
+}
+
+int res_trk_open_secure_session()
+{
+	return -EINVAL;
+}
+
+int res_trk_close_secure_session()
+{
+	return 0;
+}
+u32 get_res_trk_perf_level(enum vcd_perf_level perf_level)
+{
+	return -ENOTSUPP;
+}
+u32 res_trk_is_cp_enabled(void)
+{
+	if (resource_context.vidc_platform_data->cp_enabled)
+		return 1;
+	else
+		return 0;
+}
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
index 63d3399..f8d9053 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
@@ -1,34 +1,19 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VIDEO_720P_RESOURCE_TRACKER_H_
 #define _VIDEO_720P_RESOURCE_TRACKER_H_
-
+#include <mach/board.h>
+#include <linux/ion.h>
 #include "vcd_res_tracker_api.h"
 
 #define VCD_RESTRK_MIN_PERF_LEVEL 37900
@@ -47,7 +32,13 @@
 	unsigned long hclk_rate;
 	unsigned int clock_enabled;
 	unsigned int rail_enabled;
+	struct regulator *regulator;
+	struct msm_vidc_platform_data *vidc_platform_data;
 	u32 core_type;
+	int memtype;
+	u32 secure_session;
+	struct ion_client *res_ion_client;
+	enum ddl_mem_area res_mem_type;
 };
 
 #if DEBUG
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
index 57d3638..4b77576 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
@@ -1,35 +1,20 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VIDEO_720P_RESOURCE_TRACKER_API_H_
 #define _VIDEO_720P_RESOURCE_TRACKER_API_H_
 
 #include "vcd_core.h"
+#include "vcd_ddl.h"
 
 void res_trk_init(struct device *device, u32 irq);
 u32 res_trk_power_up(void);
@@ -42,5 +27,16 @@
 u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl);
 u32 res_trk_download_firmware(void);
 u32 res_trk_get_core_type(void);
-
+u32 res_trk_get_mem_type(void);
+u32 res_trk_get_disable_fullhd(void);
+u32 res_trk_get_enable_ion(void);
+u32 res_trk_is_cp_enabled(void);
+struct ion_client *res_trk_get_ion_client(void);
+void res_trk_set_mem_type(enum ddl_mem_area mem_type);
+int res_trk_check_for_sec_session(void);
+int res_trk_open_secure_session(void);
+int res_trk_close_secure_session(void);
+void res_trk_secure_set(void);
+void res_trk_secure_unset(void);
+u32 get_res_trk_perf_level(enum vcd_perf_level perf_level);
 #endif
diff --git a/drivers/video/msm/vidc/Kconfig b/drivers/video/msm/vidc/Kconfig
index aae34a7..9ffcb15 100644
--- a/drivers/video/msm/vidc/Kconfig
+++ b/drivers/video/msm/vidc/Kconfig
@@ -3,7 +3,7 @@
 #
 menuconfig MSM_VIDC
 	bool "Video Core Driver"
-	depends on ARCH_MSM8X60 || ARCH_MSM7X30
+	depends on ARCH_MSM8X60 || ARCH_MSM7X30 || ARCH_MSM8960
 	default y
 	---help---
 	Say Y here to see options for video device drivers.
@@ -18,7 +18,7 @@
 
 config MSM_VIDC_1080P
 	bool "1080P Video Core"
-	depends on MSM_VIDC && ARCH_MSM8X60
+	depends on MSM_VIDC && (ARCH_MSM8X60 || ARCH_MSM8960)
 	default y
 	help
 	This option enables support for Video core.
diff --git a/drivers/video/msm/vidc/Makefile b/drivers/video/msm/vidc/Makefile
index c1331d2..af41f18 100644
--- a/drivers/video/msm/vidc/Makefile
+++ b/drivers/video/msm/vidc/Makefile
@@ -48,6 +48,7 @@
 		1080p/ddl/vidc_pix_cache.o \
 		1080p/ddl/vcd_ddl_vidc.o \
 		1080p/ddl/vcd_ddl.o \
+		1080p/ddl/vcd_ddl_metadata.o \
 		1080p/resource_tracker/vcd_res_tracker.o
 endif
 
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
old mode 100644
new mode 100755
index 7cb3990..8772f23
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,11 +9,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
 #include <linux/cdev.h>
@@ -33,11 +28,12 @@
 #include <linux/android_pmem.h>
 #include <linux/clk.h>
 #include <linux/timer.h>
-
-#include "vidc_type.h"
-#include "vcd_api.h"
+#include <mach/msm_subsystem_map.h>
+#include <media/msm/vidc_type.h>
+#include <media/msm/vcd_api.h>
+#include <media/msm/vidc_init.h>
+#include "vcd_res_tracker_api.h"
 #include "vdec_internal.h"
-#include "vidc_init.h"
 
 
 
@@ -45,11 +41,15 @@
 #define INFO(x...) pr_info(x)
 #define ERR(x...) pr_err(x)
 
-#define VID_DEC_NAME		"msm_vidc_dec"
+#define VID_DEC_NAME "msm_vidc_dec"
 
+static char *node_name[2] = {"", "_sec"};
 static struct vid_dec_dev *vid_dec_device_p;
 static dev_t vid_dec_dev_num;
 static struct class *vid_dec_class;
+
+static unsigned int vidc_mmu_subsystem[] = {
+	MSM_SUBSYSTEM_VIDEO};
 static s32 vid_dec_get_empty_client_index(void)
 {
 	u32 i, found = false;
@@ -187,6 +187,10 @@
 		return;
 	}
 
+	kfree(vcd_frame_data->desc_buf);
+	vcd_frame_data->desc_buf = NULL;
+	vcd_frame_data->desc_size = 0;
+
 	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
 	if (!vdec_msg) {
 		ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg "
@@ -205,8 +209,9 @@
 		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_INPUT_FLUSHED;
 		DBG("Send INPUT_FLUSHED message to client = %p\n", client_ctx);
 	} else {
-		ERR("vid_dec_input_frame_done(): invalid event type\n");
-		return;
+		ERR("vid_dec_input_frame_done(): invalid event type: "
+			"%d\n", event);
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
 	}
 
 	vdec_msg->vdec_msg_info.msgdata.input_frame_clientdata =
@@ -230,6 +235,9 @@
 	struct file *file;
 	s32 buffer_index = -1;
 	enum vdec_picture pic_type;
+	u32 ion_flag = 0;
+	struct ion_handle *buff_handle = NULL;
+	struct vdec_output_frameinfo  *output_frame;
 
 	if (!client_ctx || !vcd_frame_data) {
 		ERR("vid_dec_input_frame_done() NULL pointer\n");
@@ -248,12 +256,12 @@
 	if (event == VCD_EVT_RESP_OUTPUT_DONE)
 		vdec_msg->vdec_msg_info.msgcode =
 		    VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
-
 	else if (event == VCD_EVT_RESP_OUTPUT_FLUSHED)
 		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_OUTPUT_FLUSHED;
 	else {
-		ERR("QVD: vid_dec_output_frame_done invalid cmd type\n");
-		return;
+		ERR("QVD: vid_dec_output_frame_done invalid cmd type: "
+			"%d\n", event);
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
 	}
 
 	kernel_vaddr = (unsigned long)vcd_frame_data->virtual;
@@ -263,7 +271,6 @@
 				      &phy_addr, &pmem_fd, &file,
 				      &buffer_index) ||
 		(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
-
 		/* Buffer address in user space */
 		vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr =
 		    (u8 *) user_vaddr;
@@ -292,6 +299,15 @@
 			vcd_frame_data->dec_op_prop.disp_frm.right;
 		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.top =
 			vcd_frame_data->dec_op_prop.disp_frm.top;
+		if (vcd_frame_data->interlaced) {
+			vdec_msg->vdec_msg_info.msgdata.
+				output_frame.interlaced_format =
+				VDEC_InterlaceInterleaveFrameTopFieldFirst;
+		} else {
+			vdec_msg->vdec_msg_info.msgdata.
+				output_frame.interlaced_format =
+				VDEC_InterlaceFrameProgressive;
+		}
 		/* Decoded picture type */
 		switch (vcd_frame_data->frame) {
 		case VCD_FRAME_I:
@@ -314,13 +330,31 @@
 		}
 		vdec_msg->vdec_msg_info.msgdata.output_frame.pic_type =
 			pic_type;
+		output_frame = &vdec_msg->vdec_msg_info.msgdata.output_frame;
+		output_frame->aspect_ratio_info.aspect_ratio =
+			vcd_frame_data->aspect_ratio_info.aspect_ratio;
+		output_frame->aspect_ratio_info.par_width =
+			vcd_frame_data->aspect_ratio_info.extended_par_width;
+		output_frame->aspect_ratio_info.par_height =
+			vcd_frame_data->aspect_ratio_info.extended_par_height;
 		vdec_msg->vdec_msg_info.msgdatasize =
 		    sizeof(struct vdec_output_frameinfo);
 	} else {
 		ERR("vid_dec_output_frame_done UVA can not be found\n");
 		vdec_msg->vdec_msg_info.status_code = VDEC_S_EFATAL;
 	}
-
+	if (vcd_frame_data->data_len > 0) {
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+				pmem_fd, kernel_vaddr, buffer_index,
+				&buff_handle);
+		if (ion_flag == CACHED) {
+			msm_ion_do_cache_op(client_ctx->user_ion_client,
+					buff_handle,
+					(unsigned long *) kernel_vaddr,
+					(unsigned long)vcd_frame_data->data_len,
+					ION_IOC_INV_CACHES);
+		}
+	}
 	mutex_lock(&client_ctx->msg_queue_lock);
 	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
 	mutex_unlock(&client_ctx->msg_queue_lock);
@@ -644,6 +678,57 @@
 		return true;
 }
 
+static u32 vid_dec_get_disable_dmx_support(struct video_client_ctx *client_ctx,
+					   u32 *disable_dmx)
+{
+
+	struct vcd_property_hdr vcd_property_hdr;
+	if (!client_ctx || !disable_dmx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX_SUPPORT;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 disable_dmx))
+		return false;
+	else
+		return true;
+}
+static u32 vid_dec_get_disable_dmx(struct video_client_ctx *client_ctx,
+					   u32 *disable_dmx)
+{
+
+	struct vcd_property_hdr vcd_property_hdr;
+	if (!client_ctx || !disable_dmx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 disable_dmx))
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_disable_dmx(struct video_client_ctx *client_ctx)
+{
+
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_disable_dmx;
+	if (!client_ctx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX;
+	vcd_property_hdr.sz = sizeof(u32);
+	vcd_disable_dmx = true;
+	DBG("%s() : Setting Disable DMX: %d\n",
+		__func__, vcd_disable_dmx);
+
+	if (vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 &vcd_disable_dmx))
+		return false;
+	else
+		return true;
+}
+
 static u32 vid_dec_set_picture_order(struct video_client_ctx *client_ctx,
 					u32 *picture_order)
 {
@@ -733,44 +818,129 @@
 					struct vdec_h264_mv *mv_data)
 {
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
+	struct vcd_property_h264_mv_buffer *vcd_h264_mv_buffer = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
 	u32 vcd_status = VCD_ERR_FAIL;
-	u32 len;
+	u32 len = 0, flags = 0;
 	struct file *file;
+	int rc = 0;
+	unsigned long ionflag = 0;
+	unsigned long buffer_size = 0;
+	unsigned long iova = 0;
 
 	if (!client_ctx || !mv_data)
 		return false;
 
 	vcd_property_hdr.prop_id = VCD_I_H264_MV_BUFFER;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_h264_mv_buffer);
+	vcd_h264_mv_buffer = &client_ctx->vcd_h264_mv_buffer;
 
-	memset(&vcd_h264_mv_buffer, 0,
+	memset(&client_ctx->vcd_h264_mv_buffer, 0,
 		   sizeof(struct vcd_property_h264_mv_buffer));
-	vcd_h264_mv_buffer.size = mv_data->size;
-	vcd_h264_mv_buffer.count = mv_data->count;
-	vcd_h264_mv_buffer.pmem_fd = mv_data->pmem_fd;
-	vcd_h264_mv_buffer.offset = mv_data->offset;
+	vcd_h264_mv_buffer->size = mv_data->size;
+	vcd_h264_mv_buffer->count = mv_data->count;
+	vcd_h264_mv_buffer->pmem_fd = mv_data->pmem_fd;
+	vcd_h264_mv_buffer->offset = mv_data->offset;
 
-	if (get_pmem_file(vcd_h264_mv_buffer.pmem_fd,
-		(unsigned long *) (&(vcd_h264_mv_buffer.physical_addr)),
-		(unsigned long *) (&vcd_h264_mv_buffer.kernel_virtual_addr),
-		(unsigned long *) (&len), &file)) {
-		ERR("%s(): get_pmem_file failed\n", __func__);
-		return false;
+	if (!vcd_get_ion_status()) {
+		if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd,
+			(unsigned long *) (&(vcd_h264_mv_buffer->
+			physical_addr)),
+			(unsigned long *) (&vcd_h264_mv_buffer->
+						kernel_virtual_addr),
+			(unsigned long *) (&len), &file)) {
+			ERR("%s(): get_pmem_file failed\n", __func__);
+			return false;
+		}
+		put_pmem_file(file);
+		flags = MSM_SUBSYSTEM_MAP_IOVA;
+		mapped_buffer = msm_subsystem_map_buffer(
+			(unsigned long)vcd_h264_mv_buffer->physical_addr, len,
+				flags, vidc_mmu_subsystem,
+				sizeof(vidc_mmu_subsystem)/
+				sizeof(unsigned int));
+		if (IS_ERR(mapped_buffer)) {
+			pr_err("buffer map failed");
+			return false;
+		}
+		vcd_h264_mv_buffer->client_data = (void *) mapped_buffer;
+		vcd_h264_mv_buffer->dev_addr = (u8 *)mapped_buffer->iova[0];
+	} else {
+		client_ctx->h264_mv_ion_handle = ion_import_fd(
+					client_ctx->user_ion_client,
+					vcd_h264_mv_buffer->pmem_fd);
+		if (!client_ctx->h264_mv_ion_handle) {
+			ERR("%s(): get_ION_handle failed\n", __func__);
+			goto import_ion_error;
+		}
+		rc = ion_handle_get_flags(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle,
+					&ionflag);
+		if (rc) {
+			ERR("%s():get_ION_flags fail\n",
+					 __func__);
+			goto import_ion_error;
+		}
+		vcd_h264_mv_buffer->kernel_virtual_addr = (u8 *) ion_map_kernel(
+			client_ctx->user_ion_client,
+			client_ctx->h264_mv_ion_handle,
+			ionflag);
+		if (!vcd_h264_mv_buffer->kernel_virtual_addr) {
+			ERR("%s(): get_ION_kernel virtual addr failed\n",
+				 __func__);
+			goto import_ion_error;
+		}
+		if (res_trk_check_for_sec_session() ||
+		   (res_trk_get_core_type() == (u32)VCD_CORE_720P)) {
+			rc = ion_phys(client_ctx->user_ion_client,
+				client_ctx->h264_mv_ion_handle,
+				(unsigned long *) (&(vcd_h264_mv_buffer->
+				physical_addr)), &len);
+			if (rc) {
+				ERR("%s():get_ION_kernel physical addr fail\n",
+					__func__);
+				goto ion_map_error;
+			}
+			vcd_h264_mv_buffer->client_data = NULL;
+			vcd_h264_mv_buffer->dev_addr = (u8 *)
+				vcd_h264_mv_buffer->physical_addr;
+		} else {
+			rc = ion_map_iommu(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle,
+					VIDEO_DOMAIN, VIDEO_MAIN_POOL,
+					SZ_4K, 0, (unsigned long *)&iova,
+					(unsigned long *)&buffer_size,
+					UNCACHED, 0);
+			if (rc) {
+				ERR("%s():get_ION_kernel physical addr fail\n",
+						 __func__);
+				goto ion_map_error;
+			}
+			vcd_h264_mv_buffer->physical_addr = (u8 *) iova;
+			vcd_h264_mv_buffer->client_data = NULL;
+			vcd_h264_mv_buffer->dev_addr = (u8 *) iova;
+		}
 	}
-	put_pmem_file(file);
-
-	DBG("Virt: %p, Phys %p, fd: %d\n", vcd_h264_mv_buffer.
-		kernel_virtual_addr, vcd_h264_mv_buffer.physical_addr,
-		vcd_h264_mv_buffer.pmem_fd);
-
+	DBG("Virt: %p, Phys %p, fd: %d", vcd_h264_mv_buffer->
+		kernel_virtual_addr, vcd_h264_mv_buffer->physical_addr,
+		vcd_h264_mv_buffer->pmem_fd);
+	DBG("Dev addr %p", vcd_h264_mv_buffer->dev_addr);
 	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-				      &vcd_property_hdr, &vcd_h264_mv_buffer);
+				      &vcd_property_hdr, vcd_h264_mv_buffer);
 
 	if (vcd_status)
 		return false;
 	else
 		return true;
+ion_map_error:
+	if (vcd_h264_mv_buffer->kernel_virtual_addr)
+		ion_unmap_kernel(client_ctx->user_ion_client,
+				client_ctx->h264_mv_ion_handle);
+	if (client_ctx->h264_mv_ion_handle)
+		ion_free(client_ctx->user_ion_client,
+			client_ctx->h264_mv_ion_handle);
+import_ion_error:
+	return false;
 }
 
 static u32 vid_dec_set_cont_on_reconfig(struct video_client_ctx *client_ctx)
@@ -827,12 +997,30 @@
 
 	if (!client_ctx)
 		return false;
+	if (client_ctx->vcd_h264_mv_buffer.client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_h264_mv_buffer.client_data);
 
 	vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
 
 	vcd_status = vcd_set_property(client_ctx->vcd_handle,
 				      &vcd_property_hdr, &h264_mv_buffer_size);
+
+	if (client_ctx->h264_mv_ion_handle != NULL) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle);
+		if (!res_trk_check_for_sec_session() &&
+		   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
+			ion_unmap_iommu(client_ctx->user_ion_client,
+				client_ctx->h264_mv_ion_handle,
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL);
+		}
+		ion_free(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle);
+	}
+
 	if (vcd_status)
 		return false;
 	else
@@ -878,7 +1066,7 @@
 	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
 	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
 	u32 vcd_status = VCD_ERR_FAIL;
-	unsigned long kernel_vaddr, buf_adr_offset = 0;
+	unsigned long kernel_vaddr, buf_adr_offset = 0, length;
 
 	if (!client_ctx || !buffer_info)
 		return false;
@@ -888,17 +1076,16 @@
 		buffer = VCD_BUFFER_OUTPUT;
 		buf_adr_offset = (unsigned long)buffer_info->buffer.offset;
 	}
-
+	length = buffer_info->buffer.buffer_len;
 	/*If buffer cannot be set, ignore */
 	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
 		(unsigned long)buffer_info->buffer.bufferaddr,
 		&kernel_vaddr, buffer_info->buffer.pmem_fd,
-		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF)) {
+		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF, length)) {
 		DBG("%s() : user_virt_addr = %p cannot be set.",
 		    __func__, buffer_info->buffer.bufferaddr);
 		return false;
 	}
-
 	vcd_status = vcd_set_buffer(client_ctx->vcd_handle,
 		buffer, (u8 *) kernel_vaddr,
 		buffer_info->buffer.buffer_len);
@@ -925,6 +1112,7 @@
 		dir_buffer = BUFFER_TYPE_OUTPUT;
 		buffer = VCD_BUFFER_OUTPUT;
 	}
+
 	/*If buffer NOT set, ignore */
 	if (!vidc_delete_addr_table(client_ctx, dir_buffer,
 				(unsigned long)buffer_info->buffer.bufferaddr,
@@ -933,7 +1121,6 @@
 		    __func__, buffer_info->buffer.bufferaddr);
 		return true;
 	}
-
 	vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer,
 					 (u8 *)kernel_vaddr);
 
@@ -1035,7 +1222,8 @@
 }
 
 static u32 vid_dec_decode_frame(struct video_client_ctx *client_ctx,
-				struct vdec_input_frameinfo *input_frame_info)
+				struct vdec_input_frameinfo *input_frame_info,
+				u8 *desc_buf, u32 desc_size)
 {
 	struct vcd_frame_data vcd_input_buffer;
 	unsigned long kernel_vaddr, phy_addr, user_vaddr;
@@ -1043,6 +1231,8 @@
 	struct file *file;
 	s32 buffer_index = -1;
 	u32 vcd_status = VCD_ERR_FAIL;
+	u32 ion_flag = 0;
+	struct ion_handle *buff_handle = NULL;
 
 	if (!client_ctx || !input_frame_info)
 		return false;
@@ -1068,7 +1258,23 @@
 		vcd_input_buffer.time_stamp = input_frame_info->timestamp;
 		/* Rely on VCD using the same flags as OMX */
 		vcd_input_buffer.flags = input_frame_info->flags;
-
+		vcd_input_buffer.desc_buf = desc_buf;
+		vcd_input_buffer.desc_size = desc_size;
+		if (vcd_input_buffer.data_len > 0) {
+			ion_flag = vidc_get_fd_info(client_ctx,
+						BUFFER_TYPE_INPUT,
+						pmem_fd,
+						kernel_vaddr,
+						buffer_index,
+						&buff_handle);
+			if (ion_flag == CACHED) {
+				msm_ion_do_cache_op(client_ctx->user_ion_client,
+				buff_handle,
+				(unsigned long *)kernel_vaddr,
+				(unsigned long) vcd_input_buffer.data_len,
+				ION_IOC_CLEAN_CACHES);
+			}
+		}
 		vcd_status = vcd_decode_frame(client_ctx->vcd_handle,
 					      &vcd_input_buffer);
 		if (!vcd_status)
@@ -1093,6 +1299,7 @@
 	struct file *file;
 	s32 buffer_index = -1;
 	u32 vcd_status = VCD_ERR_FAIL;
+	struct ion_handle *buff_handle = NULL;
 
 	struct vcd_frame_data vcd_frame;
 
@@ -1111,7 +1318,12 @@
 		vcd_frame.virtual = (u8 *) kernel_vaddr;
 		vcd_frame.frm_clnt_data = (u32) fill_buffer_cmd->client_data;
 		vcd_frame.alloc_len = fill_buffer_cmd->buffer.buffer_len;
-
+		vcd_frame.ion_flag = vidc_get_fd_info(client_ctx,
+						 BUFFER_TYPE_OUTPUT,
+						pmem_fd, kernel_vaddr,
+						buffer_index,
+						&buff_handle);
+		vcd_frame.buff_ion_handle = buff_handle;
 		vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle,
 						    &vcd_frame);
 		if (!vcd_status)
@@ -1220,16 +1432,19 @@
 	return 0;
 }
 
-static int vid_dec_ioctl(struct inode *inode, struct file *file,
+static long vid_dec_ioctl(struct file *file,
 			 unsigned cmd, unsigned long u_arg)
 {
 	struct video_client_ctx *client_ctx = NULL;
 	struct vdec_ioctl_msg vdec_msg;
 	u32 vcd_status;
 	unsigned long kernel_vaddr, phy_addr, len;
+	unsigned long ker_vaddr;
 	struct file *pmem_file;
 	u32 result = true;
 	void __user *arg = (void __user *)u_arg;
+	int rc = 0;
+	size_t ion_len;
 
 	DBG("%s\n", __func__);
 	if (_IOC_TYPE(cmd) != VDEC_IOCTL_MAGIC)
@@ -1430,17 +1645,38 @@
 	case VDEC_IOCTL_DECODE_FRAME:
 	{
 		struct vdec_input_frameinfo input_frame_info;
+		u8 *desc_buf = NULL;
+		u32 desc_size = 0;
 		DBG("VDEC_IOCTL_DECODE_FRAME\n");
 		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
 			return -EFAULT;
 		if (copy_from_user(&input_frame_info, vdec_msg.in,
 				   sizeof(input_frame_info)))
 			return -EFAULT;
+		if (client_ctx->dmx_disable) {
+			if (input_frame_info.desc_addr) {
+				desc_size = input_frame_info.desc_size;
+				desc_buf = kzalloc(desc_size, GFP_KERNEL);
+				if (desc_buf) {
+					if (copy_from_user(desc_buf,
+						input_frame_info.desc_addr,
+							desc_size)) {
+						kfree(desc_buf);
+						desc_buf = NULL;
+						return -EFAULT;
+					}
+				}
+			} else
+				return -EINVAL;
+		}
+		result = vid_dec_decode_frame(client_ctx, &input_frame_info,
+					desc_buf, desc_size);
 
-		result = vid_dec_decode_frame(client_ctx, &input_frame_info);
-
-		if (!result)
+		if (!result) {
+			kfree(desc_buf);
+			desc_buf = NULL;
 			return -EIO;
+		}
 		break;
 	}
 	case VDEC_IOCTL_FILL_OUTPUT_BUFFER:
@@ -1497,6 +1733,7 @@
 	{
 		struct vdec_seqheader seq_header;
 		struct vcd_sequence_hdr vcd_seq_hdr;
+		unsigned long ionflag;
 		DBG("VDEC_IOCTL_SET_SEQUENCE_HEADER\n");
 		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) {
 			ERR("Copy from user vdec_msg failed\n");
@@ -1512,13 +1749,56 @@
 			return -EFAULT;
 		}
 
-		if (get_pmem_file(seq_header.pmem_fd,
+		if (!vcd_get_ion_status()) {
+			if (get_pmem_file(seq_header.pmem_fd,
 				  &phy_addr, &kernel_vaddr, &len, &pmem_file)) {
-			ERR("%s(): get_pmem_file failed\n", __func__);
-			return false;
+				ERR("%s(): get_pmem_file failed\n", __func__);
+				return false;
+			}
+			put_pmem_file(pmem_file);
+		} else {
+			client_ctx->seq_hdr_ion_handle = ion_import_fd(
+				client_ctx->user_ion_client,
+				seq_header.pmem_fd);
+			if (!client_ctx->seq_hdr_ion_handle) {
+				ERR("%s(): get_ION_handle failed\n", __func__);
+				return false;
+			}
+			rc = ion_handle_get_flags(client_ctx->user_ion_client,
+						client_ctx->seq_hdr_ion_handle,
+						&ionflag);
+			if (rc) {
+				ERR("%s():get_ION_flags fail\n",
+							 __func__);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+				return false;
+			}
+			ker_vaddr = (unsigned long) ion_map_kernel(
+				client_ctx->user_ion_client,
+				client_ctx->seq_hdr_ion_handle, ionflag);
+			if (!ker_vaddr) {
+				ERR("%s():get_ION_kernel virtual addr fail\n",
+							 __func__);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+				return false;
+			}
+			kernel_vaddr = ker_vaddr;
+			rc = ion_phys(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle,
+					&phy_addr, &ion_len);
+			if (rc) {
+				ERR("%s():get_ION_kernel physical addr fail\n",
+						 __func__);
+				ion_unmap_kernel(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+				return false;
+			}
+			len = ion_len;
 		}
-		put_pmem_file(pmem_file);
-
 		vcd_seq_hdr.sequence_header_len = seq_header.seq_header_len;
 		kernel_vaddr += (unsigned long)seq_header.pmem_offset;
 		vcd_seq_hdr.sequence_header = (u8 *)kernel_vaddr;
@@ -1539,6 +1819,14 @@
 			ERR("Set Seq Header status is failed");
 			return -EFAULT;
 		}
+		if (vcd_get_ion_status()) {
+			if (client_ctx->seq_hdr_ion_handle) {
+				ion_unmap_kernel(client_ctx->user_ion_client,
+						client_ctx->seq_hdr_ion_handle);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+			}
+		}
 		break;
 	}
 	case VDEC_IOCTL_GET_NUMBER_INSTANCES:
@@ -1570,6 +1858,48 @@
 			return -EIO;
 		break;
 	}
+
+	case VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT:
+	{
+		u32 disable_dmx;
+		DBG("VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_disable_dmx_support(client_ctx,
+					&disable_dmx);
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &disable_dmx,
+					sizeof(u32)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_GET_DISABLE_DMX:
+	{
+		u32 disable_dmx;
+		DBG("VDEC_IOCTL_GET_DISABLE_DMX\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_disable_dmx(client_ctx,
+					&disable_dmx);
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &disable_dmx,
+					sizeof(u32)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_DISABLE_DMX:
+	{
+		DBG("VDEC_IOCTL_SET_DISABLE_DMX\n");
+		result =  vid_dec_set_disable_dmx(client_ctx);
+		if (!result)
+			return -EIO;
+		client_ctx->dmx_disable = 1;
+		break;
+	}
 	case VDEC_IOCTL_SET_PICTURE_ORDER:
 	{
 		u32 picture_order;
@@ -1717,69 +2047,146 @@
 		mutex_unlock(&vid_dec_device_p->lock);
 		return false;
 	}
+	client_ctx->user_ion_client = NULL;
 	memset((void *)client_ctx, 0, sizeof(struct video_client_ctx));
 	vid_dec_device_p->num_clients--;
 	mutex_unlock(&vid_dec_device_p->lock);
 	return true;
 }
 
-static int vid_dec_open(struct inode *inode, struct file *file)
+int vid_dec_open_client(struct video_client_ctx **vid_clnt_ctx, int flags)
 {
+	int rc = 0;
 	s32 client_index;
-	struct video_client_ctx *client_ctx;
-	u32 vcd_status = VCD_ERR_FAIL;
-	u8 client_count = 0;
+	struct video_client_ctx *client_ctx = NULL;
+	u8 client_count;
 
-	DBG("msm_vidc_dec: Inside %s()", __func__);
-	mutex_lock(&vid_dec_device_p->lock);
-
+	if (!vid_clnt_ctx) {
+		ERR("Invalid input\n");
+		return -EINVAL;
+	}
+	*vid_clnt_ctx = NULL;
 	client_count = vcd_get_num_of_clients();
 	if (client_count == VIDC_MAX_NUM_CLIENTS) {
 		ERR("ERROR : vid_dec_open() max number of clients"
-		    "limit reached\n");
-		mutex_unlock(&vid_dec_device_p->lock);
-		return -ENODEV;
+			"limit reached\n");
+		rc = -ENOMEM;
+		goto client_failure;
 	}
 
 	DBG(" Virtual Address of ioremap is %p\n", vid_dec_device_p->virt_base);
 	if (!vid_dec_device_p->num_clients) {
-		if (!vidc_load_firmware())
-			return -ENODEV;
+		if (!vidc_load_firmware()) {
+			rc = -ENOMEM;
+			goto client_failure;
+		}
 	}
 
 	client_index = vid_dec_get_empty_client_index();
-	if (client_index < 0) {
+	if (client_index == -1) {
 		ERR("%s() : No free clients client_index == -1\n", __func__);
-		return -ENODEV;
+		rc = -ENOMEM;
+		goto client_failure;
 	}
 	client_ctx = &vid_dec_device_p->vdec_clients[client_index];
 	vid_dec_device_p->num_clients++;
 	init_completion(&client_ctx->event);
 	mutex_init(&client_ctx->msg_queue_lock);
+	mutex_init(&client_ctx->enrty_queue_lock);
 	INIT_LIST_HEAD(&client_ctx->msg_queue);
 	init_waitqueue_head(&client_ctx->msg_wait);
 	client_ctx->stop_msg = 0;
 	client_ctx->stop_called = false;
 	client_ctx->stop_sync_cb = false;
-	vcd_status = vcd_open(vid_dec_device_p->device_handle, true,
-			      vid_dec_vcd_cb, client_ctx);
-	if (!vcd_status) {
+	client_ctx->dmx_disable = 0;
+	if (vcd_get_ion_status()) {
+		client_ctx->user_ion_client = vcd_get_ion_client();
+		if (!client_ctx->user_ion_client) {
+			ERR("vcd_open ion client get failed");
+			rc = -ENOMEM;
+			goto client_failure;
+		}
+	}
+	rc = vcd_open(vid_dec_device_p->device_handle, true,
+				  vid_dec_vcd_cb, client_ctx, flags);
+	if (!rc) {
 		wait_for_completion(&client_ctx->event);
 		if (client_ctx->event_status) {
 			ERR("callback for vcd_open returned error: %u",
 				client_ctx->event_status);
-			mutex_unlock(&vid_dec_device_p->lock);
-			return -EFAULT;
+			rc = -ENODEV;
+			goto client_failure;
 		}
 	} else {
-		ERR("vcd_open returned error: %u", vcd_status);
-		mutex_unlock(&vid_dec_device_p->lock);
-		return -EFAULT;
+		ERR("vcd_open returned error: %u", rc);
+		goto client_failure;
+	}
+	client_ctx->seq_header_set = false;
+	*vid_clnt_ctx = client_ctx;
+client_failure:
+	return rc;
+}
+
+static int vid_dec_open_secure(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+	struct video_client_ctx *client_ctx;
+	mutex_lock(&vid_dec_device_p->lock);
+	rc = vid_dec_open_client(&client_ctx, VCD_CP_SESSION);
+	if (rc)
+		goto error;
+	if (!client_ctx) {
+		rc = -ENOMEM;
+		goto error;
 	}
 
-	client_ctx->seq_header_set = false;
+	file->private_data = client_ctx;
+	if (res_trk_open_secure_session()) {
+		ERR("Secure session operation failure\n");
+		rc = -EACCES;
+		goto error;
+	}
+	mutex_unlock(&vid_dec_device_p->lock);
+	return 0;
+error:
+	mutex_unlock(&vid_dec_device_p->lock);
+	return rc;
+}
+
+static int vid_dec_open(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+	struct video_client_ctx *client_ctx;
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	mutex_lock(&vid_dec_device_p->lock);
+	rc = vid_dec_open_client(&client_ctx, 0);
+	if (rc) {
+		mutex_unlock(&vid_dec_device_p->lock);
+		return rc;
+	}
+	if (!client_ctx) {
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENOMEM;
+	}
+
 	file->private_data = client_ctx;
 	mutex_unlock(&vid_dec_device_p->lock);
+	return rc;
+}
+
+static int vid_dec_release_secure(struct inode *inode, struct file *file)
+{
+	struct video_client_ctx *client_ctx = file->private_data;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT);
+	vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT);
+	vid_dec_close_client(client_ctx);
+	vidc_release_firmware();
+#ifndef USE_RES_TRACKER
+	vidc_disable_clk();
+#endif
+	INFO("msm_vidc_dec: Return from %s()", __func__);
 	return 0;
 }
 
@@ -1787,21 +2194,32 @@
 {
 	struct video_client_ctx *client_ctx = file->private_data;
 
-	DBG("msm_vidc_dec: Inside %s()", __func__);
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT);
+	vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT);
 	vid_dec_close_client(client_ctx);
 	vidc_release_firmware();
 #ifndef USE_RES_TRACKER
 	vidc_disable_clk();
 #endif
-	DBG("msm_vidc_dec: Return from %s()", __func__);
+	INFO("msm_vidc_dec: Return from %s()", __func__);
 	return 0;
 }
 
-static const struct file_operations vid_dec_fops = {
-	.owner = THIS_MODULE,
-	.open = vid_dec_open,
-	.release = vid_dec_release,
-	.ioctl = vid_dec_ioctl,
+static const struct file_operations vid_dec_fops[2] = {
+	{
+		.owner = THIS_MODULE,
+		.open = vid_dec_open,
+		.release = vid_dec_release,
+		.unlocked_ioctl = vid_dec_ioctl,
+	},
+	{
+		.owner = THIS_MODULE,
+		.open = vid_dec_open_secure,
+		.release = vid_dec_release_secure,
+		.unlocked_ioctl = vid_dec_ioctl,
+	},
+
 };
 
 void vid_dec_interrupt_deregister(void)
@@ -1867,7 +2285,7 @@
 
 static int __init vid_dec_init(void)
 {
-	int rc = 0;
+	int rc = 0, i = 0, j = 0;
 	struct device *class_devp;
 
 	DBG("msm_vidc_dec: Inside %s()", __func__);
@@ -1878,7 +2296,8 @@
 		return -ENOMEM;
 	}
 
-	rc = alloc_chrdev_region(&vid_dec_dev_num, 0, 1, VID_DEC_NAME);
+	rc = alloc_chrdev_region(&vid_dec_dev_num, 0, NUM_OF_DRIVER_NODES,
+		VID_DEC_NAME);
 	if (rc < 0) {
 		ERR("%s: alloc_chrdev_region Failed rc = %d\n",
 		       __func__, rc);
@@ -1893,49 +2312,59 @@
 
 		goto error_vid_dec_class_create;
 	}
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++) {
+		class_devp = device_create(vid_dec_class, NULL,
+						(vid_dec_dev_num + i),
+						NULL, VID_DEC_NAME "%s",
+						node_name[i]);
 
-	class_devp = device_create(vid_dec_class, NULL, vid_dec_dev_num, NULL,
-				   VID_DEC_NAME);
+		if (IS_ERR(class_devp)) {
+			rc = PTR_ERR(class_devp);
+			ERR("%s: class device_create failed %d\n",
+				   __func__, rc);
+			if (!i)
+				goto error_vid_dec_class_device_create;
+			else
+				goto error_vid_dec_cdev_add;
+		}
 
-	if (IS_ERR(class_devp)) {
-		rc = PTR_ERR(class_devp);
-		ERR("%s: class device_create failed %d\n",
-		       __func__, rc);
-		goto error_vid_dec_class_device_create;
-	}
+	  vid_dec_device_p->device[i] = class_devp;
 
-  vid_dec_device_p->device = class_devp;
+		cdev_init(&vid_dec_device_p->cdev[i], &vid_dec_fops[i]);
+		vid_dec_device_p->cdev[i].owner = THIS_MODULE;
+		rc = cdev_add(&(vid_dec_device_p->cdev[i]),
+				(vid_dec_dev_num+i), 1);
 
-	cdev_init(&vid_dec_device_p->cdev, &vid_dec_fops);
-	vid_dec_device_p->cdev.owner = THIS_MODULE;
-	rc = cdev_add(&(vid_dec_device_p->cdev), vid_dec_dev_num, 1);
-
-	if (rc < 0) {
-		ERR("%s: cdev_add failed %d\n", __func__, rc);
-		goto error_vid_dec_cdev_add;
+		if (rc < 0) {
+			ERR("%s: cdev_add failed %d\n", __func__, rc);
+			goto error_vid_dec_cdev_add;
+		}
 	}
 	vid_dec_vcd_init();
 	return 0;
 
 error_vid_dec_cdev_add:
+	for (j = i-1; j >= 0; j--)
+		cdev_del(&(vid_dec_device_p->cdev[j]));
 	device_destroy(vid_dec_class, vid_dec_dev_num);
 error_vid_dec_class_device_create:
 	class_destroy(vid_dec_class);
 error_vid_dec_class_create:
-	unregister_chrdev_region(vid_dec_dev_num, 1);
+	unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
 error_vid_dec_alloc_chrdev_region:
 	kfree(vid_dec_device_p);
-
 	return rc;
 }
 
 static void __exit vid_dec_exit(void)
 {
-	DBG("msm_vidc_dec: Inside %s()", __func__);
-	cdev_del(&(vid_dec_device_p->cdev));
+	int i = 0;
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++)
+		cdev_del(&(vid_dec_device_p->cdev[i]));
 	device_destroy(vid_dec_class, vid_dec_dev_num);
 	class_destroy(vid_dec_class);
-	unregister_chrdev_region(vid_dec_dev_num, 1);
+	unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
 	kfree(vid_dec_device_p);
 	DBG("msm_vidc_dec: Return from %s()", __func__);
 }
diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h
index 48ba65f..89da9a2 100644
--- a/drivers/video/msm/vidc/common/dec/vdec_internal.h
+++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h
@@ -1,29 +1,13 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
@@ -32,7 +16,9 @@
 
 #include <linux/msm_vidc_dec.h>
 #include <linux/cdev.h>
-#include "vidc_init.h"
+#include <media/msm/vidc_init.h>
+
+#define NUM_OF_DRIVER_NODES 2
 
 struct vid_dec_msg {
 	struct list_head list;
@@ -40,8 +26,8 @@
 };
 
 struct vid_dec_dev {
-	struct cdev cdev;
-	struct device *device;
+	struct cdev cdev[NUM_OF_DRIVER_NODES];
+	struct device *device[NUM_OF_DRIVER_NODES];
 	resource_size_t phys_base;
 	void __iomem *virt_base;
 	unsigned int irq;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index a3684ef..ff4bc6b 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,11 +9,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
 #include <linux/cdev.h>
@@ -32,11 +27,12 @@
 #include <linux/workqueue.h>
 #include <linux/android_pmem.h>
 #include <linux/clk.h>
+#include <media/msm/vidc_type.h>
+#include <media/msm/vcd_api.h>
+#include <media/msm/vidc_init.h>
 
-#include "vidc_type.h"
-#include "vcd_api.h"
 #include "venc_internal.h"
-#include "vidc_init.h"
+#include "vcd_res_tracker_api.h"
 
 #define VID_ENC_NAME	"msm_vidc_enc"
 
@@ -52,7 +48,7 @@
 static struct vid_enc_dev *vid_enc_device_p;
 static dev_t vid_enc_dev_num;
 static struct class *vid_enc_class;
-static int vid_enc_ioctl(struct inode *inode, struct file *file,
+static long vid_enc_ioctl(struct file *file,
 	unsigned cmd, unsigned long arg);
 static int stop_cmd;
 
@@ -163,18 +159,22 @@
 
 	venc_msg->venc_msg_info.statuscode = vid_enc_get_status(status);
 
-	if (event == VCD_EVT_RESP_INPUT_DONE) {
-		venc_msg->venc_msg_info.msgcode =
-			VEN_MSG_INPUT_BUFFER_DONE;
-		DBG("Send INPUT_DON message to client = %p\n",
+	venc_msg->venc_msg_info.msgcode = VEN_MSG_INPUT_BUFFER_DONE;
+
+	switch (event) {
+	case VCD_EVT_RESP_INPUT_DONE:
+	   DBG("Send INPUT_DON message to client = %p\n",
 			client_ctx);
-	} else if (event == VCD_EVT_RESP_INPUT_FLUSHED) {
-		venc_msg->venc_msg_info.msgcode = VEN_MSG_INPUT_BUFFER_DONE;
+	   break;
+	case VCD_EVT_RESP_INPUT_FLUSHED:
 		DBG("Send INPUT_FLUSHED message to client = %p\n",
 			client_ctx);
-	} else {
-		ERR("vid_enc_input_frame_done(): invalid event type\n");
-		return;
+	   break;
+	default:
+		ERR("vid_enc_input_frame_done(): invalid event type: "
+			"%d\n", event);
+		venc_msg->venc_msg_info.statuscode = VEN_S_EFATAL;
+	   break;
 	}
 
 	venc_msg->venc_msg_info.buf.clientdata =
@@ -197,6 +197,8 @@
 	int pmem_fd;
 	struct file *file;
 	s32 buffer_index = -1;
+	u32 ion_flag = 0;
+	struct ion_handle *buff_handle = NULL;
 
 	if (!client_ctx || !vcd_frame_data) {
 		ERR("vid_enc_input_frame_done() NULL pointer\n");
@@ -212,17 +214,21 @@
 	}
 
 	venc_msg->venc_msg_info.statuscode = vid_enc_get_status(status);
+	venc_msg->venc_msg_info.msgcode = VEN_MSG_OUTPUT_BUFFER_DONE;
 
-	if (event == VCD_EVT_RESP_OUTPUT_DONE)
-		venc_msg->venc_msg_info.msgcode =
-		VEN_MSG_OUTPUT_BUFFER_DONE;
-
-	else if (event == VCD_EVT_RESP_OUTPUT_FLUSHED)
-		venc_msg->venc_msg_info.msgcode =
-		VEN_MSG_OUTPUT_BUFFER_DONE;
-	else {
-		ERR("QVD: vid_enc_output_frame_done invalid cmd type\n");
-		return;
+	switch (event) {
+	case VCD_EVT_RESP_OUTPUT_DONE:
+	   DBG("Send INPUT_DON message to client = %p\n",
+			client_ctx);
+	   break;
+	case VCD_EVT_RESP_OUTPUT_FLUSHED:
+	   DBG("Send INPUT_FLUSHED message to client = %p\n",
+		   client_ctx);
+	   break;
+	default:
+	   ERR("QVD: vid_enc_output_frame_done invalid cmd type: %d\n", event);
+	   venc_msg->venc_msg_info.statuscode = VEN_S_EFATAL;
+	   break;
 	}
 
 	kernel_vaddr =
@@ -255,7 +261,18 @@
 		venc_msg->venc_msg_info.statuscode =
 			VEN_S_EFATAL;
 	}
-
+	if (venc_msg->venc_msg_info.buf.len > 0) {
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+					pmem_fd, kernel_vaddr, buffer_index,
+					&buff_handle);
+		if (ion_flag == CACHED) {
+			msm_ion_do_cache_op(client_ctx->user_ion_client,
+				buff_handle,
+				(unsigned long *) kernel_vaddr,
+				(unsigned long)venc_msg->venc_msg_info.buf.len,
+				ION_IOC_CLEAN_INV_CACHES);
+		}
+	}
 	mutex_lock(&client_ctx->msg_queue_lock);
 	list_add_tail(&venc_msg->list, &client_ctx->msg_queue);
 	mutex_unlock(&client_ctx->msg_queue_lock);
@@ -490,7 +507,6 @@
 		mutex_unlock(&vid_enc_device_p->lock);
 		return false;
 	}
-
 	memset((void *)client_ctx, 0,
 		sizeof(struct video_client_ctx));
 
@@ -505,7 +521,7 @@
 {
 	s32 client_index;
 	struct video_client_ctx *client_ctx;
-	u32 vcd_status = VCD_ERR_FAIL;
+	int rc = 0;
 	u8 client_count = 0;
 
 	INFO("\n msm_vidc_enc: Inside %s()", __func__);
@@ -529,7 +545,7 @@
 
 	client_index = vid_enc_get_empty_client_index();
 
-	if (client_index < 0) {
+	if (client_index == -1) {
 		ERR("%s() : No free clients client_index == -1\n",
 			__func__);
 		return -ENODEV;
@@ -541,13 +557,21 @@
 
 	init_completion(&client_ctx->event);
 	mutex_init(&client_ctx->msg_queue_lock);
+	mutex_init(&client_ctx->enrty_queue_lock);
 	INIT_LIST_HEAD(&client_ctx->msg_queue);
 	init_waitqueue_head(&client_ctx->msg_wait);
-	vcd_status = vcd_open(vid_enc_device_p->device_handle, false,
-		vid_enc_vcd_cb, client_ctx);
+	if (vcd_get_ion_status()) {
+		client_ctx->user_ion_client = vcd_get_ion_client();
+		if (!client_ctx->user_ion_client) {
+			ERR("vcd_open ion get client failed");
+			return -EFAULT;
+		}
+	}
+	rc = vcd_open(vid_enc_device_p->device_handle, false,
+		vid_enc_vcd_cb, client_ctx, 0);
 	client_ctx->stop_msg = 0;
 
-	if (!vcd_status) {
+	if (!rc) {
 		wait_for_completion(&client_ctx->event);
 		if (client_ctx->event_status) {
 			ERR("callback for vcd_open returned error: %u",
@@ -556,13 +580,13 @@
 			return -EFAULT;
 		}
 	} else {
-		ERR("vcd_open returned error: %u", vcd_status);
+		ERR("vcd_open returned error: %u", rc);
 		mutex_unlock(&vid_enc_device_p->lock);
-		return -EFAULT;
+		return rc;
 	}
 	file->private_data = client_ctx;
 	mutex_unlock(&vid_enc_device_p->lock);
-	return 0;
+	return rc;
 }
 
 static int vid_enc_release(struct inode *inode, struct file *file)
@@ -582,7 +606,7 @@
 	.owner = THIS_MODULE,
 	.open = vid_enc_open,
 	.release = vid_enc_release,
-	.ioctl = vid_enc_ioctl
+	.unlocked_ioctl = vid_enc_ioctl,
 };
 
 void vid_enc_interrupt_deregister(void)
@@ -720,7 +744,7 @@
 	kfree(vid_enc_device_p);
 	INFO("\n msm_vidc_enc: Return from %s()", __func__);
 }
-static int vid_enc_ioctl(struct inode *inode, struct file *file,
+static long vid_enc_ioctl(struct file *file,
 		unsigned cmd, unsigned long u_arg)
 {
 	struct video_client_ctx *client_ctx = NULL;
@@ -963,8 +987,15 @@
 	}
 	case VEN_IOCTL_FREE_RECON_BUFFER:
 	{
+		struct venc_recon_addr venc_recon;
 		DBG("VEN_IOCTL_FREE_RECON_BUFFER\n");
-		result = vid_enc_free_recon_buffers(client_ctx);
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (copy_from_user(&venc_recon, venc_msg.in,
+				sizeof(venc_recon)))
+				return -EFAULT;
+		result = vid_enc_free_recon_buffers(client_ctx,
+				&venc_recon);
 		if (!result) {
 			ERR("VEN_IOCTL_FREE_RECON_BUFFER failed\n");
 			return -EIO;
@@ -1284,7 +1315,6 @@
 	case VEN_IOCTL_GET_SEQUENCE_HDR:
 	{
 		struct venc_seqheader seq_header, seq_header_user;
-		memset(&seq_header, 0, sizeof(struct venc_seqheader));
 		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
 			return -EFAULT;
 
@@ -1548,6 +1578,48 @@
 		}
 		break;
 	}
+	case VEN_IOCTL_SET_EXTRADATA:
+	case VEN_IOCTL_GET_EXTRADATA:
+	{
+		u32 extradata_flag;
+		DBG("VEN_IOCTL_(G)SET_EXTRADATA\n");
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (cmd == VEN_IOCTL_SET_EXTRADATA) {
+			if (copy_from_user(&extradata_flag, venc_msg.in,
+					sizeof(u32)))
+				return -EFAULT;
+			result = vid_enc_set_get_extradata(client_ctx,
+					&extradata_flag, true);
+		} else {
+			result = vid_enc_set_get_extradata(client_ctx,
+					&extradata_flag, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &extradata_flag,
+						sizeof(u32)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n");
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_SLICE_DELIVERY_MODE:
+	{
+		struct vcd_property_hdr vcd_property_hdr;
+		u32 vcd_status = VCD_ERR_FAIL;
+		u32 enable = true;
+		vcd_property_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE;
+		vcd_property_hdr.sz = sizeof(u32);
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+						&vcd_property_hdr, &enable);
+		if (vcd_status) {
+			pr_err(" Setting slice delivery mode failed");
+			return -EIO;
+		}
+		break;
+	}
 	case VEN_IOCTL_SET_AC_PREDICTION:
 	case VEN_IOCTL_GET_AC_PREDICTION:
 	case VEN_IOCTL_SET_RVLC:
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index 1298ff4..58be91a 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,11 +9,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
 #include <linux/cdev.h>
@@ -32,11 +27,12 @@
 #include <linux/workqueue.h>
 #include <linux/android_pmem.h>
 #include <linux/clk.h>
-
-#include "vidc_type.h"
-#include "vcd_api.h"
+#include <mach/msm_subsystem_map.h>
+#include <media/msm/vidc_type.h>
+#include <media/msm/vcd_api.h>
+#include <media/msm/vidc_init.h>
+#include "vcd_res_tracker_api.h"
 #include "venc_internal.h"
-#include "vidc_init.h"
 
 #if DEBUG
 #define DBG(x...) printk(KERN_DEBUG x)
@@ -45,6 +41,9 @@
 #endif
 
 #define ERR(x...) printk(KERN_ERR x)
+static unsigned int vidc_mmu_subsystem[] = {
+	MSM_SUBSYSTEM_VIDEO};
+
 
 u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx,
 		struct venc_basecfg *base_config, u32 set_flag)
@@ -318,6 +317,42 @@
 	return true;
 }
 
+u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx,
+		u32 *extradata_flag, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_meta_data_enable vcd_meta_data;
+	u32 vcd_status = VCD_ERR_FAIL;
+	if (!client_ctx || !extradata_flag)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable);
+	if (set_flag) {
+		DBG("vcd_set_property: VCD_I_METADATA_ENABLE = %d\n",
+				*extradata_flag);
+		vcd_meta_data.meta_data_enable_flag = *extradata_flag;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_meta_data);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_METADATA_ENABLE Failed\n",
+				__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_meta_data);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_METADATA_ENABLE Failed\n",
+				__func__);
+			return false;
+		}
+		*extradata_flag = vcd_meta_data.meta_data_enable_flag;
+		DBG("vcd_get_property: VCD_I_METADATA_ENABLE = %d\n",
+				*extradata_flag);
+	}
+	return true;
+}
+
 u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx,
 		struct venc_framerate *frame_rate, u32 set_flag)
 {
@@ -1496,6 +1531,11 @@
 		venc_buf_req->alignment = buffer_req.align;
 		venc_buf_req->bufpoolid = buffer_req.buf_pool_id;
 		venc_buf_req->suffixsize = 0;
+		DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, "
+			"max_count=%d, buf_pool_id=%d\n", __func__,
+			buffer_req.actual_count, buffer_req.align,
+			buffer_req.sz, buffer_req.min_count,
+			buffer_req.max_count, buffer_req.buf_pool_id);
 	}
 	return status;
 }
@@ -1523,6 +1563,11 @@
 	buffer_req.align = venc_buf_req->alignment;
 	buffer_req.buf_pool_id = 0;
 
+	DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, "
+		"max_count=%d, buf_pool_id=%d\n", __func__,
+		buffer_req.actual_count, buffer_req.align, buffer_req.sz,
+		buffer_req.min_count, buffer_req.max_count,
+		buffer_req.buf_pool_id);
 	vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
 				buffer, &buffer_req);
 
@@ -1538,7 +1583,7 @@
 	enum vcd_buffer_type vcd_buffer_t = VCD_BUFFER_INPUT;
 	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
 	u32 vcd_status = VCD_ERR_FAIL;
-	unsigned long kernel_vaddr;
+	unsigned long kernel_vaddr, length = 0;
 
 	if (!client_ctx || !buffer_info)
 		return false;
@@ -1547,14 +1592,14 @@
 		dir_buffer = BUFFER_TYPE_OUTPUT;
 		vcd_buffer_t = VCD_BUFFER_OUTPUT;
 	}
-
+	length = buffer_info->sz;
 	/*If buffer cannot be set, ignore */
 	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
 					(unsigned long)buffer_info->pbuffer,
 					&kernel_vaddr,
 					buffer_info->fd,
 					(unsigned long)buffer_info->offset,
-					VID_ENC_MAX_NUM_OF_BUFF)) {
+					VID_ENC_MAX_NUM_OF_BUFF, length)) {
 		DBG("%s() : user_virt_addr = %p cannot be set.",
 		    __func__, buffer_info->pbuffer);
 		return false;
@@ -1594,7 +1639,6 @@
 		    __func__, buffer_info->pbuffer);
 		return true;
 	}
-
 	vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer_vcd,
 					 (u8 *)kernel_vaddr);
 
@@ -1612,6 +1656,8 @@
 	int pmem_fd;
 	struct file *file;
 	s32 buffer_index = -1;
+	u32 ion_flag = 0;
+	struct ion_handle *buff_handle = NULL;
 
 	u32 vcd_status = VCD_ERR_FAIL;
 
@@ -1643,6 +1689,21 @@
 		/* Rely on VCD using the same flags as OMX */
 		vcd_input_buffer.flags = input_frame_info->flags;
 
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT,
+				pmem_fd, kernel_vaddr, buffer_index,
+				&buff_handle);
+
+		if (vcd_input_buffer.data_len > 0) {
+			if (ion_flag == CACHED) {
+				msm_ion_do_cache_op(
+				client_ctx->user_ion_client,
+				buff_handle,
+				(unsigned long *) vcd_input_buffer.virtual,
+				(unsigned long) vcd_input_buffer.data_len,
+				ION_IOC_CLEAN_CACHES);
+			}
+		}
+
 		vcd_status = vcd_encode_frame(client_ctx->vcd_handle,
 		&vcd_input_buffer);
 		if (!vcd_status)
@@ -1705,55 +1766,200 @@
 		struct venc_recon_addr *venc_recon)
 {
 	u32 vcd_status = VCD_ERR_FAIL;
-	u32 len;
+	u32 len, i, flags = 0;
 	struct file *file;
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_enc_recon_buffer control;
+	struct vcd_property_enc_recon_buffer *control = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	int rc = -1;
+	unsigned long ionflag = 0;
+	unsigned long iova = 0;
+	unsigned long buffer_size = 0;
+	size_t ion_len = -1;
+	unsigned long phy_addr;
 
-	control.buffer_size = venc_recon->buffer_size;
-	control.kernel_virtual_addr = NULL;
-	control.physical_addr = NULL;
-	control.pmem_fd = venc_recon->pmem_fd;
-	control.offset = venc_recon->offset;
-
-	if (get_pmem_file(control.pmem_fd, (unsigned long *)
-		(&(control.physical_addr)), (unsigned long *)
-		(&control.kernel_virtual_addr),
-		(unsigned long *) (&len), &file)) {
-			ERR("%s(): get_pmem_file failed\n", __func__);
-			return false;
+	if (!client_ctx || !venc_recon) {
+		pr_err("%s() Invalid params", __func__);
+		return false;
+	}
+	len = sizeof(client_ctx->recon_buffer)/
+		sizeof(struct vcd_property_enc_recon_buffer);
+	for (i = 0; i < len; i++) {
+		if (!client_ctx->recon_buffer[i].kernel_virtual_addr) {
+			control = &client_ctx->recon_buffer[i];
+			break;
 		}
-		put_pmem_file(file);
-		DBG("Virt: %p, Phys %p, fd: %d", control.kernel_virtual_addr,
-			control.physical_addr, control.pmem_fd);
+	}
+	if (!control) {
+		pr_err("Exceeded max recon buffer setting");
+		return false;
+	}
+	control->buffer_size = venc_recon->buffer_size;
+	control->kernel_virtual_addr = NULL;
+	control->physical_addr = NULL;
+	control->pmem_fd = venc_recon->pmem_fd;
+	control->offset = venc_recon->offset;
+	control->user_virtual_addr = venc_recon->pbuffer;
 
-		vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS;
-		vcd_property_hdr.sz =
-			sizeof(struct vcd_property_enc_recon_buffer);
-
-		vcd_status = vcd_set_property(client_ctx->vcd_handle,
-						&vcd_property_hdr, &control);
-		if (!vcd_status) {
-			DBG("vcd_set_property returned success\n");
-			return true;
+	if (!vcd_get_ion_status()) {
+		if (get_pmem_file(control->pmem_fd, (unsigned long *)
+			(&(control->physical_addr)), (unsigned long *)
+			(&control->kernel_virtual_addr),
+			(unsigned long *) (&len), &file)) {
+				ERR("%s(): get_pmem_file failed\n", __func__);
+				return false;
+			}
+			put_pmem_file(file);
+			flags = MSM_SUBSYSTEM_MAP_IOVA;
+			mapped_buffer = msm_subsystem_map_buffer(
+			(unsigned long)control->physical_addr, len,
+			flags, vidc_mmu_subsystem,
+			sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+			if (IS_ERR(mapped_buffer)) {
+				pr_err("buffer map failed");
+				return false;
+			}
+			control->client_data = (void *) mapped_buffer;
+			control->dev_addr = (u8 *)mapped_buffer->iova[0];
+	} else {
+		client_ctx->recon_buffer_ion_handle[i] = ion_import_fd(
+				client_ctx->user_ion_client, control->pmem_fd);
+		if (IS_ERR_OR_NULL(client_ctx->recon_buffer_ion_handle[i])) {
+			ERR("%s(): get_ION_handle failed\n", __func__);
+			goto import_ion_error;
+		}
+		rc = ion_handle_get_flags(client_ctx->user_ion_client,
+					client_ctx->recon_buffer_ion_handle[i],
+					&ionflag);
+		if (rc) {
+			ERR("%s():get_ION_flags fail\n",
+				 __func__);
+			goto import_ion_error;
+		}
+		control->kernel_virtual_addr = (u8 *) ion_map_kernel(
+			client_ctx->user_ion_client,
+			client_ctx->recon_buffer_ion_handle[i],
+			ionflag);
+		if (!control->kernel_virtual_addr) {
+			ERR("%s(): get_ION_kernel virtual addr fail\n",
+				 __func__);
+			goto import_ion_error;
+		}
+		if (res_trk_check_for_sec_session() ||
+		   (res_trk_get_core_type() == (u32)VCD_CORE_720P)) {
+			rc = ion_phys(client_ctx->user_ion_client,
+				client_ctx->recon_buffer_ion_handle[i],
+				&phy_addr, &ion_len);
+			if (rc) {
+				ERR("%s():get_ION_kernel physical addr fail\n",
+					__func__);
+				goto map_ion_error;
+			}
+			control->physical_addr =  (u8 *) phy_addr;
+			len = (unsigned long) ion_len;
+			control->client_data = NULL;
+			control->dev_addr = (u8 *)control->physical_addr;
 		} else {
-			ERR("%s(): vid_enc_set_recon_buffers failed = %u\n",
-					__func__, vcd_status);
-			return false;
+			rc = ion_map_iommu(client_ctx->user_ion_client,
+					client_ctx->recon_buffer_ion_handle[i],
+					VIDEO_DOMAIN,
+					VIDEO_MAIN_POOL,
+					SZ_4K,
+					0,
+					(unsigned long *)&iova,
+					(unsigned long *)&buffer_size,
+					UNCACHED, 0);
+			if (rc) {
+				ERR("%s():ION map iommu addr fail\n",
+					 __func__);
+				goto map_ion_error;
+			}
+			control->physical_addr =  (u8 *) iova;
+			len = buffer_size;
+			control->client_data = NULL;
+			control->dev_addr = (u8 *)iova;
 		}
+	}
+
+	vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_enc_recon_buffer);
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, control);
+	if (!vcd_status) {
+		DBG("vcd_set_property returned success\n");
+		return true;
+	} else {
+		ERR("%s(): vid_enc_set_recon_buffers failed = %u\n",
+				__func__, vcd_status);
+		return false;
+	}
+map_ion_error:
+	if (control->kernel_virtual_addr)
+		ion_unmap_kernel(client_ctx->user_ion_client,
+			client_ctx->recon_buffer_ion_handle[i]);
+	if (client_ctx->recon_buffer_ion_handle[i])
+		ion_free(client_ctx->user_ion_client,
+			client_ctx->recon_buffer_ion_handle[i]);
+		client_ctx->recon_buffer_ion_handle[i] = NULL;
+import_ion_error:
+	return false;
 }
 
-u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx)
+u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx,
+			struct venc_recon_addr *venc_recon)
 {
 	u32 vcd_status = VCD_ERR_FAIL;
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_enc_recon_buffer control;
+	struct vcd_property_enc_recon_buffer *control = NULL;
+	u32 len = 0, i;
+
+	if (!client_ctx || !venc_recon) {
+		pr_err("%s() Invalid params", __func__);
+		return false;
+	}
+	len = sizeof(client_ctx->recon_buffer)/
+		sizeof(struct vcd_property_enc_recon_buffer);
+	pr_err(" %s() address  %p", __func__,
+	venc_recon->pbuffer);
+	for (i = 0; i < len; i++) {
+		if (client_ctx->recon_buffer[i].user_virtual_addr
+			== venc_recon->pbuffer) {
+			control = &client_ctx->recon_buffer[i];
+			break;
+		}
+	}
+	if (!control) {
+		pr_err(" %s() address not found %p", __func__,
+			venc_recon->pbuffer);
+		return false;
+	}
+	if (control->client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		control->client_data);
 
 	vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
-
 	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-						&vcd_property_hdr, &control);
+						&vcd_property_hdr, control);
+	if (vcd_get_ion_status()) {
+		if (client_ctx->recon_buffer_ion_handle[i]) {
+			ion_unmap_kernel(client_ctx->user_ion_client,
+				client_ctx->recon_buffer_ion_handle[i]);
+			if (!res_trk_check_for_sec_session() &&
+			   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
+				ion_unmap_iommu(client_ctx->user_ion_client,
+				client_ctx->recon_buffer_ion_handle[i],
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL);
+			}
+			ion_free(client_ctx->user_ion_client,
+				client_ctx->recon_buffer_ion_handle[i]);
+			client_ctx->recon_buffer_ion_handle[i] = NULL;
+		}
+	}
+	memset(control, 0, sizeof(struct vcd_property_enc_recon_buffer));
 	return true;
 }
 
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
index e7b7ff3..8a07fdb 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.h
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -1,29 +1,13 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
@@ -32,8 +16,7 @@
 
 #include <linux/msm_vidc_enc.h>
 #include <linux/cdev.h>
-
-#include "vidc_init.h"
+#include <media/msm/vidc_init.h>
 
 #define VID_ENC_MAX_NUM_OF_BUFF 100
 
@@ -85,6 +68,9 @@
 u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx,
 		struct venc_switch *encoder_switch, u32 set_flag);
 
+u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx,
+		u32 *extradata_flag, u32 set_flag);
+
 u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx,
 		struct venc_switch *encoder_switch, u32 set_flag);
 
@@ -159,7 +145,8 @@
 u32 vid_enc_set_recon_buffers(struct video_client_ctx *client_ctx,
 		struct venc_recon_addr *venc_recon);
 
-u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx);
+u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx,
+		struct venc_recon_addr *venc_recon);
 
 u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx,
 		struct venc_recon_buff_size *venc_recon_size);
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
old mode 100644
new mode 100755
index b9581a9..6226c79
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,11 +9,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
 #include <linux/cdev.h>
@@ -33,13 +28,12 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/debugfs.h>
-#include <mach/internal_power_rail.h>
 #include <mach/clk.h>
 #include <linux/pm_runtime.h>
-
-#include "vcd_api.h"
+#include <mach/msm_subsystem_map.h>
+#include <media/msm/vcd_api.h>
+#include <media/msm/vidc_init.h>
 #include "vidc_init_internal.h"
-#include "vidc_init.h"
 #include "vcd_res_tracker_api.h"
 
 #if DEBUG
@@ -55,12 +49,13 @@
 static struct vidc_dev *vidc_device_p;
 static dev_t vidc_dev_num;
 static struct class *vidc_class;
+static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO};
 
 static const struct file_operations vidc_fops = {
 	.owner = THIS_MODULE,
 	.open = NULL,
 	.release = NULL,
-	.ioctl = NULL,
+	.unlocked_ioctl = NULL,
 };
 
 struct workqueue_struct *vidc_wq;
@@ -68,7 +63,7 @@
 static irqreturn_t vidc_isr(int irq, void *dev);
 static spinlock_t vidc_spin_lock;
 
-u32 vidc_msg_timing, vidc_msg_pmem;
+u32 vidc_msg_timing, vidc_msg_pmem, vidc_msg_register;
 
 #ifdef VIDC_ENABLE_DBGFS
 struct dentry *vidc_debugfs_root;
@@ -84,7 +79,7 @@
 				u32 *var)
 {
 	struct dentry *vidc_debugfs_file =
-	    debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
+		debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
 	if (!vidc_debugfs_file)
 		ERR("%s(): Error creating/opening file %s\n", __func__, name);
 }
@@ -157,8 +152,8 @@
 		ERR("%s(): Invalid resource\n", __func__);
 		return -ENXIO;
 	}
-	if (resource && resource->start)
-		vidc_device_p->phys_base = resource->start;
+
+	vidc_device_p->phys_base = resource->start;
 	vidc_device_p->virt_base = ioremap(resource->start,
 	resource->end - resource->start + 1);
 
@@ -290,14 +285,14 @@
 
 	if (unlikely(rc)) {
 		ERR("%s() :request_irq failed\n", __func__);
-		goto error_vidc_platfom_register;
+		goto error_vidc_request_irq;
 	}
 	res_trk_init(vidc_device_p->device, vidc_device_p->irq);
 	vidc_timer_wq = create_singlethread_workqueue("vidc_timer_wq");
 	if (!vidc_timer_wq) {
 		ERR("%s: create workque failed\n", __func__);
 		rc = -ENOMEM;
-		goto error_vidc_platfom_register;
+		goto error_vidc_create_workqueue;
 	}
 	DBG("Disabling IRQ in %s()\n", __func__);
 	disable_irq_nosync(vidc_device_p->irq);
@@ -316,10 +311,16 @@
 				(u32 *) &vidc_msg_timing);
 		vidc_debugfs_file_create(root, "vidc_msg_pmem",
 				(u32 *) &vidc_msg_pmem);
+		vidc_debugfs_file_create(root, "vidc_msg_register",
+				(u32 *) &vidc_msg_register);
 	}
 #endif
 	return 0;
 
+error_vidc_create_workqueue:
+	free_irq(vidc_device_p->irq, vidc_device_p->device);
+error_vidc_request_irq:
+	platform_driver_unregister(&msm_vidc_720p_platform_driver);
 error_vidc_platfom_register:
 	cdev_del(&(vidc_device_p->cdev));
 error_vidc_cdev_add:
@@ -344,31 +345,133 @@
 {
 	u32 status = true;
 
-	mutex_lock(&vidc_device_p->lock);
-	if (!vidc_device_p->get_firmware) {
-		status = res_trk_download_firmware();
-		if (!status)
-			goto error;
-		vidc_device_p->get_firmware = 1;
-	}
-	vidc_device_p->firmware_refcount++;
+	if (!res_trk_check_for_sec_session()) {
+		mutex_lock(&vidc_device_p->lock);
+		if (!vidc_device_p->get_firmware) {
+			status = res_trk_download_firmware();
+			if (!status)
+				goto error;
+			vidc_device_p->get_firmware = 1;
+		}
+		vidc_device_p->firmware_refcount++;
 error:
-	mutex_unlock(&vidc_device_p->lock);
+		mutex_unlock(&vidc_device_p->lock);
+	}
 	return status;
 }
 EXPORT_SYMBOL(vidc_load_firmware);
 
 void vidc_release_firmware(void)
 {
-	mutex_lock(&vidc_device_p->lock);
-	if (vidc_device_p->firmware_refcount > 0)
-		vidc_device_p->firmware_refcount--;
-	else
-		vidc_device_p->firmware_refcount = 0;
-	mutex_unlock(&vidc_device_p->lock);
+	if (!res_trk_check_for_sec_session()) {
+		mutex_lock(&vidc_device_p->lock);
+		if (vidc_device_p->firmware_refcount > 0)
+			vidc_device_p->firmware_refcount--;
+		else
+			vidc_device_p->firmware_refcount = 0;
+		mutex_unlock(&vidc_device_p->lock);
+	}
 }
 EXPORT_SYMBOL(vidc_release_firmware);
 
+u32 vidc_get_fd_info(struct video_client_ctx *client_ctx,
+		enum buffer_dir buffer, int pmem_fd,
+		unsigned long kvaddr, int index,
+		struct ion_handle **buff_handle)
+{
+	struct buf_addr_table *buf_addr_table;
+	u32 rc = 0;
+	if (!client_ctx)
+		return false;
+	if (buffer == BUFFER_TYPE_INPUT)
+		buf_addr_table = client_ctx->input_buf_addr_table;
+	else
+		buf_addr_table = client_ctx->output_buf_addr_table;
+	if (buf_addr_table[index].pmem_fd == pmem_fd) {
+		if (buf_addr_table[index].kernel_vaddr == kvaddr)
+			rc = buf_addr_table[index].buff_ion_flag;
+			*buff_handle = buf_addr_table[index].buff_ion_handle;
+	}
+	return rc;
+}
+EXPORT_SYMBOL(vidc_get_fd_info);
+
+void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx,
+				enum buffer_dir buffer)
+{
+	u32 *num_of_buffers = NULL;
+	u32 i = 0;
+	struct buf_addr_table *buf_addr_table;
+	if (buffer == BUFFER_TYPE_INPUT) {
+		buf_addr_table = client_ctx->input_buf_addr_table;
+		num_of_buffers = &client_ctx->num_of_input_buffers;
+		DBG("%s(): buffer = INPUT\n", __func__);
+
+	} else {
+		buf_addr_table = client_ctx->output_buf_addr_table;
+		num_of_buffers = &client_ctx->num_of_output_buffers;
+		DBG("%s(): buffer = OUTPUT\n", __func__);
+	}
+
+	if (!*num_of_buffers)
+		goto bail_out_cleanup;
+	if (!client_ctx->user_ion_client)
+		goto bail_out_cleanup;
+	for (i = 0; i < *num_of_buffers; ++i) {
+		if (buf_addr_table[i].client_data) {
+			msm_subsystem_unmap_buffer(
+			(struct msm_mapped_buffer *)
+			buf_addr_table[i].client_data);
+			buf_addr_table[i].client_data = NULL;
+		}
+		if (!IS_ERR_OR_NULL(buf_addr_table[i].buff_ion_handle)) {
+			if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) {
+				ion_unmap_kernel(client_ctx->user_ion_client,
+						buf_addr_table[i].
+						buff_ion_handle);
+				if (!res_trk_check_for_sec_session() &&
+				   (res_trk_get_core_type() !=
+				   (u32)VCD_CORE_720P)) {
+					ion_unmap_iommu(
+						client_ctx->user_ion_client,
+						buf_addr_table[i].
+						buff_ion_handle,
+						VIDEO_DOMAIN,
+						VIDEO_MAIN_POOL);
+				}
+				ion_free(client_ctx->user_ion_client,
+						buf_addr_table[i].
+						buff_ion_handle);
+				buf_addr_table[i].buff_ion_handle = NULL;
+			}
+		}
+	}
+	if (client_ctx->vcd_h264_mv_buffer.client_data) {
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_h264_mv_buffer.client_data);
+		client_ctx->vcd_h264_mv_buffer.client_data = NULL;
+	}
+	if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) {
+		if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) {
+			ion_unmap_kernel(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle);
+			if (!res_trk_check_for_sec_session() &&
+			    (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
+				ion_unmap_iommu(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle,
+					VIDEO_DOMAIN,
+					VIDEO_MAIN_POOL);
+			}
+			ion_free(client_ctx->user_ion_client,
+					client_ctx->h264_mv_ion_handle);
+			client_ctx->h264_mv_ion_handle = NULL;
+		}
+	}
+bail_out_cleanup:
+	return;
+}
+EXPORT_SYMBOL(vidc_cleanup_addr_table);
+
 u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer,
 	u32 search_with_user_vaddr,
@@ -384,7 +487,7 @@
 
 	if (!client_ctx)
 		return false;
-
+	mutex_lock(&client_ctx->enrty_queue_lock);
 	if (buffer == BUFFER_TYPE_INPUT) {
 		buf_addr_table = client_ctx->input_buf_addr_table;
 		num_of_buffers = client_ctx->num_of_input_buffers;
@@ -419,7 +522,7 @@
 	}
 
 	if (found) {
-		*phy_addr = buf_addr_table[i].phy_addr;
+		*phy_addr = buf_addr_table[i].dev_addr;
 		*pmem_fd = buf_addr_table[i].pmem_fd;
 		*file = buf_addr_table[i].file;
 		*buffer_index = i;
@@ -434,6 +537,7 @@
 			" pmem_fd = %d, struct *file	= %p "
 			"buffer_index = %d\n", *user_vaddr, *phy_addr,
 			*pmem_fd, *file, *buffer_index);
+		mutex_unlock(&client_ctx->enrty_queue_lock);
 		return true;
 	} else {
 		if (search_with_user_vaddr)
@@ -443,6 +547,7 @@
 			DBG("%s() : client_ctx = %p kernel_virt_addr = 0x%08lx"
 			" Not Found.\n", __func__, client_ctx,
 			*kernel_vaddr);
+		mutex_unlock(&client_ctx->enrty_queue_lock);
 		return false;
 	}
 }
@@ -451,17 +556,188 @@
 u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer, unsigned long user_vaddr,
 	unsigned long *kernel_vaddr, int pmem_fd,
-	unsigned long buffer_addr_offset, unsigned int max_num_buffers)
+	unsigned long buffer_addr_offset, unsigned int max_num_buffers,
+	unsigned long length)
 {
 	unsigned long len, phys_addr;
-	struct file *file;
+	struct file *file = NULL;
+	u32 *num_of_buffers = NULL;
+	u32 i, flags;
+	struct buf_addr_table *buf_addr_table;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	struct ion_handle *buff_ion_handle = NULL;
+	unsigned long ionflag = 0;
+	unsigned long iova = 0;
+	int ret = 0;
+	unsigned long buffer_size  = 0;
+	size_t ion_len;
+
+	if (!client_ctx || !length)
+		return false;
+	mutex_lock(&client_ctx->enrty_queue_lock);
+	if (buffer == BUFFER_TYPE_INPUT) {
+		buf_addr_table = client_ctx->input_buf_addr_table;
+		num_of_buffers = &client_ctx->num_of_input_buffers;
+		DBG("%s(): buffer = INPUT #Buf = %d\n",
+			__func__, *num_of_buffers);
+
+	} else {
+		buf_addr_table = client_ctx->output_buf_addr_table;
+		num_of_buffers = &client_ctx->num_of_output_buffers;
+		DBG("%s(): buffer = OUTPUT #Buf = %d\n",
+			__func__, *num_of_buffers);
+		length = length * 2; /* workaround for iommu video h/w bug */
+	}
+
+	if (*num_of_buffers == max_num_buffers) {
+		ERR("%s(): Num of buffers reached max value : %d",
+			__func__, max_num_buffers);
+		goto bail_out_add;
+	}
+
+	i = 0;
+	while (i < *num_of_buffers &&
+		user_vaddr != buf_addr_table[i].user_vaddr)
+		i++;
+	if (i < *num_of_buffers) {
+		DBG("%s() : client_ctx = %p."
+			" user_virt_addr = 0x%08lx already set",
+			__func__, client_ctx, user_vaddr);
+		goto bail_out_add;
+	} else {
+		if (!vcd_get_ion_status()) {
+			if (get_pmem_file(pmem_fd, &phys_addr,
+					kernel_vaddr, &len, &file)) {
+				ERR("%s(): get_pmem_file failed\n", __func__);
+				goto bail_out_add;
+			}
+			put_pmem_file(file);
+			flags = (buffer == BUFFER_TYPE_INPUT)
+			? MSM_SUBSYSTEM_MAP_IOVA :
+			MSM_SUBSYSTEM_MAP_IOVA|MSM_SUBSYSTEM_ALIGN_IOVA_8K;
+			mapped_buffer = msm_subsystem_map_buffer(phys_addr,
+			length, flags, vidc_mmu_subsystem,
+			sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+			if (IS_ERR(mapped_buffer)) {
+				pr_err("buffer map failed");
+				goto bail_out_add;
+			}
+			buf_addr_table[*num_of_buffers].client_data = (void *)
+				mapped_buffer;
+			buf_addr_table[*num_of_buffers].dev_addr =
+				mapped_buffer->iova[0];
+		} else {
+			buff_ion_handle = ion_import_fd(
+				client_ctx->user_ion_client, pmem_fd);
+			if (IS_ERR_OR_NULL(buff_ion_handle)) {
+				ERR("%s(): get_ION_handle failed\n",
+				 __func__);
+				goto bail_out_add;
+			}
+			if (ion_handle_get_flags(client_ctx->user_ion_client,
+						buff_ion_handle,
+						&ionflag)) {
+				ERR("%s():ION flags fail\n",
+				 __func__);
+				goto bail_out_add;
+			}
+			*kernel_vaddr = (unsigned long)
+				ion_map_kernel(
+				client_ctx->user_ion_client,
+				buff_ion_handle,
+				ionflag);
+			if (IS_ERR_OR_NULL((void *)*kernel_vaddr)) {
+				ERR("%s():ION virtual addr fail\n",
+				 __func__);
+				*kernel_vaddr = (unsigned long)NULL;
+				goto ion_free_error;
+			}
+			if (res_trk_check_for_sec_session() ||
+			   (res_trk_get_core_type() == (u32)VCD_CORE_720P)) {
+				if (ion_phys(client_ctx->user_ion_client,
+					buff_ion_handle,
+					&phys_addr, &ion_len)) {
+					ERR("%s():ION physical addr fail\n",
+					__func__);
+					goto ion_map_error;
+				}
+				len = (unsigned long) ion_len;
+				buf_addr_table[*num_of_buffers].client_data =
+					 NULL;
+				buf_addr_table[*num_of_buffers].dev_addr =
+					 phys_addr;
+			} else {
+				ret = ion_map_iommu(client_ctx->user_ion_client,
+						buff_ion_handle,
+						VIDEO_DOMAIN,
+						VIDEO_MAIN_POOL,
+						SZ_8K,
+						length,
+						(unsigned long *) &iova,
+						(unsigned long *) &buffer_size,
+						UNCACHED,
+						ION_IOMMU_UNMAP_DELAYED);
+				if (ret) {
+					ERR("%s():ION iommu map fail\n",
+					 __func__);
+					goto ion_map_error;
+				}
+				phys_addr = iova;
+				buf_addr_table[*num_of_buffers].client_data =
+						 NULL;
+				buf_addr_table[*num_of_buffers].dev_addr =
+						 iova;
+			}
+		}
+		phys_addr += buffer_addr_offset;
+		(*kernel_vaddr) += buffer_addr_offset;
+		buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr;
+		buf_addr_table[*num_of_buffers].kernel_vaddr = *kernel_vaddr;
+		buf_addr_table[*num_of_buffers].pmem_fd = pmem_fd;
+		buf_addr_table[*num_of_buffers].file = file;
+		buf_addr_table[*num_of_buffers].phy_addr = phys_addr;
+		buf_addr_table[*num_of_buffers].buff_ion_handle =
+						buff_ion_handle;
+		buf_addr_table[*num_of_buffers].buff_ion_flag =
+						ionflag;
+		*num_of_buffers = *num_of_buffers + 1;
+		DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, "
+			"kernel_vaddr = 0x%08lx phys_addr=%lu inserted!",
+			__func__, client_ctx, user_vaddr, *kernel_vaddr,
+			phys_addr);
+	}
+	mutex_unlock(&client_ctx->enrty_queue_lock);
+	return true;
+ion_map_error:
+	if (*kernel_vaddr && buff_ion_handle)
+		ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
+ion_free_error:
+	if (!IS_ERR_OR_NULL(buff_ion_handle))
+		ion_free(client_ctx->user_ion_client, buff_ion_handle);
+bail_out_add:
+	mutex_unlock(&client_ctx->enrty_queue_lock);
+	return false;
+}
+EXPORT_SYMBOL(vidc_insert_addr_table);
+
+/*
+ * Similar to vidc_insert_addr_table except intended for in-kernel
+ * use where buffers have already been alloced and mapped properly
+ */
+u32 vidc_insert_addr_table_kernel(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, unsigned long user_vaddr,
+	unsigned long kernel_vaddr, unsigned long phys_addr,
+	unsigned int max_num_buffers,
+	unsigned long length)
+{
 	u32 *num_of_buffers = NULL;
 	u32 i;
 	struct buf_addr_table *buf_addr_table;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
 
-	if (!client_ctx)
+	if (!client_ctx || !length || !kernel_vaddr || !phys_addr)
 		return false;
-
+	mutex_lock(&client_ctx->enrty_queue_lock);
 	if (buffer == BUFFER_TYPE_INPUT) {
 		buf_addr_table = client_ctx->input_buf_addr_table;
 		num_of_buffers = &client_ctx->num_of_input_buffers;
@@ -478,40 +754,42 @@
 	if (*num_of_buffers == max_num_buffers) {
 		ERR("%s(): Num of buffers reached max value : %d",
 			__func__, max_num_buffers);
-		return false;
+		goto bail_out_add;
 	}
 
 	i = 0;
 	while (i < *num_of_buffers &&
-		user_vaddr != buf_addr_table[i].user_vaddr)
+		user_vaddr != buf_addr_table[i].user_vaddr) {
 		i++;
+	}
 	if (i < *num_of_buffers) {
 		DBG("%s() : client_ctx = %p."
 			" user_virt_addr = 0x%08lx already set",
 			__func__, client_ctx, user_vaddr);
-		return false;
+		goto bail_out_add;
 	} else {
-		if (get_pmem_file(pmem_fd, &phys_addr,
-				kernel_vaddr, &len, &file)) {
-			ERR("%s(): get_pmem_file failed\n", __func__);
-			return false;
-		}
-		put_pmem_file(file);
-		phys_addr += buffer_addr_offset;
-		(*kernel_vaddr) += buffer_addr_offset;
+		mapped_buffer = NULL;
+		buf_addr_table[*num_of_buffers].client_data = (void *)
+			mapped_buffer;
+		buf_addr_table[*num_of_buffers].dev_addr = phys_addr;
 		buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr;
-		buf_addr_table[*num_of_buffers].kernel_vaddr = *kernel_vaddr;
-		buf_addr_table[*num_of_buffers].pmem_fd = pmem_fd;
-		buf_addr_table[*num_of_buffers].file = file;
+		buf_addr_table[*num_of_buffers].kernel_vaddr = kernel_vaddr;
+		buf_addr_table[*num_of_buffers].pmem_fd = -1;
+		buf_addr_table[*num_of_buffers].file = NULL;
 		buf_addr_table[*num_of_buffers].phy_addr = phys_addr;
+		buf_addr_table[*num_of_buffers].buff_ion_handle = NULL;
 		*num_of_buffers = *num_of_buffers + 1;
 		DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, "
-			"kernel_vaddr = 0x%08lx inserted!",	__func__,
-			client_ctx, user_vaddr, *kernel_vaddr);
+			"kernel_vaddr = 0x%08lx inserted!", __func__,
+			client_ctx, user_vaddr, kernel_vaddr);
 	}
+	mutex_unlock(&client_ctx->enrty_queue_lock);
 	return true;
+bail_out_add:
+	mutex_unlock(&client_ctx->enrty_queue_lock);
+	return false;
 }
-EXPORT_SYMBOL(vidc_insert_addr_table);
+EXPORT_SYMBOL(vidc_insert_addr_table_kernel);
 
 u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer,
@@ -524,33 +802,54 @@
 
 	if (!client_ctx)
 		return false;
-
+	mutex_lock(&client_ctx->enrty_queue_lock);
 	if (buffer == BUFFER_TYPE_INPUT) {
 		buf_addr_table = client_ctx->input_buf_addr_table;
 		num_of_buffers = &client_ctx->num_of_input_buffers;
-		DBG("%s(): buffer = INPUT\n", __func__);
 
 	} else {
 		buf_addr_table = client_ctx->output_buf_addr_table;
 		num_of_buffers = &client_ctx->num_of_output_buffers;
-		DBG("%s(): buffer = OUTPUT\n", __func__);
 	}
 
 	if (!*num_of_buffers)
-		return false;
+		goto bail_out_del;
 
 	i = 0;
 	while (i < *num_of_buffers &&
 		user_vaddr != buf_addr_table[i].user_vaddr)
 		i++;
 	if (i == *num_of_buffers) {
-		DBG("%s() : client_ctx = %p."
+		pr_err("%s() : client_ctx = %p."
 			" user_virt_addr = 0x%08lx NOT found",
 			__func__, client_ctx, user_vaddr);
-		return false;
+		goto bail_out_del;
+	}
+	if (buf_addr_table[i].client_data) {
+		msm_subsystem_unmap_buffer(
+		(struct msm_mapped_buffer *)buf_addr_table[i].client_data);
+		buf_addr_table[i].client_data = NULL;
 	}
 	*kernel_vaddr = buf_addr_table[i].kernel_vaddr;
+	if (buf_addr_table[i].buff_ion_handle) {
+		ion_unmap_kernel(client_ctx->user_ion_client,
+				buf_addr_table[i].buff_ion_handle);
+		if (!res_trk_check_for_sec_session() &&
+		   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
+			ion_unmap_iommu(client_ctx->user_ion_client,
+				buf_addr_table[i].buff_ion_handle,
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL);
+		}
+		ion_free(client_ctx->user_ion_client,
+				buf_addr_table[i].buff_ion_handle);
+		buf_addr_table[i].buff_ion_handle = NULL;
+	}
 	if (i < (*num_of_buffers - 1)) {
+		buf_addr_table[i].client_data =
+			buf_addr_table[*num_of_buffers - 1].client_data;
+		buf_addr_table[i].dev_addr =
+			buf_addr_table[*num_of_buffers - 1].dev_addr;
 		buf_addr_table[i].user_vaddr =
 			buf_addr_table[*num_of_buffers - 1].user_vaddr;
 		buf_addr_table[i].kernel_vaddr =
@@ -561,12 +860,18 @@
 			buf_addr_table[*num_of_buffers - 1].pmem_fd;
 		buf_addr_table[i].file =
 			buf_addr_table[*num_of_buffers - 1].file;
+		buf_addr_table[i].buff_ion_handle =
+			buf_addr_table[*num_of_buffers - 1].buff_ion_handle;
 	}
 	*num_of_buffers = *num_of_buffers - 1;
 	DBG("%s() : client_ctx = %p."
 		" user_virt_addr = 0x%08lx is found and deleted",
 		__func__, client_ctx, user_vaddr);
+	mutex_unlock(&client_ctx->enrty_queue_lock);
 	return true;
+bail_out_del:
+	mutex_unlock(&client_ctx->enrty_queue_lock);
+	return false;
 }
 EXPORT_SYMBOL(vidc_delete_addr_table);
 
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.h b/drivers/video/msm/vidc/common/init/vidc_init.h
deleted file mode 100644
index 0bd0ede..0000000
--- a/drivers/video/msm/vidc/common/init/vidc_init.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef VIDC_INIT_H
-#define VIDC_INIT_H
-
-#include "vidc_type.h"
-
-#define VIDC_MAX_NUM_CLIENTS 4
-#define MAX_VIDEO_NUM_OF_BUFF 100
-
-enum buffer_dir {
-	BUFFER_TYPE_INPUT,
-	BUFFER_TYPE_OUTPUT
-};
-
-struct buf_addr_table {
-	unsigned long user_vaddr;
-	unsigned long kernel_vaddr;
-	unsigned long phy_addr;
-	int pmem_fd;
-	struct file *file;
-};
-
-struct video_client_ctx {
-	void *vcd_handle;
-	u32 num_of_input_buffers;
-	u32 num_of_output_buffers;
-	struct buf_addr_table input_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF];
-	struct buf_addr_table output_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF];
-	struct list_head msg_queue;
-	struct mutex msg_queue_lock;
-	wait_queue_head_t msg_wait;
-	struct completion event;
-	u32 event_status;
-	u32 seq_header_set;
-	u32 stop_msg;
-	u32 stop_called;
-	u32 stop_sync_cb;
-};
-
-void __iomem *vidc_get_ioaddr(void);
-int vidc_load_firmware(void);
-void vidc_release_firmware(void);
-u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
-	enum buffer_dir buffer, u32 search_with_user_vaddr,
-	unsigned long *user_vaddr, unsigned long *kernel_vaddr,
-	unsigned long *phy_addr, int *pmem_fd, struct file **file,
-	s32 *buffer_index);
-u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
-	enum buffer_dir buffer, unsigned long user_vaddr,
-	unsigned long *kernel_vaddr, int pmem_fd,
-	unsigned long buffer_addr_offset,
-	unsigned int max_num_buffers);
-u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
-	enum buffer_dir buffer, unsigned long user_vaddr,
-	unsigned long *kernel_vaddr);
-
-u32 vidc_timer_create(void (*timer_handler)(void *),
-	void *user_data, void **timer_handle);
-void  vidc_timer_release(void *timer_handle);
-void  vidc_timer_start(void *timer_handle, u32 time_out);
-void  vidc_timer_stop(void *timer_handle);
-
-
-#endif
diff --git a/drivers/video/msm/vidc/common/init/vidc_init_internal.h b/drivers/video/msm/vidc/common/init/vidc_init_internal.h
index 9d26d92..1d903ad 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init_internal.h
+++ b/drivers/video/msm/vidc/common/init/vidc_init_internal.h
@@ -1,29 +1,13 @@
 /* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
diff --git a/drivers/video/msm/vidc/common/vcd/vcd.h b/drivers/video/msm/vidc/common/vcd/vcd.h
index a1206e5..e557dab 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd.h
@@ -1,38 +1,22 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_H_
 #define _VCD_H_
 
-#include "vcd_api.h"
+#include <media/msm/vcd_api.h>
+#include "vcd_util.h"
 #include "vcd_ddl_api.h"
 #include "vcd_res_tracker_api.h"
-#include "vcd_util.h"
 #include "vcd_client_sm.h"
 #include "vcd_core.h"
 #include "vcd_device_sm.h"
@@ -406,4 +390,9 @@
 void vcd_handle_ind_info_output_reconfig
 	(struct vcd_clnt_ctxt *cctxt, u32 status);
 
+u32 vcd_req_perf_level(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_property_perf_level *);
+
+u32 vcd_set_num_slices(struct vcd_clnt_ctxt *cctxt);
+
 #endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c
index ac9459c..172107e 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd.h"
 
 u32 vcd_init(struct vcd_init_config *config, s32 *driver_handle)
@@ -79,22 +74,105 @@
 }
 EXPORT_SYMBOL(vcd_term);
 
+struct client_security_info {
+	int secure_enc;
+	int secure_dec;
+	int non_secure_enc;
+	int non_secure_dec;
+};
+
+static int vcd_get_clients_security_info(struct client_security_info *sec_info)
+{
+	struct vcd_drv_ctxt *drv_ctxt;
+	struct vcd_clnt_ctxt *cctxt;
+	int count = 0;
+	if (!sec_info) {
+		VCD_MSG_ERROR("Invalid argument\n");
+		return -EINVAL;
+	}
+	memset(sec_info, 0 , sizeof(*sec_info));
+	drv_ctxt = vcd_get_drv_context();
+	mutex_lock(&drv_ctxt->dev_mutex);
+	cctxt = drv_ctxt->dev_ctxt.cctxt_list_head;
+	while (cctxt) {
+		if (cctxt->secure && cctxt->decoding)
+			sec_info->secure_dec++;
+		else if (cctxt->secure && !cctxt->decoding)
+			sec_info->secure_enc++;
+		else if (!cctxt->secure && cctxt->decoding)
+			sec_info->non_secure_dec++;
+		else
+			sec_info->non_secure_enc++;
+		count++;
+		cctxt = cctxt->next;
+	}
+	mutex_unlock(&drv_ctxt->dev_mutex);
+	return count;
+}
+
+static int is_session_invalid(u32 decoding, u32 flags) {
+	int is_secure;
+	struct client_security_info sec_info;
+	int client_count = 0;
+	int secure_session_running = 0;
+	is_secure = (flags & VCD_CP_SESSION) ? 1:0;
+	client_count = vcd_get_clients_security_info(&sec_info);
+	secure_session_running = (sec_info.secure_enc > 0) ||
+			(sec_info.secure_dec > 0);
+	if (!decoding && is_secure) {
+		if ((sec_info.secure_dec == 1))
+			VCD_MSG_LOW("SE-SD: SUCCESS\n");
+		else {
+			VCD_MSG_LOW("SE is permitted only with SD: FAILURE\n");
+			return -EACCES;
+		}
+	} else if (!decoding && !is_secure) {
+		if (secure_session_running) {
+			VCD_MSG_LOW("SD-NSE: FAILURE\n");
+			VCD_MSG_LOW("SE-NSE: FAILURE\n");
+			return -EACCES;
+		}
+	} else if (decoding && is_secure) {
+		if (client_count > 0) {
+			VCD_MSG_LOW("S/NS-SD: FAILURE\n");
+			if (sec_info.secure_enc > 0 ||
+				sec_info.non_secure_enc > 0) {
+				return -EAGAIN;
+			}
+			return -EACCES;
+		}
+	} else {
+		if (sec_info.secure_dec > 0) {
+			VCD_MSG_LOW("SD-NSD: FAILURE\n");
+			return -EACCES;
+		}
+	}
+	return 0;
+}
+
 u32 vcd_open(s32 driver_handle, u32 decoding,
 	void (*callback) (u32 event, u32 status, void *info, size_t sz,
 		       void *handle, void *const client_data),
-	void *client_data)
+	void *client_data, int flags)
 {
-	u32 rc = VCD_S_SUCCESS;
+	u32 rc = 0;
 	struct vcd_drv_ctxt *drv_ctxt;
-
+	struct vcd_clnt_ctxt *cctxt;
+	int is_secure = (flags & VCD_CP_SESSION) ? 1:0;
 	VCD_MSG_MED("vcd_open:");
 
 	if (!callback) {
 		VCD_MSG_ERROR("Bad parameters");
-
-		return VCD_ERR_ILLEGAL_PARM;
+		return -EINVAL;
 	}
-
+	rc = is_session_invalid(decoding, flags);
+	if (rc) {
+		VCD_MSG_ERROR("Invalid Session: is_decoder: %d, secure: %d\n",
+				decoding, flags);
+		return rc;
+	}
+	if (is_secure)
+		res_trk_secure_set();
 	drv_ctxt = vcd_get_drv_context();
 	mutex_lock(&drv_ctxt->dev_mutex);
 
@@ -102,17 +180,22 @@
 		rc = drv_ctxt->dev_state.state_table->ev_hdlr.
 		    open(drv_ctxt, driver_handle, decoding, callback,
 			    client_data);
+		if (rc) {
+			rc = -ENODEV;
+		}
 	} else {
 		VCD_MSG_ERROR("Unsupported API in device state %d",
 			      drv_ctxt->dev_state.state);
-
-		rc = VCD_ERR_BAD_STATE;
+		rc = -EPERM;
 	}
+	if (!rc) {
+		cctxt = drv_ctxt->dev_ctxt.cctxt_list_head;
+		cctxt->secure = is_secure;
+	} else if (is_secure)
+		res_trk_secure_unset();
 
 	mutex_unlock(&drv_ctxt->dev_mutex);
-
 	return rc;
-
 }
 EXPORT_SYMBOL(vcd_open);
 
@@ -122,7 +205,7 @@
 	    (struct vcd_clnt_ctxt *)handle;
 	struct vcd_drv_ctxt *drv_ctxt;
 	u32 rc;
-
+	int is_secure = 0;
 	VCD_MSG_MED("vcd_close:");
 
 	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
@@ -131,6 +214,7 @@
 		return VCD_ERR_BAD_HANDLE;
 	}
 
+	is_secure = cctxt->secure;
 	drv_ctxt = vcd_get_drv_context();
 	mutex_lock(&drv_ctxt->dev_mutex);
 	if (drv_ctxt->dev_state.state_table->ev_hdlr.close) {
@@ -143,6 +227,8 @@
 		rc = VCD_ERR_BAD_STATE;
 	}
 	mutex_unlock(&drv_ctxt->dev_mutex);
+	if (is_secure)
+		res_trk_secure_unset();
 	return rc;
 
 }
@@ -882,5 +968,18 @@
 EXPORT_SYMBOL(vcd_get_num_of_clients);
 
 
+u32 vcd_get_ion_status(void)
+{
+	return res_trk_get_enable_ion();
+}
+EXPORT_SYMBOL(vcd_get_ion_status);
+
+struct ion_client *vcd_get_ion_client(void)
+{
+	return res_trk_get_ion_client();
+}
+EXPORT_SYMBOL(vcd_get_ion_client);
+
+
 
 
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
index 97207d4..07c7347 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd.h"
 
 static const struct vcd_clnt_state_table *vcd_clnt_state_table[];
@@ -347,6 +342,7 @@
 static u32 vcd_flush_in_eos(struct vcd_clnt_ctxt *cctxt,
 	u32 mode)
 {
+	u32 rc = VCD_S_SUCCESS;
 	VCD_MSG_LOW("vcd_flush_in_eos:");
 
 	if (mode > VCD_FLUSH_ALL || !mode) {
@@ -356,10 +352,18 @@
 	}
 
 	VCD_MSG_MED("Flush mode requested %d", mode);
+	if (!(cctxt->status.frame_submitted) &&
+		(!cctxt->decoding)) {
+		rc = vcd_flush_buffers(cctxt, mode);
+		if (!VCD_FAILED(rc)) {
+			VCD_MSG_HIGH("All buffers are flushed");
+			cctxt->status.mask |= (mode & VCD_FLUSH_ALL);
+			vcd_send_flush_done(cctxt, VCD_S_SUCCESS);
+		}
+	} else
+		cctxt->status.mask |= (mode & VCD_FLUSH_ALL);
 
-	cctxt->status.mask |= (mode & VCD_FLUSH_ALL);
-
-	return VCD_S_SUCCESS;
+	return rc;
 }
 
 static u32 vcd_flush_in_invalid(struct vcd_clnt_ctxt *cctxt,
@@ -498,7 +502,12 @@
 	}
 
 	rc = ddl_set_property(cctxt->ddl_handle, prop_hdr, prop_val);
-	VCD_FAILED_RETURN(rc, "Failed: ddl_set_property");
+	if (rc) {
+		/* Some properties aren't known to ddl that we can handle */
+		if (prop_hdr->prop_id != VCD_I_VOP_TIMING_CONSTANT_DELTA)
+			VCD_FAILED_RETURN(rc, "Failed: ddl_set_property");
+	}
+
 	switch (prop_hdr->prop_id) {
 	case VCD_I_META_BUFFER_MODE:
 		{
@@ -539,6 +548,24 @@
 		  cctxt->bframe = iperiod->b_frames;
 		  break;
 	   }
+	case VCD_REQ_PERF_LEVEL:
+		rc = vcd_req_perf_level(cctxt,
+			(struct vcd_property_perf_level *)prop_val);
+		break;
+	case VCD_I_VOP_TIMING_CONSTANT_DELTA:
+	   {
+		   struct vcd_property_vop_timing_constant_delta *delta =
+			   (struct vcd_property_vop_timing_constant_delta *)
+			   prop_val;
+		   if (delta->constant_delta > 0) {
+			cctxt->time_frame_delta = delta->constant_delta;
+			rc = VCD_S_SUCCESS;
+		   } else {
+			VCD_MSG_ERROR("Frame delta must be positive");
+			rc = VCD_ERR_ILLEGAL_PARM;
+		   }
+		   break;
+	   }
 	default:
 		{
 			break;
@@ -551,6 +578,7 @@
     (struct vcd_clnt_ctxt *cctxt,
      struct vcd_property_hdr *prop_hdr, void *prop_val)
 {
+	int rc;
 	VCD_MSG_LOW("vcd_get_property_cmn in %d:", cctxt->clnt_state.state);
 	VCD_MSG_LOW("property Id = %d", prop_hdr->prop_id);
 	if (!prop_hdr->sz || !prop_hdr->prop_id) {
@@ -558,7 +586,24 @@
 
 		return VCD_ERR_ILLEGAL_PARM;
 	}
-	return ddl_get_property(cctxt->ddl_handle, prop_hdr, prop_val);
+	rc = ddl_get_property(cctxt->ddl_handle, prop_hdr, prop_val);
+	if (rc) {
+		/* Some properties aren't known to ddl that we can handle */
+		if (prop_hdr->prop_id != VCD_I_VOP_TIMING_CONSTANT_DELTA)
+			VCD_FAILED_RETURN(rc, "Failed: ddl_set_property");
+	}
+
+	switch (prop_hdr->prop_id) {
+	case VCD_I_VOP_TIMING_CONSTANT_DELTA:
+	{
+		struct vcd_property_vop_timing_constant_delta *delta =
+			(struct vcd_property_vop_timing_constant_delta *)
+			prop_val;
+		delta->constant_delta = cctxt->time_frame_delta;
+		rc = VCD_S_SUCCESS;
+	}
+	}
+	return rc;
 }
 
 static u32 vcd_set_buffer_requirements_cmn
@@ -709,10 +754,24 @@
 	struct vcd_buffer_entry *buf_entry;
 	u32 result = true;
 	u32 handled = true;
-
+	if (!cctxt || !buffer) {
+		VCD_MSG_ERROR("%s(): Inavlid params cctxt %p buffer %p",
+					__func__, cctxt, buffer);
+		return VCD_ERR_BAD_POINTER;
+	}
 	VCD_MSG_LOW("vcd_fill_output_buffer_cmn in %d:",
 		    cctxt->clnt_state.state);
-
+	if (cctxt->status.mask & VCD_IN_RECONFIG) {
+		buffer->time_stamp = 0;
+		buffer->data_len = 0;
+		VCD_MSG_LOW("In reconfig: Return output buffer");
+		cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE,
+			VCD_S_SUCCESS,
+			buffer,
+			sizeof(struct vcd_frame_data),
+			cctxt, cctxt->client_data);
+		return rc;
+	}
 	buf_entry = vcd_check_fill_output_buffer(cctxt, buffer);
 	if (!buf_entry)
 		return VCD_ERR_BAD_POINTER;
@@ -1558,18 +1617,14 @@
 		VCD_MSG_ERROR("Bad parameters. cctxt=%p, to_state=%d",
 			      cctxt, to_state);
 	}
- 
-	if (!cctxt)
-		return;
 
 	state_ctxt = &cctxt->clnt_state;
 
-	if (state_ctxt->state) {
-		if (state_ctxt->state == to_state) {
-			VCD_MSG_HIGH("Client already in requested to_state=%d",
-					to_state);
-			return;
-		}
+	if (state_ctxt->state == to_state) {
+		VCD_MSG_HIGH("Client already in requested to_state=%d",
+			     to_state);
+
+		return;
 	}
 
 	VCD_MSG_MED("vcd_do_client_state_transition: C%d -> C%d, for api %d",
@@ -1628,9 +1683,9 @@
 	 NULL,
 	 NULL,
 	 NULL,
+	 vcd_get_property_cmn,
 	 NULL,
-	 NULL,
-	 NULL,
+	 vcd_get_buffer_requirements_cmn,
 	 NULL,
 	 NULL,
 	 NULL,
@@ -1677,10 +1732,10 @@
 	 NULL,
 	 vcd_flush_in_flushing,
 	 NULL,
+	 vcd_set_property_cmn,
+	 vcd_get_property_cmn,
 	 NULL,
-	 NULL,
-	 NULL,
-	 NULL,
+	 vcd_get_buffer_requirements_cmn,
 	 NULL,
 	 NULL,
 	 NULL,
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
index 6520fb8..9f2d63d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
@@ -1,34 +1,18 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_CLIENT_SM_H_
 #define _VCD_CLIENT_SM_H_
-#include "vcd_api.h"
+#include <media/msm/vcd_api.h>
 #include "vcd_ddl_api.h"
 
 struct vcd_clnt_state_table;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h
index 47c517b..9014921 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_core.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h
@@ -1,35 +1,20 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_CORE_H_
 #define _VCD_CORE_H_
 
-#include "vcd_api.h"
+#include <linux/ion.h>
+#include <media/msm/vcd_api.h>
 #include "vcd_ddl_api.h"
 
 #include "vcd_util.h"
@@ -76,8 +61,8 @@
 };
 
 enum vcd_core_type {
-	VCD_CORE_1080P,
-	VCD_CORE_720P,
+    VCD_CORE_1080P,
+    VCD_CORE_720P
 };
 
 struct vcd_cmd_q_element {
@@ -172,7 +157,7 @@
 	u32 int_field_cnt;
 	s64 first_ts;
 	s64 prev_ts;
-	u32 time_elapsed;
+	u64 time_elapsed;
 	struct vcd_frame_data eos_trig_ip_frm;
 	struct ddl_frame_data_tag eos_prev_op_frm;
 	u32 eos_prev_op_frm_status;
@@ -200,11 +185,13 @@
 	u32 live;
 	u32 decoding;
 	u32 bframe;
+	u32 num_slices;
 
 	struct vcd_property_frame_rate frm_rate;
 	u32 frm_p_units;
 	u32 reqd_perf_lvl;
 	u32 time_resoln;
+	u32 time_frame_delta;
 
 	struct vcd_buffer_pool in_buf_pool;
 	struct vcd_buffer_pool out_buf_pool;
@@ -220,9 +207,12 @@
 	struct vcd_sequence_hdr seq_hdr;
 	u8 *seq_hdr_phy_addr;
 	struct vcd_clnt_status status;
-
+	struct ion_client *vcd_ion_client;
+	u32 vcd_enable_ion;
 	struct vcd_clnt_ctxt *next;
 	u32 meta_mode;
+	int secure;
+	int perf_set_by_client;
 };
 
 #define VCD_BUFFERPOOL_INUSE_DECREMENT(val) \
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
index 2faab76..d517028 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd.h"
 
 static const struct vcd_dev_state_table *vcd_dev_state_table[];
@@ -42,18 +37,14 @@
 		VCD_MSG_ERROR("Bad parameters. drv_ctxt=%p, to_state=%d",
 				  drv_ctxt, to_state);
 	}
- 
-	if (!drv_ctxt)
-		return;
 
 	state_ctxt = &drv_ctxt->dev_state;
 
-	if (state_ctxt->state) {
-		if (state_ctxt->state == to_state) {
-			VCD_MSG_HIGH("Device already in requested to_state=%d",
-					to_state);
-			return;
-		}
+	if (state_ctxt->state == to_state) {
+		VCD_MSG_HIGH("Device already in requested to_state=%d",
+				 to_state);
+
+		return;
 	}
 
 	VCD_MSG_MED("vcd_do_device_state_transition: D%d -> D%d, for api %d",
@@ -138,10 +129,16 @@
 		{
 			transc = (struct vcd_transc *)client_data;
 
-			if (!transc || !transc->in_use
-				|| !transc->cctxt) {
+			if (!transc || !transc->in_use || !transc->cctxt) {
 				VCD_MSG_ERROR("Invalid clientdata "
-							  "received from DDL ");
+					"received from DDL, transc = 0x%x\n",
+					(u32)transc);
+				if (transc) {
+					VCD_MSG_ERROR("transc->in_use = %u, "
+						"transc->cctxt = 0x%x\n",
+						transc->in_use,
+						(u32)transc->cctxt);
+				}
 			} else {
 				cctxt = transc->cctxt;
 
@@ -532,8 +529,8 @@
 		config->map_dev_base_addr
 		|| dev_ctxt->config.un_map_dev_base_addr !=
 		config->un_map_dev_base_addr) {
-		VCD_MSG_ERROR("Device config mismatch");
-		VCD_MSG_HIGH("VCD will be using config from 1st vcd_init");
+		VCD_MSG_HIGH("Device config mismatch. "
+			"VCD will be using config from 1st vcd_init");
 	}
 
 	*driver_handle = 0;
@@ -927,7 +924,6 @@
 			if (dev_ctxt->pwr_state == VCD_PWR_STATE_ON)
 				vcd_pause_all_sessions(dev_ctxt);
 			dev_ctxt->pwr_state = VCD_PWR_STATE_SLEEP;
-
 			break;
 		}
 
@@ -964,6 +960,9 @@
 	u32 rc = VCD_S_SUCCESS;
 	u32 client_inited = false;
 	u32 fail_all_open = false;
+	struct ddl_context *ddl_context;
+
+	ddl_context = ddl_get_context();
 
 	VCD_MSG_LOW("vcd_dev_cb_in_initing:");
 
@@ -1037,6 +1036,8 @@
 
 			tmp_client = client;
 			client = client->next;
+			if (tmp_client == dev_ctxt->cctxt_list_head)
+				fail_all_open = true;
 
 			vcd_destroy_client_context(tmp_client);
 		}
@@ -1045,6 +1046,10 @@
 	if (!client_inited || fail_all_open) {
 		VCD_MSG_ERROR("All client open requests failed");
 
+		DDL_IDLE(ddl_context);
+
+		vcd_handle_device_init_failed(drv_ctxt,
+			DEVICE_STATE_EVENT_NUMBER(close));
 		dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM;
 	} else {
 		if (vcd_power_event(dev_ctxt, NULL,
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
index 787b462..2443c33 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
@@ -1,35 +1,19 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DEVICE_SM_H_
 #define _VCD_DEVICE_SM_H_
 
-#include "vcd_api.h"
+#include <media/msm/vcd_api.h>
 #include "vcd_ddl_api.h"
 #include "vcd_core.h"
 
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
index 202e3f7..01bd931 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd_power_sm.h"
 #include "vcd_core.h"
 #include "vcd.h"
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
index 26558ca..26ce019 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
@@ -1,29 +1,13 @@
 /* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_POWERSM_H_
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
index 2ef953d..ab21bac 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,14 +9,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd.h"
 
 #define NORMALIZATION_FACTOR 3600
@@ -107,9 +102,10 @@
 				VCD_FAILED_RETURN(rc,
 					"Failed: Get VCD_I_FRAME_RATE");
 			}
-			cctxt->reqd_perf_lvl = cctxt->frm_p_units *
-				cctxt->frm_rate.fps_numerator /
-				cctxt->frm_rate.fps_denominator;
+			if (!cctxt->perf_set_by_client)
+				cctxt->reqd_perf_lvl = cctxt->frm_p_units *
+					cctxt->frm_rate.fps_numerator /
+					cctxt->frm_rate.fps_denominator;
 
 			cctxt->sched_clnt_hdl = sched_cctxt;
 			memset(sched_cctxt, 0,
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 67af827..759989d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -9,54 +9,218 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
-
+#include <linux/memory_alloc.h>
+#include <mach/msm_subsystem_map.h>
 #include <asm/div64.h>
-
-#include "vidc_type.h"
+#include <media/msm/vidc_type.h>
 #include "vcd.h"
 #include "vdec_internal.h"
 
 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
+#define MAP_TABLE_SZ 64
+#define VCD_ENC_MAX_OUTBFRS_PER_FRAME 8
 
-static int vcd_pmem_alloc(size_t sz, u8 **kernel_vaddr, u8 **phy_addr)
+struct vcd_msm_map_buffer {
+	phys_addr_t phy_addr;
+	struct msm_mapped_buffer *mapped_buffer;
+	struct ion_handle *alloc_handle;
+	u32 in_use;
+};
+static struct vcd_msm_map_buffer msm_mapped_buffer_table[MAP_TABLE_SZ];
+static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO};
+
+static int vcd_pmem_alloc(size_t sz, u8 **kernel_vaddr, u8 **phy_addr,
+			 struct vcd_clnt_ctxt *cctxt)
 {
-	*phy_addr =
-	    (u8 *) pmem_kalloc(sz, PMEM_MEMTYPE | PMEM_ALIGNMENT_4K);
+	u32 memtype, i = 0, flags = 0;
+	struct vcd_msm_map_buffer *map_buffer = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	unsigned long iova = 0;
+	unsigned long buffer_size = 0;
+	int ret = 0;
+	unsigned long ionflag = 0;
+	ion_phys_addr_t phyaddr = 0;
+	size_t len = 0;
 
-	if (!IS_ERR((void *)*phy_addr)) {
-
-		*kernel_vaddr = ioremap((unsigned long)*phy_addr, sz);
-
-		if (!*kernel_vaddr) {
-			pr_err("%s: could not ioremap in kernel pmem buffers\n",
-			       __func__);
-			pmem_kfree((s32) *phy_addr);
-			return -ENOMEM;
+	if (!kernel_vaddr || !phy_addr || !cctxt) {
+		pr_err("\n%s: Invalid parameters", __func__);
+		goto bailout;
+	}
+	*phy_addr = NULL;
+	*kernel_vaddr = NULL;
+	for (i = 0; i  < MAP_TABLE_SZ; i++) {
+		if (!msm_mapped_buffer_table[i].in_use) {
+			map_buffer = &msm_mapped_buffer_table[i];
+			map_buffer->in_use = 1;
+			break;
 		}
-		pr_debug("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
-			 (u32) *phy_addr, (u32) *kernel_vaddr);
-		return 0;
+	}
+	if (!map_buffer) {
+		pr_err("%s() map table is full", __func__);
+		goto bailout;
+	}
+	res_trk_set_mem_type(DDL_MM_MEM);
+	memtype = res_trk_get_mem_type();
+	if (!cctxt->vcd_enable_ion) {
+		map_buffer->phy_addr = (phys_addr_t)
+		allocate_contiguous_memory_nomap(sz, memtype, SZ_4K);
+		if (!map_buffer->phy_addr) {
+			pr_err("%s() acm alloc failed", __func__);
+			goto free_map_table;
+		}
+		flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
+		map_buffer->mapped_buffer =
+		msm_subsystem_map_buffer((unsigned long)map_buffer->phy_addr,
+		sz, flags, vidc_mmu_subsystem,
+		sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+		if (IS_ERR(map_buffer->mapped_buffer)) {
+			pr_err(" %s() buffer map failed", __func__);
+			goto free_acm_alloc;
+		}
+		mapped_buffer = map_buffer->mapped_buffer;
+		if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
+			pr_err("%s() map buffers failed", __func__);
+			goto free_map_buffers;
+		}
+		*phy_addr = (u8 *) mapped_buffer->iova[0];
+		*kernel_vaddr = (u8 *) mapped_buffer->vaddr;
+		VCD_MSG_LOW("vcd_pmem_alloc: phys(0x%x), virt(0x%x), "\
+			"sz(%u), flags(0x%x)", (u32)*phy_addr,
+			(u32)*kernel_vaddr, sz, (u32)flags);
 	} else {
-		pr_err("%s: could not allocte in kernel pmem buffers\n",
-		       __func__);
-		return -ENOMEM;
+		map_buffer->alloc_handle = ion_alloc(
+			    cctxt->vcd_ion_client, sz, SZ_4K,
+			    memtype);
+		if (!map_buffer->alloc_handle) {
+			pr_err("%s() ION alloc failed", __func__);
+			goto bailout;
+		}
+		if (ion_handle_get_flags(cctxt->vcd_ion_client,
+				map_buffer->alloc_handle,
+				&ionflag)) {
+			pr_err("%s() ION get flag failed", __func__);
+			goto bailout;
+		}
+		*kernel_vaddr = (u8 *) ion_map_kernel(
+				cctxt->vcd_ion_client,
+				map_buffer->alloc_handle,
+				ionflag);
+		if (!(*kernel_vaddr)) {
+			pr_err("%s() ION map failed", __func__);
+			goto ion_free_bailout;
+		}
+		if (res_trk_get_core_type() != (u32)VCD_CORE_720P) {
+			ret = ion_map_iommu(cctxt->vcd_ion_client,
+				map_buffer->alloc_handle,
+				VIDEO_DOMAIN,
+				VIDEO_MAIN_POOL,
+				SZ_4K,
+				0,
+				(unsigned long *)&iova,
+				(unsigned long *)&buffer_size,
+				UNCACHED, 0);
+			if (ret) {
+				pr_err("%s() ION iommu map failed", __func__);
+				goto ion_map_bailout;
+			}
+			map_buffer->phy_addr = iova;
+		} else {
+			ret = ion_phys(cctxt->vcd_ion_client,
+				map_buffer->alloc_handle,
+				&phyaddr,
+				&len);
+			if (ret) {
+				pr_err("%s() ion_phys failed", __func__);
+				goto ion_map_bailout;
+			}
+			map_buffer->phy_addr = phyaddr;
+		}
+		if (!map_buffer->phy_addr) {
+			pr_err("%s() acm alloc failed", __func__);
+			goto free_map_table;
+		}
+		*phy_addr = (u8 *)map_buffer->phy_addr;
+		mapped_buffer = NULL;
+		map_buffer->mapped_buffer = NULL;
+		VCD_MSG_LOW("vcd_ion_alloc: phys(0x%x), virt(0x%x), "\
+			"sz(%u), ionflags(0x%x)", (u32)*phy_addr,
+			(u32)*kernel_vaddr, sz, (u32)ionflag);
 	}
 
+	return 0;
+
+free_map_buffers:
+	if (map_buffer->mapped_buffer)
+		msm_subsystem_unmap_buffer(map_buffer->mapped_buffer);
+free_acm_alloc:
+	if (!cctxt->vcd_enable_ion) {
+		free_contiguous_memory_by_paddr(
+		(unsigned long)map_buffer->phy_addr);
+	}
+	return -ENOMEM;
+ion_map_bailout:
+	ion_unmap_kernel(cctxt->vcd_ion_client, map_buffer->alloc_handle);
+ion_free_bailout:
+	ion_free(cctxt->vcd_ion_client, map_buffer->alloc_handle);
+free_map_table:
+	map_buffer->in_use = 0;
+bailout:
+	return -ENOMEM;
 }
 
-static int vcd_pmem_free(u8 *kernel_vaddr, u8 *phy_addr)
+static int vcd_pmem_free(u8 *kernel_vaddr, u8 *phy_addr,
+			 struct vcd_clnt_ctxt *cctxt)
 {
-	iounmap((void *)kernel_vaddr);
-	pmem_kfree((s32) phy_addr);
+	u32 i = 0;
+	struct vcd_msm_map_buffer *map_buffer = NULL;
+
+	if (!kernel_vaddr || !phy_addr || !cctxt) {
+		pr_err("\n%s: Invalid parameters", __func__);
+		goto bailout;
+	}
+	for (i = 0; i  < MAP_TABLE_SZ; i++) {
+		if (msm_mapped_buffer_table[i].in_use &&
+			(msm_mapped_buffer_table[i]
+			.mapped_buffer->vaddr == kernel_vaddr)) {
+			map_buffer = &msm_mapped_buffer_table[i];
+			map_buffer->in_use = 0;
+			break;
+		}
+	}
+	if (!map_buffer) {
+		pr_err("%s() Entry not found", __func__);
+		goto bailout;
+	}
+	if (map_buffer->mapped_buffer)
+		msm_subsystem_unmap_buffer(map_buffer->mapped_buffer);
+	if (cctxt->vcd_enable_ion) {
+		VCD_MSG_LOW("vcd_ion_free: phys(0x%x), virt(0x%x)",
+			(u32)phy_addr, (u32)kernel_vaddr);
+		if (map_buffer->alloc_handle) {
+			ion_unmap_kernel(cctxt->vcd_ion_client,
+					map_buffer->alloc_handle);
+			if (res_trk_get_core_type() != (u32)VCD_CORE_720P)
+				ion_unmap_iommu(cctxt->vcd_ion_client,
+					map_buffer->alloc_handle,
+					VIDEO_DOMAIN,
+					VIDEO_MAIN_POOL);
+			ion_free(cctxt->vcd_ion_client,
+			map_buffer->alloc_handle);
+		}
+	} else {
+		VCD_MSG_LOW("vcd_pmem_free: phys(0x%x), virt(0x%x)",
+			(u32)phy_addr, (u32)kernel_vaddr);
+		free_contiguous_memory_by_paddr(
+			(unsigned long)map_buffer->phy_addr);
+	}
+bailout:
+	kernel_vaddr = NULL;
+	phy_addr = NULL;
 	return 0;
 }
 
+
 u8 *vcd_pmem_get_physical(struct video_client_ctx *client_ctx,
 			  unsigned long kernel_vaddr)
 {
@@ -83,6 +247,42 @@
 
 }
 
+u32 vcd_get_ion_flag(struct video_client_ctx *client_ctx,
+			  unsigned long kernel_vaddr,
+			struct ion_handle **buff_ion_handle)
+{
+	unsigned long phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	u32 ion_flag = 0;
+	struct ion_handle *buff_handle = NULL;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+					  false, &user_vaddr, &kernel_vaddr,
+					  &phy_addr, &pmem_fd, &file,
+					  &buffer_index)) {
+
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT,
+				pmem_fd, kernel_vaddr, buffer_index,
+				&buff_handle);
+		*buff_ion_handle = buff_handle;
+		return ion_flag;
+	} else if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+		false, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file,
+		&buffer_index)) {
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+				pmem_fd, kernel_vaddr, buffer_index,
+				&buff_handle);
+		*buff_ion_handle = buff_handle;
+		return ion_flag;
+	} else {
+		VCD_MSG_ERROR("Couldn't get ion flag");
+		return 0;
+	}
+
+}
+
 void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt)
 {
 	dev_ctxt->ddl_frame_ch_free = dev_ctxt->ddl_frame_ch_depth;
@@ -418,6 +618,8 @@
 {
 	struct vcd_buffer_entry *buf_entry;
 	u8 *physical;
+	u32 ion_flag = 0;
+	struct ion_handle *buff_handle = NULL;
 
 	buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer);
 	if (buf_entry) {
@@ -429,6 +631,9 @@
 	physical = (u8 *) vcd_pmem_get_physical(
 		cctxt->client_data, (unsigned long)buffer);
 
+	ion_flag = vcd_get_ion_flag(cctxt->client_data,
+				(unsigned long)buffer,
+				&buff_handle);
 	if (!physical) {
 		VCD_MSG_ERROR("Couldn't get physical address");
 		return VCD_ERR_BAD_POINTER;
@@ -443,7 +648,6 @@
 		VCD_MSG_ERROR("Can't allocate buffer pool is full");
 		return VCD_ERR_FAIL;
 	}
-
 	buf_entry->virtual = buffer;
 	buf_entry->physical = physical;
 	buf_entry->sz = buf_size;
@@ -452,6 +656,8 @@
 
 	buf_entry->frame.virtual = buf_entry->virtual;
 	buf_entry->frame.physical = buf_entry->physical;
+	buf_entry->frame.ion_flag = ion_flag;
+	buf_entry->frame.buff_ion_handle = buff_handle;
 
 	buf_pool->validated++;
 
@@ -481,7 +687,7 @@
 	buf_size += buf_req->align;
 
 	rc = vcd_pmem_alloc(buf_size, &buf_entry->alloc,
-				&buf_entry->physical);
+				&buf_entry->physical, cctxt);
 
 	if (rc < 0) {
 		VCD_MSG_ERROR("Buffer allocation failed");
@@ -563,7 +769,8 @@
 		return VCD_ERR_ILLEGAL_PARM;
 	}
 	if (buf_entry->in_use) {
-		VCD_MSG_ERROR("\n Buffer is in use and is not flushed");
+		VCD_MSG_ERROR("Buffer is in use and is not flushed: %p, %d\n",
+			buf_entry, buf_entry->in_use);
 		return VCD_ERR_ILLEGAL_OP;
 	}
 
@@ -571,7 +778,7 @@
 			buf_entry->virtual, buf_entry->allocated);
 
 	if (buf_entry->allocated) {
-		vcd_pmem_free(buf_entry->alloc, buf_entry->physical);
+		vcd_pmem_free(buf_entry->alloc, buf_entry->physical, cctxt);
 		buf_pool->allocated--;
 	}
 
@@ -598,7 +805,7 @@
 				buf_pool->entries[i].allocated) {
 				vcd_pmem_free(buf_pool->entries[i].alloc,
 						  buf_pool->entries[i].
-						  physical);
+						  physical, cctxt);
 			}
 		}
 
@@ -762,7 +969,6 @@
 		list_del(&entry->list);
 		pool->q_len--;
 	}
-
 	return entry;
 }
 
@@ -862,6 +1068,7 @@
 {
 	u32 rc = VCD_S_SUCCESS;
 	struct vcd_buffer_entry *buf_entry;
+	struct vcd_buffer_entry *orig_frame = NULL;
 
 	VCD_MSG_LOW("vcd_flush_buffers:");
 
@@ -885,9 +1092,19 @@
 							 vcd_frame_data),
 						cctxt,
 						cctxt->client_data);
+				orig_frame = vcd_find_buffer_pool_entry(
+						&cctxt->in_buf_pool,
+						buf_entry->virtual);
 				}
 
-			buf_entry->in_use = false;
+			if (orig_frame) {
+				orig_frame->in_use--;
+				if (orig_frame != buf_entry)
+					kfree(buf_entry);
+			} else {
+				buf_entry->in_use = false;
+				VCD_MSG_ERROR("Original frame not found in buffer pool\n");
+			}
 			VCD_BUFFERPOOL_INUSE_DECREMENT(
 				cctxt->in_buf_pool.in_use);
 			buf_entry = NULL;
@@ -925,6 +1142,14 @@
 	VCD_MSG_LOW("vcd_init_client_context:");
 	rc = ddl_open(&cctxt->ddl_handle, cctxt->decoding);
 	VCD_FAILED_RETURN(rc, "Failed: ddl_open");
+	cctxt->vcd_enable_ion = res_trk_get_enable_ion();
+	if (cctxt->vcd_enable_ion) {
+		cctxt->vcd_ion_client = res_trk_get_ion_client();
+		if (!cctxt->vcd_ion_client) {
+			VCD_MSG_LOW("vcd_init_ion_get_client_failed:");
+			return -EINVAL;
+		}
+	}
 	cctxt->ddl_hdl_valid = true;
 	cctxt->clnt_state.state = VCD_CLIENT_STATE_OPEN;
 	cctxt->clnt_state.state_table =
@@ -934,6 +1159,7 @@
 	cctxt->bframe = 0;
 	cctxt->cmd_q.pending_cmd = VCD_CMD_NONE;
 	cctxt->status.last_evt = VCD_EVT_RESP_BASE;
+	cctxt->num_slices = 1;
 	return rc;
 }
 
@@ -983,7 +1209,7 @@
 
 	if (cctxt->seq_hdr.sequence_header) {
 		vcd_pmem_free(cctxt->seq_hdr.sequence_header,
-				  cctxt->seq_hdr_phy_addr);
+				  cctxt->seq_hdr_phy_addr, cctxt);
 		cctxt->seq_hdr.sequence_header = NULL;
 	}
 
@@ -1001,7 +1227,7 @@
 	cctxt->signature = 0;
 	cctxt->clnt_state.state = VCD_CLIENT_STATE_NULL;
 	cctxt->clnt_state.state_table = NULL;
-
+	cctxt->vcd_ion_client = NULL;
 	kfree(cctxt);
 }
 
@@ -1105,6 +1331,7 @@
 		}
 
 	} else {
+		vcd_set_num_slices(transc->cctxt);
 		rc = ddl_encode_start(transc->cctxt->ddl_handle,
 					  (void *)transc);
 	}
@@ -1304,7 +1531,8 @@
 	u32 rc = VCD_S_SUCCESS;
 	u32 evcode = 0;
 	struct ddl_frame_data_tag ddl_ip_frm;
-	struct ddl_frame_data_tag ddl_op_frm;
+	struct ddl_frame_data_tag *ddl_op_frm;
+	u32 out_buf_cnt = 0;
 
 	VCD_MSG_LOW("vcd_submit_frame:");
 	cctxt = transc->cctxt;
@@ -1316,34 +1544,52 @@
 	transc->flags = ip_frm_entry->flags;
 	ip_frm_entry->ip_frm_tag = (u32) transc;
 	memset(&ddl_ip_frm, 0, sizeof(ddl_ip_frm));
-	memset(&ddl_op_frm, 0, sizeof(ddl_op_frm));
 	if (cctxt->decoding) {
 		evcode = CLIENT_STATE_EVENT_NUMBER(decode_frame);
 		ddl_ip_frm.vcd_frm = *ip_frm_entry;
 		rc = ddl_decode_frame(cctxt->ddl_handle, &ddl_ip_frm,
-							   (void *) transc);
+							(void *) transc);
 	} else {
-		op_buf_entry = vcd_buffer_pool_entry_de_q(
-			&cctxt->out_buf_pool);
-		if (!op_buf_entry) {
-			VCD_MSG_ERROR("Sched provided frame when no"
-				"op buffer was present");
-			rc = VCD_ERR_FAIL;
-		} else {
+		ddl_op_frm = (struct ddl_frame_data_tag *)
+			kmalloc((sizeof(struct ddl_frame_data_tag) *
+			VCD_ENC_MAX_OUTBFRS_PER_FRAME), GFP_KERNEL);
+		if (!ddl_op_frm) {
+			VCD_MSG_ERROR("Memory allocation failure");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+		memset(ddl_op_frm, 0, (sizeof(struct ddl_frame_data_tag) *
+			VCD_ENC_MAX_OUTBFRS_PER_FRAME));
+		for (out_buf_cnt = 0; out_buf_cnt < cctxt->num_slices ;
+				out_buf_cnt++) {
+			op_buf_entry = vcd_buffer_pool_entry_de_q(
+				&cctxt->out_buf_pool);
+			if (!op_buf_entry) {
+				VCD_MSG_ERROR("Sched provided frame when no"
+					"op buffer was present");
+				rc = VCD_ERR_FAIL;
+				break;
+			}
 			op_buf_entry->in_use = true;
 			cctxt->out_buf_pool.in_use++;
-			ddl_ip_frm.vcd_frm = *ip_frm_entry;
-			ddl_ip_frm.frm_delta =
-				vcd_calculate_frame_delta(cctxt,
-					ip_frm_entry);
-
-			ddl_op_frm.vcd_frm = op_buf_entry->frame;
-
-			evcode = CLIENT_STATE_EVENT_NUMBER(encode_frame);
-
-			rc = ddl_encode_frame(cctxt->ddl_handle,
-				&ddl_ip_frm, &ddl_op_frm, (void *) transc);
+			ddl_op_frm[out_buf_cnt].vcd_frm = op_buf_entry->frame;
+			VCD_MSG_LOW("%s : buffer_cnt = %d framebfr(virtual)"
+				" 0x%p", __func__, out_buf_cnt,
+				op_buf_entry->frame.virtual);
+			VCD_MSG_LOW("framebfr(physical) 0x%p bfrlength %d",
+				op_buf_entry->frame.physical,
+				op_buf_entry->frame.alloc_len);
 		}
+		ddl_ip_frm.vcd_frm = *ip_frm_entry;
+		ddl_ip_frm.frm_delta =
+			vcd_calculate_frame_delta(cctxt,
+				ip_frm_entry);
+		evcode = CLIENT_STATE_EVENT_NUMBER(encode_frame);
+
+		if (!VCD_FAILED(rc)) {
+			rc = ddl_encode_frame(cctxt->ddl_handle,
+				&ddl_ip_frm, &ddl_op_frm[0], (void *) transc);
+		}
+		kfree(ddl_op_frm);
 	}
 	ip_frm_entry->ip_frm_tag = transc->ip_frm_tag;
 	if (!VCD_FAILED(rc)) {
@@ -1678,17 +1924,21 @@
 	} else {
 		memset(&dev_ctxt->trans_tbl[i], 0,
 			   sizeof(struct vcd_transc));
-
 		dev_ctxt->trans_tbl[i].in_use = true;
-
+		VCD_MSG_LOW("%s: Get transc = 0x%x, in_use = %u\n",
+			__func__, (u32)(&dev_ctxt->trans_tbl[i]),
+			dev_ctxt->trans_tbl[i].in_use);
 		return &dev_ctxt->trans_tbl[i];
 	}
 }
 
 void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry)
 {
-	if (trans_entry)
+	if (trans_entry) {
 		trans_entry->in_use = false;
+		VCD_MSG_LOW("%s: Free transc = 0x%x, in_use = %u\n",
+			__func__, (u32)trans_entry, trans_entry->in_use);
+	}
 }
 
 u32 vcd_handle_input_done(
@@ -1700,6 +1950,7 @@
 		(struct ddl_frame_data_tag *) payload;
 	struct vcd_buffer_entry *orig_frame = NULL;
 	u32 rc;
+	VCD_MSG_LOW("%s\n", __func__);
 
 	if (!cctxt->status.frame_submitted &&
 		!cctxt->status.frame_delayed) {
@@ -1747,8 +1998,11 @@
 	transc->ip_buf_entry = NULL;
 	transc->input_done = true;
 
-	if (transc->input_done && transc->frame_done)
+	if (transc->input_done && transc->frame_done) {
+		VCD_MSG_LOW("%s Calling vcd_release_trans_tbl_entry\n",
+		__func__);
 		vcd_release_trans_tbl_entry(transc);
+	}
 
 	if (VCD_FAILED(status)) {
 		VCD_MSG_ERROR("INPUT_DONE returned err = 0x%x", status);
@@ -1787,6 +2041,7 @@
 		(struct ddl_frame_data_tag *) payload;
 	u32 rc = VCD_ERR_FAIL, codec_config = false;
 	u32 core_type = res_trk_get_core_type();
+	VCD_MSG_LOW("%s\n", __func__);
 	rc = vcd_validate_io_done_pyld(cctxt, payload, status);
 	if (rc == VCD_ERR_CLIENT_FATAL)
 		vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end);
@@ -1892,6 +2147,7 @@
 	struct ddl_frame_data_tag *frame =
 		(struct ddl_frame_data_tag *)payload;
 	u32 rc = VCD_S_SUCCESS;
+	VCD_MSG_LOW("%s\n", __func__);
 
 	if (!cctxt->status.frame_submitted &&
 		!cctxt->status.frame_delayed) {
@@ -1952,6 +2208,7 @@
 	struct vcd_transc *transc;
 	struct ddl_frame_data_tag *frame =
 		(struct ddl_frame_data_tag *)payload;
+	VCD_MSG_LOW("%s\n", __func__);
 
 	rc = vcd_validate_io_done_pyld(cctxt, payload, VCD_S_SUCCESS);
 	if (rc == VCD_ERR_CLIENT_FATAL)
@@ -1985,6 +2242,7 @@
 	struct vcd_transc *transc;
 	u32 rc;
 	s64 time_stamp;
+	VCD_MSG_LOW("%s\n", __func__);
 
 	rc = vcd_validate_io_done_pyld(cctxt, payload, status);
 	if (rc == VCD_ERR_CLIENT_FATAL)
@@ -2074,7 +2332,7 @@
 	struct ddl_frame_data_tag *frame =
 		(struct ddl_frame_data_tag *) payload;
 	u32 rc = VCD_S_SUCCESS;
-	VCD_MSG_LOW("vcd_handle_frame_done_in_eos:");
+	VCD_MSG_LOW("%s\n", __func__);
 	rc = vcd_validate_io_done_pyld(cctxt, payload, status);
 	if (rc == VCD_ERR_CLIENT_FATAL)
 		vcd_handle_clnt_fatal(cctxt, frame->frm_trans_end);
@@ -2155,6 +2413,7 @@
 	u32 rc, seqhdr_present = 0;
 	struct vcd_property_hdr prop_hdr;
 	struct vcd_sequence_hdr seq_hdr;
+	struct vcd_property_sps_pps_for_idr_enable idr_enable;
 	struct vcd_property_codec codec;
 	*handled = true;
 	prop_hdr.prop_id = DDL_I_SEQHDR_PRESENT;
@@ -2171,29 +2430,64 @@
 	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &codec);
 	if (!VCD_FAILED(rc)) {
 		if (codec.codec != VCD_CODEC_H263) {
-			prop_hdr.prop_id = VCD_I_SEQ_HEADER;
-			prop_hdr.sz = sizeof(struct vcd_sequence_hdr);
-			seq_hdr.sequence_header = frm_entry->virtual;
-			seq_hdr.sequence_header_len =
-				frm_entry->alloc_len;
-			rc = ddl_get_property(cctxt->ddl_handle,
-				&prop_hdr, &seq_hdr);
-			if (!VCD_FAILED(rc)) {
-				frm_entry->data_len =
-					seq_hdr.sequence_header_len;
-				frm_entry->time_stamp = 0;
-				frm_entry->flags |=
-					VCD_FRAME_FLAG_CODECCONFIG;
+			/*
+			 * The seq. header is stored in a seperate internal
+			 * buffer and is memcopied into the output buffer
+			 * that we provide.  In secure sessions, we aren't
+			 * allowed to touch these buffers.  In these cases
+			 * seq. headers are returned to client as part of
+			 * I-frames. So for secure session, just return
+			 * empty buffer.
+			 */
+			if (!cctxt->secure) {
+				prop_hdr.prop_id = VCD_I_SEQ_HEADER;
+				prop_hdr.sz = sizeof(struct vcd_sequence_hdr);
+				seq_hdr.sequence_header = frm_entry->virtual;
+				seq_hdr.sequence_header_len =
+					frm_entry->alloc_len;
+				rc = ddl_get_property(cctxt->ddl_handle,
+						&prop_hdr, &seq_hdr);
+				if (!VCD_FAILED(rc)) {
+					frm_entry->data_len =
+						seq_hdr.sequence_header_len;
+					frm_entry->time_stamp = 0;
+					frm_entry->flags |=
+						VCD_FRAME_FLAG_CODECCONFIG;
+				} else
+					VCD_MSG_ERROR("rc = 0x%x. Failed:"
+							"ddl_get_property: VCD_I_SEQ_HEADER",
+							rc);
+			} else {
+				/*
+				 * First check that the proper props are enabled
+				 * so  client can get the proper info eventually
+				 */
+				prop_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR;
+				prop_hdr.sz = sizeof(idr_enable);
+				rc = ddl_get_property(cctxt->ddl_handle,
+						&prop_hdr, &idr_enable);
+				if (!VCD_FAILED(rc)) {
+					if (!idr_enable.
+						sps_pps_for_idr_enable_flag) {
+						VCD_MSG_ERROR("SPS/PPS per IDR "
+							"needs to be enabled");
+						rc = VCD_ERR_BAD_STATE;
+					} else {
+						/* Send zero len frame */
+						frm_entry->data_len = 0;
+						frm_entry->time_stamp = 0;
+						frm_entry->flags = 0;
+					}
+				}
+
+			}
+
+			if (!VCD_FAILED(rc))
 				cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE,
-					VCD_S_SUCCESS, frm_entry,
-					sizeof(struct vcd_frame_data),
-					cctxt,
-					cctxt->client_data);
-			} else
-			VCD_MSG_ERROR(
-				"rc = 0x%x. Failed:\
-				ddl_get_property: VCD_I_SEQ_HEADER",
-				rc);
+						VCD_S_SUCCESS, frm_entry,
+						sizeof(struct vcd_frame_data),
+						cctxt,
+						cctxt->client_data);
 		} else
 			VCD_MSG_LOW("Codec Type is H.263\n");
 	} else
@@ -2666,7 +2960,7 @@
 		VCD_MSG_HIGH("Old seq hdr detected");
 
 		vcd_pmem_free(cctxt->seq_hdr.sequence_header,
-				  cctxt->seq_hdr_phy_addr);
+				  cctxt->seq_hdr_phy_addr, cctxt);
 		cctxt->seq_hdr.sequence_header = NULL;
 	}
 
@@ -2686,7 +2980,7 @@
 	ret = vcd_pmem_alloc(cctxt->seq_hdr.sequence_header_len + align +
 				 VCD_SEQ_HDR_PADDING_BYTES,
 				 &(cctxt->seq_hdr.sequence_header),
-				 &(cctxt->seq_hdr_phy_addr));
+				 &(cctxt->seq_hdr_phy_addr), cctxt);
 
 	if (ret < 0) {
 		VCD_MSG_ERROR("Seq hdr allocation failed");
@@ -2734,6 +3028,30 @@
 	return rc;
 }
 
+u32 vcd_req_perf_level(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_property_perf_level *perf_level)
+{
+	u32 rc;
+	u32 res_trk_perf_level;
+	if (!perf_level) {
+		VCD_MSG_ERROR("Invalid parameters\n");
+		return -EINVAL;
+	}
+	res_trk_perf_level = get_res_trk_perf_level(perf_level->level);
+	if (res_trk_perf_level < 0) {
+		rc = -ENOTSUPP;
+		goto perf_level_not_supp;
+	}
+	rc = vcd_set_perf_level(cctxt->dev_ctxt, res_trk_perf_level);
+	if (!rc) {
+		cctxt->reqd_perf_lvl = res_trk_perf_level;
+		cctxt->perf_set_by_client = 1;
+	}
+perf_level_not_supp:
+	return rc;
+}
+
 u32 vcd_set_frame_size(
 	struct vcd_clnt_ctxt *cctxt,
 	 struct vcd_property_frame_size *frm_size)
@@ -2742,7 +3060,12 @@
 	u32 rc;
 	u32 frm_p_units;
 	(void)frm_size;
-
+	if (res_trk_get_disable_fullhd() && frm_size &&
+		(frm_size->width * frm_size->height > 1280 * 720)) {
+		VCD_MSG_ERROR("Frame size = %dX%d greater than 1280X720 not"
+			"supported", frm_size->width, frm_size->height);
+		return VCD_ERR_FAIL;
+	}
 	prop_hdr.prop_id = DDL_I_FRAME_PROC_UNITS;
 	prop_hdr.sz = sizeof(frm_p_units);
 	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &frm_p_units);
@@ -2791,13 +3114,15 @@
 	u32 frm_delta;
 	u64 temp, max = ~((u64)0);
 
-	if (frame->time_stamp >= cctxt->status.prev_ts)
+	if (cctxt->time_frame_delta)
+		temp = cctxt->time_frame_delta;
+	else if (frame->time_stamp >= cctxt->status.prev_ts)
 		temp = frame->time_stamp - cctxt->status.prev_ts;
 	else
 		temp = (max - cctxt->status.prev_ts) +
 			frame->time_stamp;
 
-	VCD_MSG_LOW("Curr_ts=%lld  Prev_ts=%lld Diff=%llu",
+	VCD_MSG_LOW("Curr_ts=%lld  Prev_ts=%lld Diff=%llu\n",
 			frame->time_stamp, cctxt->status.prev_ts, temp);
 
 	temp *= cctxt->time_resoln;
@@ -3109,3 +3434,23 @@
 		 0, cctxt, cctxt->client_data);
 	}
 }
+
+u32 vcd_set_num_slices(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_property_hdr prop_hdr;
+	struct vcd_property_slice_delivery_info slice_delivery_info;
+	u32 rc = VCD_S_SUCCESS;
+	prop_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE;
+	prop_hdr.sz = sizeof(struct vcd_property_slice_delivery_info);
+	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr,
+				&slice_delivery_info);
+	VCD_FAILED_RETURN(rc, "Failed: Get VCD_I_SLICE_DELIVERY_MODE");
+	if (slice_delivery_info.enable) {
+		cctxt->num_slices = slice_delivery_info.num_slices;
+		VCD_MSG_LOW("%s slice delivery mode num_slices = %u\n",
+					__func__, cctxt->num_slices);
+	} else {
+		cctxt->num_slices = 1;
+	}
+	return rc;
+}
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.c b/drivers/video/msm/vidc/common/vcd/vcd_util.c
index b638359..ba991f1 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_util.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_util.c
@@ -9,11 +9,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
  */
 
 #include "vidc_type.h"
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.h b/drivers/video/msm/vidc/common/vcd/vcd_util.h
index 631f18c..7164029 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_util.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_util.h
@@ -1,35 +1,19 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_UTIL_H_
 #define _VCD_UTIL_H_
-#include "vidc_type.h"
-#include "vcd_api.h"
+#include <media/msm/vidc_type.h>
+#include <media/msm/vcd_api.h>
 
 #if DEBUG
 
diff --git a/drivers/video/msm/vidc/common/vcd/vidc_type.h b/drivers/video/msm/vidc/common/vcd/vidc_type.h
deleted file mode 100644
index c3c1b95..0000000
--- a/drivers/video/msm/vidc/common/vcd/vidc_type.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-#ifndef VIDC_TYPE_H
-#define VIDC_TYPE_H
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/list.h>
-#include <linux/time.h>
-#include <linux/dma-mapping.h>
-#include <linux/android_pmem.h>
-
-#define DEBUG   0
-#define VIDC_ENABLE_DBGFS
-
-#define USE_RES_TRACKER
-
-#ifdef CONFIG_KERNEL_PMEM_SMI_REGION
-#define PMEM_MEMTYPE   PMEM_MEMTYPE_SMI
-#else
-#define PMEM_MEMTYPE   PMEM_MEMTYPE_EBI1
-#endif
-
-#endif
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1d37f42..b9d46fa 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -11,6 +11,8 @@
 #ifndef __LINUX_CLK_H
 #define __LINUX_CLK_H
 
+#include <linux/kernel.h>
+
 struct device;
 
 /*
@@ -41,11 +43,31 @@
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_prepare - prepare a clock source
+ * @clk: clock source
+ *
+ * This prepares the clock source for use.
+ *
+ * Must not be called from within atomic context.
+ */
+#ifdef CONFIG_HAVE_CLK_PREPARE
+int clk_prepare(struct clk *clk);
+#else
+static inline int clk_prepare(struct clk *clk)
+{
+	might_sleep();
+	return 0;
+}
+#endif
+
+/**
  * clk_enable - inform the system when the clock source should be running.
  * @clk: clock source
  *
  * If the clock can not be enabled/disabled, this should return success.
  *
+ * May be called from atomic contexts.
+ *
  * Returns success (0) or negative errno.
  */
 int clk_enable(struct clk *clk);
@@ -57,6 +79,8 @@
  * Inform the system that a clock source is no longer required by
  * a driver and may be shut down.
  *
+ * May be called from atomic contexts.
+ *
  * Implementation detail: if the clock source is shared between
  * multiple drivers, clk_enable() calls must be balanced by the
  * same number of clk_disable() calls for the clock source to be
@@ -64,6 +88,47 @@
  */
 void clk_disable(struct clk *clk);
 
+
+/**
+ * clk_unprepare - undo preparation of a clock source
+ * @clk: clock source
+ *
+ * This undoes a previously prepared clock.  The caller must balance
+ * the number of prepare and unprepare calls.
+ *
+ * Must not be called from within atomic context.
+ */
+#ifdef CONFIG_HAVE_CLK_PREPARE
+void clk_unprepare(struct clk *clk);
+#else
+static inline void clk_unprepare(struct clk *clk)
+{
+	might_sleep();
+}
+#endif
+
+/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
+static inline int clk_prepare_enable(struct clk *clk)
+{
+	int ret;
+
+	ret = clk_prepare(clk);
+	if (ret)
+		return ret;
+	ret = clk_enable(clk);
+	if (ret)
+		clk_unprepare(clk);
+
+	return ret;
+}
+
+/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */
+static inline void clk_disable_unprepare(struct clk *clk)
+{
+	clk_disable(clk);
+	clk_unprepare(clk);
+}
+
 /**
  * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
  *		  This is only valid once the clock source has been enabled.
diff --git a/include/linux/ion.h b/include/linux/ion.h
index a2dbbd4..d9443ff 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -2,6 +2,7 @@
  * include/linux/ion.h
  *
  * Copyright (C) 2011 Google, Inc.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -29,12 +30,18 @@
  * @ION_HEAP_TYPE_CARVEOUT:	 memory allocated from a prereserved
  * 				 carveout heap, allocations are physically
  * 				 contiguous
- * @ION_HEAP_END:		 helper for iterating over heaps
+ * @ION_HEAP_TYPE_IOMMU: IOMMU memory
+ * @ION_HEAP_TYPE_CP:	 memory allocated from a prereserved
+ *				carveout heap, allocations are physically
+ *				contiguous. Used for content protection.
+ * @ION_HEAP_END:		helper for iterating over heaps
  */
 enum ion_heap_type {
 	ION_HEAP_TYPE_SYSTEM,
 	ION_HEAP_TYPE_SYSTEM_CONTIG,
 	ION_HEAP_TYPE_CARVEOUT,
+	ION_HEAP_TYPE_IOMMU,
+	ION_HEAP_TYPE_CP,
 	ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always
 				 are at the end of this enum */
 	ION_NUM_HEAPS,
@@ -43,6 +50,7 @@
 #define ION_HEAP_SYSTEM_MASK		(1 << ION_HEAP_TYPE_SYSTEM)
 #define ION_HEAP_SYSTEM_CONTIG_MASK	(1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
 #define ION_HEAP_CARVEOUT_MASK		(1 << ION_HEAP_TYPE_CARVEOUT)
+#define ION_HEAP_CP_MASK		(1 << ION_HEAP_TYPE_CP)
 
 
 /**
@@ -50,24 +58,56 @@
  * The ids listed are the order in which allocation will be attempted
  * if specified. Don't swap the order of heap ids unless you know what
  * you are doing!
+ * Id's are spaced by purpose to allow new Id's to be inserted in-between (for
+ * possible fallbacks)
  */
 
 enum ion_heap_ids {
-	ION_HEAP_SYSTEM_ID,
-	ION_HEAP_SYSTEM_CONTIG_ID,
-	ION_HEAP_EBI_ID,
-	ION_HEAP_SMI_ID,
-	ION_HEAP_ADSP_ID,
-	ION_HEAP_AUDIO_ID,
-	ION_HEAP_ADSP2_ID,
+	INVALID_HEAP_ID = -1,
+	ION_CP_MM_HEAP_ID = 8,
+	ION_CP_MFC_HEAP_ID = 12,
+	ION_CP_WB_HEAP_ID = 16, /* 8660 only */
+	ION_CAMERA_HEAP_ID = 20, /* 8660 only */
+	ION_SF_HEAP_ID = 24,
+	ION_IOMMU_HEAP_ID = 25,
+	ION_QSECOM_HEAP_ID = 27,
+	ION_AUDIO_HEAP_ID = 28,
+
+	ION_MM_FIRMWARE_HEAP_ID = 29,
+	ION_SYSTEM_HEAP_ID = 30,
+
+	ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_SECURE flag */
 };
 
-#define ION_KMALLOC_HEAP_NAME	"kmalloc"
+enum ion_fixed_position {
+	NOT_FIXED,
+	FIXED_LOW,
+	FIXED_MIDDLE,
+	FIXED_HIGH,
+};
+
+/**
+ * Flag to use when allocating to indicate that a heap is secure.
+ */
+#define ION_SECURE (1 << ION_HEAP_ID_RESERVED)
+
+/**
+ * Macro should be used with ion_heap_ids defined above.
+ */
+#define ION_HEAP(bit) (1 << (bit))
+
 #define ION_VMALLOC_HEAP_NAME	"vmalloc"
-#define ION_EBI1_HEAP_NAME	"EBI1"
-#define ION_ADSP_HEAP_NAME	"adsp"
-#define ION_ADSP2_HEAP_NAME	"adsp2"
-#define ION_SMI_HEAP_NAME	"smi"
+#define ION_AUDIO_HEAP_NAME	"audio"
+#define ION_SF_HEAP_NAME	"sf"
+#define ION_MM_HEAP_NAME	"mm"
+#define ION_CAMERA_HEAP_NAME	"camera_preview"
+#define ION_IOMMU_HEAP_NAME	"iommu"
+#define ION_MFC_HEAP_NAME	"mfc"
+#define ION_WB_HEAP_NAME	"wb"
+#define ION_MM_FIRMWARE_HEAP_NAME	"mm_fw"
+#define ION_QSECOM_HEAP_NAME	"qsecom"
+#define ION_FMEM_HEAP_NAME	"fmem"
+
 #define CACHED          1
 #define UNCACHED        0
 
@@ -77,6 +117,12 @@
 
 #define ION_IS_CACHED(__flags)	((__flags) & (1 << ION_CACHE_SHIFT))
 
+/*
+ * This flag allows clients when mapping into the IOMMU to specify to
+ * defer un-mapping from the IOMMU until the buffer memory is freed.
+ */
+#define ION_IOMMU_UNMAP_DELAYED 1
+
 #ifdef __KERNEL__
 #include <linux/err.h>
 #include <mach/ion.h>
@@ -91,17 +137,19 @@
    be converted to phys_addr_t.  For the time being many kernel interfaces
    do not accept phys_addr_t's that would have to */
 #define ion_phys_addr_t unsigned long
+#define ion_virt_addr_t unsigned long
 
 /**
  * struct ion_platform_heap - defines a heap in the given platform
  * @type:	type of the heap from ion_heap_type enum
- * @id:		unique identifier for heap.  When allocating (lower numbers 
+ * @id:		unique identifier for heap.  When allocating (lower numbers
  * 		will be allocated from first)
  * @name:	used for debug purposes
  * @base:	base address of heap in physical memory if applicable
  * @size:	size of the heap in bytes if applicable
- *
- * Provided by the board file.
+ * @memory_type:Memory type used for the heap
+ * @has_outer_cache:    set to 1 if outer cache is used, 0 otherwise.
+ * @extra_data:	Extra data specific to each heap type
  */
 struct ion_platform_heap {
 	enum ion_heap_type type;
@@ -110,10 +158,79 @@
 	ion_phys_addr_t base;
 	size_t size;
 	enum ion_memory_types memory_type;
+	unsigned int has_outer_cache;
+	void *extra_data;
+};
+
+/**
+ * struct ion_cp_heap_pdata - defines a content protection heap in the given
+ * platform
+ * @permission_type:	Memory ID used to identify the memory to TZ
+ * @align:		Alignment requirement for the memory
+ * @secure_base:	Base address for securing the heap.
+ *			Note: This might be different from actual base address
+ *			of this heap in the case of a shared heap.
+ * @secure_size:	Memory size for securing the heap.
+ *			Note: This might be different from actual size
+ *			of this heap in the case of a shared heap.
+ * @reusable		Flag indicating whether this heap is reusable of not.
+ *			(see FMEM)
+ * @mem_is_fmem		Flag indicating whether this memory is coming from fmem
+ *			or not.
+ * @fixed_position	If nonzero, position in the fixed area.
+ * @virt_addr:		Virtual address used when using fmem.
+ * @iommu_map_all:	Indicates whether we should map whole heap into IOMMU.
+ * @iommu_2x_map_domain: Indicates the domain to use for overmapping.
+ * @request_region:	function to be called when the number of allocations
+ *			goes from 0 -> 1
+ * @release_region:	function to be called when the number of allocations
+ *			goes from 1 -> 0
+ * @setup_region:	function to be called upon ion registration
+ *
+ */
+struct ion_cp_heap_pdata {
+	enum ion_permission_type permission_type;
+	unsigned int align;
+	ion_phys_addr_t secure_base; /* Base addr used when heap is shared */
+	size_t secure_size; /* Size used for securing heap when heap is shared*/
+	int reusable;
+	int mem_is_fmem;
+	enum ion_fixed_position fixed_position;
+	int iommu_map_all;
+	int iommu_2x_map_domain;
+	ion_virt_addr_t *virt_addr;
+	int (*request_region)(void *);
+	int (*release_region)(void *);
+	void *(*setup_region)(void);
+};
+
+/**
+ * struct ion_co_heap_pdata - defines a carveout heap in the given platform
+ * @adjacent_mem_id:	Id of heap that this heap must be adjacent to.
+ * @align:		Alignment requirement for the memory
+ * @mem_is_fmem		Flag indicating whether this memory is coming from fmem
+ *			or not.
+ * @fixed_position	If nonzero, position in the fixed area.
+ * @request_region:	function to be called when the number of allocations
+ *			goes from 0 -> 1
+ * @release_region:	function to be called when the number of allocations
+ *			goes from 1 -> 0
+ * @setup_region:	function to be called upon ion registration
+ *
+ */
+struct ion_co_heap_pdata {
+	int adjacent_mem_id;
+	unsigned int align;
+	int mem_is_fmem;
+	enum ion_fixed_position fixed_position;
+	int (*request_region)(void *);
+	int (*release_region)(void *);
+	void *(*setup_region)(void);
 };
 
 /**
  * struct ion_platform_data - array of platform heaps passed from board file
+ * @has_outer_cache:    set to 1 if outer cache is used, 0 otherwise.
  * @nr:    number of structures in the array
  * @request_region: function to be called when the number of allocations goes
  *						from 0 -> 1
@@ -125,9 +242,10 @@
  * Provided by the board file in the form of platform data to a platform device.
  */
 struct ion_platform_data {
+	unsigned int has_outer_cache;
 	int nr;
-	void (*request_region)(void *);
-	void (*release_region)(void *);
+	int (*request_region)(void *);
+	int (*release_region)(void *);
 	void *(*setup_region)(void);
 	struct ion_platform_heap heaps[];
 };
@@ -299,6 +417,125 @@
 int ion_handle_get_flags(struct ion_client *client, struct ion_handle *handle,
 				unsigned long *flags);
 
+
+/**
+ * ion_map_iommu - map the given handle into an iommu
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to map
+ * @domain_num - domain number to map to
+ * @partition_num - partition number to allocate iova from
+ * @align - alignment for the iova
+ * @iova_length - length of iova to map. If the iova length is
+ *		greater than the handle length, the remaining
+ *		address space will be mapped to a dummy buffer.
+ * @iova - pointer to store the iova address
+ * @buffer_size - pointer to store the size of the buffer
+ * @flags - flags for options to map
+ * @iommu_flags - flags specific to the iommu.
+ *
+ * Maps the handle into the iova space specified via domain number. Iova
+ * will be allocated from the partition specified via partition_num.
+ * Returns 0 on success, negative value on error.
+ */
+int ion_map_iommu(struct ion_client *client, struct ion_handle *handle,
+			int domain_num, int partition_num, unsigned long align,
+			unsigned long iova_length, unsigned long *iova,
+			unsigned long *buffer_size,
+			unsigned long flags, unsigned long iommu_flags);
+
+
+/**
+ * ion_handle_get_size - get the allocated size of a given handle
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to get the size
+ * @size - pointer to store the size
+ *
+ * gives the allocated size of a handle. returns 0 on success, negative
+ * value on error
+ *
+ * NOTE: This is intended to be used only to get a size to pass to map_iommu.
+ * You should *NOT* rely on this for any other usage.
+ */
+
+int ion_handle_get_size(struct ion_client *client, struct ion_handle *handle,
+			unsigned long *size);
+
+/**
+ * ion_unmap_iommu - unmap the handle from an iommu
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to unmap
+ * @domain_num - domain to unmap from
+ * @partition_num - partition to unmap from
+ *
+ * Decrement the reference count on the iommu mapping. If the count is
+ * 0, the mapping will be removed from the iommu.
+ */
+void ion_unmap_iommu(struct ion_client *client, struct ion_handle *handle,
+			int domain_num, int partition_num);
+
+
+/**
+ * ion_secure_heap - secure a heap
+ *
+ * @client - a client that has allocated from the heap heap_id
+ * @heap_id - heap id to secure.
+ *
+ * Secure a heap
+ * Returns 0 on success
+ */
+int ion_secure_heap(struct ion_device *dev, int heap_id);
+
+/**
+ * ion_unsecure_heap - un-secure a heap
+ *
+ * @client - a client that has allocated from the heap heap_id
+ * @heap_id - heap id to un-secure.
+ *
+ * Un-secure a heap
+ * Returns 0 on success
+ */
+int ion_unsecure_heap(struct ion_device *dev, int heap_id);
+
+/**
+ * msm_ion_secure_heap - secure a heap. Wrapper around ion_secure_heap.
+ *
+  * @heap_id - heap id to secure.
+ *
+ * Secure a heap
+ * Returns 0 on success
+ */
+int msm_ion_secure_heap(int heap_id);
+
+/**
+ * msm_ion_unsecure_heap - unsecure a heap. Wrapper around ion_unsecure_heap.
+ *
+  * @heap_id - heap id to secure.
+ *
+ * Un-secure a heap
+ * Returns 0 on success
+ */
+int msm_ion_unsecure_heap(int heap_id);
+
+/**
+ * msm_ion_do_cache_op - do cache operations.
+ *
+ * @client - pointer to ION client.
+ * @handle - pointer to buffer handle.
+ * @vaddr -  virtual address to operate on.
+ * @len - Length of data to do cache operation on.
+ * @cmd - Cache operation to perform:
+ *		ION_IOC_CLEAN_CACHES
+ *		ION_IOC_INV_CACHES
+ *		ION_IOC_CLEAN_INV_CACHES
+ *
+ * Returns 0 on success
+ */
+int msm_ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
+			void *vaddr, unsigned long len, unsigned int cmd);
+
 #else
 static inline struct ion_client *ion_client_create(struct ion_device *dev,
 				     unsigned int heap_mask, const char *name)
@@ -371,6 +608,54 @@
 {
 	return -ENODEV;
 }
+
+static inline int ion_map_iommu(struct ion_client *client,
+			struct ion_handle *handle, int domain_num,
+			int partition_num, unsigned long align,
+			unsigned long iova_length, unsigned long *iova,
+			unsigned long *buffer_size,
+			unsigned long flags,
+			unsigned long iommu_flags)
+{
+	return -ENODEV;
+}
+
+static inline void ion_unmap_iommu(struct ion_client *client,
+			struct ion_handle *handle, int domain_num,
+			int partition_num)
+{
+	return;
+}
+
+static inline int ion_secure_heap(struct ion_device *dev, int heap_id)
+{
+	return -ENODEV;
+
+}
+
+static inline int ion_unsecure_heap(struct ion_device *dev, int heap_id)
+{
+	return -ENODEV;
+}
+
+static inline int msm_ion_secure_heap(int heap_id)
+{
+	return -ENODEV;
+
+}
+
+static inline int msm_ion_unsecure_heap(int heap_id)
+{
+	return -ENODEV;
+}
+
+static inline int msm_ion_do_cache_op(struct ion_client *client,
+			struct ion_handle *handle, void *vaddr,
+			unsigned long len, unsigned int cmd)
+{
+	return -ENODEV;
+}
+
 #endif /* CONFIG_ION */
 #endif /* __KERNEL__ */
 
@@ -439,6 +724,7 @@
 /* struct ion_flush_data - data passed to ion for flushing caches
  *
  * @handle:	handle with data to flush
+ * @fd:		fd to flush
  * @vaddr:	userspace virtual address mapped with mmap
  * @offset:	offset into the handle to flush
  * @length:	length of handle to flush
@@ -449,6 +735,7 @@
  */
 struct ion_flush_data {
 	struct ion_handle *handle;
+	int fd;
 	void *vaddr;
 	unsigned int offset;
 	unsigned int length;
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 3ff2347..baef1cc 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -151,21 +151,14 @@
 #define KGSL_2D1_REG_MEMORY	"kgsl_2d1_reg_memory"
 #define KGSL_2D1_IRQ		"kgsl_2d1_irq"
 
-struct kgsl_grp_clk_name {
-	const char *clk;
-	const char *pclk;
-};
-
 struct kgsl_device_platform_data {
 	struct kgsl_pwrlevel pwrlevel[KGSL_MAX_PWRLEVELS];
 	int init_level;
 	int num_levels;
 	int (*set_grp_async)(void);
 	unsigned int idle_timeout;
-	bool strtstp_sleepwake;
 	unsigned int nap_allowed;
-	struct kgsl_grp_clk_name clk;
-	struct kgsl_grp_clk_name imem_clk_name;
+	unsigned int clk_map;
 	unsigned int idle_needed;
 	struct msm_bus_scale_pdata *bus_scale_table;
 	const char *iommu_user_ctx_name;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 219caa6..e051640 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -1,6 +1,7 @@
 /* include/linux/msm_mdp.h
  *
  * Copyright (C) 2007 Google Incorporated
+ * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -24,15 +25,18 @@
 #define MSMFB_RESUME_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 129, unsigned int)
 #define MSMFB_CURSOR _IOW(MSMFB_IOCTL_MAGIC, 130, struct fb_cursor)
 #define MSMFB_SET_LUT _IOW(MSMFB_IOCTL_MAGIC, 131, struct fb_cmap)
-#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram)
+#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram_data)
 /* new ioctls's for set/get ccs matrix */
 #define MSMFB_GET_CCS_MATRIX  _IOWR(MSMFB_IOCTL_MAGIC, 133, struct mdp_ccs)
 #define MSMFB_SET_CCS_MATRIX  _IOW(MSMFB_IOCTL_MAGIC, 134, struct mdp_ccs)
 #define MSMFB_OVERLAY_SET       _IOWR(MSMFB_IOCTL_MAGIC, 135, \
 						struct mdp_overlay)
 #define MSMFB_OVERLAY_UNSET     _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int)
+
 #define MSMFB_OVERLAY_PLAY      _IOW(MSMFB_IOCTL_MAGIC, 137, \
 						struct msmfb_overlay_data)
+#define MSMFB_OVERLAY_QUEUE	MSMFB_OVERLAY_PLAY
+
 #define MSMFB_GET_PAGE_PROTECTION _IOR(MSMFB_IOCTL_MAGIC, 138, \
 					struct mdp_page_protection)
 #define MSMFB_SET_PAGE_PROTECTION _IOW(MSMFB_IOCTL_MAGIC, 139, \
@@ -43,8 +47,9 @@
 #define MSMFB_OVERLAY_BLT       _IOWR(MSMFB_IOCTL_MAGIC, 142, \
 						struct msmfb_overlay_blt)
 #define MSMFB_OVERLAY_BLT_OFFSET     _IOW(MSMFB_IOCTL_MAGIC, 143, unsigned int)
-#define MSMFB_HISTOGRAM_START	_IO(MSMFB_IOCTL_MAGIC, 144)
-#define MSMFB_HISTOGRAM_STOP	_IO(MSMFB_IOCTL_MAGIC, 145)
+#define MSMFB_HISTOGRAM_START	_IOR(MSMFB_IOCTL_MAGIC, 144, \
+						struct mdp_histogram_start_req)
+#define MSMFB_HISTOGRAM_STOP	_IOR(MSMFB_IOCTL_MAGIC, 145, unsigned int)
 #define MSMFB_NOTIFY_UPDATE	_IOW(MSMFB_IOCTL_MAGIC, 146, unsigned int)
 
 #define MSMFB_OVERLAY_3D       _IOWR(MSMFB_IOCTL_MAGIC, 147, \
@@ -54,17 +59,9 @@
 						struct msmfb_mixer_info_req)
 #define MSMFB_OVERLAY_PLAY_WAIT _IOWR(MSMFB_IOCTL_MAGIC, 149, \
 						struct msmfb_overlay_data)
-
 #define MSMFB_WRITEBACK_INIT _IO(MSMFB_IOCTL_MAGIC, 150)
-
-/* The QCT latest code base is used, adding on 2/9/2012 */
 #define MSMFB_WRITEBACK_START _IO(MSMFB_IOCTL_MAGIC, 151)
 #define MSMFB_WRITEBACK_STOP _IO(MSMFB_IOCTL_MAGIC, 152)
-
-#define MSMFB_WRITEBACK_REGISTER_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 151, \
-						struct msmfb_writeback_data)
-#define MSMFB_WRITEBACK_UNREGISTER_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 152, \
-						struct msmfb_writeback_data)
 #define MSMFB_WRITEBACK_QUEUE_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 153, \
 						struct msmfb_data)
 #define MSMFB_WRITEBACK_DEQUEUE_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 154, \
@@ -72,29 +69,23 @@
 #define MSMFB_WRITEBACK_TERMINATE _IO(MSMFB_IOCTL_MAGIC, 155)
 #define MSMFB_MDP_PP _IOWR(MSMFB_IOCTL_MAGIC, 156, struct msmfb_mdp_pp)
 
-/* HTC: Define custom ioctl started from 200 */
-#define MSMFB_OVERLAY_CHANGE_ZORDER_VG_PIPES    _IOW(MSMFB_IOCTL_MAGIC, 200, unsigned int)
-#define MSMFB_GET_GAMMA_CURVY _IOWR(MSMFB_IOCTL_MAGIC, 201, struct gamma_curvy)
-
+#define MSMFB_OVERLAY_VSYNC_CTRL  _IOW(MSMFB_IOCTL_MAGIC, 160, unsigned int)
+#define MSMFB_VSYNC_CTRL  _IOW(MSMFB_IOCTL_MAGIC, 161, unsigned int)
 
 #define FB_TYPE_3D_PANEL 0x10101010
 #define MDP_IMGTYPE2_START 0x10000
 #define MSMFB_DRIVER_VERSION	0xF9E8D701
 
-#define MSMFB_GET_USB_PROJECTOR_INFO _IOR(MSMFB_IOCTL_MAGIC, 301, struct msmfb_usb_projector_info)
-#define MSMFB_SET_USB_PROJECTOR_INFO _IOW(MSMFB_IOCTL_MAGIC, 302, struct msmfb_usb_projector_info)
-
 enum {
 	NOTIFY_UPDATE_START,
 	NOTIFY_UPDATE_STOP,
-	NOTIFY_TERMINATE_BLOCKING,
-	NOTIFY_NUM,
 };
 
 enum {
 	MDP_RGB_565,      /* RGB 565 planer */
 	MDP_XRGB_8888,    /* RGB 888 padded */
 	MDP_Y_CBCR_H2V2,  /* Y and CbCr, pseudo planer w/ Cb is in MSB */
+	MDP_Y_CBCR_H2V2_ADRENO,
 	MDP_ARGB_8888,    /* ARGB 888 */
 	MDP_RGB_888,      /* RGB 888 planer */
 	MDP_Y_CRCB_H2V2,  /* Y and CrCb, pseudo planer w/ Cr is in MSB */
@@ -111,7 +102,10 @@
 	MDP_Y_CB_CR_H2V2,  /* Y, Cb and Cr, planar */
 	MDP_Y_CRCB_H1V1,  /* Y and CrCb, pseduo planer w/ Cr is in MSB */
 	MDP_Y_CBCR_H1V1,  /* Y and CbCr, pseduo planer w/ Cb is in MSB */
+	MDP_YCRCB_H1V1,   /* YCrCb interleave */
+	MDP_YCBCR_H1V1,   /* YCbCr interleave */
 	MDP_IMGTYPE_LIMIT,
+	MDP_RGB_BORDERFILL,	/* border fill pipe */
 	MDP_BGR_565 = MDP_IMGTYPE2_START,      /* BGR 565 planer */
 	MDP_FB_FORMAT,    /* framebuffer format */
 	MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */
@@ -155,8 +149,8 @@
 #define MDP_DEINTERLACE_ODD		0x00400000
 #define MDP_OV_PLAY_NOWAIT		0x00200000
 #define MDP_SOURCE_ROTATED_90		0x00100000
-#define MDP_MEMORY_ID_TYPE_FB		0x00001000
 #define MDP_DPP_HSIC			0x00080000
+#define MDP_BACKEND_COMPOSITION		0x00040000
 #define MDP_BORDERFILL_SUPPORTED	0x00010000
 #define MDP_SECURE_OVERLAY_SESSION      0x00008000
 #define MDP_MEMORY_ID_TYPE_FB		0x00001000
@@ -254,11 +248,9 @@
 struct msmfb_overlay_data {
 	uint32_t id;
 	struct msmfb_data data;
-#ifndef CONFIG_FB_MSM_OVERLAY_LEGACY
 	uint32_t version_key;
 	struct msmfb_data plane1_data;
 	struct msmfb_data plane2_data;
-#endif
 };
 
 struct msmfb_img {
@@ -295,9 +287,7 @@
 	uint32_t flags;
 	uint32_t id;
 	uint32_t user_data[8];
-#ifndef CONFIG_FB_MSM_OVERLAY_LEGACY
 	struct dpp_ctrl dpp;
-#endif
 };
 
 struct msmfb_overlay_3d {
@@ -345,9 +335,40 @@
 	MDP_BLOCK_DMA_P,
 	MDP_BLOCK_DMA_S,
 	MDP_BLOCK_DMA_E,
+	MDP_BLOCK_OVERLAY_2,
 	MDP_BLOCK_MAX,
 };
 
+/*
+mdp_histogram_start_req is used to provide the parameters for
+histogram start request
+*/
+
+struct mdp_histogram_start_req {
+	uint32_t block;
+	uint8_t frame_cnt;
+	uint8_t bit_mask;
+	uint8_t num_bins;
+};
+
+
+/*
+
+   mdp_histogram_data is used to return the histogram data, once
+   the histogram is done/stopped/cance
+
+ */
+
+
+struct mdp_histogram_data {
+	uint32_t block;
+	uint8_t bin_cnt;
+	uint32_t *c0;
+	uint32_t *c1;
+	uint32_t *c2;
+	uint32_t *extra_info;
+};
+
 struct mdp_pcc_coeff {
 	uint32_t c, r, g, b, rr, gg, bb, rg, gb, rb, rgb_0, rgb_1;
 };
@@ -358,6 +379,10 @@
 	struct mdp_pcc_coeff r, g, b;
 };
 
+#define MDP_CSC_FLAG_ENABLE	0x1
+#define MDP_CSC_FLAG_YUV_IN	0x2
+#define MDP_CSC_FLAG_YUV_OUT	0x4
+
 struct mdp_csc_cfg {
 	/* flags for enable CSC, toggling RGB,YUV input/output */
 	uint32_t flags;
@@ -413,7 +438,6 @@
 	uint32_t *data;
 };
 
-
 struct mdp_lut_cfg_data {
 	uint32_t lut_type;
 	union {
@@ -423,10 +447,16 @@
 	} data;
 };
 
+struct mdp_bl_scale_data {
+	uint32_t min_lvl;
+	uint32_t scale;
+};
+
 enum {
 	mdp_op_pcc_cfg,
 	mdp_op_csc_cfg,
 	mdp_op_lut_cfg,
+	mdp_bl_scale_cfg,
 	mdp_op_max,
 };
 
@@ -436,6 +466,7 @@
 		struct mdp_pcc_cfg_data pcc_cfg_data;
 		struct mdp_csc_cfg_data csc_cfg_data;
 		struct mdp_lut_cfg_data lut_cfg_data;
+		struct mdp_bl_scale_data bl_scale_data;
 	} data;
 };
 
@@ -461,30 +492,24 @@
 	struct mdp_mixer_info info[MAX_PIPE_PER_MIXER];
 };
 
-struct msmfb_usb_projector_info {
-	int usb_offset;
-	int latest_offset;
+enum {
+	DISPLAY_SUBSYSTEM_ID,
+	ROTATOR_SUBSYSTEM_ID,
 };
 
 #ifdef __KERNEL__
 
 /* get the framebuffer physical address information */
-int get_fb_phys_info(unsigned long *start, unsigned long *len, int fb_num);
+int get_fb_phys_info(unsigned long *start, unsigned long *len, int fb_num,
+	int subsys_id);
 struct fb_info *msm_fb_get_writeback_fb(void);
 int msm_fb_writeback_init(struct fb_info *info);
-
-/* The QCT latest code base is used, adding on 2/9/2012 */
 int msm_fb_writeback_start(struct fb_info *info);
-int msm_fb_writeback_stop(struct fb_info *info);
-
-int msm_fb_writeback_register_buffer(struct fb_info *info,
-		struct msmfb_writeback_data *data);
 int msm_fb_writeback_queue_buffer(struct fb_info *info,
 		struct msmfb_data *data);
 int msm_fb_writeback_dequeue_buffer(struct fb_info *info,
 		struct msmfb_data *data);
-int msm_fb_writeback_unregister_buffer(struct fb_info *info,
-		struct msmfb_writeback_data *data);
+int msm_fb_writeback_stop(struct fb_info *info);
 int msm_fb_writeback_terminate(struct fb_info *info);
 #endif
 
diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h
index 4db94be..0c03e13 100644
--- a/include/linux/msm_vidc_dec.h
+++ b/include/linux/msm_vidc_dec.h
@@ -514,6 +514,12 @@
 	uint32_t   bottom;
 };
 
+struct vdec_aspectratioinfo {
+	uint32_t aspect_ratio;
+	uint32_t par_width;
+	uint32_t par_height;
+};
+
 struct vdec_output_frameinfo {
 	void __user *bufferaddr;
 	size_t offset;
@@ -524,6 +530,8 @@
 	void *client_data;
 	void *input_frame_clientdata;
 	struct vdec_framesize framesize;
+	enum vdec_interlaced_format interlaced_format;
+	struct vdec_aspectratioinfo aspect_ratio_info;
 };
 
 union vdec_msgdata {
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index bf149eb..519c537 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -454,6 +454,10 @@
 #define VEN_IOCTL_GET_EXTRADATA \
 	_IOR(VEN_IOCTLBASE_ENC, 49, struct venc_ioctl_msg)
 
+/*IOCTL params:SET: InputData - NULL, OutputData - NULL.*/
+#define VEN_IOCTL_SET_SLICE_DELIVERY_MODE \
+	_IO(VEN_IOCTLBASE_ENC, 50)
+
 struct venc_switch{
 	unsigned char	status;
 };
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
index 8f2190e..a846644 100644
--- a/include/linux/pm_qos_params.h
+++ b/include/linux/pm_qos_params.h
@@ -1,3 +1,5 @@
+#ifndef _LINUX_PM_QOS_PARAMS_H
+#define _LINUX_PM_QOS_PARAMS_H
 /* interface for the pm_qos_power infrastructure of the linux kernel.
  *
  * Mark Gross <mgross@linux.intel.com>
@@ -15,7 +17,19 @@
 #define PM_QOS_NUM_CLASSES 5
 #define PM_QOS_DEFAULT_VALUE -1
 
-struct pm_qos_request_list;
+#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
+#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
+#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
+
+struct pm_qos_request_list {
+	struct list_head list;
+	union {
+		s32 value;
+		s32 usec;
+		s32 kbps;
+	};
+	int pm_qos_class;
+};
 
 struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value);
 void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
@@ -25,4 +39,6 @@
 int pm_qos_request(int pm_qos_class);
 int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
 int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
+int pm_qos_request_active(struct pm_qos_request_list *req);
 
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.h b/include/media/msm/vcd_api.h
similarity index 68%
rename from drivers/video/msm/vidc/common/vcd/vcd_api.h
rename to include/media/msm/vcd_api.h
index 1a530f9..c93b696 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.h
+++ b/include/media/msm/vcd_api.h
@@ -1,29 +1,13 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_API_H_
@@ -69,13 +53,20 @@
 	VCD_PWR_STATE_SLEEP,
 };
 
+struct vcd_aspect_ratio {
+	u32 aspect_ratio;
+	u32 extended_par_width;
+	u32 extended_par_height;
+};
+
 struct vcd_frame_data {
 	u8 *virtual;
 	u8 *physical;
+	u32 ion_flag;
 	u32 alloc_len;
 	u32 data_len;
 	u32 offset;
-	s64 time_stamp;
+	s64 time_stamp; /* in usecs*/
 	u32 flags;
 	u32 frm_clnt_data;
 	struct vcd_property_dec_output_buffer dec_op_prop;
@@ -83,6 +74,10 @@
 	enum vcd_frame frame;
 	u32 ip_frm_tag;
 	u32 intrlcd_ip_frm_tag;
+	u8 *desc_buf;
+	u32 desc_size;
+	struct ion_handle *buff_ion_handle;
+	struct vcd_aspect_ratio aspect_ratio_info;
 };
 
 struct vcd_sequence_hdr {
@@ -121,11 +116,14 @@
 	void (*timer_stop) (void *timer_handle);
 };
 
+/*Flags passed to vcd_open*/
+#define VCD_CP_SESSION 0x00000001
+
 u32 vcd_init(struct vcd_init_config *config, s32 *driver_handle);
 u32 vcd_term(s32 driver_handle);
 u32 vcd_open(s32 driver_handle, u32 decoding,
 	void (*callback) (u32 event, u32 status, void *info, size_t sz,
-	void *handle, void *const client_data), void *client_data);
+	void *handle, void *const client_data), void *client_data, int flags);
 u32 vcd_close(void *handle);
 u32 vcd_encode_start(void *handle);
 u32 vcd_encode_frame(void *handle, struct vcd_frame_data *input_frame);
@@ -155,5 +153,6 @@
 void vcd_read_and_clear_interrupt(void);
 void vcd_response_handler(void);
 u8 vcd_get_num_of_clients(void);
-
+u32 vcd_get_ion_status(void);
+struct ion_client *vcd_get_ion_client(void);
 #endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_property.h b/include/media/msm/vcd_property.h
similarity index 63%
rename from drivers/video/msm/vidc/common/vcd/vcd_property.h
rename to include/media/msm/vcd_property.h
index 228b36d..b5417ff 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -1,29 +1,13 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 #ifndef _VCD_DRIVER_PROPERTY_H_
@@ -64,6 +48,12 @@
 #define VCD_I_DEC_PICTYPE (VCD_START_BASE + 0x20)
 #define VCD_I_CONT_ON_RECONFIG (VCD_START_BASE + 0x21)
 #define VCD_I_META_BUFFER_MODE (VCD_START_BASE + 0x22)
+#define VCD_I_DISABLE_DMX (VCD_START_BASE + 0x23)
+#define VCD_I_DISABLE_DMX_SUPPORT (VCD_START_BASE + 0x24)
+#define VCD_I_ENABLE_SPS_PPS_FOR_IDR (VCD_START_BASE + 0x25)
+#define VCD_REQ_PERF_LEVEL (VCD_START_BASE + 0x26)
+#define VCD_I_VOP_TIMING_CONSTANT_DELTA (VCD_START_BASE + 0x27)
+#define VCD_I_SLICE_DELIVERY_MODE (VCD_START_BASE + 0x28)
 
 #define VCD_START_REQ      (VCD_START_BASE + 0x1000)
 #define VCD_I_REQ_IFRAME   (VCD_START_REQ + 0x1)
@@ -105,6 +95,12 @@
 	u32              scan_lines;
 };
 
+enum vcd_perf_level {
+	VCD_PERF_LEVEL0,
+	VCD_PERF_LEVEL1,
+	VCD_PERF_LEVEL2,
+	VCD_PERF_LEVEL_TURBO,
+};
 
 #define VCD_METADATA_DATANONE       0x001
 #define VCD_METADATA_QCOMFILLER     0x002
@@ -136,6 +132,10 @@
 	u32             target_bitrate;
 };
 
+struct vcd_property_perf_level {
+	enum vcd_perf_level level;
+};
+
 enum vcd_yuv_buffer_format {
 	VCD_BUFFER_FORMAT_NV12      = 0x1,
 	VCD_BUFFER_FORMAT_TILE_4x2    = 0x2,
@@ -171,60 +171,60 @@
 };
 
 enum vcd_codec_level {
-   VCD_LEVEL_UNKNOWN       = 0x0,
-   VCD_LEVEL_MPEG4_0       = 0x1,
-   VCD_LEVEL_MPEG4_0b      = 0x2,
-   VCD_LEVEL_MPEG4_1       = 0x3,
-   VCD_LEVEL_MPEG4_2       = 0x4,
-   VCD_LEVEL_MPEG4_3       = 0x5,
-   VCD_LEVEL_MPEG4_3b      = 0x6,
-   VCD_LEVEL_MPEG4_4       = 0x7,
-   VCD_LEVEL_MPEG4_4a      = 0x8,
-   VCD_LEVEL_MPEG4_5       = 0x9,
-   VCD_LEVEL_MPEG4_6       = 0xA,
-   VCD_LEVEL_MPEG4_7       = 0xB,
-   VCD_LEVEL_MPEG4_X       = 0xC,
-   VCD_LEVEL_H264_1        = 0x10,
-   VCD_LEVEL_H264_1b       = 0x11,
-   VCD_LEVEL_H264_1p1      = 0x12,
-   VCD_LEVEL_H264_1p2      = 0x13,
-   VCD_LEVEL_H264_1p3      = 0x14,
-   VCD_LEVEL_H264_2        = 0x15,
-   VCD_LEVEL_H264_2p1      = 0x16,
-   VCD_LEVEL_H264_2p2      = 0x17,
-   VCD_LEVEL_H264_3        = 0x18,
-   VCD_LEVEL_H264_3p1      = 0x19,
-   VCD_LEVEL_H264_3p2      = 0x1A,
-   VCD_LEVEL_H264_4        = 0x1B,
-   VCD_LEVEL_H264_4p1      = 0x1C,
-   VCD_LEVEL_H264_4p2      = 0x1D,
-   VCD_LEVEL_H264_5        = 0x1E,
-   VCD_LEVEL_H264_5p1      = 0x1F,
-   VCD_LEVEL_H263_10       = 0x20,
-   VCD_LEVEL_H263_20       = 0x21,
-   VCD_LEVEL_H263_30       = 0x22,
-   VCD_LEVEL_H263_40       = 0x23,
-   VCD_LEVEL_H263_45       = 0x24,
-   VCD_LEVEL_H263_50       = 0x25,
-   VCD_LEVEL_H263_60       = 0x26,
-   VCD_LEVEL_H263_70       = 0x27,
-   VCD_LEVEL_H263_X        = 0x28,
-   VCD_LEVEL_MPEG2_LOW     = 0x30,
-   VCD_LEVEL_MPEG2_MAIN    = 0x31,
-   VCD_LEVEL_MPEG2_HIGH_14 = 0x32,
-   VCD_LEVEL_MPEG2_HIGH    = 0x33,
-   VCD_LEVEL_MPEG2_X       = 0x34,
-   VCD_LEVEL_VC1_S_LOW     = 0x40,
-   VCD_LEVEL_VC1_S_MEDIUM  = 0x41,
-   VCD_LEVEL_VC1_M_LOW     = 0x42,
-   VCD_LEVEL_VC1_M_MEDIUM  = 0x43,
-   VCD_LEVEL_VC1_M_HIGH    = 0x44,
-   VCD_LEVEL_VC1_A_0       = 0x45,
-   VCD_LEVEL_VC1_A_1       = 0x46,
-   VCD_LEVEL_VC1_A_2       = 0x47,
-   VCD_LEVEL_VC1_A_3       = 0x48,
-   VCD_LEVEL_VC1_A_4       = 0x49,
-   VCD_LEVEL_VC1_X         = 0x4A
+	VCD_LEVEL_UNKNOWN       = 0x0,
+	VCD_LEVEL_MPEG4_0       = 0x1,
+	VCD_LEVEL_MPEG4_0b      = 0x2,
+	VCD_LEVEL_MPEG4_1       = 0x3,
+	VCD_LEVEL_MPEG4_2       = 0x4,
+	VCD_LEVEL_MPEG4_3       = 0x5,
+	VCD_LEVEL_MPEG4_3b      = 0x6,
+	VCD_LEVEL_MPEG4_4       = 0x7,
+	VCD_LEVEL_MPEG4_4a      = 0x8,
+	VCD_LEVEL_MPEG4_5       = 0x9,
+	VCD_LEVEL_MPEG4_6       = 0xA,
+	VCD_LEVEL_MPEG4_7       = 0xB,
+	VCD_LEVEL_MPEG4_X       = 0xC,
+	VCD_LEVEL_H264_1        = 0x10,
+	VCD_LEVEL_H264_1b       = 0x11,
+	VCD_LEVEL_H264_1p1      = 0x12,
+	VCD_LEVEL_H264_1p2      = 0x13,
+	VCD_LEVEL_H264_1p3      = 0x14,
+	VCD_LEVEL_H264_2        = 0x15,
+	VCD_LEVEL_H264_2p1      = 0x16,
+	VCD_LEVEL_H264_2p2      = 0x17,
+	VCD_LEVEL_H264_3        = 0x18,
+	VCD_LEVEL_H264_3p1      = 0x19,
+	VCD_LEVEL_H264_3p2      = 0x1A,
+	VCD_LEVEL_H264_4        = 0x1B,
+	VCD_LEVEL_H264_4p1      = 0x1C,
+	VCD_LEVEL_H264_4p2      = 0x1D,
+	VCD_LEVEL_H264_5        = 0x1E,
+	VCD_LEVEL_H264_5p1      = 0x1F,
+	VCD_LEVEL_H263_10       = 0x20,
+	VCD_LEVEL_H263_20       = 0x21,
+	VCD_LEVEL_H263_30       = 0x22,
+	VCD_LEVEL_H263_40       = 0x23,
+	VCD_LEVEL_H263_45       = 0x24,
+	VCD_LEVEL_H263_50       = 0x25,
+	VCD_LEVEL_H263_60       = 0x26,
+	VCD_LEVEL_H263_70       = 0x27,
+	VCD_LEVEL_H263_X        = 0x28,
+	VCD_LEVEL_MPEG2_LOW     = 0x30,
+	VCD_LEVEL_MPEG2_MAIN    = 0x31,
+	VCD_LEVEL_MPEG2_HIGH_14 = 0x32,
+	VCD_LEVEL_MPEG2_HIGH    = 0x33,
+	VCD_LEVEL_MPEG2_X       = 0x34,
+	VCD_LEVEL_VC1_S_LOW     = 0x40,
+	VCD_LEVEL_VC1_S_MEDIUM  = 0x41,
+	VCD_LEVEL_VC1_M_LOW     = 0x42,
+	VCD_LEVEL_VC1_M_MEDIUM  = 0x43,
+	VCD_LEVEL_VC1_M_HIGH    = 0x44,
+	VCD_LEVEL_VC1_A_0       = 0x45,
+	VCD_LEVEL_VC1_A_1       = 0x46,
+	VCD_LEVEL_VC1_A_2       = 0x47,
+	VCD_LEVEL_VC1_A_3       = 0x48,
+	VCD_LEVEL_VC1_A_4       = 0x49,
+	VCD_LEVEL_VC1_X         = 0x4A
 };
 
 struct vcd_property_level {
@@ -302,6 +302,10 @@
 	u32   vop_time_resolution;
 };
 
+struct vcd_property_vop_timing_constant_delta {
+      u32 constant_delta; /*In usecs */
+};
+
 struct vcd_property_short_header {
 	u32             short_header;
 };
@@ -314,11 +318,11 @@
 	u32        req_i_frame;
 };
 
-struct vcd_frame_rect{
-   u32   left;
-   u32   top;
-   u32   right;
-   u32   bottom;
+struct vcd_frame_rect {
+	u32   left;
+	u32   top;
+	u32   right;
+	u32   bottom;
 };
 
 struct vcd_property_dec_output_buffer {
@@ -327,33 +331,42 @@
 };
 
 enum vcd_output_order {
-   VCD_DEC_ORDER_DISPLAY  = 0x0,
-   VCD_DEC_ORDER_DECODE   = 0x1
+	VCD_DEC_ORDER_DISPLAY  = 0x0,
+	VCD_DEC_ORDER_DECODE   = 0x1
 };
 
-struct vcd_property_enc_recon_buffer{
+struct vcd_property_enc_recon_buffer {
+	u8 *user_virtual_addr;
 	u8 *kernel_virtual_addr;
 	u8 *physical_addr;
+	u8 *dev_addr;
 	u32 buffer_size;
 	u32 ysize;
 	int pmem_fd;
 	u32 offset;
+	void *client_data;
 };
 
-struct vcd_property_h264_mv_buffer{
+struct vcd_property_h264_mv_buffer {
 	u8 *kernel_virtual_addr;
 	u8 *physical_addr;
 	u32 size;
 	u32 count;
 	int pmem_fd;
 	u32 offset;
+	u8 *dev_addr;
+	void *client_data;
 };
 
-struct vcd_property_buffer_size{
+struct vcd_property_buffer_size {
 	int width;
 	int height;
 	int size;
 	int alignment;
 };
 
+struct vcd_property_sps_pps_for_idr_enable {
+	u32 sps_pps_for_idr_enable_flag;
+};
+
 #endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_status.h b/include/media/msm/vcd_status.h
similarity index 62%
rename from drivers/video/msm/vidc/common/vcd/vcd_status.h
rename to include/media/msm/vcd_status.h
index 6fba334..7e8ec0b 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_status.h
+++ b/include/media/msm/vcd_status.h
@@ -1,29 +1,13 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
diff --git a/include/media/msm/vidc_init.h b/include/media/msm/vidc_init.h
new file mode 100644
index 0000000..c681213
--- /dev/null
+++ b/include/media/msm/vidc_init.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef VIDC_INIT_H
+#define VIDC_INIT_H
+#include <linux/ion.h>
+#include <media/msm/vidc_type.h>
+#include <media/msm/vcd_property.h>
+
+#define VIDC_MAX_NUM_CLIENTS 4
+#define MAX_VIDEO_NUM_OF_BUFF 100
+
+enum buffer_dir {
+	BUFFER_TYPE_INPUT,
+	BUFFER_TYPE_OUTPUT
+};
+
+struct buf_addr_table {
+	unsigned long user_vaddr;
+	unsigned long kernel_vaddr;
+	unsigned long phy_addr;
+	unsigned long buff_ion_flag;
+	struct ion_handle *buff_ion_handle;
+	int pmem_fd;
+	struct file *file;
+	unsigned long dev_addr;
+	void *client_data;
+};
+
+struct video_client_ctx {
+	void *vcd_handle;
+	u32 num_of_input_buffers;
+	u32 num_of_output_buffers;
+	struct buf_addr_table input_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF];
+	struct buf_addr_table output_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF];
+	struct list_head msg_queue;
+	struct mutex msg_queue_lock;
+	struct mutex enrty_queue_lock;
+	wait_queue_head_t msg_wait;
+	struct completion event;
+	struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
+	struct vcd_property_enc_recon_buffer recon_buffer[4];
+	u32 event_status;
+	u32 seq_header_set;
+	u32 stop_msg;
+	u32 stop_called;
+	u32 stop_sync_cb;
+	struct ion_client *user_ion_client;
+	struct ion_handle *seq_hdr_ion_handle;
+	struct ion_handle *h264_mv_ion_handle;
+	struct ion_handle *recon_buffer_ion_handle[4];
+	u32 dmx_disable;
+};
+
+void __iomem *vidc_get_ioaddr(void);
+int vidc_load_firmware(void);
+void vidc_release_firmware(void);
+u32 vidc_get_fd_info(struct video_client_ctx *client_ctx,
+		enum buffer_dir buffer, int pmem_fd,
+		unsigned long kvaddr, int index,
+		struct ion_handle **buff_handle);
+u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, u32 search_with_user_vaddr,
+	unsigned long *user_vaddr, unsigned long *kernel_vaddr,
+	unsigned long *phy_addr, int *pmem_fd, struct file **file,
+	s32 *buffer_index);
+u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, unsigned long user_vaddr,
+	unsigned long *kernel_vaddr, int pmem_fd,
+	unsigned long buffer_addr_offset,
+	unsigned int max_num_buffers, unsigned long length);
+u32 vidc_insert_addr_table_kernel(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, unsigned long user_vaddr,
+	unsigned long kernel_vaddr, unsigned long phys_addr,
+	unsigned int max_num_buffers,
+	unsigned long length);
+u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, unsigned long user_vaddr,
+	unsigned long *kernel_vaddr);
+void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx,
+		enum buffer_dir buffer);
+
+u32 vidc_timer_create(void (*timer_handler)(void *),
+	void *user_data, void **timer_handle);
+void  vidc_timer_release(void *timer_handle);
+void  vidc_timer_start(void *timer_handle, u32 time_out);
+void  vidc_timer_stop(void *timer_handle);
+
+
+#endif
diff --git a/include/media/msm/vidc_type.h b/include/media/msm/vidc_type.h
new file mode 100644
index 0000000..d4db0a0
--- /dev/null
+++ b/include/media/msm/vidc_type.h
@@ -0,0 +1,30 @@
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef VIDC_TYPE_H
+#define VIDC_TYPE_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/time.h>
+#include <linux/dma-mapping.h>
+#include <linux/android_pmem.h>
+
+#define DEBUG   0
+#define VIDC_ENABLE_DBGFS
+
+#define USE_RES_TRACKER
+#endif
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
index 2622509..f48d643 100644
--- a/kernel/pm_qos_params.c
+++ b/kernel/pm_qos_params.c
@@ -48,15 +48,6 @@
  * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
  * held, taken with _irqsave.  One lock to rule them all
  */
-struct pm_qos_request_list {
-	struct list_head list;
-	union {
-		s32 value;
-		s32 usec;
-		s32 kbps;
-	};
-	int pm_qos_class;
-};
 
 static s32 max_compare(s32 v1, s32 v2);
 static s32 min_compare(s32 v1, s32 v2);