/*
 * Copyright (C) 2013-2014, 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_soft_job.h"
#include "mali_osk.h"
#include "mali_timeline.h"
#include "mali_session.h"
#include "mali_kernel_common.h"
#include "mali_uk_types.h"
#include "mali_scheduler.h"
#include "mali_executor.h"

MALI_STATIC_INLINE void mali_soft_job_system_lock(struct mali_soft_job_system *system)
{
	MALI_DEBUG_ASSERT_POINTER(system);
	_mali_osk_spinlock_irq_lock(system->lock);
	MALI_DEBUG_PRINT(5, ("Mali Soft Job: soft system %p lock taken\n", system));
	MALI_DEBUG_ASSERT(system->lock_owner == 0);
	MALI_DEBUG_CODE(system->lock_owner = _mali_osk_get_tid());
}

MALI_STATIC_INLINE void mali_soft_job_system_unlock(struct mali_soft_job_system *system)
{
	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_PRINT(5, ("Mali Soft Job: releasing soft system %p lock\n", system));
	MALI_DEBUG_ASSERT(_mali_osk_get_tid() == system->lock_owner);
	MALI_DEBUG_CODE(system->lock_owner = 0);
	_mali_osk_spinlock_irq_unlock(system->lock);
}

#if defined(DEBUG)
MALI_STATIC_INLINE void mali_soft_job_system_assert_locked(struct mali_soft_job_system *system)
{
	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_ASSERT(_mali_osk_get_tid() == system->lock_owner);
}
#define MALI_ASSERT_SOFT_JOB_SYSTEM_LOCKED(system) mali_soft_job_system_assert_locked(system)
#else
#define MALI_ASSERT_SOFT_JOB_SYSTEM_LOCKED(system)
#endif /* defined(DEBUG) */

struct mali_soft_job_system *mali_soft_job_system_create(struct mali_session_data *session)
{
	struct mali_soft_job_system *system;

	MALI_DEBUG_ASSERT_POINTER(session);

	system = (struct mali_soft_job_system *) _mali_osk_calloc(1, sizeof(struct mali_soft_job_system));
	if (system == NULL) {
		return NULL;
	}

	system->session = session;

	system->lock = _mali_osk_spinlock_irq_init(_MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_SCHEDULER);
	if (system->lock == NULL) {
		mali_soft_job_system_destroy(system);
		return NULL;
	}
	system->lock_owner = 0;
	system->last_job_id = 0;

	_MALI_OSK_INIT_LIST_HEAD(&(system->jobs_used));

	return system;
}

void mali_soft_job_system_destroy(struct mali_soft_job_system *system)
{
	MALI_DEBUG_ASSERT_POINTER(system);

	/* All jobs should be free at this point. */
	MALI_DEBUG_ASSERT(_mali_osk_list_empty(&(system->jobs_used)));

	if (system != NULL) {
		if (system->lock != NULL) {
			_mali_osk_spinlock_irq_term(system->lock);
		}
		_mali_osk_free(system);
	}
}

static void mali_soft_job_system_free_job(struct mali_soft_job_system *system, struct mali_soft_job *job)
{
	MALI_DEBUG_ASSERT_POINTER(job);
	MALI_DEBUG_ASSERT_POINTER(system);

	mali_soft_job_system_lock(job->system);

	MALI_DEBUG_ASSERT(job->id != MALI_SOFT_JOB_INVALID_ID);
	MALI_DEBUG_ASSERT(system == job->system);

	_mali_osk_list_del(&(job->system_list));

	mali_soft_job_system_unlock(job->system);

	_mali_osk_free(job);
}

MALI_STATIC_INLINE struct mali_soft_job *mali_soft_job_system_lookup_job(struct mali_soft_job_system *system, u32 job_id)
{
	struct mali_soft_job *job, *tmp;

	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_ASSERT_SOFT_JOB_SYSTEM_LOCKED(system);

	_MALI_OSK_LIST_FOREACHENTRY(job, tmp, &system->jobs_used, struct mali_soft_job, system_list) {
		if (job->id == job_id)
			return job;
	}

	return NULL;
}

