Merge "display : change wormhole calculation for swap rect"
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 33c4f32..dc5f6ae 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -36,6 +36,7 @@
 #include "ionalloc.h"
 #include "gr.h"
 #include "comptype.h"
+#include "mdp_version.h"
 
 #ifdef VENUS_COLOR_FORMAT
 #include <media/msm_media_info.h>
@@ -88,13 +89,16 @@
 {
     LINK_adreno_compute_aligned_width_and_height = NULL;
     LINK_adreno_compute_padding = NULL;
+    LINK_adreno_isMacroTilingSupportedByGpu = NULL;
 
     libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
     if (libadreno_utils) {
         *(void **)&LINK_adreno_compute_aligned_width_and_height =
-            ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
-        *(void **)&LINK_adreno_compute_padding = ::dlsym(libadreno_utils,
-                                           "compute_surface_padding");
+                ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
+        *(void **)&LINK_adreno_compute_padding =
+                ::dlsym(libadreno_utils, "compute_surface_padding");
+        *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
+                ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
     }
 }
 
@@ -105,8 +109,19 @@
     }
 }
 
+int AdrenoMemInfo::isMacroTilingSupportedByGPU()
+{
+    if ((libadreno_utils)) {
+        if(LINK_adreno_isMacroTilingSupportedByGpu) {
+            return LINK_adreno_isMacroTilingSupportedByGpu();
+        }
+    }
+    return 0;
+}
+
+
 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
-                              int& aligned_w, int& aligned_h)
+                            int tile_enabled, int& aligned_w, int& aligned_h)
 {
     aligned_w = ALIGN(width, 32);
     aligned_h = ALIGN(height, 32);
@@ -138,9 +153,8 @@
             // the function below computes aligned width and aligned height
             // based on linear or macro tile mode selected.
             if(LINK_adreno_compute_aligned_width_and_height) {
-               int tile_mode = 0;   // Linear surface
-               LINK_adreno_compute_aligned_width_and_height(width,
-                                     height, bpp, tile_mode,
+                LINK_adreno_compute_aligned_width_and_height(width,
+                                     height, bpp, tile_enabled,
                                      raster_mode, padding_threshold,
                                      &aligned_w, &aligned_h);
 
@@ -289,16 +303,42 @@
     return memalloc;
 }
 
-size_t getBufferSizeAndDimensions(int width, int height, int format,
-                                  int& alignedw, int &alignedh)
+bool isMacroTileEnabled(int format, int usage)
+{
+    bool tileEnabled = false;
+
+    // Check whether GPU & MDSS supports MacroTiling feature
+    if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
+            qdutils::MDPVersion::getInstance().supportsMacroTile())
+    {
+        // check the format
+        switch(format)
+        {
+            case  HAL_PIXEL_FORMAT_RGBA_8888:
+            case  HAL_PIXEL_FORMAT_RGBX_8888:
+            case  HAL_PIXEL_FORMAT_BGRA_8888:
+                {
+                    tileEnabled = true;
+                    // check the usage flags
+                    if (usage & (GRALLOC_USAGE_SW_READ_MASK |
+                                GRALLOC_USAGE_SW_WRITE_MASK)) {
+                        // Application intends to use CPU for rendering
+                        tileEnabled = false;
+                    }
+                    break;
+                }
+            default:
+                break;
+        }
+    }
+    return tileEnabled;
+}
+
+// helper function
+size_t getSize(int format, int width, int height, int alignedw, int alignedh)
 {
     size_t size;
 
-    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
-                                                          height,
-                                                          format,
-                                                          alignedw,
-                                                          alignedh);
     switch (format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
         case HAL_PIXEL_FORMAT_RGBX_8888:
@@ -376,10 +416,64 @@
             ALOGE("unrecognized pixel format: 0x%x", format);
             return -EINVAL;
     }
+    return size;
+}
+
+size_t getBufferSizeAndDimensions(int width, int height, int format,
+        int& alignedw, int &alignedh)
+{
+    size_t size;
+
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+            height,
+            format,
+            false,
+            alignedw,
+            alignedh);
+
+    size = getSize(format, width, height, alignedw, alignedh);
 
     return size;
 }
 
+
+size_t getBufferSizeAndDimensions(int width, int height, int format, int usage,
+        int& alignedw, int &alignedh)
+{
+    size_t size;
+    int tileEnabled = isMacroTileEnabled(format, usage);
+
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+            height,
+            format,
+            tileEnabled,
+            alignedw,
+            alignedh);
+
+    size = getSize(format, width, height, alignedw, alignedh);
+
+    return size;
+}
+
+
+void getBufferAttributes(int width, int height, int format, int usage,
+        int& alignedw, int &alignedh, int& tileEnabled, size_t& size)
+{
+    tileEnabled = isMacroTileEnabled(format, usage);
+
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+            height,
+            format,
+            tileEnabled,
+            alignedw,
+            alignedh);
+
+    if(size)
+        size = getSize(format, width, height, alignedw, alignedh);
+}
+
+
+
 // Allocate buffer from width, height and format into a
 // private_handle_t. It is the responsibility of the caller
 // to free the buffer using the free_buffer function
@@ -392,7 +486,9 @@
     data.base = 0;
     data.fd = -1;
     data.offset = 0;
-    data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
+    data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
+                                            alignedh);
+
     data.align = getpagesize();
     data.uncached = useUncached(usage);
     int allocFlags = usage;
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index b4da363..f4192c4 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -150,6 +150,10 @@
             flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
         }
 
+        if(isMacroTileEnabled(format, usage)) {
+            flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
+        }
+
         flags |= data.allocType;
         int eBaseAddr = int(eData.base) + eData.offset;
         private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
@@ -285,7 +289,8 @@
     }
 
     getGrallocInformationFromFormat(grallocFormat, &bufferType);
-    size = getBufferSizeAndDimensions(w, h, grallocFormat, alignedw, alignedh);
+    size = getBufferSizeAndDimensions(w, h, grallocFormat, usage, alignedw,
+                   alignedh);
 
     if ((ssize_t)size <= 0)
         return -EINVAL;
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 1949f45..8c68e16 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -51,9 +51,20 @@
 
 int mapFrameBufferLocked(struct private_module_t* module);
 int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
+size_t getBufferSizeAndDimensions(int width, int height, int format, int usage,
+                                  int& alignedw, int &alignedh);
 size_t getBufferSizeAndDimensions(int width, int height, int format,
                                   int& alignedw, int &alignedh);
 
+
+// Attributes include aligned width, aligned height, tileEnabled and size of the buffer
+void getBufferAttributes(int width, int height, int format, int usage,
+                           int& alignedw, int &alignedh,
+                           int& tileEnabled, size_t &size);
+
+
+bool isMacroTileEnabled(int format, int usage);
+
 int decideBufferHandlingMechanism(int format, const char *compositionUsed,
                                   int hasBlitEngine, int *needConversion,
                                   int *useBufferDirectly);
