Merge "Hardware keymaster HAL should not indicate 'software'"
diff --git a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.c b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.c
index fac8d52..e0f19aa 100644
--- a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.c
+++ b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Basecomponent.c
@@ -191,6 +191,7 @@
     if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) {
         ret = Exynos_OMX_Get_Resource(pOMXComponent);
         if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent);
             goto EXIT;
         }
     }
diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c
index 495fcae..3a831f0 100644
--- a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c
+++ b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c
@@ -1524,6 +1524,7 @@
     if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
         pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
         csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER);
         csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, pVideoDec->bDRMPlayerMode);
     } else {
         pVideoDec->csc_handle = csc_init(csc_method);
diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/enc/Android.mk
index 7c1c436..2435e0f 100644
--- a/exynos_omx/openmax/exynos_omx/component/video/enc/Android.mk
+++ b/exynos_omx/openmax/exynos_omx/component/video/enc/Android.mk
@@ -9,6 +9,8 @@
 LOCAL_ARM_MODE := arm
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_CFLAGS := -DUSE_CSC_G2D
+
 LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \
 	$(EXYNOS_OMX_INC)/exynos \
 	$(EXYNOS_OMX_TOP)/osal \
diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c b/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c
index b3b2eb9..22efe36 100644
--- a/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c
+++ b/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c
@@ -104,6 +104,8 @@
 
     pData->buffer.multiPlaneBuffer.dataBuffer[0] = pInputCodecBuffer->pVirAddr[0];
     pData->buffer.multiPlaneBuffer.dataBuffer[1] = pInputCodecBuffer->pVirAddr[1];
+    pData->buffer.multiPlaneBuffer.fd[0] = pInputCodecBuffer->fd[0];
+    pData->buffer.multiPlaneBuffer.fd[1] = pInputCodecBuffer->fd[1];
     pData->allocSize     = pInputCodecBuffer->bufferSize[0] + pInputCodecBuffer->bufferSize[1];
     pData->dataLen       = pInputCodecBuffer->dataSize;
     pData->usedDataLen   = 0;
@@ -189,8 +191,10 @@
     CSC_METHOD csc_method = CSC_METHOD_SW;
     unsigned int cacheable = 1;
 
-    unsigned char *pSrcBuf[3] = {NULL, };
-    unsigned char *pDstBuf[3] = {NULL, };
+    void *pSrcBuf[3] = {NULL, };
+    void *pSrcFd[3] = {NULL, };
+    void *pDstBuf[3] = {NULL, };
+    void *pDstFd[3] = {NULL, };
 
     CSC_ERRORCODE cscRet = CSC_ErrorNone;
 
@@ -202,13 +206,6 @@
     pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
     pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[2];
 
-    csc_get_method(pVideoEnc->csc_handle, &csc_method);
-    if (csc_method == CSC_METHOD_HW) {
-        pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.fd[0];
-        pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.fd[1];
-        pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.fd[2];
-    }
-
 #ifdef USE_METADATABUFFERTYPE
     OMX_PTR ppBuf[MAX_BUFFER_PLANE];
 
@@ -221,28 +218,21 @@
         Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf);
         if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
             ExynosVideoPlane planes[MAX_BUFFER_PLANE];
-            OMX_U32 stride;
-            int imageSize;
+            size_t i;
 
             Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, planes);
-            imageSize = nFrameWidth * nFrameHeight * 3; /* RGB888 */
 
-            if (csc_method == CSC_METHOD_HW)
-                pSrcBuf[0]  = (unsigned char *)planes[0].fd;
-            else
-                pSrcBuf[0] = planes[0].addr;
-            pSrcBuf[1]  = NULL;
-            pSrcBuf[2]  = NULL;
+#if defined(USE_CSC_GSCALER) || defined(USE_CSC_G2D)
+            csc_method = CSC_METHOD_HW;
+#endif
+            pSrcBuf[0] = planes[0].addr;
+            pSrcFd[0] = (void *)planes[0].fd;
+            for (i = 0; i < 3; i++)
+                pDstFd[i] = (void *)srcInputData->buffer.multiPlaneBuffer.fd[i];
         }
     } else
 #endif
     {
-        if (csc_method == CSC_METHOD_HW) {
-            pSrcBuf[0]  = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, checkInputStream);
-            pSrcBuf[1]  = NULL;
-            pSrcBuf[2]  = NULL;
-        }
-
         switch (eColorFormat) {
         case OMX_COLOR_FormatYUV420Planar:
             /* YUV420Planar converted to YUV420Semiplanar (interleaved UV plane) as per MFC spec.*/
@@ -261,6 +251,9 @@
         }
     }
 
+    csc_set_method(
+        pVideoEnc->csc_handle,
+        csc_method);
     csc_set_src_format(
         pVideoEnc->csc_handle,  /* handle */
         nFrameWidth,                  /* width */
@@ -281,12 +274,21 @@
         nFrameHeight,                 /* crop_height */
         csc_dst_color_format,   /* color_format */
         cacheable);             /* cacheable */
-    csc_set_src_buffer(
-        pVideoEnc->csc_handle,  /* handle */
-        pSrcBuf);               /* YUV Addr or FD */
-    csc_set_dst_buffer(
-        pVideoEnc->csc_handle,  /* handle */
-        pDstBuf);               /* YUV Addr or FD */
+    if (csc_method == CSC_METHOD_SW) {
+        csc_set_src_buffer(
+            pVideoEnc->csc_handle,  /* handle */
+            pSrcBuf);
+        csc_set_dst_buffer(
+            pVideoEnc->csc_handle,  /* handle */
+            pDstBuf);
+    } else {
+        csc_set_src_buffer(
+            pVideoEnc->csc_handle,  /* handle */
+            pSrcFd);
+        csc_set_dst_buffer(
+            pVideoEnc->csc_handle,  /* handle */
+            pDstFd);
+    }
     cscRet = csc_convert(pVideoEnc->csc_handle);
     if (cscRet != CSC_ErrorNone)
         ret = OMX_FALSE;
@@ -299,8 +301,6 @@
     }
 #endif
 
-    ret = OMX_TRUE;
-
 EXIT:
     FunctionOut();
 
@@ -403,18 +403,24 @@
             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
 
             if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
-                Exynos_CSC_InputData(pOMXComponent, srcInputData);
+                ret = Exynos_CSC_InputData(pOMXComponent, srcInputData);
+                if (ret) {
+                    inputUseBuffer->dataLen -= copySize;
+                    inputUseBuffer->remainDataLen -= copySize;
+                    inputUseBuffer->usedDataLen += copySize;
 
-                inputUseBuffer->dataLen -= copySize;
-                inputUseBuffer->remainDataLen -= copySize;
-                inputUseBuffer->usedDataLen += copySize;
+                    srcInputData->dataLen += copySize;
+                    srcInputData->remainDataLen += copySize;
 
-                srcInputData->dataLen += copySize;
-                srcInputData->remainDataLen += copySize;
-
-                srcInputData->timeStamp = inputUseBuffer->timeStamp;
-                srcInputData->nFlags = inputUseBuffer->nFlags;
-                srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
+                    srcInputData->timeStamp = inputUseBuffer->timeStamp;
+                    srcInputData->nFlags = inputUseBuffer->nFlags;
+                    srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
+                } else {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_CSC_InputData() failure");
+                    pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                            pExynosComponent->callbackData, OMX_EventError,
+                            OMX_ErrorUndefined, 0, NULL );
+                }
             } else {
                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
                 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
@@ -589,9 +595,9 @@
                     pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1;
                     pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0;
 
-                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
-                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
-                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
+                    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+                    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+                    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
 
                     Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
                 }
@@ -1085,6 +1091,8 @@
     EXYNOS_OMX_BASEPORT           *pExynosPort = NULL;
     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
 
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+
     FunctionIn();
 
     if (hComponent == NULL) {
@@ -1133,6 +1141,24 @@
     pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter
     pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter
 
+    pVideoEnc->csc_handle = csc_init(csc_method);
+    if (pVideoEnc->csc_handle == NULL) {
+        Exynos_OSAL_Free(pVideoEnc);
+        Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+        goto EXIT;
+    }
+    pVideoEnc->csc_set_format = OMX_FALSE;
+#if defined(USE_CSC_GSCALER) && defined(USE_CSC_G2D)
+#error USE_CSC_GSCALER and USE_CSC_G2D are mutually exclusive
+#elif defined(USE_CSC_GSCALER)
+    csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, CSC_GSCALER_IDX);
+    csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER);
+#elif defined(USE_CSC_G2D)
+    csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_G2D);
+#endif
+
     pExynosComponent->bMultiThreadProcess = OMX_TRUE;
 
     /* Input port */
@@ -1229,6 +1255,11 @@
 
     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
 
+    if (pVideoEnc->csc_handle != NULL) {
+        csc_deinit(pVideoEnc->csc_handle);
+        pVideoEnc->csc_handle = NULL;
+    }
+
     Exynos_OSAL_Free(pVideoEnc);
     pExynosComponent->hComponentHandle = pVideoEnc = NULL;
 
diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c b/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c
index d25503d..0806f03 100644
--- a/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c
+++ b/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c
@@ -1533,7 +1533,6 @@
     ExynosVideoEncBufferOps *pInbufOps  = NULL;
     ExynosVideoEncBufferOps *pOutbufOps = NULL;
 
-    CSC_METHOD csc_method = CSC_METHOD_SW;
     int i = 0;
 
     FunctionIn();
@@ -1596,9 +1595,9 @@
                 pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1;
                 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0;
 
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
 
                 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
             }
@@ -1632,16 +1631,6 @@
 
     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
 
-#if 0//defined(USE_CSC_GSCALER)
-    csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
-#endif
-    pVideoEnc->csc_handle = csc_init(csc_method);
-    if (pVideoEnc->csc_handle == NULL) {
-        ret = OMX_ErrorInsufficientResources;
-        goto EXIT;
-    }
-    pVideoEnc->csc_set_format = OMX_FALSE;
-
 EXIT:
     FunctionOut();
 
@@ -1667,11 +1656,6 @@
 
     FunctionIn();
 
-    if (pVideoEnc->csc_handle != NULL) {
-        csc_deinit(pVideoEnc->csc_handle);
-        pVideoEnc->csc_handle = NULL;
-    }
-
     Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent);
     pH264Enc->hDestinationStartEvent = NULL;
     pH264Enc->bDestinationStart = OMX_FALSE;
diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c b/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c
index f58ee45..c6bafc4 100644
--- a/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c
+++ b/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c
@@ -1749,7 +1749,6 @@
     ExynosVideoEncBufferOps *pInbufOps  = NULL;
     ExynosVideoEncBufferOps *pOutbufOps = NULL;
 
-    CSC_METHOD csc_method = CSC_METHOD_SW;
     int i = 0;
 
     FunctionIn();
@@ -1812,9 +1811,9 @@
                 pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1;
                 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0;
 
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
 
                 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
             }
@@ -1848,16 +1847,6 @@
 
     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
 
-#if 0//defined(USE_CSC_GSCALER)
-    csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
-#endif
-    pVideoEnc->csc_handle = csc_init(csc_method);
-    if (pVideoEnc->csc_handle == NULL) {
-        ret = OMX_ErrorInsufficientResources;
-        goto EXIT;
-    }
-    pVideoEnc->csc_set_format = OMX_FALSE;
-
 EXIT:
     FunctionOut();
 
@@ -1883,11 +1872,6 @@
 
     FunctionIn();
 
-    if (pVideoEnc->csc_handle != NULL) {
-        csc_deinit(pVideoEnc->csc_handle);
-        pVideoEnc->csc_handle = NULL;
-    }
-
     Exynos_OSAL_SignalTerminate(pMpeg4Enc->hDestinationStartEvent);
     pMpeg4Enc->hDestinationStartEvent = NULL;
     pMpeg4Enc->bDestinationStart = OMX_FALSE;
diff --git a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp
index 142580c..b4fa5f2 100644
--- a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp
+++ b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp
@@ -612,7 +612,7 @@
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
         omx_format = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
         break;
-    case HAL_PIXEL_FORMAT_ARGB888:
+    case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
         omx_format = OMX_COLOR_Format32bitARGB8888;
         break;
     default:
@@ -643,7 +643,7 @@
         hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
         break;
     case OMX_COLOR_Format32bitARGB8888:
