/*
 * 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.h"
#include "mali_hw_core.h"
#include "mali_group.h"
#include "mali_osk.h"
#include "regs/mali_gp_regs.h"
#include "mali_kernel_common.h"
#include "mali_kernel_core.h"
#if defined(CONFIG_MALI400_PROFILING)
#include "mali_osk_profiling.h"
#endif

#include <mali_platform.h>

static struct mali_gp_core *mali_global_gp_core = NULL;

/* Interrupt handlers */
static void mali_gp_irq_probe_trigger(void *data);
static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data);

struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t *resource, struct mali_group *group)
{
	struct mali_gp_core *core = NULL;

	MALI_DEBUG_ASSERT(NULL == mali_global_gp_core);
	MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description));

	core = _mali_osk_malloc(sizeof(struct mali_gp_core));
	if (NULL != core) {
		if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE)) {
			_mali_osk_errcode_t ret;

			ret = mali_gp_reset(core);

			if (_MALI_OSK_ERR_OK == ret) {
				ret = mali_group_add_gp_core(group, core);
				if (_MALI_OSK_ERR_OK == ret) {
					/* Setup IRQ handlers (which will do IRQ probing if needed) */
					core->irq = _mali_osk_irq_init(resource->irq,
								       mali_group_upper_half_gp,
								       group,
								       mali_gp_irq_probe_trigger,
								       mali_gp_irq_probe_ack,
								       core,
								       resource->description);
					if (NULL != core->irq) {
						MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core));
						mali_global_gp_core = core;

						return core;
					} else {
						MALI_PRINT_ERROR(("Mali GP: Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description));
					}
					mali_group_remove_gp_core(group);
				} else {
					MALI_PRINT_ERROR(("Mali GP: Failed to add core %s to group\n", core->hw_core.description));
				}
			}
			mali_hw_core_delete(&core->hw_core);
		}

		_mali_osk_free(core);
	} else {
		MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n"));
	}

	return NULL;
}

void mali_gp_delete(struct mali_gp_core *core)
{
	MALI_DEBUG_ASSERT_POINTER(core);

	_mali_osk_irq_term(core->irq);
	mali_hw_core_delete(&core->hw_core);
	mali_global_gp_core = NULL;
	_mali_osk_free(core);
}

void mali_gp_stop_bus(struct mali_gp_core *core)
{
	MALI_DEBUG_ASSERT_POINTER(core);

	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
}

_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core)
{
	int i;

	MALI_DEBUG_ASSERT_POINTER(core);

	/* Send the stop bus command. */
	mali_gp_stop_bus(core);

	/* Wait for bus to be stopped */
	for (i = 0; i < MALI_REG_POLL_COUNT_SLOW; i++) {
		if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) {
			break;
		}
	}

	if (MALI_REG_POLL_COUNT_SLOW == i) {
		MALI_PRINT_ERROR(("Mali GP: Failed to stop bus on %s\n", core->hw_core.description));
		if (mali_gp_reset_fail < 65533)
			mali_gp_reset_fail++;
		return _MALI_OSK_ERR_FAULT;
	}
	return _MALI_OSK_ERR_OK;
}

void mali_gp_hard_reset(struct mali_gp_core *core)
{
	const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_LIMIT;
	const u32 reset_invalid_value = 0xC0FFE000;
	const u32 reset_check_value = 0xC01A0000;
	const u32 reset_default_value = 0;
	int i;

	MALI_DEBUG_ASSERT_POINTER(core);
	MALI_DEBUG_PRINT(4, ("Mali GP: Hard reset of core %s\n", core->hw_core.description));

	mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_invalid_value);

	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET);

	for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) {
		mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value);
		if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register)) {
			break;
		}
	}

	if (MALI_REG_POLL_COUNT_FAST == i) {
		MALI_PRINT_ERROR(("Mali GP: The hard reset loop didn't work, unable to recover\n"));
	}

	mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_default_value); /* set it back to the default */
	/* Re-enable interrupts */
	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);

}

void mali_gp_reset_async(struct mali_gp_core *core)
{
	MALI_DEBUG_ASSERT_POINTER(core);

	MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description));

	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED);
	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET);

}

_mali_osk_errcode_t mali_gp_reset_wait(struct mali_gp_core *core)
{
	int i;
	u32 rawstat = 0;

	MALI_DEBUG_ASSERT_POINTER(core);

	for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) {
		rawstat = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT);
		if (rawstat & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED) {
			break;
		}
	}

	if (i == MALI_REG_POLL_COUNT_FAST) {
		MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, rawstat: 0x%08x\n",
				  core->hw_core.description, rawstat));
		if (mali_gp_reset_fail < 65533)
			mali_gp_reset_fail++;
		return _MALI_OSK_ERR_FAULT;
	}

	/* Re-enable interrupts */
	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);

	return _MALI_OSK_ERR_OK;
}

