/*
 * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdint.h>

#include <lib/mmio.h>

#include "rcar_def.h"
#include "rom_api.h"

typedef uint32_t(*rom_secure_boot_api_f) (uint32_t key, uint32_t cert,
					  rom_read_flash_f pFuncReadFlash);

typedef uint32_t(*rom_get_lcs_api_f) (uint32_t *lcs);

#define OLD_API_TABLE1	(0U)	/* H3 Ver.1.0/Ver.1.1 */
#define OLD_API_TABLE2	(1U)	/* H3 Ver.2.0 */
#define OLD_API_TABLE3	(2U)	/* M3 Ver.1.0 */
#define NEW_API_TABLE	(3U)	/* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */
#define NEW_API_TABLE2	(4U)	/* V3M WS1.0 */
#define API_TABLE_MAX	(5U)	/* table max */
				/* Later than H3 Ver.2.0 */

static uint32_t get_table_index(void)
{
	uint32_t product;
	uint32_t cut_ver;
	uint32_t index;

	product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
	cut_ver = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK;

	switch (product) {
	case PRR_PRODUCT_H3:
		if (cut_ver == PRR_PRODUCT_10)
			index = OLD_API_TABLE1;
		else if (cut_ver == PRR_PRODUCT_11)
			index = OLD_API_TABLE1;
		else if (cut_ver == PRR_PRODUCT_20)
			index = OLD_API_TABLE2;
		else
			/* Later than H3 Ver.2.0 */
			index = NEW_API_TABLE;
		break;
	case PRR_PRODUCT_M3:
		if (cut_ver == PRR_PRODUCT_10)
			index = OLD_API_TABLE3;
		else
			/* M3 Ver.1.1 or later */
			index = NEW_API_TABLE;
		break;
	case PRR_PRODUCT_V3M:
		if (cut_ver == PRR_PRODUCT_10)
			/* V3M WS1.0 */
			index = NEW_API_TABLE2;
		else
			/* V3M WS2.0 or later */
			index = NEW_API_TABLE;
		break;
	default:
		index = NEW_API_TABLE;
		break;
	}

	return index;
}

uint32_t rcar_rom_secure_boot_api(uint32_t key, uint32_t cert,
			     rom_read_flash_f read_flash)
{
	static const uintptr_t rom_api_table[API_TABLE_MAX] = {
		0xEB10DD64U,	/* H3 Ver.1.0/Ver.1.1 */
		0xEB116ED4U,	/* H3 Ver.2.0 */
		0xEB1102FCU,	/* M3 Ver.1.0 */
		0xEB100180U,	/* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */
		0xEB110128U,	/* V3M WS1.0 */
	};
	rom_secure_boot_api_f secure_boot;
	uint32_t index;

	index = get_table_index();
	secure_boot = (rom_secure_boot_api_f) rom_api_table[index];

	return secure_boot(key, cert, read_flash);
}

uint32_t rcar_rom_get_lcs(uint32_t *lcs)
{
	static const uintptr_t rom_get_lcs_table[API_TABLE_MAX] = {
		0xEB10DFE0U,	/* H3 Ver.1.0/Ver.1.1 */
		0xEB117150U,	/* H3 Ver.2.0 */
		0xEB110578U,	/* M3 Ver.1.0 */
		0xEB10018CU,	/* H3 Ver.3.0, M3 Ver.1.1 or later, M3N, E3, D3, V3M WS2.0 */
		0xEB1103A4U,	/* V3M WS1.0 */
	};
	rom_get_lcs_api_f get_lcs;
	uint32_t index;

	index = get_table_index();
	get_lcs = (rom_get_lcs_api_f) rom_get_lcs_table[index];

	return get_lcs(lcs);
}
