/*
 * Copyright (C) 2010-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_kernel_common.h"
#include "mali_osk.h"
#include "mali_l2_cache.h"
#include "mali_hw_core.h"
#include "mali_scheduler.h"
#include "mali_pm.h"
#include "mali_pm_domain.h"

/**
 * Size of the Mali L2 cache registers in bytes
 */
#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30

/**
 * Mali L2 cache register numbers
 * Used in the register read/write routines.
 * See the hardware documentation for more information about each register
 */
typedef enum mali_l2_cache_register {
	MALI400_L2_CACHE_REGISTER_SIZE         = 0x0004,
	MALI400_L2_CACHE_REGISTER_STATUS       = 0x0008,
	/*unused                               = 0x000C */
	MALI400_L2_CACHE_REGISTER_COMMAND      = 0x0010,
	MALI400_L2_CACHE_REGISTER_CLEAR_PAGE   = 0x0014,
	MALI400_L2_CACHE_REGISTER_MAX_READS    = 0x0018,
	MALI400_L2_CACHE_REGISTER_ENABLE       = 0x001C,
	MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0020,
	MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0024,
	MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x0028,
	MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x002C,
} mali_l2_cache_register;

/**
 * Mali L2 cache commands
 * These are the commands that can be sent to the Mali L2 cache unit
 */
typedef enum mali_l2_cache_command {
	MALI400_L2_CACHE_COMMAND_CLEAR_ALL = 0x01,
} mali_l2_cache_command;

/**
 * Mali L2 cache commands
 * These are the commands that can be sent to the Mali L2 cache unit
 */
typedef enum mali_l2_cache_enable {
	MALI400_L2_CACHE_ENABLE_DEFAULT = 0x0, /* Default */
	MALI400_L2_CACHE_ENABLE_ACCESS = 0x01,
	MALI400_L2_CACHE_ENABLE_READ_ALLOCATE = 0x02,
} mali_l2_cache_enable;

/**
 * Mali L2 cache status bits
 */
typedef enum mali_l2_cache_status {
	MALI400_L2_CACHE_STATUS_COMMAND_BUSY = 0x01,
	MALI400_L2_CACHE_STATUS_DATA_BUSY    = 0x02,
} mali_l2_cache_status;

#define MALI400_L2_MAX_READS_NOT_SET -1

static struct mali_l2_cache_core *
	mali_global_l2s[MALI_MAX_NUMBER_OF_L2_CACHE_CORES] = { NULL, };
static u32 mali_global_num_l2s = 0;

int mali_l2_max_reads = MALI400_L2_MAX_READS_NOT_SET;


/* Local helper functions */

static void mali_l2_cache_reset(struct mali_l2_cache_core *cache);

static _mali_osk_errcode_t mali_l2_cache_send_command(
	struct mali_l2_cache_core *cache, u32 reg, u32 val);

static void mali_l2_cache_lock(struct mali_l2_cache_core *cache)
{
	MALI_DEBUG_ASSERT_POINTER(cache);
	_mali_osk_spinlock_irq_lock(cache->lock);
}

static void mali_l2_cache_unlock(struct mali_l2_cache_core *cache)
{
	MALI_DEBUG_ASSERT_POINTER(cache);
	_mali_osk_spinlock_irq_unlock(cache->lock);
}

/* Implementation of the L2 cache interface */