_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core)
{
	mali_gp_reset_async(core);
	return mali_gp_reset_wait(core);
}

void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job)
{
	u32 startcmd = 0;
	u32 *frame_registers = mali_gp_job_get_frame_registers(job);
	u32 counter_src0 = mali_gp_job_get_perf_counter_src0(job);
	u32 counter_src1 = mali_gp_job_get_perf_counter_src1(job);

	MALI_DEBUG_ASSERT_POINTER(core);

	if (mali_gp_job_has_vs_job(job)) {
		startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS;
	}

	if (mali_gp_job_has_plbu_job(job)) {
		startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU;
	}

	MALI_DEBUG_ASSERT(0 != startcmd);

	mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME);

	if (MALI_HW_CORE_NO_COUNTER != counter_src0) {
		mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, counter_src0);
		mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
	}
	if (MALI_HW_CORE_NO_COUNTER != counter_src1) {
		mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, counter_src1);
		mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
	}

	MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd));

	mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC);

	/* Barrier to make sure the previous register write is finished */
	_mali_osk_write_mem_barrier();

	/* This is the command that starts the core.
	 *
	 * Don't actually run the job if PROFILING_SKIP_PP_JOBS are set, just
	 * force core to assert the completion interrupt.
	 */
#if !defined(PROFILING_SKIP_GP_JOBS)
	mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd);
#else
	{
		u32 bits = 0;

		if (mali_gp_job_has_vs_job(job))
			bits = MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST;
		if (mali_gp_job_has_plbu_job(job))
			bits |= MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST;

		mali_hw_core_register_write_relaxed(&core->hw_core,
						    MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, bits);
	}
#endif

	/* Barrier to make sure the previous register write is finished */
	_mali_osk_write_mem_barrier();
}

void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr)
{
	u32 irq_readout;

	MALI_DEBUG_ASSERT_POINTER(core);

	irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT);

	if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM) {
		mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG));
		mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* re-enable interrupts */
		mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, start_addr);
		mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, end_addr);

		MALI_DEBUG_PRINT(3, ("Mali GP: Resuming job\n"));

		mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC);
		_mali_osk_write_mem_barrier();
	}
	/*
	 * else: core has been reset between PLBU_OUT_OF_MEM interrupt and this new heap response.
	 * A timeout or a page fault on Mali-200 PP core can cause this behaviour.
	 */
}

u32 mali_gp_core_get_version(struct mali_gp_core *core)
{
	MALI_DEBUG_ASSERT_POINTER(core);
	return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VERSION);
}

struct mali_gp_core *mali_gp_get_global_gp_core(void)
{
	return mali_global_gp_core;
}

/* ------------- interrupt handling below ------------------ */
static void mali_gp_irq_probe_trigger(void *data)
{
	struct mali_gp_core *core = (struct mali_gp_core *)data;

	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
	mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR);
	_mali_osk_mem_barrier();
}

static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data)
{
	struct mali_gp_core *core = (struct mali_gp_core *)data;
	u32 irq_readout;

	irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
	if (MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR & irq_readout) {
		mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR);
		_mali_osk_mem_barrier();
		return _MALI_OSK_ERR_OK;
	}

	return _MALI_OSK_ERR_FAULT;
}

/* ------ local helper functions below --------- */
#if MALI_STATE_TRACKING
u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size)
{
	int n = 0;

	n += _mali_osk_snprintf(buf + n, size - n, "\tGP: %s\n", core->hw_core.description);

	return n;
}
#endif

void mali_gp_update_performance_counters(struct mali_gp_core *core, struct mali_gp_job *job)
{
	u32 val0 = 0;
	u32 val1 = 0;
	u32 counter_src0 = mali_gp_job_get_perf_counter_src0(job);
	u32 counter_src1 = mali_gp_job_get_perf_counter_src1(job);

	if (MALI_HW_CORE_NO_COUNTER != counter_src0) {
		val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
		mali_gp_job_set_perf_counter_value0(job, val0);

#if defined(CONFIG_MALI400_PROFILING)
		_mali_osk_profiling_report_hw_counter(COUNTER_VP_0_C0, val0);
		_mali_osk_profiling_record_global_counters(COUNTER_VP_0_C0, val0);
#endif

	}

	if (MALI_HW_CORE_NO_COUNTER != counter_src1) {
		val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
		mali_gp_job_set_perf_counter_value1(job, val1);

#if defined(CONFIG_MALI400_PROFILING)
		_mali_osk_profiling_report_hw_counter(COUNTER_VP_0_C1, val1);
		_mali_osk_profiling_record_global_counters(COUNTER_VP_0_C1, val1);
#endif
	}
}