@@ -95,7 +106,16 @@
      * @return aligned width, aligned height
      */
     void getAlignedWidthAndHeight(int width, int height, int format,
-                                  int& alignedw, int &alignedh);
+                            int tileEnabled, int& alignedw, int &alignedh);
+
+    /*
+     * Function to return whether GPU support MacroTile feature
+     *
+     * @return >0 : supported
+     *          0 : not supported
+     */
+    int isMacroTilingSupportedByGPU();
+
     private:
         // Pointer to the padding library.
         void *libadreno_utils;
@@ -114,6 +134,8 @@
                                                 int padding_threshold,
                                                 int *aligned_w,
                                                 int *aligned_h);
+        // link to the surface padding library.
+        int (*LINK_adreno_isMacroTilingSupportedByGpu) (void);
 
 };
 #endif /* GR_H_ */
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index f6d244a..66a67d3 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -79,8 +79,12 @@
     /* Gralloc perform enums
     */
     GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 1,
+    // This will be deprecated from latest graphics drivers. This is kept
+    // for those backward compatibility i.e., newer Display HAL + older graphics
+    // libraries
     GRALLOC_MODULE_PERFORM_GET_STRIDE,
     GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE,
+    GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES,
 };
 
 #define GRALLOC_HEAP_MASK   (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
@@ -110,6 +114,9 @@
     HAL_PIXEL_FORMAT_INTERLACE              = 0x180,
     //v4l2_fourcc('Y', 'U', 'Y', 'L'). 24 bpp YUYV 4:2:2 10 bit per component
     HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT      = 0x4C595559,
+    //v4l2_fourcc('Y', 'B', 'W', 'C'). 10 bit per component. This compressed
+    //format reduces the memory access bandwidth
+    HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED = 0x43574259,
 };
 
 /* possible formats for 3D content*/
@@ -170,6 +177,8 @@
             PRIV_FLAGS_ITU_R_601_FR       = 0x00400000,
             PRIV_FLAGS_ITU_R_709          = 0x00800000,
             PRIV_FLAGS_SECURE_DISPLAY     = 0x01000000,
+            // Buffer is rendered in Tile Format
+            PRIV_FLAGS_TILE_RENDERED      = 0x02000000
         };
 
         // file-descriptors
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index a07bdc3..109c141 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -331,10 +331,11 @@
                 int *stride = va_arg(args, int *);
                 int alignedw = 0, alignedh = 0;
                 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
-                                     0, format, alignedw, alignedh);
+                        0, format, false, alignedw, alignedh);
                 *stride = alignedw;
                 res = 0;
             } break;
+
         case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
             {
                 private_handle_t* hnd =  va_arg(args, private_handle_t*);
@@ -350,6 +351,23 @@
                 }
                 res = 0;
             } break;
+
+        case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES:
+            {
+                int width   = va_arg(args, int);
+                int height  = va_arg(args, int);
+                int format  = va_arg(args, int);
+                int usage   = va_arg(args, int);
+                int *alignedWidth = va_arg(args, int *);
+                int *alignedHeight = va_arg(args, int *);
+                int *tileEnabled = va_arg(args,int *);
+                *tileEnabled = isMacroTileEnabled(format, usage);
+                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+                        height, format, *tileEnabled, *alignedWidth,
+                        *alignedHeight);
+                res = 0;
+            } break;
+
         default:
             break;
     }
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 3322c21..86cad8f 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -188,8 +188,15 @@
             dst_h = layer->displayFrame.bottom - layer->displayFrame.top;
             dst_w = layer->displayFrame.right - layer->displayFrame.left;
 
+            if(src_w <=0 || src_h<=0 ||dst_w<=0 || dst_h<=0 ) {
+              ALOGE("%s: wrong params for display screen_w=%d \
+                         src_crop_width=%d screen_h=%d src_crop_height=%d",
+                         __FUNCTION__, dst_w,src_w,dst_h,src_h);
+              return false;
+            }
             dx = (float)dst_w/src_w;
             dy = (float)dst_h/src_h;
+
             if (dx > MAX_SCALE_FACTOR || dx < MIN_SCALE_FACTOR)
                 return false;
 
@@ -451,8 +458,8 @@
 
     if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) {
         ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \
-        screen_w=%d src_crop_width=%d", __FUNCTION__, screen_w,
-                                src_crop_width,screen_w,src_crop_width);
+        screen_h=%d src_crop_height=%d", __FUNCTION__, screen_w,
+                                src_crop_width,screen_h,src_crop_height);
         return -1;
     }
 
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index d601f8f..6bc2e75 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -45,11 +45,14 @@
 }
 
 IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
-    getBufferSizeAndDimensions(ctx->dpyAttr[dpy].xres,
-            ctx->dpyAttr[dpy].yres,
+    size_t size;
+    getBufferAttributes(ctx->dpyAttr[mDpy].xres,
+            ctx->dpyAttr[mDpy].yres,
             HAL_PIXEL_FORMAT_RGBA_8888,
+            0,
             mAlignedFBWidth,
-            mAlignedFBHeight);
+            mAlignedFBHeight,
+            mTileEnabled, size);
 }
 
 void IFBUpdate::reset() {
@@ -121,9 +124,9 @@
         }
         overlay::Overlay& ov = *(ctx->mOverlay);
 
-        ovutils::Whf info(mAlignedFBWidth,
-                mAlignedFBHeight,
-                ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888));
+        ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
+                ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
+                    mTileEnabled));
 
         //Request a pipe
         ovutils::eMdpPipeType type = ovutils::OV_MDP_PIPE_ANY;
@@ -269,8 +272,8 @@
 
         ovutils::Whf info(mAlignedFBWidth,
                 mAlignedFBHeight,
-                ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888));
-
+                ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
+                    mTileEnabled));
         //Request left pipe
         ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
                 Overlay::MIXER_LEFT);
diff --git a/libhwcomposer/hwc_fbupdate.h b/libhwcomposer/hwc_fbupdate.h
index 355e429..4b449c8 100644
--- a/libhwcomposer/hwc_fbupdate.h
+++ b/libhwcomposer/hwc_fbupdate.h
@@ -53,6 +53,7 @@
     overlay::Rotator *mRot;
     int mAlignedFBWidth;
     int mAlignedFBHeight;
+    int mTileEnabled;
 };
 
 //Non-Split panel handler.
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 0b4cbe0..3d391ab 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -325,8 +325,8 @@
     int crop_h = crop.bottom - crop.top;
     int dst_w = dst.right - dst.left;
     int dst_h = dst.bottom - dst.top;
