1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2014-2016, Toradex AG
4  */
5 
6 /*
7  * Helpers for i.MX OTP fusing during module production
8 */
9 
10 #include <common.h>
11 #ifndef CONFIG_SPL_BUILD
12 #include <console.h>
13 #include <fuse.h>
14 
15 static int mfgr_fuse(void)
16 {
17 	unsigned val, val6;
18 
19 	fuse_sense(0, 5, &val);
20 	printf("Fuse 0, 5: %8x\n", val);
21 	fuse_sense(0, 6, &val6);
22 	printf("Fuse 0, 6: %8x\n", val6);
23 	fuse_sense(4, 3, &val);
24 	printf("Fuse 4, 3: %8x\n", val);
25 	fuse_sense(4, 2, &val);
26 	printf("Fuse 4, 2: %8x\n", val);
27 	if (val6 & 0x10) {
28 		puts("BT_FUSE_SEL already fused, will do nothing\n");
29 		return CMD_RET_FAILURE;
30 	}
31 	/* boot cfg */
32 	fuse_prog(0, 5, 0x00005072);
33 	/* BT_FUSE_SEL */
34 	fuse_prog(0, 6, 0x00000010);
35 	return CMD_RET_SUCCESS;
36 }
37 
38 int do_mfgr_fuse(cmd_tbl_t *cmdtp, int flag, int argc,
39 		char * const argv[])
40 {
41 	int ret;
42 	puts("Fusing...\n");
43 	ret = mfgr_fuse();
44 	if (ret == CMD_RET_SUCCESS)
45 		puts("done.\n");
46 	else
47 		puts("failed.\n");
48 	return ret;
49 }
50 
51 int do_updt_fuse(cmd_tbl_t *cmdtp, int flag, int argc,
52 		char * const argv[])
53 {
54 	unsigned val;
55 	int ret;
56 	int confirmed = argc >= 1 && !strcmp(argv[1], "-y");
57 
58 	/* can be used in scripts for command availability check */
59 	if (argc >= 1 && !strcmp(argv[1], "-n"))
60 		return CMD_RET_SUCCESS;
61 
62 	/* boot cfg */
63 	fuse_sense(0, 5, &val);
64 	printf("Fuse 0, 5: %8x\n", val);
65 	if (val & 0x10) {
66 		puts("Fast boot mode already fused, no need to fuse\n");
67 		return CMD_RET_SUCCESS;
68 	}
69 	if (!confirmed) {
70 		puts("Warning: Programming fuses is an irreversible operation!\n"
71 				"         Updating to fast boot mode prevents easy\n"
72 				"         downgrading to previous BSP versions.\n"
73 				"\nReally perform this fuse programming? <y/N>\n");
74 		if (!confirm_yesno())
75 			return CMD_RET_FAILURE;
76 	}
77 	puts("Fusing fast boot mode...\n");
78 	ret = fuse_prog(0, 5, 0x00005072);
79 	if (ret == CMD_RET_SUCCESS)
80 		puts("done.\n");
81 	else
82 		puts("failed.\n");
83 	return ret;
84 }
85 
86 U_BOOT_CMD(
87 	mfgr_fuse, 1, 0, do_mfgr_fuse,
88 	"OTP fusing during module production",
89 	""
90 );
91 
92 U_BOOT_CMD(
93 	updt_fuse, 2, 0, do_updt_fuse,
94 	"OTP fusing during module update",
95 	"updt_fuse [-n] [-y] - boot cfg fast boot mode fusing"
96 );
97 #endif /* CONFIG_SPL_BUILD */
98