-        hal_format = HAL_PIXEL_FORMAT_ARGB888;
+        hal_format = HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888;
         break;
     default:
         hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P;
diff --git a/gralloc/framebuffer.cpp b/gralloc/framebuffer.cpp
index c1d4ce9..ce409ce 100644
--- a/gralloc/framebuffer.cpp
+++ b/gralloc/framebuffer.cpp
@@ -105,6 +105,52 @@
     return 0;
 }
 
+static void get_screen_res(const char *fbname, int32_t *xres, int32_t *yres,
+                           int32_t *refresh)
+{
+    char *path;
+    int fd;
+    char buf[128];
+    int ret;
+    unsigned int _x, _y, _r;
+
+    asprintf(&path, "/sys/class/graphics/%s/modes", fbname);
+    if (!path)
+        goto err_asprintf;
+    fd = open(path, O_RDONLY);
+    if (fd < 0)
+        goto err_open;
+    ret = read(fd, buf, sizeof(buf));
+    if (ret <= 0)
+        goto err_read;
+    buf[sizeof(buf)-1] = '\0';
+
+    ret = sscanf(buf, "U:%ux%up-%u", &_x, &_y, &_r);
+    if (ret != 3)
+        goto err_sscanf;
+
+    ALOGI("Using %ux%u %uHz resolution for '%s' from modes list\n",
+          _x, _y, _r, fbname);
+
+    *xres = (int32_t)_x;
+    *yres = (int32_t)_y;
+    *refresh = (int32_t)_r;
+
+    close(fd);
+    free(path);
+    return;
+
+err_sscanf:
+err_read:
+    close(fd);
+err_open:
+    free(path);
+err_asprintf:
+    *xres = 2560;
+    *yres = 1600;
+    *refresh = 60;
+}
+
 int init_fb(struct private_module_t* module)
 {
     char const * const device_template[] = {
@@ -135,19 +181,13 @@
         return -errno;
     }
 
-    int refreshRate = 1000000000000000LLU /
-        (
-         uint64_t( info.upper_margin + info.lower_margin + info.yres )
-         * ( info.left_margin  + info.right_margin + info.xres )
-         * info.pixclock
-        );
-
+    int32_t refreshRate;
+    get_screen_res("fb0", &module->xres, &module->yres, &refreshRate);
     if (refreshRate == 0)
-        refreshRate = 60*1000;  /* 60 Hz */
+        refreshRate = 60;  /* 60 Hz */
 
-    float xdpi = (info.xres * 25.4f) / info.width;
-    float ydpi = (info.yres * 25.4f) / info.height;
-    float fps  = refreshRate / 1000.0f;
+    float xdpi = (module->xres * 25.4f) / info.width;
+    float ydpi = (module->yres * 25.4f) / info.height;
 
     ALOGI("using (id=%s)\n"
           "xres         = %d px\n"
@@ -155,15 +195,13 @@
           "width        = %d mm (%f dpi)\n"
           "height       = %d mm (%f dpi)\n"
           "refresh rate = %.2f Hz\n",
-          finfo.id, info.xres, info.yres, info.width,  xdpi, info.height, ydpi,
-          fps);
+          finfo.id, module->xres, module->yres, info.width,  xdpi, info.height,
+          ydpi, (float)refreshRate);
 
-    module->xres = 2560;
-    module->yres = 1600;
-    module->line_length = 2560;
+    module->line_length = module->xres * 4;
     module->xdpi = xdpi;
     module->ydpi = ydpi;
-    module->fps = fps;
+    module->fps = (float)refreshRate;
 
     return 0;
 }
diff --git a/gralloc/gralloc.cpp b/gralloc/gralloc.cpp
index f3610f3..83a2407 100644
--- a/gralloc/gralloc.cpp
+++ b/gralloc/gralloc.cpp
@@ -44,10 +44,13 @@
 #include "exynos_format.h"
 #include "gr.h"
 
-#define ION_HEAP_EXYNOS_CONTIG_MASK     (1 << 4)
+#define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4)
 #define ION_EXYNOS_FIMD_VIDEO_MASK  (1 << 28)
 #define ION_EXYNOS_MFC_OUTPUT_MASK  (1 << 26)
 #define ION_EXYNOS_MFC_INPUT_MASK   (1 << 25)
+#define ION_HEAP_SYSTEM_ID          0
+#define ION_HEAP_EXYNOS_CONTIG_ID   4
+#define ION_HEAP_CHUNK_ID           6
 #define MB_1 (1024*1024)
 
 
@@ -121,9 +124,9 @@
     unsigned int heap_mask;
 
     if (usage & GRALLOC_USAGE_PROTECTED)
-        heap_mask = ION_HEAP_EXYNOS_CONTIG_MASK;
+        heap_mask = (1 << ION_HEAP_EXYNOS_CONTIG_ID);
     else
-        heap_mask = ION_HEAP_SYSTEM_MASK;
+        heap_mask = (1 << ION_HEAP_SYSTEM_ID) | (1 << ION_HEAP_CHUNK_ID);
 
     return heap_mask;
 }
@@ -189,6 +192,7 @@
 {
     size_t size;
     int err, fd;
+    unsigned int heap_mask = _select_heap(usage);
 
     switch (format) {
         case HAL_PIXEL_FORMAT_YV12:
@@ -204,8 +208,7 @@
             return -EINVAL;
     }
 
-    err = ion_alloc_fd(ionfd, size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
-                       ion_flags, &fd);
+    err = ion_alloc_fd(ionfd, size, 0, heap_mask, ion_flags, &fd);
     if (err)
         return err;
 
diff --git a/include/exynos_format.h b/include/exynos_format.h
index f4c0466..01c4657 100644
--- a/include/exynos_format.h
+++ b/include/exynos_format.h
@@ -30,7 +30,7 @@
     HAL_PIXEL_FORMAT_YCbCr_420_SP               = 0x105,
     HAL_PIXEL_FORMAT_YCrCb_422_SP               = 0x106,
     HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED         = 0x107,
-    HAL_PIXEL_FORMAT_ARGB888                    = 0x108,
+    HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888           = 0x108,
     // support custom format for zero copy
     HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP        = 0x110,
     HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP        = 0x111,
@@ -48,6 +48,15 @@
     HAL_PIXEL_FORMAT_CUSTOM_MAX
 };
 