struct mali_l2_cache_core *mali_l2_cache_create(
	_mali_osk_resource_t *resource, u32 domain_index)
{
	struct mali_l2_cache_core *cache = NULL;
#if defined(DEBUG)
	u32 cache_size;
#endif

	MALI_DEBUG_PRINT(4, ("Mali L2 cache: Creating Mali L2 cache: %s\n",
			     resource->description));

	if (mali_global_num_l2s >= MALI_MAX_NUMBER_OF_L2_CACHE_CORES) {
		MALI_PRINT_ERROR(("Mali L2 cache: Too many L2 caches\n"));
		return NULL;
	}

	cache = _mali_osk_malloc(sizeof(struct mali_l2_cache_core));
	if (NULL == cache) {
		MALI_PRINT_ERROR(("Mali L2 cache: Failed to allocate memory for L2 cache core\n"));
		return NULL;
	}

	cache->core_id =  mali_global_num_l2s;
	cache->counter_src0 = MALI_HW_CORE_NO_COUNTER;
	cache->counter_src1 = MALI_HW_CORE_NO_COUNTER;
	cache->counter_value0_base = 0;
	cache->counter_value1_base = 0;
	cache->pm_domain = NULL;
	cache->power_is_on = MALI_FALSE;
	cache->last_invalidated_id = 0;

	if (_MALI_OSK_ERR_OK != mali_hw_core_create(&cache->hw_core,
			resource, MALI400_L2_CACHE_REGISTERS_SIZE)) {
		_mali_osk_free(cache);
		return NULL;
	}

#if defined(DEBUG)
	cache_size = mali_hw_core_register_read(&cache->hw_core,
						MALI400_L2_CACHE_REGISTER_SIZE);
	MALI_DEBUG_PRINT(2, ("Mali L2 cache: Created %s: % 3uK, %u-way, % 2ubyte cache line, % 3ubit external bus\n",
			     resource->description,
			     1 << (((cache_size >> 16) & 0xff) - 10),
			     1 << ((cache_size >> 8) & 0xff),
			     1 << (cache_size & 0xff),
			     1 << ((cache_size >> 24) & 0xff)));
#endif

	cache->lock = _mali_osk_spinlock_irq_init(_MALI_OSK_LOCKFLAG_ORDERED,
			_MALI_OSK_LOCK_ORDER_L2);
	if (NULL == cache->lock) {
		MALI_PRINT_ERROR(("Mali L2 cache: Failed to create counter lock for L2 cache core %s\n",
				  cache->hw_core.description));
		mali_hw_core_delete(&cache->hw_core);
		_mali_osk_free(cache);
		return NULL;
	}

	/* register with correct power domain */
	cache->pm_domain = mali_pm_register_l2_cache(
				   domain_index, cache);

	mali_global_l2s[mali_global_num_l2s] = cache;
	mali_global_num_l2s++;

	return cache;
}

void mali_l2_cache_delete(struct mali_l2_cache_core *cache)
{
	u32 i;
	for (i = 0; i < mali_global_num_l2s; i++) {
		if (mali_global_l2s[i] != cache) {
			continue;
		}

		mali_global_l2s[i] = NULL;
		mali_global_num_l2s--;

		if (i == mali_global_num_l2s) {
			/* Removed last element, nothing more to do */
			break;
		}

		/*
		 * We removed a l2 cache from the middle of the array,
		 * so move the last l2 cache to current position
		 */
		mali_global_l2s[i] = mali_global_l2s[mali_global_num_l2s];
		mali_global_l2s[mali_global_num_l2s] = NULL;

		/* All good */
		break;
	}

	_mali_osk_spinlock_irq_term(cache->lock);
	mali_hw_core_delete(&cache->hw_core);
	_mali_osk_free(cache);
}

void mali_l2_cache_power_up(struct mali_l2_cache_core *cache)
{
	MALI_DEBUG_ASSERT_POINTER(cache);

	mali_l2_cache_lock(cache);

	mali_l2_cache_reset(cache);

	if ((1 << MALI_DOMAIN_INDEX_DUMMY) != cache->pm_domain->pmu_mask)
		MALI_DEBUG_ASSERT(MALI_FALSE == cache->power_is_on);
	cache->power_is_on = MALI_TRUE;

	mali_l2_cache_unlock(cache);
}

void mali_l2_cache_power_down(struct mali_l2_cache_core *cache)
{
	MALI_DEBUG_ASSERT_POINTER(cache);

	mali_l2_cache_lock(cache);

	MALI_DEBUG_ASSERT(MALI_TRUE == cache->power_is_on);

	/*
	 * The HW counters will start from zero again when we resume,
	 * but we should report counters as always increasing.
	 * Take a copy of the HW values now in order to add this to
	 * the values we report after being powered up.
	 *
	 * The physical power off of the L2 cache might be outside our
	 * own control (e.g. runtime PM). That is why we must manually
	 * set set the counter value to zero as well.
	 */

	if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) {
		cache->counter_value0_base += mali_hw_core_register_read(
						      &cache->hw_core,
						      MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0);
		mali_hw_core_register_write(&cache->hw_core,
					    MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0, 0);
	}

	if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER) {
		cache->counter_value1_base += mali_hw_core_register_read(
						      &cache->hw_core,
						      MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1);
		mali_hw_core_register_write(&cache->hw_core,
					    MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1, 0);
	}


	cache->power_is_on = MALI_FALSE;

	mali_l2_cache_unlock(cache);
}

