Added support for the Hynix HY27US08121A 64MB Flash chip.
[u-boot-openmoko/mini2440.git] / board / tb0229 / flash.c
blobe9f6418c4ec58b2fc2868a3a76770ceab36fd242
1 /*
2 * (C) Masami Komiya <mkomiya@sonare.it> 2004
4 * (C) Copyright 2001-2004
5 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7 * See file CREDITS for list of people who contributed to this
8 * project.
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
26 #include <common.h>
27 #include <ppc4xx.h>
28 #include <asm/processor.h>
30 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
33 #ifdef CFG_FLASH_16BIT
34 #define FLASH_WORD_SIZE unsigned short
35 #define FLASH_ID_MASK 0xFFFF
36 #else
37 #define FLASH_WORD_SIZE unsigned long
38 #define FLASH_ID_MASK 0xFFFFFFFF
39 #endif
41 /*-----------------------------------------------------------------------
42 * Functions
44 /* stolen from esteem192e/flash.c */
45 ulong flash_get_size (volatile FLASH_WORD_SIZE * addr, flash_info_t * info);
47 #ifndef CFG_FLASH_16BIT
48 static int write_word (flash_info_t * info, ulong dest, ulong data);
49 #else
50 static int write_short (flash_info_t * info, ulong dest, ushort data);
51 #endif
52 static void flash_get_offsets (ulong base, flash_info_t * info);
55 /*-----------------------------------------------------------------------
58 unsigned long flash_init (void)
60 unsigned long size_b0, size_b1;
61 int i;
62 uint pbcr;
63 unsigned long base_b0, base_b1;
65 /* Init: no FLASHes known */
66 for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
67 flash_info[i].flash_id = FLASH_UNKNOWN;
70 /* Static FLASH Bank configuration here - FIXME XXX */
72 size_b0 =
73 flash_get_size ((volatile FLASH_WORD_SIZE *) CFG_FLASH_BASE,
74 &flash_info[0]);
76 if (flash_info[0].flash_id == FLASH_UNKNOWN) {
77 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", size_b0, size_b0 << 20);
80 /* Only one bank */
81 if (CFG_MAX_FLASH_BANKS == 1) {
82 /* Setup offsets */
83 flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
85 /* Monitor protection ON by default */
86 #if 0 /* sand: */
87 (void) flash_protect (FLAG_PROTECT_SET,
88 FLASH_BASE0_PRELIM - monitor_flash_len +
89 size_b0,
90 FLASH_BASE0_PRELIM - 1 + size_b0,
91 &flash_info[0]);
92 #else
93 (void) flash_protect (FLAG_PROTECT_SET,
94 CFG_MONITOR_BASE,
95 CFG_MONITOR_BASE + monitor_flash_len -
96 1, &flash_info[0]);
97 #endif
98 size_b1 = 0;
99 flash_info[0].size = size_b0;
101 #ifdef CFG_FLASH_BASE_2
102 /* 2 banks */
103 else {
104 size_b1 =
105 flash_get_size ((volatile FLASH_WORD_SIZE *)
106 CFG_FLASH_BASE_2, &flash_info[1]);
108 /* Re-do sizing to get full correct info */
110 if (size_b1) {
111 mtdcr (ebccfga, pb0cr);
112 pbcr = mfdcr (ebccfgd);
113 mtdcr (ebccfga, pb0cr);
114 base_b1 = -size_b1;
115 pbcr = (pbcr & 0x0001ffff) | base_b1 |
116 (((size_b1 / 1024 / 1024) - 1) << 17);
117 mtdcr (ebccfgd, pbcr);
118 /* printf("pb1cr = %x\n", pbcr); */
121 if (size_b0) {
122 mtdcr (ebccfga, pb1cr);
123 pbcr = mfdcr (ebccfgd);
124 mtdcr (ebccfga, pb1cr);
125 base_b0 = base_b1 - size_b0;
126 pbcr = (pbcr & 0x0001ffff) | base_b0 |
127 (((size_b0 / 1024 / 1024) - 1) << 17);
128 mtdcr (ebccfgd, pbcr);
129 /* printf("pb0cr = %x\n", pbcr); */
132 size_b0 =
133 flash_get_size ((volatile FLASH_WORD_SIZE *) base_b0,
134 &flash_info[0]);
136 flash_get_offsets (base_b0, &flash_info[0]);
138 /* monitor protection ON by default */
139 #if 0 /* sand: */
140 (void) flash_protect (FLAG_PROTECT_SET,
141 FLASH_BASE0_PRELIM - monitor_flash_len +
142 size_b0,
143 FLASH_BASE0_PRELIM - 1 + size_b0,
144 &flash_info[0]);
145 #else
146 (void) flash_protect (FLAG_PROTECT_SET,
147 CFG_MONITOR_BASE,
148 CFG_MONITOR_BASE + monitor_flash_len -
149 1, &flash_info[0]);
150 #endif
152 if (size_b1) {
153 /* Re-do sizing to get full correct info */
154 size_b1 =
155 flash_get_size ((volatile FLASH_WORD_SIZE *)
156 base_b1, &flash_info[1]);
158 flash_get_offsets (base_b1, &flash_info[1]);
160 /* monitor protection ON by default */
161 (void) flash_protect (FLAG_PROTECT_SET,
162 base_b1 + size_b1 -
163 monitor_flash_len,
164 base_b1 + size_b1 - 1,
165 &flash_info[1]);
166 /* monitor protection OFF by default (one is enough) */
167 (void) flash_protect (FLAG_PROTECT_CLEAR,
168 base_b0 + size_b0 -
169 monitor_flash_len,
170 base_b0 + size_b0 - 1,
171 &flash_info[0]);
172 } else {
173 flash_info[1].flash_id = FLASH_UNKNOWN;
174 flash_info[1].sector_count = -1;
177 flash_info[0].size = size_b0;
178 flash_info[1].size = size_b1;
179 } /* else 2 banks */
180 #endif
181 return (size_b0 + size_b1);
185 /*-----------------------------------------------------------------------
188 static void flash_get_offsets (ulong base, flash_info_t * info)
190 int i;
192 /* set up sector start adress table */
193 if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F320J3A ||
194 (info->flash_id & FLASH_TYPEMASK) == FLASH_28F640J3A ||
195 (info->flash_id & FLASH_TYPEMASK) == FLASH_28F128J3A) {
196 for (i = 0; i < info->sector_count; i++) {
197 info->start[i] =
198 base + (i * info->size / info->sector_count);
200 } else if (info->flash_id & FLASH_BTYPE) {
201 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
203 #ifndef CFG_FLASH_16BIT
204 /* set sector offsets for bottom boot block type */
205 info->start[0] = base + 0x00000000;
206 info->start[1] = base + 0x00004000;
207 info->start[2] = base + 0x00008000;
208 info->start[3] = base + 0x0000C000;
209 info->start[4] = base + 0x00010000;
210 info->start[5] = base + 0x00014000;
211 info->start[6] = base + 0x00018000;
212 info->start[7] = base + 0x0001C000;
213 for (i = 8; i < info->sector_count; i++) {
214 info->start[i] =
215 base + (i * 0x00020000) - 0x000E0000;
217 } else {
218 /* set sector offsets for bottom boot block type */
219 info->start[0] = base + 0x00000000;
220 info->start[1] = base + 0x00008000;
221 info->start[2] = base + 0x0000C000;
222 info->start[3] = base + 0x00010000;
223 for (i = 4; i < info->sector_count; i++) {
224 info->start[i] =
225 base + (i * 0x00020000) - 0x00060000;
228 #else
229 /* set sector offsets for bottom boot block type */
230 info->start[0] = base + 0x00000000;
231 info->start[1] = base + 0x00002000;
232 info->start[2] = base + 0x00004000;
233 info->start[3] = base + 0x00006000;
234 info->start[4] = base + 0x00008000;
235 info->start[5] = base + 0x0000A000;
236 info->start[6] = base + 0x0000C000;
237 info->start[7] = base + 0x0000E000;
238 for (i = 8; i < info->sector_count; i++) {
239 info->start[i] =
240 base + (i * 0x00010000) - 0x00070000;
242 } else {
243 /* set sector offsets for bottom boot block type */
244 info->start[0] = base + 0x00000000;
245 info->start[1] = base + 0x00004000;
246 info->start[2] = base + 0x00006000;
247 info->start[3] = base + 0x00008000;
248 for (i = 4; i < info->sector_count; i++) {
249 info->start[i] =
250 base + (i * 0x00010000) - 0x00030000;
253 #endif
254 } else {
255 /* set sector offsets for top boot block type */
256 i = info->sector_count - 1;
257 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
259 #ifndef CFG_FLASH_16BIT
260 info->start[i--] = base + info->size - 0x00004000;
261 info->start[i--] = base + info->size - 0x00008000;
262 info->start[i--] = base + info->size - 0x0000C000;
263 info->start[i--] = base + info->size - 0x00010000;
264 info->start[i--] = base + info->size - 0x00014000;
265 info->start[i--] = base + info->size - 0x00018000;
266 info->start[i--] = base + info->size - 0x0001C000;
267 for (; i >= 0; i--) {
268 info->start[i] = base + i * 0x00020000;
271 } else {
273 info->start[i--] = base + info->size - 0x00008000;
274 info->start[i--] = base + info->size - 0x0000C000;
275 info->start[i--] = base + info->size - 0x00010000;
276 for (; i >= 0; i--) {
277 info->start[i] = base + i * 0x00020000;
280 #else
281 info->start[i--] = base + info->size - 0x00002000;
282 info->start[i--] = base + info->size - 0x00004000;
283 info->start[i--] = base + info->size - 0x00006000;
284 info->start[i--] = base + info->size - 0x00008000;
285 info->start[i--] = base + info->size - 0x0000A000;
286 info->start[i--] = base + info->size - 0x0000C000;
287 info->start[i--] = base + info->size - 0x0000E000;
288 for (; i >= 0; i--) {
289 info->start[i] = base + i * 0x00010000;
292 } else {
294 info->start[i--] = base + info->size - 0x00004000;
295 info->start[i--] = base + info->size - 0x00006000;
296 info->start[i--] = base + info->size - 0x00008000;
297 for (; i >= 0; i--) {
298 info->start[i] = base + i * 0x00010000;
301 #endif
307 /*-----------------------------------------------------------------------
310 void flash_print_info (flash_info_t * info)
312 int i;
313 uchar *boottype;
314 uchar botboot[] = ", bottom boot sect)\n";
315 uchar topboot[] = ", top boot sector)\n";
317 if (info->flash_id == FLASH_UNKNOWN) {
318 printf ("missing or unknown FLASH type\n");
319 return;
322 switch (info->flash_id & FLASH_VENDMASK) {
323 case FLASH_MAN_AMD:
324 printf ("AMD ");
325 break;
326 case FLASH_MAN_FUJ:
327 printf ("FUJITSU ");
328 break;
329 case FLASH_MAN_SST:
330 printf ("SST ");
331 break;
332 case FLASH_MAN_STM:
333 printf ("STM ");
334 break;
335 case FLASH_MAN_INTEL:
336 printf ("INTEL ");
337 break;
338 default:
339 printf ("Unknown Vendor ");
340 break;
343 if (info->flash_id & 0x0001) {
344 boottype = botboot;
345 } else {
346 boottype = topboot;
349 switch (info->flash_id & FLASH_TYPEMASK) {
350 case FLASH_AM400B:
351 printf ("AM29LV400B (4 Mbit%s", boottype);
352 break;
353 case FLASH_AM400T:
354 printf ("AM29LV400T (4 Mbit%s", boottype);
355 break;
356 case FLASH_AM800B:
357 printf ("AM29LV800B (8 Mbit%s", boottype);
358 break;
359 case FLASH_AM800T:
360 printf ("AM29LV800T (8 Mbit%s", boottype);
361 break;
362 case FLASH_AM160B:
363 printf ("AM29LV160B (16 Mbit%s", boottype);
364 break;
365 case FLASH_AM160T:
366 printf ("AM29LV160T (16 Mbit%s", boottype);
367 break;
368 case FLASH_AM320B:
369 printf ("AM29LV320B (32 Mbit%s", boottype);
370 break;
371 case FLASH_AM320T:
372 printf ("AM29LV320T (32 Mbit%s", boottype);
373 break;
374 case FLASH_INTEL800B:
375 printf ("INTEL28F800B (8 Mbit%s", boottype);
376 break;
377 case FLASH_INTEL800T:
378 printf ("INTEL28F800T (8 Mbit%s", boottype);
379 break;
380 case FLASH_INTEL160B:
381 printf ("INTEL28F160B (16 Mbit%s", boottype);
382 break;
383 case FLASH_INTEL160T:
384 printf ("INTEL28F160T (16 Mbit%s", boottype);
385 break;
386 case FLASH_INTEL320B:
387 printf ("INTEL28F320B (32 Mbit%s", boottype);
388 break;
389 case FLASH_INTEL320T:
390 printf ("INTEL28F320T (32 Mbit%s", boottype);
391 break;
393 #if 0 /* enable when devices are available */
395 case FLASH_INTEL640B:
396 printf ("INTEL28F640B (64 Mbit%s", boottype);
397 break;
398 case FLASH_INTEL640T:
399 printf ("INTEL28F640T (64 Mbit%s", boottype);
400 break;
401 #endif
402 case FLASH_28F320J3A:
403 printf ("INTEL28F320J3A (32 Mbit%s", boottype);
404 break;
405 case FLASH_28F640J3A:
406 printf ("INTEL28F640J3A (64 Mbit%s", boottype);
407 break;
408 case FLASH_28F128J3A:
409 printf ("INTEL28F128J3A (128 Mbit%s", boottype);
410 break;
412 default:
413 printf ("Unknown Chip Type\n");
414 break;
417 printf (" Size: %ld MB in %d Sectors\n",
418 info->size >> 20, info->sector_count);
420 printf (" Sector Start Addresses:");
421 for (i = 0; i < info->sector_count; ++i) {
422 if ((i % 5) == 0)
423 printf ("\n ");
424 printf (" %08lX%s",
425 info->start[i], info->protect[i] ? " (RO)" : " ");
427 printf ("\n");
428 return;
432 /*-----------------------------------------------------------------------
436 /*-----------------------------------------------------------------------
440 * The following code cannot be run from FLASH!
442 ulong flash_get_size (volatile FLASH_WORD_SIZE * addr, flash_info_t * info)
444 short i;
445 ulong base = (ulong) addr;
446 FLASH_WORD_SIZE value;
448 /* Write auto select command: read Manufacturer ID */
451 #ifndef CFG_FLASH_16BIT
454 * Note: if it is an AMD flash and the word at addr[0000]
455 * is 0x00890089 this routine will think it is an Intel
456 * flash device and may(most likely) cause trouble.
459 addr[0x0000] = 0x00900090;
460 if (addr[0x0000] != 0x00890089) {
461 addr[0x0555] = 0x00AA00AA;
462 addr[0x02AA] = 0x00550055;
463 addr[0x0555] = 0x00900090;
464 #else
467 * Note: if it is an AMD flash and the word at addr[0000]
468 * is 0x0089 this routine will think it is an Intel
469 * flash device and may(most likely) cause trouble.
472 addr[0x0000] = 0x0090;
474 if (addr[0x0000] != 0x0089) {
475 addr[0x0555] = 0x00AA;
476 addr[0x02AA] = 0x0055;
477 addr[0x0555] = 0x0090;
478 #endif
480 value = addr[0];
482 switch (value) {
483 case (AMD_MANUFACT & FLASH_ID_MASK):
484 info->flash_id = FLASH_MAN_AMD;
485 break;
486 case (FUJ_MANUFACT & FLASH_ID_MASK):
487 info->flash_id = FLASH_MAN_FUJ;
488 break;
489 case (STM_MANUFACT & FLASH_ID_MASK):
490 info->flash_id = FLASH_MAN_STM;
491 break;
492 case (SST_MANUFACT & FLASH_ID_MASK):
493 info->flash_id = FLASH_MAN_SST;
494 break;
495 case (INTEL_MANUFACT & FLASH_ID_MASK):
496 info->flash_id = FLASH_MAN_INTEL;
497 break;
498 default:
499 info->flash_id = FLASH_UNKNOWN;
500 info->sector_count = 0;
501 info->size = 0;
502 return (0); /* no or unknown flash */
506 value = addr[1]; /* device ID */
508 switch (value) {
510 case (AMD_ID_LV400T & FLASH_ID_MASK):
511 info->flash_id += FLASH_AM400T;
512 info->sector_count = 11;
513 info->size = 0x00100000;
514 break; /* => 1 MB */
516 case (AMD_ID_LV400B & FLASH_ID_MASK):
517 info->flash_id += FLASH_AM400B;
518 info->sector_count = 11;
519 info->size = 0x00100000;
520 break; /* => 1 MB */
522 case (AMD_ID_LV800T & FLASH_ID_MASK):
523 info->flash_id += FLASH_AM800T;
524 info->sector_count = 19;
525 info->size = 0x00200000;
526 break; /* => 2 MB */
528 case (AMD_ID_LV800B & FLASH_ID_MASK):
529 info->flash_id += FLASH_AM800B;
530 info->sector_count = 19;
531 info->size = 0x00200000;
532 break; /* => 2 MB */
534 case (AMD_ID_LV160T & FLASH_ID_MASK):
535 info->flash_id += FLASH_AM160T;
536 info->sector_count = 35;
537 info->size = 0x00400000;
538 break; /* => 4 MB */
540 case (AMD_ID_LV160B & FLASH_ID_MASK):
541 info->flash_id += FLASH_AM160B;
542 info->sector_count = 35;
543 info->size = 0x00400000;
544 break; /* => 4 MB */
545 #if 0 /* enable when device IDs are available */
546 case (AMD_ID_LV320T & FLASH_ID_MASK):
547 info->flash_id += FLASH_AM320T;
548 info->sector_count = 67;
549 info->size = 0x00800000;
550 break; /* => 8 MB */
552 case (AMD_ID_LV320B & FLASH_ID_MASK):
553 info->flash_id += FLASH_AM320B;
554 info->sector_count = 67;
555 info->size = 0x00800000;
556 break; /* => 8 MB */
557 #endif
559 case (INTEL_ID_28F800B3T & FLASH_ID_MASK):
560 info->flash_id += FLASH_INTEL800T;
561 info->sector_count = 23;
562 info->size = 0x00200000;
563 break; /* => 2 MB */
565 case (INTEL_ID_28F800B3B & FLASH_ID_MASK):
566 info->flash_id += FLASH_INTEL800B;
567 info->sector_count = 23;
568 info->size = 0x00200000;
569 break; /* => 2 MB */
571 case (INTEL_ID_28F160B3T & FLASH_ID_MASK):
572 info->flash_id += FLASH_INTEL160T;
573 info->sector_count = 39;
574 info->size = 0x00400000;
575 break; /* => 4 MB */
577 case (INTEL_ID_28F160B3B & FLASH_ID_MASK):
578 info->flash_id += FLASH_INTEL160B;
579 info->sector_count = 39;
580 info->size = 0x00400000;
581 break; /* => 4 MB */
583 case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
584 info->flash_id += FLASH_INTEL320T;
585 info->sector_count = 71;
586 info->size = 0x00800000;
587 break; /* => 8 MB */
589 case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
590 info->flash_id += FLASH_AM320B;
591 info->sector_count = 71;
592 info->size = 0x00800000;
593 break; /* => 8 MB */
595 #if 0 /* enable when devices are available */
596 case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
597 info->flash_id += FLASH_INTEL320T;
598 info->sector_count = 135;
599 info->size = 0x01000000;
600 break; /* => 16 MB */
602 case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
603 info->flash_id += FLASH_AM320B;
604 info->sector_count = 135;
605 info->size = 0x01000000;
606 break; /* => 16 MB */
607 #endif
608 case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
609 info->flash_id += FLASH_28F320J3A;
610 info->sector_count = 32;
611 info->size = 0x00400000;
612 break; /* => 32 MBit */
613 case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
614 info->flash_id += FLASH_28F640J3A;
615 info->sector_count = 64;
616 info->size = 0x00800000;
617 break; /* => 64 MBit */
618 case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
619 info->flash_id += FLASH_28F128J3A;
620 info->sector_count = 128;
621 info->size = 0x01000000;
622 break; /* => 128 MBit */
624 default:
625 /* FIXME */
626 info->flash_id = FLASH_UNKNOWN;
627 return (0); /* => no or unknown flash */
630 flash_get_offsets (base, info);
632 /* check for protected sectors */
633 for (i = 0; i < info->sector_count; i++) {
634 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
635 /* D0 = 1 if protected */
636 addr = (volatile FLASH_WORD_SIZE *) (info->start[i]);
637 info->protect[i] = addr[2] & 1;
641 * Prevent writes to uninitialized FLASH.
643 if (info->flash_id != FLASH_UNKNOWN) {
644 addr = (volatile FLASH_WORD_SIZE *) info->start[0];
645 if ((info->flash_id & 0xFF00) == FLASH_MAN_INTEL) {
646 *addr = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
647 } else {
648 *addr = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
652 return (info->size);
656 /*-----------------------------------------------------------------------
659 int flash_erase (flash_info_t * info, int s_first, int s_last)
662 volatile FLASH_WORD_SIZE *addr =
663 (volatile FLASH_WORD_SIZE *) (info->start[0]);
664 int flag, prot, sect, l_sect, barf;
665 ulong start, now, last;
666 int rcode = 0;
668 if ((s_first < 0) || (s_first > s_last)) {
669 if (info->flash_id == FLASH_UNKNOWN) {
670 printf ("- missing\n");
671 } else {
672 printf ("- no sectors to erase\n");
674 return 1;
677 if ((info->flash_id == FLASH_UNKNOWN) ||
678 ((info->flash_id > FLASH_AMD_COMP) &&
679 ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL))) {
680 printf ("Can't erase unknown flash type - aborted\n");
681 return 1;
684 prot = 0;
685 for (sect = s_first; sect <= s_last; ++sect) {
686 if (info->protect[sect]) {
687 prot++;
691 if (prot) {
692 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
693 } else {
694 printf ("\n");
697 l_sect = -1;
699 /* Disable interrupts which might cause a timeout here */
700 flag = disable_interrupts ();
701 if (info->flash_id < FLASH_AMD_COMP) {
702 #ifndef CFG_FLASH_16BIT
703 addr[0x0555] = 0x00AA00AA;
704 addr[0x02AA] = 0x00550055;
705 addr[0x0555] = 0x00800080;
706 addr[0x0555] = 0x00AA00AA;
707 addr[0x02AA] = 0x00550055;
708 #else
709 addr[0x0555] = 0x00AA;
710 addr[0x02AA] = 0x0055;
711 addr[0x0555] = 0x0080;
712 addr[0x0555] = 0x00AA;
713 addr[0x02AA] = 0x0055;
714 #endif
715 /* Start erase on unprotected sectors */
716 for (sect = s_first; sect <= s_last; sect++) {
717 if (info->protect[sect] == 0) { /* not protected */
718 addr = (volatile FLASH_WORD_SIZE *) (info->
719 start
720 [sect]);
721 addr[0] = (0x00300030 & FLASH_ID_MASK);
722 l_sect = sect;
726 /* re-enable interrupts if necessary */
727 if (flag)
728 enable_interrupts ();
730 /* wait at least 80us - let's wait 1 ms */
731 udelay (1000);
734 * We wait for the last triggered sector
736 if (l_sect < 0)
737 goto DONE;
739 start = get_timer (0);
740 last = start;
741 addr = (volatile FLASH_WORD_SIZE *) (info->start[l_sect]);
742 while ((addr[0] & (0x00800080 & FLASH_ID_MASK)) !=
743 (0x00800080 & FLASH_ID_MASK)) {
744 if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
745 printf ("Timeout\n");
746 return 1;
748 /* show that we're waiting */
749 if ((now - last) > 1000000) { /* every second */
750 serial_putc ('.');
751 last = now;
755 DONE:
756 /* reset to read mode */
757 addr = (volatile FLASH_WORD_SIZE *) info->start[0];
758 addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
759 } else {
762 for (sect = s_first; sect <= s_last; sect++) {
763 if (info->protect[sect] == 0) { /* not protected */
764 barf = 0;
765 #ifndef CFG_FLASH_16BIT
766 addr = (vu_long *) (info->start[sect]);
767 addr[0] = 0x00500050;
768 addr[0] = 0x00200020;
769 addr[0] = 0x00D000D0;
770 while (!(addr[0] & 0x00800080)); /* wait for error or finish */
771 if (addr[0] & 0x003A003A) { /* check for error */
772 barf = addr[0] & 0x003A0000;
773 if (barf) {
774 barf >>= 16;
775 } else {
776 barf = addr[0] & 0x0000003A;
779 #else
780 addr = (vu_short *) (info->start[sect]);
781 addr[0] = 0x0050; /* clear status register */
782 addr[0] = 0x0020;
783 addr[0] = 0x00D0;
784 while (!(addr[0] & 0x0080)); /* wait for error or finish */
785 if (addr[0] & 0x003A) /* check for error */
786 barf = addr[0] & 0x003A;
787 #endif
788 if (barf) {
789 printf ("\nFlash error in sector at %lx\n", (unsigned long) addr);
790 if (barf & 0x0002)
791 printf ("Block locked, not erased.\n");
792 if ((barf & 0x0030) == 0x0030)
793 printf ("Command Sequence error.\n");
794 if ((barf & 0x0030) == 0x0020)
795 printf ("Block Erase error.\n");
796 if (barf & 0x0008)
797 printf ("Vpp Low error.\n");
798 rcode = 1;
799 } else
800 printf (".");
801 l_sect = sect;
803 addr = (volatile FLASH_WORD_SIZE *) info->start[0];
804 #ifndef CFG_FLASH_16BIT
805 addr[0] = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
806 #else
807 addr[0] = (0x00FF & FLASH_ID_MASK); /* reset bank */
808 #endif
812 printf (" done\n");
813 return rcode;
816 /*-----------------------------------------------------------------------
819 /*flash_info_t *addr2info (ulong addr)
821 flash_info_t *info;
822 int i;
824 for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
825 if ((addr >= info->start[0]) &&
826 (addr < (info->start[0] + info->size)) ) {
827 return (info);
831 return (NULL);
834 /*-----------------------------------------------------------------------
835 * Copy memory to flash.
836 * Make sure all target addresses are within Flash bounds,
837 * and no protected sectors are hit.
838 * Returns:
839 * 0 - OK
840 * 1 - write timeout
841 * 2 - Flash not erased
842 * 4 - target range includes protected sectors
843 * 8 - target address not in Flash memory
846 /*int flash_write (uchar *src, ulong addr, ulong cnt)
848 int i;
849 ulong end = addr + cnt - 1;
850 flash_info_t *info_first = addr2info (addr);
851 flash_info_t *info_last = addr2info (end );
852 flash_info_t *info;
854 if (cnt == 0) {
855 return (0);
858 if (!info_first || !info_last) {
859 return (8);
862 for (info = info_first; info <= info_last; ++info) {
863 ulong b_end = info->start[0] + info->size;*/ /* bank end addr */
864 /* short s_end = info->sector_count - 1;
865 for (i=0; i<info->sector_count; ++i) {
866 ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
868 if ((end >= info->start[i]) && (addr < e_addr) &&
869 (info->protect[i] != 0) ) {
870 return (4);
875 */ /* finally write data to flash */
876 /* for (info = info_first; info <= info_last && cnt>0; ++info) {
877 ulong len;
879 len = info->start[0] + info->size - addr;
880 if (len > cnt)
881 len = cnt;
882 if ((i = write_buff(info, src, addr, len)) != 0) {
883 return (i);
885 cnt -= len;
886 addr += len;
887 src += len;
889 return (0);
892 /*-----------------------------------------------------------------------
893 * Copy memory to flash, returns:
894 * 0 - OK
895 * 1 - write timeout
896 * 2 - Flash not erased
899 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
901 #ifndef CFG_FLASH_16BIT
902 ulong cp, wp, data;
903 int l;
904 #else
905 ulong cp, wp;
906 ushort data;
907 #endif
908 int i, rc;
910 #ifndef CFG_FLASH_16BIT
913 wp = (addr & ~3); /* get lower word aligned address */
916 * handle unaligned start bytes
918 if ((l = addr - wp) != 0) {
919 data = 0;
920 for (i = 0, cp = wp; i < l; ++i, ++cp) {
921 data = (data << 8) | (*(uchar *) cp);
923 for (; i < 4 && cnt > 0; ++i) {
924 data = (data << 8) | *src++;
925 --cnt;
926 ++cp;
928 for (; cnt == 0 && i < 4; ++i, ++cp) {
929 data = (data << 8) | (*(uchar *) cp);
932 if ((rc = write_word (info, wp, data)) != 0) {
933 return (rc);
935 wp += 4;
939 * handle word aligned part
941 while (cnt >= 4) {
942 data = 0;
943 for (i = 0; i < 4; ++i) {
944 data = (data << 8) | *src++;
946 if ((rc = write_word (info, wp, data)) != 0) {
947 return (rc);
949 wp += 4;
950 cnt -= 4;
953 if (cnt == 0) {
954 return (0);
958 * handle unaligned tail bytes
960 data = 0;
961 for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
962 data = (data << 8) | *src++;
963 --cnt;
965 for (; i < 4; ++i, ++cp) {
966 data = (data << 8) | (*(uchar *) cp);
969 return (write_word (info, wp, data));
971 #else
972 wp = (addr & ~1); /* get lower word aligned address */
975 * handle unaligned start byte
977 if (addr - wp) {
978 data = 0;
979 data = (data << 8) | *src++;
980 --cnt;
981 if ((rc = write_short (info, wp, data)) != 0) {
982 return (rc);
984 wp += 2;
988 * handle word aligned part
990 /* l = 0; used for debuging */
991 while (cnt >= 2) {
992 data = 0;
993 for (i = 0; i < 2; ++i) {
994 data = (data << 8) | *src++;
997 /* if(!l){
998 printf("%x",data);
999 l = 1;
1000 } used for debuging */
1002 if ((rc = write_short (info, wp, data)) != 0) {
1003 return (rc);
1005 wp += 2;
1006 cnt -= 2;
1009 if (cnt == 0) {
1010 return (0);
1014 * handle unaligned tail bytes
1016 data = 0;
1017 for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
1018 data = (data << 8) | *src++;
1019 --cnt;
1021 for (; i < 2; ++i, ++cp) {
1022 data = (data << 8) | (*(uchar *) cp);
1025 return (write_short (info, wp, data));
1028 #endif
1031 /*-----------------------------------------------------------------------
1032 * Write a word to Flash, returns:
1033 * 0 - OK
1034 * 1 - write timeout
1035 * 2 - Flash not erased
1037 #ifndef CFG_FLASH_16BIT
1038 static int write_word (flash_info_t * info, ulong dest, ulong data)
1040 vu_long *addr = (vu_long *) (info->start[0]);
1041 ulong start, barf;
1042 int flag;
1044 #if defined (__MIPSEL__)
1045 data = cpu_to_be32 (data);
1046 #endif
1048 /* Check if Flash is (sufficiently) erased */
1049 if ((*((vu_long *) dest) & data) != data) {
1050 return (2);
1053 /* Disable interrupts which might cause a timeout here */
1054 flag = disable_interrupts ();
1056 if (info->flash_id < FLASH_AMD_COMP) {
1057 /* AMD stuff */
1058 addr[0x0555] = 0x00AA00AA;
1059 addr[0x02AA] = 0x00550055;
1060 addr[0x0555] = 0x00A000A0;
1061 } else {
1062 /* intel stuff */
1063 *addr = 0x00400040;
1066 *((vu_long *) dest) = data;
1068 /* re-enable interrupts if necessary */
1069 if (flag)
1070 enable_interrupts ();
1072 /* data polling for D7 */
1073 start = get_timer (0);
1075 if (info->flash_id < FLASH_AMD_COMP) {
1077 while ((*((vu_long *) dest) & 0x00800080) !=
1078 (data & 0x00800080)) {
1079 if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
1080 printf ("timeout\n");
1081 return (1);
1085 } else {
1087 while (!(addr[0] & 0x00800080)) { /* wait for error or finish */
1088 if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
1089 printf ("timeout\n");
1090 return (1);
1094 if (addr[0] & 0x003A003A) { /* check for error */
1095 barf = addr[0] & 0x003A0000;
1096 if (barf) {
1097 barf >>= 16;
1098 } else {
1099 barf = addr[0] & 0x0000003A;
1101 printf ("\nFlash write error at address %lx\n",
1102 (unsigned long) dest);
1103 if (barf & 0x0002)
1104 printf ("Block locked, not erased.\n");
1105 if (barf & 0x0010)
1106 printf ("Programming error.\n");
1107 if (barf & 0x0008)
1108 printf ("Vpp Low error.\n");
1109 return (2);
1115 return (0);
1118 #else
1120 static int write_short (flash_info_t * info, ulong dest, ushort data)
1122 vu_short *addr = (vu_short *) (info->start[0]);
1123 ulong start, barf;
1124 int flag;
1126 #if defined (__MIPSEL__)
1127 data = cpu_to_be16 (data);
1128 #endif
1130 /* Check if Flash is (sufficiently) erased */
1131 if ((*((vu_short *) dest) & data) != data) {
1132 return (2);
1135 /* Disable interrupts which might cause a timeout here */
1136 flag = disable_interrupts ();
1138 if (info->flash_id < FLASH_AMD_COMP) {
1139 /* AMD stuff */
1140 addr[0x0555] = 0x00AA;
1141 addr[0x02AA] = 0x0055;
1142 addr[0x0555] = 0x00A0;
1143 } else {
1144 /* intel stuff */
1145 *addr = 0x00D0;
1146 *addr = 0x0040;
1148 *((vu_short *) dest) = data;
1150 /* re-enable interrupts if necessary */
1151 if (flag)
1152 enable_interrupts ();
1154 /* data polling for D7 */
1155 start = get_timer (0);
1157 if (info->flash_id < FLASH_AMD_COMP) {
1158 /* AMD stuff */
1159 while ((*((vu_short *) dest) & 0x0080) != (data & 0x0080)) {
1160 if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
1161 return (1);
1165 } else {
1166 /* intel stuff */
1167 while (!(addr[0] & 0x0080)) { /* wait for error or finish */
1168 if (get_timer (start) > CFG_FLASH_WRITE_TOUT)
1169 return (1);
1172 if (addr[0] & 0x003A) { /* check for error */
1173 barf = addr[0] & 0x003A;
1174 printf ("\nFlash write error at address %lx\n",
1175 (unsigned long) dest);
1176 if (barf & 0x0002)
1177 printf ("Block locked, not erased.\n");
1178 if (barf & 0x0010)
1179 printf ("Programming error.\n");
1180 if (barf & 0x0008)
1181 printf ("Vpp Low error.\n");
1182 return (2);
1184 *addr = 0x00B0;
1185 *addr = 0x0070;
1186 while (!(addr[0] & 0x0080)) { /* wait for error or finish */
1187 if (get_timer (start) > CFG_FLASH_WRITE_TOUT)
1188 return (1);
1191 *addr = 0x00FF;
1195 return (0);
1198 #endif