Merge "hqd: Use MSM_VIDC_TARGET_LIST for Venus color format"
diff --git a/Android.mk b/Android.mk
index 772b66e..d8b168d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,5 +1,5 @@
 display-hals := libgralloc libgenlock libcopybit liblight
-display-hals += libhwcomposer liboverlay libqdutils libexternal libqservice
+display-hals += libhwcomposer liboverlay libqdutils libhdmi libqservice
 display-hals += libmemtrack
 ifeq ($(call is-vendor-board-platform,QCOM),true)
     include $(call all-named-subdir-makefiles,$(display-hals))
diff --git a/common.mk b/common.mk
index 18b5d4a..5a7e81f 100644
--- a/common.mk
+++ b/common.mk
@@ -4,7 +4,7 @@
 common_includes += $(LOCAL_PATH)/../libcopybit
 common_includes += $(LOCAL_PATH)/../libqdutils
 common_includes += $(LOCAL_PATH)/../libhwcomposer
-common_includes += $(LOCAL_PATH)/../libexternal
+common_includes += $(LOCAL_PATH)/../libhdmi
 common_includes += $(LOCAL_PATH)/../libqservice
 
 ifeq ($(TARGET_USES_POST_PROCESSING),true)
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 84d7620..2302d64 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -37,6 +37,7 @@
 
 #include "gralloc_priv.h"
 #include "software_converter.h"
+#include <qdMetaData.h>
 
 #define DEBUG_MDP_ERRORS 1
 
@@ -504,6 +505,13 @@
                 flags |=  MDP_BLIT_NON_CACHED;
             }
 
+            // Set Color Space for MDP to configure CSC matrix
+            req->color_space = ITU_R_601;
+            MetaData_t *metadata = (MetaData_t *)src_hnd->base_metadata;
+            if (metadata && (metadata->operation & UPDATE_COLOR_SPACE)) {
+                req->color_space = metadata->colorSpace;
+            }
+
             set_infos(ctx, req, flags);
             set_image(&req->dst, dst);
             set_image(&req->src, src);
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 5ba737a..943e64f 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -63,12 +63,15 @@
         return -EINVAL;
 
     private_handle_t* hnd = (private_handle_t*)handle;
+    unsigned int size = 0;
+    int err = 0;
+    IMemAlloc* memalloc = getAllocator(hnd->flags) ;
     void *mappedAddress;
+    // Dont map FRAMEBUFFER and SECURE_BUFFERS
     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
         !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