-    float w_dscale = ceilf((float)crop_w / (float)dst_w);
-    float h_dscale = ceilf((float)crop_h / (float)dst_h);
+    float w_scale = ((float)crop_w / (float)dst_w);
+    float h_scale = ((float)crop_h / (float)dst_h);
 
     /* Workaround for MDP HW limitation in DSI command mode panels where
      * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
@@ -337,9 +337,12 @@
     if((crop_w < 5)||(crop_h < 5))
         return false;
 
-    if((w_dscale > 1.0f) || (h_dscale > 1.0f)) {
+    if((w_scale > 1.0f) || (h_scale > 1.0f)) {
         const uint32_t downscale =
             qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
+        const float w_dscale = w_scale;
+        const float h_dscale = h_scale;
+
         if(ctx->mMDP.version >= qdutils::MDSS_V5) {
             /* Workaround for downscales larger than 4x.
              * Will be removed once decimator block is enabled for MDSS
@@ -358,6 +361,16 @@
         }
     }
 
+    if((w_scale < 1.0f) || (h_scale < 1.0f)) {
+        const uint32_t upscale =
+            qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
+        const float w_uscale = 1.0f / w_scale;
+        const float h_uscale = 1.0f / h_scale;
+
+        if(w_uscale > upscale || h_uscale > upscale)
+            return false;
+    }
+
     return true;
 }
 
@@ -541,6 +554,13 @@
         return false;
     }
 
+    // check for action safe flag and downscale mode which requires scaling.
+    if(ctx->dpyAttr[mDpy].mActionSafePresent
+            || ctx->dpyAttr[mDpy].mDownScaleMode) {
+        ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
+        return false;
+    }
+
     for(int i = 0; i < numAppLayers; ++i) {
         hwc_layer_1_t* layer = &list->hwLayers[i];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 05a560b..512a120 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -25,7 +25,7 @@
 #include <cutils/properties.h>
 #include <overlay.h>
 
-#define DEFAULT_IDLE_TIME 2000
+#define DEFAULT_IDLE_TIME 70
 #define MAX_PIPES_PER_MIXER 4
 
 namespace overlay {
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 50e94c9..8c99d64 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *  Copyright (c) 2013-14, 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
@@ -36,6 +36,7 @@
 
 using namespace android;
 using namespace qService;
+using namespace qhwc;
 
 namespace qClient {
 
@@ -165,6 +166,17 @@
     }
 }
 
+static void pauseWFD(hwc_context_t *ctx, uint32_t pause) {
+    int dpy = HWC_DISPLAY_VIRTUAL;
+    if(pause) {
+        //WFD Pause
+        handle_pause(ctx, dpy);
+    } else {
+        //WFD Resume
+        handle_resume(ctx, dpy);
+    }
+}
+
 status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
         Parcel* outParcel) {
     status_t ret = NO_ERROR;
@@ -202,6 +214,8 @@
             break;
         case IQService::SET_HSIC_DATA:
             setHSIC(mHwcContext, inParcel);
+        case IQService::PAUSE_WFD:
+            pauseWFD(mHwcContext, inParcel->readInt32());
             break;
         default:
             ret = NO_ERROR;
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 51e5526..83586ac 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -1,7 +1,7 @@
 
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-14, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are
  * retained for attribution purposes only.
@@ -50,13 +50,6 @@
 {
     ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx, dpy);
     ctx->mMDPComp[dpy] =  MDPComp::getObject(ctx, dpy);
-    int compositionType =
-                qdutils::QCCompositionType::getInstance().getCompositionType();
-    if (compositionType & (qdutils::COMPOSITION_TYPE_DYN |
-                           qdutils::COMPOSITION_TYPE_MDP |
-                           qdutils::COMPOSITION_TYPE_C2D)) {
-        ctx->mCopyBit[dpy] = new CopyBit(ctx, dpy);
-    }
 }
 
 static void clear(hwc_context_t* ctx, int dpy)
@@ -65,10 +58,6 @@
         delete ctx->mFBUpdate[dpy];
         ctx->mFBUpdate[dpy] = NULL;
     }
-    if(ctx->mCopyBit[dpy]){
-        delete ctx->mCopyBit[dpy];
-        ctx->mCopyBit[dpy] = NULL;
-    }
     if(ctx->mMDPComp[dpy]) {
         delete ctx->mMDPComp[dpy];
         ctx->mMDPComp[dpy] = NULL;
@@ -117,6 +106,58 @@
     return -1;
 }
 
+void handle_pause(hwc_context_t* ctx, int dpy) {
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        ctx->dpyAttr[dpy].isActive = true;
+        ctx->dpyAttr[dpy].isPause = true;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+           * 2 / 1000);
+    // At this point all the pipes used by External have been
+    // marked as UNSET.
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        // Perform commit to unstage the pipes.
+        if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
+            ALOGE("%s: display commit fail! for %d dpy",
+                  __FUNCTION__, dpy);
+        }
+    }
+    return;
+}
+
+void handle_resume(hwc_context_t* ctx, int dpy) {
+    //Treat Resume as Online event
+    //Since external didnt have any pipes, force primary to give up
+    //its pipes; we don't allow inter-mixer pipe transfers.
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+
+        // A dynamic resolution change (DRC) can be made for a WiFi
+        // display. In order to support the resolution change, we
+        // need to reconfigure the corresponding display attributes.
+        // Since DRC is only on WiFi display, we only need to call
+        // configure() on the VirtualDisplay device.
+        if(dpy == HWC_DISPLAY_VIRTUAL)
+            ctx->mVirtualDisplay->configure();
+
+        ctx->dpyAttr[dpy].isConfiguring = true;
+        ctx->dpyAttr[dpy].isActive = true;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
+           * 2 / 1000);
+    //At this point external has all the pipes it would need.
+    {
+        Locker::Autolock _l(ctx->mDrawLock);
+        ctx->dpyAttr[dpy].isPause = false;
+        ctx->proc->invalidate(ctx->proc);
+    }
+    return;
+}
+
 static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
 {
     bool bpanelReset = getPanelResetStatus(ctx, udata, len);
@@ -267,25 +308,8 @@
         case EXTERNAL_PAUSE:
             {   // pause case
                 ALOGD("%s Received Pause event",__FUNCTION__);
-                 {
-                     Locker::Autolock _l(ctx->mDrawLock);
-                     ctx->dpyAttr[dpy].isActive = true;
-                     ctx->dpyAttr[dpy].isPause = true;
-                     ctx->proc->invalidate(ctx->proc);
-                 }
-                 usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
-                         * 2 / 1000);
-                 // At this point all the pipes used by External have been
-                 // marked as UNSET.
-                 {
-                     Locker::Autolock _l(ctx->mDrawLock);
-                     // Perform commit to unstage the pipes.
-                     if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
-                         ALOGE("%s: display commit fail! for %d dpy",
-                                 __FUNCTION__, dpy);
-                     }
-                 }
-                 break;
+                handle_pause(ctx, dpy);
+                break;
             }
         case EXTERNAL_RESUME:
             {  // resume case
@@ -293,29 +317,7 @@
                 //Treat Resume as Online event
                 //Since external didnt have any pipes, force primary to give up
                 //its pipes; we don't allow inter-mixer pipe transfers.
-                {
-                    Locker::Autolock _l(ctx->mDrawLock);
-
-                    // A dynamic resolution change (DRC) can be made for a WiFi
-                    // display. In order to support the resolution change, we
-                    // need to reconfigure the corresponding display attributes.
-                    // Since DRC is only on WiFi display, we only need to call
-                    // configure() on the VirtualDisplay device.
-                    if(dpy == HWC_DISPLAY_VIRTUAL)
-                        ctx->mVirtualDisplay->configure();
-
-                    ctx->dpyAttr[dpy].isConfiguring = true;
-                    ctx->dpyAttr[dpy].isActive = true;
-                    ctx->proc->invalidate(ctx->proc);
-                }
-                usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
-                        * 2 / 1000);
-                //At this point external has all the pipes it would need.
-                {
-                    Locker::Autolock _l(ctx->mDrawLock);
-                    ctx->dpyAttr[dpy].isPause = false;
-                    ctx->proc->invalidate(ctx->proc);
-                }
+                handle_resume(ctx, dpy);
                 break;
             }
     default:
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 0663f67..fa021cc 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -142,16 +142,18 @@
     ctx->mFBUpdate[HWC_DISPLAY_PRIMARY] =
         IFBUpdate::getObject(ctx, HWC_DISPLAY_PRIMARY);
 
-    // Check if the target supports copybit compostion (dyn/mdp/c2d) to
+    // Check if the target supports copybit compostion (dyn/mdp) to
     // decide if we need to open the copybit module.
     int compositionType =
         qdutils::QCCompositionType::getInstance().getCompositionType();
 
-    if (compositionType & (qdutils::COMPOSITION_TYPE_DYN |
-                           qdutils::COMPOSITION_TYPE_MDP |
-                           qdutils::COMPOSITION_TYPE_C2D)) {
-            ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
-                    HWC_DISPLAY_PRIMARY);
+    // Only MDP copybit is used
+    if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
+            qdutils::COMPOSITION_TYPE_MDP)) &&
+            (qdutils::MDPVersion::getInstance().getMDPVersion() ==
+            qdutils::MDP_V3_0_4)) {
+        ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
+                                                         HWC_DISPLAY_PRIMARY);
     }
 
     ctx->mExtDisplay = new ExternalDisplay(ctx);
@@ -173,6 +175,9 @@
         ctx->mHwcDebug[i] = new HwcDebug(i);
         ctx->mLayerRotMap[i] = new LayerRotMap();
         ctx->mAnimationState[i] = ANIMATION_STOPPED;
+        ctx->dpyAttr[i].mActionSafePresent = false;
+        ctx->dpyAttr[i].mAsWidthRatio = 0;
+        ctx->dpyAttr[i].mAsHeightRatio = 0;
     }
 
     MDPComp::init(ctx);
@@ -285,22 +290,11 @@
     int w = rect.right - rect.left;
     int h = rect.bottom - rect.top;
 
-    // if external supports underscan, do nothing
-    // it will be taken care in the driver
-    if(ctx->mExtDisplay->isCEUnderscanSupported())
+    if(!ctx->dpyAttr[dpy].mActionSafePresent)
         return;
-
-    char value[PROPERTY_VALUE_MAX];
-    // Read action safe properties
-    property_get("persist.sys.actionsafe.width", value, "0");
-    int asWidthRatio = atoi(value);
-    property_get("persist.sys.actionsafe.height", value, "0");
-    int asHeightRatio = atoi(value);
-
-    if(!asWidthRatio && !asHeightRatio) {
-        //No action safe ratio set, return
-        return;
-    }
+   // Read action safe properties
+    int asWidthRatio = ctx->dpyAttr[dpy].mAsWidthRatio;
+    int asHeightRatio = ctx->dpyAttr[dpy].mAsHeightRatio;
 
     float wRatio = 1.0;
     float hRatio = 1.0;
@@ -626,7 +620,6 @@
 }
 bool needsScaling(hwc_layer_1_t const* layer) {
     int dst_w, dst_h, src_w, src_h;
-
     hwc_rect_t displayFrame  = layer->displayFrame;
     hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
 
@@ -763,6 +756,7 @@
     ctx->listStats[dpy].secureUI = false;
     ctx->listStats[dpy].yuv4k2kCount = 0;
     ctx->mViewFrame[dpy] = (hwc_rect_t){0, 0, 0, 0};
+    ctx->dpyAttr[dpy].mActionSafePresent = isActionSafePresent(ctx, dpy);
 
     trimList(ctx, list, dpy);
     optimizeLayerRects(ctx, list, dpy);
@@ -920,6 +914,27 @@
         return false;
 }
 
+// returns true if Action safe dimensions are set and target supports Actionsafe
+bool isActionSafePresent(hwc_context_t *ctx, int dpy) {
+    // if external supports underscan, do nothing
+    // it will be taken care in the driver
+    if(!dpy || ctx->mExtDisplay->isCEUnderscanSupported())
+        return false;
+
+    char value[PROPERTY_VALUE_MAX];
+    // Read action safe properties
+    property_get("persist.sys.actionsafe.width", value, "0");
+    ctx->dpyAttr[dpy].mAsWidthRatio = atoi(value);
+    property_get("persist.sys.actionsafe.height", value, "0");
+    ctx->dpyAttr[dpy].mAsHeightRatio = atoi(value);
+
+    if(!ctx->dpyAttr[dpy].mAsWidthRatio && !ctx->dpyAttr[dpy].mAsHeightRatio) {
+        //No action safe ratio set, return
+        return false;
+    }
+    return true;
+}
+
 int getBlending(int blending) {
     switch(blending) {
     case HWC_BLENDING_NONE:
@@ -1078,7 +1093,8 @@
                if(!needsScaling(&list->hwLayers[j])) {
                   hwc_layer_1_t* layer = (hwc_layer_1_t*)&list->hwLayers[j];
                   hwc_rect_t& bottomframe = layer->displayFrame;
-                  hwc_rect_t& bottomCrop = layer->sourceCrop;
+                  hwc_rect_t bottomCrop =
+                      integerizeSourceCrop(layer->sourceCropf);
                   int transform =layer->transform;
 
                   hwc_rect_t irect = getIntersection(bottomframe, topframe);
@@ -1088,7 +1104,11 @@
                      dest_rect  = deductRect(bottomframe, irect);
                      qhwc::calculate_crop_rects(bottomCrop, bottomframe,
                                                 dest_rect, transform);
-
+                     //Update layer sourceCropf
+                     layer->sourceCropf.left = bottomCrop.left;
+                     layer->sourceCropf.top = bottomCrop.top;
+                     layer->sourceCropf.right = bottomCrop.right;
+                     layer->sourceCropf.bottom = bottomCrop.bottom;
                   }
                }
                j--;
@@ -1476,8 +1496,8 @@
     eTransform orient = static_cast<eTransform>(transform);
     int downscale = 0;
     int rotFlags = ovutils::ROT_FLAGS_NONE;
-    Whf whf(getWidth(hnd), getHeight(hnd),
-            getMdpFormat(hnd->format), hnd->size);
+    uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+    Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
 
     // Handle R/B swap
     if (layer->flags & HWC_FORMAT_RB_SWAP) {
@@ -1583,9 +1603,8 @@
     eTransform orient = static_cast<eTransform>(transform);
     const int downscale = 0;
     int rotFlags = ROT_FLAGS_NONE;
-
-    Whf whf(getWidth(hnd), getHeight(hnd),
-            getMdpFormat(hnd->format), hnd->size);
+    uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+    Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
 
     // Handle R/B swap
     if (layer->flags & HWC_FORMAT_RB_SWAP) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index cd84f73..4a20d47 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C)2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (C)2012-2014, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
@@ -89,6 +89,11 @@
     bool mDownScaleMode;
     // Ext dst Rect
     hwc_rect_t mDstRect;
+    //Action safe attributes
+    // Flag to indicate the presence of action safe dimensions for external
+    bool mActionSafePresent;
+    int mAsWidthRatio;
+    int mAsHeightRatio;
 };
 
 struct ListStats {
@@ -230,6 +235,9 @@
 bool areLayersIntersecting(const hwc_layer_1_t* layer1,
         const hwc_layer_1_t* layer2);
 
+// returns true if Action safe dimensions are set and target supports Actionsafe
+bool isActionSafePresent(hwc_context_t *ctx, int dpy);
+
 /* Calculates the destination position based on the action safe rectangle */
 void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& dst);
 
