xref: /openbmc/u-boot/cmd/otp.c (revision 737ed20bb1e3c33e7fd397d8de63f4f5ed9619b8)
169d5fd8fSJohnny Huang /*
269d5fd8fSJohnny Huang  *  This program is distributed in the hope that it will be useful,
369d5fd8fSJohnny Huang  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
469d5fd8fSJohnny Huang  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
569d5fd8fSJohnny Huang  *  GNU General Public License for more details.
669d5fd8fSJohnny Huang  *
769d5fd8fSJohnny Huang  *  You should have received a copy of the GNU General Public License
869d5fd8fSJohnny Huang  *  along with this program; if not, write to the Free Software
969d5fd8fSJohnny Huang  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1069d5fd8fSJohnny Huang  */
114c1c9b35SJohnny Huang #include <stdlib.h>
1269d5fd8fSJohnny Huang #include <common.h>
1369d5fd8fSJohnny Huang #include <console.h>
1469d5fd8fSJohnny Huang #include <bootretry.h>
1569d5fd8fSJohnny Huang #include <cli.h>
1669d5fd8fSJohnny Huang #include <command.h>
1769d5fd8fSJohnny Huang #include <console.h>
184c1c9b35SJohnny Huang #include <malloc.h>
1969d5fd8fSJohnny Huang #include <inttypes.h>
2069d5fd8fSJohnny Huang #include <mapmem.h>
2169d5fd8fSJohnny Huang #include <asm/io.h>
2269d5fd8fSJohnny Huang #include <linux/compiler.h>
2369d5fd8fSJohnny Huang 
2469d5fd8fSJohnny Huang DECLARE_GLOBAL_DATA_PTR;
2569d5fd8fSJohnny Huang 
2669d5fd8fSJohnny Huang #define OTP_PASSWD			0x349fe38a
2769d5fd8fSJohnny Huang #define RETRY				3
28a6d0d645SJohnny Huang #define OTP_REGION_STRAP		1
29a6d0d645SJohnny Huang #define OTP_REGION_CONF			2
30a6d0d645SJohnny Huang #define OTP_REGION_DATA			3
31a6d0d645SJohnny Huang #define OTP_REGION_ALL			4
3269d5fd8fSJohnny Huang 
332a856b9aSJohnny Huang #define OTP_USAGE			-1
342a856b9aSJohnny Huang #define OTP_FAILURE			-2
352a856b9aSJohnny Huang #define OTP_SUCCESS			0
362a856b9aSJohnny Huang 
37a6af4a17SJohnny Huang #define OTP_PROG_SKIP			1
38a6af4a17SJohnny Huang 
3966f2f8e5SJohnny Huang #define DISABLE_SECREG_PROG(x)		(x & 0x1)
4066f2f8e5SJohnny Huang #define ENABLE_SEC_BOOT(x)		((x >> 1) & 0x1)
4166f2f8e5SJohnny Huang #define INIT_PROG_DONE(x)		((x >> 2) & 0x1)
4266f2f8e5SJohnny Huang #define ENABLE_USERREG_ECC(x)		((x >> 3) & 0x1)
4366f2f8e5SJohnny Huang #define ENABLE_SECREG_ECC(x)		((x >> 4) & 0x1)
4466f2f8e5SJohnny Huang #define DISABLE_LOW_SEC_KEY(x)		((x >> 5) & 0x1)
4566f2f8e5SJohnny Huang #define IGNORE_SEC_BOOT_HWSTRAP(x)	((x >> 6) & 0x1)
4666f2f8e5SJohnny Huang #define SEC_BOOT_MDOES(x)		((x >> 7) & 0x1)
47e1f9e54eSJohnny Huang #define   SEC_MODE1			0x0
48e1f9e54eSJohnny Huang #define   SEC_MODE2			0x1
49e1f9e54eSJohnny Huang #define OTP_BIT_CELL_MODES(x)		((x >> 8) & 0x3)
50e1f9e54eSJohnny Huang #define   SINGLE_CELL_MODE		0x0
51e1f9e54eSJohnny Huang #define   DIFFERENTIAL_MODE		0x1
52e1f9e54eSJohnny Huang #define   DIFFERENTIAL_REDUDANT_MODE	0x2
53e1f9e54eSJohnny Huang #define CRYPTO_MODES(x)			((x >> 10) & 0x3)
54e1f9e54eSJohnny Huang #define   CRYPTO_RSA1024		0x0
55e1f9e54eSJohnny Huang #define   CRYPTO_RSA2048		0x1
56e1f9e54eSJohnny Huang #define   CRYPTO_RSA3072		0x2
57e1f9e54eSJohnny Huang #define   CRYPTO_RSA4096		0x3
58e1f9e54eSJohnny Huang #define HASH_MODES(x)			((x >> 12) & 0x3)
59e1f9e54eSJohnny Huang #define   HASH_SAH224			0x0
60e1f9e54eSJohnny Huang #define   HASH_SAH256			0x1
61e1f9e54eSJohnny Huang #define   HASH_SAH384			0x2
62e1f9e54eSJohnny Huang #define   HASH_SAH512			0x3
63e1f9e54eSJohnny Huang #define SECREG_SIZE(x)			((x >> 16) & 0x3f)
6466f2f8e5SJohnny Huang #define WRITE_PROTECT_SECREG(x)		((x >> 22) & 0x1)
6566f2f8e5SJohnny Huang #define WRITE_PROTECT_USERREG(x)	((x >> 23) & 0x1)
6666f2f8e5SJohnny Huang #define WRITE_PROTECT_CONFREG(x)	((x >> 24) & 0x1)
6766f2f8e5SJohnny Huang #define WRITE_PROTECT_STRAPREG(x)	((x >> 25) & 0x1)
6866f2f8e5SJohnny Huang #define ENABLE_COPY_TO_SRAM(x)		((x >> 26) & 0x1)
6966f2f8e5SJohnny Huang #define ENABLE_IMAGE_ENC(x)		((x >> 27) & 0x1)
7066f2f8e5SJohnny Huang #define WRITE_PROTECT_KEY_RETIRE(x)	((x >> 29) & 0x1)
7166f2f8e5SJohnny Huang #define ENABLE_SIPROM_RED(x)		((x >> 30) & 0x1)
7266f2f8e5SJohnny Huang #define ENABLE_SIPROM_MLOCK(x)		((x >> 31) & 0x1)
73e1f9e54eSJohnny Huang 
74e1f9e54eSJohnny Huang #define VENDER_ID(x) 			(x & 0xFFFF)
75e1f9e54eSJohnny Huang #define KEY_REVISION(x)			((x >> 16) & 0xFFFF)
76e1f9e54eSJohnny Huang 
77e1f9e54eSJohnny Huang #define SEC_BOOT_HEADER_OFFSET(x)	(x & 0xFFFF)
78e1f9e54eSJohnny Huang 
79e1f9e54eSJohnny Huang #define KEYS_VALID_BITS(x)		(x & 0xff)
80e1f9e54eSJohnny Huang #define KEYS_RETIRE_BITS(x)		((x >> 16) & 0xff)
814c1c9b35SJohnny Huang 
8276d13988SJohnny Huang #define ENABLE_SECURE_BOOT(x)			(x & 0x1)
8376d13988SJohnny Huang #define BOOT_FROM_EMMC(x)			((x >> 1) & 0x1)
8476d13988SJohnny Huang #define BOOT_FROM_DEBUG_SPI(x)			((x >> 2) & 0x1)
8576d13988SJohnny Huang #define DISABLE_ARM_CM3(x)			((x >> 3) & 0x1)
8676d13988SJohnny Huang #define VGA_EXPANSION_ROM(x)			((x >> 4) & 0x1)
8776d13988SJohnny Huang #define MAC1_RMII_MODE(x)			((x >> 5) & 0x1)
8876d13988SJohnny Huang #define MAC2_RMII_MODE(x)			((x >> 6) & 0x1)
8976d13988SJohnny Huang #define CPU_FREQUENCY(x)			((x >> 7) & 0x7)
9076d13988SJohnny Huang #define HCLK_RATIO(x)				((x >> 10) & 0x3)
9176d13988SJohnny Huang #define VGA_MEMORY_SIZE(x)			((x >> 12) & 0x3)
9276d13988SJohnny Huang #define VGA_CLASS_CODE(x)			((x >> 17) & 0x1)
9376d13988SJohnny Huang #define DISABLE_DEBUG0(x)			((x >> 18) & 0x1)
9476d13988SJohnny Huang #define BOOT_FROM_EMMC_SPEED_MDOE(x)		((x >> 19) & 0x1)
9576d13988SJohnny Huang #define DISABLE_PCIE_EHCI(x)			((x >> 20) & 0x1)
9676d13988SJohnny Huang #define DISABLE_VGA_XDMA(x)			((x >> 21) & 0x1)
9776d13988SJohnny Huang #define DISABLE_DEDICATED_BMC_FUNCTION(x)	((x >> 22) & 0x1)
9876d13988SJohnny Huang #define DEDICATE_ROOT_COMPLEX_RELAX(x)		((x >> 23) & 0x1)
9976d13988SJohnny Huang #define SELECT_DRAM_TYPES(x)			((x >> 24) & 0x1)
10076d13988SJohnny Huang #define MAC3_RMII_MODE(x)			(x & 0x1)
10176d13988SJohnny Huang #define MAC4_RMII_MODE(x)			((x >> 1) & 0x1)
10276d13988SJohnny Huang #define SIO_CONF_ADDR(x)			((x >> 2) & 0x1)
10376d13988SJohnny Huang #define DISABLE_SIO(x)				((x >> 3) & 0x1)
10476d13988SJohnny Huang #define DISABLE_DEBUG1(x)			((x >> 4) & 0x1)
10576d13988SJohnny Huang #define ENABLE_ACPI(x)				((x >> 5) & 0x1)
10676d13988SJohnny Huang #define SELECT_LPC(x)				((x >> 6) & 0x1)
10776d13988SJohnny Huang #define ENABLE_SAFS(x)				((x >> 7) & 0x1)
10876d13988SJohnny Huang #define ENABLE_SPI_3B4B_AUTO(x)			((x >> 10) & 0x1)
10976d13988SJohnny Huang #define ENABLE_BOOT_SPI_ABR(x)			((x >> 11) & 0x1)
11076d13988SJohnny Huang #define BOOT_SPI_ABR_MODE(x)			((x >> 12) & 0x1)
11176d13988SJohnny Huang #define BOOT_SPI_FLASH_SIZE(x)			((x >> 13) & 0x7)
11276d13988SJohnny Huang #define ENABLE_HOST_SPI_ABR(x)			((x >> 16) & 0x1)
11376d13988SJohnny Huang #define EBABLE_HOST_SPI_ABR_SEL_PIN(x)		((x >> 17) & 0x1)
11476d13988SJohnny Huang #define HOST_SPI_ABR_MODE(x)			((x >> 18) & 0x1)
11576d13988SJohnny Huang #define HOST_SPI_FLASH_SIZE(x)			((x >> 19) & 0x7)
11676d13988SJohnny Huang #define ENABLE_BOOT_SPI_AUX_CONTROL_PIN(x)	((x >> 22) & 0x1)
11776d13988SJohnny Huang #define BOOT_SPI_CRTM_SIZE(x)			((x >> 23) & 0x3)
11876d13988SJohnny Huang #define HOST_SPI_CRTM_SIZE(x)			((x >> 25) & 0x3)
11976d13988SJohnny Huang #define ENABLE_HOST_SPI_AUX_CONTROL_PIN(x)	((x >> 27) & 0x1)
12076d13988SJohnny Huang #define ENABLE_GPIO_PASS_THROUGH(x)		((x >> 28) & 0x1)
12176d13988SJohnny Huang #define DISABLE_LOW_SECURITY_KEY(x)		((x >> 29) & 0x1)
12276d13988SJohnny Huang #define ENABLE_DEDICATE_GPIO_STRAP(x)		((x >> 30) & 0x1)
12376d13988SJohnny Huang 
12476d13988SJohnny Huang 
1254c1c9b35SJohnny Huang #define PBSTR "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
1264c1c9b35SJohnny Huang #define PBWIDTH 60
1274c1c9b35SJohnny Huang 
1284c1c9b35SJohnny Huang void printProgress(int numerator, int denominator, char *format, ...)
1294c1c9b35SJohnny Huang {
1304c1c9b35SJohnny Huang 	int val = numerator * 100 / denominator;
1314c1c9b35SJohnny Huang 	int lpad = numerator * PBWIDTH / denominator;
1324c1c9b35SJohnny Huang 	int rpad = PBWIDTH - lpad;
1334c1c9b35SJohnny Huang 	char buffer[256];
1344c1c9b35SJohnny Huang 	va_list aptr;
1354c1c9b35SJohnny Huang 
1364c1c9b35SJohnny Huang 	va_start(aptr, format);
1374c1c9b35SJohnny Huang 	vsprintf(buffer, format, aptr);
1384c1c9b35SJohnny Huang 	va_end(aptr);
1394c1c9b35SJohnny Huang 
1404c1c9b35SJohnny Huang 	printf("\r%3d%% [%.*s%*s] %s", val, lpad, PBSTR, rpad, "", buffer);
1414c1c9b35SJohnny Huang 	if (numerator == denominator)
1424c1c9b35SJohnny Huang 		printf("\n");
1434c1c9b35SJohnny Huang }
1444c1c9b35SJohnny Huang 
14566f2f8e5SJohnny Huang struct otpstrap_status {
14669d5fd8fSJohnny Huang 	int value;
14769d5fd8fSJohnny Huang 	int option_array[7];
14869d5fd8fSJohnny Huang 	int remain_times;
14969d5fd8fSJohnny Huang 	int writeable_option;
15069d5fd8fSJohnny Huang 	int protected;
15169d5fd8fSJohnny Huang };
15269d5fd8fSJohnny Huang 
15366f2f8e5SJohnny Huang struct otpconf_parse {
15466f2f8e5SJohnny Huang 	int dw_offset;
15566f2f8e5SJohnny Huang 	int bit;
15666f2f8e5SJohnny Huang 	int length;
15766f2f8e5SJohnny Huang 	int value;
15866f2f8e5SJohnny Huang 	int keep;
15966f2f8e5SJohnny Huang 	char status[80];
16066f2f8e5SJohnny Huang };
16166f2f8e5SJohnny Huang 
16276d13988SJohnny Huang struct otpstrap_parse {
16376d13988SJohnny Huang 	int bit;
16476d13988SJohnny Huang 	int length;
16576d13988SJohnny Huang 	int value;
16676d13988SJohnny Huang 	int keep;
16776d13988SJohnny Huang 	int protect;
16876d13988SJohnny Huang 	char status[80];
16976d13988SJohnny Huang };
17076d13988SJohnny Huang 
1712a856b9aSJohnny Huang static void otp_read_data(uint32_t offset, uint32_t *data)
17269d5fd8fSJohnny Huang {
17369d5fd8fSJohnny Huang 	writel(offset, 0x1e6f2010); //Read address
17469d5fd8fSJohnny Huang 	writel(0x23b1e361, 0x1e6f2004); //trigger read
17569d5fd8fSJohnny Huang 	udelay(2);
17669d5fd8fSJohnny Huang 	data[0] = readl(0x1e6f2020);
17769d5fd8fSJohnny Huang 	data[1] = readl(0x1e6f2024);
17869d5fd8fSJohnny Huang }
17969d5fd8fSJohnny Huang 
1802a856b9aSJohnny Huang static void otp_read_config(uint32_t offset, uint32_t *data)
18169d5fd8fSJohnny Huang {
18269d5fd8fSJohnny Huang 	int config_offset;
18369d5fd8fSJohnny Huang 
18469d5fd8fSJohnny Huang 	config_offset = 0x800;
18569d5fd8fSJohnny Huang 	config_offset |= (offset / 8) * 0x200;
18669d5fd8fSJohnny Huang 	config_offset |= (offset % 8) * 0x2;
18769d5fd8fSJohnny Huang 
18869d5fd8fSJohnny Huang 	writel(config_offset, 0x1e6f2010);  //Read address
18969d5fd8fSJohnny Huang 	writel(0x23b1e361, 0x1e6f2004); //trigger read
19069d5fd8fSJohnny Huang 	udelay(2);
19169d5fd8fSJohnny Huang 	data[0] = readl(0x1e6f2020);
19269d5fd8fSJohnny Huang }
19369d5fd8fSJohnny Huang 
19469d5fd8fSJohnny Huang static int otp_print_config(uint32_t offset, int dw_count)
19569d5fd8fSJohnny Huang {
19669d5fd8fSJohnny Huang 	int i;
19769d5fd8fSJohnny Huang 	uint32_t ret[1];
19869d5fd8fSJohnny Huang 
19969d5fd8fSJohnny Huang 	if (offset + dw_count > 32)
2002a856b9aSJohnny Huang 		return OTP_USAGE;
20169d5fd8fSJohnny Huang 	for (i = offset; i < offset + dw_count; i ++) {
20269d5fd8fSJohnny Huang 		otp_read_config(i, ret);
203a6af4a17SJohnny Huang 		printf("OTPCFG%X: %08X\n", i, ret[0]);
20469d5fd8fSJohnny Huang 	}
20569d5fd8fSJohnny Huang 	printf("\n");
2062a856b9aSJohnny Huang 	return OTP_SUCCESS;
20769d5fd8fSJohnny Huang }
20869d5fd8fSJohnny Huang 
20969d5fd8fSJohnny Huang static int otp_print_data(uint32_t offset, int dw_count)
21069d5fd8fSJohnny Huang {
21169d5fd8fSJohnny Huang 	int i;
21269d5fd8fSJohnny Huang 	uint32_t ret[2];
21369d5fd8fSJohnny Huang 
21469d5fd8fSJohnny Huang 	if (offset + dw_count > 2048 || offset % 4 != 0)
2152a856b9aSJohnny Huang 		return OTP_USAGE;
21669d5fd8fSJohnny Huang 	for (i = offset; i < offset + dw_count; i += 2) {
21769d5fd8fSJohnny Huang 		otp_read_data(i, ret);
21869d5fd8fSJohnny Huang 		if (i % 4 == 0)
21969d5fd8fSJohnny Huang 			printf("%03X: %08X %08X ", i * 4, ret[0], ret[1]);
22069d5fd8fSJohnny Huang 		else
22169d5fd8fSJohnny Huang 			printf("%08X %08X\n", ret[0], ret[1]);
22269d5fd8fSJohnny Huang 
22369d5fd8fSJohnny Huang 	}
22469d5fd8fSJohnny Huang 	printf("\n");
2252a856b9aSJohnny Huang 	return OTP_SUCCESS;
22669d5fd8fSJohnny Huang }
22769d5fd8fSJohnny Huang 
22869d5fd8fSJohnny Huang static int otp_compare(uint32_t otp_addr, uint32_t addr)
22969d5fd8fSJohnny Huang {
23069d5fd8fSJohnny Huang 	uint32_t ret;
23169d5fd8fSJohnny Huang 	uint32_t *buf;
23269d5fd8fSJohnny Huang 
23369d5fd8fSJohnny Huang 	buf = map_physmem(addr, 16, MAP_WRBACK);
23469d5fd8fSJohnny Huang 	printf("%08X\n", buf[0]);
23569d5fd8fSJohnny Huang 	printf("%08X\n", buf[1]);
23669d5fd8fSJohnny Huang 	printf("%08X\n", buf[2]);
23769d5fd8fSJohnny Huang 	printf("%08X\n", buf[3]);
23869d5fd8fSJohnny Huang 	writel(otp_addr, 0x1e6f2010); //Compare address
23969d5fd8fSJohnny Huang 	writel(buf[0], 0x1e6f2020); //Compare data 1
24069d5fd8fSJohnny Huang 	writel(buf[1], 0x1e6f2024); //Compare data 2
24169d5fd8fSJohnny Huang 	writel(buf[2], 0x1e6f2028); //Compare data 3
24269d5fd8fSJohnny Huang 	writel(buf[3], 0x1e6f202c); //Compare data 4
24369d5fd8fSJohnny Huang 	writel(0x23b1e363, 0x1e6f2004); //Compare command
24469d5fd8fSJohnny Huang 	udelay(10);
24569d5fd8fSJohnny Huang 	ret = readl(0x1e6f2014); //Compare command
24669d5fd8fSJohnny Huang 	if (ret & 0x1)
24769d5fd8fSJohnny Huang 		return 0;
24869d5fd8fSJohnny Huang 	else
24969d5fd8fSJohnny Huang 		return -1;
25069d5fd8fSJohnny Huang }
25169d5fd8fSJohnny Huang 
25269d5fd8fSJohnny Huang static void otp_write(uint32_t otp_addr, uint32_t data)
25369d5fd8fSJohnny Huang {
25469d5fd8fSJohnny Huang 	writel(otp_addr, 0x1e6f2010); //write address
25569d5fd8fSJohnny Huang 	writel(data, 0x1e6f2020); //write data
25669d5fd8fSJohnny Huang 	writel(0x23b1e362, 0x1e6f2004); //write command
25769d5fd8fSJohnny Huang 	udelay(100);
25869d5fd8fSJohnny Huang }
25969d5fd8fSJohnny Huang 
26069d5fd8fSJohnny Huang static void otp_prog(uint32_t otp_addr, uint32_t prog_bit)
26169d5fd8fSJohnny Huang {
26269d5fd8fSJohnny Huang 	writel(otp_addr, 0x1e6f2010); //write address
26369d5fd8fSJohnny Huang 	writel(prog_bit, 0x1e6f2020); //write data
26469d5fd8fSJohnny Huang 	writel(0x23b1e364, 0x1e6f2004); //write command
26569d5fd8fSJohnny Huang 	udelay(85);
26669d5fd8fSJohnny Huang }
26769d5fd8fSJohnny Huang 
268a6d0d645SJohnny Huang static int verify_bit(uint32_t otp_addr, int bit_offset, int value)
26969d5fd8fSJohnny Huang {
27069d5fd8fSJohnny Huang 	int ret;
27169d5fd8fSJohnny Huang 
27269d5fd8fSJohnny Huang 	writel(otp_addr, 0x1e6f2010); //Read address
27369d5fd8fSJohnny Huang 	writel(0x23b1e361, 0x1e6f2004); //trigger read
27469d5fd8fSJohnny Huang 	udelay(2);
27569d5fd8fSJohnny Huang 	ret = readl(0x1e6f2020);
276a6d0d645SJohnny Huang 	// printf("verify_bit = %x\n", ret);
27769d5fd8fSJohnny Huang 	if (((ret >> bit_offset) & 1) == value)
27869d5fd8fSJohnny Huang 		return 0;
27969d5fd8fSJohnny Huang 	else
28069d5fd8fSJohnny Huang 		return -1;
28169d5fd8fSJohnny Huang }
28269d5fd8fSJohnny Huang 
283d90825e2SJohnny Huang static uint32_t verify_dw(uint32_t otp_addr, uint32_t *value, uint32_t *keep, uint32_t *compare, int size)
2844c1c9b35SJohnny Huang {
2854c1c9b35SJohnny Huang 	uint32_t ret[2];
2864c1c9b35SJohnny Huang 
2874c1c9b35SJohnny Huang 	otp_addr &= ~(1 << 15);
2884c1c9b35SJohnny Huang 
2894c1c9b35SJohnny Huang 	if (otp_addr % 2 == 0)
2904c1c9b35SJohnny Huang 		writel(otp_addr, 0x1e6f2010); //Read address
2914c1c9b35SJohnny Huang 	else
2924c1c9b35SJohnny Huang 		writel(otp_addr - 1, 0x1e6f2010); //Read address
2934c1c9b35SJohnny Huang 	writel(0x23b1e361, 0x1e6f2004); //trigger read
2944c1c9b35SJohnny Huang 	udelay(2);
2954c1c9b35SJohnny Huang 	ret[0] = readl(0x1e6f2020);
2964c1c9b35SJohnny Huang 	ret[1] = readl(0x1e6f2024);
2974c1c9b35SJohnny Huang 	if (size == 1) {
2984c1c9b35SJohnny Huang 		if (otp_addr % 2 == 0) {
2994c1c9b35SJohnny Huang 			// printf("check %x : %x = %x\n", otp_addr, ret[0], value[0]);
300d90825e2SJohnny Huang 			if ((value[0] & ~keep[0]) == (ret[0] & ~keep[0])) {
3014c1c9b35SJohnny Huang 				compare[0] = 0;
3024c1c9b35SJohnny Huang 				return 0;
3034c1c9b35SJohnny Huang 			} else {
3044c1c9b35SJohnny Huang 				compare[0] = value[0] ^ ret[0];
3054c1c9b35SJohnny Huang 				return -1;
3064c1c9b35SJohnny Huang 			}
3074c1c9b35SJohnny Huang 
3084c1c9b35SJohnny Huang 		} else {
3094c1c9b35SJohnny Huang 			// printf("check %x : %x = %x\n", otp_addr, ret[1], value[0]);
310d90825e2SJohnny Huang 			if ((value[0] & ~keep[0]) == (ret[1] & ~keep[0])) {
3114c1c9b35SJohnny Huang 				compare[0] = ~0;
3124c1c9b35SJohnny Huang 				return 0;
3134c1c9b35SJohnny Huang 			} else {
314d90825e2SJohnny Huang 				compare[0] = ~(value[0] ^ ret[1]);
3154c1c9b35SJohnny Huang 				return -1;
3164c1c9b35SJohnny Huang 			}
3174c1c9b35SJohnny Huang 		}
3184c1c9b35SJohnny Huang 	} else if (size == 2) {
3194c1c9b35SJohnny Huang 		// otp_addr should be even
320d90825e2SJohnny Huang 		if ((value[0] & ~keep[0]) == (ret[0] & ~keep[0]) && (value[1] & ~keep[1]) == (ret[1] & ~keep[1])) {
3214c1c9b35SJohnny Huang 			// printf("check[0] %x : %x = %x\n", otp_addr, ret[0], value[0]);
3224c1c9b35SJohnny Huang 			// printf("check[1] %x : %x = %x\n", otp_addr, ret[1], value[1]);
3234c1c9b35SJohnny Huang 			compare[0] = 0;
3244c1c9b35SJohnny Huang 			compare[1] = ~0;
3254c1c9b35SJohnny Huang 			return 0;
3264c1c9b35SJohnny Huang 		} else {
3274c1c9b35SJohnny Huang 			// printf("check[0] %x : %x = %x\n", otp_addr, ret[0], value[0]);
3284c1c9b35SJohnny Huang 			// printf("check[1] %x : %x = %x\n", otp_addr, ret[1], value[1]);
3294c1c9b35SJohnny Huang 			compare[0] = value[0] ^ ret[0];
3304c1c9b35SJohnny Huang 			compare[1] = ~(value[1] ^ ret[1]);
3314c1c9b35SJohnny Huang 			return -1;
3324c1c9b35SJohnny Huang 		}
3334c1c9b35SJohnny Huang 	} else {
3344c1c9b35SJohnny Huang 		return -1;
3354c1c9b35SJohnny Huang 	}
3364c1c9b35SJohnny Huang }
3374c1c9b35SJohnny Huang 
3387e22f42dSJohnny Huang static void otp_soak(int soak)
339d90825e2SJohnny Huang {
340d90825e2SJohnny Huang 	if (soak) {
341d90825e2SJohnny Huang 		otp_write(0x3000, 0x4021); // Write MRA
342d90825e2SJohnny Huang 		otp_write(0x5000, 0x1027); // Write MRB
343d90825e2SJohnny Huang 		otp_write(0x1000, 0x4820); // Write MR
344d90825e2SJohnny Huang 		writel(0x041930d4, 0x1e602008); //soak program
345d90825e2SJohnny Huang 	} else {
346d90825e2SJohnny Huang 		otp_write(0x3000, 0x4061); // Write MRA
347d90825e2SJohnny Huang 		otp_write(0x5000, 0x302f); // Write MRB
348d90825e2SJohnny Huang 		otp_write(0x1000, 0x4020); // Write MR
349d90825e2SJohnny Huang 		writel(0x04190760, 0x1e602008); //normal program
350d90825e2SJohnny Huang 	}
351d90825e2SJohnny Huang }
352d90825e2SJohnny Huang 
353d90825e2SJohnny Huang static void otp_prog_dw(uint32_t value, uint32_t keep, uint32_t prog_address)
354d90825e2SJohnny Huang {
355d90825e2SJohnny Huang 	int j, bit_value, prog_bit;
356d90825e2SJohnny Huang 
357d90825e2SJohnny Huang 	for (j = 0; j < 32; j++) {
358d90825e2SJohnny Huang 		if ((keep >> j) & 0x1)
359d90825e2SJohnny Huang 			continue;
360d90825e2SJohnny Huang 		bit_value = (value >> j) & 0x1;
361d90825e2SJohnny Huang 		if (prog_address % 2 == 0) {
362d90825e2SJohnny Huang 			if (bit_value)
363d90825e2SJohnny Huang 				prog_bit = ~(0x1 << j);
364d90825e2SJohnny Huang 			else
365d90825e2SJohnny Huang 				continue;
366d90825e2SJohnny Huang 		} else {
367d90825e2SJohnny Huang 			prog_address |= 1 << 15;
368d90825e2SJohnny Huang 			if (bit_value)
369d90825e2SJohnny Huang 				continue;
370d90825e2SJohnny Huang 			else
371d90825e2SJohnny Huang 				prog_bit = 0x1 << j;
372d90825e2SJohnny Huang 		}
373d90825e2SJohnny Huang 		otp_prog(prog_address, prog_bit);
374d90825e2SJohnny Huang 	}
375d90825e2SJohnny Huang }
376d90825e2SJohnny Huang 
37776d13988SJohnny Huang 
37876d13988SJohnny Huang static void otp_strp_status(struct otpstrap_status *otpstrap)
37976d13988SJohnny Huang {
38076d13988SJohnny Huang 	uint32_t OTPSTRAP_RAW[2];
38176d13988SJohnny Huang 	int i, j;
38276d13988SJohnny Huang 
38376d13988SJohnny Huang 	for (j = 0; j < 64; j++) {
38476d13988SJohnny Huang 		otpstrap[j].value = 0;
38576d13988SJohnny Huang 		otpstrap[j].remain_times = 7;
38676d13988SJohnny Huang 		otpstrap[j].writeable_option = -1;
38776d13988SJohnny Huang 		otpstrap[j].protected = 0;
38876d13988SJohnny Huang 	}
38976d13988SJohnny Huang 
39076d13988SJohnny Huang 	for (i = 16; i < 30; i += 2) {
39176d13988SJohnny Huang 		int option = (i - 16) / 2;
39276d13988SJohnny Huang 		otp_read_config(i, &OTPSTRAP_RAW[0]);
39376d13988SJohnny Huang 		otp_read_config(i + 1, &OTPSTRAP_RAW[1]);
39476d13988SJohnny Huang 		for (j = 0; j < 32; j++) {
39576d13988SJohnny Huang 			char bit_value = ((OTPSTRAP_RAW[0] >> j) & 0x1);
39676d13988SJohnny Huang 			if ((bit_value == 0) && (otpstrap[j].writeable_option == -1)) {
39776d13988SJohnny Huang 				otpstrap[j].writeable_option = option;
39876d13988SJohnny Huang 			}
39976d13988SJohnny Huang 			if (bit_value == 1)
40076d13988SJohnny Huang 				otpstrap[j].remain_times --;
40176d13988SJohnny Huang 			otpstrap[j].value ^= bit_value;
40276d13988SJohnny Huang 			otpstrap[j].option_array[option] = bit_value;
40376d13988SJohnny Huang 		}
40476d13988SJohnny Huang 		for (j = 32; j < 64; j++) {
40576d13988SJohnny Huang 			char bit_value = ((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1);
40676d13988SJohnny Huang 			if ((bit_value == 0) && (otpstrap[j].writeable_option == -1)) {
40776d13988SJohnny Huang 				otpstrap[j].writeable_option = option;
40876d13988SJohnny Huang 			}
40976d13988SJohnny Huang 			if (bit_value == 1)
41076d13988SJohnny Huang 				otpstrap[j].remain_times --;
41176d13988SJohnny Huang 			otpstrap[j].value ^= bit_value;
41276d13988SJohnny Huang 			otpstrap[j].option_array[option] = bit_value;
41376d13988SJohnny Huang 		}
41476d13988SJohnny Huang 	}
41576d13988SJohnny Huang 	otp_read_config(30, &OTPSTRAP_RAW[0]);
41676d13988SJohnny Huang 	otp_read_config(31, &OTPSTRAP_RAW[1]);
41776d13988SJohnny Huang 	for (j = 0; j < 32; j++) {
41876d13988SJohnny Huang 		if (((OTPSTRAP_RAW[0] >> j) & 0x1) == 1)
41976d13988SJohnny Huang 			otpstrap[j].protected = 1;
42076d13988SJohnny Huang 	}
42176d13988SJohnny Huang 	for (j = 32; j < 64; j++) {
42276d13988SJohnny Huang 		if (((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1) == 1)
42376d13988SJohnny Huang 			otpstrap[j].protected = 1;
42476d13988SJohnny Huang 	}
42576d13988SJohnny Huang }
42676d13988SJohnny Huang 
42766f2f8e5SJohnny Huang static int otp_conf_parse(uint32_t *OTPCFG, struct otpconf_parse *conf_parse)
42869d5fd8fSJohnny Huang {
4294c1c9b35SJohnny Huang 	int tmp, i;
43066f2f8e5SJohnny Huang 	int k = 0;
4314c1c9b35SJohnny Huang 	int pass = 0;
432442839bbSJohnny Huang 	uint32_t *OTPCFG_KEEP = &OTPCFG[12];
43369d5fd8fSJohnny Huang 
43466f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
43566f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
43666f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
43766f2f8e5SJohnny Huang 	conf_parse[k].value = DISABLE_SECREG_PROG(OTPCFG[0]);
43866f2f8e5SJohnny Huang 	if (DISABLE_SECREG_PROG(OTPCFG_KEEP[0])) {
43966f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
44066f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
441442839bbSJohnny Huang 	} else {
44266f2f8e5SJohnny Huang 		if (DISABLE_SECREG_PROG(OTPCFG[0]))
44366f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
44466f2f8e5SJohnny Huang 			       "Disable Secure Region programming");
44569d5fd8fSJohnny Huang 		else
44666f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
44766f2f8e5SJohnny Huang 			       "Enable Secure Region programming");
448442839bbSJohnny Huang 	}
449442839bbSJohnny Huang 
45066f2f8e5SJohnny Huang 	k++;
45166f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
45266f2f8e5SJohnny Huang 	conf_parse[k].bit = 1;
45366f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
45466f2f8e5SJohnny Huang 	conf_parse[k].value = ENABLE_SEC_BOOT(OTPCFG[0]);
45566f2f8e5SJohnny Huang 	if (ENABLE_SEC_BOOT(OTPCFG_KEEP[0])) {
45666f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
45766f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
458442839bbSJohnny Huang 	} else {
45966f2f8e5SJohnny Huang 		if (ENABLE_SEC_BOOT(OTPCFG[0]))
46066f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
46166f2f8e5SJohnny Huang 			       "Enable Secure Boot");
46269d5fd8fSJohnny Huang 		else
46366f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
46466f2f8e5SJohnny Huang 			       "Disable Secure Boot");
465442839bbSJohnny Huang 	}
466442839bbSJohnny Huang 
46766f2f8e5SJohnny Huang 	k++;
46866f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
46966f2f8e5SJohnny Huang 	conf_parse[k].bit = 3;
47066f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
47166f2f8e5SJohnny Huang 	conf_parse[k].value = ENABLE_USERREG_ECC(OTPCFG[0]);
47266f2f8e5SJohnny Huang 	if (ENABLE_USERREG_ECC(OTPCFG_KEEP[0])) {
47366f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
47466f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
475442839bbSJohnny Huang 	} else {
47666f2f8e5SJohnny Huang 		if (ENABLE_USERREG_ECC(OTPCFG[0]))
47766f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
47866f2f8e5SJohnny Huang 			       "User region ECC enable");
47969d5fd8fSJohnny Huang 		else
48066f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
48166f2f8e5SJohnny Huang 			       "User region ECC disable");
482442839bbSJohnny Huang 	}
483442839bbSJohnny Huang 
48466f2f8e5SJohnny Huang 	k++;
48566f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
48666f2f8e5SJohnny Huang 	conf_parse[k].bit = 4;
48766f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
48866f2f8e5SJohnny Huang 	conf_parse[k].value = ENABLE_SECREG_ECC(OTPCFG[0]);
48966f2f8e5SJohnny Huang 	if (ENABLE_SECREG_ECC(OTPCFG_KEEP[0])) {
49066f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
49166f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
492442839bbSJohnny Huang 	} else {
49366f2f8e5SJohnny Huang 		if (ENABLE_SECREG_ECC(OTPCFG[0]))
49466f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
49566f2f8e5SJohnny Huang 			       "Secure Region ECC enable");
49669d5fd8fSJohnny Huang 		else
49766f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
49866f2f8e5SJohnny Huang 			       "Secure Region ECC disable");
499442839bbSJohnny Huang 	}
500442839bbSJohnny Huang 
50166f2f8e5SJohnny Huang 	k++;
50266f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
50366f2f8e5SJohnny Huang 	conf_parse[k].bit = 5;
50466f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
50566f2f8e5SJohnny Huang 	conf_parse[k].value = DISABLE_LOW_SEC_KEY(OTPCFG[0]);
50666f2f8e5SJohnny Huang 	if (DISABLE_LOW_SEC_KEY(OTPCFG_KEEP[0])) {
50766f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
50866f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
509442839bbSJohnny Huang 	} else {
51066f2f8e5SJohnny Huang 		if (DISABLE_LOW_SEC_KEY(OTPCFG[0]))
51166f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
51266f2f8e5SJohnny Huang 			       "Disable low security key");
51369d5fd8fSJohnny Huang 		else
51466f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
51566f2f8e5SJohnny Huang 			       "Enable low security key");
516442839bbSJohnny Huang 	}
517442839bbSJohnny Huang 
51866f2f8e5SJohnny Huang 	k++;
51966f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
52066f2f8e5SJohnny Huang 	conf_parse[k].bit = 6;
52166f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
52266f2f8e5SJohnny Huang 	conf_parse[k].value = IGNORE_SEC_BOOT_HWSTRAP(OTPCFG[0]);
52366f2f8e5SJohnny Huang 	if (IGNORE_SEC_BOOT_HWSTRAP(OTPCFG_KEEP[0])) {
52466f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
52566f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
526442839bbSJohnny Huang 	} else {
52766f2f8e5SJohnny Huang 		if (IGNORE_SEC_BOOT_HWSTRAP(OTPCFG[0]))
52866f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
52966f2f8e5SJohnny Huang 			       "Ignore Secure Boot hardware strap");
53069d5fd8fSJohnny Huang 		else
53166f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
53266f2f8e5SJohnny Huang 			       "Do not ignore Secure Boot hardware strap");
533442839bbSJohnny Huang 	}
534442839bbSJohnny Huang 
53566f2f8e5SJohnny Huang 	k++;
53666f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
53766f2f8e5SJohnny Huang 	conf_parse[k].bit = 7;
53866f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
53966f2f8e5SJohnny Huang 	conf_parse[k].value = SEC_BOOT_MDOES(OTPCFG[0]);
54066f2f8e5SJohnny Huang 	if (SEC_BOOT_MDOES(OTPCFG_KEEP[0])) {
54166f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
54266f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
543442839bbSJohnny Huang 	} else {
54466f2f8e5SJohnny Huang 		if (SEC_BOOT_MDOES(OTPCFG[0]))
54566f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
54666f2f8e5SJohnny Huang 			       "Secure Boot Mode: 1");
547e1f9e54eSJohnny Huang 		else
54866f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
54966f2f8e5SJohnny Huang 			       "Secure Boot Mode: 2");
550442839bbSJohnny Huang 	}
551442839bbSJohnny Huang 
55266f2f8e5SJohnny Huang 	k++;
55366f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
55466f2f8e5SJohnny Huang 	conf_parse[k].bit = 8;
55566f2f8e5SJohnny Huang 	conf_parse[k].length = 2;
55666f2f8e5SJohnny Huang 	conf_parse[k].value = OTP_BIT_CELL_MODES(OTPCFG[0]);
557442839bbSJohnny Huang 	if (OTP_BIT_CELL_MODES(OTPCFG_KEEP[0]) == 0x3) {
55866f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
55966f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
56066f2f8e5SJohnny Huang 	} else if (OTP_BIT_CELL_MODES(OTPCFG_KEEP[0]) == 0) {
56166f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "OTP bit cell mode : ");
56266f2f8e5SJohnny Huang 		if (conf_parse[k].value == SINGLE_CELL_MODE) {
56366f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
56466f2f8e5SJohnny Huang 			       "Single cell mode (recommended)");
56566f2f8e5SJohnny Huang 		} else if (conf_parse[k].value == DIFFERENTIAL_MODE) {
56666f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
56766f2f8e5SJohnny Huang 			       "Differnetial mode");
56866f2f8e5SJohnny Huang 		} else if (conf_parse[k].value == DIFFERENTIAL_REDUDANT_MODE) {
56966f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
57066f2f8e5SJohnny Huang 			       "Differential-redundant mode");
571442839bbSJohnny Huang 		} else {
57266f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
57366f2f8e5SJohnny Huang 			       "Value error");
57469d5fd8fSJohnny Huang 			return -1;
57569d5fd8fSJohnny Huang 		}
57666f2f8e5SJohnny Huang 	} else {
57766f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
57866f2f8e5SJohnny Huang 		return -1;
579442839bbSJohnny Huang 	}
58066f2f8e5SJohnny Huang 
58166f2f8e5SJohnny Huang 	k++;
58266f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
58366f2f8e5SJohnny Huang 	conf_parse[k].bit = 10;
58466f2f8e5SJohnny Huang 	conf_parse[k].length = 2;
58566f2f8e5SJohnny Huang 	conf_parse[k].value = CRYPTO_MODES(OTPCFG[0]);
586442839bbSJohnny Huang 	if (CRYPTO_MODES(OTPCFG_KEEP[0]) == 0x3) {
58766f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
58866f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
58966f2f8e5SJohnny Huang 	} else if (CRYPTO_MODES(OTPCFG_KEEP[0]) == 0) {
59066f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "RSA mode : ");
59166f2f8e5SJohnny Huang 		if (conf_parse[k].value == CRYPTO_RSA1024) {
59266f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
59366f2f8e5SJohnny Huang 			       "RSA1024");
59466f2f8e5SJohnny Huang 		} else if (conf_parse[k].value == CRYPTO_RSA2048) {
59566f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
59666f2f8e5SJohnny Huang 			       "RSA2048");
59766f2f8e5SJohnny Huang 		} else if (conf_parse[k].value == CRYPTO_RSA3072) {
59866f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
59966f2f8e5SJohnny Huang 			       "RSA3072");
600442839bbSJohnny Huang 		} else {
60166f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
60266f2f8e5SJohnny Huang 			       "RSA4096");
60366f2f8e5SJohnny Huang 		}
60469d5fd8fSJohnny Huang 	} else {
60566f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
60666f2f8e5SJohnny Huang 		return -1;
60769d5fd8fSJohnny Huang 	}
60866f2f8e5SJohnny Huang 
60966f2f8e5SJohnny Huang 	k++;
61066f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
61166f2f8e5SJohnny Huang 	conf_parse[k].bit = 12;
61266f2f8e5SJohnny Huang 	conf_parse[k].length = 2;
61366f2f8e5SJohnny Huang 	conf_parse[k].value = HASH_MODES(OTPCFG[0]);
614442839bbSJohnny Huang 	if (HASH_MODES(OTPCFG_KEEP[0]) == 0x3) {
61566f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
61666f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
61766f2f8e5SJohnny Huang 	} else if (HASH_MODES(OTPCFG_KEEP[0]) == 0) {
61866f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "SHA mode : ");
61966f2f8e5SJohnny Huang 		if (conf_parse[k].value == HASH_SAH224) {
62066f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
62166f2f8e5SJohnny Huang 			       "SHA224");
62266f2f8e5SJohnny Huang 		} else if (conf_parse[k].value == HASH_SAH256) {
62366f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
62466f2f8e5SJohnny Huang 			       "SHA256");
62566f2f8e5SJohnny Huang 		} else if (conf_parse[k].value == HASH_SAH384) {
62666f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
62766f2f8e5SJohnny Huang 			       "SHA384");
628442839bbSJohnny Huang 		} else {
62966f2f8e5SJohnny Huang 			strcat(conf_parse[k].status,
63066f2f8e5SJohnny Huang 			       "SHA512");
63169d5fd8fSJohnny Huang 		}
63266f2f8e5SJohnny Huang 	} else {
63366f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
63466f2f8e5SJohnny Huang 		return -1;
635442839bbSJohnny Huang 	}
63669d5fd8fSJohnny Huang 
63766f2f8e5SJohnny Huang 	k++;
63866f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
63966f2f8e5SJohnny Huang 	conf_parse[k].bit = 16;
64066f2f8e5SJohnny Huang 	conf_parse[k].length = 6;
64166f2f8e5SJohnny Huang 	conf_parse[k].value = SECREG_SIZE(OTPCFG[0]);
642442839bbSJohnny Huang 	if (SECREG_SIZE(OTPCFG_KEEP[0]) == 0x3f) {
64366f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
64466f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
64566f2f8e5SJohnny Huang 	} else if (SECREG_SIZE(OTPCFG_KEEP[0]) == 0) {
64666f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
64766f2f8e5SJohnny Huang 			"Secure Region size (DW): 0x%x", SECREG_SIZE(OTPCFG[0]));
648442839bbSJohnny Huang 	} else {
64966f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
65066f2f8e5SJohnny Huang 		return -1;
651442839bbSJohnny Huang 	}
65269d5fd8fSJohnny Huang 
65366f2f8e5SJohnny Huang 	k++;
65466f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
65566f2f8e5SJohnny Huang 	conf_parse[k].bit = 22;
65666f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
65766f2f8e5SJohnny Huang 	conf_parse[k].value = WRITE_PROTECT_SECREG(OTPCFG[0]);
65866f2f8e5SJohnny Huang 	if (WRITE_PROTECT_SECREG(OTPCFG_KEEP[0])) {
65966f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
66066f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
661442839bbSJohnny Huang 	} else {
66266f2f8e5SJohnny Huang 		if (WRITE_PROTECT_SECREG(OTPCFG[0]))
66366f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
66466f2f8e5SJohnny Huang 			       "Secure Region : Write Protect");
66569d5fd8fSJohnny Huang 		else
66666f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
66766f2f8e5SJohnny Huang 			       "Secure Region : Writable");
668442839bbSJohnny Huang 	}
669442839bbSJohnny Huang 
67066f2f8e5SJohnny Huang 	k++;
67166f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
67266f2f8e5SJohnny Huang 	conf_parse[k].bit = 23;
67366f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
67466f2f8e5SJohnny Huang 	conf_parse[k].value = WRITE_PROTECT_USERREG(OTPCFG[0]);
67566f2f8e5SJohnny Huang 	if (WRITE_PROTECT_USERREG(OTPCFG_KEEP[0])) {
67666f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
67766f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
678442839bbSJohnny Huang 	} else {
67966f2f8e5SJohnny Huang 		if (WRITE_PROTECT_USERREG(OTPCFG[0]))
68066f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
68166f2f8e5SJohnny Huang 			       "User Region : Write Protect");
68269d5fd8fSJohnny Huang 		else
68366f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
68466f2f8e5SJohnny Huang 			       "User Region : Writable");
685442839bbSJohnny Huang 	}
686442839bbSJohnny Huang 
68766f2f8e5SJohnny Huang 	k++;
68866f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
68966f2f8e5SJohnny Huang 	conf_parse[k].bit = 24;
69066f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
69166f2f8e5SJohnny Huang 	conf_parse[k].value = WRITE_PROTECT_CONFREG(OTPCFG[0]);
69266f2f8e5SJohnny Huang 	if (WRITE_PROTECT_CONFREG(OTPCFG_KEEP[0])) {
69366f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
69466f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
695442839bbSJohnny Huang 	} else {
69666f2f8e5SJohnny Huang 		if (WRITE_PROTECT_CONFREG(OTPCFG[0]))
69766f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
69866f2f8e5SJohnny Huang 			       "Configure Region : Write Protect");
69969d5fd8fSJohnny Huang 		else
70066f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
70166f2f8e5SJohnny Huang 			       "Configure Region : Writable");
702442839bbSJohnny Huang 	}
703442839bbSJohnny Huang 
70466f2f8e5SJohnny Huang 	k++;
70566f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
70666f2f8e5SJohnny Huang 	conf_parse[k].bit = 25;
70766f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
70866f2f8e5SJohnny Huang 	conf_parse[k].value = WRITE_PROTECT_STRAPREG(OTPCFG[0]);
70966f2f8e5SJohnny Huang 	if (WRITE_PROTECT_STRAPREG(OTPCFG_KEEP[0])) {
71066f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
71166f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
712442839bbSJohnny Huang 	} else {
71366f2f8e5SJohnny Huang 		if (WRITE_PROTECT_STRAPREG(OTPCFG[0]))
71466f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
71566f2f8e5SJohnny Huang 			       "OTP strap Region : Write Protect");
71669d5fd8fSJohnny Huang 		else
71766f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
71866f2f8e5SJohnny Huang 			       "OTP strap Region : Writable");
719442839bbSJohnny Huang 	}
720442839bbSJohnny Huang 
72166f2f8e5SJohnny Huang 	k++;
72266f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
72366f2f8e5SJohnny Huang 	conf_parse[k].bit = 26;
72466f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
72566f2f8e5SJohnny Huang 	conf_parse[k].value = ENABLE_COPY_TO_SRAM(OTPCFG[0]);
72666f2f8e5SJohnny Huang 	if (ENABLE_COPY_TO_SRAM(OTPCFG_KEEP[0])) {
72766f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
72866f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
729442839bbSJohnny Huang 	} else {
73066f2f8e5SJohnny Huang 		if (ENABLE_COPY_TO_SRAM(OTPCFG[0]))
73166f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
73266f2f8e5SJohnny Huang 			       "Copy Boot Image to Internal SRAM");
73369d5fd8fSJohnny Huang 		else
73466f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
73566f2f8e5SJohnny Huang 			       "Disable Copy Boot Image to Internal SRAM");
736442839bbSJohnny Huang 	}
73766f2f8e5SJohnny Huang 
73866f2f8e5SJohnny Huang 	k++;
73966f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
74066f2f8e5SJohnny Huang 	conf_parse[k].bit = 27;
74166f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
74266f2f8e5SJohnny Huang 	conf_parse[k].value = ENABLE_IMAGE_ENC(OTPCFG[0]);
74366f2f8e5SJohnny Huang 	if (ENABLE_IMAGE_ENC(OTPCFG_KEEP[0])) {
74466f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
74566f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
746442839bbSJohnny Huang 	} else {
74766f2f8e5SJohnny Huang 		if (ENABLE_IMAGE_ENC(OTPCFG[0]))
74866f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
74966f2f8e5SJohnny Huang 			       "Enable image encryption");
75069d5fd8fSJohnny Huang 		else
75166f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
75266f2f8e5SJohnny Huang 			       "Disable image encryption");
753442839bbSJohnny Huang 	}
754442839bbSJohnny Huang 
75566f2f8e5SJohnny Huang 	k++;
75666f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
75766f2f8e5SJohnny Huang 	conf_parse[k].bit = 29;
75866f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
75966f2f8e5SJohnny Huang 	conf_parse[k].value = WRITE_PROTECT_KEY_RETIRE(OTPCFG[0]);
76066f2f8e5SJohnny Huang 	if (WRITE_PROTECT_KEY_RETIRE(OTPCFG_KEEP[0])) {
76166f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
76266f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
763442839bbSJohnny Huang 	} else {
76466f2f8e5SJohnny Huang 		if (WRITE_PROTECT_KEY_RETIRE(OTPCFG[0]))
76566f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
76666f2f8e5SJohnny Huang 			       "OTP key retire Region : Write Protect");
76769d5fd8fSJohnny Huang 		else
76866f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
76966f2f8e5SJohnny Huang 			       "OTP key retire Region : Writable");
770442839bbSJohnny Huang 	}
771442839bbSJohnny Huang 
77266f2f8e5SJohnny Huang 	k++;
77366f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
77466f2f8e5SJohnny Huang 	conf_parse[k].bit = 30;
77566f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
77666f2f8e5SJohnny Huang 	conf_parse[k].value = ENABLE_SIPROM_RED(OTPCFG[0]);
77766f2f8e5SJohnny Huang 	if (ENABLE_SIPROM_RED(OTPCFG_KEEP[0])) {
77866f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
77966f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
780442839bbSJohnny Huang 	} else {
78166f2f8e5SJohnny Huang 		if (ENABLE_SIPROM_RED(OTPCFG[0]))
78266f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
78366f2f8e5SJohnny Huang 			       "SIPROM RED_EN redundancy repair enable");
78469d5fd8fSJohnny Huang 		else
78566f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
78666f2f8e5SJohnny Huang 			       "SIPROM RED_EN redundancy repair disable");
787442839bbSJohnny Huang 	}
788442839bbSJohnny Huang 
78966f2f8e5SJohnny Huang 	k++;
79066f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 0;
79166f2f8e5SJohnny Huang 	conf_parse[k].bit = 31;
79266f2f8e5SJohnny Huang 	conf_parse[k].length = 1;
79366f2f8e5SJohnny Huang 	conf_parse[k].value = ENABLE_SIPROM_MLOCK(OTPCFG[0]);
79466f2f8e5SJohnny Huang 	if (ENABLE_SIPROM_MLOCK(OTPCFG_KEEP[0])) {
79566f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
79666f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
797442839bbSJohnny Huang 	} else {
79866f2f8e5SJohnny Huang 		if (ENABLE_SIPROM_MLOCK(OTPCFG[0]))
79966f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
80066f2f8e5SJohnny Huang 			       "SIPROM Mlock memory lock enable");
80169d5fd8fSJohnny Huang 		else
80266f2f8e5SJohnny Huang 			strcpy(conf_parse[k].status,
80366f2f8e5SJohnny Huang 			       "SIPROM Mlock memory lock disable");
804442839bbSJohnny Huang 	}
80569d5fd8fSJohnny Huang 
80666f2f8e5SJohnny Huang 	k++;
80766f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 2;
80866f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
80966f2f8e5SJohnny Huang 	conf_parse[k].length = 16;
81066f2f8e5SJohnny Huang 	conf_parse[k].value = VENDER_ID(OTPCFG[2]);
81166f2f8e5SJohnny Huang 	if (VENDER_ID(OTPCFG_KEEP[2]) == 0xffff) {
81266f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
81366f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
81466f2f8e5SJohnny Huang 	} else if (VENDER_ID(OTPCFG_KEEP[2]) == 0) {
81566f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
81666f2f8e5SJohnny Huang 			"Vender ID : 0x%x", VENDER_ID(OTPCFG[2]));
817442839bbSJohnny Huang 	} else {
81866f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
81966f2f8e5SJohnny Huang 		return -1;
820442839bbSJohnny Huang 	}
82169d5fd8fSJohnny Huang 
82266f2f8e5SJohnny Huang 	k++;
82366f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 2;
82466f2f8e5SJohnny Huang 	conf_parse[k].bit = 16;
82566f2f8e5SJohnny Huang 	conf_parse[k].length = 16;
82666f2f8e5SJohnny Huang 	conf_parse[k].value = KEY_REVISION(OTPCFG[2]);
82766f2f8e5SJohnny Huang 	if (KEY_REVISION(OTPCFG_KEEP[2]) == 0xffff) {
82866f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
82966f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
83066f2f8e5SJohnny Huang 	} else if (KEY_REVISION(OTPCFG_KEEP[2]) == 0) {
83166f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
83266f2f8e5SJohnny Huang 			"Key Revision : 0x%x", KEY_REVISION(OTPCFG[2]));
833442839bbSJohnny Huang 	} else {
83466f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
83566f2f8e5SJohnny Huang 		return -1;
83666f2f8e5SJohnny Huang 	}
83766f2f8e5SJohnny Huang 
83866f2f8e5SJohnny Huang 	k++;
83966f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 3;
84066f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
84166f2f8e5SJohnny Huang 	conf_parse[k].length = 16;
84266f2f8e5SJohnny Huang 	conf_parse[k].value = SEC_BOOT_HEADER_OFFSET(OTPCFG[3]);
84366f2f8e5SJohnny Huang 	if (SEC_BOOT_HEADER_OFFSET(OTPCFG_KEEP[3]) == 0xffff) {
84466f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
84566f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
84666f2f8e5SJohnny Huang 	} else if (SEC_BOOT_HEADER_OFFSET(OTPCFG_KEEP[3]) == 0) {
84766f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
84866f2f8e5SJohnny Huang 			"Secure boot header offset : 0x%x",
849e1f9e54eSJohnny Huang 			SEC_BOOT_HEADER_OFFSET(OTPCFG[3]));
85066f2f8e5SJohnny Huang 	} else {
85166f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
85266f2f8e5SJohnny Huang 		return -1;
853442839bbSJohnny Huang 	}
85469d5fd8fSJohnny Huang 
85566f2f8e5SJohnny Huang 	k++;
85666f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 4;
85766f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
85866f2f8e5SJohnny Huang 	conf_parse[k].length = 8;
85966f2f8e5SJohnny Huang 	conf_parse[k].value = KEYS_VALID_BITS(OTPCFG[4]);
86066f2f8e5SJohnny Huang 	if (KEYS_VALID_BITS(OTPCFG_KEEP[4]) == 0xff) {
86166f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
86266f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
86366f2f8e5SJohnny Huang 	} else if (KEYS_VALID_BITS(OTPCFG_KEEP[4]) == 0) {
864e1f9e54eSJohnny Huang 		tmp = KEYS_VALID_BITS(OTPCFG[4]);
865e1f9e54eSJohnny Huang 		if (tmp != 0) {
86669d5fd8fSJohnny Huang 			for (i = 0; i < 7; i++) {
86769d5fd8fSJohnny Huang 				if (tmp == (1 << i)) {
868e1f9e54eSJohnny Huang 					pass = i + 1;
86969d5fd8fSJohnny Huang 				}
87069d5fd8fSJohnny Huang 			}
871e1f9e54eSJohnny Huang 		} else {
872e1f9e54eSJohnny Huang 			pass = 0;
873e1f9e54eSJohnny Huang 		}
87466f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
87566f2f8e5SJohnny Huang 			"Keys valid  : %d", pass);
876442839bbSJohnny Huang 	} else {
87766f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
87866f2f8e5SJohnny Huang 		return -1;
87966f2f8e5SJohnny Huang 	}
88066f2f8e5SJohnny Huang 
88166f2f8e5SJohnny Huang 	k++;
88266f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 4;
88366f2f8e5SJohnny Huang 	conf_parse[k].bit = 16;
88466f2f8e5SJohnny Huang 	conf_parse[k].length = 8;
88566f2f8e5SJohnny Huang 	conf_parse[k].value = KEYS_RETIRE_BITS(OTPCFG[4]);
88666f2f8e5SJohnny Huang 	if (KEYS_RETIRE_BITS(OTPCFG_KEEP[4]) == 0xff) {
88766f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
88866f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
88966f2f8e5SJohnny Huang 	} else if (KEYS_RETIRE_BITS(OTPCFG_KEEP[4]) == 0) {
890e1f9e54eSJohnny Huang 		tmp = KEYS_RETIRE_BITS(OTPCFG[4]);
891e1f9e54eSJohnny Huang 		if (tmp != 0) {
89269d5fd8fSJohnny Huang 			for (i = 0; i < 7; i++) {
89369d5fd8fSJohnny Huang 				if (tmp == (1 << i)) {
894e1f9e54eSJohnny Huang 					pass = i + 1;
89569d5fd8fSJohnny Huang 				}
89669d5fd8fSJohnny Huang 			}
897e1f9e54eSJohnny Huang 		} else {
898e1f9e54eSJohnny Huang 			pass = 0;
89969d5fd8fSJohnny Huang 		}
90066f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
90166f2f8e5SJohnny Huang 			"Keys Retire ID  : %d", pass);
90266f2f8e5SJohnny Huang 	} else {
90366f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
90466f2f8e5SJohnny Huang 		return -1;
905442839bbSJohnny Huang 	}
90666f2f8e5SJohnny Huang 
90766f2f8e5SJohnny Huang 	k++;
90866f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 5;
90966f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
91066f2f8e5SJohnny Huang 	conf_parse[k].length = 32;
91166f2f8e5SJohnny Huang 	conf_parse[k].value = OTPCFG[5];
912442839bbSJohnny Huang 	if (OTPCFG_KEEP[5] == 0xFFFFFFFF) {
91366f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
91466f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
91566f2f8e5SJohnny Huang 	} else if (OTPCFG_KEEP[5] == 0) {
91666f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
91766f2f8e5SJohnny Huang 			"User define data, random number low : 0x%x", OTPCFG[5]);
918442839bbSJohnny Huang 	} else {
91966f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
92066f2f8e5SJohnny Huang 		return -1;
921442839bbSJohnny Huang 	}
92269d5fd8fSJohnny Huang 
92366f2f8e5SJohnny Huang 	k++;
92466f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 6;
92566f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
92666f2f8e5SJohnny Huang 	conf_parse[k].length = 32;
92766f2f8e5SJohnny Huang 	conf_parse[k].value = OTPCFG[6];
928442839bbSJohnny Huang 	if (OTPCFG_KEEP[6] == 0xFFFFFFFF) {
92966f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
93066f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
93166f2f8e5SJohnny Huang 	} else if (OTPCFG_KEEP[6] == 0) {
93266f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
93366f2f8e5SJohnny Huang 			"User define data, random number high : 0x%x", OTPCFG[6]);
934442839bbSJohnny Huang 	} else {
93566f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
93666f2f8e5SJohnny Huang 		return -1;
937442839bbSJohnny Huang 	}
93869d5fd8fSJohnny Huang 
93966f2f8e5SJohnny Huang 	k++;
94066f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 8;
94166f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
94266f2f8e5SJohnny Huang 	conf_parse[k].length = 32;
94366f2f8e5SJohnny Huang 	conf_parse[k].value = OTPCFG[8];
944442839bbSJohnny Huang 	if (OTPCFG_KEEP[8] == 0xFFFFFFFF) {
94566f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
94666f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
94766f2f8e5SJohnny Huang 	} else if (OTPCFG_KEEP[8] == 0) {
94866f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
94966f2f8e5SJohnny Huang 			"Redundancy Repair : 0x%x", OTPCFG[8]);
950442839bbSJohnny Huang 	} else {
95166f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
95266f2f8e5SJohnny Huang 		return -1;
953442839bbSJohnny Huang 	}
95469d5fd8fSJohnny Huang 
95566f2f8e5SJohnny Huang 	k++;
95666f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 10;
95766f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
95866f2f8e5SJohnny Huang 	conf_parse[k].length = 32;
95966f2f8e5SJohnny Huang 	conf_parse[k].value = OTPCFG[10];
960442839bbSJohnny Huang 	if (OTPCFG_KEEP[10] == 0xFFFFFFFF) {
96166f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
96266f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
96366f2f8e5SJohnny Huang 	} else if (OTPCFG_KEEP[10] == 0) {
96466f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
96566f2f8e5SJohnny Huang 			"Manifest ID low : 0x%x", OTPCFG[10]);
966442839bbSJohnny Huang 	} else {
96766f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
96866f2f8e5SJohnny Huang 		return -1;
969442839bbSJohnny Huang 	}
97069d5fd8fSJohnny Huang 
97166f2f8e5SJohnny Huang 	k++;
97266f2f8e5SJohnny Huang 	conf_parse[k].dw_offset = 11;
97366f2f8e5SJohnny Huang 	conf_parse[k].bit = 0;
97466f2f8e5SJohnny Huang 	conf_parse[k].length = 32;
97566f2f8e5SJohnny Huang 	conf_parse[k].value = OTPCFG[11];
976442839bbSJohnny Huang 	if (OTPCFG_KEEP[11] == 0xFFFFFFFF) {
97766f2f8e5SJohnny Huang 		conf_parse[k].keep = 1;
97866f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Skip");
97966f2f8e5SJohnny Huang 	} else if (OTPCFG_KEEP[11] == 0) {
98066f2f8e5SJohnny Huang 		sprintf(conf_parse[k].status,
98166f2f8e5SJohnny Huang 			"Manifest ID high : 0x%x", OTPCFG[11]);
982442839bbSJohnny Huang 	} else {
98366f2f8e5SJohnny Huang 		strcpy(conf_parse[k].status, "Keep mask error!");
98466f2f8e5SJohnny Huang 		return -1;
985442839bbSJohnny Huang 	}
986442839bbSJohnny Huang 
98766f2f8e5SJohnny Huang 	return k + 1;
98869d5fd8fSJohnny Huang 
98969d5fd8fSJohnny Huang }
99069d5fd8fSJohnny Huang 
99176d13988SJohnny Huang static int otp_strap_parse(uint32_t *OTPSTRAP,
99276d13988SJohnny Huang 			   struct otpstrap_parse *strap_parse)
99376d13988SJohnny Huang {
99476d13988SJohnny Huang 	int k = 0;
99576d13988SJohnny Huang 	uint32_t *OTPSTRAP_KEEP = &OTPSTRAP[2];
99676d13988SJohnny Huang 	uint32_t *OTPSTRAP_PRO = &OTPSTRAP[4];
99776d13988SJohnny Huang 
99876d13988SJohnny Huang 	strap_parse[k].bit = 0;
99976d13988SJohnny Huang 	strap_parse[k].length = 1;
100076d13988SJohnny Huang 	strap_parse[k].value = ENABLE_SECURE_BOOT(OTPSTRAP[0]);
100176d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_SECURE_BOOT(OTPSTRAP_PRO[0]);
100276d13988SJohnny Huang 	if (ENABLE_SECURE_BOOT(OTPSTRAP_KEEP[0])) {
100376d13988SJohnny Huang 		strap_parse[k].keep = 1;
100476d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
100576d13988SJohnny Huang 	} else {
100676d13988SJohnny Huang 		if (ENABLE_SECURE_BOOT(OTPSTRAP[0]))
100776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
100876d13988SJohnny Huang 			       "Enable secure boot");
100976d13988SJohnny Huang 		else
101076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
101176d13988SJohnny Huang 			       "Disable secure boot");
101276d13988SJohnny Huang 	}
101376d13988SJohnny Huang 
101476d13988SJohnny Huang 	k++;
101576d13988SJohnny Huang 	strap_parse[k].bit = 1;
101676d13988SJohnny Huang 	strap_parse[k].length = 1;
101776d13988SJohnny Huang 	strap_parse[k].value = BOOT_FROM_EMMC(OTPSTRAP[0]);
101876d13988SJohnny Huang 	strap_parse[k].protect = BOOT_FROM_EMMC(OTPSTRAP_PRO[0]);
101976d13988SJohnny Huang 	if (BOOT_FROM_EMMC(OTPSTRAP_KEEP[0])) {
102076d13988SJohnny Huang 		strap_parse[k].keep = 1;
102176d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
102276d13988SJohnny Huang 	} else {
102376d13988SJohnny Huang 		if (BOOT_FROM_EMMC(OTPSTRAP[0]))
102476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
102576d13988SJohnny Huang 			       "Enable boot from eMMC");
102676d13988SJohnny Huang 		else
102776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
102876d13988SJohnny Huang 			       "Disable boot from eMMC");
102976d13988SJohnny Huang 	}
103076d13988SJohnny Huang 
103176d13988SJohnny Huang 	k++;
103276d13988SJohnny Huang 	strap_parse[k].bit = 2;
103376d13988SJohnny Huang 	strap_parse[k].length = 1;
103476d13988SJohnny Huang 	strap_parse[k].value = BOOT_FROM_DEBUG_SPI(OTPSTRAP[0]);
103576d13988SJohnny Huang 	strap_parse[k].protect = BOOT_FROM_DEBUG_SPI(OTPSTRAP_PRO[0]);
103676d13988SJohnny Huang 	if (BOOT_FROM_DEBUG_SPI(OTPSTRAP_KEEP[0])) {
103776d13988SJohnny Huang 		strap_parse[k].keep = 1;
103876d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
103976d13988SJohnny Huang 	} else {
104076d13988SJohnny Huang 		if (BOOT_FROM_DEBUG_SPI(OTPSTRAP[0]))
104176d13988SJohnny Huang 			strcpy(strap_parse[k].status,
104276d13988SJohnny Huang 			       "Enable Boot from debug SPI");
104376d13988SJohnny Huang 		else
104476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
104576d13988SJohnny Huang 			       "Disable Boot from debug SPI");
104676d13988SJohnny Huang 	}
104776d13988SJohnny Huang 
104876d13988SJohnny Huang 	k++;
104976d13988SJohnny Huang 	strap_parse[k].bit = 3;
105076d13988SJohnny Huang 	strap_parse[k].length = 1;
105176d13988SJohnny Huang 	strap_parse[k].value = DISABLE_ARM_CM3(OTPSTRAP[0]);
105276d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_ARM_CM3(OTPSTRAP_PRO[0]);
105376d13988SJohnny Huang 	if (DISABLE_ARM_CM3(OTPSTRAP_KEEP[0])) {
105476d13988SJohnny Huang 		strap_parse[k].keep = 1;
105576d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
105676d13988SJohnny Huang 	} else {
105776d13988SJohnny Huang 		if (DISABLE_ARM_CM3(OTPSTRAP[0]))
105876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
105976d13988SJohnny Huang 			       "Disable ARM CM3");
106076d13988SJohnny Huang 		else
106176d13988SJohnny Huang 			strcpy(strap_parse[k].status,
106276d13988SJohnny Huang 			       "Enable ARM CM3");
106376d13988SJohnny Huang 	}
106476d13988SJohnny Huang 
106576d13988SJohnny Huang 	k++;
106676d13988SJohnny Huang 	strap_parse[k].bit = 4;
106776d13988SJohnny Huang 	strap_parse[k].length = 1;
106876d13988SJohnny Huang 	strap_parse[k].value = VGA_EXPANSION_ROM(OTPSTRAP[0]);
106976d13988SJohnny Huang 	strap_parse[k].protect = VGA_EXPANSION_ROM(OTPSTRAP_PRO[0]);
107076d13988SJohnny Huang 	if (VGA_EXPANSION_ROM(OTPSTRAP_KEEP[0])) {
107176d13988SJohnny Huang 		strap_parse[k].keep = 1;
107276d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
107376d13988SJohnny Huang 	} else {
107476d13988SJohnny Huang 		if (VGA_EXPANSION_ROM(OTPSTRAP[0]))
107576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
107676d13988SJohnny Huang 			       "Enable dedicated VGA BIOS ROM");
107776d13988SJohnny Huang 		else
107876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
107976d13988SJohnny Huang 			       "No VGA BISO ROM, VGA BIOS is merged in the system BIOS");
108076d13988SJohnny Huang 	}
108176d13988SJohnny Huang 
108276d13988SJohnny Huang 	k++;
108376d13988SJohnny Huang 	strap_parse[k].bit = 5;
108476d13988SJohnny Huang 	strap_parse[k].length = 1;
108576d13988SJohnny Huang 	strap_parse[k].value = MAC1_RMII_MODE(OTPSTRAP[0]);
108676d13988SJohnny Huang 	strap_parse[k].protect = MAC1_RMII_MODE(OTPSTRAP_PRO[0]);
108776d13988SJohnny Huang 	if (MAC1_RMII_MODE(OTPSTRAP_KEEP[0])) {
108876d13988SJohnny Huang 		strap_parse[k].keep = 1;
108976d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
109076d13988SJohnny Huang 	} else {
109176d13988SJohnny Huang 		if (MAC1_RMII_MODE(OTPSTRAP[0]))
109276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
109376d13988SJohnny Huang 			       "MAC 1 : RGMII");
109476d13988SJohnny Huang 		else
109576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
109676d13988SJohnny Huang 			       "MAC 1 : RMII/NCSI");
109776d13988SJohnny Huang 	}
109876d13988SJohnny Huang 
109976d13988SJohnny Huang 	k++;
110076d13988SJohnny Huang 	strap_parse[k].bit = 6;
110176d13988SJohnny Huang 	strap_parse[k].length = 1;
110276d13988SJohnny Huang 	strap_parse[k].value = MAC2_RMII_MODE(OTPSTRAP[0]);
110376d13988SJohnny Huang 	strap_parse[k].protect = MAC2_RMII_MODE(OTPSTRAP_PRO[0]);
110476d13988SJohnny Huang 	if (MAC2_RMII_MODE(OTPSTRAP_KEEP[0])) {
110576d13988SJohnny Huang 		strap_parse[k].keep = 1;
110676d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
110776d13988SJohnny Huang 	} else {
110876d13988SJohnny Huang 		if (MAC2_RMII_MODE(OTPSTRAP[0]))
110976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
111076d13988SJohnny Huang 			       "MAC 2 : RGMII");
111176d13988SJohnny Huang 		else
111276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
111376d13988SJohnny Huang 			       "MAC 2 : RMII/NCSI");
111476d13988SJohnny Huang 	}
111576d13988SJohnny Huang 
111676d13988SJohnny Huang 	k++;
111776d13988SJohnny Huang 	strap_parse[k].bit = 7;
111876d13988SJohnny Huang 	strap_parse[k].length = 3;
111976d13988SJohnny Huang 	strap_parse[k].value = CPU_FREQUENCY(OTPSTRAP[0]);
112076d13988SJohnny Huang 	strap_parse[k].protect = CPU_FREQUENCY(OTPSTRAP_PRO[0]);
112176d13988SJohnny Huang 	if (CPU_FREQUENCY(OTPSTRAP_KEEP[0]) == 0x7) {
112276d13988SJohnny Huang 		strap_parse[k].keep = 1;
112376d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
112476d13988SJohnny Huang 	} else if (CPU_FREQUENCY(OTPSTRAP_KEEP[0]) == 0) {
112576d13988SJohnny Huang 		if (CPU_FREQUENCY(OTPSTRAP[0]) == 0) {
112676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
112776d13988SJohnny Huang 			       "CPU Frequency : 1GHz");
112876d13988SJohnny Huang 		} else if (CPU_FREQUENCY(OTPSTRAP[0]) == 1) {
112976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
113076d13988SJohnny Huang 			       "CPU Frequency : 800MHz");
113176d13988SJohnny Huang 		} else if (CPU_FREQUENCY(OTPSTRAP[0]) == 2) {
113276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
113376d13988SJohnny Huang 			       "CPU Frequency : 1.2GHz");
113476d13988SJohnny Huang 		} else if (CPU_FREQUENCY(OTPSTRAP[0]) == 3) {
113576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
113676d13988SJohnny Huang 			       "CPU Frequency : 1.4GHz");
113776d13988SJohnny Huang 		} else {
113876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
113976d13988SJohnny Huang 			       "CPU Frequency : error");
114076d13988SJohnny Huang 			return -1;
114176d13988SJohnny Huang 		}
114276d13988SJohnny Huang 	} else {
114376d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
114476d13988SJohnny Huang 		return -1;
114576d13988SJohnny Huang 	}
114676d13988SJohnny Huang 
114776d13988SJohnny Huang 	k++;
114876d13988SJohnny Huang 	strap_parse[k].bit = 10;
114976d13988SJohnny Huang 	strap_parse[k].length = 2;
115076d13988SJohnny Huang 	strap_parse[k].value = HCLK_RATIO(OTPSTRAP[0]);
115176d13988SJohnny Huang 	strap_parse[k].protect = HCLK_RATIO(OTPSTRAP_PRO[0]);
115276d13988SJohnny Huang 	if (HCLK_RATIO(OTPSTRAP_KEEP[0]) == 0x3) {
115376d13988SJohnny Huang 		strap_parse[k].keep = 1;
115476d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
115576d13988SJohnny Huang 	} else if (HCLK_RATIO(OTPSTRAP_KEEP[0]) == 0) {
115676d13988SJohnny Huang 		if (HCLK_RATIO(OTPSTRAP[0]) == 0) {
115776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
115876d13988SJohnny Huang 			       "HCLK ratio AXI:AHB = 2:1");
115976d13988SJohnny Huang 		} else if (HCLK_RATIO(OTPSTRAP[0]) == 1) {
116076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
116176d13988SJohnny Huang 			       "HCLK ratio AXI:AHB = 2:1");
116276d13988SJohnny Huang 		} else if (HCLK_RATIO(OTPSTRAP[0]) == 2) {
116376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
116476d13988SJohnny Huang 			       "HCLK ratio AXI:AHB = 3:1");
116576d13988SJohnny Huang 		} else if (HCLK_RATIO(OTPSTRAP[0]) == 3) {
116676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
116776d13988SJohnny Huang 			       "HCLK ratio AXI:AHB = 4:1");
116876d13988SJohnny Huang 		}
116976d13988SJohnny Huang 	} else {
117076d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
117176d13988SJohnny Huang 		return -1;
117276d13988SJohnny Huang 	}
117376d13988SJohnny Huang 
117476d13988SJohnny Huang 	k++;
117576d13988SJohnny Huang 	strap_parse[k].bit = 12;
117676d13988SJohnny Huang 	strap_parse[k].length = 2;
117776d13988SJohnny Huang 	strap_parse[k].value = VGA_MEMORY_SIZE(OTPSTRAP[0]);
117876d13988SJohnny Huang 	strap_parse[k].protect = VGA_MEMORY_SIZE(OTPSTRAP_PRO[0]);
117976d13988SJohnny Huang 	if (VGA_MEMORY_SIZE(OTPSTRAP_KEEP[0]) == 0x3) {
118076d13988SJohnny Huang 		strap_parse[k].keep = 1;
118176d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
118276d13988SJohnny Huang 	} else if (VGA_MEMORY_SIZE(OTPSTRAP_KEEP[0]) == 0) {
118376d13988SJohnny Huang 		if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 0) {
118476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
118576d13988SJohnny Huang 			       "VGA memory size : 8MB");
118676d13988SJohnny Huang 		} else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 1) {
118776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
118876d13988SJohnny Huang 			       "VGA memory size : 16MB");
118976d13988SJohnny Huang 		} else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 2) {
119076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
119176d13988SJohnny Huang 			       "VGA memory size : 32MB");
119276d13988SJohnny Huang 		} else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 3) {
119376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
119476d13988SJohnny Huang 			       "VGA memory size : 64MB");
119576d13988SJohnny Huang 		}
119676d13988SJohnny Huang 	} else {
119776d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
119876d13988SJohnny Huang 		return -1;
119976d13988SJohnny Huang 	}
120076d13988SJohnny Huang 
120176d13988SJohnny Huang 	k++;
120276d13988SJohnny Huang 	strap_parse[k].bit = 17;
120376d13988SJohnny Huang 	strap_parse[k].length = 1;
120476d13988SJohnny Huang 	strap_parse[k].value = VGA_CLASS_CODE(OTPSTRAP[0]);
120576d13988SJohnny Huang 	strap_parse[k].protect = VGA_CLASS_CODE(OTPSTRAP_PRO[0]);
120676d13988SJohnny Huang 	if (VGA_CLASS_CODE(OTPSTRAP_KEEP[0])) {
120776d13988SJohnny Huang 		strap_parse[k].keep = 1;
120876d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
120976d13988SJohnny Huang 	} else {
121076d13988SJohnny Huang 		if (VGA_CLASS_CODE(OTPSTRAP[0]))
121176d13988SJohnny Huang 			strcpy(strap_parse[k].status,
121276d13988SJohnny Huang 			       "VGA class code : Class Code for VGA device");
121376d13988SJohnny Huang 		else
121476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
121576d13988SJohnny Huang 			       "VGA class code : Class Code for video device");
121676d13988SJohnny Huang 	}
121776d13988SJohnny Huang 
121876d13988SJohnny Huang 	k++;
121976d13988SJohnny Huang 	strap_parse[k].bit = 18;
122076d13988SJohnny Huang 	strap_parse[k].length = 1;
122176d13988SJohnny Huang 	strap_parse[k].value = DISABLE_DEBUG0(OTPSTRAP[0]);
122276d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_DEBUG0(OTPSTRAP_PRO[0]);
122376d13988SJohnny Huang 	if (DISABLE_DEBUG0(OTPSTRAP_KEEP[0])) {
122476d13988SJohnny Huang 		strap_parse[k].keep = 1;
122576d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
122676d13988SJohnny Huang 	} else {
122776d13988SJohnny Huang 		if (DISABLE_DEBUG0(OTPSTRAP[0]))
122876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
122976d13988SJohnny Huang 			       "Disable debug interfaces 0");
123076d13988SJohnny Huang 		else
123176d13988SJohnny Huang 			strcpy(strap_parse[k].status,
123276d13988SJohnny Huang 			       "Enable debug interfaces 0");
123376d13988SJohnny Huang 	}
123476d13988SJohnny Huang 
123576d13988SJohnny Huang 	k++;
123676d13988SJohnny Huang 	strap_parse[k].bit = 19;
123776d13988SJohnny Huang 	strap_parse[k].length = 1;
123876d13988SJohnny Huang 	strap_parse[k].value = BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP[0]);
123976d13988SJohnny Huang 	strap_parse[k].protect = BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP_PRO[0]);
124076d13988SJohnny Huang 	if (BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP_KEEP[0])) {
124176d13988SJohnny Huang 		strap_parse[k].keep = 1;
124276d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
124376d13988SJohnny Huang 	} else {
124476d13988SJohnny Huang 		if (BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP[0]))
124576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
124676d13988SJohnny Huang 			       "Boot from emmc mode : Normal eMMC speed");
124776d13988SJohnny Huang 		else
124876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
124976d13988SJohnny Huang 			       "Boot from emmc mode : High eMMC speed");
125076d13988SJohnny Huang 	}
125176d13988SJohnny Huang 
125276d13988SJohnny Huang 	k++;
125376d13988SJohnny Huang 	strap_parse[k].bit = 20;
125476d13988SJohnny Huang 	strap_parse[k].length = 1;
125576d13988SJohnny Huang 	strap_parse[k].value = DISABLE_PCIE_EHCI(OTPSTRAP[0]);
125676d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_PCIE_EHCI(OTPSTRAP_PRO[0]);
125776d13988SJohnny Huang 	if (DISABLE_PCIE_EHCI(OTPSTRAP_KEEP[0])) {
125876d13988SJohnny Huang 		strap_parse[k].keep = 1;
125976d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
126076d13988SJohnny Huang 	} else {
126176d13988SJohnny Huang 		if (DISABLE_PCIE_EHCI(OTPSTRAP[0]))
126276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
126376d13988SJohnny Huang 			       "Disable Pcie EHCI device");
126476d13988SJohnny Huang 		else
126576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
126676d13988SJohnny Huang 			       "Enable Pcie EHCI device");
126776d13988SJohnny Huang 	}
126876d13988SJohnny Huang 
126976d13988SJohnny Huang 	k++;
127076d13988SJohnny Huang 	strap_parse[k].bit = 21;
127176d13988SJohnny Huang 	strap_parse[k].length = 1;
127276d13988SJohnny Huang 	strap_parse[k].value = DISABLE_VGA_XDMA(OTPSTRAP[0]);
127376d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_VGA_XDMA(OTPSTRAP_PRO[0]);
127476d13988SJohnny Huang 	if (DISABLE_VGA_XDMA(OTPSTRAP_KEEP[0])) {
127576d13988SJohnny Huang 		strap_parse[k].keep = 1;
127676d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
127776d13988SJohnny Huang 	} else {
127876d13988SJohnny Huang 		if (DISABLE_VGA_XDMA(OTPSTRAP[0]))
127976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
128076d13988SJohnny Huang 			       "Disable VGA XDMA function");
128176d13988SJohnny Huang 		else
128276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
128376d13988SJohnny Huang 			       "Enable VGA XDMA function");
128476d13988SJohnny Huang 	}
128576d13988SJohnny Huang 
128676d13988SJohnny Huang 	k++;
128776d13988SJohnny Huang 	strap_parse[k].bit = 22;
128876d13988SJohnny Huang 	strap_parse[k].length = 1;
128976d13988SJohnny Huang 	strap_parse[k].value = DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP[0]);
129076d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP_PRO[0]);
129176d13988SJohnny Huang 	if (DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP_KEEP[0])) {
129276d13988SJohnny Huang 		strap_parse[k].keep = 1;
129376d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
129476d13988SJohnny Huang 	} else {
129576d13988SJohnny Huang 		if (DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP[0]))
129676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
129776d13988SJohnny Huang 			       "Disable dedicated BMC functions for non-BMC application");
129876d13988SJohnny Huang 		else
129976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
130076d13988SJohnny Huang 			       "Normal BMC mode");
130176d13988SJohnny Huang 	}
130276d13988SJohnny Huang 
130376d13988SJohnny Huang 	k++;
130476d13988SJohnny Huang 	strap_parse[k].bit = 23;
130576d13988SJohnny Huang 	strap_parse[k].length = 1;
130676d13988SJohnny Huang 	strap_parse[k].value = DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP[0]);
130776d13988SJohnny Huang 	strap_parse[k].protect = DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP_PRO[0]);
130876d13988SJohnny Huang 	if (DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP_KEEP[0])) {
130976d13988SJohnny Huang 		strap_parse[k].keep = 1;
131076d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
131176d13988SJohnny Huang 	} else {
131276d13988SJohnny Huang 		if (DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP[0]))
131376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
131476d13988SJohnny Huang 			       "SSPRST# pin is for PCIE root complex dedicated reset pin");
131576d13988SJohnny Huang 		else
131676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
131776d13988SJohnny Huang 			       "SSPRST# pin is for secondary processor dedicated reset pin");
131876d13988SJohnny Huang 	}
131976d13988SJohnny Huang 
132076d13988SJohnny Huang 	k++;
132176d13988SJohnny Huang 	strap_parse[k].bit = 24;
132276d13988SJohnny Huang 	strap_parse[k].length = 1;
132376d13988SJohnny Huang 	strap_parse[k].value = SELECT_DRAM_TYPES(OTPSTRAP[0]);
132476d13988SJohnny Huang 	strap_parse[k].protect = SELECT_DRAM_TYPES(OTPSTRAP_PRO[0]);
132576d13988SJohnny Huang 	if (SELECT_DRAM_TYPES(OTPSTRAP_KEEP[0])) {
132676d13988SJohnny Huang 		strap_parse[k].keep = 1;
132776d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
132876d13988SJohnny Huang 	} else {
132976d13988SJohnny Huang 		if (SELECT_DRAM_TYPES(OTPSTRAP[0]))
133076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
133176d13988SJohnny Huang 			       "DRAM types : DDR4");
133276d13988SJohnny Huang 		else
133376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
133476d13988SJohnny Huang 			       "DRAM types : DDR3");
133576d13988SJohnny Huang 	}
133676d13988SJohnny Huang 
133776d13988SJohnny Huang 	k++;
133876d13988SJohnny Huang 	strap_parse[k].bit = 32;
133976d13988SJohnny Huang 	strap_parse[k].length = 1;
134076d13988SJohnny Huang 	strap_parse[k].value = MAC3_RMII_MODE(OTPSTRAP[1]);
134176d13988SJohnny Huang 	strap_parse[k].protect = MAC3_RMII_MODE(OTPSTRAP_PRO[1]);
134276d13988SJohnny Huang 	if (MAC3_RMII_MODE(OTPSTRAP_KEEP[1])) {
134376d13988SJohnny Huang 		strap_parse[k].keep = 1;
134476d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
134576d13988SJohnny Huang 	} else {
134676d13988SJohnny Huang 		if (MAC3_RMII_MODE(OTPSTRAP[1]))
134776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
134876d13988SJohnny Huang 			       "MAC 3 : RGMII");
134976d13988SJohnny Huang 		else
135076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
135176d13988SJohnny Huang 			       "MAC 3 : RMII/NCSI");
135276d13988SJohnny Huang 	}
135376d13988SJohnny Huang 
135476d13988SJohnny Huang 	k++;
135576d13988SJohnny Huang 	strap_parse[k].bit = 33;
135676d13988SJohnny Huang 	strap_parse[k].length = 1;
135776d13988SJohnny Huang 	strap_parse[k].value = MAC4_RMII_MODE(OTPSTRAP[1]);
135876d13988SJohnny Huang 	strap_parse[k].protect = MAC4_RMII_MODE(OTPSTRAP_PRO[1]);
135976d13988SJohnny Huang 	if (MAC4_RMII_MODE(OTPSTRAP_KEEP[1])) {
136076d13988SJohnny Huang 		strap_parse[k].keep = 1;
136176d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
136276d13988SJohnny Huang 	} else {
136376d13988SJohnny Huang 		if (MAC4_RMII_MODE(OTPSTRAP[1]))
136476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
136576d13988SJohnny Huang 			       "MAC 4 : RGMII");
136676d13988SJohnny Huang 		else
136776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
136876d13988SJohnny Huang 			       "MAC 4 : RMII/NCSI");
136976d13988SJohnny Huang 	}
137076d13988SJohnny Huang 
137176d13988SJohnny Huang 	k++;
137276d13988SJohnny Huang 	strap_parse[k].bit = 34;
137376d13988SJohnny Huang 	strap_parse[k].length = 1;
137476d13988SJohnny Huang 	strap_parse[k].value = SIO_CONF_ADDR(OTPSTRAP[1]);
137576d13988SJohnny Huang 	strap_parse[k].protect = SIO_CONF_ADDR(OTPSTRAP_PRO[1]);
137676d13988SJohnny Huang 	if (SIO_CONF_ADDR(OTPSTRAP_KEEP[1])) {
137776d13988SJohnny Huang 		strap_parse[k].keep = 1;
137876d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
137976d13988SJohnny Huang 	} else {
138076d13988SJohnny Huang 		if (SIO_CONF_ADDR(OTPSTRAP[1]))
138176d13988SJohnny Huang 			strcpy(strap_parse[k].status,
138276d13988SJohnny Huang 			       "SuperIO configuration address : 0x4E");
138376d13988SJohnny Huang 		else
138476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
138576d13988SJohnny Huang 			       "SuperIO configuration address : 0x2E");
138676d13988SJohnny Huang 	}
138776d13988SJohnny Huang 
138876d13988SJohnny Huang 	k++;
138976d13988SJohnny Huang 	strap_parse[k].bit = 35;
139076d13988SJohnny Huang 	strap_parse[k].length = 1;
139176d13988SJohnny Huang 	strap_parse[k].value = DISABLE_SIO(OTPSTRAP[1]);
139276d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_SIO(OTPSTRAP_PRO[1]);
139376d13988SJohnny Huang 	if (DISABLE_SIO(OTPSTRAP_KEEP[1])) {
139476d13988SJohnny Huang 		strap_parse[k].keep = 1;
139576d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
139676d13988SJohnny Huang 	} else {
139776d13988SJohnny Huang 		if (DISABLE_SIO(OTPSTRAP[1]))
139876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
139976d13988SJohnny Huang 			       "Disable LPC to decode SuperIO");
140076d13988SJohnny Huang 		else
140176d13988SJohnny Huang 			strcpy(strap_parse[k].status,
140276d13988SJohnny Huang 			       "Enable LPC to decode SuperIO");
140376d13988SJohnny Huang 	}
140476d13988SJohnny Huang 
140576d13988SJohnny Huang 	k++;
140676d13988SJohnny Huang 	strap_parse[k].bit = 36;
140776d13988SJohnny Huang 	strap_parse[k].length = 1;
140876d13988SJohnny Huang 	strap_parse[k].value = DISABLE_DEBUG1(OTPSTRAP[1]);
140976d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_DEBUG1(OTPSTRAP_PRO[1]);
141076d13988SJohnny Huang 	if (DISABLE_DEBUG1(OTPSTRAP_KEEP[1])) {
141176d13988SJohnny Huang 		strap_parse[k].keep = 1;
141276d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
141376d13988SJohnny Huang 	} else {
141476d13988SJohnny Huang 		if (DISABLE_DEBUG1(OTPSTRAP[1]))
141576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
141676d13988SJohnny Huang 			       "Disable debug interfaces 1");
141776d13988SJohnny Huang 		else
141876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
141976d13988SJohnny Huang 			       "Enable debug interfaces 1");
142076d13988SJohnny Huang 	}
142176d13988SJohnny Huang 
142276d13988SJohnny Huang 	k++;
142376d13988SJohnny Huang 	strap_parse[k].bit = 37;
142476d13988SJohnny Huang 	strap_parse[k].length = 1;
142576d13988SJohnny Huang 	strap_parse[k].value = ENABLE_ACPI(OTPSTRAP[1]);
142676d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_ACPI(OTPSTRAP_PRO[1]);
142776d13988SJohnny Huang 	if (ENABLE_ACPI(OTPSTRAP_KEEP[1])) {
142876d13988SJohnny Huang 		strap_parse[k].keep = 1;
142976d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
143076d13988SJohnny Huang 	} else {
143176d13988SJohnny Huang 		if (ENABLE_ACPI(OTPSTRAP[1]))
143276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
143376d13988SJohnny Huang 			       "Enable ACPI function");
143476d13988SJohnny Huang 		else
143576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
143676d13988SJohnny Huang 			       "Disable ACPI function");
143776d13988SJohnny Huang 	}
143876d13988SJohnny Huang 
143976d13988SJohnny Huang 	k++;
144076d13988SJohnny Huang 	strap_parse[k].bit = 38;
144176d13988SJohnny Huang 	strap_parse[k].length = 1;
144276d13988SJohnny Huang 	strap_parse[k].value = SELECT_LPC(OTPSTRAP[1]);
144376d13988SJohnny Huang 	strap_parse[k].protect = SELECT_LPC(OTPSTRAP_PRO[1]);
144476d13988SJohnny Huang 	if (SELECT_LPC(OTPSTRAP_KEEP[1])) {
144576d13988SJohnny Huang 		strap_parse[k].keep = 1;
144676d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
144776d13988SJohnny Huang 	} else {
144876d13988SJohnny Huang 		if (SELECT_LPC(OTPSTRAP[1]))
144976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
145076d13988SJohnny Huang 			       "Enable LPC mode");
145176d13988SJohnny Huang 		else
145276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
145376d13988SJohnny Huang 			       "Enable eSPI mode");
145476d13988SJohnny Huang 	}
145576d13988SJohnny Huang 
145676d13988SJohnny Huang 	k++;
145776d13988SJohnny Huang 	strap_parse[k].bit = 39;
145876d13988SJohnny Huang 	strap_parse[k].length = 1;
145976d13988SJohnny Huang 	strap_parse[k].value = ENABLE_SAFS(OTPSTRAP[1]);
146076d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_SAFS(OTPSTRAP_PRO[1]);
146176d13988SJohnny Huang 	if (ENABLE_SAFS(OTPSTRAP_KEEP[1])) {
146276d13988SJohnny Huang 		strap_parse[k].keep = 1;
146376d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
146476d13988SJohnny Huang 	} else {
146576d13988SJohnny Huang 		if (ENABLE_SAFS(OTPSTRAP[1]))
146676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
146776d13988SJohnny Huang 			       "Enable SAFS mode");
146876d13988SJohnny Huang 		else
146976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
147076d13988SJohnny Huang 			       "Enable SAFS mode");
147176d13988SJohnny Huang 	}
147276d13988SJohnny Huang 
147376d13988SJohnny Huang 	k++;
147476d13988SJohnny Huang 	strap_parse[k].bit = 42;
147576d13988SJohnny Huang 	strap_parse[k].length = 1;
147676d13988SJohnny Huang 	strap_parse[k].value = ENABLE_SPI_3B4B_AUTO(OTPSTRAP[1]);
147776d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_SPI_3B4B_AUTO(OTPSTRAP_PRO[1]);
147876d13988SJohnny Huang 	if (ENABLE_SPI_3B4B_AUTO(OTPSTRAP_KEEP[1])) {
147976d13988SJohnny Huang 		strap_parse[k].keep = 1;
148076d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
148176d13988SJohnny Huang 	} else {
148276d13988SJohnny Huang 		if (ENABLE_SPI_3B4B_AUTO(OTPSTRAP[1]))
148376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
148476d13988SJohnny Huang 			       "Enable boot SPI 3B/4B address mode auto detection");
148576d13988SJohnny Huang 		else
148676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
148776d13988SJohnny Huang 			       "Disable boot SPI 3B/4B address mode auto detection");
148876d13988SJohnny Huang 	}
148976d13988SJohnny Huang 
149076d13988SJohnny Huang 	k++;
149176d13988SJohnny Huang 	strap_parse[k].bit = 43;
149276d13988SJohnny Huang 	strap_parse[k].length = 1;
149376d13988SJohnny Huang 	strap_parse[k].value = ENABLE_BOOT_SPI_ABR(OTPSTRAP[1]);
149476d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_BOOT_SPI_ABR(OTPSTRAP_PRO[1]);
149576d13988SJohnny Huang 	if (ENABLE_BOOT_SPI_ABR(OTPSTRAP_KEEP[1])) {
149676d13988SJohnny Huang 		strap_parse[k].keep = 1;
149776d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
149876d13988SJohnny Huang 	} else {
149976d13988SJohnny Huang 		if (ENABLE_BOOT_SPI_ABR(OTPSTRAP[1]))
150076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
150176d13988SJohnny Huang 			       "Enable boot SPI ABR");
150276d13988SJohnny Huang 		else
150376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
150476d13988SJohnny Huang 			       "Disable boot SPI ABR");
150576d13988SJohnny Huang 	}
150676d13988SJohnny Huang 
150776d13988SJohnny Huang 	k++;
150876d13988SJohnny Huang 	strap_parse[k].bit = 44;
150976d13988SJohnny Huang 	strap_parse[k].length = 1;
151076d13988SJohnny Huang 	strap_parse[k].value = BOOT_SPI_ABR_MODE(OTPSTRAP[1]);
151176d13988SJohnny Huang 	strap_parse[k].protect = BOOT_SPI_ABR_MODE(OTPSTRAP_PRO[1]);
151276d13988SJohnny Huang 	if (BOOT_SPI_ABR_MODE(OTPSTRAP_KEEP[1])) {
151376d13988SJohnny Huang 		strap_parse[k].keep = 1;
151476d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
151576d13988SJohnny Huang 	} else {
151676d13988SJohnny Huang 		if (BOOT_SPI_ABR_MODE(OTPSTRAP[1]))
151776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
151876d13988SJohnny Huang 			       "Boot SPI ABR mode : single SPI flash");
151976d13988SJohnny Huang 		else
152076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
152176d13988SJohnny Huang 			       "Boot SPI ABR mode : dual SPI flash");
152276d13988SJohnny Huang 	}
152376d13988SJohnny Huang 
152476d13988SJohnny Huang 	k++;
152576d13988SJohnny Huang 	strap_parse[k].bit = 45;
152676d13988SJohnny Huang 	strap_parse[k].length = 3;
152776d13988SJohnny Huang 	strap_parse[k].value = BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]);
152876d13988SJohnny Huang 	strap_parse[k].protect = BOOT_SPI_FLASH_SIZE(OTPSTRAP_PRO[1]);
152976d13988SJohnny Huang 	if (BOOT_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0x7) {
153076d13988SJohnny Huang 		strap_parse[k].keep = 1;
153176d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
153276d13988SJohnny Huang 	} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0) {
153376d13988SJohnny Huang 		if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 0) {
153476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
153576d13988SJohnny Huang 			       "Boot SPI flash size : no define size");
153676d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 1) {
153776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
153876d13988SJohnny Huang 			       "Boot SPI flash size : 2MB");
153976d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 2) {
154076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
154176d13988SJohnny Huang 			       "Boot SPI flash size : 4MB");
154276d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 3) {
154376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
154476d13988SJohnny Huang 			       "Boot SPI flash size : 8MB");
154576d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 4) {
154676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
154776d13988SJohnny Huang 			       "Boot SPI flash size : 16MB");
154876d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 5) {
154976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
155076d13988SJohnny Huang 			       "Boot SPI flash size : 32MB");
155176d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 6) {
155276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
155376d13988SJohnny Huang 			       "Boot SPI flash size : 64MB");
155476d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 7) {
155576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
155676d13988SJohnny Huang 			       "Boot SPI flash size : 128MB");
155776d13988SJohnny Huang 		}
155876d13988SJohnny Huang 	} else {
155976d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
156076d13988SJohnny Huang 		return -1;
156176d13988SJohnny Huang 	}
156276d13988SJohnny Huang 
156376d13988SJohnny Huang 	k++;
156476d13988SJohnny Huang 	strap_parse[k].bit = 48;
156576d13988SJohnny Huang 	strap_parse[k].length = 1;
156676d13988SJohnny Huang 	strap_parse[k].value = ENABLE_HOST_SPI_ABR(OTPSTRAP[1]);
156776d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_HOST_SPI_ABR(OTPSTRAP_PRO[1]);
156876d13988SJohnny Huang 	if (ENABLE_HOST_SPI_ABR(OTPSTRAP_KEEP[1])) {
156976d13988SJohnny Huang 		strap_parse[k].keep = 1;
157076d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
157176d13988SJohnny Huang 	} else {
157276d13988SJohnny Huang 		if (ENABLE_HOST_SPI_ABR(OTPSTRAP[1]))
157376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
157476d13988SJohnny Huang 			       "Enable host SPI ABR");
157576d13988SJohnny Huang 		else
157676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
157776d13988SJohnny Huang 			       "Disable host SPI ABR");
157876d13988SJohnny Huang 	}
157976d13988SJohnny Huang 
158076d13988SJohnny Huang 	k++;
158176d13988SJohnny Huang 	strap_parse[k].bit = 49;
158276d13988SJohnny Huang 	strap_parse[k].length = 1;
158376d13988SJohnny Huang 	strap_parse[k].value = EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP[1]);
158476d13988SJohnny Huang 	strap_parse[k].protect = EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP_PRO[1]);
158576d13988SJohnny Huang 	if (EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP_KEEP[1])) {
158676d13988SJohnny Huang 		strap_parse[k].keep = 1;
158776d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
158876d13988SJohnny Huang 	} else {
158976d13988SJohnny Huang 		if (EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP[1]))
159076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
159176d13988SJohnny Huang 			       "Enable host SPI ABR mode select pin");
159276d13988SJohnny Huang 		else
159376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
159476d13988SJohnny Huang 			       "Disable host SPI ABR mode select pin");
159576d13988SJohnny Huang 	}
159676d13988SJohnny Huang 
159776d13988SJohnny Huang 	k++;
159876d13988SJohnny Huang 	strap_parse[k].bit = 50;
159976d13988SJohnny Huang 	strap_parse[k].length = 1;
160076d13988SJohnny Huang 	strap_parse[k].value = HOST_SPI_ABR_MODE(OTPSTRAP[1]);
160176d13988SJohnny Huang 	strap_parse[k].protect = HOST_SPI_ABR_MODE(OTPSTRAP_PRO[1]);
160276d13988SJohnny Huang 	if (HOST_SPI_ABR_MODE(OTPSTRAP_KEEP[1])) {
160376d13988SJohnny Huang 		strap_parse[k].keep = 1;
160476d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
160576d13988SJohnny Huang 	} else {
160676d13988SJohnny Huang 		if (HOST_SPI_ABR_MODE(OTPSTRAP[1]))
160776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
160876d13988SJohnny Huang 			       "Host SPI ABR mode : single SPI flash");
160976d13988SJohnny Huang 		else
161076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
161176d13988SJohnny Huang 			       "Host SPI ABR mode : dual SPI flash");
161276d13988SJohnny Huang 	}
161376d13988SJohnny Huang 
161476d13988SJohnny Huang 	k++;
161576d13988SJohnny Huang 	strap_parse[k].bit = 51;
161676d13988SJohnny Huang 	strap_parse[k].length = 3;
161776d13988SJohnny Huang 	strap_parse[k].value = HOST_SPI_FLASH_SIZE(OTPSTRAP[1]);
161876d13988SJohnny Huang 	strap_parse[k].protect = HOST_SPI_FLASH_SIZE(OTPSTRAP_PRO[1]);
161976d13988SJohnny Huang 	if (HOST_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0x7) {
162076d13988SJohnny Huang 		strap_parse[k].keep = 1;
162176d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
162276d13988SJohnny Huang 	} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0) {
162376d13988SJohnny Huang 		if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 0) {
162476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
162576d13988SJohnny Huang 			       "Host SPI flash size : no define size");
162676d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 1) {
162776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
162876d13988SJohnny Huang 			       "Host SPI flash size : 2MB");
162976d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 2) {
163076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
163176d13988SJohnny Huang 			       "Host SPI flash size : 4MB");
163276d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 3) {
163376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
163476d13988SJohnny Huang 			       "Host SPI flash size : 8MB");
163576d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 4) {
163676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
163776d13988SJohnny Huang 			       "Host SPI flash size : 16MB");
163876d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 5) {
163976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
164076d13988SJohnny Huang 			       "Host SPI flash size : 32MB");
164176d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 6) {
164276d13988SJohnny Huang 			strcpy(strap_parse[k].status,
164376d13988SJohnny Huang 			       "Host SPI flash size : 64MB");
164476d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 7) {
164576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
164676d13988SJohnny Huang 			       "Host SPI flash size : 128MB");
164776d13988SJohnny Huang 		}
164876d13988SJohnny Huang 	} else {
164976d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
165076d13988SJohnny Huang 		return -1;
165176d13988SJohnny Huang 	}
165276d13988SJohnny Huang 
165376d13988SJohnny Huang 	k++;
165476d13988SJohnny Huang 	strap_parse[k].bit = 54;
165576d13988SJohnny Huang 	strap_parse[k].length = 1;
165676d13988SJohnny Huang 	strap_parse[k].value = ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]);
165776d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP_PRO[1]);
165876d13988SJohnny Huang 	if (ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP_KEEP[1])) {
165976d13988SJohnny Huang 		strap_parse[k].keep = 1;
166076d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
166176d13988SJohnny Huang 	} else {
166276d13988SJohnny Huang 		if (ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]))
166376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
166476d13988SJohnny Huang 			       "Enable boot SPI auxiliary control pins");
166576d13988SJohnny Huang 		else
166676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
166776d13988SJohnny Huang 			       "Disable boot SPI auxiliary control pins");
166876d13988SJohnny Huang 	}
166976d13988SJohnny Huang 
167076d13988SJohnny Huang 	k++;
167176d13988SJohnny Huang 	strap_parse[k].bit = 55;
167276d13988SJohnny Huang 	strap_parse[k].length = 2;
167376d13988SJohnny Huang 	strap_parse[k].value = BOOT_SPI_CRTM_SIZE(OTPSTRAP[1]);
167476d13988SJohnny Huang 	strap_parse[k].protect = BOOT_SPI_CRTM_SIZE(OTPSTRAP_PRO[1]);
167576d13988SJohnny Huang 	if (BOOT_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0x3) {
167676d13988SJohnny Huang 		strap_parse[k].keep = 1;
167776d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
167876d13988SJohnny Huang 	} else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0) {
167976d13988SJohnny Huang 		if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 0) {
168076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
168176d13988SJohnny Huang 			       "Boot SPI CRTM size : disable CRTM");
168276d13988SJohnny Huang 		} else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 1) {
168376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
168476d13988SJohnny Huang 			       "Boot SPI CRTM size : 256KB");
168576d13988SJohnny Huang 		} else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 2) {
168676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
168776d13988SJohnny Huang 			       "Boot SPI CRTM size : 512KB");
168876d13988SJohnny Huang 		} else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 3) {
168976d13988SJohnny Huang 			strcpy(strap_parse[k].status,
169076d13988SJohnny Huang 			       "Boot SPI CRTM size : 1MB");
169176d13988SJohnny Huang 		}
169276d13988SJohnny Huang 	} else {
169376d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
169476d13988SJohnny Huang 		return -1;
169576d13988SJohnny Huang 	}
169676d13988SJohnny Huang 
169776d13988SJohnny Huang 	k++;
169876d13988SJohnny Huang 	strap_parse[k].bit = 57;
169976d13988SJohnny Huang 	strap_parse[k].length = 2;
170076d13988SJohnny Huang 	strap_parse[k].value = HOST_SPI_CRTM_SIZE(OTPSTRAP[1]);
170176d13988SJohnny Huang 	strap_parse[k].protect = HOST_SPI_CRTM_SIZE(OTPSTRAP_PRO[1]);
170276d13988SJohnny Huang 	if (HOST_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0x3) {
170376d13988SJohnny Huang 		strap_parse[k].keep = 1;
170476d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
170576d13988SJohnny Huang 	} else if (HOST_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0) {
170676d13988SJohnny Huang 		if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 0) {
170776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
170876d13988SJohnny Huang 			       "Host SPI CRTM size : disable CRTM");
170976d13988SJohnny Huang 		} else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 1) {
171076d13988SJohnny Huang 			strcpy(strap_parse[k].status,
171176d13988SJohnny Huang 			       "Host SPI CRTM size : 256KB");
171276d13988SJohnny Huang 		} else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 2) {
171376d13988SJohnny Huang 			strcpy(strap_parse[k].status,
171476d13988SJohnny Huang 			       "Host SPI CRTM size : 512KB");
171576d13988SJohnny Huang 		} else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 3) {
171676d13988SJohnny Huang 			strcpy(strap_parse[k].status,
171776d13988SJohnny Huang 			       "Host SPI CRTM size : 1MB");
171876d13988SJohnny Huang 		}
171976d13988SJohnny Huang 	} else {
172076d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
172176d13988SJohnny Huang 		return -1;
172276d13988SJohnny Huang 	}
172376d13988SJohnny Huang 
172476d13988SJohnny Huang 	k++;
172576d13988SJohnny Huang 	strap_parse[k].bit = 59;
172676d13988SJohnny Huang 	strap_parse[k].length = 1;
172776d13988SJohnny Huang 	strap_parse[k].value = ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]);
172876d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP_PRO[1]);
172976d13988SJohnny Huang 	if (ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP_KEEP[1])) {
173076d13988SJohnny Huang 		strap_parse[k].keep = 1;
173176d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
173276d13988SJohnny Huang 	} else {
173376d13988SJohnny Huang 		if (ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]))
173476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
173576d13988SJohnny Huang 			       "Enable host SPI auxiliary control pins");
173676d13988SJohnny Huang 		else
173776d13988SJohnny Huang 			strcpy(strap_parse[k].status,
173876d13988SJohnny Huang 			       "Disable host SPI auxiliary control pins");
173976d13988SJohnny Huang 	}
174076d13988SJohnny Huang 
174176d13988SJohnny Huang 	k++;
174276d13988SJohnny Huang 	strap_parse[k].bit = 60;
174376d13988SJohnny Huang 	strap_parse[k].length = 1;
174476d13988SJohnny Huang 	strap_parse[k].value = ENABLE_GPIO_PASS_THROUGH(OTPSTRAP[1]);
174576d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_GPIO_PASS_THROUGH(OTPSTRAP_PRO[1]);
174676d13988SJohnny Huang 	if (ENABLE_GPIO_PASS_THROUGH(OTPSTRAP_KEEP[1])) {
174776d13988SJohnny Huang 		strap_parse[k].keep = 1;
174876d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
174976d13988SJohnny Huang 	} else {
175076d13988SJohnny Huang 		if (ENABLE_GPIO_PASS_THROUGH(OTPSTRAP[1]))
175176d13988SJohnny Huang 			strcpy(strap_parse[k].status,
175276d13988SJohnny Huang 			       "Enable GPIO pass through");
175376d13988SJohnny Huang 		else
175476d13988SJohnny Huang 			strcpy(strap_parse[k].status,
175576d13988SJohnny Huang 			       "Disable GPIO pass through");
175676d13988SJohnny Huang 	}
175776d13988SJohnny Huang 
175876d13988SJohnny Huang 	k++;
175976d13988SJohnny Huang 	strap_parse[k].bit = 61;
176076d13988SJohnny Huang 	strap_parse[k].length = 1;
176176d13988SJohnny Huang 	strap_parse[k].value = DISABLE_LOW_SECURITY_KEY(OTPSTRAP[1]);
176276d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_LOW_SECURITY_KEY(OTPSTRAP_PRO[1]);
176376d13988SJohnny Huang 	if (DISABLE_LOW_SECURITY_KEY(OTPSTRAP_KEEP[1])) {
176476d13988SJohnny Huang 		strap_parse[k].keep = 1;
176576d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
176676d13988SJohnny Huang 	} else {
176776d13988SJohnny Huang 		if (DISABLE_LOW_SECURITY_KEY(OTPSTRAP[1]))
176876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
176976d13988SJohnny Huang 			       "Disable low security secure boot key");
177076d13988SJohnny Huang 		else
177176d13988SJohnny Huang 			strcpy(strap_parse[k].status,
177276d13988SJohnny Huang 			       "Enable low security secure boot key");
177376d13988SJohnny Huang 	}
177476d13988SJohnny Huang 
177576d13988SJohnny Huang 	k++;
177676d13988SJohnny Huang 	strap_parse[k].bit = 62;
177776d13988SJohnny Huang 	strap_parse[k].length = 1;
177876d13988SJohnny Huang 	strap_parse[k].value = ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP[1]);
177976d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP_PRO[1]);
178076d13988SJohnny Huang 	if (ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP_KEEP[1])) {
178176d13988SJohnny Huang 		strap_parse[k].keep = 1;
178276d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
178376d13988SJohnny Huang 	} else {
178476d13988SJohnny Huang 		if (ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP[1]))
178576d13988SJohnny Huang 			strcpy(strap_parse[k].status,
178676d13988SJohnny Huang 			       "Enable dedicate GPIO strap pins");
178776d13988SJohnny Huang 		else
178876d13988SJohnny Huang 			strcpy(strap_parse[k].status,
178976d13988SJohnny Huang 			       "Disable dedicate GPIO strap pins");
179076d13988SJohnny Huang 	}
179176d13988SJohnny Huang 
179276d13988SJohnny Huang 	return k + 1;
179376d13988SJohnny Huang }
179466f2f8e5SJohnny Huang 
179566f2f8e5SJohnny Huang static int otp_print_conf_info(uint32_t *OTPCFG)
179666f2f8e5SJohnny Huang {
179766f2f8e5SJohnny Huang 	struct otpconf_parse conf_parse[60];
179866f2f8e5SJohnny Huang 	int length;
179966f2f8e5SJohnny Huang 	int i;
180066f2f8e5SJohnny Huang 
180166f2f8e5SJohnny Huang 	length = otp_conf_parse(OTPCFG, conf_parse);
180266f2f8e5SJohnny Huang 
180366f2f8e5SJohnny Huang 	if (length <= 0)
180466f2f8e5SJohnny Huang 		return OTP_FAILURE;
180566f2f8e5SJohnny Huang 
1806*737ed20bSJohnny Huang 	printf("DW  BIT     Value       Description\n");
180766f2f8e5SJohnny Huang 	printf("__________________________________________________________________________\n");
180866f2f8e5SJohnny Huang 	for (i = 0; i < length; i++) {
180966f2f8e5SJohnny Huang 		printf("%-4d", conf_parse[i].dw_offset);
181066f2f8e5SJohnny Huang 		if (conf_parse[i].length == 1) {
181166f2f8e5SJohnny Huang 			printf("%-8d", conf_parse[i].bit);
181266f2f8e5SJohnny Huang 		} else {
181366f2f8e5SJohnny Huang 			printf("%-2d:%-5d",
181466f2f8e5SJohnny Huang 			       conf_parse[i].bit + conf_parse[i].length - 1,
181566f2f8e5SJohnny Huang 			       conf_parse[i].bit);
181666f2f8e5SJohnny Huang 		}
181766f2f8e5SJohnny Huang 		printf("0x%-10x", conf_parse[i].value);
181866f2f8e5SJohnny Huang 		printf("%s\n", conf_parse[i].status);
181966f2f8e5SJohnny Huang 	}
182066f2f8e5SJohnny Huang 	return OTP_SUCCESS;
182166f2f8e5SJohnny Huang }
182266f2f8e5SJohnny Huang 
182366f2f8e5SJohnny Huang static void otp_info_config(void)
182466f2f8e5SJohnny Huang {
182566f2f8e5SJohnny Huang 	uint32_t OTPCFG[24];
182666f2f8e5SJohnny Huang 	int i;
182766f2f8e5SJohnny Huang 
182866f2f8e5SJohnny Huang 	for (i = 0; i < 12; i++)
182966f2f8e5SJohnny Huang 		otp_read_config(i, &OTPCFG[i]);
183066f2f8e5SJohnny Huang 
183166f2f8e5SJohnny Huang 	for (i = 12; i < 24; i++)
183266f2f8e5SJohnny Huang 		OTPCFG[i] = 0;
183366f2f8e5SJohnny Huang 
183466f2f8e5SJohnny Huang 	otp_print_conf_info(OTPCFG);
183566f2f8e5SJohnny Huang }
183666f2f8e5SJohnny Huang 
183776d13988SJohnny Huang static int otp_print_strap_info(uint32_t *OTPSTRAP)
183876d13988SJohnny Huang {
183976d13988SJohnny Huang 	struct otpstrap_parse strap_parse[60];
184076d13988SJohnny Huang 	int length;
184176d13988SJohnny Huang 	int i;
184276d13988SJohnny Huang 
184376d13988SJohnny Huang 	length = otp_strap_parse(OTPSTRAP, strap_parse);
184476d13988SJohnny Huang 
184576d13988SJohnny Huang 	if (length <= 0)
184676d13988SJohnny Huang 		return OTP_FAILURE;
184776d13988SJohnny Huang 
1848*737ed20bSJohnny Huang 	printf("BIT     Value       Protect     Description\n");
184976d13988SJohnny Huang 	printf("__________________________________________________________________________________________\n");
185076d13988SJohnny Huang 	for (i = 0; i < length; i++) {
185176d13988SJohnny Huang 		if (strap_parse[i].length == 1) {
185276d13988SJohnny Huang 			printf("%-8d", strap_parse[i].bit);
185376d13988SJohnny Huang 		} else {
185476d13988SJohnny Huang 			printf("%-2d:%-5d",
185576d13988SJohnny Huang 			       strap_parse[i].bit + strap_parse[i].length - 1,
185676d13988SJohnny Huang 			       strap_parse[i].bit);
185776d13988SJohnny Huang 		}
185876d13988SJohnny Huang 		printf("0x%-10x", strap_parse[i].value);
185976d13988SJohnny Huang 		printf("0x%-10x", strap_parse[i].protect);
186076d13988SJohnny Huang 		printf("%s\n", strap_parse[i].status);
186176d13988SJohnny Huang 	}
186276d13988SJohnny Huang 	return OTP_SUCCESS;
186376d13988SJohnny Huang }
186476d13988SJohnny Huang 
186576d13988SJohnny Huang static void otp_info_strap(void)
186676d13988SJohnny Huang {
186776d13988SJohnny Huang 	struct otpstrap_status strap_status[64];
186876d13988SJohnny Huang 	uint32_t OTPSTRAP[6];
186976d13988SJohnny Huang 	int i;
187076d13988SJohnny Huang 
187176d13988SJohnny Huang 
187276d13988SJohnny Huang 	otp_strp_status(strap_status);
187376d13988SJohnny Huang 
187476d13988SJohnny Huang 	for (i = 0; i < 6; i++)
187576d13988SJohnny Huang 		OTPSTRAP[i] = 0;
187676d13988SJohnny Huang 	for (i = 0; i < 32; i++) {
187776d13988SJohnny Huang 		OTPSTRAP[0] |= (strap_status[i].value & 0x1) << i;
187876d13988SJohnny Huang 		OTPSTRAP[4] |= (strap_status[i].protected & 0x1) << i;
187976d13988SJohnny Huang 	}
188076d13988SJohnny Huang 	for (i = 0; i < 32; i++) {
188176d13988SJohnny Huang 		OTPSTRAP[1] |= (strap_status[i + 32].value & 0x1) << i;
188276d13988SJohnny Huang 		OTPSTRAP[5] |= (strap_status[i + 32].protected & 0x1) << i;
188376d13988SJohnny Huang 	}
188476d13988SJohnny Huang 
188576d13988SJohnny Huang 	otp_print_strap_info(OTPSTRAP);
188676d13988SJohnny Huang }
188776d13988SJohnny Huang 
188869d5fd8fSJohnny Huang static void buf_print(char *buf, int len)
188969d5fd8fSJohnny Huang {
189069d5fd8fSJohnny Huang 	int i;
189169d5fd8fSJohnny Huang 	printf("      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
189269d5fd8fSJohnny Huang 	for (i = 0; i < len; i++) {
189369d5fd8fSJohnny Huang 		if (i % 16 == 0) {
189469d5fd8fSJohnny Huang 			printf("%04X: ", i);
189569d5fd8fSJohnny Huang 		}
189669d5fd8fSJohnny Huang 		printf("%02X ", buf[i]);
189769d5fd8fSJohnny Huang 		if ((i + 1) % 16 == 0) {
189869d5fd8fSJohnny Huang 			printf("\n");
189969d5fd8fSJohnny Huang 		}
190069d5fd8fSJohnny Huang 	}
190169d5fd8fSJohnny Huang }
190269d5fd8fSJohnny Huang 
1903d90825e2SJohnny Huang static int otp_data_parse(uint32_t *buf)
190469d5fd8fSJohnny Huang {
190569d5fd8fSJohnny Huang 	int key_id, key_offset, last, key_type, key_length, exp_length;
190669d5fd8fSJohnny Huang 	char *byte_buf;
190769d5fd8fSJohnny Huang 	int i = 0, len = 0;
190869d5fd8fSJohnny Huang 	byte_buf = (char *)buf;
190969d5fd8fSJohnny Huang 	while (1) {
191069d5fd8fSJohnny Huang 		key_id = buf[i] & 0x7;
191169d5fd8fSJohnny Huang 		key_offset = buf[i] & 0x1ff8;
191269d5fd8fSJohnny Huang 		last = (buf[i] >> 13) & 1;
191369d5fd8fSJohnny Huang 		key_type = (buf[i] >> 14) & 0xf;
191469d5fd8fSJohnny Huang 		key_length = (buf[i] >> 18) & 0x3;
191569d5fd8fSJohnny Huang 		exp_length = (buf[i] >> 20) & 0xfff;
191669d5fd8fSJohnny Huang 		printf("Key[%d]:\n", i);
191769d5fd8fSJohnny Huang 		printf("Key Type: ");
191869d5fd8fSJohnny Huang 		switch (key_type) {
191969d5fd8fSJohnny Huang 		case 0:
192069d5fd8fSJohnny Huang 			printf("AES-256 as OEM platform key for image encryption/decryption\n");
192169d5fd8fSJohnny Huang 			break;
192269d5fd8fSJohnny Huang 		case 1:
192369d5fd8fSJohnny Huang 			printf("AES-256 as secret vault key\n");
192469d5fd8fSJohnny Huang 			break;
192569d5fd8fSJohnny Huang 		case 4:
192669d5fd8fSJohnny Huang 			printf("HMAC as encrypted OEM HMAC keys in Mode 1\n");
192769d5fd8fSJohnny Huang 			break;
192869d5fd8fSJohnny Huang 		case 8:
192969d5fd8fSJohnny Huang 			printf("RSA-public as OEM DSS public keys in Mode 2\n");
193069d5fd8fSJohnny Huang 			break;
193169d5fd8fSJohnny Huang 		case 9:
193269d5fd8fSJohnny Huang 			printf("RSA-public as SOC public key\n");
193369d5fd8fSJohnny Huang 			break;
193469d5fd8fSJohnny Huang 		case 10:
193569d5fd8fSJohnny Huang 			printf("RSA-public as AES key decryption key\n");
193669d5fd8fSJohnny Huang 			break;
193769d5fd8fSJohnny Huang 		case 13:
193869d5fd8fSJohnny Huang 			printf("RSA-private as SOC private key\n");
193969d5fd8fSJohnny Huang 			break;
194069d5fd8fSJohnny Huang 		case 14:
194169d5fd8fSJohnny Huang 			printf("RSA-private as AES key decryption key\n");
194269d5fd8fSJohnny Huang 			break;
194369d5fd8fSJohnny Huang 		default:
194469d5fd8fSJohnny Huang 			printf("key_type error: %x\n", key_type);
194569d5fd8fSJohnny Huang 			return -1;
194669d5fd8fSJohnny Huang 		}
194769d5fd8fSJohnny Huang 		if (key_type == 4) {
194869d5fd8fSJohnny Huang 			printf("HMAC SHA Type: ");
194969d5fd8fSJohnny Huang 			switch (key_length) {
195069d5fd8fSJohnny Huang 			case 0:
195169d5fd8fSJohnny Huang 				printf("HMAC(SHA224)\n");
195269d5fd8fSJohnny Huang 				break;
195369d5fd8fSJohnny Huang 			case 1:
195469d5fd8fSJohnny Huang 				printf("HMAC(SHA256)\n");
195569d5fd8fSJohnny Huang 				break;
195669d5fd8fSJohnny Huang 			case 2:
195769d5fd8fSJohnny Huang 				printf("HMAC(SHA384)\n");
195869d5fd8fSJohnny Huang 				break;
195969d5fd8fSJohnny Huang 			case 3:
196069d5fd8fSJohnny Huang 				printf("HMAC(SHA512)\n");
196169d5fd8fSJohnny Huang 				break;
196269d5fd8fSJohnny Huang 			}
1963cd1610b4SJohnny Huang 		} else if (key_type != 0 && key_type != 1) {
196469d5fd8fSJohnny Huang 			printf("RSA SHA Type: ");
196569d5fd8fSJohnny Huang 			switch (key_length) {
196669d5fd8fSJohnny Huang 			case 0:
196769d5fd8fSJohnny Huang 				printf("RSA1024\n");
196869d5fd8fSJohnny Huang 				len = 0x100;
196969d5fd8fSJohnny Huang 				break;
197069d5fd8fSJohnny Huang 			case 1:
197169d5fd8fSJohnny Huang 				printf("RSA2048\n");
197269d5fd8fSJohnny Huang 				len = 0x200;
197369d5fd8fSJohnny Huang 				break;
197469d5fd8fSJohnny Huang 			case 2:
197569d5fd8fSJohnny Huang 				printf("RSA3072\n");
197669d5fd8fSJohnny Huang 				len = 0x300;
197769d5fd8fSJohnny Huang 				break;
197869d5fd8fSJohnny Huang 			case 3:
197969d5fd8fSJohnny Huang 				printf("RSA4096\n");
198069d5fd8fSJohnny Huang 				len = 0x400;
198169d5fd8fSJohnny Huang 				break;
198269d5fd8fSJohnny Huang 			}
198369d5fd8fSJohnny Huang 			printf("RSA exponent bit length: %d\n", exp_length);
198469d5fd8fSJohnny Huang 		}
198569d5fd8fSJohnny Huang 		if (key_type == 4 || key_type == 8)
198669d5fd8fSJohnny Huang 			printf("Key Number ID: %d\n", key_id);
198769d5fd8fSJohnny Huang 		printf("Key Value:\n");
198869d5fd8fSJohnny Huang 		if (key_type == 4) {
198969d5fd8fSJohnny Huang 			buf_print(&byte_buf[key_offset], 0x40);
199069d5fd8fSJohnny Huang 		} else if (key_type == 0 || key_type == 1) {
199169d5fd8fSJohnny Huang 			printf("AES Key:\n");
199269d5fd8fSJohnny Huang 			buf_print(&byte_buf[key_offset], 0x20);
199369d5fd8fSJohnny Huang 			printf("AES IV:\n");
199469d5fd8fSJohnny Huang 			buf_print(&byte_buf[key_offset + 0x20], 0x10);
199569d5fd8fSJohnny Huang 
199669d5fd8fSJohnny Huang 		} else {
199769d5fd8fSJohnny Huang 			printf("RSA mod:\n");
199869d5fd8fSJohnny Huang 			buf_print(&byte_buf[key_offset], len / 2);
199969d5fd8fSJohnny Huang 			printf("RSA exp:\n");
200069d5fd8fSJohnny Huang 			buf_print(&byte_buf[key_offset + (len / 2)], len / 2);
200169d5fd8fSJohnny Huang 		}
200269d5fd8fSJohnny Huang 		if (last)
200369d5fd8fSJohnny Huang 			break;
200469d5fd8fSJohnny Huang 		i++;
200569d5fd8fSJohnny Huang 	}
200669d5fd8fSJohnny Huang 	return 0;
200769d5fd8fSJohnny Huang }
200869d5fd8fSJohnny Huang 
2009a6d0d645SJohnny Huang static int otp_prog_conf(uint32_t *buf)
201069d5fd8fSJohnny Huang {
2011a6d0d645SJohnny Huang 	int i, k;
2012d90825e2SJohnny Huang 	int pass = 0;
2013d90825e2SJohnny Huang 	int soak = 0;
2014a6d0d645SJohnny Huang 	uint32_t prog_address;
2015a6d0d645SJohnny Huang 	uint32_t data[12];
2016a6d0d645SJohnny Huang 	uint32_t compare[2];
2017d90825e2SJohnny Huang 	uint32_t *buf_keep = &buf[12];
2018d90825e2SJohnny Huang 	uint32_t data_masked;
2019d90825e2SJohnny Huang 	uint32_t buf_masked;
202069d5fd8fSJohnny Huang 
2021a6d0d645SJohnny Huang 	printf("Read OTP Config Region:\n");
2022a6d0d645SJohnny Huang 
2023a6d0d645SJohnny Huang 	printProgress(0, 12, "");
2024a6d0d645SJohnny Huang 	for (i = 0; i < 12 ; i ++) {
2025a6d0d645SJohnny Huang 		printProgress(i + 1, 12, "");
202669d5fd8fSJohnny Huang 		prog_address = 0x800;
2027a6d0d645SJohnny Huang 		prog_address |= (i / 8) * 0x200;
2028a6d0d645SJohnny Huang 		prog_address |= (i % 8) * 0x2;
2029a6d0d645SJohnny Huang 		otp_read_data(prog_address, &data[i]);
2030a6d0d645SJohnny Huang 	}
2031a6d0d645SJohnny Huang 
2032a6d0d645SJohnny Huang 	printf("Check writable...\n");
2033a6d0d645SJohnny Huang 	for (i = 0; i < 12; i++) {
2034d90825e2SJohnny Huang 		data_masked = data[i]  & ~buf_keep[i];
2035d90825e2SJohnny Huang 		buf_masked  = buf[i] & ~buf_keep[i];
2036d90825e2SJohnny Huang 		if (data_masked == buf_masked)
203769d5fd8fSJohnny Huang 			continue;
2038d90825e2SJohnny Huang 		if ((data_masked | buf_masked) == buf_masked) {
2039a6d0d645SJohnny Huang 			continue;
2040a6d0d645SJohnny Huang 		} else {
2041a6d0d645SJohnny Huang 			printf("Input image can't program into OTP, please check.\n");
2042a6af4a17SJohnny Huang 			printf("OTPCFG[%X] = %x\n", i, data[i]);
2043a6af4a17SJohnny Huang 			printf("Input [%X] = %x\n", i, buf[i]);
2044a6af4a17SJohnny Huang 			printf("Mask  [%X] = %x\n", i, ~buf_keep[i]);
20452a856b9aSJohnny Huang 			return OTP_FAILURE;
2046a6d0d645SJohnny Huang 		}
2047a6d0d645SJohnny Huang 	}
2048a6d0d645SJohnny Huang 
2049a6d0d645SJohnny Huang 	printf("Start Programing...\n");
2050a6d0d645SJohnny Huang 	printProgress(0, 12, "");
2051d90825e2SJohnny Huang 	otp_soak(0);
2052a6d0d645SJohnny Huang 	for (i = 0; i < 12; i++) {
2053d90825e2SJohnny Huang 		data_masked = data[i]  & ~buf_keep[i];
2054d90825e2SJohnny Huang 		buf_masked  = buf[i] & ~buf_keep[i];
2055a6d0d645SJohnny Huang 		prog_address = 0x800;
2056a6d0d645SJohnny Huang 		prog_address |= (i / 8) * 0x200;
2057a6d0d645SJohnny Huang 		prog_address |= (i % 8) * 0x2;
2058d90825e2SJohnny Huang 		if (data_masked == buf_masked) {
2059a6d0d645SJohnny Huang 			printProgress(i + 1, 12, "[%03X]=%08X HIT", prog_address, buf[i]);
2060a6d0d645SJohnny Huang 			continue;
2061a6d0d645SJohnny Huang 		}
2062d90825e2SJohnny Huang 		if (soak) {
2063d90825e2SJohnny Huang 			soak = 0;
2064d90825e2SJohnny Huang 			otp_soak(0);
2065d90825e2SJohnny Huang 		}
2066a6d0d645SJohnny Huang 		printProgress(i + 1, 12, "[%03X]=%08X    ", prog_address, buf[i]);
2067a6d0d645SJohnny Huang 
2068d90825e2SJohnny Huang 		otp_prog_dw(buf[i], buf_keep[i], prog_address);
2069a6d0d645SJohnny Huang 
207069d5fd8fSJohnny Huang 		pass = 0;
207169d5fd8fSJohnny Huang 		for (k = 0; k < RETRY; k++) {
2072d90825e2SJohnny Huang 			if (verify_dw(prog_address, &buf[i], &buf_keep[i], compare, 1) != 0) {
2073d90825e2SJohnny Huang 				if (soak == 0) {
2074d90825e2SJohnny Huang 					soak = 1;
2075d90825e2SJohnny Huang 					otp_soak(1);
2076d90825e2SJohnny Huang 				}
2077a6d0d645SJohnny Huang 				otp_prog_dw(compare[0], prog_address, 1);
2078a6d0d645SJohnny Huang 			} else {
207969d5fd8fSJohnny Huang 				pass = 1;
208069d5fd8fSJohnny Huang 				break;
208169d5fd8fSJohnny Huang 			}
208269d5fd8fSJohnny Huang 		}
2083a6d0d645SJohnny Huang 	}
2084a6d0d645SJohnny Huang 
208569d5fd8fSJohnny Huang 	if (!pass)
20862a856b9aSJohnny Huang 		return OTP_FAILURE;
2087a6d0d645SJohnny Huang 
20882a856b9aSJohnny Huang 	return OTP_SUCCESS;
2089d90825e2SJohnny Huang 
209069d5fd8fSJohnny Huang }
209169d5fd8fSJohnny Huang 
209269d5fd8fSJohnny Huang 
209376d13988SJohnny Huang static int otp_strap_image_confirm(uint32_t *buf)
209469d5fd8fSJohnny Huang {
209569d5fd8fSJohnny Huang 	int i;
209669d5fd8fSJohnny Huang 	uint32_t *strap_keep = buf + 2;
209769d5fd8fSJohnny Huang 	uint32_t *strap_protect = buf + 4;
209869d5fd8fSJohnny Huang 	int bit, pbit, kbit;
209969d5fd8fSJohnny Huang 	int fail = 0;
2100a6af4a17SJohnny Huang 	int skip = -1;
210166f2f8e5SJohnny Huang 	struct otpstrap_status otpstrap[64];
210269d5fd8fSJohnny Huang 
210369d5fd8fSJohnny Huang 	otp_strp_status(otpstrap);
210469d5fd8fSJohnny Huang 	for (i = 0; i < 64; i++) {
210569d5fd8fSJohnny Huang 		if (i < 32) {
210669d5fd8fSJohnny Huang 			bit = (buf[0] >> i) & 0x1;
210769d5fd8fSJohnny Huang 			kbit = (strap_keep[0] >> i) & 0x1;
210869d5fd8fSJohnny Huang 			pbit = (strap_protect[0] >> i) & 0x1;
210969d5fd8fSJohnny Huang 		} else {
211069d5fd8fSJohnny Huang 			bit = (buf[1] >> (i - 32)) & 0x1;
211169d5fd8fSJohnny Huang 			kbit = (strap_keep[1] >> (i - 32)) & 0x1;
211269d5fd8fSJohnny Huang 			pbit = (strap_protect[1] >> (i - 32)) & 0x1;
211369d5fd8fSJohnny Huang 		}
211469d5fd8fSJohnny Huang 
211569d5fd8fSJohnny Huang 		if (kbit == 1) {
211669d5fd8fSJohnny Huang 			continue;
211769d5fd8fSJohnny Huang 		} else {
2118a6af4a17SJohnny Huang 			printf("OTPSTRAP[%X]:\n", i);
211969d5fd8fSJohnny Huang 		}
212069d5fd8fSJohnny Huang 		if (bit == otpstrap[i].value) {
212169d5fd8fSJohnny Huang 			printf("    The value is same as before, skip it.\n");
2122a6af4a17SJohnny Huang 			if (skip == -1)
2123a6af4a17SJohnny Huang 				skip = 1;
212469d5fd8fSJohnny Huang 			continue;
2125a6af4a17SJohnny Huang 		} else {
2126a6af4a17SJohnny Huang 			skip = 0;
212769d5fd8fSJohnny Huang 		}
212869d5fd8fSJohnny Huang 		if (otpstrap[i].protected == 1) {
212969d5fd8fSJohnny Huang 			printf("    This bit is protected and is not writable\n");
213069d5fd8fSJohnny Huang 			fail = 1;
213169d5fd8fSJohnny Huang 			continue;
213269d5fd8fSJohnny Huang 		}
213369d5fd8fSJohnny Huang 		if (otpstrap[i].remain_times == 0) {
2134a6af4a17SJohnny Huang 			printf("    This bit is no remaining times to write.\n");
213569d5fd8fSJohnny Huang 			fail = 1;
213669d5fd8fSJohnny Huang 			continue;
213769d5fd8fSJohnny Huang 		}
213869d5fd8fSJohnny Huang 		if (pbit == 1) {
213969d5fd8fSJohnny Huang 			printf("    This bit will be protected and become non-writable.\n");
214069d5fd8fSJohnny Huang 		}
2141a6af4a17SJohnny Huang 		printf("    Write 1 to OTPSTRAP[%X] OPTION[%X], that value becomes from %d to %d.\n", i, otpstrap[i].writeable_option + 1, otpstrap[i].value, otpstrap[i].value ^ 1);
214269d5fd8fSJohnny Huang 	}
214369d5fd8fSJohnny Huang 	if (fail == 1)
2144a6af4a17SJohnny Huang 		return OTP_FAILURE;
2145a6af4a17SJohnny Huang 	else if (skip == 1)
2146a6af4a17SJohnny Huang 		return OTP_PROG_SKIP;
21477e22f42dSJohnny Huang 
21487e22f42dSJohnny Huang 	return 0;
214969d5fd8fSJohnny Huang }
215069d5fd8fSJohnny Huang 
21512a856b9aSJohnny Huang static int otp_print_strap(int start, int count)
215269d5fd8fSJohnny Huang {
215369d5fd8fSJohnny Huang 	int i, j;
215466f2f8e5SJohnny Huang 	struct otpstrap_status otpstrap[64];
215569d5fd8fSJohnny Huang 
21562a856b9aSJohnny Huang 	if (start < 0 || start > 64)
21572a856b9aSJohnny Huang 		return OTP_USAGE;
21582a856b9aSJohnny Huang 
21592a856b9aSJohnny Huang 	if ((start + count) < 0 || (start + count) > 64)
21602a856b9aSJohnny Huang 		return OTP_USAGE;
21612a856b9aSJohnny Huang 
216269d5fd8fSJohnny Huang 	otp_strp_status(otpstrap);
216369d5fd8fSJohnny Huang 
2164*737ed20bSJohnny Huang 	printf("BIT  Value  Avaliable        Status\n");
2165*737ed20bSJohnny Huang 	printf("______________________________________________________________________\n");
2166*737ed20bSJohnny Huang 
2167cd1610b4SJohnny Huang 	for (i = start; i < start + count; i++) {
2168*737ed20bSJohnny Huang 		printf("%-5d", i);
2169*737ed20bSJohnny Huang 		printf("%-7d", otpstrap[i].value);
2170*737ed20bSJohnny Huang 		for (j = 0; j < 7; j++)
2171*737ed20bSJohnny Huang 			printf("%d ", otpstrap[i].option_array[j]);
2172*737ed20bSJohnny Huang 		printf("   ");
217369d5fd8fSJohnny Huang 		if (otpstrap[i].protected == 1) {
2174*737ed20bSJohnny Huang 			printf("protected and not writable");
217569d5fd8fSJohnny Huang 		} else {
2176*737ed20bSJohnny Huang 			printf("not protected ");
217769d5fd8fSJohnny Huang 			if (otpstrap[i].remain_times == 0) {
2178*737ed20bSJohnny Huang 				printf("and no remaining times to write.");
217969d5fd8fSJohnny Huang 			} else {
2180*737ed20bSJohnny Huang 				printf("and still can write %d times", otpstrap[i].remain_times);
218169d5fd8fSJohnny Huang 			}
218269d5fd8fSJohnny Huang 		}
2183*737ed20bSJohnny Huang 		printf("\n");
218469d5fd8fSJohnny Huang 	}
21852a856b9aSJohnny Huang 
21862a856b9aSJohnny Huang 	return OTP_SUCCESS;
218769d5fd8fSJohnny Huang }
218869d5fd8fSJohnny Huang 
218969d5fd8fSJohnny Huang static int otp_prog_strap(uint32_t *buf)
219069d5fd8fSJohnny Huang {
219169d5fd8fSJohnny Huang 	int i, j;
219269d5fd8fSJohnny Huang 	uint32_t *strap_keep = buf + 2;
219369d5fd8fSJohnny Huang 	uint32_t *strap_protect = buf + 4;
219469d5fd8fSJohnny Huang 	uint32_t prog_bit, prog_address;
219569d5fd8fSJohnny Huang 	int bit, pbit, kbit, offset;
219669d5fd8fSJohnny Huang 	int fail = 0;
21977e22f42dSJohnny Huang 	int pass = 0;
21987e22f42dSJohnny Huang 	int soak = 0;
219966f2f8e5SJohnny Huang 	struct otpstrap_status otpstrap[64];
220069d5fd8fSJohnny Huang 
220169d5fd8fSJohnny Huang 	otp_strp_status(otpstrap);
220269d5fd8fSJohnny Huang 
22037e22f42dSJohnny Huang 	otp_soak(0);
22047e22f42dSJohnny Huang 
220569d5fd8fSJohnny Huang 	for (i = 0; i < 64; i++) {
22064c1c9b35SJohnny Huang 		printProgress(i + 1, 64, "");
220769d5fd8fSJohnny Huang 		prog_address = 0x800;
220869d5fd8fSJohnny Huang 		if (i < 32) {
220969d5fd8fSJohnny Huang 			offset = i;
221069d5fd8fSJohnny Huang 			bit = (buf[0] >> offset) & 0x1;
221169d5fd8fSJohnny Huang 			kbit = (strap_keep[0] >> offset) & 0x1;
221269d5fd8fSJohnny Huang 			pbit = (strap_protect[0] >> offset) & 0x1;
221369d5fd8fSJohnny Huang 			prog_address |= ((otpstrap[i].writeable_option * 2 + 16) / 8) * 0x200;
221469d5fd8fSJohnny Huang 			prog_address |= ((otpstrap[i].writeable_option * 2 + 16) % 8) * 0x2;
221569d5fd8fSJohnny Huang 
221669d5fd8fSJohnny Huang 		} else {
221769d5fd8fSJohnny Huang 			offset = (i - 32);
221869d5fd8fSJohnny Huang 			bit = (buf[1] >> offset) & 0x1;
221969d5fd8fSJohnny Huang 			kbit = (strap_keep[1] >> offset) & 0x1;
222069d5fd8fSJohnny Huang 			pbit = (strap_protect[1] >> offset) & 0x1;
222169d5fd8fSJohnny Huang 			prog_address |= ((otpstrap[i].writeable_option * 2 + 17) / 8) * 0x200;
222269d5fd8fSJohnny Huang 			prog_address |= ((otpstrap[i].writeable_option * 2 + 17) % 8) * 0x2;
222369d5fd8fSJohnny Huang 		}
222469d5fd8fSJohnny Huang 		prog_bit = ~(0x1 << offset);
222569d5fd8fSJohnny Huang 
222669d5fd8fSJohnny Huang 		if (kbit == 1) {
222769d5fd8fSJohnny Huang 			continue;
222869d5fd8fSJohnny Huang 		}
222969d5fd8fSJohnny Huang 		if (bit == otpstrap[i].value) {
223069d5fd8fSJohnny Huang 			continue;
223169d5fd8fSJohnny Huang 		}
223269d5fd8fSJohnny Huang 		if (otpstrap[i].protected == 1) {
223369d5fd8fSJohnny Huang 			fail = 1;
223469d5fd8fSJohnny Huang 			continue;
223569d5fd8fSJohnny Huang 		}
223669d5fd8fSJohnny Huang 		if (otpstrap[i].remain_times == 0) {
223769d5fd8fSJohnny Huang 			fail = 1;
223869d5fd8fSJohnny Huang 			continue;
223969d5fd8fSJohnny Huang 		}
22407e22f42dSJohnny Huang 
22417e22f42dSJohnny Huang 		if (soak) {
224269d5fd8fSJohnny Huang 			soak = 0;
22437e22f42dSJohnny Huang 			otp_soak(0);
22447e22f42dSJohnny Huang 		}
22457e22f42dSJohnny Huang 
22467e22f42dSJohnny Huang 		otp_prog(prog_address, prog_bit);
22477e22f42dSJohnny Huang 
22487e22f42dSJohnny Huang 		pass = 0;
22497e22f42dSJohnny Huang 
225069d5fd8fSJohnny Huang 		for (j = 0; j < RETRY; j++) {
2251a6d0d645SJohnny Huang 			if (verify_bit(prog_address, offset, 1) == 0) {
225269d5fd8fSJohnny Huang 				pass = 1;
225369d5fd8fSJohnny Huang 				break;
225469d5fd8fSJohnny Huang 			}
22557e22f42dSJohnny Huang 			if (soak == 0) {
225669d5fd8fSJohnny Huang 				soak = 1;
22577e22f42dSJohnny Huang 				otp_soak(1);
22584b65a65dSJohnny Huang 			}
225969d5fd8fSJohnny Huang 			otp_prog(prog_address, prog_bit);
226069d5fd8fSJohnny Huang 		}
226169d5fd8fSJohnny Huang 		if (!pass)
22622a856b9aSJohnny Huang 			return OTP_FAILURE;
226369d5fd8fSJohnny Huang 
226469d5fd8fSJohnny Huang 		if (pbit == 0)
226569d5fd8fSJohnny Huang 			continue;
226669d5fd8fSJohnny Huang 		prog_address = 0x800;
226769d5fd8fSJohnny Huang 		if (i < 32)
226869d5fd8fSJohnny Huang 			prog_address |= 0x60c;
226969d5fd8fSJohnny Huang 		else
227069d5fd8fSJohnny Huang 			prog_address |= 0x60e;
227169d5fd8fSJohnny Huang 
22727e22f42dSJohnny Huang 
22737e22f42dSJohnny Huang 		if (soak) {
22747e22f42dSJohnny Huang 			soak = 0;
22757e22f42dSJohnny Huang 			otp_soak(0);
22767e22f42dSJohnny Huang 		}
22777e22f42dSJohnny Huang 
22787e22f42dSJohnny Huang 		otp_prog(prog_address, prog_bit);
22797e22f42dSJohnny Huang 
22807e22f42dSJohnny Huang 		pass = 0;
22817e22f42dSJohnny Huang 
228269d5fd8fSJohnny Huang 		for (j = 0; j < RETRY; j++) {
22837e22f42dSJohnny Huang 
2284a6d0d645SJohnny Huang 			if (verify_bit(prog_address, offset, 1) == 0) {
228569d5fd8fSJohnny Huang 				pass = 1;
228669d5fd8fSJohnny Huang 				break;
228769d5fd8fSJohnny Huang 			}
22887e22f42dSJohnny Huang 			if (soak == 0) {
228969d5fd8fSJohnny Huang 				soak = 1;
22907e22f42dSJohnny Huang 				otp_soak(1);
229169d5fd8fSJohnny Huang 			}
229269d5fd8fSJohnny Huang 			otp_prog(prog_address, prog_bit);
229369d5fd8fSJohnny Huang 		}
229469d5fd8fSJohnny Huang 		if (!pass)
22952a856b9aSJohnny Huang 			return OTP_FAILURE;
229669d5fd8fSJohnny Huang 
229769d5fd8fSJohnny Huang 	}
229869d5fd8fSJohnny Huang 	if (fail == 1)
22992a856b9aSJohnny Huang 		return OTP_FAILURE;
230069d5fd8fSJohnny Huang 	else
23012a856b9aSJohnny Huang 		return OTP_SUCCESS;
230269d5fd8fSJohnny Huang 
230369d5fd8fSJohnny Huang }
230469d5fd8fSJohnny Huang 
2305cd1610b4SJohnny Huang static void otp_prog_bit(uint32_t value, uint32_t prog_address, uint32_t bit_offset, int soak)
2306cd1610b4SJohnny Huang {
2307cd1610b4SJohnny Huang 	int prog_bit;
2308cd1610b4SJohnny Huang 
23097e22f42dSJohnny Huang 	otp_soak(soak);
23107e22f42dSJohnny Huang 
2311cd1610b4SJohnny Huang 	if (prog_address % 2 == 0) {
2312cd1610b4SJohnny Huang 		if (value)
2313cd1610b4SJohnny Huang 			prog_bit = ~(0x1 << bit_offset);
2314cd1610b4SJohnny Huang 		else
2315cd1610b4SJohnny Huang 			return;
2316cd1610b4SJohnny Huang 	} else {
2317cd1610b4SJohnny Huang 		prog_address |= 1 << 15;
2318cd1610b4SJohnny Huang 		if (!value)
2319cd1610b4SJohnny Huang 			prog_bit = 0x1 << bit_offset;
2320cd1610b4SJohnny Huang 		else
2321cd1610b4SJohnny Huang 			return;
2322cd1610b4SJohnny Huang 	}
2323cd1610b4SJohnny Huang 	otp_prog(prog_address, prog_bit);
2324cd1610b4SJohnny Huang }
2325cd1610b4SJohnny Huang 
2326d90825e2SJohnny Huang static int otp_prog_data(uint32_t *buf)
23274c1c9b35SJohnny Huang {
23284c1c9b35SJohnny Huang 	int i, k;
23294c1c9b35SJohnny Huang 	int pass;
2330d90825e2SJohnny Huang 	int soak = 0;
23314c1c9b35SJohnny Huang 	uint32_t prog_address;
2332d90825e2SJohnny Huang 	uint32_t data[2048];
23334c1c9b35SJohnny Huang 	uint32_t compare[2];
2334d90825e2SJohnny Huang 	uint32_t *buf_keep = &buf[2048];
23354c1c9b35SJohnny Huang 
2336d90825e2SJohnny Huang 	uint32_t data0_masked;
2337d90825e2SJohnny Huang 	uint32_t data1_masked;
2338d90825e2SJohnny Huang 	uint32_t buf0_masked;
2339d90825e2SJohnny Huang 	uint32_t buf1_masked;
23404c1c9b35SJohnny Huang 
23414c1c9b35SJohnny Huang 	printf("Read OTP Data:\n");
23424c1c9b35SJohnny Huang 
2343d90825e2SJohnny Huang 	printProgress(0, 2048, "");
2344d90825e2SJohnny Huang 	for (i = 0; i < 2048 ; i += 2) {
2345d90825e2SJohnny Huang 		printProgress(i + 2, 2048, "");
2346d90825e2SJohnny Huang 		otp_read_data(i, &data[i]);
23474c1c9b35SJohnny Huang 	}
2348d90825e2SJohnny Huang 
23494c1c9b35SJohnny Huang 
23504c1c9b35SJohnny Huang 	printf("Check writable...\n");
2351d90825e2SJohnny Huang 	for (i = 0; i < 2048; i++) {
2352d90825e2SJohnny Huang 		data0_masked = data[i]  & ~buf_keep[i];
2353d90825e2SJohnny Huang 		buf0_masked  = buf[i] & ~buf_keep[i];
2354d90825e2SJohnny Huang 		if (data0_masked == buf0_masked)
23554c1c9b35SJohnny Huang 			continue;
2356d90825e2SJohnny Huang 		if (i % 2 == 0) {
2357d90825e2SJohnny Huang 			if ((data0_masked | buf0_masked) == buf0_masked) {
23584c1c9b35SJohnny Huang 				continue;
23594c1c9b35SJohnny Huang 			} else {
23604c1c9b35SJohnny Huang 				printf("Input image can't program into OTP, please check.\n");
2361d90825e2SJohnny Huang 				printf("OTP_ADDR[%x] = %x\n", i, data[i]);
23624c1c9b35SJohnny Huang 				printf("Input   [%x] = %x\n", i, buf[i]);
2363d90825e2SJohnny Huang 				printf("Mask    [%x] = %x\n", i, ~buf_keep[i]);
23642a856b9aSJohnny Huang 				return OTP_FAILURE;
236569d5fd8fSJohnny Huang 			}
2366d90825e2SJohnny Huang 		} else {
2367d90825e2SJohnny Huang 			if ((data0_masked & buf0_masked) == buf0_masked) {
2368d90825e2SJohnny Huang 				continue;
2369d90825e2SJohnny Huang 			} else {
2370d90825e2SJohnny Huang 				printf("Input image can't program into OTP, please check.\n");
2371d90825e2SJohnny Huang 				printf("OTP_ADDR[%x] = %x\n", i, data[i]);
2372d90825e2SJohnny Huang 				printf("Input   [%x] = %x\n", i, buf[i]);
2373d90825e2SJohnny Huang 				printf("Mask    [%x] = %x\n", i, ~buf_keep[i]);
23742a856b9aSJohnny Huang 				return OTP_FAILURE;
2375d90825e2SJohnny Huang 			}
2376d90825e2SJohnny Huang 		}
2377d90825e2SJohnny Huang 	}
237869d5fd8fSJohnny Huang 
2379d90825e2SJohnny Huang 	printf("Start Programing...\n");
2380d90825e2SJohnny Huang 	printProgress(0, 2048, "");
2381d90825e2SJohnny Huang 
2382d90825e2SJohnny Huang 	for (i = 0; i < 2048; i += 2) {
2383d90825e2SJohnny Huang 		prog_address = i;
2384d90825e2SJohnny Huang 		data0_masked = data[i]  & ~buf_keep[i];
2385d90825e2SJohnny Huang 		buf0_masked  = buf[i] & ~buf_keep[i];
2386d90825e2SJohnny Huang 		data1_masked = data[i + 1]  & ~buf_keep[i + 1];
2387d90825e2SJohnny Huang 		buf1_masked  = buf[i + 1] & ~buf_keep[i + 1];
2388d90825e2SJohnny Huang 		if ((data0_masked == buf0_masked) && (data1_masked == buf1_masked)) {
2389d90825e2SJohnny Huang 			printProgress(i + 2, 2048, "[%03X]=%08X HIT;[%03X]=%08X HIT", prog_address, buf[i], prog_address + 1, buf[i + 1]);
2390d90825e2SJohnny Huang 			continue;
2391d90825e2SJohnny Huang 		}
2392d90825e2SJohnny Huang 		if (soak) {
2393d90825e2SJohnny Huang 			soak = 0;
2394d90825e2SJohnny Huang 			otp_soak(0);
2395d90825e2SJohnny Huang 		}
2396d90825e2SJohnny Huang 		if (data1_masked == buf1_masked) {
2397d90825e2SJohnny Huang 			printProgress(i + 2, 2048, "[%03X]=%08X    ;[%03X]=%08X HIT", prog_address, buf[i], prog_address + 1, buf[i + 1]);
2398d90825e2SJohnny Huang 			otp_prog_dw(buf[i], buf_keep[i], prog_address);
2399d90825e2SJohnny Huang 		} else if (data0_masked == buf0_masked) {
2400d90825e2SJohnny Huang 			printProgress(i + 2, 2048, "[%03X]=%08X HIT;[%03X]=%08X    ", prog_address, buf[i], prog_address + 1, buf[i + 1]);
2401d90825e2SJohnny Huang 			otp_prog_dw(buf[i + 1], buf_keep[i + 1], prog_address + 1);
2402d90825e2SJohnny Huang 		} else {
2403d90825e2SJohnny Huang 			printProgress(i + 2, 2048, "[%03X]=%08X    ;[%03X]=%08X    ", prog_address, buf[i], prog_address + 1, buf[i + 1]);
2404d90825e2SJohnny Huang 			otp_prog_dw(buf[i], buf_keep[i], prog_address);
2405d90825e2SJohnny Huang 			otp_prog_dw(buf[i + 1], buf_keep[i + 1], prog_address + 1);
2406d90825e2SJohnny Huang 		}
2407d90825e2SJohnny Huang 
2408d90825e2SJohnny Huang 		pass = 0;
2409d90825e2SJohnny Huang 		for (k = 0; k < RETRY; k++) {
2410d90825e2SJohnny Huang 			if (verify_dw(prog_address, &buf[i], &buf_keep[i], compare, 2) != 0) {
2411d90825e2SJohnny Huang 				if (soak == 0) {
2412d90825e2SJohnny Huang 					soak = 1;
2413d90825e2SJohnny Huang 					otp_soak(1);
2414d90825e2SJohnny Huang 				}
2415d90825e2SJohnny Huang 				if (compare[0] != 0) {
2416d90825e2SJohnny Huang 					otp_prog_dw(compare[0], buf_keep[i], prog_address);
2417d90825e2SJohnny Huang 				}
2418d90825e2SJohnny Huang 				if (compare[1] != ~0) {
2419d90825e2SJohnny Huang 					otp_prog_dw(compare[1], buf_keep[i], prog_address + 1);
2420d90825e2SJohnny Huang 				}
2421d90825e2SJohnny Huang 			} else {
2422d90825e2SJohnny Huang 				pass = 1;
2423d90825e2SJohnny Huang 				break;
2424d90825e2SJohnny Huang 			}
2425d90825e2SJohnny Huang 		}
2426d90825e2SJohnny Huang 
2427d90825e2SJohnny Huang 		if (!pass)
24282a856b9aSJohnny Huang 			return OTP_FAILURE;
2429d90825e2SJohnny Huang 	}
24302a856b9aSJohnny Huang 	return OTP_SUCCESS;
2431d90825e2SJohnny Huang 
2432d90825e2SJohnny Huang }
2433d90825e2SJohnny Huang 
2434d90825e2SJohnny Huang static int do_otp_prog(int addr, int byte_size, int nconfirm)
243569d5fd8fSJohnny Huang {
243669d5fd8fSJohnny Huang 	int ret;
2437d90825e2SJohnny Huang 	int mode;
243869d5fd8fSJohnny Huang 	uint32_t *buf;
2439d90825e2SJohnny Huang 	uint32_t *data_region = NULL;
2440d90825e2SJohnny Huang 	uint32_t *conf_region = NULL;
2441d90825e2SJohnny Huang 	uint32_t *strap_region = NULL;
244269d5fd8fSJohnny Huang 
2443d90825e2SJohnny Huang 	buf = map_physmem(addr, byte_size, MAP_WRBACK);
244469d5fd8fSJohnny Huang 	if (!buf) {
244569d5fd8fSJohnny Huang 		puts("Failed to map physical memory\n");
24462a856b9aSJohnny Huang 		return OTP_FAILURE;
244769d5fd8fSJohnny Huang 	}
2448d90825e2SJohnny Huang 
2449d90825e2SJohnny Huang 	if (((buf[0] >> 29) & 0x7) == 0x7) {
2450d90825e2SJohnny Huang 		mode = OTP_REGION_ALL;
2451d90825e2SJohnny Huang 		conf_region = &buf[1];
2452d90825e2SJohnny Huang 		strap_region = &buf[25];
2453d90825e2SJohnny Huang 		data_region = &buf[31];
2454d90825e2SJohnny Huang 	} else {
2455d90825e2SJohnny Huang 		if (buf[0] & BIT(29)) {
2456d90825e2SJohnny Huang 			mode = OTP_REGION_DATA;
2457d90825e2SJohnny Huang 			data_region = &buf[31];
2458d90825e2SJohnny Huang 		}
2459d90825e2SJohnny Huang 		if (buf[0] & BIT(30)) {
2460d90825e2SJohnny Huang 			mode = OTP_REGION_CONF;
2461d90825e2SJohnny Huang 			strap_region = &buf[25];
2462d90825e2SJohnny Huang 		}
2463d90825e2SJohnny Huang 		if (buf[0] & BIT(31)) {
2464d90825e2SJohnny Huang 			mode = OTP_REGION_STRAP;
2465d90825e2SJohnny Huang 			conf_region = &buf[1];
2466d90825e2SJohnny Huang 		}
2467d90825e2SJohnny Huang 	}
246869d5fd8fSJohnny Huang 	if (!nconfirm) {
2469a6d0d645SJohnny Huang 		if (mode == OTP_REGION_CONF) {
247066f2f8e5SJohnny Huang 			if (otp_print_conf_info(conf_region) < 0) {
247169d5fd8fSJohnny Huang 				printf("OTP config error, please check.\n");
24722a856b9aSJohnny Huang 				return OTP_FAILURE;
247369d5fd8fSJohnny Huang 			}
2474a6d0d645SJohnny Huang 		} else if (mode == OTP_REGION_DATA) {
2475d90825e2SJohnny Huang 			if (otp_data_parse(data_region) < 0) {
247669d5fd8fSJohnny Huang 				printf("OTP data error, please check.\n");
24772a856b9aSJohnny Huang 				return OTP_FAILURE;
247869d5fd8fSJohnny Huang 			}
2479a6d0d645SJohnny Huang 		} else if (mode == OTP_REGION_STRAP) {
248076d13988SJohnny Huang 			ret = otp_strap_image_confirm(strap_region);
2481a6af4a17SJohnny Huang 			if (ret == OTP_FAILURE) {
248269d5fd8fSJohnny Huang 				printf("OTP strap error, please check.\n");
24832a856b9aSJohnny Huang 				return OTP_FAILURE;
2484a6af4a17SJohnny Huang 			} else if (ret == OTP_PROG_SKIP) {
2485a6af4a17SJohnny Huang 				printf("OTP strap skip all\n");
2486a6af4a17SJohnny Huang 				return OTP_SUCCESS;
248769d5fd8fSJohnny Huang 			}
2488a6d0d645SJohnny Huang 		} else if (mode == OTP_REGION_ALL) {
248966f2f8e5SJohnny Huang 			if (otp_print_conf_info(conf_region) < 0) {
249069d5fd8fSJohnny Huang 				printf("OTP config error, please check.\n");
24912a856b9aSJohnny Huang 				return OTP_FAILURE;
249269d5fd8fSJohnny Huang 			}
249376d13988SJohnny Huang 			if (otp_strap_image_confirm(strap_region) == OTP_FAILURE) {
249469d5fd8fSJohnny Huang 				printf("OTP strap error, please check.\n");
24952a856b9aSJohnny Huang 				return OTP_FAILURE;
249669d5fd8fSJohnny Huang 			}
2497d90825e2SJohnny Huang 			if (otp_data_parse(data_region) < 0) {
249869d5fd8fSJohnny Huang 				printf("OTP data error, please check.\n");
24992a856b9aSJohnny Huang 				return OTP_FAILURE;
250069d5fd8fSJohnny Huang 			}
250169d5fd8fSJohnny Huang 		}
250269d5fd8fSJohnny Huang 		printf("type \"YES\" (no quotes) to continue:\n");
250369d5fd8fSJohnny Huang 		if (!confirm_yesno()) {
250469d5fd8fSJohnny Huang 			printf(" Aborting\n");
25052a856b9aSJohnny Huang 			return OTP_FAILURE;
250669d5fd8fSJohnny Huang 		}
250769d5fd8fSJohnny Huang 	}
2508a6d0d645SJohnny Huang 	if (mode == OTP_REGION_CONF) {
2509d90825e2SJohnny Huang 		return otp_prog_conf(conf_region);
2510a6d0d645SJohnny Huang 	} else if (mode == OTP_REGION_STRAP) {
2511d90825e2SJohnny Huang 		return otp_prog_strap(strap_region);
2512a6d0d645SJohnny Huang 	} else if (mode == OTP_REGION_DATA) {
2513d90825e2SJohnny Huang 		return otp_prog_data(data_region);
2514a6d0d645SJohnny Huang 	} else if (mode == OTP_REGION_ALL) {
251569d5fd8fSJohnny Huang 		printf("programing data region ... ");
2516d90825e2SJohnny Huang 		ret = otp_prog_data(data_region);
25172a856b9aSJohnny Huang 		if (ret != 0) {
251869d5fd8fSJohnny Huang 			printf("Error\n");
251969d5fd8fSJohnny Huang 			return ret;
252069d5fd8fSJohnny Huang 		} else {
252169d5fd8fSJohnny Huang 			printf("Done\n");
252269d5fd8fSJohnny Huang 		}
252369d5fd8fSJohnny Huang 		printf("programing strap region ... ");
2524d90825e2SJohnny Huang 		ret = otp_prog_strap(strap_region);
25252a856b9aSJohnny Huang 		if (ret != 0) {
252669d5fd8fSJohnny Huang 			printf("Error\n");
252769d5fd8fSJohnny Huang 			return ret;
252869d5fd8fSJohnny Huang 		} else {
252969d5fd8fSJohnny Huang 			printf("Done\n");
253069d5fd8fSJohnny Huang 		}
253169d5fd8fSJohnny Huang 		printf("programing configuration region ... ");
2532d90825e2SJohnny Huang 		ret = otp_prog_conf(conf_region);
25332a856b9aSJohnny Huang 		if (ret != 0) {
253469d5fd8fSJohnny Huang 			printf("Error\n");
253569d5fd8fSJohnny Huang 			return ret;
253669d5fd8fSJohnny Huang 		}
253769d5fd8fSJohnny Huang 		printf("Done\n");
25382a856b9aSJohnny Huang 		return OTP_SUCCESS;
253969d5fd8fSJohnny Huang 	}
2540cd1610b4SJohnny Huang 
25412a856b9aSJohnny Huang 	return OTP_USAGE;
25422a856b9aSJohnny Huang }
25432a856b9aSJohnny Huang 
25442a856b9aSJohnny Huang static int do_otp_prog_bit(int mode, int otp_dw_offset, int bit_offset, int value, int nconfirm)
2545cd1610b4SJohnny Huang {
2546a6af4a17SJohnny Huang 	uint32_t read[2];
2547cd1610b4SJohnny Huang 	uint32_t strap_buf[6];
2548d90825e2SJohnny Huang 	uint32_t prog_address = 0;
254966f2f8e5SJohnny Huang 	struct otpstrap_status otpstrap[64];
2550cd1610b4SJohnny Huang 	int otp_bit;
2551cd1610b4SJohnny Huang 	int i;
2552cd1610b4SJohnny Huang 	int pass;
2553a6af4a17SJohnny Huang 	int ret;
2554cd1610b4SJohnny Huang 
2555cd1610b4SJohnny Huang 	switch (mode) {
2556a6d0d645SJohnny Huang 	case OTP_REGION_CONF:
2557a6af4a17SJohnny Huang 		otp_read_config(otp_dw_offset, read);
2558cd1610b4SJohnny Huang 		prog_address = 0x800;
2559cd1610b4SJohnny Huang 		prog_address |= (otp_dw_offset / 8) * 0x200;
2560cd1610b4SJohnny Huang 		prog_address |= (otp_dw_offset % 8) * 0x2;
2561a6af4a17SJohnny Huang 		otp_bit = (read[0] >> bit_offset) & 0x1;
2562cd1610b4SJohnny Huang 		if (otp_bit == value) {
2563a6af4a17SJohnny Huang 			printf("OTPCFG%X[%X] = %d\n", otp_dw_offset, bit_offset, value);
2564cd1610b4SJohnny Huang 			printf("No need to program\n");
25652a856b9aSJohnny Huang 			return OTP_SUCCESS;
2566cd1610b4SJohnny Huang 		}
2567cd1610b4SJohnny Huang 		if (otp_bit == 1 && value == 0) {
2568a6af4a17SJohnny Huang 			printf("OTPCFG%X[%X] = 1\n", otp_dw_offset, bit_offset);
2569cd1610b4SJohnny Huang 			printf("OTP is programed, which can't be clean\n");
25702a856b9aSJohnny Huang 			return OTP_FAILURE;
2571cd1610b4SJohnny Huang 		}
2572a6af4a17SJohnny Huang 		printf("Program OTPCFG%X[%X] to 1\n", otp_dw_offset, bit_offset);
2573cd1610b4SJohnny Huang 		break;
2574a6d0d645SJohnny Huang 	case OTP_REGION_DATA:
2575cd1610b4SJohnny Huang 		prog_address = otp_dw_offset;
2576cd1610b4SJohnny Huang 
2577cd1610b4SJohnny Huang 		if (otp_dw_offset % 2 == 0) {
2578a6af4a17SJohnny Huang 			otp_read_data(otp_dw_offset, read);
2579a6af4a17SJohnny Huang 			otp_bit = (read[0] >> bit_offset) & 0x1;
2580cd1610b4SJohnny Huang 		} else {
2581a6af4a17SJohnny Huang 			otp_read_data(otp_dw_offset - 1, read);
2582a6af4a17SJohnny Huang 			otp_bit = (read[1] >> bit_offset) & 0x1;
2583cd1610b4SJohnny Huang 		}
2584cd1610b4SJohnny Huang 		if (otp_bit == value) {
2585a6af4a17SJohnny Huang 			printf("OTPDATA%X[%X] = %d\n", otp_dw_offset, bit_offset, value);
2586cd1610b4SJohnny Huang 			printf("No need to program\n");
25872a856b9aSJohnny Huang 			return OTP_SUCCESS;
2588cd1610b4SJohnny Huang 		}
2589cd1610b4SJohnny Huang 		if (otp_bit == 1 && value == 0) {
2590a6af4a17SJohnny Huang 			printf("OTPDATA%X[%X] = 1\n", otp_dw_offset, bit_offset);
2591cd1610b4SJohnny Huang 			printf("OTP is programed, which can't be clean\n");
25922a856b9aSJohnny Huang 			return OTP_FAILURE;
2593cd1610b4SJohnny Huang 		}
2594a6af4a17SJohnny Huang 		printf("Program OTPDATA%X[%X] to 1\n", otp_dw_offset, bit_offset);
2595cd1610b4SJohnny Huang 		break;
2596a6d0d645SJohnny Huang 	case OTP_REGION_STRAP:
2597cd1610b4SJohnny Huang 		otp_strp_status(otpstrap);
2598cd1610b4SJohnny Huang 		otp_print_strap(bit_offset, 1);
2599cd1610b4SJohnny Huang 		if (bit_offset < 32) {
2600cd1610b4SJohnny Huang 			strap_buf[0] = value << bit_offset;
2601cd1610b4SJohnny Huang 			strap_buf[2] = ~BIT(bit_offset);
2602cd1610b4SJohnny Huang 			strap_buf[3] = ~0;
2603cd1610b4SJohnny Huang 			strap_buf[5] = 0;
26042a856b9aSJohnny Huang 			// if (protect)
26052a856b9aSJohnny Huang 			// 	strap_buf[4] = BIT(bit_offset);
26062a856b9aSJohnny Huang 			// else
26072a856b9aSJohnny Huang 			// 	strap_buf[4] = 0;
2608cd1610b4SJohnny Huang 		} else {
2609cd1610b4SJohnny Huang 			strap_buf[1] = value << (bit_offset - 32);
2610cd1610b4SJohnny Huang 			strap_buf[2] = ~0;
2611cd1610b4SJohnny Huang 			strap_buf[3] = ~BIT(bit_offset - 32);
2612cd1610b4SJohnny Huang 			strap_buf[4] = 0;
26132a856b9aSJohnny Huang 			// if (protect)
26142a856b9aSJohnny Huang 			// 	strap_buf[5] = BIT(bit_offset - 32);
26152a856b9aSJohnny Huang 			// else
26162a856b9aSJohnny Huang 			// 	strap_buf[5] = 0;
2617cd1610b4SJohnny Huang 		}
261876d13988SJohnny Huang 		ret = otp_strap_image_confirm(strap_buf);
2619a6af4a17SJohnny Huang 		if (ret == OTP_FAILURE)
26202a856b9aSJohnny Huang 			return OTP_FAILURE;
2621a6af4a17SJohnny Huang 		else if (ret == OTP_PROG_SKIP)
2622a6af4a17SJohnny Huang 			return OTP_SUCCESS;
2623a6af4a17SJohnny Huang 
2624cd1610b4SJohnny Huang 		break;
2625cd1610b4SJohnny Huang 	}
2626cd1610b4SJohnny Huang 
2627cd1610b4SJohnny Huang 	if (!nconfirm) {
2628cd1610b4SJohnny Huang 		printf("type \"YES\" (no quotes) to continue:\n");
2629cd1610b4SJohnny Huang 		if (!confirm_yesno()) {
2630cd1610b4SJohnny Huang 			printf(" Aborting\n");
26312a856b9aSJohnny Huang 			return OTP_FAILURE;
2632cd1610b4SJohnny Huang 		}
2633cd1610b4SJohnny Huang 	}
2634cd1610b4SJohnny Huang 
2635cd1610b4SJohnny Huang 	switch (mode) {
2636a6d0d645SJohnny Huang 	case OTP_REGION_STRAP:
2637cd1610b4SJohnny Huang 		return otp_prog_strap(strap_buf);
2638a6d0d645SJohnny Huang 	case OTP_REGION_CONF:
2639a6d0d645SJohnny Huang 	case OTP_REGION_DATA:
2640cd1610b4SJohnny Huang 		otp_prog_bit(value, prog_address, bit_offset, 0);
2641cd1610b4SJohnny Huang 		pass = -1;
2642cd1610b4SJohnny Huang 		for (i = 0; i < RETRY; i++) {
2643a6d0d645SJohnny Huang 			if (verify_bit(prog_address, bit_offset, value) != 0) {
2644cd1610b4SJohnny Huang 				otp_prog_bit(value, prog_address, bit_offset, 1);
2645cd1610b4SJohnny Huang 			} else {
2646cd1610b4SJohnny Huang 				pass = 0;
2647cd1610b4SJohnny Huang 				break;
2648cd1610b4SJohnny Huang 			}
2649cd1610b4SJohnny Huang 		}
26502a856b9aSJohnny Huang 		if (pass == 0)
26512a856b9aSJohnny Huang 			return OTP_SUCCESS;
2652cd1610b4SJohnny Huang 	}
2653cd1610b4SJohnny Huang 
26542a856b9aSJohnny Huang 	return OTP_USAGE;
2655cd1610b4SJohnny Huang }
2656cd1610b4SJohnny Huang 
26572a856b9aSJohnny Huang static int do_otpread(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
265869d5fd8fSJohnny Huang {
26592a856b9aSJohnny Huang 	uint32_t offset, count;
26602a856b9aSJohnny Huang 	int ret;
266169d5fd8fSJohnny Huang 
26622a856b9aSJohnny Huang 	if (argc == 4) {
26632a856b9aSJohnny Huang 		offset = simple_strtoul(argv[2], NULL, 16);
26642a856b9aSJohnny Huang 		count = simple_strtoul(argv[3], NULL, 16);
26652a856b9aSJohnny Huang 	} else if (argc == 3) {
26662a856b9aSJohnny Huang 		offset = simple_strtoul(argv[2], NULL, 16);
26672a856b9aSJohnny Huang 		count = 1;
26682a856b9aSJohnny Huang 	} else {
266969d5fd8fSJohnny Huang 		return CMD_RET_USAGE;
267069d5fd8fSJohnny Huang 	}
267169d5fd8fSJohnny Huang 
267269d5fd8fSJohnny Huang 
26732a856b9aSJohnny Huang 	if (!strcmp(argv[1], "conf")) {
267469d5fd8fSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
26752a856b9aSJohnny Huang 		ret = otp_print_config(offset, count);
26762a856b9aSJohnny Huang 	} else if (!strcmp(argv[1], "data")) {
26772a856b9aSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
26782a856b9aSJohnny Huang 		ret = otp_print_data(offset, count);
26792a856b9aSJohnny Huang 	} else if (!strcmp(argv[1], "strap")) {
26802a856b9aSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
26812a856b9aSJohnny Huang 		ret = otp_print_strap(offset, count);
26822a856b9aSJohnny Huang 	} else {
26832a856b9aSJohnny Huang 		return CMD_RET_USAGE;
268469d5fd8fSJohnny Huang 	}
268569d5fd8fSJohnny Huang 
26862a856b9aSJohnny Huang 	if (ret == OTP_SUCCESS)
26872a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
26882a856b9aSJohnny Huang 	else
26892a856b9aSJohnny Huang 		return CMD_RET_USAGE;
26902a856b9aSJohnny Huang 
26912a856b9aSJohnny Huang }
26922a856b9aSJohnny Huang 
26932a856b9aSJohnny Huang static int do_otpprog(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
26942a856b9aSJohnny Huang {
26952a856b9aSJohnny Huang 	phys_addr_t addr;
26962a856b9aSJohnny Huang 	uint32_t byte_size;
26972a856b9aSJohnny Huang 	int ret;
26982a856b9aSJohnny Huang 
26992a856b9aSJohnny Huang 	if (argc == 4) {
27002a856b9aSJohnny Huang 		if (strcmp(argv[1], "f"))
27012a856b9aSJohnny Huang 			return CMD_RET_USAGE;
27022a856b9aSJohnny Huang 		addr = simple_strtoul(argv[2], NULL, 16);
27032a856b9aSJohnny Huang 		byte_size = simple_strtoul(argv[3], NULL, 16);
270469d5fd8fSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
27052a856b9aSJohnny Huang 		ret = do_otp_prog(addr, byte_size, 1);
27062a856b9aSJohnny Huang 	} else if (argc == 3) {
27072a856b9aSJohnny Huang 		addr = simple_strtoul(argv[1], NULL, 16);
27082a856b9aSJohnny Huang 		byte_size = simple_strtoul(argv[2], NULL, 16);
27092a856b9aSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
27102a856b9aSJohnny Huang 		ret = do_otp_prog(addr, byte_size, 0);
27112a856b9aSJohnny Huang 	} else {
27122a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27132a856b9aSJohnny Huang 	}
27142a856b9aSJohnny Huang 
27152a856b9aSJohnny Huang 	if (ret == OTP_SUCCESS)
27162a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
27172a856b9aSJohnny Huang 	else if (ret == OTP_FAILURE)
27182a856b9aSJohnny Huang 		return CMD_RET_FAILURE;
27192a856b9aSJohnny Huang 	else
27202a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27212a856b9aSJohnny Huang }
27222a856b9aSJohnny Huang 
27232a856b9aSJohnny Huang static int do_otppb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
27242a856b9aSJohnny Huang {
27252a856b9aSJohnny Huang 	int mode = 0;
27262a856b9aSJohnny Huang 	int nconfirm = 0;
27272a856b9aSJohnny Huang 	int otp_addr = 0;
27282a856b9aSJohnny Huang 	int bit_offset;
27292a856b9aSJohnny Huang 	int value;
27302a856b9aSJohnny Huang 	int ret;
27312a856b9aSJohnny Huang 
27322a856b9aSJohnny Huang 	if (argc != 4 && argc != 5 && argc != 6)
27332a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27342a856b9aSJohnny Huang 
27352a856b9aSJohnny Huang 	/* Drop the pb cmd */
27362a856b9aSJohnny Huang 	argc--;
27372a856b9aSJohnny Huang 	argv++;
27382a856b9aSJohnny Huang 
27392a856b9aSJohnny Huang 	if (!strcmp(argv[0], "conf"))
2740a6d0d645SJohnny Huang 		mode = OTP_REGION_CONF;
27412a856b9aSJohnny Huang 	else if (!strcmp(argv[0], "strap"))
2742a6d0d645SJohnny Huang 		mode = OTP_REGION_STRAP;
27432a856b9aSJohnny Huang 	else if (!strcmp(argv[0], "data"))
2744a6d0d645SJohnny Huang 		mode = OTP_REGION_DATA;
2745cd1610b4SJohnny Huang 	else
27462a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27472a856b9aSJohnny Huang 
27482a856b9aSJohnny Huang 	/* Drop the region cmd */
27492a856b9aSJohnny Huang 	argc--;
27502a856b9aSJohnny Huang 	argv++;
27512a856b9aSJohnny Huang 
27522a856b9aSJohnny Huang 	if (!strcmp(argv[0], "f")) {
2753cd1610b4SJohnny Huang 		nconfirm = 1;
27542a856b9aSJohnny Huang 		/* Drop the force option */
27552a856b9aSJohnny Huang 		argc--;
27562a856b9aSJohnny Huang 		argv++;
27572a856b9aSJohnny Huang 	}
2758cd1610b4SJohnny Huang 
2759a6d0d645SJohnny Huang 	if (mode == OTP_REGION_STRAP) {
27602a856b9aSJohnny Huang 		bit_offset = simple_strtoul(argv[0], NULL, 16);
27612a856b9aSJohnny Huang 		value = simple_strtoul(argv[1], NULL, 16);
2762cd1610b4SJohnny Huang 		if (bit_offset >= 64)
27632a856b9aSJohnny Huang 			return CMD_RET_USAGE;
2764cd1610b4SJohnny Huang 	} else {
27652a856b9aSJohnny Huang 		otp_addr = simple_strtoul(argv[0], NULL, 16);
27662a856b9aSJohnny Huang 		bit_offset = simple_strtoul(argv[1], NULL, 16);
27672a856b9aSJohnny Huang 		value = simple_strtoul(argv[2], NULL, 16);
2768cd1610b4SJohnny Huang 		if (bit_offset >= 32)
27692a856b9aSJohnny Huang 			return CMD_RET_USAGE;
2770cd1610b4SJohnny Huang 	}
2771cd1610b4SJohnny Huang 	if (value != 0 && value != 1)
27722a856b9aSJohnny Huang 		return CMD_RET_USAGE;
2773cd1610b4SJohnny Huang 
2774cd1610b4SJohnny Huang 	writel(OTP_PASSWD, 0x1e6f2000); //password
27752a856b9aSJohnny Huang 	ret = do_otp_prog_bit(mode, otp_addr, bit_offset, value, nconfirm);
27762a856b9aSJohnny Huang 
27772a856b9aSJohnny Huang 	if (ret == OTP_SUCCESS)
27782a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
27792a856b9aSJohnny Huang 	else if (ret == OTP_FAILURE)
27802a856b9aSJohnny Huang 		return CMD_RET_FAILURE;
27812a856b9aSJohnny Huang 	else
27822a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27832a856b9aSJohnny Huang }
27842a856b9aSJohnny Huang 
27852a856b9aSJohnny Huang static int do_otpcmp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
27862a856b9aSJohnny Huang {
27872a856b9aSJohnny Huang 	phys_addr_t addr;
27882a856b9aSJohnny Huang 	int otp_addr = 0;
27892a856b9aSJohnny Huang 
27902a856b9aSJohnny Huang 	if (argc != 3)
27912a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27922a856b9aSJohnny Huang 
279369d5fd8fSJohnny Huang 	writel(OTP_PASSWD, 0x1e6f2000); //password
27942a856b9aSJohnny Huang 	addr = simple_strtoul(argv[1], NULL, 16);
27952a856b9aSJohnny Huang 	otp_addr = simple_strtoul(argv[2], NULL, 16);
27962a856b9aSJohnny Huang 	if (otp_compare(otp_addr, addr) == 0) {
279769d5fd8fSJohnny Huang 		printf("Compare pass\n");
27982a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
279969d5fd8fSJohnny Huang 	} else {
280069d5fd8fSJohnny Huang 		printf("Compare fail\n");
28012a856b9aSJohnny Huang 		return CMD_RET_FAILURE;
280269d5fd8fSJohnny Huang 	}
280369d5fd8fSJohnny Huang }
280469d5fd8fSJohnny Huang 
280566f2f8e5SJohnny Huang static int do_otpinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
280666f2f8e5SJohnny Huang {
280766f2f8e5SJohnny Huang 	if (argc != 2)
280866f2f8e5SJohnny Huang 		return CMD_RET_USAGE;
280966f2f8e5SJohnny Huang 
281066f2f8e5SJohnny Huang 
281166f2f8e5SJohnny Huang 	if (!strcmp(argv[1], "conf")) {
281266f2f8e5SJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
281366f2f8e5SJohnny Huang 		otp_info_config();
281466f2f8e5SJohnny Huang 	} else if (!strcmp(argv[1], "strap")) {
281566f2f8e5SJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
281676d13988SJohnny Huang 		otp_info_strap();
281766f2f8e5SJohnny Huang 	} else {
281866f2f8e5SJohnny Huang 		return CMD_RET_USAGE;
281966f2f8e5SJohnny Huang 	}
282066f2f8e5SJohnny Huang 
282166f2f8e5SJohnny Huang 	return CMD_RET_SUCCESS;
282266f2f8e5SJohnny Huang }
282366f2f8e5SJohnny Huang 
2824*737ed20bSJohnny Huang static int do_otpprotect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
2825*737ed20bSJohnny Huang {
2826*737ed20bSJohnny Huang 	int input;
2827*737ed20bSJohnny Huang 	int bit_offset;
2828*737ed20bSJohnny Huang 	int prog_address;
2829*737ed20bSJohnny Huang 	int pass;
2830*737ed20bSJohnny Huang 	int i;
2831*737ed20bSJohnny Huang 	if (argc != 3 && argc != 2)
2832*737ed20bSJohnny Huang 		return CMD_RET_USAGE;
2833*737ed20bSJohnny Huang 
2834*737ed20bSJohnny Huang 	if (!strcmp(argv[0], "f")) {
2835*737ed20bSJohnny Huang 		input = simple_strtoul(argv[2], NULL, 16);
2836*737ed20bSJohnny Huang 	} else {
2837*737ed20bSJohnny Huang 		input = simple_strtoul(argv[1], NULL, 16);
2838*737ed20bSJohnny Huang 		printf("OTPSTRAP[%d] will be protected\n", input);
2839*737ed20bSJohnny Huang 		printf("type \"YES\" (no quotes) to continue:\n");
2840*737ed20bSJohnny Huang 		if (!confirm_yesno()) {
2841*737ed20bSJohnny Huang 			printf(" Aborting\n");
2842*737ed20bSJohnny Huang 			return CMD_RET_FAILURE;
2843*737ed20bSJohnny Huang 		}
2844*737ed20bSJohnny Huang 	}
2845*737ed20bSJohnny Huang 
2846*737ed20bSJohnny Huang 	prog_address = 0x800;
2847*737ed20bSJohnny Huang 	if (input < 32) {
2848*737ed20bSJohnny Huang 		bit_offset = input;
2849*737ed20bSJohnny Huang 		prog_address |= 0x60c;
2850*737ed20bSJohnny Huang 	} else if (input < 64) {
2851*737ed20bSJohnny Huang 		bit_offset = input - 32;
2852*737ed20bSJohnny Huang 		prog_address |= 0x60e;
2853*737ed20bSJohnny Huang 	} else {
2854*737ed20bSJohnny Huang 		return CMD_RET_USAGE;
2855*737ed20bSJohnny Huang 	}
2856*737ed20bSJohnny Huang 
2857*737ed20bSJohnny Huang 	if (verify_bit(prog_address, bit_offset, 1) == 0) {
2858*737ed20bSJohnny Huang 		printf("OTPSTRAP[%d] already protected\n", input);
2859*737ed20bSJohnny Huang 	}
2860*737ed20bSJohnny Huang 	otp_prog_bit(1, prog_address, bit_offset, 0);
2861*737ed20bSJohnny Huang 	pass = -1;
2862*737ed20bSJohnny Huang 	for (i = 0; i < RETRY; i++) {
2863*737ed20bSJohnny Huang 		if (verify_bit(prog_address, bit_offset, 1) != 0) {
2864*737ed20bSJohnny Huang 			otp_prog_bit(1, prog_address, bit_offset, 1);
2865*737ed20bSJohnny Huang 		} else {
2866*737ed20bSJohnny Huang 			pass = 0;
2867*737ed20bSJohnny Huang 			break;
2868*737ed20bSJohnny Huang 		}
2869*737ed20bSJohnny Huang 	}
2870*737ed20bSJohnny Huang 	if (pass == 0) {
2871*737ed20bSJohnny Huang 		printf("OTPSTRAP[%d] is protected\n", input);
2872*737ed20bSJohnny Huang 		return CMD_RET_SUCCESS;
2873*737ed20bSJohnny Huang 	}
2874*737ed20bSJohnny Huang 
2875*737ed20bSJohnny Huang 	printf("Protect OTPSTRAP[%d] fail\n", input);
2876*737ed20bSJohnny Huang 	return CMD_RET_FAILURE;
2877*737ed20bSJohnny Huang 
2878*737ed20bSJohnny Huang }
28792a856b9aSJohnny Huang static cmd_tbl_t cmd_otp[] = {
28802a856b9aSJohnny Huang 	U_BOOT_CMD_MKENT(read, 4, 0, do_otpread, "", ""),
2881*737ed20bSJohnny Huang 	U_BOOT_CMD_MKENT(info, 2, 0, do_otpinfo, "", ""),
28822a856b9aSJohnny Huang 	U_BOOT_CMD_MKENT(prog, 4, 0, do_otpprog, "", ""),
28832a856b9aSJohnny Huang 	U_BOOT_CMD_MKENT(pb, 6, 0, do_otppb, "", ""),
2884*737ed20bSJohnny Huang 	U_BOOT_CMD_MKENT(protect, 3, 0, do_otpprotect, "", ""),
28852a856b9aSJohnny Huang 	U_BOOT_CMD_MKENT(cmp, 3, 0, do_otpcmp, "", ""),
28862a856b9aSJohnny Huang };
28872a856b9aSJohnny Huang 
28882a856b9aSJohnny Huang static int do_ast_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
28892a856b9aSJohnny Huang {
28902a856b9aSJohnny Huang 	cmd_tbl_t *cp;
28912a856b9aSJohnny Huang 
28922a856b9aSJohnny Huang 	cp = find_cmd_tbl(argv[1], cmd_otp, ARRAY_SIZE(cmd_otp));
28932a856b9aSJohnny Huang 
2894*737ed20bSJohnny Huang 	/* Drop the otp command */
28952a856b9aSJohnny Huang 	argc--;
28962a856b9aSJohnny Huang 	argv++;
28972a856b9aSJohnny Huang 
28982a856b9aSJohnny Huang 	if (cp == NULL || argc > cp->maxargs)
28992a856b9aSJohnny Huang 		return CMD_RET_USAGE;
29002a856b9aSJohnny Huang 	if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
29012a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
29022a856b9aSJohnny Huang 
29032a856b9aSJohnny Huang 	return cp->cmd(cmdtp, flag, argc, argv);
290469d5fd8fSJohnny Huang }
290569d5fd8fSJohnny Huang 
290669d5fd8fSJohnny Huang U_BOOT_CMD(
290769d5fd8fSJohnny Huang 	otp, 7, 0,  do_ast_otp,
290869d5fd8fSJohnny Huang 	"ASPEED One-Time-Programmable sub-system",
29092a856b9aSJohnny Huang 	"read conf|data <otp_dw_offset> <dw_count>\n"
29102a856b9aSJohnny Huang 	"otp read strap <strap_bit_offset> <bit_count>\n"
291176d13988SJohnny Huang 	"otp info conf|strap\n"
2912d90825e2SJohnny Huang 	"otp prog [f] <addr> <byte_size>\n"
2913cd1610b4SJohnny Huang 	"otp pb conf|data [f] <otp_dw_offset> <bit_offset> <value>\n"
2914*737ed20bSJohnny Huang 	"otp pb strap [f] <bit_offset> <value>\n"
2915*737ed20bSJohnny Huang 	"otp protect [f] <bit_offset>\n"
29162a856b9aSJohnny Huang 	"otp cmp <addr> <otp_dw_offset>\n"
291769d5fd8fSJohnny Huang );
2918