/*
 * Copyright (C) 2013, 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/file.h>
#include "mali_timeline_sync_fence.h"

#include "mali_osk.h"
#include "mali_kernel_common.h"
#include "mali_sync.h"

#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE)

/**
 * Creates a sync fence tracker and a sync fence.  Adds sync fence tracker to Timeline system and
 * returns sync fence.  The sync fence will be signaled when the sync fence tracker is activated.
 *
 * @param timeline Timeline.
 * @param point Point on timeline.
 * @return Sync fence that will be signaled when tracker is activated.
 */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
static struct sync_fence *mali_timeline_sync_fence_create_and_add_tracker(struct mali_timeline *timeline, mali_timeline_point point)
#else
static struct mali_internal_sync_fence *mali_timeline_sync_fence_create_and_add_tracker(struct mali_timeline *timeline, mali_timeline_point point)
#endif
{
	struct mali_timeline_sync_fence_tracker *sync_fence_tracker;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
	struct sync_fence                       *sync_fence;
#else
	struct mali_internal_sync_fence                       *sync_fence;
#endif
	struct mali_timeline_fence               fence;

	MALI_DEBUG_ASSERT_POINTER(timeline);
	MALI_DEBUG_ASSERT(MALI_TIMELINE_NO_POINT != point);

	/* Allocate sync fence tracker. */
	sync_fence_tracker = _mali_osk_calloc(1, sizeof(struct mali_timeline_sync_fence_tracker));
	if (NULL == sync_fence_tracker) {
		MALI_PRINT_ERROR(("Mali Timeline: sync_fence_tracker allocation failed\n"));
		return NULL;
	}

	/* Create sync flag. */
	MALI_DEBUG_ASSERT_POINTER(timeline->sync_tl);
	sync_fence_tracker->flag = mali_sync_flag_create(timeline->sync_tl, point);
	if (NULL == sync_fence_tracker->flag) {
		MALI_PRINT_ERROR(("Mali Timeline: sync_flag creation failed\n"));
		_mali_osk_free(sync_fence_tracker);
		return NULL;
	}

	/* Create sync fence from sync flag. */
	sync_fence = mali_sync_flag_create_fence(sync_fence_tracker->flag);
	if (NULL == sync_fence) {
		MALI_PRINT_ERROR(("Mali Timeline: sync_fence creation failed\n"));
		mali_sync_flag_put(sync_fence_tracker->flag);
		_mali_osk_free(sync_fence_tracker);
		return NULL;
	}

	/* Setup fence for tracker. */
	_mali_osk_memset(&fence, 0, sizeof(struct mali_timeline_fence));
	fence.sync_fd = -1;
	fence.points[timeline->id] = point;

	/* Finally, add the tracker to Timeline system. */
	mali_timeline_tracker_init(&sync_fence_tracker->tracker, MALI_TIMELINE_TRACKER_SYNC, &fence, sync_fence_tracker);
	point = mali_timeline_system_add_tracker(timeline->system, &sync_fence_tracker->tracker, MALI_TIMELINE_NONE);
	MALI_DEBUG_ASSERT(MALI_TIMELINE_NO_POINT == point);

	return sync_fence;
}

s32 mali_timeline_sync_fence_create(struct mali_timeline_system *system, struct mali_timeline_fence *fence)
{
	u32 i;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
	struct sync_fence *sync_fence_acc = NULL;
#else
	struct mali_internal_sync_fence *sync_fence_acc = NULL;
#endif
	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_ASSERT_POINTER(fence);

	for (i = 0; i < MALI_TIMELINE_MAX; ++i) {
		struct mali_timeline *timeline;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
		struct sync_fence *sync_fence;
#else
		struct mali_internal_sync_fence *sync_fence;
#endif
		if (MALI_TIMELINE_NO_POINT == fence->points[i]) continue;

		timeline = system->timelines[i];
		MALI_DEBUG_ASSERT_POINTER(timeline);

		sync_fence = mali_timeline_sync_fence_create_and_add_tracker(timeline, fence->points[i]);
		if (NULL == sync_fence) goto error;

		if (NULL != sync_fence_acc) {
			/* Merge sync fences. */
			sync_fence_acc = mali_sync_fence_merge(sync_fence_acc, sync_fence);
			if (NULL == sync_fence_acc) goto error;
		} else {
			/* This was the first sync fence created. */
			sync_fence_acc = sync_fence;
		}
	}

	if (-1 != fence->sync_fd) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
		struct sync_fence *sync_fence;
		sync_fence = sync_fence_fdget(fence->sync_fd);
#else
		struct mali_internal_sync_fence *sync_fence;
		sync_fence = mali_internal_sync_fence_fdget(fence->sync_fd);
#endif

		if (NULL == sync_fence) goto error;

		if (NULL != sync_fence_acc) {
			sync_fence_acc = mali_sync_fence_merge(sync_fence_acc, sync_fence);
			if (NULL == sync_fence_acc) goto error;
		} else {
			sync_fence_acc = sync_fence;
		}
	}

	if (NULL == sync_fence_acc) {
		MALI_DEBUG_ASSERT_POINTER(system->signaled_sync_tl);

		/* There was nothing to wait on, so return an already signaled fence. */

		sync_fence_acc = mali_sync_timeline_create_signaled_fence(system->signaled_sync_tl);
		if (NULL == sync_fence_acc) goto error;
	}

	/* Return file descriptor for the accumulated sync fence. */
	return mali_sync_fence_fd_alloc(sync_fence_acc);

error:
	if (NULL != sync_fence_acc) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
		sync_fence_put(sync_fence_acc);
#else
		fput(sync_fence_acc->file);
#endif
	}

	return -1;
}

void mali_timeline_sync_fence_activate(struct mali_timeline_sync_fence_tracker *sync_fence_tracker)
{
	mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY;

	MALI_DEBUG_ASSERT_POINTER(sync_fence_tracker);
	MALI_DEBUG_ASSERT_POINTER(sync_fence_tracker->flag);

	MALI_DEBUG_PRINT(4, ("Mali Timeline: activation for sync fence tracker\n"));

	/* Signal flag and release reference. */
	mali_sync_flag_signal(sync_fence_tracker->flag, 0);
	mali_sync_flag_put(sync_fence_tracker->flag);

	/* Nothing can wait on this tracker, so nothing to schedule after release. */
	schedule_mask = mali_timeline_tracker_release(&sync_fence_tracker->tracker);
	MALI_DEBUG_ASSERT(MALI_SCHEDULER_MASK_EMPTY == schedule_mask);

	_mali_osk_free(sync_fence_tracker);
}
#endif /* defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE) */
