blob: 12f827c39f7852fd1794fac871fe073fdcf75c66 [file] [log] [blame]
developer4873b412022-09-09 20:00:21 +08001// 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
191static const struct nand_header_type {
192 const char *name;
193 const union nand_boot_header *data;
194} nand_headers[] = {
195 {
196 .name = "2k+64",
197 .data = &snand_hdr_2k_64_data
198 }, {
199 .name = "2k+120",
200 .data = &snand_hdr_2k_128_data
201 }, {
202 .name = "2k+128",
203 .data = &snand_hdr_2k_128_data
204 }, {
205 .name = "4k+256",
206 .data = &snand_hdr_4k_256_data
207 }, {
208 .name = "1g:2k+64",
209 .data = &nand_hdr_1gb_2k_64_data
210 }, {
211 .name = "2g:2k+64",
212 .data = &nand_hdr_2gb_2k_64_data
213 }, {
214 .name = "4g:2k+64",
215 .data = &nand_hdr_4gb_2k_64_data
216 }, {
217 .name = "2g:2k+128",
218 .data = &nand_hdr_2gb_2k_128_data
219 }, {
220 .name = "4g:2k+128",
221 .data = &nand_hdr_4gb_2k_128_data
222 }
223};
224
225const union nand_boot_header *mtk_nand_header_find(const char *name)
226{
227 uint32_t i;
228
229 for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
230 if (!strcmp(nand_headers[i].name, name))
231 return nand_headers[i].data;
232 }
233
234 return NULL;
235}
236
237uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand)
238{
239 return 2 * le16_to_cpu(hdr_nand->pagesize);
240}
241
242static int mtk_nand_header_ap_info(const void *ptr,
243 struct nand_header_info *info)
244{
245 union nand_boot_header *nh = (union nand_boot_header *)ptr;
246
247 if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
248 strcmp(nh->id, NAND_BOOT_ID))
249 return -1;
250
251 info->page_size = le16_to_cpu(nh->pagesize);
252 info->spare_size = le16_to_cpu(nh->oobsize);
253 info->gfh_offset = 2 * info->page_size;
254
255 return 0;
256}
257
258int mtk_nand_header_info(const void *ptr, struct nand_header_info *info)
259{
260 if (!strcmp((char *)ptr, NAND_BOOT_NAME))
261 return mtk_nand_header_ap_info(ptr, info);
262
263 return -1;
264}
265
266bool is_mtk_nand_header(const void *ptr)
267{
268 struct nand_header_info info;
269
270 if (mtk_nand_header_info(ptr, &info) >= 0)
271 return true;
272
273 return false;
274}
275
276uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr)
277{
278 union nand_boot_header *nh = (union nand_boot_header *)ptr;
279 int i;
280
281 /* NAND device header, repeat 4 times */
282 for (i = 0; i < 4; i++)
283 memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
284
285 return le16_to_cpu(hdr_nand->pagesize);
286}