Merge "libqservice: Correct enum declarations w.r.t. dyn_pu node value"
diff --git a/displayengine/include/core/display_interface.h b/displayengine/include/core/display_interface.h
index 782d8fc..c041e1a 100644
--- a/displayengine/include/core/display_interface.h
+++ b/displayengine/include/core/display_interface.h
@@ -63,8 +63,11 @@
 
   kStateOn,         //!< Display is ON. Contents are rendered in this state.
 
-  kStateDoze,       //!< Display is ON but not updating contents. Client shall not push any contents
-                    //!< in this state.
+  kStateDoze,       //!< Display is ON and it is configured in a low power state.
+
+  kStateDozeSuspend,
+                    //!< Display is ON in a low power state and continue showing its current
+                    //!< contents indefinitely until the mode changes.
 
   kStateStandby,    //!< Display is OFF. Client will continue to receive VSync events in this state
                     //!< if VSync is enabled. Contents are not rendered in this state.
diff --git a/displayengine/libs/core/display_base.cpp b/displayengine/libs/core/display_base.cpp
index a70a7c9..be3b3a8 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -292,6 +292,10 @@
     error = hw_intf_->Doze();
     break;
 
+  case kStateDozeSuspend:
+    error = hw_intf_->DozeSuspend();
+    break;
+
   case kStateStandby:
     error = hw_intf_->Standby();
     break;
diff --git a/displayengine/libs/core/fb/hw_device.cpp b/displayengine/libs/core/fb/hw_device.cpp
index a0a0fe2..685d322 100644
--- a/displayengine/libs/core/fb/hw_device.cpp
+++ b/displayengine/libs/core/fb/hw_device.cpp
@@ -183,6 +183,10 @@
   return kErrorNone;
 }
 
+DisplayError HWDevice::DozeSuspend() {
+  return kErrorNone;
+}
+
 DisplayError HWDevice::Standby() {
   return kErrorNone;
 }
diff --git a/displayengine/libs/core/fb/hw_device.h b/displayengine/libs/core/fb/hw_device.h
index c1dc99d..8dca6f9 100644
--- a/displayengine/libs/core/fb/hw_device.h
+++ b/displayengine/libs/core/fb/hw_device.h
@@ -57,6 +57,7 @@
   DisplayError PowerOn();
   DisplayError PowerOff();
   DisplayError Doze();
+  DisplayError DozeSuspend();
   DisplayError Standby();
   DisplayError Validate(HWLayers *hw_layers);
   DisplayError Commit(HWLayers *hw_layers);
diff --git a/displayengine/libs/core/fb/hw_hdmi.cpp b/displayengine/libs/core/fb/hw_hdmi.cpp
index d45a620..67fa2c6 100644
--- a/displayengine/libs/core/fb/hw_hdmi.cpp
+++ b/displayengine/libs/core/fb/hw_hdmi.cpp
@@ -314,6 +314,10 @@
   return HWDevice::Doze();
 }
 
+DisplayError HWHDMI::DozeSuspend() {
+  return HWDevice::DozeSuspend();
+}
+
 DisplayError HWHDMI::Standby() {
   return HWDevice::Standby();
 }
diff --git a/displayengine/libs/core/fb/hw_hdmi.h b/displayengine/libs/core/fb/hw_hdmi.h
index 8fc3c47..322e664 100644
--- a/displayengine/libs/core/fb/hw_hdmi.h
+++ b/displayengine/libs/core/fb/hw_hdmi.h
@@ -46,6 +46,7 @@
   virtual DisplayError PowerOn();
   virtual DisplayError PowerOff();
   virtual DisplayError Doze();
+  virtual DisplayError DozeSuspend();
   virtual DisplayError Standby();
   virtual DisplayError Validate(HWLayers *hw_layers);
   virtual DisplayError Commit(HWLayers *hw_layers);
