/*
 * Copyright (C) 2011-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_gp_job.h"
#include "mali_osk.h"
#include "mali_osk_list.h"
#include "mali_uk_types.h"
#include "mali_memory_virtual.h"
#include "mali_memory_defer_bind.h"

static u32 gp_counter_src0 = MALI_HW_CORE_NO_COUNTER;      /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
static u32 gp_counter_src1 = MALI_HW_CORE_NO_COUNTER;           /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
static void _mali_gp_del_varying_allocations(struct mali_gp_job *job);


static int _mali_gp_add_varying_allocations(struct mali_session_data *session,
		struct mali_gp_job *job,
		u32 *alloc,
		u32 num)
{
	int i = 0;
	struct mali_gp_allocation_node *alloc_node;
	mali_mem_allocation *mali_alloc = NULL;
	struct mali_vma_node *mali_vma_node = NULL;

	for (i = 0 ; i < num ; i++) {
		MALI_DEBUG_ASSERT(alloc[i]);
		alloc_node = _mali_osk_calloc(1, sizeof(struct mali_gp_allocation_node));
		if (alloc_node) {
			INIT_LIST_HEAD(&alloc_node->node);
			/* find mali allocation structure by vaddress*/
			mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, alloc[i], 0);

			if (likely(mali_vma_node)) {
				mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
				MALI_DEBUG_ASSERT(alloc[i] == mali_vma_node->vm_node.start);
			} else {
				MALI_DEBUG_PRINT(1, ("ERROE!_mali_gp_add_varying_allocations,can't find allocation %d by address =0x%x, num=%d\n", i, alloc[i], num));
				_mali_osk_free(alloc_node);
				goto fail;
			}
			alloc_node->alloc = mali_alloc;
			/* add to gp job varying alloc list*/
			list_move(&alloc_node->node, &job->varying_alloc);
		} else
			goto fail;
	}

	return 0;
fail:
	MALI_DEBUG_PRINT(1, ("ERROE!_mali_gp_add_varying_allocations,failed to alloc memory!\n"));
	_mali_gp_del_varying_allocations(job);
	return -1;
}


static void _mali_gp_del_varying_allocations(struct mali_gp_job *job)
{
	struct mali_gp_allocation_node *alloc_node, *tmp_node;

	list_for_each_entry_safe(alloc_node, tmp_node, &job->varying_alloc, node) {
		list_del(&alloc_node->node);
		kfree(alloc_node);
	}
	INIT_LIST_HEAD(&job->varying_alloc);
}

struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id, struct mali_timeline_tracker *pp_tracker)
{
	struct mali_gp_job *job;
	u32 perf_counter_flag;
	u32 __user *memory_list = NULL;
	struct mali_gp_allocation_node *alloc_node, *tmp_node;

	job = _mali_osk_calloc(1, sizeof(struct mali_gp_job));
	if (NULL != job) {
		job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s));
		if (NULL == job->finished_notification) {
			goto fail3;
		}

		job->oom_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
		if (NULL == job->oom_notification) {
			goto fail2;
		}

		if (0 != _mali_osk_copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_gp_start_job_s))) {
			goto fail1;
		}

		perf_counter_flag = mali_gp_job_get_perf_counter_flag(job);

		/* case when no counters came from user space
		 * so pass the debugfs / DS-5 provided global ones to the job object */
		if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) ||
		      (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE))) {
			mali_gp_job_set_perf_counter_src0(job, mali_gp_job_get_gp_counter_src0());
			mali_gp_job_set_perf_counter_src1(job, mali_gp_job_get_gp_counter_src1());
		}

		_mali_osk_list_init(&job->list);
		job->session = session;
		job->id = id;
		job->heap_current_addr = job->uargs.frame_registers[4];
		job->perf_counter_value0 = 0;
		job->perf_counter_value1 = 0;
		job->pid = _mali_osk_get_pid();
		job->tid = _mali_osk_get_tid();


		INIT_LIST_HEAD(&job->varying_alloc);
		INIT_LIST_HEAD(&job->vary_todo);
		job->dmem = NULL;

		if (job->uargs.deferred_mem_num > session->allocation_mgr.mali_allocation_num) {
			MALI_PRINT_ERROR(("Mali GP job: The number of  varying buffer to defer bind  is invalid !\n"));
			goto fail1;
		}

		/* add varying allocation list*/
		if (job->uargs.deferred_mem_num > 0) {
			/* copy varying list from user space*/
			job->varying_list = _mali_osk_calloc(1, sizeof(u32) * job->uargs.deferred_mem_num);
			if (!job->varying_list) {
				MALI_PRINT_ERROR(("Mali GP job: allocate varying_list failed varying_alloc_num = %d !\n", job->uargs.deferred_mem_num));
				goto fail1;
			}

			memory_list = (u32 __user *)(uintptr_t)uargs->deferred_mem_list;

			if (0 != _mali_osk_copy_from_user(job->varying_list, memory_list, sizeof(u32) * job->uargs.deferred_mem_num)) {
				MALI_PRINT_ERROR(("Mali GP job: Failed to copy varying list from user space!\n"));
				goto fail;
			}

			if (unlikely(_mali_gp_add_varying_allocations(session, job, job->varying_list,
					job->uargs.deferred_mem_num))) {
				MALI_PRINT_ERROR(("Mali GP job: _mali_gp_add_varying_allocations failed!\n"));
				goto fail;
			}

			/* do preparation for each allocation */
			list_for_each_entry_safe(alloc_node, tmp_node, &job->varying_alloc, node) {
				if (unlikely(_MALI_OSK_ERR_OK != mali_mem_defer_bind_allocation_prepare(alloc_node->alloc, &job->vary_todo, &job->required_varying_memsize))) {
					MALI_PRINT_ERROR(("Mali GP job: mali_mem_defer_bind_allocation_prepare failed!\n"));
					goto fail;
				}
			}

			_mali_gp_del_varying_allocations(job);

			/* bind varying here, to avoid memory latency issue. */
			{
				struct mali_defer_mem_block dmem_block;

				INIT_LIST_HEAD(&dmem_block.free_pages);
				atomic_set(&dmem_block.num_free_pages, 0);

				if (mali_mem_prepare_mem_for_job(job, &dmem_block)) {
					MALI_PRINT_ERROR(("Mali GP job: mali_mem_prepare_mem_for_job failed!\n"));
					goto fail;
				}
				if (_MALI_OSK_ERR_OK != mali_mem_defer_bind(job, &dmem_block)) {
					MALI_PRINT_ERROR(("gp job create, mali_mem_defer_bind failed! GP %x fail!", job));
					goto fail;
				}
			}

			if (uargs->varying_memsize > MALI_UK_BIG_VARYING_SIZE) {
				job->big_job = 1;
			}
		}
		job->pp_tracker = pp_tracker;
		if (NULL != job->pp_tracker) {
			/* Take a reference on PP job's tracker that will be released when the GP
			   job is done. */
			mali_timeline_system_tracker_get(session->timeline_system, pp_tracker);
		}

		mali_timeline_tracker_init(&job->tracker, MALI_TIMELINE_TRACKER_GP, NULL, job);
		mali_timeline_fence_copy_uk_fence(&(job->tracker.fence), &(job->uargs.fence));

		return job;
	} else {
		MALI_PRINT_ERROR(("Mali GP job: _mali_osk_calloc failed!\n"));
		return NULL;
	}