+// Colorspace Gamuts
+enum {
+    HAL_PIXEL_GAMUT_DEFAULT = 0,
+    // Values range 0-255
+    HAL_PIXEL_GAMUT_JFIF_8,
+    // Values range 16-235
+    HAL_PIXEL_GAMUT_BT601_8
+};
+
 struct ADDRS {
     unsigned int addr_y;
     unsigned int addr_cbcr;
diff --git a/include/fimg2d.h b/include/fimg2d.h
new file mode 100644
index 0000000..59da4a6
--- /dev/null
+++ b/include/fimg2d.h
@@ -0,0 +1,262 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __FIMG2D_H
+#define __FIMG2D_H __FILE__
+#define FIMG2D_MAX_PLANES 2
+#define FIMG2D_IOCTL_MAGIC 'F'
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FIMG2D_BITBLT_BLIT _IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit)
+#define FIMG2D_BITBLT_SYNC _IOW(FIMG2D_IOCTL_MAGIC, 1, int)
+#define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version)
+struct fimg2d_version {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ unsigned int hw;
+ unsigned int sw;
+};
+enum blit_sync {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_SYNC,
+ BLIT_ASYNC,
+};
+enum addr_space {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ ADDR_NONE = 0,
+ ADDR_DMA_BUF,
+};
+enum pixel_order {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ AX_RGB = 0,
+ RGB_AX,
+ AX_BGR,
+ BGR_AX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ ARGB_ORDER_END,
+ P1_CRY1CBY0,
+ P1_CBY1CRY0,
+ P1_Y1CRY0CB,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ P1_Y1CBY0CR,
+ P1_ORDER_END,
+ P2_CRCB,
+ P2_CBCR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ P2_ORDER_END,
+};
+enum color_format {
+ CF_XRGB_8888 = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CF_ARGB_8888,
+ CF_RGB_565,
+ CF_XRGB_1555,
+ CF_ARGB_1555,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CF_XRGB_4444,
+ CF_ARGB_4444,
+ CF_RGB_888,
+ CF_YCBCR_444,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CF_YCBCR_422,
+ CF_YCBCR_420,
+ CF_A8,
+ CF_L8,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ SRC_DST_FORMAT_END,
+ CF_MSK_1BIT,
+ CF_MSK_4BIT,
+ CF_MSK_8BIT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ CF_MSK_16BIT_565,
+ CF_MSK_16BIT_1555,
+ CF_MSK_16BIT_4444,
+ CF_MSK_32BIT_8888,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ MSK_FORMAT_END,
+};
+enum rotation {
+ ORIGIN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ ROT_90,
+ ROT_180,
+ ROT_270,
+ XFLIP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ YFLIP,
+};
+enum repeat {
+ NO_REPEAT = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ REPEAT_NORMAL,
+ REPEAT_PAD,
+ REPEAT_REFLECT, REPEAT_MIRROR = REPEAT_REFLECT,
+ REPEAT_CLAMP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum scaling {
+ NO_SCALING,
+ SCALING_NEAREST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ SCALING_BILINEAR,
+};
+enum scaling_factor {
+ SCALING_PIXELS,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ SCALING_RATIO,
+};
+enum premultiplied {
+ PREMULTIPLIED,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ NON_PREMULTIPLIED,
+};
+enum bluescreen {
+ OPAQUE,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ TRANSP,
+ BLUSCR,
+};
+enum blit_op {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_SOLID_FILL = 0,
+ BLIT_OP_CLR,
+ BLIT_OP_SRC, BLIT_OP_SRC_COPY = BLIT_OP_SRC,
+ BLIT_OP_DST,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_SRC_OVER,
+ BLIT_OP_DST_OVER, BLIT_OP_OVER_REV = BLIT_OP_DST_OVER,
+ BLIT_OP_SRC_IN,
+ BLIT_OP_DST_IN, BLIT_OP_IN_REV = BLIT_OP_DST_IN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_SRC_OUT,
+ BLIT_OP_DST_OUT, BLIT_OP_OUT_REV = BLIT_OP_DST_OUT,
+ BLIT_OP_SRC_ATOP,
+ BLIT_OP_DST_ATOP, BLIT_OP_ATOP_REV = BLIT_OP_DST_ATOP,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_XOR,
+ BLIT_OP_ADD,
+ BLIT_OP_MULTIPLY,
+ BLIT_OP_SCREEN,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_DARKEN,
+ BLIT_OP_LIGHTEN,
+ BLIT_OP_DISJ_SRC_OVER,
+ BLIT_OP_DISJ_DST_OVER, BLIT_OP_SATURATE = BLIT_OP_DISJ_DST_OVER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_DISJ_SRC_IN,
+ BLIT_OP_DISJ_DST_IN, BLIT_OP_DISJ_IN_REV = BLIT_OP_DISJ_DST_IN,
+ BLIT_OP_DISJ_SRC_OUT,
+ BLIT_OP_DISJ_DST_OUT, BLIT_OP_DISJ_OUT_REV = BLIT_OP_DISJ_DST_OUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_DISJ_SRC_ATOP,
+ BLIT_OP_DISJ_DST_ATOP, BLIT_OP_DISJ_ATOP_REV = BLIT_OP_DISJ_DST_ATOP,
+ BLIT_OP_DISJ_XOR,
+ BLIT_OP_CONJ_SRC_OVER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_CONJ_DST_OVER, BLIT_OP_CONJ_OVER_REV = BLIT_OP_CONJ_DST_OVER,
+ BLIT_OP_CONJ_SRC_IN,
+ BLIT_OP_CONJ_DST_IN, BLIT_OP_CONJ_IN_REV = BLIT_OP_CONJ_DST_IN,
+ BLIT_OP_CONJ_SRC_OUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_CONJ_DST_OUT, BLIT_OP_CONJ_OUT_REV = BLIT_OP_CONJ_DST_OUT,
+ BLIT_OP_CONJ_SRC_ATOP,
+ BLIT_OP_CONJ_DST_ATOP, BLIT_OP_CONJ_ATOP_REV = BLIT_OP_CONJ_DST_ATOP,
+ BLIT_OP_CONJ_XOR,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ BLIT_OP_USER_COEFF,
+ BLIT_OP_USER_SRC_GA,
+ BLIT_OP_END,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define MAX_FIMG2D_BLIT_OP (int)BLIT_OP_END
+struct fimg2d_addr {
+ enum addr_space type;
+ int fd[FIMG2D_MAX_PLANES];
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct fimg2d_rect {
+ int x1;
+ int y1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ int x2;
+ int y2;
+};
+struct fimg2d_scale {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ enum scaling mode;
+ int src_w, src_h;
+ int dst_w, dst_h;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct fimg2d_clip {
+ __u32 enable;
+ int x1;
+ int y1;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ int x2;
+ int y2;
+};
+struct fimg2d_repeat {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ enum repeat mode;
+ unsigned long pad_color;
+};
+struct fimg2d_bluscr {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ enum bluescreen mode;
+ unsigned long bs_color;
+ unsigned long bg_color;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct fimg2d_image {
+ int width;
+ int height;
+ int stride;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ enum pixel_order order;
+ enum color_format fmt;
+ struct fimg2d_addr addr;
+ struct fimg2d_rect rect;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct fimg2d_param {
+ unsigned long solid_color;
+ unsigned char g_alpha;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 dither;
+ enum rotation rotate;
+ enum premultiplied premult;
+ struct fimg2d_scale scaling;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct fimg2d_repeat repeat;
+ struct fimg2d_bluscr bluscr;
+ struct fimg2d_clip clipping;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct fimg2d_blit {
+ enum blit_op op;
+ struct fimg2d_param param;
+ struct fimg2d_image *src;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct fimg2d_image *msk;
+ struct fimg2d_image *tmp;
+ struct fimg2d_image *dst;
+ enum blit_sync sync;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ unsigned int seq_no;
+};
+#endif
+
diff --git a/include/gralloc_priv.h b/include/gralloc_priv.h
index 7cec618..7a1e3e0 100644
--- a/include/gralloc_priv.h
+++ b/include/gralloc_priv.h
@@ -37,7 +37,7 @@
 struct private_module_t {
     gralloc_module_t base;
 
-    private_handle_t* framebuffer;
+    struct private_handle_t* framebuffer;
     uint32_t flags;
     uint32_t numBuffers;
     uint32_t bufferMask;
@@ -86,6 +86,7 @@
     int     height;
     int     stride;
     int     vstride;
+    int     gamut;
 
     // FIXME: the attributes below should be out-of-line
     void    *base;
@@ -97,7 +98,7 @@
 
 #ifdef __cplusplus
     static const int sNumFds = 3;
-    static const int sNumInts = 15;
+    static const int sNumInts = 16;
     static const int sMagic = 0x3141592;
 
 
@@ -105,7 +106,7 @@
 		     int h, int format, int stride, int vstride) :
         fd(fd), fd1(-1), fd2(-1), magic(sMagic), flags(flags), size(size),
         offset(0), format(format), width(w), height(h), stride(stride),
-        vstride(vstride), base(0), handle(0), handle1(0), handle2(0)
+        vstride(vstride), gamut(0), base(0), handle(0), handle1(0), handle2(0)
     {
         version = sizeof(native_handle);
         numInts = sNumInts + 2;
@@ -116,8 +117,8 @@
 		     int h, int format, int stride, int vstride) :
         fd(fd), fd1(fd1), fd2(-1), magic(sMagic), flags(flags), size(size),
         offset(0), format(format), width(w), height(h), stride(stride),
-        vstride(vstride), base(0), base1(0), base2(0), handle(0), handle1(0),
-        handle2(0)
+        vstride(vstride), gamut(0), base(0), base1(0), base2(0), handle(0),
+        handle1(0), handle2(0)
     {
         version = sizeof(native_handle);
         numInts = sNumInts + 1;
@@ -128,8 +129,8 @@
 		     int h, int format, int stride, int vstride) :
         fd(fd), fd1(fd1), fd2(fd2), magic(sMagic), flags(flags), size(size),
         offset(0), format(format), width(w), height(h), stride(stride),
-        vstride(vstride), base(0), base1(0), base2(0), handle(0), handle1(0),
-        handle2(0)
+        vstride(vstride), gamut(0), base(0), base1(0), base2(0), handle(0),
+        handle1(0), handle2(0)
     {
         version = sizeof(native_handle);
         numInts = sNumInts;
diff --git a/include/ion.h b/include/ion.h
index 0c6045e..e790cb4 100644
--- a/include/ion.h
+++ b/include/ion.h
@@ -20,6 +20,7 @@
 #include <unistd.h> /* size_t */
 
 #define ION_FLAG_CACHED 1
+#define ION_FLAG_CACHED_NEEDS_SYNC 2
 
 #define ION_HEAP_SYSTEM_MASK            (1 << 0)
 #define ION_HEAP_SYSTEM_CONTIG_MASK     (1 << 1)
diff --git a/libcamera2/ExynosCamera2.cpp b/libcamera2/ExynosCamera2.cpp
index 100f0a8..960a5e2 100644
--- a/libcamera2/ExynosCamera2.cpp
+++ b/libcamera2/ExynosCamera2.cpp
@@ -88,7 +88,7 @@
 const nsecs_t Sensor::kFrameDurationRange[2] =
     {33331760L, 30000000000L}; // ~1/30 s - 30 sec
 
-const uint8_t Sensor::kColorFilterArrangement = ANDROID_SENSOR_RGGB;
+const uint8_t Sensor::kColorFilterArrangement = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB;
 
 const uint32_t kAvailableFormats[5] = {
         HAL_PIXEL_FORMAT_RAW_SENSOR,
@@ -149,38 +149,38 @@
 
 const uint8_t availableAfModesS5K4E5[] =
 {
-    ANDROID_CONTROL_AF_OFF,
-    ANDROID_CONTROL_AF_AUTO,
-    ANDROID_CONTROL_AF_MACRO,
-    ANDROID_CONTROL_AF_CONTINUOUS_PICTURE,
-    ANDROID_CONTROL_AF_CONTINUOUS_VIDEO
+    ANDROID_CONTROL_AF_MODE_OFF,
+    ANDROID_CONTROL_AF_MODE_AUTO,
+    ANDROID_CONTROL_AF_MODE_MACRO,
+    ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
+    ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO
 };
 
 const uint8_t sceneModeOverridesS5K4E5[] =
 {
     // ANDROID_CONTROL_SCENE_MODE_ACTION
-    ANDROID_CONTROL_AE_ON,
-    ANDROID_CONTROL_AWB_AUTO,
-    ANDROID_CONTROL_AF_CONTINUOUS_PICTURE,
+    ANDROID_CONTROL_AE_MODE_ON,
+    ANDROID_CONTROL_AWB_MODE_AUTO,
+    ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
     // ANDROID_CONTROL_SCENE_MODE_NIGHT
-    ANDROID_CONTROL_AE_ON,
-    ANDROID_CONTROL_AWB_AUTO,
-    ANDROID_CONTROL_AF_CONTINUOUS_PICTURE,
+    ANDROID_CONTROL_AE_MODE_ON,
+    ANDROID_CONTROL_AWB_MODE_AUTO,
+    ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
     // ANDROID_CONTROL_SCENE_MODE_SUNSET
-    ANDROID_CONTROL_AE_ON,
-    ANDROID_CONTROL_AWB_DAYLIGHT,
-    ANDROID_CONTROL_AF_CONTINUOUS_PICTURE,
+    ANDROID_CONTROL_AE_MODE_ON,
+    ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
+    ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
     // ANDROID_CONTROL_SCENE_MODE_PARTY
-    ANDROID_CONTROL_AE_ON_AUTO_FLASH,
-    ANDROID_CONTROL_AWB_AUTO,
-    ANDROID_CONTROL_AF_CONTINUOUS_PICTURE
+    ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH,
+    ANDROID_CONTROL_AWB_MODE_AUTO,
+    ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE
 };
 
 const uint8_t availableAeModesS5K4E5[] =
 {
-    ANDROID_CONTROL_AE_OFF,
-    ANDROID_CONTROL_AE_ON,
-    ANDROID_CONTROL_AE_ON_AUTO_FLASH
+    ANDROID_CONTROL_AE_MODE_OFF,
+    ANDROID_CONTROL_AE_MODE_ON,
+    ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH
 };
 
 ExynosCamera2InfoS5K4E5::ExynosCamera2InfoS5K4E5()
@@ -245,33 +245,33 @@
 
 const uint8_t availableAfModesS5K6A3[] =
 {
-    ANDROID_CONTROL_AF_OFF
+    ANDROID_CONTROL_AF_MODE_OFF
 };
 
 const uint8_t sceneModeOverridesS5K6A3[] =
 {
     // ANDROID_CONTROL_SCENE_MODE_ACTION
-    ANDROID_CONTROL_AE_ON,
-    ANDROID_CONTROL_AWB_AUTO,
-    ANDROID_CONTROL_AF_OFF,
+    ANDROID_CONTROL_AE_MODE_ON,
+    ANDROID_CONTROL_AWB_MODE_AUTO,
+    ANDROID_CONTROL_AF_MODE_OFF,
     // ANDROID_CONTROL_SCENE_MODE_NIGHT
-    ANDROID_CONTROL_AE_ON,
-    ANDROID_CONTROL_AWB_AUTO,
-    ANDROID_CONTROL_AF_OFF,
+    ANDROID_CONTROL_AE_MODE_ON,
+    ANDROID_CONTROL_AWB_MODE_AUTO,
+    ANDROID_CONTROL_AF_MODE_OFF,
     // ANDROID_CONTROL_SCENE_MODE_SUNSET
-    ANDROID_CONTROL_AE_ON,
-    ANDROID_CONTROL_AWB_DAYLIGHT,
-    ANDROID_CONTROL_AF_OFF,
+    ANDROID_CONTROL_AE_MODE_ON,
+    ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
+    ANDROID_CONTROL_AF_MODE_OFF,
     // ANDROID_CONTROL_SCENE_MODE_PARTY
-    ANDROID_CONTROL_AE_ON,
-    ANDROID_CONTROL_AWB_AUTO,
-    ANDROID_CONTROL_AF_OFF
+    ANDROID_CONTROL_AE_MODE_ON,
+    ANDROID_CONTROL_AWB_MODE_AUTO,
+    ANDROID_CONTROL_AF_MODE_OFF
 };
 
 const uint8_t availableAeModesS5K6A3[] =
 {
-    ANDROID_CONTROL_AE_OFF,
-    ANDROID_CONTROL_AE_ON
+    ANDROID_CONTROL_AE_MODE_OFF,
+    ANDROID_CONTROL_AE_MODE_ON
 };
 
 ExynosCamera2InfoS5K6A3::ExynosCamera2InfoS5K6A3()
@@ -394,31 +394,31 @@
 
     // android.lens
 
-    ADD_OR_SIZE(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE,
+    ADD_OR_SIZE(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
             &(m_curCameraInfo->minFocusDistance), 1);
-    ADD_OR_SIZE(ANDROID_LENS_HYPERFOCAL_DISTANCE,
+    ADD_OR_SIZE(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
             &(m_curCameraInfo->minFocusDistance), 1);
 
-    ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS,
+    ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
             &m_curCameraInfo->focalLength, 1);
-    ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_APERTURES,
+    ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
             &m_curCameraInfo->aperture, 1);
 
     static const float filterDensity = 0;
-    ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_FILTER_DENSITY,
+    ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
             &filterDensity, 1);
     static const uint8_t availableOpticalStabilization =
-            ANDROID_LENS_OPTICAL_STABILIZATION_OFF;
-    ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_OPTICAL_STABILIZATION,
+            ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
             &availableOpticalStabilization, 1);
 
     static const int32_t lensShadingMapSize[] = {1, 1};
-    ADD_OR_SIZE(ANDROID_LENS_SHADING_MAP_SIZE, lensShadingMapSize,
+    ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize,
             sizeof(lensShadingMapSize)/sizeof(int32_t));
 
     static const float lensShadingMap[3 * 1 * 1 ] =
             { 1.f, 1.f, 1.f };
-    ADD_OR_SIZE(ANDROID_LENS_SHADING_MAP, lensShadingMap,
+    ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP, lensShadingMap,
             sizeof(lensShadingMap)/sizeof(float));
 
     int32_t lensFacing = cameraId ?
@@ -426,31 +426,31 @@
     ADD_OR_SIZE(ANDROID_LENS_FACING, &lensFacing, 1);
 
     // android.sensor
-    ADD_OR_SIZE(ANDROID_SENSOR_EXPOSURE_TIME_RANGE,
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
             Sensor::kExposureTimeRange, 2);
 
-    ADD_OR_SIZE(ANDROID_SENSOR_MAX_FRAME_DURATION,
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
             &Sensor::kFrameDurationRange[1], 1);
 
-    ADD_OR_SIZE(ANDROID_SENSOR_AVAILABLE_SENSITIVITIES,
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_AVAILABLE_SENSITIVITIES,
             Sensor::kAvailableSensitivities,
             sizeof(Sensor::kAvailableSensitivities)
             /sizeof(uint32_t));
 
-    ADD_OR_SIZE(ANDROID_SENSOR_COLOR_FILTER_ARRANGEMENT,
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
             &Sensor::kColorFilterArrangement, 1);
 
     static const float sensorPhysicalSize[2] = {3.20f, 2.40f}; // mm
-    ADD_OR_SIZE(ANDROID_SENSOR_PHYSICAL_SIZE,
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
             sensorPhysicalSize, 2);
 
     int32_t pixelArraySize[2] = {
         m_curCameraInfo->sensorW, m_curCameraInfo->sensorH
     };
-    ADD_OR_SIZE(ANDROID_SENSOR_PIXEL_ARRAY_SIZE, pixelArraySize, 2);
-    ADD_OR_SIZE(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, pixelArraySize,2);
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArraySize, 2);
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, pixelArraySize,2);
 
-    ADD_OR_SIZE(ANDROID_SENSOR_WHITE_LEVEL,
+    ADD_OR_SIZE(ANDROID_SENSOR_INFO_WHITE_LEVEL,
             &Sensor::kMaxRawValue, 1);
 
     static const int32_t blackLevelPattern[4] = {
@@ -468,10 +468,10 @@
         flashAvailable = 1;
     else
         flashAvailable = 0;
-    ADD_OR_SIZE(ANDROID_FLASH_AVAILABLE, &flashAvailable, 1);
+    ADD_OR_SIZE(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1);
 
     static const int64_t flashChargeDuration = 0;
-    ADD_OR_SIZE(ANDROID_FLASH_CHARGE_DURATION, &flashChargeDuration, 1);
+    ADD_OR_SIZE(ANDROID_FLASH_INFO_CHARGE_DURATION, &flashChargeDuration, 1);
 
     // android.tonemap
 
@@ -511,7 +511,7 @@
             sizeof(kAvailableJpegMinDurations)/sizeof(uint64_t));
 
     static const float maxZoom = 4;
-    ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, &maxZoom, 1);
+    ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxZoom, 1);
 
     // android.jpeg
 
@@ -532,31 +532,31 @@
     // android.stats
 
     static const uint8_t availableFaceDetectModes[] = {
-            ANDROID_STATS_FACE_DETECTION_OFF,
-            ANDROID_STATS_FACE_DETECTION_FULL
+            ANDROID_STATISTICS_FACE_DETECT_MODE_OFF,
+            ANDROID_STATISTICS_FACE_DETECT_MODE_FULL
     };
-    ADD_OR_SIZE(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES,
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
             availableFaceDetectModes,
             sizeof(availableFaceDetectModes));
 
     m_curCameraInfo->maxFaceCount = CAMERA2_MAX_FACES;
-    ADD_OR_SIZE(ANDROID_STATS_MAX_FACE_COUNT,
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
             &(m_curCameraInfo->maxFaceCount), 1);
 
     static const int32_t histogramSize = 64;
-    ADD_OR_SIZE(ANDROID_STATS_HISTOGRAM_BUCKET_COUNT,
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
             &histogramSize, 1);
 
     static const int32_t maxHistogramCount = 1000;
-    ADD_OR_SIZE(ANDROID_STATS_MAX_HISTOGRAM_COUNT,
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
             &maxHistogramCount, 1);
 
     static const int32_t sharpnessMapSize[2] = {64, 64};
-    ADD_OR_SIZE(ANDROID_STATS_SHARPNESS_MAP_SIZE,
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
             sharpnessMapSize, sizeof(sharpnessMapSize)/sizeof(int32_t));
 
     static const int32_t maxSharpnessMapValue = 1000;
-    ADD_OR_SIZE(ANDROID_STATS_MAX_SHARPNESS_MAP_VALUE,
+    ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
             &maxSharpnessMapValue, 1);
 
     // android.control
@@ -571,7 +571,7 @@
             availableSceneModes, sizeof(availableSceneModes));
 
     static const uint8_t availableEffects[] = {
-            ANDROID_CONTROL_EFFECT_OFF
+            ANDROID_CONTROL_EFFECT_MODE_OFF
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_EFFECTS,
             availableEffects, sizeof(availableEffects));
@@ -586,11 +586,11 @@
     static const camera_metadata_rational exposureCompensationStep = {
             1, 1
     };
-    ADD_OR_SIZE(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP,
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_STEP,
             &exposureCompensationStep, 1);
 
     int32_t exposureCompensationRange[] = {-3, 3};
-    ADD_OR_SIZE(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE,
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
             exposureCompensationRange,
             sizeof(exposureCompensationRange)/sizeof(int32_t));
 
@@ -602,19 +602,19 @@
             sizeof(availableTargetFpsRanges)/sizeof(int32_t));
 
     static const uint8_t availableAntibandingModes[] = {
-            ANDROID_CONTROL_AE_ANTIBANDING_OFF,
-            ANDROID_CONTROL_AE_ANTIBANDING_AUTO
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
             availableAntibandingModes, sizeof(availableAntibandingModes));
 
     static const uint8_t availableAwbModes[] = {
-            ANDROID_CONTROL_AWB_OFF,
-            ANDROID_CONTROL_AWB_AUTO,
-            ANDROID_CONTROL_AWB_INCANDESCENT,
-            ANDROID_CONTROL_AWB_FLUORESCENT,
-            ANDROID_CONTROL_AWB_DAYLIGHT,
-            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT
+            ANDROID_CONTROL_AWB_MODE_OFF,
+            ANDROID_CONTROL_AWB_MODE_AUTO,
+            ANDROID_CONTROL_AWB_MODE_INCANDESCENT,
+            ANDROID_CONTROL_AWB_MODE_FLUORESCENT,
+            ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
+            ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
             availableAwbModes, sizeof(availableAwbModes));
@@ -623,8 +623,8 @@
                 m_curCameraInfo->availableAfModes, m_curCameraInfo->numAvailableAfModes);
 
     static const uint8_t availableVstabModes[] = {
-            ANDROID_CONTROL_VIDEO_STABILIZATION_OFF,
-            ANDROID_CONTROL_VIDEO_STABILIZATION_ON
+            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
+            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
             availableVstabModes, sizeof(availableVstabModes));
@@ -681,7 +681,7 @@
 
     /** android.request */
 
-    static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_NONE;
+    static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_NONE;
     ADD_OR_SIZE(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1);
 
     static const int32_t id = 0;
@@ -707,7 +707,7 @@
     ADD_OR_SIZE(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1);
 
     static const uint8_t opticalStabilizationMode =
-            ANDROID_LENS_OPTICAL_STABILIZATION_OFF;
+            ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
     ADD_OR_SIZE(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
             &opticalStabilizationMode, 1);
 
@@ -721,7 +721,7 @@
 
     /** android.flash */
 
-    static const uint8_t flashMode = ANDROID_FLASH_OFF;
+    static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
     ADD_OR_SIZE(ANDROID_FLASH_MODE, &flashMode, 1);
 
     static const uint8_t flashPower = 10;
@@ -739,89 +739,53 @@
     uint8_t colorMode = 0;
     uint8_t tonemapMode = 0;
     uint8_t edgeMode = 0;
-    uint8_t vstabMode = 0;
+    uint8_t vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
 
     switch (request_template) {
-      case CAMERA2_TEMPLATE_PREVIEW:
-        hotPixelMode = ANDROID_PROCESSING_FAST;
-        demosaicMode = ANDROID_PROCESSING_FAST;
-        noiseMode = ANDROID_PROCESSING_FAST;
-        shadingMode = ANDROID_PROCESSING_FAST;
-        geometricMode = ANDROID_PROCESSING_FAST;
-        colorMode = ANDROID_PROCESSING_FAST;
-        tonemapMode = ANDROID_PROCESSING_FAST;
-        edgeMode = ANDROID_PROCESSING_FAST;
-        vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
-        break;
+      case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
+        vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON;
+        // fall-through
       case CAMERA2_TEMPLATE_STILL_CAPTURE:
-        hotPixelMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        demosaicMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        noiseMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        shadingMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        geometricMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        colorMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        tonemapMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        edgeMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
+        // fall-through
+      case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
+        hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
+        demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY;
+        noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
+        shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
+        geometricMode = ANDROID_GEOMETRIC_MODE_HIGH_QUALITY;
+        colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY;
+        tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
+        edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;
         break;
       case CAMERA2_TEMPLATE_VIDEO_RECORD:
-        hotPixelMode = ANDROID_PROCESSING_FAST;
-        demosaicMode = ANDROID_PROCESSING_FAST;
-        noiseMode = ANDROID_PROCESSING_FAST;
-        shadingMode = ANDROID_PROCESSING_FAST;
-        geometricMode = ANDROID_PROCESSING_FAST;
-        colorMode = ANDROID_PROCESSING_FAST;
-        tonemapMode = ANDROID_PROCESSING_FAST;
-        edgeMode = ANDROID_PROCESSING_FAST;
-        vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_ON;
-        break;
-      case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
-        hotPixelMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        demosaicMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        noiseMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        shadingMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        geometricMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        colorMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        tonemapMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        edgeMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_ON;
-        break;
-      case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
-        hotPixelMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        demosaicMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        noiseMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        shadingMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        geometricMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        colorMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        tonemapMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        edgeMode = ANDROID_PROCESSING_HIGH_QUALITY;
-        vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
-        break;
+        vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON;
+        // fall-through
+      case CAMERA2_TEMPLATE_PREVIEW:
+        // fall-through
       default:
-        hotPixelMode = ANDROID_PROCESSING_FAST;
-        demosaicMode = ANDROID_PROCESSING_FAST;
-        noiseMode = ANDROID_PROCESSING_FAST;
-        shadingMode = ANDROID_PROCESSING_FAST;
-        geometricMode = ANDROID_PROCESSING_FAST;
-        colorMode = ANDROID_PROCESSING_FAST;
-        tonemapMode = ANDROID_PROCESSING_FAST;
-        edgeMode = ANDROID_PROCESSING_FAST;
-        vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
+        hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
+        demosaicMode = ANDROID_DEMOSAIC_MODE_FAST;
+        noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST;
+        shadingMode = ANDROID_SHADING_MODE_FAST;
+        geometricMode = ANDROID_GEOMETRIC_MODE_FAST;
+        colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST;
+        tonemapMode = ANDROID_TONEMAP_MODE_FAST;
+        edgeMode = ANDROID_EDGE_MODE_FAST;
         break;
     }
     ADD_OR_SIZE(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1);
     ADD_OR_SIZE(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1);
-    ADD_OR_SIZE(ANDROID_NOISE_MODE, &noiseMode, 1);
+    ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1);
     ADD_OR_SIZE(ANDROID_SHADING_MODE, &shadingMode, 1);
     ADD_OR_SIZE(ANDROID_GEOMETRIC_MODE, &geometricMode, 1);
