/*
 * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <stdint.h>

#include <platform_def.h>

#include <common/debug.h>
#include <drivers/st/etzpc.h>
#include <drivers/st/stm32_gpio.h>

#include <stm32mp_shared_resources.h>

/*
 * Once one starts to get the resource registering state, one cannot register
 * new resources. This ensures resource state cannot change.
 */
static bool registering_locked;

/*
 * Shared peripherals and resources registration
 *
 * Each resource assignation is stored in a table. The state defaults
 * to PERIPH_UNREGISTERED if the resource is not explicitly assigned.
 *
 * Resource driver that as not embedded (a.k.a their related CFG_xxx build
 * directive is disabled) are assigned to the non-secure world.
 *
 * Each pin of the GPIOZ bank can be secure or non-secure.
 *
 * It is the platform responsibility the ensure resource assignation
 * matches the access permission firewalls configuration.
 */
enum shres_state {
	SHRES_UNREGISTERED = 0,
	SHRES_SECURE,
	SHRES_NON_SECURE,
};

/* Force uint8_t array for array of enum shres_state for size considerations */
static uint8_t shres_state[STM32MP1_SHRES_COUNT];

static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] __unused = {
	[STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0",
	[STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1",
	[STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2",
	[STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3",
	[STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4",
	[STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5",
	[STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6",
	[STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7",
	[STM32MP1_SHRES_IWDG1] = "IWDG1",
	[STM32MP1_SHRES_USART1] = "USART1",
	[STM32MP1_SHRES_SPI6] = "SPI6",
	[STM32MP1_SHRES_I2C4] = "I2C4",
	[STM32MP1_SHRES_RNG1] = "RNG1",
	[STM32MP1_SHRES_HASH1] = "HASH1",
	[STM32MP1_SHRES_CRYP1] = "CRYP1",
	[STM32MP1_SHRES_I2C6] = "I2C6",
	[STM32MP1_SHRES_RTC] = "RTC",
	[STM32MP1_SHRES_MCU] = "MCU",
	[STM32MP1_SHRES_MDMA] = "MDMA",
	[STM32MP1_SHRES_PLL3] = "PLL3",
};

static const char __unused *shres2str_id(enum stm32mp_shres id)
{
	assert(id < ARRAY_SIZE(shres2str_id_tbl));

	return shres2str_id_tbl[id];
}

static const char __unused *shres2str_state_tbl[] = {
	[SHRES_UNREGISTERED] = "unregistered",
	[SHRES_NON_SECURE] = "non-secure",
	[SHRES_SECURE] = "secure",
};

static const char __unused *shres2str_state(unsigned int state)
{
	assert(state < ARRAY_SIZE(shres2str_state_tbl));

	return shres2str_state_tbl[state];
}

/* Get resource state: these accesses lock the registering support */
static void lock_registering(void)
{
	registering_locked = true;
}

static bool periph_is_non_secure(enum stm32mp_shres id)
{
	lock_registering();

	return (shres_state[id] == SHRES_NON_SECURE) ||
	       (shres_state[id] == SHRES_UNREGISTERED);
}

static bool periph_is_secure(enum stm32mp_shres id)
{
	return !periph_is_non_secure(id);
}

/* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */
static int8_t gpioz_nbpin = -1;

static unsigned int get_gpio_nbpin(unsigned int bank)
{
	if (bank != GPIO_BANK_Z) {
		int count = fdt_get_gpio_bank_pin_count(bank);

		assert((count >= 0) || (count <= (GPIO_PIN_MAX + 1)));

		return (unsigned int)count;
	}

	if (gpioz_nbpin < 0) {
		int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z);

		assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT));

		gpioz_nbpin = count;
	}

	return (unsigned int)gpioz_nbpin;
}

static unsigned int get_gpioz_nbpin(void)
{
	return get_gpio_nbpin(GPIO_BANK_Z);
}

static void register_periph(enum stm32mp_shres id, unsigned int state)
{
	assert((id < STM32MP1_SHRES_COUNT) &&
	       ((state == SHRES_SECURE) || (state == SHRES_NON_SECURE)));

	if (registering_locked) {
		if (shres_state[id] == state) {
			return;
		}
		panic();
	}

	if ((shres_state[id] != SHRES_UNREGISTERED) &&
	    (shres_state[id] != state)) {
		VERBOSE("Cannot change %s from %s to %s\n",
			shres2str_id(id),
			shres2str_state(shres_state[id]),
			shres2str_state(state));
		panic();
	}

	if (shres_state[id] == SHRES_UNREGISTERED) {
		VERBOSE("Register %s as %s\n",
			shres2str_id(id), shres2str_state(state));
	}

	if ((id >= STM32MP1_SHRES_GPIOZ(0)) &&
	    (id <= STM32MP1_SHRES_GPIOZ(7)) &&
	    ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) {
		ERROR("Invalid GPIO pin %u, %u pin(s) available\n",
		      id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin());
		panic();
	}

	shres_state[id] = (uint8_t)state;

	/* Explore clock tree to lock dependencies */
	if (state == SHRES_SECURE) {
		enum stm32mp_shres clock_res_id;

		switch (id) {
		case STM32MP1_SHRES_GPIOZ(0):
		case STM32MP1_SHRES_GPIOZ(1):
		case STM32MP1_SHRES_GPIOZ(2):
		case STM32MP1_SHRES_GPIOZ(3):
		case STM32MP1_SHRES_GPIOZ(4):
		case STM32MP1_SHRES_GPIOZ(5):
		case STM32MP1_SHRES_GPIOZ(6):
		case STM32MP1_SHRES_GPIOZ(7):
			clock_res_id = GPIOZ;
			break;
		case STM32MP1_SHRES_IWDG1:
			clock_res_id = IWDG1;
			break;
		case STM32MP1_SHRES_USART1:
			clock_res_id = USART1_K;
			break;
		case STM32MP1_SHRES_SPI6:
			clock_res_id = SPI6_K;
			break;
		case STM32MP1_SHRES_I2C4:
			clock_res_id = I2C4_K;
			break;
		case STM32MP1_SHRES_RNG1:
			clock_res_id = RNG1_K;
			break;
		case STM32MP1_SHRES_HASH1:
			clock_res_id = HASH1;
			break;
		case STM32MP1_SHRES_CRYP1:
			clock_res_id = CRYP1;
			break;
		case STM32MP1_SHRES_I2C6:
			clock_res_id = I2C6_K;
			break;
		case STM32MP1_SHRES_RTC:
			clock_res_id = RTC;
			break;
		default:
			/* No clock resource dependency */
			return;
		}

		stm32mp1_register_clock_parents_secure(clock_res_id);
	}
}

/* Register resource by ID */
void stm32mp_register_secure_periph(enum stm32mp_shres id)
{
	register_periph(id, SHRES_SECURE);
}

void stm32mp_register_non_secure_periph(enum stm32mp_shres id)
{
	register_periph(id, SHRES_NON_SECURE);
}

static void register_periph_iomem(uintptr_t base, unsigned int state)
{
	enum stm32mp_shres id;

	switch (base) {
	case CRYP1_BASE:
		id = STM32MP1_SHRES_CRYP1;
		break;
	case HASH1_BASE:
		id = STM32MP1_SHRES_HASH1;
		break;
	case I2C4_BASE:
		id = STM32MP1_SHRES_I2C4;
		break;
	case I2C6_BASE:
		id = STM32MP1_SHRES_I2C6;
		break;
	case IWDG1_BASE:
		id = STM32MP1_SHRES_IWDG1;
		break;
	case RNG1_BASE:
		id = STM32MP1_SHRES_RNG1;
		break;
	case RTC_BASE:
		id = STM32MP1_SHRES_RTC;
		break;
	case SPI6_BASE:
		id = STM32MP1_SHRES_SPI6;
		break;
	case USART1_BASE:
		id = STM32MP1_SHRES_USART1;
		break;

	case GPIOA_BASE:
	case GPIOB_BASE:
	case GPIOC_BASE:
	case GPIOD_BASE:
	case GPIOE_BASE:
	case GPIOF_BASE:
	case GPIOG_BASE:
	case GPIOH_BASE:
	case GPIOI_BASE:
	case GPIOJ_BASE:
	case GPIOK_BASE:
	case USART2_BASE:
	case USART3_BASE:
	case UART4_BASE:
	case UART5_BASE:
	case USART6_BASE:
	case UART7_BASE:
	case UART8_BASE:
	case IWDG2_BASE:
		/* Allow drivers to register some non-secure resources */
		VERBOSE("IO for non-secure resource 0x%x\n",
			(unsigned int)base);
		if (state != SHRES_NON_SECURE) {
			panic();
		}

		return;

	default:
		panic();
	}

	register_periph(id, state);
}

void stm32mp_register_secure_periph_iomem(uintptr_t base)
{
	register_periph_iomem(base, SHRES_SECURE);
}

void stm32mp_register_non_secure_periph_iomem(uintptr_t base)
{
	register_periph_iomem(base, SHRES_NON_SECURE);
}

void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin)
{
	switch (bank) {
	case GPIO_BANK_Z:
		register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_SECURE);
		break;
	default:
		ERROR("GPIO bank %u cannot be secured\n", bank);
		panic();
	}
}

void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin)
{
	switch (bank) {
	case GPIO_BANK_Z:
		register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_NON_SECURE);
		break;
	default:
		break;
	}
}

static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank)
{
	unsigned int non_secure = 0U;
	unsigned int i;

	lock_registering();

	if (bank != GPIO_BANK_Z) {
		return true;
	}

	for (i = 0U; i < get_gpioz_nbpin(); i++) {
		if (periph_is_non_secure(STM32MP1_SHRES_GPIOZ(i))) {
			non_secure++;
		}
	}

	return non_secure == get_gpioz_nbpin();
}

