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 */
16static 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 */
38static 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 */
60static 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 */
82static 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 */
104static 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 */
126static 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 */
148static 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 */
170static 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 */
192static 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 */
216static 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 */
240static 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 */
264static 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 */
300static 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 */
336static 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 */
372static 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 */
388static 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 */
404static 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
419struct 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
504const 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
516uint32_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
533static 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
550static 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
563static 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
576int 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
588bool 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
598static 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
612static 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
626static 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
633static 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
640static 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
653uint32_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