/*
 * Copyright (C) 2012-2016 ARM Limited. All rights reserved.
 * 
 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
 * 
 * A copy of the licence is included with the program, and can also be obtained from Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include <linux/fs.h>      /* file system operations */
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
#include <linux/uaccess.h>
#else
#include <asm/uaccess.h>
#endif
#include <linux/dma-buf.h>
#include <linux/scatterlist.h>
#include <linux/rbtree.h>
#include <linux/platform_device.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/mutex.h>

#include "mali_ukk.h"
#include "mali_osk.h"
#include "mali_kernel_common.h"
#include "mali_session.h"
#include "mali_kernel_linux.h"

#include "mali_memory.h"
#include "mali_memory_dma_buf.h"
#include "mali_memory_virtual.h"
#include "mali_pp_job.h"

/*
 * Map DMA buf attachment \a mem into \a session at virtual address \a virt.
 */
static int mali_dma_buf_map(mali_mem_backend *mem_backend)
{
	mali_mem_allocation *alloc;
	struct mali_dma_buf_attachment *mem;
	struct  mali_session_data *session;
	struct mali_page_directory *pagedir;
	_mali_osk_errcode_t err;
	struct scatterlist *sg;
	u32 virt, flags, unmap_dma_size;
	int i;

	MALI_DEBUG_ASSERT_POINTER(mem_backend);

	alloc = mem_backend->mali_allocation;
	MALI_DEBUG_ASSERT_POINTER(alloc);

	mem = mem_backend->dma_buf.attachment;
	MALI_DEBUG_ASSERT_POINTER(mem);
	MALI_DEBUG_ASSERT_POINTER(mem->buf);
	unmap_dma_size = mem->buf->size;
	session = alloc->session;
	MALI_DEBUG_ASSERT_POINTER(session);
	MALI_DEBUG_ASSERT(mem->session == session);

	virt = alloc->mali_vma_node.vm_node.start;
	flags = alloc->flags;

	mali_session_memory_lock(session);
	mem->map_ref++;

	MALI_DEBUG_PRINT(5, ("Mali DMA-buf: map attachment %p, new map_ref = %d\n", mem, mem->map_ref));
	MALI_DEBUG_PRINT(5, ("Mali DMA-buf: is_mapped %d, new map_ref = %d\n", mem->is_mapped, mem_backend->flags));
#if (!defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)) && (defined(CONFIG_MALI_DMA_BUF_LAZY_MAP))
	if (MALI_FALSE == mem->is_mapped)
#else
	if (1 == mem->map_ref || (MALI_FALSE == mem->is_mapped &&
		mem_backend->flags & MALI_MEM_BACKEND_FLAG_VIDEO_LAZY_MAP))
#endif
	{
		/* First reference taken, so we need to map the dma buf */
		MALI_DEBUG_ASSERT(!mem->is_mapped);

		mem->sgt = dma_buf_map_attachment(mem->attachment, DMA_BIDIRECTIONAL);
		if (IS_ERR_OR_NULL(mem->sgt)) {
			MALI_DEBUG_PRINT_ERROR(("Failed to map dma-buf attachment\n"));
			mem->map_ref--;
			mali_session_memory_unlock(session);
			return -EFAULT;
		}

		err = mali_mem_mali_map_prepare(alloc);
		if (_MALI_OSK_ERR_OK != err) {
			MALI_DEBUG_PRINT(1, ("Mapping of DMA memory failed\n"));
			mem->map_ref--;
			mali_session_memory_unlock(session);
			return -ENOMEM;
		}

		pagedir = mali_session_get_page_directory(session);
		MALI_DEBUG_ASSERT_POINTER(pagedir);

		for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i) {
			u32 size = sg_dma_len(sg);
			dma_addr_t phys = sg_dma_address(sg);

			unmap_dma_size -= size;
			/* sg must be page aligned. */
			MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE);
			MALI_DEBUG_ASSERT(0 == (phys & ~(uintptr_t)0xFFFFFFFF));

			mali_mmu_pagedir_update(pagedir, virt, phys, size, MALI_MMU_FLAGS_DEFAULT);

			virt += size;
		}

		if (flags & MALI_MEM_FLAG_MALI_GUARD_PAGE) {
			u32 guard_phys;
			MALI_DEBUG_PRINT(7, ("Mapping in extra guard page\n"));

			guard_phys = sg_dma_address(mem->sgt->sgl);
			mali_mmu_pagedir_update(pagedir, virt, guard_phys, MALI_MMU_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT);
		}

		mem->is_mapped = MALI_TRUE;

		if (0 != unmap_dma_size) {
			MALI_DEBUG_PRINT_ERROR(("The dma buf size isn't equal to the total scatterlists' dma length.\n"));
			mali_session_memory_unlock(session);
			return -EFAULT;
		}

		/* Wake up any thread waiting for buffer to become mapped */
		wake_up_all(&mem->wait_queue);

		mali_session_memory_unlock(session);
	} else {
		MALI_DEBUG_ASSERT(mem->is_mapped);
		mali_session_memory_unlock(session);
	}

	return 0;
}