diff --git a/displayengine/libs/core/fb/hw_primary.cpp b/displayengine/libs/core/fb/hw_primary.cpp
index 33f28bb..7b9cbe0 100644
--- a/displayengine/libs/core/fb/hw_primary.cpp
+++ b/displayengine/libs/core/fb/hw_primary.cpp
@@ -225,11 +225,26 @@
     IOCTL_LOGE(FB_BLANK_POWERDOWN, device_type_);
     return kErrorHardware;
   }
+
   return kErrorNone;
 }
 
 DisplayError HWPrimary::Doze() {
-  return HWDevice::Doze();
+  if (ioctl_(device_fd_, FBIOBLANK, FB_BLANK_NORMAL) < 0) {
+    IOCTL_LOGE(FB_BLANK_NORMAL, device_type_);
+    return kErrorHardware;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWPrimary::DozeSuspend() {
+  if (ioctl_(device_fd_, FBIOBLANK, FB_BLANK_VSYNC_SUSPEND) < 0) {
+    IOCTL_LOGE(FB_BLANK_VSYNC_SUSPEND, device_type_);
+    return kErrorHardware;
+  }
+
+  return kErrorNone;
 }
 
 DisplayError HWPrimary::Standby() {
diff --git a/displayengine/libs/core/fb/hw_primary.h b/displayengine/libs/core/fb/hw_primary.h
index 8d61d74..c41f387 100644
--- a/displayengine/libs/core/fb/hw_primary.h
+++ b/displayengine/libs/core/fb/hw_primary.h
@@ -46,6 +46,7 @@
   virtual DisplayError PowerOn();
   virtual DisplayError PowerOff();
   virtual DisplayError Doze();
+  virtual DisplayError DozeSuspend();
   virtual DisplayError Standby();
   virtual DisplayError Validate(HWLayers *hw_layers);
   virtual DisplayError Commit(HWLayers *hw_layers);
diff --git a/displayengine/libs/core/fb/hw_virtual.cpp b/displayengine/libs/core/fb/hw_virtual.cpp
index 81b31d0..374cc45 100644
--- a/displayengine/libs/core/fb/hw_virtual.cpp
+++ b/displayengine/libs/core/fb/hw_virtual.cpp
@@ -110,6 +110,10 @@
   return HWDevice::Doze();
 }
 
+DisplayError HWVirtual::DozeSuspend() {
+  return HWDevice::DozeSuspend();
+}
+
 DisplayError HWVirtual::Standby() {
   return HWDevice::Standby();
 }
diff --git a/displayengine/libs/core/fb/hw_virtual.h b/displayengine/libs/core/fb/hw_virtual.h
index fb7c784..509f1c5 100644
--- a/displayengine/libs/core/fb/hw_virtual.h
+++ b/displayengine/libs/core/fb/hw_virtual.h
@@ -46,6 +46,7 @@
   virtual DisplayError PowerOn();
   virtual DisplayError PowerOff();
   virtual DisplayError Doze();
+  virtual DisplayError DozeSuspend();
   virtual DisplayError Standby();
   virtual DisplayError Validate(HWLayers *hw_layers);
   virtual DisplayError Commit(HWLayers *hw_layers);
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index 8cd608e..09fb6a9 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -141,6 +141,7 @@
   virtual DisplayError PowerOn() = 0;
   virtual DisplayError PowerOff() = 0;
   virtual DisplayError Doze() = 0;
+  virtual DisplayError DozeSuspend() = 0;
   virtual DisplayError Standby() = 0;
   virtual DisplayError Validate(HWLayers *hw_layers) = 0;
   virtual DisplayError Commit(HWLayers *hw_layers) = 0;
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index 8d7e94a..124310a 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -109,10 +109,13 @@
     last_power_mode_ = HWC_POWER_MODE_NORMAL;
     break;
   case HWC_POWER_MODE_DOZE:
-  case HWC_POWER_MODE_DOZE_SUSPEND:
     state = kStateDoze;
     last_power_mode_ = HWC_POWER_MODE_DOZE;
     break;
+  case HWC_POWER_MODE_DOZE_SUSPEND:
+    state = kStateDozeSuspend;
+    last_power_mode_ = HWC_POWER_MODE_DOZE_SUSPEND;
+    break;
   default:
     return -EINVAL;
   }
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 4f342db..3e17061 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -49,6 +49,17 @@
 
 #define ASTC_BLOCK_SIZE 16
 
+#ifdef ION_FLAG_CP_PIXEL
+#define CP_HEAP_ID ION_SECURE_HEAP_ID
+#else
+#define ION_FLAG_CP_PIXEL 0
+#define CP_HEAP_ID ION_CP_MM_HEAP_ID
+#endif
+
+#ifndef ION_FLAG_ALLOW_NON_CONTIG
+#define ION_FLAG_ALLOW_NON_CONTIG 0
+#endif
+
 using namespace gralloc;
 using namespace qdutils;
 
@@ -334,13 +345,22 @@
 
     if(usage & GRALLOC_USAGE_PROTECTED) {
         if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
-            ionHeapId |= ION_HEAP(ION_CP_MM_HEAP_ID);
+            ionHeapId = ION_HEAP(CP_HEAP_ID);
             ionFlags |= ION_SECURE;
-#ifdef ION_FLAG_ALLOW_NON_CONTIG
+            if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+                /*
+                 * There is currently no flag in ION for Secure Display
+                 * VM. Please add it here once available.
+                 *
+                   ionFlags |= <Ion flag for Secure Display>;
+                */
+            } else {
+                ionFlags |= ION_FLAG_CP_PIXEL;
+            }
+
             if (!(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
                 ionFlags |= ION_FLAG_ALLOW_NON_CONTIG;
             }
-#endif
         } else {
             // for targets/OEMs which do not need HW level protection
             // do not set ion secure flag & MM heap. Fallback to system heap.
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 9be93d6..a6f7874 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -26,10 +26,19 @@
 #include "memalloc.h"
 #include "alloc_controller.h"
 #include <qdMetaData.h>
+#include <linux/msm_ion.h>
 
 using namespace gralloc;
 
+#define SZ_2M 0x200000
 #define SZ_1M 0x100000
+#define SZ_4K 0x1000
+
+#ifdef ION_FLAG_CP_PIXEL
+#define SECURE_ALIGN SZ_4K
+#else
+#define SECURE_ALIGN SZ_1M
+#endif
 
 gpu_context_t::gpu_context_t(const private_module_t* module,
                              IAllocController* alloc_ctrl ) :
@@ -64,10 +73,14 @@
     else
         data.align = getpagesize();
 
-    /* force 1MB alignment selectively for secure buffers, MDP5 onwards */
     if ((usage & GRALLOC_USAGE_PROTECTED) &&
         (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)) {
-        data.align = ALIGN((int) data.align, SZ_1M);
+            if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+                /* The alignment here reflects qsee mmu V7L/V8L requirement */
+                data.align = SZ_2M;
+            } else {
+                data.align = SECURE_ALIGN;
+            }
         size = ALIGN(size, data.align);
     }
 
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 7423c29..1fa40ce 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -623,7 +623,8 @@
             supported |= HWC_DISPLAY_VIRTUAL_BIT;
             if(!(qdutils::MDPVersion::getInstance().is8x26() ||
                         qdutils::MDPVersion::getInstance().is8x16() ||
-                        qdutils::MDPVersion::getInstance().is8x39()))
+                        qdutils::MDPVersion::getInstance().is8x39() ||
+                        qdutils::MDPVersion::getInstance().is8x52()))
                 supported |= HWC_DISPLAY_EXTERNAL_BIT;
         }
         value[0] = supported;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index fdd7f0f..3743a8b 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -177,10 +177,11 @@
 
     bool defaultPTOR = false;
     //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