-    ADD_OR_SIZE(ANDROID_COLOR_MODE, &colorMode, 1);
+    ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1);
     ADD_OR_SIZE(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
     ADD_OR_SIZE(ANDROID_EDGE_MODE, &edgeMode, 1);
     ADD_OR_SIZE(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1);
 
     /** android.noise */
     static const uint8_t noiseStrength = 5;
-    ADD_OR_SIZE(ANDROID_NOISE_STRENGTH, &noiseStrength, 1);
+    ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_STRENGTH, &noiseStrength, 1);
 
     /** android.color */
     static const float colorTransform[9] = {
@@ -829,7 +793,7 @@
         0.f, 1.f, 0.f,
         0.f, 0.f, 1.f
     };
-    ADD_OR_SIZE(ANDROID_COLOR_TRANSFORM, colorTransform, 9);
+    ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9);
 
     /** android.tonemap */
     static const float tonemapCurve[4] = {
@@ -878,14 +842,14 @@
 
     /** android.stats */
 
-    static const uint8_t faceDetectMode = ANDROID_STATS_FACE_DETECTION_FULL;
-    ADD_OR_SIZE(ANDROID_STATS_FACE_DETECT_MODE, &faceDetectMode, 1);
+    static const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_FULL;
+    ADD_OR_SIZE(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1);
 
-    static const uint8_t histogramMode = ANDROID_STATS_OFF;
-    ADD_OR_SIZE(ANDROID_STATS_HISTOGRAM_MODE, &histogramMode, 1);
+    static const uint8_t histogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1);
 