@@ -255,6 +263,10 @@
 // BufferMirrirMode(Sidesync)
 int getMirrorModeOrientation(hwc_context_t *ctx);
 
+// Handles wfd Pause and resume events
+void handle_pause(hwc_context_t *ctx, int dpy);
+void handle_resume(hwc_context_t *ctx, int dpy);
+
 //Close acquireFenceFds of all layers of incoming list
 void closeAcquireFds(hwc_display_contents_1_t* list);
 
@@ -334,6 +346,11 @@
 static inline bool isSecureBuffer(const private_handle_t* hnd) {
     return (hnd && (private_handle_t::PRIV_FLAGS_SECURE_BUFFER & hnd->flags));
 }
+
+static inline bool isTileRendered(const private_handle_t* hnd) {
+    return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
+}
+
 //Return true if buffer is marked locked
 static inline bool isBufferLocked(const private_handle_t* hnd) {
     return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags));
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index 1b26b66..dbf328a 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -49,13 +49,9 @@
 public:
 
     /* ctor */
-    explicit Ctrl();
+    explicit Ctrl(const int& dpy);
     /* dtor close */
     ~Ctrl();
-    /* init fd etc*/
-    bool init(uint32_t dpy);
-    /* close underlying mdp */
-    bool close();
 
     /* set source using whf, orient and wait flag */
     void setSource(const utils::PipeArgs& args);