fail:
	_mali_osk_free(job->varying_list);
	/* Handle allocate fail here, free all varying node */
	{
		struct mali_backend_bind_list *bkn, *bkn_tmp;
		list_for_each_entry_safe(bkn, bkn_tmp , &job->vary_todo, node) {
			list_del(&bkn->node);
			_mali_osk_free(bkn);
		}
	}
fail1:
	_mali_osk_notification_delete(job->oom_notification);
fail2:
	_mali_osk_notification_delete(job->finished_notification);
fail3:
	_mali_osk_free(job);
	return NULL;
}

void mali_gp_job_delete(struct mali_gp_job *job)
{
	struct mali_backend_bind_list *bkn, *bkn_tmp;
	MALI_DEBUG_ASSERT_POINTER(job);
	MALI_DEBUG_ASSERT(NULL == job->pp_tracker);
	MALI_DEBUG_ASSERT(_mali_osk_list_empty(&job->list));
	_mali_osk_free(job->varying_list);

	/* Handle allocate fail here, free all varying node */
	list_for_each_entry_safe(bkn, bkn_tmp , &job->vary_todo, node) {
		list_del(&bkn->node);
		_mali_osk_free(bkn);
	}

	mali_mem_defer_dmem_free(job);

	/* de-allocate the pre-allocated oom notifications */
	if (NULL != job->oom_notification) {
		_mali_osk_notification_delete(job->oom_notification);
		job->oom_notification = NULL;
	}
	if (NULL != job->finished_notification) {
		_mali_osk_notification_delete(job->finished_notification);
		job->finished_notification = NULL;
	}

	_mali_osk_free(job);
}

void mali_gp_job_list_add(struct mali_gp_job *job, _mali_osk_list_t *list)
{
	struct mali_gp_job *iter;
	struct mali_gp_job *tmp;

	MALI_DEBUG_ASSERT_POINTER(job);
	MALI_DEBUG_ASSERT_SCHEDULER_LOCK_HELD();

	/* Find position in list/queue where job should be added. */
	_MALI_OSK_LIST_FOREACHENTRY_REVERSE(iter, tmp, list,
					    struct mali_gp_job, list) {

		/* A span is used to handle job ID wrapping. */
		bool job_is_after = (mali_gp_job_get_id(job) -
				     mali_gp_job_get_id(iter)) <
				    MALI_SCHEDULER_JOB_ID_SPAN;

		if (job_is_after) {
			break;
		}
	}

	_mali_osk_list_add(&job->list, &iter->list);
}

u32 mali_gp_job_get_gp_counter_src0(void)
{
	return gp_counter_src0;
}

void mali_gp_job_set_gp_counter_src0(u32 counter)
{
	gp_counter_src0 = counter;
}

u32 mali_gp_job_get_gp_counter_src1(void)
{
	return gp_counter_src1;
}

void mali_gp_job_set_gp_counter_src1(u32 counter)
{
	gp_counter_src1 = counter;
}

mali_scheduler_mask mali_gp_job_signal_pp_tracker(struct mali_gp_job *job, mali_bool success)
{
	mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY;

	MALI_DEBUG_ASSERT_POINTER(job);

	if (NULL != job->pp_tracker) {
		schedule_mask |= mali_timeline_system_tracker_put(job->session->timeline_system, job->pp_tracker, MALI_FALSE == success);
		job->pp_tracker = NULL;
	}

	return schedule_mask;
}
