/**
 * @file   efusewriter.h
 * @brief  Header file for efusewriter API
 *
 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
 */

#ifndef __EFUSEWRITER_H__
#define __EFUSEWRITER_H__

#ifdef __cplusplus
extern "C" {
#endif

#if defined(CONFIG_EXYNOS5430) || defined(CONFIG_EXYNOS4415) || defined(CONFIG_EXYNOS3475)
#include "DrApi/DrApiFastCall.h"
#endif

/* api select */
enum {
	BAN_APFA = 1,
	BAN_OEM_KEY,
	USE_OEM_KEY,
	SKIP_AES,
	PREORDER,
	OEM_KEY0,
	OEM_KEY1,
	MODEL_ID,
	SANTIRBK,
	NANTIRBK0,
	NANTIRBK1,
	COMMERCIAL,
	TEST,
	WARRANTY,
	EFUSE_BLOW,
	EFUSE_FINAL,
	READ,
	W_ETC,
	R_ETC,
	DATA_INPUT_OEM_KEY0,
	DATA_INPUT_OEM_KEY1,
	DATA_INPUT_NANTIRBK0,
	DATA_INPUT_NANTIRBK1,
#if defined(CONFIG_EXYNOS5430) || defined(CONFIG_EXYNOS4415) || defined(CONFIG_EXYNOS3475)
	JTAG_LOCK,
#endif
#if defined(CONFIG_EXYNOS4415)
	CHECK_JTAG_KEY,
#endif
#if defined(CONFIG_EXYNOS5430)
    JTAG_LOCK_VF,
#endif
};

#define ONE_BIT				0x1
#define ONE_BYTE			0xFF

#define NO_DATA				0x0

#if defined(CONFIG_EXYNOS5260)
#define BAN_APFA_BIT_OFFSET		0x8
#define USE_OEM_BIT_OFFSET		0x0
#define BAN_OEM_BIT_OFFSET		0x7
#define SKIP_AES_BIT_OFFSET		0x2
#define PREORDER_BIT_OFFSET		0x10
#define COMMERCIAL_BIT_OFFSET		0x0
#define TEST_BIT_OFFSET			0x2
#define WARRANTY_BIT_OFFSET		0x4

#define SECURE_BOOT_KEY0_BASE_OFFSET	0x20
#define SECURE_BOOT_KEY1_BASE_OFFSET	0x30
#define ANTIRBK_SEC_BASE_OFFSET		0x40
#define NANTIRBK0_BASE_OFFSET		0x00
#define NANTIRBK1_BASE_OFFSET		0x10

#elif defined(CONFIG_EXYNOS5430) || defined(CONFIG_EXYNOS3475)
#define BAN_APFA_BIT_OFFSET		0x8
#define USE_OEM_BIT_OFFSET		0x0
#define BAN_OEM_BIT_OFFSET		0x2
#define SKIP_AES_BIT_OFFSET		0x4
#define PREORDER_BIT_OFFSET		0x10
#define COMMERCIAL_BIT_OFFSET		0x0
#define TEST_BIT_OFFSET			0x2
#define WARRANTY_BIT_OFFSET		0x4
#define JTAG_LOCK_BIT_OFFSET		0xF

#define SECURE_BOOT_KEY0_BASE_OFFSET	0x20
#define SECURE_BOOT_KEY1_BASE_OFFSET	0x30
#define ANTIRBK_SEC_BASE_OFFSET		0x40
#define NANTIRBK0_BASE_OFFSET		0x00
#define NANTIRBK1_BASE_OFFSET		0x10

#elif defined(CONFIG_EXYNOS4415)
#define BAN_APFA_BIT_OFFSET            0x8
#define USE_OEM_BIT_OFFSET             0x0
#define BAN_OEM_BIT_OFFSET             0x2
#define SKIP_AES_BIT_OFFSET            0x4
#define PREORDER_BIT_OFFSET            0x10
#define COMMERCIAL_BIT_OFFSET          0x0
#define TEST_BIT_OFFSET                0x2
#define WARRANTY_BIT_OFFSET            0x4
#define JTAG_LOCK_BIT_OFFSET		0x64
#define JTAG_KEY_0_OFFSET		0x50
#define JTAG_KEY_1_OFFSET		0x54
#define JTAG_KEY_2_OFFSET		0x58
#define JTAG_KEY_3_OFFSET		0x5C
#define JTAG_KEY_4_OFFSET		0x60
#define JTAG_KEY_NO_FUSING		0x0
#define JTAG_KEY_FUSING 		0x1

#define SECURE_BOOT_KEY0_BASE_OFFSET   0x20
#define SECURE_BOOT_KEY1_BASE_OFFSET   0x30
#define ANTIRBK_SEC_BASE_OFFSET        0x40
#define NANTIRBK0_BASE_OFFSET          0x00
#define NANTIRBK1_BASE_OFFSET          0x10
#endif

#define COMMERCIAL_BIT			0x00000001
#define TEST_BIT			0x00000004
#define WARRANTY_BIT			0x00000010

/* efuse writer control */
#define EFUSE_WRITER_ENABLE		0x0
#define EFUSE_INITIAL_START		0x4
#define EFUSE_PROGRAM_START		0x8
#define EFUSE_COMPARE_START		0xC

/* efuse writer status */
#define EFUSE_LOCK_ON			(1 << 0)
#define EFUSE_INITIAL_END		(1 << 4)
#define EFUSE_BLOW_END			(1 << 8)
#define EFUSE_COMPARE_END_WITH_ERROR	(1 << 12)
#define EFUSE_COMPARE_END_WITHOUT_ERROR	(1 << 13)
#define EFUSE_COMPARE_END		(1 << 16)

/* error select */
enum {
	SUCCESS = 0,
	UNKNOWN,
	LOCK_ON,
	INIT_FAIL,
	BLOW_FAIL,
	COMPARE_FAIL,
	COMPARE_STATUS_FAIL,
	COMMERCIAL_BIT_SET_ALREADY,
	TEST_BIT_SET_ALREADY,
	NO_COMMAND,
	ID_FAULT = 0xBAD,
};

/* chip select */
enum {
#if defined(CONFIG_EXYNOS3475)
    SECURE_BOOT_KEY0 = 1,
    SECURE_BOOT_KEY1,
    RESERVED0,
    RESERVED1,
    RESERVED2,
    RESERVED3,
    ROOT_KEY0,
    ROOT_KEY1,
    ANTIRBK_SEC,
    ANTIRBK0,
    ANTIRBK1,
    PROVISIONKEY0,
    PROVISIONKEY1,
    CUSTOM_EFUSE,
    RESERVED4,
#else
	ROOT_KEY = 1,
	SECURE_BOOT_KEY0,
	SECURE_BOOT_KEY1,
	JTAG_KEY0,
	JTAG_KEY1,
	PROVISIONKEY0,
	PROVISIONKEY1,
	ANTIRBK_SEC,
	ANTIRBK0,
	ANTIRBK1,
	RESERVED0,
	RESERVED1,
	RESERVED2,
	RESERVED3,
	CUSTOM_EFUSE,
#endif
	EFUSE_ERROR_CON,
};

#if defined(CONFIG_EXYNOS5260)
#define MAIN_EFUSE PROVISIONKEY0
#elif defined(CONFIG_EXYNOS5430) || defined(CONFIG_EXYNOS3475)
#define MAIN_EFUSE CUSTOM_EFUSE
#elif defined(CONFIG_EXYNOS4415)
#define MAIN_EFUSE PROVISIONKEY0
#endif

struct data {
	uint32_t data0;
	uint32_t data1;
	uint32_t data2;
	uint32_t data3;
};

#if defined(CONFIG_EXYNOS5260)
#define EFUSE_WR_SC_BASE			0x10090000
#define EFUSE_WR_NS_BASE			0x100A0000
#elif defined(CONFIG_EXYNOS5430)
#define EFUSE_WR_SC_BASE			0x101E0000
#define EFUSE_WR_NS_BASE			0x100B0000
#elif defined(CONFIG_EXYNOS4415)
#define EFUSE_WR_SC_BASE			0x101B0000
#define EFUSE_WR_NS_BASE			0x101C0000
#elif defined(CONFIG_EXYNOS3475)
#define EFUSE_WR_SC_BASE			0x10090000
#define EFUSE_WR_NS_BASE			0x100D0000
#endif
#define EFUSE_WRITER_CTL			0x000
#define EFUSE_WRITER_STATUS			0x004
#define EFUSE_CHIP_SELECT			0x008
#define EFUSE_SIZE				0x00C
#define EFUSE_DATA0				0x010
#define EFUSE_DATA1				0x014
#define EFUSE_DATA2				0x018
#define EFUSE_DATA3				0x01C
#define EFUSE_Wait_Time				0x020
#define EFUSE_Program_Time			0x024
#define EFUSE_Lock_Conf				0x028
#define EFUSE_lock_bit_status			0x02C
#define EFUSE_Error_control_value0		0x030
#define EFUSE_Error_control_value1		0x034
#define EFUSE_Error_control_value2		0x038
#define EFUSE_Error_control_value3		0x03C
#define EFUSE_COMPARE_BIT_STATUS0		0x040
#define EFUSE_COMPARE_BIT_STATUS1		0x044
#define EFUSE_COMPARE_BIT_STATUS2		0x048
#define EFUSE_COMPARE_BIT_STATUS3		0x04C

void Efusewriter_Enable(void);

void Efusewriter_SelectEfuseChip(unsigned int nIndex);

int Efusewriter_CheckEfromLockOn(void);

int Efusewriter_CheckEfromInitEnd(void);

void Efusewriter_Size(unsigned char nSize);

void Efusewriter_Waittime(unsigned int nWaittime);

void Efusewriter_Programwaittime(unsigned int nProgWaittime);

void Efusewriter_InitStart(void);

void Efusewriter_WriteData(unsigned int index, unsigned int data);

void Efusewriter_StartBlow(void);

int Efusewriter_CheckBlow(void);

void Efusewriter_Sensing(void);

void Efusewriter_Compare(void);

int Efusewriter_CheckCompare(void);

int Efusewriter_CheckCompareStatus_Errorcontrol(void);

int Efusewriter_CheckCompareStatus(uint32_t nChipselect);

void Efusewriter_Lock(void);

void Efusewriter_Program(void);

void FsourceEnable(void);

void FsourceDisable(void);

int efuse_initialize(int efuse_id);

int efuse_blow(void);

int efuse_finalize(int efuse_id);

void d_list_clean(void);

uint32_t efuse_read(int efuse_id);

int efuse_writer(fastcall_registers_t regs);

#ifdef __cplusplus
}
#endif

#endif /* __EFUSEWRITER_H__ */
