Merge "fstab files: update to mount cache with noatime option"
diff --git a/gralloc960/Android.hikey960.mk b/gralloc960/Android.hikey960.mk
index a7bb472..b865bf1 100644
--- a/gralloc960/Android.hikey960.mk
+++ b/gralloc960/Android.hikey960.mk
@@ -16,8 +16,6 @@
 # limitations under the License.
 
 $(info gralloc for hikey960)
-GRALLOC_FB_SWAP_RED_BLUE := 0
-GRALLOC_DEPTH := GRALLOC_32_BITS
 
 # GPU support for AFBC 1.0
 MALI_GPU_SUPPORT_AFBC_BASIC=1
@@ -34,12 +32,16 @@
 # Software behaviour defines
 #
 
+# Gralloc1 support
+GRALLOC_USE_GRALLOC1_API=0
 # Use ION DMA heap for all allocations. Default is system heap.
 GRALLOC_USE_ION_DMA_HEAP=0
 # Use ION Compound heap for all allocations. Default is system heap.
 GRALLOC_USE_ION_COMPOUND_PAGE_HEAP=0
 # Properly initializes an empty AFBC buffer
 GRALLOC_INIT_AFBC=0
+# fbdev bitdepth to use
+GRALLOC_DEPTH=GRALLOC_32_BITS
 # When enabled, forces display framebuffer format to BGRA_8888
 GRALLOC_FB_SWAP_RED_BLUE=0
 # Disables the framebuffer HAL device. When a hwc impl is available.
diff --git a/gralloc960/Android.mk b/gralloc960/Android.mk
index 0435779..0609226 100644
--- a/gralloc960/Android.mk
+++ b/gralloc960/Android.mk
@@ -1,5 +1,5 @@
 # 
-# Copyright (C) 2016 ARM Limited. All rights reserved.
+# Copyright (C) 2016-2017 ARM Limited. All rights reserved.
 # 
 # Copyright (C) 2008 The Android Open Source Project
 #
@@ -46,6 +46,8 @@
 # Software behaviour defines
 #
 
+# Gralloc1 support
+GRALLOC_USE_GRALLOC1_API?=0
 # Use ION DMA heap for all allocations. Default is system heap.
 GRALLOC_USE_ION_DMA_HEAP?=0
 # Use ION Compound heap for all allocations. Default is system heap.
@@ -69,6 +71,7 @@
 # HAL module implemenation, not prelinked and stored in
 # hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
 include $(CLEAR_VARS)
+include $(BUILD_SYSTEM)/version_defaults.mk
 
 ifeq ($(TARGET_BOARD_PLATFORM), juno)
 ifeq ($(MALI_MMSS), 1)
@@ -108,6 +111,14 @@
 endif
 endif
 
+PLATFORM_SDK_GREATER_THAN_24 := $(shell expr $(PLATFORM_SDK_VERSION) \> 24)
+
+ifeq ($(PLATFORM_SDK_GREATER_THAN_24), 1)
+ifeq ($(GRALLOC_EXPERIMENTAL), 1)
+	GRALLOC_USE_GRALLOC1_API := 1
+endif
+endif
+
 LOCAL_C_INCLUDES := $(MALI_LOCAL_PATH) $(MALI_DDK_INCLUDES)
 
 # General compilation flags
@@ -124,6 +135,7 @@
 LOCAL_CFLAGS += -DMALI_VIDEO_VERSION=$(MALI_VIDEO_VERSION)
 
 # Software behaviour flags
+LOCAL_CFLAGS += -DGRALLOC_USE_GRALLOC1_API=$(GRALLOC_USE_GRALLOC1_API)
 LOCAL_CFLAGS += -DGRALLOC_DISP_W=$(GRALLOC_DISP_W)
 LOCAL_CFLAGS += -DGRALLOC_DISP_H=$(GRALLOC_DISP_H)
 LOCAL_CFLAGS += -DDISABLE_FRAMEBUFFER_HAL=$(GRALLOC_DISABLE_FRAMEBUFFER_HAL)
@@ -133,28 +145,39 @@
 LOCAL_CFLAGS += -D$(GRALLOC_DEPTH)
 LOCAL_CFLAGS += -DGRALLOC_FB_SWAP_RED_BLUE=$(GRALLOC_FB_SWAP_RED_BLUE)
 LOCAL_CFLAGS += -DGRALLOC_ARM_NO_EXTERNAL_AFBC=$(GRALLOC_ARM_NO_EXTERNAL_AFBC)
+LOCAL_CFLAGS += -DGRALLOC_LIBRARY_BUILD=1
 
-LOCAL_SHARED_LIBRARIES := libhardware liblog libcutils libGLESv1_CM libion
+LOCAL_SHARED_LIBRARIES := libhardware liblog libcutils libGLESv1_CM libion libsync libutils
 
 LOCAL_PRELINK_MODULE := false
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
 LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
-
 LOCAL_MODULE := gralloc.hikey960
 
 LOCAL_MODULE_TAGS := optional
 LOCAL_MULTILIB := both
 
 LOCAL_SRC_FILES := \
-	gralloc_module.cpp \
-	alloc_device.cpp \
-	alloc_ion.cpp \
-	gralloc_module_ion.cpp \
+	mali_gralloc_module.cpp \
 	framebuffer_device.cpp \
 	gralloc_buffer_priv.cpp \
 	gralloc_vsync_${GRALLOC_VSYNC_BACKEND}.cpp \
-	mali_gralloc_formats.cpp
+	mali_gralloc_bufferaccess.cpp \
+	mali_gralloc_bufferallocation.cpp \
+	mali_gralloc_bufferdescriptor.cpp \
+	mali_gralloc_ion.cpp \
+	mali_gralloc_formats.cpp \
+	mali_gralloc_reference.cpp \
+	mali_gralloc_debug.cpp
+
+ifeq ($(GRALLOC_USE_GRALLOC1_API), 1)
+LOCAL_SRC_FILES += \
+	mali_gralloc_public_interface.cpp \
+	mali_gralloc_private_interface.cpp
+else
+LOCAL_SRC_FILES += legacy/alloc_device.cpp
+endif
 
 LOCAL_MODULE_OWNER := arm
 
diff --git a/gralloc960/alloc_device.h b/gralloc960/alloc_device.h
deleted file mode 100644
index bcbc1dc..0000000
--- a/gralloc960/alloc_device.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <hardware/hardware.h>
-
-#ifndef AWAR
-#define AWAR(fmt, args...) __android_log_print(ANDROID_LOG_WARN, "[Gralloc-Warning]", "%s:%d " fmt,__func__,__LINE__,##args)
-#endif
-#ifndef AINF
-#define AINF(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "[Gralloc]", fmt,##args)
-#endif
-#ifndef AERR
-#define AERR(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "[Gralloc-ERROR]", "%s:%d " fmt,__func__,__LINE__,##args)
-#endif
-#ifndef AERR_IF
-#define AERR_IF( eq, fmt, args...) if ( (eq) ) AERR( fmt, args )
-#endif
-
-#define GRALLOC_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
-
-// Create an alloc device
-int alloc_device_open(hw_module_t const* module, const char* name, hw_device_t** device);
diff --git a/gralloc960/alloc_device_allocator_specific.h b/gralloc960/alloc_device_allocator_specific.h
deleted file mode 100644
index 2de38b5..0000000
--- a/gralloc960/alloc_device_allocator_specific.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2013 ARM Limited. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-int alloc_backend_alloc(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, uint64_t fmt, int w, int h);
-
-int alloc_backend_alloc_framebuffer(struct private_module_t* m, struct private_handle_t* hnd);
-
-void alloc_backend_alloc_free(struct private_handle_t const* hnd, struct private_module_t* m);
-
-int alloc_backend_open(alloc_device_t *dev);
-
-int alloc_backend_close(struct hw_device_t *device);
diff --git a/gralloc960/alloc_ion.cpp b/gralloc960/alloc_ion.cpp
deleted file mode 100644
index 0a84aaa..0000000
--- a/gralloc960/alloc_ion.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (C) 2013 ARM Limited. All rights reserved.
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cstdlib>
-#include <string.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <pthread.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <hardware/hardware.h>
-#include <hardware/gralloc.h>
-
-#include <sys/ioctl.h>
-
-#include "alloc_device.h"
-#include "gralloc_priv.h"
-#include "gralloc_helper.h"
-#include "framebuffer_device.h"
-#include "ion_4.12.h"
-
-#include "mali_gralloc_formats.h"
-
-#include <linux/ion.h>
-#include <ion/ion.h>
-
-static void init_afbc(uint8_t *buf, uint64_t internal_format, int w, int h)
-{
-	uint32_t n_headers = (w * h) / 64;
-	uint32_t body_offset = n_headers * 16;
-	uint32_t headers[][4] = { {body_offset, 0x1, 0x0, 0x0}, /* Layouts 0, 3, 4 */
-	                          {(body_offset + (1 << 28)), 0x200040, 0x4000, 0x80} /* Layouts 1, 5 */
-	                        };
-	uint32_t i, layout;
-
-	/* map format if necessary (also removes internal extension bits) */
-	uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
-
-	switch (base_format)
-	{
-		case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888:
-		case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888:
-		case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888:
-		case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565:
-		case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888:
-			layout = 0;
-			break;
-
-		case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
-		case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
-		case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
-			layout = 1;
-			break;
-		default:
-			layout = 0;
-	}
-
-	ALOGV("Writing AFBC header layout %d for format %" PRIu64, layout, base_format);
-
-	for (i = 0; i < n_headers; i++)
-	{
-		memcpy(buf, headers[layout], sizeof(headers[layout]));
-		buf += sizeof(headers[layout]);
-	}
-
-}
-
-static ion_user_handle_t alloc_from_ion_heap(int ion_fd, size_t size, unsigned int heap_mask,
-		unsigned int flags, int *min_pgsz)
-{
-	ion_user_handle_t ion_hnd = -1;
-	int ret;
-
-	if ((ion_fd < 0) || (size <= 0) || (heap_mask == 0) || (min_pgsz == NULL))
-		return -1;
-
-	ret = ion_alloc(ion_fd, size, 0, heap_mask, flags, &ion_hnd);
-	if (ret < 0)
-	{
-#if defined(ION_HEAP_SECURE_MASK)
-		if (heap_mask == ION_HEAP_SECURE_MASK)
-		{
-			return -1;
-		}
-		else
-#endif
-		{
-			/* If everything else failed try system heap */
-			flags = 0; /* Fallback option flags are not longer valid */
-			heap_mask = ION_HEAP_SYSTEM_MASK;
-			ret = ion_alloc(ion_fd, size, 0, heap_mask, flags, &ion_hnd);
-		}
-	}
-
-	if (ret >= 0)
-	{
-		switch (heap_mask)
-		{
-		case ION_HEAP_SYSTEM_MASK:
-			*min_pgsz = SZ_4K;
-			break;
-		case ION_HEAP_SYSTEM_CONTIG_MASK:
-		case ION_HEAP_CARVEOUT_MASK:
-#ifdef ION_HEAP_TYPE_DMA_MASK
-		case ION_HEAP_TYPE_DMA_MASK:
-#endif
-			*min_pgsz = size;
-			break;
-#ifdef ION_HEAP_CHUNK_MASK
-		/* NOTE: if have this heap make sure your ION chunk size is 2M*/
-		case ION_HEAP_CHUNK_MASK:
-			*min_pgsz = SZ_2M;
-			break;
-#endif
-#ifdef ION_HEAP_COMPOUND_PAGE_MASK
-		case ION_HEAP_COMPOUND_PAGE_MASK:
-			*min_pgsz = SZ_2M;
-			break;
-#endif
-		/* If have customized heap please set the suitable pg type according to
-		 * the customized ION implementation
-		 */
-#ifdef ION_HEAP_CUSTOM_MASK
-		case ION_HEAP_CUSTOM_MASK:
-			*min_pgsz = SZ_4K;
-			break;
-#endif
-		default:
-			*min_pgsz = SZ_4K;
-			break;
-		}
-	}
-
-	return ion_hnd;
-}
-
-static int find_system_heap_id(int ion_client)
-{
-	int i, ret, cnt, system_heap_id = -1;
-	struct ion_heap_data *data;
-
-	ret = ion_query_heap_cnt(ion_client, &cnt);
-
-	if (ret)
-	{
-		AERR("ion count query failed with %s", strerror(errno));
-		return -1;
-	}
-
-	data = (struct ion_heap_data *)malloc(cnt * sizeof(*data));
-	if (!data)
-	{
-		AERR("Error allocating data %s\n", strerror(errno));
-		return -1;
-	}
-
-	ret = ion_query_get_heaps(ion_client, cnt, data);
-	if (ret)
-	{
-		AERR("Error querying heaps from ion %s", strerror(errno));
-	}
-	else
-	{
-		for (i = 0; i < cnt; i++) {
-			if (strcmp(data[i].name, "ion_system_heap") == 0) {
-				system_heap_id = data[i].heap_id;
-				break;
-			}
-		}
-
-		if (i == cnt)
-		{
-			AERR("No System Heap Found amongst %d heaps\n", cnt);
-			system_heap_id = -1;
-		}
-	}
-
-	free(data);
-	return system_heap_id;
-}
-
-unsigned int pick_ion_heap(int usage)
-{
-	unsigned int heap_mask;
-
-	if(usage & GRALLOC_USAGE_PROTECTED)
-	{
-#if defined(ION_HEAP_SECURE_MASK)
-		heap_mask = ION_HEAP_SECURE_MASK;
-#else
-		AERR("Protected ION memory is not supported on this platform.");
-		return 0;
-#endif
-	}
-#if defined(ION_HEAP_TYPE_COMPOUND_PAGE_MASK) && GRALLOC_USE_ION_COMPOUND_PAGE_HEAP
-	else if(!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER)))
-	{
-		heap_mask = ION_HEAP_TYPE_COMPOUND_PAGE_MASK;
-	}
-#elif defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
-	else if(!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER)))
-	{
-		heap_mask = ION_HEAP_TYPE_DMA_MASK;
-	}
-#endif
-	else
-	{
-		heap_mask = ION_HEAP_SYSTEM_MASK;
-	}
-
-	return heap_mask;
-}
-
-void set_ion_flags(unsigned int heap_mask, int usage, unsigned int *priv_heap_flag, int *ion_flags)
-{
-#if !GRALLOC_USE_ION_DMA_HEAP
-	GRALLOC_UNUSED(heap_mask);
-#endif
-
-	if (priv_heap_flag)
-	{
-#if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
-		if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
-		{
-			*priv_heap_flag = private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP;
-		}
-#endif
-	}
-
-	if (ion_flags)
-	{
-#if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
-		if(heap_mask != ION_HEAP_TYPE_DMA_MASK)
-		{
-#endif
-			if ( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
-			{
-				*ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
-			}
-#if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
-		}
-#endif
-	}
-}
-
-int alloc_backend_alloc(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, uint64_t fmt, int w, int h)
-{
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
-	unsigned char *cpu_ptr = NULL;
-	int shared_fd;
-	int ret;
-	unsigned int heap_mask, priv_heap_flag = 0;
-	int ion_flags = 0;
-	static int support_protected = 1; /* initially, assume we support protected memory */
-	int lock_state = 0;
-	int min_pgsz = 0;
-
-	if (m->gralloc_legacy_ion)
-	{
-		ion_user_handle_t ion_hnd;
-
-		heap_mask = pick_ion_heap(usage);
-		if(heap_mask == 0)
-		{
-			AERR("Failed to find an appropriate ion heap");
-			return -1;
-		}
-		set_ion_flags(heap_mask, usage, &priv_heap_flag, &ion_flags);
-
-		ion_hnd = alloc_from_ion_heap(m->ion_client, size, heap_mask, ion_flags, &min_pgsz);
-		if (ion_hnd < 0)
-		{
-			AERR("Failed to ion_alloc from ion_client:%d", m->ion_client);
-			return -1;
-		}
-
-		ret = ion_share( m->ion_client, ion_hnd, &shared_fd );
-		if ( ret != 0 )
-		{
-			AERR( "ion_share( %d ) failed", m->ion_client );
-			if ( 0 != ion_free( m->ion_client, ion_hnd ) ) AERR( "ion_free( %d ) failed", m->ion_client );
-			return -1;
-		}
-
-		// we do not need ion_hnd once we have shared_fd
-		if (0 != ion_free(m->ion_client, ion_hnd))
-		{
-		    AWAR("ion_free( %d ) failed", m->ion_client);
-		}
-		ion_hnd = -1;
-	}
-	else
-	{
-		/* Support only System heap to begin with */
-		ret = ion_alloc_fd(m->ion_client, size, 0, 1 << m->system_heap_id, 0, &(shared_fd));
-		if (ret != 0)
-		{
-			AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client);
-			return -1;
-		}
-		min_pgsz = SZ_4K;
-	}
-
-	if (!(usage & GRALLOC_USAGE_PROTECTED))
-	{
-		cpu_ptr = (unsigned char*)mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0 );
-
-		if ( MAP_FAILED == cpu_ptr )
-		{
-			AERR( "ion_map( %d ) failed", m->ion_client );
-			close( shared_fd );
-			return -1;
-		}
-		lock_state = private_handle_t::LOCK_STATE_MAPPED;
-
-#if GRALLOC_INIT_AFBC == 1
-		if (fmt & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
-		{
-			init_afbc(cpu_ptr, fmt, w, h);
-		}
-#else
-		GRALLOC_UNUSED(fmt);
-		GRALLOC_UNUSED(w);
-		GRALLOC_UNUSED(h);
-
-#endif /* GRALLOC_INIT_AFBC == 1 */
-	}
-
-	private_handle_t *hnd = new private_handle_t( private_handle_t::PRIV_FLAGS_USES_ION | priv_heap_flag, usage, size, cpu_ptr,
-	                                              lock_state, -1, 0);
-
-	if ( NULL != hnd )
-	{
-		hnd->share_fd = shared_fd;
-		hnd->min_pgsz = min_pgsz;
-		*pHandle = hnd;
-		return 0;
-	}
-	else
-	{
-		AERR( "Gralloc out of mem for ion_client:%d", m->ion_client );
-	}
-
-	close( shared_fd );
-
-	if(!(usage & GRALLOC_USAGE_PROTECTED))
-	{
-		ret = munmap( cpu_ptr, size );
-		if ( 0 != ret ) AERR( "munmap failed for base:%p size: %zd", cpu_ptr, size );
-	}
-
-	return -1;
-}
-
-int alloc_backend_alloc_framebuffer(private_module_t* m, private_handle_t* hnd)
-{
-	struct fb_dmabuf_export fb_dma_buf;
-	int res;
-	res = ioctl( m->framebuffer->shallow_fbdev_fd, FBIOGET_DMABUF, &fb_dma_buf );
-	if(res == 0)
-	{
-		hnd->share_fd = fb_dma_buf.fd;
-		return 0;
-	}
-	else
-	{
-		AINF("FBIOGET_DMABUF ioctl failed(%d). See gralloc_priv.h and the integration manual for vendor framebuffer integration", res);
-		return -1;
-	}
-}
-
-void alloc_backend_alloc_free(private_handle_t const* hnd, private_module_t* m)
-{
-	(void) m;
-	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
-	{
-		return;
-	}
-	else if ( hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION )
-	{
-		/* Buffer might be unregistered already so we need to assure we have a valid handle*/
-		if ( 0 != hnd->base )
-		{
-			if ( 0 != munmap( (void*)hnd->base, hnd->size ) ) AERR( "Failed to munmap handle %p", hnd );
-		}
-		close( hnd->share_fd );
-		memset( (void*)hnd, 0, sizeof( *hnd ) );
-	}
-}
-
-int alloc_backend_open(alloc_device_t *dev)
-{
-	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
-	m->ion_client = ion_open();
-	if ( m->ion_client < 0 )
-	{
-		AERR( "ion_open failed with %s", strerror(errno) );
-		return -1;
-	}
-
-	m->gralloc_legacy_ion = ion_is_legacy(m->ion_client);
-
-	if (!m->gralloc_legacy_ion)
-	{
-		m->system_heap_id = find_system_heap_id(m->ion_client);
-		if (m->system_heap_id < 0)
-		{
-			ion_close(m->ion_client);
-			m->ion_client = -1;
-			AERR( "ion_open failed: no system heap found" );
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-int alloc_backend_close(struct hw_device_t *device)
-{
-	alloc_device_t* dev = reinterpret_cast<alloc_device_t*>(device);
-	if (dev)
-	{
-		private_module_t *m = reinterpret_cast<private_module_t*>(dev->common.module);
-		if ( 0 != ion_close(m->ion_client) ) AERR( "Failed to close ion_client: %d err=%s", m->ion_client , strerror(errno));
-		delete dev;
-	}
-	return 0;
-}
diff --git a/gralloc960/framebuffer_device.cpp b/gralloc960/framebuffer_device.cpp
index fa60eb5..44c4695 100644
--- a/gralloc960/framebuffer_device.cpp
+++ b/gralloc960/framebuffer_device.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -26,27 +26,35 @@
 #include <cutils/log.h>
 #include <cutils/atomic.h>
 #include <hardware/hardware.h>
-#include <hardware/gralloc.h>
+#include <hardware/fb.h>
 
 #include <GLES/gl.h>
 
-#include "alloc_device.h"
-#include "gralloc_priv.h"
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
 #include "gralloc_helper.h"
 #include "gralloc_vsync.h"
+#include "mali_gralloc_bufferaccess.h"
+#include "mali_gralloc_ion.h"
 
 #define STANDARD_LINUX_SCREEN
 
 // numbers of buffers for page flipping
-#define NUM_BUFFERS NUM_FB_BUFFERS 
+#define NUM_BUFFERS NUM_FB_BUFFERS
 
 enum
 {
 	PAGE_FLIP = 0x00000001,
 };
 
-
-static int fb_set_swap_interval(struct framebuffer_device_t* dev, int interval)
+static int fb_set_swap_interval(struct framebuffer_device_t *dev, int interval)
 {
 	if (interval < dev->minSwapInterval)
 	{
@@ -57,79 +65,86 @@
 		interval = dev->maxSwapInterval;
 	}
 
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
+	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
 	m->swapInterval = interval;
 
-	if (0 == interval) gralloc_vsync_disable(dev);
-	else gralloc_vsync_enable(dev);
+	if (0 == interval)
+	{
+		gralloc_vsync_disable(dev);
+	}
+	else
+	{
+		gralloc_vsync_enable(dev);
+	}
 
 	return 0;
 }
 
-static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
+static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer)
 {
 	if (private_handle_t::validate(buffer) < 0)
 	{
 		return -EINVAL;
 	}
 
-	private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
+	private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(buffer);
+	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
 
 	if (m->currentBuffer)
 	{
-		m->base.unlock(&m->base, m->currentBuffer);
+		mali_gralloc_unlock(m, m->currentBuffer);
 		m->currentBuffer = 0;
 	}
 
 	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
 	{
-		m->base.lock(&m->base, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, 
-				0, 0, m->info.xres, m->info.yres, NULL);
+		mali_gralloc_lock(m, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, -1, -1, -1, -1, NULL);
 
-		const size_t offset = (uintptr_t)hnd->base - (uintptr_t)m->framebuffer->base;
 		int interrupt;
 		m->info.activate = FB_ACTIVATE_VBL;
-		m->info.yoffset = offset / m->finfo.line_length;
+		m->info.yoffset = hnd->offset / m->finfo.line_length;
 
-                int fbdev_fd = m->framebuffer->shallow_fbdev_fd;
 #ifdef STANDARD_LINUX_SCREEN
-		if (ioctl(fbdev_fd, FBIOPAN_DISPLAY, &m->info) == -1) 
+
+		if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1)
 		{
-			AERR( "FBIOPAN_DISPLAY failed for fd: %d", fbdev_fd );
-			m->base.unlock(&m->base, buffer); 
+			AERR("FBIOPAN_DISPLAY failed for fd: %d", m->framebuffer->fd);
+			mali_gralloc_unlock(m, buffer);
 			return -errno;
 		}
+
 #else /*Standard Android way*/
-		if (ioctl(fbdev_fd, FBIOPUT_VSCREENINFO, &m->info) == -1) 
+
+		if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1)
 		{
-			AERR( "FBIOPUT_VSCREENINFO failed for fd: %d", fbdev_fd );
-			m->base.unlock(&m->base, buffer); 
+			AERR("FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fd);
+			mali_gralloc_unlock(m, buffer);
 			return -errno;
 		}
+
 #endif
-		if ( 0 != gralloc_wait_for_vsync(dev) )
+
+		if (0 != gralloc_wait_for_vsync(dev))
 		{
-			AERR( "Gralloc wait for vsync failed for fd: %d", fbdev_fd );
-			m->base.unlock(&m->base, buffer); 
+			AERR("Gralloc wait for vsync failed for fd: %d", m->framebuffer->fd);
+			mali_gralloc_unlock(m, buffer);
 			return -errno;
 		}
+
 		m->currentBuffer = buffer;
-	} 
+	}
 	else
 	{
-		void* fb_vaddr;
-		void* buffer_vaddr;
+		void *fb_vaddr;
+		void *buffer_vaddr;
 
-		m->base.lock(&m->base, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, 
-				0, 0, m->info.xres, m->info.yres, &fb_vaddr);
+		mali_gralloc_lock(m, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, -1, -1, -1, -1, &fb_vaddr);
 
-		m->base.lock(&m->base, buffer, GRALLOC_USAGE_SW_READ_RARELY, 
-				0, 0, m->info.xres, m->info.yres, &buffer_vaddr);
+		mali_gralloc_lock(m, buffer, GRALLOC_USAGE_SW_READ_RARELY, -1, -1, -1, -1, &buffer_vaddr);
 
 		// If buffer's alignment match framebuffer alignment we can do a direct copy.
 		// If not we must fallback to do an aligned copy of each line.
-		if ( hnd->byte_stride == (int)m->finfo.line_length )
+		if (hnd->byte_stride == (int)m->finfo.line_length)
 		{
 			memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
 		}
@@ -141,34 +156,29 @@
 
 			for (i = 0; i < m->info.yres; i++)
 			{
-				memcpy((void *)((uintptr_t)fb_vaddr + fb_offset),
-					   (void *)((uintptr_t)buffer_vaddr + buffer_offset),
-					   m->finfo.line_length);
+				memcpy((void *)((uintptr_t)fb_vaddr + fb_offset), (void *)((uintptr_t)buffer_vaddr + buffer_offset),
+				       m->finfo.line_length);
 
 				fb_offset += m->finfo.line_length;
 				buffer_offset += hnd->byte_stride;
 			}
 		}
-		m->base.unlock(&m->base, buffer); 
-		m->base.unlock(&m->base, m->framebuffer); 
+
+		mali_gralloc_unlock(m, buffer);
+		mali_gralloc_unlock(m, m->framebuffer);
 	}
 
 	return 0;
 }
 
-int init_frame_buffer_locked(struct private_module_t* module)
+static int init_frame_buffer_locked(struct private_module_t *module)
 {
 	if (module->framebuffer)
 	{
 		return 0; // Nothing to do, already initialized
 	}
-        
-	char const * const device_template[] =
-	{
-		"/dev/graphics/fb%u",
-		"/dev/fb%u",
-		NULL
-	};
+
+	char const *const device_template[] = { "/dev/graphics/fb%u", "/dev/fb%u", NULL };
 
 	int fd = -1;
 	int i = 0;
@@ -187,12 +197,14 @@
 	}
 
 	struct fb_fix_screeninfo finfo;
+
 	if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
 	{
 		return -errno;
 	}
 
 	struct fb_var_screeninfo info;
+
 	if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
 	{
 		return -errno;
@@ -210,27 +222,27 @@
 	 * Explicitly request 5/6/5
 	 */
 	info.bits_per_pixel = 16;
-	info.red.offset     = 11;
-	info.red.length     = 5;
-	info.green.offset   = 5;
-	info.green.length   = 6;
-	info.blue.offset    = 0;
-	info.blue.length    = 5;
-	info.transp.offset  = 0;
-	info.transp.length  = 0;
+	info.red.offset = 11;
+	info.red.length = 5;
+	info.green.offset = 5;
+	info.green.length = 6;
+	info.blue.offset = 0;
+	info.blue.length = 5;
+	info.transp.offset = 0;
+	info.transp.length = 0;
 #else
 	/*
 	 * Explicitly request 8/8/8
 	 */
 	info.bits_per_pixel = 32;
-	info.red.offset     = 16;
-	info.red.length     = 8;
-	info.green.offset   = 8;
-	info.green.length   = 8;
-	info.blue.offset    = 0;
-	info.blue.length    = 8;
-	info.transp.offset  = 0;
-	info.transp.length  = 0;
+	info.red.offset = 16;
+	info.red.length = 8;
+	info.green.offset = 8;
+	info.green.length = 8;
+	info.blue.offset = 0;
+	info.blue.length = 8;
+	info.transp.offset = 0;
+	info.transp.length = 0;
 #endif
 
 	/*
@@ -239,11 +251,12 @@
 	info.yres_virtual = info.yres * NUM_BUFFERS;
 
 	uint32_t flags = PAGE_FLIP;
+
 	if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
 	{
 		info.yres_virtual = info.yres;
 		flags &= ~PAGE_FLIP;
-		AWAR( "FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd );
+		AWAR("FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd);
 	}
 
 	if (info.yres_virtual < info.yres * 2)
@@ -251,7 +264,7 @@
 		// we need at least 2 for page-flipping
 		info.yres_virtual = info.yres;
 		flags &= ~PAGE_FLIP;
-		AWAR( "page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres*2 );
+		AWAR("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres * 2);
 	}
 
 	if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
@@ -260,36 +273,34 @@
 	}
 
 	int refreshRate = 0;
-	if ( info.pixclock > 0 )
+
+	if (info.pixclock > 0)
 	{
-		refreshRate = 1000000000000000LLU /
-		(
-			uint64_t( info.upper_margin + info.lower_margin + info.yres + info.hsync_len )
-			* ( info.left_margin  + info.right_margin + info.xres + info.vsync_len )
-			* info.pixclock
-		);
+		refreshRate =
+		    1000000000000000LLU / (uint64_t(info.upper_margin + info.lower_margin + info.yres + info.hsync_len) *
+		                           (info.left_margin + info.right_margin + info.xres + info.vsync_len) * info.pixclock);
 	}
 	else
 	{
-		AWAR( "fbdev pixclock is zero for fd: %d", fd );
+		AWAR("fbdev pixclock is zero for fd: %d", fd);
 	}
 
 	if (refreshRate == 0)
 	{
-		refreshRate = 60*1000;  // 60 Hz
+		refreshRate = 60 * 1000; // 60 Hz
 	}
 
 	if (int(info.width) <= 0 || int(info.height) <= 0)
 	{
 		// the driver doesn't return that information
 		// default to 160 dpi
-		info.width  = ((info.xres * 25.4f)/160.0f + 0.5f);
-		info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
+		info.width = ((info.xres * 25.4f) / 160.0f + 0.5f);
+		info.height = ((info.yres * 25.4f) / 160.0f + 0.5f);
 	}
 
 	float xdpi = (info.xres * 25.4f) / info.width;
 	float ydpi = (info.yres * 25.4f) / info.height;
-	float fps  = refreshRate / 1000.0f;
+	float fps = refreshRate / 1000.0f;
 
 	AINF("using (fd=%d)\n"
 	     "id           = %s\n"
@@ -301,23 +312,13 @@
 	     "r            = %2u:%u\n"
 	     "g            = %2u:%u\n"
 	     "b            = %2u:%u\n",
-	     fd,
-	     finfo.id,
-	     info.xres,
-	     info.yres,
-	     info.xres_virtual,
-	     info.yres_virtual,
-	     info.bits_per_pixel,
-	     info.red.offset, info.red.length,
-	     info.green.offset, info.green.length,
-	     info.blue.offset, info.blue.length);
+	     fd, finfo.id, info.xres, info.yres, info.xres_virtual, info.yres_virtual, info.bits_per_pixel, info.red.offset,
+	     info.red.length, info.green.offset, info.green.length, info.blue.offset, info.blue.length);
 
 	AINF("width        = %d mm (%f dpi)\n"
 	     "height       = %d mm (%f dpi)\n"
 	     "refresh rate = %.2f Hz\n",
-	     info.width,  xdpi,
-	     info.height, ydpi,
-	     fps);
+	     info.width, xdpi, info.height, ydpi, fps);
 
 	if (0 == strncmp(finfo.id, "CLCD FB", 7))
 	{
@@ -327,6 +328,10 @@
 	{
 		module->dpy_type = MALI_DPY_TYPE_HDLCD;
 	}
+	else if (0 == strncmp(finfo.id, "ARM HDLCD Control", 16))
+	{
+		module->dpy_type = MALI_DPY_TYPE_HDLCD;
+	}
 	else
 	{
 		module->dpy_type = MALI_DPY_TYPE_UNKNOWN;
@@ -354,19 +359,19 @@
 	 * map the framebuffer
 	 */
 	size_t fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual);
-	void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-	if (vaddr == MAP_FAILED) 
+	void *vaddr = mmap(0, fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+	if (vaddr == MAP_FAILED)
 	{
-		AERR( "Error mapping the framebuffer (%s)", strerror(errno) );
+		AERR("Error mapping the framebuffer (%s)", strerror(errno));
 		return -errno;
 	}
 
 	memset(vaddr, 0, fbSize);
 
-
 	// Create a "fake" buffer object for the entire frame buffer memory, and store it in the module
-	module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, GRALLOC_USAGE_HW_FB, fbSize, vaddr,
-	                                           0, fd, 0);
+	module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, fbSize, vaddr,
+	                                           GRALLOC_USAGE_HW_FB, GRALLOC_USAGE_HW_FB, dup(fd), 0);
 
 	module->numBuffers = info.yres_virtual / info.yres;
 	module->bufferMask = 0;
@@ -374,7 +379,7 @@
 	return 0;
 }
 
-static int init_frame_buffer(struct private_module_t* module)
+static int init_frame_buffer(struct private_module_t *module)
 {
 	pthread_mutex_lock(&module->lock);
 	int err = init_frame_buffer_locked(module);
@@ -384,15 +389,148 @@
 
 static int fb_close(struct hw_device_t *device)
 {
-	framebuffer_device_t* dev = reinterpret_cast<framebuffer_device_t*>(device);
+	framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(device);
+
 	if (dev)
 	{
 		free(dev);
 	}
+
 	return 0;
 }
 
-int compositionComplete(struct framebuffer_device_t* dev)
+static int fb_alloc_framebuffer_dmabuf(private_module_t *m, private_handle_t *hnd)
+{
+	struct fb_dmabuf_export fb_dma_buf;
+	int res;
+	res = ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf);
+
+	if (res == 0)
+	{
+		hnd->share_fd = fb_dma_buf.fd;
+		return 0;
+	}
+	else
+	{
+		AINF("FBIOGET_DMABUF ioctl failed(%d). See gralloc_priv.h and the integration manual for vendor framebuffer "
+		     "integration",
+		     res);
+		return -1;
+	}
+}
+
+static int fb_alloc_from_ion_module(mali_gralloc_module *m, size_t buffer_size, uint64_t consumer_usage,
+                                    uint64_t producer_usage, buffer_handle_t *pHandle)
+{
+	buffer_descriptor_t fb_buffer_descriptor;
+	gralloc_buffer_descriptor_t gralloc_buffer_descriptor[1];
+	bool shared = false;
+	int err = 0;
+
+	fb_buffer_descriptor.size = buffer_size;
+	fb_buffer_descriptor.consumer_usage = consumer_usage;
+	fb_buffer_descriptor.producer_usage = producer_usage;
+	gralloc_buffer_descriptor[0] = (gralloc_buffer_descriptor_t)(&fb_buffer_descriptor);
+
+	err = mali_gralloc_ion_allocate(m, gralloc_buffer_descriptor, 1, pHandle, &shared);
+
+	return err;
+}
+
+static int fb_alloc_framebuffer_locked(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
+                                       buffer_handle_t *pHandle, int *stride, int *byte_stride)
+{
+	// allocate the framebuffer
+	if (m->framebuffer == NULL)
+	{
+		// initialize the framebuffer, the framebuffer is mapped once and forever.
+		int err = init_frame_buffer_locked(m);
+
+		if (err < 0)
+		{
+			return err;
+		}
+	}
+
+	uint32_t bufferMask = m->bufferMask;
+	const uint32_t numBuffers = m->numBuffers;
+	/* framebufferSize is used for allocating the handle to the framebuffer and refers
+	 *                 to the size of the actual framebuffer.
+	 * alignedFramebufferSize is used for allocating a possible internal buffer and
+	 *                        thus need to consider internal alignment requirements. */
+	const size_t framebufferSize = m->finfo.line_length * m->info.yres;
+	const size_t alignedFramebufferSize = GRALLOC_ALIGN(m->finfo.line_length, 64) * m->info.yres;
+
+	*stride = m->info.xres;
+
+	if (numBuffers == 1)
+	{
+		// If we have only one buffer, we never use page-flipping. Instead,
+		// we return a regular buffer which will be memcpy'ed to the main
+		// screen when post is called.
+		uint64_t newConsumerUsage = (consumer_usage & ~GRALLOC_USAGE_HW_FB);
+		uint64_t newProducerUsage = (producer_usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
+		AWAR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres);
+		*byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
+		return fb_alloc_from_ion_module(m, alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle);
+	}
+
+	if (bufferMask >= ((1LU << numBuffers) - 1))
+	{
+		// We ran out of buffers, reset bufferMask
+		bufferMask = 0;
+		m->bufferMask = 0;
+	}
+
+	uintptr_t framebufferVaddr = (uintptr_t)m->framebuffer->base;
+
+	// find a free slot
+	for (uint32_t i = 0; i < numBuffers; i++)
+	{
+		if ((bufferMask & (1LU << i)) == 0)
+		{
+			m->bufferMask |= (1LU << i);
+			break;
+		}
+
+		framebufferVaddr += framebufferSize;
+	}
+
+	// The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
+	private_handle_t *hnd = new private_handle_t(
+	    private_handle_t::PRIV_FLAGS_FRAMEBUFFER, framebufferSize, (void *)framebufferVaddr, consumer_usage,
+	    producer_usage, dup(m->framebuffer->fd), (framebufferVaddr - (uintptr_t)m->framebuffer->base));
+
+	/*
+	 * Perform allocator specific actions. If these fail we fall back to a regular buffer
+	 * which will be memcpy'ed to the main screen when fb_post is called.
+	 */
+	if (fb_alloc_framebuffer_dmabuf(m, hnd) == -1)
+	{
+		delete hnd;
+		uint64_t newConsumerUsage = (consumer_usage & ~GRALLOC_USAGE_HW_FB);
+		uint64_t newProducerUsage = (producer_usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
+		AERR("Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd);
+		*byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
+		return fb_alloc_from_ion_module(m, alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle);
+	}
+
+	*pHandle = hnd;
+	*byte_stride = m->finfo.line_length;
+
+	return 0;
+}
+
+int fb_alloc_framebuffer(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
+                         buffer_handle_t *pHandle, int *stride, int *byte_stride)
+{
+	pthread_mutex_lock(&m->lock);
+	int err = fb_alloc_framebuffer_locked(m, consumer_usage, producer_usage, pHandle, stride, byte_stride);
+	pthread_mutex_unlock(&m->lock);
+	return err;
+}
+
+int compositionComplete(struct framebuffer_device_t *dev)
 {
 	GRALLOC_UNUSED(dev);
 
@@ -404,61 +542,76 @@
 	   synchronously in the same thread, and not asynchronoulsy in a background thread later.
 	   The SurfaceFlinger requires this behaviour since it releases the lock on all the
 	   SourceBuffers (Layers) after the compositionComplete() function returns.
-	   However this "bad" behaviour by SurfaceFlinger should not affect performance, 
-	   since the Applications that render the SourceBuffers (Layers) still get the 
+	   However this "bad" behaviour by SurfaceFlinger should not affect performance,
+	   since the Applications that render the SourceBuffers (Layers) still get the
 	   full renderpipeline using asynchronous rendering. So they perform at maximum speed,
 	   and because of their complexity compared to the Surface flinger jobs, the Surface flinger
-	   is normally faster even if it does everyhing synchronous and serial. 
+	   is normally faster even if it does everyhing synchronous and serial.
 	   */
 	return 0;
 }
 
-int framebuffer_device_open(hw_module_t const* module, const char* name, hw_device_t** device)
+int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
 {
 	int status = -EINVAL;
 
 	GRALLOC_UNUSED(name);
 
-	alloc_device_t* gralloc_device;
+#if GRALLOC_USE_GRALLOC1_API == 1
+	gralloc1_device_t *gralloc_device;
+#else
+	alloc_device_t *gralloc_device;
+#endif
+
 #if DISABLE_FRAMEBUFFER_HAL == 1
 	AERR("Framebuffer HAL not support/disabled %s",
 #ifdef MALI_DISPLAY_VERSION
-	"with MALI display enable");
+	     "with MALI display enable");
 #else
-	"");
+	     "");
 #endif
 	return -ENODEV;
 #endif
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+	status = gralloc1_open(module, &gralloc_device);
+#else
 	status = gralloc_open(module, &gralloc_device);