void mali_soft_job_destroy(struct mali_soft_job *job)
{
	MALI_DEBUG_ASSERT_POINTER(job);
	MALI_DEBUG_ASSERT_POINTER(job->system);

	MALI_DEBUG_PRINT(4, ("Mali Soft Job: destroying soft job %u (0x%08X)\n", job->id, job));

	if (job != NULL) {
		if (_mali_osk_atomic_dec_return(&job->refcount) > 0) return;

		_mali_osk_atomic_term(&job->refcount);

		if (job->activated_notification != NULL) {
			_mali_osk_notification_delete(job->activated_notification);
			job->activated_notification = NULL;
		}

		mali_soft_job_system_free_job(job->system, job);
	}
}

struct mali_soft_job *mali_soft_job_create(struct mali_soft_job_system *system, mali_soft_job_type type, u64 user_job)
{
	struct mali_soft_job *job;
	_mali_osk_notification_t *notification = NULL;

	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_ASSERT((type == MALI_SOFT_JOB_TYPE_USER_SIGNALED) ||
			  (type == MALI_SOFT_JOB_TYPE_SELF_SIGNALED));

	notification = _mali_osk_notification_create(_MALI_NOTIFICATION_SOFT_ACTIVATED, sizeof(_mali_uk_soft_job_activated_s));
	if (unlikely(notification == NULL)) {
		MALI_PRINT_ERROR(("Mali Soft Job: failed to allocate notification"));
		return NULL;
	}

	job = _mali_osk_malloc(sizeof(struct mali_soft_job));
	if (unlikely(job == NULL)) {
		MALI_DEBUG_PRINT(2, ("Mali Soft Job: system alloc job failed.\n"));
		return NULL;
	}

	mali_soft_job_system_lock(system);

	job->system = system;
	job->id = system->last_job_id++;
	job->state = MALI_SOFT_JOB_STATE_ALLOCATED;

	_mali_osk_list_add(&(job->system_list), &(system->jobs_used));

	job->type = type;
	job->user_job = user_job;
	job->activated = MALI_FALSE;

	job->activated_notification = notification;

	_mali_osk_atomic_init(&job->refcount, 1);

	MALI_DEBUG_ASSERT(job->state == MALI_SOFT_JOB_STATE_ALLOCATED);
	MALI_DEBUG_ASSERT(system == job->system);
	MALI_DEBUG_ASSERT(job->id != MALI_SOFT_JOB_INVALID_ID);

	mali_soft_job_system_unlock(system);

	return job;
}

mali_timeline_point mali_soft_job_start(struct mali_soft_job *job, struct mali_timeline_fence *fence)
{
	mali_timeline_point point;
	struct mali_soft_job_system *system;

	MALI_DEBUG_ASSERT_POINTER(job);
	MALI_DEBUG_ASSERT_POINTER(fence);

	MALI_DEBUG_ASSERT_POINTER(job->system);
	system = job->system;

	MALI_DEBUG_ASSERT_POINTER(system->session);
	MALI_DEBUG_ASSERT_POINTER(system->session->timeline_system);

	mali_soft_job_system_lock(system);

	MALI_DEBUG_ASSERT(job->state == MALI_SOFT_JOB_STATE_ALLOCATED);
	job->state = MALI_SOFT_JOB_STATE_STARTED;

	mali_soft_job_system_unlock(system);

	MALI_DEBUG_PRINT(4, ("Mali Soft Job: starting soft job %u (0x%08X)\n", job->id, job));

	mali_timeline_tracker_init(&job->tracker, MALI_TIMELINE_TRACKER_SOFT, fence, job);
	point = mali_timeline_system_add_tracker(system->session->timeline_system, &job->tracker, MALI_TIMELINE_SOFT);

	return point;
}

static mali_bool mali_soft_job_is_activated(void *data)
{
	struct mali_soft_job *job;

	job = (struct mali_soft_job *) data;
	MALI_DEBUG_ASSERT_POINTER(job);

	return job->activated;
}