-    //8x16 and 8x39 targets by default
+    //Bear family targets by default
     if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
             (qdutils::MDPVersion::getInstance().is8x16() ||
-                qdutils::MDPVersion::getInstance().is8x39())) {
+             qdutils::MDPVersion::getInstance().is8x39() ||
+             qdutils::MDPVersion::getInstance().is8x52())) {
         defaultPTOR = true;
     }
 
@@ -532,7 +533,8 @@
         ret = false;
     } else if((qdutils::MDPVersion::getInstance().is8x26() ||
                qdutils::MDPVersion::getInstance().is8x16() ||
-               qdutils::MDPVersion::getInstance().is8x39()) &&
+               qdutils::MDPVersion::getInstance().is8x39() ||
+               qdutils::MDPVersion::getInstance().is8x52()) &&
             ctx->mVideoTransFlag &&
             isSecondaryConnected(ctx)) {
         //1 Padding round to shift pipes across mixers
@@ -541,7 +543,8 @@
         ret = false;
     } else if((qdutils::MDPVersion::getInstance().is8x26() ||
                qdutils::MDPVersion::getInstance().is8x16() ||
-               qdutils::MDPVersion::getInstance().is8x39()) &&
+               qdutils::MDPVersion::getInstance().is8x39() ||
+               qdutils::MDPVersion::getInstance().is8x52()) &&
               !mDpy && isSecondaryAnimating(ctx) &&
               isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
         ALOGD_IF(isDebug(),"%s: Display animation in progress",
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 2f5aed0..aeda428 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -554,7 +554,37 @@
     }
 }
 
