/*
 * 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.
 */

/**
 * @file mali_osk_mali.c
 * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver
 */
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/platform_device.h>
#include <linux/mali/mali_utgard.h>
#include <linux/of.h>
#include <linux/of_device.h>

#include "mali_osk_mali.h"
#include "mali_kernel_common.h" /* MALI_xxx macros */
#include "mali_osk.h"           /* kernel side OS functions */
#include "mali_kernel_linux.h"

static mali_bool mali_secure_mode_enabled = MALI_FALSE;
static mali_bool mali_secure_mode_supported = MALI_FALSE;

/* Function that init the mali gpu secure mode */
void (*mali_secure_mode_deinit)(void) = NULL;
/* Function that reset GPU and enable the mali gpu secure mode */
int (*mali_gpu_reset_and_secure_mode_enable)(void) = NULL;
/* Function that reset GPU and disable the mali gpu secure mode */
int (*mali_gpu_reset_and_secure_mode_disable)(void) = NULL;

#ifdef CONFIG_MALI_DT

#define MALI_OSK_INVALID_RESOURCE_ADDRESS 0xFFFFFFFF

/**
 * Define the max number of resource we could have.
 */
#define MALI_OSK_MAX_RESOURCE_NUMBER 27

/**
 * Define the max number of resource with interrupts, and they are
 * the first 20 elements in array mali_osk_resource_bank.
 */
#define MALI_OSK_RESOURCE_WITH_IRQ_NUMBER 20

/**
 * pp core start and end location in mali_osk_resource_bank array.
 */
#define MALI_OSK_RESOURCE_PP_LOCATION_START 2
#define MALI_OSK_RESOURCE_PP_LOCATION_END 17

/**
 * L2 cache start and end location in mali_osk_resource_bank array.
 */
#define MALI_OSK_RESOURCE_L2_LOCATION_START 20
#define MALI_OSK_RESOURCE_l2_LOCATION_END 22

/**
 * DMA unit location.
 */
#define MALI_OSK_RESOURCE_DMA_LOCATION 26

static _mali_osk_resource_t mali_osk_resource_bank[MALI_OSK_MAX_RESOURCE_NUMBER] = {
	{.description = "Mali_GP", .base = MALI_OFFSET_GP, .irq_name = "IRQGP",},
	{.description = "Mali_GP_MMU", .base = MALI_OFFSET_GP_MMU, .irq_name = "IRQGPMMU",},
	{.description = "Mali_PP0", .base = MALI_OFFSET_PP0, .irq_name = "IRQPP0",},
	{.description = "Mali_PP0_MMU", .base = MALI_OFFSET_PP0_MMU, .irq_name = "IRQPPMMU0",},
	{.description = "Mali_PP1", .base = MALI_OFFSET_PP1, .irq_name = "IRQPP1",},
	{.description = "Mali_PP1_MMU", .base = MALI_OFFSET_PP1_MMU, .irq_name = "IRQPPMMU1",},
	{.description = "Mali_PP2", .base = MALI_OFFSET_PP2, .irq_name = "IRQPP2",},
	{.description = "Mali_PP2_MMU", .base = MALI_OFFSET_PP2_MMU, .irq_name = "IRQPPMMU2",},
	{.description = "Mali_PP3", .base = MALI_OFFSET_PP3, .irq_name = "IRQPP3",},
	{.description = "Mali_PP3_MMU", .base = MALI_OFFSET_PP3_MMU, .irq_name = "IRQPPMMU3",},
	{.description = "Mali_PP4", .base = MALI_OFFSET_PP4, .irq_name = "IRQPP4",},
	{.description = "Mali_PP4_MMU", .base = MALI_OFFSET_PP4_MMU, .irq_name = "IRQPPMMU4",},
	{.description = "Mali_PP5", .base = MALI_OFFSET_PP5, .irq_name = "IRQPP5",},
	{.description = "Mali_PP5_MMU", .base = MALI_OFFSET_PP5_MMU, .irq_name = "IRQPPMMU5",},
	{.description = "Mali_PP6", .base = MALI_OFFSET_PP6, .irq_name = "IRQPP6",},
	{.description = "Mali_PP6_MMU", .base = MALI_OFFSET_PP6_MMU, .irq_name = "IRQPPMMU6",},
	{.description = "Mali_PP7", .base = MALI_OFFSET_PP7, .irq_name = "IRQPP7",},
	{.description = "Mali_PP7_MMU", .base = MALI_OFFSET_PP7_MMU, .irq_name = "IRQPPMMU",},
	{.description = "Mali_PP_Broadcast", .base = MALI_OFFSET_PP_BCAST, .irq_name = "IRQPP",},
	{.description = "Mali_PMU", .base = MALI_OFFSET_PMU, .irq_name = "IRQPMU",},
	{.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE0,},
	{.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE1,},
	{.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE2,},
	{.description = "Mali_PP_MMU_Broadcast", .base = MALI_OFFSET_PP_BCAST_MMU,},
	{.description = "Mali_Broadcast", .base = MALI_OFFSET_BCAST,},
	{.description = "Mali_DLBU", .base = MALI_OFFSET_DLBU,},
	{.description = "Mali_DMA", .base = MALI_OFFSET_DMA,},
};