-    static const uint8_t sharpnessMapMode = ANDROID_STATS_OFF;
-    ADD_OR_SIZE(ANDROID_STATS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1);
+    static const uint8_t sharpnessMapMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF;
+    ADD_OR_SIZE(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1);
 
 
     /** android.control */
@@ -893,36 +857,36 @@
     uint8_t controlIntent = 0;
     switch (request_template) {
       case CAMERA2_TEMPLATE_PREVIEW:
-        controlIntent = ANDROID_CONTROL_INTENT_PREVIEW;
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
         break;
       case CAMERA2_TEMPLATE_STILL_CAPTURE:
-        controlIntent = ANDROID_CONTROL_INTENT_STILL_CAPTURE;
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
         break;
       case CAMERA2_TEMPLATE_VIDEO_RECORD:
-        controlIntent = ANDROID_CONTROL_INTENT_VIDEO_RECORD;
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
         break;
       case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
-        controlIntent = ANDROID_CONTROL_INTENT_VIDEO_SNAPSHOT;
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
         break;
       case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
-        controlIntent = ANDROID_CONTROL_INTENT_ZERO_SHUTTER_LAG;
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
         break;
       default:
-        controlIntent = ANDROID_CONTROL_INTENT_CUSTOM;
+        controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;
         break;
     }
     ADD_OR_SIZE(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);
 
-    static const uint8_t controlMode = ANDROID_CONTROL_AUTO;
+    static const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
     ADD_OR_SIZE(ANDROID_CONTROL_MODE, &controlMode, 1);
 
-    static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_OFF;
+    static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
     ADD_OR_SIZE(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
 
     static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
     ADD_OR_SIZE(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
 
-    static const uint8_t aeMode = ANDROID_CONTROL_AE_ON;
+    static const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
     ADD_OR_SIZE(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
 
     int32_t controlRegions[5] = {
@@ -931,7 +895,7 @@
     ADD_OR_SIZE(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5);
 
     static const int32_t aeExpCompensation = 0;
-    ADD_OR_SIZE(ANDROID_CONTROL_AE_EXP_COMPENSATION, &aeExpCompensation, 1);
+    ADD_OR_SIZE(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExpCompensation, 1);
 
     static const int32_t aeTargetFpsRange[2] = {
         15, 30
@@ -939,11 +903,11 @@
     ADD_OR_SIZE(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2);
 
     static const uint8_t aeAntibandingMode =
-            ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
+            ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
     ADD_OR_SIZE(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1);
 
     static const uint8_t awbMode =
-            ANDROID_CONTROL_AWB_AUTO;
+            ANDROID_CONTROL_AWB_MODE_AUTO;
     ADD_OR_SIZE(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
 
     ADD_OR_SIZE(ANDROID_CONTROL_AWB_REGIONS, controlRegions, 5);
@@ -951,22 +915,22 @@
     uint8_t afMode = 0;
     switch (request_template) {
       case CAMERA2_TEMPLATE_PREVIEW:
-        afMode = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE;
+        afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
         break;
       case CAMERA2_TEMPLATE_STILL_CAPTURE:
-        afMode = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE;
+        afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
         break;
       case CAMERA2_TEMPLATE_VIDEO_RECORD:
-        afMode = ANDROID_CONTROL_AF_CONTINUOUS_VIDEO;
+        afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
         break;
       case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
-        afMode = ANDROID_CONTROL_AF_CONTINUOUS_VIDEO;
+        afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
         break;
       case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
-        afMode = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE;
+        afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
         break;
       default:
-        afMode = ANDROID_CONTROL_AF_AUTO;
+        afMode = ANDROID_CONTROL_AF_MODE_AUTO;
         break;
     }
     ADD_OR_SIZE(ANDROID_CONTROL_AF_MODE, &afMode, 1);
diff --git a/libcamera2/ExynosCameraHWInterface2.cpp b/libcamera2/ExynosCameraHWInterface2.cpp
index ea90d05..5dee2e7 100644
--- a/libcamera2/ExynosCameraHWInterface2.cpp
+++ b/libcamera2/ExynosCameraHWInterface2.cpp
@@ -1026,11 +1026,13 @@
         if (m_exynosPictureCSC == NULL)
             ALOGE("ERR(%s): csc_init() fail", __FUNCTION__);
         csc_set_hw_property(m_exynosPictureCSC, CSC_HW_PROPERTY_FIXED_NODE, PICTURE_GSC_NODE_NUM);
+        csc_set_hw_property(m_exynosPictureCSC, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER);
 
         m_exynosVideoCSC = csc_init(cscMethod);
         if (m_exynosVideoCSC == NULL)
             ALOGE("ERR(%s): csc_init() fail", __FUNCTION__);
         csc_set_hw_property(m_exynosVideoCSC, CSC_HW_PROPERTY_FIXED_NODE, VIDEO_GSC_NODE_NUM);
+        csc_set_hw_property(m_exynosVideoCSC, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER);
 
         m_setExifFixedAttribute();
 
@@ -6046,7 +6048,7 @@
             break;
         }
         if (1 << i & cacheFlag)
-            flag = ION_FLAG_CACHED;
+            flag = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
         else
             flag = 0;
         buf->fd.extFd[i] = ion_alloc(ionClient, \
diff --git a/libcamera2/MetadataConverter.cpp b/libcamera2/MetadataConverter.cpp
index d3dd2b3..a39be4e 100644
--- a/libcamera2/MetadataConverter.cpp
+++ b/libcamera2/MetadataConverter.cpp
@@ -230,7 +230,7 @@
 
 
 
-            case ANDROID_STATS_FACE_DETECT_MODE:
+            case ANDROID_STATISTICS_FACE_DETECT_MODE:
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
                     break;
                 dst->ctl.stats.faceDetectMode = (enum facedetect_mode)(curr_entry.data.u8[0] + 1);
@@ -271,7 +271,7 @@
                 dst_ext->ae_lock = (enum ae_lockmode)(curr_entry.data.u8[0]);
                 break;
 
-            case ANDROID_CONTROL_AE_EXP_COMPENSATION:
+            case ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION:
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 1))
                     break;
                 dst->ctl.aa.aeExpCompensation = curr_entry.data.i32[0] + 5;
@@ -570,17 +570,17 @@
         return NO_MEMORY;
 
     intData = metadata->ctl.aa.aeExpCompensation - 5;
-    if (0 != add_camera_metadata_entry(dst, ANDROID_CONTROL_AE_EXP_COMPENSATION,
+    if (0 != add_camera_metadata_entry(dst, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
                 &intData, 1))
         return NO_MEMORY;
 
     byteData = metadata->dm.stats.faceDetectMode - 1;
-    if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_DETECT_MODE,
+    if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_DETECT_MODE,
                 &byteData, 1))
         return NO_MEMORY;
 
     int maxFacecount = CAMERA2_MAX_FACES;
-    if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_MAX_FACE_COUNT,
+    if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
                 &maxFacecount, 1))
         return NO_MEMORY;
 
@@ -601,19 +601,19 @@
     }
 
     if (tempFaceCount > 0) {
-        if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_RECTANGLES,
+        if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_RECTANGLES,
                     &metaFaceRectangles, 4 * tempFaceCount))
             return NO_MEMORY;
 
-        if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_LANDMARKS,
+        if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_LANDMARKS,
                     &mataFaceLandmarks, 6 * tempFaceCount))
             return NO_MEMORY;
 
-        if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_IDS,
+        if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_IDS,
                     &mataFaceIds, tempFaceCount))
             return NO_MEMORY;
 
-        if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_SCORES,
+        if (0 != add_camera_metadata_entry(dst, ANDROID_STATISTICS_FACE_SCORES,
                     &metaFaceScores, tempFaceCount))
             return NO_MEMORY;
     }
diff --git a/libcsc/Android.mk b/libcsc/Android.mk
index 8074695..bbf0ece 100644
--- a/libcsc/Android.mk
+++ b/libcsc/Android.mk
@@ -56,7 +56,7 @@
 
 LOCAL_C_INCLUDES += \
 	$(LOCAL_PATH)/../include
-LOCAL_CFLAGS += -DENABLE_GSCALER
+LOCAL_CFLAGS += -DENABLE_GSCALER -DENABLE_G2D
 LOCAL_SHARED_LIBRARIES += libexynosgscaler
 
 LOCAL_CFLAGS += -DUSE_ION
diff --git a/libcsc/csc.c b/libcsc/csc.c
index 4f2aac6..0831f61 100644
--- a/libcsc/csc.c
+++ b/libcsc/csc.c
@@ -53,6 +53,19 @@
 #include "exynos_gscaler.h"
 #endif
 
+#ifdef ENABLE_G2D
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "fimg2d.h"
+
+typedef struct
+{
+    struct fimg2d_image src;
+    struct fimg2d_image dst;
+    int fd;
+} g2d_data;
+#endif
+
 #define GSCALER_IMG_ALIGN 16
 #define ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
 
@@ -64,11 +77,6 @@
     CSC_V_PLANE = 2
 } CSC_PLANE;
 
-typedef enum _CSC_HW_TYPE {
-    CSC_HW_TYPE_FIMC = 0,
-    CSC_HW_TYPE_GSCALER
-} CSC_HW_TYPE;
-
 typedef struct _CSC_FORMAT {
     unsigned int width;
     unsigned int height;
@@ -265,7 +273,7 @@
     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
         ret = conv_sw_src_yuv420sp(handle);
         break;
-    case HAL_PIXEL_FORMAT_ARGB888:
+    case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
         ret = conv_sw_src_argb888(handle);
         break;
     default:
@@ -314,6 +322,29 @@
         }
         break;
 #endif
+#ifdef ENABLE_G2D
+    case CSC_HW_TYPE_G2D:
+    {
+        g2d_data *g2d = (g2d_data *)handle->csc_hw_handle;
+        struct fimg2d_blit blit;
+        int err;
+
+        memset(&blit, 0, sizeof(blit));
+        blit.op = BLIT_OP_SRC_COPY;
+        blit.param.g_alpha = 0xFF;
+        blit.src = &g2d->src;
+        blit.dst = &g2d->dst;
+        blit.sync = BLIT_SYNC;
+
+        err = ioctl(g2d->fd, FIMG2D_BITBLT_BLIT, &blit);
+        if (err < 0) {
+            ALOGE("FIMG2D_BITBLT_BLIT ioctl failed: %s", strerror(errno));
+            ret = CSC_Error;
+        }
+
+        break;
+    }
+#endif
     default:
         ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type);
         ret = CSC_ErrorNotImplemented;
@@ -331,12 +362,6 @@
 
     csc_handle = (CSC_HANDLE *)handle;
     if (csc_handle->csc_method == CSC_METHOD_HW) {
-#ifdef ENABLE_FIMC
-        csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC;
-#endif
-#ifdef ENABLE_GSCALER
-        csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER;
-#endif
         switch (csc_handle->csc_hw_type) {
 #ifdef ENABLE_FIMC
         case CSC_HW_TYPE_FIMC:
@@ -353,9 +378,27 @@
             ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__);
             break;
 #endif
+#ifdef ENABLE_G2D
+        case CSC_HW_TYPE_G2D:
+        {
+            g2d_data *g2d = calloc(1, sizeof(g2d_data));
+            if (!g2d) {
+                ALOGE("failed to allocate G2D data");
+                break;
+            }
+            g2d->fd = open("/dev/fimg2d", O_RDWR);
+            if (g2d->fd < 0) {
+                ALOGE("failed to open G2D: %s", strerror(errno));
+                free(g2d);
+            } else {
+                csc_handle->csc_hw_handle = g2d;
+            }
+            break;
+        }
+#endif
         default:
             ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__);
-            csc_handle->csc_hw_handle == NULL;
+            csc_handle->csc_hw_handle = NULL;
             break;
         }
     }