-//Helper to roundoff the refreshrates
+uint32_t getRefreshRate(hwc_context_t* ctx, uint32_t requestedRefreshRate) {
+
+    qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
+    int dpy = HWC_DISPLAY_PRIMARY;
+    uint32_t defaultRefreshRate = ctx->dpyAttr[dpy].refreshRate;
+    uint32_t rate = defaultRefreshRate;
+
+    if(!requestedRefreshRate)
+        return defaultRefreshRate;
+
+    uint32_t maxNumIterations =
+            (uint32_t)ceil(
+                    (float)mdpHw.getMaxFpsSupported()/
+                    (float)requestedRefreshRate);
+
+    for(uint32_t i = 1; i <= maxNumIterations; i++) {
+        rate = roundOff(i * requestedRefreshRate);
+        if(rate < mdpHw.getMinFpsSupported()) {
+            continue;
+        } else if((rate >= mdpHw.getMinFpsSupported() &&
+                   rate <= mdpHw.getMaxFpsSupported())) {
+            break;
+        } else {
+            rate = defaultRefreshRate;
+            break;
+        }
+    }
+    return rate;
+}
+
+//Helper to roundoff the refreshrates to the std refresh-rates
 uint32_t roundOff(uint32_t refreshRate) {
     int count =  (int) (sizeof(stdRefreshRates)/sizeof(stdRefreshRates[0]));
     uint32_t rate = refreshRate;
@@ -1175,21 +1205,18 @@
 
 #ifdef DYNAMIC_FPS
         if (!dpy && mdpHw.isDynFpsSupported() && ctx->mUseMetaDataRefreshRate){
-            //dyn fps: get refreshrate from metadata
-            //Support multiple refresh rates if they are same
-            //else set to  default
+            /* Dyn fps: get refreshrate from metadata */
             MetaData_t *mdata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
             if (mdata && (mdata->operation & UPDATE_REFRESH_RATE)) {
                 // Valid refreshRate in metadata and within the range
-                uint32_t rate = roundOff(mdata->refreshrate);
-                if((rate >= mdpHw.getMinFpsSupported() &&
-                                rate <= mdpHw.getMaxFpsSupported())) {
-                    if (!refreshRate) {
-                        refreshRate = rate;
-                    } else if(refreshRate != rate) {
-                        // multiple refreshrate requests, set to default
-                        refreshRate = ctx->dpyAttr[dpy].refreshRate;
-                    }
+                uint32_t rate = getRefreshRate(ctx, mdata->refreshrate);
+                if (!refreshRate) {
+                    refreshRate = rate;
+                } else if(refreshRate != rate) {
+                    /* Support multiple refresh rates if they are same
+                     * else set to default.
+                     */
+                    refreshRate = ctx->dpyAttr[dpy].refreshRate;
                 }
             }
         }
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index a74d59a..da0182b 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -352,6 +352,8 @@
 void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
                                 hwc_rect_t& inRect, hwc_rect_t& outRect);
 
+uint32_t getRefreshRate(hwc_context_t* ctx, uint32_t requestedRefreshRate);
+
 uint32_t roundOff(uint32_t refreshRate);
 
 void setRefreshRate(hwc_context_t *ctx, int dpy, uint32_t refreshRate);
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index b7c7fcc..113bd48 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -149,6 +149,8 @@
         return getPipe_8x16(pipeSpecs);
     } else if(MDPVersion::getInstance().is8x39()) {
         return getPipe_8x39(pipeSpecs);
+    } else if(MDPVersion::getInstance().is8x52()) {
+        return getPipe_8x52(pipeSpecs);
     } else if(MDPVersion::getInstance().is8994()) {
         return getPipe_8994(pipeSpecs);
     } else if(MDPVersion::getInstance().is8992()) {
@@ -247,6 +249,12 @@
     return getPipe_8x16(pipeSpecs);
 }
 