static int _mali_osk_get_compatible_name(const char **out_string)
{
	struct device_node *node = mali_platform_device->dev.of_node;

	MALI_DEBUG_ASSERT(NULL != node);

	return of_property_read_string(node, "compatible", out_string);
}

_mali_osk_errcode_t _mali_osk_resource_initialize(void)
{
	mali_bool mali_is_450 = MALI_FALSE, mali_is_470 = MALI_FALSE;
	int i, pp_core_num = 0, l2_core_num = 0;
	struct resource *res;
	const char *compatible_name = NULL;

	if (0 == _mali_osk_get_compatible_name(&compatible_name)) {
		if (0 == strncmp(compatible_name, "arm,mali-450", strlen("arm,mali-450"))) {
			mali_is_450 = MALI_TRUE;
			MALI_DEBUG_PRINT(2, ("mali-450 device tree detected."));
		} else if (0 == strncmp(compatible_name, "arm,mali-470", strlen("arm,mali-470"))) {
			mali_is_470 = MALI_TRUE;
			MALI_DEBUG_PRINT(2, ("mali-470 device tree detected."));
		}
	}

	for (i = 0; i < MALI_OSK_RESOURCE_WITH_IRQ_NUMBER; i++) {
		res = platform_get_resource_byname(mali_platform_device, IORESOURCE_IRQ, mali_osk_resource_bank[i].irq_name);
		if (res) {
			mali_osk_resource_bank[i].irq = res->start;
		} else {
			mali_osk_resource_bank[i].base = MALI_OSK_INVALID_RESOURCE_ADDRESS;
		}
	}

	for (i = MALI_OSK_RESOURCE_PP_LOCATION_START; i <= MALI_OSK_RESOURCE_PP_LOCATION_END; i++) {
		if (MALI_OSK_INVALID_RESOURCE_ADDRESS != mali_osk_resource_bank[i].base) {
			pp_core_num++;
		}
	}

	/* We have to divide by 2, because we caculate twice for only one pp(pp_core and pp_mmu_core). */
	if (0 != pp_core_num % 2) {
		MALI_DEBUG_PRINT(2, ("The value of pp core number isn't normal."));
		return _MALI_OSK_ERR_FAULT;
	}

	pp_core_num /= 2;

	/**
	 * we can caculate the number of l2 cache core according the number of pp core number
	 * and device type(mali400/mali450/mali470).
	 */
	l2_core_num = 1;
	if (mali_is_450) {
		if (pp_core_num > 4) {
			l2_core_num = 3;
		} else if (pp_core_num <= 4) {
			l2_core_num = 2;
		}
	}

	for (i = MALI_OSK_RESOURCE_l2_LOCATION_END; i > MALI_OSK_RESOURCE_L2_LOCATION_START + l2_core_num - 1; i--) {
		mali_osk_resource_bank[i].base = MALI_OSK_INVALID_RESOURCE_ADDRESS;
	}

	/* If device is not mali-450 type, we have to remove related resource from resource bank. */
	if (!(mali_is_450 || mali_is_470)) {
		for (i = MALI_OSK_RESOURCE_l2_LOCATION_END + 1; i < MALI_OSK_MAX_RESOURCE_NUMBER; i++) {
			mali_osk_resource_bank[i].base = MALI_OSK_INVALID_RESOURCE_ADDRESS;
		}
	}

	if (mali_is_470)
		mali_osk_resource_bank[MALI_OSK_RESOURCE_DMA_LOCATION].base = MALI_OSK_INVALID_RESOURCE_ADDRESS;

	return _MALI_OSK_ERR_OK;
}

