qdutils: Retrieve MDP revision and pipes information from driver.

Userspace can retrieve MDP revision number and number of different
types of MDP pipes (RGB,VG,DMA) information from driver. Add target
specific flag as previous MDP versions do not provide this support.

- Make use of this information while maintaining PipeBook.
- Move PipeBook related functions from overlay utils to PipeBook.

Change-Id: I46578bb27e515c4b9525d90b6619c11d7749914f
diff --git a/common.mk b/common.mk
index ecc2302..5ae6df9 100644
--- a/common.mk
+++ b/common.mk
@@ -27,6 +27,7 @@
 
 ifeq ($(call is-board-platform-in-list, msm8974 msm8226), true)
     common_flags += -DVENUS_COLOR_FORMAT
+    common_flags += -DMDSS_TARGET
 endif
 
 common_deps  :=
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 74ab9e0..11f7dc5 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -70,12 +70,13 @@
 void initContext(hwc_context_t *ctx)
 {
     openFramebufferDevice(ctx);
-    overlay::Overlay::initOverlay();
-    ctx->mOverlay = overlay::Overlay::getInstance();
-    ctx->mRotMgr = new RotMgr();
     ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
     ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
     ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
+    overlay::Overlay::initOverlay();
+    ctx->mOverlay = overlay::Overlay::getInstance();
+    ctx->mRotMgr = new RotMgr();
+
     //Is created and destroyed only once for primary
     //For external it could get created and destroyed multiple times depending
     //on what external we connect to.
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 5341c90..d22aedb 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+* Copyright (c) 2011-2013, 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
@@ -37,12 +37,7 @@
 using namespace utils;
 
 Overlay::Overlay() {
-    int numPipes = 0;
-    int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
-    if (mdpVersion > qdutils::MDP_V3_1) numPipes = 4;
-    if (mdpVersion >= qdutils::MDSS_V5) numPipes = 8;
-
-    PipeBook::NUM_PIPES = numPipes;
+    PipeBook::NUM_PIPES = qdutils::MDPVersion::getInstance().getTotalPipes();
     for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
         mPipeBook[i].init();
     }
@@ -74,8 +69,8 @@
             //fds
             if(mPipeBook[i].valid()) {
                 char str[32];
-                sprintf(str, "Unset pipe=%s dpy=%d; ", getDestStr((eDest)i),
-                        mPipeBook[i].mDisplay);
+                sprintf(str, "Unset pipe=%s dpy=%d; ",
+                        PipeBook::getDestStr((eDest)i), mPipeBook[i].mDisplay);
                 strncat(mDumpStr, str, strlen(str));
             }
             mPipeBook[i].destroy();
@@ -90,7 +85,7 @@
 
     for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
         //Match requested pipe type
-        if(type == OV_MDP_PIPE_ANY || type == getPipeType((eDest)i)) {
+        if(type == OV_MDP_PIPE_ANY || type == PipeBook::getPipeType((eDest)i)) {
             //If the pipe is not allocated to any display or used by the
             //requesting display already in previous round.
             if((mPipeBook[i].mDisplay == PipeBook::DPY_UNUSED ||
@@ -111,7 +106,8 @@
         if(not mPipeBook[index].valid()) {
             mPipeBook[index].mPipe = new GenericPipe(dpy);
             char str[32];
-            snprintf(str, 32, "Set pipe=%s dpy=%d; ", getDestStr(dest), dpy);
+            snprintf(str, 32, "Set pipe=%s dpy=%d; ",
+                     PipeBook::getDestStr(dest), dpy);
             strncat(mDumpStr, str, strlen(str));
         }
     } else {
@@ -183,13 +179,13 @@
     validate(index);
 
     PipeArgs newArgs(args);
-    if(dest == OV_VG0 || dest == OV_VG1) {
+    if(PipeBook::getPipeType(dest) == OV_MDP_PIPE_VG) {
         setMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE);
     } else {
         clearMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE);
     }
 
-    if(dest == OV_DMA0 || dest == OV_DMA1) {
+    if(PipeBook::getPipeType(dest) == OV_MDP_PIPE_DMA) {
         setMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_FORCE_DMA);
     } else {
         clearMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_FORCE_DMA);
@@ -205,10 +201,68 @@
     return sInstance;
 }
 
-void Overlay::initOverlay() {
-    if(utils::initOverlay() == -1) {
-        ALOGE("%s failed", __FUNCTION__);
+// Clears any VG pipes allocated to the fb devices
+// Generates a LUT for pipe types.
+int Overlay::initOverlay() {
+    int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
+    int numPipesXType[OV_MDP_PIPE_ANY] = {0};
+    numPipesXType[OV_MDP_PIPE_RGB] =
+            qdutils::MDPVersion::getInstance().getRGBPipes();
+    numPipesXType[OV_MDP_PIPE_VG] =
+            qdutils::MDPVersion::getInstance().getVGPipes();
+    numPipesXType[OV_MDP_PIPE_DMA] =
+            qdutils::MDPVersion::getInstance().getDMAPipes();
+
+    int index = 0;
+    for(int X = 0; X < (int)OV_MDP_PIPE_ANY; X++) { //iterate over types
+        for(int j = 0; j < numPipesXType[X]; j++) { //iterate over num
+            PipeBook::pipeTypeLUT[index] = (utils::eMdpPipeType)X;
+            index++;
+        }
     }
+
+    if (mdpVersion < qdutils::MDSS_V5) {
+        msmfb_mixer_info_req  req;
+        mdp_mixer_info *minfo = NULL;
+        char name[64];
+        int fd = -1;
+        for(int i = 0; i < NUM_FB_DEVICES; i++) {
+            snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
+            ALOGD("initoverlay:: opening the device:: %s", name);
+            fd = ::open(name, O_RDWR, 0);
+            if(fd < 0) {
+                ALOGE("cannot open framebuffer(%d)", i);
+                return -1;
+            }
+            //Get the mixer configuration */
+            req.mixer_num = i;
+            if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
+                ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
+                close(fd);
+                return -1;
+            }
+            minfo = req.info;
+            for (int j = 0; j < req.cnt; j++) {
+                ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
+                      minfo->z_order);
+                // except the RGB base layer with z_order of -1, clear any
+                // other pipes connected to mixer.
+                if((minfo->z_order) != -1) {
+                    int index = minfo->pndx;
+                    ALOGD("Unset overlay with index: %d at mixer %d", index, i);
+                    if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
+                        ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
+                        close(fd);
+                        return -1;
+                    }
+                }
+                minfo++;
+            }
+            close(fd);
+            fd = -1;
+        }
+    }
+    return 0;
 }
 
 void Overlay::dump() const {
@@ -254,5 +308,7 @@
 int Overlay::PipeBook::sPipeUsageBitmap = 0;
 int Overlay::PipeBook::sLastUsageBitmap = 0;
 int Overlay::PipeBook::sAllocatedBitmap = 0;
+utils::eMdpPipeType Overlay::PipeBook::pipeTypeLUT[utils::OV_MAX] =
+    {utils::OV_MDP_PIPE_ANY};
 
 }; // namespace overlay
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 0f15baa..aa12b76 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -68,7 +68,7 @@
     bool queueBuffer(int fd, uint32_t offset, utils::eDest dest);
 
     /* Closes open pipes, called during startup */
-    static void initOverlay();
+    static int initOverlay();
     /* Returns the singleton instance of overlay */
     static Overlay* getInstance();
     /* Returns available ("unallocated") pipes for a display */
@@ -116,7 +116,12 @@
         static bool isAllocated(int index);
         static bool isNotAllocated(int index);
 
+        static utils::eMdpPipeType getPipeType(utils::eDest dest);
+        static const char* getDestStr(utils::eDest dest);
+
         static int NUM_PIPES;
+        static utils::eMdpPipeType pipeTypeLUT[utils::OV_MAX];
+
 
     private:
         //usage tracks if a successful commit happened. So a pipe could be
@@ -146,7 +151,7 @@
     OVASSERT(index >=0 && index < PipeBook::NUM_PIPES, \
         "%s, Index out of bounds: %d", __FUNCTION__, index);
     OVASSERT(mPipeBook[index].valid(), "Pipe does not exist %s",
-            utils::getDestStr((utils::eDest)index));
+            PipeBook::getDestStr((utils::eDest)index));
 }
 
 inline int Overlay::availablePipes(int dpy) {
@@ -212,6 +217,20 @@
     return !isAllocated(index);
 }
 