_mali_osk_errcode_t mali_soft_job_system_signal_job(struct mali_soft_job_system *system, u32 job_id)
{
	struct mali_soft_job *job;
	struct mali_timeline_system *timeline_system;
	mali_scheduler_mask schedule_mask;

	MALI_DEBUG_ASSERT_POINTER(system);

	mali_soft_job_system_lock(system);

	job = mali_soft_job_system_lookup_job(system, job_id);

	if ((NULL == job) || (job->type != MALI_SOFT_JOB_TYPE_USER_SIGNALED)
	    || !(MALI_SOFT_JOB_STATE_STARTED == job->state || MALI_SOFT_JOB_STATE_TIMED_OUT == job->state)) {
		mali_soft_job_system_unlock(system);
		MALI_PRINT_ERROR(("Mali Soft Job: invalid soft job id %u", job_id));
		return _MALI_OSK_ERR_ITEM_NOT_FOUND;
	}

	if (job->state == MALI_SOFT_JOB_STATE_TIMED_OUT) {
		job->state = MALI_SOFT_JOB_STATE_SIGNALED;
		mali_soft_job_system_unlock(system);

		MALI_DEBUG_ASSERT(job->activated == MALI_TRUE);
		MALI_DEBUG_PRINT(4, ("Mali Soft Job: soft job %u (0x%08X) was timed out\n", job->id, job));
		mali_soft_job_destroy(job);

		return _MALI_OSK_ERR_TIMEOUT;
	}

	MALI_DEBUG_ASSERT(job->state == MALI_SOFT_JOB_STATE_STARTED);

	job->state = MALI_SOFT_JOB_STATE_SIGNALED;
	mali_soft_job_system_unlock(system);

	/* Since the job now is in signaled state, timeouts from the timeline system will be
	 * ignored, and it is not possible to signal this job again. */

	timeline_system = system->session->timeline_system;
	MALI_DEBUG_ASSERT_POINTER(timeline_system);

	/* Wait until activated. */
	_mali_osk_wait_queue_wait_event(timeline_system->wait_queue, mali_soft_job_is_activated, (void *) job);

	MALI_DEBUG_PRINT(4, ("Mali Soft Job: signaling soft job %u (0x%08X)\n", job->id, job));

	schedule_mask = mali_timeline_tracker_release(&job->tracker);
	mali_executor_schedule_from_mask(schedule_mask, MALI_FALSE);

	mali_soft_job_destroy(job);

	return _MALI_OSK_ERR_OK;
}

static void mali_soft_job_send_activated_notification(struct mali_soft_job *job)
{
	if (job->activated_notification != NULL) {
		_mali_uk_soft_job_activated_s *res = job->activated_notification->result_buffer;

		res->user_job = job->user_job;
		mali_session_send_notification(job->system->session, job->activated_notification);
	}
	job->activated_notification = NULL;
}

mali_scheduler_mask mali_soft_job_system_activate_job(struct mali_soft_job *job)
{
	mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY;

	MALI_DEBUG_ASSERT_POINTER(job);
	MALI_DEBUG_ASSERT_POINTER(job->system);
	MALI_DEBUG_ASSERT_POINTER(job->system->session);

	MALI_DEBUG_PRINT(4, ("Mali Soft Job: Timeline activation for soft job %u (0x%08X).\n", job->id, job));

	mali_soft_job_system_lock(job->system);

	if (unlikely(job->system->session->is_aborting)) {
		MALI_DEBUG_PRINT(3, ("Mali Soft Job: Soft job %u (0x%08X) activated while session is aborting.\n", job->id, job));

		mali_soft_job_system_unlock(job->system);

		/* Since we are in shutdown, we can ignore the scheduling bitmask. */
		mali_timeline_tracker_release(&job->tracker);
		mali_soft_job_destroy(job);
		return schedule_mask;
	}

	/* Send activated notification. */
	mali_soft_job_send_activated_notification(job);

	/* Wake up sleeping signaler. */
	job->activated = MALI_TRUE;

	/* If job type is self signaled, release tracker, move soft job to free list, and scheduler at once */
	if (job->type == MALI_SOFT_JOB_TYPE_SELF_SIGNALED) {
		MALI_DEBUG_ASSERT(job->state == MALI_SOFT_JOB_STATE_STARTED);

		job->state = MALI_SOFT_JOB_STATE_SIGNALED;
		mali_soft_job_system_unlock(job->system);

		schedule_mask |= mali_timeline_tracker_release(&job->tracker);

		mali_soft_job_destroy(job);
	} else {
		_mali_osk_wait_queue_wake_up(job->tracker.system->wait_queue);

		mali_soft_job_system_unlock(job->system);
	}

	return schedule_mask;
}