+#endif
+
 	if (status < 0)
 	{
 		return status;
 	}
 
-	private_module_t* m = (private_module_t*)module;
+	private_module_t *m = (private_module_t *)module;
 	status = init_frame_buffer(m);
 
 	/* malloc is used instead of 'new' to instantiate the struct framebuffer_device_t
-	 * C++11 spec specifies that if a class/struct has a const member,default constructor 
+	 * C++11 spec specifies that if a class/struct has a const member,default constructor
 	 * is deleted. So, if 'new' is used to instantiate the class/struct, it will throw
 	 * error complaining about deleted constructor. Even if the struct is wrapped in a class
-	 * it will still try to use the base class constructor to initialize the members, resulting 
+	 * it will still try to use the base class constructor to initialize the members, resulting
 	 * in error 'deleted constructor'.
-	 * This leaves two options 
+	 * This leaves two options
 	 * Option 1: initialize the const members at the instantiation time. With {value1, value2 ..}
 	 * Which relies on the order of the members, and if members are reordered or a new member is introduced
 	 * it will end up assiging wrong value to members. Designated assignment as well has been removed in C++11
-	 * Option 2: use malloc instead of 'new' to allocate the class/struct and initialize the members in code. 
+	 * Option 2: use malloc instead of 'new' to allocate the class/struct and initialize the members in code.
 	 * This is the only maintainable option available.
 	 */
 
-	framebuffer_device_t *dev =  reinterpret_cast<framebuffer_device_t*> (malloc(sizeof(framebuffer_device_t)));
+	framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(malloc(sizeof(framebuffer_device_t)));
 
 	/* if either or both of init_frame_buffer() and malloc failed */
 	if ((status < 0) || (!dev))
 	{
+#if GRALLOC_USE_GRALLOC1_API == 1
+		gralloc1_close(gralloc_device);
+#else
 		gralloc_close(gralloc_device);
-		(!dev)?	(void)(status = -ENOMEM) : free(dev);
+#endif
+		(!dev) ? (void)(status = -ENOMEM) : free(dev);
 		return status;
 	}
 
@@ -467,7 +620,7 @@
 	/* initialize the procs */
 	dev->common.tag = HARDWARE_DEVICE_TAG;
 	dev->common.version = 0;
-	dev->common.module = const_cast<hw_module_t*>(module);
+	dev->common.module = const_cast<hw_module_t *>(module);
 	dev->common.close = fb_close;
 	dev->setSwapInterval = fb_set_swap_interval;
 	dev->post = fb_post;
@@ -475,20 +628,20 @@
 	dev->compositionComplete = &compositionComplete;
 
 	int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
-	const_cast<uint32_t&>(dev->flags) = 0;
-	const_cast<uint32_t&>(dev->width) = m->info.xres;
-	const_cast<uint32_t&>(dev->height) = m->info.yres;
-	const_cast<int&>(dev->stride) = stride;
+	const_cast<uint32_t &>(dev->flags) = 0;
+	const_cast<uint32_t &>(dev->width) = m->info.xres;
+	const_cast<uint32_t &>(dev->height) = m->info.yres;
+	const_cast<int &>(dev->stride) = stride;
 #ifdef GRALLOC_16_BITS
-	const_cast<int&>(dev->format) = HAL_PIXEL_FORMAT_RGB_565;
+	const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_RGB_565;
 #else
-	const_cast<int&>(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888;
+	const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888;
 #endif
-	const_cast<float&>(dev->xdpi) = m->xdpi;
-	const_cast<float&>(dev->ydpi) = m->ydpi;
-	const_cast<float&>(dev->fps) = m->fps;
-	const_cast<int&>(dev->minSwapInterval) = 0;
-	const_cast<int&>(dev->maxSwapInterval) = 1;
+	const_cast<float &>(dev->xdpi) = m->xdpi;
+	const_cast<float &>(dev->ydpi) = m->ydpi;
+	const_cast<float &>(dev->fps) = m->fps;
+	const_cast<int &>(dev->minSwapInterval) = 0;
+	const_cast<int &>(dev->maxSwapInterval) = 1;
 	*device = &dev->common;
 
 	gralloc_vsync_enable(dev);
diff --git a/gralloc960/framebuffer_device.h b/gralloc960/framebuffer_device.h
index a653cef..1bfb00b 100644
--- a/gralloc960/framebuffer_device.h
+++ b/gralloc960/framebuffer_device.h
@@ -20,7 +20,11 @@
 #include "gralloc_priv.h"
 
 // Create a framebuffer device
-int framebuffer_device_open(hw_module_t const* module, const char* name, hw_device_t** device);
+int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device);
 
 // Initialize the framebuffer (must keep module lock before calling
-int init_frame_buffer_locked(struct private_module_t* module);
+int init_frame_buffer_locked(struct private_module_t *module);
+
+// Allocate framebuffer buffer
+int fb_alloc_framebuffer(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
+                         buffer_handle_t *pHandle, int *stride, int *byte_stride);
diff --git a/gralloc960/gralloc_buffer_priv.cpp b/gralloc960/gralloc_buffer_priv.cpp
index a357030..274dec2 100644
--- a/gralloc960/gralloc_buffer_priv.cpp
+++ b/gralloc960/gralloc_buffer_priv.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2014-2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -19,9 +19,17 @@
 #include <cutils/ashmem.h>
 #include <cutils/log.h>
 #include <sys/mman.h>
-#include "gralloc_priv.h"
-#include "gralloc_buffer_priv.h"
 
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+#include "gralloc_buffer_priv.h"
 
 /*
  * Allocate shared memory for attribute storage. Only to be
@@ -29,21 +37,24 @@
  *
  * Return 0 on success.
  */
-int gralloc_buffer_attr_allocate( private_handle_t *hnd )
+int gralloc_buffer_attr_allocate(private_handle_t *hnd)
 {
 	int rval = -1;
 
-	if( !hnd )
-		goto out;
-
-	if( hnd->share_attr_fd >= 0 )
+	if (!hnd)
 	{
-		ALOGW("Warning share attribute fd already exists during create. Closing.");
-		close( hnd->share_attr_fd );
+		goto out;
 	}
 
-	hnd->share_attr_fd = ashmem_create_region( "gralloc_shared_attr", PAGE_SIZE );
-	if(hnd->share_attr_fd < 0)
+	if (hnd->share_attr_fd >= 0)
+	{
+		ALOGW("Warning share attribute fd already exists during create. Closing.");
+		close(hnd->share_attr_fd);
+	}
+
+	hnd->share_attr_fd = ashmem_create_region("gralloc_shared_attr", PAGE_SIZE);
+
+	if (hnd->share_attr_fd < 0)
 	{
 		ALOGE("Failed to allocate page for shared attribute region");
 		goto err_ashmem;
@@ -62,17 +73,18 @@
 	 * Because of this we keep the PROT_EXEC flag.
 	 */
 
-	hnd->attr_base = mmap( NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_attr_fd, 0 );
-	if(hnd->attr_base != MAP_FAILED)
+	hnd->attr_base = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_attr_fd, 0);
+
+	if (hnd->attr_base != MAP_FAILED)
 	{
 		/* The attribute region contains signed integers only.
 		 * The reason for this is because we can set a value less than 0 for
 		 * not-initialized values.
 		 */
-		attr_region *region = (attr_region *) hnd->attr_base;
+		attr_region *region = (attr_region *)hnd->attr_base;
 
 		memset(hnd->attr_base, 0xff, PAGE_SIZE);
-		munmap( hnd->attr_base, PAGE_SIZE );
+		munmap(hnd->attr_base, PAGE_SIZE);
 		hnd->attr_base = MAP_FAILED;
 	}
 	else
@@ -85,9 +97,10 @@
 	goto out;
 
 err_ashmem:
-	if( hnd->share_attr_fd >= 0 )
+
+	if (hnd->share_attr_fd >= 0)
 	{
-		close( hnd->share_attr_fd );
+		close(hnd->share_attr_fd);
 		hnd->share_attr_fd = -1;
 	}
 
@@ -101,26 +114,29 @@
 
  * Return 0 on success.
  */
-int gralloc_buffer_attr_free( private_handle_t *hnd )
+int gralloc_buffer_attr_free(private_handle_t *hnd)
 {
 	int rval = -1;
 
-	if( !hnd )
+	if (!hnd)
+	{
 		goto out;
+	}
 
-	if( hnd->share_attr_fd < 0 )
+	if (hnd->share_attr_fd < 0)
 	{
 		ALOGE("Shared attribute region not avail to free");
 		goto out;
 	}
-	if( hnd->attr_base != MAP_FAILED )
+
+	if (hnd->attr_base != MAP_FAILED)
 	{
 		ALOGW("Warning shared attribute region mapped at free. Unmapping");
-		munmap( hnd->attr_base, PAGE_SIZE );
+		munmap(hnd->attr_base, PAGE_SIZE);
 		hnd->attr_base = MAP_FAILED;
 	}
 
-	close( hnd->share_attr_fd );
+	close(hnd->share_attr_fd);
 	hnd->share_attr_fd = -1;
 	rval = 0;
 
diff --git a/gralloc960/gralloc_buffer_priv.h b/gralloc960/gralloc_buffer_priv.h
index 516781c..122ee2a 100644
--- a/gralloc960/gralloc_buffer_priv.h
+++ b/gralloc960/gralloc_buffer_priv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2014-2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -22,6 +22,7 @@
 #include "gralloc_priv.h"
 #include <errno.h>
 #include <string.h>
+#include "mali_gralloc_private_interface_types.h"
 
 // private gralloc buffer manipulation API
 
@@ -34,38 +35,18 @@
 	int crop_width;
 	int use_yuv_transform;
 	int use_sparse_alloc;
-} __attribute__ ((packed));
+	mali_hdr_info hdr_info;
+} __attribute__((packed));
 
 typedef struct attr_region attr_region;
 
-enum
-{
-	/* CROP_RECT and YUV_TRANS are intended to be
-	 * written by producers and read by consumers.
-	 * A producer should write these parameters before
-	 * it queues a buffer to the consumer.
-	 */
-
-	/* CROP RECT, defined as an int array of top, left, height, width. Origin in top-left corner */
-	GRALLOC_ARM_BUFFER_ATTR_CROP_RECT                  = 1,
-
-	/* Set if the AFBC format used a YUV transform before compressing */
-	GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS             = 2,
-
-	/* Set if the AFBC format uses sparse allocation */
-	GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC          = 3,
-	GRALLOC_ARM_BUFFER_ATTR_LAST
-};
-
-typedef uint32_t buf_attr;
-
 /*
  * Allocate shared memory for attribute storage. Only to be
  * used by gralloc internally.
  *
  * Return 0 on success.
  */
-int gralloc_buffer_attr_allocate( struct private_handle_t *hnd );
+int gralloc_buffer_attr_allocate(struct private_handle_t *hnd);
 
 /*
  * Frees the shared memory allocated for attribute storage.
@@ -73,7 +54,7 @@
 
  * Return 0 on success.
  */
-int gralloc_buffer_attr_free( struct private_handle_t *hnd );
+int gralloc_buffer_attr_free(struct private_handle_t *hnd);
 
 /*
  * Map the attribute storage area before attempting to
@@ -81,29 +62,32 @@
  *
  * Return 0 on success.
  */