static bool stm32mp_gpio_bank_is_secure(unsigned int bank)
{
	unsigned int secure = 0U;
	unsigned int i;

	lock_registering();

	if (bank != GPIO_BANK_Z) {
		return false;
	}

	for (i = 0U; i < get_gpioz_nbpin(); i++) {
		if (periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) {
			secure++;
		}
	}

	return secure == get_gpioz_nbpin();
}

bool stm32mp_nsec_can_access_clock(unsigned long clock_id)
{
	enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT;

	switch (clock_id) {
	case CK_CSI:
	case CK_HSE:
	case CK_HSE_DIV2:
	case CK_HSI:
	case CK_LSE:
	case CK_LSI:
	case PLL1_P:
	case PLL1_Q:
	case PLL1_R:
	case PLL2_P:
	case PLL2_Q:
	case PLL2_R:
	case PLL3_P:
	case PLL3_Q:
	case PLL3_R:
	case RTCAPB:
		return true;
	case GPIOZ:
		/* Allow clock access if at least one pin is non-secure */
		return !stm32mp_gpio_bank_is_secure(GPIO_BANK_Z);
	case CRYP1:
		shres_id = STM32MP1_SHRES_CRYP1;
		break;
	case HASH1:
		shres_id = STM32MP1_SHRES_HASH1;
		break;
	case I2C4_K:
		shres_id = STM32MP1_SHRES_I2C4;
		break;
	case I2C6_K:
		shres_id = STM32MP1_SHRES_I2C6;
		break;
	case IWDG1:
		shres_id = STM32MP1_SHRES_IWDG1;
		break;
	case RNG1_K:
		shres_id = STM32MP1_SHRES_RNG1;
		break;
	case RTC:
		shres_id = STM32MP1_SHRES_RTC;
		break;
	case SPI6_K:
		shres_id = STM32MP1_SHRES_SPI6;
		break;
	case USART1_K:
		shres_id = STM32MP1_SHRES_USART1;
		break;
	default:
		return false;
	}

	return periph_is_non_secure(shres_id);
}

