Initial Contribution

msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142

Signed-off-by: Bryan Huntsman <bryanh@codeaurora.org>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4c85a4b..a564a03 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -25,6 +25,8 @@
 
 source "drivers/gpu/ion/Kconfig"
 
+source "drivers/gpu/msm/Kconfig"
+
 config VGASTATE
        tristate
        default n
@@ -2323,13 +2325,6 @@
 	  Select this option if display contents should be inherited as set by
 	  the bootloader.
 
-config FB_MSM
-	tristate "MSM Framebuffer support"
-	depends on FB && ARCH_MSM
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-
 config FB_MX3
 	tristate "MX3 Framebuffer support"
 	depends on FB && MX3_IPU
@@ -2385,6 +2380,8 @@
 	  Choose this option if you want to use the Unigfx device as a
 	  framebuffer device. Without the support of PCI & AGP.
 
+source "drivers/video/msm/Kconfig"
+
 source "drivers/video/omap/Kconfig"
 source "drivers/video/omap2/Kconfig"
 
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 5aac00e..a024064 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1169,14 +1169,11 @@
 		unlock_fb_info(info);
 		break;
 	default:
-		if (!lock_fb_info(info))
-			return -ENODEV;
 		fb = info->fbops;
 		if (fb->fb_ioctl)
 			ret = fb->fb_ioctl(info, cmd, arg);
 		else
 			ret = -ENOTTY;
-		unlock_fb_info(info);
 	}
 	return ret;
 }
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
new file mode 100644
index 0000000..677863d
--- /dev/null
+++ b/drivers/video/msm/Kconfig
@@ -0,0 +1,661 @@
+
+source "drivers/video/msm/vidc/Kconfig"
+
+config FB_MSM
+	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
+	---help---
+	  Support for MSM Framebuffer.
+
+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
+	default n
+
+config FB_MSM_TRIPLE_BUFFER
+	bool "Support for triple frame buffer"
+	default n
+
+choice
+	prompt "MDP HW version"
+	default FB_MSM_MDP22
+
+config FB_MSM_MDP22
+	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
+	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
+	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
+	bool "MDP HW ver4.0"
+	---help---
+	  Support for MSM MDP HW revision 4.0
+	  Say Y here if this is msm7x30 variant 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
+	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_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_SIMULATOR
+	bool
+	select FB_MSM_MIPI_DSI
+	default n
+
+config FB_MSM_MIPI_DSI_NOVATEK
+        bool
+        select FB_MSM_MIPI_DSI
+        default n
+
+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_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_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_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_SIMULATOR_VIDEO
+	bool
+	select FB_MSM_MIPI_DSI_SIMULATOR
+	default n
+
+
+config FB_MSM_OVERLAY_WRITEBACK
+	depends on FB_MSM_OVERLAY
+        bool "MDP overlay write back mode 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_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
+	depends on FB_MSM_LCDC_HW
+	bool "MIPI Panel Detect + LCDC Panel Auto Detect"
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+	select FB_MSM_LCDC_AUTO_DETECT
+	select FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
+	select FB_MSM_MIPI_SIMULATOR_VIDEO
+	select FB_MSM_LCDC_SAMSUNG_WSVGA
+	select FB_MSM_LCDC_AUO_WVGA
+	select FB_MSM_LCDC_SAMSUNG_OLED_PT
+
+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_SAMSUNG_OLED_PT
+	---help---
+	  Support for LCDC 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_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_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_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_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---
+          Support for HDCP mode for ADV7520 HDMI 720p Panel
+          Choose to enable HDCP
+
+
+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 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 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
+	  .
+	  .
+
+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.
+
+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
+	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
+
+endif
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index 802d6ae..280e528 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -1,19 +1,150 @@
-
-# core framebuffer
-#
 obj-y := msm_fb.o
 
-# MDP DMA/PPP engine
-#
-obj-y += mdp.o mdp_scale_tables.o mdp_ppp.o
+obj-$(CONFIG_FB_MSM_LOGO) += logo.o
+obj-$(CONFIG_FB_BACKLIGHT) += msm_fb_bl.o
 
-# MDDI interface
-#
-obj-y += mddi.o
+# MDP
+obj-y += mdp.o
 
-# MDDI client/panel drivers
-#
-obj-y += mddi_client_dummy.o
-obj-y += mddi_client_toshiba.o
-obj-y += mddi_client_nt35399.o
+obj-$(CONFIG_DEBUG_FS) += mdp_debugfs.o
 
+ifeq ($(CONFIG_FB_MSM_MDP40),y)
+obj-y += mdp4_util.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
+
+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_RENESAS) += mipi_renesas.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_SIMULATOR) += mipi_simulator.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
+obj-y += mipi_novatek_video_qhd_pt.o mipi_novatek_cmd_qhd_pt.o
+obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_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_NOVATEK_VIDEO_QHD_PT) += mipi_novatek_video_qhd_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_SIMULATOR_VIDEO) += mipi_simulator_video.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_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_MSM_VIDC_1080P) += vidc/
+obj-$(CONFIG_MSM_VIDC_720P) += vidc/
+
+clean:
+	rm *.o .*cmd
diff --git a/drivers/video/msm/adv7520.c b/drivers/video/msm/adv7520.c
new file mode 100644
index 0000000..0900f23
--- /dev/null
+++ b/drivers/video/msm/adv7520.c
@@ -0,0 +1,1005 @@
+/* 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/types.h>
+#include <linux/bitops.h>
+#include <linux/adv7520.h>
+#include <linux/time.h>
+#include <linux/completion.h>
+#include <linux/wakelock.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 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);
+	else
+		kobject_uevent(external_common_state->uevent_kobj,
+			KOBJ_OFFLINE);
+	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);
+
+	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);
+
+	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");
+
+	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;
+	}
+	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;
+	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:
+	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_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..68590af
--- /dev/null
+++ b/drivers/video/msm/ebi2_lcd.c
@@ -0,0 +1,268 @@
+/* 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,
+	.suspend_late = NULL,
+	.resume_early = 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 ebi2_lcd_resource_initialized;
+
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
+
+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;
+
+	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 = 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_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 = panel_next_on;
+	pdata->off = panel_next_off;
+	pdata->next = pdev;
+
+	/* get/set panel specific fb info */
+	mfd->panel_info = pdata->panel_info;
+
+	if (mfd->panel_info.bpp == 24)
+		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 (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;
+		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..694450a
--- /dev/null
+++ b/drivers/video/msm/external_common.c
@@ -0,0 +1,1229 @@
+/* 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/types.h>
+#include <linux/bitops.h>
+#include <linux/mutex.h>
+
+#define DEBUG
+#define DEV_DBG_PREFIX "EXT_COMMON: "
+
+#include "msm_fb.h"
+#include "external_common.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;
+		}
+	}
+}
+
+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);
+
+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_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 = 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;
+}
+
+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
+
+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;
+	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 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);
+#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(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 struct attribute *external_common_fs_attrs[] = {
+	&dev_attr_video_mode.attr,
+	&dev_attr_video_mode_str.attr,
+	&dev_attr_connected.attr,
+#ifdef CONFIG_FB_MSM_HDMI_COMMON
+	&dev_attr_edid_modes.attr,
+	&dev_attr_hdcp.attr,
+	&dev_attr_hpd.attr,
+	&dev_attr_3d_present.attr,
+	&dev_attr_hdcp_present.attr,
+#endif
+#ifdef CONFIG_FB_MSM_HDMI_3D
+	&dev_attr_format_3d.attr,
+#endif
+	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, uint8 type,
+	uint8 *len)
+{
+	/* the start of data block collection, start of Video Data Block */
+	uint32 offset = 4;
+
+	*len = 0;
+	if (in_buf[2] == 4) { /* no non-DTD data present */
+		DEV_WARN("EDID: no non-DTD data present\n");
+		return NULL;
+	}
+	while (offset < 0x80) {
+		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: block=%d 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, 3, &len);
+
+	if (vsd == NULL)
+		return 0;
+
+	DEV_DBG("EDID: VSD PhyAddr=%04x, MaxTMDS=%dMHz\n",
+		((uint32)vsd[6] << 8) + (uint32)vsd[5], (uint32)vsd[7] * 5);
+	return ((uint32)vsd[3] << 16) + ((uint32)vsd[2] << 8) + (uint32)vsd[1];
+}
+
+static void hdmi_edid_extract_3d_present(const uint8 *in_buf)
+{
+	uint8 len, offset;
+	const uint8 *vsd = hdmi_edid_find_block(in_buf, 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 = !(vsd[8] & BIT(7)) ? 9 : 13;
+	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, 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, 4, &len);
+
+	if (sad == NULL)
+		return;
+
+	external_common_state->speaker_allocation_block = sad[1];
+	DEV_DBG("EDID: speaker allocation data=%s%s%s%s%s%s%s\n",
+		(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)) ? "LFE," : "");
+}
+
+static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf)
+{
+	uint8 len;
+	const uint8 *sad = hdmi_edid_find_block(in_buf, 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_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_4_3 = (img_size_h * 3 == img_size_v * 4);
+
+	max_num_of_elements  = sizeof(hdmi_edid_disp_mode_lut)
+		/ sizeof(*hdmi_edid_disp_mode_lut);
+
+	/* Break table in half and search using H Active */
+	ndx = active_h < hdmi_edid_disp_mode_lut[max_num_of_elements / 2]
+		.active_h ? 0 : max_num_of_elements / 2;
+
+	/* EDID_TIMING_DESC_INTERLACE[0xD:8]: Relative Offset to the EDID
+	 *   detailed timing descriptors - Interlace flag */
+	interlaced = (data_buf[0xD] & 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)
+		disp_mode_list->disp_mode_list[
+			disp_mode_list->num_of_elements++] = video_format;
+}
+
+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 *svd = num_og_cea_blocks ?
+		hdmi_edid_find_block(data_buf+0x80, 2, &len) : NULL;
+
+	disp_mode_list->num_of_elements = 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);
+			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 != data_buf[0x36+desc_offset]) {
+			hdmi_edid_detail_desc(data_buf+0x36+desc_offset,
+				&video_format);
+			add_supported_video_format(disp_mode_list,
+				video_format);
+			if (video_format == HDMI_VFRMT_640x480p60_4_3)
+				has480p = TRUE;
+			desc_offset += 0x12;
+			++i;
+		}
+	} else if (1 == num_og_cea_blocks) {
+		uint32 desc_offset = 0;
+		/* 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 = data_buf[0x82];
+		while (0 != data_buf[0x80 + desc_offset]) {
+			hdmi_edid_detail_desc(data_buf+0x36+desc_offset,
+				&video_format);
+			add_supported_video_format(disp_mode_list,
+				video_format);
+			if (video_format == HDMI_VFRMT_640x480p60_4_3)
+				has480p = TRUE;
+			desc_offset += 0x12;
+			++i;
+		}
+	}
+
+	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;
+	int status = external_common_state->read_edid_block(block, edid_buf);
+	if (status || block > 0)
+		goto error;
+
+	/* Calculate checksum */
+	check_sum = 0;
+	for (ndx = 0; ndx < 0x80; ++ndx)
+		check_sum += edid_buf[ndx];
+
+	if (check_sum & 0xFF) {
+#ifdef DEBUG
+		const u8 *b = edid_buf;
+#endif
+		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;
+	}
+
+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->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);
+		}
+		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;
+	} 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);
+
+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->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;
+	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..30a8f48
--- /dev/null
+++ b/drivers/video/msm/external_common.h
@@ -0,0 +1,251 @@
+/* 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 __EXTERNAL_COMMON_H__
+#define __EXTERNAL_COMMON_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];
+	uint32	num_of_elements;
+};
+#endif
+
+struct external_common_state_type {
+	boolean hpd_state;
+	struct kobject *uevent_kobj;
+	uint32 video_resolution;
+	struct device *dev;
+#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;
+	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;
+
+#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);
+void hdmi_common_init_panel_info(struct msm_panel_info *pinfo);
+#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..53dc911
--- /dev/null
+++ b/drivers/video/msm/hdmi_msm.c
@@ -0,0 +1,3731 @@
+/* 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.
+ *
+ */
+
+/* #define DEBUG */
+#define DEV_DBG_PREFIX "HDMI: "
+/* #define REG_DUMP */
+
+#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 "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
+
+struct workqueue_struct *hdmi_work_queue;
+struct hdmi_msm_state_type *hdmi_msm_state;
+
+static DEFINE_MUTEX(hdmi_msm_state_mutex);
+static DEFINE_MUTEX(hdcp_auth_state_mutex);
+
+#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
+
+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_hpd_state_work(struct work_struct *work)
+{
+	boolean hpd_state;
+	char *envp[2];
+
+	if (!hdmi_msm_state || !hdmi_msm_state->hpd_initialized ||
+		!MSM_HDMI_BASE) {
+		DEV_DBG("%s: ignored, probe failed\n", __func__);
+		return;
+	}
+#ifdef CONFIG_SUSPEND
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->pm_suspended) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_WARN("%s: ignored, pm_suspended\n", __func__);
+		return;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif
+
+	/* HPD_INT_STATUS[0x0250] */
+	hpd_state = (HDMI_INP(0x0250) & 0x2) >> 1;
+	mutex_lock(&external_common_state_hpd_mutex);
+	mutex_lock(&hdmi_msm_state_mutex);
+	if ((external_common_state->hpd_state != hpd_state) || (hdmi_msm_state->
+			hpd_prev_state != external_common_state->hpd_state)) {
+		external_common_state->hpd_state = hpd_state;
+		hdmi_msm_state->hpd_prev_state =
+				external_common_state->hpd_state;
+		DEV_DBG("%s: state not stable yet, wait again (%d|%d|%d)\n",
+			__func__, hdmi_msm_state->hpd_prev_state,
+			external_common_state->hpd_state, hpd_state);
+		mutex_unlock(&external_common_state_hpd_mutex);
+		hdmi_msm_state->hpd_stable = 0;
+		mutex_unlock(&hdmi_msm_state_mutex);
+		mod_timer(&hdmi_msm_state->hpd_state_timer, jiffies + HZ/2);
+		return;
+	}
+	mutex_unlock(&external_common_state_hpd_mutex);
+
+	if (hdmi_msm_state->hpd_stable++) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_DBG("%s: no more timer, depending for IRQ now\n",
+			__func__);
+		return;
+	}
+
+	hdmi_msm_state->hpd_stable = 1;
+	DEV_INFO("HDMI HPD: event detected\n");
+
+	if (!hdmi_msm_state->hpd_cable_chg_detected) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		if (hpd_state) {
+			if (!external_common_state->
+					disp_mode_list.num_of_elements)
+				hdmi_msm_read_edid();
+			hdmi_msm_turn_on();
+		}
+	} else {
+		hdmi_msm_state->hpd_cable_chg_detected = FALSE;
+		mutex_unlock(&hdmi_msm_state_mutex);
+		if (hpd_state) {
+			hdmi_msm_read_edid();
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+			hdmi_msm_state->reauth = FALSE ;
+#endif
+			/* Build EDID table */
+			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);
+			hdmi_msm_turn_on();
+			DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
+			kobject_uevent(external_common_state->uevent_kobj,
+				KOBJ_ONLINE);
+			hdmi_msm_hdcp_enable();
+		} else {
+			DEV_INFO("HDMI HPD: sense DISCONNECTED: send OFFLINE\n"
+				);
+			kobject_uevent(external_common_state->uevent_kobj,
+				KOBJ_OFFLINE);
+		}
+	}
+
+	/* HPD_INT_CTRL[0x0254]
+	 *   31:10 Reserved
+	 *   9     RCV_PLUGIN_DET_MASK	receiver plug in interrupt mask.
+	 *                              When programmed to 1,
+	 *                              RCV_PLUGIN_DET_INT will toggle
+	 *                              the interrupt line
+	 *   8:6   Reserved
+	 *   5     RX_INT_EN		Panel RX interrupt enable
+	 *         0: Disable
+	 *         1: Enable
+	 *   4     RX_INT_ACK		WRITE ONLY. Panel RX interrupt
+	 *                              ack
+	 *   3     Reserved
+	 *   2     INT_EN		Panel interrupt control
+	 *         0: Disable
+	 *         1: Enable
+	 *   1     INT_POLARITY		Panel interrupt polarity
+	 *         0: generate interrupt on disconnect
+	 *         1: generate interrupt on connect
+	 *   0     INT_ACK		WRITE ONLY. Panel interrupt ack */
+	/* Set IRQ for HPD */
+	HDMI_OUTP(0x0254, 4 | (hpd_state ? 0 : 2));
+}
+
+#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)
+{
+#ifdef CONFIG_SUSPEND
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->pm_suspended) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_WARN("HDCP: deauthenticating skipped, pm_suspended\n");
+		return;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif
+
+	/* 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();
+		mod_timer(&hdmi_msm_state->hdcp_timer, jiffies + HZ/2);
+	}
+}
+
+static void hdmi_msm_hdcp_work(struct work_struct *work)
+{
+#ifdef CONFIG_SUSPEND
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->pm_suspended) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_WARN("HDCP: Re-enable skipped, pm_suspended\n");
+		return;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif
+
+	/* 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);
+		hdmi_msm_state->reauth = TRUE;
+		hdmi_msm_turn_on();
+	} else
+		mutex_unlock(&external_common_state_hpd_mutex);
+}
+#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;
+	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;
+	}
+#ifdef CONFIG_SUSPEND
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->pm_suspended) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_WARN("ISR ignored, pm_suspended\n");
+		return IRQ_HANDLED;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif
+
+	/* 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;
+
+		/* HDMI_HPD_INT_CTRL[0x0254] */
+		/* Clear all interrupts, timer will turn IRQ back on */
+		HDMI_OUTP(0x0254, 1 << 0);
+
+		DEV_DBG("%s: HPD IRQ, Ctrl=%04x, State=%04x\n", __func__,
+			hpd_int_ctrl, hpd_int_status);
+		mutex_lock(&hdmi_msm_state_mutex);
+		hdmi_msm_state->hpd_cable_chg_detected = TRUE;
+
+		/* ensure 2 readouts */
+		hdmi_msm_state->hpd_prev_state = cable_detected ? 0 : 1;
+		external_common_state->hpd_state = cable_detected ? 1 : 0;
+		hdmi_msm_state->hpd_stable = 0;
+		mod_timer(&hdmi_msm_state->hpd_state_timer, jiffies + HZ/2);
+		mutex_unlock(&hdmi_msm_state_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->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);
+		}
+		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 */
+		HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 5))
+			& ~((1 << 6) | (1 << 4)));
+		DEV_INFO("HDCP: AUTH_FAIL_INT received, LINK0_STATUS=0x%08x\n",
+			HDMI_INP_ND(0x011C));
+		if (hdmi_msm_state->full_auth_done) {
+			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
+			 */
+			queue_work(hdmi_work_queue,
+			    &hdmi_msm_state->hdcp_reauth_work);
+		}
+		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 = FALSE;
+
+		mutex_unlock(&hdcp_auth_state_mutex);
+		DEV_DBG("calling reauthenticate from %s HDCP FAIL INT ",
+		    __func__);
+
+		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 */
+
+	DEV_DBG("%s: HPD<Ctrl=%04x, State=%04x>, ddc_int_ctrl=%04x, "
+		"aud_int=%04x, cec_int=%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;
+}
+
+static 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;
+			/* HDMI_CTRL */
+			HDMI_OUTP(0x0000, reg_val);
+			/* HDMI_DVI_SEL */
+			reg_val &= ~0x00000002;
+		} else
+			reg_val |= 0x00000002;
+	} else
+		reg_val = 0x00000002;
+
+	/* HDMI_CTRL */
+	HDMI_OUTP(0x0000, reg_val);
+	DEV_DBG("HDMI Core: %s\n", power_on ? "Enable" : "Disable");
+}
+
+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 */
+	HDMI_OUTP_ND(0x0224, 0);
+
+	/* 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 = 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(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);
+
+	external_common_state->hdcp_active = FALSE;
+	/* 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 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, 0x2 << 8);
+
+		/* 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));
+
+		/* 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 */
+		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);
+			goto error;
+		}
+
+		/* 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);
+
+		/* 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;
+		}
+
+		/* 0x013C HDCP_RCVPORT_DATA2_0
+		[15:0] LINK0_RI */
+		HDMI_OUTP(0x013C, (((uint32)buf[1]) << 8) | buf[0]);
+		DEV_DBG("HDCP: R0'=%02x%02x\n", buf[1], buf[0]);
+
+		INIT_COMPLETION(hdmi_msm_state->hdcp_success_done);
+		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);
+	}
+	/* 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) & 0x10)) && 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())
+		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();
+
+	external_common_state->hdcp_active = TRUE;
+	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;
+	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);
+	}
+	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);
+	}
+}
+#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.030MHz */
+	HDMI_MSM_AUDIO_ARCS(27030, {
+		{4096, 27030}, {6272, 30030}, {6144, 27030}, {12544, 30030},
+		{12288, 27030}, {25088, 30030}, {24576, 27030} }),
+	/*  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);
+
+	return 0;
+}
+EXPORT_SYMBOL(hdmi_audio_enable);
+
+static void hdmi_msm_audio_info_setup(boolean enabled, int num_of_channels,
+	int level_shift, boolean down_mix)
+{
+	uint32 channel_allocation = 0;	/* Default to FR,FL */
+	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;
+
+	/* 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:
+			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:
+			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);
+}
+
+static void hdmi_msm_audio_ctrl_setup(boolean enabled, int delay)
+{
+	uint32 audio_pkt_ctrl_reg = 0;
+
+	/* Enable Packet Transmission */
+	audio_pkt_ctrl_reg |= enabled ? 0x00000001 : 0;
+	audio_pkt_ctrl_reg |= (delay << 4);
+
+	/* HDMI_AUDIO_PKT_CTRL1[0x0020] */
+	HDMI_OUTP(0x0020, audio_pkt_ctrl_reg);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+
+	hdmi_msm_audio_acr_setup(TRUE,
+		external_common_state->video_resolution,
+		MSM_HDMI_SAMPLE_RATE_48KHZ, channels);
+	hdmi_msm_audio_info_setup(TRUE, channels, 0, FALSE);
+	hdmi_msm_audio_ctrl_setup(TRUE, 1);
+
+	/* 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, FALSE);
+	hdmi_msm_audio_ctrl_setup(FALSE, 0);
+	hdmi_msm_audio_acr_setup(FALSE, 0, 0, 0);
+	DEV_INFO("HDMI Audio: Disabled\n");
+	return 0;
+}
+
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+static uint8 hdmi_msm_avi_iframe_lut[][14] = {
+/*	480p60	480i60	576p50	576i50	720p60	720p50	1080p60	1080i60	1080p50
+	1080i50	1080p24	1080p30	1080p25	640x480p */
+	{0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,
+	 0x10,	0x10,	0x10,	0x10,	0x10},
+	{0x18,	0x18,	0x28,	0x28,	0x28,	0x28,	0x28,	0x28,	0x28,
+	 0x28,	0x28,	0x28,	0x28,	0x18},
+	{0x04,	0x04,	0x04,	0x04,	0x04,	0x04,	0x04,	0x04,	0x04,
+	 0x04,	0x04,	0x04,	0x04,	0x88},
+	{0x02,	0x06,	0x11,	0x15,	0x04,	0x13,	0x10,	0x05,	0x1F,
+	 0x14,	0x20,	0x22,	0x21,	0x01},
+	{0x00,	0x01,	0x00,	0x01,	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},
+	{0xE1,	0xE1,	0x41,	0x41,	0xD1,	0xd1,	0x39,	0x39,	0x39,
+	 0x39,	0x39,	0x39,	0x39,	0xe1},
+	{0x01,	0x01,	0x02,	0x02,	0x02,	0x02,	0x04,	0x04,	0x04,
+	 0x04,	0x04,	0x04,	0x04,	0x01},
+	{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},
+	{0xD1,	0xD1,	0xD1,	0xD1,	0x01,	0x01,	0x81,	0x81,	0x81,
+	 0x81,	0x81,	0x81,	0x81,	0x81},
+	{0x02,	0x02,	0x02,	0x02,	0x05,	0x05,	0x07,	0x07,	0x07,
+	 0x07,	0x07,	0x07,	0x07,	0x02}
+};
+
+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;
+
+	switch (external_common_state->video_resolution) {
+	case HDMI_VFRMT_720x480p60_16_9:
+		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;
+	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];
+	/* 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);
+}
+#endif
+
+#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
+
+static int hdmi_msm_clk(int on)
+{
+	int rc;
+
+	DEV_DBG("HDMI Clk: %s\n", on ? "Enable" : "Disable");
+	if (on) {
+		rc = clk_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_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_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(hdmi_msm_state->hdmi_app_clk);
+		clk_disable(hdmi_msm_state->hdmi_m_pclk);
+		clk_disable(hdmi_msm_state->hdmi_s_pclk);
+	}
+
+	return 0;
+}
+
+static void hdmi_msm_reset_core(void)
+{
+	hdmi_msm_set_mode(FALSE);
+	hdmi_msm_clk(0);
+	udelay(5);
+	hdmi_msm_clk(1);
+
+	clk_reset(hdmi_msm_state->hdmi_app_clk, CLK_RESET_ASSERT);
+	clk_reset(hdmi_msm_state->hdmi_m_pclk, CLK_RESET_ASSERT);
+	clk_reset(hdmi_msm_state->hdmi_s_pclk, CLK_RESET_ASSERT);
+	udelay(20);
+	clk_reset(hdmi_msm_state->hdmi_app_clk, CLK_RESET_DEASSERT);
+	clk_reset(hdmi_msm_state->hdmi_m_pclk, CLK_RESET_DEASSERT);
+	clk_reset(hdmi_msm_state->hdmi_s_pclk, CLK_RESET_DEASSERT);
+}
+
+static void hdmi_msm_turn_on(void)
+{
+	uint32 hpd_ctrl;
+
+	hdmi_msm_reset_core();
+	hdmi_msm_init_phy(external_common_state->video_resolution);
+	/* HDMI_USEC_REFTIMER[0x0208] */
+	HDMI_OUTP(0x0208, 0x0001001B);
+
+	hdmi_msm_video_setup(external_common_state->video_resolution);
+	if (!hdmi_msm_is_dvi_mode())
+		hdmi_msm_audio_setup();
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	hdmi_msm_avi_info_frame();
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+#ifdef CONFIG_FB_MSM_HDMI_3D
+	hdmi_msm_vendor_infoframe_packetsetup();
+#endif
+
+	/* set timeout to 4.1ms (max) for hardware debounce */
+	hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
+
+	/* Toggle HPD circuit to trigger HPD sense */
+	HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
+	HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
+
+	hdmi_msm_set_mode(TRUE);
+
+	/* Setup HPD IRQ */
+	HDMI_OUTP(0x0254, 4 | (external_common_state->hpd_state ? 0 : 2));
+
+#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 */
+	DEV_INFO("HDMI Core: Initialized\n");
+}
+
+static void hdmi_msm_hpd_state_timer(unsigned long data)
+{
+	queue_work(hdmi_work_queue, &hdmi_msm_state->hpd_state_work);
+}
+
+#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
+
+static void hdmi_msm_hpd_read_work(struct work_struct *work)
+{
+	uint32 hpd_ctrl;
+
+	clk_enable(hdmi_msm_state->hdmi_app_clk);
+	hdmi_msm_state->pd->core_power(1, 1);
+	hdmi_msm_state->pd->enable_5v(1);
+	hdmi_msm_set_mode(FALSE);
+	hdmi_msm_init_phy(external_common_state->video_resolution);
+	/* HDMI_USEC_REFTIMER[0x0208] */
+	HDMI_OUTP(0x0208, 0x0001001B);
+	hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
+
+	/* Toggle HPD circuit to trigger HPD sense */
+	HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
+	HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
+
+	hdmi_msm_set_mode(TRUE);
+	msleep(1000);
+	external_common_state->hpd_state = (HDMI_INP(0x0250) & 0x2) >> 1;
+	if (external_common_state->hpd_state) {
+		hdmi_msm_read_edid();
+		DEV_DBG("%s: sense CONNECTED: send ONLINE\n", __func__);
+		kobject_uevent(external_common_state->uevent_kobj,
+			KOBJ_ONLINE);
+	}
+	hdmi_msm_hpd_off();
+	hdmi_msm_set_mode(FALSE);
+	hdmi_msm_state->pd->core_power(0, 1);
+	hdmi_msm_state->pd->enable_5v(0);
+	clk_disable(hdmi_msm_state->hdmi_app_clk);
+}
+
+static void hdmi_msm_hpd_off(void)
+{
+	DEV_DBG("%s: (timer, clk, 5V, core, IRQ off)\n", __func__);
+	del_timer(&hdmi_msm_state->hpd_state_timer);
+	disable_irq(hdmi_msm_state->irq);
+
+	hdmi_msm_set_mode(FALSE);
+	HDMI_OUTP_ND(0x0308, 0x7F); /*0b01111111*/
+	hdmi_msm_state->hpd_initialized = FALSE;
+	hdmi_msm_state->pd->enable_5v(0);
+	hdmi_msm_state->pd->core_power(0, 1);
+	hdmi_msm_clk(0);
+	hdmi_msm_state->hpd_initialized = FALSE;
+}
+
+static void hdmi_msm_dump_regs(const char *prefex)
+{
+#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(bool trigger_handler)
+{
+	static int phy_reset_done;
+
+	hdmi_msm_clk(1);
+	hdmi_msm_state->pd->core_power(1, 1);
+	hdmi_msm_state->pd->enable_5v(1);
+	hdmi_msm_dump_regs("HDMI-INIT: ");
+	hdmi_msm_set_mode(FALSE);
+
+	if (!phy_reset_done) {
+		hdmi_phy_reset();
+		phy_reset_done = 1;
+	}
+
+	hdmi_msm_init_phy(external_common_state->video_resolution);
+	/* HDMI_USEC_REFTIMER[0x0208] */
+	HDMI_OUTP(0x0208, 0x0001001B);
+
+	/* Check HPD State */
+	if (!hdmi_msm_state->hpd_initialized) {
+		uint32 hpd_ctrl;
+		enable_irq(hdmi_msm_state->irq);
+
+		/* set timeout to 4.1ms (max) for hardware debounce */
+		hpd_ctrl = (HDMI_INP(0x0258) & ~0xFFF) | 0xFFF;
+
+		/* Toggle HPD circuit to trigger HPD sense */
+		HDMI_OUTP(0x0258, ~(1 << 28) & hpd_ctrl);
+		HDMI_OUTP(0x0258, (1 << 28) | hpd_ctrl);
+
+		DEV_DBG("%s: (clk, 5V, core, IRQ on) <trigger:%s>\n", __func__,
+			trigger_handler ? "true" : "false");
+
+		if (trigger_handler) {
+			/* Set HPD state machine: ensure at least 2 readouts */
+			mutex_lock(&hdmi_msm_state_mutex);
+			hdmi_msm_state->hpd_stable = 0;
+			hdmi_msm_state->hpd_prev_state = TRUE;
+			mutex_lock(&external_common_state_hpd_mutex);
+			external_common_state->hpd_state = FALSE;
+			mutex_unlock(&external_common_state_hpd_mutex);
+			hdmi_msm_state->hpd_cable_chg_detected = TRUE;
+			mutex_unlock(&hdmi_msm_state_mutex);
+			mod_timer(&hdmi_msm_state->hpd_state_timer,
+				jiffies + HZ/2);
+		}
+
+		hdmi_msm_state->hpd_initialized = TRUE;
+	}
+	hdmi_msm_set_mode(TRUE);
+
+	return 0;
+}
+
+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;
+#ifdef CONFIG_SUSPEND
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->pm_suspended) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_WARN("%s: ignored, pm_suspended\n", __func__);
+		return -ENODEV;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif
+
+	DEV_INFO("power: ON (%dx%d %d)\n", mfd->var_xres, mfd->var_yres,
+		mfd->var_pixclock);
+
+#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 = TRUE;
+		DEV_INFO("HDCP: activating, returning\n");
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+	changed = hdmi_common_get_video_format_from_drv_data(mfd);
+	if (!external_common_state->hpd_feature_on) {
+		int rc = hdmi_msm_hpd_on(true);
+		DEV_INFO("HPD: panel power without 'hpd' feature on\n");
+		if (rc) {
+			DEV_WARN("HPD: activation failed: rc=%d\n", rc);
+			return rc;
+		}
+	}
+	hdmi_msm_audio_info_setup(TRUE, 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())
+		|| changed) {
+		mutex_unlock(&external_common_state_hpd_mutex);
+		hdmi_msm_turn_on();
+	} 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_SUSPEND
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->pm_suspended) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		DEV_WARN("%s: ignored, pm_suspended\n", __func__);
+		return -ENODEV;
+	}
+	mutex_unlock(&hdmi_msm_state_mutex);
+#endif
+
+#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_hpd_off();
+	hdmi_msm_powerdown_phy();
+	hdmi_msm_dump_regs("HDMI-OFF: ");
+	hdmi_msm_hpd_on(false);
+
+	mutex_lock(&external_common_state_hpd_mutex);
+	if (!external_common_state->hpd_feature_on)
+		hdmi_msm_hpd_off();
+	mutex_unlock(&external_common_state_hpd_mutex);
+
+	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 (!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(NULL, "hdmi_app_clk");
+	if (IS_ERR(hdmi_msm_state->hdmi_app_clk)) {
+		DEV_ERR("'hdmi_app_clk' clk not found\n");
+		rc = IS_ERR(hdmi_msm_state->hdmi_app_clk);
+		goto error;
+	}
+
+	hdmi_msm_state->hdmi_m_pclk = clk_get(NULL, "hdmi_m_pclk");
+	if (IS_ERR(hdmi_msm_state->hdmi_m_pclk)) {
+		DEV_ERR("'hdmi_m_pclk' clk not found\n");
+		rc = IS_ERR(hdmi_msm_state->hdmi_m_pclk);
+		goto error;
+	}
+
+	hdmi_msm_state->hdmi_s_pclk = clk_get(NULL, "hdmi_s_pclk");
+	if (IS_ERR(hdmi_msm_state->hdmi_s_pclk)) {
+		DEV_ERR("'hdmi_s_pclk' 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;
+	}
+
+	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;
+	add_timer(&hdmi_msm_state->hpd_state_timer);
+
+#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;
+	add_timer(&hdmi_msm_state->hdcp_timer);
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_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");
+
+	DEV_INFO("HDMI HPD: ON\n");
+
+	rc = hdmi_msm_hpd_on(true);
+	if (rc)
+		goto error;
+
+	if (hdmi_msm_has_hdcp())
+		external_common_state->present_hdcp = TRUE;
+	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
+	}
+
+	queue_work(hdmi_work_queue, &hdmi_msm_state->hpd_read_work);
+	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");
+	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(true);
+	else
+		hdmi_msm_hpd_off();
+
+	return rc;
+}
+
+
+#ifdef CONFIG_SUSPEND
+static int hdmi_msm_device_pm_suspend(struct device *dev)
+{
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (hdmi_msm_state->pm_suspended) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		return 0;
+	}
+
+	DEV_DBG("pm_suspend\n");
+
+	del_timer(&hdmi_msm_state->hpd_state_timer);
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
+	del_timer(&hdmi_msm_state->hdcp_timer);
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+
+	disable_irq(hdmi_msm_state->irq);
+	clk_disable(hdmi_msm_state->hdmi_app_clk);
+	clk_disable(hdmi_msm_state->hdmi_m_pclk);
+	clk_disable(hdmi_msm_state->hdmi_s_pclk);
+
+	hdmi_msm_state->pm_suspended = TRUE;
+	mutex_unlock(&hdmi_msm_state_mutex);
+
+	hdmi_msm_powerdown_phy();
+	hdmi_msm_state->pd->enable_5v(0);
+	hdmi_msm_state->pd->core_power(0, 1);
+	return 0;
+}
+
+static int hdmi_msm_device_pm_resume(struct device *dev)
+{
+	mutex_lock(&hdmi_msm_state_mutex);
+	if (!hdmi_msm_state->pm_suspended) {
+		mutex_unlock(&hdmi_msm_state_mutex);
+		return 0;
+	}
+
+	DEV_DBG("pm_resume\n");
+
+	hdmi_msm_state->pd->core_power(1, 1);
+	hdmi_msm_state->pd->enable_5v(1);
+	clk_enable(hdmi_msm_state->hdmi_app_clk);
+	clk_enable(hdmi_msm_state->hdmi_m_pclk);
+	clk_enable(hdmi_msm_state->hdmi_s_pclk);
+
+	hdmi_msm_state->pm_suspended = FALSE;
+	mutex_unlock(&hdmi_msm_state_mutex);
+	enable_irq(hdmi_msm_state->irq);
+	return 0;
+}
+#else
+#define hdmi_msm_device_pm_suspend	NULL
+#define hdmi_msm_device_pm_resume	NULL
+#endif
+
+static const struct dev_pm_ops hdmi_msm_device_pm_ops = {
+	.suspend = hdmi_msm_device_pm_suspend,
+	.resume = hdmi_msm_device_pm_resume,
+};
+
+static struct platform_driver this_driver = {
+	.probe = hdmi_msm_probe,
+	.remove = hdmi_msm_remove,
+	.driver.name = "hdmi_msm",
+	.driver.pm = &hdmi_msm_device_pm_ops,
+};
+
+static struct msm_fb_panel_data hdmi_msm_panel_data = {
+	.on = hdmi_msm_power_on,
+	.off = hdmi_msm_power_off,
+};
+
+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;
+
+	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
+
+	/*
+	 * 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);
+	INIT_WORK(&hdmi_msm_state->hpd_read_work, hdmi_msm_hpd_read_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 */
+
+	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..41c756f
--- /dev/null
+++ b/drivers/video/msm/hdmi_msm.h
@@ -0,0 +1,84 @@
+/* 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
+
+#define QFPROM_BASE		((uint32)hdmi_msm_state->qfprom_io)
+
+struct hdmi_msm_state_type {
+	boolean panel_power_on;
+	boolean hpd_initialized;
+#ifdef CONFIG_SUSPEND
+	boolean pm_suspended;
+#endif
+	int hpd_stable;
+	boolean hpd_prev_state;
+	boolean hpd_cable_chg_detected;
+	boolean full_auth_done;
+	boolean hpd_during_auth;
+	struct work_struct hpd_state_work, hpd_read_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 */
+
+	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_phy_reset(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
+
+#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..e3f1907
--- /dev/null
+++ b/drivers/video/msm/lcdc.c
@@ -0,0 +1,294 @@
+/* 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/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 <mach/msm_reqs.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(pixel_mdp_clk);
+	clk_disable(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 (mdp_rev != MDP_REV_303) {
+		if (mfd->ebi1_clk)
+			clk_disable(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
+#ifdef CONFIG_MSM_NPA_SYSTEM_BUS
+	pm_qos_rate = MSM_AXI_FLOW_MDP_LCDC_WVGA_2BPP;
+#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;
+#endif
+
+	if (mdp_rev != MDP_REV_303) {
+		if (mfd->ebi1_clk) {
+			clk_set_rate(mfd->ebi1_clk, pm_qos_rate * 1000);
+			clk_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_enable(pixel_mdp_clk);
+	clk_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;
+
+	if (pdev->id == 0) {
+		lcdc_pdata = pdev->dev.platform_data;
+		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))) {
+		printk(KERN_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;
+
+#ifndef CONFIG_MSM_BUS_SCALING
+	mfd->ebi1_clk = clk_get(NULL, "ebi1_lcdc_clk");
+	if (IS_ERR(mfd->ebi1_clk))
+		return PTR_ERR(mfd->ebi1_clk);
+#endif
+	/*
+	 * 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)
+{
+
+	pixel_mdp_clk = clk_get(NULL, "pixel_mdp_clk");
+	if (IS_ERR(pixel_mdp_clk))
+		pixel_mdp_clk = NULL;
+
+	if (pixel_mdp_clk) {
+		pixel_lcdc_clk = clk_get(NULL, "pixel_lcdc_clk");
+		if (IS_ERR(pixel_lcdc_clk)) {
+			printk(KERN_ERR "Couldnt find pixel_lcdc_clk\n");
+			return -EINVAL;
+		}
+	} else {
+		pixel_mdp_clk = clk_get(NULL, "mdp_lcdc_pclk_clk");
+		if (IS_ERR(pixel_mdp_clk)) {
+			printk(KERN_ERR "Couldnt find mdp_lcdc_pclk_clk\n");
+			return -EINVAL;
+		}
+
+		pixel_lcdc_clk = clk_get(NULL, "mdp_lcdc_pad_pclk_clk");
+		if (IS_ERR(pixel_lcdc_clk)) {
+			printk(KERN_ERR "Couldnt find mdp_lcdc_pad_pclk_clk\n");
+			return -EINVAL;
+		}
+	}
+
+	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..b1c3af0
--- /dev/null
+++ b/drivers/video/msm/lcdc_auo_wvga.c
@@ -0,0 +1,413 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
+	if (msm_fb_detect_client(LCDC_AUO_PANEL_NAME)) {
+		pr_err("%s: detect failed\n", __func__);
+		return 0;
+	}
+#endif
+
+	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..b5cce2c
--- /dev/null
+++ b/drivers/video/msm/lcdc_chimei_wxga.c
@@ -0,0 +1,233 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("lcdc_chimei_lvds_wxga"))
+		return 0;
+#endif
+
+	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_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..dccc997
--- /dev/null
+++ b/drivers/video/msm/lcdc_samsung_oled_pt.c
@@ -0,0 +1,590 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
+	if (msm_fb_detect_client("lcdc_samsung_oled")) {
+		pr_err("%s: detect failed\n", __func__);
+		return 0;
+	}
+#endif
+
+	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..b4bf8cf
--- /dev/null
+++ b/drivers/video/msm/lcdc_samsung_wsvga.c
@@ -0,0 +1,272 @@
+/* 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)
+{
+	int bl_level;
+	int ret;
+
+	bl_level = mfd->bl_level;
+
+#ifdef CONFIG_PMIC8058_PWM
+	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;
+
+#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
+	if (msm_fb_detect_client("lcdc_samsung_wsvga"))
+		return 0;
+#endif
+
+	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
new file mode 100644
index 0000000..c061e86
--- /dev/null
+++ b/drivers/video/msm/logo.c
@@ -0,0 +1,97 @@
+/* drivers/video/msm/logo.c
+ *
+ * Show Logo in RLE 565 format
+ *
+ * Copyright (C) 2008 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/module.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/unistd.h>
+#include <linux/syscalls.h>
+
+#include <linux/irq.h>
+#include <asm/system.h>
+
+#define fb_width(fb)	((fb)->var.xres)
+#define fb_height(fb)	((fb)->var.yres)
+#define fb_size(fb)	((fb)->var.xres * (fb)->var.yres * 2)
+
+static void memset16(void *_ptr, unsigned short val, unsigned count)
+{
+	unsigned short *ptr = _ptr;
+	count >>= 1;
+	while (count--)
+		*ptr++ = val;
+}
+
+/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
+int load_565rle_image(char *filename)
+{
+	struct fb_info *info;
+	int fd, count, err = 0;
+	unsigned max;
+	unsigned short *data, *bits, *ptr;
+
+	info = registered_fb[0];
+	if (!info) {
+		printk(KERN_WARNING "%s: Can not access framebuffer\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	fd = sys_open(filename, O_RDONLY, 0);
+	if (fd < 0) {
+		printk(KERN_WARNING "%s: Can not open %s\n",
+			__func__, filename);
+		return -ENOENT;
+	}
+	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) {
+		printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
+		err = -ENOMEM;
+		goto err_logo_close_file;
+	}
+	if (sys_read(fd, (char *)data, count) != count) {
+		err = -EIO;
+		goto err_logo_free_data;
+	}
+
+	max = fb_width(info) * fb_height(info);
+	ptr = data;
+	bits = (unsigned short *)(info->screen_base);
+	while (count > 3) {
+		unsigned n = ptr[0];
+		if (n > max)
+			break;
+		memset16(bits, ptr[1], n << 1);
+		bits += n;
+		max -= n;
+		ptr += 2;
+		count -= 4;
+	}
+
+err_logo_free_data:
+	kfree(data);
+err_logo_close_file:
+	sys_close(fd);
+	return err;
+}
+EXPORT_SYMBOL(load_565rle_image);
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index 178b072..9b9ee94 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-2011, 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,816 +10,578 @@
  *
  * 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/gfp.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 <mach/msm_fb.h>
-#include "mddi_hw.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>
 
-#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);
 
-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 int mddi_off(struct platform_device *pdev);
+static int mddi_on(struct platform_device *pdev);
 
-struct reg_read_info {
-	struct completion done;
-	uint32_t reg;
-	uint32_t status;
-	uint32_t result;
-};
+#ifdef CONFIG_PM
+static int mddi_suspend(struct platform_device *pdev, pm_message_t state);
+static int mddi_resume(struct platform_device *pdev);
+#endif
 
-struct mddi_info {
-	uint16_t flags;
-	uint16_t version;
-	char __iomem *base;
-	int irq;
-	struct clk *clk;
-	struct msm_mddi_client_data client_data;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mddi_early_suspend(struct early_suspend *h);
+static void mddi_early_resume(struct early_suspend *h);
+#endif
 
-	/* 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;
+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;
 
-	spinlock_t int_lock;
-	uint32_t int_enable;
-	uint32_t got_int;
-	wait_queue_head_t int_wait;
+DEFINE_MUTEX(mddi_timer_lock);
 
-	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;
-
-	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;
-};
-
-static void mddi_init_rev_encap(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)
+static int mddi_runtime_suspend(struct device *dev)
 {
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-
-	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)
-{
-	printk(KERN_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)) {
-
-		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:
-			ri = mddi->reg_read;
-			if (ri == 0) {
-				printk(KERN_INFO "rev: got reg %x = %x without "
-						 " pending read\n",
-				       rev->reg.register_address,
-				       rev->reg.register_data_list);
-				break;
-			}
-			if (ri->reg != rev->reg.register_address) {
-				printk(KERN_INFO "rev: got reg %x = %x for "
-						 "wrong register, expected "
-						 "%x\n",
-				       rev->reg.register_address,
-				       rev->reg.register_data_list, ri->reg);
-				break;
-			}
-			mddi->reg_read = NULL;
-			ri->status = 0;
-			ri->result = rev->reg.register_data_list;
-			complete(&ri->done);
-			break;
-		default:
-			printk(KERN_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)
-					printk(KERN_INFO "\n");
-				printk(KERN_INFO " %02x", rev->raw[i]);
-			}
-			printk(KERN_INFO "\n");
-			mddi_reset_rev_encap_ptr(mddi);
-		}
-	} else {
-		printk(KERN_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)
-{
-	uint32_t rev_data_count;
-	uint32_t rev_crc_err_count;
-	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)
-		printk(KERN_INFO "rev_data_count %d\n", rev_data_count);
-
-	if (rev_crc_err_count) {
-		printk(KERN_INFO "rev_crc_err_count %d, INT %x\n",
-		       rev_crc_err_count,  mddi_readl(INT));
-		ri = mddi->reg_read;
-		if (ri == 0) {
-			printk(KERN_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;
-
-	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) {
-		printk(KERN_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);
-	} else {
-		mddi_handle_rev_data(mddi, crev);
-	}
-
-	if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 &&
-	    mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) {
-		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);
-
-	/* 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;
-	}
-
-	if (active & MDDI_INT_IN_HIBERNATION) {
-		mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION);
-		mddi->int_enable |= MDDI_INT_LINK_ACTIVE;
-	}
-
-	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;
-
-	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 "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)
-{
-	mddi_writel(0x0001, VERSION);
-	mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
-	mddi_writel(0x0003, SPM); /* subframes per media */
-	mddi_writel(0x0005, TA1_LEN);
-	mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
-	mddi_writel(0x0096, DRIVE_HI);
-	/* 0x32 normal, 0x50 for Toshiba display */
-	mddi_writel(0x0050, DRIVE_LO);
-	mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
-	mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);
-
-	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 */
-	mddi_writel(0xa850f, PAD_CTL);
-
-
-	/* Need an even number for counts */
-	mddi_writel(0x60006, DRIVER_START_CNT);
-
-	mddi_set_auto_hibernate(&mddi->client_data, 0);
-
-	mddi_writel(MDDI_CMD_DISP_IGNORE, CMD);
-	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);
-	/* 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);
-}
-
-static void mddi_resume(struct msm_mddi_client_data *cdata)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	mddi_set_auto_hibernate(&mddi->client_data, 0);
-	/* turn on the client */
-	if (mddi->power_client)
-		mddi->power_client(&mddi->client_data, 1);
-	/* turn on the clock */
-	clk_enable(mddi->clk);
-	/* set up the local registers */
-	mddi->rev_data_curr = 0;
-	mddi_init_registers(mddi);
-	mddi_writel(mddi->int_enable, INTEN);
-	mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
-	mddi_writel(MDDI_CMD_SEND_RTD, CMD);
-	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-	mddi_set_auto_hibernate(&mddi->client_data, 1);
-}
-
-static int __init mddi_get_client_caps(struct mddi_info *mddi)
-{
-	int i, j;
-
-	/* 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);
-
-	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);
-			mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-			stat = mddi_readl(STAT);
-			printk(KERN_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)
-				break;
-			msleep(1);
-		}
-
-		mddi_writel(CMD_GET_CLIENT_CAP, CMD);
-		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 "mddi_init, timeout waiting for caps\n");
-	}
-	return mddi->flags & FLAG_HAVE_CAPS;
-}
-
-/* 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)
-				printk(KERN_INFO "mddi status: crc_error "
-					"count: %d\n",
-					mddi->status.crc_error_count);
-			else
-				ret = 0;
-			break;
-		} else
-			printk(KERN_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;
-}
-
-
-void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val,
-		       uint32_t reg)
-{
-	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
-					      client_data);
-	struct mddi_llentry *ll;
-	struct mddi_register_access *ra;
-
-	mutex_lock(&mddi->reg_write_lock);
-
-	ll = mddi->reg_write_data;
-
-	ra = &(ll->u.r);
-	ra->length = 14 + 4;
-	ra->type = TYPE_REGISTER_ACCESS;
-	ra->client_id = 0;
-	ra->read_write_info = MDDI_WRITE | 1;
-	ra->crc16 = 0;
-
-	ra->register_address = reg;
-	ra->register_data_list = val;
-
-	ll->flags = 1;
-	ll->header_count = 14;
-	ll->data_count = 4;
-	ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry,
-						   u.r.register_data_list);
-	ll->next = 0;
-	ll->reserved = 0;
-
-	mddi_writel(mddi->reg_write_addr, PRI_PTR);
-
-	mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
-	mutex_unlock(&mddi->reg_write_lock);
-}
-
-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;
-
-	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);
-
-	ri.reg = reg;
-	ri.status = -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);
-
-		/* 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) {
-			printk(KERN_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;
-
-		mddi_writel(MDDI_CMD_SEND_RTD, CMD);
-		mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
-		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
-		printk(KERN_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);
-	mddi->reg_read = NULL;
-	mutex_unlock(&mddi->reg_read_lock);
-	return ri.result;
-}
-
-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;
-
-	/* set up the clocks */
-	mddi->clk = clk_get(&pdev->dev, "mddi_clk");
-	if (IS_ERR(mddi->clk)) {
-		printk(KERN_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;
-	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);
+	dev_dbg(dev, "pm_runtime: suspending...\n");
 	return 0;
 }
 
-static int __devinit mddi_probe(struct platform_device *pdev)
+static int mddi_runtime_resume(struct device *dev)
 {
-	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) {
-		printk(KERN_ERR "mddi: no associated mem resource!\n");
-		return -ENOMEM;
-	}
-	mddi->base = ioremap(resource->start, resource_size(resource));
-	if (!mddi->base) {
-		printk(KERN_ERR "mddi: failed to remap base!\n");
-		ret = -EINVAL;
-		goto error_ioremap;
-	}
-	resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!resource) {
-		printk(KERN_ERR "mddi: no associated irq resource!\n");
-		ret = -EINVAL;
-		goto error_get_irq_resource;
-	}
-	mddi->irq = resource->start;
-	printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base,
-	       mddi->irq);
-	mddi->power_client = pdata->power_client;
-
-	mutex_init(&mddi->reg_write_lock);
-	mutex_init(&mddi->reg_read_lock);
-	spin_lock_init(&mddi->int_lock);
-	init_waitqueue_head(&mddi->int_wait);
-
-	ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate);
-	if (ret) {
-		printk(KERN_ERR "mddi: failed to setup clock!\n");
-		goto error_clk_setup;
-	}
-
-	ret = mddi_rev_data_setup(mddi);
-	if (ret) {
-		printk(KERN_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) {
-		printk(KERN_ERR "mddi: failed to request enable irq!\n");
-		goto error_request_irq;
-	}
-
-	/* turn on the mddi client bridge chip */
-	if (mddi->power_client)
-		mddi->power_client(&mddi->client_data, 1);
-
-	/* 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) {
-		printk(KERN_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)) {
-		printk(KERN_INFO "mddi: no client found\n");
-		/* power down the panel */
-		mddi_writel(MDDI_CMD_POWERDOWN, CMD);
-		printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
-		msleep(100);
-		printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
-		return 0;
-	}
-	mddi_set_auto_hibernate(&mddi->client_data, 1);
-
-	if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 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)
-		mddi->client_pdev.name = "mddi_c_dummy";
-	printk(KERN_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_read = mddi_remote_read;
-	mddi->client_data.auto_hibernate = mddi_set_auto_hibernate;
-	mddi->client_data.fb_resource = pdata->fb_resource;
-	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 {
-		printk(KERN_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;
-	printk(KERN_INFO "mddi: publish: %s\n", mddi->client_name);
-	platform_device_register(&mddi->client_pdev);
+	dev_dbg(dev, "pm_runtime: resuming...\n");
 	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:
-error_get_irq_resource:
-	iounmap(mddi->base);
-error_ioremap:
-
-	printk(KERN_INFO "mddi: mddi_init() failed (%d)\n", ret);
-	return ret;
 }
 
+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,
+};
+
+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(mddi_clk);
+		pmdh_clk_status = 0;
+	}
+	if (mddi_pclk)
+		clk_disable(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_enable(mddi_clk);
+		pmdh_clk_status = 1;
+	}
+	if (mddi_pclk)
+		clk_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(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 */
+		if (!clk_set_min_rate(mddi_clk, 49000000)) {
+			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_min_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);
+
+	if (clk_set_min_rate(mddi_clk, clk_rate) < 0)
+		printk(KERN_ERR "%s: clk_set_min_rate failed\n",
+			__func__);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(2);
+#else
+	if (mfd->ebi1_clk)
+		clk_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;
+
+	if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
+		mddi_pdata = pdev->dev.platform_data;
+
+		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);
+
+	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);
+#ifndef CONFIG_MSM_BUS_SCALING
+	mfd->ebi1_clk = clk_get(NULL, "ebi1_mddi_clk");
+	if (IS_ERR(mfd->ebi1_clk))
+		return PTR_ERR(mfd->ebi1_clk);
+	clk_set_rate(mfd->ebi1_clk, 65000000);
+#endif
+	/*
+	 * 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);
+
+	if (clk_set_min_rate(mddi_clk, 0) < 0)
+		printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
+
+	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);
+
+	if (clk_set_min_rate(mddi_clk, 0) < 0)
+		printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
+
+	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;
+	pmdh_clk_status = 0;
+
+	mddi_clk = clk_get(NULL, "mddi_clk");
+	if (IS_ERR(mddi_clk)) {
+		printk(KERN_ERR "can't find mddi_clk\n");
+		return PTR_ERR(mddi_clk);
+	}
+	ret = clk_set_min_rate(mddi_clk, 49000000);
+	if (ret)
+		printk(KERN_ERR "Can't set mddi_clk min rate to 49000000\n");
+
+	printk(KERN_INFO "mddi_clk init rate is %lu\n",
+		clk_get_rate(mddi_clk));
+	mddi_pclk = clk_get(NULL, "mddi_pclk");
+	if (IS_ERR(mddi_pclk))
+		mddi_pclk = NULL;
+	pmdh_clk_enable();
+
+	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 d2a091c..ebbae87 100644
--- a/drivers/video/msm/mddi_client_dummy.c
+++ b/drivers/video/msm/mddi_client_dummy.c
@@ -15,7 +15,6 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index f239f4a..c9e9349 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -21,7 +21,6 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/gpio.h>
-#include <linux/slab.h>
 #include <mach/msm_fb.h>
 
 static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
index f9bc932..8868781 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -21,7 +21,6 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <mach/msm_fb.h>
 
 
@@ -60,6 +59,7 @@
 	struct msm_panel_data panel_data;
 	struct msmfb_callback *toshiba_callback;
 	int toshiba_got_int;
+	int irq;
 };
 
 
@@ -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;
-	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);
-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..0ecd593
--- /dev/null
+++ b/drivers/video/msm/mddi_ext.c
@@ -0,0 +1,363 @@
+/* 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);
+
+	if (clk_set_min_rate(mddi_ext_clk, clk_rate) < 0)
+		printk(KERN_ERR "%s: clk_set_min_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;
+
+		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;
+
+	if (clk_set_min_rate(mddi_ext_clk, 0) < 0)
+		printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
+
+	clk_disable(mddi_ext_clk);
+	if (mddi_ext_pclk)
+		clk_disable(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_enable(mddi_ext_clk);
+	if (mddi_ext_pclk)
+		clk_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;
+
+	mddi_ext_clk = clk_get(NULL, "emdh_clk");
+	if (IS_ERR(mddi_ext_clk)) {
+		printk(KERN_ERR "can't find emdh_clk\n");
+		return PTR_ERR(mddi_ext_clk);
+	}
+	clk_enable(mddi_ext_clk);
+
+	mddi_ext_pclk = clk_get(NULL, "emdh_pclk");
+	if (IS_ERR(mddi_ext_pclk))
+		mddi_ext_pclk = NULL;
+	else
+		clk_enable(mddi_ext_pclk);
+
+	ret = mddi_ext_register_driver();
+	if (ret) {
+		clk_disable(mddi_ext_clk);
+		clk_put(mddi_ext_clk);
+		if (mddi_ext_pclk) {
+			clk_disable(mddi_ext_pclk);
+			clk_put(mddi_ext_pclk);
+		}
+		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_hw.h b/drivers/video/msm/mddi_hw.h
index 45cc01f..47bb449 100644
--- a/drivers/video/msm/mddi_hw.h
+++ b/drivers/video/msm/mddi_hw.h
@@ -53,6 +53,9 @@
 #define MDDI_MF_CNT             0x0084
 #define MDDI_CURR_REV_PTR       0x0088
 #define MDDI_CORE_VER           0x008c
+#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
@@ -125,8 +128,14 @@
 /* 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_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
 #define MDDI_HOST_REV_RATE_DIV  0x0002
+#endif
 
 
 struct __attribute__((packed)) mddi_rev_packet {
diff --git a/drivers/video/msm/mddi_orise.c b/drivers/video/msm/mddi_orise.c
new file mode 100644
index 0000000..dc913e6
--- /dev/null
+++ b/drivers/video/msm/mddi_orise.c
@@ -0,0 +1,127 @@
+/* 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 "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.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..5269b22
--- /dev/null
+++ b/drivers/video/msm/mddi_prism.c
@@ -0,0 +1,111 @@
+/* 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 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->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..330e679
--- /dev/null
+++ b/drivers/video/msm/mddi_quickvx.c
@@ -0,0 +1,718 @@
+/* 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 <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->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..b2a7188
--- /dev/null
+++ b/drivers/video/msm/mddi_sharp.c
@@ -0,0 +1,900 @@
+/* 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"
+
+#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->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..794edff
--- /dev/null
+++ b/drivers/video/msm/mddi_toshiba_vga.c
@@ -0,0 +1,133 @@
+/* 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"
+#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.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..ad4ce46
--- /dev/null
+++ b/drivers/video/msm/mddi_toshiba_wvga.c
@@ -0,0 +1,60 @@
+/* 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"
+#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.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..edf739d
--- /dev/null
+++ b/drivers/video/msm/mddi_toshiba_wvga_pt.c
@@ -0,0 +1,68 @@
+/* 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"
+#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 = 6096; /* adjust refx100 to prevent tearing */
+	pinfo.lcd.v_back_porch = 2;     /* vsw=1 + vbp = 2 */
+	pinfo.lcd.v_front_porch = 3;
+	pinfo.lcd.v_pulse_width = 1;
+	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..4989d35
--- /dev/null
+++ b/drivers/video/msm/mddihosti.c
@@ -0,0 +1,2304 @@
+/* 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/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);
+	}
+
+#if 0
+	switch (mddi_client_capability_pkt.Mfr_Name) {
+	case 0x4474:
+		if ((mddi_client_capability_pkt.Product_Code != 0x8960) &&
+		    (target == DISPLAY_1)) {
+			ret = PRISM_WVGA;
+		}
+		break;
+
+	case 0xD263:
+		if (target == DISPLAY_1)
+			ret = TOSHIBA_VGA_PRIM;
+		else if (target == DISPLAY_2)
+			ret = TOSHIBA_QCIF_SECD;
+		break;
+
+	case 0:
+		if (mddi_client_capability_pkt.Product_Code == 0x8835) {
+			if (target == DISPLAY_1)
+				ret = SHARP_QVGA_PRIM;
+			else if (target == DISPLAY_2)
+				ret = SHARP_128x128_SECD;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	if ((!client_detection_try) && (ret != TOSHIBA_VGA_PRIM)
+	    && (ret != TOSHIBA_QCIF_SECD)) {
+		/* Not a Toshiba display, so change drive_lo back to default value */
+		mddi_host_reg_out(DRIVE_LO, 0x0032);
+	}
+#endif
+
+#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 c3636d5..8df57ae 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-2011, Code Aurora Forum. All rights reserved.
  * Copyright (C) 2007 Google Incorporated
  *
  * This software is licensed under the terms of the GNU General Public
@@ -15,507 +15,1659 @@
  * 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/file.h>
-#include <linux/major.h>
-#include <linux/slab.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 <mach/msm_iomap.h>
-#include <mach/msm_fb.h>
-#include <linux/platform_device.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#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
+#include "mipi_dsi.h"
 
-#include "mdp_hw.h"
+uint32 mdp4_extn_disp;
 
-struct class *mdp_class;
+static struct clk *mdp_clk;
+static struct clk *mdp_pclk;
+static struct clk *mdp_axi_clk;
+static struct clk *mdp_lut_clk;
+int mdp_rev;
 
-#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000)
+struct regulator *footswitch;
 
-static uint16_t mdp_default_ccs[] = {
-	0x254, 0x000, 0x331, 0x254, 0xF38, 0xE61, 0x254, 0x409, 0x000,
-	0x010, 0x080, 0x080
-};
+struct completion mdp_ppp_comp;
+struct semaphore mdp_ppp_mutex;
+struct semaphore mdp_pipe_ctrl_mutex;
 
-static DECLARE_WAIT_QUEUE_HEAD(mdp_dma2_waitqueue);
-static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue);
-static struct msmfb_callback *dma_callback;
-static struct clk *clk;
-static unsigned int mdp_irq_mask;
-static DEFINE_SPINLOCK(mdp_lock);
-DEFINE_MUTEX(mdp_mutex);
+unsigned long mdp_timer_duration = (HZ/20);   /* 50 msecond */
 
-static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
+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;
+
+/*
+ * 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
+uint32 mdp_intr_mask = MDP_ANY_INTR_MASK;
+#endif
+
+MDP_BLOCK_TYPE mdp_debug[MDP_MAX_BLOCK];
+
+atomic_t mdp_block_power_cnt[MDP_MAX_BLOCK];
+
+spinlock_t mdp_spin_lock;
+struct workqueue_struct *mdp_dma_wq;	/*mdp dma wq */
+struct workqueue_struct *mdp_vsync_wq;	/*mdp vsync 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;
+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;
+ulong mdp4_display_intf;
+#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
+static struct mdp_dma_data dma3_data;
+
+extern ktime_t mdp_dma2_last_update_time;
+
+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;
+
+#ifdef CONFIG_FB_MSM_LCDC
+extern int first_pixel_start_x;
+extern int first_pixel_start_y;
+#endif
+
+#ifdef MSM_FB_ENABLE_DBGFS
+struct dentry *mdp_dir;
+#endif
+
+#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
+
+struct timeval mdp_dma2_timeval;
+struct timeval mdp_ppp_timeval;
+
+#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
+DEFINE_MUTEX(mdp_lut_push_sem);
+static int mdp_lut_i;
+static int mdp_lut_hw_update(struct fb_cmap *cmap)
 {
-	unsigned long irq_flags;
-	int ret = 0;
+	int i;
+	u16 *c[3];
+	u16 r, g, b;
 
-	BUG_ON(!mask);
+	c[0] = cmap->green;
+	c[1] = cmap->blue;
+	c[2] = cmap->red;
 
-	spin_lock_irqsave(&mdp_lock, irq_flags);
-	/* if the mask bits are already set return an error, this interrupt
-	 * is already enabled */
-	if (mdp_irq_mask & mask) {
-		printk(KERN_ERR "mdp irq already on already on %x %x\n",
-		       mdp_irq_mask, mask);
-		ret = -1;
-	}
-	/* if the mdp irq is not already enabled enable it */
-	if (!mdp_irq_mask) {
-		if (clk)
-			clk_enable(clk);
-		enable_irq(mdp->irq);
+	for (i = 0; i < cmap->len; i++) {
+		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;
+
+#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)));
 	}
 
-	/* update the irq mask to reflect the fact that the interrupt is
-	 * enabled */
-	mdp_irq_mask |= mask;
-	spin_unlock_irqrestore(&mdp_lock, irq_flags);
-	return ret;
+	return 0;
 }
 
-static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
+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)
 {
-	/* this interrupt is already disabled! */
-	if (!(mdp_irq_mask & mask)) {
-		printk(KERN_ERR "mdp irq already off %x %x\n",
-		       mdp_irq_mask, mask);
-		return -1;
+	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 int mdp_lut_update_lcdc(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);
+
+	if (ret) {
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+		return ret;
 	}
-	/* update the irq mask to reflect the fact that the interrupt is
-	 * disabled */
-	mdp_irq_mask &= ~(mask);
-	/* if no one is waiting on the interrupt, disable it */
-	if (!mdp_irq_mask) {
-		disable_irq_nosync(mdp->irq);
-		if (clk)
-			clk_disable(clk);
+
+	MDP_OUTP(MDP_BASE + 0x90070, (mdp_lut_i << 10) | 0x17);
+	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)
+{
+	if (mdp_lut_push) {
+		mutex_lock(&mdp_lut_push_sem);
+		mdp_lut_push = 0;
+		MDP_OUTP(MDP_BASE + 0x90070,
+				(mdp_lut_push_i << 10) | 0x17);
+		mutex_unlock(&mdp_lut_push_sem);
+	}
+}
+
+#define MDP_HIST_MAX_BIN 32
+static __u32 mdp_hist_r[MDP_HIST_MAX_BIN];
+static __u32 mdp_hist_g[MDP_HIST_MAX_BIN];
+static __u32 mdp_hist_b[MDP_HIST_MAX_BIN];
+
+#ifdef CONFIG_FB_MSM_MDP40
+struct mdp_histogram mdp_hist;
+struct completion mdp_hist_comp;
+boolean mdp_is_hist_start = FALSE;
+#else
+static struct mdp_histogram mdp_hist;
+static struct completion mdp_hist_comp;
+static boolean mdp_is_hist_start = FALSE;
+#endif
+static DEFINE_MUTEX(mdp_hist_mutex);
+
+int mdp_histogram_ctrl(boolean en)
+{
+	unsigned long flag;
+	boolean hist_start;
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	hist_start = mdp_is_hist_start;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	if (hist_start == TRUE) {
+		if (en == TRUE) {
+			mdp_enable_irq(MDP_HISTOGRAM_TERM);
+			mdp_hist.frame_cnt = 1;
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+#ifdef CONFIG_FB_MSM_MDP40
+			MDP_OUTP(MDP_BASE + 0x95010, 1);
+			MDP_OUTP(MDP_BASE + 0x9501c, INTR_HIST_DONE);
+			MDP_OUTP(MDP_BASE + 0x95004, 1);
+			MDP_OUTP(MDP_BASE + 0x95000, 1);
+#else
+			MDP_OUTP(MDP_BASE + 0x94004, 1);
+			MDP_OUTP(MDP_BASE + 0x94000, 1);
+#endif
+			mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF,
+					FALSE);
+		} else
+			mdp_disable_irq(MDP_HISTOGRAM_TERM);
 	}
 	return 0;
 }
 
-static int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
+int mdp_start_histogram(struct fb_info *info)
 {
-	unsigned long irq_flags;
-	int ret;
+	unsigned long flag;
 
-	spin_lock_irqsave(&mdp_lock, irq_flags);
-	ret = locked_disable_mdp_irq(mdp, mask);
-	spin_unlock_irqrestore(&mdp_lock, irq_flags);
+	int ret = 0;
+	mutex_lock(&mdp_hist_mutex);
+	if (mdp_is_hist_start == TRUE) {
+		printk(KERN_ERR "%s histogram already started\n", __func__);
+		ret = -EPERM;
+		goto mdp_hist_start_err;
+	}
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_is_hist_start = TRUE;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_HISTOGRAM_TERM);
+	mdp_hist.frame_cnt = 1;
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+#ifdef CONFIG_FB_MSM_MDP40
+	MDP_OUTP(MDP_BASE + 0x95004, 1);
+	MDP_OUTP(MDP_BASE + 0x95000, 1);
+#else
+	MDP_OUTP(MDP_BASE + 0x94004, 1);
+	MDP_OUTP(MDP_BASE + 0x94000, 1);
+#endif
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+mdp_hist_start_err:
+	mutex_unlock(&mdp_hist_mutex);
+	return ret;
+
+}
+int mdp_stop_histogram(struct fb_info *info)
+{
+	unsigned long flag;
+	int ret = 0;
+	mutex_lock(&mdp_hist_mutex);
+	if (!mdp_is_hist_start) {
+		printk(KERN_ERR "%s histogram already stopped\n", __func__);
+		ret = -EPERM;
+		goto mdp_hist_stop_err;
+	}
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_is_hist_start = FALSE;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	/* disable the irq for histogram since we handled it
+	   when the control reaches here */
+	mdp_disable_irq(MDP_HISTOGRAM_TERM);
+
+mdp_hist_stop_err:
+	mutex_unlock(&mdp_hist_mutex);
 	return ret;
 }
 
-static irqreturn_t mdp_isr(int irq, void *data)
+static int mdp_do_histogram(struct fb_info *info, struct mdp_histogram *hist)
 {
-	uint32_t status;
-	unsigned long irq_flags;
-	struct mdp_info *mdp = data;
+	int ret = 0;
 
-	spin_lock_irqsave(&mdp_lock, irq_flags);
+	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) {
+		printk(KERN_ERR "%s histogram not started\n", __func__);
+		mutex_unlock(&mdp_hist_mutex);
+		return -EPERM;
+	}
+	mutex_unlock(&mdp_hist_mutex);
 
-	status = mdp_readl(mdp, MDP_INTR_STATUS);
-	mdp_writel(mdp, status, MDP_INTR_CLEAR);
+	INIT_COMPLETION(mdp_hist_comp);
 
-	status &= mdp_irq_mask;
-	if (status & DL0_DMA2_TERM_DONE) {
-		if (dma_callback) {
-			dma_callback->func(dma_callback);
-			dma_callback = NULL;
-		}
-		wake_up(&mdp_dma2_waitqueue);
+	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);
+
+	if (hist->r) {
+		ret = copy_to_user(hist->r, mdp_hist.r, hist->bin_cnt*4);
+		if (ret)
+			goto hist_err;
+	}
+	if (hist->g) {
+		ret = copy_to_user(hist->g, mdp_hist.g, hist->bin_cnt*4);
+		if (ret)
+			goto hist_err;
+	}
+	if (hist->b) {
+		ret = copy_to_user(hist->b, mdp_hist.b, hist->bin_cnt*4);
+		if (ret)
+			goto hist_err;
+	}
+	return 0;
+
+hist_err:
+	printk(KERN_ERR "%s: invalid hist buffer\n", __func__);
+	return ret;
+}
+#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__);
 	}
 
-	if (status & DL0_ROI_DONE)
-		wake_up(&mdp_ppp_waitqueue);
+	return ret;
+}
 
-	if (status)
-		locked_disable_mdp_irq(mdp, status);
+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();
+
+	/* kick off PPP engine */
+	if (term == MDP_PPP_TERM) {
+		if (mdp_debug[MDP_PPP_BLOCK])
+			jiffies_to_timeval(jiffies, &mdp_ppp_timeval);
+
+		/* let's turn on PPP block */
+		mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+		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);
+
+		if (mdp_debug[MDP_PPP_BLOCK]) {
+			struct timeval now;
+
+			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 */
+#if 0
+		mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+#endif
+#ifdef CONFIG_FB_MSM_MDP22
+		outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x0044, 0x0);/* start DMA */
+#else
+		mdp_lut_enable();
+
+#ifdef CONFIG_FB_MSM_MDP40
+		outpdw(MDP_BASE + 0x000c, 0x0);	/* start DMA */
+#else
+		outpdw(MDP_BASE + 0x0044, 0x0);	/* start DMA */
+
+#ifdef CONFIG_FB_MSM_MDP303
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+		mipi_dsi_cmd_mdp_sw_trigger();
+#endif
+
+#endif
+
+#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
+	} 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
+}
+static int mdp_clk_rate;
+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)
+{
+	mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+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(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(mdp_pclk);
+					MSM_FB_DEBUG("MDP PCLK OFF\n");
+				}
+				if (mdp_axi_clk != NULL)
+					clk_disable(mdp_axi_clk);
+				if (mdp_lut_clk != NULL)
+					clk_disable(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_enable(mdp_clk);
+				MSM_FB_DEBUG("MDP CLK ON\n");
+			}
+			if (mdp_pclk != NULL) {
+				clk_enable(mdp_pclk);
+				MSM_FB_DEBUG("MDP PCLK ON\n");
+			}
+			if (mdp_axi_clk != NULL)
+				clk_enable(mdp_axi_clk);
+			if (mdp_lut_clk != NULL)
+				clk_enable(mdp_lut_clk);
+			mdp_vsync_clk_enable();
+		}
+		up(&mdp_pipe_ctrl_mutex);
+	}
+}
+
+#ifndef CONFIG_FB_MSM_MDP40
+irqreturn_t mdp_isr(int irq, void *ptr)
+{
+	uint32 mdp_interrupt = 0;
+	struct mdp_dma_data *dma;
+
+	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;
+
+		/* 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
+		if (mdp_interrupt & MDP_HIST_DONE) {
+			outp32(MDP_BASE + 0x94018, 0x3);
+			outp32(MDP_INTR_CLEAR, MDP_HIST_DONE);
+			if (mdp_hist.r)
+				memcpy(mdp_hist.r, MDP_BASE + 0x94100,
+						mdp_hist.bin_cnt*4);
+			if (mdp_hist.g)
+				memcpy(mdp_hist.g, MDP_BASE + 0x94200,
+						mdp_hist.bin_cnt*4);
+			if (mdp_hist.b)
+				memcpy(mdp_hist.b, MDP_BASE + 0x94300,
+						mdp_hist.bin_cnt*4);
+			complete(&mdp_hist_comp);
+			if (mdp_is_hist_start == TRUE) {
+				MDP_OUTP(MDP_BASE + 0x94004,
+						 mdp_hist.frame_cnt);
+				MDP_OUTP(MDP_BASE + 0x94000, 1);
+			}
+		}
+
+		/* 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.*/
+			MDP_OUTP(MDP_BASE + 0x94010, 1);
+			MDP_OUTP(MDP_BASE + 0x9401c, 2);
+			if (mdp_is_hist_start == TRUE) {
+				MDP_OUTP(MDP_BASE + 0x94004,
+						 mdp_hist.frame_cnt);
+				MDP_OUTP(MDP_BASE + 0x94000, 1);
+			}
+		}
+		/* LCDC Frame Start */
+		if (mdp_interrupt & LCDC_FRAME_START) {
+			/* let's disable LCDC interrupt */
+			mdp_intr_mask &= ~LCDC_FRAME_START;
+			outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+
+			dma = &dma2_data;
+			if (dma->waiting) {
+				dma->waiting = FALSE;
+				complete(&dma->comp);
+			}
+		}
+
+		/* 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 uint32_t mdp_check_mask(uint32_t mask)
+static void mdp_drv_init(void)
 {
-	uint32_t ret;
-	unsigned long irq_flags;
+	int i;
 
-	spin_lock_irqsave(&mdp_lock, irq_flags);
-	ret = mdp_irq_mask & mask;
-	spin_unlock_irqrestore(&mdp_lock, irq_flags);
-	return ret;
-}
-
-static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq)
-{
-	int ret = 0;
-	unsigned long irq_flags;
-
-	wait_event_timeout(*wq, !mdp_check_mask(mask), HZ);
-
-	spin_lock_irqsave(&mdp_lock, irq_flags);
-	if (mdp_irq_mask & mask) {
-		locked_disable_mdp_irq(mdp, mask);
-		printk(KERN_WARNING "timeout waiting for mdp to complete %x\n",
-		       mask);
-		ret = -ETIMEDOUT;
-	}
-	spin_unlock_irqrestore(&mdp_lock, irq_flags);
-
-	return ret;
-}
-
-void mdp_dma_wait(struct mdp_device *mdp_dev)
-{
-#define MDP_MAX_TIMEOUTS 20
-	static int timeout_count;
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-
-	if (mdp_wait(mdp, DL0_DMA2_TERM_DONE, &mdp_dma2_waitqueue) == -ETIMEDOUT)
-		timeout_count++;
-	else
-		timeout_count = 0;
-
-	if (timeout_count > MDP_MAX_TIMEOUTS) {
-		printk(KERN_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);
-}
-
-void mdp_dma_to_mddi(struct mdp_info *mdp, uint32_t addr, uint32_t stride,
-		     uint32_t width, uint32_t height, uint32_t x, uint32_t y,
-		     struct msmfb_callback *callback)
-{
-	uint32_t dma2_cfg;
-	uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */
-
-	if (enable_mdp_irq(mdp, DL0_DMA2_TERM_DONE)) {
-		printk(KERN_ERR "mdp_dma_to_mddi: busy\n");
-		return;
+	for (i = 0; i < MDP_MAX_BLOCK; i++) {
+		mdp_debug[i] = 0;
 	}
 
-	dma_callback = callback;
+	/* 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_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq");
+	INIT_DELAYED_WORK(&mdp_pipe_ctrl_worker,
+			  mdp_pipe_ctrl_workqueue_handler);
 
-	dma2_cfg = DMA_PACK_TIGHT |
-		DMA_PACK_ALIGN_LSB |
-		DMA_PACK_PATTERN_RGB |
-		DMA_OUT_SEL_AHB |
-		DMA_IBUF_NONCONTIGUOUS;
+	/* initialize semaphore */
+	init_completion(&mdp_ppp_comp);
+	sema_init(&mdp_ppp_mutex, 1);
+	sema_init(&mdp_pipe_ctrl_mutex, 1);
 
-	dma2_cfg |= DMA_IBUF_FORMAT_RGB565;
+	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);
 
-	dma2_cfg |= DMA_OUT_SEL_MDDI;
+	dma3_data.busy = FALSE;
+	dma3_data.waiting = FALSE;
+	init_completion(&dma3_data.comp);
+	sema_init(&dma3_data.mutex, 1);
 
-	dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
+	dma_s_data.busy = FALSE;
+	dma_s_data.waiting = FALSE;
+	init_completion(&dma_s_data.comp);
+	sema_init(&dma_s_data.mutex, 1);
 
-	dma2_cfg |= DMA_DITHER_EN;
+#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
 
-	/* 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);
+#ifndef CONFIG_FB_MSM_MDP22
+	init_completion(&mdp_hist_comp);
+#endif
 
-	/* 666 18BPP */
-	dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
-
-	/* 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, (MDDI_VDO_PACKET_DESC << 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);
-}
-
-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);
-
-	if (interface == MSM_MDDI_PMDH_INTERFACE) {
-		mdp_dma_to_mddi(mdp, addr, stride, width, height, x, y,
-				callback);
-	}
-}
-
-int get_img(struct mdp_img *img, struct fb_info *info,
-	    unsigned long *start, unsigned long *len,
-	    struct file **filep)
-{
-	int put_needed, ret = 0;
-	struct file *file;
-
-	file = fget_light(img->memory_id, &put_needed);
-	if (file == NULL)
-		return -1;
-
-	if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
-		*start = info->fix.smem_start;
-		*len = info->fix.smem_len;
-	} else
-		ret = -1;
-	fput_light(file, put_needed);
-
-	return ret;
-}
-
-void put_img(struct file *src_file, struct file *dst_file)
-{
-}
-
-int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
-	     struct mdp_blit_req *req)
-{
-	int ret;
-	unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0;
-	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
-	struct file *src_file = 0, *dst_file = 0;
-
-	/* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */
-	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 -EINVAL;
-
-	/* do this first so that if this fails, the caller can always
-	 * safely call put_img */
-	if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) {
-		printk(KERN_ERR "mpd_ppp: could not retrieve src image from "
-				"memory\n");
-		return -EINVAL;
+	/* initializing mdp power block counter to 0 */
+	for (i = 0; i < MDP_MAX_BLOCK; i++) {
+		atomic_set(&mdp_block_power_cnt[i], 0);
 	}
 
-	if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) {
-		printk(KERN_ERR "mpd_ppp: could not retrieve dst image from "
-				"memory\n");
-		return -EINVAL;
-	}
-	mutex_lock(&mdp_mutex);
+#ifdef MSM_FB_ENABLE_DBGFS
+	{
+		struct dentry *root;
+		char sub_name[] = "mdp";
 
-	/* transp_masking unimplemented */
-	req->transp_mask = MDP_TRANSP_NOP;
-	if (unlikely((req->transp_mask != MDP_TRANSP_NOP ||
-		      req->alpha != MDP_ALPHA_NOP ||
-		      HAS_ALPHA(req->src.format)) &&
-		     (req->flags & MDP_ROT_90 &&
-		      req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) {
-		int i;
-		unsigned int tiles = req->dst_rect.h / 16;
-		unsigned int remainder = req->dst_rect.h % 16;
-		req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h;
-		req->dst_rect.h = 16;
-		for (i = 0; i < tiles; i++) {
-			enable_mdp_irq(mdp, DL0_ROI_DONE);
-			ret = mdp_ppp_blit(mdp, req, src_file, src_start,
-					   src_len, dst_file, dst_start,
-					   dst_len);
-			if (ret)
-				goto err_bad_blit;
-			ret = mdp_ppp_wait(mdp);
-			if (ret)
-				goto err_wait_failed;
-			req->dst_rect.y += 16;
-			req->src_rect.x += req->src_rect.w;
+		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
+			}
 		}
-		if (!remainder)
-			goto end;
-		req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h;
-		req->dst_rect.h = remainder;
 	}
-	enable_mdp_irq(mdp, DL0_ROI_DONE);
-	ret = mdp_ppp_blit(mdp, req, src_file, src_start, src_len, dst_file,
-			   dst_start,
-			   dst_len);
-	if (ret)
-		goto err_bad_blit;
-	ret = mdp_ppp_wait(mdp);
-	if (ret)
-		goto err_wait_failed;
-end:
-	put_img(src_file, dst_file);
-	mutex_unlock(&mdp_mutex);
+#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;
-err_bad_blit:
-	disable_mdp_irq(mdp, DL0_ROI_DONE);
-err_wait_failed:
-	put_img(src_file, dst_file);
-	mutex_unlock(&mdp_mutex);
-	return ret;
 }
 
-void mdp_set_grp_disp(struct mdp_device *mdp_dev, unsigned disp_id)
+static int mdp_runtime_resume(struct device *dev)
 {
-	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);
-}
-
-int register_mdp_client(struct class_interface *cint)
-{
-	if (!mdp_class) {
-		pr_err("mdp: no mdp_class when registering mdp client\n");
-		return -ENODEV;
-	}
-	cint->class = mdp_class;
-	return class_interface_register(cint);
-}
-
-#include "mdp_csc_table.h"
-#include "mdp_scale_tables.h"
-
-int mdp_probe(struct platform_device *pdev)
-{
-	struct resource *resource;
-	int ret;
-	int n;
-	struct mdp_info *mdp;
-
-	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!resource) {
-		pr_err("mdp: can not get mdp mem resource!\n");
-		return -ENOMEM;
-	}
-
-	mdp = kzalloc(sizeof(struct mdp_info), GFP_KERNEL);
-	if (!mdp)
-		return -ENOMEM;
-
-	mdp->irq = platform_get_irq(pdev, 0);
-	if (mdp->irq < 0) {
-		pr_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) {
-		printk(KERN_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;
-	mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp;
-
-	clk = clk_get(&pdev->dev, "mdp_clk");
-	if (IS_ERR(clk)) {
-		printk(KERN_INFO "mdp: failed to get mdp clk");
-		return PTR_ERR(clk);
-	}
-
-	ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
-	if (ret)
-		goto error_request_irq;
-	disable_irq(mdp->irq);
-	mdp_irq_mask = 0;
-
-	/* debug interface write access */
-	mdp_writel(mdp, 1, 0x60);
-
-	mdp_writel(mdp, MDP_ANY_INTR_MASK, MDP_INTR_ENABLE);
-	mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);
-
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
-
-	for (n = 0; n < ARRAY_SIZE(csc_table); n++)
-		mdp_writel(mdp, csc_table[n].val, csc_table[n].reg);
-
-	/* clear up unused fg/main registers */
-	/* comp.plane 2&3 ystride */
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);
-
-	/* unpacked pattern */
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);
-
-	/* comp.plane 2 & 3 */
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);
-
-	/* clear unused bg registers */
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
-	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);
-
-	for (n = 0; n < ARRAY_SIZE(mdp_upscale_table); n++)
-		mdp_writel(mdp, mdp_upscale_table[n].val,
-		       mdp_upscale_table[n].reg);
-
-	for (n = 0; n < 9; n++)
-		mdp_writel(mdp, mdp_default_ccs[n], 0x40440 + 4 * n);
-	mdp_writel(mdp, mdp_default_ccs[9], 0x40500 + 4 * 0);
-	mdp_writel(mdp, mdp_default_ccs[10], 0x40500 + 4 * 0);
-	mdp_writel(mdp, mdp_default_ccs[11], 0x40500 + 4 * 0);
-
-	/* 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;
+	dev_dbg(dev, "pm_runtime: resuming...\n");
 	return 0;
-
-error_device_register:
-	free_irq(mdp->irq, mdp);
-error_request_irq:
-	iounmap(mdp->base);
-error_get_irq:
-error_ioremap:
-	kfree(mdp);
-	return ret;
 }
 
-static struct platform_driver msm_mdp_driver = {
-	.probe = mdp_probe,
-	.driver = {.name = "msm_mdp"},
+static struct dev_pm_ops mdp_dev_pm_ops = {
+	.runtime_suspend = mdp_runtime_suspend,
+	.runtime_resume = mdp_runtime_resume,
 };
 
-static int __init mdp_init(void)
+
+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)
 {
-	mdp_class = class_create(THIS_MODULE, "msm_mdp");
-	if (IS_ERR(mdp_class)) {
-		printk(KERN_ERR "Error creating mdp class\n");
-		return PTR_ERR(mdp_class);
-	}
-	return platform_driver_register(&msm_mdp_driver);
+	int ret = 0;
+	mdp_histogram_ctrl(FALSE);
+
+	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);
+
+	return ret;
 }
 
-subsys_initcall(mdp_init);
+static int mdp_on(struct platform_device *pdev)
+{
+	int ret = 0;
+#ifdef CONFIG_FB_MSM_MDP40
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	if (is_mdp4_hw_reset()) {
+		mdp4_hw_init();
+		outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+#endif
+	mdp_histogram_ctrl(TRUE);
+
+	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);
+	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(mdp_pdata->hw_revision_addr, 0x16);
+
+	if (cp == NULL)
+		return;
+
+	hp = (uint32 *)cp;	/* HW_REVISION_NUMBER */
+	mdp_hw_revision = *hp;
+	iounmap(cp);
+
+	mdp_hw_revision >>= 28;	/* bit 31:28 */
+	mdp_hw_revision &= 0x0f;
+
+	MSM_FB_DEBUG("%s: mdp_hw_revision=%x\n",
+				__func__, mdp_hw_revision);
+}
+
+#ifdef CONFIG_FB_MSM_MDP40
+static void configure_mdp_core_clk_table(uint32 min_clk_rate)
+{
+	uint8 count;
+	uint32 current_rate;
+	if (mdp_clk && mdp_pdata
+		&& mdp_pdata->mdp_core_clk_table) {
+		if (clk_set_min_rate(mdp_clk,
+				 min_clk_rate) < 0)
+			printk(KERN_ERR "%s: clk_set_min_rate failed\n",
+							 __func__);
+		else {
+			count = 0;
+			current_rate = clk_get_rate(mdp_clk);
+			while (count < mdp_pdata->num_mdp_clk) {
+				if (mdp_pdata->mdp_core_clk_table[count]
+						< current_rate) {
+					mdp_pdata->
+					mdp_core_clk_table[count] =
+							current_rate;
+				}
+				count++;
+			}
+		}
+	}
+}
+#endif
+
+#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
+DEFINE_MUTEX(mdp_clk_lock);
+int mdp_set_core_clk(uint16 perf_level)
+{
+	int ret = -EINVAL;
+	if (mdp_clk && mdp_pdata
+		 && mdp_pdata->mdp_core_clk_table) {
+		if (perf_level > mdp_pdata->num_mdp_clk)
+			printk(KERN_ERR "%s invalid perf level\n", __func__);
+		else {
+			mutex_lock(&mdp_clk_lock);
+			if (mdp4_extn_disp)
+				perf_level = 1;
+			ret = clk_set_rate(mdp_clk,
+				mdp_pdata->
+				mdp_core_clk_table[mdp_pdata->num_mdp_clk
+						 - perf_level]);
+			mutex_unlock(&mdp_clk_lock);
+			if (ret) {
+				printk(KERN_ERR "%s unable to set mdp_core_clk rate\n",
+					__func__);
+			}
+		}
+	}
+	return ret;
+}
+
+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;
+}
+
+unsigned long mdp_perf_level2clk_rate(uint32 perf_level)
+{
+	unsigned long clk_rate = 0;
+
+	if (mdp_pdata && mdp_pdata->mdp_core_clk_table) {
+		if (perf_level > mdp_pdata->num_mdp_clk) {
+			printk(KERN_ERR "%s invalid perf level\n", __func__);
+			clk_rate = mdp_get_core_clk();
+		} else {
+			if (mdp4_extn_disp)
+				perf_level = 1;
+			clk_rate = mdp_pdata->
+				mdp_core_clk_table[mdp_pdata->num_mdp_clk
+					- perf_level];
+		}
+	} else
+		clk_rate = mdp_get_core_clk();
+
+	return clk_rate;
+}
+
+static int mdp_irq_clk_setup(void)
+{
+	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);
+
+	footswitch = regulator_get(NULL, "fs_mdp");
+	if (IS_ERR(footswitch))
+		footswitch = NULL;
+	else
+		regulator_enable(footswitch);
+
+	mdp_clk = clk_get(NULL, "mdp_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(NULL, "mdp_pclk");
+	if (IS_ERR(mdp_pclk))
+		mdp_pclk = NULL;
+
+	if (mdp_rev == MDP_REV_42) {
+		mdp_axi_clk = clk_get(NULL, "mdp_axi_clk");
+		if (IS_ERR(mdp_axi_clk)) {
+			ret = PTR_ERR(mdp_axi_clk);
+			clk_put(mdp_clk);
+			pr_err("can't get mdp_axi_clk error:%d!\n", ret);
+			return ret;
+		}
+
+		mdp_lut_clk = clk_get(NULL, "lut_mdp");
+		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);
+			clk_put(mdp_axi_clk);
+			free_irq(mdp_irq, 0);
+			return ret;
+		}
+	} else {
+		mdp_axi_clk = NULL;
+		mdp_lut_clk = NULL;
+	}
+
+#ifdef CONFIG_FB_MSM_MDP40
+	/*
+	 * mdp_clk should greater than mdp_pclk always
+	 */
+	if (mdp_pdata && mdp_pdata->mdp_core_clk_rate) {
+		mutex_lock(&mdp_clk_lock);
+		clk_set_rate(mdp_clk, mdp_pdata->mdp_core_clk_rate);
+		if (mdp_lut_clk != NULL)
+			clk_set_rate(mdp_lut_clk, mdp_pdata->mdp_core_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 mdp_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;
+	resource_size_t  size ;
+#ifdef CONFIG_FB_MSM_MDP40
+	int intf, if_no;
+#else
+	unsigned long flag;
+#endif
+#if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
+	struct mipi_panel_info *mipi;
+#endif
+
+	if ((pdev->id == 0) && (pdev->num_resources > 0)) {
+		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();
+
+		if (rc)
+			return rc;
+
+		mdp_hw_version();
+
+		/* initializing mdp hw */
+#ifdef CONFIG_FB_MSM_MDP40
+		mdp4_hw_init();
+		mdp4_fetch_cfg(clk_get_rate(mdp_clk));
+#else
+		mdp_hw_init();
+#endif
+
+#ifdef CONFIG_FB_MSM_OVERLAY
+		mdp_hw_cursor_init();
+#endif
+
+		mdp_resource_initialized = 1;
+		return 0;
+	}
+
+	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;
+
+	/* 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_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
+		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(mfd);
+		break;
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+	case MIPI_VIDEO_PANEL:
+#ifndef CONFIG_FB_MSM_MDP303
+		pdata->on = mdp4_dsi_video_on;
+		pdata->off = mdp4_dsi_video_off;
+		mfd->hw_refresh = TRUE;
+		mfd->dma_fnc = mdp4_dsi_video_overlay;
+		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;
+		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
+		break;
+
+	case MIPI_CMD_PANEL:
+#ifndef CONFIG_FB_MSM_MDP303
+		mfd->dma_fnc = mdp4_dsi_cmd_overlay;
+#ifdef CONFIG_FB_MSM_MDP40
+		mipi = &mfd->panel_info.mipi;
+		configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 3 / 2);
+#endif
+		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;
+		}
+		mdp4_display_intf_sel(if_no, DSI_CMD_INTF);
+#else
+		mfd->dma_fnc = mdp_dma2_update;
+		mfd->do_histogram = mdp_do_histogram;
+		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
+		mdp_config_vsync(mfd);
+		break;
+#endif
+
+#ifdef CONFIG_FB_MSM_DTV
+	case DTV_PANEL:
+		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:
+		pdata->on = mdp_lcdc_on;
+		pdata->off = mdp_lcdc_off;
+		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
+		configure_mdp_core_clk_table((mfd->panel_info.clk_rate)
+								* 23 / 20);
+		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;
+		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;
+
+	default:
+		printk(KERN_ERR "mdp_probe: unknown device type!\n");
+		rc = -ENODEV;
+		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
+
+#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;
+		}
+	}
+#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;
+}
+
+#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();
+}
+
+static void mdp_early_resume(struct early_suspend *h)
+{
+	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..165502c
--- /dev/null
+++ b/drivers/video/msm/mdp.h
@@ -0,0 +1,727 @@
+/* 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.
+ *
+ */
+
+#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 <mach/hardware.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;
+
+#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)
+
+struct mdp_table_entry {
+	uint32_t reg;
+	uint32_t val;
+};
+
+extern struct mdp_ccs mdp_ccs_yuv2rgb ;
+extern struct mdp_ccs mdp_ccs_rgb2yuv ;
+
+/*
+ * 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_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;
+};
+
+#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
+#endif
+#define MDP_HISTOGRAM_TERM 0x80
+
+#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 TV_OUT_DMA3_START   BIT(13)
+#define MDP_HIST_DONE       BIT(20)
+
+#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
+
+#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)
+#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_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_config_vsync(struct msm_fb_data_type *);
+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);
+#endif
+
+int mdp_hw_cursor_update(struct fb_info *info, struct fb_cursor *cursor);
+int mdp_hw_cursor_sync_update(struct fb_info *info, struct fb_cursor *cursor);
+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(uint16 perf_level);
+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);
+#endif
+
+#ifdef MDP_HW_VSYNC
+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_start_histogram(struct fb_info *info);
+int mdp_stop_histogram(struct fb_info *info);
+int mdp_histogram_ctrl(boolean en);
+
+#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 */
+}
+#endif
+
+#endif /* MDP_H */
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
new file mode 100644
index 0000000..d6cf2d3
--- /dev/null
+++ b/drivers/video/msm/mdp4.h
@@ -0,0 +1,565 @@
+/* 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 MDP4_H
+#define MDP4_H
+
+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_histogram mdp_hist;
+extern struct completion mdp_hist_comp;
+extern boolean mdp_is_hist_start;
+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;
+
+#define MDP4_OVERLAYPROC0_BASE	0x10000
+#define MDP4_OVERLAYPROC1_BASE	0x18000
+
+#define MDP4_VIDEO_BASE 0x20000
+#define MDP4_VIDEO_OFF 0x10000
+
+#define MDP4_RGB_BASE 0x40000
+#define MDP4_RGB_OFF 0x10000
+
+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,
+	EXTERNAL_INTF_SEL
+};
+
+enum {
+	LCDC_RGB_INTF,			/* 0 */
+	DTV_INTF = LCDC_RGB_INTF,	/* 0 */
+	MDDI_LCDC_INTF,			/* 1 */
+	MDDI_INTF,			/* 2 */
+	EBI2_INTF,			/* 3 */
+	TV_INTF = EBI2_INTF,		/* 3 */
+	DSI_VIDEO_INTF,
+	DSI_CMD_INTF
+};
+
+enum {
+	MDDI_PRIMARY_SET,
+	MDDI_SECONDARY_SET,
+	MDDI_EXTERNAL_SET
+};
+
+enum {
+	EBI2_LCD0,
+	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)
+
+enum {
+	OVERLAY_MODE_NONE,
+	OVERLAY_MODE_BLT
+};
+
+enum {
+	OVERLAY_REFRESH_ON_DEMAND,
+	OVERLAY_REFRESH_VSYNC,
+	OVERLAY_REFRESH_VSYNC_HALF,
+	OVERLAY_REFRESH_VSYNC_QUARTER
+};
+
+enum {
+	OVERLAY_FRAMEBUF,
+	OVERLAY_DIRECTOUT
+};
+
+/* system interrupts */
+#define INTR_OVERLAY0_DONE		BIT(0)
+#define INTR_OVERLAY1_DONE		BIT(1)
+#define INTR_DMA_S_DONE			BIT(2)
+#define INTR_DMA_E_DONE			BIT(3)
+#define INTR_DMA_P_DONE			BIT(4)
+#define INTR_VG1_HISTOGRAM		BIT(5)
+#define INTR_VG2_HISTOGRAM		BIT(6)
+#define INTR_PRIMARY_VSYNC		BIT(7)
+#define INTR_PRIMARY_INTF_UDERRUN	BIT(8)
+#define INTR_EXTERNAL_VSYNC		BIT(9)
+#define INTR_EXTERNAL_INTF_UDERRUN	BIT(10)
+#define INTR_PRIMARY_READ_PTR		BIT(11)
+#define INTR_DMA_P_HISTOGRAM		BIT(17)
+
+/* histogram interrupts */
+#define INTR_HIST_DONE			BIT(1)
+#define INTR_HIST_RESET_SEQ_DONE	BIT(0)
+
+
+#ifdef CONFIG_FB_MSM_OVERLAY
+#define MDP4_ANY_INTR_MASK	(INTR_OVERLAY0_DONE|INTR_DMA_S_DONE | \
+					INTR_DMA_P_HISTOGRAM)
+#else
+#define MDP4_ANY_INTR_MASK	(INTR_DMA_P_DONE| \
+				INTR_DMA_P_HISTOGRAM)
+#endif
+
+enum {
+	OVERLAY_PIPE_RGB1,
+	OVERLAY_PIPE_RGB2,
+	OVERLAY_PIPE_VG1,	/* video/graphic */
+	OVERLAY_PIPE_VG2,
+	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 {
+	MDP4_MIXER0,
+	MDP4_MIXER1,
+	MDP4_MIXER_MAX
+};
+
+#define MDP4_MAX_MIXER	2
+
+enum {
+	OVERLAY_PLANE_INTERLEAVED,
+	OVERLAY_PLANE_PLANAR,
+	OVERLAY_PLANE_PSEUDO_PLANAR
+};
+
+enum {
+	MDP4_MIXER_STAGE_UNUNSED,	/* pipe not used */
+	MDP4_MIXER_STAGE_BASE,
+	MDP4_MIXER_STAGE0,	/* zorder 0 */
+	MDP4_MIXER_STAGE1,	/* zorder 1 */
+	MDP4_MIXER_STAGE2	/* zorder 2 */
+};
+
+#define MDP4_MAX_STAGE	4
+
+enum {
+	MDP4_FRAME_FORMAT_LINEAR,
+	MDP4_FRAME_FORMAT_ARGB_TILE,
+	MDP4_FRAME_FORMAT_VIDEO_SUPERTILE
+};
+
+enum {
+	MDP4_CHROMA_RGB,
+	MDP4_CHROMA_H2V1,
+	MDP4_CHROMA_H1V2,
+	MDP4_CHROMA_420
+};
+
+#define MDP4_BLEND_BG_TRANSP_EN		BIT(9)
+#define MDP4_BLEND_FG_TRANSP_EN		BIT(8)
+#define MDP4_BLEND_BG_MOD_ALPHA		BIT(7)
+#define MDP4_BLEND_BG_INV_ALPHA		BIT(6)
+#define MDP4_BLEND_BG_ALPHA_FG_CONST	(0 << 4)
+#define MDP4_BLEND_BG_ALPHA_BG_CONST	(1 << 4)
+#define MDP4_BLEND_BG_ALPHA_FG_PIXEL	(2 << 4)
+#define MDP4_BLEND_BG_ALPHA_BG_PIXEL	(3 << 4)
+#define MDP4_BLEND_FG_MOD_ALPHA		BIT(3)
+#define MDP4_BLEND_FG_INV_ALPHA		BIT(2)
+#define MDP4_BLEND_FG_ALPHA_FG_CONST	(0 << 0)
+#define MDP4_BLEND_FG_ALPHA_BG_CONST	(1 << 0)
+#define MDP4_BLEND_FG_ALPHA_FG_PIXEL	(2 << 0)
+#define MDP4_BLEND_FG_ALPHA_BG_PIXEL	(3 << 0)
+
+#define MDP4_FORMAT_SOLID_FILL		BIT(22)
+#define MDP4_FORMAT_UNPACK_ALIGN_MSB	BIT(18)
+#define MDP4_FORMAT_UNPACK_TIGHT	BIT(17)
+#define MDP4_FORMAT_90_ROTATED		BIT(12)
+#define MDP4_FORMAT_ALPHA_ENABLE	BIT(8)
+
+#define MDP4_OP_DEINT_ODD_REF  	BIT(19)
+#define MDP4_OP_DEINT_EN	BIT(18)
+#define MDP4_OP_IGC_LUT_EN	BIT(16)
+#define MDP4_OP_DITHER_EN     	BIT(15)
+#define MDP4_OP_FLIP_UD		BIT(14)
+#define MDP4_OP_FLIP_LR		BIT(13)
+#define MDP4_OP_CSC_EN		BIT(11)
+#define MDP4_OP_SRC_DATA_YCBCR	BIT(9)
+#define MDP4_OP_SCALEY_FIR 		(0 << 4)
+#define MDP4_OP_SCALEY_MN_PHASE 	(1 << 4)
+#define MDP4_OP_SCALEY_PIXEL_RPT	(2 << 4)
+#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_SCALEY_EN	BIT(1)
+#define MDP4_OP_SCALEX_EN	BIT(0)
+
+#define MDP4_PIPE_PER_MIXER	2
+
+#define MDP4_MAX_PLANE		4
+
+
+struct mdp4_overlay_pipe {
+	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 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 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 */
+	struct completion comp;
+	ulong blt_addr; /* blt mode addr */
+	ulong blt_base;
+	ulong blt_offset;
+	uint32 blt_cnt;
+	uint32 ov_cnt;
+	uint32 dmap_cnt;
+	uint32 blt_end;
+	uint32 luma_align_size;
+	struct completion dmas_comp;
+	struct mdp_overlay req_data;
+};
+
+#define MDP4_MAX_SHARE	2
+
+struct mdp4_pipe_desc {
+	int share;
+	int ref_cnt;
+	int ndx_list[MDP4_MAX_SHARE];
+	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_underrun_p;	/* Primary interface */
+	ulong intr_underrun_e;	/* external interface */
+	ulong intr_dsi;
+	ulong kickoff_mddi;
+	ulong kickoff_lcdc;
+	ulong kickoff_dtv;
+	ulong kickoff_atv;
+	ulong kickoff_dsi;
+	ulong writeback;	/* blt */
+	ulong overlay_set[MDP4_MIXER_MAX];
+	ulong overlay_unset[MDP4_MIXER_MAX];
+	ulong overlay_play[MDP4_MIXER_MAX];
+	ulong pipe[MDP4_MAX_PIPE];
+	ulong dsi_clkoff;
+	ulong err_mixer;
+	ulong err_zorder;
+	ulong err_size;
+	ulong err_scale;
+	ulong err_format;
+};
+
+#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+static inline int mdp4_overlay_writeback_setup(struct fb_info *fbi,
+		struct mdp4_overlay_pipe *pipe, uint8 *buf, int bpp)
+{
+	int off;
+
+	pipe->blt_base = (ulong) buf;
+	off = ALIGN(fbi->var.xres, 32) * fbi->var.yres * bpp * 2;
+	off += (1920 * 1080 * 2 * 1); /* hdmi */
+	pipe->blt_base += off;
+
+	pr_info("%s: base=%x offset=%x\n",
+			__func__, (int) pipe->blt_base, (int)off);
+
+	return off;
+
+}
+#else
+static inline int mdp4_overlay_writeback_setup(struct fb_info *fbi,
+		struct mdp4_overlay_pipe *pipe, uint8 *buf, int bpp)
+{
+	return 0;
+}
+#endif
+
+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);
+unsigned is_mdp4_hw_reset(void);
+void mdp4_hw_init(void);
+void mdp4_isr_read(int);
+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_mv_setup(int vp_num);
+void mdp4_vg_csc_pre_bv_setup(int vp_num);
+void mdp4_vg_csc_post_bv_setup(int vp_num);
+void mdp4_vg_csc_pre_lv_setup(int vp_num);
+void mdp4_vg_csc_post_lv_setup(int vp_num);
+void mdp4_mixer1_csc_mv_setup(void);
+void mdp4_mixer1_csc_pre_bv_setup(void);
+void mdp4_mixer1_csc_post_bv_setup(void);
+void mdp4_mixer1_csc_pre_lv_setup(void);
+void mdp4_mixer1_csc_post_lv_setup(void);
+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_overlay(struct msm_fb_data_type *mfd);
+void mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe);
+void mdp4_overlay_dtv_vsync_push(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);
+int mdp4_dsi_video_on(struct platform_device *pdev);
+int mdp4_dsi_video_off(struct platform_device *pdev);
+void mdp4_overlay0_done_dsi_video(void);
+void mdp4_overlay0_done_dsi_cmd(struct mdp_dma_data *dma);
+void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd);
+void mdp4_overlay_dsi_state_set(int state);
+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);
+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);
+int mdp4_mixer_stage_can_run(struct mdp4_overlay_pipe *pipe);
+void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe);
+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 fb_info *info, struct mdp_overlay *req);
+int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req);
+int mdp4_overlay_unset(struct fb_info *info, int ndx);
+int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
+		struct file **pp_src_file, struct file **pp_src_plane1_file,
+		struct file **pp_src_plane2_file);
+struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer,
+				int req_share);
+void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe);
+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 msm_fb_data_type *mfd, int atv);
+void mdp4_overlay_dmae_xy(struct mdp4_overlay_pipe *pipe);
+int mdp4_overlay_pipe_staged(int mixer);
+void mdp4_lcdc_primary_vsyn(void);
+void mdp4_overlay0_done_lcdc(void);
+void mdp4_overlay0_done_mddi(struct mdp_dma_data *dma);
+void mdp4_dma_s_done_mddi(void);
+void mdp4_dma_p_done_mddi(void);
+void mdp4_dma_p_done_dsi(struct mdp_dma_data *dma);
+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_mddi_overlay_restore(void);
+void mdp4_overlay_lcdc_wait4vsync(struct msm_fb_data_type *mfd);
+void mdp4_overlay_lcdc_vsync_push(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe);
+void mdp4_mddi_overlay_dmas_restore(void);
+void mdp4_mddi_dma_busy_wait(struct msm_fb_data_type *mfd);
+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);
+int mdp4_overlay_blt_offset(struct fb_info *info,
+					struct msmfb_overlay_blt *req);
+
+int mdp4_dsi_overlay_blt_start(struct msm_fb_data_type *mfd);
+int mdp4_dsi_overlay_blt_stop(struct msm_fb_data_type *mfd);
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+void mdp4_dsi_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req);
+int mdp4_dsi_overlay_blt_offset(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);
+int mdp4_dsi_video_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req);
+
+#ifdef CONFIG_FB_MSM_MDP40
+static inline void mdp3_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd)
+{
+	/* empty */
+}
+#endif
+#else
+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 int mdp4_dsi_video_overlay_blt_offset(
+	struct msm_fb_data_type *mfd, struct msmfb_overlay_blt *req)
+{
+	return -ENODEV;
+}
+#endif
+
+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);
+
+int mdp4_mddi_overlay_blt_offset(int *off);
+void mdp4_mddi_overlay_blt(ulong addr);
+void mdp4_overlay_panel_mode(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);
+void mdp4_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd);
+void mdp4_dsi_blt_dmap_busy_wait(struct msm_fb_data_type *mfd);
+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_dsi_cmd_overlay_restore(void);
+
+void mdp4_overlay_panel_3d(int mixer_num, uint32 panel_3d);
+int mdp4_overlay_3d(struct fb_info *info, struct msmfb_overlay_3d *req);
+void mdp4_dsi_cmd_3d(struct msm_fb_data_type *mfd,
+			 struct msmfb_overlay_3d *r3d);
+
+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);
+void mdp4_overlay_dsi_video_wait4vsync(struct msm_fb_data_type *mfd);
+void mdp4_overlay_dsi_video_vsync_push(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe);
+void mdp4_primary_vsync_dsi_video(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);
+#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..b039da8
--- /dev/null
+++ b/drivers/video/msm/mdp4_dtv.c
@@ -0,0 +1,329 @@
+/* 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 <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/msm_reqs.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(hdmi_clk);
+	if (mdp_tv_clk)
+		clk_disable(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(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;
+
+#ifdef CONFIG_MSM_NPA_SYSTEM_BUS
+	pm_qos_rate = MSM_AXI_FLOW_MDP_DTV_720P_2BPP;
+#else
+	if (panel_pixclock_freq > 58000000)
+		/* pm_qos_rate should be in Khz */
+		pm_qos_rate = panel_pixclock_freq / 1000 ;
+	else
+		pm_qos_rate = 58000;
+#endif
+	mdp_set_core_clk(1);
+	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_enable(ebi1_clk);
+	}
+#endif
+	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);
+
+	clk_enable(hdmi_clk);
+	clk_reset(hdmi_clk, CLK_RESET_ASSERT);
+	udelay(20);
+	clk_reset(hdmi_clk, CLK_RESET_DEASSERT);
+
+	if (mdp_tv_clk)
+		clk_enable(mdp_tv_clk);
+
+	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);
+
+	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;
+		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;
+	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;
+
+#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(NULL, "ebi1_dtv_clk");
+	if (IS_ERR(ebi1_clk)) {
+		ebi1_clk = NULL;
+		pr_warning("%s: Couldn't get ebi1 clock\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 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)
+{
+	tv_src_clk = clk_get(NULL, "tv_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(NULL, "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(NULL, "mdp_tv_clk");
+	if (IS_ERR(mdp_tv_clk))
+		mdp_tv_clk = NULL;
+
+	return dtv_register_driver();
+}
+
+module_init(dtv_driver_init);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
new file mode 100644
index 0000000..cc3bd1b
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -0,0 +1,2290 @@
+/* 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/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 <mach/hardware.h>
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+#include <linux/file.h>
+#include <linux/android_pmem.h>
+#include <linux/major.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/mutex.h>
+#include <linux/msm_kgsl.h>
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+
+#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 + 2];
+	uint32 panel_3d;
+	uint32 panel_mode;
+	uint32 mixer0_played;
+	uint32 mixer1_played;
+} mdp4_overlay_db = {
+	.ov_pipe = {
+			{
+				.share = 0,	/* RGB 1 */
+			},
+			{
+				.share = 0,	/* RGB 2 */
+			},
+			{
+				.share = 1,	/* VG 1 */
+			},
+			{
+				.share = 1,	/* VG 2 */
+			},
+		},
+	.plist = {
+		{
+			.pipe_type = OVERLAY_TYPE_RGB,
+			.pipe_num = OVERLAY_PIPE_RGB1,
+			.pipe_ndx = 1,
+		},
+		{
+			.pipe_type = OVERLAY_TYPE_RGB,
+			.pipe_num = OVERLAY_PIPE_RGB2,
+			.pipe_ndx = 2,
+		},
+		{
+			.pipe_type = OVERLAY_TYPE_RGB, /* shared */
+			.pipe_num = OVERLAY_PIPE_VG1,
+			.pipe_ndx = 3,
+		},
+		{
+			.pipe_type = OVERLAY_TYPE_RGB, /* shared */
+			.pipe_num = OVERLAY_PIPE_VG2,
+			.pipe_ndx = 4,
+		},
+		{
+			.pipe_type = OVERLAY_TYPE_VIDEO, /* shared */
+			.pipe_num = OVERLAY_PIPE_VG1,
+			.pipe_ndx = 5,
+		},
+		{
+			.pipe_type = OVERLAY_TYPE_VIDEO, /* shared */
+			.pipe_num = OVERLAY_PIPE_VG2,
+			.pipe_ndx = 6,
+		},
+	},
+};
+
+static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
+static uint32 perf_level;
+static uint32 mdp4_del_res_rel;
+/* static array with index 0 for unset status and 1 for set status */
+static bool overlay_status[MDP4_OVERLAY_TYPE_MAX];
+
+void mdp4_overlay_status_write(enum mdp4_overlay_status type, bool val)
+{
+	overlay_status[type] = val;
+}
+
+bool mdp4_overlay_status_read(enum mdp4_overlay_status type)
+{
+	return overlay_status[type];
+}
+
+int mdp4_overlay_mixer_play(int mixer_num)
+{
+	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;
+}
+
+uint32 mdp4_overlay_panel_list(void)
+{
+	return ctrl->panel_mode;
+}
+
+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 (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 16BPP */
+		    DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/* dma2 config register */
+	MDP_OUTP(MDP_BASE + 0xb0000, dmae_cfg_reg);
+	if (atv) {
+		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_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);
+}
+
+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);
+}
+
+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);
+}
+
+void mdp4_overlay_dmae_xy(struct mdp4_overlay_pipe *pipe)
+{
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/* dma_p source */
+	MDP_OUTP(MDP_BASE + 0xb0004,
+			(pipe->src_height << 16 | pipe->src_width));
+	MDP_OUTP(MDP_BASE + 0xb0008, pipe->srcp0_addr);
+	MDP_OUTP(MDP_BASE + 0xb000c, pipe->srcp0_ystride);
+
+	/* dma_p 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;
+
+	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;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+#ifndef CONFIG_FB_MSM_LCDC_CHIMEI_WXGA_PANEL
+	if (lcdc)
+		dma2_cfg_reg |= DMA_PACK_ALIGN_MSB;
+#endif
+
+	/* dma2 config register */
+	MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+/*
+ * mdp4_overlay_dmap_xy: called form baselayer only
+ */
+void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, bpp;
+
+	if (mdp_is_in_isr == FALSE)
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/* dma_p source */
+	MDP_OUTP(MDP_BASE + 0x90004,
+			(pipe->src_height << 16 | pipe->src_width));
+	if (pipe->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->blt_addr + off);
+		/* RGB888, output of overlay blending */
+		MDP_OUTP(MDP_BASE + 0x9000c, pipe->src_width * bpp);
+	} else {
+		MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
+		MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
+	}
+
+	/* dma_p dest */
+	MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
+
+	if (mdp_is_in_isr == FALSE)
+		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 num)
+{
+	uint32 bit = 0x80000000;
+	int i;
+
+	for (i = 0; i < 32; i++) {
+		if (bit & num)
+			return i;
+		bit >>= 1;
+	}
+
+	return i;
+}
+
+static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
+{
+	uint32 val;
+	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;
+	if (n < f_num) {
+		n = f_num - n;
+		val <<= n;
+	}
+
+	return val;
+}
+
+static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe)
+{
+	int ptype;
+
+	pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
+	pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
+	ptype = mdp4_overlay_format2type(pipe->src_format);
+
+	if (pipe->dst_h && pipe->src_h != pipe->dst_h) {
+		if (pipe->dst_h > pipe->src_h * 8)	/* too much */
+			return;
+		pipe->op_mode |= MDP4_OP_SCALEY_EN;
+
+		if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
+			if (pipe->dst_h <= (pipe->src_h / 4))
+				pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
+			else
+				pipe->op_mode |= MDP4_OP_SCALEY_FIR;
+		}
+
+		pipe->phasey_step = mdp4_scale_phase_step(29,
+					pipe->src_h, pipe->dst_h);
+	}
+
+	if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
+		if (pipe->dst_w > pipe->src_w * 8)	/* too much */
+			return;
+		pipe->op_mode |= MDP4_OP_SCALEX_EN;
+
+		if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
+			if (pipe->dst_w <= (pipe->src_w / 4))
+				pipe->op_mode |= MDP4_OP_SCALEX_MN_PHASE;
+			else
+				pipe->op_mode |= MDP4_OP_SCALEX_FIR;
+		}
+
+		pipe->phasex_step = mdp4_scale_phase_step(29,
+					pipe->src_w, pipe->dst_w);
+	}
+}
+
+void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
+{
+	char *rgb_base;
+	uint32 src_size, src_xy, dst_size, dst_xy;
+	uint32 format, pattern;
+
+	rgb_base = MDP_BASE + MDP4_RGB_BASE;
+	rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
+
+	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);
+
+	format = mdp4_overlay_format(pipe);
+	pattern = mdp4_overlay_unpack_pattern(pipe);
+
+#ifdef MDP4_IGC_LUT_ENABLE
+	pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
+#endif
+
+	mdp4_scale_setup(pipe);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	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);
+	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 */
+	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]++;
+}
+
+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;
+	int pnum;
+
+	pnum = pipe->pipe_num - OVERLAY_PIPE_VG1; /* start from 0 */
+	vg_base = MDP_BASE + MDP4_VIDEO_BASE;
+	vg_base += (MDP4_VIDEO_OFF * pnum);
+
+	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);
+
+	format = mdp4_overlay_format(pipe);
+	pattern = mdp4_overlay_unpack_pattern(pipe);
+
+	/* not RGB use VG pipe, pure VG pipe */
+	if (pipe->pipe_type != OVERLAY_TYPE_RGB)
+#ifdef MDP4_IGC_LUT_ENABLE
+		pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR |
+				MDP4_OP_IGC_LUT_EN);
+#else
+		pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR);
+#endif
+
+	mdp4_scale_setup(pipe);
+
+	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 */
+	outpdw(vg_base + 0x0048, frame_size);	/* TILE frame size */
+
+	/* luma component plane */
+	outpdw(vg_base + 0x0010, pipe->srcp0_addr);
+
+	/* chroma component plane or  planar color 1 */
+	outpdw(vg_base + 0x0014, pipe->srcp1_addr);
+
+	/* planar color 2 */
+	outpdw(vg_base + 0x0018, pipe->srcp2_addr);
+
+	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 */
+	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));
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	mdp4_stat.pipe[pipe->pipe_num]++;
+}
+
+int mdp4_overlay_format2type(uint32 format)
+{
+	switch (format) {
+	case MDP_RGB_565:
+	case MDP_RGB_888:
+	case MDP_BGR_565:
+	case MDP_XRGB_8888:
+	case MDP_ARGB_8888:
+	case MDP_RGBA_8888:
+	case MDP_BGRA_8888:
+	case MDP_RGBX_8888:
+		return OVERLAY_TYPE_RGB;
+	case MDP_YCRYCB_H2V1:
+	case MDP_Y_CRCB_H2V1:
+	case MDP_Y_CBCR_H2V1:
+	case MDP_Y_CRCB_H2V2:
+	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_CB_CR_H2V2:
+	case MDP_Y_CRCB_H1V1:
+	case MDP_Y_CBCR_H1V1:
+		return OVERLAY_TYPE_VIDEO;
+	default:
+		mdp4_stat.err_format++;
+		return -ERANGE;
+	}
+
+}
+
+#define C3_ALPHA	3	/* alpha */
+#define C2_R_Cr		2	/* R/Cr */
+#define C1_B_Cb		1	/* B/Cb */
+#define C0_G_Y		0	/* G/luma */
+#define YUV_444_MAX_WIDTH		1280	/* Max width for YUV 444*/
+
+int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe)
+{
+	switch (pipe->src_format) {
+	case MDP_RGB_565:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 0;
+		pipe->r_bit = 1;	/* R, 5 bits */
+		pipe->b_bit = 1;	/* B, 5 bits */
+		pipe->g_bit = 2;	/* G, 6 bits */
+		pipe->alpha_enable = 0;
+		pipe->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 2;
+		pipe->element2 = C2_R_Cr;	/* R */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C1_B_Cb;	/* B */
+		pipe->bpp = 2;	/* 2 bpp */
+		break;
+	case MDP_RGB_888:
+		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->element2 = C2_R_Cr;	/* R */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C1_B_Cb;	/* B */
+		pipe->bpp = 3;	/* 3 bpp */
+		break;
+	case MDP_BGR_565:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 0;
+		pipe->r_bit = 1;	/* R, 5 bits */
+		pipe->b_bit = 1;	/* B, 5 bits */
+		pipe->g_bit = 2;	/* G, 6 bits */
+		pipe->alpha_enable = 0;
+		pipe->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 2;
+		pipe->element2 = C1_B_Cb;	/* B */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C2_R_Cr;	/* R */
+		pipe->bpp = 2;	/* 2 bpp */
+		break;
+	case MDP_XRGB_8888:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 3;	/* alpha, 4 bits */
+		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 = 3;
+		pipe->element3 = C3_ALPHA;	/* alpha */
+		pipe->element2 = C2_R_Cr;	/* R */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C1_B_Cb;	/* B */
+		pipe->bpp = 4;		/* 4 bpp */
+		break;
+	case MDP_ARGB_8888:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 3;	/* alpha, 4 bits */
+		pipe->r_bit = 3;	/* R, 8 bits */
+		pipe->b_bit = 3;	/* B, 8 bits */
+		pipe->g_bit = 3;	/* G, 8 bits */
+		pipe->alpha_enable = 1;
+		pipe->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 3;
+		pipe->element3 = C3_ALPHA;	/* alpha */
+		pipe->element2 = C2_R_Cr;	/* R */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C1_B_Cb;	/* B */
+		pipe->bpp = 4;		/* 4 bpp */
+		break;
+	case MDP_RGBA_8888:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 3;	/* alpha, 4 bits */
+		pipe->r_bit = 3;	/* R, 8 bits */
+		pipe->b_bit = 3;	/* B, 8 bits */
+		pipe->g_bit = 3;	/* G, 8 bits */
+		pipe->alpha_enable = 1;
+		pipe->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 3;
+		pipe->element3 = C3_ALPHA;	/* alpha */
+		pipe->element2 = C1_B_Cb;	/* B */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C2_R_Cr;	/* R */
+		pipe->bpp = 4;		/* 4 bpp */
+		break;
+	case MDP_RGBX_8888:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 3;
+		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 = 3;
+		pipe->element3 = C3_ALPHA;	/* alpha */
+		pipe->element2 = C1_B_Cb;	/* B */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C2_R_Cr;	/* R */
+		pipe->bpp = 4;		/* 4 bpp */
+		break;
+	case MDP_BGRA_8888:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 3;	/* alpha, 4 bits */
+		pipe->r_bit = 3;	/* R, 8 bits */
+		pipe->b_bit = 3;	/* B, 8 bits */
+		pipe->g_bit = 3;	/* G, 8 bits */
+		pipe->alpha_enable = 1;
+		pipe->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 3;
+		pipe->element3 = C3_ALPHA;	/* alpha */
+		pipe->element2 = C2_R_Cr;	/* R */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C1_B_Cb;	/* B */
+		pipe->bpp = 4;		/* 4 bpp */
+		break;
+	case MDP_YCRYCB_H2V1:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
+		pipe->a_bit = 0;	/* alpha, 4 bits */
+		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 = 3;
+		pipe->element3 = C0_G_Y;	/* G */
+		pipe->element2 = C2_R_Cr;	/* R */
+		pipe->element1 = C0_G_Y;	/* G */
+		pipe->element0 = C1_B_Cb;	/* B */
+		pipe->bpp = 2;		/* 2 bpp */
+		pipe->chroma_sample = MDP4_CHROMA_H2V1;
+		break;
+	case MDP_Y_CRCB_H2V1:
+	case MDP_Y_CBCR_H2V1:
+	case MDP_Y_CRCB_H2V2:
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CRCB_H1V1:
+	case MDP_Y_CBCR_H1V1:
+		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
+		pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_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->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 1;		/* 2 */
+		pipe->element3 = C0_G_Y;	/* not used */
+		pipe->element2 = C0_G_Y;	/* not used */
+		if (pipe->src_format == MDP_Y_CRCB_H2V1) {
+			pipe->element1 = C2_R_Cr;	/* R */
+			pipe->element0 = C1_B_Cb;	/* B */
+			pipe->chroma_sample = MDP4_CHROMA_H2V1;
+		} else if (pipe->src_format == MDP_Y_CRCB_H1V1) {
+			pipe->element1 = C2_R_Cr;	/* R */
+			pipe->element0 = C1_B_Cb;	/* B */
+			if (pipe->src_width > YUV_444_MAX_WIDTH)
+				pipe->chroma_sample = MDP4_CHROMA_H1V2;
+			else
+				pipe->chroma_sample = MDP4_CHROMA_RGB;
+		} else if (pipe->src_format == MDP_Y_CBCR_H2V1) {
+			pipe->element1 = C1_B_Cb;	/* B */
+			pipe->element0 = C2_R_Cr;	/* R */
+			pipe->chroma_sample = MDP4_CHROMA_H2V1;
+		} else if (pipe->src_format == MDP_Y_CBCR_H1V1) {
+			pipe->element1 = C1_B_Cb;	/* B */
+			pipe->element0 = C2_R_Cr;	/* R */
+			if (pipe->src_width > YUV_444_MAX_WIDTH)
+				pipe->chroma_sample = MDP4_CHROMA_H1V2;
+			else
+				pipe->chroma_sample = MDP4_CHROMA_RGB;
+		} else if (pipe->src_format == MDP_Y_CRCB_H2V2) {
+			pipe->element1 = C2_R_Cr;	/* R */
+			pipe->element0 = C1_B_Cb;	/* B */
+			pipe->chroma_sample = MDP4_CHROMA_420;
+		} else if (pipe->src_format == MDP_Y_CBCR_H2V2) {
+			pipe->element1 = C1_B_Cb;	/* B */
+			pipe->element0 = C2_R_Cr;	/* R */
+			pipe->chroma_sample = MDP4_CHROMA_420;
+		}
+		pipe->bpp = 2;	/* 2 bpp */
+		break;
+	case MDP_Y_CBCR_H2V2_TILE:
+	case MDP_Y_CRCB_H2V2_TILE:
+		pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE;
+		pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_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->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 1;		/* 2 */
+		pipe->element3 = C0_G_Y;	/* not used */
+		pipe->element2 = C0_G_Y;	/* not used */
+		if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) {
+			pipe->element1 = C2_R_Cr;	/* R */
+			pipe->element0 = C1_B_Cb;	/* B */
+			pipe->chroma_sample = MDP4_CHROMA_420;
+		} else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) {
+			pipe->element1 = C1_B_Cb;	/* B */
+			pipe->element0 = C2_R_Cr;	/* R */
+			pipe->chroma_sample = MDP4_CHROMA_420;
+		}
+		pipe->bpp = 2;	/* 2 bpp */
+		break;
+	case MDP_Y_CR_CB_H2V2:
+	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->unpack_tight = 1;
+		pipe->unpack_align_msb = 0;
+		pipe->unpack_count = 1;		/* 2 */
+		pipe->element3 = C0_G_Y;	/* not used */
+		pipe->element2 = C0_G_Y;	/* not used */
+		if (pipe->src_format == MDP_Y_CR_CB_H2V2) {
+			pipe->element1 = C2_R_Cr;	/* R */
+			pipe->element0 = C1_B_Cb;	/* B */
+			pipe->chroma_sample = MDP4_CHROMA_420;
+		} else if (pipe->src_format == MDP_Y_CB_CR_H2V2) {
+			pipe->element1 = C1_B_Cb;	/* B */
+			pipe->element0 = C2_R_Cr;	/* R */
+			pipe->chroma_sample = MDP4_CHROMA_420;
+		}
+		pipe->bpp = 2;	/* 2 bpp */
+		break;
+	default:
+		/* not likely */
+		mdp4_stat.err_format++;
+		return -ERANGE;
+	}
+
+	return 0;
+}
+
+/*
+ * color_key_convert: output with 12 bits color key
+ */
+static uint32 color_key_convert(int start, int num, uint32 color)
+{
+	uint32 data;
+
+	data = (color >> start) & ((1 << num) - 1);
+
+	/* convert to 8 bits */
+	if (num == 5)
+		data = ((data << 3) | (data >> 2));
+	else if (num == 6)
+		data = ((data << 2) | (data >> 4));
+
+	/* convert 8 bits to 12 bits */
+	data = (data << 4) | (data >> 4);
+
+	return data;
+}
+
+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;
+
+	switch (format) {
+	case MDP_RGB_565:
+		b_start = 0;
+		g_start = 5;
+		r_start = 11;
+		r_num = 5;
+		g_num = 6;
+		b_num = 5;
+		break;
+	case MDP_RGB_888:
+	case MDP_XRGB_8888:
+	case MDP_ARGB_8888:
+	case MDP_BGRA_8888:
+		b_start = 0;
+		g_start = 8;
+		r_start = 16;
+		r_num = 8;
+		g_num = 8;
+		b_num = 8;
+		break;
+	case MDP_RGBA_8888:
+	case MDP_RGBX_8888:
+		b_start = 16;
+		g_start = 8;
+		r_start = 0;
+		r_num = 8;
+		g_num = 8;
+		b_num = 8;
+		break;
+	case MDP_BGR_565:
+		b_start = 11;
+		g_start = 5;
+		r_start = 0;
+		r_num = 5;
+		g_num = 6;
+		b_num = 5;
+		break;
+	case MDP_Y_CB_CR_H2V2:
+	case MDP_Y_CBCR_H2V2:
+	case MDP_Y_CBCR_H2V1:
+		b_start = 8;
+		g_start = 16;
+		r_start = 0;
+		r_num = 8;
+		g_num = 8;
+		b_num = 8;
+		break;
+	case MDP_Y_CR_CB_H2V2:
+	case MDP_Y_CRCB_H2V2:
+	case MDP_Y_CRCB_H2V1:
+	case MDP_Y_CRCB_H1V1:
+	case MDP_Y_CBCR_H1V1:
+		b_start = 0;
+		g_start = 16;
+		r_start = 8;
+		r_num = 8;
+		g_num = 8;
+		b_num = 8;
+		break;
+	default:
+		b_start = 0;
+		g_start = 8;
+		r_start = 16;
+		r_num = 8;
+		g_num = 8;
+		b_num = 8;
+		break;
+	}
+
+	*c0 = color_key_convert(g_start, g_num, transp);
+	*c1 = color_key_convert(b_start, b_num, transp);
+	*c2 = color_key_convert(r_start, r_num, transp);
+}
+
+uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
+{
+	uint32	format;
+
+	format = 0;
+
+	if (pipe->solid_fill)
+		format |= MDP4_FORMAT_SOLID_FILL;
+
+	if (pipe->unpack_align_msb)
+		format |= MDP4_FORMAT_UNPACK_ALIGN_MSB;
+
+	if (pipe->unpack_tight)
+		format |= MDP4_FORMAT_UNPACK_TIGHT;
+
+	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);
+	format |= (pipe->r_bit << 4);
+	format |= (pipe->b_bit << 2);
+	format |= pipe->g_bit;
+
+	format |= (pipe->frame_format << 29);
+
+	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);
+		format |= (pipe->chroma_sample << 26);
+	}
+
+	return format;
+}
+
+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 data, intf;
+	char *overlay_base;
+
+	intf = 0;
+	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 */
+
+	if (mdp_is_in_isr == FALSE)
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/*
+	 * BLT only siupport at primary display
+	 */
+	if (pipe->mixer_num == MDP4_MIXER0 && pipe->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 (ctrl->panel_mode & MDP4_PANEL_LCDC ||
+				ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
+			outpdw(overlay_base + 0x000c, pipe->blt_addr);
+			outpdw(overlay_base + 0x0010, pipe->src_width * bpp);
+			off = pipe->src_height * pipe->src_width * bpp;
+			outpdw(overlay_base + 0x001c, pipe->blt_addr + off);
+			/* LCDC - FRAME BUFFER + vsync rate */
+			outpdw(overlay_base + 0x0004, 0x02);
+		} else {	/* MDDI */
+			off = 0;
+			if (pipe->ov_cnt & 0x01)
+				off = pipe->src_height * pipe->src_width * bpp;
+
+			outpdw(overlay_base + 0x000c, pipe->blt_addr + off);
+			/* overlay ouput is RGB888 */
+			outpdw(overlay_base + 0x0010, pipe->src_width * bpp);
+			outpdw(overlay_base + 0x001c, pipe->blt_addr + off);
+			/* MDDI - BLT + on demand */
+			outpdw(overlay_base + 0x0004, 0x08);
+		}
+#ifdef BLT_RGB565
+		outpdw(overlay_base + 0x0014, 0x1); /* RGB565 */
+#else
+		outpdw(overlay_base + 0x0014, 0x0); /* RGB888 */
+#endif
+	} else {
+		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 */
+	}
+
+	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
+	outpdw(overlay_base + 0x0014, 0x4);	/* GC_LUT_EN, 888 */
+#endif
+
+	if (mdp_is_in_isr == FALSE)
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+int mdp4_overlay_pipe_staged(int mixer)
+{
+	uint32 data, mask, i;
+	int p1, p2;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	data = inpdw(MDP_BASE + 0x10100);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	p1 = 0;
+	p2 = 0;
+	for (i = 0; i < 8; i++) {
+		mask = data & 0x0f;
+		if (mask) {
+			if (mask <= 4)
+				p1++;
+			else
+				p2++;
+		}
+		data >>= 4;
+	}
+
+	if (mixer)
+		return p2;
+	else
+		return p1;
+}
+
+void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 data, mask, snum, stage, mixer, pnum;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	stage = pipe->mixer_stage;
+	mixer = pipe->mixer_num;
+	pnum = pipe->pipe_num;
+
+	/* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1  */
+	data = inpdw(MDP_BASE + 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 */
+	}
+
+	mask = 0x0f;
+	mask <<= snum;
+	stage <<= snum;
+	data &= ~mask;	/* clear old bits */
+
+	data |= stage;
+
+	outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
+
+	data = inpdw(MDP_BASE + 0x10100);
+
+	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_down(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 data, mask, snum, stage, mixer, pnum;
+
+	stage = pipe->mixer_stage;
+	mixer = pipe->mixer_num;
+	pnum = pipe->pipe_num;
+
+	if (pipe != ctrl->stage[mixer][stage])	/* not runing */
+		return;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	/* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1  */
+	data = inpdw(MDP_BASE + 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 */
+	}
+
+	mask = 0x0f;
+	mask <<= snum;
+	data &= ~mask;	/* clear old bits */
+
+	outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
+
+	data = inpdw(MDP_BASE + 0x10100);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL;	/* clear it */
+}
+
+void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
+{
+	struct mdp4_overlay_pipe *bg_pipe;
+	unsigned char *overlay_base, *rgb_base;
+	uint32 c0, c1, c2, blend_op, constant_color = 0, rgb_src_format;
+	int off;
+
+	if (pipe->mixer_num) 	/* mixer number, /dev/fb0, /dev/fb1 */
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
+	else
+		overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+
+	/* stage 0 to stage 2 */
+	off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
+
+	bg_pipe = mdp4_overlay_stage_pipe(pipe->mixer_num,
+					MDP4_MIXER_STAGE_BASE);
+	if (bg_pipe == NULL) {
+		pr_err("%s: Error: no bg_pipe\n", __func__);
+		return;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	blend_op = 0;
+
+	if (pipe->is_fg) {
+		blend_op |= (MDP4_BLEND_FG_ALPHA_FG_CONST |
+				MDP4_BLEND_BG_ALPHA_BG_CONST);
+		outpdw(overlay_base + off + 0x108, pipe->alpha);
+		outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha);
+		if (pipe->alpha == 0xff) {
+			rgb_base = MDP_BASE + MDP4_RGB_BASE;
+			rgb_base += MDP4_RGB_OFF * bg_pipe->pipe_num;
+			rgb_src_format = inpdw(rgb_base + 0x50);
+			rgb_src_format |= MDP4_FORMAT_SOLID_FILL;
+			outpdw(rgb_base + 0x50, rgb_src_format);
+			outpdw(rgb_base + 0x1008, constant_color);
+		}
+	} 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) {
+			/* no alpha on both pipe */
+			blend_op = (MDP4_BLEND_BG_ALPHA_BG_PIXEL |
+				MDP4_BLEND_FG_ALPHA_BG_PIXEL |
+				MDP4_BLEND_FG_INV_ALPHA);
+		}
+	}
+
+
+	if (pipe->transp != MDP_TRANSP_NOP) {
+		if (pipe->is_fg) {
+			transp_color_key(pipe->src_format, pipe->transp,
+					&c0, &c1, &c2);
+			/* Fg blocked */
+			blend_op |= MDP4_BLEND_FG_TRANSP_EN;
+			/* lower limit */
+			outpdw(overlay_base + off + 0x110,
+					(c1 << 16 | c0));/* low */
+			outpdw(overlay_base + off + 0x114, c2);/* low */
+			/* upper limit */
+			outpdw(overlay_base + off + 0x118,
+					(c1 << 16 | c0));
+			outpdw(overlay_base + off + 0x11c, c2);
+		} else {
+			transp_color_key(bg_pipe->src_format,
+				pipe->transp, &c0, &c1, &c2);
+			/* bg blocked */
+			blend_op |= MDP4_BLEND_BG_TRANSP_EN;
+			/* lower limit */
+			outpdw(overlay_base + 0x180,
+					(c1 << 16 | c0));/* low */
+			outpdw(overlay_base + 0x184, c2);/* low */
+			/* upper limit */
+			outpdw(overlay_base + 0x188,
+					(c1 << 16 | c0));/* high */
+			outpdw(overlay_base + 0x18c, c2);/* high */
+		}
+	}
+
+	outpdw(overlay_base + off + 0x104, blend_op);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
+{
+	struct mdp4_overlay_pipe *bg_pipe;
+	uint32 bits = 0;
+
+	if (pipe->mixer_num == MDP4_MIXER1)
+		bits |= 0x02;
+	else
+		bits |= 0x01;
+
+	if (all) {
+		if (pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
+			if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
+				bits |= 0x20;
+			else
+				bits |= 0x10;
+		} else {
+			if (pipe->is_fg && pipe->alpha == 0xFF) {
+				bg_pipe = mdp4_overlay_stage_pipe(
+							pipe->mixer_num,
+							MDP4_MIXER_STAGE_BASE);
+				if (bg_pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
+					if (bg_pipe->pipe_num ==
+							OVERLAY_PIPE_RGB2)
+						bits |= 0x20;
+					else
+						bits |= 0x10;
+				}
+			}
+			if (pipe->pipe_num == OVERLAY_PIPE_VG2)
+				bits |= 0x08;
+			else
+				bits |= 0x04;
+		}
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	outpdw(MDP_BASE + 0x18000, bits);	/* MDP_OVERLAY_REG_FLUSH */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+struct mdp4_overlay_pipe *mdp4_overlay_stage_pipe(int mixer, int stage)
+{
+	return ctrl->stage[mixer][stage];
+}
+
+struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx)
+{
+	struct mdp4_overlay_pipe *pipe;
+
+	if (ndx <= 0 || ndx > MDP4_MAX_PIPE)
+		return NULL;
+
+	pipe = &ctrl->plist[ndx - 1];	/* ndx start from 1 */
+
+	if (pipe->pipe_used == 0)
+		return NULL;
+
+	return pipe;
+}
+
+struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(
+		int ptype, int mixer, int req_share)
+{
+	int i, j, ndx, found;
+	struct mdp4_overlay_pipe *pipe, *opipe;
+	struct mdp4_pipe_desc  *pd;
+
+	found = 0;
+	pipe = &ctrl->plist[0];
+
+	for (i = 0; i < MDP4_MAX_PIPE; i++) {
+		if (pipe->pipe_type == ptype && pipe->pipe_used == 0) {
+			pd = &ctrl->ov_pipe[pipe->pipe_num];
+			if (pd->share) { /* pipe can be shared */
+				if (pd->ref_cnt == 0) {
+					/* not yet been used */
+					found++;
+					break;
+				}
+				/* pipe occupied already */
+				if (req_share && pd->ref_cnt < MDP4_MAX_SHARE) {
+					for (j = 0; j < MDP4_MAX_SHARE; j++) {
+						ndx = pd->ndx_list[j];
+						if (ndx != 0)
+							break;
+					}
+					/* ndx satrt from 1 */
+					opipe = &ctrl->plist[ndx - 1];
+					/*
+					 * occupied pipe willing to share and
+					 * same mixer
+					 */
+					if (opipe->pipe_share &&
+						opipe->mixer_num == mixer) {
+						found++;
+						break;
+					}
+				}
+			} else {	/* not a shared pipe */
+				if (req_share == 0  && pd->ref_cnt == 0) {
+					found++;
+					break;
+				}
+			}
+		}
+		pipe++;
+	}
+
+	if (found) {
+		init_completion(&pipe->comp);
+		init_completion(&pipe->dmas_comp);
+		pr_info("%s: pipe=%x ndx=%d num=%d share=%d cnt=%d\n",
+			__func__, (int)pipe, pipe->pipe_ndx, pipe->pipe_num,
+			pd->share, pd->ref_cnt);
+		return pipe;
+	}
+
+	pr_debug("%s: ptype=%d mixer=%d req_share=%d FAILED\n",
+			__func__, ptype, mixer, req_share);
+
+	return NULL;
+}
+
+
+void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
+{
+	int i;
+	uint32 ptype, num, ndx;
+	struct mdp4_pipe_desc  *pd;
+
+	pr_debug("%s: pipe=%x ndx=%d\n", __func__,
+				(int)pipe, pipe->pipe_ndx);
+	pd = &ctrl->ov_pipe[pipe->pipe_num];
+	if (pd->ref_cnt) {
+		pd->ref_cnt--;
+		for (i = 0; i < MDP4_MAX_SHARE; i++) {
+			if (pd->ndx_list[i] == pipe->pipe_ndx) {
+				pd->ndx_list[i] = 0;
+				break;
+			}
+		}
+	}
+
+	pd->player = NULL;
+
+	ptype = pipe->pipe_type;
+	num = pipe->pipe_num;
+	ndx = pipe->pipe_ndx;
+
+	memset(pipe, 0, sizeof(*pipe));
+
+	pipe->pipe_type = ptype;
+	pipe->pipe_num = num;
+	pipe->pipe_ndx = ndx;
+}
+
+int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer)
+{
+	struct mdp4_overlay_pipe *pipe;
+
+	pipe = ctrl->stage[mixer][z_order];
+
+	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_validate_downscale(struct mdp_overlay *req,
+	struct msm_fb_data_type *mfd, uint32 perf_level, uint32 pclk_rate)
+{
+	__u32 panel_clk_khz, mdp_clk_khz;
+	__u32 num_hsync_pix_clks, mdp_clks_per_hsync, src_wh;
+	__u32 hsync_period_ps, mdp_period_ps, total_hsync_period_ps;
+	unsigned long fill_rate_y_dir, fill_rate_x_dir;
+	unsigned long fillratex100, mdp_pixels_produced;
+	unsigned long mdp_clk_hz;
+
+	pr_debug("%s: LCDC Mode Downscale validation with MDP Core"
+		" Clk rate\n", __func__);
+	pr_debug("src_w %u, src_h %u, dst_w %u, dst_h %u\n",
+		req->src_rect.w, req->src_rect.h, req->dst_rect.w,
+		req->dst_rect.h);
+
+
+	panel_clk_khz = pclk_rate/1000;
+	mdp_clk_hz = mdp_perf_level2clk_rate(perf_level);
+
+	if (!mdp_clk_hz) {
+		pr_debug("mdp_perf_level2clk_rate returned 0,"
+				 "Downscale Validation incomplete\n");
+		return 0;
+	}
+
+	mdp_clk_khz = mdp_clk_hz/1000;
+
+	num_hsync_pix_clks = 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;
+
+	hsync_period_ps = 1000000000/panel_clk_khz;
+	mdp_period_ps = 1000000000/mdp_clk_khz;
+
+	total_hsync_period_ps = num_hsync_pix_clks * hsync_period_ps;
+	mdp_clks_per_hsync = total_hsync_period_ps/mdp_period_ps;
+
+	pr_debug("hsync_period_ps %u, mdp_period_ps %u,"
+		"total_hsync_period_ps %u\n", hsync_period_ps,
+		mdp_period_ps, total_hsync_period_ps);
+
+	src_wh = req->src_rect.w * req->src_rect.h;
+	if (src_wh % req->dst_rect.h)
+		fill_rate_y_dir = (src_wh / req->dst_rect.h) + 1;
+	else
+		fill_rate_y_dir = (src_wh / req->dst_rect.h);
+
+	fill_rate_x_dir = (mfd->panel_info.xres - req->dst_rect.w)
+		+ req->src_rect.w;
+
+	if (fill_rate_y_dir >= fill_rate_x_dir)
+		fillratex100 = 100 * fill_rate_y_dir / mfd->panel_info.xres;
+	else
+		fillratex100 = 100 * fill_rate_x_dir / mfd->panel_info.xres;
+
+	pr_debug("mdp_clks_per_hsync %u, fill_rate_y_dir %lu,"
+		"fill_rate_x_dir %lu\n", mdp_clks_per_hsync,
+		fill_rate_y_dir, fill_rate_x_dir);
+
+	mdp_pixels_produced = 100 * mdp_clks_per_hsync/fillratex100;
+	pr_debug("fillratex100 %lu, mdp_pixels_produced %lu\n",
+		fillratex100, mdp_pixels_produced);
+	if (mdp_pixels_produced <= mfd->panel_info.xres) {
+		pr_err("%s(): LCDC underflow detected during downscale\n",
+			__func__);
+		return -ERANGE;
+	}
+
+	return 0;
+}
+
+static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
+			struct mdp4_overlay_pipe **ppipe,
+			struct msm_fb_data_type *mfd)
+{
+	struct mdp4_overlay_pipe *pipe;
+	struct mdp4_pipe_desc  *pd;
+	int ret, ptype, req_share;
+	int j;
+
+	if (mfd == NULL) {
+		pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
+		return -ENODEV;
+	}
+
+	if (mixer >= MDP4_MAX_MIXER) {
+		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_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_err("%s: src img of zero size!\n", __func__);
+		mdp4_stat.err_size++;
+		return -EINVAL;
+	}
+
+
+	if (req->dst_rect.h > (req->src_rect.h * 8)) {	/* too much */
+		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 */
+		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 */
+		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 */
+		mdp4_stat.err_scale++;
+		pr_err("%s: scale down, too little (w)!\n", __func__);
+		return -ERANGE;
+	}
+
+	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) {
+		pr_err("%s: mdp4_overlay_format2type!\n", __func__);
+		return ptype;
+	}
+
+	req_share = (req->flags & MDP_OV_PIPE_SHARE);
+
+	if (req->id == MSMFB_NEW_REQUEST)  /* new request */
+		pipe = mdp4_overlay_pipe_alloc(ptype, mixer, req_share);
+	else
+		pipe = mdp4_overlay_ndx2pipe(req->id);
+
+	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_err("%s: h>h || w>w!\n", __func__);
+				return -ERANGE;
+			}
+	}
+
+	pipe->src_format = req->src.format;
+	ret = mdp4_overlay_format2pipe(pipe);
+	if (ret < 0) {
+		pr_err("%s: mdp4_overlay_format2pipe!\n", __func__);
+		return ret;
+	}
+
+	/*
+	 * base layer == 1, reserved for frame buffer
+	 * zorder 0 == stage 0 == 2
+	 * zorder 1 == stage 1 == 3
+	 * zorder 2 == stage 2 == 4
+	 */
+	if (req->id == MSMFB_NEW_REQUEST) {  /* new request */
+		pd = &ctrl->ov_pipe[pipe->pipe_num];
+		for (j = 0; j < MDP4_MAX_SHARE; j++) {
+			if (pd->ndx_list[j] == 0) {
+				pd->ndx_list[j] = pipe->pipe_ndx;
+				break;
+			}
+		}
+		pipe->pipe_share = req_share;
+		pd->ref_cnt++;
+		pipe->pipe_used++;
+		pipe->mixer_num = mixer;
+		pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
+		pr_debug("%s: zorder=%d pipe ndx=%d num=%d\n", __func__,
+			req->z_order, pipe->pipe_ndx, pipe->pipe_num);
+
+	}
+
+	pipe->src_width = req->src.width & 0x07ff;	/* source img width */
+	pipe->src_height = req->src.height & 0x07ff;	/* 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;
+	pipe->src_x = req->src_rect.x & 0x07ff;
+	pipe->dst_h = req->dst_rect.h & 0x07ff;
+	pipe->dst_w = req->dst_rect.w & 0x07ff;
+	pipe->dst_y = req->dst_rect.y & 0x07ff;
+	pipe->dst_x = req->dst_rect.x & 0x07ff;
+
+	pipe->op_mode = 0;
+
+	if (req->flags & MDP_FLIP_LR)
+		pipe->op_mode |= MDP4_OP_FLIP_LR;
+
+	if (req->flags & MDP_FLIP_UD)
+		pipe->op_mode |= MDP4_OP_FLIP_UD;
+
+	if (req->flags & MDP_DITHER)
+		pipe->op_mode |= MDP4_OP_DITHER_EN;
+
+	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;
+
+	*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)
+{
+	int put_needed, ret = 0, fb_num;
+	struct file *file;
+#ifdef CONFIG_ANDROID_PMEM
+	unsigned long vstart;
+#endif
+
+	if (img->flags & MDP_BLIT_SRC_GEM) {
+		*pp_file = NULL;
+		return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
+					 start, len);
+	}
+
+#ifdef CONFIG_ANDROID_PMEM
+	if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
+		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);
+	return ret;
+}
+
+int mdp4_overlay_3d(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;
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+	/* Only dsi_cmd panel support 3D */
+	if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+		mdp4_dsi_cmd_3d(mfd, req);
+		ret = 0;
+	}
+#endif
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	return ret;
+}
+
+#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	if (mfd == NULL)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
+		return -EINTR;
+
+	if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+		mdp4_dsi_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);
+
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	return 0;
+}
+
+int mdp4_overlay_blt_offset(struct fb_info *info, struct msmfb_overlay_blt *req)
+{
+	int ret = 0;
+
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
+		return -EINTR;
+
+	if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+		ret = mdp4_dsi_overlay_blt_offset(mfd, req);
+	else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
+		ret = mdp4_dsi_video_overlay_blt_offset(mfd, req);
+	else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+		ret = mdp4_lcdc_overlay_blt_offset(mfd, req);
+
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	return ret;
+}
+#endif
+
+int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
+{
+	struct mdp4_overlay_pipe *pipe;
+
+	pipe = mdp4_overlay_ndx2pipe(req->id);
+	if (pipe == NULL)
+		return -ENODEV;
+
+	*req = pipe->req_data;
+
+	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_PERF_LEVEL1	1
+#define OVERLAY_PERF_LEVEL2	2
+#define OVERLAY_PERF_LEVEL3	3
+#define OVERLAY_PERF_LEVEL4	4
+
+#ifdef CONFIG_MSM_BUS_SCALING
+#define OVERLAY_BUS_SCALE_TABLE_BASE	6
+#endif
+
+static int mdp4_overlay_is_rgb_type(int format)
+{
+	switch (format) {
+	case MDP_RGB_565:
+	case MDP_RGB_888:
+	case MDP_BGR_565:
+	case MDP_XRGB_8888:
+	case MDP_ARGB_8888:
+	case MDP_RGBA_8888:
+	case MDP_BGRA_8888:
+	case MDP_RGBX_8888:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static uint32 mdp4_overlay_get_perf_level(struct mdp_overlay *req)
+{
+	int is_fg;
+
+	if (req->is_fg && ((req->alpha & 0x0ff) == 0xff))
+		is_fg = 1;
+
+	if (req->flags & MDP_DEINTERLACE)
+		return OVERLAY_PERF_LEVEL1;
+
+	if (mdp4_overlay_is_rgb_type(req->src.format) && is_fg &&
+		((req->src.width * req->src.height) <= OVERLAY_WSVGA_SIZE))
+		return OVERLAY_PERF_LEVEL4;
+	else if (mdp4_overlay_is_rgb_type(req->src.format))
+		return OVERLAY_PERF_LEVEL1;
+
+	if (ctrl->ov_pipe[OVERLAY_PIPE_VG1].ref_cnt &&
+		ctrl->ov_pipe[OVERLAY_PIPE_VG2].ref_cnt)
+		return OVERLAY_PERF_LEVEL1;
+
+	if (req->src.width*req->src.height <= OVERLAY_VGA_SIZE)
+		return OVERLAY_PERF_LEVEL3;
+	else if (req->src.width*req->src.height <= OVERLAY_720P_TILE_SIZE)
+		return OVERLAY_PERF_LEVEL2;
+	else
+		return OVERLAY_PERF_LEVEL1;
+}
+
+int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	int ret, mixer;
+	struct mdp4_overlay_pipe *pipe;
+
+	if (mfd == NULL) {
+		pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
+		return -ENODEV;
+	}
+
+	if (!mfd->panel_power_on)	/* suspended */
+		return -EPERM;
+
+	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;
+	}
+
+	perf_level = mdp4_overlay_get_perf_level(req);
+
+	if ((mfd->panel_info.type == LCDC_PANEL) &&
+	    (req->src_rect.h >
+		req->dst_rect.h || req->src_rect.w > req->dst_rect.w)) {
+		if (mdp4_overlay_validate_downscale(req, mfd,
+			perf_level, mfd->panel_info.clk_rate)) {
+			mutex_unlock(&mfd->dma->ov_mutex);
+			return -ERANGE;
+		}
+	}
+	if ((mfd->panel_info.type == MIPI_VIDEO_PANEL) &&
+	    (req->src_rect.h >
+		req->dst_rect.h || req->src_rect.w > req->dst_rect.w)) {
+		if (mdp4_overlay_validate_downscale(req, mfd,
+			perf_level, (&mfd->panel_info.mipi)->dsi_pclk_rate)) {
+			mutex_unlock(&mfd->dma->ov_mutex);
+			return -ERANGE;
+		}
+	}
+	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;
+	}
+
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+	/*
+	 * writeback (blt) mode to provide work around for
+	 * dsi cmd mode interface hardware bug.
+	 */
+	if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+		if (mixer == MDP4_MIXER0 && req->dst_rect.x != 0) {
+			mdp4_dsi_blt_dmap_busy_wait(mfd);
+			mdp4_dsi_overlay_blt_start(mfd);
+		}
+	}
+#endif
+
+	/* return id back to user */
+	req->id = pipe->pipe_ndx;	/* pipe_ndx start from 1 */
+	pipe->req_data = *req;		/* keep original req */
+
+	pipe->flags = req->flags;
+
+	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_warn("%s: No sharpening while downscaling.\n",
+								__func__);
+			pipe->flags &= ~MDP_SHARPENING;
+		}
+	}
+
+	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);
+	}
+
+	mdp4_del_res_rel = 0;
+	mutex_unlock(&mfd->dma->ov_mutex);
+	mdp_set_core_clk(perf_level);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (pipe->mixer_num == MDP4_MIXER0) {
+		mdp_bus_scale_update_request(OVERLAY_BUS_SCALE_TABLE_BASE
+						- perf_level);
+	}
+#endif
+
+	return 0;
+}
+
+void  mdp4_overlay_resource_release(void)
+{
+	if (mdp4_del_res_rel) {
+		mdp_set_core_clk(OVERLAY_PERF_LEVEL4);
+		mdp4_del_res_rel = 0;
+	}
+}
+
+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;
+	uint32 flags;
+
+	if (mfd == NULL)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
+		return -EINTR;
+
+	pipe = mdp4_overlay_ndx2pipe(ndx);
+
+	if (pipe == NULL) {
+		mutex_unlock(&mfd->dma->ov_mutex);
+		return -ENODEV;
+	}
+
+	if (pipe->mixer_num == MDP4_MIXER1)
+		ctrl->mixer1_played = 0;
+	else {
+		/* mixer 0 */
+		ctrl->mixer0_played = 0;
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+			if (mfd->panel_power_on) {
+				mdp4_dsi_blt_dmap_busy_wait(mfd);
+			}
+		}
+#else
+		if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
+			if (mfd->panel_power_on)
+				mdp4_mddi_dma_busy_wait(mfd);
+		}
+#endif
+	}
+
+	mdp4_mixer_stage_down(pipe);
+
+	if (pipe->mixer_num == MDP4_MIXER0) {
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+			if (mfd->panel_power_on)
+				if (mdp4_dsi_overlay_blt_stop(mfd) == 0)
+					mdp4_dsi_cmd_overlay_restore();
+		}  else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
+			flags = pipe->flags;
+			pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
+			mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
+			pipe->flags = flags;
+		}
+#else
+		if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
+			if (mdp_hw_revision == MDP4_REVISION_V2_1)
+				mdp4_overlay_status_write(
+					MDP4_OVERLAY_TYPE_UNSET, true);
+			if (mfd->panel_power_on)
+				mdp4_mddi_overlay_restore();
+		}
+#endif
+		else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
+			flags = pipe->flags;
+			pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
+			mdp4_overlay_lcdc_vsync_push(mfd, pipe);
+			pipe->flags = flags;
+		}
+	}
+#ifdef CONFIG_FB_MSM_DTV
+	else {	/* mixer1, DTV, ATV */
+		flags = pipe->flags;
+		pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
+		mdp4_overlay_dtv_vsync_push(mfd, pipe);
+		pipe->flags = flags;
+	}
+#endif
+
+	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))
+		mdp4_del_res_rel = 1;
+
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	if (pipe->mixer_num == MDP4_MIXER0)
+		if (mfd->panel_power_on)
+			mdp_bus_scale_update_request(2);
+#endif
+	return 0;
+}
+
+struct tile_desc {
+	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)
+{
+	/*
+	 * each row of samsung tile consists of two tiles in height
+	 * and two tiles in width which means width should align to
+	 * 64 x 2 bytes and height should align to 32 x 2 bytes.
+	 * video decoder generate two tiles in width and one tile
+	 * in height which ends up height align to 32 X 1 bytes.
+	 */
+	tp->width = 64;		/* 64 bytes */
+	tp->row_tile_w = 2;	/* 2 tiles per row's width */
+	tp->height = 32;	/* 32 bytes */
+	tp->row_tile_h = 1;	/* 1 tiles per row's height */
+}
+
+uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
+{
+	uint32 tile_w, tile_h;
+	uint32 row_num_w, row_num_h;
+
+
+	tile_w = tp->width * tp->row_tile_w;
+	tile_h = tp->height * tp->row_tile_h;
+
+	row_num_w = (pipe->src_width + tile_w - 1) / tile_w;
+	row_num_h = (pipe->src_height + tile_h - 1) / tile_h;
+	return ((row_num_w * row_num_h * tile_w * tile_h) + 8191) & ~8191;
+}
+
+int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
+		struct file **pp_src_file, struct file **pp_src_plane1_file,
+		struct file **pp_src_plane2_file)
+{
+	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;
+	struct file *p_src_plane1_file = 0, *p_src_plane2_file = 0;
+	uint32_t overlay_version = 0;
+
+	if (mfd == NULL)
+		return -ENODEV;
+
+	if (!mfd->panel_power_on) /* suspended */
+		return -EPERM;
+
+	pipe = mdp4_overlay_ndx2pipe(req->id);
+	if (pipe == NULL) {
+		pr_err("%s: req_id=%d Error\n", __func__, req->id);
+		return -ENODEV;
+	}
+
+	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
+		return -EINTR;
+
+	pd = &ctrl->ov_pipe[pipe->pipe_num];
+	if (pd->player && pipe != pd->player) {
+		if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
+			mutex_unlock(&mfd->dma->ov_mutex);
+			return 0; /* ignore it, kicked out already */
+		}
+	}
+
+	pd->player = pipe;	/* keep */
+
+	img = &req->data;
+	get_img(img, info, &start, &len, &p_src_file);
+	if (len == 0) {
+		mutex_unlock(&mfd->dma->ov_mutex);
+		pr_err("%s: pmem Error\n", __func__);
+		return -1;
+	}
+	*pp_src_file = p_src_file;
+
+	addr = start + img->offset;
+	pipe->srcp0_addr = addr;
+	pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
+
+	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 (overlay_version > 0) {
+			img = &req->plane1_data;
+			get_img(img, info, &start, &len, &p_src_plane1_file);
+			if (len == 0) {
+				mutex_unlock(&mfd->dma->ov_mutex);
+				pr_err("%s: Error to get plane1\n", __func__);
+				return -EINVAL;
+			}
+			pipe->srcp1_addr = start + img->offset;
+			*pp_src_plane1_file = p_src_plane1_file;
+		} 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);
+		}
+		pipe->srcp0_ystride = pipe->src_width;
+		if ((pipe->src_format == MDP_Y_CRCB_H1V1) ||
+			(pipe->src_format == MDP_Y_CBCR_H1V1)) {
+			if (pipe->src_width > YUV_444_MAX_WIDTH)
+				pipe->srcp1_ystride = pipe->src_width << 2;
+			else
+				pipe->srcp1_ystride = pipe->src_width << 1;
+		} else
+			pipe->srcp1_ystride = pipe->src_width;
+
+	} else if (pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
+		if (overlay_version > 0) {
+			img = &req->plane1_data;
+			get_img(img, info, &start, &len, &p_src_plane1_file);
+			if (len == 0) {
+				mutex_unlock(&mfd->dma->ov_mutex);
+				pr_err("%s: Error to get plane1\n", __func__);
+				return -EINVAL;
+			}
+			pipe->srcp1_addr = start + img->offset;
+			*pp_src_plane1_file = p_src_plane1_file;
+
+			img = &req->plane2_data;
+			get_img(img, info, &start, &len, &p_src_plane2_file);
+			if (len == 0) {
+				mutex_unlock(&mfd->dma->ov_mutex);
+				pr_err("%s: Error to get plane2\n", __func__);
+				return -EINVAL;
+			}
+			pipe->srcp2_addr = start + img->offset;
+			*pp_src_plane2_file = p_src_plane2_file;
+		} 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;
+		}
+		pipe->srcp0_ystride = pipe->src_width;
+		pipe->srcp1_ystride = pipe->src_width / 2;
+		pipe->srcp2_ystride = pipe->src_width / 2;
+	}
+
+	if (pipe->pipe_num >= OVERLAY_PIPE_VG1)
+		mdp4_overlay_vg_setup(pipe);	/* video/graphic pipe */
+	else {
+		if (pipe->flags & MDP_SHARPENING) {
+			pr_warn(
+			"%s: Sharpening/Smoothing not supported on RGB pipe\n",
+								     __func__);
+			pipe->flags &= ~MDP_SHARPENING;
+		}
+		mdp4_overlay_rgb_setup(pipe);	/* rgb pipe */
+	}
+
+	mdp4_mixer_blend_setup(pipe);
+	mdp4_mixer_stage_up(pipe);
+
+	if (pipe->mixer_num == MDP4_MIXER1) {
+		ctrl->mixer1_played++;
+		/* enternal interface */
+		if (ctrl->panel_mode & MDP4_PANEL_DTV)
+#ifdef CONFIG_FB_MSM_DTV
+			mdp4_overlay_dtv_ov_done_push(mfd, pipe);
+#else
+			mdp4_overlay_reg_flush(pipe, 1);
+#endif
+		else if (ctrl->panel_mode & MDP4_PANEL_ATV)
+			mdp4_overlay_reg_flush(pipe, 1);
+	} else {
+		/* primary interface */
+		ctrl->mixer0_played++;
+		if (ctrl->panel_mode & MDP4_PANEL_LCDC)
+			mdp4_overlay_lcdc_vsync_push(mfd, pipe);
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+		else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
+			mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
+#endif
+		else {
+			/* mddi & mipi dsi cmd mode */
+			if (pipe->flags & MDP_OV_PLAY_NOWAIT) {
+				mdp4_stat.overlay_play[pipe->mixer_num]++;
+				mutex_unlock(&mfd->dma->ov_mutex);
+				return 0;
+			}
+#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
+		}
+	}
+
+	mdp4_stat.overlay_play[pipe->mixer_num]++;
+
+	mutex_unlock(&mfd->dma->ov_mutex);
+
+	return 0;
+}
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
new file mode 100644
index 0000000..8dcdec0
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -0,0 +1,189 @@
+/* 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/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;
+	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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	if (atv_pipe == NULL) {
+		ptype = mdp4_overlay_format2type(mfd->fb_imgType);
+		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1, 0);
+		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;
+	pipe->srcp0_addr = (uint32) buf;
+	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_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	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);
+
+	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;
+	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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	mutex_lock(&mfd->dma->ov_mutex);
+
+	pipe = atv_pipe;
+	pipe->srcp0_addr = (uint32) buf;
+	mdp4_overlay_rgb_setup(pipe);
+	mdp4_overlay_reg_flush(pipe, 1); /* rgb2 and mixer1 */
+
+	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_stat.kickoff_atv++;
+	mdp4_overlay_resource_release();
+	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..22d9d3b
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -0,0 +1,672 @@
+/* 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/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"
+#include "mipi_dsi.h"
+
+static struct mdp4_overlay_pipe *dsi_pipe;
+static struct msm_fb_data_type *dsi_mfd;
+static int busy_wait_cnt;
+static int dsi_state;
+static unsigned long  tout_expired;
+
+#define TOUT_PERIOD	HZ	/* 1 second */
+#define MS_100		(HZ/10)	/* 100 ms */
+
+static int vsync_start_y_adjust = 4;
+
+struct timer_list dsi_clock_timer;
+
+static int writeback_offset;
+
+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);
+}
+
+static void dsi_clock_tout(unsigned long data)
+{
+	if (mipi_dsi_clk_on) {
+		if (dsi_state == ST_DSI_PLAYING) {
+			mdp4_stat.dsi_clkoff++;
+			mipi_dsi_clk_disable();
+			mdp4_overlay_dsi_state_set(ST_DSI_CLK_OFF);
+		}
+	}
+}
+
+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_overlay_update_dsi_cmd(struct msm_fb_data_type *mfd)
+{
+	MDPIBUF *iBuf = &mfd->ibuf;
+	struct fb_info *fbi;
+	uint8 *src;
+	int ptype;
+	struct mdp4_overlay_pipe *pipe;
+	int bpp;
+	int ret;
+
+	if (mfd->key != MFD_KEY)
+		return;
+
+	dsi_mfd = mfd;		/* keep it */
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	if (dsi_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, 0);
+		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_DSI_CMD);
+		ret = mdp4_overlay_format2pipe(pipe);
+		if (ret < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+
+		init_timer(&dsi_clock_timer);
+		dsi_clock_timer.function = dsi_clock_tout;
+		dsi_clock_timer.data = (unsigned long) mfd;;
+		dsi_clock_timer.expires = 0xffffffff;
+		add_timer(&dsi_clock_timer);
+		tout_expired = jiffies;
+
+		dsi_pipe = pipe; /* keep it */
+
+		fbi = mfd->fbi;
+		bpp = fbi->var.bits_per_pixel / 8;
+		src = (uint8 *) iBuf->buf;
+		writeback_offset = mdp4_overlay_writeback_setup(
+						fbi, pipe, src, bpp);
+
+		/*
+		 * configure dsi stream id
+		 * dma_p = 0, dma_s = 1
+		 */
+		MDP_OUTP(MDP_BASE + 0x000a0, 0x10);
+		/* enable dsi trigger on dma_p */
+		MDP_OUTP(MDP_BASE + 0x000a4, 0x01);
+	} else {
+		pipe = dsi_pipe;
+	}
+
+	/* whole screen for base layer */
+	src = (uint8 *) iBuf->buf;
+
+
+	{
+		struct fb_info *fbi;
+
+		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;
+	}
+
+
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_dmap_xy(pipe);
+
+	mdp4_overlay_dmap_cfg(mfd, 0);
+
+	mdp4_mipi_vsync_enable(mfd, pipe, 0);
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	wmb();
+}
+
+void mdp4_dsi_cmd_3d(struct msm_fb_data_type *mfd, struct msmfb_overlay_3d *r3d)
+{
+	struct fb_info *fbi;
+	struct mdp4_overlay_pipe *pipe;
+	int bpp;
+	uint8 *src = NULL;
+
+	if (dsi_pipe == NULL)
+		return;
+
+	dsi_pipe->is_3d = r3d->is_3d;
+	dsi_pipe->src_height_3d = r3d->height;
+	dsi_pipe->src_width_3d = r3d->width;
+
+	pipe = dsi_pipe;
+
+	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);
+
+	if (mfd->panel_power_on) {
+		mdp4_dsi_cmd_dma_busy_wait(mfd);
+		mdp4_dsi_blt_dmap_busy_wait(mfd);
+	}
+
+	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_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_dmap_xy(pipe);
+
+	mdp4_overlay_dmap_cfg(mfd, 0);
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+
+#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+int mdp4_dsi_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	pr_debug("%s: blt_end=%d blt_addr=%x pid=%d\n",
+	__func__, dsi_pipe->blt_end, (int)dsi_pipe->blt_addr, current->pid);
+
+	if (dsi_pipe->blt_addr == 0) {
+		mdp4_dsi_cmd_dma_busy_wait(mfd);
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		dsi_pipe->blt_end = 0;
+		dsi_pipe->blt_cnt = 0;
+		dsi_pipe->ov_cnt = 0;
+		dsi_pipe->dmap_cnt = 0;
+		dsi_pipe->blt_addr = dsi_pipe->blt_base;
+		mdp4_stat.writeback++;
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		return 0;
+	}
+
+	return -EBUSY;
+}
+
+int mdp4_dsi_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+
+	pr_debug("%s: blt_end=%d blt_addr=%x\n",
+		 __func__, dsi_pipe->blt_end, (int)dsi_pipe->blt_addr);
+
+	if ((dsi_pipe->blt_end == 0) && dsi_pipe->blt_addr) {
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		dsi_pipe->blt_end = 1;	/* mark as end */
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		return 0;
+	}
+
+	return -EBUSY;
+}
+
+int mdp4_dsi_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	req->offset = writeback_offset;
+	req->width = dsi_pipe->src_width;
+	req->height = dsi_pipe->src_height;
+	req->bpp = dsi_pipe->bpp;
+
+	return sizeof(*req);
+}
+
+void mdp4_dsi_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	if (req->enable)
+		mdp4_dsi_overlay_blt_start(mfd);
+	else if (req->enable == 0)
+		mdp4_dsi_overlay_blt_stop(mfd);
+
+}
+#else
+int mdp4_dsi_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	return 0;
+}
+int mdp4_dsi_overlay_blt_start(struct msm_fb_data_type *mfd)
+{
+	return -EBUSY;
+}
+int mdp4_dsi_overlay_blt_stop(struct msm_fb_data_type *mfd)
+{
+	return -EBUSY;
+}
+#endif
+
+void mdp4_blt_xy_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr, addr2;
+	int bpp;
+	char *overlay_base;
+
+
+	if (pipe->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->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->blt_addr + off;
+	/* overlay 0 */
+	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+	outpdw(overlay_base + 0x000c, addr2);
+	outpdw(overlay_base + 0x001c, addr2);
+}
+
+
+/*
+ * mdp4_dmap_done_dsi: called from isr
+ * DAM_P_DONE only used when blt enabled
+ */
+void mdp4_dma_p_done_dsi(struct mdp_dma_data *dma)
+{
+	int diff;
+
+	dsi_pipe->dmap_cnt++;
+	diff = dsi_pipe->ov_cnt - dsi_pipe->dmap_cnt;
+	pr_debug("%s: ov_cnt=%d dmap_cnt=%d\n",
+			__func__, dsi_pipe->ov_cnt, dsi_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 (dsi_pipe->blt_end) {
+			dsi_pipe->blt_end = 0;
+			dsi_pipe->blt_addr = 0;
+			pr_debug("%s: END, ov_cnt=%d dmap_cnt=%d\n",
+				__func__, dsi_pipe->ov_cnt, dsi_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(dsi_pipe);
+	/* kick off dmap */
+	outpdw(MDP_BASE + 0x000c, 0x0);
+	/* trigger dsi cmd engine */
+	mipi_dsi_cmd_mdp_sw_trigger();
+
+	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+}
+
+
+/*
+ * mdp4_overlay0_done_dsi_cmd: called from isr
+ */
+void mdp4_overlay0_done_dsi_cmd(struct mdp_dma_data *dma)
+{
+	int diff;
+
+	if (dsi_pipe->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 (dsi_pipe->blt_end == 0)
+		dsi_pipe->ov_cnt++;
+
+	pr_debug("%s: ov_cnt=%d dmap_cnt=%d\n",
+			__func__, dsi_pipe->ov_cnt, dsi_pipe->dmap_cnt);
+
+	if (dsi_pipe->blt_cnt == 0) {
+		/* first kickoff since blt enabled */
+		mdp_intr_mask |= INTR_DMA_P_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	}
+	dsi_pipe->blt_cnt++;
+
+	diff = dsi_pipe->ov_cnt - dsi_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(dsi_pipe);
+	mdp_enable_irq(MDP_DMA2_TERM);	/* enable intr */
+	/* kick off dmap */
+	outpdw(MDP_BASE + 0x000c, 0x0);
+	/* trigger dsi cmd engine */
+	mipi_dsi_cmd_mdp_sw_trigger();
+	mdp_disable_irq_nosync(MDP_OVERLAY0_TERM);
+}
+
+void mdp4_dsi_cmd_overlay_restore(void)
+{
+	/* mutex holded by caller */
+	if (dsi_mfd && dsi_pipe) {
+		mdp4_dsi_cmd_dma_busy_wait(dsi_mfd);
+		mdp4_overlay_update_dsi_cmd(dsi_mfd);
+
+		if (dsi_pipe->blt_addr)
+			mdp4_dsi_blt_dmap_busy_wait(dsi_mfd);
+		mdp4_dsi_cmd_overlay_kickoff(dsi_mfd, dsi_pipe);
+	}
+}
+
+void mdp4_dsi_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_dsi_cmd_dma_busy_wait: check dsi link activity
+ * dsi 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_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+	int need_wait = 0;
+
+
+
+	if (dsi_clock_timer.function) {
+		if (time_after(jiffies, tout_expired)) {
+			tout_expired = jiffies + TOUT_PERIOD;
+			mod_timer(&dsi_clock_timer, tout_expired);
+			tout_expired -= MS_100;
+		}
+	}
+
+	pr_debug("%s: start pid=%d dsi_clk_on=%d\n",
+			__func__, current->pid, mipi_dsi_clk_on);
+
+	/* satrt dsi clock if necessary */
+	if (mipi_dsi_clk_on == 0) {
+		local_bh_disable();
+		mipi_dsi_clk_enable();
+		local_bh_enable();
+	}
+
+	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 dsi_clk_on=%d\n",
+				__func__, current->pid, mipi_dsi_clk_on);
+		wait_for_completion(&mfd->dma->comp);
+	}
+	pr_debug("%s: done pid=%d dsi_clk_on=%d\n",
+			 __func__, current->pid, mipi_dsi_clk_on);
+}
+
+void mdp4_dsi_cmd_kickoff_video(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+	if (dsi_pipe->blt_addr && dsi_pipe->blt_cnt == 0)
+		mdp4_overlay_update_dsi_cmd(mfd);
+
+	pr_debug("%s: pid=%d\n", __func__, current->pid);
+
+	if (dsi_pipe->blt_addr)
+		mdp4_dsi_blt_dmap_busy_wait(dsi_mfd);
+
+	mdp4_dsi_cmd_overlay_kickoff(mfd, pipe);
+}
+
+void mdp4_dsi_cmd_kickoff_ui(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+
+	pr_debug("%s: pid=%d\n", __func__, current->pid);
+	mdp4_dsi_cmd_overlay_kickoff(mfd, pipe);
+}
+
+
+void mdp4_dsi_cmd_overlay_kickoff(struct msm_fb_data_type *mfd,
+				struct mdp4_overlay_pipe *pipe)
+{
+	unsigned long flag;
+
+
+	mdp4_overlay_dsi_state_set(ST_DSI_PLAYING);
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_OVERLAY0_TERM);
+	mfd->dma->busy = TRUE;
+	if (dsi_pipe->blt_addr)
+		mfd->dma->dmap_busy = TRUE;
+	/* start OVERLAY pipe */
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
+
+	if (dsi_pipe->blt_addr == 0) {
+		/* trigger dsi cmd engine */
+		mipi_dsi_cmd_mdp_sw_trigger();
+	}
+}
+
+void mdp4_dsi_cmd_overlay(struct msm_fb_data_type *mfd)
+{
+	mutex_lock(&mfd->dma->ov_mutex);
+
+	if (mfd && mfd->panel_power_on) {
+		mdp4_dsi_cmd_dma_busy_wait(mfd);
+
+		if (dsi_pipe && dsi_pipe->blt_addr)
+			mdp4_dsi_blt_dmap_busy_wait(mfd);
+
+		mdp4_overlay_update_dsi_cmd(mfd);
+
+		mdp4_dsi_cmd_kickoff_ui(mfd, dsi_pipe);
+
+
+		mdp4_stat.kickoff_dsi++;
+
+	/* signal if pan function is waiting for the update completion */
+		if (mfd->pan_waiting) {
+			mfd->pan_waiting = FALSE;
+			complete(&mfd->pan_comp);
+		}
+	}
+	mdp4_overlay_resource_release();
+	mutex_unlock(&mfd->dma->ov_mutex);
+}
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..88b81e7
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -0,0 +1,404 @@
+/* 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 <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 <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include "mdp.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+
+#define DSI_VIDEO_BASE	0xE0000
+
+static int first_pixel_start_x;
+static int first_pixel_start_y;
+
+static int writeback_offset;
+
+static struct mdp4_overlay_pipe *dsi_pipe;
+
+static cmd_fxn_t display_on;
+
+void mdp4_dsi_video_fxn_register(cmd_fxn_t fxn)
+{
+	display_on = fxn;
+}
+
+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;
+	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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	if (dsi_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, 0);
+		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__);
+
+		dsi_pipe = pipe; /* keep it */
+
+		writeback_offset = mdp4_overlay_writeback_setup(
+						fbi, pipe, buf, bpp);
+	} else {
+		pipe = dsi_pipe;
+	}
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	if (is_mdp4_hw_reset()) {
+		mdp4_hw_init();
+		outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+	}
+
+	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->srcp0_addr = (uint32) buf;
+	pipe->srcp0_ystride = fbi->fix.line_length;
+	pipe->bpp = bpp;
+
+	pipe->dst_h = fbi->var.yres;
+	pipe->dst_w = fbi->var.xres;
+
+	mdp4_overlay_dmap_xy(pipe);	/* dma_p */
+	mdp4_overlay_dmap_cfg(mfd, 1);
+
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	/*
+	 * 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.mipi.xres_pad;
+	dsi_height = mfd->panel_info.yres +
+		mfd->panel_info.mipi.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_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);
+	mdp4_overlay_reg_flush(pipe, 1);
+	mdp_histogram_ctrl(TRUE);
+
+	ret = panel_next_on(pdev);
+	if (ret == 0) {
+		/* enable DSI block */
+		MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1);
+		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+		if (display_on != NULL) {
+			msleep(50);
+			display_on(pdev);
+		}
+	}
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return ret;
+}
+
+int mdp4_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);
+	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	mdp_histogram_ctrl(FALSE);
+	ret = panel_next_off(pdev);
+
+#ifdef MIPI_DSI_RGB_UNSTAGE
+	/* delay to make sure the last frame finishes */
+	msleep(100);
+
+	/* dis-engage rgb0 from mixer0 */
+	if (dsi_pipe)
+		mdp4_mixer_stage_down(dsi_pipe);
+#endif
+
+	return ret;
+}
+
+#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+int mdp4_dsi_video_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	req->offset = writeback_offset;
+	req->width = dsi_pipe->src_width;
+	req->height = dsi_pipe->src_height;
+	req->bpp = dsi_pipe->bpp;
+
+	return sizeof(*req);
+}
+
+void mdp4_dsi_video_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	unsigned long flag;
+	int change = 0;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	if (req->enable && dsi_pipe->blt_addr == 0) {
+		dsi_pipe->blt_addr = dsi_pipe->blt_base;
+		change++;
+	} else if (req->enable == 0 && dsi_pipe->blt_addr) {
+		dsi_pipe->blt_addr = 0;
+		change++;
+	}
+	pr_debug("%s: blt_addr=%x\n", __func__, (int)dsi_pipe->blt_addr);
+	dsi_pipe->blt_cnt = 0;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	if (!change)
+		return;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	/*
+	 * it does not work by turnning dsi video timing enerator off
+	 * and configure new changes and tune it back on like LCDC.
+	 */
+	mdp4_overlayproc_cfg(dsi_pipe);
+	mdp4_overlay_dmap_xy(dsi_pipe);
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+#else
+int mdp4_dsi_video_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	return 0;
+}
+void mdp4_dsi_video_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	return;
+}
+#endif
+
+void mdp4_overlay_dsi_video_wait4vsync(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	 /* enable irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_DMA2_TERM);	/* enable intr */
+	INIT_COMPLETION(dsi_pipe->comp);
+	mfd->dma->waiting = TRUE;
+	outp32(MDP_INTR_CLEAR, INTR_PRIMARY_VSYNC);
+	mdp_intr_mask |= INTR_PRIMARY_VSYNC;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	wait_for_completion_killable(&dsi_pipe->comp);
+	mdp_disable_irq(MDP_DMA2_TERM);
+}
+
+void mdp4_overlay_dsi_video_vsync_push(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+
+	mdp4_overlay_reg_flush(pipe, 1);
+	if (pipe->flags & MDP_OV_PLAY_NOWAIT)
+		return;
+
+	mdp4_overlay_dsi_video_wait4vsync(mfd);
+}
+
+/*
+ * mdp4_primary_vsync_dsi_video: called from isr
+ */
+void mdp4_primary_vsync_dsi_video(void)
+{
+	complete_all(&dsi_pipe->comp);
+}
+
+/*
+ * mdp4_overlay1_done_dsi: called from isr
+ */
+void mdp4_overlay0_done_dsi_video()
+{
+	complete(&dsi_pipe->comp);
+}
+
+
+void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	int bpp;
+	struct mdp4_overlay_pipe *pipe;
+
+	if (!mfd->panel_power_on)
+		return;
+
+	/* no need to power on cmd block since it's dsi video mode */
+	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;
+
+	mutex_lock(&mfd->dma->ov_mutex);
+
+	pipe = dsi_pipe;
+	pipe->srcp0_addr = (uint32) buf;
+	mdp4_overlay_rgb_setup(pipe);
+	mutex_unlock(&mfd->dma->ov_mutex);
+	mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
+	mdp4_stat.kickoff_dsi++;
+	mdp4_overlay_resource_release();
+}
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
new file mode 100644
index 0000000..71b460c
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -0,0 +1,404 @@
+/* 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/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
+
+/*#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;
+
+static struct mdp4_overlay_pipe *dtv_pipe;
+
+int mdp4_dtv_on(struct platform_device *pdev)
+{
+	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;
+	uint8 *buf;
+	int bpp, ptype;
+	uint32 format;
+	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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	if (bpp == 2)
+		format = MDP_RGB_565;
+	else if (bpp == 3)
+		format = MDP_RGB_888;
+	else
+		format = MDP_ARGB_8888;
+
+	if (dtv_pipe == NULL) {
+		ptype = mdp4_overlay_format2type(format);
+		if (ptype < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER1, 0);
+		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_MIXER1;
+		pipe->src_format = format;
+		mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DTV);
+		ret = mdp4_overlay_format2pipe(pipe);
+		if (ret < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+
+		dtv_pipe = pipe; /* keep it */
+	} else {
+		pipe = dtv_pipe;
+	}
+
+	/* 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->src_y = 0;
+	pipe->src_x = 0;
+	pipe->srcp0_addr = (uint32) buf;
+	pipe->srcp0_ystride = fbi->fix.line_length;
+
+	mdp4_overlay_dmae_xy(pipe);	/* dma_e */
+	mdp4_overlay_dmae_cfg(mfd, 0);
+
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	/*
+	 * 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); */
+
+	ret = panel_next_on(pdev);
+	if (ret == 0) {
+		/* enable DTV block */
+		MDP_OUTP(MDP_BASE + DTV_BASE, 1);
+		mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		dev_info(&pdev->dev, "mdp4_overlay_dtv: on");
+	} else {
+		dev_warn(&pdev->dev, "mdp4_overlay_dtv: panel_next_on failed");
+	}
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	return ret;
+}
+
+int mdp4_dtv_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 + DTV_BASE, 0);
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	/*
+	 * wait for vsync == 16.6 ms to make sure
+	 * the last frame finishes
+	*/
+	msleep(20);
+	pr_info("%s\n", __func__);
+
+	ret = panel_next_off(pdev);
+
+	/* dis-engage rgb2 from mixer1 */
+	if (dtv_pipe)
+		mdp4_mixer_stage_down(dtv_pipe);
+
+	/*
+	 * wait for another vsync == 16.6 ms to make sure
+	 * rgb2 dis-engaged
+	*/
+	msleep(20);
+
+	return ret;
+}
+
+static void mdp4_overlay_dtv_wait4vsync(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	/* enable irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_OVERLAY1_TERM);
+	INIT_COMPLETION(dtv_pipe->comp);
+	mfd->dma->waiting = TRUE;
+	outp32(MDP_INTR_CLEAR, INTR_EXTERNAL_VSYNC);
+	mdp_intr_mask |= INTR_EXTERNAL_VSYNC;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	wait_for_completion_killable(&dtv_pipe->comp);
+	mdp_disable_irq(MDP_OVERLAY1_TERM);
+}
+
+void mdp4_overlay_dtv_vsync_push(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+
+	mdp4_overlay_reg_flush(pipe, 1);
+	if (pipe->flags & MDP_OV_PLAY_NOWAIT)
+		return;
+
+	mdp4_overlay_dtv_wait4vsync(mfd);
+}
+
+static void mdp4_overlay_dtv_wait4_ov_done(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	/* enable irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_OVERLAY1_TERM);
+	INIT_COMPLETION(dtv_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(&dtv_pipe->comp);
+	mdp_disable_irq(MDP_OVERLAY1_TERM);
+}
+
+void mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+
+	mdp4_overlay_reg_flush(pipe, 1);
+	if (pipe->flags & MDP_OV_PLAY_NOWAIT)
+		return;
+
+	mdp4_overlay_dtv_wait4_ov_done(mfd);
+}
+
+void mdp4_external_vsync_dtv()
+{
+	complete(&dtv_pipe->comp);
+}
+
+/*
+ * mdp4_overlay1_done_dtv: called from isr
+ */
+void mdp4_overlay1_done_dtv()
+{
+	complete(&dtv_pipe->comp);
+}
+
+void mdp4_dtv_overlay(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	mutex_lock(&mfd->dma->ov_mutex);
+
+	pipe = dtv_pipe;
+	pipe->srcp0_addr = (uint32) buf;
+	mdp4_overlay_rgb_setup(pipe);
+	mdp4_overlay_reg_flush(pipe, 1); /* rgb2 and mixer1 */
+
+	/* enable irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_OVERLAY1_TERM);
+	INIT_COMPLETION(dtv_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(&dtv_pipe->comp);
+	mdp_disable_irq(MDP_OVERLAY1_TERM);
+
+	mdp4_stat.kickoff_dtv++;
+	mdp4_overlay_resource_release();
+	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..ed44d54
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -0,0 +1,395 @@
+/* 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/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 writeback_offset;
+
+static struct mdp4_overlay_pipe *lcdc_pipe;
+static struct completion lcdc_comp;
+
+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, 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;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	if (is_mdp4_hw_reset()) {
+		mdp4_hw_init();
+		outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+	}
+
+	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;
+
+	if (lcdc_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, 0);
+		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__);
+		lcdc_pipe = pipe; /* keep it */
+		init_completion(&lcdc_comp);
+
+		writeback_offset = mdp4_overlay_writeback_setup(
+						fbi, pipe, buf, bpp);
+	} else {
+		pipe = lcdc_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->srcp0_addr = (uint32) buf;
+	pipe->srcp0_ystride = fbi->fix.line_length;
+	pipe->bpp = bpp;
+
+	mdp4_overlay_dmap_xy(pipe);
+	mdp4_overlay_dmap_cfg(mfd, 1);
+
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(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;
+	lcdc_height = var->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
+	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 + 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);
+
+	mdp4_overlay_reg_flush(pipe, 1);
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(2);
+#endif
+	mdp_histogram_ctrl(TRUE);
+
+	ret = panel_next_on(pdev);
+	if (ret == 0) {
+		/* enable LCDC block */
+		MDP_OUTP(MDP_BASE + LCDC_BASE, 1);
+		mdp_pipe_ctrl(MDP_OVERLAY0_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;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	MDP_OUTP(MDP_BASE + LCDC_BASE, 0);
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	mdp_histogram_ctrl(FALSE);
+	ret = panel_next_off(pdev);
+
+	/* delay to make sure the last frame finishes */
+	msleep(16);
+
+#ifdef LCDC_RGB_UNSTAGE
+	/* dis-engage rgb0 from mixer0 */
+	if (lcdc_pipe)
+		mdp4_mixer_stage_down(lcdc_pipe);
+#endif
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(0);
+#endif
+
+	return ret;
+}
+
+
+#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+int mdp4_lcdc_overlay_blt_offset(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	req->offset = writeback_offset;
+	req->width = lcdc_pipe->src_width;
+	req->height = lcdc_pipe->src_height;
+	req->bpp = lcdc_pipe->bpp;
+
+	return sizeof(*req);
+}
+
+void mdp4_lcdc_overlay_blt(struct msm_fb_data_type *mfd,
+					struct msmfb_overlay_blt *req)
+{
+	unsigned long flag;
+	int change = 0;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	if (req->enable && lcdc_pipe->blt_addr == 0) {
+		lcdc_pipe->blt_addr = lcdc_pipe->blt_base;
+		change++;
+	} else if (req->enable == 0 && lcdc_pipe->blt_addr) {
+		lcdc_pipe->blt_addr = 0;
+		change++;
+	}
+	pr_debug("%s: blt_addr=%x\n", __func__, (int)lcdc_pipe->blt_addr);
+	lcdc_pipe->blt_cnt = 0;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	if (!change)
+		return;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	MDP_OUTP(MDP_BASE + LCDC_BASE, 0);	/* stop lcdc */
+	msleep(50);
+	mdp4_overlayproc_cfg(lcdc_pipe);
+	mdp4_overlay_dmap_xy(lcdc_pipe);
+	MDP_OUTP(MDP_BASE + LCDC_BASE, 1);	/* start lcdc */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+#endif
+
+void mdp4_overlay_lcdc_wait4vsync(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	 /* enable irq */
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	mdp_enable_irq(MDP_DMA2_TERM);	/* enable intr */
+	INIT_COMPLETION(lcdc_comp);
+	mfd->dma->waiting = TRUE;
+	outp32(MDP_INTR_CLEAR, INTR_PRIMARY_VSYNC);
+	mdp_intr_mask |= INTR_PRIMARY_VSYNC;
+	outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+	wait_for_completion_killable(&lcdc_comp);
+	mdp_disable_irq(MDP_DMA2_TERM);
+}
+
+void mdp4_overlay_lcdc_vsync_push(struct msm_fb_data_type *mfd,
+			struct mdp4_overlay_pipe *pipe)
+{
+
+	mdp4_overlay_reg_flush(pipe, 1);
+	if (pipe->flags & MDP_OV_PLAY_NOWAIT)
+		return;
+
+	mdp4_overlay_lcdc_wait4vsync(mfd);
+}
+
+/*
+ * mdp4_primary_vsync_lcdc: called from isr
+ */
+void mdp4_primary_vsync_lcdc(void)
+{
+	complete_all(&lcdc_comp);
+}
+
+/*
+ * mdp4_overlay0_done_lcdc: called from isr
+ */
+void mdp4_overlay0_done_lcdc(void)
+{
+	complete_all(&lcdc_comp);
+}
+
+void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd)
+{
+	struct fb_info *fbi = mfd->fbi;
+	uint8 *buf;
+	int bpp;
+	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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	mutex_lock(&mfd->dma->ov_mutex);
+
+	pipe = lcdc_pipe;
+	pipe->srcp0_addr = (uint32) buf;
+	mdp4_overlay_rgb_setup(pipe);
+	mutex_unlock(&mfd->dma->ov_mutex);
+	mdp4_overlay_lcdc_vsync_push(mfd, pipe);
+	mdp4_stat.kickoff_lcdc++;
+	mdp4_overlay_resource_release();
+}
diff --git a/drivers/video/msm/mdp4_overlay_mddi.c b/drivers/video/msm/mdp4_overlay_mddi.c
new file mode 100644
index 0000000..2bf9faf
--- /dev/null
+++ b/drivers/video/msm/mdp4_overlay_mddi.c
@@ -0,0 +1,612 @@
+/* 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/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"
+
+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
+
+void mdp4_overlay_update_lcd(struct msm_fb_data_type *mfd)
+{
+	MDPIBUF *iBuf = &mfd->ibuf;
+	uint8 *src;
+	int ptype;
+	uint32 mddi_ld_param;
+	uint16 mddi_vdo_packet_reg;
+	struct mdp4_overlay_pipe *pipe;
+	int ret;
+
+	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(mfd->fb_imgType);
+		if (ptype < 0)
+			printk(KERN_INFO "%s: format2type failed\n", __func__);
+		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0, 0);
+		if (pipe == NULL)
+			printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
+		pipe->pipe_used++;
+		pipe->mixer_num  = MDP4_MIXER0;
+		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 */
+		mddi_pipe->blt_end = 1;	/* mark as end */
+		mddi_ld_param = 0;
+		mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
+
+		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_OUTP(MDP_BASE + 0x00028, data);
+		}
+
+		if (mfd->panel_info.type == MDDI_PANEL) {
+			if (mfd->panel_info.pdest == DISPLAY_1)
+				mddi_ld_param = 0;
+			else
+				mddi_ld_param = 1;
+		} else {
+			mddi_ld_param = 2;
+		}
+
+		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_OUTP(MDP_BASE + 0x00094,
+			 (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
+
+		MDP_OUTP(MDP_BASE + 0x00098, 0x01);
+	} else {
+		pipe = mddi_pipe;
+	}
+
+	/* 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;
+
+	mdp4_overlay_rgb_setup(pipe);
+
+	mdp4_mixer_stage_up(pipe);
+
+	mdp4_overlayproc_cfg(pipe);
+
+	mdp4_overlay_dmap_xy(pipe);
+
+	mdp4_overlay_dmap_cfg(mfd, 0);
+
+	mdp4_mddi_vsync_enable(mfd, pipe, 0);
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+}
+
+int mdp4_mddi_overlay_blt_offset(int *off)
+{
+	if (mdp_hw_revision < MDP4_REVISION_V2_1) { /* need dmas dmap switch */
+		if (mddi_pipe->blt_end ||
+			(mdp4_overlay_mixer_play(mddi_pipe->mixer_num) == 0)) {
+			*off = -1;
+			return -EINVAL;
+		}
+	} else {
+		/* no dmas dmap switch */
+		if (mddi_pipe->blt_end) {
+			*off = -1;
+			return -EINVAL;
+		}
+	}
+
+	if (mddi_pipe->blt_cnt & 0x01)
+		*off = mddi_pipe->src_height * mddi_pipe->src_width * 3;
+	else
+		*off = 0;
+
+	return 0;
+}
+
+void mdp4_mddi_overlay_blt(ulong addr)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	if (addr) {
+		mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		mdp_intr_mask |= INTR_DMA_P_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+		mddi_pipe->blt_cnt = 0;
+		mddi_pipe->blt_end = 0;
+		mddi_pipe->blt_addr = addr;
+	} else {
+		mddi_pipe->blt_end = 1;	/* mark as end */
+	}
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+void mdp4_blt_xy_update(struct mdp4_overlay_pipe *pipe)
+{
+	uint32 off, addr;
+	int bpp;
+	char *overlay_base;
+
+
+	if (pipe->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->blt_addr + off;
+
+	/* dmap */
+	MDP_OUTP(MDP_BASE + 0x90008, addr);
+
+	/* overlay 0 */
+	overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
+	outpdw(overlay_base + 0x000c, addr);
+	outpdw(overlay_base + 0x001c, addr);
+}
+
+/*
+ * 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;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		mdp4_overlayproc_cfg(mddi_pipe);
+		mdp4_overlay_dmap_xy(mddi_pipe);
+	}
+
+	/*
+	 * single buffer, no need to increase
+	 * mdd_pipe->dmap_cnt here
+	 */
+}
+
+/*
+ * mdp4_overlay0_done_mddi: called from isr
+ */
+void mdp4_overlay0_done_mddi(struct mdp_dma_data *dma)
+{
+	mdp_disable_irq_nosync(MDP_OVERLAY0_TERM);
+
+	dma->busy = FALSE;
+	complete(&dma->comp);
+	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK,
+			MDP_BLOCK_POWER_OFF, TRUE);
+
+	if (busy_wait_cnt)
+		busy_wait_cnt--;
+
+	pr_debug("%s: ISR-done\n", __func__);
+
+	if (mddi_pipe->blt_addr) {
+		if (mddi_pipe->blt_cnt == 0) {
+			mdp4_overlayproc_cfg(mddi_pipe);
+			mdp4_overlay_dmap_xy(mddi_pipe);
+			mddi_pipe->ov_cnt = 0;
+			mddi_pipe->dmap_cnt = 0;
+			/* BLT start from next frame */
+		} else {
+			mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON,
+						FALSE);
+			mdp4_blt_xy_update(mddi_pipe);
+			outpdw(MDP_BASE + 0x000c, 0x0); /* start DMAP */
+		}
+		mddi_pipe->blt_cnt++;
+		mddi_pipe->ov_cnt++;
+	}
+
+
+
+}
+
+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);
+		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();
+}
+
+/*
+ * mdp4_mddi_cmd_dma_busy_wait: check mddi link activity
+ * dsi 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)
+{
+	pr_debug("%s: pid=%d\n", __func__, current->pid);
+	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)
+{
+	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);
+	mfd->dma->busy = TRUE;
+	/* start OVERLAY pipe */
+	mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
+}
+
+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);
+	mfd->dma->busy = TRUE;
+	mfd->ibuf_flushed = TRUE;
+	/* start dma_s pipe */
+	mdp_pipe_kickoff(MDP_DMA_S_TERM, mfd);
+
+	/* 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);
+		mdp4_overlay_update_lcd(mfd);
+
+		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);
+
+		mdp4_stat.kickoff_mddi++;
+
+	/* signal if pan function is waiting for the update completion */
+		if (mfd->pan_waiting) {
+			mfd->pan_waiting = FALSE;
+			complete(&mfd->pan_comp);
+		}
+	}
+	mdp4_overlay_resource_release();
+	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_util.c b/drivers/video/msm/mdp4_util.c
new file mode 100644
index 0000000..52e4a82
--- /dev/null
+++ b/drivers/video/msm/mdp4_util.c
@@ -0,0 +1,2101 @@
+/* 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/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"
+#include "mdp4.h"
+
+struct mdp4_statistic mdp4_stat;
+
+unsigned is_mdp4_hw_reset(void)
+{
+	unsigned hw_reset = 0;
+
+	/* 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_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;
+
+	if (blt_mode)
+		bits |= (1 << 3);
+	refresh &= 0x03;	/* 2 bites */
+	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)
+		outpdw(MDP_BASE + 0x10004, bits); /* MDP_OVERLAY0_CFG */
+	else
+		outpdw(MDP_BASE + 0x18004, bits); /* MDP_OVERLAY1_CFG */
+
+	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(int output, ulong intf)
+{
+	ulong bits, mask, data;
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	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) {
+			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) {
+			MSM_FB_INFO("%s: Illegal INTF selected, output=%d \
+				intf=%d\n", __func__, output, (int)intf);
+		}
+	} else
+		data = 0;
+
+	mask = 0x03;	/* 2 bits */
+	intf &= 0x03;	/* 2 bits */
+
+	switch (output) {
+	case EXTERNAL_INTF_SEL:
+		intf <<= 4;
+		mask <<= 4;
+		break;
+	case SECONDARY_INTF_SEL:
+		intf &= 0x02;	/* only MDDI and EBI2 support */
+		intf <<= 2;
+		mask <<= 2;
+		break;
+	default:
+		break;
+	}
+
+	intf |= data;
+	mask |= data;
+
+	bits &= ~mask;
+	bits |= intf;
+
+	outpdw(MDP_BASE + 0x0038, bits);	/* MDP_DISP_INTF_SEL */
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+  MSM_FB_DEBUG("mdp4_display_intf_sel: 0x%x\n", (int)inpdw(MDP_BASE + 0x0038));
+}
+
+unsigned long mdp4_display_status(void)
+{
+	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(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) {
+		outpdw(MDP_BASE + 0x0060, base);/* MDP_EBI2_LCD0 */
+		outpdw(MDP_BASE + 0x0068, ystride);/* MDP_EBI2_LCD0_YSTRIDE */
+	} else {
+		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(int mddi, unsigned long id)
+{
+	ulong 	bits;
+
+	if (mddi == MDDI_EXTERNAL_SET)
+		bits = 0x02;
+	else if (mddi == MDDI_SECONDARY_SET)
+		bits = 0x01;
+	else
+		bits = 0;	/* PRIMARY_SET */
+
+	id <<= 16;
+
+	bits |= id;
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	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);
+}
+
+int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req)
+{
+
+	/* 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 (core_clk >= 90000000) { /* 90 Mhz */
+		dmap_data = 0x47; /* 16 bytes-burst x 8 req */
+		vg_data = 0x47; /* 16 bytes-burs x 8 req */
+	} else {
+		dmap_data = 0x27; /* 8 bytes-burst x 8 req */
+		vg_data = 0x43; /* 16 bytes-burst x 4 req */
+	}
+
+	MSM_FB_DEBUG("mdp4_fetch_cfg: dmap=%x vg=%x\n",
+			dmap_data, vg_data);
+
+	/* dma_p fetch config */
+	outpdw(MDP_BASE + 0x91004, dmap_data);
+	/* dma_e fetch config */
+	outpdw(MDP_BASE + 0xB1004, dmap_data);
+
+	/*
+	 * set up two vg pipes and two rgb pipes
+	 */
+	base = MDP_BASE + MDP4_VIDEO_BASE;
+	for (i = 0; i < 4; i++) {
+		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(void)
+{
+	ulong bits;
+
+	/* MDP cmd block enable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+#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(0x17);
+#endif
+
+	mdp4_clear_lcdc();
+
+	mdp4_mixer_blend_init(0);
+	mdp4_mixer_blend_init(1);
+	mdp4_vg_qseed_init(0);
+	mdp4_vg_qseed_init(1);
+
+	/* yuv2rgb */
+	mdp4_vg_csc_mv_setup(0);
+	mdp4_vg_csc_mv_setup(1);
+	mdp4_vg_csc_pre_bv_setup(0);
+	mdp4_vg_csc_pre_bv_setup(1);
+	mdp4_vg_csc_post_bv_setup(0);
+	mdp4_vg_csc_post_bv_setup(1);
+	mdp4_vg_csc_pre_lv_setup(0);
+	mdp4_vg_csc_pre_lv_setup(1);
+	mdp4_vg_csc_post_lv_setup(0);
+	mdp4_vg_csc_post_lv_setup(1);
+
+	/* rgb2yuv */
+	mdp4_mixer1_csc_mv_setup();
+	mdp4_mixer1_csc_pre_bv_setup();
+	mdp4_mixer1_csc_post_bv_setup();
+	mdp4_mixer1_csc_pre_lv_setup();
+	mdp4_mixer1_csc_post_lv_setup();
+
+	mdp4_vg_igc_lut_setup(0);
+	mdp4_vg_igc_lut_setup(1);
+
+	mdp4_rgb_igc_lut_setup(0);
+	mdp4_rgb_igc_lut_setup(1);
+
+	outp32(MDP_EBI2_PORTMAP_MODE, 0x3);
+
+	/* system interrupts */
+
+	bits =  mdp_intr_mask;
+	outpdw(MDP_BASE + 0x0050, bits);/* enable specififed interrupts */
+
+	/* histogram */
+	MDP_OUTP(MDP_BASE + 0x95010, 1);	/* auto clear HIST */
+
+	/* enable histogram interrupts */
+	outpdw(MDP_BASE + 0x9501c, INTR_HIST_DONE);
+
+	/* 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 */
+	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(MDP4_MIXER0, OVERLAY_MODE_BLT, 0, 0);
+	mdp4_overlay_cfg(MDP4_MIXER1, OVERLAY_MODE_BLT, 0, 0);
+#endif
+
+	/* MDP cmd block disable */
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	/* 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);
+}
+
+
+void mdp4_clear_lcdc(void)
+{
+	uint32 bits;
+
+	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;
+	}
+
+	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;
+
+	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) {
+		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.*/
+		MDP_OUTP(MDP_BASE + 0x95010, 1);
+		outpdw(MDP_BASE + 0x9501c, INTR_HIST_DONE);
+		if (mdp_is_hist_start == TRUE) {
+			MDP_OUTP(MDP_BASE + 0x95004,
+					mdp_hist.frame_cnt);
+			MDP_OUTP(MDP_BASE + 0x95000, 1);
+		}
+	}
+
+	if (isr & INTR_EXTERNAL_INTF_UDERRUN)
+		mdp4_stat.intr_underrun_e++;
+
+	isr &= mask;
+
+	if (isr == 0)
+		goto out;
+
+	panel = mdp4_overlay_panel_list();
+	if (isr & INTR_PRIMARY_VSYNC) {
+		dma = &dma2_data;
+		spin_lock(&mdp_spin_lock);
+		mdp_intr_mask &= ~INTR_PRIMARY_VSYNC;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		dma->waiting = FALSE;
+		spin_unlock(&mdp_spin_lock);
+		if (panel & MDP4_PANEL_LCDC)
+			mdp4_primary_vsync_lcdc();
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+		else if (panel & MDP4_PANEL_DSI_VIDEO)
+			mdp4_primary_vsync_dsi_video();
+#endif
+	}
+#ifdef CONFIG_FB_MSM_DTV
+	if (isr & INTR_EXTERNAL_VSYNC) {
+		dma = &dma_e_data;
+		spin_lock(&mdp_spin_lock);
+		mdp_intr_mask &= ~INTR_EXTERNAL_VSYNC;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		dma->waiting = FALSE;
+		spin_unlock(&mdp_spin_lock);
+		if (panel & MDP4_PANEL_DTV)
+			mdp4_external_vsync_dtv();
+	}
+#endif
+	if (isr & INTR_DMA_P_DONE) {
+		mdp4_stat.intr_dma_p++;
+		dma = &dma2_data;
+		if (panel & MDP4_PANEL_LCDC) {
+			/* disable LCDC interrupt */
+			spin_lock(&mdp_spin_lock);
+			mdp_intr_mask &= ~INTR_DMA_P_DONE;
+			outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+			dma->waiting = FALSE;
+			spin_unlock(&mdp_spin_lock);
+		} else { /* MDDI */
+#ifdef CONFIG_FB_MSM_OVERLAY
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+			mdp4_dma_p_done_dsi(dma);
+#else
+			mdp4_dma_p_done_mddi();
+			mdp_pipe_ctrl(MDP_DMA2_BLOCK,
+				MDP_BLOCK_POWER_OFF, TRUE);
+#endif
+#else
+			spin_lock(&mdp_spin_lock);
+			dma->busy = FALSE;
+			spin_unlock(&mdp_spin_lock);
+#endif
+		}
+#ifndef CONFIG_FB_MSM_MIPI_DSI
+		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++;
+		dma = &dma_e_data;
+		spin_lock(&mdp_spin_lock);
+		mdp_intr_mask &= ~INTR_DMA_E_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		dma->busy = FALSE;
+
+		if (dma->waiting) {
+			dma->waiting = FALSE;
+			complete(&dma->comp);
+		}
+		spin_unlock(&mdp_spin_lock);
+	}
+#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 */
+			spin_lock(&mdp_spin_lock);
+			mdp_intr_mask &= ~INTR_OVERLAY0_DONE;
+			outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+			dma->waiting = FALSE;
+			spin_unlock(&mdp_spin_lock);
+			if (panel & MDP4_PANEL_LCDC)
+				mdp4_overlay0_done_lcdc();
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+			else if (panel & MDP4_PANEL_DSI_VIDEO)
+				mdp4_overlay0_done_dsi_video();
+#endif
+		} else {        /* MDDI, DSI_CMD  */
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+			if (panel & MDP4_PANEL_DSI_CMD)
+				mdp4_overlay0_done_dsi_cmd(dma);
+#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
+	}
+#endif	/* OVERLAY */
+	if (isr & INTR_DMA_P_HISTOGRAM) {
+		isr = inpdw(MDP_DMA_P_HIST_INTR_STATUS);
+		mask = inpdw(MDP_DMA_P_HIST_INTR_ENABLE);
+		outpdw(MDP_DMA_P_HIST_INTR_CLEAR, isr);
+		isr &= mask;
+		if (isr & 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);
+			if (mdp_is_hist_start == TRUE) {
+				MDP_OUTP(MDP_BASE + 0x95004,
+						mdp_hist.frame_cnt);
+				MDP_OUTP(MDP_BASE + 0x95000, 1);
+			}
+		}
+	}
+
+out:
+	mdp_is_in_isr = FALSE;
+
+	return IRQ_HANDLED;
+}
+
+
+/*
+ * QSEED tables
+ */
+
+static uint32 vg_qseed_table0[] = {
+	0x5556aaff, 0x00000000, 0x00000000, 0x00000000
+};
+
+static uint32 vg_qseed_table1[] = {
+	0x76543210, 0xfedcba98
+};
+
+static uint32 vg_qseed_table2[] = {
+	0x02000000, 0x00000000, 0x01ff0ff9, 0x00000008,
+	0x01fb0ff2, 0x00000013, 0x01f50fed, 0x0ffe0020,
+	0x01ed0fe8, 0x0ffd002e, 0x01e30fe4, 0x0ffb003e,
+	0x01d80fe1, 0x0ff9004e, 0x01cb0fde, 0x0ff70060,
+	0x01bc0fdc, 0x0ff40074, 0x01ac0fdb, 0x0ff20087,
+	0x019a0fdb, 0x0fef009c, 0x01870fdb, 0x0fed00b1,
+	0x01740fdb, 0x0fea00c7, 0x01600fdc, 0x0fe700dd,
+	0x014b0fdd, 0x0fe500f3, 0x01350fdf, 0x0fe30109,
+	0x01200fe0, 0x0fe00120, 0x01090fe3, 0x0fdf0135,
+	0x00f30fe5, 0x0fdd014b, 0x00dd0fe7, 0x0fdc0160,
+	0x00c70fea, 0x0fdb0174, 0x00b10fed, 0x0fdb0187,
+	0x009c0fef, 0x0fdb019a, 0x00870ff2, 0x0fdb01ac,
+	0x00740ff4, 0x0fdc01bc, 0x00600ff7, 0x0fde01cb,
+	0x004e0ff9, 0x0fe101d8, 0x003e0ffb, 0x0fe401e3,
+	0x002e0ffd, 0x0fe801ed, 0x00200ffe, 0x0fed01f5,
+	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,
+
+	0x02000000, 0x00000000, 0x01ff0ff9, 0x00000008,
+	0x01fb0ff2, 0x00000013, 0x01f50fed, 0x0ffe0020,
+	0x01ed0fe8, 0x0ffd002e, 0x01e30fe4, 0x0ffb003e,
+	0x01d80fe1, 0x0ff9004e, 0x01cb0fde, 0x0ff70060,
+	0x01bc0fdc, 0x0ff40074, 0x01ac0fdb, 0x0ff20087,
+	0x019a0fdb, 0x0fef009c, 0x01870fdb, 0x0fed00b1,
+	0x01740fdb, 0x0fea00c7, 0x01600fdc, 0x0fe700dd,
+	0x014b0fdd, 0x0fe500f3, 0x01350fdf, 0x0fe30109,
+	0x01200fe0, 0x0fe00120, 0x01090fe3, 0x0fdf0135,
+	0x00f30fe5, 0x0fdd014b, 0x00dd0fe7, 0x0fdc0160,
+	0x00c70fea, 0x0fdb0174, 0x00b10fed, 0x0fdb0187,
+	0x009c0fef, 0x0fdb019a, 0x00870ff2, 0x0fdb01ac,
+	0x00740ff4, 0x0fdc01bc, 0x00600ff7, 0x0fde01cb,
+	0x004e0ff9, 0x0fe101d8, 0x003e0ffb, 0x0fe401e3,
+	0x002e0ffd, 0x0fe801ed, 0x00200ffe, 0x0fed01f5,
+	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
+};
+
+
+#define MDP4_QSEED_TABLE0_OFF 0x8100
+#define MDP4_QSEED_TABLE1_OFF 0x8200
+#define MDP4_QSEED_TABLE2_OFF 0x9000
+
+void mdp4_vg_qseed_init(int vp_num)
+{
+	uint32 *off;
+	int i, voff;
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	voff = MDP4_VIDEO_OFF * vp_num;
+	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 = (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 = (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(mixer_num)
+{
+	unsigned char *overlay_base;
+	int off;
+
+	if (mixer_num) 	/* mixer number, /dev/fb0, /dev/fb1 */
+		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);
+
+	/* stage 0 to stage 2 */
+	off = 0;
+	outpdw(overlay_base + off + 0x104, 0x010);
+	outpdw(overlay_base + off + 0x108, 0xff);/* FG */
+	outpdw(overlay_base + off + 0x10c, 0x00);/* BG */
+
+	off += 0x20;
+	outpdw(overlay_base + off + 0x104, 0x010);
+	outpdw(overlay_base + off + 0x108, 0xff);/* FG */
+	outpdw(overlay_base + off + 0x10c, 0x00);/* BG */
+
+	off += 0x20;
+	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 csc_matrix_tab[9] = {
+	0x0254, 0x0000, 0x0331,
+	0x0254, 0xff37, 0xfe60,
+	0x0254, 0x0409, 0x0000
+};
+
+static uint32 csc_pre_bv_tab[3] = {0xfff0, 0xff80, 0xff80 };
+static uint32 csc_post_bv_tab[3] = {0, 0, 0 };
+
+static  uint32 csc_pre_lv_tab[6] =  {0, 0xff, 0, 0xff, 0, 0xff };
+static  uint32 csc_post_lv_tab[6] = {0, 0xff, 0, 0xff, 0, 0xff };
+
+#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
+
+void mdp4_vg_csc_mv_setup(int vp_num)
+{
+	uint32 *off;
+	int i, voff;
+
+	voff = MDP4_VIDEO_OFF * vp_num;
+	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++) {
+		outpdw(off, csc_matrix_tab[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_vg_csc_pre_bv_setup(int vp_num)
+{
+	uint32 *off;
+	int i, voff;
+
+	voff = MDP4_VIDEO_OFF * vp_num;
+	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++) {
+		outpdw(off, csc_pre_bv_tab[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_vg_csc_post_bv_setup(int vp_num)
+{
+	uint32 *off;
+	int i, voff;
+
+	voff = MDP4_VIDEO_OFF * vp_num;
+	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++) {
+		outpdw(off, csc_post_bv_tab[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_vg_csc_pre_lv_setup(int vp_num)
+{
+	uint32 *off;
+	int i, voff;
+
+	voff = MDP4_VIDEO_OFF * vp_num;
+	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++) {
+		outpdw(off, csc_pre_lv_tab[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+void mdp4_vg_csc_post_lv_setup(int vp_num)
+{
+	uint32 *off;
+	int i, voff;
+
+	voff = MDP4_VIDEO_OFF * vp_num;
+	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++) {
+		outpdw(off, csc_post_lv_tab[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+static uint32 csc_rgb2yuv_matrix_tab[9] = {
+	0x0083, 0x0102, 0x0032,
+	0x1fb5, 0x1f6c, 0x00e1,
+	0x00e1, 0x1f45, 0x1fdc
+};
+
+static uint32 csc_rgb2yuv_pre_bv_tab[3] = {0, 0, 0};
+
+static uint32 csc_rgb2yuv_post_bv_tab[3] = {0x0010, 0x0080, 0x0080};
+
+static  uint32 csc_rgb2yuv_pre_lv_tab[6] = {
+	0x00, 0xff, 0x00,
+	0xff, 0x00, 0xff
+};
+
+static  uint32 csc_rgb2yuv_post_lv_tab[6] = {
+	0x0010, 0x00eb, 0x0010,
+	0x00f0, 0x0010, 0x00f0
+};
+
+void mdp4_mixer1_csc_mv_setup(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2400);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 9; i++) {
+		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(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2500);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 3; i++) {
+		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(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2580);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 3; i++) {
+		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(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2600);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 6; i++) {
+		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(void)
+{
+	uint32 *off;
+	int i;
+
+	off = (uint32 *)(MDP_BASE + MDP4_OVERLAYPROC1_BASE + 0x2680);
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+	for (i = 0; i < 6; i++) {
+		outpdw(off, csc_rgb2yuv_post_lv_tab[i]);
+		off++;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+
+char gc_lut[] = {
+	0x0, 0x1, 0x2, 0x2, 0x3, 0x4, 0x5, 0x6,
+	0x6, 0x7, 0x8, 0x9, 0xA, 0xA, 0xB, 0xC,
+	0xD, 0xD, 0xE, 0xF, 0xF, 0x10, 0x10, 0x11,
+	0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15,
+	0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, 0x19,
+	0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1C,
+	0x1C, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1F,
+	0x1F, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21,
+	0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24,
+	0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26,
+	0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28,
+	0x28, 0x29, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A,
+	0x2A, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2C, 0x2C,
+	0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E,
+	0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x2F, 0x30,
+	0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
+	0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33,
+	0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x34,
+	0x35, 0x35, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
+	0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39,
+	0x39, 0x39, 0x39, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A,
+	0x3A, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3C,
+	0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3D, 0x3D, 0x3D,
+	0x3D, 0x3D, 0x3D, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E,
+	0x3E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x40,
+	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41,
+	0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42,
+	0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43,
+	0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+	0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
+	0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x47,
+	0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49,
+	0x49, 0x49, 0x49, 0x49, 0x49, 0x4A, 0x4A, 0x4A,
+	0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4B, 0x4B, 0x4B,
+	0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4C, 0x4C, 0x4C,
+	0x4C, 0x4C, 0x4C, 0x4C, 0x4D, 0x4D, 0x4D, 0x4D,
+	0x4D, 0x4D, 0x4D, 0x4D, 0x4E, 0x4E, 0x4E, 0x4E,
+	0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F,
+	0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x50, 0x50, 0x50,
+	0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51,
+	0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52,
+	0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53,
+	0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54,
+	0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
+	0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+	0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
+	0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
+	0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x58,
+	0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59,
+	0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x5A, 0x5A,
+	0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+	0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B,
+	0x5B, 0x5B, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
+	0x5C, 0x5C, 0x5C, 0x5C, 0x5D, 0x5D, 0x5D, 0x5D,
+	0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5E, 0x5E,
+	0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E,
+	0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F,
+	0x5F, 0x5F, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
+	0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61,
+	0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x62,
+	0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62,
+	0x62, 0x62, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+	0x63, 0x63, 0x63, 0x63, 0x63, 0x64, 0x64, 0x64,
+	0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
+	0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
+	0x65, 0x65, 0x65, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67,
+	0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67,
+	0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68,
+	0x68, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69,
+	0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+	0x69, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A,
+	0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6B, 0x6B, 0x6B,
+	0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
+	0x6B, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,
+	0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6D, 0x6D, 0x6D,
+	0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
+	0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E,
+	0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x6F, 0x6F,
+	0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F,
+	0x6F, 0x6F, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+	0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71,
+	0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71,
+	0x71, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x72,
+	0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
+	0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73,
+	0x73, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74,
+	0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74,
+	0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+	0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+	0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+	0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
+	0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+	0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78,
+	0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+	0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+	0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7A, 0x7A,
+	0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A,
+	0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B,
+	0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B,
+	0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C,
+	0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C,
+	0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
+	0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
+	0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
+	0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F,
+	0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+	0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x80, 0x80, 0x80,
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+	0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81,
+	0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+	0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82,
+	0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+	0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+	0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+	0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+	0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+	0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+	0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+	0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+	0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+	0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+	0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+	0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+	0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+	0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+	0x89, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
+	0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A,
+	0x8A, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
+	0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B,
+	0x8B, 0x8B, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
+	0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C,
+	0x8C, 0x8C, 0x8C, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
+	0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D,
+	0x8D, 0x8D, 0x8D, 0x8D, 0x8E, 0x8E, 0x8E, 0x8E,
+	0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E,
+	0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, 0x8F, 0x8F,
+	0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
+	0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x90, 0x90,
+	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x91,
+	0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+	0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+	0x91, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+	0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+	0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+	0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+	0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94,
+	0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+	0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x95, 0x95,
+	0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+	0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+	0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+	0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+	0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, 0x97,
+	0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+	0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98,
+	0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+	0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+	0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+	0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+	0x99, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
+	0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
+	0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9B, 0x9B, 0x9B,
+	0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B,
+	0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B,
+	0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C,
+	0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C,
+	0x9C, 0x9C, 0x9C, 0x9C, 0x9D, 0x9D, 0x9D, 0x9D,
+	0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
+	0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9E,
+	0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
+	0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
+	0x9E, 0x9E, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F,
+	0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F,
+	0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0xA0, 0xA0,
+	0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
+	0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
+	0xA0, 0xA0, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1,
+	0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1,
+	0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA2, 0xA2,
+	0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2,
+	0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2,
+	0xA2, 0xA2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
+	0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3,
+	0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA4, 0xA4,
+	0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
+	0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
+	0xA4, 0xA4, 0xA4, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
+	0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
+	0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
+	0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
+	0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
+	0xA6, 0xA6, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA7,
+	0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7,
+	0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7,
+	0xA7, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+	0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+	0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA9,
+	0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9,
+	0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9,
+	0xA9, 0xA9, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
+	0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
+	0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAC,
+	0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
+	0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
+	0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD,
+	0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD,
+	0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD,
+	0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE,
+	0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE,
+	0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE,
+	0xAE, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF,
+	0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF,
+	0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xB0,
+	0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0,
+	0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0,
+	0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB1, 0xB1,
+	0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1,
+	0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1,
+	0xB1, 0xB1, 0xB1, 0xB1, 0xB2, 0xB2, 0xB2, 0xB2,
+	0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
+	0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2,
+	0xB2, 0xB2, 0xB2, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3,
+	0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3,
+	0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3,
+	0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4,
+	0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4,
+	0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4,
+	0xB4, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5,
+	0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5,
+	0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5,
+	0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
+	0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
+	0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
+	0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7,
+	0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7,
+	0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB8,
+	0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8,
+	0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8,
+	0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB9,
+	0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9,
+	0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9,
+	0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xBA,
+	0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA,
+	0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA,
+	0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC,
+	0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC,
+	0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC,
+	0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD,
+	0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD,
+	0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD,
+	0xBD, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE,
+	0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE,
+	0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE,
+	0xBE, 0xBE, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF,
+	0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF,
+	0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF,
+	0xBF, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+	0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+	0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+	0xC0, 0xC0, 0xC0, 0xC0, 0xC1, 0xC1, 0xC1, 0xC1,
+	0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1,
+	0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1,
+	0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC2, 0xC2, 0xC2,
+	0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
+	0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
+	0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC3, 0xC3,
+	0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
+	0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
+	0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
+	0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4,
+	0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4,
+	0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4,
+	0xC4, 0xC4, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5,
+	0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5,
+	0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5,
+	0xC5, 0xC5, 0xC5, 0xC5, 0xC6, 0xC6, 0xC6, 0xC6,
+	0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
+	0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
+	0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, 0xC7,
+	0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7,
+	0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7,
+	0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7,
+	0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
+	0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
+	0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
+	0xC8, 0xC8, 0xC8, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9,
+	0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9,
+	0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9,
+	0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xCA, 0xCA,
+	0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA,
+	0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA,
+	0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA,
+	0xCA, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB,
+	0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB,
+	0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB,
+	0xCB, 0xCB, 0xCB, 0xCB, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCD,
+	0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
+	0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
+	0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
+	0xCD, 0xCD, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE,
+	0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE,
+	0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE,
+	0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCF, 0xCF,
+	0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF,
+	0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF,
+	0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF,
+	0xCF, 0xCF, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0,
+	0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0,
+	0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0,
+	0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD1, 0xD1, 0xD1,
+	0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1,
+	0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1,
+	0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1,
+	0xD1, 0xD1, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+	0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+	0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+	0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD3, 0xD3,
+	0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3,
+	0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3,
+	0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3,
+	0xD3, 0xD3, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4,
+	0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4,
+	0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4,
+	0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD5,
+	0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
+	0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
+	0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5,
+	0xD5, 0xD5, 0xD5, 0xD5, 0xD6, 0xD6, 0xD6, 0xD6,
+	0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
+	0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
+	0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6,
+	0xD6, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
+	0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
+	0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
+	0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+	0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+	0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+	0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+	0xD9, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
+	0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
+	0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
+	0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDB, 0xDB,
+	0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
+	0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
+	0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
+	0xDB, 0xDB, 0xDB, 0xDB, 0xDC, 0xDC, 0xDC, 0xDC,
+	0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+	0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+	0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
+	0xDC, 0xDC, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
+	0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
+	0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
+	0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDF,
+	0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
+	0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
+	0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
+	0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE0, 0xE0,
+	0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
+	0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
+	0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
+	0xE0, 0xE0, 0xE0, 0xE0, 0xE1, 0xE1, 0xE1, 0xE1,
+	0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1,
+	0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1,
+	0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1,
+	0xE1, 0xE1, 0xE1, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+	0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+	0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+	0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+	0xE2, 0xE2, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
+	0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
+	0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
+	0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
+	0xE3, 0xE3, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
+	0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
+	0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
+	0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
+	0xE4, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
+	0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
+	0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
+	0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
+	0xE5, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+	0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+	0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+	0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+	0xE6, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
+	0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
+	0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
+	0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
+	0xE7, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+	0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+	0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+	0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+	0xE8, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
+	0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
+	0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
+	0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
+	0xE9, 0xE9, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA,
+	0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA,
+	0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA,
+	0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA,
+	0xEA, 0xEA, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
+	0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
+	0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
+	0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB,
+	0xEB, 0xEB, 0xEB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+	0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+	0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+	0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+	0xEC, 0xEC, 0xEC, 0xEC, 0xED, 0xED, 0xED, 0xED,
+	0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+	0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+	0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+	0xED, 0xED, 0xED, 0xED, 0xED, 0xEE, 0xEE, 0xEE,
+	0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+	0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+	0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+	0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEF, 0xEF,
+	0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+	0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+	0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+	0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+	0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+	0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+	0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+	0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+	0xF0, 0xF0, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+	0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+	0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+	0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
+	0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, 0xF2, 0xF2,
+	0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+	0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+	0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+	0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF3, 0xF3,
+	0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+	0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+	0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+	0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+	0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+	0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+	0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+	0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+	0xF4, 0xF4, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+	0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+	0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+	0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+	0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6, 0xF6,
+	0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6,
+	0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6,
+	0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6,
+	0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6,
+	0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+	0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+	0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+	0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+	0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
+	0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
+	0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
+	0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
+	0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF9, 0xF9,
+	0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9,
+	0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9,
+	0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9,
+	0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9,
+	0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
+	0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
+	0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
+	0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
+	0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB,
+	0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
+	0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
+	0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
+	0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
+	0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
+	0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
+	0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
+	0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
+	0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD,
+	0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
+	0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
+	0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
+	0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
+	0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
+	0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
+	0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
+	0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
+	0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+void mdp4_mixer_gc_lut_setup(int mixer_num)
+{
+	unsigned char *base;
+	uint32 data;
+	char val;
+	int i, off;
+
+	if (mixer_num) 	/* mixer number, /dev/fb0, /dev/fb1 */
+		base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
+	else
+		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 */
+		outpdw(base + off, data);
+		off += 4;
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+}
+
+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,
+	0x25, 0x28, 0x2A, 0x2D, 0x30, 0x32, 0x35, 0x38,
+	0x3B, 0x3E, 0x42, 0x45, 0x48, 0x4C, 0x4F, 0x53,
+	0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x70, 0x74,
+	0x79, 0x7E, 0x83, 0x88, 0x8D, 0x92, 0x97, 0x9C,
+	0xA2, 0xA8, 0xAD, 0xB3, 0xB9, 0xBF, 0xC5, 0xCC,
+	0xD2, 0xD8, 0xDF, 0xE6, 0xED, 0xF4, 0xFB, 0x102,
+	0x109, 0x111, 0x118, 0x120, 0x128, 0x130, 0x138, 0x140,
+	0x149, 0x151, 0x15A, 0x162, 0x16B, 0x174, 0x17D, 0x186,
+	0x190, 0x199, 0x1A3, 0x1AC, 0x1B6, 0x1C0, 0x1CA, 0x1D5,
+	0x1DF, 0x1EA, 0x1F4, 0x1FF, 0x20A, 0x215, 0x220, 0x22B,
+	0x237, 0x242, 0x24E, 0x25A, 0x266, 0x272, 0x27F, 0x28B,
+	0x298, 0x2A4, 0x2B1, 0x2BE, 0x2CB, 0x2D8, 0x2E6, 0x2F3,
+	0x301, 0x30F, 0x31D, 0x32B, 0x339, 0x348, 0x356, 0x365,
+	0x374, 0x383, 0x392, 0x3A1, 0x3B1, 0x3C0, 0x3D0, 0x3E0,
+	0x3F0, 0x400, 0x411, 0x421, 0x432, 0x443, 0x454, 0x465,
+	0x476, 0x487, 0x499, 0x4AB, 0x4BD, 0x4CF, 0x4E1, 0x4F3,
+	0x506, 0x518, 0x52B, 0x53E, 0x551, 0x565, 0x578, 0x58C,
+	0x5A0, 0x5B3, 0x5C8, 0x5DC, 0x5F0, 0x605, 0x61A, 0x62E,
+	0x643, 0x659, 0x66E, 0x684, 0x699, 0x6AF, 0x6C5, 0x6DB,
+	0x6F2, 0x708, 0x71F, 0x736, 0x74D, 0x764, 0x77C, 0x793,
+	0x7AB, 0x7C3, 0x7DB, 0x7F3, 0x80B, 0x824, 0x83D, 0x855,
+	0x86F, 0x888, 0x8A1, 0x8BB, 0x8D4, 0x8EE, 0x908, 0x923,
+	0x93D, 0x958, 0x973, 0x98E, 0x9A9, 0x9C4, 0x9DF, 0x9FB,
+	0xA17, 0xA33, 0xA4F, 0xA6C, 0xA88, 0xAA5, 0xAC2, 0xADF,
+	0xAFC, 0xB19, 0xB37, 0xB55, 0xB73, 0xB91, 0xBAF, 0xBCE,
+	0xBEC, 0xC0B, 0xC2A, 0xC4A, 0xC69, 0xC89, 0xCA8, 0xCC8,
+	0xCE8, 0xD09, 0xD29, 0xD4A, 0xD6B, 0xD8C, 0xDAD, 0xDCF,
+	0xDF0, 0xE12, 0xE34, 0xE56, 0xE79, 0xE9B, 0xEBE, 0xEE1,
+	0xF04, 0xF27, 0xF4B, 0xF6E, 0xF92, 0xFB6, 0xFDB, 0xFFF,
+};
+
+void mdp4_vg_igc_lut_setup(int vp_num)
+{
+	unsigned char *base;
+	int i, voff, off;
+	uint32 data, val;
+
+	voff = MDP4_VIDEO_OFF * vp_num;
+	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 */
+		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 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,
+	0x181, 0x191, 0x1A2, 0x1B2, 0x1C2, 0x1D2, 0x1E2, 0x1F2,
+	0x202, 0x212, 0x222, 0x232, 0x242, 0x252, 0x262, 0x272,
+	0x282, 0x292, 0x2A2, 0x2B3, 0x2C3, 0x2D3, 0x2E3, 0x2F3,
+	0x303, 0x313, 0x323, 0x333, 0x343, 0x353, 0x363, 0x373,
+	0x383, 0x393, 0x3A3, 0x3B3, 0x3C4, 0x3D4, 0x3E4, 0x3F4,
+	0x404, 0x414, 0x424, 0x434, 0x444, 0x454, 0x464, 0x474,
+	0x484, 0x494, 0x4A4, 0x4B4, 0x4C4, 0x4D5, 0x4E5, 0x4F5,
+	0x505, 0x515, 0x525, 0x535, 0x545, 0x555, 0x565, 0x575,
+	0x585, 0x595, 0x5A5, 0x5B5, 0x5C5, 0x5D5, 0x5E6, 0x5F6,
+	0x606, 0x616, 0x626, 0x636, 0x646, 0x656, 0x666, 0x676,
+	0x686, 0x696, 0x6A6, 0x6B6, 0x6C6, 0x6D6, 0x6E6, 0x6F7,
+	0x707, 0x717, 0x727, 0x737, 0x747, 0x757, 0x767, 0x777,
+	0x787, 0x797, 0x7A7, 0x7B7, 0x7C7, 0x7D7, 0x7E7, 0x7F7,
+	0x808, 0x818, 0x828, 0x838, 0x848, 0x858, 0x868, 0x878,
+	0x888, 0x898, 0x8A8, 0x8B8, 0x8C8, 0x8D8, 0x8E8, 0x8F8,
+	0x908, 0x919, 0x929, 0x939, 0x949, 0x959, 0x969, 0x979,
+	0x989, 0x999, 0x9A9, 0x9B9, 0x9C9, 0x9D9, 0x9E9, 0x9F9,
+	0xA09, 0xA19, 0xA2A, 0xA3A, 0xA4A, 0xA5A, 0xA6A, 0xA7A,
+	0xA8A, 0xA9A, 0xAAA, 0xABA, 0xACA, 0xADA, 0xAEA, 0xAFA,
+	0xB0A, 0xB1A, 0xB2A, 0xB3B, 0xB4B, 0xB5B, 0xB6B, 0xB7B,
+	0xB8B, 0xB9B, 0xBAB, 0xBBB, 0xBCB, 0xBDB, 0xBEB, 0xBFB,
+	0xC0B, 0xC1B, 0xC2B, 0xC3B, 0xC4C, 0xC5C, 0xC6C, 0xC7C,
+	0xC8C, 0xC9C, 0xCAC, 0xCBC, 0xCCC, 0xCDC, 0xCEC, 0xCFC,
+	0xD0C, 0xD1C, 0xD2C, 0xD3C, 0xD4C, 0xD5D, 0xD6D, 0xD7D,
+	0xD8D, 0xD9D, 0xDAD, 0xDBD, 0xDCD, 0xDDD, 0xDED, 0xDFD,
+	0xE0D, 0xE1D, 0xE2D, 0xE3D, 0xE4D, 0xE5D, 0xE6E, 0xE7E,
+	0xE8E, 0xE9E, 0xEAE, 0xEBE, 0xECE, 0xEDE, 0xEEE, 0xEFE,
+	0xF0E, 0xF1E, 0xF2E, 0xF3E, 0xF4E, 0xF5E, 0xF6E, 0xF7F,
+	0xF8F, 0xF9F, 0xFAF, 0xFBF, 0xFCF, 0xFDF, 0xFEF, 0xFFF,
+};
+
+void mdp4_rgb_igc_lut_setup(int num)
+{
+	unsigned char *base;
+	int i, voff, off;
+	uint32 data, val;
+
+	voff = MDP4_RGB_OFF * num;
+	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 */
+		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;
+}
+
diff --git a/drivers/video/msm/mdp_csc_table.h b/drivers/video/msm/mdp_csc_table.h
index d1cde30..a0f72c0 100644
--- a/drivers/video/msm/mdp_csc_table.h
+++ b/drivers/video/msm/mdp_csc_table.h
@@ -1,4 +1,4 @@
-/* drivers/video/msm_fb/mdp_csc_table.h
+/* drivers/video/msm/mdp_csc_table.h
  *
  * Copyright (C) 2007 QUALCOMM Incorporated
  * Copyright (C) 2007 Google Incorporated
@@ -16,57 +16,116 @@
 static struct {
 	uint32_t reg;
 	uint32_t val;
-} csc_table[] = {
-	{ 0x40400, 0x83 },
-	{ 0x40404, 0x102 },
-	{ 0x40408, 0x32 },
-	{ 0x4040c, 0xffffffb5 },
-	{ 0x40410, 0xffffff6c },
-	{ 0x40414, 0xe1 },
-	{ 0x40418, 0xe1 },
-	{ 0x4041c, 0xffffff45 },
-	{ 0x40420, 0xffffffdc },
-	{ 0x40440, 0x254 },
-	{ 0x40444, 0x0 },
-	{ 0x40448, 0x331 },
-	{ 0x4044c, 0x254 },
-	{ 0x40450, 0xffffff38 },
-	{ 0x40454, 0xfffffe61 },
-	{ 0x40458, 0x254 },
-	{ 0x4045c, 0x409 },
-	{ 0x40460, 0x0 },
-	{ 0x40480, 0x5d },
-	{ 0x40484, 0x13a },
-	{ 0x40488, 0x20 },
-	{ 0x4048c, 0xffffffcd },
-	{ 0x40490, 0xffffff54 },
-	{ 0x40494, 0xe1 },
-	{ 0x40498, 0xe1 },
-	{ 0x4049c, 0xffffff35 },
-	{ 0x404a0, 0xffffffec },
-	{ 0x404c0, 0x254 },
-	{ 0x404c4, 0x0 },
-	{ 0x404c8, 0x396 },
-	{ 0x404cc, 0x254 },
-	{ 0x404d0, 0xffffff94 },
-	{ 0x404d4, 0xfffffef0 },
-	{ 0x404d8, 0x254 },
-	{ 0x404dc, 0x43a },
-	{ 0x404e0, 0x0 },
-	{ 0x40500, 0x10 },
-	{ 0x40504, 0x80 },
-	{ 0x40508, 0x80 },
-	{ 0x40540, 0x10 },
-	{ 0x40544, 0x80 },
-	{ 0x40548, 0x80 },
-	{ 0x40580, 0x10 },
-	{ 0x40584, 0xeb },
-	{ 0x40588, 0x10 },
-	{ 0x4058c, 0xf0 },
-	{ 0x405c0, 0x10 },
-	{ 0x405c4, 0xeb },
-	{ 0x405c8, 0x10 },
-	{ 0x405cc, 0xf0 },
+} 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 },
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..b89e8c7
--- /dev/null
+++ b/drivers/video/msm/mdp_debugfs.c
@@ -0,0 +1,1289 @@
+/* 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/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;
+	unsigned long flag;
+
+
+	if (*ppos)
+		return 0;	/* the end */
+
+	bp = debug_buf;
+	dlen = sizeof(debug_buf);
+
+	spin_lock_irqsave(&mdp_spin_lock, flag);
+	len = snprintf(bp, dlen, "intr_total:    %08lu\n",
+					mdp4_stat.intr_tot);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "intr_dma_p:    %08lu\n",
+					mdp4_stat.intr_dma_p);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "intr_dma_s:    %08lu\n",
+					mdp4_stat.intr_dma_s);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "intr_dma_e:    %08lu\n",
+					mdp4_stat.intr_dma_e);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "intr_overlay0: %08lu\n",
+					mdp4_stat.intr_overlay0);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "intr_overlay1: %08lu\n",
+					mdp4_stat.intr_overlay1);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "unerrun_primary:  %08lu\n",
+					mdp4_stat.intr_underrun_p);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "unerrun_external:  %08lu\n\n",
+					mdp4_stat.intr_underrun_e);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "intr_dsi  :    %08lu\n\n",
+					mdp4_stat.intr_dsi);
+
+	bp += len;
+	dlen -= len;
+	spin_unlock_irqrestore(&mdp_spin_lock, flag);
+
+	len = snprintf(bp, dlen, "kickoff_mddi:      %08lu\n",
+					mdp4_stat.kickoff_mddi);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "kickoff_lcdc:      %08lu\n",
+					mdp4_stat.kickoff_lcdc);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "kickoff_dtv:       %08lu\n",
+					mdp4_stat.kickoff_dtv);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "kickoff_atv:       %08lu\n",
+					mdp4_stat.kickoff_atv);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "kickoff_dsi:       %08lu\n\n",
+					mdp4_stat.kickoff_dsi);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "writeback:      %08lu\n",
+					mdp4_stat.writeback);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "overlay0_set:   %08lu\n",
+					mdp4_stat.overlay_set[0]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "overlay0_unset: %08lu\n",
+					mdp4_stat.overlay_unset[0]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "overlay0_play:  %08lu\n",
+					mdp4_stat.overlay_play[0]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "overlay1_set:   %08lu\n",
+					mdp4_stat.overlay_set[1]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "overlay1_unset: %08lu\n",
+					mdp4_stat.overlay_unset[1]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "overlay1_play:  %08lu\n\n",
+					mdp4_stat.overlay_play[1]);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "pipe_rgb1:  %08lu\n", mdp4_stat.pipe[0]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "pipe_rgb2:  %08lu\n", mdp4_stat.pipe[1]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "pipe_vg1:   %08lu\n", mdp4_stat.pipe[2]);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "pipe_vg2:   %08lu\n\n", mdp4_stat.pipe[3]);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "dsi_clkoff: %08lu\n\n", mdp4_stat.dsi_clkoff);
+
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_mixer:  %08lu\n", 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\n", mdp4_stat.err_scale);
+	bp += len;
+	dlen -= len;
+	len = snprintf(bp, dlen, "err_format: %08lu\n", mdp4_stat.err_format);
+	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..a78c0db
--- /dev/null
+++ b/drivers/video/msm/mdp_dma.c
@@ -0,0 +1,602 @@
+/* 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/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
+	if (mipi_dsi_clk_on == 0)
+		mipi_dsi_clk_enable();
+#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_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;
+	MDPIBUF *iBuf;
+	int bpp = info->var.bits_per_pixel / 8;
+
+	down(&mfd->sem);
+	iBuf = &mfd->ibuf;
+	iBuf->buf = (uint8 *) info->fix.smem_start;
+	iBuf->buf += info->var.xoffset * bpp +
+			info->var.yoffset * info->fix.line_length;
+
+	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..505eb74
--- /dev/null
+++ b/drivers/video/msm/mdp_dma_dsi_video.c
@@ -0,0 +1,270 @@
+/* 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/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;
+
+	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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	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 */
+	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_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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+	/* 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..9ce7e13
--- /dev/null
+++ b/drivers/video/msm/mdp_dma_lcdc.c
@@ -0,0 +1,368 @@
+/* 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 <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;
+
+	/* 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 += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length;
+
+	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
+
+	/* 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);
+
+	/* delay to make sure the last frame finishes */
+	msleep(16);
+
+	return ret;
+}
+
+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;
+
+	/* 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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	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);
+}
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..66d9422
--- /dev/null
+++ b/drivers/video/msm/mdp_dma_tv.c
@@ -0,0 +1,138 @@
+/* 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 <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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+
+	/* 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 += fbi->var.xoffset * bpp +
+		fbi->var.yoffset * fbi->fix.line_length;
+	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 d804774..f35a757 100644
--- a/drivers/video/msm/mdp_hw.h
+++ b/drivers/video/msm/mdp_hw.h
@@ -15,20 +15,61 @@
 #ifndef _MDP_HW_H_
 #define _MDP_HW_H_
 
+#include <linux/platform_device.h>
+#include <linux/wait.h>
 #include <mach/msm_iomap.h>
 #include <mach/msm_fb.h>
 
+typedef void (*mdp_dma_start_func_t)(void *private_data, uint32_t addr,
+				     uint32_t stride, uint32_t width,
+				     uint32_t height, uint32_t x, uint32_t y);
+
+struct mdp_out_interface {
+	uint32_t		registered:1;
+	void			*priv;
+
+	/* If the interface client wants to get DMA_DONE events */
+	uint32_t		dma_mask;
+	mdp_dma_start_func_t	dma_start;
+
+	struct msmfb_callback	*dma_cb;
+	wait_queue_head_t	dma_waitqueue;
+
+	/* If the interface client wants to be notified of non-DMA irqs,
+	 * e.g. LCDC/TV-out frame start */
+	uint32_t		irq_mask;
+	struct msmfb_callback	*irq_cb;
+};
+
 struct mdp_info {
+	spinlock_t lock;
 	struct mdp_device mdp_dev;
 	char * __iomem base;
 	int irq;
+	struct clk *clk;
+	struct clk *ebi1_clk;
+	struct mdp_out_interface out_if[MSM_MDP_NUM_INTERFACES];
+	int format;
+	int pack_pattern;
+	bool dma_config_dirty;
 };
+
+extern 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);
+
+extern int mdp_out_if_req_irq(struct mdp_device *mdp_dev, int interface,
+			      uint32_t mask, struct msmfb_callback *cb);
+
 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);
+
+void mdp_ppp_dump_debug(const struct mdp_info *mdp);
+
 #define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset)
 #define mdp_readl(mdp, offset) readl(mdp->base + offset)
 
@@ -48,10 +89,18 @@
 #define MDP_DISPLAY_STATUS               (0x00038)
 #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)
 #define MDP_DISPLAY1_ADDR                (0x00058)
-#define MDP_EBI2_PORTMAP_MODE            (0x0005c)
-#define MDP_MODE                         (0x00060)
+#define MDP_PPP_CMD_MODE                 (0x00060)
+#else
+#define MDP_DISPLAY0_ADDR                (0x10000)
+#define MDP_DISPLAY1_ADDR                (0x10004)
+#define MDP_PPP_CMD_MODE                 (0x10060)
+#endif
+
 #define MDP_TV_OUT_STATUS                (0x00064)
 #define MDP_HW_VERSION                   (0x00070)
 #define MDP_SW_RESET                     (0x00074)
@@ -61,6 +110,8 @@
 #define MDP_SECONDARY_VSYNC_OUT_CTRL     (0x00084)
 #define MDP_EXTERNAL_VSYNC_OUT_CTRL      (0x00088)
 #define MDP_VSYNC_CTRL                   (0x0008c)
+#define MDP_MDDI_PARAM_WR_SEL            (0x00090)
+#define MDP_MDDI_PARAM                   (0x00094)
 #define MDP_CGC_EN                       (0x00100)
 #define MDP_CMD_STATUS                   (0x10008)
 #define MDP_PROFILE_EN                   (0x10010)
@@ -107,6 +158,7 @@
 #define MDP_FULL_BYPASS_WORD35           (0x1018c)
 #define MDP_FULL_BYPASS_WORD37           (0x10194)
 #define MDP_FULL_BYPASS_WORD39           (0x1019c)
+#define MDP_PPP_OUT_XY                   (0x1019c)
 #define MDP_FULL_BYPASS_WORD40           (0x101a0)
 #define MDP_FULL_BYPASS_WORD41           (0x101a4)
 #define MDP_FULL_BYPASS_WORD43           (0x101ac)
@@ -129,11 +181,27 @@
 #define MDP_FULL_BYPASS_WORD61           (0x101f4)
 #define MDP_FULL_BYPASS_WORD62           (0x101f8)
 #define MDP_FULL_BYPASS_WORD63           (0x101fc)
+
+#ifdef CONFIG_MSM_MDP31
+#define MDP_PPP_SRC_XY                   (0x10200)
+#define MDP_PPP_BG_XY                    (0x10204)
+#define MDP_PPP_SRC_IMAGE_SIZE           (0x10208)
+#define MDP_PPP_BG_IMAGE_SIZE            (0x1020c)
+#define MDP_PPP_SCALE_CONFIG             (0x10230)
+#define MDP_PPP_CSC_CONFIG               (0x10240)
+#define MDP_PPP_BLEND_BG_ALPHA_SEL       (0x70010)
+#endif
+
 #define MDP_TFETCH_TEST_MODE             (0x20004)
 #define MDP_TFETCH_STATUS                (0x20008)
 #define MDP_TFETCH_TILE_COUNT            (0x20010)
 #define MDP_TFETCH_FETCH_COUNT           (0x20014)
 #define MDP_TFETCH_CONSTANT_COLOR        (0x20040)
+#define MDP_BGTFETCH_TEST_MODE           (0x28004)
+#define MDP_BGTFETCH_STATUS              (0x28008)
+#define MDP_BGTFETCH_TILE_COUNT          (0x28010)
+#define MDP_BGTFETCH_FETCH_COUNT         (0x28014)
+#define MDP_BGTFETCH_CONSTANT_COLOR      (0x28040)
 #define MDP_CSC_BYPASS                   (0x40004)
 #define MDP_SCALE_COEFF_LSB              (0x5fffc)
 #define MDP_TV_OUT_CTL                   (0xc0000)
@@ -158,55 +226,49 @@
 #define MDP_TEST_MISR_CURR_VAL_DCLK      (0xd020c)
 #define MDP_TEST_CAPTURED_DCLK           (0xd0210)
 #define MDP_TEST_MISR_CAPT_VAL_DCLK      (0xd0214)
-#define MDP_LCDC_CTL                     (0xe0000)
+
+#define MDP_DMA_P_START                  (0x00044)
+#define MDP_DMA_P_CONFIG                 (0x90000)
+#define MDP_DMA_P_SIZE                   (0x90004)
+#define MDP_DMA_P_IBUF_ADDR              (0x90008)
+#define MDP_DMA_P_IBUF_Y_STRIDE          (0x9000c)
+#define MDP_DMA_P_OUT_XY                 (0x90010)
+#define MDP_DMA_P_COLOR_CORRECT_CONFIG   (0x90070)
+
+#define MDP_LCDC_EN                      (0xe0000)
 #define MDP_LCDC_HSYNC_CTL               (0xe0004)
-#define MDP_LCDC_VSYNC_CTL               (0xe0008)
-#define MDP_LCDC_ACTIVE_HCTL             (0xe000c)
-#define MDP_LCDC_ACTIVE_VCTL             (0xe0010)
-#define MDP_LCDC_BORDER_CLR              (0xe0014)
-#define MDP_LCDC_H_BLANK                 (0xe0018)
-#define MDP_LCDC_V_BLANK                 (0xe001c)
-#define MDP_LCDC_UNDERFLOW_CLR           (0xe0020)
-#define MDP_LCDC_HSYNC_SKEW              (0xe0024)
-#define MDP_LCDC_TEST_CTL                (0xe0028)
-#define MDP_LCDC_LINE_IRQ                (0xe002c)
-#define MDP_LCDC_CTL_POLARITY            (0xe0030)
-#define MDP_LCDC_DMA_CONFIG              (0xe1000)
-#define MDP_LCDC_DMA_SIZE                (0xe1004)
-#define MDP_LCDC_DMA_IBUF_ADDR           (0xe1008)
-#define MDP_LCDC_DMA_IBUF_Y_STRIDE       (0xe100c)
+#define MDP_LCDC_VSYNC_PERIOD            (0xe0008)
+#define MDP_LCDC_VSYNC_PULSE_WIDTH       (0xe000c)
+#define MDP_LCDC_DISPLAY_HCTL            (0xe0010)
+#define MDP_LCDC_DISPLAY_V_START         (0xe0014)
+#define MDP_LCDC_DISPLAY_V_END           (0xe0018)
+#define MDP_LCDC_ACTIVE_HCTL             (0xe001c)
+#define MDP_LCDC_ACTIVE_V_START          (0xe0020)
+#define MDP_LCDC_ACTIVE_V_END            (0xe0024)
+#define MDP_LCDC_BORDER_CLR              (0xe0028)
+#define MDP_LCDC_UNDERFLOW_CTL           (0xe002c)
+#define MDP_LCDC_HSYNC_SKEW              (0xe0030)
+#define MDP_LCDC_TEST_CTL                (0xe0034)
+#define MDP_LCDC_CTL_POLARITY            (0xe0038)
 
+#define MDP_PPP_SCALE_STATUS             (0x50000)
+#define MDP_PPP_BLEND_STATUS             (0x70000)
 
-#define MDP_DMA2_TERM 0x1
-#define MDP_DMA3_TERM 0x2
-#define MDP_PPP_TERM 0x3
+/* MDP_SW_RESET */
+#define MDP_PPP_SW_RESET                (1<<4)
 
 /* MDP_INTR_ENABLE */
-#define DL0_ROI_DONE           (1<<0)
-#define DL1_ROI_DONE           (1<<1)
-#define DL0_DMA2_TERM_DONE     (1<<2)
-#define DL1_DMA2_TERM_DONE     (1<<3)
-#define DL0_PPP_TERM_DONE      (1<<4)
-#define DL1_PPP_TERM_DONE      (1<<5)
-#define TV_OUT_DMA3_DONE       (1<<6)
-#define TV_ENC_UNDERRUN        (1<<7)
-#define DL0_FETCH_DONE         (1<<11)
-#define DL1_FETCH_DONE         (1<<12)
+#define DL0_ROI_DONE			(1<<0)
+#define TV_OUT_DMA3_DONE		(1<<6)
+#define TV_ENC_UNDERRUN			(1<<7)
 
-#define MDP_PPP_BUSY_STATUS (DL0_ROI_DONE| \
-			   DL1_ROI_DONE| \
-			   DL0_PPP_TERM_DONE| \
-			   DL1_PPP_TERM_DONE)
-
-#define MDP_ANY_INTR_MASK (DL0_ROI_DONE| \
-			   DL1_ROI_DONE| \
-			   DL0_DMA2_TERM_DONE| \
-			   DL1_DMA2_TERM_DONE| \
-			   DL0_PPP_TERM_DONE| \
-			   DL1_PPP_TERM_DONE| \
-			   DL0_FETCH_DONE| \
-			   DL1_FETCH_DONE| \
-			   TV_ENC_UNDERRUN)
+#ifdef CONFIG_MSM_MDP22
+#define MDP_DMA_P_DONE			(1 << 2)
+#else /* CONFIG_MSM_MDP31 */
+#define MDP_DMA_P_DONE			(1 << 14)
+#define MDP_LCDC_UNDERFLOW		(1 << 16)
+#define MDP_LCDC_FRAME_START		(1 << 15)
+#endif
 
 #define MDP_TOP_LUMA       16
 #define MDP_TOP_CHROMA     0
@@ -316,7 +378,12 @@
 #define PPP_OP_SCALE_X_ON (1<<0)
 #define PPP_OP_SCALE_Y_ON (1<<1)
 
+#ifndef CONFIG_MSM_MDP31
 #define PPP_OP_CONVERT_RGB2YCBCR 0
+#else
+#define PPP_OP_CONVERT_RGB2YCBCR (1<<30)
+#endif
+
 #define PPP_OP_CONVERT_YCBCR2RGB (1<<2)
 #define PPP_OP_CONVERT_ON (1<<3)
 
@@ -372,6 +439,13 @@
 #define PPP_OP_BG_CHROMA_SITE_COSITE 0
 #define PPP_OP_BG_CHROMA_SITE_OFFSITE (1<<27)
 
+#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)
+
 /* MDP_PPP_DESTINATION_CONFIG / MDP_FULL_BYPASS_WORD20 */
 #define PPP_DST_C0G_8BIT ((1<<0)|(1<<1))
 #define PPP_DST_C1B_8BIT ((1<<3)|(1<<2))
@@ -589,20 +663,71 @@
 #define PPP_ADDR_BG_CFG			MDP_FULL_BYPASS_WORD53
 #define PPP_ADDR_BG_PACK_PATTERN	MDP_FULL_BYPASS_WORD54
 
+/* color conversion matrix configuration registers */
+/* pfmv is mv1, prmv is mv2 */
+#define MDP_CSC_PFMVn(n)		(0x40400 + (4 * (n)))
+#define MDP_CSC_PRMVn(n)		(0x40440 + (4 * (n)))
+
+#ifdef CONFIG_MSM_MDP31
+#define MDP_PPP_CSC_PRE_BV1n(n)		(0x40500 + (4 * (n)))
+#define MDP_PPP_CSC_PRE_BV2n(n)		(0x40540 + (4 * (n)))
+#define MDP_PPP_CSC_POST_BV1n(n)	(0x40580 + (4 * (n)))
+#define MDP_PPP_CSC_POST_BV2n(n)	(0x405c0 + (4 * (n)))
+
+#define MDP_PPP_CSC_PRE_LV1n(n)		(0x40600 + (4 * (n)))
+#define MDP_PPP_CSC_PRE_LV2n(n)		(0x40640 + (4 * (n)))
+#define MDP_PPP_CSC_POST_LV1n(n)	(0x40680 + (4 * (n)))
+#define MDP_PPP_CSC_POST_LV2n(n)	(0x406c0 + (4 * (n)))
+
+#define MDP_PPP_SCALE_COEFF_D0_SET	(0)
+#define MDP_PPP_SCALE_COEFF_D1_SET	(1)
+#define MDP_PPP_SCALE_COEFF_D2_SET	(2)
+#define MDP_PPP_SCALE_COEFF_U1_SET	(3)
+#define MDP_PPP_SCALE_COEFF_LSBn(n)	(0x50400 + (8 * (n)))
+#define MDP_PPP_SCALE_COEFF_MSBn(n)	(0x50404 + (8 * (n)))
+
+#define MDP_PPP_DEINT_COEFFn(n)		(0x30010 + (4 * (n)))
+
+#define MDP_PPP_SCALER_FIR		(0)
+#define MDP_PPP_SCALER_MN		(1)
+
+#else /* !defined(CONFIG_MSM_MDP31) */
+
+#define MDP_CSC_PBVn(n)			(0x40500 + (4 * (n)))
+#define MDP_CSC_SBVn(n)			(0x40540 + (4 * (n)))
+#define MDP_CSC_PLVn(n)			(0x40580 + (4 * (n)))
+#define MDP_CSC_SLVn(n)			(0x405c0 + (4 * (n)))
+
+#endif
+
+
 /* MDP_DMA_CONFIG / MDP_FULL_BYPASS_WORD32 */
-#define DMA_DSTC0G_6BITS (1<<1)
-#define DMA_DSTC1B_6BITS (1<<3)
-#define DMA_DSTC2R_6BITS (1<<5)
 #define DMA_DSTC0G_5BITS (1<<0)
 #define DMA_DSTC1B_5BITS (1<<2)
 #define DMA_DSTC2R_5BITS (1<<4)
 
+#define DMA_DSTC0G_6BITS (2<<0)
+#define DMA_DSTC1B_6BITS (2<<2)
+#define DMA_DSTC2R_6BITS (2<<4)
+
+#define DMA_DSTC0G_8BITS (3<<0)
+#define DMA_DSTC1B_8BITS (3<<2)
+#define DMA_DSTC2R_8BITS (3<<4)
+
+#define DMA_DST_BITS_MASK 0x3F
+
 #define DMA_PACK_TIGHT (1<<6)
 #define DMA_PACK_LOOSE 0
 #define DMA_PACK_ALIGN_LSB 0
 #define DMA_PACK_ALIGN_MSB (1<<7)
+#define DMA_PACK_PATTERN_MASK (0x3f<<8)
 #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)
+
+
+#ifdef CONFIG_MSM_MDP22
 
 #define DMA_OUT_SEL_AHB  0
 #define DMA_OUT_SEL_MDDI (1<<14)
@@ -610,16 +735,32 @@
 #define DMA_AHBM_LCD_SEL_SECONDARY (1<<15)
 #define DMA_IBUF_C3ALPHA_EN (1<<16)
 #define DMA_DITHER_EN (1<<17)
-
 #define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
 #define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY (1<<18)
 #define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL (1<<19)
-
 #define DMA_IBUF_FORMAT_RGB565 (1<<20)
 #define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 0
-
+#define DMA_IBUF_FORMAT_MASK (1 << 20)
 #define DMA_IBUF_NONCONTIGUOUS (1<<21)
 
+#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_IBUF_FORMAT_RGB888			(0 << 25)
+#define DMA_IBUF_FORMAT_RGB565			(1 << 25)
+#define DMA_IBUF_FORMAT_XRGB8888		(2 << 25)
+#define DMA_IBUF_FORMAT_MASK			(3 << 25)
+#define DMA_IBUF_NONCONTIGUOUS			(0)
+
+#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY		(0)
+#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY	(0)
+#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL	(0)
+#endif
+
 /* MDDI REGISTER ? */
 #define MDDI_VDO_PACKET_DESC  0x5666
 #define MDDI_VDO_PACKET_PRIM  0xC3
diff --git a/drivers/video/msm/mdp_hw40.c b/drivers/video/msm/mdp_hw40.c
new file mode 100644
index 0000000..d36125e
--- /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 */
+	mdp_set_core_clk(4);
+	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..8f8b4d3
--- /dev/null
+++ b/drivers/video/msm/mdp_hw_init.c
@@ -0,0 +1,716 @@
+/* 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);
+	MDP_OUTP(MDP_BASE + 0x94010, 1);
+	MDP_OUTP(MDP_BASE + 0x9401c, 2);
+#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
new file mode 100644
index 0000000..be8d39d
--- /dev/null
+++ b/drivers/video/msm/mdp_lcdc.c
@@ -0,0 +1,432 @@
+/* drivers/video/msm/mdp_lcdc.c
+ *
+ * Copyright (c) 2009 Google Inc.
+ * 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
+ * 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.
+ *
+ * Author: Dima Zavin <dima@android.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+
+#include <mach/msm_fb.h>
+
+#include "mdp_hw.h"
+
+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;
+
+	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;
+
+#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_info("%s: ()\n", __func__);
+	panel_ops->unblank(panel_ops);
+
+	return 0;
+}
+
+static int lcdc_blank(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_info("%s: ()\n", __func__);
+	panel_ops->blank(panel_ops);
+
+	return 0;
+}
+
+static int lcdc_suspend(struct msm_panel_data *fb_panel)
+{
+	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
+
+	pr_info("%s: suspending\n", __func__);
+
+	mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
+	clk_disable(lcdc->pad_pclk);
+	clk_disable(lcdc->pclk);
+	clk_disable(lcdc->mdp_clk);
+
+	return 0;
+}
+
+static int lcdc_resume(struct msm_panel_data *fb_panel)
+{
+	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
+
+	pr_info("%s: resuming\n", __func__);
+
+	clk_enable(lcdc->mdp_clk);
+	clk_enable(lcdc->pclk);
+	clk_enable(lcdc->pad_pclk);
+	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
+
+	return 0;
+}
+
+static int lcdc_hw_init(struct mdp_lcdc_info *lcdc)
+{
+	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_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);
+	mdp_writel(lcdc->mdp, lcdc->parms.vsync_pulse_width,
+		   MDP_LCDC_VSYNC_PULSE_WIDTH);
+	mdp_writel(lcdc->mdp, lcdc->parms.display_hctl, MDP_LCDC_DISPLAY_HCTL);
+	mdp_writel(lcdc->mdp, lcdc->parms.display_vstart,
+		   MDP_LCDC_DISPLAY_V_START);
+	mdp_writel(lcdc->mdp, lcdc->parms.display_vend, MDP_LCDC_DISPLAY_V_END);
+	mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW);
+
+	mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR);
+	mdp_writel(lcdc->mdp, 0xff, MDP_LCDC_UNDERFLOW_CTL);
+	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL);
+	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);
+	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 (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB666)
+		dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
+	else
+		dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
+
+	mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG);
+
+	/* enable the lcdc timing generation */
+	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
+
+	return 0;
+}
+
+static void lcdc_wait_vsync(struct msm_panel_data *panel)
+{
+	struct mdp_lcdc_info *lcdc = panel_to_lcdc(panel);
+	int ret;
+
+	ret = wait_event_timeout(lcdc->vsync_waitq, lcdc->got_vsync, HZ / 2);
+	if (!ret && !lcdc->got_vsync)
+		pr_err("%s: timeout waiting for VSYNC\n", __func__);
+	lcdc->got_vsync = 0;
+}
+
+static void lcdc_request_vsync(struct msm_panel_data *fb_panel,
+			       struct msmfb_callback *vsync_cb)
+{
+	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
+
+	/* the vsync callback will start the dma */
+	vsync_cb->func(vsync_cb);
+	lcdc->got_vsync = 0;
+	mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, MDP_LCDC_FRAME_START,
+			   &lcdc->frame_start_cb);
+	lcdc_wait_vsync(fb_panel);
+}
+
+static void lcdc_clear_vsync(struct msm_panel_data *fb_panel)
+{
+	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
+	lcdc->got_vsync = 0;
+	mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, 0, NULL);
+}
+
+/* called in irq context with mdp lock held, when mdp gets the
+ * MDP_LCDC_FRAME_START interrupt */
+static void lcdc_frame_start(struct msmfb_callback *cb)
+{
+	struct mdp_lcdc_info *lcdc;
+
+	lcdc = container_of(cb, struct mdp_lcdc_info, frame_start_cb);
+
+	lcdc->got_vsync = 1;
+	wake_up(&lcdc->vsync_waitq);
+}
+
+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)
+	{
+		mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
+		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);
+}
+
+static void precompute_timing_parms(struct mdp_lcdc_info *lcdc)
+{
+	struct msm_lcdc_timing *timing = lcdc->pdata->timing;
+	struct msm_fb_data *fb_data = lcdc->pdata->fb_data;
+	unsigned int hsync_period;
+	unsigned int hsync_start_x;
+	unsigned int hsync_end_x;
+	unsigned int vsync_period;
+	unsigned int display_vstart;
+	unsigned int display_vend;
+
+	hsync_period = (timing->hsync_back_porch +
+			fb_data->xres + timing->hsync_front_porch);
+	hsync_start_x = timing->hsync_back_porch;
+	hsync_end_x = hsync_start_x + fb_data->xres - 1;
+
+	vsync_period = (timing->vsync_back_porch +
+			fb_data->yres + timing->vsync_front_porch);
+	vsync_period *= hsync_period;
+
+	display_vstart = timing->vsync_back_porch;
+	display_vstart *= hsync_period;
+	display_vstart += timing->hsync_skew;
+
+	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
+	 * information in the panel info */
+	lcdc->parms.hsync_ctl = (((hsync_period & 0xfff) << 16) |
+				 (timing->hsync_pulse_width & 0xfff));
+	lcdc->parms.vsync_period = vsync_period & 0xffffff;
+	lcdc->parms.vsync_pulse_width = (timing->vsync_pulse_width *
+					 hsync_period) & 0xffffff;
+
+	lcdc->parms.display_hctl = (((hsync_end_x & 0xfff) << 16) |
+				    (hsync_start_x & 0xfff));
+	lcdc->parms.display_vstart = display_vstart & 0xffffff;
+	lcdc->parms.display_vend = display_vend & 0xffffff;
+	lcdc->parms.hsync_skew = timing->hsync_skew & 0xfff;
+	lcdc->parms.polarity = ((timing->hsync_act_low << 0) |
+				(timing->vsync_act_low << 1) |
+				(timing->den_act_low << 2));
+	lcdc->parms.clk_rate = timing->clk_rate;
+}
+
+static int mdp_lcdc_probe(struct platform_device *pdev)
+{
+	struct msm_lcdc_platform_data *pdata = pdev->dev.platform_data;
+	struct mdp_lcdc_info *lcdc;
+	int ret = 0;
+
+	if (!pdata) {
+		pr_err("%s: no LCDC platform data found\n", __func__);
+		return -EINVAL;
+	}
+
+	lcdc = kzalloc(sizeof(struct mdp_lcdc_info), GFP_KERNEL);
+	if (!lcdc)
+		return -ENOMEM;
+
+	/* 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_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_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_err("%s: failed to get lcdc_pad_pclk\n", __func__);
+		ret = PTR_ERR(lcdc->pad_pclk);
+		goto err_get_pad_pclk;
+	}
+
+	init_waitqueue_head(&lcdc->vsync_waitq);
+	lcdc->pdata = pdata;
+	lcdc->frame_start_cb.func = lcdc_frame_start;
+
+	platform_set_drvdata(pdev, lcdc);
+
+	mdp_out_if_register(mdp_dev, MSM_LCDC_INTERFACE, lcdc, MDP_DMA_P_DONE,
+			    lcdc_dma_start);
+
+	precompute_timing_parms(lcdc);
+
+	lcdc->fb_start = pdata->fb_resource->start;
+	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;
+	lcdc->fb_panel_data.wait_vsync = lcdc_wait_vsync;
+	lcdc->fb_panel_data.request_vsync = lcdc_request_vsync;
+	lcdc->fb_panel_data.clear_vsync = lcdc_clear_vsync;
+	lcdc->fb_panel_data.blank = lcdc_blank;
+	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;
+
+	ret = lcdc_hw_init(lcdc);
+	if (ret) {
+		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_err("%s: Cannot register msm_panel pdev\n", __func__);
+		goto err_plat_dev_reg;
+	}
+
+	pr_info("%s: initialized\n", __func__);
+
+	return 0;
+
+err_plat_dev_reg:
+err_hw_init:
+	platform_set_drvdata(pdev, NULL);
+	clk_put(lcdc->pad_pclk);
+err_get_pad_pclk:
+	clk_put(lcdc->pclk);
+err_get_pclk:
+	clk_put(lcdc->mdp_clk);
+err_get_mdp_clk:
+	kfree(lcdc);
+	return ret;
+}
+
+static int mdp_lcdc_remove(struct platform_device *pdev)
+{
+	struct mdp_lcdc_info *lcdc = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	clk_put(lcdc->pclk);
+	clk_put(lcdc->pad_pclk);
+	kfree(lcdc);
+
+	return 0;
+}
+
+static struct platform_driver mdp_lcdc_driver = {
+	.probe = mdp_lcdc_probe,
+	.remove = mdp_lcdc_remove,
+	.driver = {
+		.name	= "msm_mdp_lcdc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int mdp_lcdc_add_mdp_device(struct device *dev,
+				   struct class_interface *class_intf)
+{
+	/* might need locking if mulitple mdp devices */
+	if (mdp_dev)
+		return 0;
+	mdp_dev = container_of(dev, struct mdp_device, dev);
+	return platform_driver_register(&mdp_lcdc_driver);
+}
+
+static void mdp_lcdc_remove_mdp_device(struct device *dev,
+				       struct class_interface *class_intf)
+{
+	/* might need locking if mulitple mdp devices */
+	if (dev != &mdp_dev->dev)
+		return;
+	platform_driver_unregister(&mdp_lcdc_driver);
+	mdp_dev = NULL;
+}
+
+static struct class_interface mdp_lcdc_interface = {
+	.add_dev = &mdp_lcdc_add_mdp_device,
+	.remove_dev = &mdp_lcdc_remove_mdp_device,
+};
+
+static int __init mdp_lcdc_init(void)
+{
+	return register_mdp_client(&mdp_lcdc_interface);
+}
+
+module_init(mdp_lcdc_init);
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index 2b6564e..19dfe82 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -1,7 +1,7 @@
-/* drivers/video/msm/mdp_ppp.c
+/* drivers/video/msm/src/drv/mdp/mdp_ppp.c
  *
- * Copyright (C) 2007 QUALCOMM Incorporated
  * Copyright (C) 2007 Google Incorporated
+ * Copyright (c) 2008-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
@@ -12,55 +12,35 @@
  * 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/file.h>
-#include <linux/delay.h>
 #include <linux/msm_mdp.h>
-#include <mach/msm_fb.h>
+#include <linux/file.h>
+#include <linux/android_pmem.h>
+#include <linux/major.h>
 
-#include "mdp_hw.h"
-#include "mdp_scale_tables.h"
+#include "linux/proc_fs.h"
 
-#define DLOG(x...) do {} while (0)
+#include <mach/hardware.h>
+#include <linux/io.h>
 
-#define MDP_DOWNSCALE_BLUR (MDP_DOWNSCALE_MAX + 1)
-static int downscale_y_table = MDP_DOWNSCALE_MAX;
-static int downscale_x_table = MDP_DOWNSCALE_MAX;
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <linux/semaphore.h>
+#include <linux/msm_kgsl.h>
 
-struct mdp_regs {
-	uint32_t src0;
-	uint32_t src1;
-	uint32_t dst0;
-	uint32_t dst1;
-	uint32_t src_cfg;
-	uint32_t dst_cfg;
-	uint32_t src_pack;
-	uint32_t dst_pack;
-	uint32_t src_rect;
-	uint32_t dst_rect;
-	uint32_t src_ystride;
-	uint32_t dst_ystride;
-	uint32_t op;
-	uint32_t src_bpp;
-	uint32_t dst_bpp;
-	uint32_t edge;
-	uint32_t phasex_init;
-	uint32_t phasey_init;
-	uint32_t phasex_step;
-	uint32_t phasey_step;
-};
+#include "mdp.h"
+#include "msm_fb.h"
 
-static uint32_t pack_pattern[] = {
-	PPP_ARRAY0(PACK_PATTERN)
-};
-
-static uint32_t src_img_cfg[] = {
-	PPP_ARRAY1(CFG, SRC)
-};
-
-static uint32_t dst_img_cfg[] = {
-	PPP_ARRAY1(CFG, DST)
-};
+#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,
@@ -74,457 +54,499 @@
 	[MDP_Y_CBCR_H2V2] = 1,
 	[MDP_Y_CRCB_H2V1] = 1,
 	[MDP_Y_CRCB_H2V2] = 1,
-	[MDP_YCRYCB_H2V1] = 2
+	[MDP_YCRYCB_H2V1] = 2,
+	[MDP_BGR_565] = 2
 };
 
-static uint32_t dst_op_chroma[] = {
-	PPP_ARRAY1(CHROMA_SAMP, DST)
-};
+extern uint32 mdp_plv[];
+extern struct semaphore mdp_ppp_mutex;
 
-static uint32_t src_op_chroma[] = {
-	PPP_ARRAY1(CHROMA_SAMP, SRC)
-};
-
-static uint32_t bg_op_chroma[] = {
-	PPP_ARRAY1(CHROMA_SAMP, BG)
-};
-
-static void rotate_dst_addr_x(struct mdp_blit_req *req, struct mdp_regs *regs)
+int mdp_get_bytes_per_pixel(uint32_t format,
+				 struct msm_fb_data_type *mfd)
 {
-	regs->dst0 += (req->dst_rect.w -
-		       min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp;
-	regs->dst1 += (req->dst_rect.w -
-		       min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp;
+	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 void rotate_dst_addr_y(struct mdp_blit_req *req, struct mdp_regs *regs)
+static uint32 mdp_conv_matx_rgb2yuv(uint32 input_pixel,
+				    uint16 *matrix_and_bias_vector,
+				    uint32 *clamp_vector,
+				    uint32 *look_up_table)
 {
-	regs->dst0 += (req->dst_rect.h -
-		       min((uint32_t)16, req->dst_rect.h)) *
-		       regs->dst_ystride;
-	regs->dst1 += (req->dst_rect.h -
-		       min((uint32_t)16, req->dst_rect.h)) *
-		       regs->dst_ystride;
-}
+	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;
 
-static void blit_rotate(struct mdp_blit_req *req,
-			struct mdp_regs *regs)
-{
-	if (req->flags == MDP_ROT_NOP)
-		return;
+	input_C2 = (input_pixel >> 16) & 0xFF;
+	input_C1 = (input_pixel >> 8) & 0xFF;
+	input_C0 = (input_pixel >> 0) & 0xFF;
 
-	regs->op |= PPP_OP_ROT_ON;
-	if ((req->flags & MDP_ROT_90 || req->flags & MDP_FLIP_LR) &&
-	    !(req->flags & MDP_ROT_90 && req->flags & MDP_FLIP_LR))
-		rotate_dst_addr_x(req, regs);
-	if (req->flags & MDP_ROT_90)
-		regs->op |= PPP_OP_ROT_90;
-	if (req->flags & MDP_FLIP_UD) {
-		regs->op |= PPP_OP_FLIP_UD;
-		rotate_dst_addr_y(req, regs);
-	}
-	if (req->flags & MDP_FLIP_LR)
-		regs->op |= PPP_OP_FLIP_LR;
-}
+	comp_C0 = input_C0;
+	comp_C1 = input_C1;
+	comp_C2 = input_C2;
 
-static void blit_convert(struct mdp_blit_req *req, struct mdp_regs *regs)
-{
-	if (req->src.format == req->dst.format)
-		return;
-	if (IS_RGB(req->src.format) && IS_YCRCB(req->dst.format)) {
-		regs->op |= PPP_OP_CONVERT_RGB2YCBCR | PPP_OP_CONVERT_ON;
-	} else if (IS_YCRCB(req->src.format) && IS_RGB(req->dst.format)) {
-		regs->op |= PPP_OP_CONVERT_YCBCR2RGB | PPP_OP_CONVERT_ON;
-		if (req->dst.format == MDP_RGB_565)
-			regs->op |= PPP_OP_CONVERT_MATRIX_SECONDARY;
-	}
-}
+	for (i = 0; i < 9; i++)
+		matrix[i] =
+		    ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20;
 
-#define GET_BIT_RANGE(value, high, low) \
-	(((1 << (high - low + 1)) - 1) & (value >> low))
-static uint32_t transp_convert(struct mdp_blit_req *req)
-{
-	uint32_t transp = 0;
-	if (req->src.format == MDP_RGB_565) {
-		/* pad each value to 8 bits by copying the high bits into the
-		 * low end, convert RGB to RBG by switching low 2 components */
-		transp |= ((GET_BIT_RANGE(req->transp_mask, 15, 11) << 3) |
-			   (GET_BIT_RANGE(req->transp_mask, 15, 13))) << 16;
+	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);
 
-		transp |= ((GET_BIT_RANGE(req->transp_mask, 4, 0) << 3) |
-			   (GET_BIT_RANGE(req->transp_mask, 4, 2))) << 8;
+	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];
 
-		transp |= (GET_BIT_RANGE(req->transp_mask, 10, 5) << 2) |
-			  (GET_BIT_RANGE(req->transp_mask, 10, 9));
-	} else {
-		/* convert RGB to RBG */
-		transp |= (GET_BIT_RANGE(req->transp_mask, 15, 8)) |
-			  (GET_BIT_RANGE(req->transp_mask, 23, 16) << 16) |
-			  (GET_BIT_RANGE(req->transp_mask, 7, 0) << 8);
-	}
-	return transp;
-}
-#undef GET_BIT_RANGE
-
-static void blit_blend(struct mdp_blit_req *req, struct mdp_regs *regs)
-{
-	/* TRANSP BLEND */
-	if (req->transp_mask != MDP_TRANSP_NOP) {
-		req->transp_mask = transp_convert(req);
-		if (req->alpha != MDP_ALPHA_NOP) {
-			/* use blended transparancy mode
-			 * pixel = (src == transp) ? dst : blend
-			 * blend is combo of blend_eq_sel and
-			 * blend_alpha_sel */
-			regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
-				PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
-				PPP_OP_BLEND_CONSTANT_ALPHA |
-				PPP_BLEND_ALPHA_TRANSP;
-		} else {
-			/* simple transparancy mode
-			 * pixel = (src == transp) ? dst : src */
-			regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
-				PPP_OP_BLEND_SRCPIXEL_TRANSP;
-		}
-	}
-
-	req->alpha &= 0xff;
-	/* ALPHA BLEND */
-	if (HAS_ALPHA(req->src.format)) {
-		regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
-			PPP_OP_BLEND_SRCPIXEL_ALPHA;
-	} else if (req->alpha < MDP_ALPHA_NOP) {
-		/* just blend by alpha */
-		regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
-			PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
-			PPP_OP_BLEND_CONSTANT_ALPHA;
-	}
-
-	regs->op |= bg_op_chroma[req->dst.format];
-}
-
-#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)) {
-		DLOG("crap bad scale\n");
-		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;
-}
-
-static void load_scale_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;
-}
-
-static int get_edge_cond(struct mdp_blit_req *req, struct mdp_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;
-}
-
-static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req,
-		      struct mdp_regs *regs)
-{
-	uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y;
-	uint32_t scale_factor_x, scale_factor_y;
-	uint32_t downscale;
-	uint32_t dst_w, dst_h;
-
-	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 ((req->src_rect.w == dst_w)  && (req->src_rect.h == dst_h) &&
-	    !(req->flags & MDP_BLUR)) {
-		regs->phasex_init = 0;
-		regs->phasey_init = 0;
-		regs->phasex_step = 0;
-		regs->phasey_step = 0;
-		return 0;
-	}
-
-	if (scale_params(req->src_rect.w, dst_w, 1, &phase_init_x,
-			 &phase_step_x) ||
-	    scale_params(req->src_rect.h, dst_h, 1, &phase_init_y,
-			 &phase_step_y))
-		return -1;
-
-	scale_factor_x = (dst_w * 10) / req->src_rect.w;
-	scale_factor_y = (dst_h * 10) / req->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;
+	if (look_up_table == 0)	/* check for NULL point */
+		_is_lookup_table_enabled = 0;
 	else
-		downscale = MDP_DOWNSCALE_PT2TOPT4;
-	if (downscale != downscale_x_table) {
-		load_scale_table(mdp, mdp_downscale_x_table[downscale], 64);
-		downscale_x_table = downscale;
+		_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;
 
-	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_scale_table(mdp, mdp_downscale_y_table[downscale], 64);
-		downscale_y_table = downscale;
-	}
+	/* 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];
 
-	regs->phasex_init = phase_init_x;
-	regs->phasey_init = phase_init_y;
-	regs->phasex_step = phase_step_x;
-	regs->phasey_step = phase_step_y;
-	regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
-	return 0;
+	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;
 }
 
-static void blit_blur(const struct mdp_info *mdp, struct mdp_blit_req *req,
-		      struct mdp_regs *regs)
+uint32 mdp_conv_matx_yuv2rgb(uint32 input_pixel,
+			     uint16 *matrix_and_bias_vector,
+			     uint32 *clamp_vector, uint32 *look_up_table)
 {
-	if (!(req->flags & MDP_BLUR))
-		return;
+	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;
 
-	if (!(downscale_x_table == MDP_DOWNSCALE_BLUR &&
-	      downscale_y_table == MDP_DOWNSCALE_BLUR)) {
-		load_scale_table(mdp, mdp_gaussian_blur_table, 128);
-		downscale_x_table = MDP_DOWNSCALE_BLUR;
-		downscale_y_table = MDP_DOWNSCALE_BLUR;
+	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;
 	}
 
-	regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
+	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_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_CRCB_H2V2) ?  2 :\
-	 (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ?  1 : 1)
+	(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)
+			uint32_t *len0, uint32_t *len1)
 {
 	*len0 = IMG_LEN(rect->h, img->width, rect->w, bpp);
 	if (IS_PSEUDOPLNR(img->format))
@@ -533,199 +555,1016 @@
 		*len1 = 0;
 }
 
-static int valid_src_dst(unsigned long src_start, unsigned long src_len,
-			 unsigned long dst_start, unsigned long dst_len,
-			 struct mdp_blit_req *req, struct mdp_regs *regs)
+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)
 {
-	unsigned long src_min_ok = src_start;
-	unsigned long src_max_ok = src_start + src_len;
-	unsigned long dst_min_ok = dst_start;
-	unsigned long dst_max_ok = dst_start + dst_len;
-	uint32_t src0_len, src1_len, dst0_len, dst1_len;
-	get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
-		 &src1_len);
-	get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
-		 &dst1_len);
+	uint32_t src0_len, src1_len;
 
-	if (regs->src0 < src_min_ok || regs->src0 > src_max_ok ||
-	    regs->src0 + src0_len > src_max_ok) {
-		DLOG("invalid_src %x %x %lx %lx\n", regs->src0,
-		      src0_len, src_min_ok, src_max_ok);
-		return 0;
+	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);
 	}
-	if (regs->src_cfg & PPP_SRC_PLANE_PSEUDOPLNR) {
-		if (regs->src1 < src_min_ok || regs->src1 > src_max_ok ||
-		    regs->src1 + src1_len > src_max_ok) {
-			DLOG("invalid_src1");
-			return 0;
+
+}
+#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 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_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;
 		}
 	}
-	if (regs->dst0 < dst_min_ok || regs->dst0 > dst_max_ok ||
-	    regs->dst0 + dst0_len > dst_max_ok) {
-		DLOG("invalid_dst");
-		return 0;
-	}
-	if (regs->dst_cfg & PPP_SRC_PLANE_PSEUDOPLNR) {
-		if (regs->dst1 < dst_min_ok || regs->dst1 > dst_max_ok ||
-		    regs->dst1 + dst1_len > dst_max_ok) {
-			DLOG("invalid_dst1");
-			return 0;
+	/* 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;
 		}
 	}
-	return 1;
+	/* 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;
+		}
+	}
+
+	src0_ystride = src_width * inpBpp;
+	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_ystride << 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 void flush_imgs(struct mdp_blit_req *req, struct mdp_regs *regs,
-		       struct file *src_file, struct file *dst_file)
+static int mdp_ppp_verify_req(struct mdp_blit_req *req)
 {
-}
+	u32 src_width, src_height, dst_width, dst_height;
 
-static void get_chroma_addr(struct mdp_img *img, struct mdp_rect *rect,
-			    uint32_t base, uint32_t bpp, uint32_t cfg,
-			    uint32_t *addr, uint32_t *ystride)
-{
-	uint32_t compress_v = Y_TO_CRCB_RATIO(img->format);
-	uint32_t compress_h = 2;
-	uint32_t  offset;
+	if (req == NULL) {
+		printk(KERN_ERR "\n%s(): Error in Line %u", __func__,
+			__LINE__);
+		return -1;
+	}
 
-	if (IS_PSEUDOPLNR(img->format)) {
-		offset = (rect->x / compress_h) * compress_h;
-		offset += rect->y == 0 ? 0 :
-			  ((rect->y + 1) / compress_v) * img->width;
-		*addr = base + (img->width * img->height * bpp);
-		*addr += offset * bpp;
-		*ystride |= *ystride << 16;
+	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 {
-		*addr = 0;
+		dst_width = req->dst_rect.w;
+		dst_height = req->dst_rect.h;
 	}
-}
 
-static int send_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
-		     struct mdp_regs *regs, struct file *src_file,
-		     struct file *dst_file)
-{
-	mdp_writel(mdp, 1, 0x060);
-	mdp_writel(mdp, regs->src_rect, PPP_ADDR_SRC_ROI);
-	mdp_writel(mdp, regs->src0, PPP_ADDR_SRC0);
-	mdp_writel(mdp, regs->src1, PPP_ADDR_SRC1);
-	mdp_writel(mdp, regs->src_ystride, PPP_ADDR_SRC_YSTRIDE);
-	mdp_writel(mdp, regs->src_cfg, PPP_ADDR_SRC_CFG);
-	mdp_writel(mdp, regs->src_pack, PPP_ADDR_SRC_PACK_PATTERN);
+	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;
 
-	mdp_writel(mdp, regs->op, PPP_ADDR_OPERATION);
-	mdp_writel(mdp, regs->phasex_init, PPP_ADDR_PHASEX_INIT);
-	mdp_writel(mdp, regs->phasey_init, PPP_ADDR_PHASEY_INIT);
-	mdp_writel(mdp, regs->phasex_step, PPP_ADDR_PHASEX_STEP);
-	mdp_writel(mdp, regs->phasey_step, PPP_ADDR_PHASEY_STEP);
+	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;
 
-	mdp_writel(mdp, (req->alpha << 24) | (req->transp_mask & 0xffffff),
-	       PPP_ADDR_ALPHA_TRANSP);
-
-	mdp_writel(mdp, regs->dst_cfg, PPP_ADDR_DST_CFG);
-	mdp_writel(mdp, regs->dst_pack, PPP_ADDR_DST_PACK_PATTERN);
-	mdp_writel(mdp, regs->dst_rect, PPP_ADDR_DST_ROI);
-	mdp_writel(mdp, regs->dst0, PPP_ADDR_DST0);
-	mdp_writel(mdp, regs->dst1, PPP_ADDR_DST1);
-	mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_DST_YSTRIDE);
-
-	mdp_writel(mdp, regs->edge, PPP_ADDR_EDGE);
-	if (regs->op & PPP_OP_BLEND_ON) {
-		mdp_writel(mdp, regs->dst0, PPP_ADDR_BG0);
-		mdp_writel(mdp, regs->dst1, PPP_ADDR_BG1);
-		mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_BG_YSTRIDE);
-		mdp_writel(mdp, src_img_cfg[req->dst.format], PPP_ADDR_BG_CFG);
-		mdp_writel(mdp, pack_pattern[req->dst.format],
-			   PPP_ADDR_BG_PACK_PATTERN);
+	default:
+		break;
 	}
-	flush_imgs(req, regs, src_file, dst_file);
-	mdp_writel(mdp, 0x1000, MDP_DISPLAY0_START);
+
+	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 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)
+int get_gem_img(struct mdp_img *img, unsigned long *start, unsigned long *len)
 {
-	struct mdp_regs regs = {0};
+	/* Set len to zero to appropriately error out if
+	   kgsl_gem_obj_addr fails */
 
-	if (unlikely(req->src.format >= MDP_IMGTYPE_LIMIT ||
-		     req->dst.format >= MDP_IMGTYPE_LIMIT)) {
-		printk(KERN_ERR "mpd_ppp: img is of wrong format\n");
-		return -EINVAL;
+	*len = 0;
+	return kgsl_gem_obj_addr(img->memory_id, (int) img->priv, start, len);
+}
+
+int get_img(struct mdp_img *img, struct fb_info *info, unsigned long *start,
+	    unsigned long *len, struct file **pp_file)
+{
+	int put_needed, ret = 0;
+	struct file *file;
+#ifdef CONFIG_ANDROID_PMEM
+	unsigned long vstart;
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+	if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
+		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) {
+		*start = info->fix.smem_start;
+		*len = info->fix.smem_len;
+		*pp_file = file;
+	} else {
+		ret = -1;
+		fput_light(file, put_needed);
+	}
+	return ret;
+}
+
+
+void put_img(struct file *p_src_file)
+{
+#ifdef CONFIG_ANDROID_PMEM
+	if (p_src_file)
+		put_pmem_file(p_src_file);
+#endif
+}
+
+
+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;
+	MDPIBUF iBuf;
+	u32 dst_width, dst_height;
+	struct file *p_src_file = 0 , *p_dst_file = 0;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)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 (req->flags & MDP_BLIT_SRC_GEM)
+		get_gem_img(&req->src, &src_start, &src_len);
+	else
+		get_img(&req->src, info, &src_start, &src_len, &p_src_file);
+	if (src_len == 0) {
+		printk(KERN_ERR "mdp_ppp: could not retrieve image from "
+		       "memory\n");
+		return -1;
+	}
+	if (req->flags & MDP_BLIT_DST_GEM)
+		get_gem_img(&req->dst, &dst_start, &dst_len);
+	else
+		get_img(&req->dst, info, &dst_start, &dst_len, &p_dst_file);
+	if (dst_len == 0) {
+		put_img(p_src_file);
+		printk(KERN_ERR "mdp_ppp: could not retrieve image from "
+		       "memory\n");
+		return -1;
+	}
+	if (mdp_ppp_verify_req(req)) {
+		printk(KERN_ERR "mdp_ppp: invalid image!\n");
+		put_img(p_src_file);
+		put_img(p_dst_file);
+		return -1;
 	}
 
-	if (unlikely(req->src_rect.x > req->src.width ||
-		     req->src_rect.y > req->src.height ||
-		     req->dst_rect.x > req->dst.width ||
-		     req->dst_rect.y > req->dst.height)) {
-		printk(KERN_ERR "mpd_ppp: img rect is outside of img!\n");
-		return -EINVAL;
+	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 *) (src_start + req->src.offset);
+	iBuf.mdpImg.cbcr_addr =
+	    (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;
 	}
 
-	/* set the src image configuration */
-	regs.src_cfg = src_img_cfg[req->src.format];
-	regs.src_cfg |= (req->src_rect.x & 0x1) ? PPP_SRC_BPP_ROI_ODD_X : 0;
-	regs.src_cfg |= (req->src_rect.y & 0x1) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
-	regs.src_rect = (req->src_rect.h << 16) | req->src_rect.w;
-	regs.src_pack = pack_pattern[req->src.format];
-
-	/* set the dest image configuration */
-	regs.dst_cfg = dst_img_cfg[req->dst.format] | PPP_DST_OUT_SEL_AXI;
-	regs.dst_rect = (req->dst_rect.h << 16) | req->dst_rect.w;
-	regs.dst_pack = pack_pattern[req->dst.format];
-
-	/* set src, bpp, start pixel and ystride */
-	regs.src_bpp = bytes_per_pixel[req->src.format];
-	regs.src0 = src_start + req->src.offset;
-	regs.src_ystride = req->src.width * regs.src_bpp;
-	get_chroma_addr(&req->src, &req->src_rect, regs.src0, regs.src_bpp,
-			regs.src_cfg, &regs.src1, &regs.src_ystride);
-	regs.src0 += (req->src_rect.x + (req->src_rect.y * req->src.width)) *
-		      regs.src_bpp;
-
-	/* set dst, bpp, start pixel and ystride */
-	regs.dst_bpp = bytes_per_pixel[req->dst.format];
-	regs.dst0 = dst_start + req->dst.offset;
-	regs.dst_ystride = req->dst.width * regs.dst_bpp;
-	get_chroma_addr(&req->dst, &req->dst_rect, regs.dst0, regs.dst_bpp,
-			regs.dst_cfg, &regs.dst1, &regs.dst_ystride);
-	regs.dst0 += (req->dst_rect.x + (req->dst_rect.y * req->dst.width)) *
-		      regs.dst_bpp;
-
-	if (!valid_src_dst(src_start, src_len, dst_start, dst_len, req,
-			   &regs)) {
-		printk(KERN_ERR "mpd_ppp: final src or dst location is "
-			"invalid, are you trying to make an image too large "
-			"or to place it outside the screen?\n");
-		return -EINVAL;
+	req->alpha &= 0xff;
+	if (req->alpha < MDP_ALPHA_NOP) {
+		iBuf.mdpImg.mdpOp |= MDPOP_ALPHAB;
+		iBuf.mdpImg.alpha = req->alpha;
+	} else {
+		iBuf.mdpImg.alpha = 0xff;
 	}
 
-	/* set up operation register */
-	regs.op = 0;
-	blit_rotate(req, &regs);
-	blit_convert(req, &regs);
+	/* 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)
-		regs.op |= PPP_OP_DITHER_EN;
-	blit_blend(req, &regs);
-	if (blit_scale(mdp, req, &regs)) {
-		printk(KERN_ERR "mpd_ppp: error computing scale for img.\n");
-		return -EINVAL;
-	}
-	blit_blur(mdp, req, &regs);
-	regs.op |= dst_op_chroma[req->dst.format] |
-		   src_op_chroma[req->src.format];
+		iBuf.mdpImg.mdpOp |= MDPOP_DITHER;
 
-	/* if the image is YCRYCB, the x and w must be even */
-	if (unlikely(req->src.format == MDP_YCRYCB_H2V1)) {
-		req->src_rect.x = req->src_rect.x & (~0x1);
-		req->src_rect.w = req->src_rect.w & (~0x1);
-		req->dst_rect.x = req->dst_rect.x & (~0x1);
-		req->dst_rect.w = req->dst_rect.w & (~0x1);
-	}
-	if (get_edge_cond(req, &regs))
+	if (req->flags & MDP_BLEND_FG_PREMULT) {
+#ifdef CONFIG_FB_MSM_MDP31
+		iBuf.mdpImg.mdpOp |= MDPOP_FG_PM_ALPHA;
+#else
+		put_img(p_src_file);
+		put_img(p_dst_file);
 		return -EINVAL;
+#endif
+	}
 
-	send_blit(mdp, req, &regs, src_file, dst_file);
+	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);
+			put_img(p_dst_file);
+			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);
+			put_img(p_dst_file);
+			return -EINVAL;
+		}
+
+		iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_SHARPENING;
+		iBuf.mdpImg.sp_value = req->sharpening_strength & 0xff;
+#else
+		put_img(p_src_file);
+		put_img(p_dst_file);
+		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);
+	put_img(p_dst_file);
 	return 0;
 }
diff --git a/drivers/video/msm/mdp_ppp.h b/drivers/video/msm/mdp_ppp.h
new file mode 100644
index 0000000..e045643
--- /dev/null
+++ b/drivers/video/msm/mdp_ppp.h
@@ -0,0 +1,82 @@
+/* drivers/video/msm/mdp_ppp.h
+ *
+ * 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.
+ */
+
+#ifndef _VIDEO_MSM_MDP_PPP_H_
+#define _VIDEO_MSM_MDP_PPP_H_
+
+#include <linux/types.h>
+
+struct ppp_regs {
+	uint32_t src0;
+	uint32_t src1;
+	uint32_t dst0;
+	uint32_t dst1;
+	uint32_t src_cfg;
+	uint32_t dst_cfg;
+	uint32_t src_pack;
+	uint32_t dst_pack;
+	uint32_t src_rect;
+	uint32_t dst_rect;
+	uint32_t src_ystride;
+	uint32_t dst_ystride;
+	uint32_t op;
+	uint32_t src_bpp;
+	uint32_t dst_bpp;
+	uint32_t edge;
+	uint32_t phasex_init;
+	uint32_t phasey_init;
+	uint32_t phasex_step;
+	uint32_t phasey_step;
+
+	uint32_t bg0;
+	uint32_t bg1;
+	uint32_t bg_cfg;
+	uint32_t bg_bpp;
+	uint32_t bg_pack;
+	uint32_t bg_ystride;
+
+#ifdef CONFIG_MSM_MDP31
+	uint32_t src_xy;
+	uint32_t src_img_sz;
+	uint32_t dst_xy;
+	uint32_t bg_xy;
+	uint32_t bg_img_sz;
+	uint32_t bg_alpha_sel;
+
+	uint32_t scale_cfg;
+	uint32_t csc_cfg;
+#endif
+};
+
+struct mdp_info;
+struct mdp_rect;
+struct mdp_blit_req;
+
+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);
+
+#ifndef CONFIG_MSM_MDP31
+int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs);
+#else
+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..8828a8f
--- /dev/null
+++ b/drivers/video/msm/mdp_ppp_v20.c
@@ -0,0 +1,2483 @@
+/* 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"
+
+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_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_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 */
+#if 0
+			phasex_step =
+			    (uint32) mdp_do_div(0x20000000 * iBuf->roi.width,
+						dst_roi_width_scale);
+			phasey_step =
+			    (uint32) mdp_do_div(0x20000000 * iBuf->roi.height,
+						dst_roi_height_scale);
+
+/*
+    phasex_step= ((long long) iBuf->roi.width * 0x20000000)/dst_roi_width_scale;
+    phasey_step= ((long long)iBuf->roi.height * 0x20000000)/dst_roi_height_scale;
+*/
+
+			phasex_init =
+			    (((long long)phasex_step - 0x20000000) >> 1);
+			phasey_init =
+			    (((long long)phasey_step - 0x20000000) >> 1);
+
+#else
+			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);
+#endif
+			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 (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_vsync.c b/drivers/video/msm/mdp_vsync.c
new file mode 100644
index 0000000..4108c89
--- /dev/null
+++ b/drivers/video/msm/mdp_vsync.c
@@ -0,0 +1,488 @@
+/* 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/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);
+DEFINE_MUTEX(vsync_timer_lock);
+
+static struct clk *mdp_vsync_clk;
+static struct msm_fb_data_type *vsync_mfd;
+static unsigned char timer_shutdown_flag;
+
+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_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(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) {
+			mutex_lock(&vsync_timer_lock);
+			timer_shutdown_flag = 1;
+			mutex_unlock(&vsync_timer_lock);
+			del_timer_sync(&vsync_mfd->vsync_resync_timer);
+			mutex_lock(&vsync_timer_lock);
+			timer_shutdown_flag = 0;
+			mutex_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);
+	}
+
+	mutex_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);
+	}
+	mutex_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
+#endif
+
+void mdp_config_vsync(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(NULL, "mdp_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, 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 cmd block enable */
+				mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
+					      FALSE);
+				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));
+
+				mdp_hw_vsync_clk_disable(mfd);
+				/* MDP cmd block disable */
+				mdp_pipe_ctrl(MDP_CMD_BLOCK,
+					      MDP_BLOCK_POWER_OFF, FALSE);
+			}
+		}
+#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/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
new file mode 100644
index 0000000..61bb345
--- /dev/null
+++ b/drivers/video/msm/mipi_dsi.c
@@ -0,0 +1,548 @@
+/* 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/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;
+
+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);
+
+	/*
+	 * Description: dsi clock is need to perform shutdown.
+	 * mdp4_dsi_cmd_dma_busy_wait() will enable dsi clock if disabled.
+	 * also, wait until dma (overlay and dmap) finish.
+	 */
+	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
+		if (mdp_rev >= MDP_REV_41) {
+			mdp4_dsi_cmd_dma_busy_wait(mfd);
+			mdp4_dsi_blt_dmap_busy_wait(mfd);
+		} else {
+			mdp3_dsi_cmd_dma_busy_wait(mfd);
+		}
+	}
+
+	/*
+	 * 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)
+				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
+	/* disbale dsi engine */
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0000, 0);
+
+	mipi_dsi_phy_ctrl(0);
+
+	local_bh_disable();
+	mipi_dsi_clk_disable();
+	local_bh_enable();
+
+	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;
+
+	if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save)
+		mipi_dsi_pdata->dsi_power_save(1);
+
+	clk_rate = mfd->fbi->var.pixclock;
+	clk_rate = min(clk_rate, mfd->panel_info.clk_max);
+
+	local_bh_disable();
+	mipi_dsi_clk_enable();
+	local_bh_enable();
+
+#ifndef CONFIG_FB_MSM_MDP303
+	mdp4_overlay_dsi_state_set(ST_DSI_RESUME);
+#endif
+
+	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_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  = &mfd->panel_info.mipi;
+	if (mfd->panel_info.type == MIPI_VIDEO_PANEL) {
+		dummy_xres = mfd->panel_info.mipi.xres_pad;
+		dummy_yres = mfd->panel_info.mipi.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);
+	mipi_dsi_cmd_bta_sw_trigger(); /* clean up ack_err_status */
+
+	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 (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);
+			}
+			mipi_dsi_set_tear_on(mfd);
+		}
+	}
+
+#ifdef CONFIG_MSM_BUS_SCALING
+	mdp_bus_scale_update_request(2);
+#endif
+	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__);
+			}
+		}
+
+		mipi_dsi_resource_initialized = 1;
+
+		return 0;
+	}
+
+	mipi_dsi_clk_init(&pdev->dev);
+
+	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;
+
+
+	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))) {
+		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 (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.mipi.xres_pad;
+		v_period += mfd->panel_info.mipi.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..2ed0596
--- /dev/null
+++ b/drivers/video/msm/mipi_dsi.h
@@ -0,0 +1,285 @@
+/* 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_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 DSI_PANEL_MAX	3
+
+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,
+};
+
+#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_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 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	1024
+#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
+
+
+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;
+};
+
+
+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);
+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 msm_fb_data_type *mfd,
+		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_sw_trigger(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_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);
+
+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);
+void mipi_dsi_clk_init(struct device *dev);
+void mipi_dsi_clk_deinit(struct device *dev);
+
+#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..6607e4c
--- /dev/null
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -0,0 +1,1248 @@
+
+/* 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/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 dsi_buf dsi_tx_buf;
+static int dsi_irq_enabled;
+static spinlock_t dsi_lock;
+
+static struct list_head pre_kickoff_list;
+static struct list_head post_kickoff_list;
+
+void mipi_dsi_init(void)
+{
+	init_completion(&dsi_dma_comp);
+	mipi_dsi_buf_alloc(&dsi_tx_buf, DSI_BUF_SIZE);
+	spin_lock_init(&dsi_lock);
+
+	INIT_LIST_HEAD(&pre_kickoff_list);
+	INIT_LIST_HEAD(&post_kickoff_list);
+}
+
+void mipi_dsi_enable_irq(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dsi_lock, flags);
+	if (dsi_irq_enabled) {
+		pr_debug("%s: IRQ aleady enabled\n", __func__);
+		spin_unlock_irqrestore(&dsi_lock, flags);
+		return;
+	}
+	dsi_irq_enabled = 1;
+	enable_irq(dsi_irq);
+	spin_unlock_irqrestore(&dsi_lock, flags);
+}
+
+void mipi_dsi_disable_irq(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dsi_lock, flags);
+	if (dsi_irq_enabled == 0) {
+		pr_debug("%s: IRQ already disabled\n", __func__);
+		spin_unlock_irqrestore(&dsi_lock, flags);
+		return;
+	}
+
+	dsi_irq_enabled = 0;
+	disable_irq(dsi_irq);
+	spin_unlock_irqrestore(&dsi_lock, flags);
+}
+
+/*
+ * mipi_dsi_disale_irq_nosync() should be called
+ * from interrupt context
+ */
+ void mipi_dsi_disable_irq_nosync(void)
+{
+	spin_lock(&dsi_lock);
+	if (dsi_irq_enabled == 0) {
+		pr_debug("%s: IRQ cannot be disabled\n", __func__);
+		return;
+	}
+
+	dsi_irq_enabled = 0;
+	disable_irq_nosync(dsi_irq);
+	spin_unlock(&dsi_lock);
+}
+
+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;
+}
+
+void mipi_dsi_host_init(struct mipi_panel_info *pinfo)
+{
+	uint32 dsi_ctrl, intr_ctrl;
+	uint32 data;
+
+	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_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_cmd_mdp_sw_trigger(void)
+{
+	mipi_dsi_pre_kickoff_action();
+	mipi_dsi_enable_irq();
+	MIPI_OUTP(MIPI_DSI_BASE + 0x090, 0x01);	/* trigger */
+	wmb();
+}
+
+
+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(mfd, &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(mfd, &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:
+ * ov_mutex need to be acquired before call this function.
+ */
+int mipi_dsi_cmds_tx(struct msm_fb_data_type *mfd,
+		struct dsi_buf *tp, struct dsi_cmd_desc *cmds, int cnt)
+{
+	struct dsi_cmd_desc *cm;
+	uint32 dsi_ctrl, ctrl;
+	int i, video_mode;
+
+	/* 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);
+	} else { /* cmd mode */
+		/*
+		 * during boot up, cmd mode is configured
+		 * even it is video mode panel.
+		 */
+		/* make sure mdp dma is not txing pixel data */
+		if (mfd->panel_info.type == MIPI_CMD_PANEL) {
+#ifndef CONFIG_FB_MSM_MDP303
+			mdp4_dsi_cmd_dma_busy_wait(mfd);
+#else
+			mdp3_dsi_cmd_dma_busy_wait(mfd);
+#endif
+		}
+	}
+
+	mipi_dsi_enable_irq();
+	cm = cmds;
+	mipi_dsi_buf_init(tp);
+	for (i = 0; i < cnt; i++) {
+		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++;
+	}
+	mipi_dsi_disable_irq();
+
+	if (video_mode)
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl); /* restore */
+
+	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 len)
+{
+	int cnt, res;
+	static int pkt_size;
+
+	if (len <= 2)
+		cnt = 4;	/* short read */
+	else {
+		if (len > MIPI_DSI_LEN)
+			len = MIPI_DSI_LEN;	/* 8 bytes at most */
+
+		res = len & 0x03;
+		len += (4 - res); /* 4 bytes align */
+		/*
+		 * 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 */
+#ifndef CONFIG_FB_MSM_MDP303
+			mdp4_dsi_cmd_dma_busy_wait(mfd);
+#else
+			mdp3_dsi_cmd_dma_busy_wait(mfd);
+#endif
+	}
+
+	mipi_dsi_enable_irq();
+	if (pkt_size != len) {
+		/* set new max pkt size */
+		pkt_size = len;
+		max_pktsize[0] = pkt_size;
+		mipi_dsi_buf_init(tp);
+		mipi_dsi_cmd_dma_add(tp, pkt_size_cmd);
+		mipi_dsi_cmd_dma_tx(tp);
+	}
+
+	mipi_dsi_buf_init(tp);
+	mipi_dsi_cmd_dma_add(tp, cmds);
+
+	/* transmit read comamnd to client */
+	mipi_dsi_cmd_dma_tx(tp);
+	/*
+	 * once cmd_dma_done interrupt received,
+	 * return data from client is ready and stored
+	 * at RDBK_DATA register already
+	 */
+	mipi_dsi_cmd_dma_rx(rp, cnt);
+
+	mipi_dsi_disable_irq();
+
+	/* strip off dcs header & crc */
+	if (cnt > 4) { /* long response */
+		rp->data += 4; /* skip dcs header */
+		rp->len -= 6; /* deduct 4 bytes header + 2 bytes crc */
+		rp->len -= 2; /* extra 2 bytes added */
+	} else {
+		rp->data += 1; /* skip dcs short header */
+		rp->len -= 2; /* deduct 1 byte header + 1 byte ecc */
+	}
+
+	return rp->len;
+}
+
+int mipi_dsi_cmd_dma_tx(struct dsi_buf *tp)
+{
+	int len;
+
+#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
+
+	len = tp->len;
+	len += 3;
+	len &= ~0x03;	/* multipled by 4 */
+
+	tp->dmap = dma_map_single(&dsi_dev, tp->data, 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, len);
+	wmb();
+	MIPI_OUTP(MIPI_DSI_BASE + 0x08c, 0x01);	/* trigger */
+	wmb();
+
+	wait_for_completion(&dsi_dma_comp);
+
+	dma_unmap_single(&dsi_dev, tp->dmap, 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_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);
+
+#ifdef CONFIG_FB_MSM_MDP40
+	mdp4_stat.intr_dsi++;
+#endif
+
+	if (isr & DSI_INTR_ERROR) {
+		mipi_dsi_error();
+	}
+
+	if (isr & DSI_INTR_VIDEO_DONE) {
+		/*
+		* do something  here
+		*/
+	}
+
+	if (isr & DSI_INTR_CMD_DMA_DONE) {
+		complete(&dsi_dma_comp);
+	}
+
+	if (isr & DSI_INTR_CMD_MDP_DONE) {
+		mipi_dsi_disable_irq_nosync();
+		mipi_dsi_post_kickoff_action();
+	}
+
+
+	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..27108f2
--- /dev/null
+++ b/drivers/video/msm/mipi_novatek.c
@@ -0,0 +1,463 @@
+/* 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"
+#include "mdp4.h"
+
+
+static struct mipi_dsi_novatek_platform_data *mipi_novatek_pdata;
+
+static struct dsi_buf novatek_tx_buf;
+static struct dsi_buf novatek_rx_buf;
+
+
+/* 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_pwm1[2] = {0x51, 0x0};	/* DTYPE_DCS_WRITE1 */
+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_cmd_backlight_cmds[] = {
+	{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(led_pwm1), led_pwm1},
+};
+
+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;
+	mipi_dsi_buf_init(rp);
+	mipi_dsi_buf_init(tp);
+
+	cmd = &novatek_manufacture_id_cmd;
+	mipi_dsi_cmds_rx(mfd, tp, rp, cmd, 3);
+	lp = (uint32 *)rp->data;
+	pr_info("%s: manufacture_id=%x", __func__, *lp);
+	return *lp;
+}
+
+static int fpga_addr;
+static bool support_3d;
+
+static void mipi_novatek_3d_init(int addr)
+{
+	fpga_addr = addr;
+}
+
+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;
+	}
+
+	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);
+}
+
+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(mfd, &novatek_tx_buf, novatek_video_on_cmds,
+			ARRAY_SIZE(novatek_video_on_cmds));
+	} else {
+		mipi_dsi_cmds_tx(mfd, &novatek_tx_buf, novatek_cmd_on_cmds,
+			ARRAY_SIZE(novatek_cmd_on_cmds));
+
+		mipi_dsi_cmd_bta_sw_trigger(); /* clean up ack_err_status */
+
+		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(mfd, &novatek_tx_buf, novatek_display_off_cmds,
+			ARRAY_SIZE(novatek_display_off_cmds));
+
+	return 0;
+}
+
+
+
+static void mipi_novatek_set_backlight(struct msm_fb_data_type *mfd)
+{
+	struct mipi_panel_info *mipi;
+	static int bl_level_old;
+
+	mipi  = &mfd->panel_info.mipi;
+	if (bl_level_old == mfd->bl_level)
+		return;
+
+	mutex_lock(&mfd->dma->ov_mutex);
+	/* mdp4_dsi_cmd_busy_wait: will turn on dsi clock also */
+	mdp4_dsi_cmd_dma_busy_wait(mfd);
+	mdp4_dsi_blt_dmap_busy_wait(mfd);
+
+	led_pwm1[1] = (unsigned char)(mfd->bl_level);
+	mipi_dsi_cmds_tx(mfd, &novatek_tx_buf, novatek_cmd_backlight_cmds,
+			ARRAY_SIZE(novatek_cmd_backlight_cmds));
+	bl_level_old = mfd->bl_level;
+	mutex_unlock(&mfd->dma->ov_mutex);
+	return;
+}
+
+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)
+{
+	if (pdev->id == 0) {
+		mipi_novatek_pdata = pdev->dev.platform_data;
+
+	if (mipi_novatek_pdata && mipi_novatek_pdata->fpga_3d_config_addr)
+		mipi_novatek_3d_init(mipi_novatek_pdata->fpga_3d_config_addr);
+
+		/* 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;
+	}
+
+	msm_fb_add_device(pdev);
+
+	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, 0666, 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;
+
+	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 __init mipi_novatek_lcd_init(void)
+{
+	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);
+}
+
+module_init(mipi_novatek_lcd_init);
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..b3bd6c8
--- /dev/null
+++ b/drivers/video/msm/mipi_novatek_cmd_qhd_pt.c
@@ -0,0 +1,99 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("mipi_cmd_novatek_qhd"))
+		return 0;
+#endif
+
+	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.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_BGR;
+	pinfo.mipi.data_lane0 = TRUE;
+#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_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;
+
+	ret = mipi_novatek_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_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..635b66e
--- /dev/null
+++ b/drivers/video/msm/mipi_novatek_video_qhd_pt.c
@@ -0,0 +1,98 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("mipi_video_novatek_qhd"))
+		return 0;
+#endif
+
+	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;
+#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_WVGA_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_renesas.c b/drivers/video/msm/mipi_renesas.c
new file mode 100644
index 0000000..652ca29
--- /dev/null
+++ b/drivers/video/msm/mipi_renesas.c
@@ -0,0 +1,1231 @@
+/* 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"
+
+#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 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_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}
+};
+
+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_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 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(mfd, &renesas_tx_buf, renesas_sleep_off_cmds,
+			ARRAY_SIZE(renesas_sleep_off_cmds));
+
+	mipi_set_tx_power_mode(1);
+	mipi_dsi_cmds_tx(mfd, &renesas_tx_buf, renesas_display_on_cmds,
+			ARRAY_SIZE(renesas_display_on_cmds));
+
+	if (mipi->mode == DSI_VIDEO_MODE)
+		mipi_dsi_cmds_tx(mfd, &renesas_tx_buf, renesas_video_on_cmds,
+			ARRAY_SIZE(renesas_video_on_cmds));
+	else
+		mipi_dsi_cmds_tx(mfd, &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(mfd, &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;
+
+	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 __init 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);
+}
+
+module_init(mipi_renesas_lcd_init);
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..ff573a3
--- /dev/null
+++ b/drivers/video/msm/mipi_renesas_cmd_fwvga_pt.c
@@ -0,0 +1,162 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("mipi_cmd_renesas_fwvga"))
+		return 0;
+#endif
+
+	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
+
+#ifdef USE_HW_VSYNC
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.lcd.hw_vsync_mode = TRUE;
+#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.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 = 0; /* 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..0e49011
--- /dev/null
+++ b/drivers/video/msm/mipi_renesas_video_fwvga_pt.c
@@ -0,0 +1,165 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("mipi_video_renesas_fwvga"))
+		return 0;
+#endif
+
+	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..da697b5
--- /dev/null
+++ b/drivers/video/msm/mipi_simulator.c
@@ -0,0 +1,162 @@
+/* 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 dsi_buf simulator_tx_buf;
+static struct dsi_buf simulator_rx_buf;
+static struct msm_panel_common_pdata *mipi_simulator_pdata;
+
+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(mfd, &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(mfd, &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__);
+
+	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 __init 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);
+}
+
+module_init(mipi_simulator_lcd_init);
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..8795554
--- /dev/null
+++ b/drivers/video/msm/mipi_simulator_video.c
@@ -0,0 +1,88 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("mipi_video_simulator"))
+		return 0;
+#endif
+	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_FWVGA_PT);
+	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_toshiba.c b/drivers/video/msm/mipi_toshiba.c
new file mode 100644
index 0000000..09fbf24
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba.c
@@ -0,0 +1,292 @@
+/* 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 "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_toshiba.h"
+
+static struct msm_panel_common_pdata *mipi_toshiba_pdata;
+
+static struct dsi_buf toshiba_tx_buf;
+static struct dsi_buf toshiba_rx_buf;
+
+#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};
+
+#ifdef CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT_PANEL
+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_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}
+};
+
+#endif
+
+#ifdef CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT_PANEL
+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_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}
+};
+#endif
+
+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;
+
+	mipi_dsi_cmds_tx(mfd, &toshiba_tx_buf, toshiba_display_on_cmds,
+			ARRAY_SIZE(toshiba_display_on_cmds));
+
+	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(mfd, &toshiba_tx_buf, toshiba_display_off_cmds,
+			ARRAY_SIZE(toshiba_display_off_cmds));
+
+	return 0;
+}
+
+static int __devinit mipi_toshiba_lcd_probe(struct platform_device *pdev)
+{
+	if (pdev->id == 0) {
+		mipi_toshiba_pdata = pdev->dev.platform_data;
+		return 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,
+};
+
+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;
+
+	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 __init 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);
+}
+
+module_init(mipi_toshiba_lcd_init);
diff --git a/drivers/video/msm/mipi_toshiba.h b/drivers/video/msm/mipi_toshiba.h
new file mode 100644
index 0000000..657636a
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba.h
@@ -0,0 +1,21 @@
+
+/* 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.
+ *
+ */
+
+#ifndef MIPI_TOSHIBA_H
+#define MIPI_TOSHIBA_H
+
+int mipi_toshiba_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#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..0477725
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba_video_wsvga_pt.c
@@ -0,0 +1,106 @@
+/* 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_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 */
+	{0x03, 0x0a, 0x04, 0x00, 0x20},
+	/* timing */
+	{0xab, 0x8a, 0x18, 0x00, 0x92, 0x97, 0x1b, 0x8c,
+	0x0c, 0x03, 0x04, 0xa0},
+    /* phy ctrl */
+	{0x5f, 0x00, 0x00, 0x10},
+    /* strength */
+	{0xff, 0x00, 0x06, 0x00},
+	/* pll control */
+	{0x0, 0x7f, 0x1, 0x1a, 0x00, 0x50, 0x48, 0x63,
+	0x41, 0x0f, 0x01,
+	0x00, 0x14, 0x03, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01 },
+};
+
+static int __init mipi_video_toshiba_wsvga_pt_init(void)
+{
+	int ret;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("mipi_video_toshiba_wsvga"))
+		return 0;
+#endif
+
+	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.mipi.xres_pad = 200;
+	pinfo.mipi.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 = 2;
+	pinfo.lcdc.v_front_porch = 7;
+	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.clk_rate = 384000000;
+
+	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 = 0x20;
+	pinfo.mipi.t_clk_pre = 0x2d;
+	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_WVGA_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_wvga_pt.c b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
new file mode 100644
index 0000000..1913513
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba_video_wvga_pt.c
@@ -0,0 +1,108 @@
+/* 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;
+
+#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (msm_fb_detect_client("mipi_video_toshiba_wvga"))
+		return 0;
+#endif
+
+	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/msm_dss_io_7x27a.c b/drivers/video/msm/msm_dss_io_7x27a.c
new file mode 100644
index 0000000..8e1959a
--- /dev/null
+++ b/drivers/video/msm/msm_dss_io_7x27a.c
@@ -0,0 +1,390 @@
+/* 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/clk.h>
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+
+/* multimedia sub system sfpb */
+char *mmss_sfpb_base;
+void  __iomem *periph_base;
+
+int mipi_dsi_clk_on;
+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;
+
+void mipi_dsi_clk_init(struct device *dev)
+{
+	dsi_esc_clk = clk_get(NULL, "dsi_esc_clk");
+	if (IS_ERR(dsi_esc_clk)) {
+		printk(KERN_ERR "can't find dsi_esc_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_byte_div_clk = clk_get(NULL, "dsi_byte_clk");
+	if (IS_ERR(dsi_byte_div_clk)) {
+		pr_err("can't find dsi_byte_div_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_pixel_clk = clk_get(NULL, "dsi_pixel_clk");
+	if (IS_ERR(dsi_pixel_clk)) {
+		pr_err("can't find dsi_pixel_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_clk = clk_get(NULL, "dsi_clk");
+	if (IS_ERR(dsi_clk)) {
+		pr_err("can't find dsi_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_ref_clk = clk_get(NULL, "dsi_ref_clk");
+	if (IS_ERR(dsi_ref_clk)) {
+		pr_err("can't find dsi_ref_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	mdp_dsi_pclk = clk_get(NULL, "mdp_dsi_pclk");
+	if (IS_ERR(mdp_dsi_pclk)) {
+		pr_err("can't find mdp_dsi_pclk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	ahb_m_clk = clk_get(NULL, "ahb_m_clk");
+	if (IS_ERR(ahb_m_clk)) {
+		pr_err("can't find ahb_m_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	ahb_s_clk = clk_get(NULL, "ahb_s_clk");
+	if (IS_ERR(ahb_s_clk)) {
+		pr_err("can't find ahb_s_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	return;
+
+mipi_dsi_clk_err:
+	mipi_dsi_clk_deinit(NULL);
+
+}
+
+void mipi_dsi_clk_deinit(struct device *dev)
+{
+	clk_put(mdp_dsi_pclk);
+	clk_put(ahb_m_clk);
+	clk_put(ahb_s_clk);
+	clk_put(dsi_ref_clk);
+	clk_put(dsi_byte_div_clk);
+	clk_put(dsi_esc_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 */
+	msleep(100);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0000);/* end phy w reset */
+	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 + 0x200, pd->pll[0]);
+	wmb();
+	MIPI_OUTP(MIPI_DSI_BASE + 0x200, (pd->pll[0] | 0x01));
+}
+
+void mipi_dsi_clk_enable(void)
+{
+	unsigned data = 0;
+
+	if (mipi_dsi_clk_on) {
+		pr_err("%s: mipi_dsi_clk already ON\n", __func__);
+		return;
+	}
+
+	mipi_dsi_clk_on = 1;
+
+	clk_enable(dsi_ref_clk);
+	clk_set_rate(dsi_byte_div_clk, data);
+	clk_set_rate(dsi_esc_clk, data);
+	clk_enable(mdp_dsi_pclk);
+	clk_enable(ahb_m_clk);
+	clk_enable(ahb_s_clk);
+	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);
+}
+
+void mipi_dsi_clk_disable(void)
+{
+	if (mipi_dsi_clk_on == 0) {
+		pr_err("%s: mipi_dsi_clk already OFF\n", __func__);
+		return;
+	}
+
+	mipi_dsi_clk_on = 0;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0118, 0);
+
+	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);
+	clk_disable(ahb_m_clk);
+	clk_disable(ahb_s_clk);
+	clk_disable(dsi_ref_clk);
+}
+
+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);
+
+		/* DSIPHY_PLL_CTRL_0, disbale dsi pll */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x40);
+
+		/* disbale 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..ce9fb28
--- /dev/null
+++ b/drivers/video/msm/msm_dss_io_8960.c
@@ -0,0 +1,715 @@
+/* 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/clk.h>
+#include "msm_fb.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;
+
+int mipi_dsi_clk_on;
+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;
+
+void mipi_dsi_clk_init(struct device *dev)
+{
+	amp_pclk = clk_get(NULL, "amp_pclk");
+	if (IS_ERR(amp_pclk)) {
+		pr_err("can't find amp_pclk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_m_pclk = clk_get(dev, "dsi_m_pclk");
+	if (IS_ERR(dsi_m_pclk)) {
+		pr_err("can't find dsi_m_pclk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_s_pclk = clk_get(dev, "dsi_s_pclk");
+	if (IS_ERR(dsi_s_pclk)) {
+		pr_err("can't find dsi_s_pclk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_byte_div_clk = clk_get(dev, "dsi_byte_div_clk");
+	if (IS_ERR(dsi_byte_div_clk)) {
+		pr_err("can't find dsi_byte_div_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_esc_clk = clk_get(dev, "dsi_esc_clk");
+	if (IS_ERR(dsi_esc_clk)) {
+		printk(KERN_ERR "can't find dsi_esc_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	return;
+
+mipi_dsi_clk_err:
+	mipi_dsi_clk_deinit(NULL);
+}
+
+void mipi_dsi_clk_deinit(struct device *dev)
+{
+	clk_put(amp_pclk);
+	clk_put(dsi_m_pclk);
+	clk_put(dsi_s_pclk);
+	clk_put(dsi_byte_div_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)
+{
+	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, 0x01);
+
+	/* 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 < 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) {
+		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 */
+	msleep(100);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0000);/* end phy w reset */
+	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 */
+
+	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();
+
+	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();
+	MIPI_OUTP(MIPI_DSI_BASE + 0x200, (pd->pll[0] | 0x01));
+
+	mipi_dsi_phy_rdy_poll();
+
+	off = 0x0440;	/* phy timig 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 mipi_dsi_clk_enable(void)
+{
+	if (mipi_dsi_clk_on) {
+		pr_err("%s: mipi_dsi_clk already ON\n", __func__);
+		return;
+	}
+
+	mipi_dsi_clk_on = 1;
+
+	clk_enable(amp_pclk); /* clock for AHB-master to AXI */
+	clk_enable(dsi_m_pclk);
+	clk_enable(dsi_s_pclk);
+	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, 2) < 0) /* divided by 2 */
+		pr_err("%s: dsi_esc_clk - "
+			"clk_set_rate failed\n", __func__);
+	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_ahb_en();
+	mipi_dsi_sfpb_cfg();
+}
+
+void mipi_dsi_clk_disable(void)
+{
+	if (mipi_dsi_clk_on == 0) {
+		pr_err("%s: mipi_dsi_clk already OFF\n", __func__);
+		return;
+	}
+
+	mipi_dsi_clk_on = 0;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0118, 0);
+
+	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(dsi_m_pclk);
+	clk_disable(dsi_s_pclk);
+	clk_disable(amp_pclk); /* clock for AHB-master to AXI */
+}
+
+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);
+
+		/* DSIPHY_PLL_CTRL_0, disbale dsi pll */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x40);
+
+		/* disbale 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_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);
+	HDMI_OUTP(HDMI_PHY_REG_2, 0x7F);
+	HDMI_OUTP(HDMI_PHY_REG_2, 0x3F);
+	HDMI_OUTP(HDMI_PHY_REG_2, 0x1F);
+
+	offset = HDMI_PHY_REG_4;
+	while (offset <= HDMI_PHY_REG_11) {
+		HDMI_OUTP(offset, 0x0);
+		offset += 0x4;
+	}
+
+	HDMI_OUTP(HDMI_PHY_REG_12, HDMI_INP(HDMI_PHY_REG_12) | PWRDN_B);
+	msleep(100);
+
+	HDMI_OUTP(HDMI_PHY_REG_3, 0x20);
+	HDMI_OUTP(HDMI_PHY_REG_12, 0x81);
+	HDMI_OUTP(HDMI_PHY_REG_2, 0x81);
+}
+
+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..e38170f
--- /dev/null
+++ b/drivers/video/msm/msm_dss_io_8x60.c
@@ -0,0 +1,613 @@
+/* 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/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;
+
+int mipi_dsi_clk_on;
+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;
+
+void mipi_dsi_clk_init(struct device *dev)
+{
+	amp_pclk = clk_get(NULL, "amp_pclk");
+	if (IS_ERR(amp_pclk)) {
+		pr_err("can't find amp_pclk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_m_pclk = clk_get(NULL, "dsi_m_pclk");
+	if (IS_ERR(dsi_m_pclk)) {
+		pr_err("can't find dsi_m_pclk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_s_pclk = clk_get(NULL, "dsi_s_pclk");
+	if (IS_ERR(dsi_s_pclk)) {
+		pr_err("can't find dsi_s_pclk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_byte_div_clk = clk_get(NULL, "dsi_byte_div_clk");
+	if (IS_ERR(dsi_byte_div_clk)) {
+		pr_err("can't find dsi_byte_div_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	dsi_esc_clk = clk_get(NULL, "dsi_esc_clk");
+	if (IS_ERR(dsi_esc_clk)) {
+		printk(KERN_ERR "can't find dsi_esc_clk\n");
+		goto mipi_dsi_clk_err;
+	}
+
+	return;
+
+mipi_dsi_clk_err:
+	mipi_dsi_clk_deinit(NULL);
+}
+
+void mipi_dsi_clk_deinit(struct device *dev)
+{
+	clk_put(amp_pclk);
+	clk_put(dsi_m_pclk);
+	clk_put(dsi_s_pclk);
+	clk_put(dsi_byte_div_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 */
+	msleep(100);
+	MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0000);/* end phy w reset */
+	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();
+	MIPI_OUTP(MIPI_DSI_BASE + 0x200, (pd->pll[0] | 0x01));
+}
+
+void mipi_dsi_clk_enable(void)
+{
+	if (mipi_dsi_clk_on) {
+		pr_err("%s: mipi_dsi_clk already ON\n", __func__);
+		return;
+	}
+
+	mipi_dsi_clk_on = 1;
+
+	clk_enable(amp_pclk); /* clock for AHB-master to AXI */
+	clk_enable(dsi_m_pclk);
+	clk_enable(dsi_s_pclk);
+	if (clk_set_rate(dsi_byte_div_clk, 1) < 0)	/* divided by 1 */
+		pr_err("%s: clk_set_rate failed\n",	__func__);
+	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_ahb_en();
+	mipi_dsi_sfpb_cfg();
+}
+
+void mipi_dsi_clk_disable(void)
+{
+	if (mipi_dsi_clk_on == 0) {
+		pr_err("%s: mipi_dsi_clk already OFF\n", __func__);
+		return;
+	}
+
+	mipi_dsi_clk_on = 0;
+
+	MIPI_OUTP(MIPI_DSI_BASE + 0x0118, 0);
+
+	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(dsi_m_pclk);
+	clk_disable(dsi_s_pclk);
+	clk_disable(amp_pclk); /* clock for AHB-master to AXI */
+}
+
+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);
+
+		/* DSIPHY_PLL_CTRL_0, disbale dsi pll */
+		MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x40);
+
+		/* disbale 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_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)
+{
+	/* 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 ec35130..1c4cc72 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-2011, 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,627 +15,3045 @@
  * 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/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>
 
-#define PRINT_FPS 0
-#define PRINT_BLIT_TIME 0
+#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/leds.h>
+#include <linux/pm_runtime.h>
 
-#define SLEEPING 0x4
-#define UPDATING 0x3
-#define FULL_UPDATE_DONE 0x2
-#define WAKING 0x1
-#define AWAKE 0x0
+#define MSM_FB_C
+#include "msm_fb.h"
+#include "mddihosti.h"
+#include "tvenc.h"
+#include "mdp.h"
+#include "mdp4.h"
 
-#define NONE 0
-#define SUSPEND_RESUME 0x1
-#define FPS 0x2
-#define BLIT_TIME 0x4
-#define SHOW_UPDATES 0x8
+#ifdef CONFIG_FB_MSM_LOGO
+#define INIT_IMAGE_FILE "/initlogo.rle"
+extern int load_565rle_image(char *filename);
+#endif
 
-#define DLOG(mask, fmt, args...) \
-do { \
-	if (msmfb_debug_mask & mask) \
-		printk(KERN_INFO "msmfb: "fmt, ##args); \
-} while (0)
+#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
+#define MSM_FB_NUM	3
+#endif
 
-static int msmfb_debug_mask;
-module_param_named(msmfb_debug_mask, msmfb_debug_mask, int,
-		   S_IRUGO | S_IWUSR | S_IWGRP);
+static unsigned char *fbram;
+static unsigned char *fbram_phys;
+static int fbram_size;
 
-struct mdp_device *mdp;
+static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
+static int pdev_list_cnt;
 
-struct msmfb_info {
-	struct fb_info *fb;
-	struct msm_panel_data *panel;
-	int xres;
-	int yres;
-	unsigned output_format;
-	unsigned yoffset;
-	unsigned frame_requested;
-	unsigned frame_done;
-	int sleeping;
-	unsigned update_frame;
-	struct {
-		int left;
-		int top;
-		int eright; /* exclusive */
-		int ebottom; /* exclusive */
-	} update_info;
-	char *black;
+int vsync_mode = 1;
 
-	spinlock_t update_lock;
-	struct mutex panel_init_lock;
-	wait_queue_head_t frame_wq;
-	struct work_struct resume_work;
-	struct msmfb_callback dma_callback;
-	struct msmfb_callback vsync_callback;
-	struct hrtimer fake_vsync;
-	ktime_t vsync_request_time;
+#define MAX_BLIT_REQ 256
+
+#define MAX_FBI_LIST 32
+static struct fb_info *fbi_list[MAX_FBI_LIST];
+static int fbi_list_index;
+
+static struct msm_fb_data_type *mfd_list[MAX_FBI_LIST];
+static int mfd_list_index;
+
+static u32 msm_fb_pseudo_palette[16] = {
+	0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
 };
 
-static int msmfb_open(struct fb_info *info, int user)
+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);
+
+#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];
+
+DEFINE_MUTEX(msm_fb_notify_update_sem);
+void msmfb_no_update_notify_timer_cb(unsigned long data)
 {
-	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);
 }
 
-static int msmfb_release(struct fb_info *info, int user)
+struct dentry *msm_fb_get_debugfs_root(void)
 {
-	return 0;
+	if (msm_fb_debugfs_root == NULL)
+		msm_fb_debugfs_root = debugfs_create_dir("msm_fb", NULL);
+
+	return msm_fb_debugfs_root;
 }
 
-/* Called from dma interrupt handler, must not sleep */
-static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
+void msm_fb_debugfs_file_create(struct dentry *root, const char *name,
+				u32 *var)
 {
-	unsigned long irq_flags;
-	struct msmfb_info *msmfb  = container_of(callback, struct msmfb_info,
-					       dma_callback);
-
-	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");
-		schedule_work(&msmfb->resume_work);
-	}
-	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;
-	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;
-		printk(KERN_WARNING "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);
-		return -1;
-	}
-	if (msmfb->sleeping == SLEEPING) {
-		DLOG(SUSPEND_RESUME, "tried to start dma while asleep\n");
-		spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
-		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)) {
-		printk(KERN_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 = ((msmfb->xres * (yoffset + y) + x) * 2);
-	mdp->dma(mdp, addr + msmfb->fb->fix.smem_start,
-		 msmfb->xres * 2, 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);
-	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);
-	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;
-	unsigned long irq_flags;
-	int sleeping;
-	int retry = 1;
-
-	DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n",
-		left, top, eright, ebottom, yoffset, pan_display);
-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);
-		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)) {
-				panel->request_vsync(panel,
-					&msmfb->vsync_callback);
-				retry = 0;
-				printk(KERN_WARNING "msmfb_pan_display timeout "
-					"rerequest vsync\n");
-			} else {
-				printk(KERN_WARNING "msmfb_pan_display timeout "
-					"waiting for frame start, %d %d\n",
-					msmfb->frame_requested,
-					msmfb->frame_done);
-				return;
-			}
-		}
-		goto restart;
-	}
-
-
-	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 */
-	msmfb->vsync_request_time = ktime_get();
-	if (panel->request_vsync && (sleeping == AWAKE)) {
-		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);
-		}
-	}
+	msm_fb_debugfs_file[msm_fb_debugfs_file_index++] =
+	    debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
 }
+#endif
 
-static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top,
-			 uint32_t eright, uint32_t ebottom)
+int msm_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-	msmfb_pan_update(info, left, top, eright, ebottom, 0, 0);
+	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 void power_on_panel(struct work_struct *work)
+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 msmfb_info *msmfb =
-		container_of(work, struct msmfb_info, resume_work);
-	struct msm_panel_data *panel = msmfb->panel;
-	unsigned long irq_flags;
+	struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent);
+	int bl_lvl;
 
-	mutex_lock(&msmfb->panel_init_lock);
-	DLOG(SUSPEND_RESUME, "turning on panel\n");
-	if (msmfb->sleeping == UPDATING) {
-		if (panel->unblank(panel)) {
-			printk(KERN_INFO "msmfb: panel unblank failed,"
-			       "not starting drawing\n");
-			goto error;
-		}
-		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);
+	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 int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	if ((var->xres != info->var.xres) ||
-	    (var->yres != info->var.yres) ||
-	    (var->xres_virtual != info->var.xres_virtual) ||
-	    (var->yres_virtual != info->var.yres_virtual) ||
-	    (var->xoffset != info->var.xoffset) ||
-	    (var->bits_per_pixel != info->var.bits_per_pixel) ||
-	    (var->grayscale != info->var.grayscale))
-		 return -EINVAL;
-	return 0;
-}
-
-int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	struct msmfb_info *msmfb = info->par;
-	struct msm_panel_data *panel = msmfb->panel;
-
-	/* "UPDT" */
-	if ((panel->caps & MSMFB_CAP_PARTIAL_UPDATES) &&
-	    (var->reserved[0] == 0x54445055)) {
-		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);
-	}
-	return 0;
-}
-
-static void msmfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
-{
-	cfb_fillrect(p, rect);
-	msmfb_update(p, rect->dx, rect->dy, rect->dx + rect->width,
-		     rect->dy + rect->height);
-}
-
-static void msmfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
-{
-	cfb_copyarea(p, area);
-	msmfb_update(p, area->dx, area->dy, area->dx + area->width,
-		     area->dy + area->height);
-}
-
-static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image)
-{
-	cfb_imageblit(p, image);
-	msmfb_update(p, image->dx, image->dy, image->dx + image->width,
-		     image->dy + image->height);
-}
-
-
-static int msmfb_blit(struct fb_info *info,
-		      void __user *p)
-{
-	struct mdp_blit_req req;
-	struct mdp_blit_req_list req_list;
-	int i;
-	int ret;
-
-	if (copy_from_user(&req_list, p, sizeof(req_list)))
-		return -EFAULT;
-
-	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;
-		ret = mdp->blit(mdp, info, &req);
-		if (ret)
-			return ret;
-	}
-	return 0;
-}
-
-
-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;
-
-	switch (cmd) {
-	case MSMFB_GRP_DISP:
-		mdp->set_grp_disp(mdp, arg);
-		break;
-	case MSMFB_BLIT:
-		ret = msmfb_blit(p, argp);
-		if (ret)
-			return ret;
-		break;
-	default:
-			printk(KERN_INFO "msmfb unknown ioctl: %d\n", cmd);
-			return -EINVAL;
-	}
-	return 0;
-}
-
-static struct fb_ops msmfb_ops = {
-	.owner = THIS_MODULE,
-	.fb_open = msmfb_open,
-	.fb_release = msmfb_release,
-	.fb_check_var = msmfb_check_var,
-	.fb_pan_display = msmfb_pan_display,
-	.fb_fillrect = msmfb_fillrect,
-	.fb_copyarea = msmfb_copyarea,
-	.fb_imageblit = msmfb_imageblit,
-	.fb_ioctl = msmfb_ioctl,
+static struct led_classdev backlight_led = {
+	.name		= "lcd-backlight",
+	.brightness	= MAX_BACKLIGHT_BRIGHTNESS,
+	.brightness_set	= msm_fb_set_bl_brightness,
 };
+#endif
 
-static unsigned PP[16];
+static struct msm_fb_platform_data *msm_fb_pdata;
+static char panel_name[128];
+module_param_string(panel_name, panel_name, sizeof(panel_name) , 0);
 
-
-
-#define BITS_PER_PIXEL 16
-
-static void setup_fb_info(struct msmfb_info *msmfb)
+int msm_fb_detect_client(const char *name)
 {
-	struct fb_info *fb_info = msmfb->fb;
-	int r;
+	int ret = -EPERM;
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+	u32 id;
+#endif
 
-	/* 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 = msmfb->xres * 2;
-
-	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 = msmfb->xres;
-	fb_info->var.yres_virtual = msmfb->yres * 2;
-	fb_info->var.bits_per_pixel = BITS_PER_PIXEL;
-	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.
-		 */
-		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);
+	MSM_FB_DEBUG("\n name = %s, panel_name = %s", name, panel_name);
+	if (strlen(panel_name)) {
+		if (!strcmp((char *)panel_name, name))
+			return 0;
+		else
+			return -EPERM;
 	}
 
-	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;
+	if (msm_fb_pdata && msm_fb_pdata->detect_client) {
+		ret = msm_fb_pdata->detect_client(name);
 
-	r = fb_alloc_cmap(&fb_info->cmap, 16, 0);
-	fb_info->pseudo_palette = PP;
+		/* if it's non mddi panel, we need to pre-scan
+		   mddi client to see if we can disable mddi host */
 
-	PP[0] = 0;
-	for (r = 1; r < 16; r++)
-		PP[r] = 0xffffffff;
-}
-
-static int setup_fbmem(struct msmfb_info *msmfb, struct platform_device *pdev)
-{
-	struct fb_info *fb = msmfb->fb;
-	struct resource *resource;
-	unsigned long size = msmfb->xres * msmfb->yres *
-			     (BITS_PER_PIXEL >> 3) * 2;
-	unsigned char *fbram;
-
-	/* board file might have attached a resource describing an fb */
-	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!resource)
-		return -EINVAL;
-
-	/* check the resource is large enough to fit the fb */
-	if (resource->end - resource->start < size) {
-		printk(KERN_ERR "allocated resource is too small for "
-				"fb\n");
-		return -ENOMEM;
-	}
-	fb->fix.smem_start = resource->start;
-	fb->fix.smem_len = resource->end - resource->start;
-	fbram = ioremap(resource->start,
-			resource->end - resource->start);
-	if (fbram == 0) {
-		printk(KERN_ERR "msmfb: cannot allocate fbram!\n");
-		return -ENOMEM;
-	}
-	fb->screen_base = fbram;
-	return 0;
-}
-
-static int msmfb_probe(struct platform_device *pdev)
-{
-	struct fb_info *fb;
-	struct msmfb_info *msmfb;
-	struct msm_panel_data *panel = pdev->dev.platform_data;
-	int ret;
-
-	if (!panel) {
-		pr_err("msmfb_probe: no platform data\n");
-		return -EINVAL;
-	}
-	if (!panel->fb_data) {
-		pr_err("msmfb_probe: no fb_data\n");
-		return -EINVAL;
+#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
+		if (!ret && msm_fb_pdata->mddi_prescan)
+			id = mddi_get_client_id();
+#endif
 	}
 
-	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;
-
-	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);
-	INIT_WORK(&msmfb->resume_work, power_on_panel);
-	msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres,
-			       GFP_KERNEL);
-
-	printk(KERN_INFO "msmfb_probe() installing %d x %d panel\n",
-	       msmfb->xres, msmfb->yres);
-
-	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);
-
-
-	msmfb->fake_vsync.function = msmfb_fake_vsync;
-
-	ret = register_framebuffer(fb);
-	if (ret)
-		goto error_register_framebuffer;
-
-	msmfb->sleeping = WAKING;
-
-	return 0;
-
-error_register_framebuffer:
-	iounmap(fb->screen_base);
-error_setup_fbmem:
-	framebuffer_release(msmfb->fb);
 	return ret;
 }
 
-static struct platform_driver msm_panel_driver = {
-	/* need to write remove */
-	.probe = msmfb_probe,
-	.driver = {.name = "msm_panel"},
+static ssize_t msm_fb_msm_fb_type(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	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 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;
+	default:
+		ret = snprintf(buf, PAGE_SIZE, "unknown panel\n");
+		break;
+	}
+
+	return ret;
+}
+
+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 msmfb_add_mdp_device(struct device *dev,
-				struct class_interface *class_intf)
+static int msm_fb_create_sysfs(struct platform_device *pdev)
 {
-	/* might need locking if mulitple mdp devices */
-	if (mdp)
+	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 int msm_fb_probe(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	int rc;
+	int err = 0;
+
+	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 = ioremap((unsigned long)fbram_phys, fbram_size);
+
+		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);
+
+		msm_fb_resource_initialized = 1;
 		return 0;
-	mdp = container_of(dev, struct mdp_device, dev);
-	return platform_driver_register(&msm_panel_driver);
+	}
+
+	if (!msm_fb_resource_initialized)
+		return -EPERM;
+
+	mfd = (struct msm_fb_data_type *)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;
+
+	mfd->panel_info.frame_count = 0;
+	mfd->bl_level = 0;
+#ifdef CONFIG_FB_MSM_OVERLAY
+	mfd->overlay_play_enable = 1;
+#endif
+	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 void msmfb_remove_mdp_device(struct device *dev,
-				struct class_interface *class_intf)
+static int msm_fb_remove(struct platform_device *pdev)
 {
-	/* might need locking if mulitple mdp devices */
-	if (dev != &mdp->dev)
-		return;
-	platform_driver_unregister(&msm_panel_driver);
-	mdp = NULL;
+	struct msm_fb_data_type *mfd;
+
+	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;
 }
 
-static struct class_interface msm_fb_interface = {
-	.add_dev = &msmfb_add_mdp_device,
-	.remove_dev = &msmfb_remove_mdp_device,
+#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;
+
+	if ((!mfd) || (mfd->key != MFD_KEY))
+		return 0;
+
+	/* 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;
+}
+
+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,
 };
 
-static int __init msmfb_init(void)
+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_OVERLAY) || \
+	 defined(CONFIG_FB_MSM_MDP303))
+static void memset32_io(u32 __iomem *_ptr, u32 val, size_t count)
 {
-	return register_mdp_client(&msm_fb_interface);
+	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_OVERLAY) || 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);
 }
 
-module_init(msmfb_init);
+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
+
+void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl)
+{
+	struct msm_fb_panel_data *pdata;
+
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
+	if ((pdata) && (pdata->set_backlight)) {
+		down(&mfd->sem);
+		mfd->bl_level = bkl_lvl;
+		pdata->set_backlight(mfd);
+		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;
+
+			msleep(16);
+			ret = pdata->off(mfd->pdev);
+			if (ret)
+				mfd->panel_power_on = curr_pwr_state;
+
+			mfd->op_enable = TRUE;
+		}
+		break;
+	}
+
+	return ret;
+}
+
+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;
+
+	/*
+	 * 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;
+		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);
+	/* calculate smem_len based on max size of two supplied modes */
+	fix->smem_len = roundup(MAX(msm_fb_line_length(mfd->index,
+					       panel_info->xres,
+					       bpp) *
+			    panel_info->yres * mfd->fb_page,
+			    msm_fb_line_length(mfd->index,
+					       panel_info->mode2_xres,
+					       bpp) *
+			    panel_info->mode2_yres * mfd->fb_page), PAGE_SIZE);
+
+
+
+	mfd->var_xres = panel_info->xres;
+	mfd->var_yres = panel_info->yres;
+
+	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) {
+		var->reserved[4] = panel_info->lcd.refx100 / 100;
+	} 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));
+	}
+		/*
+		 * id field for fb app
+		 */
+	    id = (int *)&mfd->panel;
+
+#if defined(CONFIG_FB_MSM_MDP22)
+	snprintf(fix->id, sizeof(fix->id), "msmfb22_%x", (__u32) *id);
+#elif defined(CONFIG_FB_MSM_MDP30)
+	snprintf(fix->id, sizeof(fix->id), "msmfb30_%x", (__u32) *id);
+#elif defined(CONFIG_FB_MSM_MDP31)
+	snprintf(fix->id, sizeof(fix->id), "msmfb31_%x", (__u32) *id);
+#elif defined(CONFIG_FB_MSM_MDP40)
+	snprintf(fix->id, sizeof(fix->id), "msmfb40_%x", (__u32) *id);
+#else
+	error CONFIG_FB_MSM_MDP undefined !
+#endif
+	 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 (fbram_size < fix->smem_len) {
+		printk(KERN_ERR "error: no more framebuffer memory!\n");
+		return -ENOMEM;
+	}
+
+	fbi->screen_base = fbram;
+	fbi->fix.smem_start = (unsigned long)fbram_phys;
+
+	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
+	if (!load_565rle_image(INIT_IMAGE_FILE)) ;	/* Flip buffer */
+#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 (!mfd->ref_cnt) {
+		mdp_set_dma_pan_info(info, NULL, TRUE);
+
+		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;
+}
+
+static int msm_fb_release(struct fb_info *info, int user)
+{
+	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;
+}
+
+DEFINE_SEMAPHORE(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;
+
+	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 (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);
+	mdp_set_dma_pan_info(info, dirtyPtr,
+			     (var->activate == FB_ACTIVATE_VBL));
+	mdp_dma_pan_update(info);
+	up(&msm_fb_pan_sem);
+
+	++mfd->panel_info.frame_count;
+	return 0;
+}
+
+static int msm_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	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 (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 int msm_fb_set_par(struct fb_info *info)
+{
+	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)))) {
+		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 msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd)
+{
+	if (mfd->hw_refresh)
+		return -EPERM;
+
+	if (mfd->sw_currently_refreshing) {
+		down(&mfd->sem);
+		mfd->sw_currently_refreshing = FALSE;
+		up(&mfd->sem);
+
+		/* wait until the refresher finishes the last job */
+		wait_for_completion_killable(&mfd->refresher_comp);
+	}
+
+	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;
+
+	/* 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;
+}
+
+#ifdef CONFIG_FB_MSM_OVERLAY
+static int msmfb_overlay_get(struct fb_info *info, void __user *p)
+{
+	struct mdp_overlay req;
+	int ret;
+
+	if (copy_from_user(&req, p, sizeof(req)))
+		return -EFAULT;
+
+	ret = mdp4_overlay_get(info, &req);
+	if (ret) {
+		printk(KERN_ERR "%s: ioctl failed \n",
+			__func__);
+		return ret;
+	}
+	if (copy_to_user(p, &req, sizeof(req))) {
+		printk(KERN_ERR "%s: copy2user failed \n",
+			__func__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int msmfb_overlay_set(struct fb_info *info, void __user *p)
+{
+	struct mdp_overlay req;
+	int ret;
+
+	if (copy_from_user(&req, p, sizeof(req)))
+		return -EFAULT;
+
+	ret = mdp4_overlay_set(info, &req);
+	if (ret) {
+		printk(KERN_ERR "%s: ioctl failed, rc=%d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	if (copy_to_user(p, &req, sizeof(req))) {
+		printk(KERN_ERR "%s: copy2user failed \n",
+			__func__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int msmfb_overlay_unset(struct fb_info *info, unsigned long *argp)
+{
+	int	ret, ndx;
+
+	ret = copy_from_user(&ndx, argp, sizeof(ndx));
+	if (ret) {
+		printk(KERN_ERR "%s:msmfb_overlay_unset ioctl failed \n",
+			__func__);
+		return ret;
+	}
+
+	return mdp4_overlay_unset(info, ndx);
+}
+
+static int msmfb_overlay_play(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;
+	struct file *p_src_file = 0;
+	struct file *p_src_plane1_file = 0, *p_src_plane2_file = 0;
+
+	if (mfd->overlay_play_enable == 0)	/* nothing to do */
+		return 0;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		printk(KERN_ERR "%s:msmfb_overlay_play ioctl failed \n",
+			__func__);
+		return ret;
+	}
+
+	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);
+
+	ret = mdp4_overlay_play(info, &req, &p_src_file, &p_src_plane1_file,
+				&p_src_plane2_file);
+
+#ifdef CONFIG_ANDROID_PMEM
+	if (p_src_file)
+		put_pmem_file(p_src_file);
+	if (p_src_plane1_file)
+		put_pmem_file(p_src_plane1_file);
+	if (p_src_plane2_file)
+		put_pmem_file(p_src_plane2_file);
+#endif
+
+	return ret;
+}
+
+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;
+}
+
+
+#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+static int msmfb_overlay_blt(struct fb_info *info, unsigned long *argp)
+{
+	int     ret;
+	struct msmfb_overlay_blt req;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		printk(KERN_ERR "%s:msmfb_overlay_blt ioctl failed\n",
+			__func__);
+		return ret;
+	}
+
+	ret = mdp4_overlay_blt(info, &req);
+
+	return ret;
+}
+
+static int msmfb_overlay_blt_off(struct fb_info *info, unsigned long *argp)
+{
+	int	ret;
+	struct msmfb_overlay_blt req;
+
+	ret = mdp4_overlay_blt_offset(info, &req);
+
+	ret = copy_to_user(argp, &req, sizeof(req));
+	if (ret)
+		printk(KERN_ERR "%s:msmfb_overlay_blt_off ioctl failed\n",
+		__func__);
+
+	return ret;
+}
+#else
+static int msmfb_overlay_blt(struct fb_info *info, unsigned long *argp)
+{
+	return 0;
+}
+static int msmfb_overlay_blt_off(struct fb_info *info, unsigned long *argp)
+{
+	return 0;
+}
+#endif
+
+static int msmfb_overlay_3d(struct fb_info *info, unsigned long *argp)
+{
+	int	ret;
+	struct msmfb_overlay_3d req;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		pr_err("%s:msmfb_overlay_3d_ctrl ioctl failed\n",
+			__func__);
+		return ret;
+	}
+
+	ret = mdp4_overlay_3d(info, &req);
+
+	return ret;
+}
+
+#endif
+
+DEFINE_SEMAPHORE(msm_fb_ioctl_ppp_sem);
+DEFINE_MUTEX(msm_fb_ioctl_lut_sem);
+DEFINE_MUTEX(msm_fb_ioctl_hist_sem);
+
+/* Set color conversion matrix from user space */
+
+#ifndef CONFIG_FB_MSM_MDP40
+static void msmfb_set_color_conv(struct mdp_ccs *p)
+{
+	int i;
+
+	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);
+	}
+}
+#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 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 hist;
+#ifndef CONFIG_FB_MSM_MDP40
+	struct mdp_ccs ccs_matrix;
+#endif
+	struct mdp_page_protection fb_page_protection;
+	int ret = 0;
+
+	switch (cmd) {
+#ifdef CONFIG_FB_MSM_OVERLAY
+	case MSMFB_OVERLAY_GET:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_get(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_OVERLAY_SET:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_set(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_OVERLAY_UNSET:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_unset(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_OVERLAY_PLAY:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_play(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	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_BLT:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_blt(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_OVERLAY_BLT_OFFSET:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_blt_off(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+	case MSMFB_OVERLAY_3D:
+		down(&msm_fb_ioctl_ppp_sem);
+		ret = msmfb_overlay_3d(info, argp);
+		up(&msm_fb_ioctl_ppp_sem);
+		break;
+#endif
+	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 = -EINVAL;
+#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 = 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:
+		if (!mfd->do_histogram)
+			return -ENODEV;
+
+		ret = copy_from_user(&hist, argp, sizeof(hist));
+		if (ret)
+			return ret;
+
+		mutex_lock(&msm_fb_ioctl_hist_sem);
+		ret = mfd->do_histogram(info, &hist);
+		mutex_unlock(&msm_fb_ioctl_hist_sem);
+		break;
+
+	case MSMFB_HISTOGRAM_START:
+		if (!mfd->do_histogram)
+			return -ENODEV;
+		ret = mdp_start_histogram(info);
+		break;
+
+	case MSMFB_HISTOGRAM_STOP:
+		if (!mfd->do_histogram)
+			return -ENODEV;
+		ret = mdp_stop_histogram(info);
+		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;
+
+	default:
+		MSM_FB_INFO("MDP: unknown ioctl (cmd=%x) received!\n", cmd);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int msm_fb_register_driver(void)
+{
+	return platform_driver_register(&msm_fb_driver);
+}
+
+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;
+
+	if (!pdev)
+		return NULL;
+	id = pdev->id;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata)
+		return NULL;
+	type = pdata->panel_info.type;
+
+#if defined MSM_FB_NUM
+	/*
+	 * over written fb_num which defined
+	 * at panel_info
+	 *
+	 */
+	if (type == HDMI_PANEL || type == DTV_PANEL || type == TV_PANEL)
+		pdata->panel_info.fb_num = 1;
+	else
+		pdata->panel_info.fb_num = MSM_FB_NUM;
+
+	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;
+
+	if (fb_num <= 0)
+		return NULL;
+
+	if (fbi_list_index >= MAX_FBI_LIST) {
+		printk(KERN_ERR "msm_fb: no more framebuffer info list!\n");
+		return NULL;
+	}
+	/*
+	 * alloc panel device data
+	 */
+	this_dev = msm_fb_device_alloc(pdata, type, id);
+
+	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;
+
+	/* 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)
+{
+	struct fb_info *info;
+
+	if (fb_num > MAX_FBI_LIST)
+		return -1;
+
+	info = fbi_list[fb_num];
+	if (!info)
+		return -1;
+
+	*start = info->fix.smem_start;
+	*len = info->fix.smem_len;
+	return 0;
+}
+EXPORT_SYMBOL(get_fb_phys_info);
+
+int __init msm_fb_init(void)
+{
+	int rc = -ENODEV;
+
+	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);
+		}
+	}
+#endif
+
+	return 0;
+}
+
+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..bdf32eb
--- /dev/null
+++ b/drivers/video/msm/msm_fb.h
@@ -0,0 +1,171 @@
+/* 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.
+ *
+ */
+
+#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 <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>
+
+#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 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;
+
+	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 *hist);
+	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;
+
+#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 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);
+
+int msm_fb_detect_client(const char *name);
+
+#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);
+
+#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..84de095
--- /dev/null
+++ b/drivers/video/msm/msm_fb_panel.c
@@ -0,0 +1,141 @@
+/* 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;
+
+	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..bbf5a38
--- /dev/null
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -0,0 +1,199 @@
+/* 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.
+ *
+ */
+
+#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 */
+
+/* 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 */
+	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;
+};
+
+struct mddi_panel_info {
+	__u32 vdopkt;
+};
+
+/* DSI PHY configuration */
+struct mipi_dsi_phy_ctrl {
+	uint32 regulator[5];
+	uint32 timing[12];
+	uint32 ctrl[4];
+	uint32 strength[4];
+	uint32 pll[21];
+};
+
+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;
+	/* Pad width */
+	uint32 xres_pad;
+	/* Pad height */
+	uint32 yres_pad;
+};
+
+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;
+
+
+	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);
+	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..73e2428
--- /dev/null
+++ b/drivers/video/msm/tvenc.c
@@ -0,0 +1,521 @@
+/* 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/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>
+#include <mach/msm_reqs.h>
+
+#define TVENC_C
+#include "tvenc.h"
+#include "msm_fb.h"
+#include "mdp4.h"
+#ifdef CONFIG_MSM_NPA_SYSTEM_BUS
+/* NPA Flow ID */
+#define MSM_SYSTEM_BUS_RATE	MSM_AXI_FLOW_MDP_DTV_720P_2BPP
+#else
+/* AXI rate in KHz */
+#define MSM_SYSTEM_BUS_RATE	128000000
+#endif
+
+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_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_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(tvenc_pclk);
+		clk_disable(tvenc_clk);
+		return ret;
+	}
+tvencp_err:
+	clk_disable(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_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_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(mdp_tv_clk);
+		clk_disable(tvdac_clk);
+		if (tvenc_pdata->poll)
+			tvenc_set_encoder_clock(CLOCK_OFF);
+		return ret;
+	}
+
+mdptv_err:
+	clk_disable(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(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_enable(mfd->ebi1_clk);
+#endif
+	mdp_set_core_clk(1);
+	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;
+
+	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_pdata = pdev->dev.platform_data;
+		tvenc_resource_initialized = 1;
+		return 0;
+	}
+
+	if (!tvenc_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 (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__);
+		}
+	}
+#else
+	mfd->ebi1_clk = clk_get(NULL, "ebi1_tv_clk");
+	if (IS_ERR(mfd->ebi1_clk)) {
+		rc = PTR_ERR(mfd->ebi1_clk);
+		goto tvenc_probe_err;
+	}
+	clk_set_rate(mfd->ebi1_clk, MSM_SYSTEM_BUS_RATE);
+#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)
+{
+	int ret;
+	tvenc_clk = clk_get(NULL, "tv_enc_clk");
+	tvdac_clk = clk_get(NULL, "tv_dac_clk");
+	tvenc_pclk = clk_get(NULL, "tv_enc_pclk");
+	mdp_tv_clk = clk_get(NULL, "mdp_tv_clk");
+
+#ifdef CONFIG_FB_MSM_MDP40
+	tv_src_clk = clk_get(NULL, "tv_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;
+		}
+	}
+
+	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..6912961
--- /dev/null
+++ b/drivers/video/msm/tvout_msm.c
@@ -0,0 +1,648 @@
+/* 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;
+	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..b55c884
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
@@ -0,0 +1,634 @@
+/* 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 <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;
+	struct res_trk_firmware_addr firmware_addr;
+	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);
+	ddl_context->memtype = res_trk_get_mem_type();
+	if (ddl_context->memtype == -1) {
+		DDL_MSG_ERROR("ddl_dev_init:Illegal memtype");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	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 (ddl_context->memtype == MEMTYPE_SMI_KERNEL) {
+		ptr = ddl_pmem_alloc(&ddl_context->dram_base_a,
+			ddl_context->fw_memory_size, DDL_KILO_BYTE(128));
+	} else {
+		if (!res_trk_get_firmware_addr(&firmware_addr) &&
+		   firmware_addr.buf_size >= ddl_context->fw_memory_size) {
+			if (DDL_ADDR_IS_ALIGNED(firmware_addr.device_addr,
+				DDL_KILO_BYTE(128))) {
+				ptr = (void *) firmware_addr.base_addr;
+				ddl_context->dram_base_a.physical_base_addr =
+				ddl_context->dram_base_a.align_physical_addr =
+					(u8 *)firmware_addr.device_addr;
+				ddl_context->dram_base_a.align_virtual_addr  =
+				ddl_context->dram_base_a.virtual_base_addr =
+					firmware_addr.base_addr;
+				ddl_context->dram_base_a.buffer_size =
+					ddl_context->fw_memory_size;
+			} else {
+				DDL_MSG_ERROR("firmware base not aligned %p",
+					(void *)firmware_addr.device_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) {
+		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->memtype == MEMTYPE_EBI1)
+		clean_caches((unsigned long)firmware_addr.base_addr,
+		firmware_addr.buf_size,	firmware_addr.device_addr);
+
+	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_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;
+	}
+	ptr = ddl_pmem_alloc(&ddl->shared_mem[0],
+			DDL_FW_AUX_HOST_CMD_SPACE_SIZE, sizeof(u32));
+	if (!ptr)
+		status = VCD_ERR_ALLOC_FAIL;
+	if (!status && ddl_context->frame_channel_depth
+		== VCD_DUAL_FRAME_COMMAND_CHANNEL) {
+		ptr = ddl_pmem_alloc(&ddl->shared_mem[1],
+				DDL_FW_AUX_HOST_CMD_SPACE_SIZE, sizeof(u32));
+		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 (vidc_msg_timing) {
+		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
+	if ((encoder->codec.codec == VCD_CODEC_MPEG4 &&
+		!encoder->short_header.short_header) ||
+		encoder->codec.codec == VCD_CODEC_H264) {
+		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;
+		}
+	} else {
+		encoder->seq_header.buffer_size = 0;
+		encoder->seq_header.virtual_base_addr = 0;
+		encoder->seq_header.align_physical_addr = 0;
+		encoder->seq_header.align_virtual_addr = 0;
+	}
+	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");
+	if (vidc_msg_timing) {
+		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;
+	u32 vcd_status = VCD_S_SUCCESS;
+
+	DDL_MSG_HIGH("ddl_encode_frame");
+	if (vidc_msg_timing)
+		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_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");
+	if (vidc_msg_timing) {
+		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");
+	if (vidc_msg_timing)
+		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..9084ea8
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -0,0 +1,446 @@
+/* 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 _VCD_DDL_H_
+#define _VCD_DDL_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)
+
+struct ddl_buf_addr{
+	u8  *virtual_base_addr;
+	u8  *physical_base_addr;
+	u8  *align_physical_addr;
+	u8  *align_virtual_addr;
+	u32 buffer_size;
+};
+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_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_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_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 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;
+};
+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;
+};
+union ddl_codec_data{
+	struct ddl_codec_data_hdr  hdr;
+	struct ddl_decoder_data   decoder;
+	struct ddl_encoder_data   encoder;
+};
+struct ddl_context{
+	int memtype;
+	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;
+	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);
+	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_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_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_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);
+
+#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(void);
+#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..51a0d13
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
@@ -0,0 +1,110 @@
+/* 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 _VCD_DDL_API_H_
+#define _VCD_DDL_API_H_
+
+#include "vidc.h"
+#include "vcd_api.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 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_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..86ecec3
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
@@ -0,0 +1,134 @@
+/* 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 _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_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(10))
+#define DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE  (DDL_KILO_BYTE(500))
+#define DDL_FW_H264DEC_CONTEXT_SPACE_SIZE      (DDL_KILO_BYTE(800))
+#define DDL_FW_OTHER_CONTEXT_SPACE_SIZE        (DDL_KILO_BYTE(10))
+
+#define VCD_DEC_CPB_SIZE         (DDL_KILO_BYTE(512))
+#define DDL_DBG_CORE_DUMP_SIZE   (DDL_KILO_BYTE(10))
+
+#define DDL_BUFEND_PAD                    256
+#define DDL_ENC_SEQHEADER_SIZE            (512+DDL_BUFEND_PAD)
+#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..d658647
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -0,0 +1,755 @@
+/* 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_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_INCOMPLETE_FRAME:
+	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_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:
+		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_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;
+	}
+	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_INCOMPLETE_FRAME:
+		string = "VIDC_1080P_ERROR_INCOMPLETE_FRAME";
+	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..1b700bd
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -0,0 +1,959 @@
+/* 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 <mach/msm_memtypes.h>
+#include "vcd_ddl.h"
+#include "vcd_ddl_shared_mem.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 (frame[i].vcd_frm.virtual) {
+			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);
+		}
+
+		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)
+{
+	if (ddl_context->memtype == MEMTYPE_SMI_KERNEL) {
+		ddl_pmem_free(&ddl_context->dram_base_a);
+		ddl_pmem_free(&ddl_context->dram_base_b);
+	}
+	ddl_pmem_free(&ddl_context->metadata_shared_input);
+	ddl_fw_release();
+}
+
+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_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;
+
+	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) {
+		ptr = ddl_pmem_alloc(&dec_bufs->context, buf_size.sz_context,
+			DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (buf_size.sz_nb_ip > 0) {
+		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) {
+		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) {
+		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) {
+		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) {
+		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) {
+		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) {
+		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) {
+		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) {
+		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) {
+		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) {
+		ptr = ddl_pmem_alloc(&dec_bufs->desc, buf_size.sz_desc,
+			DDL_KILO_BYTE(2));
+		if (!ptr)
+			status = VCD_ERR_ALLOC_FAIL;
+	}
+	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;
+	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 * 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));
+			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));
+		}
+		sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE;
+		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;
+
+	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) {
+			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) {
+			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) {
+			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) {
+			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) {
+			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) {
+			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) {
+			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) {
+			ptr = ddl_pmem_alloc(&enc_bufs->context,
+				buf_size.sz_context, DDL_KILO_BYTE(2));
+			if (!ptr)
+				status = VCD_ERR_ALLOC_FAIL;
+		}
+		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)
+{
+	if (res_change) {
+		DDL_MSG_LOW("%s Resolution change, start realloc\n",
+				 __func__);
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+		ddl->cmd_state = DDL_CMD_EOS;
+		vidc_1080p_frame_start_realloc(ddl->instance_id);
+	}
+}
+
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..be46e97
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -0,0 +1,1638 @@
+/* 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_shared_mem.h"
+#include "vcd_ddl_metadata.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);
+
+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;
+
+	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);
+		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_MED("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 (!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 bottom_frame_tag;
+
+	DDL_MSG_MED("ddl_encoder_frame_run_callback");
+	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);
+		vidc_sm_get_frame_tags(&ddl->shared_mem
+			[ddl->command_channel],
+			&output_frame->ip_frm_tag, &bottom_frame_tag);
+
+		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 (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)) {
+			u8 *input_buffer_address = NULL;
+			output_frame->data_len =
+				encoder->enc_frame_info.enc_frame_size;
+			output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
+			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 =
+				DDLCLIENT_STATE_IS(ddl,
+				DDL_CLIENT_WAIT_FOR_EOS_DONE) ? 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);
+
+			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 {
+				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;
+				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 =
+					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);
+	if (!ddl || (!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);
+		ddl_handle_enc_frame_done(ddl);
+		DDL_MSG_LOW("encoder_eos_done");
+		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("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_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_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;
+
+	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);
+		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_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);
+		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);
+		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)
+{
+	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 =
+		DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)
+			? 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);
+
+}
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..3f54756
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
@@ -0,0 +1,505 @@
+/* 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 "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;
+}
+
+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;
+	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..b3656cd
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -0,0 +1,1904 @@
+/* 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"
+
+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);
+			}
+			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->physical_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;
+	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;
+
+		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));
+			vcd_status = VCD_S_SUCCESS;
+		}
+	}
+	break;
+	case VCD_I_RECON_BUFFERS:
+	{
+		int index;
+		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)
+				break;
+			else
+				continue;
+			}
+		if (property_hdr->sz == sizeof(struct
+			vcd_property_enc_recon_buffer)) {
+			encoder->hw_bufs.dpb_y[index].align_physical_addr =
+				recon_buffers->physical_addr;
+			encoder->hw_bufs.dpb_y[index].align_virtual_addr =
+				recon_buffers->kernel_virtual_addr;
+			encoder->hw_bufs.dpb_y[index].buffer_size =
+				recon_buffers->buffer_size;
+			encoder->hw_bufs.dpb_c[index].align_physical_addr =
+			recon_buffers->physical_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].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].align_virtual_addr,
+			encoder->hw_bufs.dpb_y[index].align_physical_addr,
+			encoder->hw_bufs.dpb_c[index].align_virtual_addr,
+			encoder->hw_bufs.dpb_c[index].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_ERROR("Meta Data Interface is Requested");
+		vcd_status = ddl_set_metadata_params(ddl, property_hdr,
+			property_value);
+		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;
+	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;
+				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;
+	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;
+	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;
+	ddl_set_default_metadata_flag(ddl);
+	ddl_set_default_encoder_buffer_req(encoder);
+}
+
+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;
+}
+
+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;
+	min_dpb = ddl_decoder_min_num_dpb(decoder);
+	if (estimate) {
+		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 {
+		if (min_dpb >= decoder->min_dpb_num ||
+			decoder->idr_only_decoding) {
+			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;
+		} else {
+			u32 max_dpb_size;
+
+			max_dpb_size = DDL_NO_OF_MB(
+				decoder->client_frame_size.stride,
+				decoder->client_frame_size.scan_lines);
+			max_dpb_size *= (decoder->min_dpb_num - 2);
+			DDL_MSG_ERROR("Error: H264MaxDpbSizeExceeded: %d > %d",
+				max_dpb_size, MAX_DPB_SIZE_L4PT0_MBS);
+			return false;
+		}
+	}
+	memset(output_buf_req, 0,
+		sizeof(struct vcd_buffer_requirement));
+	if ((!estimate && !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);
+	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");
+	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);
+	}
+}
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..70e1de1
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -0,0 +1,678 @@
+/* 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_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_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_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_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 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 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);
+	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);
+
+}
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..99d9651
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -0,0 +1,157 @@
+/* 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 _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)
+
+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;
+};
+
+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);
+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);
+#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..46337af
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -0,0 +1,310 @@
+/* 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 <linux/memory_alloc.h>
+#include "vcd_ddl_utils.h"
+#include "vcd_ddl.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)
+
+#define DDL_FW_CHANGE_ENDIAN
+
+#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;
+	struct ddl_context *ddl_context;
+	DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
+	if (!addr) {
+		DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__);
+		return NULL;
+	}
+	ddl_context = ddl_get_context();
+	alloc_size = (sz + alignment);
+	addr->physical_base_addr = (u8 *) allocate_contiguous_memory_nomap(
+				alloc_size, ddl_context->memtype, SZ_4K);
+	if (!addr->physical_base_addr) {
+		DDL_MSG_ERROR("%s() : pmem alloc failed (%d)\n", __func__,
+			alloc_size);
+		return NULL;
+	}
+	DDL_MSG_LOW("%s() : pmem alloc physical base addr/sz 0x%x / %d\n",\
+		__func__, (u32)addr->physical_base_addr, alloc_size);
+	addr->virtual_base_addr = (u8 *)ioremap((unsigned long)
+		addr->physical_base_addr, alloc_size);
+	if (!addr->virtual_base_addr) {
+		DDL_MSG_ERROR("%s() : ioremap failed, virtual(%x)\n", __func__,
+			(u32)addr->virtual_base_addr);
+		free_contiguous_memory_by_paddr(
+			(unsigned long) addr->physical_base_addr);
+		addr->physical_base_addr = NULL;
+		return NULL;
+	}
+	DDL_MSG_LOW("%s() : pmem alloc virtual base addr/sz 0x%x / %d\n",\
+		__func__, (u32)addr->virtual_base_addr, alloc_size);
+	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;
+	DDL_MSG_LOW("\n%s() : alig_phy_addr(%p) alig_vir_addr(%p)",
+		__func__, addr->align_physical_addr, addr->align_virtual_addr);
+	DBG_PMEM("\n%s() OUT: phy_addr(%p) vir_addr(%p) size(%u)",
+		__func__, addr->physical_base_addr, addr->virtual_base_addr,
+		addr->buffer_size);
+	return addr->virtual_base_addr;
+}
+
+void ddl_pmem_free(struct ddl_buf_addr *addr)
+{
+	DBG_PMEM("\n%s() IN: phy_addr(%p) vir_addr(%p) size(%u)",
+		__func__, addr->physical_base_addr, addr->virtual_base_addr,
+		addr->buffer_size);
+	if (addr->virtual_base_addr)
+		iounmap((void *)addr->virtual_base_addr);
+	if (addr->physical_base_addr)
+		free_contiguous_memory_by_paddr(
+			(unsigned long) addr->physical_base_addr);
+	DBG_PMEM("\n%s() OUT: phy_addr(%p) vir_addr(%p) size(%u)",
+		__func__, addr->physical_base_addr, addr->virtual_base_addr,
+		addr->buffer_size);
+	addr->physical_base_addr   = NULL;
+	addr->virtual_base_addr    = NULL;
+	addr->align_virtual_addr   = NULL;
+	addr->align_physical_addr  = NULL;
+	addr->buffer_size = 0;
+}
+
+#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
+
+#ifdef DDL_FW_CHANGE_ENDIAN
+static void ddl_fw_change_endian(u8 *fw, u32 fw_size)
+{
+	u32 i = 0;
+	u8  temp;
+	for (i = 0; i < fw_size; i = i + 4) {
+		temp = fw[i];
+		fw[i] = fw[i+3];
+		fw[i+3] = temp;
+		temp = fw[i+1];
+		fw[i+1] = fw[i+2];
+		fw[i+2] = temp;
+	}
+	return;
+}
+#endif
+
+u32 ddl_fw_init(struct ddl_buf_addr *dram_base)
+{
+
+	u8 *dest_addr;
+
+	dest_addr = DDL_GET_ALIGNED_VITUAL(*dram_base);
+	if (vidc_video_codec_fw_size > dram_base->buffer_size ||
+		!vidc_video_codec_fw)
+		return false;
+	DDL_MSG_LOW("FW Addr / FW Size : %x/%d", (u32)vidc_video_codec_fw,
+		vidc_video_codec_fw_size);
+	memcpy(dest_addr, vidc_video_codec_fw,
+		vidc_video_codec_fw_size);
+#ifdef DDL_FW_CHANGE_ENDIAN
+	ddl_fw_change_endian(dest_addr, vidc_video_codec_fw_size);
+#endif
+	return true;
+}
+
+void ddl_fw_release(void)
+{
+
+}
+
+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_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..42a991c
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
@@ -0,0 +1,73 @@
+/* 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 _VCD_DDL_UTILS_H_
+#define _VCD_DDL_UTILS_H_
+
+#include <linux/delay.h>
+#include "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,
+	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)
+
+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);
+
+#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..2efd211
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -0,0 +1,925 @@
+/* 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
+
+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;
+	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;
+	ddl_context->vidc_decode_seq_start[ddl->command_channel](
+		&seq_start_param);
+}
+
+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_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);
+}
+
+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;
+
+	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;
+	vidc_sm_set_extended_encoder_control(&ddl->shared_mem
+		[ddl->command_channel], hdr_ext_control,
+		r_cframe_skip, false, 0);
+	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((
+			DDL_FRAMERATE_SCALE(encoder->\
+			frame_rate.fps_numerator) /
+			encoder->frame_rate.fps_denominator),
+			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_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;
+		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);
+}
+
+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;
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) {
+		DDL_MSG_ERROR("STATE-CRITICAL");
+		return VCD_ERR_FAIL;
+	}
+	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);
+	ddl_decoder_dpb_init(ddl);
+	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;
+	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;
+	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;
+	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);
+}
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..ae918f0
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c
@@ -0,0 +1,1007 @@
+/* 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 "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_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_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_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);
+}
+
+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);
+}
+
+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_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_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->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->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)
+{
+	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_889944, param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_404623, param->dpb_count);
+	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)
+{
+	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_652528,  param->shared_mem_addr_offset);
+	VIDC_HWIO_OUT(REG_220637, param->dpb_count);
+	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)
+{
+	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);
+	VIDC_HWIO_OUT(REG_404623, param->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)
+{
+
+	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);
+	VIDC_HWIO_OUT(REG_404623, param->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..f871509
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h
@@ -0,0 +1,544 @@
+/* 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 _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_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_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_INCOMPLETE_FRAME                       124
+#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_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_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
+
+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_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_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;
+	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;
+};
+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;
+	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_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 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_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..f63ebcd
--- /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) (*((u32 *) (port)))
+#define __outpdw(port, val) (*((u32 *) (port)) = ((u32) (val)))
+
+#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 100644
index 0000000..ec6c39a
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -0,0 +1,508 @@
+/* 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 <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_reqs.h>
+#include <mach/msm_memtypes.h>
+#include <linux/interrupt.h>
+#include <linux/memory_alloc.h>
+#include <asm/sizes.h>
+#include "vidc.h"
+#include "vcd_res_tracker.h"
+#include "vidc_init.h"
+
+static unsigned int vidc_clk_table[3] = {
+	48000000, 133330000, 200000000
+};
+static struct res_trk_context resource_context;
+
+#define VIDC_FW	"vidc_1080p.fw"
+#define VIDC_FW_SIZE SZ_1M
+
+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 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,
+		"vcodec_clk");
+	if (IS_ERR(resource_context.vcodec_clk)) {
+		VCDRES_MSG_ERROR("%s(): vcodec_clk get failed\n",
+						__func__);
+		goto bail_out;
+	}
+	 resource_context.vcodec_pclk = clk_get(resource_context.device,
+			"vcodec_pclk");
+	if (IS_ERR(resource_context.vcodec_pclk)) {
+		VCDRES_MSG_ERROR("%s(): vcodec_pclk get failed\n",
+						__func__);
+		goto release_vcodec_clk;
+	}
+	resource_context.vcodec_axi_a_clk = clk_get(resource_context.device,
+			"vcodec_axi_a_clk");
+	if (IS_ERR(resource_context.vcodec_axi_a_clk)) {
+		VCDRES_MSG_ERROR("%s(): vcodec_axi_a_clk get failed\n",
+						__func__);
+		resource_context.vcodec_axi_a_clk = NULL;
+	}
+	resource_context.vcodec_axi_b_clk = clk_get(resource_context.device,
+			"vcodec_axi_b_clk");
+	if (IS_ERR(resource_context.vcodec_axi_b_clk)) {
+		VCDRES_MSG_ERROR("%s(): vcodec_axi_b_clk get failed\n",
+						__func__);
+		resource_context.vcodec_axi_b_clk = NULL;
+	}
+	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:
+	if (resource_context.vcodec_axi_a_clk)
+		clk_put(resource_context.vcodec_axi_a_clk);
+	if (resource_context.vcodec_axi_b_clk)
+		clk_put(resource_context.vcodec_axi_b_clk);
+	clk_put(resource_context.vcodec_pclk);
+	resource_context.vcodec_pclk = NULL;
+	resource_context.vcodec_axi_a_clk = NULL;
+	resource_context.vcodec_axi_b_clk = 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);
+	if (resource_context.vcodec_axi_a_clk)
+		clk_put(resource_context.vcodec_axi_a_clk);
+	if (resource_context.vcodec_axi_b_clk)
+		clk_put(resource_context.vcodec_axi_b_clk);
+	resource_context.vcodec_axi_b_clk = NULL;
+	resource_context.vcodec_axi_a_clk = NULL;
+	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;
+			}
+			if (resource_context.vcodec_axi_a_clk &&
+				resource_context.vcodec_axi_b_clk) {
+				if (clk_enable(resource_context.
+					vcodec_axi_a_clk))
+					VCDRES_MSG_ERROR("a_clk Enable fail\n");
+				if (clk_enable(resource_context.
+					vcodec_axi_b_clk))
+					VCDRES_MSG_ERROR("b_clk Enable fail\n");
+			}
+
+			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;
+}
+
+static 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);
+		if (resource_context.vcodec_axi_a_clk)
+			clk_disable(resource_context.vcodec_axi_a_clk);
+		if (resource_context.vcodec_axi_b_clk)
+			clk_disable(resource_context.vcodec_axi_b_clk);
+		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;
+}
+
+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");
+#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
+		bus_clk_index = 2;
+
+	if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0)
+		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);
+#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 {
+		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);
+		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;
+#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.core_type = VCD_CORE_1080P;
+		if (resource_context.memtype == MEMTYPE_EBI1) {
+			resource_context.device_addr =
+			(phys_addr_t)
+			allocate_contiguous_memory_nomap(VIDC_FW_SIZE,
+					resource_context.memtype, SZ_4K);
+			if (resource_context.device_addr) {
+				resource_context.base_addr = (u8 *)
+				ioremap((unsigned long)
+				resource_context.device_addr, VIDC_FW_SIZE);
+				if (!resource_context.base_addr) {
+					free_contiguous_memory_by_paddr(
+					(unsigned long)
+					resource_context.device_addr);
+					resource_context.device_addr =
+						(phys_addr_t)NULL;
+				}
+			}
+		}
+	}
+}
+
+u32 res_trk_get_core_type(void){
+	return resource_context.core_type;
+}
+
+u32 res_trk_get_firmware_addr(struct res_trk_firmware_addr *firm_addr)
+{
+	int status = -1;
+	if (firm_addr && resource_context.base_addr &&
+		resource_context.device_addr) {
+		firm_addr->base_addr = resource_context.base_addr;
+		firm_addr->device_addr = resource_context.device_addr;
+		firm_addr->buf_size = VIDC_FW_SIZE;
+		status = 0;
+	}
+	return status;
+}
+
+u32 res_trk_get_mem_type(void){
+	return resource_context.memtype;
+}
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..16680ad
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
@@ -0,0 +1,69 @@
+/* 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 _VIDEO_720P_RESOURCE_TRACKER_H_
+#define _VIDEO_720P_RESOURCE_TRACKER_H_
+
+#include <linux/regulator/consumer.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
+struct res_trk_context {
+	struct device *device;
+	u32 irq_num;
+	struct mutex lock;
+	struct clk *vcodec_clk;
+	struct clk *vcodec_pclk;
+	struct clk *vcodec_axi_a_clk;
+	struct clk *vcodec_axi_b_clk;
+	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;
+#ifdef CONFIG_MSM_BUS_SCALING
+	struct msm_bus_scale_pdata *vidc_bus_client_pdata;
+	uint32_t     pcl;
+#endif
+	u32 core_type;
+	u8 *base_addr;
+	phys_addr_t device_addr;
+};
+
+#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..95cddd9
--- /dev/null
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
@@ -0,0 +1,37 @@
+/* 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 _VIDEO_720P_RESOURCE_TRACKER_API_H_
+#define _VIDEO_720P_RESOURCE_TRACKER_API_H_
+
+#include "vcd_core.h"
+
+struct res_trk_firmware_addr {
+	u8 *base_addr;
+	phys_addr_t device_addr;
+	u32 buf_size;
+};
+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 res_trk_firmware_addr *firm_addr);
+u32 res_trk_get_mem_type(void);
+
+#endif
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
new file mode 100644
index 0000000..d27b354
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c
@@ -0,0 +1,629 @@
+/* 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 "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)
+{
+	struct ddl_context *ddl_context;
+	u32 status = VCD_S_SUCCESS;
+
+	if ((!ddl_init_config) ||
+	    (!ddl_init_config->ddl_callback) ||
+	    (!ddl_init_config->core_virtual_base_addr)
+	    ) {
+		VIDC_LOGERR_STRING("ddl_dev_init:Bad_argument");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	ddl_context = ddl_get_context();
+
+	if (DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dev_init:Multiple_init");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dev_init:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+
+	DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context));
+
+	DDL_BUSY(ddl_context);
+	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 =
+	    ddl_init_config->core_virtual_base_addr;
+	ddl_context->client_data = client_data;
+
+	vidc_720p_set_device_virtual_base(ddl_context->
+					   core_virtual_base_addr);
+
+	ddl_context->current_ddl = NULL;
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+
+	ddl_client_transact(DDL_INIT_CLIENTS, NULL);
+
+	ddl_pmem_alloc(&ddl_context->context_buf_addr,
+		       DDL_CONTEXT_MEMORY, DDL_LINEAR_BUFFER_ALIGN_BYTES);
+	if (!ddl_context->context_buf_addr.virtual_base_addr) {
+		VIDC_LOGERR_STRING("ddl_dev_init:Context_alloc_fail");
+		status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (!status) {
+		ddl_pmem_alloc(&ddl_context->db_line_buffer,
+			       DDL_DB_LINE_BUF_SIZE,
+			       DDL_TILE_BUFFER_ALIGN_BYTES);
+		if (!ddl_context->db_line_buffer.virtual_base_addr) {
+			VIDC_LOGERR_STRING("ddl_dev_init:Line_buf_alloc_fail");
+			status = VCD_ERR_ALLOC_FAIL;
+		}
+	}
+
+	if (!status) {
+		ddl_pmem_alloc(&ddl_context->data_partition_tempbuf,
+					   DDL_MPEG4_DATA_PARTITION_BUF_SIZE,
+					   DDL_TILE_BUFFER_ALIGN_BYTES);
+		if (ddl_context->data_partition_tempbuf.virtual_base_addr \
+			== NULL) {
+			VIDC_LOGERR_STRING
+				("ddl_dev_init:Data_partition_buf_alloc_fail");
+			status = VCD_ERR_ALLOC_FAIL;
+		}
+   }
+
+   if (!status) {
+
+		ddl_pmem_alloc(&ddl_context->metadata_shared_input,
+					   DDL_METADATA_TOTAL_INPUTBUFSIZE,
+					   DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		if (!ddl_context->metadata_shared_input.virtual_base_addr) {
+			VIDC_LOGERR_STRING
+			("ddl_dev_init:metadata_shared_input_alloc_fail");
+			status = VCD_ERR_ALLOC_FAIL;
+		}
+	 }
+
+	if (!status) {
+		ddl_pmem_alloc(&ddl_context->dbg_core_dump, \
+					   DDL_DBG_CORE_DUMP_SIZE,  \
+					   DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		if (!ddl_context->dbg_core_dump.virtual_base_addr) {
+			VIDC_LOGERR_STRING
+				("ddl_dev_init:dbg_core_dump_alloc_failed");
+			status = VCD_ERR_ALLOC_FAIL;
+		}
+		ddl_context->enable_dbg_core_dump = 0;
+	}
+
+	if (!status && !vcd_fw_init()) {
+		VIDC_LOGERR_STRING("ddl_dev_init:fw_init_failed");
+		status = VCD_ERR_ALLOC_FAIL;
+	}
+	if (status) {
+		ddl_release_context_buffers(ddl_context);
+		DDL_IDLE(ddl_context);
+		return status;
+	}
+
+	ddl_move_command_state(ddl_context, DDL_CMD_DMA_INIT);
+
+	ddl_core_init(ddl_context);
+
+	return status;
+}
+
+u32 ddl_device_release(void *client_data)
+{
+	struct ddl_context *ddl_context;
+
+	ddl_context = ddl_get_context();
+
+	if (DDL_IS_BUSY(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dev_rel:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dev_rel:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if (!ddl_client_transact(DDL_ACTIVE_CLIENT, NULL)) {
+		VIDC_LOGERR_STRING("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_move_command_state(ddl_context, DDL_CMD_INVALID);
+	vidc_720p_stop_fw();
+
+	VIDC_LOG_STRING("FW_ENDDONE");
+	ddl_release_context_buffers(ddl_context);
+
+	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;
+	u32 status;
+
+	if (!ddl_handle) {
+		VIDC_LOGERR_STRING("ddl_open:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	ddl_context = ddl_get_context();
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_open:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	status = ddl_client_transact(DDL_GET_CLIENT, &ddl);
+
+	if (status) {
+		VIDC_LOGERR_STRING("ddl_open:Client_trasac_failed");
+		return status;
+	}
+
+	ddl_move_client_state(ddl, 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;
+	return VCD_S_SUCCESS;
+}
+
+u32 ddl_close(u32 **ddl_handle)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_client_context **ddl =
+	    (struct ddl_client_context **)ddl_handle;
+
+	if (!ddl || !*ddl) {
+		VIDC_LOGERR_STRING("ddl_close:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	ddl_context = ddl_get_context();
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_close:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if (!DDLCLIENT_STATE_IS(*ddl, DDL_CLIENT_OPEN)) {
+		VIDC_LOGERR_STRING("ddl_close:Not_in_open_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	ddl_move_client_state(*ddl, DDL_CLIENT_INVALID);
+	if ((*ddl)->decoding) {
+		vcd_fw_transact(false, true,
+			(*ddl)->codec_data.decoder.codec.codec);
+	} else {
+		vcd_fw_transact(false, false,
+			(*ddl)->codec_data.encoder.codec.codec);
+	}
+	ddl_client_transact(DDL_FREE_CLIENT, 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;
+	u32 dpb_size;
+
+	ddl_context = ddl_get_context();
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_enc_start:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_enc_start:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || ddl->decoding) {
+		VIDC_LOGERR_STRING("ddl_enc_start:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+		VIDC_LOGERR_STRING("ddl_enc_start:Not_opened");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if (!ddl_encoder_ready_to_start(ddl)) {
+		VIDC_LOGERR_STRING("ddl_enc_start:Err_param_settings");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	encoder = &ddl->codec_data.encoder;
+
+	dpb_size = ddl_get_yuv_buffer_size(&encoder->frame_size,
+					&encoder->re_con_buf_format, false,
+					encoder->codec.codec);
+
+	dpb_size *= DDL_ENC_NUM_DPB_BUFFERS;
+	ddl_pmem_alloc(&encoder->enc_dpb_addr,
+		       dpb_size, DDL_TILE_BUFFER_ALIGN_BYTES);
+	if (!encoder->enc_dpb_addr.virtual_base_addr) {
+		VIDC_LOGERR_STRING("ddl_enc_start:Dpb_alloc_failed");
+		return VCD_ERR_ALLOC_FAIL;
+	}
+
+	if ((encoder->codec.codec == VCD_CODEC_MPEG4 &&
+	     !encoder->short_header.short_header) ||
+	    encoder->codec.codec == VCD_CODEC_H264) {
+		ddl_pmem_alloc(&encoder->seq_header,
+			       DDL_ENC_SEQHEADER_SIZE,
+			       DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		if (!encoder->seq_header.virtual_base_addr) {
+			ddl_pmem_free(&encoder->enc_dpb_addr);
+			VIDC_LOGERR_STRING
+			    ("ddl_enc_start:Seq_hdr_alloc_failed");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+	} else {
+		encoder->seq_header.buffer_size = 0;
+		encoder->seq_header.virtual_base_addr = 0;
+	}
+
+	DDL_BUSY(ddl_context);
+
+	ddl_context->current_ddl = ddl;
+	ddl_context->client_data = client_data;
+	ddl_channel_set(ddl);
+	return VCD_S_SUCCESS;
+}
+
+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;
+
+	ddl_context = ddl_get_context();
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dec_start:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dec_start:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || !ddl->decoding) {
+		VIDC_LOGERR_STRING("ddl_dec_start:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+		VIDC_LOGERR_STRING("ddl_dec_start:Not_in_opened_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if ((header) &&
+	    ((!header->sequence_header_len) ||
+	     (!header->sequence_header)
+	    )
+	    ) {
+		VIDC_LOGERR_STRING("ddl_dec_start:Bad_param_seq_header");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	if (!ddl_decoder_ready_to_start(ddl, header)) {
+		VIDC_LOGERR_STRING("ddl_dec_start:Err_param_settings");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	DDL_BUSY(ddl_context);
+
+	decoder = &ddl->codec_data.decoder;
+	if (header) {
+		decoder->header_in_start = true;
+		decoder->decode_config = *header;
+	} else {
+		decoder->header_in_start = false;
+		decoder->decode_config.sequence_header_len = 0;
+	}
+
+	if (decoder->codec.codec == VCD_CODEC_H264) {
+		ddl_pmem_alloc(&decoder->h264Vsp_temp_buffer,
+			       DDL_DECODE_H264_VSPTEMP_BUFSIZE,
+			       DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		if (!decoder->h264Vsp_temp_buffer.virtual_base_addr) {
+			DDL_IDLE(ddl_context);
+			VIDC_LOGERR_STRING
+			    ("ddl_dec_start:H264Sps_alloc_failed");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+	}
+
+	ddl_context->current_ddl = ddl;
+	ddl_context->client_data = client_data;
+
+	ddl_channel_set(ddl);
+	return VCD_S_SUCCESS;
+}
+
+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 = ddl_get_context();
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dec_frame:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dec_frame:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || !ddl->decoding) {
+		VIDC_LOGERR_STRING("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))
+	    )
+	    ) {
+		VIDC_LOGERR_STRING("ddl_dec_frame:Bad_input_param");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	DDL_BUSY(ddl_context);
+
+	ddl_context->current_ddl = ddl;
+	ddl_context->client_data = client_data;
+
+	ddl->input_frame = *input_bits;
+
+	if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) {
+		ddl_decode_frame_run(ddl);
+	} else {
+		if (!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) {
+			VIDC_LOGERR_STRING("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_decode_set_buffers(ddl);
+		} else
+		    if (DDLCLIENT_STATE_IS
+			(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC)) {
+			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_decode_init_codec(ddl);
+		} else {
+			VIDC_LOGERR_STRING("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 = ddl_get_context();
+
+	if (vidc_msg_timing)
+		ddl_set_core_start_time(__func__, ENC_OP_TIME);
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_enc_frame:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_enc_frame:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || ddl->decoding) {
+		VIDC_LOGERR_STRING("ddl_enc_frame:Bad_handle");
+		return VCD_ERR_BAD_HANDLE;
+	}
+	if (!input_frame ||
+	    !input_frame->vcd_frm.physical ||
+	    ddl->codec_data.encoder.input_buf_req.sz !=
+	    input_frame->vcd_frm.data_len) {
+		VIDC_LOGERR_STRING("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)
+	    )
+	    ) {
+		VIDC_LOGERR_STRING
+		    ("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) {
+		VIDC_LOGERR_STRING("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) {
+		VIDC_LOGERR_STRING
+		    ("ddl_enc_frame:offset_large, Exceeds_min_buf_size");
+	}
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) {
+		VIDC_LOGERR_STRING("ddl_enc_frame:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	DDL_BUSY(ddl_context);
+
+	ddl_context->current_ddl = ddl;
+	ddl_context->client_data = client_data;
+
+	ddl->input_frame = *input_frame;
+	ddl->output_frame = *output_bit;
+
+	ddl_encode_frame_run(ddl);
+	return VCD_S_SUCCESS;
+}
+
+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_context = ddl_get_context();
+
+	if (vidc_msg_timing) {
+		ddl_reset_core_time_variables(DEC_OP_TIME);
+		ddl_reset_core_time_variables(DEC_IP_TIME);
+	}
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dec_end:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_dec_end:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || !ddl->decoding) {
+		VIDC_LOGERR_STRING("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_FATAL_ERROR)
+	    ) {
+		VIDC_LOGERR_STRING("ddl_dec_end:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	DDL_BUSY(ddl_context);
+
+	ddl_context->current_ddl = ddl;
+	ddl_context->client_data = client_data;
+
+	ddl_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_context = ddl_get_context();
+
+	if (vidc_msg_timing)
+		ddl_reset_core_time_variables(ENC_OP_TIME);
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_enc_end:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_enc_end:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || ddl->decoding) {
+		VIDC_LOGERR_STRING("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_FATAL_ERROR)) {
+		VIDC_LOGERR_STRING("ddl_enc_end:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	DDL_BUSY(ddl_context);
+
+	ddl_context->current_ddl = ddl;
+	ddl_context->client_data = client_data;
+
+	ddl_channel_end(ddl);
+	return VCD_S_SUCCESS;
+}
+
+u32 ddl_reset_hw(u32 mode)
+{
+	struct ddl_context *ddl_context;
+	struct ddl_client_context *ddl;
+	int i_client_num;
+
+	VIDC_LOG_STRING("ddl_reset_hw:called");
+	ddl_context = ddl_get_context();
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	DDL_BUSY(ddl_context);
+
+	if (ddl_context->core_virtual_base_addr)
+		vidc_720p_do_sw_reset();
+
+	ddl_context->device_state = DDL_DEVICE_NOTINIT;
+	for (i_client_num = 0; i_client_num < VCD_MAX_NO_CLIENT;
+			++i_client_num) {
+		ddl = ddl_context->ddl_clients[i_client_num];
+		ddl_context->ddl_clients[i_client_num] = NULL;
+		if (ddl) {
+			ddl_release_client_internal_buffers(ddl);
+			ddl_client_transact(DDL_FREE_CLIENT, &ddl);
+		}
+	}
+
+	ddl_release_context_buffers(ddl_context);
+	DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context));
+
+	return true;
+}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
new file mode 100644
index 0000000..157b556
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
@@ -0,0 +1,282 @@
+/* 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_H_
+#define _VCD_DDL_H_
+#include "vcd_ddl_api.h"
+#include "vcd_ddl_utils.h"
+#include "vcd_ddl_firmware.h"
+#include "vidc.h"
+
+#undef DDL_INLINE
+#define DDL_INLINE
+
+#define DDL_BUSY_STATE 1
+#define DDL_IDLE_STATE 0
+#define DDL_ERROR_STATE 2
+#define DDL_IS_BUSY(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_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, current_state) \
+(current_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_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
+
+struct ddl_buf_addr {
+	u32 *physical_base_addr;
+	u32 *virtual_base_addr;
+	u32 *align_physical_addr;
+	u32 *align_virtual_addr;
+	u32 buffer_size;
+};
+
+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_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_32BIT = 0x7FFFFFFF
+};
+
+struct ddl_mask {
+	u32 client_mask;
+	u32 hw_mask;
+};
+
+struct ddl_context;
+
+struct ddl_client_context;
+
+struct ddl_codec_data_hdr {
+	u32 decoding;
+};
+
+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;
+	u32 meta_data_enable_flag;
+	u32 suffix;
+	struct ddl_buf_addr meta_data_input;
+	u32 meta_data_offset;
+	struct vcd_property_short_header short_header;
+	struct vcd_property_vop_timing vop_timing;
+	u32 hdr_ext_control;
+	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;
+	u32 r_cframe_skip;
+	u32 vb_vbuffer_size;
+	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 re_con_buf_format;
+	u32 dynamic_prop_change;
+	u32 dynmic_prop_change_req;
+	u32 ext_enc_control_val;
+	struct vidc_720p_enc_frame_info enc_frame_info;
+	struct ddl_buf_addr enc_dpb_addr;
+	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_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;
+	u32 progressive_only;
+	u32 output_order;
+	u32 meta_data_enable_flag;
+	u32 suffix;
+	struct ddl_buf_addr meta_data_input;
+	struct ddl_buf_addr ref_buffer;
+	u32 meta_data_offset;
+	struct vcd_property_post_filter post_filter;
+	struct vcd_sequence_hdr decode_config;
+	u32 header_in_start;
+	u32 min_dpb_num;
+	u32 y_cb_cr_size;
+	struct ddl_property_dec_pic_buffers dp_buf;
+	struct ddl_mask dpb_mask;
+	u32 dynamic_prop_change;
+	u32 dynmic_prop_change_req;
+	struct vidc_720p_dec_disp_info dec_disp_info;
+	struct ddl_buf_addr dpb_comv_buffer;
+	struct ddl_buf_addr h264Vsp_temp_buffer;
+	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;
+};
+
+union ddl_codec_data {
+	struct ddl_codec_data_hdr hdr;
+	struct ddl_decoder_data decoder;
+	struct ddl_encoder_data encoder;
+};
+
+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);
+	void *client_data;
+	void (*interrupt_clr) (void);
+	enum ddl_cmd_state cmd_state;
+	struct ddl_client_context *current_ddl;
+	struct ddl_buf_addr context_buf_addr;
+	struct ddl_buf_addr db_line_buffer;
+	struct ddl_buf_addr data_partition_tempbuf;
+	struct ddl_buf_addr metadata_shared_input;
+	struct ddl_buf_addr dbg_core_dump;
+	u32 enable_dbg_core_dump;
+	struct ddl_client_context *ddl_clients[VCD_MAX_NO_CLIENT];
+	u32 device_state;
+	u32 ddl_busy;
+	u32  intr_status;
+	u32 cmd_err_status;
+	u32 disp_pic_err_status;
+	u32 op_failed;
+};
+
+struct ddl_client_context {
+	struct ddl_context *ddl_context;
+	enum ddl_client_state client_state;
+	u32 decoding;
+	u32 channel_id;
+	struct ddl_frame_data_tag input_frame;
+	struct ddl_frame_data_tag output_frame;
+	union ddl_codec_data codec_data;
+};
+
+DDL_INLINE struct ddl_context *ddl_get_context(void);
+DDL_INLINE void ddl_move_command_state(struct ddl_context *ddl_context,
+				       enum ddl_cmd_state command_state);
+DDL_INLINE void ddl_move_client_state(struct ddl_client_context *ddl,
+				      enum ddl_client_state client_state);
+void ddl_core_init(struct ddl_context *);
+void ddl_core_start_cpu(struct ddl_context *);
+void ddl_channel_set(struct ddl_client_context *);
+void ddl_channel_end(struct ddl_client_context *);
+void ddl_encode_init_codec(struct ddl_client_context *);
+void ddl_decode_init_codec(struct ddl_client_context *);
+void ddl_encode_frame_run(struct ddl_client_context *);
+void ddl_decode_frame_run(struct ddl_client_context *);
+void  ddl_decode_eos_run(struct ddl_client_context *);
+void ddl_release_context_buffers(struct ddl_context *);
+void ddl_release_client_internal_buffers(struct ddl_client_context *ddl);
+u32 ddl_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_client_transact(u32, struct ddl_client_context **);
+void 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 inter_lace,
+     enum vcd_codec codec);
+void ddl_calculate_stride(struct vcd_property_frame_size *frame_size,
+	u32 inter_lace, enum vcd_codec codec);
+void ddl_encode_dynamic_property(struct ddl_client_context *ddl,
+				 u32 enable);
+void ddl_decode_dynamic_property(struct ddl_client_context *ddl,
+				 u32 enable);
+void ddl_set_initial_default_values(struct ddl_client_context *ddl);
+u32 ddl_handle_core_errors(struct ddl_context *ddl_context);
+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);
+#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
new file mode 100644
index 0000000..53cc93e
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h
@@ -0,0 +1,53 @@
+/* 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_API_H_
+#define _VCD_DDL_API_H_
+#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,
+		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_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);
+void ddl_read_and_clear_interrupt(void);
+u32 ddl_process_core_response(void);
+u32 ddl_reset_hw(u32 mode);
+#endif
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
new file mode 100644
index 0000000..9fdb668
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h
@@ -0,0 +1,99 @@
+/* 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 _VCD_DDL_CORE_H_
+#define _VCD_DDL_CORE_H_
+
+#define DDL_LINEAR_BUF_ALIGN_MASK   0xFFFFFFF8U
+#define DDL_LINEAR_BUF_ALIGN_GUARD_BYTES 0x7
+#define DDL_LINEAR_BUFFER_ALIGN_BYTES  8
+
+#define DDL_TILE_BUF_ALIGN_MASK   0xFFFFE000U
+#define DDL_TILE_BUF_ALIGN_GUARD_BYTES 0x1FFF
+#define DDL_TILE_BUFFER_ALIGN_BYTES  8192
+
+#define DDL_MAX_FRAME_WIDTH   (1280)
+#define DDL_MAX_FRAME_HEIGHT  (720)
+
+#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
+#define VCD_FRAME_COMMAND_DEPTH 1
+#define VCD_GENERAL_COMMAND_DEPTH 1
+#define VCD_COMMAND_EXCLUSIVE true
+
+#define DDL_HW_TIMEOUT_IN_MS  1000
+
+#define DDL_STREAMBUF_ALIGN_GUARD_BYTES 0x7
+
+#define DDL_CONTEXT_MEMORY (1024 * 15 * (VCD_MAX_NO_CLIENT + 1))
+#define DDL_DB_LINE_BUF_SIZE \
+(((((DDL_MAX_FRAME_WIDTH * 4) - 1) / 256) + 1) * 8 * 1024)
+#define DDL_MPEG4_DATA_PARTITION_BUF_SIZE (64 * 1024)
+#define DDL_DECODE_H264_VSPTEMP_BUFSIZE 0x59c00
+#define DDL_ENC_NUM_DPB_BUFFERS 2
+
+#define DDL_DBG_CORE_DUMP_SIZE (10 * 1024)
+
+#define DDL_BUFEND_PAD    256
+#define DDL_ENC_SEQHEADER_SIZE (256+DDL_BUFEND_PAD)
+#define DDL_MAX_BUFFER_COUNT  32
+
+#define DDL_MPEG_REFBUF_COUNT  2
+
+#define DDL_MPEG_COMV_BUF_NO 2
+#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
+
+#define DDL_MAX_H264_QP   51
+#define DDL_MAX_MPEG4_QP  31
+
+#define DDL_PADDING_HACK(addr) \
+ (addr) = (u32)((((u32)(addr) + DDL_STREAMBUF_ALIGN_GUARD_BYTES) & \
+			 ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES)) + DDL_BUFEND_PAD)
+
+#define DDL_QCIF_MBS 99
+#define DDL_CIF_MBS  396
+#define DDL_QVGA_MBS 300
+#define DDL_VGA_MBS  1200
+#define DDL_WVGA_MBS 1500
+#define DDL_720P_MBS 3600
+
+#define DDL_FRAMESIZE_DIV_FACTOR   (0xF)
+
+#define DDL_NO_OF_MB(width, height) \
+	(((width + 15) >> 4) * ((height + 15) >> 4))
+
+#define DDL_ALLOW_ENC_FRAMESIZE(width, height) \
+((DDL_NO_OF_MB(width, height) <= DDL_720P_MBS) \
+ && (((width) <= DDL_MAX_FRAME_WIDTH) &&            \
+     ((height) <= DDL_MAX_FRAME_WIDTH))            \
+ && ((width) >= 32 && (height) >= 32))
+
+#define DDL_VALIDATE_ENC_FRAMESIZE(width, height) \
+	(!((width) & DDL_FRAMESIZE_DIV_FACTOR) &&     \
+     !((height) & DDL_FRAMESIZE_DIV_FACTOR))
+
+#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))
+
+#endif
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
new file mode 100644
index 0000000..1b62553
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c
@@ -0,0 +1,595 @@
+/* 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_type.h"
+#include "vcd_ddl_utils.h"
+#include "vcd_ddl.h"
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+#define ERR(x...) printk(KERN_ERR x)
+
+#define INVALID_CHANNEL_NUMBER  1
+#define INVALID_COMMAND_ID 2
+#define CHANNEL_ALREADY_IN_USE 3
+#define CHANNEL_NOT_SET_BEFORE_CHANNEL_CLOSE 4
+#define CHANNEL_SET_ERROR_INIT_CODEC 5
+#define INIT_CODEC_ALREADY_CALLED 6
+#define CHANNEL_SET_ERROR_INIT_BUFFERS 7
+#define INIT_CODEC_ERROR_INIT_BUFFERS 8
+#define INIT_BUFFER_ALREADY_CALLED  9
+#define CHANNEL_SET_ERROR_FRAME_RUN 10
+#define INIT_CODEC_ERROR_FRAME_RUN 11
+#define INIT_BUFFERS_ERROR_FRAME_RUN 12
+#define CODEC_LIMIT_EXCEEDED 13
+#define FIRMWARE_SIZE_ZERO 14
+#define FIRMWARE_ADDRESS_EXT_ZERO 15
+#define CONTEXT_DMA_IN_ERROR 16
+#define CONTEXT_DMA_OUT_ERROR 17
+#define PROGRAM_DMA_ERROR 18
+#define CONTEXT_STORE_EXT_ADD_ZERO 19
+#define MEM_ALLOCATION_FAILED 20
+
+
+#define UNSUPPORTED_FEATURE_IN_PROFILE 27
+#define RESOLUTION_NOT_SUPPORTED 28
+#define HEADER_NOT_FOUND 52
+#define MB_NUM_INVALID 61
+#define FRAME_RATE_NOT_SUPPORTED 62
+#define INVALID_QP_VALUE 63
+#define INVALID_RC_REACTION_COEFFICIENT 64
+#define INVALID_CPB_SIZE_AT_GIVEN_LEVEL 65
+
+#define ALLOC_DPB_SIZE_NOT_SUFFICIENT 71
+#define ALLOC_DB_SIZE_NOT_SUFFICIENT 72
+#define ALLOC_COMV_SIZE_NOT_SUFFICIENT 73
+#define NUM_BUF_OUT_OF_RANGE 74
+#define NULL_CONTEXT_POINTER 75
+#define NULL_COMAMND_CONTROL_COMM_POINTER 76
+#define NULL_METADATA_INPUT_POINTER 77
+#define NULL_DPB_POINTER 78
+#define NULL_DB_POINTER 79
+#define NULL_COMV_POINTER 80
+
+#define DIVIDE_BY_ZERO 81
+#define BIT_STREAM_BUF_EXHAUST 82
+#define DMA_NOT_STOPPED 83
+#define DMA_TX_NOT_COMPLETE 84
+
+#define MB_HEADER_NOT_DONE  85
+#define MB_COEFF_NOT_DONE 86
+#define CODEC_SLICE_NOT_DONE 87
+#define VME_NOT_READY 88
+#define VC1_BITPLANE_DECODE_ERR 89
+
+
+#define VSP_NOT_READY 90
+#define BUFFER_FULL_STATE 91
+
+#define RESOLUTION_MISMATCH 112
+#define NV_QUANT_ERR 113
+#define SYNC_MARKER_ERR 114
+#define FEATURE_NOT_SUPPORTED 115
+#define MEM_CORRUPTION  116
+#define INVALID_REFERENCE_FRAME  117
+#define PICTURE_CODING_TYPE_ERR  118
+#define MV_RANGE_ERR  119
+#define PICTURE_STRUCTURE_ERR 120
+#define SLICE_ADDR_INVALID  121
+#define NON_PAIRED_FIELD_NOT_SUPPORTED  122
+#define NON_FRAME_DATA_RECEIVED 123
+#define INCOMPLETE_FRAME  124
+#define NO_BUFFER_RELEASED_FROM_HOST  125
+#define PICTURE_MANAGEMENT_ERROR  128
+#define INVALID_MMCO  129
+#define INVALID_PIC_REORDERING 130
+#define INVALID_POC_TYPE 131
+#define ACTIVE_SPS_NOT_PRESENT 132
+#define ACTIVE_PPS_NOT_PRESENT 133
+#define INVALID_SPS_ID 134
+#define INVALID_PPS_ID 135
+
+
+#define METADATA_NO_SPACE_QP 151
+#define METADATA_NO_SAPCE_CONCEAL_MB 152
+#define METADATA_NO_SPACE_VC1_PARAM 153
+#define METADATA_NO_SPACE_SEI 154
+#define METADATA_NO_SPACE_VUI 155
+#define METADATA_NO_SPACE_EXTRA 156
+#define METADATA_NO_SPACE_DATA_NONE 157
+#define FRAME_RATE_UNKNOWN 158
+#define ASPECT_RATIO_UNKOWN 159
+#define COLOR_PRIMARIES_UNKNOWN 160
+#define TRANSFER_CHAR_UNKWON 161
+#define MATRIX_COEFF_UNKNOWN 162
+#define NON_SEQ_SLICE_ADDR 163
+#define BROKEN_LINK 164
+#define FRAME_CONCEALED 165
+#define PROFILE_UNKOWN 166
+#define LEVEL_UNKOWN 167
+#define BIT_RATE_NOT_SUPPORTED 168
+#define COLOR_DIFF_FORMAT_NOT_SUPPORTED 169
+#define NULL_EXTRA_METADATA_POINTER  170
+#define SYNC_POINT_NOT_RECEIVED_STARTED_DECODING  171
+#define NULL_FW_DEBUG_INFO_POINTER  172
+#define ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT  173
+#define MAX_STAGE_COUNTER_EXCEEDED 174
+
+#define METADATA_NO_SPACE_MB_INFO 180
+#define METADATA_NO_SPACE_SLICE_SIZE 181
+#define RESOLUTION_WARNING 182
+
+static void ddl_handle_npf_decoding_error(
+	struct ddl_context *ddl_context);
+
+static u32 ddl_handle_seqhdr_fail_error(
+	struct ddl_context *ddl_context);
+
+void ddl_hw_fatal_cb(struct ddl_context *ddl_context)
+{
+	/* Invalidate the command state */
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	ddl_context->device_state = DDL_DEVICE_HWFATAL;
+
+	/* callback to the client to indicate hw fatal error */
+	ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL,
+					VCD_ERR_HW_FATAL, NULL, 0,
+					(void *)ddl_context->current_ddl,
+					ddl_context->client_data);
+
+	DDL_IDLE(ddl_context);
+}
+
+static u32 ddl_handle_hw_fatal_errors(struct ddl_context
+			*ddl_context)
+{
+	u32 status = false;
+
+	switch (ddl_context->cmd_err_status) {
+
+	case INVALID_CHANNEL_NUMBER:
+	case INVALID_COMMAND_ID:
+	case CHANNEL_ALREADY_IN_USE:
+	case CHANNEL_NOT_SET_BEFORE_CHANNEL_CLOSE:
+	case CHANNEL_SET_ERROR_INIT_CODEC:
+	case INIT_CODEC_ALREADY_CALLED:
+	case CHANNEL_SET_ERROR_INIT_BUFFERS:
+	case INIT_CODEC_ERROR_INIT_BUFFERS:
+	case INIT_BUFFER_ALREADY_CALLED:
+	case CHANNEL_SET_ERROR_FRAME_RUN:
+	case INIT_CODEC_ERROR_FRAME_RUN:
+	case INIT_BUFFERS_ERROR_FRAME_RUN:
+	case CODEC_LIMIT_EXCEEDED:
+	case FIRMWARE_SIZE_ZERO:
+	case FIRMWARE_ADDRESS_EXT_ZERO:
+
+	case CONTEXT_DMA_IN_ERROR:
+	case CONTEXT_DMA_OUT_ERROR:
+	case PROGRAM_DMA_ERROR:
+	case CONTEXT_STORE_EXT_ADD_ZERO:
+	case MEM_ALLOCATION_FAILED:
+
+	case DIVIDE_BY_ZERO:
+	case DMA_NOT_STOPPED:
+	case DMA_TX_NOT_COMPLETE:
+
+	case VSP_NOT_READY:
+	case BUFFER_FULL_STATE:
+	case NULL_DB_POINTER:
+		ERR("HW FATAL ERROR");
+		ddl_hw_fatal_cb(ddl_context);
+		status = true;
+		break;
+	}
+	return status;
+}
+
+void ddl_client_fatal_cb(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context  *ddl =
+		ddl_context->current_ddl;
+
+	if (ddl_context->cmd_state == DDL_CMD_DECODE_FRAME)
+		ddl_decode_dynamic_property(ddl, false);
+	else if (ddl_context->cmd_state == DDL_CMD_ENCODE_FRAME)
+		ddl_encode_dynamic_property(ddl, false);
+
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+
+	ddl_move_client_state(ddl, DDL_CLIENT_FATAL_ERROR);
+
+	ddl_context->ddl_callback
+	(
+		VCD_EVT_IND_HWERRFATAL,
+		VCD_ERR_CLIENT_FATAL,
+		NULL,
+		0,
+		(void *)ddl,
+		ddl_context->client_data
+	);
+
+	DDL_IDLE(ddl_context);
+}
+
+static u32 ddl_handle_client_fatal_errors(struct ddl_context
+			*ddl_context)
+{
+	u32 status = false;
+
+	switch (ddl_context->cmd_err_status) {
+	case MB_NUM_INVALID:
+	case FRAME_RATE_NOT_SUPPORTED:
+	case INVALID_QP_VALUE:
+	case INVALID_RC_REACTION_COEFFICIENT:
+	case INVALID_CPB_SIZE_AT_GIVEN_LEVEL:
+
+	case ALLOC_DPB_SIZE_NOT_SUFFICIENT:
+	case ALLOC_DB_SIZE_NOT_SUFFICIENT:
+	case ALLOC_COMV_SIZE_NOT_SUFFICIENT:
+	case NUM_BUF_OUT_OF_RANGE:
+	case NULL_CONTEXT_POINTER:
+	case NULL_COMAMND_CONTROL_COMM_POINTER:
+	case NULL_METADATA_INPUT_POINTER:
+	case NULL_DPB_POINTER:
+	case NULL_COMV_POINTER:
+		{
+			status = true;
+			break;
+		}
+	}
+
+	if (!status)
+		ERR("UNKNOWN-OP-FAILED");
+
+	ddl_client_fatal_cb(ddl_context);
+
+	return true;
+}
+
+static void ddl_input_failed_cb(struct ddl_context *ddl_context,
+			u32 vcd_event, u32 vcd_status)
+{
+	struct ddl_client_context  *ddl = ddl_context->current_ddl;
+
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+
+	if (ddl->decoding)
+		ddl_decode_dynamic_property(ddl, false);
+	else
+		ddl_encode_dynamic_property(ddl, false);
+
+	ddl_context->ddl_callback(vcd_event,
+		vcd_status, &ddl->input_frame,
+		sizeof(struct ddl_frame_data_tag),
+		(void *)ddl, ddl_context->client_data);
+
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME);
+}
+
+static u32 ddl_handle_core_recoverable_errors(struct ddl_context \
+			*ddl_context)
+{
+	struct ddl_client_context  *ddl = ddl_context->current_ddl;
+	u32   vcd_status = VCD_S_SUCCESS;
+	u32   vcd_event = VCD_EVT_RESP_INPUT_DONE;
+	u32   eos = false, pending_display = 0, release_mask = 0;
+
+	if (ddl->decoding)
+		if (ddl_handle_seqhdr_fail_error(ddl_context))
+			return true;
+
+	if (ddl_context->cmd_state != DDL_CMD_DECODE_FRAME &&
+		ddl_context->cmd_state != DDL_CMD_ENCODE_FRAME) {
+		return false;
+	}
+	switch (ddl_context->cmd_err_status) {
+	case NON_PAIRED_FIELD_NOT_SUPPORTED:
+		{
+			ddl_handle_npf_decoding_error(ddl_context);
+			return true;
+		}
+	case NO_BUFFER_RELEASED_FROM_HOST:
+		{
+			/* lets check sanity of this error */
+			release_mask =
+				ddl->codec_data.decoder.dpb_mask.hw_mask;
+			while (release_mask > 0) {
+				if ((release_mask & 0x1))
+					pending_display += 1;
+				release_mask >>= 1;
+			}
+
+			if (pending_display >=
+				ddl->codec_data.decoder.min_dpb_num) {
+				DBG("FWISSUE-REQBUF!!");
+				/* callback to client for client fatal error */
+				ddl_client_fatal_cb(ddl_context);
+				return true ;
+			}
+		vcd_event = VCD_EVT_RESP_OUTPUT_REQ;
+		break;
+		}
+	case BIT_STREAM_BUF_EXHAUST:
+	case MB_HEADER_NOT_DONE:
+	case MB_COEFF_NOT_DONE:
+	case CODEC_SLICE_NOT_DONE:
+	case VME_NOT_READY:
+	case VC1_BITPLANE_DECODE_ERR:
+		{
+			u32 reset_core;
+			/* need to reset the internal core hw engine */
+			reset_core = ddl_hal_engine_reset(ddl_context);
+			if (!reset_core)
+				return true;
+			/* fall through to process bitstream error handling */
+		}
+	case RESOLUTION_MISMATCH:
+	case NV_QUANT_ERR:
+	case SYNC_MARKER_ERR:
+	case FEATURE_NOT_SUPPORTED:
+	case MEM_CORRUPTION:
+	case INVALID_REFERENCE_FRAME:
+	case PICTURE_CODING_TYPE_ERR:
+	case MV_RANGE_ERR:
+	case PICTURE_STRUCTURE_ERR:
+	case SLICE_ADDR_INVALID:
+	case NON_FRAME_DATA_RECEIVED:
+	case INCOMPLETE_FRAME:
+	case PICTURE_MANAGEMENT_ERROR:
+	case INVALID_MMCO:
+	case INVALID_PIC_REORDERING:
+	case INVALID_POC_TYPE:
+	case ACTIVE_SPS_NOT_PRESENT:
+	case ACTIVE_PPS_NOT_PRESENT:
+		{
+			vcd_status = VCD_ERR_BITSTREAM_ERR;
+			break;
+		}
+	}
+
+	if (!vcd_status && vcd_event == VCD_EVT_RESP_INPUT_DONE)
+		return false;
+
+	ddl->input_frame.frm_trans_end = true;
+
+	eos = ((vcd_event == VCD_EVT_RESP_INPUT_DONE) &&
+		((VCD_FRAME_FLAG_EOS & ddl->input_frame.
+				vcd_frm.flags)));
+
+	if ((ddl->decoding && eos) ||
+		(!ddl->decoding))
+		ddl->input_frame.frm_trans_end = false;
+
+	if (vcd_event == VCD_EVT_RESP_INPUT_DONE &&
+		ddl->decoding &&
+		!ddl->codec_data.decoder.header_in_start &&
+		!ddl->codec_data.decoder.dec_disp_info.img_size_x &&
+		!ddl->codec_data.decoder.dec_disp_info.img_size_y
+		) {
+		/* this is first frame seq. header only case */
+		vcd_status = VCD_S_SUCCESS;
+		ddl->input_frame.vcd_frm.flags |=
+			VCD_FRAME_FLAG_CODECCONFIG;
+		ddl->input_frame.frm_trans_end = !eos;
+		/* put just some non - zero value */
+		ddl->codec_data.decoder.dec_disp_info.img_size_x = 0xff;
+	}
+	/* inform client about input failed */
+	ddl_input_failed_cb(ddl_context, vcd_event, vcd_status);
+
+	/* for Encoder case, we need to send output done also */
+	if (!ddl->decoding) {
+		/* transaction is complete after this callback */
+		ddl->output_frame.frm_trans_end = !eos;
+		/* error case: NO data present */
+		ddl->output_frame.vcd_frm.data_len = 0;
+		/* call back to client for output frame done */
+		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+		VCD_ERR_FAIL, &(ddl->output_frame),
+			sizeof(struct ddl_frame_data_tag),
+			(void *)ddl, ddl_context->client_data);
+
+		if (eos) {
+			DBG("ENC-EOS_DONE");
+			/* send client EOS DONE callback */
+			ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE,
+				VCD_S_SUCCESS, NULL, 0, (void *)ddl,
+				ddl_context->client_data);
+		}
+	}
+
+	/* if it is decoder EOS case */
+	if (ddl->decoding && eos)
+		ddl_decode_eos_run(ddl);
+	else
+		DDL_IDLE(ddl_context);
+
+	return true;
+}
+
+static u32 ddl_handle_core_warnings(u32 err_status)
+{
+	u32 status = false;
+
+	switch (err_status) {
+	case FRAME_RATE_UNKNOWN:
+	case ASPECT_RATIO_UNKOWN:
+	case COLOR_PRIMARIES_UNKNOWN:
+	case TRANSFER_CHAR_UNKWON:
+	case MATRIX_COEFF_UNKNOWN:
+	case NON_SEQ_SLICE_ADDR:
+	case BROKEN_LINK:
+	case FRAME_CONCEALED:
+	case PROFILE_UNKOWN:
+	case LEVEL_UNKOWN:
+	case BIT_RATE_NOT_SUPPORTED:
+	case COLOR_DIFF_FORMAT_NOT_SUPPORTED:
+	case NULL_EXTRA_METADATA_POINTER:
+	case SYNC_POINT_NOT_RECEIVED_STARTED_DECODING:
+
+	case NULL_FW_DEBUG_INFO_POINTER:
+	case ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT:
+	case MAX_STAGE_COUNTER_EXCEEDED:
+
+	case METADATA_NO_SPACE_MB_INFO:
+	case METADATA_NO_SPACE_SLICE_SIZE:
+	case RESOLUTION_WARNING:
+
+	/* decoder warnings */
+	case METADATA_NO_SPACE_QP:
+	case METADATA_NO_SAPCE_CONCEAL_MB:
+	case METADATA_NO_SPACE_VC1_PARAM:
+	case METADATA_NO_SPACE_SEI:
+	case METADATA_NO_SPACE_VUI:
+	case METADATA_NO_SPACE_EXTRA:
+	case METADATA_NO_SPACE_DATA_NONE:
+		{
+			status = true;
+			DBG("CMD-WARNING-IGNORED!!");
+			break;
+		}
+	}
+	return status;
+}
+
+u32 ddl_handle_core_errors(struct ddl_context *ddl_context)
+{
+	u32 status = false;
+
+	if (!ddl_context->cmd_err_status &&
+		!ddl_context->disp_pic_err_status &&
+		!ddl_context->op_failed)
+		return false;
+
+	if (ddl_context->cmd_state == DDL_CMD_INVALID) {
+		DBG("SPURIOUS_INTERRUPT_ERROR");
+		return true;
+	}
+
+	if (!ddl_context->op_failed) {
+		u32 disp_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)
+			DBG("ddl_warning:Unknown");
+
+		return false;
+	}
+
+	ERR("\n %s(): OPFAILED!!", __func__);
+	ERR("\n CMD_ERROR_STATUS = %u, DISP_ERR_STATUS = %u",
+		ddl_context->cmd_err_status,
+		ddl_context->disp_pic_err_status);
+
+	status = ddl_handle_hw_fatal_errors(ddl_context);
+
+	if (!status)
+		status = ddl_handle_core_recoverable_errors(ddl_context);
+
+	if (!status)
+		status = ddl_handle_client_fatal_errors(ddl_context);
+
+	return status;
+}
+
+void ddl_handle_npf_decoding_error(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	if (!ddl->decoding) {
+		ERR("FWISSUE-ENC-NPF!!!");
+		ddl_client_fatal_cb(ddl_context);
+		return;
+	}
+	vidc_720p_decode_display_info(&decoder->dec_disp_info);
+	ddl_decode_dynamic_property(ddl, false);
+	ddl->output_frame.vcd_frm.ip_frm_tag =
+		decoder->dec_disp_info.tag_top;
+	ddl->output_frame.vcd_frm.physical = 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),
+		(void *)ddl,
+		ddl->ddl_context->client_data);
+	ddl_decode_frame_run(ddl);
+}
+
+u32 ddl_handle_seqhdr_fail_error(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	u32 status = false;
+	if (ddl_context->cmd_state == DDL_CMD_HEADER_PARSE &&
+		DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) {
+		switch (ddl_context->cmd_err_status) {
+		case UNSUPPORTED_FEATURE_IN_PROFILE:
+		case HEADER_NOT_FOUND:
+		case INVALID_SPS_ID:
+		case INVALID_PPS_ID:
+		case RESOLUTION_NOT_SUPPORTED:
+			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,
+					VCD_ERR_SEQHDR_PARSE_FAIL,
+					NULL, 0, (void *)ddl,
+					ddl_context->client_data);
+			} else {
+				if (ddl->input_frame.vcd_frm.flags &
+					VCD_FRAME_FLAG_EOS)
+					ddl->input_frame.frm_trans_end = false;
+				else
+					ddl->input_frame.frm_trans_end = true;
+				ddl_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),
+					(void *)ddl, ddl_context->client_data);
+				if (ddl->input_frame.vcd_frm.flags &
+					VCD_FRAME_FLAG_EOS)
+					ddl_context->ddl_callback(
+						VCD_EVT_RESP_EOS_DONE,
+						VCD_S_SUCCESS, NULL,
+						0, (void *)ddl,
+						ddl_context->client_data);
+			}
+			ddl_move_client_state(ddl,
+				DDL_CLIENT_WAIT_FOR_INITCODEC);
+			DDL_IDLE(ddl_context);
+			status = true;
+		}
+	}
+	return status;
+}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
new file mode 100644
index 0000000..25aa6bc
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c
@@ -0,0 +1,352 @@
+/* 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 "vidc_type.h"
+#include "vcd_ddl_firmware.h"
+#include "vcd_ddl_utils.h"
+
+#define VCDFW_TOTALNUM_IMAGE  7
+#define VCDFW_MAX_NO_IMAGE    2
+
+struct vcd_firmware {
+	u32 active_fw_img[VCDFW_TOTALNUM_IMAGE];
+	struct ddl_buf_addr boot_code;
+
+	struct ddl_buf_addr enc_mpeg4;
+	struct ddl_buf_addr encH264;
+
+	struct ddl_buf_addr dec_mpeg4;
+	struct ddl_buf_addr decH264;
+	struct ddl_buf_addr decH263;
+	struct ddl_buf_addr dec_mpeg2;
+	struct ddl_buf_addr dec_vc1;
+};
+
+static struct vcd_firmware vcd_firmware;
+
+
+static void vcd_fw_change_endian(unsigned char *fw, u32 fw_size)
+{
+	u32 i = 0;
+	unsigned char temp;
+	for (i = 0; i < fw_size; i = i + 4) {
+		temp = fw[i];
+		fw[i] = fw[i + 3];
+		fw[i + 3] = temp;
+
+		temp = fw[i + 1];
+		fw[i + 1] = fw[i + 2];
+		fw[i + 2] = temp;
+	}
+	return;
+}
+
+static u32 vcd_fw_prepare(struct ddl_buf_addr *fw_details,
+			 const unsigned char fw_array[],
+			 const unsigned int fw_array_size, u32 change_endian)
+{
+	u32 *buffer;
+
+	ddl_pmem_alloc(fw_details, fw_array_size,
+		       DDL_LINEAR_BUFFER_ALIGN_BYTES);
+	if (!fw_details->virtual_base_addr)
+		return false;
+
+	fw_details->buffer_size = fw_array_size / 4;
+
+	buffer = fw_details->align_virtual_addr;
+
+	memcpy(buffer, fw_array, fw_array_size);
+	if (change_endian)
+		vcd_fw_change_endian((unsigned char *)buffer, fw_array_size);
+	return true;
+}
+
+u32 vcd_fw_init(void)
+{
+	u32 status = false;
+
+	status = vcd_fw_prepare(&vcd_firmware.boot_code,
+				vidc_command_control_fw,
+				vidc_command_control_fw_size, false);
+
+	if (status) {
+		status = vcd_fw_prepare(&vcd_firmware.dec_mpeg4,
+					vidc_mpg4_dec_fw,
+					vidc_mpg4_dec_fw_size, true);
+	}
+
+	if (status) {
+		status = vcd_fw_prepare(&vcd_firmware.decH264,
+					vidc_h264_dec_fw,
+					vidc_h264_dec_fw_size, true);
+	}
+
+	if (status) {
+		status = vcd_fw_prepare(&vcd_firmware.decH263,
+					vidc_h263_dec_fw,
+					vidc_h263_dec_fw_size, true);
+	}
+
+	if (status) {
+		status = vcd_fw_prepare(&vcd_firmware.enc_mpeg4,
+					vidc_mpg4_enc_fw,
+					vidc_mpg4_enc_fw_size, true);
+	}
+
+	if (status) {
+		status = vcd_fw_prepare(&vcd_firmware.encH264,
+					vidc_h264_enc_fw,
+					vidc_h264_enc_fw_size, true);
+	}
+
+	if (status) {
+		status = vcd_fw_prepare(&vcd_firmware.dec_vc1,
+					vidc_vc1_dec_fw,
+					vidc_vc1_dec_fw_size, true);
+	}
+	return status;
+}
+
+
+static u32 get_dec_fw_image(struct vcd_fw_details *fw_details)
+{
+	u32 status = true;
+	switch (fw_details->codec) {
+	case VCD_CODEC_DIVX_4:
+	case VCD_CODEC_DIVX_5:
+	case VCD_CODEC_DIVX_6:
+	case VCD_CODEC_XVID:
+	case VCD_CODEC_MPEG4:
+		{
+			fw_details->fw_buffer_addr =
+			    vcd_firmware.dec_mpeg4.align_physical_addr;
+			fw_details->fw_size =
+			    vcd_firmware.dec_mpeg4.buffer_size;
+			break;
+		}
+	case VCD_CODEC_H264:
+		{
+			fw_details->fw_buffer_addr =
+			    vcd_firmware.decH264.align_physical_addr;
+			fw_details->fw_size =
+			    vcd_firmware.decH264.buffer_size;
+			break;
+		}
+	case VCD_CODEC_VC1:
+	case VCD_CODEC_VC1_RCV:
+		{
+			fw_details->fw_buffer_addr =
+			    vcd_firmware.dec_vc1.align_physical_addr;
+			fw_details->fw_size =
+			    vcd_firmware.dec_vc1.buffer_size;
+			break;
+		}
+	case VCD_CODEC_MPEG2:
+		{
+			fw_details->fw_buffer_addr =
+			    vcd_firmware.dec_mpeg2.align_physical_addr;
+			fw_details->fw_size =
+			    vcd_firmware.dec_mpeg2.buffer_size;
+			break;
+		}
+	case VCD_CODEC_H263:
+		{
+			fw_details->fw_buffer_addr =
+			    vcd_firmware.decH263.align_physical_addr;
+			fw_details->fw_size =
+			    vcd_firmware.decH263.buffer_size;
+			break;
+		}
+	default:
+		{
+			status = false;
+			break;
+		}
+	}
+	return status;
+}
+
+static u32 get_enc_fw_image(struct vcd_fw_details *fw_details)
+{
+	u32 status = true;
+	switch (fw_details->codec) {
+	case VCD_CODEC_H263:
+	case VCD_CODEC_MPEG4:
+		{
+			fw_details->fw_buffer_addr =
+			    vcd_firmware.enc_mpeg4.align_physical_addr;
+			fw_details->fw_size =
+			    vcd_firmware.enc_mpeg4.buffer_size;
+			break;
+		}
+	case VCD_CODEC_H264:
+		{
+			fw_details->fw_buffer_addr =
+			    vcd_firmware.encH264.align_physical_addr;
+			fw_details->fw_size =
+			    vcd_firmware.encH264.buffer_size;
+			break;
+		}
+	default:
+		{
+			status = false;
+			break;
+		}
+	}
+	return status;
+}
+
+u32 vcd_get_fw_property(u32 prop_id, void *prop_details)
+{
+	u32 status = true;
+	struct vcd_fw_details *fw_details;
+	switch (prop_id) {
+	case VCD_FW_ENDIAN:
+		{
+			*(u32 *) prop_details = VCD_FW_BIG_ENDIAN;
+			break;
+		}
+	case VCD_FW_BOOTCODE:
+		{
+			fw_details =
+			    (struct vcd_fw_details *)prop_details;
+			fw_details->fw_buffer_addr =
+			    vcd_firmware.boot_code.align_physical_addr;
+			fw_details->fw_size =
+			    vcd_firmware.boot_code.buffer_size;
+			break;
+		}
+	case VCD_FW_DECODE:
+		{
+			fw_details =
+			    (struct vcd_fw_details *)prop_details;
+			status = get_dec_fw_image(fw_details);
+			break;
+		}
+	case VCD_FW_ENCODE:
+		{
+			fw_details =
+			    (struct vcd_fw_details *)prop_details;
+			status = get_enc_fw_image(fw_details);
+			break;
+		}
+	default:
+		{
+			status = false;
+			break;
+		}
+	}
+	return status;
+}
+
+u32 vcd_fw_transact(u32 add, u32 decoding, enum vcd_codec codec)
+{
+	u32 status = true;
+	u32 index = 0, active_fw = 0, loop_count;
+
+	if (decoding) {
+		switch (codec) {
+		case VCD_CODEC_DIVX_4:
+		case VCD_CODEC_DIVX_5:
+		case VCD_CODEC_DIVX_6:
+		case VCD_CODEC_XVID:
+		case VCD_CODEC_MPEG4:
+			{
+				index = 0;
+				break;
+			}
+		case VCD_CODEC_H264:
+			{
+				index = 1;
+				break;
+			}
+		case VCD_CODEC_H263:
+			{
+				index = 2;
+				break;
+			}
+		case VCD_CODEC_MPEG2:
+			{
+				index = 3;
+				break;
+			}
+		case VCD_CODEC_VC1:
+		case VCD_CODEC_VC1_RCV:
+			{
+				index = 4;
+				break;
+			}
+		default:
+			{
+				status = false;
+				break;
+			}
+		}
+	} else {
+		switch (codec) {
+		case VCD_CODEC_H263:
+		case VCD_CODEC_MPEG4:
+			{
+				index = 5;
+				break;
+			}
+		case VCD_CODEC_H264:
+			{
+				index = 6;
+				break;
+			}
+		default:
+			{
+				status = false;
+				break;
+			}
+		}
+	}
+
+	if (!status)
+		return status;
+
+	if (!add &&
+	    vcd_firmware.active_fw_img[index]
+	    ) {
+		--vcd_firmware.active_fw_img[index];
+		return status;
+	}
+
+	for (loop_count = 0; loop_count < VCDFW_TOTALNUM_IMAGE;
+	     ++loop_count) {
+		if (vcd_firmware.active_fw_img[loop_count])
+			++active_fw;
+	}
+
+	if (active_fw < VCDFW_MAX_NO_IMAGE ||
+	    vcd_firmware.active_fw_img[index] > 0) {
+		++vcd_firmware.active_fw_img[index];
+	} else {
+		status = false;
+	}
+	return status;
+}
+
+void vcd_fw_release(void)
+{
+	ddl_pmem_free(&vcd_firmware.boot_code);
+	ddl_pmem_free(&vcd_firmware.enc_mpeg4);
+	ddl_pmem_free(&vcd_firmware.encH264);
+	ddl_pmem_free(&vcd_firmware.dec_mpeg4);
+	ddl_pmem_free(&vcd_firmware.decH264);
+	ddl_pmem_free(&vcd_firmware.decH263);
+	ddl_pmem_free(&vcd_firmware.dec_mpeg2);
+	ddl_pmem_free(&vcd_firmware.dec_vc1);
+}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
new file mode 100644
index 0000000..7952dfb
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h
@@ -0,0 +1,53 @@
+/* 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_FIRMWARE_H_
+#define _VCD_DDL_FIRMWARE_H_
+#include "vcd_property.h"
+
+#define VCD_FW_BIG_ENDIAN     0x0
+#define VCD_FW_LITTLE_ENDIAN  0x1
+
+struct vcd_fw_details {
+	enum vcd_codec codec;
+	u32 *fw_buffer_addr;
+	u32 fw_size;
+};
+
+#define VCD_FW_PROP_BASE         0x0
+
+#define VCD_FW_ENDIAN       (VCD_FW_PROP_BASE + 0x1)
+#define VCD_FW_BOOTCODE     (VCD_FW_PROP_BASE + 0x2)
+#define VCD_FW_DECODE     (VCD_FW_PROP_BASE + 0x3)
+#define VCD_FW_ENCODE     (VCD_FW_PROP_BASE + 0x4)
+
+extern unsigned char *vidc_command_control_fw;
+extern u32 vidc_command_control_fw_size;
+extern unsigned char *vidc_mpg4_dec_fw;
+extern u32 vidc_mpg4_dec_fw_size;
+extern unsigned char *vidc_h263_dec_fw;
+extern u32 vidc_h263_dec_fw_size;
+extern unsigned char *vidc_h264_dec_fw;
+extern u32 vidc_h264_dec_fw_size;
+extern unsigned char *vidc_mpg4_enc_fw;
+extern u32 vidc_mpg4_enc_fw_size;
+extern unsigned char *vidc_h264_enc_fw;
+extern u32 vidc_h264_enc_fw_size;
+extern unsigned char *vidc_vc1_dec_fw;
+extern u32 vidc_vc1_dec_fw_size;
+
+u32 vcd_fw_init(void);
+u32 vcd_get_fw_property(u32 prop_id, void *prop_details);
+u32 vcd_fw_transact(u32 add, u32 decoding, enum vcd_codec codec);
+void vcd_fw_release(void);
+
+#endif
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
new file mode 100644
index 0000000..a81dd84
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
@@ -0,0 +1,944 @@
+/* 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 "vidc_type.h"
+
+#include "vcd_ddl_utils.h"
+#include "vcd_ddl_metadata.h"
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+void ddl_core_init(struct ddl_context *ddl_context)
+{
+	char *psz_version;
+	struct vcd_fw_details fw_details;
+	u32 fw_endianness;
+	enum vidc_720p_endian dma_endian;
+	u32 interrupt_off;
+	enum vidc_720p_interrupt_level_selection interrupt_sel;
+	u32 intr_mask = 0x0;
+
+	vcd_get_fw_property(VCD_FW_BOOTCODE, &fw_details);
+	vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness);
+	if (fw_endianness == VCD_FW_BIG_ENDIAN)
+		dma_endian = VIDC_720P_BIG_ENDIAN;
+	else
+		dma_endian = VIDC_720P_LITTLE_ENDIAN;
+
+	interrupt_off = false;
+	interrupt_sel = VIDC_720P_INTERRUPT_LEVEL_SEL;
+
+	intr_mask |= VIDC_720P_INTR_BUFFER_FULL;
+	intr_mask |= VIDC_720P_INTR_FW_DONE;
+	intr_mask |= VIDC_720P_INTR_DMA_DONE;
+	intr_mask |= VIDC_720P_INTR_FRAME_DONE;
+
+	vidc_720p_do_sw_reset();
+
+	vidc_720p_init(&psz_version,
+			fw_details.fw_size,
+			fw_details.fw_buffer_addr,
+			dma_endian,
+			interrupt_off, interrupt_sel, intr_mask);
+	return;
+}
+
+void ddl_core_start_cpu(struct ddl_context *ddl_context)
+{
+	u32 fw_endianness;
+	enum vidc_720p_endian dma_endian;
+	u32 dbg_core_dump_buf_size = 0;
+
+	vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness);
+	if (fw_endianness == VCD_FW_BIG_ENDIAN)
+		dma_endian = VIDC_720P_LITTLE_ENDIAN;
+	else
+		dma_endian = VIDC_720P_BIG_ENDIAN;
+
+	ddl_move_command_state(ddl_context, DDL_CMD_CPU_RESET);
+
+	DBG("VSP_BUF_ADDR_SIZE %d",
+		ddl_context->context_buf_addr.buffer_size);
+	if (ddl_context->enable_dbg_core_dump) {
+		dbg_core_dump_buf_size = ddl_context->dbg_core_dump.
+			buffer_size;
+	}
+
+	vidc_720p_start_cpu(dma_endian,
+		ddl_context->context_buf_addr.align_physical_addr,
+		ddl_context->dbg_core_dump.align_physical_addr,
+		dbg_core_dump_buf_size);
+
+	VIDC_DEBUG_REGISTER_LOG;
+}
+
+void ddl_channel_set(struct ddl_client_context *ddl)
+{
+	enum vidc_720p_enc_dec_selection enc_dec_sel;
+	enum vidc_720p_codec codec;
+	enum vcd_codec *vcd_codec;
+	u32 fw_property_id;
+	struct vcd_fw_details fw_details;
+
+	if (ddl->decoding) {
+		if (vidc_msg_timing)
+			ddl_set_core_start_time(__func__, DEC_OP_TIME);
+		enc_dec_sel = VIDC_720P_DECODER;
+		fw_property_id = VCD_FW_DECODE;
+		vcd_codec = &(ddl->codec_data.decoder.codec.codec);
+	} else {
+		enc_dec_sel = VIDC_720P_ENCODER;
+		fw_property_id = VCD_FW_ENCODE;
+		vcd_codec = &(ddl->codec_data.encoder.codec.codec);
+	}
+	switch (*vcd_codec) {
+	default:
+	case VCD_CODEC_MPEG4:
+		{
+			codec = VIDC_720P_MPEG4;
+
+		if (ddl->decoding) {
+			vidc_720p_decode_set_mpeg4_data_partitionbuffer
+				(ddl->ddl_context->data_partition_tempbuf.
+				 align_physical_addr);
+		}
+
+			break;
+		}
+	case VCD_CODEC_H264:
+		{
+			codec = VIDC_720P_H264;
+			break;
+		}
+	case VCD_CODEC_DIVX_4:
+	case VCD_CODEC_DIVX_5:
+	case VCD_CODEC_DIVX_6:
+		{
+			codec = VIDC_720P_DIVX;
+			break;
+		}
+	case VCD_CODEC_XVID:
+		{
+			codec = VIDC_720P_XVID;
+			break;
+		}
+	case VCD_CODEC_H263:
+		{
+			codec = VIDC_720P_H263;
+			break;
+		}
+	case VCD_CODEC_MPEG2:
+		{
+			codec = VIDC_720P_MPEG2;
+			break;
+		}
+	case VCD_CODEC_VC1:
+	case VCD_CODEC_VC1_RCV:
+		{
+			codec = VIDC_720P_VC1;
+			break;
+		}
+	}
+
+	fw_details.codec = *vcd_codec;
+	vcd_get_fw_property(fw_property_id, &fw_details);
+	VIDC_DEBUG_REGISTER_LOG;
+
+	ddl_move_command_state(ddl->ddl_context, DDL_CMD_CHANNEL_SET);
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_CHDONE);
+
+	vidc_720p_set_channel(ddl->channel_id,
+			       enc_dec_sel,
+			       codec,
+			       fw_details.fw_buffer_addr,
+			       fw_details.fw_size);
+}
+
+void ddl_decode_init_codec(struct ddl_client_context *ddl)
+{
+	u32 seq_h = 0, seq_e = 0, start_byte_num = 0;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vcd_sequence_hdr *seq_hdr = &decoder->decode_config;
+	enum vidc_720p_memory_access_method mem_access_method;
+	if (vidc_msg_timing)
+		ddl_set_core_start_time(__func__, DEC_OP_TIME);
+	ddl_metadata_enable(ddl);
+
+	vidc_720p_decode_set_error_control(true);
+
+	vidc_720p_decode_set_mpeg4Post_filter(decoder->post_filter.
+					       post_filter);
+
+	if (decoder->codec.codec == VCD_CODEC_H264) {
+		vidc_720p_decode_setH264VSPBuffer(decoder->
+						   h264Vsp_temp_buffer.
+						   align_physical_addr);
+		VIDC_LOG1("VSP_BUF_ADDR_SIZE",
+			   decoder->h264Vsp_temp_buffer.buffer_size);
+	}
+
+	if (decoder->codec.codec == VCD_CODEC_VC1_RCV ||
+		decoder->codec.codec == VCD_CODEC_VC1) {
+		vidc_720p_set_frame_size(decoder->client_frame_size.width,
+			decoder->client_frame_size.height);
+	} else {
+		vidc_720p_set_frame_size(0x0, 0x0);
+	}
+
+	switch (decoder->buf_format.buffer_format) {
+	default:
+	case VCD_BUFFER_FORMAT_NV12:
+		{
+			mem_access_method = VIDC_720P_TILE_LINEAR;
+			break;
+		}
+	case VCD_BUFFER_FORMAT_TILE_4x2:
+		{
+			mem_access_method = VIDC_720P_TILE_64x32;
+			break;
+		}
+	}
+	VIDC_LOG_STRING("HEADER-PARSE-START");
+	VIDC_DEBUG_REGISTER_LOG;
+	seq_h = (u32) seq_hdr->sequence_header;
+	start_byte_num = 8 - (seq_h & DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+	seq_e = seq_h + seq_hdr->sequence_header_len;
+	seq_h &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+	DDL_PADDING_HACK(seq_e);
+
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE);
+	ddl_move_command_state(ddl->ddl_context, DDL_CMD_HEADER_PARSE);
+
+	vidc_720p_decode_bitstream_header(ddl->channel_id,
+		   seq_hdr->sequence_header_len,
+		   start_byte_num,
+		   seq_h,
+		   seq_e,
+		   mem_access_method,
+		   decoder->output_order);
+}
+
+void ddl_decode_dynamic_property(struct ddl_client_context *ddl,
+				 u32 enable)
+{
+	uint8_t *temp = NULL;
+	u32 extra_datastart = 0;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vcd_frame_data *bit_stream =
+	    &(ddl->input_frame.vcd_frm);
+
+	if (!enable) {
+		if (decoder->dynmic_prop_change_req) {
+			decoder->dynmic_prop_change_req = false;
+			vidc_720p_decode_dynamic_req_reset();
+		}
+		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;
+		vidc_720p_decode_dynamic_req_set(VIDC_720P_FLUSH_REQ);
+	}
+	if (((decoder->meta_data_enable_flag & VCD_METADATA_PASSTHROUGH))
+	    && ((VCD_FRAME_FLAG_EXTRADATA & bit_stream->flags))
+	    ) {
+
+		temp = ((uint8_t *)bit_stream->physical +
+					bit_stream->offset +
+					bit_stream->data_len + 3);
+
+		extra_datastart = (u32) ((u32)temp & ~3);
+		decoder->dynmic_prop_change_req = true;
+
+		vidc_720p_decode_setpassthrough_start(extra_datastart);
+
+		vidc_720p_decode_dynamic_req_set(VIDC_720P_EXTRADATA);
+	}
+}
+
+void ddl_encode_dynamic_property(struct ddl_client_context *ddl,
+				 u32 enable)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	u32 enc_param_change = 0;
+
+	if (!enable) {
+		if (encoder->dynmic_prop_change_req) {
+			encoder->dynmic_prop_change_req = false;
+			encoder->ext_enc_control_val &=
+				~(VIDC_720P_ENC_IFRAME_REQ);
+			vidc_720p_encode_set_control_param
+			(encoder->ext_enc_control_val);
+			vidc_720p_encoder_set_param_change(enc_param_change);
+		}
+		return;
+	}
+	if ((encoder->dynamic_prop_change & DDL_ENC_REQ_IFRAME)) {
+		encoder->dynamic_prop_change &= ~(DDL_ENC_REQ_IFRAME);
+		encoder->ext_enc_control_val |= VIDC_720P_ENC_IFRAME_REQ;
+		vidc_720p_encode_set_control_param
+		(encoder->ext_enc_control_val);
+	}
+	if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_BITRATE)) {
+		vidc_720p_encode_set_bit_rate(
+		encoder->target_bit_rate.target_bitrate);
+		enc_param_change |= VIDC_720P_ENC_BITRATE_CHANGE;
+		encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_BITRATE);
+	}
+	if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_CIR)) {
+		vidc_720p_encode_set_intra_refresh_mb_number(
+			encoder->intra_refresh.cir_mb_number);
+		encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_CIR);
+	}
+	if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_IPERIOD)) {
+		vidc_720p_encode_set_i_period
+			(encoder->i_period.p_frames);
+		enc_param_change |= VIDC_720P_ENC_IPERIOD_CHANGE;
+		encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_IPERIOD);
+	}
+	if ((encoder->dynamic_prop_change &
+				DDL_ENC_CHANGE_FRAMERATE)) {
+		vidc_720p_encode_set_fps
+		    ((encoder->frame_rate.fps_numerator * 1000) /
+		     encoder->frame_rate.fps_denominator);
+		enc_param_change |= VIDC_720P_ENC_FRAMERATE_CHANGE;
+		encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_FRAMERATE);
+	}
+	if (enc_param_change)
+		vidc_720p_encoder_set_param_change(enc_param_change);
+}
+
+static void ddl_encode_set_profile_level(struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	u32 profile;
+	u32 level;
+
+	switch (encoder->profile.profile) {
+	default:
+	case VCD_PROFILE_MPEG4_SP:
+		{
+			profile = VIDC_720P_PROFILE_MPEG4_SP;
+			break;
+		}
+	case VCD_PROFILE_MPEG4_ASP:
+		{
+			profile = VIDC_720P_PROFILE_MPEG4_ASP;
+			break;
+		}
+	case VCD_PROFILE_H264_BASELINE:
+		{
+			profile = VIDC_720P_PROFILE_H264_CPB;
+			break;
+		}
+	case VCD_PROFILE_H264_MAIN:
+		{
+			profile = VIDC_720P_PROFILE_H264_MAIN;
+			break;
+		}
+	case VCD_PROFILE_H264_HIGH:
+		{
+			profile = VIDC_720P_PROFILE_H264_HIGH;
+			break;
+		}
+	case VCD_PROFILE_H263_BASELINE:
+		{
+			profile = VIDC_720P_PROFILE_H263_BASELINE;
+			break;
+		}
+	}
+	switch (encoder->level.level) {
+	default:
+	case VCD_LEVEL_MPEG4_0:
+		{
+			level = VIDC_720P_MPEG4_LEVEL0;
+			break;
+		}
+	case VCD_LEVEL_MPEG4_0b:
+		{
+			level = VIDC_720P_MPEG4_LEVEL0b;
+			break;
+		}
+	case VCD_LEVEL_MPEG4_1:
+		{
+			level = VIDC_720P_MPEG4_LEVEL1;
+			break;
+		}
+	case VCD_LEVEL_MPEG4_2:
+		{
+			level = VIDC_720P_MPEG4_LEVEL2;
+			break;
+		}
+	case VCD_LEVEL_MPEG4_3:
+		{
+			level = VIDC_720P_MPEG4_LEVEL3;
+			break;
+		}
+	case VCD_LEVEL_MPEG4_3b:
+		{
+			level = VIDC_720P_MPEG4_LEVEL3b;
+			break;
+		}
+
+	case VCD_LEVEL_MPEG4_4:
+	case VCD_LEVEL_MPEG4_4a:
+		{
+			level = VIDC_720P_MPEG4_LEVEL4a;
+			break;
+		}
+	case VCD_LEVEL_MPEG4_5:
+		{
+			level = VIDC_720P_MPEG4_LEVEL5;
+			break;
+		}
+	case VCD_LEVEL_MPEG4_6:
+		{
+			level = VIDC_720P_MPEG4_LEVEL6;
+			break;
+		}
+	case VCD_LEVEL_H264_1:
+		{
+			level = VIDC_720P_H264_LEVEL1;
+			break;
+		}
+	case VCD_LEVEL_H264_1b:
+		{
+			level = VIDC_720P_H264_LEVEL1b;
+			break;
+		}
+	case VCD_LEVEL_H264_1p1:
+		{
+			level = VIDC_720P_H264_LEVEL1p1;
+			break;
+		}
+	case VCD_LEVEL_H264_1p2:
+		{
+			level = VIDC_720P_H264_LEVEL1p2;
+			break;
+		}
+	case VCD_LEVEL_H264_1p3:
+		{
+			level = VIDC_720P_H264_LEVEL1p3;
+			break;
+		}
+	case VCD_LEVEL_H264_2:
+		{
+			level = VIDC_720P_H264_LEVEL2;
+			break;
+		}
+	case VCD_LEVEL_H264_2p1:
+		{
+			level = VIDC_720P_H264_LEVEL2p1;
+			break;
+		}
+	case VCD_LEVEL_H264_2p2:
+		{
+			level = VIDC_720P_H264_LEVEL2p2;
+			break;
+		}
+	case VCD_LEVEL_H264_3:
+		{
+			level = VIDC_720P_H264_LEVEL3;
+			break;
+		}
+	case VCD_LEVEL_H264_3p1:
+		{
+			level = VIDC_720P_H264_LEVEL3p1;
+			break;
+		}
+	case VCD_LEVEL_H263_10:
+		{
+			level = VIDC_720P_H263_LEVEL10;
+			break;
+		}
+	case VCD_LEVEL_H263_20:
+		{
+			level = VIDC_720P_H263_LEVEL20;
+			break;
+		}
+	case VCD_LEVEL_H263_30:
+		{
+			level = VIDC_720P_H263_LEVEL30;
+			break;
+		}
+	case VCD_LEVEL_H263_40:
+		{
+			level = VIDC_720P_H263_LEVEL40;
+			break;
+		}
+	case VCD_LEVEL_H263_45:
+		{
+			level = VIDC_720P_H263_LEVEL45;
+			break;
+		}
+	case VCD_LEVEL_H263_50:
+		{
+			level = VIDC_720P_H263_LEVEL50;
+			break;
+		}
+	case VCD_LEVEL_H263_60:
+		{
+			level = VIDC_720P_H263_LEVEL60;
+			break;
+		}
+	case VCD_LEVEL_H263_70:
+		{
+			level = VIDC_720P_H263_LEVEL70;
+			break;
+		}
+	}
+	vidc_720p_encode_set_profile(profile, level);
+}
+
+void ddl_encode_init_codec(struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	enum vidc_720p_memory_access_method mem_access_method;
+	enum vidc_720p_DBConfig db_config;
+	enum vidc_720p_MSlice_selection m_slice_sel;
+
+	ddl_encode_set_profile_level(ddl);
+
+	vidc_720p_set_frame_size
+	    (encoder->frame_size.width, encoder->frame_size.height);
+	vidc_720p_encode_set_qp_params
+	    (encoder->qp_range.max_qp, encoder->qp_range.min_qp);
+	vidc_720p_encode_set_rc_config
+	    (encoder->rc_level.frame_level_rc,
+	     encoder->rc_level.mb_level_rc,
+	     encoder->session_qp.i_frame_qp,
+	     encoder->session_qp.p_frame_qp);
+
+	if (encoder->r_cframe_skip) {
+		if (encoder->vb_vbuffer_size) {
+			encoder->ext_enc_control_val = (0x2 << 0x2) |
+			(encoder->vb_vbuffer_size << 0x10);
+		} else
+			encoder->ext_enc_control_val = (0x1 << 2);
+	} else
+		encoder->ext_enc_control_val = 0;
+
+	vidc_720p_encode_set_fps
+	    ((encoder->frame_rate.fps_numerator * 1000) /
+	     encoder->frame_rate.fps_denominator);
+
+	vidc_720p_encode_set_vop_time(
+			encoder->vop_timing.vop_time_resolution, 0);
+
+	if (encoder->rc_level.frame_level_rc) {
+		vidc_720p_encode_set_bit_rate
+		    (encoder->target_bit_rate.target_bitrate);
+
+		vidc_720p_encode_set_frame_level_rc_params
+		    (encoder->frame_level_rc.reaction_coeff);
+	}
+	if (encoder->rc_level.mb_level_rc) {
+		vidc_720p_encode_set_mb_level_rc_params
+		    (encoder->adaptive_rc.dark_region_as_flag,
+		     encoder->adaptive_rc.smooth_region_as_flag,
+		     encoder->adaptive_rc.static_region_as_flag,
+		     encoder->adaptive_rc.activity_region_flag);
+	}
+	if (encoder->codec.codec == VCD_CODEC_MPEG4) {
+		vidc_720p_encode_set_short_header
+		    (encoder->short_header.short_header);
+
+		if (encoder->hdr_ext_control) {
+			vidc_720p_encode_set_hec_period
+			(encoder->hdr_ext_control);
+			encoder->ext_enc_control_val |= (0x1 << 0x1);
+		}
+	}
+	/* set extended encoder control settings */
+	vidc_720p_encode_set_control_param
+	(encoder->ext_enc_control_val);
+
+	if (encoder->codec.codec == VCD_CODEC_H264) {
+		enum vidc_720p_entropy_sel entropy_sel;
+		enum vidc_720p_cabac_model cabac_model_number;
+		switch (encoder->entropy_control.entropy_sel) {
+		default:
+		case VCD_ENTROPY_SEL_CAVLC:
+			{
+				entropy_sel = VIDC_720P_ENTROPY_SEL_CAVLC;
+				break;
+			}
+		case VCD_ENTROPY_SEL_CABAC:
+			{
+				entropy_sel = VIDC_720P_ENTROPY_SEL_CABAC;
+				break;
+			}
+		}
+		switch (encoder->entropy_control.cabac_model) {
+		default:
+		case VCD_CABAC_MODEL_NUMBER_0:
+			{
+				cabac_model_number =
+				    VIDC_720P_CABAC_MODEL_NUMBER_0;
+				break;
+			}
+		case VCD_CABAC_MODEL_NUMBER_1:
+			{
+				cabac_model_number =
+				    VIDC_720P_CABAC_MODEL_NUMBER_1;
+				break;
+			}
+		case VCD_CABAC_MODEL_NUMBER_2:
+			{
+				cabac_model_number =
+				    VIDC_720P_CABAC_MODEL_NUMBER_2;
+				break;
+			}
+		}
+		vidc_720p_encode_set_entropy_control
+		    (entropy_sel, cabac_model_number);
+		switch (encoder->db_control.db_config) {
+		default:
+		case VCD_DB_ALL_BLOCKING_BOUNDARY:
+			{
+				db_config =
+				    VIDC_720P_DB_ALL_BLOCKING_BOUNDARY;
+				break;
+			}
+		case VCD_DB_DISABLE:
+			{
+				db_config =
+				    VIDC_720P_DB_DISABLE;
+				break;
+			}
+		case VCD_DB_SKIP_SLICE_BOUNDARY:
+			{
+				db_config =
+				    VIDC_720P_DB_SKIP_SLICE_BOUNDARY;
+				break;
+			}
+		}
+		vidc_720p_encode_set_db_filter_control
+		    (db_config,
+		     encoder->db_control.slice_alpha_offset,
+		     encoder->db_control.slice_beta_offset);
+	}
+
+	vidc_720p_encode_set_intra_refresh_mb_number
+	    (encoder->intra_refresh.cir_mb_number);
+
+	switch (encoder->multi_slice.m_slice_sel) {
+	default:
+	case VCD_MSLICE_OFF:
+		m_slice_sel = VIDC_720P_MSLICE_OFF;
+		break;
+	case VCD_MSLICE_BY_MB_COUNT:
+		{
+			m_slice_sel = VIDC_720P_MSLICE_BY_MB_COUNT;
+			break;
+		}
+	case VCD_MSLICE_BY_BYTE_COUNT:
+		{
+			m_slice_sel = VIDC_720P_MSLICE_BY_BYTE_COUNT;
+			break;
+		}
+	case VCD_MSLICE_BY_GOB:
+		{
+			m_slice_sel = VIDC_720P_MSLICE_BY_GOB;
+			break;
+		}
+	}
+	vidc_720p_encode_set_multi_slice_info
+	    (m_slice_sel, encoder->multi_slice.m_slice_size);
+
+	vidc_720p_encode_set_dpb_buffer
+	    (encoder->enc_dpb_addr.align_physical_addr,
+			 encoder->enc_dpb_addr.buffer_size);
+
+	VIDC_LOG1("ENC_DPB_ADDR_SIZE", encoder->enc_dpb_addr.buffer_size);
+
+	vidc_720p_encode_set_i_period(encoder->i_period.p_frames);
+
+	ddl_metadata_enable(ddl);
+
+	if (encoder->seq_header.virtual_base_addr) {
+		u32 ext_buffer_start, ext_buffer_end, start_byte_num;
+		ext_buffer_start =
+		    (u32) encoder->seq_header.align_physical_addr;
+		ext_buffer_end =
+		    ext_buffer_start + encoder->seq_header.buffer_size;
+		start_byte_num =
+		    (ext_buffer_start & DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+		ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+		ext_buffer_end &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+		VIDC_LOG1("ENC_SEQHDR_ALLOC_SIZE",
+			   encoder->seq_header.buffer_size);
+		vidc_720p_encode_set_seq_header_buffer(ext_buffer_start,
+							ext_buffer_end,
+							start_byte_num);
+	}
+
+	if (encoder->re_con_buf_format.buffer_format ==
+		VCD_BUFFER_FORMAT_NV12)
+		mem_access_method = VIDC_720P_TILE_LINEAR;
+	else
+		mem_access_method = VIDC_720P_TILE_16x16;
+
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE);
+	ddl_move_command_state(ddl->ddl_context, DDL_CMD_INIT_CODEC);
+
+	vidc_720p_encode_init_codec(ddl->channel_id, mem_access_method);
+}
+
+void ddl_channel_end(struct ddl_client_context *ddl)
+{
+	VIDC_DEBUG_REGISTER_LOG;
+
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_CHEND);
+	ddl_move_command_state(ddl->ddl_context, DDL_CMD_CHANNEL_END);
+
+	vidc_720p_submit_command(ddl->channel_id, VIDC_720P_CMD_CHEND);
+}
+
+void ddl_encode_frame_run(struct ddl_client_context *ddl)
+{
+	u32 ext_buffer_start, ext_buffer_end;
+	u32 y_addr, c_addr;
+	u32 start_byte_number = 0;
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm);
+
+	ext_buffer_start = (u32) stream->physical + stream->offset;
+	ext_buffer_end = ddl_encode_set_metadata_output_buf(ddl);
+	start_byte_number =
+	    (ext_buffer_start & DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+	if (start_byte_number) {
+		u32 upper_data, lower_data;
+		u32 *align_virtual_addr;
+		ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+		align_virtual_addr = (u32 *) (((u32) stream->virtual +
+						 stream->offset) -
+						start_byte_number);
+		upper_data = *align_virtual_addr;
+		align_virtual_addr++;
+		lower_data = *align_virtual_addr;
+		vidc_720p_encode_unalign_bitstream(upper_data, lower_data);
+	}
+
+	y_addr = (u32) ddl->input_frame.vcd_frm.physical +
+	    ddl->input_frame.vcd_frm.offset;
+	c_addr = (y_addr + (encoder->frame_size.scan_lines *
+				encoder->frame_size.stride));
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE);
+	ddl_move_command_state(ddl->ddl_context, DDL_CMD_ENCODE_FRAME);
+
+	if (encoder->dynamic_prop_change) {
+		encoder->dynmic_prop_change_req = true;
+		ddl_encode_dynamic_property(ddl, true);
+	}
+	vidc_720p_encode_set_vop_time(
+			encoder->vop_timing.vop_time_resolution,
+			ddl->input_frame.frm_delta
+	    );
+
+	vidc_720p_encode_frame(ddl->channel_id,
+			ext_buffer_start,
+				ext_buffer_end,
+				start_byte_number, y_addr, c_addr);
+}
+
+u32 ddl_decode_set_buffers(struct ddl_client_context *ddl)
+{
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	u32 comv_buf_size = DDL_COMV_BUFLINE_NO, comv_buf_no = 0;
+	u32 ref_buf_no = 0;
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) {
+		VIDC_LOG_STRING("STATE-CRITICAL");
+		return VCD_ERR_FAIL;
+	}
+	if (vidc_msg_timing)
+		ddl_set_core_start_time(__func__, DEC_OP_TIME);
+	switch (decoder->codec.codec) {
+	default:
+	case VCD_CODEC_DIVX_4:
+	case VCD_CODEC_DIVX_5:
+	case VCD_CODEC_DIVX_6:
+	case VCD_CODEC_XVID:
+	case VCD_CODEC_MPEG2:
+	case VCD_CODEC_MPEG4:
+		{
+			comv_buf_no = DDL_MPEG_COMV_BUF_NO;
+			ref_buf_no = DDL_MPEG_REFBUF_COUNT;
+			break;
+		}
+	case VCD_CODEC_H263:
+		{
+			comv_buf_no = DDL_H263_COMV_BUF_NO;
+			break;
+		}
+	case VCD_CODEC_VC1:
+	case VCD_CODEC_VC1_RCV:
+		{
+			comv_buf_no =
+			    decoder->client_output_buf_req.actual_count + 1;
+			comv_buf_size = DDL_VC1_COMV_BUFLINE_NO;
+			break;
+		}
+	case VCD_CODEC_H264:
+		{
+			comv_buf_no =
+			    decoder->client_output_buf_req.actual_count;
+			break;
+		}
+	}
+
+	if (comv_buf_no) {
+		comv_buf_size *= (comv_buf_no *
+			(decoder->client_frame_size.stride >> 4) *
+			((decoder->client_frame_size.scan_lines >> 4) + 1));
+		if (decoder->dpb_comv_buffer.virtual_base_addr)
+			ddl_pmem_free(&decoder->dpb_comv_buffer);
+		ddl_pmem_alloc(&decoder->dpb_comv_buffer, comv_buf_size,
+			       DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		if (!decoder->dpb_comv_buffer.virtual_base_addr) {
+			VIDC_LOGERR_STRING
+			    ("Dec_set_buf:Comv_buf_alloc_failed");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+		vidc_720p_decode_set_comv_buffer(decoder->dpb_comv_buffer.
+						  align_physical_addr,
+						  decoder->dpb_comv_buffer.
+						  buffer_size);
+	}
+	decoder->ref_buffer.align_physical_addr = NULL;
+	if (ref_buf_no) {
+		size_t sz, align_bytes;
+		sz = decoder->dp_buf.dec_pic_buffers[0].vcd_frm.alloc_len;
+		sz *= ref_buf_no;
+		align_bytes = decoder->client_output_buf_req.align;
+		if (decoder->ref_buffer.virtual_base_addr)
+			ddl_pmem_free(&decoder->ref_buffer);
+		ddl_pmem_alloc(&decoder->ref_buffer, sz, align_bytes);
+		if (!decoder->ref_buffer.virtual_base_addr) {
+			ddl_pmem_free(&decoder->dpb_comv_buffer);
+			VIDC_LOGERR_STRING
+			    ("Dec_set_buf:mpeg_ref_buf_alloc_failed");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+	}
+	ddl_decode_set_metadata_output(decoder);
+	ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_INIT);
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE);
+	ddl_move_command_state(ddl->ddl_context, DDL_CMD_DECODE_SET_DPB);
+
+	vidc_720p_submit_command(ddl->channel_id,
+		VIDC_720P_CMD_INITBUFFERS);
+	return VCD_S_SUCCESS;
+}
+
+void ddl_decode_frame_run(struct ddl_client_context *ddl)
+{
+	u32 ext_buffer_start = 0, ext_buffer_end = 0;
+	u32 start_byte_num = 8;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	struct vcd_frame_data *bit_stream =
+	    &(ddl->input_frame.vcd_frm);
+	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_decode_eos_run(ddl);
+		return;
+	}
+
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE);
+
+	ddl_decode_dynamic_property(ddl, true);
+
+	ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK);
+
+	ext_buffer_start = (u32)bit_stream->physical +
+		bit_stream->offset;
+	start_byte_num = 8 - (ext_buffer_start &
+		DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+	ext_buffer_end = ext_buffer_start + bit_stream->data_len;
+	ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES);
+	DDL_PADDING_HACK(ext_buffer_end);
+
+	ddl_move_command_state(ddl->ddl_context, DDL_CMD_DECODE_FRAME);
+
+	vidc_720p_decode_frame(ddl->channel_id,
+			ext_buffer_start,
+			ext_buffer_end,
+			bit_stream->data_len,
+			start_byte_num, bit_stream->ip_frm_tag);
+}
+
+void  ddl_decode_eos_run(struct ddl_client_context *ddl)
+{
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE);
+
+	ddl_decode_dynamic_property(ddl, true);
+
+	ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK);
+
+	decoder->dynmic_prop_change_req = true;
+
+	ddl_move_command_state(ddl->ddl_context, DDL_CMD_EOS);
+
+	vidc_720p_issue_eos(ddl->channel_id);
+}
+
+u32 ddl_hal_engine_reset(struct ddl_context *ddl_context)
+{
+	u32 eng_reset;
+	u32 channel_id = 0;
+	u32 fw_endianness;
+	enum vidc_720p_endian dma_endian;
+	enum vidc_720p_interrupt_level_selection interrupt_sel;
+	u32 intr_mask = 0x0;
+
+	if (ddl_context->current_ddl)
+		channel_id = ddl_context->current_ddl->channel_id;
+
+	interrupt_sel = VIDC_720P_INTERRUPT_LEVEL_SEL;
+	/* Enable all the supported interrupt */
+	intr_mask |= VIDC_720P_INTR_BUFFER_FULL;
+	intr_mask |= VIDC_720P_INTR_FW_DONE;
+	intr_mask |= VIDC_720P_INTR_DMA_DONE;
+	intr_mask |= VIDC_720P_INTR_FRAME_DONE;
+
+	vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness);
+	/* Reverse the endianness settings after boot code download */
+	if (fw_endianness == VCD_FW_BIG_ENDIAN)
+		dma_endian = VIDC_720P_LITTLE_ENDIAN;
+	else
+		dma_endian = VIDC_720P_BIG_ENDIAN;
+
+	/* Need to reset MFC silently */
+	eng_reset = vidc_720p_engine_reset(
+		channel_id,
+		dma_endian, interrupt_sel,
+		intr_mask);
+	if (!eng_reset) {
+		/* call the hw fatal callback if engine reset fails */
+		ddl_hw_fatal_cb(ddl_context);
+	}
+	return eng_reset ;
+}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
new file mode 100644
index 0000000..2899df6
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c
@@ -0,0 +1,286 @@
+/* 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 "vidc_type.h"
+#include "vcd_ddl_utils.h"
+
+DDL_INLINE struct ddl_context *ddl_get_context(void)
+{
+	static struct ddl_context ddl_context;
+	return &ddl_context;
+}
+
+DDL_INLINE void ddl_move_client_state(struct ddl_client_context *ddl,
+				      enum ddl_client_state client_state)
+{
+	ddl->client_state = client_state;
+}
+
+DDL_INLINE void ddl_move_command_state(struct ddl_context *ddl_context,
+				       enum ddl_cmd_state command_state)
+{
+	ddl_context->cmd_state = command_state;
+}
+
+u32 ddl_client_transact(u32 operation,
+			struct ddl_client_context **pddl_client)
+{
+	u32 ret_status = VCD_ERR_FAIL;
+	u32 counter;
+	struct ddl_context *ddl_context;
+
+	ddl_context = ddl_get_context();
+	switch (operation) {
+	case DDL_FREE_CLIENT:
+		{
+			if (pddl_client && *pddl_client) {
+				u32 channel_id;
+				channel_id = (*pddl_client)->channel_id;
+				if (channel_id < VCD_MAX_NO_CLIENT) {
+					ddl_context->
+					    ddl_clients[channel_id] = NULL;
+				} else {
+					VIDC_LOG_STRING("CHID_CORRUPTION");
+				}
+				DDL_FREE(*pddl_client);
+				ret_status = VCD_S_SUCCESS;
+			}
+			break;
+		}
+	case DDL_GET_CLIENT:
+		{
+			ret_status = VCD_ERR_MAX_CLIENT;
+			for (counter = 0; counter < VCD_MAX_NO_CLIENT &&
+			     ret_status == VCD_ERR_MAX_CLIENT; ++counter) {
+				if (!ddl_context->ddl_clients[counter]) {
+					*pddl_client =
+					    (struct ddl_client_context *)
+					    DDL_MALLOC(sizeof
+					       (struct ddl_client_context)
+					       );
+					if (!*pddl_client) {
+						ret_status = VCD_ERR_ALLOC_FAIL;
+					} else {
+						DDL_MEMSET(*pddl_client, 0,
+						   sizeof(struct
+						   ddl_client_context));
+						ddl_context->
+						    ddl_clients[counter] =
+						    *pddl_client;
+						(*pddl_client)->channel_id =
+						    counter;
+						(*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)
+{
+	u32 vcd_status = VCD_S_SUCCESS;
+	u32 loopc;
+	struct ddl_frame_data_tag *found_frame = NULL;
+	struct ddl_mask *dpb_mask = &decoder->dpb_mask;
+
+	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 &=
+					    (~(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;
+				VIDC_LOG_STRING("BUF_NOT_FOUND");
+			}
+			break;
+		}
+	case DDL_DPB_OP_SET_MASK:
+		{
+			dpb_mask->hw_mask |= dpb_mask->client_mask;
+			dpb_mask->client_mask = 0;
+			vidc_720p_decode_set_dpb_release_buffer_mask
+			    (dpb_mask->hw_mask);
+			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;
+			vidc_720p_decode_set_dpb_details(decoder->dp_buf.
+						  no_of_dec_pic_buf,
+						  dpb_size,
+						  decoder->ref_buffer.
+						  align_physical_addr);
+			for (loopc = 0;
+			     loopc < decoder->dp_buf.no_of_dec_pic_buf;
+			     ++loopc) {
+				vidc_720p_decode_set_dpb_buffers(loopc,
+							  (u32 *)
+							  decoder->
+							  dp_buf.
+							  dec_pic_buffers
+							  [loopc].
+							  vcd_frm.
+							  physical);
+				VIDC_LOG1("DEC_DPB_BUFn_SIZE",
+					   decoder->dp_buf.
+					   dec_pic_buffers[loopc].vcd_frm.
+					   alloc_len);
+			}
+			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;
+		}
+	}
+	return vcd_status;
+}
+
+void ddl_release_context_buffers(struct ddl_context *ddl_context)
+{
+	ddl_pmem_free(&ddl_context->context_buf_addr);
+	ddl_pmem_free(&ddl_context->db_line_buffer);
+	ddl_pmem_free(&ddl_context->data_partition_tempbuf);
+	ddl_pmem_free(&ddl_context->metadata_shared_input);
+	ddl_pmem_free(&ddl_context->dbg_core_dump);
+
+	vcd_fw_release();
+}
+
+void ddl_release_client_internal_buffers(struct ddl_client_context *ddl)
+{
+	if (ddl->decoding) {
+		struct ddl_decoder_data *decoder =
+		    &(ddl->codec_data.decoder);
+		ddl_pmem_free(&decoder->h264Vsp_temp_buffer);
+		ddl_pmem_free(&decoder->dpb_comv_buffer);
+		ddl_pmem_free(&decoder->ref_buffer);
+		DDL_FREE(decoder->dp_buf.dec_pic_buffers);
+		ddl_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;
+
+	} else {
+		struct ddl_encoder_data *encoder =
+		    &(ddl->codec_data.encoder);
+		ddl_pmem_free(&encoder->enc_dpb_addr);
+		ddl_pmem_free(&encoder->seq_header);
+		ddl_encode_dynamic_property(ddl, false);
+		encoder->dynamic_prop_change = 0;
+	}
+}
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
new file mode 100644
index 0000000..00c00cd
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
@@ -0,0 +1,75 @@
+/* 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_INTERNAL_PROPERTY_H_
+#define _VCD_DDL_INTERNAL_PROPERTY_H_
+#include "vcd_api.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_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_SEQHDR_PRESENT (VCD_I_CUSTOM_DDL_BASE + 0xb)
+#define DDL_I_CAPABILITY    (VCD_I_CUSTOM_DDL_BASE + 0x8)
+#define DDL_I_FRAME_PROC_UNITS    (VCD_I_CUSTOM_DDL_BASE + 0x9)
+
+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 dark_region_as_flag;
+	u32 smooth_region_as_flag;
+	u32 static_region_as_flag;
+	u32 activity_region_flag;
+};
+
+struct ddl_frame_data_tag;
+
+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 frame_command_depth;
+	u32 exclusive;
+	u32   ddl_time_out_in_ms;
+};
+
+#endif
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
new file mode 100644
index 0000000..ef5b717
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c
@@ -0,0 +1,1122 @@
+/* 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 "vidc_type.h"
+#include "vidc.h"
+#include "vcd_ddl_utils.h"
+#include "vcd_ddl_metadata.h"
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+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_frame
+    (struct vcd_frame_data *frame, u32 frame_type);
+
+static void ddl_getdec_profilelevel
+(struct ddl_decoder_data   *decoder, u32 profile, u32 level);
+
+static void ddl_dma_done_callback(struct ddl_context *ddl_context)
+{
+	if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) {
+		VIDC_LOGERR_STRING("UNKWN_DMADONE");
+		return;
+	}
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	VIDC_LOG_STRING("DMA_DONE");
+	ddl_core_start_cpu(ddl_context);
+}
+
+static void ddl_cpu_started_callback(struct ddl_context *ddl_context)
+{
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	VIDC_LOG_STRING("CPU-STARTED");
+
+	if (!vidc_720p_cpu_start()) {
+		ddl_hw_fatal_cb(ddl_context);
+		return;
+	}
+
+	vidc_720p_set_deblock_line_buffer(
+			ddl_context->db_line_buffer.align_physical_addr,
+			ddl_context->db_line_buffer.buffer_size);
+	ddl_context->device_state = DDL_DEVICE_INITED;
+	ddl_context->ddl_callback(VCD_EVT_RESP_DEVICE_INIT, VCD_S_SUCCESS,
+			NULL, 0, NULL, ddl_context->client_data);
+	DDL_IDLE(ddl_context);
+}
+
+
+static u32 ddl_eos_done_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	u32 displaystatus, resl_change;
+
+	if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_EOS)) {
+		VIDC_LOGERR_STRING("UNKWN_EOSDONE");
+		ddl_client_fatal_cb(ddl_context);
+		return true;
+	}
+
+	if (!ddl ||
+		!ddl->decoding ||
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)
+		) {
+		VIDC_LOG_STRING("STATE-CRITICAL-EOSDONE");
+		ddl_client_fatal_cb(ddl_context);
+		return true;
+	}
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+
+	vidc_720p_eos_info(&displaystatus, &resl_change);
+	if ((enum vidc_720p_display_status)displaystatus
+		!= VIDC_720P_EMPTY_BUFFER) {
+		VIDC_LOG_STRING("EOSDONE-EMPTYBUF-ISSUE");
+	}
+
+	ddl_decode_dynamic_property(ddl, false);
+	if (resl_change == 0x1) {
+		ddl->codec_data.decoder.header_in_start = false;
+		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_decode_init_codec(ddl);
+		return false;
+	}
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME);
+	VIDC_LOG_STRING("EOS_DONE");
+	ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS,
+		NULL, 0, (u32 *) ddl, ddl_context->client_data);
+	DDL_IDLE(ddl_context);
+
+	return true;
+}
+
+static u32 ddl_channel_set_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	u32 return_status = false;
+
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	VIDC_DEBUG_REGISTER_LOG;
+
+	if (!ddl ||
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHDONE)
+		) {
+		VIDC_LOG_STRING("STATE-CRITICAL-CHSET");
+		DDL_IDLE(ddl_context);
+		return return_status;
+	}
+	VIDC_LOG_STRING("Channel-set");
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC);
+
+	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_decode_init_codec(ddl);
+		} else {
+			ddl_context->ddl_callback(VCD_EVT_RESP_START,
+				VCD_S_SUCCESS, NULL,
+				0, (u32 *) ddl,
+				ddl_context->client_data);
+
+			DDL_IDLE(ddl_context);
+			return_status = true;
+		}
+	} else {
+		ddl_encode_init_codec(ddl);
+	}
+	return return_status;
+}
+
+static void ddl_init_codec_done_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	struct ddl_encoder_data *encoder;
+
+	if (!ddl ||
+		ddl->decoding ||
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)
+		) {
+		VIDC_LOG_STRING("STATE-CRITICAL-INITCODEC");
+		ddl_client_fatal_cb(ddl_context);
+		return;
+	}
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME);
+	VIDC_LOG_STRING("INIT_CODEC_DONE");
+
+	encoder = &ddl->codec_data.encoder;
+	if (encoder->seq_header.virtual_base_addr) {
+		vidc_720p_encode_get_header(&encoder->seq_header.
+			buffer_size);
+	}
+
+	ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL,
+		0, (u32 *) ddl, ddl_context->client_data);
+
+	DDL_IDLE(ddl_context);
+}
+
+static u32 ddl_header_done_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	struct ddl_decoder_data *decoder;
+	struct vidc_720p_seq_hdr_info seq_hdr_info;
+
+	u32 process_further = true;
+	u32 seq_hdr_only_frame = false;
+	u32 need_reconfig = true;
+	struct vcd_frame_data *input_vcd_frm;
+	struct ddl_frame_data_tag *reconfig_payload = NULL;
+	u32 reconfig_payload_size = 0;
+
+	if (!ddl ||
+		!ddl->decoding ||
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)
+		) {
+		VIDC_LOG_STRING("STATE-CRITICAL-HDDONE");
+		ddl_client_fatal_cb(ddl_context);
+		return true;
+	}
+	if (vidc_msg_timing)
+		ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_DPB);
+	VIDC_LOG_STRING("HEADER_DONE");
+	VIDC_DEBUG_REGISTER_LOG;
+
+	vidc_720p_decode_get_seq_hdr_info(&seq_hdr_info);
+
+	decoder = &(ddl->codec_data.decoder);
+	decoder->frame_size.width = seq_hdr_info.img_size_x;
+	decoder->frame_size.height = seq_hdr_info.img_size_y;
+	decoder->min_dpb_num = seq_hdr_info.min_num_dpb;
+	decoder->y_cb_cr_size = seq_hdr_info.min_dpb_size;
+	decoder->progressive_only = 1 - seq_hdr_info.progressive;
+	if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) {
+		VIDC_LOGERR_STRING("FATAL: ZeroImageSize");
+		ddl_client_fatal_cb(ddl_context);
+		return process_further;
+	}
+	if (seq_hdr_info.data_partitioned == 0x1 &&
+		decoder->codec.codec == VCD_CODEC_MPEG4 &&
+		seq_hdr_info.img_size_x > DDL_MAX_DP_FRAME_WIDTH &&
+		seq_hdr_info.img_size_y > DDL_MAX_DP_FRAME_HEIGHT)	{
+		ddl_client_fatal_cb(ddl_context);
+		return process_further;
+	}
+	ddl_getdec_profilelevel(decoder, seq_hdr_info.profile,
+		seq_hdr_info.level);
+	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
+		+ seq_hdr_info.crop_left_offset);
+		decoder->frame_size.height -=
+		(seq_hdr_info.crop_top_offset +
+		seq_hdr_info.crop_bottom_offset);
+	}
+	ddl_set_default_decoder_buffer_req(decoder, false);
+
+	if (decoder->header_in_start) {
+		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_context->client_data);
+		DDL_IDLE(ddl_context);
+	} else {
+		DBG("%s(): Client data: WxH(%u x %u) SxSL(%u x %u) Sz(%u)\n",
+			__func__, decoder->client_frame_size.width,
+			decoder->client_frame_size.height,
+			decoder->client_frame_size.stride,
+			decoder->client_frame_size.scan_lines,
+			decoder->client_output_buf_req.sz);
+		DBG("%s(): DDL data: WxH(%u x %u) SxSL(%u x %u) Sz(%u)\n",
+			__func__, decoder->frame_size.width,
+			decoder->frame_size.height,
+			decoder->frame_size.stride,
+			decoder->frame_size.scan_lines,
+			decoder->actual_output_buf_req.sz);
+		DBG("%s(): min_dpb_num = %d actual_count = %d\n", __func__,
+			decoder->min_dpb_num,
+			decoder->client_output_buf_req.actual_count);
+
+		input_vcd_frm = &(ddl->input_frame.vcd_frm);
+
+		if (decoder->frame_size.width ==
+			decoder->client_frame_size.width
+			&& decoder->frame_size.height ==
+			decoder->client_frame_size.height
+			&& decoder->frame_size.stride ==
+			decoder->client_frame_size.stride
+			&& decoder->frame_size.scan_lines ==
+			decoder->client_frame_size.scan_lines
+			&& 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
+			&& decoder->progressive_only)
+			need_reconfig = false;
+		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,
+				VCD_S_SUCCESS, &ddl->input_frame,
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl,
+				ddl->ddl_context->client_data);
+		} else if (decoder->codec.codec != VCD_CODEC_H263) {
+			input_vcd_frm->offset += seq_hdr_info.dec_frm_size;
+			input_vcd_frm->data_len -= seq_hdr_info.dec_frm_size;
+		}
+		if (need_reconfig) {
+			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) {
+				reconfig_payload = &ddl->input_frame;
+				reconfig_payload_size =
+					sizeof(struct ddl_frame_data_tag);
+			}
+			ddl_context->ddl_callback(VCD_EVT_IND_OUTPUT_RECONFIG,
+					VCD_S_SUCCESS, reconfig_payload,
+					reconfig_payload_size,
+					(u32 *) ddl,
+					ddl_context->client_data);
+		}
+		if (!need_reconfig && !seq_hdr_only_frame) {
+			if (ddl_decode_set_buffers(ddl) == VCD_S_SUCCESS)
+				process_further = false;
+			else
+				ddl_client_fatal_cb(ddl_context);
+		} else
+			DDL_IDLE(ddl_context);
+	}
+	return process_further;
+}
+
+static u32 ddl_dpb_buffers_set_done_callback(struct ddl_context
+						  *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	if (!ddl ||
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE)
+		) {
+		VIDC_LOG_STRING("STATE-CRITICAL-DPBDONE");
+		ddl_client_fatal_cb(ddl_context);
+		return true;
+	}
+	if (vidc_msg_timing) {
+		ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
+		ddl_reset_core_time_variables(DEC_OP_TIME);
+	}
+	VIDC_LOG_STRING("INTR_DPBDONE");
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME);
+	ddl->codec_data.decoder.dec_disp_info.img_size_x = 0;
+	ddl->codec_data.decoder.dec_disp_info.img_size_y = 0;
+	ddl_decode_frame_run(ddl);
+	return false;
+}
+
+static void ddl_encoder_frame_run_callback(struct ddl_context
+					   *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	u32 eos_present = false;
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)
+		) {
+		VIDC_LOG_STRING("STATE-CRITICAL-ENCFRMRUN");
+		ddl_client_fatal_cb(ddl_context);
+		return;
+	}
+
+	VIDC_LOG_STRING("ENC_FRM_RUN_DONE");
+
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	vidc_720p_enc_frame_info(&encoder->enc_frame_info);
+
+	ddl->output_frame.vcd_frm.ip_frm_tag =
+		ddl->input_frame.vcd_frm.ip_frm_tag;
+	ddl->output_frame.vcd_frm.data_len =
+		encoder->enc_frame_info.enc_size;
+	ddl->output_frame.vcd_frm.flags |= VCD_FRAME_FLAG_ENDOFFRAME;
+	ddl_get_frame
+		(&(ddl->output_frame.vcd_frm),
+		 encoder->enc_frame_info.frame);
+	ddl_process_encoder_metadata(ddl);
+
+	ddl_encode_dynamic_property(ddl, false);
+
+	ddl->input_frame.frm_trans_end = false;
+	ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS,
+		&(ddl->input_frame), sizeof(struct ddl_frame_data_tag),
+		(u32 *) ddl, ddl_context->client_data);
+
+	if (vidc_msg_timing)
+		ddl_calc_core_proc_time(__func__, ENC_OP_TIME);
+
+	/* check the presence of EOS */
+   eos_present =
+	((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags));
+
+	ddl->output_frame.frm_trans_end = !eos_present;
+	ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, VCD_S_SUCCESS,
+		&(ddl->output_frame),	sizeof(struct ddl_frame_data_tag),
+		(u32 *) ddl, ddl_context->client_data);
+
+	if (eos_present) {
+		VIDC_LOG_STRING("ENC-EOS_DONE");
+		ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE,
+				VCD_S_SUCCESS, NULL, 0,	(u32 *)ddl,
+				ddl_context->client_data);
+	}
+
+	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME);
+	DDL_IDLE(ddl_context);
+}
+
+static u32 ddl_decoder_frame_run_callback(struct ddl_context
+					   *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	struct vidc_720p_dec_disp_info *dec_disp_info =
+	    &(ddl->codec_data.decoder.dec_disp_info);
+	u32 callback_end = false;
+	u32 status = true, eos_present = false;;
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) {
+		VIDC_LOG_STRING("STATE-CRITICAL-DECFRMRUN");
+		ddl_client_fatal_cb(ddl_context);
+		return true;
+	}
+
+	VIDC_LOG_STRING("DEC_FRM_RUN_DONE");
+
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+
+	vidc_720p_decode_display_info(dec_disp_info);
+
+	ddl_decode_dynamic_property(ddl, false);
+
+	if (dec_disp_info->resl_change) {
+		VIDC_LOG_STRING
+			("DEC_FRM_RUN_DONE: RECONFIG");
+		ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE);
+		ddl_move_command_state(ddl_context, DDL_CMD_EOS);
+		vidc_720p_submit_command(ddl->channel_id,
+			VIDC_720P_CMD_FRAMERUN_REALLOCATE);
+		return false;
+	}
+
+	if ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)) {
+		callback_end = false;
+		eos_present = true;
+	}
+
+
+	if (dec_disp_info->disp_status == VIDC_720P_DECODE_ONLY ||
+		dec_disp_info->disp_status
+			== VIDC_720P_DECODE_AND_DISPLAY) {
+		if (!eos_present)
+			callback_end = (dec_disp_info->disp_status
+					== VIDC_720P_DECODE_ONLY);
+
+	  ddl_decoder_input_done_callback(ddl, callback_end);
+	}
+
+	if (dec_disp_info->disp_status == VIDC_720P_DECODE_AND_DISPLAY
+		|| dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY) {
+		if (!eos_present)
+			callback_end =
+			(dec_disp_info->disp_status
+				== VIDC_720P_DECODE_AND_DISPLAY);
+
+		if (ddl_decoder_output_done_callback(ddl, callback_end)
+			!= VCD_S_SUCCESS)
+			return true;
+	}
+
+	if (dec_disp_info->disp_status ==  VIDC_720P_DISPLAY_ONLY ||
+		dec_disp_info->disp_status ==  VIDC_720P_EMPTY_BUFFER) {
+		/* send the same input once again for decoding */
+		ddl_decode_frame_run(ddl);
+		/* client need to ignore the interrupt */
+		status = false;
+	} else if (eos_present) {
+		/* send EOS command to HW */
+		ddl_decode_eos_run(ddl);
+		/* client need to ignore the interrupt */
+		status = false;
+	} else {
+		ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME);
+		/* move to Idle */
+		DDL_IDLE(ddl_context);
+	}
+	return status;
+}
+
+static u32 ddl_eos_frame_done_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl = ddl_context->current_ddl;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vidc_720p_dec_disp_info *dec_disp_info =
+		&(decoder->dec_disp_info);
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
+		VIDC_LOGERR_STRING("STATE-CRITICAL-EOSFRMRUN");
+		ddl_client_fatal_cb(ddl_context);
+		return true;
+	}
+	VIDC_LOG_STRING("EOS_FRM_RUN_DONE");
+
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+
+	vidc_720p_decode_display_info(dec_disp_info);
+
+	ddl_decode_dynamic_property(ddl, false);
+
+	if (dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY) {
+		if (ddl_decoder_output_done_callback(ddl, false)
+			!= VCD_S_SUCCESS)
+			return true;
+	} else
+		VIDC_LOG_STRING("STATE-CRITICAL-WRONG-DISP-STATUS");
+
+	ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK);
+	ddl_move_command_state(ddl_context, DDL_CMD_EOS);
+	vidc_720p_submit_command(ddl->channel_id,
+		VIDC_720P_CMD_FRAMERUN);
+	return false;
+}
+
+static void ddl_channel_end_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+
+	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
+	VIDC_LOG_STRING("CH_END_DONE");
+
+	ddl = ddl_context->current_ddl;
+	if (!ddl ||
+		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHEND)
+		) {
+		VIDC_LOG_STRING("STATE-CRITICAL-CHEND");
+		DDL_IDLE(ddl_context);
+		return;
+	}
+
+	ddl_release_client_internal_buffers(ddl);
+	ddl_context->ddl_callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS,
+		NULL, 0, (u32 *) ddl,	ddl_context->client_data);
+	ddl_move_client_state(ddl, DDL_CLIENT_OPEN);
+	DDL_IDLE(ddl_context);
+}
+
+static u32 ddl_operation_done_callback(struct ddl_context *ddl_context)
+{
+	u32 return_status = true;
+
+	switch (ddl_context->cmd_state) {
+	case DDL_CMD_DECODE_FRAME:
+		{
+			return_status = ddl_decoder_frame_run_callback(
+				ddl_context);
+			break;
+		}
+	case DDL_CMD_ENCODE_FRAME:
+		{
+			ddl_encoder_frame_run_callback(ddl_context);
+			break;
+		}
+	case DDL_CMD_CHANNEL_SET:
+		{
+			return_status = ddl_channel_set_callback(
+				ddl_context);
+			break;
+		}
+	case DDL_CMD_INIT_CODEC:
+		{
+			ddl_init_codec_done_callback(ddl_context);
+			break;
+		}
+	case DDL_CMD_HEADER_PARSE:
+		{
+			return_status = ddl_header_done_callback(
+				ddl_context);
+			break;
+		}
+	case DDL_CMD_DECODE_SET_DPB:
+		{
+			return_status = ddl_dpb_buffers_set_done_callback(
+				ddl_context);
+			break;
+		}
+	case DDL_CMD_CHANNEL_END:
+		{
+			ddl_channel_end_callback(ddl_context);
+			break;
+		}
+	case DDL_CMD_EOS:
+		{
+			return_status = ddl_eos_frame_done_callback(
+				ddl_context);
+			break;
+		}
+	case DDL_CMD_CPU_RESET:
+		{
+			ddl_cpu_started_callback(ddl_context);
+			break;
+		}
+	default:
+		{
+			VIDC_LOG_STRING("UNKWN_OPDONE");
+			return_status = false;
+			break;
+		}
+	}
+	return return_status;
+}
+
+static u32 ddl_process_intr_status(struct ddl_context *ddl_context,
+			u32 int_status)
+{
+	u32 status = true;
+	switch (int_status) {
+	case VIDC_720P_INTR_FRAME_DONE:
+		 {
+			status = ddl_operation_done_callback(ddl_context);
+			break;
+		 }
+	case VIDC_720P_INTR_DMA_DONE:
+		 {
+			ddl_dma_done_callback(ddl_context);
+			status = false;
+			break;
+		 }
+	case VIDC_720P_INTR_FW_DONE:
+		 {
+			status = ddl_eos_done_callback(ddl_context);
+			break;
+		 }
+	case VIDC_720P_INTR_BUFFER_FULL:
+		 {
+			VIDC_LOGERR_STRING("BUF_FULL_INTR");
+			ddl_hw_fatal_cb(ddl_context);
+			break;
+		 }
+	default:
+		 {
+			VIDC_LOGERR_STRING("UNKWN_INTR");
+			break;
+		 }
+	}
+	return status;
+}
+
+void ddl_read_and_clear_interrupt(void)
+{
+	struct ddl_context *ddl_context;
+
+	ddl_context = ddl_get_context();
+	if (!ddl_context->core_virtual_base_addr) {
+		VIDC_LOGERR_STRING("SPURIOUS_INTERRUPT");
+		return;
+	}
+	vidc_720p_get_interrupt_status(&ddl_context->intr_status,
+		&ddl_context->cmd_err_status,
+		&ddl_context->disp_pic_err_status,
+		&ddl_context->op_failed
+	);
+
+	vidc_720p_interrupt_done_clear();
+
+}
+
+u32 ddl_process_core_response(void)
+{
+	struct ddl_context *ddl_context;
+	u32 return_status = true;
+
+	ddl_context = ddl_get_context();
+	if (!ddl_context->core_virtual_base_addr) {
+		VIDC_LOGERR_STRING("UNKWN_INTR");
+		return false;
+	}
+
+	if (!ddl_handle_core_errors(ddl_context)) {
+		return_status = ddl_process_intr_status(ddl_context,
+			ddl_context->intr_status);
+	}
+
+	if (ddl_context->interrupt_clr)
+		(*ddl_context->interrupt_clr)();
+
+	return return_status;
+}
+
+static void ddl_decoder_input_done_callback(
+	struct	ddl_client_context *ddl, u32 frame_transact_end)
+{
+	struct vidc_720p_dec_disp_info *dec_disp_info =
+		&(ddl->codec_data.decoder.dec_disp_info);
+	struct vcd_frame_data *input_vcd_frm =
+		&(ddl->input_frame.vcd_frm);
+	ddl_get_frame(input_vcd_frm, dec_disp_info->
+		input_frame);
+
+	input_vcd_frm->interlaced = (dec_disp_info->
+		input_is_interlace);
+
+	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->ddl_context->ddl_callback(
+		VCD_EVT_RESP_INPUT_DONE,
+		VCD_S_SUCCESS,
+		&ddl->input_frame,
+		sizeof(struct ddl_frame_data_tag),
+		(void *)ddl,
+		ddl->ddl_context->client_data);
+}
+
+static u32 ddl_decoder_output_done_callback(
+	struct ddl_client_context *ddl,
+	u32 frame_transact_end)
+{
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	struct vidc_720p_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;
+	u32 free_luma_dpb = 0;
+
+	output_vcd_frm->physical = (u8 *)dec_disp_info->y_addr;
+
+	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_720p_decode_skip_frm_details(&free_luma_dpb);
+		if (free_luma_dpb)
+			output_vcd_frm->physical = (u8 *) free_luma_dpb;
+	}
+
+
+	vcd_status = ddl_decoder_dpb_transact(
+			decoder,
+			output_frame,
+			DDL_DPB_OP_MARK_BUSY);
+
+	if (vcd_status != VCD_S_SUCCESS) {
+		VIDC_LOGERR_STRING("CorruptedOutputBufferAddress");
+		ddl_hw_fatal_cb(ddl->ddl_context);
+		return vcd_status;
+	}
+
+	output_vcd_frm->ip_frm_tag =  dec_disp_info->tag_top;
+	if (dec_disp_info->crop_exists == 0x1) {
+		output_vcd_frm->dec_op_prop.disp_frm.left =
+			dec_disp_info->crop_left_offset;
+		output_vcd_frm->dec_op_prop.disp_frm.top =
+			dec_disp_info->crop_top_offset;
+		output_vcd_frm->dec_op_prop.disp_frm.right =
+			dec_disp_info->img_size_x -
+			dec_disp_info->crop_right_offset;
+		output_vcd_frm->dec_op_prop.disp_frm.bottom =
+			dec_disp_info->img_size_y -
+			dec_disp_info->crop_bottom_offset;
+	} else {
+		output_vcd_frm->dec_op_prop.disp_frm.left = 0;
+		output_vcd_frm->dec_op_prop.disp_frm.top = 0;
+		output_vcd_frm->dec_op_prop.disp_frm.right =
+			dec_disp_info->img_size_x;
+		output_vcd_frm->dec_op_prop.disp_frm.bottom =
+			dec_disp_info->img_size_y;
+	}
+	if (!dec_disp_info->disp_is_interlace) {
+		output_vcd_frm->interlaced = false;
+		output_vcd_frm->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID;
+	} else {
+		output_vcd_frm->interlaced = true;
+		output_vcd_frm->intrlcd_ip_frm_tag =
+			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;
+	ddl_process_decoder_metadata(ddl);
+	output_frame->frm_trans_end = frame_transact_end;
+
+	if (vidc_msg_timing)
+		ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
+
+	ddl->ddl_context->ddl_callback(
+		VCD_EVT_RESP_OUTPUT_DONE,
+		vcd_status,
+		output_frame,
+		sizeof(struct ddl_frame_data_tag),
+		(void *)ddl,
+		ddl->ddl_context->client_data);
+	return vcd_status;
+}
+
+static u32 ddl_get_frame
+	(struct vcd_frame_data *frame, u32 frametype) {
+	enum vidc_720p_frame vidc_frame =
+		(enum vidc_720p_frame)frametype;
+	u32 status = true;
+
+	switch (vidc_frame) {
+	case VIDC_720P_IFRAME:
+		{
+			frame->flags |= VCD_FRAME_FLAG_SYNCFRAME;
+			frame->frame = VCD_FRAME_I;
+			break;
+		}
+	case VIDC_720P_PFRAME:
+		{
+			frame->frame = VCD_FRAME_P;
+			break;
+		}
+	case VIDC_720P_BFRAME:
+		{
+			frame->frame = VCD_FRAME_B;
+			break;
+		}
+	case VIDC_720P_NOTCODED:
+		{
+			frame->frame = VCD_FRAME_NOTCODED;
+			frame->data_len = 0;
+			break;
+		}
+	default:
+		{
+			VIDC_LOG_STRING("CRITICAL-FRAMETYPE");
+			status = false;
+			break;
+		}
+	}
+	return status;
+}
+
+static void ddl_getmpeg4_declevel(enum vcd_codec_level *codec_level,
+	u32 level)
+{
+	switch (level) {
+	case VIDC_720P_MPEG4_LEVEL0:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_0;
+			break;
+		}
+	case VIDC_720P_MPEG4_LEVEL0b:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_0b;
+			break;
+		}
+	case VIDC_720P_MPEG4_LEVEL1:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_1;
+			break;
+		}
+	case VIDC_720P_MPEG4_LEVEL2:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_2;
+			break;
+		}
+	case VIDC_720P_MPEG4_LEVEL3:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_3;
+			break;
+		}
+	case VIDC_720P_MPEG4_LEVEL3b:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_3b;
+			break;
+		}
+	case VIDC_720P_MPEG4_LEVEL4a:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_4a;
+			break;
+		}
+	case VIDC_720P_MPEG4_LEVEL5:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_5;
+			break;
+		}
+	case VIDC_720P_MPEG4_LEVEL6:
+		{
+			*codec_level = VCD_LEVEL_MPEG4_6;
+			break;
+		}
+	}
+}
+
+static void ddl_geth264_declevel(enum vcd_codec_level *codec_level,
+	u32 level)
+{
+	switch (level) {
+	case VIDC_720P_H264_LEVEL1:
+		{
+			*codec_level = VCD_LEVEL_H264_1;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL1b:
+		{
+			*codec_level = VCD_LEVEL_H264_1b;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL1p1:
+		{
+			*codec_level = VCD_LEVEL_H264_1p1;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL1p2:
+		{
+			*codec_level = VCD_LEVEL_H264_1p2;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL1p3:
+		{
+			*codec_level = VCD_LEVEL_H264_1p3;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL2:
+		{
+			*codec_level = VCD_LEVEL_H264_2;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL2p1:
+		{
+			*codec_level = VCD_LEVEL_H264_2p1;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL2p2:
+		{
+			*codec_level = VCD_LEVEL_H264_2p2;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL3:
+		{
+			*codec_level = VCD_LEVEL_H264_3;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL3p1:
+		{
+			*codec_level = VCD_LEVEL_H264_3p1;
+			break;
+		}
+	case VIDC_720P_H264_LEVEL3p2:
+	{
+		*codec_level = VCD_LEVEL_H264_3p2;
+		break;
+	}
+
+	}
+}
+
+static void ddl_get_vc1_dec_level(
+	enum vcd_codec_level *codec_level, u32 level,
+	enum vcd_codec_profile vc1_profile)
+{
+	if (vc1_profile == VCD_PROFILE_VC1_ADVANCE)	{
+		switch (level) {
+		case VIDC_720P_VC1_LEVEL0:
+			{
+				*codec_level = VCD_LEVEL_VC1_A_0;
+				break;
+			}
+		case VIDC_720P_VC1_LEVEL1:
+			{
+				*codec_level = VCD_LEVEL_VC1_A_1;
+				break;
+			}
+		case VIDC_720P_VC1_LEVEL2:
+			{
+				*codec_level = VCD_LEVEL_VC1_A_2;
+				break;
+			}
+		case VIDC_720P_VC1_LEVEL3:
+			{
+				*codec_level = VCD_LEVEL_VC1_A_3;
+				break;
+			}
+		case VIDC_720P_VC1_LEVEL4:
+			{
+				*codec_level = VCD_LEVEL_VC1_A_4;
+				break;
+			}
+		}
+		return;
+	} else if (vc1_profile == VCD_PROFILE_VC1_MAIN) {
+		switch (level) {
+		case VIDC_720P_VC1_LEVEL_LOW:
+			{
+				*codec_level = VCD_LEVEL_VC1_M_LOW;
+				break;
+			}
+		case VIDC_720P_VC1_LEVEL_MED:
+			{
+				*codec_level = VCD_LEVEL_VC1_M_MEDIUM;
+				break;
+			}
+		case VIDC_720P_VC1_LEVEL_HIGH:
+			{
+				*codec_level = VCD_LEVEL_VC1_M_HIGH;
+				break;
+			}
+		}
+	} else if (vc1_profile == VCD_PROFILE_VC1_SIMPLE) {
+		switch (level) {
+		case VIDC_720P_VC1_LEVEL_LOW:
+			{
+				*codec_level = VCD_LEVEL_VC1_S_LOW;
+				break;
+			}
+		case VIDC_720P_VC1_LEVEL_MED:
+			{
+				*codec_level = VCD_LEVEL_VC1_S_MEDIUM;
+				break;
+			}
+		}
+	}
+}
+
+static void ddl_get_mpeg2_dec_level(enum vcd_codec_level *codec_level,
+								 u32 level)
+{
+	switch (level) {
+	case VIDCL_720P_MPEG2_LEVEL_LOW:
+		{
+			*codec_level = VCD_LEVEL_MPEG2_LOW;
+			break;
+		}
+	case VIDCL_720P_MPEG2_LEVEL_MAIN:
+		{
+			*codec_level = VCD_LEVEL_MPEG2_MAIN;
+			break;
+		}
+	case VIDCL_720P_MPEG2_LEVEL_HIGH14:
+		{
+			*codec_level = VCD_LEVEL_MPEG2_HIGH_14;
+			break;
+		}
+	}
+}
+
+static void ddl_getdec_profilelevel(struct ddl_decoder_data *decoder,
+		u32 profile, u32 level)
+{
+	enum vcd_codec_profile codec_profile = VCD_PROFILE_UNKNOWN;
+	enum vcd_codec_level codec_level = VCD_LEVEL_UNKNOWN;
+
+	switch (decoder->codec.codec) {
+	case VCD_CODEC_MPEG4:
+		{
+			if (profile == VIDC_720P_PROFILE_MPEG4_SP)
+				codec_profile = VCD_PROFILE_MPEG4_SP;
+			else if (profile == VIDC_720P_PROFILE_MPEG4_ASP)
+				codec_profile = VCD_PROFILE_MPEG4_ASP;
+
+			ddl_getmpeg4_declevel(&codec_level, level);
+			break;
+		}
+	case VCD_CODEC_H264:
+		{
+			if (profile == VIDC_720P_PROFILE_H264_BASELINE)
+				codec_profile = VCD_PROFILE_H264_BASELINE;
+			else if (profile == VIDC_720P_PROFILE_H264_MAIN)
+				codec_profile = VCD_PROFILE_H264_MAIN;
+			else if (profile == VIDC_720P_PROFILE_H264_HIGH)
+				codec_profile = VCD_PROFILE_H264_HIGH;
+			ddl_geth264_declevel(&codec_level, level);
+			break;
+		}
+	default:
+	case VCD_CODEC_H263:
+		{
+			break;
+		}
+	case VCD_CODEC_VC1:
+	case VCD_CODEC_VC1_RCV:
+		{
+			if (profile == VIDC_720P_PROFILE_VC1_SP)
+				codec_profile = VCD_PROFILE_VC1_SIMPLE;
+			else if (profile == VIDC_720P_PROFILE_VC1_MAIN)
+				codec_profile = VCD_PROFILE_VC1_MAIN;
+			else if (profile == VIDC_720P_PROFILE_VC1_ADV)
+				codec_profile = VCD_PROFILE_VC1_ADVANCE;
+			ddl_get_vc1_dec_level(&codec_level, level, profile);
+			break;
+		}
+	case VCD_CODEC_MPEG2:
+		{
+			if (profile == VIDC_720P_PROFILE_MPEG2_MAIN)
+				codec_profile = VCD_PROFILE_MPEG2_MAIN;
+			else if (profile == VIDC_720P_PROFILE_MPEG2_SP)
+				codec_profile = VCD_PROFILE_MPEG2_SIMPLE;
+			ddl_get_mpeg2_dec_level(&codec_level, level);
+			break;
+		}
+	}
+
+	decoder->profile.profile = codec_profile;
+	decoder->level.level = codec_level;
+}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
new file mode 100644
index 0000000..376ea6d
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c
@@ -0,0 +1,580 @@
+/* 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_type.h"
+#include "vcd_ddl_utils.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->channel_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_t sz = 0;
+
+	if (!flag) {
+		decoder->suffix = 0;
+		return;
+	}
+
+	if (flag & VCD_METADATA_QPARRAY) {
+		u32 num_of_mb =
+		    ((frame_size->width * frame_size->height) >> 8);
+		sz = DDL_METADATA_HDR_SIZE;
+		sz += num_of_mb;
+		DDL_METADATA_ALIGNSIZE(sz);
+		suffix += sz;
+	}
+	if (flag & VCD_METADATA_CONCEALMB) {
+		u32 num_of_mb =
+		    ((frame_size->width * frame_size->height) >> 8);
+		sz = DDL_METADATA_HDR_SIZE + (num_of_mb >> 3);
+		DDL_METADATA_ALIGNSIZE(sz);
+		suffix += sz;
+	}
+	if (flag & VCD_METADATA_VC1) {
+		sz = DDL_METADATA_HDR_SIZE;
+		sz += DDL_METADATA_VC1_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(sz);
+		suffix += sz;
+	}
+	if (flag & VCD_METADATA_SEI) {
+		sz = DDL_METADATA_HDR_SIZE;
+		sz += DDL_METADATA_SEI_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(sz);
+		suffix += (sz * DDL_METADATA_SEI_MAX);
+	}
+	if (flag & VCD_METADATA_VUI) {
+		sz = DDL_METADATA_HDR_SIZE;
+		sz += DDL_METADATA_VUI_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(sz);
+		suffix += (sz);
+	}
+	if (flag & VCD_METADATA_PASSTHROUGH) {
+		sz = DDL_METADATA_HDR_SIZE;
+		sz += DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE;
+		DDL_METADATA_ALIGNSIZE(sz);
+		suffix += (sz);
+	}
+	sz = DDL_METADATA_EXTRADATANONE_SIZE;
+	DDL_METADATA_ALIGNSIZE(sz);
+	suffix += (sz);
+
+	suffix += DDL_METADATA_EXTRAPAD_SIZE;
+	DDL_METADATA_ALIGNSIZE(suffix);
+
+	decoder->suffix = suffix;
+	output_buf_req->sz += suffix;
+	return;
+}
+
+void ddl_set_default_encoder_metadata_buffer_size(struct ddl_encoder_data
+						  *encoder)
+{
+	u32 flag = encoder->meta_data_enable_flag;
+	u32 suffix = 0;
+	size_t sz = 0;
+
+	if (!flag) {
+		encoder->suffix = 0;
+		return;
+	}
+
+	if (flag & VCD_METADATA_ENC_SLICE) {
+		u32 num_of_mb = (encoder->frame_size.width *
+				   encoder->frame_size.height / 16 / 16);
+		sz = DDL_METADATA_HDR_SIZE;
+
+		sz += 4;
+
+		sz += (8 * num_of_mb);
+		DDL_METADATA_ALIGNSIZE(sz);
+		suffix += sz;
+	}
+
+	sz = DDL_METADATA_EXTRADATANONE_SIZE;
+	DDL_METADATA_ALIGNSIZE(sz);
+	suffix += (sz);
+
+	suffix += DDL_METADATA_EXTRAPAD_SIZE;
+	DDL_METADATA_ALIGNSIZE(suffix);
+
+	encoder->suffix = suffix;
+	encoder->output_buf_req.sz += suffix;
+}
+
+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 (flag != *meta_data_enable_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_metadata_enable(struct ddl_client_context *ddl)
+{
+	u32 flag, hal_flag = 0;
+	u32 *metadata_input;
+	if (ddl->decoding) {
+		flag = ddl->codec_data.decoder.meta_data_enable_flag;
+		metadata_input =
+		    ddl->codec_data.decoder.meta_data_input.
+		    align_physical_addr;
+	} else {
+		flag = ddl->codec_data.encoder.meta_data_enable_flag;
+		metadata_input =
+		    ddl->codec_data.encoder.meta_data_input.
+		    align_physical_addr;
+	}
+	if (flag) {
+		if (flag & VCD_METADATA_QPARRAY)
+			hal_flag |= VIDC_720P_METADATA_ENABLE_QP;
+		if (flag & VCD_METADATA_CONCEALMB)
+			hal_flag |= VIDC_720P_METADATA_ENABLE_CONCEALMB;
+		if (flag & VCD_METADATA_VC1)
+			hal_flag |= VIDC_720P_METADATA_ENABLE_VC1;
+		if (flag & VCD_METADATA_SEI)
+			hal_flag |= VIDC_720P_METADATA_ENABLE_SEI;
+		if (flag & VCD_METADATA_VUI)
+			hal_flag |= VIDC_720P_METADATA_ENABLE_VUI;
+		if (flag & VCD_METADATA_ENC_SLICE)
+			hal_flag |= VIDC_720P_METADATA_ENABLE_ENCSLICE;
+		if (flag & VCD_METADATA_PASSTHROUGH)
+			hal_flag |= VIDC_720P_METADATA_ENABLE_PASSTHROUGH;
+	} else {
+		metadata_input = 0;
+	}
+	vidc_720p_metadata_enable(hal_flag, metadata_input);
+}
+
+u32 ddl_encode_set_metadata_output_buf(struct ddl_client_context *ddl)
+{
+	struct ddl_encoder_data *encoder = &ddl->codec_data.encoder;
+	u32 *buffer;
+	struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm);
+	u32 ext_buffer_end, hw_metadata_start;
+
+	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 = encoder->meta_data_input.align_virtual_addr;
+
+	*buffer++ = encoder->suffix;
+
+	*buffer = hw_metadata_start;
+
+	encoder->meta_data_offset =
+	    hw_metadata_start - (u32) stream->physical;
+
+	return ext_buffer_end;
+}
+
+void ddl_decode_set_metadata_output(struct ddl_decoder_data *decoder)
+{
+	u32 *buffer;
+	u32 loopc;
+
+	if (!decoder->meta_data_enable_flag) {
+		decoder->meta_data_offset = 0;
+		return;
+	}
+
+	decoder->meta_data_offset = ddl_get_yuv_buffer_size(
+		&decoder->client_frame_size, &decoder->buf_format,
+		(!decoder->progressive_only), decoder->codec.codec);
+
+	buffer = decoder->meta_data_input.align_virtual_addr;
+
+	*buffer++ = decoder->suffix;
+
+	for (loopc = 0; loopc < decoder->dp_buf.no_of_dec_pic_buf;
+	     ++loopc) {
+		*buffer++ = (u32) (decoder->meta_data_offset + (u8 *)
+				     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.metadata_exists) {
+		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
+		return;
+	}
+	out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
+
+	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->dec_disp_info.metadata_exists) {
+		output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
+		return;
+	}
+	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/720p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
new file mode 100644
index 0000000..ed43861
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h
@@ -0,0 +1,79 @@
+/* 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 = (u32 *)\
+	((u8 *)(main_buffer)->align_physical_addr + \
+	(DDL_METADATA_CLIENT_INPUTBUFSIZE * (channel_id)) \
+	); \
+  (client_buffer)->align_virtual_addr = (u32 *)\
+	((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_metadata_enable(struct ddl_client_context *ddl);
+u32 ddl_encode_set_metadata_output_buf(struct ddl_client_context *ddl);
+void ddl_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/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
new file mode 100644
index 0000000..73dba03
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c
@@ -0,0 +1,1919 @@
+/* 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 "vidc_type.h"
+#include "vcd_ddl_utils.h"
+#include "vcd_ddl_metadata.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)
+{
+	u32 vcd_status;
+	struct ddl_context *ddl_context;
+	struct ddl_client_context *ddl =
+	    (struct ddl_client_context *)ddl_handle;
+
+	if (!property_hdr || !property_value) {
+		VIDC_LOGERR_STRING("ddl_set_prop:Bad_argument");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	ddl_context = ddl_get_context();
+
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		VIDC_LOGERR_STRING("ddl_set_prop:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if (!ddl) {
+		VIDC_LOGERR_STRING("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)
+		VIDC_LOGERR_STRING("ddl_set_prop:FAILED");
+
+	return vcd_status;
+}
+
+u32 ddl_get_property(u32 *ddl_handle,
+     struct vcd_property_hdr *property_hdr, void *property_value)
+{
+
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+	struct ddl_context *ddl_context;
+	struct ddl_client_context *ddl =
+	    (struct ddl_client_context *)ddl_handle;
+
+	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_GENERAL_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)
+		VIDC_LOGERR_STRING("ddl_get_prop:FAILED");
+
+	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) {
+		VIDC_LOGERR_STRING("ddl_dec_start_check:Codec_not_set");
+		return false;
+	}
+	if ((!header) &&
+	    (!decoder->client_frame_size.height ||
+	     !decoder->client_frame_size.width)
+	    ) {
+		VIDC_LOGERR_STRING
+		    ("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;
+	}
+	return true;
+}
+
+static u32 ddl_set_dec_property
+    (struct ddl_client_context *ddl,
+     struct vcd_property_hdr *property_hdr, void *property_value) {
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
+	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 &&
+			    (ddl_valid_buffer_requirement(
+						&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;
+		}
+	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(
+						&decoder->min_output_buf_req,
+						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;
+		}
+
+	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)
+			    ) {
+				u32 status;
+				vcd_fw_transact(false, true,
+					decoder->codec.codec);
+				status = vcd_fw_transact(true, true,
+					codec->codec);
+				if (status) {
+					decoder->codec = *codec;
+					ddl_set_default_dec_property(ddl);
+					vcd_status = VCD_S_SUCCESS;
+				} else {
+					status = vcd_fw_transact(true, true,
+						decoder->codec.codec);
+					vcd_status = VCD_ERR_NOT_SUPPORTED;
+				}
+			}
+			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))) {
+				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);
+				}
+				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_NV12
+			     || 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_METADATA_ENABLE:
+	case VCD_I_METADATA_HEADER:
+		{
+			vcd_status = ddl_set_metadata_params(ddl,
+							     property_hdr,
+							     property_value);
+			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_FRAME_RATE:
+		{
+			vcd_status = VCD_S_SUCCESS;
+			break;
+		}
+	default:
+		{
+			vcd_status = VCD_ERR_ILLEGAL_OP;
+			break;
+		}
+	}
+	return vcd_status;
+}
+
+static u32 ddl_set_enc_property(struct ddl_client_context *ddl,
+	struct vcd_property_hdr *property_hdr, void *property_value)
+{
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+
+	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 == VCD_S_SUCCESS)
+		return vcd_status;
+
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) ||
+		vcd_status != VCD_ERR_ILLEGAL_OP) {
+		VIDC_LOGERR_STRING
+			("ddl_set_enc_property:Fails_as_not_in_open_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	switch (property_hdr->prop_id) {
+	case VCD_I_FRAME_SIZE:
+		{
+			struct vcd_property_frame_size *framesize =
+				(struct vcd_property_frame_size *)
+				property_value;
+
+			if (sizeof(struct vcd_property_frame_size)
+				== property_hdr->sz &&
+				DDL_ALLOW_ENC_FRAMESIZE(framesize->width,
+				framesize->height) &&
+				(encoder->codec.codec == VCD_CODEC_H264 ||
+				 DDL_VALIDATE_ENC_FRAMESIZE(framesize->width,
+				 framesize->height))
+				) {
+				encoder->frame_size = *framesize;
+				ddl_calculate_stride(&encoder->frame_size,
+					false, encoder->codec.codec);
+				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) {
+				u32 status;
+
+				vcd_fw_transact(false, false,
+					encoder->codec.codec);
+
+				status = vcd_fw_transact(true, false,
+					codec->codec);
+				if (status) {
+					encoder->codec = *codec;
+					ddl_set_default_enc_property(ddl);
+					vcd_status = VCD_S_SUCCESS;
+				} else {
+					status = vcd_fw_transact(true, false,
+						encoder->codec.codec);
+					vcd_status = VCD_ERR_NOT_SUPPORTED;
+				}
+			}
+			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
+				) &&
+				(
+				(
+				(encoder->codec.
+				 codec == VCD_CODEC_MPEG4) &&
+				(level->level >= VCD_LEVEL_MPEG4_0) &&
+				(level->level <= VCD_LEVEL_MPEG4_6)
+				) ||
+				(
+				(encoder->codec.
+				 codec == VCD_CODEC_H264) &&
+				(level->level >= VCD_LEVEL_H264_1) &&
+				(level->level <= VCD_LEVEL_H264_3p1)
+				) ||
+				(
+				(encoder->codec.
+				 codec == VCD_CODEC_H263) &&
+				(level->level >= VCD_LEVEL_H263_10) &&
+				(level->level <= VCD_LEVEL_H263_70)
+				)
+				)
+				) {
+				encoder->level = *level;
+				vcd_status = VCD_S_SUCCESS;
+			}
+			break;
+		}
+	case VCD_I_MULTI_SLICE:
+		{
+			struct vcd_property_multi_slice *multislice =
+				(struct vcd_property_multi_slice *)
+				property_value;
+			switch (multislice->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 (multislice->m_slice_size
+						>= 1 && (multislice->
+						m_slice_size <=
+						(encoder->frame_size.height
+						* encoder->frame_size.width
+						/ 16 / 16))
+						) {
+						vcd_status = VCD_S_SUCCESS;
+					}
+					break;
+				  }
+			case VCD_MSLICE_BY_BYTE_COUNT:
+				{
+					if (multislice->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 = *multislice;
+				if (multislice->m_slice_sel ==
+						VCD_MSLICE_OFF)
+					encoder->multi_slice.m_slice_size = 0;
+			}
+			break;
+		}
+	case VCD_I_RATE_CONTROL:
+		{
+			struct vcd_property_rate_control
+				*ratecontrol =
+				(struct vcd_property_rate_control *)
+				property_value;
+			if (sizeof(struct vcd_property_rate_control) ==
+				property_hdr->sz &&
+				ratecontrol->
+				rate_control >= VCD_RATE_CONTROL_OFF &&
+				ratecontrol->
+				rate_control <= VCD_RATE_CONTROL_CBR_CFR
+				) {
+				encoder->rc = *ratecontrol;
+				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 *voptime =
+				(struct vcd_property_vop_timing *)
+				property_value;
+			if (
+				(sizeof(struct vcd_property_vop_timing) ==
+					  property_hdr->sz
+				) &&
+				(encoder->frame_rate.fps_numerator <=
+					voptime->vop_time_resolution)
+				) {
+				encoder->vop_timing = *voptime;
+				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) {
+				encoder->entropy_control = *entropy_control;
+				vcd_status = VCD_S_SUCCESS;
+			}
+			break;
+		}
+	case VCD_I_DEBLOCKING:
+		{
+			struct vcd_property_db_config *dbconfig =
+				(struct vcd_property_db_config *)
+				property_value;
+			if (sizeof(struct vcd_property_db_config) ==
+				property_hdr->sz &&
+				encoder->codec.codec == VCD_CODEC_H264
+				&& dbconfig->db_config >=
+				VCD_DB_ALL_BLOCKING_BOUNDARY
+				&& dbconfig->db_config <=
+				VCD_DB_SKIP_SLICE_BOUNDARY
+				) {
+				encoder->db_control = *dbconfig;
+				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_levelrc =
+			(struct vcd_property_frame_level_rc_params *)
+			property_value;
+
+			if ((sizeof(struct
+				vcd_property_frame_level_rc_params)
+				== property_hdr->sz) &&
+				(frame_levelrc->reaction_coeff) &&
+				(encoder->rc_level.frame_level_rc)
+				) {
+				encoder->frame_level_rc = *frame_levelrc;
+				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 *tile =
+				(struct vcd_property_buffer_format *)
+				property_value;
+			if (sizeof(struct vcd_property_buffer_format) ==
+				property_hdr->sz &&
+				tile->buffer_format ==
+				VCD_BUFFER_FORMAT_NV12) {
+				encoder->buf_format = *tile;
+				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;
+				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;
+		}
+	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.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;
+		}
+	case VCD_I_METADATA_ENABLE:
+	case VCD_I_METADATA_HEADER:
+		{
+			vcd_status = ddl_set_metadata_params(
+				ddl, property_hdr, property_value);
+			break;
+		}
+	default:
+		{
+			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) {
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+
+	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;
+					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) {
+				struct vcd_property_frame_size frame_sz =
+					decoder->client_frame_size;
+				ddl_calculate_stride(&frame_sz,
+					!decoder->progressive_only,
+					decoder->codec.codec);
+				*(u32 *) property_value =
+				    ((frame_sz.stride >> 4) *
+				     (frame_sz.scan_lines >> 4));
+				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_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:
+		{
+			vcd_status = ddl_get_metadata_params(
+						   ddl,
+						   property_hdr,
+						   property_value);
+			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) {
+	u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
+	struct ddl_encoder_data *encoder = &ddl->codec_data.encoder;
+
+	struct vcd_property_entropy_control *entropy_control;
+	struct vcd_property_intra_refresh_mb_number *intra_refresh;
+
+	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.buffer_size &&
+			    sizeof(struct vcd_sequence_hdr) ==
+			    property_hdr->sz
+			    && encoder->seq_header.buffer_size <=
+			    seq_hdr->sequence_header_len) {
+				DDL_MEMCPY(seq_hdr->sequence_header,
+					   encoder->seq_header.
+					   align_virtual_addr,
+					   encoder->seq_header.buffer_size);
+				seq_hdr->sequence_header_len =
+				    encoder->seq_header.buffer_size;
+				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:
+		{
+			entropy_control = property_value;
+			if (sizeof(struct vcd_property_entropy_control) ==
+			    property_hdr->sz) {
+				if (encoder->codec.codec ==
+					VCD_CODEC_H264) {
+					*entropy_control =
+				     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:
+		{
+			intra_refresh = property_value;
+			if (sizeof
+			    (struct vcd_property_intra_refresh_mb_number)
+			    == property_hdr->sz) {
+				*intra_refresh = 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;
+				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) {
+				*(u32 *) property_value =
+				    ((encoder->frame_size.width >> 4) *
+				     (encoder->frame_size.height >> 4)
+				    );
+				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_METADATA_ENABLE:
+	case VCD_I_METADATA_HEADER:
+		{
+			vcd_status = ddl_get_metadata_params(
+						   ddl,
+						   property_hdr,
+						   property_value);
+			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, 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 > 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;
+			}
+			break;
+		}
+	case VCD_I_INTRA_PERIOD:
+		{
+			struct vcd_property_i_period *iperiod =
+				(struct vcd_property_i_period *)
+				property_value;
+			if (sizeof(struct vcd_property_i_period) ==
+				property_hdr->sz &&
+				!iperiod->b_frames) {
+				encoder->i_period = *iperiod;
+				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;
+			}
+			break;
+		}
+	case VCD_I_INTRA_REFRESH:
+		{
+			struct vcd_property_intra_refresh_mb_number
+				*intra_refresh_mbnum = (
+				struct vcd_property_intra_refresh_mb_number *)
+					property_value;
+			u32 frame_mbnum =
+				(encoder->frame_size.width >> 4) *
+				(encoder->frame_size.height >> 4);
+			if (sizeof(struct
+				vcd_property_intra_refresh_mb_number)
+				== property_hdr->sz &&
+				intra_refresh_mbnum->cir_mb_number <=
+				frame_mbnum) {
+				encoder->intra_refresh =
+					*intra_refresh_mbnum;
+				dynamic_prop_change = DDL_ENC_CHANGE_CIR;
+				vcd_status = VCD_S_SUCCESS;
+			}
+
+			break;
+		}
+	default:
+		{
+			vcd_status = VCD_ERR_ILLEGAL_OP;
+			break;
+		}
+	}
+	if (vcd_status == VCD_S_SUCCESS &&
+	(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_MPEG4 ||
+	    decoder->codec.codec == VCD_CODEC_MPEG2)
+		decoder->post_filter.post_filter = true;
+	else
+		decoder->post_filter.post_filter = false;
+	decoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12;
+	decoder->client_frame_size.height = 144;
+	decoder->client_frame_size.width = 176;
+	decoder->client_frame_size.stride = 176;
+	decoder->client_frame_size.scan_lines = 144;
+	decoder->progressive_only = 1;
+	decoder->profile.profile = VCD_PROFILE_UNKNOWN;
+	decoder->level.level = VCD_LEVEL_UNKNOWN;
+	decoder->output_order = VCD_DEC_ORDER_DISPLAY;
+	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;
+	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->re_con_buf_format.buffer_format =
+		VCD_BUFFER_FORMAT_TILE_4x2;
+
+	encoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12;
+
+	encoder->hdr_ext_control = 0;
+
+	ddl_set_default_metadata_flag(ddl);
+
+	ddl_set_default_encoder_buffer_req(encoder);
+}
+
+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 =
+		    (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(
+		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 = 0;
+}
+
+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.max_qp = 0x33;
+		encoder->session_qp.i_frame_qp = 0x14;
+		encoder->session_qp.p_frame_qp = 0x14;
+
+		encoder->rc_level.mb_level_rc = true;
+		encoder->adaptive_rc.activity_region_flag = true;
+		encoder->adaptive_rc.dark_region_as_flag = true;
+		encoder->adaptive_rc.smooth_region_as_flag = true;
+		encoder->adaptive_rc.static_region_as_flag = true;
+	} else {
+		encoder->qp_range.max_qp = 0x1f;
+		encoder->session_qp.i_frame_qp = 0xd;
+		encoder->session_qp.p_frame_qp = 0xd;
+		encoder->rc_level.mb_level_rc = false;
+	}
+
+	switch (encoder->rc.rate_control) {
+	default:
+	case VCD_RATE_CONTROL_VBR_VFR:
+		{
+			encoder->r_cframe_skip = 1;
+			encoder->frame_level_rc.reaction_coeff = 0x1f4;
+			break;
+		}
+	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->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;
+		}
+	}
+}
+
+void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data *encoder)
+{
+	u32 y_cb_cr_size;
+
+	y_cb_cr_size = ddl_get_yuv_buffer_size(&encoder->frame_size,
+		&encoder->buf_format, false, encoder->codec.codec);
+
+	memset(&encoder->input_buf_req, 0,
+	       sizeof(struct vcd_buffer_requirement));
+
+	encoder->input_buf_req.min_count = 1;
+	encoder->input_buf_req.actual_count =
+	    encoder->input_buf_req.min_count + 8;
+	encoder->input_buf_req.max_count = DDL_MAX_BUFFER_COUNT;
+	encoder->input_buf_req.sz = y_cb_cr_size;
+	encoder->input_buf_req.align = DDL_LINEAR_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 = 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;
+	encoder->output_buf_req.sz = y_cb_cr_size;
+	ddl_set_default_encoder_metadata_buffer_size(encoder);
+	encoder->client_output_buf_req = encoder->output_buf_req;
+}
+
+void ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder,
+		u32 estimate)
+{
+	u32 y_cb_cr_size, min_dpb, num_mb;
+	struct vcd_property_frame_size  *frame_size;
+	struct vcd_buffer_requirement *output_buf_req, *input_buf_req;
+
+	if (!decoder->codec.codec)
+		return;
+
+	if (estimate) {
+		frame_size = &decoder->client_frame_size;
+		output_buf_req = &decoder->client_output_buf_req;
+		input_buf_req = &decoder->client_input_buf_req;
+		min_dpb = ddl_decoder_min_num_dpb(decoder);
+		 y_cb_cr_size = ddl_get_yuv_buffer_size(frame_size,
+			&decoder->buf_format, (!decoder->progressive_only),
+			decoder->codec.codec);
+	} else {
+		frame_size = &decoder->frame_size;
+		output_buf_req = &decoder->actual_output_buf_req;
+		input_buf_req = &decoder->actual_input_buf_req;
+		y_cb_cr_size = decoder->y_cb_cr_size;
+		min_dpb = decoder->min_dpb_num;
+	}
+
+	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;
+
+	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)
+		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 + 3;
+	input_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
+	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;
+
+}
+
+u32 ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size,
+     struct vcd_property_buffer_format *buf_format, u32 inter_lace,
+     enum vcd_codec codec)
+{
+	struct vcd_property_frame_size frame_sz = *frame_size;
+	u32 total_memory_size;
+	ddl_calculate_stride(&frame_sz, inter_lace, codec);
+
+	if (buf_format->buffer_format != VCD_BUFFER_FORMAT_NV12) {
+		u32 component_mem_size;
+		u32 width_round_up;
+		u32 height_round_up;
+		u32 height_chroma = (frame_sz.scan_lines >> 1);
+
+		width_round_up =
+		    DDL_TILE_ALIGN(frame_sz.stride, DDL_TILE_ALIGN_WIDTH);
+		height_round_up =
+		    DDL_TILE_ALIGN(frame_sz.scan_lines, DDL_TILE_ALIGN_HEIGHT);
+
+		component_mem_size = width_round_up * height_round_up;
+		component_mem_size = DDL_TILE_ALIGN(component_mem_size,
+						      DDL_TILE_MULTIPLY_FACTOR);
+
+		total_memory_size = ((component_mem_size +
+					 DDL_TILE_BUF_ALIGN_GUARD_BYTES) &
+					DDL_TILE_BUF_ALIGN_MASK);
+
+		height_round_up =
+		    DDL_TILE_ALIGN(height_chroma, DDL_TILE_ALIGN_HEIGHT);
+		component_mem_size = width_round_up * height_round_up;
+		component_mem_size = DDL_TILE_ALIGN(component_mem_size,
+						      DDL_TILE_MULTIPLY_FACTOR);
+		total_memory_size += component_mem_size;
+	} else {
+		total_memory_size = frame_sz.scan_lines * frame_sz.stride;
+		total_memory_size += (total_memory_size >> 1);
+	}
+	return total_memory_size;
+}
+
+void ddl_calculate_stride(struct vcd_property_frame_size *frame_size,
+	u32 interlace, enum vcd_codec codec)
+{
+	frame_size->stride = ((frame_size->width + 15) >> 4) << 4;
+	if (!interlace || codec == VCD_CODEC_MPEG4 ||
+		codec == VCD_CODEC_DIVX_4 ||
+		codec == VCD_CODEC_DIVX_5 ||
+		codec == VCD_CODEC_DIVX_6 ||
+		codec == VCD_CODEC_XVID) {
+		frame_size->scan_lines =
+			((frame_size->height + 15) >> 4) << 4;
+	} else {
+		frame_size->scan_lines =
+			((frame_size->height + 31) >> 5) << 5;
+	}
+
+}
+
+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 <= req_buf_req->align &&
+		original_buf_req->sz <= req_buf_req->sz) {
+		status = true;
+	} else {
+		VIDC_LOGERR_STRING("ddl_valid_buf_req:Failed");
+	}
+	return status;
+}
+
+static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder)
+{
+	u32 min_dpb = 0, yuv_size = 0;
+	struct vcd_property_frame_size frame_sz = decoder->client_frame_size;
+	switch (decoder->codec.codec) {
+	default:
+	case VCD_CODEC_MPEG4:
+	case VCD_CODEC_MPEG2:
+	case VCD_CODEC_DIVX_4:
+	case VCD_CODEC_DIVX_5:
+	case VCD_CODEC_DIVX_6:
+	case VCD_CODEC_XVID:
+		{
+			min_dpb = 3;
+			break;
+		}
+	case VCD_CODEC_H263:
+		{
+			min_dpb = 2;
+			break;
+		}
+	case VCD_CODEC_VC1:
+	case VCD_CODEC_VC1_RCV:
+		{
+			min_dpb = 4;
+			break;
+		}
+	case VCD_CODEC_H264:
+		{
+			ddl_calculate_stride(&frame_sz,
+				!decoder->progressive_only,
+				decoder->codec.codec);
+			yuv_size =
+			    ((frame_sz.scan_lines *
+			      frame_sz.stride * 3) >> 1);
+			min_dpb = 6912000 / yuv_size;
+			if (min_dpb > 16)
+				min_dpb = 16;
+
+			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;
+	u32 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) {
+		VIDC_LOGERR_STRING
+		    ("ddl_set_prop:Dpb_align_fail_or_alloc_size_small");
+		return vcd_status;
+	}
+	if (decoder->dp_buf.no_of_dec_pic_buf) {
+		DDL_FREE(decoder->dp_buf.dec_pic_buffers);
+		decoder->dp_buf.no_of_dec_pic_buf = 0;
+	}
+	decoder->dp_buf.dec_pic_buffers =
+	    DDL_MALLOC(dpb->no_of_dec_pic_buf *
+		       sizeof(struct ddl_frame_data_tag));
+
+	if (!decoder->dp_buf.dec_pic_buffers) {
+		VIDC_LOGERR_STRING
+		    ("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;
+		vcd_fw_transact(true, true,
+			ddl->codec_data.decoder.codec.codec);
+		ddl_set_default_dec_property(ddl);
+	} else {
+		struct ddl_encoder_data *encoder =
+		    &(ddl->codec_data.encoder);
+		encoder->codec.codec = VCD_CODEC_MPEG4;
+		vcd_fw_transact(true, false,
+			encoder->codec.codec);
+
+		encoder->target_bit_rate.target_bitrate = 64000;
+		encoder->frame_size.width = 176;
+		encoder->frame_size.height = 144;
+		encoder->frame_size.stride = 176;
+		encoder->frame_size.scan_lines = 144;
+		encoder->frame_rate.fps_numerator = 30;
+		encoder->frame_rate.fps_denominator = 1;
+		ddl_set_default_enc_property(ddl);
+	}
+
+	return;
+}
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
new file mode 100644
index 0000000..3b4528f
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c
@@ -0,0 +1,223 @@
+/* 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 <linux/memory_alloc.h>
+#include "vidc_type.h"
+#include "vcd_ddl_utils.h"
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+#define DBG_TIME(x...) printk(KERN_DEBUG x)
+#define ERR(x...) printk(KERN_ERR x)
+
+struct time_data {
+	unsigned int ddl_t1;
+	unsigned int ddl_ttotal;
+	unsigned int ddl_count;
+};
+
+static struct time_data proc_time[MAX_TIME_DATA];
+
+#ifdef NO_IN_KERNEL_PMEM
+
+void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align)
+{
+	u32 guard_bytes, align_mask;
+	u32 physical_addr, align_offset;
+	dma_addr_t phy_addr;
+
+	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;
+	}
+
+	buff_addr->virtual_base_addr =
+		kmalloc((sz + guard_bytes), GFP_KERNEL);
+
+	if (!buff_addr->virtual_base_addr) {
+		ERR("\n ERROR %s:%u kamlloc fails to allocate"
+			" sz + guard_bytes = %u\n", __func__, __LINE__,
+			(sz + guard_bytes));
+		return;
+	}
+
+	phy_addr = dma_map_single(NULL, buff_addr->virtual_base_addr,
+				  sz + guard_bytes, DMA_TO_DEVICE);
+
+	buff_addr->buffer_size = sz;
+	physical_addr = (u32) phy_addr;
+	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_virtual_addr =
+	    (u32 *) ((u32) (buff_addr->virtual_base_addr)
+		     + align_offset);
+}
+
+void ddl_pmem_free(struct ddl_buf_addr *buff_addr)
+{
+	kfree(buff_addr->virtual_base_addr);
+	buff_addr->buffer_size = 0;
+	buff_addr->virtual_base_addr = NULL;
+}
+
+#else
+
+void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align)
+{
+	u32 guard_bytes, align_mask;
+	u32 physical_addr;
+	u32 align_offset;
+	u32 alloc_size;
+	struct ddl_context *ddl_context;
+
+	if (!buff_addr) {
+		ERR("\n%s() Invalid Parameters", __func__);
+		return;
+	}
+
+	DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
+
+	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;
+	}
+	ddl_context = ddl_get_context();
+	alloc_size = sz + guard_bytes;
+
+	physical_addr = (u32)
+		allocate_contiguous_memory_nomap(alloc_size,
+					ddl_context->memtype, SZ_4K);
+
+	if (!physical_addr) {
+		pr_err("%s(): could not allocate kernel pmem buffers\n",
+		       __func__);
+		goto bailout;
+	}
+	buff_addr->physical_base_addr = (u32 *) physical_addr;
+
+	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__);
+			free_contiguous_memory_by_paddr(
+				(unsigned long) 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_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);
+
+	return;
+bailout:
+	buff_addr->physical_base_addr = NULL;
+	buff_addr->virtual_base_addr = NULL;
+	buff_addr->buffer_size = 0;
+}
+
+void ddl_pmem_free(struct ddl_buf_addr *buff_addr)
+{
+	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,
+		buff_addr->buffer_size);
+
+	if (buff_addr->virtual_base_addr)
+		iounmap((void *)buff_addr->virtual_base_addr);
+	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;
+}
+#endif
+
+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;
+		DBG("\n%s(): Start Time (%u)", func_name, act_time);
+	} else {
+		DBG_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++;
+		DBG_TIME("\n%s(): cnt(%u) Diff(%u) Avg(%u)",
+			func_name, time_data->ddl_count,
+			ddl_t2 - time_data->ddl_t1,
+			time_data->ddl_ttotal/time_data->ddl_count);
+		time_data->ddl_t1 = 0;
+	}
+}
+
+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/720p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
new file mode 100644
index 0000000..4d39ef0
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h
@@ -0,0 +1,60 @@
+/* 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 _VCD_DDL_UTILS_H_
+#define _VCD_DDL_UTILS_H_
+
+#include "vcd_ddl_core.h"
+#include "vcd_ddl.h"
+
+extern u32 vidc_msg_pmem;
+extern u32 vidc_msg_timing;
+
+enum timing_data {
+	DEC_OP_TIME,
+	DEC_IP_TIME,
+	ENC_OP_TIME,
+	MAX_TIME_DATA
+};
+
+#define DDL_INLINE
+
+#define DDL_ALIGN_SIZE(sz, guard_bytes, align_mask) \
+  (((u32)(sz) + guard_bytes) & align_mask)
+
+#define DDL_MALLOC(x)  kmalloc(x, GFP_KERNEL)
+#define DDL_FREE(x)   { if ((x)) kfree((x)); (x) = NULL; }
+
+#define DBG_PMEM(x...) \
+do { \
+	if (vidc_msg_pmem) \
+		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);
+
+void ddl_reset_core_time_variables(u32 index);
+
+#define DDL_ASSERT(x)
+#define DDL_MEMSET(src, value, len) memset((src), (value), (len))
+#define DDL_MEMCPY(dest, src, len)  memcpy((dest), (src), (len))
+
+#define DDL_ADDR_IS_ALIGNED(addr, align_bytes) \
+(!((u32)(addr) & ((align_bytes) - 1)))
+
+#endif
diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.c b/drivers/video/msm/vidc/720p/ddl/vidc.c
new file mode 100644
index 0000000..8e7abc4
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vidc.c
@@ -0,0 +1,801 @@
+/* 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/unistd.h>
+#include "vidc.h"
+#include "vidc_type.h"
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+#define VIDC_720P_VERSION_STRING "VIDC_V1.0"
+u8 *vidc_base_addr;
+
+#ifdef VIDC_REGISTER_LOG_INTO_BUFFER
+char vidclog[VIDC_REGLOG_BUFSIZE];
+unsigned int vidclog_index;
+#endif
+
+void vidc_720p_set_device_virtual_base(u8 *core_virtual_base_addr)
+{
+	vidc_base_addr = core_virtual_base_addr;
+}
+
+void vidc_720p_init(char **ppsz_version, u32 i_firmware_size,
+		     u32 *pi_firmware_address,
+		     enum vidc_720p_endian dma_endian,
+		     u32 interrupt_off,
+		     enum vidc_720p_interrupt_level_selection
+		     interrupt_sel, u32 interrupt_mask)
+{
+	if (ppsz_version)
+		*ppsz_version = VIDC_720P_VERSION_STRING;
+
+	if (interrupt_sel == VIDC_720P_INTERRUPT_LEVEL_SEL)
+		VIDC_IO_OUT(REG_491082, 0);
+	else
+		VIDC_IO_OUT(REG_491082, 1);
+
+	if (interrupt_off)
+		VIDC_IO_OUT(REG_609676, 1);
+	else
+		VIDC_IO_OUT(REG_609676, 0);
+
+	VIDC_IO_OUT(REG_614776, 1);
+
+	VIDC_IO_OUT(REG_418173, 0);
+
+	VIDC_IO_OUT(REG_418173, interrupt_mask);
+
+	VIDC_IO_OUT(REG_736316, dma_endian);
+
+	VIDC_IO_OUT(REG_215724, 0);
+
+	VIDC_IO_OUT(REG_361582, 1);
+
+	VIDC_IO_OUT(REG_591577, i_firmware_size);
+
+	VIDC_IO_OUT(REG_203921, pi_firmware_address);
+
+	VIDC_IO_OUT(REG_531515_ADDR, 0);
+
+	VIDC_IO_OUT(REG_614413, 1);
+}
+
+u32 vidc_720p_do_sw_reset(void)
+{
+
+	u32 fw_start = 0;
+	VIDC_BUSY_WAIT(5);
+	VIDC_IO_OUT(REG_224135, 0);
+	VIDC_BUSY_WAIT(5);
+	VIDC_IO_OUT(REG_193553, 0);
+	VIDC_BUSY_WAIT(5);
+	VIDC_IO_OUT(REG_141269, 1);
+	VIDC_BUSY_WAIT(15);
+	VIDC_IO_OUT(REG_141269, 0);
+	VIDC_BUSY_WAIT(5);
+	VIDC_IO_IN(REG_193553, &fw_start);
+
+	if (!fw_start) {
+		DBG("\n VIDC-SW-RESET-FAILS!");
+		return false;
+	}
+	return true;
+}
+
+u32 vidc_720p_reset_is_success()
+{
+	u32 stagecounter = 0;
+	VIDC_IO_IN(REG_352831, &stagecounter);
+	stagecounter &= 0xff;
+	if (stagecounter != 0xe5) {
+		DBG("\n VIDC-CPU_RESET-FAILS!");
+		VIDC_IO_OUT(REG_224135, 0);
+		msleep(10);
+		return false;
+	}
+	return true;
+}
+
+void vidc_720p_start_cpu(enum vidc_720p_endian dma_endian,
+						  u32 *icontext_bufferstart,
+						  u32 *debug_core_dump_addr,
+						  u32  debug_buffer_size)
+{
+	u32 dbg_info_input0_reg = 0x1;
+	VIDC_IO_OUT(REG_361582, 0);
+	VIDC_IO_OUT(REG_958768, icontext_bufferstart);
+	VIDC_IO_OUT(REG_736316, dma_endian);
+	if (debug_buffer_size) {
+		dbg_info_input0_reg = (debug_buffer_size << 0x10)
+			| (0x2 << 1) | 0x1;
+		VIDC_IO_OUT(REG_166247, debug_core_dump_addr);
+	}
+	VIDC_IO_OUT(REG_699747, dbg_info_input0_reg);
+	VIDC_IO_OUT(REG_224135, 1);
+}
+
+u32 vidc_720p_cpu_start()
+{
+	u32 fw_status = 0x0;
+	VIDC_IO_IN(REG_381535, &fw_status);
+	if (fw_status != 0x02)
+		return false;
+	return true;
+}
+
+
+void vidc_720p_stop_fw(void)
+{
+   VIDC_IO_OUT(REG_193553, 0);
+   VIDC_IO_OUT(REG_224135, 0);
+}
+
+void vidc_720p_get_interrupt_status(u32 *interrupt_status,
+	u32 *cmd_err_status, u32 *disp_pic_err_status, u32 *op_failed)
+{
+	u32 err_status;
+	VIDC_IO_IN(REG_512143, interrupt_status);
+	VIDC_IO_IN(REG_300310, &err_status);
+	*cmd_err_status = err_status & 0xffff;
+	*disp_pic_err_status = (err_status & 0xffff0000) >> 16;
+	VIDC_IO_INF(REG_724381, OPERATION_FAILED, \
+				 op_failed);
+}
+
+void vidc_720p_interrupt_done_clear(void)
+{
+	VIDC_IO_OUT(REG_614776, 1);
+	VIDC_IO_OUT(REG_97293, 4);
+}
+
+void vidc_720p_submit_command(u32 ch_id, u32 cmd_id)
+{
+	u32 fw_status;
+	VIDC_IO_OUT(REG_97293, ch_id);
+	VIDC_IO_OUT(REG_62325, cmd_id);
+	VIDC_DEBUG_REGISTER_LOG;
+	VIDC_IO_IN(REG_381535, &fw_status);
+	VIDC_IO_OUT(REG_926519, fw_status);
+}
+
+u32 vidc_720p_engine_reset(u32 ch_id,
+	enum vidc_720p_endian dma_endian,
+	enum vidc_720p_interrupt_level_selection interrupt_sel,
+	u32 interrupt_mask
+)
+{
+	u32 op_done = 0;
+	u32 counter = 0;
+
+	VIDC_LOGERR_STRING("ENG-RESET!!");
+	/* issue the engine reset command */
+	vidc_720p_submit_command(ch_id, VIDC_720P_CMD_MFC_ENGINE_RESET);
+
+	do {
+		VIDC_BUSY_WAIT(20);
+		VIDC_IO_IN(REG_982553, &op_done);
+		counter++;
+	} while (!op_done && counter < 10);
+
+	if (!op_done) {
+		/* Reset fails */
+		return  false ;
+	}
+
+	/* write invalid channel id */
+	VIDC_IO_OUT(REG_97293, 4);
+
+	/* Set INT_PULSE_SEL */
+	if (interrupt_sel == VIDC_720P_INTERRUPT_LEVEL_SEL)
+		VIDC_IO_OUT(REG_491082, 0);
+	else
+		VIDC_IO_OUT(REG_491082, 1);
+
+	if (!interrupt_mask) {
+		/* Disable interrupt */
+		VIDC_IO_OUT(REG_609676, 1);
+	} else {
+	  /* Enable interrupt */
+		VIDC_IO_OUT(REG_609676, 0);
+	}
+
+	/* Clear any pending interrupt */
+	VIDC_IO_OUT(REG_614776, 1);
+
+	/* Set INT_ENABLE_REG */
+	VIDC_IO_OUT(REG_418173, interrupt_mask);
+
+	/*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 ;
+}
+
+void vidc_720p_set_channel(u32 i_ch_id,
+			    enum vidc_720p_enc_dec_selection
+			    enc_dec_sel, enum vidc_720p_codec codec,
+			    u32 *pi_fw, u32 i_firmware_size)
+{
+	u32 std_sel = 0;
+	VIDC_IO_OUT(REG_661565, 0);
+
+	if (enc_dec_sel)
+		std_sel = VIDC_REG_713080_ENC_ON_BMSK;
+
+	std_sel |= (u32) codec;
+
+	VIDC_IO_OUT(REG_713080, std_sel);
+
+	switch (codec) {
+	default:
+	case VIDC_720P_DIVX:
+	case VIDC_720P_XVID:
+	case VIDC_720P_MPEG4:
+		{
+			if (enc_dec_sel == VIDC_720P_ENCODER)
+				VIDC_IO_OUT(REG_765787, pi_fw);
+			else
+				VIDC_IO_OUT(REG_225040, pi_fw);
+			break;
+		}
+	case VIDC_720P_H264:
+		{
+			if (enc_dec_sel == VIDC_720P_ENCODER)
+				VIDC_IO_OUT(REG_942456, pi_fw);
+			else
+				VIDC_IO_OUT(REG_942170_ADDR_3, pi_fw);
+			break;
+		}
+	case VIDC_720P_H263:
+		{
+			if (enc_dec_sel == VIDC_720P_ENCODER)
+				VIDC_IO_OUT(REG_765787, pi_fw);
+			else
+				VIDC_IO_OUT(REG_942170_ADDR_6, pi_fw);
+			break;
+		}
+	case VIDC_720P_VC1:
+		{
+			VIDC_IO_OUT(REG_880188, pi_fw);
+			break;
+		}
+	case VIDC_720P_MPEG2:
+		{
+			VIDC_IO_OUT(REG_40293, pi_fw);
+			break;
+		}
+	}
+	VIDC_IO_OUT(REG_591577, i_firmware_size);
+
+	vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_CHSET);
+}
+
+void vidc_720p_encode_set_profile(u32 i_profile, u32 i_level)
+{
+	u32 profile_level = i_profile|(i_level << 0x8);
+	VIDC_IO_OUT(REG_839021, profile_level);
+}
+
+void vidc_720p_set_frame_size(u32 i_size_x, u32 i_size_y)
+{
+	VIDC_IO_OUT(REG_999267, i_size_x);
+
+	VIDC_IO_OUT(REG_345712, i_size_y);
+}
+
+void vidc_720p_encode_set_fps(u32 i_rc_frame_rate)
+{
+	VIDC_IO_OUT(REG_625444, i_rc_frame_rate);
+}
+
+void vidc_720p_encode_set_short_header(u32 i_short_header)
+{
+	VIDC_IO_OUT(REG_314290, i_short_header);
+}
+
+void vidc_720p_encode_set_vop_time(u32 vop_time_resolution,
+				    u32 vop_time_increment)
+{
+	u32 enable_vop, vop_timing_reg;
+	if (!vop_time_resolution)
+		VIDC_IO_OUT(REG_64895, 0x0);
+	else {
+		enable_vop = 0x1;
+		vop_timing_reg = (enable_vop << 0x1f) |
+		(vop_time_resolution << 0x10) | vop_time_increment;
+		VIDC_IO_OUT(REG_64895, vop_timing_reg);
+	}
+}
+
+void vidc_720p_encode_set_hec_period(u32 hec_period)
+{
+	VIDC_IO_OUT(REG_407718, hec_period);
+}
+
+void vidc_720p_encode_set_qp_params(u32 i_max_qp, u32 i_min_qp)
+{
+	u32 qp = i_min_qp | (i_max_qp << 0x8);
+	VIDC_IO_OUT(REG_734318, qp);
+}
+
+void vidc_720p_encode_set_rc_config(u32 enable_frame_level_rc,
+				     u32 enable_mb_level_rc_flag,
+				     u32 i_frame_qp, u32 pframe_qp)
+{
+   u32 rc_config = i_frame_qp;
+
+	if (enable_frame_level_rc)
+		rc_config |= (0x1 << 0x9);
+
+	if (enable_mb_level_rc_flag)
+		rc_config |= (0x1 << 0x8);
+
+	VIDC_IO_OUT(REG_58211, rc_config);
+	VIDC_IO_OUT(REG_548359, pframe_qp);
+}
+
+void vidc_720p_encode_set_bit_rate(u32 i_target_bitrate)
+{
+	VIDC_IO_OUT(REG_174150, i_target_bitrate);
+}
+
+void vidc_720p_encoder_set_param_change(u32 enc_param_change)
+{
+	VIDC_IO_OUT(REG_804959, enc_param_change);
+}
+
+void vidc_720p_encode_set_control_param(u32 param_val)
+{
+	VIDC_IO_OUT(REG_128234, param_val);
+}
+
+void vidc_720p_encode_set_frame_level_rc_params(u32 i_reaction_coeff)
+{
+	VIDC_IO_OUT(REG_677784, i_reaction_coeff);
+}
+
+void vidc_720p_encode_set_mb_level_rc_params(u32 dark_region_as_flag,
+					      u32 smooth_region_as_flag,
+					      u32 static_region_as_flag,
+					      u32 activity_region_flag)
+{
+	u32 mb_level_rc = 0x0;
+	if (activity_region_flag)
+		mb_level_rc |= 0x1;
+	if (static_region_as_flag)
+		mb_level_rc |= (0x1 << 0x1);
+	if (smooth_region_as_flag)
+		mb_level_rc |= (0x1 << 0x2);
+	if (dark_region_as_flag)
+		mb_level_rc |= (0x1 << 0x3);
+	/* Write MB level rate control */
+	VIDC_IO_OUT(REG_995041, mb_level_rc);
+}
+
+void vidc_720p_encode_set_entropy_control(enum vidc_720p_entropy_sel
+					   entropy_sel,
+					   enum vidc_720p_cabac_model
+					   cabac_model_number)
+{
+	u32 num;
+	u32 entropy_params = (u32)entropy_sel;
+	/* Set Model Number */
+	if (entropy_sel == VIDC_720P_ENTROPY_SEL_CABAC) {
+		num = (u32)cabac_model_number;
+		entropy_params |= (num << 0x2);
+	}
+	/* Set Entropy parameters */
+	VIDC_IO_OUT(REG_504878, entropy_params);
+}
+
+void vidc_720p_encode_set_db_filter_control(enum vidc_720p_DBConfig
+					     db_config,
+					     u32 i_slice_alpha_offset,
+					     u32 i_slice_beta_offset)
+{
+	u32 deblock_params;
+	deblock_params = (u32)db_config;
+	deblock_params |=
+		((i_slice_beta_offset << 0x2) | (i_slice_alpha_offset << 0x7));
+
+	/* Write deblocking control settings */
+	VIDC_IO_OUT(REG_458130, deblock_params);
+}
+
+void vidc_720p_encode_set_intra_refresh_mb_number(u32 i_cir_mb_number)
+{
+	VIDC_IO_OUT(REG_857491, i_cir_mb_number);
+}
+
+void vidc_720p_encode_set_multi_slice_info(enum
+					    vidc_720p_MSlice_selection
+					    m_slice_sel,
+					    u32 multi_slice_size)
+{
+	switch (m_slice_sel) {
+	case VIDC_720P_MSLICE_BY_MB_COUNT:
+		{
+			VIDC_IO_OUT(REG_588301, 0x1);
+			VIDC_IO_OUT(REG_1517, m_slice_sel);
+			VIDC_IO_OUT(REG_105335, multi_slice_size);
+			break;
+		}
+	case VIDC_720P_MSLICE_BY_BYTE_COUNT:
+		{
+			VIDC_IO_OUT(REG_588301, 0x1);
+			VIDC_IO_OUT(REG_1517, m_slice_sel);
+			VIDC_IO_OUT(REG_561679, multi_slice_size);
+			break;
+		}
+	case VIDC_720P_MSLICE_BY_GOB:
+		{
+			VIDC_IO_OUT(REG_588301, 0x1);
+			break;
+		}
+	default:
+	case VIDC_720P_MSLICE_OFF:
+		{
+			VIDC_IO_OUT(REG_588301, 0x0);
+			break;
+		}
+	}
+}
+
+void vidc_720p_encode_set_dpb_buffer(u32 *pi_enc_dpb_addr, u32 alloc_len)
+{
+	VIDC_IO_OUT(REG_341928_ADDR, pi_enc_dpb_addr);
+	VIDC_IO_OUT(REG_319934, alloc_len);
+}
+
+void vidc_720p_encode_set_i_period(u32 i_i_period)
+{
+	VIDC_IO_OUT(REG_950374, i_i_period);
+}
+
+void vidc_720p_encode_init_codec(u32 i_ch_id,
+				  enum vidc_720p_memory_access_method
+				  memory_access_model)
+{
+
+	VIDC_IO_OUT(REG_841539, memory_access_model);
+	vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_INITCODEC);
+}
+
+void vidc_720p_encode_unalign_bitstream(u32 upper_unalign_word,
+					 u32 lower_unalign_word)
+{
+	VIDC_IO_OUT(REG_792026, upper_unalign_word);
+	VIDC_IO_OUT(REG_844152, lower_unalign_word);
+}
+
+void vidc_720p_encode_set_seq_header_buffer(u32 ext_buffer_start,
+					     u32 ext_buffer_end,
+					     u32 start_byte_num)
+{
+	VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start);
+
+	VIDC_IO_OUT(REG_87912, ext_buffer_start);
+
+	VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end);
+
+	VIDC_IO_OUT(REG_66693, start_byte_num);
+}
+
+void vidc_720p_encode_frame(u32 ch_id,
+			     u32 ext_buffer_start,
+			     u32 ext_buffer_end,
+			     u32 start_byte_number, u32 y_addr,
+			     u32 c_addr)
+{
+	VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start);
+
+	VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end);
+
+	VIDC_IO_OUT(REG_87912, ext_buffer_start);
+
+	VIDC_IO_OUT(REG_66693, start_byte_number);
+
+	VIDC_IO_OUT(REG_99105, y_addr);
+
+	VIDC_IO_OUT(REG_777113_ADDR, c_addr);
+
+	vidc_720p_submit_command(ch_id, VIDC_720P_CMD_FRAMERUN);
+}
+
+void vidc_720p_encode_get_header(u32 *pi_enc_header_size)
+{
+	VIDC_IO_IN(REG_114286, pi_enc_header_size);
+}
+
+void vidc_720p_enc_frame_info(struct vidc_720p_enc_frame_info
+			       *enc_frame_info)
+{
+	VIDC_IO_IN(REG_782249, &enc_frame_info->enc_size);
+
+	VIDC_IO_IN(REG_441270, &enc_frame_info->frame);
+
+	enc_frame_info->frame &= 0x03;
+
+	VIDC_IO_IN(REG_613254,
+		    &enc_frame_info->metadata_exists);
+}
+
+void vidc_720p_decode_bitstream_header(u32 ch_id,
+					u32 dec_unit_size,
+					u32 start_byte_num,
+					u32 ext_buffer_start,
+					u32 ext_buffer_end,
+					enum
+					vidc_720p_memory_access_method
+					memory_access_model,
+					u32 decode_order)
+{
+	VIDC_IO_OUT(REG_965480, decode_order);
+
+	VIDC_IO_OUT(REG_639999, 0x8080);
+
+	VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start);
+
+	VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end);
+
+	VIDC_IO_OUT(REG_87912, ext_buffer_end);
+
+	VIDC_IO_OUT(REG_761892, dec_unit_size);
+
+	VIDC_IO_OUT(REG_66693, start_byte_num);
+
+	VIDC_IO_OUT(REG_841539, memory_access_model);
+
+	vidc_720p_submit_command(ch_id, VIDC_720P_CMD_INITCODEC);
+}
+
+void vidc_720p_decode_get_seq_hdr_info(struct vidc_720p_seq_hdr_info
+					*seq_hdr_info)
+{
+	u32 display_status;
+	VIDC_IO_IN(REG_999267, &seq_hdr_info->img_size_x);
+
+	VIDC_IO_IN(REG_345712, &seq_hdr_info->img_size_y);
+
+	VIDC_IO_IN(REG_257463, &seq_hdr_info->min_num_dpb);
+
+	VIDC_IO_IN(REG_854281, &seq_hdr_info->min_dpb_size);
+
+	VIDC_IO_IN(REG_580603, &seq_hdr_info->dec_frm_size);
+
+	VIDC_IO_INF(REG_606447, DISP_PIC_PROFILE,
+				 &seq_hdr_info->profile);
+
+	VIDC_IO_INF(REG_606447, DIS_PIC_LEVEL,
+				 &seq_hdr_info->level);
+
+	VIDC_IO_INF(REG_612715, DISPLAY_STATUS,
+				&display_status);
+	seq_hdr_info->progressive =
+			((display_status & 0x4) >> 2);
+	/* bit 3 is for crop existence */
+	seq_hdr_info->crop_exists = ((display_status & 0x8) >> 3);
+
+	if (seq_hdr_info->crop_exists) {
+		/* read the cropping information */
+		VIDC_IO_INF(REG_881638, CROP_RIGHT_OFFSET, \
+			&seq_hdr_info->crop_right_offset);
+		VIDC_IO_INF(REG_881638, CROP_LEFT_OFFSET, \
+			&seq_hdr_info->crop_left_offset);
+		VIDC_IO_INF(REG_161486, CROP_BOTTOM_OFFSET, \
+			&seq_hdr_info->crop_bottom_offset);
+		VIDC_IO_INF(REG_161486, CROP_TOP_OFFSET, \
+			&seq_hdr_info->crop_top_offset);
+	}
+	/* Read the MPEG4 data partitioning indication */
+	VIDC_IO_INF(REG_441270, DATA_PARTITIONED, \
+				&seq_hdr_info->data_partitioned);
+
+}
+
+void vidc_720p_decode_set_dpb_release_buffer_mask(u32
+						   i_dpb_release_buffer_mask)
+{
+	VIDC_IO_OUT(REG_603032, i_dpb_release_buffer_mask);
+}
+
+void vidc_720p_decode_set_dpb_buffers(u32 i_buf_index, u32 *pi_dpb_buffer)
+{
+	VIDC_IO_OUTI(REG_615716, i_buf_index, pi_dpb_buffer);
+}
+
+void vidc_720p_decode_set_comv_buffer(u32 *pi_dpb_comv_buffer,
+				       u32 alloc_len)
+{
+	VIDC_IO_OUT(REG_456376_ADDR, pi_dpb_comv_buffer);
+
+	VIDC_IO_OUT(REG_490443, alloc_len);
+}
+
+void vidc_720p_decode_set_dpb_details(u32 num_dpb, u32 alloc_len,
+				       u32 *ref_buffer)
+{
+	VIDC_IO_OUT(REG_518133, ref_buffer);
+
+	VIDC_IO_OUT(REG_267567, 0);
+
+	VIDC_IO_OUT(REG_883500, num_dpb);
+
+	VIDC_IO_OUT(REG_319934, alloc_len);
+}
+
+void vidc_720p_decode_set_mpeg4Post_filter(u32 enable_post_filter)
+{
+	if (enable_post_filter)
+		VIDC_IO_OUT(REG_443811, 0x1);
+	else
+		VIDC_IO_OUT(REG_443811, 0x0);
+}
+
+void vidc_720p_decode_set_error_control(u32 enable_error_control)
+{
+	if (enable_error_control)
+		VIDC_IO_OUT(REG_846346, 0);
+	else
+		VIDC_IO_OUT(REG_846346, 1);
+}
+
+void vidc_720p_set_deblock_line_buffer(u32 *pi_deblock_line_buffer_start,
+					u32 alloc_len)
+{
+	VIDC_IO_OUT(REG_979942, pi_deblock_line_buffer_start);
+
+	VIDC_IO_OUT(REG_101184, alloc_len);
+}
+
+void vidc_720p_decode_set_mpeg4_data_partitionbuffer(u32 *vsp_buf_start)
+{
+    VIDC_IO_OUT(REG_958768, vsp_buf_start);
+}
+
+void vidc_720p_decode_setH264VSPBuffer(u32 *pi_vsp_temp_buffer_start)
+{
+	VIDC_IO_OUT(REG_958768, pi_vsp_temp_buffer_start);
+}
+
+void vidc_720p_decode_frame(u32 ch_id, u32 ext_buffer_start,
+			     u32 ext_buffer_end, u32 dec_unit_size,
+			     u32 start_byte_num, u32 input_frame_tag)
+{
+	VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start);
+
+	VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end);
+
+	VIDC_IO_OUT(REG_87912, ext_buffer_end);
+
+	VIDC_IO_OUT(REG_66693, start_byte_num);
+
+	VIDC_IO_OUT(REG_94750, input_frame_tag);
+
+	VIDC_IO_OUT(REG_761892, dec_unit_size);
+
+	vidc_720p_submit_command(ch_id, VIDC_720P_CMD_FRAMERUN);
+}
+
+void vidc_720p_issue_eos(u32 i_ch_id)
+{
+    VIDC_IO_OUT(REG_896825, 0x1);
+
+    VIDC_IO_OUT(REG_761892, 0);
+
+    vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_FRAMERUN);
+}
+
+void vidc_720p_eos_info(u32 *disp_status, u32 *resl_change)
+{
+   VIDC_IO_INF(REG_612715, DISPLAY_STATUS, disp_status);
+   (*disp_status) = (*disp_status) & 0x3;
+   VIDC_IO_INF(REG_724381, RESOLUTION_CHANGE, resl_change);
+}
+
+void vidc_720p_decode_display_info(struct vidc_720p_dec_disp_info
+				    *disp_info)
+{
+	u32 display_status = 0;
+	VIDC_IO_INF(REG_612715, DISPLAY_STATUS, &display_status);
+
+	disp_info->disp_status =
+	    (enum vidc_720p_display_status)((display_status & 0x3));
+
+	disp_info->disp_is_interlace = ((display_status & 0x4) >> 2);
+	disp_info->crop_exists = ((display_status & 0x8) >> 3);
+
+	disp_info->resl_change = ((display_status & 0x30) >> 4);
+
+	VIDC_IO_INF(REG_724381, RESOLUTION_CHANGE,
+		     &disp_info->reconfig_flush_done);
+
+	VIDC_IO_IN(REG_999267, &disp_info->img_size_x);
+
+	VIDC_IO_IN(REG_345712, &disp_info->img_size_y);
+	VIDC_IO_IN(REG_151345, &disp_info->y_addr);
+	VIDC_IO_IN(REG_293983, &disp_info->c_addr);
+	VIDC_IO_IN(REG_370409, &disp_info->tag_top);
+	VIDC_IO_IN(REG_438677, &disp_info->tag_bottom);
+	VIDC_IO_IN(REG_679165, &disp_info->pic_time_top);
+	VIDC_IO_IN(REG_374150, &disp_info->pic_time_bottom);
+
+	if (disp_info->crop_exists) {
+		VIDC_IO_INF(REG_881638, CROP_RIGHT_OFFSET,
+			&disp_info->crop_right_offset);
+		VIDC_IO_INF(REG_881638, CROP_LEFT_OFFSET,
+			&disp_info->crop_left_offset);
+		VIDC_IO_INF(REG_161486, CROP_BOTTOM_OFFSET,
+			&disp_info->crop_bottom_offset);
+		VIDC_IO_INF(REG_161486, CROP_TOP_OFFSET,
+			&disp_info->crop_top_offset);
+	}
+	VIDC_IO_IN(REG_613254, &disp_info->metadata_exists);
+
+	VIDC_IO_IN(REG_580603,
+		    &disp_info->input_bytes_consumed);
+
+	VIDC_IO_IN(REG_757835, &disp_info->input_frame_num);
+
+	VIDC_IO_INF(REG_441270, FRAME_TYPE,
+			   &disp_info->input_frame);
+
+	disp_info->input_is_interlace =
+	    ((disp_info->input_frame & 0x4) >> 2);
+
+	disp_info->input_frame &= 0x3;
+}
+
+void vidc_720p_decode_skip_frm_details(u32 *free_luma_dpb)
+{
+	u32 disp_frm;
+	VIDC_IO_IN(REG_697961, &disp_frm);
+
+	if (disp_frm == VIDC_720P_NOTCODED)
+		VIDC_IO_IN(REG_347105, free_luma_dpb);
+}
+
+void vidc_720p_metadata_enable(u32 flag, u32 *input_buffer)
+{
+	VIDC_IO_OUT(REG_854681, flag);
+	VIDC_IO_OUT(REG_988552, input_buffer);
+}
+
+void vidc_720p_decode_dynamic_req_reset(void)
+{
+	VIDC_IO_OUT(REG_76706, 0x0);
+	VIDC_IO_OUT(REG_147682, 0x0);
+	VIDC_IO_OUT(REG_896825, 0x0);
+}
+
+void vidc_720p_decode_dynamic_req_set(u32 property)
+{
+	if (property == VIDC_720P_FLUSH_REQ)
+		VIDC_IO_OUT(REG_76706, 0x1);
+	else if (property == VIDC_720P_EXTRADATA)
+		VIDC_IO_OUT(REG_147682, 0x1);
+}
+
+void vidc_720p_decode_setpassthrough_start(u32 pass_startaddr)
+{
+	VIDC_IO_OUT(REG_486169, pass_startaddr);
+}
diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.h b/drivers/video/msm/vidc/720p/ddl/vidc.h
new file mode 100644
index 0000000..685b7cc
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/ddl/vidc.h
@@ -0,0 +1,2704 @@
+/* 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_H
+#define VIDC_H
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <asm/system.h>
+
+#define VIDC_720P_IN(reg)                       VIDC_##reg##_IN
+#define VIDC_720P_INM(reg,  mask)                VIDC_##reg##_INM(mask)
+#define VIDC_720P_OUT(reg,  val)                 VIDC_##reg##_OUT(val)
+#define VIDC_720P_OUTI(reg,  index,  val)         VIDC_##reg##_OUTI(index, val)
+#define VIDC_720P_OUTM(reg,  mask,  val)          VIDC_##reg##_OUTM(mask,  val)
+#define VIDC_720P_SHFT(reg,  field)              VIDC_##reg##_##field##_SHFT
+#define VIDC_720P_FMSK(reg,  field)              VIDC_##reg##_##field##_BMSK
+
+#define VIDC_720P_INF(io, field) (VIDC_720P_INM(io, VIDC_720P_FMSK(io, field)) \
+		>> VIDC_720P_SHFT(io,  field))
+#define VIDC_720P_OUTF(io, field, val) \
+		VIDC_720P_OUTM(io, VIDC_720P_FMSK(io, field), \
+		val << VIDC_720P_SHFT(io,  field))
+
+#define __inpdw(port)	ioread32(port)
+#define __outpdw(port,  val) iowrite32(val, port)
+
+#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))); \
+	(void) out_dword(io,  shadow); \
+} while (0)
+
+#define out_dword_masked_ns(io,  mask,  val,  current_reg_content) \
+	(void) out_dword(io,  ((current_reg_content & (u32)(~(mask))) | \
+				((u32)((val) & (mask)))))
+
+extern u8 *vidc_base_addr;
+
+#define VIDC720P_BASE  vidc_base_addr
+#define VIDC_720P_WRAPPER_REG_BASE               (VIDC720P_BASE + \
+		0x00000000)
+#define VIDC_720P_WRAPPER_REG_BASE_PHYS          VIDC_720P_BASE_PHYS
+
+#define VIDC_REG_614413_ADDR                     \
+	(VIDC_720P_WRAPPER_REG_BASE      + 00000000)
+#define VIDC_REG_614413_PHYS                     \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 00000000)
+#define VIDC_REG_614413_RMSK                            0x1
+#define VIDC_REG_614413_SHFT                              0
+#define VIDC_REG_614413_IN                       \
+	in_dword_masked(VIDC_REG_614413_ADDR,        \
+		VIDC_REG_614413_RMSK)
+#define VIDC_REG_614413_INM(m)                   \
+	in_dword_masked(VIDC_REG_614413_ADDR,  m)
+#define VIDC_REG_614413_OUT(v)                   \
+	out_dword(VIDC_REG_614413_ADDR, v)
+#define VIDC_REG_614413_OUTM(m, v)                \
+do { \
+	out_dword_masked_ns(VIDC_REG_614413_ADDR, m, v, \
+			VIDC_REG_614413_IN); \
+} while (0)
+#define VIDC_REG_614413_DMA_START_BMSK                  0x1
+#define VIDC_REG_614413_DMA_START_SHFT                    0
+
+#define VIDC_REG_591577_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000000c)
+#define VIDC_REG_591577_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000000c)
+#define VIDC_REG_591577_RMSK                 0xffffffff
+#define VIDC_REG_591577_SHFT                          0
+#define VIDC_REG_591577_IN                   \
+	in_dword_masked(VIDC_REG_591577_ADDR,  \
+			VIDC_REG_591577_RMSK)
+#define VIDC_REG_591577_INM(m)               \
+	in_dword_masked(VIDC_REG_591577_ADDR,  m)
+#define VIDC_REG_591577_OUT(v)               \
+	out_dword(VIDC_REG_591577_ADDR, v)
+#define VIDC_REG_591577_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_591577_ADDR, m, v, \
+			VIDC_REG_591577_IN); \
+} while (0)
+#define VIDC_REG_591577_BOOTCODE_SIZE_BMSK   0xffffffff
+#define VIDC_REG_591577_BOOTCODE_SIZE_SHFT            0
+
+#define VIDC_REG_203921_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000014)
+#define VIDC_REG_203921_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000014)
+#define VIDC_REG_203921_RMSK                   0xffffffff
+#define VIDC_REG_203921_SHFT                            0
+#define VIDC_REG_203921_IN                     \
+	in_dword_masked(VIDC_REG_203921_ADDR,  \
+			VIDC_REG_203921_RMSK)
+#define VIDC_REG_203921_INM(m)                 \
+	in_dword_masked(VIDC_REG_203921_ADDR,  m)
+#define VIDC_REG_203921_OUT(v)                 \
+	out_dword(VIDC_REG_203921_ADDR, v)
+#define VIDC_REG_203921_OUTM(m, v)              \
+do { \
+	out_dword_masked_ns(VIDC_REG_203921_ADDR, m, v, \
+			VIDC_REG_203921_IN); \
+} while (0)
+#define VIDC_REG_203921_DMA_EXTADDR_BMSK       0xffffffff
+#define VIDC_REG_203921_DMA_EXTADDR_SHFT                0
+
+#define VIDC_REG_275113_ADDR_ADDR            \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000018)
+#define VIDC_REG_275113_ADDR_PHYS            \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000018)
+#define VIDC_REG_275113_ADDR_RMSK            0xffffffff
+#define VIDC_REG_275113_ADDR_SHFT                     0
+#define VIDC_REG_275113_ADDR_IN              \
+	in_dword_masked(VIDC_REG_275113_ADDR_ADDR,  \
+			VIDC_REG_275113_ADDR_RMSK)
+#define VIDC_REG_275113_ADDR_INM(m)          \
+	in_dword_masked(VIDC_REG_275113_ADDR_ADDR,  m)
+#define VIDC_REG_275113_ADDR_OUT(v)          \
+	out_dword(VIDC_REG_275113_ADDR_ADDR, v)
+#define VIDC_REG_275113_ADDR_OUTM(m, v)       \
+do { \
+	out_dword_masked_ns(VIDC_REG_275113_ADDR_ADDR, m, v, \
+			VIDC_REG_275113_ADDR_IN); \
+} while (0)
+#define VIDC_REG_742076_ADDR_BMSK 0xffffffff
+#define VIDC_REG_742076_ADDR_SHFT          0
+
+#define VIDC_REG_988007_ADDR_ADDR              \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000001c)
+#define VIDC_REG_988007_ADDR_PHYS              \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000001c)
+#define VIDC_REG_988007_ADDR_RMSK              0xffffffff
+#define VIDC_REG_988007_ADDR_SHFT                       0
+#define VIDC_REG_988007_ADDR_IN                \
+	in_dword_masked(VIDC_REG_988007_ADDR_ADDR,  \
+			VIDC_REG_988007_ADDR_RMSK)
+#define VIDC_REG_988007_ADDR_INM(m)            \
+	in_dword_masked(VIDC_REG_988007_ADDR_ADDR,  m)
+#define VIDC_REG_988007_ADDR_OUT(v)            \
+	out_dword(VIDC_REG_988007_ADDR_ADDR, v)
+#define VIDC_REG_988007_ADDR_OUTM(m, v)         \
+do { \
+	out_dword_masked_ns(VIDC_REG_988007_ADDR_ADDR, m, v, \
+			VIDC_REG_988007_ADDR_IN); \
+} while (0)
+#define VIDC_REG_988007_ADDR_EXT_BUF_END_ADDR_BMSK 0xffffffff
+#define VIDC_REG_988007_ADDR_EXT_BUF_END_ADDR_SHFT          0
+
+#define VIDC_REG_531515_ADDR_ADDR                  \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000020)
+#define VIDC_REG_531515_ADDR_PHYS                  \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000020)
+#define VIDC_REG_531515_ADDR_RMSK                  0xffffffff
+#define VIDC_REG_531515_ADDR_SHFT                           0
+#define VIDC_REG_531515_ADDR_IN                    \
+	in_dword_masked(VIDC_REG_531515_ADDR_ADDR,  \
+			VIDC_REG_531515_ADDR_RMSK)
+#define VIDC_REG_531515_ADDR_INM(m)                \
+	in_dword_masked(VIDC_REG_531515_ADDR_ADDR,  m)
+#define VIDC_REG_531515_ADDR_OUT(v)                \
+	out_dword(VIDC_REG_531515_ADDR_ADDR, v)
+#define VIDC_REG_531515_ADDR_OUTM(m, v)             \
+do { \
+	out_dword_masked_ns(VIDC_REG_531515_ADDR_ADDR, m, v, \
+			VIDC_REG_531515_ADDR_IN); \
+} while (0)
+#define VIDC_REG_531515_ADDR_DMA_INT_ADDR_BMSK     0xffffffff
+#define VIDC_REG_531515_ADDR_DMA_INT_ADDR_SHFT              0
+
+#define VIDC_REG_87912_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000024)
+#define VIDC_REG_87912_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000024)
+#define VIDC_REG_87912_RMSK                 0xffffffff
+#define VIDC_REG_87912_SHFT                          0
+#define VIDC_REG_87912_IN                   \
+	in_dword_masked(VIDC_REG_87912_ADDR,  \
+			VIDC_REG_87912_RMSK)
+#define VIDC_REG_87912_INM(m)               \
+	in_dword_masked(VIDC_REG_87912_ADDR,  m)
+#define VIDC_REG_87912_OUT(v)               \
+	out_dword(VIDC_REG_87912_ADDR, v)
+#define VIDC_REG_87912_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_87912_ADDR, m, v, \
+			VIDC_REG_87912_IN); \
+} while (0)
+#define VIDC_REG_87912_HOST_PTR_ADDR_BMSK   0xffffffff
+#define VIDC_REG_87912_HOST_PTR_ADDR_SHFT            0
+
+#define VIDC_REG_896825_ADDR                      \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000028)
+#define VIDC_REG_896825_PHYS                      \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000028)
+#define VIDC_REG_896825_RMSK                             0x1
+#define VIDC_REG_896825_SHFT                               0
+#define VIDC_REG_896825_IN                        \
+	in_dword_masked(VIDC_REG_896825_ADDR,         \
+	VIDC_REG_896825_RMSK)
+#define VIDC_REG_896825_INM(m)                    \
+	in_dword_masked(VIDC_REG_896825_ADDR,  m)
+#define VIDC_REG_896825_OUT(v)                    \
+	out_dword(VIDC_REG_896825_ADDR, v)
+#define VIDC_REG_896825_OUTM(m, v)                 \
+do { \
+	out_dword_masked_ns(VIDC_REG_896825_ADDR, m, v, \
+			VIDC_REG_896825_IN); \
+} while (0)
+#define VIDC_REG_896825_LAST_DEC_BMSK                    0x1
+#define VIDC_REG_896825_LAST_DEC_SHFT                      0
+
+#define VIDC_REG_174526_ADDR                        \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000002c)
+#define VIDC_REG_174526_PHYS                        \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000002c)
+#define VIDC_REG_174526_RMSK                               0x1
+#define VIDC_REG_174526_SHFT                                 0
+#define VIDC_REG_174526_IN                          \
+	in_dword_masked(VIDC_REG_174526_ADDR,  VIDC_REG_174526_RMSK)
+#define VIDC_REG_174526_INM(m)                      \
+	in_dword_masked(VIDC_REG_174526_ADDR,  m)
+#define VIDC_REG_174526_DONE_M_BMSK                        0x1
+#define VIDC_REG_174526_DONE_M_SHFT                          0
+
+#define VIDC_REG_736316_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000044)
+#define VIDC_REG_736316_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000044)
+#define VIDC_REG_736316_RMSK                          0x1
+#define VIDC_REG_736316_SHFT                            0
+#define VIDC_REG_736316_IN                     \
+	in_dword_masked(VIDC_REG_736316_ADDR,  \
+			VIDC_REG_736316_RMSK)
+#define VIDC_REG_736316_INM(m)                 \
+	in_dword_masked(VIDC_REG_736316_ADDR,  m)
+#define VIDC_REG_736316_OUT(v)                 \
+	out_dword(VIDC_REG_736316_ADDR, v)
+#define VIDC_REG_736316_OUTM(m, v)              \
+do { \
+	out_dword_masked_ns(VIDC_REG_736316_ADDR, m, v, \
+			VIDC_REG_736316_IN); \
+} while (0)
+#define VIDC_REG_736316_BITS_ENDIAN_BMSK              0x1
+#define VIDC_REG_736316_BITS_ENDIAN_SHFT                0
+
+#define VIDC_REG_761892_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000054)
+#define VIDC_REG_761892_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000054)
+#define VIDC_REG_761892_RMSK                 0xffffffff
+#define VIDC_REG_761892_SHFT                          0
+#define VIDC_REG_761892_IN                   \
+	in_dword_masked(VIDC_REG_761892_ADDR,  \
+			VIDC_REG_761892_RMSK)
+#define VIDC_REG_761892_INM(m)               \
+	in_dword_masked(VIDC_REG_761892_ADDR,  m)
+#define VIDC_REG_761892_OUT(v)               \
+	out_dword(VIDC_REG_761892_ADDR, v)
+#define VIDC_REG_761892_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_761892_ADDR, m, v, \
+			VIDC_REG_761892_IN); \
+} while (0)
+#define VIDC_REG_761892_DEC_UNIT_SIZE_BMSK   0xffffffff
+#define VIDC_REG_761892_DEC_UNIT_SIZE_SHFT            0
+
+#define VIDC_REG_782249_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000058)
+#define VIDC_REG_782249_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000058)
+#define VIDC_REG_782249_RMSK                 0xffffffff
+#define VIDC_REG_782249_SHFT                          0
+#define VIDC_REG_782249_IN                   \
+	in_dword_masked(VIDC_REG_782249_ADDR,  \
+			VIDC_REG_782249_RMSK)
+#define VIDC_REG_782249_INM(m)               \
+	in_dword_masked(VIDC_REG_782249_ADDR,  m)
+#define VIDC_REG_782249_ENC_UNIT_SIZE_BMSK   0xffffffff
+#define VIDC_REG_782249_ENC_UNIT_SIZE_SHFT            0
+
+#define VIDC_REG_66693_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000005c)
+#define VIDC_REG_66693_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000005c)
+#define VIDC_REG_66693_RMSK                       0xf
+#define VIDC_REG_66693_SHFT                         0
+#define VIDC_REG_66693_IN                  \
+	in_dword_masked(VIDC_REG_66693_ADDR,  \
+			VIDC_REG_66693_RMSK)
+#define VIDC_REG_66693_INM(m)              \
+	in_dword_masked(VIDC_REG_66693_ADDR,  m)
+#define VIDC_REG_66693_OUT(v)              \
+	out_dword(VIDC_REG_66693_ADDR, v)
+#define VIDC_REG_66693_OUTM(m, v)           \
+do { \
+	out_dword_masked_ns(VIDC_REG_66693_ADDR, m, v, \
+			VIDC_REG_66693_IN); \
+} while (0)
+#define VIDC_REG_66693_START_BYTE_NUM_BMSK        0xf
+#define VIDC_REG_66693_START_BYTE_NUM_SHFT          0
+
+#define VIDC_REG_114286_ADDR               \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000060)
+#define VIDC_REG_114286_PHYS               \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000060)
+#define VIDC_REG_114286_RMSK               0xffffffff
+#define VIDC_REG_114286_SHFT                        0
+#define VIDC_REG_114286_IN                 \
+	in_dword_masked(VIDC_REG_114286_ADDR,  \
+			VIDC_REG_114286_RMSK)
+#define VIDC_REG_114286_INM(m)             \
+	in_dword_masked(VIDC_REG_114286_ADDR,  m)
+#define VIDC_REG_114286_ENC_HEADER_SIZE_BMSK 0xffffffff
+#define VIDC_REG_114286_ENC_HEADER_SIZE_SHFT          0
+
+#define VIDC_REG_713080_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000100)
+#define VIDC_REG_713080_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000100)
+#define VIDC_REG_713080_RMSK                         0x1f
+#define VIDC_REG_713080_SHFT                            0
+#define VIDC_REG_713080_IN                     \
+	in_dword_masked(VIDC_REG_713080_ADDR,  \
+			VIDC_REG_713080_RMSK)
+#define VIDC_REG_713080_INM(m)                 \
+	in_dword_masked(VIDC_REG_713080_ADDR,  m)
+#define VIDC_REG_713080_OUT(v)                 \
+	out_dword(VIDC_REG_713080_ADDR, v)
+#define VIDC_REG_713080_OUTM(m, v)              \
+do { \
+	out_dword_masked_ns(VIDC_REG_713080_ADDR, m, v, \
+			VIDC_REG_713080_IN); \
+} while (0)
+#define VIDC_REG_713080_ENC_ON_BMSK                  0x10
+#define VIDC_REG_713080_ENC_ON_SHFT                   0x4
+#define VIDC_REG_713080_STANDARD_SEL_BMSK             0xf
+#define VIDC_REG_713080_STANDARD_SEL_SHFT               0
+
+#define VIDC_REG_97293_ADDR                         \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000104)
+#define VIDC_REG_97293_PHYS                         \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000104)
+#define VIDC_REG_97293_RMSK                               0x1f
+#define VIDC_REG_97293_SHFT                                  0
+#define VIDC_REG_97293_IN                           \
+	in_dword_masked(VIDC_REG_97293_ADDR,  VIDC_REG_97293_RMSK)
+#define VIDC_REG_97293_INM(m)                       \
+	in_dword_masked(VIDC_REG_97293_ADDR,  m)
+#define VIDC_REG_97293_OUT(v)                       \
+	out_dword(VIDC_REG_97293_ADDR, v)
+#define VIDC_REG_97293_OUTM(m, v)                    \
+do { \
+	out_dword_masked_ns(VIDC_REG_97293_ADDR, m, v, \
+			VIDC_REG_97293_IN); \
+} while (0)
+#define VIDC_REG_97293_CH_ID_BMSK                         0x1f
+#define VIDC_REG_97293_CH_ID_SHFT                            0
+
+#define VIDC_REG_224135_ADDR                     \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000108)
+#define VIDC_REG_224135_PHYS                     \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000108)
+#define VIDC_REG_224135_RMSK                            0x1
+#define VIDC_REG_224135_SHFT                              0
+#define VIDC_REG_224135_IN                       \
+	in_dword_masked(VIDC_REG_224135_ADDR,        \
+	VIDC_REG_224135_RMSK)
+#define VIDC_REG_224135_INM(m)                   \
+	in_dword_masked(VIDC_REG_224135_ADDR,  m)
+#define VIDC_REG_224135_OUT(v)                   \
+	out_dword(VIDC_REG_224135_ADDR, v)
+#define VIDC_REG_224135_OUTM(m, v)                \
+do { \
+	out_dword_masked_ns(VIDC_REG_224135_ADDR, m, v, \
+			VIDC_REG_224135_IN); \
+} while (0)
+#define VIDC_REG_224135_CPU_RESET_BMSK                  0x1
+#define VIDC_REG_224135_CPU_RESET_SHFT                    0
+
+#define VIDC_REG_832522_ADDR                        \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000010c)
+#define VIDC_REG_832522_PHYS                        \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000010c)
+#define VIDC_REG_832522_RMSK                               0x1
+#define VIDC_REG_832522_SHFT                                 0
+#define VIDC_REG_832522_IN                          \
+	in_dword_masked(VIDC_REG_832522_ADDR,  VIDC_REG_832522_RMSK)
+#define VIDC_REG_832522_INM(m)                      \
+	in_dword_masked(VIDC_REG_832522_ADDR,  m)
+#define VIDC_REG_832522_OUT(v)                      \
+	out_dword(VIDC_REG_832522_ADDR, v)
+#define VIDC_REG_832522_OUTM(m, v)                   \
+do { \
+	out_dword_masked_ns(VIDC_REG_832522_ADDR, m, v, \
+			VIDC_REG_832522_IN); \
+} while (0)
+#define VIDC_REG_832522_FW_END_BMSK                        0x1
+#define VIDC_REG_832522_FW_END_SHFT                          0
+
+#define VIDC_REG_361582_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000110)
+#define VIDC_REG_361582_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000110)
+#define VIDC_REG_361582_RMSK                           0x1
+#define VIDC_REG_361582_SHFT                             0
+#define VIDC_REG_361582_IN                      \
+	in_dword_masked(VIDC_REG_361582_ADDR,  \
+			VIDC_REG_361582_RMSK)
+#define VIDC_REG_361582_INM(m)                  \
+	in_dword_masked(VIDC_REG_361582_ADDR,  m)
+#define VIDC_REG_361582_OUT(v)                  \
+	out_dword(VIDC_REG_361582_ADDR, v)
+#define VIDC_REG_361582_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_361582_ADDR, m, v, \
+			VIDC_REG_361582_IN); \
+} while (0)
+#define VIDC_REG_361582_BUS_MASTER_BMSK                0x1
+#define VIDC_REG_361582_BUS_MASTER_SHFT                  0
+
+#define VIDC_REG_314435_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000114)
+#define VIDC_REG_314435_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000114)
+#define VIDC_REG_314435_RMSK                          0x1
+#define VIDC_REG_314435_SHFT                            0
+#define VIDC_REG_314435_IN                     \
+	in_dword_masked(VIDC_REG_314435_ADDR,  \
+			VIDC_REG_314435_RMSK)
+#define VIDC_REG_314435_INM(m)                 \
+	in_dword_masked(VIDC_REG_314435_ADDR,  m)
+#define VIDC_REG_314435_OUT(v)                 \
+	out_dword(VIDC_REG_314435_ADDR, v)
+#define VIDC_REG_314435_OUTM(m, v)              \
+do { \
+	out_dword_masked_ns(VIDC_REG_314435_ADDR, m, v, \
+			VIDC_REG_314435_IN); \
+} while (0)
+#define VIDC_REG_314435_FRAME_START_BMSK              0x1
+#define VIDC_REG_314435_FRAME_START_SHFT                0
+
+#define VIDC_REG_999267_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000118)
+#define VIDC_REG_999267_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000118)
+#define VIDC_REG_999267_RMSK                        0xffff
+#define VIDC_REG_999267_SHFT                             0
+#define VIDC_REG_999267_IN                      \
+	in_dword_masked(VIDC_REG_999267_ADDR,  \
+			VIDC_REG_999267_RMSK)
+#define VIDC_REG_999267_INM(m)                  \
+	in_dword_masked(VIDC_REG_999267_ADDR,  m)
+#define VIDC_REG_999267_OUT(v)                  \
+	out_dword(VIDC_REG_999267_ADDR, v)
+#define VIDC_REG_999267_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_999267_ADDR, m, v, \
+			VIDC_REG_999267_IN); \
+} while (0)
+#define VIDC_REG_999267_IMG_SIZE_X_BMSK             0xffff
+#define VIDC_REG_999267_IMG_SIZE_X_SHFT                  0
+
+#define VIDC_REG_345712_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000011c)
+#define VIDC_REG_345712_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000011c)
+#define VIDC_REG_345712_RMSK                        0xffff
+#define VIDC_REG_345712_SHFT                             0
+#define VIDC_REG_345712_IN                      \
+	in_dword_masked(VIDC_REG_345712_ADDR,  \
+			VIDC_REG_345712_RMSK)
+#define VIDC_REG_345712_INM(m)                  \
+	in_dword_masked(VIDC_REG_345712_ADDR,  m)
+#define VIDC_REG_345712_OUT(v)                  \
+	out_dword(VIDC_REG_345712_ADDR, v)
+#define VIDC_REG_345712_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_345712_ADDR, m, v, \
+			VIDC_REG_345712_IN); \
+} while (0)
+#define VIDC_REG_345712_IMG_SIZE_Y_BMSK             0xffff
+#define VIDC_REG_345712_IMG_SIZE_Y_SHFT                  0
+
+#define VIDC_REG_443811_ADDR                       \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000124)
+#define VIDC_REG_443811_PHYS                       \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000124)
+#define VIDC_REG_443811_RMSK                              0x1
+#define VIDC_REG_443811_SHFT                                0
+#define VIDC_REG_443811_IN                         \
+	in_dword_masked(VIDC_REG_443811_ADDR,  VIDC_REG_443811_RMSK)
+#define VIDC_REG_443811_INM(m)                     \
+	in_dword_masked(VIDC_REG_443811_ADDR,  m)
+#define VIDC_REG_443811_OUT(v)                     \
+	out_dword(VIDC_REG_443811_ADDR, v)
+#define VIDC_REG_443811_OUTM(m, v)                  \
+do { \
+	out_dword_masked_ns(VIDC_REG_443811_ADDR, m, v, \
+			VIDC_REG_443811_IN); \
+} while (0)
+#define VIDC_REG_443811_POST_ON_BMSK                      0x1
+#define VIDC_REG_443811_POST_ON_SHFT                        0
+
+#define VIDC_REG_538267_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000128)
+#define VIDC_REG_538267_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000128)
+#define VIDC_REG_538267_RMSK                    0xffffffff
+#define VIDC_REG_538267_SHFT                             0
+#define VIDC_REG_538267_IN                      \
+	in_dword_masked(VIDC_REG_538267_ADDR,  \
+			VIDC_REG_538267_RMSK)
+#define VIDC_REG_538267_INM(m)                  \
+	in_dword_masked(VIDC_REG_538267_ADDR,  m)
+#define VIDC_REG_538267_OUT(v)                  \
+	out_dword(VIDC_REG_538267_ADDR, v)
+#define VIDC_REG_538267_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_538267_ADDR, m, v, \
+			VIDC_REG_538267_IN); \
+} while (0)
+#define VIDC_REG_538267_QUOTIENT_VAL_BMSK       0xffff0000
+#define VIDC_REG_538267_QUOTIENT_VAL_SHFT             0x10
+#define VIDC_REG_538267_REMAINDER_VAL_BMSK          0xffff
+#define VIDC_REG_538267_REMAINDER_VAL_SHFT               0
+
+#define VIDC_REG_661565_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000012c)
+#define VIDC_REG_661565_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000012c)
+#define VIDC_REG_661565_RMSK                       0x1
+#define VIDC_REG_661565_SHFT                         0
+#define VIDC_REG_661565_IN                  \
+	in_dword_masked(VIDC_REG_661565_ADDR,  \
+			VIDC_REG_661565_RMSK)
+#define VIDC_REG_661565_INM(m)              \
+	in_dword_masked(VIDC_REG_661565_ADDR,  m)
+#define VIDC_REG_661565_OUT(v)              \
+	out_dword(VIDC_REG_661565_ADDR, v)
+#define VIDC_REG_661565_OUTM(m, v)           \
+do { \
+	out_dword_masked_ns(VIDC_REG_661565_ADDR, m, v, \
+			VIDC_REG_661565_IN); \
+} while (0)
+#define VIDC_REG_661565_SEQUENCE_START_BMSK        0x1
+#define VIDC_REG_661565_SEQUENCE_START_SHFT          0
+
+#define VIDC_REG_141269_ADDR                      \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000130)
+#define VIDC_REG_141269_PHYS                      \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000130)
+#define VIDC_REG_141269_RMSK                             0x1
+#define VIDC_REG_141269_SHFT                               0
+#define VIDC_REG_141269_IN                        \
+	in_dword_masked(VIDC_REG_141269_ADDR,         \
+	VIDC_REG_141269_RMSK)
+#define VIDC_REG_141269_INM(m)                    \
+	in_dword_masked(VIDC_REG_141269_ADDR,  m)
+#define VIDC_REG_141269_OUT(v)                    \
+	out_dword(VIDC_REG_141269_ADDR, v)
+#define VIDC_REG_141269_OUTM(m, v)                 \
+do { \
+	out_dword_masked_ns(VIDC_REG_141269_ADDR, m, v, \
+			VIDC_REG_141269_IN); \
+} while (0)
+#define VIDC_REG_141269_SW_RESET_BMSK                    0x1
+#define VIDC_REG_141269_SW_RESET_SHFT                      0
+
+#define VIDC_REG_193553_ADDR                      \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000134)
+#define VIDC_REG_193553_PHYS                      \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000134)
+#define VIDC_REG_193553_RMSK                             0x1
+#define VIDC_REG_193553_SHFT                               0
+#define VIDC_REG_193553_IN                        \
+	in_dword_masked(VIDC_REG_193553_ADDR,         \
+	VIDC_REG_193553_RMSK)
+#define VIDC_REG_193553_INM(m)                    \
+	in_dword_masked(VIDC_REG_193553_ADDR,  m)
+#define VIDC_REG_193553_OUT(v)                    \
+	out_dword(VIDC_REG_193553_ADDR, v)
+#define VIDC_REG_193553_OUTM(m, v)                 \
+do { \
+	out_dword_masked_ns(VIDC_REG_193553_ADDR, m, v, \
+			VIDC_REG_193553_IN); \
+} while (0)
+#define VIDC_REG_193553_FW_START_BMSK                    0x1
+#define VIDC_REG_193553_FW_START_SHFT                      0
+
+#define VIDC_REG_215724_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000138)
+#define VIDC_REG_215724_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000138)
+#define VIDC_REG_215724_RMSK                           0x1
+#define VIDC_REG_215724_SHFT                             0
+#define VIDC_REG_215724_IN                      \
+	in_dword_masked(VIDC_REG_215724_ADDR,  \
+			VIDC_REG_215724_RMSK)
+#define VIDC_REG_215724_INM(m)                  \
+	in_dword_masked(VIDC_REG_215724_ADDR,  m)
+#define VIDC_REG_215724_OUT(v)                  \
+	out_dword(VIDC_REG_215724_ADDR, v)
+#define VIDC_REG_215724_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_215724_ADDR, m, v, \
+			VIDC_REG_215724_IN); \
+} while (0)
+#define VIDC_REG_215724_ARM_ENDIAN_BMSK                0x1
+#define VIDC_REG_215724_ARM_ENDIAN_SHFT                  0
+
+#define VIDC_REG_846346_ADDR                      \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000013c)
+#define VIDC_REG_846346_PHYS                      \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000013c)
+#define VIDC_REG_846346_RMSK                             0x1
+#define VIDC_REG_846346_SHFT                               0
+#define VIDC_REG_846346_IN                        \
+	in_dword_masked(VIDC_REG_846346_ADDR,         \
+	VIDC_REG_846346_RMSK)
+#define VIDC_REG_846346_INM(m)                    \
+	in_dword_masked(VIDC_REG_846346_ADDR,  m)
+#define VIDC_REG_846346_OUT(v)                    \
+	out_dword(VIDC_REG_846346_ADDR, v)
+#define VIDC_REG_846346_OUTM(m, v)                 \
+do { \
+	out_dword_masked_ns(VIDC_REG_846346_ADDR, m, v, \
+			VIDC_REG_846346_IN); \
+} while (0)
+#define VIDC_REG_846346_ERR_CTRL_BMSK                    0x1
+#define VIDC_REG_846346_ERR_CTRL_SHFT                      0
+
+#define VIDC_REG_765787_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000200)
+#define VIDC_REG_765787_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000200)
+#define VIDC_REG_765787_RMSK                 0xffffffff
+#define VIDC_REG_765787_SHFT                          0
+#define VIDC_REG_765787_IN                   \
+	in_dword_masked(VIDC_REG_765787_ADDR,  \
+			VIDC_REG_765787_RMSK)
+#define VIDC_REG_765787_INM(m)               \
+	in_dword_masked(VIDC_REG_765787_ADDR,  m)
+#define VIDC_REG_765787_OUT(v)               \
+	out_dword(VIDC_REG_765787_ADDR, v)
+#define VIDC_REG_765787_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_765787_ADDR, m, v, \
+			VIDC_REG_765787_IN); \
+} while (0)
+#define VIDC_REG_765787_FW_STT_ADDR_0_BMSK   0xffffffff
+#define VIDC_REG_765787_FW_STT_ADDR_0_SHFT            0
+
+#define VIDC_REG_225040_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000204)
+#define VIDC_REG_225040_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000204)
+#define VIDC_REG_225040_RMSK                 0xffffffff
+#define VIDC_REG_225040_SHFT                          0
+#define VIDC_REG_225040_IN                   \
+	in_dword_masked(VIDC_REG_225040_ADDR,  \
+			VIDC_REG_225040_RMSK)
+#define VIDC_REG_225040_INM(m)               \
+	in_dword_masked(VIDC_REG_225040_ADDR,  m)
+#define VIDC_REG_225040_OUT(v)               \
+	out_dword(VIDC_REG_225040_ADDR, v)
+#define VIDC_REG_225040_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_225040_ADDR, m, v, \
+			VIDC_REG_225040_IN); \
+} while (0)
+#define VIDC_REG_225040_FW_STT_ADDR_1_BMSK   0xffffffff
+#define VIDC_REG_225040_FW_STT_ADDR_1_SHFT            0
+
+#define VIDC_REG_942456_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000208)
+#define VIDC_REG_942456_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000208)
+#define VIDC_REG_942456_RMSK                 0xffffffff
+#define VIDC_REG_942456_SHFT                          0
+#define VIDC_REG_942456_IN                   \
+	in_dword_masked(VIDC_REG_942456_ADDR,  \
+			VIDC_REG_942456_RMSK)
+#define VIDC_REG_942456_INM(m)               \
+	in_dword_masked(VIDC_REG_942456_ADDR,  m)
+#define VIDC_REG_942456_OUT(v)               \
+	out_dword(VIDC_REG_942456_ADDR, v)
+#define VIDC_REG_942456_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_942456_ADDR, m, v, \
+			VIDC_REG_942456_IN); \
+} while (0)
+#define VIDC_REG_942456_FW_STT_ADDR_2_BMSK   0xffffffff
+#define VIDC_REG_942456_FW_STT_ADDR_2_SHFT            0
+
+#define VIDC_REG_942170_ADDR_3_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000020c)
+#define VIDC_REG_942170_ADDR_3_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000020c)
+#define VIDC_REG_942170_ADDR_3_RMSK                 0xffffffff
+#define VIDC_REG_942170_ADDR_3_SHFT                          0
+#define VIDC_REG_942170_ADDR_3_IN                   \
+	in_dword_masked(VIDC_REG_942170_ADDR_3_ADDR,  \
+			VIDC_REG_942170_ADDR_3_RMSK)
+#define VIDC_REG_942170_ADDR_3_INM(m)               \
+	in_dword_masked(VIDC_REG_942170_ADDR_3_ADDR,  m)
+#define VIDC_REG_942170_ADDR_3_OUT(v)               \
+	out_dword(VIDC_REG_942170_ADDR_3_ADDR, v)
+#define VIDC_REG_942170_ADDR_3_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_942170_ADDR_3_ADDR, m, v, \
+			VIDC_REG_942170_ADDR_3_IN); \
+} while (0)
+#define VIDC_REG_942170_ADDR_3_FW_STT_ADDR_3_BMSK   0xffffffff
+#define VIDC_REG_942170_ADDR_3_FW_STT_ADDR_3_SHFT            0
+
+#define VIDC_REG_880188_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000210)
+#define VIDC_REG_880188_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000210)
+#define VIDC_REG_880188_RMSK                 0xffffffff
+#define VIDC_REG_880188_SHFT                          0
+#define VIDC_REG_880188_IN                   \
+	in_dword_masked(VIDC_REG_880188_ADDR,  \
+			VIDC_REG_880188_RMSK)
+#define VIDC_REG_880188_INM(m)               \
+	in_dword_masked(VIDC_REG_880188_ADDR,  m)
+#define VIDC_REG_880188_OUT(v)               \
+	out_dword(VIDC_REG_880188_ADDR, v)
+#define VIDC_REG_880188_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_880188_ADDR, m, v, \
+			VIDC_REG_880188_IN); \
+} while (0)
+#define VIDC_REG_880188_FW_STT_ADDR_4_BMSK   0xffffffff
+#define VIDC_REG_880188_FW_STT_ADDR_4_SHFT            0
+
+#define VIDC_REG_40293_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000214)
+#define VIDC_REG_40293_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000214)
+#define VIDC_REG_40293_RMSK                 0xffffffff
+#define VIDC_REG_40293_SHFT                          0
+#define VIDC_REG_40293_IN                   \
+	in_dword_masked(VIDC_REG_40293_ADDR,  \
+			VIDC_REG_40293_RMSK)
+#define VIDC_REG_40293_INM(m)               \
+	in_dword_masked(VIDC_REG_40293_ADDR,  m)
+#define VIDC_REG_40293_OUT(v)               \
+	out_dword(VIDC_REG_40293_ADDR, v)
+#define VIDC_REG_40293_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_40293_ADDR, m, v, \
+			VIDC_REG_40293_IN); \
+} while (0)
+#define VIDC_REG_40293_FW_STT_ADDR_5_BMSK   0xffffffff
+#define VIDC_REG_40293_FW_STT_ADDR_5_SHFT            0
+
+#define VIDC_REG_942170_ADDR_6_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000218)
+#define VIDC_REG_942170_ADDR_6_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000218)
+#define VIDC_REG_942170_ADDR_6_RMSK                 0xffffffff
+#define VIDC_REG_942170_ADDR_6_SHFT                          0
+#define VIDC_REG_942170_ADDR_6_IN                   \
+	in_dword_masked(VIDC_REG_942170_ADDR_6_ADDR,  \
+			VIDC_REG_942170_ADDR_6_RMSK)
+#define VIDC_REG_942170_ADDR_6_INM(m)               \
+	in_dword_masked(VIDC_REG_942170_ADDR_6_ADDR,  m)
+#define VIDC_REG_942170_ADDR_6_OUT(v)               \
+	out_dword(VIDC_REG_942170_ADDR_6_ADDR, v)
+#define VIDC_REG_942170_ADDR_6_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_942170_ADDR_6_ADDR, m, v, \
+			VIDC_REG_942170_ADDR_6_IN); \
+} while (0)
+#define VIDC_REG_942170_ADDR_6_FW_STT_ADDR_6_BMSK   0xffffffff
+#define VIDC_REG_942170_ADDR_6_FW_STT_ADDR_6_SHFT            0
+
+#define VIDC_REG_958768_ADDR                  \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000230)
+#define VIDC_REG_958768_PHYS                  \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000230)
+#define VIDC_REG_958768_RMSK                  0xffffffff
+#define VIDC_REG_958768_SHFT                           0
+#define VIDC_REG_958768_IN                    \
+	in_dword_masked(VIDC_REG_958768_ADDR,  \
+			VIDC_REG_958768_RMSK)
+#define VIDC_REG_958768_INM(m)                \
+	in_dword_masked(VIDC_REG_958768_ADDR,  m)
+#define VIDC_REG_958768_OUT(v)                \
+	out_dword(VIDC_REG_958768_ADDR, v)
+#define VIDC_REG_958768_OUTM(m, v)             \
+do { \
+	out_dword_masked_ns(VIDC_REG_958768_ADDR, m, v, \
+			VIDC_REG_958768_IN); \
+} while (0)
+#define VIDC_REG_699384_ADDR_BMSK     0xffffffff
+#define VIDC_REG_699384_ADDR_SHFT              0
+
+#define VIDC_REG_979942_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000234)
+#define VIDC_REG_979942_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000234)
+#define VIDC_REG_979942_RMSK                   0xffffffff
+#define VIDC_REG_979942_SHFT                            0
+#define VIDC_REG_979942_IN                     \
+	in_dword_masked(VIDC_REG_979942_ADDR,  \
+			VIDC_REG_979942_RMSK)
+#define VIDC_REG_979942_INM(m)                 \
+	in_dword_masked(VIDC_REG_979942_ADDR,  m)
+#define VIDC_REG_979942_OUT(v)                 \
+	out_dword(VIDC_REG_979942_ADDR, v)
+#define VIDC_REG_979942_OUTM(m, v)              \
+do { \
+	out_dword_masked_ns(VIDC_REG_979942_ADDR, m, v, \
+			VIDC_REG_979942_IN); \
+} while (0)
+#define VIDC_REG_979942_DB_STT_ADDR_BMSK       0xffffffff
+#define VIDC_REG_979942_DB_STT_ADDR_SHFT                0
+
+#define VIDC_REG_839021_ADDR                       \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000300)
+#define VIDC_REG_839021_PHYS                       \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000300)
+#define VIDC_REG_839021_RMSK                           0xff1f
+#define VIDC_REG_839021_SHFT                                0
+#define VIDC_REG_839021_IN                         \
+	in_dword_masked(VIDC_REG_839021_ADDR,  VIDC_REG_839021_RMSK)
+#define VIDC_REG_839021_INM(m)                     \
+	in_dword_masked(VIDC_REG_839021_ADDR,  m)
+#define VIDC_REG_839021_OUT(v)                     \
+	out_dword(VIDC_REG_839021_ADDR, v)
+#define VIDC_REG_839021_OUTM(m, v)                  \
+do { \
+	out_dword_masked_ns(VIDC_REG_839021_ADDR, m, v, \
+			VIDC_REG_839021_IN); \
+} while (0)
+#define VIDC_REG_839021_LEVEL_BMSK                     0xff00
+#define VIDC_REG_839021_LEVEL_SHFT                        0x8
+#define VIDC_REG_839021_PROFILE_BMSK                     0x1f
+#define VIDC_REG_839021_PROFILE_SHFT                        0
+
+#define VIDC_REG_950374_ADDR                      \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000308)
+#define VIDC_REG_950374_PHYS                      \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000308)
+#define VIDC_REG_950374_RMSK                          0xffff
+#define VIDC_REG_950374_SHFT                               0
+#define VIDC_REG_950374_IN                        \
+	in_dword_masked(VIDC_REG_950374_ADDR,         \
+	VIDC_REG_950374_RMSK)
+#define VIDC_REG_950374_INM(m)                    \
+	in_dword_masked(VIDC_REG_950374_ADDR,  m)
+#define VIDC_REG_950374_OUT(v)                    \
+	out_dword(VIDC_REG_950374_ADDR, v)
+#define VIDC_REG_950374_OUTM(m, v)                 \
+do { \
+	out_dword_masked_ns(VIDC_REG_950374_ADDR, m, v, \
+			VIDC_REG_950374_IN); \
+} while (0)
+#define VIDC_REG_950374_I_PERIOD_BMSK                 0xffff
+#define VIDC_REG_950374_I_PERIOD_SHFT                      0
+
+#define VIDC_REG_504878_ADDR               \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000310)
+#define VIDC_REG_504878_PHYS               \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000310)
+#define VIDC_REG_504878_RMSK                      0xd
+#define VIDC_REG_504878_SHFT                        0
+#define VIDC_REG_504878_IN                 \
+	in_dword_masked(VIDC_REG_504878_ADDR,  \
+			VIDC_REG_504878_RMSK)
+#define VIDC_REG_504878_INM(m)             \
+	in_dword_masked(VIDC_REG_504878_ADDR,  m)
+#define VIDC_REG_504878_OUT(v)             \
+	out_dword(VIDC_REG_504878_ADDR, v)
+#define VIDC_REG_504878_OUTM(m, v)          \
+do { \
+	out_dword_masked_ns(VIDC_REG_504878_ADDR, m, v, \
+			VIDC_REG_504878_IN); \
+} while (0)
+#define VIDC_REG_504878_FIXED_NUMBER_BMSK         0xc
+#define VIDC_REG_504878_FIXED_NUMBER_SHFT         0x2
+#define VIDC_REG_504878_ENTROPY_SEL_BMSK          0x1
+#define VIDC_REG_504878_ENTROPY_SEL_SHFT            0
+
+#define VIDC_REG_458130_ADDR            \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000314)
+#define VIDC_REG_458130_PHYS            \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000314)
+#define VIDC_REG_458130_RMSK                 0xfff
+#define VIDC_REG_458130_SHFT                     0
+#define VIDC_REG_458130_IN              \
+	in_dword_masked(VIDC_REG_458130_ADDR,  \
+			VIDC_REG_458130_RMSK)
+#define VIDC_REG_458130_INM(m)          \
+	in_dword_masked(VIDC_REG_458130_ADDR,  m)
+#define VIDC_REG_458130_OUT(v)          \
+	out_dword(VIDC_REG_458130_ADDR, v)
+#define VIDC_REG_458130_OUTM(m, v)       \
+do { \
+	out_dword_masked_ns(VIDC_REG_458130_ADDR, m, v, \
+			VIDC_REG_458130_IN); \
+} while (0)
+#define VIDC_REG_458130_SLICE_ALPHA_C0_OFFSET_DIV2_BMSK      \
+	0xf80
+#define VIDC_REG_458130_SLICE_ALPHA_C0_OFFSET_DIV2_SHFT      \
+	0x7
+#define VIDC_REG_458130_SLICE_BETA_OFFSET_DIV2_BMSK       0x7c
+#define VIDC_REG_458130_SLICE_BETA_OFFSET_DIV2_SHFT        0x2
+#define \
+	\
+VIDC_REG_458130_DISABLE_DEBLOCKING_FILTER_IDC_BMSK        0x3
+#define \
+	\
+VIDC_REG_458130_DISABLE_DEBLOCKING_FILTER_IDC_SHFT          0
+
+#define VIDC_REG_314290_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000318)
+#define VIDC_REG_314290_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000318)
+#define VIDC_REG_314290_RMSK                          0x1
+#define VIDC_REG_314290_SHFT                            0
+#define VIDC_REG_314290_IN                     \
+	in_dword_masked(VIDC_REG_314290_ADDR,  \
+			VIDC_REG_314290_RMSK)
+#define VIDC_REG_314290_INM(m)                 \
+	in_dword_masked(VIDC_REG_314290_ADDR,  m)
+#define VIDC_REG_314290_OUT(v)                 \
+	out_dword(VIDC_REG_314290_ADDR, v)
+#define VIDC_REG_314290_OUTM(m, v)              \
+do { \
+	out_dword_masked_ns(VIDC_REG_314290_ADDR, m, v, \
+			VIDC_REG_314290_IN); \
+} while (0)
+#define VIDC_REG_314290_SHORT_HD_ON_BMSK              0x1
+#define VIDC_REG_314290_SHORT_HD_ON_SHFT                0
+
+#define VIDC_REG_588301_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000031c)
+#define VIDC_REG_588301_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000031c)
+#define VIDC_REG_588301_RMSK                           0x1
+#define VIDC_REG_588301_SHFT                             0
+#define VIDC_REG_588301_IN                      \
+	in_dword_masked(VIDC_REG_588301_ADDR,  \
+			VIDC_REG_588301_RMSK)
+#define VIDC_REG_588301_INM(m)                  \
+	in_dword_masked(VIDC_REG_588301_ADDR,  m)
+#define VIDC_REG_588301_OUT(v)                  \
+	out_dword(VIDC_REG_588301_ADDR, v)
+#define VIDC_REG_588301_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_588301_ADDR, m, v, \
+			VIDC_REG_588301_IN); \
+} while (0)
+#define VIDC_REG_588301_MSLICE_ENA_BMSK                0x1
+#define VIDC_REG_588301_MSLICE_ENA_SHFT                  0
+
+#define VIDC_REG_1517_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000320)
+#define VIDC_REG_1517_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000320)
+#define VIDC_REG_1517_RMSK                           0x3
+#define VIDC_REG_1517_SHFT                             0
+#define VIDC_REG_1517_IN                      \
+	in_dword_masked(VIDC_REG_1517_ADDR,  \
+			VIDC_REG_1517_RMSK)
+#define VIDC_REG_1517_INM(m)                  \
+	in_dword_masked(VIDC_REG_1517_ADDR,  m)
+#define VIDC_REG_1517_OUT(v)                  \
+	out_dword(VIDC_REG_1517_ADDR, v)
+#define VIDC_REG_1517_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_1517_ADDR, m, v, \
+			VIDC_REG_1517_IN); \
+} while (0)
+#define VIDC_REG_1517_MSLICE_SEL_BMSK                0x3
+#define VIDC_REG_1517_MSLICE_SEL_SHFT                  0
+
+#define VIDC_REG_105335_ADDR                     \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000324)
+#define VIDC_REG_105335_PHYS                     \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000324)
+#define VIDC_REG_105335_RMSK                     0xffffffff
+#define VIDC_REG_105335_SHFT                              0
+#define VIDC_REG_105335_IN                       \
+	in_dword_masked(VIDC_REG_105335_ADDR,        \
+	VIDC_REG_105335_RMSK)
+#define VIDC_REG_105335_INM(m)                   \
+	in_dword_masked(VIDC_REG_105335_ADDR,  m)
+#define VIDC_REG_105335_OUT(v)                   \
+	out_dword(VIDC_REG_105335_ADDR, v)
+#define VIDC_REG_105335_OUTM(m, v)                \
+do { \
+	out_dword_masked_ns(VIDC_REG_105335_ADDR, m, v, \
+			VIDC_REG_105335_IN); \
+} while (0)
+#define VIDC_REG_105335_MSLICE_MB_BMSK           0xffffffff
+#define VIDC_REG_105335_MSLICE_MB_SHFT                    0
+
+#define VIDC_REG_561679_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000328)
+#define VIDC_REG_561679_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000328)
+#define VIDC_REG_561679_RMSK                   0xffffffff
+#define VIDC_REG_561679_SHFT                            0
+#define VIDC_REG_561679_IN                     \
+	in_dword_masked(VIDC_REG_561679_ADDR,  \
+			VIDC_REG_561679_RMSK)
+#define VIDC_REG_561679_INM(m)                 \
+	in_dword_masked(VIDC_REG_561679_ADDR,  m)
+#define VIDC_REG_561679_OUT(v)                 \
+	out_dword(VIDC_REG_561679_ADDR, v)
+#define VIDC_REG_561679_OUTM(m, v)              \
+do { \
+	out_dword_masked_ns(VIDC_REG_561679_ADDR, m, v, \
+			VIDC_REG_561679_IN); \
+} while (0)
+#define VIDC_REG_561679_MSLICE_BYTE_BMSK       0xffffffff
+#define VIDC_REG_561679_MSLICE_BYTE_SHFT                0
+
+#define VIDC_REG_151345_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000400)
+#define VIDC_REG_151345_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000400)
+#define VIDC_REG_151345_RMSK                 0xffffffff
+#define VIDC_REG_151345_SHFT                          0
+#define VIDC_REG_151345_IN                   \
+	in_dword_masked(VIDC_REG_151345_ADDR,  \
+			VIDC_REG_151345_RMSK)
+#define VIDC_REG_151345_INM(m)               \
+	in_dword_masked(VIDC_REG_151345_ADDR,  m)
+#define VIDC_REG_151345_DISPLAY_Y_ADR_BMSK   0xffffffff
+#define VIDC_REG_151345_DISPLAY_Y_ADR_SHFT            0
+
+#define VIDC_REG_293983_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000404)
+#define VIDC_REG_293983_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000404)
+#define VIDC_REG_293983_RMSK                 0xffffffff
+#define VIDC_REG_293983_SHFT                          0
+#define VIDC_REG_293983_IN                   \
+	in_dword_masked(VIDC_REG_293983_ADDR,  \
+			VIDC_REG_293983_RMSK)
+#define VIDC_REG_293983_INM(m)               \
+	in_dword_masked(VIDC_REG_293983_ADDR,  m)
+#define VIDC_REG_293983_DISPLAY_C_ADR_BMSK   0xffffffff
+#define VIDC_REG_293983_DISPLAY_C_ADR_SHFT            0
+
+#define VIDC_REG_612715_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000408)
+#define VIDC_REG_612715_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000408)
+#define VIDC_REG_612715_RMSK                      0x3f
+#define VIDC_REG_612715_SHFT                         0
+#define VIDC_REG_612715_IN                  \
+	in_dword_masked(VIDC_REG_612715_ADDR,  \
+			VIDC_REG_612715_RMSK)
+#define VIDC_REG_612715_INM(m)              \
+	in_dword_masked(VIDC_REG_612715_ADDR,  m)
+#define VIDC_REG_612715_DISPLAY_STATUS_BMSK       0x3f
+#define VIDC_REG_612715_DISPLAY_STATUS_SHFT          0
+
+#define VIDC_REG_209364_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000040c)
+#define VIDC_REG_209364_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000040c)
+#define VIDC_REG_209364_RMSK                          0x1
+#define VIDC_REG_209364_SHFT                            0
+#define VIDC_REG_209364_IN                     \
+	in_dword_masked(VIDC_REG_209364_ADDR,  \
+			VIDC_REG_209364_RMSK)
+#define VIDC_REG_209364_INM(m)                 \
+	in_dword_masked(VIDC_REG_209364_ADDR,  m)
+#define VIDC_REG_209364_HEADER_DONE_BMSK              0x1
+#define VIDC_REG_209364_HEADER_DONE_SHFT                0
+
+#define VIDC_REG_757835_ADDR                     \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000410)
+#define VIDC_REG_757835_PHYS                     \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000410)
+#define VIDC_REG_757835_RMSK                     0xffffffff
+#define VIDC_REG_757835_SHFT                              0
+#define VIDC_REG_757835_IN                       \
+	in_dword_masked(VIDC_REG_757835_ADDR,        \
+	VIDC_REG_757835_RMSK)
+#define VIDC_REG_757835_INM(m)                   \
+	in_dword_masked(VIDC_REG_757835_ADDR,  m)
+#define VIDC_REG_757835_FRAME_NUM_BMSK           0xffffffff
+#define VIDC_REG_757835_FRAME_NUM_SHFT                    0
+
+#define VIDC_REG_352831_ADDR              \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000414)
+#define VIDC_REG_352831_PHYS              \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000414)
+#define VIDC_REG_352831_RMSK              0xffffffff
+#define VIDC_REG_352831_SHFT                       0
+#define VIDC_REG_352831_IN                \
+	in_dword_masked(VIDC_REG_352831_ADDR,  \
+			VIDC_REG_352831_RMSK)
+#define VIDC_REG_352831_INM(m)            \
+	in_dword_masked(VIDC_REG_352831_ADDR,  m)
+#define VIDC_REG_352831_DBG_INFO_OUTPUT0_BMSK 0xffffffff
+#define VIDC_REG_352831_DBG_INFO_OUTPUT0_SHFT          0
+
+#define VIDC_REG_668634_ADDR              \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000418)
+#define VIDC_REG_668634_PHYS              \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000418)
+#define VIDC_REG_668634_RMSK              0xffffffff
+#define VIDC_REG_668634_SHFT                       0
+#define VIDC_REG_668634_IN                \
+	in_dword_masked(VIDC_REG_668634_ADDR,  \
+			VIDC_REG_668634_RMSK)
+#define VIDC_REG_668634_INM(m)            \
+	in_dword_masked(VIDC_REG_668634_ADDR,  m)
+#define VIDC_REG_668634_DBG_INFO_OUTPUT1_BMSK 0xffffffff
+#define VIDC_REG_668634_DBG_INFO_OUTPUT1_SHFT          0
+
+#define VIDC_REG_609676_ADDR                       \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000500)
+#define VIDC_REG_609676_PHYS                       \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000500)
+#define VIDC_REG_609676_RMSK                              0x1
+#define VIDC_REG_609676_SHFT                                0
+#define VIDC_REG_609676_IN                         \
+	in_dword_masked(VIDC_REG_609676_ADDR,  VIDC_REG_609676_RMSK)
+#define VIDC_REG_609676_INM(m)                     \
+	in_dword_masked(VIDC_REG_609676_ADDR,  m)
+#define VIDC_REG_609676_OUT(v)                     \
+	out_dword(VIDC_REG_609676_ADDR, v)
+#define VIDC_REG_609676_OUTM(m, v)                  \
+do { \
+	out_dword_masked_ns(VIDC_REG_609676_ADDR, m, v, \
+			VIDC_REG_609676_IN); \
+} while (0)
+#define VIDC_REG_609676_INT_OFF_BMSK                      0x1
+#define VIDC_REG_609676_INT_OFF_SHFT                        0
+
+#define VIDC_REG_491082_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000504)
+#define VIDC_REG_491082_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000504)
+#define VIDC_REG_491082_RMSK                        0x1
+#define VIDC_REG_491082_SHFT                          0
+#define VIDC_REG_491082_IN                   \
+	in_dword_masked(VIDC_REG_491082_ADDR,  \
+			VIDC_REG_491082_RMSK)
+#define VIDC_REG_491082_INM(m)               \
+	in_dword_masked(VIDC_REG_491082_ADDR,  m)
+#define VIDC_REG_491082_OUT(v)               \
+	out_dword(VIDC_REG_491082_ADDR, v)
+#define VIDC_REG_491082_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_491082_ADDR, m, v, \
+			VIDC_REG_491082_IN); \
+} while (0)
+#define VIDC_REG_491082_INT_PULSE_SEL_BMSK          0x1
+#define VIDC_REG_491082_INT_PULSE_SEL_SHFT            0
+
+#define VIDC_REG_614776_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000508)
+#define VIDC_REG_614776_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000508)
+#define VIDC_REG_614776_RMSK                       0x1
+#define VIDC_REG_614776_SHFT                         0
+#define VIDC_REG_614776_IN                  \
+	in_dword_masked(VIDC_REG_614776_ADDR,  \
+			VIDC_REG_614776_RMSK)
+#define VIDC_REG_614776_INM(m)              \
+	in_dword_masked(VIDC_REG_614776_ADDR,  m)
+#define VIDC_REG_614776_OUT(v)              \
+	out_dword(VIDC_REG_614776_ADDR, v)
+#define VIDC_REG_614776_OUTM(m, v)           \
+do { \
+	out_dword_masked_ns(VIDC_REG_614776_ADDR, m, v, \
+			VIDC_REG_614776_IN); \
+} while (0)
+#define VIDC_REG_614776_INT_DONE_CLEAR_BMSK        0x1
+#define VIDC_REG_614776_INT_DONE_CLEAR_SHFT          0
+
+#define VIDC_REG_982553_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000050c)
+#define VIDC_REG_982553_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000050c)
+#define VIDC_REG_982553_RMSK                       0x1
+#define VIDC_REG_982553_SHFT                         0
+#define VIDC_REG_982553_IN                  \
+	in_dword_masked(VIDC_REG_982553_ADDR,  \
+			VIDC_REG_982553_RMSK)
+#define VIDC_REG_982553_INM(m)              \
+	in_dword_masked(VIDC_REG_982553_ADDR,  m)
+#define VIDC_REG_982553_OPERATION_DONE_BMSK        0x1
+#define VIDC_REG_982553_OPERATION_DONE_SHFT          0
+
+#define VIDC_REG_259967_ADDR                       \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000510)
+#define VIDC_REG_259967_PHYS                       \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000510)
+#define VIDC_REG_259967_RMSK                              0x1
+#define VIDC_REG_259967_SHFT                                0
+#define VIDC_REG_259967_IN                         \
+	in_dword_masked(VIDC_REG_259967_ADDR,  VIDC_REG_259967_RMSK)
+#define VIDC_REG_259967_INM(m)                     \
+	in_dword_masked(VIDC_REG_259967_ADDR,  m)
+#define VIDC_REG_259967_FW_DONE_BMSK                      0x1
+#define VIDC_REG_259967_FW_DONE_SHFT                        0
+
+#define VIDC_REG_512143_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000514)
+#define VIDC_REG_512143_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000514)
+#define VIDC_REG_512143_RMSK                         0x1f8
+#define VIDC_REG_512143_SHFT                             0
+#define VIDC_REG_512143_IN                      \
+	in_dword_masked(VIDC_REG_512143_ADDR,  \
+			VIDC_REG_512143_RMSK)
+#define VIDC_REG_512143_INM(m)                  \
+	in_dword_masked(VIDC_REG_512143_ADDR,  m)
+#define VIDC_REG_512143_FRAME_DONE_STAT_BMSK         0x100
+#define VIDC_REG_512143_FRAME_DONE_STAT_SHFT           0x8
+#define VIDC_REG_512143_DMA_DONE_STAT_BMSK            0x80
+#define VIDC_REG_512143_DMA_DONE_STAT_SHFT             0x7
+#define VIDC_REG_512143_HEADER_DONE_STAT_BMSK         0x40
+#define VIDC_REG_512143_HEADER_DONE_STAT_SHFT          0x6
+#define VIDC_REG_512143_FW_DONE_STAT_BMSK             0x20
+#define VIDC_REG_512143_FW_DONE_STAT_SHFT              0x5
+#define VIDC_REG_512143_OPERATION_FAILED_BMSK         0x10
+#define VIDC_REG_512143_OPERATION_FAILED_SHFT          0x4
+#define VIDC_REG_512143_STREAM_HDR_CHANGED_BMSK        0x8
+#define VIDC_REG_512143_STREAM_HDR_CHANGED_SHFT        0x3
+
+#define VIDC_REG_418173_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000518)
+#define VIDC_REG_418173_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000518)
+#define VIDC_REG_418173_RMSK                     0x1fa
+#define VIDC_REG_418173_SHFT                         0
+#define VIDC_REG_418173_IN                  \
+	in_dword_masked(VIDC_REG_418173_ADDR,  \
+			VIDC_REG_418173_RMSK)
+#define VIDC_REG_418173_INM(m)              \
+	in_dword_masked(VIDC_REG_418173_ADDR,  m)
+#define VIDC_REG_418173_OUT(v)              \
+	out_dword(VIDC_REG_418173_ADDR, v)
+#define VIDC_REG_418173_OUTM(m, v)           \
+do { \
+	out_dword_masked_ns(VIDC_REG_418173_ADDR, m, v, \
+			VIDC_REG_418173_IN); \
+} while (0)
+#define VIDC_REG_418173_FRAME_DONE_ENABLE_BMSK      0x100
+#define VIDC_REG_418173_FRAME_DONE_ENABLE_SHFT        0x8
+#define VIDC_REG_418173_DMA_DONE_ENABLE_BMSK       0x80
+#define VIDC_REG_418173_DMA_DONE_ENABLE_SHFT        0x7
+#define VIDC_REG_418173_HEADER_DONE_ENABLE_BMSK       0x40
+#define VIDC_REG_418173_HEADER_DONE_ENABLE_SHFT        0x6
+#define VIDC_REG_418173_FW_DONE_ENABLE_BMSK       0x20
+#define VIDC_REG_418173_FW_DONE_ENABLE_SHFT        0x5
+#define VIDC_REG_418173_OPERATION_FAILED_ENABLE_BMSK       0x10
+#define VIDC_REG_418173_OPERATION_FAILED_ENABLE_SHFT        0x4
+#define VIDC_REG_418173_STREAM_HDR_CHANGED_ENABLE_BMSK        0x8
+#define VIDC_REG_418173_STREAM_HDR_CHANGED_ENABLE_SHFT        0x3
+#define VIDC_REG_418173_BUFFER_FULL_ENABLE_BMSK        0x2
+#define VIDC_REG_418173_BUFFER_FULL_ENABLE_SHFT        0x1
+
+#define VIDC_REG_841539_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000600)
+#define VIDC_REG_841539_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000600)
+#define VIDC_REG_841539_RMSK                       0x3
+#define VIDC_REG_841539_SHFT                         0
+#define VIDC_REG_841539_IN                  \
+	in_dword_masked(VIDC_REG_841539_ADDR,  \
+			VIDC_REG_841539_RMSK)
+#define VIDC_REG_841539_INM(m)              \
+	in_dword_masked(VIDC_REG_841539_ADDR,  m)
+#define VIDC_REG_841539_OUT(v)              \
+	out_dword(VIDC_REG_841539_ADDR, v)
+#define VIDC_REG_841539_OUTM(m, v)           \
+do { \
+	out_dword_masked_ns(VIDC_REG_841539_ADDR, m, v, \
+			VIDC_REG_841539_IN); \
+} while (0)
+#define VIDC_REG_841539_TILE_MODE_BMSK             0x3
+#define VIDC_REG_841539_TILE_MODE_SHFT               0
+
+#define VIDC_REG_99105_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000800)
+#define VIDC_REG_99105_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000800)
+#define VIDC_REG_99105_RMSK                0xffffffff
+#define VIDC_REG_99105_SHFT                         0
+#define VIDC_REG_99105_IN                  \
+	in_dword_masked(VIDC_REG_99105_ADDR,  \
+			VIDC_REG_99105_RMSK)
+#define VIDC_REG_99105_INM(m)              \
+	in_dword_masked(VIDC_REG_99105_ADDR,  m)
+#define VIDC_REG_99105_OUT(v)              \
+	out_dword(VIDC_REG_99105_ADDR, v)
+#define VIDC_REG_99105_OUTM(m, v)           \
+do { \
+	out_dword_masked_ns(VIDC_REG_99105_ADDR, m, v, \
+			VIDC_REG_99105_IN); \
+} while (0)
+#define VIDC_REG_99105_ENC_CUR_Y_ADDR_BMSK 0xffffffff
+#define VIDC_REG_99105_ENC_CUR_Y_ADDR_SHFT          0
+
+#define VIDC_REG_777113_ADDR_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000804)
+#define VIDC_REG_777113_ADDR_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000804)
+#define VIDC_REG_777113_ADDR_RMSK                0xffffffff
+#define VIDC_REG_777113_ADDR_SHFT                         0
+#define VIDC_REG_777113_ADDR_IN                  \
+	in_dword_masked(VIDC_REG_777113_ADDR_ADDR,  \
+			VIDC_REG_777113_ADDR_RMSK)
+#define VIDC_REG_777113_ADDR_INM(m)              \
+	in_dword_masked(VIDC_REG_777113_ADDR_ADDR,  m)
+#define VIDC_REG_777113_ADDR_OUT(v)              \
+	out_dword(VIDC_REG_777113_ADDR_ADDR, v)
+#define VIDC_REG_777113_ADDR_OUTM(m, v)           \
+do { \
+	out_dword_masked_ns(VIDC_REG_777113_ADDR_ADDR, m, v, \
+			VIDC_REG_777113_ADDR_IN); \
+} while (0)
+#define VIDC_REG_777113_ADDR_ENC_CUR_C_ADDR_BMSK 0xffffffff
+#define VIDC_REG_777113_ADDR_ENC_CUR_C_ADDR_SHFT          0
+
+#define VIDC_REG_341928_ADDR_ADDR                  \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000080c)
+#define VIDC_REG_341928_ADDR_PHYS                  \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000080c)
+#define VIDC_REG_341928_ADDR_RMSK                  0xffffffff
+#define VIDC_REG_341928_ADDR_SHFT                           0
+#define VIDC_REG_341928_ADDR_IN                    \
+	in_dword_masked(VIDC_REG_341928_ADDR_ADDR,  \
+			VIDC_REG_341928_ADDR_RMSK)
+#define VIDC_REG_341928_ADDR_INM(m)                \
+	in_dword_masked(VIDC_REG_341928_ADDR_ADDR,  m)
+#define VIDC_REG_341928_ADDR_OUT(v)                \
+	out_dword(VIDC_REG_341928_ADDR_ADDR, v)
+#define VIDC_REG_341928_ADDR_OUTM(m, v)             \
+do { \
+	out_dword_masked_ns(VIDC_REG_341928_ADDR_ADDR, m, v, \
+			VIDC_REG_341928_ADDR_IN); \
+} while (0)
+#define VIDC_REG_341928_ADDR_ENC_DPB_ADR_BMSK      0xffffffff
+#define VIDC_REG_341928_ADDR_ENC_DPB_ADR_SHFT               0
+
+#define VIDC_REG_857491_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000810)
+#define VIDC_REG_857491_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000810)
+#define VIDC_REG_857491_RMSK                         0xfff
+#define VIDC_REG_857491_SHFT                             0
+#define VIDC_REG_857491_IN                      \
+	in_dword_masked(VIDC_REG_857491_ADDR,  \
+			VIDC_REG_857491_RMSK)
+#define VIDC_REG_857491_INM(m)                  \
+	in_dword_masked(VIDC_REG_857491_ADDR,  m)
+#define VIDC_REG_857491_OUT(v)                  \
+	out_dword(VIDC_REG_857491_ADDR, v)
+#define VIDC_REG_857491_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_857491_ADDR, m, v, \
+			VIDC_REG_857491_IN); \
+} while (0)
+#define VIDC_REG_857491_CIR_MB_NUM_BMSK              0xfff
+#define VIDC_REG_857491_CIR_MB_NUM_SHFT                  0
+
+#define VIDC_REG_518133_ADDR                  \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000900)
+#define VIDC_REG_518133_PHYS                  \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000900)
+#define VIDC_REG_518133_RMSK                  0xffffffff
+#define VIDC_REG_518133_SHFT                           0
+#define VIDC_REG_518133_IN                    \
+	in_dword_masked(VIDC_REG_518133_ADDR,  \
+			VIDC_REG_518133_RMSK)
+#define VIDC_REG_518133_INM(m)                \
+	in_dword_masked(VIDC_REG_518133_ADDR,  m)
+#define VIDC_REG_518133_OUT(v)                \
+	out_dword(VIDC_REG_518133_ADDR, v)
+#define VIDC_REG_518133_OUTM(m, v)             \
+do { \
+	out_dword_masked_ns(VIDC_REG_518133_ADDR, m, v, \
+			VIDC_REG_518133_IN); \
+} while (0)
+#define VIDC_REG_518133_DEC_DPB_ADDR_BMSK     0xffffffff
+#define VIDC_REG_518133_DEC_DPB_ADDR_SHFT              0
+
+#define VIDC_REG_456376_ADDR_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000904)
+#define VIDC_REG_456376_ADDR_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000904)
+#define VIDC_REG_456376_ADDR_RMSK                 0xffffffff
+#define VIDC_REG_456376_ADDR_SHFT                          0
+#define VIDC_REG_456376_ADDR_IN                   \
+	in_dword_masked(VIDC_REG_456376_ADDR_ADDR,  \
+			VIDC_REG_456376_ADDR_RMSK)
+#define VIDC_REG_456376_ADDR_INM(m)               \
+	in_dword_masked(VIDC_REG_456376_ADDR_ADDR,  m)
+#define VIDC_REG_456376_ADDR_OUT(v)               \
+	out_dword(VIDC_REG_456376_ADDR_ADDR, v)
+#define VIDC_REG_456376_ADDR_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_456376_ADDR_ADDR, m, v, \
+			VIDC_REG_456376_ADDR_IN); \
+} while (0)
+#define VIDC_REG_456376_ADDR_DPB_COMV_ADDR_BMSK   0xffffffff
+#define VIDC_REG_456376_ADDR_DPB_COMV_ADDR_SHFT            0
+
+#define VIDC_REG_267567_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000908)
+#define VIDC_REG_267567_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000908)
+#define VIDC_REG_267567_RMSK                 0xffffffff
+#define VIDC_REG_267567_SHFT                          0
+#define VIDC_REG_267567_IN                   \
+	in_dword_masked(VIDC_REG_267567_ADDR,  \
+			VIDC_REG_267567_RMSK)
+#define VIDC_REG_267567_INM(m)               \
+	in_dword_masked(VIDC_REG_267567_ADDR,  m)
+#define VIDC_REG_267567_OUT(v)               \
+	out_dword(VIDC_REG_267567_ADDR, v)
+#define VIDC_REG_267567_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_267567_ADDR, m, v, \
+			VIDC_REG_267567_IN); \
+} while (0)
+#define VIDC_REG_798486_ADDR_BMSK   0xffffffff
+#define VIDC_REG_798486_ADDR_SHFT            0
+
+#define VIDC_REG_105770_ADDR                      \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x0000090c)
+#define VIDC_REG_105770_PHYS                      \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000090c)
+#define VIDC_REG_105770_RMSK                            0xff
+#define VIDC_REG_105770_SHFT                               0
+#define VIDC_REG_105770_IN                        \
+	in_dword_masked(VIDC_REG_105770_ADDR,         \
+	VIDC_REG_105770_RMSK)
+#define VIDC_REG_105770_INM(m)                    \
+	in_dword_masked(VIDC_REG_105770_ADDR,  m)
+#define VIDC_REG_105770_DPB_SIZE_BMSK                   0xff
+#define VIDC_REG_105770_DPB_SIZE_SHFT                      0
+
+#define VIDC_REG_58211_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000a00)
+#define VIDC_REG_58211_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a00)
+#define VIDC_REG_58211_RMSK                      0x33f
+#define VIDC_REG_58211_SHFT                          0
+#define VIDC_REG_58211_IN                   \
+	in_dword_masked(VIDC_REG_58211_ADDR,  \
+			VIDC_REG_58211_RMSK)
+#define VIDC_REG_58211_INM(m)               \
+	in_dword_masked(VIDC_REG_58211_ADDR,  m)
+#define VIDC_REG_58211_OUT(v)               \
+	out_dword(VIDC_REG_58211_ADDR, v)
+#define VIDC_REG_58211_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_58211_ADDR, m, v, \
+			VIDC_REG_58211_IN); \
+} while (0)
+#define VIDC_REG_58211_FR_RC_EN_BMSK             0x200
+#define VIDC_REG_58211_FR_RC_EN_SHFT               0x9
+#define VIDC_REG_58211_MB_RC_EN_BMSK             0x100
+#define VIDC_REG_58211_MB_RC_EN_SHFT               0x8
+#define VIDC_REG_58211_FRAME_QP_BMSK              0x3f
+#define VIDC_REG_58211_FRAME_QP_SHFT                 0
+
+#define VIDC_REG_548359_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000a04)
+#define VIDC_REG_548359_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a04)
+#define VIDC_REG_548359_RMSK                          0x3f
+#define VIDC_REG_548359_SHFT                             0
+#define VIDC_REG_548359_IN                      \
+	in_dword_masked(VIDC_REG_548359_ADDR,  \
+			VIDC_REG_548359_RMSK)
+#define VIDC_REG_548359_INM(m)                  \
+	in_dword_masked(VIDC_REG_548359_ADDR,  m)
+#define VIDC_REG_548359_OUT(v)                  \
+	out_dword(VIDC_REG_548359_ADDR, v)
+#define VIDC_REG_548359_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_548359_ADDR, m, v, \
+			VIDC_REG_548359_IN); \
+} while (0)
+#define VIDC_REG_548359_P_FRAME_QP_BMSK               0x3f
+#define VIDC_REG_548359_P_FRAME_QP_SHFT                  0
+
+#define VIDC_REG_174150_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000a08)
+#define VIDC_REG_174150_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a08)
+#define VIDC_REG_174150_RMSK                   0xffffffff
+#define VIDC_REG_174150_SHFT                            0
+#define VIDC_REG_174150_IN                     \
+	in_dword_masked(VIDC_REG_174150_ADDR,  \
+			VIDC_REG_174150_RMSK)
+#define VIDC_REG_174150_INM(m)                 \
+	in_dword_masked(VIDC_REG_174150_ADDR,  m)
+#define VIDC_REG_174150_OUT(v)                 \
+	out_dword(VIDC_REG_174150_ADDR, v)
+#define VIDC_REG_174150_OUTM(m, v)              \
+do { \
+	out_dword_masked_ns(VIDC_REG_174150_ADDR, m, v, \
+			VIDC_REG_174150_IN); \
+} while (0)
+#define VIDC_REG_174150_BIT_RATE_BMSK          0xffffffff
+#define VIDC_REG_174150_BIT_RATE_SHFT                   0
+
+#define VIDC_REG_734318_ADDR                     \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000a0c)
+#define VIDC_REG_734318_PHYS                     \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a0c)
+#define VIDC_REG_734318_RMSK                         0x3f3f
+#define VIDC_REG_734318_SHFT                              0
+#define VIDC_REG_734318_IN                       \
+	in_dword_masked(VIDC_REG_734318_ADDR,        \
+	VIDC_REG_734318_RMSK)
+#define VIDC_REG_734318_INM(m)                   \
+	in_dword_masked(VIDC_REG_734318_ADDR,  m)
+#define VIDC_REG_734318_OUT(v)                   \
+	out_dword(VIDC_REG_734318_ADDR, v)
+#define VIDC_REG_734318_OUTM(m, v)                \
+do { \
+	out_dword_masked_ns(VIDC_REG_734318_ADDR, m, v, \
+			VIDC_REG_734318_IN); \
+} while (0)
+#define VIDC_REG_734318_MAX_QP_BMSK                  0x3f00
+#define VIDC_REG_734318_MAX_QP_SHFT                     0x8
+#define VIDC_REG_734318_MIN_QP_BMSK                    0x3f
+#define VIDC_REG_734318_MIN_QP_SHFT                       0
+
+#define VIDC_REG_677784_ADDR                      \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000a10)
+#define VIDC_REG_677784_PHYS                      \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a10)
+#define VIDC_REG_677784_RMSK                          0xffff
+#define VIDC_REG_677784_SHFT                               0
+#define VIDC_REG_677784_IN                        \
+	in_dword_masked(VIDC_REG_677784_ADDR,         \
+	VIDC_REG_677784_RMSK)
+#define VIDC_REG_677784_INM(m)                    \
+	in_dword_masked(VIDC_REG_677784_ADDR,  m)
+#define VIDC_REG_677784_OUT(v)                    \
+	out_dword(VIDC_REG_677784_ADDR, v)
+#define VIDC_REG_677784_OUTM(m, v)                 \
+do { \
+	out_dword_masked_ns(VIDC_REG_677784_ADDR, m, v, \
+			VIDC_REG_677784_IN); \
+} while (0)
+#define VIDC_REG_677784_REACT_PARA_BMSK               0xffff
+#define VIDC_REG_677784_REACT_PARA_SHFT                    0
+
+#define VIDC_REG_995041_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000a14)
+#define VIDC_REG_995041_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a14)
+#define VIDC_REG_995041_RMSK                           0xf
+#define VIDC_REG_995041_SHFT                             0
+#define VIDC_REG_995041_IN                      \
+	in_dword_masked(VIDC_REG_995041_ADDR,  \
+			VIDC_REG_995041_RMSK)
+#define VIDC_REG_995041_INM(m)                  \
+	in_dword_masked(VIDC_REG_995041_ADDR,  m)
+#define VIDC_REG_995041_OUT(v)                  \
+	out_dword(VIDC_REG_995041_ADDR, v)
+#define VIDC_REG_995041_OUTM(m, v)               \
+do { \
+	out_dword_masked_ns(VIDC_REG_995041_ADDR, m, v, \
+			VIDC_REG_995041_IN); \
+} while (0)
+#define VIDC_REG_995041_DARK_DISABLE_BMSK              0x8
+#define VIDC_REG_995041_DARK_DISABLE_SHFT              0x3
+#define VIDC_REG_995041_SMOOTH_DISABLE_BMSK            0x4
+#define VIDC_REG_995041_SMOOTH_DISABLE_SHFT            0x2
+#define VIDC_REG_995041_STATIC_DISABLE_BMSK            0x2
+#define VIDC_REG_995041_STATIC_DISABLE_SHFT            0x1
+#define VIDC_REG_995041_ACT_DISABLE_BMSK               0x1
+#define VIDC_REG_995041_ACT_DISABLE_SHFT                 0
+
+#define VIDC_REG_273649_ADDR                       \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000a18)
+#define VIDC_REG_273649_PHYS                       \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a18)
+#define VIDC_REG_273649_RMSK                             0x3f
+#define VIDC_REG_273649_SHFT                                0
+#define VIDC_REG_273649_IN                         \
+	in_dword_masked(VIDC_REG_273649_ADDR,  VIDC_REG_273649_RMSK)
+#define VIDC_REG_273649_INM(m)                     \
+	in_dword_masked(VIDC_REG_273649_ADDR,  m)
+#define VIDC_REG_273649_QP_OUT_BMSK                      0x3f
+#define VIDC_REG_273649_QP_OUT_SHFT                         0
+
+#define VIDC_REG_548823_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000b00)
+#define VIDC_REG_548823_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000b00)
+#define VIDC_REG_548823_RMSK                   0xffffffff
+#define VIDC_REG_548823_SHFT                            0
+#define VIDC_REG_548823_IN                     \
+	in_dword_masked(VIDC_REG_548823_ADDR,  \
+			VIDC_REG_548823_RMSK)
+#define VIDC_REG_548823_INM(m)                 \
+	in_dword_masked(VIDC_REG_548823_ADDR,  m)
+#define VIDC_REG_548823_720P_VERSION_BMSK       0xffffffff
+#define VIDC_REG_548823_720P_VERSION_SHFT                0
+
+#define VIDC_REG_881638_ADDR                     \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000c00)
+#define VIDC_REG_881638_PHYS                     \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c00)
+#define VIDC_REG_881638_RMSK                     0xffffffff
+#define VIDC_REG_881638_SHFT                              0
+#define VIDC_REG_881638_IN                       \
+	in_dword_masked(VIDC_REG_881638_ADDR,        \
+	VIDC_REG_881638_RMSK)
+#define VIDC_REG_881638_INM(m)                   \
+	in_dword_masked(VIDC_REG_881638_ADDR,  m)
+#define VIDC_REG_881638_CROP_RIGHT_OFFSET_BMSK   0xffff0000
+#define VIDC_REG_881638_CROP_RIGHT_OFFSET_SHFT         0x10
+#define VIDC_REG_881638_CROP_LEFT_OFFSET_BMSK        0xffff
+#define VIDC_REG_881638_CROP_LEFT_OFFSET_SHFT             0
+
+#define VIDC_REG_161486_ADDR                     \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000c04)
+#define VIDC_REG_161486_PHYS                     \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c04)
+#define VIDC_REG_161486_RMSK                     0xffffffff
+#define VIDC_REG_161486_SHFT                              0
+#define VIDC_REG_161486_IN                       \
+	in_dword_masked(VIDC_REG_161486_ADDR,        \
+	VIDC_REG_161486_RMSK)
+#define VIDC_REG_161486_INM(m)                   \
+	in_dword_masked(VIDC_REG_161486_ADDR,  m)
+#define VIDC_REG_161486_CROP_BOTTOM_OFFSET_BMSK  0xffff0000
+#define VIDC_REG_161486_CROP_BOTTOM_OFFSET_SHFT        0x10
+#define VIDC_REG_161486_CROP_TOP_OFFSET_BMSK         0xffff
+#define VIDC_REG_161486_CROP_TOP_OFFSET_SHFT              0
+
+#define VIDC_REG_580603_ADDR              \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000c08)
+#define VIDC_REG_580603_PHYS              \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c08)
+#define VIDC_REG_580603_RMSK              0xffffffff
+#define VIDC_REG_580603_SHFT                       0
+#define VIDC_REG_580603_IN                \
+	in_dword_masked(VIDC_REG_580603_ADDR,  \
+			VIDC_REG_580603_RMSK)
+#define VIDC_REG_580603_INM(m)            \
+	in_dword_masked(VIDC_REG_580603_ADDR,  m)
+#define VIDC_REG_580603_720P_DEC_FRM_SIZE_BMSK 0xffffffff
+#define VIDC_REG_580603_720P_DEC_FRM_SIZE_SHFT          0
+
+
+#define VIDC_REG_606447_ADDR \
+		(VIDC_720P_WRAPPER_REG_BASE + 0x00000c0c)
+#define VIDC_REG_606447_PHYS \
+		(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c0c)
+#define VIDC_REG_606447_RMSK  0xff1f
+#define VIDC_REG_606447_SHFT  0
+#define VIDC_REG_606447_IN                         \
+		in_dword_masked(VIDC_REG_606447_ADDR, \
+		VIDC_REG_606447_RMSK)
+#define VIDC_REG_606447_INM(m)                     \
+		in_dword_masked(VIDC_REG_606447_ADDR, m)
+#define VIDC_REG_606447_OUT(v)                     \
+		out_dword(VIDC_REG_606447_ADDR, v)
+#define VIDC_REG_606447_OUTM(m, v)                  \
+		out_dword_masked_ns(VIDC_REG_606447_ADDR, \
+		m, v, VIDC_REG_606447_IN); \
+
+#define VIDC_REG_606447_DIS_PIC_LEVEL_BMSK 0xff00
+#define VIDC_REG_606447_DIS_PIC_LEVEL_SHFT 0x8
+#define VIDC_REG_606447_DISP_PIC_PROFILE_BMSK 0x1f
+#define VIDC_REG_606447_DISP_PIC_PROFILE_SHFT 0
+
+#define VIDC_REG_854281_ADDR \
+		(VIDC_720P_WRAPPER_REG_BASE      + 0x00000c10)
+#define VIDC_REG_854281_PHYS \
+		(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c10)
+#define VIDC_REG_854281_RMSK 0xffffffff
+#define VIDC_REG_854281_SHFT 0
+#define VIDC_REG_854281_IN \
+		in_dword_masked(VIDC_REG_854281_ADDR, \
+		VIDC_REG_854281_RMSK)
+#define VIDC_REG_854281_INM(m) \
+		in_dword_masked(VIDC_REG_854281_ADDR, m)
+#define VIDC_REG_854281_MIN_DPB_SIZE_BMSK 0xffffffff
+#define VIDC_REG_854281_MIN_DPB_SIZE_SHFT 0
+
+
+#define VIDC_REG_381535_ADDR \
+		(VIDC_720P_WRAPPER_REG_BASE + 0x00000c14)
+#define VIDC_REG_381535_PHYS \
+		(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c14)
+#define VIDC_REG_381535_RMSK 0xffffffff
+#define VIDC_REG_381535_SHFT 0
+#define VIDC_REG_381535_IN \
+		in_dword_masked(VIDC_REG_381535_ADDR, \
+		VIDC_REG_381535_RMSK)
+#define VIDC_REG_381535_INM(m) \
+		in_dword_masked(VIDC_REG_381535_ADDR, m)
+#define VIDC_REG_381535_720P_FW_STATUS_BMSK 0xffffffff
+#define VIDC_REG_381535_720P_FW_STATUS_SHFT 0
+
+
+#define VIDC_REG_347105_ADDR \
+		(VIDC_720P_WRAPPER_REG_BASE + 0x00000c18)
+#define VIDC_REG_347105_PHYS \
+		(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c18)
+#define VIDC_REG_347105_RMSK 0xffffffff
+#define VIDC_REG_347105_SHFT 0
+#define VIDC_REG_347105_IN \
+		in_dword_masked(VIDC_REG_347105_ADDR, \
+		VIDC_REG_347105_RMSK)
+#define VIDC_REG_347105_INM(m) \
+		in_dword_masked(VIDC_REG_347105_ADDR, m)
+#define VIDC_REG_347105_FREE_LUMA_DPB_BMSK 0xffffffff
+#define VIDC_REG_347105_FREE_LUMA_DPB_SHFT 0
+
+
+#define VIDC_REG_62325_ADDR              \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000d00)
+#define VIDC_REG_62325_PHYS              \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d00)
+#define VIDC_REG_62325_RMSK                     0xf
+#define VIDC_REG_62325_SHFT                       0
+#define VIDC_REG_62325_IN                \
+		in_dword_masked(VIDC_REG_62325_ADDR,  \
+		VIDC_REG_62325_RMSK)
+#define VIDC_REG_62325_INM(m)            \
+	in_dword_masked(VIDC_REG_62325_ADDR,  m)
+#define VIDC_REG_62325_OUT(v)            \
+	out_dword(VIDC_REG_62325_ADDR, v)
+#define VIDC_REG_62325_OUTM(m, v)         \
+do { \
+	out_dword_masked_ns(VIDC_REG_62325_ADDR, m, v, \
+			VIDC_REG_62325_IN); \
+} while (0)
+#define VIDC_REG_62325_COMMAND_TYPE_BMSK        0xf
+#define VIDC_REG_62325_COMMAND_TYPE_SHFT          0
+
+#define VIDC_REG_101184_ADDR  \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000d04)
+#define VIDC_REG_101184_PHYS  \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d04)
+#define VIDC_REG_101184_RMSK                0xffffffff
+#define VIDC_REG_101184_SHFT                0
+#define VIDC_REG_101184_OUT(v)                     \
+	out_dword(VIDC_REG_101184_ADDR, v)
+
+#define VIDC_REG_490443_ADDR  \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000d08)
+#define VIDC_REG_490443_PHYS  \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d08)
+#define VIDC_REG_490443_RMSK                       \
+	0xffffffff
+#define \
+	\
+VIDC_REG_490443_SHFT                                0
+#define VIDC_REG_490443_OUT(v)                     \
+	out_dword(VIDC_REG_490443_ADDR, v)
+
+#define VIDC_REG_625444_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000d14)
+#define VIDC_REG_625444_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d14)
+#define VIDC_REG_625444_RMSK                 0xffffffff
+#define VIDC_REG_625444_SHFT                          0
+#define VIDC_REG_625444_IN                   \
+	in_dword_masked(VIDC_REG_625444_ADDR,  \
+			VIDC_REG_625444_RMSK)
+#define VIDC_REG_625444_INM(m)               \
+	in_dword_masked(VIDC_REG_625444_ADDR,  m)
+#define VIDC_REG_625444_OUT(v)               \
+	out_dword(VIDC_REG_625444_ADDR, v)
+#define VIDC_REG_625444_OUTM(m, v)            \
+do { \
+	out_dword_masked_ns(VIDC_REG_625444_ADDR, m, v, \
+			VIDC_REG_625444_IN); \
+} while (0)
+#define VIDC_REG_625444_FRAME_RATE_BMSK      0xffffffff
+#define VIDC_REG_625444_FRAME_RATE_SHFT               0
+
+#define VIDC_REG_639999_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000d20)
+#define VIDC_REG_639999_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d20)
+#define VIDC_REG_639999_RMSK                    0xffff
+#define VIDC_REG_639999_SHFT                         0
+#define VIDC_REG_639999_OUT(v)                  \
+	out_dword(VIDC_REG_639999_ADDR, v)
+
+#define VIDC_REG_64895_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000e00)
+#define VIDC_REG_64895_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e00)
+#define VIDC_REG_64895_RMSK                    0xffffffff
+#define VIDC_REG_64895_SHFT                             0
+#define VIDC_REG_64895_OUT(v)                  \
+	out_dword(VIDC_REG_64895_ADDR, v)
+
+#define VIDC_REG_965480_ADDR \
+		(VIDC_720P_WRAPPER_REG_BASE + 0x00000e04)
+#define VIDC_REG_965480_PHYS \
+		(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e04)
+#define VIDC_REG_965480_RMSK 0x1
+#define VIDC_REG_965480_SHFT 0
+#define VIDC_REG_965480_OUT(v) \
+		out_dword(VIDC_REG_965480_ADDR, v)
+
+#define VIDC_REG_804959_ADDR              \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000e08)
+#define VIDC_REG_804959_PHYS              \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e08)
+#define VIDC_REG_804959_RMSK                     0x7
+#define VIDC_REG_804959_SHFT                       0
+#define VIDC_REG_804959_OUT(v)            \
+	out_dword(VIDC_REG_804959_ADDR, v)
+
+#define VIDC_REG_257463_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000e10)
+#define VIDC_REG_257463_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e10)
+#define VIDC_REG_257463_RMSK                   0xffffffff
+#define VIDC_REG_257463_SHFT                            0
+#define VIDC_REG_257463_IN                     \
+	in_dword_masked(VIDC_REG_257463_ADDR,  \
+			VIDC_REG_257463_RMSK)
+#define VIDC_REG_257463_INM(m)                 \
+	in_dword_masked(VIDC_REG_257463_ADDR,  m)
+#define VIDC_REG_257463_MIN_NUM_DPB_BMSK       0xffffffff
+#define VIDC_REG_257463_MIN_NUM_DPB_SHFT                0
+
+#define VIDC_REG_883500_ADDR                       \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000e14)
+#define VIDC_REG_883500_PHYS                       \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e14)
+#define VIDC_REG_883500_RMSK                       0xffffffff
+#define VIDC_REG_883500_SHFT                                0
+#define VIDC_REG_883500_OUT(v)                     \
+	out_dword(VIDC_REG_883500_ADDR, v)
+
+#define VIDC_REG_615716_ADDR(n)               \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000e18 + 4 * (n))
+#define VIDC_REG_615716_PHYS(n)               \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e18 + 4 * (n))
+#define VIDC_REG_615716_RMSK                  0xffffffff
+#define VIDC_REG_615716_SHFT                           0
+#define VIDC_REG_615716_OUTI(n, v) \
+	out_dword(VIDC_REG_615716_ADDR(n), v)
+
+#define VIDC_REG_603032_ADDR                \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000e98)
+#define VIDC_REG_603032_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e98)
+#define VIDC_REG_603032_RMSK                0xffffffff
+#define VIDC_REG_603032_SHFT                         0
+#define VIDC_REG_603032_OUT(v)              \
+	out_dword(VIDC_REG_603032_ADDR, v)
+
+#define VIDC_REG_300310_ADDR                  \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000e9c)
+#define VIDC_REG_300310_PHYS                  \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e9c)
+#define VIDC_REG_300310_RMSK                  0xffffffff
+#define VIDC_REG_300310_SHFT                           0
+#define VIDC_REG_300310_IN                    \
+	in_dword_masked(VIDC_REG_300310_ADDR,  \
+			VIDC_REG_300310_RMSK)
+#define VIDC_REG_300310_INM(m)                \
+	in_dword_masked(VIDC_REG_300310_ADDR,  m)
+#define VIDC_REG_300310_ERROR_STATUS_BMSK     0xffffffff
+#define VIDC_REG_300310_ERROR_STATUS_SHFT              0
+
+#define VIDC_REG_792026_ADDR        \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ea0)
+#define VIDC_REG_792026_PHYS        \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea0)
+#define VIDC_REG_792026_RMSK        0xffffffff
+#define VIDC_REG_792026_SHFT                 0
+#define VIDC_REG_792026_OUT(v)      \
+	out_dword(VIDC_REG_792026_ADDR, v)
+
+#define VIDC_REG_844152_ADDR        \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ea4)
+#define VIDC_REG_844152_PHYS        \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea4)
+#define VIDC_REG_844152_RMSK        0xffffffff
+#define VIDC_REG_844152_SHFT                 0
+#define VIDC_REG_844152_OUT(v)      \
+	out_dword(VIDC_REG_844152_ADDR, v)
+
+#define VIDC_REG_370409_ADDR            \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ea8)
+#define VIDC_REG_370409_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea8)
+#define VIDC_REG_370409_RMSK                0xffffffff
+#define VIDC_REG_370409_SHFT                         0
+#define VIDC_REG_370409_IN                  \
+	in_dword_masked(VIDC_REG_370409_ADDR,  \
+			VIDC_REG_370409_RMSK)
+#define VIDC_REG_370409_INM(m)              \
+	in_dword_masked(VIDC_REG_370409_ADDR,  m)
+#define VIDC_REG_370409_GET_FRAME_TAG_TOP_BMSK 0xffffffff
+#define VIDC_REG_370409_GET_FRAME_TAG_TOP_SHFT          0
+
+#define VIDC_REG_147682_ADDR               \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000eac)
+#define VIDC_REG_147682_PHYS               \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eac)
+#define VIDC_REG_147682_RMSK                        0x1
+#define VIDC_REG_147682_SHFT                        0
+#define VIDC_REG_147682_OUT(v)             \
+	out_dword(VIDC_REG_147682_ADDR, v)
+
+#define VIDC_REG_407718_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000eb0)
+#define VIDC_REG_407718_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb0)
+#define VIDC_REG_407718_RMSK                    0xffffffff
+#define VIDC_REG_407718_SHFT                             0
+#define VIDC_REG_407718_OUT(v)                  \
+	out_dword(VIDC_REG_407718_ADDR, v)
+
+#define VIDC_REG_697961_ADDR \
+		(VIDC_720P_WRAPPER_REG_BASE + 0x00000eb4)
+#define VIDC_REG_697961_PHYS \
+		(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb4)
+#define VIDC_REG_697961_RMSK 0x3
+#define VIDC_REG_697961_SHFT 0
+#define VIDC_REG_697961_IN \
+		in_dword_masked(VIDC_REG_697961_ADDR, \
+		VIDC_REG_697961_RMSK)
+#define VIDC_REG_697961_INM(m) \
+		in_dword_masked(VIDC_REG_697961_ADDR, m)
+#define VIDC_REG_697961_FRAME_TYPE_BMSK 0x3
+#define VIDC_REG_697961_FRAME_TYPE_SHFT 0
+
+
+#define VIDC_REG_613254_ADDR               \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000eb8)
+#define VIDC_REG_613254_PHYS               \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb8)
+#define VIDC_REG_613254_RMSK                      0x1
+#define VIDC_REG_613254_SHFT                        0
+#define VIDC_REG_613254_IN                 \
+	in_dword_masked(VIDC_REG_613254_ADDR,  \
+			VIDC_REG_613254_RMSK)
+#define VIDC_REG_613254_INM(m)             \
+	in_dword_masked(VIDC_REG_613254_ADDR,  m)
+#define VIDC_REG_613254_METADATA_STATUS_BMSK        0x1
+#define VIDC_REG_613254_METADATA_STATUS_SHFT          0
+#define VIDC_REG_441270_ADDR                    \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ebc)
+#define VIDC_REG_441270_PHYS                    \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ebc)
+#define VIDC_REG_441270_RMSK                           0xf
+#define VIDC_REG_441270_SHFT                             0
+#define VIDC_REG_441270_IN                      \
+	in_dword_masked(VIDC_REG_441270_ADDR,  \
+			VIDC_REG_441270_RMSK)
+#define VIDC_REG_441270_INM(m)                  \
+	in_dword_masked(VIDC_REG_441270_ADDR,  m)
+#define VIDC_REG_441270_DATA_PARTITIONED_BMSK 0x8
+#define VIDC_REG_441270_DATA_PARTITIONED_SHFT 0x3
+
+#define VIDC_REG_441270_FRAME_TYPE_BMSK                0x7
+#define VIDC_REG_441270_FRAME_TYPE_SHFT                  0
+
+#define VIDC_REG_724381_ADDR        \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ec0)
+#define VIDC_REG_724381_PHYS        \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec0)
+#define VIDC_REG_724381_RMSK               0x3
+#define VIDC_REG_724381_SHFT                 0
+#define VIDC_REG_724381_IN          \
+	in_dword_masked(VIDC_REG_724381_ADDR,  \
+			VIDC_REG_724381_RMSK)
+#define VIDC_REG_724381_INM(m)      \
+	in_dword_masked(VIDC_REG_724381_ADDR,  m)
+#define VIDC_REG_724381_MORE_FIELD_NEEDED_BMSK       0x4
+#define VIDC_REG_724381_MORE_FIELD_NEEDED_SHFT       0x2
+#define VIDC_REG_724381_OPERATION_FAILED_BMSK        0x2
+#define VIDC_REG_724381_OPERATION_FAILED_SHFT        0x1
+#define VIDC_REG_724381_RESOLUTION_CHANGE_BMSK       0x1
+#define VIDC_REG_724381_RESOLUTION_CHANGE_SHFT         0
+
+#define VIDC_REG_854681_ADDR               \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ec4)
+#define VIDC_REG_854681_PHYS               \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec4)
+#define VIDC_REG_854681_RMSK                     0x7f
+#define VIDC_REG_854681_SHFT                        0
+#define VIDC_REG_854681_OUT(v)             \
+	out_dword(VIDC_REG_854681_ADDR, v)
+
+#define VIDC_REG_128234_ADDR               \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ec8)
+#define VIDC_REG_128234_PHYS               \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec8)
+#define VIDC_REG_128234_RMSK               0xffff000f
+#define VIDC_REG_128234_SHFT                        0
+#define VIDC_REG_128234_OUT(v)             \
+	out_dword(VIDC_REG_128234_ADDR, v)
+
+#define VIDC_REG_1137_ADDR        \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ecc)
+#define VIDC_REG_1137_PHYS        \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ecc)
+#define VIDC_REG_1137_RMSK        0xffffffff
+#define VIDC_REG_1137_SHFT                 0
+#define VIDC_REG_1137_IN          \
+	in_dword_masked(VIDC_REG_1137_ADDR,  \
+			VIDC_REG_1137_RMSK)
+#define VIDC_REG_1137_INM(m)      \
+	in_dword_masked(VIDC_REG_1137_ADDR,  m)
+#define VIDC_REG_1137_METADATA_DISPLAY_INDEX_BMSK \
+	0xffffffff
+#define \
+	\
+VIDC_REG_1137_METADATA_DISPLAY_INDEX_SHFT          0
+
+#define VIDC_REG_988552_ADDR       \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ed0)
+#define VIDC_REG_988552_PHYS       \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed0)
+#define VIDC_REG_988552_RMSK       0xffffffff
+#define VIDC_REG_988552_SHFT                0
+#define VIDC_REG_988552_OUT(v)     \
+	out_dword(VIDC_REG_988552_ADDR, v)
+
+#define VIDC_REG_319934_ADDR  \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ed4)
+#define VIDC_REG_319934_PHYS  \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed4)
+#define VIDC_REG_319934_RMSK                       0xffffffff
+#define VIDC_REG_319934_SHFT                   0
+#define VIDC_REG_319934_OUT(v)                     \
+	out_dword(VIDC_REG_319934_ADDR, v)
+
+#define VIDC_REG_679165_ADDR                   \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ed8)
+#define VIDC_REG_679165_PHYS                   \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed8)
+#define VIDC_REG_679165_RMSK                   0xffffffff
+#define VIDC_REG_679165_SHFT                            0
+#define VIDC_REG_679165_IN                     \
+	in_dword_masked(VIDC_REG_679165_ADDR,  \
+			VIDC_REG_679165_RMSK)
+#define VIDC_REG_679165_INM(m)                 \
+	in_dword_masked(VIDC_REG_679165_ADDR,  m)
+#define VIDC_REG_679165_PIC_TIME_TOP_BMSK       0xffffffff
+#define VIDC_REG_679165_PIC_TIME_TOP_SHFT                0
+
+#define VIDC_REG_374150_ADDR                     \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000edc)
+#define VIDC_REG_374150_PHYS                     \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000edc)
+#define VIDC_REG_374150_RMSK                     0xffffffff
+#define VIDC_REG_374150_SHFT                              0
+#define VIDC_REG_374150_IN                       \
+	in_dword_masked(VIDC_REG_374150_ADDR,  \
+			VIDC_REG_374150_RMSK)
+#define VIDC_REG_374150_INM(m)                   \
+	in_dword_masked(VIDC_REG_374150_ADDR,  m)
+#define VIDC_REG_374150_PIC_TIME_BOTTOM_BMSK           0xffffffff
+#define VIDC_REG_374150_PIC_TIME_BOTTOM_SHFT                    0
+
+#define VIDC_REG_94750_ADDR                 \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ee0)
+#define VIDC_REG_94750_PHYS                 \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee0)
+#define VIDC_REG_94750_RMSK                 0xffffffff
+#define VIDC_REG_94750_SHFT                          0
+#define VIDC_REG_94750_OUT(v)               \
+	out_dword(VIDC_REG_94750_ADDR, v)
+
+#define VIDC_REG_438677_ADDR          \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ee4)
+#define VIDC_REG_438677_PHYS                \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee4)
+#define VIDC_REG_438677_RMSK                0xffffffff
+#define VIDC_REG_438677_SHFT                         0
+#define VIDC_REG_438677_IN                  \
+	in_dword_masked(VIDC_REG_438677_ADDR,  \
+			VIDC_REG_438677_RMSK)
+#define VIDC_REG_438677_INM(m)              \
+	in_dword_masked(VIDC_REG_438677_ADDR,  m)
+#define VIDC_REG_438677_GET_FRAME_TAG_BOTTOM_BMSK 0xffffffff
+#define VIDC_REG_438677_GET_FRAME_TAG_BOTTOM_SHFT          0
+
+#define VIDC_REG_76706_ADDR               \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00000ee8)
+#define VIDC_REG_76706_PHYS               \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee8)
+#define VIDC_REG_76706_RMSK                      0x1
+#define VIDC_REG_76706_SHFT                        0
+#define VIDC_REG_76706_OUT(v)             \
+	out_dword(VIDC_REG_76706_ADDR, v)
+
+#define VIDC_REG_809984_ADDR                       \
+	(VIDC_720P_WRAPPER_REG_BASE      + 0x00001000)
+#define VIDC_REG_809984_PHYS                       \
+	(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00001000)
+#define VIDC_REG_809984_RMSK                       0xffff0007
+#define VIDC_REG_809984_SHFT                                0
+#define VIDC_REG_809984_IN                         \
+	in_dword_masked(VIDC_REG_809984_ADDR,  VIDC_REG_809984_RMSK)
+#define VIDC_REG_809984_INM(m)                     \
+	in_dword_masked(VIDC_REG_809984_ADDR,  m)
+#define VIDC_REG_809984_720PV_720P_WRAPPER_VERSION_BMSK 0xffff0000
+#define VIDC_REG_809984_720PV_720P_WRAPPER_VERSION_SHFT       0x10
+#define VIDC_REG_809984_TEST_MUX_SEL_BMSK                 0x7
+#define VIDC_REG_809984_TEST_MUX_SEL_SHFT                   0
+
+
+#define VIDC_REG_699747_ADDR \
+       (VIDC_720P_WRAPPER_REG_BASE + 0x00000d0c)
+#define VIDC_REG_699747_PHYS \
+       (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d0c)
+#define VIDC_REG_699747_RMSK 0xffffffff
+#define VIDC_REG_699747_SHFT 0
+#define VIDC_REG_699747_OUT(v)                  \
+		out_dword(VIDC_REG_699747_ADDR, v)
+
+#define VIDC_REG_166247_ADDR \
+       (VIDC_720P_WRAPPER_REG_BASE + 0x00000d10)
+#define VIDC_REG_166247_PHYS \
+       (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d10)
+#define VIDC_REG_166247_RMSK 0xffffffff
+#define VIDC_REG_166247_SHFT 0
+#define VIDC_REG_166247_OUT(v)               \
+		out_dword(VIDC_REG_166247_ADDR, v)
+
+#define VIDC_REG_486169_ADDR \
+		(VIDC_720P_WRAPPER_REG_BASE + 0x00000d18)
+#define VIDC_REG_486169_PHYS \
+		(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d18)
+#define VIDC_REG_486169_RMSK 0xffffffff
+#define VIDC_REG_486169_SHFT 0
+#define VIDC_REG_486169_OUT(v) \
+		out_dword(VIDC_REG_486169_ADDR, v)
+
+#define VIDC_REG_926519_ADDR \
+		(VIDC_720P_WRAPPER_REG_BASE + 0x00000d1c)
+#define VIDC_REG_926519_PHYS \
+		(VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d1c)
+#define VIDC_REG_926519_RMSK 0xffffffff
+#define VIDC_REG_926519_SHFT 0
+#define VIDC_REG_926519_OUT(v) \
+		out_dword(VIDC_REG_926519_ADDR, v)
+
+/** List all the levels and their register valus */
+
+#define VIDC_720P_PROFILE_MPEG4_SP      0
+#define VIDC_720P_PROFILE_MPEG4_ASP     1
+#define VIDC_720P_PROFILE_H264_BASELINE 0
+#define VIDC_720P_PROFILE_H264_MAIN     1
+#define VIDC_720P_PROFILE_H264_HIGH     2
+#define VIDC_720P_PROFILE_H264_CPB      3
+#define VIDC_720P_PROFILE_H263_BASELINE 0
+
+#define VIDC_720P_PROFILE_VC1_SP        0
+#define VIDC_720P_PROFILE_VC1_MAIN      1
+#define VIDC_720P_PROFILE_VC1_ADV       2
+#define VIDC_720P_PROFILE_MPEG2_MAIN    4
+#define VIDC_720P_PROFILE_MPEG2_SP      5
+
+#define VIDC_720P_MPEG4_LEVEL0  0
+#define VIDC_720P_MPEG4_LEVEL0b 9
+#define VIDC_720P_MPEG4_LEVEL1  1
+#define VIDC_720P_MPEG4_LEVEL2  2
+#define VIDC_720P_MPEG4_LEVEL3  3
+#define VIDC_720P_MPEG4_LEVEL3b 7
+#define VIDC_720P_MPEG4_LEVEL4a 4
+#define VIDC_720P_MPEG4_LEVEL5  5
+#define VIDC_720P_MPEG4_LEVEL6  6
+
+#define VIDC_720P_H264_LEVEL1     10
+#define VIDC_720P_H264_LEVEL1b    9
+#define VIDC_720P_H264_LEVEL1p1   11
+#define VIDC_720P_H264_LEVEL1p2   12
+#define VIDC_720P_H264_LEVEL1p3   13
+#define VIDC_720P_H264_LEVEL2     20
+#define VIDC_720P_H264_LEVEL2p1   21
+#define VIDC_720P_H264_LEVEL2p2   22
+#define VIDC_720P_H264_LEVEL3     30
+#define VIDC_720P_H264_LEVEL3p1   31
+#define VIDC_720P_H264_LEVEL3p2   32
+
+#define VIDC_720P_H263_LEVEL10    10
+#define VIDC_720P_H263_LEVEL20    20
+#define VIDC_720P_H263_LEVEL30    30
+#define VIDC_720P_H263_LEVEL40    40
+#define VIDC_720P_H263_LEVEL45    45
+#define VIDC_720P_H263_LEVEL50    50
+#define VIDC_720P_H263_LEVEL60    60
+#define VIDC_720P_H263_LEVEL70    70
+
+#define VIDC_720P_VC1_LEVEL_LOW    0
+#define VIDC_720P_VC1_LEVEL_MED    2
+#define VIDC_720P_VC1_LEVEL_HIGH   4
+#define VIDC_720P_VC1_LEVEL0       0
+#define VIDC_720P_VC1_LEVEL1       1
+#define VIDC_720P_VC1_LEVEL2       2
+#define VIDC_720P_VC1_LEVEL3       3
+#define VIDC_720P_VC1_LEVEL4       4
+
+#define VIDCL_720P_MPEG2_LEVEL_LOW 10
+#define VIDCL_720P_MPEG2_LEVEL_MAIN 8
+#define VIDCL_720P_MPEG2_LEVEL_HIGH14 6
+
+#define VIDC_720P_CMD_CHSET               0x0
+#define VIDC_720P_CMD_CHEND               0x2
+#define VIDC_720P_CMD_INITCODEC           0x3
+#define VIDC_720P_CMD_FRAMERUN            0x4
+#define VIDC_720P_CMD_INITBUFFERS         0x5
+#define VIDC_720P_CMD_FRAMERUN_REALLOCATE 0x6
+#define VIDC_720P_CMD_MFC_ENGINE_RESET 0x7
+
+enum vidc_720p_endian {
+	VIDC_720P_BIG_ENDIAN = 0x0,
+	VIDC_720P_LITTLE_ENDIAN = 0x1
+};
+
+enum vidc_720p_memory_access_method {
+	VIDC_720P_TILE_LINEAR = 0,
+	VIDC_720P_TILE_16x16 = 2,
+	VIDC_720P_TILE_64x32 = 3
+};
+
+enum vidc_720p_interrupt_control_mode {
+	VIDC_720P_INTERRUPT_MODE = 0,
+	VIDC_720P_POLL_MODE = 1
+};
+
+enum vidc_720p_interrupt_level_selection {
+	VIDC_720P_INTERRUPT_LEVEL_SEL = 0,
+	VIDC_720P_INTERRUPT_PULSE_SEL = 1
+};
+
+#define VIDC_720P_INTR_BUFFER_FULL             0x002
+#define VIDC_720P_INTR_FW_DONE                 0x020
+#define VIDC_720P_INTR_HEADER_DONE             0x040
+#define VIDC_720P_INTR_DMA_DONE                0x080
+#define VIDC_720P_INTR_FRAME_DONE              0x100
+
+enum vidc_720p_enc_dec_selection {
+	VIDC_720P_DECODER = 0,
+	VIDC_720P_ENCODER = 1
+};
+
+enum vidc_720p_codec {
+	VIDC_720P_MPEG4 = 0,
+	VIDC_720P_H264 = 1,
+	VIDC_720P_DIVX = 2,
+	VIDC_720P_XVID = 3,
+	VIDC_720P_H263 = 4,
+	VIDC_720P_MPEG2 = 5,
+	VIDC_720P_VC1 = 6
+};
+
+enum vidc_720p_frame {
+	VIDC_720P_NOTCODED = 0,
+	VIDC_720P_IFRAME = 1,
+	VIDC_720P_PFRAME = 2,
+	VIDC_720P_BFRAME = 3
+};
+
+enum vidc_720p_entropy_sel {
+	VIDC_720P_ENTROPY_SEL_CAVLC = 0,
+	VIDC_720P_ENTROPY_SEL_CABAC = 1
+};
+
+enum vidc_720p_cabac_model {
+	VIDC_720P_CABAC_MODEL_NUMBER_0 = 0,
+	VIDC_720P_CABAC_MODEL_NUMBER_1 = 1,
+	VIDC_720P_CABAC_MODEL_NUMBER_2 = 2
+};
+
+enum vidc_720p_DBConfig {
+	VIDC_720P_DB_ALL_BLOCKING_BOUNDARY = 0,
+	VIDC_720P_DB_DISABLE = 1,
+	VIDC_720P_DB_SKIP_SLICE_BOUNDARY = 2
+};
+
+enum vidc_720p_MSlice_selection {
+	VIDC_720P_MSLICE_BY_MB_COUNT = 0,
+	VIDC_720P_MSLICE_BY_BYTE_COUNT = 1,
+	VIDC_720P_MSLICE_BY_GOB = 2,
+	VIDC_720P_MSLICE_OFF = 3
+};
+
+enum vidc_720p_display_status {
+	VIDC_720P_DECODE_ONLY = 0,
+	VIDC_720P_DECODE_AND_DISPLAY = 1,
+	VIDC_720P_DISPLAY_ONLY = 2,
+	VIDC_720P_EMPTY_BUFFER = 3
+};
+
+#define VIDC_720P_ENC_IFRAME_REQ       0x1
+#define VIDC_720P_ENC_IPERIOD_CHANGE   0x1
+#define VIDC_720P_ENC_FRAMERATE_CHANGE 0x2
+#define VIDC_720P_ENC_BITRATE_CHANGE   0x4
+
+#define VIDC_720P_FLUSH_REQ     0x1
+#define VIDC_720P_EXTRADATA     0x2
+
+#define VIDC_720P_METADATA_ENABLE_QP           0x01
+#define VIDC_720P_METADATA_ENABLE_CONCEALMB    0x02
+#define VIDC_720P_METADATA_ENABLE_VC1          0x04
+#define VIDC_720P_METADATA_ENABLE_SEI          0x08
+#define VIDC_720P_METADATA_ENABLE_VUI          0x10
+#define VIDC_720P_METADATA_ENABLE_ENCSLICE     0x20
+#define VIDC_720P_METADATA_ENABLE_PASSTHROUGH  0x40
+
+struct vidc_720p_dec_disp_info {
+	enum vidc_720p_display_status disp_status;
+	u32 resl_change;
+	u32 reconfig_flush_done;
+	u32 img_size_x;
+	u32 img_size_y;
+	u32 y_addr;
+	u32 c_addr;
+	u32 tag_top;
+	u32 pic_time_top;
+	u32 disp_is_interlace;
+	u32 tag_bottom;
+	u32 pic_time_bottom;
+	u32 metadata_exists;
+	u32 crop_exists;
+	u32 crop_right_offset;
+	u32 crop_left_offset;
+	u32 crop_bottom_offset;
+	u32 crop_top_offset;
+	u32 input_frame;
+	u32 input_bytes_consumed;
+	u32 input_is_interlace;
+	u32 input_frame_num;
+};
+
+struct vidc_720p_seq_hdr_info {
+	u32 img_size_x;
+	u32 img_size_y;
+	u32 dec_frm_size;
+	u32 min_num_dpb;
+	u32 min_dpb_size;
+	u32 profile;
+	u32 level;
+	u32 progressive;
+	u32 data_partitioned;
+	u32  crop_exists;
+	u32  crop_right_offset;
+	u32  crop_left_offset;
+	u32  crop_bottom_offset;
+	u32  crop_top_offset;
+};
+
+struct vidc_720p_enc_frame_info {
+	u32 enc_size;
+	u32 frame;
+	u32 metadata_exists;
+};
+
+void vidc_720p_set_device_virtual_base(u8 *core_virtual_base_addr);
+
+void vidc_720p_init(char **ppsz_version, u32 i_firmware_size,
+	u32 *pi_firmware_address, enum vidc_720p_endian dma_endian,
+	u32 interrupt_off,
+	enum vidc_720p_interrupt_level_selection	interrupt_sel,
+	u32 interrupt_mask);
+
+u32 vidc_720p_do_sw_reset(void);
+
+u32 vidc_720p_reset_is_success(void);
+
+void vidc_720p_start_cpu(enum vidc_720p_endian dma_endian,
+		u32 *icontext_bufferstart, u32 *debug_core_dump_addr,
+		u32  debug_buffer_size);
+
+u32 vidc_720p_cpu_start(void);
+
+void vidc_720p_stop_fw(void);
+
+void vidc_720p_get_interrupt_status(u32 *interrupt_status,
+		u32 *cmd_err_status, u32 *disp_pic_err_status,
+		u32 *op_failed);
+
+void vidc_720p_interrupt_done_clear(void);
+
+void vidc_720p_submit_command(u32 ch_id, u32 cmd_id);
+
+
+void vidc_720p_set_channel(u32 i_ch_id,
+	enum vidc_720p_enc_dec_selection enc_dec_sel,
+	enum vidc_720p_codec codec, u32 *pi_fw, u32 i_firmware_size);
+
+u32 vidc_720p_engine_reset(u32 ch_id,
+   enum vidc_720p_endian dma_endian,
+   enum vidc_720p_interrupt_level_selection interrupt_sel,
+   u32 interrupt_mask
+);
+
+void vidc_720p_encode_set_profile(u32 i_profile, u32 i_level);
+
+void vidc_720p_set_frame_size(u32 i_size_x, u32 i_size_y);
+
+void vidc_720p_encode_set_fps(u32 i_rc_frame_rate);
+
+void vidc_720p_encode_set_vop_time(u32 vop_time_resolution,
+		u32 vop_time_increment);
+
+void vidc_720p_encode_set_hec_period(u32 hec_period);
+
+void vidc_720p_encode_set_short_header(u32 i_short_header);
+
+void vidc_720p_encode_set_qp_params(u32 i_max_qp, u32 i_min_qp);
+
+void vidc_720p_encode_set_rc_config(u32 enable_frame_level_rc,
+		u32 enable_mb_level_rc_flag, u32 i_frame_qp, u32 pframe_qp);
+
+void vidc_720p_encode_set_bit_rate(u32 i_target_bitrate);
+
+void vidc_720p_encoder_set_param_change(u32 enc_param_change);
+
+void vidc_720p_encode_set_control_param(u32 param_val);
+
+void vidc_720p_encode_set_frame_level_rc_params(u32 i_reaction_coeff);
+
+void vidc_720p_encode_set_mb_level_rc_params(u32 dark_region_as_flag,
+	u32 smooth_region_as_flag, u32 static_region_as_flag,
+	u32 activity_region_flag);
+
+void vidc_720p_encode_set_entropy_control(enum vidc_720p_entropy_sel \
+		entropy_sel,
+		enum vidc_720p_cabac_model cabac_model_number);
+
+void vidc_720p_encode_set_db_filter_control(enum vidc_720p_DBConfig
+		db_config, u32 i_slice_alpha_offset, u32 i_slice_beta_offset);
+
+void vidc_720p_encode_set_intra_refresh_mb_number(u32 i_cir_mb_number);
+
+void vidc_720p_encode_set_multi_slice_info(
+		enum vidc_720p_MSlice_selection m_slice_sel,
+		u32 multi_slice_size);
+
+void vidc_720p_encode_set_dpb_buffer(u32 *pi_enc_dpb_addr, u32 alloc_len);
+
+void vidc_720p_set_deblock_line_buffer(u32 *pi_deblock_line_buffer_start,
+		u32 alloc_len);
+
+void vidc_720p_encode_set_i_period(u32 i_i_period);
+
+void vidc_720p_encode_init_codec(u32 i_ch_id,
+	enum vidc_720p_memory_access_method memory_access_model);
+
+void vidc_720p_encode_unalign_bitstream(u32 upper_unalign_word,
+	u32 lower_unalign_word);
+
+void vidc_720p_encode_set_seq_header_buffer(u32 ext_buffer_start,
+	u32 ext_buffer_end, u32 start_byte_num);
+
+void vidc_720p_encode_frame(u32 ch_id, u32 ext_buffer_start,
+	u32 ext_buffer_end, u32 start_byte_number,
+	u32 y_addr, u32 c_addr);
+
+void vidc_720p_encode_get_header(u32 *pi_enc_header_size);
+
+void vidc_720p_enc_frame_info
+	(struct vidc_720p_enc_frame_info *enc_frame_info);
+
+void vidc_720p_decode_bitstream_header(u32 ch_id, u32 dec_unit_size,
+	u32 start_byte_num, u32 ext_buffer_start, u32 ext_buffer_end,
+	enum vidc_720p_memory_access_method memory_access_model,
+	u32 decode_order);
+
+void vidc_720p_decode_get_seq_hdr_info
+    (struct vidc_720p_seq_hdr_info *seq_hdr_info);
+
+void vidc_720p_decode_set_dpb_release_buffer_mask
+    (u32 i_dpb_release_buffer_mask);
+
+void vidc_720p_decode_set_dpb_buffers(u32 i_buf_index, u32 *pi_dpb_buffer);
+
+void vidc_720p_decode_set_comv_buffer
+    (u32 *pi_dpb_comv_buffer, u32 alloc_len);
+
+void vidc_720p_decode_set_dpb_details
+    (u32 num_dpb, u32 alloc_len, u32 *ref_buffer);
+
+void vidc_720p_decode_set_mpeg4Post_filter(u32 enable_post_filter);
+
+void vidc_720p_decode_set_error_control(u32 enable_error_control);
+
+void vidc_720p_decode_set_mpeg4_data_partitionbuffer(u32 *vsp_buf_start);
+
+void vidc_720p_decode_setH264VSPBuffer(u32 *pi_vsp_temp_buffer_start);
+
+void vidc_720p_decode_frame(u32 ch_id, u32 ext_buffer_start,
+		u32 ext_buffer_end, u32 dec_unit_size,
+		u32 start_byte_num, u32 input_frame_tag);
+
+void vidc_720p_issue_eos(u32 i_ch_id);
+void vidc_720p_eos_info(u32 *disp_status, u32 *resl_change);
+
+void vidc_720p_decode_display_info
+    (struct vidc_720p_dec_disp_info *disp_info);
+
+void vidc_720p_decode_skip_frm_details(u32 *free_luma_dpb);
+
+void vidc_720p_metadata_enable(u32 flag, u32 *input_buffer);
+
+void vidc_720p_decode_dynamic_req_reset(void);
+
+void vidc_720p_decode_dynamic_req_set(u32 property);
+
+void vidc_720p_decode_setpassthrough_start(u32 pass_startaddr);
+
+
+
+#define DDL_720P_REG_BASE VIDC_720P_WRAPPER_REG_BASE
+#define VIDC_BUSY_WAIT(n) udelay(n)
+
+#undef VIDC_REGISTER_LOG_MSG
+#undef VIDC_REGISTER_LOG_INTO_BUFFER
+
+#ifdef VIDC_REGISTER_LOG_MSG
+#define VIDC_MSG1(msg_format, a) printk(KERN_INFO msg_format, a)
+#define VIDC_MSG2(msg_format, a, b) printk(KERN_INFO msg_format, a, b)
+#define VIDC_MSG3(msg_format, a, b, c) printk(KERN_INFO msg_format, a, b, c)
+#else
+#define VIDC_MSG1(msg_format, a)
+#define VIDC_MSG2(msg_format, a, b)
+#define VIDC_MSG3(msg_format, a, b, c)
+#endif
+
+#ifdef VIDC_REGISTER_LOG_INTO_BUFFER
+
+#define VIDC_REGLOG_BUFSIZE 200000
+#define VIDC_REGLOG_MAX_PRINT_SIZE 100
+extern char vidclog[VIDC_REGLOG_BUFSIZE];
+extern unsigned int vidclog_index;
+
+#define VIDC_LOG_BUFFER_INIT \
+{if (vidclog_index) \
+  memset(vidclog, 0, vidclog_index+1); \
+  vidclog_index = 0; }
+
+#define VIDC_REGLOG_CHECK_BUFINDEX(req_size) \
+  vidclog_index = \
+  (vidclog_index+(req_size) < VIDC_REGLOG_BUFSIZE) ? vidclog_index : 0;
+
+#define VIDC_LOG_WRITE(reg, val) \
+{unsigned int len; \
+	VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \
+	len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \
+	"(0x%x:"#reg"=0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE, val);\
+	vidclog_index += len; }
+
+#define VIDC_LOG_WRITEI(reg, index, val) \
+{unsigned int len; \
+	VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \
+	len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \
+	"(0x%x:"#reg"=0x%x)" , VIDC_##reg##_ADDR(index)-DDL_720P_REG_BASE,  \
+	val); vidclog_index += len; }
+
+#define VIDC_LOG_WRITEF(reg, field, val) \
+{unsigned int len; \
+	VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \
+	len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \
+	"(0x%x:"#reg":0x%x:=0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE,  \
+	VIDC_##reg##_##field##_BMSK,  val);\
+	vidclog_index += len; }
+
+#define VIDC_LOG_READ(reg, pval) \
+{ unsigned int len; \
+	VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \
+	len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \
+	"(0x%x:"#reg"==0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE,  \
+	(u32)*pval); \
+	vidclog_index += len; }
+
+#define VIDC_STR_LOGBUFFER(str) \
+{ unsigned int len; \
+	VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \
+	len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \
+	"<%s>" , str); vidclog_index += len; }
+
+#define VIDC_LONG_LOGBUFFER(str, arg1) \
+{ unsigned int len; \
+	VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \
+	len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \
+	"<%s=0x%x>" , str, arg1); vidclog_index += len; }
+
+#define VIDC_DEBUG_REGISTER_LOG \
+{ u32 val; unsigned int len; \
+	val = VIDC_720P_IN(REG_881638); \
+	VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \
+	len = snprintf(&vidclog[vidclog_index], 50,  "[dbg1=%x]" , val); \
+	vidclog_index += len; \
+	val = VIDC_720P_IN(REG_161486); \
+	VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \
+	len = snprintf(&vidclog[vidclog_index], 50,  "[dbg2=%x]" , val); \
+	vidclog_index += len; }
+
+#else
+#define VIDC_LOG_WRITE(reg, val)
+#define VIDC_LOG_WRITEI(reg, index, val)
+#define VIDC_LOG_WRITEF(reg, field, val)
+#define VIDC_LOG_READ(reg, pval)
+#define VIDC_LOG_BUFFER_INIT
+#define VIDC_STR_LOGBUFFER(str)
+#define VIDC_LONG_LOGBUFFER(str, arg1)
+#define VIDC_DEBUG_REGISTER_LOG
+#endif
+
+void vidcputlog(char *str);
+void vidcput_debug_reglog(void);
+
+#define VIDC_LOGERR_STRING(str) \
+do { \
+	VIDC_STR_LOGBUFFER(str); \
+	VIDC_MSG1("\n<%s>", str); \
+} while (0)
+
+#define VIDC_LOG_STRING(str) \
+do { \
+	VIDC_STR_LOGBUFFER(str); \
+	VIDC_MSG1("\n<%s>", str); \
+} while (0)
+
+#define VIDC_LOG1(str, arg1) \
+do { \
+	VIDC_LONG_LOGBUFFER(str, arg1); \
+	VIDC_MSG2("\n<%s=0x%08x>", str, arg1); \
+} while (0)
+
+#define VIDC_IO_OUT(reg,  val) \
+do { \
+	VIDC_LOG_WRITE(reg, (u32)val);  \
+	VIDC_MSG2("\n(0x%08x:"#reg"=0x%08x)",  \
+	(u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE),  (u32)val); \
+	mb(); \
+	VIDC_720P_OUT(reg, val);  \
+} while (0)
+
+#define VIDC_IO_OUTI(reg,  index,  val) \
+do { \
+	VIDC_LOG_WRITEI(reg, index, (u32)val); \
+	VIDC_MSG2("\n(0x%08x:"#reg"=0x%08x)",  \
+	(u32)(VIDC_##reg##_ADDR(index)-DDL_720P_REG_BASE),  (u32)val); \
+	mb(); \
+	VIDC_720P_OUTI(reg, index, val);  \
+} while (0)
+
+#define VIDC_IO_OUTF(reg,  field,  val) \
+do { \
+	VIDC_LOG_WRITEF(reg, field, val); \
+	VIDC_MSG3("\n(0x%08x:"#reg":0x%x:=0x%08x)",  \
+	(u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE),  \
+	VIDC_##reg##_##field##_BMSK,  (u32)val); \
+	mb(); \
+	VIDC_720P_OUTF(reg, field, val);  \
+} while (0)
+
+#define VIDC_IO_IN(reg, pval) \
+do { \
+	mb(); \
+	*pval = (u32) VIDC_720P_IN(reg); \
+	VIDC_LOG_READ(reg, pval); \
+	VIDC_MSG2("\n(0x%08x:"#reg"==0x%08x)",  \
+	(u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), (u32) *pval);  \
+} while (0)
+
+#define VIDC_IO_INF(reg, mask, pval) \
+do { \
+	mb(); \
+	*pval = VIDC_720P_INF(reg, mask); \
+	VIDC_LOG_READ(reg, pval); \
+	VIDC_MSG2("\n(0x%08x:"#reg"==0x%08x)",  \
+	(u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE),  *pval); \
+} while (0)
+
+#endif
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
new file mode 100644
index 0000000..12dcbf3
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
@@ -0,0 +1,722 @@
+/* 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 <linux/firmware.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+#include <mach/clk.h>
+#include <mach/msm_reqs.h>
+#include <linux/interrupt.h>
+#include "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)
+#define WVGA_PERF_LEVEL (1500 * 30)
+
+static unsigned int mfc_clk_freq_table[3] = {
+	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;
+
+#define VIDC_BOOT_FW			"vidc_720p_command_control.fw"
+#define VIDC_MPG4_DEC_FW		"vidc_720p_mp4_dec_mc.fw"
+#define VIDC_H263_DEC_FW		"vidc_720p_h263_dec_mc.fw"
+#define VIDC_H264_DEC_FW		"vidc_720p_h264_dec_mc.fw"
+#define VIDC_MPG4_ENC_FW		"vidc_720p_mp4_enc_mc.fw"
+#define VIDC_H264_ENC_FW		"vidc_720p_h264_enc_mc.fw"
+#define VIDC_VC1_DEC_FW		"vidc_720p_vc1_dec_mc.fw"
+
+unsigned char *vidc_command_control_fw;
+u32 vidc_command_control_fw_size;
+
+unsigned char *vidc_mpg4_dec_fw;
+u32 vidc_mpg4_dec_fw_size;
+
+unsigned char *vidc_h263_dec_fw;
+u32 vidc_h263_dec_fw_size;
+
+unsigned char *vidc_h264_dec_fw;
+u32 vidc_h264_dec_fw_size;
+
+unsigned char *vidc_mpg4_enc_fw;
+u32 vidc_mpg4_enc_fw_size;
+
+unsigned char *vidc_h264_enc_fw;
+u32 vidc_h264_enc_fw_size;
+
+unsigned char *vidc_vc1_dec_fw;
+u32 vidc_vc1_dec_fw_size;
+
+static u32 res_trk_disable_videocore(void)
+{
+	int rc = -1;
+	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) {
+		VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc);
+		mutex_unlock(&resource_context.lock);
+		return false;
+	}
+	msleep(20);
+
+	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)
+{
+	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 (clk_enable(resource_context.pclk)) {
+			VCDRES_MSG_ERROR("vidc pclk Enable failed\n");
+
+			clk_put(resource_context.hclk);
+			clk_put(resource_context.hclk_div2);
+			mutex_unlock(&resource_context.lock);
+			return false;
+		}
+
+		if (clk_enable(resource_context.hclk)) {
+			VCDRES_MSG_ERROR("vidc  hclk Enable failed\n");
+			clk_put(resource_context.pclk);
+			clk_put(resource_context.hclk_div2);
+			mutex_unlock(&resource_context.lock);
+			return false;
+		}
+
+		if (clk_enable(resource_context.hclk_div2)) {
+			VCDRES_MSG_ERROR("vidc  hclk Enable failed\n");
+			clk_put(resource_context.hclk);
+			clk_put(resource_context.pclk);
+			mutex_unlock(&resource_context.lock);
+			return false;
+		}
+	}
+
+	resource_context.clock_enabled = 1;
+	mutex_unlock(&resource_context.lock);
+	return true;
+}
+
+static u32 res_trk_sel_clk_rate(unsigned long hclk_rate)
+{
+	mutex_lock(&resource_context.lock);
+	if (clk_set_rate(resource_context.hclk,
+		hclk_rate)) {
+		VCDRES_MSG_ERROR("vidc hclk set rate failed\n");
+		mutex_unlock(&resource_context.lock);
+		return false;
+	}
+	resource_context.hclk_rate = hclk_rate;
+	mutex_unlock(&resource_context.lock);
+	return true;
+}
+
+static u32 res_trk_get_clk_rate(unsigned long *phclk_rate)
+{
+	if (!phclk_rate) {
+		VCDRES_MSG_ERROR("%s(): phclk_rate is NULL\n", __func__);
+		return false;
+	}
+	mutex_lock(&resource_context.lock);
+	*phclk_rate = clk_get_rate(resource_context.hclk);
+	if (!(*phclk_rate)) {
+		VCDRES_MSG_ERROR("vidc hclk get rate failed\n");
+		mutex_unlock(&resource_context.lock);
+		return false;
+	}
+	mutex_unlock(&resource_context.lock);
+	return true;
+}
+
+u32 res_trk_disable_clocks(void)
+{
+	VCDRES_MSG_LOW("in res_trk_disable_clocks()\n");
+
+	mutex_lock(&resource_context.lock);
+
+	if (!resource_context.clock_enabled) {
+		mutex_unlock(&resource_context.lock);
+		return false;
+	}
+
+	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;
+	clk_disable(resource_context.hclk);
+	clk_disable(resource_context.hclk_div2);
+	clk_disable(resource_context.pclk);
+	mutex_unlock(&resource_context.lock);
+
+	return true;
+}
+
+static u32 res_trk_enable_videocore(void)
+{
+	mutex_lock(&resource_context.lock);
+	if (!resource_context.rail_enabled) {
+		int rc = -1;
+
+		rc = regulator_enable(resource_context.regulator);
+		if (rc) {
+			VCDRES_MSG_ERROR("%s(): regulator_enable failed %d\n",
+							 __func__, rc);
+			goto bail_out;
+		}
+		VCDRES_MSG_LOW("%s(): regulator enable Success %d\n",
+							__func__, rc);
+
+		resource_context.pclk = clk_get(resource_context.device,
+			"mfc_pclk");
+
+		if (IS_ERR(resource_context.pclk)) {
+			VCDRES_MSG_ERROR("%s(): mfc_pclk get failed\n"
+							 , __func__);
+			goto disable_regulator;
+		}
+
+		resource_context.hclk = clk_get(resource_context.device,
+			"mfc_clk");
+
+		if (IS_ERR(resource_context.hclk)) {
+			VCDRES_MSG_ERROR("%s(): mfc_clk get failed\n"
+							 , __func__);
+
+			goto release_pclk;
+		}
+
+		resource_context.hclk_div2 =
+			clk_get(resource_context.device, "mfc_div2_clk");
+
+		if (IS_ERR(resource_context.hclk_div2)) {
+			VCDRES_MSG_ERROR("%s(): mfc_div2_clk get failed\n"
+							 , __func__);
+			goto release_hclk_pclk;
+		}
+
+		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;
+		}
+
+		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);
+			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)
+{
+	u64 perf_lvl;
+	u64 temp;
+
+	VCDRES_MSG_MED("\n %s():: freq = %u\n", __func__, (u32)freq);
+
+	if (!freq)
+		return 0;
+
+	temp = freq * 1000;
+	do_div(temp, VCD_RESTRK_HZ_PER_1000_PERFLVL);
+	perf_lvl = (u32)temp;
+	VCDRES_MSG_MED("\n %s(): perf_lvl = %u\n", __func__,
+		(u32)perf_lvl);
+
+	return (u32)perf_lvl;
+}
+
+static u32 res_trk_convert_perf_lvl_to_freq(u64 perf_lvl)
+{
+	u64 freq, temp;
+
+	VCDRES_MSG_MED("\n %s():: perf_lvl = %u\n", __func__,
+		(u32)perf_lvl);
+	temp = (perf_lvl * VCD_RESTRK_HZ_PER_1000_PERFLVL) + 999;
+	do_div(temp, 1000);
+	freq = (u32)temp;
+	VCDRES_MSG_MED("\n %s(): freq = %u\n", __func__, (u32)freq);
+
+	return (u32)freq;
+}
+
+static struct clk *ebi1_clk;
+
+u32 res_trk_power_up(void)
+{
+	VCDRES_MSG_LOW("clk_regime_rail_enable");
+	VCDRES_MSG_LOW("clk_regime_sel_rail_control");
+#ifdef AXI_CLK_SCALING
+{
+	VCDRES_MSG_MED("\n res_trk_power_up():: "
+		"Calling AXI add requirement\n");
+	ebi1_clk = clk_get(NULL, "ebi1_vcd_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_videocore();
+}
+
+u32 res_trk_power_down(void)
+{
+	VCDRES_MSG_LOW("clk_regime_rail_disable");
+#ifdef AXI_CLK_SCALING
+	VCDRES_MSG_MED("\n res_trk_power_down()::"
+		"Calling AXI remove requirement\n");
+	clk_disable(ebi1_clk);
+	clk_put(ebi1_clk);
+#endif
+	VCDRES_MSG_MED("\n res_trk_power_down():: Calling "
+		"res_trk_disable_videocore()\n");
+	return res_trk_disable_videocore();
+}
+
+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 = VCD_RESTRK_MAX_PERF_LEVEL;
+	return true;
+}
+
+u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl,
+	struct vcd_dev_ctxt *dev_ctxt)
+{
+	struct vcd_clnt_ctxt *cctxt_itr = NULL;
+	u32 axi_freq = 0, mfc_freq = 0, calc_mfc_freq = 0;
+	u8 enc_clnt_present = false;
+
+	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);
+	calc_mfc_freq = res_trk_convert_perf_lvl_to_freq(
+		(u64)req_perf_lvl);
+
+	if (calc_mfc_freq < VCD_RESTRK_MIN_FREQ_POINT)
+		calc_mfc_freq = VCD_RESTRK_MIN_FREQ_POINT;
+	else if (calc_mfc_freq > VCD_RESTRK_MAX_FREQ_POINT)
+		calc_mfc_freq = VCD_RESTRK_MAX_FREQ_POINT;
+
+	cctxt_itr = dev_ctxt->cctxt_list_head;
+	while (cctxt_itr) {
+		VCDRES_MSG_LOW("\n cctxt_itr = %p", cctxt_itr);
+		if (!cctxt_itr->decoding) {
+				VCDRES_MSG_LOW("\n Encoder client");
+				enc_clnt_present = true;
+				break;
+		} else {
+				VCDRES_MSG_LOW("\n Decoder client");
+		}
+		cctxt_itr = cctxt_itr->next;
+	}
+
+	if (enc_clnt_present) {
+		if (req_perf_lvl >= VGA_PERF_LEVEL) {
+			mfc_freq = mfc_clk_freq_table[2];
+			axi_freq = axi_clk_freq_table_enc[1];
+		} else {
+			mfc_freq = mfc_clk_freq_table[0];
+			axi_freq = axi_clk_freq_table_enc[0];
+		}
+		VCDRES_MSG_MED("\n ENCODER: axi_freq = %u"
+			", mfc_freq = %u, calc_mfc_freq = %u,"
+			" req_perf_lvl = %u", axi_freq,
+			mfc_freq, calc_mfc_freq,
+			req_perf_lvl);
+	} else {
+		if (req_perf_lvl <= QVGA_PERF_LEVEL) {
+			mfc_freq = mfc_clk_freq_table[0];
+			axi_freq = axi_clk_freq_table_dec[0];
+		} else {
+			axi_freq = axi_clk_freq_table_dec[0];
+			if (req_perf_lvl <= VGA_PERF_LEVEL)
+				mfc_freq = mfc_clk_freq_table[0];
+			else if (req_perf_lvl <= WVGA_PERF_LEVEL)
+				mfc_freq = mfc_clk_freq_table[1];
+			else {
+				mfc_freq = mfc_clk_freq_table[2];
+				axi_freq = axi_clk_freq_table_dec[1];
+			}
+		}
+		VCDRES_MSG_MED("\n DECODER: axi_freq = %u"
+			", mfc_freq = %u, calc_mfc_freq = %u,"
+			" req_perf_lvl = %u", axi_freq,
+			mfc_freq, calc_mfc_freq,
+			req_perf_lvl);
+	}
+
+#ifdef AXI_CLK_SCALING
+    if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) {
+		VCDRES_MSG_MED("\n %s(): Setting AXI freq to %u",
+			__func__, axi_freq);
+		clk_set_rate(ebi1_clk, axi_freq * 1000);
+	}
+#endif
+
+#ifdef USE_RES_TRACKER
+    if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) {
+		VCDRES_MSG_MED("\n %s(): Setting MFC freq to %u",
+			__func__, mfc_freq);
+		if (!res_trk_sel_clk_rate(mfc_freq)) {
+			VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n",
+				__func__);
+			*pn_set_perf_lvl = 0;
+			return false;
+		}
+	}
+#endif
+
+	*pn_set_perf_lvl =
+	    res_trk_convert_freq_to_perf_lvl((u64) mfc_freq);
+	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 = res_trk_convert_freq_to_perf_lvl((u64) freq);
+	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_boot = NULL;
+	const struct firmware *fw_mpg4_dec = NULL;
+	const struct firmware *fw_h263_dec = NULL;
+	const struct firmware *fw_h264_dec = NULL;
+	const struct firmware *fw_mpg4_enc = NULL;
+	const struct firmware *fw_h264_enc = NULL;
+	const struct firmware *fw_vc1_dec = 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_boot, VIDC_BOOT_FW,
+						  resource_context.device);
+	if (rc) {
+		VCDRES_MSG_ERROR("request_firmware for %s error %d\n",
+				VIDC_BOOT_FW, rc);
+		mutex_unlock(&resource_context.lock);
+		return false;
+	}
+	vidc_command_control_fw = (unsigned char *)fw_boot->data;
+	vidc_command_control_fw_size = (u32) fw_boot->size;
+
+	rc = request_firmware(&fw_mpg4_dec, VIDC_MPG4_DEC_FW,
+						  resource_context.device);
+	if (rc) {
+		VCDRES_MSG_ERROR("request_firmware for %s error %d\n",
+				VIDC_MPG4_DEC_FW, rc);
+		status = false;
+		goto boot_fw_free;
+	}
+	vidc_mpg4_dec_fw = (unsigned char *)fw_mpg4_dec->data;
+	vidc_mpg4_dec_fw_size = (u32) fw_mpg4_dec->size;
+
+
+	rc = request_firmware(&fw_h263_dec, VIDC_H263_DEC_FW,
+						  resource_context.device);
+	if (rc) {
+		VCDRES_MSG_ERROR("request_firmware for %s error %d\n",
+				VIDC_H263_DEC_FW, rc);
+		status = false;
+		goto mp4dec_fw_free;
+	}
+	vidc_h263_dec_fw = (unsigned char *)fw_h263_dec->data;
+	vidc_h263_dec_fw_size = (u32) fw_h263_dec->size;
+
+	rc = request_firmware(&fw_h264_dec, VIDC_H264_DEC_FW,
+						  resource_context.device);
+	if (rc) {
+		VCDRES_MSG_ERROR("request_firmware for %s error %d\n",
+				VIDC_H264_DEC_FW, rc);
+		status = false;
+		goto h263dec_fw_free;
+	}
+	vidc_h264_dec_fw = (unsigned char *)fw_h264_dec->data;
+	vidc_h264_dec_fw_size = (u32) fw_h264_dec->size;
+
+	rc = request_firmware(&fw_mpg4_enc, VIDC_MPG4_ENC_FW,
+						  resource_context.device);
+	if (rc) {
+		VCDRES_MSG_ERROR("request_firmware for %s error %d\n",
+				VIDC_MPG4_ENC_FW, rc);
+		status = false;
+		goto h264dec_fw_free;
+	}
+	vidc_mpg4_enc_fw = (unsigned char *)fw_mpg4_enc->data;
+	vidc_mpg4_enc_fw_size = (u32) fw_mpg4_enc->size;
+
+	rc = request_firmware(&fw_h264_enc, VIDC_H264_ENC_FW,
+						  resource_context.device);
+	if (rc) {
+		VCDRES_MSG_ERROR("request_firmware for %s error %d\n",
+				VIDC_H264_ENC_FW, rc);
+		status = false;
+		goto mp4enc_fw_free;
+	}
+	vidc_h264_enc_fw = (unsigned char *)fw_h264_enc->data;
+	vidc_h264_enc_fw_size = (u32) fw_h264_enc->size;
+
+	rc = request_firmware(&fw_vc1_dec, VIDC_VC1_DEC_FW,
+						  resource_context.device);
+	if (rc) {
+		VCDRES_MSG_ERROR("request_firmware for %s error %d\n",
+				VIDC_VC1_DEC_FW, rc);
+		status = false;
+		goto h264enc_fw_free;
+	}
+	vidc_vc1_dec_fw = (unsigned char *)fw_vc1_dec->data;
+	vidc_vc1_dec_fw_size = (u32) fw_vc1_dec->size;
+	mutex_unlock(&resource_context.lock);
+	return status;
+
+h264enc_fw_free:
+	release_firmware(fw_h264_enc);
+mp4enc_fw_free:
+	release_firmware(fw_mpg4_enc);
+h264dec_fw_free:
+	release_firmware(fw_h264_dec);
+h263dec_fw_free:
+	release_firmware(fw_h263_dec);
+mp4dec_fw_free:
+	release_firmware(fw_mpg4_dec);
+boot_fw_free:
+	release_firmware(fw_boot);
+	mutex_unlock(&resource_context.lock);
+	return false;
+}
+
+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__);
+		return;
+	}
+	memset(&resource_context, 0, sizeof(resource_context));
+	mutex_init(&resource_context.lock);
+	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;
+	} else {
+		resource_context.memtype = -1;
+	}
+}
+
+u32 res_trk_get_core_type(void){
+	return resource_context.core_type;
+}
+
+u32 res_trk_get_mem_type(void){
+	return resource_context.memtype;
+}
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
new file mode 100644
index 0000000..3012858
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
@@ -0,0 +1,56 @@
+/* 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 _VIDEO_720P_RESOURCE_TRACKER_H_
+#define _VIDEO_720P_RESOURCE_TRACKER_H_
+#include <mach/board.h>
+#include "vcd_res_tracker_api.h"
+
+#define VCD_RESTRK_MIN_PERF_LEVEL 37900
+#define VCD_RESTRK_MAX_PERF_LEVEL 108000
+#define VCD_RESTRK_MIN_FREQ_POINT 61440000
+#define VCD_RESTRK_MAX_FREQ_POINT 170667000
+#define VCD_RESTRK_HZ_PER_1000_PERFLVL 1580250
+
+struct res_trk_context {
+	struct device *device;
+	u32 irq_num;
+	struct mutex lock;
+	struct clk *hclk;
+	struct clk *hclk_div2;
+	struct clk *pclk;
+	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;
+};
+
+#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/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
new file mode 100644
index 0000000..db84743
--- /dev/null
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
@@ -0,0 +1,30 @@
+/* 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 _VIDEO_720P_RESOURCE_TRACKER_API_H_
+#define _VIDEO_720P_RESOURCE_TRACKER_API_H_
+
+#include "vcd_core.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_mem_type(void);
+#endif
diff --git a/drivers/video/msm/vidc/Kconfig b/drivers/video/msm/vidc/Kconfig
new file mode 100644
index 0000000..9ffcb15
--- /dev/null
+++ b/drivers/video/msm/vidc/Kconfig
@@ -0,0 +1,39 @@
+#
+# VIDEO CORE
+#
+menuconfig MSM_VIDC
+	bool "Video Core Driver"
+	depends on ARCH_MSM8X60 || ARCH_MSM7X30 || ARCH_MSM8960
+	default y
+	---help---
+	Say Y here to see options for video device drivers.
+	If you say N, all options in this submenu will be skipped and disabled.
+
+config MSM_VIDC_720P
+	bool "720P Video Core"
+	depends on MSM_VIDC && ARCH_MSM7X30
+	default y
+	help
+	This option enables support for Video core.
+
+config MSM_VIDC_1080P
+	bool "1080P Video Core"
+	depends on MSM_VIDC && (ARCH_MSM8X60 || ARCH_MSM8960)
+	default y
+	help
+	This option enables support for Video core.
+
+config MSM_VIDC_VENC
+	tristate "Video encoder"
+	depends on MSM_VIDC
+	default y
+	help
+	This option enables support for Video encoder.
+
+config MSM_VIDC_VDEC
+	tristate "Video decoder"
+	depends on MSM_VIDC
+	default y
+	help
+	This option enables support for Video decoder.
+
diff --git a/drivers/video/msm/vidc/Makefile b/drivers/video/msm/vidc/Makefile
new file mode 100644
index 0000000..af41f18
--- /dev/null
+++ b/drivers/video/msm/vidc/Makefile
@@ -0,0 +1,62 @@
+ifdef CONFIG_MSM_VIDC_720P
+EXTRA_CFLAGS += -Idrivers/video/msm/vidc/720p/ddl
+EXTRA_CFLAGS += -Idrivers/video/msm/vidc/720p/resource_tracker
+endif
+
+ifdef CONFIG_MSM_VIDC_1080P
+EXTRA_CFLAGS  += -Idrivers/video/msm/vidc/1080p/ddl
+EXTRA_CFLAGS  += -Idrivers/video/msm/vidc/1080p/resource_tracker
+endif
+
+EXTRA_CFLAGS  += -Idrivers/video/msm/vidc/common/dec
+EXTRA_CFLAGS  += -Idrivers/video/msm/vidc/common/enc
+EXTRA_CFLAGS  += -Idrivers/video/msm/vidc/common/vcd
+EXTRA_CFLAGS  += -Idrivers/video/msm/vidc/common/init
+
+obj-$(CONFIG_MSM_VIDC) += vidc.o
+
+vidc-objs :=	common/init/vidc_init.o \
+		common/vcd/vcd_api.o \
+		common/vcd/vcd_power_sm.o \
+		common/vcd/vcd_client_sm.o \
+		common/vcd/vcd_device_sm.o \
+		common/vcd/vcd_scheduler.o \
+		common/vcd/vcd_sub.o \
+
+ifdef CONFIG_MSM_VIDC_720P
+vidc-objs +=	720p/ddl/vcd_ddl_firmware.o \
+		720p/ddl/vcd_ddl_metadata.o \
+		720p/ddl/vidc.o \
+		720p/ddl/vcd_ddl_utils.o \
+		720p/ddl/vcd_ddl.o \
+		720p/ddl/vcd_ddl_helper.o \
+		720p/ddl/vcd_ddl_interrupt_handler.o \
+		720p/ddl/vcd_ddl_hal.o \
+		720p/ddl/vcd_ddl_properties.o \
+		720p/resource_tracker/vcd_res_tracker.o \
+		720p/ddl/vcd_ddl_errors.o
+endif
+
+ifdef CONFIG_MSM_VIDC_1080P
+vidc-objs +=	1080p/ddl/vcd_ddl_helper.o \
+		1080p/ddl/vcd_ddl_utils.o \
+		1080p/ddl/vcd_ddl_interrupt_handler.o \
+		1080p/ddl/vcd_ddl_properties.o \
+		1080p/ddl/vcd_ddl_errors.o \
+		1080p/ddl/vcd_ddl_shared_mem.o \
+		1080p/ddl/vidc.o \
+		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
+
+obj-$(CONFIG_MSM_VIDC_VDEC) += vidc_vdec.o
+
+vidc_vdec-objs :=	common/dec/vdec.o
+
+obj-$(CONFIG_MSM_VIDC_VENC) += vidc_venc.o
+
+vidc_venc-objs :=	common/enc/venc.o \
+			common/enc/venc_internal.o
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
new file mode 100644
index 0000000..48d5119
--- /dev/null
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -0,0 +1,1904 @@
+/* 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 <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/android_pmem.h>
+#include <linux/clk.h>
+#include <linux/timer.h>
+
+#include "vidc_type.h"
+#include "vcd_api.h"
+#include "vdec_internal.h"
+#include "vidc_init.h"
+
+
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+#define INFO(x...) printk(KERN_INFO x)
+#define ERR(x...) printk(KERN_ERR x)
+
+#define VID_DEC_NAME		"msm_vidc_dec"
+
+static struct vid_dec_dev *vid_dec_device_p;
+static dev_t vid_dec_dev_num;
+static struct class *vid_dec_class;
+static s32 vid_dec_get_empty_client_index(void)
+{
+	u32 i, found = false;
+
+	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+		if (!vid_dec_device_p->vdec_clients[i].vcd_handle) {
+			found = true;
+			break;
+		}
+	}
+	if (!found) {
+		ERR("%s():ERROR No space for new client\n", __func__);
+		return -ENOMEM;
+	} else {
+		DBG("%s(): available client index = %u\n", __func__, i);
+		return i;
+	}
+}
+
+u32 vid_dec_get_status(u32 status)
+{
+	u32 vdec_status;
+
+	switch (status) {
+	case VCD_ERR_SEQHDR_PARSE_FAIL:
+	case VCD_ERR_BITSTREAM_ERR:
+	case VCD_S_SUCCESS:
+		vdec_status = VDEC_S_SUCCESS;
+		break;
+	case VCD_ERR_FAIL:
+		vdec_status = VDEC_S_EFAIL;
+		break;
+	case VCD_ERR_ALLOC_FAIL:
+		vdec_status = VDEC_S_ENOSWRES;
+		break;
+	case VCD_ERR_ILLEGAL_OP:
+		vdec_status = VDEC_S_EINVALCMD;
+		break;
+	case VCD_ERR_ILLEGAL_PARM:
+		vdec_status = VDEC_S_EBADPARAM;
+		break;
+	case VCD_ERR_BAD_POINTER:
+	case VCD_ERR_BAD_HANDLE:
+		vdec_status = VDEC_S_EFATAL;
+		break;
+	case VCD_ERR_NOT_SUPPORTED:
+		vdec_status = VDEC_S_ENOTSUPP;
+		break;
+	case VCD_ERR_BAD_STATE:
+		vdec_status = VDEC_S_EINVALSTATE;
+		break;
+	case VCD_ERR_BUSY:
+		vdec_status = VDEC_S_BUSY;
+		break;
+	case VCD_ERR_MAX_CLIENT:
+		vdec_status = VDEC_S_ENOHWRES;
+		break;
+	default:
+		vdec_status = VDEC_S_EFAIL;
+		break;
+	}
+
+	return vdec_status;
+}
+
+static void vid_dec_notify_client(struct video_client_ctx *client_ctx)
+{
+	if (client_ctx)
+		complete(&client_ctx->event);
+}
+
+void vid_dec_vcd_open_done(struct video_client_ctx *client_ctx,
+			   struct vcd_handle_container *handle_container)
+{
+	DBG("vid_dec_vcd_open_done\n");
+
+	if (client_ctx) {
+		if (handle_container)
+			client_ctx->vcd_handle = handle_container->handle;
+		else
+			ERR("%s(): ERROR. handle_container is NULL\n",
+			    __func__);
+
+		vid_dec_notify_client(client_ctx);
+	} else
+		ERR("%s(): ERROR. client_ctx is NULL\n", __func__);
+}
+
+static void vid_dec_input_frame_done(struct video_client_ctx *client_ctx,
+				     u32 event, u32 status,
+				     struct vcd_frame_data *vcd_frame_data)
+{
+	struct vid_dec_msg *vdec_msg;
+
+	if (!client_ctx || !vcd_frame_data) {
+		ERR("vid_dec_input_frame_done() NULL pointer\n");
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg "
+		    " buffer\n");
+		return;
+	}
+
+	vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status);
+
+	if (event == VCD_EVT_RESP_INPUT_DONE) {
+		vdec_msg->vdec_msg_info.msgcode =
+		    VDEC_MSG_RESP_INPUT_BUFFER_DONE;
+		DBG("Send INPUT_DON message to client = %p\n", client_ctx);
+
+	} else if (event == VCD_EVT_RESP_INPUT_FLUSHED) {
+		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: "
+			"%d\n", event);
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
+	}
+
+	vdec_msg->vdec_msg_info.msgdata.input_frame_clientdata =
+	    (void *)vcd_frame_data->frm_clnt_data;
+	vdec_msg->vdec_msg_info.msgdatasize = sizeof(void *);
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+static void vid_dec_output_frame_done(struct video_client_ctx *client_ctx,
+			u32 event, u32 status,
+			struct vcd_frame_data *vcd_frame_data)
+{
+	struct vid_dec_msg *vdec_msg;
+
+	unsigned long kernel_vaddr = 0, phy_addr = 0, user_vaddr = 0;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	enum vdec_picture pic_type;
+
+	if (!client_ctx || !vcd_frame_data) {
+		ERR("vid_dec_input_frame_done() NULL pointer\n");
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg "
+		    " buffer\n");
+		return;
+	}
+
+	vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status);
+
+	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: "
+			"%d\n", event);
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID;
+	}
+
+	kernel_vaddr = (unsigned long)vcd_frame_data->virtual;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+				      false, &user_vaddr, &kernel_vaddr,
+				      &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;
+		/* Data length */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.len =
+		    vcd_frame_data->data_len;
+		vdec_msg->vdec_msg_info.msgdata.output_frame.flags =
+		    vcd_frame_data->flags;
+		/* Timestamp pass-through from input frame */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp =
+		    vcd_frame_data->time_stamp;
+		/* Output frame client data */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.client_data =
+		    (void *)vcd_frame_data->frm_clnt_data;
+		/* Associated input frame client data */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.
+		    input_frame_clientdata =
+		    (void *)vcd_frame_data->ip_frm_tag;
+		/* Decoded picture width and height */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.
+		bottom =
+		    vcd_frame_data->dec_op_prop.disp_frm.bottom;
+		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.left =
+		    vcd_frame_data->dec_op_prop.disp_frm.left;
+		vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.right =
+			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:
+			pic_type = PICTURE_TYPE_I;
+			break;
+		case VCD_FRAME_P:
+			pic_type = PICTURE_TYPE_P;
+			break;
+		case VCD_FRAME_B:
+			pic_type = PICTURE_TYPE_B;
+			break;
+		case VCD_FRAME_NOTCODED:
+			pic_type = PICTURE_TYPE_SKIP;
+			break;
+		default:
+			pic_type = PICTURE_TYPE_UNKNOWN;
+		}
+		vdec_msg->vdec_msg_info.msgdata.output_frame.pic_type =
+			pic_type;
+		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;
+	}
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+static void vid_dec_lean_event(struct video_client_ctx *client_ctx,
+			       u32 event, u32 status)
+{
+	struct vid_dec_msg *vdec_msg;
+
+	if (!client_ctx) {
+		ERR("%s(): !client_ctx pointer\n", __func__);
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		ERR("%s(): cannot allocate vid_dec_msg buffer\n", __func__);
+		return;
+	}
+
+	vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status);
+
+	switch (event) {
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		INFO("msm_vidc_dec: Sending VDEC_MSG_EVT_CONFIG_CHANGED"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_CONFIG_CHANGED;
+		break;
+	case VCD_EVT_IND_RESOURCES_LOST:
+		INFO("msm_vidc_dec: Sending VDEC_EVT_RESOURCES_LOST"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_EVT_RESOURCES_LOST;
+		break;
+	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
+		INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_INPUT_DONE"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode =
+		    VDEC_MSG_RESP_FLUSH_INPUT_DONE;
+		break;
+	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
+		INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_OUTPUT_DONE"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode =
+		    VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
+		break;
+	case VCD_EVT_IND_HWERRFATAL:
+		INFO("msm_vidc_dec: Sending VDEC_MSG_EVT_HW_ERROR"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_HW_ERROR;
+		break;
+	case VCD_EVT_RESP_START:
+		INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_START_DONE"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_START_DONE;
+		break;
+	case VCD_EVT_RESP_STOP:
+		INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_STOP_DONE"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_STOP_DONE;
+		break;
+	case VCD_EVT_RESP_PAUSE:
+		INFO("msm_vidc_dec: Sending VDEC_MSG_RESP_PAUSE_DONE"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_PAUSE_DONE;
+		break;
+	case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
+		INFO("msm_vidc_dec: Sending VDEC_MSG_EVT_INFO_CONFIG_CHANGED"
+			 " to client");
+		vdec_msg->vdec_msg_info.msgcode =
+			 VDEC_MSG_EVT_INFO_CONFIG_CHANGED;
+		break;
+	default:
+		ERR("%s() : unknown event type\n", __func__);
+		break;
+	}
+
+	vdec_msg->vdec_msg_info.msgdatasize = 0;
+	if (client_ctx->stop_sync_cb &&
+	   (event == VCD_EVT_RESP_STOP || event == VCD_EVT_IND_HWERRFATAL)) {
+		client_ctx->stop_sync_cb = false;
+		complete(&client_ctx->event);
+		kfree(vdec_msg);
+		return;
+	}
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+
+void vid_dec_vcd_cb(u32 event, u32 status,
+		   void *info, size_t sz, void *handle, void *const client_data)
+{
+	struct video_client_ctx *client_ctx =
+	    (struct video_client_ctx *)client_data;
+
+	DBG("Entering %s()\n", __func__);
+
+	if (!client_ctx) {
+		ERR("%s(): client_ctx is NULL\n", __func__);
+		return;
+	}
+
+	client_ctx->event_status = status;
+
+	switch (event) {
+	case VCD_EVT_RESP_OPEN:
+		vid_dec_vcd_open_done(client_ctx,
+				      (struct vcd_handle_container *)
+				      info);
+		break;
+	case VCD_EVT_RESP_INPUT_DONE:
+	case VCD_EVT_RESP_INPUT_FLUSHED:
+		vid_dec_input_frame_done(client_ctx, event, status,
+					 (struct vcd_frame_data *)info);
+		break;
+	case VCD_EVT_RESP_OUTPUT_DONE:
+	case VCD_EVT_RESP_OUTPUT_FLUSHED:
+		vid_dec_output_frame_done(client_ctx, event, status,
+					  (struct vcd_frame_data *)info);
+		break;
+	case VCD_EVT_RESP_PAUSE:
+	case VCD_EVT_RESP_STOP:
+	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
+	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+	case VCD_EVT_IND_HWERRFATAL:
+	case VCD_EVT_IND_RESOURCES_LOST:
+	case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
+		vid_dec_lean_event(client_ctx, event, status);
+		break;
+	case VCD_EVT_RESP_START:
+		if (!client_ctx->seq_header_set)
+			vid_dec_lean_event(client_ctx, event, status);
+		else
+			vid_dec_notify_client(client_ctx);
+		break;
+	default:
+		ERR("%s() :  Error - Invalid event type =%u\n", __func__,
+		    event);
+		break;
+	}
+}
+
+static u32 vid_dec_set_codec(struct video_client_ctx *client_ctx,
+			     enum vdec_codec *vdec_codec)
+{
+	u32 result = true;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_codec codec;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !vdec_codec)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+
+	switch (*vdec_codec) {
+	case VDEC_CODECTYPE_MPEG4:
+		codec.codec = VCD_CODEC_MPEG4;
+		break;
+	case VDEC_CODECTYPE_H264:
+		codec.codec = VCD_CODEC_H264;
+		break;
+	case VDEC_CODECTYPE_DIVX_3:
+		codec.codec = VCD_CODEC_DIVX_3;
+		break;
+	case VDEC_CODECTYPE_DIVX_5:
+		codec.codec = VCD_CODEC_DIVX_5;
+		break;
+	case VDEC_CODECTYPE_XVID:
+		codec.codec = VCD_CODEC_XVID;
+		break;
+	case VDEC_CODECTYPE_H263:
+		codec.codec = VCD_CODEC_H263;
+		break;
+	case VDEC_CODECTYPE_MPEG2:
+		codec.codec = VCD_CODEC_MPEG2;
+		break;
+	case VDEC_CODECTYPE_VC1:
+		codec.codec = VCD_CODEC_VC1;
+		break;
+	case VDEC_CODECTYPE_VC1_RCV:
+		codec.codec = VCD_CODEC_VC1_RCV;
+		break;
+	default:
+		result = false;
+		break;
+	}
+
+	if (result) {
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					      &vcd_property_hdr, &codec);
+		if (vcd_status)
+			result = false;
+	}
+	return result;
+}
+
+static u32 vid_dec_set_output_format(struct video_client_ctx *client_ctx,
+				     enum vdec_output_fromat *output_format)
+{
+	u32 result = true;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_format vcd_prop_buffer_format;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !output_format)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;;
+	vcd_property_hdr.sz =
+	    sizeof(struct vcd_property_buffer_format);
+
+	switch (*output_format) {
+	case VDEC_YUV_FORMAT_NV12:
+		vcd_prop_buffer_format.buffer_format = VCD_BUFFER_FORMAT_NV12;
+		break;
+	case VDEC_YUV_FORMAT_TILE_4x2:
+		vcd_prop_buffer_format.buffer_format =
+		    VCD_BUFFER_FORMAT_TILE_4x2;
+		break;
+	default:
+		result = false;
+		break;
+	}
+
+	if (result)
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					      &vcd_property_hdr,
+					      &vcd_prop_buffer_format);
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_frame_resolution(struct video_client_ctx *client_ctx,
+					struct vdec_picsize *video_resoultion)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_size frame_resolution;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !video_resoultion)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size);
+	frame_resolution.width = video_resoultion->frame_width;
+	frame_resolution.height = video_resoultion->frame_height;
+	frame_resolution.stride = video_resoultion->stride;
+	frame_resolution.scan_lines = video_resoultion->scan_lines;
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &frame_resolution);
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_get_frame_resolution(struct video_client_ctx *client_ctx,
+					struct vdec_picsize *video_resoultion)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_size frame_resolution;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !video_resoultion)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size);
+
+	vcd_status = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+					  &frame_resolution);
+
+	video_resoultion->frame_width = frame_resolution.width;
+	video_resoultion->frame_height = frame_resolution.height;
+	video_resoultion->scan_lines = frame_resolution.scan_lines;
+	video_resoultion->stride = frame_resolution.stride;
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_get_progressive_only(struct video_client_ctx *client_ctx,
+					u32 *progressive_only)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	if (!client_ctx || !progressive_only)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_PROGRESSIVE_ONLY;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 progressive_only))
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_picture_order(struct video_client_ctx *client_ctx,
+					u32 *picture_order)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL, vcd_picture_order, ret = true;
+	if (!client_ctx || !picture_order)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_OUTPUT_ORDER;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (*picture_order == VDEC_ORDER_DISPLAY)
+		vcd_picture_order = VCD_DEC_ORDER_DISPLAY;
+	else if (*picture_order == VDEC_ORDER_DECODE)
+		vcd_picture_order = VCD_DEC_ORDER_DECODE;
+	else
+		ret = false;
+	if (ret) {
+		DBG("%s() : Setting output picture order: %d\n",
+		    __func__, vcd_picture_order);
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &vcd_picture_order);
+		if (vcd_status != VCD_S_SUCCESS)
+			ret = false;
+	}
+	return ret;
+}
+
+static u32 vid_dec_set_frame_rate(struct video_client_ctx *client_ctx,
+					struct vdec_framerate *frame_rate)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_rate vcd_frame_rate;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !frame_rate)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_RATE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_rate);
+	vcd_frame_rate.fps_numerator = frame_rate->fps_numerator;
+	vcd_frame_rate.fps_denominator = frame_rate->fps_denominator;
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &vcd_frame_rate);
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_extradata(struct video_client_ctx *client_ctx,
+					u32 *extradata_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);
+	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)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_idr_only_decoding(struct video_client_ctx *client_ctx)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 enable = true;
+	if (!client_ctx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_DEC_PICTYPE;
+	vcd_property_hdr.sz = sizeof(u32);
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &enable);
+	if (vcd_status)
+		return false;
+	return true;
+}
+
+static u32 vid_dec_set_h264_mv_buffers(struct video_client_ctx *client_ctx,
+					struct vdec_h264_mv *mv_data)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 len;
+	struct file *file;
+
+	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);
+
+	memset(&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;
+
+	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);
+
+	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);
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &vcd_h264_mv_buffer);
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_cont_on_reconfig(struct video_client_ctx *client_ctx)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 enable = true;
+	if (!client_ctx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_CONT_ON_RECONFIG;
+	vcd_property_hdr.sz = sizeof(u32);
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+		&vcd_property_hdr, &enable);
+	if (vcd_status)
+		return false;
+	return true;
+}
+
+static u32 vid_dec_get_h264_mv_buffer_size(struct video_client_ctx *client_ctx,
+					struct vdec_mv_buff_size *mv_buff)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_size h264_mv_buffer_size;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !mv_buff)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_GET_H264_MV_SIZE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
+
+	h264_mv_buffer_size.width = mv_buff->width;
+	h264_mv_buffer_size.height = mv_buff->height;
+
+	vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &h264_mv_buffer_size);
+
+	mv_buff->width = h264_mv_buffer_size.width;
+	mv_buff->height = h264_mv_buffer_size.height;
+	mv_buff->size = h264_mv_buffer_size.size;
+	mv_buff->alignment = h264_mv_buffer_size.alignment;
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_free_h264_mv_buffers(struct video_client_ctx *client_ctx)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_size h264_mv_buffer_size;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx)
+		return false;
+
+	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 (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
+				  struct vdec_allocatorproperty *vdec_buf_req)
+{
+	u32 vcd_status = VCD_ERR_FAIL;
+	struct vcd_buffer_requirement vcd_buf_req;
+
+	if (!client_ctx || !vdec_buf_req)
+		return false;
+
+	if (vdec_buf_req->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
+		vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+							 VCD_BUFFER_INPUT,
+							 &vcd_buf_req);
+	} else {
+		vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+							 VCD_BUFFER_OUTPUT,
+							 &vcd_buf_req);
+	}
+
+	if (vcd_status) {
+		return false;
+	} else {
+		vdec_buf_req->mincount = vcd_buf_req.min_count;
+		vdec_buf_req->maxcount = vcd_buf_req.max_count;
+		vdec_buf_req->actualcount = vcd_buf_req.actual_count;
+		vdec_buf_req->buffer_size = vcd_buf_req.sz;
+		vdec_buf_req->alignment = vcd_buf_req.align;
+		vdec_buf_req->buf_poolid = vcd_buf_req.buf_pool_id;
+
+		return true;
+	}
+}
+
+static u32 vid_dec_set_buffer(struct video_client_ctx *client_ctx,
+			      struct vdec_setbuffer_cmd *buffer_info)
+{
+	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;
+
+	if (!client_ctx || !buffer_info)
+		return false;
+
+	if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
+		dir_buffer = BUFFER_TYPE_OUTPUT;
+		buffer = VCD_BUFFER_OUTPUT;
+		buf_adr_offset = (unsigned long)buffer_info->buffer.offset;
+	}
+
+	/*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)) {
+		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);
+
+	if (!vcd_status)
+		return true;
+	else
+		return false;
+}
+
+
+static u32 vid_dec_free_buffer(struct video_client_ctx *client_ctx,
+			      struct vdec_setbuffer_cmd *buffer_info)
+{
+	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;
+
+	if (!client_ctx || !buffer_info)
+		return false;
+
+	if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
+		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,
+				&kernel_vaddr)) {
+		DBG("%s() : user_virt_addr = %p has not been set.",
+		    __func__, buffer_info->buffer.bufferaddr);
+		return true;
+	}
+
+	vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer,
+					 (u8 *)kernel_vaddr);
+
+	if (!vcd_status)
+		return true;
+	else
+		return false;
+}
+
+static u32 vid_dec_pause_resume(struct video_client_ctx *client_ctx, u32 pause)
+{
+  u32 vcd_status;
+
+	if (!client_ctx) {
+		ERR("\n %s(): Invalid client_ctx", __func__);
+		return false;
+	}
+
+	if (pause) {
+		INFO("msm_vidc_dec: PAUSE command from client = %p\n",
+			 client_ctx);
+		vcd_status = vcd_pause(client_ctx->vcd_handle);
+	} else{
+		INFO("msm_vidc_dec: RESUME command from client = %p\n",
+			 client_ctx);
+		vcd_status = vcd_resume(client_ctx->vcd_handle);
+	}
+
+	if (vcd_status)
+		return false;
+
+	return true;
+
+}
+
+static u32 vid_dec_start_stop(struct video_client_ctx *client_ctx, u32 start)
+{
+	struct vid_dec_msg *vdec_msg = NULL;
+	u32 vcd_status;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	if (!client_ctx) {
+		ERR("\n Invalid client_ctx");
+		return false;
+	}
+
+	if (start) {
+		if (client_ctx->seq_header_set) {
+			INFO("%s(): Seq Hdr set: Send START_DONE to client",
+				 __func__);
+			vdec_msg = kzalloc(sizeof(*vdec_msg), GFP_KERNEL);
+			if (!vdec_msg) {
+				ERR("vid_dec_start_stop: cannot allocate"
+				    "buffer\n");
+				return false;
+			}
+			vdec_msg->vdec_msg_info.msgcode =
+			    VDEC_MSG_RESP_START_DONE;
+			vdec_msg->vdec_msg_info.status_code = VDEC_S_SUCCESS;
+			vdec_msg->vdec_msg_info.msgdatasize = 0;
+			mutex_lock(&client_ctx->msg_queue_lock);
+			list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
+			mutex_unlock(&client_ctx->msg_queue_lock);
+
+			wake_up(&client_ctx->msg_wait);
+
+			DBG("Send START_DONE message to client = %p\n",
+			    client_ctx);
+
+		} else {
+			INFO("%s(): Calling decode_start()", __func__);
+			vcd_status =
+			    vcd_decode_start(client_ctx->vcd_handle, NULL);
+
+			if (vcd_status) {
+				ERR("%s(): vcd_decode_start failed."
+				    " vcd_status = %u\n", __func__, vcd_status);
+				return false;
+			}
+		}
+	} else {
+		INFO("%s(): Calling vcd_stop()", __func__);
+		mutex_lock(&vid_dec_device_p->lock);
+		vcd_status = VCD_ERR_FAIL;
+		if (!client_ctx->stop_called) {
+			client_ctx->stop_called = true;
+			vcd_status = vcd_stop(client_ctx->vcd_handle);
+		}
+		if (vcd_status) {
+			ERR("%s(): vcd_stop failed.  vcd_status = %u\n",
+				__func__, vcd_status);
+			mutex_unlock(&vid_dec_device_p->lock);
+			return false;
+		}
+		DBG("Send STOP_DONE message to client = %p\n", client_ctx);
+		mutex_unlock(&vid_dec_device_p->lock);
+	}
+	return true;
+}
+
+static u32 vid_dec_decode_frame(struct video_client_ctx *client_ctx,
+				struct vdec_input_frameinfo *input_frame_info)
+{
+	struct vcd_frame_data vcd_input_buffer;
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !input_frame_info)
+		return false;
+
+	user_vaddr = (unsigned long)input_frame_info->bufferaddr;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+				      true, &user_vaddr, &kernel_vaddr,
+				      &phy_addr, &pmem_fd, &file,
+				      &buffer_index)) {
+
+		/* kernel_vaddr  is found. send the frame to VCD */
+		memset((void *)&vcd_input_buffer, 0,
+		       sizeof(struct vcd_frame_data));
+		vcd_input_buffer.virtual =
+		    (u8 *) (kernel_vaddr + input_frame_info->pmem_offset);
+		vcd_input_buffer.offset = input_frame_info->offset;
+		vcd_input_buffer.frm_clnt_data =
+		    (u32) input_frame_info->client_data;
+		vcd_input_buffer.ip_frm_tag =
+		    (u32) input_frame_info->client_data;
+		vcd_input_buffer.data_len = input_frame_info->datalen;
+		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_status = vcd_decode_frame(client_ctx->vcd_handle,
+					      &vcd_input_buffer);
+		if (!vcd_status)
+			return true;
+		else {
+			ERR("%s(): vcd_decode_frame failed = %u\n", __func__,
+			    vcd_status);
+			return false;
+		}
+
+	} else {
+		ERR("%s(): kernel_vaddr not found\n", __func__);
+		return false;
+	}
+}
+
+static u32 vid_dec_fill_output_buffer(struct video_client_ctx *client_ctx,
+		struct vdec_fillbuffer_cmd *fill_buffer_cmd)
+{
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	struct vcd_frame_data vcd_frame;
+
+	if (!client_ctx || !fill_buffer_cmd)
+		return false;
+
+	user_vaddr = (unsigned long)fill_buffer_cmd->buffer.bufferaddr;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+				      true, &user_vaddr, &kernel_vaddr,
+				      &phy_addr, &pmem_fd, &file,
+				      &buffer_index)) {
+
+		memset((void *)&vcd_frame, 0,
+		       sizeof(struct vcd_frame_data));
+		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_status = vcd_fill_output_buffer(client_ctx->vcd_handle,
+						    &vcd_frame);
+		if (!vcd_status)
+			return true;
+		else {
+			ERR("%s(): vcd_fill_output_buffer failed = %u\n",
+			    __func__, vcd_status);
+			return false;
+		}
+	} else {
+		ERR("%s(): kernel_vaddr not found\n", __func__);
+		return false;
+	}
+}
+
+
+static u32 vid_dec_flush(struct video_client_ctx *client_ctx,
+			 enum vdec_bufferflush flush_dir)
+{
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	INFO("msm_vidc_dec: %s() called with dir = %u", __func__,
+		 flush_dir);
+	if (!client_ctx) {
+		ERR("\n Invalid client_ctx");
+		return false;
+	}
+
+	switch (flush_dir) {
+	case VDEC_FLUSH_TYPE_INPUT:
+		vcd_status = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_INPUT);
+		break;
+	case VDEC_FLUSH_TYPE_OUTPUT:
+		vcd_status = vcd_flush(client_ctx->vcd_handle,
+				       VCD_FLUSH_OUTPUT);
+		break;
+	case VDEC_FLUSH_TYPE_ALL:
+		vcd_status = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_ALL);
+		break;
+	default:
+		ERR("%s(): Inavlid flush cmd. flush_dir = %u\n", __func__,
+		    flush_dir);
+		return false;
+		break;
+	}
+
+	if (!vcd_status)
+		return true;
+	else {
+		ERR("%s(): vcd_flush failed. vcd_status = %u "
+		    " flush_dir = %u\n", __func__, vcd_status, flush_dir);
+		return false;
+	}
+}
+
+static u32 vid_dec_msg_pending(struct video_client_ctx *client_ctx)
+{
+	u32 islist_empty = 0;
+	mutex_lock(&client_ctx->msg_queue_lock);
+	islist_empty = list_empty(&client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+
+	if (islist_empty) {
+		DBG("%s(): vid_dec msg queue empty\n", __func__);
+		if (client_ctx->stop_msg) {
+			DBG("%s(): List empty and Stop Msg set\n",
+				__func__);
+			return client_ctx->stop_msg;
+		}
+	} else
+		DBG("%s(): vid_dec msg queue Not empty\n", __func__);
+
+	return !islist_empty;
+}
+
+static int vid_dec_get_next_msg(struct video_client_ctx *client_ctx,
+				struct vdec_msginfo *vdec_msg_info)
+{
+	int rc;
+	struct vid_dec_msg *vid_dec_msg = NULL;
+
+	if (!client_ctx)
+		return false;
+
+	rc = wait_event_interruptible(client_ctx->msg_wait,
+				      vid_dec_msg_pending(client_ctx));
+	if (rc < 0) {
+		DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg);
+		return rc;
+	} else if (client_ctx->stop_msg) {
+		DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg);
+		return -EIO;
+	}
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+	if (!list_empty(&client_ctx->msg_queue)) {
+		DBG("%s(): After Wait\n", __func__);
+		vid_dec_msg = list_first_entry(&client_ctx->msg_queue,
+					       struct vid_dec_msg, list);
+		list_del(&vid_dec_msg->list);
+		memcpy(vdec_msg_info, &vid_dec_msg->vdec_msg_info,
+		       sizeof(struct vdec_msginfo));
+		kfree(vid_dec_msg);
+	}
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	return 0;
+}
+
+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;
+	struct file *pmem_file;
+	u32 result = true;
+	void __user *arg = (void __user *)u_arg;
+
+	DBG("%s\n", __func__);
+	if (_IOC_TYPE(cmd) != VDEC_IOCTL_MAGIC)
+		return -ENOTTY;
+
+	client_ctx = (struct video_client_ctx *)file->private_data;
+	if (!client_ctx) {
+		ERR("!client_ctx. Cannot attach to device handle\n");
+		return -ENODEV;
+	}
+
+	switch (cmd) {
+	case VDEC_IOCTL_SET_CODEC:
+	{
+		enum vdec_codec vdec_codec;
+		DBG("VDEC_IOCTL_SET_CODEC\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&vdec_codec,	vdec_msg.in,
+						   sizeof(vdec_codec)))
+			return -EFAULT;
+		DBG("setting code type = %u\n", vdec_codec);
+		result = vid_dec_set_codec(client_ctx, &vdec_codec);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_OUTPUT_FORMAT:
+	{
+		enum vdec_output_fromat output_format;
+		DBG("VDEC_IOCTL_SET_OUTPUT_FORMAT\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&output_format, vdec_msg.in,
+						   sizeof(output_format)))
+			return -EFAULT;
+
+		result = vid_dec_set_output_format(client_ctx, &output_format);
+
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_PICRES:
+	{
+		struct vdec_picsize video_resoultion;
+		DBG("VDEC_IOCTL_SET_PICRES\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&video_resoultion, vdec_msg.in,
+						   sizeof(video_resoultion)))
+			return -EFAULT;
+		result =
+		vid_dec_set_frame_resolution(client_ctx, &video_resoultion);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_GET_PICRES:
+	{
+		struct vdec_picsize video_resoultion;
+		DBG("VDEC_IOCTL_GET_PICRES\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&video_resoultion, vdec_msg.out,
+						   sizeof(video_resoultion)))
+			return -EFAULT;
+
+		result = vid_dec_get_frame_resolution(client_ctx,
+					&video_resoultion);
+
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &video_resoultion,
+					sizeof(video_resoultion)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_BUFFER_REQ:
+	{
+		struct vdec_allocatorproperty vdec_buf_req;
+		struct vcd_buffer_requirement buffer_req;
+		DBG("VDEC_IOCTL_SET_BUFFER_REQ\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+
+		if (copy_from_user(&vdec_buf_req, vdec_msg.in,
+				   sizeof(vdec_buf_req)))
+			return -EFAULT;
+
+		buffer_req.actual_count = vdec_buf_req.actualcount;
+		buffer_req.align = vdec_buf_req.alignment;
+		buffer_req.max_count = vdec_buf_req.maxcount;
+		buffer_req.min_count = vdec_buf_req.mincount;
+		buffer_req.sz = vdec_buf_req.buffer_size;
+
+		switch (vdec_buf_req.buffer_type) {
+		case VDEC_BUFFER_TYPE_INPUT:
+			vcd_status =
+			vcd_set_buffer_requirements(client_ctx->vcd_handle,
+				VCD_BUFFER_INPUT, &buffer_req);
+			break;
+		case VDEC_BUFFER_TYPE_OUTPUT:
+			vcd_status =
+			vcd_set_buffer_requirements(client_ctx->vcd_handle,
+				VCD_BUFFER_OUTPUT, &buffer_req);
+			break;
+		default:
+			vcd_status = VCD_ERR_BAD_POINTER;
+			break;
+		}
+
+		if (vcd_status)
+			return -EFAULT;
+		break;
+	}
+	case VDEC_IOCTL_GET_BUFFER_REQ:
+	{
+		struct vdec_allocatorproperty vdec_buf_req;
+		DBG("VDEC_IOCTL_GET_BUFFER_REQ\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&vdec_buf_req, vdec_msg.out,
+				   sizeof(vdec_buf_req)))
+			return -EFAULT;
+
+		result = vid_dec_get_buffer_req(client_ctx, &vdec_buf_req);
+
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &vdec_buf_req,
+					sizeof(vdec_buf_req)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_BUFFER:
+	{
+		struct vdec_setbuffer_cmd setbuffer;
+		DBG("VDEC_IOCTL_SET_BUFFER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&setbuffer, vdec_msg.in,
+				sizeof(setbuffer)))
+			return -EFAULT;
+		result = vid_dec_set_buffer(client_ctx, &setbuffer);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_FREE_BUFFER:
+	{
+		struct vdec_setbuffer_cmd setbuffer;
+		DBG("VDEC_IOCTL_FREE_BUFFER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&setbuffer, vdec_msg.in,
+				sizeof(setbuffer)))
+			return -EFAULT;
+		result = vid_dec_free_buffer(client_ctx, &setbuffer);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_START:
+	{
+		DBG(" VDEC_IOCTL_CMD_START\n");
+		result = vid_dec_start_stop(client_ctx, true);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_STOP:
+	{
+		DBG("VDEC_IOCTL_CMD_STOP\n");
+		result = vid_dec_start_stop(client_ctx, false);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_PAUSE:
+	{
+		result = vid_dec_pause_resume(client_ctx, true);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_RESUME:
+	{
+		DBG("VDEC_IOCTL_CMD_PAUSE\n");
+		result = vid_dec_pause_resume(client_ctx, false);
+
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_DECODE_FRAME:
+	{
+		struct vdec_input_frameinfo input_frame_info;
+		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;
+
+		result = vid_dec_decode_frame(client_ctx, &input_frame_info);
+
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_FILL_OUTPUT_BUFFER:
+	{
+		struct vdec_fillbuffer_cmd fill_buffer_cmd;
+		DBG("VDEC_IOCTL_FILL_OUTPUT_BUFFER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&fill_buffer_cmd, vdec_msg.in,
+				   sizeof(fill_buffer_cmd)))
+			return -EFAULT;
+		result = vid_dec_fill_output_buffer(client_ctx,
+							&fill_buffer_cmd);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_FLUSH:
+	{
+		enum vdec_bufferflush flush_dir;
+		DBG("VDEC_IOCTL_CMD_FLUSH\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&flush_dir, vdec_msg.in,
+				   sizeof(flush_dir)))
+			return -EFAULT;
+		result = vid_dec_flush(client_ctx, flush_dir);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_GET_NEXT_MSG:
+	{
+		struct vdec_msginfo vdec_msg_info;
+		DBG("VDEC_IOCTL_GET_NEXT_MSG\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_next_msg(client_ctx, &vdec_msg_info);
+		if (result)
+			return result;
+		if (copy_to_user(vdec_msg.out, &vdec_msg_info,
+					sizeof(vdec_msg_info)))
+			return -EFAULT;
+		break;
+	}
+	case VDEC_IOCTL_STOP_NEXT_MSG:
+	{
+		DBG("VDEC_IOCTL_STOP_NEXT_MSG\n");
+		client_ctx->stop_msg = 1;
+		wake_up(&client_ctx->msg_wait);
+		break;
+	}
+	case VDEC_IOCTL_SET_SEQUENCE_HEADER:
+	{
+		struct vdec_seqheader seq_header;
+		struct vcd_sequence_hdr vcd_seq_hdr;
+		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");
+			return -EFAULT;
+		}
+		if (copy_from_user(&seq_header,	vdec_msg.in,
+				   sizeof(seq_header))) {
+			ERR("Copy from user seq_header failed\n");
+			return -EFAULT;
+		}
+		if (!seq_header.seq_header_len) {
+			ERR("Seq Len is Zero\n");
+			return -EFAULT;
+		}
+
+		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;
+		}
+		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;
+		if (!vcd_seq_hdr.sequence_header) {
+			ERR("Sequence Header pointer failed\n");
+			return -EFAULT;
+		}
+		client_ctx->seq_header_set = true;
+		if (vcd_decode_start(client_ctx->vcd_handle, &vcd_seq_hdr)) {
+			ERR("Decode start Failed\n");
+			client_ctx->seq_header_set = false;
+			return -EFAULT;
+		}
+		DBG("Wait Client completion Sequence Header\n");
+		wait_for_completion(&client_ctx->event);
+		vcd_seq_hdr.sequence_header = NULL;
+		if (client_ctx->event_status) {
+			ERR("Set Seq Header status is failed");
+			return -EFAULT;
+		}
+		break;
+	}
+	case VDEC_IOCTL_GET_NUMBER_INSTANCES:
+	{
+		DBG("VDEC_IOCTL_GET_NUMBER_INSTANCES\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_to_user(vdec_msg.out,
+			&vid_dec_device_p->num_clients, sizeof(u32)))
+			return -EFAULT;
+		break;
+	}
+	case VDEC_IOCTL_GET_INTERLACE_FORMAT:
+	{
+		u32 progressive_only, interlace_format;
+		DBG("VDEC_IOCTL_GET_INTERLACE_FORMAT\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_progressive_only(client_ctx,
+					&progressive_only);
+		if (result) {
+			interlace_format = progressive_only ?
+				VDEC_InterlaceFrameProgressive :
+				VDEC_InterlaceInterleaveFrameTopFieldFirst;
+			if (copy_to_user(vdec_msg.out, &interlace_format,
+					sizeof(u32)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_PICTURE_ORDER:
+	{
+		u32 picture_order;
+		DBG("VDEC_IOCTL_SET_PICTURE_ORDER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&picture_order, vdec_msg.in,
+						   sizeof(u32)))
+			return -EFAULT;
+		result =  vid_dec_set_picture_order(client_ctx, &picture_order);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_FRAME_RATE:
+	{
+		struct vdec_framerate frame_rate;
+		DBG("VDEC_IOCTL_SET_FRAME_RATE\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&frame_rate, vdec_msg.in,
+						   sizeof(frame_rate)))
+			return -EFAULT;
+		result = vid_dec_set_frame_rate(client_ctx, &frame_rate);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_EXTRADATA:
+	{
+		u32 extradata_flag;
+		DBG("VDEC_IOCTL_SET_EXTRADATA\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&extradata_flag, vdec_msg.in,
+						   sizeof(u32)))
+			return -EFAULT;
+		result = vid_dec_set_extradata(client_ctx, &extradata_flag);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_H264_MV_BUFFER:
+	{
+		struct vdec_h264_mv mv_data;
+		DBG("VDEC_IOCTL_SET_H264_MV_BUFFER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&mv_data, vdec_msg.in,
+						   sizeof(mv_data)))
+			return -EFAULT;
+		result = vid_dec_set_h264_mv_buffers(client_ctx, &mv_data);
+
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_FREE_H264_MV_BUFFER:
+	{
+		DBG("VDEC_IOCTL_FREE_H264_MV_BUFFER\n");
+		result = vid_dec_free_h264_mv_buffers(client_ctx);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_GET_MV_BUFFER_SIZE:
+	{
+		struct vdec_mv_buff_size mv_buff;
+		DBG("VDEC_IOCTL_GET_MV_BUFFER_SIZE\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&mv_buff, vdec_msg.out,
+						   sizeof(mv_buff)))
+			return -EFAULT;
+		result = vid_dec_get_h264_mv_buffer_size(client_ctx, &mv_buff);
+		if (result) {
+			DBG(" Returning W: %d, H: %d, S: %d, A: %d",
+				mv_buff.width, mv_buff.height,
+				mv_buff.size, mv_buff.alignment);
+			if (copy_to_user(vdec_msg.out, &mv_buff,
+					sizeof(mv_buff)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_IDR_ONLY_DECODING:
+	{
+		result = vid_dec_set_idr_only_decoding(client_ctx);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_CONT_ON_RECONFIG:
+	{
+		result = vid_dec_set_cont_on_reconfig(client_ctx);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	default:
+		ERR("%s(): Unsupported ioctl\n", __func__);
+		return -ENOTTY;
+		break;
+	}
+
+	return 0;
+}
+
+static u32 vid_dec_close_client(struct video_client_ctx *client_ctx)
+{
+	struct vid_dec_msg *vdec_msg;
+	u32 vcd_status;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	if (!client_ctx || (!client_ctx->vcd_handle)) {
+		ERR("\n Invalid client_ctx");
+		return false;
+	}
+
+	mutex_lock(&vid_dec_device_p->lock);
+	if (!client_ctx->stop_called) {
+		client_ctx->stop_called = true;
+		client_ctx->stop_sync_cb = true;
+		vcd_status = vcd_stop(client_ctx->vcd_handle);
+		DBG("\n Stuck at the stop call");
+		if (!vcd_status)
+			wait_for_completion(&client_ctx->event);
+		DBG("\n Came out of wait event");
+	}
+	mutex_lock(&client_ctx->msg_queue_lock);
+	while (!list_empty(&client_ctx->msg_queue)) {
+		DBG("%s(): Delete remaining entries\n", __func__);
+		vdec_msg = list_first_entry(&client_ctx->msg_queue,
+						   struct vid_dec_msg, list);
+		if (vdec_msg) {
+			list_del(&vdec_msg->list);
+			kfree(vdec_msg);
+		}
+	}
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	vcd_status = vcd_close(client_ctx->vcd_handle);
+
+	if (vcd_status) {
+		mutex_unlock(&vid_dec_device_p->lock);
+		return false;
+	}
+	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)
+{
+	s32 client_index;
+	struct video_client_ctx *client_ctx;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u8 client_count = 0;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	mutex_lock(&vid_dec_device_p->lock);
+
+	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;
+	}
+
+	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;
+	}
+
+	client_index = vid_dec_get_empty_client_index();
+	if (client_index == -1) {
+		ERR("%s() : No free clients client_index == -1\n", __func__);
+		return -ENODEV;
+	}
+	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);
+	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) {
+		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;
+		}
+	} else {
+		ERR("vcd_open returned error: %u", vcd_status);
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -EFAULT;
+	}
+
+	client_ctx->seq_header_set = false;
+	file->private_data = client_ctx;
+	mutex_unlock(&vid_dec_device_p->lock);
+	return 0;
+}
+
+static int vid_dec_release(struct inode *inode, struct file *file)
+{
+	struct video_client_ctx *client_ctx = file->private_data;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	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;
+}
+
+static const struct file_operations vid_dec_fops = {
+	.owner = THIS_MODULE,
+	.open = vid_dec_open,
+	.release = vid_dec_release,
+	.unlocked_ioctl = vid_dec_ioctl,
+};
+
+void vid_dec_interrupt_deregister(void)
+{
+}
+
+void vid_dec_interrupt_register(void *device_name)
+{
+}
+
+void vid_dec_interrupt_clear(void)
+{
+}
+
+void *vid_dec_map_dev_base_addr(void *device_name)
+{
+	return vid_dec_device_p->virt_base;
+}
+
+static int vid_dec_vcd_init(void)
+{
+	int rc;
+	struct vcd_init_config vcd_init_config;
+	u32 i;
+
+	/* init_timer(&hw_timer); */
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	vid_dec_device_p->num_clients = 0;
+
+	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+		memset((void *)&vid_dec_device_p->vdec_clients[i], 0,
+		       sizeof(vid_dec_device_p->vdec_clients[i]));
+	}
+
+	mutex_init(&vid_dec_device_p->lock);
+	vid_dec_device_p->virt_base = vidc_get_ioaddr();
+	DBG("%s() : base address for VIDC core %u\n", __func__, \
+		(int)vid_dec_device_p->virt_base);
+
+	if (!vid_dec_device_p->virt_base) {
+		ERR("%s() : ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	vcd_init_config.device_name = "VIDC";
+	vcd_init_config.map_dev_base_addr = vid_dec_map_dev_base_addr;
+	vcd_init_config.interrupt_clr = vid_dec_interrupt_clear;
+	vcd_init_config.register_isr = vid_dec_interrupt_register;
+	vcd_init_config.deregister_isr = vid_dec_interrupt_deregister;
+	vcd_init_config.timer_create = vidc_timer_create;
+	vcd_init_config.timer_release = vidc_timer_release;
+	vcd_init_config.timer_start = vidc_timer_start;
+	vcd_init_config.timer_stop = vidc_timer_stop;
+
+	rc = vcd_init(&vcd_init_config, &vid_dec_device_p->device_handle);
+
+	if (rc) {
+		ERR("%s() : vcd_init failed\n", __func__);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int __init vid_dec_init(void)
+{
+	int rc = 0;
+	struct device *class_devp;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	vid_dec_device_p = kzalloc(sizeof(struct vid_dec_dev), GFP_KERNEL);
+	if (!vid_dec_device_p) {
+		ERR("%s Unable to allocate memory for vid_dec_dev\n",
+		       __func__);
+		return -ENOMEM;
+	}
+
+	rc = alloc_chrdev_region(&vid_dec_dev_num, 0, 1, VID_DEC_NAME);
+	if (rc < 0) {
+		ERR("%s: alloc_chrdev_region Failed rc = %d\n",
+		       __func__, rc);
+		goto error_vid_dec_alloc_chrdev_region;
+	}
+
+	vid_dec_class = class_create(THIS_MODULE, VID_DEC_NAME);
+	if (IS_ERR(vid_dec_class)) {
+		rc = PTR_ERR(vid_dec_class);
+		ERR("%s: couldn't create vid_dec_class rc = %d\n",
+		       __func__, rc);
+
+		goto error_vid_dec_class_create;
+	}
+
+	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);
+		goto error_vid_dec_class_device_create;
+	}
+
+  vid_dec_device_p->device = class_devp;
+
+	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;
+	}
+	vid_dec_vcd_init();
+	return 0;
+
+error_vid_dec_cdev_add:
+	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);
+error_vid_dec_alloc_chrdev_region:
+	kfree(vid_dec_device_p);
+
+	return rc;
+}
+
+static void __exit vid_dec_exit(void)
+{
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	cdev_del(&(vid_dec_device_p->cdev));
+	device_destroy(vid_dec_class, vid_dec_dev_num);
+	class_destroy(vid_dec_class);
+	unregister_chrdev_region(vid_dec_dev_num, 1);
+	kfree(vid_dec_device_p);
+	INFO("msm_vidc_dec: Return from %s()", __func__);
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Video decoder driver");
+MODULE_VERSION("1.0");
+
+module_init(vid_dec_init);
+module_exit(vid_dec_exit);
diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h
new file mode 100644
index 0000000..867c3b3
--- /dev/null
+++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h
@@ -0,0 +1,43 @@
+/* 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 VDEC_INTERNAL_H
+#define VDEC_INTERNAL_H
+
+#include <linux/msm_vidc_dec.h>
+#include <linux/cdev.h>
+#include "vidc_init.h"
+
+struct vid_dec_msg {
+	struct list_head list;
+	struct vdec_msginfo vdec_msg_info;
+};
+
+struct vid_dec_dev {
+	struct cdev cdev;
+	struct device *device;
+	resource_size_t phys_base;
+	void __iomem *virt_base;
+	unsigned int irq;
+	struct clk *hclk;
+	struct clk *hclk_div2;
+	struct clk *pclk;
+	unsigned long hclk_rate;
+	struct mutex lock;
+	s32 device_handle;
+	struct video_client_ctx vdec_clients[VIDC_MAX_NUM_CLIENTS];
+	u32 num_clients;
+	void(*timer_handler)(void *);
+};
+
+#endif
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
new file mode 100644
index 0000000..a69b810
--- /dev/null
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -0,0 +1,1549 @@
+/* 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/cdev.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/android_pmem.h>
+#include <linux/clk.h>
+
+#include "vidc_type.h"
+#include "vcd_api.h"
+#include "venc_internal.h"
+#include "vidc_init.h"
+
+#define VID_ENC_NAME	"msm_vidc_enc"
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+#define INFO(x...) printk(KERN_INFO x)
+#define ERR(x...) printk(KERN_ERR x)
+
+static struct vid_enc_dev *vid_enc_device_p;
+static dev_t vid_enc_dev_num;
+static struct class *vid_enc_class;
+static long vid_enc_ioctl(struct file *file,
+	unsigned cmd, unsigned long arg);
+static int stop_cmd;
+
+static s32 vid_enc_get_empty_client_index(void)
+{
+	u32 i;
+	u32 found = false;
+
+	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+		if (!vid_enc_device_p->venc_clients[i].vcd_handle) {
+			found = true;
+			break;
+		}
+	}
+	if (!found) {
+		ERR("%s():ERROR No space for new client\n",
+			__func__);
+		return -ENOMEM;
+	} else {
+		DBG("%s(): available client index = %u\n",
+			__func__, i);
+		return i;
+	}
+}
+
+
+u32 vid_enc_get_status(u32 status)
+{
+	u32 venc_status;
+
+	switch (status) {
+	case VCD_S_SUCCESS:
+		venc_status = VEN_S_SUCCESS;
+		break;
+	case VCD_ERR_FAIL:
+		venc_status = VEN_S_EFAIL;
+		break;
+	case VCD_ERR_ALLOC_FAIL:
+		venc_status = VEN_S_ENOSWRES;
+		break;
+	case VCD_ERR_ILLEGAL_OP:
+		venc_status = VEN_S_EINVALCMD;
+		break;
+	case VCD_ERR_ILLEGAL_PARM:
+		venc_status = VEN_S_EBADPARAM;
+		break;
+	case VCD_ERR_BAD_POINTER:
+	case VCD_ERR_BAD_HANDLE:
+		venc_status = VEN_S_EFATAL;
+		break;
+	case VCD_ERR_NOT_SUPPORTED:
+		venc_status = VEN_S_ENOTSUPP;
+		break;
+	case VCD_ERR_BAD_STATE:
+		venc_status = VEN_S_EINVALSTATE;
+		break;
+	case VCD_ERR_MAX_CLIENT:
+		venc_status = VEN_S_ENOHWRES;
+		break;
+	default:
+		venc_status = VEN_S_EFAIL;
+		break;
+	}
+	return venc_status;
+}
+
+static void vid_enc_notify_client(struct video_client_ctx *client_ctx)
+{
+	if (client_ctx)
+		complete(&client_ctx->event);
+}
+
+void vid_enc_vcd_open_done(struct video_client_ctx *client_ctx,
+	struct vcd_handle_container *handle_container)
+{
+	DBG("vid_enc_vcd_open_done\n");
+
+	if (client_ctx) {
+		if (handle_container)
+			client_ctx->vcd_handle = handle_container->handle;
+		else
+		ERR("%s(): ERROR. handle_container is NULL\n",
+		__func__);
+		vid_enc_notify_client(client_ctx);
+	} else
+		ERR("%s(): ERROR. client_ctx is NULL\n",
+			__func__);
+}
+
+static void vid_enc_input_frame_done(struct video_client_ctx *client_ctx,
+		u32 event, u32 status,
+		struct vcd_frame_data *vcd_frame_data)
+{
+	struct vid_enc_msg *venc_msg;
+
+	if (!client_ctx || !vcd_frame_data) {
+		ERR("vid_enc_input_frame_done() NULL pointer\n");
+		return;
+	}
+
+	venc_msg = kzalloc(sizeof(struct vid_enc_msg),
+					    GFP_KERNEL);
+	if (!venc_msg) {
+		ERR("vid_enc_input_frame_done(): cannot allocate vid_enc_msg "
+		" buffer\n");
+		return;
+	}
+
+	venc_msg->venc_msg_info.statuscode = vid_enc_get_status(status);
+
+	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);
+	   break;
+	case VCD_EVT_RESP_INPUT_FLUSHED:
+		DBG("Send INPUT_FLUSHED message to client = %p\n",
+			client_ctx);
+	   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 =
+		(void *)vcd_frame_data->frm_clnt_data;
+	venc_msg->venc_msg_info.msgdata_size =
+		sizeof(struct vid_enc_msg);
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&venc_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+static void vid_enc_output_frame_done(struct video_client_ctx *client_ctx,
+		u32 event, u32 status,
+		struct vcd_frame_data *vcd_frame_data)
+{
+	struct vid_enc_msg *venc_msg;
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+
+	if (!client_ctx || !vcd_frame_data) {
+		ERR("vid_enc_input_frame_done() NULL pointer\n");
+		return;
+	}
+
+	venc_msg = kzalloc(sizeof(struct vid_enc_msg),
+					   GFP_KERNEL);
+	if (!venc_msg) {
+		ERR("vid_enc_input_frame_done(): cannot allocate vid_enc_msg "
+		" buffer\n");
+		return;
+	}
+
+	venc_msg->venc_msg_info.statuscode = vid_enc_get_status(status);
+	venc_msg->venc_msg_info.msgcode = VEN_MSG_OUTPUT_BUFFER_DONE;
+
+	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 =
+		(unsigned long)vcd_frame_data->virtual;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+		false, &user_vaddr, &kernel_vaddr,
+		&phy_addr, &pmem_fd, &file,
+		&buffer_index)) {
+
+		/* Buffer address in user space */
+		venc_msg->venc_msg_info.buf.ptrbuffer =	(u8 *) user_vaddr;
+		/* Buffer address in user space */
+		venc_msg->venc_msg_info.buf.clientdata = (void *)
+		vcd_frame_data->frm_clnt_data;
+		/* Data length */
+		venc_msg->venc_msg_info.buf.len =
+			vcd_frame_data->data_len;
+		venc_msg->venc_msg_info.buf.flags =
+			vcd_frame_data->flags;
+		/* Timestamp pass-through from input frame */
+		venc_msg->venc_msg_info.buf.timestamp =
+			vcd_frame_data->time_stamp;
+
+		/* Decoded picture width and height */
+		venc_msg->venc_msg_info.msgdata_size =
+			sizeof(struct venc_buffer);
+	} else {
+		ERR("vid_enc_output_frame_done UVA can not be found\n");
+		venc_msg->venc_msg_info.statuscode =
+			VEN_S_EFATAL;
+	}
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&venc_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+static void vid_enc_lean_event(struct video_client_ctx *client_ctx,
+	u32 event, u32 status)
+{
+	struct vid_enc_msg *venc_msg;
+	if (!client_ctx) {
+		ERR("%s(): !client_ctx pointer\n",
+			__func__);
+		return;
+	}
+
+	venc_msg = kzalloc(sizeof(struct vid_enc_msg),
+			GFP_KERNEL);
+	if (!venc_msg) {
+		ERR("%s(): cannot allocate vid_enc_msg buffer\n",
+			__func__);
+		return;
+	}
+
+	venc_msg->venc_msg_info.statuscode =
+		vid_enc_get_status(status);
+
+	switch (event) {
+	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
+		INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_FLUSH_INPUT_DONE"
+			 " to client");
+		venc_msg->venc_msg_info.msgcode =
+			VEN_MSG_FLUSH_INPUT_DONE;
+		break;
+	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
+		INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_FLUSH_OUTPUT_DONE"
+			 " to client");
+		venc_msg->venc_msg_info.msgcode =
+			VEN_MSG_FLUSH_OUPUT_DONE;
+		break;
+
+	case VCD_EVT_RESP_START:
+		INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_START"
+			 " to client");
+		venc_msg->venc_msg_info.msgcode =
+			VEN_MSG_START;
+		break;
+
+	case VCD_EVT_RESP_STOP:
+		INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_STOP"
+			 " to client");
+		venc_msg->venc_msg_info.msgcode =
+			VEN_MSG_STOP;
+		break;
+
+	case VCD_EVT_RESP_PAUSE:
+		INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_PAUSE"
+			 " to client");
+		venc_msg->venc_msg_info.msgcode =
+			VEN_MSG_PAUSE;
+		break;
+
+	default:
+		ERR("%s() : unknown event type %u\n",
+			__func__, event);
+		break;
+	}
+
+	venc_msg->venc_msg_info.msgdata_size = 0;
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+	list_add_tail(&venc_msg->list, &client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	wake_up(&client_ctx->msg_wait);
+}
+
+
+void vid_enc_vcd_cb(u32 event, u32 status,
+	void *info, size_t sz, void *handle,
+	void *const client_data)
+{
+	struct video_client_ctx *client_ctx =
+		(struct video_client_ctx *)client_data;
+
+	DBG("Entering %s()\n", __func__);
+
+	if (!client_ctx) {
+		ERR("%s(): client_ctx is NULL\n", __func__);
+		return;
+	}
+
+	client_ctx->event_status = status;
+
+	switch (event) {
+	case VCD_EVT_RESP_OPEN:
+		vid_enc_vcd_open_done(client_ctx,
+		(struct vcd_handle_container *)info);
+		break;
+
+	case VCD_EVT_RESP_INPUT_DONE:
+	case VCD_EVT_RESP_INPUT_FLUSHED:
+		vid_enc_input_frame_done(client_ctx, event,
+		status, (struct vcd_frame_data *)info);
+		break;
+
+	case VCD_EVT_RESP_OUTPUT_DONE:
+	case VCD_EVT_RESP_OUTPUT_FLUSHED:
+		vid_enc_output_frame_done(client_ctx, event, status,
+		(struct vcd_frame_data *)info);
+		break;
+
+	case VCD_EVT_RESP_PAUSE:
+	case VCD_EVT_RESP_START:
+	case VCD_EVT_RESP_STOP:
+	case VCD_EVT_RESP_FLUSH_INPUT_DONE:
+	case VCD_EVT_RESP_FLUSH_OUTPUT_DONE:
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+	case VCD_EVT_IND_HWERRFATAL:
+	case VCD_EVT_IND_RESOURCES_LOST:
+		vid_enc_lean_event(client_ctx, event, status);
+		break;
+
+	default:
+		ERR("%s() :  Error - Invalid event type =%u\n",
+		__func__, event);
+		break;
+	}
+}
+
+static u32 vid_enc_msg_pending(struct video_client_ctx *client_ctx)
+{
+	u32 islist_empty = 0;
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+	islist_empty = list_empty(&client_ctx->msg_queue);
+	mutex_unlock(&client_ctx->msg_queue_lock);
+
+	if (islist_empty) {
+		DBG("%s(): vid_enc msg queue empty\n",
+			__func__);
+		if (client_ctx->stop_msg) {
+			DBG("%s(): List empty and Stop Msg set\n",
+				__func__);
+			return client_ctx->stop_msg;
+		}
+	} else
+		DBG("%s(): vid_enc msg queue Not empty\n",
+			__func__);
+
+	return !islist_empty;
+}
+
+static u32 vid_enc_get_next_msg(struct video_client_ctx *client_ctx,
+		struct venc_msg *venc_msg_info)
+{
+	int rc;
+	struct vid_enc_msg *vid_enc_msg = NULL;
+
+	if (!client_ctx)
+		return false;
+
+	rc = wait_event_interruptible(client_ctx->msg_wait,
+		vid_enc_msg_pending(client_ctx));
+
+	if (rc < 0 || client_ctx->stop_msg) {
+		DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg);
+		return false;
+	}
+
+	mutex_lock(&client_ctx->msg_queue_lock);
+
+	if (!list_empty(&client_ctx->msg_queue)) {
+		DBG("%s(): After Wait\n", __func__);
+		vid_enc_msg = list_first_entry(&client_ctx->msg_queue,
+					struct vid_enc_msg, list);
+		list_del(&vid_enc_msg->list);
+		memcpy(venc_msg_info, &vid_enc_msg->venc_msg_info,
+		sizeof(struct venc_msg));
+		kfree(vid_enc_msg);
+	}
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	return true;
+}
+
+static u32 vid_enc_close_client(struct video_client_ctx *client_ctx)
+{
+	struct vid_enc_msg *vid_enc_msg = NULL;
+	u32 vcd_status;
+	int rc;
+
+	INFO("\n msm_vidc_enc: Inside %s()", __func__);
+	if (!client_ctx || (!client_ctx->vcd_handle)) {
+		ERR("\n %s(): Invalid client_ctx", __func__);
+		return false;
+	}
+
+	mutex_lock(&vid_enc_device_p->lock);
+
+	if (!stop_cmd) {
+		vcd_status = vcd_stop(client_ctx->vcd_handle);
+		DBG("Waiting for VCD_STOP: Before Timeout\n");
+		if (!vcd_status) {
+			rc = wait_for_completion_timeout(&client_ctx->event,
+				5 * HZ);
+			if (!rc) {
+				ERR("%s:ERROR vcd_stop time out"
+				"rc = %d\n", __func__, rc);
+			}
+
+			if (client_ctx->event_status) {
+				ERR("%s:ERROR "
+				"vcd_stop Not successs\n", __func__);
+			}
+		}
+	}
+	DBG("VCD_STOPPED: After Timeout, calling VCD_CLOSE\n");
+	mutex_lock(&client_ctx->msg_queue_lock);
+	while (!list_empty(&client_ctx->msg_queue)) {
+		DBG("%s(): Delete remaining entries\n", __func__);
+		vid_enc_msg = list_first_entry(&client_ctx->msg_queue,
+					struct vid_enc_msg, list);
+		list_del(&vid_enc_msg->list);
+		kfree(vid_enc_msg);
+	}
+	mutex_unlock(&client_ctx->msg_queue_lock);
+	vcd_status = vcd_close(client_ctx->vcd_handle);
+
+	if (vcd_status) {
+		mutex_unlock(&vid_enc_device_p->lock);
+		return false;
+	}
+
+	memset((void *)client_ctx, 0,
+		sizeof(struct video_client_ctx));
+
+	vid_enc_device_p->num_clients--;
+	stop_cmd = 0;
+	mutex_unlock(&vid_enc_device_p->lock);
+	return true;
+}
+
+
+static int vid_enc_open(struct inode *inode, struct file *file)
+{
+	s32 client_index;
+	struct video_client_ctx *client_ctx;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u8 client_count = 0;
+
+	INFO("\n msm_vidc_enc: Inside %s()", __func__);
+
+	mutex_lock(&vid_enc_device_p->lock);
+
+	stop_cmd = 0;
+	client_count = vcd_get_num_of_clients();
+	if (client_count == VIDC_MAX_NUM_CLIENTS) {
+		ERR("ERROR : vid_enc_open() max number of clients"
+		    "limit reached\n");
+		mutex_unlock(&vid_enc_device_p->lock);
+		return -ENODEV;
+	}
+
+	DBG(" Virtual Address of ioremap is %p\n", vid_enc_device_p->virt_base);
+	if (!vid_enc_device_p->num_clients) {
+		if (!vidc_load_firmware())
+			return -ENODEV;
+	}
+
+	client_index = vid_enc_get_empty_client_index();
+
+	if (client_index == -1) {
+		ERR("%s() : No free clients client_index == -1\n",
+			__func__);
+		return -ENODEV;
+	}
+
+	client_ctx =
+		&vid_enc_device_p->venc_clients[client_index];
+	vid_enc_device_p->num_clients++;
+
+	init_completion(&client_ctx->event);
+	mutex_init(&client_ctx->msg_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);
+	client_ctx->stop_msg = 0;
+
+	if (!vcd_status) {
+		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_enc_device_p->lock);
+			return -EFAULT;
+		}
+	} else {
+		ERR("vcd_open returned error: %u", vcd_status);
+		mutex_unlock(&vid_enc_device_p->lock);
+		return -EFAULT;
+	}
+	file->private_data = client_ctx;
+	mutex_unlock(&vid_enc_device_p->lock);
+	return 0;
+}
+
+static int vid_enc_release(struct inode *inode, struct file *file)
+{
+	struct video_client_ctx *client_ctx = file->private_data;
+	INFO("\n msm_vidc_enc: Inside %s()", __func__);
+	vid_enc_close_client(client_ctx);
+	vidc_release_firmware();
+#ifndef USE_RES_TRACKER
+	vidc_disable_clk();
+#endif
+	INFO("\n msm_vidc_enc: Return from %s()", __func__);
+	return 0;
+}
+
+static const struct file_operations vid_enc_fops = {
+	.owner = THIS_MODULE,
+	.open = vid_enc_open,
+	.release = vid_enc_release,
+	.unlocked_ioctl = vid_enc_ioctl,
+};
+
+void vid_enc_interrupt_deregister(void)
+{
+}
+
+void vid_enc_interrupt_register(void *device_name)
+{
+}
+
+void vid_enc_interrupt_clear(void)
+{
+}
+
+void *vid_enc_map_dev_base_addr(void *device_name)
+{
+	return vid_enc_device_p->virt_base;
+}
+
+static int vid_enc_vcd_init(void)
+{
+	int rc;
+	struct vcd_init_config vcd_init_config;
+	u32 i;
+
+	INFO("\n msm_vidc_enc: Inside %s()", __func__);
+	vid_enc_device_p->num_clients = 0;
+
+	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+		memset((void *)&vid_enc_device_p->venc_clients[i], 0,
+		sizeof(vid_enc_device_p->venc_clients[i]));
+	}
+
+	mutex_init(&vid_enc_device_p->lock);
+	vid_enc_device_p->virt_base = vidc_get_ioaddr();
+
+	if (!vid_enc_device_p->virt_base) {
+		ERR("%s() : ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	vcd_init_config.device_name = "VIDC";
+	vcd_init_config.map_dev_base_addr =
+		vid_enc_map_dev_base_addr;
+	vcd_init_config.interrupt_clr =
+		vid_enc_interrupt_clear;
+	vcd_init_config.register_isr =
+		vid_enc_interrupt_register;
+	vcd_init_config.deregister_isr =
+		vid_enc_interrupt_deregister;
+
+	rc = vcd_init(&vcd_init_config,
+		&vid_enc_device_p->device_handle);
+
+	if (rc) {
+		ERR("%s() : vcd_init failed\n",
+			__func__);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int __init vid_enc_init(void)
+{
+	int rc = 0;
+	struct device *class_devp;
+
+	INFO("\n msm_vidc_enc: Inside %s()", __func__);
+	vid_enc_device_p = kzalloc(sizeof(struct vid_enc_dev),
+					 GFP_KERNEL);
+	if (!vid_enc_device_p) {
+		ERR("%s Unable to allocate memory for vid_enc_dev\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	rc = alloc_chrdev_region(&vid_enc_dev_num, 0, 1, VID_ENC_NAME);
+	if (rc < 0) {
+		ERR("%s: alloc_chrdev_region Failed rc = %d\n",
+			__func__, rc);
+		goto error_vid_enc_alloc_chrdev_region;
+	}
+
+	vid_enc_class = class_create(THIS_MODULE, VID_ENC_NAME);
+	if (IS_ERR(vid_enc_class)) {
+		rc = PTR_ERR(vid_enc_class);
+		ERR("%s: couldn't create vid_enc_class rc = %d\n",
+			__func__, rc);
+		goto error_vid_enc_class_create;
+	}
+
+	class_devp = device_create(vid_enc_class, NULL,
+				vid_enc_dev_num, NULL, VID_ENC_NAME);
+
+	if (IS_ERR(class_devp)) {
+		rc = PTR_ERR(class_devp);
+		ERR("%s: class device_create failed %d\n",
+		__func__, rc);
+		goto error_vid_enc_class_device_create;
+	}
+
+	vid_enc_device_p->device = class_devp;
+
+	cdev_init(&vid_enc_device_p->cdev, &vid_enc_fops);
+	vid_enc_device_p->cdev.owner = THIS_MODULE;
+	rc = cdev_add(&(vid_enc_device_p->cdev), vid_enc_dev_num, 1);
+
+	if (rc < 0) {
+		ERR("%s: cdev_add failed %d\n",
+		__func__, rc);
+		goto error_vid_enc_cdev_add;
+	}
+	vid_enc_vcd_init();
+	return 0;
+
+error_vid_enc_cdev_add:
+	device_destroy(vid_enc_class, vid_enc_dev_num);
+error_vid_enc_class_device_create:
+	class_destroy(vid_enc_class);
+error_vid_enc_class_create:
+	unregister_chrdev_region(vid_enc_dev_num, 1);
+error_vid_enc_alloc_chrdev_region:
+	kfree(vid_enc_device_p);
+
+	return rc;
+}
+
+static void __exit vid_enc_exit(void)
+{
+	INFO("\n msm_vidc_enc: Inside %s()", __func__);
+	cdev_del(&(vid_enc_device_p->cdev));
+	device_destroy(vid_enc_class, vid_enc_dev_num);
+	class_destroy(vid_enc_class);
+	unregister_chrdev_region(vid_enc_dev_num, 1);
+	kfree(vid_enc_device_p);
+	INFO("\n msm_vidc_enc: Return from %s()", __func__);
+}
+static long vid_enc_ioctl(struct file *file,
+		unsigned cmd, unsigned long u_arg)
+{
+	struct video_client_ctx *client_ctx = NULL;
+	struct venc_ioctl_msg venc_msg;
+	void __user *arg = (void __user *)u_arg;
+	u32 result = true;
+
+	DBG("%s\n", __func__);
+
+	client_ctx = (struct video_client_ctx *)file->private_data;
+	if (!client_ctx) {
+		ERR("!client_ctx. Cannot attach to device handle\n");
+		return -ENODEV;
+	}
+
+	switch (cmd) {
+	case VEN_IOCTL_CMD_READ_NEXT_MSG:
+	{
+		struct venc_msg cb_msg;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_CMD_READ_NEXT_MSG\n");
+		result = vid_enc_get_next_msg(client_ctx, &cb_msg);
+		if (!result)
+			return -EIO;
+		if (copy_to_user(venc_msg.out, &cb_msg, sizeof(cb_msg)))
+			return -EFAULT;
+		break;
+	}
+	case VEN_IOCTL_CMD_STOP_READ_MSG:
+	{
+		DBG("VEN_IOCTL_CMD_STOP_READ_MSG\n");
+		client_ctx->stop_msg = 1;
+		wake_up(&client_ctx->msg_wait);
+		break;
+	}
+	case VEN_IOCTL_CMD_ENCODE_FRAME:
+	case VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER:
+	{
+		struct venc_buffer enc_buffer;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_CMD_ENCODE_FRAME"
+			"/VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER\n");
+		if (copy_from_user(&enc_buffer, venc_msg.in,
+						   sizeof(enc_buffer)))
+			return -EFAULT;
+		if (cmd == VEN_IOCTL_CMD_ENCODE_FRAME)
+			result = vid_enc_encode_frame(client_ctx,
+					&enc_buffer);
+		else
+			result = vid_enc_fill_output_buffer(client_ctx,
+					&enc_buffer);
+		if (!result) {
+			DBG("\n VEN_IOCTL_CMD_ENCODE_FRAME/"
+				"VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_INPUT_BUFFER:
+	case VEN_IOCTL_SET_OUTPUT_BUFFER:
+	{
+		enum venc_buffer_dir buffer_dir;
+		struct venc_bufferpayload buffer_info;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_SET_INPUT_BUFFER/VEN_IOCTL_SET_OUTPUT_BUFFER\n");
+		if (copy_from_user(&buffer_info, venc_msg.in,
+			sizeof(buffer_info)))
+			return -EFAULT;
+		buffer_dir = VEN_BUFFER_TYPE_INPUT;
+		if (cmd == VEN_IOCTL_SET_OUTPUT_BUFFER)
+			buffer_dir = VEN_BUFFER_TYPE_OUTPUT;
+		result = vid_enc_set_buffer(client_ctx, &buffer_info,
+				buffer_dir);
+		if (!result) {
+			DBG("\n VEN_IOCTL_SET_INPUT_BUFFER"
+				"/VEN_IOCTL_SET_OUTPUT_BUFFER failed");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_CMD_FREE_INPUT_BUFFER:
+	case VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER:
+	{
+		enum venc_buffer_dir buffer_dir;
+		struct venc_bufferpayload buffer_info;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_CMD_FREE_INPUT_BUFFER/"
+			"VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER\n");
+
+		if (copy_from_user(&buffer_info, venc_msg.in,
+			sizeof(buffer_info)))
+			return -EFAULT;
+
+		buffer_dir = VEN_BUFFER_TYPE_INPUT;
+		if (cmd == VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER)
+			buffer_dir = VEN_BUFFER_TYPE_OUTPUT;
+
+		result = vid_enc_free_buffer(client_ctx, &buffer_info,
+				buffer_dir);
+		if (!result) {
+			DBG("\n VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER"
+				"/VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER failed");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_INPUT_BUFFER_REQ:
+	case VEN_IOCTL_SET_OUTPUT_BUFFER_REQ:
+	{
+		struct venc_allocatorproperty allocatorproperty;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_SET_INPUT_BUFFER_REQ"
+			"/VEN_IOCTL_SET_OUTPUT_BUFFER_REQ\n");
+
+		if (copy_from_user(&allocatorproperty, venc_msg.in,
+			sizeof(allocatorproperty)))
+			return -EFAULT;
+
+		if (cmd == VEN_IOCTL_SET_OUTPUT_BUFFER_REQ)
+				result = vid_enc_set_buffer_req(client_ctx,
+						&allocatorproperty, false);
+		else
+			result = vid_enc_set_buffer_req(client_ctx,
+					&allocatorproperty, true);
+		if (!result) {
+			DBG("setting VEN_IOCTL_SET_OUTPUT_BUFFER_REQ/"
+			"VEN_IOCTL_SET_INPUT_BUFFER_REQ failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_GET_INPUT_BUFFER_REQ:
+	case VEN_IOCTL_GET_OUTPUT_BUFFER_REQ:
+	{
+		struct venc_allocatorproperty allocatorproperty;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_GET_INPUT_BUFFER_REQ/"
+			"VEN_IOCTL_GET_OUTPUT_BUFFER_REQ\n");
+
+		if (cmd == VEN_IOCTL_GET_OUTPUT_BUFFER_REQ)
+			result = vid_enc_get_buffer_req(client_ctx,
+					&allocatorproperty, false);
+		else
+			result = vid_enc_get_buffer_req(client_ctx,
+					&allocatorproperty, true);
+		if (!result)
+			return -EIO;
+		if (copy_to_user(venc_msg.out, &allocatorproperty,
+				sizeof(allocatorproperty)))
+			return -EFAULT;
+		break;
+	}
+	case VEN_IOCTL_CMD_FLUSH:
+	{
+		struct venc_bufferflush bufferflush;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_CMD_FLUSH\n");
+		if (copy_from_user(&bufferflush, venc_msg.in,
+			sizeof(bufferflush)))
+			return -EFAULT;
+		INFO("\n %s(): Calling vid_enc_flush with mode = %lu",
+			 __func__, bufferflush.flush_mode);
+		result = vid_enc_flush(client_ctx, &bufferflush);
+
+		if (!result) {
+			ERR("setting VEN_IOCTL_CMD_FLUSH failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_CMD_START:
+	{
+		INFO("\n %s(): Executing VEN_IOCTL_CMD_START", __func__);
+		result = vid_enc_start_stop(client_ctx, true);
+		if (!result) {
+			ERR("setting VEN_IOCTL_CMD_START failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_CMD_STOP:
+	{
+		INFO("\n %s(): Executing VEN_IOCTL_CMD_STOP", __func__);
+		result = vid_enc_start_stop(client_ctx, false);
+		if (!result) {
+			ERR("setting VEN_IOCTL_CMD_STOP failed\n");
+			return -EIO;
+		}
+		stop_cmd = 1;
+		break;
+	}
+	case VEN_IOCTL_CMD_PAUSE:
+	{
+		INFO("\n %s(): Executing VEN_IOCTL_CMD_PAUSE", __func__);
+		result = vid_enc_pause_resume(client_ctx, true);
+		if (!result) {
+			ERR("setting VEN_IOCTL_CMD_PAUSE failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_CMD_RESUME:
+	{
+		INFO("\n %s(): Executing VEN_IOCTL_CMD_RESUME", __func__);
+		result = vid_enc_pause_resume(client_ctx, false);
+		if (!result) {
+			ERR("setting VEN_IOCTL_CMD_RESUME failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_RECON_BUFFER:
+	{
+		struct venc_recon_addr venc_recon;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_SET_RECON_BUFFER\n");
+		if (copy_from_user(&venc_recon, venc_msg.in,
+				sizeof(venc_recon)))
+				return -EFAULT;
+		result = vid_enc_set_recon_buffers(client_ctx,
+					&venc_recon);
+		if (!result) {
+			ERR("setting VEN_IOCTL_SET_RECON_BUFFER failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_FREE_RECON_BUFFER:
+	{
+		DBG("VEN_IOCTL_FREE_RECON_BUFFER\n");
+		result = vid_enc_free_recon_buffers(client_ctx);
+		if (!result) {
+			ERR("VEN_IOCTL_FREE_RECON_BUFFER failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_GET_RECON_BUFFER_SIZE:
+	{
+		struct venc_recon_buff_size venc_recon_size;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_GET_RECON_BUFFER_SIZE\n");
+		if (copy_from_user(&venc_recon_size, venc_msg.out,
+						   sizeof(venc_recon_size)))
+				return -EFAULT;
+		result = vid_enc_get_recon_buffer_size(client_ctx,
+					&venc_recon_size);
+		if (result) {
+				if (copy_to_user(venc_msg.out, &venc_recon_size,
+					sizeof(venc_recon_size)))
+					return -EFAULT;
+			} else {
+				ERR("setting VEN_IOCTL_GET_RECON_BUFFER_SIZE"
+					"failed\n");
+				return -EIO;
+			}
+		break;
+	}
+	case VEN_IOCTL_SET_QP_RANGE:
+	case VEN_IOCTL_GET_QP_RANGE:
+	{
+		struct venc_qprange qprange;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_G(S)ET_QP_RANGE\n");
+		if (cmd == VEN_IOCTL_SET_QP_RANGE) {
+			if (copy_from_user(&qprange, venc_msg.in,
+				sizeof(qprange)))
+				return -EFAULT;
+			result = vid_enc_set_get_qprange(client_ctx,
+					&qprange, true);
+		} else {
+			result = vid_enc_set_get_qprange(client_ctx,
+					&qprange, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &qprange,
+					sizeof(qprange)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_G(S)ET_QP_RANGE failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_HEC:
+	case VEN_IOCTL_GET_HEC:
+	{
+		struct venc_headerextension headerextension;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_HEC\n");
+		if (cmd == VEN_IOCTL_SET_HEC) {
+			if (copy_from_user(&headerextension, venc_msg.in,
+				sizeof(headerextension)))
+				return -EFAULT;
+
+			result = vid_enc_set_get_headerextension(client_ctx,
+					&headerextension, true);
+		} else {
+			result = vid_enc_set_get_headerextension(client_ctx,
+					&headerextension, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &headerextension,
+				sizeof(headerextension)))
+					return -EFAULT;
+			}
+		}
+
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_HEC failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_TARGET_BITRATE:
+	case VEN_IOCTL_GET_TARGET_BITRATE:
+	{
+		struct venc_targetbitrate targetbitrate;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_TARGET_BITRATE\n");
+		if (cmd == VEN_IOCTL_SET_TARGET_BITRATE) {
+			if (copy_from_user(&targetbitrate, venc_msg.in,
+				sizeof(targetbitrate)))
+				return -EFAULT;
+
+			result = vid_enc_set_get_bitrate(client_ctx,
+					&targetbitrate, true);
+		} else {
+			result = vid_enc_set_get_bitrate(client_ctx,
+					&targetbitrate, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &targetbitrate,
+					sizeof(targetbitrate)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_TARGET_BITRATE failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_FRAME_RATE:
+	case VEN_IOCTL_GET_FRAME_RATE:
+	{
+		struct venc_framerate framerate;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_FRAME_RATE\n");
+		if (cmd == VEN_IOCTL_SET_FRAME_RATE) {
+			if (copy_from_user(&framerate, venc_msg.in,
+				sizeof(framerate)))
+				return -EFAULT;
+			result = vid_enc_set_get_framerate(client_ctx,
+					&framerate, true);
+		} else {
+			result = vid_enc_set_get_framerate(client_ctx,
+					&framerate,	false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &framerate,
+					sizeof(framerate)))
+					return -EFAULT;
+			}
+		}
+
+		if (!result) {
+			ERR("VEN_IOCTL_(G)SET_FRAME_RATE failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_VOP_TIMING_CFG:
+	case VEN_IOCTL_GET_VOP_TIMING_CFG:
+	{
+		struct venc_voptimingcfg voptimingcfg;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_(G)SET_VOP_TIMING_CFG\n");
+		if (cmd == VEN_IOCTL_SET_VOP_TIMING_CFG) {
+			if (copy_from_user(&voptimingcfg, venc_msg.in,
+				sizeof(voptimingcfg)))
+				return -EFAULT;
+			result = vid_enc_set_get_voptimingcfg(client_ctx,
+					&voptimingcfg, true);
+		} else {
+			result = vid_enc_set_get_voptimingcfg(client_ctx,
+					&voptimingcfg, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &voptimingcfg,
+					sizeof(voptimingcfg)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("VEN_IOCTL_(G)SET_VOP_TIMING_CFG failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_RATE_CTRL_CFG:
+	case VEN_IOCTL_GET_RATE_CTRL_CFG:
+	{
+		struct venc_ratectrlcfg ratectrlcfg;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_RATE_CTRL_CFG\n");
+		if (cmd == VEN_IOCTL_SET_RATE_CTRL_CFG) {
+			if (copy_from_user(&ratectrlcfg, venc_msg.in,
+				sizeof(ratectrlcfg)))
+				return -EFAULT;
+
+			result = vid_enc_set_get_ratectrlcfg(client_ctx,
+					&ratectrlcfg, true);
+		} else {
+			result = vid_enc_set_get_ratectrlcfg(client_ctx,
+					&ratectrlcfg, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &ratectrlcfg,
+					sizeof(ratectrlcfg)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_RATE_CTRL_CFG failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_MULTI_SLICE_CFG:
+	case VEN_IOCTL_GET_MULTI_SLICE_CFG:
+	{
+		struct venc_multiclicecfg multiclicecfg;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_MULTI_SLICE_CFG\n");
+		if (cmd == VEN_IOCTL_SET_MULTI_SLICE_CFG) {
+			if (copy_from_user(&multiclicecfg, venc_msg.in,
+				sizeof(multiclicecfg)))
+				return -EFAULT;
+
+			result = vid_enc_set_get_multiclicecfg(client_ctx,
+					&multiclicecfg, true);
+		} else {
+			result = vid_enc_set_get_multiclicecfg(client_ctx,
+					&multiclicecfg, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &multiclicecfg,
+					sizeof(multiclicecfg)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("VEN_IOCTL_(G)SET_MULTI_SLICE_CFG failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_INTRA_REFRESH:
+	case VEN_IOCTL_GET_INTRA_REFRESH:
+	{
+		struct venc_intrarefresh intrarefresh;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_INTRA_REFRESH\n");
+		if (cmd == VEN_IOCTL_SET_INTRA_REFRESH) {
+			if (copy_from_user(&intrarefresh, venc_msg.in,
+				sizeof(intrarefresh)))
+				return -EFAULT;
+			result = vid_enc_set_get_intrarefresh(client_ctx,
+					&intrarefresh, true);
+		} else {
+			result = vid_enc_set_get_intrarefresh(client_ctx,
+					&intrarefresh, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &intrarefresh,
+					sizeof(intrarefresh)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_SET_INTRA_REFRESH failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_DEBLOCKING_CFG:
+	case VEN_IOCTL_GET_DEBLOCKING_CFG:
+	{
+		struct venc_dbcfg dbcfg;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_(G)SET_DEBLOCKING_CFG\n");
+		if (cmd == VEN_IOCTL_SET_DEBLOCKING_CFG) {
+			if (copy_from_user(&dbcfg, venc_msg.in,
+				sizeof(dbcfg)))
+				return -EFAULT;
+			result = vid_enc_set_get_dbcfg(client_ctx,
+					&dbcfg, true);
+		} else {
+			result = vid_enc_set_get_dbcfg(client_ctx,
+					&dbcfg, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &dbcfg,
+				sizeof(dbcfg)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_SET_DEBLOCKING_CFG failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_ENTROPY_CFG:
+	case VEN_IOCTL_GET_ENTROPY_CFG:
+	{
+		struct venc_entropycfg entropy_cfg;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_ENTROPY_CFG\n");
+		if (cmd == VEN_IOCTL_SET_ENTROPY_CFG) {
+			if (copy_from_user(&entropy_cfg, venc_msg.in,
+				sizeof(entropy_cfg)))
+				return -EFAULT;
+			result = vid_enc_set_get_entropy_cfg(client_ctx,
+					&entropy_cfg, true);
+		} else {
+			result = vid_enc_set_get_entropy_cfg(client_ctx,
+					&entropy_cfg, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &entropy_cfg,
+				sizeof(entropy_cfg)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_ENTROPY_CFG failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_GET_SEQUENCE_HDR:
+	{
+		struct venc_seqheader seq_header, seq_header_user;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_GET_SEQUENCE_HDR\n");
+		if (copy_from_user(&seq_header_user, venc_msg.in,
+			sizeof(seq_header_user)))
+			return -EFAULT;
+		seq_header.hdrbufptr = NULL;
+		result = vid_enc_get_sequence_header(client_ctx,
+				&seq_header);
+		if (result && ((copy_to_user(seq_header_user.hdrbufptr,
+			seq_header.hdrbufptr, seq_header.hdrlen)) ||
+			(copy_to_user(&seq_header_user.hdrlen,
+			&seq_header.hdrlen,
+			sizeof(seq_header.hdrlen)))))
+				result = false;
+		kfree(seq_header.hdrbufptr);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VEN_IOCTL_CMD_REQUEST_IFRAME:
+	{
+		result = vid_enc_request_iframe(client_ctx);
+		if (!result) {
+			ERR("setting VEN_IOCTL_CMD_REQUEST_IFRAME failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_INTRA_PERIOD:
+	case VEN_IOCTL_GET_INTRA_PERIOD:
+	{
+		struct venc_intraperiod intraperiod;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_INTRA_PERIOD\n");
+		if (cmd == VEN_IOCTL_SET_INTRA_PERIOD) {
+			if (copy_from_user(&intraperiod, venc_msg.in,
+				sizeof(intraperiod)))
+				return -EFAULT;
+			result = vid_enc_set_get_intraperiod(client_ctx,
+					&intraperiod, true);
+		} else {
+			result = vid_enc_set_get_intraperiod(client_ctx,
+					&intraperiod, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &intraperiod,
+					sizeof(intraperiod)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_INTRA_PERIOD failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_SESSION_QP:
+	case VEN_IOCTL_GET_SESSION_QP:
+	{
+		struct venc_sessionqp session_qp;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("VEN_IOCTL_(G)SET_SESSION_QP\n");
+		if (cmd == VEN_IOCTL_SET_SESSION_QP) {
+			if (copy_from_user(&session_qp,	venc_msg.in,
+				sizeof(session_qp)))
+				return -EFAULT;
+			result = vid_enc_set_get_session_qp(client_ctx,
+					&session_qp, true);
+		} else {
+			result = vid_enc_set_get_session_qp(client_ctx,
+					&session_qp, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &session_qp,
+					sizeof(session_qp)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_SESSION_QP failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_PROFILE_LEVEL:
+	case VEN_IOCTL_GET_PROFILE_LEVEL:
+	{
+		struct ven_profilelevel profile_level;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_(G)SET_PROFILE_LEVEL\n");
+		if (cmd == VEN_IOCTL_SET_PROFILE_LEVEL) {
+			if (copy_from_user(&profile_level, venc_msg.in,
+				sizeof(profile_level)))
+				return -EFAULT;
+			result = vid_enc_set_get_profile_level(client_ctx,
+					&profile_level, true);
+		} else {
+			result = vid_enc_set_get_profile_level(client_ctx,
+					&profile_level, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out,
+				&profile_level,	sizeof(profile_level)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_SET_PROFILE_LEVEL failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_CODEC_PROFILE:
+	case VEN_IOCTL_GET_CODEC_PROFILE:
+	{
+		struct venc_profile profile;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("VEN_IOCTL_(G)SET_CODEC_PROFILE\n");
+		if (cmd == VEN_IOCTL_SET_CODEC_PROFILE) {
+			if (copy_from_user(&profile, venc_msg.in,
+					sizeof(profile)))
+				return -EFAULT;
+			result = vid_enc_set_get_profile(client_ctx,
+					&profile, true);
+		} else {
+			result = vid_enc_set_get_profile(client_ctx,
+					&profile, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &profile,
+						sizeof(profile)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_SET_CODEC_PROFILE failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_SHORT_HDR:
+	case VEN_IOCTL_GET_SHORT_HDR:
+	{
+		struct venc_switch encoder_switch;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		DBG("Getting VEN_IOCTL_(G)SET_SHORT_HDR\n");
+		if (cmd == VEN_IOCTL_SET_SHORT_HDR) {
+			if (copy_from_user(&encoder_switch,	venc_msg.in,
+				sizeof(encoder_switch)))
+				return -EFAULT;
+
+			result = vid_enc_set_get_short_header(client_ctx,
+					&encoder_switch, true);
+		} else {
+			result = vid_enc_set_get_short_header(client_ctx,
+					&encoder_switch, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &encoder_switch,
+					sizeof(encoder_switch)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_SHORT_HDR failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_BASE_CFG:
+	case VEN_IOCTL_GET_BASE_CFG:
+	{
+		struct venc_basecfg base_config;
+		DBG("VEN_IOCTL_SET_BASE_CFG\n");
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (cmd == VEN_IOCTL_SET_BASE_CFG) {
+			if (copy_from_user(&base_config, venc_msg.in,
+				sizeof(base_config)))
+				return -EFAULT;
+			result = vid_enc_set_get_base_cfg(client_ctx,
+					&base_config, true);
+		} else {
+			result = vid_enc_set_get_base_cfg(client_ctx,
+					&base_config, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &base_config,
+					sizeof(base_config)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_SET_BASE_CFG failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_LIVE_MODE:
+	case VEN_IOCTL_GET_LIVE_MODE:
+	{
+		struct venc_switch encoder_switch;
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+
+		DBG("Getting VEN_IOCTL_(G)SET_LIVE_MODE\n");
+		if (cmd == VEN_IOCTL_SET_LIVE_MODE) {
+			if (copy_from_user(&encoder_switch,	venc_msg.in,
+				sizeof(encoder_switch)))
+				return -EFAULT;
+			result = vid_enc_set_get_live_mode(client_ctx,
+					&encoder_switch, true);
+		} else {
+			result = vid_enc_set_get_live_mode(client_ctx,
+					&encoder_switch, false);
+			if (result) {
+				if (copy_to_user(venc_msg.out, &encoder_switch,
+					sizeof(encoder_switch)))
+					return -EFAULT;
+			}
+		}
+		if (!result) {
+			ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n");
+			return -EIO;
+		}
+		break;
+	}
+	case VEN_IOCTL_GET_NUMBER_INSTANCES:
+	{
+		DBG("VEN_IOCTL_GET_NUMBER_INSTANCES\n");
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (copy_to_user(venc_msg.out,
+			&vid_enc_device_p->num_clients, sizeof(u32)))
+			return -EFAULT;
+		break;
+	}
+	case VEN_IOCTL_SET_AC_PREDICTION:
+	case VEN_IOCTL_GET_AC_PREDICTION:
+	case VEN_IOCTL_SET_RVLC:
+	case VEN_IOCTL_GET_RVLC:
+	case VEN_IOCTL_SET_ROTATION:
+	case VEN_IOCTL_GET_ROTATION:
+	case VEN_IOCTL_SET_DATA_PARTITION:
+	case VEN_IOCTL_GET_DATA_PARTITION:
+	case VEN_IOCTL_GET_CAPABILITY:
+	default:
+		ERR("%s(): Unsupported ioctl %d\n", __func__, cmd);
+		return -ENOTTY;
+
+		break;
+	}
+	return 0;
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Video encoder driver");
+MODULE_VERSION("1.0");
+
+module_init(vid_enc_init);
+module_exit(vid_enc_exit);
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
new file mode 100644
index 0000000..d202d81
--- /dev/null
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -0,0 +1,1784 @@
+/* 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/cdev.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/android_pmem.h>
+#include <linux/clk.h>
+
+#include "vidc_type.h"
+#include "vcd_api.h"
+#include "venc_internal.h"
+#include "vidc_init.h"
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+#define ERR(x...) printk(KERN_ERR x)
+
+u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx,
+		struct venc_basecfg *base_config, u32 set_flag)
+{
+	struct venc_targetbitrate venc_bitrate;
+	struct venc_framerate frame_rate;
+	u32 current_codec;
+
+	if (!client_ctx || !base_config)
+		return false;
+
+	if (!vid_enc_set_get_codec(client_ctx, &current_codec, false))
+			return false;
+
+	DBG("%s(): Current Codec Type = %u\n", __func__, current_codec);
+	if (current_codec != base_config->codectype) {
+		if (!vid_enc_set_get_codec(client_ctx,
+				(u32 *)&base_config->codectype, set_flag))
+			return false;
+	}
+
+	if (!vid_enc_set_get_inputformat(client_ctx,
+			(u32 *)&base_config->inputformat, set_flag))
+		return false;
+
+	if (!vid_enc_set_get_framesize(client_ctx,
+			(u32 *)&base_config->input_height,
+			(u32 *)&base_config->input_width, set_flag))
+		return false;
+
+	if (set_flag)
+		venc_bitrate.target_bitrate = base_config->targetbitrate;
+
+	if (!vid_enc_set_get_bitrate(client_ctx, &venc_bitrate, set_flag))
+		return false;
+
+	if (!set_flag)
+		base_config->targetbitrate = venc_bitrate.target_bitrate;
+
+	if (set_flag) {
+		frame_rate.fps_denominator = base_config->fps_den;
+		frame_rate.fps_numerator = base_config->fps_num;
+	}
+
+	if (!vid_enc_set_get_framerate(client_ctx, &frame_rate, set_flag))
+		return false;
+
+	if (!set_flag) {
+		base_config->fps_den = frame_rate.fps_denominator;
+		base_config->fps_num = frame_rate.fps_numerator;
+	}
+
+	return true;
+}
+
+u32 vid_enc_set_get_inputformat(struct video_client_ctx *client_ctx,
+		u32 *input_format, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_format format;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !input_format)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_buffer_format);
+
+	if (set_flag) {
+		switch (*input_format) {
+		case VEN_INPUTFMT_NV12:
+			format.buffer_format = VCD_BUFFER_FORMAT_NV12;
+			break;
+		case VEN_INPUTFMT_NV12_16M2KA:
+			format.buffer_format =
+				VCD_BUFFER_FORMAT_NV12_16M2KA;
+			break;
+		default:
+			status = false;
+			break;
+		}
+
+		if (status) {
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &format);
+			if (vcd_status) {
+				status = false;
+				ERR("%s(): Set VCD_I_BUFFER_FORMAT Failed\n",
+						 __func__);
+			}
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &format);
+
+		if (vcd_status) {
+			status = false;
+			ERR("%s(): Get VCD_I_BUFFER_FORMAT Failed\n", __func__);
+		} else {
+			switch (format.buffer_format) {
+			case VCD_BUFFER_FORMAT_NV12:
+				*input_format = VEN_INPUTFMT_NV12;
+				break;
+			case VCD_BUFFER_FORMAT_TILE_4x2:
+				*input_format = VEN_INPUTFMT_NV21;
+				break;
+			default:
+				status = false;
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_codec(struct video_client_ctx *client_ctx, u32 *codec,
+		u32 set_flag)
+{
+	struct vcd_property_codec vcd_property_codec;
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !codec)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+
+	if (set_flag) {
+		switch (*codec) {
+		case VEN_CODEC_MPEG4:
+			vcd_property_codec.codec = VCD_CODEC_MPEG4;
+			break;
+		case VEN_CODEC_H263:
+			vcd_property_codec.codec = VCD_CODEC_H263;
+			break;
+		case VEN_CODEC_H264:
+			vcd_property_codec.codec = VCD_CODEC_H264;
+			break;
+		default:
+			status = false;
+			break;
+		}
+
+		if (status) {
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+			if (vcd_status) {
+				status = false;
+				ERR("%s(): Set VCD_I_CODEC Failed\n", __func__);
+			}
+		}
+	}	else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_codec);
+
+		if (vcd_status) {
+			status = false;
+			ERR("%s(): Get VCD_I_CODEC Failed\n",
+					 __func__);
+		} else {
+			switch (vcd_property_codec.codec) {
+			case VCD_CODEC_H263:
+				*codec = VEN_CODEC_H263;
+				break;
+			case VCD_CODEC_H264:
+				*codec = VEN_CODEC_H264;
+				break;
+			case VCD_CODEC_MPEG4:
+				*codec = VEN_CODEC_MPEG4;
+				break;
+			case VCD_CODEC_DIVX_3:
+			case VCD_CODEC_DIVX_4:
+			case VCD_CODEC_DIVX_5:
+			case VCD_CODEC_DIVX_6:
+			case VCD_CODEC_MPEG1:
+			case VCD_CODEC_MPEG2:
+			case VCD_CODEC_VC1:
+			case VCD_CODEC_VC1_RCV:
+			case VCD_CODEC_XVID:
+			default:
+				status = false;
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_framesize(struct video_client_ctx *client_ctx,
+		u32 *height, u32 *width, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_size frame_size;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !height || !width)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_frame_size);
+
+	vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &frame_size);
+
+	if (vcd_status) {
+		ERR("%s(): Get VCD_I_FRAME_SIZE Failed\n",
+				__func__);
+		return false;
+	}
+	if (set_flag) {
+		if (frame_size.height != *height ||
+			frame_size.width != *width) {
+			DBG("%s(): ENC Set Size (%d x %d)\n",
+				__func__, *height, *width);
+			frame_size.height = *height;
+			frame_size.width = *width;
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &frame_size);
+			if (vcd_status) {
+				ERR("%s(): Set VCD_I_FRAME_SIZE Failed\n",
+						__func__);
+				return false;
+			}
+		}
+	} else {
+		*height = frame_size.height;
+		*width = frame_size.width;
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_bitrate(struct video_client_ctx *client_ctx,
+		struct venc_targetbitrate *venc_bitrate, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_target_bitrate bit_rate;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !venc_bitrate)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_target_bitrate);
+	if (set_flag) {
+		bit_rate.target_bitrate = venc_bitrate->target_bitrate;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &bit_rate);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_TARGET_BITRATE Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &bit_rate);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_TARGET_BITRATE Failed\n",
+					__func__);
+			return false;
+		}
+		venc_bitrate->target_bitrate = bit_rate.target_bitrate;
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx,
+		struct venc_framerate *frame_rate, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_rate vcd_frame_rate;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !frame_rate)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_RATE;
+	vcd_property_hdr.sz =
+				sizeof(struct vcd_property_frame_rate);
+
+	if (set_flag) {
+		vcd_frame_rate.fps_denominator = frame_rate->fps_denominator;
+		vcd_frame_rate.fps_numerator = frame_rate->fps_numerator;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &vcd_frame_rate);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_FRAME_RATE Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_frame_rate);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_FRAME_RATE Failed\n",
+					__func__);
+			return false;
+		}
+		frame_rate->fps_denominator = vcd_frame_rate.fps_denominator;
+		frame_rate->fps_numerator = vcd_frame_rate.fps_numerator;
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx,
+		struct venc_switch *encoder_switch, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_live live_mode;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_LIVE;
+	vcd_property_hdr.sz =
+				sizeof(struct vcd_property_live);
+
+	if (set_flag) {
+		live_mode.live = 1;
+		if (!encoder_switch->status)
+			live_mode.live = 0;
+
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &live_mode);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_LIVE Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &live_mode);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_LIVE Failed\n",
+					__func__);
+			return false;
+		}	else {
+			encoder_switch->status = 1;
+			if (!live_mode.live)
+				encoder_switch->status = 0;
+		}
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx,
+		struct venc_switch *encoder_switch,	u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_short_header short_header;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !encoder_switch)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_SHORT_HEADER;
+	vcd_property_hdr.sz =
+				sizeof(struct vcd_property_short_header);
+
+	if (set_flag) {
+		short_header.short_header = (u32) encoder_switch->status;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &short_header);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_SHORT_HEADER Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &short_header);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_SHORT_HEADER Failed\n",
+					__func__);
+			return false;
+		}	else {
+			encoder_switch->status =
+				(u8) short_header.short_header;
+		}
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_profile(struct video_client_ctx *client_ctx,
+		struct venc_profile *profile, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_profile profile_type;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !profile)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_PROFILE;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_profile);
+
+	if (set_flag) {
+		switch (profile->profile) {
+		case VEN_PROFILE_MPEG4_SP:
+			profile_type.profile = VCD_PROFILE_MPEG4_SP;
+			break;
+		case VEN_PROFILE_MPEG4_ASP:
+			profile_type.profile = VCD_PROFILE_MPEG4_ASP;
+			break;
+		case VEN_PROFILE_H264_BASELINE:
+			profile_type.profile = VCD_PROFILE_H264_BASELINE;
+			break;
+		case VEN_PROFILE_H264_MAIN:
+			profile_type.profile = VCD_PROFILE_H264_MAIN;
+			break;
+		case VEN_PROFILE_H264_HIGH:
+			profile_type.profile = VCD_PROFILE_H264_HIGH;
+			break;
+		case VEN_PROFILE_H263_BASELINE:
+			profile_type.profile = VCD_PROFILE_H263_BASELINE;
+			break;
+		default:
+			status = false;
+			break;
+		}
+
+		if (status) {
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &profile_type);
+
+			if (vcd_status) {
+				ERR("%s(): Set VCD_I_PROFILE Failed\n",
+						__func__);
+				return false;
+			}
+		}
+	}	else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &profile_type);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_PROFILE Failed\n",
+					__func__);
+			return false;
+		} else {
+			switch (profile_type.profile) {
+			case VCD_PROFILE_H263_BASELINE:
+				profile->profile = VEN_PROFILE_H263_BASELINE;
+				break;
+			case VCD_PROFILE_H264_BASELINE:
+				profile->profile = VEN_PROFILE_H264_BASELINE;
+				break;
+			case VCD_PROFILE_H264_HIGH:
+				profile->profile = VEN_PROFILE_H264_HIGH;
+				break;
+			case VCD_PROFILE_H264_MAIN:
+				profile->profile = VEN_PROFILE_H264_MAIN;
+				break;
+			case VCD_PROFILE_MPEG4_ASP:
+				profile->profile = VEN_PROFILE_MPEG4_ASP;
+				break;
+			case VCD_PROFILE_MPEG4_SP:
+				profile->profile = VEN_PROFILE_MPEG4_SP;
+				break;
+			default:
+				status = false;
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_profile_level(struct video_client_ctx *client_ctx,
+		struct ven_profilelevel *profile_level,	u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_level level;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !profile_level)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_LEVEL;
+	vcd_property_hdr.sz =
+			sizeof(struct vcd_property_level);
+
+	if (set_flag) {
+		switch (profile_level->level) {
+		case VEN_LEVEL_MPEG4_0:
+			level.level = VCD_LEVEL_MPEG4_0;
+			break;
+		case VEN_LEVEL_MPEG4_1:
+			level.level = VCD_LEVEL_MPEG4_1;
+			break;
+		case VEN_LEVEL_MPEG4_2:
+			level.level = VCD_LEVEL_MPEG4_2;
+			break;
+		case VEN_LEVEL_MPEG4_3:
+			level.level = VCD_LEVEL_MPEG4_3;
+			break;
+		case VEN_LEVEL_MPEG4_4:
+			level.level = VCD_LEVEL_MPEG4_4;
+			break;
+		case VEN_LEVEL_MPEG4_5:
+			level.level = VCD_LEVEL_MPEG4_5;
+			break;
+		case VEN_LEVEL_MPEG4_3b:
+			level.level = VCD_LEVEL_MPEG4_3b;
+			break;
+		case VEN_LEVEL_MPEG4_6:
+			level.level = VCD_LEVEL_MPEG4_6;
+			break;
+		case VEN_LEVEL_H264_1:
+			level.level = VCD_LEVEL_H264_1;
+			break;
+		case VEN_LEVEL_H264_1b:
+			level.level = VCD_LEVEL_H264_1b;
+			break;
+		case VEN_LEVEL_H264_1p1:
+			level.level = VCD_LEVEL_H264_1p1;
+			break;
+		case VEN_LEVEL_H264_1p2:
+			level.level = VCD_LEVEL_H264_1p2;
+			break;
+		case VEN_LEVEL_H264_1p3:
+			level.level = VCD_LEVEL_H264_1p3;
+			break;
+		case VEN_LEVEL_H264_2:
+			level.level = VCD_LEVEL_H264_2;
+			break;
+		case VEN_LEVEL_H264_2p1:
+			level.level = VCD_LEVEL_H264_2p1;
+			break;
+		case VEN_LEVEL_H264_2p2:
+			level.level = VCD_LEVEL_H264_2p2;
+			break;
+		case VEN_LEVEL_H264_3:
+			level.level = VCD_LEVEL_H264_3;
+			break;
+		case VEN_LEVEL_H264_3p1:
+			level.level = VCD_LEVEL_H264_3p1;
+			break;
+		case VEN_LEVEL_H264_4:
+			level.level = VCD_LEVEL_H264_4;
+			break;
+		case VEN_LEVEL_H263_10:
+			level.level = VCD_LEVEL_H263_10;
+			break;
+		case VEN_LEVEL_H263_20:
+			level.level = VCD_LEVEL_H263_20;
+			break;
+		case VEN_LEVEL_H263_30:
+			level.level = VCD_LEVEL_H263_30;
+			break;
+		case VEN_LEVEL_H263_40:
+			level.level = VCD_LEVEL_H263_40;
+			break;
+		case VEN_LEVEL_H263_45:
+			level.level = VCD_LEVEL_H263_45;
+			break;
+		case VEN_LEVEL_H263_50:
+			level.level = VCD_LEVEL_H263_50;
+			break;
+		case VEN_LEVEL_H263_60:
+			level.level = VCD_LEVEL_H263_60;
+			break;
+		case VEN_LEVEL_H263_70:
+			level.level = VCD_LEVEL_H263_70;
+			break;
+		default:
+			status = false;
+			break;
+		}
+		if (status) {
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+						&vcd_property_hdr, &level);
+
+			if (vcd_status) {
+				ERR("%s(): Set VCD_I_LEVEL Failed\n",
+						__func__);
+				return false;
+			}
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &level);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_LEVEL Failed\n",
+					__func__);
+			return false;
+		} else {
+			switch (level.level) {
+			case VCD_LEVEL_MPEG4_0:
+				profile_level->level = VEN_LEVEL_MPEG4_0;
+				break;
+			case VCD_LEVEL_MPEG4_1:
+				profile_level->level = VEN_LEVEL_MPEG4_1;
+				break;
+			case VCD_LEVEL_MPEG4_2:
+				profile_level->level = VEN_LEVEL_MPEG4_2;
+				break;
+			case VCD_LEVEL_MPEG4_3:
+				profile_level->level = VEN_LEVEL_MPEG4_3;
+				break;
+			case VCD_LEVEL_MPEG4_4:
+				profile_level->level = VEN_LEVEL_MPEG4_4;
+				break;
+			case VCD_LEVEL_MPEG4_5:
+				profile_level->level = VEN_LEVEL_MPEG4_5;
+				break;
+			case VCD_LEVEL_MPEG4_3b:
+				profile_level->level = VEN_LEVEL_MPEG4_3b;
+				break;
+			case VCD_LEVEL_H264_1:
+				profile_level->level = VEN_LEVEL_H264_1;
+				break;
+			case VCD_LEVEL_H264_1b:
+				profile_level->level = VEN_LEVEL_H264_1b;
+				break;
+			case VCD_LEVEL_H264_1p1:
+				profile_level->level = VEN_LEVEL_H264_1p1;
+				break;
+			case VCD_LEVEL_H264_1p2:
+				profile_level->level = VEN_LEVEL_H264_1p2;
+				break;
+			case VCD_LEVEL_H264_1p3:
+				profile_level->level = VEN_LEVEL_H264_1p3;
+				break;
+			case VCD_LEVEL_H264_2:
+				profile_level->level = VEN_LEVEL_H264_2;
+				break;
+			case VCD_LEVEL_H264_2p1:
+				profile_level->level = VEN_LEVEL_H264_2p1;
+				break;
+			case VCD_LEVEL_H264_2p2:
+				profile_level->level = VEN_LEVEL_H264_2p2;
+				break;
+			case VCD_LEVEL_H264_3:
+				profile_level->level = VEN_LEVEL_H264_3;
+				break;
+			case VCD_LEVEL_H264_3p1:
+				profile_level->level = VEN_LEVEL_H264_3p1;
+				break;
+			case VCD_LEVEL_H264_3p2:
+				status = false;
+				break;
+			case VCD_LEVEL_H264_4:
+				profile_level->level = VEN_LEVEL_H264_4;
+				break;
+			case VCD_LEVEL_H263_10:
+				profile_level->level = VEN_LEVEL_H263_10;
+				break;
+			case VCD_LEVEL_H263_20:
+				profile_level->level = VEN_LEVEL_H263_20;
+				break;
+			case VCD_LEVEL_H263_30:
+				profile_level->level = VEN_LEVEL_H263_30;
+				break;
+			case VCD_LEVEL_H263_40:
+				profile_level->level = VEN_LEVEL_H263_40;
+				break;
+			case VCD_LEVEL_H263_45:
+				profile_level->level = VEN_LEVEL_H263_45;
+				break;
+			case VCD_LEVEL_H263_50:
+				profile_level->level = VEN_LEVEL_H263_50;
+				break;
+			case VCD_LEVEL_H263_60:
+				profile_level->level = VEN_LEVEL_H263_60;
+				break;
+			case VCD_LEVEL_H263_70:
+				status = false;
+				break;
+			default:
+				status = false;
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_session_qp(struct video_client_ctx *client_ctx,
+		struct venc_sessionqp *session_qp, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_session_qp qp;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !session_qp)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_SESSION_QP;
+	vcd_property_hdr.sz =
+			sizeof(struct vcd_property_session_qp);
+
+	if (set_flag) {
+		qp.i_frame_qp = session_qp->iframeqp;
+		qp.p_frame_qp = session_qp->pframqp;
+
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &qp);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_SESSION_QP Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &qp);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_SESSION_QP Failed\n",
+					__func__);
+			return false;
+		} else {
+			session_qp->iframeqp = qp.i_frame_qp;
+			session_qp->pframqp = qp.p_frame_qp;
+		}
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_intraperiod(struct video_client_ctx *client_ctx,
+		struct venc_intraperiod *intraperiod,	u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_i_period period;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !intraperiod)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_i_period);
+
+	if (set_flag) {
+		period.p_frames = intraperiod->num_pframes;
+		period.b_frames = intraperiod->num_bframes;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &period);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_INTRA_PERIOD Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &period);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_INTRA_PERIOD Failed\n",
+					__func__);
+			return false;
+		} else
+			intraperiod->num_pframes = period.p_frames;
+	}
+	return true;
+}
+
+u32 vid_enc_request_iframe(struct video_client_ctx *client_ctx)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_req_i_frame request;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_REQ_IFRAME;
+	vcd_property_hdr.sz =
+				sizeof(struct vcd_property_req_i_frame);
+	request.req_i_frame = 1;
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &request);
+
+	if (vcd_status) {
+		ERR("%s(): Set VCD_I_REQ_IFRAME Failed\n",
+				__func__);
+		return false;
+	}
+	return status;
+}
+
+u32 vid_enc_get_sequence_header(struct video_client_ctx *client_ctx,
+		struct venc_seqheader	*seq_header)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_sequence_hdr hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx ||
+			!seq_header || !seq_header->bufsize)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_SEQ_HEADER;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_sequence_hdr);
+
+	hdr.sequence_header =
+		kzalloc(seq_header->bufsize, GFP_KERNEL);
+	seq_header->hdrbufptr = hdr.sequence_header;
+
+	if (!hdr.sequence_header)
+		return false;
+	hdr.sequence_header_len = seq_header->bufsize;
+	vcd_status = vcd_get_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &hdr);
+
+	if (vcd_status) {
+		ERR("%s(): Get VCD_I_SEQ_HEADER Failed\n",
+				__func__);
+		status = false;
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_entropy_cfg(struct video_client_ctx *client_ctx,
+		struct venc_entropycfg *entropy_cfg, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_entropy_control control;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !entropy_cfg)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_entropy_control);
+	if (set_flag) {
+		switch (entropy_cfg->longentropysel) {
+		case VEN_ENTROPY_MODEL_CAVLC:
+			control.entropy_sel = VCD_ENTROPY_SEL_CAVLC;
+			break;
+		case VEN_ENTROPY_MODEL_CABAC:
+			control.entropy_sel = VCD_ENTROPY_SEL_CABAC;
+			break;
+		default:
+			status = false;
+			break;
+		}
+
+		if (status && entropy_cfg->cabacmodel ==
+				VCD_ENTROPY_SEL_CABAC) {
+			switch (entropy_cfg->cabacmodel) {
+			case VEN_CABAC_MODEL_0:
+				control.cabac_model =
+					VCD_CABAC_MODEL_NUMBER_0;
+				break;
+			case VEN_CABAC_MODEL_1:
+				control.cabac_model =
+					VCD_CABAC_MODEL_NUMBER_1;
+				break;
+			case VEN_CABAC_MODEL_2:
+				control.cabac_model =
+					VCD_CABAC_MODEL_NUMBER_2;
+				break;
+			default:
+				status = false;
+				break;
+			}
+		}
+		if (status) {
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &control);
+
+			if (vcd_status) {
+				ERR("%s(): Set VCD_I_ENTROPY_CTRL Failed\n",
+						__func__);
+				status = false;
+			}
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &control);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_ENTROPY_CTRL Failed\n",
+					__func__);
+			status = false;
+		} else {
+			switch (control.entropy_sel) {
+			case VCD_ENTROPY_SEL_CABAC:
+				entropy_cfg->cabacmodel =
+					VEN_ENTROPY_MODEL_CABAC;
+				break;
+			case VCD_ENTROPY_SEL_CAVLC:
+				entropy_cfg->cabacmodel =
+					VEN_ENTROPY_MODEL_CAVLC;
+				break;
+			default:
+				status = false;
+				break;
+			}
+
+			if (status && control.entropy_sel ==
+					VCD_ENTROPY_SEL_CABAC) {
+				switch (control.cabac_model) {
+				case VCD_CABAC_MODEL_NUMBER_0:
+					entropy_cfg->cabacmodel =
+						VEN_CABAC_MODEL_0;
+					break;
+				case VCD_CABAC_MODEL_NUMBER_1:
+					entropy_cfg->cabacmodel =
+						VEN_CABAC_MODEL_1;
+					break;
+				case VCD_CABAC_MODEL_NUMBER_2:
+					entropy_cfg->cabacmodel =
+						VEN_CABAC_MODEL_2;
+					break;
+				default:
+					status = false;
+					break;
+				}
+			}
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_dbcfg(struct video_client_ctx *client_ctx,
+		struct venc_dbcfg *dbcfg, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_db_config control;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !dbcfg)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_DEBLOCKING;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_db_config);
+
+	if (set_flag) {
+		switch (dbcfg->db_mode) {
+		case VEN_DB_DISABLE:
+			control.db_config = VCD_DB_DISABLE;
+			break;
+		case VEN_DB_ALL_BLKG_BNDRY:
+			control.db_config = VCD_DB_ALL_BLOCKING_BOUNDARY;
+			break;
+		case VEN_DB_SKIP_SLICE_BNDRY:
+			control.db_config = VCD_DB_SKIP_SLICE_BOUNDARY;
+			break;
+		default:
+			status = false;
+			break;
+		}
+
+		if (status) {
+			control.slice_alpha_offset =
+				dbcfg->slicealpha_offset;
+			control.slice_beta_offset =
+				dbcfg->slicebeta_offset;
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &control);
+			if (vcd_status) {
+				ERR("%s(): Set VCD_I_DEBLOCKING Failed\n",
+						__func__);
+				status = false;
+			}
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &control);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_DEBLOCKING Failed\n",
+					__func__);
+			status = false;
+		} else {
+			switch (control.db_config) {
+			case VCD_DB_ALL_BLOCKING_BOUNDARY:
+				dbcfg->db_mode = VEN_DB_ALL_BLKG_BNDRY;
+				break;
+			case VCD_DB_DISABLE:
+				dbcfg->db_mode = VEN_DB_DISABLE;
+				break;
+			case VCD_DB_SKIP_SLICE_BOUNDARY:
+				dbcfg->db_mode = VEN_DB_SKIP_SLICE_BNDRY;
+				break;
+			default:
+				status = false;
+				break;
+			}
+			dbcfg->slicealpha_offset =
+				control.slice_alpha_offset;
+			dbcfg->slicebeta_offset =
+				control.slice_beta_offset;
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_intrarefresh(struct video_client_ctx *client_ctx,
+		struct venc_intrarefresh *intrarefresh, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_intra_refresh_mb_number control;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !intrarefresh)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_intra_refresh_mb_number);
+
+	if (set_flag) {
+		control.cir_mb_number = intrarefresh->mbcount;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &control);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_INTRA_REFRESH Failed\n",
+					__func__);
+			return false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &control);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_INTRA_REFRESH Failed\n",
+					__func__);
+			return false;
+		} else
+			intrarefresh->mbcount = control.cir_mb_number;
+	}
+	return true;
+}
+
+u32 vid_enc_set_get_multiclicecfg(struct video_client_ctx *client_ctx,
+		struct venc_multiclicecfg *multiclicecfg,	u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_multi_slice control;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !multiclicecfg)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_multi_slice);
+
+	if (set_flag) {
+		switch (multiclicecfg->mslice_mode) {
+		case VEN_MSLICE_OFF:
+			control.m_slice_sel =
+				VCD_MSLICE_OFF;
+			break;
+		case VEN_MSLICE_CNT_MB:
+			control.m_slice_sel =
+				VCD_MSLICE_BY_MB_COUNT;
+			break;
+		case VEN_MSLICE_CNT_BYTE:
+			control.m_slice_sel =
+				VCD_MSLICE_BY_BYTE_COUNT;
+			break;
+		case VEN_MSLICE_GOB:
+			control.m_slice_sel =
+				VCD_MSLICE_BY_GOB;
+			break;
+		default:
+			status = false;
+			break;
+		}
+
+		if (status) {
+			control.m_slice_size =
+				multiclicecfg->mslice_size;
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &control);
+
+			if (vcd_status) {
+				ERR("%s(): Set VCD_I_MULTI_SLICE Failed\n",
+						__func__);
+				status = false;
+			}
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &control);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_MULTI_SLICE Failed\n",
+					__func__);
+			status = false;
+		} else {
+			multiclicecfg->mslice_size =
+				control.m_slice_size;
+			switch (control.m_slice_sel) {
+			case VCD_MSLICE_OFF:
+				multiclicecfg->mslice_mode = VEN_MSLICE_OFF;
+				break;
+			case VCD_MSLICE_BY_MB_COUNT:
+				multiclicecfg->mslice_mode = VEN_MSLICE_CNT_MB;
+				break;
+			case VCD_MSLICE_BY_BYTE_COUNT:
+				multiclicecfg->mslice_mode =
+					VEN_MSLICE_CNT_BYTE;
+				break;
+			case VCD_MSLICE_BY_GOB:
+				multiclicecfg->mslice_mode =
+					VEN_MSLICE_GOB;
+				break;
+			default:
+				status = false;
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_ratectrlcfg(struct video_client_ctx *client_ctx,
+		struct venc_ratectrlcfg *ratectrlcfg,	u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_rate_control control;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !ratectrlcfg)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_rate_control);
+
+	if (set_flag) {
+		switch (ratectrlcfg->rcmode) {
+		case VEN_RC_OFF:
+			control.rate_control = VCD_RATE_CONTROL_OFF;
+			break;
+		case VEN_RC_CBR_VFR:
+			control.rate_control = VCD_RATE_CONTROL_CBR_VFR;
+			break;
+		case VEN_RC_VBR_CFR:
+			control.rate_control = VCD_RATE_CONTROL_VBR_CFR;
+			break;
+		case VEN_RC_VBR_VFR:
+			control.rate_control = VCD_RATE_CONTROL_VBR_VFR;
+			break;
+		case VEN_RC_CBR_CFR:
+			control.rate_control = VCD_RATE_CONTROL_CBR_CFR;
+			break;
+		default:
+			status = false;
+			break;
+		}
+
+		if (status) {
+			vcd_status = vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &control);
+			if (vcd_status) {
+				ERR("%s(): Set VCD_I_RATE_CONTROL Failed\n",
+						__func__);
+				status = false;
+			}
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+		&vcd_property_hdr, &control);
+
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_RATE_CONTROL Failed\n",
+					__func__);
+			status = false;
+		} else {
+			switch (control.rate_control) {
+			case VCD_RATE_CONTROL_OFF:
+				ratectrlcfg->rcmode = VEN_RC_OFF;
+				break;
+			case VCD_RATE_CONTROL_CBR_VFR:
+				ratectrlcfg->rcmode = VEN_RC_CBR_VFR;
+				break;
+			case VCD_RATE_CONTROL_VBR_CFR:
+				ratectrlcfg->rcmode = VEN_RC_VBR_CFR;
+				break;
+			case VCD_RATE_CONTROL_VBR_VFR:
+				ratectrlcfg->rcmode = VEN_RC_VBR_VFR;
+				break;
+			case VCD_RATE_CONTROL_CBR_CFR:
+				ratectrlcfg->rcmode = VEN_RC_CBR_CFR;
+				break;
+			default:
+				status = false;
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_voptimingcfg(struct video_client_ctx *client_ctx,
+		struct	venc_voptimingcfg *voptimingcfg, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_vop_timing control;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !voptimingcfg)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_VOP_TIMING;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_vop_timing);
+
+	if (set_flag) {
+		control.vop_time_resolution =
+		voptimingcfg->voptime_resolution;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+		&vcd_property_hdr, &control);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_VOP_TIMING Failed\n",
+					__func__);
+			status = false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+		&vcd_property_hdr, &control);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_VOP_TIMING Failed\n",
+					__func__);
+			status = false;
+		} else
+			voptimingcfg->voptime_resolution =
+			control.vop_time_resolution;
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_headerextension(struct video_client_ctx *client_ctx,
+		struct venc_headerextension *headerextension, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 control;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !headerextension)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_HEADER_EXTENSION;
+	vcd_property_hdr.sz = sizeof(u32);
+
+	if (set_flag) {
+		control = headerextension->header_extension;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+		&vcd_property_hdr, &control);
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_HEADER_EXTENSION Failed\n",
+					__func__);
+			status = false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+		&vcd_property_hdr, &control);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_HEADER_EXTENSION Failed\n",
+					__func__);
+			status = false;
+		} else {
+			headerextension->header_extension = control;
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_set_get_qprange(struct video_client_ctx *client_ctx,
+		struct venc_qprange *qprange, u32 set_flag)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_qp_range control;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 status = true;
+
+	if (!client_ctx || !qprange)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_QP_RANGE;
+	vcd_property_hdr.sz =
+		sizeof(struct vcd_property_qp_range);
+
+	if (set_flag) {
+		control.max_qp = qprange->maxqp;
+		control.min_qp = qprange->minqp;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+		&vcd_property_hdr, &control);
+
+		if (vcd_status) {
+			ERR("%s(): Set VCD_I_QP_RANGE Failed\n",
+					__func__);
+			status = false;
+		}
+	} else {
+		vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &control);
+		if (vcd_status) {
+			ERR("%s(): Get VCD_I_QP_RANGE Failed\n",
+					__func__);
+			status = false;
+		} else {
+			qprange->maxqp = control.max_qp;
+			qprange->minqp = control.min_qp;
+		}
+	}
+	return status;
+}
+
+u32 vid_enc_start_stop(struct video_client_ctx *client_ctx, u32 start)
+{
+	u32 vcd_status;
+
+	if (!client_ctx)
+		return false;
+
+	if (start) {
+			vcd_status = vcd_encode_start(client_ctx->vcd_handle);
+
+			if (vcd_status) {
+				ERR("%s(): vcd_encode_start failed."
+				" vcd_status = %u\n", __func__, vcd_status);
+				return false;
+			}
+	} else {
+		vcd_status = vcd_stop(client_ctx->vcd_handle);
+		if (vcd_status) {
+			ERR("%s(): vcd_stop failed.  vcd_status = %u\n",
+		__func__, vcd_status);
+			return false;
+		}
+		DBG("Send STOP_DONE message to client = %p\n",
+				client_ctx);
+	}
+	return true;
+}
+
+u32 vid_enc_pause_resume(struct video_client_ctx *client_ctx, u32 pause)
+{
+	u32 vcd_status;
+
+	if (!client_ctx)
+		return false;
+
+	if (pause) {
+		DBG("PAUSE command from client = %p\n",
+				client_ctx);
+		vcd_status = vcd_pause(client_ctx->vcd_handle);
+	} else {
+		DBG("Resume command from client = %p\n",
+				client_ctx);
+		vcd_status = vcd_resume(client_ctx->vcd_handle);
+	}
+
+	if (vcd_status)
+		return false;
+
+	return true;
+}
+
+u32 vid_enc_flush(struct video_client_ctx *client_ctx,
+		struct venc_bufferflush *bufferflush)
+{
+	u32 status = true, mode, vcd_status;
+
+	if (!client_ctx || !bufferflush)
+		return false;
+
+	switch (bufferflush->flush_mode) {
+	case VEN_FLUSH_INPUT:
+		mode = VCD_FLUSH_INPUT;
+		break;
+	case VEN_FLUSH_OUTPUT:
+		mode = VCD_FLUSH_OUTPUT;
+		break;
+	case VEN_FLUSH_ALL:
+		mode = VCD_FLUSH_ALL;
+		break;
+	default:
+		status = false;
+		break;
+	}
+	if (status) {
+		vcd_status = vcd_flush(client_ctx->vcd_handle, mode);
+		if (vcd_status)
+			status = false;
+	}
+	return status;
+}
+
+u32 vid_enc_get_buffer_req(struct video_client_ctx *client_ctx,
+		struct venc_allocatorproperty *venc_buf_req, u32 input_dir)
+{
+	enum vcd_buffer_type buffer;
+	struct vcd_buffer_requirement buffer_req;
+	u32 status = true;
+	u32 vcd_status;
+
+	if (!client_ctx || !venc_buf_req)
+		return false;
+
+	buffer = VCD_BUFFER_OUTPUT;
+	if (input_dir)
+		buffer = VCD_BUFFER_INPUT;
+
+	vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+							buffer, &buffer_req);
+
+	if (vcd_status)
+		status = false;
+
+	if (status) {
+		venc_buf_req->actualcount = buffer_req.actual_count;
+		venc_buf_req->alignment = buffer_req.align;
+		venc_buf_req->datasize = buffer_req.sz;
+		venc_buf_req->mincount = buffer_req.min_count;
+		venc_buf_req->maxcount = buffer_req.max_count;
+		venc_buf_req->alignment = buffer_req.align;
+		venc_buf_req->bufpoolid = buffer_req.buf_pool_id;
+		venc_buf_req->suffixsize = 0;
+	}
+	return status;
+}
+
+u32 vid_enc_set_buffer_req(struct video_client_ctx *client_ctx,
+		struct venc_allocatorproperty *venc_buf_req, u32 input_dir)
+{
+	enum vcd_buffer_type buffer;
+	struct vcd_buffer_requirement buffer_req;
+	u32 status = true;
+	u32 vcd_status;
+
+	if (!client_ctx || !venc_buf_req)
+		return false;
+
+	buffer = VCD_BUFFER_OUTPUT;
+	if (input_dir)
+		buffer = VCD_BUFFER_INPUT;
+
+	buffer_req.actual_count = venc_buf_req->actualcount;
+	buffer_req.align = venc_buf_req->alignment;
+	buffer_req.sz = venc_buf_req->datasize;
+	buffer_req.min_count = venc_buf_req->mincount;
+	buffer_req.max_count = venc_buf_req->maxcount;
+	buffer_req.align = venc_buf_req->alignment;
+	buffer_req.buf_pool_id = 0;
+
+	vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle,
+				buffer, &buffer_req);
+
+	if (vcd_status)
+		status = false;
+	return status;
+}
+
+u32 vid_enc_set_buffer(struct video_client_ctx *client_ctx,
+		struct venc_bufferpayload *buffer_info,
+		enum venc_buffer_dir buffer)
+{
+	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;
+
+	if (!client_ctx || !buffer_info)
+		return false;
+
+	if (buffer == VEN_BUFFER_TYPE_OUTPUT) {
+		dir_buffer = BUFFER_TYPE_OUTPUT;
+		vcd_buffer_t = VCD_BUFFER_OUTPUT;
+	}
+
+	/*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)) {
+		DBG("%s() : user_virt_addr = %p cannot be set.",
+		    __func__, buffer_info->pbuffer);
+		return false;
+	}
+
+	vcd_status = vcd_set_buffer(client_ctx->vcd_handle,
+				    vcd_buffer_t, (u8 *) kernel_vaddr,
+				    buffer_info->sz);
+
+	if (!vcd_status)
+		return true;
+	else
+		return false;
+}
+
+u32 vid_enc_free_buffer(struct video_client_ctx *client_ctx,
+		struct venc_bufferpayload *buffer_info,
+		enum venc_buffer_dir buffer)
+{
+	enum vcd_buffer_type buffer_vcd = VCD_BUFFER_INPUT;
+	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
+	u32 vcd_status = VCD_ERR_FAIL;
+	unsigned long kernel_vaddr;
+
+	if (!client_ctx || !buffer_info)
+		return false;
+
+	if (buffer == VEN_BUFFER_TYPE_OUTPUT) {
+		dir_buffer = BUFFER_TYPE_OUTPUT;
+		buffer_vcd = VCD_BUFFER_OUTPUT;
+	}
+	/*If buffer NOT set, ignore */
+	if (!vidc_delete_addr_table(client_ctx, dir_buffer,
+				(unsigned long)buffer_info->pbuffer,
+				&kernel_vaddr)) {
+		DBG("%s() : user_virt_addr = %p has not been set.",
+		    __func__, buffer_info->pbuffer);
+		return true;
+	}
+
+	vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer_vcd,
+					 (u8 *)kernel_vaddr);
+
+	if (!vcd_status)
+		return true;
+	else
+		return false;
+}
+
+u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx,
+		struct venc_buffer *input_frame_info)
+{
+	struct vcd_frame_data vcd_input_buffer;
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !input_frame_info)
+		return false;
+
+	user_vaddr = (unsigned long)input_frame_info->ptrbuffer;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+			true, &user_vaddr, &kernel_vaddr,
+			&phy_addr, &pmem_fd, &file,
+			&buffer_index)) {
+
+		/* kernel_vaddr  is found. send the frame to VCD */
+		memset((void *)&vcd_input_buffer, 0,
+					sizeof(struct vcd_frame_data));
+
+		vcd_input_buffer.virtual =
+		(u8 *) (kernel_vaddr + input_frame_info->offset);
+
+		vcd_input_buffer.offset = input_frame_info->offset;
+		vcd_input_buffer.frm_clnt_data =
+				(u32) input_frame_info->clientdata;
+		vcd_input_buffer.ip_frm_tag =
+				(u32) input_frame_info->clientdata;
+		vcd_input_buffer.data_len = input_frame_info->len;
+		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_status = vcd_encode_frame(client_ctx->vcd_handle,
+		&vcd_input_buffer);
+		if (!vcd_status)
+			return true;
+		else {
+			ERR("%s(): vcd_encode_frame failed = %u\n",
+			__func__, vcd_status);
+			return false;
+		}
+
+	} else {
+		ERR("%s(): kernel_vaddr not found\n",
+				__func__);
+		return false;
+	}
+}
+
+u32 vid_enc_fill_output_buffer(struct video_client_ctx *client_ctx,
+		struct venc_buffer *output_frame_info)
+{
+	unsigned long kernel_vaddr, phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	struct vcd_frame_data vcd_frame;
+
+	if (!client_ctx || !output_frame_info)
+		return false;
+
+	user_vaddr = (unsigned long)output_frame_info->ptrbuffer;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+			true, &user_vaddr, &kernel_vaddr,
+			&phy_addr, &pmem_fd, &file,
+			&buffer_index)) {
+
+		memset((void *)&vcd_frame, 0,
+					 sizeof(struct vcd_frame_data));
+		vcd_frame.virtual = (u8 *) kernel_vaddr;
+		vcd_frame.frm_clnt_data = (u32) output_frame_info->clientdata;
+		vcd_frame.alloc_len = output_frame_info->sz;
+
+		vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle,
+								&vcd_frame);
+		if (!vcd_status)
+			return true;
+		else {
+			ERR("%s(): vcd_fill_output_buffer failed = %u\n",
+					__func__, vcd_status);
+			return false;
+		}
+	} else {
+		ERR("%s(): kernel_vaddr not found\n", __func__);
+		return false;
+	}
+}
+u32 vid_enc_set_recon_buffers(struct video_client_ctx *client_ctx,
+		struct venc_recon_addr *venc_recon)
+{
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 len;
+	struct file *file;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_enc_recon_buffer control;
+
+	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;
+		}
+		put_pmem_file(file);
+		DBG("Virt: %p, Phys %p, fd: %d", control.kernel_virtual_addr,
+			control.physical_addr, control.pmem_fd);
+
+		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;
+		}
+}
+
+u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx)
+{
+	u32 vcd_status = VCD_ERR_FAIL;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_enc_recon_buffer control;
+
+	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);
+	return true;
+}
+
+u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx,
+		struct venc_recon_buff_size *venc_recon_size)
+{
+	u32 vcd_status = VCD_ERR_FAIL;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_size control;
+
+	control.width = venc_recon_size->width;
+	control.height = venc_recon_size->height;
+
+	vcd_property_hdr.prop_id = VCD_I_GET_RECON_BUFFER_SIZE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
+
+	vcd_status = vcd_get_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &control);
+
+	venc_recon_size->width = control.width;
+	venc_recon_size->height = control.height;
+	venc_recon_size->size = control.size;
+	venc_recon_size->alignment = control.alignment;
+	DBG("W: %d, H: %d, S: %d, A: %d", venc_recon_size->width,
+			venc_recon_size->height, venc_recon_size->size,
+			venc_recon_size->alignment);
+
+	if (!vcd_status) {
+		DBG("vcd_set_property returned success\n");
+		return true;
+		} else {
+			ERR("%s(): vid_enc_get_recon_buffer_size failed = %u\n",
+				__func__, vcd_status);
+			return false;
+		}
+}
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
new file mode 100644
index 0000000..7d4ebca
--- /dev/null
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -0,0 +1,151 @@
+/* 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 VENC_INTERNAL_H
+#define VENC_INTERNAL_H
+
+#include <linux/msm_vidc_enc.h>
+#include <linux/cdev.h>
+
+#include "vidc_init.h"
+
+#define VID_ENC_MAX_NUM_OF_BUFF 100
+
+enum venc_buffer_dir{
+  VEN_BUFFER_TYPE_INPUT,
+  VEN_BUFFER_TYPE_OUTPUT
+};
+
+struct vid_enc_msg {
+	struct list_head list;
+	struct venc_msg venc_msg_info;
+};
+
+struct vid_enc_dev {
+
+	struct cdev cdev;
+	struct device *device;
+	resource_size_t phys_base;
+	void __iomem *virt_base;
+	unsigned int irq;
+	struct clk *hclk;
+	struct clk *hclk_div2;
+	struct clk *pclk;
+	unsigned long hclk_rate;
+	struct mutex lock;
+	s32 device_handle;
+	struct video_client_ctx venc_clients[VIDC_MAX_NUM_CLIENTS];
+	u32 num_clients;
+};
+
+u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx,
+		struct venc_basecfg *base_config, u32 set_flag);
+
+u32 vid_enc_set_get_inputformat(struct video_client_ctx *client_ctx,
+		u32 *input_format, u32 set_flag);
+
+u32 vid_enc_set_get_codec(struct video_client_ctx *client_ctx, u32 *codec,
+		u32 set_flag);
+
+u32 vid_enc_set_get_framesize(struct video_client_ctx *client_ctx,
+		u32 *height, u32 *width, u32 set_flag);
+
+u32 vid_enc_set_get_bitrate(struct video_client_ctx *client_ctx,
+		struct venc_targetbitrate *venc_bitrate, u32 set_flag);
+
+u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx,
+		struct venc_framerate *frame_rate, u32 set_flag);
+
+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_short_header(struct video_client_ctx *client_ctx,
+		struct venc_switch *encoder_switch, u32 set_flag);
+
+u32 vid_enc_set_get_profile(struct video_client_ctx *client_ctx,
+		struct venc_profile *profile, u32 set_flag);
+
+u32 vid_enc_set_get_profile_level(struct video_client_ctx *client_ctx,
+		struct ven_profilelevel *profile_level, u32 set_flag);
+
+u32 vid_enc_set_get_session_qp(struct video_client_ctx *client_ctx,
+		struct venc_sessionqp *session_qp, u32 set_flag);
+
+u32 vid_enc_set_get_intraperiod(struct video_client_ctx *client_ctx,
+		struct venc_intraperiod *intraperiod, u32 set_flag);
+
+u32 vid_enc_request_iframe(struct video_client_ctx *client_ctx);
+
+u32 vid_enc_get_sequence_header(struct video_client_ctx *client_ctx,
+		struct venc_seqheader *seq_header);
+
+u32 vid_enc_set_get_entropy_cfg(struct video_client_ctx *client_ctx,
+		struct venc_entropycfg *entropy_cfg, u32 set_flag);
+
+u32 vid_enc_set_get_dbcfg(struct video_client_ctx *client_ctx,
+		struct venc_dbcfg *dbcfg, u32 set_flag);
+
+u32 vid_enc_set_get_intrarefresh(struct video_client_ctx *client_ctx,
+		struct venc_intrarefresh *intrarefresh,	u32 set_flag);
+
+u32 vid_enc_set_get_multiclicecfg(struct video_client_ctx *client_ctx,
+		struct venc_multiclicecfg *multiclicecfg, u32 set_flag);
+
+u32 vid_enc_set_get_ratectrlcfg(struct video_client_ctx *client_ctx,
+		struct venc_ratectrlcfg *ratectrlcfg, u32 set_flag);
+
+u32 vid_enc_set_get_voptimingcfg(struct video_client_ctx *client_ctx,
+		struct  venc_voptimingcfg *voptimingcfg, u32 set_flag);
+
+u32 vid_enc_set_get_headerextension(struct video_client_ctx *client_ctx,
+		struct venc_headerextension *headerextension, u32 set_flag);
+
+u32 vid_enc_set_get_qprange(struct video_client_ctx *client_ctx,
+		struct venc_qprange *qprange, u32 set_flag);
+
+u32 vid_enc_start_stop(struct video_client_ctx *client_ctx, u32 start);
+
+u32 vid_enc_pause_resume(struct video_client_ctx *client_ctx, u32 pause);
+
+u32 vid_enc_flush(struct video_client_ctx *client_ctx,
+		struct venc_bufferflush *bufferflush);
+
+u32 vid_enc_get_buffer_req(struct video_client_ctx *client_ctx,
+		struct venc_allocatorproperty *venc_buf_req, u32 input_dir);
+
+u32 vid_enc_set_buffer_req(struct video_client_ctx *client_ctx,
+		struct venc_allocatorproperty *venc_buf_req, u32 input_dir);
+
+u32 vid_enc_set_buffer(struct video_client_ctx *client_ctx,
+		struct venc_bufferpayload *buffer_info,
+		enum venc_buffer_dir buffer);
+
+u32 vid_enc_free_buffer(struct video_client_ctx *client_ctx,
+		struct venc_bufferpayload *buffer_info,
+		enum venc_buffer_dir buffer);
+
+u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx,
+		struct venc_buffer *input_frame_info);
+
+u32 vid_enc_fill_output_buffer(struct video_client_ctx *client_ctx,
+		struct venc_buffer *output_frame_info);
+
+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_get_recon_buffer_size(struct video_client_ctx *client_ctx,
+		struct venc_recon_buff_size *venc_recon_size);
+
+#endif
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
new file mode 100644
index 0000000..cda3a91
--- /dev/null
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -0,0 +1,620 @@
+/* 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 <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/android_pmem.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <mach/clk.h>
+#include <linux/pm_runtime.h>
+
+#include "vcd_api.h"
+#include "vidc_init_internal.h"
+#include "vidc_init.h"
+#include "vcd_res_tracker_api.h"
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+#define VIDC_NAME "msm_vidc_reg"
+
+#define ERR(x...) printk(KERN_ERR x)
+
+static struct vidc_dev *vidc_device_p;
+static dev_t vidc_dev_num;
+static struct class *vidc_class;
+
+static const struct file_operations vidc_fops = {
+	.owner = THIS_MODULE,
+	.open = NULL,
+	.release = NULL,
+	.unlocked_ioctl = NULL,
+};
+
+struct workqueue_struct *vidc_wq;
+struct workqueue_struct *vidc_timer_wq;
+static irqreturn_t vidc_isr(int irq, void *dev);
+static spinlock_t vidc_spin_lock;
+
+u32 vidc_msg_timing, vidc_msg_pmem;
+
+#ifdef VIDC_ENABLE_DBGFS
+struct dentry *vidc_debugfs_root;
+
+struct dentry *vidc_get_debugfs_root(void)
+{
+	if (vidc_debugfs_root == NULL)
+		vidc_debugfs_root = debugfs_create_dir("vidc", NULL);
+	return vidc_debugfs_root;
+}
+
+void vidc_debugfs_file_create(struct dentry *root, const char *name,
+				u32 *var)
+{
+	struct dentry *vidc_debugfs_file =
+	    debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
+	if (!vidc_debugfs_file)
+		ERR("%s(): Error creating/opening file %s\n", __func__, name);
+}
+#endif
+
+static void vidc_timer_fn(unsigned long data)
+{
+	unsigned long flag;
+	struct vidc_timer *hw_timer = NULL;
+	ERR("%s() Timer expired\n", __func__);
+	spin_lock_irqsave(&vidc_spin_lock, flag);
+	hw_timer = (struct vidc_timer *)data;
+	list_add_tail(&hw_timer->list, &vidc_device_p->vidc_timer_queue);
+	spin_unlock_irqrestore(&vidc_spin_lock, flag);
+	DBG("Queue the work for timer\n");
+	queue_work(vidc_timer_wq, &vidc_device_p->vidc_timer_worker);
+}
+
+static void vidc_timer_handler(struct work_struct *work)
+{
+	unsigned long flag = 0;
+	u32 islist_empty = 0;
+	struct vidc_timer *hw_timer = NULL;
+
+	ERR("%s() Timer expired\n", __func__);
+	do {
+		spin_lock_irqsave(&vidc_spin_lock, flag);
+		islist_empty = list_empty(&vidc_device_p->vidc_timer_queue);
+		if (!islist_empty) {
+			hw_timer = list_first_entry(
+				&vidc_device_p->vidc_timer_queue,
+				struct vidc_timer, list);
+			list_del(&hw_timer->list);
+		}
+		spin_unlock_irqrestore(&vidc_spin_lock, flag);
+		if (!islist_empty && hw_timer && hw_timer->cb_func)
+			hw_timer->cb_func(hw_timer->userdata);
+	} while (!islist_empty);
+}
+
+static void vidc_work_handler(struct work_struct *work)
+{
+	DBG("vidc_work_handler()");
+	vcd_read_and_clear_interrupt();
+	vcd_response_handler();
+	enable_irq(vidc_device_p->irq);
+	DBG("vidc_work_handler() done");
+}
+
+static DECLARE_WORK(vidc_work, vidc_work_handler);
+
+static int __devinit vidc_720p_probe(struct platform_device *pdev)
+{
+	struct resource *resource;
+	DBG("Enter %s()\n", __func__);
+
+	if (pdev->id) {
+		ERR("Invalid plaform device ID = %d\n", pdev->id);
+		return -EINVAL;
+	}
+	vidc_device_p->irq = platform_get_irq(pdev, 0);
+	if (unlikely(vidc_device_p->irq < 0)) {
+		ERR("%s(): Invalid irq = %d\n", __func__,
+					 vidc_device_p->irq);
+		return -ENXIO;
+	}
+
+	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (unlikely(!resource)) {
+		ERR("%s(): Invalid resource\n", __func__);
+		return -ENXIO;
+	}
+
+	vidc_device_p->phys_base = resource->start;
+	vidc_device_p->virt_base = ioremap(resource->start,
+	resource->end - resource->start + 1);
+
+	if (!vidc_device_p->virt_base) {
+		ERR("%s() : ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+	vidc_device_p->device = &pdev->dev;
+	mutex_init(&vidc_device_p->lock);
+
+	vidc_wq = create_singlethread_workqueue("vidc_worker_queue");
+	if (!vidc_wq) {
+		ERR("%s: create workque failed\n", __func__);
+		return -ENOMEM;
+	}
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	return 0;
+}
+
+static int __devexit vidc_720p_remove(struct platform_device *pdev)
+{
+	if (pdev->id) {
+		ERR("Invalid plaform device ID = %d\n", pdev->id);
+		return -EINVAL;
+	}
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static int vidc_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int vidc_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+
+static const struct dev_pm_ops vidc_dev_pm_ops = {
+	.runtime_suspend = vidc_runtime_suspend,
+	.runtime_resume = vidc_runtime_resume,
+};
+
+static struct platform_driver msm_vidc_720p_platform_driver = {
+	.probe = vidc_720p_probe,
+	.remove = vidc_720p_remove,
+	.driver = {
+		.name = "msm_vidc",
+		.pm   = &vidc_dev_pm_ops,
+	},
+};
+
+static void __exit vidc_exit(void)
+{
+	platform_driver_unregister(&msm_vidc_720p_platform_driver);
+}
+
+static irqreturn_t vidc_isr(int irq, void *dev)
+{
+	DBG("\n vidc_isr() %d ", irq);
+	disable_irq_nosync(irq);
+	queue_work(vidc_wq, &vidc_work);
+	return IRQ_HANDLED;
+}
+
+static int __init vidc_init(void)
+{
+	int rc = 0;
+	struct device *class_devp;
+#ifdef VIDC_ENABLE_DBGFS
+	struct dentry *root = NULL;
+#endif
+
+	vidc_device_p = kzalloc(sizeof(struct vidc_dev), GFP_KERNEL);
+	if (!vidc_device_p) {
+		ERR("%s Unable to allocate memory for vidc_dev\n",
+			__func__);
+		return -ENOMEM;
+	}
+
+	rc = alloc_chrdev_region(&vidc_dev_num, 0, 1, VIDC_NAME);
+	if (rc < 0) {
+		ERR("%s: alloc_chrdev_region Failed rc = %d\n",
+			__func__, rc);
+		goto error_vidc_alloc_chrdev_region;
+	}
+
+	vidc_class = class_create(THIS_MODULE, VIDC_NAME);
+	if (IS_ERR(vidc_class)) {
+		rc = PTR_ERR(vidc_class);
+		ERR("%s: couldn't create vidc_class rc = %d\n",
+		__func__, rc);
+
+		goto error_vidc_class_create;
+	}
+
+	class_devp = device_create(vidc_class, NULL, vidc_dev_num, NULL,
+					VIDC_NAME);
+
+	if (IS_ERR(class_devp)) {
+		rc = PTR_ERR(class_devp);
+		ERR("%s: class device_create failed %d\n",
+			__func__, rc);
+		goto error_vidc_class_device_create;
+	}
+
+	cdev_init(&vidc_device_p->cdev, &vidc_fops);
+	vidc_device_p->cdev.owner = THIS_MODULE;
+	rc = cdev_add(&(vidc_device_p->cdev), vidc_dev_num, 1);
+
+	if (rc < 0) {
+		ERR("%s: cdev_add failed %d\n", __func__, rc);
+		goto error_vidc_cdev_add;
+	}
+
+	rc = platform_driver_register(&msm_vidc_720p_platform_driver);
+	if (rc) {
+		ERR("%s failed to load\n", __func__);
+		goto error_vidc_platfom_register;
+	}
+
+	rc = request_irq(vidc_device_p->irq, vidc_isr, IRQF_TRIGGER_HIGH,
+			 "vidc", vidc_device_p->device);
+
+	if (unlikely(rc)) {
+		ERR("%s() :request_irq failed\n", __func__);
+		goto error_vidc_platfom_register;
+	}
+	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;
+	}
+	DBG("Disabling IRQ in %s()\n", __func__);
+	disable_irq_nosync(vidc_device_p->irq);
+	INIT_WORK(&vidc_device_p->vidc_timer_worker,
+			  vidc_timer_handler);
+	spin_lock_init(&vidc_spin_lock);
+	INIT_LIST_HEAD(&vidc_device_p->vidc_timer_queue);
+
+	vidc_device_p->ref_count = 0;
+	vidc_device_p->firmware_refcount = 0;
+	vidc_device_p->get_firmware = 0;
+#ifdef VIDC_ENABLE_DBGFS
+	root = vidc_get_debugfs_root();
+	if (root) {
+		vidc_debugfs_file_create(root, "vidc_msg_timing",
+				(u32 *) &vidc_msg_timing);
+		vidc_debugfs_file_create(root, "vidc_msg_pmem",
+				(u32 *) &vidc_msg_pmem);
+	}
+#endif
+	return 0;
+
+error_vidc_platfom_register:
+	cdev_del(&(vidc_device_p->cdev));
+error_vidc_cdev_add:
+	device_destroy(vidc_class, vidc_dev_num);
+error_vidc_class_device_create:
+	class_destroy(vidc_class);
+error_vidc_class_create:
+	unregister_chrdev_region(vidc_dev_num, 1);
+error_vidc_alloc_chrdev_region:
+	kfree(vidc_device_p);
+
+	return rc;
+}
+
+void __iomem *vidc_get_ioaddr(void)
+{
+	return (u8 *)vidc_device_p->virt_base;
+}
+EXPORT_SYMBOL(vidc_get_ioaddr);
+
+int vidc_load_firmware(void)
+{
+	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++;
+error:
+	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);
+}
+EXPORT_SYMBOL(vidc_release_firmware);
+
+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 num_of_buffers;
+	u32 i;
+	struct buf_addr_table *buf_addr_table;
+	u32 found = false;
+
+	if (!client_ctx)
+		return false;
+
+	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__);
+	}
+
+	for (i = 0; i < num_of_buffers; ++i) {
+		if (search_with_user_vaddr) {
+			if (*user_vaddr == buf_addr_table[i].user_vaddr) {
+				*kernel_vaddr = buf_addr_table[i].kernel_vaddr;
+				found = true;
+				DBG("%s() : client_ctx = %p."
+				" user_virt_addr = 0x%08lx is found",
+				__func__, client_ctx, *user_vaddr);
+				break;
+			}
+		} else {
+			if (*kernel_vaddr == buf_addr_table[i].kernel_vaddr) {
+				*user_vaddr = buf_addr_table[i].user_vaddr;
+				found = true;
+				DBG("%s() : client_ctx = %p."
+				" kernel_virt_addr = 0x%08lx is found",
+				__func__, client_ctx, *kernel_vaddr);
+				break;
+			}
+		}
+	}
+
+	if (found) {
+		*phy_addr = buf_addr_table[i].phy_addr;
+		*pmem_fd = buf_addr_table[i].pmem_fd;
+		*file = buf_addr_table[i].file;
+		*buffer_index = i;
+
+		if (search_with_user_vaddr)
+			DBG("kernel_vaddr = 0x%08lx, phy_addr = 0x%08lx "
+			" pmem_fd = %d, struct *file	= %p "
+			"buffer_index = %d\n", *kernel_vaddr,
+			*phy_addr, *pmem_fd, *file, *buffer_index);
+		else
+			DBG("user_vaddr = 0x%08lx, phy_addr = 0x%08lx "
+			" pmem_fd = %d, struct *file	= %p "
+			"buffer_index = %d\n", *user_vaddr, *phy_addr,
+			*pmem_fd, *file, *buffer_index);
+		return true;
+	} else {
+		if (search_with_user_vaddr)
+			DBG("%s() : client_ctx = %p user_virt_addr = 0x%08lx"
+			" Not Found.\n", __func__, client_ctx, *user_vaddr);
+		else
+			DBG("%s() : client_ctx = %p kernel_virt_addr = 0x%08lx"
+			" Not Found.\n", __func__, client_ctx,
+			*kernel_vaddr);
+		return false;
+	}
+}
+EXPORT_SYMBOL(vidc_lookup_addr_table);
+
+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 len, phys_addr;
+	struct file *file;
+	u32 *num_of_buffers = NULL;
+	u32 i;
+	struct buf_addr_table *buf_addr_table;
+
+	if (!client_ctx)
+		return false;
+
+	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);
+	}
+
+	if (*num_of_buffers == max_num_buffers) {
+		ERR("%s(): Num of buffers reached max value : %d",
+			__func__, max_num_buffers);
+		return false;
+	}
+
+	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);
+		return false;
+	} 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;
+		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;
+		*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);
+	}
+	return true;
+}
+EXPORT_SYMBOL(vidc_insert_addr_table);
+
+u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer,
+	unsigned long user_vaddr,
+	unsigned long *kernel_vaddr)
+{
+	u32 *num_of_buffers = NULL;
+	u32 i;
+	struct buf_addr_table *buf_addr_table;
+
+	if (!client_ctx)
+		return false;
+
+	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;
+
+	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 NOT found",
+			__func__, client_ctx, user_vaddr);
+		return false;
+	}
+	*kernel_vaddr = buf_addr_table[i].kernel_vaddr;
+	if (i < (*num_of_buffers - 1)) {
+		buf_addr_table[i].user_vaddr =
+			buf_addr_table[*num_of_buffers - 1].user_vaddr;
+		buf_addr_table[i].kernel_vaddr =
+			buf_addr_table[*num_of_buffers - 1].kernel_vaddr;
+		buf_addr_table[i].phy_addr =
+			buf_addr_table[*num_of_buffers - 1].phy_addr;
+		buf_addr_table[i].pmem_fd =
+			buf_addr_table[*num_of_buffers - 1].pmem_fd;
+		buf_addr_table[i].file =
+			buf_addr_table[*num_of_buffers - 1].file;
+	}
+	*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);
+	return true;
+}
+EXPORT_SYMBOL(vidc_delete_addr_table);
+
+u32 vidc_timer_create(void (*timer_handler)(void *),
+	void *user_data, void **timer_handle)
+{
+	struct vidc_timer *hw_timer = NULL;
+	if (!timer_handler || !timer_handle) {
+		DBG("%s(): timer creation failed\n ", __func__);
+		return false;
+	}
+	hw_timer = kzalloc(sizeof(struct vidc_timer), GFP_KERNEL);
+	if (!hw_timer) {
+		DBG("%s(): timer creation failed in allocation\n ", __func__);
+		return false;
+	}
+	init_timer(&hw_timer->hw_timeout);
+	hw_timer->hw_timeout.data = (unsigned long)hw_timer;
+	hw_timer->hw_timeout.function = vidc_timer_fn;
+	hw_timer->cb_func = timer_handler;
+	hw_timer->userdata = user_data;
+	*timer_handle = hw_timer;
+	return true;
+}
+EXPORT_SYMBOL(vidc_timer_create);
+
+void  vidc_timer_release(void *timer_handle)
+{
+	kfree(timer_handle);
+}
+EXPORT_SYMBOL(vidc_timer_release);
+
+void  vidc_timer_start(void *timer_handle, u32 time_out)
+{
+	struct vidc_timer *hw_timer = (struct vidc_timer *)timer_handle;
+	DBG("%s(): start timer\n ", __func__);
+	if (hw_timer) {
+		hw_timer->hw_timeout.expires = jiffies + 1*HZ;
+		add_timer(&hw_timer->hw_timeout);
+	}
+}
+EXPORT_SYMBOL(vidc_timer_start);
+
+void  vidc_timer_stop(void *timer_handle)
+{
+	struct vidc_timer *hw_timer = (struct vidc_timer *)timer_handle;
+	DBG("%s(): stop timer\n ", __func__);
+	if (hw_timer)
+		del_timer(&hw_timer->hw_timeout);
+}
+EXPORT_SYMBOL(vidc_timer_stop);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Video decoder/encoder driver Init Module");
+MODULE_VERSION("1.0");
+module_init(vidc_init);
+module_exit(vidc_exit);
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.h b/drivers/video/msm/vidc/common/init/vidc_init.h
new file mode 100644
index 0000000..c472718
--- /dev/null
+++ b/drivers/video/msm/vidc/common/init/vidc_init.h
@@ -0,0 +1,76 @@
+/* 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_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
new file mode 100644
index 0000000..1d903ad
--- /dev/null
+++ b/drivers/video/msm/vidc/common/init/vidc_init_internal.h
@@ -0,0 +1,41 @@
+/* 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_INIT_INTERNAL_H
+#define VIDC_INIT_INTERNAL_H
+
+#include <linux/cdev.h>
+
+struct vidc_timer {
+	struct list_head list;
+	struct timer_list hw_timeout;
+	void (*cb_func)(void *);
+	void *userdata;
+};
+
+struct vidc_dev {
+	struct cdev cdev;
+	struct device *device;
+	resource_size_t phys_base;
+	void __iomem *virt_base;
+	unsigned int irq;
+	unsigned int ref_count;
+	unsigned int firmware_refcount;
+	unsigned int get_firmware;
+	struct mutex lock;
+	s32 device_handle;
+	struct list_head vidc_timer_queue;
+	struct work_struct vidc_timer_worker;
+};
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd.h b/drivers/video/msm/vidc/common/vcd/vcd.h
new file mode 100644
index 0000000..b557752
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd.h
@@ -0,0 +1,393 @@
+/* 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 _VCD_H_
+#define _VCD_H_
+
+#include "vcd_api.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"
+
+void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt);
+
+u32 vcd_get_command_channel
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc);
+
+u32 vcd_get_command_channel_in_loop
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc);
+
+void vcd_mark_command_channel
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc);
+
+void vcd_release_command_channel
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc);
+
+void vcd_release_multiple_command_channels(struct vcd_dev_ctxt *dev_ctxt,
+		u32 channels);
+
+void vcd_release_interim_command_channels(struct vcd_dev_ctxt *dev_ctxt);
+
+u32 vcd_get_frame_channel
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc);
+
+u32 vcd_get_frame_channel_in_loop
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc);
+
+void vcd_mark_frame_channel(struct vcd_dev_ctxt *dev_ctxt);
+
+void vcd_release_frame_channel
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc);
+
+void vcd_release_multiple_frame_channels(struct vcd_dev_ctxt *dev_ctxt,
+		u32 channels);
+
+void vcd_release_interim_frame_channels(struct vcd_dev_ctxt *dev_ctxt);
+u32 vcd_core_is_busy(struct vcd_dev_ctxt *dev_ctxt);
+
+void vcd_device_timer_start(struct vcd_dev_ctxt *dev_ctxt);
+void vcd_device_timer_stop(struct vcd_dev_ctxt *dev_ctxt);
+
+
+u32 vcd_init_device_context
+    (struct vcd_drv_ctxt *drv_ctxt, u32 ev_code);
+
+u32 vcd_deinit_device_context
+    (struct vcd_drv_ctxt *drv_ctxt, u32 ev_code);
+
+u32 vcd_init_client_context(struct vcd_clnt_ctxt *cctxt);
+
+void vcd_destroy_client_context(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_check_for_client_context
+    (struct vcd_dev_ctxt *dev_ctxt, s32 driver_id);
+
+u32 vcd_validate_driver_handle
+    (struct vcd_dev_ctxt *dev_ctxt, s32 driver_handle);
+
+void vcd_handle_for_last_clnt_close
+	(struct vcd_dev_ctxt *dev_ctxt, u32 send_deinit);
+
+u32 vcd_common_allocate_set_buffer
+    (struct vcd_clnt_ctxt *cctxt,
+     enum vcd_buffer_type buffer,
+     u32 buf_size, struct vcd_buffer_pool **buf_pool);
+
+u32 vcd_set_buffer_internal
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_buffer_pool *buf_pool, u8 *buffer, u32 buf_size);
+
+u32 vcd_allocate_buffer_internal
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_buffer_pool *buf_pool,
+     u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr);
+
+u32 vcd_free_one_buffer_internal
+    (struct vcd_clnt_ctxt *cctxt,
+     enum vcd_buffer_type buffer_type, u8 *buffer);
+
+u32 vcd_free_buffers_internal
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_buffer_pool *buf_pool);
+
+u32 vcd_alloc_buffer_pool_entries
+    (struct vcd_buffer_pool *buf_pool,
+     struct vcd_buffer_requirement *buf_req);
+
+void vcd_free_buffer_pool_entries(struct vcd_buffer_pool *buf_pool);
+
+void vcd_flush_in_use_buffer_pool_entries(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_buffer_pool *buf_pool, u32 event);
+
+void vcd_reset_buffer_pool_for_reuse(struct vcd_buffer_pool *buf_pool);
+
+struct vcd_buffer_entry *vcd_get_free_buffer_pool_entry
+    (struct vcd_buffer_pool *pool);
+
+struct vcd_buffer_entry *vcd_find_buffer_pool_entry
+    (struct vcd_buffer_pool *pool, u8 *v_addr);
+
+struct vcd_buffer_entry *vcd_buffer_pool_entry_de_q
+    (struct vcd_buffer_pool *pool);
+
+u32 vcd_buffer_pool_entry_en_q
+    (struct vcd_buffer_pool *pool,
+     struct vcd_buffer_entry *entry);
+
+u32 vcd_check_if_buffer_req_met(struct vcd_clnt_ctxt *cctxt,
+	enum vcd_buffer_type buffer_type);
+
+u32 vcd_client_cmd_en_q
+    (struct vcd_clnt_ctxt *cctxt, enum vcd_command command);
+
+void vcd_client_cmd_flush_and_en_q
+    (struct vcd_clnt_ctxt *cctxt, enum vcd_command command);
+
+u32 vcd_client_cmd_de_q
+    (struct vcd_clnt_ctxt *cctxt, enum vcd_command *command);
+
+u32 vcd_handle_recvd_eos
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *input_frame, u32 * pb_eos_handled);
+
+u32 vcd_handle_first_decode_frame(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_handle_input_frame
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *input_frame);
+
+u32 vcd_store_seq_hdr
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_sequence_hdr *seq_hdr);
+
+u32 vcd_set_frame_size
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_property_frame_size *frm_size);
+
+u32 vcd_set_frame_rate
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_property_frame_rate *fps);
+
+u32 vcd_calculate_frame_delta
+    (struct vcd_clnt_ctxt *cctxt, struct vcd_frame_data *frame);
+
+struct vcd_buffer_entry *vcd_check_fill_output_buffer
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *buffer);
+
+u32 vcd_handle_first_fill_output_buffer
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *buffer, u32 *b_handled);
+
+u32 vcd_handle_first_fill_output_buffer_for_enc
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *frm_entry, u32 *b_handled);
+
+u32 vcd_handle_first_fill_output_buffer_for_dec
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *frm_entry, u32 *b_handled);
+
+u32 vcd_schedule_frame(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_clnt_ctxt **cctxt, struct vcd_buffer_entry
+	**ip_buf_entry);
+
+u32 vcd_submit_command_in_continue
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc);
+
+u32 vcd_submit_cmd_sess_start(struct vcd_transc *transc);
+
+u32 vcd_submit_cmd_sess_end(struct vcd_transc *transc);
+
+void vcd_submit_cmd_client_close(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_submit_frame
+    (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc);
+
+u32 vcd_try_submit_frame_in_continue(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_transc *transc);
+
+u32 vcd_process_cmd_sess_start(struct vcd_clnt_ctxt *cctxt);
+
+void vcd_try_submit_frame(struct vcd_dev_ctxt *dev_ctxt);
+
+u32 vcd_setup_with_ddl_capabilities(struct vcd_dev_ctxt *dev_ctxt);
+void vcd_handle_submit_frame_failed(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_transc *transc);
+
+struct vcd_transc *vcd_get_free_trans_tbl_entry
+    (struct vcd_dev_ctxt *dev_ctxt);
+
+void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry);
+
+void vcd_release_all_clnt_frm_transc(struct vcd_clnt_ctxt *cctxt);
+void vcd_release_all_clnt_transc(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_handle_input_done
+    (struct vcd_clnt_ctxt *cctxt,
+     void *payload, u32 event, u32 status);
+
+u32 vcd_handle_input_done_in_eos
+    (struct vcd_clnt_ctxt *cctxt, void *payload, u32 status);
+
+void vcd_handle_input_done_failed
+    (struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc);
+
+void vcd_handle_input_done_with_codec_config
+	(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_transc *transc,
+	struct ddl_frame_data_tag *frm);
+
+void vcd_handle_input_done_for_interlacing
+    (struct vcd_clnt_ctxt *cctxt);
+
+void vcd_handle_input_done_with_trans_end
+    (struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_handle_frame_done
+    (struct vcd_clnt_ctxt *cctxt,
+     void *payload, u32 event, u32 status);
+
+void vcd_handle_frame_done_for_interlacing
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_transc *transc_ip1,
+     struct ddl_frame_data_tag *op_frm, u32 status);
+
+
+u32 vcd_handle_frame_done_in_eos
+    (struct vcd_clnt_ctxt *cctxt, void *payload, u32 status);
+
+u32 vcd_handle_output_required(struct vcd_clnt_ctxt *cctxt,
+	void *payload, u32 status);
+
+u32 vcd_handle_output_required_in_flushing(struct vcd_clnt_ctxt *cctxt,
+	void *payload);
+
+u32 vcd_handle_output_req_tran_end_in_eos(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_validate_io_done_pyld
+	(struct vcd_clnt_ctxt *cctxt, void *payload, u32 status);
+
+void vcd_handle_eos_trans_end(struct vcd_clnt_ctxt *cctxt);
+
+
+void vcd_handle_eos_done
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_transc *transc, u32 status);
+
+void vcd_send_frame_done_in_eos
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *input_frame, u32 valid_opbuf);
+
+void vcd_send_frame_done_in_eos_for_dec
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *input_frame);
+
+void vcd_send_frame_done_in_eos_for_enc
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *input_frame);
+
+void vcd_handle_start_done(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_transc *transc, u32 status);
+
+void vcd_handle_stop_done(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_transc *transc, u32 status);
+
+void vcd_handle_stop_done_in_starting(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_transc *transc, u32 status);
+
+void vcd_handle_stop_done_in_invalid(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_transc *transc, u32 status);
+
+void vcd_send_flush_done(struct vcd_clnt_ctxt *cctxt, u32 status);
+
+void vcd_process_pending_flush_in_eos(struct vcd_clnt_ctxt *cctxt);
+
+void vcd_process_pending_stop_in_eos(struct vcd_clnt_ctxt *cctxt);
+
+void vcd_handle_trans_pending(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_handle_ind_output_reconfig
+    (struct vcd_clnt_ctxt *cctxt, void* payload, u32 status);
+
+u32 vcd_handle_ind_output_reconfig_in_flushing
+    (struct vcd_clnt_ctxt *cctxt, void* payload, u32 status);
+
+void vcd_flush_output_buffers(struct vcd_clnt_ctxt *cctxt);
+
+void vcd_flush_bframe_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode);
+
+u32 vcd_flush_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode);
+void vcd_flush_buffers_in_err_fatal(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_power_event
+    (struct vcd_dev_ctxt *dev_ctxt,
+     struct vcd_clnt_ctxt *cctxt, u32 event);
+
+u32 vcd_device_power_event(struct vcd_dev_ctxt *dev_ctxt, u32 event,
+	struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_client_power_event
+    (struct vcd_dev_ctxt *dev_ctxt,
+     struct vcd_clnt_ctxt *cctxt, u32 event);
+
+u32 vcd_enable_clock(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_disable_clock(struct vcd_dev_ctxt *dev_ctxt);
+
+u32 vcd_set_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl);
+
+u32 vcd_update_clnt_perf_lvl
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_property_frame_rate *fps, u32 frm_p_units);
+
+u32 vcd_gate_clock(struct vcd_dev_ctxt *dev_ctxt);
+
+u32 vcd_un_gate_clock(struct vcd_dev_ctxt *dev_ctxt);
+
+void vcd_handle_err_fatal(struct vcd_clnt_ctxt *cctxt,
+		u32 event, u32 status);
+
+void vcd_handle_device_err_fatal(struct vcd_dev_ctxt *dev_ctxt,
+		struct vcd_clnt_ctxt *cctxt);
+
+void vcd_clnt_handle_device_err_fatal(struct vcd_clnt_ctxt *cctxt,
+		u32 event);
+
+void vcd_handle_err_in_starting(struct vcd_clnt_ctxt *cctxt,
+		u32 status);
+
+void vcd_handle_ind_hw_err_fatal(struct vcd_clnt_ctxt *cctxt,
+		u32 event, u32 status);
+
+u32 vcd_return_op_buffer_to_hw(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_buffer_entry *buf_entry);
+
+u32 vcd_sched_create(struct list_head *sched_list);
+
+void vcd_sched_destroy(struct list_head *sched_clnt_list);
+
+u32 vcd_sched_add_client(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_sched_remove_client(struct vcd_sched_clnt_ctx *sched_cctxt);
+
+u32 vcd_sched_update_config(struct vcd_clnt_ctxt *cctxt);
+
+u32 vcd_sched_queue_buffer(
+	struct vcd_sched_clnt_ctx *sched_cctxt,
+	struct vcd_buffer_entry *buffer, u32 b_tail);
+
+u32 vcd_sched_dequeue_buffer(
+	struct vcd_sched_clnt_ctx *sched_cctxt,
+	struct vcd_buffer_entry **buffer);
+
+u32 vcd_sched_mark_client_eof(struct vcd_sched_clnt_ctx *sched_cctxt);
+
+u32 vcd_sched_suspend_resume_clnt(
+	struct vcd_clnt_ctxt *cctxt, u32 b_state);
+
+u32 vcd_sched_get_client_frame(struct list_head *sched_clnt_list,
+	struct vcd_clnt_ctxt **cctxt,
+	struct vcd_buffer_entry **buffer);
+
+void vcd_handle_clnt_fatal(struct vcd_clnt_ctxt *cctxt, u32 trans_end);
+
+void vcd_handle_clnt_fatal_input_done(struct vcd_clnt_ctxt *cctxt,
+	u32 trans_end);
+
+void vcd_handle_ind_info_output_reconfig
+	(struct vcd_clnt_ctxt *cctxt, u32 status);
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c
new file mode 100644
index 0000000..a57675e
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.c
@@ -0,0 +1,881 @@
+/* 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_type.h"
+#include "vcd.h"
+
+u32 vcd_init(struct vcd_init_config *config, s32 *driver_handle)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_drv_ctxt *drv_ctxt;
+
+	VCD_MSG_MED("vcd_init:");
+
+	if (!config ||
+	    !driver_handle || !config->map_dev_base_addr) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+	mutex_init(&drv_ctxt->dev_mutex);
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (drv_ctxt->dev_state.state_table->ev_hdlr.init) {
+		rc = drv_ctxt->dev_state.state_table->ev_hdlr.
+		    init(drv_ctxt, config, driver_handle);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in device state %d",
+			      drv_ctxt->dev_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_init);
+
+u32 vcd_term(s32 driver_handle)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_drv_ctxt *drv_ctxt;
+
+	VCD_MSG_MED("vcd_term:");
+
+	drv_ctxt = vcd_get_drv_context();
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (drv_ctxt->dev_state.state_table->ev_hdlr.term) {
+		rc = drv_ctxt->dev_state.state_table->ev_hdlr.
+		    term(drv_ctxt, driver_handle);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in device state %d",
+			      drv_ctxt->dev_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+	mutex_unlock(&drv_ctxt->dev_mutex);
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_term);
+
+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)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_drv_ctxt *drv_ctxt;
+
+	VCD_MSG_MED("vcd_open:");
+
+	if (!callback) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (drv_ctxt->dev_state.state_table->ev_hdlr.open) {
+		rc = drv_ctxt->dev_state.state_table->ev_hdlr.
+		    open(drv_ctxt, driver_handle, decoding, callback,
+			    client_data);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in device state %d",
+			      drv_ctxt->dev_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_open);
+
+u32 vcd_close(void *handle)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_close:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+	mutex_lock(&drv_ctxt->dev_mutex);
+	if (drv_ctxt->dev_state.state_table->ev_hdlr.close) {
+		rc = drv_ctxt->dev_state.state_table->ev_hdlr.
+		    close(drv_ctxt, cctxt);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in device state %d",
+			      drv_ctxt->dev_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+	mutex_unlock(&drv_ctxt->dev_mutex);
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_close);
+
+u32 vcd_encode_start(void *handle)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_encode_start:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.encode_start &&
+	    drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    encode_start(cctxt);
+	} else {
+		VCD_MSG_ERROR
+		    ("Unsupported API in dev power state %d OR client state %d",
+		     drv_ctxt->dev_ctxt.pwr_state,
+		     cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_encode_start);
+
+u32 vcd_encode_frame(void *handle, struct vcd_frame_data *input_frame)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_encode_frame:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!input_frame) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.encode_frame) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    encode_frame(cctxt, input_frame);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_encode_frame);
+
+u32 vcd_decode_start(void *handle, struct vcd_sequence_hdr *seq_hdr)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_decode_start:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.decode_start &&
+	    drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    decode_start(cctxt, seq_hdr);
+	} else {
+		VCD_MSG_ERROR
+		    ("Unsupported API in dev power state %d OR client state %d",
+		     drv_ctxt->dev_ctxt.pwr_state,
+		     cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_decode_start);
+
+u32 vcd_decode_frame(void *handle, struct vcd_frame_data *input_frame)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_decode_frame:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!input_frame) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.decode_frame) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    decode_frame(cctxt, input_frame);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_decode_frame);
+
+u32 vcd_pause(void *handle)
+{
+	struct vcd_drv_ctxt *drv_ctxt;
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_pause:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.pause) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    pause(cctxt);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_pause);
+
+u32 vcd_resume(void *handle)
+{
+	struct vcd_drv_ctxt *drv_ctxt;
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_resume:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (drv_ctxt->dev_state.state_table->ev_hdlr.resume &&
+	    drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) {
+		rc = drv_ctxt->dev_state.state_table->ev_hdlr.
+		    resume(drv_ctxt, cctxt);
+	} else {
+		VCD_MSG_ERROR
+		    ("Unsupported API in dev power state %d OR client state %d",
+		     drv_ctxt->dev_ctxt.pwr_state,
+		     cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_resume);
+
+u32 vcd_flush(void *handle, u32 mode)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_flush:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.flush) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    flush(cctxt, mode);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_flush);
+
+u32 vcd_stop(void *handle)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_stop:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.stop &&
+	    drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    stop(cctxt);
+	} else {
+		VCD_MSG_ERROR
+		    ("Unsupported API in dev power state %d OR client state %d",
+		     drv_ctxt->dev_ctxt.pwr_state,
+		     cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_stop);
+
+u32 vcd_set_property(void *handle,
+     struct vcd_property_hdr *prop_hdr, void *prop_val)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_set_property:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!prop_hdr || !prop_val) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.set_property) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    set_property(cctxt, prop_hdr, prop_val);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_set_property);
+
+u32 vcd_get_property(void *handle,
+     struct vcd_property_hdr *prop_hdr, void *prop_val)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_get_property:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!prop_hdr || !prop_val) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.get_property) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    get_property(cctxt, prop_hdr, prop_val);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_get_property);
+
+u32 vcd_set_buffer_requirements(void *handle,
+     enum vcd_buffer_type buffer,
+     struct vcd_buffer_requirement *buffer_req)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_set_buffer_requirements:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!buffer_req) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.
+	    set_buffer_requirements) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    set_buffer_requirements(cctxt, buffer, buffer_req);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_set_buffer_requirements);
+
+u32 vcd_get_buffer_requirements(void *handle,
+     enum vcd_buffer_type buffer,
+     struct vcd_buffer_requirement *buffer_req)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_get_buffer_requirements:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!buffer_req) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.
+	    get_buffer_requirements) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    get_buffer_requirements(cctxt, buffer, buffer_req);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_get_buffer_requirements);
+
+u32 vcd_set_buffer(void *handle,
+     enum vcd_buffer_type buffer_type, u8 *buffer, u32 buf_size)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_set_buffer:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!buffer || !buf_size) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.set_buffer) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    set_buffer(cctxt, buffer_type, buffer, buf_size);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_set_buffer);
+
+u32 vcd_allocate_buffer(void *handle,
+     enum vcd_buffer_type buffer,
+     u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_allocate_buffer:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!vir_buf_addr || !phy_buf_addr
+	    || !buf_size) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.allocate_buffer) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    allocate_buffer(cctxt, buffer, buf_size,
+				       vir_buf_addr, phy_buf_addr);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_allocate_buffer);
+
+u32 vcd_free_buffer(void *handle, enum vcd_buffer_type buffer_type, u8 *buffer)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_free_buffer:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.free_buffer) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    free_buffer(cctxt, buffer_type, buffer);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_free_buffer);
+
+u32 vcd_fill_output_buffer(void *handle, struct vcd_frame_data *buffer)
+{
+	struct vcd_clnt_ctxt *cctxt =
+	    (struct vcd_clnt_ctxt *)handle;
+	struct vcd_drv_ctxt *drv_ctxt;
+	u32 rc;
+
+	VCD_MSG_MED("vcd_fill_output_buffer:");
+
+	if (!cctxt || cctxt->signature != VCD_SIGNATURE) {
+		VCD_MSG_ERROR("Bad client handle");
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (!buffer) {
+		VCD_MSG_ERROR("Bad parameters");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.fill_output_buffer) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+		    fill_output_buffer(cctxt, buffer);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+			      cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_fill_output_buffer);
+
+u32 vcd_set_device_power(s32 driver_handle,
+		enum vcd_power_state pwr_state)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_drv_ctxt *drv_ctxt;
+
+	VCD_MSG_MED("vcd_set_device_power:");
+
+	drv_ctxt = vcd_get_drv_context();
+	mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (drv_ctxt->dev_state.state_table->ev_hdlr.set_dev_pwr) {
+		rc = drv_ctxt->dev_state.state_table->ev_hdlr.
+		    set_dev_pwr(drv_ctxt, pwr_state);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in device state %d",
+			      drv_ctxt->dev_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	mutex_unlock(&drv_ctxt->dev_mutex);
+
+	return rc;
+
+}
+EXPORT_SYMBOL(vcd_set_device_power);
+
+void vcd_read_and_clear_interrupt(void)
+{
+   VCD_MSG_LOW("vcd_read_and_clear_interrupt:");
+   ddl_read_and_clear_interrupt();
+}
+
+
+void vcd_response_handler(void)
+{
+	struct vcd_drv_ctxt *drv_ctxt;
+
+	VCD_MSG_LOW("vcd_response_handler:");
+  drv_ctxt = vcd_get_drv_context();
+
+  mutex_lock(&drv_ctxt->dev_mutex);
+
+	if (!ddl_process_core_response()) {
+		VCD_MSG_HIGH
+		    ("ddl_process_core_response indicated no further"
+		     "processing");
+    mutex_unlock(&drv_ctxt->dev_mutex);
+		return;
+	}
+
+	if (drv_ctxt->dev_ctxt.command_continue)
+		vcd_continue();
+	mutex_unlock(&drv_ctxt->dev_mutex);
+}
+EXPORT_SYMBOL(vcd_response_handler);
+
+u8 vcd_get_num_of_clients(void)
+{
+	struct vcd_drv_ctxt *drv_ctxt;
+	struct vcd_clnt_ctxt *cctxt;
+	u8 count = 0;
+
+	VCD_MSG_LOW("vcd_get_num_of_clients:");
+	drv_ctxt = vcd_get_drv_context();
+
+	mutex_lock(&drv_ctxt->dev_mutex);
+	cctxt = drv_ctxt->dev_ctxt.cctxt_list_head;
+	while (cctxt) {
+		count++;
+		cctxt = cctxt->next;
+	}
+	mutex_unlock(&drv_ctxt->dev_mutex);
+	return count;
+}
+EXPORT_SYMBOL(vcd_get_num_of_clients);
+
+
+
+
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.h b/drivers/video/msm/vidc/common/vcd/vcd_api.h
new file mode 100644
index 0000000..38ea202
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.h
@@ -0,0 +1,140 @@
+/* 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_API_H_
+#define _VCD_API_H_
+#include "vcd_property.h"
+#include "vcd_status.h"
+
+#define VCD_FRAME_FLAG_EOS 0x00000001
+#define VCD_FRAME_FLAG_DECODEONLY   0x00000004
+#define VCD_FRAME_FLAG_ENDOFFRAME 0x00000010
+#define VCD_FRAME_FLAG_SYNCFRAME 0x00000020
+#define VCD_FRAME_FLAG_EXTRADATA 0x00000040
+#define VCD_FRAME_FLAG_CODECCONFIG  0x00000080
+#define VCD_FRAME_FLAG_BFRAME 0x00100000
+
+#define VCD_FLUSH_INPUT   0x0001
+#define VCD_FLUSH_OUTPUT  0x0002
+#define VCD_FLUSH_ALL     0x0003
+
+#define VCD_FRAMETAG_INVALID  0xffffffff
+
+struct vcd_handle_container {
+	void *handle;
+};
+struct vcd_flush_cmd {
+	u32 mode;
+};
+
+enum vcd_frame {
+	VCD_FRAME_YUV = 1,
+	VCD_FRAME_I,
+	VCD_FRAME_P,
+	VCD_FRAME_B,
+	VCD_FRAME_NOTCODED,
+	VCD_FRAME_32BIT = 0x7fffffff
+};
+
+enum vcd_power_state {
+	VCD_PWR_STATE_ON = 1,
+	VCD_PWR_STATE_SLEEP,
+};
+
+struct vcd_frame_data {
+	u8 *virtual;
+	u8 *physical;
+	u32 alloc_len;
+	u32 data_len;
+	u32 offset;
+	s64 time_stamp;
+	u32 flags;
+	u32 frm_clnt_data;
+	struct vcd_property_dec_output_buffer dec_op_prop;
+	u32 interlaced;
+	enum vcd_frame frame;
+	u32 ip_frm_tag;
+	u32 intrlcd_ip_frm_tag;
+};
+
+struct vcd_sequence_hdr {
+	u8 *sequence_header;
+	u32 sequence_header_len;
+
+};
+
+enum vcd_buffer_type {
+	VCD_BUFFER_INPUT = 0x1,
+	VCD_BUFFER_OUTPUT = 0x2,
+	VCD_BUFFER_INVALID = 0x3,
+	VCD_BUFFER_32BIT = 0x7FFFFFFF
+};
+
+struct vcd_buffer_requirement {
+	u32 min_count;
+	u32 actual_count;
+	u32 max_count;
+	size_t sz;
+	u32 align;
+	u32 buf_pool_id;
+};
+
+struct vcd_init_config {
+	void *device_name;
+	void *(*map_dev_base_addr) (void *device_name);
+	void (*un_map_dev_base_addr) (void);
+	void (*interrupt_clr) (void);
+	void (*register_isr) (void *device_name);
+	void (*deregister_isr) (void);
+	u32  (*timer_create) (void (*timer_handler)(void *),
+		void *user_data, void **timer_handle);
+	void (*timer_release) (void *timer_handle);
+	void (*timer_start) (void *timer_handle, u32 time_out);
+	void (*timer_stop) (void *timer_handle);
+};
+
+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);
+u32 vcd_close(void *handle);
+u32 vcd_encode_start(void *handle);
+u32 vcd_encode_frame(void *handle, struct vcd_frame_data *input_frame);
+u32 vcd_decode_start(void *handle, struct vcd_sequence_hdr *seq_hdr);
+u32 vcd_decode_frame(void *handle, struct vcd_frame_data *input_frame);
+u32 vcd_pause(void *handle);
+u32 vcd_resume(void *handle);
+u32 vcd_flush(void *handle, u32 mode);
+u32 vcd_stop(void *handle);
+u32 vcd_set_property(void *handle, struct vcd_property_hdr *prop_hdr,
+					void *prop_val);
+u32 vcd_get_property(void *handle, struct vcd_property_hdr *prop_hdr,
+					 void *prop_val);
+u32 vcd_set_buffer_requirements(void *handle, enum vcd_buffer_type buffer,
+		struct vcd_buffer_requirement *buffer_req);
+u32 vcd_get_buffer_requirements(void *handle, enum vcd_buffer_type buffer,
+		struct vcd_buffer_requirement *buffer_req);
+u32 vcd_set_buffer(void *handle, enum vcd_buffer_type buffer_type,
+		u8 *buffer, u32 buf_size);
+u32 vcd_allocate_buffer(void *handle, enum vcd_buffer_type buffer,
+		u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr);
+
+u32 vcd_free_buffer(void *handle, enum vcd_buffer_type buffer_type, u8 *buffer);
+u32 vcd_fill_output_buffer(void *handle, struct vcd_frame_data *buffer);
+u32 vcd_set_device_power(s32 driver_handle,
+		enum vcd_power_state pwr_state);
+void vcd_read_and_clear_interrupt(void);
+void vcd_response_handler(void);
+u8 vcd_get_num_of_clients(void);
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
new file mode 100644
index 0000000..973ed48
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
@@ -0,0 +1,1827 @@
+/* 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 "vidc_type.h"
+#include "vcd.h"
+
+static const struct vcd_clnt_state_table *vcd_clnt_state_table[];
+
+void vcd_clnt_handle_device_err_fatal(struct vcd_clnt_ctxt *cctxt,
+								  u32 event)
+{
+	if (cctxt->clnt_state.state == VCD_CLIENT_STATE_NULL) {
+		cctxt->callback(VCD_EVT_RESP_OPEN, VCD_ERR_HW_FATAL, NULL, 0,
+			cctxt, cctxt->client_data);
+		vcd_destroy_client_context(cctxt);
+		return;
+	}
+	if (event == VCD_EVT_RESP_BASE)
+		event = VCD_EVT_IND_HWERRFATAL;
+	if (cctxt->clnt_state.state != VCD_CLIENT_STATE_INVALID) {
+		cctxt->callback(event, VCD_ERR_HW_FATAL, NULL, 0,
+			cctxt, cctxt->client_data);
+		vcd_flush_buffers_in_err_fatal(cctxt);
+		vcd_do_client_state_transition(cctxt,
+			VCD_CLIENT_STATE_INVALID,
+			CLIENT_STATE_EVENT_NUMBER(clnt_cb));
+	}
+}
+
+static u32 vcd_close_in_open(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_close_in_open:");
+	if (cctxt->in_buf_pool.allocated ||
+		 cctxt->out_buf_pool.allocated) {
+		VCD_MSG_ERROR("\n Allocated buffers are not freed yet");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	vcd_destroy_client_context(cctxt);
+	return rc;
+}
+
+static u32  vcd_close_in_invalid(struct vcd_clnt_ctxt *cctxt)
+{
+	VCD_MSG_LOW("vcd_close_in_invalid:");
+	if (cctxt->in_buf_pool.allocated ||
+		cctxt->out_buf_pool.allocated){
+		VCD_MSG_ERROR("Allocated buffers are not freed yet");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if (cctxt->status.mask & VCD_CLEANING_UP)
+		cctxt->status.mask |= VCD_CLOSE_PENDING;
+	else
+		vcd_destroy_client_context(cctxt);
+	return VCD_S_SUCCESS;
+}
+
+static u32 vcd_start_in_run_cmn(struct vcd_clnt_ctxt *cctxt)
+{
+	VCD_MSG_LOW("vcd_start_in_run_cmn:");
+	cctxt->callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL, 0,
+					  cctxt, cctxt->client_data);
+	return VCD_S_SUCCESS;
+
+}
+
+static u32 vcd_encode_start_in_open(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_property_hdr prop_hdr;
+	struct vcd_property_vop_timing timing;
+
+	VCD_MSG_LOW("vcd_encode_start_in_open:");
+
+	if (cctxt->decoding) {
+		VCD_MSG_ERROR("vcd_encode_init for decoder client");
+
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if (!cctxt->in_buf_pool.entries ||
+	    !cctxt->out_buf_pool.entries ||
+	    cctxt->in_buf_pool.validated != cctxt->in_buf_pool.count ||
+	    cctxt->out_buf_pool.validated !=
+	    cctxt->out_buf_pool.count) {
+		VCD_MSG_ERROR("Buffer pool is not completely setup yet");
+
+		return VCD_ERR_BAD_STATE;
+	}
+
+	rc = vcd_sched_add_client(cctxt);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_sched_add_client");
+
+	prop_hdr.prop_id = VCD_I_VOP_TIMING;
+	prop_hdr.sz = sizeof(struct vcd_property_vop_timing);
+	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &timing);
+
+	VCD_FAILED_RETURN(rc, "Failed: Get VCD_I_VOP_TIMING");
+	if (!timing.vop_time_resolution) {
+		VCD_MSG_ERROR("Vop_time_resolution value is zero");
+		return VCD_ERR_FAIL;
+	}
+	cctxt->time_resoln = timing.vop_time_resolution;
+
+	rc = vcd_process_cmd_sess_start(cctxt);
+
+	if (!VCD_FAILED(rc)) {
+		vcd_do_client_state_transition(cctxt,
+					       VCD_CLIENT_STATE_STARTING,
+					       CLIENT_STATE_EVENT_NUMBER
+					       (encode_start));
+	}
+
+	return rc;
+}
+
+static u32  vcd_encode_start_in_run(struct vcd_clnt_ctxt
+	*cctxt)
+{
+	VCD_MSG_LOW("vcd_encode_start_in_run:");
+	(void) vcd_start_in_run_cmn(cctxt);
+	return VCD_S_SUCCESS;
+}
+
+
+static u32 vcd_encode_frame_cmn(struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *input_frame)
+{
+	VCD_MSG_LOW("vcd_encode_frame_cmn in %d:", cctxt->clnt_state.state);
+
+	if (cctxt->decoding) {
+		VCD_MSG_ERROR("vcd_encode_frame for decoder client");
+
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	return vcd_handle_input_frame(cctxt, input_frame);
+}
+
+static u32 vcd_decode_start_in_open
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_sequence_hdr *seq_hdr)
+{
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_decode_start_in_open:");
+
+	if (!cctxt->decoding) {
+		VCD_MSG_ERROR("vcd_decode_init for encoder client");
+
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	if (seq_hdr) {
+		VCD_MSG_HIGH("Seq hdr supplied. len = %d",
+			     seq_hdr->sequence_header_len);
+
+		rc = vcd_store_seq_hdr(cctxt, seq_hdr);
+
+	} else {
+		VCD_MSG_HIGH("Seq hdr not supplied");
+
+		cctxt->seq_hdr.sequence_header_len = 0;
+		cctxt->seq_hdr.sequence_header = NULL;
+	}
+
+	VCD_FAILED_RETURN(rc, "Err processing seq hdr");
+
+	rc = vcd_process_cmd_sess_start(cctxt);
+
+	if (!VCD_FAILED(rc)) {
+		vcd_do_client_state_transition(cctxt,
+					       VCD_CLIENT_STATE_STARTING,
+					       CLIENT_STATE_EVENT_NUMBER
+					       (decode_start));
+	}
+
+	return rc;
+}
+
+static u32 vcd_decode_start_in_run(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_sequence_hdr *seqhdr)
+{
+   VCD_MSG_LOW("vcd_decode_start_in_run:");
+   (void) vcd_start_in_run_cmn(cctxt);
+   return VCD_S_SUCCESS;
+}
+
+static u32 vcd_decode_frame_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *input_frame)
+{
+	VCD_MSG_LOW("vcd_decode_frame_cmn in %d:", cctxt->clnt_state.state);
+
+	if (!cctxt->decoding) {
+		VCD_MSG_ERROR("Decode_frame api called for Encoder client");
+
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	return vcd_handle_input_frame(cctxt, input_frame);
+}
+
+static u32 vcd_pause_in_run(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_pause_in_run:");
+
+	if (cctxt->sched_clnt_hdl) {
+		rc = vcd_sched_suspend_resume_clnt(cctxt, false);
+		VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt");
+	}
+
+	if (cctxt->status.frame_submitted > 0) {
+		vcd_do_client_state_transition(cctxt,
+					       VCD_CLIENT_STATE_PAUSING,
+					       CLIENT_STATE_EVENT_NUMBER
+					       (pause));
+
+	} else {
+		VCD_MSG_HIGH("No client frames are currently being processed");
+
+		vcd_do_client_state_transition(cctxt,
+					       VCD_CLIENT_STATE_PAUSED,
+					       CLIENT_STATE_EVENT_NUMBER
+					       (pause));
+
+		cctxt->callback(VCD_EVT_RESP_PAUSE,
+				  VCD_S_SUCCESS,
+				  NULL, 0, cctxt, cctxt->client_data);
+
+		rc = vcd_power_event(cctxt->dev_ctxt, cctxt,
+				     VCD_EVT_PWR_CLNT_PAUSE);
+
+		if (VCD_FAILED(rc))
+			VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_PAUSE_END failed");
+
+	}
+
+	return VCD_S_SUCCESS;
+}
+
+static u32 vcd_resume_in_paused(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_resume_in_paused:");
+
+
+	if (cctxt->sched_clnt_hdl) {
+		rc = vcd_power_event(cctxt->dev_ctxt,
+				     cctxt, VCD_EVT_PWR_CLNT_RESUME);
+
+		if (VCD_FAILED(rc)) {
+			VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_RESUME failed");
+		} else {
+			rc = vcd_sched_suspend_resume_clnt(cctxt, true);
+			if (VCD_FAILED(rc)) {
+				VCD_MSG_ERROR
+				    ("rc = 0x%x. Failed: "
+				     "vcd_sched_suspend_resume_clnt",
+				     rc);
+			}
+
+		}
+		if (!VCD_FAILED(rc)) {
+			vcd_do_client_state_transition(cctxt,
+						       VCD_CLIENT_STATE_RUN,
+						       CLIENT_STATE_EVENT_NUMBER
+						       (resume));
+			vcd_try_submit_frame(dev_ctxt);
+		}
+	} else {
+		vcd_do_client_state_transition(cctxt,
+					       VCD_CLIENT_STATE_RUN,
+					       CLIENT_STATE_EVENT_NUMBER
+					       (resume));
+	}
+
+	return rc;
+}
+
+static u32 vcd_flush_cmn(struct vcd_clnt_ctxt *cctxt, u32 mode)
+{
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_flush_cmn in %d:", cctxt->clnt_state.state);
+
+	rc = vcd_flush_buffers(cctxt, mode);
+
+	VCD_FAILED_RETURN(rc, "Failed: vcd_flush_buffers");
+
+	if (cctxt->status.frame_submitted > 0) {
+		vcd_do_client_state_transition(cctxt,
+					       VCD_CLIENT_STATE_FLUSHING,
+					       CLIENT_STATE_EVENT_NUMBER
+					       (flush));
+	} else {
+		VCD_MSG_HIGH("All buffers are flushed");
+		cctxt->status.mask |= (mode & VCD_FLUSH_ALL);
+		vcd_send_flush_done(cctxt, VCD_S_SUCCESS);
+	}
+
+	return rc;
+}
+
+static u32  vcd_flush_inopen(struct vcd_clnt_ctxt *cctxt,
+	u32 mode)
+{
+   VCD_MSG_LOW("vcd_flush_inopen:");
+   cctxt->status.mask |= (mode & VCD_FLUSH_ALL);
+   vcd_send_flush_done(cctxt, VCD_S_SUCCESS);
+   return VCD_S_SUCCESS;
+}
+
+static u32 vcd_flush_in_flushing
+    (struct vcd_clnt_ctxt *cctxt, u32 mode)
+{
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_flush_in_flushing:");
+
+	rc = vcd_flush_buffers(cctxt, mode);
+
+	return rc;
+}
+
+static u32 vcd_flush_in_eos(struct vcd_clnt_ctxt *cctxt,
+	u32 mode)
+{
+	VCD_MSG_LOW("vcd_flush_in_eos:");
+
+	if (mode > VCD_FLUSH_ALL || !mode) {
+		VCD_MSG_ERROR("Invalid flush mode %d", mode);
+
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	VCD_MSG_MED("Flush mode requested %d", mode);
+
+	cctxt->status.mask |= (mode & VCD_FLUSH_ALL);
+
+	return VCD_S_SUCCESS;
+}
+
+static u32 vcd_flush_in_invalid(struct vcd_clnt_ctxt *cctxt,
+	u32 mode)
+{
+	u32 rc = VCD_S_SUCCESS;
+	VCD_MSG_LOW("vcd_flush_in_invalid:");
+	if (!(cctxt->status.mask & VCD_CLEANING_UP)) {
+		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);
+	return rc;
+}
+
+static u32 vcd_stop_cmn(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_transc *transc;
+
+	VCD_MSG_LOW("vcd_stop_cmn in %d:", cctxt->clnt_state.state);
+
+	rc = vcd_flush_buffers(cctxt, VCD_FLUSH_ALL);
+
+	VCD_FAILED_RETURN(rc, "Failed: vcd_flush_buffers");
+
+	if (!cctxt->status.frame_submitted) {
+
+		if (vcd_get_command_channel(dev_ctxt, &transc)) {
+			rc = vcd_power_event(dev_ctxt, cctxt,
+				VCD_EVT_PWR_CLNT_CMD_BEGIN);
+
+			if (!VCD_FAILED(rc)) {
+				transc->type = VCD_CMD_CODEC_STOP;
+				transc->cctxt = cctxt;
+
+				rc = vcd_submit_cmd_sess_end(transc);
+			} else {
+				VCD_MSG_ERROR("Failed:"
+					" VCD_EVT_PWR_CLNT_CMD_BEGIN");
+			}
+
+			if (VCD_FAILED(rc)) {
+				vcd_release_command_channel(dev_ctxt,
+							    transc);
+			}
+
+		} else {
+			vcd_client_cmd_flush_and_en_q(cctxt,
+						      VCD_CMD_CODEC_STOP);
+		}
+	}
+
+	if (VCD_FAILED(rc)) {
+		(void)vcd_power_event(dev_ctxt, cctxt,
+				      VCD_EVT_PWR_CLNT_CMD_FAIL);
+	} else {
+		vcd_do_client_state_transition(cctxt,
+					       VCD_CLIENT_STATE_STOPPING,
+					       CLIENT_STATE_EVENT_NUMBER
+					       (stop));
+	}
+
+	return rc;
+}
+
+
+static u32  vcd_stop_inopen(struct vcd_clnt_ctxt *cctxt)
+{
+	VCD_MSG_LOW("vcd_stop_inopen:");
+
+	cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS,
+					  NULL, 0, cctxt,
+					  cctxt->client_data);
+
+	return VCD_S_SUCCESS;
+}
+
+static u32 vcd_stop_in_run(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	VCD_MSG_LOW("vcd_stop_in_run:");
+	rc = vcd_stop_cmn(cctxt);
+	if (!VCD_FAILED(rc) &&
+		(cctxt->status.mask & VCD_FIRST_IP_RCVD)) {
+		rc = vcd_power_event(cctxt->dev_ctxt,
+				     cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME);
+	}
+	return rc;
+}
+
+static u32 vcd_stop_in_eos(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	VCD_MSG_LOW("vcd_stop_in_eos:");
+	if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) {
+		rc = vcd_stop_cmn(cctxt);
+		if (!VCD_FAILED(rc)) {
+			rc = vcd_power_event(cctxt->dev_ctxt,
+				cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME);
+			cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF;
+		}
+	} else
+		cctxt->status.mask |= VCD_STOP_PENDING;
+	return rc;
+}
+
+static u32  vcd_stop_in_invalid(struct vcd_clnt_ctxt *cctxt)
+{
+	VCD_MSG_LOW("vcd_stop_in_invalid:");
+	if (cctxt->status.mask & VCD_CLEANING_UP) {
+		cctxt->status.mask |= VCD_STOP_PENDING;
+	} else {
+		(void) vcd_flush_buffers(cctxt, VCD_FLUSH_ALL);
+		cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, NULL,
+			0, cctxt,	cctxt->client_data);
+	}
+	return VCD_S_SUCCESS;
+}
+
+static u32 vcd_set_property_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_property_hdr *prop_hdr, void *prop_val)
+{
+	u32 rc;
+	VCD_MSG_LOW("vcd_set_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) {
+		VCD_MSG_MED("Bad parameters");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	rc = ddl_set_property(cctxt->ddl_handle, prop_hdr, prop_val);
+	VCD_FAILED_RETURN(rc, "Failed: ddl_set_property");
+	switch (prop_hdr->prop_id) {
+	case VCD_I_LIVE:
+		{
+			struct vcd_property_live *live =
+			    (struct vcd_property_live *)prop_val;
+			cctxt->live = live->live;
+			break;
+		}
+	case VCD_I_FRAME_RATE:
+		{
+			if (cctxt->sched_clnt_hdl) {
+				rc = vcd_set_frame_rate(cctxt,
+					(struct vcd_property_frame_rate *)
+					prop_val);
+			}
+			break;
+		}
+	case VCD_I_FRAME_SIZE:
+		{
+			if (cctxt->sched_clnt_hdl) {
+				rc = vcd_set_frame_size(cctxt,
+					(struct vcd_property_frame_size *)
+					prop_val);
+			}
+			break;
+		}
+	case VCD_I_INTRA_PERIOD:
+	   {
+		  struct vcd_property_i_period *iperiod =
+			 (struct vcd_property_i_period *)prop_val;
+		  cctxt->bframe = iperiod->b_frames;
+		  break;
+	   }
+	default:
+		{
+			break;
+		}
+	}
+	return rc;
+}
+
+static u32 vcd_get_property_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_property_hdr *prop_hdr, void *prop_val)
+{
+	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) {
+		VCD_MSG_MED("Bad parameters");
+
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	return ddl_get_property(cctxt->ddl_handle, prop_hdr, prop_val);
+}
+
+static u32 vcd_set_buffer_requirements_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     enum vcd_buffer_type buffer,
+     struct vcd_buffer_requirement *buffer_req)
+{
+	struct vcd_property_hdr Prop_hdr;
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_buffer_pool *buf_pool;
+	u32 first_frm_recvd = 0;
+
+	VCD_MSG_LOW("vcd_set_buffer_requirements_cmn in %d:",
+		    cctxt->clnt_state.state);
+
+	if (!cctxt->decoding &&
+	    cctxt->clnt_state.state != VCD_CLIENT_STATE_OPEN) {
+		VCD_MSG_ERROR("Bad state (%d) for encoder",
+					cctxt->clnt_state.state);
+
+		return VCD_ERR_BAD_STATE;
+	}
+
+	VCD_MSG_MED("Buffer type = %d", buffer);
+
+	if (buffer == VCD_BUFFER_INPUT) {
+		Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ;
+		buf_pool = &cctxt->in_buf_pool;
+		first_frm_recvd = VCD_FIRST_IP_RCVD;
+	} else if (buffer == VCD_BUFFER_OUTPUT) {
+		Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ;
+		buf_pool = &cctxt->out_buf_pool;
+		first_frm_recvd = VCD_FIRST_OP_RCVD;
+	} else {
+		rc = VCD_ERR_ILLEGAL_PARM;
+	}
+
+	VCD_FAILED_RETURN(rc, "Invalid buffer type provided");
+
+	if (buf_pool->validated > 0) {
+		VCD_MSG_ERROR("Need to free allocated buffers");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	first_frm_recvd &= cctxt->status.mask;
+	if (first_frm_recvd) {
+		VCD_MSG_ERROR("VCD SetBufReq called when data path is active");
+		return VCD_ERR_BAD_STATE;
+	}
+	Prop_hdr.sz = sizeof(*buffer_req);
+	rc = ddl_set_property(cctxt->ddl_handle, &Prop_hdr, buffer_req);
+	VCD_FAILED_RETURN(rc, "Failed: ddl_set_property");
+	if (buf_pool->entries) {
+		VCD_MSG_MED("Resetting buffer requirements");
+		vcd_free_buffer_pool_entries(buf_pool);
+	}
+	return rc;
+}
+
+static u32 vcd_get_buffer_requirements_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     enum vcd_buffer_type buffer,
+     struct vcd_buffer_requirement *buffer_req)
+{
+	struct vcd_property_hdr Prop_hdr;
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_get_buffer_requirements_cmn in %d:",
+		    cctxt->clnt_state.state);
+
+	VCD_MSG_MED("Buffer type = %d", buffer);
+
+	if (buffer == VCD_BUFFER_INPUT)
+		Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ;
+	else if (buffer == VCD_BUFFER_OUTPUT)
+		Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ;
+	else
+		rc = VCD_ERR_ILLEGAL_PARM;
+
+	VCD_FAILED_RETURN(rc, "Invalid buffer type provided");
+
+	Prop_hdr.sz = sizeof(*buffer_req);
+
+	return ddl_get_property(cctxt->ddl_handle, &Prop_hdr, buffer_req);
+
+}
+
+static u32 vcd_set_buffer_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     enum vcd_buffer_type buffer_type, u8 *buffer, u32 buf_size)
+{
+	u32 rc;
+	struct vcd_buffer_pool *buf_pool;
+
+	VCD_MSG_LOW("vcd_set_buffer_cmn in %d:", cctxt->clnt_state.state);
+
+	rc = vcd_common_allocate_set_buffer(cctxt, buffer_type, buf_size,
+					    &buf_pool);
+
+	if (!VCD_FAILED(rc)) {
+		rc = vcd_set_buffer_internal(cctxt, buf_pool, buffer,
+					     buf_size);
+	}
+
+	return rc;
+}
+
+static u32 vcd_allocate_buffer_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     enum vcd_buffer_type buffer,
+     u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr)
+{
+	u32 rc;
+	struct vcd_buffer_pool *buf_pool;
+
+	VCD_MSG_LOW("vcd_allocate_buffer_cmn in %d:",
+		    cctxt->clnt_state.state);
+
+	rc = vcd_common_allocate_set_buffer(cctxt, buffer, buf_size,
+					    &buf_pool);
+
+	if (!VCD_FAILED(rc)) {
+		rc = vcd_allocate_buffer_internal(cctxt,
+						  buf_pool,
+						  buf_size,
+						  vir_buf_addr,
+						  phy_buf_addr);
+	}
+
+	return rc;
+}
+
+static u32 vcd_free_buffer_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     enum vcd_buffer_type buffer_type, u8 *buffer)
+{
+
+	VCD_MSG_LOW("vcd_free_buffer_cmn in %d:", cctxt->clnt_state.state);
+
+	return vcd_free_one_buffer_internal(cctxt, buffer_type, buffer);
+}
+
+static u32 vcd_fill_output_buffer_cmn
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *buffer)
+{
+	u32 rc = VCD_S_SUCCESS;
+	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;
+
+	if (!(cctxt->status.mask & VCD_FIRST_OP_RCVD)) {
+		rc = vcd_handle_first_fill_output_buffer(cctxt, buffer,
+			&handled);
+		VCD_FAILED_RETURN(rc,
+			"Failed: vcd_handle_first_fill_output_buffer");
+		if (handled)
+			return rc ;
+	}
+
+	result =
+	    vcd_buffer_pool_entry_en_q(&cctxt->out_buf_pool, buf_entry);
+
+	if (!result && !cctxt->decoding) {
+		VCD_MSG_ERROR("Failed: vcd_buffer_pool_entry_en_q");
+
+		return VCD_ERR_FAIL;
+	}
+
+	buf_entry->frame = *buffer;
+	rc = vcd_return_op_buffer_to_hw(cctxt, buf_entry);
+	if (!VCD_FAILED(rc) && cctxt->sched_clnt_hdl) {
+		cctxt->sched_clnt_hdl->tkns++;
+		vcd_try_submit_frame(cctxt->dev_ctxt);
+	}
+	return rc;
+}
+
+static u32 vcd_fill_output_buffer_in_eos
+    (struct vcd_clnt_ctxt *cctxt,
+     struct vcd_frame_data *buffer)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_buffer_entry *buf_entry;
+
+	VCD_MSG_LOW("vcd_fill_output_buffer_in_eos:");
+
+	buf_entry = vcd_check_fill_output_buffer(cctxt, buffer);
+	if (!buf_entry)
+		return VCD_ERR_BAD_POINTER;
+
+	if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) {
+		VCD_MSG_HIGH("Got an output buffer we were waiting for");
+
+		buf_entry->frame = *buffer;
+
+		buf_entry->frame.data_len = 0;
+		buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS;
+		buf_entry->frame.ip_frm_tag =
+		    cctxt->status.eos_trig_ip_frm.ip_frm_tag;
+		buf_entry->frame.time_stamp =
+		    cctxt->status.eos_trig_ip_frm.time_stamp;
+
+		cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE,
+				  VCD_S_SUCCESS,
+				  &buf_entry->frame,
+				  sizeof(struct vcd_frame_data),
+				  cctxt, cctxt->client_data);
+
+		cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF;
+
+		vcd_do_client_state_transition(cctxt,
+					       VCD_CLIENT_STATE_RUN,
+					       CLIENT_STATE_EVENT_NUMBER
+					       (fill_output_buffer));
+
+	} else {
+		rc = vcd_fill_output_buffer_cmn(cctxt, buffer);
+	}
+
+	return rc;
+}
+
+static void vcd_clnt_cb_in_starting
+    (struct vcd_clnt_ctxt *cctxt,
+     u32 event, u32 status, void *payload, size_t sz,
+	 u32 *ddl_handle, void *const client_data)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	struct vcd_transc *transc =
+		(struct vcd_transc *)client_data;
+	VCD_MSG_LOW("vcd_clnt_cb_in_starting:");
+	if (cctxt->ddl_handle != ddl_handle) {
+		VCD_MSG_ERROR("vcd_clnt_cb_in_initing: Wrong DDL handle %p",
+			ddl_handle);
+		return;
+	}
+
+	switch (event) {
+	case VCD_EVT_RESP_START:
+		{
+			vcd_handle_start_done(cctxt,
+				(struct vcd_transc *)client_data,
+				status);
+			break;
+		}
+	case VCD_EVT_RESP_STOP:
+		{
+			vcd_handle_stop_done_in_starting(cctxt,
+				(struct vcd_transc *)client_data,
+				status);
+			break;
+		}
+	case VCD_EVT_IND_HWERRFATAL:
+		{
+			cctxt->status.cmd_submitted--;
+			vcd_mark_command_channel(cctxt->dev_ctxt, transc);
+			vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START,
+				status);
+			break;
+		}
+	default:
+		{
+			VCD_MSG_ERROR("Unexpected callback event=%d status=%d "
+				"from DDL",	event, status);
+			dev_ctxt->command_continue = false;
+			break;
+		}
+	}
+}
+
+static void vcd_clnt_cb_in_run
+    (struct vcd_clnt_ctxt *cctxt,
+     u32 event,
+     u32 status,
+     void *payload, size_t sz, u32 *ddl_handle, void *const client_data)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 rc = VCD_S_SUCCESS;
+
+	if (cctxt->ddl_handle != ddl_handle) {
+		VCD_MSG_ERROR("ddl_handle mismatch");
+
+		return;
+	}
+
+	switch (event) {
+	case VCD_EVT_RESP_INPUT_DONE:
+		{
+			rc = vcd_handle_input_done(cctxt, payload, event,
+						   status);
+
+			break;
+		}
+
+	case VCD_EVT_RESP_OUTPUT_DONE:
+		{
+
+			rc = vcd_handle_frame_done(cctxt, payload, event,
+						   status);
+
+			break;
+		}
+	case VCD_EVT_RESP_OUTPUT_REQ:
+		{
+			rc = vcd_handle_output_required(cctxt, payload,
+				status);
+			break;
+		}
+
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		{
+			rc = vcd_handle_ind_output_reconfig(cctxt, payload,
+				status);
+      break;
+		}
+	case VCD_EVT_RESP_TRANSACTION_PENDING:
+		{
+			 vcd_handle_trans_pending(cctxt);
+			 break;
+		}
+
+	case VCD_EVT_IND_HWERRFATAL:
+		{
+			 vcd_handle_ind_hw_err_fatal(cctxt,
+				VCD_EVT_IND_HWERRFATAL, status);
+			 break;
+		}
+	case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
+		{
+			vcd_handle_ind_info_output_reconfig(cctxt, status);
+			break;
+		}
+	default:
+		{
+			VCD_MSG_ERROR
+			    ("Unexpected callback event=%d status=%d from DDL",
+			     event, status);
+			dev_ctxt->command_continue = false;
+
+			break;
+		}
+	}
+
+	if (!VCD_FAILED(rc) &&
+	    (event == VCD_EVT_RESP_INPUT_DONE ||
+	     event == VCD_EVT_RESP_OUTPUT_DONE ||
+	     event == VCD_EVT_RESP_OUTPUT_REQ)) {
+
+		if (((struct ddl_frame_data_tag *)
+					payload)->frm_trans_end)
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+	}
+}
+
+static void vcd_clnt_cb_in_eos
+    (struct vcd_clnt_ctxt *cctxt,
+     u32 event,
+     u32 status,
+     void *payload, size_t sz, u32 *ddl_handle, void *const client_data) {
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	struct vcd_transc *transc = NULL;
+	u32 frm_trans_end = false, rc = VCD_S_SUCCESS;
+
+	if (cctxt->ddl_handle != ddl_handle) {
+		VCD_MSG_ERROR("ddl_handle mismatch");
+
+		return;
+	}
+
+	switch (event) {
+	case VCD_EVT_RESP_INPUT_DONE:
+		{
+			rc = vcd_handle_input_done_in_eos(cctxt, payload,
+						     status);
+
+			break;
+		}
+
+	case VCD_EVT_RESP_OUTPUT_DONE:
+		{
+			rc = vcd_handle_frame_done_in_eos(cctxt, payload,
+						     status);
+
+			break;
+		}
+	case VCD_EVT_RESP_OUTPUT_REQ:
+		{
+			rc = vcd_handle_output_required(cctxt, payload,
+					status);
+			break;
+		}
+	case VCD_EVT_RESP_EOS_DONE:
+		{
+			transc = (struct vcd_transc *)client_data;
+			vcd_handle_eos_done(cctxt, transc, status);
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+			break;
+		}
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		{
+			rc = vcd_handle_ind_output_reconfig(cctxt,
+				payload, status);
+			if (!VCD_FAILED(rc)) {
+				frm_trans_end = true;
+				payload = NULL;
+				vcd_do_client_state_transition(cctxt,
+					VCD_CLIENT_STATE_RUN,
+					CLIENT_STATE_EVENT_NUMBER
+					(clnt_cb));
+				VCD_MSG_LOW
+					("RECONFIGinEOS:Suspending Client");
+				rc = vcd_sched_suspend_resume_clnt(cctxt,
+						false);
+				if (VCD_FAILED(rc)) {
+					VCD_MSG_ERROR
+					("Failed: suspend_resume_clnt. rc=0x%x",
+						rc);
+				}
+			}
+			break;
+		}
+	case VCD_EVT_IND_HWERRFATAL:
+		{
+			vcd_handle_ind_hw_err_fatal(cctxt,
+				VCD_EVT_IND_HWERRFATAL,	status);
+			break;
+		}
+	case VCD_EVT_IND_INFO_OUTPUT_RECONFIG:
+		{
+			vcd_handle_ind_info_output_reconfig(cctxt, status);
+			break;
+		}
+	default:
+		{
+			VCD_MSG_ERROR
+			    ("Unexpected callback event=%d status=%d from DDL",
+			     event, status);
+
+			dev_ctxt->command_continue = false;
+
+			break;
+		}
+
+	}
+	if (!VCD_FAILED(rc) &&
+		(event == VCD_EVT_RESP_INPUT_DONE ||
+		event == VCD_EVT_RESP_OUTPUT_DONE ||
+		event == VCD_EVT_RESP_OUTPUT_REQ ||
+		event == VCD_EVT_IND_OUTPUT_RECONFIG)) {
+		if (payload && ((struct ddl_frame_data_tag *)
+			payload)->frm_trans_end) {
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+			frm_trans_end = true;
+		}
+		if (frm_trans_end && !cctxt->status.frame_submitted)
+			vcd_handle_eos_trans_end(cctxt);
+	}
+}
+
+static void vcd_clnt_cb_in_flushing
+    (struct vcd_clnt_ctxt *cctxt,
+     u32 event,
+     u32 status,
+     void *payload, size_t sz, u32 *ddl_handle, void *const client_data) {
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 rc = VCD_S_SUCCESS;
+	u32 frm_trans_end = false;
+
+	VCD_MSG_LOW("vcd_clnt_cb_in_flushing:");
+
+	if (cctxt->ddl_handle != ddl_handle) {
+		VCD_MSG_ERROR("ddl_handle mismatch");
+
+		return;
+	}
+
+	switch (event) {
+	case VCD_EVT_RESP_INPUT_DONE:
+		{
+			rc = vcd_handle_input_done(cctxt,
+						   payload,
+						   VCD_EVT_RESP_INPUT_FLUSHED,
+						   status);
+
+			break;
+		}
+
+	case VCD_EVT_RESP_OUTPUT_DONE:
+		{
+
+			rc = vcd_handle_frame_done(cctxt,
+						   payload,
+						   VCD_EVT_RESP_OUTPUT_FLUSHED,
+						   status);
+
+			break;
+		}
+	case VCD_EVT_RESP_OUTPUT_REQ:
+		{
+			rc = vcd_handle_output_required_in_flushing(cctxt,
+				payload);
+			break;
+		}
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		{
+			rc = vcd_handle_ind_output_reconfig(cctxt,
+				payload, status);
+			if (!VCD_FAILED(rc)) {
+				frm_trans_end = true;
+				payload = NULL;
+			}
+			break;
+		}
+	case VCD_EVT_IND_HWERRFATAL:
+		{
+			vcd_handle_ind_hw_err_fatal(cctxt,
+				VCD_EVT_IND_HWERRFATAL,	status);
+			break;
+		}
+	default:
+		{
+			VCD_MSG_ERROR
+			    ("Unexpected callback event=%d status=%d from DDL",
+			     event, status);
+
+			dev_ctxt->command_continue = false;
+
+			break;
+		}
+	}
+	if (!VCD_FAILED(rc) && ((event == VCD_EVT_RESP_INPUT_DONE ||
+		event == VCD_EVT_RESP_OUTPUT_DONE ||
+		event == VCD_EVT_RESP_OUTPUT_REQ ||
+		event == VCD_EVT_IND_OUTPUT_RECONFIG))) {
+		if (payload &&
+			((struct ddl_frame_data_tag *)\
+			payload)->frm_trans_end) {
+
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+			frm_trans_end = true;
+		}
+		if (frm_trans_end && !cctxt->status.frame_submitted) {
+			VCD_MSG_HIGH
+			    ("All pending frames recvd from DDL");
+			if (cctxt->status.mask & VCD_FLUSH_INPUT)
+				vcd_flush_bframe_buffers(cctxt,
+							VCD_FLUSH_INPUT);
+			if (cctxt->status.mask & VCD_FLUSH_OUTPUT)
+				vcd_flush_output_buffers(cctxt);
+			vcd_send_flush_done(cctxt, VCD_S_SUCCESS);
+			vcd_release_interim_frame_channels(dev_ctxt);
+			VCD_MSG_HIGH("Flush complete");
+			vcd_do_client_state_transition(cctxt,
+				VCD_CLIENT_STATE_RUN,
+				CLIENT_STATE_EVENT_NUMBER
+				(clnt_cb));
+		}
+	}
+}
+
+static void vcd_clnt_cb_in_stopping
+    (struct vcd_clnt_ctxt *cctxt,
+     u32 event,
+     u32 status,
+     void *payload, size_t sz, u32 *ddl_handle, void *const client_data) {
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 rc = VCD_S_SUCCESS;
+	u32 frm_trans_end = false;
+
+	VCD_MSG_LOW("vcd_clnt_cb_in_stopping:");
+
+	if (cctxt->ddl_handle != ddl_handle) {
+		VCD_MSG_ERROR("ddl_handle mismatch");
+
+		return;
+	}
+
+	switch (event) {
+
+	case VCD_EVT_RESP_INPUT_DONE:
+		{
+			rc = vcd_handle_input_done(cctxt,
+						   payload,
+						   VCD_EVT_RESP_INPUT_FLUSHED,
+						   status);
+
+			break;
+		}
+
+	case VCD_EVT_RESP_OUTPUT_DONE:
+		{
+
+			rc = vcd_handle_frame_done(cctxt,
+						   payload,
+						   VCD_EVT_RESP_OUTPUT_FLUSHED,
+						   status);
+
+			break;
+		}
+	case VCD_EVT_RESP_OUTPUT_REQ:
+		{
+			rc = vcd_handle_output_required_in_flushing(cctxt,
+				payload);
+			break;
+		}
+	case VCD_EVT_RESP_STOP:
+		{
+			vcd_handle_stop_done(cctxt,
+					     (struct vcd_transc *)
+					     client_data, status);
+
+			break;
+		}
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		{
+			(void) vcd_handle_ind_output_reconfig(cctxt,
+				payload, status);
+
+			frm_trans_end = true;
+			payload = NULL;
+
+			break;
+		}
+	case VCD_EVT_IND_HWERRFATAL:
+		{
+			vcd_handle_ind_hw_err_fatal(cctxt, VCD_EVT_RESP_STOP,
+				status);
+			break;
+		}
+
+	default:
+		{
+			VCD_MSG_ERROR
+			    ("Unexpected callback event=%d status=%d from DDL",
+			     event, status);
+
+			dev_ctxt->command_continue = false;
+
+			break;
+		}
+	}
+
+	if (!VCD_FAILED(rc) && ((event == VCD_EVT_RESP_INPUT_DONE ||
+		event == VCD_EVT_RESP_OUTPUT_DONE) ||
+		event == VCD_EVT_RESP_OUTPUT_REQ ||
+		event == VCD_EVT_IND_OUTPUT_RECONFIG)) {
+
+		if (payload &&
+			((struct ddl_frame_data_tag *)\
+			payload)->frm_trans_end) {
+
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+			frm_trans_end = true;
+		}
+		if (frm_trans_end && !cctxt->status.frame_submitted) {
+				VCD_MSG_HIGH
+					("All pending frames recvd from DDL");
+				vcd_flush_bframe_buffers(cctxt,
+							VCD_FLUSH_INPUT);
+				vcd_flush_output_buffers(cctxt);
+				cctxt->status.mask &= ~VCD_FLUSH_ALL;
+				vcd_release_all_clnt_frm_transc(cctxt);
+				VCD_MSG_HIGH
+				("All buffers flushed. Enqueuing stop cmd");
+				vcd_client_cmd_flush_and_en_q(cctxt,
+						VCD_CMD_CODEC_STOP);
+		}
+	}
+}
+
+static void vcd_clnt_cb_in_pausing
+    (struct vcd_clnt_ctxt *cctxt,
+     u32 event,
+     u32 status,
+     void *payload, size_t sz, u32 *ddl_handle, void *const client_data)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 rc = VCD_S_SUCCESS;
+	u32 frm_trans_end = false;
+
+	VCD_MSG_LOW("vcd_clnt_cb_in_pausing:");
+
+	if (cctxt->ddl_handle != ddl_handle) {
+		VCD_MSG_ERROR("ddl_handle mismatch");
+
+		return;
+	}
+
+	switch (event) {
+	case VCD_EVT_RESP_INPUT_DONE:
+		{
+			rc = vcd_handle_input_done(cctxt, payload, event,
+						   status);
+
+			break;
+		}
+
+	case VCD_EVT_RESP_OUTPUT_DONE:
+		{
+			rc = vcd_handle_frame_done(cctxt, payload, event,
+						   status);
+			break;
+		}
+	case VCD_EVT_RESP_OUTPUT_REQ:
+		{
+			rc = vcd_handle_output_required(cctxt, payload,
+				status);
+			break;
+		}
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		{
+			rc = vcd_handle_ind_output_reconfig(cctxt,
+				payload, status);
+			if (!VCD_FAILED(rc)) {
+				frm_trans_end = true;
+				payload = NULL;
+			}
+			break;
+		}
+	case VCD_EVT_IND_HWERRFATAL:
+		{
+			vcd_handle_ind_hw_err_fatal(cctxt,
+				VCD_EVT_RESP_PAUSE,	status);
+			rc = VCD_ERR_FAIL;
+			break;
+		}
+	default:
+		{
+			VCD_MSG_ERROR
+			    ("Unexpected callback event=%d status=%d from DDL",
+			     event, status);
+
+			dev_ctxt->command_continue = false;
+
+			break;
+		}
+
+	}
+
+	if (!VCD_FAILED(rc)) {
+
+		if (payload &&
+			((struct ddl_frame_data_tag *)\
+			payload)->frm_trans_end) {
+
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+			frm_trans_end = true;
+		}
+		if (frm_trans_end && !cctxt->status.frame_submitted) {
+			VCD_MSG_HIGH
+			    ("All pending frames recvd from DDL");
+
+			cctxt->callback(VCD_EVT_RESP_PAUSE,
+					  VCD_S_SUCCESS,
+					  NULL,
+					  0,
+					  cctxt,
+					  cctxt->client_data);
+
+			vcd_do_client_state_transition(cctxt,
+					VCD_CLIENT_STATE_PAUSED,
+					CLIENT_STATE_EVENT_NUMBER
+						       (clnt_cb));
+
+			rc = vcd_power_event(cctxt->dev_ctxt,
+					     cctxt,
+					     VCD_EVT_PWR_CLNT_PAUSE);
+
+			if (VCD_FAILED(rc)) {
+				VCD_MSG_ERROR
+				    ("VCD_EVT_PWR_CLNT_PAUSE_END"
+				     "failed");
+			}
+		}
+	}
+}
+
+static void  vcd_clnt_cb_in_invalid(
+   struct vcd_clnt_ctxt *cctxt, u32 event, u32 status,
+   void *payload, size_t sz, u32 *ddl_handle,
+   void *const client_data
+)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	VCD_MSG_LOW("vcd_clnt_cb_in_invalid:");
+	if (cctxt->ddl_handle != ddl_handle) {
+		VCD_MSG_ERROR("ddl_handle mismatch");
+		return;
+	}
+	switch (event) {
+	case VCD_EVT_RESP_STOP:
+		{
+			vcd_handle_stop_done_in_invalid(cctxt,
+				(struct vcd_transc *)client_data,
+				status);
+			break;
+		}
+	case VCD_EVT_RESP_INPUT_DONE:
+	case VCD_EVT_RESP_OUTPUT_REQ:
+		{
+			if (cctxt->status.frame_submitted)
+				cctxt->status.frame_submitted--;
+			if (payload && ((struct ddl_frame_data_tag *)
+							payload)->frm_trans_end)
+				vcd_mark_frame_channel(cctxt->dev_ctxt);
+			break;
+		}
+	case VCD_EVT_RESP_OUTPUT_DONE:
+		{
+			if (payload && ((struct ddl_frame_data_tag *)
+							payload)->frm_trans_end)
+				vcd_mark_frame_channel(cctxt->dev_ctxt);
+			break;
+		}
+	case VCD_EVT_RESP_TRANSACTION_PENDING:
+		{
+			if (cctxt->status.frame_submitted)
+				cctxt->status.frame_submitted--;
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+			break;
+		}
+	case VCD_EVT_IND_HWERRFATAL:
+		{
+			if (status == VCD_ERR_HW_FATAL)
+				vcd_handle_stop_done_in_invalid(cctxt,
+					(struct vcd_transc *)client_data,
+					status);
+
+			break;
+		}
+	case VCD_EVT_RESP_EOS_DONE:
+		{
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+			break;
+		}
+	case VCD_EVT_IND_OUTPUT_RECONFIG:
+		{
+			if (cctxt->status.frame_submitted > 0)
+				cctxt->status.frame_submitted--;
+			else
+				cctxt->status.frame_delayed--;
+			vcd_mark_frame_channel(cctxt->dev_ctxt);
+			break;
+		}
+	default:
+		{
+			VCD_MSG_ERROR("Unexpected callback event=%d status=%d"
+				"from DDL",	event, status);
+			dev_ctxt->command_continue = false;
+			break;
+		}
+	}
+}
+
+static void vcd_clnt_enter_open
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Entering CLIENT_STATE_OPEN on api %d", state_event);
+}
+
+static void vcd_clnt_enter_starting
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Entering CLIENT_STATE_STARTING on api %d",
+		    state_event);
+	cctxt->status.last_evt = VCD_EVT_RESP_START;
+}
+
+static void vcd_clnt_enter_run
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Entering CLIENT_STATE_RUN on api %d", state_event);
+}
+
+static void vcd_clnt_enter_flushing
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Entering CLIENT_STATE_FLUSHING on api %d",
+		    state_event);
+}
+
+static void vcd_clnt_enter_stopping
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Entering CLIENT_STATE_STOPPING on api %d",
+		    state_event);
+	cctxt->status.last_evt = VCD_EVT_RESP_STOP;
+}
+
+static void vcd_clnt_enter_eos(struct vcd_clnt_ctxt *cctxt,
+	s32 state_event)
+{
+   u32     rc;
+   VCD_MSG_MED("Entering CLIENT_STATE_EOS on api %d", state_event);
+	rc = vcd_sched_suspend_resume_clnt(cctxt, false);
+	if (VCD_FAILED(rc))
+		VCD_MSG_ERROR("Failed: vcd_sched_suspend_resume_clnt."
+					  "rc=0x%x", rc);
+}
+
+static void vcd_clnt_enter_pausing
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Entering CLIENT_STATE_PAUSING on api %d",
+		    state_event);
+	cctxt->status.last_evt = VCD_EVT_RESP_PAUSE;
+}
+
+static void vcd_clnt_enter_paused
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event)
+{
+	VCD_MSG_MED("Entering CLIENT_STATE_PAUSED on api %d",
+		state_event);
+}
+
+static void  vcd_clnt_enter_invalid(struct vcd_clnt_ctxt *cctxt,
+	s32 state_event)
+{
+	VCD_MSG_MED("Entering CLIENT_STATE_INVALID on api %d",
+		state_event);
+	cctxt->ddl_hdl_valid = false;
+	cctxt->status.mask &= ~(VCD_FIRST_IP_RCVD | VCD_FIRST_OP_RCVD);
+	if (cctxt->sched_clnt_hdl)
+		vcd_sched_suspend_resume_clnt(cctxt, false);
+}
+
+static void vcd_clnt_exit_open
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event)
+{
+	VCD_MSG_MED("Exiting CLIENT_STATE_OPEN on api %d", state_event);
+}
+
+static void vcd_clnt_exit_starting
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting CLIENT_STATE_STARTING on api %d",
+		    state_event);
+	cctxt->status.last_evt = VCD_EVT_RESP_BASE;
+}
+
+static void vcd_clnt_exit_run
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting CLIENT_STATE_RUN on api %d", state_event);
+}
+
+static void vcd_clnt_exit_flushing
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting CLIENT_STATE_FLUSHING on api %d",
+		    state_event);
+}
+
+static void vcd_clnt_exit_stopping
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting CLIENT_STATE_STOPPING on api %d",
+		    state_event);
+	cctxt->status.last_evt = VCD_EVT_RESP_BASE;
+}
+
+static void vcd_clnt_exit_eos
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event)
+{
+	u32 rc;
+	VCD_MSG_MED("Exiting CLIENT_STATE_EOS on api %d", state_event);
+	rc = vcd_sched_suspend_resume_clnt(cctxt, true);
+	if (VCD_FAILED(rc))
+		VCD_MSG_ERROR("Failed: vcd_sched_suspend_resume_clnt. rc=0x%x",
+			rc);
+}
+
+static void vcd_clnt_exit_pausing
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting CLIENT_STATE_PAUSING on api %d",
+		    state_event);
+	cctxt->status.last_evt = VCD_EVT_RESP_BASE;
+}
+
+static void vcd_clnt_exit_paused
+    (struct vcd_clnt_ctxt *cctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting CLIENT_STATE_PAUSED on api %d",
+		    state_event);
+}
+
+static void  vcd_clnt_exit_invalid(struct vcd_clnt_ctxt *cctxt,
+	s32 state_event)
+{
+	VCD_MSG_MED("Exiting CLIENT_STATE_INVALID on api %d",
+		state_event);
+}
+
+void vcd_do_client_state_transition(struct vcd_clnt_ctxt *cctxt,
+     enum vcd_clnt_state_enum to_state, u32 ev_code)
+{
+	struct vcd_clnt_state_ctxt *state_ctxt;
+
+	if (!cctxt || to_state >= VCD_CLIENT_STATE_MAX) {
+		VCD_MSG_ERROR("Bad parameters. cctxt=%p, to_state=%d",
+			      cctxt, to_state);
+	}
+
+	state_ctxt = &cctxt->clnt_state;
+
+	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",
+		    (int)state_ctxt->state, (int)to_state, ev_code);
+
+	if (state_ctxt->state_table->exit)
+		state_ctxt->state_table->exit(cctxt, ev_code);
+
+
+	state_ctxt->state = to_state;
+	state_ctxt->state_table = vcd_clnt_state_table[to_state];
+
+	if (state_ctxt->state_table->entry)
+		state_ctxt->state_table->entry(cctxt, ev_code);
+}
+
+const struct vcd_clnt_state_table *vcd_get_client_state_table
+    (enum vcd_clnt_state_enum state) {
+	return vcd_clnt_state_table[state];
+}
+
+static const struct vcd_clnt_state_table vcd_clnt_table_open = {
+	{
+	 vcd_close_in_open,
+	 vcd_encode_start_in_open,
+	 NULL,
+	 vcd_decode_start_in_open,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_flush_inopen,
+	 vcd_stop_inopen,
+	 vcd_set_property_cmn,
+	 vcd_get_property_cmn,
+	 vcd_set_buffer_requirements_cmn,
+	 vcd_get_buffer_requirements_cmn,
+	 vcd_set_buffer_cmn,
+	 vcd_allocate_buffer_cmn,
+	 vcd_free_buffer_cmn,
+	 vcd_fill_output_buffer_cmn,
+	 NULL,
+	 },
+	vcd_clnt_enter_open,
+	vcd_clnt_exit_open
+};
+
+static const struct vcd_clnt_state_table vcd_clnt_table_starting = {
+	{
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_get_property_cmn,
+	 NULL,
+	 vcd_get_buffer_requirements_cmn,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_clnt_cb_in_starting,
+	 },
+	vcd_clnt_enter_starting,
+	vcd_clnt_exit_starting
+};
+
+static const struct vcd_clnt_state_table vcd_clnt_table_run = {
+	{
+	 NULL,
+	 vcd_encode_start_in_run,
+	 vcd_encode_frame_cmn,
+	 vcd_decode_start_in_run,
+	 vcd_decode_frame_cmn,
+	 vcd_pause_in_run,
+	 NULL,
+	 vcd_flush_cmn,
+	 vcd_stop_in_run,
+	 vcd_set_property_cmn,
+	 vcd_get_property_cmn,
+	 vcd_set_buffer_requirements_cmn,
+	 vcd_get_buffer_requirements_cmn,
+	 vcd_set_buffer_cmn,
+	 vcd_allocate_buffer_cmn,
+	 vcd_free_buffer_cmn,
+	 vcd_fill_output_buffer_cmn,
+	 vcd_clnt_cb_in_run,
+	 },
+	vcd_clnt_enter_run,
+	vcd_clnt_exit_run
+};
+
+static const struct vcd_clnt_state_table vcd_clnt_table_flushing = {
+	{
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_flush_in_flushing,
+	 NULL,
+	 vcd_set_property_cmn,
+	 vcd_get_property_cmn,
+	 NULL,
+	 vcd_get_buffer_requirements_cmn,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_fill_output_buffer_cmn,
+	 vcd_clnt_cb_in_flushing,
+	 },
+	vcd_clnt_enter_flushing,
+	vcd_clnt_exit_flushing
+};
+
+static const struct vcd_clnt_state_table vcd_clnt_table_stopping = {
+	{
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_get_property_cmn,
+	 NULL,
+	 vcd_get_buffer_requirements_cmn,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_clnt_cb_in_stopping,
+	 },
+	vcd_clnt_enter_stopping,
+	vcd_clnt_exit_stopping
+};
+
+static const struct vcd_clnt_state_table vcd_clnt_table_eos = {
+	{
+	 NULL,
+	 NULL,
+	 vcd_encode_frame_cmn,
+	 NULL,
+	 vcd_decode_frame_cmn,
+	 NULL,
+	 NULL,
+	 vcd_flush_in_eos,
+	 vcd_stop_in_eos,
+	 NULL,
+	 vcd_get_property_cmn,
+	 NULL,
+	 vcd_get_buffer_requirements_cmn,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_fill_output_buffer_in_eos,
+	 vcd_clnt_cb_in_eos,
+	 },
+	vcd_clnt_enter_eos,
+	vcd_clnt_exit_eos
+};
+
+static const struct vcd_clnt_state_table vcd_clnt_table_pausing = {
+	{
+	 NULL,
+	 NULL,
+	 vcd_encode_frame_cmn,
+	 NULL,
+	 vcd_decode_frame_cmn,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_set_property_cmn,
+	 vcd_get_property_cmn,
+	 NULL,
+	 vcd_get_buffer_requirements_cmn,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_fill_output_buffer_cmn,
+	 vcd_clnt_cb_in_pausing,
+	 },
+	vcd_clnt_enter_pausing,
+	vcd_clnt_exit_pausing
+};
+
+static const struct vcd_clnt_state_table vcd_clnt_table_paused = {
+	{
+	 NULL,
+	 NULL,
+	 vcd_encode_frame_cmn,
+	 NULL,
+	 vcd_decode_frame_cmn,
+	 NULL,
+	 vcd_resume_in_paused,
+	 vcd_flush_cmn,
+	 vcd_stop_cmn,
+	 vcd_set_property_cmn,
+	 vcd_get_property_cmn,
+	 vcd_set_buffer_requirements_cmn,
+	 vcd_get_buffer_requirements_cmn,
+	 vcd_set_buffer_cmn,
+	 vcd_allocate_buffer_cmn,
+	 NULL,
+	 vcd_fill_output_buffer_cmn,
+	 NULL,
+	 },
+	vcd_clnt_enter_paused,
+	vcd_clnt_exit_paused
+};
+static const struct vcd_clnt_state_table vcd_clnt_table_invalid = {
+   {
+      vcd_close_in_invalid,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      vcd_flush_in_invalid,
+      vcd_stop_in_invalid,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      vcd_free_buffer_cmn,
+      NULL,
+      vcd_clnt_cb_in_invalid,
+   },
+   vcd_clnt_enter_invalid,
+   vcd_clnt_exit_invalid
+};
+
+static const struct vcd_clnt_state_table *vcd_clnt_state_table[] = {
+	NULL,
+	&vcd_clnt_table_open,
+	&vcd_clnt_table_starting,
+	&vcd_clnt_table_run,
+	&vcd_clnt_table_flushing,
+	&vcd_clnt_table_pausing,
+	&vcd_clnt_table_paused,
+	&vcd_clnt_table_stopping,
+	&vcd_clnt_table_eos,
+   &vcd_clnt_table_invalid
+};
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
new file mode 100644
index 0000000..e9ab41c
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h
@@ -0,0 +1,110 @@
+/* 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_CLIENT_SM_H_
+#define _VCD_CLIENT_SM_H_
+#include "vcd_api.h"
+#include "vcd_ddl_api.h"
+
+struct vcd_clnt_state_table;
+struct vcd_clnt_state_ctxt;
+struct vcd_clnt_ctxt;
+
+enum vcd_clnt_state_enum {
+	VCD_CLIENT_STATE_NULL = 0,
+	VCD_CLIENT_STATE_OPEN,
+	VCD_CLIENT_STATE_STARTING,
+	VCD_CLIENT_STATE_RUN,
+	VCD_CLIENT_STATE_FLUSHING,
+	VCD_CLIENT_STATE_PAUSING,
+	VCD_CLIENT_STATE_PAUSED,
+	VCD_CLIENT_STATE_STOPPING,
+	VCD_CLIENT_STATE_EOS,
+	VCD_CLIENT_STATE_INVALID,
+	VCD_CLIENT_STATE_MAX,
+	VCD_CLIENT_STATE_32BIT = 0x7FFFFFFF
+};
+
+#define   CLIENT_STATE_EVENT_NUMBER(ppf) \
+    ((u32 *) (&(((struct vcd_clnt_state_table*)0)->ev_hdlr.ppf)) -  \
+    (u32 *) (&(((struct vcd_clnt_state_table*)0)->ev_hdlr.close)) \
+	+ 1)
+
+struct vcd_clnt_state_table {
+	struct {
+		u32(*close) (struct vcd_clnt_ctxt *cctxt);
+		u32(*encode_start) (struct vcd_clnt_ctxt *cctxt);
+		u32(*encode_frame) (struct vcd_clnt_ctxt *cctxt,
+				struct vcd_frame_data *input_frame);
+		u32(*decode_start) (struct vcd_clnt_ctxt *cctxt,
+				struct vcd_sequence_hdr *seq_hdr);
+		u32(*decode_frame) (struct vcd_clnt_ctxt *cctxt,
+				struct vcd_frame_data *input_frame);
+		u32(*pause) (struct vcd_clnt_ctxt *cctxt);
+		u32(*resume) (struct vcd_clnt_ctxt *cctxt);
+		u32(*flush) (struct vcd_clnt_ctxt *cctxt,
+				u32 mode);
+		u32(*stop) (struct vcd_clnt_ctxt *cctxt);
+		u32(*set_property) (struct vcd_clnt_ctxt *cctxt,
+				struct vcd_property_hdr *prop_hdr,
+				void *prop);
+		u32(*get_property) (struct vcd_clnt_ctxt *cctxt,
+				struct vcd_property_hdr *prop_hdr,
+				void *prop);
+		u32(*set_buffer_requirements) (struct vcd_clnt_ctxt *
+						  cctxt,
+						  enum vcd_buffer_type buffer,
+						  struct
+						  vcd_buffer_requirement *
+						  buffer_req);
+		u32(*get_buffer_requirements) (struct vcd_clnt_ctxt *
+						  cctxt,
+						  enum vcd_buffer_type buffer,
+						  struct
+						  vcd_buffer_requirement *
+						  buffer_req);
+		u32(*set_buffer) (struct vcd_clnt_ctxt *cctxt,
+				enum vcd_buffer_type buffer_type, u8 *buffer,
+				u32 buf_size);
+		u32(*allocate_buffer) (struct vcd_clnt_ctxt *cctxt,
+				enum vcd_buffer_type buffer, u32 buf_size,
+				u8 **vir_buf_addr, u8 **phy_buf_addr);
+		u32(*free_buffer) (struct vcd_clnt_ctxt *cctxt,
+				enum vcd_buffer_type buffer_type, u8 *buffer);
+		u32(*fill_output_buffer) (
+				struct vcd_clnt_ctxt *cctxt,
+				struct vcd_frame_data *buffer);
+		void (*clnt_cb) (struct vcd_clnt_ctxt *cctxt,
+				u32 event, u32 status, void *payload,
+				size_t sz, u32 *ddl_handle,
+				void *const client_data);
+	} ev_hdlr;
+
+	void (*entry) (struct vcd_clnt_ctxt *cctxt,
+			s32 state_event);
+	void (*exit) (struct vcd_clnt_ctxt *cctxt,
+			s32 state_event);
+};
+
+struct vcd_clnt_state_ctxt {
+	const struct vcd_clnt_state_table *state_table;
+	enum vcd_clnt_state_enum state;
+};
+
+extern void vcd_do_client_state_transition
+    (struct vcd_clnt_ctxt *cctxt,
+     enum vcd_clnt_state_enum to_state, u32 ev_code);
+
+extern const struct vcd_clnt_state_table *vcd_get_client_state_table(
+		enum vcd_clnt_state_enum state);
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h
new file mode 100644
index 0000000..e681feb
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h
@@ -0,0 +1,220 @@
+/* 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 _VCD_CORE_H_
+#define _VCD_CORE_H_
+
+#include "vcd_api.h"
+#include "vcd_ddl_api.h"
+
+#include "vcd_util.h"
+#include "vcd_client_sm.h"
+#include "vcd_power_sm.h"
+
+#define VCD_SIGNATURE                        0x75017591U
+
+#define VCD_MIN_PERF_LEVEL                   37900
+
+#define VCD_DRIVER_INSTANCE_MAX              4
+
+#define VCD_MAX_CLIENT_TRANSACTIONS          32
+
+#define VCD_MAX_BUFFER_ENTRIES               32
+
+#define VCD_SEQ_HDR_PADDING_BYTES            256
+
+#define VCD_DEC_NUM_INTERLACED_FIELDS        2
+
+#define VCD_TIMESTAMP_RESOLUTION             1000000
+#define VCD_DEC_INITIAL_FRAME_RATE           30
+
+#define VCD_FIRST_IP_RCVD                    0x00000004
+#define VCD_FIRST_OP_RCVD                    0x00000008
+#define VCD_EOS_PREV_VALID                   0x00000010
+#define VCD_EOS_WAIT_OP_BUF                  0x00000020
+#define VCD_CLEANING_UP                      0x00000040
+#define VCD_STOP_PENDING                     0x00000080
+#define VCD_CLOSE_PENDING                    0x00000100
+#define VCD_IN_RECONFIG                      0x00000200
+#define VCD_FIRST_IP_DONE                    0x00000400
+
+enum vcd_command {
+	VCD_CMD_NONE,
+	VCD_CMD_DEVICE_INIT,
+	VCD_CMD_DEVICE_TERM,
+	VCD_CMD_DEVICE_RESET,
+	VCD_CMD_CODEC_START,
+	VCD_CMD_CODEC_STOP,
+	VCD_CMD_CODE_FRAME,
+	VCD_CMD_OUTPUT_FLUSH,
+	VCD_CMD_CLIENT_CLOSE
+};
+
+enum vcd_core_type {
+    VCD_CORE_1080P,
+    VCD_CORE_720P
+};
+
+struct vcd_cmd_q_element {
+	enum vcd_command pending_cmd;
+};
+
+struct vcd_buffer_entry {
+	struct list_head sched_list;
+	struct list_head list;
+	u32 valid;
+	u8 *alloc;
+	u8 *virtual;
+	u8 *physical;
+	size_t sz;
+	u32 allocated;
+	u32 in_use;
+	struct vcd_frame_data frame;
+
+};
+
+struct vcd_buffer_pool {
+	struct vcd_buffer_entry *entries;
+	u32 count;
+	struct vcd_buffer_requirement buf_req;
+	u32 validated;
+	u32 allocated;
+	u32 in_use;
+	struct list_head queue;
+	u16 q_len;
+};
+
+struct vcd_transc {
+	u32 in_use;
+	enum vcd_command type;
+	struct vcd_clnt_ctxt *cctxt;
+
+	struct vcd_buffer_entry *ip_buf_entry;
+
+	s64 time_stamp;
+	u32 ip_frm_tag;
+	enum vcd_frame frame;
+
+	struct vcd_buffer_entry *op_buf_entry;
+
+	u32 input_done;
+	u32 frame_done;
+};
+
+struct vcd_dev_ctxt {
+	u32 ddl_cmd_concurrency;
+	u32 ddl_frame_ch_depth;
+	u32 ddl_cmd_ch_depth;
+	u32 ddl_frame_ch_interim;
+	u32 ddl_cmd_ch_interim;
+	u32 ddl_frame_ch_free;
+	u32 ddl_cmd_ch_free;
+
+	struct list_head sched_clnt_list;
+
+	struct vcd_init_config config;
+
+	u32 driver_ids[VCD_DRIVER_INSTANCE_MAX];
+	u32 refs;
+	u8 *device_base_addr;
+	void *hw_timer_handle;
+	u32               hw_time_out;
+	struct vcd_clnt_ctxt *cctxt_list_head;
+
+	enum vcd_command pending_cmd;
+
+	u32 command_continue;
+
+	struct vcd_transc *trans_tbl;
+	u32 trans_tbl_size;
+
+	enum vcd_power_state pwr_state;
+	enum vcd_pwr_clk_state pwr_clk_state;
+	u32 active_clnts;
+	u32 max_perf_lvl;
+	u32 reqd_perf_lvl;
+	u32 curr_perf_lvl;
+	u32 set_perf_lvl_pending;
+
+};
+
+struct vcd_clnt_status {
+	u32 req_perf_lvl;
+	u32 frame_submitted;
+	u32 frame_delayed;
+	u32 cmd_submitted;
+	u32 int_field_cnt;
+	s64 first_ts;
+	s64 prev_ts;
+	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;
+	u32	last_err;
+	u32	last_evt;
+	u32 mask;
+};
+
+struct vcd_sched_clnt_ctx {
+	struct list_head list;
+	u32 clnt_active;
+	void *clnt_data;
+	u32 tkns;
+	u32 round_perfrm;
+	u32 rounds;
+	struct list_head ip_frm_list;
+};
+
+struct vcd_clnt_ctxt {
+	u32 signature;
+	struct vcd_clnt_state_ctxt clnt_state;
+
+	s32 driver_id;
+
+	u32 live;
+	u32 decoding;
+	u32 bframe;
+
+	struct vcd_property_frame_rate frm_rate;
+	u32 frm_p_units;
+	u32 reqd_perf_lvl;
+	u32 time_resoln;
+
+	struct vcd_buffer_pool in_buf_pool;
+	struct vcd_buffer_pool out_buf_pool;
+
+	void (*callback) (u32 event, u32 status, void *info, size_t sz,
+			  void *handle, void *const client_data);
+	void *client_data;
+	struct vcd_sched_clnt_ctx *sched_clnt_hdl;
+	u32	ddl_hdl_valid;
+	u32 *ddl_handle;
+	struct vcd_dev_ctxt *dev_ctxt;
+	struct vcd_cmd_q_element cmd_q;
+	struct vcd_sequence_hdr seq_hdr;
+	u8 *seq_hdr_phy_addr;
+	struct vcd_clnt_status status;
+
+	struct vcd_clnt_ctxt *next;
+};
+
+#define VCD_BUFFERPOOL_INUSE_DECREMENT(val) \
+do { \
+	if ((val) > 0) \
+		val--; \
+	else { \
+		VCD_MSG_ERROR("%s(): Inconsistent val given in " \
+			" VCD_BUFFERPOOL_INUSE_DECREMENT\n", __func__); \
+	} \
+} while (0)
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
new file mode 100644
index 0000000..f8fb0fa
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c
@@ -0,0 +1,1203 @@
+/* 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_type.h"
+#include "vcd.h"
+
+static const struct vcd_dev_state_table *vcd_dev_state_table[];
+static const struct vcd_dev_state_table vcd_dev_table_null;
+
+struct vcd_drv_ctxt *vcd_get_drv_context(void)
+{
+	static struct vcd_drv_ctxt drv_context = {
+		{&vcd_dev_table_null, VCD_DEVICE_STATE_NULL},
+		{0},
+	};
+
+	return &drv_context;
+
+}
+
+void vcd_do_device_state_transition(struct vcd_drv_ctxt *drv_ctxt,
+	 enum vcd_dev_state_enum to_state, u32 ev_code)
+{
+	struct vcd_dev_state_ctxt *state_ctxt;
+
+	if (!drv_ctxt || to_state >= VCD_DEVICE_STATE_MAX) {
+		VCD_MSG_ERROR("Bad parameters. drv_ctxt=%p, to_state=%d",
+				  drv_ctxt, to_state);
+	}
+
+	state_ctxt = &drv_ctxt->dev_state;
+
+	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",
+			(int)state_ctxt->state, (int)to_state, ev_code);
+
+	if (state_ctxt->state_table->exit)
+		state_ctxt->state_table->exit(drv_ctxt, ev_code);
+
+
+	state_ctxt->state = to_state;
+	state_ctxt->state_table = vcd_dev_state_table[to_state];
+
+	if (state_ctxt->state_table->entry)
+		state_ctxt->state_table->entry(drv_ctxt, ev_code);
+}
+
+void vcd_hw_timeout_handler(void *user_data)
+{
+	struct vcd_drv_ctxt *drv_ctxt;
+
+	VCD_MSG_HIGH("vcd_hw_timeout_handler:");
+	user_data = NULL;
+	drv_ctxt = vcd_get_drv_context();
+	mutex_lock(&drv_ctxt->dev_mutex);
+	if (drv_ctxt->dev_state.state_table->ev_hdlr.timeout)
+		drv_ctxt->dev_state.state_table->ev_hdlr.
+			timeout(drv_ctxt, user_data);
+	else
+		VCD_MSG_ERROR("hw_timeout unsupported in device state %d",
+			drv_ctxt->dev_state.state);
+	mutex_unlock(&drv_ctxt->dev_mutex);
+}
+
+void vcd_ddl_callback(u32 event, u32 status, void *payload,
+	size_t sz, u32 *ddl_handle, void *const client_data)
+{
+	struct vcd_drv_ctxt *drv_ctxt;
+	struct vcd_dev_ctxt *dev_ctxt;
+	struct vcd_dev_state_ctxt *dev_state;
+	struct vcd_clnt_ctxt *cctxt;
+	struct vcd_transc *transc;
+
+	VCD_MSG_LOW("vcd_ddl_callback:");
+
+	VCD_MSG_LOW("event=0x%x status=0x%x", event, status);
+
+	drv_ctxt = vcd_get_drv_context();
+	dev_ctxt = &drv_ctxt->dev_ctxt;
+	dev_state = &drv_ctxt->dev_state;
+
+	dev_ctxt->command_continue = true;
+	vcd_device_timer_stop(dev_ctxt);
+
+	switch (dev_state->state) {
+	case VCD_DEVICE_STATE_NULL:
+		{
+			VCD_MSG_HIGH("Callback unexpected in NULL state");
+			break;
+		}
+
+	case VCD_DEVICE_STATE_NOT_INIT:
+		{
+			VCD_MSG_HIGH("Callback unexpected in NOT_INIT state");
+			break;
+		}
+
+	case VCD_DEVICE_STATE_INITING:
+		{
+			if (dev_state->state_table->ev_hdlr.dev_cb) {
+				dev_state->state_table->ev_hdlr.
+					dev_cb(drv_ctxt, event, status,
+						  payload, sz, ddl_handle,
+						  client_data);
+			} else {
+				VCD_MSG_HIGH("No device handler in %d state",
+						 dev_state->state);
+			}
+			break;
+		}
+
+	case VCD_DEVICE_STATE_READY:
+		{
+			transc = (struct vcd_transc *)client_data;
+
+			if (!transc || !transc->in_use
+				|| !transc->cctxt) {
+				VCD_MSG_ERROR("Invalid clientdata "
+							  "received from DDL ");
+			} else {
+				cctxt = transc->cctxt;
+
+				if (cctxt->clnt_state.state_table->ev_hdlr.
+					clnt_cb) {
+					cctxt->clnt_state.state_table->
+						ev_hdlr.clnt_cb(cctxt,
+						event, status, payload,
+						sz,	ddl_handle,
+						client_data);
+				} else {
+					VCD_MSG_HIGH
+					("No client handler in"
+					" (dsm:READY, csm:%d) state",
+					(int)cctxt->clnt_state.state);
+
+					if (VCD_FAILED(status)) {
+						VCD_MSG_FATAL("DDL callback"
+						" returned failure 0x%x",
+						status);
+					}
+				}
+			}
+			break;
+		}
+
+	default:
+		{
+			VCD_MSG_ERROR("Unknown state");
+			break;
+		}
+
+	}
+
+}
+
+u32 vcd_init_device_context(struct vcd_drv_ctxt *drv_ctxt,
+		u32 ev_code)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+	u32 rc;
+	struct ddl_init_config ddl_init;
+
+	VCD_MSG_LOW("vcd_init_device_context:");
+
+	dev_ctxt->pending_cmd = VCD_CMD_NONE;
+
+	rc = vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_INIT_BEGIN);
+	VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_INIT_BEGIN failed");
+
+	VCD_MSG_HIGH("Device powered ON and clocked");
+	rc = vcd_sched_create(&dev_ctxt->sched_clnt_list);
+	if (VCD_FAILED(rc)) {
+		VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_sched_create", rc);
+
+		(void)vcd_power_event(dev_ctxt, NULL,
+					  VCD_EVT_PWR_DEV_INIT_FAIL);
+
+		return rc;
+	}
+
+	VCD_MSG_HIGH("Created scheduler instance.");
+
+	ddl_init.core_virtual_base_addr = dev_ctxt->device_base_addr;
+	ddl_init.interrupt_clr = dev_ctxt->config.interrupt_clr;
+	ddl_init.ddl_callback = vcd_ddl_callback;
+
+	rc = ddl_device_init(&ddl_init, NULL);
+
+	if (VCD_FAILED(rc)) {
+		VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_init", rc);
+		vcd_sched_destroy(&dev_ctxt->sched_clnt_list);
+		(void)vcd_power_event(dev_ctxt, NULL,
+					  VCD_EVT_PWR_DEV_INIT_FAIL);
+	} else {
+		vcd_device_timer_start(dev_ctxt);
+		vcd_do_device_state_transition(drv_ctxt,
+						   VCD_DEVICE_STATE_INITING,
+						   ev_code);
+	}
+
+	return rc;
+}
+
+void vcd_handle_device_init_failed(struct vcd_drv_ctxt *drv_ctxt,
+		u32 status)
+{
+	struct vcd_clnt_ctxt *client;
+	struct vcd_clnt_ctxt *tmp_client;
+
+	VCD_MSG_ERROR("Device init failed. status = %d", status);
+
+	client = drv_ctxt->dev_ctxt.cctxt_list_head;
+	while (client) {
+		client->callback(VCD_EVT_RESP_OPEN,
+				   status, NULL, 0, 0, client->client_data);
+
+		tmp_client = client;
+		client = client->next;
+
+		vcd_destroy_client_context(tmp_client);
+	}
+	if (ddl_device_release(NULL))
+		VCD_MSG_ERROR("Failed: ddl_device_release");
+
+	vcd_sched_destroy(&drv_ctxt->dev_ctxt.sched_clnt_list);
+	if (vcd_power_event(&drv_ctxt->dev_ctxt,
+		NULL, VCD_EVT_PWR_DEV_INIT_FAIL))
+		VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_FAIL failed");
+
+	vcd_do_device_state_transition(drv_ctxt,
+		VCD_DEVICE_STATE_NOT_INIT,
+		DEVICE_STATE_EVENT_NUMBER(dev_cb));
+}
+
+u32 vcd_deinit_device_context(struct vcd_drv_ctxt *drv_ctxt,
+		u32 ev_code)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_deinit_device_context:");
+
+	rc = vcd_power_event(&drv_ctxt->dev_ctxt, NULL,
+				 VCD_EVT_PWR_DEV_TERM_BEGIN);
+
+	VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_TERM_BEGIN failed");
+
+	rc = ddl_device_release(NULL);
+
+	if (VCD_FAILED(rc)) {
+		VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_release", rc);
+
+		(void)vcd_power_event(dev_ctxt, NULL,
+					  VCD_EVT_PWR_DEV_TERM_FAIL);
+	} else {
+		vcd_sched_destroy(&dev_ctxt->sched_clnt_list);
+		(void) vcd_power_event(dev_ctxt, NULL,
+			VCD_EVT_PWR_DEV_TERM_END);
+
+		vcd_do_device_state_transition(drv_ctxt,
+			VCD_DEVICE_STATE_NOT_INIT, ev_code);
+	}
+	return rc;
+}
+
+void vcd_term_driver_context(struct vcd_drv_ctxt *drv_ctxt)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+
+	VCD_MSG_HIGH("All driver instances terminated");
+
+	if (dev_ctxt->config.deregister_isr)
+		dev_ctxt->config.deregister_isr();
+
+	if (dev_ctxt->config.un_map_dev_base_addr)
+		dev_ctxt->config.un_map_dev_base_addr();
+
+	if (dev_ctxt->config.timer_release)
+		dev_ctxt->config.timer_release(
+			dev_ctxt->hw_timer_handle);
+
+	kfree(dev_ctxt->trans_tbl);
+
+	memset(dev_ctxt, 0, sizeof(struct vcd_dev_ctxt));
+
+	vcd_do_device_state_transition(drv_ctxt,
+					   VCD_DEVICE_STATE_NULL,
+					   DEVICE_STATE_EVENT_NUMBER(term));
+
+}
+
+u32 vcd_reset_device_context(struct vcd_drv_ctxt *drv_ctxt,
+	u32 ev_code)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_reset_device_context:");
+	vcd_reset_device_channels(dev_ctxt);
+	rc = vcd_power_event(&drv_ctxt->dev_ctxt, NULL,
+						 VCD_EVT_PWR_DEV_TERM_BEGIN);
+	VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_TERM_BEGIN failed");
+	if (ddl_reset_hw(0))
+		VCD_MSG_HIGH("HW Reset done");
+	else
+		VCD_MSG_FATAL("HW Reset failed");
+
+	(void)vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_TERM_END);
+
+	return VCD_S_SUCCESS;
+}
+
+void vcd_handle_device_err_fatal(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_clnt_ctxt *trig_clnt)
+{
+	struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head;
+	struct vcd_clnt_ctxt *tmp_clnt = NULL;
+	VCD_MSG_LOW("vcd_handle_device_err_fatal:");
+	while (cctxt) {
+		tmp_clnt = cctxt;
+		cctxt = cctxt->next;
+		if (tmp_clnt != trig_clnt)
+			vcd_clnt_handle_device_err_fatal(tmp_clnt,
+				tmp_clnt->status.last_evt);
+	}
+	dev_ctxt->pending_cmd = VCD_CMD_DEVICE_RESET;
+	if (!dev_ctxt->cctxt_list_head)
+		vcd_do_device_state_transition(vcd_get_drv_context(),
+			VCD_DEVICE_STATE_NOT_INIT,
+			DEVICE_STATE_EVENT_NUMBER(timeout));
+	else
+		vcd_do_device_state_transition(vcd_get_drv_context(),
+			VCD_DEVICE_STATE_INVALID,
+			DEVICE_STATE_EVENT_NUMBER(dev_cb));
+}
+
+void vcd_handle_for_last_clnt_close(
+	struct vcd_dev_ctxt *dev_ctxt, u32 send_deinit)
+{
+	if (!dev_ctxt->cctxt_list_head) {
+		VCD_MSG_HIGH("All clients are closed");
+		if (send_deinit)
+			(void) vcd_deinit_device_context(
+				vcd_get_drv_context(),
+				DEVICE_STATE_EVENT_NUMBER(close));
+		else
+			dev_ctxt->pending_cmd =
+			VCD_CMD_DEVICE_TERM;
+	}
+}
+void vcd_continue(void)
+{
+	struct vcd_drv_ctxt *drv_ctxt;
+	struct vcd_dev_ctxt *dev_ctxt;
+	u32 command_continue;
+	struct vcd_transc *transc;
+	u32 rc;
+	VCD_MSG_LOW("vcd_continue:");
+
+	drv_ctxt = vcd_get_drv_context();
+	dev_ctxt = &drv_ctxt->dev_ctxt;
+
+	dev_ctxt->command_continue = false;
+
+	if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_INIT) {
+		VCD_MSG_HIGH("VCD_CMD_DEVICE_INIT is pending");
+
+		dev_ctxt->pending_cmd = VCD_CMD_NONE;
+
+		(void)vcd_init_device_context(drv_ctxt,
+			DEVICE_STATE_EVENT_NUMBER(open));
+	} else if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_TERM) {
+		VCD_MSG_HIGH("VCD_CMD_DEVICE_TERM is pending");
+
+		dev_ctxt->pending_cmd = VCD_CMD_NONE;
+
+		(void)vcd_deinit_device_context(drv_ctxt,
+			DEVICE_STATE_EVENT_NUMBER(close));
+	} else if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_RESET) {
+		VCD_MSG_HIGH("VCD_CMD_DEVICE_RESET is pending");
+		dev_ctxt->pending_cmd = VCD_CMD_NONE;
+		(void)vcd_reset_device_context(drv_ctxt,
+			DEVICE_STATE_EVENT_NUMBER(dev_cb));
+	} else {
+		if (dev_ctxt->set_perf_lvl_pending) {
+			rc = vcd_power_event(dev_ctxt, NULL,
+						 VCD_EVT_PWR_DEV_SET_PERFLVL);
+
+			if (VCD_FAILED(rc)) {
+				VCD_MSG_ERROR
+					("VCD_EVT_PWR_CLNT_SET_PERFLVL failed");
+				VCD_MSG_HIGH
+					("Not running at desired perf level."
+					 "curr=%d, reqd=%d",
+					 dev_ctxt->curr_perf_lvl,
+					 dev_ctxt->reqd_perf_lvl);
+			} else {
+				dev_ctxt->set_perf_lvl_pending = false;
+			}
+		}
+
+		do {
+			command_continue = false;
+
+			if (vcd_get_command_channel_in_loop
+				(dev_ctxt, &transc)) {
+				if (vcd_submit_command_in_continue(dev_ctxt,
+					transc))
+					command_continue = true;
+				else {
+					VCD_MSG_MED
+						("No more commands to submit");
+
+					vcd_release_command_channel(dev_ctxt,
+						transc);
+
+					vcd_release_interim_command_channels
+						(dev_ctxt);
+				}
+			}
+		} while (command_continue);
+
+		do {
+			command_continue = false;
+
+			if (vcd_get_frame_channel_in_loop
+				(dev_ctxt, &transc)) {
+				if (vcd_try_submit_frame_in_continue(dev_ctxt,
+					transc)) {
+					command_continue = true;
+				} else {
+					VCD_MSG_MED("No more frames to submit");
+
+					vcd_release_frame_channel(dev_ctxt,
+								  transc);
+
+					vcd_release_interim_frame_channels
+						(dev_ctxt);
+				}
+			}
+
+		} while (command_continue);
+
+		if (!vcd_core_is_busy(dev_ctxt)) {
+			rc = vcd_power_event(dev_ctxt, NULL,
+				VCD_EVT_PWR_CLNT_CMD_END);
+
+			if (VCD_FAILED(rc))
+				VCD_MSG_ERROR("Failed:"
+					"VCD_EVT_PWR_CLNT_CMD_END");
+		}
+	}
+}
+
+static void vcd_pause_all_sessions(struct vcd_dev_ctxt *dev_ctxt)
+{
+	struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head;
+	u32 rc;
+
+	while (cctxt) {
+		if (cctxt->clnt_state.state_table->ev_hdlr.pause) {
+			rc = cctxt->clnt_state.state_table->ev_hdlr.
+				pause(cctxt);
+
+			if (VCD_FAILED(rc))
+				VCD_MSG_ERROR("Client pause failed");
+
+		}
+
+		cctxt = cctxt->next;
+	}
+}
+
+static void vcd_resume_all_sessions(struct vcd_dev_ctxt *dev_ctxt)
+{
+	struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head;
+	u32 rc;
+
+	while (cctxt) {
+		if (cctxt->clnt_state.state_table->ev_hdlr.resume) {
+			rc = cctxt->clnt_state.state_table->ev_hdlr.
+				resume(cctxt);
+
+			if (VCD_FAILED(rc))
+				VCD_MSG_ERROR("Client resume failed");
+
+		}
+
+		cctxt = cctxt->next;
+	}
+}
+
+static u32 vcd_init_cmn
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 struct vcd_init_config *config, s32 *driver_handle)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+	s32 driver_id;
+
+	if (dev_ctxt->config.interrupt_clr !=
+		config->interrupt_clr
+		|| dev_ctxt->config.register_isr !=
+		config->register_isr
+		|| dev_ctxt->config.deregister_isr !=
+		config->deregister_isr
+		|| dev_ctxt->config.map_dev_base_addr !=
+		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");
+	}
+
+	*driver_handle = 0;
+
+	driver_id = 0;
+	while (driver_id < VCD_DRIVER_INSTANCE_MAX &&
+		   dev_ctxt->driver_ids[driver_id]) {
+		++driver_id;
+	}
+
+	if (driver_id == VCD_DRIVER_INSTANCE_MAX) {
+		VCD_MSG_ERROR("Max driver instances reached");
+
+		return VCD_ERR_FAIL;
+	}
+
+	++dev_ctxt->refs;
+	dev_ctxt->driver_ids[driver_id] = true;
+	*driver_handle = driver_id + 1;
+
+	VCD_MSG_HIGH("Driver_id = %d. No of driver instances = %d",
+			 driver_id, dev_ctxt->refs);
+
+	return VCD_S_SUCCESS;
+
+}
+
+static u32 vcd_init_in_null
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 struct vcd_init_config *config, s32 *driver_handle) {
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+	u32 done_create_timer = false;
+	VCD_MSG_LOW("vcd_init_in_dev_null:");
+
+
+	dev_ctxt->config = *config;
+
+	dev_ctxt->device_base_addr =
+		(u8 *)config->map_dev_base_addr(
+			dev_ctxt->config.device_name);
+
+	if (!dev_ctxt->device_base_addr) {
+		VCD_MSG_ERROR("NULL Device_base_addr");
+
+		return VCD_ERR_FAIL;
+	}
+
+	if (config->register_isr) {
+		config->register_isr(dev_ctxt->config.
+			device_name);
+	}
+
+	if (config->timer_create) {
+		if (config->timer_create(vcd_hw_timeout_handler,
+			NULL, &dev_ctxt->hw_timer_handle))
+			done_create_timer = true;
+		else {
+			VCD_MSG_ERROR("timercreate failed");
+			return VCD_ERR_FAIL;
+		}
+	}
+
+
+	rc = vcd_init_cmn(drv_ctxt, config, driver_handle);
+
+	if (!VCD_FAILED(rc)) {
+		vcd_do_device_state_transition(drv_ctxt,
+						   VCD_DEVICE_STATE_NOT_INIT,
+						   DEVICE_STATE_EVENT_NUMBER
+						   (init));
+	} else {
+		if (dev_ctxt->config.un_map_dev_base_addr)
+			dev_ctxt->config.un_map_dev_base_addr();
+
+		if (dev_ctxt->config.deregister_isr)
+			dev_ctxt->config.deregister_isr();
+
+		if (done_create_timer && dev_ctxt->config.timer_release)
+			dev_ctxt->config.timer_release(dev_ctxt->
+				hw_timer_handle);
+
+	}
+
+	return rc;
+
+}
+
+static u32 vcd_init_in_not_init
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 struct vcd_init_config *config, s32 *driver_handle)
+{
+
+	VCD_MSG_LOW("vcd_init_in_dev_not_init:");
+
+	return vcd_init_cmn(drv_ctxt, config, driver_handle);
+
+}
+
+static u32 vcd_init_in_initing
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 struct vcd_init_config *config, s32 *driver_handle) {
+
+	VCD_MSG_LOW("vcd_init_in_dev_initing:");
+
+	return vcd_init_cmn(drv_ctxt, config, driver_handle);
+
+}
+
+static u32 vcd_init_in_ready
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 struct vcd_init_config *config, s32 *driver_handle)
+{
+	VCD_MSG_LOW("vcd_init_in_dev_ready:");
+
+	return vcd_init_cmn(drv_ctxt, config, driver_handle);
+}
+
+static u32 vcd_term_cmn
+	(struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+
+	if (!vcd_validate_driver_handle(dev_ctxt, driver_handle)) {
+		VCD_MSG_ERROR("Invalid driver handle = %d", driver_handle);
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	if (vcd_check_for_client_context(dev_ctxt,
+				driver_handle - 1)) {
+		VCD_MSG_ERROR("Driver has active client");
+
+		return VCD_ERR_BAD_STATE;
+	}
+
+	--dev_ctxt->refs;
+	dev_ctxt->driver_ids[driver_handle - 1] = false;
+
+	VCD_MSG_HIGH("Driver_id %d terminated. No of driver instances = %d",
+			 driver_handle - 1, dev_ctxt->refs);
+
+	return VCD_S_SUCCESS;
+}
+
+static u32 vcd_term_in_not_init
+	(struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+	u32 rc;
+
+	VCD_MSG_LOW("vcd_term_in_dev_not_init:");
+
+	rc = vcd_term_cmn(drv_ctxt, driver_handle);
+
+	if (!VCD_FAILED(rc) && !dev_ctxt->refs)
+		vcd_term_driver_context(drv_ctxt);
+
+	return rc;
+}
+
+static u32 vcd_term_in_initing
+	(struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle)
+{
+	VCD_MSG_LOW("vcd_term_in_dev_initing:");
+
+	return vcd_term_cmn(drv_ctxt, driver_handle);
+}
+
+static u32 vcd_term_in_ready
+	(struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle)
+{
+	VCD_MSG_LOW("vcd_term_in_dev_ready:");
+
+	return vcd_term_cmn(drv_ctxt, driver_handle);
+}
+
+static u32  vcd_term_in_invalid(struct vcd_drv_ctxt *drv_ctxt,
+							 s32  driver_handle)
+{
+	u32 rc;
+	VCD_MSG_LOW("vcd_term_in_invalid:");
+	rc = vcd_term_cmn(drv_ctxt, driver_handle);
+	if (!VCD_FAILED(rc) && !drv_ctxt->dev_ctxt.refs)
+		vcd_term_driver_context(drv_ctxt);
+
+	return rc;
+}
+
+static u32 vcd_open_cmn
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 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, struct vcd_clnt_ctxt ** clnt_cctxt)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+	struct vcd_clnt_ctxt *cctxt;
+	struct vcd_clnt_ctxt *client;
+
+	if (!vcd_validate_driver_handle(dev_ctxt, driver_handle)) {
+		VCD_MSG_ERROR("Invalid driver handle = %d", driver_handle);
+
+		return VCD_ERR_BAD_HANDLE;
+	}
+
+	cctxt =	(struct vcd_clnt_ctxt *)
+		kmalloc(sizeof(struct vcd_clnt_ctxt), GFP_KERNEL);
+	if (!cctxt) {
+		VCD_MSG_ERROR("No memory for client ctxt");
+
+		return VCD_ERR_ALLOC_FAIL;
+	}
+
+	memset(cctxt, 0, sizeof(struct vcd_clnt_ctxt));
+	cctxt->dev_ctxt = dev_ctxt;
+	cctxt->driver_id = driver_handle - 1;
+	cctxt->decoding = decoding;
+	cctxt->callback = callback;
+	cctxt->client_data = client_data;
+	cctxt->status.last_evt = VCD_EVT_RESP_OPEN;
+	INIT_LIST_HEAD(&cctxt->in_buf_pool.queue);
+	INIT_LIST_HEAD(&cctxt->out_buf_pool.queue);
+	client = dev_ctxt->cctxt_list_head;
+	dev_ctxt->cctxt_list_head = cctxt;
+	cctxt->next = client;
+
+	*clnt_cctxt = cctxt;
+
+	return VCD_S_SUCCESS;
+
+}
+
+static u32 vcd_open_in_not_init
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 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)
+{
+	struct vcd_clnt_ctxt *cctxt;
+	u32 rc;
+
+	VCD_MSG_LOW("vcd_open_in_dev_not_init:");
+
+	rc = vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback,
+			  client_data, &cctxt);
+
+	VCD_FAILED_RETURN(rc, "Failed: vcd_open_cmn");
+
+	rc = vcd_init_device_context(drv_ctxt,
+					 DEVICE_STATE_EVENT_NUMBER(open));
+
+	if (VCD_FAILED(rc))
+		vcd_destroy_client_context(cctxt);
+
+	return rc;
+}
+
+static u32 vcd_open_in_initing(struct vcd_drv_ctxt *drv_ctxt,
+	 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)
+{
+	struct vcd_clnt_ctxt *cctxt;
+
+	VCD_MSG_LOW("vcd_open_in_dev_initing:");
+
+	return vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback,
+				 client_data, &cctxt);
+}
+
+static u32 vcd_open_in_ready
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 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)
+{
+	struct vcd_clnt_ctxt *cctxt;
+	struct vcd_handle_container container;
+	u32 rc;
+
+	VCD_MSG_LOW("vcd_open_in_dev_ready:");
+
+	rc = vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback,
+			  client_data, &cctxt);
+
+	VCD_FAILED_RETURN(rc, "Failed: vcd_open_cmn");
+
+	rc = vcd_init_client_context(cctxt);
+
+	if (!VCD_FAILED(rc)) {
+		container.handle = (void *)cctxt;
+
+		callback(VCD_EVT_RESP_OPEN,
+			 VCD_S_SUCCESS,
+			 &container,
+			 sizeof(container), container.handle, client_data);
+	} else {
+		VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_init_client_context", rc);
+
+		vcd_destroy_client_context(cctxt);
+	}
+
+	return rc;
+}
+
+static u32 vcd_close_in_ready
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 struct vcd_clnt_ctxt *cctxt) {
+	u32 rc;
+
+	VCD_MSG_LOW("vcd_close_in_dev_ready:");
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.close) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+			close(cctxt);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+				  cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	if (!VCD_FAILED(rc))
+		vcd_handle_for_last_clnt_close(&drv_ctxt->dev_ctxt, true);
+
+	return rc;
+}
+
+static u32  vcd_close_in_dev_invalid(struct vcd_drv_ctxt *drv_ctxt,
+	struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc;
+	VCD_MSG_LOW("vcd_close_in_dev_invalid:");
+	if (cctxt->clnt_state.state_table->ev_hdlr.close) {
+		rc = cctxt->clnt_state.state_table->
+			ev_hdlr.close(cctxt);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+					  cctxt->clnt_state.state);
+		rc = VCD_ERR_BAD_STATE;
+	}
+	if (!VCD_FAILED(rc) && !drv_ctxt->dev_ctxt.
+		cctxt_list_head) {
+		VCD_MSG_HIGH("All INVALID clients are closed");
+		vcd_do_device_state_transition(drv_ctxt,
+			VCD_DEVICE_STATE_NOT_INIT,
+			DEVICE_STATE_EVENT_NUMBER(close));
+	}
+	return rc;
+}
+
+static u32 vcd_resume_in_ready
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 struct vcd_clnt_ctxt *cctxt) {
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_resume_in_ready:");
+
+	if (cctxt->clnt_state.state_table->ev_hdlr.resume) {
+		rc = cctxt->clnt_state.state_table->ev_hdlr.
+			resume(cctxt);
+	} else {
+		VCD_MSG_ERROR("Unsupported API in client state %d",
+				  cctxt->clnt_state.state);
+
+		rc = VCD_ERR_BAD_STATE;
+	}
+
+	return rc;
+}
+
+static u32 vcd_set_dev_pwr_in_ready
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 enum vcd_power_state pwr_state)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+
+	VCD_MSG_LOW("vcd_set_dev_pwr_in_ready:");
+
+	switch (pwr_state) {
+	case VCD_PWR_STATE_SLEEP:
+		{
+			if (dev_ctxt->pwr_state == VCD_PWR_STATE_ON)
+				vcd_pause_all_sessions(dev_ctxt);
+			dev_ctxt->pwr_state = VCD_PWR_STATE_SLEEP;
+			break;
+		}
+
+	case VCD_PWR_STATE_ON:
+		{
+			if (dev_ctxt->pwr_state == VCD_PWR_STATE_SLEEP)
+				vcd_resume_all_sessions(dev_ctxt);
+			dev_ctxt->pwr_state = VCD_PWR_STATE_ON;
+			break;
+		}
+
+	default:
+		{
+			VCD_MSG_ERROR("Invalid power state requested %d",
+					  pwr_state);
+			break;
+		}
+
+	}
+
+	return rc;
+}
+
+static void vcd_dev_cb_in_initing
+	(struct vcd_drv_ctxt *drv_ctxt,
+	 u32 event,
+	 u32 status,
+	 void *payload, size_t sz, u32 *ddl_handle, void *const client_data)
+{
+	struct vcd_dev_ctxt *dev_ctxt;
+	struct vcd_clnt_ctxt *client;
+	struct vcd_clnt_ctxt *tmp_client;
+	struct vcd_handle_container container;
+	u32 rc = VCD_S_SUCCESS;
+	u32 client_inited = false;
+	u32 fail_all_open = false;
+
+	VCD_MSG_LOW("vcd_dev_cb_in_initing:");
+
+	if (event != VCD_EVT_RESP_DEVICE_INIT) {
+		VCD_MSG_ERROR("vcd_dev_cb_in_initing: Unexpected event %d",
+				  (int)event);
+		return;
+	}
+
+	dev_ctxt = &drv_ctxt->dev_ctxt;
+
+	dev_ctxt->command_continue = false;
+
+	if (VCD_FAILED(status)) {
+		vcd_handle_device_init_failed(drv_ctxt, status);
+
+		return;
+	}
+
+	vcd_do_device_state_transition(drv_ctxt,
+					   VCD_DEVICE_STATE_READY,
+					   DEVICE_STATE_EVENT_NUMBER(open));
+
+	if (!dev_ctxt->cctxt_list_head) {
+		VCD_MSG_HIGH("All clients are closed");
+
+		dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM;
+
+		return;
+	}
+
+	if (!dev_ctxt->ddl_cmd_ch_depth
+		|| !dev_ctxt->trans_tbl)
+		rc = vcd_setup_with_ddl_capabilities(dev_ctxt);
+
+
+	if (VCD_FAILED(rc)) {
+		VCD_MSG_ERROR
+			("rc = 0x%x: Failed vcd_setup_with_ddl_capabilities",
+			 rc);
+
+		fail_all_open = true;
+	}
+
+	client = dev_ctxt->cctxt_list_head;
+	while (client) {
+		if (!fail_all_open)
+			rc = vcd_init_client_context(client);
+
+
+		if (!VCD_FAILED(rc)) {
+			container.handle = (void *)client;
+			client->callback(VCD_EVT_RESP_OPEN,
+					   VCD_S_SUCCESS,
+					   &container,
+					   sizeof(container),
+					   container.handle,
+					   client->client_data);
+
+			client = client->next;
+
+			client_inited = true;
+		} else {
+			VCD_MSG_ERROR
+				("rc = 0x%x, Failed: vcd_init_client_context",
+				 rc);
+
+			client->callback(VCD_EVT_RESP_OPEN,
+					   rc,
+					   NULL, 0, 0, client->client_data);
+
+			tmp_client = client;
+			client = client->next;
+
+			vcd_destroy_client_context(tmp_client);
+		}
+	}
+
+	if (!client_inited || fail_all_open) {
+		VCD_MSG_ERROR("All client open requests failed");
+
+		dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM;
+	} else {
+		if (vcd_power_event(dev_ctxt, NULL,
+					 VCD_EVT_PWR_DEV_INIT_END)) {
+			VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_END failed");
+		}
+	}
+}
+
+static void  vcd_hw_timeout_cmn(struct vcd_drv_ctxt *drv_ctxt,
+							  void *user_data)
+{
+	struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt;
+	VCD_MSG_LOW("vcd_hw_timeout_cmn:");
+	vcd_device_timer_stop(dev_ctxt);
+
+	vcd_handle_device_err_fatal(dev_ctxt, NULL);
+
+	/* Reset HW. */
+	(void) vcd_reset_device_context(drv_ctxt,
+		DEVICE_STATE_EVENT_NUMBER(timeout));
+}
+
+static void vcd_dev_enter_null
+	(struct vcd_drv_ctxt *drv_ctxt, s32 state_event) {
+	VCD_MSG_MED("Entering DEVICE_STATE_NULL on api %d", state_event);
+
+}
+
+static void vcd_dev_enter_not_init
+	(struct vcd_drv_ctxt *drv_ctxt, s32 state_event) {
+	VCD_MSG_MED("Entering DEVICE_STATE_NOT_INIT on api %d",
+			state_event);
+
+}
+
+static void vcd_dev_enter_initing
+	(struct vcd_drv_ctxt *drv_ctxt, s32 state_event) {
+	VCD_MSG_MED("Entering DEVICE_STATE_INITING on api %d",
+			state_event);
+
+}
+
+static void vcd_dev_enter_ready
+	(struct vcd_drv_ctxt *drv_ctxt, s32 state_event) {
+	VCD_MSG_MED("Entering DEVICE_STATE_READY on api %d",
+			state_event);
+}
+
+static void vcd_dev_enter_invalid(struct vcd_drv_ctxt *drv_ctxt,
+							   s32 state_event)
+{
+   VCD_MSG_MED("Entering DEVICE_STATE_INVALID on api %d", state_event);
+}
+
+static void vcd_dev_exit_null
+	(struct vcd_drv_ctxt *drv_ctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting DEVICE_STATE_NULL on api %d", state_event);
+}
+
+static void vcd_dev_exit_not_init
+	(struct vcd_drv_ctxt *drv_ctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting DEVICE_STATE_NOT_INIT on api %d",
+			state_event);
+
+}
+
+static void vcd_dev_exit_initing
+	(struct vcd_drv_ctxt *drv_ctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting DEVICE_STATE_INITING on api %d",
+			state_event);
+}
+
+static void vcd_dev_exit_ready
+	(struct vcd_drv_ctxt *drv_ctxt, s32 state_event) {
+	VCD_MSG_MED("Exiting DEVICE_STATE_READY on api %d", state_event);
+}
+
+static void vcd_dev_exit_invalid(struct vcd_drv_ctxt *drv_ctxt,
+							  s32 state_event)
+{
+   VCD_MSG_MED("Exiting DEVICE_STATE_INVALID on api %d", state_event);
+}
+
+static const struct vcd_dev_state_table vcd_dev_table_null = {
+	{
+	 vcd_init_in_null,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 },
+	vcd_dev_enter_null,
+	vcd_dev_exit_null
+};
+
+static const struct vcd_dev_state_table vcd_dev_table_not_init = {
+	{
+	 vcd_init_in_not_init,
+	 vcd_term_in_not_init,
+	 vcd_open_in_not_init,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 NULL,
+	 },
+	vcd_dev_enter_not_init,
+	vcd_dev_exit_not_init
+};
+
+static const struct vcd_dev_state_table vcd_dev_table_initing = {
+	{
+	 vcd_init_in_initing,
+	 vcd_term_in_initing,
+	 vcd_open_in_initing,
+	 NULL,
+	 NULL,
+	 NULL,
+	 vcd_dev_cb_in_initing,
+	 vcd_hw_timeout_cmn,
+	 },
+	vcd_dev_enter_initing,
+	vcd_dev_exit_initing
+};
+
+static const struct vcd_dev_state_table vcd_dev_table_ready = {
+	{
+	 vcd_init_in_ready,
+	 vcd_term_in_ready,
+	 vcd_open_in_ready,
+	 vcd_close_in_ready,
+	 vcd_resume_in_ready,
+	 vcd_set_dev_pwr_in_ready,
+	 NULL,
+	 vcd_hw_timeout_cmn,
+	 },
+	vcd_dev_enter_ready,
+	vcd_dev_exit_ready
+};
+
+static const struct vcd_dev_state_table vcd_dev_table_in_invalid = {
+	{
+		NULL,
+		vcd_term_in_invalid,
+		NULL,
+		vcd_close_in_dev_invalid,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+	},
+	vcd_dev_enter_invalid,
+	vcd_dev_exit_invalid
+};
+
+static const struct vcd_dev_state_table *vcd_dev_state_table[] = {
+	&vcd_dev_table_null,
+	&vcd_dev_table_not_init,
+	&vcd_dev_table_initing,
+	&vcd_dev_table_ready,
+	&vcd_dev_table_in_invalid
+};
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
new file mode 100644
index 0000000..8245966
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h
@@ -0,0 +1,96 @@
+/* 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_DEVICE_SM_H_
+#define _VCD_DEVICE_SM_H_
+
+#include "vcd_api.h"
+#include "vcd_ddl_api.h"
+#include "vcd_core.h"
+
+struct vcd_dev_state_table;
+struct vcd_dev_state_ctxt;
+struct vcd_drv_ctxt;
+
+enum vcd_dev_state_enum {
+	VCD_DEVICE_STATE_NULL = 0,
+	VCD_DEVICE_STATE_NOT_INIT,
+	VCD_DEVICE_STATE_INITING,
+	VCD_DEVICE_STATE_READY,
+	VCD_DEVICE_STATE_INVALID,
+	VCD_DEVICE_STATE_MAX,
+	VCD_DEVICE_STATE_32BIT = 0x7FFFFFFF
+};
+
+struct vcd_dev_state_table {
+	struct {
+		u32(*init) (struct vcd_drv_ctxt *drv_ctxt,
+				struct vcd_init_config *config,
+				s32 *driver_handle);
+
+		u32(*term) (struct vcd_drv_ctxt *drv_ctxt,
+				s32 driver_handle);
+
+		u32(*open) (struct vcd_drv_ctxt *drv_ctxt,
+				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);
+
+		u32(*close) (struct vcd_drv_ctxt *drv_ctxt,
+				struct vcd_clnt_ctxt *cctxt);
+
+		u32(*resume) (struct vcd_drv_ctxt *drv_ctxt,
+				struct vcd_clnt_ctxt *cctxt);
+
+		u32(*set_dev_pwr) (struct vcd_drv_ctxt *drv_ctxt,
+				enum vcd_power_state pwr_state);
+
+		void (*dev_cb) (struct vcd_drv_ctxt *drv_ctxt,
+				u32 event, u32 status, void *payload,
+				size_t sz, u32 *ddl_handle,
+				void *const client_data);
+
+		void (*timeout) (struct vcd_drv_ctxt *drv_ctxt,
+							void *user_data);
+	} ev_hdlr;
+
+	void (*entry) (struct vcd_drv_ctxt *drv_ctxt,
+			s32 state_event);
+	void (*exit) (struct vcd_drv_ctxt *drv_ctxt,
+			s32 state_event);
+};
+
+#define   DEVICE_STATE_EVENT_NUMBER(ppf) \
+	((u32 *) (&(((struct vcd_dev_state_table*)0)->ev_hdlr.ppf)) - \
+	(u32 *) (&(((struct vcd_dev_state_table*)0)->ev_hdlr.init)) \
+	+ 1)
+
+struct vcd_dev_state_ctxt {
+	const struct vcd_dev_state_table *state_table;
+
+	enum vcd_dev_state_enum state;
+};
+
+struct vcd_drv_ctxt {
+	struct vcd_dev_state_ctxt dev_state;
+	struct vcd_dev_ctxt dev_ctxt;
+	struct mutex dev_mutex;
+};
+
+
+extern struct vcd_drv_ctxt *vcd_get_drv_context(void);
+
+void vcd_continue(void);
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
new file mode 100644
index 0000000..fff6a3b
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c
@@ -0,0 +1,351 @@
+/* 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_type.h"
+#include "vcd_power_sm.h"
+#include "vcd_core.h"
+#include "vcd.h"
+
+u32 vcd_power_event(
+	struct vcd_dev_ctxt *dev_ctxt,
+     struct vcd_clnt_ctxt *cctxt, u32 event)
+{
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_MED("Device power state = %d", dev_ctxt->pwr_clk_state);
+	VCD_MSG_MED("event = 0x%x", event);
+	switch (event) {
+
+	case VCD_EVT_PWR_DEV_INIT_BEGIN:
+	case VCD_EVT_PWR_DEV_INIT_END:
+	case VCD_EVT_PWR_DEV_INIT_FAIL:
+	case VCD_EVT_PWR_DEV_TERM_BEGIN:
+	case VCD_EVT_PWR_DEV_TERM_END:
+	case VCD_EVT_PWR_DEV_TERM_FAIL:
+	case VCD_EVT_PWR_DEV_SLEEP_BEGIN:
+	case VCD_EVT_PWR_DEV_SLEEP_END:
+	case VCD_EVT_PWR_DEV_SET_PERFLVL:
+	case VCD_EVT_PWR_DEV_HWTIMEOUT:
+		{
+			rc = vcd_device_power_event(dev_ctxt, event,
+				cctxt);
+			break;
+		}
+
+	case VCD_EVT_PWR_CLNT_CMD_BEGIN:
+	case VCD_EVT_PWR_CLNT_CMD_END:
+	case VCD_EVT_PWR_CLNT_CMD_FAIL:
+	case VCD_EVT_PWR_CLNT_PAUSE:
+	case VCD_EVT_PWR_CLNT_RESUME:
+	case VCD_EVT_PWR_CLNT_FIRST_FRAME:
+	case VCD_EVT_PWR_CLNT_LAST_FRAME:
+	case VCD_EVT_PWR_CLNT_ERRFATAL:
+		{
+			rc = vcd_client_power_event(dev_ctxt, cctxt, event);
+			break;
+		}
+
+	}
+
+	if (VCD_FAILED(rc))
+		VCD_MSG_ERROR("vcd_power_event: event 0x%x failed", event);
+
+
+	return rc;
+
+}
+
+u32 vcd_device_power_event(struct vcd_dev_ctxt *dev_ctxt, u32 event,
+	struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_ERR_FAIL;
+	u32 set_perf_lvl;
+
+	switch (event) {
+
+	case VCD_EVT_PWR_DEV_INIT_BEGIN:
+	{
+		if (dev_ctxt->pwr_clk_state ==
+			VCD_PWRCLK_STATE_OFF) {
+			if (res_trk_get_max_perf_level(&dev_ctxt->
+				max_perf_lvl)) {
+				if (res_trk_power_up()) {
+					dev_ctxt->pwr_clk_state =
+					VCD_PWRCLK_STATE_ON_NOTCLOCKED;
+					dev_ctxt->curr_perf_lvl = 0;
+					dev_ctxt->reqd_perf_lvl = 0;
+					dev_ctxt->active_clnts = 0;
+					dev_ctxt->
+						set_perf_lvl_pending = false;
+					rc = vcd_enable_clock(dev_ctxt,
+						cctxt);
+					if (VCD_FAILED(rc)) {
+						(void)res_trk_power_down();
+						dev_ctxt->pwr_clk_state =
+							VCD_PWRCLK_STATE_OFF;
+					}
+				}
+			}
+		}
+
+		break;
+	}
+
+	case VCD_EVT_PWR_DEV_INIT_END:
+	case VCD_EVT_PWR_DEV_TERM_FAIL:
+	case VCD_EVT_PWR_DEV_SLEEP_BEGIN:
+	case VCD_EVT_PWR_DEV_HWTIMEOUT:
+		{
+			rc = vcd_gate_clock(dev_ctxt);
+
+			break;
+		}
+
+	case VCD_EVT_PWR_DEV_INIT_FAIL:
+	case VCD_EVT_PWR_DEV_TERM_END:
+		{
+			if (dev_ctxt->pwr_clk_state !=
+				VCD_PWRCLK_STATE_OFF) {
+				(void)vcd_disable_clock(dev_ctxt);
+				(void)res_trk_power_down();
+
+				dev_ctxt->pwr_clk_state =
+				    VCD_PWRCLK_STATE_OFF;
+				dev_ctxt->curr_perf_lvl = 0;
+				dev_ctxt->reqd_perf_lvl = 0;
+				dev_ctxt->active_clnts = 0;
+				dev_ctxt->set_perf_lvl_pending = false;
+				rc = VCD_S_SUCCESS;
+			}
+
+			break;
+		}
+
+	case VCD_EVT_PWR_DEV_TERM_BEGIN:
+	case VCD_EVT_PWR_DEV_SLEEP_END:
+		{
+			rc = vcd_un_gate_clock(dev_ctxt);
+
+			break;
+		}
+
+	case VCD_EVT_PWR_DEV_SET_PERFLVL:
+		{
+			set_perf_lvl =
+			    dev_ctxt->reqd_perf_lvl >
+			    0 ? dev_ctxt->
+			    reqd_perf_lvl : VCD_MIN_PERF_LEVEL;
+			rc = vcd_set_perf_level(dev_ctxt, set_perf_lvl);
+			break;
+		}
+	}
+	return rc;
+}
+
+u32 vcd_client_power_event(
+	struct vcd_dev_ctxt *dev_ctxt,
+    struct vcd_clnt_ctxt *cctxt, u32 event)
+{
+	u32 rc = VCD_ERR_FAIL;
+
+	switch (event) {
+
+	case VCD_EVT_PWR_CLNT_CMD_BEGIN:
+		{
+			rc = vcd_un_gate_clock(dev_ctxt);
+			break;
+		}
+
+	case VCD_EVT_PWR_CLNT_CMD_END:
+		{
+			rc = vcd_gate_clock(dev_ctxt);
+			break;
+		}
+
+	case VCD_EVT_PWR_CLNT_CMD_FAIL:
+		{
+			if (!vcd_core_is_busy(dev_ctxt))
+				rc = vcd_gate_clock(dev_ctxt);
+
+			break;
+		}
+
+	case VCD_EVT_PWR_CLNT_PAUSE:
+	case VCD_EVT_PWR_CLNT_LAST_FRAME:
+	case VCD_EVT_PWR_CLNT_ERRFATAL:
+		{
+			if (cctxt) {
+				rc = VCD_S_SUCCESS;
+				if (cctxt->status.req_perf_lvl) {
+					dev_ctxt->reqd_perf_lvl -=
+						cctxt->reqd_perf_lvl;
+					cctxt->status.req_perf_lvl = false;
+					rc = vcd_set_perf_level(dev_ctxt,
+						dev_ctxt->reqd_perf_lvl);
+				}
+			}
+
+			break;
+		}
+
+	case VCD_EVT_PWR_CLNT_RESUME:
+	case VCD_EVT_PWR_CLNT_FIRST_FRAME:
+		{
+			if (cctxt) {
+				rc = VCD_S_SUCCESS;
+				if (!cctxt->status.req_perf_lvl) {
+					dev_ctxt->reqd_perf_lvl +=
+						cctxt->reqd_perf_lvl;
+					cctxt->status.req_perf_lvl = true;
+
+					rc = vcd_set_perf_level(dev_ctxt,
+						dev_ctxt->reqd_perf_lvl);
+				}
+			}
+			break;
+		}
+	}
+
+	return rc;
+}
+
+u32 vcd_enable_clock(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	u32 set_perf_lvl;
+
+	if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF) {
+		VCD_MSG_ERROR("vcd_enable_clock(): Already in state "
+			"VCD_PWRCLK_STATE_OFF\n");
+		rc = VCD_ERR_FAIL;
+	} else if (dev_ctxt->pwr_clk_state ==
+		VCD_PWRCLK_STATE_ON_NOTCLOCKED) {
+		set_perf_lvl =
+				dev_ctxt->reqd_perf_lvl >
+				0 ? dev_ctxt->
+				reqd_perf_lvl : VCD_MIN_PERF_LEVEL;
+		rc = vcd_set_perf_level(dev_ctxt, set_perf_lvl);
+		if (!VCD_FAILED(rc)) {
+			if (res_trk_enable_clocks()) {
+				dev_ctxt->pwr_clk_state =
+					VCD_PWRCLK_STATE_ON_CLOCKED;
+			}
+		} else {
+			rc = VCD_ERR_FAIL;
+		}
+
+	}
+
+	if (!VCD_FAILED(rc))
+		dev_ctxt->active_clnts++;
+
+	return rc;
+}
+
+u32 vcd_disable_clock(struct vcd_dev_ctxt *dev_ctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+
+	if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF) {
+		VCD_MSG_ERROR("vcd_disable_clock(): Already in state "
+			"VCD_PWRCLK_STATE_OFF\n");
+		rc = VCD_ERR_FAIL;
+	} else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKED ||
+		dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKGATED) {
+		dev_ctxt->active_clnts--;
+
+		if (!dev_ctxt->active_clnts) {
+			if (!res_trk_disable_clocks())
+				rc = VCD_ERR_FAIL;
+
+			dev_ctxt->pwr_clk_state =
+			    VCD_PWRCLK_STATE_ON_NOTCLOCKED;
+			dev_ctxt->curr_perf_lvl = 0;
+		}
+	}
+
+	return rc;
+}
+
+u32 vcd_set_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (!vcd_core_is_busy(dev_ctxt)) {
+		if (res_trk_set_perf_level(perf_lvl,
+			&dev_ctxt->curr_perf_lvl, dev_ctxt)) {
+			dev_ctxt->set_perf_lvl_pending = false;
+		} else {
+			rc = VCD_ERR_FAIL;
+			dev_ctxt->set_perf_lvl_pending = true;
+		}
+
+	} else {
+		dev_ctxt->set_perf_lvl_pending = true;
+	}
+
+	return rc;
+}
+
+u32 vcd_update_clnt_perf_lvl(
+	struct vcd_clnt_ctxt *cctxt,
+     struct vcd_property_frame_rate *fps, u32 frm_p_units)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 new_perf_lvl;
+	new_perf_lvl =
+	    frm_p_units * fps->fps_numerator / fps->fps_denominator;
+	if (cctxt->status.req_perf_lvl) {
+		dev_ctxt->reqd_perf_lvl =
+		    dev_ctxt->reqd_perf_lvl - cctxt->reqd_perf_lvl +
+		    new_perf_lvl;
+		rc = vcd_set_perf_level(cctxt->dev_ctxt,
+			dev_ctxt->reqd_perf_lvl);
+	}
+	cctxt->reqd_perf_lvl = new_perf_lvl;
+	return rc;
+}
+
+u32 vcd_gate_clock(struct vcd_dev_ctxt *dev_ctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF ||
+		dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_NOTCLOCKED) {
+		VCD_MSG_ERROR("%s(): Clk is Off or Not Clked yet\n", __func__);
+		rc = VCD_ERR_FAIL;
+	} else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKGATED)
+		rc = VCD_S_SUCCESS;
+	else if (res_trk_disable_clocks())
+		dev_ctxt->pwr_clk_state = VCD_PWRCLK_STATE_ON_CLOCKGATED;
+	else
+		rc = VCD_ERR_FAIL;
+	return rc;
+}
+
+u32 vcd_un_gate_clock(struct vcd_dev_ctxt *dev_ctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF ||
+		dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_NOTCLOCKED) {
+		VCD_MSG_ERROR("%s(): Clk is Off or Not Clked yet\n", __func__);
+		rc = VCD_ERR_FAIL;
+	} else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKED)
+		rc = VCD_S_SUCCESS;
+	else if (res_trk_enable_clocks())
+		dev_ctxt->pwr_clk_state = VCD_PWRCLK_STATE_ON_CLOCKED;
+	else
+		rc = VCD_ERR_FAIL;
+	return rc;
+}
+
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
new file mode 100644
index 0000000..26ce019
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h
@@ -0,0 +1,43 @@
+/* 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_POWERSM_H_
+#define _VCD_POWERSM_H_
+
+#define VCD_EVT_PWR_BASE                0x5000
+#define VCD_EVT_PWR_DEV_INIT_BEGIN      (VCD_EVT_PWR_BASE + 0x1)
+#define VCD_EVT_PWR_DEV_INIT_END        (VCD_EVT_PWR_BASE + 0x2)
+#define VCD_EVT_PWR_DEV_INIT_FAIL       (VCD_EVT_PWR_BASE + 0x3)
+#define VCD_EVT_PWR_DEV_TERM_BEGIN      (VCD_EVT_PWR_BASE + 0x4)
+#define VCD_EVT_PWR_DEV_TERM_END        (VCD_EVT_PWR_BASE + 0x5)
+#define VCD_EVT_PWR_DEV_TERM_FAIL       (VCD_EVT_PWR_BASE + 0x6)
+#define VCD_EVT_PWR_DEV_SLEEP_BEGIN     (VCD_EVT_PWR_BASE + 0x7)
+#define VCD_EVT_PWR_DEV_SLEEP_END       (VCD_EVT_PWR_BASE + 0x8)
+#define VCD_EVT_PWR_DEV_SET_PERFLVL     (VCD_EVT_PWR_BASE + 0x9)
+#define VCD_EVT_PWR_DEV_HWTIMEOUT       (VCD_EVT_PWR_BASE + 0xa)
+#define VCD_EVT_PWR_CLNT_CMD_BEGIN      (VCD_EVT_PWR_BASE + 0xb)
+#define VCD_EVT_PWR_CLNT_CMD_END        (VCD_EVT_PWR_BASE + 0xc)
+#define VCD_EVT_PWR_CLNT_CMD_FAIL       (VCD_EVT_PWR_BASE + 0xd)
+#define VCD_EVT_PWR_CLNT_PAUSE          (VCD_EVT_PWR_BASE + 0xe)
+#define VCD_EVT_PWR_CLNT_RESUME         (VCD_EVT_PWR_BASE + 0xf)
+#define VCD_EVT_PWR_CLNT_FIRST_FRAME    (VCD_EVT_PWR_BASE + 0x10)
+#define VCD_EVT_PWR_CLNT_LAST_FRAME     (VCD_EVT_PWR_BASE + 0x11)
+#define VCD_EVT_PWR_CLNT_ERRFATAL       (VCD_EVT_PWR_BASE + 0x12)
+
+enum vcd_pwr_clk_state {
+	VCD_PWRCLK_STATE_OFF = 0,
+	VCD_PWRCLK_STATE_ON_NOTCLOCKED,
+	VCD_PWRCLK_STATE_ON_CLOCKED,
+	VCD_PWRCLK_STATE_ON_CLOCKGATED
+};
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_property.h b/drivers/video/msm/vidc/common/vcd/vcd_property.h
new file mode 100644
index 0000000..2cb894e
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_property.h
@@ -0,0 +1,342 @@
+/* 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 _VCD_DRIVER_PROPERTY_H_
+#define _VCD_DRIVER_PROPERTY_H_
+
+#define VCD_START_BASE       0x0
+#define VCD_I_LIVE           (VCD_START_BASE + 0x1)
+#define VCD_I_CODEC          (VCD_START_BASE + 0x2)
+#define VCD_I_FRAME_SIZE     (VCD_START_BASE + 0x3)
+#define VCD_I_METADATA_ENABLE  (VCD_START_BASE + 0x4)
+#define VCD_I_METADATA_HEADER  (VCD_START_BASE + 0x5)
+#define VCD_I_PROFILE        (VCD_START_BASE + 0x6)
+#define VCD_I_LEVEL          (VCD_START_BASE + 0x7)
+#define VCD_I_BUFFER_FORMAT  (VCD_START_BASE + 0x8)
+#define VCD_I_FRAME_RATE  (VCD_START_BASE + 0x9)
+#define VCD_I_TARGET_BITRATE (VCD_START_BASE + 0xA)
+#define VCD_I_MULTI_SLICE    (VCD_START_BASE + 0xB)
+#define VCD_I_ENTROPY_CTRL   (VCD_START_BASE + 0xC)
+#define VCD_I_DEBLOCKING     (VCD_START_BASE + 0xD)
+#define VCD_I_RATE_CONTROL   (VCD_START_BASE + 0xE)
+#define VCD_I_QP_RANGE      (VCD_START_BASE + 0xF)
+#define VCD_I_SESSION_QP    (VCD_START_BASE + 0x10)
+#define VCD_I_INTRA_PERIOD   (VCD_START_BASE + 0x11)
+#define VCD_I_VOP_TIMING     (VCD_START_BASE + 0x12)
+#define VCD_I_SHORT_HEADER   (VCD_START_BASE + 0x13)
+#define VCD_I_SEQ_HEADER    (VCD_START_BASE + 0x14)
+#define VCD_I_HEADER_EXTENSION   (VCD_START_BASE + 0x15)
+#define VCD_I_INTRA_REFRESH  (VCD_START_BASE + 0x16)
+#define VCD_I_POST_FILTER    (VCD_START_BASE + 0x17)
+#define VCD_I_PROGRESSIVE_ONLY (VCD_START_BASE + 0x18)
+#define VCD_I_OUTPUT_ORDER (VCD_START_BASE + 0x19)
+#define VCD_I_RECON_BUFFERS   (VCD_START_BASE + 0x1A)
+#define VCD_I_FREE_RECON_BUFFERS   (VCD_START_BASE + 0x1B)
+#define VCD_I_GET_RECON_BUFFER_SIZE   (VCD_START_BASE + 0x1C)
+#define VCD_I_H264_MV_BUFFER   (VCD_START_BASE + 0x1D)
+#define VCD_I_FREE_H264_MV_BUFFER (VCD_START_BASE + 0x1E)
+#define VCD_I_GET_H264_MV_SIZE (VCD_START_BASE + 0x1F)
+#define VCD_I_DEC_PICTYPE (VCD_START_BASE + 0x20)
+#define VCD_I_CONT_ON_RECONFIG (VCD_START_BASE + 0x21)
+
+#define VCD_START_REQ      (VCD_START_BASE + 0x1000)
+#define VCD_I_REQ_IFRAME   (VCD_START_REQ + 0x1)
+
+#define VCD_I_RESERVED_BASE  (VCD_START_BASE + 0x10000)
+
+struct vcd_property_hdr {
+	u32    prop_id;
+	size_t sz;
+};
+
+struct vcd_property_live {
+	u32             live;
+};
+
+enum vcd_codec {
+	VCD_CODEC_H264      = 0x1,
+	VCD_CODEC_H263      = 0x2,
+	VCD_CODEC_MPEG1     = 0x3,
+	VCD_CODEC_MPEG2     = 0x4,
+	VCD_CODEC_MPEG4     = 0x5,
+	VCD_CODEC_DIVX_3    = 0x6,
+	VCD_CODEC_DIVX_4    = 0x7,
+	VCD_CODEC_DIVX_5    = 0x8,
+	VCD_CODEC_DIVX_6    = 0x9,
+	VCD_CODEC_XVID      = 0xA,
+	VCD_CODEC_VC1       = 0xB,
+	VCD_CODEC_VC1_RCV   = 0xC
+};
+
+struct vcd_property_codec {
+	enum vcd_codec       codec;
+};
+
+struct vcd_property_frame_size {
+	u32              width;
+	u32              height;
+	u32              stride;
+	u32              scan_lines;
+};
+
+
+#define VCD_METADATA_DATANONE       0x001
+#define VCD_METADATA_QCOMFILLER     0x002
+#define VCD_METADATA_QPARRAY        0x004
+#define VCD_METADATA_CONCEALMB      0x008
+#define VCD_METADATA_SEI            0x010
+#define VCD_METADATA_VUI            0x020
+#define VCD_METADATA_VC1            0x040
+#define VCD_METADATA_PASSTHROUGH    0x080
+#define VCD_METADATA_ENC_SLICE      0x100
+
+struct vcd_property_meta_data_enable {
+	u32 meta_data_enable_flag;
+};
+
+struct vcd_property_metadata_hdr {
+	u32 meta_data_id;
+	u32 version;
+	u32 port_index;
+	u32 type;
+};
+
+struct vcd_property_frame_rate {
+	u32              fps_denominator;
+	u32              fps_numerator;
+};
+
+struct vcd_property_target_bitrate {
+	u32             target_bitrate;
+};
+
+enum vcd_yuv_buffer_format {
+	VCD_BUFFER_FORMAT_NV12      = 0x1,
+	VCD_BUFFER_FORMAT_TILE_4x2    = 0x2,
+	VCD_BUFFER_FORMAT_NV12_16M2KA = 0x3,
+	VCD_BUFFER_FORMAT_TILE_1x1    = 0x4
+};
+
+struct vcd_property_buffer_format {
+	enum vcd_yuv_buffer_format  buffer_format;
+};
+
+struct vcd_property_post_filter {
+	u32           post_filter;
+};
+
+enum vcd_codec_profile {
+	VCD_PROFILE_UNKNOWN       = 0x0,
+	VCD_PROFILE_MPEG4_SP      = 0x1,
+	VCD_PROFILE_MPEG4_ASP     = 0x2,
+	VCD_PROFILE_H264_BASELINE = 0x3,
+	VCD_PROFILE_H264_MAIN     = 0x4,
+	VCD_PROFILE_H264_HIGH     = 0x5,
+	VCD_PROFILE_H263_BASELINE = 0x6,
+	VCD_PROFILE_VC1_SIMPLE    = 0x7,
+	VCD_PROFILE_VC1_MAIN      = 0x8,
+	VCD_PROFILE_VC1_ADVANCE   = 0x9,
+	VCD_PROFILE_MPEG2_MAIN    = 0xA,
+	VCD_PROFILE_MPEG2_SIMPLE  = 0xB
+};
+
+struct vcd_property_profile {
+	enum vcd_codec_profile       profile;
+};
+
+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
+};
+
+struct vcd_property_level {
+	enum vcd_codec_level   level;
+};
+
+enum vcd_m_slice_sel {
+	VCD_MSLICE_OFF             = 0x1,
+	VCD_MSLICE_BY_MB_COUNT     = 0x2,
+	VCD_MSLICE_BY_BYTE_COUNT   = 0x3,
+	VCD_MSLICE_BY_GOB          = 0x4
+};
+
+struct vcd_property_multi_slice {
+	enum vcd_m_slice_sel   m_slice_sel;
+	u32             m_slice_size;
+};
+
+enum vcd_entropy_sel {
+	VCD_ENTROPY_SEL_CAVLC = 0x1,
+	VCD_ENTROPY_SEL_CABAC = 0x2
+};
+
+enum vcd_cabac_model {
+	VCD_CABAC_MODEL_NUMBER_0 = 0x1,
+	VCD_CABAC_MODEL_NUMBER_1 = 0x2,
+	VCD_CABAC_MODEL_NUMBER_2 = 0x3
+};
+
+struct vcd_property_entropy_control {
+	enum vcd_entropy_sel  entropy_sel;
+	enum vcd_cabac_model  cabac_model;
+};
+
+enum vcd_db_config {
+	VCD_DB_ALL_BLOCKING_BOUNDARY = 0x1,
+	VCD_DB_DISABLE               = 0x2,
+	VCD_DB_SKIP_SLICE_BOUNDARY   = 0x3
+};
+struct vcd_property_db_config {
+	enum vcd_db_config    db_config;
+	u32             slice_alpha_offset;
+	u32             slice_beta_offset;
+};
+
+enum vcd_rate_control {
+	VCD_RATE_CONTROL_OFF      = 0x1,
+	VCD_RATE_CONTROL_VBR_VFR  = 0x2,
+	VCD_RATE_CONTROL_VBR_CFR  = 0x3,
+	VCD_RATE_CONTROL_CBR_VFR  = 0x4,
+	VCD_RATE_CONTROL_CBR_CFR  = 0x5
+};
+
+struct vcd_property_rate_control {
+	enum vcd_rate_control     rate_control;
+};
+
+struct vcd_property_qp_range {
+	u32              max_qp;
+	u32              min_qp;
+};
+
+struct vcd_property_session_qp {
+	u32 i_frame_qp;
+	u32 p_frame_qp;
+	u32	b_frame_qp;
+};
+
+struct vcd_property_i_period {
+	u32 p_frames;
+	u32 b_frames;
+};
+
+struct vcd_property_vop_timing {
+	u32   vop_time_resolution;
+};
+
+struct vcd_property_short_header {
+	u32             short_header;
+};
+
+struct vcd_property_intra_refresh_mb_number {
+	u32            cir_mb_number;
+};
+
+struct vcd_property_req_i_frame {
+	u32        req_i_frame;
+};
+
+struct vcd_frame_rect{
+   u32   left;
+   u32   top;
+   u32   right;
+   u32   bottom;
+};
+
+struct vcd_property_dec_output_buffer {
+	struct vcd_frame_rect   disp_frm;
+	struct vcd_property_frame_size frm_size;
+};
+
+enum vcd_output_order {
+   VCD_DEC_ORDER_DISPLAY  = 0x0,
+   VCD_DEC_ORDER_DECODE   = 0x1
+};
+
+struct vcd_property_enc_recon_buffer{
+	u8 *kernel_virtual_addr;
+	u8 *physical_addr;
+	u32 buffer_size;
+	u32 ysize;
+	int pmem_fd;
+	u32 offset;
+};
+
+struct vcd_property_h264_mv_buffer{
+	u8 *kernel_virtual_addr;
+	u8 *physical_addr;
+	u32 size;
+	u32 count;
+	int pmem_fd;
+	u32 offset;
+};
+
+struct vcd_property_buffer_size{
+	int width;
+	int height;
+	int size;
+	int alignment;
+};
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
new file mode 100644
index 0000000..34a3445
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c
@@ -0,0 +1,286 @@
+/* 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_type.h"
+#include "vcd.h"
+
+#define NORMALIZATION_FACTOR 3600
+#define ADJUST_CLIENT_ROUNDS(client, round_adjustment) \
+do {\
+	if ((client)->rounds < round_adjustment) {\
+		(client)->rounds = 0;\
+		VCD_MSG_HIGH("%s(): WARNING: Scheduler list unsorted",\
+			__func__);\
+	} else\
+		(client)->rounds -= round_adjustment;\
+} while (0)
+
+u32 vcd_sched_create(struct list_head *sched_list)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (!sched_list) {
+		VCD_MSG_ERROR("%s(): Invalid parameter", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else
+		INIT_LIST_HEAD(sched_list);
+	return rc;
+}
+
+void vcd_sched_destroy(struct list_head *sched_clnt_list)
+{
+	struct vcd_sched_clnt_ctx *sched_clnt, *sched_clnt_next;
+	if (sched_clnt_list)
+		list_for_each_entry_safe(sched_clnt,
+			sched_clnt_next, sched_clnt_list, list) {
+			list_del_init(&sched_clnt->list);
+			sched_clnt->clnt_active = false;
+		}
+}
+
+void insert_client_in_list(struct list_head *sched_clnt_list,
+	struct vcd_sched_clnt_ctx *sched_new_clnt, bool tail)
+{
+	struct vcd_sched_clnt_ctx *sched_clnt;
+	if (!list_empty(sched_clnt_list)) {
+		if (tail)
+			sched_clnt = list_entry(sched_clnt_list->prev,
+				struct vcd_sched_clnt_ctx, list);
+		else
+			sched_clnt = list_first_entry(sched_clnt_list,
+				struct vcd_sched_clnt_ctx, list);
+		sched_new_clnt->rounds = sched_clnt->rounds;
+	} else
+		sched_new_clnt->rounds = 0;
+	if (tail)
+		list_add_tail(&sched_new_clnt->list, sched_clnt_list);
+	else
+		list_add(&sched_new_clnt->list, sched_clnt_list);
+}
+
+u32 vcd_sched_add_client(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_property_hdr prop_hdr;
+	struct vcd_sched_clnt_ctx *sched_cctxt;
+	u32 rc = VCD_S_SUCCESS;
+	if (!cctxt) {
+		VCD_MSG_ERROR("%s(): Invalid parameter", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else if (cctxt->sched_clnt_hdl)
+		VCD_MSG_HIGH(
+			"%s(): Scheduler client already exists!", __func__);
+	else {
+		sched_cctxt = (struct vcd_sched_clnt_ctx *)
+			kmalloc(sizeof(struct vcd_sched_clnt_ctx),
+					GFP_KERNEL);
+		if (sched_cctxt) {
+
+			prop_hdr.prop_id = DDL_I_FRAME_PROC_UNITS;
+			prop_hdr.sz = sizeof(cctxt->frm_p_units);
+			rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr,
+						  &cctxt->frm_p_units);
+			VCD_FAILED_RETURN(rc,
+				"Failed: Get DDL_I_FRAME_PROC_UNITS");
+			if (cctxt->decoding) {
+				cctxt->frm_rate.fps_numerator =
+					VCD_DEC_INITIAL_FRAME_RATE;
+				cctxt->frm_rate.fps_denominator = 1;
+			} else {
+				prop_hdr.prop_id = VCD_I_FRAME_RATE;
+				prop_hdr.sz = sizeof(cctxt->frm_rate);
+				rc = ddl_get_property(cctxt->ddl_handle,
+						&prop_hdr, &cctxt->frm_rate);
+				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;
+
+			cctxt->sched_clnt_hdl = sched_cctxt;
+			memset(sched_cctxt, 0,
+				sizeof(struct vcd_sched_clnt_ctx));
+			sched_cctxt->tkns = 0;
+			sched_cctxt->round_perfrm = NORMALIZATION_FACTOR *
+				cctxt->frm_rate.fps_denominator /
+				cctxt->frm_rate.fps_numerator;
+			sched_cctxt->clnt_active = true;
+			sched_cctxt->clnt_data = cctxt;
+			INIT_LIST_HEAD(&sched_cctxt->ip_frm_list);
+
+			insert_client_in_list(
+				&cctxt->dev_ctxt->sched_clnt_list,
+				sched_cctxt, false);
+		}
+	}
+	return rc;
+}
+
+u32 vcd_sched_remove_client(struct vcd_sched_clnt_ctx *sched_cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_clnt_ctxt *cctxt;
+	if (!sched_cctxt) {
+		VCD_MSG_ERROR("%s(): Invalid handle ptr", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else if (!list_empty(&sched_cctxt->ip_frm_list)) {
+		VCD_MSG_ERROR(
+			"%s(): Cannot remove client, queue no empty", __func__);
+		rc = VCD_ERR_ILLEGAL_OP;
+	} else {
+		cctxt = sched_cctxt->clnt_data;
+		list_del(&sched_cctxt->list);
+		memset(sched_cctxt, 0,
+			sizeof(struct vcd_sched_clnt_ctx));
+		kfree(sched_cctxt);
+	}
+	return rc;
+}
+
+u32 vcd_sched_update_config(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (!cctxt || !cctxt->sched_clnt_hdl) {
+		VCD_MSG_ERROR("%s(): Invalid parameter", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else {
+		cctxt->sched_clnt_hdl->rounds /=
+			cctxt->sched_clnt_hdl->round_perfrm;
+		cctxt->sched_clnt_hdl->round_perfrm =
+			NORMALIZATION_FACTOR *
+			cctxt->frm_rate.fps_denominator /
+			cctxt->frm_rate.fps_numerator;
+		cctxt->sched_clnt_hdl->rounds *=
+			cctxt->sched_clnt_hdl->round_perfrm;
+	}
+	return rc;
+}
+
+u32 vcd_sched_queue_buffer(
+	struct vcd_sched_clnt_ctx *sched_cctxt,
+	struct vcd_buffer_entry *buffer, u32 tail)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (!sched_cctxt || !buffer) {
+		VCD_MSG_ERROR("%s(): Invalid parameter", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else if (tail)
+		list_add_tail(&buffer->sched_list,
+				&sched_cctxt->ip_frm_list);
+	else
+		list_add(&buffer->sched_list, &sched_cctxt->ip_frm_list);
+	return rc;
+}
+
+u32 vcd_sched_dequeue_buffer(
+	struct vcd_sched_clnt_ctx *sched_cctxt,
+	struct vcd_buffer_entry **buffer)
+{
+	u32 rc = VCD_ERR_QEMPTY;
+	if (!sched_cctxt || !buffer) {
+		VCD_MSG_ERROR("%s(): Invalid parameter", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else {
+		*buffer = NULL;
+		if (!list_empty(&sched_cctxt->ip_frm_list)) {
+			*buffer = list_first_entry(
+					&sched_cctxt->ip_frm_list,
+					struct vcd_buffer_entry,
+					sched_list);
+			list_del(&(*buffer)->sched_list);
+			rc = VCD_S_SUCCESS;
+		}
+	}
+	return rc;
+}
+
+u32 vcd_sched_mark_client_eof(struct vcd_sched_clnt_ctx *sched_cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_buffer_entry *buffer = NULL;
+	if (!sched_cctxt) {
+		VCD_MSG_ERROR("%s(): Invalid parameter", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else if (!list_empty(&sched_cctxt->ip_frm_list)) {
+		buffer = list_entry(sched_cctxt->ip_frm_list.prev,
+			struct vcd_buffer_entry, sched_list);
+		buffer->frame.flags |= VCD_FRAME_FLAG_EOS;
+	} else
+		rc = VCD_ERR_QEMPTY;
+	return rc;
+}
+
+u32 vcd_sched_suspend_resume_clnt(
+	struct vcd_clnt_ctxt *cctxt, u32 state)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_sched_clnt_ctx *sched_cctxt;
+	if (!cctxt || !cctxt->sched_clnt_hdl) {
+		VCD_MSG_ERROR("%s(): Invalid parameter", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else {
+		sched_cctxt = cctxt->sched_clnt_hdl;
+		if (state != sched_cctxt->clnt_active) {
+			sched_cctxt->clnt_active = state;
+			if (state)
+				insert_client_in_list(&cctxt->dev_ctxt->\
+					sched_clnt_list, sched_cctxt, false);
+			else
+				list_del_init(&sched_cctxt->list);
+		}
+	}
+	return rc;
+}
+
+u32 vcd_sched_get_client_frame(struct list_head *sched_clnt_list,
+	struct vcd_clnt_ctxt **cctxt,
+	struct vcd_buffer_entry **buffer)
+{
+	u32 rc = VCD_ERR_QEMPTY, round_adjustment = 0;
+	struct vcd_sched_clnt_ctx *sched_clnt, *clnt_nxt;
+	if (!sched_clnt_list || !cctxt || !buffer) {
+		VCD_MSG_ERROR("%s(): Invalid parameter", __func__);
+		rc = VCD_ERR_ILLEGAL_PARM;
+	} else if (!list_empty(sched_clnt_list)) {
+		*cctxt = NULL;
+		*buffer = NULL;
+		list_for_each_entry_safe(sched_clnt,
+			clnt_nxt, sched_clnt_list, list) {
+			if (&sched_clnt->list == sched_clnt_list->next)
+				round_adjustment = sched_clnt->rounds;
+			if (*cctxt) {
+				if ((*cctxt)->sched_clnt_hdl->rounds >=
+					sched_clnt->rounds)
+					list_move(&(*cctxt)->sched_clnt_hdl\
+						->list, &sched_clnt->list);
+				ADJUST_CLIENT_ROUNDS(sched_clnt,
+					round_adjustment);
+			} else if (sched_clnt->tkns &&
+				!list_empty(&sched_clnt->ip_frm_list)) {
+				*cctxt = sched_clnt->clnt_data;
+				sched_clnt->rounds += sched_clnt->round_perfrm;
+			} else
+				ADJUST_CLIENT_ROUNDS(sched_clnt,
+						round_adjustment);
+		}
+		if (*cctxt) {
+			rc = vcd_sched_dequeue_buffer(
+				(*cctxt)->sched_clnt_hdl, buffer);
+			if (rc == VCD_S_SUCCESS) {
+				(*cctxt)->sched_clnt_hdl->tkns--;
+				ADJUST_CLIENT_ROUNDS((*cctxt)->\
+					sched_clnt_hdl, round_adjustment);
+			}
+		}
+	}
+	return rc;
+}
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_status.h b/drivers/video/msm/vidc/common/vcd/vcd_status.h
new file mode 100644
index 0000000..807718f
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_status.h
@@ -0,0 +1,60 @@
+/* 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 _VCD_ERR_STATUS_H_
+#define _VCD_ERR_STATUS_H_
+
+#define VCD_EVT_RESP_BASE                 0x1000
+#define VCD_EVT_RESP_OPEN                 (VCD_EVT_RESP_BASE + 0x1)
+#define VCD_EVT_RESP_START                (VCD_EVT_RESP_BASE + 0x2)
+#define VCD_EVT_RESP_STOP                 (VCD_EVT_RESP_BASE + 0x3)
+#define VCD_EVT_RESP_PAUSE                (VCD_EVT_RESP_BASE + 0x4)
+#define VCD_EVT_RESP_FLUSH_INPUT_DONE     (VCD_EVT_RESP_BASE + 0x5)
+#define VCD_EVT_RESP_FLUSH_OUTPUT_DONE    (VCD_EVT_RESP_BASE + 0x6)
+#define VCD_EVT_RESP_INPUT_FLUSHED        (VCD_EVT_RESP_BASE + 0x7)
+#define VCD_EVT_RESP_OUTPUT_FLUSHED       (VCD_EVT_RESP_BASE + 0x8)
+#define VCD_EVT_RESP_INPUT_DONE           (VCD_EVT_RESP_BASE + 0x9)
+#define VCD_EVT_RESP_OUTPUT_DONE          (VCD_EVT_RESP_BASE + 0xa)
+
+#define VCD_EVT_IND_BASE                  0x2000
+#define VCD_EVT_IND_INPUT_RECONFIG        (VCD_EVT_IND_BASE + 0x1)
+#define VCD_EVT_IND_OUTPUT_RECONFIG       (VCD_EVT_IND_BASE + 0x2)
+#define VCD_EVT_IND_HWERRFATAL            (VCD_EVT_IND_BASE + 0x3)
+#define VCD_EVT_IND_RESOURCES_LOST        (VCD_EVT_IND_BASE + 0x4)
+#define VCD_EVT_IND_INFO_OUTPUT_RECONFIG  (VCD_EVT_IND_BASE + 0x5)
+
+#define VCD_S_SUCCESS           0x0
+
+#define VCD_S_ERR_BASE                    0x80000000
+#define VCD_ERR_FAIL                      (VCD_S_ERR_BASE + 0x01)
+#define VCD_ERR_ALLOC_FAIL                (VCD_S_ERR_BASE + 0x02)
+#define VCD_ERR_ILLEGAL_OP                (VCD_S_ERR_BASE + 0x03)
+#define VCD_ERR_ILLEGAL_PARM              (VCD_S_ERR_BASE + 0x04)
+#define VCD_ERR_BAD_POINTER               (VCD_S_ERR_BASE + 0x05)
+#define VCD_ERR_BAD_HANDLE                (VCD_S_ERR_BASE + 0x06)
+#define VCD_ERR_NOT_SUPPORTED             (VCD_S_ERR_BASE + 0x07)
+#define VCD_ERR_BAD_STATE                 (VCD_S_ERR_BASE + 0x08)
+#define VCD_ERR_BUSY                      (VCD_S_ERR_BASE + 0x09)
+#define VCD_ERR_MAX_CLIENT                (VCD_S_ERR_BASE + 0x0a)
+#define VCD_ERR_IFRAME_EXPECTED           (VCD_S_ERR_BASE + 0x0b)
+#define VCD_ERR_INTRLCD_FIELD_DROP        (VCD_S_ERR_BASE + 0x0c)
+#define VCD_ERR_HW_FATAL                  (VCD_S_ERR_BASE + 0x0d)
+#define VCD_ERR_BITSTREAM_ERR             (VCD_S_ERR_BASE + 0x0e)
+#define VCD_ERR_QEMPTY                    (VCD_S_ERR_BASE + 0x0f)
+#define VCD_ERR_SEQHDR_PARSE_FAIL         (VCD_S_ERR_BASE + 0x10)
+#define VCD_ERR_INPUT_NOT_PROCESSED       (VCD_S_ERR_BASE + 0x11)
+#define VCD_ERR_INDEX_NOMORE              (VCD_S_ERR_BASE + 0x12)
+
+#define VCD_FAILED(rc)   ((rc > VCD_S_ERR_BASE) ? true : false)
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
new file mode 100644
index 0000000..6bc591b
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -0,0 +1,3057 @@
+/* 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 <asm/div64.h>
+
+#include "vidc_type.h"
+#include "vcd.h"
+#include "vdec_internal.h"
+#include <linux/memory_alloc.h>
+
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+static int vcd_pmem_alloc(size_t sz, u8 **kernel_vaddr, u8 **phy_addr)
+{
+	u32 memtype;
+
+	if (!kernel_vaddr || !phy_addr) {
+		pr_err("\n%s: Invalid parameters", __func__);
+		return -ENOMEM;
+	}
+	memtype = res_trk_get_mem_type();
+	*phy_addr = (u8 *) allocate_contiguous_memory_nomap(sz,
+					memtype, SZ_4K);
+	if (!*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__);
+			free_contiguous_memory_by_paddr(
+				(unsigned long) *phy_addr);
+			*phy_addr = NULL;
+			return -ENOMEM;
+		}
+		pr_debug("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
+			 (u32) *phy_addr, (u32) *kernel_vaddr);
+		return 0;
+	} else {
+		pr_err("%s: could not allocte in kernel pmem buffers\n",
+		       __func__);
+		return -ENOMEM;
+	}
+
+}
+
+static int vcd_pmem_free(u8 *kernel_vaddr, u8 *phy_addr)
+{
+	if (kernel_vaddr)
+		iounmap((void *)kernel_vaddr);
+	if (phy_addr)
+		free_contiguous_memory_by_paddr((unsigned long)phy_addr);
+	kernel_vaddr = NULL;
+	phy_addr = NULL;
+	return 0;
+}
+
+u8 *vcd_pmem_get_physical(struct video_client_ctx *client_ctx,
+			  unsigned long kernel_vaddr)
+{
+	unsigned long phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+					  false, &user_vaddr, &kernel_vaddr,
+					  &phy_addr, &pmem_fd, &file,
+					  &buffer_index)) {
+
+		return (u8 *) phy_addr;
+	} else if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+		false, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file,
+		&buffer_index)) {
+		return (u8 *) phy_addr;
+	} else {
+		VCD_MSG_ERROR("Couldn't get physical address");
+
+		return NULL;
+	}
+
+}
+
+void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt)
+{
+	dev_ctxt->ddl_frame_ch_free = dev_ctxt->ddl_frame_ch_depth;
+	dev_ctxt->ddl_cmd_ch_free   = dev_ctxt->ddl_cmd_ch_depth;
+	dev_ctxt->ddl_frame_ch_interim = 0;
+	dev_ctxt->ddl_cmd_ch_interim = 0;
+}
+
+u32 vcd_get_command_channel(
+	struct vcd_dev_ctxt *dev_ctxt,
+	 struct vcd_transc **transc)
+{
+	u32 result = false;
+
+	*transc = NULL;
+
+	if (dev_ctxt->ddl_cmd_ch_free > 0) {
+		if (dev_ctxt->ddl_cmd_concurrency) {
+			--dev_ctxt->ddl_cmd_ch_free;
+			result = true;
+		} else if ((dev_ctxt->ddl_frame_ch_free +
+			 dev_ctxt->ddl_frame_ch_interim)
+			== dev_ctxt->ddl_frame_ch_depth) {
+				--dev_ctxt->ddl_cmd_ch_free;
+				result = true;
+		}
+	}
+
+	if (result) {
+		*transc = vcd_get_free_trans_tbl_entry(dev_ctxt);
+
+		if (!*transc) {
+			result = false;
+
+			vcd_release_command_channel(dev_ctxt, *transc);
+		}
+
+	}
+	return result;
+}
+
+u32 vcd_get_command_channel_in_loop(
+	struct vcd_dev_ctxt *dev_ctxt,
+	 struct vcd_transc **transc)
+{
+	u32 result = false;
+
+	*transc = NULL;
+
+	if (dev_ctxt->ddl_cmd_ch_interim > 0) {
+		if (dev_ctxt->ddl_cmd_concurrency) {
+			--dev_ctxt->ddl_cmd_ch_interim;
+			result = true;
+		} else if ((dev_ctxt->ddl_frame_ch_free +
+				dev_ctxt->ddl_frame_ch_interim)
+				== dev_ctxt->ddl_frame_ch_depth) {
+				--dev_ctxt->ddl_cmd_ch_interim;
+				result = true;
+		}
+	} else {
+		result = vcd_get_command_channel(dev_ctxt, transc);
+	}
+
+	if (result && !*transc) {
+		*transc = vcd_get_free_trans_tbl_entry(dev_ctxt);
+
+		if (!*transc) {
+			result = false;
+
+			++dev_ctxt->ddl_cmd_ch_interim;
+		}
+
+	}
+
+	return result;
+}
+
+void vcd_mark_command_channel(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_transc *transc)
+{
+	++dev_ctxt->ddl_cmd_ch_interim;
+
+	vcd_release_trans_tbl_entry(transc);
+	if (dev_ctxt->ddl_cmd_ch_interim +
+		dev_ctxt->ddl_cmd_ch_free >
+		dev_ctxt->ddl_cmd_ch_depth) {
+		VCD_MSG_ERROR("\n Command channel access counters messed up");
+	}
+}
+
+void vcd_release_command_channel(
+	struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc)
+{
+	++dev_ctxt->ddl_cmd_ch_free;
+
+	vcd_release_trans_tbl_entry(transc);
+	if (dev_ctxt->ddl_cmd_ch_interim + dev_ctxt->ddl_cmd_ch_free >
+		dev_ctxt->ddl_cmd_ch_depth) {
+		VCD_MSG_ERROR("\n Command channel access counters messed up");
+	}
+}
+
+void vcd_release_multiple_command_channels(struct vcd_dev_ctxt
+	*dev_ctxt, u32 channels)
+{
+	dev_ctxt->ddl_cmd_ch_free += channels;
+
+	if (dev_ctxt->ddl_cmd_ch_interim +
+		dev_ctxt->ddl_cmd_ch_free >
+		dev_ctxt->ddl_cmd_ch_depth) {
+		VCD_MSG_ERROR("\n Command channel access counters messed up");
+	}
+}
+
+void vcd_release_interim_command_channels(struct vcd_dev_ctxt *dev_ctxt)
+{
+	dev_ctxt->ddl_cmd_ch_free += dev_ctxt->ddl_cmd_ch_interim;
+	dev_ctxt->ddl_cmd_ch_interim = 0;
+
+	if (dev_ctxt->ddl_cmd_ch_interim + dev_ctxt->ddl_cmd_ch_free >
+		dev_ctxt->ddl_cmd_ch_depth) {
+		VCD_MSG_ERROR("\n Command channel access counters messed up");
+	}
+}
+
+u32 vcd_get_frame_channel(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_transc **transc)
+{
+	u32 result = false;
+
+	if (dev_ctxt->ddl_frame_ch_free > 0) {
+		if (dev_ctxt->ddl_cmd_concurrency) {
+			--dev_ctxt->ddl_frame_ch_free;
+			result = true;
+		} else if ((dev_ctxt->ddl_cmd_ch_free +
+			 dev_ctxt->ddl_cmd_ch_interim)
+			== dev_ctxt->ddl_cmd_ch_depth) {
+			--dev_ctxt->ddl_frame_ch_free;
+			result = true;
+		}
+	}
+
+	if (result) {
+		*transc = vcd_get_free_trans_tbl_entry(dev_ctxt);
+
+		if (!*transc) {
+			result = false;
+
+			vcd_release_frame_channel(dev_ctxt, *transc);
+		} else {
+			(*transc)->type = VCD_CMD_CODE_FRAME;
+		}
+
+	}
+
+	return result;
+}
+
+u32 vcd_get_frame_channel_in_loop(
+	struct vcd_dev_ctxt *dev_ctxt,
+	 struct vcd_transc **transc)
+{
+	u32 result = false;
+
+	*transc = NULL;
+
+	if (dev_ctxt->ddl_frame_ch_interim > 0) {
+		if (dev_ctxt->ddl_cmd_concurrency) {
+			--dev_ctxt->ddl_frame_ch_interim;
+			result = true;
+		} else if ((dev_ctxt->ddl_cmd_ch_free +
+			 dev_ctxt->ddl_cmd_ch_interim)
+			== dev_ctxt->ddl_cmd_ch_depth) {
+			--dev_ctxt->ddl_frame_ch_interim;
+			result = true;
+		}
+	} else {
+		result = vcd_get_frame_channel(dev_ctxt, transc);
+	}
+
+	if (result && !*transc) {
+		*transc = vcd_get_free_trans_tbl_entry(dev_ctxt);
+
+		if (!*transc) {
+			result = false;
+			VCD_MSG_FATAL("\n%s: All transactions are busy;"
+				"Couldnt find free one\n", __func__);
+			++dev_ctxt->ddl_frame_ch_interim;
+		} else
+			(*transc)->type = VCD_CMD_CODE_FRAME;
+	}
+
+	return result;
+}
+
+void vcd_mark_frame_channel(struct vcd_dev_ctxt *dev_ctxt)
+{
+	++dev_ctxt->ddl_frame_ch_interim;
+
+	if (dev_ctxt->ddl_frame_ch_interim +
+		dev_ctxt->ddl_frame_ch_free >
+		dev_ctxt->ddl_cmd_ch_depth) {
+		VCD_MSG_FATAL("Frame channel access counters messed up");
+	}
+}
+
+void vcd_release_frame_channel(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_transc *transc)
+{
+	++dev_ctxt->ddl_frame_ch_free;
+
+	vcd_release_trans_tbl_entry(transc);
+
+	if (dev_ctxt->ddl_frame_ch_interim +
+		dev_ctxt->ddl_frame_ch_free >
+		dev_ctxt->ddl_cmd_ch_depth) {
+		VCD_MSG_FATAL("Frame channel access counters messed up");
+	}
+}
+
+void vcd_release_multiple_frame_channels(struct vcd_dev_ctxt
+	*dev_ctxt, u32 channels)
+{
+	dev_ctxt->ddl_frame_ch_free += channels;
+
+	if (dev_ctxt->ddl_frame_ch_interim +
+		dev_ctxt->ddl_frame_ch_free >
+		dev_ctxt->ddl_frame_ch_depth) {
+		VCD_MSG_FATAL("Frame channel access counters messed up");
+	}
+}
+
+void vcd_release_interim_frame_channels(struct vcd_dev_ctxt
+	*dev_ctxt)
+{
+	dev_ctxt->ddl_frame_ch_free +=
+		dev_ctxt->ddl_frame_ch_interim;
+	dev_ctxt->ddl_frame_ch_interim = 0;
+
+	if (dev_ctxt->ddl_frame_ch_free >
+		dev_ctxt->ddl_cmd_ch_depth) {
+		VCD_MSG_FATAL("Frame channel access counters messed up");
+	}
+}
+
+u32 vcd_core_is_busy(struct vcd_dev_ctxt *dev_ctxt)
+{
+	if (((dev_ctxt->ddl_cmd_ch_free +
+		  dev_ctxt->ddl_cmd_ch_interim) !=
+		 dev_ctxt->ddl_cmd_ch_depth)
+		||
+		((dev_ctxt->ddl_frame_ch_free +
+		  dev_ctxt->ddl_frame_ch_interim) !=
+		 dev_ctxt->ddl_frame_ch_depth)
+	  ) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+void vcd_device_timer_start(struct vcd_dev_ctxt *dev_ctxt)
+{
+	if (dev_ctxt->config.timer_start)
+		dev_ctxt->config.timer_start(dev_ctxt->hw_timer_handle,
+			dev_ctxt->hw_time_out);
+}
+
+void vcd_device_timer_stop(struct vcd_dev_ctxt *dev_ctxt)
+{
+	if (dev_ctxt->config.timer_stop)
+		dev_ctxt->config.timer_stop(dev_ctxt->hw_timer_handle);
+}
+
+
+u32 vcd_common_allocate_set_buffer(
+	struct vcd_clnt_ctxt *cctxt,
+	 enum vcd_buffer_type buffer,
+	 u32 buf_size, struct vcd_buffer_pool **buffer_pool)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_buffer_requirement Buf_req;
+	struct vcd_property_hdr Prop_hdr;
+	struct vcd_buffer_pool *buf_pool;
+
+	if (buffer == VCD_BUFFER_INPUT) {
+		Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ;
+		buf_pool = &cctxt->in_buf_pool;
+	} else if (buffer == VCD_BUFFER_OUTPUT) {
+		Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ;
+		buf_pool = &cctxt->out_buf_pool;
+	} else {
+		rc = VCD_ERR_ILLEGAL_PARM;
+	}
+	VCD_FAILED_RETURN(rc, "Invalid buffer type provided");
+
+	*buffer_pool = buf_pool;
+
+	if (buf_pool->count > 0 &&
+		buf_pool->validated == buf_pool->count) {
+		VCD_MSG_ERROR("Buffer pool is full");
+		return VCD_ERR_FAIL;
+	}
+
+	if (!buf_pool->entries) {
+		Prop_hdr.sz = sizeof(Buf_req);
+		rc = ddl_get_property(cctxt->ddl_handle, &Prop_hdr, &Buf_req);
+		if (!VCD_FAILED(rc)) {
+			rc = vcd_alloc_buffer_pool_entries(buf_pool,
+							   &Buf_req);
+		} else {
+			VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_get_property",
+					  rc);
+		}
+	}
+
+	if (!VCD_FAILED(rc)) {
+		if (buf_pool->buf_req.sz > buf_size) {
+			VCD_MSG_ERROR("\n required buffer sz %u "
+				"allocated sz %u", buf_pool->buf_req.
+				sz, buf_size);
+
+			rc = VCD_ERR_ILLEGAL_PARM;
+		}
+	}
+
+	return rc;
+}
+
+u32 vcd_set_buffer_internal(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_buffer_pool *buf_pool, u8 *buffer, u32 buf_size)
+{
+	struct vcd_buffer_entry *buf_entry;
+	u8 *physical;
+
+	buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer);
+	if (buf_entry) {
+		VCD_MSG_ERROR("This buffer address already exists");
+
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	physical = (u8 *) vcd_pmem_get_physical(
+		cctxt->client_data, (unsigned long)buffer);
+
+	if (!physical) {
+		VCD_MSG_ERROR("Couldn't get physical address");
+		return VCD_ERR_BAD_POINTER;
+	}
+	if (((u32) physical % buf_pool->buf_req.align)) {
+		VCD_MSG_ERROR("Physical addr is not aligned");
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	buf_entry = vcd_get_free_buffer_pool_entry(buf_pool);
+	if (!buf_entry) {
+		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;
+	buf_entry->frame.alloc_len = buf_size;
+	buf_entry->allocated = false;
+
+	buf_entry->frame.virtual = buf_entry->virtual;
+	buf_entry->frame.physical = buf_entry->physical;
+
+	buf_pool->validated++;
+
+	return VCD_S_SUCCESS;
+
+}
+
+u32 vcd_allocate_buffer_internal(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_buffer_pool *buf_pool,
+	 u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr)
+{
+	struct vcd_buffer_entry *buf_entry;
+	struct vcd_buffer_requirement *buf_req;
+	u32 addr;
+	int rc = 0;
+
+	buf_entry = vcd_get_free_buffer_pool_entry(buf_pool);
+	if (!buf_entry) {
+		VCD_MSG_ERROR("Can't allocate buffer pool is full");
+
+		return VCD_ERR_FAIL;
+	}
+
+	buf_req = &buf_pool->buf_req;
+
+	buf_size += buf_req->align;
+
+	rc = vcd_pmem_alloc(buf_size, &buf_entry->alloc,
+				&buf_entry->physical);
+
+	if (rc < 0) {
+		VCD_MSG_ERROR("Buffer allocation failed");
+
+		return VCD_ERR_ALLOC_FAIL;
+	}
+
+	buf_entry->sz = buf_size;
+	buf_entry->frame.alloc_len = buf_size;
+
+	if (!buf_entry->physical) {
+		VCD_MSG_ERROR("Couldn't get physical address");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	buf_entry->allocated = true;
+
+	if (buf_req->align > 0) {
+
+		addr = (u32) buf_entry->physical;
+		addr += buf_req->align;
+		addr -= (addr % buf_req->align);
+		buf_entry->virtual = buf_entry->alloc;
+		buf_entry->virtual += (u32) (addr - (u32)
+			buf_entry->physical);
+		buf_entry->physical = (u8 *) addr;
+	} else {
+		VCD_MSG_LOW("No buffer alignment required");
+
+		buf_entry->virtual = buf_entry->alloc;
+
+	}
+
+	buf_entry->frame.virtual = buf_entry->virtual;
+	buf_entry->frame.physical = buf_entry->physical;
+
+	*vir_buf_addr = buf_entry->virtual;
+	*phy_buf_addr = buf_entry->physical;
+
+	buf_pool->allocated++;
+	buf_pool->validated++;
+
+	return VCD_S_SUCCESS;
+}
+
+u32 vcd_free_one_buffer_internal(
+	struct vcd_clnt_ctxt *cctxt,
+	 enum vcd_buffer_type buffer_type, u8 *buffer)
+{
+	struct vcd_buffer_pool *buf_pool;
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_buffer_entry *buf_entry;
+	u32 first_frm_recvd = 0;
+
+	if (buffer_type == VCD_BUFFER_INPUT) {
+		buf_pool = &cctxt->in_buf_pool;
+		first_frm_recvd = VCD_FIRST_IP_RCVD;
+	} else if (buffer_type == VCD_BUFFER_OUTPUT) {
+		buf_pool = &cctxt->out_buf_pool;
+		first_frm_recvd = VCD_FIRST_OP_RCVD;
+	} else
+		rc = VCD_ERR_ILLEGAL_PARM;
+
+	VCD_FAILED_RETURN(rc, "Invalid buffer type provided");
+
+	first_frm_recvd &= cctxt->status.mask;
+	if (first_frm_recvd) {
+		VCD_MSG_ERROR(
+			"VCD free buffer called when data path is active");
+		return VCD_ERR_BAD_STATE;
+	}
+
+	buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer);
+	if (!buf_entry) {
+		VCD_MSG_ERROR("Buffer addr %p not found. Can't free buffer",
+				  buffer);
+
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if (buf_entry->in_use) {
+		VCD_MSG_ERROR("\n Buffer is in use and is not flushed");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+
+	VCD_MSG_LOW("Freeing buffer %p. Allocated %d",
+			buf_entry->virtual, buf_entry->allocated);
+
+	if (buf_entry->allocated) {
+		vcd_pmem_free(buf_entry->alloc, buf_entry->physical);
+		buf_pool->allocated--;
+	}
+
+	memset(buf_entry, 0, sizeof(struct vcd_buffer_entry));
+	buf_pool->validated--;
+	if (buf_pool->validated == 0)
+		vcd_free_buffer_pool_entries(buf_pool);
+
+	return VCD_S_SUCCESS;
+}
+
+u32 vcd_free_buffers_internal(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_buffer_pool *buf_pool)
+{
+	u32 rc = VCD_S_SUCCESS;
+	u32 i;
+
+	VCD_MSG_LOW("vcd_free_buffers_internal:");
+
+	if (buf_pool->entries) {
+		for (i = 1; i <= buf_pool->count; i++) {
+			if (buf_pool->entries[i].valid &&
+				buf_pool->entries[i].allocated) {
+				vcd_pmem_free(buf_pool->entries[i].alloc,
+						  buf_pool->entries[i].
+						  physical);
+			}
+		}
+
+	}
+
+	vcd_reset_buffer_pool_for_reuse(buf_pool);
+
+	return rc;
+}
+
+u32 vcd_alloc_buffer_pool_entries(
+	struct vcd_buffer_pool *buf_pool,
+	 struct vcd_buffer_requirement *buf_req)
+{
+
+	VCD_MSG_LOW("vcd_alloc_buffer_pool_entries:");
+
+	buf_pool->buf_req = *buf_req;
+
+	buf_pool->count = buf_req->actual_count;
+	buf_pool->entries = (struct vcd_buffer_entry *)
+		kzalloc((sizeof(struct vcd_buffer_entry) *
+			   (VCD_MAX_BUFFER_ENTRIES + 1)), GFP_KERNEL);
+
+	if (!buf_pool->entries) {
+		VCD_MSG_ERROR("Buf_pool entries alloc failed");
+		return VCD_ERR_ALLOC_FAIL;
+	}
+
+	INIT_LIST_HEAD(&buf_pool->queue);
+	buf_pool->entries[0].valid = true;
+	buf_pool->q_len = 0;
+
+	buf_pool->validated = 0;
+	buf_pool->allocated = 0;
+	buf_pool->in_use = 0;
+
+	return VCD_S_SUCCESS;
+}
+
+void vcd_free_buffer_pool_entries(struct vcd_buffer_pool *buf_pool)
+{
+	VCD_MSG_LOW("vcd_free_buffer_pool_entries:");
+	kfree(buf_pool->entries);
+	memset(buf_pool, 0, sizeof(struct vcd_buffer_pool));
+	INIT_LIST_HEAD(&buf_pool->queue);
+}
+
+void vcd_flush_in_use_buffer_pool_entries(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_buffer_pool *buf_pool, u32 event)
+{
+	u32 i;
+	VCD_MSG_LOW("vcd_flush_buffer_pool_entries: event=0x%x", event);
+
+	if (buf_pool->entries) {
+		for (i = 0; i <= buf_pool->count; i++) {
+			if (buf_pool->entries[i].virtual &&
+				buf_pool->entries[i].in_use) {
+				cctxt->callback(event, VCD_S_SUCCESS,
+					&buf_pool->entries[i].frame,
+					sizeof(struct vcd_frame_data),
+					cctxt, cctxt->client_data);
+				buf_pool->entries[i].in_use = false;
+				VCD_BUFFERPOOL_INUSE_DECREMENT(
+					buf_pool->in_use);
+		 }
+		}
+	}
+}
+
+
+void vcd_reset_buffer_pool_for_reuse(struct vcd_buffer_pool *buf_pool)
+{
+	VCD_MSG_LOW("vcd_reset_buffer_pool_for_reuse:");
+
+	if (buf_pool->entries) {
+		memset(&buf_pool->entries[1], 0,
+			sizeof(struct vcd_buffer_entry) *
+			VCD_MAX_BUFFER_ENTRIES);
+	}
+	buf_pool->q_len = 0;
+
+	buf_pool->validated = 0;
+	buf_pool->allocated = 0;
+	buf_pool->in_use = 0;
+	INIT_LIST_HEAD(&buf_pool->queue);
+}
+
+struct vcd_buffer_entry *vcd_get_free_buffer_pool_entry
+	(struct vcd_buffer_pool *pool) {
+	u32 i;
+
+	i = 1;
+	while (i <= pool->count && pool->entries[i].valid)
+		i++;
+
+
+	if (i <= pool->count) {
+		pool->entries[i].valid = true;
+
+		return &pool->entries[i];
+	} else {
+		return NULL;
+	}
+}
+
+struct vcd_buffer_entry *vcd_find_buffer_pool_entry
+	(struct vcd_buffer_pool *pool, u8 *addr)
+{
+	u32 i;
+	u32 found = false;
+
+	for (i = 0; i <= pool->count && !found; i++) {
+		if (pool->entries[i].virtual == addr)
+			found = true;
+
+	}
+
+	if (found)
+		return &pool->entries[i - 1];
+	else
+		return NULL;
+
+}
+
+u32 vcd_buffer_pool_entry_en_q(
+	struct vcd_buffer_pool *pool,
+	 struct vcd_buffer_entry *entry)
+{
+	struct vcd_buffer_entry *list_itr;
+
+	if (pool->q_len == pool->count)
+		return false;
+
+	list_for_each_entry(list_itr, &pool->queue, list)
+	if (list_itr == entry) {
+		VCD_MSG_HIGH("\n this output buffer is already present"
+			" in queue");
+		VCD_MSG_HIGH("\n Vir Addr %p Phys Addr %p",
+			entry->virtual, entry->physical);
+		return false;
+	}
+
+	list_add_tail(&entry->list, &pool->queue);
+	pool->q_len++;
+
+	return true;
+}
+
+struct vcd_buffer_entry *vcd_buffer_pool_entry_de_q
+	(struct vcd_buffer_pool *pool) {
+	struct vcd_buffer_entry *entry;
+
+	if (!pool || !pool->q_len)
+		return NULL;
+
+	entry = list_first_entry(&pool->queue,
+		struct vcd_buffer_entry, list);
+
+	if (entry) {
+		list_del(&entry->list);
+		pool->q_len--;
+	}
+
+	return entry;
+}
+
+void vcd_flush_bframe_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode)
+{
+	int i;
+	struct vcd_buffer_pool *buf_pool;
+
+	if (!cctxt->decoding && cctxt->bframe) {
+		buf_pool = (mode == VCD_FLUSH_INPUT) ?
+			&cctxt->in_buf_pool : &cctxt->out_buf_pool;
+		if (buf_pool->entries != NULL) {
+			for (i = 1; i <= buf_pool->count; i++) {
+				if ((buf_pool->entries[i].in_use) &&
+					(buf_pool->entries[i].frame.virtual
+					 != NULL)) {
+					if (mode == VCD_FLUSH_INPUT) {
+						cctxt->callback(
+						VCD_EVT_RESP_INPUT_FLUSHED,
+						VCD_S_SUCCESS,
+						&(buf_pool->entries[i].frame),
+						sizeof(struct vcd_frame_data),
+						cctxt, cctxt->client_data);
+					} else {
+						buf_pool->entries[i].
+							frame.data_len = 0;
+						cctxt->callback(
+						VCD_EVT_RESP_OUTPUT_FLUSHED,
+						VCD_S_SUCCESS,
+						&(buf_pool->entries[i].frame),
+						sizeof(struct vcd_frame_data),
+						cctxt,
+						cctxt->client_data);
+					}
+				VCD_BUFFERPOOL_INUSE_DECREMENT(
+					buf_pool->in_use);
+				buf_pool->entries[i].in_use = false;
+				}
+			}
+		}
+	}
+}
+
+void vcd_flush_output_buffers(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_buffer_pool *buf_pool;
+	struct vcd_buffer_entry *buf_entry;
+	u32 count = 0;
+	struct vcd_property_hdr prop_hdr;
+
+	VCD_MSG_LOW("vcd_flush_output_buffers:");
+	buf_pool = &cctxt->out_buf_pool;
+	buf_entry = vcd_buffer_pool_entry_de_q(buf_pool);
+	while (buf_entry) {
+		if (!cctxt->decoding || buf_entry->in_use) {
+			buf_entry->frame.data_len = 0;
+			cctxt->callback(VCD_EVT_RESP_OUTPUT_FLUSHED,
+					VCD_S_SUCCESS,
+					&buf_entry->frame,
+					sizeof(struct vcd_frame_data),
+					cctxt, cctxt->client_data);
+			if (buf_entry->in_use) {
+				VCD_BUFFERPOOL_INUSE_DECREMENT(
+					buf_pool->in_use);
+				buf_entry->in_use = false;
+			}
+			count++;
+		}
+		buf_entry = vcd_buffer_pool_entry_de_q(buf_pool);
+	}
+	vcd_flush_bframe_buffers(cctxt, VCD_FLUSH_OUTPUT);
+	if (buf_pool->in_use || buf_pool->q_len) {
+		VCD_MSG_ERROR("%s(): WARNING in_use(%u) or q_len(%u) not zero!",
+			__func__, buf_pool->in_use, buf_pool->q_len);
+		buf_pool->in_use = buf_pool->q_len = 0;
+		}
+	if (cctxt->sched_clnt_hdl) {
+		if (count > cctxt->sched_clnt_hdl->tkns)
+			cctxt->sched_clnt_hdl->tkns = 0;
+		else
+			cctxt->sched_clnt_hdl->tkns -= count;
+	}
+
+	if (cctxt->ddl_hdl_valid && cctxt->decoding) {
+		prop_hdr.prop_id = DDL_I_REQ_OUTPUT_FLUSH;
+		prop_hdr.sz = sizeof(u32);
+		count = 0x1;
+
+		(void)ddl_set_property(cctxt->ddl_handle, &prop_hdr,
+					&count);
+	}
+	vcd_release_all_clnt_frm_transc(cctxt);
+	cctxt->status.mask &= ~VCD_IN_RECONFIG;
+}
+
+u32 vcd_flush_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_buffer_entry *buf_entry;
+
+	VCD_MSG_LOW("vcd_flush_buffers:");
+
+	if (mode > VCD_FLUSH_ALL || !(mode & VCD_FLUSH_ALL)) {
+		VCD_MSG_ERROR("Invalid flush mode %d", mode);
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	VCD_MSG_MED("Flush mode %d requested", mode);
+	if ((mode & VCD_FLUSH_INPUT) &&
+		cctxt->sched_clnt_hdl) {
+
+		rc = vcd_sched_dequeue_buffer(
+			cctxt->sched_clnt_hdl, &buf_entry);
+		while (!VCD_FAILED(rc) && buf_entry) {
+			if (buf_entry->virtual) {
+				cctxt->callback(VCD_EVT_RESP_INPUT_FLUSHED,
+						VCD_S_SUCCESS,
+						&buf_entry->frame,
+						sizeof(struct
+							 vcd_frame_data),
+						cctxt,
+						cctxt->client_data);
+				}
+
+			buf_entry->in_use = false;
+			VCD_BUFFERPOOL_INUSE_DECREMENT(
+				cctxt->in_buf_pool.in_use);
+			buf_entry = NULL;
+			rc = vcd_sched_dequeue_buffer(
+				cctxt->sched_clnt_hdl, &buf_entry);
+		}
+	}
+	if (rc != VCD_ERR_QEMPTY)
+		VCD_FAILED_RETURN(rc, "Failed: vcd_sched_dequeue_buffer");
+	if (cctxt->status.frame_submitted > 0)
+		cctxt->status.mask |= mode;
+	else {
+		if (mode & VCD_FLUSH_INPUT)
+			vcd_flush_bframe_buffers(cctxt, VCD_FLUSH_INPUT);
+		if (mode & VCD_FLUSH_OUTPUT)
+			vcd_flush_output_buffers(cctxt);
+	}
+	return VCD_S_SUCCESS;
+}
+
+void vcd_flush_buffers_in_err_fatal(struct vcd_clnt_ctxt *cctxt)
+{
+	VCD_MSG_LOW("\n vcd_flush_buffers_in_err_fatal:");
+	(void) vcd_flush_buffers(cctxt, VCD_FLUSH_ALL);
+	vcd_flush_in_use_buffer_pool_entries(cctxt,
+		&cctxt->in_buf_pool, VCD_EVT_RESP_INPUT_FLUSHED);
+	vcd_flush_in_use_buffer_pool_entries(cctxt,
+		&cctxt->out_buf_pool, VCD_EVT_RESP_OUTPUT_FLUSHED);
+	vcd_send_flush_done(cctxt, VCD_S_SUCCESS);
+}
+
+u32 vcd_init_client_context(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc;
+	VCD_MSG_LOW("vcd_init_client_context:");
+	rc = ddl_open(&cctxt->ddl_handle, cctxt->decoding);
+	VCD_FAILED_RETURN(rc, "Failed: ddl_open");
+	cctxt->ddl_hdl_valid = true;
+	cctxt->clnt_state.state = VCD_CLIENT_STATE_OPEN;
+	cctxt->clnt_state.state_table =
+		vcd_get_client_state_table(VCD_CLIENT_STATE_OPEN);
+	cctxt->signature = VCD_SIGNATURE;
+	cctxt->live = true;
+	cctxt->bframe = 0;
+	cctxt->cmd_q.pending_cmd = VCD_CMD_NONE;
+	cctxt->status.last_evt = VCD_EVT_RESP_BASE;
+	return rc;
+}
+
+void vcd_destroy_client_context(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_dev_ctxt *dev_ctxt;
+	struct vcd_clnt_ctxt *client;
+	struct vcd_buffer_entry *buf_entry;
+	u32 rc = VCD_S_SUCCESS;
+	VCD_MSG_LOW("vcd_destroy_client_context:");
+
+	dev_ctxt = cctxt->dev_ctxt;
+
+	if (cctxt == dev_ctxt->cctxt_list_head) {
+		VCD_MSG_MED("Clnt list head clnt being removed");
+
+		dev_ctxt->cctxt_list_head = cctxt->next;
+	} else {
+		client = dev_ctxt->cctxt_list_head;
+		while (client && cctxt != client->next)
+			client = client->next;
+		if (client)
+			client->next = cctxt->next;
+		if (!client) {
+			rc = VCD_ERR_FAIL;
+			VCD_MSG_ERROR("Client not found in client list");
+		}
+	}
+
+	if (VCD_FAILED(rc))
+		return;
+
+	if (cctxt->sched_clnt_hdl) {
+		rc = VCD_S_SUCCESS;
+		while (!VCD_FAILED(rc)) {
+			rc = vcd_sched_dequeue_buffer(
+				cctxt->sched_clnt_hdl, &buf_entry);
+			if (rc != VCD_ERR_QEMPTY && VCD_FAILED(rc))
+				VCD_MSG_ERROR("\n Failed: "
+					"vcd_sched_de_queue_buffer");
+		}
+		rc = vcd_sched_remove_client(cctxt->sched_clnt_hdl);
+		if (VCD_FAILED(rc))
+			VCD_MSG_ERROR("\n Failed: sched_remove_client");
+		cctxt->sched_clnt_hdl = NULL;
+	}
+
+	if (cctxt->seq_hdr.sequence_header) {
+		vcd_pmem_free(cctxt->seq_hdr.sequence_header,
+				  cctxt->seq_hdr_phy_addr);
+		cctxt->seq_hdr.sequence_header = NULL;
+	}
+
+	vcd_free_buffers_internal(cctxt, &cctxt->in_buf_pool);
+	vcd_free_buffers_internal(cctxt, &cctxt->out_buf_pool);
+	vcd_free_buffer_pool_entries(&cctxt->in_buf_pool);
+	vcd_free_buffer_pool_entries(&cctxt->out_buf_pool);
+	vcd_release_all_clnt_transc(cctxt);
+
+	if (cctxt->ddl_hdl_valid) {
+		(void)ddl_close(&cctxt->ddl_handle);
+		cctxt->ddl_hdl_valid = false;
+	}
+
+	cctxt->signature = 0;
+	cctxt->clnt_state.state = VCD_CLIENT_STATE_NULL;
+	cctxt->clnt_state.state_table = NULL;
+
+	kfree(cctxt);
+}
+
+u32 vcd_check_for_client_context(
+	struct vcd_dev_ctxt *dev_ctxt, s32 driver_id)
+{
+	struct vcd_clnt_ctxt *client;
+
+	client = dev_ctxt->cctxt_list_head;
+	while (client && client->driver_id != driver_id)
+		client = client->next;
+
+	if (!client)
+		return false;
+	else
+		return true;
+}
+
+u32 vcd_validate_driver_handle(
+	struct vcd_dev_ctxt *dev_ctxt, s32 driver_handle)
+{
+	driver_handle--;
+
+	if (driver_handle < 0 ||
+		driver_handle >= VCD_DRIVER_INSTANCE_MAX ||
+		!dev_ctxt->driver_ids[driver_handle]) {
+		return false;
+	} else {
+		return true;
+	}
+}
+
+u32 vcd_client_cmd_en_q(
+	struct vcd_clnt_ctxt *cctxt, enum vcd_command command)
+{
+	u32 result;
+
+	if (cctxt->cmd_q.pending_cmd == VCD_CMD_NONE) {
+		cctxt->cmd_q.pending_cmd = command;
+		result = true;
+	} else {
+		result = false;
+	}
+
+	return result;
+}
+
+void vcd_client_cmd_flush_and_en_q(
+	struct vcd_clnt_ctxt *cctxt, enum vcd_command command)
+{
+	cctxt->cmd_q.pending_cmd = command;
+}
+
+u32 vcd_client_cmd_de_q(struct vcd_clnt_ctxt *cctxt,
+	enum vcd_command *command)
+{
+	if (cctxt->cmd_q.pending_cmd == VCD_CMD_NONE)
+		return false;
+
+	*command = cctxt->cmd_q.pending_cmd;
+	cctxt->cmd_q.pending_cmd = VCD_CMD_NONE;
+
+	return true;
+}
+
+u32 vcd_get_next_queued_client_cmd(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_clnt_ctxt **cctxt, enum vcd_command *command)
+{
+	struct vcd_clnt_ctxt *client = dev_ctxt->cctxt_list_head;
+	u32 result = false;
+
+	while (client && !result) {
+		*cctxt = client;
+		result = vcd_client_cmd_de_q(client, command);
+		client = client->next;
+	}
+	return result;
+}
+
+u32 vcd_submit_cmd_sess_start(struct vcd_transc *transc)
+{
+	u32 rc;
+	struct vcd_sequence_hdr Seq_hdr;
+
+	VCD_MSG_LOW("vcd_submit_cmd_sess_start:");
+
+	if (transc->cctxt->decoding) {
+
+		if (transc->cctxt->seq_hdr.sequence_header) {
+			Seq_hdr.sequence_header_len =
+				transc->cctxt->seq_hdr.
+				sequence_header_len;
+			Seq_hdr.sequence_header =
+				transc->cctxt->seq_hdr_phy_addr;
+
+			rc = ddl_decode_start(transc->cctxt->ddl_handle,
+						  &Seq_hdr, (void *)transc);
+		} else {
+			rc = ddl_decode_start(transc->cctxt->ddl_handle,
+						  NULL, (void *)transc);
+		}
+
+	} else {
+		rc = ddl_encode_start(transc->cctxt->ddl_handle,
+					  (void *)transc);
+	}
+	if (!VCD_FAILED(rc)) {
+		transc->cctxt->status.cmd_submitted++;
+		vcd_device_timer_start(transc->cctxt->dev_ctxt);
+	} else
+		VCD_MSG_ERROR("rc = 0x%x. Failed: ddl start", rc);
+
+	return rc;
+}
+
+u32 vcd_submit_cmd_sess_end(struct vcd_transc *transc)
+{
+	u32 rc;
+
+	VCD_MSG_LOW("vcd_submit_cmd_sess_end:");
+
+	if (transc->cctxt->decoding) {
+		rc = ddl_decode_end(transc->cctxt->ddl_handle,
+					(void *)transc);
+	} else {
+		rc = ddl_encode_end(transc->cctxt->ddl_handle,
+					(void *)transc);
+	}
+	if (!VCD_FAILED(rc)) {
+		transc->cctxt->status.cmd_submitted++;
+		vcd_device_timer_start(transc->cctxt->dev_ctxt);
+	} else
+		VCD_MSG_ERROR("rc = 0x%x. Failed: ddl end", rc);
+
+	return rc;
+}
+
+void vcd_submit_cmd_client_close(struct vcd_clnt_ctxt *cctxt)
+{
+	(void) ddl_close(&cctxt->ddl_handle);
+	cctxt->ddl_hdl_valid = false;
+	cctxt->status.mask &= ~VCD_CLEANING_UP;
+	if (cctxt->status.mask & VCD_CLOSE_PENDING) {
+		vcd_destroy_client_context(cctxt);
+		vcd_handle_for_last_clnt_close(cctxt->dev_ctxt, true);
+	}
+}
+
+u32 vcd_submit_command_in_continue(struct vcd_dev_ctxt
+	*dev_ctxt, struct vcd_transc *transc)
+{
+	struct vcd_property_hdr   prop_hdr;
+	struct vcd_clnt_ctxt *client = NULL;
+	enum vcd_command cmd = VCD_CMD_NONE;
+	u32 rc = VCD_ERR_FAIL;
+	u32 result = false, flush = 0, event = 0;
+	u32 command_break = false;
+
+	VCD_MSG_LOW("\n vcd_submit_command_in_continue:");
+
+	while (!command_break) {
+		result = vcd_get_next_queued_client_cmd(dev_ctxt,
+			&client, &cmd);
+
+		if (!result)
+			command_break = true;
+		else {
+			transc->type = cmd;
+			transc->cctxt = client;
+
+		 switch (cmd) {
+		 case VCD_CMD_CODEC_START:
+			{
+				rc = vcd_submit_cmd_sess_start(transc);
+				event = VCD_EVT_RESP_START;
+				break;
+			}
+		 case VCD_CMD_CODEC_STOP:
+			{
+				rc = vcd_submit_cmd_sess_end(transc);
+				event = VCD_EVT_RESP_STOP;
+				break;
+			}
+		 case VCD_CMD_OUTPUT_FLUSH:
+			{
+				prop_hdr.prop_id = DDL_I_REQ_OUTPUT_FLUSH;
+				prop_hdr.sz = sizeof(u32);
+				flush = 0x1;
+				(void) ddl_set_property(client->ddl_handle,
+						 &prop_hdr, &flush);
+				vcd_release_command_channel(dev_ctxt,
+					transc);
+				rc = VCD_S_SUCCESS;
+				break;
+			}
+		 case VCD_CMD_CLIENT_CLOSE:
+			{
+				vcd_submit_cmd_client_close(client);
+				vcd_release_command_channel(dev_ctxt,
+					transc);
+				rc = VCD_S_SUCCESS;
+				break;
+			}
+		 default:
+			{
+				VCD_MSG_ERROR("\n vcd_submit_command: Unknown"
+					"command %d", (int)cmd);
+				break;
+			}
+		 }
+
+		 if (!VCD_FAILED(rc)) {
+			command_break = true;
+		 } else	{
+			VCD_MSG_ERROR("vcd_submit_command %d: failed 0x%x",
+				cmd, rc);
+			client->callback(event, rc, NULL, 0, client,
+				client->client_data);
+		 }
+	  }
+	}
+	return result;
+}
+
+u32 vcd_schedule_frame(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_clnt_ctxt **cctxt, struct vcd_buffer_entry
+	**ip_buf_entry)
+{
+	u32 rc = VCD_S_SUCCESS;
+	VCD_MSG_LOW("vcd_schedule_frame:");
+
+	if (!dev_ctxt->cctxt_list_head) {
+		VCD_MSG_HIGH("Client list empty");
+		return false;
+	}
+	rc = vcd_sched_get_client_frame(&dev_ctxt->sched_clnt_list,
+		cctxt, ip_buf_entry);
+	if (rc == VCD_ERR_QEMPTY) {
+		VCD_MSG_HIGH("No frame available. Sched queues are empty");
+		return false;
+	}
+	if (VCD_FAILED(rc)) {
+		VCD_MSG_FATAL("vcd_submit_frame: sched_de_queue_frame"
+			"failed 0x%x", rc);
+	  return false;
+	}
+	if (!*cctxt || !*ip_buf_entry) {
+		VCD_MSG_FATAL("Sched returned invalid values. ctxt=%p,"
+			"ipbuf=%p",	*cctxt, *ip_buf_entry);
+		return false;
+	}
+	return true;
+}
+
+void vcd_try_submit_frame(struct vcd_dev_ctxt *dev_ctxt)
+{
+	struct vcd_transc *transc;
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_clnt_ctxt *cctxt = NULL;
+	struct vcd_buffer_entry *ip_buf_entry = NULL;
+	u32 result = false;
+
+	VCD_MSG_LOW("vcd_try_submit_frame:");
+
+	if (!vcd_get_frame_channel(dev_ctxt, &transc))
+		return;
+
+	if (!vcd_schedule_frame(dev_ctxt, &cctxt, &ip_buf_entry)) {
+		vcd_release_frame_channel(dev_ctxt, transc);
+		return;
+	}
+
+	rc = vcd_power_event(dev_ctxt, cctxt, VCD_EVT_PWR_CLNT_CMD_BEGIN);
+
+	if (!VCD_FAILED(rc)) {
+		transc->cctxt = cctxt;
+		transc->ip_buf_entry = ip_buf_entry;
+
+		result = vcd_submit_frame(dev_ctxt, transc);
+	} else {
+		VCD_MSG_ERROR("Failed: VCD_EVT_PWR_CLNT_CMD_BEGIN");
+		(void) vcd_sched_queue_buffer(
+			cctxt->sched_clnt_hdl, ip_buf_entry, false);
+		cctxt->sched_clnt_hdl->tkns++;
+	}
+
+	if (!result) {
+		vcd_release_frame_channel(dev_ctxt, transc);
+		(void) vcd_power_event(dev_ctxt, cctxt,
+				VCD_EVT_PWR_CLNT_CMD_FAIL);
+	}
+}
+
+u32 vcd_submit_frame(struct vcd_dev_ctxt *dev_ctxt,
+					 struct vcd_transc *transc)
+{
+	struct vcd_clnt_ctxt *cctxt = NULL;
+	struct vcd_frame_data *ip_frm_entry;
+	struct vcd_buffer_entry *op_buf_entry = NULL;
+	u32 rc = VCD_S_SUCCESS;
+	u32 evcode = 0;
+	struct ddl_frame_data_tag ddl_ip_frm;
+	struct ddl_frame_data_tag ddl_op_frm;
+
+	VCD_MSG_LOW("vcd_submit_frame:");
+	cctxt = transc->cctxt;
+	ip_frm_entry = &transc->ip_buf_entry->frame;
+
+	transc->op_buf_entry = op_buf_entry;
+	transc->ip_frm_tag = ip_frm_entry->ip_frm_tag;
+	transc->time_stamp = ip_frm_entry->time_stamp;
+	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);
+	} 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 {
+			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);
+		}
+	}
+	ip_frm_entry->ip_frm_tag = transc->ip_frm_tag;
+	if (!VCD_FAILED(rc)) {
+		vcd_device_timer_start(dev_ctxt);
+		cctxt->status.frame_submitted++;
+		if (ip_frm_entry->flags & VCD_FRAME_FLAG_EOS)
+			vcd_do_client_state_transition(cctxt,
+				VCD_CLIENT_STATE_EOS, evcode);
+	} else {
+		VCD_MSG_ERROR("Frame submission failed. rc = 0x%x", rc);
+		vcd_handle_submit_frame_failed(dev_ctxt, transc);
+	}
+	return true;
+}
+
+u32 vcd_try_submit_frame_in_continue(struct vcd_dev_ctxt *dev_ctxt,
+	struct vcd_transc *transc)
+{
+	struct vcd_clnt_ctxt *cctxt = NULL;
+	struct vcd_buffer_entry *ip_buf_entry = NULL;
+
+	VCD_MSG_LOW("vcd_try_submit_frame_in_continue:");
+
+	if (!vcd_schedule_frame(dev_ctxt, &cctxt, &ip_buf_entry))
+		return false;
+
+	transc->cctxt = cctxt;
+	transc->ip_buf_entry = ip_buf_entry;
+
+	return vcd_submit_frame(dev_ctxt, transc);
+}
+
+u32 vcd_process_cmd_sess_start(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_transc *transc;
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_process_cmd_sess_start:");
+	if (vcd_get_command_channel(cctxt->dev_ctxt, &transc)) {
+		rc = vcd_power_event(cctxt->dev_ctxt,
+					 cctxt, VCD_EVT_PWR_CLNT_CMD_BEGIN);
+
+		if (!VCD_FAILED(rc)) {
+			transc->type = VCD_CMD_CODEC_START;
+			transc->cctxt = cctxt;
+			rc = vcd_submit_cmd_sess_start(transc);
+		} else {
+			VCD_MSG_ERROR("Failed: VCD_EVT_PWR_CLNT_CMD_BEGIN");
+		}
+
+		if (VCD_FAILED(rc)) {
+			vcd_release_command_channel(cctxt->dev_ctxt,
+							transc);
+		}
+	} else {
+		u32 result;
+
+		result = vcd_client_cmd_en_q(cctxt, VCD_CMD_CODEC_START);
+		if (!result) {
+			rc = VCD_ERR_BUSY;
+			VCD_MSG_ERROR("%s(): vcd_client_cmd_en_q() "
+				"failed\n", __func__);
+		}
+	}
+
+	if (VCD_FAILED(rc)) {
+		(void)vcd_power_event(cctxt->dev_ctxt,
+					  cctxt, VCD_EVT_PWR_CLNT_CMD_FAIL);
+	}
+
+	return rc;
+}
+
+void vcd_send_frame_done_in_eos(struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_frame_data *input_frame, u32 valid_opbuf)
+{
+	VCD_MSG_LOW("vcd_send_frame_done_in_eos:");
+
+	if (!input_frame->virtual && !valid_opbuf) {
+		VCD_MSG_MED("Sending NULL output with EOS");
+
+		cctxt->out_buf_pool.entries[0].frame.flags =
+			VCD_FRAME_FLAG_EOS;
+		cctxt->out_buf_pool.entries[0].frame.data_len = 0;
+		cctxt->out_buf_pool.entries[0].frame.time_stamp =
+			input_frame->time_stamp;
+		cctxt->out_buf_pool.entries[0].frame.ip_frm_tag =
+			input_frame->ip_frm_tag;
+
+		cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE,
+				  VCD_S_SUCCESS,
+				  &cctxt->out_buf_pool.entries[0].frame,
+				  sizeof(struct vcd_frame_data),
+				  cctxt, cctxt->client_data);
+
+		memset(&cctxt->out_buf_pool.entries[0].frame,
+			   0, sizeof(struct vcd_frame_data));
+	} else if (!input_frame->data_len) {
+		if (cctxt->decoding) {
+			vcd_send_frame_done_in_eos_for_dec(cctxt,
+							   input_frame);
+		} else {
+			vcd_send_frame_done_in_eos_for_enc(cctxt,
+							   input_frame);
+		}
+
+	}
+}
+
+void vcd_send_frame_done_in_eos_for_dec(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_frame_data *input_frame)
+{
+	struct vcd_buffer_entry *buf_entry;
+	struct vcd_property_hdr prop_hdr;
+	u32 rc;
+	struct ddl_frame_data_tag ddl_frm;
+
+	prop_hdr.prop_id = DDL_I_DPB_RETRIEVE;
+	prop_hdr.sz = sizeof(struct ddl_frame_data_tag);
+	memset(&ddl_frm, 0, sizeof(ddl_frm));
+	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &ddl_frm);
+
+	if (VCD_FAILED(rc) || !ddl_frm.vcd_frm.virtual) {
+		cctxt->status.eos_trig_ip_frm = *input_frame;
+		cctxt->status.mask |= VCD_EOS_WAIT_OP_BUF;
+		return;
+	}
+
+	buf_entry = vcd_find_buffer_pool_entry(&cctxt->out_buf_pool,
+		ddl_frm.vcd_frm.virtual);
+	if (!buf_entry) {
+		VCD_MSG_ERROR("Unrecognized buffer address provided = %p",
+				  ddl_frm.vcd_frm.virtual);
+		return;
+	} else {
+		if (cctxt->sched_clnt_hdl->tkns)
+			cctxt->sched_clnt_hdl->tkns--;
+
+		VCD_MSG_MED("Sending non-NULL output with EOS");
+
+		buf_entry->frame.data_len = 0;
+		buf_entry->frame.offset = 0;
+		buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS;
+		buf_entry->frame.ip_frm_tag = input_frame->ip_frm_tag;
+		buf_entry->frame.time_stamp = input_frame->time_stamp;
+
+		cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE,
+				  VCD_S_SUCCESS,
+				  &buf_entry->frame,
+				  sizeof(struct vcd_frame_data),
+				  cctxt, cctxt->client_data);
+
+		buf_entry->in_use = false;
+		VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->out_buf_pool.in_use);
+	}
+}
+
+void vcd_send_frame_done_in_eos_for_enc(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_frame_data *input_frame)
+{
+	struct vcd_buffer_entry *op_buf_entry;
+
+	if (!cctxt->out_buf_pool.q_len) {
+		cctxt->status.eos_trig_ip_frm = *input_frame;
+
+		cctxt->status.mask |= VCD_EOS_WAIT_OP_BUF;
+
+		return;
+	}
+
+	op_buf_entry = vcd_buffer_pool_entry_de_q(&cctxt->out_buf_pool);
+	if (!op_buf_entry) {
+		VCD_MSG_ERROR("%s(): vcd_buffer_pool_entry_de_q() "
+			"failed\n", __func__);
+	} else {
+		if (cctxt->sched_clnt_hdl->tkns)
+			cctxt->sched_clnt_hdl->tkns--;
+
+		VCD_MSG_MED("Sending non-NULL output with EOS");
+
+		op_buf_entry->frame.data_len = 0;
+		op_buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS;
+		op_buf_entry->frame.ip_frm_tag =
+			input_frame->ip_frm_tag;
+		op_buf_entry->frame.time_stamp = input_frame->time_stamp;
+
+		cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE,
+				  VCD_S_SUCCESS,
+				  &op_buf_entry->frame,
+				  sizeof(struct vcd_frame_data),
+				  cctxt, cctxt->client_data);
+	}
+}
+
+u32 vcd_handle_recvd_eos(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_frame_data *input_frame, u32 *pb_eos_handled)
+{
+	u32 rc;
+
+	VCD_MSG_LOW("vcd_handle_recvd_eos:");
+
+	*pb_eos_handled = false;
+
+	if (input_frame->virtual &&
+			input_frame->data_len)
+		return VCD_S_SUCCESS;
+
+	input_frame->data_len = 0;
+	rc = vcd_sched_mark_client_eof(cctxt->sched_clnt_hdl);
+	if (VCD_FAILED(rc) && rc != VCD_ERR_QEMPTY)
+		return rc;
+
+	if (rc == VCD_S_SUCCESS)
+		*pb_eos_handled = true;
+	else if (cctxt->decoding && !input_frame->virtual)
+		cctxt->sched_clnt_hdl->tkns++;
+	else if (!cctxt->decoding) {
+		vcd_send_frame_done_in_eos(cctxt, input_frame, false);
+		if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) {
+			vcd_do_client_state_transition(cctxt,
+				VCD_CLIENT_STATE_EOS,
+				CLIENT_STATE_EVENT_NUMBER
+				(encode_frame));
+		}
+		*pb_eos_handled = true;
+	}
+
+	if (*pb_eos_handled &&
+		input_frame->virtual &&
+		!input_frame->data_len) {
+		cctxt->callback(VCD_EVT_RESP_INPUT_DONE,
+				  VCD_S_SUCCESS,
+				  input_frame,
+				  sizeof(struct vcd_frame_data),
+				  cctxt, cctxt->client_data);
+	}
+	return VCD_S_SUCCESS;
+}
+
+u32 vcd_handle_first_decode_frame(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc =  VCD_ERR_BAD_STATE;
+
+	VCD_MSG_LOW("vcd_handle_first_decode_frame:");
+	if (!cctxt->in_buf_pool.entries ||
+		!cctxt->out_buf_pool.entries ||
+		cctxt->in_buf_pool.validated !=
+		cctxt->in_buf_pool.count ||
+		cctxt->out_buf_pool.validated !=
+		cctxt->out_buf_pool.count)
+		VCD_MSG_ERROR("Buffer pool is not completely setup yet");
+	else if (!cctxt->sched_clnt_hdl) {
+		rc = vcd_sched_add_client(cctxt);
+		VCD_FAILED_RETURN(rc, "Failed: vcd_add_client_to_sched");
+		cctxt->sched_clnt_hdl->tkns =
+			cctxt->out_buf_pool.q_len;
+	} else
+		rc = vcd_sched_suspend_resume_clnt(cctxt, true);
+	return rc;
+}
+
+u32 vcd_setup_with_ddl_capabilities(struct vcd_dev_ctxt *dev_ctxt)
+{
+	struct vcd_property_hdr Prop_hdr;
+	struct ddl_property_capability capability;
+	u32 rc = VCD_S_SUCCESS;
+
+	VCD_MSG_LOW("vcd_setup_with_ddl_capabilities:");
+
+	if (!dev_ctxt->ddl_cmd_ch_depth) {
+		Prop_hdr.prop_id = DDL_I_CAPABILITY;
+		Prop_hdr.sz = sizeof(capability);
+
+		/*
+		** Since this is underlying core's property we don't need a
+		** ddl client handle.
+		*/
+		rc = ddl_get_property(NULL, &Prop_hdr, &capability);
+
+		if (!VCD_FAILED(rc)) {
+			/*
+			** Allocate the transaction table.
+			*/
+			dev_ctxt->trans_tbl_size =
+				(VCD_MAX_CLIENT_TRANSACTIONS *
+				capability.max_num_client) +
+				capability.general_command_depth;
+
+			dev_ctxt->trans_tbl = (struct vcd_transc *)
+				kzalloc((sizeof(struct vcd_transc) *
+				dev_ctxt->trans_tbl_size), GFP_KERNEL);
+
+			if (!dev_ctxt->trans_tbl) {
+				VCD_MSG_ERROR("Transaction table alloc failed");
+				rc = VCD_ERR_ALLOC_FAIL;
+			} else	{
+				dev_ctxt->ddl_cmd_concurrency =
+					!capability.exclusive;
+				dev_ctxt->ddl_frame_ch_depth =
+					capability.frame_command_depth;
+				dev_ctxt->ddl_cmd_ch_depth =
+					capability.general_command_depth;
+
+				vcd_reset_device_channels(dev_ctxt);
+
+				dev_ctxt->hw_time_out =
+					capability.ddl_time_out_in_ms;
+
+			}
+		}
+	}
+	return rc;
+}
+
+struct vcd_transc *vcd_get_free_trans_tbl_entry
+	(struct vcd_dev_ctxt *dev_ctxt) {
+	u32 i;
+
+	if (!dev_ctxt->trans_tbl)
+		return NULL;
+
+	i = 0;
+	while (i < dev_ctxt->trans_tbl_size &&
+		   dev_ctxt->trans_tbl[i].in_use)
+		i++;
+
+	if (i == dev_ctxt->trans_tbl_size) {
+		return NULL;
+	} else {
+		memset(&dev_ctxt->trans_tbl[i], 0,
+			   sizeof(struct vcd_transc));
+
+		dev_ctxt->trans_tbl[i].in_use = true;
+
+		return &dev_ctxt->trans_tbl[i];
+	}
+}
+
+void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry)
+{
+	if (trans_entry)
+		trans_entry->in_use = false;
+}
+
+u32 vcd_handle_input_done(
+	struct vcd_clnt_ctxt *cctxt,
+	 void *payload, u32 event, u32 status)
+{
+	struct vcd_transc *transc;
+	struct ddl_frame_data_tag *frame =
+		(struct ddl_frame_data_tag *) payload;
+	u32 rc;
+
+	if (!cctxt->status.frame_submitted &&
+		!cctxt->status.frame_delayed) {
+		VCD_MSG_ERROR("Input done was not expected");
+		return VCD_ERR_BAD_STATE;
+	}
+
+	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);
+	VCD_FAILED_RETURN(rc, "Bad input done payload");
+
+	transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag;
+
+	if ((transc->ip_buf_entry->frame.virtual !=
+		 frame->vcd_frm.virtual)
+		|| !transc->ip_buf_entry->in_use) {
+		VCD_MSG_ERROR("Bad frm transaction state");
+		vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end);
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	frame->vcd_frm.ip_frm_tag = transc->ip_frm_tag;
+	transc->frame = frame->vcd_frm.frame;
+
+	cctxt->callback(event,
+			status,
+			&frame->vcd_frm,
+			sizeof(struct vcd_frame_data),
+			cctxt, cctxt->client_data);
+
+	transc->ip_buf_entry->in_use = false;
+	VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->in_buf_pool.in_use);
+	transc->ip_buf_entry = NULL;
+	transc->input_done = true;
+
+	if (transc->input_done && transc->frame_done)
+		vcd_release_trans_tbl_entry(transc);
+
+	if (VCD_FAILED(status)) {
+		VCD_MSG_ERROR("INPUT_DONE returned err = 0x%x", status);
+		vcd_handle_input_done_failed(cctxt, transc);
+	} else
+		cctxt->status.mask |= VCD_FIRST_IP_DONE;
+
+	if (cctxt->status.frame_submitted > 0)
+		cctxt->status.frame_submitted--;
+	else
+		cctxt->status.frame_delayed--;
+
+	if (!VCD_FAILED(status) &&
+		cctxt->decoding) {
+		if (frame->vcd_frm.flags & VCD_FRAME_FLAG_CODECCONFIG) {
+			VCD_MSG_HIGH(
+				"INPUT_DONE with VCD_FRAME_FLAG_CODECCONFIG");
+			vcd_handle_input_done_with_codec_config(cctxt,
+				transc, frame);
+			frame->vcd_frm.flags &= ~VCD_FRAME_FLAG_CODECCONFIG;
+		}
+		if (frame->vcd_frm.interlaced)
+			vcd_handle_input_done_for_interlacing(cctxt);
+		if (frame->frm_trans_end)
+			vcd_handle_input_done_with_trans_end(cctxt);
+	}
+
+	return VCD_S_SUCCESS;
+}
+
+u32 vcd_handle_input_done_in_eos(
+	struct vcd_clnt_ctxt *cctxt, void *payload, u32 status)
+{
+	struct vcd_transc *transc;
+	struct ddl_frame_data_tag *frame =
+		(struct ddl_frame_data_tag *) payload;
+	u32 rc = VCD_ERR_FAIL, codec_config = false;
+	u32 core_type = res_trk_get_core_type();
+	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);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_validate_io_done_pyld");
+	transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag;
+	codec_config = frame->vcd_frm.flags & VCD_FRAME_FLAG_CODECCONFIG;
+	rc = vcd_handle_input_done(cctxt,
+		payload, VCD_EVT_RESP_INPUT_DONE, status);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_handle_input_done");
+	if (frame->vcd_frm.flags & VCD_FRAME_FLAG_EOS) {
+		VCD_MSG_HIGH("Got input done for EOS initiator");
+		transc->input_done = false;
+		transc->in_use = true;
+		if (codec_config ||
+			((status == VCD_ERR_BITSTREAM_ERR) &&
+			 !(cctxt->status.mask & VCD_FIRST_IP_DONE) &&
+			 (core_type == VCD_CORE_720P)))
+			vcd_handle_eos_done(cctxt, transc, VCD_S_SUCCESS);
+	}
+	return rc;
+}
+
+u32 vcd_validate_io_done_pyld(
+	struct vcd_clnt_ctxt *cctxt, void *payload, u32 status)
+{
+	struct ddl_frame_data_tag *frame =
+		(struct ddl_frame_data_tag *) payload;
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	struct vcd_transc *transc = NULL;
+	u32 rc = VCD_S_SUCCESS, i = 0;
+
+	if (!frame) {
+		VCD_MSG_ERROR("Bad payload from DDL");
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag;
+	if (dev_ctxt->trans_tbl) {
+		while (i < dev_ctxt->trans_tbl_size &&
+			transc != &dev_ctxt->trans_tbl[i])
+			i++;
+		if (i == dev_ctxt->trans_tbl_size ||
+			!dev_ctxt->trans_tbl[i].in_use)
+			rc = VCD_ERR_CLIENT_FATAL;
+	} else
+		rc = VCD_ERR_CLIENT_FATAL;
+
+	if (VCD_FAILED(rc)) {
+		VCD_MSG_FATAL(
+			"vcd_validate_io_done_pyld: invalid transaction");
+	} else if (!frame->vcd_frm.virtual &&
+		status != VCD_ERR_INTRLCD_FIELD_DROP)
+		rc = VCD_ERR_BAD_POINTER;
+
+	return rc;
+}
+
+void vcd_handle_input_done_failed(
+	struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc)
+{
+	if (cctxt->decoding) {
+		cctxt->sched_clnt_hdl->tkns++;
+		vcd_release_trans_tbl_entry(transc);
+	}
+}
+
+void vcd_handle_input_done_with_codec_config(
+	struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc,
+	struct ddl_frame_data_tag *frm)
+{
+	cctxt->sched_clnt_hdl->tkns++;
+	if (frm->frm_trans_end)
+		vcd_release_trans_tbl_entry(transc);
+}
+
+void vcd_handle_input_done_for_interlacing(struct vcd_clnt_ctxt *cctxt)
+{
+	cctxt->status.int_field_cnt++;
+	if (cctxt->status.int_field_cnt == 1)
+		cctxt->sched_clnt_hdl->tkns++;
+	else if (cctxt->status.int_field_cnt ==
+		VCD_DEC_NUM_INTERLACED_FIELDS)
+		cctxt->status.int_field_cnt = 0;
+}
+
+void vcd_handle_input_done_with_trans_end(
+	struct vcd_clnt_ctxt *cctxt)
+{
+	if (!cctxt->decoding)
+		return;
+	if (cctxt->out_buf_pool.in_use <
+		cctxt->out_buf_pool.buf_req.min_count)
+		return;
+	if (!cctxt->sched_clnt_hdl->tkns)
+		cctxt->sched_clnt_hdl->tkns++;
+}
+
+u32 vcd_handle_output_required(struct vcd_clnt_ctxt
+	*cctxt, void *payload, u32 status)
+{
+	struct vcd_transc *transc;
+	struct ddl_frame_data_tag *frame =
+		(struct ddl_frame_data_tag *)payload;
+	u32 rc = VCD_S_SUCCESS;
+
+	if (!cctxt->status.frame_submitted &&
+		!cctxt->status.frame_delayed) {
+		VCD_MSG_ERROR("\n Input done was not expected");
+		return VCD_ERR_BAD_STATE;
+	}
+
+	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);
+	VCD_FAILED_RETURN(rc, "\n Bad input done payload");
+
+	transc = (struct vcd_transc *)frame->
+		vcd_frm.ip_frm_tag;
+
+	if ((transc->ip_buf_entry->frame.virtual !=
+		 frame->vcd_frm.virtual) ||
+		!transc->ip_buf_entry->in_use) {
+		VCD_MSG_ERROR("\n Bad frm transaction state");
+		vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end);
+		return VCD_ERR_BAD_STATE;
+	}
+	rc = vcd_sched_queue_buffer(cctxt->sched_clnt_hdl,
+			transc->ip_buf_entry, false);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_sched_queue_buffer");
+
+	transc->ip_buf_entry = NULL;
+	vcd_release_trans_tbl_entry(transc);
+	frame->frm_trans_end = true;
+
+	if (VCD_FAILED(status))
+		VCD_MSG_ERROR("\n OUTPUT_REQ returned err = 0x%x",
+			status);
+
+	if (cctxt->status.frame_submitted > 0)
+		cctxt->status.frame_submitted--;
+	else
+		cctxt->status.frame_delayed--;
+
+
+	if (!VCD_FAILED(status) &&
+		cctxt->decoding &&
+		frame->vcd_frm.interlaced) {
+		if (cctxt->status.int_field_cnt > 0) {
+			VCD_MSG_ERROR("\n Not expected: OUTPUT_REQ"
+				"for 2nd interlace field");
+			rc = VCD_ERR_FAIL;
+		}
+	}
+
+	return rc;
+}
+
+u32 vcd_handle_output_required_in_flushing(
+struct vcd_clnt_ctxt *cctxt, void *payload)
+{
+	u32 rc;
+	struct vcd_transc *transc;
+	struct ddl_frame_data_tag *frame =
+		(struct ddl_frame_data_tag *)payload;
+
+	rc = vcd_validate_io_done_pyld(cctxt, payload, VCD_S_SUCCESS);
+	if (rc == VCD_ERR_CLIENT_FATAL)
+		vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end);
+	VCD_FAILED_RETURN(rc, "Bad input done payload");
+
+	transc = (struct vcd_transc *)
+		(((struct ddl_frame_data_tag *)payload)->
+		 vcd_frm.ip_frm_tag);
+
+	((struct ddl_frame_data_tag *)payload)->
+		vcd_frm.interlaced = false;
+
+	rc = vcd_handle_input_done(cctxt, payload,
+			VCD_EVT_RESP_INPUT_FLUSHED, VCD_S_SUCCESS);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_handle_input_done");
+
+	vcd_release_trans_tbl_entry(transc);
+	((struct ddl_frame_data_tag *)payload)->frm_trans_end = true;
+
+	return rc;
+}
+
+u32 vcd_handle_frame_done(
+	struct vcd_clnt_ctxt *cctxt,
+	 void *payload, u32 event, u32 status)
+{
+	struct vcd_buffer_entry *op_buf_entry = NULL;
+	struct ddl_frame_data_tag *op_frm =
+		(struct ddl_frame_data_tag *) payload;
+	struct vcd_transc *transc;
+	u32 rc;
+
+	rc = vcd_validate_io_done_pyld(cctxt, payload, status);
+	if (rc == VCD_ERR_CLIENT_FATAL)
+		vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end);
+	VCD_FAILED_RETURN(rc, "Bad payload recvd");
+
+	transc = (struct vcd_transc *)op_frm->vcd_frm.ip_frm_tag;
+
+	if (op_frm->vcd_frm.virtual) {
+
+		if (!transc->op_buf_entry) {
+			op_buf_entry =
+				vcd_find_buffer_pool_entry(
+					&cctxt->out_buf_pool,
+					op_frm->vcd_frm.
+					virtual);
+		} else {
+			op_buf_entry = transc->op_buf_entry;
+		}
+
+		if (!op_buf_entry) {
+			VCD_MSG_ERROR("Invalid output buffer returned"
+				"from DDL");
+			vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end);
+			rc = VCD_ERR_BAD_POINTER;
+		} else if (!op_buf_entry->in_use) {
+			VCD_MSG_ERROR("Bad output buffer 0x%p recvd from DDL",
+					  op_buf_entry->frame.virtual);
+			vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end);
+			rc = VCD_ERR_BAD_POINTER;
+		} else {
+			op_buf_entry->in_use = false;
+			VCD_BUFFERPOOL_INUSE_DECREMENT(
+				cctxt->out_buf_pool.in_use);
+			VCD_MSG_LOW("outBufPool.InUse = %d",
+						cctxt->out_buf_pool.in_use);
+		}
+	}
+	VCD_FAILED_RETURN(rc, "Bad output buffer pointer");
+	op_frm->vcd_frm.time_stamp = transc->time_stamp;
+	op_frm->vcd_frm.ip_frm_tag = transc->ip_frm_tag;
+	if (cctxt->decoding)
+		op_frm->vcd_frm.frame = transc->frame;
+	else
+		transc->frame = op_frm->vcd_frm.frame;
+	transc->frame_done = true;
+
+	if (transc->input_done && transc->frame_done)
+		vcd_release_trans_tbl_entry(transc);
+
+	if (status == VCD_ERR_INTRLCD_FIELD_DROP ||
+		(op_frm->vcd_frm.intrlcd_ip_frm_tag !=
+		VCD_FRAMETAG_INVALID &&
+		op_frm->vcd_frm.intrlcd_ip_frm_tag)) {
+		vcd_handle_frame_done_for_interlacing(cctxt, transc,
+							  op_frm, status);
+	}
+
+	if (status != VCD_ERR_INTRLCD_FIELD_DROP) {
+		cctxt->callback(event,
+			status,
+			&op_frm->vcd_frm,
+			sizeof(struct vcd_frame_data),
+			cctxt, cctxt->client_data);
+	}
+	return rc;
+}
+
+u32 vcd_handle_frame_done_in_eos(
+	struct vcd_clnt_ctxt *cctxt, void *payload, u32 status)
+{
+	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:");
+	rc = vcd_validate_io_done_pyld(cctxt, payload, status);
+	if (rc == VCD_ERR_CLIENT_FATAL)
+		vcd_handle_clnt_fatal(cctxt, frame->frm_trans_end);
+	VCD_FAILED_RETURN(rc, "Bad payload received");
+
+	if (cctxt->status.mask & VCD_EOS_PREV_VALID) {
+		rc = vcd_handle_frame_done(cctxt,
+			(void *)&cctxt->status.
+			eos_prev_op_frm,
+			VCD_EVT_RESP_OUTPUT_DONE,
+			cctxt->status.eos_prev_op_frm_status);
+		VCD_FAILED_RETURN(rc, "Failed: vcd_handle_frame_done");
+	}
+
+	cctxt->status.eos_prev_op_frm = *frame;
+	cctxt->status.eos_prev_op_frm_status = status;
+	cctxt->status.mask |= VCD_EOS_PREV_VALID;
+	return rc;
+}
+
+void vcd_handle_frame_done_for_interlacing(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_transc *transc_ip1,
+	 struct ddl_frame_data_tag *op_frm, u32 status)
+{
+	struct vcd_transc *transc_ip2 =
+		(struct vcd_transc *)op_frm->\
+		vcd_frm.intrlcd_ip_frm_tag;
+
+	if (status == VCD_ERR_INTRLCD_FIELD_DROP) {
+		cctxt->status.int_field_cnt = 0;
+		return;
+	}
+
+	op_frm->vcd_frm.intrlcd_ip_frm_tag = transc_ip2->ip_frm_tag;
+
+	transc_ip2->frame_done = true;
+
+	if (transc_ip2->input_done && transc_ip2->frame_done)
+		vcd_release_trans_tbl_entry(transc_ip2);
+
+	if (!transc_ip1->frame || !transc_ip2->frame) {
+		VCD_MSG_ERROR("DDL didn't provided frame type");
+		return;
+	}
+}
+
+u32 vcd_handle_first_fill_output_buffer(
+	struct vcd_clnt_ctxt *cctxt,
+	struct vcd_frame_data *buffer,
+	u32 *handled)
+{
+	u32 rc = VCD_S_SUCCESS;
+	rc = vcd_check_if_buffer_req_met(cctxt, VCD_BUFFER_OUTPUT);
+	VCD_FAILED_RETURN(rc, "Output buffer requirements not met");
+	if (cctxt->out_buf_pool.q_len > 0) {
+		VCD_MSG_ERROR("Old output buffers were not flushed out");
+		return VCD_ERR_BAD_STATE;
+	}
+	cctxt->status.mask |= VCD_FIRST_OP_RCVD;
+	if (cctxt->sched_clnt_hdl)
+		rc = vcd_sched_suspend_resume_clnt(cctxt, true);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt");
+	if (cctxt->decoding)
+		rc = vcd_handle_first_fill_output_buffer_for_dec(
+			cctxt, buffer, handled);
+	else
+		rc = vcd_handle_first_fill_output_buffer_for_enc(
+			cctxt, buffer, handled);
+	return rc;
+}
+
+u32 vcd_handle_first_fill_output_buffer_for_enc(
+	struct vcd_clnt_ctxt *cctxt,
+	struct vcd_frame_data *frm_entry,
+	u32 *handled)
+{
+	u32 rc, seqhdr_present = 0;
+	struct vcd_property_hdr prop_hdr;
+	struct vcd_sequence_hdr seq_hdr;
+	struct vcd_property_codec codec;
+	*handled = true;
+	prop_hdr.prop_id = DDL_I_SEQHDR_PRESENT;
+	prop_hdr.sz = sizeof(seqhdr_present);
+	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &seqhdr_present);
+	VCD_FAILED_RETURN(rc, "Failed: DDL_I_SEQHDR_PRESENT");
+	if (!seqhdr_present) {
+		*handled = false;
+		return VCD_S_SUCCESS;
+	}
+
+	prop_hdr.prop_id = VCD_I_CODEC;
+	prop_hdr.sz = sizeof(struct vcd_property_codec);
+	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;
+				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);
+		} else
+			VCD_MSG_LOW("Codec Type is H.263\n");
+	} else
+		VCD_MSG_ERROR(
+			"rc = 0x%x. Failed: ddl_get_property:VCD_I_CODEC",
+			rc);
+	return rc;
+}
+
+u32 vcd_handle_first_fill_output_buffer_for_dec(
+	struct vcd_clnt_ctxt *cctxt,
+	struct vcd_frame_data *frm_entry,
+	u32 *handled)
+{
+	u32 rc;
+	struct vcd_property_hdr prop_hdr;
+	struct vcd_buffer_pool *out_buf_pool;
+	struct ddl_property_dec_pic_buffers dpb;
+	struct ddl_frame_data_tag *dpb_list;
+	u8 i;
+
+	(void)frm_entry;
+	*handled = true;
+	prop_hdr.prop_id = DDL_I_DPB;
+	prop_hdr.sz = sizeof(dpb);
+	out_buf_pool = &cctxt->out_buf_pool;
+
+	dpb_list = (struct ddl_frame_data_tag *)
+		kmalloc((sizeof(struct ddl_frame_data_tag) *
+		out_buf_pool->count), GFP_KERNEL);
+
+	if (!dpb_list) {
+		VCD_MSG_ERROR("Memory allocation failure");
+		return VCD_ERR_ALLOC_FAIL;
+	}
+
+	for (i = 1; i <= out_buf_pool->count; i++)
+		dpb_list[i - 1].vcd_frm = out_buf_pool->entries[i].frame;
+
+	dpb.dec_pic_buffers = dpb_list;
+	dpb.no_of_dec_pic_buf = out_buf_pool->count;
+	rc = ddl_set_property(cctxt->ddl_handle, &prop_hdr, &dpb);
+
+	kfree(dpb_list);
+	*handled = false;
+
+	return VCD_S_SUCCESS;
+}
+
+void vcd_handle_eos_trans_end(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (cctxt->status.mask & VCD_EOS_PREV_VALID) {
+		rc = vcd_handle_frame_done(cctxt,
+			(void *)&cctxt->status.eos_prev_op_frm,
+			VCD_EVT_RESP_OUTPUT_DONE,
+			cctxt->status.eos_prev_op_frm_status);
+		cctxt->status.mask &= ~VCD_EOS_PREV_VALID;
+	}
+	if (VCD_FAILED(rc))
+		return;
+
+	if (cctxt->status.mask & VCD_FLUSH_ALL)
+		vcd_process_pending_flush_in_eos(cctxt);
+
+	if (cctxt->status.mask & VCD_STOP_PENDING)
+		vcd_process_pending_stop_in_eos(cctxt);
+	else {
+		vcd_do_client_state_transition(cctxt,
+			VCD_CLIENT_STATE_RUN,
+			CLIENT_STATE_EVENT_NUMBER(clnt_cb));
+	}
+}
+
+void vcd_handle_eos_done(struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_transc *transc, u32 status)
+{
+	struct vcd_frame_data  vcd_frm;
+	u32 rc = VCD_S_SUCCESS, sent_eos_frm = false;
+	VCD_MSG_LOW("vcd_handle_eos_done:");
+
+	if (VCD_FAILED(status))
+		VCD_MSG_ERROR("EOS DONE returned error = 0x%x", status);
+
+	if (cctxt->status.mask & VCD_EOS_PREV_VALID) {
+		cctxt->status.eos_prev_op_frm.vcd_frm.flags |=
+			VCD_FRAME_FLAG_EOS;
+
+		rc = vcd_handle_frame_done(cctxt,
+						(void *)&cctxt->status.
+						eos_prev_op_frm,
+						VCD_EVT_RESP_OUTPUT_DONE,
+						cctxt->status.
+							eos_prev_op_frm_status);
+		cctxt->status.mask &= ~VCD_EOS_PREV_VALID;
+		if (!VCD_FAILED(rc) &&
+			cctxt->status.eos_prev_op_frm_status !=
+				VCD_ERR_INTRLCD_FIELD_DROP)
+			sent_eos_frm = true;
+	}
+	if (!sent_eos_frm) {
+		if (transc->ip_buf_entry) {
+			transc->ip_buf_entry->frame.ip_frm_tag =
+				transc->ip_frm_tag;
+
+			vcd_send_frame_done_in_eos(cctxt,
+				&transc->ip_buf_entry->frame, false);
+		} else {
+			memset(&vcd_frm, 0, sizeof(struct vcd_frame_data));
+			vcd_frm.ip_frm_tag = transc->ip_frm_tag;
+			vcd_frm.time_stamp = transc->time_stamp;
+			vcd_frm.flags = VCD_FRAME_FLAG_EOS;
+			vcd_send_frame_done_in_eos(cctxt, &vcd_frm, true);
+		}
+	}
+	if (VCD_FAILED(rc))
+		return;
+	if (transc->ip_buf_entry) {
+		if (transc->ip_buf_entry->frame.virtual) {
+			transc->ip_buf_entry->frame.ip_frm_tag =
+				transc->ip_frm_tag;
+			cctxt->callback(VCD_EVT_RESP_INPUT_DONE,
+					  VCD_S_SUCCESS,
+					  &transc->ip_buf_entry->frame,
+					  sizeof(struct vcd_frame_data),
+					  cctxt, cctxt->client_data);
+		}
+		transc->ip_buf_entry->in_use = false;
+		VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->in_buf_pool.in_use);
+		transc->ip_buf_entry = NULL;
+		if (cctxt->status.frame_submitted)
+			cctxt->status.frame_submitted--;
+		else
+			cctxt->status.frame_delayed--;
+	}
+
+	vcd_release_trans_tbl_entry(transc);
+	if (cctxt->status.mask & VCD_FLUSH_ALL)
+		vcd_process_pending_flush_in_eos(cctxt);
+
+	if (cctxt->status.mask & VCD_STOP_PENDING) {
+		vcd_process_pending_stop_in_eos(cctxt);
+	} else if (!(cctxt->status.mask & VCD_EOS_WAIT_OP_BUF)) {
+		vcd_do_client_state_transition(cctxt,
+						   VCD_CLIENT_STATE_RUN,
+						   CLIENT_STATE_EVENT_NUMBER
+						   (clnt_cb));
+	}
+}
+
+void vcd_handle_start_done(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_transc *transc, u32 status)
+{
+	cctxt->status.cmd_submitted--;
+	vcd_mark_command_channel(cctxt->dev_ctxt, transc);
+
+	if (!VCD_FAILED(status)) {
+		cctxt->callback(VCD_EVT_RESP_START, status, NULL,
+			0, cctxt,	cctxt->client_data);
+
+		vcd_do_client_state_transition(cctxt,
+			VCD_CLIENT_STATE_RUN,
+			CLIENT_STATE_EVENT_NUMBER(clnt_cb));
+	} else {
+		VCD_MSG_ERROR("ddl callback returned failure."
+			"status = 0x%x", status);
+		vcd_handle_err_in_starting(cctxt, status);
+	}
+}
+
+void vcd_handle_stop_done(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_transc *transc, u32 status)
+{
+
+	VCD_MSG_LOW("vcd_handle_stop_done:");
+	cctxt->status.cmd_submitted--;
+	vcd_mark_command_channel(cctxt->dev_ctxt, transc);
+
+	if (!VCD_FAILED(status)) {
+		vcd_do_client_state_transition(cctxt,
+			VCD_CLIENT_STATE_OPEN,
+			CLIENT_STATE_EVENT_NUMBER(clnt_cb));
+	} else {
+		VCD_MSG_FATAL("STOP_DONE returned error = 0x%x", status);
+		status = VCD_ERR_HW_FATAL;
+		vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt);
+		vcd_do_client_state_transition(cctxt,
+			VCD_CLIENT_STATE_INVALID,
+			CLIENT_STATE_EVENT_NUMBER(clnt_cb));
+	}
+
+	cctxt->callback(VCD_EVT_RESP_STOP, status, NULL, 0, cctxt,
+					  cctxt->client_data);
+
+	memset(&cctxt->status, 0, sizeof(struct vcd_clnt_status));
+}
+
+void vcd_handle_stop_done_in_starting(struct vcd_clnt_ctxt
+	*cctxt, struct vcd_transc *transc, u32 status)
+{
+	VCD_MSG_LOW("vcd_handle_stop_done_in_starting:");
+	cctxt->status.cmd_submitted--;
+	vcd_mark_command_channel(cctxt->dev_ctxt, transc);
+	if (!VCD_FAILED(status)) {
+		cctxt->callback(VCD_EVT_RESP_START, cctxt->status.
+			last_err, NULL, 0, cctxt, cctxt->client_data);
+		vcd_do_client_state_transition(cctxt, VCD_CLIENT_STATE_OPEN,
+			   CLIENT_STATE_EVENT_NUMBER(clnt_cb));
+	} else {
+		VCD_MSG_FATAL("VCD Cleanup: STOP_DONE returned error "
+			"= 0x%x", status);
+		vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START,
+			VCD_ERR_HW_FATAL);
+	}
+}
+
+void vcd_handle_stop_done_in_invalid(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_transc *transc, u32 status)
+{
+	u32 rc;
+	VCD_MSG_LOW("vcd_handle_stop_done_in_invalid:");
+
+	cctxt->status.cmd_submitted--;
+	vcd_mark_command_channel(cctxt->dev_ctxt, transc);
+
+	if (!VCD_FAILED(status)) {
+		vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CLIENT_CLOSE);
+		if (cctxt->status.frame_submitted) {
+			vcd_release_multiple_frame_channels(cctxt->dev_ctxt,
+			cctxt->status.frame_submitted);
+
+			cctxt->status.frame_submitted = 0;
+			cctxt->status.frame_delayed = 0;
+		}
+		if (cctxt->status.cmd_submitted) {
+			vcd_release_multiple_command_channels(
+				cctxt->dev_ctxt,
+				cctxt->status.cmd_submitted);
+			cctxt->status.cmd_submitted = 0;
+		}
+	} else {
+		VCD_MSG_FATAL("VCD Cleanup: STOP_DONE returned error "
+			"= 0x%x", status);
+		vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt);
+		cctxt->status.mask &= ~VCD_CLEANING_UP;
+	}
+	vcd_flush_buffers_in_err_fatal(cctxt);
+	VCD_MSG_HIGH("VCD cleanup: All buffers are returned");
+	if (cctxt->status.mask & VCD_STOP_PENDING) {
+		cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, NULL, 0,
+			cctxt, cctxt->client_data);
+		cctxt->status.mask &= ~VCD_STOP_PENDING;
+	}
+	rc = vcd_power_event(cctxt->dev_ctxt, cctxt,
+						  VCD_EVT_PWR_CLNT_ERRFATAL);
+	if (VCD_FAILED(rc))
+		VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_ERRFATAL failed");
+	if (!(cctxt->status.mask & VCD_CLEANING_UP) &&
+		cctxt->status.mask & VCD_CLOSE_PENDING) {
+		vcd_destroy_client_context(cctxt);
+		vcd_handle_for_last_clnt_close(cctxt->dev_ctxt, false);
+	}
+}
+
+u32 vcd_handle_input_frame(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_frame_data *input_frame)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	struct vcd_buffer_entry *buf_entry;
+	struct vcd_frame_data *frm_entry;
+	u32 rc = VCD_S_SUCCESS;
+	u32 eos_handled = false;
+
+	VCD_MSG_LOW("vcd_handle_input_frame:");
+
+	VCD_MSG_LOW("input buffer: addr=(0x%p), sz=(%d), len=(%d)",
+			input_frame->virtual, input_frame->alloc_len,
+			input_frame->data_len);
+
+	if (!input_frame->virtual &&
+		!(input_frame->flags & VCD_FRAME_FLAG_EOS)) {
+		VCD_MSG_ERROR("Bad frame ptr/len/EOS combination");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+
+	if (!input_frame->data_len &&
+		!(input_frame->flags & VCD_FRAME_FLAG_EOS)) {
+		VCD_MSG_MED("data_len = 0, returning INPUT DONE");
+		cctxt->callback(VCD_EVT_RESP_INPUT_DONE,
+				  VCD_ERR_INPUT_NOT_PROCESSED,
+				  input_frame,
+				  sizeof(struct vcd_frame_data),
+				  cctxt, cctxt->client_data);
+		return VCD_S_SUCCESS;
+	}
+
+	if (!(cctxt->status.mask & VCD_FIRST_IP_RCVD)) {
+		if (cctxt->decoding)
+			rc = vcd_handle_first_decode_frame(cctxt);
+
+		if (!VCD_FAILED(rc)) {
+			cctxt->status.first_ts = input_frame->time_stamp;
+			cctxt->status.prev_ts = cctxt->status.first_ts;
+
+			cctxt->status.mask |= VCD_FIRST_IP_RCVD;
+
+			(void)vcd_power_event(cctxt->dev_ctxt,
+						  cctxt,
+						  VCD_EVT_PWR_CLNT_FIRST_FRAME);
+		}
+	}
+	VCD_FAILED_RETURN(rc, "Failed: First frame handling");
+
+	buf_entry = vcd_find_buffer_pool_entry(&cctxt->in_buf_pool,
+						 input_frame->virtual);
+	if (!buf_entry) {
+		VCD_MSG_ERROR("Bad buffer addr: %p", input_frame->virtual);
+		return VCD_ERR_FAIL;
+	}
+
+	if (buf_entry->in_use) {
+		VCD_MSG_ERROR("An inuse input frame is being"
+			"re-queued to scheduler");
+		return VCD_ERR_FAIL;
+	}
+
+	if (input_frame->alloc_len > buf_entry->sz) {
+		VCD_MSG_ERROR("Bad buffer Alloc_len %d, Actual sz=%d",
+			input_frame->alloc_len, buf_entry->sz);
+
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+
+	frm_entry = &buf_entry->frame;
+
+	*frm_entry = *input_frame;
+	frm_entry->physical = buf_entry->physical;
+
+	if (input_frame->flags & VCD_FRAME_FLAG_EOS) {
+		rc = vcd_handle_recvd_eos(cctxt, input_frame,
+					  &eos_handled);
+	}
+
+	if (VCD_FAILED(rc) || eos_handled) {
+		VCD_MSG_HIGH("rc = 0x%x, eos_handled = %d", rc,
+				 eos_handled);
+
+		return rc;
+	}
+	rc = vcd_sched_queue_buffer(
+		cctxt->sched_clnt_hdl, buf_entry, true);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_sched_queue_buffer");
+
+	buf_entry->in_use = true;
+	cctxt->in_buf_pool.in_use++;
+	vcd_try_submit_frame(dev_ctxt);
+	return rc;
+}
+
+void vcd_release_all_clnt_frm_transc(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 i, cntr = 0;
+	VCD_MSG_LOW("vcd_release_all_clnt_frm_transc:");
+	for (i = 0; i < dev_ctxt->trans_tbl_size; i++) {
+		if (dev_ctxt->trans_tbl[i].in_use &&
+			cctxt == dev_ctxt->trans_tbl[i].cctxt) {
+			if (dev_ctxt->trans_tbl[i].
+				type == VCD_CMD_CODE_FRAME ||
+				dev_ctxt->trans_tbl[i].
+				type == VCD_CMD_NONE) {
+				vcd_release_trans_tbl_entry(&dev_ctxt->
+								trans_tbl[i]);
+			} else {
+				VCD_MSG_LOW("vcd_transaction in use type(%u)",
+					dev_ctxt->trans_tbl[i].type);
+				cntr++;
+			}
+		}
+	}
+	if (cntr)
+		VCD_MSG_ERROR("vcd_transactions still in use: (%d)", cntr);
+}
+
+void vcd_release_all_clnt_transc(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt;
+	u32 i;
+
+	VCD_MSG_LOW("vcd_release_all_clnt_transc:");
+
+	for (i = 0; i < dev_ctxt->trans_tbl_size; i++) {
+		if (dev_ctxt->trans_tbl[i].in_use &&
+			cctxt == dev_ctxt->trans_tbl[i].cctxt) {
+				vcd_release_trans_tbl_entry(
+					&dev_ctxt->trans_tbl[i]);
+		}
+	}
+}
+
+void vcd_send_flush_done(struct vcd_clnt_ctxt *cctxt, u32 status)
+{
+	VCD_MSG_LOW("vcd_send_flush_done:");
+
+	if (cctxt->status.mask & VCD_FLUSH_INPUT) {
+		cctxt->callback(VCD_EVT_RESP_FLUSH_INPUT_DONE,
+			status, NULL, 0, cctxt, cctxt->client_data);
+		cctxt->status.mask &= ~VCD_FLUSH_INPUT;
+	}
+
+	if (cctxt->status.mask & VCD_FLUSH_OUTPUT) {
+		cctxt->callback(VCD_EVT_RESP_FLUSH_OUTPUT_DONE,
+			status, NULL, 0, cctxt, cctxt->client_data);
+		cctxt->status.mask &= ~VCD_FLUSH_OUTPUT;
+	}
+}
+
+u32 vcd_store_seq_hdr(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_sequence_hdr *seq_hdr)
+{
+	u32 rc;
+	struct vcd_property_hdr prop_hdr;
+	u32 align;
+	u8 *virtual_aligned;
+	u32 addr;
+	int ret = 0;
+
+	if (!seq_hdr->sequence_header_len
+		|| !seq_hdr->sequence_header) {
+		VCD_MSG_ERROR("Bad seq hdr");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	if (cctxt->seq_hdr.sequence_header) {
+		VCD_MSG_HIGH("Old seq hdr detected");
+
+		vcd_pmem_free(cctxt->seq_hdr.sequence_header,
+				  cctxt->seq_hdr_phy_addr);
+		cctxt->seq_hdr.sequence_header = NULL;
+	}
+
+	cctxt->seq_hdr.sequence_header_len =
+		seq_hdr->sequence_header_len;
+
+	prop_hdr.prop_id = DDL_I_SEQHDR_ALIGN_BYTES;
+	prop_hdr.sz = sizeof(u32);
+
+	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &align);
+
+	VCD_FAILED_RETURN(rc,
+			  "Failed: ddl_get_property DDL_I_SEQHDR_ALIGN_BYTES");
+
+	VCD_MSG_MED("Seq hdr alignment bytes = %d", align);
+
+	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));
+
+	if (ret < 0) {
+		VCD_MSG_ERROR("Seq hdr allocation failed");
+
+		return VCD_ERR_ALLOC_FAIL;
+	}
+
+	if (!cctxt->seq_hdr_phy_addr) {
+		VCD_MSG_ERROR("Couldn't get physical address");
+
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	if (align > 0) {
+		addr = (u32) cctxt->seq_hdr_phy_addr;
+		addr += align;
+		addr -= (addr % align);
+		virtual_aligned = cctxt->seq_hdr.sequence_header;
+		virtual_aligned += (u32) (addr -
+			(u32) cctxt->seq_hdr_phy_addr);
+		cctxt->seq_hdr_phy_addr = (u8 *) addr;
+	} else {
+		virtual_aligned = cctxt->seq_hdr.sequence_header;
+	}
+
+	memcpy(virtual_aligned, seq_hdr->sequence_header,
+		seq_hdr->sequence_header_len);
+
+	return VCD_S_SUCCESS;
+}
+
+u32 vcd_set_frame_rate(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_property_frame_rate *fps)
+{
+	u32 rc;
+	cctxt->frm_rate = *fps;
+	rc = vcd_update_clnt_perf_lvl(cctxt, &cctxt->frm_rate,
+					  cctxt->frm_p_units);
+	if (VCD_FAILED(rc)) {
+		VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_update_clnt_perf_lvl",
+				  rc);
+	}
+	rc = vcd_sched_update_config(cctxt);
+	return rc;
+}
+
+u32 vcd_set_frame_size(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_property_frame_size *frm_size)
+{
+	struct vcd_property_hdr prop_hdr;
+	u32 rc;
+	u32 frm_p_units;
+	(void)frm_size;
+
+	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);
+	VCD_FAILED_RETURN(rc, "Failed: Get DDL_I_FRAME_PROC_UNITS");
+
+	cctxt->frm_p_units = frm_p_units;
+
+	rc = vcd_update_clnt_perf_lvl(cctxt, &cctxt->frm_rate,
+					  frm_p_units);
+	if (VCD_FAILED(rc)) {
+		VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_update_clnt_perf_lvl",
+				  rc);
+	}
+	return rc;
+}
+
+void vcd_process_pending_flush_in_eos(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	VCD_MSG_HIGH("Buffer flush is pending");
+	rc = vcd_flush_buffers(cctxt, cctxt->status.mask & VCD_FLUSH_ALL);
+	if (VCD_FAILED(rc))
+		VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_flush_buffers", rc);
+	cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF;
+	vcd_send_flush_done(cctxt, VCD_S_SUCCESS);
+}
+
+void vcd_process_pending_stop_in_eos(struct vcd_clnt_ctxt *cctxt)
+{
+	u32 rc = VCD_S_SUCCESS;
+	rc = vcd_flush_buffers(cctxt, VCD_FLUSH_ALL);
+	if (VCD_FAILED(rc))
+		VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_flush_buffers", rc);
+	VCD_MSG_HIGH("All buffers are returned. Enqueuing stop cmd");
+	vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP);
+	cctxt->status.mask &= ~VCD_STOP_PENDING;
+	vcd_do_client_state_transition(cctxt,
+					   VCD_CLIENT_STATE_STOPPING,
+					   CLIENT_STATE_EVENT_NUMBER(stop));
+}
+
+u32 vcd_calculate_frame_delta(
+	struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_frame_data *frame)
+{
+	u32 frm_delta;
+	u64 temp, max = ~((u64)0);
+
+	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",
+			frame->time_stamp, cctxt->status.prev_ts, temp);
+
+	temp *= cctxt->time_resoln;
+	(void)do_div(temp, VCD_TIMESTAMP_RESOLUTION);
+	frm_delta = temp;
+	cctxt->status.time_elapsed += frm_delta;
+
+	temp = (cctxt->status.time_elapsed * VCD_TIMESTAMP_RESOLUTION);
+	(void)do_div(temp, cctxt->time_resoln);
+	cctxt->status.prev_ts = cctxt->status.first_ts + temp;
+
+	VCD_MSG_LOW("Time_elapsed=%llu, Drift=%llu, new Prev_ts=%lld",
+			cctxt->status.time_elapsed, temp,
+			cctxt->status.prev_ts);
+
+	return frm_delta;
+}
+
+struct vcd_buffer_entry *vcd_check_fill_output_buffer
+	(struct vcd_clnt_ctxt *cctxt,
+	 struct vcd_frame_data *buffer) {
+	struct vcd_buffer_pool *buf_pool = &cctxt->out_buf_pool;
+	struct vcd_buffer_entry *buf_entry;
+
+	if (!buf_pool->entries) {
+		VCD_MSG_ERROR("Buffers not set or allocated yet");
+
+		return NULL;
+	}
+
+	if (!buffer->virtual) {
+		VCD_MSG_ERROR("NULL buffer address provided");
+		return NULL;
+	}
+
+	buf_entry =
+		vcd_find_buffer_pool_entry(buf_pool, buffer->virtual);
+	if (!buf_entry) {
+		VCD_MSG_ERROR("Unrecognized buffer address provided = %p",
+				  buffer->virtual);
+		return NULL;
+	}
+
+	if (buf_entry->in_use) {
+		VCD_MSG_ERROR
+			("An inuse output frame is being provided for reuse");
+		return NULL;
+	}
+
+	if ((buffer->alloc_len < buf_pool->buf_req.sz ||
+		 buffer->alloc_len > buf_entry->sz) &&
+		 !(cctxt->status.mask & VCD_IN_RECONFIG)) {
+		VCD_MSG_ERROR
+			("Bad buffer Alloc_len = %d, Actual sz = %d, "
+			 " Min sz = %u",
+			 buffer->alloc_len, buf_entry->sz,
+			 buf_pool->buf_req.sz);
+		return NULL;
+	}
+
+	return buf_entry;
+}
+
+void vcd_handle_ind_hw_err_fatal(struct vcd_clnt_ctxt *cctxt,
+	u32 event, u32 status)
+{
+	if (cctxt->status.frame_submitted) {
+		cctxt->status.frame_submitted--;
+		vcd_mark_frame_channel(cctxt->dev_ctxt);
+	}
+	vcd_handle_err_fatal(cctxt, event, status);
+}
+
+void vcd_handle_err_fatal(struct vcd_clnt_ctxt *cctxt, u32 event,
+						  u32 status)
+{
+	VCD_MSG_LOW("vcd_handle_err_fatal: event=%x, err=%x", event, status);
+	if (!VCD_FAILED_FATAL(status))
+		return;
+
+	if (VCD_FAILED_DEVICE_FATAL(status)) {
+		vcd_clnt_handle_device_err_fatal(cctxt, event);
+		vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt);
+	} else if (VCD_FAILED_CLIENT_FATAL(status)) {
+		cctxt->status.last_evt = event;
+		cctxt->callback(event, VCD_ERR_HW_FATAL, NULL, 0, cctxt,
+						   cctxt->client_data);
+		cctxt->status.mask |= VCD_CLEANING_UP;
+		vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP);
+		vcd_do_client_state_transition(cctxt,
+			VCD_CLIENT_STATE_INVALID,
+			CLIENT_STATE_EVENT_NUMBER(clnt_cb));
+	}
+}
+
+void vcd_handle_err_in_starting(struct vcd_clnt_ctxt *cctxt,
+								u32 status)
+{
+	VCD_MSG_LOW("\n vcd_handle_err_in_starting:");
+	if (VCD_FAILED_FATAL(status)) {
+		vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START, status);
+	} else {
+		cctxt->status.last_err = status;
+		VCD_MSG_HIGH("\n VCD cleanup: Enqueuing stop cmd");
+		vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP);
+	}
+}
+
+void vcd_handle_trans_pending(struct vcd_clnt_ctxt *cctxt)
+{
+	if (!cctxt->status.frame_submitted) {
+		VCD_MSG_ERROR("Transaction pending response was not expected");
+		return;
+	}
+	cctxt->status.frame_submitted--;
+	cctxt->status.frame_delayed++;
+	vcd_mark_frame_channel(cctxt->dev_ctxt);
+}
+void vcd_handle_submit_frame_failed(struct vcd_dev_ctxt
+	*dev_ctxt, struct vcd_transc *transc)
+{
+	struct vcd_clnt_ctxt *cctxt = transc->cctxt;
+	u32 rc;
+
+	vcd_mark_frame_channel(dev_ctxt);
+	vcd_release_trans_tbl_entry(transc);
+
+	vcd_handle_err_fatal(cctxt, VCD_EVT_IND_HWERRFATAL,
+		VCD_ERR_CLIENT_FATAL);
+
+	if (vcd_get_command_channel(dev_ctxt, &transc)) {
+		transc->type = VCD_CMD_CODEC_STOP;
+		transc->cctxt = cctxt;
+		rc = vcd_submit_cmd_sess_end(transc);
+		if (VCD_FAILED(rc))	{
+			vcd_release_command_channel(dev_ctxt, transc);
+			VCD_MSG_ERROR("rc = 0x%x. Failed: VCD_SubmitCmdSessEnd",
+				rc);
+		}
+	}
+}
+
+u32 vcd_check_if_buffer_req_met(struct vcd_clnt_ctxt *cctxt,
+	enum vcd_buffer_type buffer)
+{
+	struct vcd_property_hdr prop_hdr;
+	struct vcd_buffer_pool *buf_pool;
+	struct vcd_buffer_requirement buf_req;
+	u32 rc;
+	u8 i;
+
+	if (buffer == VCD_BUFFER_INPUT) {
+		prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ;
+		buf_pool = &cctxt->in_buf_pool;
+	} else {
+		prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ;
+		buf_pool = &cctxt->out_buf_pool;
+	}
+
+	prop_hdr.sz = sizeof(buf_req);
+	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &buf_req);
+	VCD_FAILED_RETURN(rc, "Failed: ddl_GetProperty");
+
+	buf_pool->buf_req = buf_req;
+	if (buf_pool->count < buf_req.actual_count) {
+		VCD_MSG_ERROR("Buf requirement count not met");
+		return VCD_ERR_FAIL;
+	}
+
+	if (buf_pool->count > buf_req.actual_count)
+		buf_pool->count = buf_req.actual_count;
+
+	if (!buf_pool->entries ||
+	buf_pool->validated != buf_pool->count) {
+		VCD_MSG_ERROR("Buffer pool is not completely setup yet");
+		return VCD_ERR_BAD_STATE;
+	}
+	for (i = 1; (rc == VCD_S_SUCCESS && i <= buf_pool->count); i++) {
+		if (buf_pool->entries[i].sz <
+			buf_pool->buf_req.sz) {
+			VCD_MSG_ERROR(
+				"BufReq sz not met:\
+					addr=(0x%p) sz=%d ReqSize=%d",
+				buf_pool->entries[i].virtual,
+				buf_pool->entries[i].sz,
+				buf_pool->buf_req.sz);
+			rc = VCD_ERR_FAIL;
+		}
+	}
+	return rc;
+}
+
+u32 vcd_handle_ind_output_reconfig(
+	struct vcd_clnt_ctxt *cctxt, void* payload, u32 status)
+{
+	struct ddl_frame_data_tag *frame =
+		(struct ddl_frame_data_tag *)payload;
+	struct vcd_property_hdr prop_hdr;
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_buffer_pool *out_buf_pool;
+	struct vcd_buffer_requirement buf_req;
+
+	if (frame)
+		rc = vcd_handle_output_required(cctxt, payload, status);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_handle_output_required in reconfig");
+	vcd_mark_frame_channel(cctxt->dev_ctxt);
+
+	rc = vcd_sched_suspend_resume_clnt(cctxt, false);
+	VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt");
+	out_buf_pool = &cctxt->out_buf_pool;
+	prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ;
+	prop_hdr.sz = sizeof(buf_req);
+	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &buf_req);
+	VCD_FAILED_RETURN(rc, "Failed: ddl_GetProperty");
+
+	out_buf_pool->buf_req = buf_req;
+
+	if (out_buf_pool->count < buf_req.actual_count) {
+		VCD_MSG_HIGH("Output buf requirement count increased");
+		out_buf_pool->count = buf_req.actual_count;
+	}
+
+	if (buf_req.actual_count > VCD_MAX_BUFFER_ENTRIES) {
+		VCD_MSG_ERROR("\n New act count exceeds Max count(32)");
+		return VCD_ERR_FAIL;
+	}
+
+	if (!VCD_FAILED(rc)) {
+		rc = vcd_set_frame_size(cctxt, NULL);
+		VCD_FAILED_RETURN(rc, "Failed: set_frame_size in reconfig");
+		cctxt->status.mask &= ~VCD_FIRST_OP_RCVD;
+		cctxt->status.mask |= VCD_IN_RECONFIG;
+		cctxt->callback(VCD_EVT_IND_OUTPUT_RECONFIG,
+			status, NULL, 0, cctxt,
+			cctxt->client_data);
+	}
+	return rc;
+}
+
+u32 vcd_handle_ind_output_reconfig_in_flushing(
+	struct vcd_clnt_ctxt *cctxt, void* payload, u32 status)
+{
+	u32 rc = VCD_S_SUCCESS;
+	if (cctxt->status.mask & VCD_FLUSH_INPUT && payload) {
+		(void)vcd_handle_input_done(cctxt, payload,
+		VCD_EVT_RESP_INPUT_FLUSHED, status);
+		payload = NULL;
+	}
+	rc = vcd_handle_ind_output_reconfig(cctxt, payload, status);
+	return rc;
+}
+
+u32 vcd_return_op_buffer_to_hw(struct vcd_clnt_ctxt *cctxt,
+	struct vcd_buffer_entry *buf_entry)
+{
+	u32 rc = VCD_S_SUCCESS;
+	struct vcd_frame_data *frm_entry = &buf_entry->frame;
+
+	VCD_MSG_LOW("vcd_return_op_buffer_to_hw in %d:",
+		    cctxt->clnt_state.state);
+	frm_entry->physical = buf_entry->physical;
+	frm_entry->ip_frm_tag = VCD_FRAMETAG_INVALID;
+	frm_entry->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID;
+	frm_entry->data_len = 0;
+
+	if (cctxt->decoding) {
+		struct vcd_property_hdr Prop_hdr;
+		struct ddl_frame_data_tag ddl_frm;
+		Prop_hdr.prop_id = DDL_I_DPB_RELEASE;
+		Prop_hdr.sz =
+			sizeof(struct ddl_frame_data_tag);
+		memset(&ddl_frm, 0, sizeof(ddl_frm));
+		ddl_frm.vcd_frm = *frm_entry;
+		rc = ddl_set_property(cctxt->ddl_handle, &Prop_hdr,
+				      &ddl_frm);
+		if (VCD_FAILED(rc)) {
+			VCD_MSG_ERROR("Error returning output buffer to"
+					" HW. rc = 0x%x", rc);
+			buf_entry->in_use = false;
+		} else {
+			cctxt->out_buf_pool.in_use++;
+			buf_entry->in_use = true;
+		}
+	}
+	return rc;
+}
+
+void vcd_handle_clnt_fatal(struct vcd_clnt_ctxt *cctxt, u32 trans_end)
+{
+	if (trans_end)
+		vcd_mark_frame_channel(cctxt->dev_ctxt);
+	vcd_handle_err_fatal(cctxt,
+		VCD_EVT_IND_HWERRFATAL, VCD_ERR_CLIENT_FATAL);
+}
+
+void vcd_handle_clnt_fatal_input_done(struct vcd_clnt_ctxt *cctxt,
+	u32 trans_end)
+{
+	if (cctxt->status.frame_submitted > 0)
+		cctxt->status.frame_submitted--;
+	vcd_handle_clnt_fatal(cctxt, trans_end);
+}
+
+void vcd_handle_ind_info_output_reconfig(
+	struct vcd_clnt_ctxt *cctxt, u32 status)
+{
+	if (cctxt) {
+		cctxt->callback(VCD_EVT_IND_INFO_OUTPUT_RECONFIG, status, NULL,
+		 0, cctxt, cctxt->client_data);
+	}
+}
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.c b/drivers/video/msm/vidc/common/vcd/vcd_util.c
new file mode 100644
index 0000000..ba991f1
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_util.c
@@ -0,0 +1,106 @@
+/* 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_type.h"
+#include "vcd_util.h"
+
+u32 vcd_critical_section_create(u32 **p_cs)
+{
+	struct mutex *lock;
+	if (!p_cs) {
+		VCD_MSG_ERROR("Bad critical section ptr");
+		return VCD_ERR_BAD_POINTER;
+	} else {
+		lock = kmalloc(sizeof(struct mutex), GFP_KERNEL);
+		if (!lock) {
+			VCD_MSG_ERROR("Failed: vcd_critical_section_create");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+		mutex_init(lock);
+		*p_cs = (u32 *) lock;
+		return VCD_S_SUCCESS;
+	}
+}
+
+u32 vcd_critical_section_release(u32 *cs)
+{
+	struct mutex *lock = (struct mutex *)cs;
+	if (!lock) {
+		VCD_MSG_ERROR("Bad critical section object");
+		return VCD_ERR_BAD_POINTER;
+	}
+
+	mutex_destroy(lock);
+	kfree(cs);
+	return VCD_S_SUCCESS;
+}
+
+u32 vcd_critical_section_enter(u32 *cs)
+{
+	struct mutex *lock = (struct mutex *)cs;
+	if (!lock) {
+		VCD_MSG_ERROR("Bad critical section object");
+		return VCD_ERR_BAD_POINTER;
+	} else
+		mutex_lock(lock);
+
+	return VCD_S_SUCCESS;
+}
+
+u32 vcd_critical_section_leave(u32 *cs)
+{
+	struct mutex *lock = (struct mutex *)cs;
+
+	if (!lock) {
+		VCD_MSG_ERROR("Bad critical section object");
+
+		return VCD_ERR_BAD_POINTER;
+	} else
+		mutex_unlock(lock);
+
+	return VCD_S_SUCCESS;
+}
+
+int vcd_pmem_alloc(u32 size, u8 **kernel_vaddr, u8 **phy_addr)
+{
+	*phy_addr =
+	    (u8 *) pmem_kalloc(size, PMEM_MEMTYPE | PMEM_ALIGNMENT_4K);
+
+	if (!IS_ERR((void *)*phy_addr)) {
+
+		*kernel_vaddr = ioremap((unsigned long)*phy_addr, size);
+
+		if (!*kernel_vaddr) {
+			pr_err("%s: could not ioremap in kernel pmem buffers\n",
+			       __func__);
+			pmem_kfree((s32) *phy_addr);
+			return -ENOMEM;
+		}
+		pr_debug("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
+			 (u32) *phy_addr, (u32) *kernel_vaddr);
+		return 0;
+	} else {
+		pr_err("%s: could not allocte in kernel pmem buffers\n",
+		       __func__);
+		return -ENOMEM;
+	}
+
+}
+
+int vcd_pmem_free(u8 *kernel_vaddr, u8 *phy_addr)
+{
+	iounmap((void *)kernel_vaddr);
+	pmem_kfree((s32) phy_addr);
+
+	return 0;
+}
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.h b/drivers/video/msm/vidc/common/vcd/vcd_util.h
new file mode 100644
index 0000000..07ad651
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vcd_util.h
@@ -0,0 +1,52 @@
+/* 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_UTIL_H_
+#define _VCD_UTIL_H_
+#include "vidc_type.h"
+#include "vcd_api.h"
+
+#if DEBUG
+
+#define VCD_MSG_LOW(xx_fmt...)		printk(KERN_INFO "\n\t* " xx_fmt)
+#define VCD_MSG_MED(xx_fmt...)		printk(KERN_INFO "\n  * " xx_fmt)
+#define VCD_MSG_HIGH(xx_fmt...)		printk(KERN_WARNING "\n" xx_fmt)
+
+#else
+
+#define VCD_MSG_LOW(xx_fmt...)
+#define VCD_MSG_MED(xx_fmt...)
+#define VCD_MSG_HIGH(xx_fmt...)
+
+#endif
+
+#define VCD_MSG_ERROR(xx_fmt...)	printk(KERN_ERR "\n err: " xx_fmt)
+#define VCD_MSG_FATAL(xx_fmt...)	printk(KERN_ERR "\n<FATAL> " xx_fmt)
+
+#define VCD_FAILED_RETURN(rc, xx_fmt...)		\
+	do {						\
+		if (VCD_FAILED(rc)) {			\
+			printk(KERN_ERR  xx_fmt);	\
+			return rc;			\
+		}					\
+	} while	(0)
+
+#define VCD_FAILED_DEVICE_FATAL(rc) \
+	(rc == VCD_ERR_HW_FATAL ? true : false)
+#define VCD_FAILED_CLIENT_FATAL(rc) \
+	(rc == VCD_ERR_CLIENT_FATAL ? true : false)
+
+#define VCD_FAILED_FATAL(rc)  \
+	((VCD_FAILED_DEVICE_FATAL(rc) || VCD_FAILED_CLIENT_FATAL(rc)) \
+	? true : false)
+
+#endif
diff --git a/drivers/video/msm/vidc/common/vcd/vidc_type.h b/drivers/video/msm/vidc/common/vcd/vidc_type.h
new file mode 100644
index 0000000..bd87c0d
--- /dev/null
+++ b/drivers/video/msm/vidc/common/vcd/vidc_type.h
@@ -0,0 +1,30 @@
+/* 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 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