void mali_l2_cache_core_set_counter_src(
	struct mali_l2_cache_core *cache, u32 source_id, u32 counter)
{
	u32 reg_offset_src;
	u32 reg_offset_val;

	MALI_DEBUG_ASSERT_POINTER(cache);
	MALI_DEBUG_ASSERT(source_id >= 0 && source_id <= 1);

	mali_l2_cache_lock(cache);

	if (0 == source_id) {
		/* start counting from 0 */
		cache->counter_value0_base = 0;
		cache->counter_src0 = counter;
		reg_offset_src = MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0;
		reg_offset_val = MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0;
	} else {
		/* start counting from 0 */
		cache->counter_value1_base = 0;
		cache->counter_src1 = counter;
		reg_offset_src = MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1;
		reg_offset_val = MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1;
	}

	if (cache->power_is_on) {
		u32 hw_src;

		if (MALI_HW_CORE_NO_COUNTER != counter) {
			hw_src = counter;
		} else {
			hw_src = 0; /* disable value for HW */
		}

		/* Set counter src */
		mali_hw_core_register_write(&cache->hw_core,
					    reg_offset_src, hw_src);

		/* Make sure the HW starts counting from 0 again */
		mali_hw_core_register_write(&cache->hw_core,
					    reg_offset_val, 0);
	}

	mali_l2_cache_unlock(cache);
}

void mali_l2_cache_core_get_counter_values(
	struct mali_l2_cache_core *cache,
	u32 *src0, u32 *value0, u32 *src1, u32 *value1)
{
	MALI_DEBUG_ASSERT_POINTER(cache);
	MALI_DEBUG_ASSERT(NULL != src0);
	MALI_DEBUG_ASSERT(NULL != value0);
	MALI_DEBUG_ASSERT(NULL != src1);
	MALI_DEBUG_ASSERT(NULL != value1);

	mali_l2_cache_lock(cache);

	*src0 = cache->counter_src0;
	*src1 = cache->counter_src1;

	if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) {
		if (MALI_TRUE == cache->power_is_on) {
			*value0 = mali_hw_core_register_read(&cache->hw_core,
							     MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0);
		} else {
			*value0 = 0;
		}

		/* Add base offset value (in case we have been power off) */
		*value0 += cache->counter_value0_base;
	}

	if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER) {
		if (MALI_TRUE == cache->power_is_on) {
			*value1 = mali_hw_core_register_read(&cache->hw_core,
							     MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1);
		} else {
			*value1 = 0;
		}

		/* Add base offset value (in case we have been power off) */
		*value1 += cache->counter_value1_base;
	}

	mali_l2_cache_unlock(cache);
}

struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index)
{
	if (mali_global_num_l2s > index) {
		return mali_global_l2s[index];
	}

	return NULL;
}

u32 mali_l2_cache_core_get_glob_num_l2_cores(void)
{
	return mali_global_num_l2s;
}

void mali_l2_cache_invalidate(struct mali_l2_cache_core *cache)
{
	MALI_DEBUG_ASSERT_POINTER(cache);

	if (NULL == cache) {
		return;
	}

	mali_l2_cache_lock(cache);

	cache->last_invalidated_id = mali_scheduler_get_new_cache_order();
	mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND,
				   MALI400_L2_CACHE_COMMAND_CLEAR_ALL);

	mali_l2_cache_unlock(cache);
}

void mali_l2_cache_invalidate_conditional(
	struct mali_l2_cache_core *cache, u32 id)
{
	MALI_DEBUG_ASSERT_POINTER(cache);

	if (NULL == cache) {
		return;
	}

	/*
	 * If the last cache invalidation was done by a job with a higher id we
	 * don't have to flush. Since user space will store jobs w/ their
	 * corresponding memory in sequence (first job #0, then job #1, ...),
	 * we don't have to flush for job n-1 if job n has already invalidated
	 * the cache since we know for sure that job n-1's memory was already
	 * written when job n was started.
	 */

	mali_l2_cache_lock(cache);