_mali_osk_errcode_t _mali_osk_resource_find(u32 addr, _mali_osk_resource_t *res)
{
	int i;

	if (NULL == mali_platform_device) {
		return _MALI_OSK_ERR_ITEM_NOT_FOUND;
	}

	/* Traverse all of resources in resources bank to find the matching one. */
	for (i = 0; i < MALI_OSK_MAX_RESOURCE_NUMBER; i++) {
		if (mali_osk_resource_bank[i].base == addr) {
			if (NULL != res) {
				res->base = addr + _mali_osk_resource_base_address();
				res->description = mali_osk_resource_bank[i].description;
				res->irq = mali_osk_resource_bank[i].irq;
			}
			return _MALI_OSK_ERR_OK;
		}
	}

	return _MALI_OSK_ERR_ITEM_NOT_FOUND;
}

uintptr_t _mali_osk_resource_base_address(void)
{
	struct resource *reg_res = NULL;
	uintptr_t ret = 0;

	reg_res = platform_get_resource(mali_platform_device, IORESOURCE_MEM, 0);

	if (NULL != reg_res) {
		ret = reg_res->start;
	}

	return ret;
}

void _mali_osk_device_data_pmu_config_get(u16 *domain_config_array, int array_size)
{
	struct device_node *node = mali_platform_device->dev.of_node;
	struct property *prop;
	const __be32 *p;
	int length = 0, i = 0;
	u32 u;

	MALI_DEBUG_PRINT(2, ("Get pmu config from device tree configuration.\n"));

	MALI_DEBUG_ASSERT(NULL != node);

	if (!of_get_property(node, "pmu_domain_config", &length)) {
		return;
	}

	if (array_size != length / sizeof(u32)) {
		MALI_PRINT_ERROR(("Wrong pmu domain config in device tree."));
		return;
	}

	of_property_for_each_u32(node, "pmu_domain_config", prop, p, u) {
		domain_config_array[i] = (u16)u;
		i++;
	}

	return;
}

u32 _mali_osk_get_pmu_switch_delay(void)
{
	struct device_node *node = mali_platform_device->dev.of_node;
	u32 switch_delay;

	MALI_DEBUG_ASSERT(NULL != node);

	if (0 == of_property_read_u32(node, "pmu_switch_delay", &switch_delay)) {
		return switch_delay;
	} else {
		MALI_DEBUG_PRINT(2, ("Couldn't find pmu_switch_delay in device tree configuration.\n"));
	}

	return 0;
}

#else /* CONFIG_MALI_DT */