@@ -363,8 +406,7 @@
     if (csc_handle->csc_method == CSC_METHOD_HW) {
         if (csc_handle->csc_hw_handle == NULL) {
             ALOGE("%s:: CSC_METHOD_HW can't open HW", __func__);
-            free(csc_handle);
-            csc_handle = NULL;
+            ret = CSC_Error;
         }
     }
 
@@ -415,6 +457,42 @@
                 0);
             break;
 #endif
+#ifdef ENABLE_G2D
+        case CSC_HW_TYPE_G2D:
+        {
+            g2d_data *g2d = (g2d_data *)csc_handle->csc_hw_handle;
+
+            g2d->src.width = ALIGN(csc_handle->src_format.width,
+                    GSCALER_IMG_ALIGN);
+            g2d->src.height = csc_handle->src_format.height;
+            g2d->src.stride = g2d->src.width *
+                    hal_2_g2d_bpp(csc_handle->src_format.color_format) >> 3;
+            g2d->src.order = hal_2_g2d_pixel_order(csc_handle->src_format.color_format);
+            g2d->src.fmt = hal_2_g2d_color_format(csc_handle->src_format.color_format);
+            g2d->src.rect.x1 = csc_handle->src_format.crop_left;
+            g2d->src.rect.y1 = csc_handle->src_format.crop_top;
+            g2d->src.rect.x2 = csc_handle->src_format.crop_left +
+                    csc_handle->src_format.crop_width;
+            g2d->src.rect.y2 = csc_handle->src_format.crop_top +
+                    csc_handle->src_format.crop_height;
+
+            g2d->dst.width = ALIGN(csc_handle->dst_format.width,
+                    GSCALER_IMG_ALIGN);
+            g2d->dst.height = csc_handle->dst_format.height;
+            g2d->dst.stride = g2d->dst.width *
+                    hal_2_g2d_bpp(csc_handle->dst_format.color_format) >> 3;
+            g2d->dst.order = hal_2_g2d_pixel_order(csc_handle->dst_format.color_format);
+            g2d->dst.fmt = hal_2_g2d_color_format(csc_handle->dst_format.color_format);
+            g2d->dst.rect.x1 = csc_handle->dst_format.crop_left;
+            g2d->dst.rect.y1 = csc_handle->dst_format.crop_top;
+            g2d->dst.rect.x2 = csc_handle->dst_format.crop_left +
+                    csc_handle->dst_format.crop_width;
+            g2d->dst.rect.y2 = csc_handle->dst_format.crop_top +
+                    csc_handle->dst_format.crop_height;
+
+            break;
+        }
+#endif
         default:
             ALOGE("%s:: unsupported csc_hw_type", __func__);
             break;
@@ -444,6 +522,22 @@
             exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, -1);
             break;
 #endif
+#ifdef ENABLE_G2D
+        case CSC_HW_TYPE_G2D:
+        {
+            g2d_data *g2d = (g2d_data *)csc_handle->csc_hw_handle;
+
+            g2d->src.addr.type = ADDR_DMA_BUF;
+            g2d->src.addr.fd[0] = (int)csc_handle->src_buffer.planes[0];
+            g2d->src.addr.fd[1] = (int)csc_handle->src_buffer.planes[1];
+
+            g2d->dst.addr.type = ADDR_DMA_BUF;
+            g2d->dst.addr.fd[0] = (int)csc_handle->dst_buffer.planes[0];
+            g2d->dst.addr.fd[1] = (int)csc_handle->dst_buffer.planes[1];
+
+            break;
+        }
+#endif
         default:
             ALOGE("%s:: unsupported csc_hw_type", __func__);
             break;
@@ -476,7 +570,7 @@
     CSC_HANDLE *csc_handle;
 
     csc_handle = (CSC_HANDLE *)handle;
-    if (csc_handle->csc_method == CSC_METHOD_HW) {
+    if (csc_handle->csc_hw_handle) {
         switch (csc_handle->csc_hw_type) {
 #ifdef ENABLE_FIMC
         case CSC_HW_TYPE_FIMC:
@@ -488,6 +582,15 @@
             exynos_gsc_destroy(csc_handle->csc_hw_handle);
             break;
 #endif
+#ifdef ENABLE_G2D
+        case CSC_HW_TYPE_G2D:
+        {
+            g2d_data *g2d = (g2d_data *)csc_handle->csc_hw_handle;
+            close(g2d->fd);
+            free(g2d);
+            break;
+        }
+#endif
         default:
             ALOGE("%s:: unsupported csc_hw_type", __func__);
             break;
@@ -518,6 +621,22 @@
     return ret;
 }
 
+CSC_ERRORCODE csc_set_method(
+    void           *handle,
+    CSC_METHOD     method)
+{
+    CSC_HANDLE *csc_handle;
+    CSC_ERRORCODE ret = CSC_ErrorNone;
+
+    if (handle == NULL)
+        return CSC_ErrorNotInit;
+
+    csc_handle = (CSC_HANDLE *)handle;
+    csc_handle->csc_method = method;
+
+    return ret;
+}
+
 CSC_ERRORCODE csc_set_hw_property(
     void                *handle,
     CSC_HW_PROPERTY_TYPE property,
@@ -530,6 +649,12 @@
         return CSC_ErrorNotInit;
 
     csc_handle = (CSC_HANDLE *)handle;
+
+    if (csc_handle->csc_hw_handle) {
+        ALOGE("%s:: cannot set hw property after hw is already initialized", __func__);
+        return CSC_ErrorUnsupportFormat;
+    }
+
     switch (property) {
     case CSC_HW_PROPERTY_FIXED_NODE:
         csc_handle->hw_property.fixed_node = value;
@@ -537,6 +662,9 @@
     case CSC_HW_PROPERTY_MODE_DRM:
         csc_handle->hw_property.mode_drm = value;
         break;
+    case CSC_HW_PROPERTY_HW_TYPE:
+        csc_handle->csc_hw_type = value;
+        break;
     default:
         ALOGE("%s:: not supported hw property", __func__);
         ret = CSC_ErrorUnsupportFormat;
@@ -711,11 +839,19 @@
         return CSC_ErrorNotInit;
 
     if ((csc_handle->csc_method == CSC_METHOD_HW) &&
-        (csc_handle->csc_hw_handle == NULL))
-        csc_init_hw(handle);
+        (csc_handle->csc_hw_handle == NULL)) {
+        ret = csc_init_hw(handle);
+        if (ret != CSC_ErrorNone)
+            return ret;
+    }
 
-    csc_set_format(csc_handle);
-    csc_set_buffer(csc_handle);
+    ret = csc_set_format(csc_handle);
+    if (ret != CSC_ErrorNone)
+        return ret;
+
+    ret = csc_set_buffer(csc_handle);
+    if (ret != CSC_ErrorNone)
+        return ret;
 
     if (csc_handle->csc_method == CSC_METHOD_HW)
         ret = conv_hw(csc_handle);
diff --git a/libcsc/csc.h b/libcsc/csc.h
index 5fc50a2..9372610 100644
--- a/libcsc/csc.h
+++ b/libcsc/csc.h
@@ -53,8 +53,16 @@
 typedef enum _CSC_HW_PROPERTY_TYPE {
     CSC_HW_PROPERTY_FIXED_NODE = 0,
     CSC_HW_PROPERTY_MODE_DRM,
+    CSC_HW_PROPERTY_HW_TYPE,
 } CSC_HW_PROPERTY_TYPE;
 
+typedef enum _CSC_HW_TYPE {
+    CSC_HW_TYPE_NONE = 0,
+    CSC_HW_TYPE_FIMC,
+    CSC_HW_TYPE_GSCALER,
+    CSC_HW_TYPE_G2D,
+} CSC_HW_TYPE;
+
 /*
  * change hal pixel format to omx pixel format
  *
@@ -80,6 +88,40 @@
     unsigned int omx_format);
 
 /*
+ * change hal pixel format to g2d color format
+ *
+ * @param hal_format
+ *   hal pixel format[in]
+ *
+ * @return
+ *   g2d color format
+ */
+unsigned int hal_2_g2d_color_format(unsigned int hal_format);
+
+/*
+ * change hal pixel format to g2d pixel order
+ *
+ * @param hal_format
+ *   hal pixel format[in]
+ *
+ * @return
+ *   g2d pixel order
+ */
+unsigned int hal_2_g2d_pixel_order(unsigned int hal_format);
+
+/*
+ * change hal pixel format to g2d "bpp" (actual bpp for RGB formats, 8 bpp for
+ * YUV formats)
+ *
+ * @param hal_format
+ *   hal pixel format[in]
+ *
+ * @return
+ *   g2d bpp
+ */
+size_t hal_2_g2d_bpp(unsigned int hal_format);
+
+/*
  * Init CSC handle
  *
  * @return
@@ -117,6 +159,22 @@
     CSC_METHOD     *method);
 
 /*
+ * set color space converter method
+ *
+ * @param handle
+ *   CSC handle[in]
+ *
+ * @param method
+ *   CSC method[in]
+ *
+ * @return
+ *   error code
+ */
+CSC_ERRORCODE csc_set_method(
+    void           *handle,
+    CSC_METHOD     method);
+
+/*
  * Set hw property
  *
  * @param handle
diff --git a/libcsc/csc_helper.c b/libcsc/csc_helper.c
index 9f13d62..d5cb4fb 100644
--- a/libcsc/csc_helper.c
+++ b/libcsc/csc_helper.c
@@ -24,6 +24,7 @@
 
 #include "csc.h"
 #include "exynos_format.h"
+#include "fimg2d.h"
 
 OMX_COLOR_FORMATTYPE hal_2_omx_pixel_format(
     unsigned int hal_format)
@@ -45,7 +46,7 @@
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
         omx_format = OMX_SEC_COLOR_FormatNV12Tiled;
         break;
-    case HAL_PIXEL_FORMAT_ARGB888:
+    case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
         omx_format = OMX_COLOR_Format32bitARGB8888;
         break;
     default:
@@ -76,7 +77,7 @@
         hal_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED;
         break;
     case OMX_COLOR_Format32bitARGB8888:
-        hal_format = HAL_PIXEL_FORMAT_ARGB888;
+        hal_format = HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888;
         break;
     default:
         hal_format = HAL_PIXEL_FORMAT_YCbCr_420_P;
@@ -84,3 +85,89 @@
     }
     return hal_format;
 }
+
+unsigned int hal_2_g2d_color_format(unsigned int hal_format)
+{
+    switch (hal_format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
+        return CF_ARGB_8888;
+
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+        return CF_XRGB_8888;
+
+    case HAL_PIXEL_FORMAT_RGB_888:
+        return CF_RGB_888;
+
+    case HAL_PIXEL_FORMAT_RGB_565:
+        return CF_RGB_565;
+
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+        return CF_ARGB_1555;
+
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+        return CF_ARGB_4444;
+
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        return CF_YCBCR_422;
+
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        return CF_YCBCR_420;
+
+    default:
+        return SRC_DST_FORMAT_END;
+    }
+}
+
+unsigned int hal_2_g2d_pixel_order(unsigned int hal_format)
+{
+    switch (hal_format) {
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+    case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
+        return AX_BGR;
+
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_RGB_888:
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+        return RGB_AX;
+
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        return P1_Y1CBY0CR;
+
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        return P2_CBCR;
+
+    default:
+        return ARGB_ORDER_END;
+    }
+}
+
+size_t hal_2_g2d_bpp(unsigned int hal_format)
+{
+    switch (hal_format) {
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            return 32;
+
+        case HAL_PIXEL_FORMAT_RGB_888:
+            return 24;
+
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+            return 16;
+
+        case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+            return 8;
+
+        default:
+            return 0;
+        }
+}
diff --git a/libexynosutils/exynos5_format_v4l2.c b/libexynosutils/exynos5_format_v4l2.c
index 8b05717..824f133 100644
--- a/libexynosutils/exynos5_format_v4l2.c
+++ b/libexynosutils/exynos5_format_v4l2.c
@@ -52,6 +52,7 @@
     switch (hal_pixel_format) {
     case HAL_PIXEL_FORMAT_RGBA_8888:
     case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
         v4l2_pixel_format = V4L2_PIX_FMT_RGB32;
         break;
 
@@ -281,6 +282,7 @@
     case HAL_PIXEL_FORMAT_RGBA_8888:
     case HAL_PIXEL_FORMAT_BGRA_8888:
     case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_CUSTOM_ARGB_8888:
         frame_size = GET_32BPP_FRAME_SIZE(width, height);
         break;
 
diff --git a/libhwc/Android.mk b/libhwc/Android.mk
index 0463494..5ef9373 100644
--- a/libhwc/Android.mk
+++ b/libhwc/Android.mk
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-ifneq ($(filter manta full_manta,$(TARGET_DEVICE)),)
-
 LOCAL_PATH:= $(call my-dir)
 # HAL module implemenation, not prelinked and stored in
 # hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.product.board>.so
@@ -31,8 +29,6 @@
 
 LOCAL_SRC_FILES := hwc.cpp
 
-LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE := hwcomposer.exynos5
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_SHARED_LIBRARY)
-
-endif
diff --git a/libhwc/hwc.cpp b/libhwc/hwc.cpp
index 1a3d4a5..20f3a1d 100644
--- a/libhwc/hwc.cpp
+++ b/libhwc/hwc.cpp
@@ -199,6 +199,22 @@
 template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; }
 template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; }
 
+static int dup_or_warn(int fence)
+{
+    int dup_fd = dup(fence);
+    if (dup_fd < 0)
+        ALOGW("fence dup failed: %s", strerror(errno));
+    return dup_fd;
+}
+
+static int merge_or_warn(const char *name, int f1, int f2)
+{
+    int merge_fd = sync_merge(name, f1, f2);
+    if (merge_fd < 0)
+        ALOGW("fence merge failed: %s", strerror(errno));
+    return merge_fd;
+}
+
 template<typename T> void align_crop_and_center(T &w, T &h,
         hwc_rect_t *crop, size_t alignment)
 {
@@ -549,6 +565,10 @@
 
 static int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev)
 {
+    /* hdmi not supported */
+    if (dev->hdmi_mixer0 < 0)
+        return 0;
+
     if (dev->hdmi_enabled)
         return 0;
 
@@ -1509,9 +1529,7 @@
         if (pdev->bufs.overlay_map[i] != -1) {
             hwc_layer_1_t &layer =
                     contents->hwLayers[pdev->bufs.overlay_map[i]];
-            int dup_fd = dup(fence);
-            if (dup_fd < 0)
-                ALOGW("release fence dup failed: %s", strerror(errno));
+            int dup_fd = dup_or_warn(fence);
             if (pdev->bufs.gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) {
                 int gsc_idx = pdev->bufs.gsc_map[i].idx;
                 exynos5_gsc_data_t &gsc = pdev->gsc[gsc_idx];
@@ -1522,7 +1540,7 @@
             }
         }
     }
-    close(fence);
+    contents->retireFenceFd = fence;
 
     return err;
 }
@@ -1578,6 +1596,14 @@
 
             gsc.dst_buf_fence[gsc.current_buf] = releaseFenceFd;
             gsc.current_buf = (gsc.current_buf + 1) % NUM_GSC_DST_BUFS;
+            if (contents->retireFenceFd < 0)
+                contents->retireFenceFd = dup_or_warn(releaseFenceFd);
+            else {
+                int merged = merge_or_warn("hdmi",
+                        contents->retireFenceFd, layer.releaseFenceFd);
+                close(contents->retireFenceFd);
+                contents->retireFenceFd = merged;
+            }
         }
 
         if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