static void mali_dma_buf_unmap(mali_mem_allocation *alloc, struct mali_dma_buf_attachment *mem)
{
	MALI_DEBUG_ASSERT_POINTER(alloc);
	MALI_DEBUG_ASSERT_POINTER(mem);
	MALI_DEBUG_ASSERT_POINTER(mem->attachment);
	MALI_DEBUG_ASSERT_POINTER(mem->buf);
	MALI_DEBUG_ASSERT_POINTER(alloc->session);

	mali_session_memory_lock(alloc->session);
	mem->map_ref--;

	MALI_DEBUG_PRINT(5, ("Mali DMA-buf: unmap attachment %p, new map_ref = %d\n", mem, mem->map_ref));
	MALI_DEBUG_PRINT(5, ("Mali DMA-buf: unmap is_mapped %d\n", mem->is_mapped));
	if (0 == mem->map_ref) {
		if (NULL != mem->sgt) {
			dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL);
			 mem->sgt = NULL;
		}
		if (MALI_TRUE == mem->is_mapped) {
			mali_mem_mali_map_free(alloc->session, alloc->psize, alloc->mali_vma_node.vm_node.start,
					       alloc->flags);
		}
		mem->is_mapped = MALI_FALSE;
	}

	/* Wake up any thread waiting for buffer to become unmapped */
	wake_up_all(&mem->wait_queue);

	mali_session_memory_unlock(alloc->session);
}

#if 1//!defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
int mali_dma_buf_map_job(struct mali_pp_job *job)
{
	struct mali_dma_buf_attachment *mem;
	_mali_osk_errcode_t err;
	int i;
	int ret = 0;
	u32 num_memory_cookies;
	struct mali_session_data *session;
	struct mali_vma_node *mali_vma_node = NULL;
	mali_mem_allocation *mali_alloc = NULL;
	mali_mem_backend *mem_bkend = NULL;

	MALI_DEBUG_ASSERT_POINTER(job);

	num_memory_cookies = mali_pp_job_num_memory_cookies(job);

	session = mali_pp_job_get_session(job);

	MALI_DEBUG_ASSERT_POINTER(session);

	for (i = 0; i < num_memory_cookies; i++) {
		u32 mali_addr  = mali_pp_job_get_memory_cookie(job, i);
		mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, mali_addr, 0);
		MALI_DEBUG_ASSERT(NULL != mali_vma_node);
		mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
		MALI_DEBUG_ASSERT(NULL != mali_alloc);
		if (MALI_MEM_DMA_BUF != mali_alloc->type) {
			continue;
		}

		/* Get backend memory & Map on CPU */
		mutex_lock(&mali_idr_mutex);
		mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
		mutex_unlock(&mali_idr_mutex);
		MALI_DEBUG_ASSERT(NULL != mem_bkend);

		mem = mem_bkend->dma_buf.attachment;

		MALI_DEBUG_ASSERT_POINTER(mem);
		MALI_DEBUG_ASSERT(mem->session == mali_pp_job_get_session(job));

		err = mali_dma_buf_map(mem_bkend);
		if (0 != err) {
			MALI_DEBUG_PRINT_ERROR(("Mali DMA-buf: Failed to map dma-buf for mali address %x\n", mali_addr));
			ret = -EFAULT;
			continue;
		}
	}
	return ret;
}

