1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <common.h>
19#include <asm/ppc4xx.h>
20#include <asm/processor.h>
21#include <asm/ppc440.h>
22#include "yucca.h"
23
24#ifdef DEBUG
25#define DEBUGF(x...) printf(x)
26#else
27#define DEBUGF(x...)
28#endif
29
30flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
31
32
33
34
35static unsigned long flash_addr_table[][CONFIG_SYS_MAX_FLASH_BANKS] = {
36 {0xfff00000, 0xfff80000, 0xe7c00001},
37 {0x00000000, 0x00000000, 0x00000000},
38 {0x00000000, 0x00000000, 0x00000000},
39 {0xe7F00000, 0xe7F80000, 0xFFC00001},
40 {0xe7F00000, 0xe7F80000, 0xFFC00001},
41 {0x00000000, 0x00000000, 0x00000000},
42 {0x00000000, 0x00000000, 0x00000000},
43 {0x00000000, 0x00000000, 0x00000000},
44 {0xfff00000, 0xfff80000, 0xe7c00001},
45};
46
47
48
49
50
51
52
53static int write_word(flash_info_t * info, ulong dest, ulong data);
54#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
55static int write_word_1(flash_info_t * info, ulong dest, ulong data);
56static int write_word_2(flash_info_t * info, ulong dest, ulong data);
57static int flash_erase_1(flash_info_t * info, int s_first, int s_last);
58static int flash_erase_2(flash_info_t * info, int s_first, int s_last);
59static ulong flash_get_size_1(vu_long * addr, flash_info_t * info);
60static ulong flash_get_size_2(vu_long * addr, flash_info_t * info);
61#endif
62
63void flash_print_info(flash_info_t * info)
64{
65 int i;
66 int k;
67 int size;
68 int erased;
69 volatile unsigned long *flash;
70
71 if (info->flash_id == FLASH_UNKNOWN) {
72 printf("missing or unknown FLASH type\n");
73 return;
74 }
75
76 switch (info->flash_id & FLASH_VENDMASK) {
77 case FLASH_MAN_AMD:
78 printf("AMD ");
79 break;
80 case FLASH_MAN_STM:
81 printf("STM ");
82 break;
83 case FLASH_MAN_FUJ:
84 printf("FUJITSU ");
85 break;
86 case FLASH_MAN_SST:
87 printf("SST ");
88 break;
89 case FLASH_MAN_MX:
90 printf("MIXC ");
91 break;
92 default:
93 printf("Unknown Vendor ");
94 break;
95 }
96
97 switch (info->flash_id & FLASH_TYPEMASK) {
98 case FLASH_AM040:
99 printf("AM29F040 (512 Kbit, uniform sector size)\n");
100 break;
101 case FLASH_AM400B:
102 printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
103 break;
104 case FLASH_AM400T:
105 printf("AM29LV400T (4 Mbit, top boot sector)\n");
106 break;
107 case FLASH_AM800B:
108 printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
109 break;
110 case FLASH_AM800T:
111 printf("AM29LV800T (8 Mbit, top boot sector)\n");
112 break;
113 case FLASH_AMD016:
114 printf("AM29F016D (16 Mbit, uniform sector size)\n");
115 break;
116 case FLASH_AM160B:
117 printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
118 break;
119 case FLASH_AM160T:
120 printf("AM29LV160T (16 Mbit, top boot sector)\n");
121 break;
122 case FLASH_AM320B:
123 printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
124 break;
125 case FLASH_AM320T:
126 printf("AM29LV320T (32 Mbit, top boot sector)\n");
127 break;
128 case FLASH_AM033C:
129 printf("AM29LV033C (32 Mbit, top boot sector)\n");
130 break;
131 case FLASH_SST800A:
132 printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
133 break;
134 case FLASH_SST160A:
135 printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
136 break;
137 case FLASH_STMW320DT:
138 printf ("M29W320DT (32 M, top sector)\n");
139 break;
140 case FLASH_MXLV320T:
141 printf ("MXLV320T (32 Mbit, top sector)\n");
142 break;
143 default:
144 printf("Unknown Chip Type\n");
145 break;
146 }
147
148 printf(" Size: %ld KB in %d Sectors\n",
149 info->size >> 10, info->sector_count);
150
151 printf(" Sector Start Addresses:");
152 for (i = 0; i < info->sector_count; ++i) {
153
154
155
156 if (i != (info->sector_count - 1))
157 size = info->start[i + 1] - info->start[i];
158 else
159 size = info->start[0] + info->size - info->start[i];
160 erased = 1;
161 flash = (volatile unsigned long *)info->start[i];
162 size = size >> 2;
163 for (k = 0; k < size; k++) {
164 if (*flash++ != 0xffffffff) {
165 erased = 0;
166 break;
167 }
168 }
169
170 if ((i % 5) == 0)
171 printf("\n ");
172 printf(" %08lX%s%s",
173 info->start[i],
174 erased ? " E" : " ",
175 info->protect[i] ? "RO " : " ");
176 }
177 printf("\n");
178 return;
179}
180
181
182
183
184
185#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
186static ulong flash_get_size(vu_long * addr, flash_info_t * info)
187{
188
189 if ((ulong)addr & 0x1)
190 return flash_get_size_2((vu_long *)((ulong)addr & 0xfffffffe), info);
191 else
192 return flash_get_size_1(addr, info);
193}
194
195static ulong flash_get_size_1(vu_long * addr, flash_info_t * info)
196#else
197static ulong flash_get_size(vu_long * addr, flash_info_t * info)
198#endif
199{
200 short i;
201 CONFIG_SYS_FLASH_WORD_SIZE value;
202 ulong base = (ulong) addr;
203 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
204
205 DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
206
207
208 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
209 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
210 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00900090;
211 udelay(1000);
212
213 value = addr2[0];
214 DEBUGF("FLASH MANUFACT: %x\n", value);
215
216 switch (value) {
217 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
218 info->flash_id = FLASH_MAN_AMD;
219 break;
220 case (CONFIG_SYS_FLASH_WORD_SIZE) FUJ_MANUFACT:
221 info->flash_id = FLASH_MAN_FUJ;
222 break;
223 case (CONFIG_SYS_FLASH_WORD_SIZE) SST_MANUFACT:
224 info->flash_id = FLASH_MAN_SST;
225 break;
226 case (CONFIG_SYS_FLASH_WORD_SIZE) STM_MANUFACT:
227 info->flash_id = FLASH_MAN_STM;
228 break;
229 default:
230 info->flash_id = FLASH_UNKNOWN;
231 info->sector_count = 0;
232 info->size = 0;
233 return (0);
234 }
235
236 value = addr2[1];
237 DEBUGF("\nFLASH DEVICEID: %x\n", value);
238
239 switch (value) {
240 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_LV040B:
241 info->flash_id += FLASH_AM040;
242 info->sector_count = 8;
243 info->size = 0x0080000;
244 break;
245
246 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_F040B:
247 info->flash_id += FLASH_AM040;
248 info->sector_count = 8;
249 info->size = 0x0080000;
250 break;
251
252 case (CONFIG_SYS_FLASH_WORD_SIZE) STM_ID_M29W040B:
253 info->flash_id += FLASH_AM040;
254 info->sector_count = 8;
255 info->size = 0x0080000;
256 break;
257
258 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_F016D:
259 info->flash_id += FLASH_AMD016;
260 info->sector_count = 32;
261 info->size = 0x00200000;
262 break;
263
264 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_LV033C:
265 info->flash_id += FLASH_AMDLV033C;
266 info->sector_count = 64;
267 info->size = 0x00400000;
268 break;
269
270 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_LV400T:
271 info->flash_id += FLASH_AM400T;
272 info->sector_count = 11;
273 info->size = 0x00080000;
274 break;
275
276 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_LV400B:
277 info->flash_id += FLASH_AM400B;
278 info->sector_count = 11;
279 info->size = 0x00080000;
280 break;
281
282 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_LV800T:
283 info->flash_id += FLASH_AM800T;
284 info->sector_count = 19;
285 info->size = 0x00100000;
286 break;
287
288 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_LV800B:
289 info->flash_id += FLASH_AM800B;
290 info->sector_count = 19;
291 info->size = 0x00100000;
292 break;
293
294 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_LV160T:
295 info->flash_id += FLASH_AM160T;
296 info->sector_count = 35;
297 info->size = 0x00200000;
298 break;
299
300 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_ID_LV160B:
301 info->flash_id += FLASH_AM160B;
302 info->sector_count = 35;
303 info->size = 0x00200000;
304 break;
305
306 default:
307 info->flash_id = FLASH_UNKNOWN;
308 return (0);
309 }
310
311
312 if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
313 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) ||
314 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) {
315 for (i = 0; i < info->sector_count; i++)
316 info->start[i] = base + (i * 0x00010000);
317 } else {
318 if (info->flash_id & FLASH_BTYPE) {
319
320 info->start[0] = base + 0x00000000;
321 info->start[1] = base + 0x00004000;
322 info->start[2] = base + 0x00006000;
323 info->start[3] = base + 0x00008000;
324 for (i = 4; i < info->sector_count; i++) {
325 info->start[i] =
326 base + (i * 0x00010000) - 0x00030000;
327 }
328 } else {
329
330 i = info->sector_count - 1;
331 info->start[i--] = base + info->size - 0x00004000;
332 info->start[i--] = base + info->size - 0x00006000;
333 info->start[i--] = base + info->size - 0x00008000;
334 for (; i >= 0; i--) {
335 info->start[i] = base + i * 0x00010000;
336 }
337 }
338 }
339
340
341 for (i = 0; i < info->sector_count; i++) {
342
343
344 addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
345
346
347
348 if (i == 32) {
349 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAAAAAAAA;
350 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55555555;
351 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x90909090;
352 }
353
354 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
355 info->protect[i] = 0;
356 else
357 info->protect[i] = addr2[2] & 1;
358 }
359
360
361 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;
362
363 return (info->size);
364}
365
366static int wait_for_DQ7_1(flash_info_t * info, int sect)
367{
368 ulong start, now, last;
369 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
370 (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
371
372 start = get_timer(0);
373 last = start;
374 while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
375 (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) {
376 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
377 printf("Timeout\n");
378 return -1;
379 }
380
381 if ((now - last) > 1000) {
382 putc('.');
383 last = now;
384 }
385 }
386 return 0;
387}
388
389#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
390int flash_erase(flash_info_t * info, int s_first, int s_last)
391{
392 if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
393 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
394 ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) ||
395 ((info->flash_id & FLASH_TYPEMASK) == FLASH_MXLV320T)) {
396 return flash_erase_2(info, s_first, s_last);
397 } else {
398 return flash_erase_1(info, s_first, s_last);
399 }
400}
401
402static int flash_erase_1(flash_info_t * info, int s_first, int s_last)
403#else
404int flash_erase(flash_info_t * info, int s_first, int s_last)
405#endif
406{
407 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
408 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
409 int flag, prot, sect;
410 int i;
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 if (info->flash_id == FLASH_UNKNOWN) {
421 printf("Can't erase unknown flash type - aborted\n");
422 return 1;
423 }
424
425 prot = 0;
426 for (sect = s_first; sect <= s_last; ++sect) {
427 if (info->protect[sect])
428 prot++;
429 }
430
431 if (prot)
432 printf("- Warning: %d protected sectors will not be erased!", prot);
433
434 printf("\n");
435
436
437 flag = disable_interrupts();
438
439
440 for (sect = s_first; sect <= s_last; sect++) {
441 if (info->protect[sect] == 0) {
442 addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
443
444 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
445 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
446 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
447 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080;
448 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
449 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
450 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00500050;
451 for (i = 0; i < 50; i++)
452 udelay(1000);
453 } else {
454 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
455 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
456 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080;
457 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
458 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
459 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00300030;
460 }
461
462
463
464
465
466
467
468 wait_for_DQ7_1(info, sect);
469 }
470 }
471
472
473 if (flag)
474 enable_interrupts();
475
476
477 udelay(1000);
478
479
480 addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
481 addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;
482
483 printf(" done\n");
484 return 0;
485}
486
487
488
489
490
491
492
493int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
494{
495 ulong cp, wp, data;
496 int i, l, rc;
497
498 wp = (addr & ~3);
499
500
501
502
503 if ((l = addr - wp) != 0) {
504 data = 0;
505 for (i = 0, cp = wp; i < l; ++i, ++cp)
506 data = (data << 8) | (*(uchar *) cp);
507
508 for (; i < 4 && cnt > 0; ++i) {
509 data = (data << 8) | *src++;
510 --cnt;
511 ++cp;
512 }
513
514 for (; cnt == 0 && i < 4; ++i, ++cp)
515 data = (data << 8) | (*(uchar *) cp);
516
517 if ((rc = write_word(info, wp, data)) != 0)
518 return (rc);
519
520 wp += 4;
521 }
522
523
524
525
526 while (cnt >= 4) {
527 data = 0;
528 for (i = 0; i < 4; ++i)
529 data = (data << 8) | *src++;
530
531 if ((rc = write_word(info, wp, data)) != 0)
532 return (rc);
533
534 wp += 4;
535 cnt -= 4;
536 }
537
538 if (cnt == 0)
539 return (0);
540
541
542
543
544 data = 0;
545 for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
546 data = (data << 8) | *src++;
547 --cnt;
548 }
549 for (; i < 4; ++i, ++cp)
550 data = (data << 8) | (*(uchar *) cp);
551
552 return (write_word(info, wp, data));
553}
554
555
556
557
558
559
560
561#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
562static int write_word(flash_info_t * info, ulong dest, ulong data)
563{
564 if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
565 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
566 ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) ||
567 ((info->flash_id & FLASH_TYPEMASK) == FLASH_MXLV320T)) {
568 return write_word_2(info, dest, data);
569 } else {
570 return write_word_1(info, dest, data);
571 }
572}
573
574static int write_word_1(flash_info_t * info, ulong dest, ulong data)
575#else
576static int write_word(flash_info_t * info, ulong dest, ulong data)
577#endif
578{
579 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
580 volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
581 volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *) & data;
582 ulong start;
583 int i, flag;
584
585
586 if ((*((vu_long *)dest) & data) != data)
587 return (2);
588
589 for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
590
591 flag = disable_interrupts();
592
593 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
594 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
595 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00A000A0;
596
597 dest2[i] = data2[i];
598
599
600 if (flag)
601 enable_interrupts();
602
603
604 start = get_timer(0);
605 while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
606 (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080)) {
607
608 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
609 return (1);
610 }
611 }
612
613 return (0);
614}
615
616#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
617
618#undef CONFIG_SYS_FLASH_WORD_SIZE
619#define CONFIG_SYS_FLASH_WORD_SIZE unsigned short
620
621
622
623
624static ulong flash_get_size_2(vu_long * addr, flash_info_t * info)
625{
626 short i;
627 int n;
628 CONFIG_SYS_FLASH_WORD_SIZE value;
629 ulong base = (ulong) addr;
630 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
631
632 DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
633
634
635 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;
636
637 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
638 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
639 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00900090;
640 udelay(1000);
641
642 value = addr2[0];
643 DEBUGF("FLASH MANUFACT: %x\n", value);
644
645 switch (value) {
646 case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
647 info->flash_id = FLASH_MAN_AMD;
648 break;
649 case (CONFIG_SYS_FLASH_WORD_SIZE) FUJ_MANUFACT:
650 info->flash_id = FLASH_MAN_FUJ;
651 break;
652 case (CONFIG_SYS_FLASH_WORD_SIZE) SST_MANUFACT:
653 info->flash_id = FLASH_MAN_SST;
654 break;
655 case (CONFIG_SYS_FLASH_WORD_SIZE) STM_MANUFACT:
656 info->flash_id = FLASH_MAN_STM;
657 break;
658 case (CONFIG_SYS_FLASH_WORD_SIZE) MX_MANUFACT:
659 info->flash_id = FLASH_MAN_MX;
660 break;
661 default:
662 info->flash_id = FLASH_UNKNOWN;
663 info->sector_count = 0;
664 info->size = 0;
665 return (0);
666 }
667
668 value = addr2[1];
669 DEBUGF("\nFLASH DEVICEID: %x\n", value);
670
671 switch (value) {
672 case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
673 info->flash_id += FLASH_AM320T;
674 info->sector_count = 71;
675 info->size = 0x00400000;
676 break;
677 case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
678 info->flash_id += FLASH_AM320B;
679 info->sector_count = 71;
680 info->size = 0x00400000;
681 break;
682 case (CONFIG_SYS_FLASH_WORD_SIZE)STM_ID_29W320DT:
683 info->flash_id += FLASH_STMW320DT;
684 info->sector_count = 67;
685 info->size = 0x00400000;
686 break;
687 case (CONFIG_SYS_FLASH_WORD_SIZE)MX_ID_LV320T:
688 info->flash_id += FLASH_MXLV320T;
689 info->sector_count = 71;
690 info->size = 0x00400000;
691 break;
692 default:
693 info->flash_id = FLASH_UNKNOWN;
694 return (0);
695 }
696
697
698 if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
699 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) ||
700 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) {
701 for (i = 0; i < info->sector_count; i++)
702 info->start[i] = base + (i * 0x00010000);
703 } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) {
704
705 base += info->size;
706 i = info->sector_count;
707
708 base -= 16 << 10;
709 --i;
710 info->start[i] = base;
711
712 for (n = 0; n < 2; ++n) {
713 base -= 8 << 10;
714 --i;
715 info->start[i] = base;
716 }
717
718 base -= 32 << 10;
719 --i;
720 info->start[i] = base;
721
722 while (i > 0) {
723 base -= 64 << 10;
724 --i;
725 info->start[i] = base;
726 }
727 } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_MXLV320T) {
728 i = info->sector_count - 1;
729 info->start[i--] = base + info->size - 0x00002000;
730 info->start[i--] = base + info->size - 0x00004000;
731 info->start[i--] = base + info->size - 0x00006000;
732 info->start[i--] = base + info->size - 0x00008000;
733 info->start[i--] = base + info->size - 0x0000a000;
734 info->start[i--] = base + info->size - 0x0000c000;
735 info->start[i--] = base + info->size - 0x0000e000;
736 info->start[i--] = base + info->size - 0x00010000;
737
738 for (; i >= 0; i--)
739 info->start[i] = base + i * 0x00010000;
740 } else {
741 if (info->flash_id & FLASH_BTYPE) {
742
743 info->start[0] = base + 0x00000000;
744 info->start[1] = base + 0x00004000;
745 info->start[2] = base + 0x00006000;
746 info->start[3] = base + 0x00008000;
747
748 for (i = 4; i < info->sector_count; i++)
749 info->start[i] = base + (i * 0x00010000) - 0x00030000;
750 } else {
751
752 i = info->sector_count - 1;
753 info->start[i--] = base + info->size - 0x00004000;
754 info->start[i--] = base + info->size - 0x00006000;
755 info->start[i--] = base + info->size - 0x00008000;
756
757 for (; i >= 0; i--)
758 info->start[i] = base + i * 0x00010000;
759 }
760 }
761
762
763 for (i = 0; i < info->sector_count; i++) {
764
765
766 addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
767
768
769
770 if (i == 32) {
771 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAAAAAAAA;
772 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55555555;
773 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x90909090;
774 }
775
776 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
777 info->protect[i] = 0;
778 else
779 info->protect[i] = addr2[2] & 1;
780 }
781
782
783 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;
784
785 return (info->size);
786}
787
788static int wait_for_DQ7_2(flash_info_t * info, int sect)
789{
790 ulong start, now, last;
791 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
792 (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
793
794 start = get_timer(0);
795 last = start;
796 while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
797 (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) {
798 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
799 printf("Timeout\n");
800 return -1;
801 }
802
803 if ((now - last) > 1000) {
804 putc('.');
805 last = now;
806 }
807 }
808 return 0;
809}
810
811static int flash_erase_2(flash_info_t * info, int s_first, int s_last)
812{
813 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
814 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
815 int flag, prot, sect;
816 int i;
817
818 if ((s_first < 0) || (s_first > s_last)) {
819 if (info->flash_id == FLASH_UNKNOWN)
820 printf("- missing\n");
821 else
822 printf("- no sectors to erase\n");
823 return 1;
824 }
825
826 if (info->flash_id == FLASH_UNKNOWN) {
827 printf("Can't erase unknown flash type - aborted\n");
828 return 1;
829 }
830
831 prot = 0;
832 for (sect = s_first; sect <= s_last; ++sect) {
833 if (info->protect[sect])
834 prot++;
835 }
836
837 if (prot)
838 printf("- Warning: %d protected sectors will not be erased!", prot);
839
840 printf("\n");
841
842
843 flag = disable_interrupts();
844
845
846 for (sect = s_first; sect <= s_last; sect++) {
847 if (info->protect[sect] == 0) {
848 addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
849
850 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
851 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
852 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
853 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080;
854 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
855 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
856 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00500050;
857 for (i = 0; i < 50; i++)
858 udelay(1000);
859 } else {
860 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
861 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
862 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080;
863 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
864 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
865 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00300030;
866 }
867
868
869
870
871
872
873
874 wait_for_DQ7_2(info, sect);
875 }
876 }
877
878
879 if (flag)
880 enable_interrupts();
881
882
883 udelay(1000);
884
885
886 addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
887 addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;
888
889 printf(" done\n");
890 return 0;
891}
892
893static int write_word_2(flash_info_t * info, ulong dest, ulong data)
894{
895 ulong *data_ptr = &data;
896 volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
897 volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *)dest;
898 volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *)data_ptr;
899 ulong start;
900 int i;
901
902
903 if ((*((vu_long *)dest) & data) != data)
904 return (2);
905
906 for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
907 int flag;
908
909
910 flag = disable_interrupts();
911
912 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
913 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
914 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00A000A0;
915
916 dest2[i] = data2[i];
917
918
919 if (flag)
920 enable_interrupts();
921
922
923 start = get_timer(0);
924 while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
925 (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080)) {
926
927 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
928 return (1);
929 }
930 }
931
932 return (0);
933}
934#endif
935
936
937
938
939static ulong flash_get_size(vu_long * addr, flash_info_t * info);
940static int write_word(flash_info_t * info, ulong dest, ulong data);
941
942
943
944
945unsigned long flash_init(void)
946{
947 unsigned long total_b = 0;
948 unsigned long size_b[CONFIG_SYS_MAX_FLASH_BANKS];
949 unsigned short index = 0;
950 int i;
951 unsigned long val;
952 unsigned long ebc_boot_size;
953 unsigned long boot_selection;
954
955 mfsdr(sdr_pstrp0, val);
956 index = (val & SDR0_PSTRP0_BOOTSTRAP_MASK) >> 28;
957
958 if ((index == 0xc) || (index == 8)) {
959
960
961
962
963 mfsdr(SDR0_SDSTP1, val);
964 boot_selection = val & SDR0_SDSTP1_BOOT_SEL_MASK;
965 ebc_boot_size = val & SDR0_SDSTP1_EBC_ROM_BS_MASK;
966
967 switch(boot_selection) {
968 case SDR0_SDSTP1_BOOT_SEL_EBC:
969 switch(ebc_boot_size) {
970 case SDR0_SDSTP1_EBC_ROM_BS_16BIT:
971 index = 3;
972 break;
973 case SDR0_SDSTP1_EBC_ROM_BS_8BIT:
974 index = 0;
975 break;
976 }
977 break;
978
979 case SDR0_SDSTP1_BOOT_SEL_PCI:
980 index = 1;
981 break;
982
983 }
984 }
985
986
987
988
989 DEBUGF("\n");
990 DEBUGF("FLASH: Index: %d\n", index);
991
992
993 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
994 flash_info[i].flash_id = FLASH_UNKNOWN;
995 flash_info[i].sector_count = -1;
996 flash_info[i].size = 0;
997
998
999 if (flash_addr_table[index][i] == 0)
1000 continue;
1001
1002
1003 size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i],
1004 &flash_info[i]);
1005
1006 flash_info[i].size = size_b[i];
1007
1008 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
1009 printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
1010 i, size_b[i], size_b[i] << 20);
1011 flash_info[i].sector_count = -1;
1012 flash_info[i].size = 0;
1013 }
1014
1015
1016 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
1017 CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN - 1,
1018 &flash_info[i]);
1019#if defined(CONFIG_ENV_IS_IN_FLASH)
1020 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
1021 CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
1022 &flash_info[i]);
1023#if defined(CONFIG_ENV_ADDR_REDUND)
1024 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
1025 CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
1026 &flash_info[i]);
1027#endif
1028#endif
1029 total_b += flash_info[i].size;
1030 }
1031
1032 return total_b;
1033}
1034