@@ -1589,6 +1615,15 @@
                 hdmi_show_layer(pdev, pdev->hdmi_layers[1]);
                 hdmi_output(pdev, pdev->hdmi_layers[1], layer, h, layer.acquireFenceFd,
                                                                  &layer.releaseFenceFd);
+
+                if (contents->retireFenceFd < 0)
+                    contents->retireFenceFd = dup_or_warn(layer.releaseFenceFd);
+                else {
+                    int merged = merge_or_warn("hdmi",
+                            contents->retireFenceFd, layer.releaseFenceFd);
+                    close(contents->retireFenceFd);
+                    contents->retireFenceFd = merged;
+                }
             } else {
                 hdmi_hide_layer(pdev, pdev->hdmi_layers[1]);
             }
@@ -1980,6 +2015,52 @@
 
 static int exynos5_close(hw_device_t* device);
 
+static void get_screen_res(const char *fbname, int32_t *xres, int32_t *yres,
+                           int32_t *refresh)
+{
+    char *path;
+    int fd;
+    char buf[128];
+    int ret;
+    unsigned int _x, _y, _r;
+
+    asprintf(&path, "/sys/class/graphics/%s/modes", fbname);
+    if (!path)
+        goto err_asprintf;
+    fd = open(path, O_RDONLY);
+    if (fd < 0)
+        goto err_open;
+    ret = read(fd, buf, sizeof(buf));
+    if (ret <= 0)
+        goto err_read;
+    buf[sizeof(buf)-1] = '\0';
+
+    ret = sscanf(buf, "U:%ux%up-%u", &_x, &_y, &_r);
+    if (ret != 3)
+        goto err_sscanf;
+
+    ALOGI("Using %ux%u %uHz resolution for '%s' from modes list\n",
+          _x, _y, _r, fbname);
+
+    *xres = (int32_t)_x;
+    *yres = (int32_t)_y;
+    *refresh = (int32_t)_r;
+
+    close(fd);
+    free(path);
+    return;
+
+err_sscanf:
+err_read:
+    close(fd);
+err_open:
+    free(path);
+err_asprintf:
+    *xres = 2560;
+    *yres = 1600;
+    *refresh = 60;
+}
+
 static int exynos5_open(const struct hw_module_t *module, const char *name,
         struct hw_device_t **device)
 {
@@ -2023,22 +2104,14 @@
         goto err_ioctl;
     }
 
-    refreshRate = 1000000000000LLU /
-        (
-         uint64_t( info.upper_margin + info.lower_margin + info.yres )
-         * ( info.left_margin  + info.right_margin + info.xres )
-         * info.pixclock
-        );
-
+    get_screen_res("fb0", &dev->xres, &dev->yres, &refreshRate);
     if (refreshRate == 0) {
         ALOGW("invalid refresh rate, assuming 60 Hz");
         refreshRate = 60;
     }
 