+inline utils::eMdpPipeType Overlay::PipeBook::getPipeType(utils::eDest dest) {
+    return pipeTypeLUT[(int)dest];
+}
+
+inline const char* Overlay::PipeBook::getDestStr(utils::eDest dest) {
+    switch(getPipeType(dest)) {
+        case utils::OV_MDP_PIPE_RGB: return "RGB";
+        case utils::OV_MDP_PIPE_VG: return "VG";
+        case utils::OV_MDP_PIPE_DMA: return "DMA";
+        default: return "Invalid";
+    }
+    return "Invalid";
+}
+
 }; // overlay
 
 #endif // OVERLAY_H
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 907597e..4cc7a37 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -84,58 +84,6 @@
 
 
 namespace utils {
-//------------------ defines -----------------------------
-#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u"
-#define NUM_FB_DEVICES 3
-
-//--------------------------------------------------------
-
-/* clears any VG pipes allocated to the fb devices */
-int initOverlay() {
-    int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
-    if (mdpVersion < qdutils::MDSS_V5) {
-        msmfb_mixer_info_req  req;
-        mdp_mixer_info *minfo = NULL;
-        char name[64];
-        int fd = -1;
-        for(int i = 0; i < NUM_FB_DEVICES; i++) {
-            snprintf(name, 64, FB_DEVICE_TEMPLATE, i);
-            ALOGD("initoverlay:: opening the device:: %s", name);
-            fd = ::open(name, O_RDWR, 0);
-            if(fd < 0) {
-                ALOGE("cannot open framebuffer(%d)", i);
-                return -1;
-            }
-            //Get the mixer configuration */
-            req.mixer_num = i;
-            if (ioctl(fd, MSMFB_MIXER_INFO, &req) == -1) {
-                ALOGE("ERROR: MSMFB_MIXER_INFO ioctl failed");
-                close(fd);
-                return -1;
-            }
-            minfo = req.info;
-            for (int j = 0; j < req.cnt; j++) {
-                ALOGD("ndx=%d num=%d z_order=%d", minfo->pndx, minfo->pnum,
-                      minfo->z_order);
-                // except the RGB base layer with z_order of -1, clear any
-                // other pipes connected to mixer.
-                if((minfo->z_order) != -1) {
-                    int index = minfo->pndx;
-                    ALOGD("Unset overlay with index: %d at mixer %d", index, i);
-                    if(ioctl(fd, MSMFB_OVERLAY_UNSET, &index) == -1) {
-                        ALOGE("ERROR: MSMFB_OVERLAY_UNSET failed");
-                        close(fd);
-                        return -1;
-                    }
-                }
-                minfo++;
-            }
-            close(fd);
-            fd = -1;
-        }
-    }
-    return 0;
-}
 
 //--------------------------------------------------------
 //Refer to graphics.h, gralloc_priv.h, msm_mdp.h
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 555232a..5eb0e1e 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -77,6 +77,9 @@
 #define MDP_OV_PIPE_FORCE_DMA 0x4000
 #endif
 
+#define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u"
+#define NUM_FB_DEVICES 3
+
 namespace overlay {
 
 // fwd
@@ -127,11 +130,6 @@
 enum { BARRIER_LAND = 1,
     BARRIER_PORT = 2 };
 
-/* if SurfaceFlinger process gets killed in bypass mode, In initOverlay()
- * close all the pipes if it is opened after reboot.
- */
-int initOverlay(void);
-
 inline uint32_t format3D(uint32_t x) { return x & 0xFF000; }
 inline uint32_t format3DOutput(uint32_t x) {
     return (x & 0xF000) >> SHIFT_OUT_3D; }
@@ -274,24 +272,27 @@
 };
 
 enum eMdpPipeType {
-    OV_MDP_PIPE_RGB,
+    OV_MDP_PIPE_RGB = 0,
     OV_MDP_PIPE_VG,
     OV_MDP_PIPE_DMA,
     OV_MDP_PIPE_ANY, //Any
 };
 
-/* Used to identify destination pipes
- */
+// Identify destination pipes
+// TODO Names useless, replace with int and change all interfaces
 enum eDest {
-    OV_VG0 = 0,
-    OV_RGB0,
-    OV_VG1,
-    OV_RGB1,
-    OV_VG2,
-    OV_RGB2,
-    OV_DMA0,
-    OV_DMA1,
+    OV_P0 = 0,
+    OV_P1,
+    OV_P2,
+    OV_P3,
+    OV_P4,
+    OV_P5,
+    OV_P6,
+    OV_P7,
+    OV_P8,
+    OV_P9,
     OV_INVALID,
+    OV_MAX = OV_INVALID,
 };
 
 /* Used when a buffer is split over 2 pipes and sent to display */
@@ -350,6 +351,12 @@
     eRotFlags rotFlags;
 };
 
+// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time
+// of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define
+enum { HW_OV_MAGNIFICATION_LIMIT = 20,
+    HW_OV_MINIFICATION_LIMIT  = 8
+};
+
 inline void setMdpFlags(eMdpFlags& f, eMdpFlags v) {
     f = static_cast<eMdpFlags>(setBit(f, v));
 }
@@ -390,12 +397,6 @@
 int getMdpOrient(eTransform rotation);
 const char* getFormatString(int format);
 
-// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time
-// of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define
-enum { HW_OV_MAGNIFICATION_LIMIT = 20,
-    HW_OV_MINIFICATION_LIMIT  = 8
-};
-
 template <class T>
 inline void memset0(T& t) { ::memset(&t, 0, sizeof(T)); }
 
@@ -687,40 +688,6 @@
         value--;
 }
 
-inline const char* getDestStr(eDest dest) {
-    switch(dest) {
-        case OV_VG0: return "VG0";
-        case OV_RGB0: return "RGB0";
-        case OV_VG1: return "VG1";
-        case OV_RGB1: return "RGB1";
-        case OV_VG2: return "VG2";
-        case OV_RGB2: return "RGB2";
-        case OV_DMA0: return "DMA0";
-        case OV_DMA1: return "DMA1";
-        default: return "Invalid";
-    }
-    return "Invalid";
-}
-
-inline eMdpPipeType getPipeType(eDest dest) {
-    switch(dest) {
-        case OV_VG0:
-        case OV_VG1:
-        case OV_VG2:
-            return OV_MDP_PIPE_VG;
-        case OV_RGB0:
-        case OV_RGB1:
-        case OV_RGB2:
-            return OV_MDP_PIPE_RGB;
-        case OV_DMA0:
-        case OV_DMA1:
-            return OV_MDP_PIPE_DMA;
-        default:
-            return OV_MDP_PIPE_ANY;
-    }
-    return OV_MDP_PIPE_ANY;
-}
-
 void preRotateSource(eTransform& tr, Whf& whf, Dim& srcCrop);
 void getDump(char *buf, size_t len, const char *prefix, const mdp_overlay& ov);
 void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov);
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index 49f0927..cd21490 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 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
@@ -28,7 +28,9 @@
  */
 #include <cutils/log.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
 #include <linux/fb.h>
