1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * MediaTek BootROM NAND header definitions
4  *
5  * Copyright (C) 2022 MediaTek Inc.
6  * Author: Weijie Gao <weijie.gao@mediatek.com>
7  */
8 
9 #include <stdint.h>
10 #include <string.h>
11 #include "imagetool.h"
12 #include "mtk_image.h"
13 #include "mtk_nand_headers.h"
14 
15 /* NAND header for SPI-NAND with 2KB page + 64B spare */
16 static const union nand_boot_header snand_hdr_2k_64_data = {
17 	.data = {
18 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
19 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
20 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
21 		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
22 		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
23 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
31 		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
32 		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
33 		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
34 	}
35 };
36 
37 /* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
38 static const union nand_boot_header snand_hdr_2k_128_data = {
39 	.data = {
40 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
41 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
42 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
43 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
44 		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
45 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
53 		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
54 		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
55 		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
56 	}
57 };
58 
59 /* NAND header for SPI-NAND with 4KB page + 256B spare */
60 static const union nand_boot_header snand_hdr_4k_256_data = {
61 	.data = {
62 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
63 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
64 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
65 		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
66 		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
67 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
75 		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
76 		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
77 		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
78 	}
79 };
80 
81 /* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
82 static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
83 	.data = {
84 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
85 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
86 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
87 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
88 		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
89 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
97 		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
98 		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
99 		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
100 	}
101 };
102 
103 /* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
104 static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
105 	.data = {
106 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
107 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
108 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
109 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
110 		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
111 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
119 		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
120 		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
121 		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
122 	}
123 };
124 
125 /* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
126 static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
127 	.data = {
128 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
129 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
130 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
131 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
132 		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
133 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
141 		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
142 		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
143 		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
144 	}
145 };
146 
147 /* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
148 static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
149 	.data = {
150 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
151 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
152 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
153 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
154 		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
155 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
163 		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
164 		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
165 		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
166 	}
167 };
168 
169 /* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
170 static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
171 	.data = {
172 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
173 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
174 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
175 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
176 		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
177 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
185 		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
186 		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
187 		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
188 	}
189 };
190 
191 /* HSM BROM NAND header for SPI NAND with 2KB page + 64B spare */
192 static const union hsm_nand_boot_header hsm_nand_hdr_2k_64_data = {
193 	.data = {
194 		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
195 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
197 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 		0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
199 		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
200 		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
206 		0xFF, 0x00, 0x00, 0x00, 0x21, 0xD2, 0xEE, 0xF6,
207 		0xAE, 0xDD, 0x5E, 0xC2, 0x82, 0x8E, 0x9A, 0x62,
208 		0x09, 0x8E, 0x80, 0xE2, 0x37, 0x0D, 0xC9, 0xFA,
209 		0xA9, 0xDD, 0xFC, 0x92, 0x34, 0x2A, 0xED, 0x51,
210 		0xA4, 0x1B, 0xF7, 0x63, 0xCC, 0x5A, 0xC7, 0xFB,
211 		0xED, 0x21, 0x02, 0x23, 0x51, 0x31
212 	}
213 };
214 
215 /* HSM BROM NAND header for SPI NAND with 2KB page + 128B spare */
216 static const union hsm_nand_boot_header hsm_nand_hdr_2k_128_data = {
217 	.data = {
218 		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
219 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220 		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
221 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 		0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
223 		0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
224 		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
229 		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
230 		0xFF, 0x00, 0x00, 0x00, 0x71, 0x7f, 0x71, 0xAC,
231 		0x42, 0xD0, 0x5B, 0xD2, 0x12, 0x81, 0x15, 0x0A,
232 		0x0C, 0xD4, 0xF6, 0x32, 0x1E, 0x63, 0xE7, 0x81,
233 		0x8A, 0x7F, 0xDE, 0xF9, 0x4B, 0x91, 0xEC, 0xC2,
234 		0x70, 0x00, 0x7F, 0x57, 0xAF, 0xDC, 0xE4, 0x24,
235 		0x57, 0x09, 0xBC, 0xC5, 0x35, 0xDC
236 	}
237 };
238 
239 /* HSM BROM NAND header for SPI NAND with 4KB page + 256B spare */
240 static const union hsm_nand_boot_header hsm_nand_hdr_4k_256_data = {
241 	.data = {
242 		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
243 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
245 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 		0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
247 		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
248 		0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
249 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253 		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
254 		0xFF, 0x00, 0x00, 0x00, 0x62, 0x04, 0xD6, 0x1F,
255 		0x2B, 0x57, 0x7A, 0x2D, 0xFE, 0xBB, 0x4A, 0x50,
256 		0xEC, 0xF8, 0x70, 0x1A, 0x44, 0x15, 0xF6, 0xA2,
257 		0x8E, 0xB0, 0xFD, 0xFA, 0xDC, 0xAA, 0x5A, 0x4E,
258 		0xCB, 0x8E, 0xC9, 0x72, 0x08, 0xDC, 0x20, 0xB9,
259 		0x98, 0xC8, 0x82, 0xD8, 0xBE, 0x44
260 	}
261 };
262 
263 /* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 64B spare */
264 static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_64_data = {
265 	.data = {
266 		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
267 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
268 		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
269 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 		0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
271 		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
272 		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 		0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
278 		0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
279 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 		0x5F, 0x4B, 0xB2, 0x5B, 0x8B, 0x1C, 0x35, 0xDA,
291 		0x83, 0xE6, 0x6C, 0xC3, 0xFB, 0x8C, 0x78, 0x23,
292 		0xD0, 0x89, 0x24, 0xD9, 0x6C, 0x35, 0x2C, 0x5D,
293 		0x8F, 0xBB, 0xFC, 0x10, 0xD0, 0xE2, 0x22, 0x7D,
294 		0xC8, 0x97, 0x9A, 0xEF, 0xC6, 0xB5, 0xA7, 0x4E,
295 		0x4E, 0x0E
296 	}
297 };
298 
299 /* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 128B spare */
300 static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_128_data = {
301 	.data = {
302 		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
303 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
304 		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
305 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 		0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
307 		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
308 		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 		0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
314 		0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
315 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 		0xF8, 0x7E, 0xC1, 0x5D, 0x61, 0x54, 0xEA, 0x9F,
327 		0x5E, 0x66, 0x39, 0x66, 0x21, 0xFF, 0x8C, 0x3B,
328 		0xBE, 0xA7, 0x5A, 0x9E, 0xD7, 0xBD, 0x9E, 0x89,
329 		0xEE, 0x7E, 0x10, 0x31, 0x9A, 0x1D, 0x82, 0x49,
330 		0xA3, 0x4E, 0xD8, 0x47, 0xD7, 0x19, 0xF4, 0x2D,
331 		0x8E, 0x53
332 	}
333 };
334 
335 /* HSM2.0 BROM NAND header for SPI NAND with 4KB page + 256B spare */
336 static const union hsm20_nand_boot_header hsm20_nand_hdr_4k_256_data = {
337 	.data = {
338 		0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21,
339 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
340 		0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
341 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 		0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
343 		0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
344 		0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 		0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
350 		0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
351 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 		0x79, 0x01, 0x1F, 0x86, 0x62, 0x6A, 0x43, 0xAE,
363 		0xE6, 0xF8, 0xDD, 0x5B, 0x29, 0xB7, 0xA2, 0x7F,
364 		0x29, 0x72, 0x54, 0x37, 0xBE, 0x50, 0xD4, 0x24,
365 		0xAB, 0x60, 0xF4, 0x44, 0x97, 0x3B, 0x65, 0x21,
366 		0x73, 0x24, 0x1F, 0x93, 0x0E, 0x9E, 0x96, 0x88,
367 		0x78, 0x6C
368 	}
369 };
370 
371 /* SPIM-NAND header for SPI NAND with 2KB page + 64B spare */
372 static const union spim_nand_boot_header spim_nand_hdr_2k_64_data = {
373 	.data = {
374 		0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
375 		0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
376 		0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
377 		0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30,
378 		0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
379 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
384 	}
385 };
386 
387 /* SPIM-NAND header for SPI NAND with 2KB page + 128B spare */
388 static const union spim_nand_boot_header spim_nand_hdr_2k_128_data = {
389 	.data = {
390 		0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
391 		0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
392 		0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
393 		0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30,
394 		0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
395 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
400 	}
401 };
402 
403 /* SPIM-NAND header for SPI NAND with 4KB page + 256B spare */
404 static const union spim_nand_boot_header spim_nand_hdr_4k_256_data = {
405 	.data = {
406 		0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21,
407 		0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
408 		0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
409 		0x40, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x30,
410 		0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
411 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
416 	}
417 };
418 
419 struct nand_header_type {
420 	const char *name;
421 	enum nand_boot_header_type type;
422 	union {
423 		const union nand_boot_header *ap;
424 		const union hsm_nand_boot_header *hsm;
425 		const union hsm20_nand_boot_header *hsm20;
426 		const union spim_nand_boot_header *spim;
427 	};
428 } nand_headers[] = {
429 	{
430 		.name = "2k+64",
431 		.type = NAND_BOOT_AP_HEADER,
432 		.ap = &snand_hdr_2k_64_data,
433 	}, {
434 		.name = "2k+120",
435 		.type = NAND_BOOT_AP_HEADER,
436 		.ap = &snand_hdr_2k_128_data,
437 	}, {
438 		.name = "2k+128",
439 		.type = NAND_BOOT_AP_HEADER,
440 		.ap = &snand_hdr_2k_128_data,
441 	}, {
442 		.name = "4k+256",
443 		.type = NAND_BOOT_AP_HEADER,
444 		.ap = &snand_hdr_4k_256_data,
445 	}, {
446 		.name = "1g:2k+64",
447 		.type = NAND_BOOT_AP_HEADER,
448 		.ap = &nand_hdr_1gb_2k_64_data,
449 	}, {
450 		.name = "2g:2k+64",
451 		.type = NAND_BOOT_AP_HEADER,
452 		.ap = &nand_hdr_2gb_2k_64_data,
453 	}, {
454 		.name = "4g:2k+64",
455 		.type = NAND_BOOT_AP_HEADER,
456 		.ap = &nand_hdr_4gb_2k_64_data,
457 	}, {
458 		.name = "2g:2k+128",
459 		.type = NAND_BOOT_AP_HEADER,
460 		.ap = &nand_hdr_2gb_2k_128_data,
461 	}, {
462 		.name = "4g:2k+128",
463 		.type = NAND_BOOT_AP_HEADER,
464 		.ap = &nand_hdr_4gb_2k_128_data,
465 	}, {
466 		.name = "hsm:2k+64",
467 		.type = NAND_BOOT_HSM_HEADER,
468 		.hsm = &hsm_nand_hdr_2k_64_data,
469 	}, {
470 		.name = "hsm:2k+128",
471 		.type = NAND_BOOT_HSM_HEADER,
472 		.hsm = &hsm_nand_hdr_2k_128_data,
473 	}, {
474 		.name = "hsm:4k+256",
475 		.type = NAND_BOOT_HSM_HEADER,
476 		.hsm = &hsm_nand_hdr_4k_256_data,
477 	},  {
478 		.name = "hsm20:2k+64",
479 		.type = NAND_BOOT_HSM20_HEADER,
480 		.hsm20 = &hsm20_nand_hdr_2k_64_data,
481 	}, {
482 		.name = "hsm20:2k+128",
483 		.type = NAND_BOOT_HSM20_HEADER,
484 		.hsm20 = &hsm20_nand_hdr_2k_128_data,
485 	}, {
486 		.name = "hsm20:4k+256",
487 		.type = NAND_BOOT_HSM20_HEADER,
488 		.hsm20 = &hsm20_nand_hdr_4k_256_data,
489 	}, {
490 		.name = "spim:2k+64",
491 		.type = NAND_BOOT_SPIM_HEADER,
492 		.spim = &spim_nand_hdr_2k_64_data,
493 	}, {
494 		.name = "spim:2k+128",
495 		.type = NAND_BOOT_SPIM_HEADER,
496 		.spim = &spim_nand_hdr_2k_128_data,
497 	}, {
498 		.name = "spim:4k+256",
499 		.type = NAND_BOOT_SPIM_HEADER,
500 		.spim = &spim_nand_hdr_4k_256_data,
501 	}
502 };
503 
mtk_nand_header_find(const char * name)504 const struct nand_header_type *mtk_nand_header_find(const char *name)
505 {
506 	uint32_t i;
507 
508 	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
509 		if (!strcmp(nand_headers[i].name, name))
510 			return &nand_headers[i];
511 	}
512 
513 	return NULL;
514 }
515 
mtk_nand_header_size(const struct nand_header_type * hdr_nand)516 uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand)
517 {
518 	switch (hdr_nand->type) {
519 	case NAND_BOOT_HSM_HEADER:
520 		return le32_to_cpu(hdr_nand->hsm->page_size);
521 
522 	case NAND_BOOT_HSM20_HEADER:
523 		return le32_to_cpu(hdr_nand->hsm20->page_size);
524 
525 	case NAND_BOOT_SPIM_HEADER:
526 		return le32_to_cpu(hdr_nand->spim->page_size);
527 
528 	default:
529 		return 2 * le16_to_cpu(hdr_nand->ap->pagesize);
530 	}
531 }
532 
mtk_nand_header_ap_info(const void * ptr,struct nand_header_info * info)533 static int mtk_nand_header_ap_info(const void *ptr,
534 				   struct nand_header_info *info)
535 {
536 	union nand_boot_header *nh = (union nand_boot_header *)ptr;
537 
538 	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
539 	    strcmp(nh->id, NAND_BOOT_ID))
540 		return -1;
541 
542 	info->page_size = le16_to_cpu(nh->pagesize);
543 	info->spare_size = le16_to_cpu(nh->oobsize);
544 	info->gfh_offset = 2 * info->page_size;
545 	info->snfi = true;
546 
547 	return 0;
548 }
549 
mtk_nand_header_hsm_info(const void * ptr,struct nand_header_info * info)550 static int mtk_nand_header_hsm_info(const void *ptr,
551 				    struct nand_header_info *info)
552 {
553 	union hsm_nand_boot_header *nh = (union hsm_nand_boot_header *)ptr;
554 
555 	info->page_size = le16_to_cpu(nh->page_size);
556 	info->spare_size = le16_to_cpu(nh->spare_size);
557 	info->gfh_offset = info->page_size;
558 	info->snfi = true;
559 
560 	return 1;
561 }
562 
mtk_nand_header_spim_info(const void * ptr,struct nand_header_info * info)563 static int mtk_nand_header_spim_info(const void *ptr,
564 				     struct nand_header_info *info)
565 {
566 	union spim_nand_boot_header *nh = (union spim_nand_boot_header *)ptr;
567 
568 	info->page_size = le16_to_cpu(nh->page_size);
569 	info->spare_size = le16_to_cpu(nh->spare_size);
570 	info->gfh_offset = info->page_size;
571 	info->snfi = false;
572 
573 	return 1;
574 }
575 
mtk_nand_header_info(const void * ptr,struct nand_header_info * info)576 int mtk_nand_header_info(const void *ptr, struct nand_header_info *info)
577 {
578 	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
579 		return mtk_nand_header_ap_info(ptr, info);
580 	else if (!strncmp((char *)ptr, HSM_NAND_BOOT_NAME, 8))
581 		return mtk_nand_header_hsm_info(ptr, info);
582 	else if (!strncmp((char *)ptr, SPIM_NAND_BOOT_NAME, 8))
583 		return mtk_nand_header_spim_info(ptr, info);
584 
585 	return -1;
586 }
587 
is_mtk_nand_header(const void * ptr)588 bool is_mtk_nand_header(const void *ptr)
589 {
590 	struct nand_header_info info;
591 
592 	if (mtk_nand_header_info(ptr, &info) >= 0)
593 		return true;
594 
595 	return false;
596 }
597 
crc16(const uint8_t * p,uint32_t len)598 static uint16_t crc16(const uint8_t *p, uint32_t len)
599 {
600 	uint16_t crc = 0x4f4e;
601 	uint32_t i;
602 
603 	while (len--) {
604 		crc ^= *p++ << 8;
605 		for (i = 0; i < 8; i++)
606 			crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
607 	}
608 
609 	return crc;
610 }
611 
mtk_nand_header_put_ap(const struct nand_header_type * hdr_nand,void * ptr)612 static uint32_t mtk_nand_header_put_ap(const struct nand_header_type *hdr_nand,
613 				       void *ptr)
614 {
615 	int i;
616 
617 	/* NAND device header, repeat 4 times */
618 	for (i = 0; i < 4; i++) {
619 		memcpy(ptr, hdr_nand->ap, sizeof(*hdr_nand->ap));
620 		ptr += sizeof(*hdr_nand->ap);
621 	}
622 
623 	return le16_to_cpu(hdr_nand->ap->pagesize);
624 }
625 
mtk_nand_header_put_hsm(const struct nand_header_type * hdr_nand,void * ptr)626 static uint32_t mtk_nand_header_put_hsm(const struct nand_header_type *hdr_nand,
627 					void *ptr)
628 {
629 	memcpy(ptr, hdr_nand->hsm, sizeof(*hdr_nand->hsm));
630 	return 0;
631 }
632 
mtk_nand_header_put_hsm20(const struct nand_header_type * hdr_nand,void * ptr)633 static uint32_t mtk_nand_header_put_hsm20(const struct nand_header_type *hdr_nand,
634 					  void *ptr)
635 {
636 	memcpy(ptr, hdr_nand->hsm20, sizeof(*hdr_nand->hsm20));
637 	return 0;
638 }
639 
mtk_nand_header_put_spim(const struct nand_header_type * hdr_nand,void * ptr)640 static uint32_t mtk_nand_header_put_spim(const struct nand_header_type *hdr_nand,
641 					 void *ptr)
642 {
643 	uint16_t crc;
644 
645 	memcpy(ptr, hdr_nand->spim, sizeof(*hdr_nand->spim));
646 
647 	crc = crc16(ptr, 0x4e);
648 	memcpy(ptr + 0x4e, &crc, sizeof(uint16_t));
649 
650 	return 0;
651 }
652 
mtk_nand_header_put(const struct nand_header_type * hdr_nand,void * ptr)653 uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, void *ptr)
654 {
655 	switch (hdr_nand->type) {
656 	case NAND_BOOT_HSM_HEADER:
657 		return mtk_nand_header_put_hsm(hdr_nand, ptr);
658 
659 	case NAND_BOOT_HSM20_HEADER:
660 		return mtk_nand_header_put_hsm20(hdr_nand, ptr);
661 
662 	case NAND_BOOT_SPIM_HEADER:
663 		return mtk_nand_header_put_spim(hdr_nand, ptr);
664 
665 	default:
666 		return mtk_nand_header_put_ap(hdr_nand, ptr);
667 	}
668 }
669