blob: 4bcf2ee7f34e697249d3c2f622454742dd9b1374 [file] [log] [blame]
wdenk7aa78612003-05-03 15:50:43 +00001/*
2 * (C) Copyright 2003
3 * Wolfgang Denk, DENX Software Engineering, wd@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#include <common.h>
25
26flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
27
28/* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
29 * has nothing to do with the flash chip being 8-bit or 16-bit.
30 */
31#ifdef CONFIG_FLASH_16BIT
32typedef unsigned short FLASH_PORT_WIDTH;
33typedef volatile unsigned short FLASH_PORT_WIDTHV;
34#define FLASH_ID_MASK 0xFFFF
35#else
36typedef unsigned long FLASH_PORT_WIDTH;
37typedef volatile unsigned long FLASH_PORT_WIDTHV;
38#define FLASH_ID_MASK 0xFFFFFFFF
39#endif
40
41#define FPW FLASH_PORT_WIDTH
42#define FPWV FLASH_PORT_WIDTHV
43
44#define ORMASK(size) ((-size) & OR_AM_MSK)
45
46#define FLASH_CYCLE1 0x0555
47#define FLASH_CYCLE2 0x02aa
48
49/*-----------------------------------------------------------------------
50 * Functions
51 */
52static ulong flash_get_size(FPWV *addr, flash_info_t *info);
53static void flash_reset(flash_info_t *info);
54static int write_word_intel(flash_info_t *info, FPWV *dest, FPW data);
55static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
56static void flash_get_offsets(ulong base, flash_info_t *info);
57static flash_info_t *flash_get_info(ulong base);
58
59/*-----------------------------------------------------------------------
60 * flash_init()
61 *
62 * sets up flash_info and returns size of FLASH (bytes)
63 */
64unsigned long flash_init (void)
65{
66 unsigned long size = 0;
67 int i;
68
69 /* Init: no FLASHes known */
70 for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
71#if 0
72 ulong flashbase = (i == 0) ? PHYS_FLASH_1 : PHYS_FLASH_2;
73#else
74 ulong flashbase = CFG_FLASH_BASE;
75#endif
76
77 memset(&flash_info[i], 0, sizeof(flash_info_t));
78
79 flash_info[i].size =
80 flash_get_size((FPW *)flashbase, &flash_info[i]);
81
82 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
83 printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
84 i, flash_info[i].size);
85 }
86
87 size += flash_info[i].size;
88 }
89
90#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
91 /* monitor protection ON by default */
92 flash_protect(FLAG_PROTECT_SET,
93 CFG_MONITOR_BASE,
94 CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
95 flash_get_info(CFG_MONITOR_BASE));
96#endif
97
98#ifdef CFG_ENV_IS_IN_FLASH
99 /* ENV protection ON by default */
100 flash_protect(FLAG_PROTECT_SET,
101 CFG_ENV_ADDR,
102 CFG_ENV_ADDR+CFG_ENV_SIZE-1,
103 flash_get_info(CFG_ENV_ADDR));
104#endif
105
106
107 return size ? size : 1;
108}
109
110/*-----------------------------------------------------------------------
111 */
112static void flash_reset(flash_info_t *info)
113{
114 FPWV *base = (FPWV *)(info->start[0]);
115
116 /* Put FLASH back in read mode */
117 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
118 *base = (FPW)0x00FF00FF; /* Intel Read Mode */
119 else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
120 *base = (FPW)0x00F000F0; /* AMD Read Mode */
121}
122
123/*-----------------------------------------------------------------------
124 */
125static void flash_get_offsets (ulong base, flash_info_t *info)
126{
127 int i;
128
129 /* set up sector start address table */
130 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
131 && (info->flash_id & FLASH_BTYPE)) {
132 int bootsect_size; /* number of bytes/boot sector */
133 int sect_size; /* number of bytes/regular sector */
134
135 bootsect_size = 0x00002000 * (sizeof(FPW)/2);
136 sect_size = 0x00010000 * (sizeof(FPW)/2);
137
138 /* set sector offsets for bottom boot block type */
139 for (i = 0; i < 8; ++i) {
140 info->start[i] = base + (i * bootsect_size);
141 }
142 for (i = 8; i < info->sector_count; i++) {
143 info->start[i] = base + ((i - 7) * sect_size);
144 }
145 }
146 else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
147 && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
148
149 int sect_size; /* number of bytes/sector */
150
151 sect_size = 0x00010000 * (sizeof(FPW)/2);
152
153 /* set up sector start address table (uniform sector type) */
154 for( i = 0; i < info->sector_count; i++ )
155 info->start[i] = base + (i * sect_size);
156 }
157}
158
159/*-----------------------------------------------------------------------
160 */
161
162static flash_info_t *flash_get_info(ulong base)
163{
164 int i;
165 flash_info_t * info;
166
167 for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
168 info = & flash_info[i];
169 if (info->start[0] <= base && base < info->start[0] + info->size)
170 break;
171 }
172
173 return i == CFG_MAX_FLASH_BANKS ? 0 : info;
174}
175
176/*-----------------------------------------------------------------------
177 */
178
179void flash_print_info (flash_info_t *info)
180{
181 int i;
182 uchar *boottype;
183 uchar *bootletter;
184 uchar *fmt;
185 uchar botbootletter[] = "B";
186 uchar topbootletter[] = "T";
187 uchar botboottype[] = "bottom boot sector";
188 uchar topboottype[] = "top boot sector";
189
190 if (info->flash_id == FLASH_UNKNOWN) {
191 printf ("missing or unknown FLASH type\n");
192 return;
193 }
194
195 switch (info->flash_id & FLASH_VENDMASK) {
196 case FLASH_MAN_AMD: printf ("AMD "); break;
197 case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break;
198 case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
199 case FLASH_MAN_SST: printf ("SST "); break;
200 case FLASH_MAN_STM: printf ("STM "); break;
201 case FLASH_MAN_INTEL: printf ("INTEL "); break;
202 default: printf ("Unknown Vendor "); break;
203 }
204
205 /* check for top or bottom boot, if it applies */
206 if (info->flash_id & FLASH_BTYPE) {
207 boottype = botboottype;
208 bootletter = botbootletter;
209 }
210 else {
211 boottype = topboottype;
212 bootletter = topbootletter;
213 }
214
215 switch (info->flash_id & FLASH_TYPEMASK) {
216 case FLASH_AM640U:
217 fmt = "29LV641D (64 Mbit, uniform sectors)\n";
218 break;
219 case FLASH_28F800C3B:
220 case FLASH_28F800C3T:
221 fmt = "28F800C3%s (8 Mbit, %s)\n";
222 break;
223 case FLASH_INTEL800B:
224 case FLASH_INTEL800T:
225 fmt = "28F800B3%s (8 Mbit, %s)\n";
226 break;
227 case FLASH_28F160C3B:
228 case FLASH_28F160C3T:
229 fmt = "28F160C3%s (16 Mbit, %s)\n";
230 break;
231 case FLASH_INTEL160B:
232 case FLASH_INTEL160T:
233 fmt = "28F160B3%s (16 Mbit, %s)\n";
234 break;
235 case FLASH_28F320C3B:
236 case FLASH_28F320C3T:
237 fmt = "28F320C3%s (32 Mbit, %s)\n";
238 break;
239 case FLASH_INTEL320B:
240 case FLASH_INTEL320T:
241 fmt = "28F320B3%s (32 Mbit, %s)\n";
242 break;
243 case FLASH_28F640C3B:
244 case FLASH_28F640C3T:
245 fmt = "28F640C3%s (64 Mbit, %s)\n";
246 break;
247 case FLASH_INTEL640B:
248 case FLASH_INTEL640T:
249 fmt = "28F640B3%s (64 Mbit, %s)\n";
250 break;
251 default:
252 fmt = "Unknown Chip Type\n";
253 break;
254 }
255
256 printf (fmt, bootletter, boottype);
257
258 printf (" Size: %ld MB in %d Sectors\n",
259 info->size >> 20,
260 info->sector_count);
261
262 printf (" Sector Start Addresses:");
263
264 for (i=0; i<info->sector_count; ++i) {
265 if ((i % 5) == 0) {
266 printf ("\n ");
267 }
268
269 printf (" %08lX%s", info->start[i],
270 info->protect[i] ? " (RO)" : " ");
271 }
272
273 printf ("\n");
274}
275
276/*-----------------------------------------------------------------------
277 */
278
279/*
280 * The following code cannot be run from FLASH!
281 */
282
283ulong flash_get_size (FPWV *addr, flash_info_t *info)
284{
285 /* Write auto select command: read Manufacturer ID */
286
287 /* Write auto select command sequence and test FLASH answer */
288 addr[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */
289 addr[FLASH_CYCLE2] = (FPW)0x00550055; /* for AMD, Intel ignores this */
290 addr[FLASH_CYCLE1] = (FPW)0x00900090; /* selects Intel or AMD */
291
292 /* The manufacturer codes are only 1 byte, so just use 1 byte.
293 * This works for any bus width and any FLASH device width.
294 */
295 udelay(1000000);//psl
296 //psl switch (addr[1] & 0xff) {
297 switch (addr[0] & 0xff) {//psl
298
299 case (uchar)AMD_MANUFACT:
300 info->flash_id = FLASH_MAN_AMD;
301 break;
302
303 case (uchar)INTEL_MANUFACT:
304 info->flash_id = FLASH_MAN_INTEL;
305 break;
306
307 default:
308 info->flash_id = FLASH_UNKNOWN;
309 info->sector_count = 0;
310 info->size = 0;
311 break;
312 }
313
314 /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
315 //psl if (info->flash_id != FLASH_UNKNOWN) switch (addr[0]) {
316 if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) {
317
318 case (FPW)AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
319 info->flash_id += FLASH_AM640U;
320 info->sector_count = 128;
321 info->size = 0x00800000 * (sizeof(FPW)/2);
322 break; /* => 8 or 16 MB */
323
324 case (FPW)INTEL_ID_28F800C3B:
325 info->flash_id += FLASH_28F800C3B;
326 info->sector_count = 23;
327 info->size = 0x00100000 * (sizeof(FPW)/2);
328 break; /* => 1 or 2 MB */
329
330 case (FPW)INTEL_ID_28F800B3B:
331 info->flash_id += FLASH_INTEL800B;
332 info->sector_count = 23;
333 info->size = 0x00100000 * (sizeof(FPW)/2);
334 break; /* => 1 or 2 MB */
335
336 case (FPW)INTEL_ID_28F160C3B:
337 info->flash_id += FLASH_28F160C3B;
338 info->sector_count = 39;
339 info->size = 0x00200000 * (sizeof(FPW)/2);
340 break; /* => 2 or 4 MB */
341
342 case (FPW)INTEL_ID_28F160B3B:
343 info->flash_id += FLASH_INTEL160B;
344 info->sector_count = 39;
345 info->size = 0x00200000 * (sizeof(FPW)/2);
346 break; /* => 2 or 4 MB */
347
348 case (FPW)INTEL_ID_28F320C3B:
349 info->flash_id += FLASH_28F320C3B;
350 info->sector_count = 71;
351 info->size = 0x00400000 * (sizeof(FPW)/2);
352 break; /* => 4 or 8 MB */
353
354 case (FPW)INTEL_ID_28F320B3B:
355 info->flash_id += FLASH_INTEL320B;
356 info->sector_count = 71;
357 info->size = 0x00400000 * (sizeof(FPW)/2);
358 break; /* => 4 or 8 MB */
359
360 case (FPW)INTEL_ID_28F640C3B:
361 info->flash_id += FLASH_28F640C3B;
362 info->sector_count = 135;
363 info->size = 0x00800000 * (sizeof(FPW)/2);
364 break; /* => 8 or 16 MB */
365
366 case (FPW)INTEL_ID_28F640B3B:
367 info->flash_id += FLASH_INTEL640B;
368 info->sector_count = 135;
369 info->size = 0x00800000 * (sizeof(FPW)/2);
370 break; /* => 8 or 16 MB */
371
372 default:
373 info->flash_id = FLASH_UNKNOWN;
374 info->sector_count = 0;
375 info->size = 0;
376 return (0); /* => no or unknown flash */
377 }
378
379 flash_get_offsets((ulong)addr, info);
380
381 /* Put FLASH back in read mode */
382 flash_reset(info);
383
384 return (info->size);
385}
386
387/*-----------------------------------------------------------------------
388 */
389
390int flash_erase (flash_info_t *info, int s_first, int s_last)
391{
392 FPWV *addr;
393 int flag, prot, sect;
394 int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
395 ulong start, now, last;
396 int rcode = 0;
397
398 if ((s_first < 0) || (s_first > s_last)) {
399 if (info->flash_id == FLASH_UNKNOWN) {
400 printf ("- missing\n");
401 } else {
402 printf ("- no sectors to erase\n");
403 }
404 return 1;
405 }
406
407 switch (info->flash_id & FLASH_TYPEMASK) {
408 case FLASH_INTEL800B:
409 case FLASH_INTEL160B:
410 case FLASH_INTEL320B:
411 case FLASH_INTEL640B:
412 case FLASH_28F800C3B:
413 case FLASH_28F160C3B:
414 case FLASH_28F320C3B:
415 case FLASH_28F640C3B:
416 case FLASH_AM640U:
417 break;
418 case FLASH_UNKNOWN:
419 default:
420 printf ("Can't erase unknown flash type %08lx - aborted\n",
421 info->flash_id);
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
432 if (prot) {
433 printf ("- Warning: %d protected sectors will not be erased!\n",
434 prot);
435 } else {
436 printf ("\n");
437 }
438
439 last = get_timer(0);
440
441 /* Start erase on unprotected sectors */
442 for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
443
444 if (info->protect[sect] != 0) /* protected, skip it */
445 continue;
446
447 /* Disable interrupts which might cause a timeout here */
448 flag = disable_interrupts();
449
450 addr = (FPWV *)(info->start[sect]);
451 if (intel) {
452 *addr = (FPW)0x00500050; /* clear status register */
453 *addr = (FPW)0x00200020; /* erase setup */
454 *addr = (FPW)0x00D000D0; /* erase confirm */
455 }
456 else {
457 /* must be AMD style if not Intel */
458 FPWV *base; /* first address in bank */
459
460 base = (FPWV *)(info->start[0]);
461 base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
462 base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
463 base[FLASH_CYCLE1] = (FPW)0x00800080; /* erase mode */
464 base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
465 base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
466 *addr = (FPW)0x00300030; /* erase sector */
467 }
468
469 /* re-enable interrupts if necessary */
470 if (flag)
471 enable_interrupts();
472
473 start = get_timer(0);
474
475 /* wait at least 50us for AMD, 80us for Intel.
476 * Let's wait 1 ms.
477 */
478 udelay (1000);
479
480 while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
481 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
482 printf ("Timeout\n");
483
484 if (intel) {
485 /* suspend erase */
486 *addr = (FPW)0x00B000B0;
487 }
488
489 flash_reset(info); /* reset to read mode */
490 rcode = 1; /* failed */
491 break;
492 }
493
494 /* show that we're waiting */
495 if ((get_timer(last)) > CFG_HZ) {/* every second */
496 putc ('.');
497 last = get_timer(0);
498 }
499 }
500
501 /* show that we're waiting */
502 if ((get_timer(last)) > CFG_HZ) { /* every second */
503 putc ('.');
504 last = get_timer(0);
505 }
506
507 flash_reset(info); /* reset to read mode */
508 }
509
510 printf (" done\n");
511 return rcode;
512}
513
514/*-----------------------------------------------------------------------
515 * Copy memory to flash, returns:
516 * 0 - OK
517 * 1 - write timeout
518 * 2 - Flash not erased
519 */
520int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
521{
522 FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
523 int bytes; /* number of bytes to program in current word */
524 int left; /* number of bytes left to program */
525 int i, res;
526
527 for (left = cnt, res = 0;
528 left > 0 && res == 0;
529 addr += sizeof(data), left -= sizeof(data) - bytes) {
530
531 bytes = addr & (sizeof(data) - 1);
532 addr &= ~(sizeof(data) - 1);
533
534 /* combine source and destination data so can program
535 * an entire word of 16 or 32 bits
536 */
537 for (i = 0; i < sizeof(data); i++) {
538 data <<= 8;
539 if (i < bytes || i - bytes >= left )
540 data += *((uchar *)addr + i);
541 else
542 data += *src++;
543 }
544
545 /* write one word to the flash */
546 switch (info->flash_id & FLASH_VENDMASK) {
547 case FLASH_MAN_AMD:
548 res = write_word_amd(info, (FPWV *)addr, data);
549 break;
550 case FLASH_MAN_INTEL:
551 res = write_word_intel(info, (FPWV *)addr, data);
552 break;
553 default:
554 /* unknown flash type, error! */
555 printf ("missing or unknown FLASH type\n");
556 res = 1; /* not really a timeout, but gives error */
557 break;
558 }
559 }
560
561 return (res);
562}
563
564/*-----------------------------------------------------------------------
565 * Write a word to Flash for AMD FLASH
566 * A word is 16 or 32 bits, whichever the bus width of the flash bank
567 * (not an individual chip) is.
568 *
569 * returns:
570 * 0 - OK
571 * 1 - write timeout
572 * 2 - Flash not erased
573 */
574static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
575{
576 ulong start;
577 int flag;
578 int res = 0; /* result, assume success */
579 FPWV *base; /* first address in flash bank */
580
581 /* Check if Flash is (sufficiently) erased */
582 if ((*dest & data) != data) {
583 return (2);
584 }
585
586
587 base = (FPWV *)(info->start[0]);
588
589 /* Disable interrupts which might cause a timeout here */
590 flag = disable_interrupts();
591
592 base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
593 base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
594 base[FLASH_CYCLE1] = (FPW)0x00A000A0; /* selects program mode */
595
596 *dest = data; /* start programming the data */
597
598 /* re-enable interrupts if necessary */
599 if (flag)
600 enable_interrupts();
601
602 start = get_timer (0);
603
604 /* data polling for D7 */
605 while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
606 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
607 *dest = (FPW)0x00F000F0; /* reset bank */
608 res = 1;
609 }
610 }
611
612 return (res);
613}
614
615/*-----------------------------------------------------------------------
616 * Write a word to Flash for Intel FLASH
617 * A word is 16 or 32 bits, whichever the bus width of the flash bank
618 * (not an individual chip) is.
619 *
620 * returns:
621 * 0 - OK
622 * 1 - write timeout
623 * 2 - Flash not erased
624 */
625static int write_word_intel (flash_info_t *info, FPWV *dest, FPW data)
626{
627 ulong start;
628 int flag;
629 int res = 0; /* result, assume success */
630
631 /* Check if Flash is (sufficiently) erased */
632 if ((*dest & data) != data) {
633 return (2);
634 }
635
636 /* Disable interrupts which might cause a timeout here */
637 flag = disable_interrupts();
638
639 *dest = (FPW)0x00500050; /* clear status register */
640 *dest = (FPW)0x00FF00FF; /* make sure in read mode */
641 *dest = (FPW)0x00400040; /* program setup */
642
643 *dest = data; /* start programming the data */
644
645 /* re-enable interrupts if necessary */
646 if (flag)
647 enable_interrupts();
648
649 start = get_timer (0);
650
651 while (res == 0 && (*dest & (FPW)0x00800080) != (FPW)0x00800080) {
652 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
653 *dest = (FPW)0x00B000B0; /* Suspend program */
654 res = 1;
655 }
656 }
657
658 if (res == 0 && (*dest & (FPW)0x00100010))
659 res = 1; /* write failed, time out error is close enough */
660
661 *dest = (FPW)0x00500050; /* clear status register */
662 *dest = (FPW)0x00FF00FF; /* make sure in read mode */
663
664 return (res);
665}