1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <common.h>
28#include <linux/byteorder/swab.h>
29
30
31flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
32
33
34#define FLASH_PORT_WIDTH8
35
36typedef unsigned char FLASH_PORT_WIDTH;
37typedef volatile unsigned char FLASH_PORT_WIDTHV;
38
39#define SWAP(x) (x)
40
41
42#define INTEL_COMPAT 0x89
43#define INTEL_ALT 0xB0
44
45
46#define INTEL_PROGRAM 0x10
47#define INTEL_ERASE 0x20
48#define INTEL_CLEAR 0x50
49#define INTEL_LOCKBIT 0x60
50#define INTEL_PROTECT 0x01
51#define INTEL_STATUS 0x70
52#define INTEL_READID 0x90
53#define INTEL_CONFIRM 0xD0
54#define INTEL_RESET 0xFF
55
56
57#define INTEL_FINISHED 0x80
58#define INTEL_OK 0x80
59
60#define FPW FLASH_PORT_WIDTH
61#define FPWV FLASH_PORT_WIDTHV
62
63#define FLASH_CYCLE1 0x0555
64#define FLASH_CYCLE2 0x02aa
65
66#define WR_BLOCK 0x20
67
68
69
70static ulong flash_get_size (FPW * addr, flash_info_t * info);
71static int write_data (flash_info_t * info, ulong dest, FPW data);
72static int write_data_block (flash_info_t * info, ulong src, ulong dest);
73static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
74static void flash_get_offsets (ulong base, flash_info_t * info);
75void inline spin_wheel (void);
76static void flash_sync_real_protect (flash_info_t * info);
77static unsigned char intel_sector_protected (flash_info_t *info, ushort sector);
78static unsigned char same_chip_banks (int bank1, int bank2);
79
80
81
82
83unsigned long flash_init (void)
84{
85 int i;
86 ulong size = 0;
87 ulong fsize = 0;
88
89 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
90 memset (&flash_info[i], 0, sizeof (flash_info_t));
91
92 switch (i) {
93 case 0:
94 flash_get_size ((FPW *) CONFIG_SYS_FLASH1_BASE,
95 &flash_info[i]);
96 flash_get_offsets (CONFIG_SYS_FLASH1_BASE, &flash_info[i]);
97 break;
98 case 1:
99 flash_get_size ((FPW *) CONFIG_SYS_FLASH1_BASE,
100 &flash_info[i]);
101 fsize = CONFIG_SYS_FLASH1_BASE + flash_info[i - 1].size;
102 flash_get_offsets (fsize, &flash_info[i]);
103 break;
104 case 2:
105 flash_get_size ((FPW *) CONFIG_SYS_FLASH0_BASE,
106 &flash_info[i]);
107 flash_get_offsets (CONFIG_SYS_FLASH0_BASE, &flash_info[i]);
108 break;
109 case 3:
110 flash_get_size ((FPW *) CONFIG_SYS_FLASH0_BASE,
111 &flash_info[i]);
112 fsize = CONFIG_SYS_FLASH0_BASE + flash_info[i - 1].size;
113 flash_get_offsets (fsize, &flash_info[i]);
114 break;
115 default:
116 panic ("configured to many flash banks!\n");
117 break;
118 }
119 size += flash_info[i].size;
120
121
122 flash_sync_real_protect(&flash_info[i]);
123 }
124
125
126
127#if defined (CONFIG_SYS_AMD_BOOT)
128 flash_protect (FLAG_PROTECT_SET,
129 CONFIG_SYS_MONITOR_BASE,
130 CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
131 &flash_info[2]);
132 flash_protect (FLAG_PROTECT_SET,
133 CONFIG_SYS_INTEL_BASE,
134 CONFIG_SYS_INTEL_BASE + monitor_flash_len - 1,
135 &flash_info[1]);
136#else
137 flash_protect (FLAG_PROTECT_SET,
138 CONFIG_SYS_MONITOR_BASE,
139 CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
140 &flash_info[3]);
141 flash_protect (FLAG_PROTECT_SET,
142 CONFIG_SYS_AMD_BASE,
143 CONFIG_SYS_AMD_BASE + monitor_flash_len - 1, &flash_info[0]);
144#endif
145
146 flash_protect (FLAG_PROTECT_SET,
147 CONFIG_ENV1_ADDR,
148 CONFIG_ENV1_ADDR + CONFIG_ENV1_SIZE - 1, &flash_info[1]);
149 flash_protect (FLAG_PROTECT_SET,
150 CONFIG_ENV_ADDR,
151 CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[3]);
152
153 return size;
154}
155
156
157
158static void flash_get_offsets (ulong base, flash_info_t * info)
159{
160 int i;
161
162 if (info->flash_id == FLASH_UNKNOWN)
163 return;
164
165 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
166 for (i = 0; i < info->sector_count; i++) {
167 info->start[i] = base + (i * PHYS_AMD_SECT_SIZE);
168 info->protect[i] = 0;
169 }
170 }
171
172 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
173 for (i = 0; i < info->sector_count; i++) {
174 info->start[i] = base + (i * PHYS_INTEL_SECT_SIZE);
175 }
176 }
177}
178
179
180
181void flash_print_info (flash_info_t * info)
182{
183 int i;
184
185 if (info->flash_id == FLASH_UNKNOWN) {
186 printf ("missing or unknown FLASH type\n");
187 return;
188 }
189
190 switch (info->flash_id & FLASH_VENDMASK) {
191 case FLASH_MAN_INTEL:
192 printf ("INTEL ");
193 break;
194 case FLASH_MAN_AMD:
195 printf ("AMD ");
196 break;
197 default:
198 printf ("Unknown Vendor ");
199 break;
200 }
201
202 switch (info->flash_id & FLASH_TYPEMASK) {
203 case FLASH_28F128J3A:
204 printf ("28F128J3A\n");
205 break;
206
207 case FLASH_AM040:
208 printf ("AMD29F040B\n");
209 break;
210
211 default:
212 printf ("Unknown Chip Type\n");
213 break;
214 }
215
216 printf (" Size: %ld MB in %d Sectors\n",
217 info->size >> 20, info->sector_count);
218
219 printf (" Sector Start Addresses:");
220 for (i = 0; i < info->sector_count; ++i) {
221 if ((i % 5) == 0)
222 printf ("\n ");
223 printf (" %08lX%s",
224 info->start[i], info->protect[i] ? " (RO)" : " ");
225 }
226 printf ("\n");
227 return;
228}
229
230
231
232
233static ulong flash_get_size (FPW * addr, flash_info_t * info)
234{
235 FPWV value;
236 static int amd = 0;
237
238
239
240 addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA;
241 __asm__ ("sync");
242 addr[FLASH_CYCLE2] = (FPW) 0x00550055;
243 __asm__ ("sync");
244 addr[FLASH_CYCLE1] = (FPW) 0x00900090;
245 __asm__ ("sync");
246
247 udelay (100);
248
249 switch (addr[0] & 0xff) {
250
251 case (uchar) AMD_MANUFACT:
252 info->flash_id = FLASH_MAN_AMD;
253 value = addr[1];
254 break;
255
256 case (uchar) INTEL_MANUFACT:
257 info->flash_id = FLASH_MAN_INTEL;
258 value = addr[2];
259 break;
260
261 default:
262 printf ("unknown\n");
263 info->flash_id = FLASH_UNKNOWN;
264 info->sector_count = 0;
265 info->size = 0;
266 addr[0] = (FPW) 0x00FF00FF;
267 return (0);
268 }
269
270 switch (value) {
271
272 case (FPW) INTEL_ID_28F128J3A:
273 info->flash_id += FLASH_28F128J3A;
274 info->sector_count = 64;
275 info->size = 0x00800000;
276 break;
277
278 case (FPW) AMD_ID_LV040B:
279 info->flash_id += FLASH_AM040;
280 if (amd == 0) {
281 info->sector_count = 7;
282 info->size = 0x00070000;
283 amd = 1;
284 } else {
285
286 info->sector_count = 1;
287 info->size = PHYS_AMD_SECT_SIZE;
288 amd = 0;
289 }
290 break;
291
292 default:
293 info->flash_id = FLASH_UNKNOWN;
294 break;
295 }
296
297 if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
298 printf ("** ERROR: sector count %d > max (%d) **\n",
299 info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
300 info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
301 }
302
303 if (value == (FPW) INTEL_ID_28F128J3A)
304 addr[0] = (FPW) 0x00FF00FF;
305 else
306 addr[0] = (FPW) 0x00F000F0;
307
308 return (info->size);
309}
310
311
312
313
314
315
316
317static void flash_sync_real_protect (flash_info_t * info)
318{
319 int i;
320
321 switch (info->flash_id & FLASH_TYPEMASK) {
322 case FLASH_28F128J3A:
323 for (i = 0; i < info->sector_count; ++i) {
324 info->protect[i] = intel_sector_protected(info, i);
325 }
326 break;
327 case FLASH_AM040:
328 default:
329
330 break;
331 }
332}
333
334
335
336
337
338
339
340
341static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
342{
343 FPWV *addr;
344 FPWV *lock_conf_addr;
345 ulong start;
346 unsigned char ret;
347
348
349
350
351
352
353
354
355
356
357
358 udelay(1);
359 addr = (FPWV *) info->start[sector];
360 *addr = (FPW) INTEL_STATUS;
361
362 start = get_timer (0);
363 while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
364 if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
365 *addr = (FPW) INTEL_RESET;
366 printf("WSM busy too long, can't get prot status\n");
367 return 1;
368 }
369 }
370
371
372 *addr = (FPW) INTEL_READID;
373
374
375 udelay(1);
376
377
378 lock_conf_addr = (FPWV *) info->start[sector] + 4;
379 ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;
380
381
382 *addr = (FPW) INTEL_RESET;
383
384 return ret;
385}
386
387
388
389
390
391
392static unsigned char same_chip_banks (int bank1, int bank2)
393{
394 unsigned char same_chip[CONFIG_SYS_MAX_FLASH_BANKS][CONFIG_SYS_MAX_FLASH_BANKS] = {
395 {1, 1, 0, 0},
396 {1, 1, 0, 0},
397 {0, 0, 1, 1},
398 {0, 0, 1, 1}
399 };
400 return same_chip[bank1][bank2];
401}
402
403
404
405
406int flash_erase (flash_info_t * info, int s_first, int s_last)
407{
408 int flag, prot, sect;
409 ulong type, start, last;
410 int rcode = 0, intel = 0;
411
412 if ((s_first < 0) || (s_first > s_last)) {
413 if (info->flash_id == FLASH_UNKNOWN)
414 printf ("- missing\n");
415 else
416 printf ("- no sectors to erase\n");
417 return 1;
418 }
419
420 type = (info->flash_id & FLASH_VENDMASK);
421 if ((type != FLASH_MAN_INTEL)) {
422 type = (info->flash_id & FLASH_VENDMASK);
423 if ((type != FLASH_MAN_AMD)) {
424 printf ("Can't erase unknown flash type %08lx - aborted\n",
425 info->flash_id);
426 return 1;
427 }
428 }
429
430 if (type == FLASH_MAN_INTEL)
431 intel = 1;
432
433 prot = 0;
434 for (sect = s_first; sect <= s_last; ++sect) {
435 if (info->protect[sect]) {
436 prot++;
437 }
438 }
439
440 if (prot) {
441 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
442 } else {
443 printf ("\n");
444 }
445
446 start = get_timer (0);
447 last = start;
448
449
450 flag = disable_interrupts ();
451
452
453 for (sect = s_first; sect <= s_last; sect++) {
454 if (info->protect[sect] == 0) {
455 FPWV *addr = (FPWV *) (info->start[sect]);
456 FPW status;
457
458 printf ("Erasing sector %2d ... ", sect);
459
460
461 start = get_timer (0);
462
463 if (intel) {
464 *addr = (FPW) 0x00500050;
465 *addr = (FPW) 0x00200020;
466 *addr = (FPW) 0x00D000D0;
467 } else {
468 FPWV *base;
469
470 base = (FPWV *) (CONFIG_SYS_AMD_BASE);
471 base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;
472 base[FLASH_CYCLE2] = (FPW) 0x00550055;
473 base[FLASH_CYCLE1] = (FPW) 0x00800080;
474 base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;
475 base[FLASH_CYCLE2] = (FPW) 0x00550055;
476 *addr = (FPW) 0x00300030;
477 }
478
479 while (((status =
480 *addr) & (FPW) 0x00800080) !=
481 (FPW) 0x00800080) {
482 if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
483 printf ("Timeout\n");
484 if (intel) {
485 *addr = (FPW) 0x00B000B0;
486 *addr = (FPW) 0x00FF00FF;
487 } else
488 *addr = (FPW) 0x00F000F0;
489
490 rcode = 1;
491 break;
492 }
493 }
494
495 if (intel) {
496 *addr = (FPW) 0x00500050;
497 *addr = (FPW) 0x00FF00FF;
498 } else
499 *addr = (FPW) 0x00F000F0;
500
501 printf (" done\n");
502 }
503 }
504 return rcode;
505}
506
507
508
509
510
511
512
513
514
515int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
516{
517 if (info->flash_id == FLASH_UNKNOWN) {
518 return 4;
519 }
520
521 switch (info->flash_id & FLASH_VENDMASK) {
522 case FLASH_MAN_AMD:
523 {
524 FPW data = 0;
525 int bytes;
526 int left;
527 int i, res;
528
529 for (left = cnt, res = 0;
530 left > 0 && res == 0;
531 addr += sizeof (data), left -=
532 sizeof (data) - bytes) {
533
534 bytes = addr & (sizeof (data) - 1);
535 addr &= ~(sizeof (data) - 1);
536
537
538
539
540 for (i = 0; i < sizeof (data); i++) {
541 data <<= 8;
542 if (i < bytes || i - bytes >= left)
543 data += *((uchar *) addr + i);
544 else
545 data += *src++;
546 }
547
548 res = write_word_amd (info, (FPWV *) addr,
549 data);
550 }
551 return res;
552 }
553
554 case FLASH_MAN_INTEL:
555 {
556 ulong cp, wp;
557 FPW data;
558 int count, i, l, rc, port_width;
559
560
561 wp = addr;
562 port_width = 1;
563
564
565
566
567 if ((l = addr - wp) != 0) {
568 data = 0;
569 for (i = 0, cp = wp; i < l; ++i, ++cp) {
570 data = (data << 8) | (*(uchar *) cp);
571 }
572
573 for (; i < port_width && cnt > 0; ++i) {
574 data = (data << 8) | *src++;
575 --cnt;
576 ++cp;
577 }
578
579 for (; cnt == 0 && i < port_width; ++i, ++cp)
580 data = (data << 8) | (*(uchar *) cp);
581
582 if ((rc =
583 write_data (info, wp, SWAP (data))) != 0)
584 return (rc);
585 wp += port_width;
586 }
587
588 if (cnt > WR_BLOCK) {
589
590
591
592 count = 0;
593 while (cnt >= WR_BLOCK) {
594
595 if ((rc =
596 write_data_block (info,
597 (ulong) src,
598 wp)) != 0)
599 return (rc);
600
601 wp += WR_BLOCK;
602 src += WR_BLOCK;
603 cnt -= WR_BLOCK;
604
605 if (count++ > 0x800) {
606 spin_wheel ();
607 count = 0;
608 }
609 }
610 }
611
612 if (cnt < WR_BLOCK) {
613
614
615
616 count = 0;
617 while (cnt >= port_width) {
618 data = 0;
619 for (i = 0; i < port_width; ++i)
620 data = (data << 8) | *src++;
621
622 if ((rc =
623 write_data (info, wp,
624 SWAP (data))) != 0)
625 return (rc);
626
627 wp += port_width;
628 cnt -= port_width;
629 if (count++ > 0x800) {
630 spin_wheel ();
631 count = 0;
632 }
633 }
634 }
635
636 if (cnt == 0)
637 return (0);
638
639
640
641
642 data = 0;
643 for (i = 0, cp = wp; i < port_width && cnt > 0;
644 ++i, ++cp) {
645 data = (data << 8) | *src++;
646 --cnt;
647 }
648
649 for (; i < port_width; ++i, ++cp)
650 data = (data << 8) | (*(uchar *) cp);
651
652 return (write_data (info, wp, SWAP (data)));
653 }
654
655 }
656 return (0);
657}
658
659
660
661
662
663
664
665static int write_data (flash_info_t * info, ulong dest, FPW data)
666{
667 FPWV *addr = (FPWV *) dest;
668 ulong start;
669 int flag;
670
671
672 if ((*addr & data) != data) {
673 printf ("not erased at %08lx (%lx)\n", (ulong)addr, (ulong)*addr);
674 return (2);
675 }
676
677 flag = disable_interrupts ();
678
679 *addr = (FPW) 0x00400040;
680 *addr = data;
681
682
683 start = get_timer (0);
684
685
686 while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
687 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
688 *addr = (FPW) 0x00FF00FF;
689 return (1);
690 }
691 }
692
693 *addr = (FPW) 0x00FF00FF;
694
695 return (0);
696}
697
698
699
700
701
702
703
704static int write_data_block (flash_info_t * info, ulong src, ulong dest)
705{
706 FPWV *srcaddr = (FPWV *) src;
707 FPWV *dstaddr = (FPWV *) dest;
708 ulong start;
709 int flag, i;
710
711
712 for (i = 0; i < WR_BLOCK; i++)
713 if ((*dstaddr++ & 0xff) != 0xff) {
714 printf ("not erased at %08lx (%lx)\n",
715 (ulong)dstaddr, (ulong)*dstaddr);
716 return (2);
717 }
718
719 dstaddr = (FPWV *) dest;
720
721
722 flag = disable_interrupts ();
723
724 *dstaddr = (FPW) 0x00e800e8;
725
726
727 start = get_timer (0);
728
729
730 while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
731 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
732 *dstaddr = (FPW) 0x00FF00FF;
733 return (1);
734 }
735 }
736
737 *dstaddr = (FPW) 0x001f001f;
738 for (i = 0; i < WR_BLOCK; i++)
739 *dstaddr++ = *srcaddr++;
740
741 dstaddr -= 1;
742 *dstaddr = (FPW) 0x00d000d0;
743
744
745 start = get_timer (0);
746
747
748 while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
749 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
750 *dstaddr = (FPW) 0x00FF00FF;
751 return (1);
752 }
753 }
754
755 *dstaddr = (FPW) 0x00FF00FF;
756
757 return (0);
758}
759
760
761
762
763
764
765
766
767
768
769
770static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
771{
772 ulong start;
773 int flag;
774 int res = 0;
775 FPWV *base;
776
777
778 if ((*dest & data) != data) {
779 return (2);
780 }
781
782 base = (FPWV *) (CONFIG_SYS_AMD_BASE);
783
784
785 flag = disable_interrupts ();
786
787 base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;
788 base[FLASH_CYCLE2] = (FPW) 0x00550055;
789 base[FLASH_CYCLE1] = (FPW) 0x00A000A0;
790
791 *dest = data;
792
793
794 if (flag)
795 enable_interrupts ();
796
797 start = get_timer (0);
798
799
800 while (res == 0
801 && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
802 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
803 *dest = (FPW) 0x00F000F0;
804 res = 1;
805 }
806 }
807
808 return (res);
809}
810
811void inline spin_wheel (void)
812{
813 static int p = 0;
814 static char w[] = "\\/-";
815
816 printf ("\010%c", w[p]);
817 (++p == 3) ? (p = 0) : 0;
818}
819
820
821
822
823
824
825int flash_real_protect (flash_info_t * info, long sector, int prot)
826{
827 ulong start;
828 int i, j;
829 int curr_bank;
830 int bank;
831 int rc = 0;
832 FPWV *addr = (FPWV *) (info->start[sector]);
833 int flag = disable_interrupts ();
834
835
836
837
838
839
840
841 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
842 info->protect[sector] = prot;
843
844 return 0;
845 }
846
847 *addr = INTEL_CLEAR;
848 if (prot) {
849 *addr = INTEL_LOCKBIT;
850 *addr = INTEL_PROTECT;
851 } else {
852 *addr = INTEL_LOCKBIT;
853 *addr = INTEL_CONFIRM;
854 }
855
856 start = get_timer (0);
857
858 while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
859 if (get_timer (start) > CONFIG_SYS_FLASH_UNLOCK_TOUT) {
860 printf ("Flash lock bit operation timed out\n");
861 rc = 1;
862 break;
863 }
864 }
865
866 if (*addr != INTEL_OK) {
867 printf ("Flash lock bit operation failed at %08X, CSR=%08X\n",
868 (uint) addr, (uint) * addr);
869 rc = 1;
870 }
871
872 if (!rc)
873 info->protect[sector] = prot;
874
875
876
877
878
879 if (!prot) {
880
881
882
883
884
885
886
887
888
889 curr_bank = CONFIG_SYS_MAX_FLASH_BANKS + 1;
890 for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; ++j) {
891 if (&flash_info[j] == info) {
892 curr_bank = j;
893 }
894 }
895 if (curr_bank == CONFIG_SYS_MAX_FLASH_BANKS + 1) {
896 printf("Error: can't determine bank number!\n");
897 }
898
899 for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
900 if (!same_chip_banks(curr_bank, bank)) {
901 continue;
902 }
903 info = &flash_info[bank];
904 for (i = 0; i < info->sector_count; i++) {
905 if (info->protect[i]) {
906 start = get_timer (0);
907 addr = (FPWV *) (info->start[i]);
908 *addr = INTEL_LOCKBIT;
909 *addr = INTEL_PROTECT;
910 while ((*addr & INTEL_FINISHED) !=
911 INTEL_FINISHED) {
912 if (get_timer (start) >
913 CONFIG_SYS_FLASH_UNLOCK_TOUT) {
914 printf ("Flash lock bit operation timed out\n");
915 rc = 1;
916 break;
917 }
918 }
919 }
920 }
921 }
922
923
924
925
926
927 flash_sync_real_protect(info);
928 }
929
930 if (flag)
931 enable_interrupts ();
932
933 *addr = INTEL_RESET;
934
935 return rc;
936}
937