-static inline int gralloc_buffer_attr_map( struct private_handle_t *hnd, int readwrite)
+static inline int gralloc_buffer_attr_map(struct private_handle_t *hnd, int readwrite)
 {
 	int rval = -1;
 	int prot_flags = PROT_READ;
 
-	if( !hnd )
+	if (!hnd)
+	{
 		goto out;
+	}
 
-	if( hnd->share_attr_fd < 0 )
+	if (hnd->share_attr_fd < 0)
 	{
 		ALOGE("Shared attribute region not available to be mapped");
 		goto out;
 	}
 
-	if( readwrite )
+	if (readwrite)
 	{
-		prot_flags |=  PROT_WRITE;
+		prot_flags |= PROT_WRITE;
 	}
 
-	hnd->attr_base = mmap( NULL, PAGE_SIZE, prot_flags, MAP_SHARED, hnd->share_attr_fd, 0 );
-	if(hnd->attr_base == MAP_FAILED)
+	hnd->attr_base = mmap(NULL, PAGE_SIZE, prot_flags, MAP_SHARED, hnd->share_attr_fd, 0);
+
+	if (hnd->attr_base == MAP_FAILED)
 	{
-		ALOGE("Failed to mmap shared attribute region err=%s",strerror(errno));
+		ALOGE("Failed to mmap shared attribute region err=%s", strerror(errno));
 		goto out;
 	}
 
@@ -118,16 +102,18 @@
  *
  * Return 0 on success.
  */
-static inline int gralloc_buffer_attr_unmap( struct private_handle_t *hnd )
+static inline int gralloc_buffer_attr_unmap(struct private_handle_t *hnd)
 {
 	int rval = -1;
 
-	if( !hnd )
-		goto out;
-
-	if( hnd->attr_base != MAP_FAILED )
+	if (!hnd)
 	{
-		if ( munmap( hnd->attr_base, PAGE_SIZE ) == 0 )
+		goto out;
+	}
+
+	if (hnd->attr_base != MAP_FAILED)
+	{
+		if (munmap(hnd->attr_base, PAGE_SIZE) == 0)
 		{
 			hnd->attr_base = MAP_FAILED;
 			rval = 0;
@@ -143,33 +129,40 @@
  *
  * Return 0 on success.
  */
-static inline int gralloc_buffer_attr_write( struct private_handle_t *hnd, buf_attr attr, int *val )
+static inline int gralloc_buffer_attr_write(struct private_handle_t *hnd, buf_attr attr, int *val)
 {
 	int rval = -1;
 
-	if( !hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST )
-		goto out;
-
-	if( hnd->attr_base != MAP_FAILED )
+	if (!hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST)
 	{
-		attr_region *region = (attr_region *) hnd->attr_base;
+		goto out;
+	}
 
-		switch( attr )
+	if (hnd->attr_base != MAP_FAILED)
+	{
+		attr_region *region = (attr_region *)hnd->attr_base;
+
+		switch (attr)
 		{
-			case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT:
-				memcpy( &region->crop_top, val, sizeof(int)*4 );
-				rval = 0;
-				break;
+		case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT:
+			memcpy(&region->crop_top, val, sizeof(int) * 4);
+			rval = 0;
+			break;
 
-			case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS:
-				region->use_yuv_transform = *val;
-				rval = 0;
-				break;
+		case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS:
+			region->use_yuv_transform = *val;
+			rval = 0;
+			break;
 
-			case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC:
-				region->use_sparse_alloc = *val;
-				rval = 0;
-				break;
+		case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC:
+			region->use_sparse_alloc = *val;
+			rval = 0;
+			break;
+
+		case GRALLOC_ARM_BUFFER_ATTR_HDR_INFO:
+			memcpy(&region->hdr_info, val, sizeof(mali_hdr_info));
+			rval = 0;
+			break;
 		}
 	}
 
@@ -177,33 +170,40 @@
 	return rval;
 }
 
-static inline int gralloc_buffer_attr_read( struct private_handle_t *hnd, buf_attr attr, int *val )
+static inline int gralloc_buffer_attr_read(struct private_handle_t *hnd, buf_attr attr, int *val)
 {
 	int rval = -1;
 
-	if( !hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST )
-		goto out;
-
-	if( hnd->attr_base != MAP_FAILED )
+	if (!hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST)
 	{
-		attr_region *region = (attr_region *) hnd->attr_base;
+		goto out;
+	}
 
-		switch( attr )
+	if (hnd->attr_base != MAP_FAILED)
+	{
+		attr_region *region = (attr_region *)hnd->attr_base;
+
+		switch (attr)
 		{
-			case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT:
-				memcpy( val, &region->crop_top, sizeof(int)*4 );
-				rval = 0;
-				break;
+		case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT:
+			memcpy(val, &region->crop_top, sizeof(int) * 4);
+			rval = 0;
+			break;
 
-			case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS:
-				*val = region->use_yuv_transform;
-				rval = 0;
-				break;
+		case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS:
+			*val = region->use_yuv_transform;
+			rval = 0;
+			break;
 
-			case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC:
-				*val = region->use_sparse_alloc;
-				rval = 0;
-				break;
+		case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC:
+			*val = region->use_sparse_alloc;
+			rval = 0;
+			break;
+
+		case GRALLOC_ARM_BUFFER_ATTR_HDR_INFO:
+			memcpy(val, &region->hdr_info, sizeof(mali_hdr_info));
+			rval = 0;
+			break;
 		}
 	}
 
diff --git a/gralloc960/gralloc_helper.h b/gralloc960/gralloc_helper.h
index 12adb53..fea10e5 100644
--- a/gralloc960/gralloc_helper.h
+++ b/gralloc960/gralloc_helper.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -20,12 +20,32 @@
 #define GRALLOC_HELPER_H_
 
 #include <sys/mman.h>
+#include <android/log.h>
 
-#define GRALLOC_UNUSED(x) ((void) x)
+#ifndef AWAR
+#define AWAR(fmt, args...) \
+	__android_log_print(ANDROID_LOG_WARN, "[Gralloc-Warning]", "%s:%d " fmt, __func__, __LINE__, ##args)
+#endif
+#ifndef AINF
+#define AINF(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "[Gralloc]", fmt, ##args)
+#endif
+#ifndef AERR
+#define AERR(fmt, args...) \
+	__android_log_print(ANDROID_LOG_ERROR, "[Gralloc-ERROR]", "%s:%d " fmt, __func__, __LINE__, ##args)
+#endif
+#ifndef AERR_IF
+#define AERR_IF(eq, fmt, args...) \
+	if ((eq))                     \
+	AERR(fmt, args)
+#endif
+
+#define GRALLOC_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1))
+
+#define GRALLOC_UNUSED(x) ((void)x)
 
 static inline size_t round_up_to_page_size(size_t x)
 {
-    return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
+	return (x + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
 }
 
 #endif /* GRALLOC_HELPER_H_ */
diff --git a/gralloc960/gralloc_module.cpp b/gralloc960/gralloc_module.cpp
deleted file mode 100644
index df2d82e..0000000
--- a/gralloc960/gralloc_module.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <inttypes.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <hardware/hardware.h>
-#include <hardware/gralloc.h>
-
-#include "gralloc_priv.h"
-#include "gralloc_helper.h"
-#include "alloc_device.h"
-#include "framebuffer_device.h"
-
-#include "gralloc_module_allocator_specific.h"
-#include "gralloc_buffer_priv.h"
-
-#include "mali_gralloc_formats.h"
-
-static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER;
-
-static int gralloc_device_open(const hw_module_t* module, const char* name, hw_device_t** device)
-{
-	int status = -EINVAL;
-
-	if (!strncmp(name, GRALLOC_HARDWARE_GPU0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
-	{
-		status = alloc_device_open(module, name, device);
-	}
-	else if (!strncmp(name, GRALLOC_HARDWARE_FB0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
-	{
-		status = framebuffer_device_open(module, name, device);
-	}
-
-	return status;
-}
-
-static int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle)
-{
-	GRALLOC_UNUSED(module);
-
-	if (private_handle_t::validate(handle) < 0)
-	{
-		AERR("Registering invalid buffer %p, returning error", handle);
-		return -EINVAL;
-	}
-
-	// if this handle was created in this process, then we keep it as is.
-	private_handle_t* hnd = (private_handle_t*)handle;
-
-	int retval = -EINVAL;
-
-	pthread_mutex_lock(&s_map_lock);
-
-	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) 
-	{
-		AINF("Register framebuffer 0x%p is no-op", handle);
-		retval = 0;
-	}
-	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
-	{
-		retval = gralloc_backend_register(hnd);
-	}
-	else
-	{
-		AERR("unknown buffer flags not supported. flags = %d", hnd->flags );
-	}
-
-	pthread_mutex_unlock(&s_map_lock);
-	return retval;
-}
-
-static int gralloc_unregister_buffer(gralloc_module_t const* module, buffer_handle_t handle)
-{
-	GRALLOC_UNUSED(module);
-
-	if (private_handle_t::validate(handle) < 0)
-	{
-		AERR("unregistering invalid buffer %p, returning error", handle);
-		return -EINVAL;
-	}
-
-	private_handle_t* hnd = (private_handle_t*)handle;
-
-	AERR_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState);
-
-	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
-	{
-		AERR( "Can't unregister buffer %p as it is a framebuffer", handle );
-	}
-	else
-	{
-		pthread_mutex_lock(&s_map_lock);
-
-		if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
-		{
-			gralloc_backend_unregister(hnd);
-		}
-		else
-		{
-			AERR("Unregistering unknown buffer is not supported. Flags = %d", hnd->flags);
-		}
-
-		/*
-		 * Close shared attribute region file descriptor. It might seem strange to "free"
-		 * this here since this can happen in a client process, but free here is nothing
-		 * but unmapping and closing the duplicated file descriptor. The original ashmem
-		 * fd instance is still open until alloc_device_free() is called. Even sharing
-		 * of gralloc buffers within the same process should have fds dup:ed.
-		 */
-		gralloc_buffer_attr_free( hnd );
-
-		hnd->base = 0;
-		hnd->lockState  = 0;
-		hnd->writeOwner = 0;
-
-		pthread_mutex_unlock(&s_map_lock);
-	}
-
-	return 0;
-}
-
-static int gralloc_lock(gralloc_module_t const* module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void** vaddr)
-{
-	GRALLOC_UNUSED(module);
-	GRALLOC_UNUSED(l);
-	GRALLOC_UNUSED(t);
-	GRALLOC_UNUSED(w);
-	GRALLOC_UNUSED(h);
-
-	if (private_handle_t::validate(handle) < 0)
-	{
-		AERR("Locking invalid buffer %p, returning error", handle );
-		return -EINVAL;
-	}
-
-	private_handle_t* hnd = (private_handle_t*)handle;
-
-	if (hnd->req_format == HAL_PIXEL_FORMAT_YCbCr_420_888)
-	{
-		AERR("Buffers with format YCbCr_420_888 must be locked using (*lock_ycbcr)" );
-		return -EINVAL;
-	}
-
-	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
-	{
-		hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
-	}
-	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
-	{
-		*vaddr = (void*)hnd->base;
-	}
-	return 0;
-}
-
-static int gralloc_lock_ycbcr(gralloc_module_t const* module, buffer_handle_t handle, int usage,
-                              int l, int t, int w, int h,
-                              android_ycbcr *ycbcr)
-{
-	GRALLOC_UNUSED(module);
-	GRALLOC_UNUSED(l);
-	GRALLOC_UNUSED(t);
-	GRALLOC_UNUSED(w);
-	GRALLOC_UNUSED(h);
-
-	if (private_handle_t::validate(handle) < 0)
-	{
-		AERR("Locking invalid buffer %p, returning error", handle );
-		return -EINVAL;
-	}
-
-	private_handle_t* hnd = (private_handle_t*)handle;
-
-	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
-	{
-		hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
-	}
-	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) &&
-		!(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK))
-	{
-		char* base = (char*)hnd->base;
-		int y_stride = hnd->byte_stride;
-		/* Ensure height is aligned for subsampled chroma before calculating buffer parameters */
-		int adjusted_height = GRALLOC_ALIGN(hnd->height, 2);
-		int y_size =  y_stride * adjusted_height;
-
-		int u_offset = 0;
-		int v_offset = 0;
-		int c_stride = 0;
-		int step = 0;
-
-		uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
-
-		switch (base_format)
-		{
-			case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
-				c_stride = y_stride;
-				/* Y plane, UV plane */
-				u_offset = y_size;
-				v_offset = y_size + 1;
-				step = 2;
-				break;
-
-			case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
-				c_stride = y_stride;
-				/* Y plane, UV plane */
-				v_offset = y_size;
-				u_offset = y_size + 1;
-				step = 2;
-				break;
-
-			case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
-			{
-				int c_size;
-
-				/* Stride alignment set to 16 as the SW access flags were set */
-				c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16);
-				c_size = c_stride * (adjusted_height / 2);
-				/* Y plane, V plane, U plane */
-				v_offset = y_size;
-				u_offset = y_size + c_size;
-				step = 1;
-				break;
-			}
-
-			default:
-				AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format);
-				return -EINVAL;
-		}
-
-		ycbcr->y = base;
-		ycbcr->cb = base + u_offset;
-		ycbcr->cr = base + v_offset;
-		ycbcr->ystride = y_stride;
-		ycbcr->cstride = c_stride;
-		ycbcr->chroma_step = step;
-	}
-	return 0;
-}
-
-static int gralloc_unlock(gralloc_module_t const* module, buffer_handle_t handle)
-{
-	GRALLOC_UNUSED(module);
-
-	if (private_handle_t::validate(handle) < 0)
-	{
-		AERR( "Unlocking invalid buffer %p, returning error", handle );
-		return -EINVAL;
-	}
-
-	private_handle_t* hnd = (private_handle_t*)handle;
-
-	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner)
-	{
-		gralloc_backend_sync(hnd);
-	}
-
-	return 0;
-}
-
-// There is one global instance of the module
-
-static struct hw_module_methods_t gralloc_module_methods =
-{
-	gralloc_device_open
-};
-
-private_module_t::private_module_t()
-{
-#define INIT_ZERO(obj) (memset(&(obj),0,sizeof((obj))))
-
-	base.common.tag = HARDWARE_MODULE_TAG;
-	base.common.version_major = 1;
-	base.common.version_minor = 0;
-	base.common.id = GRALLOC_HARDWARE_MODULE_ID;
-	base.common.name = "Graphics Memory Allocator Module";
-	base.common.author = "ARM Ltd.";
-	base.common.methods = &gralloc_module_methods;
-	base.common.dso = NULL;
-	INIT_ZERO(base.common.reserved);
-
-	base.registerBuffer = gralloc_register_buffer;
-	base.unregisterBuffer = gralloc_unregister_buffer;
-	base.lock = gralloc_lock;
-	base.lock_ycbcr = gralloc_lock_ycbcr;
-	base.unlock = gralloc_unlock;
-	base.perform = NULL;
-	INIT_ZERO(base.reserved_proc);
-
-	framebuffer = NULL;
-	flags = 0;
-	numBuffers = 0;
-	bufferMask = 0;
-	pthread_mutex_init(&(lock), NULL);
-	currentBuffer = NULL;
-	INIT_ZERO(info);
-	INIT_ZERO(finfo);
-	xdpi = 0.0f; 
-	ydpi = 0.0f; 
-	fps = 0.0f;
-	swapInterval = 1;
-
-#undef INIT_ZERO
-};
-
-/*
- * HAL_MODULE_INFO_SYM will be initialized using the default constructor
- * implemented above
- */ 
-struct private_module_t HAL_MODULE_INFO_SYM;
-
diff --git a/gralloc960/gralloc_module_ion.cpp b/gralloc960/gralloc_module_ion.cpp
deleted file mode 100644
index 49a17a0..0000000
--- a/gralloc960/gralloc_module_ion.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2013 ARM Limited. All rights reserved.
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <string.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <hardware/hardware.h>
-#include <hardware/gralloc.h>
-
-#include "gralloc_priv.h"
-#include "alloc_device.h"
-#include "framebuffer_device.h"
-#include "ion_4.12.h"
-
-#include <linux/ion.h>
-#include <ion/ion.h>
-#include <sys/mman.h>
-
-int gralloc_backend_register(private_handle_t* hnd)
-{
-	int retval = -EINVAL;
-
-	switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
-	{
-	case private_handle_t::PRIV_FLAGS_USES_ION:
-		unsigned char *mappedAddress;
-		size_t size = hnd->size;
-		hw_module_t * pmodule = NULL;
-		private_module_t *m=NULL;
-		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
-		{
-			m = reinterpret_cast<private_module_t *>(pmodule);
-		}
-		else
-		{
-			AERR("Could not get gralloc module for handle: %p", hnd);
-			retval = -errno;
-			break;
-		}
-		/* the test condition is set to m->ion_client <= 0 here, because:
-		 * 1) module structure are initialized to 0 if no initial value is applied
-		 * 2) a second user process should get a ion fd greater than 0.
-		 */
-		if (m->ion_client <= 0)
-		{
-			/* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/	
-			m->ion_client = ion_open();
-			
-			if (m->ion_client < 0) 
-			{
-				AERR( "Could not open ion device for handle: %p", hnd );
-				retval = -errno;
-				break;
-			}
-		}
-
-		mappedAddress = (unsigned char*)mmap( NULL, size, PROT_READ | PROT_WRITE,
-		                                      MAP_SHARED, hnd->share_fd, 0 );
-		
-		if ( MAP_FAILED == mappedAddress )
-		{
-			AERR( "mmap( share_fd:%d ) failed with %s",  hnd->share_fd, strerror( errno ) );
-			retval = -errno;
-			break;
-		}
-		
-		hnd->base = (void*)(uintptr_t(mappedAddress) + hnd->offset);
-		retval = 0;
-		break;
-	}
-
-	return retval;
-}
-
-void gralloc_backend_unregister(private_handle_t* hnd)
-{
-	switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
-	{
-	case private_handle_t::PRIV_FLAGS_USES_ION:
-		void* base = (void*)hnd->base;
-		size_t size = hnd->size;
-
-		if ( munmap( base,size ) < 0 )
-		{
-			AERR("Could not munmap base:%p size:%zd '%s'", base, size, strerror(errno));
-		}
-		break;
-	}
-}
-
-void gralloc_backend_sync(private_handle_t* hnd)
-{
-	switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
-	{
-	case private_handle_t::PRIV_FLAGS_USES_ION:
-		hw_module_t * pmodule = NULL;
-		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
-		{
-			private_module_t *m = reinterpret_cast<private_module_t *>(pmodule);
-			if (m->gralloc_legacy_ion)
-			{
-				if(!(hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP))
-				{
-					ion_sync_fd(m->ion_client, hnd->share_fd);
-				}
-			}
-		}
-		else
-		{
-			AERR("Could not get gralloc module for handle %p\n", hnd);
-		}
-		break;
-	}
-}
diff --git a/gralloc960/gralloc_priv.h b/gralloc960/gralloc_priv.h
index 606b365..82538bc 100644
--- a/gralloc960/gralloc_priv.h
+++ b/gralloc960/gralloc_priv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * Copyright (C) 2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -27,262 +27,42 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <sys/mman.h>
-#include <hardware/gralloc.h>
 #include <cutils/native_handle.h>
-#include "alloc_device.h"
 #include <utils/Log.h>
 
+#if GRALLOC_USE_GRALLOC1_API
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+/**
+ * mali_gralloc_formats.h needs the define for GRALLOC_MODULE_API_VERSION_0_3 and
+ * GRALLOC_MODULE_API_VERSION_1_0, so include <gralloc1.h> or <gralloc.h> before
+ * including mali_gralloc_formats.h
+ **/
 #include "mali_gralloc_formats.h"
+#include "mali_gralloc_usages.h"
 #include "gralloc_helper.h"
 
+#if defined(GRALLOC_MODULE_API_VERSION_0_3) || \
+    (defined(GRALLOC_MODULE_API_VERSION_1_0) && !defined(GRALLOC_DISABLE_PRIVATE_BUFFER_DEF))
 
-/* NOTE:
- * If your framebuffer device driver is integrated with dma_buf, you will have to
- * change this IOCTL definition to reflect your integration with the framebuffer
- * device.
- * Expected return value is a structure filled with a file descriptor
- * backing your framebuffer device memory.
+/*
+ * This header file contains the private buffer definition. For gralloc 0.3 it will
+ * always be exposed, but for gralloc 1.0 it will be removed at some point in the future.
+ *
+ * GRALLOC_DISABLE_PRIVATE_BUFFER_DEF is intended for DDKs to test while implementing
+ * the new private API.
  */
-struct fb_dmabuf_export
-{
-	__u32 fd;
-	__u32 flags;
-};
-#define FBIOGET_DMABUF	_IOR('F', 0x21, struct fb_dmabuf_export)
+#include "mali_gralloc_buffer.h"
+#endif
 
+#if defined(GRALLOC_MODULE_API_VERSION_1_0)
 
-/* the max string size of GRALLOC_HARDWARE_GPU0 & GRALLOC_HARDWARE_FB0
- * 8 is big enough for "gpu0" & "fb0" currently
+/* gralloc 1.0 supports the new private interface that abstracts
+ * the private buffer definition to a set of defined APIs.
  */
-#define MALI_GRALLOC_HARDWARE_MAX_STR_LEN 8
-#define NUM_FB_BUFFERS 2
-
-/* Define number of shared file descriptors */
-#define GRALLOC_ARM_NUM_FDS 2
-
-#define NUM_INTS_IN_PRIVATE_HANDLE ((sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int) - sNumFds)
-
-#define SZ_4K      0x00001000
-#define SZ_2M      0x00200000
-
-typedef enum
-{
-	MALI_YUV_NO_INFO,
-	MALI_YUV_BT601_NARROW,
-	MALI_YUV_BT601_WIDE,
-	MALI_YUV_BT709_NARROW,
-	MALI_YUV_BT709_WIDE
-} mali_gralloc_yuv_info;
-
-typedef enum
-{
-	MALI_DPY_TYPE_UNKNOWN = 0,
-	MALI_DPY_TYPE_CLCD,
-	MALI_DPY_TYPE_HDLCD
-} mali_dpy_type;
-
-struct private_handle_t;
-
-struct private_module_t
-{
-	gralloc_module_t base;
-
-	struct private_handle_t* framebuffer;
-	uint32_t flags;
-	uint32_t numBuffers;
-	uint32_t bufferMask;
-	pthread_mutex_t lock;
-	buffer_handle_t currentBuffer;
-	int ion_client;
-	int system_heap_id;
-	bool gralloc_legacy_ion;
-	mali_dpy_type dpy_type;
-
-	struct fb_var_screeninfo info;
-	struct fb_fix_screeninfo finfo;
-	float xdpi;
-	float ydpi;
-	float fps;
-	int swapInterval;
-
-#ifdef __cplusplus
-	/* Never intended to be used from C code */
-	enum
-	{
-		// flag to indicate we'll post this buffer
-		PRIV_USAGE_LOCKED_FOR_POST = 0x80000000
-	};
-#endif
-
-#ifdef __cplusplus
-	/* default constructor */
-	private_module_t();
-#endif
-};
-
-#ifndef __cplusplus
-/* C99 with pedantic don't allow anonymous unions which is used in below struct
- * Disable pedantic for C for this struct only.
- */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpedantic"
-#endif
-
-#ifdef __cplusplus
-struct private_handle_t : public native_handle
-{
-#else
-struct private_handle_t
-{
-	struct native_handle nativeHandle;
-#endif
-
-#ifdef __cplusplus
-	/* Never intended to be used from C code */
-	enum
-	{
-		PRIV_FLAGS_FRAMEBUFFER                = 0x00000001,
-		PRIV_FLAGS_USES_ION_COMPOUND_HEAP     = 0x00000002,
-		PRIV_FLAGS_USES_ION                   = 0x00000004,
-		PRIV_FLAGS_USES_ION_DMA_HEAP          = 0x00000008
-	};
-
-	enum
-	{
-		LOCK_STATE_WRITE     =   1<<31,
-		LOCK_STATE_MAPPED    =   1<<30,
-		LOCK_STATE_READ_MASK =   0x3FFFFFFF
-	};
-#endif
-
-	/*
-	 * Shared file descriptor for dma_buf sharing. This must be the first element in the
-	 * structure so that binder knows where it is and can properly share it between
-	 * processes.
-	 * DO NOT MOVE THIS ELEMENT!
-	 */
-	int     share_fd;
-	int     share_attr_fd;
-
-	ion_user_handle_t ion_hnd_UNUSED;
-
-	// ints
-	int        magic;
-	int        req_format;
-	uint64_t   internal_format;
-	int        byte_stride;
-	int        flags;
-	int        usage;
-	int        size;
-	int        width;
-	int        height;
-	int        internalWidth;
-	int        internalHeight;
-	int        stride;
-	union {
-		void*    base;
-		uint64_t padding;
-	};
-	int        lockState;
-	int        writeOwner;
-	int        pid_UNUSED;
-
-	// locally mapped shared attribute area
-	union {
-		void*    attr_base;
-		uint64_t padding3;
-	};
-
-	mali_gralloc_yuv_info yuv_info;
-
-	// Following members is for framebuffer only
-	int   shallow_fbdev_fd; // shallow copy, not dup'ed
-	union {
-		off_t    offset;
-		uint64_t padding4;
-	};
-
-	/*
-	 * min_pgsz denotes minimum phys_page size used by this buffer.
-	 * if buffer memory is physical contiguous set min_pgsz to buff->size
-	 * if not sure buff's real phys_page size, you can use SZ_4K for safe.
-	 */
-	int min_pgsz;
-#ifdef __cplusplus
-	/*
-	 * We track the number of integers in the structure. There are 16 unconditional
-	 * integers (magic - pid, yuv_info, shallow_fbdev_fd and offset).
-	 * Note that the shallow_fbdev_fd element is
-	 * considered an int not an fd because it is not intended to be used outside the
-	 * surface flinger process. The GRALLOC_ARM_NUM_INTS variable is used to track the
-	 * number of integers that are conditionally included. Similar considerations apply
-	 * to the number of fds.
-	 */
-	static const int sNumFds = GRALLOC_ARM_NUM_FDS;
-	static const int sMagic = 0x3141592;
-
-	private_handle_t(int _flags, int _usage, int _size, void *_base, int lock_state, int fb_file, off_t fb_offset):
-		share_fd(-1),
-		share_attr_fd(-1),
-		ion_hnd_UNUSED(-1),
-		magic(sMagic),
-		flags(_flags),
-		usage(_usage),
-		size(_size),
-		width(0),
-		height(0),
-		stride(0),
-		base(_base),
-		lockState(lock_state),
-		writeOwner(0),
-		pid_UNUSED(-1),
-		attr_base(MAP_FAILED),
-		yuv_info(MALI_YUV_NO_INFO),
-		shallow_fbdev_fd(fb_file),
-		offset(fb_offset)
-	{
-		version = sizeof(native_handle);
-		numFds = sNumFds;
-		numInts = NUM_INTS_IN_PRIVATE_HANDLE;
-	}
-
-	~private_handle_t()
-	{
-		magic = 0;
-	}
-
-	bool usesPhysicallyContiguousMemory()
-	{
-		return (flags & PRIV_FLAGS_FRAMEBUFFER) ? true : false;
-	}
-
-	static int validate(const native_handle* h)
-	{
-		const private_handle_t* hnd = (const private_handle_t*)h;
-		if (!h ||
-		    h->version != sizeof(native_handle) ||
-		    h->numInts != NUM_INTS_IN_PRIVATE_HANDLE ||
-		    h->numFds != sNumFds ||
-		    hnd->magic != sMagic)
-		{
-			return -EINVAL;
-		}
-		return 0;
-	}
-
-	static private_handle_t* dynamicCast(const native_handle* in)
-	{
-		if (validate(in) == 0)
-		{
-			return (private_handle_t*) in;
-		}
-		return NULL;
-	}
-#endif
-};
-#ifndef __cplusplus
-/* Restore previous diagnostic for pedantic */
-#pragma GCC diagnostic pop
+#include "mali_gralloc_private_interface.h"
 #endif
 
 #endif /* GRALLOC_PRIV_H_ */
diff --git a/gralloc960/gralloc_vsync.h b/gralloc960/gralloc_vsync.h
index 6027eda..af2bd2b 100644
--- a/gralloc960/gralloc_vsync.h
+++ b/gralloc960/gralloc_vsync.h
@@ -22,10 +22,10 @@
 struct framebuffer_device_t;
 
 /* Enables vsync interrupt. */
-int gralloc_vsync_enable(struct framebuffer_device_t* dev);
+int gralloc_vsync_enable(struct framebuffer_device_t *dev);
 /* Disables vsync interrupt. */
-int gralloc_vsync_disable(struct framebuffer_device_t* dev);
+int gralloc_vsync_disable(struct framebuffer_device_t *dev);
 /* Waits for the vsync interrupt. */
-int gralloc_wait_for_vsync(struct framebuffer_device_t* dev);
+int gralloc_wait_for_vsync(struct framebuffer_device_t *dev);
 
 #endif /* _GRALLOC_VSYNC_H_ */
diff --git a/gralloc960/gralloc_vsync_default.cpp b/gralloc960/gralloc_vsync_default.cpp
index 3ce7f0e..2a38fd9 100644
--- a/gralloc960/gralloc_vsync_default.cpp
+++ b/gralloc960/gralloc_vsync_default.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2014-2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -16,13 +16,25 @@
  * limitations under the License.
  */
 
-#include "gralloc_priv.h"
-#include "gralloc_vsync.h"
-#include "gralloc_vsync_report.h"
 #include <sys/ioctl.h>
 #include <errno.h>
 
-#define FBIO_WAITFORVSYNC       _IOW('F', 0x20, __u32)
+#include <hardware/hardware.h>
+#include <hardware/fb.h>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+#include "gralloc_vsync.h"
+#include "gralloc_vsync_report.h"
+
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
 
 int gralloc_vsync_enable(framebuffer_device_t *dev)
 {
@@ -38,23 +50,27 @@
 
 int gralloc_wait_for_vsync(framebuffer_device_t *dev)
 {
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
+	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
+
 	if (MALI_DPY_TYPE_CLCD == m->dpy_type || MALI_DPY_TYPE_HDLCD == m->dpy_type)
 	{
 		/* Silently ignore wait for vsync as neither PL111 nor HDLCD implement this IOCTL. */
 		return 0;
 	}
 
-	if ( m->swapInterval )
+	if (m->swapInterval)
 	{
 		int crtc = 0;
 		gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT);
-		if(ioctl(m->framebuffer->shallow_fbdev_fd, FBIO_WAITFORVSYNC, &crtc) < 0) 
+
+		if (ioctl(m->framebuffer->fd, FBIO_WAITFORVSYNC, &crtc) < 0)
 		{
 			gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
 			return -errno;
 		}
+
 		gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
 	}
+
 	return 0;
 }
diff --git a/gralloc960/gralloc_vsync_report.h b/gralloc960/gralloc_vsync_report.h
index ea45cc4..49baabf 100644
--- a/gralloc960/gralloc_vsync_report.h
+++ b/gralloc960/gralloc_vsync_report.h
@@ -20,11 +20,9 @@
 #include "gralloc_helper.h"
 
 #ifdef __cplusplus
-extern "C"
-{
+extern "C" {
 #endif
 
-
 typedef enum mali_vsync_event
 {
 	MALI_VSYNC_EVENT_BEGIN_WAIT = 0,
@@ -35,11 +33,11 @@
 
 inline void gralloc_mali_vsync_report(mali_vsync_event event)
 {
-	#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
+#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
 	_mali_base_arch_vsync_event_report(event);
-	#else
+#else
 	GRALLOC_UNUSED(event);
-	#endif
+#endif
 }
 
 #ifdef __cplusplus
diff --git a/gralloc960/gralloc_vsync_s3cfb.cpp b/gralloc960/gralloc_vsync_s3cfb.cpp
index 5740ea9..434e685 100644
--- a/gralloc960/gralloc_vsync_s3cfb.cpp
+++ b/gralloc960/gralloc_vsync_s3cfb.cpp
@@ -22,38 +22,52 @@
 #include <sys/ioctl.h>
 #include <errno.h>
 
-#define FBIO_WAITFORVSYNC       _IOW('F', 0x20, __u32)
-#define S3CFB_SET_VSYNC_INT	_IOW('F', 206, unsigned int)
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+#define S3CFB_SET_VSYNC_INT _IOW('F', 206, unsigned int)
 
 int gralloc_vsync_enable(framebuffer_device_t *dev)
 {
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
+	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
 	int interrupt = 1;
-	if(ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0) return -errno;
+
+	if (ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0)
+	{
+		return -errno;
+	}
+
 	return 0;
 }
 
 int gralloc_vsync_disable(framebuffer_device_t *dev)
 {
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
+	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
 	int interrupt = 0;
-	if(ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0) return -errno;
+
+	if (ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0)
+	{
+		return -errno;
+	}
+
 	return 0;
 }
 
 int gralloc_wait_for_vsync(framebuffer_device_t *dev)
 {
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
-	if ( m->swapInterval )
+	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
+
+	if (m->swapInterval)
 	{
 		int crtc = 0;
 		gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT);
-		if(ioctl(m->framebuffer->fd, FBIO_WAITFORVSYNC, &crtc) < 0) 
+
+		if (ioctl(m->framebuffer->fd, FBIO_WAITFORVSYNC, &crtc) < 0)
 		{
 			gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
 			return -errno;
 		}
+
 		gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
 	}
+
 	return 0;
 }
diff --git a/gralloc960/legacy/alloc_device.cpp b/gralloc960/legacy/alloc_device.cpp
new file mode 100644
index 0000000..fa381fc
--- /dev/null
+++ b/gralloc960/legacy/alloc_device.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2010-2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+
+#include <sys/ioctl.h>
+
+#include "mali_gralloc_module.h"
+#include "alloc_device.h"
+#include "gralloc_priv.h"
+#include "gralloc_helper.h"
+#include "framebuffer_device.h"
+#include "mali_gralloc_ion.h"
+#include "gralloc_buffer_priv.h"
+#include "mali_gralloc_bufferdescriptor.h"
+#include "mali_gralloc_bufferallocation.h"
+#include "mali_gralloc_formats.h"
+#include "mali_gralloc_usages.h"
+
+static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int usage, buffer_handle_t *pHandle,
+                              int *pStride)
+{
+	mali_gralloc_module *m;
+	int err = -EINVAL;
+
+	if (!dev || !pHandle || !pStride)
+	{
+		return err;
+	}
+
+	m = reinterpret_cast<private_module_t *>(dev->common.module);
+
+#if GRALLOC_FB_SWAP_RED_BLUE == 1
+
+	/* match the framebuffer format */
+	if (usage & GRALLOC_USAGE_HW_FB)
+	{
+#ifdef GRALLOC_16_BITS
+		format = HAL_PIXEL_FORMAT_RGB_565;
+#else
+		format = HAL_PIXEL_FORMAT_BGRA_8888;
+#endif
+	}
+
+#endif
+
+#if DISABLE_FRAMEBUFFER_HAL != 1
+
+	if (usage & GRALLOC_USAGE_HW_FB)
+	{
+		int byte_stride;
+		int pixel_stride;
+
+		err = fb_alloc_framebuffer(m, usage, usage, pHandle, &pixel_stride, &byte_stride);
+
+		if (err >= 0)
+		{
+			private_handle_t *hnd = (private_handle_t *)*pHandle;
+
+			/* Allocate a meta-data buffer for framebuffer too. fbhal
+			 * ones wont need it but it will lead to binder IPC fail
+			 * without a valid share_attr_fd.
+			 *
+			 * Explicitly ignore allocation errors since it is not critical to have
+			 */
+			(void)gralloc_buffer_attr_allocate(hnd);
+
+			hnd->req_format = format;
+			hnd->yuv_info = MALI_YUV_BT601_NARROW;
+			hnd->internal_format = format;
+			hnd->byte_stride = byte_stride;
+			hnd->width = w;
+			hnd->height = h;
+			hnd->stride = pixel_stride;
+			hnd->internalWidth = w;
+			hnd->internalHeight = h;
+		}
+	}
+	else
+#endif
+	{
+		/* share the same allocation interface with gralloc1.*/
+		buffer_descriptor_t buffer_descriptor;
+		gralloc_buffer_descriptor_t gralloc_buffer_descriptor[1];
+
+		buffer_descriptor.hal_format = format;
+		buffer_descriptor.consumer_usage = usage;
+		buffer_descriptor.producer_usage = usage;
+		buffer_descriptor.width = w;
+		buffer_descriptor.height = h;
+		buffer_descriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
+		gralloc_buffer_descriptor[0] = (gralloc_buffer_descriptor_t)(&buffer_descriptor);
+
+		if (mali_gralloc_buffer_allocate(m, gralloc_buffer_descriptor, 1, pHandle, NULL) < 0)
+		{
+			ALOGE("Failed to allocate buffer.");
+			err = -ENOMEM;
+		}
+		else
+		{
+			mali_gralloc_query_getstride(*pHandle, pStride);
+			err = 0;
+		}
+	}
+
+	return err;
+}
+
+static int alloc_device_free(alloc_device_t *dev, buffer_handle_t handle)
+{
+	if (private_handle_t::validate(handle) < 0)
+	{
+		return -EINVAL;
+	}
+
+	private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(handle);
+	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
+
+	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
+	{
+		// free this buffer
+		close(hnd->fd);
+	}
+	else
+	{
+		mali_gralloc_buffer_free(handle);
+	}
+
+	delete hnd;
+
+	return 0;
+}
+
+int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
+{
+	alloc_device_t *dev;
+
+	GRALLOC_UNUSED(name);
+
+	dev = new alloc_device_t;
+
+	if (NULL == dev)
+	{
+		return -1;
+	}
+
+	/* initialize our state here */
+	memset(dev, 0, sizeof(*dev));
+
+	/* initialize the procs */
+	dev->common.tag = HARDWARE_DEVICE_TAG;
+	dev->common.version = 0;
+	dev->common.module = const_cast<hw_module_t *>(module);
+	dev->common.close = mali_gralloc_ion_device_close;
+	dev->alloc = alloc_device_alloc;
+	dev->free = alloc_device_free;
+
+	*device = &dev->common;
+
+	return 0;
+}
diff --git a/gralloc960/gralloc_module_allocator_specific.h b/gralloc960/legacy/alloc_device.h
similarity index 68%
rename from gralloc960/gralloc_module_allocator_specific.h
rename to gralloc960/legacy/alloc_device.h
index f719e73..6fb186a 100644
--- a/gralloc960/gralloc_module_allocator_specific.h
+++ b/gralloc960/legacy/alloc_device.h
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2013 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,8 +16,7 @@
  * limitations under the License.
  */
 
-int gralloc_backend_register(struct private_handle_t* hnd);
+#include <hardware/hardware.h>
 
-void gralloc_backend_unregister(struct private_handle_t* hnd);
-
-void gralloc_backend_sync(struct private_handle_t* hnd);
+// Create an alloc device
+int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device);
diff --git a/gralloc960/mali_gralloc_buffer.h b/gralloc960/mali_gralloc_buffer.h
new file mode 100644
index 0000000..959653f
--- /dev/null
+++ b/gralloc960/mali_gralloc_buffer.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MALI_GRALLOC_BUFFER_H_
+#define MALI_GRALLOC_BUFFER_H_
+
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <linux/ion.h>
+#include <sys/mman.h>
+
+#include "mali_gralloc_private_interface_types.h"
+
+/* NOTE:
+ * If your framebuffer device driver is integrated with dma_buf, you will have to
+ * change this IOCTL definition to reflect your integration with the framebuffer
+ * device.
+ * Expected return value is a structure filled with a file descriptor
+ * backing your framebuffer device memory.
+ */
+struct fb_dmabuf_export
+{
+	__u32 fd;
+	__u32 flags;
+};
+#define FBIOGET_DMABUF _IOR('F', 0x21, struct fb_dmabuf_export)
+
+/* the max string size of GRALLOC_HARDWARE_GPU0 & GRALLOC_HARDWARE_FB0
+ * 8 is big enough for "gpu0" & "fb0" currently
+ */
+#define MALI_GRALLOC_HARDWARE_MAX_STR_LEN 8
+#define NUM_FB_BUFFERS 2
+
+/* Define number of shared file descriptors */
+#define GRALLOC_ARM_NUM_FDS 2
+
+#define NUM_INTS_IN_PRIVATE_HANDLE ((sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int) - sNumFds)
+
+#define SZ_4K 0x00001000
+#define SZ_2M 0x00200000
+
+struct private_handle_t;
+
+#ifndef __cplusplus
+/* C99 with pedantic don't allow anonymous unions which is used in below struct
+ * Disable pedantic for C for this struct only.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
+#ifdef __cplusplus
+struct private_handle_t : public native_handle
+{
+#else
+struct private_handle_t
+{
+	struct native_handle nativeHandle;
+#endif
+
+#ifdef __cplusplus
+	/* Never intended to be used from C code */
+	enum
+	{
+		PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
+		PRIV_FLAGS_USES_ION_COMPOUND_HEAP = 0x00000002,
+		PRIV_FLAGS_USES_ION = 0x00000004,
+		PRIV_FLAGS_USES_ION_DMA_HEAP = 0x00000008
+	};
+
+	enum
+	{
+		LOCK_STATE_WRITE = 1 << 31,
+		LOCK_STATE_MAPPED = 1 << 30,
+		LOCK_STATE_READ_MASK = 0x3FFFFFFF
+	};
+#endif
+
+	/*
+	 * Shared file descriptor for dma_buf sharing. This must be the first element in the
+	 * structure so that binder knows where it is and can properly share it between
+	 * processes.
+	 * DO NOT MOVE THIS ELEMENT!
+	 */
+	int share_fd;
+	int share_attr_fd;
+
+	// ints
+	int magic;
+	int req_format;
+	uint64_t internal_format;
+	int byte_stride;
+	int flags;
+	int size;
+	int width;
+	int height;
+	int internalWidth;
+	int internalHeight;
+	int stride;
+	union
+	{
+		void *base;
+		uint64_t padding;
+	};
+	uint64_t consumer_usage;
+	uint64_t producer_usage;
+	uint64_t backing_store_id;
+	int backing_store_size;
+	int writeOwner;
+	int allocating_pid;
+	int remote_pid;
+	int ref_count;
+	// locally mapped shared attribute area
+	union
+	{
+		void *attr_base;
+		uint64_t padding3;
+	};
+
+	mali_gralloc_yuv_info yuv_info;
+
+	// Following members is for framebuffer only
+	int fd;
+	union
+	{
+		off_t offset;
+		uint64_t padding4;
+	};
+
+	/*
+	 * min_pgsz denotes minimum phys_page size used by this buffer.
+	 * if buffer memory is physical contiguous set min_pgsz to buff->size
+	 * if not sure buff's real phys_page size, you can use SZ_4K for safe.
+	 */
+	int min_pgsz;
+#ifdef __cplusplus
+	/*
+	 * We track the number of integers in the structure. There are 16 unconditional
+	 * integers (magic - pid, yuv_info, fd and offset). Note that the fd element is
+	 * considered an int not an fd because it is not intended to be used outside the
+	 * surface flinger process. The GRALLOC_ARM_NUM_INTS variable is used to track the
+	 * number of integers that are conditionally included. Similar considerations apply
+	 * to the number of fds.
+	 */
+	static const int sNumFds = GRALLOC_ARM_NUM_FDS;
+	static const int sMagic = 0x3141592;
+
+	private_handle_t(int _flags, int _size, void *_base, uint64_t _consumer_usage, uint64_t _producer_usage,
+	                 int fb_file, off_t fb_offset)
+	    : share_fd(-1)
+	    , share_attr_fd(-1)
+	    , magic(sMagic)
+	    , flags(_flags)
+	    , size(_size)
+	    , width(0)
+	    , height(0)
+	    , stride(0)
+	    , base(_base)
+	    , consumer_usage(_consumer_usage)
+	    , producer_usage(_producer_usage)
+	    , backing_store_id(0x0)
+	    , backing_store_size(0)
+	    , writeOwner(0)
+	    , allocating_pid(getpid())
+	    , remote_pid(-1)
+	    , ref_count(1)
+	    , attr_base(MAP_FAILED)
+	    , yuv_info(MALI_YUV_NO_INFO)
+	    , fd(fb_file)
+	    , offset(fb_offset)
+	{
+		version = sizeof(native_handle);
+		numFds = sNumFds;
+		numInts = NUM_INTS_IN_PRIVATE_HANDLE;
+	}
+
+	private_handle_t(int _flags, int _size, int _min_pgsz, uint64_t _consumer_usage, uint64_t _producer_usage,
+	                 int _shared_fd, int _req_format, uint64_t _internal_format, int _byte_stride, int _width,
+	                 int _height, int _stride, int _internalWidth, int _internalHeight, int _backing_store_size)
+	    : share_fd(_shared_fd)
+	    , share_attr_fd(-1)
+	    , magic(sMagic)
+	    , req_format(_req_format)
+	    , internal_format(_internal_format)
+	    , byte_stride(_byte_stride)
+	    , flags(_flags)
+	    , size(_size)
+	    , width(_width)
+	    , height(_height)
+	    , internalWidth(_internalWidth)
+	    , internalHeight(_internalHeight)
+	    , stride(_stride)
+	    , base(NULL)
+	    , consumer_usage(_consumer_usage)
+	    , producer_usage(_producer_usage)
+	    , backing_store_id(0x0)
+	    , backing_store_size(_backing_store_size)
+	    , writeOwner(0)
+	    , allocating_pid(getpid())
+	    , remote_pid(-1)
+	    , ref_count(1)
+	    , attr_base(MAP_FAILED)
+	    , yuv_info(MALI_YUV_NO_INFO)
+	    , fd(-1)
+	    , offset(0)
+	    , min_pgsz(_min_pgsz)
+	{
+		version = sizeof(native_handle);
+		numFds = sNumFds;
+		numInts = NUM_INTS_IN_PRIVATE_HANDLE;
+	}
+
+	~private_handle_t()
+	{
+		magic = 0;
+	}
+
+	bool usesPhysicallyContiguousMemory()
+	{
+		return (flags & PRIV_FLAGS_FRAMEBUFFER) ? true : false;
+	}
+
+	static int validate(const native_handle *h)
+	{
+		const private_handle_t *hnd = (const private_handle_t *)h;
+
+		if (!h || h->version != sizeof(native_handle) || h->numInts != NUM_INTS_IN_PRIVATE_HANDLE ||
+		    h->numFds != sNumFds || hnd->magic != sMagic)
+		{
+			return -EINVAL;
+		}
+
+		return 0;
+	}
+
+	static private_handle_t *dynamicCast(const native_handle *in)
+	{
+		if (validate(in) == 0)
+		{
+			return (private_handle_t *)in;
+		}
+
+		return NULL;
+	}
+#endif
+};
+#ifndef __cplusplus
+/* Restore previous diagnostic for pedantic */
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* MALI_GRALLOC_BUFFER_H_ */
diff --git a/gralloc960/mali_gralloc_bufferaccess.cpp b/gralloc960/mali_gralloc_bufferaccess.cpp
new file mode 100644
index 0000000..ea77283
--- /dev/null
+++ b/gralloc960/mali_gralloc_bufferaccess.cpp
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <errno.h>
+#include <inttypes.h>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+#include "mali_gralloc_formats.h"
+#include "mali_gralloc_usages.h"
+#include "mali_gralloc_ion.h"
+#include "gralloc_helper.h"
+#include <sync/sync.h>
+
+int mali_gralloc_lock(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w, int h,
+                      void **vaddr)
+{
+	GRALLOC_UNUSED(m);
+	GRALLOC_UNUSED(l);
+	GRALLOC_UNUSED(t);
+	GRALLOC_UNUSED(w);
+	GRALLOC_UNUSED(h);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Locking invalid buffer %p, returning error", buffer);
+		return -EINVAL;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+
+	if (hnd->req_format == HAL_PIXEL_FORMAT_YCbCr_420_888)
+	{
+		AERR("Buffers with format YCbCr_420_888 must be locked using (*lock_ycbcr)");
+		return -EINVAL;
+	}
+
+	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+	{
+		hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
+	}
+
+	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
+	{
+		*vaddr = (void *)hnd->base;
+	}
+
+	return 0;
+}
+
+int mali_gralloc_lock_ycbcr(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w,
+                            int h, android_ycbcr *ycbcr)
+{
+	GRALLOC_UNUSED(m);
+	GRALLOC_UNUSED(l);
+	GRALLOC_UNUSED(t);
+	GRALLOC_UNUSED(w);
+	GRALLOC_UNUSED(h);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Locking invalid buffer %p, returning error", buffer);
+		return -EINVAL;
+	}
+
+	if (NULL == ycbcr)
+	{
+		return -EINVAL;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+
+	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+	{
+		hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
+	}
+
+	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) &&
+	    !(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK))
+	{
+		char *base = (char *)hnd->base;
+		int y_stride = hnd->byte_stride;
+		/* Ensure height is aligned for subsampled chroma before calculating buffer parameters */
+		int adjusted_height = GRALLOC_ALIGN(hnd->height, 2);
+		int y_size = y_stride * adjusted_height;
+
+		int u_offset = 0;
+		int v_offset = 0;
+		int c_stride = 0;
+		int step = 0;
+
+		uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+
+		switch (base_format)
+		{
+		case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+			c_stride = y_stride;
+			/* Y plane, UV plane */
+			u_offset = y_size;
+			v_offset = y_size + 1;
+			step = 2;
+			break;
+
+		case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
+			c_stride = y_stride;
+			/* Y plane, UV plane */
+			v_offset = y_size;
+			u_offset = y_size + 1;
+			step = 2;
+			break;
+
+		case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
+		{
+			int c_size;
+
+			/* Stride alignment set to 16 as the SW access flags were set */
+			c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16);
+			c_size = c_stride * (adjusted_height / 2);
+			/* Y plane, V plane, U plane */
+			v_offset = y_size;
+			u_offset = y_size + c_size;
+			step = 1;
+			break;
+		}
+
+		default:
+			AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format);
+			return -EINVAL;
+		}
+
+		ycbcr->y = base;
+		ycbcr->cb = base + u_offset;
+		ycbcr->cr = base + v_offset;
+		ycbcr->ystride = y_stride;
+		ycbcr->cstride = c_stride;
+		ycbcr->chroma_step = step;
+	}
+	else
+	{
+		AERR("Don't support to lock buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int mali_gralloc_unlock(const mali_gralloc_module *m, buffer_handle_t buffer)
+{
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Unlocking invalid buffer %p, returning error", buffer);
+		return -EINVAL;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+
+	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner)
+	{
+		mali_gralloc_ion_sync(m, hnd);
+	}
+
+	return 0;
+}
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+int mali_gralloc_get_num_flex_planes(const mali_gralloc_module *m, buffer_handle_t buffer, uint32_t *num_planes)
+{
+	GRALLOC_UNUSED(m);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Invalid buffer %p, returning error", buffer);
+		return -EINVAL;
+	}
+
+	if (NULL == num_planes)
+	{
+		return -EINVAL;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+	uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+
+	switch (base_format)
+	{
+	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+	case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
+	case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
+		*num_planes = 3;
+		break;
+
+	default:
+		AERR("Can't get planes number of buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+
+int mali_gralloc_lock_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w,
+                            int h, void **vaddr, int32_t fence_fd)
+{
+	if (fence_fd >= 0)
+	{
+		sync_wait(fence_fd, -1);
+		close(fence_fd);
+	}
+
+	return mali_gralloc_lock(m, buffer, usage, l, t, w, h, vaddr);
+}
+
+int mali_gralloc_lock_ycbcr_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t,
+                                  int w, int h, android_ycbcr *ycbcr, int32_t fence_fd)
+{
+	if (fence_fd >= 0)
+	{
+		sync_wait(fence_fd, -1);
+		close(fence_fd);
+	}
+
+	return mali_gralloc_lock_ycbcr(m, buffer, usage, l, t, w, h, ycbcr);
+}
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+
+int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t,
+                                 int w, int h, struct android_flex_layout *flex_layout, int32_t fence_fd)
+{
+	GRALLOC_UNUSED(m);
+	GRALLOC_UNUSED(l);
+	GRALLOC_UNUSED(t);
+	GRALLOC_UNUSED(w);
+	GRALLOC_UNUSED(h);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Locking invalid buffer %p, returning error", buffer);
+		return -EINVAL;
+	}
+
+	if (NULL == flex_layout)
+	{
+		return -EINVAL;
+	}
+
+	if (fence_fd >= 0)
+	{
+		sync_wait(fence_fd, -1);
+		close(fence_fd);
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+
+	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+	{
+		hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
+	}
+
+	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) &&
+	    !(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK))
+	{
+		uint8_t *base = (uint8_t *)hnd->base;
+		int y_stride = hnd->byte_stride;
+		/* Ensure height is aligned for subsampled chroma before calculating buffer parameters */
+		int adjusted_height = GRALLOC_ALIGN(hnd->height, 2);
+		int y_size = y_stride * adjusted_height;
+
+		uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+
+		switch (base_format)
+		{
+		case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+			flex_layout->format = FLEX_FORMAT_YCbCr;
+			flex_layout->num_planes = 3;
+			flex_layout->planes[0].top_left = base;
+			flex_layout->planes[0].component = FLEX_COMPONENT_Y;
+			flex_layout->planes[0].bits_per_component = 8;
+			flex_layout->planes[0].bits_used = 8;
+			flex_layout->planes[0].h_increment = 1;
+			flex_layout->planes[0].v_increment = y_stride;
+			flex_layout->planes[0].h_subsampling = 1;
+			flex_layout->planes[0].v_subsampling = 1;
+			flex_layout->planes[1].top_left = base + y_size;
+			flex_layout->planes[1].component = FLEX_COMPONENT_Cb;
+			flex_layout->planes[1].bits_per_component = 8;
+			flex_layout->planes[1].bits_used = 8;
+			flex_layout->planes[1].h_increment = 2;
+			flex_layout->planes[1].v_increment = y_stride;
+			flex_layout->planes[1].h_subsampling = 2;
+			flex_layout->planes[1].v_subsampling = 2;
+			flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + 1;
+			flex_layout->planes[2].component = FLEX_COMPONENT_Cr;
+			flex_layout->planes[2].bits_per_component = 8;
+			flex_layout->planes[2].bits_used = 8;
+			flex_layout->planes[2].h_increment = 2;
+			flex_layout->planes[2].v_increment = y_stride;
+			flex_layout->planes[2].h_subsampling = 2;
+			flex_layout->planes[2].v_subsampling = 2;
+			break;
+
+		case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
+			flex_layout->format = FLEX_FORMAT_YCbCr;
+			flex_layout->num_planes = 3;
+			flex_layout->planes[0].top_left = base;
+			flex_layout->planes[0].component = FLEX_COMPONENT_Y;
+			flex_layout->planes[0].bits_per_component = 8;
+			flex_layout->planes[0].bits_used = 8;
+			flex_layout->planes[0].h_increment = 1;
+			flex_layout->planes[0].v_increment = y_stride;
+			flex_layout->planes[0].h_subsampling = 1;
+			flex_layout->planes[0].v_subsampling = 1;
+			flex_layout->planes[1].top_left = base + y_size;
+			flex_layout->planes[1].component = FLEX_COMPONENT_Cr;
+			flex_layout->planes[1].bits_per_component = 8;
+			flex_layout->planes[1].bits_used = 8;
+			flex_layout->planes[1].h_increment = 2;
+			flex_layout->planes[1].v_increment = y_stride;
+			flex_layout->planes[1].h_subsampling = 2;
+			flex_layout->planes[1].v_subsampling = 2;
+			flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + 1;
+			flex_layout->planes[2].component = FLEX_COMPONENT_Cb;
+			flex_layout->planes[2].bits_per_component = 8;
+			flex_layout->planes[2].bits_used = 8;
+			flex_layout->planes[2].h_increment = 2;
+			flex_layout->planes[2].v_increment = y_stride;
+			flex_layout->planes[2].h_subsampling = 2;
+			flex_layout->planes[2].v_subsampling = 2;
+			break;
+
+		case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
+		{
+			int c_size;
+			int c_stride;
+			/* Stride alignment set to 16 as the SW access flags were set */
+			c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16);
+			c_size = c_stride * (adjusted_height / 2);
+			/* Y plane, V plane, U plane */
+			flex_layout->format = FLEX_FORMAT_YCbCr;
+			flex_layout->num_planes = 3;
+			flex_layout->planes[0].top_left = base;
+			flex_layout->planes[0].component = FLEX_COMPONENT_Y;
+			flex_layout->planes[0].bits_per_component = 8;
+			flex_layout->planes[0].bits_used = 8;
+			flex_layout->planes[0].h_increment = 1;
+			flex_layout->planes[0].v_increment = y_stride;
+			flex_layout->planes[0].h_subsampling = 1;
+			flex_layout->planes[0].v_subsampling = 1;
+			flex_layout->planes[1].top_left = base + y_size;
+			flex_layout->planes[1].component = FLEX_COMPONENT_Cr;
+			flex_layout->planes[1].bits_per_component = 8;
+			flex_layout->planes[1].bits_used = 8;
+			flex_layout->planes[1].h_increment = 1;
+			flex_layout->planes[1].v_increment = c_stride;
+			flex_layout->planes[1].h_subsampling = 2;
+			flex_layout->planes[1].v_subsampling = 2;
+			flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + c_size;
+			flex_layout->planes[2].component = FLEX_COMPONENT_Cb;
+			flex_layout->planes[2].bits_per_component = 8;
+			flex_layout->planes[2].bits_used = 8;
+			flex_layout->planes[2].h_increment = 1;
+			flex_layout->planes[2].v_increment = c_stride;
+			flex_layout->planes[2].h_subsampling = 2;
+			flex_layout->planes[2].v_subsampling = 2;
+			break;
+		}
+
+		default:
+			AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format);
+			return -EINVAL;
+		}
+	}
+	else
+	{
+		AERR("Don't support to lock buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+
+int mali_gralloc_unlock_async(const mali_gralloc_module *m, buffer_handle_t buffer, int32_t *fence_fd)
+{
+	*fence_fd = -1;
+
+	if (mali_gralloc_unlock(m, buffer) < 0)
+	{
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/gralloc960/mali_gralloc_bufferaccess.h b/gralloc960/mali_gralloc_bufferaccess.h
new file mode 100644
index 0000000..28e0959
--- /dev/null
+++ b/gralloc960/mali_gralloc_bufferaccess.h
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MALI_GRALLOC_BUFFERACCESS_H_
+#define MALI_GRALLOC_BUFFERACCESS_H_
+
+#include "gralloc_priv.h"
+#include "mali_gralloc_module.h"
+
+int mali_gralloc_lock(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w, int h,
+                      void **vaddr);
+int mali_gralloc_lock_ycbcr(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w,
+                            int h, android_ycbcr *ycbcr);
+int mali_gralloc_unlock(const mali_gralloc_module *m, buffer_handle_t buffer);
+
+int mali_gralloc_get_num_flex_planes(const mali_gralloc_module *m, buffer_handle_t buffer, uint32_t *num_planes);
+int mali_gralloc_lock_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w,
+                            int h, void **vaddr, int32_t fence_fd);
+int mali_gralloc_lock_ycbcr_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t,
+                                  int w, int h, android_ycbcr *ycbcr, int32_t fence_fd);
+int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t,
+                                 int w, int h, struct android_flex_layout *flex_layout, int32_t fence_fd);
+int mali_gralloc_unlock_async(const mali_gralloc_module *m, buffer_handle_t buffer, int32_t *fence_fd);
+
+#endif /* MALI_GRALLOC_BUFFERACCESS_H_ */
diff --git a/gralloc960/alloc_device.cpp b/gralloc960/mali_gralloc_bufferallocation.cpp
similarity index 60%
rename from gralloc960/alloc_device.cpp
rename to gralloc960/mali_gralloc_bufferallocation.cpp
index 9a3ff8c..0efc64e 100644
--- a/gralloc960/alloc_device.cpp
+++ b/gralloc960/mali_gralloc_bufferallocation.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -16,42 +16,40 @@
  * limitations under the License.
  */
 
-#include <string.h>
-#include <errno.h>
-#include <pthread.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
 #include <hardware/hardware.h>
+#include <inttypes.h>
+#include <atomic>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
 #include <hardware/gralloc.h>
+#endif
 
-#include <sys/ioctl.h>
-
-#include "alloc_device.h"
-#include "gralloc_priv.h"
-#include "gralloc_helper.h"
-#include "framebuffer_device.h"
-
-#include "alloc_device_allocator_specific.h"
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_bufferallocation.h"
+#include "mali_gralloc_ion.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
 #include "gralloc_buffer_priv.h"
+#include "mali_gralloc_bufferdescriptor.h"
+#include "mali_gralloc_debug.h"
 
-#include "mali_gralloc_formats.h"
+#define AFBC_PIXELS_PER_BLOCK 16
+#define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16
 
-#define AFBC_PIXELS_PER_BLOCK                    16
-#define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY  16
-
-#define AFBC_BODY_BUFFER_BYTE_ALIGNMENT          1024
-#define AFBC_NORMAL_WIDTH_ALIGN                  16
-#define AFBC_NORMAL_HEIGHT_ALIGN                 16
-#define AFBC_WIDEBLK_WIDTH_ALIGN                 32
-#define AFBC_WIDEBLK_HEIGHT_ALIGN                16
+#define AFBC_BODY_BUFFER_BYTE_ALIGNMENT 1024
+#define AFBC_NORMAL_WIDTH_ALIGN 16
+#define AFBC_NORMAL_HEIGHT_ALIGN 16
+#define AFBC_WIDEBLK_WIDTH_ALIGN 32
+#define AFBC_WIDEBLK_HEIGHT_ALIGN 16
 // Regarding Tiled Headers AFBC mode, both header and body buffer should aligned to 4KB
 // and in non-wide mode (16x16), the width and height should be both rounded up to 128
 // in wide mode (32x8) the width should be rounded up to 256, the height should be rounded up to 64
-#define AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN           128
-#define AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN          128
-#define AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN         256
-#define AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN        64
+#define AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN 128
+#define AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN 128
+#define AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN 256
+#define AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN 64
 
 // This value is platform specific and should be set according to hardware YUV planes restrictions.
 // Please note that EGL winsys platform config file needs to use the same value when importing buffers.
@@ -60,94 +58,6 @@
 // Default YUV stride aligment in Android
 #define YUV_ANDROID_PLANE_ALIGN 16
 
-static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, int* stride, int* byte_stride)
-{
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
-
-	// allocate the framebuffer
-	if (m->framebuffer == NULL)
-	{
-		// initialize the framebuffer, the framebuffer is mapped once and forever.
-		int err = init_frame_buffer_locked(m);
-		if (err < 0)
-		{
-			return err;
-		}
-	}
-
-	const uint32_t bufferMask = m->bufferMask;
-	const uint32_t numBuffers = m->numBuffers;
-	/* framebufferSize is used for allocating the handle to the framebuffer and refers
-	 *                 to the size of the actual framebuffer.
-	 * alignedFramebufferSize is used for allocating a possible internal buffer and
-	 *                        thus need to consider internal alignment requirements. */
-	const size_t framebufferSize = m->finfo.line_length * m->info.yres;
-	const size_t alignedFramebufferSize = GRALLOC_ALIGN(m->finfo.line_length, 64) * m->info.yres;
-
-	*stride = m->info.xres;
-
-	if (numBuffers == 1)
-	{
-		// If we have only one buffer, we never use page-flipping. Instead,
-		// we return a regular buffer which will be memcpy'ed to the main
-		// screen when post is called.
-		int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
-		AWAR( "fallback to single buffering. Virtual Y-res too small %d", m->info.yres );
-		*byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
-		return alloc_backend_alloc(dev, alignedFramebufferSize, newUsage, pHandle, 0, 0, 0);
-	}
-
-	if (bufferMask >= ((1LU<<numBuffers)-1))
-	{
-		// We ran out of buffers.
-		return -ENOMEM;
-	}
-
-	uintptr_t framebufferVaddr = (uintptr_t)m->framebuffer->base;
-	// find a free slot
-	for (uint32_t i=0 ; i<numBuffers ; i++)
-	{
-		if ((bufferMask & (1LU<<i)) == 0)
-		{
-			m->bufferMask |= (1LU<<i);
-			break;
-		}
-		framebufferVaddr += framebufferSize;
-	}
-
-	// The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
-	private_handle_t* hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size,
-			(void*)framebufferVaddr, 0, m->framebuffer->shallow_fbdev_fd,
-			(framebufferVaddr - (uintptr_t)m->framebuffer->base));
-
-	/*
-	 * Perform allocator specific actions. If these fail we fall back to a regular buffer
-	 * which will be memcpy'ed to the main screen when fb_post is called.
-	 */
-	if (alloc_backend_alloc_framebuffer(m, hnd) == -1)
-	{
-		delete hnd;
-		int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
-		AERR( "Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd );
-		*byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
-		return alloc_backend_alloc(dev, alignedFramebufferSize, newUsage, pHandle, 0, 0, 0);
-	}
-
-	*pHandle = hnd;
-	*byte_stride = m->finfo.line_length;
-
-	return 0;
-}
-
-static int gralloc_alloc_framebuffer(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, int* stride, int* byte_stride)
-{
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
-	pthread_mutex_lock(&m->lock);
-	int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle, stride, byte_stride);
-	pthread_mutex_unlock(&m->lock);
-	return err;
-}
-
 /*
  * Type of allocation
  */
@@ -166,6 +76,18 @@
 	AFBC_TILED_HEADERS_WIDEBLK,
 };
 
