/*
 * 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 "mali_timeline_sync_fence.h"

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

#if defined(CONFIG_SYNC)

/**
 * 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.
 */
static struct sync_fence *mali_timeline_sync_fence_create_and_add_tracker(struct mali_timeline *timeline, mali_timeline_point point)
{
	struct mali_timeline_sync_fence_tracker *sync_fence_tracker;
	struct sync_fence                       *sync_fence;
	struct mali_timeline_fence               fence;

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

	/* Allocate sync fence tracker. */
	sync_fence_tracker = _mali_osk_calloc(1, sizeof(struct mali_timeline_sync_fence_tracker));
	if (sync_fence_tracker == NULL) {
		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 (sync_fence_tracker->flag == NULL) {
		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 (sync_fence == NULL) {
		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(point == MALI_TIMELINE_NO_POINT);

	return sync_fence;
}

s32 mali_timeline_sync_fence_create(struct mali_timeline_system *system, struct mali_timeline_fence *fence)
{
	u32 i;
	struct sync_fence *sync_fence_acc = NULL;

	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_ASSERT_POINTER(fence);

	for (i = 0; i < MALI_TIMELINE_MAX; ++i) {
		struct mali_timeline *timeline;
		struct sync_fence *sync_fence;

		if (fence->points[i] == MALI_TIMELINE_NO_POINT) 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 (sync_fence == NULL) goto error;

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

	if (-1 != fence->sync_fd) {
		struct sync_fence *sync_fence;

		sync_fence = sync_fence_fdget(fence->sync_fd);
		if (sync_fence == NULL) goto error;

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

	if (sync_fence_acc == NULL) {
		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 (sync_fence_acc == NULL) goto error;
	}

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

error:
	if (sync_fence_acc != NULL) {
		sync_fence_put(sync_fence_acc);
	}

	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(schedule_mask == MALI_SCHEDULER_MASK_EMPTY);

	_mali_osk_free(sync_fence_tracker);
}

#endif /* defined(CONFIG_SYNC) */