-    dev->xres = 2560;
-    dev->yres = 1600;
-    dev->xdpi = 1000 * (info.xres * 25.4f) / info.width;
-    dev->ydpi = 1000 * (info.yres * 25.4f) / info.height;
+    dev->xdpi = 1000 * (dev->xres * 25.4f) / info.width;
+    dev->ydpi = 1000 * (dev->yres * 25.4f) / info.height;
     dev->vsync_period  = 1000000000 / refreshRate;
 
     ALOGV("using\n"
@@ -2055,11 +2128,8 @@
             dev->gsc[i].dst_buf_fence[j] = -1;
 
     dev->hdmi_mixer0 = open("/dev/v4l-subdev7", O_RDWR);
-    if (dev->hdmi_mixer0 < 0) {
+    if (dev->hdmi_mixer0 < 0)
         ALOGE("failed to open hdmi mixer0 subdev");
-        ret = dev->hdmi_mixer0;
-        goto err_ioctl;
-    }
 
     dev->hdmi_layers[0].id = 0;
     dev->hdmi_layers[0].fd = open("/dev/video16", O_RDWR);
@@ -2129,7 +2199,8 @@
 err_vsync:
     close(dev->vsync_fd);
 err_mixer0:
-    close(dev->hdmi_mixer0);
+    if (dev->hdmi_mixer0 >= 0)
+        close(dev->hdmi_mixer0);
 err_hdmi1:
     close(dev->hdmi_layers[0].fd);
 err_hdmi0:
@@ -2153,7 +2224,8 @@
         exynos5_cleanup_gsc_m2m(dev, i);
     gralloc_close(dev->alloc_device);
     close(dev->vsync_fd);
-    close(dev->hdmi_mixer0);
+    if (dev->hdmi_mixer0 >= 0)
+        close(dev->hdmi_mixer0);
     close(dev->hdmi_layers[0].fd);
     close(dev->hdmi_layers[1].fd);
     close(dev->fd);
diff --git a/libkeymaster/Android.mk b/libkeymaster/Android.mk
index 975af6a..fa1950e 100644
--- a/libkeymaster/Android.mk
+++ b/libkeymaster/Android.mk
@@ -23,12 +23,11 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/hw
 LOCAL_SRC_FILES := keymaster_mobicore.cpp tlcTeeKeymaster_if.c
 LOCAL_C_INCLUDES := \
-	system/security/keystore \
 	external/openssl/include \
 	$(MOBICORE_PATH)/daemon/ClientLib/public \
 	$(MOBICORE_PATH)/common/MobiCore/inc/
 LOCAL_C_FLAGS = -fvisibility=hidden -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_client libMcClient
+LOCAL_SHARED_LIBRARIES := libcrypto liblog libMcClient
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 
diff --git a/libkeymaster/keymaster_mobicore.cpp b/libkeymaster/keymaster_mobicore.cpp
index 0d3a05a..1cfcc50 100644
--- a/libkeymaster/keymaster_mobicore.cpp
+++ b/libkeymaster/keymaster_mobicore.cpp
@@ -19,8 +19,6 @@
 #include <string.h>
 #include <stdint.h>
 
-#include <keystore.h>
-
 #include <hardware/hardware.h>
 #include <hardware/keymaster.h>
 
diff --git a/original-kernel-headers/linux/fimg2d.h b/original-kernel-headers/linux/fimg2d.h
new file mode 100644
index 0000000..ceda93c
--- /dev/null
+++ b/original-kernel-headers/linux/fimg2d.h
@@ -0,0 +1,465 @@
+/* linux/drivers/media/video/samsung/fimg2d4x/fimg2d.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *	http://www.samsung.com/
+ *
+ * Samsung Graphics 2D driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __FIMG2D_H
+#define __FIMG2D_H __FILE__
+
+#ifdef __KERNEL__
+
+#include <linux/clk.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-buf.h>
+
+#define FIMG2D_MINOR			(240)
+#define to_fimg2d_plat(d)		(to_platform_device(d)->dev.platform_data)
+
+#ifdef CONFIG_VIDEO_FIMG2D_DEBUG
+#define fimg2d_debug(fmt, arg...)	printk(KERN_INFO "[%s] " fmt, __func__, ## arg)
+#else
+#define fimg2d_debug(fmt, arg...)	do { } while (0)
+#endif
+
+#endif /* __KERNEL__ */
+
+#define FIMG2D_MAX_PLANES	2
+
+/* ioctl commands */
+#define FIMG2D_IOCTL_MAGIC	'F'
+#define FIMG2D_BITBLT_BLIT	_IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit)
+#define FIMG2D_BITBLT_SYNC	_IOW(FIMG2D_IOCTL_MAGIC, 1, int)
+#define FIMG2D_BITBLT_VERSION	_IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version)
+
+struct fimg2d_version {
+	unsigned int hw;
+	unsigned int sw;
+};
+
+/**
+ * @BLIT_SYNC: sync mode, to wait for blit done irq
+ * @BLIT_ASYNC: async mode, not to wait for blit done irq
+ *
+ */
+enum blit_sync {
+	BLIT_SYNC,
+	BLIT_ASYNC,
+};
+
+/**
+ * @ADDR_NONE: no image/solid color
+ * @ADDR_DMA_BUF: dma-buf fds
+ */
+enum addr_space {
+	ADDR_NONE = 0,
+	ADDR_DMA_BUF,
+};
+
+/**
+ * Pixel order complies with little-endian style
+ *
+ * DO NOT CHANGE THIS ORDER
+ */
+enum pixel_order {
+	AX_RGB = 0,
+	RGB_AX,
+	AX_BGR,
+	BGR_AX,
+	ARGB_ORDER_END,
+
+	P1_CRY1CBY0,
+	P1_CBY1CRY0,
+	P1_Y1CRY0CB,
+	P1_Y1CBY0CR,
+	P1_ORDER_END,
+
+	P2_CRCB,
+	P2_CBCR,
+	P2_ORDER_END,
+};
+
+/**
+ * DO NOT CHANGE THIS ORDER
+ */
+enum color_format {
+	CF_XRGB_8888 = 0,
+	CF_ARGB_8888,
+	CF_RGB_565,
+	CF_XRGB_1555,
+	CF_ARGB_1555,
+	CF_XRGB_4444,
+	CF_ARGB_4444,
+	CF_RGB_888,
+	CF_YCBCR_444,
+	CF_YCBCR_422,
+	CF_YCBCR_420,
+	CF_A8,
+	CF_L8,
+	SRC_DST_FORMAT_END,
+
+	CF_MSK_1BIT,
+	CF_MSK_4BIT,
+	CF_MSK_8BIT,
+	CF_MSK_16BIT_565,
+	CF_MSK_16BIT_1555,
+	CF_MSK_16BIT_4444,
+	CF_MSK_32BIT_8888,
+	MSK_FORMAT_END,
+};
+
+enum rotation {
+	ORIGIN,
+	ROT_90,	/* clockwise */
+	ROT_180,
+	ROT_270,
+	XFLIP,	/* x-axis flip */
+	YFLIP,	/* y-axis flip */
+};
+
+/**
+ * @NO_REPEAT: no effect
+ * @REPEAT_NORMAL: repeat horizontally and vertically
+ * @REPEAT_PAD: pad with pad color
+ * @REPEAT_REFLECT: reflect horizontally and vertically
+ * @REPEAT_CLAMP: pad with edge color of original image
+ *
+ * DO NOT CHANGE THIS ORDER
+ */
+enum repeat {
+	NO_REPEAT = 0,
+	REPEAT_NORMAL,	/* default setting */
+	REPEAT_PAD,
+	REPEAT_REFLECT, REPEAT_MIRROR = REPEAT_REFLECT,
+	REPEAT_CLAMP,
+};
+
+enum scaling {
+	NO_SCALING,
+	SCALING_NEAREST,
+	SCALING_BILINEAR,
+};
+
+/**
+ * @SCALING_PIXELS: ratio in pixels
+ * @SCALING_RATIO: ratio in fixed point 16
+ */
+enum scaling_factor {
+	SCALING_PIXELS,
+	SCALING_RATIO,
+};
+
+/**
+ * premultiplied alpha
+ */
+enum premultiplied {
+	PREMULTIPLIED,
+	NON_PREMULTIPLIED,
+};
+
+/**
+ * @TRANSP: discard bluescreen color
+ * @BLUSCR: replace bluescreen color with background color
+ */
+enum bluescreen {
+	OPAQUE,
+	TRANSP,
+	BLUSCR,
+};
+
+/**
+ * DO NOT CHANGE THIS ORDER
+ */
+enum blit_op {
+	BLIT_OP_SOLID_FILL = 0,
+
+	BLIT_OP_CLR,
+	BLIT_OP_SRC, BLIT_OP_SRC_COPY = BLIT_OP_SRC,
+	BLIT_OP_DST,
+	BLIT_OP_SRC_OVER,
+	BLIT_OP_DST_OVER, BLIT_OP_OVER_REV = BLIT_OP_DST_OVER,
+	BLIT_OP_SRC_IN,
+	BLIT_OP_DST_IN, BLIT_OP_IN_REV = BLIT_OP_DST_IN,
+	BLIT_OP_SRC_OUT,
+	BLIT_OP_DST_OUT, BLIT_OP_OUT_REV = BLIT_OP_DST_OUT,
+	BLIT_OP_SRC_ATOP,
+	BLIT_OP_DST_ATOP, BLIT_OP_ATOP_REV = BLIT_OP_DST_ATOP,
+	BLIT_OP_XOR,
+
+	BLIT_OP_ADD,
+	BLIT_OP_MULTIPLY,
+	BLIT_OP_SCREEN,
+	BLIT_OP_DARKEN,
+	BLIT_OP_LIGHTEN,
+
+	BLIT_OP_DISJ_SRC_OVER,
+	BLIT_OP_DISJ_DST_OVER, BLIT_OP_SATURATE = BLIT_OP_DISJ_DST_OVER,
+	BLIT_OP_DISJ_SRC_IN,
+	BLIT_OP_DISJ_DST_IN, BLIT_OP_DISJ_IN_REV = BLIT_OP_DISJ_DST_IN,
+	BLIT_OP_DISJ_SRC_OUT,
+	BLIT_OP_DISJ_DST_OUT, BLIT_OP_DISJ_OUT_REV = BLIT_OP_DISJ_DST_OUT,
+	BLIT_OP_DISJ_SRC_ATOP,
+	BLIT_OP_DISJ_DST_ATOP, BLIT_OP_DISJ_ATOP_REV = BLIT_OP_DISJ_DST_ATOP,
+	BLIT_OP_DISJ_XOR,
+
+	BLIT_OP_CONJ_SRC_OVER,
+	BLIT_OP_CONJ_DST_OVER, BLIT_OP_CONJ_OVER_REV = BLIT_OP_CONJ_DST_OVER,
+	BLIT_OP_CONJ_SRC_IN,
+	BLIT_OP_CONJ_DST_IN, BLIT_OP_CONJ_IN_REV = BLIT_OP_CONJ_DST_IN,
+	BLIT_OP_CONJ_SRC_OUT,
+	BLIT_OP_CONJ_DST_OUT, BLIT_OP_CONJ_OUT_REV = BLIT_OP_CONJ_DST_OUT,
+	BLIT_OP_CONJ_SRC_ATOP,
+	BLIT_OP_CONJ_DST_ATOP, BLIT_OP_CONJ_ATOP_REV = BLIT_OP_CONJ_DST_ATOP,
+	BLIT_OP_CONJ_XOR,
+
+	/* user select coefficient manually */
+	BLIT_OP_USER_COEFF,
+
+	BLIT_OP_USER_SRC_GA,
+
+	/* Add new operation type here */
+
+	/* end of blit operation */
+	BLIT_OP_END,
+};
+#define MAX_FIMG2D_BLIT_OP (int)BLIT_OP_END
+
+#ifdef __KERNEL__
+
+/**
+ * @TMP: temporary buffer for 2-step blit at a single command
+ *
+ * DO NOT CHANGE THIS ORDER
+ */
+enum image_object {
+	IMAGE_SRC = 0,
+	IMAGE_MSK,
+	IMAGE_TMP,
+	IMAGE_DST,
+	IMAGE_END,
+};
+#define MAX_IMAGES		IMAGE_END
+#define ISRC			IMAGE_SRC
+#define IMSK			IMAGE_MSK
+#define ITMP			IMAGE_TMP
+#define IDST			IMAGE_DST
+#define image_table(u)		\
+	{			\
+		(u)->src,	\
+		(u)->msk,	\
+		(u)->tmp,	\
+		(u)->dst	\
+	}
+
+struct fimg2d_dma {
+	struct dma_buf *dma_buf;
+	struct dma_buf_attachment *attachment;
+	struct sg_table *sg_table;
+	dma_addr_t dma_addr;
+	enum dma_data_direction direction;
+};
+
+#endif /* __KERNEL__ */
+
+struct fimg2d_addr {
+	enum addr_space type;
+	int fd[FIMG2D_MAX_PLANES];
+};
+
+struct fimg2d_rect {
+	int x1;
+	int y1;
+	int x2;	/* x1 + width */
+	int y2; /* y1 + height */
+};
+
+/**
+ * pixels can be different from src, dst or clip rect
+ */
+struct fimg2d_scale {
+	enum scaling mode;
+
+	/* ratio in pixels */
+	int src_w, src_h;
+	int dst_w, dst_h;
+};
+
+struct fimg2d_clip {
+	__u32 enable;
+	int x1;
+	int y1;
+	int x2;	/* x1 + width */
+	int y2; /* y1 + height */
+};
+
+struct fimg2d_repeat {
+	enum repeat mode;
+	unsigned long pad_color;
+};
+
+/**
+ * @bg_color: bg_color is valid only if bluescreen mode is BLUSCR.
+ */
+struct fimg2d_bluscr {
+	enum bluescreen mode;
+	unsigned long bs_color;
+	unsigned long bg_color;
+};
+
+/**
+ * @plane2: address info for CbCr in YCbCr 2plane mode
+ * @rect: crop/clip rect
+ */
+struct fimg2d_image {
+	int width;
+	int height;
+	int stride;
+	enum pixel_order order;
+	enum color_format fmt;
+	struct fimg2d_addr addr;
+	struct fimg2d_rect rect;
+};
+
+/**
+ * @solid_color:
+ *         src color instead of src image
+ *         color format and order must be ARGB8888(A is MSB).
+ * @g_alpha: global(constant) alpha. 0xff is opaque, 0 is transparnet
+ * @dither: dithering
+ * @rotate: rotation degree in clockwise
+ * @premult: alpha premultiplied mode for read & write
+ * @scaling: common scaling info for src and mask image.
+ * @repeat: repeat type (tile mode)
+ * @bluscr: blue screen and transparent mode
+ * @clipping: clipping rect within dst rect
+ */
+struct fimg2d_param {
+	unsigned long solid_color;
+	unsigned char g_alpha;
+	__u32 dither;
+	enum rotation rotate;
+	enum premultiplied premult;
+	struct fimg2d_scale scaling;
+	struct fimg2d_repeat repeat;
+	struct fimg2d_bluscr bluscr;
+	struct fimg2d_clip clipping;
+};
+
+/**
+ * @op: blit operation mode
+ * @src: set when using src image
+ * @msk: set when using mask image
+ * @tmp: set when using 2-step blit at a single command
+ * @dst: dst must not be null
+ *         * tmp image must be the same to dst except memory address
+ * @seq_no: user debugging info.
+ *          for example, user can set sequence number or pid.
+ */
+struct fimg2d_blit {
+	enum blit_op op;
+	struct fimg2d_param param;
+	struct fimg2d_image *src;
+	struct fimg2d_image *msk;
+	struct fimg2d_image *tmp;
+	struct fimg2d_image *dst;
+	enum blit_sync sync;
+	unsigned int seq_no;
+};
+
+#ifdef __KERNEL__
+
+/**
+ * @ncmd: request count in blit command queue
+ * @wait_q: conext wait queue head
+*/
+struct fimg2d_context {
+	atomic_t ncmd;
+	wait_queue_head_t wait_q;
+};
+
+/**
+ * @op: blit operation mode
+ * @sync: sync/async blit mode (currently support sync mode only)
+ * @image: array of image object.
+ *         [0] is for src image
+ *         [1] is for mask image
+ *         [2] is for temporary buffer
+ *             set when using 2-step blit at a single command
+ *         [3] is for dst, dst must not be null
+ *         * tmp image must be the same to dst except memory address
+ * @seq_no: user debugging info.
+ *          for example, user can set sequence number or pid.
+ * @dma_all: total dma size of src, msk, dst
+ * @dma: array of dma info for each src, msk, tmp and dst
+ * @ctx: context is created when user open fimg2d device.
+ * @node: list head of blit command queue
+ */
+struct fimg2d_bltcmd {
+	enum blit_op op;
+	enum blit_sync sync;
+	unsigned int seq_no;
+	struct fimg2d_param param;
+	struct fimg2d_image image[MAX_IMAGES];
+	struct fimg2d_dma dma[MAX_IMAGES][FIMG2D_MAX_PLANES];
+	struct fimg2d_context *ctx;
+	struct list_head node;
+};
+
+/**
+ * @suspended: in suspend mode
+ * @clkon: power status for runtime pm
+ * @mem: resource platform device
+ * @regs: base address of hardware
+ * @dev: pointer to device struct
+ * @err: true if hardware is timed out while blitting
+ * @irq: irq number
+ * @nctx: context count
+ * @busy: 1 if hardware is running
+ * @bltlock: spinlock for blit
+ * @wait_q: blit wait queue head
+ * @cmd_q: blit command queue
+ * @workqueue: workqueue_struct for kfimg2dd
+*/
+struct fimg2d_control {
+	atomic_t suspended;
+	atomic_t clkon;
+	struct clk *clock;
+	struct device *dev;
+	struct resource *mem;
+	void __iomem *regs;
+
+	bool err;
+	int irq;
+	atomic_t nctx;
+	atomic_t busy;
+	atomic_t active;
+	spinlock_t bltlock;
+	wait_queue_head_t wait_q;
+	struct list_head cmd_q;
+	struct workqueue_struct *work_q;
+
+	void (*blit)(struct fimg2d_control *info);
+	int (*configure)(struct fimg2d_control *info,
+			struct fimg2d_bltcmd *cmd);
+	void (*run)(struct fimg2d_control *info);
+	void (*stop)(struct fimg2d_control *info);
+	void (*dump)(struct fimg2d_control *info);
+	void (*finalize)(struct fimg2d_control *info);
+};
+
+int fimg2d_register_ops(struct fimg2d_control *info);
+
+#endif /* __KERNEL__ */
+
+#endif /* __FIMG2D_H__ */