-        unsigned int size = hnd->size;
-        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
-        int err = memalloc->map_buffer(&mappedAddress, size,
+        size = hnd->size;
+        err = memalloc->map_buffer(&mappedAddress, size,
                                        hnd->offset, hnd->fd);
         if(err || mappedAddress == MAP_FAILED) {
             ALOGE("Could not mmap handle %p, fd=%d (%s)",
@@ -78,6 +81,10 @@
         }
 
         hnd->base = uint64_t(mappedAddress) + hnd->offset;
+    }
+
+    //Allow mapping of metadata for all buffers and SECURE_BUFFER
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
         mappedAddress = MAP_FAILED;
         size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
         err = memalloc->map_buffer(&mappedAddress, size,
diff --git a/libexternal/Android.mk b/libhdmi/Android.mk
similarity index 67%
rename from libexternal/Android.mk
rename to libhdmi/Android.mk
index 05e42d4..89ba4a9 100644
--- a/libexternal/Android.mk
+++ b/libhdmi/Android.mk
@@ -2,12 +2,12 @@
 include $(LOCAL_PATH)/../common.mk
 include $(CLEAR_VARS)
 
-LOCAL_MODULE                  := libexternal
+LOCAL_MODULE                  := libhdmi
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
 LOCAL_SHARED_LIBRARIES        := $(common_libs) liboverlay libqdutils
-LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdexternal\"
+LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdhdmi\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES               := external.cpp
+LOCAL_SRC_FILES               := hdmi.cpp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libexternal/external.cpp b/libhdmi/hdmi.cpp
similarity index 87%
rename from libexternal/external.cpp
rename to libhdmi/hdmi.cpp
index 28cf590..4fb7cfa 100644
--- a/libexternal/external.cpp
+++ b/libhdmi/hdmi.cpp
@@ -26,7 +26,7 @@
 #include <sys/ioctl.h>
 #include <cutils/properties.h>
 #include "hwc_utils.h"
-#include "external.h"
+#include "hdmi.h"
 #include "overlayUtils.h"
 #include "overlay.h"
 #include "qd_utils.h"
@@ -64,26 +64,37 @@
     EDIDData(HDMI_VFRMT_720x480p60_16_9, 720, 480, 60, 8),
     EDIDData(HDMI_VFRMT_720x576p50_4_3, 720, 576, 50, 9),
     EDIDData(HDMI_VFRMT_720x576p50_16_9, 720, 576, 50, 10),
-    EDIDData(HDMI_VFRMT_1024x768p60_4_3, 1024, 768, 60, 11),
-    EDIDData(HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, 60, 12),
-    EDIDData(HDMI_VFRMT_1280x720p50_16_9, 1280, 720, 50, 13),
-    EDIDData(HDMI_VFRMT_1280x720p60_16_9, 1280, 720, 60, 14),
-    EDIDData(HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, 24, 15),
-    EDIDData(HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, 25, 16),
-    EDIDData(HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, 30, 17),
-    EDIDData(HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, 50, 18),
-    EDIDData(HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, 60, 19),
-    EDIDData(HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, 60, 20),
-    EDIDData(HDMI_VFRMT_3840x2160p24_16_9, 3840, 2160, 24, 21),
-    EDIDData(HDMI_VFRMT_3840x2160p25_16_9, 3840, 2160, 25, 22),
-    EDIDData(HDMI_VFRMT_3840x2160p30_16_9, 3840, 2160, 30, 23),
-    EDIDData(HDMI_VFRMT_4096x2160p24_16_9, 4096, 2160, 24, 24),
+    EDIDData(HDMI_VFRMT_800x600p60_4_3, 800, 600, 60, 11),
+    EDIDData(HDMI_VFRMT_848x480p60_16_9, 848, 480, 60, 12),
+    EDIDData(HDMI_VFRMT_1024x768p60_4_3, 1024, 768, 60, 13),
+    EDIDData(HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, 60, 14),
+    EDIDData(HDMI_VFRMT_1280x720p50_16_9, 1280, 720, 50, 15),
+    EDIDData(HDMI_VFRMT_1280x720p60_16_9, 1280, 720, 60, 16),
+    EDIDData(HDMI_VFRMT_1280x800p60_16_10, 1280, 800, 60, 17),
+    EDIDData(HDMI_VFRMT_1280x960p60_4_3, 1280, 960, 60, 18),
+    EDIDData(HDMI_VFRMT_1360x768p60_16_9, 1360, 768, 60, 19),
+    EDIDData(HDMI_VFRMT_1366x768p60_16_10, 1366, 768, 60, 20),
+    EDIDData(HDMI_VFRMT_1440x900p60_16_10, 1440, 900, 60, 21),
+    EDIDData(HDMI_VFRMT_1400x1050p60_4_3, 1400, 1050, 60, 22),
+    EDIDData(HDMI_VFRMT_1680x1050p60_16_10, 1680, 1050, 60, 23),
+    EDIDData(HDMI_VFRMT_1600x1200p60_4_3, 1600, 1200, 60, 24),
+    EDIDData(HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, 24, 25),
+    EDIDData(HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, 25, 26),
+    EDIDData(HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, 30, 27),
+    EDIDData(HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, 50, 28),
+    EDIDData(HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, 60, 29),
+    EDIDData(HDMI_VFRMT_1920x1200p60_16_10, 1920, 1200, 60, 30),
+    EDIDData(HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, 60, 31),
+    EDIDData(HDMI_VFRMT_3840x2160p24_16_9, 3840, 2160, 24, 32),
+    EDIDData(HDMI_VFRMT_3840x2160p25_16_9, 3840, 2160, 25, 33),
+    EDIDData(HDMI_VFRMT_3840x2160p30_16_9, 3840, 2160, 30, 34),
+    EDIDData(HDMI_VFRMT_4096x2160p24_16_9, 4096, 2160, 24, 35),
 };
 
 // Number of modes in gEDIDData
 const int gEDIDCount = (sizeof(gEDIDData)/sizeof(gEDIDData)[0]);
 
-int ExternalDisplay::configure() {
+int HDMIDisplay::configure() {
     if(!openFrameBuffer()) {
         ALOGE("%s: Failed to open FB: %d", __FUNCTION__, mFbNum);
         return -1;
@@ -113,12 +124,12 @@
     return 0;
 }
 
-void ExternalDisplay::getAttributes(uint32_t& width, uint32_t& height) {
+void HDMIDisplay::getAttributes(uint32_t& width, uint32_t& height) {
     uint32_t fps = 0;
     getAttrForMode(width, height, fps);
 }
 
-int ExternalDisplay::teardown() {
+int HDMIDisplay::teardown() {
     closeFrameBuffer();
     resetInfo();
     // unset system property
@@ -126,7 +137,7 @@
     return 0;
 }
 
-ExternalDisplay::ExternalDisplay():mFd(-1),
+HDMIDisplay::HDMIDisplay():mFd(-1),
     mCurrentMode(-1), mModeCount(0), mPrimaryWidth(0), mPrimaryHeight(0),
     mUnderscanSupported(false)
 {
@@ -166,7 +177,7 @@
  * to the sysfs node, so that the driver can get that information
  * Used to show QCOM 8974 instead of Input 1 for example
  */
-void ExternalDisplay::setSPDInfo(const char* node, const char* property) {
+void HDMIDisplay::setSPDInfo(const char* node, const char* property) {
     char info[PROPERTY_VALUE_MAX];
     ssize_t err = -1;
     int spdFile = openDeviceNode(node, O_RDWR);
@@ -189,12 +200,12 @@
     }
 }
 
-void ExternalDisplay::setHPD(uint32_t value) {
+void HDMIDisplay::setHPD(uint32_t value) {
     ALOGD_IF(DEBUG,"HPD enabled=%d", value);
     writeHPDOption(value);
 }
 
-void ExternalDisplay::setActionSafeDimension(int w, int h) {
+void HDMIDisplay::setActionSafeDimension(int w, int h) {
     ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
     char actionsafeWidth[PROPERTY_VALUE_MAX];
     char actionsafeHeight[PROPERTY_VALUE_MAX];
@@ -204,12 +215,12 @@
     property_set("persist.sys.actionsafe.height", actionsafeHeight);
 }
 
-int ExternalDisplay::getModeCount() const {
+int HDMIDisplay::getModeCount() const {
     ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount);
     return mModeCount;
 }
 
-void ExternalDisplay::readCEUnderscanInfo()
+void HDMIDisplay::readCEUnderscanInfo()
 {
     int hdmiScanInfoFile = -1;
     ssize_t len = -1;
@@ -258,8 +269,8 @@
 
     if (ce_info_str) {
         // ce_info contains the underscan information
-        if (ce_info == EXT_SCAN_ALWAYS_UNDERSCANED ||
-            ce_info == EXT_SCAN_BOTH_SUPPORTED)
+        if (ce_info == HDMI_SCAN_ALWAYS_UNDERSCANED ||
+            ce_info == HDMI_SCAN_BOTH_SUPPORTED)
             // if TV supported underscan, then driver will always underscan
             // hence no need to apply action safe rectangle
             mUnderscanSupported = true;
@@ -273,7 +284,7 @@
     return;
 }
 
-ExternalDisplay::~ExternalDisplay()
+HDMIDisplay::~HDMIDisplay()
 {
     delete [] supported_video_mode_lut;
     closeFrameBuffer();
@@ -309,7 +320,7 @@
     info.upper_margin = mode->back_porch_v;
 }
 
-int ExternalDisplay::parseResolution(char* edidStr)
+int HDMIDisplay::parseResolution(char* edidStr)
 {
     char delim = ',';
     int count = 0;
@@ -330,7 +341,7 @@
     return count;
 }
 
-bool ExternalDisplay::readResolution()
+bool HDMIDisplay::readResolution()
 {
     ssize_t len = -1;
     char edidStr[128] = {'\0'};
@@ -364,7 +375,7 @@
     return (len > 0);
 }
 
-bool ExternalDisplay::openFrameBuffer()
+bool HDMIDisplay::openFrameBuffer()
 {
     if (mFd == -1) {
         char strDevPath[MAX_SYSFS_FILE_PATH];
@@ -376,7 +387,7 @@
     return (mFd > 0);
 }
 
-bool ExternalDisplay::closeFrameBuffer()
+bool HDMIDisplay::closeFrameBuffer()
 {
     int ret = 0;
     if(mFd >= 0) {
@@ -387,7 +398,7 @@
 }
 
 // clears the vinfo, edid, best modes
-void ExternalDisplay::resetInfo()
+void HDMIDisplay::resetInfo()
 {
     memset(&mVInfo, 0, sizeof(mVInfo));
     memset(mEDIDModes, 0, sizeof(mEDIDModes));
@@ -403,7 +414,7 @@
     property_set("hw.underscan_supported", prop);
 }
 
-int ExternalDisplay::getModeOrder(int mode)
+int HDMIDisplay::getModeOrder(int mode)
 {
     for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
         if (gEDIDData[dataIndex].mMode == mode) {
@@ -415,7 +426,7 @@
 }
 
 /// Returns the user mode set(if any) using adb shell
-int ExternalDisplay::getUserMode() {
+int HDMIDisplay::getUserMode() {
     /* Based on the property set the resolution */
     char property_value[PROPERTY_VALUE_MAX];
     property_get("hw.hdmi.resolution", property_value, "-1");
@@ -429,7 +440,7 @@
 }
 
 // Get the best mode for the current HD TV
-int ExternalDisplay::getBestMode() {
+int HDMIDisplay::getBestMode() {
     int bestOrder = 0;
     int bestMode = HDMI_VFRMT_640x480p60_4_3;
     // for all the edid read, get the best mode
@@ -444,7 +455,7 @@
     return bestMode;
 }
 
-inline bool ExternalDisplay::isValidMode(int ID)
+inline bool HDMIDisplay::isValidMode(int ID)
 {
     bool valid = false;
     for (int i = 0; i < mModeCount; i++) {
@@ -457,7 +468,7 @@
 }
 
 // returns true if the mode(ID) is interlaced mode format
-bool ExternalDisplay::isInterlacedMode(int ID) {
+bool HDMIDisplay::isInterlacedMode(int ID) {
     bool interlaced = false;
     switch(ID) {
         case HDMI_VFRMT_1440x480i60_4_3:
@@ -476,7 +487,7 @@
 
 // Does a put_vscreen info on the HDMI interface which will update
 // the configuration (resolution, timing info) to match mCurrentMode
-void ExternalDisplay::activateDisplay()
+void HDMIDisplay::activateDisplay()
 {
     int ret = 0;
     ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
@@ -526,7 +537,7 @@
     }
 }
 
-bool ExternalDisplay::writeHPDOption(int userOption) const
+bool HDMIDisplay::writeHPDOption(int userOption) const
 {
     bool ret = true;
     if(mFbNum != -1) {
@@ -550,7 +561,7 @@
 }
 
 
-void ExternalDisplay::setAttributes() {
+void HDMIDisplay::setAttributes() {
     uint32_t fps = 0;
     // Always set dpyAttr res to mVInfo res
     getAttrForMode(mXres, mYres, fps);
@@ -619,7 +630,7 @@
     ALOGD_IF(DEBUG, "%s xres=%d, yres=%d", __FUNCTION__, mXres, mYres);
 }
 
-void ExternalDisplay::getAttrForMode(uint32_t& width, uint32_t& height,
+void HDMIDisplay::getAttrForMode(uint32_t& width, uint32_t& height,
         uint32_t& fps) {
     for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
         if (gEDIDData[dataIndex].mMode == mCurrentMode) {
@@ -633,7 +644,7 @@
 }
 
 /* returns the fd related to the node specified*/
-int ExternalDisplay::openDeviceNode(const char* node, int fileMode) const {
+int HDMIDisplay::openDeviceNode(const char* node, int fileMode) const {
     char sysFsFilePath[MAX_SYSFS_FILE_PATH];
     memset(sysFsFilePath, 0, sizeof(sysFsFilePath));
     snprintf(sysFsFilePath , sizeof(sysFsFilePath),
@@ -649,12 +660,12 @@
     return fd;
 }
 
-bool ExternalDisplay::isHDMIPrimaryDisplay() {
+bool HDMIDisplay::isHDMIPrimaryDisplay() {
     int hdmiNode = qdutils::getHDMINode();
     return (hdmiNode == HWC_DISPLAY_PRIMARY);
 }
 
-int ExternalDisplay::getConnectedState() {
+int HDMIDisplay::getConnectedState() {
     int ret = -1;
     int mFbNum = qdutils::getHDMINode();
     int connectedNode = openDeviceNode("connected", O_RDONLY);
@@ -679,7 +690,7 @@
     return ret;
 }
 
-void ExternalDisplay::setPrimaryAttributes(uint32_t primaryWidth,
+void HDMIDisplay::setPrimaryAttributes(uint32_t primaryWidth,
         uint32_t primaryHeight) {
     mPrimaryHeight = primaryHeight;
     mPrimaryWidth = primaryWidth;
diff --git a/libexternal/external.h b/libhdmi/hdmi.h
similarity index 90%
rename from libexternal/external.h
rename to libhdmi/hdmi.h
index fa98de9..605d9be 100644
--- a/libexternal/external.h
+++ b/libhdmi/hdmi.h
@@ -18,8 +18,8 @@
  * limitations under the License.
  */
 
-#ifndef HWC_EXTERNAL_DISPLAY_H
-#define HWC_EXTERNAL_DISPLAY_H
+#ifndef HWC_HDMI_DISPLAY_H
+#define HWC_HDMI_DISPLAY_H
 
 #include <linux/fb.h>
 
@@ -28,11 +28,11 @@
 namespace qhwc {
 
 //Type of scanning of EDID(Video Capability Data Block)
-enum external_scansupport_type {
-    EXT_SCAN_NOT_SUPPORTED      = 0,
-    EXT_SCAN_ALWAYS_OVERSCANED  = 1,
-    EXT_SCAN_ALWAYS_UNDERSCANED = 2,
-    EXT_SCAN_BOTH_SUPPORTED     = 3
+enum hdmi_scansupport_type {
+    HDMI_SCAN_NOT_SUPPORTED      = 0,
+    HDMI_SCAN_ALWAYS_OVERSCANED  = 1,
+    HDMI_SCAN_ALWAYS_UNDERSCANED = 2,
+    HDMI_SCAN_BOTH_SUPPORTED     = 3
 };
 
 // Structure to store EDID related data
@@ -45,11 +45,11 @@
     { }
 };
 
-class ExternalDisplay
+class HDMIDisplay
 {
 public:
-    ExternalDisplay();
-    ~ExternalDisplay();
+    HDMIDisplay();
+    ~HDMIDisplay();
     void setHPD(uint32_t startEnd);
     void setActionSafeDimension(int w, int h);
     bool isCEUnderscanSupported() { return mUnderscanSupported; }
@@ -107,4 +107,4 @@
 
 }; //qhwc
 // ---------------------------------------------------------------------------
-#endif //HWC_EXTERNAL_DISPLAY_H
+#endif //HWC_HDMI_DISPLAY_H
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 8e3fc8e..df3e464 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -9,7 +9,7 @@
                                  $(TOP)/external/skia/include/core \
                                  $(TOP)/external/skia/include/images
 LOCAL_SHARED_LIBRARIES        := $(common_libs) libEGL liboverlay \
-                                 libexternal libqdutils libhardware_legacy \
+                                 libhdmi libqdutils libhardware_legacy \
                                  libdl libmemalloc libqservice libsync \
                                  libbinder libmedia
 
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index ae1389d..288b2e0 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -34,7 +34,7 @@
 #include "hwc_fbupdate.h"
 #include "hwc_mdpcomp.h"
 #include "hwc_dump_layers.h"
-#include "external.h"
+#include "hdmi.h"
 #include "hwc_copybit.h"
 #include "hwc_ad.h"
 #include "profiler.h"
@@ -442,7 +442,7 @@
         if(mode == HWC_POWER_MODE_NORMAL) {
             // Enable HPD here, as during bootup POWER_MODE_NORMAL is set
             // when SF is completely initialized
-            ctx->mExtDisplay->setHPD(1);
+            ctx->mHDMIDisplay->setHPD(1);
         }
 
         ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
diff --git a/libhwcomposer/hwc_ad.cpp b/libhwcomposer/hwc_ad.cpp
index 679e6d6..7e96d97 100644
--- a/libhwcomposer/hwc_ad.cpp
+++ b/libhwcomposer/hwc_ad.cpp
@@ -34,7 +34,6 @@
 #include <mdp_version.h>
 #include "hwc_ad.h"
 #include "hwc_utils.h"
-#include "external.h"
 
 #define DEBUG 0
 using namespace overlay;
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 8164fd3..67cca88 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -96,7 +96,7 @@
         int fbWidth =  ctx->dpyAttr[dpy].xres;
         int fbHeight =  ctx->dpyAttr[dpy].yres;
         unsigned int fbArea = (fbWidth * fbHeight);
-        unsigned int renderArea = getRGBRenderingArea(list);
+        unsigned int renderArea = getRGBRenderingArea(ctx, list);
             ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
                                   __FUNCTION__, renderArea, fbArea);
         if (renderArea < (mDynThreshold * fbArea)) {
@@ -112,8 +112,8 @@
     return false;
 }
 
-unsigned int CopyBit::getRGBRenderingArea
-                                    (const hwc_display_contents_1_t *list) {
+unsigned int CopyBit::getRGBRenderingArea (const hwc_context_t *ctx,
+                                     const hwc_display_contents_1_t *list) {
     //Calculates total rendering area for RGB layers
     unsigned int renderArea = 0;
     unsigned int w=0, h=0;
@@ -122,7 +122,7 @@
     for (unsigned int i=0; i<list->numHwLayers -1; i++) {
          private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
          if (hnd) {
-             if (BUFFER_TYPE_UI == hnd->bufferType) {
+             if (BUFFER_TYPE_UI == hnd->bufferType && !ctx->copybitDrop[i]) {
                  getLayerResolution(&list->hwLayers[i], w, h);
                  renderArea += (w*h);
              }
@@ -316,6 +316,9 @@
         for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
             int dst_h, dst_w, src_h, src_w;
             float dx, dy;
+            if(ctx->copybitDrop[i]) {
+                continue;
+            }
             hwc_layer_1_t *layer = (hwc_layer_1_t *) &list->hwLayers[i];
             if (layer->planeAlpha != 0xFF)
                 return true;
@@ -349,7 +352,8 @@
     }
 
     //Allocate render buffers if they're not allocated
-    if (ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
+    if ((ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
+        ctx->mMDP.version != qdutils::MDP_V3_0_5) &&
             (useCopybitForYUV || useCopybitForRGB)) {
         int ret = allocRenderBuffers(mAlignedWidth,
                                      mAlignedHeight,
@@ -375,7 +379,8 @@
         for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
             layerProp[i].mFlags |= HWC_COPYBIT;
 #ifdef QCOM_BSP
-            if (ctx->mMDP.version == qdutils::MDP_V3_0_4)
+            if (ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+               ctx->mMDP.version == qdutils::MDP_V3_0_5)
                 list->hwLayers[i].compositionType = HWC_BLIT;
             else
 #endif
@@ -496,7 +501,8 @@
        return true;
     }
     //render buffer
-    if (ctx->mMDP.version == qdutils::MDP_V3_0_4) {
+    if (ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+        ctx->mMDP.version == qdutils::MDP_V3_0_5) {
         last = (uint32_t)list->numHwLayers - 1;
         renderBuffer = (private_handle_t *)list->hwLayers[last].handle;
     } else {
@@ -541,6 +547,9 @@
             ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
             continue;
         }
+        if(ctx->copybitDrop[i]) {
+            continue;
+        }
         //skip non updating layers
         if((mDirtyLayerIndex != -1) && (mDirtyLayerIndex != i) )
             continue;
@@ -568,7 +577,8 @@
         copybit_device_t *copybit = getCopyBitDevice();
         // Async mode
         copybit->flush_get_fence(copybit, fd);
-        if(ctx->mMDP.version == qdutils::MDP_V3_0_4 &&
+        if((ctx->mMDP.version == qdutils::MDP_V3_0_4 ||
+           ctx->mMDP.version == qdutils::MDP_V3_0_5) &&
                 list->hwLayers[last].acquireFenceFd >= 0) {
             close(list->hwLayers[last].acquireFenceFd);
             list->hwLayers[last].acquireFenceFd = -1;
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 99a39c8..a7ce43e 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -101,8 +101,8 @@
     // flag that indicates whether CopyBit composition is enabled for this cycle
     bool mCopyBitDraw;
 
-    unsigned int getRGBRenderingArea
-                            (const hwc_display_contents_1_t *list);
+    unsigned int getRGBRenderingArea (const hwc_context_t *ctx,
+                                         const hwc_display_contents_1_t *list);
 
     void getLayerResolution(const hwc_layer_1_t* layer,
                                    unsigned int &width, unsigned int& height);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 7839139..43ae916 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -25,7 +25,6 @@
 #include <overlayRotator.h>
 #include "hwc_fbupdate.h"
 #include "mdp_version.h"
-#include "external.h"
 
 using namespace qdutils;
 using namespace overlay;
@@ -514,12 +513,13 @@
            based on an empirically derived value of panel height.
     */
 
-    bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
+    const bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
             qdutils::MDPVersion::getInstance().isSrcSplitAlways();
+    const uint32_t lSplit = getLeftSplit(ctx, mDpy);
+    const uint32_t cropWidth = sourceCrop.right - sourceCrop.left;
 
-    if(((sourceCrop.right - sourceCrop.left) >
-            (int)qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
-            primarySplitAlways) {
+    if((cropWidth > qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
+            (primarySplitAlways and cropWidth > lSplit)) {
         destR = ov.getPipe(pipeSpecs);
         if(destR == ovutils::OV_INVALID) {
             ALOGE("%s: No pipes available to configure fb for dpy %d's right"
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 072eda3..2904e6f 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -19,7 +19,7 @@
 #include <math.h>
 #include "hwc_mdpcomp.h"
 #include <sys/ioctl.h>
-#include "external.h"
+#include "hdmi.h"
 #include "qdMetaData.h"
 #include "mdp_version.h"
 #include "hwc_fbupdate.h"
@@ -36,7 +36,7 @@
 
 //==============MDPComp========================================================
 
-IdleInvalidator *MDPComp::idleInvalidator = NULL;
+IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
 bool MDPComp::sIdleFallBack = false;
 bool MDPComp::sHandleTimeout = false;
 bool MDPComp::sDebugLogs = false;
@@ -46,6 +46,7 @@
 int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
 bool MDPComp::sEnableYUVsplit = false;
 bool MDPComp::sSrcSplitEnabled = false;
+bool MDPComp::enablePartialUpdateForMDP3 = false;
 MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
     if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
         sSrcSplitEnabled = true;
@@ -110,7 +111,7 @@
         return false;
     }
 
-    char property[PROPERTY_VALUE_MAX];
+    char property[PROPERTY_VALUE_MAX] = {0};
 
     sEnabled = false;
     if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
@@ -134,23 +135,10 @@
     }
 
     if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
-        // Idle invalidation is not necessary on command mode panels
-        long idle_timeout = DEFAULT_IDLE_TIME;
-        if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
-            if(atoi(property) != 0)
-                idle_timeout = atoi(property);
-        }
-
-        //create Idle Invalidator only when not disabled through property
-        if(idle_timeout != -1)
-            idleInvalidator = IdleInvalidator::getInstance();
-
-        if(idleInvalidator == NULL) {
-            ALOGE("%s: failed to instantiate idleInvalidator object",
-                  __FUNCTION__);
-        } else {
-            idleInvalidator->init(timeout_handler, ctx,
-                                  (unsigned int)idle_timeout);
+        sIdleInvalidator = IdleInvalidator::getInstance();
+        if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
+            delete sIdleInvalidator;
+            sIdleInvalidator = NULL;
         }
     }
 
@@ -162,13 +150,32 @@
         sEnableYUVsplit = true;
     }
 
-    if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
-            ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
-             (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
+    bool defaultPTOR = false;
+    //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
+    //8x16 and 8x39 targets by default
+    if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
+            (qdutils::MDPVersion::getInstance().is8x16() ||
+                qdutils::MDPVersion::getInstance().is8x39())) {
+        defaultPTOR = true;
+    }
+
+    if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
+                (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
         ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
                                                     HWC_DISPLAY_PRIMARY);
     }
 
+    if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
+          (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
+       enablePartialUpdateForMDP3 = true;
+    }
+
+    if(!enablePartialUpdateForMDP3 &&
+          (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+           (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+       enablePartialUpdateForMDP3 = true;
+    }
+
     return true;
 }
 
@@ -206,6 +213,25 @@
     ctx->proc->invalidate(ctx->proc);
 }
 
+void MDPComp::setIdleTimeout(const uint32_t& timeout) {
+    enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
+
+    if(sIdleInvalidator) {
+        if(timeout <= ONE_REFRESH_PERIOD_MS) {
+            //If the specified timeout is < 1 draw cycle worth, "virtually"
+            //disable idle timeout. The ideal way for clients to disable
+            //timeout is to set it to 0
+            sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
+            ALOGI("Disabled idle timeout");
+            return;
+        }
+        sIdleInvalidator->setIdleTimeout(timeout);
+        ALOGI("Idle timeout set to %u", timeout);
+    } else {
+        ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
+    }
+}
+
 void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
                                    hwc_display_contents_1_t* list) {
     LayerProp *layerProp = ctx->layerProp[mDpy];
@@ -358,7 +384,7 @@
      * There also is a HW limilation in MDP, minimum block size is 2x2
      * Fallback to GPU if height is less than 2.
      */
-    if((crop_w < 5)||(crop_h < 5))
+    if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
         return false;
 
     if((w_scale > 1.0f) || (h_scale > 1.0f)) {
@@ -684,9 +710,18 @@
     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
     int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
 
-    // No Idle fall back, if secure display or secure RGB layers are present
+    // Fall back to video only composition, if AIV video mode is enabled
+    if(ctx->listStats[mDpy].mAIVVideoMode) {
+        ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
+            __FUNCTION__, mDpy);
+        return false;
+    }
+
+    // No Idle fall back, if secure display or secure RGB layers are present or
+    // if there's only a single layer being composed
     if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
-                    !ctx->listStats[mDpy].secureRGBCount)) {
+                    !ctx->listStats[mDpy].secureRGBCount) &&
+                    (ctx->listStats[mDpy].numAppLayers != 1)) {
         ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
         return false;
     }
@@ -1274,6 +1309,13 @@
 /* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
 bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
         hwc_display_contents_1_t* list) {
+    // Fall back to video only composition, if AIV video mode is enabled
+    if(ctx->listStats[mDpy].mAIVVideoMode) {
+        ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
+            __FUNCTION__, mDpy);
+        return false;
+    }
+
     const bool secureOnly = true;
     return mdpOnlyLayersComp(ctx, list, not secureOnly) or
             mdpOnlyLayersComp(ctx, list, secureOnly);
@@ -1570,6 +1612,24 @@
             __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
 }
 
+// drop other non-AIV layers from external display list.
+void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
+                              hwc_display_contents_1_t* list) {
+    for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
+        hwc_layer_1_t * layer = &list->hwLayers[i];
+         if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
+            mCurrentFrame.dropCount++;
+            mCurrentFrame.drop[i] = true;
+        }
+    }
+    mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
+    mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
+            mCurrentFrame.fbCount - mCurrentFrame.dropCount;
+    ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
+        __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
+        mCurrentFrame.dropCount);
+}
+
 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
         bool secureOnly, FrameInfo& frame) {
     int nYuvCount = ctx->listStats[mDpy].yuvCount;
@@ -1577,6 +1637,10 @@
         int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
         hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
 
+        if(mCurrentFrame.drop[nYuvIndex]) {
+            continue;
+        }
+
         if(!isYUVDoable(ctx, layer)) {
             if(!frame.isFBComposed[nYuvIndex]) {
                 frame.isFBComposed[nYuvIndex] = true;
@@ -1845,6 +1909,11 @@
     //Hard conditions, if not met, cannot do MDP comp
     if(isFrameDoable(ctx)) {
         generateROI(ctx, list);
+        // if AIV Video mode is enabled, drop all non AIV layers from the
+        // external display list.
+        if(ctx->listStats[mDpy].mAIVVideoMode) {
+            dropNonAIVLayers(ctx, list);
+        }
 
         // if tryFullFrame fails, try to push all video and secure RGB layers
         // to MDP for composition.
@@ -1862,6 +1931,13 @@
                     "MDP Composition Strategies Failed");
         }
     } else {
+        if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
+                enablePartialUpdateForMDP3) {
+            generateROI(ctx, list);
+            for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
+                ctx->copybitDrop[i] = mCurrentFrame.drop[i];
+            }
+        }
         ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
                 __FUNCTION__);
         ret = -1;
@@ -1880,6 +1956,8 @@
     if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
         FrameInfo frame;
         frame.reset(mCurrentFrame.layerCount);
+        memset(&frame.drop, 0, sizeof(frame.drop));
+        frame.dropCount = 0;
         ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
                  __FUNCTION__);
         updateLayerCache(ctx, list, frame);
@@ -2055,7 +2133,7 @@
     }
 
     // Set the Handle timeout to true for MDP or MIXED composition.
-    if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
+    if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
         sHandleTimeout = true;
     }
 
@@ -2310,7 +2388,7 @@
     }
 
     // Set the Handle timeout to true for MDP or MIXED composition.
-    if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
+    if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
         sHandleTimeout = true;
     }
 
@@ -2469,7 +2547,8 @@
             mdpHw.isSrcSplitAlways();
     int lSplit = getLeftSplit(ctx, mDpy);
     int dstWidth = dst.right - dst.left;
-    int cropWidth = crop.right - crop.left;
+    int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
+            crop.right - crop.left;
 
     //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
     //pipe line length, we are still using 2 pipes. This is fine just because
@@ -2528,6 +2607,10 @@
         else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
     }
+    // update source crop and destination position of AIV video layer.
+    if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
+        updateCoordinates(ctx, crop, dst, mDpy);
+    }
     /* Calculate the external display position based on MDP downscale,
        ActionSafe, and extorientation features. */
     calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index e43c4f4..4634fbc 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -25,7 +25,6 @@
 #include <cutils/properties.h>
 #include <overlay.h>
 
-#define DEFAULT_IDLE_TIME 70
 #define MAX_PIPES_PER_MIXER 4
 
 namespace overlay {
@@ -57,6 +56,7 @@
     static void resetIdleFallBack() { sIdleFallBack = false; }
     static bool isIdleFallback() { return sIdleFallBack; }
     static void dynamicDebug(bool enable){ sDebugLogs = enable; }
+    static void setIdleTimeout(const uint32_t& timeout);
 
 protected:
     enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
@@ -222,6 +222,9 @@
     bool intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
             int fromIndex, int toIndex, int targetLayerIndex);
 
+    /* drop other non-AIV layers from external display list.*/
+    void dropNonAIVLayers(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+
         /* updates cache map with YUV info */
     void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
             bool secureOnly, FrameInfo& frame);
@@ -255,13 +258,15 @@
     static bool sHandleTimeout;
     static int sMaxPipesPerMixer;
     static bool sSrcSplitEnabled;
-    static IdleInvalidator *idleInvalidator;
+    static IdleInvalidator *sIdleInvalidator;
     struct FrameInfo mCurrentFrame;
     struct LayerCache mCachedFrame;
     //Enable 4kx2k yuv layer split
     static bool sEnableYUVsplit;
     bool mModeOn; // if prepare happened
     bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
+    //Enable Partial Update for MDP3 targets
+    static bool enablePartialUpdateForMDP3;
 };
 
 class MDPCompNonSplit : public MDPComp {
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 8490058..6bde3d2 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -245,6 +245,13 @@
     }
 }
 
+static void setIdleTimeout(hwc_context_t* ctx, const Parcel* inParcel) {
+    uint32_t timeout = (uint32_t)inParcel->readInt32();
+    ALOGD("%s :%u ms", __FUNCTION__, timeout);
+    Locker::Autolock _sl(ctx->mDrawLock);
+    MDPComp::setIdleTimeout(timeout);
+}
+
 status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
         Parcel* outParcel) {
     status_t ret = NO_ERROR;
@@ -290,6 +297,9 @@
         case IQService::DYNAMIC_DEBUG:
             toggleDynamicDebug(mHwcContext, inParcel);
             break;
+        case IQService::SET_IDLE_TIMEOUT:
+            setIdleTimeout(mHwcContext, inParcel);
+            break;
         default:
             ret = NO_ERROR;
     }
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 821bfa9..6b2316b 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -30,7 +30,7 @@
 #include "hwc_mdpcomp.h"
 #include "hwc_copybit.h"
 #include "comptype.h"
-#include "external.h"
+#include "hdmi.h"
 #include "hwc_virtual.h"
 #include "mdp_version.h"
 using namespace overlay;
@@ -107,10 +107,11 @@
                 break;
             }
 
-            Locker::Autolock _l(ctx->mDrawLock);
+            ctx->mDrawLock.lock();
             destroyCompositionResources(ctx, dpy);
-            ctx->mExtDisplay->teardown();
+            ctx->mHDMIDisplay->teardown();
             resetDisplayInfo(ctx, dpy);
+            ctx->mDrawLock.unlock();
 
             /* We need to send hotplug to SF only when we are disconnecting
              * HDMI */
@@ -127,19 +128,19 @@
                          "for display: %d", __FUNCTION__, dpy);
                 break;
             }
-            {
-                //Force composition to give up resources like pipes and
-                //close fb. For example if assertive display is going on,
-                //fb2 could be open, thus connecting Layer Mixer#0 to
-                //WriteBack module. If HDMI attempts to open fb1, the driver
-                //will try to attach Layer Mixer#0 to HDMI INT, which will
-                //fail, since Layer Mixer#0 is still connected to WriteBack.
-                //This block will force composition to close fb2 in above
-                //example.
-                Locker::Autolock _l(ctx->mDrawLock);
-                ctx->dpyAttr[dpy].isConfiguring = true;
-                ctx->proc->invalidate(ctx->proc);
-            }
+            ctx->mDrawLock.lock();
+            //Force composition to give up resources like pipes and
+            //close fb. For example if assertive display is going on,
+            //fb2 could be open, thus connecting Layer Mixer#0 to
+            //WriteBack module. If HDMI attempts to open fb1, the driver
+            //will try to attach Layer Mixer#0 to HDMI INT, which will
+            //fail, since Layer Mixer#0 is still connected to WriteBack.
+            //This block will force composition to close fb2 in above
+            //example.
+            ctx->dpyAttr[dpy].isConfiguring = true;
+            ctx->mDrawLock.unlock();
+
+            ctx->proc->invalidate(ctx->proc);
             //2 cycles for slower content
             usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
                    * 2 / 1000);
@@ -163,15 +164,16 @@
                         "uevent thread", __FUNCTION__);
                 ctx->mWfdSyncLock.unlock();
             }
-            ctx->mExtDisplay->configure();
-            ctx->mExtDisplay->activateDisplay();
+            ctx->mHDMIDisplay->configure();
+            ctx->mHDMIDisplay->activateDisplay();
 
-            Locker::Autolock _l(ctx->mDrawLock);
+            ctx->mDrawLock.lock();
             updateDisplayInfo(ctx, dpy);
             initCompositionResources(ctx, dpy);
             ctx->dpyAttr[dpy].isPause = false;
             ctx->dpyAttr[dpy].connected = true;
             ctx->dpyAttr[dpy].isConfiguring = true;
+            ctx->mDrawLock.unlock();
 
             /* External display is HDMI */
             ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL ONLINE"
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 44725de..1f3e99a 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -37,12 +37,13 @@
 #include "mdp_version.h"
 #include "hwc_copybit.h"
 #include "hwc_dump_layers.h"
-#include "external.h"
+#include "hdmi.h"
 #include "hwc_qclient.h"
 #include "QService.h"
 #include "comptype.h"
 #include "hwc_virtual.h"
 #include "qd_utils.h"
+#include <sys/sysinfo.h>
 
 using namespace qClient;
 using namespace qService;
@@ -73,6 +74,11 @@
 #endif
 #endif
 
+#define PROP_DEFAULT_APPBUFFER  "ro.sf.default_app_buffer"
+#define MAX_RAM_SIZE  512*1024*1024
+#define qHD_WIDTH 540
+
+
 namespace qhwc {
 
 //Std refresh rates for digital videos- 24p, 30p and 48p
@@ -95,38 +101,40 @@
     char *yptr = NULL;
     if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
         yptr = strcasestr(property,"x");
-        int xres_new = atoi(property);
-        int yres_new = atoi(yptr + 1);
-        if (isValidResolution(ctx,xres_new,yres_new) &&
-                 xres_new != xres_orig && yres_new != yres_orig) {
-            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
-            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
-            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
+        if(yptr) {
+            int xres_new = atoi(property);
+            int yres_new = atoi(yptr + 1);
+            if (isValidResolution(ctx,xres_new,yres_new) &&
+                xres_new != xres_orig && yres_new != yres_orig) {
+                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
+                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
+                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
 
-            //Caluculate DPI according to changed resolution.
-            float xdpi = ((float)xres_new * 25.4f) / (float)width;
-            float ydpi = ((float)yres_new * 25.4f) / (float)height;
-            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
-            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
+                //Caluculate DPI according to changed resolution.
+                float xdpi = ((float)xres_new * 25.4f) / (float)width;
+                float ydpi = ((float)yres_new * 25.4f) / (float)height;
+                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
+                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
+            }
         }
     }
 }
 
-// Initialize external display attributes based on
-// external display class state
+// Initialize hdmi display attributes based on
+// hdmi display class state
 void updateDisplayInfo(hwc_context_t* ctx, int dpy) {
-    ctx->dpyAttr[dpy].fd = ctx->mExtDisplay->getFd();
-    ctx->dpyAttr[dpy].xres = ctx->mExtDisplay->getWidth();
-    ctx->dpyAttr[dpy].yres = ctx->mExtDisplay->getHeight();
-    ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mExtDisplay->getMDPScalingMode();
-    ctx->dpyAttr[dpy].vsync_period = ctx->mExtDisplay->getVsyncPeriod();
+    ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd();
+    ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth();
+    ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight();
+    ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mHDMIDisplay->getMDPScalingMode();
+    ctx->dpyAttr[dpy].vsync_period = ctx->mHDMIDisplay->getVsyncPeriod();
     ctx->mViewFrame[dpy].left = 0;
     ctx->mViewFrame[dpy].top = 0;
     ctx->mViewFrame[dpy].right = ctx->dpyAttr[dpy].xres;
     ctx->mViewFrame[dpy].bottom = ctx->dpyAttr[dpy].yres;
 }
 
-// Reset external display attributes and list stats structures
+// Reset hdmi display attributes and list stats structures
 void resetDisplayInfo(hwc_context_t* ctx, int dpy) {
     memset(&(ctx->dpyAttr[dpy]), 0, sizeof(ctx->dpyAttr[dpy]));
     memset(&(ctx->listStats[dpy]), 0, sizeof(ctx->listStats[dpy]));
@@ -232,6 +240,25 @@
     return 0;
 }
 
+static void changeDefaultAppBufferCount() {
+    struct sysinfo info;
+    unsigned long int ramSize = 0;
+    if (!sysinfo(&info)) {
+           ramSize = info.totalram ;
+    }
+    int fb_fd = -1;
+    struct fb_var_screeninfo sInfo ={0};
+    fb_fd = open("/dev/graphics/fb0", O_RDONLY);
+    if (fb_fd >=0) {
+        ioctl(fb_fd, FBIOGET_VSCREENINFO, &sInfo);
+        close(fb_fd);
+    }
+    if ((ramSize && ramSize < MAX_RAM_SIZE) &&
+         (sInfo.xres &&  sInfo.xres <= qHD_WIDTH )) {
+                  property_set(PROP_DEFAULT_APPBUFFER, "2");
+    }
+}
+
 void initContext(hwc_context_t *ctx)
 {
     openFramebufferDevice(ctx);
@@ -243,6 +270,10 @@
     ctx->mOverlay = overlay::Overlay::getInstance();
     ctx->mRotMgr = RotMgr::getInstance();
 
+    //default_app_buffer for ferrum
+    if (ctx->mMDP.version ==  qdutils::MDP_V3_0_5) {
+       changeDefaultAppBufferCount();
+    }
     // Initialize composition objects for the primary display
     initCompositionResources(ctx, HWC_DISPLAY_PRIMARY);
 
@@ -254,18 +285,20 @@
     // Only MDP copybit is used
     if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
             qdutils::COMPOSITION_TYPE_MDP)) &&
+            ((qdutils::MDPVersion::getInstance().getMDPVersion() ==
+            qdutils::MDP_V3_0_4) ||
             (qdutils::MDPVersion::getInstance().getMDPVersion() ==
-            qdutils::MDP_V3_0_4)) {
+            qdutils::MDP_V3_0_5))) {
         ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
                                                          HWC_DISPLAY_PRIMARY);
     }
 
-    ctx->mExtDisplay = new ExternalDisplay();
-    // Send the primary resolution to the external display class
+    ctx->mHDMIDisplay = new HDMIDisplay();
+    // Send the primary resolution to the hdmi display class
     // to be used for MDP scaling functionality
     uint32_t priW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
     uint32_t priH = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
-    ctx->mExtDisplay->setPrimaryAttributes(priW, priH);
+    ctx->mHDMIDisplay->setPrimaryAttributes(priW, priH);
     ctx->mHWCVirtual = new HWCVirtualVDS();
     ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
     ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
@@ -323,6 +356,9 @@
     ctx->deviceOrientation = 0;
     ctx->mBufferMirrorMode = false;
 
+    property_get("sys.hwc.windowbox_aspect_ratio_tolerance", value, "0");
+    ctx->mAspectRatioToleranceLevel = (((float)atoi(value)) / 100.0f);
+
     ctx->enableABC = false;
     property_get("debug.sf.hwc.canUseABC", value, "0");
     ctx->enableABC  = atoi(value) ? true : false;
@@ -337,6 +373,13 @@
     ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
     ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
 #endif
+    // Read the system property to determine if windowboxing feature is enabled.
+    ctx->mWindowboxFeature = false;
+    if(property_get("sys.hwc.windowbox_feature", value, "false")
+            && !strcmp(value, "true")) {
+        ctx->mWindowboxFeature = true;
+    }
+
     memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
     ALOGI("Initializing Qualcomm Hardware Composer");
     ALOGI("MDP version: %d", ctx->mMDP.version);
@@ -366,9 +409,9 @@
         ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
     }
 
-    if(ctx->mExtDisplay) {
-        delete ctx->mExtDisplay;
-        ctx->mExtDisplay = NULL;
+    if(ctx->mHDMIDisplay) {
+        delete ctx->mHDMIDisplay;
+        ctx->mHDMIDisplay = NULL;
     }
 
     for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
@@ -478,7 +521,7 @@
     if(ctx->dpyAttr[dpy].mMDPScalingMode) {
         // if MDP scaling mode is enabled for external, need to query
         // the actual width and height, as that is the physical w & h
-         ctx->mExtDisplay->getAttributes(fbWidth, fbHeight);
+         ctx->mHDMIDisplay->getAttributes(fbWidth, fbHeight);
     }
 
 
@@ -610,7 +653,7 @@
     if(ctx->dpyAttr[dpy].mMDPScalingMode) {
         uint32_t extW = 0, extH = 0;
         if(dpy == HWC_DISPLAY_EXTERNAL) {
-            ctx->mExtDisplay->getAttributes(extW, extH);
+            ctx->mHDMIDisplay->getAttributes(extW, extH);
         } else if(dpy == HWC_DISPLAY_VIRTUAL) {
             extW = ctx->mHWCVirtual->getScalingWidth();
             extH = ctx->mHWCVirtual->getScalingHeight();
@@ -696,7 +739,7 @@
                 float fbHeight = (float)ctx->dpyAttr[dpy].yres;
                 // query MDP configured attributes
                 if(dpy == HWC_DISPLAY_EXTERNAL) {
-                    ctx->mExtDisplay->getAttributes(extW, extH);
+                    ctx->mHDMIDisplay->getAttributes(extW, extH);
                 } else if(dpy == HWC_DISPLAY_VIRTUAL) {
                     extW = ctx->mHWCVirtual->getScalingWidth();
                     extH = ctx->mHWCVirtual->getScalingHeight();
@@ -926,6 +969,7 @@
     uint32_t refreshRate = 0;
     qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
 
+    ctx->listStats[dpy].mAIVVideoMode = false;
     resetROI(ctx, dpy);
 
     trimList(ctx, list, dpy);
@@ -935,6 +979,11 @@
         private_handle_t *hnd = (private_handle_t *)layer->handle;
 
 #ifdef QCOM_BSP
+        // Window boxing feature is applicable obly for external display, So
+        // enable mAIVVideoMode only for external display
+        if(ctx->mWindowboxFeature && dpy && isAIVVideoLayer(layer)) {
+            ctx->listStats[dpy].mAIVVideoMode = true;
+        }
         if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
             ctx->listStats[dpy].isDisplayAnimating = true;
         }
@@ -1114,7 +1163,7 @@
     // Disable Actionsafe for non HDMI displays.
     if(!(dpy == HWC_DISPLAY_EXTERNAL) ||
         qdutils::MDPVersion::getInstance().is8x74v2() ||
-        ctx->mExtDisplay->isCEUnderscanSupported()) {
+        ctx->mHDMIDisplay->isCEUnderscanSupported()) {
         return false;
     }
 
@@ -1434,7 +1483,7 @@
             rotData.acq_fen_fd_cnt = 1; //1 ioctl call per rot session
         }
         int ret = 0;
-        if(not ctx->mLayerRotMap[dpy]->isRotCached(i))
+        if(LIKELY(!swapzero) and (not ctx->mLayerRotMap[dpy]->isRotCached(i)))
             ret = ioctl(rotFd, MSMFB_BUFFER_SYNC, &rotData);
 
         if(ret < 0) {
@@ -1456,43 +1505,45 @@
     //Accumulate acquireFenceFds for MDP Overlays
     if(list->outbufAcquireFenceFd >= 0) {
         //Writeback output buffer
-        acquireFd[count++] = list->outbufAcquireFenceFd;
+        if(LIKELY(!swapzero) )
+            acquireFd[count++] = list->outbufAcquireFenceFd;
     }
 
     for(uint32_t i = 0; i < list->numHwLayers; i++) {
         if(((isAbcInUse(ctx)== true ) ||
           (list->hwLayers[i].compositionType == HWC_OVERLAY)) &&
                         list->hwLayers[i].acquireFenceFd >= 0) {
-            if(UNLIKELY(swapzero))
-                acquireFd[count++] = -1;
-            // if ABC is enabled for more than one layer.
-            // renderBufIndexforABC will work as FB.Hence
-            // set the acquireFD from fd - which is coming from copybit
-            else if(fd >= 0 && (isAbcInUse(ctx) == true)) {
-                if(ctx->listStats[dpy].renderBufIndexforABC ==(int32_t)i)
-                   acquireFd[count++] = fd;
-                else
-                   continue;
-            } else
-                acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+            if(LIKELY(!swapzero) ) {
+                // if ABC is enabled for more than one layer.
+                // renderBufIndexforABC will work as FB.Hence
+                // set the acquireFD from fd - which is coming from copybit
+                if(fd >= 0 && (isAbcInUse(ctx) == true)) {
+                    if(ctx->listStats[dpy].renderBufIndexforABC ==(int32_t)i)
+                        acquireFd[count++] = fd;
+                    else
+                        continue;
+                } else
+                    acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+            }
         }
         if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
-            if(UNLIKELY(swapzero))
-                acquireFd[count++] = -1;
-            else if(fd >= 0) {
-                //set the acquireFD from fd - which is coming from c2d
-                acquireFd[count++] = fd;
-                // Buffer sync IOCTL should be async when using c2d fence is
-                // used
-                data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
-            } else if(list->hwLayers[i].acquireFenceFd >= 0)
-                acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+            if(LIKELY(!swapzero) ) {
+                if(fd >= 0) {
+                    //set the acquireFD from fd - which is coming from c2d
+                    acquireFd[count++] = fd;
+                    // Buffer sync IOCTL should be async when using c2d fence is
+                    // used
+                    data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
+                } else if(list->hwLayers[i].acquireFenceFd >= 0)
+                    acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
+            }
         }
     }
 
     if ((fd >= 0) && !dpy && ctx->mPtorInfo.isActive()) {
         // Acquire c2d fence of Overlap render buffer
-        acquireFd[count++] = fd;
+        if(LIKELY(!swapzero) )
+            acquireFd[count++] = fd;
     }
 
     data.acq_fen_fd_cnt = count;
@@ -1784,6 +1835,71 @@
     return downscale;
 }
 
+bool isZoomModeEnabled(hwc_rect_t crop) {
+    // This does not work for zooming in top left corner of the image
+    return(crop.top > 0 || crop.left > 0);
+}
+
+void updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy) {
+    ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Source crop [%d %d %d %d]", dpy,
+             crop.left, crop.top, crop.right, crop.bottom);
+    if(isZoomModeEnabled(crop)) {
+        Dim srcCrop(crop.left, crop.top,
+                crop.right - crop.left,
+                crop.bottom - crop.top);
+        int extW = ctx->dpyAttr[dpy].xres;
+        int extH = ctx->dpyAttr[dpy].yres;
+        //Crop the original video in order to fit external display aspect ratio
+        if(srcCrop.w * extH < extW * srcCrop.h) {
+            int offset = (srcCrop.h - ((srcCrop.w * extH) / extW)) / 2;
+            crop.top += offset;
+            crop.bottom -= offset;
+        } else {
+            int offset = (srcCrop.w - ((extW * srcCrop.h) / extH)) / 2;
+            crop.left += offset;
+            crop.right -= offset;
+        }
+        ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
+                 " source crop [%d %d %d %d]", extW, extH, dpy,
+                 crop.left, crop.top, crop.right, crop.bottom);
+    }
+}
+
+void updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t crop,
+                           hwc_rect_t& dst, int dpy) {
+    ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Destination position [%d %d %d %d]", dpy,
+             dst.left, dst.top, dst.right, dst.bottom);
+    Dim srcCrop(crop.left, crop.top,
+            crop.right - crop.left,
+            crop.bottom - crop.top);
+    int extW = ctx->dpyAttr[dpy].xres;
+    int extH = ctx->dpyAttr[dpy].yres;
+    // Set the destination coordinates of external display to full screen,
+    // when zoom in mode is enabled or the ratio between video aspect ratio
+    // and external display aspect ratio is below the minimum tolerance level
+    // and above maximum tolerance level
+    float videoAspectRatio = ((float)srcCrop.w / (float)srcCrop.h);
+    float extDisplayAspectRatio = ((float)extW / (float)extH);
+    float videoToExternalRatio = videoAspectRatio / extDisplayAspectRatio;
+    if((fabs(1.0f - videoToExternalRatio) <= ctx->mAspectRatioToleranceLevel) ||
+        (isZoomModeEnabled(crop))) {
+        dst.left = 0;
+        dst.top = 0;
+        dst.right = extW;
+        dst.bottom = extH;
+    }
+    ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
+             " Destination position [%d %d %d %d] Source crop [%d %d %d %d]",
+             extW, extH, dpy, dst.left, dst.top, dst.right, dst.bottom,
+             crop.left, crop.top, crop.right, crop.bottom);
+}
+
+void updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
+                           hwc_rect_t& dst, int dpy) {
+    updateCropAIVVideoMode(ctx, crop, dpy);
+    updateDestAIVVideoMode(ctx, crop, dst, dpy);
+}
+
 int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
         const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
         const eDest& dest, Rotator **rot) {
@@ -1816,7 +1932,10 @@
         else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
     }
-
+    // update source crop and destination position of AIV video layer.
+    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
+        updateCoordinates(ctx, crop, dst, dpy);
+    }
     calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
     int downscale = getRotDownscale(ctx, layer);
     setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
@@ -1911,7 +2030,12 @@
             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
     }
 
-    /* Calculate the external display position based on MDP scaling mode,
+    // update source crop and destination position of AIV video layer.
+    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
+        updateCoordinates(ctx, crop, dst, dpy);
+    }
+
+    /* Calculate the external display position based on MDP downscale,
        ActionSafe, and extorientation features. */
     calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
     int downscale = getRotDownscale(ctx, layer);
@@ -2052,6 +2176,11 @@
     Whf whf(getWidth(hnd), getHeight(hnd),
             getMdpFormat(hnd->format), (uint32_t)hnd->size);
 
+    // update source crop and destination position of AIV video layer.
+    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
+        updateCoordinates(ctx, crop, dst, dpy);
+    }
+
     /* Calculate the external display position based on MDP downscale,
        ActionSafe, and extorientation features. */
     calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
@@ -2160,7 +2289,8 @@
         if(dpy == HWC_DISPLAY_PRIMARY)
             return false;
     }
-    if(ctx->mMDP.version == qdutils::MDP_V3_0_4)
+    if((ctx->mMDP.version == qdutils::MDP_V3_0_4)
+          ||(ctx->mMDP.version == qdutils::MDP_V3_0_5))
         return false;
     return true;
 }
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 041ca74..68bc741 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -62,7 +62,7 @@
 namespace qhwc {
 //fwrd decl
 class QueuedBufferStore;
-class ExternalDisplay;
+class HDMIDisplay;
 class VirtualDisplay;
 class IFBUpdate;
 class IVideoOverlay;
@@ -141,6 +141,8 @@
     int secureRGBIndices[MAX_NUM_APP_LAYERS];
     //dyn refresh rate-Client requested refreshrate
     uint32_t refreshRateRequest;
+    // Flag related to windowboxing feature
+    bool mAIVVideoMode;
 };
 
 //PTOR Comp info
@@ -182,6 +184,12 @@
     HWC_COPYBIT = 0x00000002,
 };
 
+// AIV specific flags
+enum {
+    HWC_AIV_VIDEO = 0x80000000,
+    HWC_AIV_CC    = 0x40000000,
+};
+
 // HAL specific features
 enum {
     HWC_COLOR_FILL = 0x00000008,
@@ -372,6 +380,12 @@
 void updateSource(ovutils::eTransform& orient, ovutils::Whf& whf,
         hwc_rect_t& crop, overlay::Rotator *rot);
 
+bool isZoomModeEnabled(hwc_rect_t crop);
+void updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy);
+void updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& dst, int dpy);
+void updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
+                           hwc_rect_t& dst, int dpy);
+
 //Routine to configure low resolution panels (<= 2048 width)
 int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
         ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
@@ -419,6 +433,14 @@
     return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
 }
 
+static inline bool isAIVVideoLayer(const hwc_layer_1_t* l) {
+    return (UNLIKELY(l && (l->flags & HWC_AIV_VIDEO)));
+}
+
+static inline bool isAIVCCLayer(const hwc_layer_1_t* l) {
+    return (UNLIKELY(l && (l->flags & HWC_AIV_CC)));
+}
+
 // Returns true if the buffer is yuv
 static inline bool isYuvBuffer(const private_handle_t* hnd) {
     return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO));
@@ -545,8 +567,9 @@
 
     //Primary and external FB updater
     qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
-    // External display related information
-    qhwc::ExternalDisplay *mExtDisplay;
+    // HDMI display related object. Used to configure/teardown
+    // HDMI when it is connected as primary or external.
+    qhwc::HDMIDisplay *mHDMIDisplay;
     qhwc::MDPInfo mMDP;
     qhwc::VsyncState vstate;
     qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES];
@@ -595,6 +618,13 @@
     qhwc::PtorInfo mPtorInfo;
     //Running in Thermal burst mode
     bool mThermalBurstMode;
+    //Layers out of ROI
+    bool copybitDrop[MAX_NUM_APP_LAYERS];
+    // Flag related to windowboxing feature
+    bool mWindowboxFeature;
+    // This denotes the tolerance between video layer and external display
+    // aspect ratio
+    float mAspectRatioToleranceLevel;
 };
 
 namespace qhwc {
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 66988f7..07d1e4e 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -29,7 +29,6 @@
 #include "hwc_utils.h"
 #include "qd_utils.h"
 #include "string.h"
-#include "external.h"
 #include "overlay.h"
 #define __STDC_FORMAT_MACROS 1
 #include <inttypes.h>
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 85c9b78..96c057f 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -387,7 +387,7 @@
         }
     }
 