+static int mali_gralloc_buffer_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds);
+
+/*
+ * Get a global unique ID
+ */
+static uint64_t getUniqueId()
+{
+	static std::atomic<uint32_t> counter(0);
+	uint64_t id = static_cast<uint64_t>(getpid()) << 32;
+	return id | counter++;
+}
+
 /*
  * Computes the strides and size for an RGB buffer
  *
@@ -178,8 +100,8 @@
  * size         (out)  size of the buffer in bytes
  * type         (in)   if buffer should be allocated for afbc
  */
-static void get_rgb_stride_and_size(int width, int height, int pixel_size,
-                                    int* pixel_stride, int* byte_stride, size_t* size, AllocType type)
+static void get_rgb_stride_and_size(int width, int height, int pixel_size, int *pixel_stride, int *byte_stride,
+                                    size_t *size, AllocType type)
 {
 	int stride;
 
@@ -191,7 +113,7 @@
 
 	if (size != NULL)
 	{
-		*size = stride * height;
+		*size = stride *height;
 	}
 
 	if (byte_stride != NULL)
@@ -207,42 +129,55 @@
 	if (type != UNCOMPRESSED)
 	{
 		int w_aligned;
-		int h_aligned = GRALLOC_ALIGN( height, AFBC_NORMAL_HEIGHT_ALIGN );
+		int h_aligned = GRALLOC_ALIGN(height, AFBC_NORMAL_HEIGHT_ALIGN);
 		int nblocks;
 		int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
 
 		if (type == AFBC_TILED_HEADERS_BASIC)
 		{
-			w_aligned = GRALLOC_ALIGN( width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN );
-			h_aligned = GRALLOC_ALIGN( height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN );
+			w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN);
+			h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN);
 			buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
 		}
 		else if (type == AFBC_TILED_HEADERS_WIDEBLK)
 		{
-			w_aligned = GRALLOC_ALIGN( width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN );
-			h_aligned = GRALLOC_ALIGN( height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN );
+			w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN);
+			h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN);
 			buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
 		}
 		else if (type == AFBC_PADDED)
 		{
-			w_aligned = GRALLOC_ALIGN( width, 64 );
+			w_aligned = GRALLOC_ALIGN(width, 64);
 		}
 		else if (type == AFBC_WIDEBLK)
 		{
-			w_aligned = GRALLOC_ALIGN( width, AFBC_WIDEBLK_WIDTH_ALIGN );
-			h_aligned = GRALLOC_ALIGN( height, AFBC_WIDEBLK_HEIGHT_ALIGN );
+			w_aligned = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN);
+			h_aligned = GRALLOC_ALIGN(height, AFBC_WIDEBLK_HEIGHT_ALIGN);
 		}
 		else
 		{
-			w_aligned = GRALLOC_ALIGN( width, AFBC_NORMAL_WIDTH_ALIGN );
+			w_aligned = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN);
+		}
+
+		stride = w_aligned * pixel_size;
+		stride = GRALLOC_ALIGN(stride, 64);
+
+		if (byte_stride != NULL)
+		{
+			*byte_stride = stride;
+		}
+
+		if (pixel_stride != NULL)
+		{
+			*pixel_stride = stride / pixel_size;
 		}
 
 		nblocks = w_aligned / AFBC_PIXELS_PER_BLOCK * h_aligned / AFBC_PIXELS_PER_BLOCK;
 
-		if ( size != NULL )
+		if (size != NULL)
 		{
-			*size = w_aligned * h_aligned * pixel_size +
-					GRALLOC_ALIGN( nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment );
+			*size = stride *h_aligned +
+			        GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
 		}
 	}
 }
@@ -259,8 +194,8 @@
  * type                 if buffer should be allocated for a certain afbc type
  * internalHeight (out) The internal height, which may be greater than the public known height.
  */
-static bool get_afbc_yuv420_8bit_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride,
-                                                 size_t* size, AllocType type, int *internalHeight)
+static bool get_afbc_yuv420_8bit_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride,
+                                                 size_t *size, AllocType type, int *internalHeight)
 {
 	int yuv420_afbc_luma_stride, yuv420_afbc_chroma_stride;
 	int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
@@ -288,14 +223,14 @@
 	}
 	else if (type == AFBC_TILED_HEADERS_BASIC)
 	{
-		width = GRALLOC_ALIGN( width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN );
-		height = GRALLOC_ALIGN( *internalHeight, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN );
+		width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN);
+		height = GRALLOC_ALIGN(*internalHeight, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN);
 		buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
 	}
 	else if (type == AFBC_TILED_HEADERS_WIDEBLK)
 	{
-		width = GRALLOC_ALIGN( width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN );
-		height = GRALLOC_ALIGN( *internalHeight, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN );
+		width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN);
+		height = GRALLOC_ALIGN(*internalHeight, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN);
 		buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
 	}
 	else if (type == AFBC_PADDED)
@@ -306,12 +241,12 @@
 	else if (type == AFBC_WIDEBLK)
 	{
 		width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN);
-		height = GRALLOC_ALIGN( *internalHeight, AFBC_WIDEBLK_HEIGHT_ALIGN );
+		height = GRALLOC_ALIGN(*internalHeight, AFBC_WIDEBLK_HEIGHT_ALIGN);
 	}
 	else
 	{
 		width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN);
-		height = GRALLOC_ALIGN( *internalHeight, AFBC_NORMAL_HEIGHT_ALIGN );
+		height = GRALLOC_ALIGN(*internalHeight, AFBC_NORMAL_HEIGHT_ALIGN);
 	}
 
 	yuv420_afbc_luma_stride = width;
@@ -321,9 +256,8 @@
 	{
 		int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK;
 		/* Simplification of (height * luma-stride + 2 * (height /2 * chroma_stride) */
-		*size =
-		    ( yuv420_afbc_luma_stride + yuv420_afbc_chroma_stride ) * height +
-		    GRALLOC_ALIGN( nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment );
+		*size = (yuv420_afbc_luma_stride + yuv420_afbc_chroma_stride) * height +
+		        GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
 	}
 
 	if (byte_stride != NULL)
@@ -352,14 +286,15 @@
  * internalHeight   (out) The internal height, which may be greater than the public known height.
  * stride_alignment (in)  stride aligment value in bytes.
  */
-static bool get_yv12_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size,
-                                     AllocType type, int* internalHeight, int stride_alignment)
+static bool get_yv12_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size,
+                                     AllocType type, int *internalHeight, int stride_alignment)
 {
 	int luma_stride;
 
 	if (type != UNCOMPRESSED)
 	{
-		return get_afbc_yuv420_8bit_stride_and_size(width, height, pixel_stride, byte_stride, size, type, internalHeight);
+		return get_afbc_yuv420_8bit_stride_and_size(width, height, pixel_stride, byte_stride, size, type,
+		                                            internalHeight);
 	}
 
 	/* 4:2:0 formats must have buffers with even height and width as the clump size is 2x2 pixels.
@@ -372,7 +307,7 @@
 	{
 		int chroma_stride = GRALLOC_ALIGN(luma_stride / 2, stride_alignment);
 		/* Simplification of ((height * luma_stride ) + 2 * ((height / 2) * chroma_stride)). */
-		*size = height * (luma_stride + chroma_stride);
+		*size = height *(luma_stride + chroma_stride);
 	}
 
 	if (byte_stride != NULL)
@@ -387,6 +322,7 @@
 
 	return true;
 }
+
 /*
  * Computes the strides and size for an 8 bit YUYV 422 buffer
  *
@@ -397,7 +333,7 @@
  * byte_stride      (out) stride of the buffer in bytes
  * size             (out) size of the buffer in bytes
  */
-static bool get_yuv422_8bit_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size)
+static bool get_yuv422_8bit_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size)
 {
 	int local_byte_stride, local_pixel_stride;
 
@@ -405,11 +341,11 @@
 	 * This is taken care of by the even stride alignment. */
 
 	local_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
-	local_byte_stride  = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN); /* 4 bytes per 2 pixels */
+	local_byte_stride = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN); /* 4 bytes per 2 pixels */
 
 	if (size != NULL)
 	{
-		*size = local_byte_stride * height;
+		*size = local_byte_stride *height;
 	}
 
 	if (byte_stride != NULL)
@@ -436,7 +372,8 @@
  * size         (out)  size of the buffer in bytes
  * type                if buffer should be allocated for a certain afbc type
  */
-static bool get_afbc_yuv422_8bit_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size, AllocType type)
+static bool get_afbc_yuv422_8bit_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride,
+                                                 size_t *size, AllocType type)
 {
 	int yuv422_afbc_luma_stride;
 	int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
@@ -480,8 +417,8 @@
 	{
 		int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK;
 		/* YUV 4:2:2 luma size equals chroma size */
-		*size = yuv422_afbc_luma_stride * height * 2
-			+ GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
+		*size = yuv422_afbc_luma_stride *height * 2 +
+		        GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
 	}
 
 	if (byte_stride != NULL)
@@ -514,7 +451,8 @@
  * @return true if the calculation was successful; false otherwise (invalid
  * parameter)
  */
-static bool get_yuv_pX10_stride_and_size(int width, int height, int vss, int* pixel_stride, int* byte_stride, size_t* size)
+static bool get_yuv_pX10_stride_and_size(int width, int height, int vss, int *pixel_stride, int *byte_stride,
+                                         size_t *size)
 {
 	int luma_pixel_stride, luma_byte_stride;
 
@@ -533,12 +471,12 @@
 	}
 
 	luma_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
-	luma_byte_stride  = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN);
+	luma_byte_stride = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN);
 
 	if (size != NULL)
 	{
 		int chroma_size = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN) * (height / vss);
-		*size = luma_byte_stride * height + chroma_size;
+		*size = luma_byte_stride *height + chroma_size;
 	}
 
 	if (byte_stride != NULL)
@@ -569,7 +507,7 @@
  * @return true if the calculation was successful; false otherwise (invalid
  * parameter)
  */
-static bool get_yuv_y210_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size)
+static bool get_yuv_y210_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size)
 {
 	int y210_byte_stride, y210_pixel_stride;
 
@@ -578,11 +516,11 @@
 
 	y210_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
 	/* 4x16 bits per 2 pixels */
-	y210_byte_stride  = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN);
+	y210_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN);
 
 	if (size != NULL)
 	{
-		*size = y210_byte_stride * height;
+		*size = y210_byte_stride *height;
 	}
 
 	if (byte_stride != NULL)
@@ -616,7 +554,7 @@
  * @note Each YUYAAYVYAA clump encodes a 2x2 area of pixels. YU&V are 10 bits. A is 1 bit. total 8 bytes
  *
  */
-static bool get_yuv_y0l2_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size)
+static bool get_yuv_y0l2_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size)
 {
 	int y0l2_byte_stride, y0l2_pixel_stride;
 
@@ -625,11 +563,11 @@
 	height = GRALLOC_ALIGN(height, 2);
 
 	y0l2_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
-	y0l2_byte_stride  = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN); /* 2 horiz pixels per 8 byte clump */
+	y0l2_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN); /* 2 horiz pixels per 8 byte clump */
 
 	if (size != NULL)
 	{
-		*size = y0l2_byte_stride * height / 2; /* byte stride covers 2 vert pixels */
+		*size = y0l2_byte_stride *height / 2; /* byte stride covers 2 vert pixels */
 	}
 
 	if (byte_stride != NULL)
@@ -641,8 +579,10 @@
 	{
 		*pixel_stride = y0l2_pixel_stride;
 	}
+
 	return true;
 }
+
 /*
  *  Calculate strides and strides for Y410 (AVYU packed, 4:4:4) format buffer.
  *
@@ -658,17 +598,17 @@
  * @return true if the calculation was successful; false otherwise (invalid
  * parameter)
  */
-static bool get_yuv_y410_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size)
+static bool get_yuv_y410_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size)
 {
 	int y410_byte_stride, y410_pixel_stride;
 
 	y410_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
-	y410_byte_stride  = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN);
+	y410_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN);
 
 	if (size != NULL)
 	{
 		/* 4x8bits per pixel */
-		*size = y410_byte_stride * height;
+		*size = y410_byte_stride *height;
 	}
 
 	if (byte_stride != NULL)
@@ -680,6 +620,7 @@
 	{
 		*pixel_stride = y410_pixel_stride;
 	}
+
 	return true;
 }
 
@@ -701,7 +642,8 @@
  * @return true if the calculation was successful; false otherwise (invalid
  * parameter)
  */
-static bool get_yuv420_10bit_afbc_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size, AllocType type, int* internalHeight)
+static bool get_yuv420_10bit_afbc_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride,
+                                                  size_t *size, AllocType type, int *internalHeight)
 {
 	int yuv420_afbc_byte_stride, yuv420_afbc_pixel_stride;
 	int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
@@ -711,12 +653,13 @@
 		return false;
 	}
 
-        *internalHeight = height;
+	*internalHeight = height;
 #if MALI_VIDEO_VERSION
 	/* If we have a greater internal height than public we set the internalHeight. This
 	 * implies that cropping will be applied of internal dimensions to fit the public one. */
-        *internalHeight += AFBC_PIXELS_PER_BLOCK;
+	*internalHeight += AFBC_PIXELS_PER_BLOCK;
 #endif
+
 	/* The actual height used in size calculation must include the possible extra row. But
 	 * it must also be AFBC-aligned. Only the extra row-padding should be reported back in
 	 * internalHeight. This as only this row needs to be considered when cropping. */
@@ -728,13 +671,13 @@
 	else if (type == AFBC_TILED_HEADERS_BASIC)
 	{
 		width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN);
-		height = GRALLOC_ALIGN(*internalHeight/2, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN);
+		height = GRALLOC_ALIGN(*internalHeight / 2, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN);
 		buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
 	}
 	else if (type == AFBC_TILED_HEADERS_WIDEBLK)
 	{
 		width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN);
-		height = GRALLOC_ALIGN(*internalHeight/2, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN);
+		height = GRALLOC_ALIGN(*internalHeight / 2, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN);
 		buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
 	}
 	else if (type == AFBC_PADDED)
@@ -745,22 +688,22 @@
 	else if (type == AFBC_WIDEBLK)
 	{
 		width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN);
-		height = GRALLOC_ALIGN(*internalHeight/2, AFBC_WIDEBLK_HEIGHT_ALIGN);
+		height = GRALLOC_ALIGN(*internalHeight / 2, AFBC_WIDEBLK_HEIGHT_ALIGN);
 	}
 	else
 	{
 		width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN);
-		height = GRALLOC_ALIGN(*internalHeight/2, AFBC_NORMAL_HEIGHT_ALIGN);
+		height = GRALLOC_ALIGN(*internalHeight / 2, AFBC_NORMAL_HEIGHT_ALIGN);
 	}
 
 	yuv420_afbc_pixel_stride = GRALLOC_ALIGN(width, 16);
-	yuv420_afbc_byte_stride  = GRALLOC_ALIGN(width * 4, 16); /* 64-bit packed and horizontally downsampled */
+	yuv420_afbc_byte_stride = GRALLOC_ALIGN(width * 4, 16); /* 64-bit packed and horizontally downsampled */
 
 	if (size != NULL)
 	{
 		int nblocks = width / AFBC_PIXELS_PER_BLOCK * (*internalHeight) / AFBC_PIXELS_PER_BLOCK;
-		*size = yuv420_afbc_byte_stride * height
-			+ GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
+		*size = yuv420_afbc_byte_stride *height +
+		        GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
 	}
 
 	if (byte_stride != NULL)
@@ -792,7 +735,8 @@
  * @return true if the calculation was successful; false otherwise (invalid
  * parameter)
  */
-static bool get_yuv422_10bit_afbc_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size, AllocType type)
+static bool get_yuv422_10bit_afbc_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride,
+                                                  size_t *size, AllocType type)
 {
 	int yuv422_afbc_byte_stride, yuv422_afbc_pixel_stride;
 	int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
@@ -836,14 +780,14 @@
 	}
 
 	yuv422_afbc_pixel_stride = GRALLOC_ALIGN(width, 16);
-	yuv422_afbc_byte_stride  = GRALLOC_ALIGN(width * 2, 16);
+	yuv422_afbc_byte_stride = GRALLOC_ALIGN(width * 2, 16);
 
 	if (size != NULL)
 	{
 		int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK;
 		/* YUV 4:2:2 chroma size equals to luma size */
-		*size = yuv422_afbc_byte_stride * height * 2
-			+ GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
+		*size = yuv422_afbc_byte_stride *height * 2 +
+		        GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
 	}
 
 	if (byte_stride != NULL)
@@ -880,45 +824,47 @@
 
 	switch (format)
 	{
-		case HAL_PIXEL_FORMAT_RAW16:
-			stride = w; /* Format assumes stride in pixels */
-			stride = GRALLOC_ALIGN(stride, 16); /* Alignment mandated by Android */
-			size = stride * h * 2; /* 2 bytes per pixel */
-			break;
+	case HAL_PIXEL_FORMAT_RAW16:
+		stride = w; /* Format assumes stride in pixels */
+		stride = GRALLOC_ALIGN(stride, 16); /* Alignment mandated by Android */
+		size = stride * h * 2; /* 2 bytes per pixel */
+		break;
 
-		case HAL_PIXEL_FORMAT_RAW12:
-			if (w % 4 != 0)
-			{
-				ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW12 buffers has to be multiple of 4.");
-				return false;
-			}
-			stride = (w / 2) * 3; /* Stride in bytes; 2 pixels in 3 bytes */
-			size = stride * h;
-			break;
-
-		case HAL_PIXEL_FORMAT_RAW10:
-			if (w % 4 != 0)
-			{
-				ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW10 buffers has to be multiple of 4.");
-				return false;
-			}
-			stride = (w / 4) * 5; /* Stride in bytes; 4 pixels in 5 bytes */
-			size = stride * h;
-			break;
-
-		case HAL_PIXEL_FORMAT_BLOB:
-			if (h != 1)
-			{
-				ALOGE("ERROR: Height for HAL_PIXEL_FORMAT_BLOB must be 1.");
-				return false;
-			}
-			stride = 0; /* No 'rows', it's effectively a long one dimensional array */
-			size = w;
-			break;
-
-		default:
+	case HAL_PIXEL_FORMAT_RAW12:
+		if (w % 4 != 0)
+		{
+			ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW12 buffers has to be multiple of 4.");
 			return false;
+		}
 
+		stride = (w / 2) * 3; /* Stride in bytes; 2 pixels in 3 bytes */
+		size = stride * h;
+		break;
+
+	case HAL_PIXEL_FORMAT_RAW10:
+		if (w % 4 != 0)
+		{
+			ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW10 buffers has to be multiple of 4.");
+			return false;
+		}
+
+		stride = (w / 4) * 5; /* Stride in bytes; 4 pixels in 5 bytes */
+		size = stride * h;
+		break;
+
+	case HAL_PIXEL_FORMAT_BLOB:
+		if (h != 1)
+		{
+			ALOGE("ERROR: Height for HAL_PIXEL_FORMAT_BLOB must be 1.");
+			return false;
+		}
+
+		stride = 0; /* No 'rows', it's effectively a long one dimensional array */
+		size = w;
+		break;
+
+	default:
+		return false;
 	}
 
 	if (out_size != NULL)
@@ -934,91 +880,89 @@
 	return true;
 }
 
-static int alloc_device_alloc(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride)
+int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors,
+                                 uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend)
 {
+	bool shared = false;
+	uint64_t backing_store_id = 0x0;
+	AllocType alloc_type = UNCOMPRESSED;
+	uint64_t usage;
+	uint32_t i = 0;
+	int err;
 
-	if (!pHandle || !pStride)
+	for (i = 0; i < numDescriptors; i++)
 	{
-		return -EINVAL;
-	}
+		buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
 
-	size_t size;       // Size to be allocated for the buffer
-	int byte_stride;   // Stride of the buffer in bytes
-	int pixel_stride;  // Stride of the buffer in pixels - as returned in pStride
-	uint64_t internal_format;
-	AllocType type = UNCOMPRESSED;
-	int internalWidth,internalHeight;
+		/* Some formats require an internal width and height that may be used by
+		 * consumers/producers.
+		 */
+		bufDescriptor->internalWidth = bufDescriptor->width;
+		bufDescriptor->internalHeight = bufDescriptor->height;
+		usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
 
-#if GRALLOC_FB_SWAP_RED_BLUE == 1
-	/* match the framebuffer format */
-	if (usage & GRALLOC_USAGE_HW_FB)
-	{
-#ifdef GRALLOC_16_BITS
-		format = HAL_PIXEL_FORMAT_RGB_565;
-#else
-		format = HAL_PIXEL_FORMAT_BGRA_8888;
-#endif
-	}
-#endif
+		bufDescriptor->internal_format = mali_gralloc_select_format(
+		    bufDescriptor->hal_format, bufDescriptor->format_type, usage, bufDescriptor->width * bufDescriptor->height);
 
-	/* Some formats require an internal width and height that may be used by
-	 * consumers/producers.
-	 */
-	internalWidth = w;
-	internalHeight = h;
-
-	internal_format = mali_gralloc_select_format(format, usage, w*h);
-	if(internal_format == 0)
-	{
-		ALOGE("Unrecognized and/or unsupported format(0x%08X) and usage(0x%08X).",format,usage);
-		return -EINVAL;
-	}
-
-	if (internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
-	{
-		if (internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
+		if (bufDescriptor->internal_format == 0)
 		{
-			if (internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
+			ALOGE("Unrecognized and/or unsupported format 0x%" PRIx64 " and usage 0x%" PRIx64,
+			      bufDescriptor->hal_format, usage);
+			return -EINVAL;
+		}
+
+		/* Determine AFBC type for this format */
+		if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
+		{
+			if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
 			{
-				type = AFBC_TILED_HEADERS_WIDEBLK;
+				if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
+				{
+					alloc_type = AFBC_TILED_HEADERS_WIDEBLK;
+				}
+				else if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
+				{
+					alloc_type = AFBC_TILED_HEADERS_BASIC;
+				}
+				else if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK)
+				{
+					ALOGE("Unsupported format. Splitblk in tiled header configuration.");
+					return -EINVAL;
+				}
 			}
-			else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
+			else if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING)
 			{
-				type = AFBC_TILED_HEADERS_BASIC;
+				alloc_type = AFBC_PADDED;
 			}
-			else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK)
+			else if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
 			{
-				ALOGE("Unsupported format. Splitblk in tiled header configuration.");
-				return -EINVAL;
+				alloc_type = AFBC_WIDEBLK;
+			}
+			else
+			{
+				alloc_type = AFBC;
 			}
 		}
-		else if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING)
-		{
-			type = AFBC_PADDED;
-		}
-		else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
-		{
-			type = AFBC_WIDEBLK;
-		}
-		else
-		{
-			type = AFBC;
-		}
-	}
 
-	uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
-	switch (base_format)
-	{
+		uint64_t base_format = bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+
+		switch (base_format)
+		{
 		case HAL_PIXEL_FORMAT_RGBA_8888:
 		case HAL_PIXEL_FORMAT_RGBX_8888:
 		case HAL_PIXEL_FORMAT_BGRA_8888:
-			get_rgb_stride_and_size(w, h, 4, &pixel_stride, &byte_stride, &size, type );
+			get_rgb_stride_and_size(bufDescriptor->width, bufDescriptor->height, 4, &bufDescriptor->pixel_stride,
+			                        &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type);
 			break;
+
 		case HAL_PIXEL_FORMAT_RGB_888:
-			get_rgb_stride_and_size(w, h, 3, &pixel_stride, &byte_stride, &size, type );
+			get_rgb_stride_and_size(bufDescriptor->width, bufDescriptor->height, 3, &bufDescriptor->pixel_stride,
+			                        &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type);
 			break;
+
 		case HAL_PIXEL_FORMAT_RGB_565:
-			get_rgb_stride_and_size(w, h, 2, &pixel_stride, &byte_stride, &size, type );
+			get_rgb_stride_and_size(bufDescriptor->width, bufDescriptor->height, 2, &bufDescriptor->pixel_stride,
+			                        &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type);
 			break;
 
 		case HAL_PIXEL_FORMAT_YCrCb_420_SP:
@@ -1030,249 +974,266 @@
 			 * default of 16. We only need to care about YV12 as it's the only, implicit, HAL YUV format in Android.
 			 */
 			int yv12_align = YUV_MALI_PLANE_ALIGN;
-			if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
+
+			if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
 			{
 				yv12_align = YUV_ANDROID_PLANE_ALIGN;
 			}
 
-			if (!get_yv12_stride_and_size(w, h, &pixel_stride, &byte_stride, &size, type,
-										  &internalHeight, yv12_align))
+			if (!get_yv12_stride_and_size(bufDescriptor->width, bufDescriptor->height, &bufDescriptor->pixel_stride,
+			                              &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type,
+			                              &bufDescriptor->internalHeight, yv12_align))
 			{
 				return -EINVAL;
 			}
+
 			break;
 		}
+
 		case HAL_PIXEL_FORMAT_YCbCr_422_I:
 		{
 			/* YUYV 4:2:2 */
-			if (type != UNCOMPRESSED || !get_yuv422_8bit_stride_and_size(w, h, &pixel_stride, &byte_stride, &size))
+			if (alloc_type != UNCOMPRESSED ||
+			    !get_yuv422_8bit_stride_and_size(bufDescriptor->width, bufDescriptor->height,
+			                                     &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride,
+			                                     &bufDescriptor->size))
 			{
 				return -EINVAL;
 			}
+
 			break;
 		}
+
 		case HAL_PIXEL_FORMAT_RAW16:
 		case HAL_PIXEL_FORMAT_RAW12:
 		case HAL_PIXEL_FORMAT_RAW10:
 		case HAL_PIXEL_FORMAT_BLOB:
-			if (type != UNCOMPRESSED)
+			if (alloc_type != UNCOMPRESSED)
 			{
 				return -EINVAL;
 			}
-			get_camera_formats_stride_and_size(w, h, base_format, &pixel_stride, &size);
-			byte_stride = pixel_stride; /* For Raw/Blob formats stride is defined to be either in bytes or pixels per format */
+
+			get_camera_formats_stride_and_size(bufDescriptor->width, bufDescriptor->height, base_format,
+			                                   &bufDescriptor->pixel_stride, &bufDescriptor->size);
+			/* For Raw/Blob formats stride is defined to be either in bytes or pixels per format */
+			bufDescriptor->byte_stride = bufDescriptor->pixel_stride;
 			break;
 
 		case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2:
+
 			/* YUYAAYUVAA 4:2:0 with and without AFBC */
-			if (type != UNCOMPRESSED)
+			if (alloc_type != UNCOMPRESSED)
 			{
-				if (!get_yuv420_10bit_afbc_stride_and_size(w, h, &pixel_stride, &byte_stride, &size, type, &internalHeight))
+				if (!get_yuv420_10bit_afbc_stride_and_size(
+				        bufDescriptor->width, bufDescriptor->height, &bufDescriptor->pixel_stride,
+				        &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type, &bufDescriptor->internalHeight))
 				{
 					return -EINVAL;
 				}
 			}
 			else
 			{
-				if(!get_yuv_y0l2_stride_and_size(w, h, &pixel_stride, &byte_stride, &size))
+				if (!get_yuv_y0l2_stride_and_size(bufDescriptor->width, bufDescriptor->height,
+				                                  &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride,
+				                                  &bufDescriptor->size))
 				{
 					return -EINVAL;
 				}
 			}
+
 			break;
 
 		case MALI_GRALLOC_FORMAT_INTERNAL_P010:
+
 			/* Y-UV 4:2:0 */
-			if (type != UNCOMPRESSED || !get_yuv_pX10_stride_and_size(w, h, 2, &pixel_stride, &byte_stride, &size))
+			if (alloc_type != UNCOMPRESSED ||
+			    !get_yuv_pX10_stride_and_size(bufDescriptor->width, bufDescriptor->height, 2,
+			                                  &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride,
+			                                  &bufDescriptor->size))
 			{
 				return -EINVAL;
 			}
+
 			break;
 
 		case MALI_GRALLOC_FORMAT_INTERNAL_P210:
+
 			/* Y-UV 4:2:2 */
-			if (type != UNCOMPRESSED || !get_yuv_pX10_stride_and_size(w, h, 1, &pixel_stride, &byte_stride, &size))
+			if (alloc_type != UNCOMPRESSED ||
+			    !get_yuv_pX10_stride_and_size(bufDescriptor->width, bufDescriptor->height, 1,
+			                                  &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride,
+			                                  &bufDescriptor->size))
 			{
 				return -EINVAL;
 			}
+
 			break;
 
 		case MALI_GRALLOC_FORMAT_INTERNAL_Y210:
+
 			/* YUYV 4:2:2 with and without AFBC */
-			if (type != UNCOMPRESSED)
+			if (alloc_type != UNCOMPRESSED)
 			{
-				if (!get_yuv422_10bit_afbc_stride_and_size(w, h, &pixel_stride, &byte_stride, &size, type))
+				if (!get_yuv422_10bit_afbc_stride_and_size(bufDescriptor->width, bufDescriptor->height,
+				                                           &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride,
+				                                           &bufDescriptor->size, alloc_type))
 				{
 					return -EINVAL;
 				}
 			}
 			else
 			{
-				if(!get_yuv_y210_stride_and_size(w, h, &pixel_stride, &byte_stride, &size))
+				if (!get_yuv_y210_stride_and_size(bufDescriptor->width, bufDescriptor->height,
+				                                  &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride,
+				                                  &bufDescriptor->size))
 				{
 					return -EINVAL;
 				}
 			}
+
 			break;
 
 		case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
+
 			/* AVYU 2-10-10-10 */
-			if (type != UNCOMPRESSED || !get_yuv_y410_stride_and_size(w, h, &pixel_stride, &byte_stride, &size))
+			if (alloc_type != UNCOMPRESSED ||
+			    !get_yuv_y410_stride_and_size(bufDescriptor->width, bufDescriptor->height, &bufDescriptor->pixel_stride,
+			                                  &bufDescriptor->byte_stride, &bufDescriptor->size))
 			{
 				return -EINVAL;
 			}
+
 			break;
 
 		case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT:
+
 			/* 8BIT AFBC YUV4:2:2 testing usage */
 
-			 /* We only support compressed for this format right now.
-			  * Below will fail in case format is uncompressed.
-			  */
-			if (!get_afbc_yuv422_8bit_stride_and_size(w, h, &pixel_stride, &byte_stride, &size, type))
+			/* We only support compressed for this format right now.
+			 * Below will fail in case format is uncompressed.
+			 */
+			if (!get_afbc_yuv422_8bit_stride_and_size(bufDescriptor->width, bufDescriptor->height,
+			                                          &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride,
+			                                          &bufDescriptor->size, alloc_type))
 			{
 				return -EINVAL;
 			}
+
 			break;
-			/*
-			 * Additional custom formats can be added here
-			 * and must fill the variables pixel_stride, byte_stride and size.
-			 */
+
+		/*
+		 * Additional custom formats can be added here
+		 * and must fill the variables pixel_stride, byte_stride and size.
+		 */
 		default:
 			return -EINVAL;
-	}
-
-	int err;
-#if DISABLE_FRAMEBUFFER_HAL != 1
-	if (usage & GRALLOC_USAGE_HW_FB)
-	{
-		err = gralloc_alloc_framebuffer(dev, size, usage, pHandle, &pixel_stride, &byte_stride);
-	}
-	else
-#endif
-	{
-		err = alloc_backend_alloc(dev, size, usage, pHandle, internal_format, w, h);
-	}
-
-	if (err < 0)
-	{
-		return err;
-	}
-
-	private_handle_t *hnd = (private_handle_t *)*pHandle;
-
-	err = gralloc_buffer_attr_allocate( hnd );
-	if( err < 0 )
-	{
-		private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
-
-		if ( (usage & GRALLOC_USAGE_HW_FB) )
-		{
-			/*
-			 * Having the attribute region is not critical for the framebuffer so let it pass.
-			 */
-			err = 0;
 		}
-		else
+	}
+
+	{
+		/* Allocate ION backing store memory */
+		err = mali_gralloc_ion_allocate(m, descriptors, numDescriptors, pHandle, &shared);
+
+		if (err < 0)
 		{
-			alloc_backend_alloc_free( hnd, m );
 			return err;
 		}
 	}
 
-	hnd->req_format = format;
-	hnd->byte_stride = byte_stride;
-	hnd->internal_format = internal_format;
-
-	int private_usage = usage & MALI_GRALLOC_USAGE_YUV_CONF_MASK;
-
-	switch (private_usage)
+	if (shared)
 	{
+		backing_store_id = getUniqueId();
+	}
+
+	for (i = 0; i < numDescriptors; i++)
+	{
+		buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)descriptors[i];
+		private_handle_t *hnd = (private_handle_t *)pHandle[i];
+
+		usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
+
+		err = gralloc_buffer_attr_allocate(hnd);
+
+		if (err < 0)
+		{
+			/* free all allocated ion buffer& attr buffer here.*/
+			mali_gralloc_buffer_free_internal(pHandle, numDescriptors);
+			return err;
+		}
+
+		mali_gralloc_dump_buffer_add(hnd);
+
+		switch (usage & MALI_GRALLOC_USAGE_YUV_CONF_MASK)
+		{
 		case MALI_GRALLOC_USAGE_YUV_CONF_0:
 			hnd->yuv_info = MALI_YUV_BT601_NARROW;
 			break;
+
 		case MALI_GRALLOC_USAGE_YUV_CONF_1:
 			hnd->yuv_info = MALI_YUV_BT601_WIDE;
 			break;
+
 		case MALI_GRALLOC_USAGE_YUV_CONF_2:
 			hnd->yuv_info = MALI_YUV_BT709_NARROW;
 			break;
+
 		case MALI_GRALLOC_USAGE_YUV_CONF_3:
 			hnd->yuv_info = MALI_YUV_BT709_WIDE;
 			break;
+		}
+
+		/* Workaround 10bit YUV only support BT709_WIDE in GPU DDK */
+		if ((bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK) == MALI_GRALLOC_FORMAT_INTERNAL_Y0L2)
+		{
+			hnd->yuv_info = MALI_YUV_BT709_WIDE;
+		}
+
+		if (shared)
+		{
+			/*each buffer will share the same backing store id.*/
+			hnd->backing_store_id = backing_store_id;
+		}
+		else
+		{
+			/* each buffer will have an unique backing store id.*/
+			hnd->backing_store_id = getUniqueId();
+		}
 	}
 
-	/* Workaround 10bit YUV only support BT709_WIDE in GPU DDK */
-	if ((hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK) == MALI_GRALLOC_FORMAT_INTERNAL_Y0L2)
+	if (NULL != shared_backend)
 	{
-		hnd->yuv_info = MALI_YUV_BT709_WIDE;
+		*shared_backend = shared;
 	}
