/**
 * @file  otp.h
 * @brief OTP controller API for Fastcall driver
 *
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
 *
 * This software is proprietary of Samsung Electronics.
 * No part of this software, either material or conceptual may be copied
 * or distributed, transmitted, transcribed, stored in a retrieval system
 * or translated into any human or computer language in any form by any means,
 * electronic, mechanical, manual or otherwise, or disclosed to third parties
 * without the express written permission of Samsung Electronics.
 */

#ifndef __OTP_H__
#define __OTP_H__

#ifdef __cplusplus
extern "C" {
#endif

/**********************************************************************/
/* OTP controller                                                     */
/**********************************************************************/
/* OTP controller SFR base and virtual address */
#define OTP_CONTROL_SFR_BASE	0x101E0000
#define OTP_CONTROL_SFR_VA		0x47000

/* OTP controller SFR offset */
#define OTP_LOCK0				(OTP_CONTROL_SFR_VA + 0x000)
#define OTP_LOCK1				(OTP_CONTROL_SFR_VA + 0x004)
#define OTP_SECURE_READ_DATA	(OTP_CONTROL_SFR_VA + 0x008)
#define OTP_NONSECURE_READ_DATA	(OTP_CONTROL_SFR_VA + 0x00C)
#define OTP_CON_CONTROL			(OTP_CONTROL_SFR_VA + 0x010)
#define OTP_CON_CONFIG			(OTP_CONTROL_SFR_VA + 0x014)
#define OTP_IF					(OTP_CONTROL_SFR_VA + 0x018)
#define OTP_INT_STATUS			(OTP_CONTROL_SFR_VA + 0x01C)
#define OTP_INT_EN				(OTP_CONTROL_SFR_VA + 0x020)
#define OTP_CON_TIME_PARA_0		(OTP_CONTROL_SFR_VA + 0x024)
#define OTP_CON_TIME_PARA_1		(OTP_CONTROL_SFR_VA + 0x028)
#define OTP_CON_TIME_PARA_2		(OTP_CONTROL_SFR_VA + 0x02C)
#define OTP_CON_TIME_PARA_3		(OTP_CONTROL_SFR_VA + 0x030)
#define OTP_CON_TIME_PARA_4		(OTP_CONTROL_SFR_VA + 0x034)
#define OTP_CON_TIME_PARA_5		(OTP_CONTROL_SFR_VA + 0x038)
#define OTP_CON_TIME_PARA_6		(OTP_CONTROL_SFR_VA + 0x03C)
#define OTP_CON_TIME_PARA_7		(OTP_CONTROL_SFR_VA + 0x040)
#define OTP_ADD_LOCK			(OTP_CONTROL_SFR_VA + 0x044)
#define OTP_CUSTOM_LOCK0		(OTP_CONTROL_SFR_VA + 0x048)
#define OTP_CUSTOM_LOCK01		(OTP_CONTROL_SFR_VA + 0x04C)

/* OTP controller control */
#define OTP_INIT_CMD_MASK			(1 << 0)
#define OTP_INIT_CMD_ON				(1 << 0)
#define OTP_INIT_CMD_OFF			(0 << 0)
#define OTP_READ_CMD_MASK			(1 << 1)
#define OTP_READ_CMD_ON				(1 << 1)
#define OTP_READ_CMD_OFF			(0 << 1)
#define OTP_PROGRAM_CMD_MASK		(1 << 2)
#define OTP_PROGRAM_CMD_ON			(1 << 2)
#define OTP_PROGRAM_CMD_OFF			(0 << 2)
#define OTP_STANDBY_CMD_MASK		(1 << 3)
#define OTP_STANDBY_CMD_ON			(1 << 3)
#define OTP_STANDBY_CMD_OFF			(0 << 3)
#define OTP_LOCK_PROGRAM_CMD_MASK	(1 << 4)
#define OTP_LOCK_PROGRAM_CMD_ON		(1 << 4)
#define OTP_LOCK_PROGRAM_CMD_OFF	(0 << 4)

/* OTP interrupt enable control */
#define OTP_INIT_DONE_INT_MASK			(1 << 0)
#define OTP_INIT_DONE_INT_ON			(1 << 0)
#define OTP_INIT_DONE_INT_OFF			(0 << 0)
#define OTP_READ_DONE_INT_MASK			(1 << 1)
#define OTP_READ_DONE_INT_ON			(1 << 1)
#define OTP_READ_DONE_INT_OFF			(0 << 1)
#define OTP_PROGRAM_DONE_INT_MASK		(1 << 2)
#define OTP_PROGRAM_DONE_INT_ON			(1 << 2)
#define OTP_PROGRAM_DONE_INT_OFF		(0 << 2)
#define OTP_STANDBY_DONE_INT_MASK		(1 << 3)
#define OTP_STANDBY_DONE_INT_ON			(1 << 3)
#define OTP_STANDBY_DONE_INT_OFF		(0 << 3)
#define OTP_LOCK_PROGRAM_DONE_INT_MASK	(1 << 4)
#define OTP_LOCK_PROGRAM_DONE_INT_ON	(1 << 4)
#define OTP_LOCK_PROGRAM_DONE_INT_OFF	(0 << 4)
#define OTP_PROGRAM_FAIL_INT_MASK		(1 << 5)
#define OTP_PROGRAM_FAIL_INT_ON			(1 << 5)
#define OTP_PROGRAM_FAIL_INT_OFF		(0 << 5)
#define OTP_LOCK_PROGRAM_FAIL_INT_MASK	(1 << 6)
#define OTP_LOCK_PROGRAM_FAIL_INT_ON	(1 << 6)
#define OTP_LOCK_PROGRAM_FAIL_INT_OFF	(0 << 6)

/* OTP interrupt status control */
#define OTP_INT_DONE_MASK			(1 << 0)
#define OTP_INT_DONE_ON				(1 << 0)
#define OTP_INT_DONE_OFF			(0 << 0)
#define OTP_READ_DONE_MASK			(1 << 1)
#define OTP_READ_DONE_ON			(1 << 1)
#define OTP_READ_DONE_OFF			(0 << 1)
#define OTP_PROGRAM_DONE_MASK		(1 << 2)
#define OTP_PROGRAM_DONE_ON			(1 << 2)
#define OTP_PROGRAM_DONE_OFF		(0 << 2)
#define OTP_STANDBY_DONE_MASK		(1 << 3)
#define OTP_STANDBY_DONE_ON			(1 << 3)
#define OTP_STANDBY_DONE_OFF		(0 << 3)
#define OTP_LOCK_PROGRAM_DONE_MASK	(1 << 4)
#define OTP_LOCK_PROGRAM_DONE_ON	(1 << 4)
#define OTP_LOCK_PROGRAM_DONE_OFF	(0 << 4)
#define OTP_PROGRAM_FAIL_MASK		(1 << 5)
#define OTP_PROGRAM_FAIL_ON			(1 << 5)
#define OTP_PROGRAM_FAIL_OFF		(0 << 5)
#define OTP_LOCK_PROGRAM_FAIL_MASK	(1 << 6)
#define OTP_LOCK_PROGRAM_FAIL_ON	(1 << 6)
#define OTP_LOCK_PROGRAM_FAIL_OFF	(0 << 6)
#define OTP_SECURE_FAIL_MASK		(1 << 7)
#define OTP_SECURE_FAIL_ON			(1 << 7)
#define OTP_SECURE_FAIL_OFF			(0 << 7)
#define OTP_PROGRAM_LOCK_MASK		(1 << 8)
#define OTP_PROGRAM_LOCK_ON			(1 << 8)
#define OTP_PROGRAM_LOCK_OFF		(0 << 8)

/* OTP IF control */
#define OTP_IF_ADDR_CLEAR			(0xFFFF << 15)
#define OTP_IF_ADDR_MASK			0x7FFF
#define OTP_IF_ADDR_MASK_READ		0x7FE0
#define OTP_IF_REGION_MASK			(0x3 << 13)
#define OTP_IF_REGION_SECURE		(0x2 << 13)
#define OTP_IF_REGION_NONSEC		(0x0 << 13)
#define OTP_IF_REGION_HWONLY		(0x1 << 13)

/* Maximum retry count for time out */
#define TIME_OUT				0xFFFFFF

/**********************************************************************/
/* OTP memory address                                                 */
/**********************************************************************/
#define OTP_SWCRYPTO_ADDR   	0x44D
#define OTP_CHIPID_96_ADDR   	0x460
/* OTP address for non-secure anti-rollback counter */
#define OTP_ANTIRBK_BASE		0x1C00
#define OTP_ANTIRBK_ADDR0		(OTP_ANTIRBK_BASE + 0x00)
#define OTP_ANTIRBK_ADDR1		(OTP_ANTIRBK_BASE + 0x20)
#define OTP_ANTIRBK_ADDR2		(OTP_ANTIRBK_BASE + 0x40)
#define OTP_ANTIRBK_ADDR3		(OTP_ANTIRBK_BASE + 0x60)
#define OTP_ANTIRBK_ADDR4		(OTP_ANTIRBK_BASE + 0x80)
#define OTP_ANTIRBK_ADDR5		(OTP_ANTIRBK_BASE + 0xA0)
#define OTP_ANTIRBK_ADDR6		(OTP_ANTIRBK_BASE + 0xC0)

/* OTP address for OEM_KEY */
#define OTP_SECKEY_BASE			0x4000
#define OTP_SECKEY_ADDR0		(OTP_SECKEY_BASE + 0x00)
#define OTP_SECKEY_ADDR1		(OTP_SECKEY_BASE + 0x20)
#define OTP_SECKEY_ADDR2		(OTP_SECKEY_BASE + 0x40)
#define OTP_SECKEY_ADDR3		(OTP_SECKEY_BASE + 0x60)
#define OTP_SECKEY_ADDR4		(OTP_SECKEY_BASE + 0x80)
#define OTP_SECKEY_ADDR5		(OTP_SECKEY_BASE + 0xA0)
#define OTP_SECKEY_ADDR6		(OTP_SECKEY_BASE + 0xC0)
#define OTP_SECKEY_ADDR7		(OTP_SECKEY_BASE + 0xE0)

/* OTP address for CUSTOM Key */
#define OTP_CUSTOM_KEY_BASE		0x5000
#define OTP_CUSTOM_KEY_ADDR		(OTP_CUSTOM_KEY_BASE + 0x00)
#define OTP_USE_OEM_KEY_ADDR	(OTP_CUSTOM_KEY_BASE + 0x00)
#define OTP_BAN_OEM_KEY_ADDR	(OTP_CUSTOM_KEY_BASE + 0x02)
#define OTP_SKIP_AES_ADDR		(OTP_CUSTOM_KEY_BASE + 0x04)
#define OTP_BAN_APFA_ADDR		(OTP_CUSTOM_KEY_BASE + 0x08)
#define OTP_JTAG_SOFT_LOCK_ADDR	(OTP_CUSTOM_KEY_BASE + 0x0F)
#define OTP_PREORDER_ADDR		(OTP_CUSTOM_KEY_BASE + 0x10)
#define OTP_MODEL_ID_ADDR		(OTP_CUSTOM_KEY_BASE + 0x20)
#define OTP_CUSTOM_ETC_ADDR		(OTP_CUSTOM_KEY_BASE + 0x40)
#define OTP_COMMERCIAL_ADDR		(OTP_CUSTOM_KEY_BASE + 0x40)
#define OTP_TEST_ADDR			(OTP_CUSTOM_KEY_BASE + 0x42)
#define OTP_WARRANTY_ADDR		(OTP_CUSTOM_KEY_BASE + 0x44)

/* OTP address for anti-rollback counter */
#define OTP_ANTIRBK_SEC_ADDR	0x7800

/* OTP address for lock */
#define OTP_LOCK_KEY_BASE		0x7C00
#define OTP_LOCK_KEY20_AREA_BASE	64

/**********************************************************************/
/* OTP command                                                        */
/**********************************************************************/
enum
{
	CMD_W_USE_OEM_KEY = 1,
	CMD_W_BAN_OEM_KEY,
	CMD_W_SKIP_AES,
	CMD_W_BAN_APFA,
	CMD_W_JTAG_LOCK,
	CMD_W_PREORDER,
	CMD_W_MODEL_ID,
	CMD_W_COMMERCIAL,
	CMD_W_TEST,
	CMD_W_WARRANTY,
	CMD_W_NANTIRBK0_0,
	CMD_W_NANTIRBK0_1,
	CMD_W_NANTIRBK1_0,
	CMD_W_NANTIRBK1_1,
	CMD_W_SANTIRBK,
	CMD_W_OEM_KEY0_0,
	CMD_W_OEM_KEY0_1,
	CMD_W_OEM_KEY1_0,
	CMD_W_OEM_KEY1_1,
	CMD_W_ETC,
	CMD_R_USE_OEM_KEY,
	CMD_R_BAN_OEM_KEY,
	CMD_R_SKIP_AES,
	CMD_R_BAN_APFA,
	CMD_R_JTAG_LOCK,
	CMD_R_PREORDER,
	CMD_R_MODEL_ID,
	CMD_R_COMMERCIAL,
	CMD_R_TEST,
	CMD_R_WARRANTY,
	CMD_R_NANTIRBK0_0,
	CMD_R_NANTIRBK0_1,
	CMD_R_NANTIRBK1_0,
	CMD_R_NANTIRBK1_1,
	CMD_R_OEM_KEY0_0,
	CMD_R_OEM_KEY0_1,
	CMD_R_OEM_KEY1_0,
	CMD_R_OEM_KEY1_1,
	CMD_R_ETC,
};

/**********************************************************************/
/* error codes                                                        */
/**********************************************************************/
enum
{
	RV_SUCCESS = 0,
	RV_OTP_INIT_TIME_OUT,
	RV_OTP_STANDBY_TIME_OUT,
	RV_OTP_READ_SECURE_FAIL,
	RV_OTP_READ_TIME_OUT,
	RV_OTP_READ_UNACCESSIBLE_REGION,
	RV_OTP_PROGRAM_LOCK,
	RV_OTP_PROGRAM_FAIL,
	RV_OTP_PROGRAM_SECURE_FAIL,
	RV_OTP_PROGRAM_TIME_OUT,
	RV_OTP_TEST_BIT_SET_ALREADY,
	RV_OTP_COMMERCIAL_BIT_SET_ALREADY,
	RV_OTP_LOCK_PROGRAM_FAIL,
	RV_OTP_LOCK_PROGRAM_TIME_OUT,
	RV_OTP_NO_COMMAND,
	RV_OTP_INVALID_BIT_INDEX,
};

/**********************************************************************/
/* OTP locking address                                                */
/**********************************************************************/
enum
{
	OTP_LOCK_KEY0 = 0x7C00,
	OTP_LOCK_KEY1 = 0x7C01,
	OTP_LOCK_KEY2 = 0x7C02,
	OTP_LOCK_KEY3 = 0x7C03,
	OTP_LOCK_KEY4 = 0x7C04,
	OTP_LOCK_KEY5 = 0x7C05,
	OTP_LOCK_KEY6 = 0x7C06,
	OTP_LOCK_KEY7 = 0x7C07,
	OTP_LOCK_KEY8 = 0x7C08,
	OTP_LOOK_KEY9 = 0x7C09,
	OTP_LOCK_KEY10 = 0x7C0A,
	OTP_LOCK_KEY11 = 0x7C0B,
	OTP_LOCK_KEY12 = 0x7C0C,
	OTP_LOCK_KEY13 = 0x7C0D,
	OTP_LOCK_KEY14 = 0x7C0E,
	OTP_LOCK_KEY15 = 0x7C0F,
	OTP_LOCK_KEY16 = 0x7C10,
	OTP_LOCK_KEY17 = 0x7C11,
	OTP_LOCK_KEY18 = 0x7C12,
	OTP_LOCK_KEY19 = 0x7C13,
	OTP_LOCK_KEY20 = 0x7C14,
	OTP_LOCK_KEY21 = 0x7C15,
	OTP_LOCK_KEY22 = 0x7C16,
	OTP_LOCK_KEY23 = 0x7C17,
	OTP_LOCK_KEY24 = 0x7C18,
	OTP_LOCK_KEY25 = 0x7C19,
	OTP_LOCK_KEY26 = 0x7C1A,
	OTP_LOCK_KEY27 = 0x7C1B,
	OTP_LOCK_KEY28 = 0x7C1C,
	OTP_LOCK_KEY29 = 0x7C1D,
	OTP_LOCK_KEY30 = 0x7C1E,
	OTP_LOCK_KEY31 = 0x7C1F,
	OTP_LOCK_KEY20_0 = 0x7C41,
	OTP_LOCK_KEY20_1 = 0x7C42,
	OTP_LOCK_KEY20_2 = 0x7C43,
	OTP_LOCK_KEY20_3 = 0x7C44,
	OTP_LOCK_KEY20_4 = 0x7C45,
	OTP_LOCK_KEY20_5 = 0x7C46,
	OTP_LOCK_KEY20_6 = 0x7C47,
	OTP_LOCK_KEY20_7 = 0x7C48,
};

/**********************************************************************/
/* APIs for OTP control                                               */
/**********************************************************************/
uint32_t otp_get_interrupt(void);
void otp_set_interrupt(uint32_t enable);
void otp_reset_interrupt(uint32_t data);
uint32_t otp_write_one_bit(uint32_t address, uint32_t program_data);
uint32_t otp_write_one_byte(uint32_t address, uint32_t program_data);
uint32_t otp_write_byte_array(uint32_t address, uint8_t *program_data,
			      uint32_t bit_len);
uint32_t otp_read_one_bit(uint32_t address, uint32_t *read_data);
uint32_t otp_read_one_word(uint32_t address, uint32_t *read_data);
uint32_t otp_read_byte_array(uint32_t address, uint8_t *read_data,
			     uint32_t bit_len);
uint32_t otp_control(fastcall_registers_t regs);

#ifdef __cplusplus
}
#endif

#endif //__OTP_H__