+utils::eDest Overlay::getPipe_8x52(const PipeSpecs& pipeSpecs) {
+    //8x16 & 8x52 has same number of pipes, pipe-types & scaling capabilities.
+    //Rely on 8x16 until we see a need to change.
+    return getPipe_8x16(pipeSpecs);
+}
+
 utils::eDest Overlay::getPipe_8994(const PipeSpecs& pipeSpecs) {
     //If DMA pipes need to be used in block mode for downscale, there could be
     //cases where consecutive rounds need separate modes, which cannot be
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 49be930..2782fc2 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -177,6 +177,7 @@
     utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs);
     utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs);
     utils::eDest getPipe_8x39(const PipeSpecs& pipeSpecs);
+    utils::eDest getPipe_8x52(const PipeSpecs& pipeSpecs);
     utils::eDest getPipe_8994(const PipeSpecs& pipeSpecs);
     utils::eDest getPipe_8992(const PipeSpecs& pipeSpecs);
 
@@ -344,7 +345,8 @@
 inline bool Overlay::isUIScalingOnExternalSupported() {
     if(qdutils::MDPVersion::getInstance().is8x26() or
        qdutils::MDPVersion::getInstance().is8x16() or
-       qdutils::MDPVersion::getInstance().is8x39()) {
+       qdutils::MDPVersion::getInstance().is8x39() or
+       qdutils::MDPVersion::getInstance().is8x52()) {
         return false;
     }
     return true;
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index c02e28d..f62f3d0 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -77,6 +77,15 @@
 #ifndef MDSS_MDP_HW_REV_110
 #define MDSS_MDP_HW_REV_110 0x100a0000 //8992
 #endif
+#ifndef MDSS_MDP_HW_REV_111
+#define MDSS_MDP_HW_REV_111 0x100b0000 //Unused or Next version
+#endif
+#ifndef MDSS_MDP_HW_REV_112
+#define MDSS_MDP_HW_REV_112 0x100c0000 // 8x52
+#endif
+#ifndef MDSS_MDP_HW_REV_113
+#define MDSS_MDP_HW_REV_113 0x100d0000 //Unused Next version
+#endif
 #ifndef MDSS_MDP_HW_REV_200
 #define MDSS_MDP_HW_REV_200 0x20000000 //8092
 #endif
@@ -516,5 +525,10 @@
             mMdpRev < MDSS_MDP_HW_REV_200));
 }
 
+bool MDPVersion::is8x52() {
+    return (mMdpRev >= MDSS_MDP_HW_REV_112 and
+            mMdpRev < MDSS_MDP_HW_REV_113);
+}
+
 }; //namespace qdutils
 
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 6ebe558..25356f8 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -153,6 +153,7 @@
     bool is8994();
     bool is8x16();
     bool is8x39();
+    bool is8x52();
     bool is8992();
     bool updateSplitInfo();