_mali_osk_errcode_t _mali_osk_resource_find(u32 addr, _mali_osk_resource_t *res)
{
	int i;
	uintptr_t phys_addr;

	if (NULL == mali_platform_device) {
		/* Not connected to a device */
		return _MALI_OSK_ERR_ITEM_NOT_FOUND;
	}

	phys_addr = addr + _mali_osk_resource_base_address();
	for (i = 0; i < mali_platform_device->num_resources; i++) {
		if (IORESOURCE_MEM == resource_type(&(mali_platform_device->resource[i])) &&
		    mali_platform_device->resource[i].start == phys_addr) {
			if (NULL != res) {
				res->base = phys_addr;
				res->description = mali_platform_device->resource[i].name;

				/* Any (optional) IRQ resource belonging to this resource will follow */
				if ((i + 1) < mali_platform_device->num_resources &&
				    IORESOURCE_IRQ == resource_type(&(mali_platform_device->resource[i + 1]))) {
					res->irq = mali_platform_device->resource[i + 1].start;
				} else {
					res->irq = -1;
				}
			}
			return _MALI_OSK_ERR_OK;
		}
	}

	return _MALI_OSK_ERR_ITEM_NOT_FOUND;
}

uintptr_t _mali_osk_resource_base_address(void)
{
	uintptr_t lowest_addr = (uintptr_t)(0 - 1);
	uintptr_t ret = 0;

	if (NULL != mali_platform_device) {
		int i;
		for (i = 0; i < mali_platform_device->num_resources; i++) {
			if (mali_platform_device->resource[i].flags & IORESOURCE_MEM &&
			    mali_platform_device->resource[i].start < lowest_addr) {
				lowest_addr = mali_platform_device->resource[i].start;
				ret = lowest_addr;
			}
		}
	}

	return ret;
}

void _mali_osk_device_data_pmu_config_get(u16 *domain_config_array, int array_size)
{
	_mali_osk_device_data data = { 0, };

	MALI_DEBUG_PRINT(2, ("Get pmu config from platform device data.\n"));
	if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
		/* Copy the custom customer power domain config */
		_mali_osk_memcpy(domain_config_array, data.pmu_domain_config, sizeof(data.pmu_domain_config));
	}

	return;
}

u32 _mali_osk_get_pmu_switch_delay(void)
{
	_mali_osk_errcode_t err;
	_mali_osk_device_data data = { 0, };

	err = _mali_osk_device_data_get(&data);

	if (_MALI_OSK_ERR_OK == err) {
		return data.pmu_switch_delay;
	}

	return 0;
}
#endif /* CONFIG_MALI_DT */

_mali_osk_errcode_t _mali_osk_device_data_get(_mali_osk_device_data *data)
{
	MALI_DEBUG_ASSERT_POINTER(data);

	if (NULL != mali_platform_device) {
		struct mali_gpu_device_data *os_data = NULL;

		os_data = (struct mali_gpu_device_data *)mali_platform_device->dev.platform_data;
		if (NULL != os_data) {
			/* Copy data from OS dependant struct to Mali neutral struct (identical!) */
			BUILD_BUG_ON(sizeof(*os_data) != sizeof(*data));
			_mali_osk_memcpy(data, os_data, sizeof(*os_data));

			return _MALI_OSK_ERR_OK;
		}
	}

	return _MALI_OSK_ERR_ITEM_NOT_FOUND;
}

u32 _mali_osk_identify_gpu_resource(void)
{
	if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_L2_RESOURCE1, NULL))
		/* Mali 450 */
		return 0x450;

	if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(MALI_OFFSET_DLBU, NULL))
		/* Mali 470 */
		return 0x470;

	/* Mali 400 */
	return 0x400;
}

mali_bool _mali_osk_shared_interrupts(void)
{
	u32 irqs[128];
	u32 i, j, irq, num_irqs_found = 0;

	MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
	MALI_DEBUG_ASSERT(128 >= mali_platform_device->num_resources);

	for (i = 0; i < mali_platform_device->num_resources; i++) {
		if (IORESOURCE_IRQ & mali_platform_device->resource[i].flags) {
			irq = mali_platform_device->resource[i].start;

			for (j = 0; j < num_irqs_found; ++j) {
				if (irq == irqs[j]) {
					return MALI_TRUE;
				}
			}

			irqs[num_irqs_found++] = irq;
		}
	}

	return MALI_FALSE;
}