bool stm32mp_nsec_can_access_reset(unsigned int reset_id)
{
	enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT;

	switch (reset_id) {
	case CRYP1_R:
		shres_id = STM32MP1_SHRES_CRYP1;
		break;
	case GPIOZ_R:
		/* GPIOZ reset mandates all pins are non-secure */
		return stm32mp_gpio_bank_is_non_secure(GPIO_BANK_Z);
	case HASH1_R:
		shres_id = STM32MP1_SHRES_HASH1;
		break;
	case I2C4_R:
		shres_id = STM32MP1_SHRES_I2C4;
		break;
	case I2C6_R:
		shres_id = STM32MP1_SHRES_I2C6;
		break;
	case MCU_R:
		shres_id = STM32MP1_SHRES_MCU;
		break;
	case MDMA_R:
		shres_id = STM32MP1_SHRES_MDMA;
		break;
	case RNG1_R:
		shres_id = STM32MP1_SHRES_RNG1;
		break;
	case SPI6_R:
		shres_id = STM32MP1_SHRES_SPI6;
		break;
	case USART1_R:
		shres_id = STM32MP1_SHRES_USART1;
		break;
	default:
		return false;
	}

	return periph_is_non_secure(shres_id);
}

static bool mckprot_protects_periph(enum stm32mp_shres id)
{
	switch (id) {
	case STM32MP1_SHRES_MCU:
	case STM32MP1_SHRES_PLL3:
		return true;
	default:
		return false;
	}
}