void mali_dma_buf_unmap_job(struct mali_pp_job *job)
{
	struct mali_dma_buf_attachment *mem;
	int i;
	u32 num_memory_cookies;
	struct mali_session_data *session;
	struct mali_vma_node *mali_vma_node = NULL;
	mali_mem_allocation *mali_alloc = NULL;
	mali_mem_backend *mem_bkend = NULL;

	MALI_DEBUG_ASSERT_POINTER(job);

	num_memory_cookies = mali_pp_job_num_memory_cookies(job);

	session = mali_pp_job_get_session(job);

	MALI_DEBUG_ASSERT_POINTER(session);

	for (i = 0; i < num_memory_cookies; i++) {
		u32 mali_addr  = mali_pp_job_get_memory_cookie(job, i);
		mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, mali_addr, 0);
		MALI_DEBUG_ASSERT(NULL != mali_vma_node);
		mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
		MALI_DEBUG_ASSERT(NULL != mali_alloc);
		if (MALI_MEM_DMA_BUF != mali_alloc->type) {
			continue;
		}

		/* Get backend memory & Map on CPU */
		mutex_lock(&mali_idr_mutex);
		mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
		mutex_unlock(&mali_idr_mutex);
		MALI_DEBUG_ASSERT(NULL != mem_bkend);

		mem = mem_bkend->dma_buf.attachment;

		MALI_DEBUG_ASSERT_POINTER(mem);
		MALI_DEBUG_ASSERT(mem->session == mali_pp_job_get_session(job));
		mali_dma_buf_unmap(mem_bkend->mali_allocation, mem);
	}
}
#endif /* !CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH */

int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg)
{
	_mali_uk_dma_buf_get_size_s args;
	int fd;
	struct dma_buf *buf;

	/* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
	if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s))) {
		return -EFAULT;
	}

	/* Do DMA-BUF stuff */
	fd = args.mem_fd;

	buf = dma_buf_get(fd);
	if (IS_ERR_OR_NULL(buf)) {
		MALI_DEBUG_PRINT_ERROR(("Failed to get dma-buf from fd: %d\n", fd));
		return PTR_RET(buf);
	}

	if (0 != put_user(buf->size, &user_arg->size)) {
		dma_buf_put(buf);
		return -EFAULT;
	}

	dma_buf_put(buf);

	return 0;
}

_mali_osk_errcode_t mali_mem_bind_dma_buf(mali_mem_allocation *alloc,
		mali_mem_backend *mem_backend,
		int fd, u32 flags)
{
	struct dma_buf *buf;
	struct mali_dma_buf_attachment *dma_mem;
	struct  mali_session_data *session = alloc->session;

	MALI_DEBUG_ASSERT_POINTER(session);
	MALI_DEBUG_ASSERT_POINTER(mem_backend);
	MALI_DEBUG_ASSERT_POINTER(alloc);

	/* get dma buffer */
	buf = dma_buf_get(fd);
	if (IS_ERR_OR_NULL(buf)) {
		return _MALI_OSK_ERR_FAULT;
	}

	/* Currently, mapping of the full buffer are supported. */
	if (alloc->psize != buf->size) {
		goto failed_alloc_mem;
	}

	dma_mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment));
	if (NULL == dma_mem) {
		goto failed_alloc_mem;
	}

	dma_mem->buf = buf;
	dma_mem->session = session;
#if (!defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)) && (defined(CONFIG_MALI_DMA_BUF_LAZY_MAP))
	dma_mem->map_ref = 1;
#else
	dma_mem->map_ref = 0;