-	hnd->width = w;
-	hnd->height = h;
-	hnd->stride = pixel_stride;
-	hnd->internalWidth = internalWidth;
-	hnd->internalHeight = internalHeight;
-
-	*pStride = pixel_stride;
-	return 0;
-}
-
-static int alloc_device_free(alloc_device_t* dev, buffer_handle_t handle)
-{
-	if (private_handle_t::validate(handle) < 0)
-	{
-		return -EINVAL;
-	}
-
-	private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
-	private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
-
-	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
-	{
-		// free this buffer
-		private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
-		const size_t bufferSize = m->finfo.line_length * m->info.yres;
-		int index = ((uintptr_t)hnd->base - (uintptr_t)m->framebuffer->base) / bufferSize;
-		m->bufferMask &= ~(1 << index);
-	}
-
-	gralloc_buffer_attr_free( (private_handle_t *) hnd );
-	alloc_backend_alloc_free(hnd, m);
-
-	delete hnd;
 
 	return 0;
 }
 
-int alloc_device_open(hw_module_t const* module, const char* name, hw_device_t** device)
+int mali_gralloc_buffer_free(buffer_handle_t pHandle)
 {
-	alloc_device_t *dev;
+	int rval = -1;
+	private_handle_t *hnd = (private_handle_t *)(pHandle);
 
-	GRALLOC_UNUSED(name);
-
-	dev = new alloc_device_t;
-	if (NULL == dev)
+	if (hnd != NULL)
 	{
-		return -1;
+		rval = gralloc_buffer_attr_free(hnd);
+		mali_gralloc_ion_free(hnd);
 	}
 
-	/* initialize our state here */
-	memset(dev, 0, sizeof(*dev));
+	return rval;
+}
 