@@ -90,20 +86,16 @@
 
 private:
     // mdp ctrl struct(info e.g.)
-    MdpCtrl mMdp;
+    MdpCtrl *mMdp;
 };
 
 
 class Data : utils::NoCopy {
 public:
     /* init, reset */
-    explicit Data();
+    explicit Data(const int& dpy);
     /* calls close */
     ~Data();
-    /* init fd etc */
-    bool init(uint32_t dpy);
-    /* calls underlying mdp close */
-    bool close();
     /* set overlay pipe id in the mdp struct */
     void setPipeId(int id);
     /* get overlay id in the mdp struct */
@@ -117,72 +109,46 @@
 
 private:
     // mdp data struct
-    MdpData mMdp;
-};
-
-/* This class just creates a Ctrl Data pair to be used by a pipe.
- * Although this was legacy design, this separation still makes sense, since we
- * need to use the Ctrl channel in hwc_prepare (i.e config stage) and Data
- * channel in hwc_set (i.e draw stage)
- */
-struct CtrlData {
-    Ctrl ctrl;
-    Data data;
+    MdpData *mMdp;
 };
 
 //-------------Inlines-------------------------------
 
-inline Ctrl::Ctrl() {
-    mMdp.reset();
+inline Ctrl::Ctrl(const int& dpy) : mMdp(new MdpCtrl(dpy)) {
 }
 
 inline Ctrl::~Ctrl() {
-    close();
-}
-
-inline bool Ctrl::close() {
-    if(!mMdp.close())
-        return false;
-    return true;
-}
-
-inline bool Ctrl::init(uint32_t dpy) {
-    // MDP/FD init
-    if(!mMdp.init(dpy)) {
-        ALOGE("Ctrl failed to init dpy=%d", dpy);
-        return false;
-    }
-    return true;
+    delete mMdp;
 }
 
 inline void Ctrl::setSource(const utils::PipeArgs& args)
 {
-    mMdp.setSource(args);
+    mMdp->setSource(args);
 }
 
 inline void Ctrl::setPosition(const utils::Dim& dim)
 {
-    mMdp.setPosition(dim);
+    mMdp->setPosition(dim);
 }
 
 inline void Ctrl::setTransform(const utils::eTransform& orient)
 {
-    mMdp.setTransform(orient);
+    mMdp->setTransform(orient);
 }
 
 inline void Ctrl::setCrop(const utils::Dim& d)
 {
-    mMdp.setCrop(d);
+    mMdp->setCrop(d);
 }
 
 inline void Ctrl::setColor(const uint32_t color)
 {
-    mMdp.setColor(color);
+    mMdp->setColor(color);
 }
 
 inline bool Ctrl::setVisualParams(const MetaData_t &metadata)
 {
-    if (!mMdp.setVisualParams(metadata)) {
+    if (!mMdp->setVisualParams(metadata)) {
         ALOGE("Ctrl setVisualParams failed in MDP setVisualParams");
         return false;
     }
@@ -191,12 +157,12 @@
 
 inline void Ctrl::dump() const {
     ALOGE("== Dump Ctrl start ==");
-    mMdp.dump();
+    mMdp->dump();
     ALOGE("== Dump Ctrl end ==");
 }
 
 inline bool Ctrl::commit() {
-    if(!mMdp.set()) {
+    if(!mMdp->set()) {
         ALOGE("Ctrl commit failed set overlay");
         return false;
     }
@@ -204,71 +170,56 @@
 }
 
 inline int Ctrl::getPipeId() const {
-    return mMdp.getPipeId();
+    return mMdp->getPipeId();
 }
 
 inline int Ctrl::getFd() const {
-    return mMdp.getFd();
+    return mMdp->getFd();
 }
 
 inline void Ctrl::updateSrcFormat(const uint32_t& rotDstFmt) {
-    mMdp.updateSrcFormat(rotDstFmt);
+    mMdp->updateSrcFormat(rotDstFmt);
 }
 
 inline utils::Dim Ctrl::getCrop() const {
-    return mMdp.getSrcRectDim();
+    return mMdp->getSrcRectDim();
 }
 
 inline utils::Dim Ctrl::getPosition() const {
-    return mMdp.getDstRectDim();
+    return mMdp->getDstRectDim();
 }
 
 inline void Ctrl::setDownscale(int dscale_factor) {
-    mMdp.setDownscale(dscale_factor);
+    mMdp->setDownscale(dscale_factor);
 }
 
 inline void Ctrl::getDump(char *buf, size_t len) {
-    mMdp.getDump(buf, len);
+    mMdp->getDump(buf, len);
 }
 
-inline Data::Data() {
-    mMdp.reset();
+inline Data::Data(const int& dpy) : mMdp(new MdpData(dpy)) {
 }
 
-inline Data::~Data() { close(); }
-
-inline void Data::setPipeId(int id) { mMdp.setPipeId(id); }
-
-inline int Data::getPipeId() const { return mMdp.getPipeId(); }
-
-inline bool Data::init(uint32_t dpy) {
-    if(!mMdp.init(dpy)) {
-        ALOGE("Data cannot init mdp");
-        return false;
-    }
-    return true;
+inline Data::~Data() {
+    delete mMdp;
 }
 
-inline bool Data::close() {
-    if(!mMdp.close()) {
-        ALOGE("Data close failed");
-        return false;
-    }
-    return true;
-}
+inline void Data::setPipeId(int id) { mMdp->setPipeId(id); }
+
+inline int Data::getPipeId() const { return mMdp->getPipeId(); }
 
 inline bool Data::queueBuffer(int fd, uint32_t offset) {
-    return mMdp.play(fd, offset);
+    return mMdp->play(fd, offset);
 }
 
 inline void Data::dump() const {
     ALOGE("== Dump Data MDP start ==");
-    mMdp.dump();
+    mMdp->dump();
     ALOGE("== Dump Data MDP end ==");
 }
 
 inline void Data::getDump(char *buf, size_t len) {
-    mMdp.getDump(buf, len);
+    mMdp->getDump(buf, len);
 }
 
 } // overlay
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 268480d..b278ce4 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -45,7 +45,7 @@
 namespace ovutils = overlay::utils;
 namespace overlay {
 
-bool MdpCtrl::init(uint32_t dpy) {
+bool MdpCtrl::init(const int& dpy) {
     int fbnum = Overlay::getFbForDpy(dpy);
     if( fbnum < 0 ) {
         ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, dpy);
@@ -390,7 +390,7 @@
 
 
 //// MdpData ////////////
-bool MdpData::init(uint32_t dpy) {
+bool MdpData::init(const int& dpy) {
     int fbnum = Overlay::getFbForDpy(dpy);
     if( fbnum < 0 ) {
         ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, dpy);
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index 8074724..daaeaf2 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -36,11 +36,11 @@
 class MdpCtrl {
 public:
     /* ctor reset */
-    explicit MdpCtrl();
+    explicit MdpCtrl(const int& dpy);
     /* dtor close */
     ~MdpCtrl();
     /* init underlying device using fbnum for dpy */
-    bool init(uint32_t dpy);
+    bool init(const int& dpy);
     /* unset overlay, reset and close fd */
     bool close();
     /* reset and set ov id to -1 / MSMFB_NEW_REQUEST */
@@ -160,11 +160,11 @@
 class MdpData {
 public:
     /* ctor reset data */
-    explicit MdpData();
+    explicit MdpData(const int& dpy);
     /* dtor close*/
     ~MdpData();
     /* init FD */
-    bool init(uint32_t dpy);
+    bool init(const int& dpy);
     /* memset0 the underlying mdp object */
     void reset();
     /* close fd, and reset */
@@ -196,8 +196,9 @@
 
 /////   MdpCtrl  //////
 
-inline MdpCtrl::MdpCtrl() {
+inline MdpCtrl::MdpCtrl(const int& dpy) {
     reset();
+    init(dpy);
 }
 
 inline MdpCtrl::~MdpCtrl() {
@@ -346,7 +347,10 @@
 
 ///////    MdpData   //////
 
-inline MdpData::MdpData() { reset(); }
+inline MdpData::MdpData(const int& dpy) {
+    reset();
+    init(dpy);
+}
 
 inline MdpData::~MdpData() { close(); }
 
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 1377182..30de1db 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -36,6 +36,7 @@
 #include "overlayUtils.h"
 #include "mdpWrapper.h"
 #include "mdp_version.h"
+#include <hardware/hwcomposer_defs.h>
 
 // just a helper static thingy
 namespace {
@@ -145,6 +146,34 @@
     return -1;
 }
 
+// This function returns corresponding tile format
+// MDSS support following RGB tile formats
+//  32 bit formats
+//  16 bit formats
+int getMdpFormat(int format, bool tileEnabled)
+{
+    if(!tileEnabled) {
+        return getMdpFormat(format);
+    }
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888 :
+            return MDP_RGBA_8888_TILE;
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            return MDP_RGBX_8888_TILE;
+        case HAL_PIXEL_FORMAT_RGB_565:
+            // Currenty Driver doesnt support 565 tile format
+            return MDP_RGB_565;
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            return MDP_BGRA_8888_TILE;
+        case HAL_PIXEL_FORMAT_BGRX_8888:
+            return MDP_BGRX_8888_TILE;
+        default:
+            return getMdpFormat(format);
+    }
+}
+
+
+
 //Takes mdp format as input and translates to equivalent HAL format
 //Refer to graphics.h, gralloc_priv.h, msm_mdp.h for formats.
 int getHALFormat(int mdpFormat) {
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 904d607..33802e5 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -408,6 +408,7 @@
 };
 
 int getMdpFormat(int format);
+int getMdpFormat(int format, bool tileEnabled);
 int getHALFormat(int mdpFormat);
 int getDownscaleFactor(const int& src_w, const int& src_h,
         const int& dst_w, const int& dst_h);
@@ -545,6 +546,14 @@
     formats[MDP_BGR_888] = STR(MDP_BGR_888);
     formats[MDP_Y_CBCR_H2V2_VENUS] = STR(MDP_Y_CBCR_H2V2_VENUS);
     formats[MDP_BGRX_8888] = STR(MDP_BGRX_8888);
+    formats[MDP_RGBA_8888_TILE] = STR(MDP_RGBA_8888_TILE);
+    formats[MDP_ARGB_8888_TILE] = STR(MDP_ARGB_8888_TILE);
+    formats[MDP_ABGR_8888_TILE] = STR(MDP_ABGR_8888_TILE);
+    formats[MDP_BGRA_8888_TILE] = STR(MDP_BGRA_8888_TILE);
+    formats[MDP_RGBX_8888_TILE] = STR(MDP_RGBX_8888_TILE);
+    formats[MDP_XRGB_8888_TILE] = STR(MDP_XRGB_8888_TILE);
+    formats[MDP_XBGR_8888_TILE] = STR(MDP_XBGR_8888_TILE);
+    formats[MDP_BGRX_8888_TILE] = STR(MDP_BGRX_8888_TILE);
     formats[MDP_IMGTYPE_LIMIT] = STR(MDP_IMGTYPE_LIMIT);
 
     if(format < 0 || format >= MDP_IMGTYPE_LIMIT) {
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index e0b580b..394a56e 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -32,73 +32,40 @@
 
 namespace overlay {
 
-GenericPipe::GenericPipe(int dpy) : mDpy(dpy), mRotDownscaleOpt(false),
-    pipeState(CLOSED) {
-    init();
+GenericPipe::GenericPipe(const int& dpy) : mDpy(dpy), mRotDownscaleOpt(false),
+    pipeState(CLOSED), mCtrl(new Ctrl(dpy)), mData(new Data(dpy)) {
 }
 
 GenericPipe::~GenericPipe() {
-    close();
-}
-
-bool GenericPipe::init()
-{
-    ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
-    mRotDownscaleOpt = false;
-
-    if(!mCtrlData.ctrl.init(mDpy)) {
-        ALOGE("GenericPipe failed to init ctrl");
-        return false;
-    }
-
-    if(!mCtrlData.data.init(mDpy)) {
-        ALOGE("GenericPipe failed to init data");
-        return false;
-    }
-
-    return true;
-}
-
-bool GenericPipe::close() {
-    bool ret = true;
-
-    if(!mCtrlData.ctrl.close()) {
-        ALOGE("GenericPipe failed to close ctrl");
-        ret = false;
-    }
-    if (!mCtrlData.data.close()) {
-        ALOGE("GenericPipe failed to close data");
-        ret = false;
-    }
-
+    delete mCtrl;
+    delete mData;
     setClosed();
-    return ret;
 }
 
 void GenericPipe::setSource(const utils::PipeArgs& args) {
     mRotDownscaleOpt = args.rotFlags & utils::ROT_DOWNSCALE_ENABLED;
-    mCtrlData.ctrl.setSource(args);
+    mCtrl->setSource(args);
 }
 
 void GenericPipe::setCrop(const overlay::utils::Dim& d) {
-    mCtrlData.ctrl.setCrop(d);
+    mCtrl->setCrop(d);
 }
 
 void GenericPipe::setColor(const uint32_t color) {
-    mCtrlData.ctrl.setColor(color);
+    mCtrl->setColor(color);
 }
 
 void GenericPipe::setTransform(const utils::eTransform& orient) {
-    mCtrlData.ctrl.setTransform(orient);
+    mCtrl->setTransform(orient);
 }
 
 void GenericPipe::setPosition(const utils::Dim& d) {
-    mCtrlData.ctrl.setPosition(d);
+    mCtrl->setPosition(d);
 }
 
 bool GenericPipe::setVisualParams(const MetaData_t &metadata)
 {
-        return mCtrlData.ctrl.setVisualParams(metadata);
+        return mCtrl->setVisualParams(metadata);
 }
 
 bool GenericPipe::commit() {
@@ -106,14 +73,14 @@
     int downscale_factor = utils::ROT_DS_NONE;
 
     if(mRotDownscaleOpt) {
-        ovutils::Dim src(mCtrlData.ctrl.getCrop());
-        ovutils::Dim dst(mCtrlData.ctrl.getPosition());
+        ovutils::Dim src(mCtrl->getCrop());
+        ovutils::Dim dst(mCtrl->getPosition());
         downscale_factor = ovutils::getDownscaleFactor(
                 src.w, src.h, dst.w, dst.h);
     }
 
-    mCtrlData.ctrl.setDownscale(downscale_factor);
-    ret = mCtrlData.ctrl.commit();
+    mCtrl->setDownscale(downscale_factor);
+    ret = mCtrl->commit();
 
     pipeState = ret ? OPEN : CLOSED;
     return ret;
@@ -122,36 +89,35 @@
 bool GenericPipe::queueBuffer(int fd, uint32_t offset) {
     //TODO Move pipe-id transfer to CtrlData class. Make ctrl and data private.
     OVASSERT(isOpen(), "State is closed, cannot queueBuffer");
-    int pipeId = mCtrlData.ctrl.getPipeId();
+    int pipeId = mCtrl->getPipeId();
     OVASSERT(-1 != pipeId, "Ctrl ID should not be -1");
     // set pipe id from ctrl to data
-    mCtrlData.data.setPipeId(pipeId);
+    mData->setPipeId(pipeId);
 
-    return mCtrlData.data.queueBuffer(fd, offset);
+    return mData->queueBuffer(fd, offset);
 }
 
 int GenericPipe::getCtrlFd() const {
-    return mCtrlData.ctrl.getFd();
+    return mCtrl->getFd();
 }
 
 utils::Dim GenericPipe::getCrop() const
 {
-    return mCtrlData.ctrl.getCrop();
+    return mCtrl->getCrop();
 }
 
 void GenericPipe::dump() const
 {
     ALOGE("== Dump Generic pipe start ==");
     ALOGE("pipe state = %d", (int)pipeState);
-    mCtrlData.ctrl.dump();
-    mCtrlData.data.dump();
-
+    mCtrl->dump();
+    mData->dump();
     ALOGE("== Dump Generic pipe end ==");
 }
 
 void GenericPipe::getDump(char *buf, size_t len) {
-    mCtrlData.ctrl.getDump(buf, len);
-    mCtrlData.data.getDump(buf, len);
+    mCtrl->getDump(buf, len);
+    mData->getDump(buf, len);
 }
 
 bool GenericPipe::isClosed() const  {
@@ -168,7 +134,7 @@
 }
 
 int GenericPipe::getPipeId() {
-    return mCtrlData.ctrl.getPipeId();
+    return mCtrl->getPipeId();
 }
 
 } //namespace overlay
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index ecdd001..57e1758 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -38,11 +38,9 @@
 class GenericPipe : utils::NoCopy {
 public:
     /* ctor */
-    explicit GenericPipe(int dpy);
+    explicit GenericPipe(const int& dpy);
     /* dtor */
     ~GenericPipe();
-    bool init();
-    bool close();
     /* Control APIs */
     /* set source using whf, orient and wait flag */
     void setSource(const utils::PipeArgs& args);
@@ -82,8 +80,6 @@
     bool setClosed();
 
     int mDpy;
-    /* Ctrl/Data aggregator */
-    CtrlData mCtrlData;
     //Whether we will do downscale opt. This is just a request. If the frame is
     //not a candidate, we might not do it.
     bool mRotDownscaleOpt;
@@ -93,6 +89,8 @@
         OPEN
     };
     ePipeState pipeState;
+    Ctrl *mCtrl;
+    Data *mData;
 };
 
 } //namespace overlay
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index b219cd5..b743d7a 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -37,6 +37,25 @@
 
 #define TOKEN_PARAMS_DELIM  "="
 
+#ifndef MDSS_MDP_REV
+enum mdp_rev {
+    MDSS_MDP_HW_REV_100 = 0x10000000, //8974 v1
+    MDSS_MDP_HW_REV_101 = 0x10010000, //8x26
+    MDSS_MDP_HW_REV_102 = 0x10020000, //8974 v2
+    MDSS_MDP_HW_REV_103 = 0x10030000, //8084
+    MDSS_MDP_HW_REV_104 = 0x10040000, //Next version
+    MDSS_MDP_HW_REV_105 = 0x10050000, //Next version
+    MDSS_MDP_HW_REV_107 = 0x10070000, //Next version
+    MDSS_MDP_HW_REV_200 = 0x20000000, //8092
+    MDSS_MDP_HW_REV_206 = 0x20060000, //Future
+};
+#else
+enum mdp_rev {
+    MDSS_MDP_HW_REV_104 = 0x10040000, //Next version
+    MDSS_MDP_HW_REV_206 = 0x20060000, //Future
+};
+#endif
+
 MDPVersion::MDPVersion()
 {
     mMDPVersion = MDSS_V5;
@@ -47,6 +66,7 @@
     mFeatures = 0;
     mMDPUpscale = 0;
     mMDPDownscale = 0;
+    mMacroTileEnabled = false;
     mPanelType = NO_PANEL;
     mLowBw = 0;
     mHighBw = 0;
@@ -136,6 +156,14 @@
     memset(sysfsPath, 0, sizeof(sysfsPath));
     snprintf(sysfsPath , sizeof(sysfsPath),
             "/sys/class/graphics/fb0/mdp/caps");
+    char property[PROPERTY_VALUE_MAX];
+    bool enableMacroTile = false;
+
+    if((property_get("persist.hwc.macro_tile_enable", property, NULL) > 0) &&
+       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+        enableMacroTile = true;
+    }
 
     sysfsFd = fopen(sysfsPath, "rb");
 
@@ -185,6 +213,11 @@
                                     strlen("decimation"))) {
                            mFeatures |= MDP_DECIMATION_EN;
                         }
+                        else if(!strncmp(tokens[i], "tile_format",
+                                    strlen("tile_format"))) {
+                           if(enableMacroTile)
+                               mMacroTileEnabled = true;
+                        }
                     }
                 }
             }
@@ -239,10 +272,39 @@
     return mMDPDownscale;
 }
 
+uint32_t MDPVersion::getMaxMDPUpscale() {
+    return mMDPUpscale;
+}
+
 bool MDPVersion::supportsBWC() {
     // BWC - Bandwidth Compression
     return (mFeatures & MDP_BWC_EN);
 }
 
+bool MDPVersion::supportsMacroTile() {
+    // MACRO TILE support
+    return mMacroTileEnabled;
+}
+
+bool MDPVersion::is8x26() {
+    return (mMdpRev >= MDSS_MDP_HW_REV_101 and
+            mMdpRev < MDSS_MDP_HW_REV_102);
+}
+
+bool MDPVersion::is8x74v2() {
+    return (mMdpRev >= MDSS_MDP_HW_REV_102 and
+            mMdpRev < MDSS_MDP_HW_REV_103);
+}
+
+bool MDPVersion::is8084() {
+    return (mMdpRev >= MDSS_MDP_HW_REV_103 and
+            mMdpRev < MDSS_MDP_HW_REV_104);
+}
+
+bool MDPVersion::is8092() {
+    return (mMdpRev >= MDSS_MDP_HW_REV_200 and
+            mMdpRev < MDSS_MDP_HW_REV_206);
+}
+
 }; //namespace qdutils
 
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 60a2985..853b9f5 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -63,17 +63,6 @@
 //                                        0000   -  minor number
 // 8x26 v1 minor number is 0000
 //      v2 minor number is 0001 etc..
-enum mdp_rev {
-    MDSS_MDP_HW_REV_100 = 0x10000000, //8974 v1
-    MDSS_MDP_HW_REV_101 = 0x10010000, //8x26
-    MDSS_MDP_HW_REV_102 = 0x10020000, //8974 v2
-    MDSS_MDP_HW_REV_103 = 0x10030000, //8084
-    MDSS_MDP_HW_REV_104 = 0x10040000, //Next version
-    MDSS_MDP_HW_REV_105 = 0x10050000, //Next version
-    MDSS_MDP_HW_REV_107 = 0x10070000, //Next version
-    MDSS_MDP_HW_REV_200 = 0x20000000, //8092
-    MDSS_MDP_HW_REV_206 = 0x20060000, //Future
-};
 
 enum {
     MAX_DISPLAY_DIM = 2048,
@@ -117,28 +106,17 @@
     uint8_t getDMAPipes() { return mDMAPipes; }
     bool supportsDecimation();
     uint32_t getMaxMDPDownscale();
+    uint32_t getMaxMDPUpscale();
     bool supportsBWC();
+    bool supportsMacroTile();
     int getLeftSplit() { return mSplit.left(); }
     int getRightSplit() { return mSplit.right(); }
     unsigned long getLowBw() { return mLowBw; }
     unsigned long getHighBw() { return mHighBw; }
-
-    bool is8x26() {
-        return (mMdpRev >= MDSS_MDP_HW_REV_101 and
-                mMdpRev < MDSS_MDP_HW_REV_102);
-    }
-    bool is8x74v2() {
-        return (mMdpRev >= MDSS_MDP_HW_REV_102 and
-                mMdpRev < MDSS_MDP_HW_REV_103);
-    }
-    bool is8084() {
-        return (mMdpRev >= MDSS_MDP_HW_REV_103 and
-                mMdpRev < MDSS_MDP_HW_REV_104);
-    }
-    bool is8092() {
-        return (mMdpRev >= MDSS_MDP_HW_REV_200 and
-                mMdpRev < MDSS_MDP_HW_REV_206);
-    }
+    bool is8x26();
+    bool is8x74v2();
+    bool is8084();
+    bool is8092();
 
 private:
     bool updateSysFsInfo();
@@ -157,6 +135,7 @@
     uint32_t mFeatures;
     uint32_t mMDPDownscale;
     uint32_t mMDPUpscale;
+    bool mMacroTileEnabled;
     Split mSplit;
     unsigned long mLowBw; //kbps
     unsigned long mHighBw; //kbps
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index f8e58ab..33c3ca0 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are
  * retained for attribution purposes only.
@@ -49,6 +49,7 @@
         GET_DISPLAY_ATTRIBUTES,  // Get display attributes
         SET_HSIC_DATA,           // Set HSIC on dspp
         GET_DISPLAY_VISIBLE_REGION,  // Get the visibleRegion for dpy
+        PAUSE_WFD,               // Pause/Resume WFD
         VPU_COMMAND_LIST_START = 100, //Reserved block for VPU commands
         VPU_COMMAND_LIST_END   = 200,
         COMMAND_LIST_END = 400,
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
index 3d1adc0..2817429 100644
--- a/libqservice/QServiceUtils.h
+++ b/libqservice/QServiceUtils.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+* Copyright (c) 2013-14 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
@@ -83,4 +83,8 @@
     return sendSingleParam(qService::IQService::BUFFER_MIRRORMODE, enable);
 }
 
+inline android::status_t pauseWFD(uint32_t pause) {
+    return sendSingleParam(qService::IQService::PAUSE_WFD, pause);
+}
+
 #endif /* end of include guard: QSERVICEUTILS_H */