xref: /openbmc/u-boot/cmd/otp.c (revision 76d13988cc59fb18d0e099ebd12fa6c242e739df)
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 
82*76d13988SJohnny Huang #define ENABLE_SECURE_BOOT(x)			(x & 0x1)
83*76d13988SJohnny Huang #define BOOT_FROM_EMMC(x)			((x >> 1) & 0x1)
84*76d13988SJohnny Huang #define BOOT_FROM_DEBUG_SPI(x)			((x >> 2) & 0x1)
85*76d13988SJohnny Huang #define DISABLE_ARM_CM3(x)			((x >> 3) & 0x1)
86*76d13988SJohnny Huang #define VGA_EXPANSION_ROM(x)			((x >> 4) & 0x1)
87*76d13988SJohnny Huang #define MAC1_RMII_MODE(x)			((x >> 5) & 0x1)
88*76d13988SJohnny Huang #define MAC2_RMII_MODE(x)			((x >> 6) & 0x1)
89*76d13988SJohnny Huang #define CPU_FREQUENCY(x)			((x >> 7) & 0x7)
90*76d13988SJohnny Huang #define HCLK_RATIO(x)				((x >> 10) & 0x3)
91*76d13988SJohnny Huang #define VGA_MEMORY_SIZE(x)			((x >> 12) & 0x3)
92*76d13988SJohnny Huang #define VGA_CLASS_CODE(x)			((x >> 17) & 0x1)
93*76d13988SJohnny Huang #define DISABLE_DEBUG0(x)			((x >> 18) & 0x1)
94*76d13988SJohnny Huang #define BOOT_FROM_EMMC_SPEED_MDOE(x)		((x >> 19) & 0x1)
95*76d13988SJohnny Huang #define DISABLE_PCIE_EHCI(x)			((x >> 20) & 0x1)
96*76d13988SJohnny Huang #define DISABLE_VGA_XDMA(x)			((x >> 21) & 0x1)
97*76d13988SJohnny Huang #define DISABLE_DEDICATED_BMC_FUNCTION(x)	((x >> 22) & 0x1)
98*76d13988SJohnny Huang #define DEDICATE_ROOT_COMPLEX_RELAX(x)		((x >> 23) & 0x1)
99*76d13988SJohnny Huang #define SELECT_DRAM_TYPES(x)			((x >> 24) & 0x1)
100*76d13988SJohnny Huang #define MAC3_RMII_MODE(x)			(x & 0x1)
101*76d13988SJohnny Huang #define MAC4_RMII_MODE(x)			((x >> 1) & 0x1)
102*76d13988SJohnny Huang #define SIO_CONF_ADDR(x)			((x >> 2) & 0x1)
103*76d13988SJohnny Huang #define DISABLE_SIO(x)				((x >> 3) & 0x1)
104*76d13988SJohnny Huang #define DISABLE_DEBUG1(x)			((x >> 4) & 0x1)
105*76d13988SJohnny Huang #define ENABLE_ACPI(x)				((x >> 5) & 0x1)
106*76d13988SJohnny Huang #define SELECT_LPC(x)				((x >> 6) & 0x1)
107*76d13988SJohnny Huang #define ENABLE_SAFS(x)				((x >> 7) & 0x1)
108*76d13988SJohnny Huang #define ENABLE_SPI_3B4B_AUTO(x)			((x >> 10) & 0x1)
109*76d13988SJohnny Huang #define ENABLE_BOOT_SPI_ABR(x)			((x >> 11) & 0x1)
110*76d13988SJohnny Huang #define BOOT_SPI_ABR_MODE(x)			((x >> 12) & 0x1)
111*76d13988SJohnny Huang #define BOOT_SPI_FLASH_SIZE(x)			((x >> 13) & 0x7)
112*76d13988SJohnny Huang #define ENABLE_HOST_SPI_ABR(x)			((x >> 16) & 0x1)
113*76d13988SJohnny Huang #define EBABLE_HOST_SPI_ABR_SEL_PIN(x)		((x >> 17) & 0x1)
114*76d13988SJohnny Huang #define HOST_SPI_ABR_MODE(x)			((x >> 18) & 0x1)
115*76d13988SJohnny Huang #define HOST_SPI_FLASH_SIZE(x)			((x >> 19) & 0x7)
116*76d13988SJohnny Huang #define ENABLE_BOOT_SPI_AUX_CONTROL_PIN(x)	((x >> 22) & 0x1)
117*76d13988SJohnny Huang #define BOOT_SPI_CRTM_SIZE(x)			((x >> 23) & 0x3)
118*76d13988SJohnny Huang #define HOST_SPI_CRTM_SIZE(x)			((x >> 25) & 0x3)
119*76d13988SJohnny Huang #define ENABLE_HOST_SPI_AUX_CONTROL_PIN(x)	((x >> 27) & 0x1)
120*76d13988SJohnny Huang #define ENABLE_GPIO_PASS_THROUGH(x)		((x >> 28) & 0x1)
121*76d13988SJohnny Huang #define DISABLE_LOW_SECURITY_KEY(x)		((x >> 29) & 0x1)
122*76d13988SJohnny Huang #define ENABLE_DEDICATE_GPIO_STRAP(x)		((x >> 30) & 0x1)
123*76d13988SJohnny Huang 
124*76d13988SJohnny 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 
162*76d13988SJohnny Huang struct otpstrap_parse {
163*76d13988SJohnny Huang 	int bit;
164*76d13988SJohnny Huang 	int length;
165*76d13988SJohnny Huang 	int value;
166*76d13988SJohnny Huang 	int keep;
167*76d13988SJohnny Huang 	int protect;
168*76d13988SJohnny Huang 	char status[80];
169*76d13988SJohnny Huang };
170*76d13988SJohnny 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 
377*76d13988SJohnny Huang 
378*76d13988SJohnny Huang static void otp_strp_status(struct otpstrap_status *otpstrap)
379*76d13988SJohnny Huang {
380*76d13988SJohnny Huang 	uint32_t OTPSTRAP_RAW[2];
381*76d13988SJohnny Huang 	int i, j;
382*76d13988SJohnny Huang 
383*76d13988SJohnny Huang 	for (j = 0; j < 64; j++) {
384*76d13988SJohnny Huang 		otpstrap[j].value = 0;
385*76d13988SJohnny Huang 		otpstrap[j].remain_times = 7;
386*76d13988SJohnny Huang 		otpstrap[j].writeable_option = -1;
387*76d13988SJohnny Huang 		otpstrap[j].protected = 0;
388*76d13988SJohnny Huang 	}
389*76d13988SJohnny Huang 
390*76d13988SJohnny Huang 	for (i = 16; i < 30; i += 2) {
391*76d13988SJohnny Huang 		int option = (i - 16) / 2;
392*76d13988SJohnny Huang 		otp_read_config(i, &OTPSTRAP_RAW[0]);
393*76d13988SJohnny Huang 		otp_read_config(i + 1, &OTPSTRAP_RAW[1]);
394*76d13988SJohnny Huang 		for (j = 0; j < 32; j++) {
395*76d13988SJohnny Huang 			char bit_value = ((OTPSTRAP_RAW[0] >> j) & 0x1);
396*76d13988SJohnny Huang 			if ((bit_value == 0) && (otpstrap[j].writeable_option == -1)) {
397*76d13988SJohnny Huang 				otpstrap[j].writeable_option = option;
398*76d13988SJohnny Huang 			}
399*76d13988SJohnny Huang 			if (bit_value == 1)
400*76d13988SJohnny Huang 				otpstrap[j].remain_times --;
401*76d13988SJohnny Huang 			otpstrap[j].value ^= bit_value;
402*76d13988SJohnny Huang 			otpstrap[j].option_array[option] = bit_value;
403*76d13988SJohnny Huang 		}
404*76d13988SJohnny Huang 		for (j = 32; j < 64; j++) {
405*76d13988SJohnny Huang 			char bit_value = ((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1);
406*76d13988SJohnny Huang 			if ((bit_value == 0) && (otpstrap[j].writeable_option == -1)) {
407*76d13988SJohnny Huang 				otpstrap[j].writeable_option = option;
408*76d13988SJohnny Huang 			}
409*76d13988SJohnny Huang 			if (bit_value == 1)
410*76d13988SJohnny Huang 				otpstrap[j].remain_times --;
411*76d13988SJohnny Huang 			otpstrap[j].value ^= bit_value;
412*76d13988SJohnny Huang 			otpstrap[j].option_array[option] = bit_value;
413*76d13988SJohnny Huang 		}
414*76d13988SJohnny Huang 	}
415*76d13988SJohnny Huang 	otp_read_config(30, &OTPSTRAP_RAW[0]);
416*76d13988SJohnny Huang 	otp_read_config(31, &OTPSTRAP_RAW[1]);
417*76d13988SJohnny Huang 	for (j = 0; j < 32; j++) {
418*76d13988SJohnny Huang 		if (((OTPSTRAP_RAW[0] >> j) & 0x1) == 1)
419*76d13988SJohnny Huang 			otpstrap[j].protected = 1;
420*76d13988SJohnny Huang 	}
421*76d13988SJohnny Huang 	for (j = 32; j < 64; j++) {
422*76d13988SJohnny Huang 		if (((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1) == 1)
423*76d13988SJohnny Huang 			otpstrap[j].protected = 1;
424*76d13988SJohnny Huang 	}
425*76d13988SJohnny Huang }
426*76d13988SJohnny 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 
991*76d13988SJohnny Huang static int otp_strap_parse(uint32_t *OTPSTRAP,
992*76d13988SJohnny Huang 			   struct otpstrap_parse *strap_parse)
993*76d13988SJohnny Huang {
994*76d13988SJohnny Huang 	int k = 0;
995*76d13988SJohnny Huang 	uint32_t *OTPSTRAP_KEEP = &OTPSTRAP[2];
996*76d13988SJohnny Huang 	uint32_t *OTPSTRAP_PRO = &OTPSTRAP[4];
997*76d13988SJohnny Huang 
998*76d13988SJohnny Huang 	strap_parse[k].bit = 0;
999*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1000*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_SECURE_BOOT(OTPSTRAP[0]);
1001*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_SECURE_BOOT(OTPSTRAP_PRO[0]);
1002*76d13988SJohnny Huang 	if (ENABLE_SECURE_BOOT(OTPSTRAP_KEEP[0])) {
1003*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1004*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1005*76d13988SJohnny Huang 	} else {
1006*76d13988SJohnny Huang 		if (ENABLE_SECURE_BOOT(OTPSTRAP[0]))
1007*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1008*76d13988SJohnny Huang 			       "Enable secure boot");
1009*76d13988SJohnny Huang 		else
1010*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1011*76d13988SJohnny Huang 			       "Disable secure boot");
1012*76d13988SJohnny Huang 	}
1013*76d13988SJohnny Huang 
1014*76d13988SJohnny Huang 	k++;
1015*76d13988SJohnny Huang 	strap_parse[k].bit = 1;
1016*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1017*76d13988SJohnny Huang 	strap_parse[k].value = BOOT_FROM_EMMC(OTPSTRAP[0]);
1018*76d13988SJohnny Huang 	strap_parse[k].protect = BOOT_FROM_EMMC(OTPSTRAP_PRO[0]);
1019*76d13988SJohnny Huang 	if (BOOT_FROM_EMMC(OTPSTRAP_KEEP[0])) {
1020*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1021*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1022*76d13988SJohnny Huang 	} else {
1023*76d13988SJohnny Huang 		if (BOOT_FROM_EMMC(OTPSTRAP[0]))
1024*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1025*76d13988SJohnny Huang 			       "Enable boot from eMMC");
1026*76d13988SJohnny Huang 		else
1027*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1028*76d13988SJohnny Huang 			       "Disable boot from eMMC");
1029*76d13988SJohnny Huang 	}
1030*76d13988SJohnny Huang 
1031*76d13988SJohnny Huang 	k++;
1032*76d13988SJohnny Huang 	strap_parse[k].bit = 2;
1033*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1034*76d13988SJohnny Huang 	strap_parse[k].value = BOOT_FROM_DEBUG_SPI(OTPSTRAP[0]);
1035*76d13988SJohnny Huang 	strap_parse[k].protect = BOOT_FROM_DEBUG_SPI(OTPSTRAP_PRO[0]);
1036*76d13988SJohnny Huang 	if (BOOT_FROM_DEBUG_SPI(OTPSTRAP_KEEP[0])) {
1037*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1038*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1039*76d13988SJohnny Huang 	} else {
1040*76d13988SJohnny Huang 		if (BOOT_FROM_DEBUG_SPI(OTPSTRAP[0]))
1041*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1042*76d13988SJohnny Huang 			       "Enable Boot from debug SPI");
1043*76d13988SJohnny Huang 		else
1044*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1045*76d13988SJohnny Huang 			       "Disable Boot from debug SPI");
1046*76d13988SJohnny Huang 	}
1047*76d13988SJohnny Huang 
1048*76d13988SJohnny Huang 	k++;
1049*76d13988SJohnny Huang 	strap_parse[k].bit = 3;
1050*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1051*76d13988SJohnny Huang 	strap_parse[k].value = DISABLE_ARM_CM3(OTPSTRAP[0]);
1052*76d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_ARM_CM3(OTPSTRAP_PRO[0]);
1053*76d13988SJohnny Huang 	if (DISABLE_ARM_CM3(OTPSTRAP_KEEP[0])) {
1054*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1055*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1056*76d13988SJohnny Huang 	} else {
1057*76d13988SJohnny Huang 		if (DISABLE_ARM_CM3(OTPSTRAP[0]))
1058*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1059*76d13988SJohnny Huang 			       "Disable ARM CM3");
1060*76d13988SJohnny Huang 		else
1061*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1062*76d13988SJohnny Huang 			       "Enable ARM CM3");
1063*76d13988SJohnny Huang 	}
1064*76d13988SJohnny Huang 
1065*76d13988SJohnny Huang 	k++;
1066*76d13988SJohnny Huang 	strap_parse[k].bit = 4;
1067*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1068*76d13988SJohnny Huang 	strap_parse[k].value = VGA_EXPANSION_ROM(OTPSTRAP[0]);
1069*76d13988SJohnny Huang 	strap_parse[k].protect = VGA_EXPANSION_ROM(OTPSTRAP_PRO[0]);
1070*76d13988SJohnny Huang 	if (VGA_EXPANSION_ROM(OTPSTRAP_KEEP[0])) {
1071*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1072*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1073*76d13988SJohnny Huang 	} else {
1074*76d13988SJohnny Huang 		if (VGA_EXPANSION_ROM(OTPSTRAP[0]))
1075*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1076*76d13988SJohnny Huang 			       "Enable dedicated VGA BIOS ROM");
1077*76d13988SJohnny Huang 		else
1078*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1079*76d13988SJohnny Huang 			       "No VGA BISO ROM, VGA BIOS is merged in the system BIOS");
1080*76d13988SJohnny Huang 	}
1081*76d13988SJohnny Huang 
1082*76d13988SJohnny Huang 	k++;
1083*76d13988SJohnny Huang 	strap_parse[k].bit = 5;
1084*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1085*76d13988SJohnny Huang 	strap_parse[k].value = MAC1_RMII_MODE(OTPSTRAP[0]);
1086*76d13988SJohnny Huang 	strap_parse[k].protect = MAC1_RMII_MODE(OTPSTRAP_PRO[0]);
1087*76d13988SJohnny Huang 	if (MAC1_RMII_MODE(OTPSTRAP_KEEP[0])) {
1088*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1089*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1090*76d13988SJohnny Huang 	} else {
1091*76d13988SJohnny Huang 		if (MAC1_RMII_MODE(OTPSTRAP[0]))
1092*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1093*76d13988SJohnny Huang 			       "MAC 1 : RGMII");
1094*76d13988SJohnny Huang 		else
1095*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1096*76d13988SJohnny Huang 			       "MAC 1 : RMII/NCSI");
1097*76d13988SJohnny Huang 	}
1098*76d13988SJohnny Huang 
1099*76d13988SJohnny Huang 	k++;
1100*76d13988SJohnny Huang 	strap_parse[k].bit = 6;
1101*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1102*76d13988SJohnny Huang 	strap_parse[k].value = MAC2_RMII_MODE(OTPSTRAP[0]);
1103*76d13988SJohnny Huang 	strap_parse[k].protect = MAC2_RMII_MODE(OTPSTRAP_PRO[0]);
1104*76d13988SJohnny Huang 	if (MAC2_RMII_MODE(OTPSTRAP_KEEP[0])) {
1105*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1106*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1107*76d13988SJohnny Huang 	} else {
1108*76d13988SJohnny Huang 		if (MAC2_RMII_MODE(OTPSTRAP[0]))
1109*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1110*76d13988SJohnny Huang 			       "MAC 2 : RGMII");
1111*76d13988SJohnny Huang 		else
1112*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1113*76d13988SJohnny Huang 			       "MAC 2 : RMII/NCSI");
1114*76d13988SJohnny Huang 	}
1115*76d13988SJohnny Huang 
1116*76d13988SJohnny Huang 	k++;
1117*76d13988SJohnny Huang 	strap_parse[k].bit = 7;
1118*76d13988SJohnny Huang 	strap_parse[k].length = 3;
1119*76d13988SJohnny Huang 	strap_parse[k].value = CPU_FREQUENCY(OTPSTRAP[0]);
1120*76d13988SJohnny Huang 	strap_parse[k].protect = CPU_FREQUENCY(OTPSTRAP_PRO[0]);
1121*76d13988SJohnny Huang 	if (CPU_FREQUENCY(OTPSTRAP_KEEP[0]) == 0x7) {
1122*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1123*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1124*76d13988SJohnny Huang 	} else if (CPU_FREQUENCY(OTPSTRAP_KEEP[0]) == 0) {
1125*76d13988SJohnny Huang 		if (CPU_FREQUENCY(OTPSTRAP[0]) == 0) {
1126*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1127*76d13988SJohnny Huang 			       "CPU Frequency : 1GHz");
1128*76d13988SJohnny Huang 		} else if (CPU_FREQUENCY(OTPSTRAP[0]) == 1) {
1129*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1130*76d13988SJohnny Huang 			       "CPU Frequency : 800MHz");
1131*76d13988SJohnny Huang 		} else if (CPU_FREQUENCY(OTPSTRAP[0]) == 2) {
1132*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1133*76d13988SJohnny Huang 			       "CPU Frequency : 1.2GHz");
1134*76d13988SJohnny Huang 		} else if (CPU_FREQUENCY(OTPSTRAP[0]) == 3) {
1135*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1136*76d13988SJohnny Huang 			       "CPU Frequency : 1.4GHz");
1137*76d13988SJohnny Huang 		} else {
1138*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1139*76d13988SJohnny Huang 			       "CPU Frequency : error");
1140*76d13988SJohnny Huang 			return -1;
1141*76d13988SJohnny Huang 		}
1142*76d13988SJohnny Huang 	} else {
1143*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
1144*76d13988SJohnny Huang 		return -1;
1145*76d13988SJohnny Huang 	}
1146*76d13988SJohnny Huang 
1147*76d13988SJohnny Huang 	k++;
1148*76d13988SJohnny Huang 	strap_parse[k].bit = 10;
1149*76d13988SJohnny Huang 	strap_parse[k].length = 2;
1150*76d13988SJohnny Huang 	strap_parse[k].value = HCLK_RATIO(OTPSTRAP[0]);
1151*76d13988SJohnny Huang 	strap_parse[k].protect = HCLK_RATIO(OTPSTRAP_PRO[0]);
1152*76d13988SJohnny Huang 	if (HCLK_RATIO(OTPSTRAP_KEEP[0]) == 0x3) {
1153*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1154*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1155*76d13988SJohnny Huang 	} else if (HCLK_RATIO(OTPSTRAP_KEEP[0]) == 0) {
1156*76d13988SJohnny Huang 		if (HCLK_RATIO(OTPSTRAP[0]) == 0) {
1157*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1158*76d13988SJohnny Huang 			       "HCLK ratio AXI:AHB = 2:1");
1159*76d13988SJohnny Huang 		} else if (HCLK_RATIO(OTPSTRAP[0]) == 1) {
1160*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1161*76d13988SJohnny Huang 			       "HCLK ratio AXI:AHB = 2:1");
1162*76d13988SJohnny Huang 		} else if (HCLK_RATIO(OTPSTRAP[0]) == 2) {
1163*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1164*76d13988SJohnny Huang 			       "HCLK ratio AXI:AHB = 3:1");
1165*76d13988SJohnny Huang 		} else if (HCLK_RATIO(OTPSTRAP[0]) == 3) {
1166*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1167*76d13988SJohnny Huang 			       "HCLK ratio AXI:AHB = 4:1");
1168*76d13988SJohnny Huang 		}
1169*76d13988SJohnny Huang 	} else {
1170*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
1171*76d13988SJohnny Huang 		return -1;
1172*76d13988SJohnny Huang 	}
1173*76d13988SJohnny Huang 
1174*76d13988SJohnny Huang 	k++;
1175*76d13988SJohnny Huang 	strap_parse[k].bit = 12;
1176*76d13988SJohnny Huang 	strap_parse[k].length = 2;
1177*76d13988SJohnny Huang 	strap_parse[k].value = VGA_MEMORY_SIZE(OTPSTRAP[0]);
1178*76d13988SJohnny Huang 	strap_parse[k].protect = VGA_MEMORY_SIZE(OTPSTRAP_PRO[0]);
1179*76d13988SJohnny Huang 	if (VGA_MEMORY_SIZE(OTPSTRAP_KEEP[0]) == 0x3) {
1180*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1181*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1182*76d13988SJohnny Huang 	} else if (VGA_MEMORY_SIZE(OTPSTRAP_KEEP[0]) == 0) {
1183*76d13988SJohnny Huang 		if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 0) {
1184*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1185*76d13988SJohnny Huang 			       "VGA memory size : 8MB");
1186*76d13988SJohnny Huang 		} else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 1) {
1187*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1188*76d13988SJohnny Huang 			       "VGA memory size : 16MB");
1189*76d13988SJohnny Huang 		} else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 2) {
1190*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1191*76d13988SJohnny Huang 			       "VGA memory size : 32MB");
1192*76d13988SJohnny Huang 		} else if (VGA_MEMORY_SIZE(OTPSTRAP[0]) == 3) {
1193*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1194*76d13988SJohnny Huang 			       "VGA memory size : 64MB");
1195*76d13988SJohnny Huang 		}
1196*76d13988SJohnny Huang 	} else {
1197*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
1198*76d13988SJohnny Huang 		return -1;
1199*76d13988SJohnny Huang 	}
1200*76d13988SJohnny Huang 
1201*76d13988SJohnny Huang 	k++;
1202*76d13988SJohnny Huang 	strap_parse[k].bit = 17;
1203*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1204*76d13988SJohnny Huang 	strap_parse[k].value = VGA_CLASS_CODE(OTPSTRAP[0]);
1205*76d13988SJohnny Huang 	strap_parse[k].protect = VGA_CLASS_CODE(OTPSTRAP_PRO[0]);
1206*76d13988SJohnny Huang 	if (VGA_CLASS_CODE(OTPSTRAP_KEEP[0])) {
1207*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1208*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1209*76d13988SJohnny Huang 	} else {
1210*76d13988SJohnny Huang 		if (VGA_CLASS_CODE(OTPSTRAP[0]))
1211*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1212*76d13988SJohnny Huang 			       "VGA class code : Class Code for VGA device");
1213*76d13988SJohnny Huang 		else
1214*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1215*76d13988SJohnny Huang 			       "VGA class code : Class Code for video device");
1216*76d13988SJohnny Huang 	}
1217*76d13988SJohnny Huang 
1218*76d13988SJohnny Huang 	k++;
1219*76d13988SJohnny Huang 	strap_parse[k].bit = 18;
1220*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1221*76d13988SJohnny Huang 	strap_parse[k].value = DISABLE_DEBUG0(OTPSTRAP[0]);
1222*76d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_DEBUG0(OTPSTRAP_PRO[0]);
1223*76d13988SJohnny Huang 	if (DISABLE_DEBUG0(OTPSTRAP_KEEP[0])) {
1224*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1225*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1226*76d13988SJohnny Huang 	} else {
1227*76d13988SJohnny Huang 		if (DISABLE_DEBUG0(OTPSTRAP[0]))
1228*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1229*76d13988SJohnny Huang 			       "Disable debug interfaces 0");
1230*76d13988SJohnny Huang 		else
1231*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1232*76d13988SJohnny Huang 			       "Enable debug interfaces 0");
1233*76d13988SJohnny Huang 	}
1234*76d13988SJohnny Huang 
1235*76d13988SJohnny Huang 	k++;
1236*76d13988SJohnny Huang 	strap_parse[k].bit = 19;
1237*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1238*76d13988SJohnny Huang 	strap_parse[k].value = BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP[0]);
1239*76d13988SJohnny Huang 	strap_parse[k].protect = BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP_PRO[0]);
1240*76d13988SJohnny Huang 	if (BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP_KEEP[0])) {
1241*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1242*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1243*76d13988SJohnny Huang 	} else {
1244*76d13988SJohnny Huang 		if (BOOT_FROM_EMMC_SPEED_MDOE(OTPSTRAP[0]))
1245*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1246*76d13988SJohnny Huang 			       "Boot from emmc mode : Normal eMMC speed");
1247*76d13988SJohnny Huang 		else
1248*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1249*76d13988SJohnny Huang 			       "Boot from emmc mode : High eMMC speed");
1250*76d13988SJohnny Huang 	}
1251*76d13988SJohnny Huang 
1252*76d13988SJohnny Huang 	k++;
1253*76d13988SJohnny Huang 	strap_parse[k].bit = 20;
1254*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1255*76d13988SJohnny Huang 	strap_parse[k].value = DISABLE_PCIE_EHCI(OTPSTRAP[0]);
1256*76d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_PCIE_EHCI(OTPSTRAP_PRO[0]);
1257*76d13988SJohnny Huang 	if (DISABLE_PCIE_EHCI(OTPSTRAP_KEEP[0])) {
1258*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1259*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1260*76d13988SJohnny Huang 	} else {
1261*76d13988SJohnny Huang 		if (DISABLE_PCIE_EHCI(OTPSTRAP[0]))
1262*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1263*76d13988SJohnny Huang 			       "Disable Pcie EHCI device");
1264*76d13988SJohnny Huang 		else
1265*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1266*76d13988SJohnny Huang 			       "Enable Pcie EHCI device");
1267*76d13988SJohnny Huang 	}
1268*76d13988SJohnny Huang 
1269*76d13988SJohnny Huang 	k++;
1270*76d13988SJohnny Huang 	strap_parse[k].bit = 21;
1271*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1272*76d13988SJohnny Huang 	strap_parse[k].value = DISABLE_VGA_XDMA(OTPSTRAP[0]);
1273*76d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_VGA_XDMA(OTPSTRAP_PRO[0]);
1274*76d13988SJohnny Huang 	if (DISABLE_VGA_XDMA(OTPSTRAP_KEEP[0])) {
1275*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1276*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1277*76d13988SJohnny Huang 	} else {
1278*76d13988SJohnny Huang 		if (DISABLE_VGA_XDMA(OTPSTRAP[0]))
1279*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1280*76d13988SJohnny Huang 			       "Disable VGA XDMA function");
1281*76d13988SJohnny Huang 		else
1282*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1283*76d13988SJohnny Huang 			       "Enable VGA XDMA function");
1284*76d13988SJohnny Huang 	}
1285*76d13988SJohnny Huang 
1286*76d13988SJohnny Huang 	k++;
1287*76d13988SJohnny Huang 	strap_parse[k].bit = 22;
1288*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1289*76d13988SJohnny Huang 	strap_parse[k].value = DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP[0]);
1290*76d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP_PRO[0]);
1291*76d13988SJohnny Huang 	if (DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP_KEEP[0])) {
1292*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1293*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1294*76d13988SJohnny Huang 	} else {
1295*76d13988SJohnny Huang 		if (DISABLE_DEDICATED_BMC_FUNCTION(OTPSTRAP[0]))
1296*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1297*76d13988SJohnny Huang 			       "Disable dedicated BMC functions for non-BMC application");
1298*76d13988SJohnny Huang 		else
1299*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1300*76d13988SJohnny Huang 			       "Normal BMC mode");
1301*76d13988SJohnny Huang 	}
1302*76d13988SJohnny Huang 
1303*76d13988SJohnny Huang 	k++;
1304*76d13988SJohnny Huang 	strap_parse[k].bit = 23;
1305*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1306*76d13988SJohnny Huang 	strap_parse[k].value = DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP[0]);
1307*76d13988SJohnny Huang 	strap_parse[k].protect = DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP_PRO[0]);
1308*76d13988SJohnny Huang 	if (DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP_KEEP[0])) {
1309*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1310*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1311*76d13988SJohnny Huang 	} else {
1312*76d13988SJohnny Huang 		if (DEDICATE_ROOT_COMPLEX_RELAX(OTPSTRAP[0]))
1313*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1314*76d13988SJohnny Huang 			       "SSPRST# pin is for PCIE root complex dedicated reset pin");
1315*76d13988SJohnny Huang 		else
1316*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1317*76d13988SJohnny Huang 			       "SSPRST# pin is for secondary processor dedicated reset pin");
1318*76d13988SJohnny Huang 	}
1319*76d13988SJohnny Huang 
1320*76d13988SJohnny Huang 	k++;
1321*76d13988SJohnny Huang 	strap_parse[k].bit = 24;
1322*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1323*76d13988SJohnny Huang 	strap_parse[k].value = SELECT_DRAM_TYPES(OTPSTRAP[0]);
1324*76d13988SJohnny Huang 	strap_parse[k].protect = SELECT_DRAM_TYPES(OTPSTRAP_PRO[0]);
1325*76d13988SJohnny Huang 	if (SELECT_DRAM_TYPES(OTPSTRAP_KEEP[0])) {
1326*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1327*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1328*76d13988SJohnny Huang 	} else {
1329*76d13988SJohnny Huang 		if (SELECT_DRAM_TYPES(OTPSTRAP[0]))
1330*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1331*76d13988SJohnny Huang 			       "DRAM types : DDR4");
1332*76d13988SJohnny Huang 		else
1333*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1334*76d13988SJohnny Huang 			       "DRAM types : DDR3");
1335*76d13988SJohnny Huang 	}
1336*76d13988SJohnny Huang 
1337*76d13988SJohnny Huang 	k++;
1338*76d13988SJohnny Huang 	strap_parse[k].bit = 32;
1339*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1340*76d13988SJohnny Huang 	strap_parse[k].value = MAC3_RMII_MODE(OTPSTRAP[1]);
1341*76d13988SJohnny Huang 	strap_parse[k].protect = MAC3_RMII_MODE(OTPSTRAP_PRO[1]);
1342*76d13988SJohnny Huang 	if (MAC3_RMII_MODE(OTPSTRAP_KEEP[1])) {
1343*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1344*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1345*76d13988SJohnny Huang 	} else {
1346*76d13988SJohnny Huang 		if (MAC3_RMII_MODE(OTPSTRAP[1]))
1347*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1348*76d13988SJohnny Huang 			       "MAC 3 : RGMII");
1349*76d13988SJohnny Huang 		else
1350*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1351*76d13988SJohnny Huang 			       "MAC 3 : RMII/NCSI");
1352*76d13988SJohnny Huang 	}
1353*76d13988SJohnny Huang 
1354*76d13988SJohnny Huang 	k++;
1355*76d13988SJohnny Huang 	strap_parse[k].bit = 33;
1356*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1357*76d13988SJohnny Huang 	strap_parse[k].value = MAC4_RMII_MODE(OTPSTRAP[1]);
1358*76d13988SJohnny Huang 	strap_parse[k].protect = MAC4_RMII_MODE(OTPSTRAP_PRO[1]);
1359*76d13988SJohnny Huang 	if (MAC4_RMII_MODE(OTPSTRAP_KEEP[1])) {
1360*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1361*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1362*76d13988SJohnny Huang 	} else {
1363*76d13988SJohnny Huang 		if (MAC4_RMII_MODE(OTPSTRAP[1]))
1364*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1365*76d13988SJohnny Huang 			       "MAC 4 : RGMII");
1366*76d13988SJohnny Huang 		else
1367*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1368*76d13988SJohnny Huang 			       "MAC 4 : RMII/NCSI");
1369*76d13988SJohnny Huang 	}
1370*76d13988SJohnny Huang 
1371*76d13988SJohnny Huang 	k++;
1372*76d13988SJohnny Huang 	strap_parse[k].bit = 34;
1373*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1374*76d13988SJohnny Huang 	strap_parse[k].value = SIO_CONF_ADDR(OTPSTRAP[1]);
1375*76d13988SJohnny Huang 	strap_parse[k].protect = SIO_CONF_ADDR(OTPSTRAP_PRO[1]);
1376*76d13988SJohnny Huang 	if (SIO_CONF_ADDR(OTPSTRAP_KEEP[1])) {
1377*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1378*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1379*76d13988SJohnny Huang 	} else {
1380*76d13988SJohnny Huang 		if (SIO_CONF_ADDR(OTPSTRAP[1]))
1381*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1382*76d13988SJohnny Huang 			       "SuperIO configuration address : 0x4E");
1383*76d13988SJohnny Huang 		else
1384*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1385*76d13988SJohnny Huang 			       "SuperIO configuration address : 0x2E");
1386*76d13988SJohnny Huang 	}
1387*76d13988SJohnny Huang 
1388*76d13988SJohnny Huang 	k++;
1389*76d13988SJohnny Huang 	strap_parse[k].bit = 35;
1390*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1391*76d13988SJohnny Huang 	strap_parse[k].value = DISABLE_SIO(OTPSTRAP[1]);
1392*76d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_SIO(OTPSTRAP_PRO[1]);
1393*76d13988SJohnny Huang 	if (DISABLE_SIO(OTPSTRAP_KEEP[1])) {
1394*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1395*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1396*76d13988SJohnny Huang 	} else {
1397*76d13988SJohnny Huang 		if (DISABLE_SIO(OTPSTRAP[1]))
1398*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1399*76d13988SJohnny Huang 			       "Disable LPC to decode SuperIO");
1400*76d13988SJohnny Huang 		else
1401*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1402*76d13988SJohnny Huang 			       "Enable LPC to decode SuperIO");
1403*76d13988SJohnny Huang 	}
1404*76d13988SJohnny Huang 
1405*76d13988SJohnny Huang 	k++;
1406*76d13988SJohnny Huang 	strap_parse[k].bit = 36;
1407*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1408*76d13988SJohnny Huang 	strap_parse[k].value = DISABLE_DEBUG1(OTPSTRAP[1]);
1409*76d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_DEBUG1(OTPSTRAP_PRO[1]);
1410*76d13988SJohnny Huang 	if (DISABLE_DEBUG1(OTPSTRAP_KEEP[1])) {
1411*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1412*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1413*76d13988SJohnny Huang 	} else {
1414*76d13988SJohnny Huang 		if (DISABLE_DEBUG1(OTPSTRAP[1]))
1415*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1416*76d13988SJohnny Huang 			       "Disable debug interfaces 1");
1417*76d13988SJohnny Huang 		else
1418*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1419*76d13988SJohnny Huang 			       "Enable debug interfaces 1");
1420*76d13988SJohnny Huang 	}
1421*76d13988SJohnny Huang 
1422*76d13988SJohnny Huang 	k++;
1423*76d13988SJohnny Huang 	strap_parse[k].bit = 37;
1424*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1425*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_ACPI(OTPSTRAP[1]);
1426*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_ACPI(OTPSTRAP_PRO[1]);
1427*76d13988SJohnny Huang 	if (ENABLE_ACPI(OTPSTRAP_KEEP[1])) {
1428*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1429*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1430*76d13988SJohnny Huang 	} else {
1431*76d13988SJohnny Huang 		if (ENABLE_ACPI(OTPSTRAP[1]))
1432*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1433*76d13988SJohnny Huang 			       "Enable ACPI function");
1434*76d13988SJohnny Huang 		else
1435*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1436*76d13988SJohnny Huang 			       "Disable ACPI function");
1437*76d13988SJohnny Huang 	}
1438*76d13988SJohnny Huang 
1439*76d13988SJohnny Huang 	k++;
1440*76d13988SJohnny Huang 	strap_parse[k].bit = 38;
1441*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1442*76d13988SJohnny Huang 	strap_parse[k].value = SELECT_LPC(OTPSTRAP[1]);
1443*76d13988SJohnny Huang 	strap_parse[k].protect = SELECT_LPC(OTPSTRAP_PRO[1]);
1444*76d13988SJohnny Huang 	if (SELECT_LPC(OTPSTRAP_KEEP[1])) {
1445*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1446*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1447*76d13988SJohnny Huang 	} else {
1448*76d13988SJohnny Huang 		if (SELECT_LPC(OTPSTRAP[1]))
1449*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1450*76d13988SJohnny Huang 			       "Enable LPC mode");
1451*76d13988SJohnny Huang 		else
1452*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1453*76d13988SJohnny Huang 			       "Enable eSPI mode");
1454*76d13988SJohnny Huang 	}
1455*76d13988SJohnny Huang 
1456*76d13988SJohnny Huang 	k++;
1457*76d13988SJohnny Huang 	strap_parse[k].bit = 39;
1458*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1459*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_SAFS(OTPSTRAP[1]);
1460*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_SAFS(OTPSTRAP_PRO[1]);
1461*76d13988SJohnny Huang 	if (ENABLE_SAFS(OTPSTRAP_KEEP[1])) {
1462*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1463*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1464*76d13988SJohnny Huang 	} else {
1465*76d13988SJohnny Huang 		if (ENABLE_SAFS(OTPSTRAP[1]))
1466*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1467*76d13988SJohnny Huang 			       "Enable SAFS mode");
1468*76d13988SJohnny Huang 		else
1469*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1470*76d13988SJohnny Huang 			       "Enable SAFS mode");
1471*76d13988SJohnny Huang 	}
1472*76d13988SJohnny Huang 
1473*76d13988SJohnny Huang 	k++;
1474*76d13988SJohnny Huang 	strap_parse[k].bit = 42;
1475*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1476*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_SPI_3B4B_AUTO(OTPSTRAP[1]);
1477*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_SPI_3B4B_AUTO(OTPSTRAP_PRO[1]);
1478*76d13988SJohnny Huang 	if (ENABLE_SPI_3B4B_AUTO(OTPSTRAP_KEEP[1])) {
1479*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1480*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1481*76d13988SJohnny Huang 	} else {
1482*76d13988SJohnny Huang 		if (ENABLE_SPI_3B4B_AUTO(OTPSTRAP[1]))
1483*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1484*76d13988SJohnny Huang 			       "Enable boot SPI 3B/4B address mode auto detection");
1485*76d13988SJohnny Huang 		else
1486*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1487*76d13988SJohnny Huang 			       "Disable boot SPI 3B/4B address mode auto detection");
1488*76d13988SJohnny Huang 	}
1489*76d13988SJohnny Huang 
1490*76d13988SJohnny Huang 	k++;
1491*76d13988SJohnny Huang 	strap_parse[k].bit = 43;
1492*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1493*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_BOOT_SPI_ABR(OTPSTRAP[1]);
1494*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_BOOT_SPI_ABR(OTPSTRAP_PRO[1]);
1495*76d13988SJohnny Huang 	if (ENABLE_BOOT_SPI_ABR(OTPSTRAP_KEEP[1])) {
1496*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1497*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1498*76d13988SJohnny Huang 	} else {
1499*76d13988SJohnny Huang 		if (ENABLE_BOOT_SPI_ABR(OTPSTRAP[1]))
1500*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1501*76d13988SJohnny Huang 			       "Enable boot SPI ABR");
1502*76d13988SJohnny Huang 		else
1503*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1504*76d13988SJohnny Huang 			       "Disable boot SPI ABR");
1505*76d13988SJohnny Huang 	}
1506*76d13988SJohnny Huang 
1507*76d13988SJohnny Huang 	k++;
1508*76d13988SJohnny Huang 	strap_parse[k].bit = 44;
1509*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1510*76d13988SJohnny Huang 	strap_parse[k].value = BOOT_SPI_ABR_MODE(OTPSTRAP[1]);
1511*76d13988SJohnny Huang 	strap_parse[k].protect = BOOT_SPI_ABR_MODE(OTPSTRAP_PRO[1]);
1512*76d13988SJohnny Huang 	if (BOOT_SPI_ABR_MODE(OTPSTRAP_KEEP[1])) {
1513*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1514*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1515*76d13988SJohnny Huang 	} else {
1516*76d13988SJohnny Huang 		if (BOOT_SPI_ABR_MODE(OTPSTRAP[1]))
1517*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1518*76d13988SJohnny Huang 			       "Boot SPI ABR mode : single SPI flash");
1519*76d13988SJohnny Huang 		else
1520*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1521*76d13988SJohnny Huang 			       "Boot SPI ABR mode : dual SPI flash");
1522*76d13988SJohnny Huang 	}
1523*76d13988SJohnny Huang 
1524*76d13988SJohnny Huang 	k++;
1525*76d13988SJohnny Huang 	strap_parse[k].bit = 45;
1526*76d13988SJohnny Huang 	strap_parse[k].length = 3;
1527*76d13988SJohnny Huang 	strap_parse[k].value = BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]);
1528*76d13988SJohnny Huang 	strap_parse[k].protect = BOOT_SPI_FLASH_SIZE(OTPSTRAP_PRO[1]);
1529*76d13988SJohnny Huang 	if (BOOT_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0x7) {
1530*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1531*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1532*76d13988SJohnny Huang 	} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0) {
1533*76d13988SJohnny Huang 		if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 0) {
1534*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1535*76d13988SJohnny Huang 			       "Boot SPI flash size : no define size");
1536*76d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 1) {
1537*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1538*76d13988SJohnny Huang 			       "Boot SPI flash size : 2MB");
1539*76d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 2) {
1540*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1541*76d13988SJohnny Huang 			       "Boot SPI flash size : 4MB");
1542*76d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 3) {
1543*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1544*76d13988SJohnny Huang 			       "Boot SPI flash size : 8MB");
1545*76d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 4) {
1546*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1547*76d13988SJohnny Huang 			       "Boot SPI flash size : 16MB");
1548*76d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 5) {
1549*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1550*76d13988SJohnny Huang 			       "Boot SPI flash size : 32MB");
1551*76d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 6) {
1552*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1553*76d13988SJohnny Huang 			       "Boot SPI flash size : 64MB");
1554*76d13988SJohnny Huang 		} else if (BOOT_SPI_FLASH_SIZE(OTPSTRAP[1]) == 7) {
1555*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1556*76d13988SJohnny Huang 			       "Boot SPI flash size : 128MB");
1557*76d13988SJohnny Huang 		}
1558*76d13988SJohnny Huang 	} else {
1559*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
1560*76d13988SJohnny Huang 		return -1;
1561*76d13988SJohnny Huang 	}
1562*76d13988SJohnny Huang 
1563*76d13988SJohnny Huang 	k++;
1564*76d13988SJohnny Huang 	strap_parse[k].bit = 48;
1565*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1566*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_HOST_SPI_ABR(OTPSTRAP[1]);
1567*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_HOST_SPI_ABR(OTPSTRAP_PRO[1]);
1568*76d13988SJohnny Huang 	if (ENABLE_HOST_SPI_ABR(OTPSTRAP_KEEP[1])) {
1569*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1570*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1571*76d13988SJohnny Huang 	} else {
1572*76d13988SJohnny Huang 		if (ENABLE_HOST_SPI_ABR(OTPSTRAP[1]))
1573*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1574*76d13988SJohnny Huang 			       "Enable host SPI ABR");
1575*76d13988SJohnny Huang 		else
1576*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1577*76d13988SJohnny Huang 			       "Disable host SPI ABR");
1578*76d13988SJohnny Huang 	}
1579*76d13988SJohnny Huang 
1580*76d13988SJohnny Huang 	k++;
1581*76d13988SJohnny Huang 	strap_parse[k].bit = 49;
1582*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1583*76d13988SJohnny Huang 	strap_parse[k].value = EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP[1]);
1584*76d13988SJohnny Huang 	strap_parse[k].protect = EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP_PRO[1]);
1585*76d13988SJohnny Huang 	if (EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP_KEEP[1])) {
1586*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1587*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1588*76d13988SJohnny Huang 	} else {
1589*76d13988SJohnny Huang 		if (EBABLE_HOST_SPI_ABR_SEL_PIN(OTPSTRAP[1]))
1590*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1591*76d13988SJohnny Huang 			       "Enable host SPI ABR mode select pin");
1592*76d13988SJohnny Huang 		else
1593*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1594*76d13988SJohnny Huang 			       "Disable host SPI ABR mode select pin");
1595*76d13988SJohnny Huang 	}
1596*76d13988SJohnny Huang 
1597*76d13988SJohnny Huang 	k++;
1598*76d13988SJohnny Huang 	strap_parse[k].bit = 50;
1599*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1600*76d13988SJohnny Huang 	strap_parse[k].value = HOST_SPI_ABR_MODE(OTPSTRAP[1]);
1601*76d13988SJohnny Huang 	strap_parse[k].protect = HOST_SPI_ABR_MODE(OTPSTRAP_PRO[1]);
1602*76d13988SJohnny Huang 	if (HOST_SPI_ABR_MODE(OTPSTRAP_KEEP[1])) {
1603*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1604*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1605*76d13988SJohnny Huang 	} else {
1606*76d13988SJohnny Huang 		if (HOST_SPI_ABR_MODE(OTPSTRAP[1]))
1607*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1608*76d13988SJohnny Huang 			       "Host SPI ABR mode : single SPI flash");
1609*76d13988SJohnny Huang 		else
1610*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1611*76d13988SJohnny Huang 			       "Host SPI ABR mode : dual SPI flash");
1612*76d13988SJohnny Huang 	}
1613*76d13988SJohnny Huang 
1614*76d13988SJohnny Huang 	k++;
1615*76d13988SJohnny Huang 	strap_parse[k].bit = 51;
1616*76d13988SJohnny Huang 	strap_parse[k].length = 3;
1617*76d13988SJohnny Huang 	strap_parse[k].value = HOST_SPI_FLASH_SIZE(OTPSTRAP[1]);
1618*76d13988SJohnny Huang 	strap_parse[k].protect = HOST_SPI_FLASH_SIZE(OTPSTRAP_PRO[1]);
1619*76d13988SJohnny Huang 	if (HOST_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0x7) {
1620*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1621*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1622*76d13988SJohnny Huang 	} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP_KEEP[1]) == 0) {
1623*76d13988SJohnny Huang 		if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 0) {
1624*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1625*76d13988SJohnny Huang 			       "Host SPI flash size : no define size");
1626*76d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 1) {
1627*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1628*76d13988SJohnny Huang 			       "Host SPI flash size : 2MB");
1629*76d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 2) {
1630*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1631*76d13988SJohnny Huang 			       "Host SPI flash size : 4MB");
1632*76d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 3) {
1633*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1634*76d13988SJohnny Huang 			       "Host SPI flash size : 8MB");
1635*76d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 4) {
1636*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1637*76d13988SJohnny Huang 			       "Host SPI flash size : 16MB");
1638*76d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 5) {
1639*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1640*76d13988SJohnny Huang 			       "Host SPI flash size : 32MB");
1641*76d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 6) {
1642*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1643*76d13988SJohnny Huang 			       "Host SPI flash size : 64MB");
1644*76d13988SJohnny Huang 		} else if (HOST_SPI_FLASH_SIZE(OTPSTRAP[1]) == 7) {
1645*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1646*76d13988SJohnny Huang 			       "Host SPI flash size : 128MB");
1647*76d13988SJohnny Huang 		}
1648*76d13988SJohnny Huang 	} else {
1649*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
1650*76d13988SJohnny Huang 		return -1;
1651*76d13988SJohnny Huang 	}
1652*76d13988SJohnny Huang 
1653*76d13988SJohnny Huang 	k++;
1654*76d13988SJohnny Huang 	strap_parse[k].bit = 54;
1655*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1656*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]);
1657*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP_PRO[1]);
1658*76d13988SJohnny Huang 	if (ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP_KEEP[1])) {
1659*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1660*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1661*76d13988SJohnny Huang 	} else {
1662*76d13988SJohnny Huang 		if (ENABLE_BOOT_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]))
1663*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1664*76d13988SJohnny Huang 			       "Enable boot SPI auxiliary control pins");
1665*76d13988SJohnny Huang 		else
1666*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1667*76d13988SJohnny Huang 			       "Disable boot SPI auxiliary control pins");
1668*76d13988SJohnny Huang 	}
1669*76d13988SJohnny Huang 
1670*76d13988SJohnny Huang 	k++;
1671*76d13988SJohnny Huang 	strap_parse[k].bit = 55;
1672*76d13988SJohnny Huang 	strap_parse[k].length = 2;
1673*76d13988SJohnny Huang 	strap_parse[k].value = BOOT_SPI_CRTM_SIZE(OTPSTRAP[1]);
1674*76d13988SJohnny Huang 	strap_parse[k].protect = BOOT_SPI_CRTM_SIZE(OTPSTRAP_PRO[1]);
1675*76d13988SJohnny Huang 	if (BOOT_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0x3) {
1676*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1677*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1678*76d13988SJohnny Huang 	} else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0) {
1679*76d13988SJohnny Huang 		if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 0) {
1680*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1681*76d13988SJohnny Huang 			       "Boot SPI CRTM size : disable CRTM");
1682*76d13988SJohnny Huang 		} else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 1) {
1683*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1684*76d13988SJohnny Huang 			       "Boot SPI CRTM size : 256KB");
1685*76d13988SJohnny Huang 		} else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 2) {
1686*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1687*76d13988SJohnny Huang 			       "Boot SPI CRTM size : 512KB");
1688*76d13988SJohnny Huang 		} else if (BOOT_SPI_CRTM_SIZE(OTPSTRAP[0]) == 3) {
1689*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1690*76d13988SJohnny Huang 			       "Boot SPI CRTM size : 1MB");
1691*76d13988SJohnny Huang 		}
1692*76d13988SJohnny Huang 	} else {
1693*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
1694*76d13988SJohnny Huang 		return -1;
1695*76d13988SJohnny Huang 	}
1696*76d13988SJohnny Huang 
1697*76d13988SJohnny Huang 	k++;
1698*76d13988SJohnny Huang 	strap_parse[k].bit = 57;
1699*76d13988SJohnny Huang 	strap_parse[k].length = 2;
1700*76d13988SJohnny Huang 	strap_parse[k].value = HOST_SPI_CRTM_SIZE(OTPSTRAP[1]);
1701*76d13988SJohnny Huang 	strap_parse[k].protect = HOST_SPI_CRTM_SIZE(OTPSTRAP_PRO[1]);
1702*76d13988SJohnny Huang 	if (HOST_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0x3) {
1703*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1704*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1705*76d13988SJohnny Huang 	} else if (HOST_SPI_CRTM_SIZE(OTPSTRAP_KEEP[0]) == 0) {
1706*76d13988SJohnny Huang 		if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 0) {
1707*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1708*76d13988SJohnny Huang 			       "Host SPI CRTM size : disable CRTM");
1709*76d13988SJohnny Huang 		} else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 1) {
1710*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1711*76d13988SJohnny Huang 			       "Host SPI CRTM size : 256KB");
1712*76d13988SJohnny Huang 		} else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 2) {
1713*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1714*76d13988SJohnny Huang 			       "Host SPI CRTM size : 512KB");
1715*76d13988SJohnny Huang 		} else if (HOST_SPI_CRTM_SIZE(OTPSTRAP[0]) == 3) {
1716*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1717*76d13988SJohnny Huang 			       "Host SPI CRTM size : 1MB");
1718*76d13988SJohnny Huang 		}
1719*76d13988SJohnny Huang 	} else {
1720*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Keep mask error!");
1721*76d13988SJohnny Huang 		return -1;
1722*76d13988SJohnny Huang 	}
1723*76d13988SJohnny Huang 
1724*76d13988SJohnny Huang 	k++;
1725*76d13988SJohnny Huang 	strap_parse[k].bit = 59;
1726*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1727*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]);
1728*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP_PRO[1]);
1729*76d13988SJohnny Huang 	if (ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP_KEEP[1])) {
1730*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1731*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1732*76d13988SJohnny Huang 	} else {
1733*76d13988SJohnny Huang 		if (ENABLE_HOST_SPI_AUX_CONTROL_PIN(OTPSTRAP[1]))
1734*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1735*76d13988SJohnny Huang 			       "Enable host SPI auxiliary control pins");
1736*76d13988SJohnny Huang 		else
1737*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1738*76d13988SJohnny Huang 			       "Disable host SPI auxiliary control pins");
1739*76d13988SJohnny Huang 	}
1740*76d13988SJohnny Huang 
1741*76d13988SJohnny Huang 	k++;
1742*76d13988SJohnny Huang 	strap_parse[k].bit = 60;
1743*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1744*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_GPIO_PASS_THROUGH(OTPSTRAP[1]);
1745*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_GPIO_PASS_THROUGH(OTPSTRAP_PRO[1]);
1746*76d13988SJohnny Huang 	if (ENABLE_GPIO_PASS_THROUGH(OTPSTRAP_KEEP[1])) {
1747*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1748*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1749*76d13988SJohnny Huang 	} else {
1750*76d13988SJohnny Huang 		if (ENABLE_GPIO_PASS_THROUGH(OTPSTRAP[1]))
1751*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1752*76d13988SJohnny Huang 			       "Enable GPIO pass through");
1753*76d13988SJohnny Huang 		else
1754*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1755*76d13988SJohnny Huang 			       "Disable GPIO pass through");
1756*76d13988SJohnny Huang 	}
1757*76d13988SJohnny Huang 
1758*76d13988SJohnny Huang 	k++;
1759*76d13988SJohnny Huang 	strap_parse[k].bit = 61;
1760*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1761*76d13988SJohnny Huang 	strap_parse[k].value = DISABLE_LOW_SECURITY_KEY(OTPSTRAP[1]);
1762*76d13988SJohnny Huang 	strap_parse[k].protect = DISABLE_LOW_SECURITY_KEY(OTPSTRAP_PRO[1]);
1763*76d13988SJohnny Huang 	if (DISABLE_LOW_SECURITY_KEY(OTPSTRAP_KEEP[1])) {
1764*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1765*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1766*76d13988SJohnny Huang 	} else {
1767*76d13988SJohnny Huang 		if (DISABLE_LOW_SECURITY_KEY(OTPSTRAP[1]))
1768*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1769*76d13988SJohnny Huang 			       "Disable low security secure boot key");
1770*76d13988SJohnny Huang 		else
1771*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1772*76d13988SJohnny Huang 			       "Enable low security secure boot key");
1773*76d13988SJohnny Huang 	}
1774*76d13988SJohnny Huang 
1775*76d13988SJohnny Huang 	k++;
1776*76d13988SJohnny Huang 	strap_parse[k].bit = 62;
1777*76d13988SJohnny Huang 	strap_parse[k].length = 1;
1778*76d13988SJohnny Huang 	strap_parse[k].value = ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP[1]);
1779*76d13988SJohnny Huang 	strap_parse[k].protect = ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP_PRO[1]);
1780*76d13988SJohnny Huang 	if (ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP_KEEP[1])) {
1781*76d13988SJohnny Huang 		strap_parse[k].keep = 1;
1782*76d13988SJohnny Huang 		strcpy(strap_parse[k].status, "Skip");
1783*76d13988SJohnny Huang 	} else {
1784*76d13988SJohnny Huang 		if (ENABLE_DEDICATE_GPIO_STRAP(OTPSTRAP[1]))
1785*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1786*76d13988SJohnny Huang 			       "Enable dedicate GPIO strap pins");
1787*76d13988SJohnny Huang 		else
1788*76d13988SJohnny Huang 			strcpy(strap_parse[k].status,
1789*76d13988SJohnny Huang 			       "Disable dedicate GPIO strap pins");
1790*76d13988SJohnny Huang 	}
1791*76d13988SJohnny Huang 
1792*76d13988SJohnny Huang 	return k + 1;
1793*76d13988SJohnny 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 
180666f2f8e5SJohnny Huang 	printf("DW  BIT     Value       Status\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 
1837*76d13988SJohnny Huang static int otp_print_strap_info(uint32_t *OTPSTRAP)
1838*76d13988SJohnny Huang {
1839*76d13988SJohnny Huang 	struct otpstrap_parse strap_parse[60];
1840*76d13988SJohnny Huang 	int length;
1841*76d13988SJohnny Huang 	int i;
1842*76d13988SJohnny Huang 
1843*76d13988SJohnny Huang 	length = otp_strap_parse(OTPSTRAP, strap_parse);
1844*76d13988SJohnny Huang 
1845*76d13988SJohnny Huang 	if (length <= 0)
1846*76d13988SJohnny Huang 		return OTP_FAILURE;
1847*76d13988SJohnny Huang 
1848*76d13988SJohnny Huang 	printf("BIT     Value       Protect     Status\n");
1849*76d13988SJohnny Huang 	printf("__________________________________________________________________________________________\n");
1850*76d13988SJohnny Huang 	for (i = 0; i < length; i++) {
1851*76d13988SJohnny Huang 		if (strap_parse[i].length == 1) {
1852*76d13988SJohnny Huang 			printf("%-8d", strap_parse[i].bit);
1853*76d13988SJohnny Huang 		} else {
1854*76d13988SJohnny Huang 			printf("%-2d:%-5d",
1855*76d13988SJohnny Huang 			       strap_parse[i].bit + strap_parse[i].length - 1,
1856*76d13988SJohnny Huang 			       strap_parse[i].bit);
1857*76d13988SJohnny Huang 		}
1858*76d13988SJohnny Huang 		printf("0x%-10x", strap_parse[i].value);
1859*76d13988SJohnny Huang 		printf("0x%-10x", strap_parse[i].protect);
1860*76d13988SJohnny Huang 		printf("%s\n", strap_parse[i].status);
1861*76d13988SJohnny Huang 	}
1862*76d13988SJohnny Huang 	return OTP_SUCCESS;
1863*76d13988SJohnny Huang }
1864*76d13988SJohnny Huang 
1865*76d13988SJohnny Huang static void otp_info_strap(void)
1866*76d13988SJohnny Huang {
1867*76d13988SJohnny Huang 	struct otpstrap_status strap_status[64];
1868*76d13988SJohnny Huang 	uint32_t OTPSTRAP[6];
1869*76d13988SJohnny Huang 	int i;
1870*76d13988SJohnny Huang 
1871*76d13988SJohnny Huang 
1872*76d13988SJohnny Huang 	otp_strp_status(strap_status);
1873*76d13988SJohnny Huang 
1874*76d13988SJohnny Huang 	for (i = 0; i < 6; i++)
1875*76d13988SJohnny Huang 		OTPSTRAP[i] = 0;
1876*76d13988SJohnny Huang 	for (i = 0; i < 32; i++) {
1877*76d13988SJohnny Huang 		OTPSTRAP[0] |= (strap_status[i].value & 0x1) << i;
1878*76d13988SJohnny Huang 		OTPSTRAP[4] |= (strap_status[i].protected & 0x1) << i;
1879*76d13988SJohnny Huang 	}
1880*76d13988SJohnny Huang 	for (i = 0; i < 32; i++) {
1881*76d13988SJohnny Huang 		OTPSTRAP[1] |= (strap_status[i + 32].value & 0x1) << i;
1882*76d13988SJohnny Huang 		OTPSTRAP[5] |= (strap_status[i + 32].protected & 0x1) << i;
1883*76d13988SJohnny Huang 	}
1884*76d13988SJohnny Huang 
1885*76d13988SJohnny Huang 	otp_print_strap_info(OTPSTRAP);
1886*76d13988SJohnny Huang }
1887*76d13988SJohnny 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 
2093*76d13988SJohnny 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 
2164cd1610b4SJohnny Huang 	for (i = start; i < start + count; i++) {
2165a6af4a17SJohnny Huang 		printf("OTPSTRAP[%X]:\n", i);
216669d5fd8fSJohnny Huang 		printf("  OTP Option value: ");
216769d5fd8fSJohnny Huang 		for (j = 1; j <= 7; j++)
2168a6af4a17SJohnny Huang 			printf("[%X]:%X ", j, otpstrap[i].option_array[j - 1]);
216969d5fd8fSJohnny Huang 		printf("\n");
2170a6af4a17SJohnny Huang 		printf("  OTP Value: %X\n", otpstrap[i].value);
217169d5fd8fSJohnny Huang 		printf("  Status:\n");
217269d5fd8fSJohnny Huang 		if (otpstrap[i].protected == 1) {
2173a6af4a17SJohnny Huang 			printf("    OTPSTRAP[%X] is protected and is not writable\n", i);
217469d5fd8fSJohnny Huang 		} else {
2175a6af4a17SJohnny Huang 			printf("    OTPSTRAP[%X] is not protected ", i);
217669d5fd8fSJohnny Huang 			if (otpstrap[i].remain_times == 0) {
2177a6af4a17SJohnny Huang 				printf("and no remaining times to write.\n");
217869d5fd8fSJohnny Huang 			} else {
2179a6af4a17SJohnny Huang 				printf("and still can write %d times\n", otpstrap[i].remain_times);
218069d5fd8fSJohnny Huang 			}
218169d5fd8fSJohnny Huang 		}
218269d5fd8fSJohnny Huang 	}
21832a856b9aSJohnny Huang 
21842a856b9aSJohnny Huang 	return OTP_SUCCESS;
218569d5fd8fSJohnny Huang }
218669d5fd8fSJohnny Huang 
218769d5fd8fSJohnny Huang static int otp_prog_strap(uint32_t *buf)
218869d5fd8fSJohnny Huang {
218969d5fd8fSJohnny Huang 	int i, j;
219069d5fd8fSJohnny Huang 	uint32_t *strap_keep = buf + 2;
219169d5fd8fSJohnny Huang 	uint32_t *strap_protect = buf + 4;
219269d5fd8fSJohnny Huang 	uint32_t prog_bit, prog_address;
219369d5fd8fSJohnny Huang 	int bit, pbit, kbit, offset;
219469d5fd8fSJohnny Huang 	int fail = 0;
21957e22f42dSJohnny Huang 	int pass = 0;
21967e22f42dSJohnny Huang 	int soak = 0;
219766f2f8e5SJohnny Huang 	struct otpstrap_status otpstrap[64];
219869d5fd8fSJohnny Huang 
219969d5fd8fSJohnny Huang 	otp_strp_status(otpstrap);
220069d5fd8fSJohnny Huang 
22017e22f42dSJohnny Huang 	otp_soak(0);
22027e22f42dSJohnny Huang 
220369d5fd8fSJohnny Huang 	for (i = 0; i < 64; i++) {
22044c1c9b35SJohnny Huang 		printProgress(i + 1, 64, "");
220569d5fd8fSJohnny Huang 		prog_address = 0x800;
220669d5fd8fSJohnny Huang 		if (i < 32) {
220769d5fd8fSJohnny Huang 			offset = i;
220869d5fd8fSJohnny Huang 			bit = (buf[0] >> offset) & 0x1;
220969d5fd8fSJohnny Huang 			kbit = (strap_keep[0] >> offset) & 0x1;
221069d5fd8fSJohnny Huang 			pbit = (strap_protect[0] >> offset) & 0x1;
221169d5fd8fSJohnny Huang 			prog_address |= ((otpstrap[i].writeable_option * 2 + 16) / 8) * 0x200;
221269d5fd8fSJohnny Huang 			prog_address |= ((otpstrap[i].writeable_option * 2 + 16) % 8) * 0x2;
221369d5fd8fSJohnny Huang 
221469d5fd8fSJohnny Huang 		} else {
221569d5fd8fSJohnny Huang 			offset = (i - 32);
221669d5fd8fSJohnny Huang 			bit = (buf[1] >> offset) & 0x1;
221769d5fd8fSJohnny Huang 			kbit = (strap_keep[1] >> offset) & 0x1;
221869d5fd8fSJohnny Huang 			pbit = (strap_protect[1] >> offset) & 0x1;
221969d5fd8fSJohnny Huang 			prog_address |= ((otpstrap[i].writeable_option * 2 + 17) / 8) * 0x200;
222069d5fd8fSJohnny Huang 			prog_address |= ((otpstrap[i].writeable_option * 2 + 17) % 8) * 0x2;
222169d5fd8fSJohnny Huang 		}
222269d5fd8fSJohnny Huang 		prog_bit = ~(0x1 << offset);
222369d5fd8fSJohnny Huang 
222469d5fd8fSJohnny Huang 		if (kbit == 1) {
222569d5fd8fSJohnny Huang 			continue;
222669d5fd8fSJohnny Huang 		}
222769d5fd8fSJohnny Huang 		if (bit == otpstrap[i].value) {
222869d5fd8fSJohnny Huang 			continue;
222969d5fd8fSJohnny Huang 		}
223069d5fd8fSJohnny Huang 		if (otpstrap[i].protected == 1) {
223169d5fd8fSJohnny Huang 			fail = 1;
223269d5fd8fSJohnny Huang 			continue;
223369d5fd8fSJohnny Huang 		}
223469d5fd8fSJohnny Huang 		if (otpstrap[i].remain_times == 0) {
223569d5fd8fSJohnny Huang 			fail = 1;
223669d5fd8fSJohnny Huang 			continue;
223769d5fd8fSJohnny Huang 		}
22387e22f42dSJohnny Huang 
22397e22f42dSJohnny Huang 		if (soak) {
224069d5fd8fSJohnny Huang 			soak = 0;
22417e22f42dSJohnny Huang 			otp_soak(0);
22427e22f42dSJohnny Huang 		}
22437e22f42dSJohnny Huang 
22447e22f42dSJohnny Huang 		otp_prog(prog_address, prog_bit);
22457e22f42dSJohnny Huang 
22467e22f42dSJohnny Huang 		pass = 0;
22477e22f42dSJohnny Huang 
224869d5fd8fSJohnny Huang 		for (j = 0; j < RETRY; j++) {
2249a6d0d645SJohnny Huang 			if (verify_bit(prog_address, offset, 1) == 0) {
225069d5fd8fSJohnny Huang 				pass = 1;
225169d5fd8fSJohnny Huang 				break;
225269d5fd8fSJohnny Huang 			}
22537e22f42dSJohnny Huang 			if (soak == 0) {
225469d5fd8fSJohnny Huang 				soak = 1;
22557e22f42dSJohnny Huang 				otp_soak(1);
22564b65a65dSJohnny Huang 			}
225769d5fd8fSJohnny Huang 			otp_prog(prog_address, prog_bit);
225869d5fd8fSJohnny Huang 		}
225969d5fd8fSJohnny Huang 		if (!pass)
22602a856b9aSJohnny Huang 			return OTP_FAILURE;
226169d5fd8fSJohnny Huang 
226269d5fd8fSJohnny Huang 		if (pbit == 0)
226369d5fd8fSJohnny Huang 			continue;
226469d5fd8fSJohnny Huang 		prog_address = 0x800;
226569d5fd8fSJohnny Huang 		if (i < 32)
226669d5fd8fSJohnny Huang 			prog_address |= 0x60c;
226769d5fd8fSJohnny Huang 		else
226869d5fd8fSJohnny Huang 			prog_address |= 0x60e;
226969d5fd8fSJohnny Huang 
22707e22f42dSJohnny Huang 
22717e22f42dSJohnny Huang 		if (soak) {
22727e22f42dSJohnny Huang 			soak = 0;
22737e22f42dSJohnny Huang 			otp_soak(0);
22747e22f42dSJohnny Huang 		}
22757e22f42dSJohnny Huang 
22767e22f42dSJohnny Huang 		otp_prog(prog_address, prog_bit);
22777e22f42dSJohnny Huang 
22787e22f42dSJohnny Huang 		pass = 0;
22797e22f42dSJohnny Huang 
228069d5fd8fSJohnny Huang 		for (j = 0; j < RETRY; j++) {
22817e22f42dSJohnny Huang 
2282a6d0d645SJohnny Huang 			if (verify_bit(prog_address, offset, 1) == 0) {
228369d5fd8fSJohnny Huang 				pass = 1;
228469d5fd8fSJohnny Huang 				break;
228569d5fd8fSJohnny Huang 			}
22867e22f42dSJohnny Huang 			if (soak == 0) {
228769d5fd8fSJohnny Huang 				soak = 1;
22887e22f42dSJohnny Huang 				otp_soak(1);
228969d5fd8fSJohnny Huang 			}
229069d5fd8fSJohnny Huang 			otp_prog(prog_address, prog_bit);
229169d5fd8fSJohnny Huang 		}
229269d5fd8fSJohnny Huang 		if (!pass)
22932a856b9aSJohnny Huang 			return OTP_FAILURE;
229469d5fd8fSJohnny Huang 
229569d5fd8fSJohnny Huang 	}
229669d5fd8fSJohnny Huang 	if (fail == 1)
22972a856b9aSJohnny Huang 		return OTP_FAILURE;
229869d5fd8fSJohnny Huang 	else
22992a856b9aSJohnny Huang 		return OTP_SUCCESS;
230069d5fd8fSJohnny Huang 
230169d5fd8fSJohnny Huang }
230269d5fd8fSJohnny Huang 
2303cd1610b4SJohnny Huang static void otp_prog_bit(uint32_t value, uint32_t prog_address, uint32_t bit_offset, int soak)
2304cd1610b4SJohnny Huang {
2305cd1610b4SJohnny Huang 	int prog_bit;
2306cd1610b4SJohnny Huang 
23077e22f42dSJohnny Huang 	otp_soak(soak);
23087e22f42dSJohnny Huang 
2309cd1610b4SJohnny Huang 	if (prog_address % 2 == 0) {
2310cd1610b4SJohnny Huang 		if (value)
2311cd1610b4SJohnny Huang 			prog_bit = ~(0x1 << bit_offset);
2312cd1610b4SJohnny Huang 		else
2313cd1610b4SJohnny Huang 			return;
2314cd1610b4SJohnny Huang 	} else {
2315cd1610b4SJohnny Huang 		prog_address |= 1 << 15;
2316cd1610b4SJohnny Huang 		if (!value)
2317cd1610b4SJohnny Huang 			prog_bit = 0x1 << bit_offset;
2318cd1610b4SJohnny Huang 		else
2319cd1610b4SJohnny Huang 			return;
2320cd1610b4SJohnny Huang 	}
2321cd1610b4SJohnny Huang 	otp_prog(prog_address, prog_bit);
2322cd1610b4SJohnny Huang }
2323cd1610b4SJohnny Huang 
2324d90825e2SJohnny Huang static int otp_prog_data(uint32_t *buf)
23254c1c9b35SJohnny Huang {
23264c1c9b35SJohnny Huang 	int i, k;
23274c1c9b35SJohnny Huang 	int pass;
2328d90825e2SJohnny Huang 	int soak = 0;
23294c1c9b35SJohnny Huang 	uint32_t prog_address;
2330d90825e2SJohnny Huang 	uint32_t data[2048];
23314c1c9b35SJohnny Huang 	uint32_t compare[2];
2332d90825e2SJohnny Huang 	uint32_t *buf_keep = &buf[2048];
23334c1c9b35SJohnny Huang 
2334d90825e2SJohnny Huang 	uint32_t data0_masked;
2335d90825e2SJohnny Huang 	uint32_t data1_masked;
2336d90825e2SJohnny Huang 	uint32_t buf0_masked;
2337d90825e2SJohnny Huang 	uint32_t buf1_masked;
23384c1c9b35SJohnny Huang 
23394c1c9b35SJohnny Huang 	printf("Read OTP Data:\n");
23404c1c9b35SJohnny Huang 
2341d90825e2SJohnny Huang 	printProgress(0, 2048, "");
2342d90825e2SJohnny Huang 	for (i = 0; i < 2048 ; i += 2) {
2343d90825e2SJohnny Huang 		printProgress(i + 2, 2048, "");
2344d90825e2SJohnny Huang 		otp_read_data(i, &data[i]);
23454c1c9b35SJohnny Huang 	}
2346d90825e2SJohnny Huang 
23474c1c9b35SJohnny Huang 
23484c1c9b35SJohnny Huang 	printf("Check writable...\n");
2349d90825e2SJohnny Huang 	for (i = 0; i < 2048; i++) {
2350d90825e2SJohnny Huang 		data0_masked = data[i]  & ~buf_keep[i];
2351d90825e2SJohnny Huang 		buf0_masked  = buf[i] & ~buf_keep[i];
2352d90825e2SJohnny Huang 		if (data0_masked == buf0_masked)
23534c1c9b35SJohnny Huang 			continue;
2354d90825e2SJohnny Huang 		if (i % 2 == 0) {
2355d90825e2SJohnny Huang 			if ((data0_masked | buf0_masked) == buf0_masked) {
23564c1c9b35SJohnny Huang 				continue;
23574c1c9b35SJohnny Huang 			} else {
23584c1c9b35SJohnny Huang 				printf("Input image can't program into OTP, please check.\n");
2359d90825e2SJohnny Huang 				printf("OTP_ADDR[%x] = %x\n", i, data[i]);
23604c1c9b35SJohnny Huang 				printf("Input   [%x] = %x\n", i, buf[i]);
2361d90825e2SJohnny Huang 				printf("Mask    [%x] = %x\n", i, ~buf_keep[i]);
23622a856b9aSJohnny Huang 				return OTP_FAILURE;
236369d5fd8fSJohnny Huang 			}
2364d90825e2SJohnny Huang 		} else {
2365d90825e2SJohnny Huang 			if ((data0_masked & buf0_masked) == buf0_masked) {
2366d90825e2SJohnny Huang 				continue;
2367d90825e2SJohnny Huang 			} else {
2368d90825e2SJohnny Huang 				printf("Input image can't program into OTP, please check.\n");
2369d90825e2SJohnny Huang 				printf("OTP_ADDR[%x] = %x\n", i, data[i]);
2370d90825e2SJohnny Huang 				printf("Input   [%x] = %x\n", i, buf[i]);
2371d90825e2SJohnny Huang 				printf("Mask    [%x] = %x\n", i, ~buf_keep[i]);
23722a856b9aSJohnny Huang 				return OTP_FAILURE;
2373d90825e2SJohnny Huang 			}
2374d90825e2SJohnny Huang 		}
2375d90825e2SJohnny Huang 	}
237669d5fd8fSJohnny Huang 
2377d90825e2SJohnny Huang 	printf("Start Programing...\n");
2378d90825e2SJohnny Huang 	printProgress(0, 2048, "");
2379d90825e2SJohnny Huang 
2380d90825e2SJohnny Huang 	for (i = 0; i < 2048; i += 2) {
2381d90825e2SJohnny Huang 		prog_address = i;
2382d90825e2SJohnny Huang 		data0_masked = data[i]  & ~buf_keep[i];
2383d90825e2SJohnny Huang 		buf0_masked  = buf[i] & ~buf_keep[i];
2384d90825e2SJohnny Huang 		data1_masked = data[i + 1]  & ~buf_keep[i + 1];
2385d90825e2SJohnny Huang 		buf1_masked  = buf[i + 1] & ~buf_keep[i + 1];
2386d90825e2SJohnny Huang 		if ((data0_masked == buf0_masked) && (data1_masked == buf1_masked)) {
2387d90825e2SJohnny Huang 			printProgress(i + 2, 2048, "[%03X]=%08X HIT;[%03X]=%08X HIT", prog_address, buf[i], prog_address + 1, buf[i + 1]);
2388d90825e2SJohnny Huang 			continue;
2389d90825e2SJohnny Huang 		}
2390d90825e2SJohnny Huang 		if (soak) {
2391d90825e2SJohnny Huang 			soak = 0;
2392d90825e2SJohnny Huang 			otp_soak(0);
2393d90825e2SJohnny Huang 		}
2394d90825e2SJohnny Huang 		if (data1_masked == buf1_masked) {
2395d90825e2SJohnny Huang 			printProgress(i + 2, 2048, "[%03X]=%08X    ;[%03X]=%08X HIT", prog_address, buf[i], prog_address + 1, buf[i + 1]);
2396d90825e2SJohnny Huang 			otp_prog_dw(buf[i], buf_keep[i], prog_address);
2397d90825e2SJohnny Huang 		} else if (data0_masked == buf0_masked) {
2398d90825e2SJohnny Huang 			printProgress(i + 2, 2048, "[%03X]=%08X HIT;[%03X]=%08X    ", prog_address, buf[i], prog_address + 1, buf[i + 1]);
2399d90825e2SJohnny Huang 			otp_prog_dw(buf[i + 1], buf_keep[i + 1], prog_address + 1);
2400d90825e2SJohnny Huang 		} else {
2401d90825e2SJohnny Huang 			printProgress(i + 2, 2048, "[%03X]=%08X    ;[%03X]=%08X    ", prog_address, buf[i], prog_address + 1, buf[i + 1]);
2402d90825e2SJohnny Huang 			otp_prog_dw(buf[i], buf_keep[i], prog_address);
2403d90825e2SJohnny Huang 			otp_prog_dw(buf[i + 1], buf_keep[i + 1], prog_address + 1);
2404d90825e2SJohnny Huang 		}
2405d90825e2SJohnny Huang 
2406d90825e2SJohnny Huang 		pass = 0;
2407d90825e2SJohnny Huang 		for (k = 0; k < RETRY; k++) {
2408d90825e2SJohnny Huang 			if (verify_dw(prog_address, &buf[i], &buf_keep[i], compare, 2) != 0) {
2409d90825e2SJohnny Huang 				if (soak == 0) {
2410d90825e2SJohnny Huang 					soak = 1;
2411d90825e2SJohnny Huang 					otp_soak(1);
2412d90825e2SJohnny Huang 				}
2413d90825e2SJohnny Huang 				if (compare[0] != 0) {
2414d90825e2SJohnny Huang 					otp_prog_dw(compare[0], buf_keep[i], prog_address);
2415d90825e2SJohnny Huang 				}
2416d90825e2SJohnny Huang 				if (compare[1] != ~0) {
2417d90825e2SJohnny Huang 					otp_prog_dw(compare[1], buf_keep[i], prog_address + 1);
2418d90825e2SJohnny Huang 				}
2419d90825e2SJohnny Huang 			} else {
2420d90825e2SJohnny Huang 				pass = 1;
2421d90825e2SJohnny Huang 				break;
2422d90825e2SJohnny Huang 			}
2423d90825e2SJohnny Huang 		}
2424d90825e2SJohnny Huang 
2425d90825e2SJohnny Huang 		if (!pass)
24262a856b9aSJohnny Huang 			return OTP_FAILURE;
2427d90825e2SJohnny Huang 	}
24282a856b9aSJohnny Huang 	return OTP_SUCCESS;
2429d90825e2SJohnny Huang 
2430d90825e2SJohnny Huang }
2431d90825e2SJohnny Huang 
2432d90825e2SJohnny Huang static int do_otp_prog(int addr, int byte_size, int nconfirm)
243369d5fd8fSJohnny Huang {
243469d5fd8fSJohnny Huang 	int ret;
2435d90825e2SJohnny Huang 	int mode;
243669d5fd8fSJohnny Huang 	uint32_t *buf;
2437d90825e2SJohnny Huang 	uint32_t *data_region = NULL;
2438d90825e2SJohnny Huang 	uint32_t *conf_region = NULL;
2439d90825e2SJohnny Huang 	uint32_t *strap_region = NULL;
244069d5fd8fSJohnny Huang 
2441d90825e2SJohnny Huang 	buf = map_physmem(addr, byte_size, MAP_WRBACK);
244269d5fd8fSJohnny Huang 	if (!buf) {
244369d5fd8fSJohnny Huang 		puts("Failed to map physical memory\n");
24442a856b9aSJohnny Huang 		return OTP_FAILURE;
244569d5fd8fSJohnny Huang 	}
2446d90825e2SJohnny Huang 
2447d90825e2SJohnny Huang 	if (((buf[0] >> 29) & 0x7) == 0x7) {
2448d90825e2SJohnny Huang 		mode = OTP_REGION_ALL;
2449d90825e2SJohnny Huang 		conf_region = &buf[1];
2450d90825e2SJohnny Huang 		strap_region = &buf[25];
2451d90825e2SJohnny Huang 		data_region = &buf[31];
2452d90825e2SJohnny Huang 	} else {
2453d90825e2SJohnny Huang 		if (buf[0] & BIT(29)) {
2454d90825e2SJohnny Huang 			mode = OTP_REGION_DATA;
2455d90825e2SJohnny Huang 			data_region = &buf[31];
2456d90825e2SJohnny Huang 		}
2457d90825e2SJohnny Huang 		if (buf[0] & BIT(30)) {
2458d90825e2SJohnny Huang 			mode = OTP_REGION_CONF;
2459d90825e2SJohnny Huang 			strap_region = &buf[25];
2460d90825e2SJohnny Huang 		}
2461d90825e2SJohnny Huang 		if (buf[0] & BIT(31)) {
2462d90825e2SJohnny Huang 			mode = OTP_REGION_STRAP;
2463d90825e2SJohnny Huang 			conf_region = &buf[1];
2464d90825e2SJohnny Huang 		}
2465d90825e2SJohnny Huang 	}
246669d5fd8fSJohnny Huang 	if (!nconfirm) {
2467a6d0d645SJohnny Huang 		if (mode == OTP_REGION_CONF) {
246866f2f8e5SJohnny Huang 			if (otp_print_conf_info(conf_region) < 0) {
246969d5fd8fSJohnny Huang 				printf("OTP config error, please check.\n");
24702a856b9aSJohnny Huang 				return OTP_FAILURE;
247169d5fd8fSJohnny Huang 			}
2472a6d0d645SJohnny Huang 		} else if (mode == OTP_REGION_DATA) {
2473d90825e2SJohnny Huang 			if (otp_data_parse(data_region) < 0) {
247469d5fd8fSJohnny Huang 				printf("OTP data error, please check.\n");
24752a856b9aSJohnny Huang 				return OTP_FAILURE;
247669d5fd8fSJohnny Huang 			}
2477a6d0d645SJohnny Huang 		} else if (mode == OTP_REGION_STRAP) {
2478*76d13988SJohnny Huang 			ret = otp_strap_image_confirm(strap_region);
2479a6af4a17SJohnny Huang 			if (ret == OTP_FAILURE) {
248069d5fd8fSJohnny Huang 				printf("OTP strap error, please check.\n");
24812a856b9aSJohnny Huang 				return OTP_FAILURE;
2482a6af4a17SJohnny Huang 			} else if (ret == OTP_PROG_SKIP) {
2483a6af4a17SJohnny Huang 				printf("OTP strap skip all\n");
2484a6af4a17SJohnny Huang 				return OTP_SUCCESS;
248569d5fd8fSJohnny Huang 			}
2486a6d0d645SJohnny Huang 		} else if (mode == OTP_REGION_ALL) {
248766f2f8e5SJohnny Huang 			if (otp_print_conf_info(conf_region) < 0) {
248869d5fd8fSJohnny Huang 				printf("OTP config error, please check.\n");
24892a856b9aSJohnny Huang 				return OTP_FAILURE;
249069d5fd8fSJohnny Huang 			}
2491*76d13988SJohnny Huang 			if (otp_strap_image_confirm(strap_region) == OTP_FAILURE) {
249269d5fd8fSJohnny Huang 				printf("OTP strap error, please check.\n");
24932a856b9aSJohnny Huang 				return OTP_FAILURE;
249469d5fd8fSJohnny Huang 			}
2495d90825e2SJohnny Huang 			if (otp_data_parse(data_region) < 0) {
249669d5fd8fSJohnny Huang 				printf("OTP data error, please check.\n");
24972a856b9aSJohnny Huang 				return OTP_FAILURE;
249869d5fd8fSJohnny Huang 			}
249969d5fd8fSJohnny Huang 		}
250069d5fd8fSJohnny Huang 		printf("type \"YES\" (no quotes) to continue:\n");
250169d5fd8fSJohnny Huang 		if (!confirm_yesno()) {
250269d5fd8fSJohnny Huang 			printf(" Aborting\n");
25032a856b9aSJohnny Huang 			return OTP_FAILURE;
250469d5fd8fSJohnny Huang 		}
250569d5fd8fSJohnny Huang 	}
2506a6d0d645SJohnny Huang 	if (mode == OTP_REGION_CONF) {
2507d90825e2SJohnny Huang 		return otp_prog_conf(conf_region);
2508a6d0d645SJohnny Huang 	} else if (mode == OTP_REGION_STRAP) {
2509d90825e2SJohnny Huang 		return otp_prog_strap(strap_region);
2510a6d0d645SJohnny Huang 	} else if (mode == OTP_REGION_DATA) {
2511d90825e2SJohnny Huang 		return otp_prog_data(data_region);
2512a6d0d645SJohnny Huang 	} else if (mode == OTP_REGION_ALL) {
251369d5fd8fSJohnny Huang 		printf("programing data region ... ");
2514d90825e2SJohnny Huang 		ret = otp_prog_data(data_region);
25152a856b9aSJohnny Huang 		if (ret != 0) {
251669d5fd8fSJohnny Huang 			printf("Error\n");
251769d5fd8fSJohnny Huang 			return ret;
251869d5fd8fSJohnny Huang 		} else {
251969d5fd8fSJohnny Huang 			printf("Done\n");
252069d5fd8fSJohnny Huang 		}
252169d5fd8fSJohnny Huang 		printf("programing strap region ... ");
2522d90825e2SJohnny Huang 		ret = otp_prog_strap(strap_region);
25232a856b9aSJohnny Huang 		if (ret != 0) {
252469d5fd8fSJohnny Huang 			printf("Error\n");
252569d5fd8fSJohnny Huang 			return ret;
252669d5fd8fSJohnny Huang 		} else {
252769d5fd8fSJohnny Huang 			printf("Done\n");
252869d5fd8fSJohnny Huang 		}
252969d5fd8fSJohnny Huang 		printf("programing configuration region ... ");
2530d90825e2SJohnny Huang 		ret = otp_prog_conf(conf_region);
25312a856b9aSJohnny Huang 		if (ret != 0) {
253269d5fd8fSJohnny Huang 			printf("Error\n");
253369d5fd8fSJohnny Huang 			return ret;
253469d5fd8fSJohnny Huang 		}
253569d5fd8fSJohnny Huang 		printf("Done\n");
25362a856b9aSJohnny Huang 		return OTP_SUCCESS;
253769d5fd8fSJohnny Huang 	}
2538cd1610b4SJohnny Huang 
25392a856b9aSJohnny Huang 	return OTP_USAGE;
25402a856b9aSJohnny Huang }
25412a856b9aSJohnny Huang 
25422a856b9aSJohnny Huang static int do_otp_prog_bit(int mode, int otp_dw_offset, int bit_offset, int value, int nconfirm)
2543cd1610b4SJohnny Huang {
2544a6af4a17SJohnny Huang 	uint32_t read[2];
2545cd1610b4SJohnny Huang 	uint32_t strap_buf[6];
2546d90825e2SJohnny Huang 	uint32_t prog_address = 0;
254766f2f8e5SJohnny Huang 	struct otpstrap_status otpstrap[64];
2548cd1610b4SJohnny Huang 	int otp_bit;
2549cd1610b4SJohnny Huang 	int i;
2550cd1610b4SJohnny Huang 	int pass;
2551a6af4a17SJohnny Huang 	int ret;
2552cd1610b4SJohnny Huang 
2553cd1610b4SJohnny Huang 	switch (mode) {
2554a6d0d645SJohnny Huang 	case OTP_REGION_CONF:
2555a6af4a17SJohnny Huang 		otp_read_config(otp_dw_offset, read);
2556cd1610b4SJohnny Huang 		prog_address = 0x800;
2557cd1610b4SJohnny Huang 		prog_address |= (otp_dw_offset / 8) * 0x200;
2558cd1610b4SJohnny Huang 		prog_address |= (otp_dw_offset % 8) * 0x2;
2559a6af4a17SJohnny Huang 		otp_bit = (read[0] >> bit_offset) & 0x1;
2560cd1610b4SJohnny Huang 		if (otp_bit == value) {
2561a6af4a17SJohnny Huang 			printf("OTPCFG%X[%X] = %d\n", otp_dw_offset, bit_offset, value);
2562cd1610b4SJohnny Huang 			printf("No need to program\n");
25632a856b9aSJohnny Huang 			return OTP_SUCCESS;
2564cd1610b4SJohnny Huang 		}
2565cd1610b4SJohnny Huang 		if (otp_bit == 1 && value == 0) {
2566a6af4a17SJohnny Huang 			printf("OTPCFG%X[%X] = 1\n", otp_dw_offset, bit_offset);
2567cd1610b4SJohnny Huang 			printf("OTP is programed, which can't be clean\n");
25682a856b9aSJohnny Huang 			return OTP_FAILURE;
2569cd1610b4SJohnny Huang 		}
2570a6af4a17SJohnny Huang 		printf("Program OTPCFG%X[%X] to 1\n", otp_dw_offset, bit_offset);
2571cd1610b4SJohnny Huang 		break;
2572a6d0d645SJohnny Huang 	case OTP_REGION_DATA:
2573cd1610b4SJohnny Huang 		prog_address = otp_dw_offset;
2574cd1610b4SJohnny Huang 
2575cd1610b4SJohnny Huang 		if (otp_dw_offset % 2 == 0) {
2576a6af4a17SJohnny Huang 			otp_read_data(otp_dw_offset, read);
2577a6af4a17SJohnny Huang 			otp_bit = (read[0] >> bit_offset) & 0x1;
2578cd1610b4SJohnny Huang 		} else {
2579a6af4a17SJohnny Huang 			otp_read_data(otp_dw_offset - 1, read);
2580a6af4a17SJohnny Huang 			otp_bit = (read[1] >> bit_offset) & 0x1;
2581cd1610b4SJohnny Huang 		}
2582cd1610b4SJohnny Huang 		if (otp_bit == value) {
2583a6af4a17SJohnny Huang 			printf("OTPDATA%X[%X] = %d\n", otp_dw_offset, bit_offset, value);
2584cd1610b4SJohnny Huang 			printf("No need to program\n");
25852a856b9aSJohnny Huang 			return OTP_SUCCESS;
2586cd1610b4SJohnny Huang 		}
2587cd1610b4SJohnny Huang 		if (otp_bit == 1 && value == 0) {
2588a6af4a17SJohnny Huang 			printf("OTPDATA%X[%X] = 1\n", otp_dw_offset, bit_offset);
2589cd1610b4SJohnny Huang 			printf("OTP is programed, which can't be clean\n");
25902a856b9aSJohnny Huang 			return OTP_FAILURE;
2591cd1610b4SJohnny Huang 		}
2592a6af4a17SJohnny Huang 		printf("Program OTPDATA%X[%X] to 1\n", otp_dw_offset, bit_offset);
2593cd1610b4SJohnny Huang 		break;
2594a6d0d645SJohnny Huang 	case OTP_REGION_STRAP:
2595cd1610b4SJohnny Huang 		otp_strp_status(otpstrap);
2596cd1610b4SJohnny Huang 		otp_print_strap(bit_offset, 1);
2597cd1610b4SJohnny Huang 		if (bit_offset < 32) {
2598cd1610b4SJohnny Huang 			strap_buf[0] = value << bit_offset;
2599cd1610b4SJohnny Huang 			strap_buf[2] = ~BIT(bit_offset);
2600cd1610b4SJohnny Huang 			strap_buf[3] = ~0;
2601cd1610b4SJohnny Huang 			strap_buf[5] = 0;
26022a856b9aSJohnny Huang 			// if (protect)
26032a856b9aSJohnny Huang 			// 	strap_buf[4] = BIT(bit_offset);
26042a856b9aSJohnny Huang 			// else
26052a856b9aSJohnny Huang 			// 	strap_buf[4] = 0;
2606cd1610b4SJohnny Huang 		} else {
2607cd1610b4SJohnny Huang 			strap_buf[1] = value << (bit_offset - 32);
2608cd1610b4SJohnny Huang 			strap_buf[2] = ~0;
2609cd1610b4SJohnny Huang 			strap_buf[3] = ~BIT(bit_offset - 32);
2610cd1610b4SJohnny Huang 			strap_buf[4] = 0;
26112a856b9aSJohnny Huang 			// if (protect)
26122a856b9aSJohnny Huang 			// 	strap_buf[5] = BIT(bit_offset - 32);
26132a856b9aSJohnny Huang 			// else
26142a856b9aSJohnny Huang 			// 	strap_buf[5] = 0;
2615cd1610b4SJohnny Huang 		}
2616*76d13988SJohnny Huang 		ret = otp_strap_image_confirm(strap_buf);
2617a6af4a17SJohnny Huang 		if (ret == OTP_FAILURE)
26182a856b9aSJohnny Huang 			return OTP_FAILURE;
2619a6af4a17SJohnny Huang 		else if (ret == OTP_PROG_SKIP)
2620a6af4a17SJohnny Huang 			return OTP_SUCCESS;
2621a6af4a17SJohnny Huang 
2622cd1610b4SJohnny Huang 		break;
2623cd1610b4SJohnny Huang 	}
2624cd1610b4SJohnny Huang 
2625cd1610b4SJohnny Huang 	if (!nconfirm) {
2626cd1610b4SJohnny Huang 		printf("type \"YES\" (no quotes) to continue:\n");
2627cd1610b4SJohnny Huang 		if (!confirm_yesno()) {
2628cd1610b4SJohnny Huang 			printf(" Aborting\n");
26292a856b9aSJohnny Huang 			return OTP_FAILURE;
2630cd1610b4SJohnny Huang 		}
2631cd1610b4SJohnny Huang 	}
2632cd1610b4SJohnny Huang 
2633cd1610b4SJohnny Huang 	switch (mode) {
2634a6d0d645SJohnny Huang 	case OTP_REGION_STRAP:
2635cd1610b4SJohnny Huang 		return otp_prog_strap(strap_buf);
2636a6d0d645SJohnny Huang 	case OTP_REGION_CONF:
2637a6d0d645SJohnny Huang 	case OTP_REGION_DATA:
2638cd1610b4SJohnny Huang 		otp_prog_bit(value, prog_address, bit_offset, 0);
2639cd1610b4SJohnny Huang 		pass = -1;
2640cd1610b4SJohnny Huang 		for (i = 0; i < RETRY; i++) {
2641a6d0d645SJohnny Huang 			if (verify_bit(prog_address, bit_offset, value) != 0) {
2642cd1610b4SJohnny Huang 				otp_prog_bit(value, prog_address, bit_offset, 1);
2643cd1610b4SJohnny Huang 			} else {
2644cd1610b4SJohnny Huang 				pass = 0;
2645cd1610b4SJohnny Huang 				break;
2646cd1610b4SJohnny Huang 			}
2647cd1610b4SJohnny Huang 		}
26482a856b9aSJohnny Huang 		if (pass == 0)
26492a856b9aSJohnny Huang 			return OTP_SUCCESS;
2650cd1610b4SJohnny Huang 	}
2651cd1610b4SJohnny Huang 
26522a856b9aSJohnny Huang 	return OTP_USAGE;
2653cd1610b4SJohnny Huang }
2654cd1610b4SJohnny Huang 
26552a856b9aSJohnny Huang static int do_otpread(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
265669d5fd8fSJohnny Huang {
26572a856b9aSJohnny Huang 	uint32_t offset, count;
26582a856b9aSJohnny Huang 	int ret;
265969d5fd8fSJohnny Huang 
26602a856b9aSJohnny Huang 	if (argc == 4) {
26612a856b9aSJohnny Huang 		offset = simple_strtoul(argv[2], NULL, 16);
26622a856b9aSJohnny Huang 		count = simple_strtoul(argv[3], NULL, 16);
26632a856b9aSJohnny Huang 	} else if (argc == 3) {
26642a856b9aSJohnny Huang 		offset = simple_strtoul(argv[2], NULL, 16);
26652a856b9aSJohnny Huang 		count = 1;
26662a856b9aSJohnny Huang 	} else {
266769d5fd8fSJohnny Huang 		return CMD_RET_USAGE;
266869d5fd8fSJohnny Huang 	}
266969d5fd8fSJohnny Huang 
267069d5fd8fSJohnny Huang 
26712a856b9aSJohnny Huang 	if (!strcmp(argv[1], "conf")) {
267269d5fd8fSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
26732a856b9aSJohnny Huang 		ret = otp_print_config(offset, count);
26742a856b9aSJohnny Huang 	} else if (!strcmp(argv[1], "data")) {
26752a856b9aSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
26762a856b9aSJohnny Huang 		ret = otp_print_data(offset, count);
26772a856b9aSJohnny Huang 	} else if (!strcmp(argv[1], "strap")) {
26782a856b9aSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
26792a856b9aSJohnny Huang 		ret = otp_print_strap(offset, count);
26802a856b9aSJohnny Huang 	} else {
26812a856b9aSJohnny Huang 		return CMD_RET_USAGE;
268269d5fd8fSJohnny Huang 	}
268369d5fd8fSJohnny Huang 
26842a856b9aSJohnny Huang 	if (ret == OTP_SUCCESS)
26852a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
26862a856b9aSJohnny Huang 	else
26872a856b9aSJohnny Huang 		return CMD_RET_USAGE;
26882a856b9aSJohnny Huang 
26892a856b9aSJohnny Huang }
26902a856b9aSJohnny Huang 
26912a856b9aSJohnny Huang static int do_otpprog(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
26922a856b9aSJohnny Huang {
26932a856b9aSJohnny Huang 	phys_addr_t addr;
26942a856b9aSJohnny Huang 	uint32_t byte_size;
26952a856b9aSJohnny Huang 	int ret;
26962a856b9aSJohnny Huang 
26972a856b9aSJohnny Huang 	if (argc == 4) {
26982a856b9aSJohnny Huang 		if (strcmp(argv[1], "f"))
26992a856b9aSJohnny Huang 			return CMD_RET_USAGE;
27002a856b9aSJohnny Huang 		addr = simple_strtoul(argv[2], NULL, 16);
27012a856b9aSJohnny Huang 		byte_size = simple_strtoul(argv[3], NULL, 16);
270269d5fd8fSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
27032a856b9aSJohnny Huang 		ret = do_otp_prog(addr, byte_size, 1);
27042a856b9aSJohnny Huang 	} else if (argc == 3) {
27052a856b9aSJohnny Huang 		addr = simple_strtoul(argv[1], NULL, 16);
27062a856b9aSJohnny Huang 		byte_size = simple_strtoul(argv[2], NULL, 16);
27072a856b9aSJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
27082a856b9aSJohnny Huang 		ret = do_otp_prog(addr, byte_size, 0);
27092a856b9aSJohnny Huang 	} else {
27102a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27112a856b9aSJohnny Huang 	}
27122a856b9aSJohnny Huang 
27132a856b9aSJohnny Huang 	if (ret == OTP_SUCCESS)
27142a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
27152a856b9aSJohnny Huang 	else if (ret == OTP_FAILURE)
27162a856b9aSJohnny Huang 		return CMD_RET_FAILURE;
27172a856b9aSJohnny Huang 	else
27182a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27192a856b9aSJohnny Huang }
27202a856b9aSJohnny Huang 
27212a856b9aSJohnny Huang static int do_otppb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
27222a856b9aSJohnny Huang {
27232a856b9aSJohnny Huang 	int mode = 0;
27242a856b9aSJohnny Huang 	int nconfirm = 0;
27252a856b9aSJohnny Huang 	int otp_addr = 0;
27262a856b9aSJohnny Huang 	int bit_offset;
27272a856b9aSJohnny Huang 	int value;
27282a856b9aSJohnny Huang 	int ret;
27292a856b9aSJohnny Huang 
27302a856b9aSJohnny Huang 	if (argc != 4 && argc != 5 && argc != 6)
27312a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27322a856b9aSJohnny Huang 
27332a856b9aSJohnny Huang 	/* Drop the pb cmd */
27342a856b9aSJohnny Huang 	argc--;
27352a856b9aSJohnny Huang 	argv++;
27362a856b9aSJohnny Huang 
27372a856b9aSJohnny Huang 	if (!strcmp(argv[0], "conf"))
2738a6d0d645SJohnny Huang 		mode = OTP_REGION_CONF;
27392a856b9aSJohnny Huang 	else if (!strcmp(argv[0], "strap"))
2740a6d0d645SJohnny Huang 		mode = OTP_REGION_STRAP;
27412a856b9aSJohnny Huang 	else if (!strcmp(argv[0], "data"))
2742a6d0d645SJohnny Huang 		mode = OTP_REGION_DATA;
2743cd1610b4SJohnny Huang 	else
27442a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27452a856b9aSJohnny Huang 
27462a856b9aSJohnny Huang 	/* Drop the region cmd */
27472a856b9aSJohnny Huang 	argc--;
27482a856b9aSJohnny Huang 	argv++;
27492a856b9aSJohnny Huang 
27502a856b9aSJohnny Huang 	if (!strcmp(argv[0], "f")) {
2751cd1610b4SJohnny Huang 		nconfirm = 1;
27522a856b9aSJohnny Huang 		/* Drop the force option */
27532a856b9aSJohnny Huang 		argc--;
27542a856b9aSJohnny Huang 		argv++;
27552a856b9aSJohnny Huang 	}
2756cd1610b4SJohnny Huang 
2757a6d0d645SJohnny Huang 	if (mode == OTP_REGION_STRAP) {
27582a856b9aSJohnny Huang 		bit_offset = simple_strtoul(argv[0], NULL, 16);
27592a856b9aSJohnny Huang 		value = simple_strtoul(argv[1], NULL, 16);
2760cd1610b4SJohnny Huang 		if (bit_offset >= 64)
27612a856b9aSJohnny Huang 			return CMD_RET_USAGE;
2762cd1610b4SJohnny Huang 	} else {
27632a856b9aSJohnny Huang 		otp_addr = simple_strtoul(argv[0], NULL, 16);
27642a856b9aSJohnny Huang 		bit_offset = simple_strtoul(argv[1], NULL, 16);
27652a856b9aSJohnny Huang 		value = simple_strtoul(argv[2], NULL, 16);
2766cd1610b4SJohnny Huang 		if (bit_offset >= 32)
27672a856b9aSJohnny Huang 			return CMD_RET_USAGE;
2768cd1610b4SJohnny Huang 	}
2769cd1610b4SJohnny Huang 	if (value != 0 && value != 1)
27702a856b9aSJohnny Huang 		return CMD_RET_USAGE;
2771cd1610b4SJohnny Huang 
2772cd1610b4SJohnny Huang 	writel(OTP_PASSWD, 0x1e6f2000); //password
27732a856b9aSJohnny Huang 	ret = do_otp_prog_bit(mode, otp_addr, bit_offset, value, nconfirm);
27742a856b9aSJohnny Huang 
27752a856b9aSJohnny Huang 	if (ret == OTP_SUCCESS)
27762a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
27772a856b9aSJohnny Huang 	else if (ret == OTP_FAILURE)
27782a856b9aSJohnny Huang 		return CMD_RET_FAILURE;
27792a856b9aSJohnny Huang 	else
27802a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27812a856b9aSJohnny Huang }
27822a856b9aSJohnny Huang 
27832a856b9aSJohnny Huang static int do_otpcmp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
27842a856b9aSJohnny Huang {
27852a856b9aSJohnny Huang 	phys_addr_t addr;
27862a856b9aSJohnny Huang 	int otp_addr = 0;
27872a856b9aSJohnny Huang 
27882a856b9aSJohnny Huang 	if (argc != 3)
27892a856b9aSJohnny Huang 		return CMD_RET_USAGE;
27902a856b9aSJohnny Huang 
279169d5fd8fSJohnny Huang 	writel(OTP_PASSWD, 0x1e6f2000); //password
27922a856b9aSJohnny Huang 	addr = simple_strtoul(argv[1], NULL, 16);
27932a856b9aSJohnny Huang 	otp_addr = simple_strtoul(argv[2], NULL, 16);
27942a856b9aSJohnny Huang 	if (otp_compare(otp_addr, addr) == 0) {
279569d5fd8fSJohnny Huang 		printf("Compare pass\n");
27962a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
279769d5fd8fSJohnny Huang 	} else {
279869d5fd8fSJohnny Huang 		printf("Compare fail\n");
27992a856b9aSJohnny Huang 		return CMD_RET_FAILURE;
280069d5fd8fSJohnny Huang 	}
280169d5fd8fSJohnny Huang }
280269d5fd8fSJohnny Huang 
280366f2f8e5SJohnny Huang static int do_otpinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
280466f2f8e5SJohnny Huang {
280566f2f8e5SJohnny Huang 	if (argc != 2)
280666f2f8e5SJohnny Huang 		return CMD_RET_USAGE;
280766f2f8e5SJohnny Huang 
280866f2f8e5SJohnny Huang 
280966f2f8e5SJohnny Huang 	if (!strcmp(argv[1], "conf")) {
281066f2f8e5SJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
281166f2f8e5SJohnny Huang 		otp_info_config();
281266f2f8e5SJohnny Huang 	} else if (!strcmp(argv[1], "strap")) {
281366f2f8e5SJohnny Huang 		writel(OTP_PASSWD, 0x1e6f2000); //password
2814*76d13988SJohnny Huang 		otp_info_strap();
281566f2f8e5SJohnny Huang 	} else {
281666f2f8e5SJohnny Huang 		return CMD_RET_USAGE;
281766f2f8e5SJohnny Huang 	}
281866f2f8e5SJohnny Huang 
281966f2f8e5SJohnny Huang 	return CMD_RET_SUCCESS;
282066f2f8e5SJohnny Huang }
282166f2f8e5SJohnny Huang 
28222a856b9aSJohnny Huang static cmd_tbl_t cmd_otp[] = {
28232a856b9aSJohnny Huang 	U_BOOT_CMD_MKENT(read, 4, 0, do_otpread, "", ""),
28242a856b9aSJohnny Huang 	U_BOOT_CMD_MKENT(prog, 4, 0, do_otpprog, "", ""),
28252a856b9aSJohnny Huang 	U_BOOT_CMD_MKENT(pb, 6, 0, do_otppb, "", ""),
28262a856b9aSJohnny Huang 	U_BOOT_CMD_MKENT(cmp, 3, 0, do_otpcmp, "", ""),
282766f2f8e5SJohnny Huang 	U_BOOT_CMD_MKENT(info, 3, 0, do_otpinfo, "", ""),
282869d5fd8fSJohnny Huang 
28292a856b9aSJohnny Huang };
28302a856b9aSJohnny Huang 
28312a856b9aSJohnny Huang static int do_ast_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
28322a856b9aSJohnny Huang {
28332a856b9aSJohnny Huang 	cmd_tbl_t *cp;
28342a856b9aSJohnny Huang 
28352a856b9aSJohnny Huang 	cp = find_cmd_tbl(argv[1], cmd_otp, ARRAY_SIZE(cmd_otp));
28362a856b9aSJohnny Huang 
28372a856b9aSJohnny Huang 	/* Drop the mmc command */
28382a856b9aSJohnny Huang 	argc--;
28392a856b9aSJohnny Huang 	argv++;
28402a856b9aSJohnny Huang 
28412a856b9aSJohnny Huang 	if (cp == NULL || argc > cp->maxargs)
28422a856b9aSJohnny Huang 		return CMD_RET_USAGE;
28432a856b9aSJohnny Huang 	if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
28442a856b9aSJohnny Huang 		return CMD_RET_SUCCESS;
28452a856b9aSJohnny Huang 
28462a856b9aSJohnny Huang 	return cp->cmd(cmdtp, flag, argc, argv);
284769d5fd8fSJohnny Huang }
284869d5fd8fSJohnny Huang 
284969d5fd8fSJohnny Huang U_BOOT_CMD(
285069d5fd8fSJohnny Huang 	otp, 7, 0,  do_ast_otp,
285169d5fd8fSJohnny Huang 	"ASPEED One-Time-Programmable sub-system",
28522a856b9aSJohnny Huang 	"read conf|data <otp_dw_offset> <dw_count>\n"
28532a856b9aSJohnny Huang 	"otp read strap <strap_bit_offset> <bit_count>\n"
2854*76d13988SJohnny Huang 	"otp info conf|strap\n"
2855d90825e2SJohnny Huang 	"otp prog [f] <addr> <byte_size>\n"
2856cd1610b4SJohnny Huang 	"otp pb conf|data [f] <otp_dw_offset> <bit_offset> <value>\n"
2857cd1610b4SJohnny Huang 	"otp pb strap [f] <bit_offset> <value> <protect>\n"
28582a856b9aSJohnny Huang 	"otp cmp <addr> <otp_dw_offset>\n"
285969d5fd8fSJohnny Huang );
2860