/* ETZPC configuration at drivers initialization completion */
static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id)
{
	assert((id < STM32MP1_SHRES_GPIOZ(0)) ||
	       (id > STM32MP1_SHRES_GPIOZ(7)));

	if (periph_is_non_secure(id)) {
		return ETZPC_DECPROT_NS_RW;
	}

	return ETZPC_DECPROT_S_RW;
}

static void set_etzpc_secure_configuration(void)
{
	/* Some system peripherals shall be secure */
	etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW);
	etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW);
	etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID,
				ETZPC_DECPROT_NS_R_S_W);
	etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID,
				ETZPC_DECPROT_NS_R_S_W);

	/* Configure ETZPC with peripheral registering */
	etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID,
				shres2decprot_attr(STM32MP1_SHRES_CRYP1));
	etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID,
				shres2decprot_attr(STM32MP1_SHRES_HASH1));
	etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID,
				shres2decprot_attr(STM32MP1_SHRES_I2C4));
	etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID,
				shres2decprot_attr(STM32MP1_SHRES_I2C6));
	etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID,
				shres2decprot_attr(STM32MP1_SHRES_IWDG1));
	etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID,
				shres2decprot_attr(STM32MP1_SHRES_RNG1));
	etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID,
				shres2decprot_attr(STM32MP1_SHRES_USART1));
	etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID,
				shres2decprot_attr(STM32MP1_SHRES_SPI6));
}

static void check_rcc_secure_configuration(void)
{
	uint32_t n;
	uint32_t error = 0U;
	bool mckprot = stm32mp1_rcc_is_mckprot();
	bool secure = stm32mp1_rcc_is_secure();

	for (n = 0U; n < ARRAY_SIZE(shres_state); n++) {
		if (shres_state[n] != SHRES_SECURE) {
			continue;
		}

		if (!secure || (mckprot_protects_periph(n) && (!mckprot))) {
			ERROR("RCC %s MCKPROT %s and %s secure\n",
			      secure ? "secure" : "non-secure",
			      mckprot ? "set" : "not set",
			      shres2str_id(n));
			error++;
		}
	}

	if (error != 0U) {
		panic();
	}
}

static void set_gpio_secure_configuration(void)
{
	uint32_t pin;

	for (pin = 0U; pin < get_gpioz_nbpin(); pin++) {
		bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin));

		set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state);
	}
}

static void print_shared_resources_state(void)
{
	unsigned int id;

	for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) {
		switch (shres_state[id]) {
		case SHRES_SECURE:
			INFO("stm32mp1 %s is secure\n", shres2str_id(id));
			break;
		case SHRES_NON_SECURE:
		case SHRES_UNREGISTERED:
			VERBOSE("stm32mp %s is non-secure\n", shres2str_id(id));
			break;
		default:
			VERBOSE("stm32mp %s is invalid\n", shres2str_id(id));
			panic();
		}
	}
}

void stm32mp_lock_periph_registering(void)
{
	registering_locked = true;

	print_shared_resources_state();

	check_rcc_secure_configuration();
	set_etzpc_secure_configuration();
	set_gpio_secure_configuration();
}