mali_scheduler_mask mali_soft_job_system_timeout_job(struct mali_soft_job *job)
{
	mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY;

	MALI_DEBUG_ASSERT_POINTER(job);
	MALI_DEBUG_ASSERT_POINTER(job->system);
	MALI_DEBUG_ASSERT_POINTER(job->system->session);
	MALI_DEBUG_ASSERT(job->activated == MALI_TRUE);

	MALI_DEBUG_PRINT(4, ("Mali Soft Job: Timeline timeout for soft job %u (0x%08X).\n", job->id, job));

	mali_soft_job_system_lock(job->system);

	MALI_DEBUG_ASSERT(MALI_SOFT_JOB_STATE_STARTED  == job->state ||
			  MALI_SOFT_JOB_STATE_SIGNALED == job->state);

	if (unlikely(job->system->session->is_aborting)) {
		/* The session is aborting.  This job will be released and destroyed by @ref
		 * mali_soft_job_system_abort(). */
		mali_soft_job_system_unlock(job->system);

		return MALI_SCHEDULER_MASK_EMPTY;
	}

	if (job->state != MALI_SOFT_JOB_STATE_STARTED) {
		MALI_DEBUG_ASSERT(job->state == MALI_SOFT_JOB_STATE_SIGNALED);

		/* The job is about to be signaled, ignore timeout. */
		MALI_DEBUG_PRINT(4, ("Mali Soft Job: Timeout on soft job %u (0x%08X) in signaled state.\n", job->id, job));
		mali_soft_job_system_unlock(job->system);
		return schedule_mask;
	}

	MALI_DEBUG_ASSERT(job->state == MALI_SOFT_JOB_STATE_STARTED);

	job->state = MALI_SOFT_JOB_STATE_TIMED_OUT;
	_mali_osk_atomic_inc(&job->refcount);

	mali_soft_job_system_unlock(job->system);

	schedule_mask = mali_timeline_tracker_release(&job->tracker);

	mali_soft_job_destroy(job);

	return schedule_mask;
}

void mali_soft_job_system_abort(struct mali_soft_job_system *system)
{
	struct mali_soft_job *job, *tmp;

	_MALI_OSK_LIST_HEAD_STATIC_INIT(jobs);

	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_ASSERT_POINTER(system->session);
	MALI_DEBUG_ASSERT(system->session->is_aborting);

	MALI_DEBUG_PRINT(3, ("Mali Soft Job: Aborting soft job system for session 0x%08X.\n", system->session));

	mali_soft_job_system_lock(system);

	_MALI_OSK_LIST_FOREACHENTRY(job, tmp, &system->jobs_used, struct mali_soft_job, system_list) {
		MALI_DEBUG_ASSERT(MALI_SOFT_JOB_STATE_STARTED   == job->state ||
				  MALI_SOFT_JOB_STATE_TIMED_OUT == job->state);

		if (job->state == MALI_SOFT_JOB_STATE_STARTED) {
			/* If the job has been activated, we have to release the tracker and destroy
			 * the job.  If not, the tracker will be released and the job destroyed when
			 * it is activated. */
			if (job->activated == MALI_TRUE) {
				MALI_DEBUG_PRINT(3, ("Mali Soft Job: Aborting unsignaled soft job %u (0x%08X).\n", job->id, job));

				job->state = MALI_SOFT_JOB_STATE_SIGNALED;
				_mali_osk_list_move(&job->system_list, &jobs);
			}
		} else if (job->state == MALI_SOFT_JOB_STATE_TIMED_OUT) {
			MALI_DEBUG_PRINT(3, ("Mali Soft Job: Aborting timed out soft job %u (0x%08X).\n", job->id, job));

			/* We need to destroy this soft job. */
			_mali_osk_list_move(&job->system_list, &jobs);
		}
	}

	mali_soft_job_system_unlock(system);

	/* Release and destroy jobs. */
	_MALI_OSK_LIST_FOREACHENTRY(job, tmp, &jobs, struct mali_soft_job, system_list) {
		MALI_DEBUG_ASSERT(MALI_SOFT_JOB_STATE_SIGNALED  == job->state ||
				  MALI_SOFT_JOB_STATE_TIMED_OUT == job->state);

		if (job->state == MALI_SOFT_JOB_STATE_SIGNALED) {
			mali_timeline_tracker_release(&job->tracker);
		}

		/* Move job back to used list before destroying. */
		_mali_osk_list_move(&job->system_list, &system->jobs_used);

		mali_soft_job_destroy(job);
	}
}