_mali_osk_errcode_t _mali_osk_gpu_secure_mode_init(void)
{
	_mali_osk_device_data data = { 0, };

	if (_MALI_OSK_ERR_OK ==  _mali_osk_device_data_get(&data)) {
		if ((NULL != data.secure_mode_init) && (NULL != data.secure_mode_deinit)
		    && (NULL != data.gpu_reset_and_secure_mode_enable) && (NULL != data.gpu_reset_and_secure_mode_disable)) {
			int err = data.secure_mode_init();
			if (err) {
				MALI_DEBUG_PRINT(1, ("Failed to init gpu secure mode.\n"));
				return _MALI_OSK_ERR_FAULT;
			}

			mali_secure_mode_deinit = data.secure_mode_deinit;
			mali_gpu_reset_and_secure_mode_enable = data.gpu_reset_and_secure_mode_enable;
			mali_gpu_reset_and_secure_mode_disable = data.gpu_reset_and_secure_mode_disable;

			mali_secure_mode_supported = MALI_TRUE;
			mali_secure_mode_enabled = MALI_FALSE;
			return _MALI_OSK_ERR_OK;
		}
	}
	MALI_DEBUG_PRINT(3, ("GPU secure mode not supported.\n"));
	return _MALI_OSK_ERR_UNSUPPORTED;

}

_mali_osk_errcode_t _mali_osk_gpu_secure_mode_deinit(void)
{
	if (NULL !=  mali_secure_mode_deinit) {
		mali_secure_mode_deinit();
		mali_secure_mode_enabled = MALI_FALSE;
		mali_secure_mode_supported = MALI_FALSE;
		return _MALI_OSK_ERR_OK;
	}
	MALI_DEBUG_PRINT(3, ("GPU secure mode not supported.\n"));
	return _MALI_OSK_ERR_UNSUPPORTED;

}


_mali_osk_errcode_t _mali_osk_gpu_reset_and_secure_mode_enable(void)
{
	/* the mali executor lock must be held before enter this function. */

	MALI_DEBUG_ASSERT(MALI_FALSE == mali_secure_mode_enabled);

	if (NULL !=  mali_gpu_reset_and_secure_mode_enable) {
		if (mali_gpu_reset_and_secure_mode_enable()) {
			MALI_DEBUG_PRINT(1, ("Failed to reset GPU or enable gpu secure mode.\n"));
			return _MALI_OSK_ERR_FAULT;
		}
		mali_secure_mode_enabled = MALI_TRUE;
		return _MALI_OSK_ERR_OK;
	}
	MALI_DEBUG_PRINT(1, ("GPU secure mode not supported.\n"));
	return _MALI_OSK_ERR_UNSUPPORTED;
}

_mali_osk_errcode_t _mali_osk_gpu_reset_and_secure_mode_disable(void)
{
	/* the mali executor lock must be held before enter this function. */

	MALI_DEBUG_ASSERT(MALI_TRUE == mali_secure_mode_enabled);

	if (NULL != mali_gpu_reset_and_secure_mode_disable) {
		if (mali_gpu_reset_and_secure_mode_disable()) {
			MALI_DEBUG_PRINT(1, ("Failed to reset GPU or disable gpu secure mode.\n"));
			return _MALI_OSK_ERR_FAULT;
		}
		mali_secure_mode_enabled = MALI_FALSE;

		return _MALI_OSK_ERR_OK;

	}
	MALI_DEBUG_PRINT(1, ("GPU secure mode not supported.\n"));
	return _MALI_OSK_ERR_UNSUPPORTED;

}

mali_bool _mali_osk_gpu_secure_mode_is_enabled(void)
{
	return mali_secure_mode_enabled;
}

mali_bool _mali_osk_gpu_secure_mode_is_supported(void)
{
	return mali_secure_mode_supported;
}


