]>
Commit | Line | Data |
---|---|---|
f682e425 WD |
1 | /* |
2 | * (C) Copyright 2002 | |
3 | * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | /* #define DEBUG */ | |
25 | ||
26 | #include <common.h> | |
27 | #include <environment.h> | |
28 | ||
6069ff26 | 29 | static ulong flash_get_size (vu_long *addr, flash_info_t *info); |
f682e425 | 30 | |
6d0f6bcf | 31 | flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; |
f682e425 WD |
32 | |
33 | ||
34 | #define CMD_READ_ARRAY 0x00F000F0 | |
35 | #define CMD_UNLOCK1 0x00AA00AA | |
36 | #define CMD_UNLOCK2 0x00550055 | |
37 | #define CMD_ERASE_SETUP 0x00800080 | |
38 | #define CMD_ERASE_CONFIRM 0x00300030 | |
39 | #define CMD_PROGRAM 0x00A000A0 | |
40 | #define CMD_UNLOCK_BYPASS 0x00200020 | |
6069ff26 | 41 | #define CMD_READ_MANF_ID 0x00900090 |
b4757cee WD |
42 | #define CMD_UNLOCK_BYPASS_RES1 0x00900090 |
43 | #define CMD_UNLOCK_BYPASS_RES2 0x00000000 | |
f682e425 | 44 | |
6d0f6bcf JCPV |
45 | #define MEM_FLASH_ADDR (*(volatile u32 *)CONFIG_SYS_FLASH_BASE) |
46 | #define MEM_FLASH_ADDR1 (*(volatile u32 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 2))) | |
47 | #define MEM_FLASH_ADDR2 (*(volatile u32 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 2))) | |
f682e425 WD |
48 | |
49 | #define BIT_ERASE_DONE 0x00800080 | |
50 | #define BIT_RDY_MASK 0x00800080 | |
51 | #define BIT_PROGRAM_ERROR 0x00200020 | |
52 | #define BIT_TIMEOUT 0x80000000 /* our flag */ | |
53 | ||
54 | #define READY 1 | |
55 | #define ERR 2 | |
56 | #define TMO 4 | |
57 | ||
58 | /*----------------------------------------------------------------------- | |
59 | */ | |
60 | ||
61 | ulong flash_init (void) | |
62 | { | |
63 | int i, j; | |
64 | ulong size = 0; | |
65 | ||
6d0f6bcf | 66 | for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) { |
f682e425 | 67 | ulong flashbase = 0; |
6069ff26 WD |
68 | flash_info_t *info = &flash_info[i]; |
69 | ||
70 | /* Init: no FLASHes known */ | |
71 | info->flash_id = FLASH_UNKNOWN; | |
72 | ||
6d0f6bcf | 73 | size += flash_get_size (CONFIG_SYS_FLASH_BASE, info); |
f682e425 | 74 | |
f682e425 | 75 | if (i == 0) |
6d0f6bcf | 76 | flashbase = CONFIG_SYS_FLASH_BASE; |
f682e425 WD |
77 | else |
78 | panic ("configured too many flash banks!\n"); | |
6069ff26 WD |
79 | for (j = 0; j < info->sector_count; j++) { |
80 | ||
81 | info->protect[j] = 0; | |
82 | info->start[j] = flashbase; | |
83 | ||
84 | switch (info->flash_id & FLASH_TYPEMASK) { | |
85 | case (FLASH_AM320B & FLASH_TYPEMASK): | |
efa329cb | 86 | case (FLASH_MXLV320B & FLASH_TYPEMASK): |
6069ff26 WD |
87 | /* Boot sector type: 8 x 8 + N x 128 kB */ |
88 | flashbase += (j < 8) ? 0x4000 : 0x20000; | |
89 | break; | |
90 | case (FLASH_AM640U & FLASH_TYPEMASK): | |
91 | /* Uniform sector type: 128 kB */ | |
92 | flashbase += 0x20000; | |
93 | break; | |
94 | default: | |
95 | printf ("## Bad flash chip type 0x%04lX\n", | |
96 | info->flash_id & FLASH_TYPEMASK); | |
97 | } | |
f682e425 | 98 | } |
f682e425 WD |
99 | } |
100 | ||
101 | /* | |
102 | * Protect monitor and environment sectors | |
103 | */ | |
104 | flash_protect ( FLAG_PROTECT_SET, | |
6d0f6bcf JCPV |
105 | CONFIG_SYS_FLASH_BASE, |
106 | CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1, | |
f682e425 WD |
107 | &flash_info[0]); |
108 | ||
109 | flash_protect ( FLAG_PROTECT_SET, | |
0e8d1586 JCPV |
110 | CONFIG_ENV_ADDR, |
111 | CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]); | |
f682e425 | 112 | |
0e8d1586 | 113 | #ifdef CONFIG_ENV_ADDR_REDUND |
f682e425 | 114 | flash_protect ( FLAG_PROTECT_SET, |
0e8d1586 JCPV |
115 | CONFIG_ENV_ADDR_REDUND, |
116 | CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SIZE_REDUND - 1, | |
f682e425 WD |
117 | &flash_info[0]); |
118 | #endif | |
119 | ||
120 | return size; | |
121 | } | |
122 | ||
123 | /*----------------------------------------------------------------------- | |
124 | */ | |
125 | void flash_print_info (flash_info_t * info) | |
126 | { | |
127 | int i; | |
128 | ||
129 | switch (info->flash_id & FLASH_VENDMASK) { | |
6069ff26 | 130 | case (FLASH_MAN_AMD & FLASH_VENDMASK): |
1cb8e980 WD |
131 | printf ("AMD "); break; |
132 | case (FLASH_MAN_FUJ & FLASH_VENDMASK): | |
133 | printf ("FUJITSU "); break; | |
efa329cb WD |
134 | case (FLASH_MAN_MX & FLASH_VENDMASK): |
135 | printf ("MACRONIX "); break; | |
1cb8e980 | 136 | default: printf ("Unknown Vendor "); break; |
f682e425 WD |
137 | } |
138 | ||
139 | switch (info->flash_id & FLASH_TYPEMASK) { | |
6069ff26 | 140 | case (FLASH_AM320B & FLASH_TYPEMASK): |
f682e425 WD |
141 | printf ("2x Am29LV320DB (32Mbit)\n"); |
142 | break; | |
efa329cb WD |
143 | case (FLASH_MXLV320B & FLASH_TYPEMASK): |
144 | printf ("2x MX29LV320DB (32Mbit)\n"); | |
145 | break; | |
6069ff26 WD |
146 | case (FLASH_AM640U & FLASH_TYPEMASK): |
147 | printf ("2x Am29LV640D (64Mbit)\n"); | |
148 | break; | |
f682e425 WD |
149 | default: |
150 | printf ("Unknown Chip Type\n"); | |
151 | goto Done; | |
152 | break; | |
153 | } | |
154 | ||
155 | printf (" Size: %ld MB in %d Sectors\n", | |
156 | info->size >> 20, info->sector_count); | |
157 | ||
158 | printf (" Sector Start Addresses:"); | |
159 | for (i = 0; i < info->sector_count; i++) { | |
160 | if ((i % 5) == 0) { | |
161 | printf ("\n "); | |
162 | } | |
163 | printf (" %08lX%s", | |
164 | info->start[i], | |
165 | info->protect[i] ? " (RO)" : " "); | |
166 | } | |
167 | printf ("\n"); | |
168 | ||
e86e5a07 | 169 | Done: ; |
f682e425 WD |
170 | } |
171 | ||
172 | /*----------------------------------------------------------------------- | |
173 | */ | |
174 | ||
175 | int flash_erase (flash_info_t * info, int s_first, int s_last) | |
176 | { | |
177 | ulong result; | |
178 | ||
179 | #if 0 | |
180 | int cflag; | |
181 | #endif | |
182 | int iflag, prot, sect; | |
183 | int rc = ERR_OK; | |
184 | int chip1, chip2; | |
185 | ||
186 | debug ("flash_erase: s_first %d s_last %d\n", s_first, s_last); | |
187 | ||
188 | /* first look for protection bits */ | |
189 | ||
190 | if (info->flash_id == FLASH_UNKNOWN) | |
191 | return ERR_UNKNOWN_FLASH_TYPE; | |
192 | ||
193 | if ((s_first < 0) || (s_first > s_last)) { | |
194 | return ERR_INVAL; | |
195 | } | |
196 | ||
3bac3513 WD |
197 | switch (info->flash_id & FLASH_VENDMASK) { |
198 | case (FLASH_MAN_AMD & FLASH_VENDMASK): break; /* OK */ | |
199 | case (FLASH_MAN_FUJ & FLASH_VENDMASK): break; /* OK */ | |
efa329cb | 200 | case (FLASH_MAN_MX & FLASH_VENDMASK): break; /* OK */ |
3bac3513 WD |
201 | default: |
202 | debug ("## flash_erase: unknown manufacturer\n"); | |
203 | return (ERR_UNKNOWN_FLASH_VENDOR); | |
f682e425 WD |
204 | } |
205 | ||
206 | prot = 0; | |
207 | for (sect = s_first; sect <= s_last; ++sect) { | |
208 | if (info->protect[sect]) { | |
209 | prot++; | |
210 | } | |
211 | } | |
212 | ||
213 | if (prot) { | |
214 | printf ("- Warning: %d protected sectors will not be erased!\n", | |
215 | prot); | |
216 | } else { | |
217 | printf ("\n"); | |
218 | } | |
219 | ||
220 | /* | |
221 | * Disable interrupts which might cause a timeout | |
222 | * here. Remember that our exception vectors are | |
223 | * at address 0 in the flash, and we don't want a | |
224 | * (ticker) exception to happen while the flash | |
225 | * chip is in programming mode. | |
226 | */ | |
227 | #if 0 | |
228 | cflag = icache_status (); | |
229 | icache_disable (); | |
230 | #endif | |
231 | iflag = disable_interrupts (); | |
232 | ||
233 | /* Start erase on unprotected sectors */ | |
234 | for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { | |
235 | ||
236 | debug ("Erasing sector %2d @ %08lX... ", | |
237 | sect, info->start[sect]); | |
238 | ||
239 | /* arm simple, non interrupt dependent timer */ | |
240 | reset_timer_masked (); | |
241 | ||
242 | if (info->protect[sect] == 0) { /* not protected */ | |
243 | vu_long *addr = (vu_long *) (info->start[sect]); | |
244 | ||
245 | MEM_FLASH_ADDR1 = CMD_UNLOCK1; | |
246 | MEM_FLASH_ADDR2 = CMD_UNLOCK2; | |
247 | MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; | |
248 | ||
249 | MEM_FLASH_ADDR1 = CMD_UNLOCK1; | |
250 | MEM_FLASH_ADDR2 = CMD_UNLOCK2; | |
251 | *addr = CMD_ERASE_CONFIRM; | |
252 | ||
253 | /* wait until flash is ready */ | |
254 | chip1 = chip2 = 0; | |
255 | ||
256 | do { | |
257 | result = *addr; | |
258 | ||
259 | /* check timeout */ | |
6d0f6bcf | 260 | if (get_timer_masked () > CONFIG_SYS_FLASH_ERASE_TOUT) { |
f682e425 WD |
261 | MEM_FLASH_ADDR1 = CMD_READ_ARRAY; |
262 | chip1 = TMO; | |
263 | break; | |
264 | } | |
265 | ||
266 | if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE) | |
267 | chip1 = READY; | |
268 | ||
269 | if (!chip1 && (result & 0xFFFF) & BIT_PROGRAM_ERROR) | |
270 | chip1 = ERR; | |
271 | ||
272 | if (!chip2 && (result >> 16) & BIT_ERASE_DONE) | |
273 | chip2 = READY; | |
274 | ||
275 | if (!chip2 && (result >> 16) & BIT_PROGRAM_ERROR) | |
276 | chip2 = ERR; | |
277 | ||
278 | } while (!chip1 || !chip2); | |
279 | ||
280 | MEM_FLASH_ADDR1 = CMD_READ_ARRAY; | |
281 | ||
282 | if (chip1 == ERR || chip2 == ERR) { | |
283 | rc = ERR_PROG_ERROR; | |
0de7fa59 | 284 | printf ("Flash erase error\n"); |
f682e425 WD |
285 | goto outahere; |
286 | } | |
287 | if (chip1 == TMO) { | |
288 | rc = ERR_TIMOUT; | |
0de7fa59 | 289 | printf ("Flash erase timeout error\n"); |
f682e425 WD |
290 | goto outahere; |
291 | } | |
f682e425 WD |
292 | } |
293 | } | |
294 | ||
295 | outahere: | |
296 | /* allow flash to settle - wait 10 ms */ | |
297 | udelay_masked (10000); | |
298 | ||
299 | if (iflag) | |
300 | enable_interrupts (); | |
301 | ||
302 | #if 0 | |
303 | if (cflag) | |
304 | icache_enable (); | |
305 | #endif | |
306 | return rc; | |
307 | } | |
308 | ||
309 | /*----------------------------------------------------------------------- | |
310 | * Copy memory to flash | |
311 | */ | |
312 | ||
8de7ed3a | 313 | static int write_word (flash_info_t * info, ulong dest, ulong data) |
f682e425 WD |
314 | { |
315 | vu_long *addr = (vu_long *) dest; | |
316 | ulong result; | |
317 | int rc = ERR_OK; | |
318 | ||
319 | #if 0 | |
320 | int cflag; | |
321 | #endif | |
322 | int iflag; | |
323 | int chip1, chip2; | |
324 | ||
325 | /* | |
326 | * Check if Flash is (sufficiently) erased | |
327 | */ | |
328 | result = *addr; | |
329 | if ((result & data) != data) | |
330 | return ERR_NOT_ERASED; | |
331 | ||
332 | /* | |
333 | * Disable interrupts which might cause a timeout | |
334 | * here. Remember that our exception vectors are | |
335 | * at address 0 in the flash, and we don't want a | |
336 | * (ticker) exception to happen while the flash | |
337 | * chip is in programming mode. | |
338 | */ | |
339 | #if 0 | |
340 | cflag = icache_status (); | |
341 | icache_disable (); | |
342 | #endif | |
343 | iflag = disable_interrupts (); | |
344 | ||
5a3dfef7 WD |
345 | MEM_FLASH_ADDR1 = CMD_UNLOCK1; |
346 | MEM_FLASH_ADDR2 = CMD_UNLOCK2; | |
347 | MEM_FLASH_ADDR1 = CMD_PROGRAM; | |
f682e425 WD |
348 | *addr = data; |
349 | ||
350 | /* arm simple, non interrupt dependent timer */ | |
351 | reset_timer_masked (); | |
352 | ||
353 | /* wait until flash is ready */ | |
354 | chip1 = chip2 = 0; | |
355 | do { | |
356 | result = *addr; | |
357 | ||
358 | /* check timeout */ | |
6d0f6bcf | 359 | if (get_timer_masked () > CONFIG_SYS_FLASH_WRITE_TOUT) { |
f682e425 WD |
360 | chip1 = ERR | TMO; |
361 | break; | |
362 | } | |
363 | if (!chip1 && ((result & 0x80) == (data & 0x80))) | |
364 | chip1 = READY; | |
365 | ||
366 | if (!chip1 && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) { | |
367 | result = *addr; | |
368 | ||
369 | if ((result & 0x80) == (data & 0x80)) | |
370 | chip1 = READY; | |
371 | else | |
372 | chip1 = ERR; | |
373 | } | |
374 | ||
375 | if (!chip2 && ((result & (0x80 << 16)) == (data & (0x80 << 16)))) | |
376 | chip2 = READY; | |
377 | ||
378 | if (!chip2 && ((result >> 16) & BIT_PROGRAM_ERROR)) { | |
379 | result = *addr; | |
380 | ||
381 | if ((result & (0x80 << 16)) == (data & (0x80 << 16))) | |
382 | chip2 = READY; | |
383 | else | |
384 | chip2 = ERR; | |
385 | } | |
386 | ||
387 | } while (!chip1 || !chip2); | |
388 | ||
389 | *addr = CMD_READ_ARRAY; | |
390 | ||
0de7fa59 | 391 | if (chip1 == ERR || chip2 == ERR || *addr != data) { |
f682e425 | 392 | rc = ERR_PROG_ERROR; |
0de7fa59 WD |
393 | printf ("Flash program error\n"); |
394 | debug ("chip1: %#x, chip2: %#x, addr: %#lx *addr: %#lx, " | |
395 | "data: %#lx\n", | |
396 | chip1, chip2, addr, *addr, data); | |
397 | } | |
f682e425 WD |
398 | |
399 | if (iflag) | |
400 | enable_interrupts (); | |
401 | ||
402 | #if 0 | |
403 | if (cflag) | |
404 | icache_enable (); | |
405 | #endif | |
406 | ||
407 | return rc; | |
408 | } | |
409 | ||
410 | /*----------------------------------------------------------------------- | |
411 | * Copy memory to flash. | |
412 | */ | |
413 | ||
414 | int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) | |
415 | { | |
416 | ulong cp, wp, data; | |
417 | int l; | |
418 | int i, rc; | |
419 | ||
420 | wp = (addr & ~3); /* get lower word aligned address */ | |
421 | ||
422 | /* | |
423 | * handle unaligned start bytes | |
424 | */ | |
425 | if ((l = addr - wp) != 0) { | |
426 | data = 0; | |
427 | for (i = 0, cp = wp; i < l; ++i, ++cp) { | |
428 | data = (data >> 8) | (*(uchar *) cp << 24); | |
429 | } | |
430 | for (; i < 4 && cnt > 0; ++i) { | |
431 | data = (data >> 8) | (*src++ << 24); | |
432 | --cnt; | |
433 | ++cp; | |
434 | } | |
435 | for (; cnt == 0 && i < 4; ++i, ++cp) { | |
436 | data = (data >> 8) | (*(uchar *) cp << 24); | |
437 | } | |
438 | ||
439 | if ((rc = write_word (info, wp, data)) != 0) { | |
b4757cee | 440 | goto Done; |
f682e425 WD |
441 | } |
442 | wp += 4; | |
443 | } | |
444 | ||
445 | /* | |
446 | * handle word aligned part | |
447 | */ | |
448 | while (cnt >= 4) { | |
f07771cc WD |
449 | if (((ulong)src) & 0x3) { |
450 | for (i = 0; i < 4; i++) { | |
451 | ((char *)&data)[i] = ((vu_char *)src)[i]; | |
452 | } | |
453 | } | |
454 | else { | |
455 | data = *((vu_long *) src); | |
456 | } | |
8bde7f77 | 457 | |
f682e425 | 458 | if ((rc = write_word (info, wp, data)) != 0) { |
b4757cee | 459 | goto Done; |
f682e425 WD |
460 | } |
461 | src += 4; | |
462 | wp += 4; | |
463 | cnt -= 4; | |
464 | } | |
465 | ||
466 | if (cnt == 0) { | |
b4757cee WD |
467 | rc = ERR_OK; |
468 | goto Done; | |
f682e425 WD |
469 | } |
470 | ||
471 | /* | |
472 | * handle unaligned tail bytes | |
473 | */ | |
474 | data = 0; | |
475 | for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) { | |
476 | data = (data >> 8) | (*src++ << 24); | |
477 | --cnt; | |
478 | } | |
479 | for (; i < 4; ++i, ++cp) { | |
480 | data = (data >> 8) | (*(uchar *) cp << 24); | |
481 | } | |
482 | ||
b4757cee WD |
483 | rc = write_word (info, wp, data); |
484 | ||
485 | Done: | |
486 | ||
b4757cee | 487 | return (rc); |
f682e425 | 488 | } |
6069ff26 WD |
489 | |
490 | /*----------------------------------------------------------------------- | |
491 | */ | |
492 | ||
493 | static ulong flash_get_size (vu_long *addr, flash_info_t *info) | |
494 | { | |
495 | ulong value; | |
496 | ||
497 | /* Write auto select command sequence and read Manufacturer ID */ | |
498 | addr[0x0555] = CMD_UNLOCK1; | |
499 | addr[0x02AA] = CMD_UNLOCK2; | |
500 | addr[0x0555] = CMD_READ_MANF_ID; | |
501 | ||
502 | value = addr[0]; | |
503 | ||
504 | debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value); | |
505 | ||
506 | switch (value) { | |
507 | case AMD_MANUFACT: | |
508 | info->flash_id = FLASH_MAN_AMD; | |
509 | break; | |
1cb8e980 WD |
510 | case FUJ_MANUFACT: |
511 | info->flash_id = FLASH_MAN_FUJ; | |
512 | break; | |
efa329cb WD |
513 | case MX_MANUFACT: |
514 | info->flash_id = FLASH_MAN_MX; | |
515 | break; | |
6069ff26 WD |
516 | default: |
517 | info->flash_id = FLASH_UNKNOWN; | |
518 | info->sector_count = 0; | |
519 | info->size = 0; | |
5a3dfef7 | 520 | addr[0] = CMD_READ_ARRAY; /* restore read mode */ |
6069ff26 WD |
521 | debug ("## flash_init: unknown manufacturer\n"); |
522 | return (0); /* no or unknown flash */ | |
523 | } | |
524 | ||
525 | value = addr[1]; /* device ID */ | |
526 | ||
527 | debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value); | |
528 | ||
529 | switch (value) { | |
530 | case AMD_ID_LV320B: | |
531 | info->flash_id += FLASH_AM320B; | |
532 | info->sector_count = 71; | |
533 | info->size = 0x00800000; | |
534 | ||
5a3dfef7 | 535 | addr[0] = CMD_READ_ARRAY; /* restore read mode */ |
6069ff26 WD |
536 | break; /* => 8 MB */ |
537 | ||
538 | case AMD_ID_LV640U: | |
539 | info->flash_id += FLASH_AM640U; | |
540 | info->sector_count = 128; | |
541 | info->size = 0x01000000; | |
542 | ||
5a3dfef7 | 543 | addr[0] = CMD_READ_ARRAY; /* restore read mode */ |
6069ff26 WD |
544 | break; /* => 16 MB */ |
545 | ||
efa329cb WD |
546 | case MX_ID_LV320B: |
547 | info->flash_id += FLASH_MXLV320B; | |
548 | info->sector_count = 71; | |
549 | info->size = 0x00800000; | |
550 | ||
5a3dfef7 | 551 | addr[0] = CMD_READ_ARRAY; /* restore read mode */ |
efa329cb WD |
552 | break; /* => 8 MB */ |
553 | ||
6069ff26 WD |
554 | default: |
555 | debug ("## flash_init: unknown flash chip\n"); | |
556 | info->flash_id = FLASH_UNKNOWN; | |
5a3dfef7 | 557 | addr[0] = CMD_READ_ARRAY; /* restore read mode */ |
6069ff26 WD |
558 | return (0); /* => no or unknown flash */ |
559 | ||
560 | } | |
561 | ||
6d0f6bcf | 562 | if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) { |
6069ff26 | 563 | printf ("** ERROR: sector count %d > max (%d) **\n", |
6d0f6bcf JCPV |
564 | info->sector_count, CONFIG_SYS_MAX_FLASH_SECT); |
565 | info->sector_count = CONFIG_SYS_MAX_FLASH_SECT; | |
6069ff26 WD |
566 | } |
567 | ||
568 | return (info->size); | |
569 | } |