+#include <linux/msm_mdp.h>
 #include "mdp_version.h"
 
 ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::MDPVersion);
@@ -40,6 +42,11 @@
     int mdp_version = MDP_V_UNKNOWN;
     char panel_type = 0;
     struct fb_fix_screeninfo fb_finfo;
+
+    mMdpRev = 0;
+    mRGBPipes = mVGPipes = 0;
+    mDMAPipes = 0;
+
     if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fb_finfo) < 0) {
         ALOGE("FBIOGET_FSCREENINFO failed");
         mdp_version =  MDP_V_UNKNOWN;
@@ -57,8 +64,24 @@
             if (mdp_version < 100)
                 mdp_version *= 10;
 
+            mRGBPipes = mVGPipes = 2;
+
         } else if (!strncmp(fb_finfo.id, "mdssfb", 6)) {
             mdp_version = MDSS_V5;
+#ifdef MDSS_TARGET
+            struct msmfb_metadata metadata;
+            memset(&metadata, 0 , sizeof(metadata));
+            metadata.op = metadata_op_get_caps;
+            if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) {
+                ALOGE("Error retrieving MDP revision and pipes info");
+                mdp_version = MDP_V_UNKNOWN;
+            } else {
+                mMdpRev = metadata.data.caps.mdp_rev;
+                mRGBPipes = metadata.data.caps.rgb_pipes;
+                mVGPipes = metadata.data.caps.vig_pipes;
+                mDMAPipes = metadata.data.caps.dma_pipes;
+            }
+#endif
         } else {
             mdp_version = MDP_V_UNKNOWN;
         }
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 515d767..98de371 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 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
@@ -72,10 +72,18 @@
     int getMDPVersion() {return mMDPVersion;}
     char getPanelType() {return mPanelType;}
     bool hasOverlay() {return mHasOverlay;}
+    uint8_t getTotalPipes() { return (mRGBPipes + mVGPipes + mDMAPipes);}
+    uint8_t getRGBPipes() { return mRGBPipes; }
+    uint8_t getVGPipes() { return mVGPipes; }
+    uint8_t getDMAPipes() { return mDMAPipes; }
 private:
     int mMDPVersion;
     char mPanelType;
     bool mHasOverlay;
+    uint32_t mMdpRev;
+    uint8_t mRGBPipes;
+    uint8_t mVGPipes;
+    uint8_t mDMAPipes;
 };
 }; //namespace qdutils
 #endif //INCLUDE_LIBQCOMUTILS_MDPVER