-    if (mdpVersion < qdutils::MDSS_V5 && mdpVersion != qdutils::MDP_V3_0_4) {
+    if (mdpVersion < qdutils::MDSS_V5 && mdpVersion > qdutils::MDP_V3_0_5) {
         msmfb_mixer_info_req  req;
         mdp_mixer_info *minfo = NULL;
         char name[64];
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index ddc40ee..b8bb33e 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -218,6 +218,13 @@
 
 bool MdpCtrl::setVisualParams(const MetaData_t& data) {
     ALOGD_IF(0, "In %s: data.operation = %d", __FUNCTION__, data.operation);
+
+    // Set Color Space for MDP to configure CSC matrix
+    mOVInfo.color_space = ITU_R_601;
+    if (data.operation & UPDATE_COLOR_SPACE) {
+        mOVInfo.color_space = data.colorSpace;
+    }
+
 #ifdef USES_POST_PROCESSING
     bool needUpdate = false;
     /* calculate the data */
diff --git a/libqdutils/idle_invalidator.cpp b/libqdutils/idle_invalidator.cpp
index 86191e9..5850ce5 100644
--- a/libqdutils/idle_invalidator.cpp
+++ b/libqdutils/idle_invalidator.cpp
@@ -47,10 +47,13 @@
     ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
 }
 
-int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data,
-                         unsigned int idleSleepTime) {
-    ALOGD_IF(II_DEBUG, "IdleInvalidator::%s idleSleepTime %d",
-        __FUNCTION__, idleSleepTime);
+IdleInvalidator::~IdleInvalidator() {
+    if(mTimeoutEventFd >= 0) {
+        close(mTimeoutEventFd);
+    }
+}
+
+int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data) {
     mHandler = reg_handler;
     mHwcContext = user_data;
 
@@ -62,34 +65,47 @@
         return -1;
     }
 
-    // Open a sysfs node to send the timeout value to driver.
-    int fd = open(IDLE_TIME_PATH, O_WRONLY);
-    if (fd < 0) {
-        ALOGE ("%s:not able to open %s node %s",
-                __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+    enum {DEFAULT_IDLE_TIME = 70}; //ms
+    if(not setIdleTimeout(DEFAULT_IDLE_TIME)) {
         close(mTimeoutEventFd);
         mTimeoutEventFd = -1;
         return -1;
     }
-    char strSleepTime[64];
-    snprintf(strSleepTime, sizeof(strSleepTime), "%d", idleSleepTime);
-    // Notify driver about the timeout value
-    ssize_t len = pwrite(fd, strSleepTime, strlen(strSleepTime), 0);
-    if(len < -1) {
-        ALOGE ("%s:not able to write into %s node %s",
-                __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
-        close(mTimeoutEventFd);
-        mTimeoutEventFd = -1;
-        close(fd);
-        return -1;
-    }
-    close(fd);
 
     //Triggers the threadLoop to run, if not already running.
     run(threadName, android::PRIORITY_LOWEST);
     return 0;
 }
 
+bool IdleInvalidator::setIdleTimeout(const uint32_t& timeout) {
+    ALOGD_IF(II_DEBUG, "IdleInvalidator::%s timeout %d",
+            __FUNCTION__, timeout);
+
+    // Open a sysfs node to send the timeout value to driver.
+    int fd = open(IDLE_TIME_PATH, O_WRONLY);
+
+    if (fd < 0) {
+        ALOGE ("%s:Unable to open %s node %s",
+                __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+        return false;
+    }
+
+    char strSleepTime[64];
+    snprintf(strSleepTime, sizeof(strSleepTime), "%d", timeout);
+
+    // Notify driver about the timeout value
+    ssize_t len = pwrite(fd, strSleepTime, strlen(strSleepTime), 0);
+    if(len < -1) {
+        ALOGE ("%s:Unable to write into %s node %s",
+                __FUNCTION__, IDLE_TIME_PATH, strerror(errno));
+        close(fd);
+        return false;
+    }
+
+    close(fd);
+    return true;
+}
+
 bool IdleInvalidator::threadLoop() {
     ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
     struct pollfd pFd;
diff --git a/libqdutils/idle_invalidator.h b/libqdutils/idle_invalidator.h
index a881c4b..52334a0 100644
--- a/libqdutils/idle_invalidator.h
+++ b/libqdutils/idle_invalidator.h
@@ -37,16 +37,18 @@
 typedef void (*InvalidatorHandler)(void*);
 
 class IdleInvalidator : public android::Thread {
+    IdleInvalidator();
     void *mHwcContext;
     int mTimeoutEventFd;
     static InvalidatorHandler mHandler;
     static android::sp<IdleInvalidator> sInstance;
 
-    public:
-    IdleInvalidator();
+public:
+    ~IdleInvalidator();
     /* init timer obj */
-    int init(InvalidatorHandler reg_handler, void* user_data, unsigned int
-             idleSleepTime);
+    int init(InvalidatorHandler reg_handler, void* user_data);
+    bool setIdleTimeout(const uint32_t& timeout);
+
     /*Overrides*/
     virtual bool        threadLoop();
     virtual int         readyToRun();
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index b0a8d7d..088f82b 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -411,6 +411,10 @@
 }
 
 
+bool MDPVersion::hasMinCropWidthLimitation() const {
+    return mMdpRev <= MDSS_MDP_HW_REV_102;
+}
+
 bool MDPVersion::supportsDecimation() {
     return mFeatures & MDP_DECIMATION_EN;
 }
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index d26c55c..3c7f6a3 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -138,6 +138,7 @@
     uint32_t getMinFpsSupported() { return mPanelInfo.mMinFps; }
     uint32_t getMaxFpsSupported() { return mPanelInfo.mMaxFps; }
     uint32_t getMaxMixerWidth() const { return mMaxMixerWidth; }
+    bool hasMinCropWidthLimitation() const;
     bool isSrcSplit() const;
     bool isSrcSplitAlways() const;
     bool isRGBScalarSupported() const;
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index de94591..88109c9 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -90,6 +90,9 @@
         case UPDATE_COLOR_SPACE:
             data->colorSpace = *((ColorSpace_t *)param);
             break;
+        case MAP_SECURE_BUFFER:
+            data->mapSecureBuffer = *((int32_t *)param);
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index a71ee8b..32d788e 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -79,6 +79,13 @@
     int64_t timestamp;
     uint32_t refreshrate;
     enum ColorSpace_t colorSpace;
+     /* Gralloc sets PRIV_SECURE_BUFFER flag to inform that the buffers are from
+      * ION_SECURE. which should not be mapped. However, for GPU post proc
+      * feature, GFX needs to map this buffer, in the client context and in SF
+      * context, it should not. Hence to differentiate, add this metadata field
+      * for clients to set, and GPU will to read and know when to map the
+      * SECURE_BUFFER(ION) */
+    int32_t mapSecureBuffer;
 };
 
 enum DispParamType {
@@ -92,6 +99,7 @@
     UPDATE_BUFFER_GEOMETRY = 0x0080,
     UPDATE_REFRESH_RATE = 0x0100,
     UPDATE_COLOR_SPACE = 0x0200,
+    MAP_SECURE_BUFFER = 0x400,
 };
 
 struct private_handle_t;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 30c064e..3be20f1 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -53,6 +53,7 @@
         SET_WFD_STATUS,          // Set if wfd connection is on/off
         SET_VIEW_FRAME,          // Set view frame of display
         DYNAMIC_DEBUG,           // Enable more logging on the fly
+        SET_IDLE_TIMEOUT,        // Set idle timeout for GPU fallback
         COMMAND_LIST_END = 400,
     };