#endif
	if (flags & _MALI_MAP_VIDEO_LAYER)
		dma_mem->map_ref = 1;
	init_waitqueue_head(&dma_mem->wait_queue);

	dma_mem->attachment = dma_buf_attach(dma_mem->buf, &mali_platform_device->dev);
	if (NULL == dma_mem->attachment) {
		goto failed_dma_attach;
	}

	mem_backend->dma_buf.attachment = dma_mem;

	alloc->flags |= MALI_MEM_FLAG_DONT_CPU_MAP;
	if (flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
		alloc->flags |= MALI_MEM_FLAG_MALI_GUARD_PAGE;
	}

#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
	/* Map memory into session's Mali virtual address space. */
	if (!(flags & _MALI_MAP_VIDEO_LAYER) &&
		(0 != mali_dma_buf_map(mem_backend))) {
		goto Failed_dma_map;
	}
#endif

	return _MALI_OSK_ERR_OK;

#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
Failed_dma_map:
	mali_dma_buf_unmap(alloc, dma_mem);
#endif
	/* Wait for buffer to become unmapped */
	wait_event(dma_mem->wait_queue, !dma_mem->is_mapped);
	MALI_DEBUG_ASSERT(!dma_mem->is_mapped);
	dma_buf_detach(dma_mem->buf, dma_mem->attachment);
failed_dma_attach:
	_mali_osk_free(dma_mem);
failed_alloc_mem:
	dma_buf_put(buf);
	return _MALI_OSK_ERR_FAULT;
}

void mali_mem_unbind_dma_buf(mali_mem_backend *mem_backend)
{
	struct mali_dma_buf_attachment *mem;
	struct  mali_session_data *session;
	MALI_DEBUG_ASSERT_POINTER(mem_backend);
	MALI_DEBUG_ASSERT(MALI_MEM_DMA_BUF == mem_backend->type);

	mem = mem_backend->dma_buf.attachment;

	MALI_DEBUG_ASSERT_POINTER(mem);
	MALI_DEBUG_ASSERT_POINTER(mem->attachment);
	MALI_DEBUG_ASSERT_POINTER(mem->buf);
	MALI_DEBUG_PRINT(3, ("Mali DMA-buf: release attachment %p\n", mem));

	MALI_DEBUG_ASSERT_POINTER(mem_backend->mali_allocation);
	session = mem_backend->mali_allocation->session;

#if (defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)) ||((!defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)) && (defined(CONFIG_MALI_DMA_BUF_LAZY_MAP)))
	/* We mapped implicitly on attach, so we need to unmap on release */
	mali_dma_buf_unmap(mem_backend->mali_allocation, mem);
#endif
	/* Wait for buffer to become unmapped */
	wait_event(mem->wait_queue, !mem->is_mapped);
	MALI_DEBUG_ASSERT(!mem->is_mapped);

	dma_buf_detach(mem->buf, mem->attachment);
	dma_buf_put(mem->buf);

	MALI_DEBUG_ASSERT_POINTER(session);
	mali_session_memory_lock(session);
	_mali_osk_free(mem);
	mali_session_memory_unlock(session);
}

_mali_osk_errcode_t meson_update_video_texture(struct  mali_session_data *session, int fd)
{
	struct dma_buf *buf;
	struct dma_buf_attachment *attachment;
	struct sg_table *sgt;
	_mali_osk_errcode_t ret = _MALI_OSK_ERR_OK;

	/* get dma buffer */
	buf = dma_buf_get(fd);
	if (IS_ERR_OR_NULL(buf)) {
		return _MALI_OSK_ERR_FAULT;
	}

	attachment = dma_buf_attach(buf, &mali_platform_device->dev);
	if (NULL == attachment) {
		MALI_DEBUG_PRINT_ERROR(("Failed to attach dma-buf\n"));
		ret = _MALI_OSK_ERR_FAULT;
		goto failed_dma_attach;
	}

	sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
	if (IS_ERR_OR_NULL(sgt)) {
		MALI_DEBUG_PRINT_ERROR(("Failed to dma-buf-map attachment\n"));
		ret = _MALI_OSK_ERR_FAULT;
		goto failed_dma_map;
	}

	dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
	sgt = NULL;

failed_dma_map:
	dma_buf_detach(buf, attachment);
failed_dma_attach:
	dma_buf_put(buf);

    return ret;
}