-	/* initialize the procs */
-	dev->common.tag = HARDWARE_DEVICE_TAG;
-	dev->common.version = 0;
-	dev->common.module = const_cast<hw_module_t*>(module);
-	dev->common.close = alloc_backend_close;
-	dev->alloc = alloc_device_alloc;
-	dev->free = alloc_device_free;
+static int mali_gralloc_buffer_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds)
+{
+	int err = -1;
+	uint32_t i = 0;
 
-	if (0 != alloc_backend_open(dev)) {
-		delete dev;
-		return -1;
+	for (i = 0; i < num_hnds; i++)
+	{
+		private_handle_t *hnd = (private_handle_t *)(pHandle[i]);
+
+		err = gralloc_buffer_attr_free(hnd);
+		mali_gralloc_ion_free(hnd);
 	}
 
-	*device = &dev->common;
-
-	return 0;
+	return err;
 }
diff --git a/gralloc960/mali_gralloc_bufferallocation.h b/gralloc960/mali_gralloc_bufferallocation.h
new file mode 100644
index 0000000..5148252
--- /dev/null
+++ b/gralloc960/mali_gralloc_bufferallocation.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MALI_GRALLOC_BUFFERALLOCATION_H_
+#define MALI_GRALLOC_BUFFERALLOCATION_H_
+
+#include <hardware/hardware.h>
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+#include "mali_gralloc_bufferdescriptor.h"
+
+int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors,
+                                 uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend);
+int mali_gralloc_buffer_free(buffer_handle_t pHandle);
+
+#endif /* MALI_GRALLOC_BUFFERALLOCATION_H_ */
diff --git a/gralloc960/mali_gralloc_bufferdescriptor.cpp b/gralloc960/mali_gralloc_bufferdescriptor.cpp
new file mode 100644
index 0000000..11e3cb3
--- /dev/null
+++ b/gralloc960/mali_gralloc_bufferdescriptor.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hardware/hardware.h>
+#include <stdlib.h>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_bufferdescriptor.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+int mali_gralloc_create_descriptor_internal(gralloc1_buffer_descriptor_t *outDescriptor)
+{
+	buffer_descriptor_t *buffer_descriptor;
+
+	if (NULL == outDescriptor)
+	{
+		return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+	}
+
+	buffer_descriptor = reinterpret_cast<buffer_descriptor_t *>(malloc(sizeof(buffer_descriptor_t)));
+
+	if (NULL == buffer_descriptor)
+	{
+		AERR("failed to create buffer descriptor");
+		return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+	}
+
+	*outDescriptor = (gralloc1_buffer_descriptor_t)buffer_descriptor;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_destroy_descriptor_internal(gralloc1_buffer_descriptor_t descriptor)
+{
+	if (!descriptor)
+	{
+		return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+	}
+
+	buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor;
+	free(buffer_descriptor);
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_set_dimensions_internal(gralloc1_buffer_descriptor_t descriptor, uint32_t width, uint32_t height)
+{
+	if (!descriptor)
+	{
+		return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+	}
+
+	buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor;
+	buffer_descriptor->width = width;
+	buffer_descriptor->height = height;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_set_format_internal(gralloc1_buffer_descriptor_t descriptor, int32_t format)
+{
+	if (!descriptor)
+	{
+		return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+	}
+
+	buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor;
+	buffer_descriptor->hal_format = format;
+	buffer_descriptor->format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_set_producerusage_internal(gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
+{
+	if (!descriptor)
+	{
+		return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+	}
+
+	buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor;
+	buffer_descriptor->producer_usage = usage;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_set_consumerusage_internal(gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
+{
+	if (!descriptor)
+	{
+		return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+	}
+
+	buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor;
+	buffer_descriptor->consumer_usage = usage;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_get_backing_store_internal(buffer_handle_t buffer, gralloc1_backing_store_t *outStore)
+{
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Invalid buffer %p, returning error", buffer);
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+
+	*outStore = (gralloc1_backing_store_t)hnd->backing_store_id;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_get_consumer_usage_internal(buffer_handle_t buffer, uint64_t *outUsage)
+{
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Invalid buffer %p, returning error", buffer);
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+	*outUsage = hnd->consumer_usage;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_get_dimensions_internal(buffer_handle_t buffer, uint32_t *outWidth, uint32_t *outHeight)
+{
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Invalid buffer %p, returning error", buffer);
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+	*outWidth = hnd->width;
+	*outHeight = hnd->height;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_get_format_internal(buffer_handle_t buffer, int32_t *outFormat)
+{
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Invalid buffer %p, returning error", buffer);
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+	*outFormat = hnd->req_format;
+	return GRALLOC1_ERROR_NONE;
+}
+
+int mali_gralloc_get_producer_usage_internal(buffer_handle_t buffer, uint64_t *outUsage)
+{
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		AERR("Invalid buffer %p, returning error", buffer);
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)buffer;
+	*outUsage = hnd->producer_usage;
+	return GRALLOC1_ERROR_NONE;
+}
+
+#endif
+int mali_gralloc_query_getstride(buffer_handle_t buffer, int *pixelStride)
+{
+	int rval = -1;
+
+	if (buffer != NULL && pixelStride != NULL)
+	{
+		private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(buffer);
+
+		if (hnd)
+		{
+			*pixelStride = hnd->stride;
+			rval = 0;
+		}
+	}
+
+	return rval;
+}
diff --git a/gralloc960/mali_gralloc_bufferdescriptor.h b/gralloc960/mali_gralloc_bufferdescriptor.h
new file mode 100644
index 0000000..6783be0
--- /dev/null
+++ b/gralloc960/mali_gralloc_bufferdescriptor.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MALI_GRALLOC_BUFFERDESCRIPTOR_H_
+#define MALI_GRALLOC_BUFFERDESCRIPTOR_H_
+
+#include <hardware/hardware.h>
+#include "gralloc_priv.h"
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_formats.h"
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+typedef uint64_t gralloc_buffer_descriptor_t;
+
+typedef struct buffer_descriptor
+{
+	uint32_t width;
+	uint32_t height;
+	uint64_t producer_usage;
+	uint64_t consumer_usage;
+	uint64_t hal_format;
+
+	mali_gralloc_format_type format_type;
+	size_t size;
+	int byte_stride;
+	int pixel_stride;
+	int internalWidth;
+	int internalHeight;
+	uint64_t internal_format;
+} buffer_descriptor_t;
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+int mali_gralloc_create_descriptor_internal(gralloc1_buffer_descriptor_t *outDescriptor);
+int mali_gralloc_destroy_descriptor_internal(gralloc1_buffer_descriptor_t descriptor);
+int mali_gralloc_set_dimensions_internal(gralloc1_buffer_descriptor_t descriptor, uint32_t width, uint32_t height);
+int mali_gralloc_set_format_internal(gralloc1_buffer_descriptor_t descriptor, int32_t format);
+int mali_gralloc_set_producerusage_internal(gralloc1_buffer_descriptor_t descriptor, uint64_t usage);
+int mali_gralloc_set_consumerusage_internal(gralloc1_buffer_descriptor_t descriptor, uint64_t usage);
+
+int mali_gralloc_get_backing_store_internal(buffer_handle_t buffer, gralloc1_backing_store_t *outStore);
+int mali_gralloc_get_consumer_usage_internal(buffer_handle_t buffer, uint64_t *outUsage);
+int mali_gralloc_get_dimensions_internal(buffer_handle_t buffer, uint32_t *outWidth, uint32_t *outHeight);
+int mali_gralloc_get_format_internal(buffer_handle_t buffer, int32_t *outFormat);
+int mali_gralloc_get_producer_usage_internal(buffer_handle_t buffer, uint64_t *outUsage);
+#endif
+int mali_gralloc_query_getstride(buffer_handle_t handle, int *pixelStride);
+
+#endif /* MALI_GRALLOC_BUFFERDESCRIPTOR_H_ */
diff --git a/gralloc960/mali_gralloc_debug.cpp b/gralloc960/mali_gralloc_debug.cpp
new file mode 100644
index 0000000..d4473ed
--- /dev/null
+++ b/gralloc960/mali_gralloc_debug.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2016 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <vector>
+#include <algorithm>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+#include <hardware/hardware.h>
+
+#include "mali_gralloc_module.h"
+#include "gralloc_priv.h"
+#include "mali_gralloc_debug.h"
+
+static pthread_mutex_t dump_lock = PTHREAD_MUTEX_INITIALIZER;
+static std::vector<private_handle_t *> dump_buffers;
+static android::String8 dumpStrings;
+
+void mali_gralloc_dump_buffer_add(private_handle_t *handle)
+{
+	if (NULL == handle)
+	{
+		ALOGE("Invalid handle %p and return", handle);
+		return;
+	}
+
+	pthread_mutex_lock(&dump_lock);
+	dump_buffers.push_back(handle);
+	pthread_mutex_unlock(&dump_lock);
+}
+
+void mali_gralloc_dump_buffer_erase(private_handle_t *handle)
+{
+	if (NULL == handle)
+	{
+		ALOGE("Invalid handle %p and return", handle);
+		return;
+	}
+
+	pthread_mutex_lock(&dump_lock);
+	dump_buffers.erase(std::remove(dump_buffers.begin(), dump_buffers.end(), handle));
+	pthread_mutex_unlock(&dump_lock);
+}
+
+void mali_gralloc_dump_string(android::String8 &buf, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	buf.appendFormatV(fmt, args);
+	va_end(args);
+}
+
+void mali_gralloc_dump_buffers(android::String8 &dumpStrings, uint32_t *outSize)
+{
+	if (NULL == outSize)
+	{
+		ALOGE("Invalid pointer to dump buffer size and return");
+		return;
+	}
+
+	dumpStrings.clear();
+	mali_gralloc_dump_string(dumpStrings,
+	                         "-------------------------Start to dump Gralloc buffers info------------------------\n");
+	private_handle_t *hnd;
+	size_t num;
+
+	mali_gralloc_dump_string(dumpStrings, "    handle  | width | height | stride |   req format   |internal "
+	                                      "format|consumer usage|producer usage| shared fd | AFBC "
+	                                      "|\n");
+	mali_gralloc_dump_string(dumpStrings, "------------+-------+--------+--------+----------------+---------------+----"
+	                                      "----------+--------------+-----------+------+\n");
+	pthread_mutex_lock(&dump_lock);
+
+	for (num = 0; num < dump_buffers.size(); num++)
+	{
+		hnd = dump_buffers[num];
+		mali_gralloc_dump_string(dumpStrings, " %08" PRIxPTR " | %5d |  %5d |  %5d |    %08x    |    %09" PRIx64
+		                                      "  |   %09" PRIx64 "  |   %09" PRIx64 "  |  %08x | %4d |\n",
+		                         hnd, hnd->width, hnd->height, hnd->stride, hnd->req_format, hnd->internal_format,
+		                         hnd->consumer_usage, hnd->producer_usage, hnd->share_fd,
+		                         (hnd->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) ? true : false);
+	}
+
+	pthread_mutex_unlock(&dump_lock);
+	mali_gralloc_dump_string(
+	    dumpStrings, "---------------------End dump Gralloc buffers info with num %zu----------------------\n", num);
+
+	*outSize = dumpStrings.size();
+}
+
+void mali_gralloc_dump_internal(uint32_t *outSize, char *outBuffer)
+{
+	uint32_t dumpSize;
+
+	if (NULL == outSize)
+	{
+		ALOGE("Invalid pointer to dump buffer size and return");
+		return;
+	}
+
+	if (NULL == outBuffer)
+	{
+		if (!dumpStrings.isEmpty())
+		{
+			dumpStrings.clear();
+		}
+
+		mali_gralloc_dump_buffers(dumpStrings, outSize);
+	}
+	else
+	{
+		if (dumpStrings.isEmpty())
+		{
+			*outSize = 0;
+		}
+		else
+		{
+			dumpSize = dumpStrings.size();
+			*outSize = (dumpSize < *outSize) ? dumpSize : *outSize;
+			memcpy(outBuffer, dumpStrings.string(), *outSize);
+		}
+	}
+}
diff --git a/gralloc960/mali_gralloc_debug.h b/gralloc960/mali_gralloc_debug.h
new file mode 100644
index 0000000..26e2381
--- /dev/null
+++ b/gralloc960/mali_gralloc_debug.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MALI_GRALLOC_DEBUG_H_
+#define MALI_GRALLOC_DEBUG_H_
+
+#include <utils/String8.h>
+#include <hardware/hardware.h>
+#include "gralloc_priv.h"
+#include "mali_gralloc_module.h"
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+void mali_gralloc_dump_buffer_add(private_handle_t *handle);
+void mali_gralloc_dump_buffer_erase(private_handle_t *handle);
+
+void mali_gralloc_dump_string(android::String8 &buf, const char *fmt, ...);
+void mali_gralloc_dump_buffers(android::String8 &dumpBuffer, uint32_t *outSize);
+void mali_gralloc_dump_internal(uint32_t *outSize, char *outBuffer);
+#endif
diff --git a/gralloc960/mali_gralloc_formats.cpp b/gralloc960/mali_gralloc_formats.cpp
index 67127fd..a62898c 100644
--- a/gralloc960/mali_gralloc_formats.cpp
+++ b/gralloc960/mali_gralloc_formats.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 ARM Limited. All rights reserved.
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -18,11 +18,16 @@
 
 #include <string.h>
 #include <dlfcn.h>
-#include <hardware/gralloc.h>
 #include <inttypes.h>
 #include <cutils/log.h>
 
-#include "mali_gralloc_formats.h"
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
 #include "gralloc_priv.h"
 
 static mali_gralloc_format_caps dpu_runtime_caps;
@@ -41,51 +46,53 @@
 #define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib/egl/"
 #endif
 
+#define GRALLOC_AFBC_MIN_SIZE 75
+
 static bool get_block_capabilities(bool hal_module, const char *name, mali_gralloc_format_caps *block_caps)
 {
-    void *dso_handle = NULL;
-    bool rval = false;
+	void *dso_handle = NULL;
+	bool rval = false;
 
-    /* Look for MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR symbol in user-space drivers
-     * to determine hw format capabilities.
-     */
-    if(!hal_module)
-    {
-        dso_handle = dlopen(name, RTLD_LAZY);
-    }
-    else
-    {
-        /* libhardware does some heuristics to find hal modules
-         * and then stores the dso handle internally. Use this.
-         */
-        const struct hw_module_t *module = {NULL};
+	/* Look for MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR symbol in user-space drivers
+	 * to determine hw format capabilities.
+	 */
+	if (!hal_module)
+	{
+		dso_handle = dlopen(name, RTLD_LAZY);
+	}
+	else
+	{
+		/* libhardware does some heuristics to find hal modules
+		 * and then stores the dso handle internally. Use this.
+		 */
+		const struct hw_module_t *module = { NULL };
 
-        if(hw_get_module(name, &module) >= 0)
-        {
-            dso_handle = module->dso;
-        }
-    }
+		if (hw_get_module(name, &module) >= 0)
+		{
+			dso_handle = module->dso;
+		}
+	}
 
-    if(dso_handle)
-    {
-        void *sym = dlsym(dso_handle, MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR);
+	if (dso_handle)
+	{
+		void *sym = dlsym(dso_handle, MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR);
 
-        if(sym)
-        {
-            memcpy((void*) block_caps, sym, sizeof(mali_gralloc_format_caps));
-            rval = true;
-        }
+		if (sym)
+		{
+			memcpy((void *)block_caps, sym, sizeof(mali_gralloc_format_caps));
+			rval = true;
+		}
 
-        if(!hal_module)
-        {
-            dlclose(dso_handle);
-        }
-    }
+		if (!hal_module)
+		{
+			dlclose(dso_handle);
+		}
+	}
 
-    return rval;
+	return rval;
 }
 
-static int map_flex_formats(int req_format, uint64_t *producer_runtime_mask)
+static int map_flex_formats(uint64_t req_format)
 {
     /* Map Android flexible formats to internal base formats */
     if(req_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
@@ -93,361 +100,393 @@
     {
         req_format = MALI_GRALLOC_FORMAT_INTERNAL_NV12;
 
-        /*
-         * We disable AFBC for NV12 since neither VPU or DPU DDKs support
-         * them currently.
-         */
-        *producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
     }
     return req_format;
 }
 
 static bool is_afbc_supported(int req_format_mapped)
 {
-    bool rval = true;
+	bool rval = true;
 
-    /* These base formats we currently don't support with compression */
-    switch(req_format_mapped)
-    {
-        case MALI_GRALLOC_FORMAT_INTERNAL_RAW16:
-        case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
-        case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
-        case MALI_GRALLOC_FORMAT_INTERNAL_BLOB:
-        case MALI_GRALLOC_FORMAT_INTERNAL_P010:
-        case MALI_GRALLOC_FORMAT_INTERNAL_P210:
-        case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
-        case HAL_PIXEL_FORMAT_YCbCr_422_I:
-            rval = false;
-            break;
-    }
-    return rval;
+	/* These base formats we currently don't support with compression */
+	switch (req_format_mapped)
+	{
+	case MALI_GRALLOC_FORMAT_INTERNAL_RAW16:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
+	case MALI_GRALLOC_FORMAT_INTERNAL_BLOB:
+	case MALI_GRALLOC_FORMAT_INTERNAL_P010:
+	case MALI_GRALLOC_FORMAT_INTERNAL_P210:
+	case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
+	case HAL_PIXEL_FORMAT_YCbCr_422_I:
+		rval = false;
+		break;
+	}
+
+	return rval;
 }
 
 static bool is_android_yuv_format(int req_format)
 {
-    bool rval = false;
+	bool rval = false;
 
-    switch(req_format)
-    {
-        case HAL_PIXEL_FORMAT_YV12:
-        case HAL_PIXEL_FORMAT_Y8:
-        case HAL_PIXEL_FORMAT_Y16:
-        case HAL_PIXEL_FORMAT_YCbCr_420_888:
-        case HAL_PIXEL_FORMAT_YCbCr_422_888:
-        case HAL_PIXEL_FORMAT_YCbCr_444_888:
-            rval = true;
-            break;
-    }
-    return rval;
+	switch (req_format)
+	{
+	case HAL_PIXEL_FORMAT_YV12:
+	case HAL_PIXEL_FORMAT_Y8:
+	case HAL_PIXEL_FORMAT_Y16:
+	case HAL_PIXEL_FORMAT_YCbCr_420_888:
+	case HAL_PIXEL_FORMAT_YCbCr_422_888:
+	case HAL_PIXEL_FORMAT_YCbCr_444_888:
+	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+	case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+		rval = true;
+		break;
+	}
+
+	return rval;
 }
 
 static bool is_afbc_allowed(int buffer_size)
 {
-    bool afbc_allowed = false;
+	bool afbc_allowed = false;
 
-    (void) buffer_size;
+	(void)buffer_size;
 
+#if MALI_DISPLAY_VERSION == 550 || MALI_DISPLAY_VERSION == 650
 #if GRALLOC_DISP_W != 0 && GRALLOC_DISP_H != 0
-    afbc_allowed = ((buffer_size*100) / (GRALLOC_DISP_W*GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE;
+	afbc_allowed = ((buffer_size * 100) / (GRALLOC_DISP_W * GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE;
 
 #else
-    /* If display size is not valid then always allow AFBC */
-    afbc_allowed = true;
+	/* If display size is not valid then always allow AFBC */
+	afbc_allowed = true;
 
 #endif
-
-    return afbc_allowed;
+#else
+	/* For cetus, always allow AFBC */
+	afbc_allowed = true;
+#endif
+	return afbc_allowed;
 }
 
 static bool is_afbc_format(uint64_t internal_format)
 {
-    return (internal_format & MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK) != 0;
+	return (internal_format & MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK) != 0;
 }
 
-static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type producer, mali_gralloc_consumer_type consumer,
-                                      uint64_t producer_runtime_mask, uint64_t consumer_runtime_mask)
+static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type producer,
+                                      mali_gralloc_consumer_type consumer, uint64_t producer_runtime_mask,
+                                      uint64_t consumer_runtime_mask)
 {
-    /* Default is to return the requested format */
-    uint64_t internal_format = req_format;
-    uint64_t dpu_mask = dpu_runtime_caps.caps_mask;
-    uint64_t gpu_mask = gpu_runtime_caps.caps_mask;
-    uint64_t vpu_mask = vpu_runtime_caps.caps_mask;
-    uint64_t cam_mask = cam_runtime_caps.caps_mask;
+	/* Default is to return the requested format */
+	uint64_t internal_format = req_format;
+	uint64_t dpu_mask = dpu_runtime_caps.caps_mask;
+	uint64_t gpu_mask = gpu_runtime_caps.caps_mask;
+	uint64_t vpu_mask = vpu_runtime_caps.caps_mask;
+	uint64_t cam_mask = cam_runtime_caps.caps_mask;
 
-    if(producer == MALI_GRALLOC_PRODUCER_GPU && gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
-    {
-        gpu_mask &= producer_runtime_mask;
+	if (producer == MALI_GRALLOC_PRODUCER_GPU &&
+	    gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
+	{
+		gpu_mask &= producer_runtime_mask;
 
-        if(consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
-        {
-            gpu_mask &= consumer_runtime_mask;
-            dpu_mask &= consumer_runtime_mask;
+		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
+		{
+			gpu_mask &= consumer_runtime_mask;
+			dpu_mask &= consumer_runtime_mask;
 
-            if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK &&
-               dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK)
-            {
-                internal_format |= MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
-            }
-            else if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
-                    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
-            {
-                internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
+			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK &&
+			    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK)
+			{
+				internal_format |= MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
+			}
+			else if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
+			         dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
+			{
+				internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
 
-                if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
-                   dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
-                {
-                    internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
-                }
-            }
-        }
-        else if(consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
-        {
-            gpu_mask &= consumer_runtime_mask;
+				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
+				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
+				{
+					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
+				}
+			}
+		}
+		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
+		{
+			gpu_mask &= consumer_runtime_mask;
 
-            /* When GPU acts as both producer and consumer it prefers 16x16 superblocks */
-            if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
-            {
-                internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
-            }
+			/* When GPU acts as both producer and consumer it prefers 16x16 superblocks */
+			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
+			{
+				internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
+			}
 
-            if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
-            {
-                internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
-            }
-        }
-        else if(consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
-        {
-            vpu_mask &= consumer_runtime_mask;
+			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
+			{
+				internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
+			}
+		}
+		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
+		{
+			vpu_mask &= consumer_runtime_mask;
 
-            if(req_format == HAL_PIXEL_FORMAT_YV12)
-            {
-                if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
-                   vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
-                {
-                    internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
-                }
+			if (internal_format == HAL_PIXEL_FORMAT_YV12 || internal_format == MALI_GRALLOC_FORMAT_INTERNAL_NV12)
+			{
+				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
+				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
+				{
+					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
+				}
 
-                if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
-                   vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
-                {
-                    internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
-                }
-            }
-        }
-    }
-    else if(producer == MALI_GRALLOC_PRODUCER_VIDEO_DECODER && vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
-    {
-        vpu_mask &= producer_runtime_mask;
+				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
+				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
+				{
+					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
+				}
+			}
+		}
+	}
+	else if (producer == MALI_GRALLOC_PRODUCER_VIDEO_DECODER &&
+	         vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
+	{
+		vpu_mask &= producer_runtime_mask;
 
-        if(consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
-        {
-            gpu_mask &= consumer_runtime_mask;
-            dpu_mask &= consumer_runtime_mask;
+		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
+		{
+			gpu_mask &= consumer_runtime_mask;
+			dpu_mask &= consumer_runtime_mask;
 
-            if(internal_format == HAL_PIXEL_FORMAT_YV12)
-            {
-                if(vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
-                   gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
-                   dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
-                {
-                    internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
-                }
+			if (internal_format == HAL_PIXEL_FORMAT_YV12)
+			{
+				if (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
+				    gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
+				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
+				{
+					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
+				}
 
-                if(vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
-                   gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
-                   dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
-                {
-                    internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
-                }
-            }
-        }
-        else if(consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
-        {
-            gpu_mask &= consumer_runtime_mask;
+				if (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
+				    gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
+				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
+				{
+					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
+				}
+			}
+		}
+		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
+		{
+			gpu_mask &= consumer_runtime_mask;
 
-            if(internal_format == HAL_PIXEL_FORMAT_YV12)
-            {
-                if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
-                   vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
-                {
-                    internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
-                }
+			if (internal_format == HAL_PIXEL_FORMAT_YV12)
+			{
+				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
+				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
+				{
+					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
+				}
 
-                if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
-                   vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
-                {
-                    internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
-                }
-            }
-        }
-        else if(consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
-        {
-            /* Fall-through. To be decided.*/
-        }
-  }
-  else if(producer == MALI_GRALLOC_PRODUCER_CAMERA && cam_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
-  {
-        if(consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
-        {
-            /* Fall-through. To be decided.*/
-        }
-        else if(consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
-        {
-            /* Fall-through. To be decided.*/
-        }
-        else if(consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
-        {
-            /* Fall-through. To be decided.*/
-        }
-  }
-  return internal_format;
+				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
+				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
+				{
+					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
+				}
+			}
+		}
+		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
+		{
+			/* Fall-through. To be decided.*/
+		}
+	}
+	else if (producer == MALI_GRALLOC_PRODUCER_CAMERA &&
+	         cam_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
+	{
+		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
+		{
+			/* Fall-through. To be decided.*/
+		}
+		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
+		{
+			/* Fall-through. To be decided.*/
+		}
+		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
+		{
+			/* Fall-through. To be decided.*/
+		}
+	}
+
+	return internal_format;
 }
 
-static uint64_t decode_internal_format(int req_format)
+static uint64_t decode_internal_format(uint64_t req_format, mali_gralloc_format_type type)
 {
-    uint64_t internal_format, me_mask, base_format, mapped_base_format;
-    uint64_t ignore_mask;
+	uint64_t internal_format, me_mask, base_format, mapped_base_format;
 
-    internal_format = GRALLOC_PRIVATE_FORMAT_UNWRAP(req_format);
+	if (type == MALI_GRALLOC_FORMAT_TYPE_USAGE)
+	{
+		internal_format = GRALLOC_PRIVATE_FORMAT_UNWRAP((int)req_format);
+	}
+	else if (type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL)
+	{
+		internal_format = req_format;
+	}
+	else
+	{
+		internal_format = 0;
+		goto out;
+	}
 
-    me_mask = internal_format & MALI_GRALLOC_INTFMT_ME_EXT_MASK;
-    if(me_mask > 0 && ((me_mask - 1) & me_mask) != 0)
-    {
-        ALOGE("Internal format contains multiple mutually exclusive modifier bits: %" PRIx64, internal_format);
-        internal_format = 0;
-        goto out;
-    }
+	me_mask = internal_format & MALI_GRALLOC_INTFMT_ME_EXT_MASK;
 
-    base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+	if (me_mask > 0 && ((me_mask - 1) & me_mask) != 0)
+	{
+		ALOGE("Internal format contains multiple mutually exclusive modifier bits: %" PRIx64, internal_format);
+		internal_format = 0;
+		goto out;
+	}
 
-    /* Even though private format allocations are intended to be for specific
-     * formats, certain test cases uses the flexible formats that needs to be mapped
-     * to internal ones.
-     */
-    mapped_base_format = map_flex_formats((uint32_t ) base_format, &ignore_mask);
+	base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
 
-    /* Validate the internal base format passed in */
-    switch(mapped_base_format)
-    {
-        case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888:
-        case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888:
-        case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888:
-        case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565:
-        case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888:
-        case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
-        case MALI_GRALLOC_FORMAT_INTERNAL_Y8:
-        case MALI_GRALLOC_FORMAT_INTERNAL_Y16:
-        case MALI_GRALLOC_FORMAT_INTERNAL_RAW16:
-        case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
-        case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
-        case MALI_GRALLOC_FORMAT_INTERNAL_BLOB:
-        case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
-        case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
-        case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT:
-        case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2:
-        case MALI_GRALLOC_FORMAT_INTERNAL_P010:
-        case MALI_GRALLOC_FORMAT_INTERNAL_P210:
-        case MALI_GRALLOC_FORMAT_INTERNAL_Y210:
-        case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
-            if(mapped_base_format != base_format)
-            {
-                internal_format = (internal_format & MALI_GRALLOC_INTFMT_EXT_MASK) | mapped_base_format;
-            }
-            break;
+	/* Even though private format allocations are intended to be for specific
+	 * formats, certain test cases uses the flexible formats that needs to be mapped
+	 * to internal ones.
+	 */
+	mapped_base_format = map_flex_formats((uint32_t)base_format);
 
-        default:
-            ALOGE("Internal base format requested is unrecognized: %" PRIx64 ,internal_format);
-            internal_format = 0;
-            break;
-    }
+	/* Validate the internal base format passed in */
+	switch (mapped_base_format)
+	{
+	case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565:
+	case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888:
+	case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
+	case MALI_GRALLOC_FORMAT_INTERNAL_Y8:
+	case MALI_GRALLOC_FORMAT_INTERNAL_Y16:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RAW16:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
+	case MALI_GRALLOC_FORMAT_INTERNAL_BLOB:
+	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+	case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
+	case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT:
+	case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2:
+	case MALI_GRALLOC_FORMAT_INTERNAL_P010:
+	case MALI_GRALLOC_FORMAT_INTERNAL_P210:
+	case MALI_GRALLOC_FORMAT_INTERNAL_Y210:
+	case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
+		if (mapped_base_format != base_format)
+		{
+			internal_format = (internal_format & MALI_GRALLOC_INTFMT_EXT_MASK) | mapped_base_format;
+		}
+
+		break;
+
+	default:
+		ALOGE("Internal base format requested is unrecognized: %" PRIx64, internal_format);
+		internal_format = 0;
+		break;
+	}
+
 out:
-    return internal_format;
+	return internal_format;
 }
 
-static bool determine_producer(mali_gralloc_producer_type *producer, uint64_t *producer_runtime_mask, int req_format, int usage)
+static bool determine_producer(mali_gralloc_producer_type *producer, uint64_t *producer_runtime_mask, int req_format,
+                               int usage)
 {
-    bool rval = true;
+	bool rval = true;
 
-    /* Default to GPU */
-    *producer = MALI_GRALLOC_PRODUCER_GPU;
+	/* Default to GPU */
+	*producer = MALI_GRALLOC_PRODUCER_GPU;
 
-    if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
-    {
-        rval = false;
-    }
-    else if(usage & GRALLOC_USAGE_HW_RENDER)
-    {
-        if(is_android_yuv_format(req_format))
-        {
-            if(gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE)
-            {
-                *producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-            }
-            else
-            {
-                /* All GPUs that can write YUV AFBC can only do it in 16x16, optionally with tiled */
-                *producer_runtime_mask &= ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK);
-            }
-        }
-        *producer = MALI_GRALLOC_PRODUCER_GPU;
-    }
-    else if(usage & GRALLOC_USAGE_HW_CAMERA_MASK)
-    {
-        *producer = MALI_GRALLOC_PRODUCER_CAMERA;
-    }
-    /* HW_TEXTURE+HW_COMPOSER+EXTERNAL_DISP is a definition set by
-     * stagefright for "video decoder". We check for it here.
-     */
-    else if((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP)) ==
-                    (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP))
-    {
-        *producer = MALI_GRALLOC_PRODUCER_VIDEO_DECODER;
-    }
+	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
+	{
+		rval = false;
+	}
+	else if (usage & GRALLOC_USAGE_HW_RENDER)
+	{
+		if (is_android_yuv_format(req_format))
+		{
+			if (gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE)
+			{
+				*producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+			}
+			else
+			{
+				/* All GPUs that can write YUV AFBC can only do it in 16x16, optionally with tiled */
+				*producer_runtime_mask &=
+				    ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK);
+			}
+		}
 
-   return rval;
+		*producer = MALI_GRALLOC_PRODUCER_GPU;
+	}
+	else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK)
+	{
+		*producer = MALI_GRALLOC_PRODUCER_CAMERA;
+	}
+	/* HW_TEXTURE+HW_COMPOSER+EXTERNAL_DISP is a definition set by
+	 * stagefright for "video decoder". We check for it here.
+	 */
+	else if ((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP)) ==
+	         (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP))
+	{
+		*producer = MALI_GRALLOC_PRODUCER_VIDEO_DECODER;
+	}
+
+	return rval;
 }
 
-static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *consumer_runtime_mask, int req_format, int usage)
+static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *consumer_runtime_mask, int req_format,
+                               int usage)
 {
-    bool rval = true;
+	bool rval = true;
 
-    /* Default to GPU */
-    *consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL;
+	/* Default to GPU */
+	*consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL;
 
-    if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
-    {
-        rval = false;
-    }
-    /* When usage explicitly targets a consumer, as it does with GRALLOC_USAGE_HW_FB,
-     * we pick DPU even if there are no runtime capabilities present.
-     */
-    else if( usage & GRALLOC_USAGE_HW_FB )
-    {
-        *consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY;
-    }
-    else if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
-    {
-        if((vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD) &&
-           is_android_yuv_format(req_format))
-        {
-            *consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-        }
-        *consumer = MALI_GRALLOC_CONSUMER_VIDEO_ENCODER;
-    }
-    /* GRALLOC_USAGE_HW_COMPOSER is by default applied by SurfaceFlinger so we can't exclusively rely on it
-     * to determine consumer. When a buffer is targeted for either we reject the DPU when it lacks
-     * runtime capabilities, in favor of the more capable GPU.
-     */
-    else if((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER )) == (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER ) &&
-            dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
-    {
-        *consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY;
-    }
-    else if(usage & GRALLOC_USAGE_HW_TEXTURE)
-    {
-        *consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL;
-    }
-    return rval;
+	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
+	{
+		rval = false;
+	}
+	/* When usage explicitly targets a consumer, as it does with GRALLOC_USAGE_HW_FB,
+	 * we pick DPU even if there are no runtime capabilities present.
+	 */
+	else if (usage & GRALLOC_USAGE_HW_FB)
+	{
+		*consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY;
+	}
+	else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
+	{
+		if (is_android_yuv_format(req_format))
+		{
+			if (vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD)
+				*consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+		}
+		else
+		{
+			*consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+		}
+		*consumer = MALI_GRALLOC_CONSUMER_VIDEO_ENCODER;
+	}
+	/* GRALLOC_USAGE_HW_COMPOSER is by default applied by SurfaceFlinger so we can't exclusively rely on it
+	 * to determine consumer. When a buffer is targeted for either we reject the DPU when it lacks
+	 * runtime capabilities, in favor of the more capable GPU.
+	 */
+	else if ((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER)) ==
+	             (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER) &&
+	         dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
+	{
+		*consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY;
+	}
+	else if (usage & GRALLOC_USAGE_HW_TEXTURE)
+	{
+		*consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL;
+	}
+
+	return rval;
 }
 
 /*
@@ -457,196 +496,201 @@
  */
 static void determine_format_capabilities()
 {
-    /* Loading libraries can take some time and
-     * we may see many allocations at boot.
-     */
-    pthread_mutex_lock(&caps_init_mutex);
+	/* Loading libraries can take some time and
+	 * we may see many allocations at boot.
+	 */
+	pthread_mutex_lock(&caps_init_mutex);
 
-    if(runtime_caps_read)
-    {
-        goto already_init;
-    }
+	if (runtime_caps_read)
+	{
+		goto already_init;
+	}
 
-    memset((void*) &dpu_runtime_caps,0,sizeof(dpu_runtime_caps));
-    memset((void*) &vpu_runtime_caps,0,sizeof(vpu_runtime_caps));
-    memset((void*) &gpu_runtime_caps,0,sizeof(gpu_runtime_caps));
-    memset((void*) &cam_runtime_caps,0,sizeof(cam_runtime_caps));
+	memset((void *)&dpu_runtime_caps, 0, sizeof(dpu_runtime_caps));
+	memset((void *)&vpu_runtime_caps, 0, sizeof(vpu_runtime_caps));
+	memset((void *)&gpu_runtime_caps, 0, sizeof(gpu_runtime_caps));
+	memset((void *)&cam_runtime_caps, 0, sizeof(cam_runtime_caps));
 
-    /* Determine DPU format capabilities */
-    if(!get_block_capabilities(true, "hwcomposer", &dpu_runtime_caps))
-    {
+	/* Determine DPU format capabilities */
+	if (!get_block_capabilities(true, "hwcomposer", &dpu_runtime_caps))
+	{
 #if MALI_DISPLAY_VERSION >= 500
-        dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
-        dpu_runtime_caps.caps_mask |=  MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
+		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
+		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
 
 #if MALI_DISPLAY_VERSION >= 550
-        dpu_runtime_caps.caps_mask |=  MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
+		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
 #endif
 #endif
-    }
+	}
 
-    /* Determine GPU format capabilities */
-    if(access(MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME,R_OK) == 0)
-    {
-        get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps);
-    }
-    else if(access(MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME,R_OK) == 0)
-    {
-        get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps);
-    }
+	/* Determine GPU format capabilities */
+	if (access(MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0)
+	{
+		get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps);
+	}
+	else if (access(MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0)
+	{
+		get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps);
+	}
 
-    if((gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) == 0)
-    {
-        ALOGW("Failed to find GPU block configuration in %s. Using static build configuration.", MALI_GRALLOC_GPU_LIB_NAME);
+	if ((gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) == 0)
+	{
+		ALOGW("Failed to find GPU block configuration in %s. Using static build configuration.",
+		      MALI_GRALLOC_GPU_LIB_NAME);
 
 #if MALI_GPU_SUPPORT_AFBC_BASIC == 1
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
 
-        /* Need to verify when to remove this */
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE;
+		/* Need to verify when to remove this */
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE;
 
 #if MALI_SUPPORT_AFBC_SPLITBLK == 1
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
 #endif
 
 #if MALI_SUPPORT_AFBC_WIDEBLK == 1
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK;
 #endif
 
 #if MALI_USE_YUV_AFBC_WIDEBLK != 1
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK_YUV_DISABLE;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK_YUV_DISABLE;
 #endif
 
 #if MALI_SUPPORT_AFBC_TILED_HEADERS == 1
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK;
-        gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK;
+		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS;
 #endif
 #endif /* MALI_GPU_SUPPORT_AFBC_BASIC == 1 */
-    }
+	}
 
-    /* Determine VPU format capabilities */
+/* Determine VPU format capabilities */
 #if MALI_VIDEO_VERSION == 500 || MALI_VIDEO_VERSION == 550
-    vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
-    vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
-    vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD;
+	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
+	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
+	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD;
 #endif
 
 #if MALI_VIDEO_VERSION == 61
-    vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
-    vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
-    vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS;
+	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
+	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
+	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS;
 #endif
 
-
-    /* Build specific capability changes */
+/* Build specific capability changes */
 #if GRALLOC_ARM_NO_EXTERNAL_AFBC == 1
-    {
-        dpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-        gpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-        vpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-        cam_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-    }
+	{
+		dpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+		gpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+		vpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+		cam_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+	}
 #endif
 
-    runtime_caps_read = true;
+	runtime_caps_read = true;
 
 already_init:
-    pthread_mutex_unlock(&caps_init_mutex);
+	pthread_mutex_unlock(&caps_init_mutex);
 
-    ALOGV("GPU format capabilities 0x%" PRIx64 , gpu_runtime_caps.caps_mask);
-    ALOGV("DPU format capabilities 0x%" PRIx64 , dpu_runtime_caps.caps_mask);
-    ALOGV("VPU format capabilities 0x%" PRIx64 , vpu_runtime_caps.caps_mask);
-    ALOGV("CAM format capabilities 0x%" PRIx64 , cam_runtime_caps.caps_mask);
+	ALOGV("GPU format capabilities 0x%" PRIx64, gpu_runtime_caps.caps_mask);
+	ALOGV("DPU format capabilities 0x%" PRIx64, dpu_runtime_caps.caps_mask);
+	ALOGV("VPU format capabilities 0x%" PRIx64, vpu_runtime_caps.caps_mask);
+	ALOGV("CAM format capabilities 0x%" PRIx64, cam_runtime_caps.caps_mask);
 }
 
-uint64_t mali_gralloc_select_format(int req_format, int usage, int buffer_size)
+uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_type type, uint64_t usage, int buffer_size)
 {
-    uint64_t internal_format = 0;
-    mali_gralloc_consumer_type consumer;
-    mali_gralloc_producer_type producer;
-    uint64_t producer_runtime_mask = ~(0ULL);
-    uint64_t consumer_runtime_mask = ~(0ULL);
-    int req_format_mapped=0;
+	uint64_t internal_format = 0;
+	mali_gralloc_consumer_type consumer;
+	mali_gralloc_producer_type producer;
+	uint64_t producer_runtime_mask = ~(0ULL);
+	uint64_t consumer_runtime_mask = ~(0ULL);
+	uint64_t req_format_mapped = 0;
 
-    if(!runtime_caps_read)
-    {
-        /*
-         * It is better to initialize these when needed because
-         * not all processes allocates memory.
-         */
-        determine_format_capabilities();
-    }
+	if (!runtime_caps_read)
+	{
+		/*
+		 * It is better to initialize these when needed because
+		 * not all processes allocates memory.
+		 */
+		determine_format_capabilities();
+	}
 
-    /* A unique usage specifies that an internal format is in req_format */
-    if(usage & MALI_GRALLOC_USAGE_PRIVATE_FORMAT)
-    {
-        internal_format = decode_internal_format(req_format);
-        goto out;
-    }
+	/* A unique usage specifies that an internal format is in req_format */
+	if (usage & MALI_GRALLOC_USAGE_PRIVATE_FORMAT || type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL)
+	{
+		internal_format = decode_internal_format(req_format, type);
+		goto out;
+	}
 
-    /* Re-map special Android formats */
-    req_format_mapped = map_flex_formats(req_format, &producer_runtime_mask);
+	/* Re-map special Android formats */
+	req_format_mapped = map_flex_formats(req_format);
 
-    /* Determine producer/consumer */
-    if(!determine_producer(&producer, &producer_runtime_mask, req_format, usage) ||
-       !determine_consumer(&consumer, &consumer_runtime_mask, req_format, usage))
-    {
-        /* Failing to determine producer/consumer usually means
-         * client has requested sw rendering.
-         */
-        internal_format = req_format_mapped;
-        goto out;
-    }
+	/* Determine producer/consumer */
+	if (!determine_producer(&producer, &producer_runtime_mask, req_format, usage) ||
+	    !determine_consumer(&consumer, &consumer_runtime_mask, req_format, usage))
+	{
+		/* Failing to determine producer/consumer usually means
+		 * client has requested sw rendering.
+		 */
+		internal_format = req_format_mapped;
+		goto out;
+	}
 
-    /*
-     * Determine runtime capability limitations
-     */
+	/*
+	 * Determine runtime capability limitations
+	 */
 
-    /* Disable AFBC based on unique usage */
-    if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC)
-    {
-        if(is_android_yuv_format(req_format_mapped))
-        {
-            ALOGE("It is invalid to specify NO_AFBC usage flags when allocating YUV formats.\
-                   Requested fmt: 0x%08X Re-Mapped fmt: 0x%08X",req_format,req_format_mapped);
-            internal_format = 0;
-            goto out;
-        }
-        producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-    }
-    /* Disable AFBC based on buffer dimensions */
-    else if(!is_afbc_allowed(buffer_size))
-    {
-        producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-    }
-    else if(!is_afbc_supported(req_format_mapped))
-    {
-        producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
-    }
+	/* Disable AFBC based on unique usage */
+	if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC)
+	{
+		if (is_android_yuv_format(req_format_mapped))
+		{
+			ALOGE("It is invalid to specify NO_AFBC usage flags when allocating YUV formats.\
+                   Requested fmt: 0x%" PRIx64 " Re-Mapped fmt: 0x%" PRIx64,
+			      req_format, req_format_mapped);
+			internal_format = 0;
+			goto out;
+		}
 
-    /* Automatically select format in case producer/consumer identified */
-    internal_format = determine_best_format(req_format_mapped, producer, consumer, producer_runtime_mask, consumer_runtime_mask);
+		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+	}
+	/* Disable AFBC based on buffer dimensions */
+	else if (!is_afbc_allowed(buffer_size))
+	{
+		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+	}
+	else if (!is_afbc_supported(req_format_mapped))
+	{
+		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
+	}
+
+	/* Automatically select format in case producer/consumer identified */
+	internal_format =
+	    determine_best_format(req_format_mapped, producer, consumer, producer_runtime_mask, consumer_runtime_mask);
 
 out:
-    ALOGV("mali_gralloc_select_format: req_format=0x%08X req_fmt_mapped=0x%08X internal_format=0x%" PRIx64 " usage=0x%08X",req_format, req_format_mapped, internal_format, usage);
+	ALOGV("mali_gralloc_select_format: req_format=0x%08" PRIx64 " req_fmt_mapped=0x%" PRIx64
+	      " internal_format=0x%" PRIx64 " usage=0x%" PRIx64,
+	      req_format, req_format_mapped, internal_format, usage);
 
-    return internal_format;
+	return internal_format;
 }
 
-extern "C"
-{
+extern "C" {
 void mali_gralloc_get_gpu_caps(struct mali_gralloc_format_caps *gpu_caps)
 {
-    if(gpu_caps != NULL)
-    {
-        if(!runtime_caps_read)
-        {
-            determine_format_capabilities();
-        }
-        memcpy(gpu_caps,(void*) &gpu_runtime_caps,sizeof(struct mali_gralloc_format_caps));
-    }
+	if (gpu_caps != NULL)
+	{
+		if (!runtime_caps_read)
+		{
+			determine_format_capabilities();
+		}
+
+		memcpy(gpu_caps, (void *)&gpu_runtime_caps, sizeof(struct mali_gralloc_format_caps));
+	}
 }
 }
diff --git a/gralloc960/mali_gralloc_formats.h b/gralloc960/mali_gralloc_formats.h
index 5b893b4..928dc2a 100644
--- a/gralloc960/mali_gralloc_formats.h
+++ b/gralloc960/mali_gralloc_formats.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 ARM Limited. All rights reserved.
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
  *
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -30,10 +30,10 @@
 typedef uint64_t mali_gralloc_internal_format;
 
 /* Internal format masks */
-#define    MALI_GRALLOC_INTFMT_FMT_MASK             0x00000000ffffffffULL
-#define    MALI_GRALLOC_INTFMT_EXT_MASK             0xffffffff00000000ULL
-#define    MALI_GRALLOC_INTFMT_ME_EXT_MASK          0x0000ffff00000000ULL
-#define    MALI_GRALLOC_INTFMT_REG_EXT_MASK         0xffff000000000000ULL
+#define MALI_GRALLOC_INTFMT_FMT_MASK 0x00000000ffffffffULL
+#define MALI_GRALLOC_INTFMT_EXT_MASK 0xffffffff00000000ULL
+#define MALI_GRALLOC_INTFMT_ME_EXT_MASK 0x0000ffff00000000ULL
+#define MALI_GRALLOC_INTFMT_REG_EXT_MASK 0xffff000000000000ULL
 
 /* Internal base formats */
 
@@ -44,85 +44,84 @@
 
 typedef enum
 {
-    /* Internal definitions for HAL formats. */
-    MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888,
-    MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888,
-    MALI_GRALLOC_FORMAT_INTERNAL_RGB_888 = HAL_PIXEL_FORMAT_RGB_888,
-    MALI_GRALLOC_FORMAT_INTERNAL_RGB_565 = HAL_PIXEL_FORMAT_RGB_565 ,
-    MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888,
-    MALI_GRALLOC_FORMAT_INTERNAL_YV12 = HAL_PIXEL_FORMAT_YV12 ,
-    MALI_GRALLOC_FORMAT_INTERNAL_Y8 = HAL_PIXEL_FORMAT_Y8,
-    MALI_GRALLOC_FORMAT_INTERNAL_Y16 = HAL_PIXEL_FORMAT_Y16,
-    MALI_GRALLOC_FORMAT_INTERNAL_YUV420_888 = HAL_PIXEL_FORMAT_YCbCr_420_888,
+	MALI_GRALLOC_FORMAT_TYPE_USAGE,
+	MALI_GRALLOC_FORMAT_TYPE_INTERNAL,
+} mali_gralloc_format_type;
 
-    /* Camera specific HAL formats */
-    MALI_GRALLOC_FORMAT_INTERNAL_RAW16 = HAL_PIXEL_FORMAT_RAW16,
-    MALI_GRALLOC_FORMAT_INTERNAL_RAW12 = HAL_PIXEL_FORMAT_RAW12,
-    MALI_GRALLOC_FORMAT_INTERNAL_RAW10 = HAL_PIXEL_FORMAT_RAW10,
-    MALI_GRALLOC_FORMAT_INTERNAL_BLOB = HAL_PIXEL_FORMAT_BLOB,
+typedef enum
+{
+	/* Internal definitions for HAL formats. */
+	MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888,
+	MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888,
+	MALI_GRALLOC_FORMAT_INTERNAL_RGB_888 = HAL_PIXEL_FORMAT_RGB_888,
+	MALI_GRALLOC_FORMAT_INTERNAL_RGB_565 = HAL_PIXEL_FORMAT_RGB_565,
+	MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888,
+	MALI_GRALLOC_FORMAT_INTERNAL_YV12 = HAL_PIXEL_FORMAT_YV12,
+	MALI_GRALLOC_FORMAT_INTERNAL_Y8 = HAL_PIXEL_FORMAT_Y8,
+	MALI_GRALLOC_FORMAT_INTERNAL_Y16 = HAL_PIXEL_FORMAT_Y16,
+	MALI_GRALLOC_FORMAT_INTERNAL_YUV420_888 = HAL_PIXEL_FORMAT_YCbCr_420_888,
 
-    /* Flexible YUV formats would be parsed but not have any representation as
+	/* Camera specific HAL formats */
+	MALI_GRALLOC_FORMAT_INTERNAL_RAW16 = HAL_PIXEL_FORMAT_RAW16,
+	MALI_GRALLOC_FORMAT_INTERNAL_RAW12 = HAL_PIXEL_FORMAT_RAW12,
+	MALI_GRALLOC_FORMAT_INTERNAL_RAW10 = HAL_PIXEL_FORMAT_RAW10,
+	MALI_GRALLOC_FORMAT_INTERNAL_BLOB = HAL_PIXEL_FORMAT_BLOB,
+
+	/* Flexible YUV formats would be parsed but not have any representation as
      * internal format itself but one of the ones below
      */
 
-    /* The internal private formats that have no HAL equivivalent are defined
+	/* The internal private formats that have no HAL equivivalent are defined
      * afterwards starting at a specific base range */
-    MALI_GRALLOC_FORMAT_INTERNAL_NV12 = MALI_GRALLOC_FORMAT_INTERNAL_RANGE_BASE,
-    MALI_GRALLOC_FORMAT_INTERNAL_NV21,
-    MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT,
+	MALI_GRALLOC_FORMAT_INTERNAL_NV12 = MALI_GRALLOC_FORMAT_INTERNAL_RANGE_BASE,
+	MALI_GRALLOC_FORMAT_INTERNAL_NV21,
+	MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT,
 
-    /* Extended YUV formats
+	/* Extended YUV formats
      *
      * NOTE: P010, P210, and Y410 are only supported uncompressed.
      */
-    MALI_GRALLOC_FORMAT_INTERNAL_Y0L2,
-    MALI_GRALLOC_FORMAT_INTERNAL_P010,
-    MALI_GRALLOC_FORMAT_INTERNAL_P210,
-    MALI_GRALLOC_FORMAT_INTERNAL_Y210,
-    MALI_GRALLOC_FORMAT_INTERNAL_Y410,
+	MALI_GRALLOC_FORMAT_INTERNAL_Y0L2,
+	MALI_GRALLOC_FORMAT_INTERNAL_P010,
+	MALI_GRALLOC_FORMAT_INTERNAL_P210,
+	MALI_GRALLOC_FORMAT_INTERNAL_Y210,
+	MALI_GRALLOC_FORMAT_INTERNAL_Y410,
 
-    /* Add more internal formats here. Make sure decode_internal_format() is updated. */
+	/* Add more internal formats here. Make sure decode_internal_format() is updated. */
 
-    /* These are legacy 0.3 gralloc formats used only by the wrap/unwrap macros. */
-    MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP,
-    MALI_GRALLOC_FORMAT_INTERNAL_Y8_WRAP,
-    MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP,
+	/* These are legacy 0.3 gralloc formats used only by the wrap/unwrap macros. */
+	MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP,
+	MALI_GRALLOC_FORMAT_INTERNAL_Y8_WRAP,
+	MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP,
 
 	MALI_GRALLOC_FORMAT_INTERNAL_RANGE_LAST,
 } mali_gralloc_pixel_format;
 
-
 /* Format Modifier Bits Locations */
-#define MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START             32
-#define MALI_GRALLOC_INTFMT_EXTENSION_BIT_START                (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START+16)
+#define MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START 32
+#define MALI_GRALLOC_INTFMT_EXTENSION_BIT_START (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 16)
 
 /* Mutually Exclusive Modifier Bits */
 
 /* This format will use AFBC */
-#define    MALI_GRALLOC_INTFMT_AFBC_BASIC                 (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START+0))
+#define MALI_GRALLOC_INTFMT_AFBC_BASIC (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 0))
 
 /* This format uses AFBC split block mode */
-#define    MALI_GRALLOC_INTFMT_AFBC_SPLITBLK        (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START+1))
+#define MALI_GRALLOC_INTFMT_AFBC_SPLITBLK (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 1))
 
-#define    MALI_GRALLOC_INTFMT_UNUSED               (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START+2))
+#define MALI_GRALLOC_INTFMT_UNUSED (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 2))
 
 /* This format uses AFBC wide block mode */
-#define    MALI_GRALLOC_INTFMT_AFBC_WIDEBLK         (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START+3))
-
+#define MALI_GRALLOC_INTFMT_AFBC_WIDEBLK (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 3))
 
 /* Regular Modifier Bits */
-#define    MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS   (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START+0))
-
+#define MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 0))
 
 /* This mask should be used to check or clear support for AFBC for an internal format
  * These bits are mutually exclusive so this mask should not be used to enable support
  */
-#define    MALI_GRALLOC_INTFMT_AFBCENABLE_MASK                   ((uint64_t) (MALI_GRALLOC_INTFMT_AFBC_BASIC | \
-                                                                   MALI_GRALLOC_INTFMT_AFBC_SPLITBLK | \
-                                                                   MALI_GRALLOC_INTFMT_AFBC_WIDEBLK))
-
-/* Prototypes */
-uint64_t mali_gralloc_select_format(int req_format,int usage, int buffer_size);
+#define MALI_GRALLOC_INTFMT_AFBCENABLE_MASK \
+	((uint64_t)(MALI_GRALLOC_INTFMT_AFBC_BASIC | MALI_GRALLOC_INTFMT_AFBC_SPLITBLK | MALI_GRALLOC_INTFMT_AFBC_WIDEBLK))
 
 /* These are legacy Gralloc 0.3 support macros for passing private formats through the 0.3 alloc interface.
  * It packs modifier bits together with base format into a 32 bit format identifier.
@@ -136,78 +135,83 @@
  */
 static inline int mali_gralloc_format_wrapper(int format, int modifiers)
 {
-    /* Internal formats that are identical to HAL formats
-     * have the same definition. This is convenient for
-     * client parsing code to not have to parse them separately.
-     *
-     * For 3 of the HAL YUV formats that have very large definitions
-     * this causes problems for packing in modifier bits.
-     * Because of this reason we redefine these three formats
-     * while packing/unpacking them.
-     */
-    if(format == MALI_GRALLOC_FORMAT_INTERNAL_YV12)
-    {
-        format = MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP;
-    }
-    else if(format == MALI_GRALLOC_FORMAT_INTERNAL_Y8)
-    {
-        format = MALI_GRALLOC_FORMAT_INTERNAL_Y8_WRAP;
-    }
-    else if(format == MALI_GRALLOC_FORMAT_INTERNAL_Y16)
-    {
-        format = MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP;
-    }
-    return (modifiers | format);
+	/* Internal formats that are identical to HAL formats
+	 * have the same definition. This is convenient for
+	 * client parsing code to not have to parse them separately.
+	 *
+	 * For 3 of the HAL YUV formats that have very large definitions
+	 * this causes problems for packing in modifier bits.
+	 * Because of this reason we redefine these three formats
+	 * while packing/unpacking them.
+	 */
+	if (format == MALI_GRALLOC_FORMAT_INTERNAL_YV12)
+	{
+		format = MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP;
+	}
+	else if (format == MALI_GRALLOC_FORMAT_INTERNAL_Y8)
+	{
+		format = MALI_GRALLOC_FORMAT_INTERNAL_Y8_WRAP;
+	}
+	else if (format == MALI_GRALLOC_FORMAT_INTERNAL_Y16)
+	{
+		format = MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP;
+	}
+
+	return (modifiers | format);
 }
 
 static inline uint64_t mali_gralloc_format_unwrap(int x)
 {
-    uint64_t internal_format = (uint64_t) (    ((((uint64_t)(x)) & 0xff000000) << 24) | // Regular modifier bits
-                                               ((((uint64_t)(x)) & 0x00ff0000) << 16) | // Mutually exclusive modifier bits
-                                                (((uint64_t)(x)) & 0x0000ffff)   );     // Private format
+	uint64_t internal_format = (uint64_t)(((((uint64_t)(x)) & 0xff000000) << 24) | // Regular modifier bits
+	                                      ((((uint64_t)(x)) & 0x00ff0000) << 16) | // Mutually exclusive modifier bits
+	                                      (((uint64_t)(x)) & 0x0000ffff)); // Private format
 
-    uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
-    uint64_t modifiers = internal_format & MALI_GRALLOC_INTFMT_EXT_MASK;
+	uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+	uint64_t modifiers = internal_format & MALI_GRALLOC_INTFMT_EXT_MASK;
 
-    if(base_format == MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP)
-    {
-        base_format = MALI_GRALLOC_FORMAT_INTERNAL_YV12;
-    }
-    else if(base_format == MALI_GRALLOC_FORMAT_INTERNAL_Y8_WRAP)
-    {
-        base_format = MALI_GRALLOC_FORMAT_INTERNAL_Y8;
-    }
-    else if(base_format == MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP)
-    {
-        base_format = MALI_GRALLOC_FORMAT_INTERNAL_Y16;
-    }
-    return (modifiers | base_format);
+	if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP)
+	{
+		base_format = MALI_GRALLOC_FORMAT_INTERNAL_YV12;
+	}
+	else if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_Y8_WRAP)
+	{
+		base_format = MALI_GRALLOC_FORMAT_INTERNAL_Y8;
+	}
+	else if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP)
+	{
+		base_format = MALI_GRALLOC_FORMAT_INTERNAL_Y16;
+	}
+
+	return (modifiers | base_format);
 }
 
-#define    GRALLOC_PRIVATE_FORMAT_WRAPPER(x)                           ( mali_gralloc_format_wrapper(x, 0) )
-#define    GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC(x)                      ( mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)) )
-#define    GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_SPLITBLK(x)             ( mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> 16)) )
-#define    GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDEBLK(x)              ( mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16)) )
-#define    GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_BASIC(x)  ( mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 24) | \
-                                                                                                        (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))
-#define    GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_WIDE(x)   ( mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 24) | \
-                                                                                                        (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16)))
-#define    GRALLOC_PRIVATE_FORMAT_UNWRAP(x)                            mali_gralloc_format_unwrap(x)
+#define GRALLOC_PRIVATE_FORMAT_WRAPPER(x) (mali_gralloc_format_wrapper(x, 0))
+#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC(x) (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))
+#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_SPLITBLK(x) \
+	(mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> 16)))
+#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDEBLK(x) \
+	(mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16)))
+#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_BASIC(x)                   \
+	(mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 24) | \
+	                                    (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))
+#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_WIDE(x)                    \
+	(mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 24) | \
+	                                    (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16)))
+#define GRALLOC_PRIVATE_FORMAT_UNWRAP(x) mali_gralloc_format_unwrap(x)
 
 /* IP block capability masks */
-#define MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT            ((uint64_t) (1 << 0))
-#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC                 ((uint64_t) (1 << 1))
-#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK              ((uint64_t) (1 << 2))
-#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK               ((uint64_t) (1 << 3))
-#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK_YUV_DISABLE   ((uint64_t) (1 << 4))
-#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD            ((uint64_t) (1 << 5))
-#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE           ((uint64_t) (1 << 6))
-#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS         ((uint64_t) (1 << 7))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT ((uint64_t)(1 << 0))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC ((uint64_t)(1 << 1))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK ((uint64_t)(1 << 2))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK ((uint64_t)(1 << 3))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK_YUV_DISABLE ((uint64_t)(1 << 4))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD ((uint64_t)(1 << 5))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE ((uint64_t)(1 << 6))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS ((uint64_t)(1 << 7))
 
-#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK ((uint64_t) (MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC | \
-                                                                    MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | \
-                                                                    MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK | \
-                                                                    MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS))
+#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK                                                     \
+	((uint64_t)(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | \
+	            MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS))
 
 struct mali_gralloc_format_caps
 {
@@ -215,8 +219,8 @@
 };
 typedef struct mali_gralloc_format_caps mali_gralloc_format_caps;
 
-#define MALI_GRALLOC_FORMATCAPS_SYM_NAME        mali_gralloc_format_capabilities
-#define MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR    "mali_gralloc_format_capabilities"
+#define MALI_GRALLOC_FORMATCAPS_SYM_NAME mali_gralloc_format_capabilities
+#define MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR "mali_gralloc_format_capabilities"
 
 /* Producer and Consumer definitions */
 typedef enum
@@ -229,68 +233,30 @@
 typedef enum
 {
 
-    /* For surface composition in SurfaceFlinger a producer
+	/* For surface composition in SurfaceFlinger a producer
      * will not know what consumer will process a buffer.
      *
      * MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY means the GPU
      * MUST support the given format but it should be allocated
      * with preference to the DPU.
      */
-    MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY,
-    MALI_GRALLOC_CONSUMER_VIDEO_ENCODER,
+	MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY,
+	MALI_GRALLOC_CONSUMER_VIDEO_ENCODER,
 
-
-    /* This is used when no known "premium" dpu is configured.
+	/* This is used when no known "premium" dpu is configured.
      * For example, HDLCD/CLCD would be such a dpu.
      */
-    MALI_GRALLOC_CONSUMER_GPU_EXCL,
+	MALI_GRALLOC_CONSUMER_GPU_EXCL,
 } mali_gralloc_consumer_type;
 
-
-/*
- * Below usage types overlap, this is intentional.
- * The reason is that for Gralloc 0.3 there are very
- * few usage flags we have at our disposal.
- *
- * The overlapping is handled by processing the definitions
- * in a specific order.
- *
- * MALI_GRALLOC_USAGE_PRIVATE_FORMAT and MALI_GRALLOC_USAGE_NO_AFBC
- * don't overlap and are processed first.
- *
- * MALI_GRALLOC_USAGE_YUV_CONF are only for YUV formats and clients
- * using MALI_GRALLOC_USAGE_NO_AFBC must never allocate YUV formats.
- * The latter is strictly enforced and allocations will fail.
- *
- * MALI_GRALLOC_USAGE_AFBC_PADDING is only valid if MALI_GRALLOC_USAGE_NO_AFBC
- * is not present.
- */
-typedef enum
-{
-	/* The client has specified a private format in the format parameter */
-	MALI_GRALLOC_USAGE_PRIVATE_FORMAT = (int) GRALLOC_USAGE_PRIVATE_3,
-
-	/* Buffer won't be allocated as AFBC */
-	MALI_GRALLOC_USAGE_NO_AFBC = (int) (GRALLOC_USAGE_PRIVATE_1 | GRALLOC_USAGE_PRIVATE_2),
-
-	/* Valid only for YUV allocations */
-	MALI_GRALLOC_USAGE_YUV_CONF_0 = 0,
-	MALI_GRALLOC_USAGE_YUV_CONF_1 = (int) GRALLOC_USAGE_PRIVATE_1,
-	MALI_GRALLOC_USAGE_YUV_CONF_2 = (int) GRALLOC_USAGE_PRIVATE_0,
-	MALI_GRALLOC_USAGE_YUV_CONF_3 = (int) (GRALLOC_USAGE_PRIVATE_0 | GRALLOC_USAGE_PRIVATE_1),
-	MALI_GRALLOC_USAGE_YUV_CONF_MASK = MALI_GRALLOC_USAGE_YUV_CONF_3,
-
-	/* A very specific alignment is requested on some buffers */
-	MALI_GRALLOC_USAGE_AFBC_PADDING = GRALLOC_USAGE_PRIVATE_2,
-
-} mali_gralloc_usage_type;
-
-/* Prototypes */
-uint64_t mali_gralloc_select_format(int req_format,int usage, int buffer_size);
+/* Internal prototypes */
+#if defined(GRALLOC_LIBRARY_BUILD)
+uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_type type, uint64_t usage,
+                                    int buffer_size);
+#endif
 
 #ifdef __cplusplus
-extern "C"
-{
+extern "C" {
 #endif
 
 void mali_gralloc_get_gpu_caps(struct mali_gralloc_format_caps *gpu_caps);
diff --git a/gralloc960/mali_gralloc_ion.cpp b/gralloc960/mali_gralloc_ion.cpp
new file mode 100644
index 0000000..30eecdb
--- /dev/null
+++ b/gralloc960/mali_gralloc_ion.cpp
@@ -0,0 +1,770 @@
+/*
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdlib>
+#include <string.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <pthread.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <linux/ion.h>
+#include <ion/ion.h>
+#include <sys/ioctl.h>
+
+#include <hardware/hardware.h>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+#include "gralloc_helper.h"
+#include "framebuffer_device.h"
+#include "mali_gralloc_formats.h"
+#include "mali_gralloc_usages.h"
+#include "mali_gralloc_bufferdescriptor.h"
+#include "ion_4.12.h"
+
+
+
+#define ION_SYSTEM     (char*)"ion_system_heap"
+#define ION_CMA        (char*)"linux,cma"
+static bool gralloc_legacy_ion;
+static int system_heap_id;
+static int cma_heap_id;
+
+static void mali_gralloc_ion_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds);
+
+static void init_afbc(uint8_t *buf, uint64_t internal_format, int w, int h)
+{
+	uint32_t n_headers = (w * h) / 256;
+	uint32_t body_offset = n_headers * 16;
+	uint32_t headers[][4] = {
+		{ body_offset, 0x1, 0x10000, 0x0 }, /* Layouts 0, 3, 4 */
+		{ (body_offset + (1 << 28)), 0x80200040, 0x1004000, 0x20080 } /* Layouts 1, 5 */
+	};
+	uint32_t i, layout;
+
+	/* For AFBC 1.2, header buffer can be initilized to 0 for Layouts 0, 3, 4 */
+	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
+	{
+		memset(headers[0], 0, sizeof(uint32_t) * 4);
+	}
+	/* map format if necessary (also removes internal extension bits) */
+	uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+
+	switch (base_format)
+	{
+	case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888:
+	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565:
+	case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888:
+		layout = 0;
+		break;
+
+	case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
+	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+	case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
+		layout = 1;
+		break;
+
+	default:
+		layout = 0;
+	}
+
+	ALOGV("Writing AFBC header layout %d for format %" PRIu64, layout, base_format);
+
+	for (i = 0; i < n_headers; i++)
+	{
+		memcpy(buf, headers[layout], sizeof(headers[layout]));
+		buf += sizeof(headers[layout]);
+	}
+}
+
+
+
+static int find_heap_id(int ion_client, char *name)
+{
+	int i, ret, cnt, heap_id = -1;
+	struct ion_heap_data *data;
+
+	ret = ion_query_heap_cnt(ion_client, &cnt);
+
+	if (ret)
+	{
+		AERR("ion count query failed with %s", strerror(errno));
+		return -1;
+	}
+
+	data = (struct ion_heap_data *)malloc(cnt * sizeof(*data));
+	if (!data)
+	{
+		AERR("Error allocating data %s\n", strerror(errno));
+		return -1;
+	}
+
+	ret = ion_query_get_heaps(ion_client, cnt, data);
+	if (ret)
+	{
+		AERR("Error querying heaps from ion %s", strerror(errno));
+	}
+	else
+	{
+		for (i = 0; i < cnt; i++) {
+			if (strcmp(data[i].name, name) == 0) {
+				heap_id = data[i].heap_id;
+				break;
+			}
+		}
+
+		if (i == cnt)
+		{
+			AERR("No %s Heap Found amongst %d heaps\n", name, cnt);
+			heap_id = -1;
+		}
+	}
+
+	free(data);
+	return heap_id;
+}
+
+
+static int alloc_from_ion_heap(int ion_fd, size_t size, unsigned int heap_mask, unsigned int flags, int *min_pgsz)
+{
+	ion_user_handle_t ion_hnd = -1;
+	int shared_fd, ret;
+
+	if ((ion_fd < 0) || (size <= 0) || (heap_mask == 0) || (min_pgsz == NULL))
+	{
+		return -1;
+	}
+
+	/**
+	 * step 1: ion_alloc new ion_hnd
+	 * step 2: ion_share from ion_hnd and get shared_fd
+	 * step 3: ion free the given ion_hnd
+	 * step 4: when we need to free this ion buffer, just close the shared_fd,
+	 *            kernel will count the reference of file struct, so it's safe to
+	 *            be transfered between processes.
+	 */
+	ret = ion_alloc(ion_fd, size, 0, heap_mask, flags, &ion_hnd);
+
+	if (ret < 0)
+	{
+#if defined(ION_HEAP_SECURE_MASK)
+
+		if (heap_mask == ION_HEAP_SECURE_MASK)
+		{
+			return -1;
+		}
+		else
+#endif
+		{
+			/* If everything else failed try system heap */
+			flags = 0; /* Fallback option flags are not longer valid */
+			heap_mask = ION_HEAP_SYSTEM_MASK;
+			ret = ion_alloc(ion_fd, size, 0, heap_mask, flags, &ion_hnd);
+		}
+	}
+
+	ret = ion_share(ion_fd, ion_hnd, &shared_fd);
+
+	if (ret != 0)
+	{
+		AERR("ion_share( %d ) failed", ion_fd);
+		shared_fd = -1;
+	}
+
+	ret = ion_free(ion_fd, ion_hnd);
+
+	if (0 != ret)
+	{
+		AERR("ion_free( %d ) failed", ion_fd);
+		close(shared_fd);
+		shared_fd = -1;
+	}
+
+	if (ret >= 0)
+	{
+		switch (heap_mask)
+		{
+		case ION_HEAP_SYSTEM_MASK:
+			*min_pgsz = SZ_4K;
+			break;
+
+		case ION_HEAP_SYSTEM_CONTIG_MASK:
+		case ION_HEAP_CARVEOUT_MASK:
+#ifdef ION_HEAP_TYPE_DMA_MASK
+		case ION_HEAP_TYPE_DMA_MASK:
+#endif
+			*min_pgsz = size;
+			break;
+#ifdef ION_HEAP_CHUNK_MASK
+
+		/* NOTE: if have this heap make sure your ION chunk size is 2M*/
+		case ION_HEAP_CHUNK_MASK:
+			*min_pgsz = SZ_2M;
+			break;
+#endif
+#ifdef ION_HEAP_COMPOUND_PAGE_MASK
+
+		case ION_HEAP_COMPOUND_PAGE_MASK:
+			*min_pgsz = SZ_2M;
+			break;
+#endif
+/* If have customized heap please set the suitable pg type according to
+		 * the customized ION implementation
+		 */
+#ifdef ION_HEAP_CUSTOM_MASK
+
+		case ION_HEAP_CUSTOM_MASK:
+			*min_pgsz = SZ_4K;
+			break;
+#endif
+
+		default:
+			*min_pgsz = SZ_4K;
+			break;
+		}
+	}
+
+	return shared_fd;
+}
+
+unsigned int pick_ion_heap(uint64_t usage)
+{
+	unsigned int heap_mask;
+
+	if (usage & GRALLOC_USAGE_PROTECTED)
+	{
+#if defined(ION_HEAP_SECURE_MASK)
+		heap_mask = ION_HEAP_SECURE_MASK;
+#else
+		AERR("Protected ION memory is not supported on this platform.");
+		return 0;
+#endif
+	}
+
+#if defined(ION_HEAP_TYPE_COMPOUND_PAGE_MASK) && GRALLOC_USE_ION_COMPOUND_PAGE_HEAP
+	else if (!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER)))
+	{
+		heap_mask = ION_HEAP_TYPE_COMPOUND_PAGE_MASK;
+	}
+
+#elif defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
+	else if (!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER)))
+	{
+		heap_mask = ION_HEAP_TYPE_DMA_MASK;
+	}
+
+#endif
+	else
+	{
+		heap_mask = ION_HEAP_SYSTEM_MASK;
+	}
+
+	return heap_mask;
+}
+
+void set_ion_flags(unsigned int heap_mask, uint64_t usage, unsigned int *priv_heap_flag, int *ion_flags)
+{
+#if !GRALLOC_USE_ION_DMA_HEAP
+	GRALLOC_UNUSED(heap_mask);
+#endif
+
+	if (priv_heap_flag)
+	{
+#if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
+
+		if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
+		{
+			*priv_heap_flag = private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP;
+		}
+
+#endif
+	}
+
+	if (ion_flags)
+	{
+#if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
+
+		if (heap_mask != ION_HEAP_TYPE_DMA_MASK)
+		{
+#endif
+
+			if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
+			{
+				*ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
+			}
+
+#if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
+		}
+
+#endif
+	}
+}
+
+static bool check_buffers_sharable(const gralloc_buffer_descriptor_t *descriptors, uint32_t numDescriptors)
+{
+	unsigned int shared_backend_heap_mask = 0;
+	int shared_ion_flags = 0;
+	uint64_t usage;
+	uint32_t i;
+
+	if (numDescriptors <= 1)
+	{
+		return false;
+	}
+
+	for (i = 0; i < numDescriptors; i++)
+	{
+		unsigned int heap_mask;
+		int ion_flags;
+		buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)descriptors[i];
+
+		usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
+		heap_mask = pick_ion_heap(usage);
+
+		if (0 == heap_mask)
+		{
+			return false;
+		}
+
+		set_ion_flags(heap_mask, usage, NULL, &ion_flags);
+
+		if (0 != shared_backend_heap_mask)
+		{
+			if (shared_backend_heap_mask != heap_mask || shared_ion_flags != ion_flags)
+			{
+				return false;
+			}
+		}
+		else
+		{
+			shared_backend_heap_mask = heap_mask;
+			shared_ion_flags = ion_flags;
+		}
+	}
+
+	return true;
+}
+
+static int get_max_buffer_descriptor_index(const gralloc_buffer_descriptor_t *descriptors, uint32_t numDescriptors)
+{
+	uint32_t i, max_buffer_index = 0;
+	size_t max_buffer_size = 0;
+
+	for (i = 0; i < numDescriptors; i++)
+	{
+		buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)descriptors[i];
+
+		if (max_buffer_size < bufDescriptor->size)
+		{
+			max_buffer_index = i;
+			max_buffer_size = bufDescriptor->size;
+		}
+	}
+
+	return max_buffer_index;
+}
+
+int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors,
+                              uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend)
+{
+	static int support_protected = 1; /* initially, assume we support protected memory */
+	unsigned int heap_mask, priv_heap_flag = 0;
+	unsigned char *cpu_ptr = NULL;
+	uint64_t usage;
+	uint32_t i, max_buffer_index = 0;
+	int shared_fd, ret, ion_flags = 0;
+	int min_pgsz = 0;
+
+	if (m->ion_client < 0)
+	{
+		m->ion_client = ion_open();
+
+		if (m->ion_client < 0)
+		{
+			AERR("ion_open failed with %s", strerror(errno));
+			return -1;
+		}
+
+		gralloc_legacy_ion = ion_is_legacy(m->ion_client);
+		if (!gralloc_legacy_ion)
+		{
+			system_heap_id = find_heap_id(m->ion_client, ION_SYSTEM);
+			cma_heap_id = find_heap_id(m->ion_client, ION_CMA);
+			if (system_heap_id < 0)
+			{
+				ion_close(m->ion_client);
+				m->ion_client = -1;
+				AERR( "ion_open failed: no system heap found" );
+				return -1;
+			}
+			if (cma_heap_id < 0) {
+				AERR("No cma heap found, falling back to system");
+				cma_heap_id = system_heap_id;
+			}
+		}
+	}
+
+	*shared_backend = check_buffers_sharable(descriptors, numDescriptors);
+
+	if (*shared_backend)
+	{
+		buffer_descriptor_t *max_bufDescriptor;
+
+		max_buffer_index = get_max_buffer_descriptor_index(descriptors, numDescriptors);
+		max_bufDescriptor = (buffer_descriptor_t *)(descriptors[max_buffer_index]);
+		usage = max_bufDescriptor->consumer_usage | max_bufDescriptor->producer_usage;
+
+		heap_mask = pick_ion_heap(usage);
+
+		if (heap_mask == 0)
+		{
+			AERR("Failed to find an appropriate ion heap");
+			return -1;
+		}
+
+		set_ion_flags(heap_mask, usage, &priv_heap_flag, &ion_flags);
+		if (gralloc_legacy_ion)
+		{
+			shared_fd = alloc_from_ion_heap(m->ion_client, max_bufDescriptor->size, heap_mask, ion_flags, &min_pgsz);
+		}
+		else
+		{
+			int heap = 1 << system_heap_id;
+			if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
+				heap = 1 << cma_heap_id;
+
+			ret = ion_alloc_fd(m->ion_client, max_bufDescriptor->size, 0, heap, 0, &(shared_fd));
+			if (ret != 0)
+			{
+				AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client);
+				return -1;
+			}
+			min_pgsz = SZ_4K;
+		}
+
+		if (shared_fd < 0)
+		{
+			AERR("ion_alloc failed form client: ( %d )", m->ion_client);
+			return -1;
+		}
+
+		for (i = 0; i < numDescriptors; i++)
+		{
+			buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
+			int tmp_fd;
+
+			if (i != max_buffer_index)
+			{
+				tmp_fd = dup(shared_fd);
+
+				if (tmp_fd < 0)
+				{
+					/* need to free already allocated memory. */
+					mali_gralloc_ion_free_internal(pHandle, numDescriptors);
+					return -1;
+				}
+			}
+			else
+			{
+				tmp_fd = shared_fd;
+			}
+
+			private_handle_t *hnd = new private_handle_t(
+			    private_handle_t::PRIV_FLAGS_USES_ION | priv_heap_flag, bufDescriptor->size, min_pgsz,
+			    bufDescriptor->consumer_usage, bufDescriptor->producer_usage, tmp_fd, bufDescriptor->hal_format,
+			    bufDescriptor->internal_format, bufDescriptor->byte_stride, bufDescriptor->width, bufDescriptor->height,
+			    bufDescriptor->pixel_stride, bufDescriptor->internalWidth, bufDescriptor->internalHeight,
+			    max_bufDescriptor->size);
+
+			if (NULL == hnd)
+			{
+				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
+				return -1;
+			}
+
+			pHandle[i] = hnd;
+		}
+	}
+	else
+	{
+		for (i = 0; i < numDescriptors; i++)
+		{
+			buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
+			usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
+
+			heap_mask = pick_ion_heap(usage);
+
+			if (heap_mask == 0)
+			{
+				AERR("Failed to find an appropriate ion heap");
+				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
+				return -1;
+			}
+
+			set_ion_flags(heap_mask, usage, &priv_heap_flag, &ion_flags);
+			if (gralloc_legacy_ion)
+			{
+				shared_fd = alloc_from_ion_heap(m->ion_client, bufDescriptor->size, heap_mask, ion_flags, &min_pgsz);
+			}
+			else
+			{
+				int heap = 1 << system_heap_id;
+				if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
+					heap = 1 << cma_heap_id;
+
+				ret = ion_alloc_fd(m->ion_client, bufDescriptor->size, 0, heap, 0, &(shared_fd));
+				if (ret != 0)
+				{
+					AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client);
+					mali_gralloc_ion_free_internal(pHandle, numDescriptors);
+					return -1;
+				}
+				min_pgsz = SZ_4K;
+			}
+
+			if (shared_fd < 0)
+			{
+				AERR("ion_alloc failed from client ( %d )", m->ion_client);
+
+				/* need to free already allocated memory. not just this one */
+				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
+
+				return -1;
+			}
+
+			private_handle_t *hnd = new private_handle_t(
+			    private_handle_t::PRIV_FLAGS_USES_ION | priv_heap_flag, bufDescriptor->size, min_pgsz,
+			    bufDescriptor->consumer_usage, bufDescriptor->producer_usage, shared_fd, bufDescriptor->hal_format,
+			    bufDescriptor->internal_format, bufDescriptor->byte_stride, bufDescriptor->width, bufDescriptor->height,
+			    bufDescriptor->pixel_stride, bufDescriptor->internalWidth, bufDescriptor->internalHeight,
+			    bufDescriptor->size);
+
+			if (NULL == hnd)
+			{
+				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
+				return -1;
+			}
+
+			pHandle[i] = hnd;
+		}
+	}
+
+	for (i = 0; i < numDescriptors; i++)
+	{
+		buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
+		private_handle_t *hnd = (private_handle_t *)(pHandle[i]);
+
+		usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
+
+		if (!(usage & GRALLOC_USAGE_PROTECTED))
+		{
+			cpu_ptr =
+			    (unsigned char *)mmap(NULL, bufDescriptor->size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);
+
+			if (MAP_FAILED == cpu_ptr)
+			{
+				AERR("mmap failed from client ( %d ), fd ( %d )", m->ion_client, hnd->share_fd);
+				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
+				return -1;
+			}
+
+#if GRALLOC_INIT_AFBC == 1
+
+			if ((bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) && (!(*shared_backend)))
+			{
+				init_afbc(cpu_ptr, bufDescriptor->internal_format, bufDescriptor->width, bufDescriptor->height);
+			}
+
+#endif
+			hnd->base = cpu_ptr;
+		}
+	}
+
+	return 0;
+}
+
+void mali_gralloc_ion_free(private_handle_t const *hnd)
+{
+	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
+	{
+		return;
+	}
+	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+	{
+		/* Buffer might be unregistered already so we need to assure we have a valid handle*/
+		if (0 != hnd->base)
+		{
+			if (0 != munmap((void *)hnd->base, hnd->size))
+			{
+				AERR("Failed to munmap handle %p", hnd);
+			}
+		}
+
+		close(hnd->share_fd);
+		memset((void *)hnd, 0, sizeof(*hnd));
+	}
+}
+
+static void mali_gralloc_ion_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds)
+{
+	uint32_t i = 0;
+
+	for (i = 0; i < num_hnds; i++)
+	{
+		if (NULL != pHandle[i])
+		{
+			mali_gralloc_ion_free((private_handle_t *)(pHandle[i]));
+		}
+	}
+
+	return;
+}
+
+void mali_gralloc_ion_sync(const mali_gralloc_module *m, private_handle_t *hnd)
+{
+	if (!gralloc_legacy_ion)
+		return;
+
+	if (m != NULL && hnd != NULL)
+	{
+		switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+		{
+		case private_handle_t::PRIV_FLAGS_USES_ION:
+			if (!(hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP))
+			{
+				ion_sync_fd(m->ion_client, hnd->share_fd);
+			}
+
+			break;
+		}
+	}
+}
+
+int mali_gralloc_ion_map(private_handle_t *hnd)
+{
+	int retval = -EINVAL;
+
+	switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+	{
+	case private_handle_t::PRIV_FLAGS_USES_ION:
+		unsigned char *mappedAddress;
+		size_t size = hnd->size;
+		hw_module_t *pmodule = NULL;
+		private_module_t *m = NULL;
+
+		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
+		{
+			m = reinterpret_cast<private_module_t *>(pmodule);
+		}
+		else
+		{
+			AERR("Could not get gralloc module for handle: %p", hnd);
+			retval = -errno;
+			break;
+		}
+
+		/* the test condition is set to m->ion_client <= 0 here, because:
+		 * 1) module structure are initialized to 0 if no initial value is applied
+		 * 2) a second user process should get a ion fd greater than 0.
+		 */
+		if (m->ion_client <= 0)
+		{
+			/* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/
+			m->ion_client = ion_open();
+
+			if (m->ion_client < 0)
+			{
+				AERR("Could not open ion device for handle: %p", hnd);
+				retval = -errno;
+				break;
+			}
+		}
+
+		mappedAddress = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);
+
+		if (MAP_FAILED == mappedAddress)
+		{
+			AERR("mmap( share_fd:%d ) failed with %s", hnd->share_fd, strerror(errno));
+			retval = -errno;
+			break;
+		}
+
+		hnd->base = (void *)(uintptr_t(mappedAddress) + hnd->offset);
+		retval = 0;
+		break;
+	}
+
+	return retval;
+}
+
+void mali_gralloc_ion_unmap(private_handle_t *hnd)
+{
+	switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+	{
+	case private_handle_t::PRIV_FLAGS_USES_ION:
+		void *base = (void *)hnd->base;
+		size_t size = hnd->size;
+
+		if (munmap(base, size) < 0)
+		{
+			AERR("Could not munmap base:%p size:%zd '%s'", base, size, strerror(errno));
+		}
+
+		break;
+	}
+}
+
+int mali_gralloc_ion_device_close(struct hw_device_t *device)
+{
+#if GRALLOC_USE_GRALLOC1_API == 1
+	gralloc1_device_t *dev = reinterpret_cast<gralloc1_device_t *>(device);
+#else
+	alloc_device_t *dev = reinterpret_cast<alloc_device_t *>(device);
+#endif
+
+	if (dev)
+	{
+		private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
+
+		if (m->ion_client != -1)
+		{
+			if (0 != ion_close(m->ion_client))
+			{
+				AERR("Failed to close ion_client: %d err=%s", m->ion_client, strerror(errno));
+			}
+
+			m->ion_client = -1;
+		}
+
+		delete dev;
+	}
+
+	return 0;
+}
diff --git a/gralloc960/mali_gralloc_ion.h b/gralloc960/mali_gralloc_ion.h
new file mode 100644
index 0000000..015e8a3
--- /dev/null
+++ b/gralloc960/mali_gralloc_ion.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MALI_GRALLOC_ION_H_
+#define MALI_GRALLOC_ION_H_
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_bufferdescriptor.h"
+
+int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors,
+                              uint32_t numDescriptors, buffer_handle_t *pHandle, bool *alloc_from_backing_store);
+void mali_gralloc_ion_free(private_handle_t const *hnd);
+void mali_gralloc_ion_sync(const mali_gralloc_module *m, private_handle_t *hnd);
+int mali_gralloc_ion_map(private_handle_t *hnd);
+void mali_gralloc_ion_unmap(private_handle_t *hnd);
+int mali_gralloc_ion_device_close(struct hw_device_t *device);
+
+#endif /* MALI_GRALLOC_ION_H_ */
diff --git a/gralloc960/mali_gralloc_module.cpp b/gralloc960/mali_gralloc_module.cpp
new file mode 100644
index 0000000..eea6bdb
--- /dev/null
+++ b/gralloc960/mali_gralloc_module.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <inttypes.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <hardware/hardware.h>
+#include <hardware/fb.h>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+#include "gralloc_helper.h"
+#include "framebuffer_device.h"
+#include "gralloc_buffer_priv.h"
+#include "mali_gralloc_formats.h"
+#include "mali_gralloc_usages.h"
+#include "mali_gralloc_bufferaccess.h"
+#include "mali_gralloc_reference.h"
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include "mali_gralloc_public_interface.h"
+#else
+#include "legacy/alloc_device.h"
+#endif
+
+static int mali_gralloc_module_device_open(const hw_module_t *module, const char *name, hw_device_t **device)
+{
+	int status = -EINVAL;
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+
+	if (!strncmp(name, GRALLOC_HARDWARE_MODULE_ID, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
+	{
+		status = mali_gralloc_device_open(module, name, device);
+	}
+
+#else
+
+	if (!strncmp(name, GRALLOC_HARDWARE_GPU0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
+	{
+		status = alloc_device_open(module, name, device);
+	}
+
+#endif
+	else if (!strncmp(name, GRALLOC_HARDWARE_FB0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
+	{
+		status = framebuffer_device_open(module, name, device);
+	}
+
+	return status;
+}
+
+static int gralloc_register_buffer(gralloc_module_t const *module, buffer_handle_t handle)
+{
+	const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module);
+
+	return mali_gralloc_reference_retain(m, handle);
+}
+
+static int gralloc_unregister_buffer(gralloc_module_t const *module, buffer_handle_t handle)
+{
+	const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module);
+
+	return mali_gralloc_reference_release(m, handle, false);
+}
+
+static int gralloc_lock(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h,
+                        void **vaddr)
+{
+	const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module);
+
+	return mali_gralloc_lock(m, handle, usage, l, t, w, h, vaddr);
+}
+
+static int gralloc_lock_ycbcr(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w,
+                              int h, android_ycbcr *ycbcr)
+{
+	const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module);
+
+	return mali_gralloc_lock_ycbcr(m, handle, usage, l, t, w, h, ycbcr);
+}
+
+static int gralloc_unlock(gralloc_module_t const *module, buffer_handle_t handle)
+{
+	const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module);
+
+	return mali_gralloc_unlock(m, handle);
+}
+
+static int gralloc_lock_async(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w,
+                              int h, void **vaddr, int32_t fence_fd)
+{
+	const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module);
+
+	return mali_gralloc_lock_async(m, handle, usage, l, t, w, h, vaddr, fence_fd);
+}
+
+static int gralloc_lock_ycbcr_async(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t,
+                                    int w, int h, android_ycbcr *ycbcr, int32_t fence_fd)
+{
+	const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module);
+
+	return mali_gralloc_lock_ycbcr_async(m, handle, usage, l, t, w, h, ycbcr, fence_fd);
+}
+
+static int gralloc_unlock_async(gralloc_module_t const *module, buffer_handle_t handle, int32_t *fence_fd)
+{
+	const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module);
+
+	return mali_gralloc_unlock_async(m, handle, fence_fd);
+}
+
+// There is one global instance of the module
+
+static struct hw_module_methods_t mali_gralloc_module_methods = { mali_gralloc_module_device_open };
+
+private_module_t::private_module_t()
+{
+#define INIT_ZERO(obj) (memset(&(obj), 0, sizeof((obj))))
+	base.common.tag = HARDWARE_MODULE_TAG;
+#if GRALLOC_USE_GRALLOC1_API == 1
+	base.common.version_major = GRALLOC_MODULE_API_VERSION_1_0;
+#else
+	base.common.version_major = GRALLOC_MODULE_API_VERSION_0_3;
+#endif
+	base.common.version_minor = 0;
+	base.common.id = GRALLOC_HARDWARE_MODULE_ID;
+	base.common.name = "Graphics Memory Allocator Module";
+	base.common.author = "ARM Ltd.";
+	base.common.methods = &mali_gralloc_module_methods;
+	base.common.dso = NULL;
+	INIT_ZERO(base.common.reserved);
+
+#if GRALLOC_USE_GRALLOC1_API == 0
+	base.registerBuffer = gralloc_register_buffer;
+	base.unregisterBuffer = gralloc_unregister_buffer;
+	base.lock = gralloc_lock;
+	base.lock_ycbcr = gralloc_lock_ycbcr;
+	base.unlock = gralloc_unlock;
+	base.lockAsync = gralloc_lock_async;
+	base.lockAsync_ycbcr = gralloc_lock_ycbcr_async;
+	base.unlockAsync = gralloc_unlock_async;
+	base.perform = NULL;
+	INIT_ZERO(base.reserved_proc);
+#endif
+
+	framebuffer = NULL;
+	flags = 0;
+	numBuffers = 0;
+	bufferMask = 0;
+	pthread_mutex_init(&(lock), NULL);
+	currentBuffer = NULL;
+	INIT_ZERO(info);
+	INIT_ZERO(finfo);
+	xdpi = 0.0f;
+	ydpi = 0.0f;
+	fps = 0.0f;
+	swapInterval = 1;
+	ion_client = -1;
+
+#undef INIT_ZERO
+};
+
+/*
+ * HAL_MODULE_INFO_SYM will be initialized using the default constructor
+ * implemented above
+ */
+struct private_module_t HAL_MODULE_INFO_SYM;
diff --git a/gralloc960/mali_gralloc_module.h b/gralloc960/mali_gralloc_module.h
new file mode 100644
index 0000000..53e08e5
--- /dev/null
+++ b/gralloc960/mali_gralloc_module.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MALI_GRALLOC_MODULE_H_
+#define MALI_GRALLOC_MODULE_H_
+
+#include <linux/fb.h>
+#include <pthread.h>
+
+typedef enum
+{
+	MALI_DPY_TYPE_UNKNOWN = 0,
+	MALI_DPY_TYPE_CLCD,
+	MALI_DPY_TYPE_HDLCD
+} mali_dpy_type;
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+typedef struct
+{
+	struct hw_module_t common;
+} gralloc_module_t;
+
+/*
+ * Most gralloc code is fairly version agnostic, but certain
+ * places still use old usage defines. Make sure it works
+ * ok for usages that are backwards compatible.
+ */
+#define GRALLOC_USAGE_PRIVATE_0 GRALLOC1_CONSUMER_USAGE_PRIVATE_0
+#define GRALLOC_USAGE_PRIVATE_1 GRALLOC1_CONSUMER_USAGE_PRIVATE_1
+#define GRALLOC_USAGE_PRIVATE_2 GRALLOC1_CONSUMER_USAGE_PRIVATE_2
+#define GRALLOC_USAGE_PRIVATE_3 GRALLOC1_CONSUMER_USAGE_PRIVATE_3
+
+#define GRALLOC_USAGE_SW_WRITE_RARELY GRALLOC1_PRODUCER_USAGE_CPU_WRITE
+#define GRALLOC_USAGE_SW_WRITE_OFTEN GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN
+#define GRALLOC_USAGE_SW_READ_RARELY GRALLOC1_CONSUMER_USAGE_CPU_READ
+#define GRALLOC_USAGE_SW_READ_OFTEN GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN
+#define GRALLOC_USAGE_HW_FB GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET
+#define GRALLOC_USAGE_HW_2D 0x00000400
+
+#define GRALLOC_USAGE_SW_WRITE_MASK 0x000000F0
+#define GRALLOC_USAGE_SW_READ_MASK 0x0000000F
+#define GRALLOC_USAGE_PROTECTED GRALLOC1_PRODUCER_USAGE_PROTECTED
+#define GRALLOC_USAGE_HW_RENDER GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET
+#define GRALLOC_USAGE_HW_CAMERA_MASK (GRALLOC1_CONSUMER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_CAMERA)
+#define GRALLOC_USAGE_HW_TEXTURE GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE
+#define GRALLOC_USAGE_HW_VIDEO_ENCODER GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER
+#define GRALLOC_USAGE_HW_COMPOSER GRALLOC1_CONSUMER_USAGE_HWCOMPOSER
+#define GRALLOC_USAGE_EXTERNAL_DISP 0x00002000
+
+#endif
+
+struct private_module_t
+{
+	gralloc_module_t base;
+
+	struct private_handle_t *framebuffer;
+	uint32_t flags;
+	uint32_t numBuffers;
+	uint32_t bufferMask;
+	pthread_mutex_t lock;
+	buffer_handle_t currentBuffer;
+	int ion_client;
+	mali_dpy_type dpy_type;
+
+	struct fb_var_screeninfo info;
+	struct fb_fix_screeninfo finfo;
+	float xdpi;
+	float ydpi;
+	float fps;
+	int swapInterval;
+
+#ifdef __cplusplus
+	/* Never intended to be used from C code */
+	enum
+	{
+		// flag to indicate we'll post this buffer
+		PRIV_USAGE_LOCKED_FOR_POST = 0x80000000
+	};
+#endif
+
+#ifdef __cplusplus
+	/* default constructor */
+	private_module_t();
+#endif
+};
+typedef struct private_module_t mali_gralloc_module;
+
+#endif /* MALI_GRALLOC_MODULE_H_ */
diff --git a/gralloc960/mali_gralloc_private_interface.cpp b/gralloc960/mali_gralloc_private_interface.cpp
new file mode 100644
index 0000000..2f84e37
--- /dev/null
+++ b/gralloc960/mali_gralloc_private_interface.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc1.h>
+
+#include "mali_gralloc_private_interface.h"
+#include "mali_gralloc_buffer.h"
+#include "gralloc_helper.h"
+#include "gralloc_buffer_priv.h"
+#include "mali_gralloc_bufferdescriptor.h"
+
+#define CHECK_FUNCTION(A, B, C)                    \
+	do                                             \
+	{                                              \
+		if (A == B)                                \
+			return (gralloc1_function_pointer_t)C; \
+	} while (0)
+
+static int32_t mali_gralloc_private_get_buff_int_fmt(gralloc1_device_t *device, buffer_handle_t handle,
+                                                     uint64_t *internal_format)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || internal_format == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*internal_format = hnd->internal_format;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_buff_fd(gralloc1_device_t *device, buffer_handle_t handle, int *fd)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || fd == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*fd = hnd->share_fd;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_buff_int_dims(gralloc1_device_t *device, buffer_handle_t handle,
+                                                      int *internalWidth, int *internalHeight)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || internalWidth == NULL || internalHeight == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*internalWidth = hnd->internalWidth;
+	*internalHeight = hnd->internalHeight;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_buff_offset(gralloc1_device_t *device, buffer_handle_t handle, int64_t *offset)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || offset == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*offset = hnd->offset;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_buff_bytestride(gralloc1_device_t *device, buffer_handle_t handle,
+                                                        int *bytestride)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || bytestride == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*bytestride = hnd->byte_stride;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_buff_yuvinfo(gralloc1_device_t *device, buffer_handle_t handle,
+                                                     mali_gralloc_yuv_info *yuvinfo)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || yuvinfo == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*yuvinfo = hnd->yuv_info;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_buff_size(gralloc1_device_t *device, buffer_handle_t handle, int *size)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || size == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*size = hnd->size;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_buff_flags(gralloc1_device_t *device, buffer_handle_t handle, int *flags)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || flags == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*flags = hnd->flags;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_buff_min_page_size(gralloc1_device_t *device, buffer_handle_t handle,
+                                                           int *min_pgsz)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || min_pgsz == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *hnd = static_cast<const private_handle_t *>(handle);
+	*min_pgsz = hnd->min_pgsz;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_get_attr_param(gralloc1_device_t *device, buffer_handle_t handle, buf_attr attr,
+                                                   int32_t *val, int32_t last_call)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || val == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *const_hnd = static_cast<const private_handle_t *>(handle);
+	private_handle_t *hnd = const_cast<private_handle_t *>(const_hnd);
+
+	if (hnd->attr_base == MAP_FAILED)
+	{
+		if (gralloc_buffer_attr_map(hnd, 1) < 0)
+		{
+			return GRALLOC1_ERROR_BAD_HANDLE;
+		}
+	}
+
+	if (gralloc_buffer_attr_read(hnd, attr, val) < 0)
+	{
+		gralloc_buffer_attr_unmap(hnd);
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	if (last_call)
+	{
+		gralloc_buffer_attr_unmap(hnd);
+	}
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_set_attr_param(gralloc1_device_t *device, buffer_handle_t handle, buf_attr attr,
+                                                   int32_t *val, int32_t last_call)
+{
+	GRALLOC_UNUSED(device);
+
+	if (private_handle_t::validate(handle) < 0 || val == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	const private_handle_t *const_hnd = static_cast<const private_handle_t *>(handle);
+	private_handle_t *hnd = const_cast<private_handle_t *>(const_hnd);
+
+	if (hnd->attr_base == MAP_FAILED)
+	{
+		if (gralloc_buffer_attr_map(hnd, 1) < 0)
+		{
+			return GRALLOC1_ERROR_BAD_HANDLE;
+		}
+	}
+
+	if (gralloc_buffer_attr_write(hnd, attr, val) < 0)
+	{
+		gralloc_buffer_attr_unmap(hnd);
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	if (last_call)
+	{
+		gralloc_buffer_attr_unmap(hnd);
+	}
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_private_set_priv_fmt(gralloc1_device_t *device, gralloc1_buffer_descriptor_t desc,
+                                                 uint64_t internal_format)
+{
+	GRALLOC_UNUSED(device);
+
+	buffer_descriptor_t *priv_desc = reinterpret_cast<buffer_descriptor_t *>(desc);
+
+	if (priv_desc == NULL)
+	{
+		return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+	}
+
+	priv_desc->hal_format = internal_format;
+	priv_desc->format_type = MALI_GRALLOC_FORMAT_TYPE_INTERNAL;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_function_pointer_t mali_gralloc_private_interface_getFunction(int32_t descriptor)
+{
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_INT_FMT, mali_gralloc_private_get_buff_int_fmt);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_FD, mali_gralloc_private_get_buff_fd);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_INTERNAL_DIMS, mali_gralloc_private_get_buff_int_dims);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_OFFSET, mali_gralloc_private_get_buff_offset);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_BYTESTRIDE, mali_gralloc_private_get_buff_bytestride);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_YUVINFO, mali_gralloc_private_get_buff_yuvinfo);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_SIZE, mali_gralloc_private_get_buff_size);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_FLAGS, mali_gralloc_private_get_buff_flags);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_MIN_PAGESIZE,
+	               mali_gralloc_private_get_buff_min_page_size);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_ATTR_PARAM, mali_gralloc_private_get_attr_param);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_SET_ATTR_PARAM, mali_gralloc_private_set_attr_param);
+	CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_SET_PRIV_FMT, mali_gralloc_private_set_priv_fmt);
+
+	return NULL;
+}
diff --git a/gralloc960/mali_gralloc_private_interface.h b/gralloc960/mali_gralloc_private_interface.h
new file mode 100644
index 0000000..5f9428a
--- /dev/null
+++ b/gralloc960/mali_gralloc_private_interface.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MALI_GRALLOC_PRIVATE_INTERFACE_H_
+#define MALI_GRALLOC_PRIVATE_INTERFACE_H_
+
+#include "mali_gralloc_private_interface_types.h"
+
+typedef enum
+{
+
+	MALI_GRALLOC1_LAST_PUBLIC_FUNCTION = GRALLOC1_LAST_FUNCTION,
+
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_INT_FMT = MALI_GRALLOC1_LAST_PUBLIC_FUNCTION + 100,
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_FD,
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_INTERNAL_DIMS,
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_OFFSET,
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_BYTESTRIDE,
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_YUVINFO,
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_SIZE,
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_FLAGS,
+	MALI_GRALLOC1_FUNCTION_GET_BUFF_MIN_PAGESIZE,
+	MALI_GRALLOC1_FUNCTION_SET_PRIV_FMT,
+
+	/* API related to the shared attribute region */
+	MALI_GRALLOC1_FUNCTION_GET_ATTR_PARAM,
+	MALI_GRALLOC1_FUNCTION_SET_ATTR_PARAM,
+
+	MALI_GRALLOC1_LAST_PRIVATE_FUNCTION
+} mali_gralloc1_function_descriptor_t;
+
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_INT_FMT)(gralloc1_device_t *device, buffer_handle_t handle,
+                                                         uint64_t *internal_format);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_FD)(gralloc1_device_t *device, buffer_handle_t handle, int *fd);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_INTERNAL_DIMS)(gralloc1_device_t *device, buffer_handle_t handle,
+                                                               int *internalWidth, int *internalHeight);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_OFFSET)(gralloc1_device_t *device, buffer_handle_t handle,
+                                                        int64_t *offset);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_BYTESTRIDE)(gralloc1_device_t *device, buffer_handle_t handle,
+                                                            int *bytestride);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_YUVINFO)(gralloc1_device_t *device, buffer_handle_t handle,
+                                                         mali_gralloc_yuv_info *yuvinfo);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_SIZE)(gralloc1_device_t *device, buffer_handle_t handle, int *size);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_FLAGS)(gralloc1_device_t *device, buffer_handle_t handle, int *flags);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_MIN_PAGESIZE)(gralloc1_device_t *device, buffer_handle_t handle,
+                                                              int *min_pgsz);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_ATTR_PARAM)(gralloc1_device_t *device, buffer_handle_t handle, buf_attr attr,
+                                                       int32_t *val, int32_t last_call);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_SET_ATTR_PARAM)(gralloc1_device_t *device, buffer_handle_t handle, buf_attr attr,
+                                                       int32_t *val, int32_t last_call);
+typedef int32_t (*GRALLOC1_PFN_PRIVATE_SET_PRIV_FMT)(gralloc1_device_t *device, gralloc1_buffer_descriptor_t desc,
+                                                     uint64_t internal_format);
+
+#if defined(GRALLOC_LIBRARY_BUILD)
+gralloc1_function_pointer_t mali_gralloc_private_interface_getFunction(int32_t descriptor);
+#endif
+
+#endif /* MALI_GRALLOC_PRIVATE_INTERFACE_H_ */
diff --git a/gralloc960/mali_gralloc_private_interface_types.h b/gralloc960/mali_gralloc_private_interface_types.h
new file mode 100644
index 0000000..eb644a6
--- /dev/null
+++ b/gralloc960/mali_gralloc_private_interface_types.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2017 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MALI_GRALLOC_PRIVATE_INTERFACE_TYPES_H_
+#define MALI_GRALLOC_PRIVATE_INTERFACE_TYPES_H_
+
+#define GRALLOC_ARM_BUFFER_ATTR_HDR_INFO_SUPPORT
+
+typedef enum
+{
+	MALI_HDR_NO_INFO,
+	MALI_HDR_ST2084,
+	MALI_HDR_HLG,
+	MALI_HDR_LAST
+} mali_transfer_function;
+
+typedef struct
+{
+	//values are in units of 0.00002
+	uint16_t x;
+	uint16_t y;
+} primaries;
+
+typedef struct
+{
+	primaries r;
+	primaries g;
+	primaries b;
+	primaries w;
+	uint16_t minDisplayLuminance; // in cd/m^2
+	uint16_t maxDisplayLuminance; // in 0.0001 cd/m^2
+	uint16_t maxContentLightLevel; // in cd/m^2
+	uint16_t maxFrameAverageLightLevel; // in cd/m^2
+	mali_transfer_function eotf;
+} mali_hdr_info;
+
+enum
+{
+	/* CROP_RECT and YUV_TRANS are intended to be
+	 * written by producers and read by consumers.
+	 * A producer should write these parameters before
+	 * it queues a buffer to the consumer.
+	 */
+
+	/* CROP RECT, defined as an int array of top, left, height, width. Origin in top-left corner */
+	GRALLOC_ARM_BUFFER_ATTR_CROP_RECT = 1,
+
+	/* Set if the AFBC format used a YUV transform before compressing */
+	GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS = 2,
+
+	/* Set if the AFBC format uses sparse allocation */
+	GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC = 3,
+
+	/* HDR Informations*/
+	GRALLOC_ARM_BUFFER_ATTR_HDR_INFO = 4,
+
+	GRALLOC_ARM_BUFFER_ATTR_LAST
+};
+
+typedef uint32_t buf_attr;
+
+typedef enum
+{
+	MALI_YUV_NO_INFO,
+	MALI_YUV_BT601_NARROW,
+	MALI_YUV_BT601_WIDE,
+	MALI_YUV_BT709_NARROW,
+	MALI_YUV_BT709_WIDE
+} mali_gralloc_yuv_info;
+
+#endif /* MALI_GRALLOC_PRIVATE_INTERFACE_TYPES_H_ */
diff --git a/gralloc960/mali_gralloc_public_interface.cpp b/gralloc960/mali_gralloc_public_interface.cpp
new file mode 100644
index 0000000..9475d82
--- /dev/null
+++ b/gralloc960/mali_gralloc_public_interface.cpp
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2016 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <hardware/hardware.h>
+#include <hardware/gralloc1.h>
+
+#include "mali_gralloc_module.h"
+
+#include "mali_gralloc_private_interface.h"
+#include "mali_gralloc_buffer.h"
+#include "mali_gralloc_ion.h"
+#include "mali_gralloc_bufferdescriptor.h"
+#include "mali_gralloc_bufferallocation.h"
+#include "mali_gralloc_reference.h"
+#include "mali_gralloc_bufferaccess.h"
+#include "framebuffer_device.h"
+#include "gralloc_buffer_priv.h"
+#include "mali_gralloc_debug.h"
+
+typedef struct mali_gralloc_func
+{
+	gralloc1_function_descriptor_t desc;
+	gralloc1_function_pointer_t func;
+} mali_gralloc_func;
+
+static void mali_gralloc_dump(gralloc1_device_t *device, uint32_t *outSize, char *outBuffer)
+{
+	if (NULL == outSize)
+	{
+		ALOGE("Invalid pointer to outSize and return");
+		return;
+	}
+
+	mali_gralloc_dump_internal(outSize, outBuffer);
+	GRALLOC_UNUSED(device);
+}
+
+static int32_t mali_gralloc_create_descriptor(gralloc1_device_t *device, gralloc1_buffer_descriptor_t *outDescriptor)
+{
+	int ret = 0;
+	ret = mali_gralloc_create_descriptor_internal(outDescriptor);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_destroy_descriptor(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor)
+{
+	int ret = 0;
+	ret = mali_gralloc_destroy_descriptor_internal(descriptor);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_set_consumer_usage(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor,
+                                               /*uint64_t */ gralloc1_consumer_usage_t usage)
+{
+	int ret = 0;
+	ret = mali_gralloc_set_consumerusage_internal(descriptor, usage);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_set_dimensions(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor,
+                                           uint32_t width, uint32_t height)
+{
+	int ret = 0;
+	ret = mali_gralloc_set_dimensions_internal(descriptor, width, height);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_set_format(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor,
+                                       /*int32_t*/ android_pixel_format_t format)
+{
+	int ret = 0;
+	ret = mali_gralloc_set_format_internal(descriptor, format);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_set_producer_usage(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor,
+                                               /*uint64_t */ gralloc1_producer_usage_t usage)
+{
+	int ret = 0;
+	ret = mali_gralloc_set_producerusage_internal(descriptor, usage);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_get_backing_store(gralloc1_device_t *device, buffer_handle_t buffer,
+                                              gralloc1_backing_store_t *outStore)
+{
+	int ret = 0;
+	ret = mali_gralloc_get_backing_store_internal(buffer, outStore);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_get_consumer_usage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                               uint64_t * /*gralloc1_consumer_usage_t*/ outUsage)
+{
+	int ret = 0;
+	ret = mali_gralloc_get_consumer_usage_internal(buffer, outUsage);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_get_dimensions(gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *outWidth,
+                                           uint32_t *outHeight)
+{
+	int ret = 0;
+	ret = mali_gralloc_get_dimensions_internal(buffer, outWidth, outHeight);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_get_format(gralloc1_device_t *device, buffer_handle_t buffer, int32_t *outFormat)
+{
+	int ret = 0;
+	ret = mali_gralloc_get_format_internal(buffer, outFormat);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_get_producer_usage(gralloc1_device_t *device, buffer_handle_t buffer,
+                                               uint64_t * /*gralloc1_producer_usage_t*/ outUsage)
+{
+	int ret = 0;
+	ret = mali_gralloc_get_producer_usage_internal(buffer, outUsage);
+	GRALLOC_UNUSED(device);
+	return ret;
+}
+
+static int32_t mali_gralloc_get_stride(gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *outStride)
+{
+	GRALLOC_UNUSED(device);
+
+	int stride;
+
+	if (mali_gralloc_query_getstride(buffer, &stride) < 0)
+	{
+		return GRALLOC1_ERROR_UNSUPPORTED;
+	}
+
+	*outStride = (uint32_t)stride;
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_allocate(gralloc1_device_t *device, uint32_t numDescriptors,
+                                     const gralloc1_buffer_descriptor_t *descriptors, buffer_handle_t *outBuffers)
+{
+	mali_gralloc_module *m;
+	m = reinterpret_cast<private_module_t *>(device->common.module);
+	buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(*descriptors);
+	uint64_t usage;
+	bool shared = false;
+
+	usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
+
+#if DISABLE_FRAMEBUFFER_HAL != 1
+
+	if (usage & GRALLOC_USAGE_HW_FB)
+	{
+		int byte_stride;
+		int pixel_stride;
+		int width, height;
+		uint64_t format;
+
+		format = bufDescriptor->hal_format;
+		width = bufDescriptor->width;
+		height = bufDescriptor->height;
+
+#if GRALLOC_FB_SWAP_RED_BLUE == 1
+#ifdef GRALLOC_16_BITS
+		format = HAL_PIXEL_FORMAT_RGB_565;
+#else
+		format = HAL_PIXEL_FORMAT_BGRA_8888;
+#endif
+#endif
+
+		if (fb_alloc_framebuffer(m, bufDescriptor->consumer_usage, bufDescriptor->producer_usage, outBuffers,
+		                         &pixel_stride, &byte_stride) < 0)
+		{
+			return GRALLOC1_ERROR_NO_RESOURCES;
+		}
+		else
+		{
+			private_handle_t *hnd = (private_handle_t *)*outBuffers;
+
+			/* Allocate a meta-data buffer for framebuffer too. fbhal
+			 * ones wont need it but for hwc they will.
+			 *
+			 * Explicitly ignore allocation errors since it is not critical to have
+			 */
+			(void)gralloc_buffer_attr_allocate(hnd);
+
+			hnd->req_format = format;
+			hnd->yuv_info = MALI_YUV_BT601_NARROW;
+			hnd->internal_format = format;
+			hnd->byte_stride = byte_stride;
+			hnd->width = width;
+			hnd->height = height;
+			hnd->stride = pixel_stride;
+			hnd->internalWidth = width;
+			hnd->internalHeight = height;
+		}
+	}
+	else
+#endif
+	{
+		if (mali_gralloc_buffer_allocate(m, (gralloc_buffer_descriptor_t *)descriptors, numDescriptors, outBuffers,
+		                                 &shared) < 0)
+		{
+			ALOGE("Failed to allocate buffer.");
+			return GRALLOC1_ERROR_NO_RESOURCES;
+		}
+
+		if (!shared && 1 != numDescriptors)
+		{
+			return GRALLOC1_ERROR_NOT_SHARED;
+		}
+	}
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_retain(gralloc1_device_t *device, buffer_handle_t buffer)
+{
+	mali_gralloc_module *m;
+	m = reinterpret_cast<private_module_t *>(device->common.module);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	if (mali_gralloc_reference_retain(m, buffer) < 0)
+	{
+		return GRALLOC1_ERROR_NO_RESOURCES;
+	}
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc_release(gralloc1_device_t *device, buffer_handle_t buffer)
+{
+	mali_gralloc_module *m;
+	m = reinterpret_cast<private_module_t *>(device->common.module);
+
+	if (mali_gralloc_reference_release(m, buffer, true) < 0)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc1_get_num_flex_planes(gralloc1_device_t *device, buffer_handle_t buffer,
+                                                 uint32_t *outNumPlanes)
+{
+	mali_gralloc_module *m;
+	m = reinterpret_cast<private_module_t *>(device->common.module);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	if (mali_gralloc_get_num_flex_planes(m, buffer, outNumPlanes) < 0)
+	{
+		return GRALLOC1_ERROR_UNSUPPORTED;
+	}
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc1_lock_async(gralloc1_device_t *device, buffer_handle_t buffer,
+                                        uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
+                                        uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
+                                        const gralloc1_rect_t *accessRegion, void **outData, int32_t acquireFence)
+{
+	mali_gralloc_module *m;
+	m = reinterpret_cast<private_module_t *>(device->common.module);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	if (!((producerUsage | consumerUsage) & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)))
+	{
+		return GRALLOC1_ERROR_BAD_VALUE;
+	}
+
+	if (mali_gralloc_lock_async(m, buffer, producerUsage | consumerUsage, accessRegion->left, accessRegion->top,
+	                            accessRegion->width, accessRegion->height, outData, acquireFence) < 0)
+	{
+		return GRALLOC1_ERROR_UNSUPPORTED;
+	}
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc1_lock_flex_async(gralloc1_device_t *device, buffer_handle_t buffer,
+                                             uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
+                                             uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
+                                             const gralloc1_rect_t *accessRegion,
+                                             struct android_flex_layout *outFlexLayout, int32_t acquireFence)
+{
+	mali_gralloc_module *m;
+	m = reinterpret_cast<private_module_t *>(device->common.module);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	if (!((producerUsage | consumerUsage) & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)))
+	{
+		return GRALLOC1_ERROR_BAD_VALUE;
+	}
+
+	if (mali_gralloc_lock_flex_async(m, buffer, producerUsage | consumerUsage, accessRegion->left, accessRegion->top,
+	                                 accessRegion->width, accessRegion->height, outFlexLayout, acquireFence) < 0)
+	{
+		return GRALLOC1_ERROR_UNSUPPORTED;
+	}
+
+	return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t mali_gralloc1_unlock_async(gralloc1_device_t *device, buffer_handle_t buffer, int32_t *outReleaseFence)
+{
+	mali_gralloc_module *m;
+	m = reinterpret_cast<private_module_t *>(device->common.module);
+
+	if (private_handle_t::validate(buffer) < 0)
+	{
+		return GRALLOC1_ERROR_BAD_HANDLE;
+	}
+
+	mali_gralloc_unlock_async(m, buffer, outReleaseFence);
+	return GRALLOC1_ERROR_NONE;
+}
+
+static const mali_gralloc_func mali_gralloc_func_list[] = {
+	{ GRALLOC1_FUNCTION_DUMP, (gralloc1_function_pointer_t)mali_gralloc_dump },
+	{ GRALLOC1_FUNCTION_CREATE_DESCRIPTOR, (gralloc1_function_pointer_t)mali_gralloc_create_descriptor },
+	{ GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR, (gralloc1_function_pointer_t)mali_gralloc_destroy_descriptor },
+	{ GRALLOC1_FUNCTION_SET_CONSUMER_USAGE, (gralloc1_function_pointer_t)mali_gralloc_set_consumer_usage },
+	{ GRALLOC1_FUNCTION_SET_DIMENSIONS, (gralloc1_function_pointer_t)mali_gralloc_set_dimensions },
+	{ GRALLOC1_FUNCTION_SET_FORMAT, (gralloc1_function_pointer_t)mali_gralloc_set_format },
+	{ GRALLOC1_FUNCTION_SET_PRODUCER_USAGE, (gralloc1_function_pointer_t)mali_gralloc_set_producer_usage },
+	{ GRALLOC1_FUNCTION_GET_BACKING_STORE, (gralloc1_function_pointer_t)mali_gralloc_get_backing_store },
+	{ GRALLOC1_FUNCTION_GET_CONSUMER_USAGE, (gralloc1_function_pointer_t)mali_gralloc_get_consumer_usage },
+	{ GRALLOC1_FUNCTION_GET_DIMENSIONS, (gralloc1_function_pointer_t)mali_gralloc_get_dimensions },
+	{ GRALLOC1_FUNCTION_GET_FORMAT, (gralloc1_function_pointer_t)mali_gralloc_get_format },
+	{ GRALLOC1_FUNCTION_GET_PRODUCER_USAGE, (gralloc1_function_pointer_t)mali_gralloc_get_producer_usage },
+	{ GRALLOC1_FUNCTION_GET_STRIDE, (gralloc1_function_pointer_t)mali_gralloc_get_stride },
+	{ GRALLOC1_FUNCTION_ALLOCATE, (gralloc1_function_pointer_t)mali_gralloc_allocate },
+	{ GRALLOC1_FUNCTION_RETAIN, (gralloc1_function_pointer_t)mali_gralloc_retain },
+	{ GRALLOC1_FUNCTION_RELEASE, (gralloc1_function_pointer_t)mali_gralloc_release },
+	{ GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES, (gralloc1_function_pointer_t)mali_gralloc1_get_num_flex_planes },
+	{ GRALLOC1_FUNCTION_LOCK, (gralloc1_function_pointer_t)mali_gralloc1_lock_async },
+	{ GRALLOC1_FUNCTION_LOCK_FLEX, (gralloc1_function_pointer_t)mali_gralloc1_lock_flex_async },
+	{ GRALLOC1_FUNCTION_UNLOCK, (gralloc1_function_pointer_t)mali_gralloc1_unlock_async },
+
+	/* GRALLOC1_FUNCTION_INVALID has to be the last descriptor on the list. */
+	{ GRALLOC1_FUNCTION_INVALID, NULL }
+};
+
+static void mali_gralloc_getCapabilities(gralloc1_device_t *dev, uint32_t *outCount, int32_t *outCapabilities)
+{
+	GRALLOC_UNUSED(dev);
+	GRALLOC_UNUSED(outCapabilities);
+
+	if (outCount != NULL)
+	{
+		*outCount = 0;
+	}
+}
+
+static gralloc1_function_pointer_t mali_gralloc_getFunction(gralloc1_device_t *dev, int32_t descriptor)
+{
+	GRALLOC_UNUSED(dev);
+	gralloc1_function_pointer_t rval = NULL;
+	uint32_t pos = 0;
+
+	while (mali_gralloc_func_list[pos].desc != GRALLOC1_FUNCTION_INVALID)
+	{
+		if (mali_gralloc_func_list[pos].desc == descriptor)
+		{
+			rval = mali_gralloc_func_list[pos].func;
+			break;
+		}
+
+		pos++;
+	}
+
+	if (rval == NULL)
+	{
+		rval = mali_gralloc_private_interface_getFunction(descriptor);
+	}
+
+	return rval;
+}
+
+int mali_gralloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
+{
+	gralloc1_device_t *dev;
+
+	GRALLOC_UNUSED(name);
+
+	dev = new gralloc1_device_t;
+
+	if (NULL == dev)
+	{
+		return -1;
+	}
+
+	/* initialize our state here */
+	memset(dev, 0, sizeof(*dev));
+
+	/* initialize the procs */
+	dev->common.tag = HARDWARE_DEVICE_TAG;
+	dev->common.version = 0;
+	dev->common.module = const_cast<hw_module_t *>(module);
+	dev->common.close = mali_gralloc_ion_device_close;
+
+	dev->getCapabilities = mali_gralloc_getCapabilities;
+	dev->getFunction = mali_gralloc_getFunction;
+
+	*device = &dev->common;
+
+	return 0;
+}
diff --git a/gralloc960/mali_gralloc_public_interface.h b/gralloc960/mali_gralloc_public_interface.h
new file mode 100644
index 0000000..b35d11c
--- /dev/null
+++ b/gralloc960/mali_gralloc_public_interface.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MALI_GRALLOC_PUBLIC_INTERFACE_H_
+#define MALI_GRALLOC_PUBLIC_INTERFACE_H_
+
+#include <hardware/hardware.h>
+
+int mali_gralloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device);
+
+#endif /* MALI_GRALLOC_PUBLIC_INTERFACE_H_ */
diff --git a/gralloc960/mali_gralloc_reference.cpp b/gralloc960/mali_gralloc_reference.cpp
new file mode 100644
index 0000000..826a391
--- /dev/null
+++ b/gralloc960/mali_gralloc_reference.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hardware/hardware.h>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+#include "mali_gralloc_ion.h"
+#include "gralloc_buffer_priv.h"
+#include "mali_gralloc_bufferallocation.h"
+#include "mali_gralloc_debug.h"
+
+static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER;
+
+int mali_gralloc_reference_retain(mali_gralloc_module const *module, buffer_handle_t handle)
+{
+	GRALLOC_UNUSED(module);
+
+	if (private_handle_t::validate(handle) < 0)
+	{
+		AERR("Registering/Retaining invalid buffer %p, returning error", handle);
+		return -EINVAL;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)handle;
+	pthread_mutex_lock(&s_map_lock);
+
+	if (hnd->allocating_pid == getpid() || hnd->remote_pid == getpid())
+	{
+		hnd->ref_count++;
+		pthread_mutex_unlock(&s_map_lock);
+		return 0;
+	}
+	else
+	{
+		hnd->remote_pid = getpid();
+		hnd->ref_count = 1;
+	}
+
+	int retval = -EINVAL;
+
+	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
+	{
+		retval = 0;
+	}
+	else if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_ION))
+	{
+		retval = mali_gralloc_ion_map(hnd);
+	}
+	else
+	{
+		AERR("unkown buffer flags not supported. flags = %d", hnd->flags);
+	}
+
+	pthread_mutex_unlock(&s_map_lock);
+	return retval;
+}
+
+int mali_gralloc_reference_release(mali_gralloc_module const *module, buffer_handle_t handle, bool canFree)
+{
+	GRALLOC_UNUSED(module);
+
+	if (private_handle_t::validate(handle) < 0)
+	{
+		AERR("unregistering/releasing invalid buffer %p, returning error", handle);
+		return -EINVAL;
+	}
+
+	private_handle_t *hnd = (private_handle_t *)handle;
+	pthread_mutex_lock(&s_map_lock);
+
+	if (hnd->ref_count == 0)
+	{
+		AERR("Buffer %p should have already been released", handle);
+		pthread_mutex_unlock(&s_map_lock);
+		return -EINVAL;
+	}
+
+	if (hnd->allocating_pid == getpid())
+	{
+		hnd->ref_count--;
+
+		if (hnd->ref_count == 0 && canFree)
+		{
+
+			if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
+			{
+				close(hnd->fd);
+			}
+			else
+			{
+				mali_gralloc_dump_buffer_erase(hnd);
+			}
+			mali_gralloc_buffer_free(handle);
+			delete handle;
+
+		}
+	}
+	else if (hnd->remote_pid == getpid()) // never unmap buffers that were not imported into this process
+	{
+		hnd->ref_count--;
+
+		if (hnd->ref_count == 0)
+		{
+
+			if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_ION))
+			{
+				mali_gralloc_ion_unmap(hnd);
+			}
+			else
+			{
+				AERR("Unregistering/Releasing unknown buffer is not supported. Flags = %d", hnd->flags);
+			}
+
+			/*
+			 * Close shared attribute region file descriptor. It might seem strange to "free"
+			 * this here since this can happen in a client process, but free here is nothing
+			 * but unmapping and closing the duplicated file descriptor. The original ashmem
+			 * fd instance is still open until alloc_device_free() is called. Even sharing
+			 * of gralloc buffers within the same process should have fds dup:ed.
+			 */
+			gralloc_buffer_attr_free(hnd);
+
+			hnd->base = 0;
+			hnd->writeOwner = 0;
+		}
+	}
+	else
+	{
+		AERR("Trying to unregister buffer %p from process %d that was not imported into current process: %d", hnd,
+		     hnd->remote_pid, getpid());
+	}
+
+	pthread_mutex_unlock(&s_map_lock);
+	return 0;
+}
diff --git a/gralloc960/mali_gralloc_reference.h b/gralloc960/mali_gralloc_reference.h
new file mode 100644
index 0000000..5fa6809
--- /dev/null
+++ b/gralloc960/mali_gralloc_reference.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 ARM Limited. All rights reserved.
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MALI_GRALLOC_REFERENCE_H_
+#define MALI_GRALLOC_REFERENCE_H_
+
+#include "gralloc_priv.h"
+
+int mali_gralloc_reference_retain(mali_gralloc_module const *module, buffer_handle_t handle);
+int mali_gralloc_reference_release(mali_gralloc_module const *module, buffer_handle_t handle, bool canFree);
+
+#endif /* MALI_GRALLOC_REFERENCE_H_ */
diff --git a/gralloc960/mali_gralloc_usages.h b/gralloc960/mali_gralloc_usages.h
new file mode 100644
index 0000000..4f034eb
--- /dev/null
+++ b/gralloc960/mali_gralloc_usages.h
@@ -0,0 +1,92 @@
+/*
+ * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MALI_GRALLOC_USAGES_H_
+#define MALI_GRALLOC_USAGES_H_
+
+/*
+ * Below usage types overlap, this is intentional.
+ * The reason is that for Gralloc 0.3 there are very
+ * few usage flags we have at our disposal.
+ *
+ * The overlapping is handled by processing the definitions
+ * in a specific order.
+ *
+ * MALI_GRALLOC_USAGE_PRIVATE_FORMAT and MALI_GRALLOC_USAGE_NO_AFBC
+ * don't overlap and are processed first.
+ *
+ * MALI_GRALLOC_USAGE_YUV_CONF are only for YUV formats and clients
+ * using MALI_GRALLOC_USAGE_NO_AFBC must never allocate YUV formats.
+ * The latter is strictly enforced and allocations will fail.
+ *
+ * MALI_GRALLOC_USAGE_AFBC_PADDING is only valid if MALI_GRALLOC_USAGE_NO_AFBC
+ * is not present.
+ */
+
+/*
+ * Gralloc private usage 0-3 are the same in 0.3 and 1.0.
+ * We defined based our usages based on what is available.
+ */
+#if defined(GRALLOC_MODULE_API_VERSION_1_0)
+typedef enum
+{
+	/* The client has specified a private format in the format parameter */
+	MALI_GRALLOC_USAGE_PRIVATE_FORMAT = (int)GRALLOC1_PRODUCER_USAGE_PRIVATE_3,
+
+	/* Buffer won't be allocated as AFBC */
+	MALI_GRALLOC_USAGE_NO_AFBC = (int)(GRALLOC1_PRODUCER_USAGE_PRIVATE_1 | GRALLOC1_PRODUCER_USAGE_PRIVATE_2),
+
+	/* Valid only for YUV allocations */
+	MALI_GRALLOC_USAGE_YUV_CONF_0 = 0,
+	MALI_GRALLOC_USAGE_YUV_CONF_1 = (int)GRALLOC1_PRODUCER_USAGE_PRIVATE_1,
+	MALI_GRALLOC_USAGE_YUV_CONF_2 = (int)GRALLOC1_PRODUCER_USAGE_PRIVATE_0,
+	MALI_GRALLOC_USAGE_YUV_CONF_3 = (int)(GRALLOC1_PRODUCER_USAGE_PRIVATE_0 | GRALLOC1_PRODUCER_USAGE_PRIVATE_1),
+	MALI_GRALLOC_USAGE_YUV_CONF_MASK = MALI_GRALLOC_USAGE_YUV_CONF_3,
+
+	/* A very specific alignment is requested on some buffers */
+	MALI_GRALLOC_USAGE_AFBC_PADDING = (int)GRALLOC1_PRODUCER_USAGE_PRIVATE_2,
+
+} mali_gralloc_usage_type;
+#elif defined(GRALLOC_MODULE_API_VERSION_0_3)
+typedef enum
+{
+	/* The client has specified a private format in the format parameter */
+	MALI_GRALLOC_USAGE_PRIVATE_FORMAT = (int)GRALLOC_USAGE_PRIVATE_3,
+
+	/* Buffer won't be allocated as AFBC */
+	MALI_GRALLOC_USAGE_NO_AFBC = (int)(GRALLOC_USAGE_PRIVATE_1 | GRALLOC_USAGE_PRIVATE_2),
+
+	/* Valid only for YUV allocations */
+	MALI_GRALLOC_USAGE_YUV_CONF_0 = 0,
+	MALI_GRALLOC_USAGE_YUV_CONF_1 = (int)GRALLOC_USAGE_PRIVATE_1,
+	MALI_GRALLOC_USAGE_YUV_CONF_2 = (int)GRALLOC_USAGE_PRIVATE_0,
+	MALI_GRALLOC_USAGE_YUV_CONF_3 = (int)(GRALLOC_USAGE_PRIVATE_0 | GRALLOC_USAGE_PRIVATE_1),
+	MALI_GRALLOC_USAGE_YUV_CONF_MASK = MALI_GRALLOC_USAGE_YUV_CONF_3,
+
+	/* A very specific alignment is requested on some buffers */
+	MALI_GRALLOC_USAGE_AFBC_PADDING = GRALLOC_USAGE_PRIVATE_2,
+
+} mali_gralloc_usage_type;
+#else
+#if defined(GRALLOC_LIBRARY_BUILD)
+#error "Please include mali_gralloc_module.h before including other gralloc headers when building gralloc itself"
+#else
+#error "Please include either gralloc.h or gralloc1.h header before including gralloc_priv.h"
+#endif
+#endif
+
+#endif /*MALI_GRALLOC_USAGES_H_*/
diff --git a/hikey-common.mk b/hikey-common.mk
index ae7106e..1927fcf 100644
--- a/hikey-common.mk
+++ b/hikey-common.mk
@@ -4,7 +4,7 @@
 endif
 
 ifndef TARGET_COMPRESSED_KERNEL
-TARGET_COMPRESSED_KERNEL=false
+TARGET_COMPRESSED_KERNEL=true
 endif
 
 ifeq ($(TARGET_COMPRESSED_KERNEL), false)
diff --git a/hikey960/device-hikey960.mk b/hikey960/device-hikey960.mk
index 49ed263..8bfc5b8 100644
--- a/hikey960/device-hikey960.mk
+++ b/hikey960/device-hikey960.mk
@@ -36,9 +36,11 @@
 
 PRODUCT_PACKAGES += gralloc.hikey960
 
+#binary blobs from ARM
+PRODUCT_PACKAGES +=	libGLES_mali.so libbccArm.so libRSDriverArm.so libmalicore.bc \
+			vulkan.hikey960.so android.hardware.renderscript@1.0-impl.so \
+			END_USER_LICENCE_AGREEMENT.txt
+
 PRODUCT_PACKAGES += power.hikey960
 
 PRODUCT_PACKAGES += sensors.hikey960
-
-# Include vendor binaries
-$(call inherit-product-if-exists, vendor/linaro/hikey960/device-vendor.mk)
diff --git a/mali/Android.mk b/mali/Android.mk
new file mode 100644
index 0000000..4060483
--- /dev/null
+++ b/mali/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2015 The Android Open-Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# WARNING: Everything listed here will be built on ALL platforms,
+# including x86, the emulator, and the SDK.  Modules must be uniquely
+# named (liblights.panda), and must build everywhere, or limit themselves
+# to only building on ARM if they include assembly. Individual makefiles
+# are responsible for having their own logic, for fine-grained control.
+
+ifneq ($(filter hikey%, $(TARGET_DEVICE)),)
+
+LOCAL_PATH := $(call my-dir)
+
+# if some modules are built directly from this directory (not subdirectories),
+# their rules should be written here.
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/mali/bifrost/Android.mk b/mali/bifrost/Android.mk
new file mode 100644
index 0000000..bb47d97
--- /dev/null
+++ b/mali/bifrost/Android.mk
@@ -0,0 +1,81 @@
+ifneq ($(filter hikey960, $(TARGET_DEVICE)),)
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := END_USER_LICENCE_AGREEMENT.txt
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_STRIP_MODULE := false
+LOCAL_SRC_FILES_arm := $(LOCAL_MODULE)
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)
+LOCAL_MULTILIB := 32
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libGLES_mali.so
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_STRIP_MODULE := false
+LOCAL_SRC_FILES_arm := lib/egl/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_arm64 := lib64/egl/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl/
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl/
+LOCAL_MULTILIB := both
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbccArm.so
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_STRIP_MODULE := false
+#LOCAL_SRC_FILES_arm := lib/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_arm64 := lib64/$(LOCAL_MODULE)
+#LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/
+LOCAL_MULTILIB := 64
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libRSDriverArm.so
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_STRIP_MODULE := false
+LOCAL_SRC_FILES_arm := lib/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_arm64 := lib64/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/
+LOCAL_MULTILIB := both
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libmalicore.bc
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_STRIP_MODULE := false
+LOCAL_SRC_FILES_arm := lib/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_arm64 := lib64/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/
+LOCAL_MULTILIB := both
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.renderscript@1.0-impl.so
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_STRIP_MODULE := false
+LOCAL_SRC_FILES_arm := lib/hw/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_arm64 := lib64/hw/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/
+LOCAL_MULTILIB := both
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := vulkan.hikey960.so
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_STRIP_MODULE := false
+LOCAL_SRC_FILES_arm := lib/hw/$(LOCAL_MODULE)
+LOCAL_SRC_FILES_arm64 := lib64/hw/$(LOCAL_MODULE)
+LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/
+LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/
+LOCAL_MULTILIB := both
+include $(BUILD_PREBUILT)
+
+endif
+
+
diff --git a/mali/bifrost/END_USER_LICENCE_AGREEMENT.txt b/mali/bifrost/END_USER_LICENCE_AGREEMENT.txt
new file mode 100644
index 0000000..34da5f8
--- /dev/null
+++ b/mali/bifrost/END_USER_LICENCE_AGREEMENT.txt
@@ -0,0 +1,194 @@
+LES-PRE-20769

+SP-Version: 1.0

+25 November 2015

+

+END USER LICENCE AGREEMENT FOR THE MALI USERSPACE DRIVER ("Mali DRIVER")

+

+THIS END USER LICENCE AGREEMENT ("LICENCE") IS A LEGAL AGREEMENT

+BETWEEN YOU (EITHER A SINGLE INDIVIDUAL, OR SINGLE LEGAL ENTITY) AND

+ARM LIMITED ("ARM") FOR THE USE OF THE SOFTWARE ACCOMPANYING THIS

+LICENCE. ARM IS ONLY WILLING TO LICENSE THE SOFTWARE TO YOU ON

+CONDITION THAT YOU ACCEPT ALL OF THE TERMS IN THIS LICENCE. BY

+INSTALLING OR OTHERWISE USING OR COPYING THE SOFTWARE YOU INDICATE

+THAT YOU AGREE TO BE BOUND BY ALL OF THE TERMS OF THIS LICENCE. IF YOU

+DO NOT AGREE TO THE TERMS OF THIS LICENCE, ARM IS UNWILLING TO LICENSE

+THE SOFTWARE TO YOU AND YOU MAY NOT INSTALL, USE OR COPY THE SOFTWARE,

+AND YOU SHOULD PROMPTLY RETURN THE SOFTWARE TO YOUR SUPPLIER.

+

+"Applications" means applications for use solely in conjunction with

+Mali-based products manufactured under licence from ARM.

+

+"Output" means data resulting from your use of the Software and all

+direct and indirect derivatives thereof.

+

+"Software" means any software, firmware and data accompanying this

+Licence, any printed, electronic or online documentation supplied with

+it under the terms of this Licence for the Mali Driver.

+

+1. LICENCE GRANTS TO YOU.

+

+1.1 ARM hereby grants to you, subject to the terms and conditions of

+this Licence, a non-exclusive, non-transferable, revocable, worldwide

+licence to:

+

+(i)	use and copy the Software or certain components or optional

+	functionality in the Software, as applicable, solely for the

+	purposes of running, designing or developing Applications; and

+

+(ii)	subject to Clause 1.2, distribute the whole of the Software;

+	and/or (b) the whole or any part of the Software together

+	with, or as incorporated into, Applications; and

+

+1.2 If you choose to redistribute the whole or any part of the

+Software pursuant to the licences granted in Clause 1.1(ii), you

+agree: (i) not to use ARM's or any of its licensors names, logos or

+trademarks to market Applications; (ii) to retain any and all

+copyright notices and other notices (whether ARM's or its licensor's)

+which are included with the Software; and (iii) include a copy of this

+Licence with such redistribution.

+

+2. RESTRICTIONS ON USE OF THE SOFTWARE.

+

+BENCHMARKING: This Licence does not prevent you from using the

+Software for benchmarking purposes. However, you shall ensure that any

+and all benchmarking data relating to the Software, and any other

+results of your use or testing of the Software which are indicative of

+its performance, efficacy, reliability or quality, shall not be used

+to disparage ARM, its products or services, or in a manner that, in

+ARM's reasonable judgment, may diminish or otherwise damage the

+reputation of ARM.

+

+COPYRIGHT AND RESERVATION OF RIGHTS: The Software is owned by ARM or

+its licensors and is protected by copyright and other intellectual

+property laws and international treaties. The Software is licensed not

+sold. You acquire no rights to the Software other than as expressly

+provided by this Licence. You shall not remove from the Software any

+copyright notice or other notice and shall ensure that any such notice

+is reproduced in any copies of the whole or any part of the Software

+made by you or other permitted users.

+

+REVERSE ENGINEERING: Except to the extent that such activity is

+permitted by applicable law you shall not reverse engineer, decompile

+or disassemble any of the Software. If the Software was provided to

+you in Europe you shall not reverse engineer, decompile or disassemble

+any of the Software for the purposes of error correction.

+

+RESTRICTED USE: You agree that you shall not use the Software or the

+Output other than pursuant to and in accordance with the exercise of

+any of the licences granted under this Licence. Without limiting the

+generality of the foregoing, you shall not use the Software or any

+Output: (a) for determining if any features, functions or processes

+provided by the Software are covered by any patents or patent

+applications owned by you or a third party; or (b) for developing

+technology, applications or products which avoid any of ARM's

+intellectual property in the Software licensed hereunder; or (c) as a

+reference for modifying existing patents or patent applications or

+creating any continuation, continuation in part, or extension of

+existing patents or patent applications.

+

+3. SUPPORT.

+

+ARM is not under an obligation to provide support, but it may do so at

+its own discretion, and if it does, it will only be in respect of the

+Software as delivered.

+

+4. NO WARRANTIES.

+

+YOU AGREE THAT THE SOFTWARE IS LICENSED "AS IS", AND THAT ARM

+EXPRESSLY DISCLAIMS ALL REPRESENTATIONS, WARRANTIES, CONDITIONS OR

+OTHER TERMS, EXPRESS OR IMPLIED OR STATUTORY, INCLUDING WITHOUT

+LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, SATISFACTORY

+QUALITY, AND FITNESS FOR A PARTICULAR PURPOSE.

+

+YOU EXPRESSLY ASSUME ALL LIABILITIES AND RISKS, FOR USE OR OPERATION

+OF APPLICATIONS, INCLUDING WITHOUT LIMITATION, APPLICATIONS DESIGNED

+OR INTENDED FOR MISSION CRITICAL APPLICATIONS, SUCH AS PACEMAKERS,

+WEAPONRY, AIRCRAFT NAVIGATION, FACTORY CONTROL SYSTEMS, ETC. SHOULD

+THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE ENTIRE COST OF ALL

+NECESSARY SERVICING, REPAIR OR CORRECTION.

+

+5. LIMITATION OF LIABILITY.

+

+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL

+ARM BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL

+DAMAGES (INCLUDING LOSS OF PROFITS) ARISING OUT OF THE USE OR

+INABILITY TO USE THE SOFTWARE WHETHER BASED ON A CLAIM UNDER CONTRACT,

+TORT OR OTHER LEGAL THEORY, EVEN IF ARM WAS ADVISED OF THE POSSIBILITY

+OF SUCH DAMAGES.

+

+ARM does not seek to limit or exclude liability for death or personal

+injury arising from ARM's negligence or ARM's fraud and because some

+jurisdictions do not permit the exclusion or limitation of liability

+for consequential or incidental damages the above limitation relating

+to liability for consequential damages may not apply to you.

+

+NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED IN THIS LICENCE,

+THE MAXIMUM LIABILITY OF ARM TO YOU IN AGGREGATE FOR ALL CLAIMS MADE

+AGAINST ARM IN CONTRACT TORT OR OTHERWISE UNDER OR IN CONNECTION WITH

+THE SUBJECT MATTER OF THIS LICENCE SHALL NOT EXCEED THE GREATER OF:

+(I) THE TOTAL OF SUMS PAID BY YOU TO ARM (IF ANY) FOR THIS LICENCE;

+AND (II) $10.00 USD. THE EXISTENCE OF MORE THAN ONE CLAIM WILL NOT

+ENLARGE OR EXTEND THE LIMIT.

+

+6. U.S. GOVERNMENT END USERS.

+

+US Government Restrictions: Use, duplication, reproduction, release,

+modification, disclosure or transfer of the Software is restricted in

+accordance with the terms of this Licence.

+

+7. TERM AND TERMINATION.

+

+This Licence shall remain in force until terminated by you or by ARM.

+Without prejudice to any of its other rights if you are in breach of

+any of the terms and conditions of this Licence then ARM may terminate

+this Licence immediately upon giving written notice to you or on

+thirty (30) days written notice without cause. You may terminate this

+Licence at any time. Upon termination of this Licence by you or by ARM

+, you shall stop using the Software and destroy all copies of the

+Software in your possession, together with all documentation and

+related materials. The provisions of clauses 2, 3, 4, 5, 6, 7, and 8

+shall survive termination of this Licence.

+

+8. GENERAL.

+

+This Licence is governed by English Law. Except where ARM agrees

+otherwise in: (i) a written contract signed by you and ARM; or (ii) a

+written contract provided by ARM and accepted by you, this is the only

+agreement between you and ARM relating to the Software and it may only

+be modified by written agreement between you and ARM. Except as

+expressly agreed in writing, this Licence may not be modified by

+purchase orders, advertising or other representation by any person. If

+any clause or sentence in this Licence is held by a court of law to be

+illegal or unenforceable the remaining provisions of this Licence

+shall not be affected thereby. The failure by ARM to enforce any of

+the provisions of this Licence, unless waived in writing, shall not

+constitute a waiver of ARM's rights to enforce such provision or any

+other provision of this Licence in the future.

+

+At ARM's request, you agree to check your computers for installations

+of the Software and any other information requested by ARM relating to

+Software installation and to provide this information to ARM. You

+agree that auditors nominated by ARM may also perform such checking

+and reporting on behalf of ARM by prior appointment during your normal

+business hours on seven (7) days' notice. ARM shall bear the auditors'

+costs for that audit unless it reveals unlicensed usage in which case

+you shall promptly reimburse ARM for all reasonable costs and

+expenses, including professional fees, relating to such audit. Any

+information which is disclosed to ARM or such auditors during checking

+or audit shall be treated as your confidential information and shall

+only be used by ARM for licence management, compliance and enforcement

+purposes.

+

+The Software provided under this Agreement is subject to U.K.,

+European Union, and U.S. export control laws and regulations,

+including the U.S. Export Administration Act and its associated

+regulations (hereafter collectively referred to as "Export

+Regulations").  LICENSEE agrees to comply fully with all such Export

+Regulations and LICENSEE agrees that it shall not, either directly or

+indirectly, export in breach of the Export Regulations, any Software

+received under this Agreement, nor any direct products thereof; (i) to

+any country, company or person subject to export restrictions or

+sanctions under the Export Regulations; or (ii) for any prohibited end

+use, which at the time of export requires an export license or other

+governmental approval, without first obtaining such license or

+approval.

diff --git a/mali/bifrost/lib/egl/libGLES_mali.so b/mali/bifrost/lib/egl/libGLES_mali.so
new file mode 100755
index 0000000..e43c584
--- /dev/null
+++ b/mali/bifrost/lib/egl/libGLES_mali.so
Binary files differ
diff --git a/mali/bifrost/lib/hw/android.hardware.renderscript@1.0-impl.so b/mali/bifrost/lib/hw/android.hardware.renderscript@1.0-impl.so
new file mode 100755
index 0000000..d0edb82
--- /dev/null
+++ b/mali/bifrost/lib/hw/android.hardware.renderscript@1.0-impl.so
Binary files differ
diff --git a/mali/bifrost/lib/hw/gralloc.hikey960.so b/mali/bifrost/lib/hw/gralloc.hikey960.so
new file mode 100755
index 0000000..860df66
--- /dev/null
+++ b/mali/bifrost/lib/hw/gralloc.hikey960.so
Binary files differ
diff --git a/mali/bifrost/lib/hw/vulkan.hikey960.so b/mali/bifrost/lib/hw/vulkan.hikey960.so
new file mode 120000
index 0000000..57c186c
--- /dev/null
+++ b/mali/bifrost/lib/hw/vulkan.hikey960.so
@@ -0,0 +1 @@
+../egl/libGLES_mali.so
\ No newline at end of file
diff --git a/mali/bifrost/lib/libRSDriverArm.so b/mali/bifrost/lib/libRSDriverArm.so
new file mode 100755
index 0000000..6185d3d
--- /dev/null
+++ b/mali/bifrost/lib/libRSDriverArm.so
Binary files differ
diff --git a/mali/bifrost/lib/libmalicore.bc b/mali/bifrost/lib/libmalicore.bc
new file mode 100644
index 0000000..86bb619
--- /dev/null
+++ b/mali/bifrost/lib/libmalicore.bc
Binary files differ
diff --git a/mali/bifrost/lib64/egl/libGLES_mali.so b/mali/bifrost/lib64/egl/libGLES_mali.so
new file mode 100755
index 0000000..fc60d29
--- /dev/null
+++ b/mali/bifrost/lib64/egl/libGLES_mali.so
Binary files differ
diff --git a/mali/bifrost/lib64/hw/android.hardware.renderscript@1.0-impl.so b/mali/bifrost/lib64/hw/android.hardware.renderscript@1.0-impl.so
new file mode 100755
index 0000000..fc20123
--- /dev/null
+++ b/mali/bifrost/lib64/hw/android.hardware.renderscript@1.0-impl.so
Binary files differ
diff --git a/mali/bifrost/lib64/hw/gralloc.hikey960.so b/mali/bifrost/lib64/hw/gralloc.hikey960.so
new file mode 100755
index 0000000..bc960d6
--- /dev/null
+++ b/mali/bifrost/lib64/hw/gralloc.hikey960.so
Binary files differ
diff --git a/mali/bifrost/lib64/hw/vulkan.hikey960.so b/mali/bifrost/lib64/hw/vulkan.hikey960.so
new file mode 120000
index 0000000..57c186c
--- /dev/null
+++ b/mali/bifrost/lib64/hw/vulkan.hikey960.so
@@ -0,0 +1 @@
+../egl/libGLES_mali.so
\ No newline at end of file
diff --git a/mali/bifrost/lib64/libRSDriverArm.so b/mali/bifrost/lib64/libRSDriverArm.so
new file mode 100755
index 0000000..e6f0236
--- /dev/null
+++ b/mali/bifrost/lib64/libRSDriverArm.so
Binary files differ
diff --git a/mali/bifrost/lib64/libbccArm.so b/mali/bifrost/lib64/libbccArm.so
new file mode 100755
index 0000000..ff74da2
--- /dev/null
+++ b/mali/bifrost/lib64/libbccArm.so
Binary files differ
diff --git a/mali/bifrost/lib64/libmalicore.bc b/mali/bifrost/lib64/libmalicore.bc
new file mode 100644
index 0000000..5fe75ab
--- /dev/null
+++ b/mali/bifrost/lib64/libmalicore.bc
Binary files differ