	if (((s32)id) > ((s32)cache->last_invalidated_id)) {
		/* Set latest invalidated id to current "point in time" */
		cache->last_invalidated_id =
			mali_scheduler_get_new_cache_order();
		mali_l2_cache_send_command(cache,
					   MALI400_L2_CACHE_REGISTER_COMMAND,
					   MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
	}

	mali_l2_cache_unlock(cache);
}

void mali_l2_cache_invalidate_all(void)
{
	u32 i;
	for (i = 0; i < mali_global_num_l2s; i++) {
		struct mali_l2_cache_core *cache = mali_global_l2s[i];
		_mali_osk_errcode_t ret;

		MALI_DEBUG_ASSERT_POINTER(cache);

		mali_l2_cache_lock(cache);

		if (MALI_TRUE != cache->power_is_on) {
			mali_l2_cache_unlock(cache);
			continue;
		}

		cache->last_invalidated_id =
			mali_scheduler_get_new_cache_order();

		ret = mali_l2_cache_send_command(cache,
						 MALI400_L2_CACHE_REGISTER_COMMAND,
						 MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
		if (_MALI_OSK_ERR_OK != ret) {
			MALI_PRINT_ERROR(("Failed to invalidate cache\n"));
		}

		mali_l2_cache_unlock(cache);
	}
}

void mali_l2_cache_invalidate_all_pages(u32 *pages, u32 num_pages)
{
	u32 i;
	for (i = 0; i < mali_global_num_l2s; i++) {
		struct mali_l2_cache_core *cache = mali_global_l2s[i];
		u32 j;

		MALI_DEBUG_ASSERT_POINTER(cache);

		mali_l2_cache_lock(cache);

		if (MALI_TRUE != cache->power_is_on) {
			mali_l2_cache_unlock(cache);
			continue;
		}

		for (j = 0; j < num_pages; j++) {
			_mali_osk_errcode_t ret;

			ret = mali_l2_cache_send_command(cache,
							 MALI400_L2_CACHE_REGISTER_CLEAR_PAGE,
							 pages[j]);
			if (_MALI_OSK_ERR_OK != ret) {
				MALI_PRINT_ERROR(("Failed to invalidate cache (page)\n"));
			}
		}

		mali_l2_cache_unlock(cache);
	}
}

/* -------- local helper functions below -------- */

static void mali_l2_cache_reset(struct mali_l2_cache_core *cache)
{
    MALI_DEBUG_ASSERT_POINTER(cache);
    MALI_DEBUG_ASSERT_LOCK_HELD(cache->lock);

    /* Kasin Added, skip off power domain. */
    if (cache && cache->pm_domain && cache->pm_domain->power_is_on == MALI_FALSE) {
        printk("===========%s, %d skip off power domain?\n", __FUNCTION__, __LINE__);
    }


    /* Invalidate cache (just to keep it in a known state at startup) */
    mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND,
            MALI400_L2_CACHE_COMMAND_CLEAR_ALL);

    /* Enable cache */
    mali_hw_core_register_write(&cache->hw_core,
            MALI400_L2_CACHE_REGISTER_ENABLE,
            (u32)MALI400_L2_CACHE_ENABLE_ACCESS |
            (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE);

	if (MALI400_L2_MAX_READS_NOT_SET != mali_l2_max_reads) {
		mali_hw_core_register_write(&cache->hw_core,
					    MALI400_L2_CACHE_REGISTER_MAX_READS,
					    (u32)mali_l2_max_reads);
	}

	/* Restart any performance counters (if enabled) */
	if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) {

		mali_hw_core_register_write(&cache->hw_core,
					    MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0,
					    cache->counter_src0);
	}

	if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER) {
		mali_hw_core_register_write(&cache->hw_core,
					    MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1,
					    cache->counter_src1);
	}
}

static _mali_osk_errcode_t mali_l2_cache_send_command(
	struct mali_l2_cache_core *cache, u32 reg, u32 val)
{
	int i = 0;
	const int loop_count = 100000;

	MALI_DEBUG_ASSERT_POINTER(cache);
	MALI_DEBUG_ASSERT_LOCK_HELD(cache->lock);

	/*
	 * First, wait for L2 cache command handler to go idle.
	 * (Commands received while processing another command will be ignored)
	 */
	for (i = 0; i < loop_count; i++) {
		if (!(mali_hw_core_register_read(&cache->hw_core,
						 MALI400_L2_CACHE_REGISTER_STATUS) &
		      (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY)) {
			break;
		}
	}

	if (i == loop_count) {
		MALI_DEBUG_PRINT(1, ("Mali L2 cache: aborting wait for command interface to go idle\n"));
		return _MALI_OSK_ERR_FAULT;
	}

	/* then issue the command */
	mali_hw_core_register_write(&cache->hw_core, reg, val);

	return _MALI_OSK_ERR_OK;
}
